1 ATM实战项目说明文档

模拟实现银行ATM机的操作系统,完整项目见资源https://download.csdn.net/download/weixin_44410704/85191854

1.1 项目基本功能

ATM系统主要功能:(要求使用类实现)

  • 1.注册:用户名、手机号、身份证号、密码(两次确认,长度6位)
  • 2.查询:账号必须存在,密码(三次机会,不对就锁卡)
  • 3.取款:账号必须存在,密码(三次机会,不对就锁卡),取款金额不能大于存款
  • 4.存款:账号必须存在,密码(三次机会,不对就锁卡),存款金额不能低于0
  • 5.转账:两个账户都必须存在,密码(三次机会,不对就锁卡),转账金额不能超过余额
  • 6.锁卡:账号存在,可以使用密码/身份证号冻结
  • 7.解卡:账号存在,只能使用身份证号解卡
  • 8.补卡:使用身份证补卡,每个身份证只有一张卡,之前的卡作废
  • 9.改密:账号存在,使用原密码/身份证号改密
  • 0.退出:保存数据

1.2 项目基本结构

ATM/
│  main.py
│  README.md
│
├─databases
│      cardid.txt
│      userid.txt
│      __init__.py
│
├─packages
│  │  cardclass.py
│  │  controllerclass.py
│  │  personclass.py
│  │  viewclass.py
│  └─__init__.py
│
└─Transaction_records100001.txt100002.txt__init__.py

1.3 运行环境

  • 系统:windows
  • 版本:python 3.9+
  • 其他:无

1.4 待开发功能(已开发)

给当前ATM增加一个交易记录的功能(存折),每次金额变动都存储下来

记录的格式:

  • [日期 时间]存款200元,余额300元
  • [日期 时间]转账 向用户:张三,卡号:******转账100元,余额200元

1.5 项目开发流程(学习用)

  • (1)定义各个类(属性写完整)—方法实现框架即可(可先不写详细)
  • (2)实现main
  • (3)详细定义类中的方法

1.6 项目代码

main.py

"""
ATM系统主要功能:(要求使用类实现)1.注册:用户名、手机号、身份证号、密码(两次确认,长度6位)2.查询:账号必须存在,密码(三次机会,不对就锁卡)3.取款:账号必须存在,密码(三次机会,不对就锁卡),取款金额不能大于存款4.存款:账号必须存在,密码(三次机会,不对就锁卡),存款金额不能低于05.转账:两个账户都必须存在,密码(三次机会,不对就锁卡),转账金额不能超过余额6.锁卡:账号存在,可以使用密码/身份证号冻结7.解卡:账号存在,只能使用身份证号解卡8.补卡:使用身份证补卡,每个身份证只有一张卡,之前的卡作废9.改密:账号存在,使用原密码/身份证号改密0.退出:保存数据
扩展功能:给当前ATM增加一个交易记录的功能(存折),每次金额变动都存储下来记录的格式:[日期 时间]存款200元,余额300元[日期 时间]转账 向用户:张三,卡号:******转账100元,余额200元
项目分析:
思考需要那些对象?类:1.银行卡:Card卡号:     cardid密码:     password余额:     money是否锁卡:  islock2.用户对象:     Person用户名:     name身份证号:   userid手机号:     phoneNumber卡:        Card 银行卡对象3.控制器对象:Controller  具体的操作控制类1.注册:register2.查询:query3.取款:withdraw4.存款:deposit5.转账:transfer6.锁卡:lock7.解卡:unlock8.补卡:new_card9.改密:change_pwd0.退出:exit4.视图对象:Views(欢迎界面,操作界面)
思考如何存储数据?文件存储:卡号:用户==>user.txt身份证:==>userid.txt
"""
from packages.viewclass import Views
from packages.controllerclass import Controller
import timeclass main:def __init__(self):view = Views()obj = Controller()while True:num = input("请输入您需要使用的操作:")if num == '1':obj.register()time.sleep(2)view.show_operator()elif num == '2':obj.query()time.sleep(2)view.show_operator()elif num == '3':obj.withdraw()time.sleep(2)view.show_operator()elif num == '4':obj.deposit()time.sleep(2)view.show_operator()elif num == '5':obj.transfer()time.sleep(2)view.show_operator()elif num == '6':obj.lock('b')time.sleep(2)view.show_operator()elif num == '7':obj.unlock()time.sleep(2)view.show_operator()elif num == '8':obj.new_card()time.sleep(2)view.show_operator()elif num == '9':obj.change_pwd()time.sleep(2)view.show_operator()elif num == '0':obj.store()breakelse:print("您的输入有误,请重新输入:")view.show_operator()run = main()

