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 else clause 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

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -