OmniAICreator/Qiita-1.07M huggingface dataset:
AWS EC2 でファイルが更新されたタイミングでrsyncと任意のコマンドを実行する


## 必要パッケージのインストール
### Master側（同期元) AmazonLinux2
```
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y rsyncd inotify-tools
```

### Slave側（同期先) AmazonLinux2
```
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y xinetd rsyncd
```


## SSH公開鍵の発行
### Master側で接続用のssh鍵を発行する

```
sudo su
ssh-keygen -t rsa -N ""
```

``/root/.ssh``に``id_rsa``と``id_rsa.pub``が存在する状態  

### Slave側で公開鍵を設置する
Masterのid_rsa.pubの中身を貼り付ける  

```
vim ~/.ssh/master_rsa.pub
```

Permissionの変更

```
chmod 644 ~/.ssh/master_rsa.pub
```

## Master側に変更検知のスクリプトを設置する
### スクリプトは任意の場所に設置する

監視ディレクトリとIP、コマンドは各自任意のものに

```reflesh.sh
#!/bin/bash
# required package: inotify-tools

WATCH_DIR=/var/www/html
SLAVE_IP=xxx.xxx.xxx.xxx

events=(-e CREATE -e DELETE -e MODIFY -e MOVED_TO)
while inotifywait ${events[@]} $WATCH_DIR; do
    echo "変更検知"
    rsync -avz $WATCH_DIR $SLAVE_IP::html
    // 任意のコマンド
done
```

### 自動起動するようにsystemdにサービスとして追加する

サービス名は任意(今回はreflesh)

```
sudo vim /etc/systemd/system/reflesh.service
```

```
[Unit]
Description=Product Server Rsync 
[Service]
ExecStart=/path/to/reflesh.sh
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
```

サービスを登録する

```
sudo systemctl enable reflesh
```


## Slave側でxinetdとrsyncの設定
### xinetdの設定
ファイルが存在しない場合は作成する

```
sudo vim /etc/xinetd.d/rsync 
```

``disable = yes ``を``no``に変更する

```
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#	allows crc checksumming etc.
service rsync
{
	disable	= no
	flags		= IPv6
	socket_type     = stream
	wait            = no
	user            = root
	server          = /usr/bin/rsync
	server_args     = --daemon
	log_on_failure  += USERID
}
```

### rsyncの設定
ファイルが存在しない場合は作成する

```
sudo vim /etc/rsyncd.conf
```

許可するIPと同期するディレクトリを設定

```
#--------------
# Global options
#--------------
uid           = root
gid           = root
log file      = /var/log/rsyncd.log
pid file      = /var/run/rsyncd.pid
hosts allow   = xxx.xxx.xxx.xx/32
hosts deny    = *
dont compress = *.gz *.tgz *.zip *.pdf *.sit *.sitx *.lzh *.bz2 *.jpg *.gif *.png

[html]
  comment      = rsync server
  path         = /var/www/rsync/
  read only    = false
  exclude      = *.mp
  include      = *.mp30
```

同期先ディレクトリはなければ作る必要がある
permissionは755
(存在しないとrsyncがコケる)

### xinetdを再起動する

```
sudo systemctl restart xineted
```

## 試験
### 監視ディレクトリにファイル変更を行う
設定したSlave側でrsyncが実施され任意のコマンドが実行されればOK
fancyboxでモーダルを作ったが、androidで開きスワイプするとクローズしてしまうとき

## 背景
fancyboxのモーダルで、androidだけなぜかスワイプするとモーダルの続きが読めずに閉じてしまうバグを修正してほしいと依頼がきました。

## 解決
fancyboxに用意されている`modal: true`というモーダル用のオプションが抜けていました。追加して解決です。

```js
$('#btn').fancybox({
	modal: true
  .
  .
  .
 (略)
});
```


また、`modal: true`にすると右上のクローズボタンが消えてしまうので

```html
<button data-fancybox-close="" class="fancybox-close-small" title="Close"></button>
```
をモーダルの大枠タグ直下に配置します。

modalオプションのあるなしを比較しながら配置してあげると楽かもしれません。
RubyとPHPの対応　〜超超入門〜


#文字列の表示
自動で改行がされる「Ruby：puts」に対し、「PHP:echo」は改行に記載が必要となる。

```
# Ruby
puts 'Hello,World'
// PHP
// セミコロンがないとエラーが起きる
echo 'Hello,World';
//echoは改行されないため複数回echoが出力される場合は,<br>タグにより改行が必要
echo 'Hello,world'.'<br>'
```

#変数の宣言
変数の宣言の際に、PHPは変数名の頭に「$」が必要となる。

```
# Ruby
name = 'yamada'
// PHP
// 変数名の前に「$」が必要(呼び出しの際も必要)
$name = 'yamada';
```

#文字列の連結

```
# Ruby
lesson = "Ruby"
language = "言語"
puts lesson+language
puts lesson.concat(language)
// PHP
// 文字列の連結に「.」が必要
$lesson = 'PHP;
$language = '言語';
echo $lesson.'言語';
echo $lesson.$language;
  => PHP学習
$lesson. = '入門';
  => PHP入門
```

#変数の展開
PHPでは{}内部で変数の計算はできない。

```
# Ruby
name = '田中'
puts = "こんにちは、#{name}さん"
  => こんにちは、田中さん
// PHP
$name = '田中';
echo "こんにちは、{$name}さん";
  => こんにちは、田中さん
```

#if文

```
# Ruby
// PHP
if 第一条件式
  # 第一条件trueの場合の処理
elsif 第二条件式 
  # 第二条件trueの場合の処理
else
  # falseの場合の処理
end
if(第一条件式){
  // 第一条件式trueの場合の処理
}elseif(第二条件式){
  // 第二条件式treeの場合の処理
}else{
  // falseの場合の処理
}
```

#case文/switch文

```
# Ruby
case 変数
when 値1
  値1の時の処理
when 値2
  値2の時の処理
when 値3
  値3の時の処理
else
  いずれにも一致しなかった時の処理
end

// PHP
switch(変数){
  case 値1:
    //変数　== 値1の時の処理
    break; 
  case 値2:
    //変数　== 値1の時の処理
    break; 
     ・
     ・
     ・
  default:
    //いずれのcaseにも一致しなかった場合の処理
    break;
}
```

#配列の作成
PHPのarray()の宣言は古いVerのPHPでの仕様となる
```
# Ruby
fruits = ['りんご','バナナ','みかん']
// PHP
fruits = array('りんご','バナナ','みかん');
fruits = ['りんご','バナナ','みかん'];
```

#連想配列の作成

```
#Ruby
user = {"name":"田中","age":24,"gender":"男"}
puts user["name"]
  => 田中
// PHP
$user = array('name'=>'田中','age'=>24,'gender'=>'男');
$user = ['name'=>'田中','age'=>24,'gender'=>'男'];
echo $user['name']
  => 田中
```

#for文

```
# Ruby
for i..100　 # iをいくつまで繰り返すか
  # 繰り返す処理
  i+1   # iの更新条件
end
// PHP
for($i = 1;$i <= 100;$i++){　　//for(変数の初期値;繰り返し条件;変数の更新条件）{
  // 繰り返す処理
}
```

#while文

```
# Ruby
i = 1
while(i <= 100)
  puts i
  i += 1
end

// PHP
$i = 1;
while($i <= 100){
  echo $i;
  $i += 1;
}
```

#繰り返し文の終了
該当箇所のループを終了させる文が「Ruby:next」に対し、「PHP:continue」となる。

```
# Ruby
break  //繰り返しのブロック自体の処理の終了
next   //該当の処理の終了

// PHP
break  //繰り返しのブロック自体のブロックの処理の終了
continue  //該当の処理の終了
```
# foreach文

```
# Ruby
配列.each do |値変数|
  # 値変数の処理
end

//PHP
foreach(配列 as 値変数）{
  // 値変数の処理
}
foreach(連想配列 as キー変数　=> 値変数){
  // キー変数、値変数の処理
}
```

# 関数の作成
```
# Ruby
def 関数名(引数)
  #  実行する処理
end

// PHP
function 関数名（引数）{
  // 実行する処理;
}
```
Cloud OnBoard 機械学習講座（エンドツーエンドで学ぶGCPを活用した機械学習モデルの構築）

