Code not working inside a class - python

i'm trying to solve an exercice which consists in a primal factorization of a given number.
def primes(n):
p=[]
for a in range(2,n+1):
if (is_prime(a)): p.append(a)
return p
def is_prime(number):
for n in range(2,number):
if not number%n : return False
return True
def factor(z):
p=primes(z)
fact={}
if z in p:
fact[z]=1
else:
for n in p:
while z%n==0 and (z/n not in p):
if n not in fact: fact[n]=1
else: fact[n]+=1
z/=n
if z%n==0 and (z/n in p):
if n in fact: fact[n]+=1+(z/n==n)
else:
fact[n]=1
fact[z/n]=1+(z/n==n)
break
return fact
print factor(13)
My code work like a charm; but the exercice wants me to put it in a class starting with :
class PrimeFactorizer:
#your code here
Which would be call with PrimeFactorizer(n).factor
When i add the working code above into
class PrimeFactorizer:
def __init__(self, z):
self.z=z
It returns me an empty stuff when calling PrimeFactorizer(13).factor
Could someone give me a hint on what i'm doing wrong ?
Thanks

This should do the trick:
class PrimeFactorizer:
def __init__(self, z):
self.z=z
def primes(self,n):
p=[]
for a in range(2,n+1):
if (self.is_prime(a)): p.append(a)
return p
def is_prime(self,number):
for n in range(2,number):
if not number%n : return False
return True
def factor(self):
p=self.primes(self.z)
fact={}
if self.z in p:
fact[self.z]=1
else:
for n in p:
while self.z%n==0 and (self.z/n not in p):
if n not in fact: fact[n]=1
else: fact[n]+=1
self.z/=n
if self.z%n==0 and (self.z/n in p):
if n in fact: fact[n]+=1+(self.z/n==n)
else:
fact[n]=1
fact[self.z/n]=1+(z/n==n)
break
return fact
print PrimeFactorizer(8).factor() # Output: {2: 3}
print PrimeFactorizer(13).factor() # Output: {13: 1}}

Related

Implementing fibonacci series using greedy approach?

