Python程式練習4--模擬員工信息資料庫操作

来源:http://www.cnblogs.com/byron-li/archive/2017/10/22/7711623.html
-Advertisement-
Play Games

1.功能簡介 此程式模擬員工信息資料庫操作,按照語法輸入指令即能實現員工信息的增、刪、改、查功能。 2.實現方法 架構: 本程式採用python語言編寫,關鍵在於指令的解析和執行:其中指令解析主要運用了正則表達式來高效匹配有效信息;指令執行通過一個commd_exe主執行函數和增、刪、改、查4個子執 ...


1.功能簡介

此程式模擬員工信息資料庫操作,按照語法輸入指令即能實現員工信息的增、刪、改、查功能。

 

2.實現方法

  • 架構:

本程式採用python語言編寫,關鍵在於指令的解析和執行:其中指令解析主要運用了正則表達式來高效匹配有效信息;指令執行通過一個commd_exe主執行函數和增、刪、改、查4個子執行函數來實現,操作方法主要是運用面向對象方法將員工信息對象化,從而使各項操作都能方便高效實現。程式主要函數如下: 
(1)command_exe(command) 
指令執行主函數,根據指令第一個欄位識別何種操作,並分發給相應的處理函數執行。
(2)add(command) 
增加員工記錄函數,指令中需包含新增員工除id號以外的其他所有信息,程式執行後信息寫入員工信息表最後一行,id號根據原最後一條記錄的id號自增1。 
(3)delete(command) 
刪除員工記錄函數,可根據where後的條件檢索需刪除的記錄,並從信息表中刪除。 
(4)update(command) 
修改和更新員工記錄函數,根據where後的條件檢索需更新的記錄,根據set後的等式修改和更新指定的信息。 
(5)search(command) 
查詢員工記錄函數,根據where後的條件查詢到相應的記錄,根據select後的關鍵字來顯示記錄的指定信息,如果為*顯示記錄的所有信息。 
(6)verify(staff_temp,condition) 
員工信息驗證函數,傳入一個對象化的員工記錄和指令中where後的條件字元串,判斷記錄是否符合條件,符合在返回True,否則返回False。指令包含where欄位的刪、改、查操作會調用此函數。 
(7)logic_cal(staff_temp,logic_exp) 
單個邏輯表達式的運算函數,傳入一個對象化的員工記錄和從where條件字元串中被and、or、not分割的單個表達式,實現=,>,<,>=,<=,like等確定的一個邏輯表達式的運算,返回結果為True或False。

  • 主要操作:

