'while' loop not behaving as expected - python

Background:
I have made a program that takes a text input, applies encryption (a simple cipher) and saves the output to a list - if desired. Messages can also be decrypted.
The program is navigated through an options menu:
1. Encrypt a message
2. View encrypted messages
3. Decrypt a message
To allow all sections of the program to access the same list (variable) of saved messages, I have written it within a class. Within the class exist def's that call on this list.
Only the 'encrypt a message' bit has been written so far.
Problem:
The user decision flow is made with two Y/N choices.
However, the choices do not work - even if the user types in 'N' - my program thinks they have typed 'Y' in both cases.
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
I think the problem lay within the scope, and that somehow the same variable is not being referenced when setting and reading Y or N. I have been going up and down the same code for about 3 hours and still nothing, declaring all variables in many different places with no luck, so any advice greatly appreciated.
Full executable code:
class cct:
print("Welcome to the CaeserCipher tool v1.0")
menu_state = "main" #This is used to record what state the program is in
unciphered_messages = [] #Decrypted messages are saved here
ciphered_messages = [] #Encrypted messages are saved here
def menu(): #This is the main menu interface
while cct.menu_state == "main": #This while
cct.menu_state = input("What would you like to do? \n 1: Encrypt a Message \n 2: View Encrypted Messages \n 3: Decrypt a message\n")
if cct.menu_state == "1":
cct.encrypt()
elif cct.menu_state == "2":
cct.view()
elif cct.menu_state == "3":
cct.decrypt()
elif cct.menu_state == "main":
print("\n\nWelcome back to the menu!\n\n")
else:
print("You did not enter a valid choice. Please enter a number between 1 and 3.\n")
cct.menu_state = "make_choice"
continue
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
#This while loop continually takes messages, gives the option of saving, and asks if you want to cipher another
while cct.menu_state == "1":
text = input("Enter your message: ") #Enter the message you wish to cipher
cipher = '' #Create a string for the cipher
for char in text: #This for sub-loop will increment each character by 1. e.g. A -> B, T -> U, Z -> A
if not char.isalpha():
continue
char = char.upper()
code = ord(char) + 1
if code > ord('Z'):
code = ord('A')
cipher += chr(code)
print(' '.join(["Your ciphered message is:", cipher]))
save_cip()
print(cct.ciphered_messages)
#This sub-while loop is reponsible for checking if you want to cipher another message
#and making sure the user has made a valid choice
choosing_another = True
while choosing_another == True:
choice_variable = input(' '.join(["You have", str(len(cct.ciphered_messages)), "saved messages \n", "Would you like to Cipher another? (Y/N)\n"]))
if choice_variable == "Y" or "y":
print("You chose yes")
choosing_another = False
elif choice_variable == "N" or "n":
print("You chose no")
cct.menu_state = "main"
choosing_another = False
else:
choice_variable = input("That was not a valid entry, please enter Y or N only: \n")
continue
return
def view():
#TO BE CODED
return
def decrypt():
#TO BE CODED
return
cct.menu()

This is always true:
if save_choice == "Y" or "y":
bacause its interpreted as :
if (condition) or (condition):
the 1st condition is (save_choice == "Y")
the 2nd condition is just ( "y" ) which python interprets as 'True'
So the whole condition is always True.
U probably mean:
if save_choice == "Y" or save_choice == "y":
Or better :
if save_choice.lower() == "y":

Not a python programmer, but i don't think python allows a "implied" subject for the or operator
--> IF save_choice == "Y" OR save_choice == "y" :

Related

Breaking out of loop - Python

