Chapter 8.1: Building a Simple Banking System
Every great project starts with a plan, so before we write a single line of code, let’s set up our workspace.
Step 1: Project Setup
Let’s create a folder structure that keeps our logic tidy and modular.
banking_system/
│
├── src/
│ ├── account.glang # Handles individual account creation and checks
│ └── system.glang # Handles deposits, withdrawals, and transaction logic
│
└── main.glang # Entry point where users interact with the system
Here’s what each file will do:
account.glang: Knows how to add accounts and verify if one exists.system.glang: Controls how money moves in and out of those accounts.main.glang: Acts as our "bank clerk" and talks directly to the user.
Step 2: Managing Accounts (account.glang)
This file is the foundation of our system. It defines how accounts are stored, checked, and added to the registry.
glang
fetch std_hashmap;
fetch std_format;
# Checks if a name already exists in the account registry.
func account_exists(accounts, name) {
if contains(hashmap_keys(accounts), name) {
give true;
} otherwise {
give false;
}
}
# Adds a new account to the registry with an initial balance.
func add_account(accounts, name, balance) {
hashmap_set(accounts, name, balance);
}
What’s Happening Here:
- The
accountsobject is a hashmap where the keys are account names, and the values are balances. account_exists()prevents duplicate accounts or invalid operations on non-existent ones.add_account()is a simple wrapper to store new data in the hashmap.
Step 3: Transaction Logic (system.glang)
Now that we can store and find accounts, it’s time to handle transactions like deposits and withdrawals.
glang
fetch std_hashmap;
fetch std_format;
fetch "account.glang"; # We need 'account_exists' from the account file.
# Deposits money into an account.
func make_deposit(accounts, name, amount) {
if account_exists(accounts, name) {
hashmap_set(accounts, name, amount);
} otherwise {
bark(format("Error: account '{}' not found", name));
}
}
# Withdraws money, with basic error checking.
func make_withdrawl(accounts, name, amount) {
if account_exists(accounts, name) {
obj og_amount = hashmap_get(accounts, name);
obj new_amount = og_amount - amount;
# Prevents overdrafts — no negative balances allowed.
if new_amount < 0 {
bark("Error: invalid balance after withdrawl");
give null; # Stop execution early.
}
hashmap_set(accounts, name, new_amount);
} otherwise {
bark(format("Error: account '{}' not found", name));
}
}
Step 4: The Main Program (main.glang)
Now comes the fun part; making the system interactive!
This file ties everything together, allowing a user to create accounts, deposit or withdraw money, and view balances.
glang
fetch std_hashmap;
fetch std_format;
fetch "src/account.glang";
fetch "src/system.glang";
obj accounts = hashmap(); # Our central registry of all accounts.
while true {
bark("\n** Welcome to the bank! **\n");
bark("1. Make a withdrawl");
bark("2. Make a deposit");
bark("3. Open an account with us");
bark("4. Check account balance");
bark("5. Exit\n");
obj input = chew("Enter an option: ");
if input == "1" {
obj name = chew("Enter the account name: ");
obj amount = chew("Enter an amount to withdraw: ");
try {
amount = tonumber(amount);
} catch _ {
bark("Invalid amount");
}
make_withdrawl(accounts, name, amount);
} alsoif input == "2" {
obj name = chew("Enter the account name: ");
obj amount = chew("Enter an amount to deposit: ");
try {
amount = tonumber(amount);
} catch _ {
bark("Invalid amount");
}
make_deposit(accounts, name, amount);
} alsoif input == "3" {
obj name = chew("Enter the account name: ");
obj starting_balance = chew("Enter the starting balance for this account: ");
try {
starting_balance = tonumber(starting_balance);
} catch _ {
bark("Invalid starting balance");
}
add_account(accounts, name, starting_balance);
} alsoif input == "4" {
obj name = chew("Enter the account name: ");
if account_exists(accounts, name) {
obj amount = hashmap_get(accounts, name);
bark(format("Your account balance is: {}", amount));
} otherwise {
bark(format("Error: account '{}' not found", name));
}
} alsoif input == "5" {
leave; # Exit the program gracefully.
} otherwise {
bark("Invalid option");
}
}
What’s Happening Here:
- A
while trueloop keeps the system running until the user chooses to exit. - Each option corresponds to a banking action, using our earlier helper functions.
- Errors (like non-existent accounts or bad inputs) are handled gracefully.
Your Challenge 🤔
Add a way for users to close accounts they have created. It's up to you how to implement this!