Bank Management System

Advanced Bank Management System with Account Handling, Secure Transactions, and Data Persistence

Project Overview

The Bank Management System is a Python-based application designed to simulate the operations of a bank, providing users with the ability to manage their accounts, conduct transactions, and access financial services securely. This project is highly modular, incorporating essential concepts of file handling, object-oriented programming, and data serialization via JSON. It’s a great project for intermediate Python developers looking to enhance their programming and problem-solving skills.

Key Features

  • Account Creation:
    • Automatically generates a unique 10-digit account number.
    • Stores user details like name, date of birth, contact information, and password.
    • Enforces validation checks for initial deposit and user input.
  • Secure Authentication:
    • Allows users to log in using their account number and password.
    • Ensures secure access to account details and operations.
  • Transaction Handling:
    • Deposit: Add funds to the account.
    • Withdrawal: Securely deduct funds.
    • Transfer: Facilitate money transfers between accounts.
    • All transactions are logged with timestamps for accountability.
  • Account Management:
    • Update user details such as phone number, email, or password.
  • Transaction History:
    • Provides a comprehensive log of all activities, including deposits, withdrawals, and transfers.
  • Data Persistence:
    • Uses a JSON file (bank_data.json) to ensure that all user data is saved and retrieved seamlessly across sessions.

Flow of the Program

  • User Interaction : The program begins with a main menu displaying the available operations. The user selects an option, which directs the flow to the respective functionality.
  • Authentication : Most operations require the user to authenticate using their account number and password. This ensures that only authorized users can access sensitive account information.
  • Execution : The chosen operation (e.g., deposit, withdrawal, account update) is executed after authentication.
  • Data Management : All changes made during the session are immediately saved to the JSON file to ensure data consistency.
  • Exit : When the user exits the program, the session gracefully ends, and all updates are securely stored.

Breaking Down the Code

1. Loading and Saving Data

The program ensures persistent data storage using JSON files.

  def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r") as file:
            return json.load(file)
    return {}

def save_data(data):
    with open(DATA_FILE, "w") as file:
        json.dump(data, file, indent=4)
  

Explanation:

  • load_data() reads the bank_data.json file to load account information. If the file doesn’t exist, it initializes an empty dictionary.
  • save_data(data) writes the updated account data back to the file, ensuring changes persist after the program closes.

2. Account Creation

This function allows new users to create an account with all required details.

  def create_account(accounts):
    account_number = generate_account_number(accounts)
    name = input("Enter account holder's name: ")
    dob = input("Enter date of birth (DD-MM-YYYY): ")
    ...
    accounts[account_number] = {
        "name": name,
        "dob": dob,
        ...
    }
    print(f"Account created successfully for {name}. Your account number is {account_number}.")
    return accounts
  

Explanation:

  • A unique account number is generated using the generate_account_number() function.
  • User input is validated and stored in a dictionary with the account number as the key.
  • The initial deposit is mandatory, ensuring every account starts with a positive balance.

3. Authentication

The program secures access by verifying the account number and password.

  def authenticate_user(accounts):
    account_number = input("Enter your account number: ")
    if account_number not in accounts:
        print("Account not found!")
        return None
    ...
    print("Authentication successful!")
    return account_number
  

Explanation:

  • Users provide their account number and password.
  • If credentials are incorrect, access is denied, safeguarding sensitive data.

4. Deposit Money

Users can deposit funds into their account securely.

  def deposit_money(accounts):
    account_number = authenticate_user(accounts)
    if account_number:
        amount = float(input("Enter amount to deposit: "))
        ...
        print(f"Amount deposited successfully! New balance: {accounts[account_number]['balance']}")
  

Explanation:

  • After authentication, the deposit amount is validated and added to the account balance.
  • A deposit transaction record is appended to the account’s transaction log.

5. Transaction History

Users can view detailed logs of their account transactions.

  def view_transaction_history(accounts):
    account_number = authenticate_user(accounts)
    if account_number:
        print("Transaction history for account:")
        ...
  

Explanation:

  • Retrieves and displays a chronological list of all transactions, including deposits, withdrawals, and transfers.

