· 8 years ago · Apr 11, 2018, 01:18 AM
1# By: Michael Sheinman
2# Date: 2018-03-28 13:31:37.934330
3# File Name: ATM project
4# Description: Making a bank project
5import sys
6import os
7import time
8import re
9from datetime import datetime
10from decimal import Decimal
11
12
13# Function to change the user file. Complete
14def replaceFile(account, file):
15 os.remove(account + '.txt')
16 userFile = open(account + '.txt', 'w')
17 # Rewrite here
18 for line in range(len(file)):
19 userFile.write(str(file[line]) + '\n')
20 userFile.close()
21 return file
22
23
24# Recursion to make sure the pin numbers are the same
25def equal(p):
26 # If there is only one number left, we know all were equal
27 if len(p) == 1:
28 return True
29 else:
30 if p[0] == p[1]:
31 # If they are equal, we have to check the next ones
32 return equal(p[1:])
33 else:
34 return False
35
36# Handles special cases such as 20 & 8 transactions
37def is_special(account, file):
38 myFile = open(account + 'history.txt')
39 allTransactions = myFile.readlines()
40 if len(allTransactions) % 8 == 0:
41 now = datetime.now()
42 current_time = "%s:%s %s / %s / %s" % (
43 now.hour, now.minute, now.month, now.day, now.year)
44 history_file = open(account + 'history.txt', 'a')
45 history_file.write(current_time + '\n')
46 history_file.write(str(-4.00) + '\n')
47 if Decimal(file[4]) >= 4:
48 file.pop(4)
49 file.insert(4, str(Decimal(file[4]) -4))
50 elif 0 < Decimal(file[4]) < 4:
51 difference = 4 - Decimal(file[4])
52 file.pop(4)
53 file.pop(4)
54 file.insert(4, str(0))
55 file.insert(5, str(Decimal(file[5]) -difference))
56 file = overdraftfunction(difference, file[2], current_time, file)
57 else:
58 to_be_used = file[5]
59 file.pop(5)
60 file.insert(5, Decimal(to_be_used) - 4)
61 elif len(allTransactions) % 40 == 0:
62 history_file = open(account + 'history.txt', 'r')
63 myhistory = history_file.readlines()
64 total = 0
65 print("You have reached 20 transactions. Here they are:")
66 for a in range(len(myhistory)):
67 if not a % 2 == 0:
68 total += Decimal(myhistory[a].split('\n')[0])
69 sys.stdout.write(myhistory[a])
70 if total > 0:
71 print("\nYour net income is: %s" % total)
72 else:
73 print("\nYour net lose is: %s" % total)
74
75 pass
76
77# Account details.
78def view(file):
79 print(file)
80 print("Account details:")
81 print("_______________________")
82 print("Card number: %s" % file[0])
83 print("Balance: %s" % file[4])
84 print("Overdraft: %s" % file[5])
85 time.sleep(2)
86
87
88# Printing transaction history
89def print_transaction(account):
90 transactions = open(account + 'history.txt', 'r')
91 allTransactions = transactions.readlines()
92 transactions.close()
93 if len(allTransactions) == 0:
94 print("No transactions yet")
95 else:
96 print("Transactions:")
97 for tran in range(len(allTransactions)):
98 sys.stdout.write(allTransactions[tran])
99
100
101# Replacing the pin
102def pin(current, account, file):
103 while True:
104 pin = input("Enter the new pin(must be 4 digits): ")
105 if not re.search(r'^\d{4}$', pin):
106 continue
107 if equal(pin):
108 continue
109 if pin == current:
110 continue
111 if pins_check(pin):
112 break
113 else:
114 print("This pin already exists")
115 file.pop(1)
116 file.insert(1, str(pin))
117 print("Changing pin...")
118 time.sleep(2)
119 return replaceFile(account, file)
120
121
122def withdraw(money, overdraft, file, account, gone_overdraft):
123 if overdraft == 'True':
124 gone_overdraft = Decimal(gone_overdraft)
125 allOptions = {'1': 20, '2': 40, '3': 60, '4': 80, '5': 100, '6': 120, '7': 'other'}
126 while True:
127 option = input("Pick a withdraw option: 1) $20 2) $40 3) $60 4) $80 5) $100 6) $120 7) Other: ")
128 if option not in allOptions.keys():
129 continue
130 break
131 withdrawen = allOptions[option]
132 if withdrawen == 'other':
133 while True:
134 withdrawen = input("Enter an amount: ")
135 try:
136 if Decimal(withdrawen) > 0:
137 break
138 except Exception:
139 continue
140 withdrawen = Decimal(withdrawen)
141 if money > withdrawen or overdraft == 'True' and money + gone_overdraft > withdrawen:
142 sys.stdout.write("dispensing money")
143 name = ".....\n"
144 for char in name:
145 sys.stdout.write(char)
146 sys.stdout.flush()
147 time.sleep(.5)
148 if money > withdrawen:
149 file.pop(4)
150 file.insert(4, str(money - withdrawen))
151 else:
152 difference = withdrawen - money
153 gone_overdraft -= difference
154 now = datetime.now()
155 current_time = "%s:%s %s / %s / %s" % (
156 now.hour, now.minute, now.month, now.day, now.year)
157 file = overdraftfunction(gone_overdraft, file[2], current_time, file)
158 money = 0
159 file.pop(4)
160 file.pop(4)
161 file.insert(4, money)
162 file.insert(5, gone_overdraft)
163
164 # Rewrite file point
165 now = datetime.now()
166 current_time = "%s:%s %s / %s / %s\n" % (now.hour, now.minute, now.month, now.day, now.year)
167 history_file = open(account + 'history.txt', 'a')
168 history_file.write(current_time + '\n')
169 history_file.write(str(-withdrawen) + '\n')
170 history_file.close()
171 is_special(account, file)
172 return replaceFile(account, file)
173 else:
174 print("No enough money")
175 return file
176
177
178def deposit(file, userMoney, account):
179 allDeposits = []
180 while True:
181 while True:
182 money = input("Enter money to Deposit(done to quit): ".lower())
183 try:
184 if Decimal(money) < 0:
185 continue
186 break
187 except Exception:
188 # Value error means a string was entered
189 if money == "done":
190 break
191 else:
192 continue
193
194 if money != 'done':
195 allDeposits.append(money)
196 time.sleep(2)
197 print("Deposit accepted")
198 else:
199 break
200 total = 0
201 for i in range(len(allDeposits)):
202 total += Decimal(allDeposits[i])
203 if file[3] == 'True' and Decimal(file[5]) < 500:
204 if total + Decimal(file[5]) <= 500:
205 newOverDraft = Decimal(file[5]) + total
206 else:
207 subtract = total - Decimal(file[5])
208 newOverDraft = 500
209 another_varaible_to_store_total = total - subtract
210 userMoney += another_varaible_to_store_total
211 else:
212 userMoney += total
213 if file[3] == 'True':
214 newOverDraft = 500
215 else:
216 newOverDraft = "Not in action"
217 file.pop(4)
218 file.insert(4, str(userMoney))
219 file.pop(5)
220 file.insert(5, str(newOverDraft))
221 now = datetime.now()
222 current_time = "%s:%s %s / %s / %s\n" % (now.hour, now.minute, now.month, now.day, now.year)
223 history_file = open(account + 'history.txt', 'a')
224 history_file.write(current_time)
225 history_file.write(str(total) + '\n')
226 history_file.close()
227 is_special(account, file)
228 return replaceFile(account, file)
229
230
231# Function that will notify the user when they go beyond overdraft
232def overdraftfunction(howfar, email, time, file):
233 import smtplib
234 from email.mime.multipart import MIMEMultipart
235 from email.mime.text import MIMEText
236
237 # variables for to and from
238 the_overdraft = str(Decimal(file[5]) - Decimal(howfar))
239 charge = str(Decimal(the_overdraft) * Decimal(0.25))
240 howfar -= Decimal(charge)
241 myadd = "casinogames99@gmail.com"
242 youradd = email
243
244 msg = MIMEMultipart()
245 msg['From'] = myadd
246 msg['To'] = youradd
247 msg['Subject'] = "ATM project"
248
249 # body of text
250 body = "Dir Sir/Madam, Your recent transaction at (%s) shows that you have gone into your overdraft. " \
251 "You overdraft protection is $%s. " \
252 "You have gone $%s into your overdraft, leaving you with a balance of $%s in your overdraft. " \
253 "This is including a small service charge of $%s (25 percent of $%s) has been added to your account. Thank you." % \
254 (time, file[5], the_overdraft, howfar, charge, the_overdraft)
255 msg.attach(MIMEText(body, "plain"))
256
257 server = smtplib.SMTP("smtp.gmail.com", 587)
258 server.starttls()
259 server.login(myadd, 'mikejack')
260 text = msg.as_string()
261 server.sendmail(myadd, youradd, text)
262 server.quit()
263 to_be_used = file[5]
264 file.pop(5)
265 file.insert(5, str(Decimal(to_be_used) - Decimal(charge)))
266 return replaceFile(file[0], file)
267
268
269# Function that lets the user pay bills
270def bills(file, userMoney, account, overdraft, email, overdraftAmount):
271 if overdraft == 'True':
272 overdraftAmount = Decimal(overdraftAmount)
273 billName = input("Enter bill name: ")
274 while True:
275 accountNumber = input("Enter account number(must be 6 digits): ")
276 if re.search(r'^\d{6}$', accountNumber):
277 break
278 while True:
279 amount = input("Enter amount to be paid: ")
280 try:
281 if Decimal(amount) > 0:
282 break
283 else:
284 continue
285 except Exception:
286 # Exception indicates decimal error.
287 continue
288 amount = Decimal(amount)
289 # The if statements checks where the money should go (overdraft/balance)
290 if userMoney > amount or overdraft == 'True' and userMoney + overdraftAmount > amount:
291 if userMoney > amount:
292 userMoney -= amount
293 file.pop(4)
294 file.insert(4, userMoney)
295 else:
296 userMoney = 0
297 goneIntoOverdraft = overdraftAmount - (amount - userMoney)
298 now = datetime.now()
299 current_time = "%s:%s %s / %s / %s" % (
300 now.hour, now.minute, now.month, now.day, now.year)
301 file = overdraftfunction(goneIntoOverdraft, email, current_time, file)
302 file.pop(4)
303 file.pop(4)
304 file.insert(4, userMoney)
305 file.insert(5, goneIntoOverdraft)
306 now = datetime.now()
307 current_time = "%s:%s %s / %s / %s\n" % (now.hour, now.minute, now.month, now.day, now.year)
308 history_file = open(account + 'history.txt', 'a')
309 history_file.write(current_time + '\n')
310 history_file.write(str(-amount) + '\n')
311 history_file.close()
312 is_special(account, file)
313 return replaceFile(account, file)
314 else:
315 print("Not enough money")
316 return file
317
318
319def menu(file):
320 while True:
321 print("Welcome to the menu. You may pick one of the following options:"
322 "\n1. View your account details"
323 "\n2. Change PIN"
324 "\n3. Withdraw money"
325 "\n4. Deposit money"
326 "\n5. Pay bills"
327 "\n6. View History"
328 "\n7. Quit")
329 navigation = input("Pick option: ")
330 if navigation == '1':
331 view(file)
332 elif navigation == '2':
333 file = pin(file[1], file[0], file)
334 elif navigation == '3':
335 file = withdraw(Decimal(file[4]), file[3], file, file[0], file[5])
336 elif navigation == '4':
337 file = deposit(file, Decimal(file[4]), file[0])
338 elif navigation == '5':
339 file = bills(file, Decimal(file[4]), file[0], file[3], file[2], file[5])
340 elif navigation == '6':
341 print_transaction(file[0])
342 elif navigation == '7':
343 print_transaction(file[0])
344 return
345
346
347def pins_check(pin_input):
348 if os.path.exists('pins.txt'):
349 pins = open('pins.txt', 'r')
350 myFile = pins.readlines()
351 pins.close()
352 for pin in range(len(myFile)):
353 new = myFile[pin].replace('\n', '')
354 myFile.pop(pin)
355 myFile.insert(pin, new)
356 if pin_input in myFile:
357 return False
358 else:
359 myPin = open('pins.txt', 'a')
360 myPin.write(pin_input + '\n')
361 myPin.close()
362 return True
363
364 else:
365 pins = open('pins.txt', 'w')
366 pins.write(pin_input + '\n')
367 pins.close()
368 return True
369
370def signup():
371 # Card input
372 while True:
373 card = input("Enter the card number(must be 4 digits): ")
374 if not re.search(r'^\d{4}$', card):
375 continue
376 if equal(card):
377 continue
378 break
379 # PIN input
380 while True:
381 pin = input("Enter the pin number(must be 4 digits): ")
382 if not re.search(r'^\d{4}$', pin):
383 continue
384 if equal(pin):
385 continue
386 if pins_check(pin):
387 break
388 else:
389 print("The pin already exists")
390 # Gmail input
391 while True:
392 email = input("Enter email(gmail only): ")
393 if '@gmail.com' in email:
394 break
395 # Overdraft protection input
396 while True:
397 print("Would you like to sign up for overdraft protection?")
398 prompt_overdraft = input("y for yes, n for no, i for 'what is overdraft?' ")
399 if prompt_overdraft == 'y' or prompt_overdraft == 'yes':
400 overdraft = 'True'
401 break
402 elif prompt_overdraft == 'n' or prompt_overdraft == 'no':
403 overdraft = 'False'
404 break
405 elif prompt_overdraft == 'i':
406 print("Overdraft allows you to go beyond 0 to maximum of $500\n"
407 "Each time you go beyond the overdraft, you will be charged with 25% of your overdraft\n"
408 "An email will be sent to you each time you go beyond the overdraft. ")
409 userFile = open(card + '.txt', 'w')
410 userFile.write(card + '\n' + pin + '\n' + email + '\n' + overdraft + '\n' + '0' + '\n')
411 if overdraft == 'True':
412 userFile.write('500')
413 else:
414 userFile.write('Not in action')
415 userFile.close()
416 user_history_file = open(card + 'history.txt', 'w')
417 user_history_file.close()
418 sys.stdout.write("redirecting to login")
419 name = ".....\n"
420 for char in name:
421 sys.stdout.write(char)
422 sys.stdout.flush()
423 time.sleep(.6)
424 login()
425
426
427def login():
428 while True:
429 card_login = input("Enter your card number: ")
430 if not os.path.exists(card_login + '.txt'):
431 continue
432 break
433 user_file = open(card_login + '.txt')
434 userLines = user_file.readlines()
435 # The process of removing the line spacing
436 for line in range(len(userLines)):
437 new = userLines[line].replace('\n', '')
438 userLines.pop(line)
439 userLines.insert(line, new)
440 user_file.close()
441
442 actual_pin = userLines[1]
443 while True:
444 pin_login = input("Enter your pin: ")
445 if not pin_login == actual_pin:
446 continue
447 break
448
449 menu(userLines)
450 return
451
452
453while True:
454 enter = input("Would you like to sign in(I) or sign up(U): ".lower())
455 if enter == 'i':
456 login()
457 break
458 elif enter == 'u':
459 signup()
460 break