My code keeps looping, when it should not - python

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

Related

Omit in for loop in Python

I have a function to move between the given range of values, but I would like to add in my function a parameter that will be an array which would contain the numbers which must be skipped while my function run iteration
my function:
nums = []
def loopIteration(minValue, maxValue):
minValue += 1
for i in range(maxValue-minValue+1):
num = i+minValue
nums.append(Num('numbers_{}'.format(i)))
#function call
loopIteration(4,25)
i want to add in my function call an parameter like this:
loopIteration(4,25,[8,9,16])
thanks for any answers :)
You can use continue to skip certain is:
def loopIteration(minValue, maxValue, skip=set()):
for i in range(minValue + 1, maxValue + 1):
if i in skip:
continue
cells.append(Cell("numbers_{}".format(i)))
Continue is a Python syntax which would allow you to pass iteration in a for loop. Usually, continue can make it quite hard to follow flow later on, if you ever wish to look back on your script. Here is what you could do:
def loopInteration(minValue, maxValue, skipNums):
for number in range(maxValue-minValue+1):
if number in skipNums:
continue
num = i+minValue
nums.append(Num("numbers_{}".format(i)))
loopIteration(4,25,[NUMBERS HERE])

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)

Number of Odds and Evens in a List Function - Python

I am trying to create a function called "odd_even" which takes my already created list (named "nums") and determines the number of odd and even numbers, and then returns the variables to me. However when I run this code I get:
NameError: name 'odd' is not defined
How do I fix this? If you can give me any useful pointers on the "return" function that would also be greatly appreciated.
import random
def main():
nums = []
for x in range(10):
nums.append(random.randrange(1,26))
def odd_even(given_list):
odd = 0
even = 0
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return odd
return even
odd_even(nums)
print("List had ", odd, "odds and ", even, "evens.")
main()
You are doing 2 things wrong.
First, you are trying to return two values but on different lines. You cant do this, to do this, do so as a tuple:
def odd_even(given_list):
odd = 0
even = 0
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return odd, even
Second, you call the function but dont store the value(s) of return. So you need change:
odd_even(nums) to odd, even = odd_even(nums)
By trying to execute:
print("List had ", odd, "odds and ", even, "evens.")
The main() is looking for variables odd and even, but they dont exist in main(), they exist locally in odd_even() (hence why you are calling return as to return them to the calling function. The reason you only see an error with respect to odd is because it is the first variable in that print() that the interpreter encounters an error on.
The only way around this without correct use of return is to declare them as global. But that is a bad idea so don't do that, keep things local on the stack!
You have some syntactic errors. Python...unlike many programming languages is whitespace conscious. This means you need to be careful with your indentation and spacing. More traditional languages like Java and C use brackets {} to define a scope, and semicolons ; to figure out line termination.
Perhaps you copied it poorly, but from what I see, it appears as though you are defining the function odd_even() within the function main(). That is, the definition of odd_even() is tabbed to the right, which means that its definition is within the function main. I assume that you want main to call the function odd_even(). Thus, you must tab it back over to the left so that it is at the same indentation level as main().
For this reason I use horizontal lines (see below) to clearly outline the scope of functions. This is good for me when I write in Python because otherwise it can be very unclear where one function ends, and where another begins.
Also, it appears as though you have 2 return statements. If you want to return 2 values, you should encompass it within an object. To get around this, there are two simple solutions that come to mind. You can make the odd_even() function access global variables (not recommended)...or you can return an array (any number of values back) or a tuple (exactly 2, but this is python specific).
Below is an implementation of both:
import random
# Declare global variables outside the scope of any function
odd = 0
even = 0
#-------------------------------------------------------------------------------
def main():
nums = [1,2,3,4,5,6,7,8,9,10]
return_value = odd_even(nums)
# Get the individual values back
o = return_value[0]
e = return_value[1]
# You can use the global variables
print("List had ", odd, "odds and ", even, "evens.")
# Or you can get the array back
print("List had ", o, "odds and ", e, "evens.")
#-------------------------------------------------------------------------------
def odd_even(given_list):
# This means we are referencing the variables odd and even that are global
global odd
global even
# Loop through the array
for x in given_list:
if x % 2 == 0:
even += 1
else:
odd += 1
return [odd, even]
#-------------------------------------------------------------------------------
main()

variable lists in user created functions

I am using python and trying to speed up the process of checking what is inside strings for a q & a program. I want to do the following for a variable amount of conditions:
a = input("Any question")
if "a condition" in a:
print("the condition is in the question")
So here I'm checking if a condition is in a question to see what kind of question it is, and here was my idea for doing multiple conditions:
def ifs(a,b,c):
b=[d,e,f,g,h,i,j,k]
while a < 8:
b.remove(b[a])
a = a - 1
print("c")
Here, a is the number of conditions you want to check and b are the conditions being checked while c, the final, is the something to print afterwards. (c does not have anything to do with the problem). That second part b=[d,e,f,g,h,i,j,k] is a list that is meant to be inserted where b is so you can assign a certain amount of values, which varies depending on a, which counts down to zero, as shown in a = a - 1 removing variables one by one b.remove(b[a]).
I'm wondering if there's any way to be able to list off conditions without making a specifically defined command for each amount of conditions... below is what i mean:
def if1(a,b,c):
if a in b:
print(c)
def if2(a,b,c,d):
if a in c:
print(d)
if b in c:
print(d)
def if3(a,b,c,d,e):
if a in d:
print(e)
if b in d:
print(e)
if c in d:
print(e)
And so on...
Any help is appreciated, THANKS!
why not pack the arguments in a list instead of writing many functions?
e.g. something like this:
def condition_met(condition, to_check):
if condition in to_check:
print(condition)
data = list(range(4)) # [0, 1, 2, 3]
condition_met(3, data) # ok
condition_met(7, data) # nope

Python recursive return using dict.get

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]

Categories