6. Money Transfer

Users can securely transfer funds between accounts.

  def transfer_money(accounts):
    sender_account = authenticate_user(accounts)
    if sender_account:
        recipient_account = input("Enter recipient's account number: ")
        if recipient_account not in accounts:
            print("Recipient account not found!")
            return
        amount = float(input("Enter transfer amount: "))
        ...
        print(f"Successfully transferred {amount} to {recipient_account}. New balance: {accounts[sender_account]['balance']}")
  

Explanation:

  • Authenticates the sender’s account.
  • Validates the recipient account and ensures sufficient balance before completing the transfer.
  • Updates transaction logs for both sender and recipient accounts.

Final Code

Here is the complete code for the Bank Management System

  import os
import json
import random
import datetime

DATA_FILE = "bank_data.json"

def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r") as file:
            return json.load(file)
    return {}

def save_data(data):
    with open(DATA_FILE, "w") as file:
        json.dump(data, file, indent=4)

def generate_account_number(existing_accounts):
    while True:
        account_number = str(random.randint(1000000000, 9999999999))
        if account_number not in existing_accounts:
            return account_number

def create_account(accounts):
    account_number = generate_account_number(accounts)
    name = input("Enter account holder's name: ")
    dob = input("Enter date of birth (DD-MM-YYYY): ")
    phone = input("Enter phone number: ")
    email = input("Enter email address: ")
    password = input("Set a password for your account: ")
    initial_deposit = float(input("Enter initial deposit amount: "))
    if initial_deposit < 0:
        print("Initial deposit cannot be negative!")
        return accounts

    accounts[account_number] = {
        "name": name,
        "dob": dob,
        "phone": phone,
        "email": email,
        "password": password,
        "balance": initial_deposit,
        "transactions": [{
            "type": "Deposit",
            "amount": initial_deposit,
            "date": str(datetime.datetime.now())
        }]
    }
    print(f"Account created successfully for {name}. Your account number is {account_number}.")
    return accounts

def authenticate_user(accounts):
    account_number = input("Enter your account number: ")
    if account_number not in accounts:
        print("Account not found!")
        return None

    password = input("Enter your password: ")
    if accounts[account_number]["password"] != password:
        print("Incorrect password!")
        return None

    print("Authentication successful!")
    return account_number

def check_balance(accounts):
    account_number = authenticate_user(accounts)
    if account_number:
        print(f"Account holder: {accounts[account_number]['name']}")
        print(f"Current balance: {accounts[account_number]['balance']}")

def view_transaction_history(accounts):
    account_number = authenticate_user(accounts)
    if account_number:
        print(f"Transaction history for account {account_number}:")
        print("Type       | Amount     | Date")
        print("---------------------------------------")
        for transaction in accounts[account_number]["transactions"]:
            print(f"{transaction['type']:<10} | {transaction['amount']:<10} | {transaction['date']}")
        print()

def update_account_details(accounts):
    account_number = authenticate_user(accounts)
    if account_number:
        print(f"Updating details for account {account_number} - {accounts[account_number]['name']}")
        new_phone = input("Enter new phone number (leave blank to keep current): ")
        new_email = input("Enter new email address (leave blank to keep current): ")
        new_password = input("Enter new password (leave blank to keep current): ")

        if new_phone:
            accounts[account_number]["phone"] = new_phone
        if new_email:
            accounts[account_number]["email"] = new_email
        if new_password:
            accounts[account_number]["password"] = new_password

        print("Account details updated successfully!")
    return accounts

def transfer_money(accounts):
    sender_account = authenticate_user(accounts)
    if sender_account:
        receiver_account = input("Enter the recipient's account number: ")
        if receiver_account not in accounts:
            print("Recipient account not found!")
            return

        transfer_amount = float(input("Enter amount to transfer: "))
        if transfer_amount <= 0:
            print("Transfer amount must be greater than zero!")
        elif accounts[sender_account]["balance"] < transfer_amount:
            print("Insufficient balance!")
        else:
            accounts[sender_account]["balance"] -= transfer_amount
            accounts[sender_account]["transactions"].append({
                "type": "Transfer Out",
                "amount": transfer_amount,
                "date": str(datetime.datetime.now()),
                "to": receiver_account
            })

            accounts[receiver_account]["balance"] += transfer_amount
            accounts[receiver_account]["transactions"].append({
                "type": "Transfer In",
                "amount": transfer_amount,
                "date": str(datetime.datetime.now()),
                "from": sender_account
            })

            print(f"Transfer of {transfer_amount} successful!")
            print(f"New balance: {accounts[sender_account]['balance']}")

