How to avoid using to much if else? - python

This is the concept of what I'm trying to acheive with the code. I want the user to be able to leave the login section whenever they press '0', the codes below works, but is there anyway that I can shorten these codes, cause I felt like there's too much if else being use.
def signup():
print("Press '0' to return mainpage")
firstname = input("Please enter your first name : ")
if firstname == "0":
print("Mainpage returned")
mainpage()
else:
lastname = input("Please enter your last name : ")
if lastname == "0":
print("Mainpage returned")
mainpage()
else:
username = firstname+lastname
print("Welcome", username)
def mainpage():
option = input("Press '1' to signup: ")
if option == '1':
print("Sign up page accessed")
signup()
mainpage()

You could use early returns to remove some of the nesting.
def signup():
print("Press '0' to return mainpage")
firstname = input("Please enter your first name : ")
if firstname == "0":
print("Mainpage returned")
mainpage()
return
lastname = input("Please enter your last name : ")
if lastname == "0":
print("Mainpage returned")
mainpage()
return
username = firstname+lastname
print("Welcome", username)

First of all, write code that matches your true logic. This potentially infinite recursion is inappropriate. This is a nested process, not something innately recursive.
You say that you want to leave the signup area when the user inputs 0. If so, then leave -- don't go down yet another "rabbit hole": delete those calls to mainpage and return normally. After all, mainpage is where you came from.
As for using fewer if statements, you can't reduce this much without very much generalizing the interactions in your program. You want to check for 0 in two places and for 1 in another. This requires either 3 if checks or a process general enough to make all of the transitions given a list of legal "moves". If you want that, please look up how to implement a finites state machine.
However, there is one straightforward economy: your user interface is unduly wordy. Just ask for the entire name at once:
def signup():
print("Press '0' to return mainpage")
username = input("Please enter your name : ")
if name == "0":
print("Mainpage returned")
else:
username.replace(' ', '') # remove space(s)
print("Welcome", username)
Either way, this routine naturally returns to mainpage.

Related

How to delete an item from a class in python based on user input?

I am trying to allow a member to leave the Team if they so wish. By doing this, the system will delete them and their user ID will become available to the next person who wishes to join the team. I am receiving an error with my code. Can someone please advise what I am doing wrong and how this can be achieved?
I would like my add members and remove members to update all the time, based on user input and the needs of the members. I hope this makes sense!
For example: If 'Carl' decided to leave, he would be removed and the next member to join would be assigned the membership ID '2'
Below is my code:
all_users = []
class Team(object):
members = []
user_id = 0
def __init__(self, first, last, address):
self.user_id = Team.user_id
self.first = first
self.last = last
self.address = address
self.email = first + '.' + last + '#python.com'
Team.user_id += 1
Team.members.append(self)
def __str__(self):
print()
return 'Membership ID: {}\nFirst Name: {}\nSurname: {}\nLocation: {}\nEmail: {}\n'.format(self.user_id,
self.first, self.last,
self.address,
self.email)
print()
#staticmethod
def all_members():
for user in all_users:
print(user)
#staticmethod
def add_member():
print()
print("Welcome to the team!")
print()
first_name = input("What's your first name?\n")
second_name = input("What's your surname?\n")
address = input("Where do you live?\n")
all_users.append(Team(first_name, second_name, address))
#staticmethod
def remove_member():
print()
print("We're sorry to see you go , please fill out the following information to continue")
print()
first_name = input("What's your first name?\n")
second_name = input("What's your surname?\n")
address = input("Where do you live?\n")
unique_id = input("Finally, what is your User ID?\n")
if unique_id in all_users:
del unique_id
all_users(User(first_name, second_name, address))
def main():
user_1 = Team('Chris', 'Parker', 'London')
user_2 = Team('Carl', 'Lane', 'Chelsea')
all_users.extend([user_1, user_2])
continue_program = True
while continue_program:
print("1. View all members")
print("2. Want to join the team?")
print("3. Need to leave the team?")
print("3. Quit")
try:
choice = int(input("Please pick one of the above options "))
if choice == 1:
Team.all_members()
elif choice == 2:
Team.add_member()
elif choice == 3:
Team.remove_member()
elif choice == 4:
continue_program = False
print()
print("Come back soon! ")
print()
else:
print("Invalid choice, please enter a number between 1-3")
main()
except ValueError:
print()
print("Please try again, enter a number between 1 - 3")
print()
if __name__ == "__main__":
main()
The remove_member method is wrong for several reasons. The line del unique_id will not remove the value from all_users, which is just a list of Team Members. And you shouldn't have to ask the user for all of this information - just the ID (or the name) would be enough.
What I suggest is:
#staticmethod
def remove_member():
print()
print("We're sorry to see you go , please fill out the following information to continue")
print()
unique_id = input("what is your User ID?\n")
unique_id = int(unique_id)
for i, user in enumerate(all_users):
if user.user_id == unique_id:
all_users.remove(i)
break
If it is important that the user ids are reused, you can keep a list of user ids that are available again. When creating a new member, you can first check that list, and use an old id if there is one.
You can also choose not to reuse the user ids of removed users. An id doesn't really have a meaning and not reusing it makes it simpeler for you.
Finally, you might want to restructure your code:
Team(first_name, second_name, address)
This doesn't make sense: a team with a first name, last name and adress! Better would be to have two classes:
team = Team()
user = User(first_name, second_name, address)
team.add_member(user)
team.remove_member(user)
Some other tips:
# This won't work, because all_users contains Team instances, not numbers. So the user will never be found.
if unique_id in all_users:
# This won't do anything: `del` only removes the access to the variable (might free up memory in heavy applications). It doesn't remove the user from all_users
del unique_id