#[Cloud OnBoard 機械学習講座（エンドツーエンドで学ぶGCPを活用した機械学習モデルの構築）](https://event.shoeisha.jp/devsumi/20190214)
　日時：5月15日（水）
　　　　　14:00～17:00（受付開始 13:00）
　会場:Google 六本木オフィス　東京都港区六本木6丁目10-1 六本木ヒルズ森タワー27階
　登壇者：中井悦司
　[【受講資料はPDF】]()

---

##■
 
#####【memomeo】
* Jupiternotebook
* hosting環境
* ストレージバケット
* バケット
* カテゴリー変数：離散的なラベル値ととるもの
<br>カテゴリー変数と数値変数の区別がつきにくいものについて厳密に分けなくてもいい。シミュレーション結果がよいもの（モデルとして優秀なもの）を採用すればいい。※厳密に分けることが目的ではない。
* telass：tf.learnとは使用目的がちがうライブラリ。分散学習が対応していない。
* tf.learn：研究者レベルで位置から作りたい人、パッケージも出るもあるのでそれを利用することもある人、分散学習のパッケージを使いたい人向けのライブラリ。



#####【】


#####【】.

---
Nuxt.jsでURLからパラメーターを取得する

# パスからパラメーターを取得する
<code>localhost:3000/post/12345/</code> にアクセスした時に<code>12345</code>の部分を取得したい。

~~~
pages/
--| post/
-----| _id.vue
~~~

~~~vue:_id.vue
<template>
  <section>
    <p>{{ $route.params.id }}</p>
  </section>
</template>
~~~

参考：[動的なルーティング](https://ja.nuxtjs.org/guide/routing#%E5%8B%95%E7%9A%84%E3%81%AA%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)

# Getパラメーターを取得する
<code>localhost:3000/post/?id=12345</code> にアクセスした時に<code>12345</code>の部分を取得したい。

~~~
pages/
--| post/
-----| index.vue
~~~

~~~vue:index.vue
<template>
  <section>
    <p>{{ $route.query.id }}</p>
  </section>
</template>
~~~
node-redで「No 'Access-Control-Allow-Origin' header」が消えない(react)

# 事象
reactで作成したwebアプリケーションから、node-redで作成したAPIにアクセスすると下記のエラーが出る。

```
Access to XMLHttpRequest at 'http://127.0.0.1:1880/api/v1/get/image' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

![スクリーンショット 2019-05-15 18.29.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170662/fd8debdf-a35a-8023-456a-bd9465995826.png)

# 対応1
Http responseのHeaderに"Access-Control-Allow-Origin": "*"を追加
![スクリーンショット 2019-05-15 18.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170662/a82bd012-c308-0f66-0334-965e18333090.png)

エラーは解消されませんでした。

# 対応2 (解決)
node-redの「setting.js」の「httpNodeCors」をコメントアウト解除
setting.jsのパス： /Users/{ユーザー名}/.node-red/settings.js
*macのPCでnpmでグローバルにインストールした場合

<img width="720" alt="スクリーンショット 2019-05-15 17.28.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170662/bea5dbe9-606a-0272-c2a8-3e15d32b08be.png">

解決しました！

# 参考
https://nodered.jp/docs/configuration
Goでファイルの存在や属性をチェックするライブラリを書いた

表題の通り、小さなライブラリを一つ書きました。
> リポジトリ: https://github.com/eihigh/filetest
> ドキュメント: https://godoc.org/github.com/eihigh/filetest

以下のような関数を実装しています。perlのファイルテスト演算子を参考にしました。

```go
func Exists(path string) bool
func IsFile(path string) bool
func IsDir(path string) bool
func IsReadable(path string) bool
func IsWritable(path string) bool
func IsExecutable(path string) bool
func IsSymlink(path string) bool
func IsZero(path string) bool
```

## 動機
Goでのファイル存在チェックは[たびたび](https://qiita.com/suin/items/b9c0f92851454dc6d461)[言及されている](https://qiita.com/hnakamur/items/848097aad846d40ae84b)話題ですが、いちいち正しい書き方を調べるのが面倒になったので、パッケージとして公開することにしました。

結構使う頻度が高そうな処理なので、お気に召した方はぜひお使いください。
p15nライブラリを作ってみたにぃ！　すごいだらぁ！？


多言語化（i18n）があるなら、地域ならではの方言に対応する都道府県化（p15n [^1]）があっても良くない？　と思い作りました。



[^1]: p15nとはPrefectureizationを表しており、都道府県化の意味



:link: [p15n.js](<https://www.npmjs.com/package/p15n.js>)

## 概要



i18n系のライブラリのように、都道府県ごとに `key` と `value` を設定することで表示するテキストを **方言表記** できるようにします。

設定値は次のような形。

```javascript
resources: {
  '東京都': {
    'title': 'p15nライブラリを作ってみました！　すごいでしょ！？',
    'description': 'p15n.jsは、簡単に『方言』が使えるライブラリです。'
  },
  '鳥取県': {
    'title': 'p15nライブラリを作ってみたにぃ！　すごいだらぁ！？',
    'description': 'p15n.jsは簡単に『方言』が使えるライブラリだにぃ。'
  }
}
```

利用する方言を決定するために、都道府県名を渡します。

```javascript
p15n.init({
  pref: '島根県',
  fallbackPref: '鳥取県'
});
```

`pref` でメインの都道府県を、 `fallbackPref` で第二候補の都道府県を指定できます。

上の例では、まず島根県を検索し、キーがなければ鳥取県を検索する感じです。

両方ともなければ、標準語（東京都）に設定された値を利用します。



HTML要素などへの方言セットをコールバック関数や、`Promise` を使って行わせるのは、DOM要素の生成タイミングを意識しなくていいようにと考慮したためです。

このあたりは、有名な [i18next](<https://www.i18next.com/>) のコードを参考にさせていただきました。

## Installation

##### ブラウザから:

```html
<script src="p15n.js"></script>
```

##### npmを使う:

```shell
$ npm install p15n.js
```



## Usage

##### コールバック関数を渡す方法:

```javascript
import p15n from 'p15n';

p15n.init({
  pref: '鳥取県',
  resources: {
    '東京都': {
      'title': 'p15nライブラリを作ってみました！　すごいでしょ！？',
      'description': 'p15n.jsは、簡単に『方言』が使えるライブラリです。'
    },
    '鳥取県': {
      'title': 'p15nライブラリを作ってみたにぃ！　すごいだらぁ！？',
      'description': 'p15n.jsは簡単に『方言』が使えるライブラリだにぃ。'
    }
  }
}, function(t) {
  // initialized and ready to go!
  document.getElementById('title').textContent = p15n.t('title');
  document.getElementById('description').textContent = p15n.t('description');
});
```

##### Promiseを使う方法:

```javascript
import p15n from 'p15n';

p15n.init({
  pref: '鳥取県',
  resources: {
    '東京都': {
      'title': 'p15nライブラリを作ってみました！　すごいでしょ！？',
      'description': 'p15n.jsは、簡単に『方言』が使えるライブラリです。'
    },
    '鳥取県': {
      'title': 'p15nライブラリを作ってみたにぃ！　すごいだらぁ！？',
      'description': 'p15n.jsは簡単に『方言』が使えるライブラリだにぃ。'
    }
  }
}).then(() => {
  // initialized and ready to go!
  document.getElementById('title').textContent = p15n.t('title');
  document.getElementById('description').textContent = p15n.t('description');
});
```



## まとめ

利用シーンは限られますが、興味のある方は使ってみてください！

ちなみに鳥取弁は20年近く使っていないので、間違ってたらごめんなさい！！
stimulus、初歩の初歩（基本構造についての私的理解まとめ）

[こちら](https://qiita.com/wkya_4a/items/e85bd6324fe4085dce0e)の続き、railsプロジェクトに当てる前提でいろいろ試しています。

とりあえず[ハンドブック](https://stimulusjs.org/handbook/introduction)を読んで、自分なりに纏めてみる（ちなみに書いている人間はWebプログラミング初心者です。間違いなどあればどしどし指摘をよろしくおねがいします[^1]）。

#stimulus、HTML側の三要素ーー【controller】【target】【action】

HTML側で記述する基本的な要素は、

・data-controller
・data-action
・data-target

の３つのはず。
……前回も触れた、[ハンドブックの【Hello, Stimulus】](https://stimulusjs.org/handbook/hello-stimulus)を持ち出すと、


```rails:app/views/users/index.html.erb

<div data-controller="hello">

  <input data-target="hello.name" type="text">
  <button data-action="click->hello#greet">Greet</button>

</div>
```

```rails:app/javascript/controllers/hello_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name" ]

  greet() {
    console.log(`Hello, ${this.name}!`)
  }

  get name() {
    return this.nameTarget.value
  }
}
```

（ファイルの場所がハンドブックと違うのは、railsプロジェクトに当てているから……前回参照）。

##それぞれ、何をやっているかというとーー
###data-controller
```rails:

