洗礼灵魂,修炼python(77)--全栈项目实战篇(5)—— ATM自动存取机系统
要求:
1.完成常识中的ATM存取款机功能
2.把ATM机故障考虑进去
3.不能直接输入账户名和卡号等等信息,模拟出插银行卡让ATM机自动读取卡信息
4.密码验证超过三次错误即锁定账户
5.操作类型有:存款,取款,查询,转账,打印凭条,退卡,一共六个选项,跟用户输入做出不同的反馈
6.当用户正常进入,列出操作类型,每次操作结束后都要重新选择操作类型,只有退卡操作才会结束
7.操作结束后,数据要同步更新
8.要有日志文件,每个涉及到钱走向的操作都要有日志记录
分析:
同样的没什么可说的,根据生活中的场景来就行
关键的问题:怎么模拟插卡操作,让ATM机自动获取信息,方法有:
1.调用API接口读取卡信息,但基本实现起来很难,除非真的搞来一个和现实中的ATM机一样的读卡设备
2.我想了很久,用一个文本文档,里面存放有卡号,用户名等基本信息,然后导入文本的数据来模拟插卡操作,剩下的操作就简单了
我希望你已经思考过再看的下面:
源代码及相关文件源码下载地址:传送门
需要四个文件:
主程序ATM.py
#!usr/bin/env python #-*- coding:utf-8 -*- # author:yangva # datetime:2017/12/16 0015 13:32 import random,time atm_fault = random.randint(0,100) #ATM机随机故障系数 if atm_fault == 0: print('ATM出现故障,暂时不可用,抱歉给您带来不便') else: print('ATM播放幻灯片,推销新业务(信用卡办理,VIP会员特权,新卡新功能等等)') #插入卡操作 try: #模拟读卡的操作,这里用文本文档代替 card = open(input('欢迎光临,请在下方插入口插入您的银行卡(输入文本文件路径和文件名):')) print('正在读卡,请稍后。。。') time.sleep(2) f = eval(card.read()) username = list(f.keys())[0] #取出账户名 user_id = f[username]['ID'] #取出银行卡号 except (NameError,IOError,FileNotFoundError): #输入的文本不存在则捕获 print('插入卡操作过程有误,请检查是否存在该文件或打开该文件的权限') else: f = open('database.txt','r') database = eval(f.read()) f.close() #这里不用with 语句,为保证数据库文件能立即关闭 print('%s先生,欢迎您!!!'%username[0]) #问候语 if username not in database.keys(): print('您的账户已冻结,请本人携带身份证到银行柜台解冻\n已退卡,请收好您的银行卡') else: password = input('请输入您的密码(密码为6位数字),请注意周围环境以及遮挡键盘操作:').strip() #后期可以改为语言提示 count = 0 #用于操作计数 ctrl_flag = False #标志位,用于跳出多层循环 while not ctrl_flag: if count == 2: print('您已输入多次错误密码,银行账户已冻结') with open('log.txt','a') as f2: #写入日志 database['freeze'+username] = database.pop(username) f1 = open('database.txt','w') #同样的,不用with语句,保证数据文件立即关闭 f1.write(str(database)) f2.write(str(time.strftime("%Y %b %d %X"))+'\n用户 %s 的银行卡已冻结\n'%user_id) f1.close() ctrl_flag = True break if len(str(password)) == 6: #用于判断输入的密码位数是否正确 if password == database[username]['password']: database_bk = database #做临时备份数据的操作,方便后面出错时会滚 temp = '' #凭条 while not ctrl_flag: cont = input('1.取款\n2.存款\n3.转账\n4.查询\n5.打印凭条\n6.退卡\n请选择交易类型(输入对应的序号即可):') #账户主体操作 if cont == '1': #取款 withdraw_money = int(input('请输入取款金额(最低一百):')) #ATM存取都是100的整数,直接用int类型 if withdraw_money %100 == 0: print('正在点钞,请稍后。。。') if withdraw_money > database[username]['balance']: print('操作失败,您输入的金额大于您的余额总数') else: time.sleep(3) print('已成功出钞,请取走您的钞票 %s元'%withdraw_money) database[username]['balance'] -= withdraw_money with open('log.txt','a') as f: #写入日志 f.write(str(time.strftime("%Y %b %d %X"))+'\t卡号为 %s 的用户 %s 取出金额:%d\n'%(user_id,username,withdraw_money)) temp += str(time.strftime("%Y %b %d %X"))+'\t取款金额:%d\n'%withdraw_money #记录凭条 else: print('输入金额不是100的整数倍,请重新输入') elif cont == '2': #存款 save_money = int(input('请将钞票叠好,并整齐放入存钞口(输入存款金额):')) #ATM存取款都是100的整数,直接用int类型 print('正在点钞,请稍后。。。') time.sleep(3) print('%s 元已成功存入账户 %s\t账户名 %s'%(save_money,user_id,username)) database[username]['balance'] += save_money with open('log.txt','a') as f: #写入日志 f.write(str(time.strftime("%Y %b %d %X"))+'\t卡号为 %s 的用户 %s 已存入金额 %d\n'%(user_id,username,save_money)) temp += str(time.strftime("%Y %b %d %X"))+'\t存入金额:%d\n'%save_money elif cont == '3': #转账 transfer_id = input('请输入转账帐户卡号:') transfer_user = input('请输入帐户名:') if transfer_id == database[transfer_user]['ID']: transfer_money = float(input('请输入转账金额:')) print('正在转账,请稍后。。。') time.sleep(3) database[username]['balance'] -= transfer_money database[transfer_user]['balance'] += transfer_money with open('log.txt','a') as f: #写入日志 f.write(str(time.strftime("%Y %b %d %X"))+'\t卡号为 %s 的用户 %s 转出金额为 %d 给卡号为 %s 的用户 %s\n'%(user_id,username,transfer_money,transfer_id,transfer_user)) print('成功转账 %s 给卡号为 %s 的用户 %s'%(transfer_money,transfer_id,transfer_user)) temp += time.strftime("%Y %b %d %X")+'\t向卡号为 %s 的用户 %s 转账 %d \n'%(transfer_id,transfer_user,transfer_money) else: print('输入的卡号为 %s 的用户名为 %s 账户有误,原因可能账户信息不匹配或被冻结'%(transfer_id,transfer_user)) elif cont == '4': #查询 print('您的余额为:%.2f'%database[username]['balance']) elif cont == '5': #打印凭条 print(temp) elif cont == '6': #退卡 print('正在退卡。。') time.sleep(1) print('请取走您的银行卡,感谢使用') ctrl_flag = True break else: print('序号输入有误,可能不存在序号%s 对应的选项'%cont) else: count +=1 password = input('输入有误,您还有 %s 次机会\n请重新输入:'%(3-count)).strip() else: count +=1 password = input('密码仅为6位数字,您还有 %s 次机会\n请重新输入: '%(3-count)).strip() with open('log.txt','a') as f1: #写入日志 f2 = open('database.txt','w') f2.write(str(database)) f1.write(str(time.strftime("%Y %b %d %X"))+'\t修改数据库文件\n') f2.close()
日志文件log.txt(自动生成,初始状态为空)
模拟的银行卡文件card.txt
{'yang':{'password':'111111','ID': '6662008891880688689'}}
数据文件database.txt
{'ling': {'password': '123456', 'ID': '6662008891880688688', 'balance': 500.86}, 'liu': {'password': '888888', 'ID': '6662008891880688687', 'balance': 200000.0}, 'tian': {'password': '00000', 'ID': '6662008891880688680', 'balance': 448.03}, 'liang': {'password': '666666', 'ID': '6662008891880688681', 'balance': 522.5}, 'yang': {'password': '111111', 'ID': '6662008891880688689', 'balance': 21310.0}}
结果测试:
运行环境随便你了
(截图只展示了部分,全部效果自己去体验吧)
总结优化:
1.其实不光是这个ATM机,前面的几个项目里都可以用函数或者类来实现功能,如果你们感兴趣可以用函数或者类来操作。(为什么不用函数的原因后期有空再说)。其实我现在都还正在优化中,尽量的简化代码但功能又只增不减那种
2.相信聪明的你已经发现了,程序还没有加入取款当天内只能取多少,存款存多少(单次最多存取多少)的限制,这个就自己去优化了
3.可以优化和扩展的功能还有很多,你可以做成图形化界面,也可以编译成exe可执行文件,尽量的做到和真实的ATM机一样的功能,那你就牛逼了
洗礼灵魂,修炼python(77)--全栈项目实战篇(5)—— ATM自动存取机系统的更多相关文章
- 洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)
本次项目相当于对python基础做总结,常用语法,数组类型,函数,文本操作等等 本项目在博客园里其他开发者也做过,我是稍作修改来的,大体没变的 项目需求: 信用卡+商城: A.信用卡(类似白条/花呗) ...
- 洗礼灵魂,修炼python(73)--全栈项目实战篇(1)——【转载】前提准备之学习ubuntu
本篇是为项目实战做准备,学习Linux是必备的,不然都不好意思叫全栈对吧?下面是一位资深大神写的文章,够详细,我也不用浪费时间再写了 原文链接:Ubuntu学习——第一篇 内容: 一. Ubuntu简 ...
- 洗礼灵魂,修炼python(78)--全栈项目实战篇(6)—— 多级目录菜单之地址管理系统
相信各位都在在网上买过东西吧?那么今天我的主题就是写个在线购物系统,是不可能的,哈哈(后期确实有这个项目),那么购物都填写过快递地址吧?然后网上查个地址都有地址管理吧? 要求: 1.打印出省.市.县等 ...
- 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天
由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...
- 洗礼灵魂,修炼python(80)--全栈项目实战篇(8)—— 计算器
用正则表达式开发一个计算器,计算用户给定的一串带有加减乘除的公式. 要求:不能使用eval转换字符串 分析: 要求简单,就是计算混合运算,但是不能使用eval直接转换,主要就是把整个式子中的小括号优先 ...
- 洗礼灵魂,修炼python(79)--全栈项目实战篇(7)—— 多级目录菜单之地址管理系统升级版
要求: 1.在上一篇的地址管理系统的基础上做升级改动 2.添加增删改的功能 3.尽量的贴近生活常识中的地址管理 分析: 需求不用多说了,干就完了 相关文件源码地址:github 这次由于要有增删改的操 ...
- 洗礼灵魂,修炼python(75)--全栈项目实战篇(3)—— 账户注册登录管理系统
要求: 1.系统可以创建用户和登录用户,根据用户的输入不同,做出不同的反应(创建还是登录) 2.创建用户不能创建已存在的用户名 3.登录用户的操作最多只能有三次,超过三次冻结账户,每使用一次提示用户还 ...
- 洗礼灵魂,修炼python(81)--全栈项目实战篇(9)—— 购物商城登录验证系统
都在线购物过吧?那么你应该体验过,当没有登录账户时,点开购物车,个人中心,收藏物品等的操作时,都会直接跳转到登录账户的界面,然后如果登录一次后就不用再登录,直到用户登出. 是的,本次项目就是做一个登录 ...
- 洗礼灵魂,修炼python(76)--全栈项目实战篇(4)—— 购物车系统
要求: 1.基本符合日常购物车的要求(根据你的想法开放性提升功能) 2.展示商品信息,并且可随时上新商品 3.用户购买每一样商品时都对所剩的钱做一次对比,如果够则提示“已购买”,如果不够提示“余额不足 ...
随机推荐
- 【原创】Python第二章——行与缩进
Python的基本组成——逻辑行和缩进 a="我是一个物理行" a="""我是一个逻辑行 因为我一条语句便跨越了2个物理行""&q ...
- kubernetes 安装kong、kong-ingress-controlor
一.关于kong的详细内容这里不再赘述,可以查看官网. kong升级到1.0以后功能越来越完善,并切新版本的kong可以作为service-mesh使用,并可以将其作为kubernetes的ingre ...
- nginx部署django应用
Django部署方式有很多种,之前写过一篇部署在Apache上的博文:https://www.cnblogs.com/shenh/p/7552722.html .下文介绍的是通过Nginx来部署. N ...
- Mycat - 高可用与负载均衡实现,满满的干货!
前言 开心一刻 和朋友去吃小龙虾,隔壁桌一个小女孩问妈妈:"妈妈,小龙虾回不了家,它妈妈会不会着急?" 她妈妈愣住了,我扒虾的手停下了,这么善良的问题,怎么下得了口.这是老板急忙过 ...
- shell高效处理文本(1):xargs并行处理
xargs具有并行处理的能力,在处理大文件时,如果应用得当,将大幅提升效率. xargs详细内容(全网最详细):https://www.cnblogs.com/f-ck-need-u/p/592592 ...
- 快速制作gif动图
0.环境准备 gif动画录制工具,下载后可以直接安装: 安装提示需要.net framework4.0.30319环境的话,下载一个直接安装即可 1.开始录制 安装成功界面: 开始录制: 录制效果如下 ...
- CIL中间语言浅谈
CIL中间语言 通用中间语言(Common Intermediate Language,简称CIL)(曾经被称为微软中间语言或MSIL)是一种属于通用语言架构和.NET框架的低阶(lowest-lev ...
- 使用浏览器自定义协议启动本地程序(.EXE文件)
比如,自定义协议名称为 myapp,要启动的本地程序为 myapp.exe. 1)首先向注册表添加如下内容: Windows Registry Editor Version 5.00 [HKEY_CL ...
- 【Spring】使用Spring和AMQP发送接收消息(下)
上篇讲了使用RabbitMQ发送消息,本篇则来讲接收消息.在传统JMS中有两种从队列获取信息的方式,使用JmsTemplate的同步方式以及使用消息驱动pojo的异步方式.Spring AMQP也提供 ...
- JS基础(一)dom小实例
DOM的新增示例 <script language="JavaScript"> window.onload = function(){ //createDocument ...