Python error: "global name 'counter1' is not defined" - python

My code:
class Persistence:
num = 0
counter1 = 0
counter2 = 0
def __init__(self, num):
self.num = num
#num = input("Enter a non-negative number:: ")
if num < 0:
raise NameError("Negative")
#test else:
#print "ok!"
num_list = []
def digitize(self, num):
num_list = []
n = str(num)
for digit in n:
num_list.append(int(digit))
return num_list
def sum_digits(self, num):
the_list = self.digitize(num)
the_sum = 0
for digit in the_list:
the_sum = the_sum + digit
return the_sum
def times_digits(self, num):
the_list = self.digitize(num)
the_product = 0
for digit in the_list:
the_product = the_product * digit
return the_product
def additive(self, num):
global counter1
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if list1.__len__() > 1:
global counter1
counter1 = counter1 + 1
self.additive(sum1)
return sum1, counter1
def multiplicative(self, num):
global counter2
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if list1.__len__() > 1:
global counter1
counter2 = counter2 + 1
self.multiplicative(prod1)
return prod1, counter2
c = Persistence(5)
print c.additive(5)
print c.multiplicative(5)
Not sure why I'm getting this error? It seems to me that I have defined the global variable counter1. I'm also getting this error for counter2, and the only way I've been able to resolve the error is by inserting counter1 = 0 (or any other number) a single line above the return statement on the additive() method. Help would be much appreciated!!

One of the solutions is to move the counters out of class like:
# global variables
num = 0
counter1 = 0
counter2 = 0
class Persistence:
....
....
Leave the rest of your code unmodified.

counter1 and counter2 are defined as class attributes currently, if you want to keep it that way, just access them as classname.attrname:
class Persistence:
num = 0
counter1 = 0
counter2 = 0
def __init__(self, num):
self.num = num
#num = input("Enter a non-negative number:: ")
if num < 0:
raise NameError("Negative")
#test else:
#print "ok!"
num_list = []
def digitize(self, num):
...
def sum_digits(self, num):
...
def times_digits(self, num):
...
def additive(self, num):
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if list1.__len__() > 1:
Persistence.counter1 = Persistence.counter1 + 1
self.additive(sum1)
return sum1, Persistence.counter1
def multiplicative(self, num):
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if list1.__len__() > 1:
Persistence.counter2 = Persistence.counter2 + 1
self.multiplicative(prod1)
return prod1, Persistence.counter2
c = Persistence(5)
print c.additive(5)
print c.multiplicative(5)

The appropriate way of solving this issue will be to move the 3 class variables to init method. These variable will become associated with the object can be accessed using 'self'
class Persistence(object):
def __init__(self):
self.counter1 = 0
self.counter2 = 0
def digitize(self, num):
return [int(digit) for digit in str(num)]
def sum_digits(self, num):
return sum(self.digitize(num))
def times_digits(self, num):
the_list = self.digitize(num)
the_product = 0
for digit in the_list:
the_product = the_product * digit
return the_product
def additive(self, num):
sum1 = self.sum_digits(num)
list1 = []
list1 = self.digitize(sum1)
if len(list1) > 1:
self.counter1 += 1
self.additive(sum1)
return sum1, self.counter1
def multiplicative(self, num):
prod1 = self.times_digits(num)
list1 = []
list1 = self.digitize(prod1)
if len(list1) > 1:
self.counter2 += 1
self.multiplicative(prod1)
return prod1, self.counter2
c = Persistence()
print c.additive(5)
print c.multiplicative(5)
You don't num in the constructor if you are not actually using it.

Related

Error in code while converting infix form to prefix form using stack class

