Intermediate classes

From 22118
Jump to navigation Jump to search
Previous: Beginning classes Next: Beginning unit test

Required course material for the lesson

Powerpoint: Classes
Resource: Example code - Classes

Subjects covered

Magic methods in classes
Object Oriented Programming
Polymorphism and inheritance
Practical knowledge

Exercises to be handed in

The first four exercises will continue with the Fasta class from last time.

  1. Use magic methods to add iteration and length evaluation (using __iter__ and __len__ magic methods) to the Fasta class. Do this so you can write code like
    if len(MyFastaInstance) > 0:
        for header, sequence in MyFastaInstance:
            # Do something with header and sequence
            print(header, sequence)
    The function len returns the number of sequences.

  2. Add the methods deletethis(), insertthis(header, sequence), verifythis(alphabet) and discardthis(alphabet) to the Fasta class. The methods should only work when iterating over an instance at the current item, i.e. they work when you are iterating over the fasta sequences on the current sequence and header, like this:
    for header, sequence in MyFastaInstance:
        if not MyFastaInstance.verifythis("DNA"):
            MyFastaInstance.deletethis()
            continue
        # Do something with header and sequence
    As some may remember, it is normally impossible to successfully iterate straightforward through a list and delete and/or add elements to the list during the iteration. You have to make this possible. Hint: change the way your iteration works in the previous exercise.

  3. Let's do something natural. Make it possible to add one FastaInstance to another using the += operator, like this:
    FastaInstance1 += FastaInstance2
    The headers and sequences in Fastainstance2 should be added (list extension) to the headers and sequences in FastaInstance1. Use the magic method __iadd__.

  4. Implement the addition, using __add__. Addition creates a new Fasta instance, but leaves the originals untouched.
    FastaInstance3 = FastaInstance1 + FastaInstance2
    The resulting Fasta object must contain the headers and sequences from FastaInstance1 and FastaInstance2 in that order. Note that this works as an alternative constructor.

  5. You can consider a Fasta instance as a set of headers/sequences. The sequences are obviously uniquely identified by the identifier in the header, which is what will be used as key in the set operations. In the rest of the exercises we will explore inheritance by making a new class called FastaSet, which inherits from the Fasta class.
    A) The original __init__, save, load, insert, the iteration and the corresponding deletethis, insertthis, verifythis and discardthis methods are fine to keep in the new class (meaning do nothing about them).
    B) To help in the new class create a new getter method, which returns a list of identifiers from the header lines.
    C) Override the content method such that it takes a set or list of identifiers and returns only the headers/sequences that corresponds to the identifiers in the list. If you do not specify a list/set of identifiers, it still returns all.
    D) Override the delete method in a similar way - it deletes the headers/sequences that corresponds to the input.
    E) Override the verify method in a similar way to content.
    F) Override the discard method in a similar way to content.

Exercises for extra practice

  1. Considering a FastaInstance as a set of headers/sequences, you could implement the set operations; union (| __or__), intersection (& __and__), difference (- __sub__) and symmetric difference (^ __xor__). This is quite similar to the addition in exercise 4 - a new Fasta object is returned. The identity of the sequence depends on the identifier in the corresponding header. This is an example of operator overloading.