python - How to check with a class method if my input is valid -
in program, have class represent volume (containing quantity , unit). i'm getting error when run it, , when attempt following in interpreter:
>>> = (10, "mil") >>> print(a) error: <repr(<__main__.volume @ 0x9ab7cc0>) failed: typeerror: __repr__ returned non-string (type nonetype)> i need fix error before can check if other methods work can't seem find how fix this. here code:
class volume(object): def __init__ (self, m = 0, u = "ml"): self.__magnitude = m self.__units = u def is_valid (self): #checks if volume , units valid if type(self.__magnitude) == int , type(self.__units) == str: if self.__units == "ml" or self.__units == "oz": if self.__magnitude < 0: return true else: return false else: return false else: return false def __repr__ (self): if volume.is_valid(self): return str(self.__magnitude) + " " + str(self.__units) #needs fix def __str__ (self): if volume.is_valid(self): return round(self.__repr__(),3) #fix def units (self): #returns units of volume if volume.is_valid(self): return self.__units def magnitude (self): #returns magnitude of volume if volume.is_valid(self): return self.__magnitude def metric (self): #transforms magnitude metric system if needed if volume.is_valid(self): if self.__units == "ml": return self.__units elif self.__units == "oz": mil = self.__units / 0.033814 return mil def customary (self): #transforms magnitude customary if needed if volume.is_valid(self): if self.__units == "oz": return self.__units elif self.__units == "ml": ozs = self.__units * 0.033814 return ozs def __add__ (self, v2): #adds magnitude using int or volume if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): #check if v2 valid if self.__units == v2.__units: return volume(self.__magnitude + v2.__magnitude, self.__units) else: if v2.__units == 'ml': v3 = v2.customary() return volume(self.__magnitude + v3.__magnitude, self.__units) elif v2.__units == 'oz': v3 = v2.__units return volume(self.__magnitude + v3.__magnitude, self.__units) elif isinstance(v2,(int,float)): #create new volume same units self v3 = volume(v2, self.__units) return volume(self.__magnitude + v3.__magnitude, self.__units) def __radd__ (self, v2): #adds ability i.e. 2 + return self.__add__(v2) def __sub__ (self, v2): #same __add__ subtracts if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return volume(self.__magnitude - v2.__magnitude, self.__units) else: if v2.__units == 'ml': v3 = v2.customary() return volume(self.__magnitude - v3.__magnitude, self.__units) elif v2.__units == 'oz': v3 = v2.__units return volume(self.__magnitude - v3.__magnitude, self.__units) elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return volume(self.__magnitude - v3.__magnitude, self.__units) def __rsub__ (self, v2): return volume(v2.__magnitude - self.__magnitude, self.__units) def __mult__ (self, v2):#multiplies volume int (not other vol) if volume.is_valid(self): return volume(self.__magnitude * v2.__magnitude, self.__units) def __rmult__ (self, v2): return self.__mult__(v2) def __eq__ (self, v2): #checks if 2 volumes equal if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude == v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude == v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude == v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude == v3.__magnitude def __noteq__ (self, v2): #checks if 2 volumes not equal if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude != v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude != v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude != v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude != v3.__magnitude def __lt__ (self, v2): #checks if 1 volume < other volume if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude < v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude < v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude < v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude <= v3.__magnitude def __gt__ (self, v2): #checks if 1 volume > other volume if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude > v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude > v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude > v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude > v3.__magnitude def __lteq__ (self, v2):#checks if 1 volume <= other volume if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude <= v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude <= v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude <= v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude <= v3.__magnitude def __gteq__ (self, v2):#checks if 1 volume >= other volume if volume.is_valid(self): if isinstance(v2, volume): if volume.is_valid(v2): if self.__units == v2.__units: return self.__magnitude >= v2.__magnitude else: if v2.__units == 'ml': v3 = v2.customary() return self.__magnitude >= v3.__magnitude elif v2.__units == 'oz': v3 = v2.__units return self.__magnitude >= v3.__magnitude elif isinstance(v2,(int,float)): v3 = volume(v2, self.__units) return self.__magnitude >= v3.__magnitude
def __repr__ (self): if volume.is_valid(self): return str(self.__magnitude) + " " + str(self.__units) #needs fix in code, if test false, function returns nothing (aka none) don't have else close. have same anti-pattern in different methods. either:
- add
elseclause return sensible value; - or (probably better) raise exception when method called on invalid object;
- finally, mentioned @malfunctionning in comment bellow considered bad style validate object on each , every method call. given use case, should have validated parameters in constructor , raised exception @ point.
as volume(10, "ml") -- afaict, not validate according is_valid method:
def is_valid (self): #checks if volume , units valid if type(self.__magnitude) == int , type(self.__units) == str: if self.__units == "ml" or self.__units == "oz": if self.__magnitude < 0: return true else: return false else: return false else: return false the way method return true unit of "oz" or "ml" , negative magnitude (self.__magnitude < 0).
for understand, validation logic should more that:
def is_valid (self): #checks if volume , units valid return (self.__units == "ml" or self.__units == "oz") , \ self.__magnitude >= 0; as last word, don't need invoke is_valid class method:
if volume.is_valid(self): ... from see, proper instance method , should called that:
if self.is_valid(): ...
Comments
Post a Comment