Python 类与对象应用 —— 银行管理系统(双系统)

# 银行管理系统


"""
思考:
    1.怎么随机产生不重复的6位数字?
    2.怎么存储银行卡信息?
    3.怎么引用自己写的模块

介绍:
    从早期的钱庄到现如今的银行,金融行业在不断地变革,随着科技的发展,计算机的普及,
    计算机技术在金融行业得到了广泛的应用。
    银行管理系统是一个集开户、查询、取款、存款、转账、锁定、解锁、退出等功能的管理系统。

    操作:本程序有两个系统,分别是管理员系统和普通用户系统,
    初始管理员账户:123456,密码:123456

知识点:
    1.类和对象的使用:类的定义、属性和方法的调用、类方法和静态方法的封装和调用
    2.字典的使用;本程序是有字典来存储数据的,包括字典的增、删、改、查、遍历
    3.文件模块引用:我把本程序和之前写的程序(文本进度条)进行调用
    4.循环/嵌套循环语句:while/ for
    5.条件/嵌套条件语句:if/ elif/ else
    6.跳转语句:break/ continue
    7.函数封装:把单一重复的代码封装成一个函数
    8.旗帜的使用:方便我们跳出多层循环体

不足(待改善):
    1.本程序有一个bug还没改善:在普通用户登录操作输入金额时,不能输入字符,否则会报错

"""


