Reputation: 79
I have this python file that I'm working on:
class Range:
""" An object that has a non-negative start position and a non-negative length"""
def __init__(self, start, end):
"""
Function: generates a new Range
Returns : a new range
Args : start - start position
end - end position
Start and End must be non-negative """
self.start = 0
self.end = 10000
self.setStart(start)
self.setEnd(end)
def getStart(self):
"""
Function: get the start of the range
Returns : a number or None
Args : start - the int index of the first nucleotide of this range """
return self.start
def setStart(self, s):
"""
Function: set the start of the range
Returns : None
Args : start - a non-negative int or None """
if type(s) !=int:
raise TypeError ("Cannot set Start as this is not an interger")
elif s < 0:
raise ValueError ("Cannot set Start as this is not a non-negative int")
elif s > self.end:
raise ValueError("start cannot be larger than end")
else:
self.start = s
def getEnd(self):
"""
Function: get the end of the range
Returns : a number
Args :
"""
return self.end
def setEnd(self, e):
"""
Function: set the end of the range
Returns : None
Args : end - a non-negative int or None
"""
if type(e) !=int:
raise TypeError ("Cannot set End as this is not an interger")
elif e < 0:
raise ValueError ("Cannot set End as this is not a non-negative int")
elif e < self.start:
raise ValueError ("end has to be larger than start")
else:
self.end = e
def getLength(self):
"""
Function: get the length of the range
Returns : an int. the length of this range
Args:
"""
return self.end - self.start
def overlaps(self, r):
"""
Function: to test if two nucleotide is overlap
Returns : True or False
Args : other - a Range object
"""
start1 = self.getStart()
end1 = start1 + self.getLength()
start2 = r.getStart()
end2 = start2 + self.getLength()
max_start = max(start1,start2)
min_end = min(end1,end2)
return min_end - max_start > 0
if self.getStart() == r.getStart():
return True
else:
return False
class DNAFeature(Range):
"""Represents a feature on a DNA sequence """
def __init__(self, seq_name = None, strand = 0, **kwargs):
"""
Function : represents a rane
Returns :
Args : strand, seqname, **kwargs
"""
Range.__init__(self, **kwargs)
self.setStrand(strand)
self.setSeqName(seq_name)
def getSeqName(self):
"""
Function: Gets object's Sequence Name
Returns : seqname - string
Args :
"""
return self.seq_name
def setSeqName(self, seq_name):
"""
Function: Sets object's Sequence Name
Returns : None
Args : seqname - mRNA accession name
"""
self.seq_name = seq_name
def getStrand(self):
"""
Function: Retrieve the strand affiliation of this
Returns : 1, 0, -1 - strand
Args :
"""
return self.strand
def setStrand(self, strand):
"""
Function: sets which strand the object is on
Returns : None
Args : strand - one of ['+',1,'F','-',-1,'R']
"""
StrandValues = [1, 0, -1]
if not strand in StrandValues:
raise ValueError("only able to setStrand if the values is 1, 0, or -1")
else:
self.strand = strand
def overlaps(self, other, ignore_strand = True):
"""
Function: tests if this overlaps other
Returns : true if the ranges have same Seqname and overlap, false if not
Args : other - another Range object
"""
if ignore_strand == True and self.getSeqName() == other.getSeqName():
return Range.overlaps(self,other)
else:
return False
class GeneModel(DNAFeature):
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs):
"""
Function : contains a group of DNAFeature objects representing exons
Returns :
Args : **kwargs
"""
DNAFeature.__init__(self, **kwargs)
self.setTranslStart(transl_start)
self.setTranslStop(transl_stop)
self.setDisplayId(display_id)
self.exons = [ ]
def getFeats(self):
"""
Function: gets object's feats list
Returns : list of feature keys
Args : feature_type - the type of strand the object holds
"""
self.exons.sort(cmp=self.start)
return self.exons
def addFeat(self, feat):
"""
Function: adds SeqFeature to feats keys
Returns : None
Args : feat - a single SeqFeature object
"""
if type(feat) == DNAFeature:
self.exons.append(feat)
else:
raise TypeError("Cannot add feature as it is not a type of DNAFeature")
def setTranslStart(self, transl_start):
"""
Function : accepts an non-negative int, sets the start position of the initiating ATG
Returns :
Args : transl_start
"""
if transl_start == None:
self.transl_start = None
return
elif type(transl_start) !=int:
raise TypeError("TranslStart cannot be set since it is not a type of int")
elif transl_start < 0:
raise ValueError("TranslStart cannot be set to a negative int")
else:
self.translStart = transl_start
def getTranslStart(self):
"""
Function: the start position of initiating ATG codon
Return : an int.
Args :
"""
return self.transl_start
def setTranslStop(self, transl_stop):
"""
Function: set the end position of initiating ATG codon
Return : None
Args : a positive int
"""
if transl_stop == None:
self.transl_stop = None
return
elif type(transl_stop) !=int:
raise TypeError("TranslStop cannot be set since it is not a type of int")
elif transl_stop < 0:
raise ValueError("TranslStop cannot be set to a negative int")
else:
self.translStop = transl_stop
def getTranslStop(self):
"""
Function: the end position of initiating ATG codon
Return : an int.
Args :
"""
return self.transl_stop
def setDisplayId(self, display_id):
"""
Function: set the display id
Returns : None
Args : display_id - a string, a preferred name for this
"""
if type(display_id) !=str:
raise TypeError("Cannot set displayId as it is not a type string")
else:
self.display_id = display_id
def getDisplayId(self):
"""
Function: get the display id
Returns : display_id - a string, a preferred name for this, e.g AT1G10555.1
Args :
"""
return self.display_id
Then, I got some code from my professor to test my file:
class TestGeneModelConstructor(unittest.TestCase):
def testGeneModelConstructor(self):
"""GeneModel constructor supports named arguments display_id,transl_start,transl_stop"""
p1.GeneModel(start=0,end=10,seq_name='something',strand=1,display_id='foobar',
transl_start=0,transl_stop=10)
def testGeneModelConstructorDefaults(self):
"""Default values for display_id, transl_start, transl_stop should be None"""
r = p1.GeneModel()
self.assertEquals(r.getDisplayId(),None)
self.assertEquals(r.getTranslStart(),None)
self.assertEquals(r.getTranslStop(),None)
def testGeneModelConstructorWrongTypeDisplayId(self):
"""Raise a TypeError if display_id is not a string."""
self.assertRaises(TypeError,p1.GeneModel,display_id=0)
def testGeneModelConstructorWrongTypeTranslStart(self):
"""Raise a TypeError if transl_start is not an int."""
self.assertRaises(TypeError,p1.GeneModel,transl_start='0')
def testGeneModelConstructorWrongTypeTranslStop(self):
"""Raise a TypeError if transl_stop is not an int."""
self.assertRaises(TypeError,p1.GeneModel,transl_stop='0')
def testGeneModelConstructorWrongValueTranslStart(self):
"""Raise a ValueError if transl_start is int < 0."""
self.assertRaises(ValueError,p1.GeneModel,transl_start=-1)
def testGeneModelConstructorWrongValueTranslStop(self):
"""Raise a ValueError if transl_stop is int < 0."""
self.assertRaises(ValueError,p1.GeneModel,transl_stop=-1)
I have run it and got these errors:
ERROR: Default values for display_id, transl_start, transl_stop should be None
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 117, in testGeneModelConstructorDefaults
r = p1.GeneModel()
TypeError: __init__() takes at least 3 arguments (1 given)
======================================================================
ERROR: Raise a ValueError if transl_start is int < 0.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 136, in testGeneModelConstructorWrongValueTranslStart
self.assertRaises(ValueError,p1.GeneModel,transl_start=-1)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 336, in failUnlessRaises
TypeError: __init__() takes at least 3 non-keyword arguments (2 given)
======================================================================
ERROR: Raise a ValueError if transl_stop is int < 0.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 140, in testGeneModelConstructorWrongValueTranslStop
self.assertRaises(ValueError,p1.GeneModel,transl_stop=-1)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 336, in failUnlessRaises
TypeError: __init__() takes at least 3 non-keyword arguments (1 given)
I'm not sure what is wrong, I have tried to fixed it couple times, but haven't figure out what is wrong in my codes.
Alright, I have change my code in DNAFeature like this:
class DNAFeature(Range):
"""Represents a feature on a DNA sequence """
def __init__(self, seq_name = None, strand = 0, **kwargs):
"""
Function : represents a rane
Returns :
Args : strand, seqname, **kwargs
"""
Range.__init__(self, 0,10000, **kwargs)
self.setStrand(strand)
self.setSeqName(seq_name)
And then, get 3 more errors and 1 failure like this:
ERROR: DNAFeature on different sequence don't overlap
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 164, in testDiffSequenceOverlaps
r1 = p1.DNAFeature(start=0,end=10,strand=1,seq_name="foo")
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
======================================================================
ERROR: DNAFeatures on the same strand can overlap if ignore_strand is True.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 185, in testDiffStrandsDontOverlap
r1 = p1.DNAFeature(start=0,end=10,strand=1,seq_name="foo")
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
======================================================================
ERROR: GeneModel constructor supports named arguments display_id,transl_start,transl_stop
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 113, in testGeneModelConstructor
transl_start=0,transl_stop=10)
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 151, in __init__
DNAFeature.__init__(self, **kwargs)
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
FAIL: Raise a TypeError if seq_name is not a string.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 98, in testDNAFeatureSeqNameConstructorWrongType
self.assertRaises(TypeError,p1.DNAFeature,seq_name=0)
AssertionError: TypeError not raised
Upvotes: 4
Views: 1929
Reputation: 59653
There are several things wrong:
Firstly:
In your test function, testGeneModelConstructorDefaults, you have the comment: "Default values for display_id, transl_start, transl_stop should be None".
The problem you are seeing is that you have only set up the defaults on 1 of the 3 arguments; whereas this test function assumes you have set up defaults on all three. To fix this, you need to define the constructor like this:
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs)
By having the keyword arguments, it will use the default of None
. If you don't specify those keyword arguments explicitly, Python will complain (as it is currently doing).
Secondly:
You have to consider your superclass constructors. The Range
superclass asks for two parameters: start and end.
def __init__(self, start, end):
However, when the DNAFeature
constructor calls the Range
superclass, it doesn't pass in begin or end:
Range.__init__(self, **kwargs)
This is where I think the error is now (I think before it was at the p1.GeneModel()
call - there are probably different error lines in your two error messages).
To fix this, make the values for start and end into keyword parameters also. So instead of:
def __init__(self, start, end):
make it:
def __init__(self, start=0, end=10000):
You can then delete the following lines of code in your range
constructor:
self.start = 0
self.end = 10000
That should at least get you past this error - you may find more errors that you have.
Upvotes: 2
Reputation: 3908
Smashery is right. Try running this simplified code:
class GeneModel(object):
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs):
pass
def testGeneModelConstructor():
g = GeneModel(start=0,end=10,seq_name='something',strand=1,display_id='foobar', transl_start=0,transl_stop=10)
def testGeneModelConstructorDefaults():
r = GeneModel()
testGeneModelConstructor()
testGeneModelConstructorDefaults()
Upvotes: 1
Reputation: 1602
It appears that the tests are assuming that all parameters are passed by value. You need to give the positional arguments defaults.
Upvotes: 1