OmniAICreator/Qiita-1.07M huggingface dataset:
CPANのパッケージをrpm化する

* `fpm`を使う。CentOS7にて確認。

* https://www.cpan.org/modules/by-module/IO/

```sh
wget https://www.cpan.org/modules/by-module/IO/IO-BufferedSelect-1.0.tar.gz

tar xzf IO-BufferedSelect-1.0.tar.gz
cd IO-BufferedSelect
```

* [IO-BufferedSelect-1.0.readme](https://www.cpan.org/modules/by-module/IO/IO-BufferedSelect-1.0.readme)を見ながらビルド。

```sh
perl Makefile.PL
make
make install DESTDIR=/opt/cpan
```

* /opt/cpan/usr/local/share/perl5/IO/BufferedSelect.pm
* /opt/cpan/usr/local/share/man/man3/IO::BufferedSelect.3pm

にインストールされる。これをrpm化する。

```sh
fpm -s dir \
  -v 1.0 \
  -t rpm \
  -n local-perl-IO-BufferedSelect \
  -p local-perl-IO-BufferedSelect-1.0.el7.x86_64.rpm \
  -C /opt/cpan \
  --prefix / \
  -a x86_64 \
  ./usr/local/share/perl5/IO/BufferedSelect.pm ./usr/local/share/man/man3/IO::BufferedSelect.3pm
```

* `local-perl-IO-BufferedSelect-1.0.el7.x86_64.rpm` が作られる。
    * `-s dir`じゃなくても良い気がする。
    * x86_64ではなく noarch 指定で良い気もする。

## DBD-mysqlのビルドオプションを渡す場合

```sh
# 一覧の確認
perl Makefile.PL --help

perl Makefile.PL \
 --mysql_config=/opt/mysql/bin/mysql_config
 --libs="-L/opt/mysql/lib/mysql" --nossl

# --libs="-L/opt/mysql/lib/mysql -lmysqlclient -lcrypt -lnsl -lm"

# --libs="-L/opt/mysql/lib/mysql -L/opt/openssl-1.0.2t/lib64"
```

## undefined symbol: Perl_xs_apiversion_bootcheck

`undefined symbol: Perl_xs_apiversion_bootcheck`のメッセージは
.soファイルをコンパイルをしたときのperlと異なるPerlを使ったときに出る。
開発環境限定のルートを設定する方法


# 動機

masterブランチに食い込んでいるのに一般公開できないページが溜まってしまったので。

# コード

```index.js
import Vue from 'vue'
import Router from 'vue-router'
import DevRoute from './dev-route'

Vue.use(Router)

const router = new Router({
  routes: [
    ...DevRoute,
  }
})

export default router

```

```dev-route.js
import test from '@/pages/dev/test'

const route = []

if (process.env.NODE_ENV !== 'production') {
  route.push(...[
    {
      path: '/dev/test',
      component: test 
    },
    // ルートを足すならここ
  ])
}

export default route
```

# 雑感

計画性を持って正しくブランチが切れていたら、
ビルドのたびにルートをコメント化するような羽目にはならなかったのだろう…。

スプレッド構文、超便利。
強化学習９　ChainerRLの魔改造

強化学習８まで終了していることが前提です。

強化学習８では、ChainerUIの魔改造をしました。
あれでもいいのですが、今回は、同じようなことをChainerRLでします。

まず、
userFolder/anaconda3/envs/chainer/lib/python3.7/site-packages/chainerrl/experiments/evaluator.py
の３１行目を変更します。

変更前

```python
_basic_columns = ('steps', 'episodes', 'elapsed', 'mean',
                  'median', 'stdev', 'max', 'min')
```
変更後

```python
_basic_columns = ('step', 'episode', 'elapsed_time', 'mean',
                  'median', 'stdev', 'max', 'min')
```

これで、scores.txtのヘッダーが変更されるので、ChainerRLの変更は不要になります。

もう一つは、
userFolder/anaconda3/envs/chainer/lib/python3.7/site-packages/chainerrl/experiments/train_agent.pyの
９３行目にあるdef train_agent_with_evaluationの関数末尾に追加します。pythonは、インデントで動くので、インデントに注意が必要です。

```python
    json_list = []

    with open(os.path.join(outdir, 'scores.txt'), 'r') as f:
        for row in csv.DictReader(f,delimiter='\t'):
            for key in row:
                row[key]=float(row[key])
            json_list.append(row)
    with open(os.path.join(outdir, 'log'), 'w') as f:
        json.dump(json_list, f)
```

importも追加します。

```python
import json
import csv
```

魔改造すると、ノーマルChainerUIで簡単に見ることができるので、chainerRL本家も対応してくれるといいなあ。
windowsは、少し違うので強化学習12にまとめて書きます。
postfix の queue_directory を tmpfs に設置する

PRECSの佐々木です。

弊社ではECを主軸にサービスを展開しており、弊社サービスを利用する顧客向けに月間1億通超のメールを取り扱っています。

大量メールを一定時間内に配信するには、高速にメールを配信できるメールサーバーが不可欠です。

弊社では postfix をチューニングし、1 VMあたり100万通/時超の性能のメールリレーサーバーを構築し運用しておりますが、postfixでメールを高速に配信するためのノウハウについて何回かに分けて順次公開いたします。

まずは第1回として、postfixのqueue_directoryをtmpfsに配置する方法について記載いたします。

## queue_directory を tmpfs に配置する理由

queue_directory を tmpfs に配置する理由はI/Oボトルネックを減らすためです。

tmpfsは物理メモリ及びスワップ領域を含む仮想記憶上に作成されるファイルシステムです。
メモリ上に配置されるためHDDやSSDに比べ、高速なRead/Writeが行えます。

1時間に100万通超のメール配信を行うには単純計算で、毎秒278通以上のメールをキューに格納する必要があります。
postfixは状態毎に複数のキューがあり、1通のメールを単純に配信するだけでも incoming → activeの遷移を辿り、遅延がある場合は更に active → deferred → active の順に遷移します。
キューに格納されたメールはファイルシステム上に書き込まれるため、Write → Read → Deelete だけで1つのキューにつき単純計算で3回、ファイルやディレクトリを管理しているinodeへのRead/Writeも考慮すると更に複数回のI/Oが発生することになります。

postfixのqueue_directoryをtmpfsに設置することで、I/Oボトルネックを減らし高速化することができます。
又、SSDではなくメモリ配置することで、ストレージの長寿命化も期待することができます。

## 環境

今回は下記環境で説明します。

* CentOS 7.x
* postfix 2:2.10.x （baseリポジトリ）

## 設定

### 1. tmpfs のマウント設定

まず tmpfs のマウントポイントとなるディレクトリを作成します。

```bash
sudo mkdir -p /var/tmpfs
```

次に tmpfsをマウントポイントとなるディレクトリにマウントします。

```bash
sudo mount -t tmpfs tmpfs -o rw,noatime,nodiratime /var/tmpfs
```

マウントできました。
起動直後にマウントされるように、 /etc/fstab にエントリーを記載します。

```bash
tmpfs                   /var/tmpfs              tmpfs   rw,noatime,nodiratime   0  0
```

尚、実際に運用している環境ではオプションでsizeも指定していますが、多くの環境で試されることも考慮して上記例では外しています。
必要に応じて適宜記載ください。

### 2. queue_directory の設定

次にpostfixの設定を変更し、queue_directoryをtmpfsファイルシステム上のディレクトリに設定します。

queue_directory は /etc/postfix/main.cf に設定を記載します。
main.cfには、下記のように記載します。

```
queue_directory = /var/tmpfs/postfix
```

main.cfの書き換えはエディタで直接行うこともできますが、設定変更を行うコマンドとしてpostconfコマンドが用意されているため、postconfコマンドでの設定方法で説明します。

```
sudo postconf queue_directory=/var/tmpfs/postfix
```

### 3. queue_directory の初期化

次に queue_directory を初期化します。
tmpfs の場合、再起動後は動作に必要なディレクトリが消えてしまうため、再実行できるようにバッチスクリプトとして用意しておきます。

今回は例として、 /usr/local/sbin/postfix_spool_init.sh にバッチスクリプトを作成することにします。
postfix_spool_init.sh に下記のように記載してください。

```bash
#!/bin/bash

mkdir -p /var/tmpfs/postfix
chmod 755 /var/tmpfs/postfix
postfix check
```

/usr/local/sbin/postfix_spool_init.sh に配置し、実行権を追加します。

```bash
sudo cp postfix_spool_init.sh /usr/local/sbin/postfix_spool_init.sh
sudo chown root:wheel /usr/local/sbin/postfix_spool_init.sh
sudo chmod +x /usr/local/sbin/postfix_spool_init.sh
```

queue_directory 初期化のためバッチスクリプトを実行します。

```bash
sudo /usr/local/sbin/postfix_spool_init.sh
```



### 4. postfix 起動時に queue_directory を初期化する

postfix 起動時に queue_directory が初期化されるように設定します。

```bash
sudo systemctl edit postfix
```

下記設定を記載します。

```ini
[Service]
PIDFile=/var/tmpfs/postfix/pid/master.pid
ExecStartPre=-/usr/local/sbin/postfix_spool_init.sh
```

上記で postfix 起動時に queue_directory が初期化されるようになります。

## おわりに

以上、postfix で高速配信を行うチューニングの方法として、 queue_directory を tmpfs に設置する方法について記載いたしました。
高速配信チューニングについては多数記事を書けるネタがあるため、今後も順次記載していこうと考えています。
よく使う組み込み関数、メソッド一覧

#はじめに
　最近、組み込み関数なのかメソッドなのかよくわからなくなってきてしまったので、よく使うものを分類してみました。

[すべての組み込み関数はこちら](https://docs.python.org/ja/3.5/library/functions.html)

|組み込み関数|機能|
|:---|---|
|print()|()内を表示する|
|str()|str型のオブジェクトを返す|
|int()|int型のオブジェクトを返す|
|float()|float型のオブジェクトを返す|
|bool()|bool型のオブジェクトを返す。空、0、NoneはFalseを返す|
|type()|オブジェクトの型を返す|
|input()|文字列を入力する(入力値は文字列扱い)|
|len()|要素数を取得する|
|abs()|絶対値を返す|
|sum()|合計を返す|
|max()|最大値を返す|
|min()|最小値を返す|
|pow(a, b)|aのb乗を返す|
|range()|指定範囲の整数列を返す|
|round()|値を四捨五入する。第２引数は小数点以下の数|
|hex()|16進数を返す|
|oct()|8進数を返す|
|bin()|2進数を返す|
|enumerate()|シーケンスとインデックスを取得する。第２引数はインデックスの開始ナンバーでデフォルトは0|
|open()|ファイルを開く|

|メソッド|機能|リスト|タプル|辞　書|文字列|
|:---|:---|---|---|---|---|
|.append()|リストの末尾に要素を追加する|〇
|.extend()|リストの末尾にシーケンスを追加する。リスト、タプル、辞書を追加できる|〇
|.reverse()|リスト要素の順番を逆にする|〇
|.sort()|リスト要素を並べ替える|〇
|.remove()|指定した値と同じ要素を検索し、最初の要素を削除する。要素自体が書き換わる|〇
|.count()|ある要素がリストにいくつ含まれるか数える|〇|〇|||
|.pop()|指定したインデックスの要素を１つだけ抜き出す|〇||〇
|.clear()|すべての要素を削除する|〇||〇|
|.keys()|辞書型のkeyについてループ処理する|||〇|
|.values()|辞書型のvalueについてループ処理する|||〇|
|.items()|辞書型のkeyとvalueについてループ処理する|||〇|
|.keys()|辞書型のkeyについてループ処理する|||〇|
|.values()|辞書型のvalueについてループ処理する|||〇|
|.items()|辞書型のkeyとvalueについてループ処理する|||〇|
|.upper()|全体を大文字に変換する||||〇
|.lower()|全体を小文字に変換する||||〇
|.capitalize()|最初の文字を大文字に、その他を小文字にする||||〇
|.replace(a, b)|文字列aを文字列bに置き換える||||〇
|.split()|文字列を特定の文字で分割する||||〇
|.join(シーケンス)|連結した文字列を得る||||〇
|.index()|最初に指定した文字が現れる位置のインデックス値を返す||||〇
|.format()|{}を()内で置き換える||||〇|
GCP上のCentOS8のPortを変更するやり方

## 前回までのあらすじ

前回はGCP上のマシンを作ってそこにVSCodeを使ってアクセスする方法を説明しました。
[VSCodeとGCPを使ってリモート開発マシン作ってみた](https://qiita.com/noumi0k/items/e6a6d0ca1c663687af1f)

ここまでは良かったのですがPort22のままだと僕だけではなく、不正アクセスの人にとっても簡単にアクセスを試せる環境になってしまうと言うことで今回はsshアクセスできるPortを変更していきたいと思います。

## 今回やること
SELinuxを無効にせずちゃんとPort開ける。

 - /etc/ssh/sshd_configの設定を書き換える(CentOS側)
 - SELinuxの設定を書き換える(CentOS側)
 - ファイアウォール ルールを書き換える(GCP側)

## 注意
この作業はアクセスできるPortを変更します。
**途中でsshの接続を切ってしまうと自分もアクセスできなくなる可能性があります。**

設定が全て完了し、別のシェル(ターミナル)で接続確認を完了してから接続を切るようにしてください。

## /etc/ssh/sshd_configの設定を書き換える(CentOS側)
ポート番号は0～65535の中から選べますので好きな数字にしてください。

```
# 設定ファイルのバックアップを行う
$ sudo cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.org

# ポート番号を変更する
$ sudo sed -i -e "s/#Port 22/Port [変更したいポート番号]/g" /etc/ssh/sshd_config
```

`#Port 22`の部分を書き換えるコマンドなので、すでに書き換えている場合はそれに置き換えて動作させてください。

## SELinuxの設定を書き換える(CentOS側)

```
# semanageを使うためにsemanageを含むパッケージをインストール
$ sudo dnf install -y policycoreutils-python-utils

# ポート番号を変更
$ sudo semanage port --add --type ssh_port_t --proto tcp [変更したいポート番号]

# 変更できてるか確認
$ sudo semanage port --list | grep ssh
ssh_port_t                    tcp      49152, 22

# 再起動して設定を有効にする
$ sudo systemctl restart sshd
```
## ファイアウォール ルールを書き換える(GCP側)
まずはGCP(Google Cloud Platform)のページを開きファイアウォールの設定画面に移動します。
`メニュー>VPCネットワーク>ファイアウォールルール`
<img width="486" alt="スクリーンショット 2019-11-15 8.52.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67805/cd6f1863-6a93-90d5-16e3-c2d4d8f2420d.png">

次にファイアウォールルールを作成をクリックし下記設定を行います。

 - 名前：ssh-[変更したいポート番号] #などわかりやすいルール名
 - 優先度：1000 #数が小さい方が優先なので他の65534より小さい数字
 - トラフィック方向：上り
 - 一致したときのアクション：許可
 - ターゲット：ネットワーク上のすべてのインスタンス<br>
 　　#プロジェクトごとでいつもやってるけどわかりにくいので一旦これ。
 - ソースフィルタ：IP範囲
 - ソースIPの範囲：0.0.0.0/0 #今回は接続元IPアドレスを固定できないので全開放
 - プロトコルとポート：指定したプロトコルとポート
  - tcpにチェック [変更したいポート番号]を設定

 ルールの設定が完了すると他の設定と同じように一覧に表示されるので確認してください。
<img width="1043" alt="スクリーンショット 2019-11-15 8.53.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67805/a5901b33-737b-0371-a464-0d09123f781b.png">

## 動作確認
下記でアクセスできるか試してみてください。
今までと違ってポート番号が必要になりますが、アクセスできると思います。
`$ ssh [ユーザ名]@[外部IP] -i ~/.ssh/[sshkey名] -p [変更したいポート番号]`

もし`~/.ssh/config`を設定していた場合は`Port [変更したいポート番号]`を追加することで今まで通りのコマンド・方法でアクセスが可能です。

```
Host [Host名]
  HostName [外部IP]
  User [ユーザ名]
  Port [変更したいポート番号]
  IdentityFile ~/.ssh/[sshkey名]
  IdentitiesOnly yes
```

## おわりに

これでPort22で不正アクセス出来ちゃう環境から脱することができたと思います！
これからも少しずつセキュアな生活を満喫していきましょう＼(^^)／

Twitterフォローもよろしくです！
 - [@noumi0k](https://twitter.com/noumi0k)

この記事も合わせて読んでみてください。
[VSCodeとGCPを使ってリモート開発マシン作ってみた](https://qiita.com/noumi0k/items/e6a6d0ca1c663687af1f)
AWS ACM で com.amazon.coral.service.InternalFailure エラーが出る

ACM で証明書のリクエストを行ったら、`com.amazon.coral.service.InternalFailure` エラーが表示された。

実行していた IAM ユーザは、AdministratorAccess ポリシーと下記のように `NotIpAddress` による IP 制限ポリシーをアタッチしていた。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx.xxx/32"
                    ]
                }
            }
        }
    ]
}
```

一旦、この IP 制限をかけていたポリシーを外すと正常に動作した。
ACM 設定が終わってから、IP 制限を戻す予定。
ionicのgridで楽々reverse

# はじめに
どうも！
今回はionic4で開発をしていてこれはちょっといいなと思った機能をご紹介します
ion-wrap-reverseってご存知ですか？
こいつ痒いところに手が届く機能なんです。

# ion-wrap-reverseとは
使い方としてはこう

```html
<ion-content>
  <ion-grid>
    <ion-row class="ion-wrap-reverse">
      <ion-col size="12" size-sm>
        <ion-button color="primary">上だったのに</ion-button>
      </ion-col>
      <ion-col size="12" size-sm>
        <ion-button color="danger">下だったのに</ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>
