Implementing fractions in python - python

I tried to implement fractions using classes in python, but when I ran it,
it showed the error 'function gcd is not defined'. I can't seem to figure out how.
However, when I defined GCD outside the class it was working perfectly fine.
class frac:
def gcd(a, b):
if(b == 0):
return a
else:
return gcd(b, a%b)
def __init__(self, numer, denom):
if(denom == 0):
raise Exception("WTF")
else:
self.numer = numer
self.denom = denom
self.ratify()
def ratify(self):
g = gcd(self.numer, self.denom)
self.numer = self.numer/g
self.denom = self.denom/g
def add(self, b):
n,d = self.numer, self.denom
self.numer = n*b.denom + d*b.numer
self.denom = d*b.denom
self.ratify()
What is going wrong?

Your gcd method needs to look like:
def gcd(self, a, b):
if(b == 0):
return a
else:
return self.gcd(b, a%b)

Related

Using staticmethod to calculate fractions

I am doing a task where I have a class Fractions which contains functions as to how I can add, subtract, multiply and divide the fractions. I am having trouble creating the add function which will be adding 2 fractions and this function must use the staticmethod. This is the code that I have written so far:
class Fraction:
def __init__(self,num1=0,num2=0):
self.num1=num1
self.num2=num2
def __str__(self):
while self.num1>self.num2:
a = self.num1//self.num2
b = self.num1 % self.num2
if self.num2==1:
return "%s"%(self.num1)
elif self.num1 % self.num2==0:
return "%s"%(self.num1/self.num2)
else:
return "%s+%s|%s"%(a,b,self.num2)
if self.num1==0:
return "0"
elif self.num1 or self.num2 < 0 and self.num1==self.num2:
return "-1"
elif self.num2==1:
return "%s"%(self.num1)
elif self.num1==self.num2:
return "1"
else:
return "%s|%s"%(self.num1,self.num2)
#staticmethod
def add(a,b):
a=Fraction(n,d)
b=Fraction(num,den)
if a.d == b.den and a.n<a.d or b.num<b.den:
return "%s|%s"%(a.n+b.num,a.d)
elif a.d != b.den:
return "%s|%s"%((a.n*b.den)+(a.d*b.num),(a.d*b.den))
I am facing trouble in trouble in the add function and I do not know how to make the function work.
For example:
Fraction.add(Fraction(1,4),Fraction(2,4))
>>> 3|4
Fraction.add(Fraction(1,5),Fraction(6,7))
>>> 1 + 2|35
This is what the output should look like. Could anyone guide me through the add function and how I can improve it using the staticmethod
If the arguments a and b are already Fraction objects, then you would use the attributes from them directly in your method:
#staticmethod
def add(a,b):
if a.num2 == b.num2 and (a.num1 < a.num2 or b.num1 < b.num2):
return "%s|%s"%(a.num1 + b.num1, a.num2)
elif a.num2 != b.num2:
return "%s|%s"%((a.num1 * b.num2) + (a.num2 * b.num1), (a.num2 * b.num2))
There were also a missing parenthesis in the first if clause.

I don't know what is wrong with this python code

class FC():
def data(self, a, b):
self.n1 = a
self.n2 = b
def add(self):
return (self.n1 + self.n2)
>>> def pbnc(start, num):
pb = FC()
pb.data(start, start)
while (num > 0):
print(pb.add())
pb.data(pb.n2, pb.add())
num -= 1
>>> def pbnc(1, 10)
SyntaxError: invalid syntax
I'm currently learning 'Class' in python. And I can't find the wrong thing in this code. Is it wrong to use classes in other functions?
Appears to be a simple indentation error, this should be fine:
class FC():
def data(self, a, b):
self.n1 = a
self.n2 = b
def add(self):
return (self.n1 + self.n2)
def pbnc(self, start, num):
pb = FC()
pb.data(start, start)
while (num > 0):
print(pb.add())
pb.data(pb.n2, pb.add())
num -= 1
'''
# Uncomment this part if you want this method outside of the class
def pbnc(start, num):
pb = FC()
pb.data(start, start)
while (num > 0):
print(pb.add())
pb.data(pb.n2, pb.add())
num -= 1
'''

Updating object values in class

