题目要求
做一个ATM系统可以实现下列功能
- 每个用户有15000的额度,或可以自定义
- 实现购物商城,买东西加入购物车,使用信用卡接口结账
- 可提现,手续费%5
- 每月22号出账单,10号为还款日,过期未还按欠款总额万分之5,每日计息
- 支持多账户登陆
- 支持用户间转账
- 记录每月日常消费流水
- 提供还款接口
- ATM操作日志
- 提供管理接口:创建用户、冻结账户、设置额度等
流程图
目录结构
atm_admin.py:pyatm系统的管理接口
atm_log:atm操作记录
atm_user:记录ATM用户信息
atmtime.py:此模块用来计算账单日以及当前日期近几个月的日期
checkliushui.py:此模块用户查询流水
create_all.py:初始化
getmoney.py:提现
huankuan.py:还款
login.py:登陆
main.py:主界面
now_user:保存当前正在登陆的用户
selectbill.py:查询账单
shopcar.py:购物车
shopping_list:存放商城内的商品
user_log.py:用户流水模块
xiaowang_log:记录用户流水
xiaowang_shopping_car:记录用户的购物车
zhuanzhang.py:转账模块
代码
atm_admin.py
"""
用于ATM账户管管理
"""
import pickle
import login
import time
def write_atmlog(the_str):
log_time = time.strftime('%Y-%m-%d %H-%M-%S', time.localtime(time.time()))
log_srt = "%s at %s\n" % (the_str, log_time)
with open("atm_log", "a") as f:
f.write(log_srt)
def adduser():
atm_dict = login.load_atm_user()
add_user_name = input("请输入用户姓名")
add_user_password = input("请输入用户密码")
add_user_lock = 0
add_user_frozen = 0
while 1:
try:
add_user_money = int("请输入初始额度")
break
except:
continue
atm_dict[add_user_name] ={
"password":add_user_password,
"lock":add_user_lock,
"forzen":add_user_frozen,
"money":add_user_money,
},
login.update_atm_user(atm_dict)
write_atmlog("add user %s" % add_user_money)
def forzenuser():
change_user = input("请输入用户:")
atm_dict = login.load_atm_user()
if change_user not in atm_dict:
print("没有这个用户")
else:
atm_dict[change_user]["forzen"] = 1
login.update_atm_user(atm_dict)
write_atmlog("冻结用户%s" % change_user)
def unforzenuser():
change_user = input("请输入用户:")
atm_dict = login.load_atm_user()
if change_user not in atm_dict:
print("没有这个用户")
else:
atm_dict[change_user]["forzen"] = 0
login.update_atm_user(atm_dict)
write_atmlog("解冻用户%s" % change_user)
def change_money():
change_user = input("请输入用户:")
atm_dict = login.load_atm_user()
if change_user not in atm_dict:
print("没有这个用户")
else:
try:
change_user_money = int(input("输入金额"))
except:
print("输入有误")
return
atm_dict[change_user]["money"] = change_user_money
login.update_atm_user(atm_dict)
write_atmlog("用户%s 额度修改" % change_user)
def menu():
while 1:
title="""
欢迎来到管理员界面
\t1.添加用户
\t2.冻结用户
\t3.解冻用户
\t4.修改金额
"""
func_dict = {
"1":adduser,
"2":forzenuser,
"3":unforzenuser,
"4":change_money,
}
print(title)
choice = input("请输入(q退出):")
if choice == "q":
break
try:
func_dict[choice]()
except:
print("输入有误")
if __name__ == "__main__":
menu()
atmtime.py
import datetime
"""
此模块用来计算账单日以及当前日期近几个月的日期
"""
def tow_month_ago(atm_year, atm_month, atm_day,): #用户输入年月日 返回2个月前22号的日期
now = datetime.date(atm_year, atm_month, atm_day)
atm_month = atm_month - 2
if atm_month <= 0:
atm_month += 12
atm_year -= 1
month_ago = now.replace(year=atm_year,month=atm_month,day=22)
return month_ago
def one_month_ago(atm_year, atm_month, atm_day): #用户输入年月日 返回1个月前22号的日期
now = datetime.date(atm_year, atm_month, atm_day)
atm_month = atm_month - 1
if atm_month <= 0: #小于0的话,反推前一年的
atm_month += 12
atm_year -= 1
month_ago = now.replace(year=atm_year,month=atm_month,day=22)
return month_ago
def user_month_ago(atm_year, atm_month, atm_day, user_month): #返回n个月前22号的日期 用户手动输入
now = datetime.date(atm_year, atm_month, atm_day)
atm_month = atm_month - user_month
if atm_month <= 0:
atm_month += 12
atm_year -= 1
month_ago = now.replace(year=atm_year,month=atm_month,day=1)
return str(month_ago)
checkliushui.py
import userlog
import shopcar
import selectbill
import atmtime
import datetime
"""
此模块用户查询流水
"""
def check_liu_shui(): #获取用户想查询几个月前的流水
while 1:
try:
check_month = int(input("请选择查询的时间段:"))
except:
print("输入有误")
if check_month < 12:
break
else:
print("输入的数字应该小于12")
return check_month
def get_user_log(): #获取用户所有的流水
user_name = shopcar.load_now_user()
log_file = userlog.check_file(user_name)
user_log = userlog.load_log(log_file)
return user_log
def get_user_want_time(check_month): #获取用户想要查询的日期
now_year, now_month, now_day = selectbill.get_ymd()
user_ago = atmtime.user_month_ago(now_year, now_month, now_day, check_month)
# print("userago",user_ago)
return str(user_ago)
def menu(): #界面
liu_shui = []
user_log = get_user_log()
check_month = check_liu_shui()
user_ago = get_user_want_time(check_month)
now = datetime.datetime.now()
now = datetime.datetime.strftime(now,"%Y-%m-%d")
now = str(now)
# print("now:",now)
print(user_log[0])
for i in user_log:
if user_ago < i[-1] <= now:
liu_shui.append(i)
print(i)
if __name__ == "__main__":
menu()
create_all.py
import pickle
"""
初始化模块,初始化所有数据
"""
user_dict = {
"xiaoming":{
"password":"123456",
"lock":0,
"forzen":0,
"money":15000,
},
"xiaowang": {
"password": "111111",
"lock": 0,
"forzen": 0,
"money": 15000,
},
"xiaolan": {
"password": "222222",
"lock": 0,
"forzen": 0,
"money": 15000,
},
"xiaoli": {
"password": "333333",
"lock": 0,
"forzen": 0,
"money": 15000,
},
}
shopping_list = {
'电子通讯': {
'手机': [
('iphone12', 6500),
('samsunsS33', 7800),
('xiaomiMIX8', 4500),
],
'手机配件': [
('耳机', 250),
('保护壳', 50),
('手机膜', 25),
],
},
'电脑': {
'联想': [
('小新700', 5700),
('Y560', 4200),
('T567', 8520),
],
'apple': [
('mac book', 8890),
('mac pro', 12500),
('mac air', 12400),
],
'dell': [
('MX004', 6500),
('laji009', 7800),
('sb512', 4512),
],
},
'成人用品': {
'避孕': [
('duleisi', 40),
('gangben', 35),
('di6gan', 44)
],
'男用': [
('feijibei', 450),
('wawa', 1520),
('runhuaye', 35),
],
'女用': [
("dabangbang", 480),
('zhendonghuan', 250),
('diwenla', 25)
],
},
}
def create_user():
with open("atm_user", "wb") as f:
pickle.dump(user_dict, f)
def load_user():
with open("atm_user", "rb") as f:
user_list = pickle.load(f)
return user_list
def createt_shopping_list():
with open("shopping_list", "wb") as f:
pickle.dump(shopping_list, f)
def load_shopping_list():
with open("shopping_list", "rb") as f:
shopping_list = pickle.load(f)
return shopping_list
if __name__ == "__main__":
# createt_shopping_list()
# print(load_shopping_list())
create_user()
getmoney.py
#!/usr/bin/env python
import pickle
import shopcar
import userlog
"""
用户提现
"""
def menu():
user_name = shopcar.load_now_user()
user_money = shopcar.get_user_money(user_name)
user_choise = input("请确认是否提现(y确认,按任意键退出):")
if user_choise == "y":
while 1:
try:
print("余额:",user_money)
user_wang_money = int(input("请输入金额"))
break
except:
print("输入有误")
if user_wang_money * (2+0.05) < user_money: #提现只能是一般 还有5%手续费
user_money = user_money - user_wang_money
shopcar.update_user_money(user_name, user_money)
userlog.write_log(user_name, user_money, user_wang_money, "提现", "未还款")
else:
print("您的剩余额度不够")
return
else:
return
if __name__ == "__main__":
menu()
huankuan.py
import shopcar
import userlog
import selectbill
import atmtime
import datetime
"""
用户还款模块
"""
def get_user_log(): #获取用户流水
user_name = shopcar.load_now_user()
log_file = userlog.check_file(user_name)
user_log = userlog.load_log(log_file)
return user_log
def update_log(user_log): #更新用户流水
user_name = shopcar.load_now_user()
log_file = userlog.check_file(user_name)
userlog.update_log(log_file, user_log)
def all_lixi(): #计算所有的本息
huan_money = 0 #还款的钱
user_log = get_user_log()
now_year, now_month, now_day = selectbill.get_ymd() #计算时间
tow_ago = str(atmtime.tow_month_ago(now_year, now_month, now_day))
print(user_log[0])
for i in user_log:
if i[-1] < tow_ago and i[4] == "未还款":
print(i)
y, m, d = i[-1].split("-")
y = int(y)
m = int(m)
d = int(d)
huan_money += ben_xi(i[2], now_year, now_month, now_day, y, m, d) #计算单个流水的本息并相加
print("需还款:%.2f" % huan_money)
return huan_money
def ben_xi(money, now_year, now_month, now_day ,y, m, d): #计算单个流水的本息
d1 = datetime.datetime(now_year, now_month, now_day)
d2 = datetime.datetime(y, m, d)
d3 = int((d1 - d2).days) #计算经过了多少天
xi = money * 0.0005 *d3
money += xi
return money
def bu_fen_huan_kuan(): #只还一部分款
user_name = shopcar.load_now_user()
user_money = shopcar.get_user_money(user_name)
user_log = get_user_log()
temp_a = [] #临时存放未还款项
for i in user_log:
if i[4] == "未还款":
temp_a.append(i)
for j,i in enumerate(temp_a):
print(j,i)
while 1:
user_choice = input("请选择要还款的项(q:退出)")
if user_choice == "q":
return
try:
user_choice = int(user_choice)
except:
continue
if user_choice >= len(temp_a):
continue
else:
temp_b = temp_a[user_choice]
break
for i in user_log:
if i == temp_b:
i[4] = "已还款"
user_money += i[2]
shopcar.update_user_money(user_name, user_money)
update_log(user_log)
def all_huan_kuan(): #一次还清所有 将所有未还款改成已还款
user_log = get_user_log()
user_name = shopcar.load_now_user()
user_money = shopcar.get_user_money(user_name)
user_money_up = 0
while 1:
user_choice = input("是否全部还款(y确认,按任意键退出)")
if user_choice == "y":
for i in user_log:
if i[4] == "未还款":
i[4] = "已还款"
user_money_up += i[2]
update_log(user_log)
user_money += user_money_up
shopcar.update_user_money(user_name, user_money)
else:
break
def menu(): #菜单
user_choice = input("是否部分还款(1:部分 2:全部 其他按键退出)")
if user_choice == "1":
bu_fen_huan_kuan()
elif user_choice == "2":
all_huan_kuan()
else:
return
if __name__ == "__main__":
bu_fen_huan_kuan()
login.py
import pickle
import time
"""
用户登陆
"""
def user_input(): #获取用户输入
user_name = input("请输入用户名:")
user_password = input("请输入密码:")
return (user_name, user_password)
def load_atm_user(): #读取ATM系统的所有用户
with open("atm_user", "rb") as f:
user_list = pickle.load(f)
return user_list
def update_atm_user(user_list): #更新用户状态
with open("atm_user", "wb") as f:
pickle.dump(user_list, f)
def check_lock_user(user_name, user_list): #检查用户时候被锁定
if user_name in user_list and user_list[user_name]['lock'] == 0:
return True
else:
return False
def check_user_name_password(user_name, user_password, user_list): #检查用户名密码是否正确
if user_name in user_list and user_list[user_name]["password"] == user_password:
return True
else:
return False
def lock_user(user_name, user_list, lose_num): #锁定用户
if user_name in user_list and lose_num > 3:
# print("Here is check lock")
user_list[user_name]["lock"] = 1
update_atm_user(user_list)
def atm_log_in(user_name): #ATM操作日志
log_time = time.strftime('%Y-%m-%d %H-%M-%S',time.localtime(time.time()))
log_str = "%s login at %s\n" % (user_name, log_time)
with open("atm_log", "a")as f:
f.write(log_str)
def user_now(user_name): #记录当前用户
with open("now_user", "w") as f:
f.write(user_name)
def user_login(): #主函数
error_list = []
while 1:
user_list = load_atm_user()
user_name, user_password = user_input()
if check_lock_user(user_name, user_list):
if check_user_name_password(user_name, user_password, user_list):
print("The user login")
user_now(user_name)
return True
else:
print("The user's name or passwoed is error")
error_list.append(user_name)
# print(error_list)
lose_num = error_list.count(user_name)
# print(lose_num)
lock_user(user_name, user_list, lose_num)
else:
print("The user is locked")
atm_log_in(user_name)
return False
if __name__ == "__main__":
print(load_atm_user())
user_login()
main.py
import login
import shopcar
import getmoney
import selectbill
import checkliushui
import zhuanzhang
import huankuan
"""
顶层模块,程序启动模块
"""
def menu(): #显示菜单
while 1:
title = """欢迎来到ATM系统
\t1.商城
\t2.体现
\t3.账单查询
\t4.每月流水查询
\t5.转账
\t6.还款
"""
func_ditc = {
"1": shopcar.menu ,
"2": getmoney.menu,
"3": selectbill.menu,
"4": checkliushui.menu,
"5": zhuanzhang.menu,
"6": huankuan.menu,
}
print(title)
choice = input("请输入(q退出):")
if choice == "q":
break
try:
func_ditc[choice]()
except:
print("输入有误")
if login.user_login():
menu()
else:
print("err")
selectbill.py
import userlog
import shopcar
import datetime
import atmtime
"""
查询账单并显示
"""
def get_bill_time(): #获取账单的日期区间
now_year, now_month, now_day = get_ymd()
one_ago = atmtime.one_month_ago(now_year, now_month, now_day) #一个月以前的时候
tow_ago = atmtime.tow_month_ago(now_year, now_month, now_day) #两个月以前的时间
return (str(one_ago), str(tow_ago))
def get_ymd(): #将现在时间的年月日返回(已数字类型)
a = datetime.datetime.now()
a = datetime.datetime.strftime(a,"%Y,%m,%d")
atm_year, atm_month, atm_day = a.split(",")
return (int(atm_year), int(atm_month), int(atm_day))
def get_user_log(one_ago, tow_ago): #获取流水中属于账单的信息
atm_bill = []
user_name = shopcar.load_now_user()
log_file = userlog.check_file(user_name)
user_log = userlog.load_log(log_file)
for i in user_log:
if tow_ago < i[-1] < one_ago and i[4] == "未还款":
atm_bill.append(i)
return atm_bill
def menu(): #显示界面
one_ago, tow_ago = get_bill_time()
atm_bill = get_user_log(one_ago, tow_ago)
title = ("姓名", "余额", "支出", "行为", "还款状态", "日期")
user_pay = 0
print(title)
for i in atm_bill:
print(i)
user_pay += i[2]
print("需付款:",user_pay)
return user_pay
if __name__ == "__main__":
one_ago, tow_ago = get_bill_time()
# get_user_log(one_ago, tow_ago)
print(one_ago, tow_ago)
# a,b,c = get_ymd()
# print(a,b,c)
shopcar.py
#!/usr/bin/env python3
import pickle
import login
import userlog
import os
"""
商城模块
"""
def load_now_user(): #读取当前用户
with open("now_user", "r") as f:
user_name = f.read()
return user_name
def get_user_money(user_name): #获取当前用户余额
user_list = login.load_atm_user()
user_money = user_list[user_name]["money"]
return user_money
def update_user_money(user_name, now_user_money): #更新用户余额
user_list = login.load_atm_user()
user_list[user_name]["money"] = now_user_money
login.update_atm_user(user_list)
def get_shopping_list(): #获取商城的商品清单
with open("shopping_list", "rb") as f:
shopping_list = pickle.load(f)
return shopping_list
def menu(): #显示菜单
while 1:
title = """
动感商城
1、购物
2、管理购物车
3、结算
"""
print(title)
func_ditc = {
"1": shop ,
"2": del_shop_car,
"3": pay_shop_car,
}
choice = input("请输入(q退出):")
if choice == "q":
break
try:
func_ditc[choice]()
except:
print("输入有误")
def shopping(shopping_list): #显示商城菜单
while 1: #一级菜单
f_list = []
for j,i in enumerate(shopping_list.keys()):
f_list.append(i)
print(j,i)
f_user_input = input("请选择(q:退出):")
if f_user_input == "q":
return
try:
f_user_input = int(f_user_input)
except:
continue
if f_user_input >= len(f_list):
continue
while 1: #二级菜单
s_list = []
for j,i in enumerate(shopping_list[f_list[f_user_input]].keys()):
s_list.append(i)
print(j,i)
s_user_input = input("请选择(b:返回上级菜单 q:退出):")
if s_user_input == "q":
return
elif s_user_input == "b":
break
try:
s_user_input = int(s_user_input)
except:
continue
if s_user_input >= len(s_list):
continue
while 1: #三级菜单
t_list = []
for j,i in enumerate(shopping_list[f_list[f_user_input]][s_list[s_user_input]]):
t_list.append(i)
print(j,i[0],i[1])
t_user_input = input("请选择(b:返回上级菜单 q:退出)")
if t_user_input == "q":
return
elif t_user_input == "b":
break
try:
t_user_input = int(t_user_input)
except:
continue
if t_user_input >= len(t_list):
continue
return t_list[t_user_input]
def load_shop_car(): #获取某个用户的购物车清单,没有则创建
now_user = load_now_user()
shop_file = "%s_shopping_car" % now_user
if not os.path.isfile(shop_file):
with open(shop_file,"wb") as f:
a = []
pickle.dump(a, f)
with open(shop_file,"rb") as f:
shopping_car_list = pickle.load(f)
return shopping_car_list
def add_shop_car():#用户选择商品并加入购物车
shopping_list = get_shopping_list()
shopping_car_list = load_shop_car()
user_shopping = shopping(shopping_list)
if not user_shopping:
return
shopping_car_list.append(user_shopping)
update_shop_car(shopping_car_list)
def update_shop_car(shopping_car_list): #更新购物车
now_user = load_now_user()
shop_file = "%s_shopping_car" % now_user
with open(shop_file, "wb") as f:
pickle.dump(shopping_car_list, f)
def del_shop_car(): #编辑购物车
shopping_car_list = load_shop_car()
if len(shopping_car_list) == 0:
print("购物车为空")
return
for j,i in enumerate(shopping_car_list):
print(j,i[0],i[1])
while 1:
try:
del_num = input("想删除哪一个(q退出)?")
if del_num == "q":
break
if int(del_num) < len(shopping_car_list):
shopping_car_list.pop(int(del_num))
update_shop_car(shopping_car_list)
print("删除成功")
break
else:
print("输入的商品不存在")
except:
print("输入有误")
def clear_shop_car(): #清空购物车
shopping_car_list = load_shop_car()
shopping_car_list.clear()
update_shop_car(shopping_car_list)
def pay_shop_car(): #结算购物车
user_name = load_now_user()
shopping_car_list = load_shop_car()
user_money = get_user_money(user_name)
car_money = 0
for i in shopping_car_list:
car_money += i[1]
print("user_money:", user_money)
print("car_money:", car_money)
if user_money >= car_money:
user_money -= car_money
clear_shop_car()
update_user_money(user_name, user_money)
userlog.write_log(user_name, user_money, car_money, "购物", "未还款",)
else:
print("余额不足")
def shop(): #购物的主体函数
while 1:
add_shop_car()
user_input = input("是否继续购物(按任意键继续、n退出)")
if user_input == 'n' or user_input == 'N':
break
if __name__=="__main__":
# print(get_user_money(load_now_user()))
# print(load_shop_car())
# pay_shop_car()
while 1:
menu()
user_log.py
#!/usr/bin/env python3
import pickle
import os
import time
"""
用户日志处理
"""
def check_file(user_name): #初始化文件
log_file = "%s_log" % user_name
if not os.path.isfile(log_file):
with open(log_file,"wb") as f:
a = [["姓名", "余额", "金额变动", "行为", "还款状态", "日期"],]
pickle.dump(a, f)
return log_file
def load_log(log_file): #读取流水
with open(log_file, "rb") as f:
user_log = pickle.load(f)
return user_log
def update_log(log_file, user_log): #更新流水
with open(log_file, "wb") as f:
pickle.dump(user_log, f)
def write_log(user_name, user_money, user_pay_money, user_cation, money_stats,): #插入一条流水
log_file = check_file(user_name)
user_log = load_log(log_file)
log_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))
user_log.append([user_name, user_money, user_pay_money, user_cation, money_stats, log_time])
with open(log_file, "wb") as f:
pickle.dump(user_log, f)
if __name__ == "__main__":
# write_log('xiaowang', 14200, 100, '提现', '未还款', '2017-03-25')
for i in load_log("xiaowang_log"):
print(i)
zhuanzhang.py
import shopcar
import login
import userlog
def menu():
user_name = shopcar.load_now_user()
while 1:
user_input = input("确认是否转账(y确认、按任意键退出)")
if user_input == "y":
zhuanzhang_user = input("想给谁转账?")
atm_user = login.load_atm_user()
if zhuanzhang_user in atm_user:
while 1:
try:
zhuanzhang_money = float(input("请输入转账金额"))
break
except:
print("输入有误")
user_money = shopcar.get_user_money(user_name)
zhuanzhang_user_money = shopcar.get_user_money(zhuanzhang_user)
if zhuanzhang_money < user_money:
user_money -= zhuanzhang_money
zhuanzhang_user_money += zhuanzhang_money
shopcar.update_user_money(user_name, user_money)
shopcar.update_user_money(zhuanzhang_user, zhuanzhang_user_money)
userlog.write_log(user_name, user_money, zhuanzhang_money, "支出", "转账",)
userlog.write_log(zhuanzhang_user, zhuanzhang_user_money, zhuanzhang_money, "收入", "转账", )
break
else:
print("金额不能大于余额")
else:
print("没有这个账号")
continue
else:
break
if __name__ == "__main__":
menu()