OmniAICreator/Qiita-1.07M huggingface dataset:
【R】RとR Studioのインストール手順

## 1:記事内容
- 統計解析ツール「R」とRをより使いやすくした統合開発環境（IDE）の「R Studio」のインストール手順
- WIndows向けに記載しているため、Macの方は以下の記事を参考にしてください

[R と R Studioのインストール](https://qiita.com/hujuu/items/ddd66ae8e6f3f989f2c0)

## 2:Rってどんな言語？
- 統計解析向けのオープンソースのプログラミング言語
- 基礎統計の確認のみならず、グラフ化やデータ前処理のパッケージも充実
- ビジネス上のデータを使用して、レポート集計や探索的な分析をする上で便利

### 参考：Excelとの比較
![RとExcelの比較.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/249b01eb-7297-1258-43ce-d1a14353af02.png)

[出典：Rで入門！仕事で使える統計学資料](https://speakerdeck.com/hujuu/r-and-rstudioru-men?slide=6)

### Rのメリット
- 処理速度が優れているため、大量データを分析する際は効率的
- Excelでは扱えない統計解析ができる
  - クラスター分析
  - 重回帰分析
    - モデル作成に加え変数選択や多重共線性の確認など
- グラフの描画に強い
  - ggplot2は自由度が高く、視認性が高いデザイン
  - 散布図で、3要素以上の描画などもサクッとできる
#### グラフ例


### R Studioとは？
- いわゆるRのIDE（統合開発環境）
- 無料
- コーディング中の入力補助が強い
  - 関数や代数などの補完が便利
- コードの管理やアウトプットの管理がしやすい
  - グラフのサイズ調整やクリップボードへのコピー、pngへの書き出しなどが簡単にできる
 
#### R StudioのUI
![rstudio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/cde62426-f0c4-c47d-802e-5299d66a8e19.png)




## 3:インストール手順
- （2020年5月15日時点）以下の手順でWindows10 Proであれば問題なくインストールできました
- Rをインストールし、後にR Studioをインストールします

### 3.1:Rをインストール
#### ①ダウンロードサイトにいく
RはCRAN（Comprehensive R Archive Network）からダウンロードします。日本では、以下のミラーサイトからダウンロードするとよいでしょう。
[統計数理研究所のCRANミラーサイト](https://cran.ism.ac.jp/)


#### ②以下の流れに沿って進める
以下の手順でダウンロードを進めてください
![②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/40f9bc34-815f-7007-fbae-888cbb704116.png)
![③.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/ab0e44a1-d0a4-fccb-3f50-9784c0950e67.png)
![④.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/81f201da-d7a3-01d1-1bbd-1b7b4f7d1b4d.png)
![⑥.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/2d098c01-7c49-578d-c6a4-754ebb47c360.png)


#### ③ダウンロードが完了すればOK
![⑦.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/b9a64568-844a-fb02-35ac-f5a3502a0d85.png)


### 3.2:R Studsioをインストール
#### ①R Studio公式サイトにいく

[R Studio公式サイト](https://rstudio.com/products/rstudio/download/#download)にいく



#### ②以下の流れに沿って進める
でっかい青いボタンを押してダウンロードして、実行する。
![②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/e481355d-4d3b-7f9c-b072-e4a354ce98d3.png)
![③.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/128c49c6-cf68-abba-0c50-13f0e843b429.png)
![④.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/e78ad80d-b4fe-b2d5-ed1e-28adc9cf5009.png)


#### ③ダウンロードが完了すればOK
![⑤.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631817/7123994f-c7c3-0dda-f5b9-96bd49591293.png)


## 4:確認
- キーワードのウィンドウズボタンを押下→Rと入力してR studioを開く
- R Studioが立ち上がれば完了です


## 参考にした記事
[R初心者の館（RとRStudioのインストール、初期設定、基本的な記法など）](https://das-kino.hatenablog.com/entry/2019/11/07/125044)
[R と R Studioのインストール](https://qiita.com/hujuu/items/ddd66ae8e6f3f989f2c0)
プログラミング学習を始めてから9ヶ月間の学習履歴

2019年8月からプログラミングの学習を始めて、9ヶ月が経ちました。
せっかくなので、今まで学習してきたことをまとめようと思います。

#2019年8月-9月
会社の研修でJavaを学習し始める。
ある企業の講師が会社に来て、プログラミングを教えてくれました。

学んだことは次の通りです。
・Javaの基本文法
・jsp/Servlet
・JDBC

#2019年10月-11月
会社の研修でチーム開発を行いました。
架空の物流会社のシステムを6人で開発しました。

実装したことは次の通りです。
・ログイン/ログアウト
・従業員検索/製品検索
・注文登録
・注文内容照会

#2019年11月20日
Oracle Certified Java Programmer, Silver SE 11を取得しました。
Goldを2020年3月頃受けようと思っていたのですが、Silver 11では、Gold 8を受けることができないことを知りました。。。
SE 11の参考書がまだ出ておらず、受験を延期しました。

#2019年12月
ここから趣味で開発し始めました。
最初に開発したウェブサイトは、家計簿です。
[詳しくはこちら！](https://qiita.com/dumbbell/items/d3bae8444df86ab7cedc)

言語：Java

実装したことは次の通りです。
・ログインログアウト
・使った金額と内容、分類を登録
・月別に合計金額やその内訳など表示
・メールアドレスを指定して該当月の出費を送付

#2020年1月前半
趣味レベルでは、簡単なウェブサイトを開発できるようになったので、フレームワーク（Spring）を勉強することにしました。
Udemyで次の講座を購入し、勉強しました。
[Spring 入門 ～ SpringBoot 2 を使ってお問い合わせアプリとToDoアプリを作る ～](https://www.udemy.com/course/java_spring_beginner/)


#2020年1月後半
Springを学んでいる時に、友人にラーメン屋レビューサイト欲しい、と言われたので、開発しました。
[詳しくはこちら！](https://qiita.com/dumbbell/items/31acaab81484b5545ee3)

言語：Java（Spring）

#2020年2月
DUO 3.0という英単語帳の学習サイトを開発しました。
[詳しくはこちら](https://qiita.com/dumbbell/items/544ac2a941896f17a061)

言語：JavaScript

#2020年3月-4月前半
JavaScriptの学習を本格的に始めました。
ドットインストールの有料会員になり、JavaScript関連の動画は全て見ました。
少しずつJavaScriptが分かるようになり、自分なりにウェブアプリを開発しました。

例えば、
[茨城県におけるコロナウイルス感染動向を作ってみた。](https://qiita.com/dumbbell/items/d80fac63cf2b5b898cd8)
[映画情報を取得するAPIを使って上映中の映画と評価の高い映画の一覧を表示してみた。](https://qiita.com/dumbbell/items/c57084cc3e123ad5af13)

#2020年4月後半
JavaScriptが少しずつ分かってきたので、Reactに手を出してみました。
Udemyで次の講座を購入し、学習しました。
[React + Redux を使用したモダンフロントエンド開発](https://www.udemy.com/course/react-redux-basic/?start=315)

基礎はなんとなく分かったので、自分なりに次のウェブサービスを開発してみました。
[React + Reduxを学習し始めた初心者の成果物](https://qiita.com/dumbbell/items/a312fd8a5d9f84fb0e94)

#2020年5月
実際に手を動かすだけでなく、コードの書き方やウェブが動く仕組み、などについて学習する必要性を感じたため、次の本を読みました。

[リーダブルコード](https://www.amazon.co.jp/dp/4873115655/ref=cm_sw_em_r_mt_dp_U_.uiWEb895HY0M)
[Webを支える技術 -HTTP、URI、HTML、そしてREST ](https://www.amazon.co.jp/dp/4774142042/ref=cm_sw_em_r_mt_dp_U_4viWEb72XHN4A)

２冊とも名著というだけあって、もっと早く読んでおけば良かった、、、というのが正直な感想でした。
まだ読んだことない方がいらっしゃいましたら、ぜひ読んでみてください！

今は、[プログラマの数学](https://www.amazon.co.jp/dp/4797395451/ref=cm_sw_em_r_mt_dp_U_wxiWEb2RSBFM2)を読んでいます。

#まとめ
これまで、Udemyやドットインストールでインプットし、自分なりに何か開発することでアウトプットしてきました。
それはやり方として正しかったように思うので、今後も続けていきたいです。

これからは、もっともっと技術書やプログラマにとって名著と呼ばれているような書籍に触れていきます。
最後まで読んでくださり、ありがとうございました。
Ubuntu 18.04 で mono + llvm をmakeしてみる

Ubuntu 18.04 で mono + llvm をmakeしてみる
#目的
Ubuntu 18.04 Ubuntu 18.04 に mono + llvm をsrcからmake & installしてみる
#コンパイル用のパッケージを追加する
<pre>
$ sudo apt install gcc
$ sudo apt install gcc-7-locales gcc-multilib make autoconf automake libtool
  flex bison gcc-doc gcc-7-multilib gcc-7-doc libgcc1-dbg libgomp1-dbglibitm1-dbg
  libatomic1-dbg libasan4-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg libcilkrts5-dbg
  libmpx2-dbg libquadmath0-dbg glibc-doc
$ sudo apt install cmake
$ sudo apt install cmake-doc ninja-build
$ sudo apt install build-essential
</pre>
#ソースをダウンロードする
<pre>
$ git clone git://github.com/mono/llvm.git
$ git clone --recursive git@github.com:mono/mono
</pre>
#LLVMのコンパイル用のdirを作成後コンパイルする
<pre>
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE ../llvm
$ make
$ sudo make install
</pre>
#monoをコンパイルする
<pre>
$ cd mono
$ ./autogen.sh --with-sgen=yes --enable-llvm --with-wasm=yes --with-winaot=yes
$ make
$ sudo make install

$ mono -V
Mono JIT compiler version 6.13.0 
Copyright (C) Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        Interpreter:   yes
        LLVM:          yes(610)
        Suspend:       hybrid
        GC:            sgen (concurrent by default)
</pre>
##テストコード
```c#
using System;

public class HelloWorld
{
    public static void Main(string[] args)
    {
        Console.WriteLine ("Hello World!");
    }
}
```
<pre>
$ csc hello.cs
$ mono hello.exe
Hello World!
</pre>
#参考にしたのは以下のサイト
[mono/mono](https://github.com/mono/mono)
[Mono LLVM](https://www.mono-project.com/docs/advanced/mono-llvm/)
[Building LLVM with CMake](http://llvm.org/docs/CMake.html)
collection_selectの使い方

今回はcollection_selectの使い方について解説です。

#やりたいこと

selectの中身の要素ひとつひとつにidを付与し、nameで表示したい。
こんな感じに。

[![Image from Gyazo](https://i.gyazo.com/71af1978130129ddb8ddc434402be826.jpg)](https://gyazo.com/71af1978130129ddb8ddc434402be826)


#使い方

collection_selectには、オプションやHTML属性等があり、それらを変えることで様々な見た目の変更ができますが、今回は一番オーソドックスな、先頭に”選択してください”という空のオプションを付けてあげたいと思います。

模範はこんな感じです。

```ruby
= f.collection_select カラム名, 要素の配列, value属性の項目, テキストの項目, { prompt: "選択してください" } 
```

実際に使うとこんな感じです。

```ruby
= f.collection_select :prefecture, @prefecture, :id, :name, { prompt: "選択してください" } 

#@prefecture（インスタンス変数）に都道府県の情報をallで入れておく
#要素のvalueでidを付与したいので、value属性の項目箇所は:idにする
#テキストではnameで表示したいので、テキストの項目箇所は:nameにする
```
[![Image from Gyazo](https://i.gyazo.com/4795e1802613b0c5f1b2d288106cad23.png)](https://gyazo.com/4795e1802613b0c5f1b2d288106cad23)


基本的にcollection_selectはactive_hashと並行して使うことが多いです。
active_hashの勉強をしてからcellection_selectを学んだ方が効率はいいかもしれません。

####active_hashに使い方
https://qiita.com/Yu-8chan/items/9f19e2495937f4e36dde

##参考資料
https://railsdoc.com/page/collection_select

以上
駆け出しエンジニアの機械学習メモ その１

#はじめに
「ゼロから作るDeep-Learning」の学習メモその１です。

#忘れがちなスライス操作
* [start:step:stop]で表示する数値の操作を行える。

```java:スライス
x=[1,2,3,4,5]
# 全表示
x[:]
# 1から2まで
x[0:2]
# 1、3、5の2個飛ばし
x[::2]
# 逆順、-2にすると逆から２個飛ばし
x[::-1]
```
# Numpy 形状の一致
* これが分かっていないとデータ前処理ができない

```java:numpy
# 3×2 の形
A = np.array([[1,2], 
              [3,4],
              [5,6]])
# 2×1 の形
B = np.array([7,
              8])
# 内積計算
np.dot(A,B)
>>>array([23,53,83])
```

#ニューラルネットワークの実装(3章)
* Google Colaboratoryを使用しているためGoogleドライブのマウントが必要、これをしなければ別のPythonファイルのインポートができない。

```java:マウント
from google.colab import drive
drive.mount('/content/drive')

cd drive/My Drive/deep-learning-from-scratch-master/ch03
```
* import文、numpy、pickle、別ファイルの関数を呼び出している

```java:neuralnet
# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax
```
* 訓練データと訓練ラベル及びテストデータとテストラベルをmnist.pyより呼び出し格納、ここでx_test,t_testしか呼び出していないのは学習済みのデータを利用して推論処理を行うため。
学習させるためではないので訓練データは使わない。

```java:neuralnet
def get_data():
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test
```
* 「sample_weight.pkl」は学習済み重みデータ、データの中身は辞書型で{W1:,W2:,W3:,b1:,b2:,b3}が入っている。

```java:neuralnet
def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network
```
*「sample_weight.pkl」から呼び出したデータを変数に格納し、モデルに投入、結果はNumpy配列として出てくる。このとき、numpy配列の中で最も大きい数値が予測の数字となる。

```java:neuralnet
def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)

    return y
```
* 変数tにはラベルデータが入っており、if文で予測値と正解ラベルが一致しているか判定している。ここでは、10000枚の画像データ中何枚正解か判定。結果はAccuracy:0.9352となる。

```java:neuralnet
x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
    y = predict(network, x[i])
    p= np.argmax(y) # 最も確率の高い要素のインデックスを取得
    if p == t[i]:
        accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
```

#バッチ処理(3章続き)
* 前項目で記載しているニューラルネットワークは入力層784個、出力層10個のニューロンで構成。784は画像サイズの28×28で10は数字0~9のクラスの分類となっている。隠れ層が2つ、1つ目の隠れ層が50個、2つ目の隠れ層が100個のニューロンを持つ設定となっている。これは学習済みデータである「sample_weight.pkl」の形に合わせている。
* バッチ処理では10000枚ある画像データのうち100枚分のデータをまとめて入力データとすることができる。これにより、処理がはやくなる。
* axis = 1 と書いてある部分は列方向の最大値をとるようにしている。
* np.sum(p == t[i:i+batch_size])では比較演算子(==)でTrueを判定し、個数を算出している。

```java:バッチ処理
x, t = get_data()
network = init_network()

batch_size = 100 # バッチの数
accuracy_cnt = 0

#range(start,stop,step)
for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size]
    y_batch = predict(network, x_batch)
    p = np.argmax(y_batch, axis=1)
    accuracy_cnt += np.sum(p == t[i:i+batch_size])

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
```




#参考
ゼロから作るDeep Learning
VirtualBoxとVagrantを使ってCentOS7を入れる

#手順
1.VirtualBoxとVagrantをインストール
2.仮想マシン用のファルダを作成
3.boxの用意（OSのイメージファイルのようなもの）
4.vagrant init
5.vagrant up



#1.VirtualBoxとVagrantをインストール

VirtualBoxをインストール
https://www.virtualbox.org/wiki/Downloads

Vagrantをインストール
https://www.vagrantup.com/downloads.html

#2.仮想マシン用のフォルダを作成

今回はCentOS7を入れるのでWindows Power Shellで以下のフォルダを作成しました。

```
  C:\Users\ユーザー名\MyVagrant\CentOS7
```

#3.boxの用意（OSのイメージファイルのようなもの）
vagrant Cloud　または　vagrantbox.es　でboxを追加します。

####1.Vagrant Cloud
https://app.vagrantup.com/boxes/search

Vagrant Cloudから入れる場合は以下のコマンドです。

```
$ vagrant box add {名前}
```

####2.Vagrant box.es
http://www.vagrantbox.es/

vagrant box.esから入れる場合は以下のコマンドです。

```
$ vagrant box add {名前} {url}
```



####今回はVagrant CloudのCentOS7のboxを追加するので以下のコマンドを入力します。

```
$ vagrant box add centos/7
```


※vagrant box listで 現在あるboxの一覧が確認でき、centos/7が追加された事が分かります。

```
$ vagrant box list
centos/7          
```

#4.vagrant init
```
$ vagrant init
```
Vagrantfileがフォルダ内に作成されます。

#5.vagrant up
上記コマンドでVagrantが起動され、Virtual Box上にCentOS7が作られます。

#操作コマンド

|コマンド | 機能 |
|:-----------|------------:|
|vagrant init|Vagrantの初期化|
|vagrant box add {名前}|boxの追加|
|vagrant box remove|boxの削除|
|vagrant box list|box一覧の確認|
| vagrant up |仮想マシンの起動 |
| vagrant halt|仮想マシンの停止|
| vagrant suspend|仮想マシンを一時停止 |
| vagrant resume |仮想マシン一時停止からの復帰|
|vagrant ssh|仮想マシンにsshでログイン|
|vagrant status|仮想マシンの起動状態を確認|
|vagrant destroy|仮想マシンを破棄|


#参照元
Vagrantで仮想環境構築入門
https://webbibouroku.com/Blog/Article/vagrant
I18n::InvalidLocale エラー

今回は、I18n::InvalidLocale と言うエラーが出たので私が、解決した方法を記載したいと思う。（ちなみに初投稿
<img width="1431" alt="7c5e5a037cf54512bba567762c953ea8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634795/9f9a0274-a0fa-fb3e-b351-dbcbd41beeb3.png">
###はじめに
この、エラーが出た経緯について説明しよう
今回、投稿日時を日本時間で表示する作業を行った後に、I18n::InvalidLocale in　とエラーが起きました。

こ・れ・は、完全にその作業が怪しいですよね！そして、もう一つこのエラーについてのヒントがターミナルに表示されていました。それが「ActionView::Template::Error (:ja is not a valid locale)」です。これの（）の中身に注目して訳すと。。。「ローカルでJaは有効でありません」となりました。
じゃあ、ローカルにJa（日本語）を有効にしてやればいい！と言うことで解決法です。↓

まず、config/localesに「ja.yml」と新たにファイルを作成してください。
その中に、https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
のGithubに記載されているコードをコピペしてもらえれば解決です。
###参考
ちなみにエラー文のI18nって何？って気になる方もいるかもしれないので参考リンクです。
[railsガイドI18n](https://railsguides.jp/i18n.html)
gitbashのpythonで対話モードに入れない状態からコマンドに戻る方法

#gitbashのpythonで対話モードに入れない状態からコマンドに戻る方法

gitbashでpythonの対話モードに入ろうとして`python`とうつと、対話モードにも入れず、コマンドにも戻れず、そこに居座る状態が続く。

`ctrl+c`、`esc`、`exit()`などでも抜けられず、適当にキーボードで入力してたりEnterを押してると抜けられる。

↓この状態

```
$ python

o

ora

oraora

oraoraora

#抜けられない、、、
```

##pythonから抜ける方法
`スペース＋文字＋Enter`　
これで抜けられる。

**↓「 a」を入力しEnter**

```
$ python
 a
  File "<stdin>", line 1
    a
    ^
IndentationError: unexpected indent

$
```

エラーで抜けてるけど、正しい方法が他にあるのかな？


<br>
##（補足）gitbashでpython対話モードに入る方法
冒頭に`winpty`をつける。コレだけ。

```
$ winpty python
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```


gitbashでpythonの対話モードを使うのであればipythonがおすすめです。

ipythonについては[こちらがご参考](https://qiita.com/yuta-38/items/6d89ea82f1454027b27c)になるかと。
gitbashでpythonの対話モードの使い方

#gitbashでpythonの対話モードの使い方

gitbashでpythonの対話モードに入る方法です。

Windowsのpowershellだとシンプルに`python`と入力すれば対話モードに入るもののgitbashでは入れない。


##winpty
コマンド冒頭に`winpyty`をつける。
　└ `winpty python`これだけでOK

```
$ winpty python
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

対話モードから抜けるときは`exit()`
　└ カッコ必須

```
>>> exit()
```

<br>
##ipython
pythonの対話モードで処理を実行するのであればipythonがおすすめ。
whileやfor文のインデントを自動でつけてくれる。（コードをコピペした場合もインデントが残る）

通常のpythonだとインデントは自分で逐一つけないとエラーになる。


###ipythonのインストール方法

```python:
#ipythonのインストール
pip install ipython

#ipythonの起動
winpty ipython

#起動成功
Python 3.7.4 (default, Aug  9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.8.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:
```

通常のpythonの`>>>`が`In [行番号]:`になる。

対話モードから抜けるときは`exit`または`exit()`
　└ カッコなくてもOK

```
In [1]: exit
```


<br>
###pipとは（補足）
python公式のパッケージ管理システム。pythonの中にデフォルトで入っている。

pythonを使う上ではなにかと便利（というか必須）な機能。

[＞pipの詳細や主要コマンド一覧](https://qiita.com/yuta-38/items/730bf91526f92fe0b41a)



<br>
##ショートカットの作成
毎回`winpty python`や`winpty ipython`と打つのが面倒なので、
エイリアス（ショートカットコマンド）を設定すると、対話モードに入るのが簡単になります。

[＞設定方法はこちら](https://qiita.com/yuta-38/items/8cbc61939029e046753b)

慣れてしまえば設定は簡単で、gitbushを使うなら必須の機能。
【LifeKeeper×Linux】HAクラスター構築後のインタフェースダウンの挙動がおかしい場合

## はじめに
仕事でLifeKeeperの検証～構築手順書への落とし込みを担当しておりました。
今回は、LifeKeeperの検証を行っていた際のトラブルシューティングの内容になります。
LifeKeeper構築後の試験の際にインターフェースダウンの挙動がおかしくなる事象がありました。
こちらの原因と対処について解説していきます。

## 環境

こちらの環境になります。

![図.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/d4b14488-9b0d-d738-bb67-e46b85b1d07f.jpeg)


- HyperVisor(今回は省略)
**vSphere6.7(ESXi6.7)**

- VM(「サーバー」の部分)
**RHEL6.9**

- NIC
**Service用NIC × 1**
**コミュニケーションパス用NIC × 2**

- 共有ディスク/Quorumディスク#1,#2
**VMDK**



## 起きた事象

片系ずつサービスNICを落とした挙動についてテストしました。


**実行したコマンド**

```
# ifdown eth0
```


- **サーバー#1でのインタフェースダウン**

![サーバー#1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/52dd387e-5263-6df8-db61-2532188a4dcd.jpeg)



- **サーバー#2でのインタフェースダウン**

![サーバー#2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/3ad95f25-9bd0-aefc-b0d2-6b40e56d951d.jpeg)


こちらの試験を実施したところ、結果に差異がありました。

サーバー#1のサービスNIC
**→数秒後に自動復旧**

サーバー#2のサービスNIC
**→DOWN状態のまま**

疑問に思ったので調査をしました。


## 原因

**サーバー#2の「NetworkManager」が立ち上がっていた。**
※サーバー1の「NetworkManager」はオフの状態


## 対策

サーバー#2の「NetworkManager」のサービス停止/自動起動停止を実施

```
# service NetworkManager stop
# chkconfig  NetworkManager off
```

再度テストを実施したところ、サーバー#1と同じ挙動であることを確認

## 最後に

いかがでしたでしょうか？
今回、初めてLifeKeeperについての記事を上げました。
LifeKeeperのHAクラスターの設計・構築をしている方に参考になる記事になると思います。

今回の内容はミドルウェア(LifeKeeper)から疑って調査した結果になります。
一つでも参考になれば幸いです。


**よろしければTwitterのフォローも宜しくお願いします！**
https://twitter.com/satton6987

**主にインフラエンジニアのキャリアハックや技術について呟いています。**
hidden_fieldがめちゃめちゃ使える件について

#hidden_fieldってどういう時に使う？？

例えば、メルカリのようなフリマアプリだと、”商品の在庫があるか、売り切れなのか”の判断ができるようにカラムを作成して予めidを付与させておく必要があるよね。

在庫管理のカラムをsituationカラムとして、商品出品時はid=１が付与されて、売り切れになったらid=0が付与されるように判別してみたとします。

こういった予め特定のidを登録時に付与したい時にこのhidden_fieldがお役に立つのです。

#使い方はとても簡単！！

formの中に以下の記述を追記してあげるだけ！

```ruby

= f.hidden_field :situation, value: "1"　#valueで１と指定してあげることで、商品出品時にid=1が付与される
```

以上
pythonでは演算子 ++, --が使えない（phpとの違い）

#pythonでは演算子 ++, --が使えない

phpやJacaScriptで使える、「++」と「--」がpythonでは使えない。
使おうとすると構文エラーになる。


##エラー

```python:
i=0;
while i<5:
   print(i)
   i++

#出力
i++
   ^
SyntaxError: invalid syntax
```

##対処法
`i+=1`, `i-=1`を使う

```python:
i=0;
while i<5:
     print(i)
     i+=1

#出力
0
1
2
3
4

```


| 処理 | python | php | JavaScript |
|:-:|:-:|:-:|:-:|
| i++  | - | ◯ | ◯ |
| i+=1  | ◯ | ◯ | ◯ |
| i=i+1  | ◯ | ◯ | ◯ |
| i--  | - | ◯ | ◯ |
| i-=1  | ◯ | ◯ | ◯ |
| i=i-1  | ◯ | ◯ | ◯ |



<br>
for文でi++使えないのかと思ったら、phpとpythonではfor文の書き方が全然違ったので問題なしでした、、

```python:python
for i in range(5):
    print(i)
```

- pythonのfor文はlistやrangeなど連続したものを一つずつ取り出す。（phpのforeach）
- ステップも特に指定しなければ i++と同じ処理になる。
- phpのfor文は条件が成り立つ間繰り返す。

＞[【python】for文の使い方解説](https://qiita.com/yuta-38/items/d5bea6efdfb948b4e90e)


<br>

```php:php
<?php
for ($i=0; $i<5; $i++){
  echo $i;
} 
?>
```

```php:php(HTMLに埋め込み)
<?php for ($i=0; $i<5; $i++): ?>
  <?php echo $i; ?>
<?php endfor; ?>
} 
```

phpは各処理の後に「;」が必要。
pythonは改行で処理終了とみなす。
WiFiアダプタ - TP-Link AC600 Archer T2U Nano をUbuntuで使用するための設定

- 以下のコマンドを順次実行してドライバをインストール 
`sudo apt install git dkms` 
`git clone https://github.com/jeremyb31/rtl8812au-1.git` 
`cd rtl8812au-1` 
`sudo ./dkms-install.sh` 

- インストール後、アダプタを抜き差しすると、認識しました 
- あとはWiFiの設定すればOK

(参考)
https://askubuntu.com/questions/1149117/tp-link-ac600-archer-t2u-nano-driver-for-ubuntu-18-04/1149288#1149288

(余談)
予め有線LANで上記コマンドを試すことが必要ですが、有線LANの使えない環境だった場合は、別PCから上記ドライバをダウンロードして持ってくるとか、ひと手間必要になります・・・
初心者によるプログラミング学習ログ 318日目

#100日チャレンジの318日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
318日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>318日目 2h<br>・架空LP模写9日目2h（<a href="https://twitter.com/ririru_123?ref_src=twsrc%5Etfw">@ririru_123</a>）<br>・架空LP模写：スキル部分を作成<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1261778819708407808?ref_src=twsrc%5Etfw">May 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
PHPにてPDOでMySQLに接続して、複数のSQLを実行する

1つのPHPファイル内に、INSERTとSELECTのSQLを記載する方法です。
DB接続1回で複数のSQLが実行できます。
2個目のSQLでは配列$dataの値をクリアすることがポイントです。

以下のソースコードは、ユーザーID登録実行画面の想定です。
前画面のユーザーID登録確認画面からユーザー名を受け取り、DB登録しています。

```php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="description" content="XXXX">
  <title>XXXX</title>
  <link rel="stylesheet" href="/main.css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>

<body>
<?php

//データベースの接続エラー対策
try
{
  // POSTメソッドで前の画面の入力値を取得する
  $user_name=$_POST['user_name'];

  //データベースに接続する
  $dsn = 'mysql:dbname=XXXX;host=mysqlXXXX';
  $user = 'XXXX'; //''内にはユーザ名を入力
  $password = 'XXXX';  //''内にはパスワードを入力
  $dbh = new PDO($dsn, $user, $password);
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  //7桁数値をランダムで生成する
  $user_id= rand(100000,9999999);

  //ランダムで生成した7桁数値の存在チェック。$user_idがDBに存在する場合、再度ランダム数値を生成する
  $sql ='SELECT COUNT(*) as cnt FROM XXXX_table WHERE user_id=?';
  $stmt = $dbh->prepare($sql);  // prepareメソッドでSQLをセット
  $data[] = $user_id; // 1つ目の?にセットしたいデータが入っている変数を書く
  $stmt->execute($data);  //executeでDBへの処理要求を実行
  $rec=$stmt->fetch(PDO::FETCH_ASSOC);

  // SQL分を使ってレコードを追加
  $sql ='INSERT INTO place_data_table(place_id) VALUES (?)'; //'INSERT INTO~'を変数$sqlに格納する
  $stmt = $dbh->prepare($sql); // prepareメソッドでSQLをセット
  $data = []; // 配列$dataの値をクリア
  $data[] = $user_id; // 1つ目の?にセットしたいデータが入っている変数を書く
  $stmt->execute($data);  //executeでDBへの処理要求を実行

  // データベースから切断する
  $dbh = null;

  //結果を表示
  print $user_name;
  print 'を追加しました。<br />';

}
catch (Exception $e)
{
  /* ?><pre><?= print_r($e, true); ?></pre><?php デバッグの時にはコメントアウトを外す。エラー内容、問題が発生した行番がわかる*/
  print 'ただいま障害により接続できません。';
  exit(); //強制終了の命令
}
?>

<a href="user_list.php">戻る</a>

</body>
</html>

````
devise導入

#deviseの使い方メモ

gemfileにdeviseというGemを追加。

```ruby:gemfile
  gem 'devise'
```

ターミナル内で該当ディレクトリ（今回はsample）へ移動し、
「bundle install」でGemをインストールしてから、
「rails g devise:install」を実行してdeviseの設定ファイルを作成しましょう。


```ruby:ターミナル
$ cd ~/projects/sample

$ bundle install

$ rails g devise:install
```

**新規作成されるファイル**

- config/initializers/devise.rb
- config/locales/devise.en.yml

ファイルが作成されたのを確認できたら、
deviseのモデル作成用コマンドでUserモデルを作成しましょう。

```ruby:ターミナル
rails g devise user
```
**新規作成されるファイル**

- app/models/user.rb
- db/migrate/20XXXXXXXXXXXX_devise_create_users.rb
- test/fixtures/users.yml
- test/models/user_test.rb

また、route.rbに以下のルーティングが自動的に追記されます。

```rubu:config/routes.rb
  devise_for :users
```

devise_forはユーザー機能に必要なルーティングを一度に生成してくれるdeviseのメソッドです。

usersテーブルにnicknameカラムを追加したい場合はマイグレーションファイルに付け足します。
もしnicknameで検索をかける機能を追加する場合はindexも貼りましょう。

```ruby:マイグレーションファイル
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :nickname,               null: false
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      # 〜省略〜
    end

    #後々、検索機能を実装しnicknameカラムで検索をかける場合は下記も追記する。
    add_index :users, :nickname, unique: true

# 〜省略〜
```

モデルファイルにもきっちりバリデーションをかけておきましょう。

```ruby:app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  validates :nickname, presence: true, uniqueness: true

end
```
そしてターミナルにてマイグレーションを実行します。

```ruby:ターミナル
rails db:migrate
```
deviseを用いてログイン機能を実装した場合のパラメータの受け取り方は通常とは異なります。
ログイン時に送られてくるパラメータを制限するストロングパラメータはdeviseのGem内に記述されているため編集することはできません。
そこでdeviseが提供している「**configure_permitted_parametersメソッド**」を利用してフォームからnicknameカラムの値を受け取れるように許可します。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end
```

これでnicknameカラムに値を送れるように許可できたので、サインアップ画面にニックネームのフォームを追加するためにビューファイルを変更します。
ビューファイルに変更を加えるにはdeviseのコマンドを利用してビューファイルを生成する必要があります。

```ruby:ターミナル
$ rails g devise:views
```

上記の作業でdevise用のビューファイルを生成することができました。
生成されたビューファイルを編集して、サインアップ画面にnickname用のフォームを追加したり、レイアウトを好みに変更していきます。

サインアップ画面は

- **app/views/devise/registrations/new.html.erb**

ログイン画面は

- **app/views/devise/sessions/new.html.erb**

というビューファイルが対応しています。

以上でdeviseの導入の説明は終わります。
TypeScript の特殊な表現メモ

### Omit, & : プロパティを除外・追加

```ts
// X クラスから 'id' と 'createdAt' プロパティを除外
Omit<X, 'id' | 'createdAt'>

// X クラスに 'id' と 'createdAt' プロパティを追加
X & { id: string, createdAt: string }
```

### Exclude, NonNullable, | : 指定のものを除外・追加

```ts
// X から 指定の値 除外
type X = 'A' | 'B' | 'C' | null
type Y = Exckyde<X, 'B' | 'C'> // = 'A' | null
```

```ts
// X から null 除外
type X = 'A' | 'B' | null
type Y = NonNullable<X> // = 'A' | 'B'
```

```ts
// X に指定の値 追加
type X = 'A' | 'B'
type Y = X | 'C' | null // = 'A' | 'B' | 'C' | null
```

### Partial, Required : プロパティをすべて必須/非必須に

```ts
Required<Hoge> // すべて必須
Partial<Hoge> // すべて非必須
```

### [] : クラスのプロパティ

```ts
interface X { // クラスでも可
  aaa: string | null
}

type Y = X['aaa'] // = string | null
```

### Paramters, ReturnType : 関数の引数・戻り値

```ts
function xxx (aaa: string | null, bbb: number): object { ... }

// 最初の引数
type Y = Paramters<typeof xxx>[0] // = string | null

// 戻り値
type Z = ReturnType<typeof xxx> // = object
```
herokuでselenium利用時にクラッシュする場合の解決方法

# herokuでselenium利用時にクラッシュする場合の解決方法
## はじめに
herokuでseleniumを利用する方へ向けた、クラッシュする場合の解決方法を記載しました。

## 発生事象
heroku上でseleniumを実行時に下記のようなエラーが発生しました。

```
Running python manage.py task on ⬢ xxxxx... up, run.9999 (Hobby)
Message: unknown error: session deleted because of page crash
from unknown error: cannot determine loading status
from tab crashed
  (Session info: headless chrome=81.0.4044.129)
```

## 解決方法
調べてみると、メモリ不足によるクラッシュのようです。
そのため、メモリ不足にならないように、seleniumを省メモリ化する対策をとればよさそうです。

### １. seleniumの引数に省メモリ化するための引数をつける

```
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--remote-debugging-port=9222')
driver = webdriver.Chrome(settings.CHROME_PATH, options=options)
```

### 2. 画面サイズをできる限り小さくする
```
driver.set_window_size(950, 800)
```

## 参考
How do I prevent headless Chromium from crashing? - Heroku Help
https://help.heroku.com/DOB4Y0I4/how-do-i-prevent-headless-chromium-from-crashing

Rspecで突然謎のエラーが - Qiita
https://qiita.com/mishitoshi/items/3ca5a9a26ceb7e2cf034

Selenium::WebDriver::Error::NoSuchDriverError - Today I Learned
https://selleo.com/til/posts/mxkjoppuxm-seleniumwebdrivererrornosuchdrivererror
【Kotlin】KClassからClassを取得する3通りの方法

`KClass`には`Class`を返すプロパティとして以下の3種類が定義されています。

- `.java`
- `.javaObjectType`
- `.javaPrimitiveType`

`Kotlin`の`Int`型を例にすると、返却内容は以下のようになります。

|                      |     `.java`     | `.javaObjectType` | `.javaPrimitiveType` |
|:--------------------:|:---------------:|:-----------------:|:--------------------:|
|   **`Int::class`**   | `int.class`     | `Integer.class`   | `int.class`          |
| **`Integer::class`** | `Integer.class` |  `Integer.class`  | `int.class`          |
|      **その他**      |    `*.class`    |     `*.class`     | `null`               |

# どんな時に気にすべきか
プリミティブ型とラッパー型を区別する必要の有無によって使い分ける必要が出るでしょう。
また、「`Class`を要求するような実装でプリミティブ型に対応していない」というパターンを踏んだことが有るので、そういった場合には`.javaObjectType`呼び出しを行う必要が有ります。

# 参考にさせて頂いた記事
- [Kotlin 1\.0 Beta 4の変更点 \- Qiita](https://qiita.com/mattak/items/ba0e3294d539a86f120f#%E3%81%95%E3%82%89%E3%81%AB%E3%83%8F%E3%82%A4%E3%83%A9%E3%82%A4%E3%83%88)
Dockerで用意した開発環境のキャッシュが邪魔で開発が捗らないときに見直すべきこと（Nginx + PHP-FPM）

Dockerで下記のイメージを使用して開発環境を用意しました。

- nginx:latest
- bitnami/php-fpm:latest

キャッシュが効きすぎてしまい、ブラウザキャッシュを削除してもデータが更新されない状態でした。時間計測してみると60秒ごとにファイルを見に行っているような挙動ということがわかりました。このような状況を解決するための備忘録です。

# Nginxが原因ではなかった
Nginxを初めて使ったので、こいつが原因かと思っていましたが間違っていました。
PHP-FPMイメージでデフォルトで有効になっている拡張モジュールが原因でした。

# Zend OPcacheを無効にすればOK
Zend OPcacheというキャッシュ拡張モジュールが働いていたために爆速キャッシュが効いていました。

## Zend OPcacheを無効にする
php.iniの中にある `opcache.enable = 1` という箇所を `opcache.enable = 0` としてサービスを再起動するだけです。

以上でキャッシュが効かない状態で開発が可能となります！
Dart とC言語の連携 : dart:js と dart:ffi の両立 (2) Hello!!


[前回](https://qiita.com/kyorohiro/items/fdb948886923da5d4d75)作成した環境で、Shared Library と JS を作成してみます。

"Hello!!" と表示する C言語の関数を作成して、"Webブラウザー" と "Linux Server "　でその関数を呼び出してみます。


## C言語の関数を作成する。
```c++
:ky.c
#include <stdio.h>

// [Linux]
// find . -name "*.o" | xargs rm
// gcc -Wall -Werror -fpic -I. -c ky.c -o ky.o 
// gcc -shared -o libky.so ky.o

// [Wasm]
// find . -name "*.o" | xargs rm
// find . -name "*.wasm" | xargs rm
// emcc ky.c -o ky.o 
// emcc ky.o -o libky.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s EXPORTED_FUNCTIONS="['_print_hello']"
// cp libky.js ../web/libky.js 
// cp libky.wasm ../web/libky.wasm
void print_hello() {
    printf("Hello!!\n");
}
```


## Shared Library を作成する

```bash
$ find . -name "*.o" | xargs rm
$ gcc -Wall -Werror -fpic -I. -c ky.c -o ky.o 
$ gcc -shared -o libky.so ky.o
```

libky.so というファイルが出来ます。


## JSとWASMを作成する

```bash
$ find . -name "*.o" | xargs rm
$ find . -name "*.wasm" | xargs rm
$ emcc ky.c -o ky.o 
$ emcc ky.o -o libky.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s EXPORTED_FUNCTIONS="['_print_hello']"
```



## Dartから 関数を呼び出す:Linux Server

```dart:main.dart

import 'dart:ffi' as ffi;

typedef PrintHelloFunc = ffi.Pointer<ffi.Void> Function();
typedef PrintHello = ffi.Pointer<ffi.Void> Function();

ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open('/app/libc/libky.so');
PrintHello _print_hello = dylib
    .lookup<ffi.NativeFunction<PrintHelloFunc>>('print_hello')
    .asFunction();

void printHello() {
  _print_hello();
}

main(List<String> args) {
  printHello();
}

```

# Dartから 関数を呼び出す:Webブラウザー

```dart:main.dart

import 'dart:js' as js;

js.JsObject Module = js.context['Module'];
js.JsFunction _print_hello =  Module.callMethod('cwrap',['print_hello','',[]]);

void printHello() {
  _print_hello.apply([]);
}

void main() {  
  printHello();
}

```

# 試してみる

```
dart ./bin/main.dart 
```

```
webdev serve --hostname=0.0.0.0
```

以上

# 次回

Buffer の扱いかた または、各種Primitive の扱いについて解説します。

# PS

今回のコードは以下です
https://github.com/kyorohiro/dart_clang_codeserver/tree/02_hello

以下でも書いています
https://dev.to/kyorohiro/dart-and-c-how-to-ffi-and-wasm-2-hello-4jo2
[xcode11][swift] storyboardで作る scrollView 備忘録

つまづいたので備忘録


###storyboardの配置
1,ViewにScrollViewを設置しオートレイアウト設定
2,Exit下にScrollView内に表示させたいViewを設置 高さを600に設定
3,今回はStackViewを使用　オートレイアウトはbottom以外の3点を設定
4,StackView内のViewを設置　高さを500に設定
**画面View範囲外まで及ばないとスクロールされない**
5,わかりやすいように、背景色を変更


<img width="307" alt="スクリーンショット 2020-05-17 3.41.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/af34b4af-9c0d-0645-61de-4db44299b85a.png">

<img width="307" alt="スクリーンショット 2020-05-17 3.41.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/d6966bbc-43a7-0d08-fe5c-3303657819a5.png">


###コード

**追記**
Exit下のViewの名前をcontentViewに変更しました
名前の変更はコードには影響しませんが、下のコードでOutletを接続する際の誤解を防ぐためです。

```ViewController.swift

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet var stackView: UIStackView!
    @IBOutlet var contentView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // コンテンツViewを載せる
        contentView.frame.origin = CGPoint.zero
        scrollView.addSubview(contentView)
        self.stackView.layoutIfNeeded() //重要//
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        // コンテンツの幅を画面に合わせる
        contentView.frame.size.width = scrollView.frame.width
        // コンテンツの高さを調整する
        contentView.frame.size.height = stackView.frame.height
        // スクロール範囲をコンテンツに合わせる
        scrollView.contentSize = contentView.frame.size
    }
}

```
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/ab0a69c7-a9e7-428c-4dce-62c444d6fa78.gif)

コンテンツの幅のサイズなどを調整すると横のスライドはなくすことが出来ます


以上です。
VSCode でPHPをステップ実行するまでの３つの手順 (ローカル版 ＋ VM環境版)

更新
2020/05/17 `launch.json` に pathMappings の例を追記

- - -
- 
今日も明日も明後日も VSCode でしょう😎

## ゴール

以下の場合でステップ実行できること

- デバッグ対象がローカルにある場合 (VMなし) 
  - ローカルに `PHP, Web サーバ, ソースコード, Vscode` 
- デバッグ対象がVM上にある場合
  - ゲストOSに `PHP, Web サーバ, ソースコード`  
  - ホストOSに `VScode`
  
![debug.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/a95ca797-2ef3-19ce-db50-5e9852a5cbb1.gif)

## 書かないこと
- PHPと Web サーバのインストール手順

## 手順

&nbsp;&nbsp;&#xFFF0;0. (デバッグ対象がVM上にある場合のみ) ゲストOSのソースコードをホストから見れるようにする  


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`C:/app/src/wwwroot` を共有フォルダに設定


1. 拡張 `PHP Debug` をインストール 

    `shift + ctrl + x` で `php debug` を入力
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/7a2620d4-ea03-de11-2f1d-368aa9531a27.png" width="450">

1. デバッグ構成ファイルを作る

    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/35ea3921-d631-92fc-95ba-e08583a03aea.png" width="450">

    ```/.vscode/launch.json
    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Listen for XDebug PHP",
                "type": "php",
                "request": "launch",
                "port": 9000,

                // 以下、デバッグ対象がVM上にある場合のみ書く
                "pathMappings": {
                    // ゲストOSのソースの場所 : VSCode のあるホストOSから見えるゲストOS上のソースの場所
                    // e.g. いずれかひとつでOK
                    // "C:/app/src/wwwroot" : "//guest-hostname/wwwroot"
                    // "C:/app/src/wwwroot" : "//192.168.100.101/wwwroot"
                    // "C:/app/src/wwwroot" : "${workspaceRoot}"
                }
            }
        ]
    }
    ```

1. `Xdebug` をインストール

    
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/18954fe3-86a1-c720-05eb-4cb248117ebb.png" width="750">

    ⅰ. `php -i` の結果 **(全部)** を https://xdebug.org/wizard に張り付ける

    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/c1d713e0-da12-cd5c-73bd-ffdbb12b80c7.png" width="850">

    ⅱ. DLLをダウンロード

    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/18081b5b-7b93-546f-059f-ebfb94a406ea.png" width="650">

    ⅲ. `php.ini` と同じ階層に `ext` フォルダを作りそこにダウンロードした `DLL` を置く ※ `php.ini` の場所は上述のコマンドで出力されている

    ⅳ. Xdebug を設定

    ```/php.ini
    ; ローカルのみで環境をつくってる場合
    zend_extension = php_xdebug-2.9.5-7.4-vc15-x86_64.dll
    xdebug.remote_enable = 1
    xdebug.remote_autostart = 1
    xdebug.remote_host=localhost

    ; - - -

    ; デバッグ対象がVM上にある場合
    zend_extension = php_xdebug-2.9.5-7.4-vc15-x86_64.dll
    xdebug.remote_enable = 1
    xdebug.remote_autostart = 1
    ; ゲストOSから見たホストOSのIP
    xdebug.remote_host=192.168.100.101

    ```

    ⅴ. <font color="OrangeRed">**Web サーバを再起動**</font>


## ステップ実行

「ブレークモード」になることを確認できればOK。

余談ですがブレークモードで `ctrl + alt + w` して `w` だけ離して `a` で選択してる式を**ウォッチ式に追加**できますね。この辺り Visual Studio のショートカット体系に寄せてくれていて、ありがたいです😊
   
## 参考
Documentation - all settings: https://xdebug.org/docs/all_settings
Power Queryで文字列同士の類似度を求める

Power Queryで文字列同士の類似度を得る方法はないかと、

- レーベンシュタイン距離を実装してみたり
- [Power QueryのFuzzyJoin(曖昧結合)関数の結果から逆算しようとしてみたり](https://qiita.com/D-Three/items/fb35e9343c468f36d572)

と色々試してはみたものの、安定しなかったり重すぎたりで実用には厳しそう。
そこで、こんなのを作ってみました。

##処理手順

各文字列について、含まれる文字を

- 文字そのもの(char)
- 文字列内での登場回数(occ)
- 文字列内での位置(idx)

という3列のテーブルで表現する。「Qualia」と「Qiita」なら次のようになる。

|char|occ|idx|
|:--:|:-:|:-:|
|Q|1|0|
|u|1|1|
|a|1|2|
|l|1|3|
|i|1|4|
|a|2|5|

|char|occ|idx|
|:--:|:-:|:-:|
|Q|1|0|
|i|1|1|
|i|2|2|
|t|1|3|
|a|1|4|

行数の多いほうを左表として、charとoccで左外部結合する。

|char|occ|idx|char|occ|idx|
|:--:|:-:|:-:|:--:|:-:|:-:|
|Q|1|0|Q|1|0|
|u|1|1|null|null|null|
|a|1|2|a|1|4|
|l|1|3|null|null|null|
|i|1|4|i|1|1|
|a|2|5|null|null|null|

各行について、長い方の文字列の文字数を満点として、idxの差の絶対値を減点したスコアを求める。
ただし、nullの場合は0点とする。

|char|occ|idx|char|occ|idx|score|
|:--:|:-:|:-:|:--:|:-:|:-:|:---:|
|Q|1|0|Q|1|0|6|
|u|1|1|null|null|null|0|
|a|1|2|a|1|4|4|
|l|1|3|null|null|null|0|
|i|1|4|i|1|1|3|
|a|2|5|null|null|null|0|

scoreの合計を満点だった場合のスコアで割ったものを類似度とする。

(6 + 4 + 3) / (6 * 6) = 0.36111...

## Power Queryでの実装例

```matlab:TextSimilarity.pq
let
	fx = (s as nullable text) => (t as nullable text) as nullable number =>

	if (List.Contains({s, t}, null)) then null
	else if s = t then 1 
	else if List.Contains({s, t}, "") then 0
	else if Text.Length(s) < Text.Length(t) then @fx(t)(s)
	else

	let
		join = Table.NestedJoin(
			TextDetail(s), {"char" ,"occ"},
			TextDetail(t), {"char" ,"occ"},
			"t",
			JoinKind.LeftOuter
		),
		expand = Table.ExpandTableColumn(
			join,
			"t",
			{"idx"},
			{"t.idx"}
		),
		maxLength = Text.Length(s),
		add = Table.AddColumn(
			expand,
			"score",
			each if [t.idx] = null then
				0
			else
				maxLength - Number.Abs([idx] - [t.idx]),
			type number
		)
	in
		List.Sum(add[score]) / Number.Power(maxLength, 2)
in
	fx
```

```matlab:TextDetail.pq

(text as text) as table =>
let
	table = #table(
		type table [char = text, occ = Int32.Type, idx = Int32.Type],
		{}
	)
in
	List.Accumulate(
		Text.ToList(text),
		table,
		(state, current) => Table.InsertRows(
			state,
			Table.RowCount(state),
			{[
				char = current,
				occ = Table.RowCount(Table.SelectRows(state, each [char] = current)) + 1,
				idx = Table.RowCount(state)
			]}
		)
	)
```
爆速！Vercelとfreenomで独自ドメインのサイトを無料で作成する


無料でWebアプリケーションのホスティングが出来るnow.shが名称変更してVercelになってましたね。

使い勝手などがどうなのか触って試してみました。

結果、ただ触るだけだと簡単すぎて記事にならないので、ついでにfreenomも使って無料で独自ドメイン（カスタムドメイン）も反映させてみます。

※タイトルの爆速！は処理速度ではなく手順の話
※[プロトアウトスタジオ](https://protoout.studio)の授業補足資料にもなります。

## 作るもの

こんな感じの独自ドメインのWebサイトを作成（デプロイ）します。

https://suikousaibai.gq

> ![](https://i.gyazo.com/7e03f2c961496cd3e08255cbee54cca5.png)

ちゃんとSSLも対応してます。

## Vercel

読み方はバーセル？ですかね。

https://vercel.com

無料でWebアプリケーションのデプロイが出来ます。

**コマンド一発で出来ます**

![](https://i.gyazo.com/4974918831ad37c1ba367bcef2272aec.png)

### Vercelで爆速デプロイ

* 1. 簡単なhtmlファイルを作成します。

`20200516sample`というフォルダを作成してindex.htmlを作成しました。

> ![](https://i.gyazo.com/40f1feadb7ea5c2eb9f8a534ea536cc1.png)

以下の記事のhtmlをコピーして作りました。

> [Vue.jsで東京都の今日の天気を表示するWebサイトを作るコピペサンプル](https://qiita.com/n0bisuke/items/439c7dac42603e7dd1aa)

* 2. Vercelのコマンドをインストール

```
npm i -g vercel
```

* 3. デプロイ

```
vercel
```

以上です。相変わらずシンプルで簡単。
(ここで初めての人はメールアドレスの認証などを聞かれるかもしれません。僕の場合はnow（旧名称）で使っていたからだと思いますが特に聞かれませんでした。)

あとは対話式の質問が出てくるので答えていけばデプロイされます。

> ![](https://i.gyazo.com/a5aafd90031b025baa80ecd4a5a49947.gif)

プロジェクト名を聞かれたのでsuikousaibaiにしました。なんとなく。

https://suikousaibai.n0bisuke.now.sh のURLでデプロイされました。

8888。

ここまででもだいぶ便利です。

ついでに独自ドメインもやってみます。

## FreenomとVercelで独自ドメインなWebサイト

無料でドメインを取得できるサービスです。

https://www.freenom.com/ja/index.html

> ![](https://i.gyazo.com/78c03b82687f60cb885d5e82109e94e3.jpg)

* 1. Freenomでドメインを取得します。

ここは割愛します。無料なので空いているものを取ってみましょう。

`suikousaibai.gq`というドメインを取得してみました。

* 2. Vercelのネームサーバー情報を取得

Vercelの管理画面にいきます。
https://vercel.com/dashboard/domains

`add`ボタンを押します。

> ![](https://i.gyazo.com/94358d57d314af22bbc4958231a2f2ed.png)

作成したアプリ(ここでは`suikousaibai`)を選択して進みます。

> ![](https://i.gyazo.com/72f07c23a0533bd42ec136d387735647.png)

freenomで取得したドメイン（ここでは`suikousaibai.gq`）を入力して進みます。

> ![](https://i.gyazo.com/d87c10c70915a3044ce358ef1fdadee1.png)

次の画面で`Checking Domain Status`の箇所が読み込み中...のような表示になります。 **画面表示が変わるので少し待ちましょう。**

> ![](https://i.gyazo.com/268c43851e8ab36ef08405597d594b5a.png)

しばらく待つと`Intended Nameservers`のネームサーバー情報が表示されます。
ここの情報はユーザーやアプリごとで若干異なるみたいです。

> ![](https://i.gyazo.com/c3459e3e582212b26798e628362ab23a.png)

今回は以下のような情報でした。

```
a.zeit-world.co.uk
c.zeit-world.org
d.zeit-world.net
f.zeit-world.com
```

* 3. 取得したドメインをVercelのアプリに紐付け

このネームサーバーの情報をFreenom側に設定します。

Freenomのドメイン管理画面から利用するドメインの設定（Manage Domain）のボタンを押してドメインの設定画面に移動します。

`Management Tools` > `Nameservers`からネームサーバーを入力して保存します。

> ![](https://i.gyazo.com/340bbe1258bab3ed752c0404ae049000.png)

これで設定は完了です。

* 4. 浸透されるのを待つ

設定は完了ですが、反映されるのに時間がかかるので少し待ちましょう。
数分〜数十分かかるときもありそうな印象です。

気長に待ちましょう。完了すると冒頭で紹介したような独自ドメインのWebサイトが出来ます。

お疲れ様でした。

## 更新するとき

index.htmlを編集してvercelコマンドで更新できます。

## 所感

無料でやれるのはやはり気軽で良いですね。
Freenom側のキャッシュなのか、更新時も反映されるのに時間がかかる印象でした。

無料なので文句言えないところはあるねぇくらいの感覚で使うと良いのかなと思います。
AWSのELB(Elastic Load Balancing) 構成時に Auth0 認証の例外 (Invalid state) に対処する

## 経緯

1. ローカル環境 (ロードバランサー無し) ではうまく認証できる。
1. AWS上 (ロードバランサーあり) だと `Invalid state` でエラーになる。

    ```/Auth0.php
    throw new CoreException('Invalid state');
    ```

    https://github.com/auth0/auth0-PHP/blob/660163b31beae4c550db68022c568b41df75d8e9/src/Auth0.php#L518

1. エラーの原因を調べる。どうやら xxx.auth0.com 側の認証処理後に `callback url` に乗せて Get パラメータで戻される `state` の値とサーバの `state` の値に相違がある...。

## 結論

EC2 > ロードバランシング > ターゲットグループ > 属性の編集 > 「維持設定 有効化: `on`」 にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134761/68d23cea-33c5-f058-21e7-0084722f7c61.png)

注: 根本解決ではないが、ひとまずこの対処でいくことにした。
一定負荷を超えた場合に備えてスケーラブルなサービスを提供している場合、**この方法ではのちのち問題**になるので `Amazon ElastiCache`を使うのが定石らしい。

## 余談

んなことで２時間ちかく時間が...けどこれロードバランサー使うときの常識なんだろうな😂
ちゃんと理解しておかないと他のトラブル時に対処できない、まずいな。

## 参考

**スティッキーセッション**というらしい。
https://hack-le.com/sticky-session/
Amazon S3 SRR（Same Region Replication）について



### 1. はじめに
本投稿では、Amazon S3の機能の一つであるSRR(Same Region Replication)について解説したのちに、簡易的な使用方法について載せる。

### 2. 概要

概要について箇条書きする。

- レプリケーションの方法は***２種類***存在する。
- ***異なる***リージョンのバケットに対するレプリケーションを、***Cross-Region レプリケーション(CRR***)
- ***同一***リージョンのバケットに対するレプリケーションを、 ***Same-Region レプリケーション(SRR***)
- ***厳しいコンプライアンス要件***（離れた場所にデータを保存することが要求される場合など）は、クロスリージョンレプリケーションが有効。
- Amazon S3 バケットにアップロードされた新しいオブジェクトは、***バケットレベル、プレフィックスレベル、またはオブジェクトタグレベルでのレプリケーション***で設定することが可能。
- レプリケーション設定の際は、Amazon S3 がオブジェクトをレプリケートする　***レプリケート先バケット***が必要
- ***S3 Replication Time Control (S3 RTC)***を使用すると、データのレプリケーションに関するコンプライアンス要件やビジネス要件を満たし、Amazon S3 レプリケーション時間を可視化できます。S3 RTC は、Amazon S3 にアップロードしたほとんどのオブジェクトを数秒でレプリケートし、これらのオブジェクトの ***99.99% を 15 分以内にレプリケート***。ただし、ベストエフォートで保証するわけではない。

### 3. 手順

送信元と送信先のバケットのバージョニングを有効化
<img width="1246" alt="スクリーンショット 2020-05-17 1.26.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/25484038-6ca9-42e0-2af5-d29b0328d0c8.png">

管理タブからレプリケーションルールを作成

<img width="1277" alt="スクリーンショット 2020-05-17 1.27.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/22372070-824f-3652-4345-6647dfdb636e.png">

レプリケーションルールを設定（レプリケーション先、S3ストレージクラスなど）

<img width="695" alt="スクリーンショット 2020-05-17 1.28.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/85945e77-2d74-fd56-18d3-b7672d5f20f9.png">

以上
Memo: Git command

# git log
<pre>
git log --oneline --pretty=format:'%h [%cd] %d %s <%an>' --date=format:'%Y/%m/%d %H:%M:%S'
</pre>
https://qiita.com/tomlla/items/219cea9dd071c8a9e147
<pre>
git log --date=iso --pretty=format:"[%ad] %h %an : %s"
</pre>
https://qiita.com/harukasan/items/9149542584385e8dea75
NVIDIA Jetson Nano 開発者キットB01 セットアップ方法

# やったこと

* Jetson Nanoのセットアップ
* SDカードイメージのダウンロードから日本語入力を確認まで

# 用意するもの（ハードウエア）

* Jetson Nano B01
* SDカード
    * Samsung EVO Plus 128GB microSDXC
* DC電源アダプタ
    * SUCCUL ACアダプター 5V 4A

※以前必要だったジャンパーピンは不要（同梱されている）

# 手順

## SDカードへのイメージ書き込み

### NVIDIAサイトからJetson NanoのSDカードイメージをダウンロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/ab7a3e76-e3da-f0ef-cec3-6f9906150c7b.png)

* JetPack4.3(r32.3.1)に対応したSDカードイメージ
    * nv-jetson-nano-sd-card-image-r32.3.1.zip
* ダウンロードサイト
    * https://developer.nvidia.com/embedded/downloads
    * 下記サイトでもOK
        * https://developer.nvidia.com/jetpack-43-archive
       
### 上記ダウンロードしたSDカードイメージを書き込む

* お好みのソフトで書き込む
* balenaEtcherがおすすめ
    * https://www.balena.io/etcher/
    * 使い方
        * https://freesoft-100.com/review/balena-etcher.html


## Jetson Nanoセットアップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/fd6807af-a6b5-6a86-96c5-507edb1659d4.png)


1. 作成したmicro SDカードをJetson Nanoに差し込む（上図の①）
2. ジャンパーピンをセット（上図の⑧の近く２本のピンをまたぐようにセットする）
3. DC電源を差し込んで電源投入（上図の⑧）
4. 起動したら、ユーザ名、パスワード、キーボード設定、言語設定などをウィザードに従って進めていく　　
    * パーティションサイズ：そのままで最大まで使う設定になっている
    * 言語：　日本語
    * キーボード：　日本語
5. ネットワークに接続（デフォルトでは有線LANのみサポート）
6. 言語サポートの設定
    1. システム設定 -> 言語サポート  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/dc29ffa6-bef2-2007-2df3-1711a98919cc.png)

    2.  システム全体に適用を押す  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/c5437404-0889-db6d-5a07-ea22cb3dc742.png)
7. ソフトの更新＆再起動
9. フォルダ名を英語にする（任意）
    * 参考
        * https://qiita.com/taiko19xx/items/d1a001bfc25245b91354
【Dart】DartでRESTful API ① Tutorial編

# はじめに
普段はiOSエンジニアをしていて「休みの日ぐらい違う技術を触りたい！」と思うようになったので、今の自分とは一番縁がなさそうなDart×RESTfulで遊んでいこうと思います :muscle: 


# Dart Tutorial
まずは様々なframeworkを使うよりも[公式のTutorial](https://dart.dev/tutorials/server/httpserver)を読みながら進めていきます。サンプルも提供されていてありがたい :clap: 

## 環境構築
### Dartをインストールする

```
% brew tap dart-lang/dart
% brew install dart
```

### VSCodeの拡張機能を入れておく
一旦は[Dart-Code](https://github.com/Dart-Code/Dart-Code)だけ入れておけば大丈夫そうでした。
VSCode上からRunできて便利 :clap: 


## その① Hello WorldにGETリクエストとして受け付けてみる
HelloWorldの表示に関してはTutorialに載っているのでそちらを実行してみるとして...

- GETリクエストのみ受け付けるようにしてみる
- 対象以外はエラーを返すようにしてみる

をしてみると以下のようになります

```dart
import 'dart:io';

String _host = InternetAddress.loopbackIPv4.host;

Future main() async {
  var server = await HttpServer.bind(_host, 4040);

  await for (var req in server) {
    ContentType contentType = req.headers.contentType;
    HttpResponse response = req.response;
    Map<String, String> queryParameters = req.uri.queryParameters;

    if (req.method == 'GET' && contentType?.mimeType == 'application/json') {
      String name = queryParameters['name'] ?? 'unknown';
      response
        ..statusCode = HttpStatus.ok
        ..write('Hello! ${name}');
    } else {
      response
        ..statusCode = HttpStatus.methodNotAllowed
        ..write('Not Supported');
    }

    await response.close();
  }
}
```

### 結果
textがレスポンスとして返却されてます :clap: 

```sh
% curl -H 'Content-Type:application/json' -X GET 'http://localhost:4040?name=tomo'
Hello! tomo
% curl -H 'Content-Type:application/json' -X GET 'http://localhost:4040'
Hello! unknown
% curl -H 'Content-Type:application/json' -X POST 'http://localhost:4040'
Not Supported
```

## その② レスポンスをJSONにする
このままでは使い物にならない...のでJSONに変更してから返すようにしてみる

```dart
import 'dart:io';
import 'dart:convert'; // 追加

/*　略  */
    if (req.method == 'GET' && contentType?.mimeType == 'application/json') {
      String name = queryParameters['name'] ?? 'unknown';
      Map<String, dynamic> jsonValue = {'greeting': 'Hello! ${name}'}; // 追加

      response
        ..statusCode = HttpStatus.ok
        ..write(jsonEncode(jsonValue));
    } else {
      Map<String, dynamic> jsonValue = {'message': 'Not Supported'}; // 追加

      response
        ..statusCode = HttpStatus.methodNotAllowed
        ..write(jsonEncode(jsonValue));
    }
/*　略  */
```

### 結果
JSONとして返却されてますね :clap: 

```sh
% curl -H 'Content-Type:application/json' -X GET "http://localhost:4040?name=tomo"
{"greeting":"Hello! tomo"}
% curl -H 'Content-Type:application/json' -X GET 'http://localhost:4040'
{"greeting":"Hello! unknown"}
% curl -H 'Content-Type:application/json' -X POST 'http://localhost:4040'
{"message":"Not Supported"}
```

# 感想
自分は結構サーバーサイドの実装が苦手(作れても本当に単純なもののみ)で今まで逃げてきたのですがこの際にもう一度勉強を始めてみることにしました。特に環境構築の部分では作りながら「え、これだけ？」となるぐらい簡単だったのでとっつきやすかったです。実際に運用するとアーキテクチャ、DB周り、インフラなどなどもっと複雑になるんだろうなと思いながらやってみました。

次回はもう少し複雑なことに挑戦してみます :muscle:
Vue.jsを勉強するモチベーション

# 概要
流行や学習コストの低さなどでチヤホヤされる存在となったVue.jsですが、みなさんはVue.jsの学習捗ってますか？
業務で使うから仕方なく覚えるのではあれば、やるでしょう！
でも自分の可能性を広げるための勉強ならどうでしょう？
流行だからと飛び付いたもののやる気がでない…
他にモチベーションの繋がるものはないか？

# アニメは好きかい？
Vue.jsの開発者エヴァン・ヨーさんはどうやら日本アニメが好きらしい
彼はアニメヲタクなのだ！

# ヲタクならわかるだろ？
| ersion | 開発コードネーム | 日本語名称 | アニメ初出年 |
|:--|:--|:--|:--|
| v2.6 | Macross | 超時空要塞マクロス | 1982年 |
| v2.5 | Level E | レベルE | 2011年 |
| v2.4 | Kill la Kill | キルラキル | 2013年 |
| v2.3 | JoJo's Bizarre Adventure | ジョジョの奇妙な冒険 | 1993年 |
| v2.2 | Initial D | 頭文字D | 1998年 |
| v2.1 | Hunter X Hunter | HUNTER✕HUNTER | 1999年 |
| v2.0 | Ghost in the Shell | GHOST IN THE SHELL / 攻殻機動隊 | 1995年 |
| v1.0 | Evangelion | 新世紀エヴァンゲリオン | 1995年 |
| v0.12.0 | Dragon Ball | ドラゴンボール | 1986年 |
| v0.11.0 | Cowboy Bebop | カウボーイビバップ | 1998年 |
| v0.12.0 | Blade Runner | - | 1982年 |
| v0.12.0 | Animatrix | アニマトリックス | 2003年 |

日本のアニメの名前がコードネームに使われた技術に愛着がわかないわけがないだろう！

# あとがき
今回の記事は技術的観点からの記事ではないけど、何かをはじめる時には動機や目標などが明確でないと長続きしないわけです。
そこでアニメが好きな人にはVue.jsを愛でる理由になりうるであろう開発コードネームを紹介する事にしました。
この記事が今にも勉強のモチベーションが消えかけているVue.jsを勉強しているアニメヲタクに届くとよいないと思います。