OmniAICreator/Qiita-1.07M huggingface dataset:
Goで依存性の注入を例えて説明

## 例えて説明
部屋と照明でたとえて`依存性の注入`をしない場合とする場合をコードで説明する。

### 依存性の注入(DI)をしない場合
#### 初期構成
- 照明
    - 白熱電球はフィラメントが光る機能がある。

```go
type Incandescent struct{}

func (*Incandescent) LightUp() string {
	return "フィラメントが光るよ!"
}
```

- 部屋の構成
    - 部屋には照明(白熱電球)が2つあって、照明に電源を入れる機能をするスイッチも2つある。

```go
type Room struct {
	LightOne Incandescent
	LightTwo Incandescent
}

func (r *Room) SwitchOnOne() {
	fmt.Println("1番照明:", r.LightOne.LightUp())
}
func (r *Room) SwitchOnTwo() {
	fmt.Println("2番照明:", r.LightTwo.LightUp())
}
```

#### 僕の部屋を生成する
`Room`構造体で僕の部屋を作って電気をつける

```go
func main() {
	myRoom := new(Room)
	myRoom.SwitchOnOne() // 1番照明: フィラメントが光るよ!
	myRoom.SwitchOnTwo() // 2番照明: フィラメントが光るよ!
}
```

#### 電球を変えたくなった!
時代が進んで、LEDが発売され、一個買って使おうとした。

```go
// LED電球
type LedLight struct{}

func (*LedLight) LightUp() string {
	return "LEDが光るよ!"
}

// 部屋の工事が発生 (設計変更)
type Room struct {
	LightOne Incandescent
	LightTwo LedLight // Incandescentから LedLightに変更
}
```

#### 問題点
- 僕の部屋は電球の種類に依存していた。
    - 部屋は初期に白熱電球だけを考えて設計された。
    - 電球の仕組みが異なる照明に変えようとする度に部屋の工事が発生する。(ソケットは一緒なのに!!)

めったに工事がいらない部屋が、明るくするという部屋の一部機能に振り回されるのはおかしくない?

### 依存性の注入(DI)をする場合
照明の実装は上と変わらない。

