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

takami228's Kadai2 #18

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions kadai2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 課題2-1

## 課題

* io.Readerとio.Writerについて調べてみよう
* 標準パッケージでどのように使われているか
* io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる

## 回答

参照したコード

* https://github.com/golang/go/blob/master/src/io/io.go
* https://github.com/golang/go/blob/master/src/bytes/buffer.go
* https://github.com/golang/go/blob/master/src/bytes/reader.go
* https://github.com/golang/go/blob/master/src/archive/zip/reader.go
* https://github.com/golang/go/blob/master/src/archive/zip/writer.go

### どのように使われているか

* io.go
* io.goRead、Write、Close、Seek等に対してそれぞれInterfaceが定義されている
* ReadWriter、ReadCloser等複数の振る舞いに対しては型埋め込みが使われている
* bytes/buffer.go, bytes/reader.go
* io.goでintefaceとして定義されたByteReaderのメソッド `ReadByte` の振る舞いをそれぞれ記述していた
* zip/reader.go, zip/writer.go
* ...

### どういう利点があるのか

* ???

---

# 課題2-2

## 課題

* 1回目の宿題のテストを作ってみて下さい
* テストのしやすさを考えてリファクタリングしてみる
* テストのカバレッジを取ってみる
* テーブル駆動テストを行う
* テストヘルパーを作ってみる

## 回答

