码迷,mamicode.com
首页 > 其他好文 > 详细

ATM

时间:2016-09-05 12:26:38      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:

ATM:
1. 指定最大透支额度
2. 可取款
3. 定期还款(每月指定日期还款,如15号)
4. 可存款
5. 定期出账单
6. 支持多用户登陆,用户间转帐
7. 支持多用户
8. 管理员可添加账户、指定用户额度、冻结用户等

 

---------------------------------

运行环境:OS X and Win
工具:运行pyCharm
Python 版本:3.5+

---------------------------------

博客地址:https://www.cnblogs.com/blademaster/

---------------------------------
主程序入口:main.py
管理员账号/密码:abc/123

 

目录结构:

技术分享

1.主程序入口

技术分享
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import sys, os
 4 sys.path.append(os.path.join(os.path.dirname(__file__), "admin.py"))
 5 sys.path.append(os.path.join(os.path.dirname(__file__), "user.py"))
 6 import admin, user
 7 
 8 
 9 def show_main_menu():
10     while True:
11         print("[1]管理员登录\n"
12               "[2]用户登录\n"
13               "[q]退出系统")
14 
15         cmd = input("请输入选项:")
16         if cmd == "q":
17             break
18 
19         if not cmd.isdigit():
20             print("无效输入")
21             continue
22 
23         if cmd == 1:
24             admin.show_admin_menu()
25         elif cmd == "2":
26             user.show_user_menu()
27         else:
28             print("无效输入")
29             continue
30 
31 
32 if __name__ == "__main__":
33     show_main_menu()
main.py

2.Admin 入口

