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_records
100001.txt
100002.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.存款:账号必须存在,密码(三次机会,不对就锁卡),存款金额不能低于0
5.转账:两个账户都必须存在,密码(三次机会,不对就锁卡),转账金额不能超过余额
6.锁卡:账号存在,可以使用密码/身份证号冻结
7.解卡:账号存在,只能使用身份证号解卡
8.补卡:使用身份证补卡,每个身份证只有一张卡,之前的卡作废
9.改密:账号存在,使用原密码/身份证号改密
0.退出:保存数据
扩展功能:
给当前ATM增加一个交易记录的功能(存折),每次金额变动都存储下来
记录的格式:[日期 时间]存款200元,余额300元
[日期 时间]转账 向用户:张三,卡号:******转账100元,余额200元
项目分析:
思考需要那些对象?
类:
1.银行卡:Card
卡号: cardid
密码: password
余额: money
是否锁卡: islock
2.用户对象: Person
用户名: name
身份证号: userid
手机号: phoneNumber
卡: Card 银行卡对象
3.控制器对象:Controller 具体的操作控制类
1.注册:register
2.查询:query
3.取款:withdraw
4.存款:deposit
5.转账:transfer
6.锁卡:lock
7.解卡:unlock
8.补卡:new_card
9.改密:change_pwd
0.退出:exit
4.视图对象:Views(欢迎界面,操作界面)
思考如何存储数据?
文件存储:
卡号:用户==>user.txt
身份证:==>userid.txt
"""
from packages.viewclass import Views
from packages.controllerclass import Controller
import time
class 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()
break
else:
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
self.cardid = cardid
controllerclass.py
from packages.cardclass import Card
from packages.personclass import Person
import os
import pickle
import time
class Controller:
def __init__(self):
self.personlist = []
self.cardlist = []
self.cardidlist = []
self.namelist = []
self.useridlist = []
self.data_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
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:
for i in self.personlist:
self.namelist.append(i.name)
self.useridlist.append(i.userid)
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:
for 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)
while str(cardid) in self.cardidlist:
cardid += 1
cardid = 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()
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("取出金额不可大于余额!")
continue
else:
if self.input_pwd(self.cardidlist[idx]):
self.cardlist[idx].money -= num
print(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()
break
else:
print("转账失败!")
break
def deposit(self):
idx = self.login()
if idx != 'a':
while True:
num = int(input("请输入存储金额:"))
if self.input_pwd(self.cardidlist[idx]):
self.cardlist[idx].money += num
print(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()
break
else:
print("存储失败!")
break
def transfer(self):
idx = self.login()
if idx != 'a':
flag = 1
while flag:
cardid = input("请输入转账卡号:")
if cardid not in self.cardidlist:
print("卡号不存在,请重新输入卡号!")
continue
else:
trfr_idx = self.cardidlist.index(cardid)
while True:
num = int(input("请输入转账金额:"))
if num > self.cardlist[idx].money:
print("转账金额不可大于余额!")
continue
else:
if self.input_pwd(self.cardidlist[idx]):
self.cardlist[idx].money -= num
self.cardlist[trfr_idx].money += num
print(f"卡号:{self.cardlist[idx].cardid},余额:{self.cardlist[idx].money}")
self.store()
flag = 0
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)
break
else:
print("密码错误,转账失败!")
break
def lock(self,idx):
if idx == 'b':
print("不可主动锁卡")
else:
self.cardlist[idx].islock = True
self.store()
def unlock(self):
flag = 1
while flag:
userid = input("请输入身份证号:")
if userid not in self.useridlist:
print("身份证号不存在,请重新输入!")
continue
else:
while True:
cardid = input("请输入卡号:")
if cardid not in self.cardidlist:
print("卡号不存在,请重新输入!")
continue
else:
if self.useridlist.index(userid) != self.cardidlist.index(cardid):
print("身份证号和卡号不匹配,解卡失败!")
else:
self.cardlist[self.useridlist.index(userid)].islock = False
print("解卡成功!")
self.store()
flag = 0
break
def new_card(self):
flag = 1
while flag:
name = input("请输入姓名:")
if name not in self.namelist:
print("姓名不存在,请重新输入!")
continue
else:
while True:
userid = input("请输入身份证号:")
if userid not in self.useridlist:
print("身份证号不存在,请重新输入!")
continue
else:
if self.namelist.index(name) != self.useridlist.index(userid):
print("姓名和身份证号不匹配,补卡失败!")
else:
idx = self.useridlist.index(userid)
if self.cardlist[idx].islock:
print("您的卡号已锁,请先解卡!")
break
else:
self.cardlist[idx].cardid = str(100000 + len(self.personlist))
cardid = 100000 + len(self.personlist)
while str(cardid) in self.cardidlist:
cardid += 1
self.cardidlist[idx] = str(cardid)
self.cardlist[idx].cardid = str(cardid)
print(f"补卡成功!新卡号为:{self.cardidlist[idx]}")
self.store()
flag = 0
break
def change_pwd(self):
idx = self.login()
flag = 1
while flag:
password = input("请输入新密码(6位数字):")
if len(password) == 6:
for i in range(6):
if password[i] not in self.data_list:
print("新密码必须全部为数字,请重新输入新密码!")
break
if i == 5:
self.cardlist[idx].password = password
print("密码修改成功!")
flag = 0
self.store()
break
else:
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("首字母不能为数字,请重新输入用户名!")
continue
else:
if name not in self.namelist:
return name
else:
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("身份证号必须全部为数字,请重新输入身份证号!")
break
if i == 7:
if userid not in self.useridlist:
return userid
else:
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("电话号码必须全部为数字,请重新输入电话号码!")
break
if i == 5:
return phoneNumber
else:
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("密码必须全部为数字,请重新输入密码!")
break
if i == 5:
return password
else:
print("密码必须为六位,请重新输入密码!")
def input_pwd(self,cardid):
idx = self.cardidlist.index(cardid)
pwd = input("请输入密码,您共有3次机会:")
num = 2
while num:
if pwd == self.cardlist[idx].password:
return True
else:
num -= 1
pwd = input(f"密码错误,您还有{num + 1}次机会:")
print("密码错误,已锁卡,请解卡!")
self.lock(idx)
return False
def login(self):
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 idx
else:
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 time
class 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()
|