顯示具有 Python::檔案處理 標籤的文章。 顯示所有文章
顯示具有 Python::檔案處理 標籤的文章。 顯示所有文章

2021年7月10日 星期六

處理CSV檔案內容更新問題

學習目標:
  • 了解 Python 如何更新 CSV 檔案內容!

處理過程實作
  1. 先準備好需要更新的 CSV 檔案, stores.csv
    ID,name,owner,prize
    1,日本,-1,2500
    7,加拿大,-1,3500
    13,英國,-1,4500
    19,埃及,-1,1200
    2,南韓,-1,2000
    8,美國,-1,4300
    14,法國,-1,4200
    20,象牙海岸,-1,2200
    4,台灣,-1,2500
    10,巴拿馬,-1,3500
    16,德國,-1,3800
    22,南非,-1,1800
    5,新加坡,-1,3000
    11,阿根廷,-1,2800
    17,立陶宛,-1,1700
    23,印度,-1,1800
    
  2. 撰寫一個 Stores.py 的類別程式,可讀取 stores.csv 檔案:
    import csv
    
    class Stores:
    
        def __init__(self):
            self.__id = []
            self.__name = []
            self.__owner = []
            self.__prize = []
            with open('stores.csv', newline='',encoding='utf-8') as csvfile:
                rows = csv.DictReader(csvfile)
                for row in rows:
                    self.__id.append(row['ID'])
                    self.__name.append(row['name'])
                    self.__owner.append(row['owner'])
                    self.__prize.append(row['prize'])
    
        def getStoreData(self,po):
            index = self.__id.index(po)
            print(self.__name[index])
    
    if __name__ == "__main__":
        myStore = Stores()
        myStore.getStoreData(str(2))
    
  3. 修改 Stores.py ,將更新後的資料,可以寫入原讀取的資料行:
    (前方略過....)
        def setStoreData(self,newdata):
            index = self.__id.index(newdata[0])
            self.__owner[index] = newdata[2]
            with open('stores.csv', 'w', newline='') as csvfile:
                writer = csv.writer(csvfile)
                length = len(self.__id)
                writer.writerow(['ID','name','owner','prize'])
                for i in range(0,length):
                    writer.writerow([self.__id[i],self.__name[i],self.__owner[i],self.__prize[i]])
    
    if __name__ == "__main__":
        myStore = Stores()
        result = myStore.getStoreData(str(2))
        result[2] = '1'
        myStore.setStoreData(result)
        newresult = myStore.getStoreData(str(2))
        print(newresult)
    
修改遊戲主要流程
  1. 加入 Stores 類別,修改遊戲主要流程:
    # 加入 Stores 類別
    import Stores
    (中間一堆程式碼,略過!)
    ##### c.) 移動到骰子點數的框格
            newpo = players[i].getPo()
            
            # I. 可能經過起點
            if newpo >= areas:
                newpo = playerPo(newpo)
                if newpo == 0:
                    print("玩家回到「開始」位置:", newpo)
                elif newpo < (areas/4):
                    print("玩家越過「開始」位置:", newpo)
    
            print("玩家在新位置:",newpo)
            #  II. 可能落在邊角框格
            if (newpo  == 6):
                print("玩家休息一天")
            elif (newpo  == 18):
                print("玩家再玩一次")
    
            #  III. 可能是在機會與命運框格
            ## 機會的地圖編號是 3,15 兩個號碼
            elif ((newpo == 3) or (newpo == 15)):
                myChance = Chance.Chance()
                chances = myChance.choice()    
                print("玩家中機會:",chances[0])
    
            #  IV. 可能是在地產框格
            else:
                playerStore = Stores.Stores()
                store = playerStore.getStoreData(str(newpo))
                ## 判斷是否有人己取得該地產所有權了
                if store[2] == '-1':
                    print("該地產無人所有!")
                else:
                    print("該地產為:" + str(players[store[2]].getName()) + "所有")
    (剩下的程式碼略過....)
    