class Stack:
def __init__(self):
self.stack=[]
self.top = None
def empty(self):
return not self.stack
def push(self, item):
self.stack.append(item)
self.top = item
def pop(self):
if self.empty():
a = self.stack.pop()
return a
else:
print("Empty stack")
def printall(self):
print(self.stack)
def clear(self):
self.stack = []
self.top = None
ysj = Stack()
jy = []
list = input().split()
leng = len(list)
num = 0
for i in range(0, leng):
if list[i] == '+' or list[i] == '-':
while ysj.top is not None:
jy.append(ysj.pop())
num = num - 1
ysj.push(list[i])
num = num + 1
elif list[i] == '/' or list[i] == '*':
while ysj.top == '/' or ysj.top == '*':
jy.append(ysj.pop())
num = num - 1
ysj.push(list[i])
num = num + 1
else:
jy.append(int(list[i]))
for i in range(1, num + 1):
jy.append(ysj.pop())
for i in range(0, len(jy)):
print(jy[i], end=" ")
I'm trying to convert the equation from infix form to postfix form using Stack class.
This code works when I type in
1 + 2 * 3
but doesn't work well when I type in
1 * 2 + 3 or 1 * 2 * 3 or 1 + 2 + 3
I think there's something wrong with my while loop but I can't figure out what part is wrong. Please help me.
You forgot to insert None to top when the list gets empty, and you are trying to remove a item when the list is empty:
class Stack:
def __init__(self):
self.stack=[]
self.top = None
def empty(self):
return not self.stack
def push(self, item):
self.stack.append(item)
self.top = item
def pop(self):
if not self.empty(): # remove item only if the stack is not empty
a = self.stack.pop()
# after removing a item, check if the stack is empty
if self.empty(): # if it is, set the top as None
self.top = None
return a
else:
print("Empty stack")

Function call not working proparly (python)

For input 1 to self.trying, the set_jump() method doesn't work. the program dosent execute the while loop in it
Code:
jump = []
z = []
class jumps:
def __init__(self, numberOfJumps, trying):
self.numberOfJumps = numberOfJumps
self.trying = int(trying)
def setJumps(self):
if self.trying == 1:
# print("hello")
self.set_jump()
if self.trying == 2:
self.get_jump()
return ""
def set_jump(self):
counterSetJump = 0
while counterSetJump < int(self.numberOfJumps):
print("what was the distance the athlete jumped at jump number" + str(counterSetJump + 1))
z.append(float(input()))
counterSetJump += 1
return ""
def get_jump(self):
counterGetJumps = 0
while counterGetJumps < int(self.numberOfJumps):
print(z[counterGetJumps])
print("this is the jump for the " + str(counterGetJumps) + " time")
counterGetJumps += 1
return ""
class athlete:
def __init__(self, name, yearsPro):
self.name = name
self.yearsPro = yearsPro
def information(self):
print("the athletes name is " + self.name)
print("he as been active for " + str(self.yearsPro))
return ""
a = []
b = []
i = 0
know = int(input("how many athletes you know the information for"))
while i < know:
a.append(0)
b.append(0)
i = i + 1
j = 0
while j < know:
a[j] = athlete(input("what is the athletes name?"), input("how many years as the athlete been active"))
b[j] = jumps(input("how many jumps did the athlete jumped?"),
input("input 1 for settig and 2 for getting the jumps")) # not getting called?
b[j].setJumps()
j = j + 1
infoFor = int(input("who do you want the info for"))
print(a[int(infoFor) - 1].information())
print(b[int(infoFor) - 1].get_jump())
Check the code out
jump = []
z = []
class jumps:
def __init__(self, numberOfJumps, trying):
self.numberOfJumps = numberOfJumps
self.trying = int(trying)
print("trying = "+str(self.trying))
def setJumps(self) :
if self.trying == 1:
#print("hello")
self.set_jump()
if self.trying == 2:
self.get_jump()
print("Yes I have chnaged trying to = :"+str(self.trying))
return ""
def set_jump(self):
print("set_jump finally called")
i = 0
while(i < int(self.numberOfJumps)):
print("what was the distance the athlete jumped at jump number" + str(i))
z.append(int(input()))
i = i + 1
def get_jump(self):
i = 0
while(i < int(self.numberOfJumps)):
return z[i]
i = i + 1
class athlete:
def __init__(self, name, yearsPro):
self.name = name
self.yearsPro = yearsPro
def information(self):
print("the athletes name is " + self.name)
print("he as been active for " + str(self.yearsPro))
return ""
a = []
b = []
i = 0
know = int(input("how many athletes you know the information for"))
while(i < know):
a.append(0)
b.append(0)
i = i + 1
j = 0
while(j <know):
a[j] = athlete(input("what is the athletes name?"), input("how many years as the athlete been active"))
b[j] = jumps(input("how many jumps did the athlete jumped?"),
input("input 1 for settig and 2 for getting the jumps")) #not getting called?
b[j].setJumps()
k=j
for k in b:
k.setJumps()
#j=j+1
j = j + 1
infoFor = int(input("who do you want the info for"))
print(a[int(infoFor) - 1].information())
print(b[int(infoFor) - 1].setJumps())