<div data-controller="hello">
　　　　〜〜〜〜
</div>
```
→「div」に当てて、
　**この「div〜〜/div」の範囲が「data-controller="hello"」の該当範囲だよー**
　と教えている。

###data-action
```rails:
  <button data-action="click->hello#greet">Greet</button>
```
→「button」に当てて、
　**この「button」がドウコウした（今回なら「click」された）時、js側で何らかの動き（今回なら「helloのgreetメソッド」）を発生させるよー**
　と言っている。

###data-target
```rails:
  <input data-target="hello.name" type="text">
```
→「input」に当てて、
　**上記【data-actionで発生するｊｓ側の動き】の中では、このinput要素は「helloのname」として取得される[^2]（あるいはjs側で用意した値を設定する[^3]）よー**
　と教えている。


#それぞれに対応するjs側の要素は……
###【data-controller】への対応→jsファイルそのもの
『【data-controller】が指定した該当範囲』内で発生した刺激（stimulus）については、『【data-controller名】_controller.js』にあるjs記述が処理を行う。


###【data-action】への対応→jsファイル内の関数
```rails:
  greet() {
    console.log(`Hello, ${this.name}!`)
  }
```

『"〜〜〜〜->【data-controller名】#【data-action名】"』の刺激が発生すると、『【data-controller名】_controller.js』にある『【data-action名】と同名のメソッド』が起動する。

###【data-target】への対応→jsファイル内の記述、『static targets = [【target名】]』および『this.【target名】Target(s)』
```rails:
  static targets = [ "name" ]

  get name() {
    return this.nameTarget.value
  }
