2020年3月31日 星期二

使用EduBlocks用樍木式圖形化介面學習Python程式設計

許多人反應學習Python能用樍木式圖形化介面來學習嗎?答案是OK,網址為:https://app.edublocks.org/
1.啟動EduBlocks網站,選擇下方Start Creating按鈕。
2.選擇Python程式按鈕。

3.選擇右手邊的功能表選單。

 4.選擇Smaple功能表單

5.選擇Graph範例
 6.查看樍木式程式結構
7.執行結果
8.查看程式

2020年3月29日 星期日

圖形化編輯器學習Python, MicroPython, micro:bit

在2020年2月2日我們發表"沒有硬體但想學MicroPython怎麼辦?就用MicroPython on Unicorn!",今天我們來看看對於兒童學習程式設計,利用圖形化編輯器來培養兒童的邏輯思考能力。
(1)Micropython圖形化編輯器就是Python編輯器
在Python有一個分支,MicroPython或CirduitPython,可以把程式放到晶片中,透過軟硬體控制,可以更容易瞭解微控制器的運作。對於TPYBoard系列開發板而言,第一款Micropython圖形化編輯器就是Python編輯器,網址:http://www.tpyboard.com/pythoneditor/#
(2)微軟的MakeCode
微軟的MakeCode也提供許多工具,包括:模擬器、積木編輯器、以及Java編輯器。在模擬器方面有micro:bit、Circuit Playground Express等,網址:https://www.microsoft.com/zh-tw/makecode

以下是micro:bit可以用積木來控制micro:bit的模擬器,挺好玩的。
(3) EduBlocks
很容易地轉換積木到Python,網址:https://edublocks.org/
上圖的右下角有一個Start Creating按鈕,就可以看到它支援4種積木式程式設計,分別是:
(1) Python 3
(2) Raspberry Pi
(3) Micro:bit
(4) CircuitPython

https://microbit.org/code/ 網頁最下方還有許多工具喔!

2020年3月22日 星期日

使用Python,Dash和Plotly等技術將COVID-19案例數據視覺化

上圖是執行程式後,查詢台灣COVID-19案例數據視覺化的結果,此程式是使用PythonDash和Plotly等技術,以Flask網站來呈現視覺化的結果。

參考文章:Visualise COVID-19 case data using Python, Dash and Plotly
程式網址:https://github.com/ploner/coronavirus-py


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output
import pandas as pd

baseURL = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/"

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

tickFont = {'size':12, 'color':"rgb(30,30,30)", 'family':"Courier New, monospace"}

def loadData(fileName, columnName): 
    data = pd.read_csv(baseURL + fileName) \
             .drop(['Lat', 'Long'], axis=1) \
             .melt(id_vars=['Province/State', 'Country/Region'], var_name='date', value_name=columnName) \
             .fillna('<all>')
    data['date'] = data['date'].astype('datetime64[ns]')
    return data

allData = loadData("time_series_19-covid-Confirmed.csv", "CumConfirmed") \
    .merge(loadData("time_series_19-covid-Deaths.csv", "CumDeaths")) \
    .merge(loadData("time_series_19-covid-Recovered.csv", "CumRecovered"))

countries = allData['Country/Region'].unique()
countries.sort()

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    style={ 'font-family':"Courier New, monospace" },
    children=[
    html.H1('Case History of the Coronavirus (COVID-19)'),
    html.Div(className="row", children=[
        html.Div(className="four columns", children=[
            html.H5('Country'),
            dcc.Dropdown(
                id='country',
                options=[{'label':c, 'value':c} for c in countries],
                value='Italy'
            )
        ]),
        html.Div(className="four columns", children=[
            html.H5('State / Province'),
            dcc.Dropdown(
                id='state'
            )
        ]),
        html.Div(className="four columns", children=[
            html.H5('Selected Metrics'),
            dcc.Checklist(
                id='metrics',
                options=[{'label':m, 'value':m} for m in ['Confirmed', 'Deaths', 'Recovered']],
                value=['Confirmed', 'Deaths']
            )
        ])
    ]),
    dcc.Graph(
        id="plot_new_metrics",
        config={ 'displayModeBar': False }
    ),
    dcc.Graph(
        id="plot_cum_metrics",
        config={ 'displayModeBar': False }
    )
])