# 定义一个类     ===================================================================
class Info:

    # 定义一个字典,用于存储银行卡信息
    __info = {'123456': ['周华', '(空)', '(空)', 0, '123456', '管理员']}

    # 管理员账户
    admin_account = '123456'     # 缺点:不是私有属性,可以被外部调用

    # 随机生成6位数账号(不重复)    ==================================================
    @staticmethod
    def __random_num(min=100000, max=999999):

        from random import randint              # 导入random模块的randomint函数
        Info.num = str(randint(min, max))       # 随机生成一个(100000-999999)的账户

        if Info.__info == dict():               # 判断字典是否为空
            return Info.num                     # 返回随机产生的账户

        else:
            # 调用账户查找函数,判断现在生成的随机账户是否与字典中的账户相同(保证唯一性)
            if not Info.find_account(find=Info.num):        # 如果不相同
                return Info.num                             # 那就返回这个账户

            else:                                           # 如果有重复
                Info.__random_num()                         # 那就在重新产生一个账户(递归函数)
                return Info.num                             # 返回账户

    # 账号开户  ====================================================================
    @classmethod
    def create_account(cls, name='(空)', id_card='(空)', phone_num='(空)', money=0, password='(空)', state='(空)'):

        Info.account = Info.__random_num()  # 调用私有方法,随机生成6位数账户,并赋值

        # 把账户信息添加到字典中(字典添加元素),注意不可以使用update()添加元素
        Info.__info[Info.account] = [name, id_card, phone_num, money, password, state]

        return Info.account         # 返回新生成的账户

    # 查找账户  ===================================================================
    @staticmethod
    def find_account(find, container=None):
        if not container:                       # 判断传入的container是否为None
            container = Info.__info             # 如果为None,那就赋值

        for i in container:         # 字典遍历查找账户
            if find == i:           # 判断是否存在此账户
                return True         # 如果存在此账户,那就返回True

        return None                 # 此返回值是:在字典中不存在此账户,返回None

    # 查找密码  ===================================================================
    @classmethod
    def find_password(cls, account, password):
        # 先判断账号是否存在
        if not Info.find_account(find=account, container=Info.__info):
            return None                             # 账户错误

        # 再判断此账号的密码是否正确
        if password == Info.__info[account][4]:
            return True                             # 账户和密码正确

        return False                                # 账户正确,密码错误

    # 账户锁定
    @staticmethod
    def account_lock(account):
        # 在账户信息里添加旗帜(说明此账户已被锁定)
        Info.__info[account][5] = '已锁定'

    # 账户解锁
    @staticmethod
    def account_unlock(account):
        Info.__info[account][5] = '(空)'

    # 判断账户是否被锁定
    @staticmethod
    def whether_account_lock(account):

        # 判断账户是否被锁定
        if '已锁定' == Info.__info[account][-1]:
            return False

        return True

    # 账户销户  ===================================================================
    @staticmethod
    def remove_account(remove):

        # 判断此账户是否存在
        if Info.find_account(remove):

            Info.__info.pop(remove)     # 如果存在,就删除此账户
            return True                 # 删除此账户并返回True

        return None                     # 如果此账户不存在,就返回False

    # 打印账户  ===================================================================
    @staticmethod
    def output_account(account, scope=None):
        # 遍历打印账户信息
        for i in Info.__info:

            # 判断传入的参数是否为‘all’
            if scope == 'all':
                account = i             # 如果是‘all’,就赋值

            # 打印账户信息
            if account == i:
                print(f'账户:{i}\t密码:{Info.__info[i][4]}', end='\t')
                print(f'余额:{Info.__info[i][3]}¥\t姓名:{Info.__info[i][0]}', end='\t')
                print(f'身份证:{Info.__info[i][1]}\t手机号:{Info.__info[i][2]}\t状态:{Info.__info[i][5]}')

    # 修改普通账户信息    ==========================================================
    @staticmethod
    def change_account(account, position, info):
        Info.__info[account][position] = info       # 索引赋值

    # 修改管理员账号   =============================================================
    @staticmethod
    def change_admin_account(account, new_account):

        # 把新的管理员账户保存进系统,(因为字典的特点是不可重复,所以键相同,就覆盖,如果键不同,就赋值产生新的元素)
        Info.__info[new_account] = Info.__info[account]

        # 如果键不同,就删除原管理员账号
        if new_account != account:
            Info.__info.pop(account)

        # 把新账户啊设置成管理员
        Info.admin_account = new_account

    # 删库跑路  ===================================================================
    @staticmethod
    def clear_account():
        buf = Info.__info[Info.admin_account]       # 管理员账户保存
        Info.__info.clear()                         # 清空系统账户信息
        Info.__info[Info.admin_account] = buf       # 复原管理员账户

        # 打印加载进度条
        from loading import show_load
        show_load(0.5)

    # 打印普通账户信息    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    @staticmethod
    def output_info(account):
        print(f'账户:{account}\t姓名:{Info.__info[account][0]}\t余额:{Info.__info[account][3]}¥')

    # 账户存款  ====================================================================
    @staticmethod
    def user_depo(account, money):
        Info.__info[account][3] += money

    # 账户取款  ====================================================================
    @staticmethod
    def user_withdrawal(account, money):
        Info.__info[account][3] -= money

    # 外部调用私有属性接口    ========================================================
    @staticmethod
    def user_money(account):
        return Info.__info[account][3]


