python, how to write an iterative function - python

I am quering a database for some paramaters which depend on a attribute called count! count can be incremented incase the 1st query does not return anything. Here is a sample code
sls = {(213.243, 55.556): {}, (217.193, 55.793): {}, (213.403, 55.369): {}}
for key in sls.keys:
if not sls[key]:
ra, dec = key[0], key[1]
search_from_sourcelist(sl, ra,dec)
count = 1
def search_from_sourcelist(sl, ra,dec):
dist = count/3600.0
sls[(ra,dec)] = sl.sources.area_search(Area=(ra,dec,dist))
return
Incase i run the method search_from_sourcelist, and it doesnt return anything, i would like to increment count, and do the query again. This is to be done for all keys in sls dictionary, untill all the keys have a value!!

Here is the most fundamental recursive function
def countdown(n):
if n == 0:
return "Blastoff"
else:
print "T minus %s" % n
return countdown(n-1)
You will notice that countdown returns itself with a modified argument, in this case n but -1, so if you actually followed this all the way through you would get
(-> indicates a call)
countdown(5) -> countdown(4) -> countdown(3) -> countdown(2) -> countdown(1) -> countdown(0) #stop
So now you understand what a recursive function looks like you realize you never actually return a call of your own function, thus your code is not recursive
We use recursion because we want to boil a task down to its simplest form then work from there, so a good example of this would be the mcnuggets problem. So you need to tell us what you are trying to achieve and how it can be made a smaller problem (or more importantly why.) Are you sure you cannot do this iteratively? remember you don't want to blow your stack depth because python is NOT tail recursive by standard

Recursion is useful when you find a way to reduce the initial problem to a "smaller version of itself".
The standard example is the factorial function
def fac(n):
return n * fac(n-1) if n > 1 else 1
Here you reduce the problem of calculating the factorial of n to calculating the factorial of n-1.
In your code there is no such "reduction". You just increment a value and start the same problem over again. Thus, I recommend you solve it iteratively.

I'm not sure that you need a recursive algorithm for this.
Incase i run the method search_from_sourcelist, and it doesnt return anything, i would like to increment count, and do the query again. This can be done with a while loop as follows:
for key, value in sls.iteritems():
if not value:
ra, dec = key[0], key[1]
count = 1
while not search_from_sourcelist(sls, ra, dec):
count += 1
But if you really do want to do this recursively, you can do it as follows, leave a comment and I'll write it up.
Further, you should look into your search_from_sourcelist function, as it always returns None

Related

Counting the leaves of a binary tree using recursion: the final return statement of (recursive function)+(recursive function)

I have been learning binary trees lately and have looked through the code for counting the leaves.
This is the recursive function to count the leaves:
def __count_leaves_recursive(self, node):
if node == None:
return 0
elif node.left == None and node.right == None:
return 1
else:
return self.__count_leaves_recursive(node.left) + self.__count_leaves_recursive(node.right)
When learning how recursion works with trees, the Python Tutor visualisation tool has been invaluable. However it hasn't helped me visualise the final return statement. I am struggling to visualise what's happening when a recursion function is added to another recursive function in the same line.
Is it simply the same as any other time the program reaches a recursive function? In that, the program simply records where it enter the function in order to return to the same spot when the function has been completed?
Is it simply the same as any other time the program reaches a recursive function?
Yes, you can image that line of code like this:
a = self.__count_leaves_recursive(node.left)
b = self.__count_leaves_recursive(node.right)
return a + b
So the first recursive call has to finish completely before the second one is launched. When that second recursive call also has finished its job, both returned values are summed up, and that value is returned to the caller.

Keep track of items in dynamic programming(similar to Knapsack problem)

