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