python 實作 === 是作業_(:3 ⌒゙)_ # 股票收盤價趨勢 ![執行畫面](https://hackmd.io/_uploads/Bkp1CJ1S0.png) ![excel輸出](https://hackmd.io/_uploads/ByG7A1yHR.png) ![圖表輸出](https://hackmd.io/_uploads/rk08AJkBA.png) ## if \_\_name\_\_ == '\_\_main\_\_': ```python= # -*- coding: utf-8 -*- """ Created on Thu Jun 6 13:13:11 2024 @author: liquorem """ # 所需套件 import requests import bs4 import pandas as pd import matplotlib.pyplot as plt import matplotlib import re if __name__ == '__main__': # 設定中文字體 matplotlib.rc('font', family='Microsoft JhengHei') # 將資料存入excel with pd.ExcelWriter('stock.xlsx') as file: # 設定日期 year = 0 while year < 1998 or year > 2024: # 防呆 year = int(input('請輸入年分(西元):')) month = 0 if year == 2024: while month < 1 or month > 5: month = int(input('請輸入月份:')) else: while month < 1 or month > 12: month = int(input('請輸入月份:')) if month < 10: month_s = '0' + str(month) date = str(year) + month_s + '01' # 使用者輸入證券代碼 while 1: stock = input('請輸入有價證券代號(結束搜尋請輸入\"0\"): ') if stock == '0': break # 取得網址 url = 'https://www.twse.com.tw/rwd/zh/afterTrading/STOCK_DAY_AVG?date='+ date +'&stockNo='+ stock + '&response=json&_=1717048389165' html = requests.get(url) # 直接取得json檔 stock_json = html.json() df = pd.DataFrame(stock_json['data']) # 轉為DataFrame df = df.rename(columns = {0: '日期', 1:'收盤價'}) # 設定column名稱 #print(df) # 寫入excel、設定分頁 df.to_excel(file, sheet_name = stock_json['title']) print('已搜尋:' + stock_json['title']) # 從excel取得所有分頁資料 df = pd.read_excel('stock.xlsx', sheet_name=None) # 資料分類放進dictionary stock_dic = {} for i in df.keys(): stock_dic[i] = {} for j in range(len(df[i]) - 1): #最後一筆資料是月平均,過濾掉 tmp = df[i]['日期'][j][-2:] # 精簡日期格式,只留下'日' if df[i]['收盤價'][j] == '--': # 當日沒有交易資料 k = 1 while df[i]['收盤價'][j-k] == '--': # 改存 有資料的上一筆資料 k = k + 1 stock_dic[i][tmp] = float(df[i]['收盤價'][j-k]) else: stock_dic[i][tmp] = float(df[i]['收盤價'][j]) #print(stock_dic[i]) stock_date = '' # 折線設定 line = ['-', '--', '-.', ':'] color = ['r', 'g', 'b', 'k', 'y', 'm', 'c'] k = 0 l = 0 # 畫圖 for i in stock_dic: # 篩選資料 x = [key for key in stock_dic[i].keys()] y = [value for value in stock_dic[i].values()] # 標題精簡 s_lst = i.split(' ') # 字串分割 stock_date = s_lst[0] # 日期(年月) plt.plot(x, y, color[k] + line[l], label = s_lst[1] + s_lst[2]) #畫圖 k = k + 1 if k > 6: k = 0 l = l + 1 if l > 3: l = 0 # 其他圖表設定 plt.title('股票市場趨勢', fontsize = 16) plt.xlabel(stock_date, fontsize = 12) plt.ylabel('收盤價', fontsize = 12) plt.legend(loc = 0) plt.show() ``` # 天氣預報 ![image](https://hackmd.io/_uploads/HJmbXzO4C.png) ## 直接寫 ```python= # -*- coding: utf-8 -*- """ Created on Sat Jun 1 10:20:36 2024 @author: liquorem """ import requests import matplotlib # 把圖表寫進視窗 matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure # 視窗功能 from tkinter import * import tkinter as tk # 時間套件 from datetime import date # 設定中文字體 matplotlib.rc('font', family='Microsoft JhengHei') # 獲得今日日期 today = str(date.today()) # 資料來源:中央氣象署開放資料平臺之資料擷取API url = 'https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-D0047-091?Authorization=CWA-ACB674BF-A2DC-49F0-9DDA-47425C068ECD' data = requests.get(url) # 取得 JSON 檔案的內容為文字 data_json = data.json() # 設置視窗 root = Tk() root.title("一周天氣預報") # 圖表區域設置 f = Figure(figsize=(10, 6), dpi=100) # 設定子圖 tem_plot = f.add_subplot(111) # 獲取縣市序號 def getLocIndex(target): for i in range(22): if target == location[i]: return i # 篩選平均溫度資料 def getAvgTem(target): weekly_T = {} i = getLocIndex(target) # 取得縣市代號 k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"]) for j in range(long): # 篩選出白日的資料 if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 回傳資料 # 篩選最低溫度資料 def getMinTem(target): weekly_T = {} i = getLocIndex(target) k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"]) for j in range(long): if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 篩選最高溫度資料 def getMaxTem(target): weekly_T = {} i = getLocIndex(target) k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"]) for j in range(long): if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 獲得明日天氣狀況 def getWeather(target): i = getLocIndex(target) long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"]) for j in range(long): # 取得"今天"下一個資料 if today in data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j]["startTime"]: if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j+1]["startTime"]: return data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j+1]["elementValue"][0]["value"] # 接收視窗資訊後的行動 def show(*e): target = value.get() weather.set('明天天氣狀況:' + getWeather(target)) # 替換標籤 tem_plot.clear() # 清除上一次的圖 # 平均溫度 weekly_T_avg = getAvgTem(target) avg_x = [weekly_T_avg[key]['time'] for key in range(len(weekly_T_avg))] avg_y = [weekly_T_avg[key]['temper'] for key in range(len(weekly_T_avg))] tem_plot.plot(avg_x, avg_y, 'r-*', label = '平均溫度') # 最低溫 weekly_T_min = getMinTem(target) min_x = [weekly_T_min[key]['time'] for key in range(len(weekly_T_min))] min_y = [weekly_T_min[key]['temper'] for key in range(len(weekly_T_min))] tem_plot.plot(min_x, min_y, 'g--^', label = '最低溫度') # 最高溫 weekly_T_max = getMaxTem(target) max_x = [weekly_T_max[key]['time'] for key in range(len(weekly_T_max))] max_y = [weekly_T_max[key]['temper'] for key in range(len(weekly_T_max))] tem_plot.plot(max_x, max_y, 'b:+', label = '最高溫度') # 其他圖表設定 tem_plot.set_xlabel('時間') tem_plot.set_ylabel('溫度') tem_plot.legend(loc = 0) tem_plot.set_title('白日溫度') # 畫圖 canvs.draw() # 下拉式選單 place = tk.StringVar() place.set('') location = ['新竹縣', '金門縣', '苗栗縣', '新北市', '宜蘭縣', '雲林縣', '臺南市', '高雄市', '彰化縣', '臺北市', '南投縣', '澎湖縣', '基隆市', '桃園市', '花蓮縣', '連江縣', '臺東縣', '嘉義市', '嘉義縣', '屏東縣', '臺中市', '新竹市'] value = tk.StringVar() value.set('') menu = tk.OptionMenu(root, value, *location) # 選單 menu.config(width=20, fg='#f00') # 設定樣式 menu.grid(column=3, row=0) # 排版 # 顯示按鈕 button = tk.Button(root, text='顯示', command=show) button.grid(column=4, row=0) # 天氣現象顯示 weather = tk.StringVar() # 建立文字變數 weather.set('') # 設定內容 weatherlabel = tk.Label(root, textvariable=weather, font=('Arial',20)) # 內容是 weather 變數 weatherlabel.grid(column=3, row=1, columnspan=3) # 視窗裡顯示圖表 canvs = FigureCanvasTkAgg(f, root) canvs.get_tk_widget().grid(column=0, row=2, columnspan=8) root.mainloop() ``` ## if \_\_name__ == "\_\_main__": ``` python= # -*- coding: utf-8 -*- """ Created on Sat Jun 1 10:20:36 2024 @author: liquorem """ import requests import matplotlib # 把圖表寫進視窗 matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure # 視窗功能 from tkinter import * import tkinter as tk # 時間套件 from datetime import date if __name__ == "__main__": # 設定中文字體 matplotlib.rc('font', family='Microsoft JhengHei') # 獲得今日日期 today = str(date.today()) # 資料來源:中央氣象署開放資料平臺之資料擷取API url = 'https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-D0047-091?Authorization=CWA-ACB674BF-A2DC-49F0-9DDA-47425C068ECD' data = requests.get(url) # 取得 JSON 檔案的內容為文字 data_json = data.json() # 設置視窗 root = Tk() root.title("一周天氣預報") # 圖表區域設置 f = Figure(figsize=(10, 6), dpi=100) # 設定子圖 tem_plot = f.add_subplot(111) # 獲取縣市序號 def getLocIndex(target): for i in range(22): if target == location[i]: return i # 篩選平均溫度資料 def getAvgTem(target): weekly_T = {} i = getLocIndex(target) # 取得縣市代號 k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"]) for j in range(long): # 篩選出白日的資料 if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][1]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 回傳資料 # 篩選最低溫度資料 def getMinTem(target): weekly_T = {} i = getLocIndex(target) k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"]) for j in range(long): if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][8]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 篩選最高溫度資料 def getMaxTem(target): weekly_T = {} i = getLocIndex(target) k = 0 long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"]) for j in range(long): if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["startTime"]: weekly_T[k] = {} weekly_T[k]["time"] = data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["startTime"][5:11] # 同時精簡時間格式 weekly_T[k]["temper"] = int(data_json["records"]["locations"][0]["location"][i]["weatherElement"][12]["time"][j]["elementValue"][0]["value"]) # 白天06:00-18:00的預測氣溫 k = k + 1 return weekly_T # 獲得明日天氣狀況 def getWeather(target): i = getLocIndex(target) long = len(data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"]) for j in range(long): # 取得"今天"下一個資料 if today in data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j]["startTime"]: if "06:00" in data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j+1]["startTime"]: return data_json["records"]["locations"][0]["location"][i]["weatherElement"][6]["time"][j+1]["elementValue"][0]["value"] # 接收視窗資訊後的行動 def show(*e): target = value.get() weather.set('明天天氣狀況:' + getWeather(target)) # 替換標籤 tem_plot.clear() # 清除上一次的圖 # 平均溫度 weekly_T_avg = getAvgTem(target) avg_x = [weekly_T_avg[key]['time'] for key in range(len(weekly_T_avg))] avg_y = [weekly_T_avg[key]['temper'] for key in range(len(weekly_T_avg))] tem_plot.plot(avg_x, avg_y, 'r-*', label = '平均溫度') # 最低溫 weekly_T_min = getMinTem(target) min_x = [weekly_T_min[key]['time'] for key in range(len(weekly_T_min))] min_y = [weekly_T_min[key]['temper'] for key in range(len(weekly_T_min))] tem_plot.plot(min_x, min_y, 'g--^', label = '最低溫度') # 最高溫 weekly_T_max = getMaxTem(target) max_x = [weekly_T_max[key]['time'] for key in range(len(weekly_T_max))] max_y = [weekly_T_max[key]['temper'] for key in range(len(weekly_T_max))] tem_plot.plot(max_x, max_y, 'b:+', label = '最高溫度') # 其他圖表設定 tem_plot.set_xlabel('時間') tem_plot.set_ylabel('溫度') tem_plot.legend(loc = 0) tem_plot.set_title('白日溫度') # 畫圖 canvs.draw() # 下拉式選單 place = tk.StringVar() place.set('') location = ['新竹縣', '金門縣', '苗栗縣', '新北市', '宜蘭縣', '雲林縣', '臺南市', '高雄市', '彰化縣', '臺北市', '南投縣', '澎湖縣', '基隆市', '桃園市', '花蓮縣', '連江縣', '臺東縣', '嘉義市', '嘉義縣', '屏東縣', '臺中市', '新竹市'] value = tk.StringVar() value.set('') menu = tk.OptionMenu(root, value, *location) # 選單 menu.config(width=20, fg='#f00') # 設定樣式 menu.grid(column=3, row=0) # 排版 # 顯示按鈕 button = tk.Button(root, text='顯示', command=show) button.grid(column=4, row=0) # 天氣現象顯示 weather = tk.StringVar() # 建立文字變數 weather.set('') # 設定內容 weatherlabel = tk.Label(root, textvariable=weather, font=('Arial',20)) # 內容是 weather 變數 weatherlabel.grid(column=3, row=1, columnspan=3) # 視窗裡顯示圖表 canvs = FigureCanvasTkAgg(f, root) canvs.get_tk_widget().grid(column=0, row=2, columnspan=8) root.mainloop() ```