OmniAICreator/Qiita-1.07M huggingface dataset:
Oculus Questの映像を今すぐテレビで見る方法

## 用意するもの
・Oculus Quest
・MacBook
・iPhone
・iPhoneの充電ケーブル
・HDMIケーブル(あれば)

## 手順①
iPhoneとMacBookをケーブルで接続します。

## 手順②
MacでQuickTimePlayerを起動します。
<img width="385" alt="スクリーンショット 2019-06-15 16.49.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/0c8a5c56-8045-3776-03be-6df18f86fc34.png">

そして新規ムービー収録を選択し
<img width="364" alt="スクリーンショット 2019-06-15 16.49.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/ed959992-f424-c7a9-f276-cfbe0820147b.png">

◯◯◯のiPhoneを選択します。
![スクリーンショット 2019-06-15 16.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/9a834d94-aeeb-e62e-f65c-1d49a45d0a03.png)


するとiPhoneの画面をMacに共有することができます。
![IMG_1401.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/6b49510c-d263-41f6-26a3-2c480ee2d328.jpeg)


## 手順③

Oculus Questのキャスト機能を使用し、iPhoneとOculusで画面を共有します。

あとはこのままMacで見るもよし、HDMIでテレビにつなぐもよし

![スクリーンショット 2019-06-15 17.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/43e6a2c1-34ec-a787-11c0-5ca391851c16.png)


## まとめ
手っ取り早く近くにあるもので画面共有するならこの方法が一番楽かと思いました。
他のHMDでも同じ手順で行けると思います。

それでは！👋
≪今さら≫ Python 言語仕様のイケてるところ、イケてないところ（Ruby比較）

#イケてるところ

###インデント:
インデントするとブロックになって省力化できるところなど。
（Ruby みたいにやたら end を書いたりしなくていい）

```py
for i in range(3):
    print(i)
```
(でも１行目のコロン ":" が本来要るのか？という小さな疑問は後述。。)

###その他のイケてるところ：
**たくさんありすぎて書ききれない。**

#イケてないところ

### 変数のスコープ
ブロック内でグローバル変数が気軽に使えてしまうという、
小さな親切が余計なお世話。
間違って使っても叱ってくれなくて、気づかずにハマる。

```py
q=1
def foo(p):
    print(q)

foo(2)
=> 1
```
ブロック外でグローバル変数という意識がなかった変数も
ブロック内で不意に未定義で使うとグローバルなスコープになってしまう。
**そんなこと勝手に解釈しないで、未定義だと言ってほしい。**

### クラス定義内の仮引数 "self"

```py
class Cls:
   def __init__(self, x):
      self.a = x
   def plus(self, b):
      return self.a + b
c = Cls(1)
c.plus(2)
```
self, self って自己主張強すぎ！
ついでに前述のコロン不要説も。

↓　情報量としては、こんな感じでいいのでは？

```py
class Cls
   def __init__(x)
      self.a = x
   def plus(b)
      return self.a + b
c = Cls(1)
c.plus(2)
```
Ruby な人なら 「'return' も不要じゃね？」となるんだけど、
それはさておき。

後者を **Rython** と名付けてPythonのプリプロセッサにしよか？（しないけど）
LuaTeXでのPDFバージョンと圧縮レベル

古い`LuaTeX`では`pdfTeX`の変数がそのまま使えたが、最近では使えない。対応策としては `\RequirePackage{luatex85}` するか

```latex
\pdfvariable minorversion 4
\pdfvariable compresslevel 0
\pdfvariable objcompresslevel 0
```

（圧縮なしPDF1.4）や

```latex
\pdfvariable minorversion 7
\pdfvariable compresslevel 9
\pdfvariable objcompresslevel 9
```

（最大圧縮PDF1.7）とする。
【phperのための"A Tour of Go"】のリンク集

# 【概要】

