作业三 ATM
模拟实现一个ATM+购物商场程序
1.额度15000自定义 商城和银行两个帐户
2.实现购物商城,买东西加入购物车,调用信用卡接口结账
3.可以提现,手续费5%,提现额度不能超过50%
4.每月22日出帐单,每月10日为还款日,过期没还,按欠款总额万分之5 每日计息。 免费用48天,借2000,还1000也用2000*万分之5的利息。
5.支持多帐户登录
6.支持帐户间转账
7.记录每月日常消费流水
8.提供还款接口
9.ATM记录操作日志
10.提供管理接口,包括添加帐户、用户额度、冻结帐户等。。。
作业要求:
ATM:
- 指定最大透支额度
- 可取款
- 定期还款(每月指定日期还款,如15号)
- 可存款
- 定期出账单
- 支持多用户登陆,用户间转帐
- 支持多用户
- 管理员可添加账户、指定用户额度、冻结用户等
目录结构:
bin目录 执行文件 主程序在此目录 每个程序不超过10行
atm.py start
shopping.py
不写任何业务逻辑
conf目录 配置文件
user_db
log文件路径和格式
log目录 日志
db目录 数据库
modules/core 模块和核心目录 存放业务逻辑
功能独立的就应该使用一个单独的文件
帐户等信息必须用json或pickle存,不要追加文件要清掉重新写,覆盖。确保只dump,load一次。
此作业经过思路的梳理,最后终于基本写出,过程中还感冒,休息了几天,期间用到了不少文件夹和配置文件,个人感觉要是学到数据库就方便多了。
一、流程图:
二、readme:
系统分为两部分(模块):
一、商城购物
1.用户登录
2.显示商品列表
3.选购的商品加入购物车
4.调用信用卡模块判断额度及帐户余额
5.购物及消费记录
二、信用卡中心
1.用户登录(管理员、普通用户)
2.权限管理
3.普通用户的增、删、改,额度管理(增加用户目录及记录相关文件)
4.提现、转账
5.手续费用管理
6.时间日期处理
三、数据存储
1.bin目录 执行文件 主程序在此目录 每个程序不超过10行shop.py 和 atm.py start 不包含任何业务逻辑
2.conf目录 配置文件 费率等信息
3.userinfo目录 存储user基本信息和信用、消费记录
4.log目录 日志
5.core 模块和核心目录 存放业务逻辑
目录结构:
代码如下:
bin目录下包含main.py和atm.py:
main.py
!/usr/bin/env python
-- encoding:utf-8 --
Author:'liudong'
import sys
sys.path.append('..\bin')
import atm
import os
if name == 'main':
if len(sys.argv) != 2:
print('Please input args')
elif sys.argv[1] != 'start':
print('use 'python3 main start' to run program:')
exit()
else:
print('Welcome to ATM system'.center(50, '*'))
atm.main()
atm.py
-- conding:utf-8 --
Author:'liudong'
import sys, os, pickle
sys.path.append('..\core')
sys.path.append('..\config\')
import user_manage,login, user_func
login_username = '' # 保存当前登录用户名
def main():
admin_logined = False
user_logined = False
user_locked = False
while True:
user_choice_menu = input('\n1.查看信息\n2.存款\n3.取款\n4.还款\n5.转帐\n6.管理功能\n7.Q[q] = Exit')
if user_choice_menu == '7' or user_choice_menu == 'Q' or user_choice_menu == 'q':
quit()
elif user_choice_menu == '6':
print('login as Administrator first')
username = input('please input your username:')
password = input('please input your password:')
admin_logined = login.admin_login(username, password)
if admin_logined:
print('welcome administrator %s'.center(50, '_') % username)
admin_choice = input('1.增加用户\n2.删除用户\n3.锁定用户\n4.额度管理'
'\nQ[q]=Exit')
if admin_choice == 'Q' or admin_choice == 'q':
exit()
elif admin_choice == '1': #增加用户
user_manage.add_user()
elif admin_choice == '2':
user_manage.del_user()
elif admin_choice == '3':
user_manage.lock_user()
elif admin_choice == '4':
user_func.credit_set()
else:
print('Please log in as administrator first!')
else:
if not user_logined:
print('login as user first')
user = input('please input your username:')
passwd = input('please input your password:')
user_logined = login.user_login(user, passwd)
login_username = user
else:
if user_choice_menu == '1': # 显示用户信息
print('%s用户信息:' % user)
user_list_file = open('..\\db\\user.db', 'rb')
user_list = pickle.load(user_list_file)
print(user_list[user])
continue
# else:
# print('invalid input.')
if user_choice_menu == '2': # 存款
print('-' * 50)
save_amount = input('请输入存款金额')
save_result = user_func.save_money(user, save_amount)
if save_result:
print('Save successed!')
else:
print('save failed!')
if user_choice_menu == '3': # 取款
print('-' * 50)
withdraw_money = input('请输入取款金额')
withdraw_result = user_func.withdraw_money(user, withdraw_money)
if withdraw_result:
print('withdraw successed!')
else:
print('withdraw failed!')
if user_choice_menu == '4': # 还款
print('-' * 50)
payback = input('请输入还款数额')
payback_result = user_func.payback_money(user, payback)
if payback_result:
print('payback successed!')
else:
print('payback failed!')
if user_choice_menu == '5': # 转帐
print('-' * 50)
tran_user = input('请输入接收用户名')
amount = input('请输入金额')
tran_result = user_func.transfor_money(user, tran_user, amount)
if tran_result:
print('transfor successed!')
else:
print('transfor failed!')
core目录下包含login.py、user_func.py、user_manage.py
login.py
!/usr/bin/env python
-- conding:utf-8 --
Author:'liudong'
import sys
import os
import pickle
LOGIN_USER = {'is_login': False} # 判断用户登录成功与否
USER_TYPE = {'is_admin': False} # 判断用户类型
user_base_info = {'username': 'rain',
'card': card_num,
'password': commons.md5('8888'),
'credit': 15000, # 信用卡额度
'balance': 15000, # 本月可用额度
'saving': 0, # 储蓄金额
"enroll_date": "2016-01-01", # 注册时间
'expire_date': "2021-01-01",
'status': 0, # 0=normal,1=locked,2=disabled
"debt": [], # 欠款记录,如:[{'date':"2015_4_10","total}]
}
pickle.dump(user_base_info,open('..\db\user.db','wb'))
def admin_login(user, passwd):
user_password = [] # 保存用户、密码列表
user_list = []
with open('..\db\admins.db') as admin_file:
for u in admin_file: # 取出用户名和密码
user_password = u.split()
user_list.append(user_password[0]) # 保存用户名到user_list
user_list.append(user_password[1]) # 保存密码到user_list
# print(user_password)
for user_login in user_list: # 判断用户输入的用户名存在?
passwd_index = user_list.index(user) + 1 # 取出用户名下标
# print(passwd_index)
if passwd == user_list[passwd_index]: # 判断用户名对应的密码
print('You login as administrator>>>%s<<<' % user)
LOGIN_USER['is_login'] = True
USER_TYPE['is_admin'] = True
return True
else:
print('Invalid username or password')
return False
def user_login(user,passwd):
"""
普通用户登录程序
:param user:
:param passwd:
:return:
"""
user_list_file = open('..\\db\\user.db','rb') #读取用户基本信息
user_list = pickle.load(user_list_file)
# print(user_list,type(user_list))
# for user_loop in user_list:
# # print(user_list[user][1])
while True:
if user in user_list and passwd == user_list[user][1] :
if user_list[user][7] == '1':
print('your account is locked, please contact administrator!')
else:
print('Welcome user %s' %user)
return True
else:
print('Invalid username or password!')
return False
continue
user_func.py
!/usr/bin/env python
-- conding:utf-8 --
Author:'liudong'
import os,logging
import pickle
import sys
sys.path.append('..\core\')
import show_log
def save_money(user, amount):
"""
存款功能
:param user:用户名
:param amount: 存款额
:return:
"""
save_file = open('..\db\user.db', 'rb') # 打开文件读取用户信息
save_user_userinfo = pickle.load(save_file)
# print(save_user_userinfo,type(save_user_userinfo))
save_file.close()
save_user_userinfo[user][4] += str(int(save_user_userinfo[user][4])+int(amount))
new_save_file = open('..\db\newuser.db', 'wb')
pickle.dump(save_user_userinfo, new_save_file)
new_save_file.close()
os.remove('..\db\user.db')
os.renames('..\db\newuser.db', '..\db\user.db')
dir_card = str(save_user_userinfo[user][0]) #获取用户卡号,用于进入该目录
os.chdir('..\db\' + dir_card )
logging.basicConfig(filename='userlog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('user money saved $%s' % amount + '\n')
return True
def withdraw_money(user, amount):
"""
用户取款功能
:param user:
:param amount:
:return:
"""
withdraw_file = open('..\db\user.db', 'rb') # 打开文件读取用户信息
withdraw_userinfo = pickle.load(withdraw_file)
# print(save_user_userinfo,type(save_user_userinfo))
withdraw_file.close()
if not amount >= withdraw_userinfo[user][3]:
withdraw_userinfo[user][3] = str(int(withdraw_userinfo[user][3]) - int(amount))
new_save_file = open('..\db\newuser.db', 'wb')
pickle.dump(withdraw_userinfo, new_save_file)
new_save_file.close()
os.remove('..\db\user.db')
os.renames('..\db\newuser.db', '..\db\user.db')
dir_card = str(withdraw_userinfo[user][0])
os.chdir('..\db\' + dir_card)
logging.basicConfig(filename='userlog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('withdraw money $%s' % amount + '\n')
return True
def payback_money(user, amount):
"""
用户还款功能
:param user:
:param amount:
:return:
"""
payback_file = open('..\db\user.db', 'rb') # 打开文件读取用户信息
payback_userinfo = pickle.load(payback_file)
# print(save_user_userinfo,type(save_user_userinfo))
payback_file.close()
payback_userinfo[user][3] = str(int(payback_userinfo[user][3])+int(amount))
new_payback_file = open('..\db\newuser.db', 'wb')
pickle.dump(payback_userinfo, new_payback_file)
new_payback_file.close()
os.remove('..\db\user.db')
os.renames('..\db\newuser.db', '..\db\user.db')
dir_card = str(payback_userinfo[user][0])
os.chdir('..\db\' + dir_card)
logging.basicConfig(filename='userlog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('withdraw money $%s' % amount + '\n')
return True
def transfor_money(user_out, user_in, amount):
"""
转账功能
:param user_out:
:param user_in:
:param amount:
:return:
"""
tran_file = open('..\db\user.db', 'rb') # 打开文件读取用户信息
tran_userinfo = pickle.load(tran_file)
tran_file.close()
if not amount >= tran_userinfo[user_out]:
tran_userinfo[user_out][2] = str(int(tran_userinfo[user_out][2]) - int(amount))
tran_userinfo[user_in][2] = str(int(tran_userinfo[user_in][2]) + int(amount))
new_tran_file = open('..\db\newuser.db', 'wb')
pickle.dump(tran_userinfo, new_tran_file)
new_tran_file.close()
os.remove('..\db\user.db')
os.renames('..\db\newuser.db', '..\db\user.db')
dir_card_out = str(tran_userinfo[user_out][0])
dir_card_in = str(tran_userinfo[user_in][0])
os.chdir('..\db\' + dir_card_out)
logging.basicConfig(filename='userlog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('withdraw money $%s' % amount + '\n')
os.chdir('..\db\' + dir_card_in)
logging.basicConfig(filename='userlog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('withdraw money $%s' % amount + '\n')
return True
user_manage.py
!/usr/bin/env python
-- conding:utf-8 --
Author:'liudong'
import pickle, os,time,logging
all_user_info = {} # 保存文件所有用户信息
def add_user():
old_file = open('..\db\user.db', 'rb')
all_user_info = pickle.load(old_file)
old_file.close()
add_username = input('please input username you want add.')
other_information = input('please input basic information, like this: ' # 输入的内容是字符串
"""
信用卡号,密码,信用卡额度,本月可用额度,储蓄金额,注册时间,到期日,状态 0=normal,1=locked
""")
list_other_information = list(other_information.split(','))
# print(list_other_information, type(list_other_information))
all_user_info[add_username] = list_other_information
# print(add_user_key, type(add_user_key))
user_card_no = all_user_info[add_username][0] # 获取用户卡号
# print(user_card_no)
user_db_file = open('..\db\usernew.db', 'wb')
pickle.dump(all_user_info, user_db_file)
user_db_file.close()
os.remove('..\db\user.db')
os.renames('..\db\usernew.db', '..\db\user.db')
os.chdir('..\db') # 切换到db目录
os.mkdir(user_card_no) # 创建该用户卡号为名称的文件夹
print('%s user created' % add_username)
logging.basicConfig(filename='timelog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('add user %s' % add_username + '\n') #记录用户增加日志
def del_user():
print('_' * 50)
del_username = input('please input username you want to delete.')
confirm = input('please confirm? y[Y]')
if confirm == 'y' or confirm == 'Y':
os.chdir('..\db\')
del_user_file = open('..\DB\user.db', 'rb') # 打开用户基本信息文件
del_uesr_list = pickle.load(del_user_file) # 读取文件所有用户基本信息到del_user_list
del_user_file.close()
dir_del = str(del_uesr_list[del_username][0]) # 保存要删除用户目录的名字
del del_uesr_list[del_username] # 从字典del_user_list中删除用户输入的用户名为key的所有信息
os.rmdir(dir_del) # 删除目录
# print(del_uesr_list,type(del_uesr_list))
new_file = open('..\DB\usernew.db', 'wb') # 打开新的文件用于写入新用户字典信息
pickle.dump(del_uesr_list, new_file) # 将新的字典信息序列化后写入usernew.db文件
new_file.close() # 关闭文件
os.remove('..\db\user.db') # 将原文件删除
os.renames('..\db\usernew.db', '..\db\user.db')
logging.basicConfig(filename='timelog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('delete user %s' % del_username + '\n')
def lock_user():
print('' * 50)
lock_username = input('please input username you want to delete.')
confirm = input('please confirm? y[Y]')
if confirm == 'y' or confirm == 'Y':
os.chdir('..\db\')
lock_user_file = open('..\DB\user.db', 'rb') # 打开用户基本信息文件
lock_user_list = pickle.load(lock_user_file) # 读取文件所有用户基本信息到del_user_list
lock_user_file.close()
lock_user_list[lock_username][7] = '1'
new_file = open('..\DB\usernew.db', 'wb') # 打开新的文件用于写入新用户字典信息
pickle.dump(lock_uesr_list, new_file) # 将新的字典信息序列化后写入usernew.db文件
new_file.close() # 关闭文件
os.remove('..\db\user.db') # 将原文件删除
os.renames('..\db\usernew.db', '..\db\user.db') #新文件改名
logging.basicConfig(filename='timelog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('lock user %s' % lock_username + '\n')
def credit_set():
print('' * 50)
credit_user = input('please input the username you want to set credit:')
credit_amount = input('please input credit amount:')
credit_user_file = open('..\DB\user.db', 'rb') # 打开用户基本信息文件
credit_user_list = pickle.load(credit_user_file) # 读取文件所有用户基本信息到del_user_list
credit_user_file.close()
credit_user_list[credit_user][2] = credit_amount
new_file = open('..\DB\usernew.db', 'wb') # 打开新的文件用于写入新用户字典信息
pickle.dump(credit_user_list, new_file) # 将新的字典信息序列化后写入usernew.db文件
new_file.close() # 关闭文件
os.remove('..\db\user.db') # 将原文件删除
os.renames('..\db\usernew.db', '..\db\user.db') # 新文件改名
logging.basicConfig(filename='timelog.txt', level=logging.INFO, format='%(asctime)s%(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
logging.info('user %s credit is set %s' % (credit_user,credit_amount) + '\n')
编辑界面上怎么找不到插入代码呢。还有很多待完善的地方,但急于申请后续课程的学习啊,没办法,先完成,后续再改善吧。
作业三 ATM的更多相关文章
- 个人作业三——ATM管理系统
一 作业信息 博客班级 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/ 作业要求 https://edu.cnblogs.com/campus/a ...
- Python-S13作业-day5-之 ATM
Python-S13作业-day5-之 ATM 需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 其实是两 ...
- JAVA作业三
(一)学习总结 1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Gr ...
- jQuery 作业三个按钮
作业三个按钮 <!--声明 文档--> <!DOCTYPE html> <!--定义字符集--> <html lang="zh-CN"&g ...
- 作业三:LINUX内核的启动过程
作业三:LINUX内核的启动过程 一.使用GDB跟踪内核从start_kernel到init进程启动(附实验截图) (一)使用自己的Linux系统环境搭建MenuOS的过程 下载内核源代码编译内核 c ...
- 20155303狄惟佳预备作业三Linux学习笔记
20155303狄惟佳预备作业三Linux学习笔记 初次接触Ubuntu系统以及Linux内核,了解了其产生的历史,从感性来讲,深深吸引我的是其中蕴含的珍贵的开源精神,以及Stallman等人对&qu ...
- 20165301 预备作业三:Linux安装及命令入门
预备作业三:Linux安装及命令入门 VirtualBox虚拟机的安装 在进行安装之前,原本以为有了娄老师的安装教程会是一件很容易的事情.万万没想到,在自己实际动手操作中,还是遇到了许多困难.通过与同 ...
- 機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 课后习题解答
今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业三的习题解答.笔者在做这些题目时遇到非常多困难,当我在网上寻找答案时却找不到,而林 ...
- Day5作业,商城+ATM机+后台管理
晚来了....东西太多,需要写的blog内容太多,re讲的渣渣,不明白为什么oldboy经常换老师,吐槽下吧,真心不爱了.... github地址在这:https://github.com/ccorz ...
随机推荐
- JAVA classpath, 纠正我一直以来错误的认知
如何调在CLI中使用java tool(JDK中的java命令)调用一个打包在jar中的类,我想大多数人都能给出笼统的方案: java -classpath xxxxx com.test.classA ...
- Sql Server索引(转载)
官方说法: 聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序. 聚集索引确定表中数据的物理顺序.聚集索引类似于电话簿,后者按姓氏排列数据.由于聚集索引规定数据在表中的物理存储顺序, ...
- box flex 弹性盒模型(转载)
css3引入了新的盒模型——弹性盒模型,该模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间.这与XUL(火狐使用的用户交互语言)相似,其它语言也使用相同的盒模型,如XAML .GladeX ...
- mysql 整形的长度问题
tinyint 有符号的范围是-128至127: 无符号的范围是0到255,2的8 次方-1: 存储大小为 1 字节. smallint 有符号的范围是-32768至32767: 无符号的范围是0 ...
- 《EM-PLANT仿真技术教程》读书笔记(持续更新中)
1.在系统分析过程中,必须考虑系统所处的环境,因此划分系统与环境的边界是系统分析的首要任务 2.模型可以分为物理模型和数学模型.数学模型可以分为解析模型.逻辑模型.网络模型以及仿真模型.模型可以分为离 ...
- mysql优化 - mysql 的 hint
FORCE INDEX 强制索引 只使用建立在field1上的索引,而不使用其它字段上的索引. SELECT * FROM table1 FORCE INDEX (field1) IGNORE IND ...
- poj 3232 Accelerator
http://poj.org/problem?id=3232 题意:有一个含有n辆车的车队,当前距离终点的距离已知,有m个加速器,每个加速器在一个时刻只能给一辆车用,一旦使用就会使得其速度由1变成k, ...
- MFC的杂七杂八
1.判断焦点当前所在控件 2.动态移动控件位置 3.GDI+绘制文字 4.编辑框跳变显示 5.最大化显示 6.Uint uFormat常用值 7.获取菜单个数 8.添加气泡提示 9.编辑框输入时响应函 ...
- 3个QT新闻网,2个发烧友网站
http://planet.qt.io/ http://blog.basyskom.com/2015/introducing-qtopcua/ http://www.qtworldsummit.com ...
- Jquery 对象集合的迭代扩展forEach
if (jQuery && !jQuery.fn.forEach) { $(function () { (function ($) { $.fn.extend({ forEach: f ...