How to use __mul__ in a class named Fraction - python

How do I make multiplication work with my class Fraction?
class Fraction(object):
def __init__(self, num, den):
self.num = num
self.den = den
def resolve(self):
#a = 2
#b = 6
#c = 2
#d = 5
self.num = self.num / other.num
self.den = self.den / other.den
return self
def __str__(self):
return "%d/%d" %(self.num, self.den)
def __mul__(self, other):
den = self.den * other.num
num = self.num * other.den
return (Fraction(self.num * other.num, self.den * other.den))
print('Multiplication:', Fraction.__mul__(2, 6))
This is the output:
Traceback (most recent call last):
File "app.py", line 43, in <module>
print('Multiplication:', Fraction.__mul__(2, 6))
File "app.py", line 27, in __mul__
den = self.den * other.num
AttributeError: 'int' object has no attribute 'den'

Try this
f1 = Fraction(1, 2)
f2 = Fraction(2, 3)
print(f1 * f2)
Here I'm
Creating an object f1 of class Fraction this is 1/2
Similarly f2 which is 2/3
Now f1 * f2 automatically calls the dunder method __mul__ of f1 with f2 as the other argument
So you should see the expected Fraction object getting printed
PS: The reason why you're getting the AttributeError is because, __mul__ expects Fraction objects to be passed - while you are passing ints

Related

i cant seem to know how to transform a Method in a class

here is my code
: https://i.stack.imgur.com/FOGQ8.png
I don't know how to transform the self.weekly_salary into a float so i can multiply
it by another number in self.monthly_salary
class Employee:
weeks_in_month = 4
def __init__(self,w,wd):
self.wage = w
self.work_days = wd
def weekly_salary(self):
return self.wage*8*self.work_days
def monthly_salary(self):
return self.weeks_in_month *self.weekly_salary
def yearly_salary(self):
return self.monthly_salary*12
Joe = Employee(13.5,4)
I have tried using __int__ or __float__ on the method but it all comes back as an error
please help i am still a newbie
class Employee:
weeks_in_month = 4
def __init__(self, w, wd):
self.wage = w
self.work_days = wd
def month_in_year(self):
return 12
def weekly_salary(self):
#print('Weekly salary', self.wage * 8 * self.work_days)
return float(self.wage * 8 * self.work_days)
def monthly_salary(self):
#print('Monthly Salary',self.weeks_in_month * self.weekly_salary())
return float(self.weeks_in_month * self.weekly_salary())
def yearly_salary(self):
print('Yearly Salary', self.monthly_salary() * self.month_in_year())
return self.monthly_salary() * 12
Joe = Employee(13.5, 4)
Joe.yearly_salary()
You forgot to call self.monthly_salary() instead you tried to subtract an int with a method directly which gives typeerror

Name "function name" is not defined

I've been attempting to complete one of my subjects for the OOP, but I couldn't manage to figure out what's wrong with the definition of my functions. I'm a newbie in this language, already searched the forums but I couldn't find anything useful.
Error message:
Traceback (most recent call last):
File "/home/main.py", line 44, in
add(x, y)
NameError: name 'add' is not defined
This is the program I wrote.
class Complex(object):
def __init__(self, r = 0, i = 0):
self.r = r
self.i = i
def __str__ (self):
return "%s + i%s" % (self.r, self.i)
def add (self, other):
summ = Complex()
summ.r = self.r + other.r
summ.i = self.i + other.i
return "Sum is %d" % summ
def dif (self, other):
dif = Complex()
dif.r = self.r - other.r
dif.i = self.i - other.i
return dif
def multiply (self, other):
multiply = Complex()
multiply.r = self.r * other.r
multiply.i = self.i * other.i
return "%d" % (-1 * multiply.r * multiply.i)
def divide (self, other):
divide = Complex()
divide.r = self.r / other.r
divide.i = self.i / other.i
return "%d" % (divide.r / divide.i)
x = Complex()
y = Complex()
x.r = int(input("Type in real part of x: \n"))
x.i = int(input("Type in imaginary of x: \n"))
print (x, "\n")
y.r = int(input("Type in real part of y: \n"))
y.i = int(input("Type in imaginary of y: \n"))
print (y, "\n")
add(x, y)
The add() function is a member of the Complex class but you are calling it on its own.
You need to call it like this
x.add(y)
When a function is a member of a class like below:
class Complex(object):
def add (self, other):
# Do stuff
The object the function is called on automatically gets passed as self.
So if you call x.add(y), self will be x and other will be y.
If add is a method of your class Complex, then you must write x.add(y) instead of add(x, y).
I know that it is confusing in Python. You need always to apply the "self" as first argument of a method, although it is not an argument, but the object whose method you call.

