diff --git a/kadai2/README.md b/kadai2/README.md new file mode 100644 index 00000000..61f2d72b --- /dev/null +++ b/kadai2/README.md @@ -0,0 +1,50 @@ +# 課題2 + +## 1. io.Readerとio.Writerについて調べてみよう + +### 標準パッケージでどのように使われているか +【io.Reader】 +* io.Readerは、入力処理の基本インターフェース +* `Read(p []byte) (n int, err error)` をもつインターフェース +* バイト列を読み出すインターフェース + +【io.Reader】 +* io.Writerは、出力処理の基本インターフェース +* `Write(p []byte) (n int, err error)` をもつインターフェース +* バイト列を書き出すインターフェース + +### io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる +* 様々な場面で出てくる入出力にio.Readerインターフェースに準拠しているため、汎用性に優れている。 +* Read関数を実装している型を抽象化して扱うことができる。ファイル、文字列、メモリのデータ、ネットワーク接続情報等。 +* 入力の値を明確に意識しなくても、シンプルに実装が可能。 + +[参考サイト](https://qiita.com/ktnyt/items/8ede94469ba8b1399b12) + +## 2. テストを書いてみよう + +### 1回目の課題のテストを作ってみて下さい +#### 課題要件 +* テストのしやすさを考えてリファクタリングしてみる +* テストのカバレッジを取ってみる +* テーブル駆動テストを行う +* テストヘルパーを作ってみる + +#### Usage +モジュール配下に移動 +`cd convert` + +テスト実行 +`go test -run ''` + +カバー内容を吐き出す +`go test -cover ./... -coverprofile=cover.out` + +go toolを用いてcover.htmlを作成する +`go tool cover -html=cover.out -o cover.html` + +cover.htmlを開く +`open cover.html` + +#### カバレッジ +current : coverage: 75.0% of statements + diff --git a/kadai2/convert/convert.go b/kadai2/convert/convert.go new file mode 100644 index 00000000..303f33aa --- /dev/null +++ b/kadai2/convert/convert.go @@ -0,0 +1,92 @@ +package convert + +import ( + "io/ioutil" + "path/filepath" + "os" + "image" + "image/jpeg" + "image/png" + "errors" +) + +// user defined type +type Conv struct { + From string + To string + Dir string +} + +// create Conv +func NewConv(from string, to string, dir string)(*Conv, error){ + return &Conv{from, to, dir}, nil +} + +// search directory +func (conv *Conv)FileSearch(dir string, from string)([]string, error){ + var paths []string + files, err := ioutil.ReadDir(dir) + if err != nil { + return nil, err + } + + for _, file := range files { + if file.IsDir() { + subpaths, err := conv.FileSearch(filepath.Join(dir, file.Name()), from) + paths = append(paths, subpaths...) + if err != nil { + return nil, err + } + continue + } + ext := filepath.Ext(file.Name()) + + if ext !="" && ext[1:] == from { + fullpath := filepath.Join(dir, file.Name()) + paths = append(paths, fullpath) + } + } + return paths, err +} + +// replace filepath +func (conv *Conv) Convert(path string, to string) (error) { + inputFile, err := os.Open(path) + if err != nil { + return err + } + defer inputFile.Close() + + img, _, err := image.Decode(inputFile) + if err != nil { + return err + } + + out_file, err := os.Create(path[:len(path)-len(filepath.Ext(path))+1] + to) + if err != nil { + return err + } + defer out_file.Close() + + switch to { + case "jpg", "jpeg" : + err := jpeg.Encode(out_file, img, &jpeg.Options{}) + if err != nil { + return err + } + case "png" : + err := png.Encode(out_file, img) + if err != nil { + return err + } + default: + errors.New("wrong after extension") + } + + err = os.Remove(path) + if err != nil { + return err + } + + return err +} diff --git a/kadai2/convert/convert_test.go b/kadai2/convert/convert_test.go new file mode 100644 index 00000000..285eab8e --- /dev/null +++ b/kadai2/convert/convert_test.go @@ -0,0 +1,66 @@ +package convert_test + +import ( + "testing" + "reflect" + "convert/convert" +) + +func TestFileSearch(t *testing.T) { + cases := []struct{ + name string + from string + dir string + output []string + }{ + {name : "jpeg, current_dir" , from : "jpeg", dir : "../test_images", output : []string{"../test_images/test_image1.jpeg", "../test_images/test_image2.jpeg","../test_images/test_subimages/test_image1.jpeg","../test_images/test_subimages/test_image2.jpeg"}}, + {name : "png, current_dir" , from : "png", dir : "../test_images", output : []string{"../test_images/test_image1.png", "../test_images/test_image2.png","../test_images/test_subimages/test_image1.png","../test_images/test_subimages/test_image2.png"}}, + {name : "jpeg, sub_dir" , from : "jpeg", dir : "../test_images/test_subimages", output : []string{"../test_images/test_subimages/test_image1.jpeg","../test_images/test_subimages/test_image2.jpeg"}}, + {name : "png, sub_dir" , from : "png", dir : "../test_images/test_subimages", output : []string{"../test_images/test_subimages/test_image1.png","../test_images/test_subimages/test_image2.png"}}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + conv := &convert.Conv{c.from, "", c.dir} + paths, err := conv.FileSearch(c.dir, c.from); + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(paths, c.output) { + t.Errorf("invalid result. testCase:%#v, actual:%v", c.output, paths) + } + }) + } +} + +func CheckErr(t *testing.T, err error) bool { + t.Helper() + if err !=nil { + t.Errorf("%s",err) + return true + } + return false +} + +func TestConvert (t *testing.T) { + cases := []struct{ + name string + path string + to string + output error + }{ + {name : "jpeg, png" , path : "../test_images/test_image1.jpeg", to : "png", output : nil}, + {name : "jpeg, png" , path : "../test_images/test_image2.jpeg", to : "png", output : nil}, + {name : "png, jpeg" , path : "../test_images/test_image1.png", to : "jpeg", output : nil}, + {name : "png, jpeg" , path : "../test_images/test_image2.png", to : "jpeg", output : nil}, + } + + conv := &convert.Conv{"", "", ""} + for _, c := range cases { + err := conv.Convert(c.path, c.to) + ch := CheckErr(t, err) + if !ch && err != c.output { + t.Errorf("invalid result. testCase:%#v, actual:%v", c.output, err) + } + } +} diff --git a/kadai2/go.mod b/kadai2/go.mod new file mode 100644 index 00000000..c2b01a1d --- /dev/null +++ b/kadai2/go.mod @@ -0,0 +1,3 @@ +module convert + +go 1.14 diff --git a/kadai2/go.sum b/kadai2/go.sum new file mode 100644 index 00000000..9b6bac85 --- /dev/null +++ b/kadai2/go.sum @@ -0,0 +1,29 @@ +github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/kadai2/main.go b/kadai2/main.go new file mode 100644 index 00000000..dd63693f --- /dev/null +++ b/kadai2/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "convert/convert" + "flag" + "fmt" +) + +// initialize flag +var ( + from = flag.String("from", "jpeg", "from extension") + to = flag.String("to", "png", "after extension") + directory = flag.String("directory", "images", "directory path") +) + +func init() { + flag.Usage = func() { + fmt.Printf(`Usage: -from FROM_FORMAT -to TO_FORMAT -dir DIRECTORY + Use: convert image files. + Default: from jpeg to png. + `) + flag.PrintDefaults() + } +} + +func main() { + flag.Parse() + + conv, err := convert.NewConv(*from, *to, *directory) + if err != nil { + fmt.Println(err) + } + + paths, err := conv.FileSearch(*directory, *from) + if err != nil { + fmt.Println(err) + } + for _, path := range paths { + err := conv.Convert(path, *to) + if err != nil { + fmt.Println(err) + } + } +} diff --git a/kadai2/test_images/test_image1.jpeg b/kadai2/test_images/test_image1.jpeg new file mode 100644 index 00000000..468e49b2 Binary files /dev/null and b/kadai2/test_images/test_image1.jpeg differ diff --git a/kadai2/test_images/test_image2.jpeg b/kadai2/test_images/test_image2.jpeg new file mode 100644 index 00000000..136ae006 Binary files /dev/null and b/kadai2/test_images/test_image2.jpeg differ diff --git a/kadai2/test_images/test_image3 b/kadai2/test_images/test_image3 new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_image3 differ diff --git a/kadai2/test_images/test_image3.tttt b/kadai2/test_images/test_image3.tttt new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_image3.tttt differ diff --git a/kadai2/test_images/test_subimages/test_image1.jpeg b/kadai2/test_images/test_subimages/test_image1.jpeg new file mode 100644 index 00000000..37d0c719 Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image1.jpeg differ diff --git a/kadai2/test_images/test_subimages/test_image1.png b/kadai2/test_images/test_subimages/test_image1.png new file mode 100644 index 00000000..37d0c719 Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image1.png differ diff --git a/kadai2/test_images/test_subimages/test_image2.jpeg b/kadai2/test_images/test_subimages/test_image2.jpeg new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image2.jpeg differ diff --git a/kadai2/test_images/test_subimages/test_image2.png b/kadai2/test_images/test_subimages/test_image2.png new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image2.png differ diff --git a/kadai2/test_images/test_subimages/test_image3 b/kadai2/test_images/test_subimages/test_image3 new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image3 differ diff --git a/kadai2/test_images/test_subimages/test_image3.tttt b/kadai2/test_images/test_subimages/test_image3.tttt new file mode 100644 index 00000000..18309acd Binary files /dev/null and b/kadai2/test_images/test_subimages/test_image3.tttt differ diff --git a/kadai3-1/README.md b/kadai3-1/README.md new file mode 100644 index 00000000..ef58808a --- /dev/null +++ b/kadai3-1/README.md @@ -0,0 +1,20 @@ +# 課題3-1 + +タイピングゲームを作ろう + +* 標準出力に英単語を出す(出すものは自由) +* 標準入力から1行受け取る +* 制限時間内に何問解けたか表示する + +ヒント +* 制限時間にはtime.After関数を用いる +(context.WithTimeoutでもよい) +* select構文を用いる +(制限時間と入力を同時に待つ) + +## Setup +* init `$ go install` +## Usage +* `go run main.go [-time time limit ] ` + + diff --git a/kadai3-1/go.mod b/kadai3-1/go.mod new file mode 100644 index 00000000..35b61a03 --- /dev/null +++ b/kadai3-1/go.mod @@ -0,0 +1,5 @@ +module typing + +go 1.14 + +require github.com/fatih/color v1.12.0 // indirect diff --git a/kadai3-1/go.sum b/kadai3-1/go.sum new file mode 100644 index 00000000..5cf2f07a --- /dev/null +++ b/kadai3-1/go.sum @@ -0,0 +1,9 @@ +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/kadai3-1/main.go b/kadai3-1/main.go new file mode 100644 index 00000000..ae83a4f2 --- /dev/null +++ b/kadai3-1/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "flag" + "fmt" + "typing/typing" + "github.com/fatih/color" + "time" +) + +// initialize flag +var ( + tim = flag.Int("time", 30, "time limit") +) + +func init() { + flag.Usage = func() { + fmt.Printf(`Usage: -time TIME LIMIT + Use: typing game (only English). + Default: time 30 seconds. + `) + flag.PrintDefaults() + } +} + +func main() { + flag.Parse() + tim := *tim + fmt.Printf("start typing game. time limit %d second\n", tim) + var score int + var judge = true + + timeout := time.After(time.Duration(tim) * time.Second) + now := time.Now() + for judge { + word := typing.RandomWord() + fmt.Printf("右の文字を入力せよ : %s \n", word) + c := typing.CreateChan(word) + select { + case res := <- c: + if word == res { + score++ + fmt.Printf("経過: %vs\n", int(time.Since(now).Seconds())%60) + } else { + color.Red("fail") + fmt.Printf("経過: %vs\n", int(time.Since(now).Seconds())%60) + } + case <- timeout: + fmt.Println("Time up") + fmt.Println("result score: ", score) + judge = false + } + } +} diff --git a/kadai3-1/typing/typing.go b/kadai3-1/typing/typing.go new file mode 100644 index 00000000..85c7e91b --- /dev/null +++ b/kadai3-1/typing/typing.go @@ -0,0 +1,37 @@ +package typing + +import ( + "math/rand" + "time" + "os" + "bufio" +) + +// Randomly extract word +func RandomWord() string { + words := []string { + "reason", + "secret", + "gimlet", + "escape", + "galaxy", + "breeze", + "beetle", + "allure", + "velvet", + } + + rand.Seed(time.Now().UnixNano()) + + return words[rand.Intn(len(words))] +} + +// Create Chan +func CreateChan(word string) <-chan string { + stdin := bufio.NewScanner(os.Stdin) + stdin.Scan() + text := stdin.Text() + c := make(chan string, 1) + c <- text + return c +}