```
【data-target】にされた要素は、js内では**this.【target名】Target(s)**としてデータを取得/設定する。この両者は、**static targets = [【target名】]**の記述により関連付けられる。

「Target」「Targets」の違いについては、また今度。


##で、結局つまりどういうこと？
###……たぶん、こういうこと。
![スクリーンショット 2019-05-15 18.23.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/fedb6a76-3c7c-16cb-7bc1-f0c49976f5bf.png)


①：HTML側でアクション（ボタンのクリックとか）が発生し、それによってjs側の【action名と同じ名称のメソッド】が呼び出される。
②：「HTML側target要素」と「js側のThis."target名"Target(s)」は、「static targets ="target名"」の記述で関連付けられている。
③：「①」によって起動したメソッド内（あるいは、さらにそこから呼び出されたメソッド内）で、
　　・「This."target名"Target(s)」から値が取得される。
　　・「This."target名"Target(s)」に値を設定する。
　→「②」によって「This."target名"Target(s)」はHTML側の要素と関連付けられているので、この「値設定」「値取得」によりHTML要素の取得，設定が行われる。

とりあえず、概要はつかめたような気がする。
「Target」と「Targets」の違い、具体的な値の取得方法、アクションの種類などは、また追々……書けていけたらいいなぁ。

[^1]: というかこのstimulus、便利そうなのに触れている情報があんまりない。自分のを含め、Qiitaのタグに登録されている記事が３件だけ（２０１９年５月１５日現在）って、なにさ！？

[^2]: ｊｓ側から見ると、「data-target」の情報がinputされる。

[^3]: 同じくｊｓ側から見ると、「data-target」の情報へ値をoutputする。
r104で外部パッケージ不要に　ES6 / TypeScriptでThree.jsのexamplesをimport

## はじめに

ここ数週間で、Three.jsのOrbitControlsなどを含む`jsm`ディレクトリが頻繁に更新されています。この更新により、いままでよりも簡単に各種カメラコントロールやローダーが利用できるようになりました。

現状（2019/05/15）でのexamples内のモジュールをimportする方法をご紹介します。

### 環境

この記事はthree.jsの以下のバージョンを元に書かれています。

*▼package.json*

```json
"three": "0.104.0"
```

この記事の内容は流動的です。three.jsのバージョンが更新されると指定したクラスが移動したり削除される可能性があります。ご注意ください。

### 想定する読者

この記事は、現在three.jsを利用しているユーザーを想定して書かれています。

## import

[公式ドキュメント](https://threejs.org/docs/index.html#manual/en/introduction/Import-via-modules)の`Importable Examples`の章に、新たにモジュールのimportの項目が追加されました。
公式ドキュメントの[更新](https://github.com/mrdoob/three.js/commit/25dae4d0f2b2ce8112469f61dfedb33d6c277ed1#diff-11c68ca759f6b6da72355cda8ef1f518)は、r104に合わせて4/22に行われています。

例として、OrbitControlsとOBJLoaderは以下のようにimportが可能です。[three-js](https://www.npmjs.com/package/three-js)など、外部パッケージは必要ありません。

⭕️

```js
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
```

`jsm` ディレクトリには、ES6のjsファイルとTypeScript用のd.tsファイルが揃っています。importするだけでそのまま使えます。

## ~~@types/threeは非推奨~~

~~r104の更新に合わせて[@types/three](https://www.npmjs.com/package/@types/three)が非推奨になりました。three.js本体にTypeScript用の型定義ファイルが同梱されるようになったためです。r104環境で@types/threeがインストールされている場合は削除をオススメします。~~

Three.js r126で、TypeScript型定義ファイルが再度[@types/three](https://www.npmjs.com/package/@types/three)に分離されました。([該当issue](https://github.com/mrdoob/three.js/pull/21174))
TypeScriptでThree.jsを利用する場合は型定義のインストールが必要です。

以上、ありがとうございました。
unicorn を監視して、落ちたら自動再起動するワンライナー

今回は負荷の高いRailsアプリのunicornが落ちてしまうことがあり、
手動で再起動しているようでは、ダウンタイムが発生してしまうのでなんとか自動的に再起動をかけられないかと考えさがしていたところ、
手軽にできる方法を発見し、暫定的に採用させていただきました。

もっと良い方法や違うアプローチがあるかもしれませんが、
今回は表題の内容を紹介させていただきます。

## 環境
- AWS EC2
- Ubuntu
- Rails
- Unicorn

`restart-server` という`unicorn`を再起動するコマンドを予め作成しておりましたので、
プロセスを監視して`unicorn`がいなかったらそのスクリプトを実行するという形を取りました。

またデプロイ専用のユーザーで無いと、`restart-server`は実行できないという環境です。


## 概要
linuxコマンドの`watch`を利用して、60秒ごとに`unicorn`と含まれるプロセスが存在するかを確認、
プロセス数が0であれば、`restart-server`を実行するという具合です。

ただ`ssh`で接続して`watch`を実行しても`watch`を終了しなければ、sshを切断できませんので、
sshを繋ぎっぱなしにしなければなりません。

よってsshを切っても、`watch`が動き続けるように`nohuo`を利用します。

それらを組み合わせてできたワンライナーが以下のものです。

```
nohup watch -n 60 "if [ 0 -eq `ps ax | grep unicorn | grep -v grep | wc -l` ] ; then restart-server ; fi" &
```

## 使用方法
`{繰り返しの秒数}`のところに繰り返し監視する感覚を秒数で入力します。0.1以下は設定不可
`{実行するコマンド}`のところに、unicornプロセスがなかったときに実行するコマンドを入力します。
`{実行するコマンド}`の部分はあまり長いもの入れられませんので、別途スクリプトを用意するなどして簡単に呼び出せるようにすることが必要です。

```
nohup watch -n {繰り返しの秒数} "if [ 0 -eq `ps ax | grep unicorn | grep -v grep | wc -l` ] ; then {実行するコマンド} ; fi" &
```

以下、各部分を簡単に解説していきます。

```
nohup <command> &
```

先頭の`nohup`と末尾の`&`が`nohup`コマンドです。
その間に半角スペースを挟んで、ssh切断後も実行しておきたいコマンドを入れます。
今回は`watch`コマンドです。

```
watch -n 60
```
この部分が`watch`コマンドとオプション指定です。
`-n`が実行間隔を指定するオプションでその後に半角スペースにつづけて秒数を入力します。

```
if [ 0 -eq `ps ax | grep unicorn | grep -v grep | wc -l` ] ;
```
おなじみのif文です。`[]`内が条件式です。
`0 -eq` の部分がイコール0ならば真という条件式です。
続く`ps ax`が全てのプロセスを一覧表示するコマンド、`|`パイプで繋いで`grep unicorn`で`unicorn`を含むプロセスだけに絞り込みます。
ただこれだけだと、絞り込んだ結果の中にこの`grep`自体もプロセスも含まれてしまいますので、`grep -v grep`で`grep`の実行プロセスを除外します。

最後の`wc -l`でその絞り込んだ結果を数字にします。
そうすることで`0 -eq`と数字で比較します。

`unicorn`プロセスが居ないときは、プロセスリストにunicornと含まれるプロセスも0になりますので、
0と比較して真になれば、`then`に続くコマンドが呼び出されるという形です。

## 注意点
当たり前のことかもですが、スペースに注意してください。
`[]`や`;`の前後のスペースが抜けるとうまくいきません。

あとクオートとバッククウォートにも注意が必要です。

`if ~ fi`までがif文ですが、それをダブルクォーテーションでくくっています。
また`ps ~ -l`まではバッククウォートでくくっています。

## まとめ
こんなワンライナーで済ませてしまっていいものかとも思いますが、
きちんとしたunicorn監視&再起動の方法があればご教授ください。
自分でも引き続き調べていこうと思います。

## 参考にした記事
以下の記事を参考にさせていただきました。
非常に助かりました。ありがとうございました。

[grepでこういう時はどうする?](https://qiita.com/sanryuu/items/6d9ba9adbcefd15a2ebf)
[SSHからログアウトした後もプロセスを起動しておく方法](https://qiita.com/IshitaTakeshi/items/531e4c9c1782a7549a62)
[シェルスクリプト(bash)の「 [ ] 」と「 [[ ]] 」の違い](https://qiita.com/miyazato_te/items/3ecb400666ccad754cc0)
[grepでこういう時はどうする?](https://qiita.com/hirohiro77/items/771ffb64dddceabf69a3)
【Unity】The type or namespace name 'IObservable<>' could not be foundの解決方法

# 概要
unitypackageをimportすると個人的に頻繁に目にする
> The type or namespace name 'IObservable<>' could not be found (are you missing a using directive or an assembly reference?)

というエラーをとりあえず解決する方法を書きました。

# 環境
Unity 2019 1.1f1
UniRx 6.2.2

# 解決方法
エラーの出る全てのファイルに対して`using System;`を追加してください。とりあえずエラーは消えるはずです。

# 感想
とりあえずこの方法でエラーは消えるのですが、何かもっと根本的な解決方法があるような気がしています。


# 参考
[IObservable<T> Interface (System) \| Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.iobservable-1?view=netframework-4.8)
#django のバージョンをワンライナーで確認するコマンド ( $ python -c 'import django; print(django.get_version())' )

```
$ python -c 'import django; print(django.get_version())'
2.2
```

# thanks

[Djangoのバージョン確認方法 - Qiita](https://qiita.com/yukhig/items/368dde026609ef37fce8)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#python ( ipython ) で事前に pip モジュールを読み込んでからインタラクティブモードを起動する

# 例

```
$ python -i -c 'import re' 
```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Gitの基礎(リポジトリの作成～プッシュまで)

###はじめに
仕事で新しくプログラムを作る際に、Gitのリポジトリを作成してソースの管理を行うことが多いです。
毎回忘れて調べるのでここにメモしておきます。

だいたい仕事では下記の流れで作業するので、それに沿って書きます。

- リモートリポジトリの作成
- リポジトリのクローン
- ファイルの追加
- 変更のコミット
- プッシュ

###環境
OS : Windows10 64bit Home

###Gitのインストール
[Gitの公式サイト](https://git-scm.com/)からインストーラをダウンロードする。
設定しておくと便利なので、"Windows Explorer integration"にチェックをつけておく。
![GItインストーラ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/cb1f4241-49e7-a09f-eeee-aae16b25d7ce.png)

※エクスプローラー上で右クリックをしたときに、"Git Bash Here"と"Git GUI Here"が表示されるようになる。

あとはデフォルトで問題なし。

###リモートリポジトリの作成
リモートリポジトリを作成したいフォルダー上に新しいフォルダーを作成する。
フォルダー名は"プロジェクト名.git"とするのが一般的らしい。

作成したフォルダーに入り、右クリックメニューから"Git Bash Here"を選択する。

下記コマンドを実行する。

```
git init --bare --share
```

###リポジトリのクローン(Git Bashを使用)
下記コマンドを実行。

```
git clone [リポジトリのURL] <ディレクトリ名>
```

###ユーザー登録
コミットするときに、ユーザー名とメールアドレスを登録しておかないとエラーとなるため登録する。

下記コマンドを実行する。

```
git config --global user.name [ユーザー名]
git config --global user.email [メールアドレス]
```

###ファイルの追加
下記コマンドを実行。

```
git add [ファイル名]
```
ファイル名にはワイルドカードが使用可能。

###変更のコミット(Git Bashを使用)
下記コマンドを実行する。

```
git commit -a
```
Vimが起動するので、先頭にコミットコメントを書く。

コミットコメントは一般的に、
1行目：[プレフィックス]変更内容の要約
2行目：空行
3行目：変更した理由
とするらしい。

プレフィックスの例は下記のような感じ。

- fix：バグ修正
- add：ファイル追加
- update：機能修正
- delete：ファイル削除

-mオプションをつけることでコマンド実行と同時にコメントを記載できる。

###プッシュ(Git Bashを使用)
下記コマンドを実行する。

```
git push
```

###最後に
クローン以降の作業はGit GUIを使って視覚的に作業したほうが良い気がするけど、なぜかみんなコマンドで作業するみたい。
やはり作業効率が良いのかな？
【Houdini】立体的な令和を作ってみる

## はじめに
令和が始まって2週間が経ちました。皆さんはいかがお過ごしでしょうか。

今回はHoudiniを使って、立体的な令和3Dモデルを作る方法を紹介したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/65bd5d52-76c3-5f72-bcc6-b299ee61e0af.png)


## 使用するHoudiniのバージョン
Houdini Apprentice 17.0

## 令和の透過pngを用意する
今回は下記URLにある横書き(白)の令和pngを使用させていただきました。
https://edit-anything.com/blog/reiwa-png.html

# 画像をメッシュ化する
**Trace**ノードを使うと、画像をメッシュ化することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/5abbbf0e-fbff-b6c1-a304-4b495e23a3f6.png)

TraceノードのImage Inputには令和pngのパスを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/38214802-52bf-fc68-fcf6-65dc1a2c0cc3.png)

豆知識ですが、$HIPと入力すると現在開いているHoudiniプロジェクトのディレクトリになります。

## 結果
令和の文字がメッシュ化されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/02c23a3b-3ae6-11ea-835e-7fd0bef698c8.png)

# 穴をあける
令の文字の下の部分に穴が開いていないのが気になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/d707e499-3a80-8f5d-7b61-212d39852d55.png)

TraceノードのFiltersタブの**Hole Faces**のチェックを入れると穴が開いてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/238a4dd8-2284-dcf5-e971-06d9d120619a.png)

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/d91bf9e8-0651-24dd-d971-615bf699003f.png)
穴が開いてくれました。

# 令和に厚みを持たせる
**PolyExtrude**ノードを使って令和メッシュに厚みを持たせます。

## PolyExtrudeノード作成
PolyExtrudeを作成して、Traceノードに接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/a2b99fc0-5a01-d657-1204-96ac121be54f.png)

**Distance**(厚み)には1を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/a63e9701-97bb-88b1-2ece-0b41014eba3e.png)

## 結果
立体的な令和の出来上がりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/2ac16119-9835-7399-54f8-3320970b9edc.png)

# 問題 : 頂点数が多すぎる
立体的な令和ができたわけですが、**頂点数が2万を超えています。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/eec06145-e854-2df9-f14f-42b556132cd7.png)

ゲームで使おうとなった場合、頂点数が多すぎてちょっと扱いづらいです。

## Fuseで頂点数を削る
**Fuse**ノードを使うと、「まとまった頂点を1つにまとめる」という加工を行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/df1bcb64-6822-cb30-0fd5-883d5cb56b8d.png)

## 結果
令和3Dモデルは以下のような見た目になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/e51cbe4c-10cb-e1e9-2c35-5a44b7c17385.png)

頂点数を見てみると、2500近くまで抑えることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/603105c9-bcaf-ad32-b452-b121649bb9b3.png)
Python3で鉄道遅延情報apiからjson形式で情報を取ってくる方法メモ

[鉄道遅延情報api](https://rti-giken.jp/fhc/api/train_tetsudo/)
から遅延情報を取ってきて遅延してる線の名前を取ってくる方法

```py
#あらかじめ　"pip install request"　しておく
import json
import request

