-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbank.py
398 lines (259 loc) · 10.4 KB
/
bank.py
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# This is a command-line banking transactions application
import stdiomask
from sys import exit
""" DECLARATION & INITIALIZATION OF VARIABLES
"""
prompt1, prompt2 = 0, 0 # dummy variable initialization
insecure_key = False # variable that checks for password strength
user_balance = 5000.00
beneficiary_balance, deposit, withdraw = 0.00, 0.00, 0.00
user_email, user_password = "", ""
user_details = {}
user_input, my_input = 0, 0
# Default user details
user_details["Email address"] = "[email protected]"
user_details["Password"] = "Sammyjay96"
user_details["Balance"] = user_balance
# Beneficiary email addresses
beneficiary_email = [
]
exit_kinds = ("exit", "Exit", "EXIT", "cancel", "Cancel", "CANCEL")
""" FUNCTION DEFINITIONS
"""
# The first prompt
def my_decorator(my_func):
def exit_wrapper():
my_func()
if (user_input or user_password or user_email) in exit_kinds:
exit()
return exit_wrapper
@my_decorator #this actually decorates prompt1 below
def first_prompt():
global prompt1, user_input
print("Command-line Banking Application".upper().center(65, "*"))
print()
print("NOTE: To terminate this application abruptly, type either 'exit' or 'cancel' anytime you're requested for an input.")
print()
print("You are welcome.🤝🤝🤝", "I'm here to help you with your banking transactions.", sep = "\n")
print()
print(
"Choose an option below:",
"1: Create Account",
"2: Transactions",
sep="\n")
print()
prompt1 = input("Press 1 or 2 to choose among the above listed options: ")
# this authenticates a numeric user input only with an exception
if prompt1.isalpha():
user_input = prompt1 # only the words exit, Exit, EXIT here would activate the decorator function
else:
prompt1 = int(prompt1)
print()
# Main Program Body
def main():
if prompt1 == 1:
create_account()
elif prompt1 == 2:
transactions()
else:
invalid_input()
def child_main():
global prompt2, exit_kinds
if prompt2 == 1:
check_balance()
elif prompt2 == 2:
deposit()
elif prompt2 == 3:
withdraw()
elif prompt2 == 4:
transfer()
elif prompt2 in exit_kinds:
pass # this allows for the execution of decorator function on transactions_child()
else:
child_invalid_input()
@my_decorator #this actually decorates prompt2 below
def transactions_child():
global prompt2
print(
"Choose an option below:",
"1: Check balance",
"2: Deposit",
"3: Withdraw",
"4: Transfer",
sep="\n")
print()
prompt2 = input(
"Press 1 or 2 or 3 or 4 to choose among the above listed options: ")
print()
# this authenticates a numeric user input only
if prompt2.isalpha():
user_input = prompt2 # only the words exit, Exit, EXIT would activate the decorator function
else:
prompt2 = int(prompt2)
child_main()
def invalid_input():
print("Invalid input!", "Enter either 1 or 2 please.", sep="\n")
print()
first_prompt()
main()
def child_invalid_input():
print("Invalid input!", "Enter either 1 or 2 or 3 or 4 please.", sep="\n")
print()
transactions()
@my_decorator #this actually decorates user_email below
def user_email_prompt():
global user_email
user_email = input("Type your email adress: ").lower()
@my_decorator #this actually decorates user_input below
def masked_password_prompt():
global user_input
user_input = stdiomask.getpass(prompt="Enter your password: ", mask = "*")
print()
@my_decorator #this actually decorates user_password below
def user_password_prompt():
global user_password, insecure_key, exit_kinds
user_password = input("Enter your password: ")
# this checks for the user's password strength
if user_password not in exit_kinds:
if len(user_password) < 8 or user_password.isalpha() is True or user_password.isnumeric() is True or user_password[0].isupper() == False:
insecure_key = True
else:
insecure_key = False
# Function that creates an account for a new customer
def create_account():
global insecure_key, user_details, user_balance, user_email
user_email_prompt()
print()
# the conditional statement checks if user input email is valid in that it's length must be greater than that of "@gmail.com" and it must have
# a suffix of "@gmail.com"
# the first conditional statement below allows decorator for user_email_prompt(line 150) to work pretty well
if user_email not in exit_kinds:
while user_email.endswith("@gmail.com") is False or len(user_email) <= len("@gmail.com"):
print()
print("Invalid email address!", "Hint: use a valid gmail address.", sep="\n")
print()
user_email_prompt()
user_password_prompt()
#this prevents the acceptance of a weak password strength
while insecure_key is True:
print()
print("Enter a more secure password please.","Hint: Password must start with a capital letter, it must not be less than 8 characters, it must contain numbers.",sep="\n")
print()
user_password_prompt()
print()
# new user details is stored in a dictionary data structure
if insecure_key is False:
new_user_details = {"Email address": user_email,"Password": user_password,
"Balance": user_balance}
# this checks if the new user account details is not pre-existing
if user_details.get("Email address") != new_user_details.get("Email address") and user_details.get("Password") != new_user_details.get("Password"):
print()
print(f"Your account with a registered email address of {user_email} has been created with a bonus deposit of ${user_balance}!", "Proceed to performing your banking transactions of choice.", sep="\n")
# these make a new customer eligible for transactions immediately after
# creating an account
user_details["Email Address"] = new_user_details.get("Email address")
user_details["Password"] = new_user_details.get("Password")
print()
transactions()
else:
print()
print("Account creation failed!","The account details entered exists.",sep="\n")
print("Kindly, re-enter a different account details.")
print()
create_account()
# Function that aids banking transactions
def transactions():
global user_balance, deposit, withdraw, user_details, dummy, prompt2, user_input
masked_password_prompt()
#These conditional statements authenticates a user for transactions and permits the re-entering of password (if not recognized at first) thrice after which a new account is suggested to be created.
if user_input not in exit_kinds:
if user_input not in user_details.values():
print("Incorrect password!!!")
print()
print("Kindly, re-enter your password.")
print()
masked_password_prompt()
if user_input not in user_details.values():
print("Incorrect password!!!")
print()
print("Kindly, enter a correct password.")
print()
masked_password_prompt()
if user_input not in user_details.values():
print("Access Denied!!!", "You are an unrecognized user.", sep = "\n")
print()
print("Kindly proceed to creating a new account.")
print()
create_account()
else:
transactions_child()
else:
transactions_child()
else:
transactions_child()
def check_balance():
global user_balance
print(f"Your balance is ${user_balance}")
print()
transactions_child()
def deposit():
global user_balance
deposit = float(input("Enter your deposit amount: $"))
print(f"You've successfully saved ${str(deposit)} into your bank account.")
print()
print(f"Your total balance is now ${user_balance + deposit}")
print()
#transactions_child()
def withdraw():
global withdraw, user_balance
# this ensures that withdrawal can't be done with zero available balance
if user_balance > 0:
withdraw = float(input("Enter your withdrawal amount: $"))
# this prevents withdrawal greater than the available balance
if withdraw <= user_balance:
print()
print(f"${withdraw} successfully withdrawn!")
print()
print(f"Your total balance is now ${user_balance - withdraw}")
else:
print()
print(
"Withdrawal amount is greater than available balance!",
f"You can only withdraw an amount not greater than your available balance which is ${user_balance}",
sep="\n")
else:
print()
print("Insufficient funds!!!", "Please, deposit some money.", sep="\n")
print()
deposit()
@my_decorator #this actually decorates recipient_email below
def transfer():
global beneficiary_email, beneficiary_balance, user_balance, exit_kinds
recipient_email = input("Enter the beneficiary's email address: ")
# this grants access to transfer to only recognized beneficiaries
if recipient_email not in exit_kinds:
if recipient_email in beneficiary_email:
transfer_amount = float(input("Enter the amount to be transferred: $"))
beneficiary_balance = beneficiary_balance + transfer_amount
# this prevents the transfer of an amount greater than the available
# balance of user
if transfer_amount <= user_balance:
print()
print(
f"You have successfully transferred ${transfer_amount} to a beneficiary with an email address of {recipient_email}")
print()
print(f"Your total balance is now ${user_balance - transfer_amount}")
else:
print()
print("Insufficient funds!!!")
else:
print()
print("Beneficiary email not recognized.")
"""MAIN FUNCTION INVOCATIONS
"""
# Function calls that starts program
first_prompt()
main()