2.4 - 函数编程 - 总结练习题

1.logging 模块有几个日志级别?
debug info warning error critical

2.请配置logging模块,使其在屏幕和文件里同时打印以下格式的日志
2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts

import logging

logger = logging.getLogger('mylog')
logger.level = logging.INFO

fh = logging.FileHandler('log.log')
ch = logging.StreamHandler()
fh.level = logging.WARNING
ch.level = logging.ERROR

logger.addHandler(fh)
logger.addHandler(ch)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)s - %(message)s')

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

logger.debug('too many login attempts')
logger.info('too many login attempts')
logger.warning('too many login attempts')
logger.error('too many login attempts')
logger.critical('too many login attempts')

3.json、pickle、shelve三个区别是什么?
json:转化的数据类型,int str list tuple dict 不支持set
pickle: 支持python里的所有数据类型,只能在python里使用,函数也可以序列化
shelve: pickle封装了shelve只能在python中使用

4.json的作用是什么?
将内存里的数据类型转变成字符串,使其能存储到硬盘上或通过网络传输到远程,因为硬盘或网络传输只能接受bytes

5.subprocess执行命令方式有几种?
subprocess.run() subprocess.call() subprocess.Popen()

6.为什么要设计好目录结构?
可读性高,可维护性高

7.打印出命令行的第一个参数。例如:
python argument.py luffy
打印出 luffy
import sys
print(sys.argv[1:])
python exec.py luffy

