Intermediate classes: Difference between revisions

From 22118
Jump to navigation Jump to search
Line 20: Line 20:
# Let's do something natural. Make it possible to add one FastaInstance to another using the '''+=''' operator, like this:<div style="font-family:'Courier New'">FastaInstance1 += FastaInstance2<br></div>The headers and sequences in Fastainstance2 should be added (list extension) to the headers and sequences in FastaInstance1. Use the magic method [https://zetcode.com/python/dunder-iadd/ '''__iadd__'''].<br><br>
# Let's do something natural. Make it possible to add one FastaInstance to another using the '''+=''' operator, like this:<div style="font-family:'Courier New'">FastaInstance1 += FastaInstance2<br></div>The headers and sequences in Fastainstance2 should be added (list extension) to the headers and sequences in FastaInstance1. Use the magic method [https://zetcode.com/python/dunder-iadd/ '''__iadd__'''].<br><br>
# Implement the ''addition'', using [https://zetcode.com/python/dunder-add/ '''__add__''']. Addition creates a new Fasta instance, but leaves the originals untouched.<div style="font-family:'Courier New'">FastaInstance3 = FastaInstance1 + FastaInstance2<br></div>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.
# Implement the ''addition'', using [https://zetcode.com/python/dunder-add/ '''__add__''']. Addition creates a new Fasta instance, but leaves the originals untouched.<div style="font-family:'Courier New'">FastaInstance3 = FastaInstance1 + FastaInstance2<br></div>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.
# You can consider a Fasta instance as a ''set'' of headers/sequences. The sequences are obviously uniquely identified by the identifier in the header.


== Exercises for extra practice ==
== Exercises for extra practice ==
# 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.
# 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.

Revision as of 15:09, 17 March 2026

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 two 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.

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.