#loop to get input that is not blank, strips input of whitespacedef ckin(a): while a=='': a=input().strip() return a#creates list with includes user adminuser_names = ['admin'] #Ask for 5 names to store as usernamesprint('Please enter 5 user names: ') #if username is valid, add to listfor i in range(0,5) lib_name=input().strip() lib_name=ckin(lib_name) user_names.append(lib_name)#asks for login name, must be validprint('Enter login name:') log_name=input().strip()log_name=ckin(log_name)#Create a test list that is lower case to compare login#against without altering the cases used by user to creat username listtest=[name.lower() for name in user_names] #if login name not in list continue to promptwhile log_name.lower() not in test: print('Enter login name:') log_name=input().strip() log_name=ckin(log_name)#find login name in test, then return either response for admin, or login name using #case formatting that original used for original entryfor i in range(len(test)): if log_name.lower() == 'admin': print('Hello admin, would you like to see a status report?') break elif log_name.lower() == test[i]: print('Hello '+user_names[i]+', thank you for logging in again') breakLooking for general review self-teaching, Day 4
I haven't learned much but I keep attempting to do what I'm learning with user inputs instead of set entries
My goal here was to be able to create a list that keeps the original entry cases to be used for responding. I created a second list in lower cases to compare to and then responded using the cases the entries were stored as.
Any comments are greatly appreciated!
2 Answers2
You can reduce your code duplication a bit. First, the way you are currently using theckin function is like this:
name = input("Enter a name").strip()name = ckin(name)Wouldn't it be nicer to be able to do:
name = ask_user("Enter a name: ")For this, just modify your function like this:
def ask_user(message=""): user_input = "" while not user_input: user_input = input(message).strip() return user_inputNote that I renamed it (to make it clearer what it does), used the fact that empty strings are falsy and added whitespace around the= operator, as recommended by Python's official style-guide,PEP8.
Going further, you should get into the habit of defining clearly named functions for separate things.
One such concern is getting a pre-populated username list. Currently this list is populated with user input, but this might change in the future. So it would be nice to bundle that part all together in one function:
def get_users(): # creates a users set, which always includes admin users = {'admin'} #Ask for 5 names to store as usernames print('Please enter 5 unique user names: ') while len(users) < 6: users.add(ask_user("Enter a valid user name: ").lower()) return usersNote that I made the datastructure aset here, which gives you \$\mathcal{O}(1)\$ time complexity forin tests. I also made sure that there are actually 5 + 1 users (in other words, user names need to be unique). I also put thestr.lower transformation here so we don't need to do it later and only store the canonical user name.
Next is a login function, that asks for a username until a valid one is entered:
def login(users): user_name = None while user_name not in users: user_name = ask_user("Enter login name: ").lower() return user_nameAnd then, the greeting. Instead of iterating over all users until you reached the user that is currently logging in, use the fact that we already know that the user is inusers (since we explicitly checked for that inlogin). So this becomes a simpleif..else check:
def print_greeting(user_name): if user_name == 'admin': print('Hello admin, would you like to see a status report?') else: print(f'Hello {user_name}, thank you for logging in again')Here I used anf-string, as introduced in Python 3.6, to make the string formatting a bit easier.
And finally, tying it all together in amain function:
def main(): users = get_users() user_name = login(users) print_greeting(user_name)if __name__ == "__main__": main()Note that I call thismain function only under aif __name__ == "__main__": guard. This ensures that themain function does not run if you import from this script in another script.
- \$\begingroup\$Thank you this is exciting! This is my first time seeing the
while notand I sort of grasp the idea ofmainhere, definitely going to review this and integrate these concepts.\$\endgroup\$vash_the_stampede– vash_the_stampede2018-08-22 14:52:13 +00:00CommentedAug 22, 2018 at 14:52 - \$\begingroup\$could you breakdown the use of
=""in this portion of the code, I understand what is being done, checked, and returned just not what is happening with the=""in theask_userfunction\$\endgroup\$vash_the_stampede– vash_the_stampede2018-08-22 21:42:07 +00:00CommentedAug 22, 2018 at 21:42 - \$\begingroup\$@anthonyvalva: It just sets
user_inputto a value where thewhileloop's condition is met, so the user is asked for the first time. I also could have putuser_input = input(message).strip()there as well, but that would then be repeated (so if you ever e.g. want to change that the user input is not only stripped, but also lowercased, you would need to remember to change it in both places, making it a bit harder to maintain).\$\endgroup\$Graipher– Graipher2018-08-22 21:44:21 +00:00CommentedAug 22, 2018 at 21:44 - \$\begingroup\$I'm sorry I was actually reffering to the
message=''portion what does this do?\$\endgroup\$vash_the_stampede– vash_the_stampede2018-08-22 21:53:50 +00:00CommentedAug 22, 2018 at 21:53 - 1\$\begingroup\$@anthonyvalva The
message=''default keyword argument is used as input prompt in the call of theinput()built-in instead of using aprint()statement beforehand.\$\endgroup\$user51621– user516212018-08-23 08:38:14 +00:00CommentedAug 23, 2018 at 8:38
General
Read and familiarize yourself with
- PEP8
- Functions
- The
if __name__ == '__main__':check
Make sure, the function and variable names convey their purpose.
Specific
The user input check could be done a little more pythonic:
def get_user_name(): user_name = None while not user_name: user_name = input().strip() return user_nameAnd thus, the firstmanual reading can be omitted:
for i in range(5): # lib_name = input().strip() # Useless lib_name = get_user_name() user_names.append(lib_name)Same here:
print('Enter login name:') log_name = get_user_name()For quicker lookup of data, use a hasing container:
known_user_names = frozenset(name.lower() for name in user_names)#if login name not in list continue to promptwhile log_name.lower() not in known_user_names: print('Unknown user. Enter valid login name:') # Add an error hint to the user. log_name = get_user_name()The loop here is useless:
for i in range(len(test)): if log_name.lower() == 'admin': print('Hello admin, would you like to see a status report?') break elif log_name.lower() == test[i]: print('Hello '+user_names[i]+', thank you for logging in again') breakAbove you already made sure, that the user name is known.
if log_name.lower() == 'admin': print('Hello admin, would you like to see a status report?')else: print('Hello', log_name + ', thank you for logging in again')- \$\begingroup\$going to review all this and applyt it, greatly appreciate your time!\$\endgroup\$vash_the_stampede– vash_the_stampede2018-08-22 14:31:52 +00:00CommentedAug 22, 2018 at 14:31
- \$\begingroup\$Maybe wait for some other reviews first.\$\endgroup\$user51621– user516212018-08-22 14:32:29 +00:00CommentedAug 22, 2018 at 14:32
You mustlog in to answer this question.
Explore related questions
See similar questions with these tags.
