Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【課題3】タイピングゲームと分割ダウンローダー #31

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

kz23szk
Copy link

@kz23szk kz23szk commented Sep 21, 2019

課題3

1.タイピングゲームを作ろう

  • 標準出力に英単語を出す(出すものは自由)
  • 標準入力から1行受け取る
  • 制限時間内に何問解けたか表示する

2.分割ダウンローダを作ろう

  • Rangeアクセスを用いる
  • いくつかのゴルーチンでダウンロードしてマージする
  • エラー処理を工夫する
  • golang.org/x/sync/errgourpパッケージなどを使ってみる
  • キャンセルが発生した場合の実装を行う

@kz23szk kz23szk added the kadai3 label Sep 21, 2019
@kz23szk kz23szk self-assigned this Sep 21, 2019
@kz23szk kz23szk added kadai3-1 kadai3-2 分割ダウンローダー and removed kadai3 labels Sep 23, 2019
errgroup "golang.org/x/sync/errgroup"
)

var COUNT = 4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

定数であれば、constで先頭を大文字にするとパッケージ外に公開されます


func main() {

url := "https://misc.laboradian.com/test/003"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const?

header, err := HeaderInfo(url)

if err != nil {
fmt.Println(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラーであれば、os.Stderrに出して、os.Exit(1)とかで終了する

}

func HeaderInfo(url string) (map[string][]string, error) {
req, _ := http.NewRequest("HEAD", "https://misc.laboradian.com/test/003/", nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラー処理

func HeaderInfo(url string) (map[string][]string, error) {
req, _ := http.NewRequest("HEAD", "https://misc.laboradian.com/test/003/", nil)

client := new(http.Client)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この用途ならhttp.DefaultClientで十分。

defer resp.Body.Close()

if err != nil {
fmt.Printf("ioutil err: %v", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラーの表示も立派なエラーハンドリングなので、2重にハンドリングしない。
表示するなら表示する、returnするならreturnする。

return resp.Header, nil
}

func canRangeAccess(header map[string][]string) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http.Headerを使った方が良さそう

func canRangeAccess(header map[string][]string) bool {
v, ok := header["Accept-Ranges"]

if ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

早めにreturnしたほうがよい


func Download(url, byteRange string) error {

req, _ := http.NewRequest("GET", url, nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error処理


client := new(http.Client)
resp, err := client.Do(req)
// TODO: エラー処理する?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラー処理は必須です

_, fileName := path.Split(url)
fmt.Println(url, byteRange, fileName)

file, err := os.Create(path.Join("./tmp/", fileName+"_"+byteRange))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ファイルにpathパッケージは使わない。filepathを使う。
一時ファイルはioutilとかを使う https://golang.org/pkg/io/ioutil/#TempDir

}
_, err = io.Copy(file, resp.Body)
if closeErr := file.Close(); err == nil {
err = closeErr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そのままreturnしないのはなぜ?

}

func NthRange(length, parallel_num, n int) string {
bytes_per_file := length / parallel_num
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

識別子(変数名など)はスネークケースを使わない。キャメルケースを使う。

func NthRange(length, parallel_num, n int) string {
bytes_per_file := length / parallel_num
if n == 1 {
return "0-" + strconv.Itoa(bytes_per_file)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returnするならelseやelse if はいらない

if n == 1 {
return "0-" + strconv.Itoa(bytes_per_file)
} else if n < parallel_num {
return strconv.Itoa(bytes_per_file*(n-1)+1) + "-" + strconv.Itoa(bytes_per_file*n)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt.Sprintfを使ったほうがわかりやすそう

readBytes, err := ioutil.ReadAll(f)
writeBytes = append(writeBytes, readBytes)

if err := f.Close(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writeじゃないのでエラー処理は不要ではある。


fmt.Println(fileName)

err := ioutil.WriteFile(fileName, bytes.Join(writeBytes, emptyByte), 0644)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こうすると一気にメモリを消費するので、徐々に書き込むべき。


words, err := RegisterWords()
if err != nil {
fmt.Println("err")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

エラーメッセージは丁寧に書く。
os.Stderrに出す。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kadai3-1 kadai3-2 分割ダウンローダー
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants