· 4 years ago · Aug 04, 2021, 10:48 AM
1from random import randint
2import sqlite3
3
4
5class BankAccount:
6 def __init__(self, uid=None, card=None, pin=None, balance=0):
7 self.id = uid
8 self.card = card or self.generate_card_number()
9 self.pin = pin or self.generate_pin()
10 self.balance = balance
11
12 def generate_card_number(self):
13 iin = '400000'
14 can = ''.join(str(randint(0, 9)) for _ in range(9))
15 checksum = self.luhn(iin + can)
16 return iin + can + checksum
17
18 @staticmethod
19 def luhn(card):
20 nums = [int(i) for i in card[1::2]]
21 for i in card[::2]:
22 n = int(i) * 2
23 if n > 9:
24 n -= 9
25 nums.append(n)
26 return str((10 - sum(nums) % 10) % 10)
27
28 @staticmethod
29 def generate_pin():
30 return ''.join(str(randint(0, 9)) for _ in range(4))
31
32
33class ABS:
34 main_menu = ('1. Create an account', '2. Log into account', '0. Exit')
35 user_menu = ('1. Balance', '2. Add income', '3. Do transfer', '4. Close account', '5. Log out', '0. Exit')
36
37 def __init__(self, database):
38 self.connection = sqlite3.connect(database)
39 self.cursor = self.connection.cursor()
40 self.cursor.execute('''
41 CREATE TABLE IF NOT EXISTS card
42 (id INTEGER PRIMARY KEY,
43 number TEXT NOT NULL UNIQUE,
44 pin TEXT NOT NULL,
45 balance INTEGER DEFAULT 0);
46 ''')
47 self.connection.commit()
48
49 def main(self):
50 while True:
51 print(*ABS.main_menu, sep='\n')
52
53 user_input = int(input())
54 if user_input == 1:
55 self.create_account()
56 elif user_input == 2:
57 logged_user = self.login()
58 if logged_user:
59 print('\nYou have successfully logged in!\n')
60 self.account_actions(logged_user)
61 else:
62 print('\nWrong card number or PIN!\n')
63 elif user_input == 0:
64 self.connection.close()
65 print('\nBye!')
66 exit()
67 else:
68 print('Wrong input\n')
69 continue
70
71 def create_account(self):
72 new = BankAccount()
73 self.cursor.execute('INSERT INTO card (number, pin, balance) VALUES (?, ?, 0);', (new.card, new.pin))
74 self.connection.commit()
75 print('\nYour card has been created',
76 'Your card number:', new.card,
77 'Your card PIN:', new.pin,
78 sep='\n')
79 print()
80
81 def login(self):
82 login_card = input('Enter your card number:\n')
83 login_pin = input('Enter your PIN:\n')
84 self.cursor.execute(f'SELECT * FROM card WHERE number = "{login_card}" AND pin = "{login_pin}";')
85 return self.cursor.fetchone()
86
87 def account_actions(self, logged):
88 user = BankAccount(*logged) # user.id, user.card, user.pin, user.balance
89
90 while True:
91 print(*ABS.user_menu, sep='\n')
92
93 user_input = int(input())
94 if user_input == 1:
95 print(f'\nBalance: {user.balance}\n')
96 elif user_input == 2:
97 print('Enter income:')
98 user.balance += int(input())
99 self.cursor.execute('UPDATE card SET balance = ? WHERE id = ?;', (user.balance, user.id))
100 self.connection.commit()
101 print('Income was added!\n')
102 elif user_input == 3:
103 print(self.do_transfer(user) + '\n')
104 elif user_input == 4:
105 self.cursor.execute('DELETE FROM card WHERE id = ?;', (user.id))
106 self.connection.commit()
107 print('\nThe account has been closed!\n')
108 break
109 elif user_input == 5:
110 print('\nYou have successfully logged out!\n')
111 break
112 elif user_input == 0:
113 self.connection.close()
114 print('\nBye!')
115 exit()
116 else:
117 print('Wrong input\n')
118 continue
119
120 def do_transfer(self, user):
121 print('\nTransfer', 'Enter card number:', sep='\n')
122 receiver_card = input()
123 if receiver_card == user.card:
124 return "You can't transfer money to the same account!"
125
126 if not self.check_luhn(receiver_card):
127 return "Probably you made a mistake in the card number. Please try again!\n"
128
129 self.cursor.execute(f'SELECT * FROM card where number="{receiver_card}"')
130 get_receiver = self.cursor.fetchone()
131 if not get_receiver:
132 return "Such a card does not exist."
133
134 print("Enter how much money you want to transfer:")
135 money_to_transfer = int(input())
136 if money_to_transfer > user.balance:
137 return "Not enough money!"
138
139 receiver = BankAccount(*get_receiver)
140 user.balance -= money_to_transfer
141 receiver.balance += money_to_transfer
142
143 self.cursor.execute('UPDATE card SET balance = ? WHERE id = ?;', (user.balance, user.id))
144 self.cursor.execute('UPDATE card SET balance = ? WHERE id = ?;', (receiver.balance, receiver.id))
145 self.connection.commit()
146 return 'Success!'
147
148 @staticmethod
149 def check_luhn(card) -> bool:
150 return card[-1] == BankAccount.luhn(card[:-1])
151
152
153my_bank = ABS('card.s3db')
154my_bank.main()
155