• python练习题-day20


    1、json、pickle、shelve三个区别是什么?

    首先,这三个模块都是序列化工具。
     1. json是所有语言的序列化工具,优点跨语言、体积小.只能序列化一些基本的数据类型。intstrlist	upledict
     pickle是python语言特有序列化工具,所有数据都能序列化。只能在python中使用,存储数据占空间大.
     shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。

    2、json的作用是什么?

    序列化,把dict,tuple,list等内存对象转换为字符串,持久化数据,存储到硬盘中或网络传输,因为网络和硬盘只接受bytes

    3、为什么要设计好目录结构?

    1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
    2.可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。

    4、打印出命令行的第一个参数。例如:

    python argument.py luffy
    打印出 luffy
    import sys
    print(sys.argv[1])

    5、

    '''
    Linux当前目录/usr/local/nginx/html/
    文件名:index.html
    '''
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath('index.html')))
    print(BASE_DIR)
    
    打印
    /usr/local/nginx/

    6、os.path.dirname和os.path.abspath含义是什么?

    os.path.dirname:指定文件的目录
    os.path.abspath:指定文件的绝对路径

    7、通过configparser模块完成以下功能

    文件名my.cnf

    [DEFAULT]
    
     [client]
     port = 3306
     socket = /data/mysql_3306/mysql.sock
    
     [mysqld]
     explicit_defaults_for_timestamp = true
     port = 3306
     socket = /data/mysql_3306/mysql.sock
     back_log = 80
     basedir = /usr/local/mysql
     tmpdir = /tmp
     datadir = /data/mysql_3306
     default-time-zone = '+8:00'

    修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00

    删除 explicit_defaults_for_timestamp = true

    为DEFAULT增加一条 character-set-server = utf8

    import configparser
    import os
    config = configparser.ConfigParser()
    config.read('my.cnf')
    new_file = 'my.cnf%s'%('new')
    with open(new_file,'w') as new_f:
    
        print(config.sections())
        print(config)
        # 为DEFAULT增加一条 character-set-server = utf8
        config['DEFAULT']={'character-set-server':'utf8'}
        # 修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00
        config.set('mysqld','default-time-zone','+00:00')
        # 删除 explicit_defaults_for_timestamp = true
        config.remove_option('mysqld','explicit_defaults_for_timestamp')
        config.write(new_f)
    os.remove('my.cnf')
    os.rename(new_file,'my.cnf')

    8、写一个6位随机验证码程序(使用random模块),要求验证码中至少包含一个数字、一个小写字母、一个大写字母.、

    import random
    a=list(range(48,58))+list(range(65,91))+list(range(97,123))
    count=0
    list_code=[]
    c1=random.choice(list(range(48,58)))
    list_code.append(c1)
    c2=random.choice(list(range(65,91)))
    list_code.append(c2)
    c3=random.choice(list(range(97,123)))
    list_code.append(c3)
    while count<3:
        c=random.choice(a)
        list_code.append(c)
        count+=1
    random.shuffle(list_code)
    str_code=""
    for i in list_code:
        str_code+=chr(i)
    print(str_code)

    9、利用正则表达式提取到 luffycity.com ,内容如下

    s='''
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>luffycity.com</title>
    </head>
    <body>
    </body>
    </html>
    '''
    
    import re
    match_s = re.findall('<title>(.*?)</title>',s)
    print(match_s[0])

    10、写一个用户登录验证程序,文件如下 1234.json

    import json
    import time
    with open("1234.json","r+",encoding="utf-8") as f1:
        ret=json.load(f1)
    count=0
    if ret.get("status")==0:
        ex_t=ret.get("expire_date")
        st_t=time.strptime(ex_t,"%Y-%m-%d")
        c_t=time.mktime(st_t)
        g_t=c_t-time.time()
        if g_t>0:
            while count<3:
                uname=input("pls input your username:")
                pwd=input("pls input your password:")
                if uname =="1234" and pwd==ret.get("password"):
                    print("登录成功")
                    break
                else:
                    print("用户名或密码错误,请重新输入(%s后锁定)"%(2-count))
                    count+=1
            if count==3:
                print("账号已锁定")
                ret["status"]=1
                with open("1234.json","w+",encoding="utf-8") as f2:
                    json.dump(ret,f2)
        else:
            print("密码已过期")
    if ret.get("status")==1:
        print("账号已锁定")

    11、把第上一题三次验证的密码进行hashlib加密处理。即:json文件保存为md5的值,然后用md5的值进行验证。

    加密密码

    f ='1234.json'
    fp = open(f,'r+',encoding='utf-8')
    j_user = json.load(fp)
    md = hashlib.md5()
    md.update('abc'.encode('utf-8'))
    md_pwd = md.hexdigest()
    print(md_pwd)
    j_user["password"] = md_pwd
    fp.seek(0)
    fp.truncate()  # 清空文件内容
    json.dump(j_user,fp)  # 写入md5密码信息
    fp.close()
    count = 0
    exit_flag = False
    md = hashlib.md5()
    
    while count < 3:
        user = input('输入用户名: ')
        f = user.strip()+'.json'
        if os.path.exists(f):
            fp = open(f,'r+',encoding='utf-8')
            j_user = json.load(fp)
            if j_user["status"] == 1:
                print('账号已经锁定')
                break
            else:
                expire_dt = j_user["expire_date"]
    
                current_st = time.time()
                expire_st = time.mktime(time.strptime(expire_dt,'%Y-%m-%d'))
                # print(expire_st,current_st)
                if current_st > expire_st:
                    print('用户已经过期')
                    break
                else:
                    while count < 3:
                        pwd = input('输入密码: ')
                        md.update(pwd.strip().encode('utf-8'))
                        md5_pwd = md.hexdigest()
                        if md5_pwd == j_user["password"]:
                            print('用户[%s]登录成功'%user)
                            exit_flag = True
                            break
                        else:
                            print('密码不对')
                            if count == 2:
                                print('用户登录已超过3次,锁定账号')
                                j_user["status"] = 1
                                fp.seek(0)
                                fp.truncate()  # 清空文件内容
                                json.dump(j_user,fp)  # 写入锁定信息
                                fp.close()
    
                        count += 1
        if exit_flag:
            break
        else:
            print('用户不存在')
            count += 1

    12、

    1. 最近luffy买了个tesla,通过转账的形式,并且支付了5%的手续费,tesla价格为75万。文件为json,请用程序实现该转账行为。 需求如下:

    2. 目录结构为

        .
      ├── account
      │ ├── luffy.json
      │ └── tesla.json
      └── bin
      └── start.py

    当执行start.py时,出现交互窗口

      
    ------- Luffy Bank ---------
    1. 账户信息
    2. 转账
    • 选择1 账户信息 显示luffy的当前账户余额。

    • 选择2 转账 直接扣掉75万和利息费用并且tesla账户增加75万

    • 对上题增加一个需求:提现。 目录结构如下

        
      .
      ├── account
      │ └── luffy.json
      ├── bin
      │ └── start.py
      └── core
      └── withdraw.py

    当执行start.py时,出现交互窗口

      
    ------- Luffy Bank ---------
    1. 账户信息
    2. 提现
    • 选择1 账户信息 显示luffy的当前账户余额和信用额度。

    • 选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。

    • 尝试把上一章的验证用户登陆的装饰器添加到提现和转账的功能上。

    • 对第用户转账、登录、提现操作均通过logging模块记录日志,日志文件位置如下

        .
      ├── account
      │ └── luffy.json
      ├── bin
      │ └── start.py
      └── core
      | └── withdraw.py
      └── logs
      └── bank.log

     目录结构

    代码 settings.py

    import os
    
    '''
    日志文件设置
    '''
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    LOG_LEVEL='INFO'
    LOG_FILE='bank.log'
    
    '''
    交易类型
    '''
    TRANS_TYPE={
        'withdraw':{'interest':0.05,'action':'minus'},
        'transfer': {'interest': 0.05, 'action': 'minus'}
    }
    
    print(BASE_DIR)

    代码 my_logset.py

    import logging
    import os
    from conf import settings
    
    # 日志格式
    log_format = '[%(asctime)s - %(levelname)s - %(name)s - %(filename)s - %(lineno)d ] %(message)s '
    
    def get_mylogger(name):
        """
        get log
        :param name:
        :return:
        """
        logger = logging.getLogger(name)
        logger.setLevel(settings.LOG_LEVEL)
    
        console_handler = logging.StreamHandler()
        # 文件绝对路径
        logfile_path = os.path.join(settings.BASE_DIR, 'log',settings.LOG_FILE)
        file_handler = logging.FileHandler(logfile_path)
    
        logger.addHandler(console_handler)
        logger.addHandler(file_handler)
    
        file_format = logging.Formatter(fmt=log_format)
        console_format = logging.Formatter(fmt=log_format, datefmt='%Y-%m-%d %H:%M:%S ')
    
        console_handler.setFormatter(console_format)
        file_handler.setFormatter(file_format)
    
        return logger
    
    if __name__ == '__main__':
        log = get_mylogger('access')
        log.info('access')
        log.error('Error')
    
        log1 = get_mylogger('trans')
        log1.info('trans')

     代码 auth.py

    import json
    import time
    import os
    from conf import settings
    from log import my_logset
    from functools import wraps
    
    
    # logger = my_logset.get_mylogger('access')
    
    
    def login_required(func):
        """
         登录认证装饰器
        :param func:
        :return:
        """
        @wraps(func)
        def wrapper(*args,**kwargs):
            # print(args[0].get('is_authenticated'))
            if args[0].get('is_authenticated'):
                print('execute %s'%func.__name__)
                res = func(*args, **kwargs)
            else:
                exit('user is not authenticated')
            return res
    
        return wrapper
    
    
    def acc_login(user, pwd,logger):
        """
         用户登录
        :param log_obj:
        :return:
        """
        # 账号文件
        account_file = os.path.join(settings.BASE_DIR,'account','%s.json'%user)
        if os.path.isfile(account_file):
            user_fp = open(account_file,'r',encoding='utf-8')
            account_data = json.load(fp=user_fp)
            if account_data["password"] == pwd:
                exp_time_stamp = time.mktime(time.strptime(account_data["expire_date"],'%Y-%m-%d'))
                status = account_data['status']
                if time.time() > exp_time_stamp:
                    msg = 'Account [%s] has expired,please contact the back to get a new card!' % user
                    logger.error(msg)
    
                elif status != 0:
                    msg = 'Account [%s] has frozen' % user
                    logger.error(msg)
    
                else:
                    logger.info('***********欢迎{}登录***********'.format(user))
                    return account_data
            else:
                logger.error("Account ID or password is incorrect!")
        else:
            msg = "Account [%s] does not exist!" % user
            logger.error(msg)
    
    def auth_acc(user_data,logger):
        """
         用户登录
        :return:
        """
        retry_count = 0
        if user_data['is_authenticated'] is not True:
            while retry_count < 3:
                user = input('input username: ').strip()
                pwd = input('input password: ').strip()
    
                acc_data = acc_login(user, pwd,logger)
                if acc_data:
                    user_data['is_authenticated'] = True
                    return acc_data
    
                retry_count +=1
            else:
                exit("account too many login attempts" )
    
    
    if __name__ == '__main__':
        logger = my_logset.get_mylogger('access')
        user_data = {'is_authenticated':False}
        auth_acc(user_data,logger)

    代码 main.py

    import os
    import json
    from core import auth
    from core.auth import login_required
    from conf import settings
    from log import my_logset
    
    
    
    user_data = {
        'user_id':None,
        'is_authenticated':False,
        'user':None
    }
    
    # transaction logger
    trans_logger = my_logset.get_mylogger('transaction')
    # access logger
    access_logger = my_logset.get_mylogger('access')
    
    @login_required
    def account_info(user_data):
        """
           print acoount_info
           :param acc_data:
           :return:
           """
        curr_data = user_data['user']
        current_user = ''' 
           --------- USER INFO --------
           user_id:     {}
           Credit :     {}
           Balance:     {}
           expire_date: {}      
           ----------------------------------
           '''.format(curr_data['id'], curr_data['credit'], curr_data['balance'],curr_data['expire_date'])
        access_logger.info(current_user)
    
    @login_required
    def withdraw(user_data):
        """
    
         print current balance and let user do the withdraw action
        :param user_data:
        :return:
        """
        curr_data = user_data['user']
        back_flag = False
        while not back_flag:
            withdraw_amount = input("Input withdraw amount:").strip()
            if withdraw_amount.isdigit():
                    old_bal = curr_data['balance']
                    curr_data['balance'] = old_bal - float(withdraw_amount)*settings.TRANS_TYPE['withdraw']['interest']
                    if curr_data['balance']:
                        msg = "New Balance:%s" % (curr_data['balance'])
                        trans_logger.info(msg)
                        save_data(curr_data)
            elif withdraw_amount == 'b':
                back_flag = True
            else:
                msg = "[%s] is not a valid amount, only accept integer!" % withdraw_amount
                trans_logger.error(msg)
    
    
    
    @login_required
    def transfer(user_data):
        """
         print current balance and let user do the transfer action
        :param user_data:
        :return:
        """
        curr_data = user_data['user']
        back_flag = False
        while not back_flag:
            transfer_amount = input("Input transfer amount:").strip()
            tesla_data = get_data('tesla')  # 得到转账人的信息
            if transfer_amount.isdigit():
                transfer_amount = float(transfer_amount)  # 转账金额转化float
                old_bal = curr_data['balance']
                new_tesla_bal = tesla_data['balance'] + transfer_amount  # 得到转账人的余额
                curr_data['balance'] = old_bal - float(transfer_amount) * settings.TRANS_TYPE['withdraw']['interest']
                tesla_data['balance'] = new_tesla_bal
                if curr_data['balance']:
                    msg = "New Balance: %s new_tesla_bal: %s " % (curr_data['balance'], new_tesla_bal)
                    trans_logger.info(msg)
                    # 保存数据
                    save_data(curr_data)
                    save_data(tesla_data)
            elif transfer_amount == 'b':
                back_flag = True
            else:
                msg = "[%s] is not a valid amount, only accept integer!" % transfer_amount
                trans_logger.error(msg)
    
    
    def logout(user_data):
        """
        user logout
        :param acc_data:
        :return:
        """
        msg = "%s logout" % user_data['user_id']
        user_data['is_authenticated']= False
    
    
    def save_data(acc_data):
        """
         保存acc_data
        :param acc_data:
        :return:
        """
        file = os.path.join(settings.BASE_DIR,'account',acc_data['id']+'.json')
        user_fp = open(file,'w',encoding='utf-8')
        print('save_data: ',file, acc_data)
        json.dump(acc_data,user_fp,ensure_ascii=False)
        user_fp.close()
    
    def get_data(user_id):
        """
         得到acc_data
        :param user_id:
        :return:
        """
        file = os.path.join(settings.BASE_DIR, 'account', user_id+'.json')
        user_fp = open(file, 'r', encoding='utf-8')
        acc_data = json.load(user_fp)
        user_fp.close()
        return acc_data
    
    def interactive(acc_data):
    
        '''
        interact with user
        :return:
        '''
        menu = """
        ------- Bank ---------
        1.  账户信息(功能已实现)
        2.  取款(功能已实现)
        3.  转账(功能已实现)
        4.  用户退出(功能已实现)
        """
        menu_dic = {
            '1': account_info,
            '2': withdraw,
            '3': transfer,
            '4': logout,
        }
        exit_flag = False
        while not exit_flag:
            print(menu)
            user_option = input(">>:").strip()
            if user_option in menu_dic:
                # print('accdata', acc_data)
                # print(menu_dic[user_option], acc_data)
                menu_dic[user_option](acc_data)
            else:
                print("Option does not exist!", "error")
                exit_flag = True
    
    
    def run():
        '''
        this function will be called right a way when the program started, here handles the user interaction stuff
        :return:
        '''
        acc_data = auth.auth_acc(user_data,access_logger)
        # print(acc_data)
        # 如果用户认证成功
        if user_data['is_authenticated']:
             user_data['user'] = acc_data
             user_data['user_id'] = acc_data.get('id')
             interactive(user_data)
    
    
    if __name__ == '__main__':
        run()
        # print(a[0])

    代码 start.py

    import sys,os
    
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)  # 加入环境变量
    
    from core import main as m
    
    if __name__ == '__main__':
        m.run()

     

  • 相关阅读:
    跨浏览器 JavaScript判断窗口是否最小化
    .net 5 获取用户真实IP(nginx)
    C# EF 字符串模糊查询完整实例 lambda
    (zt)过程生成
    (zt)IOS开发常用的开源类库和一些示例
    wp7 生命周期及多任务 详解
    Js中concat()与push()的区别
    Ruby中p、print和puts的区别
    jquery Bug:当表单中包含name为nodeType的input时jquery选择器失效的bug 与您分享我的快乐
    Openlaszlo学习(一)Demo "Applying Constraints"的修改 与您分享我的快乐
  • 原文地址:https://www.cnblogs.com/fumy/p/10594834.html
Copyright © 2020-2023  润新知