I am trying to finish off my program my adding a menu that allows the user to select a few options that allow the user to store website names and passwords in lists. But there was a problem as soon as I have appended some website names and passwords into their respective vaults where whenn I try to select an option after appending the website names and passwords, "1" for example is the expected input to call the viewapp() function to see the websites and passwords stored so far. The thing is it takes more than twice to call the viewapp() function, where it rejects the first expected input but accepts the 2nd one strangely. Also when I select the 3rd option for the purpose to call summary(), the whole printed summary would print out twice, which is a similar pattern to the menu only accepting the 2nd expected input. The program is doing what I want except for this annoying bug where selecting those four options makes it ask for input a second time when it's supposed to straight away jump to that function. Help would be appreciated.
appvault = []
passvault = []
def logged():
print("----------------------------------------------------------------------\n")
print("Hello, welcome to the password vault console. ")
modea = input("""Below are the options you can choose from in the password vault console:
##########################################################################\n
1) Find the password for an existing webiste/app
2) Add a new website/app and a new password for it
3) Summary of the password vault
4) Exit
##########################################################################\n
> """).strip()
return modea
def viewapp():
if len(appvault) > 0:
for app in appvault:
print("Here is the website/app you have stored:")
print("- {}\n".format(app))
if len(passvault) > 0 :
for code in passvault:
print("Here is the password you have stored for the website/app: ")
print("- {}\n".format(code))
else:
print("You have no apps or passwords entered yet!")
def addapp():
while True:
validapp = True
while validapp:
new_app = input("Enter the new website/app name: ").strip().lower()
if len(new_app) > 20:
print("Please enter a new website/app name no more than 20 characters: ")
elif len(new_app) < 1:
print("Please enter a valid new website/app name: ")
else:
validapp = False
appvault.append(new_app)
validnewpass = True
while validnewpass:
new_pass = input("Enter a new password to be stored in the passsword vault: ")
if not new_pass.isalnum():
print("Your password for the website/app cannot be null, contain spaces or contain symbols \n")
elif len(new_pass) < 8:
print("Your new password must be at least 8 characters long: ")
elif len(new_pass) > 20:
print("Your new password cannot be over 20 characters long: ")
else:
validnewpass = False
passvault.append(new_pass)
validquit = True
while validquit:
quit = input("\nEnter 'end' to exit or any key to continue to add more website/app names and passwords for them: \n> ")
if quit in ["end", "End", "END"]:
logged()
else:
validquit = False
addapp()
return addapp
def summary():
if len(passvault) > 0:
for passw in passvault:
print("----------------------------------------------------------------------")
print("Here is a summary of the passwords stored in the password vault:\n")
print("The number of passwords stored:", len(passvault))
print("Passwords with the longest characters: ", max(new_pass for (new_pass) in passvault))
print("Passwords with the shortest charactrs: ", min(new_pass for (new_pass) in passvault))
print("----------------------------------------------------------------------")
else:
print("You have no passwords entered yet!")
while True:
chosen_option = logged()
print(chosen_option)
if chosen_option == "1":
viewapp()
elif chosen_option == "2":
addapp()
elif chosen_option == "3":
summary()
elif chosen_option == "4":
break
else:
print("That was not a valid option, please try again: ")
print("Goodbye")
This happens because you call logged() when exiting addapp():
if quit in ["end", "End", "END"]:
logged()
Then, the choice you enter is returned by logged(), and thrown away as it isn't assigned to anything.
You're now back at the end of the previous block in addapp(), and the next instruction is return addapp, that will bring you back to your main loop, where you'll be sent to logged() again by chosen_option = logged()
Note that in return addapp, you return the addapp function itself, which is certainly not what you want to do. So, as you don't need a return value for addapp(), just use return, or nothing at all, Python will automatically return at the end of the function.
So, to solve your problem: directly return when you're done entering sites:
if quit in ["end", "End", "END"]:
return
Note also that you recursively call addapp() from itself when you add more sites.
You should generaly avoid that unless you really want to use some recursive algorithm, and rather use a loop as you did in your main loop. By default, Python limits you to 1000 recursion levels - so you could even crash your app by entering more than 1000 sites in a row ;)
The summary problem is only caused by the unnecessary for loop in summary()
You are nearly there. The issue is in the addapp() function at line 63:
if quit not in ["end", "End", "END"]:
logged()
if you replace
logged()
with
pass
Then everything will work a ok.
You are not handling the result of the logged function here anyway.
You also do not need to process the logged function here. The addapp will exit and the logged function will be called and handled in the while loop the addapp function was called from.
Related
There's one last feature I want for my bank account system.
I want it to check if a username has already been saved to the text file database. If the username already exists, then it should tell the user that they can't have that name option. If not, then they would be able to use it.
The rest of my code works as it should, it's just the fcat that I can't append/update my text file properly and see if usernames already exist in the text file database.
import sys
users = {}
status = ""
# Functions ---------------------------------------------------------------------------------------------------------
# Select either account creation or login
def displayMenu():
global status
status = input("Are you a registered user? \n1 - Yes \n2 - No \nQ - Quit \n")
if status == '1':
oldUser()
elif status == '2':
newUser()
else:
print("Unknown input error, exiting . . . .")
sys.exit(0)
return status
# Account creation
def newUser():
global createLogin
createLogin = input("Create login name: ")
if createLogin in users: # check if login name exists
print ("\nLogin name already exists!\n")
else:
createPassw = input("Create password: ")
users[createLogin] = createPassw # add login and password
print("\nAccount created!\n")
#---- Storing the username in a txt file
file = open("accountfile.txt", "a")
file.write(createLogin)
file.write("\n")
file.close()
oldUser()
# Account login
def oldUser():
global login
login = input("Enter login name: ")
passw = input("Enter password: ")
# check if user exists and login matches password
if login in users and users[login] == passw:
file = open("accountfile.txt", "r")
for text in file: ######## This is where I'm trying to compare username duplicates
if text in file == createLogin:
print("Username already exists!")
print("\nLogin successful!\n")
Bank_Account()
else:
print("\nUser doesn't exist or wrong password!\n")
print("Restarting. Please enter details correctly . . . . .")
sys.exit(0)
class Bank_Account:
def __init__(self):
self.balance=0
response = ''
def deposit(self):
try:
amount=float(input("Enter amount to be Deposited: "))
except ValueError:
print("Enter digits only")
else:
self.balance += amount
print("\n Amount Deposited:",amount)
def withdraw(self):
try:
amount = float(input("Enter amount to be Withdrawn: "))
if self.balance>=amount:
self.balance-=amount
print("\n You Withdrew:", amount)
except ValueError:
print("Enter digits only")
s.withdraw()
else:
print("\n ")
def display(self):
print("\n Remaining Balance=",self.balance)
displayMenu()
s = Bank_Account()
# Calling functions with that class object
s.deposit()
s.withdraw()
s.display()
So it looks you are are writing the user input in the file accountfile.txt. So after a few users log in it might look something like:
$ cat accountfile.txt
mike
sarah
morgan
lee
The section of your code in question is here:
file = open("accountfile.txt", "r")
for text in file:
if text in file == createLogin:
print("Username already exists!")
This particular part is probably not doing what you think it's doing:
if text in file == createLogin
...
if text in file is returning either True or False.
...
So the line above is essentially saying
if False == createLogin
or
if True == createLogin
I believe what you want to do is check if a name is in accountfile.txt. The smallest change you could make to your code in order to achieve that would be
file = open("accountfile.txt", "r")
for text in file:
if text.strip() == createLogin: # .strip() will clean up the \n
print("Username already exists!")
This line:
if text in file == createLogin: is where you are making a mistake. The line is essentially saying:
"(if the text is in the file) compare the result of that check with the string createLogin".
i.e. if (True/False) == createLogin, which is always false because the True/False boolean primitives are never equal to any string (if it actually runs, i have not tested to see if an exception will be thrown).
what you should do is this
for text in file: # get one line of text
if createLogin == text.strip(): # compare the line with the user input string
print("Username already exists!")
break
.strip() removes any leading or trailing spaces in the database stored name (in this case the line break character \n used to denote the end of a line in the file. break ends the loop prematurely cos your lookup is complete since you found what you were looking for, and it would be an unnecessary to continue comparing the user input with other strings, imagine the txt had 1000 names and the 1st name was a match, the user would see the error printed but the program would continue running for the rest of the 999 tries, making it seem sluggish and waste unnecessary CPU cycles.
The database is still case sensitive however which may or may not be desired depending on your requirements. For case insensitivity you could do the following:
for text in file: # get one line of text
if createLogin.lower() == text.strip().lower(): # compare the line with the user input string
print("Username already exists!")
break
.lower() makes both strings into lower case strings and then checks if they are the same, eliminating the case sensitivity.
Instead of writing to the text file, try pickling the database.
This will save a representation of the object that you can easily load back into your program.
import pickle
users = {}
users["Ash"] = "password"
pickle.dump(users, open("users.p", "wb"))
loaded_users = pickle.load(open("users.p", "rb"))
print(loaded_users)
A more advanced solution may also be to check out a relational database, such as [sqlite3][1]
I am trying to write a menu in which option 1 would add a key:value pair to a dictionary and option 2 would run a threading module using the items from the dictionary. Key is a message from the user input and Value is a number of seconds, from the user input, that a thread should pause for, before displaying the message.
Threading itself is irrelevant right now though. What I'm struggling with is the fact that when I use the function for option 1, it adds the key:value pairs to the dictionary (called messages_and_times) successfully. But as soon as the function is finished the dictionary becomes empty again, as can be seen from the function for option 2, which accesses it.
At the bottom you can see my code. I've added the following lines in order to check what's in the dictionary at each step:
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
It doesn't seem to work correctly either however. First of all it prints "This dictionary contains items." whether the printed dictionary looks empty or not. Second of all the following part of my code (clear() is used for clearing the terminal display):
def create_dictionary():
clear()
answer = input(
"Would you like to add another message? (yes/no)").lower()
if answer == "yes":
option_1()
elif answer == "no":
clear()
print("You will now be returned to the main menu.")
print(dict(messages_and_times))
does print a dictionary containing items if I chose to add them. But if I add the line
print(dict(messages_and_times))
to the main_menu() itself, the above mentioned create_dictionary() function prints an empty dictionary instead. Just this one print() statement in the main_menu() affects whether create_dictionary() shows a dictionary with items in it or not.
Could someone please help me understand how to design a code in which the dictionary retains the items created by one function, so that they can be accessed by other functions?
Thank you in advance for your time and assistance,
import os
clear = lambda: os.system('cls')
def main_menu():
list_of_messages = []
list_of_times = []
messages_and_times = zip(list_of_messages, list_of_times)
def option_1():
clear()
list_of_messages.append(
input("Please type in a message you would like to add to the list:"))
clear()
list_of_times.append(
input("Please type in the time of delay for this message:"))
def create_dictionary():
clear()
answer = input(
"Would you like to add another message? (yes/no)").lower()
if answer == "yes":
option_1()
elif answer == "no":
clear()
print("You will now be returned to the main menu.")
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
time.sleep(1.5)
main_menu()
else:
clear()
print("Please answer yes or no.")
time.sleep(1.5)
create_dictionary()
create_dictionary()
def option_2():
clear()
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
time.sleep(5)
main_menu()
clear()
selection = 0
while selection == 0:
print(("-" * 15) + "MAIN MENU" + ("-" * 15) + "\n")
print("1: Input a message and a corresponding time of delay before its display.")
print("2: Print your customized list of messages.")
print("3: Generate a list of random messages with random delays.\n")
selection = int(input(
"Please select one of the options, by typing in the corresponding number:"))
if selection == 1:
option_1()
elif selection == 2:
option_2()
elif selection == 3:
clear()
print("You've selected the third option.")
else:
clear()
print("Please select from options 1 - 3.\n")
time.sleep(1.5)
main_menu()
this is my password checker code (whether it is valid or not)
I need to run the password checker for 5 times, until it's valid.
If it's valid, I have to break out of the loop.
The password should be more than 7 characters.
The password needs to include both numbers (at least two) and characters.
(If not, return False)
There should be no space.
If there is anything else than numbers and characters, I need to return False
I need to run my password_checker function in the for loop,
but I'm not so sure what to say after 'if'.
I have tried -
if a=False:
print(password_checker(i))
print(Invalid password)
but it didn't work.
Also, I don't understand how should I call my password_checker() in the for loop.
Finally, I need to put a break in my for loop
if the password in the input is valid.
But I'm not sure where is the appropriate part to place it
def password_checker(password):
a=True
num_Count = 0
if password.isalpha() == True:
print ("error! needs numbers")
a = False
if password.isnum() == True:
print ("error! needs characters")
a = False
if password.isspace() == True:
print ("error! no space allowed")
a = False
if len(password)<=8:
print ("error! needs more than 8 characters")
a = False
for i in range(0, 10):
num_Count += password.count(i)
if num_Count(password.count()) < 2:
print("error! needs at least 2 numbers")
a = False
password = str(input("Enter password: "))
for i in range(0,5):
if ____________________:
print(password_checker(i))
print("Invalid password")
else:
print(password_checker(i))
print("Valid password")
break
How should I correct my code in order to make my function work?
for i in range(0,5):
password = str(input("Enter password: "))
password_checker_result = password_checker(password)
if not password_checker_result:
print("Invalid password")
else:
print("Valid password")
break
This code will work for you, now let me explain:
The flow is as following:
This is done 5 times (is inside the for loop):
1) Request password from user.
2) Check if password is valid.
3) Print according to valid/not valid result.
The fact that you are using a for loop does not require you to actually use the iteration index (meaning 'i' in our case)
I'm trying to create a menu for my application, the menu has 4 options and each of these options should return with the correct information when the user has entered the chosen value. i keep getting an error with the Elif statements.
I am a newbie so please understand where am coming from.
much appreciation.
when i indent the while ans: i will receive an error says invalid syntax after indenting the elif ans==2.
elif ans==2 <--- this error keeps saying indention block error or syntex invalid when i indent it.
def print_menu(self,car):
print ("1.Search by platenumber")
print ("2.Search by price ")
print ("3.Delete 3")
print ("4.Exit 4")
loop=True
while loop:
print_menu()
ans==input("Please choose from the list")
if ans==1:
print("These are the cars within this platenumber")
return platenumber_
while ans:
if ans==2:
elif ans==2:
print("These are the prices of the cars")
return price_
elif ans==3:
print("Delete the cars ")
return delete_
elif ans==4:
return Exit_
loop=False
else:
raw_input("please choose a correct option")
You have a while loop without a body. Generally speaking, if there is an indentation error message and the error is not on the line mentioned, it's something closely above it.
loop=True
while loop:
print_menu()
ans = int(input("Please choose from the list"))
if ans==1:
print("These are the cars within this platenumber")
# return some valid information about plate numbers
elif ans==2:
print("These are the prices of the cars")
# return some valid information about pricing
elif ans==3:
print("Delete the cars ")
# Perform car deletion action and return
elif ans==4:
# I am assuming this is the exit option? in which case
# return without doing anything
else:
# In this case they have not chosen a valid option. Send
# A message to the user, and do nothing. The while loop will run again.
print("please choose a correct option")
Also, your code is a bit confusing to me. It looks like you're going to return car_ no matter what, which means your loop will only execute once. Also, = is assignment and == is equality. Be careful.
I am extremely new to Python, and to programming in general, so I decided to write some basic code to help me learn the ins and outs of it. I decided to try making a database editor, and have developed the following code:
name = []
rank = []
age = []
cmd = input("Please enter a command: ")
def recall(item): #Prints all of the information for an individual when given his/her name
if item in name:
index = name.index(item) #Finds the position of the given name
print(name[index] + ", " + rank[index] + ", " + age[index]) #prints the element of every list with the position of the name used as input
else:
print("Invalid input. Please enter a valid input.")
def operation(cmd):
while cmd != "end":
if cmd == "recall":
print(name)
item = input("Please enter an input: ")
recall(item)
elif cmd == "add":
new_name = input("Please enter a new name: ")
name.append(new_name)
new_rank = input("Please enter a new rank: ")
rank.append(new_rank)
new_age = input("Please input new age: ")
age.append(new_age)
recall(new_name)
else:
print("Please input a valid command.")
else:
input("Press enter to quit.")
operation(cmd)
I want to be able to call operation(cmd), and from it be able to call as many functions/perform as many actions as I want. Unfortunately, it just infinitely prints one of the outcomes instead of letting me put in multiple commands.
How can I change this function so that I can call operation(cmd) once, and call the other functions repeatedly? Or is there a better way to go about doing this? Please keep in mind I am a beginner and just trying to learn, not a developer.
Take a look at your code:
while cmd != "end":
if cmd == "recall":
If you call operation with anything than "end", "recall" or "add", the condition within while is True, the next if is also True, but the subsequent ifs are false. Therefore, the function executes the following block
else:
print("Please input a valid command.")
and the while loop continues to its next lap. Since cmd hasn't changed, the same process continues over and over again.
You have not put anything in your code to show where operator_1, operator_2, and operator_3 come from, though you have hinted that operator_3 comes from the commandline.
You need to have some code to get the next value for "operator_3". This might be from a list of parameters to function_3, in which case you would get:
def function_3(operator_3):
for loopvariable in operator_3:
if loopvariable == some_value_1:
#(and so forth, then:)
function_3(["this","that","something","something else"])
Or, you might get it from input (by default, the keyboard):
def function_3():
read_from_keyboard=raw_input("First command:")
while (read_from_keyboard != "end"):
if read_from_keyboard == some_value_1:
#(and so forth, then at the end of your while loop, read the next line)
read_from_keyboard = raw_input("Next command:")
The problem is you only check operator_3 once in function_3, the second time you ask the user for an operator, you don't store its value, which is why its only running with one condition.
def function_3(operator_3):
while operator_3 != "end":
if operator_3 == some_value_1
function_1(operator_1)
elif operator_3 == some_value_2
function_2
else:
print("Enter valid operator.") # Here, the value of the input is lost
The logic you are trying to implement is the following:
Ask the user for some input.
Call function_3 with this input.
If the input is not end, run either function_1 or function_2.
Start again from step 1
However, you are missing #4 above, where you are trying to restart the loop again.
To fix this, make sure you store the value entered by the user when you prompt them for an operator. To do that, use the input function if you are using Python3, or raw_input if you are using Python2. These functions prompt the user for some input and then return that input to your program:
def function_3(operator_3):
while operator_3 != 'end':
if operator_3 == some_value_1:
function_1(operator_3)
elif operator_3 == some_value_2:
function_2(operator_3)
else:
operator_3 = input('Enter valid operator: ')
operator_3 = input('Enter operator or "end" to quit: ')
looks like you are trying to get input from the user, but you never implemented it in function_3...
def function_3(from_user):
while (from_user != "end"):
from_user = raw_input("enter a command: ")
if from_user == some_value_1:
# etc...