IndexError with dict in python,

classes = []
due = []
minutes =[]
grade = []
classname = []
classnume = []
form_orderer = []
listobj = []
i = 0
n = 0
k = 0
def classesl(): #setup class list
classesnum = int(input("How many classes do you have?"))
classnume.append(classesnum)
for _ in range(0,int(classnume[0])):
classname = input("What is the class name??")
classes.append(classname)
def duel(): #setup class list
print("How many days is this assignment for", classes[i], "due in?")
c = input()
due.append(c)
def minutesl(): #setup class list
print("How many minutes will this take", classes[i], "?")
e = input()
minutes.append(e)
def gradesl(): #setup class list
print("What is your grade in that", classes[i], "?")
g = input()
grade.append(g)
def getvars():
global i
for _ in range(0,int(classnume[0])):
duel()
minutesl()
gradesl()
make_dicts()
i += 1
def form_order():
for n in range(0,int(classnume[0])):
a = int(minutes[n])
b = int(grade[n])
form_orderer.append(a/b)
print(form_orderer)
n += 1
def make_dicts():
for k in range(0,int(classnume[0])):
dictx = {'keyz': 'valz'}
dictx.update({'class': classes[k], 'form_order': int(form_orderer[k])})
listobj.append(dictx)
k += 1
def sort(form_orderer):
size = len(form_orderer)
for x in range(form_orderer):
for y in range(form_orderer-x-1):
if(form_orderer[y] > form_orderer[y+1]):
tmp = form_orderer[j]
form_orderer[y] = form_orderer[y+1]
form_orderer[y+1] = tmp
def setup():
while True:
classesl()
getvars()
form_order()
make_dicts()
# sort(form_orderer)
print()
break
setup()
I was wondering how would I get it so the form_orderer list corresponds with a classes list in a dict. So I can then print out the classes in order based off of the order of the form_order list sorted from least to greatest. I already have the bubble sort method down, just need help with the dict.
You call make_dicts twice, which leads to an exception, it's called in get_vars and in setup, if i comment it out in get_vars i don't get any errors
classes = []
due = []
minutes =[]
grade = []
classname = []
classnume = []
form_orderer = []
listobj = []
i = 0
n = 0
k = 0
def classesl(): #setup class list
classesnum = int(input("How many classes do you have?"))
classnume.append(classesnum)
for _ in range(0,int(classnume[0])):
classname = input("What is the class name??")
classes.append(classname)
def duel(): #setup class list
print("How many days is this assignment for", classes[i], "due in?")
c = input()
due.append(c)
def minutesl(): #setup class list
print("How many minutes will this take", classes[i], "?")
e = input()
minutes.append(e)
def gradesl(): #setup class list
print("What is your grade in that", classes[i], "?")
g = input()
grade.append(g)
def getvars():
global i
for _ in range(0,int(classnume[0])):
duel()
minutesl()
gradesl()
#make_dicts()
i += 1
def form_order():
for n in range(0,int(classnume[0])):
a = int(minutes[n])
b = int(grade[n])
form_orderer.append(a/b)
print(form_orderer)
n += 1
def make_dicts():
for k in range(0,int(classnume[0])):
dictx = {'keyz': 'valz'}
dictx.update({'class': classes[k], 'form_order': int(form_orderer[k])})
listobj.append(dictx)
k += 1
def sort(form_orderer):
size = len(form_orderer)
for x in range(form_orderer):
for y in range(form_orderer-x-1):
if(form_orderer[y] > form_orderer[y+1]):
tmp = form_orderer[j]
form_orderer[y] = form_orderer[y+1]
form_orderer[y+1] = tmp
def setup():
while True:
classesl()
getvars()
form_order()
make_dicts()
# sort(form_orderer)
print()
break
setup()