Python Quadratic Equation Class

I am currently creating a class in python to make a quadratic equation. I wrote down a discriminant function within the class, and I'm trying to call on it within the roots function, however, I'm not sure how to do it for certain. I am getting an attribute error.
AttributeError: 'QuadraticEquation' object has no attribute 'discrimiant'
def discriminant(self):
return ((self.b)**2) - (4 * self.a * self.c)
def root1(self):
if self.discrimiant() < 0:
return None
else:
return (-self.b + math.sqrt(self.discriminant())) / (2 * self.a)
def root2(self):
if self.discrimiant() < 0:
return None
else:
return (-self.b - math.sqrt(self.discriminant())) / (2 * self.a)
There is a spelling mistake in your code. discriminant, not discrimiant. Here is a working code -
class QuadraticEquation:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def discriminant(self):
return ((self.b)**2) - (4 * self.a * self.c)
def root1(self):
if self.discriminant() < 0:
return None
else:
return (-self.b + math.sqrt(self.discriminant())) / (2 * self.a)
def root2(self):
if self.discriminant() < 0:
return None
else:
return (-self.b - math.sqrt(self.discriminant())) / (2 * self.a)
a = QuadraticEquation(1,2,3)
print a.root1()
print a.root2()
print a.discriminant()

Defining a function within a class in Python 2.7

I tried to add a pgdc function in the Fraction class in order to calculate the biggest common divided or a number pgdc ... The function should be recursive. However, I keep getting the following error:
Traceback (most recent call last):
File "C:/Users/jf/Desktop/Python-jEdit_v2/23_fraction.py", line 60, in <module>
p = a.plus(b)
File "C:/Users/jf/Desktop/Python-jEdit_v2/23_fraction.py", line 35, in plus
return resultat.simplifier()
File "C:/Users/jf/Desktop/Python-jEdit_v2/23_fraction.py", line 27, in simplifier
p = pgcd(self.num, self.den)
NameError: global name 'pgcd' is not defined
In addition,
I also got the following error for the simplifier : AttributeError: Fraction instance has no attribute 'simplifier'
Which, leave me puzzle, as I tried to add self.pgcd=pgcd and self.simplifier=simplifier
at various places and it still did not work well...
# -*- coding: utf-8 -*-
class Fraction():
# constructeur et attributs
def __init__(self, num = 0, den = 1):
self.num = num
if (den == 0):
erreur("Dénominateur nul") #fonction d'erreur
self.den = den
def __str__(self):
return str(self.num) + "/" + str(self.den)
def erreur(message):
print "Erreur: " + message
from sys import exit
exit()
def pgcd(a, b):
if a == b:
return a
if a > b:
return pgcd(a-b, b)
else:
return pgcd(a, b-a)
def simplifier(self):
p = pgcd(self.num, self.den)
self.num = self.num / p
self.den = self.den / p
return self
def plus(self, f):
resultat = Fraction(self.num * f.den + self.den * f.num, \
self.den * f.den)
return resultat.simplifier()
def moins(self, f):
resultat = Fraction(self.num * f.den - self.den * f.num, \
self.den * f.den)
if (resultat.num < 0):
# changer de signe avant de simplifier
resultat.num = - resultat.num
resultat = resultat.simplifier()
resultat.num = - resultat.num
return resultat
else:
return resultat.simplifier()
def fois(self, f):
resultat = Fraction(self.num * f.num, self.den * f.den)
return resultat.simplifier()
def div(self, f):
resultat = Fraction(self.num * f.den, self.den * f.num)
return resultat.simplifier()
#### CONSOLE ####
a = Fraction(5, 11)
b = Fraction(3, 7)
p = a.plus(b)
You need to declare self as a parameter of your function and use it when you want to recursively call pgcd:
def pgcd(self,a, b):
if a == b:
return a
if a > b:
return self.pgcd(a-b, b)
else:
return self.pgcd(a, b-a)
Also, call pgcd with self. on this line:
p = self.pgcd(self.num, self.den) #from pgcd(self.num, self.den)

