Python全棧專案(電子詞典、協程、pdb除錯)
什麼是專案?
軟體專案 : 實現一定完整性功能的程式碼
軟體專案的開發流程
需求分析
概要設計
專案規劃
詳細設計
編碼測試
專案測試
除錯修改
專案釋出
後期維護更新
需求分析 : 確定使用者的真實需求
1. 確定使用者的真實需求,即專案的基本功能
2. 對專案的難度和可行性進行分析
3. 完成需求分析文件,進行確認
概要設計 : 對專案進行整體分析,初步確定技術方向
1. 整體設計,確定專案架構
2. 確定專案功能模組劃分
3. 確定大的技術方向
4. 編寫專案概要設計文件,開發流程圖
專案規劃 : 確定專案分工,按照專案時限進行規劃
1. 確定開發順序
2. 確定開發的時間軸和里程碑
3. 人員的分配
4. 完成甘特圖和思維導圖指導開發
詳細設計 : 專案具體的開發設計,完成設計手冊
1.根據開發內容,形成詳細設計文件
思路, 邏輯流程 ,功能說明,技術點說明,資料結構,程式碼說明,注意事項,預期效果,環境約束
編碼測試 : 按照規劃完成編碼,做基本的測試工作
1.寫程式碼
2.程式碼基本測試
3.技術攻關
4.程式碼整合
專案測試 : 對專案整體功能進行測試
1. 跨平臺性,是否符合環境,功能bug,壓力測試
2. 完成測試報告
3. 根據測試結果修改bug
專案釋出
1.將專案提交給使用者,進行釋出使用
2.完成專案使用文件
後期維護
1.處理使用中出現的問題
2.專案的升級和功能的新增
專案注意事項
1.按時完成專案開發是首要工作
2.專案實施人員的衝突問題
3.無計劃的實施必要帶來後期更大的效率低下
專案開發工具
文件編寫 :
word ppt markdowm LaTex
專案流程圖 :
Mindmanager Xmind visio
專案管理:
project
程式碼管理工具:
git svn
編輯工具:
pycharm Webstream eclipse
sublime vim vscode atom
電子詞典專案文件
功能說明 :
1. 使用者可以登入註冊
登入憑藉使用者名稱密碼即可 如果輸入不正確可以重複輸入
註冊 要求使用者有填寫使用者名稱密碼,且使用者名稱不能重複。其他資訊隨意
2. 使用者資訊可以長期儲存在伺服器,保證下次登入可以使 用
3. 能夠滿足多個使用者端程式同時操作的情況
4. 功能分為客戶端和服務端,客戶端執行後即進入第一界 面
第一介面 : 登入 註冊 退出
5. 登入成功後進入第二介面
第二介面 : 查詞 檢視歷史記錄 退出
6. 功能說明
登入 :
選擇登入功能 輸入使用者名稱密碼,如果成功進入第二介面,不成功保持在第一介面,提示失敗原因
註冊 :
選擇註冊功能,填寫資訊,成功後可以保持第一介面或者使用新註冊使用者直接完成登入到第二介面,失敗提示失敗原因
第一介面退出 :
直接退出客戶端
第二介面退出 :
第二介面退出相當於登出,即退回到第一介面
查詞 :
可以迴圈輸入單詞,顯示出單詞詞義
輸入q表示查詞結束回到第二介面。如果查詢的詞不存在則有相應提示
*單詞本 : 每一行一個單詞
單詞和解釋之間一定有空格
單詞有序排列
1. 文字查詢 2.資料庫查詢
歷史記錄:
選擇檢視歷史記錄即列印出使用者的查詢記錄
可以列印所有記錄也可以列印最近10條。
name word time
專案分析
模組 : socket 套接字
pymysql/pymongo
os multiprocessing threading select
1.確定服務端和客戶端分為哪些功能,每個功能要做什麼工作
服務端 :
main() :
建立套接字,父子程式,子程式處理客戶端請求,父程式接受新的連線
login 接受客戶端資訊
資料庫匹配
返回結果
register 接受使用者資料
判斷是否重複
插入資料庫返回註冊成功
使用者存在返回註冊失敗
query 接受使用者單詞
通過資料庫或者檔案查詢單詞
將單詞結果返回給使用者
如果沒有查到返回相應資訊
如果查詞成功則插入歷史記錄
history 接受客戶請求
查詢資料庫返回歷史記錄
如果使用者沒有歷史記錄則返回資訊
客戶端 :
main: 建立套接字 —> 連線 —> 列印一級介面
login : 輸入使用者名稱密碼
傳送給服務端
接受返回結果,如果成功則跳轉到二級介面
失敗列印結果
register : 輸入使用者名稱密碼
傳送給服務端
接受返回結果
query : 迴圈輸入單詞
傳送單詞給服務端
接受結果並列印
history : 傳送請求 —> 接受結果列印
2.確定建立什麼樣的資料表,表的結構,將表建立起來
user : id name passwd
create table user (
id int auto_increment primary key,
name varchar(32) not null,
passwd varchar(16) default `000000`);
hist : id name word time
create table hist (
id int auto_increment primary key,
name varchar(32) not null,
word varchar(64) not null,
time varchar(64));
words : id word interpret
create table words (
id int auto_increment primary key,
word varchar(64),
interpret text);
3. 如果要使用資料庫查詞則程式設計將單詞本內容存入資料庫
import pymysql
import re
def main():
# 獲取詞典檔案流物件
f = open(`dict.txt`)
# 連結資料庫並建立遊標物件
db = pymysql.connect
(`localhost`,`root`,`123456`,`dict`)
cursor = db.cursor()
# 迴圈讀取每一行內容
for line in f:
try:
L = re.split("[ ]+",line)
except Exception:
pass
sql = "insert into words (word,interpret)
values (`%s`,`%s`)"%(L[0],` `.join(L[1:]))
# 處理破壞SQL的特殊字元
try:
cursor.execute(sql)
db.commit()
except Exception:
db.rollback()
f.close()
if __name__ == "__main__":
main()
4. 搭建框架,實現通訊 (建立套接字,設定結構,建立併發)
伺服器端:
#!/usr/bin/env python3
#coding=utf-8
```
name : Paris
date : 2018-8-27
email : 1546079656@qq.com
modules: python3.5 mysql pymysql
This is a dict project for AID
```
from socket import *
import os
import pymysql
import time
import sys
import signal
DICT_TEXT = "./dict.txt"
HOST = `0.0.0.0`
PORT = 8000
ADDR = (HOST,PORT)
#主控制流程
def main():
#連線資料庫
db = pymysql.connect
(`localhost`,`root`,`123456`,`dict`)
#建立流式套接字
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ADDR)
s.listen(5)
#或略子程式退出
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
while True:
try:
c,addr = s.accept()
print("Connect from",addr)
except KeyboardInterrupt:
s.close()
sys.exit("伺服器退出")
except Exception as e:
print(e)
continue
#建立子程式處理客戶端請求
pid = os.fork()
if pid == 0:
s.close()
do_child(c,db)
else:
c.close()
def do_child(c,db):
#迴圈接收請求
while True:
data = c.recv(128).decode()
print("Request:",data)
if (not data) or data[0] == `E`:
c.close()
sys.exit(0)
elif data[0] == `R`:
do_register(c,db,data)
elif data[0] == "L":
do_login(c,db,data)
elif data[0] == `Q`:
do_query(c,db,data)
elif data[0] == `H`:
do_history(c,db,data)
def do_register(c,db,data):
pass
def do_login(c,db,data):
pass
def do_query(c,db,data):
pass
def do_history(c,db,data):
pass
if __name__ == "__main__":
main()
客戶端:
#!/usr/bin/env python3
#coding=utf-8
from socket import *
import sys
import getpass
def main():
if len(sys.argv) < 3:
print("argv is error")
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
s = socket()
s.connect(ADDR)
while True:
print(```
===========Welcome=========
--1.註冊 2.登入 3.退出--
===========================
```)
try:
cmd = int(input("輸入選項>>"))
except Exception:
print("輸入命令錯誤")
continue
if cmd not in [1,2,3]:
print("對不起,沒有該命令")
sys.stdin.flush() #清除輸入
continue
elif cmd == 1:
name = do_register(s)
if name != 1:
print("註冊成功,直接登入!")
login(s,name)
else:
print("註冊失敗!")
elif cmd == 2:
name = do_login(s)
if name != 1:
print("登入成功!")
login(s,name)
else:
print("登入失敗!")
elif cmd == 3:
s.send(b"E")
sys.exit("謝謝使用")
def do_register(s):
pass
def do_login(s):
pass
def login(s,name):
pass
def do_query(s,name):
pass
def do_history(s,name):
pass
if __name__ == "__main__":
main()
5. 實現具體框架優化和具體功能
完整程式碼:
#!/usr/bin/env python3
#coding=utf-8
```
name : Paris
date : 2018-8-27
email : 1546079656@qq.com
modules: python3.5 mysql pymysql
This is a dict project for AID
```
from socket import *
import os
import pymysql
import time
import sys
import signal
DICT_TEXT = "./dict.txt"
HOST = `0.0.0.0`
PORT = 8000
ADDR = (HOST, PORT)
# 主控制流程
def main():
# 連線資料庫
db = pymysql.connect
(`localhost`, `root`, `123456`, `dict`)
# 建立流式套接字
s = socket()
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(ADDR)
s.listen(5)
# 或略子程式退出
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
while True:
try:
c,addr = s.accept()
print("Connect from", addr)
except KeyboardInterrupt:
s.close()
sys.exit("伺服器退出")
except Exception as e:
print(e)
continue
# 建立子程式處理客戶端請求
pid = os.fork()
if pid == 0:
s.close()
do_child(c,db)
else:
c.close()
def do_child(c,db):
# 迴圈接收請求
while True:
data = c.recv(128).decode()
print("Request:", data)
if (not data) or data[0] == `E`:
c.close()
sys.exit(0)
elif data[0] == `R`:
do_register(c, db, data)
elif data[0] == "L":
do_login(c, db, data)
elif data[0] == `Q`:
do_query(c, db, data)
elif data[0] == `H`:
do_history(c, db, data)
def do_register(c, db, data):
l = data.split(` `)
name = l[1]
passwd = l[2]
cursor = db.cursor()
sql =
"select * from user where name=`%s`" % name
cursor.execute(sql)
r = cursor.fetchone()
if r != None:
c.send(b`EXISTS`)
return
sql = "insert into user (name, passwd)
values (`%s`, `%s`)" % (name, passwd)
try:
cursor.execute(sql)
db.commit()
c.send(b`OK`)
except:
db.rollback()
c.send(b`FALL`)
return
else:
print("%s註冊成功" % name)
def do_login(c, db, data):
l = data.split(` `)
name = l[1]
passwd = l[2]
cursor = db.cursor()
sql = "select * from user where
name=`%s` and passwd=`%s`" % (name, passwd)
cursor.execute(sql)
r = cursor.fetchone()
if r == None:
c.send(`使用者名稱或密碼不正確`.encode())
else:
c.send(b`OK`)
def do_query(c, db, data):
l = data.split(` `)
name = l[1]
word = l[2]
cursor = db.cursor()
def insert_history():
tm = time.ctime()
sql = "insert into hist (name, word, time)
values (`%s`, `%s`, `%s`)" % (name, word, tm)
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
return
try:
f = open(DICT_TEXT, `rb`)
except:
c.send("500 服務端異常".encode())
return
while True:
line = f.readline().decode()
w = line.split(` `)[0]
if (not line) or w > word:
c.send("沒找到該單詞".encode())
break
elif w == word:
c.send(b`OK`)
time.sleep(0.1)
c.send(line.encode())
insert_history()
break
f.close()
def do_history(c, db, data):
name = data.split(` `)[1]
cursor = db.cursor()
try:
sql = "select * from hist
where name=`%s`" % name
cursor.execute(sql)
r = cursor.fetchall()
if not r:
c.send(`沒有歷史記錄`.encode())
return
else:
c.send(b`OK`)
except:
c.send("資料庫查詢錯誤".encode())
return
n = 0
for i in r:
n += 1
#最多顯示10條
if n > 10:
break
time.sleep(0.1)
msg = "%s %s %s" % (i[1], i[2], i[3])
c.send(msg.encode())
time.sleep(0.1)
c.send(b`##`)
if __name__ == "__main__":
main()
客戶端:
#!/usr/bin/env python3
#coding=utf-8
from socket import *
import sys
import getpass
def main():
if len(sys.argv) < 3:
print("argv is error")
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST, PORT)
s = socket()
s.connect(ADDR)
while True:
print(```
===========Welcome=========
--1.註冊 2.登入 3.退出--
===========================
```)
try:
cmd = int(input("輸入選項>>"))
except Exception:
print("輸入命令錯誤")
continue
if cmd not in [1, 2, 3]:
print("對不起,沒有該命令")
sys.stdin.flush() # 清除輸入
continue
elif cmd == 1:
name = do_register(s)
if name != 1:
print("註冊成功,直接登入!")
login(s, name)
else:
print("註冊失敗!")
elif cmd == 2:
name = do_login(s)
if name != 1:
print("登入成功!")
login(s, name)
else:
print("登入失敗!")
elif cmd == 3:
s.send(b"E")
sys.exit("謝謝使用")
def do_register(s):
while True:
name = input("使用者名稱:")
passwd = getpass.getpass("密 碼:")
passwd1 = getpass.getpass("確認密碼:")
if (` ` in name) or (` ` in passwd):
print("使用者名稱密碼不允許空格")
continue
if passwd != passwd1:
print("兩次密碼不一致")
continue
msg = "R {} {}".format(name, passwd)
# 傳送請求
s.send(msg.encode())
# 接收回復
data = s.recv(128).decode()
if data == "OK":
return name
elif data == `EXISTS`:
print("該使用者已存在")
return 1
else:
return 1
def do_login(s):
name = input("使用者名稱:")
passwd = getpass.getpass("密 碼:")
msg = "L {} {}".format(name, passwd)
s.send(msg.encode())
data = s.recv(128).decode()
if data == `OK`:
return name
else:
print(data)
return 1
def login(s, name):
while True:
print(```
===========查詢介面============
1.查詞 2.歷史記錄 3.登出
=============================
```)
try:
cmd = int(input("輸入選項>>"))
except Exception:
print("命令錯誤")
continue
if cmd not in [1,2,3]:
print("對不起,沒有該命令")
sys.stdin.flush() # 清除輸入
continue
elif cmd == 1:
do_query(s, name)
elif cmd == 2:
do_history(s, name)
elif cmd == 3:
return
def do_query(s, name):
while True:
word = input("單詞:")
if word == "q":
break
msg = "Q {} {}".format(name, word)
s.send(msg.encode())
data = s.recv(128).decode()
if data == `OK`:
data = s.recv(2048).decode()
print(data)
else:
print(data)
def do_history(s, name):
msg = "H {}".format(name)
s.send(msg.encode())
data = s.recv(128).decode()
if data == `OK`:
while True:
data = s.recv(1024).decode()
if data == "##":
break
print(data)
else:
print(data)
if __name__ == "__main__":
main()
import getpass
passwd = getpass.getpass()
功能 : 隱藏密碼輸入
pdb除錯:
通過pdb模組完成除錯功能
功能 : 斷點設定,單步執行,函式檢視,程式碼段檢視,變數值檢視等…
break , b 設定斷點
continue , c 繼續執行
list , l 檢視當前程式碼段
next, n 單步執行
step, s 進入函式單步執行
pp 列印變數值
help 幫助
pdb.set_trace()
功能 : 設定初始斷點,開始進入pdb除錯模式
以pdb除錯模式執行
python3 -m pdb dict_client.py
協程:
定義 : 纖程,微執行緒。協程本質只是一個單執行緒程式
工作原理 :
通過應用層層程式,記錄上下文的執行棧。實現程式在執行過程中的跳躍執行,
選擇可以不能阻塞的部分執行,這樣就可以大大提高IO執行的效率。
yield 是 python實現協程的基本關鍵字
安裝第三方模組:
sudo pip3 install greenlet
sudo pip3 install gevent
greenlet模組:
greenlet.greenlet() 生成協程物件
gr.switch() 選擇要執行的協程事件
gevent模組:
1. 將要執行的事件封裝為函式
2. 生成協程物件
gevent.spawn(func,argv)
功能 :
將事件變為協程
引數:
func 繫結的協程函式
argv 給函式傳遞引數
返回值 :
協程物件
3. 回收協程
gevent.joinall([obj1,obj2…..])(obj:協程物件)
4. 協程阻塞
gevent.sleep(n)
相關文章
- Python 程式碼除錯—使用 pdb 除錯Python除錯
- 除錯python專案除錯Python
- 使用pdb進行Python除錯Python除錯
- 使用pdb除錯python指令碼除錯Python指令碼
- Linux TCP/IP協議棧全過程LinuxTCP協議
- 使用Android簡單實現有道電子詞典Android
- Python全棧視訊教程-尹成-專題視訊課程Python全棧
- 四種免費英漢電子詞典軟體簡評
- Kotlin 1.4.0-RC協程除錯Kotlin除錯
- 【Python全棧】第五週 Python Web專案開發實現(上)-CSDN就業班-專題視訊課程Python全棧Web就業
- 一探全棧專案真面目全棧
- 列舉電子遊戲史上最經典的5句臺詞遊戲
- python全棧工程師-CSDN就業班-專題視訊課程Python全棧工程師就業
- 全棧低程式碼專案,你手寫一個企業級的低程式碼全棧專案全棧
- 貫通詞典破解過程
- Vue專案除錯技能Vue除錯
- Qt實用技巧:Qt+Sql server英漢漢英電子詞典QTSQLServer
- 詞典及容錯處理
- 2018 年不容錯過的 Django 全棧專案 YaDjangoBlogDjango全棧
- 零基礎學習PDB命令列除錯Python程式碼命令列除錯Python
- Python進階01 詞典Python
- 使用 vuetron 除錯 mpvue 專案Vue除錯
- cesium原始碼編譯除錯及呼叫全過程原始碼編譯除錯
- Python全棧工程師之從網頁搭建入門到Flask全棧專案實戰(7) - 線上問答系統Python全棧工程師網頁Flask
- Python全棧工程師之從網頁搭建入門到Flask全棧專案實戰(5) - Flask中的ORM使用Python全棧工程師網頁FlaskORM
- 電子專案1-安全燈
- Python進階教程01 詞典Python
- 全棧 - 17 NLP 使用jieba分詞處理文字全棧Jieba分詞
- 如何用 PyCharm 除錯 scrapy 專案PyCharm除錯
- nukkit maven 專案除錯外掛Maven除錯
- Python全棧工程師之從網頁搭建入門到Flask全棧專案實戰(6) - Flask表單的實現Python全棧工程師網頁Flask
- python 協程Python
- Python協程Python
- 一個nuxt(vue)+mongoose全棧專案聊聊我粗淺的專案架構UXVueGo全棧架構
- 推薦十大Python經典練手專案,讓你的Python技能點全亮Python
- 談電子政務專案管理(轉)專案管理
- 電子商務專案監理(轉)
- Vue、Node全棧專案~面向小白的部落格系統~Vue全棧