```

 `ion-grid`に `class="ion-wrap-reverse"`を追加すると
設定したsizeに合わせてレスポンシブ対応をするんですが、
上下逆になってくれるんです！
cssでも `flex-wrap: wrap-reverse;`を使えばいけますが
`class="ion-wrap-reverse"`の方が楽チンで好きですw
##デモ![loxhn-ew1t5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311852/5ee247bf-e3a4-ac02-fc6e-4108bc0a7568.gif)

#終わりに
ion-wrap-reverseの様なionic特有のクラスっていっぱい有りそうなので
次の記事でまとめやりたいなぁと思います。
pythonのfor文中で複数の変数を定義する方法

for文で変数名を変えながら定義する方法ってどうやるんだ? となったのでメモ  

## python の組み込み関数 exec を使う

```
for i in range(5):
    exec('var%d = %d' % (i, i**2))

>>>var0, var1, var2, var3, var4
>>>(0, 1, 4, 9, 16)
```
他にも配列に入れていくやり方が考えられますが、一気に複数の変数を作るならexecを使うのがスマート。
JSXを使わずにJS内にHTMLを記述する

#結論
IE以外はテンプレートリテラル
IEは無名関数 + コメントアウト
を使用する

※htsignさんにコメント頂いた内容を更新しました。ありがとうございます。

#IE以外(ES6対応ブラウザ)
```getHtmlTemplete.js
let insert_html = `
 <div class="greeting">
   Hello World!
 </div>
`;