Python language-center of a circle using OOP

class Point:
def __init__(self, initX, initY):
""" Create a new point at the given coordinates. """
self.x = initX
self.y = initY
def getX(self):
return self.x
def getY(self):
return self.y
def distanceFromOrigin(self):
return ((self.x ** 2) + (self.y ** 2))** 0.5
def __str__(self):
return "x=" + str(self.x) + ", y=" + str(self.y)
def get_line_to(self, target):
mx = (-target.x + self.x )
my = (-target.y + self.y)
grad=my/mx
c=-(grad*(self.x))+self.y
return grad
def halfway(self, target):
"""calculating midpoint"""
mx = (self.x + target.x) / 2
my = (self.y + target.y) / 2
return Point(mx, my)
def cencd(p1,p2,p3):
"""calculating the center of a circle"""
ma=(p2.getY-p1.getY)/(p2.getX-p1.getX)
mb=(p3.getY-p2.getY)/(p3.getX-p2.getX)
hw=p1.halfway(p2)
x=(ma*mb*(p1.getY-p3.getY)+mb*(p1.getX+p2.getX)-ma*(p2.getX+p3.getX))/2*(mb-ma)
ya=-(1/ma)*((x-hw.getX)+hw.getY)
return x,ya
"""defining the points for p1,p2 and p3"""
p = Point(5,5)
q = Point(6,-2)
r=Point(2,-4)
print(cencd(p,q,r))
I get this error message:SyntaxError: duplicate argument 'p1' in function definition on
Traceback (most recent call last):
File "python", line 45, in
File "python", line 34, in cencd
TypeError: unsupported operand type(s) for -: 'method' and 'method'
please assist.
"""working solution """"
ma=(p2.y-p1.y)/(p2.x-p1.x)
mb=(p3.y-p2.y)/(p3.x-p2.x)
hw=p1.halfway(p2)
x1=(ma*mb*(p1.y-p3.y)+mb*(p1.x+p2.x)-ma*(p2.x+p3.x))/(2*(mb-ma))
ya=-(1/ma)*((x1-hw.x))+hw.y
You don't need getters or setters in python nor is it pythonic to use them, you should access the attributes directly:
def cencd(p1, p2, p3):
"""calculating the center of a circle"""
ma = (p2.y - p1.y) / (p2.x - p1.x)
mb = (p3.y - p2.y) / (p3.x - p2.x)
hw = p1.halfway(p2)
x = (ma * mb * (p1.y - p3.y) + mb * (p1.x + p2.x) - ma * (p2.x + p3.x)) / 2 * (mb - ma)
ya = -(1 / ma) * ((x - hw.x) + hw.y)
return x, ya
Both getX and getY are methods in your code, not attributes. So you will need to call them using getX() and getY().
So ma=(p2.getY-p1.getY)/(p2.getX-p1.getX) becomes:
ma = (p2.getY()-p1.getY())/(p2.getX()-p1.getX())
And so on, the other code changes.
Otherwise, you can also define your methods as #property:
class Point:
...
...
#property
def getX(self):
return self.x
#property
def getY(self):
return self.y
...
And now you can access these as p1.getX and p2.getY and so on.
Note that the above #property decorator turns the method into a getter, which makes sense to use only with private variables (variables defined to start with _).
As such, since both x and y are normal attributes of your class, you can access them directly without using and property decorators or using getter methods, like p1.x and p2.y, as #Padraic points in his post.
As Padraic Cunningham said, we don't need getters or setters in Python, but as mu said we can make getters if we want, but normally they are used to get "fake" attributes that are actually computed from true attributes. For example, in the code below I've added a fake norm attribute to your Point class.
I've also added a few more double-underscore methods (aka dunder methods or magic methods) to your class. These methods are discussed in the official Python docs.
One of the most common dunder methods is __repr__() which should return a string that corresponds to how you create an instance of the class. This is especially handy when you're using a class in the interactive interpreter. FWIW, if a class doesn't define a __str__() method its __repr__() method will be used if you attempt to turn a class instance into a string. If a __repr__() method hasn't been defined a default one will be used.
The other dunder methods I've added make it easier to perform arithmetic operations on points; this can make code easier to write and to read. I think you'll agree that it makes the cencd() function a little clearer. (I'm not sure exactly what that function's supposed to do; I assume you've got the algebra correct :) ).
This code was tested on Python 2.6.6; it should run ok on Python 3 without modification.
#!/usr/bin/env python
''' Point class demo
From http://stackoverflow.com/q/28602056/4014959
Written by koseph, Padraic Cunningham, and PM 2Ring
2015.02.19
'''
from __future__ import print_function
from __future__ import division
class Point(object):
def __init__(self, initX, initY):
""" Create a new point at the given coordinates. """
self.x, self.y = initX, initY
#property
def norm(self):
return self.x ** 2 + self.y ** 2
def distance_from_origin(self):
return self.norm ** 0.5
def __repr__(self):
return 'Point({self.x}, {self.y})'.format(self=self)
def __str__(self):
return 'x={self.x}, y={self.y}'.format(self=self)
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __mul__(self, scale):
return Point(self.x * scale, self.y * scale)
__rmul__ = __mul__
def __neg__(self):
return -1 * self
def __sub__(self, other):
return self + -other
def weighted_mean(self, other, weight):
cweight = 1.0 - weight
x = cweight * self.x + weight * other.x
y = cweight * self.y + weight * other.y
return Point(x, y)
def halfway(self, other):
return self.weighted_mean(other, 0.5)
def cencd(p1, p2, p3):
""" Calculate the center of a circle """
a = p2 - p1
b = p3 - p2
ma = a.y / a.x
mb = b.y / b.x
hw = p1.halfway(p2)
x = ma * mb * (p1 - p3).y + mb * (p1 + p2).x - ma * (p2 + p3).x
x /= 2.0 * (mb - ma)
y = -(x - hw.x + hw.y) / ma
return Point(x, y)
p1 = Point(3, 4)
print(p1)
print('p1 is {0!r}, its norm is {1}'.format(p1, p1.norm))
print('and its distance from the origin is', p1.distance_from_origin(), end='\n\n')
p2 = Point(7, 2)
print('p2 is', repr(p2), end='\n\n')
print('p1 + p2 is', repr(p1 + p2))
print('p1 * 0.1 is', repr(p1 * 0.1))
print('p2 - p1 is', repr(p2 - p1), end='\n\n')
p3 = 4 * p1
print('p3 is', repr(p3), end='\n\n')
print('Weighted means from p1 to p3')
for i in range(5):
weight = i / 4.0
print('{0} {1:4.2f} {2!r}'.format(i, weight, p1.weighted_mean(p3, weight)))
print()
print('center of a circle for p1, p2, & p3:', repr(cencd(p1, p2, p3)))
output
x=3, y=4
p1 is Point(3, 4), its norm is 25
and its distance from the origin is 5.0
p2 is Point(7, 2)
p1 + p2 is Point(10, 6)
p1 * 0.1 is Point(0.3, 0.4)
p2 - p1 is Point(4, -2)
p3 is Point(12, 16)
Weighted means from p1 to p3
0 0.00 Point(3.0, 4.0)
1 0.25 Point(5.25, 7.0)
2 0.50 Point(7.5, 10.0)
3 0.75 Point(9.75, 13.0)
4 1.00 Point(12.0, 16.0)
center of a circle for p1, p2, & p3: Point(8.22727272727, 12.4545454545)

Categories