@app.callback(
    [Output('state', 'options'), Output('state', 'value')],
    [Input('country', 'value')]
)
def update_states(country):
    states = list(allData.loc[allData['Country/Region'] == country]['Province/State'].unique())
    states.insert(0, '<all>')
    states.sort()
    state_options = [{'label':s, 'value':s} for s in states]
    state_value = state_options[0]['value']
    return state_options, state_value

def nonreactive_data(country, state):
    data = allData.loc[allData['Country/Region'] == country]
    if state == '<all>':
        data = data.drop('Province/State', axis=1).groupby("date").sum().reset_index()
    else:
        data = data.loc[data['Province/State'] == state]
    newCases = data.select_dtypes(include='int64').diff().fillna(0)
    newCases.columns = [column.replace('Cum', 'New') for column in newCases.columns]
    data = data.join(newCases)
    data['dateStr'] = data['date'].dt.strftime('%b %d, %Y')
    return data

def barchart(data, metrics, prefix="", yaxisTitle=""):
    figure = go.Figure(data=[
        go.Bar( 
            name=metric, x=data.date, y=data[prefix + metric],
            marker_line_color='rgb(0,0,0)', marker_line_width=1,
            marker_color={ 'Deaths':'rgb(200,30,30)', 'Recovered':'rgb(30,200,30)', 'Confirmed':'rgb(100,140,240)'}[metric]
        ) for metric in metrics
    ])
    figure.update_layout( 
              barmode='group', legend=dict(x=.05, y=0.95, font={'size':15}, bgcolor='rgba(240,240,240,0.5)'), 
              plot_bgcolor='#FFFFFF', font=tickFont) \
          .update_xaxes( 
              title="", tickangle=-90, type='category', showgrid=True, gridcolor='#DDDDDD', 
              tickfont=tickFont, ticktext=data.dateStr, tickvals=data.date) \
          .update_yaxes(
              title=yaxisTitle, showgrid=True, gridcolor='#DDDDDD')
    return figure

@app.callback(
    Output('plot_new_metrics', 'figure'), 
    [Input('country', 'value'), Input('state', 'value'), Input('metrics', 'value')]
)
def update_plot_new_metrics(country, state, metrics):
    data = nonreactive_data(country, state)
    return barchart(data, metrics, prefix="New", yaxisTitle="New Cases per Day")

@app.callback(
    Output('plot_cum_metrics', 'figure'), 
    [Input('country', 'value'), Input('state', 'value'), Input('metrics', 'value')]
)
def update_plot_cum_metrics(country, state, metrics):
    data = nonreactive_data(country, state)
    return barchart(data, metrics, prefix="Cum", yaxisTitle="Cumulated Cases")

if __name__ == '__main__':
    app.run_server(debug=True)

程式解說:
程式第1-7行滙入所需要套件
程式第8行定義一個baseURL,數據位於約翰霍普金斯大學系統科學與工程中心(JHU / CSSE)的服務器上,讓我們可以按國家和地區下載冠狀病毒的病例數據。
程式第10行指定引用CSS的網址。
程式第12行設定字型等CSS樣式。
程式第14到20行定義函數loadData處理下載和一些基本轉換。
程式第22到24行載入案例數據含確診、死亡、康復等人數。
程式第26到27行過濾重複資料以及排序。
程式第29行建立儀錶板物件。
程式第31行到67行建立網頁的佈局
程式第69行到79行是回呼函式處理選擇國家時能列出各省的資訊。
程式第81行到91行是依照區域和省份等資訊列出COVID-19的資料。
程式第93行到109行是將資訊轉成條狀圖。
程式第111行到125行是回呼函式反應網站送來的資訊。
程式第127行到128行是主程式


兩行指令讀取COVID-19即時訊息


利用Python即時查詢COVID-19資訊,只需要兩行指令。一行是滙入Requests套件,另一行則是使用print函式來顯示出資訊,並呼叫reuests.get()函式,最後.text則是把從伺服器讀到的資料取出文件部份。

1.讀取最新結果:

1
2
import requests
print(requests.get('https://coronavirus-tracker-api.herokuapp.com/v2/latest').text)

執行結果:

2.查詢各地區的結果:

1
2
import requests
print(requests.get('https://coronavirus-tracker-api.herokuapp.com/v2/locations').text)

執行結果:

3.查詢某一地區


1
2
import requests
print(requests.get('https://coronavirus-tracker-api.herokuapp.com/v2/locations?country_code=US').text)

執行結果: