OmniAICreator/Qiita-1.07M huggingface dataset:
どうやら本番サーバー上でsidekiqをサービスで動かすと環境変数が別物のようだ


# 概要
AWSのEC2上でsidekiqをsystemdでサービス化して起動していたところ、通したはずのPythonコマンド用の環境変数のPATHが効かない現象が起きたので調査した。

# 調査
コード中のいろんな箇所にwhoamiや環境変数を確かめるコマンドを差し込んだりした結果、
sidekiqのジョブとPOSTリクエストを受けているcontrollerで実行しているユーザが違うことからsidekiqをサービス起動する設定が怪しいことに気がついた。

ちなみにRspecやローカル環境は実行ユーザーに環境変数が効いていたからなのかsidekiqで失敗するジョブもオールグリーンだった。

<strong>ところでSystemdってなに？</strong>
ってぐぐってみたらこの記事が参考になった。
> これからSystemd入門する
> https://qiita.com/bluesDD/items/eaf14408d635ffd55a18


# 対処法
systemdのsidekiq.serviceファイルの設定を書き換えることにした。

## systemdのsidekiq.serviceファイル
環境変数を読みこむシェルスクリプトを実行するようにExecStartPreを追記。

```config:/etc/systemd/system/sidekiq.service
[Unit]
Description=sidekiq
After=syslog.target network.target

[Service]
WorkingDirectory=/var/www/hoge-app
ExecStartPre=/bin/sh /var/www/hoge-app/aws/service/sidekiq_exec_start.sh
ExecStart=/root/.rbenv/bin/rbenv exec bundle exec sidekiq -e production

・・・(中略)・・・

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

## ExecStartPreで実行するシェルスクリプト 
sourceで.bash_profile読んだり、exportでなど何らかの形で環境変数を設定した後、systemctlのset-environmentでsystemdでも同じ環境変数を使えるようにする。

```sh:/var/www/hoge-app/aws/service/sidekiq_exec_start.sh
source /home/ec2-user/.bash_profile

# systemdにも環境変数を適用
/bin/systemctl set-environment PYENV_ROOT="$PYENV_ROOT"
/bin/systemctl set-environment PATH="$PATH"

# Python関連の設定処理
pyenv global 3.8.3
eval "$(pyenv init -)"