I have a question about how to return the update value of an object in a class and then use that in another function in the same class. Here is my old code.
class Vector:
def __init__(self, a):
self.a = a
assert type(self.a) == list
for i in self.a:
assert type(i) == int or type(i) == float
def dim(self):
return len(self.a)
def __getitem__(self, i):
assert i >= 1 and i <= self.dim()
return self.a[i-1]
def __setitem__(self, i, x):
assert i >= 1 and i <= self.dim()
self.a[i-1] = x
return self.a[i-1]
def __str__(self):
return 'Vector: ' + str(self.a)
def __add__(self, other):
assert type(other.a) == list and other.dim() == self.dim()
n = []
for j in range(self.dim()):
n.append(self.a[j]+other.a[j])
self.a = n
return self.a
so when i'm running this test case:
v1 = Vector([2, 3, 4])
v2 = Vector([1, 2, 3])
str(v1 + v2)
my output is '[3, 5, 7]' which means it is only following return self.a and not the __str__ function however i want my output to be 'Vector: [3, 5, 7]' as it should be following the __str__ function. I fixed this by returning Vector(self.a) in the __add__ function but i dont know why this works. Can anyone explain why that works, and why return self.a does not simply update the object value and run the __str__ function instead?
Note: Python uses following equivalent notations:
v[i] == v.__getitem__(i)
v[i] = x == v.__setitem__(i, x)
str(v) == v.__str__()
v + other == v.__add__(other)

Using a parameterized decorator in python

I am having difficulties understanding the concept of parameterized decorator and how it works. Could someone please explain how it works and what would the decorator base look like in the example below:
#base(10)
def sum(x,y):
return x+y
print(sum(1,2))
Code speaks more than a thousand words:
def int2base(x, base):
""" Converts int to string with given base representation.
Credit to #Alex Martelli on http://stackoverflow.com/questions/2267362/convert-integer-to-a-string-in-a-given-numeric-base-in-python"""
if x < 0: sign = -1
elif x == 0: return digs[0]
else: sign = 1
x *= sign
digits = []
while x:
digits.append(digs[x % base])
x //= base
if sign < 0:
digits.append('-')
digits.reverse()
return ''.join(digits)
def base(num):
def decorator(func):
def wrapper(*args):
return int2base(func(*args), num)
return wrapper
return decorator
def my_sum(num1, num2):
return num1 + num2
# using decorator syntax
#base(2)
def my_sum2(num1, num2):
return num1 + num2
print(my_sum(1,2))
print(my_sum2(1,2))
# decorating manually
decorator = base(2) # base acts kinda like factory method
my_sum2_manual = decorator(my_sum)
print(my_sum2_manual(1,2))

How to invoke some method during the initialising process of an instance in Python

I'm new to Python,
After initialising an instance f of class Fraction, I want the method reduce has been invoked, so the print result is after reduced
f = Fraction(3,6)
print f #=> 1/2 not 3/6
here's the code:
class Fraction(object):
'''Define a fraction type'''
def __init__(self, num=0, denom=1):
'''Create a new Fraction with numerator num and denominator demon'''
self.numerator = num
if denom != 0:
self.denominator = denom
else:
raise ZeroDivisionError
def reduce(self):
gcd = findgcd(self.numerator, self.denominator)
self.numerator /= gcd
self.denominator /= gcd
def findgcd(self, x, y):
gcd = None
min_number = min(x, y)
for i in range(min_number, 1, -1):
if x % i == 0 and y % i == 0:
gcd = i
return gcd
def __repr__(self):
return "{0}/{1}".format(self.numerator, self.denominator)
What prevent you from calling self.reduce() at the end of __init__ method?
You have two problems:
you need to call self.reduce() in your constructor __init__ to have method reduce() invoked during the instantiation phase.
you also need to change:
def reduce(self):
gcd = findgcd(self.numerator, self.denominator)
to:
def reduce(self):
gcd = self.findgcd(self.numerator, self.denominator)
because otherwise your instance will not be able to find findgcd.
The following code will fix your problem:
class Fraction(object):
'''Define a fraction type'''
def __init__(self, num=0, denom=1):
'''Create a new Fraction with numerator num and denominator demon'''
self.numerator = num
if denom != 0:
self.denominator = denom
else:
raise ZeroDivisionError
self.reduce()
def reduce(self):
gcd = self.findgcd(self.numerator, self.denominator)
self.numerator /= gcd
self.denominator /= gcd
def findgcd(self, x, y):
gcd = None
min_number = min(x, y)
for i in range(min_number, 1, -1):
if x % i == 0 and y % i == 0:
gcd = i
return gcd
def __repr__(self):
return "{0}/{1}".format(self.numerator, self.denominator)
>>>> f = Fraction(3,6)
>>>> f
1/2

Categories