UnboundLocalError: local variable 'cnt' referenced before assignment

class Solution:
def subarraysDivByK(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
l = len(A)
div = [[0 for col in range(l)] for row in range(l)]
sums = [[None for col in range(l)] for row in range(l)]
global cnt
cnt = 0
for i in range(l):
if A[i]%K == 0:
div[i][i] = 1
cnt = cnt+1
def impl(self,st,en):
print(st,en)
if sums[st][en]!=None:
return sums[st][en]
if A[st] == A[en]:
if A[st]%K == 0:
sums[st][st] = A[st]
div[st][st] = 1
print(st,en,sums[st][en])
if sums[st][en]%k == 0:
div[st][en] = 1
cnt = cnt+1
return sums[st][st]
elif st+1==en:
sums[st][en] = A[st]+A[en]
print(st,en,sums[st][en])
if sums[st][en]%K == 0:
div[st][en] = 1
cnt = cnt+1
return sums[st][en]
else:
if sums[st+1][en]==None:
sums[st][en] = impl(self,st+1,en)+A[st]
if sums[st][en-1]==None:
sums[st][en] = impl(self,st,en-1)+A[en]
#sums[st][en] = sums[st+1][en]+ A[st]
print(st,en,sums[st][en])
if sums[st][en]%K == 0:
div[st][en] = 1
cnt = cnt+1
return sums[st][en]
impl(self,0,len(A)-1)
print(cnt)
#print(sums)
You should add global cnt inside the function impl so that the global variable will be visible.
def impl(self,st,en):
global cnt
...
For more information, please check: enter link description here.

Prime numbers iterator

I wrote a piece of code to print n prime numbers:
class PrimeGen:
def __init__(self):
self.current = 2
def genPrime(self, num):
for i in range(num):
while 1:
for j in range(2, self.current/2 + 1):
if self.current % j == 0:
self.current = self.current + 1
break
else:
break
print self.current,
self.current = self.current + 1
if __name__ == '__main__':
p = PrimeGen()
p.genPrime(5)
The code works fine. I get 2 3 5 7 11 as output. I tried to make the class iterable. Code below. But the output is 0 1 2 3 4. I could not quite figure out where I am going wrong. Any help is appreciated. Thanks
class PrimeIter:
def __init__(self):
self.current = 1
def next(self):
self.current = self.current + 1
while 1:
for i in range(2, self.current/2 + 1):
if self.current % i == 0:
self.current = self.current + 1
break # Break current for loop
else:
break # Break the while loop and return
return self.current
def __iter__(self):
return self
if __name__ == '__main__':
p = PrimeIter()
for p in range (5):
print p,
You're using this code to print out the values:
for p in range (5):
print p,
If you look at that, it's printing the values of the range. You probably want to print things from the prime iterator. itertools has some functions that may help:
for prime in itertools.islice(p, 5):
print prime,
Additionally, you may want to consider using a generator:
def primes():
current = 1
while True:
current += 1
while True:
for i in xrange(2, current // 2 + 1):
if current % i == 0:
current += 1
break
else:
break
yield current
Your problem is that you are reusing the variable p in your test code:
if __name__ == '__main__':
p = PrimeIter() # first declaration of p
for p in range (5): # second declaration of p
print p, # uses second declaration of p
I'd recommend using itertools.islice to get the first 5 elements of an iterator:
if __name__ == '__main__':
p = PrimeIter()
for x in itertools.islice(p, 5):
print x,
Iterator for generating prime numbers upto some maximum m:
class PrimeIter:
def ___init__(self, m):
self.max = m
def __iter__(self):
self.n = 1
return self
def __next__(self):
if self.n < self.max:
self.n += 1
i = 2
while i < (self.n//2+1):
if self.n % i == 0:
self.n = self.n+1
if self.n > self.max:
raise StopIteration
i = 1
i += 1
else:
return self.n
else:
raise StopIteration
p = PrimeIter (100)
for i in p:
print(i, end=' ')

Categories

Resources