phperである筆者がgolangの勉強を[A Tour of Go](https://go-tour-jp.appspot.com/list) で行うにあたり、ExerciseをgolangおよびPHPにて解答することで言語の特徴やgolang, PHPの違いを考察していきたいと思います。phperの方でA Tour of Goをやって行く方は参考にしていただけると幸いです。
なお本記事は各記事へのリンク集となります。

# 【リンク集】

-  [Loops and Functions編](https://qiita.com/Suzuki_Cecil/items/c16cab4579757a684614)
-  [Stringers編](https://qiita.com/Suzuki_Cecil/items/af54fcf5e5aef544bf01)
-  [Fibonacci closure編](https://qiita.com/Suzuki_Cecil/items/f2ef1f2b40f92cc27244)
Module not found: Can't resolve 'react-redux' in 'xxx/yyy/zzz/src'と出てきたときの対処法

#<h1>初めに</h1>
Reactを使用してサンプルプログラムを作っていざ動かそうとしたときにエラーが出てしまい
せっかく作ったプログラムが動かない。

そんな経験エンジニアなら一度や二度ならずとも経験していると思う。

そこでこの記事ではodule not found:Can't resolve 'react-redux' in　＊＊＊
が出てきたときの対処法について書きたいと思う。

#<h1>対処法</h1>
./src/index.js
Module not found: Can't resolve 'react-redux' in 'xxxx/yyyy/react/memo/src'

こんなエラーが出てきてしまい、動かない。
そんなときはズバリ下記コマンドを実行してほしい

```
$ npm i -S redux
# OR
$ yarn add redux
```

```
$ npm i -S react-redux
# OR
$ yarn add react-redux
```


これであなたのプログラムも息を吹き返すのでは。

では、また次回の記事で
Ubuntu 18.04 on WSL を Ansible でプロビジョニングする

Ubuntu 18.04 on WSL 上に Ansible をインストールし、localhostのプロビジョニングを行います

# 環境
* Windows10 Home
  * Ubuntu 18.04 on WSL インストールが完了していること

# 手順
## 1. 必要なパッケージのインストール
```shell
sude apt update
sudo apt install -y python3 python3-pip
pip3 install --user --upgrade ansible setuptools virtualenv
```

## 2. Ansible Playbook の作成
playbook その他ファイルを作成します。ファイル階層は以下の通り

```
ansible/
 ├ hosts
 ├ host_vars/
 │  └ localhost.yaml
 └ playbook.yaml
```

```toml:ansible/hosts
[local]
localhost
```
```yaml:ansible/host_vars/localhost.yaml
ansible_python_interpreter: /usr/bin/python3
```
```yaml:ansible/playbook.yaml
---
- hosts: local
  connection: local
  tasks:
    - name: apt update/upgrade
      become: yes
      apt:
        autoclean: yes
        autoremove: yes
        cache_valid_time: 3600
        update_cache: yes
        upgrade: safe
```
ポイントは `ansible/playbook.yaml` 内の `connection: local` です。
これにより、プロビジョニングの際に localhost への SSH ログインを行わなくなるため、
Ubuntu on WSL の SSH サーバ起動が不要になります。

## 3. プロビジョニングの実行
```shell
ansible-playbook --ask-become-pass --inventory ansible/hosts ansible/playbook.yaml
```

# おまけ
Ansible のインストールから Playbook の実行までをシェルスクリプトとしてまとめたものを Github で公開しています（Ansible-Vault 対応）
https://github.com/epaew/init.wsl.ubuntu
cherry-pickコマンドの実行手順について

#cherry-pickコマンドとは？

cherry-pickコマンドとは、他のブランチ上にある特定のコミット内容を別のブランチ上に反映できるコマンドをいう。
このコマンドは、mergeコマンドのように全てのコミット内容を反映するコマンドとは異なり、余計なコミット内容まで取り込んでしまう恐れがないのでとても便利なコマンドである。

このコマンドを使えば、プルリクエストを細かく作り直したい時や誤って他のブランチ上でコミットしてしまった場合に役立つことができる。


#実行手順

##1.cherry-pickコマンドの使い方

cherry-pickコマンドを実行する前に以下のコマンドを実行する必要がある。

```
git checkout ブランチ名
```
git checkoutコマンドについては、以下の記事を参照ください。
https://qiita.com/yusukaaay/items/56de8e5f3f0d888906d1

また、ブランチ名が長かったり、複雑な表記で記憶してない場合は、以下のコマンドを実行すると、ブランチ名がターミナル上に表記される。

```
git branch
```


そして、cherry-pickコマンドの使い方は、以下のように実行する。

```
git cherry-pick　コミットID
```

##２.コミットIDの特定方法
そして、コミットIDを表示させるには、ターミナル上で以下のコマンドを実行する。

```
git log
```

すると、以下の画像のようにコミットIDの一覧が表示される。
https://gyazo.com/5c999344f08c260275ee3281f82095af

しかし、コミットIDの一覧だけ表示されても、コミット内容がなんなのか不明なことがある。そんな時は、ターミナル上で、以下のコマンドを実行する。

```
git log --stat
```
すると、以下の画像にように、コード修正を行ったファイル名や変更修正をどれほど行ったのかの一覧が表示される。
https://gyazo.com/b99c730ea2cdb51f2edcbf5a1a7308f5

また、目当てのコミットIDが見当たらない場合は、GitHub　Desktop上にて、コミットされているブランチ名と同じブランチ名のブランチに切り替えてみる。そして、再びターミナル上で、　git logコマンドを実行してみると表示されうる。

##3.競合が発生した場合について
コミットIDを特定して、cherry-pickコマンドした時、以下のような表示がターミナル上に出た場合、競合が生じています。

```
git cherry-pick 26151f9ee8......
error: could not apply 26151f9ee8......
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
```

競合を解消（解決）方法については、以下の記事を参照ください。
https://qiita.com/okamoto_ryo/items/1cb1977916e8270efca0

競合を解消（解決）できた後は、以下のコマンドを実行しする。

```
git add .
```

そして、最後にGitHub Desktopにて、cherry-pickした内容をコミットして、リモート環境にpushし、マージを行うことで作業完了となる。

　　　　　　　　　　　　　　　　　　　　　　　　以上
<参考記事>
・https://qiita.com/ta__ho/items/8204a22a53b02ee0817e
・https://qiita.com/bossunn24/items/dedb620541d852327934
・https://www.sejuku.net/blog/71544#ID
・https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E5%B1%A5%E6%AD%B4%E3%81%AE%E9%96%B2%E8%A6%A7
基盤地図情報をShapefileに変換する（要Windowsマシン）

#基盤地図情報とは
　国土地理院が製作している地形図を電子データ化したもの。
　特に地図上に描かれる情報（等高線や道路、建物など）をベクトルデータ化した基本項目はデータとして使いやすい。
　この他に数値標高モデル、ジオイド・モデルがある。

#基盤地図情報を利用するまで
##ダウンロード
　国土基盤情報は[国土地理院のサイト](https://fgd.gsi.go.jp/download/menu.php)からダウンロードする。
　ダウンロードしたい情報を選びファイル選択をクリックする。
　ダウンロードする範囲は、都道府県、市町村といった行政界の他、全国を碁盤の目に区切ったメッシュで指定できる。
　まあ普通の事務屋さんがこういう情報を使いたい場合、行政界単位で選ぶと思う。でも、市町村単位で選ぶと、その市町村が含まれているメッシュ全部をダウンロードすることになる。
　ダウンロードファイルリストのページでは、何か理由が無い限り「全てチェック」をクリックして「まとめてダウンロード」しておくのが無難でしょう。
　ダウンロードは誰でもできるが、ユーザー登録が必要となる。未登録の場合、登録してからダウンロードとなる。
　続いて使用目的等のアンケート画面になるので、思うところがあれば記入しておく。
　ダウンロードする際、地図データの他に「基盤地図情報ビューワ（以下、FGDV）」というソフトウェアも下ろしておく。これはデータ変換のために必要となる。
　また、基盤地図情報は随時更新されていくのでダウンロードする際は、ダウンロード日時がわかるようにしたほうが良い。
##データの解凍・読み込み
　どうも基盤地図情報とFGDVは対応しているものらしい。というのも、同時期にダウンロードしたFGDVで無いと基盤地図情報を開けなかったことがことがある。
　ダウンロードした基盤地図情報は一つのZipファイルにまとまっている。
　FGDVもZipファイルになっているので、まずFGDVを解凍する。fgdv.exeが変換のためのソフトウェアで、特にインストールなどは要らない。クリックするだけで起動する。
　起動すると、「新規プロジェクト作成」というダイアログが開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/56eb0d71-f73d-7fb2-b670-69f24510ab2c.png)
　【追加】というボタンをクリックし、一緒にダウンロードした基盤地図情報（PackDLMap.zip）を読み込ませ【OK】をクリックする。
　解凍しながら地図を描画し始めるので動作完了まで結構時間がかかるので待つこと。
##データ変換
　基盤地図情報はJPGIS2014(XML)というxmlベースのファイルフォーマットになっていて、そのままではqgisなどのGISで利用できない。最近のqgisでは読み込めるとの話も聞くけど、[Shapefile](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%97%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)形式に変換しておいた方が使い勝手が良い。
　この変換作業には、大変時間がかかるので、fgdvの描画関係の設定を変えておく。
　【設定】をクリックすると、次のダイアログが開く。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/7bd2a70f-19ba-43bd-169b-2968dd593d86.png)
　【表示設定】をクリックすると次のような項目があるので、行政界のみを再描画の対象にする。
　これをしないと操作をするたびに全ての内容を書き換えようとするので、操作性が極めて悪化する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/c3b6d320-ae1f-77a1-fb2c-d6d865294250.png)
　これをすると次のような表示になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/63621028-03c6-fe32-7a08-447846ff38b2.png)
　【エクスポート】から【エクスポート】を選択する。
　変換種別でShapefileを選択し、「全データ領域を出力」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/b11bb2dc-5465-a5de-c1b2-b076a3309b17.png)
　これで選んだ全域が変換される。
　「直角座標系に変換」は、そのままにしておいた方が便利。これは地図上の位置を原点からの距離で示す「[平面直角座標系](https://ja.wikipedia.org/wiki/%E5%B9%B3%E9%9D%A2%E7%9B%B4%E8%A7%92%E5%BA%A7%E6%A8%99%E7%B3%BB)（またの名を公共座標系）」に変換することを現していて、これを外すと緯度経度方式になってしまう。
　平面直角座標系にしておくと、地図上の距離をそのまま「m単位」で計れる。
　さて、変換作業は、秋田市くらいの地図で数時間はかかる。
　fgdvは変換中、操作すると「応答無し」という状態になってしまうが、気長にそのまま放っておくこと。
　私の経験では、等高線、建物のデータ変換にとても時間がかかっているようだ。
 と思ったら、今日は十数分で変換できた。
##試しに表示
　背景地図に地理院地図の1960年代の空中写真を設定し、その上に建物の外周線を表示してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/eeb64561-2c60-63e9-d374-ad8b94c534c2.png)
　現在、秋田駅周辺の地図だが、建物がオレンジ色の線で表示されている。
　アルヴェのあるあたりに、扇形車庫と転車台が見える。
　秋田駅の東側は、この五十年で随分と変わってることがわかる。

#その他
　qiitaにスクリーンショットを貼れることに気がついた。画面があると説明しやすい。
AWS CLI

# AWS CLIを理解する
AWS CLIを」利用するにあたって、ざっと大事なとこだけを整理する。
[AWS Command Line Interface-ユーザーガイド](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html)

## WindowsOSへのインストール

1. MSIインストーラの取得
1. インストーラ実行

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/c7ddc44c-97fa-753a-2ad3-6336be3e21c5.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/ea2a915b-933a-78cc-24bc-f607af0f0d2a.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/3bf325b1-1e24-5fbd-40b6-df1a4fd445f9.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/04e652af-efc8-5938-2be7-14fd63ef0746.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/1de10812-f546-9de0-ae10-2cac52a3a836.png)

1. AWS CLI設定

    ```DOS
    C:\Users\blackcat>aws configure
    AWS Access Key ID [None]: **********************
    AWS Secret Access Key [None]: *****************************************
    Default region name [None]: ap-northeast-1
    Default output format [None]: json
    ```

1. 設定確認
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/666cb175-136a-270f-c4ad-88942ac27c40.png)

## 補足
### インスタンスメタデータ
>Amazon EC2 インスタンス内から AWS CLI を実行すると、コマンドへの認証情報の提供を簡素化できます。各 Amazon EC2 インスタンスにはメタデータが含まれており、AWS CLI は一時的な認証情報に対してクエリを直接実行できます。

### CLI Skeleton
>AWS Command Line Interface (AWS CLI) コマンドのほとんどは、--cli-input-json パラメータを使用してファイルから入力されるパラメータのすべてを受け入れる機能をサポートしています。

### リターンコード
>AWS CLI コマンドのリターンコードを判断するには、CLI コマンドの実行直後に次のいすれかのコマンドを実行します。`C:\> echo %errorlevel%`
phperのための"A Tour of Go" 【Stringers編】

# 【概要】