Hello I'm trying to solve this dp problem: https://vjudge.net/problem/UVA-990
I'm able to solve the initial problem result using this code below:
I used recursion and a memo table arr to optimize the code.
s=list(map(int,input().split()))
t=s[0] #seconds allowed under water
w=s[1] #w
n=int(input()) #number of treasures
depth=[-1]
gold=[-1]
time=[-1]
for i in range(3):
q=list(map(int,input().split()))
depth.append(q[0])
gold.append(q[1])
time.append(q[0]*w*3)
arr = [[-1]*(t+1) for i in range(0,(n+1))]
def maxGold(n,T):
if n==0 or T==0:
return 0
if arr[n][T]!=-1:
return arr[n][T]
if time[n]>T:
answer=maxGold(n-1,T)
else:
answer=max(maxGold(n-1,T),gold[n]+maxGold(n-1,T-time[n]))
arr[n][T]=answer
return answer
result=maxGold(n,t)
print(result)
However I have no idea how to keep track of the chosen items.
I was thinking to store all indices of chosen treasures of the maxGold() output and print them later in a loop for instance.
One approach I had was to add a paramter to the maxGold() function and append to it the indices and return two result and the indices list from the function like the following:
def maxGold(n,T,l):
if n==0 or T==0:
return 0,l
if arr[n][T]!=-1:
return arr[n][T],l
if time[n]>T:
answer=maxGold(n-1,T,l)
else:
l2=l[:]
l2.append(n)
answer=max(maxGold(n-1,T,l)[0],gold[n]+maxGold(n-1,T-time[n],l2)[0])
arr[n][T]=answer
return answer,l
result=maxGold(n,t,[])
print(result[0])
list_of_indices=result[1]
length=len(list_of_indices)
#proceed outputs
However I ran into many tuple/integer type, subscriptable,iteratable errors. from this specific line even after trying to get a round the tuple output due to several outputs :
answer=max(maxGold(n-1,T,l)[0],gold[n]+maxGold(n-1,T-time[n],l2)[0])
And honestly I'm uncertain whether this approach is the right one.
Any hints?

Python Recursion Issue; I Can’t Change My Hard Code Into a Recursive Function

beside(picture,picture) #beside takes two pictures as arguments and prints them side by side in a 1:1 ratio.
stackn(n,picture) #stackn takes a number and a picture as arguments and prints n number of shapes in a vertical row.
show(picture) #show takes a picture as an argument and shows it on the canvas
In this case picture is the parameter heart_bb:
(n=2)# show(beside((stackn(1,heart_bb)),(stackn(2,heart_bb))))
(n=3)# show(beside((stackn(1,heart_bb)),(beside((stackn(2,heart_bb)),(stackn(4,heart_bb))))))
(n=4)# show(beside((stackn(1,heart_bb)),(beside((stackn(2,heart_bb)),(beside((stackn(4,heart_bb)),(stackn(8,heart_bb))))))))
My task is to come up with a recursive function(I’m going to call it test):
def test(n, picture):
I need this function to return the corresponding line of code shown above. For example, test(3,heart_bb) should return the line of code for n=3. Likewise, test(4,heart_bb) will return the line of code for n=4.
It has to work for any n>1, but after n=5 coding it gets really tedious.
def fractal(picture,n):
if n==1:
return(picture)
else:
return(beside((fractal(picture,(n-1))),(stackn((2**(n-1)), (picture)))))
I suppose you mainly need an idea of how you can do it and not a way to find someone that writes the code for you.
I would suggest to use a n-ary beside operation in place of your one, in such a way to simplify the code for n=2,3,4,... Since I cannot modify it I will define a new one in terms of your binary operation in this way:
def beside_pictures(pictures):
assert len(pictures) > 0
result = pictures[-1]
for tmp in pictures[:-1:-1]: # reverse order, starting from -1
result = beside(tmp, result)
return result
Now we are ready to transform your test function in a one line function:
def test(n, picture):
assert n > 0
show(beside_pictures([stackn(2**i,picture) for i in range(n)]))
UPDATE: If the requirement to have a recursive function is strict, one possible solution is the following one:
def test(n, picture):
if n == 1:
return stackn(1,picture)
return beside(test(n-1, picture), stackn(2**(n-1),picture))

Really weird python error

