ATM和购物商城-错题集

1、获取当前月份前一个月月份

import datetime
aaa = ((datetime.datetime.now() + datetime.timedelta(days = -30))).strftime("%Y%m")
print(aaa)

2、遍历目录

os.walk(dir_name)

def go_though():
    '''
    遍历指定目录
    '''
    db_path = db_handler.db_handler(settings.DATABASE)
    # 获取路径,目录,文件名称
    for root, dirs, files in os.walk(db_path):
        print("root:%s, dirs:%s files:%s" % (root,dirs,files))
        for f in files:
            # 判断是否存在.json结尾的文件
            if os.path.splitext(f)[1] == ".json":
                # 获取账户ID
                account_id = os.path.splitext(f)[0]  # 帐户id
                # account_file = "%s/%s.json" % (db_path, account_id)
                # account_data = auth.check_account(account_id)  # 获取用户信息
                account_data = auth.ck_acc_data(account_id)
                # 判断用户权限是否为管理员
                if account_data:
                    status = account_data['status']
                    # print(status)
                    print("Account bill:".center(50, "-"))

                    # 除了管理员,普通帐户都应该出帐单,即使帐户禁用
                    if status != 8:
                        # print("status != 8 ",account_id)
                        auth.display_account_info(account_data)
                        get_user_bill(account_id)  # 获取帐单
                        print("End".center(50, "-"))
    return True
    
3、用户登录次数验证


def acc_login(user_data,log_obj):
    '''
    判断用户登录错误次数,超过3次记录日志和打印屏幕输出,使用字典方式支持多用户互相切换错误记录
    :param user_data:
    :param log_obj: access_logger
    :return: auth  =  account_data
    '''
    account_login_dic = {}
    retry_count = 0
    exit_count = 4


    while user_data['is_authorized'] is False and retry_count < exit_count:
        account = input('\033[32;1m请输入账户ID:\033[0m'.strip())
        password = input('\033[32;1m请输入密码:\033[0m'.strip())

        #  判断用户正确性,用户正确则初始化用户数据状态
        auth = acc_auth(account,password)
        if auth:
            user_data['is_authorized'] = True
            user_data['account_id'] = account
            return auth
        else:
            #先检测 dic 里面是否有相同名称 的key,没有就增加,有就取value
            if account not in account_login_dic:  # 如果账户不存在于字典
                count = 0
                count += 1
                account_login_dic.update({account:count}) # 初始化新用户到字典
            else:
                count = account_login_dic[account]  # 初始化 计数
                count += 1                          # 到此处错误已经产生,错误次数+1
                account_login_dic.update({account:count})  # 将用户对应错误次数更新到字典
                # print("old",account_login_dic)
                for i in account_login_dic.values():  # 判断字典中用户名对应的 错误次数
                    retry_count = i
                    # print(retry_count)
                    if retry_count == 3:  # 判断用户是否产生3次错误,3次错误 记录日志 并且 退出当前程序
                        curr_account = list(account_login_dic.keys())[list(account_login_dic.values()).index(retry_count)]
                        # print(curr_account)
                        #  记录用户错误行为日志
                        log_obj.error(" [%s] have try too many attempts,System exit!" % (curr_account))
                        exit()
                        

4、初始化用户数据到字典,再将字典写入数据文件

curr_day = datetime.datetime.now().strftime("%Y-%m-%d")  #  当前日期
yesterday = datetime.datetime.now() + datetime.timedelta(days=-1)  #  昨天日期
after_3_years_day = yesterday.replace(year=(int(yesterday.strftime("%Y")) + 3))  # 三年后的昨天(过期时间)
expire_day = after_3_years_day.strftime('%Y-%m-%d')   # 过期日期
pay_day = 22  # 还款日

account_data = {
            'enroll_date': curr_day,
            'password': password,
            'id': account,
            'credit': 15000,
            'status': 0,
            'balance': 0.0,
            'expire_date': expire_day,
            'pay_day': pay_day
 }
#  存储新用户数据
accounts.dump_account(account_data)

5、空格分隔数据

    # 格式化输出结果,a,b间隔20个空格,以':' 分隔,b变色
    print("{:<20}:\033[32;1m{:<20}\033[0m".format(a,b))
    
6、密码加密
def get_md5(password):
    '''
    用户密码加密
    :param password:
    :return:
    '''
    # 获取 md5
    md5 = hashlib.md5()
    md5.update(password)
    return md5.hexdigest()
    