2021年7月9日 星期五

讀取檔案與寫入檔案的方式

學習目標:
  • 了解 Python 如何讀寫檔案!
  • 了解 Python 如何使用 CSV 檔案!

讀寫一般檔案
  1. 從檔案中,讀取資料:
    • stores.txt 檔案內容如下:
      阿好蚵仔煎
      管長大腸包小腸
      盧小小滷味店
      阿Q日式拉麵店
      小寬肉粽老店
      阿強冷凍水餃店
      
    • readStores.py 檔案內容如下:
      # 讀取檔案內容
      files = open("stores.txt","r", encoding='utf-8')
      
      # 建立一個空的串列,準備接收檔案的每一行文字
      stores = []
      
      # 利用迴圈將每一行文字,放入串列
      for i in files:
      	stores.append(i)
         
      print(stores)
      print("第五家店:",stores[4])
      
      # 關閉檔案
      files.close()
      
    • 更快的讀取方式
      # 讀取檔案內容
      files = open("stores.txt","r", encoding='utf-8')
      
      # 建立一個空的串列,準備接收檔案的每一行文字
      stores = []
      
      # 利用 readlines 將每一行文字,放入串列
      stores = files.readlines()
      
      print(stores)
      
  2. 將資料寫回檔案,例:writeStores.py
    # 將檔案內容讀出至串列
    files = open("stores.txt","r", encoding='utf-8')
    stores = []
    for i in files:
        stores.append(i)
    files.close()
    
    # 最後一筆資料要處理換行的問題
    stores[-1] = str(stores[-1] + "\n")
    
    # 新增一家店名,店名後方,要加上"\n"
    newstore = "北極熊火鍋店\n"
    
    # 將新店家名稱加入 stores 串列
    stores.append(newstore)
    
    # 開啟檔案,設定成可寫入模式
    new_files = open("stores.txt","w", encoding='utf-8')
    
    # 將串列寫入檔案中
    new_files.writelines(stores)
    
    # 關閉檔案
    new_files.close()
    
  3. 如果只是附加,可以更快一點!
    # 新增一家店名,店名後方,要加上"\n"
    newstore = "\n北極熊火鍋店"
    
    # 開啟檔案,設定成附加寫入模式
    new_files = open("stores.txt","a", encoding='utf-8')
    
    # 將串列寫入檔案中
    new_files.writelines(newstore)
    
    # 關閉檔案
    new_files.close()
    
讀寫 CSV 檔案
  1. 從 CSV 檔案中,讀取資料:
    • CSV 檔案 food.csv 內容如下:
      菜單,價錢
      原汁牛肉麵,150
      牛肉湯麵,80
      餛飩麵,75
      泡麵,50
      
    • 讀取 CSV 檔案的作法,例:readFood.py
      # 引用 csv 類別
      import csv
      
      # 開啟 CSV 檔案
      with open('food.csv', newline='') as csvfile:
      
          # 讀取 CSV 檔案內容,可指定分隔符號
          rows = csv.reader(csvfile, delimiter=',')
      
          # 以迴圈輸出每一列
          for row in rows:
              print(row)
      
    • 第一行是欄位名稱
      # 引用 csv 類別
      import csv
      
      # 開啟 CSV 檔案
      with open('food.csv', newline='') as csvfile:
      
          # 讀取 CSV 檔內容,將每一列轉成一個 dictionary
          rows = csv.DictReader(csvfile)
      
          # 以迴圈輸出指定欄位
          for row in rows:
              print(row['菜單'], row['價錢'])
      
  2. 將資料,寫入 CSV 檔案內
    • 第一行是欄位名稱,CSV檔案一開始不用建立
          
      # 引用 csv 類別
      import csv
      
      # 開啟輸出的 CSV 檔案
      with open('food2.csv', 'w', newline='') as csvfile:
          # 建立 CSV 檔寫入器
          writer = csv.writer(csvfile, delimiter=',')
      
          # 寫入一列資料
          writer.writerow(['茶飲', '價錢'])
      
          # 寫入另外幾列資料
          writer.writerow(['綠茶', 30])
          writer.writerow(['紅茶', 35])
      
    • 一口氣寫入的方法
      # 引用 csv 類別
      import csv
      
      # 二維表格
      table = [
          ['茶飲', '價錢'],
          ['綠茶', 30],
          ['紅茶', 35]
      ]
      
      with open('food2.csv', 'w', newline='') as csvfile:
          writer = csv.writer(csvfile)
      
          # 寫入二維表格
          writer.writerows(table)
      
    • 使用 Python 的 Dictionary 寫法
      # 引用 csv 類別
      import csv
      
      # 開啟輸出的 CSV 檔案
      with open('food2.csv', 'w', newline='') as csvfile:
        # 定義欄位
        fieldnames = ['茶飲', '價錢']
      
        # 將 dictionary 寫入 CSV 檔
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
      
        # 寫入第一列的欄位名稱
        writer.writeheader()
      
        # 寫入資料
        writer.writerow({'茶飲': '綠茶', '價錢': 30})
        writer.writerow({'茶飲': '紅茶', '價錢': 35})
      
