diff --git a/.ipynb_checkpoints/lab-python-oop-checkpoint.ipynb b/.ipynb_checkpoints/lab-python-oop-checkpoint.ipynb new file mode 100644 index 0000000..ccde7d7 --- /dev/null +++ b/.ipynb_checkpoints/lab-python-oop-checkpoint.ipynb @@ -0,0 +1,855 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e", + "metadata": {}, + "source": [ + "# Lab | Object Oriented Programming" + ] + }, + { + "cell_type": "markdown", + "id": "6f8e446f-16b4-4e21-92e7-9d3d1eb551b6", + "metadata": {}, + "source": [ + "Objective: Practice how to work with OOP using classes, objects, and inheritance to create robust, maintainable, and scalable code." + ] + }, + { + "cell_type": "markdown", + "id": "20c3e882-9625-471e-afb4-48a4f40c5d1b", + "metadata": { + "tags": [] + }, + "source": [ + "## Challenge 1: Bank Account" + ] + }, + { + "cell_type": "markdown", + "id": "fe982bf8-9610-4de3-aa93-256db5a05903", + "metadata": {}, + "source": [ + "Create a BankAccount class with the following attributes and methods:\n", + "\n", + "Attributes:\n", + "\n", + "- account_number (a unique identifier for the bank account)\n", + "- balance (the current balance of the account. By default, is 0)\n", + "\n", + "Methods:\n", + "\n", + "- deposit(amount) - adds the specified amount to the account balance\n", + "- withdraw(amount) - subtracts the specified amount from the account balance\n", + "- get_balance() - returns the current balance of the account\n", + "- get_account_number() - returns the account number of the account\n", + "\n", + "Instructions:\n", + "\n", + "- Create a BankAccount class with the above attributes and methods.\n", + "- Test the class by creating a few instances of BankAccount and making deposits and withdrawals.\n", + "- Ensure that the account_number attribute is unique for each instance of BankAccount.\n", + "\n", + "*Hint: create a class attribute account_count. The account_count class attribute is used to keep track of the total number of bank accounts that have been created using the BankAccount class. Every time a new BankAccount object is created, the account_count attribute is incremented by one. This can be useful for various purposes, such as generating unique account numbers or monitoring the growth of a bank's customer base.*" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ee789466-d4cf-4dd8-b742-6863d42c3e5c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 balance: 1000\n", + "Account 2 balance: 500\n", + "Deposited $200.00. New balance: $1200.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $150.00. Remaining balance: $1050.00\n", + "Withdrew $50.00. Remaining balance: $750.00\n", + "\n", + "Final Balances:\n", + "Account 1 balance: $1050.00\n", + "Account 2 balance: $750.00\n", + "\n", + "Account Numbers:\n", + "Account 1 number: 1\n", + "Account 2 number: 2\n" + ] + } + ], + "source": [ + "# ------------------------------------------\n", + "# BankAccount Class and Testing\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " # Class attribute to track number of accounts created\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with a unique account number and optional initial balance.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the BankAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two accounts\n", + "account1 = BankAccount(1000)\n", + "account2 = BankAccount(500)\n", + "\n", + "# Display initial balances\n", + "print(\"Account 1 balance:\", account1.get_balance())\n", + "print(\"Account 2 balance:\", account2.get_balance())\n", + "\n", + "# Make deposits\n", + "account1.deposit(200)\n", + "account2.deposit(300)\n", + "\n", + "# Make withdrawals\n", + "account1.withdraw(150)\n", + "account2.withdraw(50)\n", + "\n", + "# Display final balances\n", + "print(\"\\nFinal Balances:\")\n", + "print(f\"Account {account1.get_account_number()} balance: ${account1.get_balance():.2f}\")\n", + "print(f\"Account {account2.get_account_number()} balance: ${account2.get_balance():.2f}\")\n", + "\n", + "# Display unique account numbers\n", + "print(\"\\nAccount Numbers:\")\n", + "print(\"Account 1 number:\", account1.get_account_number())\n", + "print(\"Account 2 number:\", account2.get_account_number())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "21625526-3fae-4c55-bab5-f91940070681", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 balance: 1000\n", + "Account 2 balance: 500\n", + "Deposited $200.00. New balance: $1200.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $150.00. Remaining balance: $1050.00\n", + "Withdrew $50.00. Remaining balance: $750.00\n", + "Account 1 final balance: 1050\n", + "Account 2 final balance: 750\n", + "Account 1 number: 1\n", + "Account 2 number: 2\n" + ] + } + ], + "source": [ + "# Testing the BankAccount class\n", + "account1 = BankAccount(1000)\n", + "account2 = BankAccount(500)\n", + "\n", + "print(\"Account 1 balance:\", account1.get_balance()) # Should print 1000\n", + "print(\"Account 2 balance:\", account2.get_balance()) # Should print 500\n", + "\n", + "# Deposits\n", + "account1.deposit(200)\n", + "account2.deposit(300)\n", + "\n", + "# Withdrawals\n", + "account1.withdraw(150)\n", + "account2.withdraw(50)\n", + "\n", + "# Final balances\n", + "print(\"Account 1 final balance:\", account1.get_balance())\n", + "print(\"Account 2 final balance:\", account2.get_balance())\n", + "\n", + "# Unique account numbers\n", + "print(\"Account 1 number:\", account1.get_account_number())\n", + "print(\"Account 2 number:\", account2.get_account_number())\n" + ] + }, + { + "cell_type": "markdown", + "id": "929305ed-67cb-4094-8af2-4fa9b751832a", + "metadata": {}, + "source": [ + "## Challenge 2: Savings Account\n", + "\n", + "Create a SavingsAccount class that inherits from the BankAccount class. The SavingsAccount class should have the following additional attributes and methods:\n", + "\n", + "Attributes:\n", + "\n", + "- interest_rate (the annual interest rate for the savings account. By default - if no value is provided - sets it to 0.01)\n", + "\n", + "Methods:\n", + "\n", + "- add_interest() - adds the interest earned to the account balance\n", + "- get_interest_rate() - returns the interest rate for the account\n", + "\n", + "Instructions:\n", + "\n", + "- Create a SavingsAccount class that inherits from the BankAccount class and has the above attributes and methods.\n", + "- Test the class by creating a few instances of SavingsAccount and making deposits and withdrawals, as well as adding interest." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4f8848b5-05d3-4259-9e24-914537926778", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 - Balance: $1000.00, Interest Rate: 3.0%\n", + "Account 2 - Balance: $500.00, Interest Rate: 1.0%\n", + "Deposited $500.00. New balance: $1500.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $200.00. Remaining balance: $1300.00\n", + "Withdrew $100.00. Remaining balance: $700.00\n", + "\n", + "Adding interest...\n", + "Interest of $39.00 added. New balance: $1339.00\n", + "Interest of $7.00 added. New balance: $707.00\n", + "\n", + "Final Balances:\n", + "Account 1 balance: $1339.00\n", + "Account 2 balance: $707.00\n" + ] + } + ], + "source": [ + "# ------------------------------------------\n", + "# BankAccount Base Class\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " # Class attribute to track number of accounts created\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with a unique account number and optional initial balance.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# SavingsAccount Subclass\n", + "# ------------------------------------------\n", + "\n", + "class SavingsAccount(BankAccount):\n", + " def __init__(self, balance=0, interest_rate=0.01):\n", + " \"\"\"Initialize a new savings account with an interest rate.\"\"\"\n", + " super().__init__(balance) # Call the parent constructor\n", + " self.interest_rate = interest_rate\n", + "\n", + " def add_interest(self):\n", + " \"\"\"Calculate and add interest to the account balance.\"\"\"\n", + " interest = self.balance * self.interest_rate\n", + " self.balance += interest\n", + " print(f\"Interest of ${interest:.2f} added. New balance: ${self.balance:.2f}\")\n", + "\n", + " def get_interest_rate(self):\n", + " \"\"\"Return the current interest rate.\"\"\"\n", + " return self.interest_rate\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the SavingsAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two savings accounts with different interest rates\n", + "savings1 = SavingsAccount(1000, 0.03) # 3% interest\n", + "savings2 = SavingsAccount(500) # Default 1% interest\n", + "\n", + "# Display initial info\n", + "print(f\"Account {savings1.get_account_number()} - Balance: ${savings1.get_balance():.2f}, Interest Rate: {savings1.get_interest_rate()*100:.1f}%\")\n", + "print(f\"Account {savings2.get_account_number()} - Balance: ${savings2.get_balance():.2f}, Interest Rate: {savings2.get_interest_rate()*100:.1f}%\")\n", + "\n", + "# Perform transactions\n", + "savings1.deposit(500)\n", + "savings2.deposit(300)\n", + "savings1.withdraw(200)\n", + "savings2.withdraw(100)\n", + "\n", + "# Add interest\n", + "print(\"\\nAdding interest...\")\n", + "savings1.add_interest()\n", + "savings2.add_interest()\n", + "\n", + "# Final balances\n", + "print(\"\\nFinal Balances:\")\n", + "print(f\"Account {savings1.get_account_number()} balance: ${savings1.get_balance():.2f}\")\n", + "print(f\"Account {savings2.get_account_number()} balance: ${savings2.get_balance():.2f}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "d2c84bdb-e7d1-491d-9b0e-194288702c02", + "metadata": {}, + "source": [ + "Example of testing the SavingsAccount\n", + "\n", + "- Create a SavingsAccount object with a balance of $100 and interest rate of 2%\n", + "\n", + "- Deposit $50 into the savings account\n", + "\n", + "- Withdraw $25 from the savings account\n", + "\n", + "- Add interest to the savings account (use the default 0.01)\n", + "\n", + "- Print the current balance and interest rate of the savings account\n", + "\n", + "Expected output:\n", + " \n", + " Current balance: 127.5\n", + " \n", + " Interest rate: 0.02" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "bccc7f6d-d58c-4909-9314-aaf4afc1cd30", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current balance: 126.25\n", + "Interest rate: 0.01\n" + ] + } + ], + "source": [ + "# ------------------------------------------\n", + "# BankAccount Base Class\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + "\n", + " def withdraw(self, amount):\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + "\n", + " def get_balance(self):\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# SavingsAccount Subclass\n", + "# ------------------------------------------\n", + "\n", + "class SavingsAccount(BankAccount):\n", + " def __init__(self, balance=0, interest_rate=0.01):\n", + " \"\"\"Initialize a savings account with an optional interest rate.\"\"\"\n", + " super().__init__(balance)\n", + " self.interest_rate = interest_rate\n", + "\n", + " def add_interest(self):\n", + " \"\"\"Add interest to the current balance.\"\"\"\n", + " interest = self.balance * self.interest_rate\n", + " self.balance += interest\n", + "\n", + " def get_interest_rate(self):\n", + " return self.interest_rate\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Example Test (Based on Your Scenario)\n", + "# ------------------------------------------\n", + "\n", + "# 1. Create SavingsAccount with $100 and 2% interest rate\n", + "savings = SavingsAccount(100, 0.02)\n", + "\n", + "# 2. Deposit $50\n", + "savings.deposit(50)\n", + "\n", + "# 3. Withdraw $25\n", + "savings.withdraw(25)\n", + "\n", + "# 4. Temporarily change rate to default (0.01) and add interest\n", + "savings.interest_rate = 0.01\n", + "savings.add_interest()\n", + "\n", + "# 5. Print results\n", + "print(\"Current balance:\", savings.get_balance())\n", + "print(\"Interest rate:\", savings.get_interest_rate())\n" + ] + }, + { + "cell_type": "markdown", + "id": "a5455a88-a8d1-47a6-86b0-7c70647b4f31", + "metadata": {}, + "source": [ + "### Challenge 3: Checking Account\n", + "\n", + "Create a CheckingAccount class that inherits from the BankAccount class. The CheckingAccount class should have the following additional attributes and methods:\n", + "\n", + "Attributes:\n", + "\n", + "- transaction_fee (the fee charged per transaction. By default is 1$)\n", + "- transaction_count (the number of transactions made in the current month)\n", + "\n", + "Methods:\n", + "\n", + "- deduct_fees() - deducts transaction fees from the account balance based on the number of transactions made in the current month and the transaction fee per transaction. The method calculates the total fees by multiplying the transaction count with the transaction fee, and deducts the fees from the account balance if it's sufficient. If the balance is insufficient, it prints an error message. Otherwise, it prints how much it's been deducted. After deducting the fees, the method resets the transaction count to 0.\n", + "- reset_transactions() - resets the transaction count to 0\n", + "- get_transaction_count() - returns the current transaction count for the account\n", + "\n", + "Instructions:\n", + "\n", + "- Create a CheckingAccount class that inherits from the BankAccount class and has the above attributes and methods.\n", + "- Test the class by creating a few instances of CheckingAccount and making deposits, withdrawals, and transactions to deduct fees.\n", + "\n", + "Note: To ensure that the transaction count is updated every time a deposit or withdrawal is made, we need to overwrite the deposit and withdraw methods inherited from the BankAccount class. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "3c883c6e-3cb8-4043-92d3-12409668a28e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deposited $200.00. New balance: $700.00\n", + "Withdrew $100.00. Remaining balance: $600.00\n", + "Deposited $50.00. New balance: $650.00\n", + "Withdrew $300.00. Remaining balance: $700.00\n", + "Deposited $400.00. New balance: $1100.00\n", + "Withdrew $200.00. Remaining balance: $900.00\n", + "\n", + "Transaction Summary:\n", + "Account 1 - Balance: $650.00, Transactions: 3\n", + "Account 2 - Balance: $900.00, Transactions: 3\n", + "\n", + "Deducting Fees...\n", + "Deducted $3.00 in transaction fees. New balance: $647.00\n", + "Deducted $6.00 in transaction fees. New balance: $894.00\n", + "\n", + "Final Balances After Fees:\n", + "Account 1 balance: $647.00\n", + "Account 2 balance: $894.00\n" + ] + } + ], + "source": [ + "# ------------------------------------------\n", + "# Base Class: BankAccount\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with unique account number.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the unique account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Subclass: CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "class CheckingAccount(BankAccount):\n", + " def __init__(self, balance=0, transaction_fee=1):\n", + " \"\"\"Initialize a checking account with transaction fee.\"\"\"\n", + " super().__init__(balance)\n", + " self.transaction_fee = transaction_fee\n", + " self.transaction_count = 0\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Deposit money and increase transaction count.\"\"\"\n", + " super().deposit(amount)\n", + " if amount > 0:\n", + " self.transaction_count += 1\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Withdraw money and increase transaction count.\"\"\"\n", + " if amount > 0 and amount <= self.balance:\n", + " super().withdraw(amount)\n", + " self.transaction_count += 1\n", + " else:\n", + " super().withdraw(amount) # Let parent handle errors\n", + "\n", + " def deduct_fees(self):\n", + " \"\"\"Deduct transaction fees based on the number of transactions.\"\"\"\n", + " total_fees = self.transaction_count * self.transaction_fee\n", + " if total_fees == 0:\n", + " print(\"No transactions this month. No fees deducted.\")\n", + " return\n", + " if total_fees > self.balance:\n", + " print(\"Insufficient funds to deduct transaction fees.\")\n", + " return\n", + " self.balance -= total_fees\n", + " print(f\"Deducted ${total_fees:.2f} in transaction fees. New balance: ${self.balance:.2f}\")\n", + " self.transaction_count = 0 # Reset count after deduction\n", + "\n", + " def reset_transactions(self):\n", + " \"\"\"Reset transaction count to 0.\"\"\"\n", + " self.transaction_count = 0\n", + " print(\"Transaction count has been reset to 0.\")\n", + "\n", + " def get_transaction_count(self):\n", + " \"\"\"Return the current transaction count.\"\"\"\n", + " return self.transaction_count\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the CheckingAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two checking accounts\n", + "checking1 = CheckingAccount(500)\n", + "checking2 = CheckingAccount(1000, transaction_fee=2)\n", + "\n", + "# Perform deposits and withdrawals\n", + "checking1.deposit(200)\n", + "checking1.withdraw(100)\n", + "checking1.deposit(50)\n", + "\n", + "checking2.withdraw(300)\n", + "checking2.deposit(400)\n", + "checking2.withdraw(200)\n", + "\n", + "# Check balances and transaction counts\n", + "print(\"\\nTransaction Summary:\")\n", + "print(f\"Account {checking1.get_account_number()} - Balance: ${checking1.get_balance():.2f}, Transactions: {checking1.get_transaction_count()}\")\n", + "print(f\"Account {checking2.get_account_number()} - Balance: ${checking2.get_balance():.2f}, Transactions: {checking2.get_transaction_count()}\")\n", + "\n", + "# Deduct fees for both accounts\n", + "print(\"\\nDeducting Fees...\")\n", + "checking1.deduct_fees()\n", + "checking2.deduct_fees()\n", + "\n", + "# Final balances\n", + "print(\"\\nFinal Balances After Fees:\")\n", + "print(f\"Account {checking1.get_account_number()} balance: ${checking1.get_balance():.2f}\")\n", + "print(f\"Account {checking2.get_account_number()} balance: ${checking2.get_balance():.2f}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "8217ec46-3eae-4a7c-9c7c-d4a87aac7e6d", + "metadata": {}, + "source": [ + "Example of testing CheckingAccount:\n", + "\n", + " - Create a new checking account with a balance of 500 dollars and a transaction fee of 2 dollars\n", + " - Deposit 100 dollars into the account \n", + " - Withdraw 50 dollars from the account \n", + " - Deduct the transaction fees from the account\n", + " - Get the current balance and transaction count\n", + " - Deposit 200 dollars into the account\n", + " - Withdraw 75 dollars from the account\n", + " - Deduct the transaction fees from the account\n", + " - Get the current balance and transaction count again\n", + " \n", + "\n", + "Expected output:\n", + " \n", + " Transaction fees of 4$ have been deducted from your account balance.\n", + " \n", + " Current balance: 546\n", + " \n", + " Transaction count: 0\n", + " \n", + " Transaction fees of 4$ have been deducted from your account balance.\n", + " \n", + " Current balance: 667\n", + " \n", + " Transaction count: 0\n", + "\n", + "Note: *the print \"Transaction fees of 4$ have been deducted from your account balance\" is done in the method deduct_fees*" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "faa5b148-c11b-4be0-b810-de8a7da81451", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transaction fees of 4$ have been deducted from your account balance.\n", + "\n", + "Current balance: 546\n", + "Transaction count: 0\n", + "Transaction fees of 4$ have been deducted from your account balance.\n", + "\n", + "Current balance: 667\n", + "Transaction count: 0\n" + ] + } + ], + "source": [ + "# ------------------------------------------\n", + "# Base Class: BankAccount\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with unique account number.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the unique account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Subclass: CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "class CheckingAccount(BankAccount):\n", + " def __init__(self, balance=0, transaction_fee=1):\n", + " \"\"\"Initialize a checking account with transaction fee.\"\"\"\n", + " super().__init__(balance)\n", + " self.transaction_fee = transaction_fee\n", + " self.transaction_count = 0\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Deposit money and increase transaction count.\"\"\"\n", + " super().deposit(amount)\n", + " if amount > 0:\n", + " self.transaction_count += 1\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Withdraw money and increase transaction count.\"\"\"\n", + " if amount > 0 and amount <= self.balance:\n", + " super().withdraw(amount)\n", + " self.transaction_count += 1\n", + " else:\n", + " super().withdraw(amount)\n", + "\n", + " def deduct_fees(self):\n", + " \"\"\"Deduct transaction fees based on transaction count.\"\"\"\n", + " total_fees = self.transaction_count * self.transaction_fee\n", + " if total_fees == 0:\n", + " print(\"No transactions to deduct fees for.\")\n", + " return\n", + " if total_fees > self.balance:\n", + " print(\"Insufficient funds to deduct transaction fees.\")\n", + " return\n", + " self.balance -= total_fees\n", + " print(f\"Transaction fees of {total_fees}$ have been deducted from your account balance.\")\n", + " self.transaction_count = 0\n", + "\n", + " def reset_transactions(self):\n", + " \"\"\"Reset transaction count to 0.\"\"\"\n", + " self.transaction_count = 0\n", + "\n", + " def get_transaction_count(self):\n", + " \"\"\"Return the current transaction count.\"\"\"\n", + " return self.transaction_count\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Example Testing of CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "# Step 1: Create a new checking account with $500 balance and $2 fee\n", + "checking = CheckingAccount(500, transaction_fee=2)\n", + "\n", + "# Step 2: Deposit $100\n", + "checking.deposit(100)\n", + "\n", + "# Step 3: Withdraw $50\n", + "checking.withdraw(50)\n", + "\n", + "# Step 4: Deduct fees\n", + "checking.deduct_fees()\n", + "\n", + "# Step 5: Print current balance and transaction count\n", + "print(\"\\nCurrent balance:\", int(checking.get_balance()))\n", + "print(\"Transaction count:\", checking.get_transaction_count())\n", + "\n", + "# Step 6: Deposit $200\n", + "checking.deposit(200)\n", + "\n", + "# Step 7: Withdraw $75\n", + "checking.withdraw(75)\n", + "\n", + "# Step 8: Deduct fees again\n", + "checking.deduct_fees()\n", + "\n", + "# Step 9: Print current balance and transaction count again\n", + "print(\"\\nCurrent balance:\", int(checking.get_balance()))\n", + "print(\"Transaction count:\", checking.get_transaction_count())\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ba14df9-c308-4690-8eb6-314bd56e8467", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lab-python-oop.ipynb b/lab-python-oop.ipynb index c13bc58..ccde7d7 100644 --- a/lab-python-oop.ipynb +++ b/lab-python-oop.ipynb @@ -56,39 +56,151 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "21625526-3fae-4c55-bab5-f91940070681", + "execution_count": 6, + "id": "ee789466-d4cf-4dd8-b742-6863d42c3e5c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 balance: 1000\n", + "Account 2 balance: 500\n", + "Deposited $200.00. New balance: $1200.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $150.00. Remaining balance: $1050.00\n", + "Withdrew $50.00. Remaining balance: $750.00\n", + "\n", + "Final Balances:\n", + "Account 1 balance: $1050.00\n", + "Account 2 balance: $750.00\n", + "\n", + "Account Numbers:\n", + "Account 1 number: 1\n", + "Account 2 number: 2\n" + ] + } + ], "source": [ - "# your code goes here\n", - "\n" + "# ------------------------------------------\n", + "# BankAccount Class and Testing\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " # Class attribute to track number of accounts created\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with a unique account number and optional initial balance.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the BankAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two accounts\n", + "account1 = BankAccount(1000)\n", + "account2 = BankAccount(500)\n", + "\n", + "# Display initial balances\n", + "print(\"Account 1 balance:\", account1.get_balance())\n", + "print(\"Account 2 balance:\", account2.get_balance())\n", + "\n", + "# Make deposits\n", + "account1.deposit(200)\n", + "account2.deposit(300)\n", + "\n", + "# Make withdrawals\n", + "account1.withdraw(150)\n", + "account2.withdraw(50)\n", + "\n", + "# Display final balances\n", + "print(\"\\nFinal Balances:\")\n", + "print(f\"Account {account1.get_account_number()} balance: ${account1.get_balance():.2f}\")\n", + "print(f\"Account {account2.get_account_number()} balance: ${account2.get_balance():.2f}\")\n", + "\n", + "# Display unique account numbers\n", + "print(\"\\nAccount Numbers:\")\n", + "print(\"Account 1 number:\", account1.get_account_number())\n", + "print(\"Account 2 number:\", account2.get_account_number())\n" ] }, { "cell_type": "code", - "execution_count": null, - "id": "ee789466-d4cf-4dd8-b742-6863d42c3e5c", + "execution_count": 3, + "id": "21625526-3fae-4c55-bab5-f91940070681", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 balance: 1000\n", + "Account 2 balance: 500\n", + "Deposited $200.00. New balance: $1200.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $150.00. Remaining balance: $1050.00\n", + "Withdrew $50.00. Remaining balance: $750.00\n", + "Account 1 final balance: 1050\n", + "Account 2 final balance: 750\n", + "Account 1 number: 1\n", + "Account 2 number: 2\n" + ] + } + ], "source": [ "# Testing the BankAccount class\n", - "# Creating two instances of the BankAccount class with initial balances of 1000 and 500\n", "account1 = BankAccount(1000)\n", "account2 = BankAccount(500)\n", "\n", - "print(\"Account 1 balance:\", account1.get_balance()) # This should print 1000\n", - "print(\"Account 1 number:\", account1.get_account_number()) # This should print 1\n", + "print(\"Account 1 balance:\", account1.get_balance()) # Should print 1000\n", + "print(\"Account 2 balance:\", account2.get_balance()) # Should print 500\n", + "\n", + "# Deposits\n", + "account1.deposit(200)\n", + "account2.deposit(300)\n", "\n", - "print(\"Account 2 balance:\", account2.get_balance()) #This should print 500\n", - "print(\"Account 2 number:\", account2.get_account_number()) #This should print 2\n", + "# Withdrawals\n", + "account1.withdraw(150)\n", + "account2.withdraw(50)\n", "\n", - "account1.deposit(500) # We depoist 500 in the first account\n", - "account1.withdraw(200) # We withdraw 200 in the first account\n", - "print(\"Account 1 balance after transactions:\", account1.get_balance()) # This should print 1300\n", + "# Final balances\n", + "print(\"Account 1 final balance:\", account1.get_balance())\n", + "print(\"Account 2 final balance:\", account2.get_balance())\n", "\n", - "account2.withdraw(600) # We withdraw 600 in the 2nd account \n", - "print(\"Account 2 balance after transactions:\", account2.get_balance())# This should print insufficient balance, and still 500 in funds" + "# Unique account numbers\n", + "print(\"Account 1 number:\", account1.get_account_number())\n", + "print(\"Account 2 number:\", account2.get_account_number())\n" ] }, { @@ -117,12 +229,122 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "4f8848b5-05d3-4259-9e24-914537926778", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Account 1 - Balance: $1000.00, Interest Rate: 3.0%\n", + "Account 2 - Balance: $500.00, Interest Rate: 1.0%\n", + "Deposited $500.00. New balance: $1500.00\n", + "Deposited $300.00. New balance: $800.00\n", + "Withdrew $200.00. Remaining balance: $1300.00\n", + "Withdrew $100.00. Remaining balance: $700.00\n", + "\n", + "Adding interest...\n", + "Interest of $39.00 added. New balance: $1339.00\n", + "Interest of $7.00 added. New balance: $707.00\n", + "\n", + "Final Balances:\n", + "Account 1 balance: $1339.00\n", + "Account 2 balance: $707.00\n" + ] + } + ], "source": [ - "# your code goes here" + "# ------------------------------------------\n", + "# BankAccount Base Class\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " # Class attribute to track number of accounts created\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with a unique account number and optional initial balance.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# SavingsAccount Subclass\n", + "# ------------------------------------------\n", + "\n", + "class SavingsAccount(BankAccount):\n", + " def __init__(self, balance=0, interest_rate=0.01):\n", + " \"\"\"Initialize a new savings account with an interest rate.\"\"\"\n", + " super().__init__(balance) # Call the parent constructor\n", + " self.interest_rate = interest_rate\n", + "\n", + " def add_interest(self):\n", + " \"\"\"Calculate and add interest to the account balance.\"\"\"\n", + " interest = self.balance * self.interest_rate\n", + " self.balance += interest\n", + " print(f\"Interest of ${interest:.2f} added. New balance: ${self.balance:.2f}\")\n", + "\n", + " def get_interest_rate(self):\n", + " \"\"\"Return the current interest rate.\"\"\"\n", + " return self.interest_rate\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the SavingsAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two savings accounts with different interest rates\n", + "savings1 = SavingsAccount(1000, 0.03) # 3% interest\n", + "savings2 = SavingsAccount(500) # Default 1% interest\n", + "\n", + "# Display initial info\n", + "print(f\"Account {savings1.get_account_number()} - Balance: ${savings1.get_balance():.2f}, Interest Rate: {savings1.get_interest_rate()*100:.1f}%\")\n", + "print(f\"Account {savings2.get_account_number()} - Balance: ${savings2.get_balance():.2f}, Interest Rate: {savings2.get_interest_rate()*100:.1f}%\")\n", + "\n", + "# Perform transactions\n", + "savings1.deposit(500)\n", + "savings2.deposit(300)\n", + "savings1.withdraw(200)\n", + "savings2.withdraw(100)\n", + "\n", + "# Add interest\n", + "print(\"\\nAdding interest...\")\n", + "savings1.add_interest()\n", + "savings2.add_interest()\n", + "\n", + "# Final balances\n", + "print(\"\\nFinal Balances:\")\n", + "print(f\"Account {savings1.get_account_number()} balance: ${savings1.get_balance():.2f}\")\n", + "print(f\"Account {savings2.get_account_number()} balance: ${savings2.get_balance():.2f}\")\n" ] }, { @@ -151,12 +373,94 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "bccc7f6d-d58c-4909-9314-aaf4afc1cd30", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current balance: 126.25\n", + "Interest rate: 0.01\n" + ] + } + ], "source": [ - "# your code goes here" + "# ------------------------------------------\n", + "# BankAccount Base Class\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + "\n", + " def withdraw(self, amount):\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + "\n", + " def get_balance(self):\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# SavingsAccount Subclass\n", + "# ------------------------------------------\n", + "\n", + "class SavingsAccount(BankAccount):\n", + " def __init__(self, balance=0, interest_rate=0.01):\n", + " \"\"\"Initialize a savings account with an optional interest rate.\"\"\"\n", + " super().__init__(balance)\n", + " self.interest_rate = interest_rate\n", + "\n", + " def add_interest(self):\n", + " \"\"\"Add interest to the current balance.\"\"\"\n", + " interest = self.balance * self.interest_rate\n", + " self.balance += interest\n", + "\n", + " def get_interest_rate(self):\n", + " return self.interest_rate\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Example Test (Based on Your Scenario)\n", + "# ------------------------------------------\n", + "\n", + "# 1. Create SavingsAccount with $100 and 2% interest rate\n", + "savings = SavingsAccount(100, 0.02)\n", + "\n", + "# 2. Deposit $50\n", + "savings.deposit(50)\n", + "\n", + "# 3. Withdraw $25\n", + "savings.withdraw(25)\n", + "\n", + "# 4. Temporarily change rate to default (0.01) and add interest\n", + "savings.interest_rate = 0.01\n", + "savings.add_interest()\n", + "\n", + "# 5. Print results\n", + "print(\"Current balance:\", savings.get_balance())\n", + "print(\"Interest rate:\", savings.get_interest_rate())\n" ] }, { @@ -189,12 +493,156 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "3c883c6e-3cb8-4043-92d3-12409668a28e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deposited $200.00. New balance: $700.00\n", + "Withdrew $100.00. Remaining balance: $600.00\n", + "Deposited $50.00. New balance: $650.00\n", + "Withdrew $300.00. Remaining balance: $700.00\n", + "Deposited $400.00. New balance: $1100.00\n", + "Withdrew $200.00. Remaining balance: $900.00\n", + "\n", + "Transaction Summary:\n", + "Account 1 - Balance: $650.00, Transactions: 3\n", + "Account 2 - Balance: $900.00, Transactions: 3\n", + "\n", + "Deducting Fees...\n", + "Deducted $3.00 in transaction fees. New balance: $647.00\n", + "Deducted $6.00 in transaction fees. New balance: $894.00\n", + "\n", + "Final Balances After Fees:\n", + "Account 1 balance: $647.00\n", + "Account 2 balance: $894.00\n" + ] + } + ], "source": [ - "# your code goes here" + "# ------------------------------------------\n", + "# Base Class: BankAccount\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with unique account number.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + " print(f\"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}\")\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + " print(f\"Withdrew ${amount:.2f}. Remaining balance: ${self.balance:.2f}\")\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the unique account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Subclass: CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "class CheckingAccount(BankAccount):\n", + " def __init__(self, balance=0, transaction_fee=1):\n", + " \"\"\"Initialize a checking account with transaction fee.\"\"\"\n", + " super().__init__(balance)\n", + " self.transaction_fee = transaction_fee\n", + " self.transaction_count = 0\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Deposit money and increase transaction count.\"\"\"\n", + " super().deposit(amount)\n", + " if amount > 0:\n", + " self.transaction_count += 1\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Withdraw money and increase transaction count.\"\"\"\n", + " if amount > 0 and amount <= self.balance:\n", + " super().withdraw(amount)\n", + " self.transaction_count += 1\n", + " else:\n", + " super().withdraw(amount) # Let parent handle errors\n", + "\n", + " def deduct_fees(self):\n", + " \"\"\"Deduct transaction fees based on the number of transactions.\"\"\"\n", + " total_fees = self.transaction_count * self.transaction_fee\n", + " if total_fees == 0:\n", + " print(\"No transactions this month. No fees deducted.\")\n", + " return\n", + " if total_fees > self.balance:\n", + " print(\"Insufficient funds to deduct transaction fees.\")\n", + " return\n", + " self.balance -= total_fees\n", + " print(f\"Deducted ${total_fees:.2f} in transaction fees. New balance: ${self.balance:.2f}\")\n", + " self.transaction_count = 0 # Reset count after deduction\n", + "\n", + " def reset_transactions(self):\n", + " \"\"\"Reset transaction count to 0.\"\"\"\n", + " self.transaction_count = 0\n", + " print(\"Transaction count has been reset to 0.\")\n", + "\n", + " def get_transaction_count(self):\n", + " \"\"\"Return the current transaction count.\"\"\"\n", + " return self.transaction_count\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Testing the CheckingAccount class\n", + "# ------------------------------------------\n", + "\n", + "# Create two checking accounts\n", + "checking1 = CheckingAccount(500)\n", + "checking2 = CheckingAccount(1000, transaction_fee=2)\n", + "\n", + "# Perform deposits and withdrawals\n", + "checking1.deposit(200)\n", + "checking1.withdraw(100)\n", + "checking1.deposit(50)\n", + "\n", + "checking2.withdraw(300)\n", + "checking2.deposit(400)\n", + "checking2.withdraw(200)\n", + "\n", + "# Check balances and transaction counts\n", + "print(\"\\nTransaction Summary:\")\n", + "print(f\"Account {checking1.get_account_number()} - Balance: ${checking1.get_balance():.2f}, Transactions: {checking1.get_transaction_count()}\")\n", + "print(f\"Account {checking2.get_account_number()} - Balance: ${checking2.get_balance():.2f}, Transactions: {checking2.get_transaction_count()}\")\n", + "\n", + "# Deduct fees for both accounts\n", + "print(\"\\nDeducting Fees...\")\n", + "checking1.deduct_fees()\n", + "checking2.deduct_fees()\n", + "\n", + "# Final balances\n", + "print(\"\\nFinal Balances After Fees:\")\n", + "print(f\"Account {checking1.get_account_number()} balance: ${checking1.get_balance():.2f}\")\n", + "print(f\"Account {checking2.get_account_number()} balance: ${checking2.get_balance():.2f}\")\n" ] }, { @@ -234,13 +682,153 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "faa5b148-c11b-4be0-b810-de8a7da81451", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Transaction fees of 4$ have been deducted from your account balance.\n", + "\n", + "Current balance: 546\n", + "Transaction count: 0\n", + "Transaction fees of 4$ have been deducted from your account balance.\n", + "\n", + "Current balance: 667\n", + "Transaction count: 0\n" + ] + } + ], "source": [ - "# your code goes here" + "# ------------------------------------------\n", + "# Base Class: BankAccount\n", + "# ------------------------------------------\n", + "\n", + "class BankAccount:\n", + " account_count = 0\n", + "\n", + " def __init__(self, balance=0):\n", + " \"\"\"Initialize a new bank account with unique account number.\"\"\"\n", + " BankAccount.account_count += 1\n", + " self.account_number = BankAccount.account_count\n", + " self.balance = balance\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Add the specified amount to the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Deposit amount must be positive.\")\n", + " return\n", + " self.balance += amount\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Subtract the specified amount from the account balance.\"\"\"\n", + " if amount <= 0:\n", + " print(\"Withdrawal amount must be positive.\")\n", + " return\n", + " if amount > self.balance:\n", + " print(\"Insufficient funds.\")\n", + " return\n", + " self.balance -= amount\n", + "\n", + " def get_balance(self):\n", + " \"\"\"Return the current balance of the account.\"\"\"\n", + " return self.balance\n", + "\n", + " def get_account_number(self):\n", + " \"\"\"Return the unique account number.\"\"\"\n", + " return self.account_number\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Subclass: CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "class CheckingAccount(BankAccount):\n", + " def __init__(self, balance=0, transaction_fee=1):\n", + " \"\"\"Initialize a checking account with transaction fee.\"\"\"\n", + " super().__init__(balance)\n", + " self.transaction_fee = transaction_fee\n", + " self.transaction_count = 0\n", + "\n", + " def deposit(self, amount):\n", + " \"\"\"Deposit money and increase transaction count.\"\"\"\n", + " super().deposit(amount)\n", + " if amount > 0:\n", + " self.transaction_count += 1\n", + "\n", + " def withdraw(self, amount):\n", + " \"\"\"Withdraw money and increase transaction count.\"\"\"\n", + " if amount > 0 and amount <= self.balance:\n", + " super().withdraw(amount)\n", + " self.transaction_count += 1\n", + " else:\n", + " super().withdraw(amount)\n", + "\n", + " def deduct_fees(self):\n", + " \"\"\"Deduct transaction fees based on transaction count.\"\"\"\n", + " total_fees = self.transaction_count * self.transaction_fee\n", + " if total_fees == 0:\n", + " print(\"No transactions to deduct fees for.\")\n", + " return\n", + " if total_fees > self.balance:\n", + " print(\"Insufficient funds to deduct transaction fees.\")\n", + " return\n", + " self.balance -= total_fees\n", + " print(f\"Transaction fees of {total_fees}$ have been deducted from your account balance.\")\n", + " self.transaction_count = 0\n", + "\n", + " def reset_transactions(self):\n", + " \"\"\"Reset transaction count to 0.\"\"\"\n", + " self.transaction_count = 0\n", + "\n", + " def get_transaction_count(self):\n", + " \"\"\"Return the current transaction count.\"\"\"\n", + " return self.transaction_count\n", + "\n", + "\n", + "# ------------------------------------------\n", + "# Example Testing of CheckingAccount\n", + "# ------------------------------------------\n", + "\n", + "# Step 1: Create a new checking account with $500 balance and $2 fee\n", + "checking = CheckingAccount(500, transaction_fee=2)\n", + "\n", + "# Step 2: Deposit $100\n", + "checking.deposit(100)\n", + "\n", + "# Step 3: Withdraw $50\n", + "checking.withdraw(50)\n", + "\n", + "# Step 4: Deduct fees\n", + "checking.deduct_fees()\n", + "\n", + "# Step 5: Print current balance and transaction count\n", + "print(\"\\nCurrent balance:\", int(checking.get_balance()))\n", + "print(\"Transaction count:\", checking.get_transaction_count())\n", + "\n", + "# Step 6: Deposit $200\n", + "checking.deposit(200)\n", + "\n", + "# Step 7: Withdraw $75\n", + "checking.withdraw(75)\n", + "\n", + "# Step 8: Deduct fees again\n", + "checking.deduct_fees()\n", + "\n", + "# Step 9: Print current balance and transaction count again\n", + "print(\"\\nCurrent balance:\", int(checking.get_balance()))\n", + "print(\"Transaction count:\", checking.get_transaction_count())\n" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ba14df9-c308-4690-8eb6-314bd56e8467", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -259,7 +847,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.13.6" } }, "nbformat": 4,