8

I need to implement a DNA class which has attribute a sequence which consists of a string of characters from the alphabet ('A,C,G,T') and I need to overload some operators like less than, greater than, etc..

here is my code:

class DNA:
    def __init__(self, sequence):
        self.seq = sequence

    def __lt__(self, other):
        return (self.seq < other)

    def __le__(self, other):
        return(self.seq <= other)

    def __gt__(self, other):
        return(self.seq > other)

    def __ge__(self, other):
        return(len(self.seq) >= len(other))

    def __eq__(self, other):
        return (len(self.seq) == len(other))

    def __ne__(self, other):
        return not(self.__eq__(self, other))

dna_1=DNA('ACCGT')
dna_2=DNA('AGT')
print(dna_1 > dna_2)

Problem:

when I print(dna_1>dna_2) it returns False instead of True... Why?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Java dev
  • 89
  • 1
  • 1
  • 7

2 Answers2

19

You probably want to compare seqs:

def __lt__(self, other):
    return self.seq < other.seq

etc.

Not self's seq with other, self's seq with other's seq.

other here is another DNA.

If you need to compare lengths:

def __lt__(self, other):
    return len(self.seq) < len(other.seq)

etc.
Pavel Anossov
  • 60,842
  • 14
  • 151
  • 124
  • 1
    and looking at `__ge__`, `__ne__` and `__eq__`, I think OP wants to compare the `len` of `seq` – dmg Mar 17 '13 at 14:03
  • the purpose of __ge__,__ne__,ect are used to compare the length of dna_1 and dna_2 – Java dev Mar 17 '13 at 14:08
  • Didn't you just post that `len` should be removed? – Pavel Anossov Mar 17 '13 at 14:09
  • Anyway, you decide whether you need `len` or not, just look at `seq` on both sides of the comparison. – Pavel Anossov Mar 17 '13 at 14:09
  • when i do use len,it gives an error message..so i got rid of it!and when i print(dna_1>dna_2),it returns the incorrect answer..this is confusing – Java dev Mar 17 '13 at 14:13
  • 1
    You get an error because you use `len` on `other`. Use `len(other.seq)`. – Pavel Anossov Mar 17 '13 at 14:14
  • yes it now works with this def __lt__(self, other): return len(self.seq) < len(other.seq) but can you explain len(other.seq) please?why is other attached to the first dna? i have another problem when overloading 'not equal to'(__ne__)..is this the way to write it? def __ne__(self,other): return not(self.__eq__) – Java dev Mar 17 '13 at 16:05
  • `self` is attached to the first dna, `other` to the other one. – Pavel Anossov Mar 17 '13 at 16:07
  • why did we not write len(self.seq) < len(other) ? – Java dev Mar 17 '13 at 16:09
  • We want to compare the `seq` attributes of `self` and `other`, not the `seq` attribute of `self` with the entire `other` itself. – Pavel Anossov Mar 17 '13 at 16:21
0

When you compare with less-than, __lt__(other) is called with with a DNA object. When you call __init__, self.seq is set to a string (str). So, you are comparing a str < DNA object.

Magic method are magic, not clairvoyant. They won't know what you intend the comparison to be, so it will use what it will use a default (probably the output of repr(), I didn't check).

You need to specify your design what makes one DNA equal to another. Your code implies that the sequence length determines equality. So different sequences can be computed as being equal. Your equality method therefore implies that a sequence is less than another when it is shorter. So your method might be better written by comparing the lengths of the sequences rather the str to DNA object.

Les
  • 10,335
  • 4
  • 40
  • 60