document.getElementById("insert_target").innerHTML = insert_html;

```

#IE
```getHtmlTemplete.js
var insert_html = function(){/*
 <div class="greeting">
   Hello World!
 </div>
*/}).toString().match(/\/\*([^]*)\*\//)[1];

document.getElementById("insert_target").innerHTML = insert_html;

```
TypeError: The added layer must be an instance of class Layer. Found: <keras.engine.training.Model object at XXXXXXXX>

#エラー内容
コード

```python
from keras.applications.resnet50 import ResNet50
from tensorflow.keras.models import Sequential

resnet = ResNet50(include_top=False, pooling='avg', weights='imagenet')
my_new_model = Sequential()
my_new_model.add(resnet)
```

エラー

```
TypeError: The added layer must be an instance of class Layer. Found: <keras.engine.training.Model object at XXXXXXXX>
```

#原因
kerasとtensorflow.kerasを同時に使っていたからだと思う。
#解決
```python
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.models import Sequential

resnet = ResNet50(include_top=False, pooling='avg', weights='imagenet')
my_new_model = Sequential()
my_new_model.add(resnet)
```
enumで、キーの文字列に数字を含める方法

＊前提＊

```Rails:schema.rb
t.integer "sex"
t.integer "age"
```


通常のenum(文字列のみ)の書き方は以下の通り。

```Rails:user.rb

enum sex: { 未選択: 0, 男性: 1, 女性: 2 }
```


enumで数字を含めるには以下のように

```Rails:user.rb

enum age: { 未選択: 0, "10代": 1, "20代": 2, "30代": 3, "40代": 4, "50代": 5, "60代": 6, "70代": 7, "80代": 8, "90代": 9 }

```

キーをダブルクオーテーション("")で囲えば良い。
むしろ本来こんなふうに書くべきなのかもしれない。
file geodatabaseの中身をサクッと参照する

ArcGISを使っていると、
ちょっとしたときにあのデータの中身なんだったっけなと思うことがたびたびある割に
エクスプローラでは参照できないため、ArcGIS Proなどを起動しないと参照できないのがめんどくさい。

ということで、以下をNotebookで実行させて確認するとたぶん速い


~~~ python
from arcgis.features import SpatialDataFrame
import arcpy
import os
gdb = r"C:\temp\sample.gdb"
~~~

~~~ python
arcpy.env.workspace = gdb
arcpy.ListFeatureClasses()
~~~

これで中身のフィーチャクラスが参照できるので、下で名称を指定する

~~~ python
fc = os.path.join(gdb, "参照したいフィーチャクラス名")
SpatialDataFrame.from_featureclass(fc)
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106639/1fcf5553-7571-1416-c330-e90e042b6391.png)

こんな感じ。

自分の備忘録としても残しておく。
Ubuntu16.04で、snapを使って、Heroku CLIをインストールする

# はじめに

Ubuntu16.04に、snapを使って、Heroku CLIをインストールする手順についてまとめました。インストール手順は、公式サイトを見て、その通りにやって下さいと言えばそれまでなのだが、初学者向けに、少し掘り下げて詳しく書いてみた。

《公式サイト》
https://devcenter.heroku.com/articles/heroku-cli#download-and-install

# 環境

Ubuntu 16.04.5 LTS
Windows10 + Vagrant

# 手順

・ 公式サイトを読んでみると、注意点として、**Heroku CLI**をインストールする前に、**Git**がインストールされている事が前提とあるので、Gitがインストールされていなければ、インストールして下さい。

・ **Ubuntu16+**の場合は、どうも、**snap install**コマンドを推奨しているようです。今まで、パッケージのインストールは**apt install**コマンドしか使った事がなかったのだが、依存関係を解消させるために、**snap**というパッケージ管理システムが存在しています。Heroku CLIでは、**apt**ではインストールができないという事になります。環境がUbuntu16+より低いバージョンでは、snapは動かせないようで、**Ubuntu16.04**であれば、snapはデフォルトで入っているようです。

・ 本当にsnapがプレインストールされているか確認します。コマンド一覧が表示されればインストールされています。

```
snap
```

・ バージョンを確認してもOK。

```
snap version
```


>　● 参考：aptとsnapの違いについて
　　https://teratail.com/questions/158844

>　● 参考：snapコマンドの詳細について
　　https://mekou.com/linux-magazine/snapsnappy-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/

・ 公式サイトには、**snap**以外に、**curl**でインストールする方法も記載されています。インストール方法は２種類あるという事になります。ただし、curlでインストールすれば、Heroku CLIのバージョンが上がった時は、**apt-get**コマンドを使って、手動でアップデートをしなくてはいけない手間がかかるため、その点、snapでインストールしておけば、自動でアップデートしてくれるという違いがあるようです。自分は、snapでやる事にした。

・ curlを使ってインストールする場合のコマンド（参考）

```
curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
```


・ このコマンドで、インストール済のsnapパッケージの一覧が表示されます。しかし、snapでインストールするのは今回が始めてであるため、snapでインストールされたものは未だありませんと表示されます。

```
snap list
No snaps are installed yet. Try 'snap install hello-world'.
```

・ 公式サイト通りにコマンドを実行します。処理は、割と早く終わり、30秒程度でインストール完了。

```
sudo snap install --classic heroku
```

・ 再度、インストール済のsnapパッケージ一覧を表示すると、**core**と、**heroku**が表示されます。確かにインストールされた事を確認する。

```
snap list
```

・ バージョンを表示させて、Heroku CLIがインストールされた事を確認する方法でもOK。但し、OSを再起動しないと、反映されなかったので注意。

```
heroku --version
```

・ Herokuにログインする。メッセージが表示されるので、そのままEnterでOK。

```
heroku login
heroku: Press any key to open up the browser to login or q to exit:
```

**heroku: Waiting for login... ⢿** このようなメッセージが出てきて、なかなか先に進まない場合は、このように入力すればOK。

```
heroku login --interactive
```

Herokuにアカウントを作成した時の、**Email**と**パスワード**を聞いてくるので、入力してログインする。

・ ログアウトして終わり

```
heroku logout
```
Docker&Railsの環境構築をしようとしたらはまった話

## はじめに
私は、Arch Linuxをインストールして1カ月くらい経つぐらいの人です。Arch Linuxの知識ほぼないです:sweat: Dockerについても今回初めてやるので、全く知識がない状態の人がDockerやってみたので、おかしいところが少々あるかもしれないので、よろしくお願いします。

## 私が開発した環境
|種類  |version |
|---|---|
|使用OS  |Arch Linux|
|Docker  |19.03.4|
|Ruby  |2.5.7|
|Rails  |5.2.3|
|rbenv  |1.1.2|
## 実現したかったこと
ローカル上のRuby,RailsのバージョンをDockerコンテナの中のバージョンと揃えて、開発をすること。

## 試してみたこと
* rbenvを使って、Rubyのバージョンを切り替える。
 * バージョンを変えても適用されないなどと、環境がおかしくなり、断念しました。  
* dockerコンテナの中で、開発をすべて行う(?)
 * railsコマンドを書き換えてdockerコンテナのバージョンで作成するように書き換えたら、うまくできました。

私なりに、やって正解だったことをまとめます。

## やったこと
```rails``` コマンドをそのまま打ち込むとローカルのRuby,Railsのバージョンが適用されてしまうため、頭にかならず,```docker-compose run web``` とつけるとDockerコンテナ内のバージョンが適用されるので、バージョンのエラーなどが起きなくなり、正常に作成できます。

## 注意すること
また、何回も同じポート番号を指定してしまうと、重複エラーが出るので、ポート番号に気を付けましょう！間違えた場合は、
``` docker ps```コマンドで、今動いてるコンテナを確認して、```docker stop コンテナ名(または、$(docker ps))``` コンテナを止めてあげないと、削除することができないので、気を付けます。止めた後、```docker rm コンテナ名``` でコンテナを削除しましょう。また全削除したい場合は```コンテナ名``` を```$(docker ps -a)``` とすると今あるコンテナをすべて削除することができます。




## 最後に

rbenvを駆使してバージョン問題に取り組むことも重要ですが、
コンテナ技術をつかえば違う選択肢もあるのかな、と感じました。
dockerコンテナわかると、消したり作ったりするの楽しくなるんでよかったら、やってみてください！


参考
[DockerでRailsの環境構築してHerokuへデプロイする](https://qiita.com/fuku_tech/items/dc6b568f7f34df10cae7)
Amazon RDS for MySQL でスナップショットから復元したDBにアクセスする

某案件で Amazon RDS for MySQL を利用しています。
追加開発で既存テーブルにカラム追加をしてAPIを新設してほしいという作業依頼がきました。

追加対象のテーブルの現在のレコード数を聞くと、7桁レベルのレコードがあるようです。
そこへ ALTER TABLE 〜 を流すと、どのくらい時間がかかるのだろうか？ リリース時、本番環境で流せるレベルだろうか？

ふと気になったので先輩に相談し、スナップショットからデータベースを復元し、検証用のデータベースを作成して試してみることにしました。
スナップショットは毎晩深夜に自動取得されているものを使います。

Amazon RDS > スナップショット で表示される一覧から、復元したいスナップショットを選択して 「スナップショットから復元」を選択します。

データベース名の入力が必須、インスタンスタイプがデフォルトで本番環境と異なったものが選択されていたので、選択し直しました。
これは本番環境のインスタンスタイプが "旧世代のインスタンスタイプ" という扱いになってしまったからかもしれません。

それと念の為、本番環境とは別のVPCを選択して起動することにしました。

最後に 「DBインスタンスの復元」 ボタンを押して数分待つと復元されたデータベースを使えるようになります。


# さて、どうやって接続してSQLを流そうか？

データベースを復元した先と同じVPCにEC2インスタンスを1つ立てました。これをSSHの踏み台サーバーとして使います。
RDSについているセキュリティーグループでEC2インスタンスのIPから MySQL/Auroraのアクセスを許可する設定を追加しました。

## さてこれで接続できるはず・・・！

MySQLクライアントとして、TablePlus というアプリを使います
https://tableplus.com/

ここで気がつきました、DB復元時にユーザー名やパスワードの設定が何もしていません。
「RDS 復元 パスワード」 いろいろググった結果、これだという情報にたどり着けませんでした。

もしや元のデータベースと同じ情報ではないか・・・と試してみると無事接続できました！

## 大事なことなのでもう一度、
**スナップショットから復元したデータベースは、元のデータベースと同じユーザ名・パスワード を使ってアクセスできます**。


# 結果

TablePlusから目的の SQL文を流して、おおよその実行時間が判明しました。
結果、数十秒 という単位で終わることがわかり、先輩に報告です。

このくらいであれば、無理な負荷ではない、ただしリリース時はメンテナンス状態にしてアクセスをなくした状態で行うのが良さそう
といった相談をしました。

負荷が気になったときは、実際に同等の環境を作って動かして検証するのが確実ですね。
そんな話を、別な先輩が書いた [Amazon Web Services負荷試験入門](https://www.amazon.co.jp/dp/B075SV3VN3) っていう本で読んだことを思い出しました。


# 最後に

検証用に立てたデータベースインスタンスはそれなりのサイズなので、料金もそれなりにかかってきます。
検証が終わったあとは忘れずに削除しましょう。EC2インスタンスも忘れずに。
Ionic+AnglerJSでQRコード生成するモジュール使い比べ感想

#Ionic+AnglerJSでQRコード生成するモジュール使い比べ感想

いろいろ合って迷ったのでグーグルで検索で出てきたやつを使い比べ
基本的にTypeScriptで動作するもの。
ngx-kujaはQR読み込みでQR生成はこれあるよに入っていたので

|名称|git|
|--- |---| 
|angular2-qrcode|https://github.com/SuperiorJT/angular2-qrcode| 
|angularx-qrcode|https://github.com/cordobo/angularx-qrcode|
|ng-qrcode|https://github.com/mnahkies/ng-qrcode|
|ngx-kjua|https://github.com/werthdavid/ngx-kjua|

##開発環境

Ionicスタートで作成したプロジェクトで実行

```
Ionic start
```

反映方法は、モジュールへの追記とHTMLへのタグ追加のみで、GitHubのREADMEで分かりやすかったので、個人の感想などがメインです。


## 個別ごとに気になった点

###angular2-qrcode

**気になった点**
paddinggaが設定できるのが、意外と便利になる可能性が。。。？

### angularx-qrcode

**気になった点**
HTMLでプロパティ引数で文字はシングルコーテーション('')囲いが必要なところ？

```
<qrcode [qrdata]="'Your QR code data string'" [size]="256" [level]="'M'" [usesvg]="true"></qrcode>
```

### ng-qrcode
![NoName_2019-11-15_10-3-43_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/06013679-b13d-3767-1588-64fe7156bff5.png)
**気になった点**
QRなどへの色指定がなさそう？

### ngx-kjua
![NoName_2019-11-15_10-3-57_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/aa76db35-5dca-3fc7-0529-a75fdd22e2a0.png)


**気になった点**
いろいろできすぎるですね。。
HTMLでプロパティ引数で文字はシングルコーテーション('')囲いが必要なところ？

```
<ngx-kjua [text]="'Your QR code data string'"></ngx-kjua>
```

## 書き出しに違いがあるのが大きな差

|名称|PNG|Canvas|SVG|Image on Code|Image as Code|
|---|---|---|---|---|---|
|angular2-qrcode|○|○||||
|angularx-qrcode|○||○|||
|ng-qrcode||○||||
|ngx-kjua|○|○|○|○|○|

## 結果

書き出しの画像が何を使いたいかで、棲み分けが良さそう。
QRにIMG埋め込んで華やかさ？出したいかもだから、kuja使ってみようと検討
C++ でOpenMPを使うときの注意点(超初心者)

## 概要
c++ で開発をしているときに、簡単にマルチプロセスをできる方法はないかと検索したときに、**OpenMP**が出てきたので色々試した結果、少しハマった部分があったので共有。

**注意**: 筆者はc++初心者なので、低レベルなハマりです。

## 簡単なコード
ググったらopenmpのc++サンプルコードは結構転がってます。例えば、

```main.cpp 

#include <stdio.h>
#include <omp.h> 

int main() {
    printf("使用可能な最大スレッド数：%d\n", omp_get_max_threads());

#pragma omp parallel for
    for (int i = 0; i < 10; i++) {

        // （何かの処理）

        // 検証用の表示
        printf("thread = %d, i = %2d\n", omp_get_thread_num(), i);
    }

    return 0;
}

```
と書いて、linuxであれば

```bash

g++ main.cpp -fopenmp
```

MacOSであれば

```bash

g++ main.cpp -Xpreprocessor -fopenmp -lomp
```

とすれば、

```
使用可能な最大スレッド数：4
thread = 3, i =  8
thread = 2, i =  6
thread = 3, i =  9
thread = 1, i =  3
thread = 0, i =  0
thread = 2, i =  7
thread = 1, i =  4
thread = 0, i =  1
thread = 1, i =  5
thread = 0, i =  2
```

となって、それぞれのイテレーションで、確かに複数スレッドが並列して走る。
for文の前に一行書くだけで並列処理、すごい！！となるわけです。

## ハマりポイント()
for 文回す時って、だいたいの場合それぞれのイテレーションでなにか処理をして、結果を配列に格納する時が多いのではないでしょうか？
例として、

```main.cpp
#include <stdio.h>
#include <omp.h> 
#include <vector>
#include <iostream>
#include <stdio.h>

using namespace std;

//単純に２乗を計算して返す関数
double test_square(double x){
    return x*x;
}

int main() {
    printf("使用可能な最大スレッド数：%d\n", omp_get_max_threads());

    double test;  

    //最後に結果を格納する配列
    vector<double> box;
    box.resize(10);

    //各for文で呼ばれる配列
    vector<double> chocolates;
    for(int i=0; i<10; i++){
        chocolates.push_back(i);
    }

    //for文だよ〜
    //chocolateの各要素を２乗してboxの配列に格納するよ〜
    #pragma omp parallel for
    for (int i = 0; i < 10; i++) {

        test = test_square(chocolates[i]);
        box[i] = test;
        printf("thread = %d, i = %2d\n", omp_get_thread_num(), i);
    }

    //最後に結果をプリントするよ〜
    for(int i=0; i<10; i++){
        cout << box[i] << endl;
    }
    return 0;
}
```

のような時です。
まあ、これはきちんと動いてくれました。
このとき、各イテレーションでtestという変数に、test_square()で２乗された値を入れています。
これが各プロセスで並列化して行われるわけですが、アクセス競合みたいなのが気になるわけです。。
今回は上手く動きましたが、自分の場合は似たようなロジックのコードを書いていて、アクセス競合が起き、結果がうまく受け取れない自体が発生していました。

そこで、以下のコードに書き換えることで上手くいきました。

```main.cpp
#pragma omp parallel for private(test)
```

なんてことはないのですが、**private(test)** と書き、
各イテレーションでそれぞれ代入されるべきtestという変数を
private(各プロセスに関して独立している)と明記することで、競合をなくすことができました。

## まとめ
たぶんわかっている人には常識すぎることだったかもしれませんが、初心者にはつまづきやすいところだと思ったので、もし誰かの助けになれば幸いです。

慣れてくればc++楽しい！！
これからも勉強がんばりましょ


おわり
WinSCP > 大きなSFTPパケット (589325935 B)を受信しました。サポートしている最大パケットサイズは102400 Bです。 > 対処: .bashrcのechoをコメントアウト | 検討: ターミナル起動時のメッセージ

```txt:動作環境
Windows 8.1 Pro(64bit) 
WinSCP v5.15.4
```

### 接続エラー

![2019-11-15_09h52_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/35610f78-979c-5030-701f-4f2f48376538.png)

> 大きなSFTPパケット (589325935 B)を受信しました。サポートしている最大パケットサイズは102400 Bです。
> 
> このエラーは(.profileといった）スタートアップスクリプトによって表示されたメッセージによるものです。メッセージが""# fo""で始まっています。

### .basrhcによるメッセージ

```
# for v3.7.1
ln -snf WPSv3.7.1 WPS && ls -l WPS
ln -snf WRFv3.7.1 WRF && ls -l WRF
```

上記のようなエラーを表示するようにしている。
数値計算で様々なバージョンを切替えてしようする時用。

### 対処

上記のecho出力をコメントアウトするとWinSCPの接続が成功するようになった。


### 関連

- [WinSCP において、「SFTPプロトコルを初期化できません。」などと言われて接続できない問題を調べる修行](https://unau.hatenadiary.org/entry/20090204/1233735823)
    - by ゆーの(id:unau)さん

情報感謝です。


### ターミナル起動時のメッセージ

ターミナル起動時(例としてbash）を検討してみる。

- A. echoによるメッセージ
    - WinSCPでエラー
- B. catによるメッセージ
    - WinSCPでエラー
- C. subl (Sublime Text)によるメッセージ
    - WinSCPで正常

X転送が有効のとき、bashターミナル起動ごとにSublime Textが起動というのもどうかだが。

.bashrcの最後

```.basrhc
### WRF v3.7.1 and v4.1.1 (2019.10.17)
subl ~/doc_WRFuse_191115 
```
Bashのカーソル移動、削除ショートカット

自分用メモ

### カーソル移動
|キー操作|内容|
|---|---|
|Ctrl+f|1文字進む|
|Ctrl+b|1文字分戻る|
|Ctrl+a|行頭に移動|
|Ctrl+e|行末に移動|
|Esc+f|スペース区切りで1単語分進む|
|Esc+b|スペース区切りで1単語分戻る|

### 文字削除
|キー操作|内容|
|---|---|
|Ctrl+h|前1文字削除|
|Ctrl+d|カーソル位置の1文字削除|
|Ctrl+w|カーソル位置からスペース区切りで1単語分削除|
|Ctrl+k|カーソル位置から行末までを削除|
|Ctrl+u|カーソル位置から行頭までを削除|
lessコマンドの操作

## lessコマンド
ファイルの内容を1画面ごとに表示してスクロールして見ることができる

## 操作
|キー|内容|
|---|---|
|スペース|1画面下にスクロール|
|b|1画面上にスクロール|
|j|1行下にスクロール|
|k|1行上にスクロール|
|q|コマンドの終了|
|/<文字列>|下方向にファイル内検索|
|?<文字列>|上方向にファイル内検索|
|n|次の検索結果へ|
|N|前の検索結果へ|
CloudFormation Resource Importで、実体と違うテンプレートを使うとどうなるのか

# 概要
CloudFormationに待望のリソースインポート機能がリリース[^aws]:tada:
使い方は、例によってクラメソさんが記事化しているので[^class]、気になったところを追加で確認する。

# 気になっていること
対象のリソースが存在していなければならない、などいくつかの必須条件はドキュメントにも記載済み[^req]。
では、インポートするリソースと、違うパラメータ設定のテンプレートを使うとどうなるのか。置換されたり、上書きされたりする？

# 実験
対象はS3 Bucket：`hogehoge-fugafuga-poyopoyo`
全てデフォルト設定。

## テストその1：ユニークキーとなるBucketNameが違うテンプレート
取り込むバケット名とBucketNameが異なる。

```yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: 'Retain'
    Properties:
      BucketName: 'piyopiyo-foo-bar'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/54f2623d-b0e8-941f-6ea6-69d0b05afe8b.png)