修改遊戲主要流程
  1. 製作「機會」的 CSV 檔案,例如:chance.csv:
    機會訊息,金額
    中大樂透普獎2000元,2000
    賣出股票獲利1000元,1000
    繳納水電費支出500元,-500
    加油站加油支出800元,-800
    過年紅包收入1500元,1500
    
  2. 製作「機會」類別,抽取機會內容:
    import random
    import csv
    
    class Chance:
        
        __messages = []
        __money = []
    
        # 讀取 CSV 檔案
        def choice(self):
            with open('chance.csv', newline='', encoding='utf-8') as csvfile:
                rows = csv.DictReader(csvfile)
                for row in rows:
                    self.__messages.append(row['機會訊息'])
                    self.__money.append(row['金額'])
                
            # 隨機抽取一張
            nums = random.randint(0,len(self.__messages)-1)
            return (self.__messages[nums],self.__money[nums])
        
    
    if __name__ == "__main__":
        myChance = Chance()
        print(myChance.choice())
    
  3. 修改遊戲流程主程式 main.py :
    # 引用 random 類別中的 randrange() 函數
    from random import randrange
    
    # 引用 Player 物件
    import Player
    
    # 引用 Chance 物件
    import Chance
    
    # 常用函式、參數設定區域
    ## 遊戲方格總數
    areas = 24
    
    ## 處理玩家是否有經過「開始」
    def playerPo(steps):
        if (steps >= areas):
            return (steps % areas)
        else:
            return steps
    
    # 程式流程開始
    # 使用 if __name__
    if __name__ == "__main__":
    
        # 要求玩家要輸入遊戲人數
        players_num = eval(input("請輸入玩家人數:"))
    
        # 建立玩家物件
        players = []
    
        # 按照遊戲人數,使用 Player 類別
        # 逐次產生玩家名稱、玩家代號、玩家初始遊戲幣、玩家初始位置等物件內容
        for i in range(players_num):
            players.append(Player.Player())
            # 要求玩家輸入玩家名稱
            players[i].setName(input("請輸入玩家名稱:"))
            
        # 輸出資料
        for i in range(players_num):
            print(players[i].getName())
            print(players[i].getPo())
            print(players[i].getMoney())
    
        # 設定玩家順序值
        i = 0
    
        # 開始進行遊戲
        while True:    
        ##### a.)
        ##### b.) 擲骰子
            newstep = randrange(1,6)
            print(players[i].getName() + "擲骰子:" + str(newstep) + " 點")
            print(players[i].getName() + "前進中...")
            # 設定玩家新的位置
            players[i].setPo(newstep)
            
        ##### c.) 移動到骰子點數的框格
            newpo = players[i].getPo()
            
            # I. 可能經過起點
            if newpo >= areas:
                newpo = playerPo(newpo)
                if newpo == 0:
                    print("玩家回到「開始」位置:", newpo)
                elif newpo < (areas/4):
                    print("玩家越過「開始」位置:", newpo)
    
            print("玩家在新位置:",newpo)
            #  II. 可能落在邊角框格
            if (newpo  == 6):
                print("玩家休息一天")
            if (newpo  == 18):
                print("玩家再玩一次")
    
            #  III. 可能是在機會與命運框格
            ## 機會的地圖編號是 3,15 兩個號碼
            if ((newpo == 3) or (newpo == 15)):
                myChance = Chance.Chance()
                chances = myChance.choice()    
                print("玩家中機會:",chances[0])
    
            #  IV. 可能是在地產框格
               
        ##### e.)
            # 輪至下一位玩家
            i = i + 1
            if (i >= players_num):
                i = i - players_num
            
        ##### f.) 結束遊戲條件
            ends = input("是否結束遊戲?Y:是 N:繼續")
            if ((ends == "Y") or (ends == "y")):
                break
    

