OmniAICreator/Qiita-1.07M huggingface dataset:
トップレベルのループと関数内のループの違い

# 動機

「[競技プログラミングで Python を使う時は関数にしよう](https://qiita.com/takecian/items/10bca93004ca9d7dd138)」という記事を見て、トップレベルに処理を記載した場合：

```loop_toplevel.py
for i in range(10**7):
    pass
```

と、関数内に処理を記載した場合：

```loop_function.py
def main():
    for i in range(10**7):
        pass
main()
```

で大きな性能差があることを知りました。実際に時間を測ってみると

```
$ python3 --version
Python 3.7.2
$ time python3 loop_toplevel.py
python3 loop_toplevel.py  0.66s user 0.02s system 95% cpu 0.712 total
$ time python3 loop_function.py
python3 loop_function.py  0.39s user 0.01s system 97% cpu 0.418 total
```

と確かに有意な差が出ることが確認できます。

この差異はどこから来ているのでしょうか？違いを理解するために、まずはコードを逆アセンブルして、Python VM上で実行されるバイトコードの差異を確認しましょう。

## 関数の逆アセンブル

「[dis --- Python バイトコードの逆アセンブラ](https://docs.python.org/ja/3/library/dis.html)」を使うと、関数の逆アセンブルができます。関数の中に処理を書いたほうだと

```
>>> from loop_function import main
>>> type(main)
<class 'function'>
>>> import dis
>>> dis.dis(main)
  2           0 SETUP_LOOP              16 (to 18)
              2 LOAD_GLOBAL              0 (range)
              4 LOAD_CONST               1 (10000000)
              6 CALL_FUNCTION            1
              8 GET_ITER
        >>   10 FOR_ITER                 4 (to 16)
             12 STORE_FAST               0 (i)

  3          14 JUMP_ABSOLUTE           10
        >>   16 POP_BLOCK
        >>   18 LOAD_CONST               0 (None)
             20 RETURN_VALUE
>>>
```

と逆アセンブルすることができます。

## モジュールの逆アセンブル

モジュールを対象にして `dis.dis` を呼ぶと

```
>>> import loop_toplevel
>>> type(loop_toplevel)
<class 'module'>
>>> import dis
>>> dis.dis(loop_toplevel)
>>>
```

あれれ？何も表示されません。

`dis.dis` のヘルプを見ると、

```
Disassemble classes, methods, functions, and other compiled objects.
```

と説明されていて、モジュールが対象として書いてない代わりに、コンパイルしたオブジェクトが対象に入っています。

というわけで、ソースを読み込んでコンパイルしてみます。

```
>>> f = open('loop_toplevel.py')
>>> s = f.read()
>>> c = compile(s, 'loop_toplevel', 'exec')
>>> c
<code object <module> at 0x10af69930, file "loop_toplevel", line 1>
```

これでコンパイルしたものが得られたので逆アセンブルすると

```
>>> import dis
>>> dis.dis(c)
  1           0 SETUP_LOOP              16 (to 18)
              2 LOAD_NAME                0 (range)
              4 LOAD_CONST               0 (10000000)
              6 CALL_FUNCTION            1
              8 GET_ITER
        >>   10 FOR_ITER                 4 (to 16)
             12 STORE_NAME               1 (i)

  2          14 JUMP_ABSOLUTE           10
        >>   16 POP_BLOCK
        >>   18 LOAD_CONST               1 (None)
             20 RETURN_VALUE
```

と結果が得られました！

## 結果の比較

逆アセンブルした結果を見比べると

| loop_function.py | loop_toplevel.py |
|---|---|---|
| LOAD_GLOBAL | LOAD_NAME |
| STORE_FAST | STORE_NAME |

という違いがあります。

rangeに与える整数、すなわちループの回数を大きくすると、実行時間の差も大きくなることが見れるので、実行時間の差に効いているのはループ内、つまりFOR_ITERとJUMP_ABSOLUTEの間にあるSTORE_FASTとSTORE_NAMEの違いであることがわかります。

それぞれに対するVMの処理を比較すればもう少し詳細を理解できるはずですが、今回はバイトコードの差異まで見れたのでここまでにしておきます。

→ 「[Python VMのプロファイル](https://qiita.com/yoichi22/items/8eb876264456d1898206)」でVMの処理のプロファイルをしてみました。
Rails じゃなくて Ruby で直接 erb テンプレートを利用して HTML を文字列で得る一番簡単な例 ( #ruby )

# ファイル

some.erb

```
<%= message %>
<%= name %>

```

# ruby

- File を ERB.new に渡して 変数を binding する
- 引数も渡さずに変数が反映されているのが不思議だが、bindingってそういうことらしい

```rb
require 'erb'

message = 'hello!'
name = 'Alice'

erb = File.read('some.erb')
# => "<%= message %>\n<%= name %>\n"

ERB.new(erb).result(binding)
# => "hello!\nAlice\n"
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2641








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Node.js（express）を用いたハッシュ化の仕方

## はじめに
　会員登録の際に、ユーザーから送られてきたパスワードをハッシュ化する方法について解説します。
また、ログインの際にユーザーが入力したパスワードとハッシュ化されたパスワードが一致しているのか確認する必要があると思います。それについても解説します。

## 実装
### 事前準備
　まずはNodeにハッシュ化するためのモジュールをインストールします。

```
npm install --save bcrypt -s
```
### パスワードをハッシュ化する

```hash.js
const bcrypt = require('bcrypt');
//モジュールの読み込み
const password = "hoge";
let hashed_password = bcrypt.hashSync(password, 10);
```
以上でパスワードのハッシュ化が行えます。

### ハッシュ化された値とパスワードの値の一致の確認

```hash.js
bcrypt.compareSync("hoge", hashed_password) // =>ture
```
第一引数に確認文字列、第二引数にハッシュ化したパスワードを入れることで、真偽値が返ってきます。

### 参考
- [[Node.js]Expressでパスワードのハッシュ化を行おう](https://qiita.com/tatsumi44/items/83ac5c18f213e22ed322)
Tinderで右スワイプを自動化！

#Tinderで右スワイプを自動化！

こんにちは！けーすけです！

第一回はTinderの右スワイプ自動化です！
男性の皆さん。おそらく全力無心で右スワイプをしていることでしょう。
その時間を有効に活用できたらいいなーって思いませんか？
**プログラミングでできちゃうんです。**
今回はそんな夢のような機能を実装していきます！
引用元：天才プログラマーKboyさん(https://twitter.com/kboy_silvergym)

##実装していきましょう

めちゃくちゃ大変そう。。と思ってしまったでしょう。
###書くのこの5行だけです。
とりあえずこの5行貼り付けたら動きます。笑

```javascript:tinderAutoSwipe.js
setInterval (
  function () {
    const elem = document.getElementsByClassName("rescGamepad__button");
    elem[3].click();
  }, 1000) 
```
###コード解説
setInterval(a, b)何かを定期的に実行する。
* 第一引数：定期的に実行したい処理
* 第二引数：処理のインターバル(bミリ秒)

今回は第一引数に`いいね!ボタン`をクリックする動作、第二引数に`1000ミリ秒`を入れております。
=>1秒に一回いいねボタンを押す。

getElementByClassName({取得したいクラス名})
*この名前を持つすべての子要素を取得できる。
=>Tinderの下に並んでいる5つのボタンの配列を取得。

elem[3]取得してきた配列のインデックス番号3を指定。

click()これがクリックされた際に発火。

##それでは試してみましょう！
注：pcでやってね

まずはTinderサイト画面で右クリック　→　検証を選択　→　検証画面のConsoleを選択

###ここに先ほどのコード書いて(貼り付けて)行きます！
<img width="1440" alt="スクリーンショット 2019-10-30 21.01.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456901/07d155ed-0322-42b0-7434-31c46b15bfc6.png">

enterを押すと。。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/sJO2gzcO9W">pic.twitter.com/sJO2gzcO9W</a></p>&mdash; けーすけ＠丸メガネエンジニア (@K_941226) <a href="https://twitter.com/K_941226/status/1189530330820009986?ref_src=twsrc%5Etfw">October 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



できました

以上Tinderの右スワイプ自動化でした！
ご閲覧ありがとうございました。
classやnameの属性取得によってテキストボックスへ値を代入する方法

### 経緯
Webフォームのテストで毎回手入力するのが面倒だったので、１回実行すれば要素を取得して必要な項目を全部埋めてくれるスクリプトを作ろうと考えた。

# idは単数系 / classやnameは複数形
てっきりgetElementByIdのようにclassやname属性についても『getElementBy〜』で要素を取得できるのかと思ったがサジェストされないことに気づく。
単数系と複数形の違いは何なのだろうと思い調べたらこんな記事を見つけた。

[class属性とid属性の役割の違い](https://allabout.co.jp/gm/gc/23897/2/)
idが一意であるのに対して、classは再利用前提の考え方とのこと。
デザイナーが二つをどう使い分けてるのか理解できて納得。

# 複数形なら配列として各要素を取得する
そして本題。
class属性（nameも同様）の要素は複数形が基本であることから、『配列』として全体を見る必要があることが分かる。一度しか登場しない属性であっても下記のような記述でないといけない。

```javascript:
document.getElementsByClassName("hoge")[0].value = "fuga";
document.getElementsByName("foo")[0].value = "bar";
```
同じclassやnameが画面内に複数回登場するなら配列のインデックスを変えるだけ。
ラジオボタンやプルダウンでも要素を取得してあとはcheckedやselectedIndexを呼び出せばいいだけ。

他にもquerySelectorやquerySelectorAllっていうjQueryライクな汎用性の高いメソッドもあるそうだからそっちも使ってみよ。
データベースとSQLについて

SQL：リレーショナルデータベース（RDB）の操作を行うための言語

SQLを学ぶ理由：データの削除、更新、検索について学習する必要がある。

データの登録
→INSERT文
例）
INSERT INTO テーブル名 VALUES(値1, 値2, 値3);
INSERT INTO テーブル名(カラム名1, カラム名2) VALUES(値1, 値2);
の２種類ある

入力したデータの確認方法としては
SELECT * FROM　テーブル名
で行う

データの更新
→UPDATE文
例）
UPDATE テーブル名 SET 変更内容 WHERE 条件;
herokuでLINEbot @ ラズパイ

ラズパイにherokuインストール
https://qiita.com/sunaga70/items/593ddb3e1eb36774bc5d
https://qiita.com/arashida/items/b2f2e01259238235e187
https://qiita.com/shimajiri/items/cf7ccf69d184fdb2fb26

途中
文字列から指定した文字列の左側・右側のみ抽出する関数

# 文字列から指定した文字列の左側・右側のみ抽出する関数

VBAのLeft関数とRight関数に少し手を加えた関数を作成しました。

以下のような使い方をします。

```
bar = right_get("aaabbbccc","bbb") 'bar="ccc"が入る
bar = leght_get("aaabbbccc","bbb") 'bar="aaa"が入る
```

## 文字列から指定した文字列の右側のみ抽出する関数
```
Function right_get(ByVal FULL_TXIT As String, ByVal DELIMITER As String) As String
' 文字列から、指定した文字列の右側のみ抽出する関数

    'FULL_TXIT 抽出元の全文
    'DELIMITER 区切り文字

    Dim ANS '戻り値
    Dim FULL_TXIT_LEN '抽出元の全文の文字数
    Dim DELIMITER_LEN '区切り文字の文字数
    
    FULL_TXIT_LEN = Len(FULL_TXIT)
    
    DELIMITER_LEN = Len(DELIMITER)
    
    ANS = Right(FULL_TXIT, FULL_TXIT_LEN - InStr(FULL_TXIT, DELIMITER) - (DELIMITER_LEN - 1))
    
    right_get = ANS
    
End Function
```

## 文字列から指定した文字列の左側のみ抽出する関数

```
Function left_get(ByVal FULL_TXIT As String, ByVal DELIMITER As String) As String
' 文字列から、指定した文字列の左側のみ抽出する関数

    'FULL_TXIT 抽出元の全文
    'DELIMITER 区切り文字
  
    Dim ANS '戻り値
    Dim FULL_TXIT_LEN '抽出元の全文
    Dim DELIMITER_LEN '区切り文字
    
    FULL_TXIT_LEN = Len(FULL_TXIT)
    DELIMITER_LEN = Len(DELIMITER)
    
    ANS = Left(FULL_TXIT, InStr(FULL_TXIT, DELIMITER) - 1)
    
    left_get = ANS
    
End Function
```
Linuxサーバのインシデント調査で多用するコマンド

インシデント対応で多用するけど、忘れがちなコマンドをまとめ

##目次
[プロセス単位でCPUの使用率が高い順に表示](#プロセス単位でcpuの使用率が高い順に表示)
[プロセス単位でMemoryの使用率が高い順に表示](#プロセス単位でmemoryの使用率が高い順に表示)
[Unitを指定したjournal logの確認](#unitを指定したjournal-logの確認)


##プロセス単位でCPUの使用率が高い順に表示

```
[root@host ~]# ps axu --sort -%cpu

Option
a:端末を持つ全てのプロセスを表示する
x:端末を持たない全てのプロセスを表示する
u:ユーザー指向のフォーマットで表示する (CPUやMemoryの使用率をわかりやすく表示)
--sort -%cpu:CPUの使用率が高い順に出力
```


##プロセス単位でMemoryの使用率が高い順に表示

```
[root@host ~]# ps axu --sort -%mem

Option
a:端末を持つ全てのプロセスを表示する
x:端末を持たない全てのプロセスを表示する
u:ユーザー指向のフォーマットで表示する (CPUやMemoryの使用率をわかりやすく表示)
--sort -%mem:Memoryの使用率が高い順に出力
```

##Unitを指定したjournal logの確認
コマンド例としてsshd Unitのjournal logを参照している
主にprocessの再起動前後のlogなどを確認する際に使用

```
[root@host ~]# journalctl -u sshd

Option
-u:unit名を指定してjournal logを出力
```
MySQL クライアントツールで "password" という単語が含まれる行がヒストリに残らない件

MySQL の CLI クライアントツール（以後 MySQL CLI）を使用中に "password" を含む行がヒストリに残らなくてイライラした事がある人も少なくないと思います。開発環境等では ```~/.mysql_history``` にパスワードが残ってしまうリスクより利便性を優先したい所ですし、そもそも "password" という文字列が含まれるだけでヒストリに残りませんので、思わぬ場面でこの機能が邪魔になる事もあります。

この問題を解決するためのメモです。

## 解決方法

これを解決するためには、ソースコードを修正してコンパイルしなおすか、バイナリを書き換える以外に方法が無いです。今回はバイナリ書き換えで対応しました。以下のコマンドを実行し、新しい MySQL CLI を作って下さい。

```bash
cat `which mysql` | 
  perl -pe 's/\*(IDENTIFIED\*:\*PASSWORD\*)/\0\1/' > ~/mymysql && 
  chmod 755 ~/mymysql
```

あとは標準の mysql コマンドの代わりに新しく作ったバイナリ（上記の例では ```~/mymysql```）を使うだけです。

## これしか方法が無い理由

MySQL CLI には ```MYSQL_HISTIGNORE``` という環境変数、または ```--histignore``` オプションを参照し、ここに設定された文字列をヒストリに残さない仕組みがあります。詳細は以下をご覧下さい。

 * https://dev.mysql.com/doc/refman/5.6/ja/mysql-logging.html

ならば ```MYSQL_HISTIGNORE``` を意図的に空にしてやれば "password" が含まれる文字列もヒストリに残るのではないかと思いますが、そうは行きません。なぜなら ```MYSQL_HISTIGNORE``` の設定値は、ハードコーディングされた値 ```*IDENTIFIED*:*PASSWORD*``` に追加する形でしか登録されないからです（```*``` はワイルドカード、```:``` はデリミタです）。この辺のソースは以下の部分です。

 * MySQL 5.7
  * https://github.com/mysql/mysql-server/blob/5.7/client/mysql.cc#L1366
 * MySQL 8.0
  * https://github.com/mysql/mysql-server/blob/8.0/client/mysql.cc#L1359

というわけで、初期値の文字列を直接書き換える事で対応させました。

## 最後に

ずっと気になってたのですが軽微な問題なので放置してました。別件で MySQL のソースを利用している最中なので、改めて確認してみたら上記の通りで、環境変数やオプションでどうにか出来る問題ではない事が分かってしまいました。

ところで何のためにこうなっているかですが、ヒストリを記録する ```~/.mysql_history``` にパスワード等の秘匿情報を平文で残さないための配慮である事は言うまでもありません。個人的にはこれによって得られるメリットは特に開発環境等において少ないと思っているのですが、リスクと利便性のトレードオフは各自で判断して下さい。
初心者によるプログラミング学習ログ 141日目

# 100日チャレンジの141日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

141日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>141日目です<br><br>技術書で架空のwebサイト構築メインコンテンツ部分<br><br>cssをsassで書いてみる<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</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/%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></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1187841371060654081?ref_src=twsrc%5Etfw">October 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
WindowsでCakePHP開発していたらbin/cakeが動かない！？

# bin/cakeコマンドが動かない！？

PHP開発するならやはりUNIXベースのmacOSをおすすめしますが、
windowで開発する人もやはりいるでしょう。

僕もwindowsのvisual studio codeで開発することがあります。

例えばvisual studio codeのターミナルで以下のコマンドを打ったとしましょう。

```
bin/cake bake model
```

データベースからbakeできるテーブル名の一覧を取得できるコマンドです。

通常は

```
Mails
Items
Users
```

みたいにテーブル名称が返ってきます。

だけどwindowsでやると、、

```
'bin' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

となるのです。


一瞬、ビビるのですが、なんてことはありません。

**bin/cake**を**bin\cake**にしてあげればいいだけです。
（スラッシュとバックスラッシュの違い）

```
bin\cake bake model
```
```
Mails
Items
Users
```

これで通常通り、windowsでもbin/cakeコマンドが動くようになりました。

## まとめ

windowsの場合

```
bin\cake
```

macの場合

```
bin/cake
```


参考までに。
【Unityエディター拡張】シーンビューの3Dカメラをマウス位置に合わせて拡大縮小する

####概要
Unityシーンビューの2Dモードでは標準に搭載されているマウス位置に合わせたカメラの拡大縮小機能を、3Dモードでも実装するエディター拡張です。イラストソフトなんかでは標準的なカメラの操作が非常にしやすい機能。これで捗る。
<img width="400" alt="gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522357/77a423bd-4a5c-9da9-7975-feb0f8f29bad.gif">
標準機能っぽいのに調べても出てこなかったので自分で作りました。これだけのソースですがUnityの仕様に振り回されて大分苦労した…正確な計算は面倒だったのでしてません。拡大位置にズレはありますが、おおむね動作するかと思います。
####TraceSceneViewCamera.cs
```cs
//Unity 2018.4.11f1
//	このスクリプトをプロジェクト下に置くだけで実行されます。
//	エディター拡張機能なので Editor フォルダに置くと良いです。

using UnityEngine;
using UnityEditor;

[InitializeOnLoad]
static public class TraceSceneViewCamera
{
	static TraceSceneViewCamera()
	{
		//シーンビュー上のイベントを取得するためのメソッドを追加
		//			※この方法でないとメソッド内で全イベントが取得できない
		SceneView.onSceneGUIDelegate += onSceneGUIDelegate;
	}

	static private void onSceneGUIDelegate(SceneView scene)
	{
		//3Dモード時にマウススクロールにトレースする
		if (scene.in2DMode)
			return;
		if (Event.current.type != EventType.ScrollWheel)
			return;

		var camera = scene.camera.transform;

		//カーソルの画面中央からの差を計算
		var center = new Vector2(scene.position.width, scene.position.height) * 0.5f;
		var difference = Event.current.mousePosition - center;
		difference.x = difference.x / center.x * 0.1f;
		difference.y = -difference.y / center.y * 0.1f;

		//カメラの中心を拡大率に比例してカーソル方向に動かす
		var pivot = scene.pivot;
		pivot += camera.up * difference.y * -Event.current.delta.y * scene.size * 0.2f;
		pivot += camera.right * difference.x * -Event.current.delta.y * scene.size * 0.2f;

		scene.LookAtDirect(pivot, Quaternion.LookRotation(camera.forward));
	}
}
```
Redash v8で追加されたアラートカスタマイズ機能


この記事ではRedash v8で追加されたアラートのメッセージカスタマイズ機能について書いていきます。  

## 再追記(v9でのアラートカスタマイズ機能の記事も書きました)

https://qiita.com/k-tomoyasu/items/405a8afb404909c06162

## 追記
- 次期リリースv9でのアラート機能の改善点を公式がまとめていました
https://blog.redash.io/v9-alerts-improvements/

## はじめに
Redash v8がリリースされました。今回のリリースでアラート機能に関するコントリビュートができたので、その機能について書いていきます。  

## TL;DR
- Redash v8でアラート機能にクエリの実行結果を入れてメッセージをカスタマイズする機能が入った
- v8時点ではデフォルトOFFになっており、使うには環境変数で有効化する必要がある
- v9に後方非互換な変更があるので注意が必要

## アラートメッセージのカスタマイズ機能
Redashにはクエリの実行結果が設定した閾値を超えた際に、メールやslackに通知するアラート機能があります。
手軽にちょっとした監視ができて便利なのですが、通知されるメッセージの情報量が少なく、アラートが鳴っていることしか分かりませんでした。そのためクエリの実行結果を見る手間がかかったり、アラートのシリアスさが伝わりづらかったです。
v8で追加されたアラートメッセージのカスタマイズ機能では、クエリの実行結果を埋め込んだ任意のメッセージを送るテンプレートを作ることができます。  
なお[User Guide](https://redash.io/help/user-guide/alerts/custom-alert-notifications)に機能説明がありますが、こちらはv9についての説明になっており、(ホスティング版では既に使える)v8のものとは異なります。

### 機能
v8時点ではデフォルト無効化されており、環境変数`REDASH_FEATURE_EXTENDED_ALERT_OPTIONS=true` で有効化されます。
これはこの機能がまだ実験段階で、UX改善を計画しているためです。masterブランチでは既に色々と改善・変更が行われています。
テンプレートは[{{mustache}}](https://mustache.github.io/)で書くことができ、次の変数にクエリの実行結果、アラートの状態が割当てられています。 

*v8のテンプレートで使える変数*

|  変数名  |  値  | 型 |
| ---- | ---- | ----|
| state   |  アラートの発火状態 | string
| rows | クエリ実行結果の各行  |value array
| cols | クエリ実行結果の各カラム  |value array

### 実行例
`target` 列、 `rate` 列を実行結果に含むクエリのにアラートを設定します。
閾値などを設定し、テンプレートを次のように書きます。

```
ターゲット : 売上前日比
{{#rows}}
{{target}} : {{rate}}%
{{/rows}}
```
アラート編集画面
![編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/a3b1640d-8f6b-665f-596f-8494faeba14d.png)

実行結果が閾値を超えるとSlackにスクショのように通知されました。  
Slackへの通知
![slack](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/64eb9459-824e-3fd1-550c-e383ce6ce527.png)
### レポーティング的な使い方
閾値はクエリ実行結果の先頭行の指定カラムの値と比較されます。
常に1以上の値が入るカラムや文字列が入るカラムを指定カラムにして「greater than 0」のような条件にしておくと毎回アラートがなりカスタムメッセージが送られます。これを利用してレポーティングや簡易のスナップショットのような使い方もできそうです。
## v9の後方非互換な差分
v9ではカスタマイズ機能を含めアラート編集画面のUIががっつり改修されています。少し見た感じでも使いやすくなっていると感じました。ただし、カスタマイズ機能についてはv8と非互換な変更があるので、v8でこの機能を使う場合は注意が必要です。
v9ではクエリ実行結果などが割り当てられている変数の名前が変わっています。このため、v8時点で作成した変数を含むテンプレートはv9では期待通りに動きません。  

*v9のテンプレートで使える変数*

|  変数名  |  値  | 型 |
| ---- | ---- | ----|
| ALERT_STATUS   |  アラートの状態(OK, NG, UNKNOWN) | string
| ALERT_CONDITION|  オペレータ  |string
| ALERT_THRESHOLD|  閾値  |string or number
| ALERT_NAME|  アラート名  |string
| ALERT_URL|  アラートのURL  |string
| QUERY_NAME |  クエリ名  |string
| QUERY_URL |  クエリのURL  |string
| QUERY_RESULT_VALUE | 監視対象の最新の値  |string or number
| QUERY_RESULT_ROWS | クエリ実行結果の各行  |value array
| QUERY_RESULT_COLS | クエリ実行結果の各カラム  |value array

## 最後に  
v8で作ったテンプレートがv9で機能しなくなる可能性を考えると、アラートを大量に作るような使い方をするとマイグレーションのコストが高くなることに注意する必要があると思います。
[Redash meetup](https://redash-meetup.connpass.com/event/141830/)のLTでこの機能を作り始めてマージするまでの話を発表させていただきました。 
[speaker deck](https://speakerdeck.com/fusuma/redasharatofalsezui-jin-kasutamaizuji-neng-wozuo-tutahua)
この記事を書くにあたって最近のRedashのプルリクを覗くと、アラート画面のUIが刷新されていたり、ついに[Python 3](https://github.com/getredash/redash/pull/4251)になっていたりと活発な開発が続いていて、既に次のリリースが楽しみです。Redashにはとてもお世話になっているので、また何かコントリビュートしていきたいです。
誕生日当て問題

###Ruby誕生日当て問題
##仕様
①私の誕生日を当ててね！
数字を入力してね！(1~31まで)
2(terminal入力)

②ハズレだよ〜、ヒントをあげるね！
私の誕生日は15日以下だよ！
3(terminal入力)

③またまたハズレだよ〜ヒントをあげるね！
私の誕生日は奇数だよ！
5(terminal入力)

④惜しいけどハズレだよ〜ヒントをあげるね！
私の誕生日は6日~10日以下だよ！
※5日刻みで設定
7(terminal入力)

⑤あと一歩！ヒントをあげるね！
私の誕生日は[9, 10, 11]のどれかだよ！
※答え+-2の範囲からランダムに3日表示する
9(terminal入力)

⑥やったね！最後まで考えてくれてありがとう！
or
⑥'全部外れたねwwwどんまい！正解は9日でした〜また遊んでね！

※1~31以外の数字を入力すると、「その値は無効だよ！」と表示され終了します。
※途中で正解したら、「なんでわかったの！？天才！正解だよ☆」と褒めてくれます。

##押さえておきたいポイント
1.randメソッド
　乱数、つまりランダムな数値を生成してくれるメソッド。
　rand(5)とすると0から4までの数値になりますが、rand(1..5)は1から5までの数値になるので注意。

2.sampleメソッド
　配列の要素を1つランダムに返してくれるメソッド。配列が空の場合はnilを返します。
　また、sample(3)のように引数に整数を指定すると、その数だけ要素をランダムに取り出し配列で返します。要素の順番もランダムになります。

3.to_iとto_sメソッドの使い分け
　to_iメソッド　→　文字から数値
　to_sメソッド　→　数値から文字

##これが私の精一杯です。
もっとコードをスッキリさせる方法を教えてください。

```ruby

puts "私の誕生日を当ててね！\n数字を入力してね！(1~31まで)"
  birth = rand(1..31)
  yosoku = gets.to_i

def yosoku7(birth,yosoku)
  if birth == yosoku
    puts "なんでわかったの！？天才！正解だよ☆"
  elsif birth != yosoku
    hint = [birth , birth + 1 ,birth - 1,birth + 2,birth -2]
    puts "あと一歩！ヒントをあげるね！"
    puts "私の誕生日は" + hint.sample(3).to_s + "日のどれかだよ！"
    yosoku8 = gets.to_i
    if yosoku8 == birth
      puts "やったね！最後まで考えてくれてありがとう！"
    else
      puts "全部外れたねwwwどんまい！正解は#{birth}日でした〜また遊んでね！"
    end
  end
end

def yosoku5(birth,yosoku)
  if birth == yosoku
    puts "なんでわかったの！？天才！正解だよ☆"
  elsif birth != yosoku
    puts "惜しいけどハズレだよ〜ヒントをあげるね！"
    if birth <= 5
      puts "私の誕生日は5日以下だよ！"
      yosoku6 = gets.to_i
      return yosoku7(birth,yosoku6)
    elsif birth > 5 && birth < 11
      puts "私の誕生日は6日~10日以下だよ！"
      yosoku6 = gets.to_i
      return yosoku7(birth,yosoku6)
    elsif birth > 10 && birth < 16
      puts "私の誕生日は11日~15日以下だよ！"
      yosoku6 = gets.to_i
      return yosoku7(birth,yosoku6)
    elsif birth > 15 && birth < 21
      puts "私の誕生日は16日~20日以下だよ！"
      yosoku6 = gets.to_i
      return yosoku7(birth,yosoku6)
    elsif birth > 22 && birth < 32
      puts "私の誕生日は21日~31日以下だよ！"
      yosoku6 = gets.to_i
      return yosoku7(birth,yosoku6)
    else 
      puts "値が無効だよ！"
    end
  end
end


def yosoku3(birth,yosoku)
  if birth == yosoku
    puts "なんでわかったの！？天才！正解だよ☆"
  elsif birth != yosoku
    puts "またまたハズレだよ〜ヒントをあげるね！"
    if birth % 2 == 0 && birth < 32
      puts "私の誕生日は偶数だよ！"
      yosoku4 = gets.to_i
      return yosoku5(birth,yosoku4)
    elsif birth % 2 != 0 && birth < 32
      puts "私の誕生日は奇数だよ！"
      yosoku4 = gets.to_i
      return yosoku5(birth,yosoku4)
    else 
      puts "値が無効だよ！"
    end
  end
end
    

  if birth == yosoku
    puts "なんでわかったの！？天才！正解だよ☆"
  elsif birth != yosoku && yosoku < 32
    puts "ハズレだよ〜、ヒントをあげるね！"
    if birth < 16
      puts "私の誕生日は15日以下だよ！"
      yosoku2 = gets.to_i
      return yosoku3(birth,yosoku2)
    elsif birth > 15 && birth < 32
      puts "私の誕生日は15日より上だよ！"
      yosoku2 = gets.to_i
      return yosoku3(birth,yosoku2)
    else 
      puts "値が無効だよ！"
    end
  else
    puts "値が無効だよ！"
  end
```
サイト埋め込みはVimeoとYouTubeどちらが良い？

#はじめに
サイト埋め込みはVimeoとYouTubeどちらが良いでしょうか？
Webサイトに動画を埋め込みたいケースはよくあると思います。自社やサービスの紹介にも動画を使う企業が増えてきました。
そこで、今回はサイト埋め込みに使う動画サービスとしてVimeoとYouTubeを比較してみたいと思います。


#Vimeoとは？

[公式：Vimeoについて]
(https://vimeo.com/jp/about)

Vimeoは日本ではあまり知名度がありませんが、一早くHD動画を導入した動画サービスです。
投稿者にアーティストやクリエーターが多く、投稿される動画はクリエイティブなものがほとんどです。
Vimeoという名前はVieoとMeを組み合わせた造語で、Movieのアナグラムにもなっています。
また、投稿ポリシーは厳しく、転載や自身が作ったものでないと判断された場合は動画を削除されてしまいます。ゲームのプレイ動画や他人が作った映像をクリッピングしたものも基本的に禁止されています。



#Vimeoの特徴
1.
まず、動画サイトの大きな特徴としては基本一切広告が入らないことです。Vimeoには、インストリーム広告やオーバーレイ広告といった広告が存在しません。常に広告に邪魔されず動画を見る機会を提供できます。
また、関連動画に他者の動画が表示されることもありません。

2.
公開範囲の設定がしやすい。
単なる公開＆非公開だけでなくパスワードによる動画閲覧制限が可能です。
さらに、商用の有料プランを利用すれば、より詳細なプライバシー設定が可能になります。再生可能ドメインまで指定できるため、自社サイト内や会員サイト内など自由に視聴者を絞ることができます。
更には、ダウンロード可否も任意で設定できます。昨今、YouTube用のダウンロードツールなども流通しており、動画を保存されるケースも多いですが、こちらは容易に複製することが難しくなっています。

3.
埋め込みプレイヤーの見た目を好みに応じて変えられます。プレイヤーの色を変えたり、ボタンの表示・非表示、更には、Vimeoのロゴを消して自社サービスのロゴを入れたりすることも可能です。（ロゴ消しは有料プランのみ）



#YouTubeの特徴

1. ユーザー数
YouTubeは日本だけでなく世界的に有名な動画サイトです。
ネット人口の8割が見ているとされており、「ユーチューブの世界の月間ログイン視聴者数は19億人で、日本では6200万人だった。」と日本経済新聞で報じられました。（2018/7/6 16:20）記事より
（https://www.nikkei.com/article/DGXMZO32703140W8A700C1X30000/）

また総務省の最新統計でも、日本国内の10代～20代のYouTube利用率は約90％で、全年代平均でも66.7％に達しているとされています。つまり、より多くの人に動画を視聴してもらいたい場合、“バズ”を起こしたい場合、YouTubeは不可欠な存在なのです。

平成 2７年情報通信メディアの利用時間と情報行動に関する調査より
　　

2. SEOに強い
YouTubeは現在Google傘下のサービスであり、SEOに大変強い特徴があります。
YouTube動画は特にGoogleの検索エンジンにて上位に表示されやすくなっているため、視聴者を獲得する機会を非常に得易いと言えます。
　　

3. 動画広告
特定のターゲットに確実に動画を届けたい場合は、動画広告が有効と言えます。
YouTubeはユーザー規模が大きいため一部をターゲットとしても、相当の規模を担保できます。動画開始5秒後にスキップが可能になるTrueView動画広告はプレロール広告の代表格として多く企業に活用されています。
　　

#両社比較・まとめ


上記のような特徴から、新規ファンの獲得など多くの人に動画を届けたい場合には、YouTube上で動画を公開し、広告配信やSEOも積極的に行っていくことが得策といえるでしょう。

一方、自社サイトなどに動画を埋め込み、すでに一定の関心を持っている潜在顧客にしっかりと動画を視聴してもらいたい場合、あるいはブランドの世界観をより大事にしたい場合はVimeoの方が使いやすいと言えます。

動画マーケティングを展開する企業は、どちらか一方を選択する必要はなく、1つひとつの動画の目的や使い方によってYouTubeとVimeoを使いわけることが大切でしょう。
iPadのSwift PlaygroundsでもSwiftUI書けるじゃん！

# TL;DR
[Swift Playgrounds](https://apps.apple.com/jp/app/swift-playgrounds/id908519492?ign-mpt=uo%3D4) v3.1以上ならSwiftUIが書ける。

![スクリーンショット 2019-10-30 14.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149055/f3eb7a19-789d-b86a-fbd0-deff0485c403.png)

# 注意点
Swift Playgroundsで実装したViewをliveViewで表示するには、以下のように書く必要がありますね。

```SampleForUIKit.swift
import UIKit
import PlaygroundSupport

class MyViewController: UIViewController {
    // 省略
}

PlaygroundPage.current.liveView = MyViewController()
```

liveViewで表示するためには`PlaygroundLiveViewable`なるプロトコルに準拠したclassでなければならないそうです。
SwiftUIのviewはこのプロトコルに準拠していないようなので、SwiftUIで用意されている`UIHostingController`を使うことでliveViewで表示できるようになります。

```SampleForSwiftUI.swift
import SwiftUI
import PlaygroundSupport

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }
    }
}

PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())
```

ほらこの通り。
![BDB1DE83-37FD-43A1-AB2A-AD14AB103D62.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149055/cf55d851-9fb2-1f71-ae8b-c182ecb33798.png)


※ContentViewのコードは[公式のチュートリアル](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)を引用しています。

# ひとこと
SwiftUIが出たもののiOS 13以降でないと使えないため、プロダクトでサポートするOSバージョンを考えるとあと2〜3年は使えないなぁ……と思いほとんどキャッチアップしていませんでした。
とはいえ、カジュアルにSwiftUIを書いていければいざ移行する時に早いのでは？と思いふとSwift Playgroundsで `import SwiftUI` と書いたら……なんと！！

これで気軽にスイスイSwiftUIできますね(๑•̀ㅁ•́๑)✧

# 参考
- https://developer.apple.com/documentation/playgroundsupport/playgroundliveviewable
- https://developer.apple.com/documentation/swiftui/uihostingcontroller
- https://developer.apple.com/tutorials/swiftui/creating-and-combining-views
- https://qiita.com/owen/items/73473cd2206afda3c5d4
CentOSにnvmインストールしたnodeが再起動時には扱えなくなる現象の解決

#概要
普段はReact NativeでiOSアプリを開発してます
今回は、CentOS内でnvmでインストールしたnodeコマンド利用ができなくなった現象を解決した流れのメモを共有します

```
[vagrant@localhost ~]$ node
node: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.17' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by node)
[vagrant@localhost ~]$ 
```
上記のようなエラーが吐かれnodeが利用できません

#解決策
nvmでインストールしたnodeをデフォルトでの利用をさせるようにします

```
[vagrant@localhost ~]$ which node
/usr/bin/node


[vagrant@localhost ~]$ nvm alias default v6.14.4
default -> v6.14.4
#ここで重要なのは上記のように、対象nodeバージョンの値にvをつけることです

[vagrant@localhost ~]$ which node
~/.nvm/versions/node/v6.14.4/bin/node
```

これで再起動してもnvmからのnode利用が行えるようになりました
ユーザー新規登録備忘録 part1：複数ページをまたいで行う新規登録の時のデータの流れ~sessionの使い方~ 

## やりたいこと
  - 某フリマアプリにて新規登録STEP1~STEP3の３ページで入力した情報を経由してデータベースに出力する
  ![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/fe3d2916-5d57-ad78-75f4-80efd75242d5.png)

  ~~~rb:SignupController
  def step1
    @user = User.new # 新規インスタンス作成
  end

  def step2
    # step1で入力された値をsessionに保存
    session[:nick_name] = user_params[:nick_name]
    session[:email] = user_params[:email]
                      [省略]   
    @user = User.new # 新規インスタンス作成
  end

  def step3
    # step2で入力された値をsessionに保存
    session[:phone_number] = user_params[:phone_number]
    @user = User.new # 新規インスタンス作成
  end
                      [省略]   
  ~~~


  - **session**に送るのは最初の２ページだけ!!
 
~~~rb:
nick_name: session[:nick_name], 
email: session[:email],
                      [省略]   
~~~

  - 最後のページは**user_params**で呼び出す
 
~~~rb:
building_name: user_params[:building_name],
phone_number2: user_params[:phone_number2]
                      [省略]   
~~~
### 完成イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/2887e1f2-5c88-8c45-8004-7f485da272e9.png)

====================================================================================

~~~rb:SignupController完全版
class SignupController < ApplicationController
  def step1
    @user = User.new # 新規インスタンス作成
  end

  def step2
    # step1で入力された値をsessionに保存
    session[:nick_name] = user_params[:nick_name]
    session[:email] = user_params[:email]
                    [省略]  
    @user = User.new # 新規インスタンス作成
  end

  def step3
    # step2で入力された値をsessionに保存
    session[:phone_number] = user_params[:phone_number]
    @user = User.new # 新規インスタンス作成
  end

  def create
    @user = User.new(
    # sessionに保存された値をインスタンスに渡す
    〜〜〜〜１ページ目から２ページまでで入力したデータ〜〜〜〜
      nick_name: session[:nick_name], 
      email: session[:email],
                      [省略]   
      〜〜〜〜3ページ目で入力したデータ〜〜〜〜
      address: user_params[:address],
      building_name: user_params[:building_name],
      phone_number2: user_params[:phone_number2]
                      [省略]
~~~
What's "Node.js" ?

よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。

>勉強中の関連記事まとめ
>[自分用の勉強記事をまとめた目次　~擬似知識体系~](https://qiita.com/oekaki-hoho-ron/items/3194f560efc461ec03b0)

#Node.jsとは

スケーラブルなネットワークアプリケーションを構築するために設計された非同期型のイベント駆動の JavaScript 環境

- サーバーサイドJavaScript
- 非同期
- イベントドリブン
- シングルスレッド

>参考文献
>[Node.js公式サイト](https://nodejs.org/ja/)
>[Node.js を5分で大雑把に理解する](https://qiita.com/hshimo/items/1ecb7ed1b567aacbe559)

大量のリクエストを高速で捌くためのプラットフォーム。Node.js単体でもWEBサービスを作れるが、基本的には大規模システムの大量のリクエストを高速に捌く必要のあるAPIやメッセージングなどに利用される。

Node.jsは頻繁にバージョンアップされるため、公式サイトのAPIドキュメントの内容をよく読む必要がある。使える命令にも要不要や安定不安定といった変遷があるので、ドキュメントのStabilityという基準を参考にする。

#「ノード」の由来

節、結び目、結節点、集合点、中心点、中継点、拠点などの意。つまり樹形図の各節点のこと。おそらくNode.jsでいうノードはサーバーサイドのPC、クライアントサイドのPCなどのことを指す。それらをWEBアプリの本体であるサーバーサイドから操作するJavaScriptライブラリということ。

>参考文献
>[ノード【node】 - weblio辞書](https://www.weblio.jp/content/%E3%83%8E%E3%83%BC%E3%83%89)

#Apacheについて

Node.js以前の大量のリクエストを捌くシステムの処理形式としてスレッドモデルといものがあり、Apacheなどで使われていた。しかし、スマホなどによりインターネットが一般的になってからはリクエスト処理が追いつかなくなり、今度はイベントループという処理形式が採用される様になった。Node.jsはイベントループを採用している。

#nodeの実行

ターミナルで`node`と実行すればインタラクティブはjs環境が起動する。ただしこの方法ではブラウザを使うわけではないので、WindowやDOMに関する命令は使えない。

.help
.exit　nodeを閉じる

###簡単なnodeアプリ

```zsh
mkdir myapp
cd myapp
vim hello.js    // console.log("Hello World");と記述
node hello.js

> Hello World
```

#ノンブロッキング処理とコールバック関数

Node.jsでは時間のかかりそうな処理は後続の処理をブロックしないような書き方をする。
AWS環境改善メモ

# 前置き
- 基本の部分は情報あるけど、アカウントの分け方はあまり記事としてまとまってない

# 基本
- 親アカウントは1つだけど、子アカウントを色々作れるよ
- 子アカウントを適切に分けて作ると便利だよ

## Organization
- 親AWS account id = 契約（請求はここでまとまる）

## Unit
- 親アカウントから複数の子アカウントを作るだけでなく、グループ分けができるようになった
- ユニットは、作って階層構造の切り替えが比較的容易にできる
- ユニットにはSCPを設定できる

### 例
- UnitA <- SCP1
  - account1
  - account2 
- UnitB <- SCP2 → IAM
  - account3
  - account4 
- UnitC

## SCP(サービスコントロールポリシー)

- Allow
- Deny

## アカウントの分け方
- アカウントをサービスごとに作る
- ユニットを環境ごとに分ける

### 例
- Unit Service - 本番
  - account-Service-A
  - account-Service-B
- Unit Sandbox - 開発環境
  - account-Service-A-dev
  - account-Service-B-dev

## ユニットやアカウントを分けるメリット
- 各サービスごとのコストが正確にわかる

# IAM Role

## 例
- role
  - reader（読み取り）
  - developer（全部読み取り、一部書き込み）
  - admin
  - analyser
  - poweruser（読み取り、一部書き込み）
- user
  - tanaka
  - yamada
  - suzuki  

## asume-role
- tanakaがreader, developerのroleになれる権限を持っている
- ユーザーはポリシー・権限を持たない。どのロールになれるかだけを持つ
- クロスアカウント設定を許可できる
 - サービスごとに複数のアカウントを切り替えてログインする必要がなくなる

# 理想のユニット構成
親アカウントにmasterのroleを付与（各サービスアカウントに最上位の権限を付与するため）
→これが漏れるとまずいので封印が必要 

- OU - admin
  - employee
  - log
     - 各環境にあるログを監視するのはあまり良くない
     - S3にログを集約
     - ≒ Athena → BI, シームで可視化
- OU - service
  - service1
  - service2
- OU - sandbox
  - service1-dev
  - service1-qa
  - service1-stage 
- OU - network
  - transit
     - transit gatewayを作るためだけのアカウント
- OU - office(仮)
  - office 
     - 社内用。TGを使ってサービスとの相互通信もできる
     - 監視もできる

## 相互通信
- サービス間の相互通信をグローバルネットワーク経由でやるべきではない
- transit gatewayを経由して、プライベートネットワークでやる

## 自宅から
- transitアカウントで認証して、グローバルネットワークを使わずに完結できる

# どうやって理想に持っていくか
## 第一段階
### AWS CLI
1. Organization作成
1. Unitを作成
  - service
  - admin 
1. 子ID作成 → Unitに移動
  - service1
  - service2
  - service3
1. 監査系 IAM VPC 流す

### CloudFormation
1. 既存アカウントのassume-role設定

## 第二段階
- employee化（クラウドフォーメーションを流す）

# 移行が終わったら？
- アプリケーションコードの改良

# 移行の壁
- yaml書くのだれる
- デバッグ面倒
- 設計して、コード書くのが大変
- 最新機能はAPIだけだったり、CLIしかなかったりする
- CloudFormationでできるのはその後

# 関連記事
- [AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888)
GitHubDesktopとGitHub

GitHubDesktop ：自分のPC内で管理しているデータ。
　　　　　　　　＝ローカルで管理している。

ローカルリポジトリ：自分のPC上に置くリポジトリの事。

リポジトリ：Gitの管理元にあるファイルやフォルダの変更履歴を保管するもの。

ブランチ：リポジトリで管理しているデータ、サービスの流れを記録していく所、枝

ーーーーーーーーーーーーーーーーーーーーーーーーーーー

GitHub :グーグルクロムで見れるネット上に上げられたデータ、ネット上にあげる事でチームで開発を行なっていったり多くの人に見てもらったりする事もできる。

リモートリポジトリ：ネットワーク上に置くリポジトリ複数人で共同でアプリを作れる。

コンフリクト：日本語で混乱、例えばAがあるデータ1.0verを修正しようとした時、Bが同じデータ1.0verを先に修正してしまいデータのバージョンが変わってしまったため起きてしまう現象

プルリクエスト：変更した所について説明文等のコメントをつけること

LGTM： 「Looks good to me」の略
　　　 翻訳すると「自分的にはOKだよ」という意味
　　　 メンターに確認して貰った時これから何度となく見るだろう・・・


他it用語
push（プッシュ）： 情報を送る
pull（プル）： 情報を受信する
What's "nvm" ?

よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。

>勉強中の関連記事まとめ
>[自分用の勉強記事をまとめた目次　~擬似知識体系~](https://qiita.com/oekaki-hoho-ron/items/3194f560efc461ec03b0)

#nvmとは

Node Version Managerの略で、Node.jsをダウンロードしてインストールするするツール

nvmはMac OSXで使えるnode.jsのバージョンマネージャー

複数のバージョンのNode.jsをシステムにインストールしたい場合、またはバージョンをアップグレードしたい場合以外は、nvmは必要ありません。

node.jsのバージョンを好きなものに切り替えるツール

>[nvm公式サイト](https://github.com/nvm-sh/nvm)
Zapierを用いたTwitter→Discordの連携方法（特定ユーザのツイート）

#目次
1. 前提条件
2. ZapierでZap（連携レシピ）の作成

#前提条件
#### Discord
- アカウントを持っていること
- サーバを持っていること（管理者権限が必須？筆者は自身が作成したサーバを利用）

#### Twitter
- アカウントを持っていること

#### Zapier
- アカウントを持っていること（フリープランでOK）

#ZapierでZap（連携レシピ）の作成①（Twitter側）
1. Zapierのホーム画面から「Make a Zap!」ボタンをクリック
2. ***Choose App & Event*** で「Twitter」を入力
3. Choose Trigger Event で「User Tweet」を入力
4. 「continue」をクリック
5. ***Choose Account*** > Twitter account で自分のTwitterアカウントを連携
6. ***Customize Tweet*** で対象のユーザIDを入力（@xxxxx）
7. 「continue」をクリック

#ZapierでZap（連携レシピ）の作成②（Discord側）
1. ***Choose App & Event***で「Discord」を入力
2. Choose Action Eventで「Send Channel Message」を入力
3. 「continue」をクリック
4. ***Discord account***で自分のDiscordアカウントを連携とサーバを選択
5. ***Customize Channel Message*** > Channelで受信するチャンネルを選択
6. Message Textで受信する情報（Tweet内容、時刻等）を選択（右上の「+」アイコンから選択可能）
7. Bot Name でDiscordのチャンネルに表示されるユーザ名を指定
8. Bot Icon でDiscordのチャンネルに表示されるアイコンを指定
9. TEST & CONTINUEでDiscord側にTweetが表示されたら完了

#参考
https://das-gaming.com/index.php/2018/06/09/discord_tweet/
便利そうなCSSメモ

## 概要
便利そうなCSSメモです。

## scroll-behavior
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="sakas" data-slug-hash="MWWEObJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Scroll-Behavior">
  <span>See the Pen <a href="https://codepen.io/sakas/pen/MWWEObJ">
  Scroll-Behavior</a> by saka (<a href="https://codepen.io/sakas">@sakas</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

[scroll-behavior](https://developer.mozilla.org/ja/docs/Web/CSS/scroll-behavior)

[scroll-behavior - Can I use ...](https://caniuse.com/#search=scroll-behavior)

Chrome、Firefox対応済み、Edgeは76からサポート、Safariは未対応


## はみ出した文字の省略

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="sakas" data-slug-hash="pooWdeE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Truncation Test">
  <span>See the Pen <a href="https://codepen.io/sakas/pen/pooWdeE">
  Truncation Test</a> by saka (<a href="https://codepen.io/sakas">@sakas</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

- text-overflow(単一行)
- line-clump(複数行)

[text-overflow - Can I use ...](https://caniuse.com/#feat=text-overflow)

[line-clump - Can I use ...](https://caniuse.com/#search=line-clamp)

line-clumpは最新バージョンで各ブラウザ対応してるみたいです。(IE以外）
[ゼロから作るDeep Learning]誤差逆伝播法理解のために計算グラフについて解説してみた

#はじめに
この記事は**ゼロから作るディープラーニング 6章誤差逆伝播法**を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。

#誤差逆伝播法を用いた勾配式
前回の記事で実装したニューラルネットワークの勾配式は、各パラメータに微量な値の増加をして偏微分を求めて勾配を出していました。(数値微分)
しかし、数値微分は単純で実装もしやすいですが、処理が遅いという欠点があります。DeepLearningには相当な時間がかかるので、できる限り時間を省略できる工夫をしていかなくてはいけません。
そこで用いられるのが、誤差逆伝播法を用いた勾配式です。

これを用いることで、処理にかかる時間を大幅に短縮することができます。ですが、実装がかなり複雑になるので、実装に手間取ったりミスが起こってしまいます。それがデメリットです。

まず、誤差逆伝播法を理解するには**計算グラフ**というものを理解することが一番の近道と言えます。
これから計算グラフについて解説していきます。


#計算グラフとは
計算グラフというのは計算をニューラルネットワークの構造のように層の形にして表し、各ニューロンにはその計算に使う関数を入れて入力層には関数に入る変数の値が入ります。
言葉だと理解するのが難しいので、図にしてみます。

**一つ100円のリンゴを３つ買う時の合計金額を求めよ。なお消費税は10%とする。**
<img width="633" alt="スクリーンショット 2019-10-30 16.51.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510602/75bb95b9-3ab4-20dc-be75-00a055c65644.png">

上のように計算を分けて層の形にして順番に解いていくのを計算グラフと言います。

そして、計算グラフを左から右に解いていく、上の例でいうと合計金額を求める処理を**順伝播処理**と言います。
計算グラフを右から左に解いていく、各関数の変数の微分を求めることを目的とした処理を**逆伝播処理**と言います。
手元の.NET Core 3.0 Preview環境をReleaseにアップデートしたら、ビルドで`error MSB4236`が発生した

# 状況
.NET Core 3.0 Preview SDKから、Release版にアップデートした環境で、`dotnet new`したプロジェクトを`dotnet build`すると、error MSB4236が発生した。

```
C:\workspace>dotnet new console -n someproject
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on someproject\someproject.csproj...
  C:\workspace\someproject\someproject.csproj の復元が 47.43 ms で完了しました。

Restore succeeded.

C:\workspace>cd someproject
C:\workspace\someproject>dotnet build
.NET Core 向け Microsoft (R) Build Engine バージョン 16.3.0+0f4c62fea
Copyright (C) Microsoft Corporation.All rights reserved.

C:\workspace\someproject\someproject.csproj : error MSB4236: 指定された SDK 'Microsoft.NET.Sdk' は見つかりま せんでした。

ビルドに失敗しました。

C:\workspace\someproject\someproject.csproj : error MSB4236: 指定された SDK 'Microsoft.NET.Sdk' は見つかりま せんでした。
    0 個の警告
    1 エラー

経過時間 00:00:00.05
```

`dotnet --list`で表示されるパスには、ファイルは有りそうだった。

古い.NET Core 2.2 SDKをアンインストールして、さらに.NET Core 3.0 SDKをアンインストールした後に再インストールしたが、状況に変化なし。
PCを再起動しても変わらない。

#  原因
[ここらへん](https://github.com/microsoft/msbuild/issues/2532)を見てたら、環境変数`MSBuildSDKsPath`について言及されていた。
結構前に、vscodeでビルドするためだったかWindowsDesktopをビルドするためだったかで追加していた。

```
MSBuildSDKsPath=C:\Program Files\dotnet\sdk\3.0.100-preview7-012821\Sdks
````

.NET Core 3.0 はインプレースアップデートなので、

`MSBuildSDKsPath`を消したら無事ビルドできた。
ユーザー新規登録備忘録 part2：新規登録時のdate_selectタグとsessionの組み合わせの使い方メモ


## sessionを用いてdate_selectで取得したデータをUserテーブルに情報を送る

### 某フリマアプリでユーザー登録の際に日付のデータの情報を送れなくてつまづいたので備忘録。

![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/dedbb8ce-a1a0-d105-7843-97e57f23446b.png)


#### date_select部分の情報だけはuser_paramsだと日付を持っていけない!?
<img width="478" alt="スクリーンショット 2019-10-30 17.42.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/cf03e960-a1b5-ea7d-385c-a3fc64978086.png">

#### paramsだったら持ってこれた!!
<img width="845" alt="スクリーンショット 2019-10-30 17.42.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/f36c846f-2881-f314-6e6f-1512e39bf49d.png">



### 修正後
~~~rb:修正後
class SignupController < ApplicationController

  def names
    @user = User.new # 新規インスタンス作成
  end

  def telephones
    binding.pry//日付を取得できるか確認する
    # namesで入力された値をsessionに保存
    session[:nick_name] = user_params[:nick_name]
    session[:email] = user_params[:email]
    session[:password] = user_params[:password]
              [省略]
    session["birthday(1i)"] = params[:birthday]["birthday(1i)"] //user_paramsではなくparamsを使う
    session["birthday(2i)"] = params[:birthday]["birthday(2i)"] //user_paramsではなくparamsを使う
    session["birthday(3i)"] = params[:birthday]["birthday(3i)"] //user_paramsではなくparamsを使う
    @user = User.new # 新規インスタンス作成
  end
  
  [省略]
  
    # 許可するキーを設定します
  def user_params
    params.require(:user).permit(
      :nick_name,
      :email,
      :password,
      [省略]
      :birthday,
      [省略]
    )
  end
~~~

## 解決方法
paramsで見つかった

#####参考
  - [【Rails】date_selectタグの使い方メモ - Qiita](https://qiita.com/ozackiee/items/3c027d07cdeb61df6029)
  - https://teratail.com/questions/162913
macOSにbrewでcoq_jupyterをインストールする

# 1. 概要

以下の環境でJupyter上でCoqが使える環境を構築する。
（Anacondaは使わない）

* macOS Catalina
* Homebrew
* Python3
* Jupyter
* Coq 8.10.0


# 2. ソフトウェアのインストールと初期化

brewのインストールはこのページを参照。
[Homebrew](https://brew.sh/index_ja)

以下のコマンドを実行する。

```
brew update
brew upgrade
brew install python3
brew install coq
pip3 install --upgrade pip
pip3 install jupyter
pip3 install coq-jupyter
python3 -m coq_jupyter.install
```

# 3. Jupyter notebookの起動

以下のコマンドを実行する。

```
jupyter notebook
```

ブラウザからlocalhost:8888をアクセスすると、Jupyterを起動したディレクトリのファイル一覧が表示される。Mac版のJupyterでは、デフォルト設定でログイン画面は表示されない。

# 4. 付録
## 4.1 チュートリアルの取得

Coqのチュートリアルをcloneでとってくる。そのディレクトリ下でjupyterを起動すると便利。

```
git clone https://github.com/maruyama097/coq-tutorial.git
cd coq-turorial
jupyter notebook
```

## 4.2 Jupyter Labの導入

以下の手順でJupyter Labをインストール、起動することができる。
Jupyter LabからCoqを使用できる。

```
pip3 install jupyterlab
jupyter lab
```

以上
Nuxt x Monaca x Android でビルド時のみローディングから進まなかったTips

# この記事について
タイトルの通りで、nuxtで実装したものをMonacaにもっていったところ、iOSやMonacaデバッガーでは動くのに、ビルドしてAndroid端末にインストールするとうまく動かないということがありました。その対応です

# 調査
うまく動かないというのは、アプリが立ち上がったあとNuxtのローディングのまま進まないという状態になりました

logCatで確認すると、
`E/AndroidProtocolHandler: Unable to open asset URL: file:///android_asset/www/_nuxt/bac0a27cb58f83031038.js`

index.htmlからの初っ端の.js読み込みに失敗していました。
そして調べていくと、Phonegapではローカルリソースのパスはセンシティブという記事を見つけました。

# やったこと
ということで、
dist の中にできる
`_nuxt` の名称を変えたら、それだけでAndroidでも動くようになりました

``` nuxt.config.ts抜粋
build: {
    publicPath: '/mynuxt/',
    extend(config, ctx) {
      config.output.publicPath = 'mynuxt/'
    }
  }
```
admin.auth().setCustomUserClaimsは上書き

掲題の通り。
例えば、

``` javascript
userRecord.customUserClaim//=>{oldClaim:true} 
```
の時に

``` javascript
admin.auth().setCustromUserClaim(userId,{newClaim:true});
```
とすると、完全にClaim情報が上書きされて``oldClaim:true``の部分が消えてしまう。

# 対処法
updateClaimのようなメソッドがあればよかったのだが、そういうものはないので一度取得してから追記する

``` javascript
admin.auth().setCustomUserClaim(userId,{...userRecord.customUserClaim,newClaim:true});
```
venv が動かないときの対応の一例

# 状況
`python -m venv $HOME/venv/3.6.8` などとしても、

```
Error: Command '['/home/tabaru/venv/3.6.8/bin/python', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
```

となり、venv の設定ができない。

# 環境
* `icc --version` とすると、Intel compiler が動く。
* `python --version` とすると、 `Python 3.6.8 :: Intel Corporation` などと出力される。python 3系は python3 としないと呼ばれないはずなのに。
* Ubunt 18.04 だが、おそらく distribution は無関係。
* Intel compiler の設定を直前に行っていた。

# 原因
環境変数 PATH 中で Intel python の bin ディレクトリが先に書かれていたため、distribution の python コマンドが呼ばれていなかった。これにより、色々不具合が出ていた模様。

# 対策
PATH から Intel python のディレクトリを削除。
これにより、 `python3 -m venv $HOME/venv/3.6.8` でエラーなく環境を作れた。
vagrant upでGuestAdditions seems to be installed (6.0.14) correctly, but not running. The following SSH command responded with a non-zero exit status.

# Vagrant upしたら、共有フォルダがマウントされなくなった
先日まで、普通に使えていた仮想環境（vagrant）が突然エラーを吐いて、共有フォルダをマウントしてくれなった...

おそらくMacOSをCatalinaにしたことが原因だと思われる？

```:console
$ vagrant up
...
...
GuestAdditions seems to be installed (6.0.4) correctly, but not running.
...
...
（省略）
...
...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

 setup

Stdout from the command:


Stderr from the command:

bash: line 3: setup: command not found
```
というエラーでハマり、他にも同じハマり方してる方がいる中、ググって出てきた方法を試してもなかなか解決しなかったので、備忘録的にまとめることにしました。（祝 初投稿!!）
## TL;DR
```
vagrant plugin list
==> vagrant: A new version of Vagrant is available: 2.2.6 (installed version: 2.2.3)!
==> vagrant: To upgrade visit: https://www.vagrantup.com/downloads.html

vagrant-vbguest (0.17.2, global)
```
Vagrantfileに下の３行を追加するだけで解決

```
if Vagrant.has_plugin?("vagrant-vbguest")
   config.vbguest.auto_update = false  
end
```

・サンプル

```:Vagrantfile
Vagrant.configure(2) do |config|

（省略）

　　 if Vagrant.has_plugin?("vagrant-vbguest")
    config.vbguest.auto_update = false  
　　 end
end
```
追加後に

```
$ vagrant reload --provision
```

この方の記事が全く同じ境遇に出会っていて、解決方法が見つかりました
こちらの記事の方が詳しいです。
[vagrant Homestead でホストOSの共有フォルダが見れなくなった際の対処
](https://sakamata.hateblo.jp/entry/2019/06/24/123601)

さかまたさん ありがとうございました。

## 以下、過程
・参考記事
[vagrant upでエラー 「command failed! setup」](https://qiita.com/gun534/items/9fe8ebcedbe978cccc63)
[vagrant up するとGuestAdditions エラーが発生](https://qiita.com/satokourov/items/e632df854be6048adf7b)
[Vagrantで共有フォルダがマウントされない](https://qiita.com/uralogical/items/231ba43c593432a3b470)


この辺りの解決策が同じエラーに出会ってそうなので、参考にして

```
・yum update　したり
・wget http://download.virtualbox.org/virtualbox/6.0.14/VBoxGuestAdditions_6.0.14.iso　したり
・Virtual Boxを最新版に修正したり
```

色々試しては、snapshotで復元して他の方法を繰り返し試しました。
エラー吐いても、sshログインは出来るので、共有フォルダがマウントされていないか確認することができるので、毎回確認していましたが、自分の場合は何も改善はなかったです。
Micro CMS を少し触ってみたので所感をざっくりまとめた

Headless CMS を選定する機会があり、Micro CMS も触ってみたのでその所感を軽くまとめてみた。

普段そこまで REST API を用いてフロント重視の実装をしている訳でもないので、見当違いな理解をしている可能性は大いにありますが、逆にそういったエンジニアから見た率直な感想として書き残しておきます。


## 良い点

サービスを開始するのがとても簡単。DBの設定なども気にしなくてよいので、詰まることなくスムーズに新規サービスを開始できる。設定周りのハマりに無駄な時間を使わなくて済むのは嬉しい。

コンテンツの APIスキーマ設定や入力がシンプルで使いやすい。サンプルコードも表示できるので、フロント側の実装で詰まることも少なそう。



## 気になった点

コンテンツの追加に使える入力方法がシンプルすぎて配列すら渡せない。

関連付けのフィールドが使えるものの、複数登録ができないため、WordPress でいう「タグ」のように「コンテンツ一つに対して複数の外部コンテンツを紐付ける」ということはできない。

API を叩いたときに「検索」「フィルタ」「ソート」等のそれなりによく使う機能が使えない。（2019/10/30時点での開発ロードマップを見る限り、これらの機能は将来的には実装される見込みのようだが、優先度「低」となっているのであまり期待できない）



## まとめ

導入が驚くほど簡単なので、アプリのプロトタイプを作るような段階で実験的に使ったり、将来的にもコンテンツの取得に複雑さを求めないアプリでは使い勝手が良さそう。

しかし、リリースから間もないこともあってかまだまだ不自由な点も多く、サービスの継続性にも不安があるので、実務に組み込んでいくには難しそうというのが正直なところ。

とはいえ気軽に始めて使えるという点では素晴らしかったので、今後の機能拡充に期待したい。
【ios】swiftのユニットテストでHTTPリクエストをスタブ化する

# 背景

iosアプリのユニットテスト(XCTest)を実行するたびにAWSのAPI Gatewayに接続していた
ユニットテストなので、外接のサービスとは関係を持って欲しくない

# やったこと

## ライブラリのインストール

今回は[OHHTTPStubs](https://github.com/AliSoftware/OHHTTPStubs)を選択した（実行まで時間かからなさそうだったから）

CocoaPods でインストールする
下記をPodfileに追記する

 ```
pod 'OHHTTPStubs/Swift'
```

podコマンドでインストール

```
pod install
```

## コーディング

テストクラスでインポートを記述

``` swift:
import OHHTTPStubs
```

スタブの設定を記述
http接続した際の戻り値を設定しておく

``` swift:
stub(condition: isHost("[ここにホスト名を記述(ex:hiroky.com)]")) { _ in
    # 返却するJsonObjectを宣言
    let obj = ["result": "ok"]
    # ステータスコード等を記述
    return OHHTTPStubsResponse(jsonObject: obj, statusCode: 200, headers: nil)
}
```

以上でスタブの完成！
テストケースないで1度記載しておくと、何回呼ばれても同一の返却をしてくれる模様
ぜひ、スタブを使ってみてください！
Maya AnimCurve のデータを Pythonで取得するメモ

![animcurve.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/38da2588-dacb-0e66-8818-827802f2a72f.png)

## 背景

AnimCurve node の値を取得して, JSON なりでエクスポートしたい.

## PyMel

http://help.autodesk.com/cloudhelp/2019/ENU/Maya-Tech-Docs/PyMel/generated/classes/pymel.core.nodetypes/pymel.core.nodetypes.AnimCurve.html

(最近 Autodesk の PyMel ヘルプサイトが壊れているようでつらい)

`numKeys()` or `numKeyframes()` でキーの数を取得.


Angle 型の AnimCurve の場合は, radian の値が返ってくるので注意ください.
たとえば UI 上で 62.78493 の値は, `getValue()` すると  1.0958037491341635 がかえってきます.

### Time について.

どうも? `getTime(int)` で取得する time 値はバグるときがあるようです.

MEL での,

```
getAttr "animCurveUA.ktv[1]";
```

と同等の python を使って値(time, value)取得がよいです.

## その他参考情報

`keyframe` 関数 
http://download.autodesk.com/global/docs/maya2012/ja_jp/PyMel/generated/functions/pymel.core.animation/pymel.core.animation.keyframe.html

Scripting for Animation in Maya
https://hub.packtpub.com/scripting-animation-maya/

## TODO

* [ ] cmds.keyframe で値を取得しようとすると, 構成によっては None or 空配列が返ってくるケースがある原因を突き止める.
* [ ] 補間した値を取得する方法を調べる
NVIDIA, CT Organ Segmentation AI を試す

触ってみました。（with @Selene-Misso ）

https://ngc.nvidia.com/catalog/containers/nvidia:clara-ai

#前提

Nvidia-Dockerが必要です。

#手順

上のリンクのページにある通りに実行していくだけです。

最初にテストデータやモデル、予測結果などを保存する場所を作ります。

```
mkdir -p input output
```

訓練済みのモデルを利用するために使うサーバーのために、dockerのネットワーク（例えばclaranetという名称にします）を作ります。

```
docker network create claranet
```

訓練済みのモデルをダウンロードします。

```
mkdir -p models
 docker run -it --rm -u $UID:$UID -v $(pwd):/data --entrypoint "" nvcr.io/nvidia/clara-ai:0.1.2 bash -c 'rsync -a --info=progress2 /models /data'
```

テストに使う画像をダウンロードします。

```
 # Download 'input/test' folder from the internet.
 mkdir -p input/test
 wget -q https://www.dropbox.com/s/5fk0m9v12if5da9/dense_vnet_abdominal_ct_model_zoo_data.tar.gz?dl=1 -O - | tar xvz -C input/test
 rm input/test/100_Label.nii # Remove unnecessary label image.
```

簡便にテストするために、TRITISというサーバコンテナをDocker上で起動します。

```
nvidia-docker run -it --rm -d \
 --shm-size=1g \
 --ulimit memlock=-1 \
 --ulimit stack=67108864 \
 --name trtis \
 --network claranet \
 -p 8000:8000 \
 -v `pwd`/models/v_net:/models/v_net \
 nvcr.io/nvidia/tensorrtserver:18.11-py3 \
 trtserver --model-store=/models
```

もう一つclara-aiサーバーを立てます。（上記のサーバとどちらがアプリケーションサーバ？その辺り分かっていません。ごめんなさい。）

```
 nvidia-docker run -it --rm -d \
   --name ai \
   --network claranet \
   -p 5002:5002 \
   -e CIM_APP_FOLDER_NAME=custom_application_vnet \
   -e CIM_APP_SKIP_INSTALL=true \
   -v $(pwd)/input:/ai/in \
   -v $(pwd)/output:/ai/out \
   nvcr.io/nvidia/clara-ai:0.1.2 \
   serve --input_folder=/ --output_folder=/ \
     --trtis_url=trtis:8000 --port=5002
```

処理実行

```
# .nii file is interpreted as image with LPS axis code so transpose it to ARS to match with vnet model
curl -H "Content-Type: application/json" \
-d '{"name":"test","workflow":5,"pre_axcodes":"ARS"}' \
http://localhost:5002/ai
```

実行したら、特にエラーがなければ、「output/test」フォルダに結果が保存されます。
今回の例では、「100_CT.seg.raw」が結果です。

raw画像データなので、(144,144)のマトリクスで、144スライス画像になっています。（isoですね）
Fiji(imagej)で開いてみます。

![100_CT-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/43a18bd7-d44c-16b3-0d75-0d70b07c0da8.png)

![100_CT.seg-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/7876e4e5-6007-7fea-b315-4cf842a525fe.png)

![100_CT-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/b8ba0cf3-f6db-50ee-4f4e-128f15252e24.png)

![100_CT.seg-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/8c99ad25-6374-19c3-5c3a-ec2000ec2a14.png)

以上です。