Why is this creating an infinite loop? And if it isn't creating one, why does the program freeze up? Not like IDLE stops responding, It just stops like I created a infinite loop and the only thing it does is input(). Try the code out to see what I mean.
(also, tell me if the for's are correct in the comments please)
Accounts = {}
def create_account(x,y,z,a):
global Accounts
Checked = False
while Checked == False:
if x in Accounts:
print("Sorry, that name has already been taken")
print("Please choose a new name")
x = input()
for dictionary in Accounts:
for key in dictionary:
if a in key:
print("Sorry, password is invalid or not avalible")
print("Please choose a new password")
a = input()
Accounts[x] = {"Proggress":y,"Points":z,"Pass":a}
print(Accounts[x])
Your code creates an infinite loop because there is nothing to stop it.
while checked == False will do exactly what it sounds like, it will loop over the code over and over until checked = True OR until you break
break will simply stop the loop, allowing the program to finish.
checked = True will also stop the loop
I think that what you are trying to do is something like this:
This code is untested
Accounts = {}
def create_account(x,y,z,a):
global Accounts
Checked = False
while Checked == False:
if x in Accounts:
print("Sorry, that name has already been taken")
print("Please choose a new name")
x = input()
else:
passwordOk = True
for dictionary in Accounts:
for key in dictionary:
if a in key:
passwordOk = False
break
if not passwordOk:
break
if not passwordOk:
print("Sorry, password is invalid or not avalible")
print("Please choose a new password")
a = input()
else:
Checked = True # this is the important part that you missed
Accounts[x] = {"Proggress":y,"Points":z,"Pass":a}
print(Accounts[x])
Just for you to know, your code can be optimized. I tried to solve your issue by modifying as minimum code as possible, so that you could understand the problem
There are two issues causing this.
As you say,
the print() is before the input(), and the print never outputs, so it doesn't get that far
However, let's take a step back: the print statements are inside the block if x in Accounts:. At the very first line, you set Accounts to be an empty dictionary (Accounts = {}), so no matter what x is, at that point, x in Accounts will never be true - there's nothing in it.
Now, you do have a line that adds items to Accounts:
Accounts[x] = {"Proggress":y,"Points":z,"Pass":a}
However, as other people have pointed out, you'll never get here - it's outside the loop, and the loop never exits because Checked is never set to True, nor is a break called.
Your program then is essentially just going through the same few steps that don't do anything:
Does Checked == False? Yep, continue the loop.
Is x in Accounts? Nope, skip this block.
For every dictionary in Accounts, do some stuff, but Accounts is empty, so I don't need to do anything.
Does Check == False? Yep, continue the loop.
Related
I'm "newish" to python programming. I'm trying my best to make my code look nice and function well. I'm using Pycharm as my IDE. I'm doing something for myself. I play tabletop RPG's and I'm attempting to create a character creator for a game I play. I have everything working well, but Pycharm is telling me that "Expression can be simplified" and "PEP 8: E712 comparison to True should be 'if cond is not True:' or 'if not cond:'"
Here is the code in question:
fname = False
while fname != True:
new_character.firstName = input('What would you like your first name to be?\n').capitalize()
if 1 >= len(new_character.firstName) or len(new_character.firstName) > 20:
print('Name does not meet length requirements. Please try again.')
if new_character.firstName.isalpha() != True:
print('Please do not use numbers or special characters in your name. Please try again.')
if (1 < len(new_character.firstName) < 20) and (new_character.firstName.isalpha() == True):
fname = True
Pycharm is telling me that my "while fname != True:" is the part that can be simplified as well as the "if new_character.firstName.isalpha() != True:".
I've tried googling a solution for what I'm doing, but most of them are for something kinda like what I'm asking, but never with the != True portion. I've even reached out to one of my friends that's a python programmer, but I haven't heard back yet.
Again, I want to state that as it is now, the code works correctly the way it is written, I'm just wanting to understand if there is a way to make the code look cleaner/neater or do the same function and be simplified somehow.
Any pointers on how to potentially simplify those lines of code and maintain the functionality would be greatly appreciated.
Here's one way you could rewrite this code to make it easier to read, and more efficient:
# Loop until the user provides a good input
while True:
# Set a temp variable, don't constantly reassign to the new_character.firstName attribute
name = input('What would you like your first name to be?\n').capitalize()
# If the name isn't between 2 and 20 characters, start the loop over at the beginning
if not (1 < len(name) <= 20):
print('Name does not meet length requirements. Please try again.')
continue
# If the name contains anything other than letters, start the loop over at the beginning
if not name.isalpha():
print('Please do not use numbers or special characters in your name. Please try again.')
continue
# You can only reach this break if the name "passed" the two checks above
break
# Finally, assign the character name
new_character.firstName = name
One thing you could do to simplify further is to check both conditions at the same time, and print a more helpful error message that re-states the requirements explicitly:
NAME_ERROR_MESSAGE = """
Invalid name '{name}'. Your character's name
must be between 2 and 20 characters long, and
contain only letters. Please try again.
"""
while True:
name = input('What would you like your first name to be?\n').capitalize()
if (1 < len(name) <= 20) and name.isalpha():
new_character.firstName = name
break
print(NAME_ERROR_MESSAGE.format(name=name)
So I've almost finished a calculator but after giving the results, I want it to ask if I'm still gonna use it.
At the beginning of the code I have this loop to make it start again unless I typed 'n'.
# LOOP TO MAKE IT STAY ON
import sys
from colorama import init
from colorama import Fore, Back, Style
init()
while True:
Then the rest of the code which is finished goes on.
Then, at the end, I've tried this:
answer = input()
def badanswer():
if answer != "y" or "n":
return True
else:
return False
while badanswer is True:
print ("Wrong answer")
answer = input(("Wanna keep using the calculator? y/n "))
if badanswer is False:
if answer == "y":
continue
else:
break
sys.exit()
Somehow when I test it I type a random letter (not y or n) and the program continues... What I am missing here? I'm pretty new to python so forgive my mistakes! Thanks.
One problem is the
if answer != "y" or "n":
"or" is a logical operator, and does not allow you to "double" a != comparison like you are trying to do. The actual meaning of this statement is if answer is not "y", or if "n", and "n", like any nonempty string, is always True in boolean context.
You want
if answer not in ("y", "n"):
You also need to actually call badanswer() by adding the parentheses.
There's also no reason to add the if True to the loop condition — while badanswer() does the same thing.
badanswer is a function, not a boolean. You need to call the function and get its return value, like so: if badanswer() is True
However, your logic for exiting the program is needlessly contrived. You don't need the badanswer function at all. Just get the input from the user and check whether it is 'y' or 'n'.
while True: # loop for exit prompt
answer = input("Wanna keep using the calculator? y/n ").lower()
# using .lower() to permit 'Y' and 'N' as well
if answer == "n":
sys.exit()
elif answer == "y":
break
# exits from the 'exit prompt' loop,
# returns to the outside calculator loop
else:
print("Bad answer!")
Note: As mentioned in the comments, sys.exit() is a pretty cutthroat way to exit your program. You can do it more gracefully by modifying a variable that is checked by the outer calculator loop; e.g., initialize a variable keep_running = True, run the main loop with while keep_running: (...) and if the user requests to exit from the calculator, set keep_running = False so that the main loop exits.
I have two functions, one checks if you would like to add any items to a dictionary, and then checks what the value of that item is and saves that data to a file. If you are done adding new items to the dictionary it moves to the next function that checks if you would like to change the value of any currently existing items. If everything is good to go you can command the program to exit.
My problem is creating the while loop and to make it call the first function and run it but when you have no more items to add I need it to call the next function and makes sure you don't need to change any values of currently existing items. And then when the exit command is put in it exits the while loop and the program quits. I can't figure out how to make the while loop determine the first function is over and to call the next one.
I had made the program work properly by using recurrence and no while loop. But somebody told me that was sloppy. Also I made it work when I built the functions inside the while loop, but they told me that was sloppy too. So I am trying to make the while loop after the functions are built and call for the functions inside of it. Thanks in advance and hopefully my question is clear.
# current dictionary
itemNames = {}
# checks if you want to add to your dictionary
def addToDictionary():
checkIF_newItems = raw_input("Add new item? 'YES' or 'NO' \n ").upper()
if checkIF_newItems.startswith("Y"):
newItems = raw_input("What type of item would you like to add today? \n")
newItems_Name = raw_input("What is the value of your new item? \n")
itemNames[newItems] = newItems_Name
return True
elif 'PRINT' in checkIF_newItems:
print "These are your current items. \n\n"
return True
elif checkIF_newItems.startswith("N"):
print("OKAY")
exit()
elif 'Exit' in checkIF_newItems:
exit()
# checks if you want to edit your current dictionary
def check_forChanges():
#checks user intent and if YES prints current keys
checkIf = raw_input("Change item value? 'YES' 'NO' 'EXIT' 'ADD' 'PRINT' \n").upper()
print("\n")
if checkIf.startswith("Y"):
for i in itemNames.keys():
print i
print("\n")
#finds what key to access and ask for its new value
itemChoice = raw_input("what item would you like to change the value of? \n")
return True
if itemChoice in itemNames.keys():
newName = raw_input("What is the new value? \n")
itemNames[itemChoice] = newName
print("You've changed your " + itemChoice + "'s value to " + newName + ".")
return True
print('\n')
return True
#if NO then checks to exit
elif checkIf.startswith("N"):
CLOSE = raw_input("OKAY then, would you like to exit? ").upper()
if CLOSE.startswith('Y'):
exit()
return False
elif EXIT.startswith('N'):
check_forChanges()
elif EXIT is 'print':
for i in itemNames:
print i
return True
# goes back to first function
elif 'ADD' in checkIf:
addToDictionary()
return True
#prints current values
elif 'PRINT' in checkIf:
for i in itemNames.values():
print i
return True
elif 'EXIT' in checkIf:
exit()
return False
# main routine
validIntro = False
while not validIntro:
addToDictionary()
if addToDictionary() == False:
continue
else:
exit()
check_forChanges()
if check_forChanges() == False:
break
else:
continue
But I expect to be able to run this program until the user decides to quit. Also I expect the single while loop to call both of my functions but only when necessary.
My problem is creating the while loop and to make it call the first function and run it but when you have no more items to add I need it to call the next function and makes sure you don't need to change any values of currently existing items. And then when the exit command is put in it exits the while loop and the program quits. I can't figure out how to make the while loop determine the first function is over and to call the next one.
It sounds like you want to keep adding to the dictionary until the user says "nothing more to add" and then checks the values until the user quits. That would look something like:
while addToDictionary(): pass
while check_forChanges(): pass
You'd have to modify your existing functions to False when the current action is complete and to call sys.exit() when the user asks to quit. Although I don't think you need to ask for quitting -- if they don't want to add or check, then they're done and the loops have terminated.
Do you ever want the user to add to the dictionary after check_forChanges is called? If yes, but you still want to enforce adding is done, then checking, then maybe more adding, you want a loop around the whole thing:
keep_looping = True
while keep_looping:
while addToDictionary(): pass
while check_forChanges(): pass
keep_looping = askToContinue()
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 6 years ago.
This seems kind of simple but for the life of me I have no idea on how to even approach this
At the end of my code, I have a
if(__name__ == "__main__"):
block
And after that line I ask for the users input for something and I execute my function kind of like so
b = input("enter something")
run_my_func(b)
And right now it just ends right there.
How can I make it so that it will again ask for an input or exit of the user inputs nothing and presses enter
My initial idea was to put it in a while loop? But I'm not sure if that'd work/how to implement it
Yes, you can use a while loop. Because you need to check a condition (empty user input) right in the middle of the loop to decide when to stop, there's a standard trick for this. You write a while True loop which runs forever by default, and then you use break statement when the condition is met to end the loop early:
while True:
b = input("enter something: ")
if b == "":
break
run_my_func(b)
A while loop would be a great way to implement what you are trying to do. Below is an example:
functional = True
while functional:
userInput = input("enter something")
if userInput == "":
functional = False
else:
print(userInput)
Basically, for every iteration in which the while loop condition evaluates to True, it will run the code inside of the while loop. So when the user enters "" (nothing) we want the while loop condition to evaluate to False for the next iteration -- so you can implement this a variety of ways, my approach was to set a variable called functional to False.
You're right! Wrap your function in a while loop and it will keep asking until it gets something none empty!
b = ''
while b == '':
b = input("enter something")
run_my_func(b)
This works in python3
A good Pythonic while loop would look like this:
b = input("enter something")
while not b:
b = input("enter something")
run_my_func(b)
Hi so I am working on a game and my game at the start asks the user if they want the rules to the game (y/n). I'm using if statements and else for this, so if user puts in y print rules and if user puts in n start game etc...it works fine, until the user puts in an integer or a word or something python doesn't recognize and it just goes and uses the else statement. My game is a math game so I used try statements before that if the user punched in something that's not a number it tells the user "Invalid, try again". The problem I'm having now is how to tell python to try multiple things...
I tried using try x = 'y' or x = 'n' but it says you can't give try multiple operations or something
Please help,
Cheers
You might want to use the following:
if inp=="Option1":
...
elif inp=="Option2":
...
elif inp=="Option3":
...
else:
print "Not known command"
You need a while loop that will keep taking input until the user inputs either y or n
while True:
inp = raw_input("Add intruction here")
if inp == "y":
# code here
elif inp == "n":
# code here
else:
print "Invalid input"