OmniAICreator/Qiita-1.07M huggingface dataset:
VMware ESXi のコンソールで、クライアントPCとの文字列のコピー＆ペーストを有効にする

※VMware_vSphereクライアントでの設定手順になります。

#1.対象仮想マシンの電源がオフの状態で[設定の編集]
#2.[オプション]タブの[詳細]-[全般]を選択し、[構成パラメータ]ボタン
#3.下記の２行を追加
 
| 名前|値 |
|:------------------:|:------------------:|
|isolation.tools.copy.disable|false|
|isolation.tools.paste.disable|false|

※ コンソールにつないだ状態でクライアントPC上でコピーを行うと、仮想マシン上のクリップボードにコピーされて残り、後から仮想マシンに接続した別の人もペーストできるので注意。
Sinatraで環境構築・データベース連携

#前説
お久しぶりです。色々あって休んでしまいました。心機一転！頑張っていこうと思います。

#目的
- Sinatraで環境構築
- アプリを一つ作る
- SQL、ActiveRecord、Gemに対する少しの理解

Railsを用いてアプリを作っていましたが、Railsはフルスタックなフレームワークなので、根本のシステム構成の理解が乏しい感じがしました。そのため、今回はSinatraを用いての開発です。

#手順
- プロジェクト作成
- Gemfile作成
- Sinatra、MySQL、ActiveRecord導入
- データベース作成
- view、main.rbを書いていく

#プロジェクト作成

#Gemfile
Gemfileからbundle installをしたいのですが、SinatraではGemfileを作成しないといけません。
以下のコマンドを打つと、Gemfile生成ができます。
Railsの時のようにGemfileにgemを書いてインストールしていきます。

```:Terminal
$ bundle init
```

```rb:Gemfile
#frozen_string_literal: true

source "https://rubygems.org"

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

gem 'sinatra'
gem 'mysql2'
gem 'activerecord'
gem 'rake'
gem 'sinatra-activerecord'
gem 'pry'
gem 'bcrypt'
```

色々入れました！！


```:Terminal
$ bundle install
```

#MySQLとの連携、ActiveRecord導入
私はMySQLを使うことができました。SQL文でデータベースとテーブルを作成してみましょう。
gemでの名前はmysql2なのでご注意ください。
mysql2というgemを使うことによって、MySQLと連携できます！

```:Terminal
$ mysql -u root
mysql>
```

これでMySQLにrootユーザーでログイン。
Sequel Proというアプリを使うと、GUIでデータベースやテーブルを確認できます！
ここでSQL文でテーブルを作っていきます。

```sql:mysql
mysql>CREATE [DATABASE_NAME];
mysql>USE [DATABASE_NAME];

mysql>CREATE TABLE [TABLE_NAME] (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  email VARCHAR(255) NOT NULL,
  url VARCHAR(255) NOT NULL,
  user_id INT UNSIGNED NOT NULL,
  created_at DATETIME NOT NULL,
  updated_at DATETIME NOT NULL,
  PRIMARY KEY(id)
);
```

私はRSSで情報をスクレイピングするまとめサイトのようなサイトを作るので以上のようなカラム設計となります。
PRIMARY KEY(id)は忘れないでください。
[TABLE_NAME]は小文字複数形で

```sql:mysql
mysql>SHOW [TABLE_NAME];
mysql>SHOW COLUMNS FROM [TABLE_NAME];
```

カラムを確認できます。

<img width="622" alt="スクリーンショット 2018-06-29 20.00.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/60d1f6ae-86fb-da67-12da-588c222bc874.png">


しかし、このままではSinatraのコードにSQL文を書かないといけません。
ここでActive Recordが役に立つのです。


SinatraのプロジェクトフォルダのRootディレクトリにdatabase.ymlを作成
これでMySQLで作成したデータベースに接続してくれます！
今回はdevelopment環境のみ。

```yaml:database.yml
development:
  adapter: mysql2
  database: [DATABASE_NAME]
  host: localhost
  username: root
  password: [私の場合は空白]
  encoding: utf8

test:

production:

```

main.rbです。

```ruby:main.rb
  #Gemfileからrequire
  require 'bundler'
  Bundler.require
  require 'rss'

  #database.ymlを読み込んでくれえ
  ActiveRecord::Base.configurations = YAML.load_file('database.yml')
  #development設定でお願い
  ActiveRecord::Base.establish_connection(:development)

class [TABLE_NAMEを単数形にして頭文字を大文字] <ActiveRecord::Base
  #値が空でないか
   validates_presence_of :name
   validates_presence_of :url
 end

#ルーティング
get '/' do
  erb :index
end
```

index.erbをViewsフォルダの中にで作成すればいい！

```:Terminal
$ ruby main.rb
```

もし何か不具合あればおしらせください！

#次回
user管理や踏み込んでその他諸々を書いていきます。