W.I.P...
1 change: 1 addition & 0 deletions kadai2/imgconvert/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
outputs/*
Empty file added kadai2/imgconvert/.gitkeep
Empty file.
82 changes: 82 additions & 0 deletions kadai2/imgconvert/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# 課題1 - 画像変換コマンドを作ろう -

以下の仕様を満たすコマンドを作る。

- ディレクトリを指定する
- 指定したディレクトリ以下のJPGファイルをPNGに変換
- ディレクトリ以下は再帰的に処理する
- 変換前と変換後の画像形式を指定できる

また以下を満たすように実装すること

- mainパッケージと分離する
- 自作パッケージと標準パッケージと準標準パッケージのみ使う
- 準標準パッケージ:golang.org/x以下のパッケージ
- ユーザ定義型を作ってみる
- GoDocを生成してみる

# 実行手順

以下のコマンドでビルドする。

```
# ビルド
go build -o myconverter

# 出力用フォルダを作成する
mkdir outputs
```

ディレクトリは`-target`で指定し、`-from`で変更前の拡張子、`-to`で変更後の拡張子を指定する。変換されたファイルはoutputフォルダに出力される。

```
# images配下のjpgファイルをpngへ変換する
$ ./myconverter -target=images -from=jpg -to=png
Convert Success from images/dir/sub_lena.jpg to outputs/sub_lena.png
Convert Success from images/lena.jpg to outputs/lena.png

# images配下のpngファイルをjpgへ変換する
$ ./myconverter -target=images -from=png -to=jpg
Convert Success from images/dir/sub_icon.png to outputs/sub_icon.jpg
Convert Success from images/icon.png to outputs/icon.jpg
```

デフォルトでは`target`はカレントディレクトリが指定され、`jpg`から`png`への変換を実行する。
```
$ ./myconverter
Convert Success from current_rena.jpg to outputs/current_rena.png
Convert Success from images/dir/sub_lena.jpg to outputs/sub_lena.png
Convert Success from images/lena.jpg to outputs/lena.png
```

`jpg`から`png`、`png`から`jpg`への変換のみサポートしており、その他の変換には失敗する。
```
$ ./myconverter -target=images -from=gif -to=jpg
[ERROR]No supprot to convert from gif to jpg
```

ヘルプコマンド
```
# ヘルプコマンドの実行例
$ ./myconverter -h
Usage of ./myconverter:
-from string
from file extention (default "jpg")
-target string
target filepath. (default ".")
-to string
to file extention (default "png")
```

godocを生成してみる
```
$godoc -html ./converter > godoc-converter.html
```

---

# 所感

- 以前入れ忘れたVSCodeのGoプラグインを入れた結果、GoLintによってコンパイル実行前に型エラーに気づけたり、GoDocの記入漏れに気づくことができた
- まだGoに書きなれてないので文法をググりながらやったので時間がかかってしまった
- GoDocの生成のときにgithub.comから参照しようとしたがブランチを参照する方法が分からなかった
128 changes: 128 additions & 0 deletions kadai2/imgconvert/converter/converter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Package converter Overview
package converter

import (
"fmt"
"image"
"image/jpeg"
"image/png"
"os"
"path/filepath"
)

// MyImageFile contains fileExt, filepath before converted, and after converted.
type MyImageFile struct {
fileExt string // file extension
fromFilepath string // from filepath
toFilepath string // to filepath
}

// ConvertImagesFromJpgToPngInDir converts all jpg images to png in target directory.
func ConvertImagesFromJpgToPngInDir(dir string) {
for _, path := range GetFilepathListByExt(dir, ".jpg") {
myImageFile := MyImageFile{fileExt: "jpg", fromFilepath: path, toFilepath: ""}
if err := ConvertJpgToPng(&myImageFile); err != nil && myImageFile.fileExt == "png" {
fmt.Println("[ERROR] Convert failed from jpg to png.")
} else {
fmt.Println("Convert Success from " + myImageFile.fromFilepath + " to " + myImageFile.toFilepath)
}
}
}

// ConvertImagesFromPngToJpgInDir converts all png images to jpg in target directory.
func ConvertImagesFromPngToJpgInDir(dir string) {
for _, path := range GetFilepathListByExt(dir, ".png") {
myImageFile := MyImageFile{fileExt: "png", fromFilepath: path, toFilepath: ""}
if err := ConvertPngToJpg(&myImageFile); err != nil && myImageFile.fileExt == "jpg" {
fmt.Println("[ERROR] Convert failed from png to jpg.")
} else {
fmt.Println("Convert Success from " + myImageFile.fromFilepath + " to " + myImageFile.toFilepath)
}
}
}

// GetFilepathListByExt returns the filepath list by the extention in target directory.
func GetFilepathListByExt(dir string, ext string) []string {
filePathList := make([]string, 0)
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if filepath.Ext(path) == ext {
filePathList = append(filePathList, path)
}
return nil
})

if err != nil {
return nil
}

return filePathList
}

// ConvertJpgToPng convert target jpg image to png.
func ConvertJpgToPng(imageFile *MyImageFile) error {
file, err := os.Open(imageFile.fromFilepath)
if err != nil {
fmt.Println("[ERROR] No Such File.")
return err
}
defer file.Close()

outputFilePath := "outputs/" + GetFileNameWithoutExt(imageFile.fromFilepath) + ".png"

img, _, err := image.Decode(file)

dstfile, err := os.Create(outputFilePath)
if err != nil {
fmt.Println("[ERROR] No Such FilePath.")
return err
}
defer dstfile.Close()

err = jpeg.Encode(dstfile, img, nil)
if err != nil {
fmt.Println("[ERROR] File Encode Failed.")
return err
}

imageFile.fileExt = "png"
imageFile.toFilepath = outputFilePath

return nil
}

// ConvertPngToJpg convert target png image to jpg.
func ConvertPngToJpg(imageFile *MyImageFile) error {
file, err := os.Open(imageFile.fromFilepath)
if err != nil {
fmt.Println("[ERROR] No Such File.")
return err
}
defer file.Close()

outputFilePath := "outputs/" + GetFileNameWithoutExt(imageFile.fromFilepath) + ".jpg"

img, _, err := image.Decode(file)

dstfile, err := os.Create(outputFilePath)
if err != nil {
fmt.Println("[ERROR] No Such FilePath.")
return err
}
defer dstfile.Close()

err = png.Encode(dstfile, img)
if err != nil {
fmt.Println("[ERROR] File Encode Failed.")
return err
}

imageFile.fileExt = "jpg"
imageFile.toFilepath = outputFilePath

return nil
}

// GetFileNameWithoutExt returns the filename without file extension
func GetFileNameWithoutExt(path string) string {
return filepath.Base(path[:len(path)-len(filepath.Ext(path))])
}
Binary file added kadai2/imgconvert/current_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/imgconvert/current_rena.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading