OmniAICreator/Qiita-1.07M huggingface dataset:
自宅でスクレイピングbotを動かしているとAkamaiを利用している一部Webサイトが見えなくなる話

## なぜか大企業のサイトが見えない

筆者の自宅から一部サイトにアクセスした際、次のようなエラーが表示されることがありました。

> ![Access Denied You don't have permission to access "http://www.toyota.co.jp/" on this server. Reference #18.49067668.1538899594.53a6215](https://qiita-image-store.s3.amazonaws.com/0/46856/caceb1c2-2bb2-7a63-e843-f3d46b7a9c47.png)

この現象はたとえば次のサイトで起こります。

- [トヨタ自動車](https://www.toyota.co.jp/)
- [本田技研工業](https://www.honda.co.jp/)
- [サントリー](https://www.suntory.co.jp/)
- [アメリカン・エキスプレス](https://www.americanexpress.com/)
- [HIS](https://www.his.co.jp/)

最初は閲覧しようとしているサイト側の障害かな？と思っていたのですが、この現象は筆者の自宅のみで起きており、障害ではないことがわかりました。

## 共通点はAkamaiを利用していること

上記5サイトで共通しているのはレスポンスヘッダの`Server`行です。

```
  HTTP/1.1 403 Forbidden
  Server: AkamaiGHost
```

どうやらこれはAkamaiのエッジサーバが返しているようです。実際、上記ホスト名のCNAMEとしてAkamaiのエッジサーバらしき名前が登録されています。

```
› dig www.toyota.co.jp

; <<>> DiG 9.12.1 <<>> www.toyota.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46903
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.toyota.co.jp.		IN	A

;; ANSWER SECTION:
www.toyota.co.jp.	657	IN	CNAME	www.toyota.co.jp.edgekey.net.
www.toyota.co.jp.edgekey.net. 6957 IN	CNAME	e5170.ksd.akamaiedge.net.
e5170.ksd.akamaiedge.net. 17	IN	A	184.31.41.141

;; Query time: 1 msec
;; SERVER: 192.168.2.1#53(192.168.2.1)
;; WHEN: Thu Oct 04 09:28:43 JST 2018
;; MSG SIZE  rcvd: 141
```

## 原因を探る

筆者がこのエラーに気づいてから数週間の間、自宅から上記のサイトを閲覧しようとすると同じエラーが出る状況でした。

ところが、ある日プロバイダのPPPoEセッションを再接続するとその瞬間から上記サイトが閲覧可能になりました。そして2日ほどするとまた同じエラーが出るようになっていました。

状況から判断すると、筆者の自宅IPアドレスがAkamaiのブラックリスト入りしているようです。

そこで関係しそうな内容を探すとAkamaiの記事が見つかりました。

- [Why is Akamai blocking me?](https://community.akamai.com/customers/s/article/Why-is-Akamai-blocking-me?language=en_US)

この記事によれば次のような原因でAkamaiにブロックされることがあるようです。

> - 明示的なIPブロッキング・ブラックリスト
> - 位置ベースのブラックリスト
> - ルールベースのブロッキング（WAFなど）
> - 評判ベースのブロッキング
> - HTTPリクエストのアクセス速度コントロール（DoS対策など）

私の場合どれもピンときませんが、4番目の「評判ベース」に引っかかっているのかもしれません。上記ページには次のような記述もあります。

> 次のような行動により、アプリケーションセキュリティ制御が作動するかもしれません。
> 
> - SQLインジェクション、クロスサイトスクリプティング、ローカルファイルインクルージョン、リモートコマンド実行、リモートファイルインクルードなどのWebアプリケーションレイヤの攻撃
> - DoS攻撃または同様の高速HTTPトラフィック
> - Webコンテンツのスクレイピング、データマイニング、Webコンテンツ索引作成などの自動化されたWebリクエスト
> - 自動ツールを使用したWeb脆弱性スキャン

私の場合3番目に該当するリクエストが1日に数百〜数千リクエストほどありますが、上に挙げたトヨタなど5サイトへのアクセスは通常ゼロです。

つまり、私が自動化しているリクエストのうち一部がAkamaiのエッジサーバでサーブされていて、そのアクセス情報を元にトヨタなど別サイトのブロッキングに利用されているということになりそうです。

私は十分なリクエスト間隔を空けているつもりだったので、攻撃者であるという判定をされているなら若干腑に落ちませんし、それが別のサイトのブロッキングに利用されているのも不思議な気がしますが、そういうこともあるのでしょう。
[iOS]カスタマイズ可能なUIButton風のCustomViewを作ってみました

## コード

https://github.com/osanaikoutarou/ButtonView

## モチベーション

UIButtonをカスタマイズしようとした時、どうするでしょうか？
UIButtonはInterfaceBuilder上で、子Viewを置けません。

1. UIButtonのパラメータをいじって頑張る
2. すべて画像にしてしまう
3. UIButtonにaddSubviewしてしまう
4. Viewの上に、同じ大きさの透明なUIButtonを置く
5. UIGestureRecognizerを使う
6. UIButtonの親クラスであるUIControlをカスタマイズする

今回は、6を作ってみました。

利点：InterfaceBuilder上でButtonの中身に対してAutoLayoutを組める。


## 動き

こんな感じです。すべてUIControlのサブクラスです。

<img width="250" alt="ButtonView1edit.gif" src="https://qiita-image-store.s3.amazonaws.com/0/20784/1a17fae1-60ea-e4fb-b679-b324e0e5164e.gif">

| Type       |       見た目 |
|:-----------------|:------------------|
| componentLight             | 子Viewを薄くする |
| componentDark           | Label以外を暗くする |
| baseDark             | 全体を暗くする |
| lighterTheWhole               |  全体の半透明にする |
| likeButtonPlane             |  通常のUIButton状態　ラベルだけ薄くなる |
| likeButtonCustom          | 通常のCustomUIButton状態　Imageが暗くなる |
| whiteTheWhole          | 全体が白くなる |

他にも柔軟にカスタマイズできます

<img width="250" alt="ButtonView2edit.gif" src="https://qiita-image-store.s3.amazonaws.com/0/20784/9252899d-6eca-da34-858c-6f2172ee7fee.gif">

selected,disable,highlightのViewをセットできます

<img width="250" alt="ButtonView3edit.gif" src="https://qiita-image-store.s3.amazonaws.com/0/20784/4c027e77-4381-1e48-c083-fe4037ebc902.gif">

ボタンとの比較です。似せています。

<img width="250" alt="ButtonView4edit.gif" src="https://qiita-image-store.s3.amazonaws.com/0/20784/4d1832a5-0358-1b9c-eb07-1ad7cf8122a9.gif">

画像ボタンも簡単です。
角丸の場合は、WhiteやDarkがその形に沿っています（重要）

## 類似ライブラリはないのか？

私は探せませんでした。
もっと具体的な「よく使うボタン」をまとめたものはあります。

## 使い方

<img width="886" alt="スクリーンショット 2018-10-07 17.08.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/20784/4ccee220-c46b-da54-f9a6-aac382c6f064.png">

UIViewにButtonViewをClass指定してください。
UIControlでもいいですが。
そうすればいつものアレが出ます。

<img width="772" alt="スクリーンショット 2018-10-07 17.09.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/20784/5abbf9bd-3fe2-4b26-602c-98a124cc85e3.png">

ボタンはタイプの設定が必要です。デフォルトではUIButtonっぽくなります。

```swift
inuButton.setup(type: .darkerTheWhole)
```

特定のStateに対するViewを設定する場合は以下です。あまり使わないですけど。

```swift
inuButton.setView(view: pressedInuButton, forState: .highlighted)
```

あまりViewの階層を深くしたり、複雑なViewを組み込んだ場合は想定していないのでどうなるかわかりません。
StackViewくらいならどうにかなると思います。


## 実装の中身

目標としては、UIControlとUIButtonの差分を埋めるだけです。
ただし今回はTitleやImage、BacgroundImageは不要です。
あと細かなShadowの仕様とか、Insetの仕様は詰めていません（完全に自分が普段使っていない仕様を無視している状態）

TODO一覧

- タッチした際に表示を変える
    - 表示パターンのルールを作る（UIButtonに存在しないパターンもあるので）
- 範囲を外れた時、範囲に戻ったときに表示を変える
- selected,highlight,disableの時のViewをセットできるようにする

実は、イベント関連はUIButtonじゃなく、UIControlなんですよね（知らなかった）
UIControlStateはもちろんUIControlの仕様なんですが、setImage:forStateとかはUIButtonの仕様です（解せない。もしくは私が知らないだけか）

実際のコードに関しては特に面白くないので割愛します。


## 所感、その他

3 UIButtonにaddSubviewしてしまう
4 Viewの上に、同じ大きさの透明なUIButtonを置く

こっちの方でも似たことできそうなんですが、3はやはりInterfaceBuilderでレイアウトが組めませんし、4はイベントとの繋ぎ込みができないので使い勝手が悪そうです。

実際に半年くらい使っていますが、痒いところに手が届く感じが気に入っています。
よく「そのボタンの仕様って、iOS的じゃないんですよね〜〜」とか以前は言ってましたがもう言いません。
iconをどの位置にどの大きさで置くとかにも悩みません。
ボタンの中でアニメーションも簡単です。

あと残す面倒事はシャドーくらいです・・・
fastai 1.0をGoogle Colaboratoryで動かすためにしたこと

ソフトウェア・エンジニア（プログラマー）にオススメの深層学習MOOCの[fast.ai](https://course.fast.ai/)が講義の中で使用しているライブラリ[fastai](https://docs.fast.ai/)が[正式に1.0になった](http://www.fast.ai/2018/10/02/fastai-ai/)ので、Google Colaboratory（以下、Colab）で使ってみました。
その際、細かいところで少しつまづいたので、それをまとめてみました。

## PyTorch 1.0のインストール

fastaiは[PyTorch](http://pytorch.org/)の上に作られています。  
しかし、正式リリース前のPyTorch 1.0を使っているため、Nightlyビルドを使う必要があります。  
ColabではCUDA 8.0しか入っていないようなので、そちらを指定しています（:arrow_down: の `cu80` の部分）。

```python
!pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cu80/torch_nightly.html
```

## もし古いバージョンのPyTorchをインストール済みの場合
下記コマンドで削除しておきましょう。  
:warning: また、このようにライブラリを削除して新しく入れ直す場合はランタイムを再起動させるのをお忘れなく:exclamation: 古いライブラリを読み込んだままになってしまいます。

```python
!pip uninstall torch
```

## fastaiのインストール

```python
!pip install fastai
```

:warning: このとき、どのバージョンがインストールされるか、ご注意を！
まだ1.0になったばかりで、まだAPIが頻繁に変わっています。サブマイナーバージョンの更新（例：1.0.**2** :arrow_right: 1.0.**3**）でも変わったりします。

## workerの数
fastaiはデフォルトでCPUの数に応じて複数プロセスで走らせるようになっているのですが、どうもColabでは安定して動かないので、その機能を切った方が良さそうです。

ImageNet形式のフォルダ構造用の関数である`image_data_from_folder`の場合は以下のように`num_workers`で`0`を指定するとメインプロセスのみで実行されるようになります。

```python
data = image_data_from_folder(
    DATA_DIR, ds_tfms=get_transforms(), tfms=imagenet_norm, size=224,
    num_workers=0   # <== こちらで0を指定する
)

learner = ConvLearner(data, arch, metrics=accuracy)
```

当然ながら処理に時間がかかってしまいますが、無料で使っている範囲では仕方ないかと…。
Rails 5.2 jQuery 動かし方（turbolinks含む)

jqueryを動かすのに結構時間がかかってしまったので、備忘録程度に書いてきます。３ステップで簡単にできます。

###1　gem "jquery-rails"のインストール
Gemfileに書いて、bundle installをします。
###2　//= require jqueryをapplication.jsに追加

書く場所が読み込む順番に影響を与えるので、重要です。

```js:app/assets/javascripts/application.js

//
//= require jquery
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
```


###3 viewが読み込まれてからjqueryが読み込まれるようにします。

```js:app/assets/javascripts/application.js

$(document).ready(function() {
    $("button").text("Hello JQuery on Rails");
 });
```
こういう風にかくとviewの後に読み込まれます。

**注意** : **turbolinks**が動いている場合（ページ遷移した場合など）は上のreadyイベントは呼び出されませ。そうなので、下のように書くと、初期ロード時や、ページ遷移時など常に動きます。

```js:app/assets/javascripts/application.js
$(document).on('turbolinks:load', function() {
    $("button").text("Hello JQuery on Rails");
});
```
メールの添付ファイルを自動保存

メールの固定ファイル名の添付ファイルを自動的に決まった場所に保存する方法。
## 材料
* getmail
* procmail
* python

## getmail
http://pyropus.ca/software/getmail/
定番は fetchmail なのかな。

#### インストール
`$ cd /opt/src`
`$ wget http://pyropus.ca/software/getmail/old-versions/getmail-5.6.tar.gz`
`$ tar xzf getmail-5.6.tar.gz`
`$ cd getmail-5.6`
`$ python setup.py build`
`$ su`
`# python setup.py install`

#### 設定
`$ mkdir -m 700 ~/.getmail`
`$ vi ~/.getmail/getmailrc`

```getmailrc
[options]
message_log = ~/.getmail/log
# デバッグが終わったらコメント
message_log_verbose = true
read_all = False
# 指定した日数経過後サーバーから削除
#delete_after = 30
# デバッグが終わったらコメントを外す
#verbose = 0

[retriever]
#type = SimplePOP3SSLRetriever
type = SimplePOP3Retriever
server = pop.hoge.co.jp
username = username
#port = 110
password = password

[destination]
#type = Maildir
#path = ~/Maildir/
type = MDA_external
path = /bin/procmail
unixfrom = True
```
`$ chmod 600 ~/.getmail/getmailrc`
`$ mkdir -p ~/Maildir/{cur,new,tmp}`
`$ chmod -R 700 ~/Maildir/`

## procmail
#### インストール
`# yum -y install procmail`
`# which procmail`
`/bin/procmail`

#### 設定
`$ vi ~/.procmailrc`

```.procmailrc
#----- ヘッダ
#PATH=
MAILDIR=$HOME/Maildir
DEFAULT=$HOME/Maildir/
#LOGFILE=/dev/null
LOGFILE=$HOME/procmail.`date +%Y%m%d`.log
#SHELL=/bin/sh
# デバッグが終わったら"OFF"る
VERBOSE=ON
#-- 追加変数
FROMADDRESS=from@hoge\.co\.jp
TOADDRESS=to@hoge\.co\.jp
TARGETSUBJECT=mailtitle
ATTACHFILE=filename

#----- レシピ
:0 HBcw :
* $ ^From:.*$FROMADDRESS
* $ ^To:.*$TOADDRESS
* $ ^Subject:.*$TARGETSUBJECT
* ^Content-Type:.*multipart
* $ filename=\"$ATTACHFILE\"
| $HOME/save_attachment.py $ATTACHFILE

:0
$DEFAULT
```
`$ chmod 600 ~/.procmailrc`

## python
`$ which python`
`/usr/bin/python`
`$ python --version`
`Python 2.7.5`
`$ vi ~/save_attachment.py`

```save_attachment.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import email

# 添付ファイル保存先
filedir = '/tmp/'

def attachmentSave(message, attachfile):
    for part in message.walk():
        # 添付ファイルありで区切りを書いている部分なので飛ばす
        if part.get_content_maintype() == 'multipart':
            continue
        # ファイル名取得
        fname = part.get_filename()
        if fname and fname.find(attachfile) != -1:
            savefile = open(os.path.join(filedir, fname), 'wb')
            savefile.write(part.get_payload(decode=True))
            savefile.close()

if __name__ == '__main__':
    args = sys.argv
    message = email.message_from_string(sys.stdin.read())
    attachmentSave(message, args[1])
```
`$ chmod 700 ~/save_attachment.py`

## 実食
`$ getmail`
うまくいかない場合は procmail.*.log を参照。
ファイルは常に上書きなので用途によりカスタマイズ。
~/Maildir/new/ にメールが残り続けるので別途定期的に削除するシェル等で対応する。
はじめてなElixir(18) Taskにも触ってみる

こうなったらタスクもやってみましょう。
[はじめてなElixir(17)](https://qiita.com/kikuyuta/items/2336bb83ed0ffb1bc47a) で Agent を使ってみました。プログラミングElixirに出てくる残りの並行プロセス技法は Task です。今日はあまりハマらずで短いです。

なお、プログラミングElixirではAgentより扱いが軽いですが、リファレンス読むとまあまあ他のプロセス系なモジュールと同じぐらいの分量があります。

#前回でいいわすれたこと　

備忘録ですが Agent 名は大文字で始めます。これ、裏で勝手に :Elixir が補われるらしく `Foo` と書くと `:Elixir.Foo` というアトムになるそうな。この中途半端で微妙なおせっかい、Elixir らしいなあと思います。

#勝手に走ってて問い合わせに応答もするプロセスを作る
Agent は自立して走りますが、メッセージを与えるたびに関数が走るので、勝手に何かやってるという感じではありません。（その意味では Agent ってネーミングはあまり適切ではないかもしれません。私が技を知らないだけかもしれませんが）
たとえば前回のエージェントは定期的に（例えば1秒ごとに）関数を起動して状態を変える（リストを伸ばす）ということはしません。

## タスクでエージェントを刺激する
これ、毎秒 cast なり update なりを叩けばできます。人間がやらなくても別のプロセスがやってくれれば良いですね。

```temp12.ex
defmodule Temp12 do
  def tick(agent, interval \\ 1000) do
    cast(agent)
    :timer.sleep(interval)
    tick(agent, interval)
  end

  def start(agent) do
    Agent.start(fn -> [0] end, name: agent)
  end
  
  def cast(agent) do
    Agent.update(agent, __MODULE__.succ())
  end

  def get(agent) do
    Agent.get(agent, &(&1))
  end

  def succ() do
    fn(l) -> [hd(l) +1 | l] end
  end
end
```

tick という関数は指定時間ごとに agent の cast を叩くので、これを非同期に起動してやれば望みのものができそうです。

```iex.ex
iex(1)> Temp12.start(Foo) # Agent Foo を動かします
{:ok, #PID<0.106.0>}
iex(2)> Temp12.get(Foo) # Foo の持ってる初期値を表示
[0]
iex(3)> task=Task.async(fn -> Temp12.tick(Foo) end) # 非同期の task を立ち上げます。Foo を刺激します。
%Task{
  owner: #PID<0.104.0>,
  pid: #PID<0.109.0>,
  ref: #Reference<0.906436406.773062658.108199>
}
iex(4)> Temp12.get(Foo) # Foo の状態リストが伸び始めました
[3, 2, 1, 0]
iex(5)> Temp12.get(Foo) # 待ってるとずっと伸びます
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
iex(6)> 
```

とまあ Task と Agent でよろしくやってくれます。こういう、ちょこちょこと書いて組み合わせて合成するのは楽しいです。

## Task でもう少し遊ぶ
インターバルタイマでちょっとずつリストを作るというのは、凝ったことをしないで良いなら Stream.interval でできます。

```iex.ex
iex(1)> Stream.interval(1000) |> Enum.take(5)            
[0, 1, 2, 3, 4]
```

これ、結果が出てくるのに5秒ほど待たされます。

これに Task の async_stream というのをひっつけます。関数はもらった要素をそのまま返すようにしておきます。

```
iex(2)> task = Stream.interval(1000) |> Task.async_stream(&(&1)) 
#Function<1.95549051/2 in Task.build_stream/3>
```

これでバックグラウンドで task が走ります。

```
iex(3)> Enum.map(task, &(IO.inspect(&1)))
{:ok, 0}
{:ok, 1}
{:ok, 2}
{:ok, 3}
{:ok, 4}
{:ok, 5}
{:ok, 6}
```

Enum.map を使って task の結果を見ると毎秒出力がはじまります。全部 :ok をつけてよこしてるのが分かります。だから何だって言われそうですが、わざわざ非同期プロセスを噛ましてストリームしてみたというところです。

Task は途中でなにかやり取りするような関数がなさそうですし、Agent はずっと何か勝手にやり続けるようなことがなさそうですし、やりたいことはどっちかだけじゃ実現できそうにないようです。

あと、Task は Agent と違って async や start のときに name: で名前を付けられませんでした。


#参考文献
漁るといろいろ出てくるので「車輪の再発明」ならぬ「車輪の再発見」を続けてるような気分になります。でもまあ、打って、エラーして、くじけて、調べて、やり直して… しないと身体が覚えないのでね。すべてのエンジニアが車輪の再発見をしてるものと信じてます。

- [[翻訳] Elixir ─ 状態はどこにある？](https://qiita.com/HirofumiTamori/items/b6957686e0ba93006184) @HirofumiTamori
- [進捗どうですかと煽ってくるプログラムをElixirのAgentとStream.transform/2を使って状態遷移で解く](https://qiita.com/niku/items/f06752d165945ff0b72e) @niku 
- [Elixir 1.7.3 Task](https://hexdocs.pm/elixir/Task.html#summary)
【Unity】カメラが邪魔なので非表示にしたい時

<h2><font color="DeepPink">Sceneビューのカメラが邪魔な時、カメラを非表示に切り替える。</font></h2>
(Unity version 2017.2.0f3)


<b><font color="DeepPink">①Gizmosを選択する</font></b>
![004.png](https://qiita-image-store.s3.amazonaws.com/0/93155/8129bbe4-4a46-ee35-7dd8-cb68c82dd162.png)


<b><font color="DeepPink">②Cameraの画像をTapする（カメラのShow/Hideを切り替えることができる。）</font></b>
![003.png](https://qiita-image-store.s3.amazonaws.com/0/93155/5bc62240-9ac3-7c2d-14b3-e0569bf06e8b.png)

<b><font color="DeepPink">③カメラをHideにする。</font></b>
![002.png](https://qiita-image-store.s3.amazonaws.com/0/93155/2d50c48f-cd77-557c-858d-ab590afd8214.png)

<b><font color="DeepPink">④カメラが非表示になる。</font></b>
![001.png](https://qiita-image-store.s3.amazonaws.com/0/93155/ff8c9ac4-95f2-efad-e7d4-8b2089d9b96e.png)
pipで更新可能なライブラリを一括でアップデートするシェルスクリプト

condaなら

```
$conda update --all
```

でライブラリの一括アップデートできる。
でもpipにはそのオプションがない（はず）。

pipでは、


```
$pip list -o
#出力結果は下記
Package     Version Latest  Type 
----------- ------- ------- -----
```

でアップデートが可能なライブラリの一覧が取得できる。

アップデートする際にはパッケージ名以外はいらないのでこっちが見やすい。

```
$ pip list -o | awk '{print $1}'
#出力結果は下記
Package      
-----------
```

アップデートしたいライブラリが１つだけなら

```
$ pip install -U パッケージ名
```
とすればアップデートできる。

複数ある場合は、テキストファイルにまとめておいてシェルで処理すると楽。

```update.sh
#!/bin/bash
while read line
do
  pip install -U $line
done < pip_update_list.txt
```

ほんとうはアップデートリスト生成からアップデートまでをまとめて行いたいけど、
シェルスクリプトでテキストを処理する方法がいまいち分からなかった。

```
$ pip list -o | awk '{print $1}'
#この出力結果から[Package]と[-----------]を削除したい。
Package      
-----------
パッケージ名
```

わかる方がいれば教えていただけるとありがたいです。
Sassの書き方

#この記事の目的

Railsアプリの開発でフロント部分をSassを用いて書くことにしましたので、基本的な使い方を整理するために書きます。


##Sassをなぜ使うのか？

目的はコードを簡略化し可読性を向上させることにあると思っている。

##コードを簡略化できるとはどういうことか？

具体的に使いやすい点をまとめる。

####①ネストを利用してセレクタの記述を少なくできる

下記のようなHTMLおよびCSSがあったとする。

```sample.html
<div class="content">
  <h1 class="title">Hello Ruby on Rails</h1>
  <p class="text">Sass is <span>greate!</span>
</div>
```

```sample.css
.content {
  background-color: #000;
}

.content .title {
  color: #FFF;
  font-size: 70px;
  text-align: center:
}

.content .text {
  font-size: 15px;
  color: #FFF;
}

.content .text span {
  color: red;
  font-size: 20px;
}
```


```sample.scss
.content {
   background-color: #000;
  .title {
    color: #FFF;
    font-size: 70px;
    text-align: center:
  }
  .text {
    font-size: 15px;
    color: #FFF;
    span {
      color: red;
      font-size: 20px;
    }
  }
}
```

sample.cssとsample.scssを比べて見ると、.content, .text, ...と書いている部分がネストによって簡略化できているのがわかる。sample.cssではcontentを４回記述しているのに対して、sample.scssでは一回のみで済んでいる。


####②変数が使える
なんども同じ色や、プロパティを指定する際に変数を使うことによってコピペをせずに変数に格納して利用することができる。何度も同じ色を利用するというケースは、例えば、テーマカラーや配色バランスなどが設定されているWEBサービスなどでは役に立つのではと考えている。

ベースカラーを変数に格納して入れたりして、別ファイルから値をコピペして来ずに`$main-color`のように利用できたら使いやすいはず。

変数の指定の仕方

```sample.scss
$変数名: 値;
```

####③パーシャルを活用する
パーシャルを活用することによって、散らばっているSassファイルをまとめることができる。

- ファイル名は`_`（アンダースコア）からネーミングする //railsの部分テンプレートも同じだ
- これ、アンダースコアから始めない場合はCSSとして読み込まれてエラーの原因になってしまう
- 読み込みかたは：@importファイル名と記述する

```sample.scss
@import "reset";  //_reset.scssファイルを読み込んでいる
```

複数インポートも可能

```sample.scss
@import "reset", "btn", "module";  
```


####④ mixinを使ってスタイルを定義する
mixinを利用することで、何度も同じスタイルを記述する必要がなくなる。

例えば何かボタンを作りたいときに、なんども同じスタイルを定義するのはめんどくさいので_variable.scssとかに記述しておいたり。


```_variable.scss
@mixin btn {
  display:block;
  color: $main-color;
  text-align:center;
  text-decoration:none;
  float:right;
}
```
使うときは

```aaa.scss
@import "reset";  //_reset.scssファイルを読み込んでいる

////////////

.hogehoge {
  @include btn();
  aaaa: ;
  bbbb: ;
}
```


####⑤extendで指定のセレクタのスタイルを継承する

`@extend`を使ってスタイを継承することができる。


```sample.scss

.box {
  margin: 0 0 30px;
  padding: 15px;
  border: 1px solid #ccc;
}

.item {
 @extend .box; //.boxのスタイを継承する
}
```


```sample.css

.box, .item {　　//グループ化される
  margin: 0 0 30px;
  padding: 15px;
  border: 1px solid #ccc;
}
```

このように、使いまわせるスタイを後から指定できるので、使い回す回数が多くなるたびに効率的にかける。

##最後に

可読性を高めるため→他の人が読むことが前提にあるプロジェクトでの利用なのでFLOCSSという考え方が大事らしい。

複雑なミックスイン、過剰なエクステンド、自分本位なフォルダ構成、その他、ルールを複雑化をしないことが大切。

- F：Foundation(reset.scss,variable.scssなど土台となるものたち)
- L：Layout(header, sidebar, footerなどのレイアウト用CSS群)
- O：Object(プロジェクトにおける繰り返されるビジュアルパターン)
    - Component(再利用できるパターン：ボタンとか）
    - Project（固有のパターン：記事、ユーザ画面、画像パターンなどのコンテンツを構成する要素）
    - Utility（ComponentとProjectのObjectのモディファイアで解決することが難しい・適切では無い、わずかなスタイルの調整のための便利クラスを定義する。）
  
https://github.com/hiloki/flocss
 

大切なのは*「思いやり」*ですね。
ずんだの1桁足し算問題 Brainf**k版

[てぃーびーさん](/tbpgr)の[ずんだの1桁足し算問題](/tbpgr/items/6c75930566dda97bb5b6)をBrainf\*\*kで実装しました。
ループの制御、複数桁の数字管理等、Brainf\*\*kの初～中級として手頃な問題ではないかと思います。

```Brainfuck:実装(367文字)
** ずんだの1桁足し算問題
** prepare symbol characters
+++[->+++++++<]
>[->P++>E+++>C++++++<<<]
>P+>E-->>

** double loop
i+++++++++[-
 >>j+++++++++[-
  ** main
  * memory layout: PECi_j
  *  P E C: character code for PLUS EQUAL TILDE respectively
  *  i j: loop counters from 8 downto 0

  ** create several numbers from i j
  <<i[->+>>S->>I->>S-<<<<<<<]>[-<+>]
  >j[-<+>>S->>>J->S-<<<<<]
  ++++++++++[->S++>>I+>J+>S++<<<<<]

  * memory layout: PECij_S_IJS
  *  I J: 10 minus i/j
  *  S  : I plus J

  ** divide by 10
  >>>>>>>R++++++++++<<S--[->>R-[<r+>>>>]<[r+[->R+<]>>q+>]<<<<]

  * memory layout: PECij_S_IJ_rRq
  *  r q: remainder and quotient ( result of the division )
  *  R: 10 minus r

  ** digit compaction and replacement
  >>>q[+[-<<<+>>>]<R[-]<r+>>]  ( if q is not zero )
  <R[[-]<r+[-<+>]>]            ( else             )

  * memory layout: PECij_S_IJD(D)
  *  D: created digit(s) of S minus 2 through the division
  *  notice: I J D are all larger by 1 than they are meant to be

  ** convert numbers to characters and print
  <<<<<<S<++++++[->>>I[>]<[++++++++<]<<]
  >>>I-.<<<<<<<<P.>>>>>>>>>J-.<<<<<<<<E.>>>>>S--[-<<<<T.>>>>]>>>>D[-.>]

  ** print newline and clear temporary characters I J D then move j back
  ++++++++++.[[-]<]<<<[->+<]
 >j]
<<i]
```

実行例は[ideoneでの実行例](https://ideone.com/hhH3aE)を、Brainf\*\*kの組み方については[Brainf**k講座(リンク)](/angel_p_57/items/618bed4e96c5e96778a5)をご参照ください。
iPhone->iPhoneの個人的移行手順メモ (二段階認証, Wallet, LINE)

## はじめに

iPhoneを移行するたびにやることリストを書き出すのが面倒なので、このページだけみれば分かる状態にしておきたいと思います。

**移行元のiPhoneが必要になる**手順があるので、下取りなど出す場合は注意してください。

### 検証環境

- macOS High Sierra 10.13.5
- iTunes 12.8.0.150
- 移行元iPhone: iPhone 8 Plus
- 移行先iPhone: iPhone XS

## iTunesでバックアップの作成と復元

### 【移行元iPhone】 バックアップの作成

時間の目安: 1時間程度 (作業時間は2,3分)

Macに移行前のiPhoneを繋ぎ、iTunesからバックアップを作成します。

下記現象が起きる時がありますが、待ってたらバックアップ始まりました。
[iTunesバックアップで「iPhoneのバックアップのロックを解除するために入力したパスワードが間違っていました。やり直してください」が表示されたときのポイント](https://did2memo.net/2015/09/27/itunes-backup-backup-lock-password-error/)

余談ですが、iPhoneのバックアップファイルはかなり容量が大きいので、僕は保存先を外付けHDDに変更しています。おすすめです。
[【Mac版】iPhone&iPadのバックアップ保存先をMac本体内から外付HDDに変更する手順 | HYZ STUDIO BLOG（ハイズスタジオブログ）](https://hyzstudioblog.com/technology/486/)

### 【移行先iPhone】 バックアップからの復元

時間の目安: 1時間程度 (作業時間は2,3分)

Macに移行後のiPhoneを繋ぎ、iTunesからバックアップから復元をします。

## LINEの移行

時間の目安: 5分程度

### 【移行元iPhone】 LINEでの設定

友達タブ>左上の設定アイコン>`[アカウント引き継ぎ]`>`[アカウントを引き継ぐ]`のトグルをオンにする

また、事前にメールアドレスとパスワードが設定されていることを確認しておいてください。

### 【移行先iPhone】 LINEのログイン

移行先iPhoneでLINEにログインします。

ログインに成功すると、移行元iPhoneのアプリ情報が全て初期化されるため注意してください。(少しラグがありました)


## Wallet

時間の目安: 10分程度

チケットなどは基本的にバックアップ経由で自動的に移行されると思います。

### Quick Pay / iD

Walletを開き、`[+]`アイコンからクレジットカードの追加を選ぶと、移行元iPhoneで登録されていたカードを登録する画面になります。セキュリティコードを入力すると登録することができます。

### モバイルスイカ

同時に複数の端末上に表示できない仕様なようです。

> 【Suica情報の端末間移動手順】
> ---旧端末にて---
> ① Walletを起動
> ② 設定されたSuicaを選択（1枚ずつ）
> ③ 画面右下の i ボタンをタップ（Apple Watchの場合はSuicaの画面を強く長押し）
> ④ 「情報」タブを選択（Apple Watchの場合は手順④はありません）
> ⑤ 「カードを削除」をタップ　※削除するとiCloudに紐づいたサーバに退避されます。
> ---新端末にて---　Touch ID/Face IDの設定は以下手順の前にお済ませください。
> ⑥ Walletを起動
> ⑦ 右上の + ボタンをタップ
> ⑧ Apple Payの案内画面は「続ける」をタップ
> ⑨ カードの種類「Suica」をタップ
> ⑩ カードを追加で⑤操作より退避されたSuicaが表示されますので「次へ」をタップ（1枚ずつ）

引用元: [【機種変更】Apple PayからApple Payへ（iPhone/Apple Watch→新しい | Suica Apple Pay よくあるご質問](http://appsuica.okbiz.okwave.jp/faq/show/1537?site_domain=default)


## Authenticator(二段階認証アプリ)の移行

時間の目安: 15分程度

このアプリ上での情報は自動的に移行が行われません。
各種サービスから設定しなおす必要があるのですが、その際にログインが必要になる場合があります。
移行前iPhoneの二段階認証アプリを使うか、もし手元にない場合はリカバリーコードから復元してください。
どちらもない場合、サービスによっては復元不可能なものもあるので注意してください。

### Google

以下のページを開き、認証システム アプリの`[スマートフォンを変更]`から設定してください。

2 段階認証プロセス
https://myaccount.google.com/signinoptions/two-step-verification

リカバリーコードは更新されませんでした。

### GitHub

以下のページから設定してください。
https://github.com/settings/two_factor_authentication/intro

GitHubの場合は認証端末を変更した場合にリカバリーコードも更新されるようなので、途中で表示されるコードはしっかり保存するようにしてください。(設定完了後の画面での表示できます)

### Qiita

更新するためには、以下のページから一度二段階認証を無効にして再度設定してください。
https://qiita.com/settings/two_factor_authentication/configure

リカバリーコードも更新されるので、保存しておいてください。

### Trello

https://trello.com/2fa

リカバリーコードは更新されませんでした。
また、Googleアカウント経由でログインする場合、こちらの二段階認証は適用されないようです。

### Discord

解除から再度設定してください。

https://discordapp.com/activity

リカバリーコードも更新されるので保存してください。

### Facebook

https://www.facebook.com/security/2fac/settings/

~~リカバリーコード更新されました。~~
リカバリーコードは更新されませんでした。

### Twitter

`モバイルセキュリティアプリ`を一度offにすると変更することができます

https://twitter.com/settings/account/login_verification

リカバリーコードは更新されませんでした。

## 感想

二段階認証アプリの移行が面倒だったので、あんまり使わないサービスは二段階認証使わなくてもいいかもしれないと思いました。
透過ディスプレイでGateBoxぽいものを自作してみた


#はじめに
Vチューバー関係や初音ミクとの結婚など、最近バーチャルキャラクターに関する話題が増えてきたと感じます。

そんな中で、バーチャルキャラクター関連でよく話題に出てくるのが[GateBox](https://gatebox.ai/home/)です。
ただ、かなりの高額なため買うのが難しいです。しかし、そんなGateBoxを自作した方がいらっしゃいました。


MMDモニターを作ってみたの
[http://www.nicovideo.jp/watch/sm33086157](http://www.nicovideo.jp/watch/sm33086157)

キャラクターとの会話機能はないですが、本当にその場にいるようですね。

自分も自作できないかと思い試してみました。

#完成品

![monita.png](https://qiita-image-store.s3.amazonaws.com/0/278812/5bf73082-a3f5-0a2b-4b24-207bb3388a25.png)



制作過程はカットです。モニターをばらしただけなので。見た目があんまり良くないのには目を瞑っていただけると幸いです。
モニターに思いっきり部屋が映ってますが気にしないでください。

実際に動いているものはYoutubeにアップロードしておきます。
URL:[https://www.youtube.com/watch?v=RneR4vbbU6A](https://www.youtube.com/watch?v=RneR4vbbU6A)

#あとがき
今回はただ作って動画を流しただけですが、本家と同じようにAIを載せて会話できるようにしていきたいですね。
見た目も整えてもう少しまともな感じに仕上げていきたいと思います。
Microsoft Teams Scraping

# Microsoft Teams Scraping

**更新履歴**
- 2019/02/13 Application Registration Portalが，AzurePortalと統合されたことにより画面イメージが変更になったことと，トークンの更新にoffline_readが必要なので更新．
- 2019/02/25 いいね・被いいねの関係性や，メッセージの投稿に対する返答の関係性のデータを抽出できるようにしました．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/327054b2-9540-ced9-a803-4ec08000961f.png)

## 目的
- Microsoft Teams上でやりとりされているメッセージを全て取得します．
- 個人的なチャットは2018/10/06現在取得できません．
- 取得できる範囲は，AD認証したユーザーが所属している全チームのメッセージです．

## 結論
### 全コード
- [GitHub](https://github.com/tatsuya-takahashi/microsoft-teams-scraping)


### 使い方
#### ADアプリ登録
- [Registragion Portal](https://apps.dev.microsoft.com/)にアクセス，ログイン．
- 下記の通りに登録する．
  - 名前：任意
  - リダイレクトURL：http://localhost:3000/token
  - アクセス許可（Mailとかは本当は不要なので削ってOK）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/b8480c7b-c436-c662-c40d-d187d56b6fe9.png)


- 発行されたキーと，パスワードを控えておく．

#### アプリの準備
- 下記からClone
- [GitHub](https://github.com/tatsuya-takahashi/microsoft-teams-scraping)
- 変数の書き換え（環境変数にセットするのが面倒であれば，直接書き換えで良い）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/8b1e4161-dbe1-feac-7d4b-c799859d3cdd.png)
  - LoginURL：Azure Portalの右上で確認できる，下記値を設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/501a5bf0-7340-8727-7e90-5dd9092a2be1.png)
  - clientId：アプリ登録時に控えたキー
  - secret：アプリ登録時に控えたシークレット
- ```npm intall```
- ```node index.js```
- http://localhost:3000 にアクセスすると，ADログイン画面に飛ばされる．ログイン後，ログインしたユーザーが所属するチームのスクレイピングが始まり，スクレイピングが終了すると「teams.tsv」が吐き出される．

#### 出力形式
##### i.e.　（IDはでたらめな数字に置き換えています．）

###### teams.tsv

|teamId|teamName|channelId|channelName|userId|name|content|
|---|---|---|---|---|---|---|
|9d93a0d9-c462-4cbb-9cb8-9badb0b65f45|マネージャーチーム|05:6d03b62a324042e6885d2f8bf2d80b6e@thread.skype|General|b0543ed0-a012-4653-bbd7-9fe60c967af7|高橋|みなさんこんにちは．本日のアジェンダをお送りします．|

###### teams_relations.tsv

|relationType|fromUserId|toUserId|
|---|---|---|
|like|7de1cc33-077b-42c3-9fdd-2d5c62a31522|95eecce7-f85e-4c4b-9df3-4a7e1d02d03b|
|like|d9db64c1-bd8c-45a2-8552-012e54ebcb20|bde2bf3e-5307-416b-b469-d2c730f2ab65|
|reply|4a543f69-917d-4eb5-8f56-14955fde3ea1|bde2bf3e-5307-416b-b469-d2c730f2ab65|
|like|bde2bf3e-5307-416b-b469-d2c730f2ab65|4a543f69-917d-4eb5-8f56-14955fde3ea1|
|reply|7de1cc33-077b-42c3-9fdd-2d5c62a31522|5095ec96-e9be-492a-a8e7-7b1ce466a5dc|

## 解説
### 概要
- AD認証して，Microsoft Graph API経由でTeamsのデータを取得する．
- つい最近できるようになった．以前はできなかった．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/327054b2-9540-ced9-a803-4ec08000961f.png)

### APIのクセ
- 一度に取得できるメッセージの上限が決まっている．
- テキスト全体を取得しようとすると，上限数で切られた状態でテキストが返ってきて，HTTP HeaderのOdataにNextLinkが設定される．NextLinkで再度取得すると，前回取得した次の部分からテキストを取得できる．
- このようにNextLinkを繰り返していき，メッセージをリカーシヴに取得し続ける．
- なお，**メッセージに対する返信も取得している．**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/c92514c8-d367-5081-a333-10f28b9a2bc1.png)

## 所感
- Twitterなどのスクレイピングとかとクセは変わらない．AD認証がひと手間いるぐらい．
- いいね数や，いいねした人も取得できる．　→**取得するように修正しました（2019/02/285）**
- 添付ファイルも取得できる．
- 今回のテキストクリーニングは，URLとHTMLタグの削除のみ．
- それでもHTMLタグですらない変なゴミは残る．

## 参考
- [Graph API Teamwork Document](https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/resources/team)


以上です．
Brainf**k講座(リンク)

リンクのみですが、過去にブログで公開したBrainf\*\*k講座をまとめておきます。

* [Brainf**k講座(1) Hello, BF!](http://ange1.hateblo.jp/entry/2016/07/08/220611)
* [Brainf**k講座(2) 数値入力と簡単なループ](http://ange1.hateblo.jp/entry/2016/07/09/210000)
* [Brainf**k講座(3) スライド型ループ](http://ange1.hateblo.jp/entry/2016/07/10/210000)
* [Brainf**k講座(4) 条件分岐](http://ange1.hateblo.jp/entry/2016/07/11/210000)
* [Brainf**k講座(5) 条件分岐の多段化](http://ange1.hateblo.jp/entry/2016/07/12/210000)
* [Brainf**k講座(6) 非破壊的条件分岐](http://ange1.hateblo.jp/entry/2016/07/13/210000)
* [Brainf**k講座(7) divmodアルゴリズムと数値出力](http://ange1.hateblo.jp/entry/2016/07/14/210000)
* [Brainf**k講座(8) BCD演算](http://ange1.hateblo.jp/entry/2016/07/15/210000)
* [Brainf**k講座(番外編) Baconian Cipher](http://ange1.hateblo.jp/entry/2016/07/16/210000)
* [Brainf\*\*k講座(番外編) Brainf**k golfでのコード短縮例～PPSP～](http://ange1.hateblo.jp/entry/2016/12/09/100000)
* [Brainf\*\*k講座(番外編) Brainf**k golfでのコード短縮例 おまけ](http://ange1.hateblo.jp/entry/2016/12/10/154108)
* [Brainf**k講座(番外編)「あしあと」問題解答コードの設計～実装](http://ange1.hateblo.jp/entry/2017/03/12/174104)
schema.rbとmigrationファイルの関係をまとめてみたよ

`rails` を使いはじめたときに最初につまづいた、 `schema.rb` ファイルとマイグレーションファイルの関係について自分用備忘録。

# 図解
![Untitled Diagram.jpg](https://qiita-image-store.s3.amazonaws.com/0/145575/35d26297-fef8-f0be-c079-ca061afbb9b2.jpeg)

- migrationファイルと`schema.rb`は直接無関係。
- `schema.rb` は `db:schema:dump` タスクにより、現在参照しているDBのテーブル構造から作成される。
 - マイグレーションがどこまで実行されているかは関係ない。
- `db:migrate` (`db:rollback`) タスクの実行でmigrationファイルの実行が行われる。
 - その後自動的に `db:schema:dump` も実行されるので`schema.rb`も更新される。

- `db:schema:load` タスクで`schema.rb`の内容を現在参照しているDBに適用。   
 - 新規作成した空っぽのDBにテーブル構造などをロードする際に使う。

# その他、db関連のrakeタスクまとめ
## db:create
DBの作成。

## db:drop
DBの削除。

## db:reset
以下のショートカット。

```
db:drop
db:create
db:schema:load
```
久々の記事。組み込みのログについて

仕事関連のプレゼンで組込みソフトウェアのログにまつわることをやることになりました。
組込みってタイミング・性能がシビアでやたらとログが出せなかったり、ログを出したらバグが出なくなったり、ログを書きだすためのメモリが数MByteしかなかったり、といったあるあるをおかしく話そうかと思っています。

そんな中、この先このログの仕組みを持っていれば大丈夫かな、という手法を編み出しました。
具体的なことはQiita記事1つじゃ書き出せないのでgithubにも登録してせっせとサンプルコードを書いている最中です。出来ましたらまた知らせいたします。

ちなみにどんなものかというと、
printfとかは重いので直接4Byteアクセスでメモリに書きこむもので、
とはいっても暗号のようなコードだと何を書いてあるかわからないので外出しツールで文字列を付加して読めるものにするといった仕組みです。

15年ほど前に、Excelでその文字列を辞書のように管理していたのですが
まぁ1つログを追加するためにExcelを手直しするという非常に手の込んだものでした。
新しい仕組みはログを識別するIDをある方法でユニークにするというものです。
ぜひみなさんに知ってもらうべく、gitで悪戦苦闘しております(汗)

追伸：ワタクシ今年からプログラマから急に企画へ配属され、開発現場から離れました。もうemacs触るても錆ついてしまっていますが、自己研鑽のため、常にコードは触っていようと思います。
【Excel】Excelのオプション「新しいブックの作成時」の挙動について

# 「新しいブックの作成時」の挙動

### 環境
* OS : Windows10
* Excel : 2016


### 動作検証
ファイル > オプション > 基本設定 > 新しいブックの作成時
![1.png](https://qiita-image-store.s3.amazonaws.com/0/219708/2d8375a4-b29a-0256-d42b-ac0da075c9ec.png)


おそらく初期設定値は上記のようになっていたと思う。
私の場合、フォントはMeiryo_UIの9サイズがしっくりくるので
下図のように設定を変えて確定する。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/219708/d3e5ad91-ebd8-fff7-d930-ea92ecd25c12.png)



Excelを再起動し、テンプレートから「空白のブック」を選択する。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/219708/4d5ae3f6-5f46-944c-d3df-b048b41043ce.png)


当然といえば当然だが、その手順で新規に作成したブックは、
すべてのセルの書式がMeiryo_UIの9サイズとなっている。

だが厳密には、すべてのセルの書式がオプションによって設定されるわけではなく、
セルのスタイル「標準」の書式が変わっている。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/219708/e26e8aee-39d6-7e95-b1c6-7a99b8041203.png)

セルのスタイル「標準」はデフォルトですべてのセルに適用されているため、
結果としてこのオプションの目的が果たされるという寸法。


ちなみに、右クリックメニュー > 新規作成 > Microsoft Excel ワークシート からブックを作成した場合
このオプションは適用されない。
AWS AmazonLinux2 での tmux設定

#古いバージョンのtmuxで①マウス操作と②コピぺを両立する

###【この記事で解決すること】
1. tmux外部との文字列コピー＆ペースト（tmux↔️ターミナル端末側OS）
2. tmuxのマウス操作(入力ペイン切替/ペイン境界調整)
3. tmux1.8(AmazonLinux2標準)の設定ファイル(.tmux.conf) 

###【この記事がある理由】
- tmuxのマウス機能有効->通常キー操作でコピぺができなくなる
- ネットには「通常キー操作でコピぺできる様にする」方法がたくさん
- コピぺには「キー操作を変更するだけでOK」
- その他混乱する要因もあり整理
    - AWS AmazonLinux2を選ぶと、古いバージョンのtmux1.8が入ります。一方で最新バージョンは2.7。（2018.10.7時点）
    - インストールするにはAmazonLinux未検証リポジトリへの接続が必要
    - そもそもAmazonLinux選ぶ人は↑みたいなことはやるつもりないはず

###【この記事の対象者】
1. EC2インスタンスにssh接続が済んだ方
2. セッション管理にtmuxを使う方
3. tmux最新バージョン(2.7等)をインストールせず、すぐに運用したい方
4. tmux **コピーモード ```C-b [``` とか使いたくない人**

---

## 0.準備
1. tmuxをyumでインストール

``` 
sudo yum install tmux
``` 

###【注意】
- **マウス環境であれば、tmuxコピーモード ```C-b [``` は使う必要がありません**
- **この時点では普通にコピぺ出来ます**。マウス選択し通常キー操作(C-c C-v)でコピぺ。
- この後の**「tmuxマウス操作機能」を有効にするとコピぺ出来なくなります**。

## 1. tmuxの設定（「tmuxマウス操作機能」を有効化）

``` bash:.tumx.conf
~~抜粋~~
#マウス操作を有効にする
set-option -g mouse-select-pane on
set-option -g mouse-select-window on
set-option -g mouse-resize-pane on

# マウススクロール反映
set-window-option -g mode-mouse on
```
###【注意】
- 通常キー操作(C-c C-v)でコピぺ出来なくなっています。
- 以下のキー操作でコピぺ出来ます。
- 本質的には、**tmuxのコピーモードを回避しているだけ** です。


## 2. コピぺの新キー操作（「tmuxマウス操作機能」有効化時）
**もちろん、tmuxコピーモード ```C-b [``` とか使いません**
使用するターミナルソフトによってキー操作が異なります。

### MacOS : Terminal.app
<dl>
  <dt>コピー</dt>
  <dd>Shift+Command+マウスでコピーしたい箇所を選択</dd>
  <dt>ペースト</dt>
  <dd>Shift+Command+マウス右ボタンをクリック</dd>
</dl>

---
### MacOS: iTerm2 
**[激しく推奨!] Optionキーを使うだけ！**

<dl>
  <dt>コピー</dt>
  <dd> Option+マウスでコピーしたい箇所を選択、通常キー操作（Command+c）</dd>
  <dt>ペースト</dt>
  <dd>通常キー操作（Command+v）</dd>
</dl>

---
### xterm
<dl>
  <dt>コピー</dt>
  <dd>Ctrl+Shift+マウスでコピーしたい箇所を選択</dd>
  <dt>ペースト</dt>
  <dd>３ボタンマウス：　Ctrl+マウス真ん中ボタンをクリック</dd>
  <dd>上記以外　　　：　Ctrl+Shiftマウス右ボタンをクリック</dd>
</dl>
---

## 私の使っている tmux設定

``` bash:.tumx.conf
#マウス操作を有効にする
set-option -g mouse-select-pane on
set-option -g mouse-select-window on
set-option -g mouse-resize-pane on

# マウススクロール反映
set-window-option -g mode-mouse on

# 異なるサイズの端末からアクセスした時にリサイズ
setw -g aggressive-resize on

# 256 色対応
set -g default-terminal "xterm-256color"
set -g terminal-overrides "term:colors=256"
set -g display-time 2000

# バインドキーを vi 風に
set-window-option -g mode-keys vi

# 日本語対応
setw -g utf8 on
set -g status-utf8 on
```

---
## 感想
tmuxのコピぺの話は、３つのトピックがネット上でごっちゃになっており、よくよく読まないと混乱します。

<dl>
  <dt>tmuxコピーモードの話題</dt>
  <dd>「ターミナル端末側でコピぺ機能が使えない」大昔の環境下を仮定。現代では正直何が便利なのか？この機能がないと困る状況が思い浮かばない。</dd>
<dd></dd>
  <dt>tmuxマウス操作機能有効化による不具合（本記事）</dt>
  <dd>マウス操作機能有効化でおかしくなったので回避したいという話。マウスで領域選択した際にコピーモードが起動してしまい、OSのクリップボードに入らないため。ネットに数ある対策ではコピーモードの中でOSクリップボードに転送するスクリプトを挿入。一方、本寺記事の対策はtmuxのコピーモードを回避するキー操作を紹介してる。</dd>
<dd></dd>
  <dt>macOS版tmuxの問題：</dt>
  <dd>MacOS側とtmux側でクリップボード共有がうまくできない問題。記事内に「reattach-to-user-namespaceをインストールしましょう」という説明があるもの。tmux 2.6で問題解消されたり、設定ファイル内のコマンド名が変わったりしていて、説明記事は多い。</dd>
</dl>

tmuxの問題は、「コピーモードを使いたい」「キー操作を絶対変えたくない」という要望にすぎないのではないか？

## 【参考サイト】
1. https://scripter.co/tmux-shift-plus-mouse/
2. https://qiita.com/upinetree/items/cd80bc7865c52091be10
【Python3.6】任意の場所のモジュールを任意の名前で動的にimportする

Python 3.x でモジュールの動的importをする場合、 `importlib.machinery.SourceFileLoader.load_module()` が便利でした。

```python
import importlib.machinery as imm
datum = imm.SourceFileLoader('some', 'foo/some.py').load_module()
```

引用: [モジュールの動的読み込み](https://qiita.com/progrommer/items/abd2276f314792c359da)

しかし、Python3.6から `Loader.load_module()` が非推奨になってしまいました[^1]。`load_module()` の機能のうち、モジュールオブジェクトの生成は `create_module()`　が、コードの実行は `exec_module()` が引き継ぎ、`sys.modules` の管理などはインポートシステムが裏で行うことになったようです。

ではPython3.6以降の動的importはどうするべきかというと、`sys.meta_path` を一時的に変更するのが楽そうです。


```python
import sys
from importlib import import_module
from importlib.abc import MetaPathFinder
from importlib.util import spec_from_file_location

def import_module_from_file_location(name, location):
    class Finder(MetaPathFinder):
        @staticmethod
        def find_spec(fullname, *_):
            if fullname == name:
                return spec_from_file_location(name, location)

    finder = Finder()
    sys.meta_path.insert(0, finder)
    try:
        return import_module(name)
    finally:
        sys.meta_path.remove(finder)

mod = import_module_from_file_location('some', 'foo/some.py')
```

[^1]: https://docs.python.jp/3.6/library/importlib.html#importlib.machinery.SourceFileLoader
Railsのsystem testを実行すると何故かCSSとJSの読み込みだけ500が返ってきた

Railsのsystem testを導入する際,なぜかsystem test上でCSS及びJavaScriptのリクエストだけ500になるという問題に巡り会いました. 

かなりマイナーな問題なので同じ部分でハマる方がいるか分かりませんが, Web上を探しても特に解決策が載っていなかったため,一応メモとして残しておきます.

## 結論
- Pumaはヘッダーのキーにシンボルが使われていると落ちる ([# Issue 687](https://github.com/puma/puma/issues/682))
- 手元の環境では `test.rb` の `config.public_file_server.headers` で `Cache-Control` がシンボルだった

## 環境

``` ruby
'rails', '5.1.6'
'rspec-rails', '3.7'
```

## 事象
`rspec-rails` の3.7からsystem specが使えるようになったため導入するための準備を進めていました. その中で, 何故かsystem specの実行時のみサーバーから500が返され, ブラウザでCSSとJSの読み込みに失敗していました.

## 原因
system specのデフォルトサーバーであるpumaないで以下のエラーが発生していました.

```
Read error: #<TypeError: no implicit conversion of Symbol into String>
/vendor/bundle/ruby/2.5.2/gems/puma-3.12.0/lib/puma/server.rb:750:in `append'
```

エラーをもとにググると, Pumaはリクエストヘッダーにシンボルを指定すると落ちるようです ([# Issue 687](https://github.com/puma/puma/issues/682)). 

ここまで分かれば,あとはPuma内の当該箇所にdebuggerを仕込んで地道にどのヘッダーで落ちたのかを探りました.結果として,手元のRailsアプリケーションでは以下の `config/environments/test.rb` で `Cache-Control` がシンボル指定されていました.

``` ruby
config.public_file_server.headers = {
    "Cache-Control": 'public, max-age=3600'
  }
```

## 解決策

以下のようにシンボルを文字列に直して解決.

``` ruby
config.public_file_server.headers = {
    'Cache-Control' => 'public, max-age=3600'
  }
```

## その他
- system spec実行中のPumaのログは `Capybara.server = :puma` を明示的に指定してあげないと表示されないので注意
- Railsの[デフォルトテンプレート](https://github.com/rails/rails/blob/53eea40d354dafbeda1703aa0e4b4a688bc26017/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt#L18)は `Cache-Control` が文字列になっているのでなにかの拍子にそこを変更していなければ同じエラーでハマる人はいなさそう
[備忘録] Debian にユーザー追加するときにやること

## 概要

adduser <username> でユーザー追加、それだけで終わりじゃない。
自分のための備忘録として記録。

## 詳細

### OSにユーザーアカウント追加

```
sudo adduser <username>
```

### sudo 権限の追加、グループへの追加

```
sudo usermod -aG sudo <username>

# さらに、Docker 利用者の場合
sudo usermod -aG docker <username>
```

### ホームのサブディレクトリ名を英語化

```
LANGUAGE=en xdg-user-dirs-update --force
```

> 参考： <https://qiita.com/hidekuro/items/4519383f70c708e1b2d8>

### SSH 認証キーの登録

* すでに持っている認証キーを登録する場合

    + ~/.ssh/config にサーバー(server_alias)を登録
    + Windows でも `bash` と `ssh-keygen` が使える環境なら `ssh-copy-id` も使えるはず。

    ```
    PS> bash
    bash> ssh-copy-id -i <keyfile> <server>
    ```

* 認証キーを新規作成してから登録する場合
    > 参考：
    > * <https://qiita.com/Tats_U_/items/b8faf7dedb3187f609ca>

* 認証キーの暗号強度について
    + 今からなら ECDSA 鍵 256bit 以上を使おう。
     
    > 参考： お前らのSSH Keysの作り方は間違っている
    > * <https://qiita.com/suthio/items/2760e4cff0e185fe2db9>
    > 参考： GitHubユーザーのSSH鍵6万個を調べてみた
    > * <https://hnw.hatenablog.com/entries/2014/07/05>

## その他、注意事項

* TBD
【Vue】mixin オプションを別の mixin で使用する方法



## `Vue.util.mergeOptions`を使う

`Vue.util` モジュールには多数のユーティリティメソッドを持っています。
その中に `mergeOption` メソッドがあり、 これを利用して `mixin` 同士のオプションをマージさせます👆 
※本来は `vue` インスタンスオプションをマージするために利用されます。

### サンプル

```javascript


const mixin1 = {
  data () {
    return {
      mixin1: 'aaa'
    }
  },
  methods: {
    method1 () {
      console.log('method 1')
    }
  }
}
// Vue.util.mergeOptionsで mixin1 と mixin2 をマージする
const mixin2 = Vue.util.mergeOptions(mixin1, {
  data () {
    return {
      mixin2: 'bbb'
    }
  },
  methods: {
    method2 () {
      console.log('method 2')
    }
  }
})
const mixin3 = {
  mixins: [mixin2],
  data () {
    return {
      mixin3: 'ccc'
    }
  },
  methods: {
    method3 () {
      console.log('method 3')
    },
    methodAll () {
      this.method1()
      this.method2()
      this.method3()
    }
  }
}

new Vue({
  el: '#app',
  mixins: [mixin3],
  data () {
    return {
      message: 'hello'
    }
  },
  created () {
    this.methodAll()
  }
})

// => "method 1"
// => "method 2"
// => "method 3"

```

上記の場合、 `data` オプションの中身は以下のようになります。

```json:data
{
  "message": "hello",
  "mixin3": "ccc",
  "mixin2": "bbb",
  "mixin1": "aaa"
}
```

`Vue.util.mergeOptions` を使用することで、
他の `mixin` が持っているメソッドをコピーしなくても、
それらのコンポーネント内で利用することが可能になります👏


## 注意点

### `mixin` とコンポーネント自体に、重複するオプションが含まれる場合

たとえば、 `created` などのライフサイクルフックは配列にマージされ、すべてが呼び出されます✅
※コンポーネントよりも先に、 `mixin` のライフサイクルフックが実行されます

`methods`　などのオプションが重複するとコンポーネントのオプションにオーバライドされます✅
※同じ `methods`名や`data`プロパティ名など、マージしている場合は常に上書きされます。
ioniceコマンド・EBS pre-warmingメモ

ioniceを久々に利用したので忘れないようにメモ。

## 背景
EBSボリューム拡張(2.5TB→3.0TB)のため、スナップショットから作成し、EC2にアタッチ。
EBSはスナップショットから復元した場合、下記リンクの通りボリュームの初期化が必要。
　※EBSのオンライン拡張の機能が可能だが、+500GBと比較的大容量を拡張するため、拡張時間が膨大になりそう+IOに影響があるとのことで、メンテナンス時間を確保し従来の方法を採択
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-initialize.html

対象領域がおよそ3TBと大容量で、普通にpre-warmingを以下の
ddコマンドで実行するととてつもない時間がかかる。(1時間弱で25GB程度しか読み込みできず)

```$ sudo dd if=/dev/xvdc of=/dev/null bs=1M```
※拡張したデバイスは/dev/xvdc

本番環境で作業可能な時間も限られているため、
動かしながらionice / niceで少しずつ処理をさせることを検討。

## 実施したコマンド

```
$ sudo ionice -c 3 nice -n 19 dd if=/dev/xvdc of=/dev/null bs=1M
```

ioniceについては以下引用ページに十分な説明があるのでコマンドオプションなどはこちらを参照。
http://www.atmarkit.co.jp/ait/articles/1708/18/news018.html

## 補足
ioniceコマンドは実はIOスケジューラcfqしか効かないようなので注意。

　そのioniceほんとに効いていますか？
　https://www.slideshare.net/narimichitakamura/ionice

実行中プロセスのioniceを確認するコマンド

```
$ sudo ionice -p {プロセスID}
```

nice値の確認
"ps -l"コマンドを利用、"NI"列を参照。

```
$ ps -ewfly
S UID         PID   PPID  C PRI  NI   RSS    SZ WCHAN  STIME TTY          TIME CM
(略)
D root      35195      1  0  99  19  1664 26757 sync_p 13:01 ?        00:00:36 dd if=/dev/xvdc of=/dev/null bs=1M
```
リポジトリのcloneとforkの違い

# はじめに
Gitを使うようになってしばらく立つのですが、cloneとforkの違いについて理解できていなかったので、まとめました。

# clone
リモートリポジトリをローカルリポジトリに複製すること

# fork
他人のリポジトリを自分のアカウントの**リモートリポジトリ**にコピーすること

- **オリジナルのリポジトリへの貢献が前提**
- forkした場合そのリポジトリを所有する開発者に通知される

# forkによるワークフロー
![fork.PNG](https://qiita-image-store.s3.amazonaws.com/0/284567/c6162ef3-ab22-7062-d9f3-707d999a1a2a.png)
1. リポジトリAをfork
2. forkしたリポジトリBをローカルにclone
3. cloneしたリポジトリCで開発し、リポジトリBに反映
4. リポジトリAの管理者にPull Requestを送信

# まとめ
cloneは単に任意のリポジトリをローカルに複製する。
forkはOSSなどの自分以外のリポジトリに対して、何らかの追加機能の実装、バグ改修を行いたい場合使用するものである。
M5Stack FIRE 加速度センサーを取る方法

# M5Stackとは
M5Stack社が開発したArduino互換の開発キットです。
http://m5stack.com

## M5Stack fireに搭載の9DOFセンサー
9DOFとしてMPU6050とMAG3110を搭載しています。
MPU6050は３軸加速センサー、３軸ジャイロセンサー。
MAG3110は３軸磁力センサー。

##環境の構築

```shell
mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && \
python get.py 
```
環境構築詳細は下記リンクをご覧ください。
http://m5stack.com/assets/docs/index.html

ArduinoにM5Stack FIREが追加されたことを確認する。
<b>【確認方法】</b>

![mst004.png](https://qiita-image-store.s3.amazonaws.com/0/299088/1d00844f-aa7f-c47c-47d0-eeec0fdbe3bd.png)



## MPU6050ドライバーのインストール

まずはM5Stackライブラリをインストールする。
<b>【インストールの方法】</b>
![mst005.png](https://qiita-image-store.s3.amazonaws.com/0/299088/5005f295-3d49-ac80-36c5-02af791ab06e.png)
![mst006.png](https://qiita-image-store.s3.amazonaws.com/0/299088/70dcb5d4-d291-5e31-1278-18a3c0379c7b.png)

MPU6050ドライバーをインストールする。
<b>【インストールの方法】</b>
先程と同様に<b><i>"スケッチ〉ライブラリをインクルード〉ライブラリを管理"</i></b>からインストールする。
![mst007.png](https://qiita-image-store.s3.amazonaws.com/0/299088/b3800728-af7f-27ac-f005-21ee5d53f644.png)

## 加速度センサーのソースコード

M5Stackを接続し、シリアルポートを確認する。
![mst008.png](https://qiita-image-store.s3.amazonaws.com/0/299088/3eec15b0-9566-9bdd-c44c-3ae8e6a76f47.png)


加速度センサーのソースコード

```cpp

#include <M5Stack.h>
#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup()
{
  // Power ON Stabilizing...
  delay(500);
  M5.begin();
  //M5.setPowerBoostKeepOn(false);

  Wire.begin();
  Wire.setClock(400000UL);  // Set I2C frequency to 400kHz

  mpu6050.begin();
  mpu6050.calcGyroOffsets(false);

  M5.Lcd.setTextFont(2);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
  M5.Lcd.println("M5Stack Balance Mode start");
}

void loop()
{
  mpu6050.update();
  M5.Lcd.clear();
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.printf("X: %f", mpu6050.getAccX());
  M5.Lcd.setCursor(0, 20);
  M5.Lcd.printf("Y: %f", mpu6050.getAccY());
  M5.Lcd.setCursor(0, 40);
  M5.Lcd.printf("Z: %f", mpu6050.getAccZ());
  delay(500);
  // M5 Loop
  M5.update();
}

```

ソースコードは、ここを参考にしました。
http://forum.m5stack.com/topic/325/m5stack-fire-gyro-mpu6050/2

ビルドしてM5Stack FIREに転送して、確認。
dockerメモ

# この記事について
今のところ使う予定ないけど気になったり、いつか何かで使えるんじゃね？
と思ったものをまとめたもの。随時更新予定。

## build 時のオプション
`--build-arg`で変数指定、`-f`でDockerfile指定、ファイルじゃなくて git url を
渡すやつは知ったときに目からウロコだった。
http://docs.docker.jp/engine/reference/commandline/build.html

## 特定のユーザでコンテナにログイン

```bash
docker exec -u [UID] -it [コンテナ名] /bin/bash
```

## Docker hub に push

```bash
# ローカルのイメージを push する場合
docker tag [イメージ名]:[タグ] [レポジトリ]:[タグ]
docker push [レポジトリ]:[タグ]

# 起動しているコンテナのイメージを push する場合
docker commit [コンテナ名] [レポジトリ]:[タグ]
docker push [レポジトリ]:[タグ]
```

## --privileged フラグ
このフラグを付与すると、コンテナからホストのデバイス（/dev）にアクセスできるらしい。
https://medium.com/lucjuggery/docker-tips-mind-the-privileged-flag-d6e2ae71bdb4

## docker ログをローテートさせる
`--log-opt` で指定する。
以下は 100MB でローテート、10世代保存の場合。

```bash

docker run -d 
  --log-opt max-size=100m \
  --log-opt max-file=10 \
  --name metabase metabase/metabase
```
ifをパイプの中で使用する

[fukuoka.ex](https://fukuokaex.fun/)代表の[piacere](https://twitter.com/piacere_ex)です
今回もご覧いただいて、ありがとうございます:bow:

[前回のコラム](https://qiita.com/piacere_ex/items/c7c31499a6bde7f1fe0e)で、ifが、引数を2つ取る関数であることを解明しました

このことを利用して、パイプの中で、ifを使う方法について解説します

# パイプでifの第1引数を渡す

ifは、以下のように、第1引数に条件、第2引数に「do:」と「else:」のキーワードリストを取ります

```elixir
iex> if( "abc" == "abc", do: "abc is abc", else: "abc is not abc" )
"abc is abc"
iex> if( "abc" == "xyz", do: "abc is abc", else: "abc is not abc" )
"abc is not abc"
```

これをパイプで書き直すと、こうなります

```elixir
iex> ( "abc" == "abc" ) |> if( do: "abc is abc", else: "abc is not abc" )
"abc is abc"
```

なお、パイプで渡す部分をカッコで囲まないと、うまく動きませんので、注意してください

```elixir
iex> "abc" == "abc" |> if( do: "abc is abc", else: "abc is not abc" )
false
iex> "abc" == "xyz" |> if( do: "abc is abc", else: "abc is not abc" )
false
```

# パイプで繋いだ処理の中でifを使う

以下のような、0～10までの数字列のうち、3で割り切れるものだけ、trueを返す処理があったとします

```elixir
iex> 0..10 |> Enum.map( &( rem( &1, 3 ) == 0 ) )
[true, false, false, true, false, false, true, false, false, true, false]
```

この処理の中で、ifを挟むと、以下のような、trueになった数字だけをピックアップできます

```elixir
iex> 0..10 |> Enum.map( &( ( rem( &1, 3 ) == 0 ) |> if( do: &1 ) ) )
[0, nil, nil, 3, nil, nil, 6, nil, nil, 9, nil]
```

nilをEnum.filterで除去すると、こんな感じになります

```elixir
iex> 0..10 |> Enum.map( &( ( rem( &1, 3 ) == 0 ) |> if( do: &1 ) ) ) |> Enum.filter( &( &1 != nil ) )
[0, 3, 6, 9]
```

ifをパイプ中で使う方法が、お分かりになったでしょうか？

# ifをパイプで書かなくてもいいし、ifを使わなくてもいい

なお、このサンプルは、以下のように、普通のif文で書き直すこともできます

```elixir
iex> 0..10 |> Enum.map( &( if rem( &1, 3 ) == 0, do: &1 ) ) |> Enum.filter( &( &1 != nil ) )
[0, 3, 6, 9]
```

1行ifの強力さを実感できますね

更に単純化すると、以下の通りです

```elixir
iex> 0..10 |> Enum.filter( &( rem( &1, 3 ) == 0 ) )
[0, 3, 6, 9]
```

ifが無くなってしまいました:sweat:

全てのケースが、ここまで単純化できるかは、何とも言えませんが、Enumをマスターしていくと、データの塊を処理する際に、if文での判定が不要になっていくニュアンスを、ここから何となく受け取っていただけたら幸いです

# p.s.「いいね」よろしくお願いします

よろしければ、ページ左上の ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/4d515047-cc48-382e-c2b1-3ad0cc50dbbf.png) や ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/a4e3da58-70a3-4197-95a2-6a6906650d01.png) のクリックをお願いしますー:bow:
goenvでGoのバージョン管理

`golang` を使った開発のため、バージョン管理を導入したときの手順を書きます。 
 
> 最新版のGoを使うには goenv のリポジトリから取得する必要があることがわかりました。  
> 最新版Goを使うための手順はこちらに記載しました。  
> https://qiita.com/fujitahiroshi/items/48825404aa376fa293bb

## goenv について

**goenv** は Golang のバージョン管理ツールです。

https://github.com/syndbg/goenv

pyenv や rbenv など、他のバージョン管理ツールと同じようなものです。

## 環境情報

* macOS Mojave 10.14.6
* zsh 5.3 (x86_64-apple-darwin18.0)

## goenv インストール

Homebrew を使ってインストールします。

```console:zsh
$ brew install goenv
```

次は bash の場合 `.bashrc`、zsh の場合 `.zshrc` の設定をしていきます。 

## GOPATH 設定

go を使う時に必要な `$GOPATH` を設定しておきます。

### .zshrc

`$ vim ~/.zshrc` で編集開始。

```.zshrc:.zshrc
...
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$PATH
...
```

設定すると、`$HOME/go` 以下にパッケージ等がインストールされていくようになります。
(`go get -u github.com/go-sql-driver/mysql`  したものとか。)

## goenv パス設定

`goenv` を使うためのパスを通します。


### .zshrc


`$ vim ~/.zshrc` で編集開始。

```.zshrc:.zshrc
...
export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
export PATH=$HOME/.goenv/bin:$PATH
eval "$(goenv init -)"
...
```

## 設定反映

いつものおまじないコマンド

```consoe:zsh
$ source ~/.zshrc
```

## Go インストール

```
$ goenv install -l
Available versions:
  1.2.2
  1.3.0
  1.3.1
  ...
  1.11.4

...

$ goenv install 1.11.4
...
Installed Go Darwin 64bit 1.11.4 to /path/to/.goenv/versions/1.11.4
```

## 利用する Go バージョンの指定

環境によってバージョン切り替えます

```
# global の設定
$ goenv global 1.11.4

# 特定リポジトリ以下のバージョンを指定する場合
$ cd /path/to/repository
$ goenv local 1.9.7
```

これで、好きな場所、好きなバージョンで `go` を使えます。
便利だ。
.NET XXXの違いについて、ざっくりまとめてみた。

前々から疑問に思っていた.NET XXXの違いについて調べてみました。
すでに、まとめは色々な方がされていますが、それでも理解できなかったことがあったので、
それを踏まえて、ざっくりとまとめます。


# 関係性
![DotNet.png](https://qiita-image-store.s3.amazonaws.com/0/294947/00047631-26f3-c940-f74d-bfede78d369e.png)
###.NET Framework：
Windows環境向けのフレームワーク。
###.NET Core：
様々なOS上（Windows, Linux, macOS）で動作するアプリケーション開発用のフレームワーク。
主にサーバーアプリ/コンソールアプリとして使われる。
### Xamarin
様々なOS上（Linux, macOS, Andoriod, iOS）で動作するアプリケーション開発用のフレームワーク。
モバイル環境上にも対応している。
### .NET Standard
仕様。各.NET実装（.NET Framework, .NET Core, Xamarin）での共通で使用できるAPIをまとめたもの。
各.NET実装（.NET Framework/.NET Core/Xamarin）のベースライブラリ（Base Class Library/Core Library/Mono Class Library）の共通部分をまとめたもの。
.NET Standardプロジェクトで作成したDLLは、どの.NET実装環境下でも使用できる。

# .NET Core と Xamarin との違い
どちらもクロスプラットフォーム開発を目的とした.NET実装。
違いとして、守備範囲（対応するOS）が異なり、Xamarinのほうが守備範囲が広い。
また、以下の文章を見ると、処理性能では.NET Coreに軍配が上がるよう。（本当に？）
> 体的には、異なるデバイス（プラットフォーム）への対応を前提としたアプリ開発の場合、
> 開発手段としては 「Xamarin」を用いる。開発した.NETアプリケーションを特定用途でより高速実行したい、
> あるいはASP.NETのようなサーバ側のアプリケーションとして高速実行に期待したい場合には「.NET Core」といった形に、「水平展開」と「高速実行」で両者を使い分ける形になる。 
http://ascii.jp/elem/000/001/156/1156721/index-3.html

また、Visual Studioのデフォルトプロジェクトテンプレートだけを見ると、
.NET Core＝サーバーApp/コンソール向け、Xamarin=モバイル/macOS向け ともとれます。
（そう見せているのは、Microsoftの戦略なのだろうか。）


# 理解不足な点
上記引用文中の、
> 開発した.NETアプリケーションを特定用途でより高速実行したい、

について正しい理解が得れていません。。。そんなに性能面で異なるのか疑問です。
実際に、それぞれの環境で作成してみるとまた理解が深まるのかもしれません。


参考資料
-https://msdn.microsoft.com/ja-jp/magazine/mt842506.aspx
-http://www.atmarkit.co.jp/ait/articles/1707/28/news033.html
-https://www.infoq.com/jp/news/2017/10/dotnet-core-standard-difference
-http://ascii.jp/elem/000/001/156/1156721/