generic Number class refactoring? - python

I just made a generic number class.
this class is so simple, descriptions are below
from any ordered character list, make number class representing that ordered character list.
create_number_class("01") returns binary number class
create_number_class("0123456789") returns decimal number class
create_number_class("abcdefghij") return decimal number class but representing each digit as a alphabet.
belows is generic number class definition.
I think it is well-made class definition.
are there something needed improvement in that class definition?
thank you all. always.
ex)
ABC_Class = create_number_class("abc")
x = ABC_Class("baa")
y = ABC_Class("bbb")
print(x+y)
#output digits: abc, v: cbb, decimal_v: 22
below is class definition
def create_number_class(alphabet):
class temp(object):
digits = alphabet
def __init__(self, v):
self.v = v
self.decimal_v = self.to_decimal(self)
#staticmethod
def to_decimal(self):
r = 0
for i in range(0, len(self.v)):
r += len(temp.digits)**(len(self.v)-i-1)*(temp.digits.index(self.v[i]))
return r
#classmethod
def from_decimal(cls, decimal_v):
r = []
mod = len(temp.digits)
if decimal_v < mod:
return cls(temp.digits[decimal_v])
while True:
remainder = decimal_v % mod
r.append(remainder)
decimal_v = int((decimal_v - remainder)/ mod)
if decimal_v < mod:
r.append(decimal_v)
break
r = "".join(list(reversed([temp.digits[x] for x in r])))
#r = "".join(list(reversed([str(temp.digits.index(str(x))) for x in r])))
return cls(r)
def __add__(self, other):
return temp.from_decimal(self.decimal_v+other.decimal_v)
def __sub__(self, other):
return temp.from_decimal(self.decimal_v-other.decimal_v)
def __mul__(self, other):
return temp.from_decimal(self.decimal_v*other.decimal_v)
def __floordiv__(self, other):
return temp.from_decimal(self.decimal_v//other.decimal_v)
def __str__(self):
return "digits: {}, v: {}, decimal_v: {}".format(temp.digits, self.v, self.decimal_v)
def convert_to(self, new_class):
return new_class.from_decimal(self.decimal_v)
return temp
below are example
BinClass = create_number_class("01")
DecimalClass = create_number_class("0123456789")
x = BinClass("111")
x = BinClass("1000")
y = BinClass("10")
HexClass = create_number_class('0123456789ABCDEF')
x = HexClass('1')
y = HexClass('AA')
print(x+y)
print(x-y)
print(x*y)
print(x//y)
print(x.convert_to(DecimalClass))
isinstance(x, BinClass)

Related

Expected type tuple in function

My program implements a generic coerce_apply function that, given the name of an action and the two arguments as objects of types, units of measurement calculates and returns the result of the action on the arguments, by converting one of the objects to the type of the other object
Copy all the code to see the error that is in the key and I can not solve
class Centimeters(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Centimeters({0})'.format(self.val)
class Inches(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Inches({0})'.format(self.val)
class Feets(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Feets({0})'.format(self.val)
def Inches_to_Centimeters(C):
return Centimeters(C.Inches*2.54)
def add_Centimeters(s,o):
return Centimeters('%.20f' % (s.val + o.val))
def add_Inches(s,o):
return Inches('%.20f' % (s.val + o.val))
def add_Inches_Centimeters(i,c):
return add_Inches(i,centimeter_to_inche(c))
def add_Centimeters_Inches(c, i):
return add_Centimeters(c, inche_to_centimeter(i))
def type_tag(x):
return type_tag.tags[type(x)]
type_tag.tags = {Centimeters: 'cen', Inches: 'inc', Feets: 'fee'}
centimeter_to_inche = lambda x: Centimeters(x.val * 1/2.54)
inche_to_centimeter = lambda x: Inches(x.val * 2.54)
coercions = {('inc', 'cen'): inche_to_centimeter}
def coerce_apply(operator_name, x, y):
tx, ty = type_tag(x), type_tag(y)
if tx != ty:
if (tx, ty) in coercions:
tx, x = ty, coercions[(tx, ty)](x)
elif (ty, tx) in coercions:
ty, y = tx, coercions[(ty, tx)](y)
else:
return 'No coercion possible.'
assert tx == ty
key = (operator_name, tx)
return coerce_apply.implementations[key](x, y)
coerce_apply.implementations = {}
coerce_apply.implementations[('add', ('inc', 'cen'))] = add_Inches_Centimeters
print(coerce_apply('add',Inches(1),Centimeters(150)))
Your approach is convoluted - normally you use classes to combine data with methods to allow f.e. the Centimeter class to handle its own conversion and addition to other units.
You get
File "t.py", line 46, in <module>
print(coerce_apply('add',Inches(1),Centimeters(150)))
File "t.py", line 43, in coerce_apply
return coerce_apply.implementations[key](x, y)
KeyError: ('add', 'cen')
because you are missing the conversion to add centimeters to centimerters in your code.
You can fix it like so (I removed Feets):
class Centimeters(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Centimeters({0})'.format(self.val)
# enable self-addition by other centimeters
def __add__(self, other):
if not isinstance(other, Centimeters):
raise Exception("Bad __add__ call")
self.val += other.val
return Centimeters(self.val + other.val)
class Inches(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Inches({0})'.format(self.val)
# enable self-addition by other Inches
def __add__(self, other):
if not isinstance(other, Inches):
raise Exception("Bad __add__ call")
return Inches(self.val + other.val)
def Inches_to_Centimeters(C):
return Centimeters(C.Inches*2.54)
def add_Centimeters(s,o):
return Centimeters('%.20f' % (s.val + o.val))
def add_Inches(s,o):
return Inches('%.20f' % (s.val + o.val))
def add_Inches_Centimeters(i,c):
return add_Inches(i,centimeter_to_inche(c))
def add_Centimeters_Inches(c, i):
return add_Centimeters(c, inche_to_centimeter(i))
def type_tag(x):
return type_tag.tags[type(x)]
type_tag.tags = {Centimeters: 'cen', Inches: 'inc', Feets: 'fee'}
centimeter_to_inche = lambda x: Centimeters(x.val * 1/2.54)
inche_to_centimeter = lambda x: Inches(x.val * 2.54)
coercions = {('inc', 'cen'): inche_to_centimeter}
def coerce_apply(operator_name, x, y):
tx, ty = type_tag(x), type_tag(y)
if tx != ty:
if (tx, ty) in coercions:
tx, x = ty, coercions[(tx, ty)](x)
elif (ty, tx) in coercions:
ty, y = tx, coercions[(ty, tx)](y)
else:
return 'No coercion possible.'
assert tx == ty
key = (operator_name, (tx,ty))
return coerce_apply.implementations[key](x, y)
coerce_apply.implementations = {}
coerce_apply.implementations[('add', ('inc', 'cen'))] = add_Inches_Centimeters
# add self-addition via classes __add__ method to "conversion"
coerce_apply.implementations[('add', ('cen', 'cen'))] = Centimeters.__add__
print(coerce_apply('add',Inches(1),Centimeters(150)))
Output:
Centimeters(152.54)

A* algorithm TypeError: cannot unpack non-iterable int object

This is the python code which uses A* algorithm for finding solution for 8 puzzle problems, I got some error messages, how can I fix it?(The error message is under the code)
There are several object-oriented programming concepts for Problems class, Node class that are implemented to express the problem solution search that you need to understand in order to make the Python program complete. The priority queue is to make the nodes to be explored to be sorted according to their f-evaluation function score and return the min one as the first node to be searched next.
There is also a memorize function to memorize the heuristic value of state as a look-up table so that you don’t need to calculate the redundant computing of heuristic estimation value, so you can ignore it at this point if you don’t understand.
The components you need to implement is to make the abstract part of the program realizable for 8 -puzzle with the successor methods attached to a problem class which consists of initial state and goal state. Make sure the program can run correctly to generate the solution sequence that move the empty tile so that the 8-puzzle can move "Up", "Down", "Left", "Right", from initial state to goal state.
import math
infinity = math.inf
from itertools import chain
import numpy as np
import bisect
class memoize:
def __init__(self, f, memo={}):
self.f = f
self.memo = {}
def __call__(self, *args):
if not str(args) in self.memo:
self.memo[str(args)] = self.f(*args)
return self.memo[str(args)]
def coordinate(state):
index_state = {}
index = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]
for i in range(len(state)):
index_state[state[i]] = index[i]
return index_state
def getInvCount(arr):
inv_count = 0
empty_value = -1
for i in range(0, 9):
for j in range(i + 1, 9):
if arr[j] != empty_value and arr[i] != empty_value and arr[i] > arr[j]:
inv_count += 1
return inv_count
def isSolvable(puzzle) :
inv_count = getInvCount([j for sub in puzzle for j in sub])
return (inv_count % 2 == 0)
def linear(state):
return sum([1 if state[i] != goal[i] else 0 for i in range(9)])
#memoize
def manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = abs(index_goal[i][j] - index_state[i][j]) + mhd
return mhd
#memoize
def sqrt_manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = (index_goal[i][j] - index_state[i][j])**2 + mhd
return math.sqrt(mhd)
#memoize
def max_heuristic(state):
score1 = manhattan(state)
score2 = linear(state)
return max(score1, score2)
class PriorityQueueElmt:
def __init__(self,val,e):
self.val = val
self.e = e
def __lt__(self,other):
return self.val < other.val
def value(self):
return self.val
def elem(self):
return self.e
class Queue:
def __init__(self):
pass
def extend(self, items):
for item in items: self.append(item)
class PriorityQueue(Queue):
def __init__(self, order=min, f=None):
self.A=[]
self.order=order
self.f=f
def append(self, item):
queueElmt = PriorityQueueElmt(self.f(item),item)
bisect.insort(self.A, queueElmt)
def __len__(self):
return len(self.A)
def pop(self):
if self.order == min:
return self.A.pop(0).elem()
else:
return self.A.pop().elem()
# Heuristics for 8 Puzzle Problem
class Problem:
def __init__(self, initial, goal=None):
self.initial = initial; self.goal = goal
def successor(self, state):
reachable = []
def get_key(val):
for key, value in index_state.items():
if val == value:
return key
return -1
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state
index_state = coordinate(state)
zero_position = index_state[0]
move_pair = {"left":[zero_position[0], zero_position[1] - 1],
"right":[zero_position[0], zero_position[1] + 1],
"up":[zero_position[0] - 1, zero_position[1]],
"down":[zero_position[0] + 1, zero_position[1]]
}
for action, position in move_pair.items():
#print(action, position)
if get_key(position) != -1:
reachable.append((action, candidate(state, position)))
#print(reachable)
return reachable
def goal_test(self, state):
return state == self.goal
def path_cost(self, c, state1, action, state2):
return c + 1
def value(self):
abstract
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0, depth =0):
self.parent = parent
if parent:
self.depth = parent.depth + 1
else:
self.depth = 0
self.path_cost = path_cost
self.state = state
if action:
self.action = action
else: self.action = "init"
def __repr__(self):
return "Node state:\n " + str(np.array(self.state).reshape(3,3)) +"\n -> action: " + self.action + "\n -> depth: " + str(self.depth)
def path(self):
x, result = self, [self]
while x.parent:
result.append(x.parent)
x = x.parent
return result
def expand(self, problem):
for (act,n) in problem.successor(self.state):
if n not in [node.state for node in self.path()]:
yield Node(n, self, act,
problem.path_cost(self.path_cost, self.state, act, n))
def graph_search(problem, fringe):
closed = {}
fringe.append(Node(problem.initial,depth=0))
while fringe:
node = fringe.pop()
if problem.goal_test(node.state):
return node
if str(node.state) not in closed:
closed[str(node.state)] = True
fringe.extend(node.expand(problem))
return None
def best_first_graph_search(problem, f):
return graph_search(problem, PriorityQueue(min, f))
def astar_search(problem, h = None):
h = h or problem.h
def f(n):
return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
return best_first_graph_search(problem, f)
def print_path(path, method):
print("*" * 30)
print("\nPath: (%s distance)" % method)
for i in range(len(path)-1, -1, -1):
print("-" * 15)
print(path[i])
goal = [1, 2, 3, 4, 5, 6, 7, 8, 0]
# Solving the puzzle
puzzle = [7, 2, 4, 5, 0, 6, 8, 3, 1]
if(isSolvable(np.array(puzzle).reshape(3,3))): # even true
# checks whether the initialized configuration is solvable or not
print("Solvable!")
problem = Problem(puzzle,goal)
path = astar_search(problem, manhattan).path()
print_path(path, "manhattan")
path = astar_search(problem, linear).path()
print_path(path, "linear")
path = astar_search(problem, sqrt_manhattan).path()
print_path(path, "sqrt_manhattan")
path = astar_search(problem, max_heuristic).path()
print_path(path, "max_heuristic")
else :
print("Not Solvable!") # non-even false
TypeError Traceback (most recent call last)
<ipython-input-124-2a60ddc8c009> in <module>
9 problem = Problem(puzzle,goal)
10
---> 11 path = astar_search(problem, manhattan).path()
12 print_path(path, "manhattan")
13
<ipython-input-123-caa97275712e> in astar_search(problem, h)
18 def f(n):
19 return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
---> 20 return best_first_graph_search(problem, f)
21
22 def print_path(path, method):
<ipython-input-123-caa97275712e> in best_first_graph_search(problem, f)
12
13 def best_first_graph_search(problem, f):
---> 14 return graph_search(problem, PriorityQueue(min, f))
15
16 def astar_search(problem, h = None):
<ipython-input-123-caa97275712e> in graph_search(problem, fringe)
8 if str(node.state) not in closed:
9 closed[str(node.state)] = True
---> 10 fringe.extend(node.expand(problem))
11 return None
12
<ipython-input-121-e5a968bd54f0> in extend(self, items)
18
19 def extend(self, items):
---> 20 for item in items: self.append(item)
21
22 class PriorityQueue(Queue):
<ipython-input-122-db21613469b9> in expand(self, problem)
69
70 def expand(self, problem):
---> 71 for (act,n) in problem.successor(self.state):
72 if n not in [node.state for node in self.path()]:
73 yield Node(n, self, act,
TypeError: cannot unpack non-iterable int object
I got some error messages, how can I fix it?
There is one error message, The pieces of codes you get in the error message are the stack trace, which might help you to know how the execution got at the final point where the error occurred. In this case that is not so important. The essence of the error is this:
for (act,n) in problem.successor(self.state)
TypeError: cannot unpack non-iterable int object
So this means that the successor method returned an int instead of a list.
Looking at the code for successor, I notice that it intends to return a list called reachable, but there is a return statement right in the middle of the code, leaving the largest part of that code unexecuted (so-called "dead code"):
return state
This statement makes no sense where it is positioned. It seems to be an indentation problem: that return belongs inside the function just above it, like this:
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state # <-- indentation!

Is there any method like divide by or multiply by in python range()?

for java, we can do:
for(int i=100; i>2 ; i=i/2){things to execute}
but what if in python?
is there anything like
for i in range(100:2:something)
could solve this problem?
If you need something simple which you can have at hand at several places, you can create a generator function:
def range_divide(start, end, denominator): # TODO: Think for a better name!
value = start
while value > end:
yield value
value /= denominator
and then do
for value in range_divide(100, 2, 2):
# do_stuff
You could even flexibilize this with
def range_flexible(start, end, action):
value = start
while value > end:
yield value
value = action(value)
and do
for value in range_flexible(100, 2, lambda x: x/2):
# do_stuff
or even
def for_loop(start, cont_condition, action):
value = start
while cont_condition(value):
yield value
value = action(value)
for value in for_loop(100, lambda x: x > 2, lambda x: x/2):
# do_stuff
There isn't by using a range, you could prepopulate a list and iterate over that but you'd be better off using a while loop.
i = 100
while i > 2:
...
i = i / 2
If you want it to look more like a java (or C) for loop, you can define a function that will process the parameters as a string in the C style (at the expense of execution speed):
cachedCFor = dict()
def cFor(params):
if params in cachedCFor: return cachedCFor[params]()
setup,condition,step = [ p.strip() for p in params.split(";") ]
varName = setup.split("=",1)[0].strip()
fn = dict()
code = f"""
def iterator():
{setup}
while {condition}:
yield {varName}
{step}
"""
exec(code,{},fn)
cachedCFor[params] = fn["iterator"]
return fn["iterator"]()
for i in cFor("i=100;i>2;i=i/2"):
print(i)
100
50.0
25.0
12.5
6.25
3.125
Note that the i variable in the string parameter is internal to the iterator and is not accessible within the for loop's code. We could have written for i in cFor("x=100;x>2;x=x/2") and still use i within the loop
That being said, I would still suggest that you embrace Python's way of doing things and not try to reproduce other language's syntax (i.e. use a while statement in this particular case)
for example:
x = 100
while x > 2:
i,x = x,x/2 # using x for the next value allows this to be placed
# at the beginning of the loop (rather than at the end)
# and avoids issues with the continue statement
print(i)
# ... your code ...
Or, you could use a bit of math:
# 6 = int(math.log(100,2))
for i in [100/2**i for i in range(6)]:
print(i)
# Strangely enough, this is actually slower than the cFor() folly
Here's another approach to handle special progressions in a cleaner and more generic fashion. It is a class that implements (and hides) internal workings of a loop variable.
class Loop:
def __init__(self,start=0):
self._firstPass = True
self._value = start
#property
def value(self): return self._value
def start(self,initial):
if self._firstPass : self._value = initial
return self
def next(self,nextValue=None):
if nextValue is None : nextValue = self.value + self._increment
if self._firstPass : self._firstPass = False
else : self._value = nextValue
return self
def up(self,by=1):
return self.next(self.value+by)
def down(self,by=1):
return self.next(self.value-by)
def upTo(self,last,by=1):
if self._firstPass: self._firstPass = False
else: self._value += by
return self.value <= last
def downTo(self,last,by=1):
if self._firstPass: self._firstPass = False
else: self._value -= by
return self.value >= last
def loop(self,condition=True):
self._firstPass = False
return condition
def until(self,condition=False):
self._firstPass = False
return not condition
def __getitem__(self,index): return self.value[index]
def __str__(self): return str(self.value)
def __int__(self): return int(self.value)
def __float__(self): return float(self.value)
def __add__(self,other): return self.value + other
def __sub__(self,other): return self.value - other
def __mul__(self,other): return self.value * other
def __matmul__(self,other): return self.value.__matmul__(other)
def __divmod__(self,other): return divmod(self.value,other)
def __pow__(self,other): return self.value ** other
def __truediv__(self,other): return self.value / other
def __floordiv__(self,other): return self.value // other
def __mod__(self,other): return self.value % other
def __lshift__(self,other): return self.value << other
def __rshift__(self,other): return self.value >> other
def __lt__(self,other): return self.value < other
def __le__(self,other): return self.value <= other
def __eq__(self,other): return self.value == other
def __ne__(self,other): return self.value != other
def __gt__(self,other): return self.value > other
def __ge__(self,other): return self.value >= other
def __and__(self,other): return self.value & other
def __or__(self,other): return self.value | other
def __xor__(self,other): return self.value ^ other
def __invert__(self): return -self.value
def __neg__(self): return -self.value
def __pos__(self): return self.value
def __abs__(self): return abs(self.value)
def __radd__(self, other): return other + self.value
def __rsub__(self, other): return other - self.value
def __rmul__(self, other): return other * self.value
def __rmatmul__(self, other): return other.__matmul__(self.value)
def __rtruediv__(self, other): return other / self.value
def __rfloordiv__(self, other): return other // self.value
def __rmod__(self, other): return other % self.value
def __rdivmod__(self, other): return divmod(other,self.value)
def __rpow__(self, other): return other ** self.value
def __rlshift__(self, other): return other << self.value
def __rrshift__(self, other): return other >> self.value
def __rand__(self, other): return other & self.value
def __rxor__(self, other): return other ^ self.value
def __ror__(self, other): return other | self.value
The class is designed to work with the while statement after initializing a loop variable. The loop variable behaves like a normal int (or float, or str, etc.) when used in calculations and conditions. This allows the progression and stop condition to be expressed as you would write them for an ordinary loop variable. The class adds a few method to control the loop process allowing for non-standard increments/decrements:
For example:
i = Loop()
while i.start(100).next(i//2).loop(i>2):
print(i) # 100, 50, 25, 12, 6 ,3
# Note: to use i for assignment or as parameter use +i or i.value
# example1: j = +i
# example2: for j in range(+i)
#
# i.value cannot be modified during the loop
You can also give a start value in the constructor to make the while statement more concise. The class also has an until() function to invert the stop condition:
i = Loop(start=100)
while i.next(i//2).until(i<=2):
print(i) # 100, 50.0, 25.0, 12.5, 6.25, 3.125
Finally there are a couple of helper functions to implement the simpler loops (although a for in would probably be better in most cases):
i = Loop()
while i.start(1).upTo(10):
print(i) # 1,2,...,9,10
i = Loop()
while i.upTo(100,by=5):
print(i) # 0,5,10,15,20,...,95,100
i = Loop(100)
while i.down(by=5).until(i<20):
print(i) # 100,95,90,...,25,20

How can i implement Vector addition for the form [1,2,3,4] + v where v is vector and [1,2,3,4] is a list in python?

Here is the code for the program:
I tried to implement a vector class as i learned about operator overloading in python. I was able to make a vector class which can be used much like a list with operations like len(vector) , vector1 + vector2 (addition operator overloading) and subtraction . But i found a problem. Here is the code of the program and i have stated the problem below :
class vector:
"""Initialize Vector"""
def __init__(self,d):
self.coords = [0]*d
def __len__(self):
return len(self.coords)
def __getitem__(self, item): #Getting an item from a vector
return self.coords[item]
def __setitem__(self, key, value):
self.coords[key] = value
def __add__(self, other):
if(len(self)!= len(other)):
print("Don't add these too ! they are not same types :P")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] + other[i]
return result
def __sub__(self, other):
if(len(self) != len(other)):
print("Dont subtract these two!")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] - other[i]
return result
def __eq__(self, other):
return self.coords == other.coords
def __ne__(self, other):
return self.coords != other.coords
def __str__(self):
return '<'+ str(self.coords)[1:-1] +'>'
print("Input for vector 1")
x = vector(2)
for i in range(0,len(x)):
x[i] = int(input('Enter a number\n'))
print("Input for vector 2")
y = vector(2)
for i in range(0,len(y)):
y[i] = int(input('Enter a number\n'))
z = x-y
print(str(x))
print(" + ")
print(str(y))
print(" = ")
print(str(z))
It works if i add a vector + list but list + vector gives an error. How can i implement the other .
You want to implement __radd__. Since it should do the same thing as __add__ here, you can just assign __add__ to it:
class vector:
...
def __add__(self, other):
if(len(self)!= len(other)):
print("Don't add these too ! they are not same types :P")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] + other[i]
return result
__radd__ = __add__
...

Overloading Operators with MATLAB

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

Categories

Resources