cardclass.py

class Card:def __init__(self,cardid,pwd,islock=False,money=10):self.password = pwd  # 密码self.money = money  # 余额self.islock = islock  # 卡号是否已锁,True表示已锁,False表示未锁self.cardid = cardid  # 卡号

controllerclass.py

from packages.cardclass import Card
from packages.personclass import Person
import os
import pickle
import timeclass Controller:def __init__(self):#  以下列表中,每个用户的相关信息的索引是一样的,比如用户1的个人信息在personlist[1]中,则其卡信息在cardlist[1]中,#  卡号在cardidlist[1]中,身份证号在useridlist[1]中,姓名在namelist[1]中,即相关信息的索引都是1self.personlist = []  # 存储所有的用户,Person类的实现self.cardlist = []  # 存储所有的卡,Card的实现self.cardidlist = []  # 存储所有的卡号self.namelist = []  # 存储所有的姓名self.useridlist = []  # 存储所有的身份证号self.data_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']  # 就是存储一个字典,方便检查某个输入输入是否为数字#  读取userid.txt中的数据,将其存储到相应的列表中if os.path.getsize('./databases/userid.txt') > 0:with open('./databases/userid.txt', 'rb') as fp:try:while True:self.personlist = pickle.load(fp)  # 这里就是为了读出所有的对象except EOFError:  # 就是防止对象读完之后报错EOFErrorfor i in self.personlist:self.namelist.append(i.name)self.useridlist.append(i.userid)#  读取cardid.txt中的数据,将其存储到相应的列表中if os.path.getsize('./databases/cardid.txt') > 0:with open('./databases/cardid.txt', 'rb') as fp:try:while True:self.cardlist = pickle.load(fp)  # 这里就是为了读出所有的对象except EOFError:  # 就是防止对象读完之后报错EOFErrorfor i in self.cardlist:self.cardidlist.append(i.cardid)def register(self):name = self.__getusername()userid = self.__getuserid()phoneNumber = self.__getphoneNumber()cardid = 100000 + len(self.personlist)  # 第一个卡号为100000,后面每增加一个用户,卡号增加1while str(cardid) in self.cardidlist:  # 由于换卡的存在,增加用户卡号增加1会导致卡号相同,为了避免这种情况出现而设置的机制cardid += 1cardid = str(cardid)pwd = self.__getpassword()person = Person(name, userid, phoneNumber, cardid)card = Card(cardid, pwd)self.cardlist.append(card)  # 注册一个用户就将其信息添加到相应的信息列表中self.personlist.append(person)self.namelist.append(name)self.useridlist.append(userid)self.cardidlist.append(cardid)print(f"注册成功,卡号为{cardid}")self.store()  # 注册一个用户就存储,保证用户信息存储到对应的.txt文件中def query(self):idx = self.login()  # 这个函数是起到登录的作用if idx != 'a':print(f"卡号:{self.cardlist[idx].cardid},余额:{self.cardlist[idx].money}")def withdraw(self):idx = self.login()if idx != 'a':while True:num = int(input("请输入取出金额:"))if num > self.cardlist[idx].money:print("取出金额不可大于余额!")continueelse:if self.input_pwd(self.cardidlist[idx]):  # 这个函数检查输入的密码是否正确self.cardlist[idx].money -= numprint(f"卡号:{self.cardlist[idx].cardid},余额:{self.cardlist[idx].money}")file_url = f'./Transaction_records/{self.cardlist[idx].cardid}.txt'content = time.strftime('%Y-%m-%d %H:%M:%S') + f'##卡号:{self.cardlist[idx].cardid},取款:{num}元,余额:{self.cardlist[idx].money}元\n'with open(file_url, 'a+',encoding='utf-8') as fp:fp.write(content)self.store()  # 取款后就就存储,保证用户信息更新到对应的.txt文件中breakelse:print("转账失败!")breakdef deposit(self):idx = self.login()if idx != 'a':while True:num = int(input("请输入存储金额:"))if self.input_pwd(self.cardidlist[idx]):self.cardlist[idx].money += numprint(f"卡号:{self.cardlist[idx].cardid},余额:{self.cardlist[idx].money}")file_url = f'./Transaction_records/{self.cardlist[idx].cardid}.txt'content = time.strftime('%Y-%m-%d %H:%M:%S') + f'##卡号:{self.cardlist[idx].cardid},存款:{num}元,余额:{self.cardlist[idx].money}元\n'with open(file_url, 'a+', encoding='utf-8') as fp:fp.write(content)self.store()  # 存款后就就存储,保证用户信息更新到对应的.txt文件中breakelse:print("存储失败!")breakdef transfer(self):idx = self.login()if idx != 'a':flag = 1while flag:cardid = input("请输入转账卡号:")if cardid not in self.cardidlist:print("卡号不存在,请重新输入卡号!")continueelse:trfr_idx = self.cardidlist.index(cardid)while True:num = int(input("请输入转账金额:"))if num > self.cardlist[idx].money:print("转账金额不可大于余额!")continueelse:if self.input_pwd(self.cardidlist[idx]):self.cardlist[idx].money -= numself.cardlist[trfr_idx].money += numprint(f"卡号:{self.cardlist[idx].cardid},余额:{self.cardlist[idx].money}")self.store()flag = 0file_url = f'./Transaction_records/{self.cardlist[idx].cardid}.txt'content = time.strftime('%Y-%m-%d %H:%M:%S') + f'##卡号:{self.cardlist[idx].cardid},转账:{num}元,余额:{self.cardlist[idx].money}元\n'with open(file_url, 'a+', encoding='utf-8') as fp:fp.write(content)breakelse:print("密码错误,转账失败!")breakdef lock(self,idx):if idx == 'b':print("不可主动锁卡")else:self.cardlist[idx].islock = Trueself.store()def unlock(self):  # 需要提供身份证号和卡号才可解卡flag = 1while flag:userid = input("请输入身份证号:")if userid not in self.useridlist:print("身份证号不存在,请重新输入!")continueelse:while True:cardid = input("请输入卡号:")if cardid not in self.cardidlist:print("卡号不存在,请重新输入!")continueelse:if self.useridlist.index(userid) != self.cardidlist.index(cardid):print("身份证号和卡号不匹配,解卡失败!")else:self.cardlist[self.useridlist.index(userid)].islock = Falseprint("解卡成功!")self.store()flag = 0breakdef new_card(self):  # 需要输入姓名和身份证号才可补卡flag = 1while flag:name = input("请输入姓名:")if name not in self.namelist:print("姓名不存在,请重新输入!")continueelse:while True:userid = input("请输入身份证号:")if userid not in self.useridlist:print("身份证号不存在,请重新输入!")continueelse:if self.namelist.index(name) != self.useridlist.index(userid):print("姓名和身份证号不匹配,补卡失败!")else:idx = self.useridlist.index(userid)if self.cardlist[idx].islock:print("您的卡号已锁,请先解卡!")breakelse:self.cardlist[idx].cardid = str(100000 + len(self.personlist))cardid = 100000 + len(self.personlist)while str(cardid) in self.cardidlist:cardid += 1self.cardidlist[idx] = str(cardid)self.cardlist[idx].cardid = str(cardid)print(f"补卡成功!新卡号为:{self.cardidlist[idx]}")self.store()flag = 0breakdef change_pwd(self):idx = self.login()flag = 1while flag:password = input("请输入新密码(6位数字):")if len(password) == 6:for i in range(6):if password[i] not in self.data_list:print("新密码必须全部为数字,请重新输入新密码!")breakif i == 5:self.cardlist[idx].password = passwordprint("密码修改成功!")flag = 0self.store()breakelse:print("新密码必须为六位,请重新输入新密码!")def store(self):with open('./databases/userid.txt', 'ab') as fp:pickle.dump(self.personlist, fp)with open('./databases/cardid.txt', 'ab') as fp:pickle.dump(self.cardlist, fp)def __getusername(self):while True:name = input("请输入用户名:")# 检查用户名首字母不能为数字if name[0] in self.data_list:print("首字母不能为数字,请重新输入用户名!")continueelse:# 检查用户名是否已存在if name not in self.namelist:return nameelse:print("用户名已存在,请重新输入用户名!")def __getuserid(self):while True:userid = input("请输入身份证号(8位数字):")if len(userid) == 8:for i in range(8):if userid[i] not in self.data_list:print("身份证号必须全部为数字,请重新输入身份证号!")breakif i == 7:# 检查身份证号是否已存在if userid not in self.useridlist:return useridelse:print("身份证号已存在,请重新输入身份证号!")else:print("身份证号必须为八位,请重新输入身份证号!")def __getphoneNumber(self):while True:phoneNumber = input("请输入电话号码(6位数字):")if len(phoneNumber) == 6:for i in range(6):if phoneNumber[i] not in self.data_list:print("电话号码必须全部为数字,请重新输入电话号码!")breakif i == 5:return phoneNumberelse:print("电话号码必须为六位,请重新输入电话号码!")def __getpassword(self):while True:password = input("请输入密码(6位数字):")if len(password) == 6:for i in range(6):if password[i] not in self.data_list:print("密码必须全部为数字,请重新输入密码!")breakif i == 5:return passwordelse:print("密码必须为六位,请重新输入密码!")def input_pwd(self,cardid):idx = self.cardidlist.index(cardid)pwd = input("请输入密码,您共有3次机会:")num = 2while num:if pwd == self.cardlist[idx].password:return Trueelse:num -= 1pwd = input(f"密码错误,您还有{num + 1}次机会:")print("密码错误,已锁卡,请解卡!")self.lock(idx)return Falsedef login(self):  # 如果返回数字,则登录成功,如果返回字符'a',则登录失败while True:cardid = input("请输入卡号:")if cardid in self.cardidlist:  # 检查身份证号是否存在idx = self.cardidlist.index(cardid)if not self.cardlist[idx].islock:  # 检查卡号是否锁住啦if self.input_pwd(cardid):return idxelse:return 'a'else:print("您的卡号已锁,请解卡!")return 'a'else:print("卡号未注册,请重新输入!")

