Python入门学习笔记——22.Python编程阶段项目-ATM

'''
使用面向对象编程完成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

你可能感兴趣的:(Python入门学习笔记)