失敗。

## テストその2：デフォルト値と異なるテンプレート
バージョニングはデフォルトで無効。

```yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: 'Retain'
    Properties:
      BucketName: 'hogehoge-fugafuga-poyopoyo'
      VersioningConfiguration: 
        Status: 'Enabled'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/7b6c6af5-821a-0694-8571-ae9c4a2b6733.png)

インポートは成功。**バージョニングは無効化のまま**。
どうやら、反映はされないよう。
その後、テンプレート側をDisabled / Enabledと変更しつつ反映したところちゃんと更新された。

# まとめ
リソースインポートによって既存リソースが取り込めるようになってとても便利になった。
取り込みと設定更新は同時に行われないようなので、
1. 必須項目だけを記述したテンプレートで取り込み
2. 任意項目を追加

の方が安全そう。



[^aws]: [New – Import Existing Resources into a CloudFormation Stack | AWS News Blog](https://aws.amazon.com/jp/blogs/aws/new-import-existing-resources-into-a-cloudformation-stack/)

[^class]: [【アップデート】ついに来た！CloudFormationで手動で作成したリソースをStackにインポート可能になりました ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/cloudformation-import-existing-resources/)

[^req]: [Bringing Existing Resources Into CloudFormation Management - AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html)
ログイン機能を勉強していく

#目的
ログイン機能とはなんぞ？どう作成したらいいものかを調べていく
※私は、ログイン素人なので参考程度にとどめてくださいませ(=_=)

#手順
ざっくりでいいので下記のログインイメージを調べてメモする。
①ログイン画面からのログイン処理
②ログインAPIからのログイン処理
（外部サイトからの認証に自社ユーザーを使用させるとき）

#ログインイメージ①（ログイン画面-セッション編）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/feb88e06-a365-b0f9-30d2-4dda7f0c6cac.png)

▼メモ
・認証…通信の相手が誰（何）であるかを確認すること
・認可…とある特定の条件に対して、リソースアクセスの権限を与えること
・セッションクッキー…クライアントがブラウザを終了した場合にCookieが削除される.
・持続（永続）クッキー…指定された日時または期間が過ぎるとCookieが無効になる.
・デメリットは、サーバごとにセッションファイルが作成されているため、
　サーバ複数台構成（負荷分散）では使用できないこと。

#参考
>https://blog.apar.jp/php/12373/
>https://dev.classmethod.jp/security/authentication-and-authorization/

#ログインイメージ②（ログイン画面-DB編）
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/909cd257-45c3-78c6-cfd2-44f5601f6af5.jpeg)

これが、一般的でしょうね。

▼メモ
・サーバ複数台構成でも、すべてのさーばが同一のDBを参照することで、
　アクセスごとにサーバが変わってもログイン状態が維持できる。
・DBデータをNoSQLとかにいれておくと、高速になる気がする。

#ログインイメージ③（ログインAPI）

![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/16197e16-7ed9-7dc8-f7ba-2fc150323e0a.jpeg)

###こちらを参考にさせていただきました。
>https://www.bokukoko.info/entry/2015/12/20/%E8%AA%8D%E8%A8%BC%E3%82%92%E5%90%AB%E3%82%80_API_%E9%96%8B%E7%99%BA%E3%81%A7%E6%A4%9C%E8%A8%8E%E3%81%99%E3%81%B9%E3%81%8D%E3%81%93%E3%81%A8

★もっと改良を加えないとダメなんですねぇ。
・外部サイトでのID/PASSの流出を防ぐために、自社画面のログインを使って、
　トークンや認証コードを戻すなど。
・トークンの流出に備えて、リフレッシュトークンを用意するなど。
　⇒盗聴されトークンが漏れたとしても、リフレッシュトークンは
　　トークン使用時には送信されていないので情報は洩れない。
　　うんうん、よく考えられているなぁ。

▼メモ
・外部に提供するなら、攻撃があった際の負荷を軽減する必要あり。
　スロットリングでアクセスを絞る、
　また、サイト側にrecaptchaを導入していたら、
　ログインAPIへのアクセスは抑えられるでしょうねぇ。

#その他メモ
・パスワードをハッシュ化していても平文に戻されることもあるのですね。
　そのために、ユーザーごとに任意の文字列を付与してからハッシュ化する
　「SALT」を施すなど、いろいろあるのですねぇ。
>https://ferret-plus.com/9602

#まとめ
基本的な動きは把握できたかなぁと思います。
あとは、セキュリティとしてどういうものを抑えたらいいか理解したら、
ログインは把握できたとなるのでしょうかねぇ、どうなんやろう(^^;
【Mac】Homebrew を使って PostgreSQL を動かす

何度も同じことを調べてしまうので、まとめてみました📝


## インストール可能なバージョンをリストアップ
✔︎がついているものはインストール済みです。

```shell
$ brew search postgresql
==> Formulae
postgresql@10 ✔️   postgresql@13     postgresql@9.4    postgrest
postgresql@11     postgresql@14     postgresql@9.5
postgresql@12     postgresql@15     qt-postgresql
```

## インストールする
`@11`など、バージョン指定してインストールすることが推奨されています。

```
$ brew install postgresql@11
```

## アンインストールする
```
$ brew uninstall postgresql@11
```

## バージョン確認

```
$ psql --version
psql (PostgreSQL) 11.5
```

## シンボリックリンク
シンボリックリンクが作成されない場合、うまくバージョンが切り替わらない場合があります。使うバージョンを link /unlink で切り替えると良さそうです。

#### 使い方

```
$ brew unlink postgresql@10
```
```
$ brew link postgresql@11
```

## PostgreSQL を起動
```shell
$ brew services start postgresql@11
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
```

## 起動状況の確認
複数のバージョンが起動していると、通常緑色の`started`が黄色になります。１つだけを起動させて、その他は停止させましょう。

```
$ brew services list
Name           Status  User  Plist
mysql          stopped       
postgresql@11  started yuppy /Users/yuppy/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
postgresql@10  stopped       
```

## PostgreSQL を停止
```shell
$ brew services stop postgresql@11
Stopping `postgresql`... (might take a while)
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)
```

## DB一覧を表示
使用しているデータベース一覧が表示されます。

```
$ psql -l
               Name                | Owner | Encoding | Collate | Ctype | Access privileges 
