OmniAICreator/Qiita-1.07M huggingface dataset:
Exploratoryでのカスタムパレットの作成方法

**カスタムパレットの作成方法**

現在15種類の色のパレットが存在しますが、チャートに合うパレットを作りたい場合は**カスタムパレット**という機能を使用することで、独自の色のパレットを作ることができます。

例えば、このようなチャートがあった時に、女性はピンク、男性は青で表示したいとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/61a47a8d-88cb-c3a2-42e2-a14535b1fb28.png)



はじめに、色(グループ化)の設定ボタンをクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/3c79faf6-cecc-3a71-0c6f-971c46f6099a.png)


色の設定のパレットをクリックします。

![185CB3CC-E20B-4D49-8D52-A3FCA080FF56-6241-00000A65B70346EA.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/0a432783-3a00-b68b-adbb-313be9758499.png)


下の方にスクロールして**カスタム**を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/1a361860-7025-c33f-1f69-5cb8a90f425d.png)


ここでカスタムパレットを選択することができます。
しかし、カスタムパレットがない場合は選択できないので、編集をクリックして作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/4d2f1531-8cd2-f9dc-5453-89312b5b0b5c.png)


追加ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/f0704051-5d28-c967-1ea5-eb8bc9992198.png)


**表示名の入力**と**カラーパレットの追加**をしていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/fce7619f-118f-ae79-9727-74b260c55916.png)


色を割り当てたいパレットをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/7d173f59-a06d-085e-7e32-857e2ddcaa71.png)


 お好きな色を選択してください。
 今回は女性にピンク(Hex:FA766F)、男性に青(Hex:4A90E2)を割り当てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/55362e7f-8f73-0bb8-6bd7-ad1dcae52876.png)



パレットの追加と色の割り当てが完成したら、追加ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/0f390cd1-69d4-8629-22c2-a57e8850a532.png)




カスタムパレットを作成することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/f19ced3f-d5d4-3918-2dd0-ea6552484267.png)



それでは、先ほどのチャートにカスタムパレットを適用してみましょう。

色の設定から、カスタムパレットを選択し先ほど作成したFemale_maleを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/b0b69565-c248-6400-2ae1-de906dcc11d4.png)


女性にピンクと男性に青を割り当てることができました。
Vue CLIに関するすること（メモ）

#Vue-cliをするまで
>
https://qiita.com/567000/items/dde495d6a8ad1c25fa43

こちらのページがわかりやすかった。
>
https://techacademy.jp/magazine/16105

npmについても調べたページをメモ。

#手順画像
1.VS Codeを開く
![VS Code.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/563093e4-f882-15eb-86cd-999e546b64c7.jpeg)

2.ターミナルを開く（※コマンドプロンプトでもいいけどね）
![Terminal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/1a930bfc-886f-d019-8144-5c996f0ceaea.jpeg)

3.「cd （ファイルを保存するディレクトリ）」
![cd.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/60c1560f-8393-801c-a92e-e2a64bc090cc.jpeg)

4.「vue create (プロジェクト名）」
![vue create.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/fae2ad6e-a950-452e-8c74-47b20f153dce.jpeg)

※versionが古いと怒られる・・・
>
vue create is a Vue CLI 3 only command and you are using Vue CLI 2.9.6.
You may want to run the following to upgrade to Vue CLI 3:
  npm uninstall -g vue-cli
  npm install -g @vue/cli

（意訳）
「『vue create』は3からのコマンドなのにお前の古いよ」
「下のコマンド打って上げろ」

![ver.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/08e6aa61-3611-7e85-fb2e-8d50cca9bdea.jpeg)

5.保存したディレクトリを開く
![created.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/b0e8ba31-71d3-d578-d4ab-ba5d5804e0d5.jpeg)

6.できてる！
![directory.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244716/5292c81d-20f6-bf94-7d8a-80800f3a771b.jpeg)

#つづく
つづく
Flipping Signs

- [Flipping Signs](https://atcoder.jp/contests/abc125/tasks/abc125_d)

## コンテスト中の考察(AC)

- 何も思いつかないのでとりあえずDFSを書いてみる。ほとんどTLEでWAがちょっと出た。
- よくわからないので色々実験してみる。
- 実験した結果、数列に0が含まれる場合は全てプラスにすることができることに気づく（証明はできんけど）
- それ以外の場合は、数列に対しループを回し、i番目にマイナスの値が出てきたらA[i]とA[i+1]に-1をかける操作をする。その結果が、マイナスの値が1つ以上の場合とそれ以外の場合に分けることができそう（証明できんけど）。マイナスの値が1つ以上の場合、数列中に含まれるマイナスの値はひとつでその他はプラスの値となる。これは、実験した結果なんとなくそう思った。操作後の数列にマイナスが含まれない場合は、全てをプラスにすることができる。たぶんね。
- そんな感じで考察して提出したらACしてしまった。実験してそれっぽい解法投げただけなので全然理解してない。



## 反省

### 詰まった部分

- 要素5に対して操作→要素1に対して操作→要素3に対して操作→...みたいなことができるので、頭が壊れた。何が最適かわからなくなっていた。

### 思いつき方1(パターン列挙から入る)

- 操作する対象のパターンを列挙する。
- この問題では連続する2つの要素に対して操作を行う。ぱっと見ぐちゃぐちゃに見える。でも、２要素に対する操作ののパターンを抜き出すと`++`、`--`、`+-`、`-+`の4パターンへの操作しかない。
- `--`はすべて`++`にしても問題ない。
- `-+`は`+-`にしていくことで、マイナスを右端に集めることができる。そして、集めたやつを`--`から`++`にすることができる。
- この操作をすると、マイナスの個数が0個か1個になる。`+-`と`-+`への操作はマイナスの個数の偶奇は変わらない。そして、`--`への操作でもマイナスの個数の偶奇は変わらない。なので、与えられた配列のマイナスの個数によって残るマイナスの個数が異なる。
- マイナスの個数が偶数個ならすべてのマイナスを消せる。マイナスの個数が奇数個なら偶数個しか減らすことしかできないためマイナスは1つ残る。

### 思いつき方2(どうなれば嬉しいか考える)

- フリップ操作では連続する2つの要素の偶奇をフリップする。
- これより、任意の2つの要素をフリップできたら嬉しいなぁって思う。これができればいいことがあるので、試してみる。

<img width="909" alt="flipping_signs_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218584/67e0ed8c-1991-25ab-2c8a-01245da6378d.png">


- 赤い2つの要素のプラマイを反転させる。図のようにすれば赤い部分は1回で反転、その間の要素は2回反転で元に戻る。なので、実質赤い２つの要素のプラマイを反転させることができる。
- これより、マイナスの要素を2つずつ消していくことができる。マイナスの個数が偶数この場合はすべての要素をプラスにすることができる。だが、マイナスの個数が奇数個の時はマイナスの要素が1つだけ残る。



## 解法

- 与えられた配列のマイナスの個数をカウントする。
- マイナスの個数が偶数個ならば要素の絶対値の和が答え。
- マイナスの個数が奇数個ならば要素の絶対値が一番小さいものをマイナスにし、その他の要素をプラスにして足し合わせたものが答え。



## [コード](https://atcoder.jp/contests/abc125/submissions/5231392)

```cpp
#include <bits/stdc++.h>
using namespace std;

#define int long long

int N;
int A[111111];

signed main() {
  cin >> N;
  int minus = 0; // マイナスの個数
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    if (A[i] < 0) {
      minus++;
    }
  }

  if (minus % 2 == 0) {
    int ans = 0;
    for (int i = 0; i < N; i++) {
      ans += abs(A[i]);
    }
    cout << ans << endl;
  } else {
    for (int i = 0; i < N; i++) {
      A[i] = abs(A[i]);
    }
    sort(A, A+N);
    int ans = -A[0]; // 一番小さいやつをマイナスにする
    for (int i = 1; i < N; i++) {
      ans += A[i];
    }
    cout << ans << endl;
  }

  return 0;
}
```



## 要点

- どうなれば嬉しいか考えると良さげ
- パターン列挙するのも良さげ。
  - なんかぐちゃぐちゃだった盤面をシンプルに考えられたので。



## メモ

- [けんちょんさんの記事](http://drken1215.hatenablog.com/entry/2019/04/27/224100)
- 類題出て思いつける気がしねえ
- DPでも解けるみたい
mrubyがIchigoJamで動くらしい

# あらすじ

IchigoJamでmrubyが動くって聞いたから試してみた。
本家の方のリンクを貼っていいものか判断しかねたので貼ってない。
が、''mrubyがIchigoJamで動く''でググると上位に来るので簡単に分かると思う。

以下が前提の環境

 + IchigoJam: くまモン型の奴を持っているのでそれを利用する。
 + PC: Windows 10
 + Visual Studio Code: 1.30.2

# 結果

![dekinkatta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/07cd4b48-d580-6fdb-a3ef-49517bc317ee.png)


# 環境構築

[こちら](https://github.com/taisukef/micro_mruby_for_lpc1114)からコードを落として展開する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/7e93f69e-e570-89b8-5e4a-3b0601680422.png)
<font color="red">こんな感じ</font>

gcc,makeが必要となるので、[こちら](http://gnuwin32.sourceforge.net/packages/make.htm)から落としてパスを通す。
自分の場合は''C:\Program Files (x86)\GnuWin32\bin''をパスに追加した。
コマンドプロンプトでmakeが認識でいればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/716546ab-a7f9-e3fd-2cb6-ebb19f49eadd.png)
<font color="red">まぁ、なんとかなるだろう</font>

makeが認識出来たら、Visual Studio Codeでディレクトリを開き、terminalでmakeを叩く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/8752775e-02cb-b3bf-5887-c9c7e78b21f2.png)

<font color="red">gcc入れ忘れてるよねコレ</font>

と言うわけで[こちら](http://www.msys2.org/)からMinGWを入れる。
手順に従ってパッケージを同期。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/ec675581-b539-befd-8ead-44b012989dc9.png)

gccをぶちこむ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/322848c3-d9a2-62a0-2d1c-cb815a221ebc.png)

無事入ったらバイナリのパスをWindows側で通す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/5a249de4-7461-13cc-b778-fb469de52779.png)

再度Visual Studio Codeでmakeしてみる。多分一発で通らないので、各環境に応じてMakefileを修正する。
変えたところとしては

 + CPU: corei7
 + CC: gcc
 + OBJCOPY: objcopy
 + OBJDUMP: objdump
 + SIZE: size
 + NM: gcc-nm

いざビルド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42445/fef3738a-1fa1-ed40-5483-390be05e6900.png)

