• python3 实现简单的信用卡还款,取款转账功能V2


    仅实现还款,取款,转账,信息查询功能

    程序结构:

    atm(函数主执行程序):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import os,sys
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(Father_path)
    from core import main
    
    if __name__  ==  '__main__':
        main.run()
    

    main(程序主逻辑模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import os,sys,time,json
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,Father_path)
    from core import auth
    from core import db_handle
    from conf import settings
    from conf import Color_set
    from core import transaction
    color=Color_set.Colorset()
    user_data = {
        'account_id': None,
        'is_authentic': False,
        'account_data': None
    }
    def auth_transfer_id():
        trans_id = input("输入转账ID:").strip()
        trans_file = Father_path+"/db/accounts/%s.json" % trans_id
        if os.path.isfile(trans_file):
            return trans_id
    
    def action_type(acc_data,action):
        Exit_flag = True
        while Exit_flag:
            values = input("请输入%s金额:" %action.strip())
            if values.isdigit():
                if action == "还款":
                    action_result = transaction.make_transaction(acc_data,"repayment",values)
                    if action_result:
                        print(color.red("您的最新余额为%s" %action_result['balance']))
                        break
                elif action == "取款":
                    action_result = transaction.make_transaction(acc_data, "enchashment", values)
                    if action_result:
                        print(color.red("您的最新余额为%s" % action_result['balance']))
                        break
                elif action == "转账":
                    while True:
                        trans_id = auth_transfer_id()
                        if trans_id == acc_data['id']:
                            print(color.red("账户无效,请重新输入!"))
                        elif not trans_id:
                            Exit_flag = False
                            print(color.red("账户无效,请重新输入!"))
                        elif trans_id:
                            f = Father_path + "/db/accounts/%s.json" % trans_id
                            trans_file = open(f)
                            trans_dict = json.load(trans_file)
                            action_result = transaction.make_transaction(acc_data, "transfer", values)
                            if action_result:
                                print(color.red("您的最新余额为%s" % action_result['balance']))
                                # logger.logger(acc_data["id"], action_result['balance'], "transfer")
                                break
                        else:
                            print("33[31;1m 账户无效,请重新输入!!33[;0m")
                            break
    
                elif values == "b":
                    Exit_flag = False
                else:
                    print(color.red("[%s]不是有效的金额,必需输入数字!" % values))
    
    def account_info(acc_data):
        print("以下为您的个人账户基本信息:
    ")
        print(color.red("卡号:%s
    信用额度:%s
    可用余度:%s
    还款日:%s
    出账日:%s
    账户状态:%s
    " %(acc_data['id'],acc_data['credit'],acc_data['balance'],acc_data['pay_day'],acc_data['account_day'],acc_data['status']))
              )
    def repayment(acc_data):
        action_type(acc_data,"还款")
    def enchashment(acc_data):
        action_type(acc_data, "取款")
    def transfer(acc_data):
        action_type(acc_data, "转账")
    def billing(acc_data):
        print("账单查询功能正在建设中,给您造成不便,敬请谅解!")
    def logout(acc_data):
        print("欢迎再次使用,祝生活愉快,再见!")
        exit()
    
    def interactive(acc_data):
        menu = color.red('''
        1.  账户信息
    
        2.  还款
    
        3.  取款
    
        4.  转账
    
        5.  账单
    
        6.  退出
    
        ''')
        menu_dic = {
            '1' : account_info,
            '2' : repayment,
            '3' : enchashment,
            '4' : transfer,
            '5' : billing,
            '6' : logout
        }
        str = "欢迎使用银行信用卡自助服务系统!
    "
        for i in str:
            sys.stdout.write(i)
            sys.stdout.flush()
            time.sleep(0.3)
        Exit_flag = True
        while Exit_flag:
            print(menu)
            user_option = input("请选择服务项目:").strip()
            if user_option in menu_dic:
                menu_dic[user_option](acc_data)
            else:
                print(color.red("输入错误,请重新输入!"))
    
    def run():
        acc_data = auth.acc_login(user_data)
        if user_data['is_authentic']:
            user_data['account_data'] = acc_data
            interactive(acc_data)
    

    db_handle(用于判断数据类型以及数据文件位置模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    '''
    conn_params    must be a dict
    以下定义了两个函数:
    file_db_handle 来确定数据文件的路径
    db_handle_type 来确定数据文件的类型
    
    '''
    def file_db_handle(conn_params):
        db_path = '%s/%s' %(conn_params['path'],conn_params['name'])
        return db_path
    
    def db_handle_type(conn_params):
        if conn_params['engine'] == 'file_storage':
            return file_db_handle(conn_params)
    

    auth(用户认证模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import os,sys,json
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,Father_path)
    from core import db_handle
    from conf import settings
    from conf import Color_set
    color=Color_set.Colorset()
    
    def acc_auth(account,passwd):
        db_path=db_handle.db_handle_type(settings.DATABASE)
        data_file='%s/%s.json' %(db_path,account)
        if os.path.isfile(data_file):
            with open(data_file,encoding='utf-8') as f:
                account_data=json.load(f)
                if account_data['password'] == passwd:
                    return account_data
                else:
                    print(color.red("用户名或密码错误!"))
        else:
            print(color.red("账户不存在!"))
    
    
    def acc_login(user_data):
        retry_times = 0
        while user_data["is_authentic"] is not True and retry_times < 3:
            account = input("请输入账号:")
            passwd = input("请输入密码:")
            auth = acc_auth(account,passwd)
            if auth:
                user_data["is_authentic"] = True
                user_data ["account_id"] = account
                return auth
            retry_times += 1
        else:
             print(color.red("账户 [%s] 错误登录次数已达上限,已被锁定,解锁请联系客服10086!" % account))
             exit()
    

    accounts (读取和保存用户数据模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import json,os,sys
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,Father_path)
    from core import db_handle
    from conf import settings
    
    def load_current_balance(account_id):
        db_path = db_handle.db_handle_type(settings.DATABASE)
        account_file = "%s/%s.json" % (db_path, account_id)
        with open(account_file,encoding='utf-8') as f:
            acc_data = json.load(f)
            return acc_data
    
    def dump_account(account_data):
        db_path = db_handle.db_handle_type(settings.DATABASE)
        account_file = "%s/%s.json" % (db_path, account_data["id"])
        with open(account_file, "w",encoding='utf-8') as f:
            json.dump(account_data, f)
        return True
    

    settings(程序配置模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import os,sys
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    DATABASE = {
        'engine':'file_storage',
        'name':'accounts',
        'path':'%s/db' %Father_path
    }
    TRANSACTIONE_TYPE = {
        'repayment': {'action' : 'plus', 'interest': 0},
        'enchashment': {'action' : 'minus', 'interest': 0.005},
        'transfer': {'action' : 'minus', 'interest': 0.005}
    }
    

    Color_set(字体输出颜色设置模块):

    #coding:gbk
    # ------------------------------------------------
    #   python终端显示彩色字符类,可以调用不同的方法
    # 选择不同的颜色.使用方法看示例代码就很容易明白.
    # ------------------------------------------------
    #
    # 显示格式: 33[显示方式;前景色;背景色m
    # ------------------------------------------------
    # 显示方式             说明
    #   0                 终端默认设置
    #   1                 高亮显示
    #   4                 使用下划线
    #   5                 闪烁
    #   7                 反白显示
    #   8                 不可见
    #   22                非粗体
    #   24                非下划线
    #   25                非闪烁
    #
    #   前景色             背景色            颜色
    #     30                40              黑色
    #     31                41              红色
    #     32                42              绿色
    #     33                43              黃色
    #     34                44              蓝色
    #     35                45              紫红色
    #     36                46              青蓝色
    #     37                47              白色
    # ------------------------------------------------
    class Colorset(object):
        # 显示格式: 33[显示方式;前景色;背景色m
        # 只写一个字段表示前景色,背景色默认
        RED = '33[31m'       # 红色
        GREEN = '33[32m'     # 绿色
        YELLOW = '33[33m'    # 黄色
        BLUE = '33[34m'      # 蓝色
        FUCHSIA = '33[35m'   # 紫红色
        CYAN = '33[36m'      # 青蓝色
        WHITE = '33[37m'     # 白色
    
        #: no color
        RESET = '33[0m'      # 终端默认颜色
    
        def color_str(self, color, s):
            return '{}{}{}'.format(
                getattr(self, color),
                s,
                self.RESET
            )
    
        def red(self, s):
            return self.color_str('RED', s)
    
        def green(self, s):
            return self.color_str('GREEN', s)
    
        def yellow(self, s):
            return self.color_str('YELLOW', s)
    
        def blue(self, s):
            return self.color_str('BLUE', s)
    
        def fuchsia(self, s):
            return self.color_str('FUCHSIA', s)
    
        def cyan(self, s):
            return self.color_str('CYAN', s)
    
        def white(self, s):
            return self.color_str('WHITE', s)
    
    # ----------使用示例如下:-------------
    # color = Colorset()
    # print(color.red('I am red!'))
    # print(color.green('I am gree!'))
    # print(color.yellow('I am yellow!'))
    # print(color.blue('I am blue!'))
    # print(color.fuchsia('I am fuchsia!'))
    # print(color.cyan('I am cyan!'))
    # print(color.white('I am white'))
    

    transaction(转账、取款、还款实际执行模块):

    #Author by Andy
    #_*_ coding:utf-8 _*_
    import os,sys,json
    Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,Father_path)
    from conf import settings
    from conf import Color_set
    from core import accounts
    color = Color_set.Colorset()
    def make_transaction(acc_data, action_type, values, **others):
        values = float(values)
        if action_type in settings.TRANSACTIONE_TYPE:
            interest = values * settings.TRANSACTIONE_TYPE[action_type]['interest']
            old_balance = acc_data['balance']
            if settings.TRANSACTIONE_TYPE[action_type]['action'] == "plus":
                new_balance = old_balance + values + interest
                print("此次操作的手续费为:%s" %interest)
            elif settings.TRANSACTIONE_TYPE[action_type]['action'] == "minus":
                new_balance = old_balance - values - interest
                print("此次操作的手续费为:%s" % interest)
                if new_balance < 0:
                    print(color.red("当前信用值%s不允许进行此交易[-%s],当前余额%s" % 
                    (acc_data["cridit"], (values + interest), old_balance)))
                    return
            acc_data["balance"] = new_balance
            accounts.dump_account(acc_data)
            return acc_data
        else:
            print(color.red("交易类型 [%s] 不存在!" % action_type))
    

    用户数据文件:

    10086.jason:

    {"id": 10010, "pay_day": "每月9日", "balance": 15000, "status": "nomal", "credit": 15000, "password": "abcd","account_day": "每月21日"}
    

      

    10010.jason:

    {"balance": 801645.0, "id": 10086, "pay_day": "u6bcfu670822u65e5", "credit": 15000, "password": "abcd", "status": "nomal", "account_day": "u6bcfu67085u65e5"}
    

     

  • 相关阅读:
    寻找——无限游戏破关(一)
    运维入职梳理文档
    seafile 旧版本升级新版本时python库引用报错
    操作系统-计算进程的物理地址(例题)
    拉取微信公众号视频文件
    洛谷-P3654 First Step (ファーストステップ)
    洛谷-P3392 涂国旗
    洛谷-P1706 全排列问题
    洛谷-P1157 组合的输出
    洛谷-P2241 统计方形(数据加强版)
  • 原文地址:https://www.cnblogs.com/pythonstudy/p/6224177.html
Copyright © 2020-2023  润新知