From 139179ff13772fd8723e6b8a23c33704ead39cd0 Mon Sep 17 00:00:00 2001 From: marltake Date: Tue, 10 Sep 2019 00:22:34 +0900 Subject: [PATCH 1/7] add request --- kadai1/marltake/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 kadai1/marltake/README.md diff --git a/kadai1/marltake/README.md b/kadai1/marltake/README.md new file mode 100644 index 0000000..e72fb2f --- /dev/null +++ b/kadai1/marltake/README.md @@ -0,0 +1,14 @@ +# 課題1回答 +## 画像変換コマンド仕様 +* 指定されたディレクトリ以下の画像ファイルを再帰的に検索して処理する +* デフォルトはJPGファイルをPNGファイルに変換 +* オプションで変更前後の形式を指定可能 + * 前後のフォーマットが同じオプションは指定不可 + * 返還後のファイル名が存在する場合は、処理をskip + * -i 問い合わせる、-f 強制上書きとかできるかな +## 実装条件 +* mainパッケージと分離する +* 自作パッケージと標準パッケージと準標準パッケージのみ使う + * 準標準パッケージ:golang.org/x以下のパッケージ +* ユーザ定義型を作ってみる +* GoDocを生成してみる From 4a40fda67433d35bbbfc493c763dad5c212ed82a Mon Sep 17 00:00:00 2001 From: marltake Date: Tue, 10 Sep 2019 00:23:42 +0900 Subject: [PATCH 2/7] 1st work code --- kadai1/marltake/convert/convert.go | 73 ++++++++++++++++++++++++++++++ kadai1/marltake/main.go | 23 ++++++++++ 2 files changed, 96 insertions(+) create mode 100644 kadai1/marltake/convert/convert.go create mode 100644 kadai1/marltake/main.go diff --git a/kadai1/marltake/convert/convert.go b/kadai1/marltake/convert/convert.go new file mode 100644 index 0000000..b766c8b --- /dev/null +++ b/kadai1/marltake/convert/convert.go @@ -0,0 +1,73 @@ +package convert + +import ( + "image" + "image/gif" + "image/jpeg" + "image/png" + "os" + "path/filepath" + "strings" +) + +func ConfigConvert(src string, dest string) func(string, os.FileInfo, error) error { + srcExt := "." + src + lenSrcExt := len(srcExt) + destExt := "." + dest + // TODO declare decode for src and encode for dest here + return func(path string, info os.FileInfo, err error) error { + println(path) + if strings.ToLower(filepath.Ext(path)) == srcExt { + destPath := path[:len(path)-lenSrcExt] + destExt + // TODO error handling + if _, err := os.Stat(destPath); os.IsNotExist(err) { + file, _ := os.Open(path) + defer file.Close() + var img image.Image + switch src { + case "jpg": + img, _ = jpeg.Decode(file) + case "png": + img, _ = png.Decode(file) + case "gif": + img, _ = gif.Decode(file) + } + destfile, _ := os.Create(destPath) + defer destfile.Close() + switch dest { + case "jpg": + jpeg.Encode(destfile, img, nil) + case "png": + png.Encode(destfile, img) + case "gif": + gif.Encode(destfile, img, nil) + } + } else { + println("skip not to over write.", path) + } + } + return nil + } +} + +func ParseTarget(target string) (src string, dest string, ok bool) { + targets := strings.Split(target, ",") + allowedExt := map[string]bool{ + "jpg": true, + "png": true, + "gif": true, + } + if len(targets) != 2 { + return "", "", false + } + if targets[0] == "" { + targets[0] = "Jpg" + } + if targets[1] == "" { + targets[1] = "png" + } + if targets[0] != targets[1] && allowedExt[targets[0]] && allowedExt[targets[1]] { + return targets[0], targets[1], true + } + return "", "", false +} diff --git a/kadai1/marltake/main.go b/kadai1/marltake/main.go new file mode 100644 index 0000000..0888556 --- /dev/null +++ b/kadai1/marltake/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "flag" + "fmt" + "log" + "path/filepath" + + "./convert" +) + +func main() { + var target = flag.String("t", "jpg,png", "source and destination picture type") + flag.Parse() + src, dest, ok := convert.ParseTarget(*target) + if !ok { + log.Fatal(fmt.Errorf("Invalid target option %s", *target)) + } + err := filepath.Walk(flag.Arg(0), convert.ConfigConvert(src, dest)) + if err != nil { + log.Fatal(err) + } +} From d5694b55397857e9e3c4ac5a8e010d6582d67407 Mon Sep 17 00:00:00 2001 From: marltake Date: Tue, 10 Sep 2019 00:24:37 +0900 Subject: [PATCH 3/7] just return when using named return --- kadai1/marltake/convert/convert.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kadai1/marltake/convert/convert.go b/kadai1/marltake/convert/convert.go index b766c8b..b1e34ec 100644 --- a/kadai1/marltake/convert/convert.go +++ b/kadai1/marltake/convert/convert.go @@ -57,17 +57,23 @@ func ParseTarget(target string) (src string, dest string, ok bool) { "png": true, "gif": true, } + src, dest, ok = "", "", false if len(targets) != 2 { - return "", "", false + return } if targets[0] == "" { - targets[0] = "Jpg" + src = "jpg" + } else { + src = targets[0] } if targets[1] == "" { - targets[1] = "png" + dest = "png" + } else { + dest = targets[1] } - if targets[0] != targets[1] && allowedExt[targets[0]] && allowedExt[targets[1]] { - return targets[0], targets[1], true + if src != dest && allowedExt[src] && allowedExt[dest] { + ok = true + return } - return "", "", false + return } From c9a400a06036c60a6125d279156f7f4bea81dda6 Mon Sep 17 00:00:00 2001 From: marltake Date: Tue, 10 Sep 2019 00:25:36 +0900 Subject: [PATCH 4/7] use go module to remove relative import --- kadai1/marltake/go.mod | 3 +++ kadai1/marltake/main.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 kadai1/marltake/go.mod diff --git a/kadai1/marltake/go.mod b/kadai1/marltake/go.mod new file mode 100644 index 0000000..f3e50eb --- /dev/null +++ b/kadai1/marltake/go.mod @@ -0,0 +1,3 @@ +module marltake + +go 1.12 diff --git a/kadai1/marltake/main.go b/kadai1/marltake/main.go index 0888556..2447169 100644 --- a/kadai1/marltake/main.go +++ b/kadai1/marltake/main.go @@ -6,7 +6,7 @@ import ( "log" "path/filepath" - "./convert" + "marltake/convert" ) func main() { From 08fab566f6bbba347d7330be07298bc8afadb5a7 Mon Sep 17 00:00:00 2001 From: marltake Date: Wed, 18 Sep 2019 18:55:47 +0900 Subject: [PATCH 5/7] update kadai doc --- kadai1/marltake/README.md | 24 ++++++++++-------------- kadai1/marltake/doc/kadai1.md | 14 ++++++++++++++ kadai1/marltake/doc/kadai2.md | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 kadai1/marltake/doc/kadai1.md create mode 100644 kadai1/marltake/doc/kadai2.md diff --git a/kadai1/marltake/README.md b/kadai1/marltake/README.md index e72fb2f..42b7875 100644 --- a/kadai1/marltake/README.md +++ b/kadai1/marltake/README.md @@ -1,14 +1,10 @@ -# 課題1回答 -## 画像変換コマンド仕様 -* 指定されたディレクトリ以下の画像ファイルを再帰的に検索して処理する -* デフォルトはJPGファイルをPNGファイルに変換 -* オプションで変更前後の形式を指定可能 - * 前後のフォーマットが同じオプションは指定不可 - * 返還後のファイル名が存在する場合は、処理をskip - * -i 問い合わせる、-f 強制上書きとかできるかな -## 実装条件 -* mainパッケージと分離する -* 自作パッケージと標準パッケージと準標準パッケージのみ使う - * 準標準パッケージ:golang.org/x以下のパッケージ -* ユーザ定義型を作ってみる -* GoDocを生成してみる +# image format converter + +## usage + +`convert [-t [][,]] ` + +## description + + Search image files that's SRC_IMAGE_FORMAT type in TARGET_DIRECTORY recursively and convert to DEST_IMAGE_FORMAT type. + Default SRC_IMAGE_FORMAT is jpeg and default DEST_IMAGE_FORMAT is png. \ No newline at end of file diff --git a/kadai1/marltake/doc/kadai1.md b/kadai1/marltake/doc/kadai1.md new file mode 100644 index 0000000..e72fb2f --- /dev/null +++ b/kadai1/marltake/doc/kadai1.md @@ -0,0 +1,14 @@ +# 課題1回答 +## 画像変換コマンド仕様 +* 指定されたディレクトリ以下の画像ファイルを再帰的に検索して処理する +* デフォルトはJPGファイルをPNGファイルに変換 +* オプションで変更前後の形式を指定可能 + * 前後のフォーマットが同じオプションは指定不可 + * 返還後のファイル名が存在する場合は、処理をskip + * -i 問い合わせる、-f 強制上書きとかできるかな +## 実装条件 +* mainパッケージと分離する +* 自作パッケージと標準パッケージと準標準パッケージのみ使う + * 準標準パッケージ:golang.org/x以下のパッケージ +* ユーザ定義型を作ってみる +* GoDocを生成してみる diff --git a/kadai1/marltake/doc/kadai2.md b/kadai1/marltake/doc/kadai2.md new file mode 100644 index 0000000..8c9375c --- /dev/null +++ b/kadai1/marltake/doc/kadai2.md @@ -0,0 +1,15 @@ +# 課題2 + +## io.Readerとio.Writerについて調べる +* 標準パッケージでどのように使われているか +* io.Readerとio.Writerがあることで、どういう利点があるのか具体例を挙げて考えてみる + + File, メモリ上の配列、ネットワークインターフェースなど複数種類のデバイスを、データ読み取り可能なもの(Reader)、データ書き込み可能なもの(Writer)と抽象化して、デバイスの特性をケアすることなく、データ処理部分を記述すことが可能になる。 + buffio.NewReader(io.Reader)では単純なReaderをwrapして、複数種類の読み出し方法を提供している。 + +## 1回目の宿題のテストを作る +* テストのしやすさを考えてリファクタリングしてみる +* テストのカバレッジを取ってみる slide 287 + * `go test -coverprofile=profile ./...` +* テーブル駆動テストを行う + サブテスト slide 284 +* テストヘルパーを作ってみる From 8587005cccdba106a2b8b330982ad115c4ea27ab Mon Sep 17 00:00:00 2001 From: marltake Date: Fri, 20 Sep 2019 09:05:44 +0900 Subject: [PATCH 6/7] add test --- kadai1/marltake/convert/convert_test.go | 44 +++++++++++++++++++++++++ kadai1/marltake/go.mod | 2 ++ 2 files changed, 46 insertions(+) create mode 100644 kadai1/marltake/convert/convert_test.go diff --git a/kadai1/marltake/convert/convert_test.go b/kadai1/marltake/convert/convert_test.go new file mode 100644 index 0000000..663e903 --- /dev/null +++ b/kadai1/marltake/convert/convert_test.go @@ -0,0 +1,44 @@ +package convert_test + +import ( + "marltake/convert" + "testing" + + "github.com/google/go-cmp/cmp" +) + +type result struct { + Src string + Dest string + Ok bool +} + +func TestParseTarget(t *testing.T) { + cases := []struct { + name string + input string + expected result + }{ + {name: "default", input: "", expected: result{"jpg", "png", true}}, + {name: "default_dest", input: "jpg", expected: result{"jpg", "png", true}}, + {name: "default_src", input: ",png", expected: result{"jpg", "png", true}}, + {name: "jpg to png", input: "jpg,png", expected: result{"jpg", "png", true}}, + {name: "jpg to gif", input: "jpg,gif", expected: result{"jpg", "gif", true}}, + {name: "png to jpg", input: "png,jpg", expected: result{"png", "jpg", true}}, + {name: "png to gif", input: "png,gif", expected: result{"png", "gif", true}}, + {name: "gif to jpg", input: "gif,jpg", expected: result{"gif", "jpg", true}}, + {name: "gif to png", input: "gif,png", expected: result{"gif", "png", true}}, + {name: "invalid dest", input: ",mp3", expected: result{"", "", false}}, + } + for _, c := range cases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + if src, dest, ok := convert.ParseTarget(c.input); !cmp.Equal(c.expected, result{src, dest, ok}) { + t.Errorf( + "want ParseTarget(%q) = %v, got %v", + c.input, c.expected, result{src, dest, ok}) + } + }) + } +} diff --git a/kadai1/marltake/go.mod b/kadai1/marltake/go.mod index f3e50eb..2d21aa4 100644 --- a/kadai1/marltake/go.mod +++ b/kadai1/marltake/go.mod @@ -1,3 +1,5 @@ module marltake go 1.12 + +require github.com/google/go-cmp v0.3.1 From 491afc2e795d2efcf19650906fb309cfae6a1057 Mon Sep 17 00:00:00 2001 From: marltake Date: Fri, 20 Sep 2019 09:23:58 +0900 Subject: [PATCH 7/7] fix default case --- kadai1/marltake/convert/convert.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/kadai1/marltake/convert/convert.go b/kadai1/marltake/convert/convert.go index b1e34ec..aff8194 100644 --- a/kadai1/marltake/convert/convert.go +++ b/kadai1/marltake/convert/convert.go @@ -50,6 +50,7 @@ func ConfigConvert(src string, dest string) func(string, os.FileInfo, error) err } } +// ParseTarget parse and validate target image type option func ParseTarget(target string) (src string, dest string, ok bool) { targets := strings.Split(target, ",") allowedExt := map[string]bool{ @@ -58,22 +59,23 @@ func ParseTarget(target string) (src string, dest string, ok bool) { "gif": true, } src, dest, ok = "", "", false - if len(targets) != 2 { + if len(targets) == 0 { + src, dest = "jpg", "png" + } else if len(targets) == 1 { + src, dest = targets[0], "png" + } else if len(targets) == 2 { + src, dest = targets[0], targets[1] + } else { return } - if targets[0] == "" { + if src == "" { src = "jpg" - } else { - src = targets[0] } - if targets[1] == "" { + if dest == "" { dest = "png" - } else { - dest = targets[1] } - if src != dest && allowedExt[src] && allowedExt[dest] { - ok = true - return + if ok = src != dest && allowedExt[src] && allowedExt[dest]; !ok { + src, dest = "", "" } return }