Python 3 added a new range class to efficiently handle "an immutable sequence of numbers" (similar to Python 2's xrange). Python 2 does not have such a range class, so the range function just returns a list.
Python 3 added a new range class to efficiently handle "an immutable sequence of numbers" (similar to Python 2's xrange). Python 2 does not have such a range class, so the range function just returns a list.
In Python 2 range(val) produces an instance of a list, it simply a function. Thereby type(range(10)) will return class 'list'.
In Python 3, range is equivalent to xrange in Python 2 and it returns an instance of a new class named range. For more changes/differences between Python 2/3 see PEP 3100.
Videos
I first thought that it just returns numbers and you can do a lot of stuff with those numbers but now I am seeing that it is being used to run a loop a specific number of times. It's just not making sense to me why this works, like I can't intuitively understand it.
Tho I have started using in my code, an explanation on why it was developed this way would help.
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