---
# System prepended metadata

title: Python小應用

---

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

##多行內容翻譯處理
'''
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 = ''
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 cut == '':
            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=
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')
```
## 連線程式client端
```python=
import socket, time, os, struct

##連線程式client端
'''

'''
HOST = "163.24.242.196"
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

##郵件檢視 + 隱藏密碼輸入

'''
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

    try:
        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())
    except:
        

    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) + '   該郵件發生錯誤，跳過顯示...\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, 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/user-t/user-5.py'
##
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/backup/')
print('\n當前更新後版本號為%s' % str(int(p.split('/')[-1].split('.')[0].split('-')[1]) + 1) )
os.system('pause')
##

```
## 視覺化歷年黃金價格
```python=
import pandas as pd               # 資料處理套件
import matplotlib.pyplot as plt   # 資料視覺化套件
import numpy as np

'''
記得將新下載的csv做欄位名稱的預處理(中文換英文，多餘欄位刪除)
'''
csvs = '107GoldPassbook.csv'



def disPic(csv, sea):
    readCsv = pd.read_csv(csv)
    # print( readCsv['buyin'][:]) # 顯示資料
    
    date = [None] * len(readCsv['date']) # 建立一個空列表，數量為年月的數量
    
    # 以for迴圈逐一將年月資料類別轉成字串類別
    for i in range(len(readCsv['date'])):  
       date[i] = str(readCsv['date'][i])[4:8]
    
    
    readCsv['date'] = date[::-1]  # 將原本年月欄位資料反轉並替換掉，因為預設為資料為年尾到年初

    
    # 設定視窗大小、邊界顏色、邊框顯示
    plt.figure(figsize=(10.5,3.5), edgecolor = 'b', frameon = True)
    # 設定圖表與視窗的邊界距離(比例)
    plt.subplots_adjust(left = 0.07, right = 0.99, top = 0.9, bottom = 0.18)
    plt.style.use('ggplot') # 使用ggplot主題樣式
    
    # 畫第一條線，plt.plot(x, y, c)參數分別為 x 軸資料、 y 軸資料及線顏色 = 紅色
    plt.plot(readCsv['date'], readCsv['buyin'],c = 'r')
    # 畫第二條線
    plt.plot(readCsv['date'], readCsv['sellout'],c = 'g')

    # 設定圖例，參數為標籤、位置
    plt.legend(labels=['buyin', 'sellout'], loc = 'best')

    star = readCsv['date'][0]
    end = len(readCsv['date'])
    if int(sea) >= 1 and int(sea) <= 4:
        if sea == '1':
            end = end / 4
        elif sea == '2':
            star = end / 4
            end = end / 2
        elif sea == '3':
            star = end / 2
            end = end * 3/4
        elif sea == '4':
            star = end * 3/4
        elif sea == '':
            pass
    else:
        print('界外輸入，將回復預設值(全年)')
        pass
            
    # 設定x軸顯示範圍   
    plt.xlim(star, end) # 設定 x 軸顯示範圍
    plt.xlabel('Date', fontweight = 'bold',fontsize = 12) # 設定 x 軸標題及粗體
    plt.xticks(fontsize = 8, rotation = 35)   # 將 x 軸數字旋轉35度，避免文字重疊

    # 設定y軸標題及粗體
    plt.ylabel('Price(NTW)', fontweight = 'bold')
    plt.yticks(fontsize = 8, rotation = 20)# 刻度字體大小、逆時鐘旋轉角度

    # 設定標題、文字大小、粗體及位置
    plt.title('Gold Price', fontsize = 15, fontweight = 'bold', y = 1)   
    

    '''
    plt.savefig('Goldgrowth.jpg',   # 儲存圖檔
            bbox_inches='tight',               # 去除座標軸占用的空間
            pad_inches=0.0)                    # 去除所有白邊
    '''
    plt.show()
    plt.close() #隨手關燈~
    
season = input('輸入指定季節(預設輸入空值為整年度)：')
disPic(csvs, season)
    
```