この記事では [A Tour of Go](https://go-tour-jp.appspot.com/list) のExercise: [Stringers](https://go-tour-jp.appspot.com/methods/18) の解答例をgolangおよびPHPで提示します。phperの方はこの解答例を参考にしてGopherちゃんと触れ合っていただけると幸いです。

今回取り扱うExerciseの内容は下記の通りです

> IPAddr 型を実装してみましょう IPアドレスをドットで4つに区切った( dotted quad )表現で出力するため、 fmt.Stringer インタフェースを実装してください。
> 
> 例えば、 IPAddr{1, 2, 3, 4} は、 "1.2.3.4" として出力するようにします。

<font color="Red">※なお先に宣言させていただきますがPHPでは問題とはかなり異なる仕上がりとなっております</font>

# 【golangでの解答例】

## - コード
```go
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.
func (ip IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
}

func main() {
	hosts := map[string]IPAddr{
		"loopback":  {127, 0, 0, 1},
		"googleDNS": {8, 8, 8, 8},
	}
	for name, ip := range hosts {
		fmt.Printf("%v: %v\n", name, ip)
	}
}
```
## - 実行結果
```
loopback: 127.0.0.1
googleDNS: 8.8.8.8
```
# 【PHPでの解答例】
## - コード
```php
<?php

interface Convertable
{
    public function get();
}

class IPAddr implements Convertable
{
    private $ip1;
    private $ip2;
    private $ip3;
    private $ip4;
    public function __construct($ip1, $ip2, $ip3, $ip4)
    {
        $this->ip1 = $ip1;
        $this->ip2 = $ip2;
        $this->ip3 = $ip3;
        $this->ip4 = $ip4;
    }

    public function get()
    {
        return $this->ip1 . "." . $this->ip2 . "." . $this->ip3 . "." . $this->ip4;
    }
}

class Printer
{
    public function __construct()
    {
    }

    public static function create()
    {
        return new self();
    }

    public function print($elem)
    {
        if ($elem instanceof Convertable) {
            echo $elem->get();
        } elseif (gettype($elem) === "object") {
            throw new Exception("invalid argument");
        } else {
            echo $elem;
        }
    }
}

$hosts = array(
    "loopback" => new IPAddr(127, 0, 0, 1),
    "googleDNS" => new IPAddr(8, 8, 8, 8)
);
foreach ($hosts as $name => $ip) {
    Printer::create()->print($name);
    Printer::create()->print(": ");
    Printer::create()->print($ip);
    Printer::create()->print("\n");
}
```
## - 実行結果
```
loopback: 127.0.0.1
googleDNS: 8.8.8.8
```

# 【golangとPHPを比較して】
golangとPHPとではインターフェースの定義が異なるため混同してしまうと訳が分からなくなってしまいます。
参考までにA Tour of Goではgolangのインターフェースについて下記のように記述されています。
> interface(インタフェース)型は、メソッドのシグニチャの集まりで定義します。

> そのメソッドの集まりを実装した値を、interface型の変数へ持たせることができます。

StringのインターフェースをPHPでは定義できない以上このような実装になるしかないのかと思います。もしPHPで綺麗な実装ができるのであればコメントで指摘していただけると幸いです。
GitHubで公開されているプロジェクトをAndroid Studioから開く

# 概要
GitHubで公開されているプロジェクトをAndroid Studioで開く方法は2つある。

# 方法1
Androidプロジェクトを管理するディレクトリに移動し、以下を実行

```
git clone https://github.com/[name]/[Project].git
```


# 方法2
Android Studioで"Check out project from Version Control"の"Git"を選択。

<img width="409" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276354/c35f1454-1035-0e1b-62b5-df2ca9839322.png">

"URL:"にリポジトリのURLを入力し、Clone

<img width="399" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276354/5451ff80-ecde-66f5-d3ec-b3aeba7af288.png">
AWSブログで紹介されていた、音声翻訳アプリを作成してみた

2019/06/14のAWSブログに載った記事を元に、やってみました。
完成するまで30分、完了するためのコストは1USD未満って書いてたから・・・。

  - [AWS サービスを使用した独自のリアルタイム音声翻訳アプリケーションの構築](https://aws.amazon.com/jp/blogs/news/build-your-own-real-time-voice-translator-application-with-aws-services/)

### 手順
1. コンソールにログインします。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-01.png)

2. [Launch stack](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=VoiceTranslatorApp&templateURL=https://aws-ml-blog.s3.amazonaws.com/artifacts/voicetranslator/voice-translator.yaml)（←このリンク）を押すと、CloudFormationの「スタックの作成」が開きます。リージョンは「バージニア北部」となっているが、それはそのままで。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-02.png)

3. 色々出てくるけれど、基本はデフォルトのまま。CloudFormationがIAMを作成するところも承諾します。そうするとCloudFormationが実行されます。出来上がるまで10分くらい待ちましょう。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-03.png)
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-04.png)
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-05.png)
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-06.png)

4. 待っている間に、[こちらのzipファイル](https://aws-ml-blog.s3.amazonaws.com/artifacts/voicetranslator/voice-translator.zip)をダウンロードして解凍しておきます。あと、飲み物を用意したり、トイレに行ったり。

5. スタックが完了したら、出力（Outputs）タブを開きます。4つのファイルが作成されています。ここの値をこの後使います。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-07.png)
    - VoiceTranslatorLink – ウェブページへのリンク。
    - VoiceTranslatorLambda – ウェブアプリケーションから呼び出されるLambda関数の名前。
    - VoiceTranslatorBucket – アプリケーションをホストし、オーディオファイルが保存されるS3バケット。
    - IdentityPoolIdOutput – IDプールのID。S3とLambdaにセキュアに接続することを可能にします。

6. 先ほどダウンロードしたzipファイルの中にある、voice-translator-config.jsという名前のファイルを開き、スタックの4つの出力値に基づいて編集します。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-08.png)

7. S3コンソールでCloudFormationで作成されたS3バケットを開きます。編集したvoice-translator-config.jsを含む3つのファイルをすべてアップロードします。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-09.png)
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-10.png)

8. S3にアップロードしたリンクを開きます。S3でバケットを開いて、プロパティからStatic website hostingを開くとエンドポイントが載っています。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-11.png)