# 定义一个菜单功能实现类(管理员)
class Realize:

    # 打印标题  ===================================================================
    @staticmethod
    def show_title(info='', num=9, num1=0):
        print(' ' * num1 + '=' * num + info + '=' * num)  # 字符串拼接

    # 管理员菜单打印  ==============================================================
    @staticmethod
    def admin_menu():
        Realize.show_title(info='银行管理系统(管理员)', num=4)
        print('1.账号开户\t\t2.账户销户')
        print('3.账户锁定\t\t4.账户解锁')
        print('5.账户查询\t\t6.账户修改')
        print('7.删库跑路\t\t0.退卡')

    # 输入编号(选择菜单功能)  ======================================================
    @staticmethod
    def input_num(info=''):
        print(info, end='')
        return input()

    # 判断账户是否存在  ============================================================
    @staticmethod
    def account_whether_exist(info):
        while True:
            account = input(info)

            # 如果账户存在
            if Info.find_account(account):
                return account

            # 退出
            elif account == 'q':
                Realize.show_title(info='返回菜单')
                return False

            print(f'账户:{account}不存在!(返回:q)')

    # 选择确认  ===================================================================
    @staticmethod
    def option_affirm(account, info, num=9, num1=0):
        message = f'请确认是否对账户:{account},进行{info}(Y/N):'  # 字符串拼接

        while True:
            buf = input(message)

            # 确定
            if buf == 'y' or buf == 'Y':
                Realize.show_title(info=f'{info}成功', num=num, num1=num1)
                return True

            # 反悔
            elif buf == 'n' or buf == 'N':
                print(f'账户:{account},{info}失败!')
                return False

            # 输入有误
            print('输入有误!请输入字母:Y/N')

    # 账号开户  ===================================================================
    @staticmethod
    def set_up_account():
        # 输入开户信息
        Realize.show_title(info='账号开户')
        name = input('请输入您的姓名:')
        id_card = input('请输入您的身份证:')
        phone_num = input('请输入您的手机号码:')
        password = input('请设置您的账户密码:')

        # 保存账户信息
        account = Info.create_account(name=name, id_card=id_card, phone_num=phone_num, password=password)

        # 打印账户信息
        print(f'账户:{account}\t密码:{password}\t姓名:{name}\t余额:0元')
        Realize.show_title(info='开户成功')

    # 账户销户  ===================================================================
    @staticmethod
    def del_account():
        Realize.show_title(info='账户销户')

        # 如果账户不存在
        account = Realize.account_whether_exist('请输入需要注销的账户:')
        if not account:
            return

        Info.output_account(account)                        # 打印账户信息

        # 管理员账户无法注销
        if account == Info.admin_account:
            print(f'{account}为管理员账户,无法注销!')
            return

        # 选择确认销户
        if Realize.option_affirm(account=account, info='销户'):
            Info.remove_account(account)        # 销户

    # 账户锁定  ===================================================================
    @staticmethod
    def frozen_account():
        Realize.show_title(info='账户锁定')

        # 如果账户不存在
        account = Realize.account_whether_exist('请输入需要锁定的账户:')
        if not account:
            return

        # 管理员账户无法锁定
        if account == Info.admin_account:
            print(f'{account}为管理员账户,无法锁定!')
            return

        # 如果账户已锁定
        if not Info.whether_account_lock(account):
            print(f'账户:{account},已被锁定!')
            return

        # 锁定选择确认
        if Realize.option_affirm(account=account, info='锁定'):
            # 账户锁定
            Info.account_lock(account)

    # 账户解锁  ===================================================================
    @staticmethod
    def account_unlock():
        Realize.show_title('账户解锁')

        # 如果账户不存在
        account = Realize.account_whether_exist('请输入需要解锁的账户:')
        if not account:
            return

        # 如果没有锁定
        if Info.whether_account_lock(account):
            print(f'账户:{account},未锁定,无需解锁!')
            return

        # 如果选择解锁
        if Realize.option_affirm(account=account, info='解锁'):
            Info.account_unlock(account)        # 账户解锁

    # 账户查询  ===================================================================
    @staticmethod
    def find_account_info():
        Realize.show_title('账户查询')

        # 因为这里添加了‘all’,所以要单独处理
        while True:
            account = input('请输入需要查询的账户(全部:all):')

            # 如果账户存在
            if Info.find_account(account):
                break

            # 退出
            elif account == 'q':
                Realize.show_title(info='返回菜单')
                return False

            # 打印全部
            elif account == 'all' or account == 'ALL':
                break

            print(f'账户:{account}不存在!(返回:q)')

        # 打印系统所有账户信息
        if account == 'all':
            Info.output_account(account='参数无要求', scope='all')
            return

        # 单纯打印此账户信息
        Info.output_account(account)

    # 账户修改  ===================================================================
    @staticmethod
    def change_account_info():
        Realize.show_title('账户修改')

        # 如果账户不存在
        account = Realize.account_whether_exist('请输入需要修改的账户:')
        if not account:
            return

        # 管理员特殊处理
        if account == Info.admin_account:
            while True:
                new_account = input('请输入新的账号:')

                # 如果修改成功
                if Realize.option_affirm(account=account, info='账号修改', num=7, num1=1):
                    # 确认修改后赋值
                    Info.change_admin_account(account=account, new_account=new_account)
                    # 打印修改后账户信息
                    Info.output_account(new_account)
                    # 赋值
                    account = new_account
                    break

        # 账户信息修改(可以封装到函数里)
        while True:
            # 打印账户信息修改菜单
            Realize.show_title('账户修改')
            print('1.修改姓名\t  2.修改身份证')
            print('3.修改密码\t  4.修改手机号')

            # 选择菜单功能
            num = Realize.input_num(f'请账户{account}选择修改内容:')

            # 1.修改姓名
            if num == '1':
                new_name = input('请输入新的姓名:')
                # 参数传参赋值
                info = '姓名修改'
                index = 0
                data = new_name
                num = 7
                space = 1

            # 2.修改身份证
            elif num == '2':
                data = input('请输入新的身份证:')
                # 参数传参赋值
                info = '身份证修改'
                index = 1
                num = 6
                space = 1

            # 3.修改密码
            elif num == '3':
                data = input('请输入新的密码:')
                # 参数传参赋值
                info = '密码修改'
                index = 4
                num = 7
                space = 1

            # 4.修改手机号
            elif num == '4':
                data = input('请输入新的手机号:')
                # 参数传参赋值
                info = '手机号修改'
                index = 2
                num = 6
                space = 1

            # 返回
            elif num == 'q':
                break

            # 其他
            else:
                print('编号输入有误!(退出:q)')
                continue

            # 如果修改失败
            if not Realize.option_affirm(account=account, info=info, num=num, num1=space):
                continue

            # 修改成功后赋值
            Info.change_account(account=account, position=index, info=data)
            Info.output_account(account)        # 打印赋值后信息

    # 删库跑路  ===================================================================
    @staticmethod
    def clear_account():
        Realize.show_title('恢复出厂')

        while True:
            buf = input('请确认是否删库跑路(Y/N):')

            if buf == 'Y' or buf == 'y':
                Info.clear_account()
                Realize.show_title('恢复出厂')
                break

            elif buf == 'N' or buf == 'n':
                Realize.show_title('删库失败')
                break

            elif buf == 'q':
                Realize.show_title('放弃删库')
                break

            print('输入有误!(返回:q)')

    # 登录界面打印    ==============================================================
    @staticmethod
    def interface():

        while True:
            Realize.show_title(info='账户登录')  # 打印标题
            whether = input('请问您是否有账户(Y/N):')

            if whether == 'N' or whether == 'n':
                print('很遗憾您还没有账户!!!')
                print('快来找管理员开户吧!')
                print('管理员账户:123456')
                print('管理员密码:123456')
                continue

            elif whether == 'Y' or whether == 'y':

                account = input('请输入账户:')  # 输入账户

                # 先判断账户是否正确
                if not Info.find_account(find=account):
                    error_count = 1  # 记录输入错误的次数

                    while True:
                        print('账号输入错误!(返回:q)')  # 打印错误提示语
                        account = input('请重新输入账户:')  # 重新输入账户

                        # 判断系统里是否有此账户
                        if Info.find_account(find=account):
                            break  # 如果有就停止输入

                        # 判断输入的次数能否被4整除
                        if error_count % 4 == 0:
                            buf = f'您已经输入错误{error_count + 1}次!'   # 如果能被4整除,就打印提示语
                            Realize.show_title(info=buf, num=4)         # 调用函数打印打印提示语

                        # 判断是否输入的账户是字符‘q’
                        if account == 'q':
                            break  # 如果为真,就跳出循环输入

                        error_count += 1  # 输入错误数累加

                # 判断输入的账户是否为字符‘q’
                if account == 'q':
                    continue  # 如果为真,就回到本次循环的开始

                # 判断账户是否被锁定
                if not Info.whether_account_lock(account):
                    print(f'此账户:{account} 已被锁定!\n请及时找管理员处理!')
                    continue

                password = input('请输入密码:')  # 输入密码

                # 只有三次机会
                for i in range(4):

                    # 再判断密码是否正确
                    if Info.find_password(account=account, password=password):
                        return account  # 如果正确,就返回账户

                    else:
                        error = '输入密码错误!'

                    # 打印提示语
                    if i < 3:
                        print(error, end='')  # 打印输入错误提示
                        print(f'还有{3 - i}次机会')
                        password = input('请重新输入密码:')

                # 密码全输错了(账户锁定,管理员除外)
                if account != Info.admin_account:
                    print(f'此账户:{account} 已被锁定!\n请及时找管理员处理!')

                    Info.account_lock(account)  # 调用静态方法,说明此账户已被锁定

    # 选择菜单功能  ================================================================
    @staticmethod
    def select_function(num):

        # 1.账号开户
        if num == '1':
            Realize.set_up_account()        # 调用静态方法开户

        # 2.账号销户
        elif num == '2':
            Realize.del_account()           # 调用静态方法

        # 3.账户锁定
        elif num == '3':
            Realize.frozen_account()        # 调用静态方法

        # 4.账户解锁
        elif num == '4':
            Realize.account_unlock()        # 调用静态方法

        # 5.账户查询
        elif num == '5':
            Realize.find_account_info()     # 调用静态方法

        # 6.账户修改
        elif num == '6':
            Realize.change_account_info()   # 调用静态方法

        # 7.删库跑路
        elif num == '7':
            Realize.clear_account()         # 调用静态方法


