Python recursive return using dict.get - python

I'm writting a code for rock scissor paper game. But when I run it, it falls into infinite loop.
The problem happened in following code. Why this code result in infinite loop for any input value?
(my python version is 3.5.0)
class Peoples(object):
def recept(self):
u = input('choose..r or s or p: ')
print('choice: ',{'r':'rock','s':'scissor','p':'p'}.get(u,'{} (wrong input)'.format(u)))
return {'s':0,'r':1,'p':2}.get(u,self.recept())
P=Peoples()
P.recept()

Because the second argument of get gets executed regardless of whether it will ultimately be used by get. You ought to break it up into multiple lines so it only recursively calls when necessary:
d = {'s':0,'r':1,'p':2}
if u in d:
return d[u]
else:
return self.recept()
But really, it would be preferable to not use recursion at all, since you'll hit the maximum recursion depth and crash after the user chooses an invalid input enough times in a row.
def recept(self):
d = {'s':0,'r':1,'p':2}
while True:
u = input('choose..r or s or p: ')
print('choice: ',{'r':'rock','s':'scissor','p':'p'}.get(u,'{} (wrong input)'.format(u)))
if u in d:
return d[u]

Related

My code keeps looping, when it should not

I'm creating a python program that given any angles/sides of a triangle will solve for all other applicable sides. to do this I have a dictionary of lists with lengths a,b,c and sides aa,ba,ca. the dictionary is structured so the first item in the list is the value of the key and the second item is a 0 or a 1, depending on if it is answered or not.
The program takes the second value of the list and puts it into another dictionary i called eqdict. for eqdict the value is either a 1 or a 0, depending if the value is known or not. With this we can do Pythagorean theorem, so if a+b+c=2, then we know 1 value is missing so it starts a function to find the missing side. After this function the answer gets saved with the saveanswer function, and the equation finder function is called again. However when the program goes back through equation finder, the eqdict for whichever character it found is not set to 0, so it has a continuous loop.
import math
def main():
#creating terms in strings because I cant find an answer on how
#to make floats with a non zero no value
global terms
terms={"a":[0,0],"b":[0,0],"c":[0,0],"aa":[0,0],"ba":[0,0],"ca":[0,0]}
selectterms()
def selectterms():
"""takes user input for terms"""
doneterm=False
while not doneterm:
print("Please select the variable and then write it's value")
print("When done, please press enter with command prompt empty")
term1=input("Variable: ")
#to start program need to enter no command
if term1=="":
doneterm=True
appender()
#to end program after its finished
if doneterm ==False:
term2=float(input("Number: "))
terms[term1]=[term2]
terms[term1].append(1)
return
def addtoeqdict(term):
eqdict[term]=1
return
def saveanswer(term,num):
"""saves answer to answers dict, makes second term 1 and sends back the number"""
answers={}
print("saveanswer")
answers[term]=num
#print("answers",answers)
terms[term][1]=1
terms[term][0]=num
eqdict[term]=1
print(answers)
print(eqdict)
eqfinder(**eqdict)
def appender():
"""Append a 0 on to terms that have only 1 item in list"""
global eqdict
eqdict={}
keys=terms.keys()
for i in keys:
i = str(i)
eqdict[i]=int(terms[i][1])
eqfinder(**eqdict)
return
def eqfinder(a,b,c,aa,ba,ca):
"""runs through given terms to find any possible equations.
looks for possible equations by adding appended values"""
nomoreterms=False
while nomoreterms == False:
print(terms)
if terms["aa"][0]!=0 or terms["ba"][0]!=0 or terms["ca"][0]!=0:
if terms["aa"][0]<0 or terms["ba"][0]<0 or terms["ca"][0]<0:
posangles(terms["aa"][0],terms["ba"][0],terms["ca"][0])
print(a,b,c,aa,ba,ca)
if c+a+b==2:
cab(terms["c"][0],terms["a"][0],terms["b"][0])
else:
nomoreterms=True
def posangles(aa,ba,ca):
print("Posangles")
if aa<0:
aa=aa*(-1)
saveanswer("aa",aa)
elif ba<0:
ba=ba*(-1)
saveanswer("ba",ba)
elif ca<0:
ca=ca*(-1)
saveanswer("ca",ca)
def cab(c,a,b):
print("cab")
if c==0:
c=math.sqrt(a**2+b**2)
saveanswer("c",c)
elif a==0:
a=math.sqrt(c**2-b**2)
saveanswer("a", a)
elif b==0:
b=math.sqrt(c**2-a**2)
saveanswer("b",b)
main()
So the issue is your eqfinder function. You pass in a, b, c find the missing value using cab, and save the answer. It then gets back to eqfinder and checks if a + b + c == 2 which it does since you never updated the a, b, c variables. There are number of fixes you could do to make this break out of the for loop. Here's one (added line marked with >>>):
def eqfinder(a,b,c,aa,ba,ca):
"""runs through given terms to find any possible equations.
looks for possible equations by adding appended values"""
nomoreterms=False
while nomoreterms == False:
print(terms)
if terms["aa"][0]!=0 or terms["ba"][0]!=0 or terms["ca"][0]!=0:
if terms["aa"][0]<0 or terms["ba"][0]<0 or terms["ca"][0]<0:
posangles(terms["aa"][0],terms["ba"][0],terms["ca"][0])
print(a,b,c,aa,ba,ca)
if c+a+b==2:
cab(terms["c"][0],terms["a"][0],terms["b"][0])
>>> c, a, b = terms["c"][1],terms["a"][1],terms["b"][1]
else:
nomoreterms=True

Creating a function with a condition in Python