requestURL = "https://rti-giken.jp/fhc/api/train_tetsudo/delay.json"

response = response.get(requestURL)

jsonData = response.json()

for obj in jsonData:
    print(obj['name'])
```

```text:実行結果
[線の名前]
[線の名前]
[線の名前]
   :
```

ってでるはず
Django内でJavaScriptを使うときのファイルや画像の置き場所のベストプラクティスは結局何なんだ！？

以前この記事でDjango内でJavaScriptを使った時のことをまとめました。
https://qiita.com/sr2460/items/ee516e494ccc11baed6b


その後色々なサンプルプログラムをつなぎ合わせていじっていたのですがここで疑問が生じました。
JavaScriptを使うときのファイルや画像の置き場所。
基本的にstaticディレクトリ内に入れているんですけどこれって本当に正しいのかなあと疑問に思ったんですよね。

![スクリーンショット (205).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290841/2d5c9417-5cc4-bd87-5519-4304ec4a9aa8.png)
<br>

こんな感じの構造でアプリケーションを作っています。
staticディレクトリの中にjavaScriptディレクトリを設置。
その下のimagesディレクトリには画像。Scriptsディレクトリにはjsファイル。
soundディレクトリにはmp3などの音楽ファイルが入っています。

<br>
例えばなにかボタンを押した瞬間にsound内の音楽を鳴らしたい！
とか思うとまずこんな感じでボタンを設置して

```html
      <button type="button" class="btn btn-primary btn-block" id="btnPlay">Play</button>
      <button type="button" class="btn btn-primary btn-block" id="btnLoop">Play Loop</button>
      <button type="button" class="btn btn-primary btn-block" id="btnStop">Stop</button>
```

udemyの講座のコードなので細かいコードは割愛しますが<br>

```js
      	// ボタンのイベントを登録
      	$("#btnPlay").click(play);
      	$("#btnLoop").click(loop);
      	$("#btnStop").click(stop);
```

こんな感じでボタンのidに対応して音楽をスタートする関数、ループさせる関数、ストップさせる関数を入力していきます。
しかしいくら関数が合っていても音楽ファイルまでのパスがきちんと通っていなければボタンを押しても何も起こりません。

![スクリーンショット (206)(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290841/440f3ff9-d9f0-61e4-6313-c64c21822229.png)

ただ上のようにstaticディレクトリの下にファイルを置いてしまうと問題が起きてしまうのです。
それは、main.jsでパスを正しく書いてもプログラムは動作しないということ。
<br>
実際に以下のようにパスを通しているのですが

```js
var sndPth = "{%static 'javascript/sound/se_maoudamashii_jingle05.' %}";	// 音声パス（拡張子なし）
```
htmlファイルに以下のような構成で書けば普通にパスは通ります。


```django
{% load static %}


<script>
var sndPth = "{%static 'javascript/sound/se_maoudamashii_jingle05.' %}";	// 音声パス（拡張子なし）


~音楽を再生させるためのプログラム～

</script>
```
<br>
<br>
しかしこのプログラムをmain.jsにコピーしてそのまま使おうとするとうまくいかないんですよ・・・。
<strong>パスが通らないから！！</strong>
<br>

```django
{% load static %}
```
と書くことでDjangoではstaticディレクトリ内をのぞけるようになるのですが、jsファイルでは{% load static %}は動作しないのですよね。全ファイルを実験したわけではないので分かりませんがhtmlファイルじゃないと{% load static %}は動作しないんじゃないかな？知らんけど。
ざっくり図にするとこんな感じになりますｗ
直感的過ぎるか。
↓↓↓
![スクリーンショット (206).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290841/3f916afc-97b2-f1ea-090b-99be99a63a7e.png)

以前の記事で
https://qiita.com/sr2460/items/ee516e494ccc11baed6b


>プロジェクト直下にmediaディレクトリを作成し、そこに画像を配置します。

と書いた通りこんな風にmediaディレクトリを設置してそこにファイルを投げ込んでいけばパスは{% static　～%}を使う必要はなく

```
/mysite/media/ファイル名
```

の形で目的のファイルにアクセスできます。
<br>
ファイルを置く場所によってパスの通し方が違う・・・ということは分かりました。
ただDjangoでJavaScriptを使う時に使用するファイルはstaticディレクトリに入れてhtmlの下にJavaScriptのコードを書いていくのが正解なのか？
それともmediaディレクトリにファイルを入れてmain.jsにJavaScriptのコードを書いていくのが正解なのか？
他の方法がいいのか？
正直よく分からないんですよね。
<br>
多分業務を通じて知っていく知識だと思うのですが僕には業務の経験はないわけですからね。
DjangoでJavaScriptやjQueryを使う場合、問題なく動作するのですがパスの部分だけは躓いたんですよね。
もしDjangoを学んでいてJavaScriptと組み合わせたい方はパスの部分だけは意識しておいてください。
それともしファイルの置場のベストプラクティスが分かったら追記したいです！
以上！
[golang] contextを継承したとき、親contextによる終了か子contextによる終了かを判定する

プログラム全体にタイムアウトを設定していて、また特定の関数にもタイムアウトを設定しているとき、どちらによるタイムアウトかを判定したい場合がある。
子contextの`Done()`が`close`されたとき、親contextの`Done()`が`close`されたかどうかをチェックするとよい。

```go
func main() {
	// 親のcontext
	ctxP, cancelP := context.WithTimeout(context.Background(), 5*time.Second)
RETRY:
	// 子のcontext
	ctxC, cancelC := context.WithTimeout(ctxP, time.Second)
	select {
	case <-ctxC.Done():
		cancelC()
		select {
		// 親のタイムアウト（終了）
		case <-ctxP.Done():
			cancelP()
			fmt.Println("deadline of parent")
		// 子のタイムアウト（リトライ）
		default:
			fmt.Println("deadline of child")
			goto RETRY
		}
	}
}
```
https://play.golang.org/p/MwRQncs98qw
2次元スライスの切り出し

### TL;DR

[正解例](https://qiita.com/egnr-in-6matroom/items/859559296f8e78bffd34#%E6%AD%A3%E8%A7%A3%E4%BE%8B)

### よくある間違い

例えば、

```go
[][]int[
  []int[11 12 13 14 15]
  []int[21 22 23 24 25]
  []int[31 32 33 34 35]
  []int[41 42 43 44 45]
  []int[51 52 53 54 55]
]
```

から

```go
[][]int{
  []int[23 24]
  []int[33 34]
  []int[43 44]
]
```

↑この参照がほしい

`arr[1:4][2:4]`ってやると、

```go
var arr = [][]int{
	[]int{11, 12, 13, 14, 15},
	[]int{21, 22, 23, 24, 25},
	[]int{31, 32, 33, 34, 35},
	[]int{41, 42, 43, 44, 45},
	[]int{51, 52, 53, 54, 55},
}
sliced := arr[1:4][2:4]
for _, row := range sliced {
    fmt.Println(row)
}

// 結果
// [41 42 43 44 45]
// [51 52 53 54 55]
```

となってしまう。これは`(arr[1:4])[2:4]`と同義

```
arr[1:4]

0:[21 22 23 24 25]
1:[31 32 33 34 35]
2:[41 42 43 44 45]

から[2:4を]スライス

[41 42 43 44 45]
[51 52 53 54 55] (参照元のメモリには残ってる)
```

### 正解例
内部の配列のみ通常のスライス。

```go
var arr = [][]int{
	[]int{11, 12, 13, 14, 15},
	[]int{21, 22, 23, 24, 25},
	[]int{31, 32, 33, 34, 35},
	[]int{41, 42, 43, 44, 45},
	[]int{51, 52, 53, 54, 55},
}
// slice範囲
rf, rt, cf, ct := 1, 4, 2, 4
// slicing
sliced := make([][]int, rt-rf)
copy(sliced, arr[rf:rt]) // arr[rf:rt]のスライスを書き換えちゃうと、元の配列で内部配列のlengthが変わっちゃう
for i := range sliced {
	sliced[i] = sliced[i][cf:ct]
}
// show
fmt.Println("Source array")
for _, row := range arr {
	fmt.Println(row)
}
fmt.Println("\nSliced array 1:4,2:4")
for _, row := range sliced {
	fmt.Println(row)
}

