First Pass

Type the damn thing step by step

I'm continuing with the idea of typing or transcribing the script β€”I do feel this is good practice to get some muscle memory, and it also helps me a lot in understanding what the code does, gives me familiarity with structures and vocabularyβ€”, but do it step by step in a more "realistic" workflow... it's all still simulated, obviously, but baby steps, getting closer to the real thing.

BUT... for this project, Claude.AI decided to spit out 388 lines, so just to make that part smoother, I asked it to give me the step-by-step of what the "real" workflow would look like; this is what it gave me:

πŸ—οΈ Build Order - Password Manager

Phase 1: Basic Structure (Get something running)

Goal: Create a working loop that does nothing
  1. Start with the skeleton:

    • main() function with welcome message
    • Simple while True loop with input()
    • quit command to exit
    • if __name__ == "__main__": block
  2. Test it: Should be able to type quit and exit


Phase 2: Help & Commands (Navigation)

Goal: Show available commands
  1. Add:

    • show_help() function
    • help command in main loop
    • Handle unknown commands with else clause
  2. Test it: Type help, see commands, type garbage, see error message


Phase 3: In-Memory Storage (No files yet)

Goal: Store passwords temporarily (they disappear when you quit)
  1. Add:

    • vault = {} dictionary at top of main()
    • add_account() function (simplified - no encryption, no file save)
      • Just get account name, username, password
      • Store in vault[account_name] = {...}
      • Print success message
    • Wire up add command in main loop
  2. Test it: Add a few accounts, they exist during session

  3. Add:

    • list_accounts() function
    • Wire up list command
  4. Test it: Add accounts, list them, see them appear

  5. Add:

    • view_account() function
    • Wire up view command
  6. Test it: Add account, view it, see details


Phase 4: File Persistence (Save/Load - NO encryption yet)

Goal: Data survives program restarts
  1. Add:

    • VAULT_FILE = "password_vault.json" constant at top
    • save_vault() function (simple version - no encryption)
      • Use json.dump()
    • Update add_account() to call save_vault() at the end
  2. Test it: Add account, quit, restart program - file exists but can't load yet

  3. Add:

    • load_vault() function (simple version - no encryption)
      • Check if file exists with os.path.exists()
      • Use json.load()
      • Return empty dict if file doesn't exist
    • Call load_vault() in main() before the loop
    • Pass vault to functions that need it
  4. Test it: Add accounts, quit, restart, list - accounts persist! πŸŽ‰


Phase 5: Encryption (Make it secure-ish)

Goal: Encrypt stored passwords
  1. Add:

    • Master password prompt in main() (use getpass.getpass())
    • simple_encrypt() function
    • simple_decrypt() function
  2. Update:

    • save_vault() to encrypt username/password before saving
    • load_vault() to decrypt after loading
    • Add try/except for wrong master password
  3. Test it:

    • Add account with master password "test123"
    • Quit, restart with "test123" - works!
    • Quit, restart with "wrong" - fails!
    • Look at password_vault.json - gibberish! βœ“

Phase 6: Polish & Features

Goal: Nice-to-haves
  1. Add:

    • delete_account() function
    • search_accounts() function
    • Timestamps (datetime import, add to add_account())
    • Better input validation (empty checks, confirmation prompts)
    • Error handling (try/except blocks)
  2. Test each feature individually


Phase 7: UX Polish

Goal: Make it feel professional
  1. Add:
    • Emoji decorations (πŸ”, βœ“, βœ—, ⚠️)
    • Formatting (borders, spacing)
    • Confirm password when adding
    • Optional fields (URL, notes)

πŸ“ Development Tips:

For each phase:

Use print statements liberally:

def load_vault():
    print(f"DEBUG: Looking for {VAULT_FILE}")  # Remove later
    if not os.path.exists(VAULT_FILE):
        print("DEBUG: File doesn't exist yet")
        return {}
    # ...

Start simple, add complexity:

This way you'll have a working program at EVERY step, not just at the end! Much more satisfying.