(新人如若写的不好望海涵)
一、项目需求
设计一个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