OmniAICreator/Qiita-1.07M huggingface dataset:
多段 SSH で秘密鍵を「ローカルに持つ」パターンと「踏み台に持つ」パターン

# はじめに

多段 SSH の設定方法はググればたくさんでてきますが，「踏み台に秘密鍵を持つ」パターンの情報が少なくて躓いたので，今後のためにメモしておきます。

Special Thanks: @chitoku

## ローカルに持つ場合

通常はこちらの方法が望ましいです。

```rb
[A] ----> [B] ----> [C]
 |
 "~/.ssh/id_rsa_for_B"
 "~/.ssh/id_rsa_for_C"
```

```
Host B
  Hostname B.example.com
  User user_b
  IdentityFile ~/.ssh/id_rsa_for_B

Host C
  Hostname C.example.com
  User user_c
  IdentityFile ~/.ssh/id_rsa_for_C
  ProxyJump B
```

参考: [linux - SSH from A through B to C, using private key on A - Server Fault](https://serverfault.com/questions/934642/ssh-from-a-through-b-to-c-using-private-key-on-a)

## 踏み台に持つ場合

秘密鍵の漏洩リスクがあるためあまり推奨されませんが，踏み台の秘密鍵を全ユーザで共有している場合などには有効です。

```rb
[A] ----> [B] ----> [C]
 |         |
 |         "~/.ssh/id_rsa_for_C"
 |
 "~/.ssh/id_rsa_for_B"
```

```
Host B
  Hostname B.example.com
  User user_b
  IdentityFile ~/.ssh/id_rsa_for_B

Host C
  Hostname C.example.com
  User user_c
  ProxyCommand ssh -o 'ForwardAgent yes' B 'ssh-add ~/.ssh/id_rsa_for_C && nc %h %p'
```

参考: [linux - SSH from A through B to C, using private key on B - Server Fault](https://serverfault.com/questions/337274/ssh-from-a-through-b-to-c-using-private-key-on-b)
AmazonLinux2のDockerコンテナにPython3を入れる

```bash
# docker run
docker run -it --rm amazonlinux:2 bash
```

コンテナ内で、

```bash
yum update -y

# install
amazon-linux-extras install python3.8 -y

# install devel
# `amazon-linux-extras install python3.8` の後じゃないと no package と言われる
yum install -y python38-devel # /usr/include/python3.8
pip3.8 install --upgrade pip # `pip`, `pip3` が3.8を向くようになる
pip install setuptools --upgrade

# run
python3.8

# venv
cd /tmp
python3.8 -m venv venv
source venv/bin/activate
```

おまけ（MySQL対応、3.8以外）

```bash
# 3.8じゃない時用
yum install -y python-devel # /usr/include/python2.7
yum install -y python3-devel # /usr/include/python3.7m

# MySQL操作で必要になる時用
yum install -y gcc
yum install -y mysql-devel mysql-libs # /lib64/mysql/libmysqlclient.so.18 が入る
```
Maxでエンベロープを使ってポーーをポーンやホワーァンに

#前の記事
[MaxでMIDI鍵を離した時の信号（ノートオフ信号）をカット](https://qiita.com/waokitsune/items/18c48f48bcd1bccd035e)

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#エンベロープって何ぞや
一定音量で『ポーー』と鳴ってるだけの音を、時間と音の大きさのグラフにするとこれ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f147ab73-b6ca-4bf7-6a8a-bbcbbb11ed5b.png)
青い線がエンベロープ。

『ポーン』って音はこれ。大雑把に言うと打楽器的な音。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8ca20e04-a2b2-9c37-9797-b496262d25dc.png)
『ホワーァン』って音はこれ。大雑把に言うと弦楽器的な音。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4b078d3d-7827-4ef1-4b88-b4f04216be09.png)

エンベロープによって **時間的な変化をつけることができる(*ﾟ▽ﾟ)ﾉ** です。

#エンベロープを設定できるパーツを追加
**function** ってやつ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8302db56-8896-7eb1-8440-7d912ffc9193.png)
functionエリア内でクリックするとポイントが追加されてエンベロープを描ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/53041271-8a7b-aee7-5c9f-b23c9848c299.png)

* 編集モード中はポイントの編集はできないどす。
* Shift + クリックでポイントを消せる。（Windowsの場合）
* Y軸の範囲0～1。
* X軸の範囲はfunctionのインスペクタの **ハイ・ドメインの表示値（X軸）** で設定可。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8fdccfe5-a23d-e87a-646b-63c3b96cf535.png)

#functionにはbangメッセージを送る
（bangメッセージ ≒ いつやるの？今でしょ！な信号）
ひとまずbuttonをかませて、MIDI鍵からのキーボード番号の信号をbangメッセージに変換。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c2920095-c6b9-9844-4e86-07c3e358e8f7.png)
もしかしたらbuttonオブジェクトじゃなくて **t** オブジェクトの方が、グラフィカルな描画をしない分、演算コストが低いのかも、と思った次第。（これについては残課題どす）

#functionの戻り値にはline~をかませて、*~で音源と掛け算する
**line~** と **\*~** は感覚的には分かるんだけど言葉でうまく説明できない……。(ﾉдヽ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/de4ecd82-a565-e7e8-9c1c-2c066f77790c.png)
参考サイトさん [https://numeralcreation.info/モノフォニック・シンセサイザーを作る/](https://numeralcreation.info/%E3%83%A2%E3%83%8E%E3%83%95%E3%82%A9%E3%83%8B%E3%83%83%E3%82%AF%E3%83%BB%E3%82%B7%E3%83%B3%E3%82%BB%E3%82%B5%E3%82%A4%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%9C%E3%82%8B/)

#最終的にはこんな感じ
音に表情をつけられるようになってくると、楽器を作ってるって感じがしていいです(\*´ω｀*)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5254067f-d79a-7c4a-c249-dc2bce424210.png)