// [23 24]
// [33 34]
// [43 44]

```

当然要素のメモリ参照は元の配列と同じなので、`sliced`を書き換えると`arr`も書き換わる。


[Playground](https://play.golang.org/p/S_bE5JBMIuQ)
アップロードした画像ファイルをgitの管理対象から外す

#はじめに
プログラミング初心者がCarrieWaveを使って、画像アップロード機能を開発していました。その際、大量の画像ファイルがgitでバージョン管理をされていたことにあとあと気づきました。
なので、 <b>必要のない画像ファイルをgitの管理対象から外す方法</b>をまとめます。

※今回は、CarrieWaveを使って、画像アップロードすることを前提としています。
しかし、CarrieWaveの詳細については、こちらでは触れません。

#バージョン
carrierwave 1.3.1
rails 5.1.7

#画像ファイルの保存場所を確認する
CarrieWaveでは、アップロードされた画像ファイルの保存場所は、デフォルトで決まっています。

`$ rails g uploader images`で、<b>uploader</b>をジェネレータした場合、app/uploaders/images_uploader.rbファイルが生成されます。
中身を見てみると、下記のコードが記載されています。

```images_uploader.rb
def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
```
こちらのコードでは、アップロードされた画像ファイルは`"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"`の形式で保存することを記しています。

実際にアプリケーションに画像ファイルをアップロードした場合、その画像ファイルは下記のようなディレクトリ構造で保存されているはずです。
これで、<b>画像ファイルの保存場所を確認できました。

```
└public
  └uploads
    └#{model.class.to_s.underscore}
      └#{mounted_as}
        └#{model.id}　#画像が保存されるディレクトリ
```

#.gitignoreを編集する
<b>.gitignoreを使うと無視する（Gitのトラッキングの対象外とする）ファイル or ディレクトリを指定できます。</b>
※ .gitignoreの詳細は、[こちら](https://qiita.com/anqooqie/items/110957797b3d5280c44f)を参照してください。


今回は、CarrierWaveでアップロードした画像ファイルは全てGit管理下に置かないことに決めます。
その場合、下記のように.gitignoreを編集します。

```.gitignore
#~~上記にある他のignoreは省略

以下を書き加えます。
 # Ignore uploaded files in development
 /public/uploads/
```

<b>これで、uploadsディレクトリ以降のファイル、つまり今後アップロードした画像ファイルはgit管理下から外すことができます。

###.gitignoreしたファイルをリポジトリから削除する方法を知りたい方は[こちら](https://qiita.com/Tsh-43879562/items/e2397035da33f910c5b5)

#参考リンク
+ [.gitignoreの仕様](https://qiita.com/anqooqie/items/110957797b3d5280c44f)
+ [CarrierWaveについて](https://qiita.com/Inp/items/cc447237e23bf10d159e)
+ https://qiita.com/Tsh-43879562/items/e2397035da33f910c5b5
RailsでRansackを使用して検索機能を実装

#Ransackについて
タスク管理アプリケーション等で、タスクの登録件数が多くなると、タスク一覧画面だけでは確認できないケースがあります。そのような場合に検索機能があると非常に便利です。Railsでは**Ransack**と言うgemを使うと簡単に検索機能が実装できるので、実装方法を紹介します。
**※前提として、タスクの新規投稿、編集、削除等の一連の機能が実装できている前提で紹介します。また、bootstrapを使用しています。**

##Ransackをインストール
まず**Ransack**をインストールします。Rails内のGemfileに

```Gemfile
gem 'ransack'
```

を記述し、bundlerを利用しターミナルで

```
bundle install
```

を実行します。

ransackをインストールすることで、検索を行うためのransackメソッドがモデルに追加されます。
次に、該当する検索機能を実装したいcontrollerとviewに必要な設定を記述していきます。
今回は、tasks_controllerとindexアクションと仮定して進めます。


```tasks_controller
def index
  @q = tasks.ransack(params[:q])
  @tasks = @q.result(distinct: true).resent
end
```


以上がcontrollerの記述になります。

次に検索画面を実装します。ここでは、ransackが提供するsearch_form_forを使用します。

```
= search_form_for @q, class: 'mb-5' do |f|
  .form-group.row
    = f.label :name_cont, '名称', class: 'col-sm-2 col-form-label'
    .col-sm-10
      = f.search_field :name_cont, class: 'form-control'
  .form-group
    = f.submit class: 'btn btn-outline-primary'
```

以上の記述が終わると、以下のような画面になります。

<img width="1106" alt="スクリーンショット 2019-05-14 21.28.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390473/a3b4b9fb-08e8-2208-d7c0-ac450ef43e4c.png">

これで検索機能が実装完了です。

##最後に
非常に簡単に説明しているので、説明を省略している箇所がありますが、大まかな流れとしては

**・ransackをインストールする**
**・検索機能を実装したい箇所のcontrollerとviewに必要な設定を記述**

になります。
初学者なので間違っている箇所や説明不足の箇所があればご指摘お願いします。

**公式ドキュメント**
https://github.com/activerecord-hackery/ransack
CentOS 日々最小限なセキュリティ更新チェック


+ ない場合はyum-plugin-security をインストール

`yum -y install yum-plugin-security`

+ yum-plugin-securityパッケージを更新

`yum update yum-plugin-security`

+ セキュリティ関連パッケージチェック

`yum --security check-update`

+ セキュリティ関連パッケージ更新

`yum --security update`
おまえの言霊（ツイート）がモンスターを召喚するかもな

# はじめに

> 言霊（ことだま）とは、一般的には日本において言葉に宿ると信じられた霊的な力のこと。言魂とも書く。

こないだ、ビール飲みながら考え事してて、ふと**「Twitterって、現代版の[言霊](https://ja.wikipedia.org/wiki/%E8%A8%80%E9%9C%8A)みたいなものなのかもなぁ」** みたいなことを想像していた。ポジティブなものも、ネガティブなものもあるし、それが人に支持されると大きく拡散されより大きなパワーになる... みたいな。結構、日々のツイートの想いって、現実化するしな。



# アイデア

ちょうどいいので、今遊んでいる、`Vue.js`, `Firebase` あたりの勉強がてら、アプリでも作ってみようか

アプリのイメージとしては、ある人の過去のツイートを分析してネガティブ、ポジティブに分類して、そのツイートの影響度をみてパワーを計算、その結果として起こることは.... モンスターでも出しとくか。まあ、ミニゲームみたいな感じで。

# ざっくり こんな感じか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/d5cad3cd-76d0-f45f-058f-2910eab0f564.png)

# 具体的には...

1. Twitter アカウントからその人の過去のツイートとってくる
2. とってきた Tweet を Google Natural Language API でネガポジ分析
3. Twitter の Favorites および Retweets から ネガポジの影響力（パワー）を計算
4. ネガポジのパワーに応じて、それっぽいモンスターが生まれる、育つ

# つくり始めた

ある程度動き始めたのでデモのビデオを貼っておきます。（なんか gif にすると色がまざる...）

![tweet-monster-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/3177db8c-ff10-15b5-3c62-5be19ebf9e48.gif)


上記の1-3までは動いてきた。あと、4の「**ツイートの内容に応じて、それっぽいモンスターを出す**」というところは、まだできてません。少し実現方法を検討中です。どなたか、お知恵をください。

# 次の目標

1. ツイートの分析結果に応じたモンスターイメージの表示、モンスタープロファイルの生成
2. 結果をセーブして、モンスターが成長、レベルアップ
3. すぐに飽きてしまわないこと！ > 自分

# それから..
Firebase でつくってるので以下に動くの置いておきます。興味あれば **いいね** とか コメント で応援してください。

[Tweet Monster®](https://power-of-words.firebaseapp.com/)

実はちょっと今回のはQiita向きでない記事な気がする。こういうアプリ記事公開するのってどこがいいんでしょうね...
#django って別々のアプリケーションのモデル同士でもリレーション・アソシエーションを設定できるの？ -> できるっぽい

できるっぽい。

# ./user/models.py

カスタムモデルなのは特に意味なし。

```py
from django.db import models

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

