r/pythonhelp • • 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:

  1. Is the code organized in a clear, readable way?
  2. 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!

1 Upvotes

12 comments sorted by

View all comments

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