I've tried googling and searching on SO, but I cant figure out why my break on the second to last line is not heading out of the while loop. Better yet, I cant figure out why the loop is not continuing either. My intention is to give the user the possibiltiy to head to the main menu after the last choice (basically the while loop for menuchoice (which is one loop above what I have pasted here).
Any suggestions? Thank you in advance. It feels like I'm missing something essential.
#this is going to show how many exercise weapons you need for next magic level
if menuchoice == "4":
#these functions returns the amount of magic wands/rods that is needed to be spent for next magic level
print("Select vocation")
print("Press P for Royal Paladin")
#ask user to input vocation:
while True:
vocationchoice = input()
if vocationchoice == "P" or vocationchoice == "p":
#ask user to input magic level for paladin
num1 = float (input("Enter your magic level: "))
#ask for own training dummy
print("Do you have your own exercise dummy? Type Y for yes and N for no.")
while True:
trainingdummy = input()
if trainingdummy == "y" or trainingdummy == "Y":
#list the different exercise weapons
print("Select exercise weapon:")
print("1. Training rod")
#loop, where we ask user to input what exercise weapon they want to calculate
while True:
while True:
weaponchoice = input()
if weaponchoice == "q":
sys.exit() #quit the program
if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
break #break out of the input loop
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
if trainingdummy == "n" or trainingdummy == "N":
#list the different exercise weapons
print("Select exercise weapon:")
print("1. Training rod")
#loop where ask user to input what exercise weapon they want to calculate
while True:
weaponchoice = input()
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpal(num1))) + ".")
elif weaponchoice == "f":
break
print("\nGo to main menu? Press F.")
This will help you I think. Break only breaks from current loop. If you want to go up on levels you need to break from each loop separately.
A suggestion is to turn a loop into a function and use return which will effectively exit any loop. A little bit of code refactor will be needed though.
If not the case can you maybe provide some more info and possibly the full code (there is a higher loop that we dont see here?)
First, you should print things in the input() command as it will be cleared in intend: input("Text to display").
Second, if you want to exit to the main menu, you need to break every nested loop. Here you only break the most inner loop.
As in Python there is no goto instruction nor named loops, you can use a flag. A flag is set to true when the used presses 'F' and this flag is then used at the beginning of every outer nested loop to break them. It can look like this:
while True: # This is your menu loop
menuFlag = False # Declare and set the flag to False here
menu = input("Choose the menu: ")
# ...
while True: # Choose character loop
if menuFlag: break # Do not forget to break all outer loops
character = input("Choose a character: ")
# ...
while True: # Any other loop (choose weapon, ...)
weapon = input("Choose weapon: ")
# Here you want to return to the menu if f is pressed
# Set the flag to True in this condition
if weapon == "f":
menuFlag = True
break
In your game this ressembles to:
goToMainMenu = False
while True:
if goToMainMenu: break
vocationchoice = input("Select vocation.\nPress P for Royal Paladin: ")
if vocationchoice == "P" or vocationchoice == "p":
#ask user to input magic level for paladin
num1 = float (input("Enter your magic level: "))
#ask for own training dummy
while True:
if goToMainMenu: break
trainingdummy = input("Do you have your own exercise dummy?\nType Y for yes and N for no: ")
if trainingdummy == "y" or trainingdummy == "Y":
#loop, where we ask user to input what exercise weapon they want to calculate
while True:
while True:
weaponchoice = input("Select exercise weapon:\n1. Training rod: ")
if weaponchoice == "q":
sys.exit() #quit the program
if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
break #break out of the input loop
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
if trainingdummy == "n" or trainingdummy == "N":
#list the different exercise weapon
#loop where ask user to input what exercise weapon they want to calculate
while True:
weaponchoice = input("Select exercise weapon (press F for main menu):\n1. Training rod: ")
#User choice
if weaponchoice == "1":
print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")
elif weaponchoice == "f" or weaponchoice == "F":
goToMainMenu = True
break
Add a break for weaponchoice == "1" to get out of the loop.

How would I make Python read a file line and use it as a variable?

