Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sub-classes

Tags:

python

class

I have this class which works with fractions (e.g. (1,2), (3,4) etc):

class Fraction(object):

    def __init__(self, num=0, denom=1):
        ''' Creates a new Fraction with numberator num and denominator denom'''
        self.numerator = num
        if denom != 0:
            self.denominator = denom
        else: 
            raise ZeroDivisionError
    def __str__(self):
        '''Returns the string numerator/denominator '''
        return "{0}/{1}".format(self.numerator, self.denominator)
    def __repr__(self):
        """blah"""
        return Fraction(self.numerator, self.denominator)

And I want to have a sub-class Mixed number which can accept both a whole number and a fraction (e.g. 2 Fraction(1,2), 3 Fraction (3,4) etc). I'm not sure how to do this however, Any help as to how to do this would be appreciated

class MixedNumber(Fraction):
like image 1000
user2101517 Avatar asked Feb 01 '26 20:02

user2101517


1 Answers

There are two ways that immediately come to mind when thinking of implementing a MixedNumber class with a Fraction class provided. One way is as @HunterMcMillen suggests, is to have the class use composition, which is to utilize distinct objects to represent the whole number, and fraction parts, respectively. This gives you access to each objects specialized methods inside your class, which can be handy if the components you're building from have distinct behaviors each encapsulates.

class MixedNumber(object):
   def __init__(self, whole_number, fraction):
        self.whole_number = whole_number
        self.fraction = fraction

   def __str__(self):
        if self.fraction.numerator == 0:
            return str(self.whole_number)
        elif self.whole_number == 0:
            return str(self.fraction)
        else:
            return '{} {}'.format(self.whole_number,self.fraction)

   def __repr__(self):
        return 'MixedNumber({},{!r})'.format(self.whole_number,self.fraction)

The other possibility is inheritance, if your Fraction class supports improper fractions, then you can use a subclass to appropriately handle initialization and string rendering in mixed number format, as follows:

class MixedNumber(Fraction):
    def __init__(self, whole_number, fraction):     
        num = whole_number * fraction.denominator + fraction.numerator
        super(MixedNumber,self).__init__(num,  fraction.denominator)

    def __str__(self):
        # assume positive fractions for demonstration only
        q, r = divmod(self.numerator,self.denominator)
        if r == 0:
            return str(q)
        elif q == 0:
            return super(MixedNumber,self).__str__() 
        else:
            return '{} {}/{}'.format(q,r,self.denominator)

    def __repr__(self):
        q, r = divmod(self.numerator, self.denominator)
        return 'MixedNumber({},Fraction({},{}))'.format(q,r,self.denominator)

Your Fraction.__repr__ method should return a string that when passed into eval should instantiate something equal to the source object, i.e. eval(frac) == frac. See this stack overflow question for more details on the distinction between __str__ and __eval__.

like image 117
mtadd Avatar answered Feb 03 '26 10:02

mtadd