Menu navigation with if and else in Python - python

This is my little menu navigation with if and else statements:
def navigation():
navigation_eingabe = int(input())
if navigation_eingabe == 1:
met1()
if navigation_eingabe == 2:
pass
if navigation_eingabe == 3:
pass
if navigation_eingabe == 4:
pass
if navigation_eingabe == 5:
pass
if navigation_eingabe == 6:
pass
else:
print("Pls give only Integer numbers")
def met1():
print("method1")
met2()
def met2():
print("method2")
navigation()
Its not working correctly, after I give the Input as 1, the code goes to met1, then to meth2 and then to the else statement. I dont know why?
And then I program this alternativ code with a example:
def navigation ():
x = int(input())
if x == 1:
print("1")
xx1()
if x == 2:
print("2")
xx2()
else:
print("else statement")
def xx1():
print("this is met1")
def xx2():
print("this is met2")
navigation()
But in this code, the statement is working correctly, why not in the first code? Is this a problem with functional programming logic, or with the statement structury? but I cant see the difference of this two codes.
Thank you!

In python, when testing multiple conditions in the same block, you use if for the first condition, elif for other conditional statements after that, and then else. The code block under else runs only if the other conditions were False. The problem with your code is that you use all if statements where you should use elif. The reason your first code goes to the else statement is because your last if statement runs no matter what the result of the first if statement was.
if navigation_eingabe == 1:
met1()
elif navigation_eingabe == 2:
pass
put the rest of your elif statements, and end with the else statement, so it will print if none of the other conditions are true:
else:
print('Pls only give integer numbers.')
However, this code does not do what you think it does. You are using the else statement for exception handling. This does not work. What you need is a try-except statement:
try:
navigation_eingabe = int(input())
if navigation_eingabe == 1:
met1()
elif navigation_eingabe == 2:
pass
elif navigation_eingabe == 3:
pass
elif navigation_eingabe == 4:
pass
elif navigation_eingabe == 5:
pass
elif navigation_eingabe == 6:
pass
else:
print('not a number 1-6')
except ValueError: #the type of error if you try to convert a non-integer string to an int.
print('Pls only give integer numbers.')
This will check each condition and catch the error if an invalid string is passed to the input.

This happened because you thought the execution of navigation() function would stop after the first if statement. It is wrong as after that more if statements are there instead of elif.
So use elif instead of more if statements
if navigation_eingabe == 1:
met1()
elif navigation_eingabe == 2:
pass
elif navigation_eingabe == 3:
pass
elif navigation_eingabe == 4:
pass
elif navigation_eingabe == 5:
pass
elif navigation_eingabe == 6:
pass
else:
print("Pls give only Integer numbers")

Because you're using consecutive if statements as opposed to elif statements, the Python interpreter treats each block as a separate decisional, so navigation() is first evaluating whether navigation_eingabe == 1. For an entry of 1 at the input prompt, this is true. Then, because the next line is treated as a separate decisional statement, it checks if navigation_eingabe == 2, and so on, until it reaches the following block:
if navigation_eingabe == 6:
pass
else:
print("Pls give only Integer numbers")
At which the interpreter enters the decisional with the comparison navigation_eingabe == 6, and evaluates this regardless of whether any of the previous five comparisons were True or False. This comparison evaluates to False because navigation_eingabe == 1, and we fall into the else block as a catch-all.
Additionally, the else clause will never be reached for non-integer input anyway because int(input()) will raise a ValueError exception for anything that cannot be cast as an int. To catch non-integer input, you should separate the contents of navigation() into a try and an except block.
I suspect what you are actually trying to do is the following:
def navigation():
try:
navigation_eingabe = int(input())
if navigation_eingabe == 1:
met1()
elif navigation_eingabe == 2:
pass
elif navigation_eingabe == 3:
pass
elif navigation_eingabe == 4:
pass
elif navigation_eingabe == 5:
pass
elif navigation_eingabe == 6:
pass
except ValueError:
print("Please only enter integers.")
def met1():
print("method1")
met2()
def met2():
print("method2")
navigation()
For which, when you enter 1 at the prompt, the output is the following:
1
method1
method2

Related

Infinite loop 'try and if' under a method