...
def splitMunipulation(p,threshold=5000):
runs=[];i=0
while i<len(p):
l=[];i+=1
print i,p[i]
while p[i]!=press(0,1,0):
l.append(p[i]);i+=1
else:
runs.append(l)#here i points to another (0,1,0)
return runs
...
record=splitMunipulation(record)
'''
Output:
1 <__main__.press instance at 0x046690A8>
File "H:\mutate.py", line 28, in splitMunipulation
while p[i]!=press(0,1,0):
IndexError: list index out of range
pressis a class
and since print p[i] works well,why p[i] is considered out of range?
Really don't get what's going on
'''
so, a few things..
Firstly, your code is very... unpythonic. This isn't C, so you don't need to use while loops for iteration, and don't use semicolons to separate multiple commands on one line in Python. Ever. Also, the while...else format is confusing and should be avoided.
If you look at the first few 'lines' of your while loop,
while i<len(p):
l=[];i+=1
You keep i below the length of p, but you immediately increase i's value by one. As such, when i=len(p) - 1, you will make i one larger, len(p). So when you try to access p[i], you are trying to access a value that doesn't exist.
Fixing those issues, you would get:
...
def splitMunipulation(p,threshold=5000):
runs=[]
for i in p:
l=[]
print i
if i != press(0,1,0):
runs.append(i)
return runs
...
record=splitMunipulation(record)
while p[i]!=press(0,1,0):
l.append(p[i]);i+=1
The variable i gets incremented in this loop until p[i]!=press(0,1,0). Since nothing is happening to make p longer, or to test that i is not greater than the length of p, it is easy to see how the index could get out of range.
len returns the length, not the last index. If l=[1,2,3], then len(l) returns 3, but l[3] is out of range.
so you should use
while i<len(p)-1
or better yet:
for i in range(len(p)):

Recursion in Python: what am I doing wrong?

I'm writing my first program in python and it has to simulate the mixing of particles (two gases). I don't know what am I doing wrong with this function.
I don't want the particles to leave certain area, that is the walls of container.
I use VPython.
def poruszanie(lista,pozycja,numCell):
flaga = 0
pozycjaTmp = (pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0)
for i in range( 0, len(lista) ):
if pozycjaTmp==lista[i].pos:
flaga=1
if flaga==1:
return poruszanie(lista,(pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0),numCell)
elif pozycjaTmp[0]==0 or pozycjaTmp[0]==numCell or pozycjaTmp[0]==-numCell or pozycjaTmp[1]==numCell or pozycjaTmp[1]==-numCell:
return poruszanie(lista,(pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0),numCell)
return pozycjaTmp
poruszanie - name of function
pozycja - position of the sphere
0,numCell,-numCell - the borders of container (0 is the wall in the middle that separate the gasses in the beggining)
All of this is in the x,y plane and z is always 0
That's where I start to use this function:
while 1:
rate(20)
for i in range(0,len(self.listBalls)):
self.listBalls[i].pos=poruszanie(self.listBalls,self.listBalls[i].pos,self.numCell)
I think you're calling it exactly the same each time and not returning properly:
if flaga==1:
return poruszanie(lista,(pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0),numCell)
else:
if pozycjaTmp[0]==0 or pozycjaTmp[0]==numCell or pozycjaTmp[0]==-numCell:
poruszanie(lista,(pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0),numCell)
elif pozycjaTmp[1]==numCell or pozycjaTmp[1]==-numCell:
poruszanie(lista,(pozycja[0]+choice([-1,0,1]),pozycja[1]+choice([-1,0,1]),0),numCell)
From the first call you return, but from the next two, you don't. Also, the parameters you're passing look to be exactly the same.
Edit
Considering the edit and your new error (maximum depth reached).
That error means that your function is recursing farther than python allows.
I'm still not sure what you're doing but you need a base condition at which point no matter what the recursion will stop. If you're satisfying either branch of the if ... elif ... statement each time you call the function, your recursion will never stop. You need something that will always break, and preferably you should place it before the if .. elif ... block.

Categories