7、日志记录函数
def logger(log_type):
    '''
    日志输出和记录
    :param log_type:
    :return:
    '''
    logger = logging.getLogger(log_type)
    logger.setLevel(settings.LOG_LEVEL)

    # 屏幕输出 screen output show
    ch = logging.StreamHandler()
    ch.setLevel(settings.LOG_LEVEL)  # 屏幕 输出 info

    # 日志文件输出 logs file output
    log_file = "%s/logs/%s" % (settings.BASE_DIR,settings.LOG_TYPES[log_type])
    # print(log_file)
    fh = logging.FileHandler(log_file)

    fh.setLevel(settings.LOG_LEVEL)  # 日志记录 info

    #日志输出格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')

    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    #屏幕输出和日志输出加入到logger
    logger.addHandler(ch)
    logger.addHandler(fh)

    #返回输出
    return logger

8、根据传入类型函数进行操作函数
类型为在配置中定义值
TRANSACTION_TYPE = {
    'repay': {'action': 'plus', 'interest': 0}, # 还款
    'receive': {'action': 'plus', 'interest': 0},   # 接收
    'withdraw': {'action': 'minus', 'interest': 0.05},  # 提款
    'transfer': {'action': 'minus', 'interest': 0.05},  # 转出
    'pay': {'action': 'minus', 'interest': 0},  # 支付
    'save': {'action': 'plus', 'interest': 0},  # 存钱

}

def make_transaction(log_obj,account_data,trans_type,amount,**others):
    '''
    用户金额操作改动数据后存储日志,改动后返回用户数据
    :param log_obj:
    :param account_data:
    :param trans_type:
    :param amount:
    :param others:
    :return:account_data
    '''
    # 金额转换浮点类型
    amount = float(amount)

    #  判断 交易类型
    if trans_type in settings.TRANSACTION_TYPE:  # 交易类型存在
        interest = amount * settings.TRANSACTION_TYPE[trans_type]['interest']  # 定义利息
        old_balance = account_data['balance']   # 初始化 交易前的值

        #  根据交易类型,对金额进行加减操作,并减除带有利息的操作
        if settings.TRANSACTION_TYPE[trans_type]['action'] == 'plus':
            new_balance = old_balance + amount + interest
            account_data['balance'] = new_balance
            accounts.dump_account(account_data)

        elif settings.TRANSACTION_TYPE[trans_type]['action'] == 'minus':
            new_balance = old_balance - amount - interest
            if new_balance < 0:
                print("\033[32;1m 您的信用额度为:[%s],您的额度不支持本次操作[-%s],您当前的余额为:[%s]\033[0m"
                      %(account_data['credit'],(amount +interest),old_balance))
                return False
            account_data['balance'] = new_balance
            accounts.dump_account(account_data)
        # log_obj = transaction_logger = logger.logger('transaction')
        # 将操作记录到日志文件
        log_obj.info("accounts:%s   action:%s   amount:%s   interest:%s "
                     %(account_data['id'],trans_type,amount,interest))
        return account_data
    else:
        print("您的选项有误或不存在:%s"%(trans_type))
        

9、接口调用流程
调用方:
以充值为例:
                        atm_api = os.path.dirname(BASE_DIR) + "/Atm/api/pay_api.py"
                        #  定义  接口文件和金额
                        comm = "python " + atm_api + " " + charge
                        # 创建 调用进程,执行指定的comm
                        pgm = subprocess.Popen(comm,shell=True)
                        # 接口文件交互
                        pgm.communicate()
                        if pgm.returncode == 0:
                            print("\033[31;1m付款成功\033[0m")
                            # 充值成功后,更新用户余额
                            acc_data['balance'] += float(charge)
                            # 将用户余额存入账户
                            accounts.dumpAccount(acc_data)
                            print("您的余额为:%s"%acc_data['balance'])

                        else:
                            print("充值失败!")
                            
                            
            

被调用方 入口   
pay_api.py

# 取金额参数
amount = sys.argv[1]

# 执行接口程序调用,定义退出
rlt = main.payApi(amount)

if rlt:
    exit(0)
else:
    exit(1)


def payApi(amount):
    '''
    交易接口,提供给其他消费方式调用
    :param amount:
    :return:
    '''
    amount = int(amount)
    acc_data = get_user_data()
    # print("\033[42;1m payApi \033[0m",acc_data)
    # 根据获取到的用户id 获取用户数据
    account_data = accounts.load_balance(acc_data['account_id'])
    # 判断交易金额 是否大于,交易大于0 则进行交易操作
    if amount > 0:
        new_balance = transaction.make_transaction(transaction_logger,account_data,'pay',amount)
        if new_balance:
            return True
    else:
        print("你的输入 [%s] 有误,请输入数字金额"% amount)
        return None

 

posted @ 2018-04-16 15:11  boundshunter  阅读(158)  评论(0编辑  收藏  举报