How to end a while Loop when a desired input is given? - python

My program takes an input from the user about what they want to add. This works fine, but the problem arises when it comes down to the nested while loop that promps the user if they wish to add more items (y/n). I want y to start the loop from the beginning, n to exit the loop and continue the program, and any other input to give an error whilst restarting the y/n prompt.
I can't seem to figure out how to get out of the nested while loop nor can I figure out how to throw an error if the input is neither y or n. How would I go about fixing this?
elif user_input == "a":
while True:
try:
add_item = input("What item would you like to add? ").lower()
if not re.match("^[a-z, A-Z]*$", add_item):
print("ERROR: Only letters A-Z are allowed!")
continue
elif len(add_item) < 1 or len(add_item) > 20:
print("Item name is too long, only a maximum of 20 characters are allowed!")
continue
else:
item_amount = int(input("How many of these would you like to add? "))
shopping_list[add_item] = item_amount
print(f"{item_amount}x {add_item.title()} added to the shopping list.\n")
while True:
try:
add_more = input("Would you like to add more items? (y/n): ").lower()
if add_more == "y":
break
elif add_more == "n":
break
except TypeError:
print("ERROR: Expected y or n in return! Try again!.\n")
break
except ValueError:
print("\nERROR: Amount must be an integer! Try adding an item again!\n")

use boolean variable(keep_adding for below code) to decide while loop's terminal condition. It will be set to False iff add_more == "n"
use raise TypeError to raise error if user input is neither "y" nor "n".
You should remove break from except TypeError in order to keep asking "Would you like to add more items? (y/n): " if input is invalid.
elif user_input == "a":
keep_adding = True
while keep_adding:
try:
add_item = input("What item would you like to add? ").lower()
if not re.match("^[a-z, A-Z]*$", add_item):
print("ERROR: Only letters A-Z are allowed!")
continue
elif len(add_item) < 1 or len(add_item) > 20:
print("Item name is too long, only a maximum of 20 characters are allowed!")
continue
else:
item_amount = int(input("How many of these would you like to add? "))
shopping_list[add_item] = item_amount
print(f"{item_amount}x {add_item.title()} added to the shopping list.\n")
while True:
try:
add_more = input("Would you like to add more items? (y/n): ").lower()
if add_more == "y":
break
elif add_more == "n":
keep_adding = False
break
else:
raise TypeError
except TypeError:
print("ERROR: Expected y or n in return! Try again!.\n")
except ValueError:
print("\nERROR: Amount must be an integer! Try adding an item again!\n")

Related

how do i make my code start at the same point the user was already on once they go through a valueerror exception?

I complete all the steps that I am given by my code and finally it asks 'again (Y or N)'. (I have written an except argument that will prevent someone from ending the code by typing a wrong answer) When they input the wrong answer it starts the user back to the top of the code. I would like it to output what step the user was already on.
CODE:
while True:
try:
choice = int(input("ONLY CHOOSE 1 AS THERE IS NO OTHER CHOICE: "))
assert choice == 1
if choice == (1):
userInp = input("TYPE: ")
words = userInp.split()
start_count = 0
for word in words:
word = word.lower()
if word.startswith("u"):
start_count += 1
print(f"You wrote {len(words)} words.")
print(f"You wrote {start_count} words that start with u.")
again = str(input("Again? (Y or N) "))
again = again.upper()
if again == "Y":
continue
elif again == "N":
break
except AssertionError:
print("Please type a given option.")
except ValueError:
print("Please type a given option.")
EDIT:
So I have made some progress but I have one last problem
CODE:
while True:
try:
choice = int(input("ONLY CHOOSE 1 AS THERE IS NO OTHER CHOICE: "))
assert choice == 1
if choice == (1):
userInp = input("TYPE: ")
words = userInp.split()
start_count = 0
for word in words:
word = word.lower()
if word.startswith("u"):
start_count += 1
print(f"You wrote {len(words)} words.")
print(f"You wrote {start_count} words that start with u.")
while True:
again = input("again? (Y or N)")
if again not in "yYnN":
continue
break
if again == "Y":
continue
elif again == "N":
break
except AssertionError:
print("Please type a given option.")
except ValueError:
print("Please type a given option.")
The problem is that the variable 'again' is not defined when outside of the while loop (outside the while loop that is in the while loop). How do I fix this?
You could create another loop (inside this main loop) where you are asking for input, and have a try block there, so that it loops just the section where the user is giving input until they give correct input.

Stuck at WHILE LOOP when pressing N for escaping from the loop

