I'm trying to better understand how Python flow control works. Accordingly, I wrote a little script to understand how to make functional menus that include the ability to enter and leave sub-menus. The code below works as expected (no errors, it prints the expected output, etc). But when I enter option 4 "Exit" in the sub-menu "stage1" it accepts the input and re-prints the sub-menu. If I select option 4 again it exits the sub-menu and returns me to the main menu.
Why would it work after selecting the option twice?
I trimmed my code down to include the snippet for your review, and once I trimmed it down, it no longer requires I enter the "Exit" option twice. I'd like to have a menu with more than 1 option, so I'd love to get to the bottom of this.
import time
import os
def stage1():
print("stage1")
time.sleep(1)
stage1_loop = 1
while stage1_loop == 1:
os.system('clear')
print("Sub Menu")
print("1. Stage 1")
print("4. Exit")
option = int(input("Please select a stage."))
if option == 1:
stage1()
elif option == 2:
stage2()
elif option == 3:
stage3()
elif option == 4:
print("Exit")
stage1_loop = 0
main_loop = 1
while main_loop == 1:
os.system('clear')
print("Main Menu")
print("1. Stage 1")
print("4. Exit")
option = int(input("Please select a stage."))
if option == 1:
stage1()
elif option == 2:
stage2()
elif option == 3:
stage3()
elif option == 4:
print("Exit")
main_loop = 0
If I comment out the elif lines for stage 2 & 3 in the sub-menu then the issue disappears.
CodePudding user response:
I see multiple potential issues here, let's get into it:
- First issue:
stage1
is recursive:
You've included a call to stage 1 inside stage 1.
Which means that when you call the stage1
function if you press 1
, you have created a sub-sub menu.
To fix this issue is suggest the following edit:
def stage1():
print("stage1")
time.sleep(1)
stage1_loop = 1
while stage1_loop == 1:
os.system('clear')
print("Sub Menu")
print("1. Stage 1")
print("4. Exit")
option = int(input("Please select a stage."))
if option == 1:
continue # This skips to the next loop iteration
elif option == 2:
stage2()
elif option == 3:
stage3()
elif option == 4:
print("Exit")
stage1_loop = 0
- Second issue: You'd like for exit to quit, but you are inside a sub menu.
For that simply call the exit()
method and your code will terminate altogether. You won't need to exit the submenu and then the menu.
Note: I may have misunderstood this last point, in that case simply ignore the second issue.
CodePudding user response:
Your code is quite messy:
- You don't require to create variables for while. You can use
True
andbreak
- Looks like you're repeating code a lot of times, we'll fix that later on
Here's the fixed code:
import time
import os
def stage1():
print("stage1")
time.sleep(1)
while True:
# os.system('clear')
print("Sub Menu")
print("1. Stage 1")
print("4. Exit")
option = int(input("Please select a stage."))
if option == 1:
stage1()
elif option == 2:
stage2()
elif option == 3:
stage3()
elif option == 4:
print("Exit")
return True # returns true and exits the loop
while True:
# os.system('clear')
print("Main Menu")
print("1. Stage 1")
print("4. Exit")
option = int(input("Please select a stage."))
if option == 1:
if stage1(): # checks if stage 4 is True and then breaks the loop
break
elif option == 2:
stage2()
elif option == 3:
stage3()
elif option == 4:
print("Exit")
break
Here's a faster non-repeating code for all 4 stages
:
import time
import os
def stageFunction(stage):
if stage in [1,2,3]: print(f"Stage {stage}") # Fast print stage number
if stage == 1:
# Do whatever
pass
elif stage == 2:
# DO whatever
pass
elif stage == 3:
# Do whatever
pass
elif stage == 4:
print("Exit")
# Do whatever
exit()
else:
print("Invalid Stage!")
def stageSystem(stage=0):
# os.system('clear')
print("Main Menu")
for i in range(1,4):
print(f"{i}. Stage {i}") # fast print stages
print("4. Exit")
option = stage
if (not stage):
option = int(input("Please select a stage: "))
stageSystem(option)
else:
stageFunction(stage)
stageSystem() # recursive call
stageSystem()
It might look lengthy, but it works pretty well considering you have 4 stages.