I'm trying to implement Shamir Secret Sharing Sceme in python,i need to ask the user for a password and then obtain a hash code with sha256, but when I try to use that as a parameter for AES it says that the length of the key must be 16, 24 or 32 bits, doesn´t sha256 return a 32 byte string?
Here's my code:
import getpass
import hashlib
import random
import operator
from functools import reduce
import sys
import os
from Crypto.Cipher import AES
p= 208351617316091241234326746312124448251235562226470491514186331217050270460481
points= []
## Class Prime
#
# Class that represents integers modulo p, it is built from a non negative integer
# , comes with its own implementations of basic operations like sum, multiplication
# and division, the division is calculated ith the extended euclidean algorithm.
class Prime(object):
## The constructor
def __init__(self, n):
self.n = n % p
def __add__(self, other): return Prime(self.n + other.n)
def __sub__(self, other): return Prime(self.n - other.n)
def __mul__(self, other): return Prime(self.n * other.n)
def __pow__(self, x): return Prime(self.n**x)
def __truediv__(self, other): return self * other.inverse()
def __div__(self, other): return self * other.inverse()
def __neg__(self): return Prime(-self.n)
def __eq__(self, other): return isinstance(other, Prime) and self.n == other.n
def __abs__(self): return abs(self.n)
def __str__(self): return str(self.n)
def __divmod__(self, divisor):
q,r = divmod(self.n, divisor.n)
return (Prime(q), Prime(r))
def EuclideanAlgorithm(a, b):
if abs(b) > abs(a):
(x,y,d) = EuclideanAlgorithm(b, a)
return (y,x,d)
if abs(b) == 0:
return (1, 0, a)
x1, x2, y1, y2 = 0, 1, 1, 0
while abs(b) > 0:
q, r = divmod(a,b)
x = x2 - q*x1
y = y2 - q*y1
a, b, x2, x1, y2, y1 = b, r, x1, x, y1, y
return (x2, y2, a)
def inverse(self):
(x,y,d)= EuclideanAlgorithm(self.n, p)
return Prime(x)
## Class Polynomial
#
# Class that represents a polynomial, it is built from a list of coefficients
# comes with a call method to evaluate the polynomial in a value "x", and has
# a reduced lagrange method that gets the constant value of a polynomial from
# a set of points
class Polynomial(object):
## The constructor
def __init__(self, coefficients):
self.coeff= coefficients
def __call__(self, x):
n = 0
tmp = Prime(0)
for i in self.coeff:
tmp = tmp + (i*(x**n))
n += 1
return tmp
def lagrange(points):
product= functools.reduce(operator.mul, points, 1)
sum= 0
for x in points:
p= 1
for y in points:
if x!= y:
p= p*(x-y)
sum+= poly(x)/(-x*p)
return sum
## Ask the user for a password and gets its hash code with sha256
def password():
p= getpass.getpass()
h= hashlib.sha256(p)
s= h.hexdigest()
constant= int(s, 16)
return constant
## Makes a polynomial with random coefficients and a fixed constant value, and
# evaluates it with n random values an writes the results to a file.
# #param constant The constant value of the polynomial.
# #param evaluations The number of evaluations to be made.
# #param degree The degree of the polynomial.
# #param out_fileName The name of the file where the evaluations are going
# to be written.
# \pre The constant, evaluations and degree must be positive integers.
# \post If no error occurs then, the file whose name was passed will contain
# n evaluations of the polynomial.
def makeKeys(constant, evaluations, degree, out_fileName):
coeffs= []
coeffs.append(Prime(constant))
for x in range(1, degree):
randomc= random.randint(1, p - 1)
coeffs.append(Prime(randomc))
poly= Polynomial(coeffs)
file= open(out_fileName, "w")
for x in range(1, evaluations + 1):
randomi= random.randint(1, p - 1)
points.append(randomi)
e= poly(Prime(randomi))
file.write("(%d, %d)\n" % (randomi, e.n))
file.close()
def encrypt(key, in_fileName, out_fileName):
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_ECB, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt(ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_ECB, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
def decrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(ciphertext, key)
with open(file_name[:-4], 'wb') as fo:
fo.write(dec)
I cannot see the link between pasword and encrypt/decrypt functions but I supose password returns the key. In this case the key is an int that has 32 or 64 bits. Minimum for AES is 128 bits.
Try this:
def password():
p= getpass.getpass()
h= hashlib.sha256(p)
return h.digest()
Related
Now, in addition from my two previous posts ODE implements I try to refactro my code and fix some problems. And I decided, that logically create such classes: Solver,Problem.
So code for ODE_Solver and FE classes finally code and working.
# ODS.py
import numpy as np
class ODE_Solver(object):
def __init__(self, f):
if not callable(f):
raise TypeError('f is not %s, function' % type(f))
self.f = lambda u, x: np.asarray(f(u, x), float)
self.err_sch = None
def solver_st(self):
raise NotImplementedError
def err_st(self):
raise NotImplementedError
def set_initial_condition(self, u0):
if isinstance(u0, (float, int)):
self.neq = 1
u0 = float(u0)
else:
u0 = np.asarray(u0)
self.neq = u0.size
self.u0 = u0
try:
f0 = self.f(self.u0, 0)
except IndexError:
raise IndexError(
'index out of bounds f(u,x). correct index %s' % (str(range(self.neq))))
if f0.size != self.neq:
raise ValueError('f(u,x) returend %d elems, vector u has %d elems' % (f0.size, self.neq))
def solve(self, coord_points, terminate=None):
if terminate is None:
terminate = lambda u, x, step_no: False
if isinstance(coord_points, (float, int)):
raise TypeError('solve: x points not numpy array or numbers.')
self.x = np.asarray(coord_points)
if self.x.size <= 1:
raise ValueError('ODESolver.solve points of coords less than two')
n = self.x.size
if self.neq == 1: # ОДУ
self.u = np.zeros(n)
self.err_sch = np.zeros(n)
else:
self.u = np.zeros((n, self.neq))
self.err_sch = np.zeros((n, self.neq))
self.u[0] = self.u0
self.err_sch[0] = 0
for k in range(n - 1):
self.k = k
self.u[k + 1] = self.solver_st()
self.err_sch[k + 1] = self.err_st()
if terminate(self.u, self.x, self.k + 1):
break
return self.u[:k + 2], self.x[:k + 2]
# ES.py
from ODS import ODE_Solver
import numpy as np
class FE(ODE_Solver):
def solver_st(self):
u, f, k, x = self.u, self.f, self.k, self.x
dx = x[k + 1] - x[k]
u_new = u[k] + dx * f(u[k], x[k])
return u_new
def err_st(self):
u, f, k, x, err_sch = self.u, self.f, self.k, self.x, self.err_sch
dx = x[k + 1] - x[k]
err_sch = np.max(dx)**2
return err_sch
I try to implement class Problem (return ODE and get initial conditions)
import numpy as np
class Problem(object):
def __init__(self, u0, End):
self.u0 = np.asarray(u0)
self.End = End # end point of coords
def __call__(self, u, x):
return (u[1], u[2], u[3], u[4],
- 15 * u[4] - 90 * u[3] - 270 * u[2] - 405 * u[1] - 243 * u[0])
And code class Solver for call numerical scheme, plotting the final result, plot and evaluate error:
import numpy as np
import matplotlib as plt
import ES
import ODS
from ADS import ABM4
from ES import FE
from MLNS import MLN
from RKS import RK4
class Solver(object):
def __init__(self, problem, dx,
method=ES.FE): # choose FE scheme for tetsting
"""
"""
self.problem, self.dx = problem, dx
self.solver = method
#staticmethod
def choose_sch(type):
if type == 1:
method = FE
return method
elif type == 2:
method = RK4
return method
elif type == 3:
method = ABM4
return method
elif type == 4:
method = MLN
return method
else:
raise ValueError('not choose numerical scheme!')
def dsolve(self):
solver = self.method(self.problem)
solver.set_initial_condition(self.problem.u0)
n = int(round(self.problem.End / self.dx))
x_points = np.linspace(0, self.problem.End, n + 1)
self.u, self.x = solver.solve(x_points)
if solver.k + 1 == n:
self.plot()
raise ValueError('not converge this scheme,' % self.problem.End)
def plot(self):
plt.plot(self.x, self.u)
plt.show()
Now, when I call this Solver and Problem
import numpy as np
from ODE_Problem import Problem
from SLV_Prob import Solver
def test():
problem = Problem(u0=[0, 3, -9, -8, 0], End=5)
solver = Solver(problem, dx=0.1)
solver.dsolve()
solver.plot()
if __name__ == '__main__':
test()
I get the error:
Traceback (most recent call last):
File "C:\Fin_Proj_ODE\test2.py", line 14, in <module>
test()
File "C:\Fin_Proj_ODE\test2.py", line 9, in test
solver.dsolve()
File "C:\Fin_Proj_ODE\SLV_Prob.py", line 37, in dsolve
solver = self.method(self.problem)
AttributeError: 'Solver' object has no attribute 'method'
And I dont' understand and suppose what reason of this bug...
So, I have 2 questions for implement this Solver:
How to fix this bug?
How to correct rewrite def choose_sch(type):, that I could to call solver and send args type ( and depending on it, a specific numerical scheme will already be started)?
Question One:
Well, as the error states, your Solver class doesn't have an attribute called "method". Your attribute is actually "solver", so instead of calling
self.method(self.problem)
Try
self.solver(self.problem)
Question Two:
If I'm understanding you correctly, you want to know how you can call the choose_sch method from within the solver constructor and take in a type instead of a method directly. For that, simply do this:
class Solver(object):
def __init__(self, problem, dx, solver_type=1): # choose FE scheme for tetsting
"""
"""
self.problem, self.dx = problem, dx
self.solver = self._choose_sch(solver_type)
#staticmethod
def _choose_sch(solver_type):
methods = {1: FE, 2: RK4, 3: ABM4, 4: MLN}
if solver_type in methods:
return methods[solver_type]
else:
raise ValueError('not choose numerical scheme!')
The dictionary here is much better than the if statement for these kinds of tasks.
You can also alternatively not make _choose_ach a staticmethod if you don't need to call it from a static context and just make it set the solver directly.
I have a python code which implements cuckoo hashing.
I'm working on code for a hash table where collisions are corrected using cuckoo hashing. But it is taking a lot of time if there are more collisions.
I have used mmh3 family for hashing
so, is there a way to optimize this code and cuckoo hashing technique?
If yes kindly elaborate
from random import randint
import math
import mmh3
#parameters
from parameters import output_bits, number_of_hashes
mask_of_power_of_2 = 2 ** output_bits - 1
log_no_hashes = int(math.log(number_of_hashes) / math.log(2)) + 1
#The hash family used for Cuckoo hashing relies on the Murmur hash family (mmh3)
def location(seed, item):
'''
:param seed: a seed of a Murmur hash function
:param item: an integer
:return: Murmur_hash(item_left) xor item_right, where item = item_left || item_right
'''
item_left = item >> output_bits
item_right = item & mask_of_power_of_2
hash_item_left = mmh3.hash(str(item_left), seed, signed=False) >> (32 - output_bits)
return hash_item_left ^ item_right
def left_and_index(item, index):
'''
:param item: an integer
:param index: a log_no_hashes bits integer
:return: an integer represented as item_left || index
'''
return ((item >> (output_bits)) << (log_no_hashes)) + index
def extract_index(item_left_and_index):
'''
:param item_left_and_index: an integer represented as item_left || index
:return: index extracted
'''
return item_left_and_index & (2 ** log_no_hashes - 1)
def reconstruct_item(item_left_and_index, current_location, seed):
'''
:param item_left_and_index: an integer represented as item_left || index
:param current_location: the corresponding location, i.e. Murmur_hash(item_left) xor item_right
:param seed: the seed of the Murmur hash function
:return: the integer item
'''
item_left = item_left_and_index >> log_no_hashes
hashed_item_left = mmh3.hash(str(item_left), seed, signed=False) >> (32 - output_bits)
item_right = hashed_item_left ^ current_location
return (item_left << output_bits) + item_right
def rand_point(bound, i):
'''
:param bound: an integer
:param i: an integer less than bound
:return: a uniform integer from [0, bound - 1], distinct from i
'''
value = randint(0, bound - 1)
while (value == i):
value = randint(0, bound - 1)
return value
class Cuckoo():
def __init__(self, hash_seed):
self.number_of_bins = 2 ** output_bits
self.recursion_depth = int(8 * math.log(self.number_of_bins) / math.log(2))
self.data_structure = [None for j in range(self.number_of_bins)]
self.insert_index = randint(0, number_of_hashes - 1)
self.depth = 0
self.FAIL = 0
self.hash_seed = hash_seed
def insert(self, item): #item is an integer
current_location = location( self.hash_seed[self.insert_index], item)
current_item = self.data_structure[ current_location]
self.data_structure[ current_location ] = left_and_index(item, self.insert_index)
if (current_item == None):
self.insert_index = randint(0, number_of_hashes - 1)
self.depth = 0
else:
unwanted_index = extract_index(current_item)
self.insert_index = rand_point(number_of_hashes, unwanted_index)
if (self.depth < self.recursion_depth):
self.depth +=1
jumping_item = reconstruct_item(current_item, current_location, self.hash_seed[unwanted_index])
self.insert(jumping_item)
else:
self.FAIL = 1
Hi I am new to encryption algorithms and am a little confused by the terminology and what to choose for which situation. For now I don't need the most secure algorithm but it should have the following properties:
A shared secret key, that encrypts/decrypts the message (two way).
The Cipher should be the same if same text for encryption has been used.
I used the Fernet algorithm in Python, however the Ciphertext is always different. and therefore not suitable for my needs. Is there an algorithm similar to Fernet but without the Salt?
Assuming you're using the cryptography module (which you should): Instead of using generate_key(), build the key and pass it to the Fernet constructor.
Check this link for the precise example: https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet
Additionally, check https://www.crypto101.io/ if you haven't yet.
Actually there's no ready algorithm do what you're asking for "at lease that what I know".
But in the past I've wrote a GUI chat room with a real server and real clients in python.
And I've wrote a basic encryption/decryption algorithm to pass the data encrypted "like messages".
you can use it if you want cuz I've never used that server I made it just for fun ;).
The algorithm:
from cryptography.fernet import Fernet
CODES_KEY = b'LYsrKDiTRNJDm3g_h25GW0uyUzPTk8l8G02hcPM_d_U='
def encryption(msg):
'''
Encryption Func
'''
class RSA:
'''
RSA Encryption Func
'''
def __init__(self):
self.e = self.d = self.p = self.q = self.phi = 0
def __egcd(self, a, b):
if a == 0:
return (b, 0, 1)
g, y, x = self.__egcd(b % a, a)
return (g, x - (b // a) * y, y)
def __modinv(self, a, m):
g, x, _ = self.__egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
return x % m
def encrypt(self, m, key_pair=None):
'''
Encrypting Func
'''
if key_pair is None:
key_pair[0] = self.e
key_pair[1] = self.n
return pow(m, key_pair[0], key_pair[1])
def generate_keys(self, p, q, e=3):
'''
Generating Keys Func
'''
self.p = p
self.q = q
self.n = self.p * self.q
self.phi = (self.p - 1) * (self.q - 1)
self.e = e
self.d = self.__modinv(self.e, self.phi)
if self.phi % self.e == 0:
raise Exception('invalid values for p and q')
def get_public_key(self):
'''
Getting PublicKey Func
'''
return self.e, self.n
rsa = RSA()
# Two 1024-bit primes
rsa.generate_keys(17055899557196527525682810191339089909014331959812898993437334555169285087976951946809555356817674844913188193949144165887100694620944167618997411049745043243260854998720061941490491091205087788373487296637817044103762239946752241631032791287021875863785226376406279424552454153388492970310795447866569138481,
171994050316145327367864378293770397343246561147593187377005295591120640129800725892235968688434055779668692095961697434700708550594137135605048681344218643671046905252163983827396726536078773766353616572531688390937410451433665914394068509329532352022301339189851111636176939179510955519440490431177444857017)
int_message = []
for i in msg:
int_message.append(ord(i))
codes = []
for i in int_message:
codes.append(len(str(i)))
message = int(''.join([str(x) for x in int_message]))
# Encrypting
encrypted_message = rsa.encrypt(message, key_pair=rsa.get_public_key())
f = Fernet(CODES_KEY)
encrypted_codes = f.encrypt(str(codes).encode())
return encrypted_message, encrypted_codes
def decryption(msg, codes):
'''
Decryption Func
'''
class RSA:
'''
RSA Decryption Func
'''
def __init__(self):
self.e = self.d = self.p = self.q = self.phi = 0
def __egcd(self, a, b):
if a == 0:
return (b, a, 1)
g, y, x = self.__egcd(b % a, a)
return (g, x - (b // a) * y, y)
def __modinv(self, a, m):
g, x, _ = self.__egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
return x % m
def decrypt(self, c, key_pair=None):
'''
Decrypting Func
'''
if key_pair is None:
key_pair[0] = self.d
key_pair[1] = self.n
return pow(c, key_pair[0], key_pair[1])
def generate_keys(self, p, q, e=3):
'''
Generating Keys Func
'''
self.p = p
self.q = q
self.n = self.p * self.q
self.phi = (self.p - 1) * (self.q - 1)
self.e = e
self.d = self.__modinv(self.e, self.phi)
if self.phi % self.e == 0:
raise Exception('invalid values for p and q')
def get_private_key(self):
'''
Getting Private Key Func
'''
return self.d, self.n
rsa = RSA()
# Two 1024-bit primes
rsa.generate_keys(17055899557196527525682810191339089909014331959812898993437334555169285087976951946809555356817674844913188193949144165887100694620944167618997411049745043243260854998720061941490491091205087788373487296637817044103762239946752241631032791287021875863785226376406279424552454153388492970310795447866569138481,
171994050316145327367864378293770397343246561147593187377005295591120640129800725892235968688434055779668692095961697434700708550594137135605048681344218643671046905252163983827396726536078773766353616572531688390937410451433665914394068509329532352022301339189851111636176939179510955519440490431177444857017)
# Decrypting
f = Fernet(CODES_KEY)
# set_trace()
decrypted_message = str(rsa.decrypt(int(msg), key_pair=rsa.get_private_key()))
decrypted_codes = f.decrypt(codes).decode()
decrypted_message = list(decrypted_message)
original_codes = []
for i in decrypted_codes:
if i not in ['[', ']', ',', ' ']:
original_codes.append(int(i))
original_message = ""
for _, value in enumerate(original_codes):
handler = ""
for i in decrypted_message[:value]:
handler += i
original_message += chr(int(handler))
decrypted_message = decrypted_message[value:]
return original_message
def main():
message = "Hi, This is a secret message"
encrypted_message, encrypted_codes = encryption(message)
decrypted_message = decryption(encrypted_message, encrypted_codes)
print(decrypted_message)
if __name__ == '__main__':
main()
Sorry if it's a mess but I'm just 17 years old bro :) !
Maybe you can optimize it more I've wrote this when i was new to python.
you can always generate new "CODES_KEY" by running this in python:
from cryptography.fernet import Fernet
f = Fernet
print(f.generate_key())
EDIT: I wrote this as an RSA but then changed the code, this is why it's named RSA but it's not :)
I'm trying to represent a matrix of complex numbers using 2 real value matrices (in Pytorch, but using numpy here just for illustrative purposes).
Currently I'm doing it this way:
import numpy as np
# represent real
X = np.random.randn(10,10)
# represent imaginary
I = np.random.randn(10,10)
# build complex matrix using the identity
real = np.concatenate([X, -I], axis=-1)
img = np.concatenate([I, X], axis=-1)
complex_W = np.concatenate([real, img,], axis=0)
# is complex_W now correctly represented??
Could I also do it this way?
# represent real
X = np.random.randn(10,10)
# represent imaginary
I = np.random.randn(10,10)
complex_W = X + I
You can implement complex ndarray data structure using numpy arrays. You may want to store real part in one variable of the datasture and complex in anthor variable. Python provides a way to overload some operators including +, -, *, /. E.g I've the following class implements complex data structure with three operators(+, - , *)
class ComplexNDArray(object):
def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary
#property
def real(self):
return self.__real
#real.setter
def real(self, value):
if type(value) == np.ndarray:
self.__real = value
elif isinstance(value, (int, float, list, tuple)):
self.__real = np.array(value)
else:
raise ValueError("Unsupported type value:%s" % (str(type(value))))
#property
def imaginary(self):
return self.__imaginary
#imaginary.setter
def imaginary(self, value):
if type(value) == np.ndarray:
self.__imaginary = value
elif isinstance(value, (int, float, list, tuple)):
self.__imaginary = np.array(value)
else:
raise ValueError("Unsupported type value:%s" % (str(type(value))))
def __add__(self, other):
real = self.real + other.real
imaginary = self.imaginary + other.imaginary
return ComplexNDArray(real, imaginary)
def __sub__(self, other):
real = self.real - other.real
imaginary = self.imaginary - other.imaginary
return ComplexNDArray(real, imaginary)
def __mul__(self, other):
real = self.real * other.real - self.imaginary * other.imaginary
imaginary = self.real * other.imaginary + self.imaginary * other.real
return ComplexNDArray(real, imaginary)
def __str__(self):
return str(self.real) + "+"+str(self.imaginary)+"i"
Now you can use this data structure to do some operations.
a = np.array([1, 2,3])
b = np.array([4, 5, 1])
c = np.array([4, 7,3])
d = np.array([5, 1,7])
cmplx = ComplexNDArray(a, b)
cmplx2 = ComplexNDArray(c, d)
print(cmplx) # [1 2 3]+[4 5 1]i
print(cmplx2) # [4 7 3]+[5 1 7]i
print(cmplx+cmplx2) # [5 9 6]+[9 6 8]i
print(cmplx-cmplx2) # [-3 -5 0]+[-1 4 -6]i
print(cmplx*cmplx2) # [-16 9 2]+[21 37 24]i
I'm currently writing a code to perform Gaussian elimination in MATLAB and then write out the code needed to generate a LaTex file showing all the steps. A lot of the times when I do Gaussian elimination the answers start turning into Fractions. So I thought as a nice learning exercise for classes in Matlab that I would write a Fraction class. But I have no clue how to overload operators and frankly Mathwork's documentation wasn't helpful.
classdef Fraction
properties
numer
denom
end
methods
function a = Fraction(numer,denom)
a.denom = denom;
a.numer = numer;
end
function r = mtimes(a,b)
r = Fraction(a.numer*b.numer,a.denom*b.demon);
end
function r = plus(a,b)
c = a.numer*b.denom+a.denom*b.numer;
d = a.denom*b.denom;
r = Fraction(c,d);
function r = minus(a,b)
c = a.numer*b.denom-a.denom*b.numer;
d = a.denom*b.denom;
r = Fraction(c,d);
end
function r = mrdivide(a,b)
r = Fraction(a.numer*b.denom,a.denom*b.numer);
end
function b = reduceFrac(a)
x = a.numer;
y = b.denom;
while y ~= 0
x = y;
y = mod(x,y);
end
b =Fraction(a.numer/x, a.denom/x)
end
end
end
The plus operator works but the other three do not. Does any one have any ideas? Also how do I call my method reduceFrac?
Fraction.reduceFrac(Fraction(2.4))
I thought that the code above would work, but it didn't. Below is the python version of what I am trying to acheive.
Fraction.py
class Fraction(object):
"""Fraction class
Attributes:
numer: the numerator of the fraction.
denom: the denominator of the fraction.
"""
def __init__(self, numer, denom):
"""Initializes the Fraction class
Sets the inital numer and denom for the
fraction class.
Args:
numer: Top number of the Fraction
denom: Bottom number of the Fraction
Returns:
None
Raises:
None
"""
self.numer = numer
self.denom = denom
def __str__(self):
"""function call along with the print command
Args:
None
Returns:
String: numer / denom.
Raises:
None
"""
return str(self.numer) + '/' + str(self.denom)
def get_numer(self):
return self.numer
def set_numer(self, numer):
self.numer = numer
def get_denom(self):
return self.denom
def set_denom(self, denom):
self.denom = denom
def __add__(self, other):
numer = self.numer*other.denom+other.numer*self.denom
denom = self.denom*other.denom
return Fraction.reduceFrac(Fraction(numer,denom))
def __div__(self, other):
numer = self.numer*other.denom
denom = self.denom*other.numer
return Fraction.reduceFrac(Fraction(numer,denom))
def __sub__(self, other):
numer = self.numer*other.denom-other.numer*self.denom
denom = self.denom*other.denom
return Fraction.reduceFrac(Fraction(numer,denom))
def __mul__(self, other):
numer = self.numer*other.numer
denom = self.denom*other.denom
return Fraction.reduceFrac(Fraction(numer,denom))
def reduceFrac(self):
x = self.numer
y = self.denom
while y != 0:
(x, y) = (y, x % y)
return Fraction(self.numer/x, self.denom/x)
if __name__ == "__main__":
v = Fraction(4,3)
g = Fraction(7,8)
r = Fraction(4,8)
a = v + g
print a
s = v - g
print s
d = v / g
print d
m = v * g
print m
f = Fraction.reduceFrac(r)
print f
Your plus function misses an end