From ad92e9f49f028b1a6d46b76f58ea00ade6b683ad Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Sat, 21 Sep 2019 15:02:47 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=E6=99=82=E9=96=93=E5=88=B6=E9=99=90?= =?UTF-8?q?=E3=81=AE=E3=81=BFgorutine=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kadai3/su-san/typing-game/main.go | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 kadai3/su-san/typing-game/main.go diff --git a/kadai3/su-san/typing-game/main.go b/kadai3/su-san/typing-game/main.go new file mode 100644 index 0000000..b9fb9cf --- /dev/null +++ b/kadai3/su-san/typing-game/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "bufio" + "context" + "fmt" + "math/rand" + "os" + "time" +) + +func main() { + + var counter int + + words, err := RegisterWords() + if err != nil { + fmt.Println("err") + } + + wordNum := len(words) + rand.Seed(time.Now().UnixNano()) + + scanner := bufio.NewScanner(os.Stdin) + // answer := make(chan string) + var displayWord string + go func() { + for { + displayWord = words[rand.Intn(wordNum)] + fmt.Print(displayWord, " : ") + scanner.Scan() + if scanner.Text() == displayWord { + counter += 1 + fmt.Println("o") + } else { + fmt.Println("x") + } + } + }() + + bc := context.Background() + t := 10 * time.Second + ctx, cancel := context.WithTimeout(bc, t) + defer cancel() + + select { + case <-time.After(4 * time.Second): + fmt.Println("\ntime up!\nscore :", counter) + case <-ctx.Done(): + fmt.Println(ctx.Err()) + } + +} + +func RegisterWords() ([]string, error) { + f, err := os.Open("list.csv") + if err != nil { + return nil, err + } + + var words []string + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + words = append(words, scanner.Text()) + } + err = f.Close() + return words, err +} From 23f9f1a383dccbecc9b8f5b84ab33622b2b3bb71 Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Sat, 21 Sep 2019 19:05:02 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=E3=81=A9=E3=81=A1=E3=82=89=E3=82=82?= =?UTF-8?q?=E5=90=8C=E3=81=98select=E3=81=A7=E6=8D=95=E6=8D=89=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kadai3/su-san/typing-game/main.go | 55 +++++++++++++++++++------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/kadai3/su-san/typing-game/main.go b/kadai3/su-san/typing-game/main.go index b9fb9cf..4254882 100644 --- a/kadai3/su-san/typing-game/main.go +++ b/kadai3/su-san/typing-game/main.go @@ -4,6 +4,7 @@ import ( "bufio" "context" "fmt" + "io" "math/rand" "os" "time" @@ -12,6 +13,7 @@ import ( func main() { var counter int + ch := input(os.Stdin) words, err := RegisterWords() if err != nil { @@ -21,35 +23,34 @@ func main() { wordNum := len(words) rand.Seed(time.Now().UnixNano()) - scanner := bufio.NewScanner(os.Stdin) - // answer := make(chan string) var displayWord string - go func() { - for { - displayWord = words[rand.Intn(wordNum)] - fmt.Print(displayWord, " : ") - scanner.Scan() - if scanner.Text() == displayWord { - counter += 1 - fmt.Println("o") - } else { - fmt.Println("x") - } - } - }() + + displayWord = words[rand.Intn(wordNum)] + fmt.Print(displayWord, " : ") bc := context.Background() t := 10 * time.Second ctx, cancel := context.WithTimeout(bc, t) defer cancel() - select { - case <-time.After(4 * time.Second): - fmt.Println("\ntime up!\nscore :", counter) - case <-ctx.Done(): - fmt.Println(ctx.Err()) + for { + select { + case v := <-ch: + fmt.Println(v, "come") + if v == displayWord { + counter += 1 + fmt.Println("o") + } else { + fmt.Println("x") + } + displayWord = words[rand.Intn(wordNum)] + fmt.Print(displayWord, " : ") + case <-ctx.Done(): + fmt.Println("\ntime up!\nscore :", counter) + goto finish + } } - + finish: } func RegisterWords() ([]string, error) { @@ -67,3 +68,15 @@ func RegisterWords() ([]string, error) { err = f.Close() return words, err } + +func input(r io.Reader) chan string { + c := make(chan string) + go func() { + s := bufio.NewScanner(r) + for s.Scan() { + c <- s.Text() + } + close(c) + }() + return c +} From 1e35535dfb84622a9fa6be336de5a348bc97cace Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Sat, 21 Sep 2019 19:25:09 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF?= =?UTF-8?q?=E3=83=88=E3=83=AA=E5=90=8D=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kadai3/su-san/typing_game/.DS_Store | Bin 0 -> 6148 bytes kadai3/su-san/typing_game/list.csv | 5 ++ kadai3/su-san/typing_game/main.go | 82 ++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 kadai3/su-san/typing_game/.DS_Store create mode 100644 kadai3/su-san/typing_game/list.csv create mode 100644 kadai3/su-san/typing_game/main.go diff --git a/kadai3/su-san/typing_game/.DS_Store b/kadai3/su-san/typing_game/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fcf107287bf8b86475a4bfafb6c4a1e7d1076756 GIT binary patch literal 6148 zcmeHKJx>Bb5Pgdj7#m8vh=uJ1A<=|rfmnNdsA$9s+!?jHpYEI4g-Fnj7(!-} z**7~oGkg2?a(fHFwTp2Jr~{}`1uKVaei0cL-H=M~2s*8Cff#*EFvt5wv^jQ>0ol6~ z+~NjZT;b>bO)=t5#^_;+1#((tC}0w>^vDs4^QlCi>cSPn`E>fD5SIijJ^FMwotbsQ z%r4weoX$>vq~UOhM{A7%V_=t86qxhJrLVqL%F$q|Dq=#ZZ0!o85#=yTa@C}YpQl|g_ literal 0 HcmV?d00001 diff --git a/kadai3/su-san/typing_game/list.csv b/kadai3/su-san/typing_game/list.csv new file mode 100644 index 0000000..fb9fd32 --- /dev/null +++ b/kadai3/su-san/typing_game/list.csv @@ -0,0 +1,5 @@ +apple +orange +wood +tree +flower diff --git a/kadai3/su-san/typing_game/main.go b/kadai3/su-san/typing_game/main.go new file mode 100644 index 0000000..4254882 --- /dev/null +++ b/kadai3/su-san/typing_game/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "bufio" + "context" + "fmt" + "io" + "math/rand" + "os" + "time" +) + +func main() { + + var counter int + ch := input(os.Stdin) + + words, err := RegisterWords() + if err != nil { + fmt.Println("err") + } + + wordNum := len(words) + rand.Seed(time.Now().UnixNano()) + + var displayWord string + + displayWord = words[rand.Intn(wordNum)] + fmt.Print(displayWord, " : ") + + bc := context.Background() + t := 10 * time.Second + ctx, cancel := context.WithTimeout(bc, t) + defer cancel() + + for { + select { + case v := <-ch: + fmt.Println(v, "come") + if v == displayWord { + counter += 1 + fmt.Println("o") + } else { + fmt.Println("x") + } + displayWord = words[rand.Intn(wordNum)] + fmt.Print(displayWord, " : ") + case <-ctx.Done(): + fmt.Println("\ntime up!\nscore :", counter) + goto finish + } + } + finish: +} + +func RegisterWords() ([]string, error) { + f, err := os.Open("list.csv") + if err != nil { + return nil, err + } + + var words []string + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + words = append(words, scanner.Text()) + } + err = f.Close() + return words, err +} + +func input(r io.Reader) chan string { + c := make(chan string) + go func() { + s := bufio.NewScanner(r) + for s.Scan() { + c <- s.Text() + } + close(c) + }() + return c +} From 2b0864d594e8558a65d5b8ed7ef61649b41e2f60 Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Mon, 23 Sep 2019 20:49:33 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E5=88=86=E5=89=B2=E3=83=80=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=AD=E3=83=BC=E3=83=89=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spread_downloader/cmd/spget/main.go | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 kadai3/su-san/spread_downloader/cmd/spget/main.go diff --git a/kadai3/su-san/spread_downloader/cmd/spget/main.go b/kadai3/su-san/spread_downloader/cmd/spget/main.go new file mode 100644 index 0000000..dc6211c --- /dev/null +++ b/kadai3/su-san/spread_downloader/cmd/spget/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" + "path" + "strconv" +) + +var COUNT = 4 + +func main() { + //req, _ := http.NewRequest("GET", "https://misc.laboradian.com/test/003/", nil) + + url := "https://misc.laboradian.com/test/003/" + + header, err := HeaderInfo(url) + + if err != nil { + fmt.Println(err) + } + + var byteRanges []string + if canRangeAccess(header) { + // 分割ダウンロードする + byte_num, err := strconv.Atoi(header["Content-Length"][0]) + if err != nil { + fmt.Println("normal download") + return + } + byteRanges = ByteRanges(byte_num, 2) + } else { + fmt.Println("normal download") + // TODO: 分岐として通常ダウンロード処理を入れる(やるかどうかY/nで聞いてから?) + return + } + + // TODO: tmpディレクトリ作成 + + for _, range_suffix := range byteRanges { + // 分割ダウンロードする + Download(url, range_suffix) + } +} + +func HeaderInfo(url string) (map[string][]string, error) { + req, _ := http.NewRequest("HEAD", "https://misc.laboradian.com/test/003/", nil) + + client := new(http.Client) + resp, err := client.Do(req) + defer resp.Body.Close() + + if err != nil { + fmt.Printf("ioutil err: %v", err) + return nil, err + } + + // fmt.Println(resp.Header) + return resp.Header, nil +} + +func canRangeAccess(header map[string][]string) bool { + v, ok := header["Accept-Ranges"] + + if ok { + for _, val := range v { + if val == "bytes" { + if _, ok := header["Content-Length"]; ok { + return true + } + } + } + } + return false +} + +func Download(url, byteRanges string) error { + //fmt.Println(url, byteRanges) + + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("Range", "bytes="+byteRanges) + + client := new(http.Client) + resp, err := client.Do(req) + // TODO: エラー処理する? + defer resp.Body.Close() + + _, fileName := path.Split(url) + + file, err := os.Create(path.Join("./tmp/", fileName, byteRanges)) + if err != nil { + return err + } + _, err = io.Copy(file, resp.Body) + if closeErr := file.Close(); err == nil { + err = closeErr + } + + return err +} + +// ByteRanges は分割したバイト範囲を返す関数です +// ex) 100 で 2分割 0-50, 51-100 +func ByteRanges(length int, parallel_num int) []string { + var byteRanges []string + + for i := 1; i < parallel_num+1; i++ { + byteRanges = append(byteRanges, NthRange(length, parallel_num, i)) + } + return byteRanges +} + +func NthRange(length, parallel_num, n int) string { + bytes_per_file := length / parallel_num + 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) + } else { + return strconv.Itoa(bytes_per_file*(n-1)+1) + "-" + strconv.Itoa(length) + } +} From 5f51030b4c1361e26bc0720f96330950aac4c49c Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Mon, 23 Sep 2019 22:13:40 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=E5=88=86=E5=89=B2=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E3=83=9E=E3=83=BC=E3=82=B8=E3=80=81?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=87=A6=E7=90=86=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spread_downloader/cmd/spget/main.go | 71 +++++++++++++++++-- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/kadai3/su-san/spread_downloader/cmd/spget/main.go b/kadai3/su-san/spread_downloader/cmd/spget/main.go index dc6211c..fa843d6 100644 --- a/kadai3/su-san/spread_downloader/cmd/spget/main.go +++ b/kadai3/su-san/spread_downloader/cmd/spget/main.go @@ -1,20 +1,23 @@ package main import ( + "bytes" "fmt" "io" + "io/ioutil" + "log" "net/http" "os" "path" "strconv" + errgroup "golang.org/x/sync/errgroup" ) var COUNT = 4 func main() { - //req, _ := http.NewRequest("GET", "https://misc.laboradian.com/test/003/", nil) - url := "https://misc.laboradian.com/test/003/" + url := "https://misc.laboradian.com/test/003" header, err := HeaderInfo(url) @@ -39,10 +42,34 @@ func main() { // TODO: tmpディレクトリ作成 + eg := errgroup.Group{} for _, range_suffix := range byteRanges { // 分割ダウンロードする - Download(url, range_suffix) + range_suffix := range_suffix + eg.Go(func() error { + return Download(url, range_suffix) + }) } + + if err = eg.Wait(); err != nil { + // TODO:標準エラー出力使う + log.Fatal(err) + return + } + + _, fileName := path.Split(url) + fmt.Println(fileName) + var filePaths []string + for _, suffix := range byteRanges{ + filePaths = append(filePaths, path.Join("./tmp/", fileName + "_" + suffix)) + } + // そろっていればtmpファイルを結合する + err = concatFiles(filePaths, "./" + fileName) + + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %v", err) + } + } func HeaderInfo(url string) (map[string][]string, error) { @@ -76,11 +103,11 @@ func canRangeAccess(header map[string][]string) bool { return false } -func Download(url, byteRanges string) error { - //fmt.Println(url, byteRanges) +func Download(url, byteRange string) error { + req, _ := http.NewRequest("GET", url, nil) - req.Header.Set("Range", "bytes="+byteRanges) + req.Header.Set("Range", "bytes="+byteRange) client := new(http.Client) resp, err := client.Do(req) @@ -88,8 +115,9 @@ func Download(url, byteRanges string) error { defer resp.Body.Close() _, fileName := path.Split(url) + fmt.Println(url, byteRange, fileName) - file, err := os.Create(path.Join("./tmp/", fileName, byteRanges)) + file, err := os.Create(path.Join("./tmp/", fileName + "_" + byteRange)) if err != nil { return err } @@ -122,3 +150,32 @@ func NthRange(length, parallel_num, n int) string { return strconv.Itoa(bytes_per_file*(n-1)+1) + "-" + strconv.Itoa(length) } } + + +func concatFiles(filePaths []string, fileName string)error{ + + var writeBytes [][]byte + + for _, path := range filePaths{ + f, err := os.Open(path) + if err != nil { + return err + } + + // 一気に全部読み取り + readBytes, err := ioutil.ReadAll(f) + writeBytes = append(writeBytes, readBytes) + + if err := f.Close(); err != nil { + return err + } + } + + emptyByte := []byte{} + + fmt.Println(fileName) + + err := ioutil.WriteFile(fileName, bytes.Join(writeBytes, emptyByte), 0644) + + return err +} \ No newline at end of file From 8cfc86c45b0d518c6d11ac900a389a87f677808e Mon Sep 17 00:00:00 2001 From: Kazufumi Suzuki Date: Mon, 23 Sep 2019 22:40:00 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=E5=88=86=E5=89=B2=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=8C=E3=81=82=E3=82=8B=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AF=E3=83=80=E3=82=A6=E3=83=B3=E3=83=AD=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=97=E3=81=AA=E3=81=84=EF=BC=88=E4=B8=AD=E6=96=AD=E5=87=A6?= =?UTF-8?q?=E7=90=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spread_downloader/cmd/spget/main.go | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/kadai3/su-san/spread_downloader/cmd/spget/main.go b/kadai3/su-san/spread_downloader/cmd/spget/main.go index fa843d6..72ea97a 100644 --- a/kadai3/su-san/spread_downloader/cmd/spget/main.go +++ b/kadai3/su-san/spread_downloader/cmd/spget/main.go @@ -5,11 +5,11 @@ import ( "fmt" "io" "io/ioutil" - "log" "net/http" "os" "path" "strconv" + errgroup "golang.org/x/sync/errgroup" ) @@ -47,24 +47,27 @@ func main() { // 分割ダウンロードする range_suffix := range_suffix eg.Go(func() error { + if downloadedFile(url, range_suffix) { + return nil + } return Download(url, range_suffix) }) } if err = eg.Wait(); err != nil { // TODO:標準エラー出力使う - log.Fatal(err) + fmt.Fprintf(os.Stderr, "ERROR: %v", err) return } _, fileName := path.Split(url) fmt.Println(fileName) var filePaths []string - for _, suffix := range byteRanges{ - filePaths = append(filePaths, path.Join("./tmp/", fileName + "_" + suffix)) + for _, suffix := range byteRanges { + filePaths = append(filePaths, path.Join("./tmp/", fileName+"_"+suffix)) } // そろっていればtmpファイルを結合する - err = concatFiles(filePaths, "./" + fileName) + err = concatFiles(filePaths, "./"+fileName) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v", err) @@ -103,8 +106,13 @@ func canRangeAccess(header map[string][]string) bool { return false } -func Download(url, byteRange string) error { +func downloadedFile(url, suffix string) bool { + _, fileName := path.Split(url) + _, err := os.Stat(path.Join("./tmp/", fileName+"_"+suffix)) + return err == nil +} +func Download(url, byteRange string) error { req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Range", "bytes="+byteRange) @@ -117,7 +125,7 @@ func Download(url, byteRange string) error { _, fileName := path.Split(url) fmt.Println(url, byteRange, fileName) - file, err := os.Create(path.Join("./tmp/", fileName + "_" + byteRange)) + file, err := os.Create(path.Join("./tmp/", fileName+"_"+byteRange)) if err != nil { return err } @@ -151,12 +159,11 @@ func NthRange(length, parallel_num, n int) string { } } - -func concatFiles(filePaths []string, fileName string)error{ +func concatFiles(filePaths []string, fileName string) error { var writeBytes [][]byte - for _, path := range filePaths{ + for _, path := range filePaths { f, err := os.Open(path) if err != nil { return err @@ -178,4 +185,4 @@ func concatFiles(filePaths []string, fileName string)error{ err := ioutil.WriteFile(fileName, bytes.Join(writeBytes, emptyByte), 0644) return err -} \ No newline at end of file +}