# 定义一个普通账户菜单功能实现类(普通用户)
class User:

    # 打印菜单  ====================================================================
    @staticmethod
    def user_menu():
        Realize.show_title(info='银行管理系统(用户)', num=5)
        print('1.取款\t\t\t\t2.余额')
        print('3.存款\t\t\t\t4.转账')
        print('0.退卡')

    # 存款    =====================================================================
    @staticmethod
    def deposit(account):
        Realize.show_title('用户存款')

        while True:
            money = float(input('请输入存款金额:'))       # 理想状态,如果输入负数和字符串会出现bug
            if money < 0:
                print('不能输入负数')
                continue

            break

        Info.user_depo(account=account, money=money)    # 金额增加
        Info.output_info(account)                       # 打印账户信息

        # 如果放弃存款
        if not Realize.option_affirm(account=account, info='存款'):
            Info.user_withdrawal(account=account, money=money)     # 金额减少
            return

    # 取款    =====================================================================
    @staticmethod
    def withdrawal(account):
        Realize.show_title('用户取款')

        while True:
            Info.output_info(account)                # 打印账户信息
            money = float(input('请输入取款金额:'))    # 理想状态,如果输入负数和字符串会出现bug

            if money < 0:
                print('不能输入负数')
                continue

            # 如果银行卡里的余额<取款余额
            elif Info.user_money(account) < money:
                print('已超出最大取款金额!')
                continue

            break

        # 如果放弃存款
        if not Realize.option_affirm(account=account, info='取款'):
            return

        Info.user_withdrawal(account=account, money=money)  # 金额减少

    # 转账    =====================================================================
    @staticmethod
    def transfer(account):

        Realize.show_title('账户转账')

        # 被转账账户真是存在,且不是管理员
        while True:
            new_account = input('请输入转账的账户:')

            # 如果被转账账户存在
            if Info.find_account(new_account):
                break

            # 返回上一级
            elif new_account == 'q':
                Realize.show_title('转账失败')
                return

            # 不能对管理员转账
            elif new_account == Info.admin_account:
                print('无法给管理员账户转账!')
                continue

            print('此账户不存在,(返回:q)')

        # 输入合适的转账金额
        while True:
            Info.output_info(account)  # 打印账户信息

            # 输入转账金额
            money = float(input('请输入转账金额:'))

            if money < 0:
                print('不能输入负数')
                continue

            # 如果银行卡里的余额<取款余额
            elif Info.user_money(account) < money:
                print('已超出最大取款金额!')
                continue

            break

        # 如果放弃转账
        if not Realize.option_affirm(account=account, info='转账'):
            return

        # 转账成功
        Info.user_withdrawal(account=account, money=money)  # 金额减少
        Info.user_depo(account=new_account, money=money)    # 金额增加

    # 菜单功能实现    ===============================================================
    @staticmethod
    def option_function(num, account):
        # 1.取款
        if num == '1':
            User.withdrawal(account)

        # 2.余额
        elif num == '2':
            Realize.show_title('显示余额')
            Info.output_info(account)

        # 3.存款
        elif num == '3':
            User.deposit(account)

        # 4.转账
        elif num == '4':
            User.transfer(account)


