---
# System prepended metadata

title: JSON

---

# JSON
學完了怎麼開關編輯檔案，這裡介紹一個常見的資料格式，許多程式的資料庫或資料顯示方式都是 JSON

JSON 是 JavaScript Object Notation 的簡稱，JavaScript 是目前最普遍的寫網頁用的語言，object notation 就是指在 JavaScript 這個語言裡，object 的形式幾乎就是 JSON 的形狀。許多網頁資料庫就是用 JSON 寫。
而很幸運地，Python 要處理 JSON 也非常容易。

[json官網在這]( https://www.json.org/json-en.html)

簡單來說，json 就是一個大 dictionary。
複雜來說，它是一個 a format of strings，一個裝了無限個 dictionary 和 list 的 dictionary。

---
### For example,
以下是一個 json 檔實際運用的例子，在我的疫情bot裡，許多功能都會需要每日確診的資料，因為每一次需要資料時都重新上網抓很麻煩，所以我們決定把資料一次抓下來，讓需要用到的地方讀我們自己的資料庫就好
``` json
{
    "today_confirmed": 0,
    "today_domestic": 0,
    "today_imported": 0,
    "today_deaths": "26",
    "additional_text": "\n今日新增之16,524例本土病例",
    "error": false
}
```
 
可以看到最外層是一組大括號，跟 dictionary 一樣
裡面也是一個 key 加 一個 value，跟 dictionary 一樣

下面是另一個我的疫情bot有用到的 json，這一個檔名叫 `history_data.json`，用來製作統計圖表的。
因為程式每天都會被重新跑一次，所以前一天的資料沒有辦法只存在程式記憶體 -- 也就是任何 variable 裡，於是我們用一個外部的檔案作為資料庫。
``` json
{
    "confirmed": [
        50, 25, 50, 25, 55187, 94808, 0, 0, 10000, 8822, 49, 0, 1000, 104
    ],
    "average": [
        21449, 21442, 22867, 24120, 24123, 16239, 2838, 2853, 2996, 1582, 326, 320, 323, 187
    ],
    "dates": [
        "1015", "1014", "1013", "1012", "1011", "1010", "1009", "1008", "1007", "1006", "1005", "1004", "1003", "1002"
    ]
}
```
可以看到最外依然是 dictionary 的起手勢，但比較特別的是，這次的 value 是一個 list

---
### Step by step...
有基礎的概念之後，使用方式跟一般的 Python file I/O 差不多，只是我們可以用 Python 的 json library 來方便控制每一項

以上面的 `histiry_data.json` 為例
讀檔會跟一般讀檔一樣
``` python
import json

with open("history_data.json", "r") as jsonFile1:
    history = json.load(jsonFile1)
```
這裡 `with open("history_data.json", "r") as jsonFile1` 和 `jsonFile1 = open("history_data.json", "r")` 一樣，差別是後者最後需要 `jsonFile1.close()` 而前者不用。
接著 `json.load(jsonFile1)` 叫了一開始 import 進來的 json module，並使用了它的 `load()` function，最後這個 function 的 return 是一個 Python 看得懂的 json 格式，我們把它塞進一個名為 hostory 的 variable。
從這一刻起，hisotry 就不是一般讀檔讀進來的一堆純文字，而是一個 Python 的 json object

Python 對於 json 最友善的部份就是我們完全可以把讀進來的 json 檔當作 dictionary 用


``` python
confirmed_history_list = history["confirmed"]
average_history_list = history["average"]
dates_history_list = history["dates"]
```
就像用 key 讀取 dict 的 value 一樣，上面讀了 confirmed 和 average 這兩個 key 的 value，這兩個 value 不是單一數值而是一個 list，但仍然可以分別塞近 variable 裡，變成一般的 list

接著繼續
``` python 
confirmed_history_list.pop()
average_history_list.pop()
dates_history_list.pop()
#--------------------------------------
confirmed_history_list.insert(0, today_confirmed)

today_average = int(statistics.mean(confirmed_history_list[:7]))
average_history_list.insert(0, today_average)

dates_history_list.insert(0, today_date)
```
上面第一部份是簡單地把 list 的最後一項刪除
第二部份用了 Python list 的 `insert()` function （也是我當下搜尋才知道有這個東西），憑直覺地，可以看出 `insert()` 這個 funciton 的第一個 argument 應該代表想要插入的 index，而第二個代表想插入的值
於是這一段我把 list 的尾巴刪掉，從頭補了新的一項進去
也就是把當天的資料加入資料庫，然後把超過兩星期的過時資料刪掉了

但到目前為止 confirmed_history_list, average_history_list, 和 dates_history_list 都是我的 variable，與我的檔案無關，所以還需要把這些更新後的資料重新寫入檔案內
``` python 
history["confirmed"] = confirmed_history_list
history["average"] = average_history_list
history["dates"] = dates_history_list


with open("history_data.json", "w", encoding='utf-8') as jsonFile2:
    json.dump(history, jsonFile2, indent=4)

```
上半部我們借用之前的 history 這個 json object，覆蓋掉它原本的值，把原本 key 是 confirmed, average, 和 dates 的 value 換成新的、改過的 list
下半部我們重開了一個可以寫入的 stream，然後用 json 的 `dump()` function 把更新後的 json object 整包塞到檔案

這就是說基礎不基礎，說複雜不複雜的 json 基本用法～

---
### 實際運用
這裡是一個政府的開放資訊平台的資訊
https://data.gov.tw/dataset/156914
很多(或大部分)的個人 project 都會用到各種政府開放資訊，常見的格式有 txt, json, 和 csv，我個人最喜歡的格式就是 json。
現在可以來玩玩看開放資訊囉


###### by json王 XD


<br></br>
:::info
[BACK](https://hackmd.io/@lhsueh1/python101)
:::