-----------------------------------+-------+----------+---------+-------+-------------------
 postgres                          | yuppy | UTF8     | C       | C     |  
 template0                         | yuppy | UTF8     | C       | C     | =c/yuppy         +
                                   |       |          |         |       | yuppy=CTc/yuppy
 template1                         | yuppy | UTF8     | C       | C     | =c/yuppy         +
                                   |       |          |         |       | yuppy=CTc/yuppy
(3 rows)
```

## DB操作
良く調べるのでついでにメモします。

#### データベースに入る
```
$ psql 入りたいデータベース名
```

#### テーブル一覧表示
`\` option キーと ¥ を同時に押します。

```
# \dt
```

#### データベースの切り替え
```
# \c 切り替えたいデータベース名
```

#### データベースの削除
```
# drop database 削除したいデータベース名
```

#### データベースから出る
```
# \q
```

## 追記

🔽 バージョンを変えた時に status に`error`が出て動かなくなったので、以下の記事も作成しました。

https://qiita.com/yuppymam/items/852fa2864534ce4aa590
【第5話】Flutterでwebゲーム作ろっかなって思った 【構想と現在の状態】

#現在の状態
<font color=red>【第X話】系の記事は、自分へ向けての作業日報のようなものになります。ゲームができていく過程がどんな感じなのか伝わればイイなと思って書いています。</font>
見た感じ戦えそうになってきた（テストデプロイ先には未適用
アイコンが全てｲｲﾈになっているのは、ベースの機能が揃ったらなおす予定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173892/f9b93a6f-2310-9c0f-c8fe-55e8f38179d0.png)

##最終目標を確認
最終的には、ゲームのロジック部分はサーバー側に持っていく予定。
描画のみがflutterで作られたクライアントに残る予定。
そのために画面の設定からキャラクターの設定値から全部jsonでファイルから読み込むようにしていっている。

#戦闘の仕組みについて
戦闘については戦闘クエリーをサーバーに投げて、結果オブジェクトを頂いた上でそれをもとにエフェクトを付けていくみたいな感じにする予定です。

たった今、一人で脳内会議を開き、戦闘は以下のように決定されることになりました。

###startフェイズ
状態異常や継続攻撃の成否を判定し、そのターンでのプレイヤーの開始状態を決定する。

###selectフェイズ
各プレイヤーが行動を選択する

###battleフェイズ
- サーバー：selectフェイズで取りまとめられたクエリーを処理する
- クライアント：処理された結果を受け取って、表示する

###endフェイズ
勝利条件の確認 ? 終了 : 継続;

##selectフェイズで作成するクエリーのリスト
List\<SelectedBattleAction\> をプレイヤー側とモンスター側で一つづつ作成される
モンスターも実体はPlayerとして処理する。

```
SelectedBattleAction
{
	Player:<id>,
	Action:<attack>,<skill>,<defend>,<item>,<swap>,<special>,<escape>,
	source:<name><null>,
	target:[
	    {
 		    partyId:<id>,
  		    targetType:<single><row><all><column>,
   		    targetId:[<null>,<id>,<random>]
	  	}
  	]
}
```

##戦闘の計算の流れ
###下準備
リスト２つを一個に取りまとめる。
SelectedBattleAction一つづつについて、行動速度を計算し、決定する。
行動速度から処理する順番を決定し、その順番に従って戦闘計算を行う。
###戦闘計算を行う順番
Playerの状態をチェックする。
ActionとSourceがそのPlayerにとって現在実行可能なのかをチェックする。
ActionとSrouceがTargetに対して現在実行可能なのかをチェックする。⇛副次的にターゲットとの距離がわかる
※攻撃対象が妥当でなくなった場合に、自動で切り替えるのか切り替えないのか、ゲームバランスになるので考慮が必要
※randomの場合、実行可能範囲に敵がいるかどうか（自分が後ろに下げられた場合に届かないことがある
Player Action Source Target を利用して戦闘の計算を行う。
計算の途中でダメージや状態異常になったとしても、それらは最後の結果反映時にまとめて反映される。
※明示的に効果の最初に状態が変化するようなものは除く
戦闘の結果を反映する。


##とりあえずは・・・
アタックが敵と味方で飛び交うようになるところまで進めようと思います。そこまでできれば多分あとはコピペで増やしていけるでしょう。
ガードについては防御がUPするとかになるのか、減算にするのか、悩ましいところ。とりあえず防御UPだけするようにして後で色々足せるように考えて作ります。

これを見て気になった人は以下で詳しく見ることができます。
テスト公開については、アタックが飛び交って、勝利か敗北ができるようになったらまた更新します。
ソースコード：https://github.com/ClozedJP/adventure
テスト公開：https://clozedjp.github.io/adventure

#FlutterタグつけたのでFlutterネタを
##Routeオブジェクトは一度使うとdisposeされる
なので、たとえ同じパスで同じページを表示するとしても、ルートオブジェクトはnewしなければならない。
MapにMaterialPageRoute(builder: (context) => Hoge())などを突っ込んで、再利用しようとするとクラッシュします。
そういうときはmapにHoge()を入れておいて、ルートに合わせてMaterialPageRoute(builder: (context) => Map[routeName])とかしましょう。

##RowとかColumnクラッシュしがち
何かと幅や高さが無限になりましたってプンスコ怒るRowくんとColumnちゃんですが、Containerに優しく包んであげると怒らなくなります。

##Container小さくなりがち
Align.start Algin.endみたいなことをやっても動かないのは、コンテナちゃんが小さいから。SizedBox.expand(child: Container(child: ,),)すると割と思った感じに配置できたりします。

##未解決：枠線のある、中塗りもされているボタンが作れない
OutlineButtonにcolorの項目があるが、何設定しても関係ない。枠線とテキストだけ塗られる。
FlatButton RaisedButtonは枠線が出ない。
Containerで枠線ごまかそうとしたけど、隙間ができてしまうためコレジャナイ感がすごい。
変則でstackで裏になんか重ねるみたいな事やればできると思うけど、そうじゃない、そうじゃないと思います。
【メモ】MacでSAC

MacOS (Mojave) で SAC([Seismic Analysis Code](http://ds.iris.edu/ds/nodes/dmc/software/downloads/sac/)) [Version: 101.6a] を使おうと思ったのだが、ソースコードからのコンパイルがうまくいかなかった。

フォーラムを見ると[libeditに問題がある](http://ds.iris.edu/message-center/thread/1193/)ようなのだが、これまた修正が面倒そうであった。

IRISにMac版のバイナリを申請して待っている間に調べていると、[George Helffrich](https://members.elsi.jp/~george/gh.html) 先生のページに [Bug fix されたバイナリが置いてある](https://members.elsi.jp/~george/sac-bugs.html)のを見つけた。インストールしたところ、秒で使えるようになった（コンパイルエラーの問題解決は何もしていないけどね）。

ちなみにG.Helffrich先生は["The Seismic Analysis Code" A Primer and User's Guide](https://www.cambridge.org/gb/academic/subjects/earth-and-environmental-science/solid-earth-geophysics/seismic-analysis-code-primer-and-users-guide#contentsTabAnchor)っていう本も書かれているので、間違いなさそう。
Reactライブラリー開発環境で、"Invalid Hook Call Warning"に対処する

# "Invalid Hook Call Warning"の原因と対応方法

Reactライブラリーを開発するため環境構築で"Invalid Hook Call Warning"に対処したので、その原因と対応方法について書きます。

## "Invalid Hook Call Warning"の原因とは？

### 原因は３種類ある

ReactのHooksの書き方や、Reactプロジェクトの構成が原因で発生するエラーです。

[Reactの公式ページで詳しく解説](https://reactjs.org/warnings/invalid-hook-call-warning.html)されていて具体的には３つの原因があります。

1. 関数型コンポーネントの外でhooksを使おうとしている
2. コンポーネントのトップレベル以外（if文など）でhooksを使おうとしている
3. ２つ以上のReactが存在する（後ほど詳しく）

Reactや、その周辺ライブラリーを使いながらアプリ開発をしていて"Invalid Hook Call Warning"に遭遇するケースはほぼ1や2のケースです。

### ２つ以上のReactが存在する、とは？

複数のReactパッケージを参照しながら１つのReactアプリを動かそうとしてしまっている状態です。

Reactライブラリーを開発する際に私は以下のような構成を選びました。

#### Reactライブラリープロジェクト
* React（これがないと始まらない）
* Typescript（バグを減らしてきれいに書くため型が欲しい）
* rollup（アプリ開発はwebpack、ライブラリー開発はrollupらしい）

[こちらのサイト](https://www.pluralsight.com/guides/react-typescript-module-create)の通りに構築しました。

#### 開発コンポーネント確認用プロジェクト
こちらは create-react-app のTypescript使用バージョンで簡単に作りました。

この構成でライブラリーの中でhooksを使い、開発コンポーネント確認用プロジェクトで`npm start`して動きを確認しようとすると"Invalid Hook Call Warning"が発生します。

これは開発コンポーネント確認用プロジェクトは、そのプロジェクト内のnode_modulsにあるreactを参照しますし、
Reactライブラリーとして開発中のコンポーネントは、Reactライブラリープロジェクトにあるnode_modulsのreactを参照してしまう訳です。

こうして、「２つ以上のReactが存在する」という条件が整ってエラーになります。

## npm link による対応方法

私はnpmを使っているので以下の方法で対応しました。

開発コンポーネント確認用プロジェクトで以下のコマンドを実行

```
cd node_modules/react && npm link
cd ../../
cd node_modules/react-dom && npm link
cd ../../
```

Reactライブラリープロジェクトで以下のコマンドを実行

```
npm link react && npm link react-dom
npm link
```

再び開発コンポーネント確認用プロジェクトで以下のコマンドを実行

```
npm link [module-name]
```

困っている人たちがたくさんいるようで、[こちらのissue](https://github.com/facebook/react/issues/13991)を参考にしました。
AWS無料枠内だと思ってたら料金発生してた話

EC2のt2.microは月750時間までは無料とういことで早速使ってみたんですが、**いきなり料金発生してる！なんで？**ってなったのでメモ

参考：https://hosochin.com/2020/06/21/post-449/

[▼AWS ドキュメント » Amazon EC2 » Linux インスタンス用ユーザーガイド » ネットワークとセキュリティ » Elastic IP アドレス](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384069/e67f617f-e792-61b7-7d58-03199695ea42.png)

なるほど、

- Elastic IP アドレスが実行中のインスタンスに関連付けられていない場合
- Elastic IP アドレスが停止しているインスタンスやアタッチされていないネットワークインターフェイスに関連付けられている場合

にも料金が発生するようです
今回はElastic IPに関連付けられているインスタンスを停止させていたせいでした
使ってないときは停止しといた方がいいかなーってな感じで停止させていたのですが、
24時間起動していても1インスタンス月750時間は超えないので、常時起動させとくのがいいですね
各種クラウド PaaS (Platform as a Service) 実行環境 (プログラミング言語とバージョン) まとめ (2019年11月15日現在)

## 概要

- AWS Elastic Beanstalk, Azure App Service, Google App Engine について実行環境 (プログラミング言語とバージョン) の情報をまとめる

## AWS Elastic Beanstalk (Amazon Web Services: AWS)

- [AWS Elastic Beanstalk Supported Platforms \- AWS Elastic Beanstalk](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html)
- Packer 1.0.3
- Docker
- Go 1.13
- Java 8, 7
- .NET Core 3.0.0, 2.2.7
- Node.js 10, 8, 6, 5, 4
- PHP 7.2.19
- Python 3.6.8
- Ruby 2.6, 2.5, 2.4

## Azure App Service (Microsoft Azure)

- [App Service on Linux の概要 \- Azure \| Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-intro)
- Node.js 4, 6, 8, 9, 10
- Java 8
- PHP 5.6, 7.0, 7.2, 7.3
- Python 2.7, 3.6, 3.7
- .NET Core 1.0, 1.1, 2.0, 2.1, 2.2
- Ruby 2.3, 2.4, 2.5, 2.6

## Google App Engine (Google Cloud Platform: GCP)

- [App Engine Standard Environment Runtimes  \|  App Engine Documentation  \|  Google Cloud](https://cloud.google.com/appengine/docs/standard/runtimes)

- First generation
  - Python 2.7
  - Java 8
  - PHP 5.5
  - Go 1.11

- Second generation
  - Python 3.7, 3.8
  - Java 11
  - Node.js 10, 12
  - PHP 7.2, 7.3
  - Ruby 2.5 (beta)
  - Go 1.12, 1.13

- [App Engine Flexible Environment  \|  Google App Engine flexible environment docs  \|  Google Cloud](https://cloud.google.com/appengine/docs/flexible/)
  - Python 2.7, 3.6
  - Java 8
  - Node.js
  - Go 1.9, 1.10, 1.11
  - Ruby
  - PHP 5.6, 7.0, 7.1, 7.2
  - .NET Core
【fishシェルのテンプレ】$PATHにパスを追加する(「Googleの中の人」ver)

# テンプレ

解説はインラインのコメントを参照してください。

```sh
# The begin/end block limits the scope of all variables except $PATH
# begin/endは(-xでexportしている)$PATH以外のすべての変数スコープを限定するよ
begin

  # 例として/opt/binを追加します
  set new_path "/opt/bin"

  # -gx for global (not limited to this begin/end block) and exportable (part of
  # the environment for child processes)
  # -gxはグローバル化(begin/endブロック以外の場所からも使えるようにする)とエクスポート(個プロセスでも使える環境変数にする)の為に使っているよ
  if not contains "$new_path" $PATH
    set -gx PATH "$new_path" $PATH
  end

