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

原文地址:https://www.cnblogs.com/summer-han/p/8855976.html

时间: 2024-11-13 10:59:42

ATM和购物商城-错题集的相关文章

Python学习day5作业-ATM和购物商城

Python学习day5作业 Python学习day5作业 ATM和购物商城 作业需求 ATM: 指定最大透支额度 可取款 定期还款(每月指定日期还款,如15号) 可存款 定期出账单 支持多用户登陆,用户间转帐 支持多用户 管理员可添加账户.指定用户额度.冻结用户等 购物车: 商品信息- 数量.单价.名称 用户信息- 帐号.密码.余额 用户可充值 购物历史信息 允许用户多次购买,每次可购买多件 余额不足时进行提醒 用户退出时 ,输出当次购物信息 用户下次登陆时可查看购物历史 商品列表分级显示 1

node学习错题集

1.请求路径/favicon.ico 问题:node http.createServer()创建服务器,用户请求一次,但是服务器显示两次请求:一次为用户请求,一次请求路径为/favicon.ico ?? 代码如下: var http = require('http'); http.createServer(function(req,res){ console.log( req.url ); }).listen(8080);console.log("The server is on ...&quo

大学生活6 上课应该记笔记。应不应该有错题集?

个人观点.认为对,就做.认为错,就不做.即可 好记性不如烂笔头.上课应该记笔记,而且每一个必修,专业选修课程都应该有一个笔记本.有的人会说了,每个课程都有一个本子,那得多费钱呀.我说,不呀.你到网上买2,3块钱一个本子,课程笔记不建议你买厚的本子.为啥?你算一算,一学期有多少次课,每次课有几节,一节课你会记多少内容.你就会发现本子不需要太厚的. 每到期末考试阶段,有的同学就会说:史诗级灾难大片开始上演.为什么会出现这种现象?因为平时上课没有好好学习,作业不认真做,而且到了期末考试的时候发现自己手

C语言错题集

2018-10-02 C语言错题集 main 是一个合法的标识符吗? 答:是,main 是函数的标识符名称. 如果有符号常量定义如下: 1 #define F(n) 2*n 那么请问代码中 F(3+2) 的值等于多少? 答:F(3+2) == 2*3+2 == 8,注意,宏定义是在程序编译时先进行的预处理,做法是直接将标识符替换为常量,并不会进行相关运算.因此,直接将 F(3+2) 替换为 2*3+2. 我们说 printf() 是一个用于格式化打印的函数,那 sizeof() 是一个函数吗?

模拟实现ATM与购物商城

一.功能介绍(第6条未实现)模拟实现一个ATM + 购物商城程序1额度15000或自定义2实现购物商城,买东西加入购物车,调用信用卡接口结账3可以提现,手续费5%4支持多账户登录5支持账户间转账6记录每月日常消费流水7提供还款接口8ATM记录操作日志9提供管理接口,包括添加账户.用户额度,冻结账户等...10用户认证用装饰器 二.实现流程图 三.程序目录结构 ATM_WHW ├── whw_atm ├── README.txt ├── atm #入口程序目录 │ ├── __init__.py

数据结构——二叉树错题集

2-11 任何一棵二叉树的叶结点在先序.中序和后序遍历序列中的相对次序 遍历顺序 ,令所有遍历中的 根==NULL 遍历顺序都是 左右,即左节点先于右节点,不会改变顺序: 2-xx 先序序列遍历为 a b c d 的二叉树有多少个? 14 运用卡特兰算式 , n = 4 ,ans = C(n,2*n)/(n+1) = 14 1-5: 若一个结点是某二叉树的中序遍历序列的最后一个结点,则它必是该树的前序遍历序列中的最后一个结点. 错误: 特例: A-B-C 一条线上,C是根节点: 中序遍历:ABC

[初赛备战]计算机基础知识错题集(1)

这里整理一些错题,太sb的题就没放上来了,有些题还有疑问,求大佬解答,然后解析都是来自网络(wiki和百度百科),无法保证正确性. 在微机中,通用寄存器的位数是() A.8 位    B.16 位   C.计算机字长  D.32 位 计算机字长不仅是CPU一次可处理的位数,同时也是寄存器的位数. 不同的计算机,其指令系统也不相同,这主要取决于( ) A.所用的 CPU    B.所用的操作系统   C.所用的程序设计语言  D.系统的总体结构 主要是取决于所用的CPU指令系统的意思是计算机硬件的

错题集07

解析: 此题目考查的是对Hibernate中交叉连接的理解.HQL支持SQL风格的交叉连接查询,交叉连接适用于两个类之间没有定义任何关联时.在where字句中,通过属性作为筛选条件,如统计报表数据.使用交叉连接时应避免“from Dept,Emp”这样的语句出现.执行这条HQL查询语句,返回DEPT表和EMP表的交叉组合,结果集的记录数为两个表的记录数之积,也就是数据库中的笛卡尔积.这样的查询结果没有实际意义,因此选项b是正确的.A和C答案都是符合上述描述的,是适合使用交叉连接的场合.D答案认为

错题集

1.通过ServletResponse的()方法可以设置响应的字符编码类型(选择一项). A:setCharacterEncoding (String charset) B:setCharacterEncode (String charset) C:setCharset (String charset) D:setPageEncoding (String charset) 解析:request.setCharacterEncoding("UTF-8"); 2.在设计Web项目的目录结构