Tried looking it up elsewhere, to no avail. How would I do something like, having Python read a file line, then use what's in that line as a variable for a different file?
Essentially, I want a different file that acts as a verification key, and when the content of the file (the passkey) is entered, my code recognizes that and passes it, then opening said file. I also want to be able to read a lockout file to check and see whether the user should be "locked out", and need to enter the passkey. Any possible way of doing this?
Update: I edited the code a little by my self, just so everyone is aware.
filename = ".UbuntuAlt/.Info.txt"
#I'm aware that the use of many of the "quit()" functions is ambiguous but idc
verify = ".UbuntuAlt/.Verify.txt"
locktxt = ".UbuntuAlt/.Lockout.txt"
#this is where I want to make ".Lockout.txt" verify whether the passkey needs to be used, and set variable "lockout" accordingly
infotxt = open(filename, "r")
verifyread = open(verify, "r")
locktestw = open(locktxt, "w")
locktestr = open(locktxt, "r")
if lockout == True:
verify1 = raw_input("Please enter verification key: ")
#this is where I want the code to read ".Verify.txt" and use its content as the passkey
if verify1 == "look above":
for line in infotxt:
print line,
infotxt.close()
verifyread.close()
lockout = False
#this is where I want ".Lockout.txt" edited to be false-- I can do that myself though
lockoutq = raw_input("Lockout is disabled. Reenable? [Y/n]: ")
if lockoutq == "y" or "Y" or " ":
#also where I plan on editing it
quit()
if lockoutq == "n" or "N":
quit()
else:
lockdownerr = raw_input("Invalid input. [2] attempts remaining. Reenable? [Y/n]: ")
if lockdownerr == "y" or "Y" or " ":
#aaa
quit()
if lockdownerr == "n" or "N":
quit()
else:
lockdownfinal = raw_input("Invalid input. [1] attempt remaining. Reenable? [Y/n]: ")
if lockdownerr == "y" or "Y" or " ":
#aaa
quit()
if lockdownerr == "n" or "N":
quit()
else:
print "Invalid input. Enabling anyway."
#you get the point
quit()
else:
verifyread.close()
print "You've inputted an invalid key. Aborting."
quit()
else:
for line in infotxt:
print line,
infotxt.close()
verifyread.close()
lockoutq2 = raw_input("Lockout is disabled. Reenable? [Y/n]: ")
if lockoutq2 == "y" or "Y" or " ":
#same as above w/ editing the lockout text
quit()
if lockoutq2 == "n" or "N":
quit()
else:
lockdownerr = raw_input("Invalid input. [2] attempts remaining. Reenable? [Y/n]: ")
if lockdownerr == "y" or "Y" or " ":
#aaa
quit()
if lockdownerr == "n" or "N":
quit()
else:
lockdownfinal = raw_input("Invalid input. [1] attempt remaining. Reenable? [Y/n]: ")
if lockdownerr == "y" or "Y" or " ":
#aaa
quit()
if lockdownerr == "n" or "N":
quit()
else:
print "Invalid input. Enabling anyway."
#you get the point
quit()
this is where I want the code to read ".Verify.txt" and use its content as the passkey
I suggest you start with a much smaller example e.g.
verify1 = raw_input("Please enter verification key: ")
passkey = open(".Verify.txt").read().strip()
if verify1 == passkey:
print("Match")
else:
print("Not Match")
Similarly, you can open .Lockout.txt and check its contents for lockout
If you need to open a file for read/write, use "rw", not two variables for doing either against the same file.

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\": ")

python trouble getting code to work

update so it seems like no matter what i do or type it asks
what would you like to add?
instead of doing the other options it just keeps asking this
it should only be asking this if the user types a
this is a 2 issue thing im having and the main original post is here
How to debug errors in Python?
but the bigger issue im having is i cant get the bottom half of my code to work
it just ignores the inputs given to it and continues to add them to the list
#.....
elif user == "d" :
listdelete = input("what item do you want deleted")
list.remove (listdelete)
elif user == "p" : # prints the list
print (list)
elif user == "x" : # exits the program
print ("good bye")
print ("!!!!!!that is not a choice!!!!!!")
#right now everything is being called through a single procedure
print (option())
and on the bottom here is going to be the entire code sorry for pasting the entire code on the bottom here but i thought it would be easy to understand the whole issue if i showed the whole code and then the section thats not working since its all under one procedure
list = []
def option() :
print ("(a) -to add item ")
print ("(d) -to delete item")
print ("(p) -to see items on your list")
print ("(x) -to exit ")
#above just prints out user options with a input after
user = input("please select a choice")
if user == "a" :
item = input("what would you like to add? ")
list.append (item)
# next im going to ask if they would like to add another item
more = input(" would you like to add something else? yes or no")
while more == "yes":
if more == "yes" :
item = input("what else would you like to add? type b to back ")
if item == "b" :
print (option())
else :
list.append(item)
elif more == "no" :
print (option())
#.....
elif user == "d" :
listdelete = input("what item do you want deleted")
list.remove (listdelete)
elif user == "p" : # prints the list
print (list)
elif user == "x" : # exits the program
print ("good bye")
print ("!!!!!!that is not a choice!!!!!!")
#right now everything is being called through a single procedure
print (option())
I have updated your code which still has flaws and exploits the mutability of the list datatype but does work as you would expect it:
#!/usr/bin/env python
def AddElement(collection):
elementToAdd = input("What would you like to add: ")
collection.append(elementToAdd)
return collection
def DeleteElement(collection):
print("You have the following items:", collection)
elementToDelete = input("What item do you want deleted: ")
for elements in collection:
if elements == elementToDelete:
collection.remove(elements)
print("You have the following items left:", collection)
return collection
def WriteMenu():
print("(a) -to add item")
print("(d) -to delete item")
print("(p) -to see items on your lst1")
print("(x) -to exit")
return True
def option():
WriteMenu()
UserInput = input("Please select a choice: ")
while UserInput:
if UserInput == "a":
AddElement(collection)
elif UserInput == "d":
DeleteElement(collection)
elif UserInput == "p":
print(collection)
elif UserInput == "x":
print("Good bye!")
break
WriteMenu()
UserInput = input("Please select a choice: ")
else:
print(collection)
#right now everything is being called through a single procedure
collection = []
option()