Python pickles not storing data

I am trying to create a registrar system through Python with pickles. I have gotten the system to record user input, but it does not save it for future implementations of the program.
Here is the code that will start the program:
import datetime
import pandas as pd
import pickle as pck
import pathlib
from pathlib import *
from registrar import *
prompt = "Please select an option: \n 1 Create a new course \n 2 Schedule a new course offering \n 3 List this school's course catalogue \n 4 List this school's course schedule \n 5 Hire an instructor \n 6 Assign an instructor to a course \n 7 Enroll a student \n 8 Register a student for a course \n 9 List this school's enrolled students \n 10 List the students that are registered for a course \n 11 Submit a student's grade \n 12 Get student records \n 13 Exit"
farewell = "Thank you for using the Universal University Registrar System. Goodbye!"
print ("Welcome to the Universal University Registration System.")
print ("\n")
try: #As long as CTRL-C has not been pressed, or 13 not been input by user.
input_invalid = True
while input_invalid:
inst = input("Please enter the name of your institution. ").strip()
domain = input("Please enter the domain. ").strip().lower()
if inst == "" or domain == "":
print("Your entry is invalid. Try again.")
else:
input_invalid = False
schoolie = Institution(inst, domain)
if Path(inst + '.pkl').exists() == False:
with open(inst + '.pkl', 'r+b') as iptschool:
schoolie = pck.load(iptschool)
while True:
print (prompt)
user_input = input("Please enter your choice: ")
try:
user_input = int(user_input)
if user_input < 1 or user_input > 14: #UserInput 14: on prompt.
raise ValueError("Please enter a number between 1 and 13, as indicated in the menu.")
except ValueError:
print("Not a valid number. Please try again.")
if user_input == 1: #Create a new course
input_invalid2 = True #Ensure that the user actually provides the input.
while input_invalid2:
input_name = input("Please enter a course name: ").strip()
input_department = input("Please enter the course's department: ").strip()
input_number = input("Please enter the course's number (just the number, not the departmental prefix): ").strip()
try:
input_number = int(input_number)
except ValueError:
print ("Please print an integer. Try again.")
input_credits = input("Please enter the number of credits awarded for passing this course. Please use an integer: ").strip()
try:
input_credits = int(input_credits)
except ValueError:
print ("Please print an integer. Try again.")
if input_name != "" and input_department != "" and input_number and input_credits:
input_invalid2 = False #Valid input
else:
print("One or more of your entries is invalid. Try again.")
added_course = Course(input_name, input_department, input_number, input_credits)
for course in schoolie.course_catalog:
if course.department == input_department and course.number == input_number and course.name == input_name:
print("That course is already in the system. Try again.")
input_invalid2 == True
if input_invalid2 == False:
schoolie.add_course(added_course)
print ("You have added course %s %s: %s, worth %d credits."%(input_department,input_number,input_name, input_credits))
And here is the second option, which SHOULD reveal that it is stored, but it does not.
elif user_input == 2: #Schedule a course offering
input_invalid2 = True #Ensure that the user actually provides the input.
while input_invalid2:
input_department = input("Please input the course's department: ").strip()
input_number = input("Please input the course's number: ").strip()
course = None
courseFound = False
for c in schoolie.course_catalog:
if c.department == input_department and c.number == input_number: #Course found in records
courseFound = True
course = c
input_section_number = input("Please enter a section number for this course offering: ").strip()
input_instructor = input("If you would like, please enter an instructor for this course offering: ").strip()
input_year = input("Please enter a year for this course offering: ").strip()
input_quarter = input("Please enter the quarter in which this course offering will be held - either SPRING, SUMMER, FALL, or WINTER: ").strip().upper()
if input_course != "" and input_course in schoolie.course_catalog and input_section_number.isdigit() and input_year.isdigit() and input_quarter in ['SPRING', 'SUMMER', 'FALL', 'WINTER'] and input_credits.isdigit():
if input_instructor != "": #Instructor to be added later, if user chooses option 6.
added_course_offering = CourseOffering(c, input_section_number, None, input_year, input_quarter)
else:
added_course_offering = CourseOffering(c, input_section_number, input_instructor, input_year, input_quarter)
schoolie.add_course_offering(added_course_offering)
input_invalid2 = False #Valid input
print ("You have added course %s, Section %d: %s, worth %d credits."%(input_course,input_section_number,input_name, input_credits))
else:
print("One or more of your entries is invalid. Try again.")
if courseFound == False: #If course has not been found at the end of the loop:
print("The course is not in our system. Please create it before you add an offering.")
break
By the way, I think I have the system closing properly. Correct me if I'm wrong:
elif user_input == 13: #Exit
with open(inst + '.pkl', 'wb') as output:
pck.dump(schoolie, output, pck.HIGHEST_PROTOCOL)
del schoolie
print (farewell)
sys.exit()
except KeyboardInterrupt: #user pushes Ctrl-C to end the program
print(farewell)
I believe that there is something wrong with the way that I am setting up the pickles files. I'm creating them, but I seem not to be putting data into them.
I apologize for the long-winded nature of this question, but I hope that the details will help you understand the problems that I've been having. Thanks in advance for the help!
it seems you may have dump and load reversed: (from the docs)
Signature: pck.load(file, *, fix_imports=True, encoding='ASCII', errors='strict')
Docstring:
Read and return an object from the pickle data stored in a file.
Signature: pck.dump(obj, file, protocol=None, *, fix_imports=True)
Docstring:
Write a pickled representation of obj to the open file object file.
With all those lines of code, it does get a little confusing, but I don't see any code that is pickling and writing the objects to a file.
Before anything else, you should assign the file to a variable so you can reference it. To do this, you'll have code similar to this:MyFile = open("FileName.extension","wb"). MyFile can be any name you want, it will be what you use later to reference the file. FileName is the name of the file itself. This is the name it will have in File Explorer. .extension is the file's extension, specifying the type of file. You should use .dat for this. wb is the file access mode. "w" means write, and "b" means binary. (Pickled objects can only be stored in a binary file.)
To write the pickled objects, you'll need this code:pck.dump(object,MyFile). (Usually, you would use pickle.dump(object,MyFile), but you imported pickle as pck.)
After writing the data to the file, you'll want to retrieve it. To do this, the "wb" instance of MyFile needs to be closed like this:MyFile.close(). Then you'll need to re-open the file in read mode using the following code:MyFile = open("FileName.extension","rb") Then you would use this:object = pickle.load(MyFile) to read the data. In the preceding example, (the load function), your object must have the same name as when you pickled it using the dump function. (pck.dump(object,MyFile))
In the end, you'll end up with something similar to this:
if writing conditions are true:
MyFile = open("FileName.dat","wb")
pickle.dump(object,MyFile) # This will be repeated for each object.
MyFile.close()
if reading conditions are true:
MyFile = open("FileName.dat","rb")
object = pickle.load(MyFile) # This will be repeated for each object.
MyFile.close()
I'm sorry if this wasn't the answer you wanted. Because of all those lines of code, it is somewhat hard to understand. I need clarification to give a better answer.

