• 【python练习】ATM&购物商城程序


    程序功能

    本程序模拟实现了一个ATM + 购物商城程序

    1、额度 15000或自定义
    2、实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3、可以提现,手续费5%
    4、支持多账户登录
    5、支持账户间转账
    6、记录每月日常消费流水
    7、提供还款接口
    8、ATM记录操作日志
    9、提供管理接口,包括添加账户、用户额度,冻结账户等

    程序结构:

    atm/
    ├── README
    ├── atm #ATM主程目录
    │   ├── init.py
    │   ├── bin #ATM 执行文件 目录
    │   │   ├── init.py
    │   │   ├── atm.py  #ATM 执行程序
    │   │   └── manage.py #ATM 管理端
    │   ├── conf #配置文件
    │   │   ├── init.py
    │   │   └── settings.py
    │   ├── core #主要程序逻辑都
    │   │   ├── init.py
    │   │   ├── db_handler.py   #数据的存储和加载
    │   │   ├── logger.py       #日志记录模块
    │   │   ├── login.py   #登陆模块
    │   │   ├── main.py         #主逻辑交互程序
    │   │   └── transaction.py  #记账还钱取钱等所有的与账户金额相关的操作
    │   ├── db #用户数据存储的地方
    │   │   ├── init.py
    │   │   └── accounts #存各个用户的账户数据 ,一个用户一个文件
    │   │       ├── guanyu.json #用户账户示例文件
    │   │       ├── liubei.json #用户账户示例文件
    │   │       └── zhangfei.json #用户账户示例文件
    │   ├── interface #提供为其他应用的接口
    │   │   ├── init.py
    │   │   └── pay_interface #支付接口
    │   └── logs #日志目录
    │       ├── init.py
    │       ├── access.log #用户访问和操作的相关日志
    │       └── transactions.log #所有的交易日志
    └── shopping_mall #购物车程序
        ├── data #用户数据存储的地方
        │       ├── guanyu #用户账户示例文件
        │       ├── liubei #用户账户示例文件
        │       └── zhangfei #用户账户示例文件
        └── shopping.py #购物车主程序

    测试账号

    atm:
        1. 账号:liubei    密码:liubei123
        2. 账号:guanyu    密码:gy123
        3. 账号:zhangfei  密码:zf123
    购物商城程序:
        1. 账号:liubei    密码:liubei123
    

      


    atm/atm/bin/atm.py
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import os
    import sys
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    print(BASE_PATH)
    sys.path.append(BASE_PATH)
    
    from core import main
    
    if __name__ == '__main__':
        main.run()
    atm/atm/bin/manage.py
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import os
    import sys
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    print(BASE_PATH)
    sys.path.append(BASE_PATH)
    
    from core import main
    
    if __name__ == '__main__':
        main.root()

    atm/atm/config/setting.py
    import os
    import sys
    import logging
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    DATABASE = {
        'engine': 'file_storage',
        'name': 'accounts',
        'path': '%s\db' % BASE_PATH
    }
    
    LOG_LEVEL = logging.INFO
    LOG_TYPES = {
        'transaction': 'transaction.log',
        'access': 'access.log'
    }
    
    TRANSACTION_TYPE = {
        'repay': {'action': 'plus', 'interest': 0},
        'withdraw': {'action': 'minus', 'interest': 0.05},
        'transfer': {'action': 'minus', 'interest': 0.05},
        'consume': {'action': 'minus', 'interest': 0},
    }

    atm/atm/core/db_handle.py
    import json
    import os
    from conf import settings
    
    
    def db_save(acc_data):
        path = '%s\account\%s.json' % (settings.DATABASE['path'], acc_data['account'])
        with open(path, 'w') as f:
            f.write(json.dumps(acc_data))
        return 1
    
    
    def db_read(account):
        path = '%s\account\%s.json' % (settings.DATABASE['path'], account)
        if os.path.isfile(path):
            with open(path, 'r') as f:
                data = json.loads(f.read())
            return data
        else:
            return 0
    atm/atm/core/logger.py
    import logging
    from conf import settings
    
    def logger(log_type):
        # 创建Logger
        logger = logging.getLogger(log_type)
        logger.setLevel(logging.INFO)
        # 创建handler
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
    
        path = '%s\logs\%s' % (settings.BASE_PATH,settings.LOG_TYPES[log_type])
        fh = logging.FileHandler(path)
        fh.setLevel(logging.INFO)
        # 定义formatter
        formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s  %(message)s')
        # 绑定formatter
        ch.setFormatter(formatter)
        fh.setFormatter(formatter)
        # 添加handle对象
        # logger.addHandler(ch)
        logger.addHandler(fh)
    
        return logger
    atm/atm/core/login.py
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import os
    import json
    from core import logger
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    def authentication(func):
        '''
        用户认证程序
        :return:登陆成功返回True
        '''
        def inner(data):
            acc = ''
            auth_list = []  # 用于存放每次输入的用户名
            user_data = {}
            auth_flag = False
    
            print('- - - Login - - -')
            while auth_list.count(acc) < 3 and auth_flag == False:  # 当相同的用户名登陆失败3次,跳出循环
                # acc = 'liubei'
                # pwd = 'lb123'
    
                acc = input('Account:').strip()
                pwd = input('Password:').strip()
    
                path = '%s\db\account\%s.json' % (BASE_PATH, acc)  # 用户信息存放路径
                if os.path.isfile(path):  # 用户名是否存在
                    with open(path) as f:
                        acc_data = json.loads(f.read())  # 读取信息
                    if acc_data['lock state']:  # 用户是否被锁定
                        if acc_data['password'] == pwd:
                            print('Login success !')
                            auth_flag = True
    
                            user_data['account_id'] = acc
                            user_data['is_authenticated'] = auth_flag
                            user_data['account_data'] = acc_data
                            user_data['tem_data'] = data
    
                            logger.logger('access').info('Login %s' % acc)
    
                            func(user_data)
                        else:
                            auth_list.append(acc)
                            logger.logger('access').info('Login %s - Password Error' % acc)
                            print('The password is error,you have %s times' % (3 - auth_list.count(acc)))
                    else:
                        logger.logger('access').info('Login %s - Lock' % acc)
                        print('Your account has locked.')
                        exit()
                else:
                    auth_list.append(acc)
                    print('The account is not exist...you have %s times' % (3 - auth_list.count(acc)))
    
            if auth_list.count(acc) == 3:  # 已存在的用户登陆失败三次,锁定,写入文件
                if os.path.isfile(path):
                    with open(path, 'w')as f:
                        acc_data['lock state'] = False
                        f.write(json.dumps(acc_data))
        return inner
    atm/atm/core/main.py
    # Author:q1.ang
    
    from core import login
    from core import transaction
    from core import logger
    from core import db_handle
    
    
    transaction_logger = logger.logger('transaction')
    
    user_data = {
        'account_id': None,
        'is_authenticated': False,
        'account_data': None,
        'exit_flag': False
    }
    
    
    def withdraw():
        '''
        提现功能
        :return:
        '''
        while True:
            print('''
        - - - - 提现 - - - -
        信用卡额度:%s
        可用金额: %s
        ''' % (user_data['account_data']['limit'], user_data['account_data']['balance']))
    
            money = input("    33[0;32m输入提现金额(手续费%5)('q'退出):33[0m").strip()
            if money == 'q':
                break
            else:
                money = - int(money) * 1.05
            tem = transaction.transaction(user_data['account_data'], money, 'withdraw')
            if tem == 1:  # 提现成功
                print('    33[0;35m... 提现成功,手续费(%s):%s 33[0m'%('%5',abs(money)/1.05*0.05))
                transaction_logger.info(
                    'Account %s - Withdraw %s - Balance %s' % (
                        user_data['account_data']['account'], abs(money),
                        user_data['account_data']['balance']))
            elif tem == 0:  # 提现失败
                print('    33[0;31m余额不足 ... 提现失败 ...33[0m')
                transaction_logger.info(
                    'Account %s - Withdraw %s - Balance %s - Fail(balance not enough)' % (
                        user_data['account_data']['account'], abs(money),
                        user_data['account_data']['balance']))
            else:
                print('    33[0;31m遇到了一些错误 ... 提现失败,请重试 ...33[0m')
                transaction_logger.error(
                    'Account %s - Withdraw %s - Balance %s - Fail' % (
                        user_data['account_data']['account'], abs(money),
                        user_data['account_data']['balance']))
    
    
    def repayment():
        '''
        还款功能
        :return:
        '''
        while True:
            print('''
        - - - - 还款 - - - -
        信用卡额度:%s
        可用金额: %s
            ''' % (user_data['account_data']['limit'], user_data['account_data']['balance']))
    
            money = input("    33[0;32m输入还款金额('q'退出):33[0m").strip()
            if money == 'q':
                break
            else:
                money = int(money)
    
            tem = transaction.transaction(user_data['account_data'], money, 'repayment')
            if tem == 1:
                print('    33[0;35m... 还款成功 33[0m')
                transaction_logger.info(
                    'Account %s - Repayment %s - Balance %s' % (
                        user_data['account_data']['account'], money,
                        user_data['account_data']['balance']))
            elif tem == 0:
                print('    33[0;31m... 还款成功 ... 超出还款额度,退还:%s 33[0m' % (money - user_data['account_data']['repayment_money']))
                transaction_logger.info(
                    'Account %s - Repayment %s - Return %s - Balance %s' % (
                        user_data['account_data']['account'], money,
                        money - user_data['account_data']['repayment_money'],
                        user_data['account_data']['balance']))
            else:
                print('    33[0;31m遇到了一些错误 ... 还款失败,请重试 ...33[0m')
                transaction_logger.error(
                    'Account %s - Withdraw %s - Balance %s - Fail' % (
                        user_data['account_data']['account'], money,
                        user_data['account_data']['balance']))
    
    
    def transfer():
        while True:
            print('''
        - - - - 转账 - - - -
        信用卡额度:%s
        可用金额: %s
                    ''' % (user_data['account_data']['limit'], user_data['account_data']['balance']))
    
            account1 = input("    33[0;32m收款人('q'退出):33[0m").strip()
            if account1 == 'q':
                break
            elif account1 == user_data['account_data']['account']:
                print('    33[0;31m不能给自己转账,请重输 ...33[0m')
                break
            # 收款人data
            user_data2 = db_handle.db_read(account1)
            if user_data2 == 0:
                print('    33[0;31m该用户不存在,请重输 ...33[0m')
            else:
                money = input("    33[0;32m转账金额('q'退出):33[0m").strip()
                if money == 'q':
                    break
                else:
                    money = int(money)
                # 转账
                if user_data['account_data']['balance'] >= money:
                    tem_receive = transaction.transaction(user_data2, money, 'transfer in')  # 收款
                    if tem_receive == 1:  # 收款成功,无返还
                        if transaction.transaction(user_data['account_data'], -money, 'transfer out') == 1:  #扣款成功
                            print('    33[0;35m... 转账成功  33[0m')
    
                            transaction_logger.info(
                                'Account %s - Receive Account %s - transfer %s - Balance %s' % (
                                    user_data['account_data']['account'], account1, money,
                                    user_data['account_data']['balance']))
                            continue
                    elif tem_receive == 0:  # 收款成功,有返还
                        if transaction.transaction(user_data['account_data'], -user_data2['repayment_money'], 'transfer out') == 1:  # 扣款成功
                            print('    33[0;31m... 转账成功 ... 超出还款额度,退还:%s 33[0m' % (
                                        money - user_data2['repayment_money']))
    
                            transaction_logger.info(
                                'Account %s - Receive Account %s - transfer %s - Balance %s - Return %s' % (
                                    user_data['account_data']['account'], account1, money,
                                    user_data['account_data']['balance'],money - user_data2['repayment_money']))
                            continue
                else:
                    print('    33[0;31m余额不足 ... 转账失败 ...33[0m')
    
                    transaction_logger.info(
                        'Account %s - Receive Account %s - Transfer %s - Balance %s - Fail(balance not enough)' % (
                            user_data['account_data']['account'], account1, money,
                            user_data['account_data']['balance']))
                    continue
    
                print('    33[0;31m遇到了一些错误 ... 转账失败,请重试 ...33[0m')
                transaction_logger.error(
                    'Account %s - Transfer %s - Balance %s - Fail' % (
                        user_data['account_data']['account'], money,
                        user_data['account_data']['balance']))
    
    
    def balance():
        print('''
        - - - - 余额 - - - -
        信用卡额度:%s
        可用金额: %s
        ''' % (user_data['account_data']['limit'], user_data['account_data']['balance']))
        input('    33[0;31m任意键退出 ...33[0m')
    
    
    def bill():
        print('    - - - - 账单 - - - -
    ')
    
        record_option = input('    33[0;32mPlease write day of bill[e.g:20180101-20180807]:33[0m').strip()
        record_start = int(record_option.split('-')[0])
        record_end = int(record_option.split('-')[1])
    
        for i in user_data['account_data']['record'].keys():
            print('    33[0;35m- - - - %s - - - -33[0m' % i)
            for j in user_data['account_data']['record'][i].keys():
                if (record_start <= int(j)) and (int(j) <= record_end):
                    print('    33[0;34m[%s-%s-%s]33[0m' % (j[0:4],j[4:6], j[6:8]))
                    for time,money in user_data['account_data']['record'][i][j].items():
                        print('    ',time,'-',money)
        input('    33[0;31m任意键退出 ...33[0m')
    
    
    @login.authentication
    def pay_interface(data):
        '''
        外接支付功能
        :return:
        '''
        global user_data
        user_data = data
    
        print('''
        - - - - 支付 - - - -
        信用卡额度:%s
        可用金额: %s
        ''' % (user_data['account_data']['limit'], user_data['account_data']['balance']))
        money = - user_data['tem_data']['price']
        tem = transaction.transaction(user_data['account_data'], money, 'consumption',user_data['tem_data'])
        if tem == 1:
            print('    33[0;35m... 支付成功33[0m')
            transaction_logger.info(
                'Account %s - Pay %s - Goods %s - Balance %s' % (
                    user_data['account_data']['account'], abs(money),
                    user_data['tem_data']['name'],
                    user_data['account_data']['balance']))
        elif tem == 0:
            print('    33[0;31m余额不足 ... 支付失败 ...33[0m')
            transaction_logger.info(
                'Account %s - Pay %s -  Goods %s - Balance %s - Fail(balance not enough)' % (
                    user_data['account_data']['account'], abs(money),
                    user_data['tem_data']['name'],
                    user_data['account_data']['balance']))
        else:
            print('    33[0;31m遇到了一些错误 ... 提现失败,请重试 ...33[0m')
            transaction_logger.error(
                'Account %s - Pay %s - Balance %s - Fail' % (
                    user_data['account_data']['account'], abs(money),
                    user_data['account_data']['balance']))
        input('    33[0;31m任意键退出 ...33[0m
    ')
    
    
    @login.authentication
    def interactive(data):
        global user_data
        user_data = data
    
        menu = '''
        - - - - welcome - - - -
        1.提现
        2.还款
        3.转账
        4.查询余额
        5.查询账单
        - - - - - - - - - - - -
        '''
    
        menu_dic = {
            '1': withdraw,
            '2': repayment,
            '3': transfer,
            '4': balance,
            '5': bill
        }
    
        while True:
            print(menu)
            option = input('>>>').strip()
    
            if option in menu_dic:
                menu_dic[option]()
            elif option == 'q':
                exit()
            else:
                print('Without this option[%s]' % option)
    
    
    def root():
        '''
        管理接口
        :return:
        '''
        def add_acc():
            acc_data = {
                'lock state': True,
                'record':{
                    'withdraw': {},
                    'repayment': {},
                    'transfer out': {},
                    'transfer in': {},
                    'consumption': {}
                }
            }
            acc = input("    33[0;32m账户名:33[0m").strip()
            pwd = input("    33[0;32m密码:33[0m").strip()
            limit = input("    33[0;32m额度:33[0m").strip()
    
            acc_data['account'] = acc
            acc_data['password'] = pwd
            acc_data['limit'] = int(limit)
            acc_data['balance'] = int(limit)
    
            if db_handle.db_save(acc_data) == 1:
                print('    33[0;35m... 账户创建成功33[0m')
                transaction_logger.info('CreateAccount %s - Limit %s ' % (acc_data['account'], acc_data['limit']))
            else:
                print('    33[0;31m遇到了一些错误 ... 创建失败,请重试 ...33[0m')
                transaction_logger.error('CreateAccount %s - Limit %s - Fail ! ' % (acc_data['account'], acc_data['limit']))
    
        def change_limit():
            acc = input("    33[0;32m账户名:33[0m").strip()
            acc_data = db_handle.db_read(acc)
            if acc_data != 0:
                limit = input("    33[0;32m额度:33[0m").strip()
                acc_data['limit'] = int(limit)
                if db_handle.db_save(acc_data) == 1:
                    print('    33[0;35m... 额度更改成功33[0m')
                    transaction_logger.info('Change limit %s - Account %s ' % (limit, acc))
                else:
                    print('    33[0;31m遇到了一些错误 ... 额度更改失败,请重试 ...33[0m')
                    transaction_logger.error('Change limit %s - Account %s - Fail ! ' % (limit, acc))
            else:
                print('    33[0;31m用户不存在,请重试 ...33[0m')
    
        def lock():
            acc = input("    33[0;32m账户名:33[0m").strip()
            acc_data = db_handle.db_read(acc)
            if acc_data != 0:
                acc_data['lock state'] = False
                if db_handle.db_save(acc_data) == 1:
                    print('    33[0;35m... 冻结成功33[0m')
                    transaction_logger.info('Lock Account %s' % acc)
                else:
                    print('    33[0;31m遇到了一些错误 ... 冻结失败,请重试 ...33[0m')
                    transaction_logger.error('Lock Account %s - Fail ! ' % acc)
            else:
                print('    33[0;31m用户不存在,请重试 ...33[0m')
    
        menu = '''
        - - - - welcome - - - -
        1. 添加账户
        2. 更改用户额度
        3. 冻结账户
        - - - - - - - - - - - -
        '''
    
        menu_dic = {
            '1': add_acc,
            '2': change_limit,
            '3': lock,
        }
    
        while True:
            print(menu)
            option = input('>>>').strip()
    
            if option in menu_dic:
                menu_dic[option]()
            elif option == 'q':
                exit()
            else:
                print('Without this option[%s]' % option)
    
    
    def run():
        interactive(user_data)
    atm/atm/core/transaction.py
    # Author:q1.ang
    
    import os
    import sys
    import time
    from core import db_handle
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_PATH)
    
    
    def transaction(*args):
        acc_data = args[0]
        money = args[1]
        trans_type = args[2]
        if money <= 0:
            if abs(money) <= acc_data['balance']:
                acc_data['balance'] += money
                if trans_type == 'consumption':
                    pay_data = args[3]
                    record(acc_data, trans_type, pay_data)
                else:
                    record(acc_data,trans_type,abs(money))
                return db_handle.db_save(acc_data)
            else:
                return 0
        elif money >= 0:
            if acc_data['balance'] + money <= acc_data['limit']:
                acc_data['balance'] += money
                record(acc_data, trans_type, money)
                if db_handle.db_save(acc_data) == 1:
                    return 1
            else:
                acc_data['repayment_money'] = acc_data['limit'] - acc_data['balance']
                acc_data['balance'] = acc_data['limit']
                record(acc_data, trans_type, acc_data['repayment_money'])
                if db_handle.db_save(acc_data) == 1:
                    return 0
        return 3
    
    
    def record(acc_data, trans_type, money):
        localday = time.strftime('%Y%m%d', time.localtime())
        localtime = time.strftime('%H:%M:%S', time.localtime())
        if localday in acc_data['record'][trans_type]:
            acc_data['record'][trans_type][localday][localtime] = money
        else:
            acc_data['record'][trans_type][localday] = {localtime: money}

    atm/atm/db/account/guanyu.json
    {"lock state": true, "account": "guanyu", "password": "gy123", "limit": 20000, "balance": 20000, "record": {"withdraw": {"20180807": {"00:00:00": 100, "18:00:15": 123, "18:01:24": 321, "18:05:51": 1, "20:01:08": 1234, "20:04:03": 123, "20:17:42": 100, "20:56:57": 5000, "21:00:57": 5000, "21:07:00": 5000}}, "repayment": {"20180101": {"00:00:00": 1}, "20180807": {"20:38:54": 0, "20:40:27": 0, "20:42:09": 0, "20:43:38": 0, "20:57:06": 0, "21:01:13": 1, "21:02:23": 1, "21:02:38": 4997, "21:06:51": 1, "21:07:08": 10000, "21:40:17": 500, "21:43:38": 500, "21:46:08": 500, "21:59:17": 500}}, "transfer out": {}, "transfer in": {"20180807": {"22:37:54": 123, "22:39:25": 5000, "22:43:40": 1, "22:48:36": 1, "22:49:40": 200, "22:50:41": 3000, "22:52:27": 699, "22:58:38": 0}, "20180808": {"17:06:31": 0}}, "consumption": {"20180101": {"00:00:00": {"name": "u7535u8111", "price": 1999}, "23:01:02": {"name": "u9f20u6807", "price": 10}}, "20180202": {"00:02:00": {"name": "u7f8eu5973", "price": 998}}, "20180724": {"22:11:13": {"name": "u7535u8111", "price": 1999}, "22:11:14": {"name": "u9f20u6807", "price": 10}, "22:38:21": {"name": "u7535u8111", "price": 1999}, "22:40:32": {"name": "u7535u8111", "price": 1999}, "22:41:31": {"name": "u7535u8111", "price": 1999}, "22:41:35": {"name": "u9f20u6807", "price": 10}, "22:42:41": {"name": "u7535u8111", "price": 1999}, "22:42:43": {"name": "u9f20u6807", "price": 10}, "22:46:16": {"name": "u9f20u6807", "price": 10}, "22:56:56": {"name": "u9f20u6807", "price": 10}, "23:13:32": {"name": "u7535u8111", "price": 1999}}}}, "repayment_money": 0}
    atm/atm/db/account/liubei.json
    {"lock state": true, "account": "liubei", "password": "lb123", "limit": 15000, "balance": 823.1000000000003, "record": {"withdraw": {"20180807": {"00:00:00": 100, "18:00:15": 123, "18:01:24": 321, "18:05:51": 1, "20:01:08": 1234, "20:04:03": 123, "20:17:42": 100, "20:56:57": 5000, "21:00:57": 5000, "21:07:00": 5000, "22:48:56": 100, "23:18:59": 210.0, "23:22:23": 210.0, "23:22:45": 210.0, "23:23:59": 210.0}, "20180808": {"17:05:34": 105.0, "19:50:45": 1377.6000000000001, "20:20:33": 1.05, "21:36:22": 1.05, "22:45:15": 1.05, "22:56:45": 2.1, "22:57:17": 1.05}}, "repayment": {"20180101": {"00:00:00": 1}, "20180807": {"20:38:54": 0, "20:40:27": 0, "20:42:09": 0, "20:43:38": 0, "20:57:06": 0, "21:01:13": 1, "21:02:23": 1, "21:02:38": 4997, "21:06:51": 1, "21:07:08": 10000, "21:36:09": 500, "21:37:24": 500, "21:38:38": 500, "21:40:17": 500, "21:43:38": 500, "21:46:08": 500, "21:47:09": 1, "21:59:02": 1, "21:59:17": 500, "23:01:55": 1301}, "20180808": {"17:06:10": 100, "17:06:15": 845.0, "22:57:32": 1}}, "transfer out": {"20180807": {"22:37:54": 123, "22:39:25": 0, "22:43:40": 4999, "22:48:36": 1, "22:49:40": 200, "22:50:41": 1000, "22:52:27": 0, "22:58:38": 0}, "20180808": {"17:06:31": 0, "23:02:45": 1}}, "transfer in": {}, "consumption": {"20180808": {"20:24:50": {"name": "u9f20u6807", "price": 10}, "20:24:51": {"name": "u9f20u6807", "price": 10}, "20:24:52": {"name": "u9f20u6807", "price": 10}, "20:24:53": {"name": "u9f20u6807", "price": 10}, "20:26:25": {"name": "u9f20u6807", "price": 10}, "20:26:26": {"name": "u9f20u6807", "price": 10}, "20:26:27": {"name": "u9f20u6807", "price": 10}, "20:26:28": {"name": "u9f20u6807", "price": 10}, "20:26:29": {"name": "u9f20u6807", "price": 10}, "20:29:45": {"name": "u6e38u8247", "price": 20}, "20:30:17": {"name": "u6e38u8247", "price": 20}, "20:30:24": {"name": "u6e38u8247", "price": 20}, "20:30:26": {"name": "u6e38u8247", "price": 20}, "20:33:58": {"name": "u7f8eu5973", "price": 998}, "20:35:02": {"name": "u7f8eu5973", "price": 998}, "20:35:49": {"name": "u9f20u6807", "price": 10}, "20:35:51": {"name": "u9f20u6807", "price": 10}, "20:37:29": {"name": "u9f20u6807", "price": 10}, "20:37:39": {"name": "u9f20u6807", "price": 10}, "20:37:53": {"name": "u9f20u6807", "price": 10}, "20:37:54": {"name": "u9f20u6807", "price": 10}, "20:37:59": {"name": "u9f20u6807", "price": 10}, "20:45:08": {"name": "u9f20u6807", "price": 10}, "20:45:10": {"name": "u9f20u6807", "price": 10}, "20:49:09": {"name": "u9f20u6807", "price": 10}, "20:49:10": {"name": "u9f20u6807", "price": 10}, "20:49:13": {"name": "u9f20u6807", "price": 10}, "20:49:19": {"name": "u9f20u6807", "price": 10}, "20:49:38": {"name": "u9f20u6807", "price": 10}, "20:49:40": {"name": "u9f20u6807", "price": 10}, "20:49:41": {"name": "u9f20u6807", "price": 10}, "20:49:42": {"name": "u9f20u6807", "price": 10}, "20:49:43": {"name": "u9f20u6807", "price": 10}, "20:56:34": {"name": "u9f20u6807", "price": 10}, "20:56:36": {"name": "u9f20u6807", "price": 10}, "20:58:59": {"name": "u9f20u6807", "price": 10}, "20:59:21": {"name": "u9f20u6807", "price": 10}, "21:22:02": {"name": "u9f20u6807", "price": 10}, "21:23:25": {"name": "u6e38u8247", "price": 20}, "21:23:54": {"name": "u9f20u6807", "price": 10}, "21:26:59": {"name": "u7f8eu5973", "price": 998}, "21:29:53": {"name": "u9f20u6807", "price": 10}, "21:34:57": {"name": "u9f20u6807", "price": 10}, "21:37:50": {"name": "u7535u8111", "price": 1999}, "21:43:46": {"name": "u6e38u8247", "price": 20}, "21:44:40": {"name": "u9f20u6807", "price": 10}, "21:51:24": {"name": "u9f20u6807", "price": 10}, "21:54:54": {"name": "u9f20u6807", "price": 10}, "23:04:18": {"name": "u9f20u6807", "price": 10}, "23:39:52": {"name": "u9f20u6807", "price": 10}}}}, "repayment_money": 845.0}

    atm/atm/interface/pay_interface.py
    import os
    import sys
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_PATH)
    
    from core import main
    
    
    def run(data):
        main.pay_interface(data)

    atm/atm/logs/...


    shopping/shopping.py
    {"lock state": true, "account": "liubei", "password": "lb123", "balance": 973, "record": {"20180101": {"00:00:00": {"name": "u7535u8111", "price": 1999}, "23:01:02": {"name": "u9f20u6807", "price": 10}}, "20180202": {"00:02:00": {"name": "u7f8eu5973", "price": 998}}, "20180724": {"22:11:13": {"name": "u7535u8111", "price": 1999}, "22:11:14": {"name": "u9f20u6807", "price": 10}, "22:38:21": {"name": "u7535u8111", "price": 1999}, "22:40:32": {"name": "u7535u8111", "price": 1999}, "22:41:31": {"name": "u7535u8111", "price": 1999}, "22:41:35": {"name": "u9f20u6807", "price": 10}, "22:42:41": {"name": "u7535u8111", "price": 1999}, "22:42:43": {"name": "u9f20u6807", "price": 10}, "22:46:16": {"name": "u9f20u6807", "price": 10}, "22:56:56": {"name": "u9f20u6807", "price": 10}, "23:13:32": {"name": "u7535u8111", "price": 1999}}, "20180808": {"20:28:50": {"name": "u9f20u6807", "price": 10}, "21:53:58": {"name": "u9f20u6807", "price": 10}, "21:54:57": {"name": "u9f20u6807", "price": 10}, "23:04:07": {"name": "u7f8eu5973", "price": 998}, "23:04:20": {"name": "u9f20u6807", "price": 10}, "23:39:55": {"name": "u9f20u6807", "price": 10}}}}

    shopping/data/liubei.json
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    '''
    测试账号(用户名:liubei,密码:lb123)
    '''
    
    import os
    import sys
    import time
    import json
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_PATH)
    
    from atm.interface import pay_interface
    # from atm.core import main
    
    
    
    goods = [
        {'name': '电脑', 'price': 1999},
        {'name': '鼠标', 'price': 10},
        {'name': '游艇', 'price': 20},
        {'name': '美女', 'price': 998}
    ]
    
    
    class Shopping(object):
        def __init__(self):
            self.acc_data = {}  # 用户信息
    
        def authentication(self):
            '''
            用户认证程序
            :return:登陆成功返回True
            '''
            acc = ''
            auth_list = []  # 用于存放每次输入的用户名
    
            print('- - - Login - - -')
            while auth_list.count(acc) < 3:  # 当相同的用户名登陆失败3次,跳出循环
                acc = input('Account:').strip()
                pwd = input('Password:').strip()
    
                path = 'data\%s' % acc  # 用户信息存放路径
                if os.path.isfile(path):  # 用户名是否存在
                    with open(path) as f:
                        self.acc_data = json.loads(f.read())    #读取信息
                        if self.acc_data['lock state']:  #用户是否被锁定
                            if self.acc_data['password'] == pwd:
                                print('Login success !')
                                return True
                            else:
                                auth_list.append(acc)
                                print('The password is error,you have %s times' % (3 - auth_list.count(acc)))
                        else:
                            print('You have tried 3 times,your account has locked.')
                            exit()
                else:
                    auth_list.append(acc)
                    print('The account is not exist...you have %s times' % (3 - auth_list.count(acc)))
    
            if auth_list.count(acc) == 3:  # 已存在的用户登陆失败三次,锁定,写入文件
                if os.path.isfile(path):
                    with open(path, 'w')as f:
                        self.acc_data['lock state'] = False
                        f.write(json.dumps(self.acc_data))
    
        def shopping(self):
            '''
            购物窗口
            :return:
            '''
            buy_dic = []
            while True:
                print('List of goods'.center(30,'-'))
                for index,item in enumerate(goods,1):
                    print('%s . 33[0;33m%s33[0m   33[0;32m%s33[0m'%(index,item['name'],item['price']))
                buy = input('("q" to exit)
    choose one to buy:').strip()
                if buy.isnumeric() and 0 < int(buy) <= len(goods): #输入是数字且在商品序号范围内
                    print('''
                    - - - choose how to pay - - -
                    1. Shopping VIP Card
                    2. Credit Card''')
                    pay_way = input('>>>').strip()
                    if pay_way == '1':  # 选择使用超市vip付款
                        if self.acc_data['balance'] >= int(goods[int(buy) - 1]['price']):
                            self.acc_data['balance'] -= int(goods[int(buy) - 1]['price'])    # 扣除余额
                        else:
                            print('33[0;33mYour balance can not afford anyone..33[0m')
                    elif pay_way == '2':
                        pay_interface.run(goods[int(buy) - 1])  # 调用atm
    
                    # 更新购物清单
                    buy_dic.append(goods[int(buy) - 1])  # 购物记录
                    localday = time.strftime('%Y%m%d', time.localtime())
                    localtime = time.strftime('%H:%M:%S', time.localtime())
                    if localday in self.acc_data['record']:
                        self.acc_data['record'][localday][localtime] = goods[int(buy) - 1]
                    else:
                        self.acc_data['record'][localday] = {localtime: goods[int(buy) - 1]}
                    # 写入文件
                    if self.db_handle():
                        print('You have buy:33[0;32m%s33[0m' % goods[int(buy) - 1]['name'])
                    else:
                        print('33[0;31mSystem error...you have not buy %s33[0m' % goods[int(buy) - 1]['name'])
    
                elif buy == 'q':
                    if len(buy_dic) != 0:
                        print('33[1;31;46mShopping receipts33[0m')
                        for index,item in enumerate(buy_dic,1):
                            print('%s . 33[0;33m%s33[0m   33[0;32m%s33[0m' % (index, item['name'], item['price']))
                    break
                else:
                    print('33[0;31minput error...33[0m')
    
        def recharge(self):
            '''
            充值
            :return:
            '''
            recharge = input('You want to recharge:').strip()
            if recharge.isnumeric() and int(recharge) < 0:
                print('33[0;31mPlease input a number greater than zero33[0m')
            elif recharge.isnumeric():
                self.acc_data['balance'] += int(recharge)
                if self.db_handle():
                    print('33[0;31mRecharge success !33[0m')
                else:
                    print('33[0;31mRecharge error...33[0m')
            else:
                print('33[0;31minput error...33[0m')
    
        def record(self):
            '''
            查询历史清单
            :return:
            '''
            for date in self.acc_data['record']:
                print('33[0;34m%s33[0m'%date.center(20, '-'))
                for time in self.acc_data['record'][date]:
                    print(time, ':', self.acc_data['record'][date][time]['name'],
                          self.acc_data['record'][date][time]['price'])
    
        def exit(self):
            '''
            退出函数
            :return:
            '''
            print('exit...')
            exit()
    
        def db_handle(self):
            '''
            文件写入
            :return:
            '''
            with open('data\'+self.acc_data['account'],'w') as f:
                f.write(json.dumps(self.acc_data))
                return True
    
        def interaction(self):
            '''
            交互
            :return:
            '''
            print(' Mall '.center(30, '*'))
            if self.authentication():    #登陆认证成功
                exit_flag = False
                while not exit_flag:
                    print('''
    Vip name:{account}
    Balance:33[1;31;46m{balance}33[0m
    
    1.  购物
    2.  充值
    3.  清单
    4.  退出
                    '''.format(account=self.acc_data['account'], balance=self.acc_data['balance']))
    
                    menu_dic = { #对应类方法的字典
                        '1': self.shopping,
                        '2': self.recharge,
                        '3': self.record,
                        '4': self.exit
                    }
                    user_option = input('>>>').strip()
                    if user_option in menu_dic:
                        menu_dic[user_option]()
                    else:
                        print('Without this option(%s)' % user_option)
    
    if __name__ == '__main__':
        s = Shopping()    #实例化
        s.interaction()
  • 相关阅读:
    git常用命令总结
    chrome浏览器使用技巧
    chorme浏览器的Access-Control-Allow-Origin拦截限制
    基于HP DL388 Gen 9服务器基本配置(ESXI 6.5)
    c# winform 窗体之间的传参
    <<测试驱动开发的艺术>>读书笔记
    <<人性的弱点>>读书笔记
    一个很奇怪的重复链接lib的问题
    redis集群的一些笔记
    <<敏捷开发>>读书笔记
  • 原文地址:https://www.cnblogs.com/q1ang/p/9000361.html
Copyright © 2020-2023  润新知