Executing menu() and go to 1 or 2 or 3 is good to do its work.
But after passing by getproduct(character) and getting back to menu() and then if you choose number 3, it makes a bad loop.
I want to know why, and how to solve this problem...
def menu():
menu = '1. ice\n2. cream\n3. quit'
print(menu)
try:
order = int(input('choose one: '))
if order == 1:
c = 'ice'
getproduct(c)
elif order == 2:
c = 'cream'
getproduct(c)
elif order == 3:
exit()
else: menu()
except ValueError: menu()
def getproduct(character):
toping = int(input('1. ice or 2. cream?'))
try:
if character == 'ice' and toping == 1:
print(character + 'ice')
menu()
elif character == 'ice' and toping == 2:
print(character + 'cream')
menu()
elif character == 'cream' and toping == 1:
print(character + 'ice')
menu()
elif character == 'cream' and toping == 2:
print(character + 'cream')
menu()
else: getproduct(character)
except: getproduct(character)
menu()
There are several mistakes on the code. First of all, you are using exit, that should not be used within files, instead of it, I use on my example the module sys (sys.exit(0)) that has the same goal.
On the other hand, you are using the input checks in an imprecise way, and looping should be different. In menus, I personally recommend using while loops.
Solution for your problem and a a couple of improvements (could be better):
import sys
def menu():
menu = '1. ice\n2. cream\n3. quit'
while True:
print(menu)
try:
order = int(input('choose one: '))
except:
print("Use a correct answer")
else:
if order == 1:
c = 'ice'
getproduct(c)
elif order == 2:
c = 'cream'
getproduct(c)
elif order == 3:
sys.exit(0)
else:
print("Use a correct answer")
def getproduct(character):
topings = '1. ice or 2. cream?: '
while True:
print(topings)
try:
second_order = int(input())
except:
print("Use a correct answer")
else:
if character == 'ice' and second_order == 1:
print(character + 'ice')
break
elif character == 'ice' and second_order == 2:
print(character + 'cream')
break
elif character == 'cream' and second_order == 1:
print(character + 'ice')
break
elif character == 'cream' and second_order == 2:
print(character + 'cream')
break
else:
print("Use a correct answer.")
menu()
The exit() function works by raising the SystemExit type of exception, which propagates up the chain until there's nothing more to run and the program comes to a stop.
That it is an exception means that the code above where the SystemExit is raised is allowed to close resources and do other wind-down activities, so as not to break any external resources. However, it also means that a blank except: statement can catch the SystemExit and ignore it. Which is what's happening here.
def getproduct(character):
toping = int(input('1. ice or 2. cream?'))
try:
...
# call to menu(), which calls exit()
except: # this activates on ANY exception, including SystemExit
getproduct(character)
In general, you should almost never use a raw except block, because of situations like this where it catches something you don't want it to. Instead, analyze the code inside the try, figure out what types of exceptions it would throw, and catch those. In your case, it's likely to be either ValueError or TypeError:
try:
...
except (ValueError, TypeError):
getproduct(character)
or, if you're dead set on catching everything, you can write a special exception for if the error is a SystemExit (though, again, a blank except: or a except Exception: is considered bad practice):
try:
...
except SystemExit:
pass # ignore it
except:
getproduct(character)
You should note, according to the documentation:
quit(code=None)
exit(code=None)
Objects that when printed, print a message like “Use quit() or Ctrl-D (i.e. EOF) to exit”, and when called, raise SystemExit with the specified exit code.
You should probably use sys.exit() instead, though it does basically the same thing.

wrong answer with the nested if in python

I expect 3 value in return but my code doesn't return anything .
Thanks
a = 3
if a > 0:
if a == 1:
print(1)
elif a == 2:
print(2)
elif a == 2:
print(2)
elif a == 3:
print(3)
else:
print(a)
This is because your first condition is met, if a > 0. Because of this the code travels down that path and does not meet the two nested conditions of a == 1 or a == 2.
elif only executes if the if condition is False, so you may need:
a = 3
if a > 0:
if a == 1:
print(1)
elif a == 2:
print(2)
if a == 3:
print(3)
else:
print(a)
Output:
3
The first if statement is met as the value of a is greater than 0. The result you're looking for could be achieved with the following if/elif block:
a = 3
if a == 3:
print(3)
elif a == 2:
print(2)
elif a == 1:
print(1)
else:
print(a)
The above will check the variable for the three conditions, printing the desired result. The else: will catch any other input and print the variable.
because a ==3 , your first if is satisfied (other elif(s) will not trigger, because they only trigger if the previous ifs fail), then your code will test if a ==1 or 2 (which is not the case) hence your code prints nothing. Your should modify your code like this
a = 3
if a > 0:
if a == 1:
print(1)
elif a == 2:
print(2)
if a == 2:
print(2)
if a == 3:
print(3)
else:
print(a)

Can you use input to accept both an integer and a string?