end

```

# 経緯

最近、google-cloud-sdkを対話スクリプトでインストールした際、次のような対話項目がありました。

```sh
Enter a path to an rc file to update, or leave blank to use 
[/home/dev-user/.config/fish/config.fish]:

```

この手のパス追加はB系シェルを前提としたものが多いので、fishシェルを使っている身としては嬉しい限りです。上記config.fishに追加されていた設定スクリプトを開いたところ、私のような輩を想定していたのか各行に初心者向けのコメントがついていたので、感動して記事にしました。（コメントの英語部分はオリジナルそのままです。）


ありがとうございます、Googleの中の人
Unityで物理演算を使いたくなかった話　～横スクロールアクションゲームの開発～

# 物理演算を使いたくない理由
Unityの物理演算（Rigidbody周り）は大変便利な機能ですが、時に制御しきれないときもあります。
意図せず、Collisionを突き抜けてしまったりしますよね。
なにより、**Unityの便利機能に甘えっぱなしな感じがちょっと嫌なので、**今回はRigidbody、Rigidbody2Dを使わず、横スクロールアクションゲームを開発した時のことを書こうと思います。（Collisionは使います。）
![qiita1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414549/31ad8848-ee4e-1fe2-15c4-b912c9e9dc16.png)
不思議の国のアリスが、ハートの女王などが仕掛ける罠をよけるゲームです。

# Raycastを使う
本来、Rigidbodyを設定しないと、Collision周りのメソッド(OnCollisionEnterメソッドとか)が反応しないため、「何かに当たったときに、ダメージを負う」的な処理ができません。
なので、**結局Unityの機能に甘える**形にはなりますが、Rayを使用します。Rayを投げ、当たったCollisionの座標との距離を測ったりして、衝突判定の処理を実装します。
![qiita2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414549/fa5d54f4-2cf8-982f-75e3-329cfc902d11.png)
これは、```Debug.DrawRay()```メソッドでキャラクターやトラップからRayを飛ばす様子をSceneウィンドウから確認したものです。白い線が当たり判定によるアリスの動きの処理をするためのRayで、鎌から伸びている赤い線が、アリスに当たった瞬間アリスにダメージを与える処理をするためのRayです。

# 床判定、壁判定
今回作るゲームは、スマートフォン向けの**ずっと横に走り続けながら、敵をかわしてスコアを伸ばす**ゲームなので、床の判定と壁の判定が必要になりました。
なので、まずはキャラクターから横向きと、下向きにRayを飛ばします。（左右に動く場合は、左右どちらにもRayを飛ばす必要がありますが、今回はずっと右向きに走るゲームなので、右向き、Vector3(1,0,0)の方向と下向き、Vector3(0,-1,0)の方向のみにRayを飛ばします。）

```Alice.cs
    private bool IsCollision(Vector2 direction,float distance,float adjast = 0)
    {
        var position = transform.position;
        // Rayを飛ばす初期位置を調整する
        position.y += adjast;

        var raycastHit2D = Physics2D.RaycastAll(position, direction, distance);
        Debug.DrawRay(position, direction);

        // 何も検知できなかった場合、処理を中断し、falseを返す
        if (raycastHit2D.Length == 0)
            return false;

        foreach (var raycastHit in raycastHit2D)
        {
            if (raycastHit.collider
                && !raycastHit.collider.gameObject.Equals(gameObject))
                return true;
        }
        return false;
    }
