1、logging模块有几个日志级别?
# answer
# logging模块共5个级别,它们分别是:
# DEBUG INFO WARNING ERROR CRITICAL
2、请配置logging模块,使其在屏幕和文件里同时打印以下格式的日志
2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts
import logging
ch = logging.StreamHandler()
fh = logging.FileHandler("access.log")
formatter = logging.Formatter('%(asctime)s,- %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger = logging.getLogger("access")
logger.setLevel(logging.ERROR)
logger.addHandler(fh)
logger.addHandler(ch)
logger.error("account [1234] too many login attempts")
- 3、json、pickle、shelve三个区别是什么?
# json跨语言,但适用范围小,仅限于简单的数据结构。
# pickle支持python,适用所有的python数据类型。
# shelve是可以多次dump、load
# answer
# 首先,这三个模块都是序列化工具。
# 1. json是所有语言的序列化工具,优点跨语言、体积小.只能序列化一些基本的数据类型。int\str\list\tuple\dict
# pickle是python语言特有序列化工具,所有数据都能序列化。只能在python中使用,存储数据占空间大.
# shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
# 2. 使用方式,json和pickle用法一样,shelve是f = shelve.open('shelve_test')
4、json的作用是什么?
# 将内容数据转成字符串
# answer
# 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes
5、subprocess执行命令方法有几种?
# 对系统命令或脚本的实现。run,call,popen
# answer:
# 有三种方法,分别是
# run()方法
# call()方法
# Popen()方法
6、为什么要设计好目录结构?
#可读性高,可维护性高
# answer
# 1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,
# 测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
# 2.可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。
# 这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
7、打印出命令行的第一个参数。例如:python argument.py luffy 打印出 luffy
import sys
print(sys.argv[1])
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)
打印的内容是什么?
# answer
# /usr/local/nginx
9、os.path.dirname和os.path.abspath含义是什么?
# answer
# os.path.dirname:指定文件的目录
# os.path.abspath:指定文件的绝对路径
10、通过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
# config = configparser.ConfigParser()
# config["DEFAULT"]={}
# config["client"]={}
# config["client"]["port"]="3306"
# config["client"]["soket"]="/data/mysql_3306/mysql.sock"
# config["mysqld"] = {}
# config["mysqld"]["explicit_defaults_for_timestamp"]="true"
# config["mysqld"]["port"]="3306"
# config["mysqld"]["socket"]="/data/mysql_3306/mysql.sock"
# config["mysqld"]["back_log"]="80"
# config["mysqld"]["basedir"]="/usr/local/mysql"
# config["mysqld"]["tmpdir"]="/tmp"
# config["mysqld"]["datadir"]="/data/mysql_3306"
# config["mysqld"]["default-time-zone"]="'+8:00'"
# with open("my.cnf","w")as configfile:
# config.write(configfile)
#
# con = configparser.ConfigParser()
# con.read("my.cnf")
# con.set("mysqld","default-time-zone","+00:00")
# con.remove_option("mysqld","explicit_defaults_for_timestamp")
# con["DEFAULT"]["character-set-server"]="utf8"
# con.write(open("my.cnf","w"))
# answer修改
# import configparser
# config = configparser.ConfigParser()
# config.read('my.cnf')
# config.set('mysqld','default-time-zone','+00:00')
# config.write(open('my.cnf', "w"))
# print(config['mysqld']['default-time-zone'] )
# answer 删除
# import configparser
# config = configparser.ConfigParser()
# config.read('my.cnf')
# config.remove_option('mysqld','explicit_defaults_for_timestamp')
# config.write(open('my.cnf', "w"))
# answer 添加
# import configparser
# config = configparser.ConfigParser()
# config.read('my.cnf')
# config.set('DEFAULT','character-set-server','utf8')
# config.write(open('my.cnf', "w"))
11、写一个6位随机验证码程序(使用random模块),要求验证码中至少包含一个数字、一个小写字母、一个大写字母.
# import random,string
# msg = random.sample(string.ascii_letters+string.digits,6)
# msg = ''.join(msg)
# print(msg)
# import random
# import string
# code_li = []
# code_li.append(random.choice(string.ascii_lowercase))
# code_li.append(random.choice(string.digits))
# code_li.append(random.choice(string.ascii_uppercase))
# while len(code_li) < 6:
# code_li.append(random.choice(string.digits+string.ascii_lowercase+string.ascii_uppercase))
# q_code=''.join(code_li)
# print(q_code)
12、利用正则表达式提取到 luffycity.com ,内容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>luffycity.com</title> </head> <body> </body> </html>
# name = ET.SubElement(new_xml,"html lang")
# name.text = '"en"'
# head = ET.SubElement(new_xml,"head")
# meta = ET.SubElement(head,"meta charset")
# meta.text = '"UTF-8"'
# title = ET.SubElement(head,"title")
# title.text = "luffycity.com"
# body = ET.SubElement(new_xml,"body")
# et = ET.ElementTree(new_xml)
# et.write("c",encoding="utf-8")
# ET.dump(new_xml)
# import re
# f = open('text.xml','r',encoding='utf-8')
# data = f.read()
# print(re.search('luffycity.com',data).group())
# answer
# import re
# f = open('index.html','r',encoding='utf-8')
# data = f.read()
# print(re.findall('luffycity.com',data))
13、写一个用户登录验证程序,文件如下
1234.json
{"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
用户名为json文件名,密码为 password。
判断是否过期,与expire_date进行对比。
登陆成功后,打印“登陆成功”,三次登陆失败,status值改为1,并且锁定账号。
# import json,time,os
# data = {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
# with open("1234.json","w")as fp:
# json.dump(data,fp)
# fp = open("1234.json","r")
# data = json.load(fp)
# count = 0
# while count < ATM与购物商城:
# name = input("username:")
# passwd = input("possword:")
# n = "1234.json".split(".")
# if name == n[0] and passwd == data["password"]:
# if data["status"] == 1:
# print("Locked!")
# exit()
# else:
# t= time.strftime('%Y-%m-%d',time.localtime())
# if t <= data["expire_date"]:
# print("Welcome...")
# exit()
# else:
# print("过期")
# exit()
# else:
# count += 1
# print("wrong")
#
# else:
# print("Fail")
# data["status"] = 1
# with open("1234.json", "w")as fp:
# json.dump(data,fp)
14、把第13题三次验证的密码进行hashlib加密处理。即:json文件保存为md5的值,然后用md5的值进行验证。
# import json,time,os,hashlib
# # data = {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
# # m = hashlib.md5()
# # m.update(data["password"].encode("utf-8"))
# # data["password"] = m.hexdigest()
# # with open("1234.json","w")as fp:
# # json.dump(data,fp)
#
# fp = open("1234.json","r")
# data = json.load(fp)
# count = 0
# while count < ATM与购物商城:
# name = input("username:")
# passwd = input("possword:")
# m = hashlib.md5()
# m.update(passwd.encode("utf-8"))
# passwd = m.hexdigest()
# n = "1234.json".split(".")
# if name == n[0] and passwd == data["password"]:
# if data["status"] == 1:
# print("Locked!")
# exit()
# else:
# t= time.strftime('%Y-%m-%d',time.localtime())
# if t <= data["expire_date"]:
# print("Welcome...")
# exit()
# else:
# print("过期")
# exit()
# else:
# count += 1
# print("wrong")
#
# else:
# print("Fail")
# data["status"] = 1
# with open("1234.json", "w")as fp:
# json.dump(data,fp)
15、最近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万
# import os,sys,json
# from bin.start import deal
# deal()
account ->_init__:
import json
data = {"账户余额":"800000","信用额度":"1000000"}
with open("luffy.json","w")as f:
json.dump(data,f)
with open("luffy.json","r")as f2:
d = json.load(f2)
print(d)
bin -> start.py
import os,json
from core.withdraw import withdraw1
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
base_dir = os.path.join(base_dir, "account")
luffy_path = os.path.join(base_dir, "luffy.json")
tsela_path = os.path.join(base_dir, "tsela.json")
flag = False
name, passwd = "alex", "123"
def confirm(func):
def conf(*args, **kwargs):
global flag
if not flag:
username = input("name:")
password = input("password:")
if name == username and passwd == password:
print("Welcome")
flag = True
else:
print("Fail")
else:
print("login in ")
if flag:
func()
return conf
@confirm
def trans():
price = 750000
other = 0.05 * price
price1 = price + other
tesla_data = json.load(open(tsela_path, "r", encoding="utf_8"))
num = int(tesla_data["账户余额"])
luffy_data = json.load(open(luffy_path, "r", encoding="utf_8"))
cost = int(luffy_data["账户余额"]) - price1
num = num + price
tesla_data["账户余额"] = num
luffy_data["账户余额"] = cost
json.dump(tesla_data, open(tsela_path, "w", encoding="utf_8"))
json.dump(luffy_data, open(luffy_path, "w", encoding="utf_8"))
print("done")
def deal():
info = """
------- Luffy Bank ---------
1. 账户信息
2. 转账
ATM与购物商城. 提现
"""
print(info)
choice = input("choice num:>")
if choice == "1":
f1 = open(luffy_path, "r", encoding="utf-8")
luffy_data = json.load(f1)
for i in luffy_data:
print(i, luffy_data[i])
elif choice == "2":
trans()
elif choice == "ATM与购物商城":
withdraw1()
16、对上题增加一个需求:提现。
目录结构如下
. ├── account │ └── luffy.json ├── bin │ └── start.py └── core └── withdraw.py
当执行start.py时,出现交互窗口
------- Luffy Bank --------- 1. 账户信息 2. 提现
选择1 账户信息 显示luffy的当前账户余额和信用额度。
选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。
尝试把上一章的验证用户登陆的装饰器添加到提现和转账的功能上。
17、对第15题的用户转账、登录、提现操作均通过logging模块记录日志,日志文件位置如下
. ├── account │ └── luffy.json ├── bin │ └── start.py └── core | └── withdraw.py └── logs └── bank.log