9. Source LanguageとTarget Languageを選択し、「START RECORDING」を押してから喋ります。「STOP RECORDING」を押すとProcessingになり、少し経つと翻訳されます。
![コンソール画面](https://susudata-public-picture.s3-ap-northeast-1.amazonaws.com/2019/06/20190615_qiita-12.png)

-----
### はまったところ

作るところまでは全然はまらず、最後に実際に使うところではまりました。
喋っても何も反応がなくて、調べてみたところgetUserMediaでエラーが発生しており、マイクへのアクセスが許可されていない（変更もできない）ことが判明。
Google Chromeだとどうしようもなかったので、Firefoxでやってみたらうまくできました。
翻訳されるまで時間がかかるのは、ロケーションの問題ですかね・・・。

娘たちが楽しそうに、英語の翻訳遊びをして笑っていたので、良かったです。
とりあえず、喧嘩するのをやめてくれ。

暇があったら、これをベースにちょっといじってみようと思います。
Splunkで先月比のグラフをつくる

~~Excelだと簡単にできるけど、Splunkでやるにはちょっと頑張らなきゃいけなかった。~~
`chart`を使えば簡単にできました。（半年後の感想）

#データの準備
```splunk:SPL
| gentimes start=05/01/2019 end=07/01/2019
| rename starttime as _time
| eval count=(random() % 1000 ) +1
| eval date_month=strftime(_time, "%m")
| eval date_mday=strftime(_time, "%d")
| fields _time,count,date_month,date_mday
```

`gentimes`でずらっと日付を二ヶ月分作成して、適当なデータを`random()`で作成

`strftime`で月と日にちを作成。これはあとで集計する際の指標とする。

`fields`で必要なデータのフィールドのみとする。
#集計と表示向け加工
```splunk:SPL
| chart sum(count) as count by date_mday date_month
| rename date_mday as _date_mday
| foreach * 
    [ eval time="<<MATCHSTR>>"."-"._date_mday]
    | eval _time=strptime(time,"%m-%d")
    | fields - time
    | table _time *
```
[chart@splunk>docs](https://docs.splunk.com/Documentation/Splunk/8.0.1/SearchReference/chart)の記述をみると

```
chart [<chart-options>] [agg=<stats-agg-term>]
( <stats-agg-term> | <sparkline-agg-term> | "("<eval-expression>")" )...
[ BY <row-split> <column-split> ] | [ OVER <row-split> ] [BY <column-split>] ]
[<dedup_splitvals>]
```
**BY**のところに注目
`<row-split> <column-split>`なので、最初が行を分割、次が列を分割
今回は_date_mday(日付)_で行を分割、_date_month(月)_で列を分割した。

_date_mday_は文字列(String)なので、月を付けてあげて`strptime`で時間にもどしてあげる。
ここはいつ作ってもいいように自動判定にしている。

月の表示は`foreach`での判定もあり_%m(2桁数字)_にしたけど、最終的に`rename`を使用して日本語に変えてもらえばいいと思う。

#結果

![qiiita1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/8fc847f9-9a3a-f9e6-cddf-be9c7950a1ce.jpeg)
![qiita2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/18b15a74-55a4-ab7a-65ae-0b5aec5cabe1.jpeg)

ここは修正していないけど、概ねこんな感じで出ます。

\:sweat: 職場のグラフ直さないといけない・・・・
Pandas 最頻値による欠損値補完

#Pandas 欠損値の最頻値による置換

欠損値（nan）を中央値、平均値、最頻値などで置き換えますが、最頻値での置換にちょっと躓いたので、メモを残したいと思います。

まずはデータフレームを以下のように定義

```
df = pd.DataFrame(["東","西","南","北","北",np.nan], columns=["方位"])
```

|      |  方位 |
|------|-------|
| 0    |    東 |
| 1    |    西 |
| 2    |    南 |
| 3    |    北 |
| 4    |    北 |
| 5    |   NaN |

mode()を使って確かめてみると、最頻値は"北"です。

```
df["方位"].mode()
```
|      |  方位 |
|------|-------|
| 0    |    北 |

中央値、平均値と同じ要領でfillna()を使うと

```
df.fillna(df["方位"].mode())
```

エラーにはなりませんが、更新できていません。

|      |  方位 |
|------|-------|
| 0    |    東 |
| 1    |    西 |
| 2    |    南 |
| 3    |    北 |
| 4    |    北 |
| 5    |   NaN |

原因はこれです。

```
type(df["方位"].mode())
pandas.core.series.Series
```
最頻値の場合、平均値や中央値と違って、複数の値を返す可能性があるため、戻り値は
    - DataFrame渡しの場合は、DataFrame
    - Series渡しの場合は、Series
が返ってきます。

```
df.fillna(df["方位"].mode()[0])
```
そのため、明示的にインデックス番号を指定してあげなければなりませんでした。
これで無時に更新できました。

|      |  方位 |
|------|-------|
| 0    |    東 |
| 1    |    西 |
| 2    |    南 |
| 3    |    北 |
| 4    |    北 |
| 5    |    北 |
Testifyでmockを作ってテストを記述してみたメモ

# はじめに
Testifyというテストライブラリでテストを記述する際にモックを用意してテストする方法が感覚的にわからなかったので、実装して理解しようと思いました。
加えてたぶん数日したら、忘れそうな気がしたので忘備録も兼ねてます。
それから誰かの助けになれば、と思って公開します。

## 前提条件
以下のような環境でテストしてみました。

go 1.12.1
mac os 10.13.2(High Sierra)

## 事前準備
適当なところに検証用のディレクトリを作り、モジュールを定義します。
今回はテストライブラリなので、用意するファイルはmain.goとmain_test.goの２つ。
main.goは何らかの処理を行い、main_test.goはテストコードになります。

```
mkdir test
cd test
go mod init test
touch main.go main_test.go
```

## testifyのインストール
go getでインストール可能。
ちなみに公式サイトは[こちら](https://github.com/stretchr/testify)。

```
go get github.com/stretchr/testify
```

## まずはプログラムの実装
どこかの天気配信サービスに天気をリクエストして天気を取得する、みたいな感じのものを作ります。
実際の天気配信サービスにアクセスするのは大変なので、単に文字列を返却するだけの、簡単なプログラムにします。

処理の流れとしては
```
WeatherService.GetWeather() -> WeatherClient.RequestWeather()
```
みたいな感じです。

```main.go
package main

import (
	"fmt"
)

// お天気クライアントのinterface
type WeatherClient interface {
	RequestWeather() string
}

// お天気クライアントの実態の構造体
type WeatherClientImpl struct{}

// お天気をリクエストする関数
func (c WeatherClientImpl) RequestWeather() string {
	fmt.Println("天気をリクエストするクライアント")
	// 本当は天気をリクエストする処理とかがここに入る
	return "晴れ"
}

// お天気を扱うサービスの構造体(interfaceの実態)
type WeatherService struct {
	client WeatherClient
}

// お天気取得関数
func (w WeatherService) GetWeather() string {
	fmt.Println("天気を取得する")
	return w.client.RequestWeather()
}

func main() {
	weatherClient := WeatherClientImpl{}
	weatherService := WeatherService{client: weatherClient}
	weather := weatherService.GetWeather()
	fmt.Printf("天気は%s\n", weather)
}
```


## プログラムの実行
実行すると以下のような感じの文字列が出力されます。

```
❯ go run main.go

天気を取得する
天気をリクエストするクライアント
天気は晴れ
```

## テストコードの記述
次にテストコードを以下のように記述します。
このテストではモックのClientに"くもり"を返却するように指定して、"くもり"が変革されることを期待するテストを行っています。

```main_test.go
package main

import (
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

// モック(今回の場合はTokyoWeatherClientのモック)
type weatherClientMock struct {
	mock.Mock
}

// モック関数定義
func (mock *weatherClientMock) RequestWeather() string {
	fmt.Println("モック実行")
	result := mock.Called() // 呼び出し
	return result.String(0) // モックの返却値 Returnの引数を返却する
}

// くもりの時のテスト
func TestRequestWeather1(t *testing.T) {
	assert := assert.New(t)

	// モック準備
	weatherClientMock := new(weatherClientMock)
	weatherClientMock.On("RequestWeather").Return("くもり")   // このテストではモックに"くもり"を返却するように指定している

	// テスト実行
	weatherService := WeatherService{client: weatherClientMock}
	weather := weatherService.GetWeather()

	// 検証
	assert.Equal(weather, "くもり") // 天気サービスが"くもり"を返却しているか検証
}
```

## テストの実行
以下のようにテストを実行することでテストが無事にパスすると思います。

```
❯ go test
天気を取得する
モック実行
天気を取得する
モック実行
PASS
ok      _/test  0.016s
```

## ポイント

ポイントは以下の2つかなと思います。

* WeatherClientをinterfaceとして定義している。こうすることでWeatherServiceではClientの実態を気にしなくても良くなる。
* WeatherServiceを初期化する際にclient: weatherClientを渡している。外部からclientを与えるようにすることでテスト時にモックに差し替えられます。

## 参考
[公式](https://github.com/stretchr/testify)
[Go言語でテスト作成　testifyの基本的な使い方](https://re-engines.com/2018/10/16/go-testify%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%86%E3%82%B9%E3%83%88%E4%BD%9C%E6%88%90/)
[testify/mockでgolangのテストを書く](https://qiita.com/muroon/items/f8beec802c29e66d1918)
VB基本まとめ~クラス(インスタンス・コンストラクタ・デストラクタ)編~

#インスタンスとコンストラクタ
クラスを利用するには基本的にインスタンス(実態)の生成が必要になり、インスタンスの生成にはNew演算子を使用します。

New演算子でクラスのインスタンスを生成する際に実行されるのがNewメソッドで、このようにインスタンス生成時に自動的に実行されるメソッドの事をコンストラクタと言います。
コンストラクタでは主に初期化をおこないます。

```VB
'*** クラスの宣言
Private Class Data
    '*** Sub Newは無くとも可

End Class

'*** wk1 Is Nothing
'*** Newをしない場合、インスタンスは生成されない
Dim wk1 As Data
'*** wk1 IsNot Nothing
'*** Newした時点でインスタンスが生成される
wk1 = New Data

'*** 宣言と同時にインスタンスを生成することも可能
Dim wk2 As New Data
```

また、クラスのインスタンス生成に引数を設定することも可能です。

```VB
'*** クラスの宣言
Private Class Data
    ''' <summary>
    ''' 引数の無いコンストラクタ
    ''' </summary>
    Sub New()
        '*** 初期化処理を記述
    End Sub
    ''' <summary>
    ''' 引数ありのコンストラクタ
    ''' </summary>
    ''' <param name="value1"></param>
    Sub New(value1 As Integer)
        '*** 引数の無いコンストラクタ実施
        MyClass.New
    End Sub
    ''' <summary>
    ''' 引数が異なる複数のコンストラクタを定義可能
    ''' </summary>
    ''' <param name="value1"></param>
    ''' <param name="value2"></param>
    Sub New(value1 As Integer, value2 As Integer)
        MyClass.New(value1)
    End Sub
End Class

Dim wk1 As Data
Dim wk2 As Data
Dim wk3 As Data

'*** 引数無しでインスタンス生成
wk1 = New Data
'*** 引数付きでインスタンス生成
wk2 = New Data(1)
wk3 = New Data(1, 2)
```


#デストラクタ
コンストラクタがクラスの生成じに実行されるのに対し、デストラクタはクラスのインスタンスが破棄される時に実行されます。

インスタンスの破棄ということでDisposeを思い浮かべるかもしれませんが、VB.NetでのデストラクタはFinalizeメソッドになります。ですが、明示的に分ける必要も無い為、一旦Disposeもデストラクタの一部と考えても差し支えないかと思っております。

DisposeとFinalizeの違いはDisposeはUsing等で明示的に呼び出すのに対し、FinalizeはGCで回収される時に実行されるという違いになります。
独自実装のクラスにDisposeやFinalizeを実装するにはIDisposableインターフェースを実装します。

```VB
'*** クラスの宣言
Public Class Data
    Implements IDisposable
    ''' <summary>
    ''' 引数の無いコンストラクタ
    ''' </summary>
    Sub New()
        '*** 初期化処理を記述
    End Sub

    ''' <summary>開放処理が実施済みかのフラグ</summary>
    Protected _disposed = False

    Public Overloads Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
    End Sub
    Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
        If Not _disposed Then
            If disposing Then
                '*** アンマネージリソースの開放

            End If
            '*** マネージドリソースの開放

        End If
        _disposed = True
    End Sub

    ''' <summary>
    ''' デストラクタ
    ''' </summary>
    Protected Overrides Sub Finalize()
        MyBase.Finalize()
        Dispose(False)
    End Sub
End Class
```

前記したようにDisposeとFinalizeの大きな違いは明示的に呼び出せるか否かになってきます(FinalizeもGC.Collectで間接的に呼べなくもないですが)。
その為、VB.Netで開放処理をする場合、Disposeを使用するのが一般的になります。
win10, RTX2060, cuda9.2, tensorflow1.13.1でVGG16を何とか完遂

Qiitaの記事で何度も助けられました。　mouse computerのEGPN787 RTX2060を購入したものの、GPU利用に試行錯誤しました。
とても人のお役に立てるようなものではないが、備忘録として残します。
初心者もいいところなので、笑い飛ばしてください。

１．PC購入の目的
　jupyter notebookで脳の画像分類を行っていたが、GPUなしmacでは1epoch 20secと気の遠くなるような状況に耐えられなかった

２．上手くいかなかったこと:pensive:
a) 試した環境設定
　Visual Studio 2015 C++
　Cuda9.0とcuDNN v7.1.4 fow win10
　tensorflow-gpu 1.13.1
　anaconda
　　jupyter notebook
　h5py, matplotlib, pillow, pandas, scikit-learn, keras
b)導入過程
　visual studioはcommunity versionからC++環境を見つけてインストール、再頒布ver3もインストール
　cuda9.0は1年前の成功例を参考にして導入。
　anaconda prompotで仮想環境をpytho3.6で構築
　　tensorflow-gpuインストール
　　　python立ち上げ、'import tensorflow'で起動を確認
c)上記でdeep learningが中止する状況
　以下のページを参考にしてjuypterプログラムを組む
http://cedro3.com/ai/keras-vgg16-fine-tuning/
　CPUでは問題なかったが、何故かモデルコンパイルできずにエラーが発生する　そこでは、tensorflow-gpuのバージョンを1.8.0に落とすことで解決するとの記事があり、'pip install tensorflow-gpu==1.8.0'を試したが、結果は変わらなかった。

３．上手くいった状況
CUDA10.0, tensorflow-gpu 2.0（失敗）→　CUDA9.2, tensorflow-gpu 1.13（成功）

:frowning:正直、どうしてうまくいったか分かりませんが、以下の状況を試したらGPUが突然動き出しました
3-1）本当にGPUが作動するのか確認。
　visual studio 2015とcuda9.0をアンインストール:point_up_tone1:。win10にcuda10, VS2017, ChainerをインストールしてGPUを動かすという記事（https://qiita.com/kekekekenta/items/a46a899956b1c756ddce）を写経させていただき、tensorflow-gpuなしでGPUの作動までは確認できた。とりあえず自分が悪いと自覚でき、本当に作者の@kekekekentaに感謝！
3-2）tensorflow-gpuを2.0の最新版にして、cuda10.0を導入
　これを行うと、処理開始前に、defaul_graphが取り込めないとエラーがでる。いくつか同様な記事から対策を試したがどうにもならない。　tensoflow2.0ではgraph機能がないとかいうことなので、あきらめ:sob:
3-3）CUDA9.2, tensorflow-gpu 1.13.1に切り替え成功
　案内にあるCUDA9.xの最も新しいものと、tensorflow-gpu 1.xの最も新しいものに最後の望みをかけて導入（cuda10.0はインストールされたまま）。これでだめなら、もう一度visual studio 2015(すでにアンインストール）を再導入かと、ダウンロード中にうまくいった。:relaxed:

教訓
自分のような初心者が新しいグラボに飛びつかない（安定のモデル末期を選ぶ）
’tensorflow backend’と表示されても、最後までやらないとわからない。

参考ページ
＊cuda10とVS2017で仮想環境を構築のページ
https://qiita.com/kekekekenta/items/a46a899956b1c756ddce
＊GPUをあきらめCPUでなんとか動かすときの参考ページ
https://pcyaranaika.com/blog/machine-learning/how-to-disable-gpu-with-keras-on-jupyter.html
＊自分でdeep learningを行うときのラベル、データ分類のやり方がわかるページ
http://cedro3.com/ai/keras-vgg16-fine-tuning/
素数が無限にあることの証明（背理法）

素数が無限にあることを次のように背理法で証明します。

## 証明

素数が有限で$n$個であるとする。その$n$個を$$p_1,\,p_2,\,\cdots,\,p_n$$とする。
このとき，次の自然数$K$を考える。$$K=p_1\times p_2\times \cdots\times p_n+1$$
この$K$はどの素数でも割り切ることができないので，素数となり，素数の個数が$n$個であることに矛盾します。故に素数は無限あります。

## 証明を振り返って

こう書くと，$K$という自然数は素数であるように思えます。素数になるかどうはか調べてみないとわからないので，Jupyter notebookとWolfram Language 12を使って調べてみました。

### Mathematicaの数学関数

コマンドの確認です。

```
PrimeQ[expr]
expr が素数の場合にはTrueを，その他の場合にはFalseを与える

Prime[n]
第 n 番目の素数を与える．

FactorInteger[n]
整数 n の素因数をこれらの指数とともにリストとして返す．
```

### コード

$K$を計算してみます。とりあえず10個計算して，結果を調べてみました。

```
In [1]: Table[Product[Prime[i],{i,1,n}]+1,{n,1,10}]
Out[1]: {3, 7, 31, 211, 2311, 30031, 510511, 9699691, 223092871, 6469693231}

In [2]: PrimeQ[%]
Out[2]: {True, True, True, True, True, False, False, False, False, False}

```

となり，6個目からは素数でないことがわかります。一応，6個目を確認して，因数分解してみます。


```
In [3]: 2*3*5*7*11*13+1
Out[3]: 30031

In [4]: FactorInteger[30031]
Out[4]: {{59, 1}, {509, 1}}

```

ということで，$$2\times3\times5\times 7\times 11\times13+1=30031=59\times509$$でした。今回のケースで言えば，14より大きいところに因数59と509があるわけです。

### 考察
まあ，数が大きくなるとあまり素数にならないんだろうなあと思っているのですが，とりあえず1000個くらい調べてみると，

```
In [5]: list1=Table[Product[Prime[i],{i,1,n}]+1,{n,1,1000}];
        list2=PrimeQ[list1];
        Position[list2,True]

Out[5]: {{1}, {2}, {3}, {4}, {5}, {11}, {75}, {171}, {172}, {384}, {457}, 
         {616}, {643}}
```

13個でした。このような素数は無限にあるとは思いますが，どうなんでしょうか？
AWS Summit TOKYO 2019 レポート

# AWS summiの概要
AWS summit とは、AWS に関する情報交換・学習を行うことができる、日本最大級のカンファレンスです。
セッションとよばれる、AWSに関するセミナーが、１３箇所で毎時間行われていました。
他にも企業のブースがあって情報交換ができたり、AWSの人に気軽に相談したりできます。

また、資格を取得していると、認定者ラウンジに入れます。
受付で認定証をみせると、今年は、ステンレスボトルとバッジが貰えました！
ラウンジでは、お菓子や飲み物が提供されます！
飲み物は買わずにすみました（笑）

# 参加の目的
セッションを聞きに行って、AWS利用のトレンドを知るのが目的です。
また、「こんなことが課題で、AWSでこういう風に解決した」という話と、その苦労話が聞けるので、これからAWSを取り入れようとするにはとても参考になります。
私の所属する部署からも何人も参加して、手分けしてセッションを聞いたりしていました。
そして、3日間職場にほとんど人がいない状態になっていました・・・（笑）

# セッションの傾向
下記のジャンルが、去年よりもとても増えたと思いました。

- AWS移行に向けて組織の作り方・教育方法
- コンテナ
- データレイク
- SageMaker
- CI/CD DevOps

去年は現行のシステム・オンプレから、AWSに移行する話が多い印象でしたが、
今年は、移行後のDevOpsをどう回すかについての話が増えたと思いました。

# 面白かったセッション
とても興味深かったセッションは下記です。

- B2Cビジネスの本番環境で必要な継続性と高レスポンス性能を支えるコンテナアーキテクチャ
- 事業責任者も必見！AWS Well-AechitectedFremeworkのビジネスへの有効活用
- クラウドの利用メリットを最大化するための組織体制とそれを支える基盤テクノロジーの紹介
- ロマサガRSの大規模トラフィックを捌く AmazonECS & Docker 運用の知見

コンテナ系の具体的な実践事例は取り入れたいと思うところが多かったです。
私の所属部署では、AWSに移行しようとしているところなので、組織づくりや教育方法は参考になりました。
どんどん偉い人に提案していきたいです。

# セッション申し込みにあたって
技術セッションでは、仕事で使おうとしているものを選んだ方が良かったです。
でないと、専門的で話についていけなかったものもありました・・・。
製品紹介系は、その製品をなぜ作ったのか、取り入れる際のメリット・デメリット、などの話が聞けると嬉しいのですが、ただ製品に特化した話だと、導入予定はないので退屈になってしまいました。

事前登録推奨ですが、当日でも聞くことができます。
当日の待機列があって、開始5分前に入場となります。
事前登録で満席だったものでも、当日並んで席に座ることもできましたし、立ち見となっても、全員会場に入れました。
去年は当日申し込みでも座れないことがあったので、今年は余裕に座れたので良かったです。

# おわりに
会社の複数の人と参加して、手分けしてセッションを聞いたりして、ディスカッションする時間は、とても有意義だなと思いました。
資料は去年はだいたい2週間後から順次公開されました。
動画とスライドがアップロードされるので、参加していないセッションも見てみようと思います。
Go言語の勉強はじめ

業務で使う機会にはなかなか恵まれませんが、Go言語がとても良いと聞くので導入からちょっとしたプログラムの作成までをメモを取りながら行います。

# 投稿者のレベル
- C言語からプログラミングに触れる
    - 苦手だけどポインタくらいはなんとか
- ちょっとだけならC++を触れる
- 普段はC#とJavaが中心

# Go言語について

- 2009年に登場した、比較的若いGoogle製のオープンソースプログラミング言語
- Linux, macOS, Windows, FreeBSDで動作させることが可能
- C言語のようなコンパイル言語

# インストール(Mac)

homebrewを使用してインストールできます。

```bash
brew install go
```

```bash
# インストール確認
$ go version
go version go1.12.6 darwin/amd64
```

Windowsの場合は以下を参考にしてください。
インストーラーを使用してインストールできるみたいです。
https://golang.org/doc/install#windows

# 手始めにHello World

私はVisual Studio Code派なので以下の拡張機能をインストールしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/2ba5b5ca-05da-9ee8-fd4a-09d3c5f0e776.png)

上記をインストール後、推奨するツールが出てきたので全てインストールしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/8a78cd2a-e2eb-9a8e-35dd-7dd5811496f2.png)

便利になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/153adff4-c280-13ab-ed3d-e19a6bff762e.png)




以下のソースを作成します。

```go:hello.go
package main

import "fmt"

func main() {
	fmt.Println("Hello World.")
}
```

実行は以下のコマンドで行います。

```bash
go run hello.go

#実行結果
$ go run hello.go 
Hello World.
```

軽く説明を書きます。

`package main`：最初にパッケージを指定します。
mainパッケージ以外はパッケージ名とフォルダ名を同じにする必要があります。
Javaと同じですね。

`import`：使用したいパッケージをインポートします。
今回、fmtは標準出力を使用するためにインポートしました。
こちらもJavaやC#と同じですね。

`func`：関数宣言です。今回は全ての起点となるmain関数を宣言しました。
詳細については後ほど記載します。

# コメント

コメントは以下の方式で記載できます。

```go
// コメント
/*
複数行
コメント
/*
```

# 変数

基本的な変数を宣言・使用してみます。

## 宣言方法

グローバル、ローカルスコープに関係なく、以下で宣言が可能です。
文末にセミコロンは不要です。

```go
var test1 int // 数値型、初期値なし
var test2 int = 1 // 数値型、初期値あり
var test3 = 1 // 初期値あり、型は勝手に予測される

// 複数同時に宣言
var (
	test4 int
	test5 int = 1
	test6 = 1
)

var test7, test8 int
var test9, test10 int = 1, 2
var test11, test12 = 1, 2
```

ローカルスコープに限り、以下の記載が可能です。

```go
func hoge() {
	a := 1
	fmt.Println(a)
}
```

グローバルスコープとローカルスコープの違いはご存知かと思いますが、
関数の中で宣言しているか(ローカル)、していないか(グローバル)の違いです。

## 基本的な型

|型|説明|
|:--|:--|
|int|符号付整数|
|int8, int16, int32, int64|８ビット〜64ビットまでのint|
|uint|符号無し整数|
|uint8, uint16, uint32, uint64|8ビット〜６４ビットまでのuint|
|float32, float64|浮動小数点数の数値|
|complex64, complex128|複素数型|
|string|UTF-8の文字列型|
|bool|真偽値型(true, false)|

## 定数

ご存知かと思いますが、定数は後から変更できません。

```go
const c1 int = 1
const c2 string = "定数"
const (
	c3 = "hoge"
	c4 = "fuga"
)
```

## 実際に使ってみる

```go:hello.go
package main

import "fmt"

// グローバルスコープ
var g1 int
var g2 int = 1 // 書けるけど、冗長な宣言は警告出るらしい
var g3 = 2

func main() {
	fmt.Println("Hello World.")

	// ローカルスコープ
	var l1 int
	l1 = 3
	l2 := 4

	var str = "文字列"
	var b1 bool
	b2 := true

	var (
		f1 float32
		f2 = 0.1
	)

	fmt.Printf("g1=%d, g2=%d, g3=%d\n", g1, g2, g3)
	fmt.Printf("l1=%d, l2=%d\n", l1, l2)
	fmt.Printf("str=%s\n", str)
	fmt.Printf("b1=%t, b2=%t\n", b1, b2)
	fmt.Printf("f1=%f, f2=%f\n", f1, f2)
}
```

```bash
# 実行結果
$ go run hello.go 
Hello World.
g1=0, g2=1, g3=2
l1=3, l2=4
str=文字列
b1=false, b2=true
f1=0.000000, f2=0.100000
```

ちゃっかり`Printf`を使用しましたが、C言語と同じなんですね。

疲れてしまったので、一旦ここまでとします。
次は構造体から勉強します。
Linux マシン(主に Ubuntu )を初めて使用するときの Proxy 設定

# 背景

`sudo apt update`や`npm install`、`git clone`、さらには`docker serach [package]`を実行するときに、まさか Proxy の設定が必要とは知らず、エラーログを見て検索してエラーログを見て検索...といった多大な労力を割いてしまった。

今後そのようなことがないように備忘録として、本記事を投稿する。

## Ubuntu の Proxy 設定

Proxy の設定をしないと```sudo apt update```などによる外部との接続はできない。

そのため、初めに以下のような設定をする必要がある。

```
$ sudo vi /etc/environment

http_proxy="http://proxy.example.com:8080/"
HTTP_PROXY="http://proxy.example.com:8080/"
https_proxy="http://proxy.example.com:8080/"
HTTPS_PROXY="http://proxy.example.com:8080/"
ftp_proxy="ftp://proxy.example.com:8080/"
FTP_PROXY="ftp://proxy.example.com:8080/"
no_proxy=".example.co.jp,.test.local,server1.example.com,server2.example.com"
```

## npm の Proxy 設定

Proxy 環境下では Ubuntu 自身の Proxy を設定しても、npm 用の Proxy 設定をしないと```npm install```による外部との接続ができない。

そのため、以下のような設定をする必要がある。

### 1. 現在の設定の確認

まずは現在の npm の設定を確認する。

```
$ npm config ls -l
```

### 2. npm 用の Proxy の設定

デフォルトでは環境変数の HTTP_PROXY か http_proxy の値を見るらしいが、自分の場合は設定したにもかかわらず通信ができなかったので、以下の設定で npm に Proxy 設定を行った。

```
$ npm config set proxy http://proxy.example.com:8080
$ npm config set https-proxy http://proxy.example.com:8080
```
## Git の Proxy 設定

こちらは Proxy の設定というよりかは初期設定に近い話であるが、Proxy の設定も必要なので、この記事でまとめることにする。

### 1. Git のユーザ設定

```
$ git config --global user.name "First-name Family-name"
$ git config --global user.email "username@example.com"
```

### 2. Git の Proxy 設定

```
$ git config --global http.proxy http://proxy.example.com:8080
$ git config --global https.proxy http://proxy.example.com:8080
```

## Docker の Proxy 設定

Docker にも Proxy の設定が必要であったので、ここにまとめる。

### 1. Docker 自身の Proxy 設定

```
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ echo -e "[Service]\nEnvironment=\"HTTP_PROXY=http://proxy.example.com:8080/\"" | sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf

[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080/"

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

### 2. Container 用の Proxy 設定

以下を記述することで、Container の環境変数`HTTP_PROXY`に Proxy の URL がセットされる。

```
$ mkdir ~/.docker
$ vi ~/.docker/config.json

{
   "proxies":
   {
       "default":
       {
           "httpProxy": "http://your.proxy.url:port"
       }
   }
}
```
> 参考：[Proxy 環境下のための Docker の設定](https://qiita.com/homines22/items/00eebe3c36a9591c3803)
Nest Hubを使って家にいる家族と通話する

# はじめに

最近 Nest Hub を買いました。
できることは基本音声だけの Google Home と変わらないのですが、
Nest Hub だけができることとして Google Duo を使った通話があります。
（カメラはついてないので音声通話だけ）

  [スマートディスプレイでビデオ通話をする](https://support.google.com/assistant/answer/9071980?hl=ja)

  ※リンク先によるとまだ日本語には対応していないことになっている (2019/06/15 現在)


# やりたいこと

家には固定電話がないので、外から家にいる子供と通話したいことがたびたびありました。
以下を実現したいです。
今までは家にあるタブレットを使って LINE で連絡をとったりしていましたが、バッテリーが切れていたり LINE の通知に気づかないことも多く、リビングに固定的においてある Nest Hub を使えばうまくできそうです。 


 1. スマートフォン (パパ) → Net Hub （子供)

    外にいるときに家の子供と通話したいケースです。

 2. Nest Hub (子供) → スマートフォン (パパ)

    逆に、子供から通話したいこともあるでしょう。

![Nesthub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131166/d0db8a40-aa72-e764-ba88-095e4cbd764c.png)

結論としては、多少面倒なところはありつつもやりたいことは実現できました。
（バグっぽい挙動もあるので将来は改善されそう）

# 実現方法

私のスマートフォンは Android ですので、以下も Android で確認した方法になります。

## 準備

まずは Google Duo 自体のセットアップが必要ですがここは省略します。
案内に従って Google アカウントに電話番号を紐づけて、Duo を使えるようにします。

次に Nest Hub に Duo のアカウントを紐づけます。
設定方法は下記に記載されています。

https://support.google.com/assistant/answer/9071980?hl=ja

これで通話はできそうですが、実際の通話には現時点では一工夫必要でした。

追記）
Nest Hubを使って Duo で電話をするためには、Voice Match を行って利用するアカウントと人を紐づけて置く必要があります。（かつ、Duo で利用する SMS 認証のための電話番号がそれぞれ必要です。）
今回の場合だと、自分と子供両方の Google アカウントを準備して、それぞれ Voice Match 及び Duo の準備をしておく必要があります。

Nest Hub には複数のアカウント (Duo の電話番号) を紐付けることができ、どのアカウントにかかってきた Duo 通話も Nest Hub で着信を受けることができます。

## スマートフォン → Nest Hub

Duo のアプリから Nest Hub に通話したいのですが、自分自身のためか連絡先に表示されません。
また、Google の Help によると Google Assistant に「リビング（Nest Hub の名前）にビデオ通話して」と話しかけると通話できそうですが、こちらもうまく動きませんでした。

うまくいった方法としては、電話帳（連絡先）に自分の電話番号を登録しておき、電話帳アプリ→自分の連絡先→「080-xxxx-yyyy 宛に Duo のビデオ通話を発信」を選択することで Nest Hub に対して発信して通話することができました。

追記）
アカウントを分けている場合は、子供のアカウント (電話番号) を連絡先に登録しておくことで、
Duo からも普通に通話することができます。

追記）
Duo からアカウントに紐付けられた Nest Hub が連絡先に見えるようになり、
直接通話できるようになりました。

## Nest Hub → スマートフォン

「xx に電話して」と話すことで通話ができるそうですが、こちらも連絡先に自分の連絡先がうまく表示されずうまくいきませんでした。

電話番号に対して、「080-xxxx-yyyy に電話して」と話すとスマートフォンに対して発信ができます。
ただ、毎回番号を言うのは大変なので、Google Home からルーティンに「パパに電話して：080-xxxx-yyyyに電話して」と登録することで簡単に発信できるようにしています。

追記）
子供のアカウントの連絡先にパパ:080-xxxx-yyyy と登録しておくことで、「パパに電話して」で普通に通話することができます。

なお、アカウントを分けている場合は、ルーティンもそれぞれのアカウントで登録しておく必要があります。

# まとめ
Nest Hub を使うことで家にいる家族（主に子供）と簡単に通話できるようになりました。
もちろん LINE などを使うことで通話はできますが、固定的においてあるデバイスを使って声で簡単に発信／受信できるので、子供でも簡単に使えそうです。
[python] シェルからpythonファイルの関数を実行する

## どういったときに使うのか
自作したpythonファイル内に大量の関数があり，それらを個別で使用したいが，そのために大量の実行用ファイルを作りたくない，複雑な引数制御を書きたくない，というとき。

例えば，通信試験を行うとき，大量の通信コマンドを任意のタイミングで動かす必要があるため，手動でコマンドライン操作を行うことになると思いますが，そういったときに，もしかしたら本記事の内容が役に立つかもしれません。

## 本記事の環境
そこまで気にしなくてもいいと思いますが，一応書いておきます。

* Windows10
* Python 3.7.3 
* git-bash 4.4.23

## ファイルの準備
解説用に次のpyファイルを作ります。引数のない`hello`関数と2つの引数がある`add`関数が書かれています。これをターミナルから実行してみます。

```call_test.py
def hello():
    print('hello qiita')

def add(a, b):
    print(a + b)
```

## 方法1: pythonのcmdオプションを使う
典型的な方法として，pythonの[cmdオプション](https://docs.python.org/ja/3.6/using/cmdline.html#cmdoption-c)を使う方法があります。

```
python -c <command>
```

pythonを実行するとき，上記のように`-c`をつけることで後ろのコマンドを実行できます。コマンド内での改行は`;`で表現します。

これを使って上記のpyファイルの関数を呼び出してみましょう。

```sh:hello関数を実行する
python -c "import call_test; call_test.hello()"
```

```sh:実行結果
hello qiita
```

hello関数が実行されていることがわかると思います。次に，引数がある関数を実行します。

```sh:引数がある関数を実行する
a=1
b=2
python -c "import call_test; call_test.add($a,$b)"
```

```sh:実行結果
3
```

pyファイルを編集せずに済むので，最もよく使われる方法だと思います。ただし，importを書く必要があるため，コマンドが冗長になりやすいという欠点があります。

## 方法2 : 汎用的なmain関数を作る
状況によっては，やっぱりmain関数を作ったほうがいい場合もあると思います。例えば，初期化処理がimportだけでは済まず，長大なコマンド文が必要になる場合，関数の戻り値に応じた制御が必要な場合，などです。

このとき大事なことは，関数名をmain関数のソースコード上にべた書きしないということです（そこにミスがあったら何の試験をやっているのかわからなくなる）

説明用にmain関数を作りました。先ほどの`call_test.py`に以下のmain関数を追加してください。標準的な引数（任意個数の`float`や`str`）には対応するように書いたので，割と使いまわせると思います。

```py
import argparse
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('function_name',
                        type=str,
                        help='set fuction name in this file')
    parser.add_argument('-i', '--func_args',
                        nargs='*',
                        help='args in function',
                        default=[])
    args = parser.parse_args()

    # このファイル内の関数を取得
    func_dict = {k: v for k, v in locals().items() if callable(v)}
    # 引数のうち，数値として解釈できる要素はfloatにcastする
    func_args = [float(x) if x.isnumeric() else x for x in args.func_args]
    # 関数実行
    ret = func_dict[args.function_name](*func_args)
```

使い方は次のようになっています。ファイル名と関数名を並べて指定し，関数内引数が存在する場合は`-i`オプションの後に指定します。

```
python <file.py> <関数名> -i <関数内引数>
```

例えば，先ほどの`-c`オプションの解説と同様のことは，次のようにできます。

```sh
# call_test.py の hello() を実行
python call_test.py hello
# call_test.py の add(1,2) を実行
python call_test.py add -i 1 2
```

可読性は，やっぱりこっちのほうがいいかなと思います。

## さいごに
実は[runpパッケージ](https://pypi.org/project/runp/)といったpythonの関数をターミナルから呼び出すことに特化したpythonパッケージがあります。`runp`はpipで入れられたのですが，残念なことに，python3系には対応していないようでした。3系に対応したrunpのようなパッケージをどなたかご存じであれば，教えてください（時間があれば自分で作りたいけど…）

## 参考資料
- [stackoverflow: Run function from the command line](https://stackoverflow.com/questions/3987041/run-function-from-the-command-line)
- [GitHub: vascop/runp](https://github.com/vascop/runp)
- [Qiita: ArgumentParserの使い方を簡単にまとめた](https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0)
- [Qiita: Python - 関数を文字列から動的に呼び出す](https://qiita.com/Chanmoro/items/9b0105e4c18bb76ed4e9)
パスワード用文字列生成関数 (Python3)

記号、数字の割合を制御しながらランダムな文字列を生成する関数

```
import random
import string
from typing import List


def get_pw(length: int = 10, symbols: str = string.punctuation,
           digit_ratio: float = 0.2, symbol_ratio: float = 0.2) -> str:
    assert digit_ratio + symbol_ratio <= 1
    
    def get_chars(length: int, candidates: str) -> List[str]:
        return list(random.choice(candidates) for i in range(length))

    digit_num = int(length * digit_ratio)
    symbol_num = int(length * symbol_ratio)
    letter_num = length - digit_num - symbol_num

    chars = get_chars(digit_num, string.digits) \
        + get_chars(symbol_num, symbols) \
        + get_chars(letter_num, string.ascii_letters)
    
    random.shuffle(chars)
    return ''.join(chars)


print(get_pw())  # j4U*2fic=b
print(get_pw(8))  # XsR&Zu2j
print(get_pw(symbols='!-_'))  # BpSX!_49mj
print(get_pw(digit_ratio=0.7))  # 146!X8@908
```
WordPressでページごとに背景色を変えるやり方

## 概要
WordPressで自分のサイトを簡単に作っています。個人でやっていて自分の実績を載せるポートフォリオのようなイメージのサイトです。
シンプルな見た目を意識して作成しているのですが、逆にメリハリがなくなってしまったのでアクセントをつけることを目的としています。

## やること
具体的にやることとしては、ページに背景色をつけて見た目にめりはりをつけることです。特にトップページはコンテンツが一覧として流れているので、どこが区切りであるか見えずにパッとしないという印象でした。これを改善します。

## 手順
### 背景色が違うテンプレートを作成
まずは新しいテンプレートファイルを作成します。レイアウトは同じで背景色を変えるのでページファイルとヘッダーファイルをそれぞれコピーして任意の名前に変更します。

![Screenshot_2019-06-13_07-51-18-944.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/1ae081d0-587e-af94-3c5d-c4c5821c59a8.png)

作成したページファイルへテンプレートとしてみなす記述を追加し、ヘッダーの呼び出しを変更します。

![Screenshot_2019-06-13_07-53-18-088.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/129ac90a-ade5-dd87-67f8-c7f66da6421f.png)

呼び出すヘッダーへ背景色を変えるためのスタイルを追記します。

![Screenshot_2019-06-13_07-54-06-061.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/4934a31b-8b4d-512c-63a6-09e30312af25.png)

### CSSで背景色を定義
WordPressの標準機能へ組み込みます。背景色の指定だけなのであっさりした記述。
![Screenshot_2019-06-13_07-57-07-188.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/42cfa20d-c089-f44e-43d0-280a772882fc.png)

色はこちらのサイトを参考にするといいです。
https://www.colordic.org/

### 固定ページのテンプレートを変更
固定ページの編集画面を開き、テンプレートを選択するだけです。テンプレートファイルを増やすとこの表示が出てきます。
![Screenshot_2019-06-15_15-42-56-484.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/aefa68cf-150b-1660-335a-8ad9859d9d89.png)
※注意事項
テンプレートを変更してプレビューしても、変更を確認できません。ページの設定を「更新」してからテンプレートが変わったことを確認しましょう。

### トップページの背景色を個別に指定
ページのテンプレートを変更しても、トップページに表示しているページには反映されませんでした。そのため、該当ページのclass名を確認し、そのclassに対してスタイルを設定します。
![Screenshot_2019-06-15_15-56-24-005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/ab6ecf55-4955-09a8-492d-2772de3eb1e5.png)

![Screenshot_2019-06-13_07-57-07-188-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48817/9dd593bf-10fe-355c-9162-8ce6e324243a.png)

### 変更されたか確認
トップページ、遷移後のページを見て変更が反映されていることを確認しましょう。色合いや細かい調整を行う場合は個別ページでデザインを変更、CSSでスタイルの設定をしていきましょう。

## さいごに
簡単な内容でしたが、これを参考に個別にスタイルを作り込んで独自のサイトを構築する手助けになればと思います。
最後まで読んでいただき、ありがとうございました。
Elixirの関数呼び出しで引数の意味をわかりやすくする

# モチベーション
Elixirの関数の引数の意味は位置だけで決まります。たまに関数の名称から各引数の役割が読みにくく戸惑うことがありました。

`Enum.reverse/1`を例にとります。

```elixir
Enum.reverse([1, 2, 3])
```
の結果が`[3, 2, 1]`になることは容易に想像できると思います。この場合は特に問題なしです。

一方で、`Enum.reverse/2`、たとえば

```elixir
Enum.reverse([1, 2, 3], [4, 5, 6])
```
については、日常的にElixirを使い続けている人でなければ、ドキュメンテーションなしには結果が予想しにくいのではと思います。

結果は`[3, 2, 1, 4, 5, 6]`で、第1引数 (`enumerable`) を逆順にし、その後ろに第2引数 (`tail`) を結合したリストになります。特に関数名に紐づかない処理なので、一見わかりませんよね。。

この動作をコードをぱっとみただけでわかるようにしたい！

## たとえばPythonの場合
まず思い出したのはPythonのキーワード引数でした。

たとえば、`csv.DictWriter`のコンストラクタの第2引数には、各カラムの名称を与える必要があります。

```python:位置引数
writer = csv.DictWriter(sys.stdout, ['a', 'b', 'c'])                                                                          
```
（引数の絵面からなんとなく意味がわかってしまい、悪い例かもしれません。。）


これは下記のようにも書くことができます。

```python:キーワード引数
writer = csv.DictWriter(sys.stdout, fieldnames=['a', 'b', 'c'])                                                                          
```

引数名がコードに明示されるので、役割が明確になりますね。


## Elixirの場合
こういったことがElixirでもできないか？と悩む日々を過ごしていましたが、[`Access`モジュールのソースコード](https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/access.ex) を読んでいたときに、これだ！という書き方を見つけました。

```elixir:access.ex
defp all(:get_and_update, data, next) when is_list(data) do
  all(data, next, _gets = [], _updates = [])
end
```

`_gets`と`_updates`を用いて、引数の意味を表しています。アンダースコアで始まる変数は以後使われないので、機能的な影響はないと考えられます。

## 気になる点
これで引数の意味がわかりやすくなりました！が、デメリットがないか考察してみました。

### ネーミング
Pythonのキーワード引数は名前を完全に一致させないと`TypeError`になりますが、Elixirで先ほどのやりかたをしようとすると、`_gets`のようなネーミングは書き手のセンスになります。

### そもそもわかりやすくする
自作の関数であれば、そもそもわかりにくい関数名をつけない、雑多な引数はよくある`opts`のようなキーワードリストにする、などの工夫もできるかもしれません。

### パフォーマンス
引数名をつけない場合とつける場合でパフォーマンスを比較してみました。

<details><summary>計測用コードはこちら</summary><div>

```elixir
defmodule Argtest do
  @n_iter 300_000_000

  defp fun_with_many_args(a1, a2, a3, a4, a5) do
    a1 + a2 + a3 + a4 + a5
  end

  def timeit_plain do
    :timer.tc(fn ->
      Enum.each(1..@n_iter, &fun_with_many_args(&1, 2, 3, 4, 5))
    end)
    |> elem(0)
    |> IO.inspect(label: "plain")
  end

  def timeit_annot do
    :timer.tc(fn ->
      Enum.each(1..@n_iter, &fun_with_many_args(&1, _a2 = 2, _a3 = 3, _a4 = 4, _a5 = 5))
    end)
    |> elem(0)
    |> IO.inspect(label: "annot")
  end
end
```
</div></details>


結果は下記の通りで、実行時間に変わりはないようです。引数名の変数は未使用であることがわかっているので、最適化の段階で削除されているのでしょうか。

```bash
# 引数名をつけない
> MIX_ENV=prod mix run -e Argtest.timeit_plain
plain: 17667837
# つける
> MIX_ENV=prod mix run -e Argtest.timeit_annot
annot: 17418437
```


なお、iexでは引数名をつけたほうが実行に時間がかかりました。

```elixir
iex> fun_with_many_args = fn a1, a2, a3, a4, a5 -> a1 + a2 + a3 + a4 + a5 end
iex> :timer.tc(fn -> Enum.each(1..1_000_000, & fun_with_many_args.(&1, 1, 2, 3, 4)) end) 
{7086417, :ok}
iex> :timer.tc(fn -> Enum.each(1..1_000_000, & fun_with_many_args.(&1, _a1 = 1, _a2 = 2, _a3 = 3, _a4 = 4)) end)
{9065831, :ok}
```

## まとめ
引数の意味がわかりにくい関数は

```elixir
iex> Enum.reverse([1, 2, 3], _tail = [4, 5, 6])
[3, 2, 1, 4, 5, 6]
```
のように引数に「アンダースコア + 引数名」をつけて呼び出すとわかりやすい！