#### 照明のソケット(インタフェース)を用意する
部屋の設計に特定種類の電球を付けるのではなく、電球を入れられるソケットを付けて置く。
`LigthUp()`という機能さえ満たせば部屋のソケットに入れることができる。
*[依存性逆転の原則(Dependency Inversion Principle)の依存性逆転パターン - Wikipedia](https://ja.wikipedia.org/wiki/%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%81%AE%E5%8E%9F%E5%89%87#%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)*

```go
// 照明のソケット
type LightSocket interface {
	LightUp() string
}

type Room struct {
	LightOne LightSocket // 部屋にはソケットを付けておく
	LightTwo LightSocket
}

// Constructor Injection
func NewRoom(lightOne, lightTwo LightSocket) *Room {
	room := &Room{
		LightOne: lightOne,
		LightTwo: lightTwo,
	}
	return room
}
```

#### 部屋に電球を依存性の注入(DI)で入れる
これで、部屋の工事が発生せず、ソケットに合う照明であれば、入れ替えるのが可能になる。

```go
func main() {
	lightOne := new(light.Incandescent) // 注入するオブジェクト
	lightTwo := new(light.LedLight)     // 注入するオブジェクト

	myRoom := NewRoom(lightOne, lightTwo) // ここがDI

	myRoom.SwitchOnOne() // 1番照明: フィラメントが光るよ!
	myRoom.SwitchOnTwo() // 2番照明: LEDが光るよ!
}
```

## DIの利点
テストコードのために関連機能全てを実装せずに、`Mock`を使ってテストができる。

上記の「[依存性の注入(DI)をしない場合](#依存性の注入diをしない場合)」のコードでは部屋のスイッチを入れると電気が流れるのかをテストしたくても電球の機能が実装されてないとテストが難しい。

DIをするコードではまだ電球の実装有無にかかわらず、このような`Mock`電球を用意して注入することでテストが可能

```go
type MockLight struct{}

func (*MockLight) LightUp() string {
	return "ぴーぴー音を鳴らす"
}

func TestSwitchOnOne(t *testing.T) {
	room := NewRoom(new(MockLight), new(MockLight)) // ここがDI
	...
}
```

##

##
Gitで異なるブランチのファイルをカレントのブランチへ持ってくる

**ちょっと色々あって**、AブランチのファイルをBブランチに持ってこなきゃならなくなったとする。頻繁にこういうのがあって、そのたびに何度も忘れるので書いとくと、下記で持ってこれる。

```
git checkout ブランチ名 -- ファイルパス
```

ハイフン２つ `--` はgitというよりも、コマンドのオプション終了を指示する制御文字みたいだ。下記が詳しかった。

https://qiita.com/ymko/items/9c7dd37a7b41d1e21e84

最近、こんなことばかりをしてる。
低頻度語をぶっ壊す~How to subword-nmt~

LSTMとかの深層学習モデルで自然言語を扱うとき、 
語彙数が増えると計算量やGPUメモリサイズが爆発的に増えてしまうことが多い。  
予め低頻度語を**BPE**で**サブワード化**することで語彙サイズを減らそうというエントリー。

## サブワード化ってなんだ。
あまり出現しない単語を、文字や部分文字(サブワード)に分割しようということ。 
これにより、語彙サイズが圧縮できる。 
極端な話、英単語を文字に分割すれば語彙数は英語アルファベットの52種(大文字+小文字)に圧縮可能。

## BPEって何だ。
BPE(Byte Pair Encoding)は元々圧縮に使われていた技術。 
共通な2バイトを新しい1バイトに置き換えることで圧縮していく。 
例えば、`aabbaac`の`aa`を`A`に置き換えると、`AbbAc`と圧縮できる。  
この処理を語彙圧縮に適用したのが、 
[Neural Machine Translation of Rare Words with Subword Units](https://arxiv.org/abs/1508.07909)。   
事前にコーパスの語彙に対してBPEを適用することで、サブワードを学習する。 

## subword-nmtのインストール
[subword-nmt](https://github.com/rsennrich/subword-nmt)を使えば、簡単にBPEを使用したサブワードの学習とサブワード化ができる。
Pythonで書かれているのでpipでインストールする。

~~~bash
pip install subword-nmt
~~~

## データ準備と前処理
サブワードの学習にはコーパスが必要。
今回は、[吾輩は猫である](https://www.aozora.gr.jp/cards/000148/files/789_14547.html)を用意した。

~~~:wagahai.txtの一部
　吾輩わがはいは猫である。名前はまだ無い。
　どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。
~~~

日本語からサブワードを学習する場合は、文章はあらかじめ単語単位に分割されている必要がある。 
今回はMeCabを使って、分かち書きした`wakati_wagahai.txt`を用意した。

~~~bash
mecab -b 100000 -Owakati wagahai.txt -o wakati_wagahai.txt
~~~

~~~:wakati_wagahai.txtの一部
　 吾輩 わがはい は 猫 で ある 。 名前 は まだ 無い 。 
　 どこ で 生れ た か とんと 見当 けん とう が つか ぬ 。 何 でも 薄暗い じめじめ し た 所 で ニャーニャー 泣い て いた事 だけ は 記憶 し て いる 。 吾輩 は ここ で 始め て 人間 という もの を 見 た 。 
~~~

## いざサブワードの学習
以下のコマンドで`wakati_wagahai.txt`からサブワードを学習する。

~~~bash
subword-nmt learn-bpe -s 3000 < wakati_wagahai.txt > codes.txt
~~~

`-s`は共通文字置き換え回数を指定している。 
小さいほどサブワードは文字単位になる。(0だと完全に文字になるはず。) 

`codes.txt`の中身はこんな感じ。 

~~~:codes.txtの一部
吾 輩</w>
ま す</w>
さ ん</w>
じ ゃ</w>
な っ</w>
こ れ</w>
と こ
で も</w>
~~~

`吾 輩</w>`は、単語内に`我`と`輩</w>`が出現したら`我輩</w>`に結合するよ。という意味。
さっきのBPEの例で行くと`aa`を`A`にするよ。と同意。
(`</w>`は元の単語の末尾であることを表してます。 )

## サブワード化する。

学習した`codes.txt`を用いて以下のコマンドで`wakati_wagahai.txt`をサブワード化してみる。

~~~bash
subword-nmt apply-bpe -c codes.txt < wakati_wagahai.txt > subword_wagahai.txt
~~~

`subword_wagahai.txt`はこんな感じ。

~~~:subword_wagahai.txtの一部
　 吾輩 わが@@ はい は 猫 で ある 。 名前 は まだ 無い 。 
　 どこ で 生れ た か とんと 見当 けん とう が つか ぬ 。 何 でも 薄@@ 暗い じ@@ め@@ じめ し た 所 で ニャ@@ ー@@ ニャ@@ ー 泣い て いた@@ 事 だけ は 記憶 し て いる 。 吾輩 は ここ で 始め て 人間 という もの を 見 た 。
~~~

`わが@@`は`はい`と元々1単語であったことを示している。

## 低頻度語は解体できたのか
以下の簡単なPythonスクリプトで語彙数を確認してみる。

~~~Python
import sys
for arg in sys.argv[1:]:
    print("Input : {}".format(arg))
    with open(arg, "r") as f:
        text = f.read()
    tokens = text.split()
    print("Vocab : {}".format(len(set(tokens))))
~~~

~~~bash
$ python3 counter.py wakati_wagahai.txt subword_wagahai.txt 
Input : wakati_wagahai.txt
Vocab : 15717
Input : subword_wagahai.txt
Vocab : 7515
~~~

無事語彙数が`15717`から`7515`に減ったことがわかる。
コード で フローチャート シーケンス図 ガントチャート等 を 描く① ～mermaidの紹介～

# 目的
- コードでシーケンス図やガントチャートを書くことの出来るmermaidと言うものをまとめる  
※本記事ではmermaidの紹介を主に行う。mermaidを描く方法は「コード で シーケンス図等 を 描く ～mermaidで図を描く～ mermaidまとめ②」で記載。該当記事は[こちら](https://qiita.com/miriwo/items/7e26f0d85829bb15e69c)

# この記事のターゲット
- 手軽にかっこよくシーケンス図を描きたい方
- Excelでのフローチャート作成に飽きた方
- 各種図をソースコードで管理したい方
- 下記のような図をコードで描きたい方(gitのブランチ図は現在機能開発中)  
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2099c6dd-155c-cb98-e88b-33c24f9985ee.png)
  
![sequence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b9f847f8-fb17-8191-32b4-0b339847d37e.png)

![gantt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/89d74822-ca92-4aad-5fe9-1b3d0cf38c00.png)

![git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f6685b3d-9137-6017-5521-d2c03443328e.png)
# mermaidって？？
- 一言で言うならソースコードで図形が描けるもの。
- フローチャート、シーケンス図、ガントチャート図、※Gitグラフをソースコードで作成出来る。
※Gitグラフは現在実装段階で完全サポートされていません。

# mermaidのいいところ
- 各種図の見た目がほぼ決まっているので、記法に従って書くことによりだれでも簡単に図を書くことが出来る
- Markdownファイルに記載することができる。
- 公式のサイトの書き方の例が英語だけどわかりやすい
公式サイトは[こちら](https://mermaidjs.github.io/#/)
- オンラインサイトで作成した図形をsvgファイルに出力できる  
サイト名は「Mermaid Live Editor」
出力サイトは[こちら](https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbkFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG5DIC0tPnxPbmV8IERbTGFwdG9wXVxuQyAtLT58VHdvfCBFW2lQaG9uZV1cbkMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ)
- Visual Studio Code(エディタ)でリアルタイムプレビュー表示が行えるプラグインがある
Visual Studio Codeの導入に関しては[こちら](https://qiita.com/miriwo/items/306769d90d910944e471)

# mermaidのよくないところ
- Visual Studio Codeを使用しないと.png/.jpegで出力できない。
- オンラインサイトでの出力だとsvgファイルにしか出力できない。
svgファイルについては[こちら](https://qiita.com/miriwo/items/e421f56431d773baf7e8)
- 細かい調整(フローのテキストの種類を変更したいなど)ができない。
- 職場で使用する際はメンテナンス性に難あり。
※Excelと違い、全員にmermaidの知識が必要になる

# mermaidの記載方法
- 記載方法は大きく分けて二種類ある。
    1. Markdownのコマンドブロック内に記載する。
    Markdownドキュメント内の一部としてmermaidの表を使用したいときに効果的。  
※ただしHTML出力はうまくいかないことがある。本件については後述する。
    1. 公式のオンライン出力サイトに記載する。  
    svgファイルとして図を取得したいときに効果的。

# まとめ
- mermaidではコードで図を書くことができる。
- フロー、シーケンス、ガントチャート、Gitグラフは作れる。
- 出力拡張子がちょっとだけ特殊(出力サイトではsvgのみ)
- 簡単にかっこいい図が書ける。
異なるプロジェクトのCloudStorageからComputeEngineへファイルをコピー

# 概要

AプロジェクトのCloudStorageからBプロジェクトのComputeEngineへファイルをコピーする方法

# 実現方法
Aプロジェクトのバケットの権限に以下の設定を追加する

```
[Bプロジェクトのプロジェクト番号]-compute@developer.gserviceaccount.com
```

プロジェクト番号はGCPコンソールのHOMEから確認できる。

# 設定箇所
１．GCPコンソールの左ペインから「Storage」を選択し、コピー元のファイルがあるバケットを選択する。
２．権限⇒メンバーの追加をクリックする。
![権限、メンバーの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169814/fa785d82-9c88-55b2-6995-4fc237ff6607.png)


３．権限を追加する。コピーしてくるだけであれば役割は「ストレージオブジェクトの閲覧者」でよい。
![権限追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169814/caad0c82-d534-5952-fd6a-428c83e74e5b.png)

これでBプロジェクトに作成したComputeEngineからgsutilコマンド等でストレージのファイルをコピーすることができます。
Nuxt × Vuetifyの状況下でv-btnをnuxt-linkにして使いたい

## はじめに
最近Vue.jsをまたやり始めました.今は記憶を取り戻す作業をしています. 以前はvue-cliで頑張ってましたがNuxt.jsやらVuetifyやらいろいろ使いはじめました.

## 環境
```
Vuejs - 2.6.10
Nuxtjs - 2.8.1
Vuetify - 1.5.16
```
## 簡単な説明
### Vuetify
[Vuetify](https://vuetifyjs.com/ja/)
VuetifyはVue.jsで使えるUIコンポーネントフレームワークです.SSR,SPA,PWA対応でいい感じにUIを作れます.
### nuxt-link
[API: nuxt-link](https://ja.nuxtjs.org/api/components-nuxt-link/)
Nuxt.jsで使えるコンポーネントです.`<nuxt-link>`はVue Routerの`<router-link>`を拡張したものになります.ブラウザの表示領域に`<nuxt-link>`が表示されればそのリンク先を先読みしといてくれるというすぐれものです.

```vue
<nuxt-link to="/path/to/page">このサイトについて（Nuxt アプリケーション内部リンク）</nuxt-link>
```
こんな感じで[Vue Router](https://router.vuejs.org/api/#router-link)の`<router-link>`みたいに使えます.タグに追加できる属性についてはVue Routerのリファレンスを見てみましょう.



## v-btnのリンクでもnuxt-link使いたい
v-btnはVuetifyのコンポーネントの一つで,簡単にきれいなボタンを実装できます.
でもv-btnのリンクをnuxt-linkにしたい時にちょっとよくわからなかったです.
nuxt-linkでv-btnを囲っても(また,その逆も)レイアウト崩れてしまって変になっちゃいます.
一応`<nuxt-link tag="v-btn" to="/pass/to/page">`とかも無理です.
どうしたらええんや.

## 結論
こうすればいいだけです.

```vue
<v-btn to="/pass/to/link" nuxt>リンク</ v-btn>
```

[ドキュメント](https://v15.vuetifyjs.com/en/components/buttons)のv-btnのAPIにはこう書かれています.
>nuxt
Specifies the link is a nuxt-link

nuxtプロパティはリンクがnuxt-linkであることを指定します.

## Vuetifyのドキュメントは英語を読め
ドキュメントあるあるかも知れませんが特にVuetifyのドキュメントは英語の方を見ましょう.すべてがそこにあるので.
<img width="400"alt="英語ドキュメント" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344098/181361d1-ce8d-8985-df2d-bba2da673fdd.png">
[英語ドキュメント: v-btn](https://v15.vuetifyjs.com/en/components/buttons)

<img width="400"alt="日本語ドキュメント" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344098/b0122e31-7bc0-df87-a0c4-a2b563493c40.png">
[日本語ドキュメント: v-btn](https://v15.vuetifyjs.com/ja/components/buttons)

v-btnとかはまだ書いてる方ですが
調子が悪い時は`Components.Buttons.`と書いてしのいでいます.

## まとめ
* これを使えばv-btnをnuxt-linkにできる.

```vue
<v-btn to="/pass/to/link" nuxt>リンク</ v-btn>
```
* 英語のドキュメントを見よう.
s3:ObjectCreated:*でお手軽クラウド死

どうも170万円爆死男です。

170万円について詳しくは[こちら](https://www.slideshare.net/shinichitakahashi790/athena-74059026)

さて、また死にそうでした。
前回はボーナス査定の直前でしたが、今回は直後ということもあり気持ちも穏やかに死にそうになったのでシェアします。

---

#### 手順

1. s3:ObjectCreated:* なイベントでLambdaとS3をつなぐ
2. Lambda内で s3.upload() する
3. 無限ループ！


さて、冒頭で死に `そう` と表現したのは死ななかったからなんですが、いくつか繰り返すうちに止まりました。
Amazonたん素敵な配慮をｻﾝｷｭ♡と思ったんですが、厳密には違う理由です。

今回は幸運にも元ファイル名のサフィックスをつける仕様でつくっていたため、何回か実行した後に `KeyTooLongError` を吐いて死んでました。

ソースはこんだけ

```ts
new S3().upload(
  Bucket: bucket,
  Key: `${org.Key}.lock`
).promise()
```

もうおわかりだと思いますが、

1. originalFilenameをUpload
2. originalFilename.lockがつくられ
3. それが原因でoriginalFilename.lock.lockがつくられ
4. それが原因でoriginalFilename.lock.lock......

ってことです。
もし同名ファイル作ってたら発覚も遅れるしログだけガリガリ増えて死ぬところでした。
そうなったら一応Lambda消せばとまりますが、マジで気をつけろよ！！！！！！！！！！！！
ubuntu 20.04 / 18.04 に pyenv をインストールする話


# 前置き

最近WSLがブームですね．windowsでunixを実行できるようになって，デュアルブートや仮想環境を用意する必要がなくなり，速度もそこそこ出るのは嬉しい．．．microsoft，unixコミュニティさまさまです．

ということで，Ubuntuにpythonのバージョン管理を行うpyenvをインストールする手順を載せました．

:::note warn
最新情報はZennにアップロードしています。
https://zenn.dev/neruo/articles/install-pyenv-on-ubuntu
:::

# 実行環境

- ホストOS：Ubutu18.04.05
    - shell: bash
- ホストOS：windows10(ビルド20161)
    - WSL2：Ubuntu 18.04
    - WSL2：Ubuntu 20.04
- pyenv: v2.0.3(2021/07/05時点)

# 事前準備

次のコマンドを管理者権限で実行し，PCを再起動してください．WSLの場合はログアウトし，もう一度サインインしてください．

```{shell}
sudo apt update
sudo apt upgrade
```

# インストール手順

手順1. 必要ライブラリをインストールし，再起動します．

- build-essential: c++ compiler
- libssl-dev: openssl
- liblzma-dev: pandas
- libbz2-dev: bz2
- libreadline-dev: readline
- libsqlite3-dev: sqlite3
- libopencv-dev: opencv
- tk-dev: tkinter

```{shell}
sudo apt install -y \
build-essential \
libffi-dev \
libssl-dev \
zlib1g-dev \
liblzma-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
libopencv-dev \
tk-dev \
git
```

手順2. pyenvパッケージをインストールします．

```{shell}
# pyenv本体のダウンロードとインストール
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

# (Option)pyenvのバージョンをv2.0.3に変更
cd ~/.pynev
git checkout v2.0.3

# .bashrcの更新
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
source ~/.bashrc
```

手順3. Ubuntuを再起動した後，pyenvを確認し，pythonをインストールします．

```{shell}
# pyenvがインストールできたかを確認
pyenv -v 

# pythonのインストール
pyenv install 3.8.6 # 例えば，version 3.8.6
pyenv versions # インストール済みのpyenvのバージョンを確認できる
# pyenv local 3.8.6 (任意のディレクトリで実行)
```

# 参考文献

ありがとうございました．
- [Pyenvを使用してUbuntuにPythonをインストールする](https://qiita.com/micheleno13/items/39ad85cfe44ca32f53ee)
- [【pyenv】ubuntu16.04でのpython環境の構築](https://qiita.com/banaoh/items/00aea13fe045fab7e8ba)
- [Ubuntu 15.10 で pyenv install 3.5.0 したら pip がインストールできなくて落ちる](https://qiita.com/utgwkk/items/bf282ca95f64ef7dd594)
- [PythonでTkinterがimportできなかった](https://qiita.com/4hiziri/items/aba80f0bc92300ea22e2)
sqlでの集計について教えてください。

元々あったテーブルをsumとかgroup byでなんとかこの形のテーブルにまでしたんですが、この先どうすればいいのか、次にどんなクエリや、関数を使えば答えを出せるのか、教えていただけないでしょうか？

| ID | 購入数 | 購入日 | 購入額 |
|--:|--:|:--|--:|
| 1 | 7 | 2018-10-11 | 2205 |
| 1 | 4 | 2018-10-12 | 1260 |
| 22 | 5 | 2018-10-11 | 1575 |
| 1225 | 1 | 2018-10-11 | 500 |
| 2451 | 1 | 2018-10-11 | 500 |
| 2451 | 1 | 2018-10-12 | 500 |
| 2453 | 3 | 2018-10-11 | 945 |
| 2456 | 2 | 2018-10-11 | 630 |
| 2460 | 6 | 2018-10-11 | 1890 |
| 2462 | 1 | 2018-10-11 | 315 |


というテーブルがあったとき、最終的に

|最初に購入した数 | 購入した合計人数 | 合計購入額 |
|--:|--:|:--|--:|
| 1個 | 7 | 2205 |
| 2個 | 4 | 1260 |
| 3個 | 5 | 1575 |
| 4個 | 1 |  500 |

という形にしたいです。（この最終の数値は適当です）
この形にするにはどういうクエリを書いていけばいいのか、ご教授いただけないでしょうか？

よろしくお願いします。
javascriptで分数クラス

C#でも分数class
https://qiita.com/HitsujiRere/items/e49275a42ddda92b510c

こんな記事を見たのでjavascriptで書いてみた。

が、javascriptの場合は数値が整数とは限らないので、小数を渡されることも考慮する必要がある。

そこでこんな感じになった。


```javascript
const fraction = class {
  constructor(numerator=0, denomitor=1){
    this.n = numerator;
    this.d = denomitor;
    fraction._reduce(this);
  }

  /** 約分 */
  static _reduce(o) {
    const m = fraction._integerizable(o.n, o.d);
    o.n *= m, o.d *= m; // 小数が渡されたら分子分母を整数化
    const g = fraction._gcm(o.n, o.d);
    o.n /=g, o.d /=g;   // 最大公約数で除算
  }
  static _gcm(n, d) {
    for(let i = Math.min(n,d); i > 1; i--) if(n%i==0 && d%i==0) return i;
    return 1;
  }
  static _integerizable(n, d) {
    for(let m = 1; m < Number.MAX_SAFE_INTEGER; m++)
      if (m*n%1==0 && m*d%1==0) return m;
    throw new Error("overflow while reducing ("+n+","+d+")");
  }

  toString()  { return this.n + (this.d>1?("/" + this.d):""); }
  numerize()  { return this.n / this.d; }
  valueOf()   { return this.numerize(); }

  add     (other){
            return new fraction(
                     this.n * other.d + other.n * this.d, 
                     other.d * this.d
                   );
          }
  subtract(other){ return this.add(new fraction(other.n * -1, other.d)); }
  multiply(other){ return new fraction(this.n * other.n, this.d * other.d); }
  divide  (other){ return this.multiply(other.reciprocal()); }

  reciprocal(){ return new fraction(this.d, this.n); }
```

出来上がったらとりあえずテスト。

```javascript
const test = (arr)=> arr.forEach(f=>{
  const t=(a,b)=>{
    const stra = a.toString();
    const strb = b.toString();
    console.log(stra + " * " + strb + " = " + a.multiply(b));
    console.log(stra + " / " + strb + " = " + a.divide(b));
    console.log(stra + " + " + strb + " = " + a.add(b));
    console.log(stra + " - " + strb + " = " + a.subtract(b));
  };
  t(f.a, f.b); t(f.b,f.a);
});

test([
  { a:new fraction(5),   b:new fraction(1,2) },
  { a:new fraction(2,3), b:new fraction(1,6) },
  { a:new fraction(1,2), b:new fraction(1,2) },
  { a:new fraction(1/3), b:new fraction(3)   }
]);
```

今回の気づきとしては｢javascriptでは無理数が近似値に有理化されてしまっている｣ということ。

```javascript
[ Math.PI, Math.sqrt(2) ].forEach(e=>{
  console.log(e);
  const o = new fraction(e);
  console.log(o);
  console.log(o.numerize());
});
// Math.PI:      fraction {n: 245850922, d: 78256779}
// Math.sqrt(2); fraction {n: 131836323, d: 93222358}
```

ついでに小数の文字列表現からもインスタンス化できるようにしてみたが、

```javascript
fraction.fromString(exp) {
  const arr = exp.split(/[ \/]+/).filter(e=>e.length).map(e=>Number(e));
  if(arr.length < 2) arr.push(1);
  return new fraction(arr[0], arr[1]);
}
```

こっちの方が簡単だわな。

```javascript
fraction.fromString(exp) {
  return new fraction(Number(eval(exp)));
}
```
コマンドラインから PDF ファイルの差分を確認する

初投稿です。PDF ファイルの差分を確認したいときちょくちょくってありますよね。PDF で提供されるマニュアルの改訂版を確認するとき、どこが改訂されたのかがわからず困ってしまいます。そんなあなたにおすすめなのが [diff-pdf](https://vslavik.github.io/diff-pdf/) です。PDF の差分をテキスト・画像の両面から知ることができます。GUI 表示はもちろん、CLI 環境で実行し結果を PDF ファイルとして出力もできます。便利ですね！

![スクリーンショット](https://vslavik.github.io/diff-pdf/screenshot.png)
(出典：[公式 GitHub Pages](https://vslavik.github.io/diff-pdf/))

クロスプラットフォーム対応で、Windows 版はバイナリとしても提供されています。本稿では Linux 版のコンパイル方法を中心に記載していきます。

## インストール

Debian 11 を想定しています。

### 前提：依存性を解消する

ビルドと実行に必要なパッケージをインストールします。wxWidgets はクロスプラットフォームな GUI ライブラリです（[参考](https://qiita.com/496_/items/3c2929bc296d39ce708c)）。diff-pdf も wxWidgets3 を利用しています。GTK3 は wxWidgets が、poppler は diff-pdf が依存しているパッケージです。

```bash
apt install automake git g++ libgtk-3-dev libwxgtk3.0-gtk3-dev libpoppler-glib-dev make
```

### diff-pdf をコンパイル＆インストールする

1. `git clone` する

    ```bash
    cd ~
    git clone https://github.com/vslavik/diff-pdf.git
    ```

2. `bootstrap` と `configure` を実行する

    ```bash
    cd diff-pdf
    ./bootstrap
    ./configure
    ```

3. コンパイル＆インストール

    ```bash
    make install
    ```

4. 動作確認

    ```log
    root@0a840f01fc92:/tmp# diff-pdf --help
    Usage: diff-pdf [-h] [-v] [-s] [-m] [-g] [--output-diff <str>] [--channel-tolerance <num>] [--per-page-pixel-tolerance <num>] [--dpi <num>] [--view] file1.pdf file2.pdf
    -h, --help                            show this help message
    -v, --verbose                         be verbose
    -s, --skip-identical                  only output pages with differences
    -m, --mark-differences                additionally mark differences on left side
    -g, --grayscale                       only differences will be in color, unchanged parts will show as gray
    --output-diff=<str>                   output differences to given PDF file
    --channel-tolerance=<num>             consider channel values to be equal if within specified tolerance
    --per-page-pixel-tolerance=<num>      total number of pixels allowed to be different per page before specifying the page is different
    --dpi=<num>                           rasterization resolution (default: 300 dpi)
    --view                                view the differences in a window
    ```

## 使い方

### CLI

```bash
diff-pdf --output-diff=差分.pdf 比較元.pdf 比較先.pdf
```

### GUI

```bash
diff-pdf --view 比較元.pdf 比較先.pdf
```

## 参照

* [wxWidgetsの紹介](https://qiita.com/496_/items/3c2929bc296d39ce708c)
* [Automakeでmakeする](http://www.02.246.ne.jp/~torutk/cxx/automake/automake.html)
FirebaseのDebugViewの使用方法について


## Firebase(DEBUBVIEW)の使用方法

```
DebugView を使用すると、開発端末上のアプリによってロギングされる生のイベントデータをほぼリアルタイムで見ることができます。開発のインストゥルメンテーション フェーズにおける検証に役立ち、アナリティクスの実装でのエラーを検出するとともに、イベントとユーザー プロパティがすべて正しくロギングされていることを確認するのにも便利です。
```

公式リファレンス
https://firebase.google.com/docs/analytics/debugview?hl=ja

## 環境準備から実行までの手順

### 1)コマンドラインツールをインストールする
ADBコマンドを実行するための環境を用意する。AndroidStudioをインストールしている場合はSDKもありADBコマンドも使えるため不要

下記ページより環境別zipをダウンロードしインストールを行う
https://developer.android.com/studio/releases/platform-tools.html

### 2)sdkのパスを通す
.zshrcやbashrc系でパスを通す

```
export PATH=~/Library/Android/sdk/platform-tools:$PATH
```
※パスは各環境に合わせること（インストールした場所）

adbコマンドが使えれば成功。

### 3) アプリをインストール
アプリをインストールする
GoogleプレイでもAPK直でもOK

### 4)FirebaseのDebugViewページをブラウザで開く

各環境別にコンソール画面から選択して開く。先頭ページから環境毎でページを開く。

先端ページ
https://console.firebase.google.com/u/0/

### 5)ターミナルを立ち上げる
デフォでもitermでもなんでもいい

### 6) 端末に接続

下記のADBコマンドをターミナルで実行する。
問題ない場合はエラーなど出ない

#### QAデバッグ
```
adb shell setprop debug.firebase.analytics.app [パッケージ名]
```

### 7)  4)で開いているブラウザでDebugViewを確認
何かしらの操作を対象アプリで行うと反映してログが表示される。
注意として4)と7)をインストールしたアプリの環境に合わせること
【Vue.js, TypeScript】グローバル変数を拾いたい

webpackされたVue.js + TypeScriptのComponentからグローバル変数を拾うための備忘録です。

ページの一部要素をコンポーネント化し、値をサーバー側でレンダリングして渡したいという要件がありました。
その値を使いたいコンポーネントは複数に渡るため、propsにいちいち渡すのも面倒です。

# Vue.js公式では
[インスタンスプロパティの追加](https://jp.vuejs.org/v2/cookbook/adding-instance-properties.html)
> 多くのコンポーネントで使用したいデータ/ユーティリティがあるかもしれませんが、グローバルスコープを汚染したくはありません。
この場合は、プロトタイプに追加すれば全ての Vue インスタンスで使用できます

グローバルは汚染したくないので、以上のようにprototypeを生やして拾えればよさそうです。

# TypeScriptではうまくいかない
生のJSであればうまくいくのですが、TypeScriptが絡むと

```index.html
Vue.prototype.$config = {
    isLogon: true,
}
```
```App.vue
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  data(): {
    isLogon: boolean;
  } {
    return {
      isLogon: this.$config.isLogon, // ここで怒られる
    }
  }
})
</script>
```
そんなプロパティはないよって怒られてしまいました。

# TypeScriptの定義ファイルを用意して解決
直接拾えないことがわかったので、定義ファイルを用意してあげました。

```index.html
Vue.prototype.$config = {
    isLogon = true,
}
```
```App.vue
<script lang="ts">
import Vue from "vue";
import Config from "../config"; // 定義ファイルをimport
export default Vue.extend({
  data(): {
    isLogon: boolean;
  } {
    return {
      isLogon: this.$config.isLogon,
    }
  }
})
</script>
```
```config.d.ts
// 定義ファイルを用意
import Vue from "vue";
declare module "vue/types/vue" {
  interface Vue {
    $config: {
        isLogon: boolean,
    };
  }
}
```

無事グローバル変数を拾うことができました。
Gitの「.git」フォルダ(ディレクトリ)を削除した状態でcloneする方法は"ない"

# 結論
Gitの「.git」フォルダ(ディレクトリ)を削除した状態でcloneする方法は
**ありません。**

リポジトリの頭のディレクトリにある「.git」を手動で削除して下さい。
# 経緯
Gitの中にあるスクリプトファイルだけを渡したくて
Gitリポジトリからcloneしたのですが、
Gitの管理ディレクトリである「.git」が不要である事に気付き、

「.git」のディレクトリを除いてCloneする方法を調べましたが、
1.5hほど調べても見つかりませんでした。

# 対応
結論と同じ事を書いていますが、
git clone後にリポジトリの頭にある「.git」を手動で削除して下さい。

「.git」はsvnの「.svn」の様に各ディレクトリ毎に散乱しておらず、
頭(ルート)のディレクトリにしか存在しません。
安心して「.git」のファイルを削除して下さい。
ionicのion-split-paneの使い方

##はじめに
ionicを使うのに普通のサイドメニューを使うより使ったことのない技術を
使っていこーぜ的なノリでion-split-paneを使ってみたので
せっかくなので記事にします。
一応ドキュメントを貼っておきますが深くは掘り下げられてないですw
[ionicのドキュメント](https://ionicframework.com/jp/docs/api/split-pane)

##使う理由と使用例
app.component.htmlに書くと全ページに反映される。
非表示にしたいページもMenuControllerを使うと非表示設定可能。
ion-split-paneの特徴としてレスポンシブな対応を勝手にやってくれるのがすごい楽。
下記の様にブレークポイントを設定すると指定したブレークポイントでヘッダーメニューに隠れてくれるのでおすすめ


```app.component.html
<ion-app>
<!--  ここでブレークポイントを設定する。 when=""でmin-width指定かxsやxlの様なサイズ指定も可-->
  <ion-split-pane when="(min-width: 769px)">
<!--    このmenuIdで非表示にしたいページに設定を書くと非表示になる。後で説明します。-->
    <ion-menu menuId="custom">
      <ion-header >
        <ion-toolbar>
          <ion-title>Menu</ion-title>
        </ion-toolbar>
      </ion-header>
<!--      ここにメニュー内容書き書きします。-->
      <ion-content>
        <ion-list>
<!--          auto-hide="false"を書かないとメニューが表示されまてん。これ不具合らしい。-->
          <ion-menu-toggle auto-hide="false">
            <ion-item [routerLink]="['/home']">
              <ion-icon name="home"></ion-icon>
              <ion-label>home</ion-label>
            </ion-item>
          </ion-menu-toggle>
        </ion-list>
      </ion-content>
    </ion-menu>
    <ion-router-outlet main></ion-router-outlet>
  </ion-split-pane>
</ion-app>
```

##こんな感じになります
![ion-split.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311852/6bf4da73-ea29-9b4f-cbfa-3b538c1785b9.gif)

### メ ニ ューボタンをヘッダーに書き書き
このままでは画面幅が769pxを下回った際にメニューボタンが表示されないのでサイドメニューを表示させたいページに下記のコードを書き書きしましょう

```home.page.html
<ion-header>
  <ion-toolbar>
    <ion-title>
    </ion-title>
<!--    ここにボタンを書き書き。slotで表示させる場所を指定。-->
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>
<ion-content>
  <div class="ion-padding">
    The world is your oyster.
    <p>If you get lost, the <a target="_blank" rel="noopener" href="https://ionicframework.com/docs/">docs</a> will be your guide.</p>
  </div>
</ion-content>
```

###これでメニューボタンゲット！！
![split.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311852/5dfed6ce-c9b1-04a1-06d8-47892b87cd99.gif)
##非表示にさせたい場合
サイドメニューを非表示にさせたい場合ってありますよねー
ログイン画面とかねー
その場合は下記の様に設定してください。
MenuControllerを使ってion-split-paneで設定した
menuId="custom"がここで活用されます。

```hoge.page.ts
import { Component, OnInit } from '@angular/core';
import { MenuController } from '@ionic/angular';

@Component({
  selector: 'app-hoge',
  templateUrl: './hoge.page.html',
  styleUrls: ['./hoge.page.scss'],
})
export class HogePage implements OnInit {

  constructor(private menu: MenuController) {
    this.menu.enable(false, 'custom');
  }

  ngOnInit() {
  }

}

```

##終わりに
こんな感じでion-split-paneを使うと簡単にレスポンシブなサイドメニューを作ることが出来ます！
せっかくionicを使うならionic特有の物も使っていきたいですよね。
今後もionic特有の物を使う機会があったら記事書きます！
Kotlinで文字列の先頭・末尾から指定した文字列を削除する

# 文字列の先頭から指定した文字列を削除する

例えば、「Documents/hogehoge」という文字列から「hogehoge」を取り出したいときは、Stringクラスの拡張関数`removePrefix`メソッドを使います。
このメソッドは文字列の先頭から指定した文字列を削除します。

``` prefix.kt
val str = "Documents/hogehoge"
val newStr = str.removePrefix("Documents/") // "hogehoge"
```

これで「hogehoge」が取り出せます。

# 文字列の末尾から指定した文字列を削除する

例えば、「hogehoge.csv」という文字列から拡張子を取り除いた「hogehoge」を取り出したいときは、Stringクラスの拡張関数`removeSuffix`メソッドを使います。
このメソッドは文字列の末尾から指定した文字列を削除します。

``` suffix.kt
val str = "hogehoge.csv"
val newStr = str.removeSuffix(".csv") // "hogehoge"
```

これで「hogehoge」が取り出せます。

# 参考

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/remove-prefix.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/remove-suffix.html
carrier waveで画像投稿がうまくいかない

carrier waveを使う時に、画像が投稿できませんでした。

その結果、brewの image_magickがinstallされていないという結果になりました。
```
brew install imagemagick
```

これを実行すると、保存ができました。

ちなみに、保存できない時にbinding.pryして
@hoge.save!としてみるとsaveの際に出ているエラーなんかも見れるのでおすすめです。（それが解決策のエラーとは限りませんが）

自分の備忘録で書いてるので、超短めの記事・・・・。
stackドライバでProcessorに指定した項目をログ出力させる方法

# はじめに
Laravel 5.8のstackドライバを使ったら、Monologコンストラクタの第3引数に指定するProcessorが無視されるので、
コード読んでやり方調べたので残しとく。

# どーなってんのか

Illuminate\Log\LogManager::createStackDriver

```php

    protected function createStackDriver(array $config)
    {
        $handlers = collect($config['channels'])->flatMap(function ($channel) {
            return $this->channel($channel)->getHandlers();
        })->all();

        if ($config['ignore_exceptions'] ?? false) {
            $handlers = [new WhatFailureGroupHandler($handlers)];
        }

        return new Monolog($this->parseChannel($config), $handlers);
    }

```

Processor全く使ってない・・・以上

# やること
## 方針
* LogServiceProvider自前で準備。
* LogManager継承して自前のLogManager作成してそこに必要なモノを放り込む

### LogServiceProviderの実装
動機は、自前のLogManagerのインスタンスから生成したいからってだけ

LogServiceProvider

```php
class LogServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('log', function () {
            return new LogManager($this->app); // ← これが自分で作ったLogManagerになるだけ
        });
    }
}
```

### LogManagerの実装
stackドライバの生成方法をマネしてチョット変えるだけ

log channelからProcessorも取って返して、そのままMonologコンストラクタの引数に渡すだけ。
extraとして全部吐かれるから、ログチャンネルごとに細かく出し分けるとかできないけど、
自分の中ではこれで十分なので、この実装。

```php

class LogManager extends \Illuminate\Log\LogManager
{
    public function createCustomStackDriver(array $config)
    {
        $channels = collect($config['channels'])->map(function ($channel) {
            $channel = $this->channel($channel);
            return [
                'handlers' => $channel->getHandlers(),
                'processors' => $channel->getProcessors()
            ];
        })->all();

        $handlers = Arr::flatten(array_column($channels, 'handlers'));
        if ($config['ignore_exceptions'] ?? false) {
            $handlers = [new WhatFailureGroupHandler($handlers)];
        }

        return new Monolog($this->parseChannel($config), $handlers, Arr::flatten(array_column($channels, 'processors')));
    }
}
```

ちなみにここでProcessorを自分で生成すると、思った出力にならないヤツが居たりするので、
Processorの生成自体はカスタムログクラスで生成したものである必要がある。

> Arr::flatten(array_column($channels, 'handlers'));

は書き方が周りくどいから何か良い書き方教えて欲しいです。
for文ぐるぐるしてもいいんだけど・・・。

# 使い方

config/logging.php

以下を追加する

```php

'customStack' => [
    'driver' => 'customStack',
    'channels' => env('LOG_SLACK_WEBHOOK_URL', '') !== '' ? ['custom', 'slack'] : ['custom'],
],
'custom' => [
    'driver' => 'custom',
    'via' => \Oga\Logger::class,
    'path' => env('LOG_FILE_PATH') ?? storage_path('logs/app.log'),
    'level' => env('LOG_LEVEL', 'debug'),
    'days' => 14,
],
```

あとは.envのLOG_CHANNELにcustomStackを指定しとくだけ


# おわりに
stackドライバでProcessorの指定を有効にする方法でした。
TwitterAPIを叩いてみた！

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしています。
今回TwitterAPIを叩く方法を解説します。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください！

#TwitterAPIの利用方法
TwitterAPIを利用するためにはDeveloper申請を行う必要があります。
申請が認められると、トークンやキーを取得できるようになります。
下記のプログラムは「球宴」「オールスター」を検索して、検索結果にでてくるツイートを10個取得し、jsonファイルに書き込みます。

```python
import config
import json
from requests_oauthlib import OAuth1Session

# 各キーの読み込み
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET

# 認証処理
twitter = OAuth1Session(CK, CS, AT, ATS)

url = 'https://api.twitter.com/1.1/search/tweets.json'
keyword = ['#球宴', '#オールスター']
params = {
    'count' : 10,
    'q' : keyword,
    'tweet_mode': 'extended' # full text
}

req = twitter.get(url, params=params)


if req.status_code == 200:
    res = req.json()
    with open('response.json', 'w') as f:
        json.dump(res, f, ensure_ascii=False, indent=4)
    print('fin write a response')
else:
    print('Failed your requests, statu_code: {}'.format(req.status_code))
```
#まとめ
今回はTwitterAPIの利用方法についてご紹介しました。
これからも勉強を続けていきます！
BigQuery標準SQLで日付の加減をする

## やりたいこと
ある日付を起点に今日までと同じ日数遡った日付を取得する。
例：起点日付=2019/07/01　今日=2019/07/29

## 起点日付と今日の差分を取得する
### DATE_DIFF(日付1,日付2,単位)

```
 DATE_DIFF(CURRENT_DATE, '2019-07-01', DAY)

=> 31
```

### DATE_SUB(DATE 日付 INTERVAL x 単位)
起点日から31日遡った日付を取得する。
DATE_SUBを使用すると指定した日付からx 単位を減算することができる。

```
SELECT
 DATE_SUB(DATE '2019-07-01', INTERVAL 28 DAY)

=> 2019-06-03

```
DATE_DIFFとDATE_SUBどちらも使用する。

```
SELECT
  DATE_SUB(DATE '2019-07-01', INTERVAL DATE_DIFF(CURRENT_DATE, '2019-07-01', DAY) DAY)

=>2019-06-03
```
adbコマンドでUnity製アプリを起動する

## はじめに

Buildした.apkを`$ adb install -r hoge.apk`した後に、端末上でアプリを起動するの面倒ですよね。そこでそのままadbコマンドでアプリを起動する方法を調べてみました。Oculus Go/Questの開発時とかにも使えるかもしれません。

## 方法

参考: [package名のみからadb shell am start -nする - Qiita](https://qiita.com/mattak/items/41b1ce1d48ddb3b2bb4a)

UnityではActivity名が`com.unity3d.player.UnityPlayerActivity`で固定なので、Package名だけ指定できれば良い。

## コード

```.bash
$ adb shell am start -n {Package Name}/com.unity3d.player.UnityPlayerActivity
```

Package NameはPlayer Settingで設定できる`com.Company.ProductName`みたいなやつです。

## 最後に

書いてて思ったんですけど、初めから`Build & Run`すればいいのでは…？

(同一apkを複数端末で起動する時とかに使えるかも…)
pythonのお勉強１２日目

###Blenderを初めて操作してデータをpythonで使う。
Python超初心者の備忘録です。
今回はBlenderでオブジェクトを作ることに挑戦してみました。
blenderは全く初心者です。
####流れ　
blenderをインストールする　
マニュアル、解説を読んで　データをpythonで読み込める形式で出力する。
pythonで読み込むsampleプログラムをネットで検索する。
windowsのpythonで結果を出力する。

###１　blenderをインストールする
   blenderで検索。https://blender.jp/ から　ver2.78bをDownload
   指示に従ってインストール
###２　オブジェクトを作り　stl形式で出力する。   
   
[Blender初心者が、コーヒーカップをモデリングしてみる。](https://qiita.com/yassyskywalker/items/18e8541079bfae2af0e7)が分かりやすいです。
 参考にさせてもらいました。有難うございました。この解説に従って、
オブジェクトをロードする。　
拡大（オブジェクトを選択した状態でSを押して拡大倍率をテンキーで指定。）
ファイルメニューのエクスポートから　stl 形式を選択して出力しました。
（ロード、拡大、エクスポートを逆引きで調べただけで　blenderのことはわからないので　全く初めての方には分かりづらいと思います）
###３　numpy-stl で　取り込めそうに思えたので 
pythonhosted.org/numpy-stl/usage.html のsampleで試してみましたが。WindowsのVisualStudioでは最初の２行目import文でエラーが出て先に進めませんでした。

```
from stl import mesh
from mpl_toolkits import mplot3d  
from matplotlib import pyplot

# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)

# Load the STL files and add the vectors to the plot
your_mesh = mesh.Mesh.from_file('tests/stl_binary/HalfDonut.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))

# Auto scale to the mesh size
scale = your_mesh.points.flatten(-1)
axes.auto_scale_xyz(scale, scale, scale)

# Show the plot to the screen
pyplot.show()
```
####Mac（anaconda) では問題なく出力できました。

<img width="496" alt="Screen Shot 2019-07-29 at 5.54.08 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435503/17452ae8-84ef-52f1-47c2-97f0c5177aeb.png">

Windowsでは別の方法を探してみました。　stl形式をtxt形式に変換してpythonに表示する記事を見つけたのでその方式を採用しました。
#####sabopy.com [matplotlib 3D]47.VoxelCactus 
の記事を参考にさせて頂きました。感謝です！Cactusとはサボテンのことです

（stlファイルは３Dプリンターで最も使用されているファイルフォーマットでオンライン上に３Dプリンターのサイトが多くあり無料のstlファイルサンプルも入手できると思います。）

blenderで作成したstlファイル　または　無料サンプルで入手したstlファイルを
stlファイルのオンラインファイル変換サイトでTXT形式を指定して変換する。
記事に掲載されたプログラムを実行。でできました。有難うございました。
個人的にはこちらの出力が気に入っています。
興味のある方は　sabopy.comで検索してみてください。
（マウスで記事を選択して右クリックで検索サイトへ）

####Windows のpythonで出力

![キャプチ4ャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435503/00905262-e194-80a4-4156-46add17821e7.png)
【Android】MVVMを導入したアプリにSocketServer開発のまとめ

### 前提
１対１の接続を前提とした仕様のアプリ開発のため、複数Socketの同時通信は考慮していません。
複数Socketの場面を対応できないではないが、設計上調整する必要がありそうです。

## 依存関係
View　→　Viewmodel　→　Usecase　→　Repository

## 実装方針
・UsecaseでSocketserverの基本操作を実装
・Main画面のviewmodelでSocketserverのインターフェースを実現して、通信内容のハンドルを実装
・受けとたメッセージに応じて、タスクを作成し、RxJavaのBehavior経由で各サブ画面のViewmodelで処理を行う
・逆の場合に各サブ画面がRxJavaのBehavior経由で送信相手とメッセージをMain画面のViewmodelへ送信

## 状況よりの変形
・要件：
　メッセージを受け取る　→　view経由で別Viewmodelの処理を呼びだす　→　処理の戻り値を通信相手に送信
・本来は：
　MainViewModelで受け取り、処理タスクを生成し、個別画面へ送信
　個別画面で処理し、返信タスクを生成し、Main画面へ送信
・経緯：
　確実に返信したいに結果待ちのTimeoutを書きたくない
・変形後：
　MainViewModelから親のViewを呼び出す　→　Viewから別Viewmodelを呼び出す　→　目標処理を行い結果をMainViewModelへ返却　→　結果を相手に送信

## 感想
・処理タスクは基本一方的にRepositoryへの呼び出しのみですが、上記要件のため、別Viewmodelの関数を呼び出した、よくなさそう
・Viewmodel間の呼び出しはよくなさそう
・MVVMを導入したせいでソースはきれいになりましたが、制限もでできました。
Pgadminでトランザクションがアボートしたときには

この対応に苦慮していたのですが、実はこれだけで解決します。Pgadminを操作していると、このメッセージに遭遇することがあります。


**トランザクションがアボートしました**


そんなときは、PgadminのSQLビューアを開いて、これだけを記述してクエリを実行してください。

```
commit;
```

こうすれば、再びSQLコマンドを受け付けるようになります。ちなみにアボートとは休止、中断という意味です。

# どういうことなのか？
postgreSQLは基本、トランザクションの実行とデータ更新を分けており、commitコマンドの実行によって、初めて挿入、更新、ロールバック（差し戻し）などの更新処理が実行されます。そして、基本はauto commitがデフォルトとなっています。

そして、データを挿入、更新しようとしてクエリを記述して命令しても、制約などに違反（同値のユニークキーを挿入しようとした、設定カラム数以上のカラムを挿入しようとした、など）が生じると、エラーメッセージが表示され、クエリ実行時に記述された**命令すべてをロールバック（差し戻し）する**仕様になっており、一旦、待機状態となります。

したがって、**auto commit(自動コミット)を何らかの理由でオフに制御している**と、一度待機しているロールバックを実行しないと、以後のコマンドを一切受け付けつけてくれずに、トランザクションがアボートしましたと、上記のメッセージが表示されることになります。

ですが、その解決策として`commit;`という命令文を一つ記述するだけでロールバックを実行してくれるので、SQL文にcommitと記述すればいいのです。

# データが反映されない場合
こっちも知らないと引っかかりがちですが、auto commitをOFFにしている場合、insert文やupdate文、delete文やalter文などといった**データ更新に関する命令文をクエリで実行した後**は、必ず最終行に

```
commit;
```

この一行を忘れないでください。これを行わないとデータ更新処理を受け付けてくれなくなり（というより、コミット《実行》されていないので、待機状態となっている）トラブルの元になります。そして、このcommitを受け付けていない状態で、新たなデータ更新に関わるSQL文を実行したりすると同様にトランザクションがアボートしてしまいます。

ですので、Pgadminは必ず

::: note
**結果にコミットすること**
:::

これを心がけましょう。~~それが言いたいだけだろ自分~~

※select文はデータを呼び出すだけなので、命令実行後にcommitはなくても問題ありません。

# そもそものトラブルを防止したい
安全対策などでautocommitをoffに制御していない限りは、**autocommitをon**にしておいたほうがいい気もします。セキュリティ的なリスクより、commitを忘れ、必要なデータを投入、更新できていない（特に定期的にメンテをかけたりするケース）ことの方が問題が大きくなると判断した場合はそのようにした方がいいでしょう（要はどちらに重きを置くかです）。

### auto commitをSQLで修正するためのコマンド
```
postgres=# \set AUTOCOMMIT on
postgres=# \echo :AUTOCOMMIT
on                                   /*このように表示される
```

このように定数に代入されて表示されますので、AUTOCOMMITは**必ず英半角大文字**にしてください。小文字にするとただ、`:autocommit`という文字列をechoするだけになります。

# 参考になったサイト

- [技術/PostgreSQL/メモ](https://www.glamenv-septzen.net/view/726)
SQSのメッセージをトリガーにLambdaを起動する

#1.SQSの作成#
lambda-queue という名前で作成しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/fd5b4e14-7f17-ebcf-f977-03200fccf9c6.png)


#2.Lambda用Roleの作成#
Lambdaに「AWSLambdaSQSQueueExecutionRole」のポリシーをアタッチする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/71db7d12-589b-ab73-656c-c5a27df8d9b7.png)


#3.Lambda関数の作成#
python3.6、IAMロールは「2.Lambda用Roleの作成」で作成したものを指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/8acc2c41-18b2-9600-57f3-8318c0031195.png)

「1.SQSの作成」で作成したSQSキューを選択し、「有効」にする。
![スクリーンショット 2019-07-29 18.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/843fb405-9113-96cb-52e0-66c587533811.png)


Lambda関数を入れる。

```
from __future__ import print_function
 
def lambda_handler(event, context):
    for record in event['Records']:
       print ("test")
       payload=record["body"]
       print(str(payload))
```


#4.実行確認#
SQSからメッセージの送信。
![スクリーンショット 2019-07-29 18.28.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/a5fbfab0-da1d-6f98-f248-d91d028ce4c2.png)

CloudWatchlogsを確認して、Lambda関数が実行されているか確認しましょう。
![スクリーンショット 2019-07-29 18.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4ad759a8-cf96-d1e9-1e75-de594fae3d78.png)
Railsの初期データを投入する方法

# シードファイルを使う

ごく一般的な方法はシードファイルで初期データを入れる方法です。

```ruby:db/seeds.rb
users = ["太郎", "花子", "次郎", "京子"]
users.each do |user|
  User.create(name: user)
end
```

`seeds.rb` に初期データを記述して、コマンド `bundle exec rails db:seeds` を叩けば `User` テーブルに投入されます。

## シードファイルの問題点

後々になって追加で初期データを投入したい場合、すでにテーブルにある初期データを削除して、いちから入れる必要があるが、データを削除するのは怖さがある。

```ruby:db/seeds.rb
# users テーブルを trancate
ActiveRecord::Base.connection.execute('TRUNCATE TABLE `users`')

users = ["太郎", "花子", "次郎", "京子", "三郎"] # 三郎が追加
users.each do |user|
  User.create(name: user)
end
```

開発環境ならこれでもいいが、本番環境でこんなことはしたくない。
なので、もっと安全な方法で初期データを投入する。

## マイグレーションファイルを使う

みんな大好きマイグレーションファイルで初期データを投入する。

### コマンドでマイグレーションファイルを作成

```bash
$ bundle exec rails g migration insertInitialUsers
```

### マイグレーションファイルに投入したいデータを追加

```ruby:db/migrate/xxxxxxxxxxxxxx_insert_initial_users.rb
class InsertInitialUsers < ActiveRecord::Migration[5.2]
  def change
    users = ["太郎", "花子", "次郎", "京子"]
    users.each do |user|
      User.create(name: user)
    end
  end
end
```

### マイグレーションを実行

```bash
$ bundle exec rails db:migrate
```

これで初期データの投入が完了する。
そしてシードファイルで問題になっていた、追加で初期データを投入する場合は新しくマイグレーションファイルを作り、追加分のデータだけ記述すればよい。

```bash
$ bundle exec rails g migration addInitialUsers
```

```ruby:db/migrate/xxxxxxxxxxxxxx_add_initial_users.rb
class InsertInitialUsers < ActiveRecord::Migration[5.2]
  def change
    users = ["三郎", "佳子"]
    users.each do |user|
      User.create(name: user)
    end
  end
end
```

これによって、本番環境へのデプロイ時にマイグレーションが実行されれば、そのまま初期データの投入が完了される。
QNAP NASのディレクトリをUbuntuサーバにautofsでマウントする

#概要
本記事では、NASの任意のディレクトリをUbuntuの計算機サーバにマウントした手順をまとめる。

※ QNAP NAS自体の導入方法は書かない。[参考にさせて頂いたサイト](https://www.forcemedia.co.jp/blog/initial-setup)だけ載せておきます。
※ autofs自体の導入方法は書かない。



#経緯
所属研究室では、ZFSというNFSサーバサービスを用いて、ファイルサーバの大容量ディレクトリを複数台の計算機サーバ（Ubuntu16.04.3）に共有するという構造をとって来たが、先日ついにファイルサーバの容量が足りなくなってしまった。
自前でファイルサーバを立てるのは大変なので既製品に頼ることにし、QNAP NAS TS-453Beを購入した。



## NAS側の設定
### NFSサービスを有効にする

1. ブラウザにNASのIPアドレスを入力し、管理webページに接続する
1. 管理者権限のユーザ名とパスワードでログインする
1. コントロールパネル>ネットワークサービスとファイルサービス>Win/Mac/NFS>NFSサービス を開く
1. 利用したいバージョンのNFSにチェック（NFSv2・NFSv3/ NFSv4）
1. 適用ボタンを押下



### 共有したいフォルダにNFSアクセス権を設定
1. コントロールパネル>権限設定>共有フォルダ
1. マウントしたい共有フォルダの「アクション」欄の「共有フォルダ権限の編集アイコン」を押下
1. 権限タイプの選択で「NFSホストのアクセス権」を選択
1. アクセス権にチェック
1. 権限を適宜変更
1. 適用ボタンを押下



## 計算機サーバ側の設定
所属研究室ではNFSクライアントサービスとしてautofsを利用しているので、これを用いてマウントを行う。


### autofs とは
[AUTOFSの紹介ページ](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/storage_administration_guide/nfs-autofs)

autofsは、共有ファイルの自動マウントおよび自動アンマウントをしてくれるautomountシステムである。

NFSクライアントサービスとしては、`apt install`できる`nfs-common`などが一般的？であるらしい。そのようなパッケージを用いる場合、/etc/fstab というファイルにNFSサーバやマウント先のパスの設定などを書き、ディレクトリの共有を行う。
しかし、/etc/fstab を使用した場合だと、ユーザーが NFS でマウントしたファイルシステムにそれほど頻繁にはアクセスしなくても、システムにはその使用頻度に関係なくマウントしているファイルシステム専用のリソースを維持しなければならないという弱点がある。

これに対し、automountシステムは自動的にマウント・アンマウントを行うので、システムのリソースを節約することができるという利点がある。

autofs は、デフォルトの主要設定ファイルとして /etc/auto.master (マスターマップ) を使用し、マウント設定は/etc/auto.hogeに書く。


### NFSクライアント側の設定

1. /etc/auto.hogeファイルを編集。管理者権限が必要。
1. `$ sudo /etc/init.d/autofs restart` にてautofsを再起動。

/etc/auto.hogeの書式は`mount-point [options] location`で、例えば以下のようになる。

```
/nas_home    -fstype=nfs,rw,noacl,rsize=32768,wsize=32768    192.168.0.2:/homes # nas
```

ここで、オプションの意味は

- rw:読み込み書き込み可、
- noacl:ACP の処理をすべてオフにする、
- rsize及びwsize:NFS 通信の読み込み (rsize) と書き込み (wsize) のときに一度に転送するデータブロックサイズ (バイト単位) 。NFSv3 のデフォルト値はいずれも 8192、NFSv4 のデフォルト値は 32768 。


# 参考
- [NFSにてNASの共有ディレクトリをマウントする方法](https://www.forcemedia.co.jp/support/qa/qnap/7645.html)
- [QNAP NASをubuntuとdebianからマウントする](http://wizqro.net/qnap-nas%E3%82%92ubuntu%E3%81%A8debian%E3%81%8B%E3%82%89%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%81%99%E3%82%8B/)
ImageMagickで全ての画像と同じサイズの単色画像を生成するシェルスクリプト

ImageMagicで、作業ディレクトリ内にある全ての画像と同じサイズの単色画像を生成するシェルスクリプトです。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162655/ebed6af4-14fd-4150-e511-cb93711e5213.png">

## 必要なツール
- `ImageMagick`

## ソースコード
このコードでは、JPGのみを対象画像に設定しています。（PNG、SVGでも動作確認済み）

```sh:create_gray_img.sh
#!/bin/sh

dir_name="gray_img"

# mkdir except exist
if [ ! -e $dir_name ]; then
    mkdir $dir_name
fi

for file in *; do
	# filter JPG only
	if [ ${file##*.} = "jpg" ]; then	

		# convert params
		size=`identify -format %wx%h ${file}`
		color="gray"
		slash="/"
		output_f_path=$dir_name$slash$file

		echo "Processing: ${file}"

		convert -size $size xc:$color $output_f_path
    fi
done
```

## 実行例

### 実行コマンド
```
$ bash create_gray_img.sh

Processing: onigiri.jpg
```

### 実行結果
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162655/77160e12-a55c-aa85-f63e-ab9406fdb4a7.png">

## なんで書いたの？
lazyloadで、ブラウザがオリジナルの画像をloadする前にpreloadさせておくダミー画像を作るために書きました。

preloadさせておかないと、ページ内リンクによるスクロールイベントで、画像サイズ分のズレが発生してしまいます。
もちろん、他にも回避方法はあります（[一例](https://github.com/verlok/lazyload#-tips--tricks)）が、表示する画像サイズが一定でない場合はこの方法が有効です。

ただ、preloadする画像の数だけRequestが増えるので、最善策ではない気がしてます。
やっぱり事前に画像サイズのパターン決めてcssで制御するのが良いのかな...？

他に良い方法を知ってる方がいたら教えてください🙏
LeetCode / Binary Tree Level Order Traversal II

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/07/29/181940)からの転載）

[https://leetcode.com/problems/binary-tree-level-order-traversal-ii/]

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

For example:

Given binary tree [3,9,20,null,null,15,7],
<img width="101" alt="スクリーンショット 2019-07-29 9.38.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/edb03401-d4a0-f459-9bfd-07c9fb5d81f4.png">
return its bottom-up level order traversal as:
<img width="100" alt="スクリーンショット 2019-07-29 9.38.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/33a6a893-3a51-6eb2-16ce-3fd1c55d6aaa.png">
Binary Tree Level Order Traversal "II"ということで"I"はどこいったんだという話ですが、"I"が難易度medium、"II"がeasyという謎順序になっているので、"II"から記事にします。

#### 解答・解説

##### 解法1
recursiveな解法。

```python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        res = []
        self.dfs(root, 0, res)
        return res

    def dfs(self, root, level, res):
        if root:
            if len(res) < level + 1: # n階層目に初めて到達したときにはリストを1つ追加する（n階層目にはn個のリストがあるなので、それより少ない場合は追加する）
                res.insert(0, []) # index0にリストを追加。こうすることで追加済みリストが古いものほど後ろになる（最後に全体をreverseする必要がない）
            res[-(level+1)].append(root.val)
            self.dfs(root.left, level+1, res)
            self.dfs(root.right, level+1, res)
```

##### 解法2
Iterativeな解法その1。
処理を行う順番待ちのリストqueueを作ってやり、そこにnode.left, node.rightを格納するIterationを回します。

```python
class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        res, queue = [], [root]
        while queue:
            res.append([node.val for node in queue if node])
            queue = [child for node in queue if node for child in (node.left, node.right)]
        return res[-2::-1]
```

細かな工夫として、root=[]でも全く同一のコードで処理できるように、res[-2::-1]でリストをreverseした上で初めの要素を削除する処理としています。

##### 解法3
Iterativeな解法その2。
型はdeque型ですが、順番待ちのリストqueueを作り、そこにnode.left, node.rightを格納するIterationを回すというやり方は解法2と全く同じです。
かつ、if node 以降の処理は解法1の考え方と同じ。
解法1と同様、最後にリストをreverseする必要がないのが計算量の点で優れています。

```python
from collections import deque
class Solution:
    def levelOrderBottom(self, root):
        queue, res = deque([(root, 0)]), []
        while queue:
            node, level = queue.popleft()
            if node:
                if len(res) < level+1:
                    res.insert(0, [])
                res[-(level+1)].append(node.val)
                queue.append((node.left, level+1))
                queue.append((node.right, level+1))
        return res
```
【CentOS7】CentOS7でIPv6をFirewalldで真面目に使う【Firewalld】

# はじめに
CentOS7(RHEL7系)のfirewalldを使用して、IPv6通信を許可するための設定手順についてちゃんと使ってる事例ないのかなぁと思ったのでメモをまとめました。

# 設定ファイル置き場
Zone: public の場合以下に置かれているかと思います
- /etc/firewalld/zones/public.xml
デフォルトではsshd,dhcpv6-client等のサービスのみかと思います

- 確認コマンド

```shell
$ sudo firewall-cmd --get-active-zones
public
  interfaces: eth1 eth0
trusted
  interfaces: lo
```

# デフォルト拒否
デフォルト拒否の設定の場合、zoneの設定ファイルの「zone　target」がDROPになっているはずです

```xml:public..xml
<zone target="DROP">
```
この場合、IPv6のいくつかの挙動はサービスに紐付かない場合は拒否されると思います。
例えば、
- アドレス付与がRA(SLAAC)の場合
- 同一セグメントユーザとの通信
- IPv6での名前解決
等

# IPv6の基本プロトコル許可
IPv6の基本プロトコル許可をする場合は、以下のようにすると
- リンクローカルユニキャストアドレス (fe80::/10)
- マルチキャストアドレス (ff00::/8)
などの通信を許容することができます

```xml:public..xml
<?xml version="1.0" encoding="utf-8"?>
<zone target="DROP">
  <short>Public</short>
  <description>hello</description>
  <interface name="eth0"/>
  <rule family="ipv6">
    <destination address="fe80::/10"/>
    <accept/>
  </rule>
  <rule family="ipv6">
    <destination address="ff00::/8"/>
    <accept/>
  </rule>
</zone>
```

# 適用
以下コマンドで適用

```shell
$ sudo firewall-cmd --reload
```

# IPv6サービスをアドレスで許可
IPv6サービスをアドレス＋ポートで許可するには以下を追加

```xml:public.xml
  <rule family="ipv4">
    <source address="xxx.xxx.xxx.xxx"/>
    <port protocol="tcp" port="443"/>
    <accept/>
  </rule>
  <rule family="ipv6">
    <source address="2xxx:xxxx:xxxx:xxxx::xxxx"/>
    <port protocol="tcp" port="443"/>
    <accept/>
  </rule>
```
Goで[]interface{}型のスライスを型ごとに分配する

GAE/Goを書いている時によく遭遇するので、リフレクションでかっこよく解決した。

# やりたいこと

```go
// いろんな型の構造体（のポインタ）が混ざったスライス
	list := []interface{}{
		&Dog{CanOte: true},
		&Cat{NowSleeping: true},
		&Shark{StarringMovie: true},
		&Dog{CanOte: false},
	}

// 型
type (
	Animals struct {
		Dogs   []*Dog
		Cats   []*Cat
		Sharks []*Shark
	}

	Dog struct {
		CanOte bool
	}

	Cat struct {
		NowSleeping bool
	}

	Shark struct {
		StarringMovie bool
	}
)


```
型を見て適切なフィールドにappendをしていきたい。

- DogをAnimals.Dogsにappend
- CatをAnimals.Catsにappend
- SharkをAnimals.Sharksにappend


同じ挙動をするコードはこれ。

```go

func appendEachObjects(animals Animals, list []interface{}) {
	for _, l := range list {
		switch m := l.(type) {
		case *Dog:
			animals.Dogs = append(animals.Dogs, m)
		case *Cat:
			animals.Cats = append(animals.Cats, m)
		case *Shark:
			animals.Sharks = append(animals.Sharks, m)
		}
	}
}

```


# リフレクションで解決するには

さて、いちいちcaseを増やしていくのはだるいのでリフレクションで解決する方法を考えた。

```go

func appendEachObjects(animals Animals, list []interface{}) Animals {

	defer func() {
		if e := recover(); e != nil {
			fmt.Printf("panic: %+v\n", e)
			fmt.Println("DataObjectsのフィールドの型がポインタのSliceではないと思います")
		}
	}()

	for _, i := range list {

		hpv := reflect.ValueOf(&animals)
		t := hpv.Elem().Type()
		n := t.NumField()
		for fieldIndex := 0; fieldIndex < n; fieldIndex++ {
			field := t.Field(fieldIndex)
			fieldType := field.Type
			if fieldType.Kind() != reflect.Slice {
				continue
			}
			match := fieldType.Elem().Elem() == reflect.TypeOf(i).Elem()
			if !match {
				continue
			}
			l := reflect.Append(hpv.Elem().Field(fieldIndex), reflect.ValueOf(i))
			hpv.Elem().Field(fieldIndex).Set(l)
		}
	}
	return animals
}

func Test_ObjectAppendEach(t *testing.T) {

	animals := Animals{}
	list := []interface{}{
		&Dog{CanOte: true},
		&Cat{NowSleeping: true},
		&Shark{StarringMovie: true},
		&Dog{CanOte: false},
	}
	actual := appendEachObjects(animals, list)

	if len(actual.Dogs) != 2 {
		t.Fatalf("犬が２匹ではなく%d", len(actual.Dogs))
	}

	if len(actual.Cats) != 1 {
		t.Fatalf("猫が１匹ではなく%d", len(actual.Cats))
	}

	if len(actual.Sharks) != 1 {
		t.Fatalf("サメが１匹ではなく%d", len(actual.Sharks))
	}

	if actual.Cats[0].NowSleeping != true {
		t.Fatalf("actual.Cats[0].NowSleepingがTrueではなく%T", actual.Cats[0].NowSleeping)
	}

}

```