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

Kadai2 shinta #17

Open
wants to merge 14 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
File renamed without changes.
1 change: 1 addition & 0 deletions kadai2/shinta/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
testdata
36 changes: 36 additions & 0 deletions kadai2/shinta/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 課題2
## io.Readerとio.Writerについて調べてみよう
### 標準パッケージでどのように使われているか
- os(os.Open, os.Create, os.Stdin, os.Stdout, os.Stderr)
- *os.File型、ファイルを開いたりするときに使う
- bytes.Buffer (struct), bytes.Reader (struct)
- ファイルではなくメモリへデータを書き込むのに使う。*bytes.Buffer が io.Writer として利用可能。
- *bytes.Reader が io.Reader として利用可能。
- bufio.Scanner
- ファイルや標準入力から作られた io.Reader から1行ずつ文字列を読み込む。
- io/ioutil.ReadAll, io/ioutil.ReadFile, io/ioutil.WriteFile, io.Copy
- io/ioutil.ReadAll: io.Reader から全てデータを読み込んで[]byte を作成する。
- io/ioutil.ReadFile: 指定されたファイル名から全てのデータを読み込んで[]byte を作成する。
- io/ioutil.WriteFile: 指定されたファイル名に[]byte を書き込む。os.Create に合わせるなら第三引数permは0666を渡す。
- io.Copy: io.Reader から io.Writer にデータを全てコピーする便利関数

### io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる
- io.Reader io.Writerを持っている関数であれば、抽象的にIOしていると考えて良い
- 呼び出し側はI/O処理がどんなことをしているのかを理解する必要が無い
- DIPにできる。

### test
```
// 通常のtest
go test ./imageconversion
```

```
// カバレッジ
go test -cover ./imageconversion
go test -coverprofile=cover.out ./imageconversion
go tool cover -html=cover.out -o cover.html
```

- エラーケースのテストがまだできていない。
- test しやすい設計についてもっと考えないといけない。
228 changes: 228 additions & 0 deletions kadai2/shinta/cover.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body {
background: black;
color: rgb(80, 80, 80);
}
body, pre, #legend span {
font-family: Menlo, monospace;
font-weight: bold;
}
#topbar {
background: black;
position: fixed;
top: 0; left: 0; right: 0;
height: 42px;
border-bottom: 1px solid rgb(80, 80, 80);
}
#content {
margin-top: 50px;
}
#nav, #legend {
float: left;
margin-left: 10px;
}
#legend {
margin-top: 12px;
}
#nav {
margin-top: 10px;
}
#legend span {
margin: 0 5px;
}
.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }

</style>
</head>
<body>
<div id="topbar">
<div id="nav">
<select id="files">

<option value="file0">github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go (81.8%)</option>

</select>
</div>
<div id="legend">
<span>not tracked</span>

<span class="cov0">not covered</span>
<span class="cov8">covered</span>

</div>
</div>
<div id="content">

<pre class="file" id="file0" style="display: none">/*
Package imageconversion は画像ファイル形式の変換を行います。
optionで、実行するディレクトリと変換前と変換後の画像形式を指定できます。
option を指定しない場合、コマンドを実行するディレクトリと、 変換前の画像タイプがjpeg、変換後の画像タイプがpngになります。
変換可能な拡張子として、jpg、jpeg、png、gif としています。
*/
package imageconversion

import (
"errors"
"image"
"image/gif"
"image/jpeg"
"image/png"
"os"
"path/filepath"
"strings"
)

type arg struct {
dir string
preExt string
afterExt string
}

func (a *arg) valid() error <span class="cov8" title="1">{
if a.preExt == a.afterExt </span><span class="cov0" title="0">{
return errors.New("変換前と変換後で拡張子が同じです。")
}</span>
<span class="cov8" title="1">allowExtList := []string{"jpg", "jpeg", "png", "gif"}
allowExtMap := map[string]bool{}
for _, ext := range allowExtList </span><span class="cov8" title="1">{
allowExtMap[ext] = true
}</span>
<span class="cov8" title="1">if !allowExtMap[a.preExt] || !allowExtMap[a.afterExt] </span><span class="cov0" title="0">{
return errors.New("指定できる拡張子: " + strings.Join(allowExtList, ","))
}</span>
<span class="cov8" title="1">return nil</span>
}

func (a *arg) convertExt() <span class="cov8" title="1">{
a.preExt, a.afterExt = "."+a.preExt, "."+a.afterExt
}</span>

// imageFile struct は変換対象の画像のpath(path)、拡張子を除いたファイル名(base)、拡張子(ext)を持っています。
type imageFile struct {
path string
base string
ext string
}

// getFileNameWithoutExt は対象ファイルのpathと拡張子を除いたファイル名を返します。
func getFileNameWithoutExt(path string) string <span class="cov8" title="1">{
return filepath.Base(path[:len(path)-len(filepath.Ext(path))])
}</span>