Python: Being asked for input twice and outputting duplicate print statements

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.

Variable and Function help // Python

Alright so here's the code
def user_password():
input('Please Enter Password: ')
#profiles
def intercept():
user_password()
if user_password == "intercept":
print("this is working so far")
else:
print("Incorect Password")
def Jimmy():
user_password()
if user_password == "Jimmy":
print("this is working so far")
else:
print("Incorect Password")
def Tommy():
user_password()
if user_password == "Tommy":
print("this is working so far")
else:
print("Incorect Password")
#login
user_functions = dict(
intercept=intercept,
Jimmy=Jimmy,
Tommy=Tommy,
# ...
)
user_input = input("Input function name: ")
if user_input in user_functions:
user_functions[user_input]()
else:
print("Error: Unknown function.")
PROBLEMS:
My code always starts with asking for the password even though I don't want it
to.
When I change the first variable to a function it fixes this
Why does it execute when I'm just setting the variable. I'm pretty sure I shouldn't have to use a function instead of a variable
No matter what it always ends up as Incorrect Password even if I give the correct password
I think you are trying to write something like that:
def get_user_password():
return input('Please Enter Password: ')
def Jimmy():
user_password = get_user_password()
if user_password == "Jimmy":
print("this is working so far")

Continuous results from a single function call

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...

Categories

Resources