#次の記事
[Maxで和音を奏でられる（ポリフォニック）シンセサイザーを](https://qiita.com/waokitsune/items/da173954f2ee047a0628)
Python3でMySQLdbを求められたときの問題と解決

## 問題点

`MySQLdb` を入れるための `pip install MySQL-Python` はPython3に対応できてない。

※↓を実行しようとするが、

```python
import ConfigParser
```

Python3から、↓（全て小文字）になっているため`ModuleNotFoundError: No module named 'ConfigParser'`でエラーになる。

```python
import configparser
```

## 解決

`pip install mysqlclient` で。

`python-devel` が入っていないと↑は失敗するので注意。。
※`/usr/include/pythonX.X` 内に `Python.h` がないとダメ。 

```
yum update -y
yum install -y python-devel # /usr/include/python2.7
yum install -y python3-devel # /usr/include/python3.7m
yum install -y python38-devel # /usr/include/python3.8
```

↓も実行しておくの推奨

```
yum install -y gcc mysql-devel mysql-libs # /lib64/mysql/libmysqlclient.so.18 が入る
```

**Lambda上で動かす場合、必ず参照項の`Lambda上でmysqlclientを動かす`を見ること**

## 参照

* [AmazonLinux2のDockerコンテナにPython3を入れる](https://qiita.com/k_hoso/items/bcd773bbfd260656e621)
* [Lambda上でmysqlclientを動かす](https://qiita.com/k_hoso/items/6bab9eb288cba01cdb18)
postgresの初期状態について

# 環境情報
- 環境：macOS  
- PostgreSQLのバージョン：12.4
- パッケージマネージャ：Homebrew

# 久しぶりにPostgreSQLに触った。
最初の認識としては、postgresユーザが作成され、
postgresという名前のDBが存在している物と考えていた。
（考えが古かった・・・）

HomebrewからインストールしたPostgreSQL12.4は
1. zshにログイン中のユーザが作成される。
2. postgresというユーザは存在しない。
3. postgresというデータベースは存在する。


なので、ログインする際には
`psql postgres`
でログインできます。

ちなみに、権限（role）としてもrolsuperを持っています。
[ロールについてのPostgreSQLの公式（日本語）](https://www.postgresql.jp/document/12/html/role-attributes.html)

## その他、macの困った点。
Windowsだと`¥`だけで`¥dt`とかできますが、
macの場合、`Option + ¥`で初めて`\dt`と認識されます。
DHCP サーバーを建てよう

当方素人ですまさかり大歓迎ですよろしくおねがいします。
当環境で期待通りの動きをしたので記録として残します。

# 環境

- Ubuntu 20.04 on VMware ESXi
- isc-dhcp-server v.4.3.5-3ubuntu7.1
- LAN
    - `10.0.0.0/24` (CIDR に突っ込みは NG)
    - デフォルトゲートウェイ `10.0.0.1`

# インストール

```sh
$ sudo apt install isc-dhcp-server
```

# 設定

IPv4 用設定ファイル: `/etc/dhcp/dhcpd.conf`
IPv6 用設定ファイル: `/etc/dhcp/dhcpd6.conf`

## IPv4

```sh:/etc/dhcp/dhcpd.conf
option domain-name "xxxxxxx.local"; # 接続固有 DNS サフィックス
option domain-name-servers [DNS v4アドレス], 1.1.1.1; # 配布する DNS サーバーのアドレス (カンマ区切り)

authoritative; # コメント解除

subnet 10.0.0.0 netmask 255.255.255.0 { # ネットワークアドレスとサブネットマスク
  option routers 10.0.0.1; # デフォルトゲートウェイ
  option subnet-mask 255.255.255.0; # サブネットマスク
  range dynamic-bootp 10.0.0.6 10.0.0.97; # DHCP リース帯 ex) .6 ～ .97を貸し出す
}
```

## IPv6

```sh:/etc/dhcp/dhcpd6.conf
option domain-name "xxxxxxx.local"; # 接続固有 DNS サフィックス
option dhcp6.name-servers [DNS v6アドレス], 2606:4700:4700::1111; # 配布する DNS サーバーのアドレス (カンマ区切り)
```

# 設定反映

```sh
$ sudo systemctl restart isc-dhcp-server
$ sudo systemctl restart isc-dhcp-server6
```

あとは家庭用ルーターなどが喋る DHCP を止めれば OK です。
vimを終了させる方法

初めてvim/viを学んだ際に抜け方が分からずに混乱したため、当時の自分に向けてメモを残します。
同じ状況の方の参考になれば幸いです。


###①エスケープキー（esc）を押す

###②状況に合わせて下記を入力


#####1.変更した内容を保存して抜ける

```
:wq
```

#####2.変更した内容を保存しないで抜ける

```
:q!
```

#####3.内容を何も変更してない時にそのまま抜ける

```
:q
```


---------------------------------------
上記②まで行えば正しくvimから抜け出せています。
Eclipse 画面レイアウト変更方法　（Java編）

画面レイアウト変更方法

参考動画

【Eclipse入門】初心者はまずココをイジれ！「Java編」
　https://www.youtube.com/watch?v=5p_3OudszfA

<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/5p_3OudszfA?start=47" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Slackに通知を飛ばすスクリプト

要約: SlackのIncoming-Webhookを用いて通知を投稿するコマンドをシェルスクリプトで書いて、brewでインストールできるようにしました。（N番煎じ）

# はじめに

~~全てのログや通知をSlackに集約したい。~~皆さんはSlackのIncomming-Webhook、活用していますか？URLに対してJSONパラメータを含んだHTTPリクエストを投げてやると、代わりに投稿してくれるすごいやつです。

しかし、OSインストールしたてのサーバにから通知を送信したいとか、一度URL設定したはずなのにどこにスクリプトを用意したか忘れてしまったということが多くて、毎回Incoming-Webhookの設定を追加しまくってしまいます。

# INSTALL

Mac(OS X), HomeBrewを想定しています。

1. Slackでアプリの追加よりIncoming-Webhookを追加し、URLを取得([方法](https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8))
2. slack-notifyコマンドをインストール
3. 環境変数SLACK_WEBHOOKを設定

```
$ brew tap ymmtr6/slack-notify && brew install slack-notify
$ echo "export SLACK_WEBHOOK=https://hooks.slack.com/services/[hogehoge]" >> ~/.bashrc
```

`SLACK_WEBHOOK`は取得したURLを設定してください。
zshの人は、`~/.bashrc`を`~/.zshrc`に読み替えてください。

# RUN

パイプでつなげる使い方と、引数を与える使い方の二つがあります。

```
$ echo "test" | slack-notify
$ slack-notify "これはテストです。"
```

例えば、コマンド出力をSlackに押し付けておく。

```
$ ls -lah | slack-notify
```

コマンド実行が終わったら、Slackに通知する。

```
$ python train.py && slack-notify "学習終了"
```

みたいな使い方ができます。


## slack-notifyの実装

シェルでガリガリ書いています。

```sh:slack-notify
#!/bin/bash
SLACK_NOTIFY_VERSION="0.0.3"
# env check
if [ -z "$SLACK_WEBHOOK" ]; then
  echo "環境変数SLACK_WEBHOOKを設定してください"
  exit
fi
# stdin check
if [ -p /dev/stdin ]; then
  echo -n -e $(cat -)
  message="\`\`\`$(cat -)\`\`\`"
else
  # args check
  message=""
  for x in "$@"
  do
    message="${message}${x}\n"
  done
    # default
  if [ -z "${message}" ]; then
    message="$(hostname):${PWD##*/} ${USER}\$ 
    slack-notify\n"
  fi
  echo -n -e "${message}"
fi

# JSON DATA
data=`cat << EOF
{
  "text": "${message}",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "${message}"
      }
    }
  ]
}
EOF`

curl -H "Content-type: application/json" -s -S -X POST -d "${data}" "${SLACK_WEBHOOK}" > /dev/null
```

## HomeBrewでインストールできるようにするには

参考文献参照。GitHubに *homebrew-hogehoge* という名前のレポジトリを作って、Rubyのファイルを作ってpushする。別ページでtarファイルを公開する必要があるが、GitHubのReleaseでも大丈夫。

# 参考文献
* [Slack での Incoming Webhook の利用](https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8)
* [Hello Slack. Incoming Webhook スニペット集](https://qiita.com/miyanaga/items/3a0c3963cc7497c62cff)
* [Homebrewの自作コマンドを正しく作る with ShellScript](https://qiita.com/hayashier/items/dd699857253b1f433655)
JDK 11 ドキュメント　Java 初学者向け

JDK11 の公式ドキュメントです😊　(All English:flag_us:)

　公式URL　➡　https://docs.oracle.com/en/java/javase/11/

![2020-09-16 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3f0ded0e-76ef-52ef-87b7-78207782675d.png)
Linuxで簡易WebDAVサーバ構築

# はじめに
コンテスト中にもっと簡単に素早くファイルサーバ立てれたらいいのになあと思い始めたのがきっかけ。目指すのは、WinSCPのようなクライアントで手早くアクセスし、ファイル転送やファイルオープンが簡単にできる環境です。

# WebDAVに至るまでの過程
単にファイルサーバと言っても色々ありますが、パッと浮かんだ候補について少し説明しておきます。

* SFTPは？  
SSHサーバを下手にいじって壊すとログインできなくなるため、コンテストではアンタッチャブルな世界(もちろん弄れないように設定されているはずではある)
* FTPは？  
SSHポート転送を間に入れることになった場合に、少し手間(できなくはないはず)
* WebDAVは？  
SSHポート転送にも耐え、重大な環境破壊を起こす可能性は少なそう

ということで、WebDAVサーバをたてる方向で模索することにしました。

# 選ばれたのはWsgiDAVでした
* Nginxは(個人的に)慣れているので簡単だが、デフォルトだとモジュールが足りないのでソースビルドしないといけない。
* Apacheだと不慣れであることと、触る設定ファイルが多くてよくわからない。もしコンテストでApacheが必須だった場合上手く共存させる自身がない。

ということでメジャーなWebサーバは諦めました。
調べてみたところ、WsgiDAVがとても手軽。
https://github.com/mar10/wsgidav

※動作確認はUbuntu20.04行いましたが、Pythonが入ってるならwindowsでもMacでも大丈夫なはず。

## インストール
```
$ pip install wsgidav cheroot
```

## 実行

動作確認。環境によってはsudoいるかも。

```
$ wsgidav --host=0.0.0.0 --port=8080 --root=/home/ --auth anonymous
```
あとはブラウザなりWinSCPなりでアクセスしてみる。

動作確認が終わったら、nohupをつけて実行。

```
$ nohup wsgidav --host=0.0.0.0 --port=8080 --root=/home/ --auth anonymous  > /dev/null 2>&1 &
```

# 感想
簡単すぎました。
アプリのユーザー編集をするとログアウトされる事件(rails)




#事件内容

Ruby onrails6 で難解な起こった事件

deviseで作ったユーザーの機能の
パスワードやメアドを編集する機能を作ったが
編集を更新すると、ログアウトされてしまう。


#解決方法

rails のガイドブックにちゃんと載っていたみたいです！
デフォルトでパスワードやメアドを編集すると、ログアウトされるみたいです。


これを解決する方法は。。。。

```user.controller.rb

 def edit
    @user=User.find(params[:id])
  end

  def update
     @user = User.find(params[:id])
     if @user.update(user_params)
      bypass_sign_in(@user)       #これを記述！！！！！！！！

      else
        render 'edit'
      end

  end

```

コメントアウトで記したコードを追加することで
この事件を解決することに成功しました。:sunny:

わーいわーい:shamrock:
PostgreSQLのUPDATE文の仕様を腹落ちさせる

# ことの発端

PostgreSQL 9.6環境で、下記UPDATE文を実行したところ、

```sql
UPDATE
  table1
SET 
  table1.column1 = table2.column1
FROM
  table2
WHERE
  table2.table1_id = table1.id
;
```

下記エラーが発生した。

``` 
Error: ERROR: column "table1" of relation "table1" does not exist
```

# なぜ？

[公式リファレンス](https://www.postgresql.jp/document/9.6/html/sql-update.html)でSET句の左辺の仕様を読んだところ

>table_nameで指名されたテーブル内の列名です。 必要に応じて、列名を副フィールド名や配列の指示子で修飾することも可能です。 
>対象列の指定にはテーブル名を含めないでください。 たとえば、UPDATE table_name SET table_name.col = 1は無効です。

と書かれており、エイリアスの使用が禁止されていることがわかった。
なるほど、と思いつつ、

- **別にエイリアスを使用したところで処理には影響ないのでは？**
- **なぜSET句の左辺だけエイリアスの使用が禁止されているのか？**

という疑問が残ったので、腹落ちするまで調べてみた。

# 結論

- **エイリアスを使用できる = 任意のテーブル内のカラムを参照できる**
- **エイリアスを使用できない = 特定のテーブル内のカラムしか参照できない**

という解釈で腹落ち。

PostgreSQLのUPDATE文は **同時に複数テーブルを更新できない** という制約があるため、SET句の左辺に記述できるカラムは、必然的にUPDATE句で指定したテーブル内のカラムになる。
つまり、特定のテーブル内のカラムしか参照できないため、エイリアスを使用できない制約にしている(のではないか)。

# おまけ

MySQLやSQL Serverでも同じ仕様なのか気になり、SET句の左辺でエイリアスを使用してUPDATE文を実行したところ、 正常に更新された。

### MySQL 5.7の場合

```sql
UPDATE
  table1, table2
SET 
  table1.column1 = table2.column1
WHERE 
  table2.table1_id = table1.id
;
```

### SQL Server 2017 Standardの場合

```sql
UPDATE
  table1
SET 
  table1.column1 = table2.column1
FROM 
  table2
WHERE 
  table2.table1_id = table1.id
;
```

MySQLの場合、UPDATE句に複数テーブルを記述することができるので、「そりゃできるよな」という所感だが、SQL ServerはPostgreSQLと同じUPDATE文なため、少しばかり違和感を覚える。

普段SELECT文を書く際にテーブル名.カラム名で記述しているため、SQL Serverの仕様の方が(個人的には)しっくりくる。
ただ、そもそもUPDATE句で指定したテーブル内のカラムしか更新できないのであれば、 **エイリアスの使用を禁止した方が、他テーブルを参照できてしまうという曖昧さを潰せる** というメリットもあるなぁ、という気づきも今回の調査で得ることができた。
instagramのクローンアプリを作る③

##はじめに
タイトルの通り、簡易版instagramのアプリを作っていきます。
下記の工程に分けて記事を執筆していきますので、順を追って読んでいただけたらなと思います。

①[アプリ作成〜ログイン機能の実装](https://qiita.com/maca12vel/items/d1d558dbf55a82b98990)
②[写真投稿機能の実装](https://qiita.com/maca12vel/items/592c78d435a8d950c434)　
③[ユーザーページの実装]
(https://qiita.com/maca12vel/items/c716702b02f977303011)　←イマココ
④[フォロー機能の実装]
(https://qiita.com/maca12vel/items/2760d33f3683fac91de5)
⑤投稿削除機能の実装

##Users Controllerを作成・編集する
今更ですが、命名規則としてモデル名は単数形、コントローラ名は複数形です。
今回はコントローラ名なので``users``と複数形にしています。
※以下、アプリケーションのディレクトリで

```
rails g controller users
```

ルーティングの設定も忘れずに行います。

```routes.rb
Rails.application.routes.draw do
  root 'homes#index'

  devise_for :users

  resources :photos
  resources :users # ←ここ
end
```

設定できたら、``users_controller.rb``を編集します。

```users_controller.rb
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
end
```

``showアクション``でユーザーを一覧表示するようにしました。

##viewファイルを編集する
前回の記事で、ホーム画面で投稿された画像とテキストを見られるようにしていましたが、
今回は各ユーザーのページ内で投稿内容が見られるように編集していきます。

ます、ユーザーページの作成から。
``app/views/users``に``show.html.erb``を作成し編集します。

```erb:app/views/users/show.html.erb
<h3><%= @user.email %></h3>

<% @user.photos.each do |photo| %>
  <div>
    <p><%= photo.caption %></p>
    <%= image_tag photo.image %>
  </div>
<% end %>
```

``@user.email``はユーザー名の代わりです。
そして、前回 投稿内容の表示を
``<% current_user.photos.each do |photo| %>``
としていたところを
``<% @user.photos.each do |photo| %>``
としました。

もちろん、ホーム画面に表示させていた投稿内容は削除します。

```erb:app/views/homes/index.html.erb
<h3>home</h3>

<div>
  <%= link_to 'logout', destroy_user_session_path, method: :delete %>
</div>

<div>
  <%= link_to '写真投稿', new_photo_path %>
</div>

#　↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ここから下を削除 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

<% current_user.photos.each do |photo| %>
  <div>
    <p><%= photo.caption %></p>
    <%= image_tag photo.image %>
  </div>
<% end %>
```

削除したら、各ユーザーのページへのリンクを表示させます。

```erb:app/views/homes/index.html.erb
<h3>home</h3>

<div>
  <%= link_to 'logout', destroy_user_session_path, method: :delete %>
</div>

<div>
  <%= link_to '写真投稿', new_photo_path %>
</div>

#　↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ここから下を追加 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

<% User.all.each do |user| %>
<div>
  <%= link_to user.email, user_path(user) %>
</div>
<% end %>
```
メールアドレスをユーザー名の代わりにしています。
``user_path(user)``の部分は``rails routes``のPrefixを確認。
今回は**``userのid``**も識別する必要があるので、``(user)``が必要です。
※``user_path(user)``の部分を``[user]``としても同じです。
[![Image from Gyoazo](https://i.gyazo.com/7f41bf12c9cb210e9cce21b3276171a2.png)](https://gyazo.com/7f41bf12c9cb210e9cce21b3276171a2)

ホーム画面が以下のようになっていれば成功です。
[![Image from Gyazo](https://i.gyazo.com/35de465f3847b9ae05d815f38e78a7b8.png)](https://gyazo.com/35de465f3847b9ae05d815f38e78a7b8)

実際の挙動はこのようになっています。
[![Image from Gyazo](https://i.gyazo.com/2bcef617df2b77622242277347ca014c.gif)](https://gyazo.com/2bcef617df2b77622242277347ca014c)

``sample@gmail.com``のページへアクセスすると、
一番上にユーザー名、続いて投稿内容が表示されています。

``example@gmail.com``のページへアクセスすると、
まだ投稿されていないのでユーザー名のみ表示されています。

ちなみに、ログインしていない状態でも各ユーザーのページにアクセスできるように、
``users_controller``に``before_action`` を設定していません。

---

以上です。お疲れ様でした。

次へ → ④[フォロー機能の実装]
(https://qiita.com/maca12vel/items/2760d33f3683fac91de5)
GitHubでブランチをマージすると自動でブランチを削除する（Delete merged branchの使い方）

# Delete merged branchを使う

こちらのリンクをクリック（GitHub上のアプリインストール画面）
https://probot.github.io/apps/delete-merged-branch/

README.md
https://github.com/SvanBoxel/delete-merged-branch/blob/master/README.md

## 「Add to GitHub」をクリック

![スクリーンショット 2020-09-16 0.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206542/f9babd78-bcda-5830-efb5-383b67009d64.png)

## アカウントとリポジトリを選択

![スクリーンショット 2020-09-16 0.36.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206542/54f03608-53a2-aa29-a33e-f3513d63c82b.png)

## GitHubでアプリをどのリポジトリーに適用するか決める

このアラートが出たらインストール成功

```
Okay, Delete merged branch was installed on the @UserName account.
```

![スクリーンショット 2020-09-16 0.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206542/d5acbcd2-3474-b0c9-f334-86632d2f4f81.png)

## 設定ファイルを作成

`exclude` -> マージ後に削除されて欲しくないブランチ名
`delete_closed_pr` -> マージせずにブランチが閉じられた時にブランチを削除するか否か

```yml:~/.github/delete-merged-branch-config.yml
exclude:
  - master
  - staging
  - develop
delete_closed_pr: true

```

## 機能テスト

上記の設定ファイルを書いたブランチをGitHubにpushaしてマージして見てください。
マージ後に暫くしてブランチがdeleteされたら成功です。

## アプリ
下記が今回使ったDelete merged branchの使い方です。
詳しくはこちらを見て思うような設定をおこなってください。
https://github.com/SvanBoxel/delete-merged-branch/blob/master/README.md
ARC 067 E Grouping

##問題
https://atcoder.jp/contests/arc067/tasks/arc067_c
##見た感じ
変な設定の組み合わせだと思って、ちょっとdpするしかないかなと思いながら、何もできずにいた。
解説をチラ見して解いた。。。
##解法
dp[i][j]をi人のグループまででj人がグループ分けされている場合の数としたとき、
dpの更新は

```math
dp[i][j]=\sum_{k=\{0,C,C+1,\dots D\}}dp[i-1][j-i*k]*\frac{(n-j+i*k)!}{(n-j)!*(i!)^k*k!}
\\dp[i][0]=1
```
で更新される。
これを踏まえて、こんかいはA人からB人までのグループしか作っちゃダメなので、
上の漸化式の立て方から、上の漸化式の更新をdp[a][1]からしていけば、A人からB人までのグループのみの場合の数が出てくることに気づく。
これでいける
##ソースコード
```c++
struct mint{
    ll x; // typedef long long ll;
    const ll EXC=-1;
    mint(ll x=0 ) : x((x % mod + mod) % mod) {}
    mint &operator= (const mint &a) { x=a.x; return *this; }
    mint operator-() const { return mint(-x); }
    mint &operator+=(const mint a)
    {
        if ((x += a.x) >= mod)
            x -= mod;
        return *this;
    }
    mint &operator-=(const mint a)
    {
        if ((x += mod - a.x) >= mod)
            x -= mod;
        return *this;
    }
    mint &operator*=(const mint a)
    {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const { return mint(*this) += a; }
    mint operator-(const mint a) const { return mint(*this) -= a; }
    mint operator*(const mint a) const { return mint(*this) *= a; }
    mint pow(ll t) const
    {
        if (!t)
            return mint(1);
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1)
            a *= *this;
        return a;
    }

    // for prime mod
    mint inv() const { return pow(mod - 2); }
    mint &operator/=(const mint a) { return *this *= a.inv(); }
    mint operator/(const mint a) const { return mint(*this) /= a; }
    bool operator!=(const int a) { return this->x!=a; }
    bool operator==(const int a) { return this->x==a; }
};
istream &operator>>(istream &is, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination{
    vector<mint> fact, ifact;
    combination(int n) : fact(n + 1), ifact(n + 1)
    {
        assert(n < mod);
        fact[0] = 1;
        for (int i = 1; i <= n; ++i)
            fact[i] = fact[i - 1] * i;
        ifact[n] = fact[n].inv();
        for (int i = n; i >= 1; --i)
            ifact[i - 1] = ifact[i] * i;
    }
    mint operator()(int n, int k)
    {
        if (k < 0 || k > n)
            return 0;
        return fact[n] * ifact[k] * ifact[n - k];
    }
    mint parm(int n,int k){
        if (k < 0 || k > n)
            return 0;
        return fact[n] * ifact[k];
    }
};

const int N_MAX=100005;
int n,a,b,c,d;
combination com(1000);
mint dp[1005][1005];

void Main(){
    int x=0,y=INF10,z=1;
    //入力
    cin>>n>>a>>b>>c>>d;
    //処理
    rep2(i,a-1,b)dp[i][0]=1;
    rep2(i,a,b){
        rep2(j,1,n){
            dp[i][j]=dp[i-1][j];
            rep2(l,c,d){
                if(l*i>j)break;
                dp[i][j]+=dp[i-1][j-i*l]*com.parm(n-j+i*l,n-j)*com.ifact[i].pow(l)*com.ifact[l];
            }
        }
    }
    //出力
    cout << dp[b][n] <<endl;
}

int main(){
    cin.tie(nullptr);
    cout<<fixed<<setprecision(12);
    Main();
}
```
【備忘録】Gate権限制御 @canでクエリ発行数が増えちゃった話+対処法

##なんだかものすごい権限参照のクエリ重複してる...

###①対処
blade内の

```
@can

@endcan
```


の記述を

```
@if
@endif
```

へと変更し、判定に用いる権限の値をviewへと渡す。


ループ処理内でcanが使われていた場合、これが原因の可能性が高いですが以下に続きを...


###②原因
<span>@</span>canによる判定をおこなう時にFacadeクラスのインスタンス化、権限参照のDBアクセスが発生します。
今回の自分の場合レコード情報と合わせてアイコン表示をする必要がありました。
この時、**ループ処理内で表示/非表示の制御**をしていたことからレコード数分のDBアクセスが起こっていました。



###③対処例
自分の作業でおこなった対処の一例です。

1：①の通りbladeの記述を<span>@</span>can→<span>@</span>ifへ変更
2：controller側でユーザーインスタンスから権限、またはそれに相当する値を取得し、compactもしくはwithでviewへ渡す
3：bladeで受け取り判定に使用

大したことはしていませんが、手間をかけずにできたのでこの方法で解決できるパターンもあると思います。

***


###参考記事
@Yorinton様
https://qiita.com/Yorinton/items/604c5b1f3445cb23d565

公式
https://readouble.com/laravel/5.7/ja/authorization.html


***

以上となります。
仕様や現状の改善点など調べておりますので、備忘録ではありますが随時修正していきます。
DjangoのMiddlewareの実行順序

DjangoでMiddlewareを複数指定した場合どのような順序でコードが実行されるのか気になったので試してみた。

# 実験コード
## settings.py
設定ファイルの抜粋

```python
MIDDLEWARE = (
    # ・・・・諸々のMiddleware,
    "middleware.Middleware1",
    "middleware.Middleware2",
)
```

## middleware.py
middlewareを2つ定義

```python
class Middleware1:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print("M1 before")
        response = self.get_response(request)
        print("M1 after")

        return response


class Middleware2:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print("M2 before")
        response = self.get_response(request)
        print("M2 after")

        return response
```

## hoge.py
テキトーなView

```python
from django.http import HttpResponse
from django.views import View


class Hoge(View):
    def get(self, request):
        print("View")
        return HttpResponse()
```

# 実験結果
Hoge View に対応するエンドポイントにリクエストした結果

```
M1 before
M2 before
View
M2 after
M1 after
```

- 設定ファイルで定義したMiddlewareの順に、入れ子になるような形で `__call__` が実行される。
- Viewのコードは入れ子の真ん中で一度だけ実行される。

書いた後で気づいたけど、[こちらの記事](https://qiita.com/shirakiya/items/1503eaffe81f91af5b9d#middleware%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E8%A8%AD%E5%AE%9A%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)にも同様の事実を示す下記の記載があった。

> また、Middlewareはリクエストが送られたらこのsettings.pyに設定されているものを上から順番に(2)に書かれた処理が実行されます。一方で(3)に書かれた処理はこの逆の順番で実行されます。なので場合によってはこの順番を意識して設定する必要があります。

(入れ子になっている様子がよくわかったのでまぁいいか・・。)
JPEG Exif Orientation を exiftoolで編集

MacでJPEG Exif Orientationを編集する方法の備忘録。
JPEG Exif Orientationは、exiftoolで編集できる。

# exiftoolのインストール

```
% brew install exiftool
% /usr/local/bin/exiftool -ver
12.00
```


# Orientationの編集
```
/usr/local/bin/exiftool -Orientation#=<Orientation> -n <ファイル名>"
```
#### 実行例
```
/usr/local/bin/exiftool -Orientation#=2 sample.jpg"
```

#### Orientationで指定する引数

```
1 = Horizontal (normal) : 標準
2 = Mirror horizontal   : 水平方向に反転
3 = Rotate 180          : 180°回転
4 = Mirror vertical     : 垂直方向に反転
5 = Mirror horizontal and rotate 270 CW :反時計回りに90°回転および垂直方向に反転
6 = Rotate 90 CW        : 反時計回りに90°回転
7 = Mirror horizontal and rotate 90 CW  : 時計回りに90°回転および垂直方向に反転
8 = Rotate 270 CW       :方向: 時計回りに90°回転
```


|1: Horizontal (normal)|2: Mirror horizontal|3: Rotate 180|4: Mirror vertical|
|---|---|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/a4bb604f-d5d3-8eb9-7b5b-d7cdd11fdaf6.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/bbeeeb0e-b1b1-a542-6a6d-9c53b5276230.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/c95fd190-3c7a-ca79-6f7a-99822de15476.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/9cec0489-e744-2107-340e-e076180d4261.png)|

|5 = Mirror horizontal and rotate 270 CW|6: Rotate 90 CW|7: Mirror horizontal and rotate 90 CW|8: Rotate 270 CW|
|---|---|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/9ff84409-f7a7-8bad-aea2-6b06491972d4.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/c465cee1-dc8d-89ee-3acd-0afdbc44225f.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/6b09f386-d698-1aa6-c343-ff739a29a28c.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97314/6be633e5-fd21-aa83-cd28-3f49a359560e.png)|
Vert.x on KotlinのTuppleをforしながらパスワードっぽいのはマスクする(SQLログとかに使うのよ)

動機: 
SQLロギングでパラメーターを順番に出力したい
パスワードとかはマスクしたい

```kotlin
    val a = Tuple.of(1,"password","ppp")
    val x = listOf(1,2) // パスワードが入っている添字的なもののリスト
    for(i in 0 until a.size()){
      if(x.contains(i)){
        println("<password-mask>")
      } else {
        println(a.getValue(i).toString())
      }
    }
```
そとからパスワードのindexを与えれば行けそうね。

```
1
<password-mask>
<password-mask>
```

マスク要らない時はl`istOf`にジェネリクスで型与える必要あり

```kotlin
    val a = Tuple.of(1,"password","ppp")
    val x = listOf<Int>() // パスワードが入っている添字的なもののリスト
    for(i in 0 until a.size()){
      if(x.contains(i)){
        println("<password-mask>")
      } else {
        println(a.getValue(i).toString())
      }
    }

```

```
1
password
ppp
```

これで勝てる
【備忘録】Laravelのエラーメッセージを日本語にしたい場合

#エラーメッセージ定義があるのはよいけど日本語にならないものか...

１つずつ設定することも可能ですが、公式ドキュメントや偉大なる先人が日本語化したものがあるので簡単に変更できます。


###手順
1:resources/lang 配下に日本語メッセージ用ファイルを作成
@ama_keshi様の記事を参考に作成していただくとスムーズです。お世話になりました。
https://qiita.com/ama_keshi/items/27292949d41fdd8bd930

Laravel5.7の時点では、以下のコマンド実行で日本語化用ファイルがまとめて生成できます。
https://readouble.com/laravel/5.7/ja/validation-php.html
>このページの内容を含め、auth.php、passwords.php、pagination.php,validation.phpの４日本語ファイルをまとめて生成するには、以下のコマンドをプロジェクトのルートディレクトリで実行してください。（Windows環境ではまだ試していません。）


```
php -r "copy('https://readouble.com/laravel/5.7/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
php -f install-ja-lang.php
php -r "unlink('install-ja-lang.php');"
```

2:メッセージ編集
好きなメッセージへと個別に変更することも可能ですが、日本語にしたいだけであれば一括で書き換えましょう。


公式ドキュメント
https://readouble.com/laravel/5.7/ja/validation-php.html
git minoryorg様
https://github.com/minoryorg/laravel-resources-lang-ja

***
[OutSystems]Reactive Web AppのAggregateは全データが露出する

今年 (2020) のNext Stepの中で、Reactive Web Appのセキュリティセッションを聞いていて気になったので試してみました。

Reactive Web AppのAggreagateは最適化は開発者が自分で行わなければならず、セキュリティとパフォーマンスの観点で注意が必要とのこと。

# 環境情報
Personal Environment(Version 11.9.0 (Build 16900))
Service Studio(Version 11.8.7)
対象はReactive Web Appです。

# テスト画面を用意
入力としてユーザーIDを受け取り、System EntityのUserレコードを取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5dd91be2-d543-332a-ac9c-507ccff012ae.png)

更にそのレコードのNameだけを画面にExpressionで表示しました。
サーバーサイドのAggregateであれば、OutSystemsによる最適化が行われ、使わない列（Name以外の列）はデータベースから取得されなくなるのですが……。

# 動作確認
## Aggregateの条件等に使う変数もセキュリティ上注意
画面にぶら下げたAggregateは、初期表示時点で自動的に通信が走り取得されます。
非同期に呼ばれるために、画面のユーザーへの初期表示をブロックしないのがいいところ。

以下は、Chromeのデベロッパーツールで画面の通信を表示したところ。
Aggregateのフィルターに使っているUserIdが露出していますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/82386446-0143-c8e3-d386-c676bf500b86.png)

HTTPSの通信なので、ユーザーが通信を見て、自分で任意のパラメータを渡して実行することはできてしまいますね。それを踏まえた設計にする必要があります。

## 結果は全列通信として返ってくる
以下は、Aggregateの通信のレスポンスに含まれるJSONを、JSON.parseで整形したもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/e436e9ab-1d04-ca58-0ecb-c33cd734fb08.png)

User Entityの各列が全部出てしまっていますね。
ユーザーに見せたら行けない列が含まれないように注意しなければなりません。

# 列を隠す方法
Data Actionを使うことで解決しそうです。
Data ActionはScreenを右クリックし、「Fetch Data from Other Sources」を選択して作成します。

実装例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/6567a7a9-782c-fb03-353b-2a6cfc0f0dd3.png)

画面入力のUserIdでUserを検索し、そのName列を出力変数にセットするだけのシンプルなAction。
Data ActionもAggregateと同様に通信が発生しますが、出力は、定義した出力変数のみです。

``` JavaScript
{"versionInfo":{"hasModuleVersionChanged":false,"hasApiVersionChanged":false},"data":{"Name":"テストユーザー"}}
```

設定したName出力だけが通信結果に出ていますね。

# AggregateとData Actionのどちらを使うか？
基本はAggregateで良いと思います。
楽なので。

ただ、上で確認した特性を検討し、通信量が大きすぎる、セキュリティ上問題があるときにはData Actionを選ぶのが良いバランスではないかと。
備忘録　Javascript 配列のデータ抽出 filter

# Javascript filter

## 基本（数字）
```
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var result = array.filter((value)=>{
    //valueには配列の要素が入る(1 2 3 ... 9 10)
    //valueが5よりも小さい数だけ抽出
    return value < 5;
})

console.log(result);
// [1, 2, 3, 4]　という新しい配列ができる。

```

## 基本②（文字列）
```
var string_array = ["apple", "orange", "peach", "lemon"];

var result = string_array.filter((value) => {
    return value === "apple" || value == "orange";
})

console.log(result);
//["apple", "orange"] という新しい配列ができる。

```

## 重複を操作
```
var array = [2, 3, 4, 5, 3, 4, 5, 6, 7, 8, 6];

var result = array.filter((value, index, array) => {
    return array.indexOf(value) === index;
})
console.log(result);
//[2, 3, 4, 5, 6, 7, 8]
```

## オブジェクト
※ array.filter(callback,object)とするとthisでobjectを参照できる。

```
var students_id = {
    1: "tanaka",
    2: "suzuki",
    3: "sato",
    4: "nakata",
    5: "nakamura" 
}

var ids = [1, 2, 3, 5, 7, 8, 9];

var result = ids.filter(function(value){
    for(var id in this){
        if(id == value){
            return value;
        }
    }
},students_id)

console.log(result);
//[1, 2, 3, 5]
```

# 参考
https://www.sejuku.net/blog/21887
PoetryスクリプトでFastAPIアプリを起動する

## 前提

[転職黙示録 (5) 意外と使えるPoetry入門 (Poetry + FastAPI)](https://qiita.com/BrainVader/items/99bd2f66c977635da915)などを見てPoetryのプロジェクトにFastAPIを依存性として加えておきましょう(手前味噌).

またpoetryのpyproject.tomlのtool.poetry.scriptsセクションに記述するコマンドを便宜上poetryスクリプトと呼びます.

## モチベーション

poetryにもNPMスクリプトのような機能があるのですが, ただNPMスクリプトのようにターミナルに入力するコマンドをコピペしても動きません. つまり以下のようにしても動きません.

```python
[tool.poetry.scripts]
start = "poetry run uvicorn project_name.main:main --reload"
```

## Poetryスクリプトの書き方

記法はmodule:functionとするようです. したがって

```python
[tool.poetry.scripts]
start = "project_name.main:main"
```

とするのが正しいようです. project_nameとmainをドットでつなぐのは絶対インポートのようです. 実行は

```shell
poetry run start
```

です.

## Uvicornによる起動

次にUvicornはASGIサーバーでFastAPIで作ったアプリケーションを起動してくれます. [First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/)の例を載せときます.

```python
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}
```

これはコマンドラインから

```shell
poetry run uvicorn project-name.main:main --reload
```

と実行できます. しかしpoetryスクリプトからは実行できません. まず呼び出すべきmain関数がありません. そのためmain関数を作ってそこから呼び出すように変更します.


```python
import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

def main():
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)

if __name__ == "__main__":
    main()
```

これを,

```python
poetry run start
```

で実行すると

> WARNING:  You must pass the application as an import string to enable 'reload' or 'workers'.

と警告をくらいます. 動かないので実質エラーですが警告どおりアプリケーションをimport stringとして渡せとあるので今度はappを文字列にしてみます.

> ERROR:    Error loading ASGI app. Import string "app" must be in format "<module>:<attribute>".

今度はエラーをくらいました.

## 結果

モジュールは絶対パスでproject_name.mainでした. 問題はattributeですがモジュールの後にappを指定すると動きました.


```python
import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

def main():
    uvicorn.run("project_name.main:app", host="0.0.0.0", port=8000, reload=True)

if __name__ == "__main__":
    main()
```

これでpoetry run startでUvicornサーバーがFastAPIのアプリケーションを起動してくれます. 大勝利:trophy:

## まとめ

Pythonの属性ってよく分かりませんね:sweat_smile:

## Reference

Poetryスクリプトに関しては情報がなく分からなさすぎてstackoverflowに質問したやつです. そのまま答えとはなりませんでしたが.

[How to run FastAPI application from Poetry?](https://stackoverflow.com/questions/63809553/how-to-run-fastapi-application-from-poetry/63870151#63870151)
git ignoreを後から追加するときの流れ

#モチベーション
- 最近後輩に教えることや，自分の昔のリポジトリを整理することが多くgit ignoreがきちんと書かれていないコード（多分色々良くない）と対面することが多かった


# 流れ

## step0 準備

macだと

```
[command] + [shift] + [.(ドット)]
```
で隠しファイルが見えるようになります。

※windowはショートカットキーがなさそう（あったら教えてください🙇‍♂️）なので，
設定を弄ってください。

## step1 ignoreを書く


よく使うものの例

````
*.csv #拡張子
results/　#ディレクトリ毎
````

##step2 remoteにあるいらないファイルを消す（gitの管理下から消す）

一個一個管理下から外す方法もあるぽいが，今回はまとめて外して後で，git ignoreしないファイルをコミットするという手順を取ることにしました（めんどくさいから）

```
$ git rm -r --cached .
```

##step3 commitする

```
$ git add .
$ git commit -m '適当にコメント'
```


#まとめ
これからはリポジトリを作った時に必ず書くことにします（戒め）
[メモ] Windows 10に組み込まれているオープンソースソフトウェア

「最近はWindows 10にオープンソースソフトウェアが組み込まれることが増えたね」って思ってリストアップしてみた。
記憶から引っ張っているので、リストはガバガバです。

ライセンス条項は[Third Party Notices](https://www.microsoft.com/en-us/legal/products/notices/win)として一覧がありますが、「本当に使っているの？」ってものもあったりするので、一般の開発者/ユーザーが利用できる(はずの)ものをリストアップしました。

# ライブラリ

## International Components for Unicode (ICU)
 - icuuc.dll 
 - icuin.dll 

Windows SDK にヘッダー/libあり。

## SQLite3
- winsqlite3.dll

Windows SDK にヘッダー/libあり。

## LibreSSL
- libcryopto.dll

Windows SDK にヘッダー/libなし。
多分OpenSSHから使う前提。

## zlib
- clrcompression.dll

Windows というか.NET Frameworkに含まれる。
.NET Frameworkから使う前提なので、ヘッダーはない。


# アプリケーション(コマンド)

## OpenSSH
- ssh-shellhost.exe
- scp.exe
- sftp.exe
- sftp-server.exe
- ssh.exe
- ssh-add.exe
- ssh-agent.exe
- sshd.exe
- ssh-keygen.exe
- ssh-keyscan.exe

標準ではないが、オプション機能として利用できる。

## curl

- curl.exe

## Edge

言わずと知れた Chromium版Edge。
これに含まれるオープンソースソフトウェアは大量にあるので、詳細は割愛。
EC2 (Amazon Linux) にPHP7.2 をインストールし、php.ini を設定するまでのまとめ

:warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning:

  【2020/12/23追記】 
Amazon Linux は2020/12/31 でサポートが終了してしまうため、
後継のOS であるAmazon Linux 2 を使うことをおすすめします。

新しく書き直した記事はこちら ↓
[EC2 (Amazon Linux 2 ) にPHP7.2 をインストールし、php.ini を設定するまでのまとめ](https://qiita.com/kanadeee/items/93f83eaea079a31e8994)

:warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning: :warning:

タイトルのとおりの備忘録です。
LAMP環境を作り、PHPの初期設定をします。

後々同じことをやる方のググる手間を省ければと思い、まとめました。
「とりあえずEC2でPHPを動かしたいぞ！！！」というあなたのお役に立てれば幸いです:pray:

# 前提
■ 先にVPCやサブネットの用意を終わらせておくとスムーズです。
　 （ECインスタンス作成時に紐付けられるため）

　 もしよろしければ、以下の記事を参考になさってみてください！
　 ・[VPC作成 〜 パブリック・プライベートサブネットを作るまでの手順①](https://qiita.com/kanadeee/items/527e7ea4daed36b396fe)
　 ・[VPC作成 〜 パブリック・プライベートサブネットを作るまでの手順②](https://qiita.com/kanadeee/items/daba7a84ac89eb89556c)

■ CloudFormation を使った構築手順については今回触れません。

# ざっくりの流れ
1. EC2 インスタンスを作成
2. LAMP環境をインストールする
3. `mb`モジュールをインストールする
4. `php.ini` を設定する

# 1. EC2 インスタンスを作成

**▼ 参考：
　[AWSコンソールからEC2インスタンスを作成する手順](https://qiita.com/kanadeee/items/cfdcffea3e47a0a71c98)**

LAMP環境をインストールする際、EC2インスタンスにssh接続する必要があります。
EC2インスタンス作成時には`既存のキーペアの選択` or `新しいキーペアの作成`を選ぶようにしてください。

**▼ EC2インスタンスにssh接続するコマンド：**

```
ssh -i [キーペアのパス] ec2-user@[パブリック IPv4 アドレス]
```
# 2. LAMP環境をインストールする
**▼ 参考：
　[チュートリアル: Amazon Linux AMI を使用して LAMP ウェブサーバーをインストールする - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-LAMP.html)**

# 3. `mb`モジュールをインストールする
**▼ 参考：
　[Amazon Linuxでphpでmbstringを使う - Qiita](https://qiita.com/osada/items/885510dae4e8ec4c88f4)**

PHPにはマルチバイト文字列を扱うための関数がいろいろあります。(例：`mb_substr`)

`mb`モジュールをインストールしておかないと、PHPを実行した際に`Fatal error` が出てしまいます。

# 4. `php.ini` を設定する
**▼ 参考：
　[【PHP】PHPをインストールしたらやっておきたい設定 - Qiita](https://qiita.com/knife0125/items/0e1af52255e9879f9332)**
 
初期状態の`/etc/php.ini` をコピーしてバックアップを取っておいてから設定を変更するようにすれば、何かあったときに戻せるので安心です。

上記の記事で「セキュリティに関する設定」として記載されている`session.hash_function` などは`PHP 7.1.0` から削除されているので設定不要です。

# 参考
- [チュートリアル: Amazon Linux AMI を使用して LAMP ウェブサーバーをインストールする - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-LAMP.html)
- [Amazon Linuxでphpでmbstringを使う - Qiita](https://qiita.com/osada/items/885510dae4e8ec4c88f4)
- [【PHP】PHPをインストールしたらやっておきたい設定 - Qiita](https://qiita.com/knife0125/items/0e1af52255e9879f9332)
- [PHP: 実行時設定 - Manual](https://www.php.net/manual/ja/session.configuration.php)
React Nativeをいちから始める＜公式ドキュメントを読んでいく＞　Part.2 Environment setup

こんにちは。

スマホアプリを作成するフレームワークReact Nativeの公式ドキュメントを読んでいくシリーズ第2回は、環境設定です。

# 本記事の位置づけ

基本的に、公式ドキュメントの解説を上から順番に見て、ざっとまとめた記事です。
また、本ページは、下記公式ドキュメントの一番最初「The Basics」の部分をまとめた記事となります。

https://reactnative.dev/docs/getting-started
- [Part1. The Basics](https://qiita.com/rogistyle/items/97ccce9bc0a8d720829f)
- [Part2. Environment setup](https://qiita.com/rogistyle/items/e7bc1104fc4b57c29e56) ←今ココ★
- Part3. Workflow
- Part4. Design
- Part5. Interaction
- Part6. Inclusion
- Part7. Performance
- Part8. JavaScript Runtime
- Part9. Connectivity
- Part10. Native Components and Modules
- Part11. Guides (Android)
- Part12. Guides (iOS)

なお、本ページに記載のソースコードはすべて上記サイトから引用したものとなります。

# 開発環境のセットアップ

- モバイル開発経験がない方は、ExpoCLIを使うのが便利
- ブラウザでぱっと動作を確認したい場合は、[Snack](https://snack.expo.io/)を使うのが便利
- モバイル開発の経験がある方は、React Native CLIを使うのが便利(ここでは解説しない)

## Expo CLIのセットアップ

1.Node.js(バージョン12 LTS以降)をインストール
2.`npm`でExpo CLIをインストール

```terminal
npm install -g expo-cli
```

3.以下コマンドで"AwesomeProject"という名前のプロジェクトを作る

```
expo init AwesomeProject
cd AwesomeProject
npm start
```

`npm start`の代わりに`expo start`でもよい


## Expo CLI上でのアプリ実行

1.[Expo](https://expo.io/)アプリをスマホにインストールする(iOS、Android両方あり)
2.PCとスマホを同じWifiネットワーク上に接続する
3.Android:Expoアプリ上でPCのターミナル上のQRコードを読む
  iOS:カメラアプリのQRコードリーダーでPCのターミナル上のQRコードを読む
4.アプリがスマホで実行される
5.メインファイルである`App.js`の修正からしていきましょう！コードを修正すると自動的にスマホに反映されます。

## 困ったときのリンク

- [Expo docs](https://docs.expo.io/)
- [Expo CLIの制限事項](https://docs.expo.io/introduction/why-not-expo/?redirected)


## Expo CLI利用時の注意事項

- Expo CLIはネイティブコードを実行しているわけではないため、各プラットフォームのネイティブコードは実行できない
- 各デバイスのシミュレータや実機で動かしたい場合もExpo CLIは使えない
- 上記のような場合は、[React Native CLI Quickstart](https://reactnative.dev/docs/0.8/getting-started)を読んでネイティブ環境をセットアップするなり、ネイティブコードを["eject"](https://docs.expo.io/workflow/customizing/?redirected)するなどの必要がある。
- Expo CLIは最新のReact Nativeをフォローするため、どのバージョンをサポートしているかは[バージョン依存のページ](https://docs.expo.io/versions/latest/sdk/overview/#sdk-version)を見てね。

# 既存アプリとの統合

すみませんが、この章は割愛します。
[原文](https://reactnative.dev/docs/integration-with-existing-apps)を読んでください。



# TVデバイスとの統合

すみませんが、この章は割愛します。
[原文](https://reactnative.dev/docs/building-for-tv)を読んでください。

# Android、iOS、Web以外のプラットフォーム

下記のプラットフォームに対応しているので、気になるものはぐぐってみてください。
実験的に対応しているだけのものもあるため、よく読んでから使うようにするとよいです。

- React Native Windows
- React Native DOM
- React Native Turbolinks
- React Native Desktop
- React Native macOS
- React Native tvOS
- alita
- Proton Native

また、好きなプラットフォームに独自に対応させることもできるようなので、こちらもドキュメントを参照してください。

[Creating your own React Native platform](https://reactnative.dev/docs/out-of-tree-platforms#creating-your-own-react-native-platform)
《未経験→webエンジニア》実務2日目


## この記事の目的
自分がやったこと、知らなかったこと、やるべきことを明確にし
1日あたりの成長速度を速める。


## 【今日やったこと】
APIテスト

postmanを利用して、
主に登録フォームにpost情報を送った際に
期待通りに帰ってくるかのテスト


## 【知らなかったこと】

postmanというツール、使い方


## 【明日】やるべきこと、読みたい記事など

AWS資格取得のために、やるべきこと
https://qiita.com/x5dwimpejx/items/0b9b7e7b502d8bd255e9


Dokerのチュートリアル記事！
https://qiita.com/Michinosuke/items/5778e0d9e9c04038903c
M5Stack Core2にArudino IDEで書き込みと発生したまさかのエラー #iotlt


2020年9月頭に発売されたばかりの[M5Stack Core2](https://www.switch-science.com/catalog/6530/)をArduino IDEで触ってみます。

Arduino IDEでの書き込みと発生したエラーのメモ書きです。

## 書き込み時のボードライブラリ選択

通常のESP32系ボードと同じです。

![スクリーンショット 2020-09-15 23.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f9498995-30c5-05e6-4b2b-57d6705af55d.png "スクリーンショット 2020-09-15 23.17.30.png")


* 標準の`ESP Dev Module`を選択


![スクリーンショット 2020-09-15 23.18.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ff8ae821-354b-0a76-54b5-7f27011cf7c6.png "スクリーンショット 2020-09-15 23.18.40.png")


## とりあえず書き込み

```hello.ino
void setup() {
  Serial.begin(115200);
  Serial.println("start");
}

void loop() {
}
```

こんな感じで問題なければ書き込みできます。

また、タッチパネルやらのセンサーにアクセスするためのライブラリはまた別である模様なのでこちらを利用しましょう

> [m5stack/M5Core2](https://github.com/m5stack/M5Core2/)

## エラー: Failed to connect to ESP32 Timed out waiting for packet header


**問題発生しました。**

> ![スクリーンショット 2020-09-15 17.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/33038e28-f855-f4b4-c749-27f690ba43d6.png "スクリーンショット 2020-09-15 17.23.09.png")


このエラーはよく見るのですが、Bootボタン押しながら〜とか書き込み速度遅くしてねーとか調べると出てきます。

が、今回は...

.
.
.

### まさかのUSB Ttype-Cのコネクタの上下が逆という問題

こんなことあるんですねぇ...

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Core2をArduino IDEから書き込みが全然できなかったんだけど、まさかのこれでした... <a href="https://twitter.com/mgo_tec?ref_src=twsrc%5Etfw">@mgo_tec</a> さんありがとう... <a href="https://twitter.com/hashtag/m5stack_core2?src=hash&amp;ref_src=twsrc%5Etfw">#m5stack_core2</a> <a href="https://twitter.com/hashtag/m5stack?src=hash&amp;ref_src=twsrc%5Etfw">#m5stack</a> <a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a><br><br>&quot;USB-TypeCコネクタの上下を逆に挿していると~書き込みエラーが出る場合があります。&quot; / <br><br>こんなことあるんだな...<a href="https://t.co/qvGmIeWEb9">https://t.co/qvGmIeWEb9</a> <a href="https://t.co/lOE6LLlN8M">pic.twitter.com/lOE6LLlN8M</a></p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1305785997146443783?ref_src=twsrc%5Etfw">September 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[mgo-tec電子工作さんの記事](https://www.mgo-tec.com/blog-entry-trouble-shooting-esp32-wroom.html/3)でこの件に触れていて、まさかと思い試したらそのまさかでした。

## まとめ

みんながみんな二分の一の確率でハマるのかわからないですが、このエラーが出た時にこういった不具合もあるということを認識しておくと良さそうです。


運が良かったのか悪かったのか...


## 参考: M5Core2触ってみたけど上下注意 #iotlt vol67

* https://speakerdeck.com/n0bisuke/m5core2hong-tutemitakedoshang-xia-zhu-yi-number-iotlt-vol67
* https://iotlt.connpass.com/event/185929/
異なる階層の View の座標を取得しよう

今回も初学者向けに階層の異なる特定の View の座標を取得したい時に使用する `convert()` 関数の使い方を簡単に紹介したいと思います。

### 実際に使ってみる👨‍💻

下記のような階層の View を参考に `convert()` メソッドを使って見て座標を取得してみます。

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yum_fishing/20200908/20200908175122.png">


#### 緑色からみた黄色

これは、そもそも`緑色の View` の中に `黄色の View` が含まれている(`addSubView()`されている)ので、黄色の View の Frame を取得すれば座標が分かります。

```swift
let greenToYellowRect = yellowView.frame
print(greenToYellowRect.toString) // (x: 19.0, y: 38.5)
```

また、`toString` というプロパティは下記のように CGRect の Extension プロパティとして追加すると独自に値を取得するためのプロパティを追加することができるようになります🙃 特に iOS 開発ではこの Extension 記法は頻繁に使用するので、どんどん書いて使い方をマスターしましょう！

```swift
extension CGRect {
    var toString: String {
        return "(x: \(self.origin.x), y: \(self.origin.y))"
    }
}
```

#### 赤色からみた黄色

次に、赤色の View から見た黄色の View の座標を取得していきましょう。先ほどと同じように `frame` を使って座標を取得したいところですが、今回は赤色から見た黄色の座標を取得したいので、`frame` で取得してしまうと**緑色**から見た**黄色**になってしまうので気をつけましょう。

それでは早速、`convert()`メソッドを使って**赤色**から見た**黄色**の座標を取得してみます。

```swift
let redToYellowRect = greenView.convert(yellowView.frame, to: redView)
print(redToYellowRect.toString) // (x: 94.5, y: 146.0)
```

それぞれの View の指定方法は、最後のセクションにまとめてあります。

#### 白色からみた黄色

次に、白色の View からみた黄色の View の座標を取得していきます。コードは下記のようになります。

```swift
let whiteToYellowRect = greenView.convert(yellowView.frame, to: self.view)
print(whiteToYellowRect.toString) // (x: 181.5, y: 315.0)
```

それぞれの View からみた黄色の View の正しい座標が取れるようになりました🎉


### まとめ

`convert()` メソッドは、どこにどの View を指定するのか忘れがちなので下記のように覚えておくと便利です。

#### `convert(to:)` の場合

```swift
let redToYellowRect = 座標を知りたいViewの親View.convert(座標を知りたいView.frame, to: 座標変換の基準となるView)
```

#### `convert(from:)` の場合

```swift
let redToYellowRect = 座標変換の基準となるView.convert(座標を知りたいView.frame, from: 座標を知りたいViewの親View)
```

### 参考

- https://developer.apple.com/documentation/uikit/uiview/1622442-convert
- https://qiita.com/sachiko-kame/items/6ac03b422de1d1006ec8
Parallels Desktop for Macを使ってMac OSにメイリオをインストールする方法

# 目的

MacのPagesで作成したWord形式のファイルを相手に送った時、Windowsで開かれる可能性があったので、Macでもメイリオを使えるようにしました


# 注意

- Parallels Desktopを使っているのであれば、Windows上にLibreOfficeなどをインストールして資料を作成した方が早いです
- MacにもMS Pゴシックはインストールされているので、そちらを使った方が効率は良いかもしれません
- この方法が問題ないか各自で確認の上お試しください

# 手順
1. Parallels Desktop for Macをインストール
2. Windows 10を起動し、コントロールパネルでフォントを開く
3. メイリオのフォントファイルをコピーし適当なMacのフォルダにペーストする
4. Mac上でコピーしたファイルをダブルクリックし、インストールする

これでPagesのフォントでメイリオが選べるようになります。

# 参考
- https://aprico-media.com/posts/1389
【DbUnit】テストデータで動的に日時を設定する

`DbUnit 2.7.0`より、データセットで「今日からn日後」というように、動的に日時を設定することができるようになりました。

- リリースノート: [DbUnit – Changes](http://dbunit.sourceforge.net/changes-report.html#a2.7.0)

# やり方
以下[公式ドキュメント](http://dbunit.sourceforge.net/datatypes.html#relativedatetime)からの抜粋です。

- データとして現在時刻を入れたい場合、XMLファイルなら`${カラム名}="[now]"`というように指定する
  - 昨日を指定したい場合は`[now-1d]`など、加算/減算の形で書く
  - この文字列は`LocalTime#parse()`がパースできる形式で指定する

## 補足
`now`のような情報は、処理中の生成タイミングの差で結果が壊れるのを防ぐため、1連の処理の中で1度のみ生成される形にすべきです。
今回紹介した機能が必要になるのは`MySql`の`CURRENT_DATE`みたいな機能により日時を`DB`側で生成している場合が殆どだと思いますが、これを踏まえると、この機能で頑張るよりは設計を見直したほうが良い場合の方が多いと思います。

# 参考にさせて頂いた記事
- [java\-DBUnitデータセットの現在を基準とした日付\-スタックオーバーフロー](https://stackoverflow.com/questions/2856840/date-relative-to-current-in-the-dbunit-dataset)
node-red-contrib-generic-ble（notifyでデータ読み込みを行う）

node-red-contrib-generic-bleでnotifyでデータを読み込む方法をメモしておきます。

#node-red-contrib-generic-ble

ここからインストールできます。（Node-REDのパレット管理からダウンロードしても良いですけど）
[node-red-contrib-generic-ble](https://flows.nodered.org/node/node-red-contrib-generic-ble)


#BLEのデータへのアクセス手法
BLEのデータへのアクセス手法は以下の3つがあります。
###Read
セントラル側がペリフェラル側へデータを読みに行く

###Write
セントル側がペリフェラルに対してデータを書き込む

###Notify
ペリフェラル側のタイミングで継続的にセントラル側へデータ送信させる

#Readの設定

下の図のように、inject～generic-ble～debugをつなぎますが、injectのペイロードを日時にしている場合、Readでデータを取りに行くことになります。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353289/fbf50774-b42a-e9fc-33f0-f7bb7eded561.png)

#Notifyの設定
notifyでデータを取得したい場合は、injectのペイロードを「JSON」にし、以下を記載します。

`{"notify":true, "period":6000}`

periodの6000は6000回データを送信させるということで、際限なく送信させる場合は0にします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353289/27b8b86f-0019-8b1b-d71f-7f88b859a13f.png)

デプロイ後、injectノードの左側にあるボタンをクリックするとNotifyが実行され、ペリフェラル側からデータが送信されてきます。

#Node-RED起動後、Notifyを開始する
Node-RED起動後、自動的にNotifyを実行したい場合は、functionノードにNotifyのコードを書くとよいでしょう。
（下はNode-RED起動後、30秒後に開始したい場合です）

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353289/24d9fcbd-cf2f-9d0a-6730-1ee2704a06b6.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353289/7bd304e1-3dea-2f4f-b815-8643d2a00301.png)

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353289/5f8d3fc0-ccb8-8d7a-7911-580932ac64a4.png)