# 功能实现(等价于C语言的主函数)   ====================================================
while True:

    flag_break = 0                      # 跳出循环旗帜

    account = Realize.interface()       # 判断是否有账户,并赋值

    while not False:

        if flag_break == 1:             # 跳出两层循环
            break

        # 如果被锁定
        if not Info.whether_account_lock(account):
            print(f'此账户:{account} 已被锁定!\n请及时找管理员处理!')
            break

        # 打印加载进度条
        from loading import show_load
        show_load()

        # 如果是管理员账户登录
        if account == Info.admin_account:

            while True:
                Realize.admin_menu()                        # 打印管理员菜单
                num = Realize.input_num('请管理员选择功能:')    # 选择功能

                if num == '0':
                    flag_break = 1          # 跳出两层循环旗帜
                    Realize.show_title(info='已退出管理员管理系统', num=4)
                    break

                Realize.select_function(num)        # 菜单功能实现

        # 普通账户登录
        else:
            while True:
                User.user_menu()  # 打印用户菜单
                num = Realize.input_num(f'请[{account}]选择功能:')  # 选择功能

                if num == '0':
                    flag_break = 1  # 跳出两层循环旗帜
                    Realize.show_title(info='已退出银行管理系统', num=5)
                    break

                User.option_function(num=num, account=account)  # 菜单功能实现