8.代码如下:
'''
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)
打印的内容是什么? nginx
os.path.dirname和os.path.abspath含义是什么?
目录名,绝对路径

9.通过configparser模块完成以下功能

文件名my.cfg
[DEFAULT]

[client]
port = 3306
socket = /data/mysql_3306/mysql.sock

[mysqld]
explicit_defaults_for_timestamp = 342
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' 

1.修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00
2.删除 explicit_defaults_for_timestamp
3.为DEFAULT增加一条 character-set-server = utf8

import configparser

config = configparser.ConfigParser()
config.read('my.cfg')
config.set('mysqld','default-time-zone','+00.00')
config.write(open('my.cfg','w'))
config.remove_option('mysqld','explicit_defaults_for_timestamp')
config.write(open('my.cfg','w'))
config.set('DEFAULT','character-set-server','utf-8')
config.write(open('my.cfg','w'))

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

import random,string

s = string.ascii_letters + string.digits
print(s)
res = random.sample(s,6)
print(''.join(res))

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

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>luffycity.com</title>
</head>
<body>
</body>
</html>

print(re.search('\w+[^<>]+\.com',s).group())

12.写一个用户登录验证程序,文件如下
1234.json
{"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
1.用户名为json文件名,密码为 password。
2.判断是否过期,与expire_date进行对比。
3.登陆成功后,打印“登陆成功”,三次登陆失败,status值改为1,并且锁定账号。

import json,time

count = 0
data = json.load(open('1234.json','r',encoding='utf-8'))
_username = '1234.json'
_password = data['password']
time_json = time.mktime(time.strptime(data['expire_date'],'%Y-%m-%d'))
time_now = time.time()
while count < 3:
    if data['status'] == 1:
        print('账号已锁定!')
        break
    elif time_now > time_json:
        print('账号已过期!')
        break
    else:
        name = input('name:').strip()
        password = input('password:').strip()
        if name == _username and password == _password:
            print('登录成功!')
            break
        else:
            print('请重新输入')
        count += 1
else:
    data['status'] = 1
    json.dump(data,open('1234.json','w',encoding='utf-8'))

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

{"expire_date": "2019-03-01", "id": 1234, "status": 0, "pay_day": 22, "password": "900150983cd24fb0d6963f7d28e17f72"}
import json,time,hashlib

count = 0
data = json.load(open('1234.json','r',encoding='utf-8'))
_username = '1234.json'
_password = data['password'] #abc
time_json = time.mktime(time.strptime(data['expire_date'],'%Y-%m-%d'))
time_now = time.time()
while count < 3:
    if data['status'] == 1:
        print('账号已锁定!')
        break
    elif time_now > time_json:
        print('账号已过期!')
        break
    else:
        name = input('name:').strip()
        password = input('password:').strip()
        if name == _username:
            m = hashlib.md5()
            m.update(password.encode())
            if m.hexdigest() == _password:
                print('登录成功!')
                break
        else:
            print('请重新输入')
        count += 1
else:
    data['status'] = 1
    json.dump(data,open('1234.json','w',encoding='utf-8'))

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

目录结构为
.
├── account
│ ├── luffy.json
│ └── tesla.json
└── bin
└── start.py
当执行start.py时,出现交互窗口

------- Luffy Bank ---------
1. 账户信息
2. 转账
选择1 账户信息 显示luffy的当前账户余额。
选择2 转账 直接扣掉75万和利息费用并且tesla账户增加75万

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

.
├── account
│ └── luffy.json
├── bin
│ └── start.py
└── core
└── withdraw.py
当执行start.py时,出现交互窗口

------- Luffy Bank ---------
1. 账户信息
2. 提现
选择1 账户信息 显示luffy的当前账户余额和信用额度。
选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。

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

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

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

-----------------------------------------------------------

解答:

luffy.json
{"account_balance": 212500.0, "credit_account": 790000.0}
tesla.json
{"account_balance": 750000}
  1 # -*- coding:utf-8 -*-
  2 import os,sys
  3 import json
  4 import logging
  5 from logging import handlers
  6 core_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  7 sys.path.append(core_path)
  8 from core import withdraw
  9 
 10 _username = 'alice'
 11 _password = '123'
 12 msg = '''
 13 1. 账户信息
 14 2. 转账
 15 3. 提现
 16 '''
 17 json_path = os.path.join(core_path, 'account')
 18 flag_login = False
 19 logger = logging.getLogger('record')
 20 
 21 
 22 def log_record():
 23     global logger
 24     logger.setLevel(logging.DEBUG)
 25     # fh = logging.FileHandler(os.path.join(core_path, 'logs/bank.log'),encoding='utf-8')
 26     fh = logging.handlers.TimedRotatingFileHandler(filename=os.path.join(core_path, 'logs/bank.log'),when='S',interval=3,backupCount=3,encoding='utf-8')
 27     logger.addHandler(fh)
 28     f_formatter = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
 29     fh.setFormatter(f_formatter)
 30 
 31 
 32 def login(func):
 33     def inner():
 34         global flag_login
 35         if not flag_login:
 36             username = input('username:').strip()
 37             password = input('password:').strip()
 38             if username == _username and password == _password:
 39                 print('登录成功!')
 40                 flag_login = True
 41                 logger.info('登录成功')
 42             else:
 43                 print('用户名或密码有误!')
 44         else:
 45             print('用户已登录,通过认证')
 46         if flag_login is True:
 47             func()
 48     return inner
 49 
 50 
 51 def print_info():
 52     # 账户信息
 53     luffy_data = json.load(open(os.path.join(json_path, 'luffy.json'), 'r', encoding='utf-8'))
 54     print('account_balance:', luffy_data['account_balance'])
 55     print('credit_account:', luffy_data['credit_account'])
 56 
 57 
 58 @login
 59 def transfer_account():
 60     # 转账
 61     luffy_data = json.load(open(os.path.join(json_path, 'luffy.json'), 'r', encoding='utf-8'))
 62     tesla_data = {'account_balance': 750000}
 63     luffy_data['account_balance'] = luffy_data['account_balance'] - tesla_data['account_balance'] * (1 + 0.05)
 64     json.dump(luffy_data, open(os.path.join(json_path, 'luffy.json'), 'w', encoding='utf-8'))
 65     json.dump(tesla_data, open(os.path.join(json_path, 'tesla.json'), 'w', encoding='utf-8'))
 66     print('转账成功!')
 67     logger.debug('转账成功')
 68 
 69 
 70 @login
 71 def withdraws_func():
 72     # 提现
 73     moneys = input('moneys>>>:').strip()
 74     if moneys.isdigit():
 75         moneys = int(moneys)
 76         withdraw.withdraws(moneys, json_path, logger)
 77 
 78 
 79 def main():
 80     while True:
 81         print("Luffy Bank".center(30, '-'))
 82         print(msg)
 83         num = input('num(q表示退出)>>>:').strip()
 84         if not num:
 85             continue
 86         if num.isdigit():
 87             num = int(num)
 88             if num == 1:    # 账号信息
 89                 print_info()
 90             elif num == 2:  # 转账
 91                 transfer_account()
 92             elif num == 3:  # 提现
 93                 withdraws_func()
 94         elif num == 'q':
 95             exit()
 96 
 97 
 98 if __name__ == '__main__':
 99     log_record()
100     main()
start.py
 1 # -*- coding:utf-8 -*-
 2 import os, json
 3 
 4 
 5 def withdraws(moneys, json_path, logger):
 6     luffy_data = json.load(open(os.path.join(json_path, 'luffy.json'), 'r', encoding='utf-8'))
 7     if moneys <= luffy_data['credit_account']:
 8         luffy_data['credit_account'] = luffy_data['credit_account'] - moneys*(1+0.05)
 9         json.dump(luffy_data, open(os.path.join(json_path, 'luffy.json'), 'w', encoding='utf-8'))
10         print('提现成功!')
11         logger.warning('提现成功')
12     else:
13         print('\033[0;31m提现金额大于信用额度了!\033[0m')
14         logger.error('提现金额大于信用额度')
withdraw.py
bank.log
02/28/2018 10:00:51 PM - record - INFO - 登录成功
02/28/2018 10:00:55 PM - record - WARNING - 提现成功
02/28/2018 10:00:56 PM - record - DEBUG - 转账成功
posted @ 2018-02-28 21:44  Alice的小屋  阅读(326)  评论(3编辑  收藏  举报