Python 小應用2 ======================== ###### 相較於另一份筆記 "Python 小應用" 雖有重複主題或內容,但另外成立主要是可有個舊版的寫法供參考,需要的人可以直接做比對看看即可。留言我會再注意,以更新內容,謝謝你 ###### ## user檔案比較與更新 ```python= import os, time, sys ##批量檔案內容更新 ##記得更新版本號 def fileExists(file1, file2):#確認兩檔案是否皆存在 ### FileExistsError: [Errno 17] File exists: ### 確認版本號或路徑是否更新 print(str(os.path.exists(file1))) print(str(os.path.exists(file2))) if os.path.exists(file1) and os.path.exists(file2): return True else: return False def compare(file1, file2, lineSave, strS, strS2, look = True):#比較兩檔案內容差異並列出 lineNum = 1 #確認檔案存在 print ('兩檔案皆存在...' + str(fileExists(file1, file2)) +'\n') if not fileExists(file1, file2): print ('不存在該檔案,將自動新增...\n') f2 = open(file2, 'x', encoding = 'utf-8') f2.close() f1 = open(file1, encoding = 'utf-8') f2 = open(file2, encoding = 'utf-8') #讀入各自變數 flist1 = [x for x in f1] flist2 = [y for y in f2] #得出資料長度 flines1 = len(flist1) flines2 = len(flist2) #對兩串列作等長處理以比較 if flines1 < flines2: flist1[flines1:flines2+1] = ' ' * (flines2 - flines1) elif flines1 > flines2: flist2[flines2:flines1+1] = ' ' * (flines1 - flines2) #輸出比較結果 if look: print ('%s和%s比較結果:\n' % (file1, file2)) for y in zip(flist1, flist2):#字典化合併處理 if y[0] == y[1]: lineNum +=1 continue if y[0] != y[1] :#發現相異內容就呈現 if look: print('第%s行: %s <--> %s\n' % (lineNum, y[0].strip(), y[1].strip())) lineNum +=1 lineSave.append(lineNum-1)#保留相異資訊的行號 strS.append(y[0]) strS2.append(y[1]) #未有內容呈現,回報兩檔案相同 if len(lineSave) == 0: print ('%s 和 %s \n內容和排版完全相同!' % (file1, file2)) def contentModify(fileO, fileM, lineSave, strS, strS2):#進行內容修改(以fileO為準修正fileM) #確認有內容要更新 if len(lineSave) == 0: print ('沒有要更新的內容!') return #開啟兩檔案,一個讀取,一個寫入 file = open(fileO, 'r', encoding = 'utf-8') file2 = open(fileM, 'w', encoding = 'utf-8') lineN = 0 for line in file:#修改內容回報 if(lineN < len(lineSave)) and strS2[lineN] in line: print ('修正第%s行內容...' % lineSave[lineN]) lineN += 1 #print(line) file2.write(line) #隨手關檔 file2.close() file.close() #回收空間 lineSave.clear() strS.clear() strS2.clear() def addNote(file, note, jum = True):#追加註記 if not jum: return #開啟檔案 f = open(file, 'a', encoding = 'utf-8') #寫入註記 note = '\n##' + note + '\n##' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '秒 註\n' f.write(note) print ('完成註記\n') #隨手關檔 f.close() def keyHandle(file, n): key = ['test','吳俊廷-195','李重瑩-196','鄭宇軒-197','連士謙-198'] file = open(file, 'r+', encoding = 'utf-8') fileCon = file.read() fileCon = fileCon.replace('keyname = \'test\'', 'keyname = \'%s\'' % key[n]) file.seek(0,0) file.write(fileCon) file.close() if n > 0: print('\n' + str(194 + n) + '=======成功修正關鍵字!=======') else: print('\n' + 'test' + '=======成功修正關鍵字!=======') def update(new, files, li, note, strS, strS2, p, ju, look): compare(new, files, li, strS, strS2, look) print ('=====================開始更新======================') contentModify(new, files, li, strS, strS2) ##print ('==============更新結束,比對更新結果===============') ##compare(new, files, li, strS, strS2, look) keyHandle(files, p) addNote(files, note, ju) print ('\n完成%s更新!\n' % files) ### li = []#行號 strS = []#對照檔 strS2 = []#待修正檔 ju = True #跳過註解 ''' stdFile = 'K:/tuser/user.py' files = ['C:/Users/Public/Downloads/user/user-t/user-3.py'] ''' stdFile = 'K:/tuser/user.py' files = ['C:/Users/Public/Downloads/user/user-t/user-5.py','C:/Users/Public/Downloads/user/user-195/user-195.py', 'C:/Users/Public/Downloads/user/user-196/user-196.py', 'C:/Users/Public/Downloads/user/user-197/user-197.py', 'C:/Users/Public/Downloads/user/user-198/user-198.py'] ans = input('\n先進行校對檢視?') if ans == 'y' or ans == '1': for j in range(len(files)): print('===================================================') print ('===================核對第%s個檔案===================' % str(j+1)) print('===================================================') compare(stdFile, files[j], li, strS, strS2) elif ans == 'n' or ans == '0': print ('取消校對') pass ans = input('\n進行批量更新?(y/n)') if ans == 'y' or ans == '1': note = input('\n更新內容註記:') if note == '': ju = False #計時開始 start_t = time.time() for i in range(len(files)): print ('===================更新第%s個檔案===================' % str(i+1)) update(stdFile , files[i], li, note, strS, strS2, i, ju, False) print ('完成批次更新!') #計時結束 end_t = time.time() #v顯示計時結果 print ('\n花費時間為 %s 秒' % str(end_t - start_t)) elif ans == 'n' or ans == '0': print ('取消更新') pass print('按任一鍵結束...') os.system('pause') ``` ## 多行內容翻譯處理 ```python= from googletrans import Translator import os, sys #2020/10/12 修 ##多行內容翻譯處理 ''' py3 中,input()只能输入一行 但 sys.stdin.readlines() 僅需 按下换行键後輸入 ctrl + z 才能 按 enter 鍵结束輸入 pip install googletrans ''' def tranStr(tString, cut):#去掉換行與銜接 ###'':'%', afterStr = '' for p in range(len(tString)): afterStr += tString[p][0:len(tString[p])-1] + ' ' ##print(afterStr) if cut == 'c' or cut == '1': aStrlist = [None] aStrlist = recutStr(afterStr) return aStrlist else : return afterStr def recutStr(cString):#逐一分句 aStr = [] starStr = 0 endStr = 0 for p in range(len(cString)): if cString[p] == '.' or cString[p] == ':': endStr = p + 1 aStr.append(cString[starStr:endStr]) starStr = endStr + 1 ##print(aStr) return aStr def gTranStr(tContext, cut):#接收輸入並翻譯 ''' 別妄想要寫爬蟲來爬結果,因為每筆資料都有個tk 值尾隨,那個計算和取得的工程浩大 放棄吧! ''' translator = Translator() googleAns = tranStr(tContext, cut) if cut == 'c' or cut == '1': for i in range(len(googleAns)): response = translator.translate(googleAns[i], dest='zh-TW').text print('\n' + '-' * 30 + ' 第 ' + str(i+1) + ' 句 ' + '-' * 30 + '>>') print(' ' + googleAns[i] + '\n') print(response) else : response = translator.translate(googleAns, dest='zh-TW').text print('\n ' + googleAns + '\n') print(response) ### cut = input('是否需要逐句翻譯?(輸入 c 或 1 為是,否則按 Enter 鍵,之後不會再追問)') if len(cut) == 0: cut = '' elif cut == 'c' or cut == '1': cut = 'c' while True: beforeString = '' print('輸入欲翻譯的內容,按下最後一次換行鍵後,輸入 ctrl + z 再按 enter 鍵才算結束輸入:') ''' #多行讀入的寫法 for line in sys.stdin: beforeString += line 但 cmd 時會有無限輸入的麻煩 ''' beforeString = sys.stdin.readlines() ##print(beforeString) print('=' * 28 + ' 翻譯結果 ' + '=' * 28) gTranStr(beforeString, cut) print('\n' + '=' * 28 + ' 翻譯至此 ' + '=' * 28) re = input('\n輸入 n 離開,' + '不輸入按 Enter 鍵重新開始,' + '輸入 # 反轉上次的逐句翻譯設定並重新開始\n') ## + '輸入 @ 清空版面並重新開始\n') if re == 'n' or re == '0': break elif re == '#': if len(cut) == 0: cut = 'c' elif cut == 'c': cut = '' pass ''' elif re == '@': os,system('cls') 就算改 clear 亦沒有作用,都會閃退,奇怪... ''' os.system('pause') ``` ## 爬取學校的活動系統 ```python= from requests import get from bs4 import BeautifulSoup import os ##爬取學校的活動系統 ''' soup.select('h3.r a')中的h3為標籤名稱.為class屬性, . 的後面接class名稱也就是r,# 為 id屬性。 soup.prettify() 印出網頁原始碼 ''' actUrl = "https://webap.nptu.edu.tw/aes/aes/aee0010.aspx" ## def adjust(infList, aP, bP, add = False):#調整串列內容 if add: infList[aP] += ' ' + infList[bP] else: infList[aP] += infList[bP] infList.remove(infList[bP]) def spicalSet(adList, num): #自行定義調整後的串列,參數的串列不會被更改,會由另一個串列回傳 backList = adList #進行次數 i = len(backList) - 1 while(i): adjust(backList, 0, 1, True) i -= 1 return backList def check(p, tarStr, clist):#核對統計結果並輸出 #預設不寫入 w = False afterList = [] for i in range(len(clist)): if i % 7 == 0:#找到資料組(7個一組)的頭並核對欄位 if clist[i + p] == tarStr: w = True else: w = False ##print(str(i) + ' ' + str(w) + ' ' + clist[i + p]) if not w:#不符則跳過不繼續寫入 continue afterList.append(clist[i]) return afterList def crawlbug(url, appoint = False):#預設會把不能報名的項目淘汰,但'未開始'的會一併呈現 #取得網頁資料 r = get(url) #將網頁資料以html.parser soup = BeautifulSoup(r.text,"html.parser") #找到各欄位資料 allData = soup.select('table#GridView1 td') ''' 各欄位資料如下: 每 7 個為一筆資料循環,記得加.text.split()保留純文字,不然會連html都跑出來 ''' ''' 開啟布林參數(appoint)並設定數字參數(point),對資料進行單一過濾 ''' allresult = []#首輪輸出結果,未調整 result = []#最終輸出結果 sta = []#儲存統計值 jump = True #決定跳過該輪資料寫入 point = 7 #指定欄位指標 allDis = False #是否全顯示 #指定欄位顯示 if appoint: print('0 -活動名稱') print('1 -報名對象') print('2 -主辦單位') print('3 -錄(備)取人數') print('4 -活動起迄日期') print('5 -報名起迄日期') print('6 -報名狀態') point = input('輸入指定報名狀態(數字):') point = int(point) if point < 0 or point > 7: point = 7 default = input('\n是否完全顯示所有報名狀態(涵蓋\'已截止\'、\'已額滿\',預設自動排除)?(y/n)') if default == 'y' or default == '1': allDis = True elif default == 'n' or default == '0': allDis = False else: print('\n例外選項,自動回歸預設處理...\n') #進行預設(排除'已截止'、'已額滿')整理 for i in range(len(allData)): if i % 7 == 0: if appoint == True and i < len(allData) and allDis == False: if allData[i + 6].text.split() == ['已截止'] or allData[i + 6].text.split() == ['已額滿']: jump = False else: jump = True if not jump:#決定是否寫入 continue data = allData[i].text.split() ##print ('%s %s' % (i, data)) adData = spicalSet(data, i % 7) ##print (str(i) + ' ' + adData[0]) allresult.append(adData[0]) #寫入過濾條件 if point != 7 and i % 7 == 6: if i < 7: if sta.count(allresult[point]) == 0: sta.append(allresult[point]) else: long = len(allresult) if sta.count(allresult[long - 1 - (6 - point)]) == 0: sta.append(allresult[long - 1 - (6 - point)]) if point != 7:#列出指定欄位下的選項 print('\n目標代號如下:') for j in range(len(sta)): if j < 10: print(str(j) + ' ' + sta[j]) else: print(str(j) + ' ' + sta[j]) print('-') #選擇該選項 numP = int(input('\n輸入代號:')) #進行核對輸出 result = check(point, sta[numP], allresult) else: result = allresult #確認無資料顯示 if len(result) == 0: return print ('\n沒有可顯示的資料!\n') #為顯示資料組間作分隔 for i in range(len(result)): if i % 7 == 0 : print ('<===================第%s筆資料===================>\n' % str(int(i/7) + 1)) print (result[i]) print ('\n') #資源回收 result.clear() ## ans = input('是否有指定欄位與內容?(y/n)') if ans == 'y' or ans == '1': crawlbug(actUrl, True) elif ans == 'n' or ans == '0': crawlbug(actUrl) else: print('\n例外選項,自動回歸預設處理...\n') os.system('pause') ``` ## 倒數計時器 ```python= #倒數計時器 #介面完成 #測試完成 from tqdm import tqdm from time import sleep import os ##輸入時間 t = input('輸入倒數時間(分鐘 + 秒, ex:3500)?') ts = int(t[0:2])*60 + int(t[2:4]) #開始倒數 for i in tqdm(range(ts)): sleep(1) print() print('時間到啦~~') os.system('pause') ``` ## 動態進度點(百分比) ```python= import time import sys, os ##動態進度點 #該效果限在 cmd 時才看的到喔! for i in range(101): time.sleep(0.005) sys.stdout.write("\r%d%%" % i) sys.stdout.flush() print() print('跑開心的,沒什麼用途~~') os.system('pause') ``` ## 動態進度點(進度條) ```python= import time import sys, os ##動態進度點(進度條) #該效果限在 cmd 時才看的到喔! size = 100 long = '\r[%-' + str(size - 1) + 's] %d%% ' size += 1 for i in range(size): time.sleep(0.005) sys.stdout.write(long % ('='*i, i)) sys.stdout.flush() print() print('跑開心的,沒什麼用途~~') os.system('pause') ``` ## 連線程式client端 ```python= import socket, time, os, struct ##連線程式client端 ''' ''' HOST = "#(同網域的 IP)" PORT = 20 #(自行調整) choose = '' keyname = 'test1' def DownLoad(choose): sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sockfd.connect_ex((HOST,PORT)) print (HOST,"建立連線") b = choose.encode() sockfd.sendall(b) fileinfo_size = struct.calcsize('128sl') buf = sockfd.recv(fileinfo_size) if buf: filename, filesize = struct.unpack('128sl', buf) fn = filename.strip(b'\00') new_filename = os.path.join(b'./'+ fn) print ('檔案名稱為 {0}, 大小 {1}'.format(new_filename,filesize)) recvd_size = 0 # 定義已接收檔案的大小 fp = open(new_filename, 'wb') print ('開始接收') while not recvd_size == filesize: if filesize - recvd_size > 1024: data = sockfd.recv(1024) recvd_size += len(data) else: data = sockfd.recv(filesize - recvd_size) recvd_size = filesize fp.write(data) print ('下載中...') fp.close() print ('下載完成') print ("與",HOST,"結束連線") sockfd.close() def punch(name, choose): sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sockfd.connect_ex((HOST,PORT)) print (HOST,"建立連線") b = choose.encode() sockfd.send(b) time.sleep(0.5) #送出名稱 print ('你好! ',name,' 歡迎來到網路實驗室!') txtData = name Cbyt = txtData.encode() sockfd.send(Cbyt) print ('送出打卡訊息') #等待回覆 response = sockfd.recv(1024).decode() print(response) print ("與",HOST,"結束連線") sockfd.close() ###主介面 #sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: #連線 #sockfd.connect_ex((HOST,PORT)) #print (HOST,"建立連線") while True: print ('----------------------------------------' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) #主畫面 print ("(1)download -下載記錄檔") print ("(2)punch -打卡") choose = input("請輸入想操作的內容: ") #需要連線伺服器的功能才要這兩行 #byt = choose.encode() #sockfd.sendall(byt) if choose == '1': DownLoad(choose) elif choose == '2': punch(keyname, choose) #暫停以檢視 print ('按任一鍵結束...') os.system('pause') except socket.error as msg : print (msg) print ("連線中斷or失敗,倘若仍有操作尚未完成,洽相關人員~~:)") #暫停以檢視 print ('按任一鍵結束...') os.system('pause') ``` ## 郵件檢視 + 隱藏密碼輸入 ```python= import imaplib, email, base64, quopri, binascii, getpass from os import system ##郵件檢視 + 隱藏密碼輸入 #由於 imaplib.IMAP4.error: b'[AUTHENTICATIONFAILED] Invalid credentials (Failure) #該程式針對 gmail 需要先設定存取權 #設定網址 https://myaccount.google.com/lesssecureapps?pli=1 #目前僅能執行事先設定過的 gmail ''' payload = "測爽沒" b =base64.b64encode(payload.encode('utf-8')).decode("utf-8") print(b) c = base64.b64decode(b.encode("utf-8")).decode("utf-8") print(c) b =quopri.encodestring(payload.encode("utf-8")).decode("utf-8") print(b) c = quopri.decodestring(b.encode("utf-8")).decode("utf-8") print(c) GetPassWarning: Can not control echo on the terminal. Warning: Password input may be echoed 因為 getpass 效果僅限於 cmd 介面喔! ''' def selfbase64(string): #實作base64 ''' (作者碎念) 只能轉英文不能轉中文,會亂碼 找不到轉中文的對應辦法,有夠爛 網路上各種互抄,還只抄轉出去的,沒抄轉回來的 ''' base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' stringFirst = '' for i in range(len(string)): point = base64Table.find(string[i]) pointStr = str(point) if len(pointStr) < 2: pointStr = '0' + pointStr stringFirst += pointStr #print (point) strSecond = '' for j in range(len(stringFirst)): if j % 2 == 1: continue num = int(stringFirst[j:j+2]) #print(str(num)) numStr = '' for k in range(6): numStr = str(num % 2) + numStr num = num // 2 #print(str(num) + ' ' + numStr) strSecond += numStr #print (stringFirst[j:j+2] + ' ' + numStr) #print(strSecond) strThird = '' #print(str(len(strSecond))) key = 8 uninum = '' for m in range(len(strSecond)): if m % key != 0: continue ascStr = strSecond[m:m+key] #print(str(m//16) + ' ' + str(len(ascStr)) + ' ' + ascStr) num = 0 for n in range(key): powN = 2**(key-n-1) num += int(ascStr[n])* powN uninum += chr(num) #print(str(num) + ' ' + uninum + '\n') print(uninum) def printMail(ue, pd): #挖郵件 many = input('輸入顯示的數量(全顯示輸入a,預設為前五筆):') #預設顯示郵件數量 lim = 5 m = imaplib.IMAP4_SSL('imap.gmail.com', 993) ##下列該行會有驗證問題 m.login(ue, pd) status, count = m.select() email_count = len(m.search(None, 'ALL')[1][0].split()) if many == 'a': lim = email_count elif many == '': pass elif int(many) > email_count: print('數量過大,自動轉成最大值') else: lim = int(many) print('郵件總數為: ' + str(email_count) + ' ' + '指定數量為: ' + str(lim)) print() for i in range(email_count): status, email_content = m.fetch(f'{email_count-i}'.encode(), '(RFC822)') try: email_content = email_content[0][1].decode() #print (email_content) except: #print (email_content) print(str(i+1) + ' 該郵件發生錯誤,不顯示...QAQ\n') continue strat = email_content.find('MIME-Version: 1.0') dateStart = email_content.find('Date:', strat) if dateStart == -1: dateStart = email_content.rfind('Date:') dateEnd = email_content.find('\r',dateStart) date = email_content[dateStart:dateEnd] subStart = email_content.rfind('Subject:') subEnd = email_content.find('\r',subStart) sub = email_content[subStart:subEnd] froStart = email_content.find('From:', strat) if froStart == -1: froStart = email_content.rfind('From:') froEnd = email_content.find('\r',froStart) fro = email_content[froStart:froEnd] sub = sub.lstrip('Subject:Re ') if sub[0] == '=': backup = sub sub = sub.strip().strip('=?').lstrip('UTFutf-8?') if sub[0] == 'b' or sub[0] == 'B': sub = sub.lstrip('Bb?') try: long = len(sub) % 4 if long != 0: for many in range(4 - long): sub += '=' sub = base64.b64decode(sub.encode('utf-8')).decode('utf-8') except : print (str(i+1) + ' ' + backup + ' ' + str(len(backup))) print (' ' + sub + ' ' + str(len(sub)) + '\n') continue elif sub[0] == 'q' or sub[0] == 'Q': sub = sub.lstrip('Qq?_') try: sub = quopri.decodestring(sub.encode('utf-8')).decode('utf-8') except : print (str(len(sub)) + ' ' + sub) continue fro = fro.lstrip('From: ') if fro[0] == '=': backup = fro fro = fro.strip().strip('=?').lstrip('UTFutf-8?') if fro[0] == 'b' or fro[0] == 'B': fro = fro.lstrip('Bb?') try: long = len(fro) % 4 if long != 0: for many in range(4 - long): fro += '=' fro = base64.b64decode(fro.encode('utf-8')).decode('utf-8') except : fro = backup continue elif fro[0] == 'q' or fro[0] == 'Q': fro = fro.lstrip('Qq?_') #try: fro = quopri.decodestring(fro.encode('utf-8')).decode('utf-8') #except : #fro = backup #continue print (str(i+1) + ' ' + sub) print ('From: ' + fro) print (date) print ('') if i == lim - 1: break m.close() m.logout() username = input('郵件帳號:') password = getpass.getpass('密碼:') printMail(username, password) system('pause') ``` ## 遍歷文件夾並複製指定副檔名的檔案 ```python= #完成介面 #遍歷文件夾底下的所有子目錄,將指定的副檔名複製至指定路徑 #並統計文件夾底下所有副檔名類型 #統計出未被複製檔案的文件夾 #輸出"未獲取到指定文件的路徑"中是否有需要排除的檔案須留意 import os import numpy as np from shutil import copy #目標路徑 #'C:\\Users\\user\\Desktop\\' yourPath = str(input('輸入目標路徑(亦可用拖曳的):')) #欲儲存的位置及名稱 #'C:\\Users\\user\\Desktop\\輸出資料夾' Target = str(input('輸入輸出路徑(亦可用拖曳的),若僅有名稱,則會輸出在目標的目錄位置:')) #指定的副檔名類型 # pdf docx pptx pointFileExtension = str(input('輸入指定副檔名,可以一次多個並以空白間隔:')).split(' ') def checkFileNextLevel(Path): #列出指定路徑底下所有檔案(包含資料夾) # listdir 只是將指定路徑底下的目錄和檔案列出來 # 逐一查詢檔案清單 for file in os.listdir(Path): #這邊也可以視情況,做檔案的操作(複製、讀取...等) #使用 isdir 檢查是否為目錄 #使用 join 的方式把路徑與檔案名稱串起來 if os.path.isdir(os.path.join(yourPath, file)): print("- dir: ", file) #使用isfile判斷是否為檔案 elif os.path.isfile(yourPath + file): print("- file: ", file) else: print('error !!') print() os.system('pause') def checkFileAllLevel(Path): # walk 的方式則會將指定路徑底下所有的目錄與檔案陳列出來(包含子目錄以及子目錄底下的檔案) #並將資料存進字典 vector vector = dict() #列出所有子目錄與子目錄底下所有的檔案 for root, dirs, files in os.walk(Path): #列出目前讀取到的路徑 print("path:", root) for f in files: #絕對路徑不會重複,故以此當 key 值,檔名作為 value 值 vector[os.path.join(root, f)] = f print("- file:", f) print('\n合計共 ' + str(len(vector)) + ' 筆檔案') return vector def catchFileExtension(filename): #擷取出副檔名(含點) ##該方式會受檔名含有相同的點號而受影響 #print(filename.split('.')[1]) #return filename.split('.')[1] #print(os.path.splitext(filename)) #print(os.path.splitext(filename)[-1]) return os.path.splitext(filename)[-1] def copyFile(FileOriPosition, SaveDir, NewName): #複製檔案或目錄至目標資料夾 copy(FileOriPosition, SaveDir + '\\' + NewName ) print('copyed ' + FileOriPosition) print(' to ' + SaveDir + '\\' + NewName ) def analyzeNumbers(dic): #統計檔案路徑總名單 sta = set() for key, value in dic.items(): #取學號的部分 sta.add(catchPathString(key, len(yourPath.split('\\')))) #print(sta) return sta def catchPathString(Path, index): #擷取檔案路徑上的特定字串 #print(Path.split('\\')) #print(Path.split('\\')[index]) return Path.split('\\')[index] ###main total = dict()#存取學號檔名和其子目錄 done = 0#完成作業次數 donedirs = set()#存取有被取得檔案的學號資料夾 sta = set()#統計副檔名 total = checkFileAllLevel(yourPath) print('============================ ~ 開抓啦 ~ ==========================') #如果指定目錄不存在就建立目錄 if not os.path.isdir(Target): os.mkdir(Target) print('目錄尚未找到,自動建立新目錄 => ', Target) for key, value in total.items(): #遍歷所有資料 for FileExt in range(len(pointFileExtension)): #比對指定副檔名 FileExtension = catchFileExtension(value) if FileExtension == '.' + pointFileExtension[FileExt]: #符合者進行複製和記錄處理 #copyFile 函數的 value 參數可以修改成指定的檔名 #亦可以用 value 保持原樣 copyFile(key, Target, catchPathString(key, len(yourPath.split('\\'))) + FileExtension) #取學號的部分 donedirs.add(catchPathString(key, len(yourPath.split('\\')))) sta.add(FileExtension) print('\n' + str(len(donedirs)) + ' Finished copying!!') print('============================ ~ 結算啦 ~ ==========================') print('所有副檔名統計名單:') print(np.array(list(sta))) print('\n未獲取到指定文件的路徑:') print(np.array(list(analyzeNumbers(total) - donedirs))) print() os.system('pause') ``` ## 壓縮和解壓縮檔案 _rar ```python= #壓縮和解壓縮檔案 #完成介面 #格式限定為 rar #檢查命令及是否有支援 rar 指令 #預設系統磁碟為 C ##會受限於權限問題 import os from shutil import copyfile ###main if os.path.isfile('C:\\Windows\\Rar.exe'): print('已確認支援該指令...') else: print('未支援該指令,嘗試進行補強...') #確認是否不存在 Rar.exe if not os.path.isfile('C:\\Program Files\\WinRAR\\Rar.exe'): print('\n疑似未安裝 WinRAR ,請關閉本程式後') print('\n嘗試安裝 WinRAR 並將其目錄底下的 Rar.exe 複製至 C:\\Windows\\') print('\n之後再重啟程式') else: print('\n找到目標程式!協助您進行處理...') try: copyfile('C:\\Program Files\\WinRAR\\Rar.exe', 'C:\\Windows\\Rar.exe') except PermissionError: print('\n權限問題!請依照下面指示手動完成預設定:') print('\n1. 檔案總管,到 C:\\Program Files\\WinRAR\\') print('\n2. 將目錄 WinRAR 底下的 Rar.exe 複製至 C:\\Windows\\') print('\n3. 重啟本程式') except: print("例外錯誤:", sys.exc_info()) print('\n倘若後續仍有閃退現象,嘗試重啟程式或訊問作者') print() os.system('pause') os._exit(1) do = str(input('\n壓縮(0)/解壓縮(1)?')) if do == '0': #source = 'C:\\Users\\user\\Desktop\\hw_185005' source = str(input('壓縮誰:')) #destination = 'C:\\Users\\user\\Desktop\\hw_185005' destination = str(input('壓縮完丟哪(路徑末為指定的壓縮檔名,放空也行):')) if len(destination) == 0: destination = source print('壓縮中請稍後...') #找到檔案當前所在的路徑 #切換程式當前目錄至壓縮目標旁 os.chdir(os.sep.join(source.split(os.sep)[:-1]) + os.sep) #print(os.sep.join(source.split(os.sep)[:-1]) + os.sep) #print(source.split(os.sep)[-1]) #再進行壓縮 #source.split(os.sep)[-1] 倘若改成僅有 source 的話, #壓縮檔會變成從輸入的目錄( source )開始打包喔 os.system('rar a ' + destination + '.rar' + ' ' + source.split(os.sep)[-1]) print('\n完成的檔案路徑:' + destination + '.rar') elif do == '1': #source = 'C:\\Users\\user\\Desktop\\hw_185005.rar' source = str(input('誰要解壓縮:')) #destination = 'C:\\Users\\user\\Desktop\\' destination = str(input('解完丟哪個目錄,放空也行):')) if len(destination) == 0: destination = source.split('.')[0] print('解壓縮中請稍後...') #找到檔案當前所在的路徑 #切換程式當前目錄至壓縮目標旁 os.chdir(destination) os.system('rar x ' + source + ' ' + destination + '-unpack' + os.sep) print('\n完成的檔案路徑:' + destination + '-unpack' + os.sep) else: print('沒這選項啦~') print() os.system('pause') ``` ## 壓縮和解壓縮檔案 ```python= #壓縮和解壓縮檔案 #完成介面 #依據官方文件檔,格式限定為“zip”,“tar”,“gztar”,“bztar”, or“xztar” import os from shutil import make_archive, move, unpack_archive def makeArchive(source, destination): base = os.path.basename(destination) name = base.split('.')[0] archiveFormat = base.split('.')[1] archive_from = os.path.dirname(source) archive_to = os.path.basename(source.strip(os.sep)) make_archive(name, archiveFormat, archive_from, archive_to) move('%s.%s'%(name,archiveFormat), destination) def unpackArchive(source, destination): base = os.path.basename(source) #name = base.split('.')[0] archiveFormat = base.split('.')[1] unpack_archive(source, destination, archiveFormat) ###main do = str(input('壓縮(0)/解壓縮(1)?')) if do == '0': #source = 'C:\\Users\\user\\Desktop\\hw_185005' source = str(input('壓縮誰:')) #destination = 'C:\\Users\\user\\Desktop\\hw_185005.zip' destination = str(input('壓縮完丟哪(路徑末須包含指定的壓縮檔副檔名):')) print('壓縮中請稍後...') makeArchive(source, destination) print('壓縮完成') elif do == '1': #source = 'C:\\Users\\user\\Desktop\\hw_185005.zip' source = str(input('誰要解壓縮:')) #destination = 'C:\\Users\\user\\Desktop\\fin_hw_185005' destination = str(input('解完丟哪:')) print('解壓縮中請稍後...') unpackArchive(source, destination) print('壓縮完成') else: print('沒這選項啦') print() os.system('pause') ``` ## 檔案比較與更新 ```python= import os, time, threading ##批量檔案內容更新 def fileExists(file1, file2):#確認兩檔案是否皆存在 if os.path.exists(file1) and os.path.exists(file2): return True else: return False def compare(file1, file2, lineSave, strS, strS2, look = False):#比較兩檔案內容差異並列出 lineNum = 1 if fileExists(file1, file2):#確認檔案存在 print ('該檔案存在...') else: print ('不存在該檔案,將自動新增...') f2 = open(file2, 'x', encoding = 'utf-8') f2.close() f1 = open(file1, encoding = 'utf-8') f2 = open(file2, encoding = 'utf-8') #讀入各自變數 flist1 = [x for x in f1] flist2 = [y for y in f2] #得出資料長度 flines1 = len(flist1) flines2 = len(flist2) #對兩串列作等長處理以比較 if flines1 < flines2: flist1[flines1:flines2+1] = ' ' * (flines2 - flines1) elif flines1 > flines2: flist2[flines2:flines1+1] = ' ' * (flines1 - flines2) #輸出比較結果 if look: print ('%s和%s比較結果:\n' % (file1, file2)) for y in zip(flist1, flist2):#字典化合併處理 if y[0] == y[1]: lineNum +=1 continue if y[0] != y[1] :#發現相異內容就呈現 if look: print('第%s行: %s <--> %s\n' % (lineNum, y[0].strip(), y[1].strip())) lineNum +=1 lineSave.append(lineNum-1)#保留相異資訊的行號 strS.append(y[0]) strS2.append(y[1]) #未有內容呈現,回報兩檔案相同 if len(lineSave) == 0: print ('\n%s和%s內容和排版完全相同!' % (file1, file2)) def contentModify(fileO, fileM, lineSave, strS, strS2):#進行內容修改(以fileO為準修正fileM) #確認有內容要更新 if len(lineSave) == 0: print ('\n沒有要更新的內容!') return #開啟兩檔案,一個讀取,一個寫入 file = open(fileO, 'r', encoding = 'utf-8') file2 = open(fileM, 'w', encoding = 'utf-8') lineN = 0 for line in file:#修改內容回報 if(lineN < len(lineSave)) and strS2[lineN] in line: sys.stdout.write('修正第%s行內容...' % lineSave[lineN]) sys.stdout.flush() #print ('修正第%s行內容...' % lineSave[lineN]) lineN += 1 ##print(line) file2.write(line) #隨手關檔 file2.close() file.close() #回收空間 lineSave.clear() strS.clear() strS2.clear() def addNote(file, note):#追加註記 #開啟檔案 f = open(file, 'a', encoding = 'utf-8') #寫入註記 note = '\n##' + note + '\n##' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '秒 註\n' f.write(note) print ('完成註記\n') #隨手關檔 f.close() def update(new, files, li, note, strS, strS2, look): compare(new, files, li, strS, strS2, look) print ('=====================開始更新======================') contentModify(new, files, li, strS, strS2) #print ('==============更新結束,比對更新結果===============') #compare(new, files, li, strS, strS2, look) #addNote(files, note) print ('完成該檔更新!\n') ## li = []#行號 strS = []#對照檔 strS2 = []#待修正檔 stdFile = 'K:/tserver/server-2.py' files = ['C:/Users/BigBapu/Desktop/server/server-2.py'] for j in files: print ('===================更新第%s個檔案===================' % str(files.index(j))) compare(stdFile, j, li, strS, strS2, True) ans = input('進行批量更新?(y/n)') if ans == 'y' or ans == '1': note = input('\n更新內容註記:') start_t = time.time() for i in range(len(files)): print ('===================更新第%s個檔案===================' % str(i+1)) thread_Update = threading.Thread(target = update, args = (stdFile , files[i], li, note, strS, strS2, False)) thread_Update.start() thread_Update.join() #update(stdFile , files[i], li, note, strS, strS2, False) print ('完成批次更新!') end_t = time.time() print ('\n花費時間為 %s 秒' % str(end_t - start_t)) elif ans == 'n' or ans == '0': print ('取消更新') pass #暫停以檢視 print('按任一鍵結束...') os.system('pause') ``` ## 檔案備份 ```python= import shutil, os ##檔案備份 p = 'C:/Users/Public/Downloads/user/'#輸入備份路徑 ## def backup(oriPath, newdir):#移動舊版本至備份區(backup/) print('備份目錄是否存在...' + str(os.path.isdir(newdir))) if not os.path.isdir(newdir):#如果指定目錄不存在就建立目錄 os.mkdir(newdir) print ('建立新目錄' + newdir) if os.path.isfile(oriPath):#確認待更新檔案存在 #複製至指定路徑下 shutil.copyfile(oriPath, newdir + oriPath.split('/')[-1]) #擷取路徑各個位置 ''' print(p) print(p.split('/')[-1]) print('') print(p.split('/')[-1].split('.')[0].split('-')[0]) print(p.split('/')[-1].split('.')[0]) print(str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1)) print(p.split('/')[-1].split('.')[1]) print('') print(p[0:len(p)-len(p.split('/')[-1])] + p.split('/')[-1].split('.')[0].split('-')[0] + '-' + str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1) + '.' + p.split('/')[-1].split('.')[1]) print(str(len(p)-len(p.split('/')[-1]))) print(os.path.isfile(p)) ''' #修改檔名 os.rename(oriPath, p[0:len(p)-len(p.split('/')[-1])] + p.split('/')[-1].split('.')[0].split('-')[0] + '-' + str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1) + '.' + p.split('/')[-1].split('.')[1]) print ('備份檔案完成!') else: print ('待更新的檔案不存在!') ''' print(p) print(p.split('/')[-1]) print('') print(p.split('/')[-1].split('.')[0].split('-')[0]) print(p.split('/')[-1].split('.')[0]) print(str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1)) print(p.split('/')[-1].split('.')[1]) print('') print(p[0:len(p)-len(p.split('/')[-1])] + p.split('/')[-1].split('.')[0].split('-')[0] + '-' + str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1) + '.' + p.split('/')[-1].split('.')[1]) print(str(len(p)-len(p.split('/')[-1]))) print(os.path.isfile(p)) ''' backup (p, 'C:/Users/Public/Downloads/user/')#引號內置入備份路徑 print('\n當前更新後版本號為%s' % str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1) ) os.system('pause') ``` ## ```python= ```