Advanced banking application in Python using object-oriented programming (OOP) principles with database integration. This application will feature user authentication, account management, transaction logging, and database integration using SQLite.
Let’s start by outlining the structure of our application:
- User Class: This class will represent a bank user and will handle user-related functionalities such as registration, authentication, and account management.
- BankAccount Class: This class will represent a bank account and will handle account-related functionalities such as deposit, withdrawal, balance inquiry, and transaction logging.
- Database Integration: We’ll integrate SQLite database to store user information, account details, and transaction history.
Let’s implement each component step by step:
import sqlite3 # Import the SQLite library for database operations
import hashlib # Import the hashlib library for password hashing
import uuid # Import the uuid library for generating unique identifiers
# Connect to the SQLite database
conn = sqlite3.connect('banking_app.db') # Establish a connection to the SQLite database
c = conn.cursor() # Create a cursor object to execute SQL queries
# Create users table if not exists
c.execute('''CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- User ID (Primary Key)
username TEXT UNIQUE NOT NULL, -- Username (Unique and Not Null)
password TEXT NOT NULL)''') -- Password (Not Null)
# Create accounts table if not exists
c.execute('''CREATE TABLE IF NOT EXISTS accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- Account ID (Primary Key)
user_id INTEGER NOT NULL, -- User ID (Foreign Key)
balance REAL DEFAULT 0, -- Account Balance (Default 0)
FOREIGN KEY (user_id) REFERENCES users(id))''') -- Foreign Key Constraint
# Create transactions table if not exists
c.execute('''CREATE TABLE IF NOT EXISTS transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- Transaction ID (Primary Key)
account_id INTEGER NOT NULL, -- Account ID (Foreign Key)
amount REAL NOT NULL, -- Transaction Amount (Not Null)
type TEXT NOT NULL, -- Transaction Type (e.g., deposit, withdrawal)
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, -- Timestamp (Default Current Timestamp)
FOREIGN KEY (account_id) REFERENCES accounts(id))''') -- Foreign Key Constraint
# Commit changes and close connection
conn.commit() # Commit the changes to the database
conn.close() # Close the database connection
class User:
def __init__(self, username, password):
self.username = username
self.password = self._encrypt_password(password)
def _encrypt_password(self, password):
# Generate a unique salt for each user
salt = uuid.uuid4().hex
# Hash the password along with the salt
hashed_password = hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
return hashed_password
@staticmethod
def authenticate(username, password):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT password FROM users WHERE username=?", (username,))
result = c.fetchone()
conn.close()
if result:
hashed_password, salt = result[0].split(':')
if hashed_password == hashlib.sha256(salt.encode() + password.encode()).hexdigest():
return True
return False
def register(self):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("INSERT INTO users (username, password) VALUES (?, ?)", (self.username, self.password))
conn.commit()
conn.close()
print("User registered successfully.")
class BankAccount:
def __init__(self, username):
self.username = username
def create_account(self):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT id FROM users WHERE username=?", (self.username,))
user_id = c.fetchone()[0]
c.execute("INSERT INTO accounts (user_id) VALUES (?)", (user_id,))
conn.commit()
conn.close()
print("Account created successfully.")
def deposit(self, amount):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT id FROM users WHERE username=?", (self.username,))
user_id = c.fetchone()[0]
c.execute("SELECT id FROM accounts WHERE user_id=?", (user_id,))
account_id = c.fetchone()[0]
c.execute("UPDATE accounts SET balance=balance+? WHERE id=?", (amount, account_id))
c.execute("INSERT INTO transactions (account_id, amount, type) VALUES (?, ?, 'deposit')", (account_id, amount))
conn.commit()
conn.close()
print("Deposit successful.")
def withdraw(self, amount):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT id FROM users WHERE username=?", (self.username,))
user_id = c.fetchone()[0]
c.execute("SELECT id FROM accounts WHERE user_id=?", (user_id,))
account_id = c.fetchone()[0]
c.execute("SELECT balance FROM accounts WHERE id=?", (account_id,))
balance = c.fetchone()[0]
if balance >= amount:
c.execute("UPDATE accounts SET balance=balance-? WHERE id=?", (amount, account_id))
c.execute("INSERT INTO transactions (account_id, amount, type) VALUES (?, ?, 'withdrawal')",
(account_id, amount))
conn.commit()
conn.close()
print("Withdrawal successful.")
else:
print("Insufficient funds.")
def display_balance(self):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT id FROM users WHERE username=?", (self.username,))
user_id = c.fetchone()[0]
c.execute("SELECT id FROM accounts WHERE user_id=?", (user_id,))
account_id = c.fetchone()[0]
c.execute("SELECT balance FROM accounts WHERE id=?", (account_id,))
balance = c.fetchone()[0]
conn.close()
print("Your account balance is:", balance)
def display_transactions(self):
conn = sqlite3.connect('banking_app.db')
c = conn.cursor()
c.execute("SELECT id FROM users WHERE username=?", (self.username,))
user_id = c.fetchone()[0]
c.execute("SELECT id FROM accounts WHERE user_id=?", (user_id,))
account_id = c.fetchone()[0]
c.execute("SELECT * FROM transactions WHERE account_id=?", (account_id,))
transactions = c.fetchall()
conn.close()
print("Transaction History:")
for transaction in transactions:
print("Transaction ID:", transaction[0])
print("Amount:", transaction[2])
print("Type:", transaction[3])
print("Timestamp:", transaction[4])
def main():
print("Welcome to Our Bank!")
while True:
print("\n1. Register")
print("2. Login")
print("3. Exit")
choice = input("Enter your choice: ")
if choice == '1':
username = input("Enter username: ")
password = input("Enter password: ")
user = User(username, password)
user.register()
elif choice == '2':
username = input("Enter username: ")
password = input("Enter password: ")
if User.authenticate(username, password):
print("Login successful.")
bank_account = BankAccount(username)
while True:
print("\n1. Create Account")
print("2. Deposit")
print("3. Withdraw")
print("4. Display Balance")
print("5. Display Transactions")
print("6. Logout")
option = input("Enter your option: ")
if option == '1':
bank_account.create_account()
elif option == '2':
amount = float(input("Enter deposit amount: "))
bank_account.deposit(amount)
elif option == '3':
amount = float(input("Enter withdrawal amount: "))
bank_account.withdraw(amount)
elif option == '4':
bank_account.display_balance()
elif option == '5':
bank_account.display_transactions()
elif option == '6':
break
else:
print("Invalid option.")
else:
print("Login failed.")
elif choice == '3':
break
else:
print("Invalid choice.")
if __name__ == "__main__":
main()
Let’s go through the code step by step, explaining each part in detail:
Database Initialization:
- The script starts by importing necessary modules:
sqlite3
,hashlib
, anduuid
. - It establishes a connection to an SQLite database named
'banking_app.db'
. - Three tables are created if they do not exist already:
users
,accounts
, andtransactions
. These tables are used to store user information, account details, and transaction history respectively. - Each table has its structure defined: primary keys, foreign keys, and constraints.
- The script starts by importing necessary modules:
User Class:
- The
User
class represents a bank user. It has methods to register a new user and authenticate existing users. - When a
User
object is created, it takesusername
andpassword
as parameters, and the password is encrypted using a salt generated byuuid
. - The
authenticate
method takesusername
andpassword
as parameters and checks if the provided credentials match those stored in the database. - The
register
method inserts a new user into theusers
table in the database.
- The
BankAccount Class:
- The
BankAccount
class represents a bank account. It has methods to create a new account, deposit funds, withdraw funds, display account balance, and display transaction history. - When a
BankAccount
object is created, it takesusername
as a parameter. - The
create_account
method inserts a new account into theaccounts
table in the database. - The
deposit
method updates the account balance by adding the deposited amount and logs a deposit transaction into thetransactions
table. - The
withdraw
method updates the account balance by subtracting the withdrawn amount if sufficient funds are available and logs a withdrawal transaction. - The
display_balance
method retrieves and prints the current account balance. - The
display_transactions
method retrieves and prints the transaction history for the account.
- The
Main Function:
- The
main
function serves as the entry point of the application. - It presents a menu to the user with options to register, login, or exit.
- If the user chooses to register, they are prompted to enter a username and password. A new
User
object is created, and theregister
method is called. - If the user chooses to login, they are prompted to enter their credentials. The
authenticate
method is called to verify the credentials. If successful, a menu for account actions is presented. - The user can create a new account, deposit funds, withdraw funds, display balance, display transactions, or logout.
- The process continues until the user chooses to exit.
- The
Main Execution:
- The
main
function is called when the script is executed directly (not imported as a module). - This ensures that the banking application runs when the script is executed standalone.
- The
Overall, the code provides a comprehensive banking application with user authentication, account management, and database integration. It uses object-oriented programming principles to organize functionalities into User
and BankAccount
classes, making the code modular and easy to understand. The SQLite database handles data persistence, storing user information, account details, and transaction history.
Welcome to DevTechTutor.com, your ultimate resource for mastering web development and technology! Whether you're a beginner eager to dive into coding or an experienced developer looking to sharpen your skills, DevTechTutor.com is here to guide you every step of the way. Our mission is to make learning web development accessible, engaging, and effective.