技术分享
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 import os, pickle, time
  4 
  5 USER_INFO_SAMPLE = {"username": "abc",
  6                     "card_no": "1234567",
  7                     "password": "8888",
  8                     "credit": 15000.00,
  9                     "balance": 15000.00,
 10                     "saving": 0.00,
 11                     "pay_date": "15",
 12                     "stat_date": "1",
 13                     "user_status": 1}
 14 
 15 ADMIN_INFO_SAMPLE = {"username": "admin"}
 16 
 17 USER_INFO = {}
 18 
 19 ADMIN_INFO = {}
 20 
 21 
 22 def deco(func):
 23     """
 24     装饰器
 25     :param func: 要装饰的函数
 26     :return: _deco: 内层函数
 27     """
 28     def _deco(*args, **kwargs):
 29         if ADMIN_INFO:
 30             func(*args, **kwargs)
 31         else:
 32             admin_login_menu()
 33     return _deco
 34 
 35 
 36 def admin_login_menu():
 37     """
 38     显示管理员登录菜单
 39     :return:
 40     """
 41     while True:
 42         print("-"*40)
 43         username = input("请输入管理员用户名:")
 44         pwd = input("请输入管理员密码:")
 45         r = admin_login(username, pwd)
 46         if r:
 47             break
 48 
 49 
 50 def admin_login(username, pwd):
 51     """
 52     管理员登录
 53     :param username: 用户名
 54     :param pwd: 密码
 55     :return:
 56     """
 57     if os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "admin", username)):
 58         with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "admin", username), "r",
 59                   encoding="utf-8") as f:
 60             pwd_file = f.readline()
 61         if pwd_file.strip("\n").strip() == pwd:
 62             ADMIN_INFO["username"] = username
 63             ADMIN_INFO["password"] = pwd
 64             print("管理员登录成功")
 65             print("-"*40)
 66             show_admin_menu()
 67             return True
 68         else:
 69             print("密码错误")
 70     else:
 71         print("管理员不存在")
 72 
 73 
 74 def show_all_user():
 75     """
 76     打印所有用户
 77     :return:
 78     """
 79     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
 80         print("目录结构错误")
 81         return None
 82 
 83     for root, dirs, files in os.walk(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
 84         for d in dirs:
 85             u_name = os.path.join(root, d, d)
 86             with open(u_name, "rb") as f:
 87                 data = pickle.load(f)
 88                 print(data.get("username").center(40, "-"))
 89                 print("用户名 %s"%data["username"])
 90                 print("卡号 %s"%data["card_no"])
 91                 print("密码 %s"%data["password"])
 92                 print("信用卡额度 $%.2f"%data["credit"])
 93                 print("信用卡可用额度 $%.2f" % data["balance"])
 94                 print("存款 $%.2f"%data["saving"])
 95                 print("账单日 每个月%s日"%data["stat_date"])
 96                 print("还款日 每个月%s日"%data["pay_date"])
 97                 if data["user_status"] == 0:
 98                     print("用户状态正常")
 99                 elif data["user_status"] == 1:
100                     print("用户被锁定")
101                 if data["user_status"] == 2:
102                     print("用户已销户")
103                 print("-"*40)
104 
105 
106 def create_user():
107     """
108     创建用户
109     :return:
110     """
111     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
112         print("目录结构错误")
113         return None
114 
115     username = input("请输入新用户名:")
116     card_no = input("请输入卡号:")
117     pwd = input("请输入新密码:")
118     credit = input("请输入额度:")
119 
120     USER_INFO["username"] = username
121     USER_INFO["card_no"] = card_no
122     USER_INFO["password"] = pwd
123     USER_INFO["credit"] = float(credit)
124     USER_INFO["balance"] = float(credit)
125     USER_INFO["saving"] = 0.00
126     USER_INFO["pay_date"] = "15"
127     USER_INFO["stat_date"] = "1"
128     USER_INFO["user_status"] = 0  # 正常用户
129 
130     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no)):
131         os.makedirs(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no))
132 
133     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no), "wb") as f:
134         pickle.dump(USER_INFO, f, 0)
135 
136 
137 def load_user(card_no):
138     """
139     读取用户信息
140     :param card_no: 用户卡号
141     :return:
142     """
143     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no)):
144         print("无效卡号, 读取失败")
145         return None
146 
147     global USER_INFO
148     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no), "rb") as f:
149         USER_INFO = pickle.load(f)
150     return True
151 
152 
153 def dump_user(card_no):
154     """
155     写入用户信息
156     :param card_no: 用户卡号
157     :return:
158     """
159     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no)):
160         print("无效卡号, 写入失败")
161         return None
162 
163     global USER_INFO
164     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no), "wb") as f:
165         pickle.dump(USER_INFO, f, 0)
166     return True
167 
168 
169 def set_credit():
170     """
171     调整用户额度
172     :return:
173     """
174     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
175         print("目录结构错误")
176         return None
177 
178     card_no = input("请输入用户卡号:")
179     credit = input("请输入新的额度:")
180 
181     if credit.isdigit() and float(credit) > 0:
182         if load_user(card_no):
183             old_credit = float(USER_INFO.get("credit", None))
184             old_balance = float(USER_INFO.get("balance", None))
185             USER_INFO["credit"] = float(credit)
186             if old_credit > float(credit):
187                 if old_balance > float(credit):
188                     USER_INFO["balance"] = float(credit)
189             else:
190                 USER_INFO["balance"] = old_balance + (float(credit) - old_credit)
191             dump_user(card_no)
192             print("调整额度完成")
193         else:
194             print("调整额度失败")
195     else:
196         print("额度输入有误")
197 
198 
199 def freeze_user():
200     """
201     冻结用户
202     :return:
203     """
204     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
205         print("目录结构错误")
206         return None
207 
208     card_no = input("请输入用户卡号:")
209     print("1. 恢复用户, 2. 冻结用户")
210     cmd = input("请输入选项:")
211     if cmd.isdigit() and cmd == "2":
212         if load_user(card_no):
213             USER_INFO["user_status"] = 1
214             dump_user(card_no)
215             print("冻结用户完成")
216         else:
217             print("冻结用户失败")
218     elif cmd.isdigit() and cmd == "1":
219         if load_user(card_no):
220             USER_INFO["user_status"] = 0
221             dump_user(card_no)
222             print("恢复用户完成")
223         else:
224             print("恢复用户失败")
225     else:
226         print("输入错误")
227 
228 
229 def bill():
230     """
231     为每个用户生成账单
232     :return:
233     """
234     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
235         print("目录结构错误")
236         return None
237 
238     for root, dirs, files in os.walk(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
239         for d in dirs:
240             u_name = os.path.join(root, d, d)
241             with open(u_name, "rb") as f:
242                 data = pickle.load(f)
243                 stat_name = "%s-%s" % (time.strftime("%Y"), time.strftime("%m"))
244                 if int(time.strftime("%d")) > int(data["stat_date"]) and 245                         (not os.path.exists(os.path.join(root, d, stat_name))):
246                     with open(os.path.join(root, d, stat_name), "w", encoding="utf-8") as f1:
247                         f1.write("%s年%s月需还金额为: %.2f" % (time.strftime("%Y"), time.strftime("%m"),
248                                                         float(data["credit"]) - float(data["balance"])))
249 
250 
251 def auto_pay():
252     """
253     自动还款
254     :return:
255     """
256     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
257         print("目录结构错误")
258         return None
259 
260     for root, dirs, files in os.walk(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
261         for d in dirs:
262             u_name = os.path.join(root, d, d)
263             with open(u_name, "rb") as f:
264                 data = pickle.load(f)
265                 stat_name = "%s-%s" % (time.strftime("%Y"), time.strftime("%m"))
266                 if int(time.strftime("%d")) > int(data["pay_date"]) and (os.path.exists(os.path.join(root, d, stat_name))):
267                     with open(os.path.join(root, d, stat_name), "r", encoding="utf-8") as f1:
268                         pay = float(f1.readline().strip("\n").split()[1])
269                         saving = float(data["saving"])
270                         if saving > pay:
271                             data["saving"] -= float(pay)
272                             data["balance"] += float(pay)
273                             os.rename(os.path.join(root, d, stat_name), os.path.join(root, d, "%s.ok" % stat_name))
274                             global USER_INFO
275                             USER_INFO = data
276                             dump_user(USER_INFO.get("card_no"))
277                         else:
278                             print("卡号%s还款失败, 余额不足" % data["card_no"])
279 
280 
281 @deco
282 def show_admin_menu():
283     """
284     显示管理员菜单
285     :return:
286     """
287 
288     while True:
289         bill()
290         auto_pay()
291         print("[1]查看所有用户\n"
292               "[2]添加用户\n"
293               "[3]指定用户额度\n"
294               "[4]冻结用户\n"
295               "[q]退出系统")
296 
297         cmd = input("请输入选项:")
298         if cmd == "q":
299             global ADMIN_INFO
300             ADMIN_INFO = {}
301             break
302 
303         if not cmd.isdigit():
304             print("无效输入")
305             continue
306 
307         if cmd == 1:
308             show_all_user()
309         elif cmd == "2":
310             create_user()
311         elif cmd == "3":
312             set_credit()
313         elif cmd == "4":
314             freeze_user()
315         else:
316             print("无效输入")
317             continue
admin.py

3.User 入口

技术分享
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 import os, pickle, time, logging
  4 
  5 USER_INFO_SAMPLE = {"username": "abc",
  6                     "card_no": "1234567",
  7                     "password": "8888",
  8                     "credit": 15000.00,
  9                     "balance": 15000.00,
 10                     "saving": 0.00,
 11                     "pay_date": "15",
 12                     "stat_date": "1",
 13                     "user_status": 1}
 14 
 15 ADMIN_INFO_SAMPLE = {"username": "admin.py"}
 16 
 17 USER_INFO = {}
 18 
 19 
 20 def deco(func):
 21     """
 22     装饰器
 23     :param func: 要装饰的函数
 24     :return: _deco: 内层函数
 25     """
 26     def _deco(*args, **kwargs):
 27         if USER_INFO:
 28             func(*args, **kwargs)
 29         else:
 30             user_login_menu()
 31     return _deco
 32 
 33 
 34 def user_login_menu():
 35     """
 36     显示登录菜单
 37     :return:
 38     """
 39     while True:
 40         print("-"*40)
 41         card_no = input("请输入卡号:")
 42         pwd = input("请输入密码:")
 43         r = user_login(card_no, pwd)
 44         if r:
 45             break
 46 
 47 
 48 def user_login(card_no, pwd):
 49     """
 50     用户登录
 51     :param card_no: 卡号
 52     :param pwd: 密码
 53     :return:
 54     """
 55     load_user(card_no)
 56     if pwd == USER_INFO.get("password"):
 57         print("登录成功")
 58         print("-" * 40)
 59         show_user_menu()
 60         return True
 61     else:
 62         print("密码错误")
 63 
 64 
 65 def load_user(card_no):
 66     """
 67     读取用户信息
 68     :param card_no: 用户卡号
 69     :return:
 70     """
 71     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no)):
 72         print("无效卡号, 读取失败")
 73         return None
 74 
 75     global USER_INFO
 76     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no), "rb") as f:
 77         USER_INFO = pickle.load(f)
 78     return True
 79 
 80 
 81 def dump_user(card_no):
 82     """
 83     写入用户信息
 84     :param card_no: 用户卡号
 85     :return:
 86     """
 87     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no)):
 88         print("无效卡号, 写入失败")
 89         return None
 90 
 91     global USER_INFO
 92     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no), "wb") as f:
 93         pickle.dump(USER_INFO, f, 0)
 94     return True
 95 
 96 
 97 def set_credit():
 98     """
 99     调整用户额度
100     :return:
101     """
102     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
103         print("目录结构错误")
104         return None
105 
106     credit = input("请输入新的额度:")
107     card_no = USER_INFO.get("card_no")
108 
109     if credit.isdigit() and float(credit) > 0:
110         if load_user(card_no):
111             old_credit = float(USER_INFO.get("credit", None))
112             old_balance = float(USER_INFO.get("balance", None))
113             USER_INFO["credit"] = float(credit)
114             if old_credit > float(credit):
115                 if old_balance > float(credit):
116                     USER_INFO["balance"] = float(credit)
117             else:
118                 print("无法调整为更高的额度, 请联系管理员")
119             dump_user(card_no)
120             print("调整额度完成")
121         else:
122             print("调整额度失败")
123     else:
124         print("额度输入有误")
125 
126 
127 def withdraw():
128     """
129     取款
130     :return:
131     """
132     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
133         print("目录结构错误")
134         return None
135 
136     money = input("请输入取款金额:")
137     card_no = USER_INFO.get("card_no")
138     if money.isdigit() and float(money) > 0:
139         old_saving = float(USER_INFO.get("saving", None))
140         if old_saving >= float(money):
141             USER_INFO["saving"] = float(old_saving) - float(money)
142         else:
143             print("余额不足")
144         dump_user(card_no)
145     else:
146         print("输入有误")
147 
148 
149 def save_money():
150     """
151     取款
152     :return:
153     """
154     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
155         print("目录结构错误")
156         return None
157 
158     money = input("请输入存款金额:")
159     card_no = USER_INFO.get("card_no")
160 
161     if money.isdigit() and float(money) > 0:
162         old_saving = float(USER_INFO.get("saving", None))
163         USER_INFO["saving"] = float(old_saving) + float(money)
164         dump_user(card_no)
165     else:
166         print("输入有误")
167 
168 
169 def trans_money():
170     """
171     转账
172     :return:
173     """
174     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
175         print("目录结构错误")
176         return None
177 
178     card_no_to = input("请输入转账卡号:")
179     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no_to)):
180         print("卡号不存在")
181         return None
182     money = input("请输入转账金额:")
183     card_no = USER_INFO.get("card_no")
184 
185     if money.isdigit() and float(money) > 0:
186         from_name = os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no, card_no)
187         to_name = os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no_to, card_no_to)
188         with open(from_name, "rb") as f1, open(to_name, "rb") as f2:
189             data_from = pickle.load(f1)
190             data_to = pickle.load(f2)
191 
192         if data_from["saving"] >= float(money):
193             data_from["saving"] -= float(money)
194             data_to["saving"] += float(money)
195         else:
196             print("余额不足")
197             return None
198 
199         try:
200             data_from_new = data_from
201             data_to_new = data_to
202             with open(from_name, "wb") as f1, open(to_name, "wb") as f2:
203                 pickle.dump(data_from_new, f1, 0)
204                 pickle.dump(data_to_new, f2, 0)
205         except IOError as e:
206             print("出现异常, 操作撤销")
207             logging.error(e)
208             with open(from_name, "wb") as f1, open(to_name, "wb") as f2:
209                 pickle.dump(data_from, f1, 0)
210                 pickle.dump(data_to, f2, 0)
211     else:
212         print("输入有误")
213 
214 
215 def show_bill():
216     """
217     打印账单
218     :return:
219     """
220     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
221         print("目录结构错误")
222         return False
223 
224     card_no = USER_INFO.get("card_no")
225 
226     if os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
227                                    "%s-%s.ok" % (time.strftime("%Y"), time.strftime("%m")))):
228         print("本期账单已还清")
229         return False
230 
231     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
232                                        "%s-%s" % (time.strftime("%Y"), time.strftime("%m")))):
233         print("无账单")
234         return False
235 
236     with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
237                            "%s-%s" % (time.strftime("%Y"), time.strftime("%m"))), "r", encoding="utf-8") as f:
238         print(f.readline().strip("\n"))
239     return True
240 
241 
242 def show_balance():
243     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
244         print("目录结构错误")
245         return False
246     balance = USER_INFO.get("balance")
247     print(您当前的可用额度为: %s%balance)
248     return True
249 
250 
251 def pay_credit():
252     """
253     信用卡还款
254     :return:
255     """
256     if not os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user")):
257         print("目录结构错误")
258         return None
259 
260     card_no = USER_INFO.get("card_no")
261     if not show_bill():
262         print("无需还款")
263         return
264     money = input("请输入还款金额:")
265     if not money.isdigit():
266         print("输入有误")
267         return
268     money = float(money)
269     if float(USER_INFO.get("saving")) >= money:
270         USER_INFO["saving"] = float(USER_INFO.get("saving")) - money
271         USER_INFO["balance"] = float(USER_INFO.get("balance")) + money
272         with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
273                                "%s-%s" % (time.strftime("%Y"), time.strftime("%m"))), "r+", encoding="utf-8") as f:
274             ls = f.readline().strip("\n").split()
275             pay = float(ls[1])
276             pay -= money
277             if pay < 0:
278                 pay = 0
279             f.seek(0)
280             f.write("%s %.2f" % (ls[0], pay))
281         if pay == 0:
282             os.rename(os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
283                                    "%s-%s" % (time.strftime("%Y"), time.strftime("%m"))),
284                       os.path.join(os.path.dirname(os.path.dirname(__file__)), "db", "user", card_no,
285                                    "%s-%s.ok" % (time.strftime("%Y"), time.strftime("%m"))))
286         dump_user(card_no)
287     else:
288         print("还款失败, 余额不足")
289 
290 
291 @deco
292 def show_user_menu():
293     """
294     显示用户菜单
295     :return:
296     """
297     while True:
298         print("[1]取款\n"
299               "[2]存款\n"
300               "[3]转账\n"
301               "[4]查看账单\n"
302               "[5]信用卡还款\n"
303               "[6]查看额度\n"
304               "[q]退出系统")
305 
306         cmd = input("请输入选项:")
307         if cmd == "q":
308             global USER_INFO
309             USER_INFO = {}
310             break
311 
312         if not cmd.isdigit():
313             print("无效输入")
314             continue
315 
316         if cmd == 1:
317             withdraw()
318         elif cmd == "2":
319             save_money()
320         elif cmd == "3":
321             trans_money()
322         elif cmd == "4":
323             show_bill()
324         elif cmd == "5":
325             pay_credit()
326         elif cmd == "6":
327             show_balance()
328 
329         else:
330             print("无效输入")
331             continue
user.py

 

ATM

标签:

原文地址:http://www.cnblogs.com/blademaster/p/5841536.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!