Could any one tell me whats wrong in the following code? (In Python 2.7)
def echo(msg):
print msg
def loop(x,y):
a = 0
while (a < x + 1):
a = a + 1
y
loop(5,echo("ok"))
I should be getting "ok" five times, but instead I just get "ok" once, no matter what
amount I set x to be.
echo("ok") is being evaluated before passing it to the function maybe, this is what you really want
def loop(x,y, *args):
a = 0
while (a < x + 1):
a = a + 1
y(*args)
def echo(msg):
print msg
loop(5,echo, "ok")
It's because you're evaluating echo("ok") when you call loop.
What you probably want to do is call echo("ok") on each iteration.
def echo(msg):
print msg
def call_echo_ok():
echo("ok")
def loop(x,y):
a = 0
while (a < x + 1):
a = a + 1
y()
loop(5, call_echo_ok)
Note that this can be done more concisely with lambda functions.
def echo(msg):
print msg
def loop(x,y):
a = 0
while (a < x + 1):
a = a + 1
y()
loop(5, lambda: echo('ok'))
You can try this:
def loop(times,message):
for i in range(times):
print message
loop(5,"Ok")
Related
def fibonacci_closure(n):
def fibonaci():
if n == 0: """in this line error occured idk why because in watches i see n=4"""
return 0
elif n == 1 or n == 2:
return 1
else:
i = 1
j = 1
tmp = 1
while n != 2:
n -=1
tmp = i
i = j + i
j = tmp
return i
return fibonaci
a = fibonacci_closure(4)
a()
Task:
Return a closure that will generate elements of the Fibonacci sequence when called repeatedly.
Example:
g = fibonacci_closure()
g() # 1
g() # 1
g() # 2
g() # 3
UnboundLocalError: local variable 'n' referenced before assignment
Fibonacci numbers are a typical example for generators. It's only irritating why the function should return a function instead of a generator.
def fibonacci_closure():
def fibonacci():
i = j = 1
while True:
yield i
i, j = j, i + j
return fibonacci().__next__
The task you are trying to accomplish could be done by creating a class. (Or you could look into creating a 'generator' object, which is its own separate thing.)
What you need in order to preserve the value of n from one call to the next is some sort of global variable. Global variables in Python are possible, but are bad practice. The same thing can be accomplished from within a class where n is stored and encapsulated within that class.
Have a look at the changes I made and see if the function now works as you intended. Cheers!
class fibonacci_closure():
def __init__(self):
self.n = 0
def fibonaci(self):
if self.n == 0:
self.n+=1
print(0)
elif self.n == 1 or self.n == 2:
self.n+=1
print(1)
else:
i = 1
j = 1
tmp = 1
hold = self.n
while hold != 2:
hold -=1
tmp = i
i = j + i
j = tmp
self.n+=1
print(i)
I am trying to find a efficient solution for the 3n + 1 problem on uvaonlinejudge. The code I have uses memoization using a dictionary. Can anyone suggest an improvement(s) that will help with the execution time of this code? At the moment I am getting a 'Time limit Exceeded' error when I submit the code. If anyone has a working solution to the problem please share it with me. PLEASE DON'T mark this post as DUPLICATE. I have already seen this post and others on stackoverflow but they don't answer the question posted here. My code is as below:
import sys
def recCycleLength(n,cycLenDict):
if n==1:
return 1
if n not in cycLenDict:
if n%2==0:
cycLen = recCycleLength(n//2, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
cycLen = recCycleLength(3*n+1, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
return cycLenDict[n]
def maxCycle(a, b):
i = a
mydict = {}
maxLength = 1
while i <= b:
m = recCycleLength(i, mydict)
if m > maxLength:
maxLength = m
i = i + 1
return maxLength
for line in sys.stdin:
curr_line=line.split()
num1 = int(curr_line[0])
num2 = int(curr_line[1])
if num1>num2:
num1, num2 = num2, num1
m = maxCycle(num1, num2)
print("{} {} {}".format(num1, num2, m))
I found the problem in your code. Actually, you are not saving cycLenDict generated on the previous interval for next one. And this is why your code is so "slow" because it will generate all possible endings over and over again. Just move it in global scope or make something like this:
import sys
def rec(n, cache):
if n in cache:
return cache[n]
if n % 2 == 0:
cycle = rec(n//2, cache)
else:
cycle = rec(3*n+1, cache)
cache[n] = cycle + 1
return cache[n]
def cycle(a, b, cache):
return max(rec(i, cache) for i in range(a, b+1))
if __name__ == '__main__':
cache = {1: 1}
for line in sys.stdin:
a, b = map(int, line.split())
a, b = min(a, b), max(a, b)
m = cycle(a, b, cache)
print("{} {} {}".format(a, b, m))
The code seems to do the right thing to execute maxCycle optimally by caching all calculated results in mydict.
However, the input to the application consists of many pairs of values to be processed and maxCycle will reset mydict = {} and calculate everything from scratch.
I suggest remembering the results globally instead. A simple modification of the original code would be:
cycLenDict = {} # global dictionary
def recCycleLength(n): # no cycLenDict argument
if n==1:
return 1
if n not in cycLenDict:
# ...
def maxCycle(a, b):
# ...
while i <= b:
m = recCycleLength(i) # no myDict argument
To make everything a little bit nicer looking (without any difference performance-wise, compared to the solution above), make a decorator which remembers the results, so that the remainder of the code does not have to take care of that:
def memoize(func):
"""decorate any function which takes positional arguments to cache its results"""
func.results = {} # results are stored globally as the funtion's attribute
def memoized(*a): # memoized version of func
if a not in func.results: # if not cached
func.results[a] = func(*a) # save to cache
return func.results[a] # return from cache
return memoized
#memoize # with this, recCycleLength is called only once for every n value
def recCycleLength(n):
if n==1:
return 1
elif n%2==0:
return recCycleLength(n//2) + 1
else:
return recCycleLength(3*n+1) + 1
def maxCycle(a, b):
return max(recCycleLength(i) for i in range(a, b+1))
import sys
def cycle(current, count=1):
if current == 1:
return count
if current % 2 == 0:
return cycle(current / 2, count + 1)
return cycle(current * 3 + 1, count + 1)
def max_cycles(lower, upper):
max = 0
for current in range(lower, upper):
result = cycle(current, 1)
if result > max:
max = result
return max
def main(i, j):
if i > j:
(i, j) = (j, i)
print (i, j, max_cycles(i, j))
if __name__ == "__main__":
if len(sys.argv) < 3:
print 'usage: python filename argv1 argv2'
print 'exiting'
exit(0)
main(int(sys.argv[1]), int(sys.argv[2]))
import numpy as np
import matplotlib.pyplot as plt
class Prisoners_Dilemma:
def __init__(self,n,p):
self.n = n
self.p = p
def decision_array(self):
self.dict_dict = {}
for i in range(1,self.n + 1):
self.dict_dict[i] = []
list_list = []
for j in range(1,self.n):
#np.random.seed(j)
self.r = np.random.uniform(0,1)
if self.r > self.p:
q = 0
else:
q = 1
list_list.append(q)
self.dict_dict[i] = list_list
return self.dict_dict
def payoff(self):
self.dict_dict_2 = {}
for i in range(1,self.n + 1):
self.dict_dict_2[i] = []
list_list_2 = []
list_list_3=[]
for j in range(1, i):
list_list_2.append(self.dict_dict[j][i-2])
for j in range(i + 1, self.n + 1):
list_list_2.append(self.dict_dict[j][i-1])
list_list_2_np = np.array(list_list_2)
against_i = np.sum(list_list_2_np)
for_i = np.sum(self.dict_dict[i])
if against_i == 0 and for_i == 0:
payoff_i = 2
elif against_i == 0 and for_i != 0:
payoff_i = 5
elif against_i != 0 and for_i == 0:
payoff_i = -5
else:
payoff_i = -2
list_list_3.append(payoff_i)
self.dict_dict_2[i]=list_list_3
return self.dict_dict_2
def gameplay(self, N, initial_count):
self.counter = initial_count
for i in range(N):
for j in range(1, self.n + 1):
z = self.dict_dict_2[j]
x = np.array(z)
self.counter += np.sum(z)
return self.counter
y = Prisoners_Dilemma(15,0.015)
print (y.gameplay(20,100))
In the above code, the compiler gives the error that instance has no attribute as dict_dict_2 even though its prefixed with self. Moreover, it is perfectly fine with dict_dict. For the sake of completeness I have included the whole code but the problem lies only in payoff and gameplay methods?
dict_dict_2 is only created in payoff(), therefore you must call it before attempting to call gameplay().
The issue is that you are only creating self.dict_dict_2 variable in the payoff function, but in your logic where you are calling gameplay() function , you are not calling the payoff() function before accessing dict_dict_2 , from the looks of it you are not calling that function anywhere at all.
Not sure what dict_dict_2 holds, but the above is the reason why you are getting the issue, maybe you can move the initialization part of dict_dict_2 to __init__() function , though that would not fix the complete issue, since you would still be trying to access dict_dict_1[j] which can error out if j is not a key in dict_dict_2 .
def test_countdown(self):
from_3 = '3\n2\n1\nBlastoff!'
self.assertEqual(countdown(3), from_3)
from_0 = 'Blastoff!'
self.assertEqual(countdown(0), from_0)
#THIS IS THE TEST
def countdown(n):
while n>0:
print(n)
n=n-1
print("Blastoff!")
#This is my code for the function
It is not passing the test because on the back end it is coming out as 'none' > for countdown(3) instead of '3\n2\n1\nBlastoff!'
You're printing, not concatenating:
def countdown(n):
return '\n'.join(map(str, range(n, 0, -1))) + '\nBlastoff!'
Or as Lalaland suggested below:
def countdown(n):
result = ''
while n > 0:
result += str(n) + '\n'
n = n - 1 # decrement
result = result + '\nBlastoff!'
return result # not printing
i have written some code that i want to convert into something i can import instead of it being used as the main.
floorMap = [[000,000,000,000,000,999,999,999,999,999],
[000,000,999,000,999,000,000,000,999,999],
[000,000,999,000,999,000,000,000,999,999],
[000,000,000,000,999,000,000,000,999,999],
[999,000,000,000,999,000,999,999,999,999],
[999,000,000,000,000,000,999,000,000,999],
[999,000,000,000,999,999,999,000,000,999],
[999,000,999,000,000,000,999,000,000,999],
[999,000,999,999,999,000,000,000,000,999],
[999,999,999,999,999,999,999,999,000,000]]
currentNum=0
wall=999
uncalculated=000
robotX=0
robotY=0
goalX=9
goalY=9
floorMap[goalY][goalX]=1
def changeSurroundings(X, Y):
#left
if(floorMap[X-1][Y]==uncalculated and X > 0):
floorMap[X-1][Y]=currentNum
#right
if(X < len(floorMap[0])-1 and floorMap[X+1][Y]==uncalculated):
floorMap[X+1][Y]=currentNum
#up
if(floorMap[X][Y-1]==uncalculated and Y > 0):
floorMap[X][Y-1]=currentNum
#down
if(Y < len(floorMap)-1 and floorMap[X][Y+1]==uncalculated):
floorMap[X][Y+1]=currentNum
def printMap():
i=0
floorMap[goalY][goalX]='G'
floorMap[robotY][robotX]='R'
while(i<len(floorMap)):
print floorMap[i]
print ""
i+=1
print ""
print ""
#------------------MOST IMPORTANT CHUNK OF CODE--------------
while(floorMap[robotY][robotX]==uncalculated):
x=0
while(x<len(floorMap[0])):
y=0
while(y<len(floorMap)):
if(floorMap[x][y] > uncalculated and floorMap[x][y] < wall):
currentNum=floorMap[x][y]+1
changeSurroundings(x,y)
y+=1
x+=1
printMap()
my problem is that whenever i try to put the most important chunk of code at the bottom into a method like so;
def calcMap():
while(floorMap[robotY][robotX]==uncalculated):
x=0
while(x<len(floorMap[0])):
y=0
while(y<len(floorMap)):
if(floorMap[x][y] > uncalculated and floorMap[x][y] < wall):
currentNum=floorMap[x][y]+1
changeSurroundings(x,y)
y+=1
x+=1
printMap()
it breaks my code. why? I dont seem to get any errors, it just gets stuck on one of the nested loops. i dont see any reason it should be doing this, but you guys probably will ;)
Thanks, Logan
Your problem comes from your global variables, in particular currentNum. This is basically what you're doing :
current = 0
def f():
current = 1
g()
def g():
print(current)
f() # Output: 0
What you need to do is:
current = 0
def f():
global current
current = 1
g()
def g():
print(current)
f() # Output: 1
Or better :
def f():
current = 1
g(current)
def g(current):
print(current)
f() # Output: 1
Also, you should consider using a more pythonic synthax for your calcMap function, something like :
def calc_map():
while floor_map[robot_x][robot_y] == uncalculated :
for x,array in enumerate(floor_map):
for y,element in enumerate(array):
if uncalculated < element < wall:
current_num = element + 1
change_surroundings(x, y, current_num)