开发者

Python Range Class/Subclass

开发者 https://www.devze.com 2023-01-19 08:42 出处:网络
I have code for a Range class like this: class Range: def __init__(self, start, end): self.setStart(start)

I have code for a Range class like this:

class Range:
   def __init__(self, start, end):
      self.setStart(start)
      self.setEnd(end)
   def getStart(self):
      return self.start
   def setStart(self, s):
      self.start = s
   def getEnd(self):
      return self.end
   def setEnd(self, e):
      self.end = e
   def getLength(self):
      return len(range(self.start, self.end))
   def overlaps(self, r):
      if (r.getStart() < self.getEnd() and r.getEnd() >= self.getEnd()) or \
         (self.getStart() < r.getEnd() and self.getEnd() >= r.getEnd()) or \
         (self.getStart() >= r.getStart() and self.getEnd() <= r.getEnd()) or \
         (r.getStart() >= self.getStart() and r.getEnd() <= self.getEnd()):
          return True
      else:
          return False

My assignment is to create a subclass of Range, called DNAFeature, that represents a Range that also has a strand and a sequence name:

Implement setStrand and getStrand, which set and return开发者_如何学JAVA strand information, and setSeqName and getSeqName, which set or return the name of the sequence the feature belongs to. If a feature is on the minus (reverse) strand, getStrand() should return ‐1. If a feature is on the plus strand, getStrand() should return 1. If strand is not set, getStrand() should return 0.

I have tried to write something but doesn't look right at all for me, can everyone please help me with this, thank you so much guys, this is my code:

class DNAFeature(Range):
    def __init__(self, strand, sequence):
            self.setStrand(strand)
            self.setSeqName(sequence)
    def getSeqName(self):
            return self.plus or minus
    def setSeqName(self, seq):
            self.sequence = seq
    def getStrand(self):
            if self.getSeqName(self.strand) == 'plus':
                    return 1
            if self.getSeqName(self.strand) == 'minus':
                    return -1
            else:
                    return 0
    def setStrand(self, strand):
            self.strand = strand


In general it is much easier to answer questions if you provide a specific error message or thing that is going wrong. Here's what happened when I tried to run the above:

  • First up:

    `SyntaxError: invalid syntax` 
    

    on if seq == POSITIVE. What's wrong here? Oh yes, you're missing a colon after the conditional. If you add that the file at least parses. So let's try doing some coding:

    # Your code here, then:
    feature = DNAFeature()
    
  • Running that gives:

    TypeError: __init__() takes exactly 3 positional arguments (1 given)
    

    Oh, OK, we need to pass some arguments to the initialiser of DNAFeature. Let's put this on the + strand, and call it foo:

    feature = DNAFeature(1, "foo")
    
  • Now we get:

    AttributeError: 'DNAFeature' object has no attribute 'setStrand'
    

    What's that about? OK, you haven't defined setStrand. (Note: you shouldn't have to. But more on that later.) Let's define it:

    def setStrand(self, strand):
        self.strand = strand
    

I don't want to go through the rest of the problems with the code (hint: you need to define variables before you use them), but this is the sort of thing you should be doing.


Right, something different. The above is bad code. I hope you've written the Range class and that it hasn't been provided as part of the course, because if it has you're taking a badly-taught course. The main problem is the use of getters and setters -- I'm guessing you're Java-born and bred? In Python you don't need to write getters and setters for everything, because you can always add them in later if you need them. Instead, just use class attributes. Look at the following code for Range:

class Range:
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def length(self):
        return self.end - self.start

    def overlaps(self, other):
        return not(self.end < other.start or other.end < self.start)

Isn't that much nicer? No more nasty accessors, no icky comparisons in the overlaps method... It helps if you work out the logic that your code is trying to implement before you implement it.

See if you can write a better DNAFeature now.


You still haven't told me what getStrand should, do, but here's what I think you're aiming towards. Suppose the strand name that gets passed to __init__ is of the form "+name" or "-name". You can then do the following:

def __init__(self, strand):
    sequence = strand[0] #first character of strand

    if sequence == "+":
        self.strand = 1
        self.sequence= strand[1:]
    elif sequence == "-":
        self.strand = -1
        self.sequence = strand[1:]
    else:
        self.strand = 0
        self.sequence = strand

See if you can work out how that works.


In the most generic case (without making any assumptions), it seems that this is what you need:

class DNAFeature(Range):

    def __init__(self, start, end):
        self.setStart(start)
        self.setEnd(end)
        self.strand = None
        self.sequencename = None

    def setStrand(self, s):
        self.strand = s

    def getStrand(self):
        if self.sequenceName == 'plus':
            return 1
        elif self.sequenceName == 'minus':
            return -1
        else:
            return 0

    def setSequenceName(self, s):
        self.sequencename = s

    def getSequenceName(self, s):
        return self.sequenceName

You will notice that here, I have redefined init. There is a reason for this. I remember that in one of your earlier questions, you had mentioned that this was a Java assignment, just renamed to python. In Java, constructors are not inherited (correct me if I'm wrong). Therefore, if the same grading rubric is being used, you will lose marks for not redefining the constructor here.

Hope this helps

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号