練習題|python常用模塊
re模塊練習
1.驗證手機號是否合法
import re phone_pat = re.compile(‘^(13\d|14[5|7]\d|15\d|166|17[3|6|7]|18\d)\d{8}$‘) while True: phone = input(‘請輸入您的手機號:‘) res = re.search(phone_pat, phone) if res: print(‘正常手機號‘) else: print(‘這不是一個手機號‘)
‘‘‘ * 手機號碼 * 移動:134,135,136,137,138,139,150,151,157,158,159,182,187,188 * 聯通:130,131,132,152,155,156,185,186 * 電信:133,134,153,180,189 147... 176...‘‘‘ import re # phone_num = ‘13789481229‘ phone_num = input(‘phone>>>:‘) # pattern = re.compile(‘^0\d{2,3}\d{7,8}$|^1[358]\d{9}$|^147\d{8}‘) pattern = re.compile(‘^1[34578]\d{9}‘) phone_match = pattern.fullmatch(phone_num) if phone_match: print(phone_match.group()) else: print(‘\033[1;31mphone is error\033[0m‘)
2.驗證郵箱是否合法
import re # email = ‘[email protected]‘ email = input(‘email>>>:‘) # pattern = re.compile(‘\w+@\w+\.(com|cn)‘) pattern = re.compile(‘[-_\w]+@[-_\w]+\.(com|cn|edu)‘) email_match = pattern.fullmatch(email) if email_match: print(email_match.group())else: print(‘\033[1;31memail is error\033[0m‘) #re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email)
3.開發一個簡單的python計算器,實現加減乘除及拓號優先級解析
用戶輸入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等類似公式後,必須自己解析裏面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現),運算後得出結果,結果必須與真實的計算器所得出的結果一致
hint: re.search(r‘\([^()]+\)‘,s).group()#可拿到最裏層的括號中的值 ‘(-40/5)‘
參考 http://www.bubuko.com/infodetail-1729967.html
本章總結練習
1、logging模塊有幾個日誌級別?
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 #1.生成logger對象 logger =logging.getLogger("access") logger.setLevel(logging.DEBUG) #2.生成handler對象 ch = logging.StreamHandler() ch.setLevel(logging.ERROR) ##設置輸出屏幕級別 fh = logging.FileHandler("access.log") #生成文件 fh.setLevel(logging.ERROR) ##設置輸出文件級別 #2.1把handler對象綁定到logger logger.addHandler(ch) logger.addHandler(fh) #3.生成formatter對象 #3.1把formatter對象綁定handler對象 file_formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) console_formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s- %(lineno)d- %(message)s‘) ch.setFormatter(console_formatter) fh.setFormatter(file_formatter) logger.error("account [1234] too many login attempts")
3、json、pickle、shelve三個區別是什麽
首先,這三個模塊都是序列化工具。 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的作用是什麽?
序列化是指把內存裏的數據類型轉變成字符串,以使其能存儲到硬盤或通過網絡傳輸到遠程,因為硬盤或網絡傳輸時只能接受bytes
5、subprocess執行命令方法有幾種?
有三種方法,他們分別是
run()方法
call()方法
Popen()方法
6、為什麽要設計好目錄結構?
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)
- 打印的內容是什麽? 打印的內容是:
/usr/local/nginx
- os.path.dirname和os.path.abspath含義是什麽? os.path.dirname是指定文件的目錄;os.path.abspath指的是文件的絕對路徑。
9、通過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
import configparser config = configparser.ConfigParser() config.read(‘my.cnf‘) print(config[‘mysqld‘][‘default-time-zone‘] ) #08:00 config.set(‘mysqld‘,‘default-time-zone‘,‘+00:00‘) config.write(open(‘my.cnf‘, "w")) print(config[‘mysqld‘][‘default-time-zone‘] ) #+00:00
- 刪除 explicit_defaults_for_timestamp
import configparser config = configparser.ConfigParser() config.read(‘my.cnf‘) config.remove_option(‘mysqld‘,‘explicit_defaults_for_timestamp‘) config.write(open(‘my.cnf‘, "w"))
- 為DEFAULT增加一條 character-set-server = utf8
import configparser config = configparser.ConfigParser() config.read(‘my.cnf‘) config.set(‘DEFAULT‘,‘character-set-server‘,‘utf8‘) config.write(open(‘my.cnf‘, "w"))
10、寫一個6位隨機驗證碼程序(使用random模塊),要求驗證碼中至少包含一個數字、一個小寫字母、一個大寫字母.
import random import string a = ‘‘.join(random.sample(string.ascii_lowercase + string.ascii_uppercase + string.digits,6)) print(a)
11、利用正則表達式提取到 luffycity.com ,內容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>luffycity.com</title> </head> <body> </body> </html>
import re f = open(‘index.html‘,‘r‘,encoding=‘utf-8‘) data = f.read() #print(data) print(re.findall(‘luffycity.com‘, data)) #[‘luffycity.com‘]
12、寫一個用戶登錄驗證程序,文件如下
1234.json
{"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
- 用戶名為json文件名,密碼為 password。
- 判斷是否過期,與expire_date進行對比。
- 登陸成功後,打印“登陸成功”,三次登陸失敗,status值改為1,並且鎖定賬號。
import json import time username = input(‘請輸入用戶名(文件名):‘) f = open(‘1234.json‘,‘r‘,encoding=‘utf-8‘) data = f.read() data1 = json.loads(data) #print(data1[‘password‘]) count = 0 while count < 3: if (int(time.strftime(‘%Y‘)))-(int(data1["expire_date"][0:4])) > 0: print(‘您的賬戶已過期‘) exit() if data1[‘status‘] == 1: print(‘您的賬戶已被鎖定,無法登錄‘) exit() password = input(‘請輸入密碼:‘) if password == data1[‘password‘]: print(‘登錄成功‘) elif count == 2: data1[‘status‘] = 1 f1 = open(‘1234.json‘,‘w‘,encoding=‘utf-8‘) json.dump(data1,f1) #修改json數據 print(‘您的賬戶已被鎖定‘) exit() else: print(‘您的密碼有誤,請重新輸入‘) count += 1
13、把第12題三次驗證的密碼進行hashlib加密處理。即:json文件保存為md5的值,然後用md5的值進行驗證。
"password": "900150983cd24fb0d6963f7d28e17f72"
#加入下面這個就可以 password = input(‘請輸入密碼:‘) m = hashlib.md5() m.update(password.encode()) if m.hexdigest() == data1[‘password‘]: print(‘登錄成功‘)
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
14--17:
bin start.py
#Author:Kris # -*- coding:utf-8 -*- import os,sys import json import logging from logging import handlers core_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(core_path) from core import withdraw _username = ‘alice‘ _password = ‘123‘ msg = ‘‘‘ 1. 賬戶信息 2. 轉賬 3. 提現 ‘‘‘ json_path = os.path.join(core_path, ‘account‘) flag_login = False logger = logging.getLogger(‘record‘) def log_record(): global logger logger.setLevel(logging.DEBUG) # fh = logging.FileHandler(os.path.join(core_path, ‘logs/bank.log‘),encoding=‘utf-8‘) fh = logging.handlers.TimedRotatingFileHandler(filename=os.path.join(core_path, ‘logs/bank.log‘),when=‘S‘,interval=3,backupCount=3,encoding=‘utf-8‘) logger.addHandler(fh) f_formatter = logging.Formatter(fmt=‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘,datefmt=‘%m/%d/%Y %I:%M:%S %p‘) fh.setFormatter(f_formatter) def login(func): def inner(): global flag_login if not flag_login: username = input(‘username:‘).strip() password = input(‘password:‘).strip() if username == _username and password == _password: print(‘登錄成功!‘) flag_login = True logger.info(‘登錄成功‘) else: print(‘用戶名或密碼有誤!‘) else: print(‘用戶已登錄,通過認證‘) if flag_login is True: func() return inner def print_info(): # 賬戶信息 luffy_data = json.load(open(os.path.join(json_path, ‘luffy.json‘), ‘r‘, encoding=‘utf-8‘)) print(‘account_balance:‘, luffy_data[‘account_balance‘]) print(‘credit_account:‘, luffy_data[‘credit_account‘]) @login def transfer_account(): # 轉賬 luffy_data = json.load(open(os.path.join(json_path, ‘luffy.json‘), ‘r‘, encoding=‘utf-8‘)) tesla_data = {‘account_balance‘: 750000} luffy_data[‘account_balance‘] = luffy_data[‘account_balance‘] - tesla_data[‘account_balance‘] * (1 + 0.05) json.dump(luffy_data, open(os.path.join(json_path, ‘luffy.json‘), ‘w‘, encoding=‘utf-8‘)) json.dump(tesla_data, open(os.path.join(json_path, ‘tesla.json‘), ‘w‘, encoding=‘utf-8‘)) print(‘轉賬成功!‘) logger.debug(‘轉賬成功‘) @login def withdraws_func(): # 提現 moneys = input(‘moneys>>>:‘).strip() if moneys.isdigit(): moneys = int(moneys) withdraw.withdraws(moneys, json_path, logger) def main(): while True: print("Luffy Bank".center(30, ‘-‘)) print(msg) num = input(‘num(q表示退出)>>>:‘).strip() if not num: continue if num.isdigit(): num = int(num) if num == 1: # 賬號信息 print_info() elif num == 2: # 轉賬 transfer_account() elif num == 3: # 提現 withdraws_func() elif num == ‘q‘: exit() if __name__ == ‘__main__‘: log_record() main()
core withdraw.py
#Author:Kris # -*- coding:utf-8 -*- import os, json def withdraws(moneys, json_path, logger): luffy_data = json.load(open(os.path.join(json_path, ‘luffy.json‘), ‘r‘, encoding=‘utf-8‘)) if moneys <= luffy_data[‘credit_account‘]: luffy_data[‘credit_account‘] = luffy_data[‘credit_account‘] - moneys*(1+0.05) json.dump(luffy_data, open(os.path.join(json_path, ‘luffy.json‘), ‘w‘, encoding=‘utf-8‘)) print(‘提現成功!‘) logger.warning(‘提現成功‘) else: print(‘\033[0;31m提現金額大於信用額度了!\033[0m‘) logger.error(‘提現金額大於信用額度‘)
練習題|python常用模塊