diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44636f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +kadai1/takata/takata +kadai1/takata/output/1.png +kadai1/takata/output/10.png +kadai1/takata/output/2.png +kadai1/takata/output/3.png +kadai1/takata/output/4.png +kadai1/takata/output/5.png +kadai1/takata/output/6.png +kadai1/takata/output/7.png +kadai1/takata/output/8.png +kadai1/takata/output/9.png +kadai2/takata/takata +kadai2/takata/output/1.png +kadai2/takata/output/10.png +kadai2/takata/output/2.png +kadai2/takata/output/3.png +kadai2/takata/output/4.png +kadai2/takata/output/5.png +kadai2/takata/output/6.png +kadai2/takata/output/7.png +kadai2/takata/output/8.png +kadai2/takata/output/9.png diff --git a/kadai1/takata/README.md b/kadai1/takata/README.md new file mode 100644 index 0000000..2f029e4 --- /dev/null +++ b/kadai1/takata/README.md @@ -0,0 +1,57 @@ +# Kadai1 + + +## 実行方法 + +``` +go build -o converter main.go +./converter -d test -sf jpg -df png + +または + +go run main.go -d test -sf jpg -df png + + +出力結果はoutputディレクトリに格納される +``` + + +## Options + +``` +-d 変換対象の画像が入ったディレクトリ(中にディレクトリを含めてもOK) + +-sf 変換前のフォーマット(jpg,jpeg,png,gifが指定可能) デフォルトはjpg + +-df 変換後のフォーマット(jpg,jpeg,png,gifが指定可能) デフォルトはpng + + +``` + +## 課題の回答 + +### ディレクトリを指定する +`flag.Args()`で受け取る値を対象のディレクトリとしました。 + +### ディレクトリ以下は再帰的に処理する +dirwalkメソッドの中でディレクトリの場合はさらにディレクトリ内のファイルを探すようにしました。 + + +### 指定したディレクトリ以下のJPGファイルをPNGに変換 + +オプションを指定しなかった場合、デフォルトでjpgファイルをpngファイルに変換するようにしました。 + +### mainパッケージと分離する +画像変換処理をconvertパッケージに格納し、mainパッケージへimportして呼び出すようにしました。 + + +### ユーザ定義型を作ってみる +Fileタイプを作成しました。ファイル名と変換元のファイル形式、変換後のファイル形式を格納します。 + +### GoDocを生成してみる + +``` +godoc -http:3000 +``` + +で作成しました。 \ No newline at end of file diff --git a/kadai1/takata/convert/convert.go b/kadai1/takata/convert/convert.go new file mode 100644 index 0000000..cee3b68 --- /dev/null +++ b/kadai1/takata/convert/convert.go @@ -0,0 +1,167 @@ +/* +Package convert provides convert function +to some extension to other extension +*/ +package convert + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" +) + +// Convert images with srcFmt in dir to images with dstFmt +func Convert(dir string, srcFmt string, dstFmt string) { + + if !exists(dir) { + panic("ディレトリは存在しません") + } + + fInfo, _ := os.Stat(dir) + if !fInfo.IsDir() { + panic("ディレクトリを指定してください") + } + + files := dirwalk(dir, srcFmt, dstFmt) + + for _, file := range files { + convertImage(file) + } +} + +// find files with some extension in a directory recursively +func dirwalk(dir string, srcFmt string, dstFmt string) []FileInformation { + + files, err := ioutil.ReadDir(dir) + if err != nil { + panic(err) + } + + var paths []FileInformation + for _, file := range files { + if file.IsDir() { + paths = append(paths, dirwalk(filepath.Join(dir, file.Name()), srcFmt, dstFmt)...) + continue + } + name := file.Name() + pos := strings.LastIndex(name, ".") + 1 + if name[pos:] != srcFmt { + continue + } + + path := FileInformation{filepath.Join(dir, name[:pos-1]), srcFmt, dstFmt} + paths = append(paths, path) + } + return paths +} + +// convert file with some extension to file with other extension +func convertImage(src FileInformation) { + + if !isAvailableFormat(src.srcFmt) { + log.Fatal("指定した変換元の画像形式は無効です") + return + } + + if !isAvailableFormat(src.dstFmt) { + log.Fatal("指定した変換先の画像形式は無効です") + return + } + + startConvert(src) +} + +// Encode the targer image +func startConvert(src FileInformation) { + + file, err := os.Open(src.name + "." + src.srcFmt) + if err != nil { + log.Fatal(err) + return + } + defer file.Close() + + img, _, err := decode(file) + if err != nil { + log.Fatal(err) + return + } + + dstFile := makeDstFile(src) + + out, err := os.Create(dstFile) + defer out.Close() + + if !encode(src.dstFmt, out, img) { + log.Fatal("encodeに失敗") + } +} + +// decode file +func decode(file *os.File) (image.Image, string, error) { + return image.Decode(file) +} + +// encode image to dstFormat +func encode(format string, out *os.File, img image.Image) bool { + + switch format { + case "jpeg", "jpg": + jpeg.Encode(out, img, nil) + return true + case "gif": + gif.Encode(out, img, nil) + return true + case "png": + png.Encode(out, img) + return true + default: + return false + } +} + +// make destination file +func makeDstFile(src FileInformation) string { + dstDir := "output" + if _, err := os.Stat(dstDir); os.IsNotExist(err) { + os.Mkdir(dstDir, 0777) + } + return dstDir + "/" + fmt.Sprintf("%s.%s", getFileNameWithoutExt(src.name), src.dstFmt) +} + +// check if this format is avalable +func isAvailableFormat(format string) bool { + lowerFormat := strings.ToLower(format) + switch lowerFormat { + case "jpg", "jpeg", "png", "gif": + return true + default: + return false + + } +} + +// Get file name withour extension +func getFileNameWithoutExt(path string) string { + return filepath.Base(path[:len(path)-len(filepath.Ext(path))]) +} + +// Check if file exists +func exists(filename string) bool { + _, err := os.Stat(filename) + return err == nil +} + +// FileInformation contains Name and srcFmt and dstFmt. +type FileInformation struct { + name string // name of a file + srcFmt string // original format of a file + dstFmt string // format to convert +} diff --git a/kadai1/takata/main.go b/kadai1/takata/main.go new file mode 100644 index 0000000..08cb4b0 --- /dev/null +++ b/kadai1/takata/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "convert" + "flag" +) + +// main +func main() { + var ( + dir = flag.String("d", "", "directory to convert imagefiles") + srcFmt = flag.String("sf", "jpg", "src file format") + dstFmt = flag.String("df", "png", "dest file format") + ) + + flag.Parse() + + convert.Convert(*dir, *srcFmt, *dstFmt) +} diff --git a/kadai1/takata/test/1.jpg b/kadai1/takata/test/1.jpg new file mode 100644 index 0000000..8a0d03d Binary files /dev/null and b/kadai1/takata/test/1.jpg differ diff --git a/kadai1/takata/test/2.jpg b/kadai1/takata/test/2.jpg new file mode 100644 index 0000000..c685157 Binary files /dev/null and b/kadai1/takata/test/2.jpg differ diff --git a/kadai1/takata/test/3.jpg b/kadai1/takata/test/3.jpg new file mode 100644 index 0000000..c6b9b84 Binary files /dev/null and b/kadai1/takata/test/3.jpg differ diff --git a/kadai1/takata/test/4.jpg b/kadai1/takata/test/4.jpg new file mode 100644 index 0000000..0916c19 Binary files /dev/null and b/kadai1/takata/test/4.jpg differ diff --git a/kadai1/takata/test/5.jpg b/kadai1/takata/test/5.jpg new file mode 100644 index 0000000..f98ecf5 Binary files /dev/null and b/kadai1/takata/test/5.jpg differ diff --git a/kadai1/takata/test/inner/10.jpg b/kadai1/takata/test/inner/10.jpg new file mode 100644 index 0000000..f98ecf5 Binary files /dev/null and b/kadai1/takata/test/inner/10.jpg differ diff --git a/kadai1/takata/test/inner/6.jpg b/kadai1/takata/test/inner/6.jpg new file mode 100644 index 0000000..8a0d03d Binary files /dev/null and b/kadai1/takata/test/inner/6.jpg differ diff --git a/kadai1/takata/test/inner/7.jpg b/kadai1/takata/test/inner/7.jpg new file mode 100644 index 0000000..c685157 Binary files /dev/null and b/kadai1/takata/test/inner/7.jpg differ diff --git a/kadai1/takata/test/inner/8.jpg b/kadai1/takata/test/inner/8.jpg new file mode 100644 index 0000000..c6b9b84 Binary files /dev/null and b/kadai1/takata/test/inner/8.jpg differ diff --git a/kadai1/takata/test/inner/9.jpg b/kadai1/takata/test/inner/9.jpg new file mode 100644 index 0000000..0916c19 Binary files /dev/null and b/kadai1/takata/test/inner/9.jpg differ diff --git a/kadai2/takata/README.md b/kadai2/takata/README.md new file mode 100644 index 0000000..dcc2f41 --- /dev/null +++ b/kadai2/takata/README.md @@ -0,0 +1,91 @@ +# Kadai1 + + +## 実行方法 + +``` +go build -o converter main.go +./converter -d test -sf jpg -df png + +または + +go run main.go -d test -sf jpg -df png + + +出力結果はoutputディレクトリに格納される +``` + + +## Options + +``` +-d 変換対象の画像が入ったディレクトリ(中にディレクトリを含めてもOK) + +-sf 変換前のフォーマット(jpg,jpeg,png,gifが指定可能) デフォルトはjpg + +-df 変換後のフォーマット(jpg,jpeg,png,gifが指定可能) デフォルトはpng + + +``` + +## 課題1の回答 + +### ディレクトリを指定する +`flag.Args()`で受け取る値を対象のディレクトリとしました。 + +### ディレクトリ以下は再帰的に処理する +dirwalkメソッドの中でディレクトリの場合はさらにディレクトリ内のファイルを探すようにしました。 + + +### 指定したディレクトリ以下のJPGファイルをPNGに変換 + +オプションを指定しなかった場合、デフォルトでjpgファイルをpngファイルに変換するようにしました。 + +### mainパッケージと分離する +画像変換処理をconvertパッケージに格納し、mainパッケージへimportして呼び出すようにしました。 + + +### ユーザ定義型を作ってみる +Fileタイプを作成しました。ファイル名と変換元のファイル形式、変換後のファイル形式を格納します。 + +### GoDocを生成してみる + +``` +godoc -http:3000 +``` + +で作成しました。 + + +## 課題2の回答 + +## io.Readerとio.Writerについて調べてみよう + +### 標準パッケージでどのように使われているか + +サポートしている標準パッケージ +- json +- bytes.Buffer +- bufio.Reader +- os.File +- image +- jpeg +- png +- base64 + +インターフェイスを実装していたり、引数として扱えるようにしている。 + +### io.Readerとio.Writerがあることでどういう利点があるのか + +- io.Readerとio.Writerを満たした構造体(クラス)を同じように扱える +読み込み元や出力先がファイル、画面、バッファ、ネットワークなどのデータの種類に関わらず[]byteでさえあれば全て同じように処理できる。 + +また、例えば引数としてio.Reader型を宣言している場合、 +os.Stdinやos.Fileなどio.Readerを満たしている全ての構造体を同じように扱える。 + +また、テスト時にio.Readerとio.Writerを実装したモックを作成することで、 +入出力先をローカルファイルなどにすることでテストがやりやすくなる。 + + + + diff --git a/kadai2/takata/convert/convert.go b/kadai2/takata/convert/convert.go new file mode 100644 index 0000000..1912e5a --- /dev/null +++ b/kadai2/takata/convert/convert.go @@ -0,0 +1,210 @@ +/* +Package convert provides convert function +to some extension to other extension +*/ +package convert + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/pkg/errors" +) + +// Converter is interface to convert all files in dir. +type Converter interface { + Convert(dir string) error +} + +// ImageConverter for images contains from format and to format. +type ImageConverter struct { + From string // original format of a file + To string // format to convert +} + +// FileInfo contains Name and srcFmt and dstFmt. +type FileInfo struct { + name string // name of a file +} + +// Convert images with srcFmt in dir to images with dstFmt +func (i ImageConverter) Convert(dir string) error { + + if !isFileOrDirExists(dir) { + return errors.New("ディレクトリは存在しません") + } + + fInfo, error := os.Stat(dir) + if error != nil { + return errors.Wrapf(error, "os.Stat() with %s", dir) + } + + if !fInfo.IsDir() { + return errors.New("ディレクトリを指定してください") + } + + if !isAvailableFormat(i.From) { + return errors.New("指定した変換元の画像形式は無効です") + } + + if !isAvailableFormat(i.To) { + return errors.New("指定した変換先の画像形式は無効です") + } + + files, error := i.dirwalk(dir) + if error != nil { + return error + } + for _, file := range files { + if error := i.convertImage(file); error != nil { + return error + } + } + return nil +} + +// find files with some extension in a directory recursively +func (i ImageConverter) dirwalk(dir string) ([]FileInfo, error) { + + files, error := ioutil.ReadDir(dir) + if error != nil { + return nil, errors.Wrapf(error, "ioutil.ReadDir() with %s", dir) + } + + var paths []FileInfo + for _, file := range files { + if file.IsDir() { + files, error := i.dirwalk(filepath.Join(dir, file.Name())) + if error != nil { + return nil, error + } + paths = append(paths, files...) + continue + } + name := file.Name() + pos := strings.LastIndex(name, ".") + 1 + if name[pos:] != i.From { + continue + } + + path := FileInfo{filepath.Join(dir, name[:pos-1])} + paths = append(paths, path) + } + return paths, nil +} + +// convert file with some extension to file with other extension +func (i ImageConverter) convertImage(src FileInfo) error { + if error := i.convert(src); error != nil { + return error + } + return nil +} + +// Convert the targer image +func (i ImageConverter) convert(src FileInfo) error { + + fileName := src.name + "." + i.From + file, error := os.Open(fileName) + if error != nil { + return errors.Wrapf(error, "os.Open() with %s", fileName) + } + defer file.Close() + + img, error := i.decode(file) + if error != nil { + return error + } + + dstFile, error := i.makeDstFile(src) + if error != nil { + return error + } + + out, error := os.Create(dstFile) + if error != nil { + return errors.Wrapf(error, "os.Create() with %s", dstFile) + } + defer out.Close() + + if error := i.encode(out, img); error != nil { + return error + } + return nil +} + +// encode image to dstFormat +func (i ImageConverter) encode(out io.Writer, img image.Image) error { + + switch i.To { + case "jpeg", "jpg": + if error := jpeg.Encode(out, img, nil); error != nil { + return errors.Wrapf(error, "jpeg.Encode() with %s", i.To) + } + return nil + case "gif": + if error := gif.Encode(out, img, nil); error != nil { + return errors.Wrapf(error, "gif.Encode() with %s", i.To) + } + return nil + case "png": + if error := png.Encode(out, img); error != nil { + return errors.Wrapf(error, "png.Encode() with %s", i.To) + } + return nil + default: + return errors.New("不正な画像形式を出力先に指定しています") + } +} + +// decode image +func (i ImageConverter) decode(r io.Reader) (image.Image, error) { + img, _, error := image.Decode(r) + if error != nil { + return nil, error + } + return img, nil +} + +// make destination file +func (i ImageConverter) makeDstFile(src FileInfo) (string, error) { + dstDir := "output" + if _, err := os.Stat(dstDir); os.IsNotExist(err) { + os.Mkdir(dstDir, 0777) + } + return filepath.Join(dstDir, fmt.Sprintf("%s.%s", getFileNameWithoutExt(src.name), i.From)), nil +} + +// check if this format is avalable +func isAvailableFormat(format string) bool { + lowerFormat := strings.ToLower(format) + switch lowerFormat { + case "jpg", "jpeg", "png", "gif": + return true + default: + return false + + } +} + +// Get file name withour extension +func getFileNameWithoutExt(path string) string { + return filepath.Base(path[:len(path)-len(filepath.Ext(path))]) +} + +// Check if file exists +func isFileOrDirExists(filename string) bool { + if _, err := os.Stat(filename); os.IsNotExist(err) { + return false + } + return true + +} diff --git a/kadai2/takata/convert/convert_test.go b/kadai2/takata/convert/convert_test.go new file mode 100644 index 0000000..2602752 --- /dev/null +++ b/kadai2/takata/convert/convert_test.go @@ -0,0 +1,164 @@ +package convert + +import ( + "fmt" + "image" + "io/ioutil" + "os" + "testing" + + "github.com/pkg/errors" +) + +type Args struct { + dir string + srcFmt string + dstFmt string +} + +func TestConvert(t *testing.T) { + + argsList := []Args{ + {"../testdata/test", "jpg", "png"}, + {"../testdata/test", "jpeg", "png"}, + {"../testdata/test", "jpeg", "gif"}, + {"../testdata/test2", "png", "gif"}, + {"../testdata/test2", "png", "jpg"}, + {"../testdata/test3", "gif", "jpg"}, + {"../testdata/test3", "gif", "png"}, + {"../testdata/test4", "png", "jpg"}, + } + + for _, arg := range argsList { + + i := ImageConverter{arg.srcFmt, arg.dstFmt} + + t.Run(fmt.Sprintf("convertTest %s to %s", arg.srcFmt, arg.dstFmt), func(t *testing.T) { + err := i.Convert(arg.dir) + if err != nil { + t.Error(err) + } + removeTestOutput("./output") + }) + } +} + +func TestInvalidConvert(t *testing.T) { + + failArgsList := []Args{ + {"../testdata/test", "jpbg", "png"}, + {"../testdata/test", "jpg", "pdf"}, + {"../testdata/test2", "pag", "jpg"}, + {"../testdata/test3", "gof", "jpg"}, + {"../testdata/test2", "png", "gof"}, + } + + for _, arg := range failArgsList { + + i := ImageConverter{arg.srcFmt, arg.dstFmt} + + t.Run(fmt.Sprintf("convertFailTest %s to %s", arg.srcFmt, arg.dstFmt), func(t *testing.T) { + err := i.Convert(arg.dir) + if err == nil { + t.Error("Invalid Convert Result") + } + removeTestOutput("./output") + }) + } +} + +func TestFail_isFileOrDirExists(t *testing.T) { + + t.Run("NG isFileOrDirExists", func(t *testing.T) { + result := isFileOrDirExists("../notfound/1.png") + if result { + t.Error("Invalid Result") + } + }) +} + +func TestFail_dirwalk(t *testing.T) { + + t.Run("NG dirwalk", func(t *testing.T) { + + i := ImageConverter{"png", "jpg"} + _, err := i.dirwalk("../notfound") + + expectedError := errors.New("ioutil.ReadDir() with ../notfound: open ../notfound: no such file or directory") + if err.Error() != expectedError.Error() { + t.Error(err) + } + }) +} + +func TestFail_convert(t *testing.T) { + t.Run("NG convert", func(t *testing.T) { + + i := ImageConverter{"png", "jpg"} + fi := FileInfo{name: "999"} + err := i.convert(fi) + expectedError := errors.New("os.Open() with 999.png: open 999.png: no such file or directory") + if err.Error() != expectedError.Error() { + t.Error(err) + } + }) +} + +func TestFail_encode(t *testing.T) { + t.Run("NG encode", func(t *testing.T) { + + i := ImageConverter{"png", "pdf"} + f := testTempFile(t) + img := testTempImage(t) + err := i.encode(f, img) + expectedError := errors.New("不正な画像形式を出力先に指定しています") + if err.Error() != expectedError.Error() { + t.Error(err) + } + }) +} + +func TestFail_decode(t *testing.T) { + t.Run("NG decode", func(t *testing.T) { + f, error := os.Open("../testdata/test4/1.txt") + if error != nil { + t.Error(error) + } + + i := ImageConverter{"png", "pdf"} + _, error = i.decode(f) + if error != nil { + t.Error(error) + } + }) +} + +func testTempFile(t *testing.T) *os.File { + t.Helper() + tf, err := ioutil.TempFile("", "test") + if err != nil { + t.Error(err) + } + tf.Close() + return tf +} + +func testTempImage(t *testing.T) image.Image { + t.Helper() + + file, error := os.Open("../testdata/test/2.jpg") + if error != nil { + t.Error(error) + } + defer file.Close() + + img, _, error := image.Decode(file) + if error != nil { + t.Error(error) + } + return img +} + +func removeTestOutput(dir string) { + os.RemoveAll(dir) +} diff --git a/kadai2/takata/main.go b/kadai2/takata/main.go new file mode 100644 index 0000000..08cb4b0 --- /dev/null +++ b/kadai2/takata/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "convert" + "flag" +) + +// main +func main() { + var ( + dir = flag.String("d", "", "directory to convert imagefiles") + srcFmt = flag.String("sf", "jpg", "src file format") + dstFmt = flag.String("df", "png", "dest file format") + ) + + flag.Parse() + + convert.Convert(*dir, *srcFmt, *dstFmt) +} diff --git a/kadai2/takata/profile b/kadai2/takata/profile new file mode 100644 index 0000000..30ea87d --- /dev/null +++ b/kadai2/takata/profile @@ -0,0 +1,66 @@ +mode: set +convert/convert.go:39.51,41.29 1 1 +convert/convert.go:45.2,46.18 2 1 +convert/convert.go:50.2,50.20 1 1 +convert/convert.go:54.2,54.32 1 1 +convert/convert.go:58.2,58.30 1 1 +convert/convert.go:62.2,63.18 2 1 +convert/convert.go:66.2,66.29 1 1 +convert/convert.go:71.2,71.12 1 1 +convert/convert.go:41.29,43.3 1 0 +convert/convert.go:46.18,48.3 1 0 +convert/convert.go:50.20,52.3 1 0 +convert/convert.go:54.32,56.3 1 1 +convert/convert.go:58.30,60.3 1 1 +convert/convert.go:63.18,65.3 1 0 +convert/convert.go:66.29,67.50 1 1 +convert/convert.go:67.50,69.4 1 0 +convert/convert.go:75.65,78.18 2 1 +convert/convert.go:82.2,83.29 2 1 +convert/convert.go:101.2,101.19 1 1 +convert/convert.go:78.18,80.3 1 1 +convert/convert.go:83.29,84.19 1 1 +convert/convert.go:92.3,94.27 3 1 +convert/convert.go:98.3,99.30 2 1 +convert/convert.go:84.19,86.20 2 1 +convert/convert.go:89.4,90.12 2 1 +convert/convert.go:86.20,88.5 1 0 +convert/convert.go:94.27,95.12 1 1 +convert/convert.go:105.58,106.43 1 1 +convert/convert.go:109.2,109.12 1 1 +convert/convert.go:106.43,108.3 1 0 +convert/convert.go:113.53,117.18 3 1 +convert/convert.go:120.2,123.18 3 1 +convert/convert.go:127.2,128.18 2 1 +convert/convert.go:132.2,133.18 2 1 +convert/convert.go:136.2,138.47 2 1 +convert/convert.go:141.2,141.12 1 1 +convert/convert.go:117.18,119.3 1 1 +convert/convert.go:123.18,125.3 1 0 +convert/convert.go:128.18,130.3 1 0 +convert/convert.go:133.18,135.3 1 0 +convert/convert.go:138.47,140.3 1 0 +convert/convert.go:145.70,147.14 1 1 +convert/convert.go:148.21,149.56 1 1 +convert/convert.go:152.3,152.13 1 1 +convert/convert.go:153.13,154.55 1 1 +convert/convert.go:157.3,157.13 1 1 +convert/convert.go:158.13,159.50 1 1 +convert/convert.go:162.3,162.13 1 1 +convert/convert.go:163.10,164.81 1 1 +convert/convert.go:149.56,151.4 1 0 +convert/convert.go:154.55,156.4 1 0 +convert/convert.go:159.50,161.4 1 0 +convert/convert.go:169.66,171.18 2 1 +convert/convert.go:174.2,174.17 1 1 +convert/convert.go:171.18,173.3 1 0 +convert/convert.go:178.67,180.51 2 1 +convert/convert.go:183.2,183.98 1 1 +convert/convert.go:180.51,182.3 1 1 +convert/convert.go:187.44,189.21 2 1 +convert/convert.go:190.35,191.14 1 1 +convert/convert.go:192.10,193.15 1 1 +convert/convert.go:199.48,201.2 1 1 +convert/convert.go:204.46,205.53 1 1 +convert/convert.go:208.2,208.13 1 1 +convert/convert.go:205.53,207.3 1 1 diff --git a/kadai2/takata/testdata/test/2.jpg b/kadai2/takata/testdata/test/2.jpg new file mode 100644 index 0000000..c685157 Binary files /dev/null and b/kadai2/takata/testdata/test/2.jpg differ diff --git a/kadai2/takata/testdata/test/inner/6.jpg b/kadai2/takata/testdata/test/inner/6.jpg new file mode 100644 index 0000000..8a0d03d Binary files /dev/null and b/kadai2/takata/testdata/test/inner/6.jpg differ diff --git a/kadai2/takata/testdata/test2/1.png b/kadai2/takata/testdata/test2/1.png new file mode 100644 index 0000000..b2ce8f3 Binary files /dev/null and b/kadai2/takata/testdata/test2/1.png differ diff --git a/kadai2/takata/testdata/test2/inner/8.png b/kadai2/takata/testdata/test2/inner/8.png new file mode 100644 index 0000000..0d84e3c Binary files /dev/null and b/kadai2/takata/testdata/test2/inner/8.png differ diff --git a/kadai2/takata/testdata/test3/1.gif b/kadai2/takata/testdata/test3/1.gif new file mode 100644 index 0000000..b2ce8f3 Binary files /dev/null and b/kadai2/takata/testdata/test3/1.gif differ diff --git a/kadai2/takata/testdata/test3/inner/9.gif b/kadai2/takata/testdata/test3/inner/9.gif new file mode 100644 index 0000000..93ea6cd Binary files /dev/null and b/kadai2/takata/testdata/test3/inner/9.gif differ diff --git a/kadai2/takata/testdata/test4/1.txt b/kadai2/takata/testdata/test4/1.txt new file mode 100644 index 0000000..b2ce8f3 Binary files /dev/null and b/kadai2/takata/testdata/test4/1.txt differ diff --git a/kadai3-1/README.md b/kadai3-1/README.md new file mode 100644 index 0000000..e6ba195 --- /dev/null +++ b/kadai3-1/README.md @@ -0,0 +1,10 @@ +# 課題3-1 + +- タイピングゲームを作ろう +- 標準出力に英単語を出す(出すものは自由) +- 標準入力から1行受け取る +- 制限時間内に何問解けたか表示する + +# 備考 + +テストで標準入力に文字を入力する方法がわからず止まってしまいました。 \ No newline at end of file diff --git a/kadai3-1/takata/main.go b/kadai3-1/takata/main.go new file mode 100644 index 0000000..4476f37 --- /dev/null +++ b/kadai3-1/takata/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "os" + "time" +) + +const limitTime = 5 + +var writer io.Writer + +var words []string + +func init() { + writer = os.Stdout + + // TODO: ファイルから読み込むなどを検討する + words = []string{ + "apple", + "banana", + "orange", + "grape", + "Melon", + "Muscat", + "strawberry", + "persimmon", + "kiwi fruit", + "cherry", + } +} + +func start() { + fmt.Fprintln(writer, "Game スタート") + fmt.Fprintf(writer, "制限時間は %v秒です\n", limitTime) +} + +func end() { + fmt.Fprintln(writer, "Game 終了") +} + +func createCh(input io.Reader) <-chan string { + ch := make(chan string) + go func() { + s := bufio.NewScanner(input) + for s.Scan() { + ch <- s.Text() + } + close(ch) + }() + return ch +} + +func run(input io.Reader) int { + + var answer int + + ch := createCh(input) + + for i, w := range words { + + fmt.Fprintf(writer, "%d回目 文字を入力してください -> %s\n", i+1, w) + fmt.Fprint(writer, "> ") + select { + case <-time.After(limitTime * time.Second): + fmt.Fprintln(writer, "時間切れです") + case tw := <-ch: + if w == tw { + fmt.Fprintln(writer, "正解") + answer++ + } else { + fmt.Fprintln(writer, "残念") + } + } + } + fmt.Fprintf(writer, "正解数: %d\n", answer) + return answer +} + +func main() { + start() + run(os.Stdin) + end() +} diff --git a/kadai3-1/takata/main_test.go b/kadai3-1/takata/main_test.go new file mode 100644 index 0000000..b6bdb2f --- /dev/null +++ b/kadai3-1/takata/main_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "bytes" + "testing" +) + +var buffer *bytes.Buffer + +func init() { + buffer = &bytes.Buffer{} + writer = buffer +} + +func TestStart(t *testing.T) { + defer buffer.Reset() + start() + expected := "Game スタート\n制限時間は 5秒です\n" + actual := buffer.String() + if actual != expected { + t.Errorf(`expected=%s, actual=%s`, expected, actual) + } +} + +func TestEnd(t *testing.T) { + defer buffer.Reset() + end() + expected := "Game 終了\n" + actual := buffer.String() + if actual != expected { + t.Errorf(`expected=%s, actual=%s`, expected, actual) + } +} + +func TestCreateCh(t *testing.T) { + input := "hello world." + inputBuf := bytes.NewBufferString(input) + ch := createCh(inputBuf) + received := <-ch + if input != received { + t.Errorf(`expected=%s, actual=%s`, input, received) + } +} + +func TestRunNoAnswer(t *testing.T) { + defer buffer.Reset() + expected := 0 + actual := run(buffer) + if actual != expected { + t.Errorf(`expected=%d, actual=%d`, expected, actual) + } +} + +func TestRunOK(t *testing.T) { + defer buffer.Reset() + expected := 1 + // TODO: どうしたら標準入力のテストができるのか? + actual := run(buffer) + if actual != expected { + t.Errorf(`expected=%d, actual=%d`, expected, actual) + } +}