'''
使用面向对象编程完成ATM系统
1.注册功能:用户名,手机号,身份证号(18位),密码(两次确认,长度6位)
2.查询功能:账号必须存在,密码(三次机会,不对就锁卡)
3.取款功能:账号必须存在,密码(三次机会,不对就锁卡),取款金额不能大于存款
4.存款功能:账号必须存在,存款金额不能低于0
5.转帐功能:你的账户,转款账户都必须存在,密码(三次机会,不对就锁卡),转账金额不能超过余额
6.锁卡功能:账号必须存在,可以使用密码冻结,还可以使用身份证号冻结
7.解卡功能:账号必须存在,只能使用身份证号进行解锁
8.补卡功能:使用身份证进行补卡,每个身份证只能有一张卡,之前的卡作废
9.改密功能:愿密码进行改密,也可以使用身份证进行改密
10.退出功能:保存数据
扩展功能
给当前ATM增加一个交易记录的功能
就像存折一样,每次对金额的变动都需要记录下来
每个银行卡都有自己的交易记录
记录的格式:
[2019/12/12 12:12:12]存款200元,余额300元。
[2019/12/12 13:13:13]转账向用户:张三,卡号: 100100转账100元,余额200元。
'''
main.py
from operation import Operation
#主程序
class Main:
def begin():
while True:
print('***欢迎使用ATM自动存取款系统***')
print('有以下功能可供选择:')
print(' 1.注册 2.查询')
print(' 3.取款 4.存款')
print(' 5.转账 6.锁卡')
print(' 7.解卡 8.补卡')
print(' 9.改密 0.退出')
print('****************************')
n=int(input('请输入序号选择相应功能:'))
if n==1:
o.zhuce()
elif n==2:
o.chaxun()
elif n==3:
o.get_money()
elif n==4:
o.save_money()
elif n==5:
o.trans_money()
elif n==6:
o.lock()
elif n==7:
o.unlock()
elif n==8:
o.new_card()
elif n==9:
o.change_pwd()
elif n==0:
print('退出系统成功,欢迎下次使用!')
o.save()
break
else:
print('输入不符合规范,请重新输入')
if __name__=='__main__':
o = Operation()
Main.begin()
operation.py
from card import Card
from person import Person
import random
import pickle
import os
import time
class Operation():
def __init__(self):
#加载卡号用户
self.load_user()
#加载用户身份证号
self.load_user_id()
#保存
def save(self):
with open('user.txt', 'wb') as f:
pickle.dump(self.user_dict, f)#dump 写入
with open('userid.txt', 'wb') as f:
pickle.dump(self.user_id_dict, f)
#读取
def load_user(self):
#如果文件存在 读取文件内容给字典
if os.path.exists('user.txt'):
with open('user.txt', 'rb') as f:
self.user_dict = pickle.load(f)
else:
#如果不存在 字典为空
self.user_dict = {}
#读取user_id
def load_user_id(self):
#如果文件存在,则进行读取
if os.path.exists('userid.txt'):
with open('userid.txt', 'rb') as f:
self.user_id_dict = pickle.load(f)
#不存在就把user_id_dict设置为空字典
else:
self.user_id_dict = {}
#####################################################################
#1.注册功能:用户名,手机号,身份证号(18位),密码(两次确认,长度6位)
def zhuce(self):
#用户名
while True:
name=input('请输入用户名:')
if name=='' or ' ' in name:
print('用户名不能为空或含有空字符,请重新输入')
else:
self.name =name
break
#手机号
while True:
phone=input('请输入手机号:')
if len(phone)!=11 and phone!='0':#0为代码测试专用
print('手机号长度应该为11位,请重新输入')
else:
self.phone =phone
break
#身份证号(18位)
while True:
user_id=input('请输入身份证号:')
if len(user_id)!=18 and user_id!='0':#0为代码测试专用
print('身份证号长度应该为18位,请重新输入')
else:
self.user_id =user_id
break
#密码(两次确认,长度6位)
while True:
pwd=input('请输入6位密码:')
pwd2=input('再次确认密码:')
if len(pwd)!=6:
print('密码应该为6位,请重新输入')
continue
elif pwd!=pwd2:
print('两次输入密码不相同,请重新输入')
continue
else:
self.pwd = pwd
break
money=10
#调用生成卡号的方法,得到的卡号由card_id接收
self.card_id = self.get_card_id()
# 把卡号,密码,余额传给Card类接收,并由card接收
self.card = Card(self.card_id, self.pwd, money)
# 把用户名,身份证号,手机号,卡对象传给Person类接收,并由person用户接收
self.person = Person(self.name, self.user_id, self.phone, self.card)
#以身份证:卡号 形式存进字典
self.user_id_dict[self.user_id] = self.card_id
#以卡号: 用户 形式存进字典
self.user_dict[self.card_id] = self.person
#打印显示
print('{}开户成功,卡号为{},余额为{}'.format(self.name, self.card_id, money))
#得到一个随机六位数的卡号
def get_card_id(self):
while True:
# 得到一个随机六位数的卡号,如果此六位数的卡号没有在user_id_dict里面,就返回出来
card_id = str(random.randrange(100000, 1000000))
if card_id not in self.user_id_dict:
return card_id
#####################################################################
#2.查询功能: 账号必须存在,密码(三次机会,不对就锁卡)
def chaxun(self):
while True:
card_id = input('请输入卡号:')
if card_id in self.user_dict:
# 取出user_dict里面的card_id对应的值
user = self.user_dict[card_id]
# 再从里面取出相应的卡对象
card = user.card
# 卡号存在,如果状态是islock,那就提示被冻结
if card.islock:
print('此卡被冻结')
break
# 卡号存在,islock是False,就调用输入检测密码的方法
else:
# 相当于return的check_pwd 是true
if self.check_pwd(card):
# card.money 是对象里面的money(在注册用户里)
print('此余额为{}元'.format(card.money))
break
else:
print('此卡号不存在')
# 判断卡号是否存在
def get_card_info(self):
card_id = input('请输入卡号:')
# 如果输入的卡号在user_dict这个字典里
if card_id in self.user_dict:
# 取出user_dict里面的card_id对应的值
user = self.user_dict[card_id]
# 再从里面取出相应的卡对象
card = user.card
return card
else:
print('此卡号不存在')
# 密码不一致锁卡
def check_pwd(self, card):
#定义标志,控制循环为三次
time = 1
while time < 4:
pwd = input('请输入密码:')
# 输入对了就返回
if pwd == card.password:
# 结束循环
return True
print('密码错误,您还有{}次机会'.format(3-time))
time += 1
# 循环结束,也就意味着三次输错,则锁卡
card.islock = True
print('卡被锁定了')
#####################################################################
#3.取款功能: 账号必须存在,密码(三次机会,不对就锁卡),取款金额不能大于存款
def get_money(self):
# card是接收返回的判断卡号是否存在的卡对象
card = self.get_card_info()
if card:
if card.islock:
print('卡已经被冻结了!')
else:
# 调用方法,检查输入的密码 和 卡密码是否相等
self.check_pwd(card)
try:
get_money = float(input('请输入要取的金额:'))
# 判断取钱数额是否小于卡内余额-10 (10元不能取)
if 0 < get_money <= card.money - 10:
card.money -= get_money
print('成功取走了{}元,卡内余额{}元'.format(get_money, card.money))
self.jilu(2,get_money,card.money)#取款
else:
print('卡内余额不足,不可以进行取款')
except:
print('输入不合法')
#####################################################################
#4.存款功能: 账号必须存在,存款金额不能低于0
def save_money(self):
# card是接收返回的判断卡号是否存在的卡对象
card = self.get_card_info()
if card:
# 判断是否锁定
if card.islock:
print('您的卡已被锁定')
else:
#未锁定则从user_dict取出卡号对应的用户对象
user = self.user_dict[card.cardid]
print('存入的账户名为:%s' % (user.name))
num = input('按1存款,其他返回上一层:')
if num == '1':
str_money = input('输入存款金额:')
# 判断如果是纯整数的字符串并且大于0的话,则相应对card.money做加法操作
if str_money.isdecimal() and int(str_money) > 0:
money = int(str_money)
card.money += money
print('成功存入%d' % money)
self.jilu(1,money,card.money)#存款
else:
print('输入的金额有误')
#####################################################################
#5.转帐功能: 你的账户,转款账户都必须存在,密码(三次机会,不对就锁卡),转账金额不能超过余额
def trans_money(self):
# 获取卡号及的卡对象
card = self.get_card_info()
if card:
if card.islock:
print('卡已经被冻结了!')
else:
# 检查输入的密码 和 卡密码是否相等
if self.check_pwd(card):
others_card = input('请输入对方账号:')
if others_card == card.cardid:
print('不能给自己转账,请重新输入卡号')
elif others_card in self.user_dict:
user = self.user_dict[others_card]
num = input('你将给%s进行转账,确认请输入1,返回主菜单输入其他键:' % user.name)
if num == '1':
trans_money = input('请输入转账金额:')
try:
trans_money = float(trans_money)
# 卡默认存10元
if 0 < trans_money <= card.money - 10:
user.card.money += trans_money
card.money -= trans_money
print('您向%s功转账%.2f元' % (user.name, trans_money))
self.jilu(3, trans_money, card.money,user.name,card.cardid) #转账记录
else:
print('金额不足')
except:
print('输入不合法!')
else:
print('此卡号不存在,请重新输入')
#####################################################################
#6.锁卡功能:账号必须存在,可以使用密码冻结,还可以使用身份证号冻结
def lock(self):
# 获取卡号及的卡对象
card = self.get_card_info()
if card:
if card.islock:
print('卡之前已经被锁定了!')
else:
num = input('1)使用密码冻结 2)使用身份证冻结:')
if num == '1':
# 检查输入的密码 和 卡密码是否相等
if self.check_pwd(card):
card.islock = True
print('卡被锁定完毕')
elif num == '2':
# 拿身份证号
user_id = input('请输入您的身份证号:')
if user_id.isdecimal() == False:
print('身份证号需要纯数字')
else:
user = self.user_dict[card.cardid]
if user_id == user.userid:
card.islock = True
print('卡已被锁定')
else:
print('身份证号不正确,锁卡失败')
#####################################################################
#7.解卡功能:账号必须存在,只能使用身份证号进行解锁
def unlock(self):
card = self.get_card_info()
if card:
if card.islock == False:
print('卡之前就没有被锁定!')
else:
# 拿身份证号
user_id = input('请输入您的身份证号:')
if user_id.isdecimal() == False:
print('身份证号需要纯数字')
else:
user = self.user_dict[card.cardid]
if user_id == user.userid:
card.islock = False
print('卡已被解锁')
else:
print('身份证号不正确!')
#####################################################################
#8.补卡功能:使用身份证进行补卡,每个身份证只能有一张卡,之前的卡作废
def new_card(self):
# 拿身份证号
user_id = input('请输入您的身份证号:')
if user_id.isdecimal() == False:
print('身份证号需要纯数字')
else:
if user_id in self.user_id_dict:
# 获取card卡号:
card_id1 = self.user_id_dict[user_id]
user1 = self.user_dict[card_id1]
# 删除旧卡号
self.user_id_dict.pop(user_id)
# 获取新卡号
card_id = self.get_card_id()
# 复制给两个字典 更新
self.user_id_dict[user_id] = card_id
self.user_dict[card_id] = user1
print('新卡号:', card_id)
else:
print('身份证不存在!!')
#####################################################################
#9.改密功能: 愿密码进行改密,也可以使用身份证进行改密
def change_pwd(self):
# 获取卡号及的卡对象
card = self.get_card_info()
if card:
if card.islock:
print('卡已经被冻结了!')
else:
num = input('1.原密码改密 2.身份证改密:')
if num == '1':
self.check_pwd(card)
self.check_change_pwd(card)
elif num == '2':
# 拿身份证号
user_id = input('请输入您的身份证号:')
if user_id.isdecimal() == False:
print('身份证号需要纯数字')
else:
user = self.user_dict[card.cardid]
if user_id == user.userid:
self.check_change_pwd(card)
# 新密码的判断函数
def check_change_pwd(self, card):
while True:
new_pwd = input('请输入新密码:')
# self.try_pwd(new_pwd)
new_pwd2 = input('请确认新密码:')
# if self.try_pwd(new_pwd2) != 1:
if new_pwd == new_pwd2:
card.password = new_pwd
print(card.password)
print('修改密码成功')
break
else:
print('两次密码不一致')
break
#####################################################################
#10.退出功能:保存数据
#直接放在主程序中
#####################################################################
#11.交易记录
# 给当前ATM增加一个交易记录的功能
# 就像存折一样,每次对金额的变动都需要记录下来
#
# 每个银行卡都有自己的交易记录
# 记录的格式:
# [2019 / 12 / 12 12: 12:12]存款200元,余额300元。
# [2019 / 12 / 12 13: 13:13]转账向用户: 张三,卡号: 100100
# 转账100元,余额200元。
def jilu(self,n,money,s_money,name=0,card_id=0):
f=open('交易记录.txt','a+')
if n==1:#存款取款
res = time.strftime('%Y / %m / %d %H:%M:%S')
f.write(f'[{res}]存款{money}元,余额{s_money}元。\n')
f.close()
if n==2:#取款
res = time.strftime('%Y / %m / %d %H:%M:%S')
f.write(f'[{res}]取款{money}元,余额{s_money}元。\n')
f.close()
elif n==3:#转账
res = time.strftime('%Y / %m / %d %H:%M:%S')
f.write(f'[{res}]转账向用户:{name},卡号:{card_id},转账{money}元,余额{s_money}元。\n')
f.close()
else:
pass
if __name__=='__main__':
o=Operation()
o.jilu(2,200,300)
person.py
class Person:
def __init__(self, name, userid, phone, card):
self.name = name
self.userid = userid
self.phone = phone
self.card = card
card.py
class Card():
def __init__(self, cardid, password, money):
self.cardid = cardid
self.password = password
self.money = money
self.islock = False