# Feature to ask the user to type numbers and store them in lists
def asking_numbers_from_users():
active = True
while active:
user_list = []
message = input("\nPlease put number in the list: ")
try:
num = int(message)
user_list.append(message)
except ValueError:
print("Only number is accepted")
continue
# Asking the user if they wish to add more
message_1 = input("Do you want to add more? Y/N: ")
if message_1 == "Y" or "y":
continue
elif message_1 == "N" or "n":
# Length of list must be more or equal to 3
if len(user_list) < 3:
print("Insufficint numbers")
continue
# Escaping WHILE loop when the length of the list is more than 3
else:
active = False
else:
print("Unrecognised character")
print("Merging all the numbers into a list........./n")
print(user_list)
def swap_two_elements(user_list, loc1, loc2):
loc1 = input("Select the first element you want to move: ")
loc1 -= 1
loc2 = input("Select the location you want to fit in: ")
loc2 -= 1
loc1, loc2 = loc2, loc1
return user_list
# Releasing the features of the program
asking_numbers_from_users()
swap_two_elements
I would break this up into more manageable chunks. Each type of user input can be placed in its own method where retries on invalid text can be assessed.
Let's start with the yes-or-no input.
def ask_yes_no(prompt):
while True:
message = input(prompt)
if message in ("Y", "y"):
return True
if message in ("N", "n"):
return False
print("Invalid input, try again")
Note: In your original code you had if message_1 == "Y" or "y". This does not do what you think it does. See here.
Now lets do one for getting a number:
def ask_number(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("Invalid input, try again")
Now we can use these method to create you logic in a much more simplified way
def asking_numbers_from_users():
user_list = []
while True:
number = ask_number("\nPlease put number in the list: ")
user_list.append(number)
if len(user_list) >= 3:
if not ask_yes_no("Do you want to add more? Y/N: ")
break
print("Merging all the numbers into a list........./n")
print(user_list)

How to make a specific string work in a try-except block?

I don't want to make the user be able to enter anything other than numbers as the input for the "number" variable, except for the string "done".
Is it possible to somehow make an exception to the rules of the try-except block, and make the user be able to write "done" to break the while loop, while still keeping the current functionality? Or should I just try something different to make that work?
while number != "done":
try:
number = float(input("Enter a number: ")) #The user should be able to write "done" here as well
except ValueError:
print("not a number!")
continue
Separate the two parts : ask the user and verify if it is done, then parse it in a try/except
number = None
while True:
number = input("Enter a number: ")
if number == "done":
break
try:
number = float(number)
except ValueError:
print("not a number!")
continue
print("Nice number", number)
Instead of trying to make exceptions to the rules, you can instead do something like,
while True:
try:
number=input("Enter a number: ")
number=float(number)
except:
if number=="done":
break
else:
print("Not a number")
Check if the error message contains 'done':
while True:
try:
number = float(input("Enter a number: "))
except ValueError as e:
if "'done'" in str(e):
break
print("not a number!")
continue
also in this case continue is not necessary here (for this example at least) so it can be removed
Maybe convert the number to float afterwards. You can check if number is not equal to done,then convert the number to float
number = 0
while number != "done":
try:
number = input("Enter a number: ") #The user should be able to write "done" here as well
if number=="done":
continue
else:
number = float(number )
except ValueError:
print("not a number!")
continue
There are various ways to approach this situation.
First one that came across my mind is by doing:
while True:
user_input = input("Enter a number: ")
if user_input == "done":
break
else:
try:
number = float(user_input)
except ValueError:
print("not a number!")
continue
while True:
try:
user_input = input("Enter a number: ")
if user_input == "done":
break
number = float(user_input)
except ValueError:
print("not a number!")
continue
You can cast the input to float after checking if the input is 'done'

How to make the code jump back instead of forward?

I was working with a mastermind assignment but one of my define function isn't working as expected.
How do I make the "quit" jump back to "have a guess..." instead of continue to the colourlst?
def valid_usercolour():
while True:
#print('Welcome to the Mastermind')
usercolour = input('Please have your guess [r,o,y,g]: ').lower()
if 'quit' in usercolour:
while True:
dc_quit = input('Do you really wanted to quit the game?[y/n]: ')
if dc_quit.lower() == "y":
print()
print('Alright, thank You for playing, Goodbye', user_name, '!' )
quit()
break
elif dc_quit.lower() == "n":
print("Alright, let's continue to our game")
break
else:
print("Sorry! I don't understand what you mean, could you please type only [Y/N]")
continue
colourslist = ['r','o','y','g']
if any(character not in colourslist for character in usercolour):
print("Error! Only Characters ,", colourslist, "are allowed")
continue
if len(usercolour) != 4:
print("Error! Only 4 characters are allowed!")
continue
break
return usercolour
Just add else: and indent what's below it right before colourslist. Python codes do not "jump back":
def valid_usercolour():
while True:
#print('Welcome to the Mastermind')
usercolour = input('Please have your guess [r,o,y,g]: ').lower()
if 'quit' in usercolour:
while True:
dc_quit = input('Do you really wanted to quit the game?[y/n]: ')
if dc_quit[0].lower()[0] == "y":
print()
print('Alright, thank You for playing, Goodbye', user_name, '!' )
quit()
break
elif dc_quit[0].lower()[0] == "n":
print("Alright, let's continue to our game")
break
else:
print("Sorry! I don't understand what you mean, could you please type only [Y/N]")
continue
else:
colourslist = ['r','o','y','g']
if any(character not in colourslist for character in usercolour):
print("Error! Only Characters ,", colourslist, "are allowed")
continue
if len(usercolour) != 4:
print("Error! Only 4 characters are allowed!")
continue
break
return usercolour
BONUS: I added [0] at the values of dc_quit to force taking one character only. A full 'yes' or 'no' works too ;-)