2016年7月26日 星期二

Python 操作檔案目錄

Python 對於檔案處理的方法
  • 檔案處理方式:
    • 讀寫檔案內容!(上一章節)
    • 操作檔案目錄系統!
    • 執行檔案程式!(下一章節)
  • Python 常用的檔案操作函數:
    函數名稱說明所屬模組
    open(檔案名稱, 檔案操作類型)
    close()
    開啟檔案
    關閉檔案
    default
    exits('路徑/檔案名稱')測試檔案是否存在os.path
    isfile('檔案名稱')
    isdir('目錄名稱')
    檢查檔案類型os.path
    isabs('路徑名稱')檢查路徑名稱是否為路徑os.path
    copy('來源檔名','目的檔名')複製檔案shutil
    move('來源檔名','目的檔名')搬移檔案shutil
    rename('來源檔名','目的檔名')將檔案名稱更名os
    link('來源檔名','目的檔名')
    symlink('來源檔名','目的檔名')
    建立檔案連結os
    islink('檔案名稱')判斷是否為符號連結檔案os.path
    chmod('檔案名稱',0o權限值)更改檔案權限os
    chown('檔案名稱',uid,gid)更改檔案擁有權os
    abspath('檔案名稱')取得檔案絕對路徑名稱os.path
    realpath('檔案名稱')取得檔案符號連結路徑名稱os.path
    remove('檔案名稱')將檔案刪除os.path

  • Python 常用的目錄操作函數:
    函數名稱說明所屬模組
    mkdir('目錄名稱')建立目錄os
    rmdir('目錄名稱')刪除目錄os
    listdir('目錄名稱')列出目錄內容os
    chdir('目錄名稱')切換目錄os