def main():
    accounts = load_data()
    while True:
        print("\n=== Bank Management System ===")
        print("1. Create New Account")
        print("2. Deposit Money")
        print("3. Withdraw Money")
        print("4. Check Balance")
        print("5. View Transaction History")
        print("6. Update Account Details")
        print("7. Transfer Money")
        print("8. Exit")
        choice = input("Enter your choice (1-8): ")

        if choice == "1":
            accounts = create_account(accounts)
        elif choice == "2":
            account_number = authenticate_user(accounts)
            if account_number:
                amount = float(input("Enter amount to deposit: "))
                if amount > 0:
                    accounts[account_number]["balance"] += amount
                    accounts[account_number]["transactions"].append({
                        "type": "Deposit",
                        "amount": amount,
                        "date": str(datetime.datetime.now())
                    })
                    print(f"Amount deposited successfully! New balance: {accounts[account_number]['balance']}")
                else:
                    print("Amount must be greater than zero!")
        elif choice == "3":
            account_number = authenticate_user(accounts)
            if account_number:
                amount = float(input("Enter amount to withdraw: "))
                if 0 < amount <= accounts[account_number]["balance"]:
                    accounts[account_number]["balance"] -= amount
                    accounts[account_number]["transactions"].append({
                        "type": "Withdrawal",
                        "amount": amount,
                        "date": str(datetime.datetime.now())
                    })
                    print(f"Amount withdrawn successfully! New balance: {accounts[account_number]['balance']}")
                else:
                    print("Invalid withdrawal amount or insufficient balance!")
        elif choice == "4":
            check_balance(accounts)
        elif choice == "5":
            view_transaction_history(accounts)
        elif choice == "6":
            accounts = update_account_details(accounts)
        elif choice == "7":
            transfer_money(accounts)
        elif choice == "8":
            save_data(accounts)
            print("Thank you for using the Bank Management System. Goodbye!")
            break
        else:
            print("Invalid choice! Please select a valid option.")

if __name__ == "__main__":
    main()
  

sample output

Bank Management System by python 01
Bank Management System by python 02
Bank Management System by python 03
Bank Management System by python 04
Bank Management System by python 05

Creating an Account, Making Transactions, and Viewing History Scenario A user named John Doe wants to open an account. He makes an initial deposit, performs a withdrawal, and checks his transaction history. Step 1: Account Creation Input: Name: "John Doe" DOB: "15-05-1985" Phone: "9876543210" Email: "john.doe@example.com" Initial Deposit: 5000 Output: Account number generated: 1234567890 Confirmation message: "Account created successfully for John Doe. Your account number is 1234567890." Step 2: Deposit Funds Log in using account number 1234567890 and password. Deposit 2000. Output: "Amount deposited successfully! New balance: 7000." Step 3: Withdraw Funds Log in using account number 1234567890. Withdraw 3000. Output: "Amount withdrawn successfully! New balance: 4000." Step 4: View Transaction History Log in using account number 1234567890. Output: Transaction history for account 1234567890: Type | Amount | Date --------------------------------------- Deposit | 5000 | 2024-12-01 10:30:00 Deposit | 2000 | 2024-12-02 11:15:00 Withdrawal | 3000 | 2024-12-03 12:45:00

Conclusion

The Bank Management System is a powerful demonstration of Python’s capabilities for building real-world applications. With secure data handling, user authentication, and intuitive operations, this project offers a comprehensive learning experience. By enhancing the interface or integrating advanced features like online banking APIs, this program can evolve into a professional-grade tool.

End of Post

Leave a Reply

Your email address will not be published. Required fields are marked *