數據記錄包含6個關鍵字:id,name,age,phone,dept,enroll_date
指令可用的邏輯運算符:<,>,=,<=,>=,like,and,or,not
資料庫操作: 
1.增(add to xxxx values xxxx) 
示例:add to staff_table values Alex Li,22,13651054608,IT,2013-04-01
2.刪(delete from xxxx where xxxx) 
示例:delete from staff_table where age<=18 and enroll_date like "2017"
3.改(update xxxx set xxxx where xxxx
示例: 
update staff_table set dept="Market",age=30 where dept="IT" and phone like "189"
4.查(select xxxx from xxxx where xxxx
示例1: 
select * from staff_table where age>=25 and not phone like "136" or name like "李"
示例2: 
select name,age,dept from db.txt where id<9 and enroll_date like "-05-"
示例3:select * from staff_table where * #顯示所有記錄 

  • 使用文件:

staff_table 
存放員工信息表,作為模擬的資料庫文件,每條記錄包含id,name,age,phone,dept,enroll_date六項信息,如"1,Alex Li,22,13651054608,IT,2013-04-0"

 

3.流程圖

4.代碼

  1 #!usr/bin/env python3
  2 #_*_coding:utf-8_*_
  3 
  4 'staff infomation management module'
  5 __author__='Byron Li'
  6 
  7 '''----------------------------------------------員工信息資料庫操作指令語法---------------------------------------------
  8 數據記錄包含6個關鍵字:id,name,age,phone,dept,enroll_date
  9 指令可用的邏輯運算符:<,>,=,<=,>=,like,and,or,not
 10 1.增(add to xxxx values xxxx)
 11   示例:add to staff_table values Alex Li,22,13651054608,IT,2013-04-01  
 12 2.刪(delete from xxxx where xxxx)
 13   示例:delete from staff_table where age<=18 and enroll_date like "2017"
 14 3.改(update xxxx set xxxx where xxxx)
 15   示例:update staff_table set dept="Market",age=30 where dept="IT" and phone like "189"
 16 4.查(select xxxx from xxxx where xxxx)
 17   示例1:select * from staff_table where age>=25 and not phone like "136" or name like "李"
 18   示例2:select name,age,dept from  db.txt  where id<9  and  enroll_date like "-05-"
 19   示例3:select * from staff_table where *           #顯示所有記錄
 20 ---------------------------------------------------------------------------------------------------------------------'''
 21 import re
 22 import os
 23 class staff(object):               #員工類
 24     def __init__(self,*args):      #員工信息初始化:從字元串列表傳參賦值
 25         self.id=args[0]
 26         self.name=args[1]
 27         self.age=args[2]
 28         self.phone=args[3]
 29         self.dept=args[4]
 30         self.enroll_date=args[5]
 31         self.allinfo=','.join(args)
 32     def update(self,**kwargs):       #員工信息更新:從字典傳參賦值
 33         if 'id' in kwargs:
 34             self.id=kwargs['id']
 35         if 'name' in kwargs:
 36             self.name=kwargs['name']
 37         if 'age' in kwargs:
 38             self.age = kwargs['age']
 39         if 'phone' in kwargs:
 40             self.phone=kwargs['phone']
 41         if 'dept' in kwargs:
 42             self.dept=kwargs['dept']
 43         if 'enroll_date' in kwargs:
 44             self.enroll_date = kwargs['enroll_date']
 45         self.allinfo = ','.join(map(str,[self.id, self.name, self.age, self.phone, self.dept, self.enroll_date]))
 46     def print_info(self,info):     #員工信息列印顯示:傳入的參數為"*"或數據記錄的若幹個關鍵字
 47         if info=='*':
 48             print(self.allinfo)
 49         else:
 50             info=info.split(',')
 51             res=[]
 52             for i in info:
 53                 if hasattr(self,i.strip()):
 54                     res.append(str(getattr(self,i.strip())))
 55             print(','.join(res))
 56 
 57 def command_exe(command):   #指令執行主函數,根據指令第一個欄位識別何種操作,並分發給相應的處理函數執行
 58     command=command.strip()
 59     return {
 60         'add':add,
 61         'delete':delete,
 62         'update':update,
 63         'select':search,
 64     }.get(command.split()[0],error)(command)
 65 
 66 def error(command):        #錯誤提示函數,指令不合語法調用該函數報錯
 67     print('\033[31;1m語法錯誤,請重新輸入!\033[0m\n')
 68 
 69 def add(command):        #增加員工記錄函數
 70     command_parse=re.search(r'add\s*?to\s(.*?)values\s(.*)',command)    #正則表達式指令解析
 71     if(command_parse):
 72         data_file=command_parse.group(1).strip()   #資料庫文件
 73         info=command_parse.group(2).strip()        #需新增的員工信息,不含id
 74         id=1                                       #新增員工id,預設為1以防資料庫為空表時新增記錄id取1
 75         with open(data_file, 'r+', encoding='utf-8') as fr:
 76             line=fr.readline()
 77             while(line):
 78                 if line.strip()=='':
 79                     fr.seek(fr.tell()-len(line)-2)  #定位文件最後一行(只有空字元)的開頭
 80                     break
 81                 staff_temp = staff(*line.strip().split(','))     #讀取的信息轉換為staff對象
 82                 id = int(staff_temp.id) + 1         #末行員工id加1為新員工id
 83                 line = fr.readline()
 84             info_new=''.join([str(id),',',info])  #id與其他信息合併成完整記錄
 85             fr.write(info_new)
 86             fr.write('\n')
 87             fr.flush()
 88             print("資料庫本次\033[31;1m新增1條\033[0m員工信息:", info_new)  #新增記錄列印
 89     else:
 90         error(command)
 91 
 92 def delete(command):    #刪除員工記錄函數
 93     command_parse=re.search(r'delete\s*?from\s(.*?)where\s(.*)',command)   #指令解析
 94     if(command_parse):
 95         data_file=command_parse.group(1).strip()  #資料庫文件
 96         condition=command_parse.group(2).strip()  #檢索條件
 97         data_file_bak = ''.join([data_file, '.bak'])
 98         count = 0           #刪除記錄計數
 99         staff_list = []     #刪除記錄的員工對象列表
100         with open(data_file, 'r', encoding='utf-8') as fr, \
101                 open(data_file_bak, 'w', encoding='utf-8') as fw:
102             for line in fr:
103                 staff_temp = staff(*line.strip().split(','))
104                 if (verify(staff_temp, condition)):  #驗證員工信息是否符合條件
105                     count+=1
106                     staff_list.append(staff_temp)
107                     continue
108                 fw.write(staff_temp.allinfo)
109                 fw.write('\n')
110             fw.flush()
111         os.remove(data_file)
112         os.rename(data_file_bak, data_file)
113         print("資料庫本次共\033[31;1m刪除%d條\033[0m員工信息,如下:"%count)
114         for staff_temp in staff_list:
115             staff_temp.print_info('*')   #刪除記錄列印
116     else:
117         error(command)
118 
119 def update(command):     #修改和更新員工記錄函數
120     command_parse=re.search(r'update\s(.*?)set\s(.*?)where\s(.*)',command)   #指令解析
121     if(command_parse):
122         data_file=command_parse.group(1).strip()     #資料庫文件
123         info=command_parse.group(2).strip()          #需更新的信息
124         condition=command_parse.group(3).strip()     #檢索條件
125         data_file_bak=''.join([data_file,'.bak'])
126 
127         info = ''.join(['{', info.replace('=', ':'), '}'])   #將需更新的信息按字典格式修飾字元串
128         info = eval(re.sub(r'(\w+)\s*:', r'"\1":', info))    #將字元串進一步修飾最終轉化成字典
129         count = 0
130         staff_list = []
131         with open(data_file,'r',encoding='utf-8') as fr,\
132                 open(data_file_bak,'w',encoding='utf-8') as fw:
133             for line in fr:
134                 staff_temp=staff(*line.strip().split(','))
135                 if(verify(staff_temp,condition)):    #驗證員工信息是否符合條件
136                     staff_temp.update(**info)        #調用員工對象成員函數更新信息
137                     count += 1
138                     staff_list.append(staff_temp)
139                 fw.write(staff_temp.allinfo)
140                 fw.write('\n')
141             fw.flush()
142         os.remove(data_file)
143         os.rename(data_file_bak,data_file)
144         print("資料庫本次共\033[31;1m更新%d條\033[0m員工信息,如下:"%count)
145         for staff_temp in staff_list:
146             staff_temp.print_info('*')  #更新記錄列印
147     else:
148         error(command)
149 
150 def search(command):        #查詢員工記錄函數
151     command_parse=re.search(r'select\s(.*?)from\s(.*?)where\s(.*)',command)   #指令解析
152     if(command_parse):
153         info=command_parse.group(1).strip()         #檢索結束後需顯示的信息,"*"為顯示整體記錄
154         data_file=command_parse.group(2).strip()    #資料庫文件
155         condition=command_parse.group(3).strip()    #檢索條件
156         count = 0
157         staff_list = []
158         with open(data_file,'r',encoding='utf-8') as fr:
159             for line in fr:
160                 staff_temp=staff(*line.strip().split(','))
161                 if(verify(staff_temp,condition)):   #驗證員工信息是否符合條件
162                     count += 1
163                     staff_list.append(staff_temp)
164         print("資料庫本次共\033[31;1m查詢到%d條\033[0m員工信息,如下:" % count)
165         for staff_temp in staff_list:
166             staff_temp.print_info(info)     #查詢記錄列印
167     else:
168         error(command)
169 
170 def verify(staff_temp,condition):             #員工信息驗證函數,傳入一個員工對象和條件字元串
171     if condition.strip()=='*':return True   #如果條件為'*',即所有記錄都滿足條件
172     condition_list=condition.split()           #檢索條件字元串轉列表
173     if len(condition_list)==0:return False
174     logic_str=['and','or','not']    #邏輯運算字元串 且、或、非
175     logic_exp=[]                  #單個條件的邏輯表達式組成的列表,形如[‘age',' ','>','=',20] 或 [‘dept',' ','like',' ','HR']
176     logic_list=[]                 #每個條件的表達式的計算結果再重組後的列表,形如 [‘True','and','False','or','not','False']
177     for i in condition_list:
178         if i in logic_str:
179             if(len(logic_exp)!=0):
180                 logic_list.append(str(logic_cal(staff_temp,logic_exp)))  #邏輯表達式計算並將返回的True或False轉化成字元串添加到列表
181             logic_list.append(i)
182             logic_exp=[]
183         else:
184             logic_exp.append(i)
185     logic_list.append(str(logic_cal(staff_temp, logic_exp)))
186     return eval(' '.join(logic_list))    #列表轉化成數學表達式完成所有條件的綜合邏輯運算,結果為True或False
187 
188 def logic_cal(staff_temp,logic_exp):   #單個邏輯表達式的運算函數
189     logic_exp = re.search('(.+?)([=<>]{1,2}|like)(.+)',''.join(logic_exp))  #表達式列表優化成三個元素,形如[‘age','>=',20] 或 [‘dept','like','HR']
190     if(logic_exp):
191         logic_exp=list(logic_exp.group(1,2,3))
192         if(hasattr(staff_temp,logic_exp[0])):
193             logic_exp[0] = getattr(staff_temp,logic_exp[0])
194         else:
195             return False
196         if logic_exp[1]=='=':        #指令中的'='轉化成程式中相等判別的"=="
197             logic_exp[1]='=='
198         if logic_exp[1]=='like':     #運算符為like的表達式運算
199             return re.search(logic_exp[2].strip("'").strip('"'),logic_exp[0]) and True
200         elif(logic_exp[0].isdigit() and logic_exp[2].isdigit()):   #兩頭為數字的運算,直接eval函數轉數學表達式
201             return eval(''.join(logic_exp))
202         elif(logic_exp[1]=='=='):    #非數字的運算,即字元串運算,此時邏輯符只可能是‘=’,若用eval函數則字元串會轉成無定義變數而無法計算,所以拿出來單獨用"=="直接計算
203             return logic_exp[0]==logic_exp[2].strip("'").strip('"')   #字元串相等判別,同時消除指令中字元串引號的影響,即輸引號會比記錄中的字元串多一層引號
204         else:          #其他不合語法的條件格式輸出直接返回False
205             return False
206     else:
207         return False
208 
209 if __name__=='__main__':     #主函數,資料庫指令輸入和執行
210     while(True):
211         command=input("請按語法輸入資料庫操作指令:")    #指令輸入
212         if command=='exit':
213             print("資料庫操作結束,成功退出!".center(50, '*'))
214             break
215         command_exe(command)        #指令執行
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於目後佐道IT教育 http://www.cnblogs.com/itpua/p/7710917.html 目後佐道IT教育的師資團隊 http://www.cnblogs.com/itpua/p/7712077.html 目後佐道IT教育正在打架報名中,歡迎高中生、大學生前來學習編程技術,招生面 ...
  • Twisted是用Python實現的基於事件驅動的網路引擎框架,Twisted支持許多常見的傳輸及應用層協議,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。就像Python一樣,Twisted也具有“內置電池”(batteries-included)的特點。Twi ...
  • 關於目後佐道IT教育 http://www.cnblogs.com/itpua/p/7710917.html 目後佐道IT教育的師資團隊 http://www.cnblogs.com/itpua/p/7712077.html 目後佐道IT教育正在打架報名中,歡迎高中生、大學生前來學習編程技術,招生面 ...
  • 關於目後佐道IT教育 http://www.cnblogs.com/itpua/p/7710917.html 高端技術顧問 1. leepoor 擁有12年的Web開發和架構經驗,在阿裡巴巴擔任高級架構師,參與阿裡巴巴基礎技術平臺開發和www.alibaba.com架構設計。擅長大型網站技術架構,工 ...
  • 題目描述 現有n個正整數,n≤10000,要求出這n個正整數中的第k個最小整數(相同大小的整數只計算一次),k≤1000,正整數均小於30000。 輸入輸出格式 輸入格式: 第一行為n和k; 第二行開始為n個正整數的值,整數間用空格隔開。 輸出格式: 第k個最小整數的值;若無解,則輸出“NO RES ...
  • 1、簡介 從接觸yii框架到現在已經快有兩個月了,但是自己對yii框架的瞭解程度並不是很深,並沒有系統地去學習,僅僅只是在做項目的時候遇到不懂得知識才去翻手冊。 在上一個項目中因為需要將關聯的表的欄位顯示出來並且帶搜索排序功能,這個在之前並沒有接觸過,因此在手冊中查找了相關的資料把這個需求寫出來了, ...
  • 題目描述 一組數,分別表示地平線的高度變化。高度值為整數,相鄰高度用直線連接。找出並統計有多少個可能積水的低窪地? 如圖:地高變化為 0 1 0 2 1 2 0 0 2 0 輸入輸出格式 輸入格式: 兩行,第一行n,表示有n個數。第2行連續n個數表示地平線高度變化的數據,保證首尾為0。(3<=n<= ...
  • InputStream is = null;try { is = new FileInputStream(textPath); BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 512); / ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...