personclass.py

class Person:def __init__(self,name,userid,phonenumber,cardid):self.name = name  # 用户姓名self.userid = userid  # 用户身份证号self.phoneNumber = phonenumber  # 用户电话号self.cardid = cardid  # 卡号

viewclass.py

import timeclass Views:def __init__(self):self.__show_welcome()print("系统正在启动中,请稍后...")time.sleep(1)self.show_operator()def __show_welcome(self):varstr = '''*******************************************************
*                                                     *
*                                                     *
*                  Welcome to Bank                    *
*                                                     *
*                                                     *
*******************************************************'''print(varstr)def show_operator(self):varstr_operator = '''*******************************************************
*            (1)注册              (2)查询              *
*            (3)取款              (4)存款              *
*            (5)转账              (6)锁卡              *
*            (7)解卡              (8)补卡              *
*            (9)改密              (0)退出              *
*******************************************************'''print(varstr_operator)if __name__ == '__main__':obj = Views()

Python ATM实战相关推荐

  1. python项目实战——银行取款机系统(七)

    项目实战目录 python项目实战--银行取款机系统(一) python项目实战--银行取款机系统(二) python项目实战--银行取款机系统(三) python项目实战--银行取款机系统(四) p ...

  2. python项目实战——银行取款机系统(一)

    项目实战目录 python项目实战--银行取款机系统(一) 前言 今天我们将通过python完成简易银行提款机系统的实战,我们一步步实现我们的要求.话不多说,看操作. 环境使用 python 3.9 ...

  3. python项目实战——银行取款机系统(六)

    项目实战目录 python项目实战--银行取款机系统(一) python项目实战--银行取款机系统(二) python项目实战--银行取款机系统(三) python项目实战--银行取款机系统(四) p ...

  4. 重磅升级,52个Python+OpenCV实战项目教你掌握图像处理

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 近期小白学视觉公众号推出了多篇Python+OpenCV实战项目的 ...

  5. 线程,协程对比和Python爬虫实战说明

    此文首发于我的个人博客:线程,协程对比和Python爬虫实战说明 - zhang0peter的个人博客 这篇文章写的是我对线程和协程的理解,有错误之处欢迎指出. 举一个餐馆的例子.我们把一个餐厅当做一 ...

  6. 阿里P8连肝一周整理出这份python自动化测试实战PDF

    由于细节内容实在太多啦,也为了不影响各位大大观看,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!总共整理了有282页的PDF文档,有需要的可以查看我文章最后. 整理了一份pyt ...

  7. python爬虫图片实例-【图文详解】python爬虫实战——5分钟做个图片自动下载器...

    我想要(下)的,我现在就要 python爬虫实战--图片自动下载器 之前介绍了那么多基本知识[Python爬虫]入门知识(没看的赶紧去看)大家也估计手痒了.想要实际做个小东西来看看,毕竟: talk ...

  8. python自动化测试看什么书-《Python自动化测试实战》终于出版!!!

    一.为什么会写这本书 1.系统梳理.可以加深对测试知识体系的系统梳理 2.名气.增加个人的名气,比如:面试时,可以很自豪的说,我是xxxx书的作者 3.利他.帮助有需要的学习者更系统.完备的学习和进阶 ...

  9. python入门新手项目-Python入门实战项目有哪些适合新手?

    Python入门实战项目有哪些适合新手?目前市面上有很多适合新手的Python入门练手项目,Python入门需要理论与实践相结合,前面夯实基础知识,后面通过实战项目帮助你更好的运用这些Python知识 ...

