(新人如若写的不好望海涵)
设计一个ATM存取款机小程序,实现以下功能:
1、开卡功能:根据用户的用户名、身份证号、手机号、密码进行开卡,自动生成6位卡号,并卡内存入10元
用户名:不能为空,只能为数字字母下划线
身份证号:卡死生日年月日部分,不能出现日期以外的数字,18位数字(或+x 19位),一个身份证只能绑定一个卡号
手机号:只能按照标准手机号码格式输入
密码:固定6位,数字字母下划线
卡号:生成卡号不能出现重复
2、查询功能:用户根据卡号、密码进行余额查询,密码输错3次自动冻结卡号,已冻结卡号不能进行查询
3、存款功能:输入卡号进行存款,存入金额不能为小数、负数
4、取款功能:用户根据卡号、密码进行取款,取款金额不能为小数、负数,密码输错3次自动冻结卡号,已冻结卡号不能进行取款
5、转帐功能:用户根据自身卡号,给其他卡进行转账,转账金额不能为小数或负数,不能给自己转账,密码输错三次后冻结卡号,已冻结卡号不能进行转账
6、改密功能:用户输入卡号,可根据原密码或身份证号码进行改密,新密码必须严格遵循密码设定规则
7、锁卡功能:用户输入卡号,可根据原密码或身份证号进行锁卡,锁卡后冻结此卡号,已冻结卡号无法再进行锁卡
8、解卡功能:用户输入卡号,可根据原密码或身份证号进行解卡,解卡后解除此卡号的冻结状态,未冻结卡号无法进行解卡
9、补卡功能:直接根据身份证号进行补卡操作,生成一个新卡号,新卡继承原卡除卡号外的所有信息(包括冻结状态),删除原卡,原卡作废
10、修改绑定手机:用户可通过身份证修改绑定手机信息(需确认卡密码,密码输入错误则不能对绑定手机进行修改),修改后的手机号不能与原手机号相同
11、结束操作:用户操作完成后ATM自动保存修改信息并退出操作界面
在此项目中,我们需要构建4个模块文件,分别是卡(Card)模块、用户(Person)模块、操作(Operation)模块以及视图(View)模块,最后用单入口模式通过一个主文件(main)来调用。
1、Card模块:用来初始化卡信息,成员包括卡号、密码、金额以及冻结状态
2、Person模块:用来初始化用户信息,成员包括用户名、身份证号、手机号以及card对象(用户拥有一个卡对象)
3、View模块:ATM对用户的展示页面,提醒用户可进行的操作
4、Operation模块:在此模块中,我们需要罗列出两个字典,用来存储用户与卡之间的对应,第一个字典存储{卡号:用户对象},拥有这个字典,我们就可以通过卡号提取出用户对象,因为用户对象成员中存在卡对象,借由用户对象,我们继而可以提取出卡对象中的成员,第二个字典存储{身份证:卡号},拥有这个字典,我们就可以通过身份证提出出对应的卡号,我们在操作过程中,就可以形成一个:身份证—>卡号—>用户对象—>卡对象 的调用关系,将这两个字典以字节流的形式存储在文件中(因为字节流可存储一切数据),以便于我们第二次打开程序时用户卡信息不丢失
成员方法(功能):
1)开卡(register):在此方法中,我们需要通过正则匹配来完成用户以及卡信息的注册,并根据Card类以及Person类传入对应初始化参数分别生成card和user对象,并根结以上要求存入字典当中,最后将开卡展示给用户
2)查询(query):在此方法中,用户输入卡号,我们需对卡号先做一个判断,如果卡号不存在,给用户展示卡不存在的报错信息,如果存在,继续检测卡是否被冻结,如未被冻结,我们继续判断密码,密码正确获取卡金额,如不正确提示密码错误,并进行冻结计数
3)存钱(save_money):在此方法中,我们只需判断卡号是否存在,如存在,则通过用户对象获取卡对象,并调用卡对象的money方法进行存钱操作,存储金额只能是数字且不能为0或负数
4)取钱(get_money):此方法前半部分判断方法和查询操作一致,在判断完卡密码是否正确之后,继续进行存储金额格式判断,只能是数字且不能出现0或负数,所有判断通过后进行取钱操作
5)转账(trans):在此方法中,同样存在卡号、密码及冻结判断,我们需对两个卡对象进行操作,用户的卡需扣除金额,扣除的金额不能大于卡内总金额,收款方的卡需存入对应金额,并且需判断转账方与收款方的两个卡号是否相同,如相同,则提示不能给自己转账
6)改密(change_pwd):在此方法中,存在卡号、及冻结判断,需罗列出两种改密码方式:1、通过原密码改密 2、通过身份证改密,并通过判断实现对应的改密功能
7)锁卡(lock):锁卡方法需要判断卡是否已被冻结,如果卡被冻结,需提示用户卡已被冻结,不能重复锁卡,锁卡方式有密码锁卡和身份证号锁卡两种,如果我们输入身份证号或密码错误,则锁卡失败,由于我们card对象中默认开卡为未冻结状态(False),此时需要我们手动将card的islock属性改为True
8)解卡(unlock):原理与锁卡相同,将card的islock属性改为False
9)补卡(new_card):补卡因为新卡需继承旧卡除了卡号外的所有属性,故我们可以通过Card类创建一个新对象,其默认参数为旧卡的所有属性,然后动态将新卡号替换到新对象,再把新对象传给用户对象,给两个字典重新根据新对象赋值,并删除对应旧元素,完成补卡操作
10)修改绑定手机(change_phone):根据身份证找到对应绑定手机,输入新手机号,判断新手机号不能与旧手机号相同,如果不相同,执行替换操作,完成修改
1、包结构:
采用单入口模式,主文件ATMmain.py与包同一层级
2、card模块
初始化卡对象
class Card():
def __init__(self,cardid,password,money):
self.cardid=cardid
self.password=password
self.money=money
self.islock=False
3、person模块
初始化用户对象
class Person():
def __init__(self,name,userid,phone,card):
self.name=name
self.userid=userid
self.phone = phone
self.card=card
4、view模块
用户视图
import time
class View():
def admin_login():
usr=input("请输入用户名:")
passwd=input("请输入密码:")
if usr == "admin" and passwd == "Abc123!":
View.welcome()
time.sleep(0.5)
print("请稍后...")
time.sleep(1)
View.operation_view()
return True
else:
print("管理员账号或密码不正确!")
def welcome():
strvar=" "
print(43*"*")
print("*{:41s}*".format(strvar))
print("*{:41s}*".format(strvar))
print("*{:^40s}*".format("@~Welcome Come Wzy's Bank~@"))
print("*{:41s}*".format(strvar))
print("*{:41s}*".format(strvar))
print(43*"*")
def operation_view():
print(43*"*")
print("* 开户(1) 查询(2) *")
print("* 存钱(3) 取钱(4) *")
print("* 转账(5) 改密(6) *")
print("* 锁卡(7) 解卡(8) *")
print("* 补卡(9) 修改绑定手机(10) *")
print("*-----------------退出(0)------------------*")
print(43*"*")
if __name__=="__main__":
View.admin_login()
5、operation模块
用户执行操作后端处理逻辑
import os
import pickle
import re
import random
from .card import Card
from .person import Person
class Operation():
def __init__(self):
self.get_usr_card()
self.get_usrid_card()
def get_usr_card(self):
if os.path.exists("usr_card.txt"):
with open("usr_card.txt",mode="rb") as fp:
self.usr_card=pickle.load(fp)
else:
self.usr_card={}
def get_usrid_card(self):
if os.path.exists("usrid_card.txt"):
with open("usrid_card.txt",mode="rb") as fp:
self.usrid_card=pickle.load(fp)
else:
self.usrid_card={}
def save(self):
with open("usr_card.txt",mode="wb") as fp:
pickle.dump(self.usr_card,fp)
with open("usrid_card.txt",mode="wb") as fp:
pickle.dump(self.usrid_card,fp)
print("<-----已完成业务办理,欢迎下次光临!----->")
def register(self):
#设置用户名
name = self.get_name()
#绑定身份证号
userid = self.get_userid()
#输入手机号
phone = self.get_phone()
#设置卡密码
pwd = self.get_pwd()
#获取卡号
cardid = self.get_cardid()
#设置余额
money = 10
#创建一个卡
card=Card(cardid,pwd,money)
#创建一个用户
user=Person(name,userid,phone,card)
#卡号:用户对象
self.usr_card[cardid]=user
#身份证:卡号
self.usrid_card[userid]=cardid
print("恭喜{}开卡成功,您的卡号为{},余额为{}".format(name,cardid,money))
def get_name(self):
while True:
user=input("请输入用户名:")
if re.findall("^\w*$",user) == [] or user == "":
print("用户名格式不正确")
else:
return user
def get_userid(self):
while True:
userid = input("请输入您的身份证号:")
if userid in self.usrid_card:
print("此身份证已注册,请勿重复开卡")
else:
res = re.findall("^\d{6}[12]\d{3}(?:0[1-9]|1[12])(?:0[1-9]|1[0-9]|2[0-9]|3[01])\d{4}[x]?$",userid)
if res == []:
print("身份证格式不正确,请重新输入")
else:
return userid
def get_phone(self):
while True:
phone = input("请输入手机号:")
res = re.findall("^1[3-9]\d{9}$",phone)
if res == []:
print("手机号格式不正确,请重新输入")
else:
return phone
def get_pwd(self):
while True:
pwd1 = input("请输入密码:")
res = re.findall("^\w{6}$", pwd1)
if res == []:
print("密码必须为6位,要求:数字、字母、下划线")
else:
pwd2 = input("请确认密码:")
if pwd1 == pwd2:
return pwd1
else:
print("密码不正确,请重新输入")
def get_cardid(self):
while True:
cardnum=str(random.randrange(100000,1000000))
if cardnum not in self.usr_card:
return cardnum
def query(self):
#获取卡相关信息
card= self.get_card_info()
if not card:
print("卡号不存在!")
else:
if card.islock:
print("您的卡已被冻结")
else:
i = 1
while i < 4:
pwd=input("请输入密码:")
if pwd == card.password:
print("您当前卡上余额为{}".format(card.money))
break
else:
print("密码不正确,剩余{}此机会".format(3-i))
if i == 3:
card.islock=True
print("您的卡已被冻结")
i += 1
def get_card_info(self):
cardid=input("请输入您的卡号:")
if cardid not in self.usr_card:
print(self.usr_card)
return False
else:
user=self.usr_card[cardid]
return user.card
def save_money(self):
card = self.get_card_info()
if not card:
print("卡号不存在!")
else:
user=self.usr_card[card.cardid]
print("您这张卡用户名为{}".format(user.name))
info=input("确认存款请按1,任意按键回上一层!")
if info == "1":
while True:
money=input("请输入存款金额:")
if money.isdecimal() and int(money) > 0:
money= int(money)
card.money += money
print("成功存入{}元".format(money))
break
else:
print("请输入正确的金额")
def get_money(self):
card = self.get_card_info()
if not card:
print("卡号不存在")
else:
if card.islock:
print("您的卡已被冻结")
else:
i = 1
while i < 4:
pwd=input("请输入密码:")
if pwd == card.password:
while True:
get_num=input("请输入取款金额:")
if get_num.isdecimal() and int(get_num) > 0:
get_num = int(get_num)
if get_num <= card.money:
card.money -= get_num
print("您已成功取出{}元,卡上余额{}元".format(get_num, card.money))
break
else:
print("您的余额不足,卡上余额{}元".format(card.money))
else:
print("请输入正确的提款金额!")
break
else:
print("您输入的密码错误,请重新输入,剩余{}次".format(3-i))
if i == 3:
card.islock=True
print("您的卡已被冻结")
i += 1
def get_card_info2(self):
cardid=input("请输入对方卡号:")
if cardid not in self.usr_card:
print(self.usr_card)
return False
else:
user=self.usr_card[cardid]
return user.card
def trans_money(self):
card1 = self.get_card_info()
if not card1:
print("卡号不存在")
else:
if card1.islock:
print("您的卡已被冻结")
else:
i = 1
while i < 4:
pwd=input("请输入您的密码:")
if pwd == card1.password:
card2 = self.get_card_info2()
if not card2:
print("卡号不存在")
else:
if card1.cardid != card2.cardid:
info=input("您将给{}进行转账,确认请输入1,返回主菜单请输入其他键".format(self.usr_card[card2.cardid].name))
if info == "1":
trans = input("请输入转账金额:")
if trans.isdecimal() and card1.money > int(trans):
trans=int(trans)
card1.money -= trans
card2.money += trans
print("您已成功向{}转账{}元".format(self.usr_card[card2.cardid].name,trans))
break
else:
print("请输入正确的金额,当前卡余额{}元!".format(card1.money))
else:
break
else:
print("抱歉,您不能给自己转账!")
else:
print("您输入的密码错误,请重新输入,剩余{}次".format(3 - i))
if i == 3:
card1.islock = True
print("您的卡已被冻结")
i += 1
def change_pwd(self):
card = self.get_card_info()
if not card:
print("卡号不存在")
else:
if card.islock:
print("您的卡已被冻结")
else:
choice=input("请选择改密方式:1、原密码改密 2、身份信息验证")
if choice == "1":
password=input("请输入原密码:")
if password == card.password:
print("请设置新密码:")
pwd = self.get_pwd()
card.password=pwd
print("密码已变更")
else:
print("原密码错误")
elif choice == "2":
usrid=input("请输入身份证号:")
if usrid == self.usr_card[card.cardid].userid:
print("请设置新密码:")
pwd = self.get_pwd()
card.password = pwd
print("密码已变更")
else:
print("身份证号码错误")
def lock(self):
card = self.get_card_info()
if not card:
print("卡号不存在")
else:
if card.islock:
print("您的卡已被冻结")
else:
choice = input("请选择锁卡方式:1、密码锁卡 2、身份证锁卡")
if choice == "1":
password = input("请输入原密码:")
if password == card.password:
card.islock = True
print("锁卡成功")
else:
print("锁卡失败")
elif choice == "2":
usrid = input("请输入身份证号:")
if usrid == self.usr_card[card.cardid].userid:
card.islock = True
print("锁卡成功")
else:
print("锁卡失败")
def unlock(self):
card = self.get_card_info()
if not card:
print("卡号不存在")
else:
if not card.islock:
print("您的卡未冻结")
else:
choice = input("请选择解卡方式:1、密码解卡 2、身份证解卡")
if choice == "1":
password = input("请输入原密码:")
if password == card.password:
card.islock = False
print("解卡成功")
else:
print("解卡失败")
elif choice == "2":
usrid = input("请输入身份证号:")
if usrid == self.usr_card[card.cardid].userid:
card.islock = False
print("解卡成功")
else:
print("解卡失败")
def new_card(self):
usrid=input("请输入身份证号:")
if usrid in self.usrid_card:
new_cardid=self.get_cardid()
new_card=Card(self.usr_card[self.usrid_card[usrid]].card.cardid,self.usr_card[self.usrid_card[usrid]].card.password,self.usr_card[self.usrid_card[usrid]].card.money)
new_card.cardid=new_cardid
user=self.usr_card[self.usrid_card[usrid]]
user.card=new_card
self.usr_card.pop(self.usrid_card[usrid])
self.usr_card[new_cardid]=user
self.usrid_card.pop(usrid)
self.usrid_card[usrid]=new_cardid
print("新卡号为{}".format(new_cardid))
else:
print("此身份证号不存在")
def change_phone(self):
userid = input("请输入身份证:")
if userid not in self.usrid_card:
print("未查询到此身份证")
else:
print("您的卡号是{},绑定手机号码:{}".format(self.usrid_card[userid],self.usr_card[self.usrid_card[userid]].phone))
choice=input("请确认信息,是否要修改绑定手机?(Y/N)\n")
if choice.upper() == "N":
print("您已退出修改!")
elif choice.upper() == "Y":
pwd = input("请输入卡密码:")
if pwd == self.usr_card[self.usrid_card[userid]].card.password:
while True:
new_phone=self.get_phone()
if new_phone != self.usr_card[self.usrid_card[userid]].phone:
self.usr_card[self.usrid_card[userid]].phone=new_phone
print("{}绑定手机已变更为{}".format(self.usrid_card[userid],new_phone))
break
else:
print("不能与原手机号相同")
else:
print("密码不正确!")
else:
print("请输入正确选项,已退出修改!")
6、ATMmain主文件
用户在主文件中执行操作,调用模块
from ATMpackage.view import View
from ATMpackage.operation import Operation
class Main():
@staticmethod
def run():
if View.admin_login():
obj = Operation()
while True:
business=input("请选择要办理的业务:")
if business == "1":
obj.register()
elif business == "2":
obj.query()
elif business == "3":
obj.save_money()
elif business == "4":
obj.get_money()
elif business == "5":
obj.trans_money()
elif business == "6":
obj.change_pwd()
elif business == "7":
obj.lock()
elif business == "8":
obj.unlock()
elif business == "9":
obj.new_card()
elif business == "10":
obj.change_phone()
elif business == "0":
obj.save()
break
if __name__=="__main__":
Main.run()
只展示基础功能,具体功能请自行尝试: