Skip to content

Password Generator

A console-based password generator built entirely with the Python Standard Library, generate a random password on demand, adjust the active length (4-128 characters), generate a batch of up to 50 passwords at once, review current settings, or reset back to the default, all through a clean, menu-driven terminal interface with full input validation. Built as Project 3 for the DecodeLabs Python Programming Internship, immediately after the to-do list manager and expense tracker, with the same emphasis on writing correct, PEP8-conventional Python rather than just something that technically works.

Type
CLI Tool
Role
Software Engineering Intern
Built
2026
Updated
2026
Source
Tech Stack
Python 3
01

Why I Built This

This was built as Project 3 during the DecodeLabs Python Programming Internship, following the official assignment brief for a Core Python CLI password generator, right after the to-do list manager and expense tracker.

Keeping it to the Python Standard Library only, with zero external packages, GUI frameworks, or file storage, was a deliberate constraint carried over from the earlier two internship projects; every piece (validation, the character pool, the menu loop) had to be built from first principles.

02

Security Considerations

Password strength here comes down to the entropy of the randomness source and the size of the character pool it draws from. Python's random module is fine for games and simulations but isn't cryptographically secure, so this generator uses secrets instead, the Standard Library module specifically built for security-sensitive randomness like this.

Nothing is ever sent anywhere: this is a local console script with no network request, no server log, and no third party that could ever end up with a copy of a generated password.

03

Random Generation Logic

Generation works by drawing repeatedly from a fixed pool built from string.ascii_letters and string.digits using secrets.choice(), for the length currently set (4-128 characters, default 12). The pool itself is fixed rather than user-configurable in the current version, uppercase, lowercase, and digits are always available; character-set toggles and symbol support are a documented future addition, not something already built.

04

Menu & Input Validation

The interface is a persistent terminal menu with six options (generate, change length, generate multiple, view settings, reset settings, exit) that keeps running until the user explicitly chooses to exit. Every single prompt, menu selection and length input alike, runs through the same validation path: empty, non-numeric, zero, and negative values are rejected and re-prompted rather than allowed to crash the session.

05

Future Improvements

These are documented directions for a future version, not features in the current implementation: optional inclusion of special characters with independent uppercase/lowercase toggles, a password-strength indicator, copy-to-clipboard support, and exporting generated passwords to an encrypted local file.

06

Key Decisions

Passwords are drawn from secrets.choice() over a combined pool of uppercase letters, lowercase letters, and digits (string.ascii_letters + string.digits), specifically because the Standard Library's secrets module is built for security-sensitive randomness, unlike the general-purpose random module.

Nothing is written to disk; settings and generated passwords exist only for the duration of a single run, which keeps the scope honest for a project whose whole point is demonstrating correct randomness and input handling, not building a password manager.

Batch generation is capped at 50 passwords per run and length is bounded to 4-128 characters, both enforced through the same input-validation path as every other menu option.

07

What I Learned

Designing a modular, function-based CLI application with a clear separation between input validation, core generation logic, and menu handling made the program far easier to reason about than one long script would have been.

Writing input validation that never crashes the program, for empty, non-numeric, zero, and negative input across every prompt, took more careful thought than the generation logic itself.

Using secrets.choice() instead of random.choice() for every character draw was the single most important correctness decision in the project; random is fine for games and simulations but isn't built for security-sensitive randomness.

Structuring a continuously running menu loop with clean exit handling, including catching KeyboardInterrupt and EOFError so the program never ends in an ugly traceback, was a small detail that mattered more than expected.