快速測試:
  1. 開啟互動式指令:
    #python3
    Python 3.4.3 (default, Jan 26 2016, 02:25:35)
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    
  2. 建立檔案:
    >>> test1 = open("test",'wt')
    >>> print('Hello World!',file=test1)
    >>> test1.close()
    
  3. 判斷檔案是否存在:
    >>> import os
    >>> os.path.exists('test')
    True
    
  4. 檢查檔案類型:
    >>> os.path.isfile('test')
    True
    >>> os.path.isdir('test')
    False
    >>> os.path.isdir('.')
    True
    >>> os.path.isdir('..')
    True
    >>> os.path.isabs('/tmp')
    True
    >>>
    
  5. 複製檔案:
    >>> import shutil
    >>> shutil.copy('test','test1')
    'test1'
    >>>
    
  6. 更改檔案名稱:
    >>> import shutil
    >>> shutil.move('test1','test2')
    'test2'
    >>> import os
    >>> os.rename('test2','test2_move')
    >>>
    
  7. 建立連結檔案:
    >>> os.link('test2_move','test2.txt')
    >>> os.symlink('test2.txt','test3.txt')
    >>> os.path.islink('test3.txt')
    True
    >>> os.path.islink('test2.txt')
    False
    >>>
    
  8. 更改檔案權限:
    >>> os.chmod('test2.txt',0o400)
    >>>
    
  9. 更改檔案擁有權:
    >>> os.chown('test2.txt',1000,5)
    >>>
    
  10. 取得檔案目前路徑:
    >>> os.path.abspath('test2.txt')
    '/home/student/python_HW/files/test2.txt'
    >>>
    
  11. 取得符號連結檔案路徑名稱:
    >>> os.path.realpath('test3.txt')
    '/home/student/python_HW/files/test2.txt'
    
  12. 刪除檔案:
    >>> os.remove('test3.txt')
    >>> os.path.exists('test3.txt')
    False
    >>>
    
  13. 建立目錄:
    >>> os.mkdir('work')
    >>> os.path.exists('work')
    True
    
  14. 刪除目錄:
    >>> os.rmdir('work')
    >>> os.path.exists('work')
    False
    >>>
    
  15. 列出目錄內容:
    >>> os.mkdir('work')
    >>> os.listdir('work')
    []
    >>> os.mkdir('work/test')
    >>> os.listdir('work/test')
    []
    >>>
    
  16. 改變目前工作路徑:
    >>> os.chdir('work')
    >>> os.listdir('.')
    ['test']
    >>>
    

Python 的檔案讀寫功能

Python 對於檔案處理的方法
  • 檔案處理方式:
    • 讀寫檔案內容!
    • 操作檔案目錄系統!(下一章節)
    • 執行檔案程式!(下一章節)
    • Python 常用的檔案讀寫函數:
      函數名稱說明
      write(資料內容)寫入資料到檔案內
      read()
      read(字元數量)
      一次讀出所有資料內容
      讀出多少字元數量
      readline()每次只讀取一行
      readlines()讀取全部內容,但每次只回傳一行
  • Python 開啟檔案內容的基本格式:
    檔案物件變數名稱 = open(檔案名稱, 檔案操作類型)
    
    ##檔案操作類型,共兩個字元###
    ####第一個字元####
    r : 讀取
    w : 寫入檔案(可新增檔案)
    x : 寫入檔案(不可新增檔案)
    a : 寫入檔案(附加在檔案結尾處)
    
    ####第二個字元####
    t : 代表文字
    b : 代表二進位
    
快速測試:
  1. 開啟互動式指令:
    #python3
    Python 3.4.3 (default, Jan 26 2016, 02:25:35)
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    
  2. 對檔案進行寫入文字的動作:
    >>> text1 = "This is a test files!"
    >>> fileOut = open('test1.txt','wt')
    >>> fileOut.write(text1)
    21
    >>>quit()
    #
    
  3. 驗證寫入結果:
    $ cat test1.txt
    This is a test files!
    
  4. 編寫讀取檔案的程式:
    #vim readFiles.py
    class readFiles():
       def __init__(self):
          self.__name = ""
    
       def readFiles(self,name):
          self.__files = open(name,'rt').read()
          return self.__files
    
    
    testfiles = readFiles()
    print(testfiles.readFiles("test1.txt"))
    
  5. 執行程式:
    #python3 readFiles.py
    This is a test files!
    
  6. 修改一下檔案的程式:
    #vim readFiles.py
    class readFiles():
       def __init__(self):
          self.__name = ""
    
       def readFiles(self,name):
          self.__files = open(name,'rt')
          po = self.__files.read()
          self.__files.close()
          return po
    
       def readLines(self,name):
          self.__lines = open(name,'rt')
          lin = len(self.__lines.readlines())
          self.__lines.close()
          return lin
    
    testfiles = readFiles()
    print(testfiles.readFiles("test1.txt"))
    print("test1.txt has ",testfiles.readLines("test1.txt")," lines")
    
  7. 執行程式:
    #python3 readFiles.py
    This is a test files!
    Hello World !!
    This is the 3rd lines!!
    
    test1.txt has  3  lines