Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Object-Oriented Python Advanced Objects Multiplication

Sebastiaan van Vugt
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Sebastiaan van Vugt
Python Development Techdegree Graduate 13,554 Points

mul and rmul work perfectly but the assignment is not accepted

I have tried to anticipate int, float and str types and allow for multiplication accordingly in the mul and rmul functions. In my tests it worked perfectly and I therefore do not understand why the assignment is not accepted:

class NumString:
    def __init__(self, value):
        self.value = str(value)


    def __str__(self):
        print('This came from __str__()')
        return('s' + str(self.value))

    def __int__(self):
        print('This came from __int__()')
        return(int(self.value))

    def __float__(self):
        print('This came from __float__()')
        return(float(self.value))

    def __add__(self, other):
        print('This came from __add__()')
        if '.' in self.value:
            return(float(self) + other)
        else:
            return(int(self) + other)

    def __radd__(self, other):
        print('This came from __radd__()')
        return self + other

    def __iadd__(self, other):
        self.value = self + other
        print('This came from __iadd__()')
        return self.value

    def __mul__ (self, other):
        print('This came from __mul__()')
        try:
            s1 = int(self.value)
        except ValueError:
            try:
                s1 = float(self.value)
            except ValueError:
                s1 = self.value
        try:
            o1 = int(other)
        except ValueError:
            try:
                o1 = float(other)
            except ValueError:
                o1 = other
        try:
            return s1*o1
        except TypeError:
            print("There was a type error")

    def __rmul__ (self, other):
        print('This came from __rmul__()')
        try:
            s1 = int(self.value)
        except ValueError:
            try:
                s1 = float(self.value)
            except ValueError:
                s1 = self.value
        try:
            o1 = int(other)
        except ValueError:
            try:
                o1 = float(other)
            except ValueError:
                o1 = other
        try:
            return s1*o1
        except TypeError:
            print("There was a type error")


five = NumString(5)
fourpointone = NumString(4.1)
age = NumString(25)


age +=1
print(age)
print(age*2)
print(3*age)
print()
print(3*NumString(25))
print(NumString(25)*4)
print(five*age)
print()
print(3*NumString(25.2))
print(NumString(25)*'Sebastiaan')
print('Sebastiaan'*NumString(25))
print(five*'ages')

Any help is much appreciated. Thank you.

numstring.py
class NumString:
    def __init__(self, value):
        self.value = str(value)

    def __str__(self):
         return self.value

    def __int__(self):
        return int(self.value)

    def __float__(self):
        return float(self.value)

    def __add__(self, other):
        if '.' in self.value:
            return float(self) + other
        return int(self) + other

    def __radd__(self, other):
        return self + other

    def __iadd__(self, other):
        self.value = self + other
        return self.value  

    def __mul__ (self, other):     
        try:
            s1 = int(self.value)
        except ValueError:
            try:
                s1 = float(self.value)
            except ValueError:
                s1 = self.value
        try:
            o1 = int(other)
        except ValueError:
            try:
                o1 = float(other)
            except ValueError:
                o1 = other
        try:
            return s1*o1
        except TypeError:
            pass

    def __rmul__ (self, other):
        try:
            s1 = int(self.value)
        except ValueError:
            try:
                s1 = float(self.value)
            except ValueError:
                s1 = self.value
        try:
            o1 = int(other)
        except ValueError:
            try:
                o1 = float(other)
            except ValueError:
                o1 = other
        try:
            return o1*s1
        except TypeError:
            pass

2 Answers

Sebastiaan van Vugt
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Sebastiaan van Vugt
Python Development Techdegree Graduate 13,554 Points

Thank you very much for your Answer.

I finally got it to work along the lines of add/radd/iadd as you said which was real short. I still wonder though what multiplication this code could do which my previous code couldn't. All listed print examples multiply correctly.

Furthermore it surprised me that the simpler code along the line of add/radd:

    def __mul__(self, other):
        print('This came from __mul__()')
        if '.' in self.value:
            return float(self) * other
        return int(self) * other

    def __rmul__(self, other):
        print('This came from __rmul__()')
        return self * other

is able to deal with double floats. For example:


fourpointone = NumString(4.1) fivepointtwo = NumString(5.2)

print(fourpointone*fivepointtwo)


is calculated correctly, even though only the self component is checked for floats. From my debugging analysis I can see the following:


This came from mul() This came from float() This came from rmul() This came from mul() This came from float()


May I assume this means that the first (self) float is prepped correctly for multiplication through mul and float and that when the second float cannot be dealt with in mul it automatically is passed on to rmul which tries the component in mul again in reversed order basically resulting in both components being treated as self?

Steven Parker
Steven Parker
230,250 Points

Any time you do math with "self" it causes the appropriate internal conversion function to be applied.

Steven Parker
Steven Parker
230,250 Points

I didn't analyze the exact cause the problem, but at first glance these appear to be way more complicated than necessary for the challenge.

Try using the add/radd/iadd functions as models to create your mul/rmul/imul code and see if you get better results.

Also for the challenge you'll only need to expand the class definition, you won't need to create instances, call functions, or print anything.