```

※Rayを飛ばすオブジェクト自体にCollisionを付けている場合、Rayを飛ばす位置は自身のオブジェクトも含んで当たったことを通知します。なので自身と子オブジェクトの当たり判定を外す必要があります。

# 移動の処理

Rigidbodyを使う場合は、velocityなどを使えば簡単にオブジェクトを動かせます。
しかし、Rigidbodyを設定していないため、Tween系のライブラリを使うか、**transform.positionを愚直に操作する**しかありません。

本来であればTweenなどを使うべきかもしれませんが、面倒くさかったため、transform.positionの値を0.001fずつ動かすというヤバみの深い実装になりました。
（UIとかはTween使うと綺麗に動くので、Tween好きです。）

# 結論
カジュアルゲーム作るぐらいなら、**普通にRigidBody使ったほうが良い**と思いました。
ちょっと調べると、Rayも普通に処理として重いそうです。（なので、あらかじめ飛ばす距離などはできるだけ短く指定してあげるとましになるとか、ならないとか・・・）

あと、見た目が2.5Dの場合は、2D用のRayではなく、3D用のRayを使用したほうが開発しやすいのでは・・・と思いました。
imacoco ～I'm here～

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533171/4d0ad5db-3c07-99c2-8ab3-0b83b1d7953c.png)

# 今、自分はここにいる

「今、自分はここにいる」ということを自分で簡単に確認できるだけでなく、家族や友人、ホテルの従業員等、必要な人に 1 タップで知らせることができる、LINE を使ったサービスです。

今乗っている電車がどの駅を出て、次にどの駅に向かっている知りたい時があります。訪日観光客の方が慣れない電車に乗っているのかもしれません。騒音のため車内アナウンスが聞き取れなかったかもしれません。またはつかれていてふと意識が途切れたのかもしれません。

※利用イメージ動画
[![imacoco 第3回東京公共交通オープンデータチャレンジ_音声ガイド付き](http://img.youtube.com/vi/7jifdIFCu8k/0.jpg)](http://www.youtube.com/watch?v=7jifdIFCu8k)

## 他のサービスと何が違うの？
現在の一状況を知らせる、確認するサービスは多くありますが、現在乗っている電車がどの駅を出て、どの駅に向かっているかを 1 タップで確認できるところがサービスの売りであり、東京公共交通オープンデータを活かしいるとこです。地図情報だけでは把握しずらい内容を、タイピングする手間もなく確認、共有できることは、今後より複雑に高度になっていく公共交通において必須の機能であると考えています。

# 使い方

1\. まずは LINE で imacoco と友達になってください。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533171/cfcb0d05-e0cb-f704-41e3-05d09437900b.png"/>

2\. 自分で使いたい場合は、リッチメニューより 「位置情報を知らせる」 タップします。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533171/c5f2da5f-5787-9300-07d9-9f3bec540e0f.png"/>

3\. 自動で位置情報を取得する画面が起動します。位置情報の許可を求めてきた場合は、優しく許可してください。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533171/9bb0c544-eaf2-8caf-62ab-5d12b53e2341.png"/>

4\. 電車に乗っている場合現在の情報が取れる。
<img width="317" alt="Picture1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533171/c4fa8d89-6bdf-bca1-57b6-c14176ef6e54.png">

5\. グループで使いたい場合は、グループに招待してください。

# 今後の予定

現在は山の手線しか対応していないため、今後はより多くの路線の対応やバスの対応を目指します。まだまだ精度の問題などがありますが、今後も改善する予定ですので、是非使ってみてください！
【Rails】 form_with, form_for でプルダウン（セレクトボックス）を実装してみる

# 概要

今回はrailsアプリケーションにおいてフォームを送信する際に、以下のような簡単なプルダウンを実装できるようにします。（何か質問等あったら気軽にコメントください！）

本記事は`form_with`を例としていますが、`form_for`内でも同様のコードで使用可能です。

![スクリーンショット 2019-11-15 3.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409257/31f1560e-fc23-9124-2a44-b54738630943.png)

![スクリーンショット 2019-11-15 3.35.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409257/3b334d3d-66f1-9389-d217-f98be69e351e.png)

## 例
上記の例は以下のようなコード1行で実装できます。（"faculty"カラムに、選択肢内の学部のいずれかを選んで保存させるイメージです。また「hoge」は「ホニャララ」という意味で使っているので、こちらも適宜自分のプロダクトに合わせて変更してください。）

```erb:view/hoges/new.html.erb
  <%= form_with model: @hoge do |f| %>

     # 以下の一行がプルダウンを実装するためのコード（追記部分）
     <%= f.select :faculty, [["理工学部", "理工学部"], ["経済学部", "経済学部"], ["法学部", "法学部"], ["医学部", "医学部"]], include_blank: "選択して下さい" %>

     <%= f.submit '送信'%>
  <% end %>