loading.py 文本进度加载


# 文本下载进度条

"""
知识点:
    1、time 模块使用
    2、回到本行首位置'\r'与 替换本行末尾换行符end=''
    3、显示百分号
    4、字符串运算,只能用加法和乘法
    5、while 循环使用
"""


def show_load(speed=0.1):

    import time  # 导入 time模块

    # 变量定义
    i = 1
    a = '*'
    # b = '.'

    start = '='*10 + '加载中' + '='*10     # 字符串拼接
    finish = '='*9 + '加载完成' + '='*9

    # 打印开始下载
    # print(start)

    while True:

        # 字符串拼接
        progress_bar = '[{}{}{:.0%}]'.format(a * i, '.' * (19 - i), (i * 100 / 19) / 100)

        # 打印进度条
        print('\r' + progress_bar, end='')

        # 循环结束条件
        if i >= 19:
            break  # 跳出循环

        i += 1  # 循环累加

        time.sleep(speed)  # 等待0.5秒

    # 打印下载完成
    # print('\n' + finish)

    print()


运行结果:

=========账户登录=========
请问您是否有账户(Y/N):n
很遗憾您还没有账户!!!
快来找管理员开户吧!
管理员账户:123456
管理员密码:123456
=========账户登录=========
请问您是否有账户(Y/N):y
请输入账户:123456
请输入密码:123456
[*******************100%]
====银行管理系统(管理员)====
1.账号开户		2.账户销户
3.账户锁定		4.账户解锁
5.账户查询		6.账户修改
7.删库跑路		0.退卡
请管理员选择功能:5
=========账户查询=========
请输入需要查询的账户(全部:all):all
账户:123456	密码:123456	余额:0¥	姓名:周华	身份证:(空)	手机号:(空)	状态:管理员
====银行管理系统(管理员)====
1.账号开户		2.账户销户
3.账户锁定		4.账户解锁
5.账户查询		6.账户修改
7.删库跑路		0.退卡
请管理员选择功能:

作者:周华

创作日期:2022/6/5

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值