#参考文献
[Sinatra+MySQL+ActiveRecordでDatabaseの設定を行う - 珈琲駆動開発](http://totutotu.hatenablog.com/entry/2015/05/27/Sinatra%2BMySQL%2BActiveRecord%E3%81%A7Database%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E8%A1%8C%E3%81%86)
【UiPath】謎技術State machineに挑戦だ②（まとめ）

[前回の①](https://qiita.com/UmegayaRollcake/items/31320181a33375ddf747)では、State machineの知識ゼロの状態でスタートして、トライ＆エラーを繰り返しながら
Stateとtransition(s)を理解して、超簡単なワークフローを組むところまでいきました。
今回はState machineを触ってみてわかった事を、整理して解説してみます。

# 結局State machineとは何か
UiPathでワークフローを組むためのアクティビティはSequence, Flowchart, State machineの３種類。
SequenceとFlowchartは「ロボットに処理させたい作業の手順」を定義したものですが、
State machineは**「ロボットの日々の過ごし方」**を定義します。具体的には、

- この状態(State)の時、ロボットには何をさせるべきか？
- この状態(State)の時、何が起きたらどの状態(State)に移るのか？

を考えて、Stateを中心にワークフローを設計します。
人間に例えるとこんな感じ。
![state_salary.png](https://qiita-image-store.s3.amazonaws.com/0/255097/20038ea0-42bb-606d-22d5-aa40e21969ee.png)

面白くないので、別の絵にしてみた。

![state_ net.png](https://qiita-image-store.s3.amazonaws.com/0/255097/82e0191f-d852-6208-ca73-1573825666ea.png)
いいな！これいいな！**この生活いいな！**

・・・話をロボットに戻して、
Unattended robotのように無人で１日中動いているようなロボットにはState machineの発想がピッタリで、
ロボットの管理者は「このロボットにどんな働き方をして欲しいか」を考え、
その働き方／過ごし方をState machineを使ってデザインします。

そしてデザインする単位がSequence/FlowchartでなくState（状態）であり、
State間の遷移の条件をTransition（遷移）で定義します。

# StateとTransitionの解説
State machineを構成する要素についても解説します。

まずStateアクティビティです。
Stateには、そのStateに入ってきた時(Entry)と別のStateに遷移する時(Exit)に実行させたい作業を定義します。
別Stateに遷移するまでの間、同じ作業を繰り返しさせたい場合は遷移先の１つを自分にします。
そうすればループしてEntryとExitを延々と実行し続けます。
![loop.png](https://qiita-image-store.s3.amazonaws.com/0/255097/d5cb72d5-bd20-6db9-d5d2-b515e0fa24ba.png)


以下、Stateの各ブロックの解説です。
![state_exp.png](https://qiita-image-store.s3.amazonaws.com/0/255097/89c03821-5132-c88f-4868-68d50b26ce2b.png)

次にTransition。
マウスクリックやキー押下などのイベントをトリガーに遷移したい場合はそのイベントをTrigger部に定義。
※Monitor EventsアクティビティのRepeatForeverプロパティはFalseに直さないと
Trigger部から抜けられないので注意。

Conditionには、複数の遷移先Stateがある場合にそれぞれのStateに遷移する条件を定義。
それぞれのConditionはIfとElse Ifの関係になっていて**Elseが無い**ので、
条件の抜け漏れがあると詰まって進まなくなる。こちらも注意。

![tansition_exp.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a4a2e977-538a-d930-9c39-63e049aeac08.png)

# まとめ：State machineの使いみち
State machineが必要なケースは、
**「SequenceやFlowchartでは表現しきれないくらい、複雑すぎるワークフロー」**
を組む場合です。

Flowchartでもflow decision(If)やループを使う事で似たような事は実装できますが、
State machineはワークフローに存在する「状態」に着目して、まず状態とその移り変わりを定義し、
その後にそれぞれの状態の中でロボットに行わせたい作業を定義します。

「状態の遷移」と「作業の手順」を分離して考えられるので、
複雑なワークフローを設計するのに適しているのです。

というのが、ちょっとState machineを触っただけのニワカが勝手にまとめた結論です。

---
今回はここまで。
State machineはSequence, Flowchartと同様、元は.NETのWindows Workflow Foundation(WWF)の機能です。
Microsoft Docsの[ステートマシン ワークフロー](https://docs.microsoft.com/ja-jp/dotnet/framework/windows-workflow-foundation/state-machine-workflows)を見るとUiPathのワークフローと全く同じ絵面が出てくるので
UiPathの正体がWWF + RPA用のアドオンである事がよくわかります。
多層ニューラルネットワークの作成③

新生児の体重を予測することが今回多層ニューラルネットワークの作成①,②の目的だった。
[TensorFlow-cookbook~using multiple layers~](https://github.com/nfmcclure/tensorflow_cookbook/blob/master/06_Neural_Networks/06_Using_Multiple_Layers/06_using_a_multiple_layer_network.py)
そのために3つの隠れ層を持つニューラルネットワークを作成して7つの特徴量(お母さんの情報とか)を機械に教えた。
正答率は
*Test Accuracy: 0.394
Train Accuracy: 0.536*
と低い。この精度を上げるにはどうすればいいんだろう。(1に近づけたい)

考えたのは以下の通り
*①バッチサイズ(Batch_size)の変更
②反復(iteration)の変更
③ばらつき(st_dev)の変更
④ノードの数(Weight,biasの所)変更
⑤学習率(Adam)の変更*

##①バッチサイスの変更
もともとバッチサイズは100でした。
一番良かったのは32のときバッチサイズ小さくするといいんだ。へえー。でもデメリットもなんかありそう。

| Batch_size | Test  | Train |
|:-----------|------------:|:------------:|
| 32       | 0.500       | 0.609         |
| 64     | 0.473     | 0.596       |
| 100       | 0.394        | 0.536        |
| 256        | 0.315          | 0.523           |

##②反復iterationの変更
もともと200でした
反復は回数に比例して精度が上がる。そのまんまで書いた意味

| iteration | Test  | Train |
|:-----------|------------:|:------------:|
| 100       | 0.236       | 0.394         |
| 200     | 0.394      | 0.536       |
| 500       |  0.552      |  0.642       |
| 1000        | 0.710          | 0.768           |

##③ばらつきst_devの変更
もともと10だった
書くのがおっくうになってきた。
st_dev=2.5のときTest=0.868,Train=0.754で一番良かった。今回に限ってだけどばらつきは少ないほうが良かったのかな。

| st_dev       |       Test |   Train    |
|:-----------------|------------------:|:------------------:|
| 2.5             |              0.868 |        0.754        |
| 5.0           |            0.763 |       0.735       |
| 10.0             |              0.394 |        0.536        |
| 20.0             |                0.157 |         0.357         |
| 50.0            |             0.157 |       0.357       |

##④ノードの数を変更
重みは1~3層で変更可能なので複雑。一つの層をいじくってどれだけよくなったかをしか調べてない。
でも今回に関しては少しノードの数を少なくしたら精度が上がった。同時にやったらまた結果は変わりそうなのできにしない。

##⑤学習率の変更
学習率は大きくすると過学習、小さくするとデコイ？になるのが値で気づけた。
少しだけ上下に値を変えると精度が上がった。

| Adam       |       Test |   Train    |
|:-----------------|------------------:|:------------------:|
| 0.02             |              0.368 |        0.476        |
| 0.04           |            0.447 |       0.543       |
| 0.05             |              0.394 |        0.536        |
| 0.06             |                0.421 |         0.562         |
| 0.10            |             0.157 |       0.350       |

なぐりかきまとめ
Xgboost : feature_importanceのimportance_type算出方法

最近よく使用しているXgboostのfeature_importanceについてまとめます。
Qiita初投稿なので見にくさや誤り等ご容赦ください。

#決定木(Decision Tree)・回帰木(Regerssion Tree/CART)
決定木や回帰木は、データセットのジニ係数やエントロピーを最も改善させることのできる変数とその閾値を見つけ、それらをもとに枝分かれさせる、という操作を繰り返すことによって木が生成されていく。

#Tree Ensenble Model
RandomForestやXgboost、LightGBMをはじめとするTree Ensenble Modelは、これらの木を多数作成し、その重み付き多数決や加重平均によって予測値を算出するが、それぞれのアルゴリズムにはその木の作成手順(逐次的or並列的・評価基準・変数決定　など)において様々な工夫が施されている。

たとえばデフォルトのXgboostは以下のようなものがあげられる。

- 木の生成 : ブースティング(逐次的な生成)
- 評価基準 : ジニ係数と正則化項との和
- 変数決定 : histogram-based(変数を定められた数に量子化し、ビンごとに閾値として探索する)の貪欲法
- 重みづけ : 二次近似を行うニュートン法によって最適化

# Xgboost の Feature_importance
Tree Ensenble Modelはkaggleなどのコンペで多くの参加者に好まれているが、これらを使う利点としてはその強い予測性能に加え、変数重要度を容易に可視化できる点も大きい。
実際、僕も変数を選択する際、Xgboostのplot_importance_にかなり依存しているため、この重要度の算出にについてちゃんと理解しておく必要がある。
しかし日本語での記事が見当たらないため、Xgboostのドキュメントを読んで理解したので、メモ書き程度だがまとめてみたい。
[Xgboostドキュメント(Python)](https://xgboost.readthedocs.io/en/latest/python/python_api.html)


# importance type
Xgboostには変数重要度(=feature_importance)の指標として以下3つ用意されていた。

- weight
- gain
- cover


## weight
~~デフォルトではこのweightが用いられる。~~
weightは「生成された全ての木の中にその変数がいくつ分岐として存在するか」である。
ポイントとなるのはあくまで「存在する個数」しか見ていないという点。
どれだけ予測に近づける分岐をしているかや、入力に対してどれだけ分岐に使用されるのかという情報はここにはない。


## gain
gainとは評価基準をどれだけ改善させたることができる(できた)のかという値である。
各分岐においてこれが最大となる変数とその閾値を見つけるのがTree based Modelであるが、最終的に完成されたモデルにおいて、その変数が平均的にどれだけgainを与えたのかという指標が"gain"というimportance_typeである。
たとえばmax_depth:3・n_estimator:100であればモデル全体で分岐が合計700回起こるので、変数Xがgain=10で10回分岐に採用されたのであれば、Xのfeature_importanceは、100/7000=0.143となる。

## cover
coverという値は以下のように定義されている。[Xgboost(R ver)](https://github.com/dmlc/xgboost/blob/f5659e17d5200bd7471a2e735177a81cb8d3012b/R-package/man/xgb.plot.tree.Rd)
>
the sum of second order gradient of training data classified to the leaf, if it is square loss, this simply corresponds to the number of instances in that branch. Deeper in the tree a node is, lower this metric will be

そのまま訳すと、「coverとは葉に分類された訓練データの二次勾配の合計値である。誤差関数が二乗誤差であれば単純に分類に登場した回数に対応する。木の中で深い位置にあるほどこの指標は小さくなる。」

一方で、importance_typeの欄に、
>“cover” is the average coverage of splits which use the feature

とある。わかりにくいがおそらくこの文に登場するcoverageという値が先の引用でのcoverにあたり、その平均値を変数重要度として用いたのが、"cover"というimportance_typeなのであろう。分類問題における"cover"を理解するには誤差関数の二次勾配について知っておく必要があるが、回帰問題の時にはとても直観的で「一つの入力が何度この変数によって分岐されるか」の平均がfeature_importanceとなる。

##追記　(@Koutaru さんのご指摘をうけて)
デフォルトがgainに変わったそうです。
また、平均ではなく合計をとったtotal_gain,total_coverもできたそうです。

# まとめ
- weight : その変数が全ての木の中にいくつ分岐点として存在するか
- gain : その変数が平均的にどれぐらい評価基準を改善しているのか(全分岐点についての平均)
- cover : (回帰問題では)
ある入力に対して平均的に何度分岐に用いられているか(全入力についての平均)

\*平均の意味が微妙に異なる点に注意が必要。



以上、大雑把ですがXgboostの変数重要度に関するまとめでした。
直観的にはgainやcoverが本質的な重要度な気がするのですが、なぜweightがデフォルトなのかとても気になります。
その点についても調査できれば今後記事にしたいと思います。
unique_ptrとインスタンス配列

生ポインタをC++で使うのが不安で仕方ないのでスマートポインタを勉強しているのだが、unique_ptr周りの挙動で独特な部分があったのでまとめておこうと思う。

#ポリモーフィックな定義をするとき
C++でポリモーフィックなコードを書くときは、次のように親クラスのポインタに子クラスをnewで代入することが多い。

```C++
parent_class* myptr = new child_class;
```

ただし誰もが知るように大原則として**newしたら必ずdeleteしなければならない**ので、この方法ではうっかりdeleteし忘れる不安がついて回る。

そこでポインタの代わりにスマートポインタを使う。これはC++11以降導入された機能で、スコープを抜けるとき勝手にデストラクタを呼んでくれる便利な代物だ。使うには```memory```ライブラリをincludeしておき、さらにコンパイルオプションに```-std=c++11```（c++11以降ならよい）と指定する必要がある。

```C++
std::unique_ptr<parent_class> myptr(new child_class);
```

このようにしておくことで、```myptr```がスコープを抜けて消滅するときデストラクタが呼ばれる。通常のポインタと同様まずはparent_classのデストラクタが呼ばれるし、それがvirtualならchild_class、parent_classの順でデストラクタが呼ばれる。

#インスタンスの配列なら？
Cを知ってる人ならわかるが、配列を指す生ポインタは配列の先頭アドレスを指す。そのため生ポインタでは次のようにすることでインスタンスの配列をアロケートすることができる。

```c++
parent_class* myptr = new child_class[10]

//...

//deleteするとき
delete[] myptr
```

また、**組み込み型に限り**、スマートポインタでも同様に置き換えることができる。

```c++
std::unique_ptr<int[]> myint[10]
```

なので、インスタンスの配列でも同じようにしたくなるところだが、うまくいかない。

```c++
//コンパイルが通らない
unique_ptr<parent_class[]> myptr(new child_class);
unique_ptr<parent_class[]> myptr(new child_class[10]);
//コンパイルは通るがresetできない
unique_ptr<parent_class[]> myptr(child_class[10]);
```

そこで調べたところ、以下の記事にたどり着いた。

https://ja.stackoverflow.com/questions/33196/unique-ptr%E9%85%8D%E5%88%97%E3%81%AB%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B%E6%96%B9%E6%B3%95

どうやら**unique_ptrでインスタンスの配列の先頭アドレスを指すというような使い方はできない**ようで、無理にunique_ptrを使おうとしてもなかなか面倒なようだ。

なのでこのような場合はおとなしく```vector<parent_class>```や```array<parent_class>```とするのがよいようだ。しかしこれではポリモーフィズムを実装できない。

そこで、**unique_ptrのコンテナ**という形で定義する。arrayを使う場合は次のようになる。

```c++
std::array<std::unique_ptr<parent_class>, 10> myptrs;

for(int i=0;i<10;i++){
   myptrs[i].reset(new child_class);
}
```
Virtualbox に Raspberry Pi Desktop をインストール

Arch Linux にインストールした Virtualbox に Raspberry Pi Desktop をインストールしました。
>インストールイメージは、
2018-06-27-rpd-x86-stretch.iso

次のページを参考にしました。
[VirtualBox に入れた CentOS のネットワーク設定](http://www.shookuro.com/entry/2018/02/10/172724)
![raspbian_jun2900.png](https://qiita-image-store.s3.amazonaws.com/0/179446/5b238c33-d899-1a41-005f-47bd83caf985.png)

1) Raspbian をインストールします。
インストールするだけで、インターネットに ping が通ります。
![raspbian_jun2901.png](https://qiita-image-store.s3.amazonaws.com/0/179446/763b7435-065e-c31a-a1f5-c0433f3c9ab6.png)

2) ポートフォワーディングの設定
「設定」→「ネットワーク」→「高度」→「ポートフォワーディング」
Host Port 2000
Gest Port 22

![port_jun2901.png](https://qiita-image-store.s3.amazonaws.com/0/179446/c6ca0395-aa81-5378-c052-34fcc42786ff.png)
![port_jun2902.png](https://qiita-image-store.s3.amazonaws.com/0/179446/41241f69-1fe7-5c33-41c3-21de851cd551.png)

3) ssh を有効にする

```bash
sudo raspi-config
```

![ssh_jun2901.png](https://qiita-image-store.s3.amazonaws.com/0/179446/c84febdd-e86a-bb90-0e41-111321bb8571.png)

4) ホストから　ssh で接続

```bash
ssh -p 2000 pi@localhost
```
webpack4で外部のCSSフレームワークを自分のjsにbundleせずに読み込みたい

# やりたいこと
**外部CSSフレームワークのCSSを自分のjsにbundleせずに読み込みたい。**

例えばBootstrapのCSSを使いたいけど、自分のReactコンポーネントでは`css-modules`や`react-css-modules`を使いたいので、vendorとは分けたいという場合の忘備録。

- 必要なものをインストール

```bash
npm install --save webpack webpack-cli css-loader extract-text-webpack-plugin@next react-css-modules css-modules
```
*1.* vendorのscssファイルをまとめたものを用意する。
`/vendor/css/import.scss`

*2.* 自分のscssファイルは各自コンポーネントで読み込む。
`src/index.js`とかで`import styles from './index.scss';`で使う。

```js:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './index.scss';

class App extends React.Component {
  render() {
    return (
      <div className={styles.main}>
        <h1>Hello React World</h1>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.querySelector('#main'));
```

*3.* webpackのentryとoutputを編集。

```js:webpack.config.js
  entry: {
    bundle: './src/index.js',
    vendor: './vendor/css/import.scss',
  },
  output: {
    path: dist,
    filename: '[name].js',
  },
```
*4.* cssのruleを設定する。
vendorのcssはmodulesをfalseにして、`extract-text-webpack-plugin` でjsとcssを分割する。

```js:webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractCSS = new ExtractTextPlugin({ filename: '[name].css', allChunks: true });
// bundle 
const bundleSassRule = {
  test: /\.(css|scss)$/,
  exclude: fs.realpathSync('./vendor'),
  use: extractCSS.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
        options: {
          importLoaders: 1,
          modules: true,
          url: true,
          localIdentName: '[name]__[local]--[hash:base64:5]',
        },
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: true,
          outputStyle: 'expanded',
          sourceComments: true,
          indentWidth: 2,
        },
      },
    ],
  })
};
// vendor
const vendorSassRule = {
  test: /\.(css|scss)$/,
  include: fs.realpathSync('./vendor'),
  use: extractCSS.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: true,
          outputStyle: 'expanded',
          sourceComments: true,
          indentWidth: 2,
        },
      },
    ],
  })
};
module.exports = {
  module: {
    rules: [jsRule, bundleSassRule, vendorSassRule ...],
  },
};

```
これで以下のファイルが出力されるはず。

```
bundle.js
bundle.css
vendor.js
vendor.css
```
あとはhtmlでbundle.jsとbundle.css、vendor.cssを読み込めばOK。

#### その他
entry で `vendor: './vendor/css/import.scss',`を指定しているのにvendor.jsができちゃう問題は[issue](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/518)にも上がっていますが、解決方法はないようです。

とはいえ、今どきはstyled-component使うか・・・。
【BigQuery】当月の初めの日付と終わりの日付を取得する

あまり褒められるような書き方ではないかもですが、
6月中であれば、毎日、

```
_TABLE_SUFFIX BETWEEN
  '20180601'
  AND
  '20180630'
```

という指定をしてクエリを投げたかったのです。

## 書き方

```sql
CREATE TEMPORARY FUNCTION GET_FROM_DATE() AS (DATE_TRUNC(CURRENT_DATE(), MONTH));
CREATE TEMPORARY FUNCTION GET_TO_DATE() AS (DATE_ADD(DATE_ADD(GET_FROM_DATE(), INTERVAL 1 MONTH), INTERVAL -1 DAY));
CREATE TEMPORARY FUNCTION TO_SUFFIX(_date DATE) AS (FORMAT_DATE('%Y%m%d', _date));

SELECT
  *
FROM
  `dataset.table*`
WHERE
  _TABLE_SUFFIX BETWEEN
    TO_SUFFIX(GET_FROM_DATE())
    AND
    TO_SUFFIX(GET_TO_DATE())

```


なんかもっと楽にできる気がするけど、なかなかそんな便利な関数を見つけられなかったので・・・。
別の簡単な方法があればどなたか教えてください。
論理回路の基礎 #1デジタル信号の基礎

# 信号って何だ？

この世の中にはラジオのAM/FMから始まり、ありとあらゆる(電気)信号が飛び交っていて、その中には

* アナログ信号
* デジタル信号

の2種類が存在しています。

もともと、人間は信号を発明してから長らく、アナログ信号をメインに使っていましたが、ここ2～30年でデジタル信号が圧倒的に増えてきました。
インターネットを使う人は増え、電話もテレビもデジタル化されてきました。

なぜ、アナログからデジタルに変わってきたかというと、以下の理由が挙げられます。

1. 精度がよい。
  cf.) アナログの信号の場合、最大値が大きいときに小さな値の違いを正確に見ることができない。

2. ノイズの影響を受けずらい
　cf.) デジタル信号は0か1なので、多少ノイズが入っても大丈夫。
       ノイズが大きすぎるなら、信号自体も大きくすればいい。

3. 回路内に記憶させることが容易。
  cf.) 電圧がかかったかかかっていないか、のみ残ればよいので、記憶が容易。

4. 演算を行うことが容易。
  cf.) バイトごとに処理するなどの標準化を行うことによって、簡易に処理できる。

以上の理由からデジタル信号は今日に至るまでの盛況を見ているようです。

# デジタル信号の表記方法

デジタル信号は2進数ですべてを表現する形をとっています。

2進数とは、0と1で数字を表現する方法で、人間が理解しやすい方法として8進数と16進数で書き換えることが多いです。

## 2進数・8進数・16進数
ここで、2進数・8進数・16進数と10進数の比較を見てみましょう。

``` math
  0_{(10)} = 00000_{(2)} = 0_{(8)} = 0_{(16)}\\
  1_{(10)} = 00001_{(2)} = 1_{(8)} = 1_{(16)}\\
  2_{(10)} = 00010_{(2)} = 2_{(8)} = 2_{(16)}\\
  3_{(10)} = 00011_{(2)} = 3_{(8)} = 3_{(16)}\\
  4_{(10)} = 00100_{(2)} = 4_{(8)} = 4_{(16)}\\
  5_{(10)} = 00101_{(2)} = 5_{(8)} = 5_{(16)}\\
  6_{(10)} = 00110_{(2)} = 6_{(8)} = 6_{(16)}\\
  7_{(10)} = 00111_{(2)} = 7_{(8)} = 7_{(16)}\\
  8_{(10)} = 01000_{(2)} = 10_{(8)} = 8_{(16)}\\
  9_{(10)} = 01001_{(2)} = 11_{(8)} = 9_{(16)}\\
  10_{(10)} = 01010_{(2)} = 12_{(8)} = A_{(16)}\\
  11_{(10)} = 01011_{(2)} = 13_{(8)} = B_{(16)}\\
  12_{(10)} = 01100_{(2)} = 14_{(8)} = C_{(16)}\\
  13_{(10)} = 01101_{(2)} = 15_{(8)} = D_{(16)}\\
  14_{(10)} = 01110_{(2)} = 16_{(8)} = E_{(16)}\\
  15_{(10)} = 01111_{(2)} = 17_{(8)} = F_{(16)}\\
  16_{(10)} = 10000_{(2)} = 20_{(8)} = 10_{(16)}\\
  17_{(10)} = 10001_{(2)} = 21_{(8)} = 11_{(16)}\\
  18_{(10)} = 10010_{(2)} = 22_{(8)} = 12_{(16)}\\
  19_{(10)} = 10011_{(2)} = 23_{(8)} = 13_{(16)}\\
```
これを見ると、8進数は2進数の3桁分、16進数は4桁分をまとめて表現できるのがわかるでしょう。

例えば、10進数の11と19を見てみてください。
2進数で見ると下3桁8進数で見ると1桁が同じです。
8進数は2進数の3桁分とイコールなのです。

このように2進数を表現しやすいため、8進数や16進数も一緒にコンピュータの世界では使われるのです。

# 勉強会のお知らせ

この記事は、勉強会の資料を兼ねて書かれたものです。
2018/08/09 19:30～
溜池山王：細川ビル3階会議室で、勉強会を行います。
よろしければ、ふるってご参加くださいね！

https://connpass.com/event/93120/
AlibabaCloudのECSのユーザーデータについて

# はじめに
今までECSを起動してますが、サーバにログインして
Nginxを起動するのは手間ですネ。
今回はECSのユーザーデータに触れます。

# ユーザーデータとは

[ユーザー定義データ - ユーザガイド| Alibaba Cloud ドキュメントセンター](https://jp.alibabacloud.com/help/faq-detail/49121.htm)

> ユーザー定義データは、ECSインスタンスの起動動作をカスタマイズし、ECSインスタンスにデータを渡すためにAlibaba Cloudによって提供される機能です。 この機能は、WindowsまたはLinuxのいずれかを実行するECSインスタンスで機能します。
> 
> ユーザー定義データは、以下のように分類できます。
> 
> ・ユーザー定義のスクリプト。インスタンスの開始時に実行するためにインスタンスに渡すことができます。
> ・汎用データ。インスタンス内で参照されるインスタンスに渡すことができます。

# 起動するユーザーデータはコチラ

```shell
#!/bin/sh
yum update -y
yum install -y nginx
systemctl enable nginx.service
systemctl start nginx.service
```

# コンソールからECSを起動するとき

![e5c8811c.png](https://qiita-image-store.s3.amazonaws.com/0/241104/1ffee615-9c76-9be2-8075-effd4fdbdb33.png)

と入れるだけでOKです。

# ROSからECSを起動するとき

**Base64エンコーディング**
が必要になります。

**"ALIYUN::ECS::Instance"**
のパラメータで

```json
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "\n",
              [
                "#!/bin/sh",
                "yum update -y",
                "yum install -y nginx",
                "systemctl enable nginx.service",
                "systemctl start nginx.service"
              ]
            ]
          }
        }
```

といれればOKです。

[User data - User Guide| Alibaba Cloud Documentation Center](https://www.alibabacloud.com/help/faq-detail/49121.htm)

# まとめ
これで、ECSを起動するとnginxが動くようになります。

# おまけ
サーバにSSHして下記のコマンドを打つと

```shell
[root@poc ~]# curl http://100.100.100.200/latest/user-data
#!/bin/sh
yum update -y
yum install -y nginx
systemctl enable nginx.service
systemctl start nginx.service
```

とメタデータからユーザーデータを確認することができます。
こちらはまた別の機会にお話します。
そろそろJSわかってきたぞ！！ってときに改めて確認しておきたいJSデータ型の落とし穴

改めてJSの基本を勉強し直していて、
あーここもう少し前に知りたかったなという点があったので書いておきます。

## データ型について　
そもそもデータ型とは、データの種類の事。
大きく分けると基本型と参照型があります。

- **基本型**…数値や文字列、真偽値など
- **参照型**…配列や連想配列、関数など

この2つの大きな違いは「値を変数に格納する方法」。
基本形は値そのものが変数に入りますが、
参照型はその配列や関数の入れてあるメモリ上のアドレスが変数に入ります。
イメージでいうと以下のような感じです。

![データ型1.png](https://qiita-image-store.s3.amazonaws.com/0/237008/4bf4373c-73bb-6c47-73b1-e66fadbda550.png)



## これがわかってないと何が困るの？？？

参照を行った時に「？？？」となる可能性があります。
具体例を見てみましょう。

```javascript:test.js

var num1 = 5;
var num2 = num1;
num1= 10;

console.log(num2);

```
この場合consoleに表示される値は「5」となります。
数字を上書きされたのはnum1なので、num2は元の数字のままというのは直感的にわかりますよね。

では下の例ではどうでしょうか？

```javascriptt:test.js

var array1 = [1,2,3];
var array2 = array1;
array1[0] = 5;

console.log(array2[0]);

```

この場合、表示される値は「1」…ではなく「5」になります。
なぜ！？値を変えたのはarray1の方だけだよ？？？
と思うかもしれませんが、これは先ほど言ったアドレスが変数に入っているためです。
どうゆうことかというと、以下の図のような感じ。

![データ型2.png](https://qiita-image-store.s3.amazonaws.com/0/237008/92ec4147-b01a-2027-7db9-8099d7358052.png)



ちょっとしたことですが、このイメージができるかできないかで壁にぶつかった際の理解スピードが違うと思うので、
頭の片隅にでもおいておいてもらえればと思います。
[AWS] ALB Target Groupの登録解除遅延をpythonで一括で変更

解除遅延が未設定では300秒になっており、
リリースの際ALBから切り離すのを待つのが地味につらいため、60秒に一括で変更したかった。
Management Consoleからポチポチ変更しても良かったが、面倒なのでスクリプトで。


```python
import boto3

timeout_seconds = 60

elbv2 = boto3.client('elbv2')
target_groups = elbv2.describe_target_groups()['TargetGroups']
for target_group in target_groups:
  print('# ' + target_group['TargetGroupName'])

  attr = elbv2.describe_target_group_attributes(TargetGroupArn=target_group['TargetGroupArn'])['Attributes']

  now_timeout_seconds = filter(lambda x: x['Key'] == 'deregistration_delay.timeout_seconds', attr)[0]['Value']
  if int(now_timeout_seconds) > timeout_seconds:
    print('modify deregistration_delay timeout_seconds')
    elbv2.modify_target_group_attributes(
      TargetGroupArn=target_group['TargetGroupArn'],
      Attributes=[{
        'Key': 'deregistration_delay.timeout_seconds',
        'Value': str(timeout_seconds)
      }]
    )
  else :
    print('not change: ' + now_timeout_seconds)

```
属性の変更ならこの部分を変更すれば大体行けるはず
`filter(lambda x: x['Key'] == ${変更したい属性}, attr)[0]['Value']`

使い捨てスクリプトだが、似たようなことをまたやるだろうからメモ
JavaScriptの配列操作

Javaなら`List.add`とか`List.remove`とか`List.addAll`とかで簡単にできることがJavaScriptだと難しかったりするので、よく使う配列操作をまとめてみました。


## 配列の末尾に要素を追加する

配列`array`に要素`item`を追加する。Java的には`List.add()`。この操作は`array`自身を変更する。

```js
array.push(item)
```


## 配列から要素を削除する

配列`array`内の要素`item`を削除する。Java的には`List.remove(item)`。この操作は`array`自身を変更する。

```js
const index = array.indexOf(item)
if (index >= 0) {
  array.splice(index, 1)
}
```


## 配列の先頭に要素を追加する

配列`array`の**先頭**に要素`item`を追加する。Java的には`List.add(0, item)`。この操作は`array`自身を変更する。

```js
array.unshift(item)
```


## 配列の後ろに配列を結合する

配列`a`に配列`b`を追加する。Java的には`List.addAll(b)`。この操作は`a`自身を変更する。

```js
a.splice(a.length, 0, ...b)
```

配列`a`に配列`b`を追加した配列`c`を作成する。`a`自身は**変更しない**。

```js
c = a.concat(b)
```
Prometheusのすすめ - Service Discovery -  EndPointが「http://:9100/metrics」になって、自分自身になってしまう件

##【問題】
以前[Prometheusのすすめ - Service Discovery -]([https://qiita.com/nekoneck/items/aefdbb9d2a1bb1f03513)にて設定したやり方だと
PublicIPを持っていないインスタンスに対してはEndPointが「http://:9100/metrics」になって
自分自身にexporterを入れてる場合に、「http://:9100/metrics」になっているインスタンスは自分自身のexporterに取得しに行ってしまう。


##【解決策】

色々と悩んだ結果、PublicIPがちゃんと設定されている場合のみrelabelがされれば良いようにする。

```diff:prometheus.yml抜粋
    relabel_configs:
      - source_labels: [__meta_ec2_public_ip]
-        regex:  '(.*)'
+        regex:  '([1-9].*)'
        target_label: __address__
        replacement: '${1}:9100'
      - source_labels: [__meta_ec2_tag_Name]
        target_label: instance
```


これで、PublicIPを持ってないインスタンスはそのままプライベートIPになるので、問題なし。
CreateMLを使ってさらっと画像認識させてみた

# はじめに
こんにちは、先日WWDC2018報告会にいってきました。
そこでCreateMLについて発表されていた方がいて面白そう✨と思ったので
やってみました

## CreateMLってまずなんだよ
SwiftやPlayGround上でCreateMLを使うことによって機械学習ができるフレームワークです。
データを学習させれば画像認識や文章の分類やデータの分類や量の推定ができるなどができるようになります。
その中から今回は画像認識についてやっていきまっせ
XcodeとSwiftだけで機械学習ができるなんてすごいね！！！

## やる前に準備しなきゃね
* macOS 10.14+ (mojave)
* Xcode 10.0+

この二つが必要です
まだbetaなのでmojaveを入れる時にはバックアップを取っておくと安全ですね！
（ちなみに僕はアァーって感じでバックアップを取らずに会社のMacBookにぶち込みました）

## やってみよう
PlayGroundを開いてtargetをmacOSにします

```swift:MyPlayGround 
import CreateMLUI

//画像を分類するでってやつ
let buidler = MLImageClassifierBuilder()
//AssistantEditorのLiveViewに表示するでってやつ
buidler.showInLiveView()
```

コードはこれだけ!!!
わーすごい!
RunしてAssistantBuidlerを開くとこんな画面![スクリーンショット 2018-06-29 16.33.35.png](https://qiita-image-store.s3.amazonaws.com/0/126492/7b4cb899-c69a-1e99-9ca6-3e9a0c2e0e1d.png)

そういえば...
データセットを用意してなかったね！
なんか適当にたくさん画像を拾って来ましょう
最低でも10枚は必要そうなので頑張って集めましょうね

![スクリーンショット 2018-06-29 16.36.49.png](https://qiita-image-store.s3.amazonaws.com/0/126492/06445ac5-18bc-79ab-2ef2-18b784612c8c.png)
僕はこんな感じでトレーニングさせるようのデータを各フォルダに３０枚ずつぶちこんでます
とりあえずはこれぐらいでいいかな(チョットメンドクサカッタヨネ)

テストデータとトレーニングデータは1:9の比率がベストらしいので（なんかで見た）
テスト用のデータを３枚ずつ準備しましょう![スクリーンショット 2018-06-29 16.41.33.png](https://qiita-image-store.s3.amazonaws.com/0/126492/e27006cc-5388-b9ff-9334-cc80b758f199.png)
こんな感じで

そしたらAssistant Editorの点線のなかにDrop Images To Begin Trainingって書いてあるので
トレーニング用のフォルダをドロップアンドドロップしてやりましょう
そうすると学習している様を見学できます

終わったら点線の中身がDrop Images To Begin Testingに変更されているので
テスト用のフォルダをドロップアンドドロップしてやりましょう

![スクリーンショット 2018-06-29 17.36.23.png](https://qiita-image-store.s3.amazonaws.com/0/126492/a7fb783e-8d63-f689-3fc3-86e178d924c2.png)

結果がでましたね！
全部あってました(すごいっ...)

あとはAssistantEditorのImage Classifierって書いてある横の下矢印を選択して保存する場所とかを
選んで保存すればプロジェクトなどで今回できたmlmodelを使うことができます。
*ちなみに保存したmlmodelのサイズは33KBととても軽量...!

##終わりに

割と簡単にできましたね
CreateMLではPhotsとSiriの学習基盤を使っているおかげで軽量かつ速い学習が
実現しているみたいです

ざっくりとしか書いていないのでもし興味がある方は下記のURLから調べて見てくださいhttps://developer.apple.com/documentation/create_ml

ありがとうございました。マサカリ待ってます。
Openweathermapの観測ポイントをGoogleMap上で確認してみた。

#目的
観測ポイントをGoogleMap上で確認できるようにする。

※天気情報を取得できるサービスのOpenweathermapから温度、天気を取得する際に、情報を取得したい位置に近い観測ポイントを調べるために行いました。

#手順
①Openweathermapを使うための準備を行います。ここで観測ポイントの情報が入ったjsonファイルを取得します。
②経度、緯度からピンを立ててくれるWebサービスに貼り付けるテキストを①で所得したjsonファイルから作成します。
※テキストエディタ(sakuraエディタ）でゴリゴリ加工して作成します！もっとスマートなやり方があれば教えてください。
③②で加工したテキストをWebサービスに貼り付け、MAPを確認。観測位置に近いポイント情報を取得！

##①Openweathermapを使うための準備を行います。
最初にどの天気情報サービスを使うかを検討した際に参考にさせていただいたのが下記の記事です。
https://qiita.com/Barbara/items/93ae7969691164c7c2bc

欲しい情報はOpenweathermapで取得できそうだったので、今回はOpenweathermapを選択。
Openweathermapの使い方は下記の記事を参考にさせていただきました。
https://qiita.com/nownabe/items/aeac1ce0977be963a740

※このブログの手順の中で観測ポイント情報の「city.list.json」をダウンロードするので、それを保管しておいてください。

###とりあえずテスト実行してみる。
テスト実行はRestlet Clientを使って行いました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/a8c95a36-7909-889c-3607-f124475a5ceb.png)

URL:http://api.openweathermap.org/data/2.5/weather?id=1857910&APPID=[取得したキー]&units=metric&lang=ja
パラメータ：
id：1857910　（京都=kyotoのidをcity.list.jsonファイルから取得）
units=metric ：　気温を℃で取得します。
lang=ja　：　お天気情報を日本語で取得します。

＜結果＞
無事に取得できました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/3e5a364e-d2e5-fdf4-f611-d64ff52d0f17.png)

##②　経度、緯度からピンを立ててくれるWebサービスに貼り付けるテキストを①で所得したjsonファイルから作成します。
Jsonファイルをプログラムで読み込ませて加工しようかとも考えたのですが、正規表現で置換すればとりあえずいけるのではないかと考えて、加工して見ました。
エディタはsakraエディタを使っています。

＜手順＞

1. ①で保存した観測ポイント情報の「city.list.json」ファイルをコピーし、mapinfo.txtという名前に変更
2. mapinfo.txtをsakuraエディタで開く（文字コードはutf-8で開く）
3. 下記の手順で加工する
　※置換する際は正規表現チェックをＯＮにしておいてください。
　※１工程ごとに保存することをお勧めします。
    
    3-1. " "を""に置換（スペースを削除）
    3-2. "\""を""に置換（ダブルクォートを削除）
    3-3. "\n"を""に置換（改行”\n" を削除）
    3-4. "},{"を"\n"に置換（データの区切りで改行）
    3-5. 最終行に\nを入力（次の置換を成功させるために必要）
    3-6. "^(?!.*,country:JP,).*\n"を""に置換（JPを含まない行を削除）
    3-7. "}\n"を"\n"に置換（行末の}を削除）
    3-8. "[A-z|{]*:"を""に置換（不要な文字を削除）
    3-9. "^([0-9]*),"を"$1_"に置換 （id列とname列を結合）
    3-10. ",JP"を""に置換　（country列を削除）
    3-11. "\n"を",0\n"に置換　（アイコン記号番号を追加）

正常に終了すると下記のようなテキストになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/75b7803e-4e7a-a891-581d-7cb5428c5978.png)

##③　②で加工したテキストをWebサービスに貼り付け、MAPを確認。観測位置に近いポイント情報を取得！

使用するＷｅｂサービスのＵＲＬ：
http://ktgis.net/gcode/lonlatmapping.html

設定ポイント：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/6fce7cbc-0f4f-b61b-ed6a-c67b9787e083.png)

表示を押すと、下記のような画面が表示されます。ちょっと怖いですねｗ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/30dc2010-283b-c6ca-86ec-18afff1caae6.png)

調べたいポイントまで画像を拡大し、マウスを当てるとid_nameが見れるので、自分が知りたい場所の近くのidを取得してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/191429/23139a21-6b9b-6446-8aca-7eca499342e0.png)

#まとめ
はじめはお天気API関連の記事を書こうと考えましたが、他の方が書いた記事が充実していたので、別の視点からの記事ということで、今回の記事になりました。
今回、改めて正規表現は便利だなと思いました。
使い方などを一応抑えておくとサービスを使った方法を探すより早い場合があるなと感じました。
rails consoleでcase文が期待通りに動かない理由

# 経緯

こんなcase文があるとします。
前提として、case文では渡されたオブジェクトとwhenに書かれているオブジェクトを `===` で評価します。

[caseで変数のクラスを比較しようとすると上手く行かない](https://ja.stackoverflow.com/questions/4596/case%E3%81%A7%E5%A4%89%E6%95%B0%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E6%AF%94%E8%BC%83%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8%E4%B8%8A%E6%89%8B%E3%81%8F%E8%A1%8C%E3%81%8B%E3%81%AA%E3%81%84)

```checker.rb
class Checker
  def check(object)
    case object
    when Book
      puts "これはBookです"
    else
      puts "わかりません"
    end
  end
end
```

今回使用するBookクラスはこんな感じだとします。


```app/models/book.rb
# == Schema Information
#
# Table name: books
#
#  id              :integer          not null, primary key
#  created_at      :datetime
#  updated_at      :datetime
#

class Book < ApplicationRecord
end
```

そして、次のコマンドをrails consoleで実行していたとします。
僕はpryを使っています。

```ruby
$ rails console

checker = Checker.new
book = Book.first
checker.check(book)
# これはBookです
```

そのあと、consoleでゴニョゴニョしていると突然先ほどの処理が期待通りに動かなくなりました。

```ruby
checker = Checker.new
checker.check(book)
# わかりません
checker.check(book)
# わかりません
checker.check(book)
# わかりません

```

なんでやねん！

# 原因

原因は至ってシンプルで、consoleにいるときにファイルを編集した際に **リロードしてしまったために、Bookクラスの#object_idが変わってしまった** ためでした。

# 調査

こんな調査をしました。

まず、Bookクラスが読み込まれたらputsでわかるようにします。

```book.rb
class Book
  puts "Bookを読み込みました"
end
```

rails consoleを実行すると、まずBookクラスが読み込まれるので、putsが出力されます。

```ruby
$ rails console
# Bookを読み込みました
```

次に、先ほどの処理を実行します。この時、

```ruby
checker = Checker.new
book = Book.first
checker.check(book)
# これはBookです

# object_idは同じ
book.class.object_id
=> 70296714581660
Book.object_id
=> 70296714581660

# 同一のオブジェクト
book.class == Book
=> true
```

しかし、この流れでリロードを実行すると、状況が変わります。

```ruby
reload!
# Reloading...
=> true

# checker.rbを変更したからもう一回読み込むと想定
checker = Checker.new

checker.check(book)
# Bookを読み込みました
# わかりません

# object_idが違う
book.class.object_id
=> 70296714581660
Book.object_id
=> 70296942109640

# 同一のオブジェクトではなくなっている
book.class == Book
=> false
```

当たり前と言えば当たり前ですが、reload!を実行すると、その後Bookを呼んだタイミングで読み込まれるので仕込んだ `Bookを読み込みました` が出力されます。そうすると、rubyの#object_idが変わってしまうために、見かけ上では一緒でも、同一のオブジェクトとして認識されないということでした。
アニメーション#1　円が広がり、点滅しながら消滅する

上手くペーストできなかったので、スクリーンショットになってます;;

![スクリーンショット 2018-06-29 17.53.32.png](https://qiita-image-store.s3.amazonaws.com/0/263583/2945aa76-47e7-836a-26f3-b02b34fa21ff.png)
![スクリーンショット 2018-06-29 17.53.46.png](https://qiita-image-store.s3.amazonaws.com/0/263583/f8cbab0b-064f-1d3b-1090-992419e8b229.png)
Power BI Desktop 空のクエリを使った Azure AD 認証の活用

本日 PowerBI Desktop から Microsoft Graph に接続しようとした際、コネクターがないため自分で認証を書く必要がありました。その覚書。

情報元: [Error getting OData from Microsoft Graph: Access to the resource is forbidden](https://community.powerbi.com/t5/Issues/Error-getting-OData-from-Microsoft-Graph-Access-to-the-resource/idi-p/430087)

# Azure AD へのアプリケーション登録

[Microsoft Graph を使ってみよう : Azure AD v1 エンドポイントのアプリケーション認証を ADAL で行う](https://qiita.com/kenakamu/items/1e4557dfcedeebe78e88) を参考に Azure AD に Microsoft Graph が使えるアプリケーションを登録し、以下を取得。

- アプリケーション ID
- クライアントシークレット

# Power BI Desktop で接続を作成

1\. Power BI Desktop を起動。

2\. 「クエリを編集」をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/2626220a-bc4b-f170-7813-66d25f8fc354.png)

3\. 「新しいソース」より「空のソース」をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/955218ea-1436-2521-947f-651a22079b0b.png)

4\. 「詳細エディター」をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/2260574a-1a06-1217-4e12-326ca2102be7.png)

5\. クエリに以下内容を張り付け。`tenant_name` および `client_id` と `client_secret` を実際の値に更新。

```
let
    TokenResponse = Json.Document(Web.Contents("https://login.windows.net/<tenant_name>/oauth2/token", 
	[
	Content = Text.ToBinary(Uri.BuildQueryString([
            client_id = #"Azure Application Id", 
            resource = "https://graph.microsoft.com", 
            grant_type = "client_credentials", 
            client_secret = #"Azure Application Client Secret"
        ])), 
	Headers = [Accept = "application/json"], ManualStatusHandling = {400}
        ]
    )),
    AzureAccessToken = TokenResponse[access_token]
in
    AzureAccessToken
```

6\. クエリの名前を AzureAccessToken に変更。これでアクセストークンが取れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/d7dc3800-bace-e530-2954-630239d0f011.png)

7\. 次に実際のクエリに追加。空のクエリをもう一つ追加し、「詳細エディター」をクリック。以下をクエリとして追加。ここではユーザーの一覧を取得するクエリを利用。Authorization ヘッダーには先ほど作成したクエリを指定。

```
let
    Users = OData.Feed("https://graph.microsoft.com/v1.0/users", [Authorization = "Bearer " & AzureAccessToken])
in
    Users
```
8\. 「完了」をクリックした際に資格を求められた場合は、「視覚情報の編集」をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/9fb3ff4c-f661-58d2-981c-f0fd6b38e835.png)

9\. 匿名で接続。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/742bbc42-df4c-6273-6668-5c982f050ac7.png)

尚、この時点で以下のエラーが出る場合は、設定の変更が必要。

Formula.Firewall: クエリ 'クエリ1' (ステップ 'Users') は他のクエリまたはステップを参照しているため、データ ソースに直接アクセスできません。このデータの組み合わせを再構築してください。

# Power BI Desktop 設定の変更

1\. File より、オプションと設定 | オプションをクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/3eb2fbf6-30fe-a476-8960-12552cecd68b.png)

2\. 「現在のファイル」の「プライバシー」より、二つ目のオプションを選択し「OK」。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/c53c5c03-8e0e-6778-873e-176566a08a8f.png)

3\. 「プレビューの更新」をクリックしてデータ取得を確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214116/5153d276-af4c-1ba3-fd19-bddd0bbc40f6.png)

# まとめ

そのうち Microsoft Graph 用のコネクタが出ると思いますが、一旦はこちらで回避できます。尚、トークンは都度取得する必要があります。
Apigee を使ってみるの巻

#目的
私達は、マイクロサービス化をシンプルかつセキュアに行う、、、ために
Apigee で使われている言葉を理解する

#目標1
私が、Apigee 語で迷わないようになる
ex.Apigee とは
ex.Apigee の主な構成要素とは

#目標2
Apigee で、yahoo ニュースのプロキシーを作成


#成果イメージ
API をセキュアに運用するための知識を得て、Apigee の単語で悩まなくなる
yahoo ニュースプロキシーを作成する

#利用の仕方
[セールス向け] apigee 管理のデモを見せる
[プログラマ向け] 自身のプログラムをAPI として公開するための筋トレ
[サーバエンジニア向け] マイクロサービスとして、API 連携の仕方やさせ方を確認



#勉強
日本語のドキュメントが無いので、下を参照するしかないです！ですっ！！！
https://docs.apigee.com/api-platform/get-started/get-started

Qiita に素晴らしい記事を発見したので共有
https://qiita.com/komikoni/items/088f67007395d84b8962

構築は、こちらのサイトを参照
https://qiita.com/snomoto/items/3a68d5127e703505b23f


##API Proxy
Apigee Edge(Apigee 社のAPI platform Service の名称。タイトルも正しくは、Apigee ではなく、Apigee Edge だけど、いいやろの精神)における最頻出の言葉。

>API proxy is your interface to developers that want to use your backend services. Rather than having them consume those services directly, they access an Edge API proxy that you create. With a proxy, you can provide value-added features such as:
Security
Rate limiting
Quotas
Caching & persistence
Analytics
Transformations
CORS
Fault handling
And so much more...

API プロキシーは、開発者とのインターフェース。あなたのバックエンドサービスを使いたい人向け。
サービスは、直接バックエンドサービスへアクセスせず、Edge API proxy へアクセスするようになります。
Proxy を経由することで、セキュリティ強化や高速化が望めます。

##Reverse proxy
Proxy タイプの選択肢の一つ。
百貨店のコンサルタントのように、一つの問合せ先で、色々なサービスを返答する。
認証や負荷分散に利用される。
![WS000008.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/b77dc2f1-cdc7-8014-084d-b7db13e8c603.jpeg)


##OAuth 2.0
ユーザが、安全で便利にアプリケーションを認可する仕組み。
ユーザは、ID/PW といった公開したくない情報を使わず、毎回の認証も代理させれる。
![WS000009.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/4038f5b3-e201-6ebc-c4c2-0bbf4283afd8.jpeg)



#やってみるの巻
下のサイトへアクセス
https://enterprise.apigee.com/platform/

APIs > API Proxies
![WS000000.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/badfe2da-0cb4-e0e4-ffa3-3c5ff75d6571.jpeg)

+API Proxy

Build a Proxy ページにて、プロキシータイプを選択する。
![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/163adfb0-87df-afa8-3e10-bd6095d129a6.jpeg)
今回は、Reverse Proxy を選択。
詳しくは、##Reverse proxy にて。


各情報を入力。私は下の情報で試験中
Existing API へyahoo news のURL を入れること。
https://news.yahoo.co.jp/
![WS000011.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/6c3b091b-6ba7-e643-6314-8c48337daf87.jpeg)


セキュリティ
Pass through (none) を選択
![WS000012.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/391df973-947d-0b86-21ff-93ae34b19cfe.jpeg)

VirtualHosts
デフォルトとセキュアの２つが選べる。基本は、google がhttps 以外のサイトに危険だよ！とブラウザから警告がでるようになってるため、セキュアは選ぼう。
　・デフォルト　：http　ベース
　・セキュア　　：https ベース


下の図では、デフォルトも選択。
![WS000015.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/3e430489-cf5f-66d5-8a03-f3f2fe6a00f1.jpeg)


Build
今回は、test 環境へデプロイ。
![WS000017.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/61e845c8-21ff-8755-b8b1-03329e4394d2.jpeg)


構築中、、、
![WS000020.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/fb6d6418-9d89-ea61-b1aa-157206b82539.jpeg)
プロキシー名(図では"ahoonewstest")のリンクをクリック

プロキシーのテスト
![WS000021.JPG](https://qiita-image-store.s3.amazonaws.com/0/184724/b58f09d7-a19a-2736-5fbe-d26486dcf35a.jpeg)
図のURL をクリック
yahoo news が表示されることを確認する


私の作ったヤフーニュースプロキシーは、下の通り。
※近いうちに消します
http://h1d34h4t-eval-test.apigee.net/yahoonewstest
System.Net.Http.HttpClientで証明書のホスト名と実際のホスト名が異なる場合のエラーを回避

# はじめに

C#の`System.Net.Http.HttpClient`で自己署名証明書で適当に作ったサーバーに接続したらエラーになったのでこれを回避する方法を探してみた。
古い情報だと、`WebRequest`とか使ってるときに`ServicePointManager.ServerCertificateValidationCallback`を指定すればいいみたいな記事が多いんだけど、`System.Net.Http.HttpClient`を使ってるとこの手は使えないみたい。
で、よくよく調べてみると別の方法で回避するようなので残しておきます。

# 環境

* Windows 10 1803
* .Net Core 2.1

# 回避方法
要は`HttpClient`作成時に`HttpClientHandler`を渡すんですが、そのときにコールバックを設定しておくということ。

```C#
    var handler = new HttpClientHandler() {
        ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
        {
            switch (sslPolicyErrors)
            {
                case SslPolicyErrors.None:
                case SslPolicyErrors.RemoteCertificateNameMismatch:
                    return true;
                default:
                    return false ;
            }
        }
    };

    using (HttpClient client = new HttpClient(handler))
    {
        .....
    }
```

いくつか参考になったサイトはあったけど、コールバックで単純に`true`を返している例が多いので、もうちょっとちゃんとエラーを見て、その他のエラーはハンドルしないようにしてみました。

ちなみに、通常のサーバーに接続するときはちゃんと名前をチェックして無視しない方が安全です。ホスト名が変わったりするときなどにやむを得ず回避する場合に限って使いましょう。

(追記：2018/7/9)
sslPolicyErrorsはフラグなので、上記サンプルではエラーが組み合わせになった場合正しくハンドルできません。なので、そこはそこできちんと実装してくださいな。
laravelのクエリビルダでinvalid input syntax for type timestampメモ

#where句を使うときは種類がいっぱいあるのを知らなかった
- laravelのクエリビルダを利用してDBへアクセスした際に`invalid input syntax for type timestamp`がでてしまった。
- sqlを直書きすれば返ってくる。
- 全部`where`で繋いでいた。
- カラム同士を比較した際には`whereColumn`を使用しなければならなかった。
- timestamp型のカラムの比較を、`whereColumn`ではなく`where`で行うと`invalid input syntax for type timestamp`のエラーが返ってくる。
   - ```where('DB1.time', '<', 'DB2.time')```のようなことをやるとエラーが返ってくる。
  - DB1.timeが文字列型だとエラーは吐かれないが`'DB2.time'`という文字列を探しにいく

※間違いがあったら教えてください
CentOS7を立てたときにいつも見るようなリンクまとめ

## はじめに
検証等でCentOS7を稀にイチからセッティングするので良くやる作業を想定してリンクにまとめてみた。
検証用なので本番環境では推奨されないような内容もあるかもしれないので注意が必要。

##ネットワーク設定
[ネットワークの設定を変更](https://www.linuxmaster.jp/linux_blog/2011/06/linux-7.html)

##ルーティング
[静的ルーティングの設定 - Linux](https://qiita.com/kooohei/items/b0931ae210911cc52adc)

##PROXY設定
[LinuxでのプロキシとDNSの設定 - 超ウィザード級ハッカーのたのしみ](http://fj.hatenablog.jp/entry/2014/08/20/204554)

<!--
##iptables
http://te2u.hatenablog.jp/entry/2013/09/12/215031
-->
##インターフェース追加
[CentOS 7 NIC デバイス追加](http://server.etutsplus.com/centos-7-add-a-network-interface-card/)

##firewalld関連
[CentOS7 firewalldの設定](http://www.unix-power.net/networking/post-680)
[CentOS7でポートを開放する方法。 - プログラミングで飯を食え。腕をあげたきゃ備忘録！](http://senoway.hatenablog.com/entry/2015/02/11/142139)
[CentOS 7 firewalld よく使うコマンド](https://qiita.com/kenjjiijjii/items/1057af2dddc34022b09e)

##プロキシ関連
[[Linux] wgetをプロキシ経由で実行する方法](https://qiita.com/nutti/items/4ed09d3d61ccad49069b)

##python3系インストール(yum install)
[CentOS6にPython3入れる](https://qiita.com/f-akazawa/items/5ec741f8a5cca999d7b3)
※CentOS6用だけど7でも同じだった(はず)

## yum update upgrade の違い
[yum update と yum upgradeの違い（ついでにDebianも）](https://qiita.com/mokrai/items/4e0597505097538b6e2c)

##samba
[CentOS7にSambaをインストール | 俺的備忘録 ～なんかいろいろ～](https://orebibou.com/2014/12/centos7%E3%81%ABsamba%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)

##初期設定まとめ
[CentOS 7.3 (1611)の初期設定 - よくわからないエンジニア](http://www.unknownengineer.net/entry/2016/12/26/123104)

##DNSサーバ
[CentOS 7: bindをインストールして内部ネットワーク向けにDNSサーバを立ち上げる - Narrow Escape](https://www.hiroom2.com/2016/05/02/centos-7%E3%81%ABbind%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6%E5%86%85%E9%83%A8%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%90%91%E3%81%91%E3%81%ABdns%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92%E3%82%8B/)

##syslog関連
[CentOS 7のロク゛管理「journald」 | Think IT（シンクイット）](https://thinkit.co.jp/story/2014/12/18/5389)

##メール
[メールサーバー構築手順（Postfix / Dovecot）初心者でもできるメモ](https://genchan.net/it/server/1566/)
(このままメールサーバ立てるとセキュリティ的にダメっぽいけど、メール関連プロトコルの勉強としてはOK)

##NTP
[NTPサーバー構築](https://centossrv.com/chrony.shtml)

##Radius
[CentOS7 に FreeRadius をインストールする - らくがきちょう](http://sig9.hatenablog.com/entry/2016/10/20/120000)

##telnet
[CentOS7 に Telnet サーバをインストールする - らくがきちょう](http://sig9.hatenablog.com/entry/2017/10/17/000000)
CentOS7にはtelnetが組み込まれていない場合があるのでyum installする必要がある。
※一応メールサーバとかWebサーバとかのサービス突っつく用

##SNMP
[技術的備忘録日記: snmptrapの設定について](http://ssksn1.blogspot.com/2008/05/snmptrap.html)

##Cacti
[CentOS7 Cacti1.1.xのインストールと基本設定](https://www.unix-power.net/networking/post-726)

##自己署名証明書
[SSLを利用するための自己証明書（オレオレ証明書）の設定メモ](https://qiita.com/clown0082/items/551d7c081ff6b41b1717)
[秘密鍵のパスフレーズを解除する](https://rms-digicert.ne.jp/howto/basis/decrypt_key.html)
(2つ目は復号化について)

##証明書情報の取得
[SSL証明書ペア確認コマンド | インフラ | DoRuby](https://doruby.jp/users/nyan_blog/entries/SSL_)
データフレームの基本

Rでデータフレームの使い方を忘れてしまいがちなので、備忘がてら書き連ねみます。

##行番号と列番号を指定して値を取る。
　例：1行目、3列目の値を表示する。

```
　x[1,3]
```

##データフレームの基本統計量を出す。
```
 　summary(x)
```

##データフレームの項目構成を見る。
```
　str(x)
```

##データフレームの特定の行だけを表示する。
　例：10行目を表示する。

```
　x[10,]
```

##データフレームの特定の列だけを表示する。
　例：10列目を表示する。

```
　x[,10］
```

##データフレームの特定の複数行を表示する。
例：1行目、3行目、5行目を表示する。

```
　x[c(1,3,5),]
```

##データフレームの特定の複数列を表示する。
例：5列目、10列目、18列目を表示する。

```
　x[,c(5,10,18)]
```

##データフレームの最初の数行を表示する。
```
　head(x)
```

##データフレームの最初の10行を表示する
```
　head(x,10)
```

##データフレームの最後の数行を表示する。
```
　tail(x)
```

##データフレームの最後20行を表示する
```
 　tail(x,20)
```

##データフレームから特定の行を削除する
　例：1行目を削除する

```
    x[c(-1),]
```

##データフレームから特定の列を削除する
　例：1列目を削除する

```
    x[,c(-1)]
```

##データフレームから条件に合致するレコードを抽出する。(数値データの場合)
　例：年齢(列名はage)が30以上のレコードを抽出

```
　subset(x,age>=30)
```

##データフレームから条件に合致するレコードを抽出する。(文字データの場合)
　例：住居(列名はrestype)がSDUのレコードを抽出

```
　subset(x,grepl("SDU",x$restype))
```

##データフレームの列名を表示する
```
　names(x)
```

##データフレームのNA値をゼロに変換する
```
　x[is.na(x)]<-0
```

#まとめ
まだありそうなので、ぶつかりしだい更新していきます。
GPU環境のセットアップ

業務でGPUサーバのセットアップを行なっていて色々詰まっているのでメモをまとめていこうと思う。
NVIDIA-DRIVERのインストールが終わってnvidai-dockerも動いたのでchainerを動かそうとしたらcuDNN関連で詰まってしまったのでその時のメモ。

## 環境情報
- Ubuntu 16.04.4 LTS
- nvidia-driver 390.67 
- CUDA 9.1
- Python3.5.2

## つまったところ
chainerでGPUを使って学習をしようとすると以下のエラーが出た。
`CUDNN_STATUS_NOT_INITIALIZED`

## 解決方法
cupyのインストールをミスっていたようである。
もともと以下の方法でcupyをインストールしていた。
`pip install cupy`
これを改めて以下の方法でインストールするとエラーが出なくなった。
`pip install cupy-cuda91`
もちろん改めてインストールする際は既存のcupyをアンインストールしてから行なった。
`pip uninstall cupy`

## 考察
chainerの公式サイトの以下のNoteを参考に解決した。pipでcupyを入れる時は`cupy`ではなく`cupy-cudaXX`でCUDAのバージョンにあったものを入れないとダメみたい。

>Note. If you are using a wheel, cupy shall be replaced with cupy-cudaXX (where XX is a CUDA version number).
https://docs-cupy.chainer.org/en/latest/install.html#run-cupy-with-docker

- `pip install cupy-cudaXX`でインストールすると最新版のcuDNNとNCCLがインストールされる。
- `pip install cupy`でcupyをいれるとcuDNNとNCCLがインストールされないので手動でインストールする必要がある。
- cuDNNとNCCLのバージョンを個別に選びたい場合は`pip install cupy`を使う。

cuDNNがインストールされていなかったから上記のエラーが出ていたみたい。
notfound

VagrantでCentOS7の環境を新しく作って、
PHPやらApacheやらComposerやら色々導入して、Laravelで遊ぼうとしたときのこと。

とりあえず、http://<address>/<project_name>/public/ で初期画面見れてほっこり。

このとき、初期画面が見れるのは、routes/web.php に
こんな感じでルーティングが設定されているからですよね。

Route::get('/', function () {
    return view('welcome');
});
ただ、今回起こったことは、
下みたいに、ルーティングを追加したときに Not Found が表示されました。 fugaだろうがfooだろうが全部 Not Found。

Route::get('/hoge', function () {
    return 'Hello World';
});
/ でルーティングしたものは表示されてそれ以外はNot foundなもんで、
プロジェクト側の設定ミスか何かなのかな〜と思ってたらApache側でしたね。

httpd.confの中身を覗いてみると、

<Directory "/var/www">
    AllowOverride None
    Require all granted
</Directory>
~
~
<Directory "/var/www/html">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride All

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>
<Directory "/var/www"></Directory> と
<Directory "/var/www/html"></Directory> の中の AllowOverride がNoneになってますが、
ここが原因だったみたいです。 それぞれ AllowOverride All に直して、Apacheを再起動してあげましょう。

$ systemctl restart httpd
これでルーティング上手く行きました。
laravel apach centos 

---
laravel apach centos 
tags: mamp Apach
author: benchan
slide: false
---

※バージョンによって多少パス等違うかも

　
php7をapacheで利用する場合には、以下のモジュール設定を追加する必要がある。

```/etc/httpd/conf/httpd.conf
<IfModule prefork.c>
  #LoadModule php5_module modules/libphp5.so
  LoadModule php7_module modules/libphp7.so
</IfModule>
```

　
  
   

今回は、/etc/httpd/conf/httpd.confの中にある<Directory "/var/www/html"></Directory>を書き換える。



```/etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
    Options +FollowSymLinks
    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    Require all granted
    AllowOverride All
</Directory>
```

　

/Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

```httpd-vhosts.conf
NameVirtualHost *:443

<VirtualHost *:443>
    ServerAdmin admin@localhost
    DocumentRoot "/Documents/localhost"
    ServerName localhost

    SSLEngine on
    SSLCertificateFile /Applications/MAMP/conf/apache/ssl/localhost.crt
    SSLCertificateKeyFile /Applications/MAMP/conf/apache/ssl/localhost.key

</VirtualHost>
```
　これで編集は完了するので、再度systemctl restart httpd.serviceコマンドを実行する。



###うまくいかない時に

Laravelのプロジェクトでは[project-name]/public/配下をDocumentRootに設定する必要がある。



```composer create-project --prefer-dist laravel/laravel [project-name]
   chown -R apache:apache [project-name]
   chmod -R 777 [project-name]
```
結局scriptをどこで読み込むのかが正解なのか

何気なく読み込んでいるscriptタグ。
なぜその場所で読み込んでいるのか説明できますか？
高速化について調べている時に改めて調べ直したのでメモメモ。

## 読み込む場所候補
以下の３箇所のうちscriptタグの読み込みに最も適した読み込み場所でしょうか？

![script書き出し場所.png](https://qiita-image-store.s3.amazonaws.com/0/237008/9a7f8419-b85d-8c6c-3d82-3fe01665624e.png)


①``<body>``タグの内のどこか
②``<body>``タグの閉じタグ直前
③``<head>``タグ内のどこか

## 答え合わせ
①昔よく選ばれていた場所。コンテンツと混在してしまうので保守性や可読性が良くなく、
例外を除いては使わない方が良い書き方。（例外：外部ウィジェットの埋め込み等）

②サイトの高速化を考えた場合に選ばれる場所。スクリプトが読み込まれている間は以降の
描写がされないため、可能な限りコードの後ろで読み込む方がサイトの表示速度が早くなる。
問題がなければ基本選びたい書き方。

③他のスクリプトで呼ばれる関数がある場合はそのスクリプトより前に読み込まれている必要がある。
つまりbody要素のどこかで呼ばれるスクリプトから関数が参照される場合は事前に読み込まれている必要があるためheadタグの中で読み込む。

## つまり…
基本は②の場所で読み込み、先に読み込む必要がある場合は③を指定する。
外部ウィジェット等のどうしても①で読み込まないといけない例外以外は①で読み込ませない。