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()
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('提现金额大于信用额度')
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 - 转账成功