```

## 一般形
コードを一般形に直すと以下のようになります。

```erb:view/hoges/new.html.erb
  <%= form_with model: @hoge do |f| %>

     # 以下の一行がプルダウンを実装するためのコード（追記部分）
     <%= f.select :保存先のカラム名, [["選択肢１", "実際にDBに保存させる内容"], ["選択肢２", "実際にDBに保存させる内容"]], include_blank: "選択して下さい" %>

     <%= f.submit '送信'%>
  <% end %>
```
「保存先のカラム名」には、プルダウンで選択した値を送信する際に保存したいカラムの名前を記述します。


もし送信ボタンを押しても値が保存されないという場合は、コントローラーの*Strong Parameters*の記述について確認してみてください。
（`params.require(:hoge).permit(:hoge, :hogehoge)` のところ）


「選択肢」と「実際にDBに保存させる内容」は基本一緒にして大丈夫です。
（「実際にDBに保存させる内容」を変えれば、"経済学部"を選択して送信した際に保存される内容を例えばtrueや2などの整数にする、といったことができます。）
## 応用編
以下のように、プルダウンの選択肢をDB内のあるテーブルの特定のカラムの内容にすることもできます。

```erb:view/hoges/new.html.erb
  <%= form_with model: @hoge do |f| %>

     # 以下の一行がプルダウンを実装するためのコード（追記部分）
     <%= f.collection_select :保存先のカラム名, テーブル（モデル）名.all, :実際にDBに保存させるカラム名, :選択肢に用いるカラム名, include_blank: "選択して下さい" %>

     <%= f.submit '送信'%>
  <% end %>
```
## 参考記事

[【開発メモ】Ruby on Railsのform_forでドロップダウンリストの選択ボックスを設置する方法](https://freesworder.net/rails-form_for-select/)

[[Rails 4.x] FormのSelect プルダウンメニューの項目をDBから引っ張ってくる方法](https://qiita.com/colorrabbit/items/b58888506e41d1370fd1)
Ruby + alpine でほんの少しだけバッチバージョンを変えた Dockerfile を自作してみようとした例 ( #ruby #docker )

# Rubyでは公式イメージのDockerfileが公開されている

https://github.com/docker-library/ruby/blob/bf0e16e7511c97fdf351fdfc2e7e17478a4eaf16/2.6/alpine3.10/Dockerfile

![image](https://user-images.githubusercontent.com/13635059/68855189-12dcd900-0721-11ea-84d7-d178567aa058.png)



# Ruby 

該当のruby version のSHA をコピっておく

https://www.ruby-lang.org/en/news/2019/04/17/ruby-2-6-3-released/

![image](https://user-images.githubusercontent.com/13635059/68855323-546d8400-0721-11ea-8fb9-9ae222415300.png)


# Dockerfile

VERSION と SHA だけ書き換えた Dockerfile を作る

```diff
ENV RUBY_MAJOR 2.6
- ENV RUBY_VERSION 2.6.4
- ENV RUBY_DOWNLOAD_SHA256 df593cd4c017de19adf5d0154b8391bb057cef1b72ecdd4a8ee30d3235c65f09
+ ENV RUBY_VERSION 2.6.3
+ ENV RUBY_DOWNLOAD_SHA256 11a83f85c03d3f0fc9b8a9b6cad1b2674f26c5aaa43ba858d4b0fcc2b54171e1
```

# build

`docker build . -t yumainaura/ruby2.6.4-alipine3.10`

# うまく行けば動くはず。

うまくいけば。

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
mastodonのアバターを更新する方法

インスタンス運営側なら以下のコマンドでいけるんだけど、今回は、ユーザーの場合。

```sh
mastodon:media:redownload_avatars
```

検索ボックスで、`https://mstdn.syui.cf/@syui`みたいに検索すると、更新される。

ユーザーを検索すると、avatarのurlが変更されてるかチェック、変更されてたらインスタンスのメディアサーバーにダウンロード、avatarを更新する処理が`sidekiq`で走るぽい？