最新文章

  1. 越南一难倒博士的趣味数学题
  2. 什么是C中的“静态”功能?
  3. AMDF换成ACF和AMDF合作算法
  4. Kaggle知识点:时序数据与Embedding
  5. 【数据结构与算法】之深入解析“最接近的三数之和”的求解思路与算法示例
  6. java 获得响应内容_Java 纯HTTP Get请求获取响应内容,如果302,继而获取重定向后的响应内容。...
  7. VIm中Python自动补全插件Pydiction
  8. java.lang.UnsatisfiedLinkError: Couldn't load XXX
  9. 合作共赢,共同飞跃 | DDG一站式数字化转型集成解决方案正式发布
  10. CHARACTERISTIC DEFINITION
  11. 用python做时间序列预测八:Granger causality test(格兰杰因果检验)
  12. 静态变量和静态方法编程训练—信用卡消费记录
  13. window用户切换
  14. 计算机课学生段密码,启课程学生端电脑版
  15. Matlab2013a学习之男女的声音识别
  16. 织梦文章发布 html仅动态,织梦dedecms采集文章后导出为仅动态的解决方案
  17. 天融信 还有什么型号服务器,天融信日志服务器
  18. 位图与bitblt【位图知识】
  19. AC_AttitudeControl_Heli.cpp的AC_AttitudeControl_Heli::rate_target_to_motor_yaw函数代码分析
  20. xlwings出现的报错

热门文章

  1. 20180517 迭代器
  2. 揭秘Product Hunt怎样运用邮件崛起
  3. 基于ARM的车牌识别技术研究与实现
  4. hdu 3917 Road constructions 最大权闭合子图
  5. JS 将JSON对象转换为字符串
  6. 【译】《Pro ASP.NET MVC4 4th Edition》第三章(二)
  7. 创业与老子的顺其自然
  8. 东方第一等幻象骑士团
  9. leetcode 1223 python
  10. mysql怎么访问网页版_mysql在本地已经启动,但是在网页上不能直接访问的解决...