OmniAICreator/Qiita-1.07M huggingface dataset:
研究室のwifiと大学のwifiをよしなに接続するスクリプトを書いた


#td;tl
**優先的に使用したいWiFi**( 研究室wifi。速い。)と、
**接続に認証が必要なwifi**( 大学学内wifi。遅い。 )がそれぞれ大学に存在し、
研究室内では研究室wifi, それ以外の学内では学内wifiへ接続したい。

しかし、**接続に認証が必要なwifi**の認証が面倒臭くて、htmlで学番とパスワードを入力しなければいけないタイプ。
学内wifiに繋ぐのもhtmlでの認証が必要だし、いちいちつなぎ直すのも面倒くさい。
面倒くさかったのでshellで書いた。

実行するとよしなに繋いでくれる。

[2357gi/auto_connect_any_wifi](https://github.com/2357gi/auto_connect_any_wifi)

# つかいかた
## じゅんび
`git clone`して環境変数を設定してください。

```bash:connect_any_ssid.sh
︙

PRIMARY_SSID=$l_ssid
PRIMARY_PASSWORD=$l_password

SECONDRY_SSID=$u_ssid
SECONDRY_PW=$u_pw
STUDENT_ID=$s_id
STUDENT_PW=$s_pw

︙
```

`PRIMARY_*`が優先的に接続したいwifi(ここなら研究室のwifi),
`SECONDRY_*`が接続に認証が必要なwifiです。
`STUDENT_*`は学生番号とパスワードです。  

## つかう

実行すればよしなにwifiを繋いでくれます。
もしプライマリーwifiがありましたらそちら、
なかったらセカンダリーwifiを繋ぎます。
弊学用のwifi認証用のコードもあります。学生情報正しく入力していれば繋いでくれるはず。

touchbarなりに登録したりしてよしなにやってください。

ちなみにもう一つのshellscriptは現在接続しているwifiを表示するやつです。
ぼくはこれを使ってtouchbarにssidを表示しつつ、それをタップすると`connect_any_ssid.sh`が走るようになってます。

touchbarにshellscriptが登録できない？そもそもカスタマイズできない？だって？？
うるせえこの[ \[お前らのTouch Barはダサい - Qiita\] ](https://qiita.com/2357gi/items/8235093de77aa3e5fecc)を読め
Windows版のQEMUでDebian 10.0(PowerPC)をインストールしてみた。

梅雨でむしゃくしゃしたのでQEMUにDebian 10.0(PowerPC)をインストールしてみたメモを置いておく。

## 用意するもの
qemu-w64-setup-20190218.exe

## 手元の環境
NEC Lavie LS150/F (Pentium B950 2.10GHz)
Windows 10 (64bit版)

## 手順メモ
1. QEMUをダウンロードして、手元のPCにインストール
2. インストール先フォルダを C:\qemuwork とする
 （フォルダ名は何でもよいが、Program Files配下だとパスが長くなりがちなので、作業上判りやすい名前のフォルダ配下とした方がよい）
3. コマンドプロンプトを開き、QEMUで使用するqcow2ディスクを作成する
```
qemu\qemu-img.exe create -f qcow2 c:\qemuwork\debian-macppc.qcow2 70G
```

4. Debian 10.0をインストールする
```
.qemu\qemu-system-ppc.exe -L pc-bios -M mac99,via=pmu -m 1024 -net nic,model=sungem -net user -hda debian-macppc.qcow2 -cdrom debian-10.0-powerpc-NETINST-1.iso -boot d -g 800x600x8
```
注) 手元のPCの解像度が1366x768のため、QEMU上の解像度(-g オプション)を800x600としている。Debianインストーラの画面が見切れないように

5. あとは通常のDebianインストーラの操作となる(手順は省略)

## 参考URL
https://wiki.qemu.org/Documentation/Platforms/PowerPC
　⇒"Debian 10 (Buster)" 以降の部分
　　同ページ下部の "Debian 10 PPC release" にisoイメージがある
[USBで持ち歩けるポータブルな開発環境 作ってみた](https://qiita.com/pixie-grasper/items/6d42f284b2ce58ac15e7)
Xcodeでエンコーディングしても反映されている気配がない

## 問題
[これ](https://youtu.be/K2dapXxPgJ0)はXcodeを用いてファイルインスペクタからエンコードを変更することで、あるC言語ファイルの文字化けを解消しようとしている動画である。
だが、どんなにエンコードを変更しても表示が変わらず、一向に反映されている気配がない。

## 対処法
[この](https://youtu.be/KchfLidc1x4)ように、一度テキストエディタで開いてから上書き保存すると、正しく表示されるようになる。
アプリケーションにBasic承認を導入する時にハマったこと！！



#Basic認証とは
Basic認証とは、HTTP通信の規格に備え付けられているユーザー認証の仕組み

解決したいこと
アプリケーションにBasic承認を導入する
正しいパスワードを設定し入力しているはずだが、ログインできない
（入力フォームが表示され入力もできる）
以下動作動画
https://gyazo.com/272b9a414067dc55c898907512c02b10
＊ターミナル上では４０１のエラーが起きている


設定の流れ

```rb:ApplicationController.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth

  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == 'sample' && password == '1234'
    end
  end
end
```
秘匿情報は公開できないので、環境変数を設定する！

```
username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
```
```:.bash_profile
#環境変数を設定

$ vim ~/.bash_profile
[I]
export BASIC_AUTH_USER='sample'
export BASIC_AUTH_PASSWORD='1234'
$ source ~/.bash_profile
```
正しいパスワードを設定し入力しているはずだが、ログインできない
（入力フォームが表示され入力もできる）
＊４０１エラー

検証したこと
1.コントローラに直接ユーザー名とパスワードを入力すると正しくログインできる
	
2.Rails consoleで確認すると正しく値を取得できている？

	[1] pry(main)> ENV["BASIC_AUTH_USER"]
	=> ”sample”
	[2] pry(main)> ENV['BASIC_AUTH_PASSWORD'] 
	=> "1234"
3./etc/environment、vim ~/.bashrcに記載し直しても解決しなかった
　
4. binding.pryでは以下のように表示される

  ```

     6: def basic_auth
     7: 
     8:   authenticate_or_request_with_http_basic do |username, password|
 =>  9:     binding.pry
    10:     username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
    11:     
    12:   end
    13: end
[1] pry(#<ItemsController>)> username 
=> "sample”
[2] pry(#<ItemsController>)> ENV["BASIC_AUTH_USER"]
=> nil

```

#仮説

→環境変数を設定しているが、コントローラで正しい値を取得できていないかもしれない

##解決の糸口
rails cでは値が取得できているが、rails sをbinding.pryで止めて値を確認すると『nil』
この二つの違いは何だろうか？？

あっ、そういえばターミナルではそれぞれ別のタブを開いて作業している！
もしかすると、、、片方のタブで書き込んだ環境変数は、同時に立ち上げているもう一つのタブには反映されないのかもしれない！！

#<img width="935" alt="スクリーンショット 0001-06-30 12.47.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445389/0425fcfb-a6bd-a8c4-c296-707b15348dbf.png">

rails sしているタブで、＄env を入力し中身を確認すると、、、、確かに別タブで設定したつもりのBASIC認証の環境変数がない！！！

⇨改めてrails sしていたタブで＄source ~/.bash_profile すると、、、、
うまくいった！！！！！！！！！


学んだこと
basic承認に限らず、
ターミナルの環境変数はタブを立ち上げた瞬間に一度だけ読み込まれる。
もし、他のタブで環境変数などの設定をいじったら、関連するタブ全てに更新をかけること！！！以上
論文紹介-#2 Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks

## 論文紹介-#2 
[落合先生のフォーマット](https://www.slideshare.net/Ochyai/1-ftma15?ref=http://lafrenze.hatenablog.com/entry/2015/08/04/120205)を元に論文をまとめ紹介していく記事です。

今回は、CVPR2018の[Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks](http://openaccess.thecvf.com/content_cvpr_2018/papers/Feng_Wing_Loss_for_CVPR_2018_paper.pdf)という論文を紹介します。
至らないところばかりなのでツッコミお待ちしてます！

## どんなもの？
CNNベースのfaces alignmentにおいてL2 よりL1, L1 smoothの方が良いことを示した。
wing lossという新しいloss functionを提案と顔のポーズのデータバランス戦略、二段階のalignment frameworkによりface alignmentでSOTA。

## 先行研究と比べてどこがすごい？
既存研究の多くが外れ値に敏感なL2 loss関数を使っているのに対して、新しいwing lossを提案。
精度はSOTAではないが、6層のCNNを使うことで他の既存DNN face alignmentよりも早い結果に。
入力サイズは恐らく224 * 224 * 3
<img width="294" alt="スクリーンショット 2019-06-30 18.24.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218202/4893e26d-21a7-a936-5d6a-3c9d82f5e10e.png">


## 技術や手法のキモはどこ？
L1もL2も大きなlossに学習が影響されやすい。wong lossは小さなlossと大きなlossの影響のバランスをうまく取った。

## どうやって有効だと検証した？
AFLWと300Wデータセットに対して、既存研究と精度比較した。
様々なbaseCNNを用い、展開性を検証した。
少数の訓練サンプルを複製し、ランダムな回転などのデータオーグメントを適用することでデータの不均衡問題に対応した。
<img width="389" alt="スクリーンショット 2019-06-30 18.20.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218202/909a3889-9818-6ca0-89f7-3563053b013a.png">
<img width="390" alt="スクリーンショット 2019-06-30 18.20.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218202/2fc144fa-dd92-7940-20b2-c7f329f4339e.png">

## 議論はある？
CNNベースの他の回帰問題にもwing lossは使えるのではないか？

## 次に読むべき論文は？
[A Deep Re-gression Architecture With Two-Stage Re-Initialization for High Performance Facial Landmark Detection](http://ir.ia.ac.cn/bitstream/173211/20074/1/CVPR17ADeepRegressionArchitectureWithTwoStageReInitializationForHighPerformanceFacialLandmarkDetection.pdf)
Arduinoを使った電子工作教育的おもちゃスマートロボットカーV3.0で遊ぶ

# 目的

amazonで売っていたスマートロボットカーV3.0 電子工作教育的おもちゃを衝動買いしました。
工作して遊んだ際の記録です。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">中国製のスマートロボットカーを買って組み立てて動かしただけ <a href="https://t.co/OM0aTHkSnp">pic.twitter.com/OM0aTHkSnp</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1140640572413059078?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 準備
[ELEGOO スマートロボットカーV3.0 電子工作教育的おもちゃ、全年齢対象ロボット](https://www.amazon.co.jp/dp/B06Y5N73CZ/ref=cm_sw_r_tw_dp_U_x_eOCbDbH51JY4D)


# 接続図
https://www.elegoo.com/download/
Elegoo Smart Robot Car Kit V3.0 を参照

# コード

プログラムは下記の「Obstacle_Avoidance_Car.ino」を使用しています。

```
URL        : https://www.elegoo.com/download/
Document   : Elegoo Smart Robot Car Kit V3.0
             Lesson 2   Obstacle_Avoidance_Car
Obstacle_Avoidance_Car.ino 
```



# テスト
ロボットカーが動けばOK

# FAQ
制作所要時間は３〜５時間ほど
接続を間違わなければスムーズ、間違えたら原因特定に一苦労すると思います。

# 参考
[ELEGOO スマートロボットカーV3.0 電子工作教育的おもちゃ、全年齢対象ロボット](https://www.amazon.co.jp/dp/B06Y5N73CZ/ref=cm_sw_r_tw_dp_U_x_eOCbDbH51JY4D)
[スマートロボットカーを子供と組立てた 親サポートの難易度が思うより高い…](https://enjoy-taboriedman.com/2019/01/09/post-2273/)
[elegoo.com  - download](https://www.elegoo.com/download/)
Sysdig Inspect をつかってみた

## sysdigとは？

Linux上で、straceやtcpdumpのように、システムコール、IOや通信状況をキャプチャするオープンソースのコマンドラインツール。システムで何が起こっているのかをキャプチャしトラブルシュートなどを行うことができます。

インフラエンジニアならよくある、問題が起こったときに、grepやzcatを駆使して特定時間のログを探りに行ったりしたことはないですか？そのときのLinuxの状況をキャプチャしておくことができます。

システムに関するraw dataをキャプチャしておいて、その原因を探るためのビジュアライズツールといえそうです。

たとえば、`$sysdig -w dump.scap -M 10` で、10秒間sysdigにてシステム情報を祝して、 `dump.scap`ファイルに保存できます。


## sysdig Inspectorはなに？
sysdigでdumpしたファイルをwebにて、visualizeすることができます。
時間を狭めたり

https://github.com/draios/sysdig-inspect


## ツール群

**sysdig : Linuxの状況をキャプチャーするツール**

```
$ sysdig
56914 08:26:18.796286489 0 sshd (20271) < select res=1 
56915 08:26:18.796287455 0 sshd (20271) > rt_sigprocmask 
56916 08:26:18.796287741 0 sshd (20271) < rt_sigprocmask 
56917 08:26:18.796288238 0 sshd (20271) > rt_sigprocmask 
56918 08:26:18.796288450 0 sshd (20271) < rt_sigprocmask 
56919 08:26:18.796289193 0 sshd (20271) > clock_gettime 
56920 08:26:18.796289466 0 sshd (20271) < clock_gettime 
56921 08:26:18.796290207 0 sshd (20271) > read fd=10(<f>/dev/ptmx) size=16384 
56922 08:26:18.796290788 0 sshd (20271) < read res=145 data=..2564 08:26:18.739307667 0 sshd (20271) < write res=124 data=.b..~%T,u=.k...I..
```
https://github.com/draios/sysdig#what-does-sysdig-do-and-why-should-i-use-it

**csysdig : LinuxテキストUIライブラリ、curses　をつかってつくったコマンドラインUI (クリックできる！！！）**
<img width="1106" alt="Screen Shot 2019-06-30 at 17.39.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1232/f57d1632-65a2-a10b-4175-3010dd787508.png">


**sysdig-inspector : sysdigのdumpファイルをウェブでUIにおとしてくれる**
<img width="1499" alt="Screen Shot 2019-06-30 at 17.39.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1232/8a0e9fe8-c84e-5da3-18fe-2cd08d71bdbd.png">



## sysdig inspectorの使い方


**1. captureする**

`$ mkdir -p /usr/share/sysdig/captures` dumpファイルを置くディレクトリつくっておく
`$ sysdig -w /usr/share/sysdig/captures/dump.scap -M 10`  スナップする

**2. inspectorをdockerで立ち上げる**


`$ docker run -d -v /usr/share/sysdig/captures:/captures -p80:3000 sysdig/sysdig-inspect:0.4.0` 3000portでたちあがるので、そのまま80portにアサイン

`$ docker logs -f <<container-id>>` ログを見て起動を確認する

**3. dockerを起動した、URLにアクセスして、フルパスでファイルを指定する**
<img width="1117" alt="Screen Shot 2019-06-30 at 18.17.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1232/a6315419-df9e-bb33-7b80-05805161bbf9.png">


pathを入れて、Ｅｎｔｅｒ。
WebUIにてInspectorが立ち上がります。
<img width="1498" alt="Screen Shot 2019-06-30 at 18.19.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1232/597a289f-fea3-dc54-6d47-8420bb966c85.png">



## ちなみにMac版もあります。

https://github.com/draios/sysdig-inspect　
にMac版もあります。ファイルをFinderで指定してオープンすることができます。


<img width="461" alt="Screen Shot 2019-06-30 at 18.20.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1232/7326f27a-f115-2ff0-db57-00854ce60c20.png">
勾配降下法をアニメーション化した

機械学習でよく使われる勾配降下法をアニメーション化した。
勾配降下法を使うとパラメータの値を逐次的に更新していくことによって一番尤もらしいパラメータの値を求められる。
関数$f(\theta)$のパラメータ$\theta$のj回目の更新式は以下のように表せる。


```math
\theta_j := \theta_j - \eta f'(\theta)
```

毎更新のたびに、$\theta$から$f'(\theta)$と学習率$\eta$の積を引いていく。値が収束するまでこれを続ける。



```python

%matplotlib nbagg
fig = plt.figure()
x = np.linspace(-10, 10)
y = x ** 2
plt.ylim(-10, 100)
plt.plot(x, y)
ims = []
lr = 0.1
p = 9
count = 0
while True:
    count += 1
    q = p ** 2
    slope = 2 * p
    intercept = q - (abs(p) * slope)
    y2 = intercept + x * slope
    img = plt.plot(x, y2)
    ims.append(img)
    diff = slope * 2 * lr # 傾き * 学習率がdiff
    p = p - diff
    if abs(slope) < 0.1:
        break



ani = animation.ArtistAnimation(fig, ims, interval=300)
plt.show()
```

![anim-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275145/9678ee6f-34c3-5d78-3a26-82e4d0c51974.gif)
繰り返し二乗法をpythonで実装してみた

蟻本p114の繰り返し二乗法をpythonで書いてみた:relaxed:
通常のべき乗を計算とどの程度高速化ができているかを$3^{1000}$の計算で比較します。

####繰り返し二乗法の実装
```python
import time

def pow(x, n):
  ans = 1
  while(n > 0):
    if(bin(n & 1) == bin(1)):
      ans = ans*x
    x = x*x
    n = n >> 1 #ビットシフト
  return ans

x = 3
y = 1000

start = time.time()
#繰り返し２乗法を使う場合
ans1 = pow(x,y)
elapsed_time1 = time.time() - start
print ("elapsed_time1:{0}".format(elapsed_time1) + "[sec]")
#通常のべき乗
ans2 = x**y
elapsed_time2 = time.time() - elapsed_time1
print ("elapsed_time2:{0}".format(elapsed_time2) + "[sec]")
```

####結果比較
```
#繰り返し二乗法
elapsed_time1:8.797645568847656e-05[sec] 
#通常のべき乗
elapsed_time2:1561884434.65922[sec]
```


めっちゃ早い・・・！
Leetcode #389: Find the Difference

```swift
func findTheDifference(_ s: String, _ t: String) -> Character {
    var dict = [Character: Int]()
    for char in s {
        if let value = dict[char] {
            dict[char] = value + 1
        } else {
            dict[char] = 1
        }
    }
    
    for char in t {
        if let value = dict[char] {
            if value == 0 {
                return char
            } else {
                dict[char] = value - 1
            }
        } else {
            return char
        }
    }
    return "X"
}
```
AWS S3のETagにファイル名は関係ない

# 概要

AWS S3のETagはファイル内容のmd5ハッシュ値であるため，ファイルの内容が同一かどうかを簡単に確認することができます．

ところで，ファイル名が異なるとETagの値は異なるのでしょうか？
ファイル内容に対するハッシュ値なのでファイル名は関係しないと思いますが，実際どうなのか確認しました．

# 結論

ETagの値にファイル名は関係ありません．

ファイル内容に対するハッシュ値なのでファイル名は関係ありませんでした．念の為確認できて安心しました．


# 調査方法

```shell
$ echo "Hello World" >> test1.txt
$ cp test1.txt test2.txt
$ aws s3 cp ./test1.txt s3://<S3バケット名>
$ aws s3 cp ./test2.txt s3://<S3バケット名>
$ aws s3api list-objects-v2 --bucket <S3バケット名>
{
    "Contents": [
        {
            "LastModified": "2019-06-30T08:42:47.000Z",
            "ETag": "\"e59ff97941044f85df5297e1c302d260\"",
            "StorageClass": "STANDARD",
            "Key": "test1.txt",
            "Size": 12
        },
        {
            "LastModified": "2019-06-30T08:42:51.000Z",
            "ETag": "\"e59ff97941044f85df5297e1c302d260\"",
            "StorageClass": "STANDARD",
            "Key": "test2.txt",
            "Size": 12
        }
    ]
}

$ md5 test1.txt
MD5 (test1.txt) = e59ff97941044f85df5297e1c302d260
```
Python　戻り値（return）について

どうも。只今Pythonについて勉強してるMarnyです。
勉強してて、疑問に思った**「戻り値」**について、自分の勉強も兼ねて説明していきます。（間違いがあったら指摘お願いします（笑））

#戻り値とは　（return）
>そもそも戻り値とは、
**「関数の呼び出し元に、関数本体から特定の情報を返す。」**

というのが定義っぽいです。

例として、以下のプログラムを実行しました。

```python

def num():
    print("実行されました")

num()
```
↓実行結果

```python
実行されました
```
これは、単に**「def」**コマンドで関数を定義し、呼び出した形になります。


では、以下のプログラムを実行すると、結果はどうなるでしょう。

```python
def num(a,b):
    c = a*b
    
print(num(2,5))
```
結果は以下のようになります。

```python
None
```
結果は「10」と見せかけて、None…
？？？となりますよね。（笑）
なぜこうなるかというと、num関数をa=2,b=5で呼び出し、c=a*bが実行されましたが、print文からしては、**num(2,5)**という内容なので、cという情報がないのです。ここで使うのが**戻り値（return）**です。
returnを入れるとこのようになります。

```python

def num(a,b):
    c = a*b
    return c

print(num(2,5))
```
結果は

```python

10
```
とちゃんと2*5が適用され、10が出てきました。

僕もこれを知った段階でもいまいち理解できてませんでした。（笑）
なので、以下のようにプログラムを書き換えてみました。

```python
def num(a,b):
    c = a*b
    print(c)

print(num(2,5))
```
このように、num関数内にprint文を追加し、実行してみると以下のようになります。

```python
10
None
```
ちょっとわかりやすくなりました。（多分）
num関数自体にprint文があるので、10の値とNoneという結果になりました。



##最後に
　自分も先ほど勉強し、すぐに書いたものなので間違っているところがあるかしれません。なので、参考程度にかる～くという感じで…（泣）
androidアプリをマルチモジュール化したりビルド時間を短くするコツ

[前回の記事（マルチモジュールにして生産性を上げよう）](https://qiita.com/tak-wisteria/items/4894e7484e2d88effdcb)の続きです。
筆者がマルチモジュール化を通して得た知見を共有します。

#モジュール構成

まずはどんな感じのアーキテクチャにしたのかをご紹介します。
筆者の担当プロダクトは、レイヤードアーキテクチャだったので、以下の様な構造になりました。

![スクリーンショット 0031-06-30 16.00.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15146/34c2c584-febf-c104-b051-0d8d64a3f3d8.png)

## ルール概要
- bridge_diは全てのモジュールから参照OK
- 上位レイヤーから下位レイヤーへの参照はOKだが、逆は禁止（componentが上位、infraが下位）
- 同一レイヤー内では、coreモジュールは参照OK。その他は兄弟間の参照も禁止。（xxxモジュールは、coreは参照OKだが、yyyは参照NG）
- coreモジュールは、基本的には共通コードのみ配置する思想。しかし、レガシーコードの参照が複雑で切り出しに工数がかかる場合は、全てcoreに突っ込む。

### bridge_di
全レイヤー、全モジュールから参照可能。DI(Dependendy Injection)を行うためのフレームワークで、かなり抽象度が高い実装になっています。

### infra層
通信リポジトリ、DB、ストレージ操作などの実装クラス群を配置しています。

### domain層
ビジネスロジックを集約しました。

### component層
UI周りの実装（Activity, Fragmentなど）と、その他、レガシーコードで参照が複雑過ぎて切り出せないコードを全て突っ込んでいます。

#マルチモジュール移行のコツ

###モジュール構成を決め、既存クラスを移動する（ビルドエラーは放置）

空のモジュール、空のパッケージを作成し、ひたすらドラッグ&ドロップします。
（自信のある人はリファクタリング機能を使っても良いかもですが、筆者は予期せぬ自動リファクタで何度も手戻りが発生。。。）

目的のモジュールにクラスが一通り揃ったら、ビルドが通ってなくても一旦、ローカルリポジトリにコミットします。

クラスの移動とビルドエラー修正を同時に行ってしまうと、ビルドエラーの修正内容や、マルチモジュールに適合するための実装が埋もれてしまいます（実装トレーサビリティ低下）。

##徹底的にDIに頼ってビルドエラー修正（依存関係を解消）していく
前述の通り、モジュール間の参照ルールが非常に厳しいので、多少汚いコードでも良いので、まずはDIを徹底的に活用してビルドエラーを解決していきます。
筆者の場合、Dagger2を使っていますが、appモジュールにDagger系の実装を詰め込みました。
interfaceは、infra_coreに配置しました。

##uiは一旦同じモジュールに閉じ込める
uiは様々な依存関係を持ち、カオスになりがちです。ここを理想的な設計にするのはかなり大変。
まずは、uiをcomponent_coreに閉じ込めましょう。fatモジュール上等です。
リファクタリングは、今じゃなくても出来ます。

##共通で外部参照しているライブラリを、徹底的に集約する。
domain_xxxとcomponento_yyyで共通の外部参照ライブラリを参照しているような場合
例えば、infra_coreに外部参照ライブラリのwrapperを作成し、domain層、component層に提供します。
そうする事で、gradleに記載する外部参照ライブラリがinfra層のみに集約され、ビルド時間が僅かに短くなります。

##gradleは徹底してimplement。api参照は禁止。
api参照はとても便利ですよね。しかし、ビルド時間を少しでも短くする為には、徹底してimplementを使います。
例えば、infra_core、component_xxxで同じ外部参照を用いる場合、infra層でapi参照すれば、component層でも依存関係が解消されます。
しかし、component層を修正した際、外部参照ライブラリを探してinfra層まで増分ビルドが発生してビルド時間が短縮されません。

##[Butter Knife](https://github.com/JakeWharton/butterknife#butter-knife)は作法変更が必要

[こちらを参照](https://github.com/JakeWharton/butterknife#library-projects)。
R2クラスを使うことになります。

##java & kotlinが混在するプロジェクトは、kaptのビルドエラー注意
Javaコードの方には適切に依存関係を指定してても、最終的にappモジュールでリンクする際に、kaptでエラーが発生する事があります。
原因を追求するのが望ましいですが、あまり時間がかかるようならば、appモジュールのgradleにビルドエラーが発生するリンク切れをkaptに指定してやりましょう。

##多少の変なコードは一旦、容認する
ここまで読んでいただいた方は、感じているかもしれません。

「本当にこんな事できるの？？メチャクチャになりそうだけど」

はい、抽象度が非常に高いクラスが発生したり、汎用的ではないDIの実装が発生したりすると思います。
ですが、多少の変なコードを許容する勇気も必要と考えています。
いきなり完璧を求めすぎず、別のタイミングでリファクタリングすれば良いんじゃないでしょうか。


#いかがでしたでしょうか
マルチモジュール化すると、依存関係の制約が厳しくなり、実装が面倒になるかと思いきや、モジュール毎に担当範囲が明確になるので、設計に秩序が発生し、楽になったりします。
あとは、モジュール毎にテストを書くと、差分ビルドがそのモジュールのみに限定されるのでビルド時間が早くなったり、メリットも多いです。

設計やビルドにかかっていた時間を短縮し、浮いた時間でコーヒーブレイクしてみてはどうでしょう。
忙しい日々に、少し、ゆとりができるかもしれませんね。
Leetcode #657: Robot Return to Origin

```swift
func judgeCircle(_ moves: String) -> Bool {
    var horizontal = 0
    var vertical = 0
    for char in moves {
        if char == "U" {
            vertical += 1
        } else if char == "D" {
            vertical -= 1
        } else if char == "R" {
            horizontal += 1
        } else if char == "L" {
            horizontal -= 1
        }
    }
    return vertical == 0 && horizontal == 0
}
```
IMAPでGmailを受信する(Ruby編)

ユーザ登録のフロー（メアド入力、メールのURL開く、ユーザ情報入力）をE2Eテストしたかったのですが、gmailをプログラムで受信する検証をしていました。

## 要件
- 2017-01-01以降に送信され、送信者に「corec.jp」を含むメール
- gmailアカウントやパスワードは .env ファイルから読み込む
- vscodeでbundler使ってdebugできる

## 準備
- gmailの設定で「IMAPを有効」及び「安全性の低いアプリからのアクセスの許可」をオンにしておく

## 検証環境

- Windows10
- https://rubyinstaller.org/downloads/ で Ruby+Devkit 2.6.3-1 (x64) をダウンロード、インストール

```
ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]
```

## ソースコード

```ruby:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "mail"
gem "dotenv"
gem "ruby-debug-ide"
gem "debase"
```

```:.bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_JOBS: "4"
```

```json:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "Ruby",
            "request": "launch",
            "name": "ruby",
            "useBundler": true,
            "pathToBundler": "C:/Ruby26-x64/bin/bundle.cmd",
            "program": "${workspaceRoot}/gmail.rb"
        }
    ]
}
```

```:.env.sample
ACCOUNT=example@gmail.com
PASSWORD=example
```

```ruby:gmail.rb
require 'net/imap'
require 'kconv'
require 'mail'
require 'dotenv'
Dotenv.load
imap = Net::IMAP.new('imap.gmail.com', 993, true)
imap.login(ENV["ACCOUNT"], ENV["PASSWORD"])
imap.examine('INBOX')
imap.search(["FROM","corec.jp", "SINCE", "1-Jan-2017"])
  .tap{|x| puts "search results: #{x.size}"}
  .each do |msg|
  s = imap.fetch(msg, "RFC822")[0].attr["RFC822"]
  m = Mail.new(s)
  puts "subject: #{m.subject}"
  if m.multipart?
    if m.text_part
      body = m.text_part.decoded.toutf8
      puts body
    elsif m.html_part
      body = m.html_part.decoded
      puts body
    end
  else
    body = m.body.to_s.toutf8
    puts body
  end
  # break
end
```

## 実行

```sh
cp .env.sample .env
# .env を任意のエディタで開き、ACCOUNTとPASSWORDを編集する

bundle install
bundle exec ruby gmail.rb
```

## 参照

さくっと手元で試したい人はこちらをgit cloneしてどうぞ
https://github.com/oharato/imap-gmail-sample
FactoryBotとCarrierWaveを使ってRSpecに画像ファイルアップロードのテストを通す

#はじめに

はじめまして。かちゃあ([@katya_swa](https://twitter.com/katya_swa))と申します。
Qiita 初投稿です。
CarrierWave、FactoryBotを使って、画像ファイルをmodelスペックへテストを通す事になったので、
調べたことをまとめようと思います。

#環境
ruby 2.5.1
rails 5.2.3
carrierwave
factory_bot_rails





#fixturesディレクトリの作成
まずspec内にfixturesディレクトリがない場合は、作成する。

その後、使いたい画像ファイルをfixturesディレクトリの中に入れる。

ここでは私の場合は、spec/fixturesの中にtest.jpgという画像ファイルを入れています。


#モデル内アップローダの確認

```app/models/item.rb

class Item < ApplicationRecord
  mount_uploader :picture, PictureUploader
  validates :picture, presence: true
end
```

pictureアップローダーがある事を確認します。
ちなみに私の場合はpictureカラムを必須にしています。



#FactoryBot内でpictureアップローダを呼び出す


```spec/factories/items.rb
FactoryBot.define do
  factory :item do
    content { '紹介文' }
    picture { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec/fixtures/test.jpg')) }
    tag_list {'テスト'}
    user
  end
end

```



このように記述すると画像を含めたモデルスペックのテストが通るようになりました。

もしも、テスト内で何度も画像添付ファイルを繰り返すのであれば、

下記のように添付ファイルを属性値に含めてしまうのと良いみたいです。





```spec/factories/items.rb
trait :with_picture do
 picture { File.new("#{Rails.root}/spec/fixtures/picture.jpg") }
end
```


これでテスト内で`FactoryBot.create(:item, :with_picture)`と書けば

引数を渡してくれるので画像ファイルがある状態の新しいitemを作成することができるようになります。



もしテストを高速化させたい場合は、アップロードフォルダを分けたり、
テスト終了ごとに画像ファイルの消去設定することが必要みたいです。


また、この他にも Paperclipを使ったファイルアップロードのテスト方法もありました。

今後テスト内容を増やす事になると、さらに細かい設定が必要だと思うので、
必要になり次第、学習していきたいと思います。


#参考元
https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Use-test-factories
https://til.codes/testing-carrierwave-file-uploads-with-rspec-and-factorygirl/
https://qiita.com/motty93/items/5cbc46ce79a502fcaa65
[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp)
M5StackでWHILL Model CRの電源をON/OFFしてみた

# はじめに
この記事は[WHILL Advent Calendar 2018](https://adventar.org/calendars/3238#list-2018-12-03)の6日目の記事です。

---
今流行りのM5StackでModel CRが制御できるので、一番簡単な電源ON/OFFをやってみました。

# WHILL Model CRとは
RS232Cで外部から制御できるパーソナルモビリティです。
詳しくはこちらのページご参照ください。
https://whill.jp/model-cr

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149063/9326d538-6308-e8c9-df59-3514df992bd5.png)

# 準備するもの
- WHILL Model CR
- M5Stack
- [極小RS232-TTLコンバータモジュール- Ｄサブ９ピン オスコネクタ](https://www.amazon.co.jp/gp/product/B00OPU2QJ4/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1)

# 接続方法
M5StackのHardwareSerial2(16,17pin)を使うため、Model CRから出ているRS232Cケーブルから、下記のポートに接続します。

| M5Stack       |RS232C-TTLコンバータ |
|:-----------------|:------------------|
|16pin(RXD)| TXD |
|17pin(TXD)| RXD |

あとは、3.3VとGNDを各々接続します。

# Arduino SDKの取得
Model CR用のArduino SDKをダウンロードしてライブラリに追加します。
M5StackではHardwareSerialを使用するので、esp32ブランチを使用してください。(masterはSoftwareSerialを使用しています。）

https://github.com/WHILL/whill-sdk-arduino/tree/esp32

ライブラリの詳しい使用方法はこちらの記事を参照ください。
[ArduinoからWHILL Model CRを動かす](https://qiita.com/aquahika/items/14a129db401926485bda)

# 電源ON/OFFのコーディング
このようなコードを書けば電源ON/OFF出来ます。
- Aボタン：電源ON
- Bボタン：電源OFF


```cpp:M5Stack_whill_power_control.ino
#include <M5Stack.h>
#include "WHILL.h"

#define LCD

WHILL whill(&Serial2);

void setup()
{
  Serial.begin(115200);
  // Power ON Stabilizing...
  delay(500);
  M5.begin();
  
  M5.Lcd.setTextColor(GREEN);
  M5.Lcd.setTextSize(4);
  M5.Lcd.clear(BLACK);
}

void loop() {
  M5.update();
  if (M5.BtnA.wasPressed())
  {
    whill.setPower(true);  // Turn WHILL on
    M5.Lcd.clear(BLACK);
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.println("POWER ON");
  }
  if (M5.BtnB.wasPressed())
  {
    whill.setPower(false);  // Turn WHILL off
    M5.Lcd.clear(BLACK);
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.println("POWER OFF");
  }
}
```

#おまけ
POWER ON/OFFのテキスト表示だけだとそっけないのでアバターくんに喋らせてみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">M5StackからWHILL Model CRの電源を入れられるようにしたので、ついでアバターも喋らせてみた。<a href="https://twitter.com/hashtag/M5Stack?src=hash&amp;ref_src=twsrc%5Etfw">#M5Stack</a> <a href="https://twitter.com/hashtag/WHILL?src=hash&amp;ref_src=twsrc%5Etfw">#WHILL</a> <a href="https://t.co/RQkiMcpuuO">pic.twitter.com/RQkiMcpuuO</a></p>&mdash; Katsushun89 (@katsushun89) <a href="https://twitter.com/katsushun89/status/1071001199938138112?ref_src=twsrc%5Etfw">2018年12月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>





# 最後に
M5 StackにつないでModel CRの電源ON/OFFしてみました。

Arduino SDKにはJoystickの制御など諸々用意されていますので、簡単にM5Stack経由でModel CRを動かすことも出来ます。
是非試してみてください。
[golang]RedisでKEYSしたい

# 環境

- go 1.12.5
- redigo 1.6.0

# コード

`redis.Strings` という便利関数が用意されているので、それを使う。

```go
keys, err := redis.Strings(conn.Do("KEYS", "hoge:*"))
if err != nil {
    // 何かエラー処理
}
for _, key := range keys {
   fmt.Println(key)
}
```

一般的な注意喚起としては、キーが増えてきたら、トラフィックを食うし、応答速度は落ちるしでボトルネックになりがちなので、そこは注意して利用したい。

# 参考

- [Get All keys From redis in go - Stack Overflow](https://stackoverflow.com/questions/31473676/get-all-keys-from-redis-in-go)
今日学んだ事(自分用)

#6/29(土) 7:30〜8:30

###●whereメソッド
・データベースから条件に当てはまるレコードを全て取得する。

```
モデル.where(条件)
```
###※whereメソッドを使用する時の注意点
whereメソッドを使う場合裏側でどんなSQLが走っているかログを確認する必要がある。
ログを確認するためには、to_sqlメソッドを使用する。


###●first_or_initializeメソッド
・whereメソッドと使う事で、whereメソッドで検索した条件のレコードがあればレコードのインスタンスを返し、なければ新しくインスタンスを作るメソッド

```
user = User.where(条件).first_or_initialize
```
インスタンスを作成したら保存する

```
user.save
```

###●href属性
・a(アンカー)タグの属性の1つ
・aタグは、他のページサイトのリンクを貼り付ける時に利用
⇨リンクを指定するのが『href』属性

###●unless文
・条件式がfalseの場合処理を行う

```
unless 条件式
```

コードの簡略化

```簡略前.
unless user_signed_in?
  puts "ログインしてください"
end
```
```簡略後.
puts "ログインしてください" unless user_signed_in?
end
```

###rails g migration クラス名
・このコマンドで指定したクラス名のマイグレーションファイルの作成
・テーブルにカラムを追加する
・マイグレーションファイル内の、changeメソッドの中にコードを記述する

マイグレーションの作成
例

```ターミナル.
$ rails g migration AddRateToProducts
```


例
Booksテーブルにinteger型（整数）のカラムpriceを追加する

```201XXXXXXXXXXX_add_price_to_books.rb
class AddPriceToBooks < ActiveRecord::Migration[5.2]
  def change
    add_column :books, :price, :integer
  end
end
```

###●add_column
・add_columnをマイグレーションファイル内のchange内に書くと、カラムの追加ができる

例

```
add_column :テーブル名, :カラム名, :カラムの型
```
複数の場合

```
 add_column :テーブル名, :カラム名, :カラムの型
 add_column :テーブル名, :カラム名, :カラムの型
```

###●remove_colmn（消去する_カラム）
・マイグレーションファイル内のchangeメソッドは、カラムの消去もできる
・changeメソッド内に、remove_colmnを記述するとカラムの消去ができる

例

```
remove_colmn :テーブル名 :カラム名 :カラムの型
```

###※マイグレーションの内容を変更した場合
マイグレーションの実行を行う

```ターミナル.
$ rake db:migrate
```
canvasとvuejsの連携を初心者なりに調べた

ちょっとjavascriptを使って、canvasとvuejsの連携を試す必要性が出てきたものの、調べるのに時間がかかったのでここにメモを。
## 方針
- vuejsで変化した値に応じて、canvasの描画を変えたい
- なるべくシンプルなコードで
    - コンポーネントについて、自分が理解しきれていない

# 参考にさせて頂いたもの
- canvasについて
[https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D](https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D)

# 実際の中身

```javascript:index.js
let app = new Vue({
    data(){
        // 値を関数で宣言する
        // 関数で宣言しておくのが標準らしい
        return{
        canvas: null,
        context: null,
        px : 20
        }
    },
    mounted(){
        // 読み込まれる際の定義
        // refによってdiv内の要素を指定する
        this.canvas = this.$refs.canvas;
        this.context = this.canvas.getContext("2d");
        this.draw(this.px);
    },
    watch:{
        //pxの値が変わり次第、this.drawする
        px : function(val,oldVal) {
            this.draw(val);
            console.log('new: %n, old: %o', val, oldVal);
        }
    },
    methods:{
        draw(px){
            let ctx = this.context.canvas.getContext("2d");
            // 引数のpxをlinewidthに
            ctx.lineWidth = px;
            // 1度消す
            ctx.clearRect(0, 0, 400, 400)
            // 以下で壁を作成
            ctx.strokeRect(75, 140, 150, 110);
            // 以下でドアを作成
            ctx.fillRect(130, 190, 40, 60);
            // 以下で屋根を作成
            ctx.moveTo(50, 140);
            ctx.lineTo(150, 60);
            ctx.lineTo(250, 140);
            ctx.closePath();
            // この設定で描画
            ctx.stroke();
        }
    }
}).$mount('#a01')
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="a01">
    <h2>{{px}}px</h2>
    <p><input v-model.number="px"></p>
    <canvas id="canvas" ref="canvas" width="400" height="400"></canvas>
    <br>
</div>
<script src="index.js"></script>
</body>
```

# 分からなかったので調べて理解した箇所
## ref
- htmlの要素自体を取得する。
- つまり今回なら、div内のcanvasを呼び出すために必要

## console.logの%oとか
> console.log('new: %n, old: %o', val, oldVal);

このあたりを見ると良さそう。

[https://qiita.com/nakajmg/items/0a27c6642268243c8eef](https://qiita.com/nakajmg/items/0a27c6642268243c8eef)

## new Vueのmountedなど
1. data
    - 「関数にしておくこと」byアドバイスくれた方
2. mounted
    - 読み込まれる際にする処理
    - ここではデフォルト値で初回の描画を行う
3. watch
    - 変数pxについて監視し、変化があれば実行される
4. methods
    - Vue インスタンスに組み込まれるメソッドです
    - 追加の関数定義を行う場所？あとで勉強しておく
werckerでタイムアウトを延長する

`wercker.yml` ファイルの根っこに以下のように書き足す。

```yaml:wercker.yml
box:
  id: golang
  :

# werckerは5分間無応答の場合はビルドを停止する
# 延長または短縮したい時には、以下のように分単位で書く
no-response-timeout: 10

# werckerは個々のステップが25分で終わらない場合もビルドを停止する
# 延長または短縮したい時には、以下のように分単位で書く
command-timeout: 30
:
```

# 参考

- [How do I bypass the timeout for builds? :: Wercker Documentation](https://devcenter.wercker.com/supplementary-information/faqs/how-to-bypass-timeouts/)
JFreeChart-パイチャート


目次 ⇒ [JFreeChartサンプル](https://qiita.com/artery/items/3e9c63e5c14a9e965c97)


```java
package jp.avaj.lib.chart;

import java.awt.Color;
import java.lang.reflect.InvocationTargetException;

import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.Plot;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;

/** JFreeChart-パイチャート */
public class Chart04_00 {
  // 目次-パイチャート(PieChart)
  A_Chart04 a_Chart04;
  // 目次-Artery-JFreeChart用のライブラリ
  A_Chart00 a_LibChartSampeContents;


  /** 商品の売上数のデータからパイチャートを生成する */
  public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    // PieDatasetを作成する
    DefaultPieDataset dataSet = new DefaultPieDataset();
    dataSet.setValue("商品A",200);
    dataSet.setValue("商品B",150);
    dataSet.setValue("商品C",90);
    dataSet.setValue("商品D",120);
    dataSet.setValue("商品E",230);

    // Plotを生成する
    PiePlot piePlot = new PiePlot((PieDataset)dataSet);
    // 3Dパイチャートならば次のようにする
    //piePlot = (PiePlot)new PiePlot3D((PieDataset)dataSet);

    // 商品cを強調して表示する,値は結果を見て調整する
    piePlot.setExplodePercent("商品C",0.1D);

    // 商品bの色を変える,注、指定しなければJFreeChartが勝手に決める
    piePlot.setSectionPaint("商品B", Color.black);

    // チャートを生成する
    JFreeChart jfreeChart = new JFreeChart("商品別売上高",(Plot)piePlot);
    //
    ChartFrame cFrame = new ChartFrame("PieChartFrame",(JFreeChart)jfreeChart);
    cFrame.pack();
    cFrame.setVisible(true);
  }
}

```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/38402be0-8a24-047e-dae7-38827a3ecec1.png)
機械学習 アルゴリズム 講義課題視聴レポート (現場で潰しが効くディープラーニング講座)

### アルゴリズム
##### k近傍法(kNN)
- 教師ありの分類問題を解く機械学習の手法
- 新しいデータから最も近いk個のデータを求め、その中で最も多いクラスを新しいデータの予測値とする。
![無題19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/9c259dda-5969-d8a7-5504-c5bbace767ed.png)

- kの値を変化させることで、同じデータで学習しても結果が変わる可能性がある。
- kを大きくすると決定境界は滑らかになる。
- k近傍法は怠惰学習やmemory-based learningとも呼ばれ、学習時は学習データをそのまま記録するだけで、予測時に実際の計算が行われる。そのためデータの数が多ければ多いほど予測に時間がかかる。

##### k平均法(k-means)
- 教師なし学習のクラスタリング(特徴の似ているデータでグループ化)を行う手法。与えられたデータをk個のクラスタに分類する。
- k平均法のアルゴリズムは以下の通り
    - 1)各クラスタ中心初期値を設定する
    - 2)各データ点に対して、各クラスタ中心との距離を計算し、最も距離が近いクラスタを割り当てる
    - 3)各クラスタの平均ベクトル(中心)を計算し、クラスタの中心を更新する
    - 4)収束するまで2～3を繰り返す
![無題20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/64d72cde-e033-faaa-d916-8f3c404372d0.png)
![無題21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/2a11f7f2-3b71-1c62-34a1-e6e784fe1539.png)
![無題22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/4f565672-4691-f62a-4111-787f5b0d9f60.png)

- 中心の初期値やkの値を変えるとクラスタリングの結果が変わる
- 似た手法に、中心の初期値を広くとるように工夫したk-means++や、クラスタの中心を更新する際に平均ではなく中央値をとるk-medoidsなどがある。両者ともk-meansより良い結果を出す場合がある。
- 最適なkの値を調べる方法としてエルボー法がある。クラスターの中心と、そのクラスターに属するデータの距離の総和に注目する。kの数を増やしていくと、ある段階で距離の総和がほとんど減少しなくなる。この時のkを最適とするのがエルボー法である。
[次へ(サポートベクターマシン)](https://qiita.com/yuma-k105/items/4a1e1b4b746c121488cd)
機械学習 主成分分析 講義課題視聴レポート (現場で潰しが効くディープラーニング講座)

### 主成分分析
##### 主成分分析
- 複数の変数を持つデータに対して、なるべく情報量を減らさずに変数の数を減らす手法。変数を減らすことでデータと可視化などが可能になる。
- 学習データの分散が最大になる方向への線形変換を行う。つまり線形変換したときに分散が最大となるベクトルを求める必要がある。
![無題16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/e93ac172-a563-9ad1-62a8-e014d8133451.png)

- 上記の最適化問題はラグランジュ関数を最大化する係数ベクトルを求めるのと同義のため、ラグランジュ関数の係数ベクトルでの微分が0になるときの係数ベクトルの値を求める。ラグランジュ関数とは制約付きの最適化問題を解くときに、最適化したい関数に制約式を加えた関数のことを言う。
![無題17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/0e18ce80-2c30-4496-19d0-de337fb44b71.png)

- 上記の解は入力データの分散共分散行列に関する固有値と固有ベクトルの式と一致する。したがって入力データの分散共分散行列の固有値と固有ベクトルを求めることで、求めたいベクトルを求めることができる。
- 線形変換後の分散の値は固有値と一致する
- 第2主成分は上記のベクトルと直行するベクトルとなる。

##### 主成分
- 最も大きい固有値に対応する固有ベクトルで線形変換された変数を第一主成分と呼ぶ。
- k番目の固有値に対応する固有ベクトルで線形変換された変数を第k主成分と呼ぶ。

##### 寄与率
- 変換された特徴量の分散は固有値に一致するので、全分散量は元のデータの持つ全分散量と一致する。
- 全分散に対して第k主成分の分散が占める割合を第k主成分の寄与率と呼ぶ。これは第k主成分が持つ情報量の割合を表す。
- 第k主成分までの累積寄与率を求めることで、どこの次元までの主成分を使うかを判断できる。
![無題18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/dbb51ba6-97f5-68cb-d1a1-8191e1aa550e.png)

[次へ(アルゴリズム)](https://qiita.com/yuma-k105/items/2c6736a71d464ccae372)
プログラマ面接で質問してみたい事

# この記事について
単純に、「もし自分が企業の面接官として、プログラマの面接に駆り出される事になったら？」を想定し、どのような質問を投げようかマシンガンの如く書き殴ろうと思うだけの記事。
何か思いついたら随時更新予定。
正直結構適当に考えるので、ツッコミ所があればコメントなり編集リクエストなり貰えれば。

# 人柄面
- **「あなたの配属されたプロジェクトにボトルネックとなる低レベルなプログラマがいて、あなたの作業にも悪影響を与えていたとします。あなたならどう対処しますか？」**
 - 不平不満に対してどう対処していくか？を見る為の質問。
 - 前職では低レベルプログラマに対する陰口をよく聞いていたのだが、単純にそういうのが嫌と言うのもある。（一応、「陰口等の類を漏らした奴は解雇もあり得る。」と言った厳しい社内規則はあったのだが・・・。法的にそういった理由で解雇できるのかどうかはさておき。）
 - 当然ながら、自分主体の回答は即不採用。（上述したような「陰口」と言う対処法に行き着く可能性がある為、チームに悪影響を及ぼしかねない人材だと判断。）
 - 「メンバの入れ替えを上に持ちかけてみる」と言った回答が来た場合は、「それが通らなかったらどうしますか？」と返す。
 - そもそも「ボトルネックとなる低レベルなプログラマがいる」と言う事は、「プロジェクトの教育体制が悪い可能性がある」と言う事を意味する。（例えば「コードレビューが無い」等。）それに気付き、具体的な対応策を挙げるような回答がベスト。  （不平不満の根本的な原因の有無を考え、対処できるか？） 

- **「あなたにはどんな特徴がありますか？また、それはチームに入った時にどのような個性になると思いますか？仕事に関係のない事でも構いませんので、教えてください。」**
 - 「チームに入った時、どのような『キャラ』になるのか？」、「チームメンバからの印象はどうなりそうか？」、ひいては、「チームにどのように馴染んでいけそうか？」を大体イメージする為の質問。
 - 自分の場合、「野菜が食えない」と言う特徴が結構ネタにされてた事があるが、それもチームに馴染むための一つの特徴であったと考えている。
 - 勿論、「チームにこのように貢献できる」と言った方面で真面目に答えてもらっても構わない。（「真剣に面接に取り組んでいる」と言う評価点にもなり得る。）

# 技術面
- **「自分の学んできた技術を挙げて、それぞれの習熟度について１００点満点で点数を付けてください。」**
 - 「広く浅く学ぶタイプ」なのか、「一つの技術に特化したタイプ」なのかを見る質問。
 - 後者であれば、「識者」として即戦力になり得る。
 - また、「自分の持つ技術を客観的に評価できるか？（課題点を挙げられるか？）」と言った面も見れる。
 - 自分のプロジェクトに関係する技術が挙げられた場合、「その技術の点数を上げる為にはどうすればいいと思いますか？」と掘り下げてみるのもいいかもしれない。（・・・と言うか、そもそも自分のプロジェクトに関する技術が挙げられなかった場合は即戦力にならない。新卒採用なら仕方ないと思うけど。）
 - 何か実際にたまにありそうな質問な気がする・・・。

# 成長面
- **（新卒採用の場合）「あなたを戦力にする為に、チームメンバは何をすればいいと思いますか？」**
 - 「自分がどのように自走して成長するビジョンが見えているか？」を見るための質問。
 - 「どこまで自走で成長でき、どこからが限界だと思うのか？」
 - 既存のチームメンバにも新人を教育する義務があるとは言え、自分自身が持っている作業もこなさなければならない。それが理解できているか？も見ている。
 - 勿論、完全に他力本願で自走する気が無さそうなら不採用。
機械学習 非線形回帰モデル 講義課題視聴レポート (現場で潰しが効くディープラーニング講座)

### 非線形回帰モデル
##### 基底展開法
- 非線形回帰モデルとは出力値が直線ではなく曲線を描く予測を行うモデル。
- 線形回帰モデルと違い、複雑な現象に対して使われる。
- 基底関数と呼ばれる関数とパラメータの線形結合で予測値を出力する。
- パラメータの予測は線形回帰モデルと同様に最小二乗法で行われる。
![無題5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/b782fe8d-8286-9197-360d-2445da601cef.png)

- よく使われる基底関数として、多項関数、ガウス型基底関数があげられる。
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/9f9c21d4-4a70-f68c-64a9-5c7d8268a59f.png)
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/e87f393b-0561-ba32-7637-a10963425f00.png)


##### 正則化法
- 学習データに対して十分に小さな誤差を求められない状態を未学習と呼び、小さな誤差を得ることができたがテスト時の誤差が大きい場合を過学習と呼ぶ。
- 正則化法は過学習を回避するための方法。(ただし正則化しすぎると未学習となる)
- 正則化を行うことで、未知のデータに対する予測性能(汎化性能)を高めることができる。汎化性能はテストデータとの誤差の期待値で定義される。
- 未学習または過学習かどうかを判断する指標としてバイアスとバリアンスが存在する。バイアスとは作成したモデルと学習データのズレをのことを指し、バリアンス(分散)はモデルの複雑さを表す。バイアスの数値が高いと過学習の状態を示し、バリアンスが高いと未学習の状態を示す。バイアスとバリアンスがトレードオフの関係にあり、この2つの数値を可能な限り低くすることで正確な予測値を出力することができる。
- モデルが複雑になるにつれて値が大きくなるペナルティ項を加えた関数の最小化をすることで正則化を行う。
![無題6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/8b295a20-7c75-a3d5-26a0-201cbe640c32.png)

-ペナルティ項にはL2ノルムを利用したRidge推定量とL1ノルムを利用したLasso推定量がある。
![無題7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/00943899-882d-bb7a-97ab-f1047288aee2.png)


##### モデル選択
- 正則化パラメータはクロスバリデーションという方法で選択する。
- クロスバリデーションとはモデルの評価の方法の1つで、ほかにはホールドアウト法というものも存在する。
- ホールドアウト法
    - 手元のデータを2つに分割し一方を学習に使い、もう一方は学習に使わず汎化性能の測定などに使う方法。
    - 学習用データを増やすとテスト用データが減り、テスト用データを減らすと学習用データが減ってしまう。そのためデータの数が十分でないとモデルの学習も汎化性能の評価も適切に行えないという欠点がある。
- クロスバリデーション法
    - ホールドアウト法の欠点を補う方法として使われる。
    - 手元のデータをそれぞれm個のグループに分割しm-1個のグループを学習に使い、残りの1グループをテストに使用する(分類問題の場合は各グループに全種類のクラスが入るように分割すると性能が高くなる)
    - 上記をm回繰り返し、それらの平均二乗誤差の平均を汎化性能とする。
    - 手元にあるすべてのデータを学習とテストに使用するので、データ数が少ない場合でも良い性能評価をすることができる。
    - ホールドアウト法と違い分割の仕方で制度の違いが出にくいので、複数のモデルをクロスバリデーション法で評価し、一番精度の良いモデルを使用するという方法がとられる。

[次へ(ロジスティック回帰モデル)](https://qiita.com/yuma-k105/items/b7f60fab7a505ecbc731)
機械学習 線形回帰モデル 講義課題視聴レポート (現場で潰しが効くディープラーニング講座)

# 機械学習
### 線形回帰モデル
##### 回帰問題
- 回帰問題とは入力された数値から、連続値を予測する問題のことをいう。
- 回帰問題では入力にベクトルを使い、スカラー値を出力する。このとき入力に使う変数を説明変数(特徴量)と呼び、出力値を目的変数と呼ぶ。
    - 例) 住宅の価格予測
        - 説明変数：敷地の広さ、築年数など
        - 目的変数：家の価格

##### 線形回帰
- 線形回帰とは回帰問題を解くための機械学習モデル
- 教師あり学習(正解付きデータでの学習)で学習が行われる。
- 入力がm次元ベクトルの場合、m次元のパラメータの各要素を掛け算した結果の和(線形結合)に切片を足したものが出力される。(入力の次元にかかわらず出力はスカラーになる。)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/2fc6ec9b-c1f8-af9f-a73a-f36613db2dd1.png)

- パラメータは入力ベクトルの各要素がどの程度出力に影響を与えるかを決める。パラメータが正の値だと出力を増加させ、パラメータが負の値だと出力を減少させる。パラメータが0に近い場合は出力にあまり影響を与えない。
- このパラメータを最適な値にすることで正しい予測が可能になる。

##### モデルの選択
- 手元にあるデータをすべて学習させてしまうと未知のデータに対する予測精度(汎化性能)を評価するのが困難になってしまう。そこで手元にあるデータを学習用とテスト用で分けるのが一般的である。

##### パラメータの推定
- データは回帰直線に誤差が加わり観測されていると仮定し、この誤差が最小になるときのパラメータを求めることが機械学習のゴール。
- 誤差の大きさは平均二乗誤差で表すことができる。平均二乗誤差とは各データとモデルの出力の差を二乗して、それらを足し合わせたものである。平均二乗誤差が小さいほど誤差が少ないと言える。
- 平均二乗誤差を最小にするパラメータを求める方法を最小二乗法という。最小二乗法とは平均二乗誤差の勾配が0になる点、つまり平均二乗誤差をパラメータで微分した値が0になる点を求める方法である。
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/ef91702e-3d3e-c6c4-6e80-094261622410.png)

- このようにして求められたパラメータをもとにできた回帰直線が各データに当てはまっているかを決定係数を用いて評価することができる。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/a9730411-da6f-c7ab-443b-c99e3da8a11e.png)

##### ハンズオン
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/141d1ec2-fdac-7a8e-acee-e8dc6ef33761.png)
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/5417a2aa-3abf-1693-b282-54cd9db01cb9.png)
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/3fbae7b1-7a90-00b9-a2b1-ffbdd65ae7f5.png)
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/0d17978a-2ee0-97aa-ce8c-a56b6adc43d7.png)
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/1eb18136-2d82-108d-2860-43e7326e48d9.png)
![無題5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/a467c32c-6ad5-ab4f-0e00-f36b25b51b3b.png)
![無題6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/cd83b5c4-a357-ecc1-12bb-092daa4732a2.png)
![無題7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/5451c005-f77d-a899-b3b5-e5b933ceac72.png)
![無題8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/f58f563c-caa9-fb7d-ed76-87f08aed95ed.png)
![無題9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/4266e486-4de9-aac9-ddc8-a8583d4e5175.png)
![無題10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440745/83013212-8c76-5c48-ede6-57b5cef3c3dc.png)
##### サマリーと考察
- 単回帰分析では部屋数を説明変数とし、重回帰分析では部屋数と犯罪率を説明変数としてモデルを作成した。
- train_test_splitをインポート時にエラーが発生したため修正した。
- 重回帰分析時に説明変数として築年数や面積の広さを増やしてみたところ、過学習をおこしたようだった。グラフを見る限り予測データに対しての当てはまりは現状でも良さそうに見えるが、より精度を高めたい場合は別の機械学習モデルを使うほうが良いと考える。

[次へ(非線形回帰モデル)](https://qiita.com/yuma-k105/items/721d66fdecfccb9a3128)
NetlifyでSPAをbuildする

Netlifyでは公開サイトのルートに_redirectsを置き、その中にリダイレクトの設定を書き込みます。

ReactなどのSPAを作るフレームワークでは `build` がルートになるので buildディレクトリの配下に`_redirects`を置きます。

```
./build/_redirects
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/cdd3dbbb-eb0c-dff6-0d45-bbe7e9be0d18.png)

Netlifyにログインし管理画面で `Domain management` を選択し


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/df62c0c3-3866-fbad-d790-7ebdcfa45e04.png)

上記ソースが表示されるので `_redirects` にコピペあとはコミットしてpushしたらbuildファイルをルートとして表示させることができます。
組織・複数人環境におけるUnityのライセンス管理について

# はじめに
組織や複数人環境におけるUnityのライセンス管理方法がよくわからなかったので、ベストプラクティスをUnityに問い合わせしました。
その返答内容をまとめたものになります。
※2019-06-27時点での情報になります。


# Unityでの開発におけるライセンスの種類
Unityにおいてライセンスは以下の2種類があるようです。

- **Unity License**
    - 用途：Unityエディタを使うためのライセンス
    - 購入先：Unity Store (https://store.unity.com/)
    - 購入数：利用する人数分購入する必要あり
- **Asset License**
    - 用途：アセットを使うためのライセンス
    - 購入先：Asset Store (https://assetstore.unity.com/)
    - 購入数：利用する人数分 or 組織で一つ  
    ※Asset Store のAsset詳細ページの「Requirements」欄に記載があります。  
　無ければ組織で一つ（たぶん）、エディタ拡張系は基本的に利用する人数分必要みたいです。
     
※わかりやすく説明するために勝手につけた名所です。以降説明において使っていきます。
※リモート勤務におけるライセンスは少し特殊な模様。以下のページが一定参考になりそうです。
　テレワークの際Unityライセンスに関するFAQ(https://forpro.unity3d.jp/wfh-faq/)
　
# ライセンスの管理のベストプラクティス
「**ライセンス購入用アカウント**」と「**作業用のアカウント**」といった形で分けて管理するのがベスト。
以下例

- 購入用アカウント（作業しない、ライセンスを３つ購入、ライセンスは割り当てない） 
- 作業アカウント１（作業する、ライセンスを割り当てる） 
- 作業アカウント２（作業する、ライセンスを割り当てる） 
- 作業アカウント３（作業する、ライセンスを割り当てる） 

※**Asset License**は割り当てという作業がないため、利用する人数分購入するだけでOK。
※上記アカウントは同一組織内である必要があります。
　複数の組織にまたがっての割当はできないので注意してください。
　組織は「Unity ID - 組織(https://id.unity.com/ja/organizations )」から作成できます。
　作成した後、削除はできないようなので注意してください。
    

# 作業アカウントへの購入したAssetの共有方法
購入したAssetについては「**Asset License**」を持っている人がDL・インポートする必要があり、以下のどちらかのプロセスが必要。

- 購入用アカウントの情報を作業者に貸し出せる場合
    1. 購入用アカウントの UnityIDとそのパスワードを作業者様にお渡しください
    2. 作業者様のPCで購入用アカウントで Unityにログインし直してください
    3. 対象のアセットをダウンロードしてください
    4. 作業者様の UnityIDで Unityにログインし直してください

- 購入用アカウントの情報を作業者に貸し出せない場合
    1. 購入用アカウントを管理している方のPCに Unityをインストールしてください
    2. 購入用アカウントで Unityにログインしてください
    3. 対象のアセットをダウンロードしてください
    4. 下記フォルダ内にある .unitypackageファイルを USBメモリあるいは社内サーバー等を経由して作業者様にお渡しください
    5. 作業者様の PCの Unity内で、対象の .unitypackageファイルをインポートしてください

※作業しないアカウントなのにUnityEditorにログインして良いの？と思っていましたがDL・インポート程度であれば大丈夫みたいです。



以上です。
ゼロから作るDeepLearningでmnist_show.pyがエラーになる

ゼロから作るDeepLearningの学習用として、windows10環境にPython Japanから入手したPython3.6.5をインストールして使っています。
Anaconda3も
https://www.anaconda.com/
からダウンロードして入れました。

githubの
https://github.com/oreilly-japan/deep-learning-from-scratch
から、本書で出てくる例題がすべてダウンロードできますので、すべてを適当なホルダに格納しておいて、コマンドプロンプトからそのホルダに移動して*.pyファイルを実行できます。

たとえば、例題をc:\deeplearningにすべて格納しているとすると、p.9に出てくるhungry.pyは、コマンドプロンプトから、
c:\deeplearning\ch01>hungry.py
と入力してenterすれば実行されます。

このやり方で学習を進めていきましたが、3章のmnist_show.pyを実行しようとすると次のようなエラーが出ます。
ModuleNotFoundError: No module named 'PIL'
これはネット上でも話題になっていて、PILライブラリがpillowというものに置き換わったことが原因だそうで、pillowをインストールすれば解決します。
コマンドプロンプトを管理者モードで起動し、

c:\WINDOWS\system32>py -m pip install pillow

のようにして、pillowをインストールします。

これでめでたくmnist_show.pyが起動できるかと思いきや、

c:\deeplearning\ch03>mnist_show.py

とすると画像が出るところでペイント3Dを起動しようとしてエラーが出ます。
よくわかりませんが、生成されたビットマップデータがペイント3Dで開けないというようなことかもしれません。

そこで、mnist_show.pyを次のように変更します。
変更箇所は#####でコメントを入れました。

```
# coding: utf-8
import sys, os
import matplotlib.pyplot as plt #####追加行1
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image

def img_show(img):
    pil_img = Image.fromarray(np.uint8(img))
    pil_img.show()

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)

img = x_train[0]
label = t_train[0]
print(label)  # 5

print(img.shape)  # (784,)
img = img.reshape(28, 28)  # 形状を元の画像サイズに変形
print(img.shape)  # (28, 28)

#img_show(img)　#####コメントアウト

plt.imshow(img) #####追加行2
plt.show()      #####追加行3
```

つまり、image_showを使おうとするとペイント3Dを起動して失敗するので、pyplotを使って表示させています。

お役に立てれば幸いです。
macにAWS CLIをインストールする

macにAWS CLIをインストールしたときの備忘録です。

前提条件確認
---
```
//パイソンがmacに入っているか確認
$python --version
Python 2.7.10
```
バンドルされたインストーラを使用して AWS CLI をインストール
---

・コマンド要約 （下記3つでおけー）

```
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
```

・以下は実際にcmd流した結果です。

```
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11.6M  100 11.6M    0     0   301k      0  0:00:39  0:00:39 --:--:--  285k

$ unzip awscli-bundle.zip
Archive:  awscli-bundle.zip
  inflating: awscli-bundle/install   
  inflating: awscli-bundle/packages/argparse-1.2.1.tar.gz  
  inflating: awscli-bundle/packages/rsa-3.4.2.tar.gz  
  inflating: awscli-bundle/packages/ordereddict-1.1.tar.gz  
  inflating: awscli-bundle/packages/simplejson-3.3.0.tar.gz  
  inflating: awscli-bundle/packages/urllib3-1.25.3.tar.gz  
  inflating: awscli-bundle/packages/python-dateutil-2.6.1.tar.gz  
  inflating: awscli-bundle/packages/s3transfer-0.2.1.tar.gz  
  inflating: awscli-bundle/packages/six-1.12.0.tar.gz  
  inflating: awscli-bundle/packages/python-dateutil-2.8.0.tar.gz  
  inflating: awscli-bundle/packages/virtualenv-15.1.0.tar.gz  
  inflating: awscli-bundle/packages/jmespath-0.9.4.tar.gz  
  inflating: awscli-bundle/packages/urllib3-1.22.tar.gz  
  inflating: awscli-bundle/packages/colorama-0.3.9.tar.gz  
  inflating: awscli-bundle/packages/PyYAML-3.13.tar.gz  
  inflating: awscli-bundle/packages/pyasn1-0.4.5.tar.gz  
  inflating: awscli-bundle/packages/docutils-0.14.tar.gz  
  inflating: awscli-bundle/packages/botocore-1.12.180.tar.gz  
  inflating: awscli-bundle/packages/awscli-1.16.190.tar.gz  
  inflating: awscli-bundle/packages/PyYAML-5.1.tar.gz  
  inflating: awscli-bundle/packages/futures-3.2.0.tar.gz  
  inflating: awscli-bundle/packages/setup/setuptools_scm-1.15.7.tar.gz  

$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
Password:
Running cmd: /usr/bin/python virtualenv.py --no-download --python /usr/bin/python /usr/local/aws
Running cmd: /usr/local/aws/bin/pip install --no-cache-dir --no-index --find-links file:///Users/XXX/awscli-bundle/packages/setup setuptools_scm-1.15.7.tar.gz
Running cmd: /usr/local/aws/bin/pip install --no-cache-dir --no-index --find-links file:///Users/XXX/awscli-bundle/packages awscli-1.16.190.tar.gz
You can now run: /usr/local/bin/aws --version
```



インストール確認
---
下記コマンドでインストールされたか確認可能


```
$ aws --version
aws-cli/1.16.190 Python/2.7.10 Darwin/18.6.0 botocore/1.12.180
```



参考
--
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-macos.html
[swift] userDefaultsの使用手順（メモ）

#実現したいこと
アプリ内でユーザーの状態（ログイン済or未、個人情報の入力済or未）によって画面遷移やダイアログを出したい。


#userDefaultsを使用する
アプリを再起動してもユーザーのログイン情報等を保持したかったが今回は該当ユーザーが「ログインしている」「ログインしていない」のようなBool値のみを利用して判断すれば良いため、keyとそれに対応するvalue（Bool値）を持つことができたらいい。
またアプリ内で永続的に保持していたい。その場合`userDefaults`を使用したら良いことが分かった。


#userDefaultsの使用手順

今回頭の整理も兼ねてuserDefaults使用の手順を書いてみた。
なお今回は`"LoginInfo"`というkeyに`false`というvalueをセットする場合である。

###1.userDefaultsのインスタンスを生成
`let userDefaults = UserDefaults.standard`

###2.デフォルト値を設定(初期値は今回falseに設定している)
`userDefaults.register(defaults: ["LoginStatus": false])`

###3.指定したkeyに対してvalueを設定する。
ログインボタンが押された際、`"LoginInfo"`に`true`のkeyを設定したい。
下記のような書き方で`"LoginInfo"`というkeyに対して`true`というのbool値を設定している。
`userDefaults.set(true, forKey: "LoginStatus")`

###4.データを取ってくる。今回はkeyである"LoginStatus"のbool値`true`を取ってきて`loginStatus`に入れている。
`let loginStatus = userDefaults.bool(forKey: "LoginStatus")`