Overview
Offline-Bank is a lightweight, console-based wallet manager built in ~2 hours during a major power outage, no internet, no docs, no AI tools. It uses db.csv as a tiny database and pandas to manage balances, compute portfolio stats, and apply interest formulas through a simple menu loop. In this sprint version, changes are kept in memory (no write-back to db.csv).
What it demonstrates
- Building something functional under constraints (offline + time-boxed)
- Clean separation of operations (deposit/withdraw/stats/interest) behind menu actions
- Using pandas as a quick “data layer” for scripting tasks
Code (representative excerpt)
Representative excerpt of the core loop (full code in the repo).
python
import pandas as pd
# Load "database"
df = pd.read_csv("db.csv")
MENU = """
Choose an option:
a) Add to wallet
b) Withdraw from wallet
c) Add new wallet
d) Total balance
e) Mean balance
f) Wipe a wallet
g) Simple interest
h) Compound interest
i) Highest balance
j) Lowest balance
k) Exit
"""
def select_wallet(prompt: str) -> int:
print(prompt)
print(df)
return int(input("> "))
def add_wallet(name: str) -> None:
pos = df["name"].count()
df.loc[pos + 1, "name"] = name
df.loc[pos + 1, "balance"] = 0
def add_to_wallet() -> None:
idx = select_wallet("Select a wallet (index):")
amount = int(input("Amount to deposit: "))
df.loc[idx, "balance"] += amount
def withdraw() -> None:
idx = select_wallet("Select a wallet (index):")
amount = int(input("Amount to withdraw: "))
df.loc[idx, "balance"] -= amount
def wipe_wallet() -> None:
idx = select_wallet("Select a wallet (index):")
df.loc[idx, "balance"] = 0
def simple_interest() -> None:
idx = select_wallet("Select a wallet (index):")
r = float(input("Interest rate (e.g. 0.05): "))
df.loc[idx, "balance"] = (1 + r) * df.loc[idx, "balance"]
def compound_interest() -> None:
idx = select_wallet("Select a wallet (index):")
r = float(input("Interest rate (e.g. 0.05): "))
years = int(input("Years: "))
df.loc[idx, "balance"] = df.loc[idx, "balance"] * (1 + r) ** years
def total_balance() -> None:
print(df["balance"].sum())
def mean_balance() -> None:
print(df["balance"].mean())
def highest_balance() -> None:
print(df["balance"].max())
def lowest_balance() -> None:
print(df["balance"].min())
print(MENU)
option = input("Select your choice: ").strip().lower()
while option:
if option == "show":
print(MENU)
elif option == "a":
add_to_wallet()
elif option == "b":
withdraw()
elif option == "c":
name = input("Enter new wallet name: ")
add_wallet(name)
elif option == "d":
total_balance()
elif option == "e":
mean_balance()
elif option == "f":
wipe_wallet()
elif option == "g":
simple_interest()
elif option == "h":
compound_interest()
elif option == "i":
highest_balance()
elif option == "j":
lowest_balance()
elif option == "k":
break
else:
print("Invalid option. Type 'show' to see the menu.")
option = input("Select your choice: ").strip().lower()Limitations (intentional for the exercise)
- No write-back to
db.csv(loaded viapd.read_csv, but noto_csvpersistence). - Index-based wallet selection (
df.loc[idx]) is brittle if CSV rows are reordered or indices don’t match the UI. - Minimal validation (inputs assumed to be valid numbers/indices; negative balances allowed).
Next steps
If I were to evolve this beyond the “offline sprint” version, I’d add:
- Save/commit changes back to CSV (or SQLite).
- Safer wallet selection (by name, not index) + validation.
- Basic negative-balance constraints and guardrails.