<font color="red">できないものはできない。</font>

# ふりかえり

なんかアプローチが間違ってる気がする。
が、できなかったものはできなかったのでGWの成果としてアップする。
同じアプローチとってもビルドできないから気を付けていただければ幸いだ。
Azure Spatial Anchors v1.1.0 Unity iOS版をビルドしてみる

# はじめに

[Azure Spatial Anchors v1.1.0 Unity Android版をビルドしてみる](https://qiita.com/bathtimefish/items/8184286b52ecaa358ccd) の次にiOS版もビルドしてみる。公式ドキュメントは[こちら](https://docs.microsoft.com/en-us/azure/spatial-anchors/quickstarts/get-started-unity-ios)

# やってみる

Azure Portalでの設定と、[azure-spatial-anchors-samples](https://github.com/Azure/azure-spatial-anchors-samples)をcloneして`Unity`フォルダを開くところまではAndroid版と同じ

[Unity ARKit Plugin version 2.0.0](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/get/v2.0.0.zip) をダウンロードしておく

**ファイル** -> **ビルド設定** を選択する

![スクリーンショット 2019-05-02 15.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/fde14876-b325-0071-bd76-106e81fca01f.png)


**ビルドに含まれるシーン** はデフォルトのまま全選択。**プラットフォーム** で `iOS`を選択し**Switch Platform**ボタンをクリックする

![スクリーンショット 2019-05-02 15.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/d4f67929-11fe-cb29-bd1f-0c739f45fd87.png)


設定が完了したら**ビルド設定** を閉じる

先ほどダウンロードしておいた**Unity ARKit Plugin version 2.0.0**を展開し、展開したフォルダの`Assets`フォルダの中身をUnityの`Assets`フォルダにコピーする

プロジェクトから**Assets** -> **AzureSpatialAnchorsPlugin** -> **Examples** -> **Resources** とフォルダを選択して、`AzureSpatialAnchorsDemoConfig` アセットを選択する

![2d171c2b-34d5-4c57-819e-ad376fc49790.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/50ab97d6-3807-8702-0d79-b9bc530799c5.png)


インスペクターで控えておいたSpatial Anchor Accountの**Account ID**と**Primary Key**を入力してプロジェクトを保存する

![fc56cf5a-f9bd-42f8-95d1-2765fd6e5504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/d5a20733-9bfa-43a4-bce7-697ca8e3f7c1.png)


ビルド前にアセットの再インポートをやっておいたほうがいいのはAndroid版と同じ。**アセット** -> **すべてを再インポート**を選択してアセットを再構成する

**ファイル** -> **ビルド設定** を選択する

![スクリーンショット 2019-05-02 15.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/7c61964a-06bd-028d-bd41-d4ed9b127295.png)


**ビルド** ボタンをクリックしてプロジェクト名を入力し**Save**ボタンをクリックする。ここではプロジェクト名を`SpatialAnchorsDemo-iOS`とする

![スクリーンショット 2019-05-02 15.53.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/7d42885c-31eb-d4b4-209a-8cb500450593.png)


エクスポートされたプロジェクトに移動して、依存パッケージをインストールする

```
cd SpatialAnchorsDemo-iOS

pod install --repo-update
```

XCodeで`Unity-iPhone.xcworkspace`を開く。`.xcodeproj`でないことに注意

```
open ./Unity-iPhone.xcworkspace
```

**Bundle Identifier**を適当な名称に変更して、**Team**に有効なアカウントを設定する

![スクリーンショット 2019-05-02 16.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/624d3d1e-e1f1-517f-97c4-166ae23ec525.png)


iPhoneをMacに接続して、ビルドボタンをクリックし、iPhoneにアプリケーションをインストーする

アプリがインストールされるのでデモを実行する。デモの操作方法はAndroid版と同じ

![iOSdemo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/5a53996e-cfd1-1b8c-d6d7-b83c4b17c3e9.png)


#  まとめ

Android版との違いは`Unity ARKit Plugin version 2.0.0`のインポートくらいであとは普通にiOS用にビルドすればできる。次はAndroid版とこのiOS版のデモを使って[シェアリング](https://docs.microsoft.com/en-us/azure/spatial-anchors/tutorials/tutorial-share-anchors-across-devices)をやってみたいと思う
Node-REDを使ってブラウザに喋って複数の動画を制御する

# はじめに
## やりたいこと
* 複数人で動画を見ていて、誰かが止めてといえば、全員が見ている動画がとまるようにしたい
* 基本的な使い方は関連記事を参照してください。

## Node-REDのまとめ記事
* [Node-RED系の記事のまとめ](https://qiita.com/kazutxt/items/8c72448eefcba56dabef)

## 動作環境
* IBM bluemix Node-RED : v0.20.5

## 免責事項
* 検証をして確実と思われる情報を載せておりますが、誤っている可能性もゼロではないので、参考程度にご利用ください

# 本編
## 画面
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/557399b2-ad2c-9df5-9d38-75de6a42a703.png)

動画は著作権とかあるので、あえてロード中にしています

## 処理の流れ
1. 画面を開くとWebSocketを使ってサーバとの通信を確立
2. ボタンを押すと音声を認識できる状態になる
3. WebSpeechAPIを使って、ブラウザに向かって話した内容を文字列化
4. 文字列をサーバに送る
5. 制御用文字と時間をJSON化してブロードキャストする
7. 受け取ったJSONでブラウザ側で制御(止めたり、戻したり)をする
8. WebSpeechAPIを使って結果を喋らせる

## フロー

![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/0b7463f5-b339-8b70-5322-43069c776838.png)

## 補足
* ブロードキャストされるように、` delete msg._session` をしています
* 10秒戻してを{back:10} のように変換して各クライアントにブロードキャストします
* コマンドは、再生、停止、早送り、巻き戻し、頭出しの5つでよく使いそうな言葉と紐づけています
    * the worldも作ろうかと思いましたが、いちいち説明するのがwww

## ブラウザ側の実装
WebSpeechAPI部分は、前回記事をご参照ください

* [Node-REDを使ってブラウザに喋った内容を各SNSに通知する] (https://qiita.com/kazutxt/items/19cd4bca52da73ffaf62)

動画制御部分のみの掲載です。

``` js:ブラウザのhtml内のjs
   var v = document.getElementById("video");
   var [command,time] = evt.data.split(":")
        switch (command){
            case 'play':
            v.play();
            speakText = "動画を再生します"
            break;
            case 'pause':
            v.pause();
            speakText = "動画を停止します"
            break;
            case 'forward':
            v.currentTime += Number(time);
            speakText = "動画を"+time+"秒進めます"
            break;
            case 'back':
            v.currentTime -= Number(time);
            speakText = "動画を"+time+"秒戻します"
            break;
            case 'reset':
            v.currentTime = 0;
            speakText = "動画を最初から再生"
            break;
        }
```
videoタグっていろいろなことができるんですねぇ

* http://www.htmq.com/video/
UnityでiPhoneX系による表情取得について

#自己紹介
こんにちはゆずです。@Yuzu_Unity


##はじめに
これを使います…これで記事は終わりです。
https://github.com/Unity-Technologies/facial-ar-remote
キズナアイが使ってるらしい？ZIPで紹介されていたみたいです（自分は見ていないので…）
にじさんじの3Dはこれを使っていのかな？

##準備物
iPhoneX/XR/XS
Mac(iOSビルドを行うため)
最終的にiPhoneの表情データを取得させたい!
Windows/Mac

##使い方
https://github.com/Unity-Technologies/facial-ar-remote/releases
releasesから使いたいところですが
iPhoneXS/XRで使える記述がver1.1ではないみたいです。
なので最新版をクローンします！！
zipでダウンロードするといろんなデータが死んでしまうみたいなので
LFSが使えるGit等でクローンしましょう。

[Github](https://github.com/Unity-Technologies/facial-ar-remote)に使い方等が書いています。
iOS Build Setup
Editor Animation Setup
の欄です。

iOSビルドを行った後
Win/MacのローカルLan内での接続です。
ファイアーウォールの設定を行わないと接続できないので注意

###インストールTips
ARKit pluginの場所　[BitBucket](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/downloads/)

7.Enable "ARKit Uses Facetracking" on UnityARKitPlugin > Resources > UnityARKitPlugIn > ARKitSettingsの場所
![unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/57a177af-2af5-2a77-393e-d821f788b608.png)


##自分のキャラクターを動かしたい…
可愛くないし…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/20b6f3b9-7b7f-3569-11a5-b184334f49b4.png)

このアセットに含まれている自分のメッシュへの適用なのですがセットアップがめんどくさい…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/7e7f417b-e246-de41-f83d-609444e4a9bb.png)

なのでそこは触れず自分は
>tmp[i]=Mathf.Clamp(skin.GetBlendShapeWeight(i),0,100);

を用い
狸？のブレンドシェイプをそのままコピーすることにしました。
あとは自分の使いたいキャラクターにSetBlendShapeWeightを行うだけです。

```c#

 //目線制御 こちらもブレンドシェイプから取得しボーンに回転値を割り当てします。
    void Update()
    {
        debugRotL = EyeRot(tmp[1], tmp[4], tmp[3], tmp[2]);
        debugRotR = EyeRot(tmp[8], tmp[11], tmp[9], tmp[10]);
        eyeL.localRotation = Quaternion.Euler(debugRotL);
        eyeR.localRotation = Quaternion.Euler(debugRotR);
    }

    Vector3 EyeRot(float valueL,float valueR,float valueUp,float valueDown)
    {
        float left = (valueL - valueR) * 45/100/4;
        float up = (valueDown - valueUp) * 45/100/4;
        return new Vector3(left, up, 0);
    }
```

Unityの地味な便利機能Constraintでコード書かずボーンに割り当て…
Mayaとの連帯機能ですが便利です。
首や頭の傾き等もこれを用い設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/0974d2f4-0764-751c-bd2f-c181672e550f.png)
[【Unity】複数のオブジェクトの位置を元にオブジェクトを動かす、○○○Constraint系というオモシロ機能]
(http://tsubakit1.hateblo.jp/entry/2018/01/12/233522)


##表情レコード機能
このアセットにはレコード機能など含まれていますが
自分はこちらを使うため使わないことにします。
https://qiita.com/Yuzu_Unity/items/d891ecee64a164149167

##結果
リップシンクはOVRLipSyncを用いたので今回は瞬きのみ適用しました。
iPhoneで取得するとリアル差がかなり上がります。
人間の瞬きは奥が深いものですね…
OpenCV×Dlibで行うより簡単で高精度なのでおすすめかと…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/b6c52eba-b13a-8ebb-6e62-d43e92e1c581.png)
Mac mini 2018に繋げたSSDにWindow10をインストールする手順

Mac mini 2018に繋げたSSDにWindow10をインストールしたときのメモです。

MacでWindows10を使う場合にMac内部のSSDにbootcampを使ってでもできますがディスクを分けて外付けにした方がosxのディスクを減らす必要がなくなるため利点があると思います。

iPhoneアプリのプログラミング環境はOSXが必須になるためどうしてもMacが要ります。
Windowsの方がよい場合もあるため両OSのプログラミング環境があれば隙なしです。

どんな言語もプログラミング環境がないと先に進めないため絶対的な用意が必要になります。
よりよいプログラミング環境こそがビジョンへの最善の近道な気もします。

Mac mini 2018になってからCPUが劇的に良くなったためビルド時間なども改善されました。

# 用意するもの
- Mac mini 2018（恐らくほかのMacでも同じだと思われる。）
- Windows10がインストールされたPC(VMアプリを使ってもできそうだがSSDのマウント周りで壁にあたる。)
- 外付けにするM.2 SSD (Samsung 970 evo 1Tで成功しました。)
- 外付けUSB SSDケース (ali express等で売られているUSB3.1ケースなど。2000円位)
- 外付けM.2ケース (eGPUケースで代替可能。USBケースのままでもよいが速度的に不利なので最後にこれに変更。)
- WinToUSB 3.9 (3.9で成功しました。)
- Windows.isoファイル。(MSのサイトからこのファイルをダウンロードして落とします。) 
- WindowsSupport (Bootcampのドライバ類。osxのbootcampアプリで落としてきます。)

# 手順
1. 外付けUSB SSDケースにSSDを装着しMacに繋いだのち「Mac OS拡張（ジャーナリング）」「 GUID パーティションマップ」でフォーマットします。
2. Windows10がインストールされたPCに1.の外付けSSDをそのまま接続します。
3. Windows10のディスクの管理からマウントされたSSDの第2パーティションを削除します。（EFIパーティションではない方。）
4. 第２パーティションをNTFSでフォーマットします。EFI側はそのままにしておきます。
5. WinToUSB 3.9を起動します。
6. イメージファイルにWindows.isoファイルを指定し次へボタン。
7. ディスクを選択でUSB接続された外付けSSDを選択します。(USB以外NGです。TB3ディスクは不可)
8. WinToUSBのWizardでNextボタンを押していけば外付けSSDの完成です。
9. Macに外付けSSDを繋ぎ変えてoptionキーを押しながら再起動で外付けSSDから起動します。
10. Windows10が起動したのちbootcampで落としたWindowsSupportのドライバーを入れます。（固まる場合あり。デバイス毎に個別に入れなおした方がよい。）

- 10.で起動時に固まる場合はリカバリモードに入ったのちこのコンピュータを初期状態に戻すでOS丸ごと初期化します。

# SSDの高速化
- USB3.1はすでに規格が古くなってしまった感があります。USB4に移行されるらしい。
amazon.comなどで売られているThunderbolt3対応の外付けM.2ケースを使った方が良いとおもいます。
速度が2800MB/s位でます。ビルドも早くなります。
- GPU用の大型eGPUケースを外付けM.2 SSDドライブにすることも可能です。M.2対応のPCIexのカードを入れます。

# T2チップの問題
- 外付けSSDから起動するためにはT2のセキュリティを解除する必要があります。
Mac起動時にcommand+Rで起動し起動セキュリティユーティリティを使って外部メディアからの起動を許可しておきます。外付け起動が使えないというのは開発環境にとっては悪でしかない気もします。物理的なメディアを超えたクローンが取れないからです。テスト環境で元環境を壊したくない場合があります。

# Samsung 970 evoと970 evo plus
- 最近970 evo plusがリリースされたのですがこれはMac OSで使用するとクラッシュします。まだ解決できていない？
今回SSDは970 evoの方にしました。
信頼があるSSDを使った方があとでソースが全部消えてなくなったという事故を減らせます。
最低限ソースコードのバックアップ対策は必要です。
Macのタイムマシーンなどを用意してもいいと思います。
Rubyの改行はそのまま出力される

## printの引数内で改行すると…？

printの引数で改行するには以下のように「\n」を入れる必要がある。

```Ruby:sample.rb
print("Hello,\nHogehoge\n")
```

んで、以下のコードでこれと同じ出力ができる。

```Ruby:sample_rewrite.rb
print("Hello,
Hogehoge\n")
```
書き方的に汚いと思ったものの、「\n」を複数回挟むことがあるなら有用かも…？

## ひねくれてないで素直に書け

ま、こう書いた方が素直ですな。

```Ruby:print2puts.rb
puts("Hello,")
puts("Hogehoge")
```
GitHub へのアクセスで remote: Invalid username or password と言われたので、git remote set-url でリポジトリを指定した。

Git のローカルリポジトリから push をしたらパスワードを求められて失敗しました。

```Git:
git push origin master
Username for 'https://github.com': pugiemonn
Password for 'https://pugiemonn@github.com': 
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/pugiemonn/pugiemonn.com'
```

あらら、前はこんな表示が出なかったのにおかしいです😭

# GitHub へのアクセスを確認
よくある `ssh -T` で GitHub へのアクセスを確認します。

```
ssh -T git@github.com
Hi pugiemonn! You've successfully authenticated, but GitHub does not provide shell access.
```

successfully authenticated と言われているのに、前述のアクセスはダメみたいです。

# Git の設定を確認
リポジトリ設定を確認します。

```
git remote -v
origin	https://github.com/pugiemonn/pugiemonn.com (fetch)
origin	https://github.com/pugiemonn/pugiemonn.com (push)
```
ぱっと見は合っている気がしたのですがここを変えてみます。

# remote set-url でリポジトリを上書きする
remote の設定を上書きします。

```Git:
git remote set-url origin リポジトリ名
```
こんな書き方なので

```
git remote set-url origin git@github.com:pugiemonn/pugiemonn.com.git
```

# 再び push
push ができるかを確認します。

```
git push origin master
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (7/7), done.
略
```

成功😇


## Git の設定を確認

```
git remote -v 
origin	git@github.com:pugiemonn/pugiemonn.com.git (fetch)
origin	git@github.com:pugiemonn/pugiemonn.com.git (push)
```
書き換わっています。remote の設定がよくなかったみたいです。


# REF
[git \- GitHub: invalid username or password \- Stack Overflow](https://stackoverflow.com/questions/29297154/github-invalid-username-or-password)
GCLB ヘルスチェック早見表

# GCLB ヘルスチェック早見表

GCLB のヘルスチェックにおけるソース IP や対応するヘルスチェックを一覧で見れるよう整理したメモです。

| GCLB リソース | リソースタイプ | カテゴリー | 対応ヘルスチェック種別 | ヘルスチェックソースIP | Proxy/Non-proxy |
|:----------|:---------|:-----------|:--------------------|:--------------------|:----------------|
| HTTP(S)   | Global   | Non-legacy | HTTP, HTTPS, HTTP/2, SSL, TCP | 130.211.0.0/22<br>35.191.0.0/16 | Proxy |
| SSL Proxy | Global   | Non-legacy | HTTP, HTTPS, HTTP/2, SSL, TCP | 130.211.0.0/22<br>35.191.0.0/16 | Proxy |
| TCP Proxy | Global   | Non-legacy | HTTP, HTTPS, HTTP/2, SSL, TCP | 130.211.0.0/22<br>35.191.0.0/16 | Proxy |
| Network   | Regional | Legacy | HTTP, HTTPS | 209.85.152.0/22<br>209.85.152.0/22<br>209.85.152.0/22 | Non-proxy |
| Internal  | Regional | Non-legacy | HTTP, HTTPS, HTTP/2, SSL, TCP | 130.211.0.0/22<br>35.191.0.0/16 | Non-proxy |

* ヘルスチェックには Non-legacy と Legacy とで 2 つのカテゴリーがある
* 対応するヘルスチェック種別およびソース IP は Non-legacy か Legacy かで異なる
* Network Load Balancing は Legacy ヘルスチェックにのみ対応
* Legacy タイプは HTTP, HTTPS ヘルスチェックのみ利用可能
Azure ExpressRoute QA

ExpressRouteを設定する際に、悩んだ点に関するメモ。

# オンプレ側のサーバから、プライベートピアリングで利用可能なAzureサービスは？

ExpressRouteをプライベートピアリングで構成した場合、オンプレ側のサーバから利用できるAzureサービスは何か？

[Azure プライベート ピアリング](https://docs.microsoft.com/ja-jp/azure/expressroute/expressroute-circuit-peerings#azure-private-peering)

ここにあるように、**仮想ネットワークにデプロイできるサービス**であれば、利用可能となる。では、仮想ネットワークにデプロイできるサービスは何か？

[仮想ネットワークにデプロイできるサービス](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-network-for-azure-services#services-that-can-be-deployed-into-a-virtual-network)

ここに記載のAzureサービスを使うのであれば、プライベートピアリングで設定したExpressRoute経由でのアクセスが可能。

（2020/08/11 追記）
Azure Private Endpointを使うと、ほとんどのサービスをプライベートピアリングで使用できる。Microsoftピアリングを使うには、Global IPが必要だったり、オンプレ側のスイッチでNAT設定をしないといけなかったりといろいろ面倒だったので、これは便利そう。

[Azureプライベートエンドポイントとは？](https://docs.microsoft.com/ja-jp/azure/private-link/private-endpoint-overview)

# オンプレ側のサーバから、Microsoftピアリングで利用可能なAzureサービスは？

プライベートピアリングで利用できるAzureサービス以外は、Microsoftピアリングで利用できる。ただし、一部利用できないサービスがある。

[Microsoft ピアリング](https://docs.microsoft.com/ja-jp/azure/expressroute/expressroute-faqs#microsoft-peering)

# Microsoftピアリングで使用するPublic IPは、どうやって入手する？

Microsoftピアリング設定をするためには、/30のサブネットが2個必要。Public IPを自分で持っていれば問題ないが、持っていないなら接続プロバイダーから入手する必要がある。AzureのサービスにPublic IPを取得するサービスとして、[パブリック IP アドレス プレフィックス](https://docs.microsoft.com/ja-jp/azure/virtual-network/public-ip-address-prefix)というサービスがあるが、これを使用することはできないらしい。（MSサポートへの確認済み）
なお、接続プロバイダーとして、EquinixのCloudExchangeを使っている場合、IP Blocks機能でPublic IPの払い出しが可能。ただし、/29のサブネットを1個のみ。複数のシステムを構築するようなときはもっと多くのIPが必要になるが、別途入手しなければならない。
海外であれば、[IPv4Cloud.com](http://ipv4cloud.com/)で購入可能。日本国内で同様のサービスを提供している会社があれば教えてほしい。

# ExpressRouteはプライマリ接続とセカンダリ接続の動作モードは？
ExpressRouteはActive-Activeで動作する。
以下参照：
https://docs.microsoft.com/ja-jp/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections

# 経路障害時の切り替え時間は？
プライベートピアリング、Microsoftピアリング共にBFDを有効にすることで、約1秒で切り替え可能。Azure側はデフォルトでBFDが有効になっているので、ユーザ側のルータでBFDを有効にする必要がある。
参考：
[ExpressRoute 経由の BFD の構成](https://docs.microsoft.com/ja-jp/azure/expressroute/expressroute-bfd)

# オンプレ側のサーバからAzureのサービスにアクセスする際に名前解決するには？
オンプレ側サーバからAzure Storage AccountやAzure Database等のサービスにアクセスするには、IPアドレスではなくFQDNでアクセスする必要がある。このため、DNSによる名前解決が必要。この際にインターネット経由でDNS参照するのではなく、ExpressRoute (Private Peering)経由でAzureのVirtual Network内のDNS（168.63.129.16）に直接アクセスしたい。
しかし、このAzureのDNSにはオンプレ側から直接アクセスできない。このため、DNS ForwarderをVirtual Network内にVM or コンテナで構築し、このDNS ForwarderがAzureのDNS(168.63.129.16)にDNS Queryをフォワードするようにする。そして、オンプレ側のサーバのDNS設定にDNS ForwarderのPrivate IP アドレスを設定することで、ExpressRoute経由での名前解決ができる。
できれば、VMやコンテナではなくAzureのサービスを使いたかったが、Azure DNSはExpressRoute経由でのアクセスはできない・・・

# Azure側からオンプレ側のサーバの監視ができるか？
Azure Monitorを使えば、syslog監視ができる。オンプレ側のサーバにエージェントをインストールする必要があるが。([Syslog data sources in Azure Monitor](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/data-sources-syslog))
Switchの監視はいい方法がない。誰か教えて！
[JavaScript]タッチイベントからoffsetXとoffsetXを取得する

スマホのタッチイベントからoffsetX, offsetYを取得する手法。
忘れがちなのでメモ。

```javascript
        const rect = event.target.getBoundingClientRect()
        const offsetX = (event.touches[0].clientX - window.pageXOffset - rect.left) 
        const offsetY = (event.touches[0].clientY - window.pageYOffset - rect.top)
```
TypeError: $(…).validate is not a functionではまった件

# ライブラリ内の関数が参照できない。。。
- 開発経験無しの初心者が自作Webアプリケーション作成に挑戦してみてはまった点を備忘録がてらに記述しています。
- お気軽にコメント頂けますと幸いです:bow_tone1:
 - 同様の現象ではまり、より詳細な情報が欲しい方
 - 記述内容に関して、より詳細なお持ちの方
 - 記述内容に関して、疑問点がある方

## 対象レベル
- 初学者
  - Webアプリケーション開発経験なし。
  - JavaScriptを用いた開発初体験。

## 発生環境
- PHP Laravelフレームワーク使用。
- jQuery Validation Plugin使用。  
  - http://jqueryvalidation.org  

## 現象
- 以下のコマンドでバリデーション実行。
  - $('セレクタ').validate(ルール);    
- "TypeError: $(…).validate is not a function"のエラーで関数が実行できない。
- validate()関数は、ライブラリ内で定義されている。
- ライブラリ(jQuery.validate.jsファイル)自体は読み込まれている。
- なぜ、、、？

## 原因・解決方法
- スクリプトタグの読み込みタイミングで、はまっていた模様。
- 記述箇所・順序、asyncやdeferを組み合わせ読み込みタイミングを制御することで正常に動作するようになった。  

## 注意点
- JavaScriptでは、読み込む順番・タイミングによってエラーが発生する。
- コピペではだめですね、、、
Day001 webエンジニアへの道 -VirturlBoxの導入から仮想マシンの起動と接続-

はじめまして！
webエンジニアを目指すtomoです。

エンジニアの勉強をしている日々の学びをこれからQiitaに記録していきます。

私自身の頭の整理と今後迷った時のリファレンスも兼ねて書き連ねていきますが、同じようにエンジニア転職を考えている方の参考にもなればと考えています。
また、「ここ間違ってる！こっちが正しい！」といったご指摘もあれば頂けると嬉しいです🙏

それでは、よろしくお願いします！

#バージョン情報
macOS Mojave 10.14.4
iTerm2 3.2.9

##VirtualBoxのインストール
公式サイトからOS X版を選んでダウンロード。
[Download VirtualBox](https://www.virtualbox.org/wiki/Downloads
)

ダウンロードしたパッケージを開き、手順に沿ってインストール。
アプリケーションフォルダ内にVirtualBox.appがインストールされていることを確認。

##Vagrantのインストール
公式サイトからmacOS版を選んでダウンロード。
[Download Vagrant](https://www.vagrantup.com/downloads.html
)

ダウンロードしたパッケージを開き、手順に沿ってインストール。

##仮想マシンを起動する
コマンドラインで仮想マシンを作るフォルダを作成。

```:commandline
$ cd
$ mkdir Vagrant && cd $_  //Vagrantフォルダを作成(名前は任意）
$ mkdir Ubuntu-sun && cd $_  //仮想マシンを作るフォルダを作成（名前は任意。今回はUbuntuを導入、sunと命名）
```

以下のサイトから導入したいVagrantBoxを探してVagrantfileを作成。
今回はubuntu/trusty64を導入します。
[Discover Vagrant Boxes](https://app.vagrantup.com/boxes/search
)

```:commandline
$ vagrant init ubuntu/trusty64  //Vagrant fileを作成
```

Vagrantfileに以下のコードを追記して設定を変更。

```:vagrantfile
### custom setting
# ホストマシンと仮想マシンの時刻を同期する
config.vm.provider :virtualbox do |vb|
   vb.customize ["setextradata", :id, "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled", 0]
end
# ipアドレスの設定（別の仮想マシンと重複しない任意の数であればOK）
config.vm.network "private_network", ip: "192.168.33.10"
# ゲストOSにホスト名を定義（任意の名称でOK）
config.vm.hostname = "Ubuntu-sun"
# ホストマシンと仮想マシンの共有フォルダ設定（それぞれ任意のフォルダパスでOK)
config.vm.synced_folder "~/Works/Current-works/Ubuntu-sun-shared", "/home/vagrant"
# ログイン毎に仮想マシンの公開鍵が変更されないよう設定
config.ssh.insert_key = false
###
```

時刻設定がUTCになっていた場合は以下の処理で日本時間に修正できる。

```:commandline
$ date
  //仮想マシンの時刻を表示
$ sudo rm /etc/localtime
$ sudo ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ date
```

[参考]
[【vagrant】【時刻】ホスト側の時間と一緒にする方法【時間がずれてしまう：初心者】](https://teratail.com/questions/88135
)
[Vagrantにおける仮想マシンの設定 (config.vm)](https://weblabo.oscasierra.net/vagrant-config-vm/
)
[vagrant upコマンド実行時にAuthentication failure.エラーが発生する](https://qiita.com/shyse/items/9ec50b868b90f847c75f
)

仮想マシンを起動する。

```:commandline
$ vagrant up
$ vagrant status  //仮想マシンの状態確認。runningなら起動できている
$ vagrant ssh  //仮想マシンにログイン。デフォルトで設定されているパスワードは”vagrant"
```

##Transmitとの接続
今回、ファイル転送アプリとしてTransmitを使用します。
[Transmit 5](https://panic.com/jp/transmit/)

Transmitは有料のアプリケーションなので、まずはCyberduckという無料アプリを使用してみると良いと思います。
[Cyberduck](https://cyberduck.io/)

Transmitと仮想マシンの接続手順は以下になります。

1. +アイコンをクリックしてサーバリストを追加する。
2. 設定はSFTPでOK。サーバ名はUbuntu-sunとして入力
3. サーバアドレスは先ほど設定した"192.168.33.10"を入力
4. ポート番号は未入力でOK
5. ユーザ名とパスワードは初期設定の"vagrant"を入力
6. サーバリストから"Ubuntu-sun"をダブルクリックで開けば接続完了(接続するため仮想マシンは起動しておいて下さい）

[参考]
[FTP、FTPS、SFTP、SCPの違いってなんなんだ？](https://liginc.co.jp/398039)

##まとめ
以上がVirtualBoxのインストールから仮想マシンの起動と接続まででした。

twitterもやっているので、宜しければフォローお願いします！
[@tomo_tech_](https://twitter.com/tomo_tech_)
Flaskチュートリアル「Step 3: データベースを作成する」で躓いたことのメモ

[Flask Tutorial](https://a2c.bitbucket.io/flask/tutorial/dbinit.html#tutorial-dbinit)
の「Step 3: データベースを作成する」で躓いたので忘れないようにやったことをメモ。

init_db()を実行すると、

```
ValueError: script argument must be unicode.
```
って怒られる。

```
db.cursor().executescript(f.read())
→
db.cursor().executescript(f.read().decode('utf-8'))
```
に書き換えればOK。
must be unicode　って言ってるからunicode(utf-8)に変換して上げればOKってことね。
文字コードは難しい…。

参考：https://ikapblg.blog.fc2.com/blog-entry-81.html



2019/05/05 追記

[Flaskアプリケーションのテスト](https://a2c.bitbucket.io/flask/testing.html)　でも同様の下記エラーが発生。
assert 'No entries here so far' in rv.data
TypeError: a bytes-like object is required, not 'str'

同じように対応すればエラーが起きなくなりました。

``` 
def test_empty_db(self):
    rv = self.app.get('/')
    assert 'No entries here so far' in rv.data
→
    assert 'No entries here so far' in rv.data.decode('utf-8')
```
SQL 本をさら読み

### SQLとは

Structured Query Language

つまり、問い合わせ（DBへ）の言語な

### SQLの種類

- DDL
 
箱を作る（DB）

```
CREATE
ALERT
...
```

- DML

操作する

```
SELECT
INSERT
...
```

- DCL

制約を入れる

```
begin
commit
rollback 
...
```


### 基本構文

```
SELECT karamu
  FROM テーブル
  WHERE 条件
```

- 比較演算子

```
= イコール
<> not
>= 以上とか　※右にイコール!!
```
本番環境にデプロイできない時の対処法（初心者向け）

#AWSで本番環境にデプロイできない時の対処法（初心者向け）
##前提
AWSを利用してwebサイトを公開し、開発したものをデプロイすると本番環境に反映されないことや、サイトが閲覧できない状態（We're sorry ~ ）になることがよくあるので、対処法を解説します。

##開発環境
Ruby 2.3.1
Rails 5.2.2.1
AWS EC2（無料枠使用）
※一旦デプロイが完了し、自動デプロイの設定が完了している前提で解説します。
自動デプロイには、capistranoを使用しています。

###対処法（１）　EC２のインスタンスを再起動
何度も自動デプロイを行なっていると、EC2側で変更が反映されず、場合によっては変更箇所が見れないことがあります。（ex.ユーザーログインの機能を実装したのに反映されていない等）
その場合、AWSのマネージメントコンソールから
EC2 →　インスタンス　→　該当のインスタンスをクリック　→　アクションのインスタンスの状態　→　再起動　を行います。
その後、再度ターミナルからEC2にログインし
``sudo service nginx start　
sudo service mysqld start
``
のコマンドを実行し、WEBサーバのnginxとmysqlを立ち上げます。
その後、ローカルで自動デプロイのコマンドを実行すると、アプリケーションサーバのunicornが立ち上がり、サイト上に変更が反映され、閲覧できるようになります。

###対処法（２） ローカルでエラーが起きていないか確認する
ローカルでは反映されないエラーが、本番ではエラーと認識されることがあります。
例えば、ECサイトを作成し商品一覧は問題なく表示されるが、商品の詳細画面にアクセスするとsyntaxエラー（hamlで記述している場合はインデント等）が起きている場合、本番ではエラーがあると認識されサイト全体が閲覧できないことがあります。
ローカルで確認し、エラーの箇所が分からなければ、サーバー側から
``
less log/production.log
less log/unicorn.log
``　
のコマンドでログを確認し、エラーの箇所を特定します。
ここにsyntaxエラーやFATALと記載されている項目があれば、そのエラーを解消した上で再度デプロイします。
具体的な例としては、gemでfont-awesome-railsを使用していると、記述の方法によって、ローカルでエラーは出ないが本番ではエラーとなることがあり、このようなエラーはログを確認しなければ特定することは困難です。

### 対処法（３）　AWSの無料枠を確認する
直接的なエラーではありませんが、AWSの無料枠（メモリの容量等）を越えるとデプロイできなくなることがあります。
AWSの無料枠はあくまでお試しのような枠なので、同時に２つサイトを公開するとなると容量が足りなくなることがあり、その結果デプロイできないことや変更内容が反映されないことがあります。
また、gemもメモリに影響を与えるので、一度確認しておきましょう。
私の場合、無料枠を利用して２つ目のアプリケーションを公開し、gemのfont-awesome-sassを導入しようとしたら、ターミナルでメモリの容量が足りないというエラーが発生しました。font-awesome-sassを削除し、再度デプロイするとエラーが解消されました。

以上が初歩的な本番環境で発生するエラーの解消方法です。
他にも対処法は多くありますので、参考程度にして下さい。
日時の表示変更をどうするか。

#地味にポートフォリオ作成で詰まった点

・日時の表示変更をどうするか。
![スクリーンショット 2019-05-02 16.28.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/16699e8b-d607-8308-1623-ecc73eb02444.png)
デフォルトではとても長ったらしく日頃あまり見ない日時表記になってしまっている。
ツイッターでこの指摘をしていただいて、この表記はかなり微妙だなと気づいたので
改善に向けて調べて見ました！

↓結果、
`strftime`メソッドを使って変更してみました。

![スクリーンショット 2019-05-02 16.33.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/b14e0a5a-645b-b3df-d5d6-480f95d284b7.png)

`created_at`や上記画像の`updated_at`の後ろに
`strftime('%Y年%m月%d日 %H:%M')`をつけるだけでした。

![スクリーンショット 2019-05-02 16.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/485b8865-da05-4f5c-8982-3cab6ff86daa.png)
このようにスッキリした表記に変わります。

ただ、調べていて思ったのは、
今回は小規模なポートフォリオで作成したアプリなので
上記の方法でも問題ないですが
大規模なアプリの場合はいちいち表記を変更するの大変だと思うので、

・`time_formats` を使う　方法が良さそうな気がします。

方法としては、
まず config/initializers/time_formatsに フォーマットを指定して

```config/initializers/time_formats.rb

Time::DATE_FORMATS[:ymd] = ("%Y年%m月%d日") 
Date::DATE_FORMATS[:ymd] = ("%Y年%m月%d日")
```

その後、
`user.created_at.to_s(:ymd)`
`# => 2016年10月23日`とするとフォーマットが
`initializers/time_formats.rb`に集約されていい感じになるようです。

今度また色々試してみたいと思います。
JSでブラウザの履歴を操作する

## historyについて
JSではhistoryオブジェクトを使用して、ブラウザの履歴を操作することができる
ブラウザの戻るボタンを押した時に戻る場合など、この履歴に応じてページの遷移が行われている
[ブラウザの履歴を操作する](https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history)

## historyは削除できない
追加や変更はできるようだが、historyの削除はできないよう

## 代替案
ケースバイケースだけど、もし消したいと思った場合に使えるかもしれないことがいくつかあったのでまとめ
`A→B→C` の遷移でCから戻る時にAに戻したいというケースを考えてみる(Bを消したい)

### 履歴を残さないで遷移させる
画面遷移時に`location.replace`を使うと履歴が残らないようになる

BページからCページへ遷移する際に使用をすると、Bページの履歴が残らなくなる
そのため、Cページで戻るボタンを押すとその前にいたAページに戻ることができる

画面遷移:`A→B→C`
履歴:`A→C`

```js
// page B →　page C
location.replace('/C/')
```

参考
http://note.onichannn.net/archives/1443

### 履歴書き換えることはできる
前にいたーページをJSを使って書き換えることで、戻るボタンを押したおきにそのページに戻るようにする

`A→B→C`の順番でページの遷移をしている場合、Cページで1つ前の履歴をAページとするとAページに戻れるが、`A→A→C`という履歴になってしまうので注意が必要

画面遷移:`A→B→C`
履歴:`A→A→C`


```js
// Cページで1つ前の履歴をAページとする
history.replaceState(null,null,"/A/");
```

### 戻るボタンクリック時に2つ戻す
戻るボタンをクリックすると、JSで`C→B→A`と遷移をさせる

画面遷移:`A→B→C`
履歴:`A→B→C`


```js
// 戻るボタンを押された時に何も処理を行わない
history.pushState(null, null, null);

// 戻るボタンを押した時の処理を追加
window.addEventListener("pushState", function() {
  // -2で2つ戻る(-1なら1つ戻る)
  history.go(-2);
})
```
NotoSansCJKJPを使ってみてのメモ（Android）

# 仕事でNotoSansCJKJPを使ったので
仕事でデザイナーさんに指定されて、NotoSansCJKJPを使うことが続いたので、メモを残します。
ソースはこちらに。
https://github.com/shinya-takano/NotoSansCjkJpSample

# NotoSansCJKJPのダウンロードからAndroidStudioへの格納まで
- https://www.google.com/get/noto/ からフォントをDLして、zipを解凍します。
- 解凍したotfファイルをresフォルダのfontフォルダに格納します。
- そのままだと大文字と「-」がフォーマット違反なので、キャプチャのようにリネームして格納します。

<img width="374" alt="スクリーンショット 2019-05-02 16.26.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/dd9e974a-ed9c-b8a4-cda6-62e3c8497d10.png">

これで、xmlから使うときは、`android:fontFamily="@font/noto_sans_cjk_jp_regular"`
のように使えます。
ソースから使う場合は、

```
val font = context.resources.getFont(R.font.noto_sans_cjk_jp_regular)
textView.setTypeface(font, Typeface.NORMAL)
```

のようにして使えます。

# いくつかハマったところがあったので、解決策をメモ
そのまま使うと、キャプチャ（サンプルアプリ）の3つめのように元々のフォントの空白が大きく出てしまい、
デザインで指定・イメージしているマージンとだいぶ違う結果になってしまうので、
`android:includeFontPadding="false"` を設定します。
（フォントがNotoSansCJKJPでプロパティをfalseに設定しているのが、4つめ）
![Screenshot_1556781750.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/9dedd692-5c44-ba98-ba29-386e4a999f5e.png)

ちょっとサンプルアプリがわかりにくいのですが、以下の形でまとめています。

| 上から1つめ| 上から2つめ| 上から3つめ| 一番下|
|:--|:--|:--|:--|
| DefaultFont| DefaultFontで includeFontPadding="false"| NotoFont| NotoFontで includeFontPadding="false"|

なお、ViewPagerのタブ文字の場合は、フォント自体がうまく適用できなかったので、
[stackoverflow](https://stackoverflow.com/questions/48258092/how-can-i-change-the-font-on-my-tab-view) を参考に直接フォントを設定します。

```
    private fun changeTabsFont(tabs: TabLayout) {

        val font = this.resources.getFont(R.font.noto_sans_cjk_jp_regular)

        val vg = tabs.getChildAt(0) as ViewGroup
        val tabsCount = vg.childCount
        for (j in 0 until tabsCount) {
            val vgTab = vg.getChildAt(j) as ViewGroup
            val tabChildsCount = vgTab.childCount
            for (i in 0 until tabChildsCount) {
                val tabViewChild = vgTab.getChildAt(i)
                if (tabViewChild is TextView) {
                    tabViewChild.setTypeface(font, Typeface.NORMAL)
                    tabViewChild.includeFontPadding = false
                }
            }
        }
    }
```

# まとめ
NotoSansCJKJPを使う機会がちょくちょく出るので、解決策をメモしておきたかったので、
自分用のメモを作りました。
Linux基本

## プロセス

プロセスは実行中のプログラム
割り込みの概念がある


コマンド

top

## マルチタスク

タスク = プロセス

## プロセスのステータス

STAT:プロセスの状態を表示

```
S スリープやユーザからの入力待ち
D ディスクの入出力待
R 実行可能または実行中
T サスペンドシグナルを送られて実行中断
Z ゾンビ状態
< スケジュール優先度引き上げ
N スケジューリング優先度引き下げ
L メモリのページをロックして利用している
s セッションリーダである
+ フォアグラウンドプロセスグループ


```

### オプション

よく使うやつ

```
オプション a
端末操作のプロセスを表示する。

オプション x
オプション u
ＣＰＵやメモリの使用率なども表示する。

```


https://eng-entrance.com/linux-command-ps

## 記事

https://eng-entrance.com/linux-process



アクセシビリティモニター
http://blog.livedoor.jp/info_clips/archives/27222182.html

## メモリ

- 意味
　記憶領域

- スワップとは？
一時避難メモリ領域　メモリが足りなくなったら使う

- 確認コマンド
 top

##　メモリの分類

- 使用中のメモリ
- キャッシュ
- 空きメモリ
- スワップ

HDD（Hard Disk Drive）

## スワップ

https://webbibouroku.com/Blog/Article/linux-swap



https://qiita.com/kunihirotanaka/items/70d43d48757aea79de2d

### topコマンド使い方

https://orebibou.com/2015/07/top%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E4%BD%BF%E3%81%84%E6%96%B914%E5%80%8B/

### 参考記事
https://qiita.com/zakiyamaaaaa/items/20d4dc4a3d587500e1f1
【CraftCMS】エントリ一覧のページネーション

忘れないうちに今回使った小技を出来るだけ残す。

CMS開発で誰もが苦しむページネーションはCraftCMSなら瞬殺出来ます。

登録日付降順で30件ごとにページネーションしましょうね〜

```twig
{% paginate craft.entries.section("ahiru").orderBy("postDate DESC").limit(30) as pageInfo,pageEntries %}

{# 1エントリずつ出力 #}
{% if pageEntries | length > 0 %}
    <ul>
    {% for detail in pageEntries %}
        <li>{{detail.title}}</li>
    {% endfor %}
    </ul>
{% endif%}
```
ページネーションリンクはこう書きます
全部出力するならloop.indexとか当てたらfor文一発で出来るかなと

```twig
<a href="{{pageInfo.getPageUrl(1)}}"> 1 </a> 
<a href="{{pageInfo.getPageUrl(2)}}"> 2 </a> 
<a href="{{pageInfo.getPageUrl(3)}}"> 3 </a> 
<a href="{{pageInfo.getPageUrl(4)}}"> 4 </a> 
```

現在が何ページ目である情報、何ページ目はあるかどうか等を加味すると
前後にこんな感じで書きます

```twig
{% if pageInfo.getPageUrl(1) %}{% if pageInfo.currentPage == 1 %} 1 {% else %}<a href="{{pageInfo.getPageUrl(1)}}"> 1 </a>{% endif %}{% endif %}
```

現在が何ページ目か・・・・pageInfo.currentPage
 nページ目は存在するか・・pageInfo.getpageUrl(n)

今回はMAX8ページだったのでベタ書きしたけどループでどうにでも行ける書き方もいけますね
（たぶんだけど）
Ubuntuでパソコンを閉じての画面オフからの復帰でタッチパッドが無効化される問題

###画面オフからの復帰時にタッチパッドの入力が無効化される問題
筆者はThinkPad上でUbuntu18.04を使用していますが、パソコンを閉じての画面オフから復帰する際にタッチパッドが無効化されて反応しなくなることがあります。
再起動や再ログインすれば治るのですが毎回それでは大変です。

* キーボードの入力は受け付けるものとします



###解決策
`Ctrl + Alt + t`の同時押しでターミナルを開きます。

```
$ xinput
```
xinputとだけコマンドを実行すると現在の入力のデバイス一覧が表示されます。
自分の場合はこんな感じに表示されました。

![Screenshot from 2019-05-02 16-19-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285516/ec4d37ec-87cf-9d30-ab32-f9a68abe8ba1.png)
id=9のようにそれぞれにid番号が割り当てられているのが確認できます。
そのなかから目的の入力デバイスであろうものを探し以下のコマンドを実行します。

```
$ xinput enable (id番号)
```
再び入力ができるようになります。
自分の場合はid=9の Wacom Pen and multitouch sensor Finger touchをenableにすると治りました。


**(注) 一度disableにしてからenableにしないとうまくいかないことがあります。**

###補足
xinputについての使い方のヘルプは

```
$ xinput --help
```
TensorflowとNumpyを、疑問を解決しながら使ってみる。

#目的
TensorflowとNumpyを、疑問を解決しながら使ってみる。

何年も前から、多くの方が、TensorflowとNumpyの使い方などを報告されています。それらを参考にして、自分が疑問に思った部分などを整理しつつ、後追いしてみます。

当面、利用目的は、CNNの実行とします。

まだ、書きはじめですが、多少、役立つと思う記載は以下。

　　　　　テンソルとは？:candy:
　　　　　しかし、テンソルとは？:candy:

#テンソルとは？
Tensorflowの名前にも入っているtensor（テンソル）とは、なんだろうか？
ネット上で調べると、テンソル自体は、結構、難しいものであることがわかります。Tensorflowと関連づけて、テンソルの説明をされているものも多くありますが、簡単に説明しようとして頂いているが、テンソルの説明だけが、難しくなっていて、Tensorflowに対応づいていない気がします。

自分としては、以下のブログ説明されているように、**「多次元配列」という理解でいい**と思いました。（以下のブログは、説明に成功している気がしました。）

HELLO CYBERNETICS「TensorFlowを始める前に知っておくべきテンソルのこと(追記：より一般的な話題へ)」 
https://www.hellocybernetics.tech/entry/2016/12/01/223834

#しかし、テンソルとは？
最初にこの記事を書いてから1年ぐらいたつのですが、、、、
**突然、テンソルがどういうものかわかった気がします。**
(というか、説明しようとしているサイトで、何を伝えようとしているのかが、わかった気がする。）
説明できるほどには、わかっていませんが、ある分野で、それなりに複雑でキーとなっている技術で、
その領域では、「多次元配列」というような数字の並びではなくて、もっと、意味のあるものだと思う。
しかし、**深層学習とかの領域では、高々、「多次元配列」の理解で問題ない**と思う。

## 突然、Tensorの雰囲気がつかめたサイト

引用元：
https://medium.com/@quantumsteinke/whats-the-difference-between-a-matrix-and-a-tensor-4505fbdc576c

>A tensor is often thought of as a generalized matrix. That is, it could be a 1-D matrix (a vector is actually such a tensor), a 3-D matrix (something like a cube of numbers), even a 0-D matrix (a single number), or a higher dimensional structure that is harder to visualize. The dimension of the tensor is called its rank.
But this description misses the most important property of a tensor!
A tensor is a mathematical entity that lives in a structure and interacts with other mathematical entities. If one transforms the other entities in the structure in a regular way, then the tensor must obey a related transformation rule.


## Tensorの雰囲気がつかめると、Wikiの説明も何となく理解できる

引用元：
https://ja.wikipedia.org/wiki/テンソル

>テンソル（英: tensor, 独: Tensor）とは、線形的な量または線形的な幾何概念を一般化したもので、基底を選べば、多次元の配列として表現できるようなものである。しかし、テンソル自身は、特定の座標系によらないで定まる対象である。個々のテンソルについて、対応する量を記述するのに必要な配列の添字の組の数は、そのテンソルの階数とよばれる。 
例えば、質量や温度などのスカラー量は階数0のテンソルだと理解される。同様にして力や運動量などのベクトル的な量は階数1のテンソルであり、力や加速度ベクトルの間の異方的な関係などをあらわす線型変換は階数2のテンソルで表される。 
物理学や工学においてしばしば「テンソル」と呼ばれているものは、実際には位置や時刻を引数としテンソル量を返す関数である「テンソル場」であることに注意しなければならない。いずれにせよテンソル場の理解のためにはテンソルそのものの概念の理解が不可欠である。 

## さらに、以下の詳細記事とかもなんとなく、理解できるようになる。

以下、**詳しい**です。

「テンソル」とは何か
http://m-ac.jp/me/subjects/linear_algebra/tensor/index_j.phtml

「2.3 「共変・反変」とは何か」の項とか、
**あんまりわかりませんが、なんかを、積み上げようとしている雰囲気は、伝わります。**

#まとめ
テンソルではまったので、まず、ひとこと、記載しました。

#今後
また、何か関連する検討ができれば。
コメントなどあれば、お願いします。:candy:

#関連（本人）
[良書「ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装」を読む](https://qiita.com/enoughspacefor/items/d545b23bd64d285647de)
【Rails】ローカルにないエラーがherokuで表示された時の対処法

「ローカル環境での挙動はバッチリ、さあ herokuへアップロードだ」

と思ったら、アップロード後にはなんのヒントもないエラーページ。

本番環境だとエラー画面のデフォルトが下記のように設定されています。

![スクリーンショット 2019-04-30 7.50.16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331354/00edf2cd-d87d-a258-761a-000361a7b0e6.jpeg)

オリジナルアプリケーション開発で遭遇したシチュエーションをもとに、このような時の解決法を整理します。

# 1.コマンドでログを確認する

```ruby:
heroku logs -t #-tでも-tailでもOK
```

ログを確認すると、

 - 本番環境ではカラムが追加されていない（※`heroku rails db:migrate`で解消）

などのエラー内容ががつかめるはずです。

参考：[Heroku コマンド・設定 メモメモ](https://qiita.com/pugiemonn/items/0e69b7a29a384b356e65)

# 2.アドオン(Papertail)でログを確認する
コメントをいただき知った方法ですが、ご紹介させていただきます。

herokuのadd-onの`Papertail`を利用する方法です。

https://elements.heroku.com/addons/papertrail

導入すると下記のような画面でログの検索や、あらかじめ設定したエラーに対する通知をすることができます。

![スクリーンショット 2019-05-05 15.51.351.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331354/3a4eb57e-5d95-2b9b-6ed6-bbdb5a6c81db.jpeg)

参考:[Herokuにログ管理ツール「papertrail」を導入&利用してみる
](http://vdeep.net/heroku-papertrail)

# ※エラー画面を表示するのはオススメできない

記事公開当初は、「エラー画面を表示する」方法も1つの手だてかと考えていましたが、コメントをいただき、**セキュリティの観点から好ましくない**ということがわかりました。

念のための備忘録ですが、下記の設定ファイルを`false`から`true`に変えることでエラー画面の表示は可能です。

```ruby:config/environments/production.rb
config.consider_all_requests_local = false

```
とは言え、**セキュリティ的に問題もある**かつ**実務でも利用しない方法**とのことなので、利用しない方が良いとの見解に至りました。
「令和元年」を「プログラミング元年」に

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているKentoです。
元号が**平成**から**令和**に変わるタイミングにどこかで変わりたいと思っている自分がいました。
そこで、思い立ったのが**プログラミング**です。
普段はWebマーケティングの業務を務めていますが、こうした業務をこなしながらプログラミングを頑張っているインターンの仲間がいたのもプログラミングを始めるに至った大きな要因です。

具体的な目標はありませんが、**個の力で生きることが要求される令和時代**を生き抜くためにも、少しずつプログラミングを学んでいこうと思います。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#踏み出した第一歩

インターン先のカリキュラムに沿って、まずは**Progate**の**「HTML&CSS　初級編」**から手をつけました。
こうして私のプログラミング元年がスタートしました。

※プログラミングに精通している人からすると、HTMLやCSSは厳密にはプログラミングではないと思われるでしょうがご容赦ください。

プログラミングに初めて触れた率直な感想は「すっげぇぇぇ〜けど、いちいち細かい……」です！！（笑）

自分が打ちこんだコードが形となり、様々なものを駆使すればするほど、見やすく複雑なものになっていくことに感動と達成感を覚えました。
一方で、ちょっとしたスペルのミスや記号一つですぐにエラーを吐かれるので、融通が聞かないなあと苦しみもしました。

#今後について

今後はこのままProgateでHTMLやCSSを学び、それが終わればPHPなどを学んでいこうと思います。
学習を進めていく上で、常に**楽しむ**ということは大事にしていきたいと思います。
Forge式BlockStateを利用してItemのJsonModelを削減する方法

# 概要
例えばmetadataをもつItemを追加するにはそのmetadataの個数(今回は４つ)だけのjsonファイルが必要だったが、それを2個で済ませる(同じModelを使いまわす)方法

#環境
Minecraft-1.10.2
Minecraft-1.11.2
Minecraft-1.12.2

(*試していないだけでおそらく他バージョンでも可)

#追加するJSONファイル
(以下、modidはそのItemを追加するmodのID)

まずassets/modid/models/**block**/に以下のJSONファイルを作る
**このときitemではなくblockのModelの位置に追加するのを間違えないように**

```json:item_generated.json
{
  "parent": "item/generated"
}
```
<details><summary>これは普通の板状に表示されるItemの場合で、ツール等ちゃんと持たせたい場合は**generated**を**handheld**に。</summary>

<details><summary>その他のmodel(自作も含む)の場合も同じようにassets/modid/models/**block**以下に置いてModelを指定すれば使える。</summary>


次にassets/modid/blockstates/に以下のJSONファイルを作る
(variantsには追加するmeta数だけ書き加える)

```json:sample_item.json
{
  "forge_marker": 1,
  "defaults": {
    "model": "modid:item_generated",
    "transform": "forge:default-item",
    "uvlock": true
  },
  "variants": {
    "meta0": [{
      "textures": {
        "layer0": "modid:items/sample_item_0"
      }
    }],
    "meta1": [{
      "textures": {
        "layer0": "modid:items/sample_item_1"
      }
    }],
    "meta2": [{
      "textures": {
        "layer0": "modid:items/sample_item_2"
      }
    }],
    "meta3": [{
      "textures": {
        "layer0": "modid:items/sample_item_3"
      }
    }]
  }
}
```

<details><summary>テクスチャ指定はlayer0, layer1と数字が上がるごとに上に重ねて表示される(何枚いけるのかは不明)。</summary>

#Modelの登録(kotlin)
次は先ほど追加したModelの登録。

```kotlin:ClientProxy.kt
for (i in 0 until 4) {
    ModelLoader.setCustomModelResourceLocation(sampleItem, i,
            ModelResourceLocation(ResourceLocation(modid, "sample_item"), "meta$i"))
}
```

javaの場合も同じように

```java:ClientProxy.java
for (int i = 0; i < 4; i++) {
    ModelLoader.setCustomModelResourceLocation(sampleItem, i,
            new ModelResourceLocation(new ResourceLocation(modid, "sample_item"), "meta" + i));
}
```

#最後に
おそらくModelResourceLocationの第2引数を弄ればBlockと同じように、

```json:sample_item.json
{
  "forge_marker": 1,
  "defaults": {
    "model": "modid:item_generated",
    "transform": "forge:default-item",
    "uvlock": true
  },
  "variants": {
    "meta": {
      "0":{   },
      "1":{   },
      "2":{   },
      "3":{   }
  }
}
```

のような形にもできると思う~~けどめんどくさいからやめた~~。
CodeBuildでの環境変数読み込み

CodeBuildのBuild Spec（buildspec.yml）では環境変数をenvに列挙する必要がある。Build Spec バージョン0.2から各フェーズ（コマンド）間で環境変数を引き継げるようになったため、環境変数をファイルに記載しておき、installフェーズの最初で読み込んでしまうと管理しやすい。

参考：[Shells and Commands in Build Environments](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-cmd.html)

buildspec.ymlの設定例

```yaml
version: 0.2
env:
  variables:
    ENV: test
phases:
  install:
    commands:
      - set -a; for f in env/${ENV}/*.env; do . ${f}; done; set +a
```
【Ruby】コードを少し変えてYARV命令の違いを確認する

# はじめに
自分が書いたRubyのコードがどのような道のりを辿って実行されるのか興味を持ったことはあるでしょうか。

[Rubyのしくみ](https://www.amazon.co.jp/dp/B01IGW56CU/)によるとRubyコードは以下の流れでYARV命令へと変換されます。

```markdown
Rubyコード
↓
字句解析
↓ 
構文解析
↓ 
コンパイル
↓
YARV命令
```

この記事では、YARV命令の部分をピックアップし、YARV命令がコードによってどう変わるのか簡単に見ていきます。


なお、今回利用したRuby処理系、Rubyバージョンは以下の通りです。

| Ruby処理系 | Rubyバージョン |
|:-:|:-:|
| MRI |2.6.1|

# YARV命令表示

まず、YARV命令を表示してみます。

簡単なRubyのコード `4 + 3` のYARV命令をみてみましょう。YARV命令は `RubyVM::InstructionSequence` を使うことで見ることができます。

```irb
irb(main):001:0> puts RubyVM::InstructionSequence.compile('4+3').disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,3)> (catch: FALSE)
0000 putobject                    4                                   (   1)[Li]
0002 putobject                    3
0004 opt_plus                     <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 leave
=> nil
```

`putobject`でスタックに値をプッシュし、`opt_plus`で加算を実行するのが確認できます。

すなわち、以下の流れでコードが実行されます。

1. `4`をスタックにプッシュ
2. `3`をスタックにプッシュ
3. 加算（`4 + 3`）

# `4 + 3 * 2` vs `(4 + 3) * 2`

続いて、`4 + 3 * 2`と`(4 + 3) * 2`のYARV命令を表示して結果を比べてみます。

```irb
irb(main):001:0> puts RubyVM::InstructionSequence.compile('4+3*2').disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,5)> (catch: FALSE)
0000 putobject                    4                                   (   1)[Li]
0002 putobject                    3
0004 putobject                    2
0006 opt_mult                     <callinfo!mid:*, argc:1, ARGS_SIMPLE>, <callcache>
0009 opt_plus                     <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0012 leave
=> nil
```
```irb
irb(main):001:0> puts RubyVM::InstructionSequence.compile('(4+3)*2').disasm
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,7)> (catch: FALSE)
0000 putobject                    4                                   (   1)[Li]
0002 putobject                    3
0004 opt_plus                     <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 putobject                    2
0009 opt_mult                     <callinfo!mid:*, argc:1, ARGS_SIMPLE>, <callcache>
0012 leave
=> nil
```

上記2つを比べると`opt_plus`の位置が変わっていることに気がつきます。

それぞれ以下の流れでコードが実行されます。

・　`4 + 3 * 2`

1. `4`をスタックにプッシュ
2. `3`をスタックにプッシュ
3. `2`をスタックにプッシュ
4. 乗算（`3 * 2`）
5. 加算（`4 + 6`）

・ `(4 + 3) * 2`

1. `4`をスタックにプッシュ
2. `3`をスタックにプッシュ
3. 加算（`4 + 3`）
4. `2`をスタックにプッシュ
5. 乗算（`7 * 2`）

命令の順番によって、計算結果が変わることが確認できます。


# まとめ
コードを少し変えることでYARV命令がどう変わるのかみてきました。
普段YARVの内部スタックの状態を意識することはなかったですが、より深いところまで理解できるよう知識を深めていきたいものです。