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=
```