I have implemented fibonacci series using recursion:
def fibonacci(n):
if n==0:
return 0
elif n==1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
I have also implemented it using dynamic programming:
def fibonacci(n):
result = [0, 1]
if n > 1:
for i in range(2, n+1):
result.append(result[i-1] + result[i-2])
return result[n]
I want to implement it using greedy approach. I am unable to think of it in greedy terms. Please provide a greedy approach for this problem.
I didn't understand what you wanted to say by saying the word 'greedy'. But these are ways:
Example 1: Using looping technique
def fib(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
print fib(5)
Example 2: Using recursion
def fibR(n):
if n==1 or n==2:
return 1
return fibR(n-1)+fibR(n-2)
print fibR(5)
Example 3: Using generators
a,b = 0,1
def fibI():
global a,b
while True:
a,b = b, a+b
yield a
f=fibI()
f.next()
f.next()
f.next()
f.next()
print f.next()
Example 4: Using memoization
def memoize(fn, arg):
memo = {}
if arg not in memo:
memo[arg] = fn(arg)
return memo[arg]
fib() as written in example 1.
fibm = memoize(fib,5)
print fibm
Example 5: Using memoization as the decorator
class Memoize:
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, arg):
if arg not in self.memo:
self.memo[arg] = self.fn(arg)
return self.memo[arg]
#Memoize
def fib(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
print fib(5)

How to call a python class like calling a function

Searching to build up my personal style of programming i want to be able to call a python class the same way i'd call a python function.
Here's what i mean:
consider this function:
def Factorial(n):
if n == 0:
return 1
else:
return n * Factorial(n - 1)
This is a function that outputs 24 when you call Factorial(4).
Now let's consider a class instead:
class Factorial:
def __call__(n):
if n == 0:
return 1
else:
return n * Factorial()(n - 1)
This code works the same way as the previous code except at call time where you instead write:
Factorial()(4) # which outputs 24
Now my question is how could you do this instead:
Factorial(4) # just that, and output 24, from THE object.
Thanks!
Use self.
class Factorial:
def __call__(self, n):
if n == 0:
return 1
else:
return n * self(n - 1)
f = Factorial()
f(3)
# 6
f(5)
# 120
From there you can easily add a starting value in your __new__ constructor.
class Factorial:
def __new__(cls, value=None):
instance = super().__new__(cls)
if value is None:
return instance
else:
return instance(value)
def __call__(self, n):
if n == 0:
return 1
else:
return n * self(n - 1)
Now you can
Factorial(5)
# 120
f = Factorial()
f(5)
# 120
Use a constructor (which is __init__ in Python) like so:
class Factorial:
def __init__(self, n):
// code here
You can override __new__ method:
class Factorial:
def __new__(cls, n):
if n == 0:
return 1
else:
return n * Factorial(n - 1)
Although the above solution works, I prefer a decorator-based solution which is less magical and is more intuitive and explicit:
def function_factory(cls):
return cls()
#function_factory
class Factorial:
def __call__(self, n):
if n == 0:
return 1
else:
return n * Factorial(n - 1)
A short & simple change in your existing code:
>>> class Factorial:
... def __call__(self,n):
... if n == 0:
... return 1
... else:
... return n * self.__call__(n - 1)
...
>>> Factorial = Factorial()
>>> Factorial(4)
24
>>>

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__
...

Issue with python __eq__ method in checking if 2 lists are equal

I have a python program in which I have a class called Vector and an empty list inside of that class which is being populated runtime.
Here is the init:
def __init__(self,n):
self.vector = [];
self.n = n;
for x in range(n):
self.vector.append(False);
And here is the eq:
def __eq__(self, other):
t = True
for x in range(self.n):
if self.vector[x] != other.vector[x]:
t = False;
return t
however, when I try to check if 2 objects of this type are equal, I always get true, even though I changed values inside of vector in Vector class.
Here is the code where I do the above:
vectors = []
n = tmp.size();
k = calculateCombinationCount(n,int(n/2))
for i in range(k):
for j in range(0,n-1):
if (tmp.vector[j] != tmp.vector[j+1]):
t = True
for x in vectors:
if x == tmp:
t = False;
if t:
vectors.append(tmp)
tmp.printVector();
tmp.swap(j,j+1);
I would appreciate any help that you can provide. Thank you :)
EDIT:
def swap(self,i,j):
tmp = self.vector[i]
self.vector[i] = self.vector[j]
self.vector[j] = tmp
def calculateCombinationCount(n,r):
k = factorial(n)/(factorial(int(r))*factorial(int(n-r)))
return int(k)
Right so I've updated your code to be much more pythonic (I can tell you come from another language, Java?).
from math import factorial
class Vector:
def __init__(self, size):
self.size = size
self.vector = [False] * size
def __eq__(self, other):
"""
Same if self.size == other.size
"""
assert self.size == other.size, (self.size, other.size)
return self.vector == other.vector
def print_vector(self):
print(self.vector)
def swap(self, i, j):
"""
More efficient and pythonic
"""
self.vector[i], self.vector[j] = self.vector[j], self.vector[i]
def calculate_combination_count(n, r):
"""
This is slow, I'd replace it with scipy.special.comb
https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html#scipy.special.comb
"""
return factorial(n) // (factorial(r) * factorial(n-r))
tmp = Vector(10)
vectors = []
n = tmp.size
k = calculate_combination_count(n, n // 2)
for i in range(k):
for j in range(0, n-1):
if tmp.vector[j] != tmp.vector[j + 1]:
if not any(vec == tmp for vec in vectors): # much more efficient
vectors.append(tmp)
tmp.print_vector()
tmp.swap(j, j + 1)
else: # Just to prove why it doesn't work
print('tmp.vector is all False: {}'.format(not all(tmp.vector)))
This prints out tmp.vector is all False: True repeatedly. I think this is your problem.
If you

generic Number class refactoring?

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)

Categories

Resources