"while loop" not breaking (using Python)

This is my code :
#Choose Report
def chooseReport():
print "Choose a report."
while True:
choice = raw_input("Enter A or B: ")
if choice == 'a' or choice == 'A':
reportA()
break
elif choice == 'b' or choice == 'B':
reportB()
break
else:
continue
When I input either a or b, it just asks me to "Enter A or B" again. It doesn't go to the functions its supposed to.
Any idea why is this?
The code is perfect, except a redundant else, as mentioned in the comment. Are you entering a (a + space) rather than simply a (a without space) ? The problem is in the input that you are providing and not in the code!
def chooseReport():
print "Choose a report."
t=True # t starts at true
while t:
choice = raw_input("Enter A or B: ")
if choice == 'a' or choice == 'A':
reportA()
t=False # t turns false to break out of loop
elif choice == 'b' or choice == 'B':
reportB()
t=False
Try this. It keeps looping when t is true and stops when t is false. The problem might also be in reportA or reportB or how you are calling chooseReport.
The problem is in the raw_input(). It returns a string but maybe this string is "a " or "a\n" though you have entered "a" or "b".
I would do this:
def chooseReport():
print "Choose a report."
while True:
choice = raw_input("Enter A or B: ")
if "a" in choice or "A" in choice:
reportA()
break
elif "b" in choice or "B" in choice:
reportB()
break
else:
continue
Tried your code in the following script, it works fine both on Linux and on Windows.
def reportA():
print "AAAAA"
def reportB():
print "BBBBB"
#Choose Report
def chooseReport():
print "Choose a report."
while True:
choice = raw_input("Enter A or B: ")
if choice == 'a' or choice == 'A':
reportA()
break
elif choice == 'b' or choice == 'B':
reportB()
break
else:
continue
chooseReport();
First, your code works fine, the most probably error is that you are writing a wrong input (e.g: with more characters). To solve that you could use "a" in choice or "A" in choice. But if it isn't working... keep reading.
It's seems that break isn't affecting the while loop, I don't have python 2 so I am not very sure why (in python 3 [after change raw_input to input and print to print()] your code works perfect). So you should use the condition of the while to break it.
while True work theorically for ever because each time the code is executed it checks the condition -True- and because it's true it keeps looping.
You could manipulate that condition in order to break the loop (don't allow execute again its code).
For example you could use this:
#Choose Report
def chooseReport():
print "Choose a report."
allow = True # allow start as True so the while will work
while allow:
choice = raw_input("Enter A or B: ")
if choice.lower().strip() == "a": # This is better. .lower() make "A" > "a", and .strip() delete " a " to "a", and "a/n" to "a".
reportA()
allow = False # allow now is False, the while won't execute again
elif choice.lower().strip() == "b":
reportB()
allow = False # allow now is False, the while won't execute again
# The else is complete redundant, you don't need it
Code is fine. I think you call your chooseReport() function in a loop or your input has extra characters and if conditions didn't satisfied.

Categories