Python while loop isn't doing as expected

I'm trying to complete my assignment and have been struggling. The idea is that you select report type, A or T. From there you enter keep entering integers until you quit. Once you quit, it should print out the total of integers added together for report 'T'; or for report 'A', it should print the total, plus a list of integers entered.
The problem I'm encountering at the moment is from report 'T', once I'm entering integers nothing will make it error or quit. It just keeps constantly asking me to enter another integer. Then from report 'A', every integer I enter it just comes up with 'invalid input'. I'm sure there are probably plenty more issues with my code but can't get past these ones at the moment. Any pointers would really be appreciated. Thanks
def adding_report(report):
total = 0
items = []
while True:
user_number = input("Enter an ingteger to add to the total or \"Q\" to quit: ")
if report.upper == "A":
if user_number.isdigit():
total += int(user_number)
items.append(user_number)
elif user_number.upper() == "Q":
break
else:
print("Invalid input\n")
elif report.upper() == "T":
if user_number.isdigit():
total += int(user_number)
elif user_number.upper() == "Q":
break
else:
print("Invalid input\n")
report = input("Report types include All Items (\"A\") or Total Only (\"T\")\nPlease select report type \"A\" or \"T\": ")
while True:
if report.upper() in "A T":
adding_report(report)
else:
print ("Invalid input")
report = input("Please select report type \"A\" or \"T\": ")
The in operator needs a collection of possible values. Use
if report.upper() in ("A", "T")
or (closer to what you have)
if report.upper() in "A T".split()
Your first problem is in this line:
if report.upper == "A":
This always evaluates to False, because report.upper is a function object, not a value. You need
if report.upper() == "A":
to return the value. You would also do well to rename the input variable and replace its value to the internal one you want:
report = input("Report types include All Items (\"A\") or Total Only (\"T\")\nPlease select report type \"A\" or \"T\": ")
report = report.upper()
This saves you the mess and time of calling upper every time you access that letter.
Please look through your code for repeated items and typos; you'll save headaches in the long run -- I know from personal experience.
Try this
def adding_report(report):
total = 0
items = []
while True:
user_number = input("Enter an integer to add to the total or \"Q\" to quit: ")
#You used "report.upper" instead of "report.upper()"
if report.upper() == "A":
if user_number.isdigit():
total += int(user_number)
items.append(user_number)
elif user_number.upper() == "Q":
break
else:
print("Invalid input\n")
elif report.upper() == "T":
if user_number.isdigit():
total += int(user_number)
#You forgot ot add this : "items.append(user_number)"
items.append(user_number)
elif user_number.upper() == "Q":
break
else:
print("Invalid input\n")
break
#Add this for loop termination: "or 0 to quit: "
report = input("Report types include All Items (\"A\") or Total Only (\"T\")\nPlease select report type \"A\" or \"T\" Or 0 to quit: ")
while True:
#it should be this ""if report.upper() in "A" or "T":"" not this ""if report.upper() in "A T":""
if report.upper() in "A" or "T":
adding_report(report)
#The condition below terminates the program
elif report == '0':
break
else:
print("Invalid input")
report = input("Please select report type \"A\" or \"T\": ")

Categories