· 5 years ago · Aug 03, 2020, 07:26 AM
1# Write your code here
2import random
3import sqlite3
4
5'''
6Some remarks of mine
7
81. Too much functional decomposition. you can do it in few methods/functions
92. Some unnecessary code (DRY - Don't Repeat Yourself):
10 1. You can transform this (the one below) to this! (the one below), thus You can shorten your code
11
12 if <something>: return <something>
13 return True
14 else:
15 return False
16
17 2. or some parts like two Luhn-algorithm methods (just transform it into one!) and
18 3. reusing sqlite3.connection.commit() more times than needed
19 4. You can also fetch the data from the 'select' statement by using to lines of code
20 consider this:
21 <variable> = self.cursor.execute('<SQL statement>').fetchone()
22 instead of this:
23 <variable> = self.cursor.execute('<SQL statement>')
24 <variable> = self.cursor.fetchone()
25 this will save you much more code (and nerves ???)
26
27
28I don't make You follow these recomendations, I just want to help and point You to some mistakes I've done before too.
29Again, it's only mine point of view, you can whether take advice, or skip it - it's all about YOU
30Do everything in here at your peril
31I haven't done any changes in code, just commented it, like this
32'''
33
34
35class BankingSystem:
36
37 def __init__(self):
38 self.pin = ''
39 self.card_num = ''
40 self.conn = None
41 self.cur = None
42 self.amt_transfer = 0
43
44
45 def database(self):
46 self.conn = sqlite3.connect('card.s3db')
47 self.cur = self.conn.cursor()
48 self.cur.execute('create table if not exists card(id integer, number text, pin text, balance integer default 0)')
49 self.conn.commit()
50
51
52 def store_data(self): #
53 self.cur.execute(f'insert into card(number, pin) values({self.card_num},{self.pin})') # Remarks 1.
54 self.conn.commit() #
55
56
57 def checksum_add_luhn(self): #
58 raw_card_num = '400000' + str(random.randint(100000000, 1000000000)) #
59 raw_card_num_list_convert = list(raw_card_num) #
60 new_number_card = '' #
61 sum_digits = 0 #
62 card_n = '' #
63 for (index, digit) in enumerate(raw_card_num_list_convert): #
64 if index % 2 == 0: #
65 digit = str(int(digit) * 2) # Remarks 2.2
66 if int(digit) > 9: #
67 digit = str(int(digit) - 9) #
68 new_number_card += digit #
69 sum_digits += int(digit) #
70 last_digit = 0 #
71 while (sum_digits + last_digit) % 10 != 0: #
72 last_digit += 1 #
73 card_n = raw_card_num + str(last_digit) #
74 return card_n #
75
76
77 def generate_card_num(self): #
78 self.card_num = self.checksum_add_luhn() # Remarks 1.
79 return self.card_num #
80
81
82 def generate_pin(self): #
83 self.pin = str(random.randint(0, 9999)).zfill(4) # Remarks 1.
84 return self.pin #
85
86
87 def create_acc(self): #
88 print(f"\nYour card has been created\nYour card number:\n{self.generate_card_num()}\nYour card PIN:\n{self.generate_pin()}") # Remarks 1.
89 self.store_data() #
90
91
92 def log_in_acc(self):
93 self.ask_card_num = input("\nEnter you card number:\n")
94 self.ask_pin = input("Enter your PIN:\n")
95 login = self.cur.execute(f'select number, pin from card where number = {self.ask_card_num} and pin = {self.ask_pin}') # Remarks 2.4
96 login_ = self.cur.fetchone() #
97 if login_ is not None:
98 print("\nYou have successfully logged in!")
99 return self.log_in_success()
100 else:
101 print("Wrong card number or PIN!")
102
103
104 def log_in_success(self):
105 while True:
106 choose_option_lis = input("""\n1. Balance\n2. Add income\n3. Do transfer\n4. Close account\n5. Log out\n0. Exit\n""")
107 if choose_option_lis == '1':
108 self.fetch_balance()
109 elif choose_option_lis == '2':
110 self.add_income()
111 elif choose_option_lis == '3':
112 self.do_transfer()
113 elif choose_option_lis == '4':
114 self.close_account()
115 elif choose_option_lis == '5':
116 print("\nYou have successfully logged out!")
117 break
118 else:
119 print('Bye!') # can change this by "quit('Bye!')" (this will print the message and quit)
120 quit() #
121
122
123 def fetch_balance(self):
124 bal = self.cur.execute(f'select balance from card where number = {self.card_num} and pin = {self.pin}') # Remarks 1.
125 bal = self.cur.fetchone() # Remarks 2.4
126 print('\nBalance:', bal[0])
127
128
129 def add_income(self): # Remarks 1.
130 amt = int(input('\nEnter income:\n')) #
131 update_amt = self.cur.execute(f'update card set balance = balance + {amt} where number = {self.ask_card_num} and pin = {self.ask_pin}')
132 update_amt_ = self.conn.commit()
133 print("Income was added!")
134
135
136 # For do transfer option
137 def check_luhn(self, ask_receiver_card_num): #
138 ask_card_num_strip = ask_receiver_card_num[0:15] #
139 ask_card_num_strip_list_convert = list(ask_card_num_strip) #
140 new_number_card = '' #
141 sum_digits = 0 #
142 card_n = '' #
143 for (index, digit) in enumerate(ask_card_num_strip_list_convert): #
144 if index % 2 == 0: #
145 digit = str(int(digit) * 2) #
146 if int(digit) > 9: #
147 digit = str(int(digit) - 9) # Remarks 2.2
148 new_number_card += digit #
149 sum_digits += int(digit) #
150 last_digit = 0 #
151 while (sum_digits + last_digit) % 10 != 0: #
152 last_digit += 1 #
153 card_n = ask_card_num_strip + str(last_digit) #
154 #
155 if ask_receiver_card_num == card_n: #
156 return True #
157 else: # Remarks 2.1
158 return False #
159
160
161 def check_card_existence(self):
162 check_card_num_exist = self.cur.execute(f'select number from card where number = {self.ask_receiver_card_num}') # Remarks 1.
163 check_card_num_exist_ = self.cur.fetchone() # Remarks 2.4
164 if check_card_num_exist_ is not None: #
165 return True #
166 else: # Remarks 2.1
167 return False #
168
169
170 def amt_avail(self):
171 sender_avail_money = self.cur.execute(f'select balance from card where number = {self.ask_card_num} and pin = {self.ask_pin}') # Remarks 2.4
172 sender_avail_money = self.cur.fetchone() #
173 sender_avail_money_ = int(sender_avail_money[0]) # Remarks 1.
174 return sender_avail_money_ #
175
176
177 def transfer_success(self):
178 upd_rec_acc = self.cur.execute(f'update card set balance = balance + {self.amt_transfer} where number = {self.ask_receiver_card_num}' ) # Remarks 1.
179 upd_rec_acc_ = self.conn.commit() #
180 # Remarks 2.3
181 upd_sen_acc = self.cur.execute(f'update card set balance = balance - {self.amt_transfer} where number = {self.card_num}') #
182 upd_sen_acc_ = self.conn.commit() #
183
184
185 def do_transfer(self):
186 self.ask_receiver_card_num = input("\nTransfer\nEnter card number:\n") #
187 if self.check_luhn(self.ask_receiver_card_num) is True: # No need to compare with True, just drop the 'is True' part
188 if self.check_card_existence() is True: # Same above
189 if self.ask_receiver_card_num == self.ask_card_num: #
190 print("\nYou can't transfer money to the same account!") #
191 return self.log_in_success() #
192 else: # I would have mase the complex if/else
193 self.amt_transfer = int(input("Enter how much money you want to transfer:\n")) # statements more undestandable
194 if self.amt_avail() >= self.amt_transfer: #
195 self.transfer_success() #
196 print("Success!") #
197 return self.log_in_success() # No need to return log_in_success(),
198 else: # You have called do_transfer() from it, and there's an infinite loop, so no need to add any return statements
199 print("Not enough money!") #
200 return self.log_in_success() #
201 else: #
202 print("Such a card does not exit.") # IMPORTANT - typo 'exists' (not 'exit')
203 return self.log_in_success() # It can be the cause of an error of 9-th testcase
204 else: #
205 print("Probably you made mistake in the card number. Please try again!") #
206 return self.log_in_success() #
207
208 def close_account(self):
209 del_acc = self.cur.execute(f'delete from card where number = {self.ask_card_num}') # Remarks 1.
210 del_acc_ = self.conn.commit() # No need to declare a variable
211 print("\nThe account has been closed!") #
212
213
214 # main
215 def main(self):
216 self.database()
217 while True:
218 choose_option = input("\n1. Create an account\n2. Log into account\n0. Exit\n") # Delete the first newline (no need)
219 if choose_option == '1':
220 self.create_acc()
221 elif choose_option == '2':
222 self.log_in_acc()
223 else:
224 print("\nBye!") # can also change to "quit('\nBye!')"
225 break # (not necessary)
226
227if __name__ == '__main__': # for the safe 'import' from other files
228 account = BankingSystem()
229 account.main()
230