// createImgStrunct は、imageFile structを生成し、返します。
func createImgStruct(path string) (image imageFile) <span class="cov8" title="1">{
base := getFileNameWithoutExt(path)
image = imageFile{filepath.Dir(path), base, filepath.Ext(path)}
return
}</span>

/*
convertExec は画像ファイルを引数で指定された変換後の拡張子(defaultはpng)に変換した新しい画像ファイルを生成します。
処理が成功するとnil、errorが起きた場合、errorを返します。
*/
func convertExec(path, afterExt string) error <span class="cov8" title="1">{
img := createImgStruct(path)
targetImg, err := os.Open(img.path + "/" + img.base + img.ext)
if err != nil </span><span class="cov0" title="0">{
return err
}</span>
<span class="cov8" title="1">readImg, _, err := image.Decode(targetImg)
if err != nil </span><span class="cov0" title="0">{
return err
}</span>
<span class="cov8" title="1">outputImg, err := os.Create((img.path + "/" + img.base + afterExt))
if err != nil </span><span class="cov0" title="0">{
return err
}</span>

<span class="cov8" title="1">switch afterExt </span>{
case ".jpeg", ".jpg":<span class="cov8" title="1">
jpeg.Encode(outputImg, readImg, nil)</span>
case ".gif":<span class="cov8" title="1">
gif.Encode(outputImg, readImg, nil)</span>
default:<span class="cov8" title="1">
png.Encode(outputImg, readImg)</span>
}
<span class="cov8" title="1">err = targetImg.Close()
err = outputImg.Close()
return err</span>
}

/*
Excute は画像変換処理を実行します。
このpackageで呼び出せる唯一の関数です。
引数で、ディレクトリ(デフォルトは ./)、変換前拡張子(デフォルトは jpg)、変換後拡張子(デフォルトは png)を受け取ります。
引数が指定されない場合はデフォルトの値が適用されます。
引数で受け取ったディレクトリ以下の変換前拡張子のファイルを変換後拡張子に変換した新しいファイルを作成します。
処理が成功の場合、nilをerrorが起きた場合はerrorを返します。
引数で指定されたディレクトリ以下から引数で指定した変換前拡張子(defaultはjpg)のファイルを、
変換後拡張子(defaultはpng)に変換した新しい画像ファイルを生成します。
処理が成功するとnil、errorが起きた場合、errorを返します。
*/
func Excute(dir, preExt, afterExt string) error <span class="cov8" title="1">{
arg := &amp;arg{dir, preExt, afterExt}
if err := arg.valid(); err != nil </span><span class="cov0" title="0">{
return err
}</span>
<span class="cov8" title="1">arg.convertExt()
err := filepath.Walk(arg.dir, func(path string, info os.FileInfo, err error) error </span><span class="cov8" title="1">{
if err != nil </span><span class="cov0" title="0">{
return err
}</span>
<span class="cov8" title="1">if filepath.Ext(path) == arg.preExt </span><span class="cov8" title="1">{
err = convertExec(path, arg.afterExt)
if err != nil </span><span class="cov0" title="0">{
return err
}</span>
}
<span class="cov8" title="1">return err</span>
})
<span class="cov8" title="1">return err</span>
}
</pre>

</div>
</body>
<script>
(function() {
var files = document.getElementById('files');
var visible;
files.addEventListener('change', onChange, false);
function select(part) {
if (visible)
visible.style.display = 'none';
visible = document.getElementById(part);
if (!visible)
return;
files.value = part;
visible.style.display = 'block';
location.hash = part;
}
function onChange() {
select(files.value);
window.scrollTo(0, 0);
}
if (location.hash != "") {
select(location.hash.substr(1));
}
if (!visible) {
select("file0");
}
})();
</script>
</html>
32 changes: 32 additions & 0 deletions kadai2/shinta/cover.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
mode: set
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:26.29,27.28 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:30.2,32.35 3 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:35.2,35.56 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:38.2,38.12 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:27.28,29.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:32.35,34.3 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:35.56,37.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:41.28,43.2 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:53.48,55.2 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:58.53,62.2 3 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:68.47,71.16 3 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:74.2,75.16 2 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:78.2,79.16 2 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:83.2,83.18 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:91.2,93.12 3 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:71.16,73.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:75.16,77.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:79.16,81.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:84.23,85.39 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:86.14,87.38 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:88.10,89.33 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:107.49,109.36 2 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:112.2,113.85 2 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:125.2,125.12 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:109.36,111.3 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:113.85,114.17 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:117.3,117.39 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:123.3,123.13 1 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:114.17,116.4 1 0
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:117.39,119.18 2 1
github.com/gopherdojo/dojo7/kadai2/shinta/imageconversion/imageconversion.go:119.18,121.5 1 0
3 changes: 3 additions & 0 deletions kadai2/shinta/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/gopherdojo/dojo7/kadai2/shinta

go 1.12
6 changes: 6 additions & 0 deletions kadai2/shinta/imageconversion/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package imageconversion

// var ImageFile imageFile
var GetFileNameWithoutExt = getFileNameWithoutExt
var CreateImgStruct = createImgStruct
var ConvertExec = convertExec
Loading