iTranslated by AI
Developing a Go Package to Retrieve Google COVID-19 Forecast Data for Japan
I spent some of my leisure time over the weekend creating a command-line tool to retrieve the Japanese version of Google COVID-19 Forecast data.
Since this itself is written in Go, it can also be used as a package. I have placed several code examples in the sample directory of the repository, so please refer to them.
For example:
// +build run
package main
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"os"
"github.com/spiegel-im-spiegel/cov19jpn/entity"
"github.com/spiegel-im-spiegel/cov19jpn/fetch"
"github.com/spiegel-im-spiegel/cov19jpn/filter"
"github.com/spiegel-im-spiegel/cov19jpn/values/prefcodejpn"
)
func main() {
r, err := fetch.Web(context.Background(), &http.Client{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer r.Close()
es, err := fetch.Import(
r,
filter.New(
prefcodejpn.TOTTORI,
prefcodejpn.SHIMANE,
prefcodejpn.OKAYAMA,
prefcodejpn.HIROSHIMA,
prefcodejpn.YAMAGUCHI,
),
)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
list := entity.NewList(es)
list.Sort()
_, _ = io.Copy(os.Stdout, bytes.NewReader(list.EncodeCSV()))
}
You can extract data for the five prefectures in the Chugoku region like this.
If you want to use a CSV file already downloaded locally:
r, err := fetch.Web(context.Background(), &http.Client{})
You can use the following instead:
r, err := fetch.File("./forecast_JAPAN_PREFECTURE_28.csv")
The result of the fetch.Import() function is returned as an array of structs defined as follows:
package entity
import (
"encoding/json"
"github.com/spiegel-im-spiegel/cov19jpn/values/date"
"github.com/spiegel-im-spiegel/cov19jpn/values/prefcodejpn"
)
type Entity struct {
JapanPrefectureCode prefcodejpn.Code `json:"japan_prefecture_code"`
PrefectureName string `json:"prefecture_name"`
TargetPredictionDate date.Date `json:"target_prediction_date"`
CumulativeConfirmed *json.Number `json:"cumulative_confirmed,omitempty"`
CumulativeConfirmedQ0025 *json.Number `json:"cumulative_confirmed_q0025,omitempty"`
CumulativeConfirmedQ0975 *json.Number `json:"cumulative_confirmed_q0975,omitempty"`
CumulativeDeaths *json.Number `json:"cumulative_deaths,omitempty"`
CumulativeDeathsQ0025 *json.Number `json:"cumulative_deaths_q0025,omitempty"`
CumulativeDeathsQ0975 *json.Number `json:"cumulative_deaths_q0975,omitempty"`
HospitalizedPatients *json.Number `json:"hospitalized_patients,omitempty"`
HospitalizedPatientsQ0025 *json.Number `json:"hospitalized_patients_q0025,omitempty"`
HospitalizedPatientsQ0975 *json.Number `json:"hospitalized_patients_q0975,omitempty"`
Recovered *json.Number `json:"recovered,omitempty"`
RecoveredQ0025 *json.Number `json:"recovered_q0025,omitempty"`
RecoveredQ0975 *json.Number `json:"recovered_q0975,omitempty"`
CumulativeConfirmedGroundTruth *json.Number `json:"cumulative_confirmed_ground_truth,omitempty"`
CumulativeDeathsGroundTruth *json.Number `json:"cumulative_deaths_ground_truth,omitempty"`
HospitalizedPatientsGroundTruth *json.Number `json:"hospitalized_patients_ground_truth,omitempty"`
RecoveredGroundTruth *json.Number `json:"recovered_ground_truth,omitempty"`
ForecastDate date.Date `json:"forecast_date"`
NewDeaths *json.Number `json:"new_deaths,omitempty"`
NewConfirmed *json.Number `json:"new_confirmed,omitempty"`
NewDeathsGroundTruth *json.Number `json:"new_deaths_ground_truth,omitempty"`
NewConfirmedGroundTruth *json.Number `json:"new_confirmed_ground_truth,omitempty"`
PrefectureNameKanji string `json:"prefecture_name_kanji,omitempty"`
}
Since it is returned as an array, you can encode it directly into JSON format. Also, by wrapping it into the entity.EntityList type using the entity.NewList() function, tasks like sorting, filtering data, and encoding to CSV become much easier.
Regarding bar charts:
// +build run
package main
import (
"context"
"fmt"
"net/http"
"os"
"github.com/spiegel-im-spiegel/cov19jpn/chart"
"github.com/spiegel-im-spiegel/cov19jpn/entity"
"github.com/spiegel-im-spiegel/cov19jpn/fetch"
"github.com/spiegel-im-spiegel/cov19jpn/filter"
"github.com/spiegel-im-spiegel/cov19jpn/values/prefcodejpn"
)
func main() {
r, err := fetch.Web(context.Background(), &http.Client{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer r.Close()
prefcode := prefcodejpn.TOKYO
es, err := fetch.Import(
r,
filter.New(prefcode),
)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
list := entity.NewList(es)
hlist := chart.New(list.StartDayMeasure(), list.EndDayMeasure().AddDay(7), 7, list)
if err := chart.MakeHistChart(hlist, prefcode.Title(), "./output.png"); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
Doing this will give you an output like this, which is the same as the command-line version:

Well, as for graphs, people have their own preferences, so this might not be very helpful. My design sense is catastrophic (haha).
Please feel free to use it if you like.
Reference Links
Discussion