# この時点で設定されている環境変数を任意のログファイルに書き出す。(デバッグ用)
LOGFILE=/var/www/hoge-app/log/production.log
echo "Sidekiq Service Exec Start Pre --------" >> $LOGFILE
echo "$PYENV_ROOT" >> $LOGFILE
echo "$PATH" >> $LOGFILE
python -V >> $LOGFILE
whoami >> $LOGFILE
echo "-------------------------------------" >> $LOGFILE
```


サービス再起動

```
systemctl daemon-reload 
systemctl restart sidekiq.service
```

サービスのステータスがactiveかつ、ProcessのExecStartPreの記載が設定と一致していれば設定は成功。
後は実際にアプリケーションを動作させて確認。

```
[root@ip-＊-＊-＊-＊ hoge-app]# systemctl status sidekiq.service
● sidekiq.service - sidekiq
   Loaded: loaded (/etc/systemd/system/sidekiq.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2020-10-31 18:28:39 JST; 3s ago
  Process: 7130 ExecStartPre=/bin/sh /var/www/hoge-app/aws/service/sidekiq_exec_start.sh (code=exited, status=0/SUCCESS)
 Main PID: 7731 (bundle)
   CGroup: /system.slice/sidekiq.service
           └─7731 sidekiq 6.1.1 hoge-app [0 of 1 busy]
```
[laravel]formでpost以外を指定する方法

#formでpost以外を指定したいときはこんな感じになる
```php5:create.php
<form action="{{route('post.update',['post'=>$post->id])}}" method="post">
　　//↓これ
    @method=('put');　
    @csrf
    <label for="title">タイトル</label>
    <input type="text" id="title" name="title" value="$post->title">
    <input type="submit">
</form>

```
##余談
僕はもともこんな感じでinputに入れてたけど上のようなスマートな書き方がしれてよかった。
これからは上記の書き方をしたいと思います。

```php5:create.php
<form action="{{route('post.update',['post'=>$post->id])}}" method="post">
    <input type="hidden" name="_method" value="delete">
</form>
```
Docker Hubにpushしたらrequested access to the resource is deniedと出てしまった

# はじめに
普段あまり使わないDocker Hubを久々に使おうとしたところpushした際に
`denied: requested access to the resource is denied`と出てしまった。

# 対応

`docker build --tag`で指定していたユーザーIDの部分を自分のアカウントのものと同じにしることによってpush出来るようになる。

```
docker image tag 元のタグ名 dockerhub_userid/app:latest
```
これで自分はpush出来るようになりました。
data augmentation ツールについて調査中

機械学習をする上では、どれだけ、学習内容を安定なものにできるかが勝負どころだ。
そのための必要な条件としては、少々のデータの変動を加えても、画像の分類・検出に対する結果が変わるべきではないというこことだ。
　最近の機械学習の枠組みの中では、学習時にdata augmentation をする枠組みもある。
　たとえば、Kerasの場合だとImageDataGeneratorクラス　の中に、「リアルタイムにデータ拡張しながら，テンソル画像データのバッチを生成」する機能があります。
https://keras.io/ja/preprocessing/image/
　既存の物体検出フレームワークでも、バージョンの改訂で学習時のdata augmentation機能が強化されていることがあります。そのようなフレームワークに内蔵されたdata augmentation機能は、学習結果の性能を上げることにつながっているし、自前のdata augmentationを不要にするので、学習データの管理の対象の枚数を無駄に増やさないという点でもありがたいものです。

　最近では、機械学習を半教師付き学習で行いやすくするためにも、data augmentation が使われています。data augmentationで増やした学習ができるというだけではなく、学習時の損失関数の定義の中に、同一の画像に対するdata augmentation による画像とは同一の分類結果を与えるべきであるという損失関数が加わっているのです。

#### todo:

- 画像認識の機械学習プログラムの中で用意されているdata augmentation の範囲を確認すること　
- 機械学習する課題の中で使ってよいdata augmentation の範囲を確認する。
    - 学習したい課題によっては、色相を大幅に変えてはいけなかったりする。
- 
　ただ、そのような枠組みが全ての機械学習の枠組みに用意されているわけではない。だから、data augmentation ツールが役立つ。



https://takmin.hatenablog.com/entry/20141106/1415286867


TensorFlowのObject Detection APIのData Augmentationで何をやっているか動かして確認
https://qiita.com/karaage0703/items/cba4e6f284cc81070a45


https://github.com/srp-31/Data-Augmentation-for-Object-Detection-YOLO-

https://github.com/anhtuan85/Data-Augmentation-for-Object-Detection

https://github.com/albumentations-team/albumentations


---
https://demura.net/robot/athome/15558.html

次のリンクは、darknet の学習時のパラメータによって、どのように画像の見え方が変わるかを示している。

https://www.ccoderun.ca/darkmark/DataAugmentationColour.html
WordPressの.htaccessファイルをサブディレクトリにWPがインストールされている場合にスクリプトで対応させる方法

# はじめに
WordPressをサブディレクトリにインストールした場合、`.htaccess`ファイルをサブディレクトリに対応したものに修正する必要があります。


```conf:.htaccess
# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/subdir/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /path/to/subdir/index.php [L]
</IfModule>
```

この `.htaccess` ファイルをサブディレクトリ指定で動くように変換するためのスクリプト(`sed`)です。

```rewrite_htaccess.sh:bash
#!/usr/bin/env bash

# RewriteBase / ->  /path/to/subdir/
# DIR=/path/to/subdir/
DIR=${1:-/}
sed -i -e 's#^RewriteBase.*#RewriteBase '${DIR}'#' | \
  sed -i -e 's#^RewriteRule.*#RewriteRule . '${DIR}index.html' [L]#' 
```

このファイルを下記のように呼び出すと必要な部分が書き換わります。

```consle
$ ./rewrite_htaccess.sh /path/to/subdir > .htaccess
```


```conf:.htaccess
...
RewriteBase /path/to/subdir/
...
RewriteRule . /path/to/subdir/index.php [L]
```

# 困ったこと
WP-CLIや「設定>パーマリンク設定」から「更新」で、良い感じに`.htaccess`ファイルを書き出してくれていたと思ったのですが、サブディレクトリにうまく対応できませんでした。できた気がするんですが…。
第六章: 最後に

## 最後に
全ての章が終わりました。お疲れ様です。
余計なコストをかけない様に作ったサービスは全て削除しておくことをお勧めします。

* Elastic IPアドレスの関連付けの解除+解放
* Ec2のsnapshotを削除
* Ec2のボリュームを削除
* IAMを削除
* RDSのDBインスタンス終了
* RDSのスナップショットを削除
* ELBを終了
* ネットワークインターフェースを削除
* セキュリティーグループを削除
* CloudWatchのログを削除
* ルートテーブルを削除
* インターネットゲートウェイを削除
* サブネットを削除
* VPCを削除
* ACMを削除
* Route53のホストを削除


[前へ: 第五章: EC2からRDSに接続してみよう](https://qiita.com/Yuuki46240345/private/551539a3f1a037a75c37)
[最初へ: AWSのELBとEC2を使ってwebアーキテクチャを構築しよう](https://qiita.com/Yuuki46240345/private/0ee089a49325463cab5a)
第五章: EC2からRDSに接続してみよう

# EC2にmysqlをインストールしてRDS接続

### RDSのセキュリティーグループを作成
1. EC2のコンソールからセキュリティーグループタブに遷移して「セキュリティーグループの作成」
2. 下の画像の様に設定をしてください。セキュリティーグループ名**my-best-rds-sg**
![スクリーンショット 2020-10-16 8.26.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/c4f25191-37a9-a40d-ce82-12c38a2b85ed.png)
3. 入力が完了したら「セキュリティーグループを作成」

### RDSのサブネットグループを作成
1. AWSのコンソール画面でRDSを検索してRDSのコンソール画面に遷移
2. サブネットグループタブを選択して「DB サブネットグループを作成」を選択
3. 画像の様に設定してください。サブネットにいは２つのアベイラビリティーゾーンにまたがるサブネット**my-best-database-1a**,**my-best-database-2b**を選択します。
![screencapture-console-aws-amazon-rds-home-2020-10-16-08_52_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/b4d732b8-6412-c917-393b-4a6b56a4b23f.png)
4. 終了したら「作成」

### RDSを作成する
1. AWSのコンソール画面でRDSを検索してRDSのコンソール画面に遷移
2. ダッシュボードから「データベースの作成」を押す
3. 画像の様に入力します。重要な変更箇所を赤枠に囲いましたので変更してください
![screencapture-console-aws-amazon-rds-home-2020-10-16-09_01_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/d72ba942-23ad-9bdf-321e-8e7a41104cd9.png)

4. 入力したら「データベースの作成」
6. 「認証情報の詳細を表示」を開いてパスワードをメモしておいてください。パスワードはここでしかみれません
![スクリーンショット 2020-10-16 9.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/6c763f3c-d080-af42-4692-b656403e6cc9.png)
![スクリーンショット 2020-10-16 9.05.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/0c771187-4e2d-8b01-8024-62948c9ad5b7.png)

### EC2からRDSに接続する
1. RDSのコンソール画面から先ほど作成したRDSの**my-best-rds**を選択してエンドポイントをコピーします。
![スクリーンショット 2020-10-16 23.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/b97775d3-71ae-e778-9d82-71c8a2189a70.png)

1. EC2にsshで接続します
1. 接続したらmysqlをインストールします

```
$ sudo yum install mysql -y
```
４. EC2からRDSに接続できれば成功です。

ENDPOINT: 1でコピーしたエンドポイント
username: rdsのユーザ名(自分の場合だとadmin)
password: メモしておいたrdsのパスワード

```
$ mysql -h {ENDPOINT} -P 3306 -u {username} –p

エンターを押したらpasswordを打ち込みます
下の様になれば接続成功です。

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 
```

[前へ: 第四章: ELBとRoute53を使って独自ドメインををSSL化してHello worldを表示させよう](https://qiita.com/Yuuki46240345/private/a148b10db7bf1aa904ab)
[次へ: 第六章: 最後に](https://qiita.com/Yuuki46240345/private/5e2015277da0f6b2bd1f)
第二章: VPCやサブネット等の設定をしよう


今回の環境はリージョン: **バージニア北部**(us-east-1)で行います
### VPCの作成
Virtual Private Cloud (VPC)とは — AWS アカウント専用の仮想ネットワーク
今回は192.168.0.0/16で作成していく

1. awsのコンソール画面でVPCを選択
2. VPCのタブから「VPCの作成」ボタン押下
3. 名前・IPv4 CIDRブロック・タグを入力して[VPCの作成] を押す
![スクリーンショット 2020-10-15 21.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/112b0527-aa56-c463-343a-d78d90666a7a.png)

### Subnetの作成
VPCのIPアドレス範囲内のIPアドレスを使って作る必要があります。
アベイラビリティゾーンaとbにEC2用とRDS用の合計４つ作りましょう

**作成するサブネット**

| subnet | IPアドレス | アベイラビリティゾーン |
|:-----------:|:------------:|:------------:|
| my-best-application-1a | 192.168.1.0/24 | us-east-1a |
| my-best-database-1a | 192.168.2.0/24 | us-east-1a |
| my-best-application-2b | 192.168.3.0/24 | us-east-1b |
| my-best-database-2b | 192.168.4.0/24 | us-east-1b |

2. VPCのサブネットのタブから「サブネットの作成」ボタン押下
3. 上のサブネットを４つ作成作成する

### インターネットゲートウェイを作成する
先ほど作ったVPCをインターネットと紐づけるためにVPCにインターネットゲートウェイを紐づける必要があります。

2. VPCのインターネットゲートウェイのタブから「インターネットゲートウェイの作成」ボタン押下
3. 画像のように「my-best-internet-gateway」と記入して「インターネットゲートウェイの作成」
![スクリーンショット 2020-10-15 22.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/29be1507-57cb-b673-a8b4-6e5c827831fd.png)
1. インターネットゲートウェイをVPCにアタッチ
![スクリーンショット 2020-10-15 22.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/9e12362c-9cef-26f2-f86e-17893bce227b.png)


### ルートテーブルの作成
インターネットに公開するサブネットにルートテーブルを紐付けましょう

2. VPCのルートテーブルのタブから「ルートテーブルの作成」ボタン押下
3. 名前タグに「my-best-root-table」を入力して、先ほどのVPCを選択し、「作成」
4. 作成したら先ほど作ったルートテーブルを選択し「ルートの編集」を選択します
![スクリーンショット 2020-10-15 22.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/029cfa8d-5f48-754e-edb6-1f6b58c5bc62.png)
1. ルートの追加を押して、0.0.0.0/0のデフォルトゲートウェイに先ほどのインターネットゲートウェイを紐付けます。
![スクリーンショット 2020-10-15 22.14.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/3ed6e7f0-6885-6e0e-ce61-12e2618ec489.png)
1. 今度「サブネットの関連づけの編集」をクリックします
2. ここにec2を配置するサブネットである「my-best-application-1a」と「my-best-application-2b」を選択して「保存」

インターネットに公開するサブネットと公開しないサブネットにルーティングすることができました。
### セキュリティーグループの作成
ec2でどの通信をするかを決めるセキュリティーグループを設定します
今回はssh(port番号:22)とhttp(port番号:80)の設定をしていきます。

1. VPCのセキュリティーグループのタブから「セキュリティーグループを作成」ボタン押下
1. 下の画像のように必要な項目を入力したら「セキュリティーグループを作成」ボタン押下
![スクリーンショット 2020-10-15 22.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/b7651931-f81b-3f5b-d457-b0ec54cd5615.png)

### IAMの設定をする
cloud watchにEC2サーバーのログを出力するようにIAMを設定しましょう

1. awsのコンソール画面で[IAM]を選択
2. ロールタブから「ロールの作成」を押下
3. 画像のように選択して、「次のステップ　アクセス権限」ボタンを押下
4. ポリシーのフィルターに「CloudWatchFullAccess」を入力し、出てきたポリシーを選択して「次のステップタグ」を選択
5. キーに「Name」値に「my-best-ec2-log」を選択して「次のステップ確認」を選択
6. 次の画面のロール名の箇所にも「my-best-ec2-log」を入力して「ロールの作成」して終了


[前へ: 第一章: ドメインを取得してRoute53に登録する](https://qiita.com/Yuuki46240345/private/7c332948fefa9f4130dc)
[次へ: 第三章: EC2とRoute53を使って独自ドメインでHello world!を表示させよう](https://qiita.com/Yuuki46240345/private/c79c5a1f505d1f0eb50a)
AWSのELBとEC2を使ってwebアーキテクチャを構築しよう

今回使う環境としてPCはmacを使います。windowsの方は適宜読み替えて読み進めてください。

# この記事のゴール
**以下の画像の様な基本的なwebアーキテクチャを設計すること**
![Untitled Diagram (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528444/95593a8f-64f2-b53b-8649-625323628499.png)

[第一章: ドメインを取得してRoute53に登録する](https://qiita.com/Yuuki46240345/private/7c332948fefa9f4130dc)
[第二章: VPCやサブネット等の設定をしよう](https://qiita.com/Yuuki46240345/private/e7631c3172ffba52ede6)
[第三章: EC2とRoute53を使って独自ドメインでHello world!を表示させよう](https://qiita.com/Yuuki46240345/private/c79c5a1f505d1f0eb50a)
[第四章: ELBとRoute53を使って独自ドメインををSSL化してHello worldを表示させよう](https://qiita.com/Yuuki46240345/private/a148b10db7bf1aa904ab)
[第五章: EC2からRDSに接続してみよう](https://qiita.com/Yuuki46240345/private/551539a3f1a037a75c37)
[第六章: 最後に](https://qiita.com/Yuuki46240345/private/5e2015277da0f6b2bd1f)

[参考URL](https://employment.en-japan.com/engineerhub/entry/2018/12/21/130000#%E5%AE%9F%E4%BE%8B%E3%81%AB%E5%AD%A6%E3%81%B6Web%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9)
RailsにBootstrapを導入する方法

#RubyにBootstrapを導入する方法
##手順
* Bootstrapのインストール
* SCSSファイルの作成
* JSファイルの修正
* Rails（Puma）の再起動
## Bootstrapをgemでインストール

```java:Gemfile
gem 'bootstrap', '~> 4.3.1'
gem 'jquery-rails'
```
```java:ターミナル
bundle install
```
##SCSSファイルを作成
```java:ターミナル
mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
```
```java:app/assets/stylesheets/application.scss
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .    ＜（削除）
 *= require_self      ＜（削除）
 */
@import "bootstrap";  ＜（追加）
```
##JSファイルを修正
```java:app/assets/javascripts/application.js
# 以下の３つを追記
//= require jquery3
//= require popper
//= require bootstrap

# 元々のコード
//= require rails-ujs
//= require activestorage
//= require turbolinks
```
##Rails（Puma）を再起動
```java:Dockerfile
# Railsに必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y nodejs
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
    && apt-get install -y nodejs

# 以下の公式サイトの記述では、node.jsのバージョンが低くてbootstrapが使えない
# RUN apt-get update -qq && apt-get install -y nodejs
```
##Bootstrapの使い方（テンプレート）
```java:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
      <h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5>
      <nav class="my-2 my-md-0 mr-md-3">
        <a class="p-2 text-dark" href="#">Features</a>
        <a class="p-2 text-dark" href="#">Enterprise</a>
        <a class="p-2 text-dark" href="#">Support</a>
        <a class="p-2 text-dark" href="#">Pricing</a>
      </nav>
      <a class="btn btn-outline-primary" href="#">Sign up</a>
    </div>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>
```
#こうなる！
![e8cf55d4ebff169216236d8d3dfac518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/94eab6fa-6490-153d-7702-9e18fa720caf.png)

##現場からは以上です！
[Rust] lettreで日本語メールを送るときの注意点

lettreで日本語メールを構築するとき、以下のように書くと思います。

```rs
use lettre_email::{Email, EmailBuilder};

fn build_email() -> EmailBuilder {
  EmailBuilder::new()
    .from(("hoge@example.com", "ほげ"))
    .to("fuga@example.com")
    .subject("テストメール")
    .text("テスト")
    .build().unwrap()
}
```

しかし、このように書いた場合、**不正なメールが生成されます**。

```
Subject: テストメール
To: <fuga@example.com>
From: "ほげ" <hoge@example.com>
...

テストメール
```

一見問題なさそうですが、実はこのメール、ヘッダに問題があります。
というのも、本来メールヘッダには**ASCII文字以外が勝手に出現してはならない**のです。

UTF-8文字などをヘッダに使いたい場合、正常なクライアントならば以下のようにMIMEエンコードを行います。

```
Subject: =?UTF-8?B?44OG44K544OI?=
```

これは公式に定められたエンコード方式で、Base64で文字列をエンコードしています。

## 自前でエンコードしてみる

lettreに修正を依頼するより自分で直すが早そうな気がするので適当に書いてみます。

```rs
// 別途base64クレートが必要

use lettre_email::{Email, EmailBuilder};

fn mime_encode(txt: &str) -> String {
  format!("=?UTF-8?B?{}?=", base64::encode(txt.as_bytes()))
}

fn build_email() -> Email {
  EmailBuilder::new()
    .from(("hoge@example.com", mime_encode("ほげ")))
    .to("fuga@example.com")
    .subject(mime_encode("テストメール"))
    .text("テスト")
}
```

lettre自体が単に与えられた文字列を埋め込んでるだけっぽかったのでうまく動いたみたいです。
とりあえずはこれで良しとしましょう。

## 気づいたきっかけ

DKIMありのメールサーバーでメールを送信したときになぜかlettreから送ったときだけ検証が失敗するのでおかしいとなり、
通常のメールクライアントの出力と比較したところこの点に気づきました。
ActiveRecord::PendingMigrationError解決方法

・実行中の作業
Railsでブラウザにアクセスしトップページを表示
・問題点
トップページ表示中にActiveRecord::PendingMigrationErrorと言われる


#**PendingMigrationError**
以下エラー内容

```ruby:エラー
      # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
      def check_pending!(connection = Base.connection)
        raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
      end

      def load_schema_if_pending!
```

トップページの表示のみなので必要ないかと判断していましたが
きちんとMigrationしてください、とあります。

#rails db:migrateを実行する

```ruby:migrate
rails db:migrate
== 20201016135035 Createディレクトリ名: migrating ===================================
-- create_table(:ディレクトリ名)
   -> 0.0111s
== 20201016135035 Createディレクトリ名: migrated (0.0112s) ==========================
```

以上でマイグレーションが実行済み

#rails sを実行し確認
エラー解決できました。

#まとめ
今回は初歩的なミスですがトップページの表示のみを行いたかったのですが、マイグレーションで引っかかるのは想定外でした。
yukicoder contest 270 (mathematics contest) 参戦記

# yukicoder contest 270 (mathematics contest) 参戦記

mathematics という文字列を見ただけでやる気が無くなるのはなぜだろうか. そしてまた鯖落ち.

## [A 1256 連続整数列](https://yukicoder.me/problems/no/1256)

長さ3の連続整数列を考える. 0+1+2=3 で、これに +3n できるので、3の倍数なら何でも生成できる. 同様の長さ4の整数列は4n+2、長さ5の整数列は5nが、長さ6の整数列は6n+3が生成できることが分かる. これをまとめると長さnの整数列は、nが奇数の場合にはnの倍数が、nが偶数のときにはnの倍数+(n/2)が生成できることが分かる.

つまりAが偶数の場合には長さ2Aの連続整数列で必ず生成できる. Aが奇数の場合には長さAもしくは長さ2Aの連続整数列で必ず生成できる. ところで問題の制約により長さ1, 2の連続整数列は使えないので、1だけが生成できない整数になる.

```python
A = int(input())

if A == 1:
    print('NO')
else:
    print('YES')
```

## [B 1257 変わった平均値](https://yukicoder.me/problems/no/1257)

操作1を1回だけやると整数ではなくなって絶対に一致しない. かといって2回やるともとの値に戻る. となると使える操作は実質2だけになるので、A, B, C と D, E, F の構成する整数が順序を変えただけなら、'Yes' で1回だけ操作2をしてやればよく、そうでないなら 'No' となる.

```python
A, B, C = map(int, input().split())
D, E, F = map(int, input().split())

if sorted([A, B, C]) == sorted([D, E, F]):
    print('Yes')
    print(2)
else:
    print('No')
```

## [C 1258 コインゲーム](https://yukicoder.me/problems/no/1258)

求めるものは X = 0 のとき <sub>N</sub>C<sub>0</sub>M<sup>0</sup>+<sub>N</sub>C<sub>2</sub>M<sup>2</sup>+... となり、X = 1 のときは <sub>N</sub>C<sub>1</sub>M<sup>1</sup>+<sub>N</sub>C<sub>3</sub>M<sup>3</sup>+... となる. ところで (M+1)<sup>N</sup>=<sub>N</sub>C<sub>N</sub>M<sup>N</sup>+<sub>N</sub>C<sub>N-1</sub>M<sup>N-1</sup>+...+<sub>N</sub>C<sub>0</sub>M<sup>0</sup> であり (M-1)<sup>N</sup>=<sub>N</sub>C<sub>N</sub>M<sup>N</sup>-<sub>N</sub>C<sub>N-1</sub>M<sup>N-1</sup>+... なことから (M+1)<sup>N</sup> と (M-1)<sup>N</sup> から求めるものは計算できる.

```python
from sys import stdin

readline = stdin.readline
m = 1000000007

S = int(readline())
div2 = pow(2, m - 2, m)
for _ in range(S):
    N, M, X = map(int, readline().split())
    a = pow(M + 1, N, m)
    b = pow(M - 1, N, m)
    if (N + X) % 2 == 0:
        print((a + b) * div2 % m)
    else:
        print((a - b) * div2 % m)
```
(1)イントロ - JS Algorithms and Data Structures Masterclass

個人メモです。

Udemyの「[JavaScript Algorithms and Data Structures Masterclass](https://www.udemy.com/course/js-algorithms-and-data-structures-masterclass/)」コースの勉強。

プログラミング関連英語の学習も兼ねて。
まずはイントロパートなので英単語メイン。chromeのsourceのsippets機能は便利そう。


<br>
##英単語
・divide and conquer:分割統治法。難しい問題を小さく区切って解を求め、統合して全体の解を求める手法。

・sliding window: スライディングウィンドウ。高速化のためのアルゴリズム。一定要領の枠を設け、枠に空きがあるかぎりデータを処理し続ける

・recursion: 再帰法。関数の中で自身の関数を呼び出す。returnで関数を終了する処理を入れておく。

・binary search:二分探索。指定したデータを検索する手法の一つ。真ん中のデータを基準として、その数値より大きい小さいを判断。該当しない方をバッサリ切り捨てる。この検索範囲を絞る作業を繰り返し、目当てのデータを探し求める手法。

・bubble sort: バブルソート。後ろから隣り合う二つの要素の大小を比較して並べ替えていくソート

・selection sort:選択ソート。最少値を見つけて最初の値と交換していくソート。

・insertion sort: 挿入ソート。整列済みの配列を作り、未整列の配列の先頭を１つ追加して、大小を比較し、適切ないちに挿入していくソート。

・merge sort:２分割を繰り返し最少単位にした後に大小比較し並べ替えしてマージするのを繰り返す。

・radix sort:[基数ソート](https://algoful.com/Archive/Algorithm/RadixSort)。バケットソートの改良版。桁数ごとにソートを繰り返す。１桁目でソート、２桁目でソート、、、

・stepping stone: 踏み台

・singly linked lists: 片方向リスト。データを一方向に連結する。

・double linked lists: 双方向リスト。データを前後双方向に連結する。

・Qs：キュー

・hone: 磨きをかける。研ぎ石で研ぐのが元の意味。

・tree traversal: 探索木。特定のキーを探索する方法。二分探索木や三分探索木がある。

・breath first search: 幅優先探索。探索アルゴリズムの一つ。

・depth first search: 深さ優先探索。探索アルゴリズムの一つ。

・binary heaps: 二分ヒープ。データ構造の一種。

・hash tables: ハッシュテーブル。キーと値でデータを管理する方法。jsのオブジェクト。key-valueデータ構造。

・routing: 発音はラウティング。ルーティングは日本語発音。

・pinnacle: とんがった先端。

・second consideration: ２番目に考慮すること。必須ではないがやっとくと便利。

・O notation: O表記法。コードの能力や効率を表す。かなり重要な概念。

・chrome developer tool source snippets:クロームのソースの中のスニペット機能。任意のコードを保存し、好きな時に実行できる。デバッグなどに使える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/aecd5189-2c72-6e77-cef1-9f187c3d06de.png)

・welcome back:おかえり
　┗ コース冒頭でいきなり。
　　他の関連コースが以前にあったことを想定？

・curriculum:発音の場所はリが強い。kəríkjʊləm

・walk thorugh:　一通り説明する

・linear: 発音はラニヤー。コースが順番に並んでるかどうか。ライナーは日本語読み。

・prerequisites:事前に必要なもの。pre+requisite

・nice and short: いい感じで短い

・confront: （意識的に）立ち向かう。encountは偶発的。

・in tandem:二人で。gose in tandem。スピーカーと協力して２人で学んでいく的な。 


・archetypes: 原型。
androidのアプリリンクで開く時にプロセスが２つ立ち上がったりジャンプ元のアプリ内で開く時の対処法

## はじめに
アプリリンク(iOSでいうところのユニバーサルリンク)を導入すると、リンクを開く時に指定したアプリで開くことができるため、ユーザーに「どのアプリで開くのか」を選択してもらう必要がなくなりUXの向上になります。

しかし、androidではデフォルトの設定だと、アプリリンクを踏んだ時の動きがおかしくなります。
アプリリンクを踏むアプリをA、アプリリンクで開きたいアプリををアプリBとした時の理想の動きとしては

> 
- アプリBがバックグラウンドにいる
  - アプリAでアプリリンクを踏むとアプリBに遷移する
- アプリBがkill状態
  - アプリAでアプリリンクを踏むとアプリBが起動して遷移する

ですが、androidのデフォルトの設定だと

>
- アプリBがバックグラウンドにいる
  - アプリAでアプリリンクを踏むとアプリAのなかでアプリBが開いているパターン
  - アプリAでアプリリンクを踏むと、アプリBがもう１つ開かれて遷移するパターン
- アプリBがkill状態
  - アプリAでアプリリンクを踏むとアプリAのなかでアプリBが開いているパターン

といった現象が発生します。起動しているアプリ一覧を見ると、同じアプリが複数立ち上がっているような状況で明らかに異常な状態です。



## 原因
androidManifest内でlaunchModeを設定していないため、デフォルトの`standard`が適用されてしまっているから

## 対応
AndroidManifestのactivity内にlaunchMode="singleTask"を追加する

例

~~~xml
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustPan"
        android:screenOrientation="portrait"
        android:launchMode="singleTask">
~~~

## launchModeについて
launchModeには４つある。
standard、singleTop、singleTask、singleInstance

#### standard
> デフォルトの設定です。システムは常に、ターゲット タスク内でアクティビティの新しいインスタンスを作成し、そのインスタンスにインテントを渡します。

つまりジャンプ元のアプリの中で、アプリリンクで開きたいアプリを展開される。（タイトルの不具合）


#### singleTop
> アクティビティのインスタンスがターゲット タスクの一番上に既に存在する場合は、システムはアクティビティの新しいインスタンスを作成せずに、onNewIntent() メソッドを呼び出して、インテントをそのインスタンスに渡します。

アプリリンクでアプリを開く時、
- すでにアプリが開いている時は、そのままジャンプする
- アプリが開いていない時は、ジャンプ元のアプリの中で開きたいアプリが展開される


#### singleTask
> システムは新しいタスクのルートでアクティビティを作成し、そのアクティビティにインテントを渡します。ただし、アクティビティのインスタンスが既に存在する場合は、システムは新しいインスタンスを作成せずに、onNewIntent() メソッドを呼び出して、インテントを既存のインスタンスに渡します。

アプリリンク でアプリを開く時、

- すでにアプリが開いている時は、そのままジャンプする
- アプリが開いていない時は、新たにアプリを開いてジャンプする


#### singleInstance
> インスタンスを保持しているタスクでシステムが他のアクティビティを起動しないことを除いて "singleTask" と同じです。アクティビティは常に、そのタスクの唯一のメンバーです。

singleTaskと同じ？要動作確認



## 備考
公式では`singleTask`と`singleInstance`は推奨されていません。
しかし、同じアプリリンクでジャンプできるgoogle play storeの動きを見ると明らかに`singleTask`の動きであるため、アプリリンクを使う時はこのオプションは必須と考えても良いのではないでしょうか。


## 参考
https://developer.android.com/guide/topics/manifest/activity-element.html
【Rails物語】デメテルの法則〜知りすぎてはいけない〜

###概要
とある街に駆け出しのエンジニアのY君がいました

彼にとってプログラミングは難しいものでした

しかし彼はつよつよエンジニアになりたいと願い、数ヶ月前から毎日プログラミングの勉強をしてました

そんなある日、彼はより実践的な経験値を得るため共同開発チームに入るのでした

与えられたミッション（タスク）をこなし報告（プルリク）を出した時、それは起こりました、、、

###デメテルの怒り

Y君はこんなコードを書いていました


```erb
<%= "#{message.user.name}さん : " %>
<!-- messageの中身はこんな感じ{"user_id"=>1, "content"=>"やっほー"} -->
```

、、、これがデメテルの怒りに触れてしまったのです。

デメテル「知りすぎじゃーーーーーー！！」

デメテル曰く、プログラミングの世界では「知りすぎている」のは罪なのです

この場合`message`は`user_id`は知っていて紐づいている。だけど`user`自体の事は知らないし、その`name`なんて事は知らないはずなのです

ギャングがボスの存在は知っていても本当の名前を知ってはならないように、、、（ディア○ロ思考）

これをデメテルの法則と言います

>参考
https://qiita.com/br_branch/items/37cf71dd5865cae21401

Y君は絶望の淵に立たされました

###賢者の救援

どうすれば良いのかわからず途方にくれていたY君

そこへ仲間の賢者（つよつよエンジニア）がやってきてこう言いました（レビュー）

賢者「delegate使えばええんやで、ｽｯ」

>参考
https://qiita.com/TT-nasu/items/13fb0617435a960407ec

Y君「！！」

###必殺delegate

delegateマクロを使うとメソッドを簡単に委譲できる

Y君は上記記事を参考に下記のようにコードを書き加えました

```rb
class User < ApplicationRecord  
  has_many :messages
  
  def user_name
    "#{name}さん : "
  end
end

class Message < ApplicationRecord
  belongs_to :user

  delegate :user_name, to: :user
end
```
すると先ほどのデメテルぷんぷんコードはこうなりました、、、

```erb
<%= message.user_name %>
```

これを見たデメテルは「まぁよかろう」とだけ言って去って行きました

罪の晴れたY君は、デメテルの法則を肝に命じて、新たな開発を進めていくのでした。

*この物語は半フィクションです、あと本当にこれでデメテルの法則を守れてるのか微妙かもです、この方がいいよというやり方あったら是非教えてください！*
Backlogのお知らせが増えたらデスクトップ通知を行う（API）

Backlogを使っていて
どうしても通知に気付き辛く
見逃してしまう事があります。

課題一覧から未対応だけ見るのもありですが
自身がお知らせ対象に入ったらすぐに気付きたい
そんな方にオススメのAPIを活用した
「デスクトップに通知」方法を紹介します。

![osirase-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/ef58a6aa-40f9-e341-51a7-b6b1881c1d0b.png)


##情報取得と通知の概要

___①APIでお知らせの数を取得___
___②サイト監視ツールで見張って自動通知___

##APIキー設定方法と情報取得方法

個人APIキーの発行：
　Backlog→個人設定（顔アイコンから）→API
　メモには「お知らせ情報取得」などと記載
　
___このキーを使ってBacklogのAPI利用___

http～始まるURLはこういったものになります
https://★★.backlog.jp/api/v2/notifications/count?apiKey=XXXXXXXXX

★★：利用するbacklogアカウントに合わせてください。
XXXXXX：取得したAPIキーを入れてください

下記のような表示されれば成功です。
![api-count.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/ec0d35b7-cc23-44b8-3878-c273abf0fa8e.png)


ちなみに
backlog//api/v2/notifications?apiKey=XXXXXX
でお知らせ一覧を取得できます。

Backlog　API一覧についてはこちら
https://developer.nulab.com/docs/backlog/#


##オススメ監視ツール

Distill Web Monitor（Chrome拡張機能）
https://chrome.google.com/webstore/detail/distill-web-monitor/inlikjemeeknofckkjolnjbpehgadgge

こちらは指定したURLを定期的にチェックし、
その変化を検知したらデスクトップ通知などが
行えるChroe拡張機能です。

##最後に
毎日見に行くのではなく、必要な時にだけアクセスしたく
そしてなるべく早く気付きたいので考えました。
（普段あまりお知らせが多くない人向けです）

ただ、
Backlogについてはリアルタイム性を求めるツールでは
無いので、本来急務ならSlackなどを使えばよいと思いますｗ

効率化などにご活用いただければ幸いです。
でも将来的にはデフォルト機能であるかもですね。
ChromeでPDFを見開き表示する方法

#ChromeでPDFを見開き表示する方法 
備忘録として置いておきます。
86にアップデートされてから、

```
#pdf-two-up-view
```
が使えなくなってしまったので対応版です。

いつものようにアドレスバーに以下を入力。

```
chrome://flags/#pdf-viewer-update
```

![スクリーンショット 2020-10-16 23.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649817/e740749b-fb6d-0243-27b0-88ba54dffd7a.png)
PDF Viewer Updateがハイライトされるので
![スクリーンショット 2020-10-16 23.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649817/9fec1f90-1a5a-3832-6d2f-97a5ac3eb9bd.png)
Enabledに変更し、一番下に出る
"Your changes will take effect the next time you relaunch Google Chrome."
の横のRelaunchでChromeを再起動します。
![スクリーンショット 2020-10-16 23.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649817/13547c9d-6068-a32f-511e-a0dec80768db.png)

あとはお好きなPDFをChromeで開き、
![スクリーンショット 2020-10-16 23.28.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649817/e805d3df-471e-9477-f187-c164024eee52.png)
画面右上の縦の3点リーダーをクリックし「２ページ表示」にチェックして完了です！
![スクリーンショット 2020-10-16 23.32.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649817/5d055cdf-5e7b-5d79-710e-9094d996d72a.png)


ちなみにアノテーションは注釈のことです。
LambdaでLaravelのコマンドを定期実行する

Laravelで書いたバッチを実行するにあたって、EC2インスタンスだと実行タイミング以外もコストがかかるし、ECSタスクだとコンテナの管理がちょっと面倒。Lambdaで動かせればメンテも楽だし安く上がりそうなのでやってみた。

## 前提

brefphp を導入済の環境。

実行するのは Laravel で作成済みのコマンド、```croncmd:exec```。通常は ```php artisan croncmd:exec```で実行。

brefphp の導入については　[brefphpを使って簡単にLaravelをサーバレス環境で動かす - Qiita](https://qiita.com/YuK1Game/items/ff7744478339c09151d5) がとてもわかりやすいです。

## serverless.yml

今回は ```serverles.yml``` の設定のみです。例として月曜から金曜まで 09:00-17:00まで５分ごとに定期実行する設定を記載します。

input 部分で実行するコマンドを、rate で実行タイミングを指定します。時間についてはGMTで設定することに注意してください。


```yml
service: test-app

provider:
    name: aws
    region: ap-northeast-1
    runtime: provided

plugins:
    - ./vendor/bref/bref

functions:
    artisan:
        handler: artisan
        timeout: 120 # in seconds
        layers:
            - ${bref:layer.php-73}
            - ${bref:layer.console}
        events:
          - schedule:
              rate: cron(0/5 0-8 ? * MON-FRI *) # GMT
              input: '"croncmd:exec"'

```
配列内スペースを余分にとってソースの見栄えをよくする

PHPを使っているとよく配列を使うのですが、keyと要素を揃えて書くのが好きです。

人により好みが分かれるところだと思いますが私の場合以下の二つであれば下の書き方(sample2.php)を好みます。


```sample1.php
$input = array
(
    "id" => 1,
    "name" => "sato",
    "postal_code" => "000-0000",
    "address" => "Tokyo",
    "phone_number" => "09012345678"
);
```



```sample2.php
$input = array
(
    "id"           => 1,
    "name"         => "sato",
    "postal_code"  => "000-0000",
    "address"      => "Tokyo",
    "phone_number" => "09012345678"  // 揃っていて見やすい！
);
```

しかし後から長い要素が増えると全てをいちいち揃えることになってしまい面倒です。
そんな時はあらかじめスペースを余分に取っておくと楽かもしれません。

```sample2.php
$input = array
(
    "id"                 => 1,
    "name"               => "sato",
    "postal_code"        => "000-0000",
    "address"            => "Tokyo",
    "phone_number"       => "09012345678"
);
```

こうしておけば例え長い要素が増えたとしても対応できます。

```sample3.php
$input = array
(
    "id"                 => 1,
    "name"               => "sato",
    "postal_code"        => "000-0000",
    "address"            => "Tokyo",
    "phone_number"       => "09012345678",
    "Family structure"   => "single"   // 追加要素
);
```
大した話ではないですが、他人の書いたソースを見ていて自分なりにテンションが上がったので書いてみました。色々応用が効きそうです。
Chainerによる機械学習のためのPython学習メモ　8章 Numpy入門

#What
Chainerを利用して機械学習を学ぶにあたり、私自身が、気がついた点、リサーチした内容をまとめる記事になります。今回は、Numpyを勉強します。

私の理解に基づいて記述しているため、間違っている場合があります。間違いは都度修正するつもりです、ご容赦ください。

#Content

###Numpyとは
回帰分析を取り扱うアルゴリズム、多次元配列を便利に扱えるライブラリ？

###Pythonプログラムへのモジュール読み込み
```py
import numpy as np
```
テキスト読んでて、ライブラリとモジュールの違いが分からなくなったので調べてみました。下記参考記事
https://qiita.com/yutaro50/items/f93893a2d7b23cb05461
テンソルはarrayで扱う。

### テンソルの取り扱い方法

```py
 a = np.array([1, 2, 3])　#Numpy形式の行列を定義
 a.shape => #形をタプルで出力
 a.rank => #ランクを出力
 a.size =>#サイズを出力　データ個数
 a.ndim =>  # lenを出力
 a = np.zeros((3, 3)) => #3x3の零行列
 a = np.ones((2, 3)) => #2x3の要素が全て１の行列
 a = np.full((3, 2), 9) => #3x2の要素が全て９の行列
 a = np.eye(5)          => #5x5の単位行列
 a = np.random.random((4, 5)) => #4x5で要素が0~1の乱数で決定された行列
 a = np.arange(3, 10, 1) => #3から１０まで１ずつ増える行ベクトル
 a = np[0,3] => #１行４列目をの値
 #↓この説明が理解できない><
 # 4 x 5 行列 e の真ん中の 2 x 3 = 6 個の値を取り出す
 center = e[1:3, 1:4]
 a[[0, 2, 1], [1, 1, 0]] => # (1, 2), (3, 2), (2, 1)の要素を行ベクトルで出力

```
そのほか四則演算もできる
行列形が違くても加減算ができる＝ブロードキャスト
逆に不本意な計算が発生する可能性がある。注意

行列積 ABの計算

```py
np.dot(A,B) or A.dot(B) # とかく
np.dot(X.T, X)          # 行列Xの転置行列とXの積を計算
np.linalg.inv(A)        # 行列Aの逆行列を計算 
```
交換法則は一般には成り立たないので順序に注意

行列の取り扱いに困ったときはここを見返そう

#Comment
内容が難しくなってきたので、更新頻度が落ちてしまっているが頑張ろう
phpMyAdminがやたらに遅い。

# phpMyAdminのテーブル一覧表示が遅い時に取った対応
phpMyAdmin(Ver.4.0.10.20)を業務上必要だったので、設定してみたのですがテーブル一覧表示がやたらに遅い。。。テーブル一覧表示がされるまでに3分近くかかる。いつもかかる。

## $cfg['MaxExactCount']と$cfg['MaxExactCountViews']の設定
いろいろ調べると、config.inc.phpの**$cfg['MaxExactCount']**と**$cfg['MaxExactCountViews']**の設定値を「0」にしてテーブル一覧表示のレコード数を正確に取らなければいいとの事。

``` php
$cfg['MaxExactCount']=0;
$cfg['MaxExactCountViews']=0;
```

設定してみました。でも、**全然変わりませんでした。**
いろいろ、config.inc.phpの設定を変えたり、ブラウザのcookieやキャッシュをクリアしたり、ブラウザを変えたりしたのですが、結果は変わりませんでした。
原因が特定できず、仕方なく、しばらくそのまま使っていきました。

## 原因が見つかった！（version_check.php、君でしたか。。）
我慢して使っていたのですが、2か月ぐらいたった時、**「もういい加減にしろー！！やってられん！！」**と切れ気味モードで原因調査を再び開始しました。

DBサーバへガリガリとリクエストを行っていないのは、特定済みだったので原因はWebサーバ側との推測で調査を行う。
apacheのアクセスログにリクエストを処理するのにかかった時間、マイクロ秒単位で出力(フォーマットに %Dを指定）しているのですが、よくよくログを確認すると、**version_check.php**が処理終了まで数分かかっていた。こいつが原因だったようです。

version_check.phpって何？必要なの？と、phpMyAdminのドキュメントを確認する。

https://docs.phpmyadmin.net/en/latest/config.html#cfg_VersionCheck

最新のバージョンをチェックするためのプログラムらしい。下記のように設定するとバージョンチェックしないようにできる。

```php
$cfg['VersionCheck']=false;
```

config.inc.phpに上記を記述したら、長時間待たされることは無くなりました。
動作環境がPHP 5.4までしか使えず、必然的にphpMyAdminも古いものしか利用できないため、その影響だったのかも知れません。

ようやく、ストレス無く使えるようになりました。やれやれです。
【図解】硬貨の和を再帰関数で求める【Ruby】

#はじめに
ProjectEulerのProbem31についてです。
再帰関数での他の人の解答を参考にして、再帰関数初心者が解説してみました。
下で[図解](#図解)もしているので、そちらもぜひ見てください。

（※追記）
また、他の方がコメント欄で別の解答を提示してくれています。
是非他にも解いた方いらっしゃいましたら教えてください。

#問題
>Problem 31 「硬貨の和」
イギリスでは硬貨はポンド£とペンスpがあり，一般的に流通している硬貨は以下の8種類である.
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
以下の方法で£2を作ることが可能である．
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
これらの硬貨を使って£2を作る方法は何通りあるか?

[日本語版](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2031)
[英語版公式](https://projecteuler.net/problem=31)

#方針
`coins = [1,2,5,10,20,50,100,200]`の中から任意の一枚ずつ取り出していく作業を、200になるまで繰り返す。
人間の手で行ってたらとてもじゃないけど、数えきれないのでこういう時は`「再帰関数」`!

####再帰関数とは？
`def ~ end`で定義した関数内で自分自身を呼び出す関数のことをいいます。
有名なものだとフィボナッチ関数などはよく再帰関数の入門として扱われたりします。
初めて聞いたよという方は検索してみてください。

別の解説記事：[【図解】階乗の再帰関数【Ruby】](https://qiita.com/u_nayama/items/5291ab090fb19bd145ed)

#解答
```ruby
def coin_count(coins, goal, last = 0)
  if goal == 0
    return 1
  end

  total = 0
  coins.each do |c|
    if c < last
      next
    end
    if goal >= c
      total += coin_count(coins, goal - c, c)
    end
  end

  total
end

coins = [1,2,5,10,20,50,100,200]
puts coin_count(coins,200)
```

恥ずかしながら自力では解けなかったので[こちら](http://joezack.com/2010/09/26/project-euler-problem-31-in-ruby/)を元に作成しました。
この解法を日本語で解説しようと思います。

#解説
今回作りたいのは`200`という数値。
そこで`goal = 200`と設定して、硬貨一つの値

まず関数内のeach文内から説明を始めます。

```ruby
if c < last
  next
end
```
これは直近で足した数`last`を超える数は足さないようにしています。
つまり、`50 + 50 + 100`と`50 + 100 + 50`は今回の問題では同じなので、昇順に足していくパターンのみを採用するようにしています。

[next](https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#next)はブロック内のnext以降の処理をスキップするという処理になります。

次に、再帰関数を用いている関数内の3つ目のif文内です。

```ruby
if goal >= c
  total += coin_count(coins, goal - c, c)
end
```
今回、`c`は`coins = [1,2,5,10,20,50,100,200]`の要素のいずれかなので`1 <= c`です。
ですので`coin_count(coins, goal, last)`の引数として渡される`goal`は`goal - c`で0に向かって減っていきます。

仮に`c = 50、 goal = 200`の時は下のようになります。

```
例）
再帰関数で goal - c が繰り返されていくと、引数の goal　は
1回目: 150     ※coin_count(coins, 150, 50)で呼び出し
2回目: 100     ※coin_count(coins, 100, 50)
3回目: 50      ※coin_count(coins, 50, 50)
4回目: 0       ※coin_count(coins, 0, 50)
```
4回目に`coin_count(coins, 0, 50)`で関数が呼び出されたとき、

```ruby
if goal == 0
  return 1
end
```
になるので、ここまできてようやく、

```ruby
total += coin_count(coins, goal - c, c)
```
の`coin_count関数`が`戻り値 1` を持つことになります。
そこででようやく`total += 1`となり、１プラスされます。

- `goal > 0`の時
- `goal < 0`の時

この場合は、`total = 0`が0のまま戻り値に渡されます。
最終的に組み合わせの総数がtotalの値として得られます。

#図解
この、関数が繰り返し呼び出されていく状態を図にしてみました。
![projecteuler31解説.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644441/47bd5384-c2ae-52de-0153-28373c9a138d.jpeg)

#終わりに
説明の足りない点や、間違っている点、よりわかりやすい説明があればどしどし教えてください。
読んでいただきありがとうございました。
【図解】階乗の再帰関数【Ruby】

#はじめに
自分が初めて再帰関数を知ったときに、理解するのに苦労しました。
その際に紙に書いたことで理解できたので、それを今回図解しました。

####再帰関数とは？
`def ~ end`で定義した関数内で自分自身を呼び出す関数のことをいいます。
有名なものだとフィボナッチ関数などがよく再帰関数の入門として扱われたりします。
初めて聞いた方は検索してみてください。

####階乗とは
>1からnまでの連続するn個の自然数の積をnの階乗という。
n!と書き、例えば4!＝1×2×3×4＝24と表す。
ただし、0の階乗は1とする。

引用元：[goo辞書](https://dictionary.goo.ne.jp/word/%E9%9A%8E%E4%B9%97/)

#再帰関数を用いたコード
```ruby
def factorial(num)
  if num == 1 || num == 0
    return 1
  end
  return num * factorial(num - 1)
end
```
※`num < 0`が渡されてしまった場合は今回は考慮していません。

非常にシンプルなコードですが、脳内で考えていると意外と混乱します。

#図解
![スクリーンショット 2020-10-16 22.45.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644441/c7cf2cfa-eff7-e41a-e178-feff6616f338.png)

#終わりに
まだまだ再帰関数初心者なので複雑なものは私もまだ混乱します。
ただ、今回図解したコードなどが基本になっていると思うので迷った時は初心に戻ろうと思います。

この記事がどなたかの再帰関数理解の一助になれば幸いです。
メモ：twitterで自分のアカウントのメディア削除を連続削除

# メモ
## twitterで自分のアカウントのメディアを連続で一気に削除する方法
※もしご利用される場合は自己責任でお願いします

1. MacのChromeで`https://twitter.com/スクリーンネーム/media`にアクセス
2. 右クリックメニューから検証
3. Consoleタブを開く
4. 以下のソースをコピーし、Console内にペーストする

```javascript
const process2 = function() {
    document.getElementsByClassName("css-1dbjc4n r-1loqt21 r-18u37iz r-1ny4l3l r-ymttw5 r-1yzf0co r-o7ynqc r-6416eg r-13qz1uu")[0].click();
    document.getElementsByClassName("css-901oao r-1awozwy r-jwli3a r-6koalj r-18u37iz r-16y2uox r-1tl8opc r-a023e6 r-b88u0q r-1777fci r-rjixqe r-bcqeeo r-q4m81j r-qvutc0")[0].click();

    process();
};

const process = function(){
    if (document.getElementsByClassName("css-18t94o4 css-1dbjc4n r-1777fci r-bt1l66 r-1ny4l3l r-bztko3 r-lrvibr").length == 0) {
        return;
    }

    document.getElementsByClassName("css-18t94o4 css-1dbjc4n r-1777fci r-bt1l66 r-1ny4l3l r-bztko3 r-lrvibr")[0].click();
    setTimeout(process2, 100)
};
process();
```

## twitterで自分のアカウントのツイートを連続で一気に削除する方法

```javascript
const rtProcess = function() {
    document.getElementsByClassName("css-1dbjc4n r-1loqt21 r-18u37iz r-1ny4l3l r-ymttw5 r-1yzf0co r-o7ynqc r-6416eg r-13qz1uu")[0].click();
    setTimeout(process, 300);
};

const process2 = function() {
    let menus = document.getElementsByClassName("css-1dbjc4n r-1loqt21 r-18u37iz r-1ny4l3l r-ymttw5 r-1yzf0co r-o7ynqc r-6416eg r-13qz1uu");
    if (menus.length == 5 || menus.length == 6) {
        // 閉じる
        document.getElementsByClassName("css-1dbjc4n r-1p0dtai r-1d2f490 r-1xcajam r-zchlnj r-ipm5af")[0].click();
        // RTメニュー開く
        document.getElementsByClassName("css-901oao r-1awozwy r-nw8l94 r-6koalj r-1qd0xha r-a023e6 r-16dba41 r-1h0z5md r-ad9z0x r-bcqeeo r-o7ynqc r-clp7b1 r-3s2u2q r-qvutc0")[0].click();
        setTimeout(rtProcess, 100)
        return;
    }

    menus[0].click();
    document.getElementsByClassName("css-18t94o4 css-1dbjc4n r-1dgebii r-42olwf r-sdzlij r-1phboty r-rs99b7 r-16y2uox r-1w2pmg r-ero68b r-1gg2371 r-1ny4l3l r-1fneopy r-o7ynqc r-6416eg r-lrvibr")[0].click();
    setTimeout(process, 100);
};

const process = function(){
    if (document.getElementsByClassName("css-18t94o4 css-1dbjc4n r-1777fci r-11cpok1 r-1ny4l3l r-bztko3 r-lrvibr").length == 0) {
        return;
    }

    document.getElementsByClassName("css-18t94o4 css-1dbjc4n r-1777fci r-11cpok1 r-1ny4l3l r-bztko3 r-lrvibr")[0].click();
    setTimeout(process2, 100)
};
process();


```
React NativeのWebViewの中のリンクをブラウザで開く

## はじめに
アプリを作っている時に、全てネイティブで作るのではなく、WebViewを使ってコンテンツを表示したい時があると思います。さらにWebViewの中のリンクを押すとそこからブラウザに飛んで欲しい場面がたまにあります。
例えば、アプリ内のお知らせをHTMLで作成しwebViewで読み込むアプリで、自社のキャンペーンの紹介をする時にHTMLのリンクからブラウザで自社サイトに飛んで欲しい時などです。

## やり方

1.LinkingとPlatformをインポートしておく

~~~javascript
import { Linking, Platform } from 'react-native'
~~~

2.WebViewのオプションを設定する

~~~javascript
onShouldStartLoadWithRequest={event => {
  const isExternalLink =
    Platform.OS === 'ios'
      ? event.navigationType === 'click'
      : true
  if (event.url !== 'about:blank' && isExternalLink) {
    Linking.openURL(event.url)
      return false
    }
  return true
}}
~~~

こうすることで、webView内のリンクを踏むとブラウザ開かれます。

---

- isExternalLinkについて

isEternalLinkの記述がなくてもリンクを踏むとちゃんとブラウザが開きますが、**iOSの場合webViewでページを開いた瞬間にLinkingが発火してブラウザに遷移してしまいます。**
そこで、iOSの時にはリンクをクリックした時にのみLinkingが発火するようにしています。

---

- return falseについて

なくてもリンクはブラウザで開きますが、アプリに戻ってきた時にwebViewの画面がリンク先のページになっているので、それを防いでいます。
Rust入門 初心者がYouTube生放送でWeb開発入門 1時間目, 2時間目

YouTubeの生放送でRustを勉強中なのですが、そこでRustを勉強してわかったことを書いていきます。
生放送2回で約2時間でやったことを書いてます。


放送アーカイブ↓　（2時間目のものになります。1時間目のものは個人情報など入ってしまったのでアーカイブなし）
[![maxresdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/0401a670-a768-64e2-caef-9c5d4b9fc548.jpeg)
](https://youtu.be/mfhJb15umYU)

## Rust のインストール方法

```bash
brew install rustup
```

これで Rust インストール完了。 `brew install rust` よりこちらのほうが良いみたい。

インストールされるこまんどは、 `rustup` , `rustc` , `cargo` などで `rust` コマンドはインストールされなかった。

ここで `Cargo` というのがパッケージマネージャーだと知る。

## 開発環境構築

JetBrains 系のIDEを使いたいので、 RustのプラグインをWebStormにいれた。

https://www.jetbrains.com/rust/

## 文法

とほほのWWW入門の Rust入門 のページがわかりやすい。

http://www.tohoho-web.com/ex/rust.html#cargo-project

ざーっと30分眺めるだけである程度頭に入るので、いきなりコードを書き出すよりは最初に30分程度だけでも読んでみるのがおすすめです。

## Webフレームワーク選定

文法を少し確認したら、次はフレームワーク選定をしました。
Rustの前情報一切なしなので、どんなフレームワークがあるか調べて、その後はGitHubのスター数で比較しました。

|フレームワーク名|スター数|
|:--|:--|
|Rocket|11.6k|
|Iron|5.8k|
|Nickel|2.8k|


## Rocketの公式ページでGet Startedをやってみる

わかりやすく記載されているのでスムーズに進行

https://rocket.rs/v0.4/guide/getting-started/

文法などわからない部分はスルーしていくのが初学ではおすすめです。
全部理解しようとするとすごく遅いので。

## Rocket で JSONを返す

なかなか GetStarted で JSON をレスポンスで返す方法が来なかったので検索

https://github.com/SergioBenitez/Rocket/tree/v0.4/examples/json

JSONがレスポンスで返せるようになって満足 :smile: 

## 次やりたいこと

JSONでの返し方がわかったところで2時間目終了。

ふんわり理解しながら新しい技術を身に着けていくと楽しいですね。


次回は、

- Rocket から Database アクセス
- Templateの使い方
- セッション
- フロントとつないでみる
    - Rust WebAssembly を調べる
    - Rust Kagura フレームワークを調べる（フロントエンドフレームワークらしい）

あたりをやっていきたいと思っています。

最終的には、新規登録、ログインのある何らかのアプリを作れると良いなと思ってます。

## 続き

[Rust入門 初心者がYouTube生放送でWeb開発 3時間目](https://qiita.com/yassun-youtube/items/1065598e0f5b76372f04)
https://qiita.com/yassun-youtube/items/1065598e0f5b76372f04
for-in文を理解しよう！

今回は、for-in文について学習したので、アウトプットしていきます
※以下の内容は、学習内容のアウトプット用のため、誤りがある場合があります。予めご了承ください

#for-in文とは？
***for-in文は各要素を実行文に順次渡しながら、その要素の数だけ繰り返しを行います。***

基本的な書き方は以下の通りです


```swift:qiita.rbvar 
for 要素名 in シーケンス { 
要素ごとに繰り返し実行される文
 }
```

※シーケンス・・・連続（しているもの）、一続き（のもの）、順序、順番、並び、配列（する）、逐次、並べる、順序付ける、などの意味を持つ。

次は簡単な例を見ていきましょう。

```swift:qiita.rbvar 
1.let array = [1,2,3]
2.for element in array {

print(element)
}
実行結果
1
2
3
```
上記の例では、配列array内の値に、定数elementを通じて１つずつアクセスしています。

Dictionary<key,Value>型の要素をfor-inで列挙する場合、要素の型は（key,value）型のタプルとなります。例えば、[String: Int]型の値を
for-in文に渡すと、要素は（String: Int）型となります。

簡単な例を見ていきましょう。

```swift:qiita.rbvar 
let dictionary = ["a": 1,"b": 2]

for (key,value) in dictionary {

print("key:\(key),Value\(value)")
}
実行結果
key: a Value: 1
key: b Value: 2
```

#break文
break文は、実行文を中断し、さらに、繰り返し文全体を終了します。例えば、これ以上繰り返しを行なう必要が奈君あた場合などに使用します。

簡単な例を見ていきましょう。

```swift:qiita.rbvar 
var containsThree = false
let array = [1,2,3,4,5]

for element in array {
if element == 3 {
  containsThree = true
  break
//3が見つかったら終了
}
print("element:\(containsTwo)")
}
print("containsTwo: \(containsTwo)")

実行結果
element: 3
containsTwo: true

```

上記の例では、配列の中に3が含まれているかを検査するプログラムです。
3が見つかった時点で後続の繰り返しを行なう必要はないので、break文を用いて繰り返し文を終了しています。


#continue文
continue文は、実行文を中断した後、後続の繰り返しを継続します。例えば、特定の場合だけ処理をスキップする場合などに使用します。

```swift:qiita.rbvar 
var adds = [Int]()
let array = [1,2,3,]

for element in array {
    if element % 2 == 1 {
    adds.append(element)
    continue
}
print("even: \(element)")

}

print("odds:\(adds)")

実行結果
even: 2
adds: [1,3]
```

上記の例では、break文とは異なり後続の繰り返しは継続され、全ての要素にたいして処理が行われていることがわかります。
ストアドで複数レコードを返却する

# はじめに
業務の中で、DBからテーブルに1時間毎に入っているレコードを10分刻みにして、結果を取得する処理を作成する機会があったので、誰かの参考になればと思います。


### 環境
・postgresql 9.6
・Windows 10

## PL/pgSQL
今回はpostgresqlなので、`PL/pgSQL`で作成します。

```sql
CREATE OR REPLACE FUNCTION test_function()
  RETURNS TABLE(
    id bigint,
    name varchar(20),
    age smallint
  ) AS $$

  DECLARE
    -- カーソル
    cur cursor for SELECT * FROM user;

  BEGIN
    FOR cur_rec IN cur
      LOOP
        id := cur_user.food_id;
        name := rec_user.food_name;
        age := rec_user.food_name;

        RETURN NEXT;
      END LOOP;
    RETURN;
  END;
$$ LANGUAGE plpgsql;
```

## 解説
`RETURNS TABLE`
上記を定義することで、テーブル構造の戻り値を指定することができる。

`RETURN NEXT`
RETURNS TABLEで宣言した変数にカーソルで取得した値を代入して、`RETURN NEXT`を呼ぶとその列を戻り値として返却することができる。実際にはループの中でデータを加工するなどの処理を行い、その結果をレコードとして返却できるため、非常便利です。

### 参考文献
[PostgreSQLのPL/pgSQLで複数行の戻り値を返す](http://eatsmart.hatenablog.com/entry/2019/03/01/155838)
Cannot find module 'firebase-admin' or its corresponding type declarations. 解決法

#久しぶりに`index.ts`を覗くと、、
個人開発のアプリで使ってるCloud Functionsにコードを加えようと、久しぶりに`index.ts`をエディタで開いてみた。

```typescript:functions/index.ts
import * as functions from 'firebase-functions'; // なぜかエラー発生！！
import * as admin from 'firebase-admin'; // なぜかエラー発生！！
admin.initializeApp();
const db = admin.firestore();
```
**Cannot find module 'firebase-functions' or its corresponding type declarations.**
**Cannot find module 'firebase-admin' or its corresponding type declarations.**

このような謎のエラーが発生していた。。
何もコードを変えていないので、環境系のエラーである事はわかる。

とりあえず`npm install`してみるも、解決しない・・・:expressionless:

#functionsフォルダの階層で`npm install`する必要があった！
さっきした`npm install`したのは、**アプリのプロジェクトの階層**

Cloud Functionsの実行環境を作った時（参考は[こちら](https://qiita.com/tdkn/items/2ed2b01f2656fc50da8c)）に作成された**functionsフォルダの階層**で`npm install`する必要があったようだ。

よくみるとfunctionsフォルダにも`package.json`や`node_modeules`といったフォルダ達が存在していた。



#参考
https://stackoverflow.com/questions/46822801/firebase-deploy-error-cannot-find-module-firebase-admin
民間企業の次期ネットワーク構想に向けて　第1話

#まえがき
今，常駐している契約先にお世話になって2年半が経ちました。
今年の春から色々提案してきた案件がどんどん大きくなり，来年度は大きなプロジェクトとして動くことになりました。
私のフリーランスSE人生の中でも一番大きく，一つの集大成となるプロジェクトです。
どんなきっかけで，どんな話の流れでこんな話になったのか。
現在進行形のプロジェクトですが，忘れないうちに思い出しながら振り返りの記事を書こうと思います。
常駐型フリーランスSEの経験談も交えて書いてみようと思います。
拙い文章ですが，最終的にはリアルタイムで進む記事になりそうなので，気軽にお読み頂けたら幸いです。
製品名はそのまま書きますが，登場する会社名などは可能な限りぼかして書きますのでご了承ください。

#え？いるの？
世間ではローカルブレイクアウトやゼロトラストなど次世代のネットワーク技術や構成がどんどん出てきます。
日々，ウチにもベンダーさんが様々な提案を持ってこられます。
※ウチ＝常駐先。名刺も常駐先のものを使うので対外的には常駐先の人間となります。
私はネットワークのスペシャリストではありませんが，業界もそこそこ長く，進化する技術の過程を見てきたので，提案内容がウチにどんなメリットがあるか，オーバースペックではないか，などを判断する事を求められる立場になってきました。
そんな中，昨年後半，ウチのIPS/IDS(オンプレ)が2021年秋に保守切れを迎えるので，リプレースをしなければならないからベンダーさんの提案を一緒に聞いてほしいと話がありました。
もちろん断る理由もなく，一緒に参加させて頂きましたが，びっくりするぐらい高く，まず，
　「え？いるの？」
という思いが真っ先に出てきました。
今導入しているのは「Proventia」でリプレースするにも後継機がなく，IBM社のSOCが要件となるならCisco社の機器になるとの説明でした。価格は，機器だけでも地を這うような高級外車と同等でした。
インターネット回線は本社からのみ接続されており，DMZのサーバも本社にオンプレで構築されているのでIPSもオンプレで導入しているとのことでした。
その他，FWもプロキシサーバも全てオンプレで構築されています。
IPS/IDSの金額にびっくりしつつも，年間どのぐらいのコストをかけているのか気になり，調査することにしました。

(次回：第2話)
　調査はしたけど急にコロナ！
Ansible 初心者がplaybook～roleを学ぶ ② Ansibleインストール

前回に引き続き、Ansible環境構築を本稿でも進めます。
前回作成したvm:ansibleにAnsibleをインストール、設定を進めていくのが主な目的になります。

os:centos7.2
ansible version (2.9.13) ※Mitogen for Ansibleを使いたいため､このversion
python version  (3.6.8) 　
※デフォルトでpython2.7.5が入っていますが、
　サポート終了しているということで、この手順ではpython3でのインストールにしました。

###０．tera-tarmで前回作成したvm:ansibleへssh接続する。
```
    IP address: 192.168.16.11
    ID: vagrant
    PW: vagrant
```
###１．pythno3のインストール
```    
    $ sudo yum update -y
    $ sudo yum install -y python36 python36-pip python36-devel
```
###２．pip3でAnsible install
```shell
$ sudo pip3 install --upgrade pip
$ sudo pip3 install ansible\==2.9.13
```
###５．ansibleバージョンを確認する。
```shell:
$  ansible --version
ansible 2.9.13
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```    
★python3でansibleが稼働していることが確認できたらOK.
####次回Link>>[Ansible 初心者がplaybook～roleを学ぶ ③ Ansible初期設定](https://qiita.com/showa-engine/items/bdfbe0c66054f85c9fe9)