Repository navigation
Expand file tree
/
Copy pathMain.py
More file actions
277 lines (221 loc) · 9.52 KB
/
Copy pathMain.py
File metadata and controls
277 lines (221 loc) · 9.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
class BankAccount:
"""Base bank account used by checking and savings accounts."""
def __init__(self, account_number, holder_name, account_type, balance=0.0):
self.account_number = account_number
self.holder_name = holder_name
self.account_type = account_type
self.balance = balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("Deposit amount must be greater than zero.")
self.balance += amount
return self.balance
def withdraw(self, amount):
if amount <= 0:
raise ValueError("Withdrawal amount must be greater than zero.")
if amount > self.balance:
raise ValueError("Insufficient funds.")
self.balance -= amount
return self.balance
def get_balance(self):
return self.balance
def __str__(self):
return (
f"{self.account_type} Account: {self.account_number}\n"
f"Holder: {self.holder_name}\n"
f"Balance: ${self.balance:.2f}"
)
class CheckingAccount(BankAccount):
"""Checking account with a small overdraft allowance."""
def __init__(self, account_number, holder_name, balance=0.0):
super().__init__(account_number, holder_name, "Checking", balance)
self.overdraft_limit = 100.0
def withdraw(self, amount):
if amount <= 0:
raise ValueError("Withdrawal amount must be greater than zero.")
if amount > self.balance + self.overdraft_limit:
raise ValueError("Withdrawal exceeds checking limit.")
self.balance -= amount
return self.balance
class SavingsAccount(BankAccount):
"""Savings account with interest support."""
def __init__(self, account_number, holder_name, balance=0.0, interest_rate=0.01):
super().__init__(account_number, holder_name, "Savings", balance)
self.interest_rate = interest_rate
def apply_interest(self):
self.balance += self.balance * self.interest_rate
return self.balance
class Customer:
"""Represents a customer with one or more bank accounts."""
def __init__(self, customer_id, name):
self.customer_id = customer_id
self.name = name
self.accounts = {}
def add_account(self, account):
self.accounts[account.account_number] = account
def get_account(self, account_number):
return self.accounts.get(account_number)
class Bank:
"""Bank service layer that manages customers, accounts, and transfers."""
def __init__(self, name):
self.name = name
self.customers = {}
self.accounts = {}
self._next_customer_id = 1
self._next_account_number = 10001
def create_customer(self, name):
customer_id = f"CUST-{self._next_customer_id}"
self._next_customer_id += 1
customer = Customer(customer_id, name)
self.customers[customer_id] = customer
return customer
def create_checking_account(self, customer_id, initial_deposit=0.0):
customer = self.customers.get(customer_id)
if customer is None:
raise ValueError("Customer not found.")
account_number = f"CHK-{self._next_account_number}"
self._next_account_number += 1
account = CheckingAccount(account_number, customer.name, initial_deposit)
customer.add_account(account)
self.accounts[account_number] = account
return account
def create_savings_account(self, customer_id, initial_deposit=0.0):
customer = self.customers.get(customer_id)
if customer is None:
raise ValueError("Customer not found.")
account_number = f"SAV-{self._next_account_number}"
self._next_account_number += 1
account = SavingsAccount(account_number, customer.name, initial_deposit)
customer.add_account(account)
self.accounts[account_number] = account
return account
def find_account(self, account_number):
return self.accounts.get(account_number)
def deposit(self, account_number, amount):
account = self.find_account(account_number)
if account is None:
raise ValueError("Account not found.")
return account.deposit(amount)
def withdraw(self, account_number, amount):
account = self.find_account(account_number)
if account is None:
raise ValueError("Account not found.")
return account.withdraw(amount)
def transfer(self, from_account_number, to_account_number, amount):
from_account = self.find_account(from_account_number)
to_account = self.find_account(to_account_number)
if from_account is None or to_account is None:
raise ValueError("Account number not found.")
if from_account.balance < amount:
raise ValueError("Insufficient funds for transfer.")
from_account.withdraw(amount)
to_account.deposit(amount)
return True
def apply_savings_interest(self):
for account in self.accounts.values():
if isinstance(account, SavingsAccount):
account.apply_interest()
def list_accounts(self):
return list(self.accounts.values())
class BankConsoleApp:
"""Console interface for the banking application."""
def __init__(self, bank_name="Witherspoon Bank"):
self.bank = Bank(bank_name)
self._setup_demo_data()
def _setup_demo_data(self):
customer = self.bank.create_customer("Jane Carter")
self.bank.create_checking_account(customer.customer_id, 500.0)
self.bank.create_savings_account(customer.customer_id, 1500.0)
def display_menu(self):
print("\n===== WITHERSPOON BANK =====")
print("1. Create customer")
print("2. Open checking account")
print("3. Open savings account")
print("4. Deposit")
print("5. Withdraw")
print("6. Transfer")
print("7. Check balance")
print("8. Apply savings interest")
print("9. List accounts")
print("10. Exit")
def create_customer(self):
name = input("Enter customer name: ").strip()
customer = self.bank.create_customer(name)
print(f"Customer created: {customer.customer_id} ({customer.name})")
def open_checking(self):
customer_id = input("Enter customer ID: ").strip()
deposit = float(input("Enter initial deposit: ") or 0)
account = self.bank.create_checking_account(customer_id, deposit)
print(f"Checking account created: {account.account_number}")
def open_savings(self):
customer_id = input("Enter customer ID: ").strip()
deposit = float(input("Enter initial deposit: ") or 0)
account = self.bank.create_savings_account(customer_id, deposit)
print(f"Savings account created: {account.account_number}")
def deposit(self):
account_number = input("Enter account number: ").strip()
amount = float(input("Enter deposit amount: ").strip())
balance = self.bank.deposit(account_number, amount)
print(f"Deposit successful. New balance: ${balance:.2f}")
def withdraw(self):
account_number = input("Enter account number: ").strip()
amount = float(input("Enter withdrawal amount: ").strip())
balance = self.bank.withdraw(account_number, amount)
print(f"Withdrawal successful. New balance: ${balance:.2f}")
def transfer(self):
from_account = input("Enter source account number: ").strip()
to_account = input("Enter destination account number: ").strip()
amount = float(input("Enter transfer amount: ").strip())
self.bank.transfer(from_account, to_account, amount)
print(f"Transfer of ${amount:.2f} successful.")
def check_balance(self):
account_number = input("Enter account number: ").strip()
account = self.bank.find_account(account_number)
if account is None:
print("Account not found.")
else:
print(f"Account balance: ${account.get_balance():.2f}")
def apply_savings_interest(self):
self.bank.apply_savings_interest()
print("Savings interest applied.")
def list_accounts(self):
accounts = self.bank.list_accounts()
if not accounts:
print("No accounts found.")
else:
for account in accounts:
print(account)
print("-" * 40)
def run(self):
while True:
self.display_menu()
choice = input("Choose an option: ").strip()
try:
if choice == "1":
self.create_customer()
elif choice == "2":
self.open_checking()
elif choice == "3":
self.open_savings()
elif choice == "4":
self.deposit()
elif choice == "5":
self.withdraw()
elif choice == "6":
self.transfer()
elif choice == "7":
self.check_balance()
elif choice == "8":
self.apply_savings_interest()
elif choice == "9":
self.list_accounts()
elif choice == "10":
print("Thank you for using Witherspoon Bank.")
break
else:
print("Invalid option. Please select a valid menu choice.")
except ValueError as error:
print(f"Error: {error}")
if __name__ == "__main__":
app = BankConsoleApp()
app.run()