I have a small script I have been working on for practice with Python. I am having trouble getting my input to accept a number for an if statement and also accept string as lower case.
I want to tell my script for any input if the user types '99' then close the program. So far it works where I have int(input()), but it won't work where I have input(). What am I doing wrong or is it not something I can do?
Right now my if statement looks like:
if choice1 == 99:
break
Should I just make 99 into a string by quoting it?
Maybe something like this:
if choice1 == "99":
break
Here is the script:
global flip
flip = True
global prun
prun = False
def note_finder(word):
prun = True
while prun == True:
print ('\n','\n','Type one of the following keywords: ','\n','\n', keywords,)
choice2 = input('--> ').lower()
if choice2 == 'exit':
print ('Exiting Function')
prun = False
start_over(input)
elif choice2 == 99: # this is where the scrip doesnt work
break # for some reason it skips this elif
elif choice2 in notes:
print (notes[choice2],'\n')
else:
print ('\n',"Not a Keyword",'\n')
def start_over(word):
flip = True
while flip == True:
print ('# Type one of the following options:\n# 1 \n# Type "99" to exit the program')
choice1 = int(input('--> '))
if choice1 == 99:
break
elif choice1 < 1 or choice1 > 1:
print ("Not an option")
else:
flip = False
note_finder(input)
while flip == True:
print ('# Type one of the following options:\n# 1 \n# Type "99" to exit the program')
choice1 = int(input('--> '))
if choice1 == 99:
break
elif choice1 < 1 or choice1 > 1:
print ("Not an option")
else:
flip = False
note_finder(input)
So input() always returns a string. You can see the docs here:
https://docs.python.org/3/library/functions.html#input
What you could do is something like this:
choice2 = input('--> ')
if choice2.isnumeric() and (int(choice2) == 99):
break
this avoids you to type check and catch errors that aren't important.
see below for how isnumeric works with different numeric types:
In [12]: a='1'
In [13]: a.isnumeric()
Out[13]: True
In [14]: a='1.0'
In [15]: a.isnumeric()
Out[15]: False
In [16]: a='a'
In [17]: a.isnumeric()
Out[17]: False

Python Raspberry PI Guessing Game(Function call not working)

My problem is that my Random function doesn't get called from the Menu function. I've tried everything, but it still doesn't work. It's weird, because i think that i have structured the functions correctly, and everything should work fine, but it doesn't call Random.
def Menu():
name = raw_input("What's your name?\n:")
print "Hello, %s!\nWeclome to the Guessing Game!" % name
print "Select an option:"
print "1- Guess a number between 1-100."
print "2- Guess a number between 1-1000."
print "3- Guess a number between 1-10,000."
print "4- Guess a number between 1-100,000."
print "5- Exit."
try:
selection = raw_input("Enter your selection:")
if selection == 1:
Random(100)
elif selection == 2:
Random(1000)
elif selection == 3:
Random(10000)
elif selection == 4:
Random(100000)
elif selection == 5:
exit()
except:
os.system("clear")
print "Sorry, that wasn't an option. Enter your selection again."
Menu()
raw_input() retuns a string so you have to cast the input to int or compare the input with strings. Either this way:
selection = raw_input("Enter your selection:")
if selection == "1":
Random(100)
elif selection == "2":
Random(1000)
elif selection == "3":
Random(10000)
elif selection == "4":
Random(100000)
elif selection == "5":
exit()
or this way:
selection = raw_input("Enter your selection:")
if int(selection) == 1:
Random(100)
elif int(selection) == 2:
Random(1000)
elif int(selection) == 3:
Random(10000)
elif int(selection) == 4:
Random(100000)
elif int(selection) == 5:
exit()
Furthermore you can avoid try by kicking out elif int(selection) == 5: and using else:" instead. So the game will be ended with any other input than 1,2,3 or 4. There will be no possibility to "enter your selection again" after calling except in your code anyway because the script stops.
The function Random is not very optimal. See this:
def Random(select):
range = "1-" + str(select)
Correct_Guess = random.randint(1,select+1)
Difficulty()
It is the same but shorte and more readable ;)

Except block always being thrown even after going through the try block and rest of the program?

I check to see if input can be changed into an integer if it can't it starts back from the beginning of UI(). I followed it through pycharm's debugger and it will pass the try, but when I try using 4 to exit.It will go through to the end, and then go back up to the except block.
I think the parts I commented after are the only relevant parts. Thanks for any help.
def UI():
global exitBool
global newBool
if not TV.tvList:
tv = TurnOnTV()
if TV.tvList:
l = list(TV.tvList.keys())
tv = TV.tvList.get(l[0])
print("1)change channel\n2)change volume\n3)Turn on another TV\n4)Exit\n5)Choose TV") #print accepted answers
choice = input()
try:
choice = int(choice) #try block and exception block
except:
print("\nInvalid Choice\n")
UI()
choice = int(choice)
if choice == 1:
if tv:
tv.changechannel(input("enter channel: "))
else:
print('sorry no tvs are available\n')
elif choice == 2:
if tv:
tv.changevolume(input("Enter in volume: "))
else:
print('Sorry no Tvs available')
elif choice == 3:
TurnOnTV()
elif choice == 4:
exitBool = True # exit bool to exit main loop
elif choice == 5:
tv = ChooseTV(input("Enter in TV name: "))
else:
print("Invalid Choice")
if tv:
tv.display()
def Main():
while exitBool == False: #Main Loop
UI()
When you catch the error and print "invalid choice" you must not call UI() again. That way you are making a recursive call, and when the inner UI() terminates the code goes on on the outer one.
Use a "while" statement to repeat a block of code until the user makes a valid choice.

Categories