I need to create a function named 'Bernoulli' that should take 2 input variables 'rr' and 'p' and should return a value of 1 if rr is less than or equal to p and a value of 0 if rr is greater than p.
The code I have produced so far is this:
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 'X=1'
else:
return 'X=0'
I am not sure how correct this is.
Upon running tests I get this feedback:
Your program took too long to execute.
Make sure that it isn't waiting for input and that there is no infinite loop.
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 1
else:
return 0
x = bernoulli(rr,p)
print(x)
However, if you are simply checking if one number is bigger than the other, it might make more sense down the line to use True and False because comparing them will be a shorter line of code later on. if x == False That being in the logical sense that we understand true to be positive and false to be negative. You might forget which way round the 1 and the 0 are ordered :)
Swift answered this in the same way I would approach this. The reason your code is not executing, is because it is never used. You must call a function to use it.
Here is how I did it:
rr=float(input())
p=float(input())
def bernoulli(rr,p):
if rr<=p:
return 'X=1'
else:
return 'X=0'
function_response = bernoulli(rr,p)
print(function_response)

Return and assignment in recursive function in python: None type given, expected an int value

I am fairly new to python but worked with recursion previously. I came across this problem while working with recursive functions.
archive = {1: 0}
def engine(base, chain=0):
if base in archive:
return archive[base]
else:
if base == 1:
return chain
elif base % 2 == 0:
get = engine(base/2)
meaning = 1 + get
archive[base] = meaning
else:
next = 3 * base + 1
get = engine(next)
meaning = 1 + get
archive[base] = meaning
print archive(13)
I worked with scheme recently. So, I expected it to work.
I want the code to evaluate till the case bool(base==1) becomes true and then work it's way up ward making a new entry to the dictionary on each level of recursion.
How can I achieve that? I am just counting the level of recursion until the fore-mentioned condition becomes True with the variable 'chain'.
[Solved]: I missed the return statement in two clauses of if-else statement. The scheme would pass the function itself and the last return statement would do the work but not with python. I understand it now.
Thanks everyone who responded. It was helpful.
Your last two elif and else clauses have no return statements and Python returns None by default.

Flow of recursion in python roman to arabic

So I just solved the last quiz on recursion on codeacademy. But while I was trying to understand the flow of execution of this code on pythontutor.org, I just couldnt follow the flow of this code.
def rval(letr):
if(letr=='I'):
return 1
elif(letr=='V'):
return 5
elif(letr=='X'):
return 10
elif(letr=='L'):
return 50
elif(letr=='C'):
return 100
elif(letr=='D'):
return 500
elif(letr=='M'):
return 1000
else:
return "error"
def arabic(n):
if len(n)==0:
return 0
elif len(n)==1:
return rval(n)
elif len(n)==2:
if rval(n[0])>rval(n[1]):
return rval(n[0])+rval(n[1])
else:
return rval(n[1])-rval(n[0])
else:
return arabic(n[len(n)-2:])+arabic(n[:len(n)-2])
arabic('DXCVI')
======PROBLEM FACED======
My question is this --
Suppose I run arabic('DXCVI'), then how does this line arabic(n[len(n)-2:])+arabic(n[:len(n)-2]) get executed
Do both arabic(n[len(n)-2:]) & arabic(n[:len(n)-2]) start getting executed simultaneously or does the second term wait until the first is done/returns a value ?
The left part arabic(n[len(n)-2:]) is always called first. An easy way to find this out is to put a print statement in your arabic(n) function.
Try something like this:
def arabic(n):
print n
if len(n)==0:
return 0
elif len(n)==1:
return rval(n)
elif len(n)==2:
# more code
Which would output this:
DXCVI
VI
DXC
XC
D
Proving that the left side, arabic(n[len(n)-2:]), gets called before +arabic(n[:len(n)-2]).
First arabic(n[len(n)-2:]) (the left part) is executed, then arabic(n[:len(n)-2]) (the right part) is executed.
Remember that the first part may also have recursive calls, so the second one must wait until it returns a value to get executed.

How do I keep a list of numbers I have already enountered?

I am currently working on a BASIC simulator in Python, as the title suggests. Here is my code for this problem:
def getBASIC():
l = []
x = 1
while x == 1:
i = input()
l.append(i)
if len(i.split()) != 3:
x = 0
return l
def findLine(prog, target):
for l in range(0, len(prog)):
progX = prog[l].split()
if progX[0] == target:
return l
def execute(prog):
location = 0
visited = [False] * len(prog)
while True:
T = prog[location].split()[2]
location = findLine(prog, T)
visited[location] = True
if visited[len(visited)-1] == False:
return "infinite loop"
else:
return "success"
The first function does what it is intended to do -- convert input of BASIC code into a list. The second function, findLine also does what it is intended to do, in that it finds the item which contains the string equal to the input. The last function, however, I cannot get to work. I know what I have to do, and that is to check whether or not a part of it has been visited twice. I cannot figure out how to do this, due to the existence of the while loop. As a result of this, the second half of that function is just placeholder. If you could help me figure out how to solve this, it would be greatly appreciated. Thanks.
You keep a list of places that have been visited (you already do this) and then when you encounter a goto, you check if it does to a line that already have been visited, and if it has been visited, you exit.
One mistake right now is that you make a list that is as long as the program is. That's pretty pointless. Just keep a list of the visited line numbers instead, and check with
if current_line in visited:
Try adding an if statement declaring a line in the visited list to be true when it is encountered in the loop. This is my solution:
def execute(prog):
location = 0
visited=[False]*len(prog)
while True:
if location==len(prog)-1:
return "success"
if visited[location]==True:
return "infinite loop"
if visited[location]==False:
visited[location]=True
line2strings=prog[location].split()
T=line2strings[-1]
location=findLine(prog, T)

Categories