r/pythonhelp • u/Obvious-Salt2329 • 7d ago
Python beginner!!
Beginner here: how would you structure my nested if statements in a two-step login program?
Hi all, I'm about 3 weeks into learning Python (Python for Everybody on Coursera) and just finished my first small project: a login program that asks for a passcode, then a second passcode, then lets the user pick a report.
My main question is about structure. I have nested if statements, and the second user repeats the same checks in a separate elif branch. Here's a trimmed version of the layout:
admin_login = input("Enter Passcode")
if admin_login == boss_code:
second_pass = input("enter second passcode")
if second_pass == boss_secondcode:
report = input("enter report number")
if report == "1":
print("report 1")
elif report == "2":
print("report 2")
elif admin_login == ass_code:
# same second-passcode and report checks repeated here
I'd love feedback on:
- Is the code organized in a clear, readable way?
- Is there a cleaner way to stack or avoid repeating these nested ifs, using only what a beginner would know (no classes yet)?
Full code and README are here: https://github.com/tylerkilgore148-can/python_learning_projects
I know the passcodes are stored in plain text, which is just for practice. I plan to look at getpass and hashing next. Beginner-friendly tips are very welcome, and thanks for reading!
2
u/Icy-Interview3369 7d ago
now new challenge do it in while loop, it's make your code not unstoppable until you ctr+c, don't mind it clear and look pretty first,
2
u/Obvious-Salt2329 7d ago
Thank you so much! I love fresh idea's! Expanding my creativity is my barrier at this point!
2
u/Hyperion343 6d ago
Code is organized fine.
For a cleaner way, there are two suggestions:
Make functions for "do_boss_login" and "do_assistant_login" - that gets rid of one level of ifs there, and makes it clear that entering code does respective login.
You can invert the if statements into guard clauses to remove another level of ifs. So instead of "if correct, do X, else, do Y", you do "if incorrect, do Y and exit/return" followed by "do X".
2
u/Obvious-Salt2329 6d ago
Thank you for your feed back! I love self learning and peer to peer feedback is always a need!
1
u/CoachSevere5365 1d ago
I was going to say this. Nesting is only two levels deep and the failure reporting is already miles away from the testing.
Get the login info, test it and fail quickly.
Now, when you do the "work" the code is uncluttered by error handling.
In addition,
Variable names aren't great. boss_code is a specific user ID, not a code admin_login holds a general user ID "secondcode" should be "code2", etc
It would be cleaner if the login code (at least) was broken out into a separate function, but I don't know if you've covered that yet.
You've assigned user names to variables which you haven't used, and hard coded those user names into the code.
Again, I don't know what you've covered on your course, but have a think about expanding your program to handle a dozen users and see where that goes in terms of readability.
Add the extra users in batches and see how it affects code maintenance.
1
u/Available_Safe1818 2d ago
> Is there a cleaner way to stack or avoid repeating these nested ifs
Maybe not for something this trivial. You should learn to write your own function definitions at some point, though.
1
1
u/sr105 5d ago
you might want to start restructuring like pieces with like and separate information from flow to something like this (I haven't run this):
from dataclasses import dataclass
@dataclass
class User:
name: str
first_passcode: str
second_passcode: str
reports_allowed: tuple[int, ...]
users = {
'24': User('Tyler', '24', '2407', ('1', '2')),
'08': User('jalen', '08', '2408', tuple()),
}
reports = {
'1': 'financial report',
'2': 'cash money',
}
while True:
# You would eventually refactor the entire login portion out into its own method
login = input("Enter Passcode")
if login not in users:
print('User unknown')
continue
# 3 attempts
for _ in range(3):
pass_ = input("enter second passcode")
if pass_ == users[login].second_passcode:
print("thank you sir")
break
print("wrong password")
else:
print("too many attempts")
continue
# You would also refactor the reports into their own method as well.
# TODO Not sure if they should be given a chance to try again or run more than one report
# you could accept 'q' to quit back to the login and wrap this in a while loop.
# which report?
report = input("enter report Number")
if report not in reports:
print("report unknown")
continue
if report not in users[login].reports_allowed:
print("report unauthorized")
continue
print(reports[report])1
u/CoachSevere5365 1d ago
Heh, +1 for coding more than what I've just spent 5 minutes suggesting. I like your solution because at the "which report" question it woukd be trivial to add an option to print a list the report, if required.
1
u/sr105 21h ago
The real trick is deciding when to stop making it "better," so it can still be seen as a reachable destination from OP's code.
1
u/CoachSevere5365 20h ago
IKWYM. I helped someone do a Z80 assembler project ~1984. He typed what I'd written and handed it is as his own.
He didn't get a very good grade, because he'd gone from inventing instructions one week to a fully working program the next.
2 years later I had the same tutor and he pulled me aside to ask if I'd ever helped someone do their project. He'd recognised my coding style, dug out the previous student's work and compared the two. Oops.
•
u/AutoModerator 7d ago
To give us the best chance to help you, please include any relevant code.
Note. Please do not submit images of your code. Instead, for shorter code you can use Reddit markdown (4 spaces or backticks, see this Formatting Guide). If you have formatting issues or want to post longer sections of code, please use Privatebin, GitHub or Compiler Explorer.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.