```

# ./blog/models.py

```py
from django.db import models
from user.models import User

class Blog(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blogs')


```

 # shell

```
In [1]: u = User.objects.create(username="yumainaura")

In [2]: Blog.objects.create(user_id=u.id)
Out[2]: <Blog: Blog object (3)>

In [3]: u.blogs
Out[3]: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x11197fc50>

```

# NOTE

こちらの記事を読んでどうなんだろう？と思い確認。

>アプリケーションを独立させると、他プロジェクトでの再利用性と、アプリケーション単位でダンプファイル操作が可能になるメリットがあります。

>「users」はcookiecutter-djangoでも使われている名前です。こちらで統一するのがよいと思います。
参考：cookiecutter-djangoを使ってみた

[Django ユーザー カスタマイズ方法 - Qiita](https://qiita.com/okoppe8/items/10ae61808dc3056f9c8e)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
nmcliコマンド備忘録

##ip alias（IPエイリアス）の追加
```
[root@localhost ~]# nmcli connection modify eth0 +ipv4.addresses "172.31.2.101/22"
[root@localhost ~]# systemctl restart network.service
[root@localhost ~]# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 172.31.1.127/22 brd 172.31.3.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.31.2.101/22 brd 172.31.3.255 scope global secondary eth0
       valid_lft forever preferred_lft forever

```

削除したいときは+の部分を-にする

```
nmcli connection modify eth0 -ipv4.addresses "172.31.2.101/22"
```

##resolv.confの設定
```
[root@localhost ~]# nmcli connection modify System\ eth0 ipv4.dns "8.8.8.8 8.8.8.4"
[root@localhost ~]# systemctl restart NetworkManager
[root@localhost ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.8.4
```

その他

```
nmcli c m enp10s0 ipv4.method manual ipv4.address 10.110.2.141/16
nmcli c m enp10s0 connection.autoconnect yes
nmcli c m enp10s0 ipv4.gateway 10.110.0.254
nmcli c m enp10s0 ipv4.dns "180.222.191.16 180.222.191.15 8.8.8.8"

IP変更
nmcli c m enp10s0 ipv4.method manual ipv4.addresses "＜IPアドレス＞/xx ＜デフォルトゲートウェイ＞"
ifup vpn_nic01


```
最終手段

↑上記コマンドだとIPがつかない場合、以下で行う
`ifcfg vpn_nic01 add 10.10.0.15/16`
Gradient Boosting Decision Treeを用いたモデルトレーニング-Breast Cancer Wisconsin (Diagnostic) Data Set-

#やりたいこと
XGBoostの元になったGradient Boosting Decision Treeを用いたモデルトレーニングを体験する。
Gradient Boosting Decision TreeとXGBoostとの大きな違いは、実行速度らしい。

#コード
```
'''
Created on 2019/05/14

@author: tatsunidas
'''

#勾配加速決定木モデルインポート
from sklearn.ensemble import GradientBoostingClassifier

#訓練データとテストデータを分けるファンクション
from sklearn.model_selection import train_test_split

#データの読み込み
from sklearn.datasets import load_breast_cancer
dataset = load_breast_cancer()

#目的変数(y)と説明変数(X)を設定
X = dataset.data
y = dataset.target#[0 = 'malignant' 1 = 'benign']

#訓練データとテストデータに分ける
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.1,random_state=0)

#決定木をトレーニング
gbdt = GradientBoostingClassifier(criterion="friedman_mse")#n_estimators : int (default=100)
gbdt.fit(X_train, y_train)

pred = gbdt.predict(X_test)
print(pred, y_test, sep = '\n')
print("Accuracy of GBDT model is: ", gbdt.score(X_test, y_test))

'''
どのestimatorのtreeを取得するか
gbdt.estimators_[(num of estimators - 1),0]
'''
#可視化する graphviz
from sklearn.tree import export_graphviz
import pydotplus
dot_data = export_graphviz(gbdt.estimators_[0,0], out_file=None,  
                filled=True, rounded=True,
                special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data) 
graph.write_png('test_graph.png')

# 可視化する dtreeviz
from dtreeviz.trees import *
viz = dtreeviz(gbdt.estimators_[0,0],
               X_train, 
               y_train,
               target_name='cancer',
               class_names=["malignant", "benign"],
               feature_names=dataset.feature_names)
viz.view()  # save as svg to tmp dir
```
##結果

予測
[0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1
 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 1 1 1 1]
正解ラベル
[0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1
 0 1 0 0 1 0 1 1 0 1 1 1 0 0 0 0 1 1 1 1]

Accuracy of GBDT model is:  0.9649122807017544

##可視化１(graphviz)
![test_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/ce1dc2fa-33cb-d838-abac-4b771d80fb6f.png)

##可視化2(dtreeviz)
![Screenshot from 2019-05-15 16-49-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379410/cb965673-38bf-2cc9-1028-8c95df764eb0.png)

決定木モデルの可視化はscikit-learn 0.21以上でscikit-learnデフォルトのグラフ関数が使えそう。執筆時点では推奨バージョンが0.20だったため、未テスト。

#参考文献やURLなど
* https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html
* 東京大学のデータサイエンティスト育成講座
【Node-Red】Deleteしたノードで発生するエラー対処



Node-Redでデプロイした時に謎のエラーが発生し、その対処について記述しています。
Node-RedとNode.jsのバージョンは次の通りです。

・Node-RED version: v0.19.6
・Node.js  version: v11.10.1

#現象
発生したエラーは次の通りです。

```
Error: two instances of WebSocketServer cannot listen on the same http server path
```

#原因
　以前作成して消した"WebSocketノード"のインスタンスが残っており、設定したアクセス先に接続できないようです。

#対処
　"WebSoketノード"のインスタンスを削除します。

1.debugタブから対象のエラーの"node:xxxxxxxx.xxxx"をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/1e85b9e1-0fb5-1fc5-4ebc-1a7a84dfc114.png)

２．configタブが表示されるので、unusedを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/45cf0451-0b10-5b32-cf7a-cbcaf25d1cba.png)

３．対象のノード、今回は"WebSocketノード"をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/9d2eea3a-7ef1-40d7-834b-42e1cf0d057a.png)

４．Deleteをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/1632efd6-3555-5080-f62c-77cdcbf17d78.png)

以上でエラーが消えました。

#おわりに
　１度フローに置いたノードを選択して、キーボードのDeleteボタンで消すとこの問題が発生するようです。
ノードを消す際は、対象ノードの設定画面からDeleteするとよいと思います。
Alibaba Cloudでの仮想マシン作成手順[AWSとの違いも記載]

## 仮想マシンの作成
Alibaba Cloudを初めて触るという方向けに仮想マシン作成手順を記します。
AWSを知っている方向けに、AWSとの違いも併せて記します。

##### 1. ECSサービスの選択
ログイン後のコンソールで[「Elastic Compute Service」](https://jp.alibabacloud.com/product/ecs)（以下ECS）をクリックします 
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/67a150d0-a13c-313e-ef98-eb7e98e8d587.jpeg)

ECSダッシュボード画面で「インスタンス」をクリックします
　※AWSとの違い: ECSダッシュボード画面では全リージョンのインスタンスの利用状況が表示される
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/7ea02078-c80e-02aa-ed2d-31d6d0ff269e.jpeg)

##### 2. リージョン確認
インスタンス画面で初めてリージョンが確認できるので「日本（東京）」である事を確認します
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/6ac17288-3237-7ab3-ac76-d120020555a8.jpeg)

##### 3. インスタンス作成開始
「インスタンスの作成」をクリックします
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/07afdbc6-54f6-e00f-76a8-db72b7a5ebab.jpeg)

##### 4. パラメータ入力
以下パラメータを入力して、「次のステップ：ネットワーク」をクリックします

- サブスクリプション（AWSでいうリザーブドインスタンス）か従量課金か
- アベイラビリティゾーン
- インスタンスタイプ
- インスタンスOS
- ルートディスクの種類とサイズ

![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/7f32264e-3699-e32c-1e7c-f7710b9b5a80.jpeg)
![WS000007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/96951c80-ea4b-36f8-c526-c2e28bcbd520.jpeg)

以下パラメータを入力して、「次のステップ：システム構成」をクリックします

- 所属するVPCとVSwitch(AWSでいうサブネット)
- パブリックIPの割り当て
- アタッチするセキュリティグループと主要プロトコルの許可設定
![WS000008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/1672bde6-af62-ec2b-8490-acdd051e2022.jpeg)

以下パラメータを入力して、「次のステップ：グループ化」をクリックします

- インスタンスにアクセスする為の秘密鍵もしくはパスワードを指定します  
　※AWSとの違い：デフォルトだと秘密鍵・パスワード共に指定なし  
- コンソール上のインスタンス名と説明、インスタンスOS内部のホスト名を入力します  

![WS000010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/a680410f-9d8c-bb01-aca0-3a1463db1d3e.jpeg)

タグ名とタグ値を入力して、「次のステップ：プレビュー」をクリックします
![WS000011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/47ba3e40-479f-4895-0dcd-99fbdca62fc3.jpeg)

##### 5. インスタンス作成の完了
「ECS SLAと利用規約に同意します」にチェックを入れて、「インスタンスの作成」をクリックします
![WS000013.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/f3ca1baf-3c35-8b7b-ee5c-487cd504fc81.jpeg)

##### 6. 作成されたインスタンスの確認
有効と表示されたら、「コンソール」をクリックして、当該インスタンスが作成されている事を確認します
![WS000015.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/40c11e37-e25c-639f-7c80-783c6f46444b.jpeg)
![WS0000166.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/2a0c29c7-b05f-71de-b27f-7e6c56c8a12e.jpeg)
パブリックIP/EIPを割り当てている場合は、IPアドレスの列にグローバルIPアドレスが表示されます
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139731/095e566f-6af3-463a-9793-54e747923003.jpeg)
初心者のフローチャート入門

プログラムを組むには、処理の流れがわかってないとダメ…。
処理の流れを図式化すると、わかりやすいし見返せるし便利…。
ということで、フローチャートについてまとめて見ました。

# フローチャートとは
　処理の各ステップを箱で表し、そのステップの流れを視覚的に見えるように図にしたもの。
流れ図とも呼ばれる。

# フローチャートの利点
- 問題解決の手順が視覚的に明確に表すことができる
- 処理手順が追いやすく、手順に問題がある際発見・修正することが容易になる
- 複数人で問題解決を行う際、担当箇所の明確化や理解の向上に役立つ

# 実際にどう書くのか
　記号とその内容、その流れで成る。

<table>
  <tr>
    <td>記号</td>
    <td>名称</td>
    <td>詳細</td>
  </tr>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410737/30eb1ce8-92b5-cc9f-1261-bddacd04adb2.png" width=80px>
    <td>開始/終了</td>
    <td>一連の処理の開始、終了を表す</td>
    </td>
  </tr>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410737/328b30e1-cfbb-9afd-1a79-5d1e62431560.png" width=80px></td>
    <td>処理</td>
    <td>一般的な処理</td>
  </tr>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410737/25ae3f9d-7e63-2512-baf0-211e580910f3.png" width=80px></td>
    <td>判断</td>
    <td>条件を満たすか否かを判断する</td>
  </tr>
  <tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410737/3a12d7a5-49a4-18ee-d5d4-bda9fc4875da.png" width=80px></td>
    <td>矢印</td>
    <td>データや処理の流れを表す</td>
  </tr>
</table>

とりあえず上記の記号があればなんとなくフローチャートが書ける。
上記の他にもループの記号や関数、ファイル入出力などを表す記号もある。

## 実例
<img src='https://cdn-ak.f.st-hatena.com/images/fotolife/g/gene320/20180606/20180606224145.png' width="90%">
引用元：<a href="https://www.fastclassinfo.com/entry/points_for_flowchart">フローチャート（フロー図）の書き方や作成方法の3つのポイント</a>

# 注意したい点
　上から下に流れるように書くのが基本。戻るのは最小限にとどめたほうが良い。
分岐した後合流する際は、プロセスに直接つなげるのではなく直前の線に合流させる。
矢印は交差させない。どうしても交差してしまうときは飛びこえる線に設定すると良い。

# まとめ
　細かい部分まで書くかどうかは人それぞれですが、細かく書きすぎても見にくいものだと良くないし、逆に大雑把過ぎてどうなっているかわからなくなってしまえばフローチャートの意味がないので、ほど良くまとめられるようにすべきですね。
プログラミングにかかわらず日常でも軽くまとめてみると、効率的に動くことができるかつアルゴリズムへの理解が深まるかもしれないですね。
【Rails Action Cable】チャットの投稿が反映されない/別のRoomに反映されてしまった時の対処方法。

# はじめに
[以前の投稿(【Rails】 Action Cableを用いてチャット機能を作成)で](https://qiita.com/yusaku_/items/4fdb95aeff2bde1d21ae)、ChatRoom毎で非同期表示される（自分/相手の投稿をリアルタイムで表示できる）チャットアプリを作成したが、
違うChatRoomの投稿の表示が反映されてしまうというバグが発生していた。


具体的には

```
Aさん：Room1にいる　Bさん：Room2にいる
↓
Aさんが投稿した内容がRoom1だけでなく、Bさんの画面(Room2)にも表示が反映されてしまった
```

他にも、投稿したのにも関わらず表示されない（ただしDBにはPOSTされている）といった事象も発生していた。

# 原因と解決方法
どうやら**turbolinks**が悪さをしているらしく、以下の方法で解決した。

### ◆ turbolinksを無効化

①**gemfile**の`gem 'turbolinks'`を削除
②**application.js**の`//= require turbolinks` を削除

### ◆ room.coffeeをfix
1行目の以下のコードを

```
document.addEventListener 'turbolinks:load', ->
```
↓以下に変更

```
$ ->
```
カラム追加・カラム並び替え(Embulk)

Embulkのfilter-columnプラグイン使い方メモ

https://github.com/sonots/embulk-filter-column

### 構文
- nameは必須
- srcかdefaultは必須
- defaultの場合typeは必須
- formatはtimestampの時だけ指定できて、デフォルトは文字列でデフォルト生成されたtimestamp(ただadd_timeあるから基本は使わない)

## カラム追加
```
filters:
  - type: column
    add_columns:
      - {name: カラム名 type: 型}
      - {name: カラム名 src: コピーするカラム名}
      - {name: カラム名 default: デフォルト文字列}
```

## カラム並び替え
```
in:
　・
　・
　・
  parser:
    columns:
```
で指定したカラムをそのまま並び替えて指定

```
filters:
  - type: column
    columns:
      - {name: カラム名 src: コピーするカラム名}
      - {name: カラム名 type: 型}
      - {name: カラム名 default: デフォルト文字列}
```

## 雑感
現場では複数条件やステップがあるためDigdagと組み合わせてSQLで格納していたが、単なるカラムの追加・並び替え・削除だったらこっちを使うのが良さそう
Vue Router で TypeError: Cannot read property '_c' of undefined

## 症状
ページが遷移しない。
以下のようなログが出力される。

```
vue-router.esm.js?880d:1921 TypeError: Cannot read property '_c' of undefined
```

## 原因
単純にタイプミス

```
誤: components
正: component
```

```javascript
import Vue from 'vue';
import VueRouter from 'vue-router';
import Top from './views/Top.vue';
import Portfolio from './views/Portfolio.vue';
import Stocks from './views/Stocks.vue';

Vue.use(VueRouter);
const routes = [
  {
    path: '/',
    name: 'top',
    components: Top,  // <- s 要らない
  },
  {
    path: '/portfolio',
    name: 'portfolio',
    components: Portfolio,  // <- s 要らない
  },
  {
    path: '/stocks',
    name: 'stocks',
    components: Stocks,  // <- s 要らない
  },
];

export default new VueRouter({
  routes,
});

```

## きっかけ
これで気づけた

* [vue-router : failed to resolve async component render - Stackoverflow](https://stackoverflow.com/questions/48975648/vue-router-failed-to-resolve-async-component-render)
#django  | モデルオブジェクトの保存・更新・削除でトランザクションの有効範囲をリクエスト開始から終了までにする設定 ( ATOMIC_REQUESTS )

使えそうです。

![image](https://user-images.githubusercontent.com/13635059/57750193-37c5a480-771c-11e9-9419-a054fcf866c3.png)


[現場で使える Django の教科書《基礎編》 | 横瀬 明仁 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81/dp/4802094744/ref=pd_lpo_sbs_14_img_2?_encoding=UTF8&psc=1&refRID=6X8DN0W9SFBYEXVMEPM5)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->