OmniAICreator/Qiita-1.07M huggingface dataset:
ChainerでOctave Convolutionを実装してみた

# 動機
トレンドに上がっていた[Octave Convolution](https://qiita.com/koshian2/items/0e40a5930f1aa63a66b9)がなんだかよさそうだったのですが、Keras実装だったのでChainerしか知らない僕にはちょっと不便です。なので自分で実装してみることにしました。
「間違ってるよ」とか「ここはこう書くといいよ」的なアドバイスよろしくお願いします。

# 実装
```Python
from chainer import Chain
import chainer.functions as F
import chainer.links as L
import numpy as np


class OctConv(Chain):

    def __init__(self, in_ch, out_ch, ksize, stride, pad, alpha0=0.25, alpha1=0.25):
        super().__init__()
        with self.init_scope():
            self.h2h = L.Convolution2D(int(in_ch * (1 - alpha0)), int(out_ch * (1 - alpha1)), ksize, stride, pad)
            self.h2l = L.Convolution2D(int(in_ch * (1 - alpha0)), int(out_ch * alpha1), ksize, stride, pad)
            self.l2h = L.Convolution2D(int(in_ch * alpha0), int(out_ch * (1 - alpha1)), ksize, stride, pad)
            self.l2l = L.Convolution2D(int(in_ch * alpha0), int(out_ch * alpha1), ksize, stride, pad)

    def __call__(self, high, low):
        _, _, H, W = high.shape
        h2h = self.h2h(high)
        h2l = self.h2l(F.average_pooling_2d(high, ksize=2))
        l2h = F.unpooling_2d(self.l2h(low), ksize=2, outsize=(H, W))
        l2l = self.l2l(low)

        h = h2h + l2h
        l = h2l + l2l
        return h, l
```

まだこのコードで実験していないので、後で追記します。
CentOS7にComediをインストール

[RTAI-Lab tutorial: Scilab, Comedi, and real-time control](https://www.rtai.org/userfiles/downloads/RTAILAB/RTAI-Lab-tutorial.pdf)の「2.5 Comedilib」および、「2.8 Comedi」の内容です。

### 2.5 Comedilib
#### ソースの入手

チュートリアルに記載されているCVSのリポジトリは無くなっているみたい。
[公式ページ](https://www.comedi.org/)にあったGitを使う方法でソースを入手。

```
$ git clone https://github.com/Linux-Comedi/comedi.git
$ git clone https://github.com/Linux-Comedi/comedilib.git
```

#### ビルド

チュートリアルに従って、以下で特にトラブルなくビルド&インストール完了。

```
# cd comedilib/
# sh autogen.sh
# ./configure --sysconfdir=/etc
# make
# make install
# make dev
```

### 2.8 Comedi

#### ビルド

```
# cd ../comedi
# sh autogen.sh
# ./configure --with-linuxdir=/usr/src/linux --with-rtaidir=/usr/realtime
# make
# make install
# depmod -a
# make dev
```

`depmod -a`は、`make install`時に実施を促されたのでチュートリアルには記載されていなかったが実施。`make dev`すると`mknod: `/dev/comedi0': ファイルが存在します`などのメッセージがでますが、Comedilibインストール時に作成済みだったから出るメッセージで問題ないと判断。

```
# cp include/linux/comedi.h include/linux/comedilib.h /usr/include/
# cp include/linux/comedi.h include/linux/comedilib.h /usr/local/include/
# ln -s /usr/include/comedi.h /usr/include/linux/comedi.h
# ln -s /usr/include/comedilib.h /usr/include/linux/comedilib.h
```

/usr/local/includeには既にファイルがあったけど、上書きした。

```
# modprobe rsrc_nonstatic
# modprobe i82092
# modprobe yenta_socket
# insmod /usr/realtime/modules/rtai_hal.ko 
# insmod /usr/realtime/modules/rtai_sched.ko 
# insmod /usr/realtime/modules/rtai_fifos.ko 
# insmod /usr/realtime/modules/rtai_sem.ko 
# insmod /usr/realtime/modules/rtai_mbx.ko 
# insmod /usr/realtime/modules/rtai_msg.ko 
# insmod /usr/realtime/modules/rtai_netrpc.ko ThisNode="127.0.0.1"
# insmod /usr/realtime/modules/rtai_shm.ko 
# insmod /usr/realtime/modules/rtai_tasklets.ko 
# modprobe comedi
# modprobe kcomedilib
# modprobe comedi_fc
# modprobe 8255
# modprobe ni_mio_cs
```

チュートリアルでは、`rtai_up.ko`か`rtai_lxrt.ko`を入れる事になっていますが、どちらもない。代わりに`rtai_sched.ko`を入れる。これを入れないと、`rtai_fifos.ko`のinsmodに失敗していたので、入れたモジュールは多分あっているでしょう。

`rsrc_nonstatic`、`i82092`、`rtai_signal.ko`、`ni_mio_cs`は見つからなかったけど、とりあえずこのままで。

信号の入出力に使用するドライバを把握していなかったので、`comedi config`は実施せず。
Bulmaでulを使う方法

# 解決したいこと

Bulmaを使っていて```<ul>```でリスト表示しようとしたところ、以下のようにリストマーカーもインデントも反映されなかったので、ここに解決方法をメモっておきます。

```html:コード
<ul>
  <li>いぬ</li>
  <li>ねこ</li>
</ul>
```
<img width="130" alt="スクリーンショット 2019-05-02 13.45.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16555/126abbad-a41c-15ef-cca1-1f936d0f52f3.png">

# 解決方法
以下のようにcontentクラスで```<ul>```ブロックを囲ってやるとデザインが反映されます。

```html
<div class="content">
  <ul>
    <li>いぬ</li>
    <li>ねこ</li>
  </ul>
</div>
```
無事、リスト表示できました。

<img width="130" alt="スクリーンショット 2019-05-02 13.46.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16555/57462c5f-2a42-ebc0-4ebd-d34ce081dfec.png">
VPS最初にやること備忘録

### Ubuntuのバージョンアップ
```
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade
$ sudo reboot
$ sudo apt install ubuntu-release-upgrader-core
$ sudo do-release-upgrade
```


### rootパスワード変更
```
root@localhost:~# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

### 普段使うユーザーを追加
```
root@localhost:/home# adduser ninja
Adding user `ninja' ...
Adding new group `ninja' (1000) ...
Adding new user `ninja' (1000) with group `ninja' ...
Creating home directory `/home/ninja' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for ninja
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] y
```
### 普段使うユーザーにsudo権限付与
```
root@localhost:/home# gpasswd -a ninja sudo
Adding user ninja to group sudo
```
### rootログインを無効にする
``` 
cd /etc/ssh
vi sshd_config

/*PermitRootLoginをyesからnoに変更する*/
PermitRootLogin no
/*sshを再起動*/
ninja@localhost:/etc/ssh# sudo /etc/init.d/ssh restart
```

### aptのアップデート
```
ninja@localhost:/etc/ssh# sudo apt-get update
ninja@localhost:~$ sudo apt-get upgrade
```

### 鍵認証
```
/*ローカルで鍵作成*/
$ cd ~
$ mkdir .ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/ユーザー/.ssh/id_rsa):
/*passphreseは11文字以上にしておく*/
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

サーバーにid_rsa.pubを送る。

ninja@localhost:~$ sudo apt-get install openssh-server
ninja@localhost:~$ mkdir ~/.ssh
ninja@localhost:~$ chmod 700 .ssh
ninja@localhost:~$ touch ~/.ssh/authorized_keys
ninja@localhost:~$ chmod 600 ~/.ssh/authorized_keys
ninja@localhost:~$ cat ~/id_rsa.pub >> .ssh/authorized_keys
```

###パスワード認証を禁止する（必ず鍵認証でログインできることを確認してから行う）
```
ninja@localhost:~$ sudo vi /etc/ssh/sshd_config

/* 「#PasswordAuthentication yes」を「PasswordAuthentication no」へ変更 */
PasswordAuthentication no

ninja@localhost:~$ sudo service ssh restart
※他のコンソールを開いて入れるか確認する。間違っていると入れなくなるため。
```

###ファイアウォール設定
```
/* とりあえず、SSH接続のみ許可*/
ninja@localhost:~$ sudo apt-get install ufw
ninja@localhost:~$ sudo ufw allow 3843

ninja@localhost:~$ sudo vi /etc/default/ufw

-   IPV6=yes
+   IPV6=no

ninja@localhost:~$ sudo ufw enable
ninja@localhost:~$ sudo ufw reload

/* 以下のコマンドで確認*/
ninja@localhost:~$ sudo ufw status
```
Laravelとdockerの開発環境でMailHogを使ってメール送信する

Laravelでメールを送信するアプリケーションを開発している間は、実際のメールアドレスにメールを送信したくはありません。ローカルでの開発環境ではMailHogを使って、「ダミー」のメールボックスへメールメッセージを送る方法がとても便利です。

以前の [Laravel5の環境をdockerで構築した記事](https://qiita.com/ucan-lab/items/17c806973e69792ada99) の続きです。

# 環境

- Laravel 5.8.3
- PHP 7.3.4

## Laravel環境構築してテストメールを送信するまで

```
$ git clone git@github.com:ucan-lab/docker-laravel5.git
$ cd docker-laravel5
$ docker-compose up -d --build
$ docker-compose exec app composer create-project --prefer-dist "laravel/laravel=5.8.*" .
```

ここまでのコマンドでLaravelの環境構築が完了です。

```
$ docker-compose exec app ash
$ sed -i -e "s/MAIL_HOST=.*/MAIL_HOST=mail/" .env
$ sed -i -e "s/MAIL_PORT=.*/MAIL_PORT=1025/" .env

$ php artisan tinker
Mail::raw('test mail',function($message){$message->to('test@example.com')->subject('test');});
```

`.env` の `MAIL_HOST` と `MAIL_PORT` の設定を書き換えます。
tinkerを起動して、テストメールを送信してみます。

http://127.0.0.1:3504

![スクリーンショット 2019-05-02 1.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/fc858df5-3ed2-b85a-f5ee-38a872f5a59c.png)

テストメールを受信できていればokです。

## MailHog とは

- [MailHog GitHub](https://github.com/mailhog/MailHog)
- [MailHog DockerHub](https://hub.docker.com/r/mailhog/mailhog)

MailHogは開発者向けの電子メールテストツールです。
Laravelで送信したメールの内容をブラウザ上で確認できます。
宛先に設定した実際のメールアドレス宛には送信されません。

Homebrewでインストールできたり、DockerHubにイメージが公開されているので導入が非常に簡単です。

- SMTPサーバーの標準ポートは `1025`
- HTTPサーバーの標準ポートは `8025`
- メモリ内のメッセージストレージを使用(コンテナを再起動するとクリアされる)
- 届いたメールはほぼリアルタイムで受信トレイに表示

## docker-compose.yml の設定例

実際の設定はこちらのご参考ください。
https://github.com/ucan-lab/docker-laravel5/pull/8/files

DockerHubにMailHogのイメージが登録されているので、
docker-compose.yml で指定すると簡単に導入できます。

```
# docker-compose.yml

  mail:
    image: mailhog/mailhog
    ports:
      - ${MAILHOG_PORT}:8025
```

Laravel側の `.env` の `MAIL_HOST` には コンテナ名を指定します。
`MAIL_PORT` には MailHog の SMTP のポート番号を指定します。

```
# .env

MAIL_HOST=mail
MAIL_PORT=1025
```

## 参考

- [CakePHP+MailHog+dockerでメールテストをしてみる](https://qiita.com/nagimaruxxx/items/0f0a918ef107069fcf15)
- [dockerコンテナでPHPからのメール送信とhttpsに対応する](https://qiita.com/kinoleaf/items/0b0002aa03993e58e2f0)
- [MailHogでテスト用メールサーバーを立てる](https://qiita.com/k8uwall/items/e3e19937f7749f5c2a32)
iOSのヘルスケアデータをCSVに変換する

iOS（iPhone）やApple Watchで溜めているヘルスケアデータを、
再利用するためにデータ出力をしたが、xml形式で使いにくかったのでCSVに変換してみようというお話。

[githubリポジトリ](https://github.com/ishibashi-futos/health-to-csv.git)

## 当方環境

* iPhone7 iOS 12.2
* Apple Watch gen3（だった気がする）

## やり方

* iPhoneのHealthアプリケーションから、`Export Health Darta`を選択し、zipファイルをエクスポートさせる。

<img width="375" alt="IMG_1219.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280383/7212121a-e6c6-8f88-cf6a-e3531badde30.jpeg">

⇨しばらくするとファイルをどうするか聞かれるので、任意の方法でPCに送る
当方はmacでiCloud連携を使用してデスクトップにおきました。

* zipファイルを解凍する
    * ZIPファイルを解凍すると以下のようなディレクトリ構成になっています。

      ```bash
        .
         ├── README.md
         ├── apple_health_export
         │   ├── export.xml
         │   └── export_cda.xml
      ```

  * export_cda.xmlは中身がよくわからなかったので無視。
* 以下、編集するためのプログラムです。

```go
package main

import (
	"encoding/xml"
	"io/ioutil"
	"log"
	"os"

	"github.com/gocarina/gocsv"
)

type HealthData struct {
	XMLName xml.Name `xml:"HealthData"`
	Record  []Record
}

type Record struct {
	Type          string `xml:"type,attr" csv:"type"`
	SourceName    string `xml:"sourceName,attr" csv:"-"`
	SourceVersion string `xml:"sourceVersion,attr" csv:"-"`
	Unit          string `xml:"unit,attr" csv:"unit"`
	CreationDate  string `xml:"creationDate,attr" csv:"-"`
	StartDate     string `xml:"startDate,attr" csv:"startDate"`
	EndDate       string `xml:"endDate,attr" csv:"endDate"`
	Value         string `xml:"value,attr" csv:"value"`
}

func main() {

	// open xml file.
	xmlFile, err := os.Open("./apple_health_export/export.xml")
	if err != nil {
		log.Fatal(err)
	}
	defer xmlFile.Close()

	// read xml data.
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		log.Fatal(err)
	}

	// parse xml and export to csv.
	csvFile, err := os.Create("./export.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer csvFile.Close()

	var healthData HealthData
	xml.Unmarshal(xmlData, &healthData)
	records := healthData.Record
	gocsv.MarshalFile(&records, csvFile)

}
```

## ポイント

HealthData内にRecordとして複数データが含まれているデータ構造だったので、
HealthData構造体とRecord構造体を用意しました。

Record構造体から抜き出す項目は `csv:"xxx"`として記述し、
抽出不要項目は`csv:"-"`とすることでparserが良い感じに処理してくれます。

## 改善ポイント

* メモリ消費が非常に大きい
    * ファイルサイズが大きいとそれに比例してメモリ使用量が増える

## 最後に

走り書きですが、とりあえず使えそうなデータが取れたので、
CSVを使って何かできないか試してみたいと思います。
「Envato Market（エンバトマーケット）」登録ミスのまま購入してしまった時の対処法

自分のメモとして描きます。
また自分と同じ状態になってしまった人の助けになれば幸いです。

内容
・30DAYSトライアルDAY18にてEnvato Marke（海外のテンプレ販売サイト）にて
【Kerri】を購入しようとした。
・参考としてアルパカさんのブログを見ながら行った。
「Envato Market」の使い方説明。アカウントの作り方や購入方法など【日本語で解説】→https://www.engineer-step.com/entry/envato-market


ミス内容
・登録時メールアドレスを入力して登録するが、その後のメアド認証の為のメールが受信されなかった。だが、Envato Markeのサイト右上部には登録したユーザー名が表示されていたので登録が完了したのかと勘違いした。

原因
・登録時に入力したメアドに脱字があった為、認証用のメールが送られてこなかった。
→メアドがあっていれば送られてくるメール内容
![スクリーンショット 2019-05-02 13.22.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408013/e18264aa-447a-7716-11da-a6aa74150162.png)

この時点で私は、【Kerri】をPayPalにて購入しました。
・購入自体は問題なくできましたが、肝心の購入したファイルを開くには、
購入した際に送られてくるメールを開かないとダウンロードできず、この時点で認証必要だったんじゃないかと気づきました。
→メアドがあっていれば送られてくるメール内容
![スクリーンショット 2019-05-02 13.25.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408013/6d2a9340-5c81-c891-99a0-af86bbac69ab.png)





対策
・メアドの変更をかけたい→日本語の解説サイトは登録する手順しかなく、わからない状態
→英語のサイトならあるかもしれないと「envato market change email 」にて検索
→![スクリーンショット 2019-05-02 13.11.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408013/99b0964b-e58f-b53e-a0b0-24c463fec70e.png)

英語サイトだと知りたい情報がありました。
このページを訳すをクリックすれば、英語があまり読めない私でもわかる内容でした。
一応リンクを貼ります。
→https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwjBkOed7_vhAhUFTrwKHR8LATIQFjAAegQIBBAB&url=https%3A%2F%2Fhelp.market.envato.com%2Fhc%2Fen-us%2Farticles%2F204163534-How-Do-I-Change-My-Email-Address-&usg=AOvVaw2yaP-0C6bQpyGxs7WGUwuC

このサイトどうりに進めていけばメアドの変更がかけられます。

ですが、私がやった時は、何回やってもログインできなく結構焦りました。
＄１７使ってすでに買い物をしてしまっていたので、、、

原因としてはユーザー名の脱字という凡ミスでしたが、
メアド、ユーザー名の１文字の脱字が命取りということを経験できたので良しとします笑

以上、英語のサイトで登録ミスをすると痛い目にあいます。
Craft 2 のテンプレートでユーザー一覧を JSON で返す

ユーザーの情報をテンプレートで表示することはほとんどないが、Feed Me を使ったデータ移行の際に利用できる。

```twig
{% set response = [] %}
{% for user in craft.users.limit(null) %}
  {% set response = response | merge([{
    firstName: user.firstName,
    lastName: user.lastName,
    userName: user.username,
    email: user.email,
    id: user.id
  }]) %}
{% endfor %}

{% header 'Content-Type: application/json; charset=utf-8' %}
{{ response | json_encode() | raw }}
```

下記も参考に。

- [Twig で配列に push して、その配列からランダムに値を取り出す \| かたつむりくんのWWW](https://tinybeans.net/blog/2019/03/26-113243.html)
開発環境も本番環境もDocker

# 作業環境
■前提
- Docker for Macインストール済み
- AWS EC2インスタンス作成済み

■環境
- macos high sierra 10.13.6
- EC2 Amazon Linux AMI release 2018.03


# なぜ興味を持った
今年の１月〜４月までは開発環境の構築の仕事をする時には差分を調べて本番環境に合わすことに多くの時間を使いました。[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2/dp/4297100339/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=Docker%2FKubernetes+%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80&qid=1556454357&s=gateway&sr=8-1)という本を読んで開発環境も本番環境もDockerにすれば環境差異問題からの脱却することができるを知って、もうすでにかもしれませんがこれからはこれだと思いました！！！

# 解説

### 全体の流れ
1. Docker for Macで開発環境を作って開発をする。
2. インフラとアプリケーションを同梱した箱のようなコンテナのイメージを作成してDocker Hubにプッシュ。
3. EC2のLinux上のDockerを使ってDocker Hubにプッシュしたイメージを取得してこれを使って本番環境を作成する。<br>
※ 開発環境はDocker for Windowsだと本番環境はLinux環境で上手く行かないの情報はありましたが、Docker for Macでは問題なくできました。

### 開発環境

- ディレクトリの構成<br>
<img width="205" alt="スクリーンショット 2019-05-02 13.03.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91907/5f3ebbe7-d34e-a21d-6e8e-59a5f6817159.png"><br>
 - delusion_quiz<br>
   アプリケーションの実体
 - Dockerfile<br>
   Dockerコンテナの構成内容をまとめて記述されているファイル<br>
 - docker-compose.yml<br>
   yaml でDocker コンテナに関する起動オプションを記述したファイル

```ruby:Dockerfile
    FROM php:7.0.21-apache
    COPY ./delusion_quiz/ /var/www/html
```

```ruby:docker-compose.yml
    version: "3"
    services:
      echo:
         build: .
         ports:
         - 80:80
```

*以上の条件で下記のコマンドを実行するとos、ミドルウェア、phpのどれも揃ってアプリケーションが動くようになる*
`docker-compose up` 

- イメージを作成してDocker Hubにプッシュ<br>
　1. コンテナを確認<br>
　   `docker ps -a`<br>
　2. コンテナをイメージにコミットする<br>
　   `docker commit 092723cefd67 iiwao/delusion_quiz:version1`<br>
　3. コミットしたイメージを確認<br>
　   `docker image ls`<br>
　4. イメージをDocker Hubにプッシュ<br>
　   `docker image push iiwao/delusion_quiz:version1`

  *以上でDocker Hubにイメージがアップされる*

### 本番環境
*EC2のLinux上のdockerで以下を実行する*

1. Docker Hubからイメージを取得<br>
   `docker pull iiwao/delusion_quiz:version1`
2. イメージをコンテナにビルドする<br>
   `docker build -t iiwao/delusion_quiz .`
3. Docker実行環境の80ポート経由でHTTPリクエストを受けられるようにする<br>
   `docker run -dit -p 80:80 iiwao/delusion_quiz:version1`


*以上で簡単な開発環境も本番環境もDockerが完成*
[EC2にデプロイしたアプリケーション](http://delusion.site/)
Cloud9にTerraformをインストールする手順

2019年4月にAWS Cloud9が東京リージョンでリリースされましたが、このCloud9でAWSのリソースを構築するコードをデプロイしながら、SSH等でサーバを操作できると運用が捗ります。そこで、Cloud9でTerraformをインストールする手順をまとめてみました。

# 1. Homebrewをインストール
以下の記事の内容の通り、Homebrewをインストールします。2019年では、HomebrewはLinuxをオフィシャルにサポートし、インストールできるようになっています。手順は非常に簡単なものでした。
[Cloud9にHomebrewをインストールする手順](https://qiita.com/nasuvitz/items/5eec6ab9444cff8e9467)

# 2. tfenvをインストール
Terraformのバージョンを切り替えることができるtfenvをインストールします。
tfenvをインストールしていれば、新しいTerraformのバージョンがリリースされても、Cloud9上で旧バージョンのインストールを維持したまま、新バージョンを試すことができます。

```bash
$ brew install tfenv
```

# 3. tfenvで利用できるTerraformのバージョンを確認
以下のコマンドで、tfenvを使ってインストールできるTerraformのバージョンを確認します。

```bash
$ tfenv list-remote
```

# 4. tfenvでTerraformをインストール
最新のバージョンでインストールするには、以下のコマンドを実行します。

```bash
$ tfenv install latest
```

バージョンを指定する場合は、以下のコマンドに倣います。

```bash
$ tfenv install 0.11.13
```

# 5. tfenvでTerraformのバージョンを選択
tfenvでバージョンを指定すると、terraformコマンドを実行した時に、指定したバージョンが使われるようになります。1つしかバージョンをインストールしていなくても、コマンドを実行する必要があります。

```bash
$ tfenv use latest
```
バージョンを指定する場合は、以下のコマンドに倣います。

```bash
$ tfenv use 0.11.13
```

# 6. 動作確認
Terraformのバージョン確認コマンドを実行して、バージョンを表す文字列が返ることを確認します。

```bash
$ terraform --version
Terraform v0.12.0-beta2
```

これでCloud9でもTerraformが使えるようになりました。Cloud9をEC2モードで動かしている場合は、EC2にIAM Roleをアタッチすれば、TerraformでAWSのリソースを構築できるようになります。
ImageMagick の equalize の昔話

ImageMagick の equalize(ヒストグラム平坦化) の昔話です。

2012年2月(ImageMagick-6.7.9-3) まで ImageMagick の equalize は色味を維持しませんでした。そこから 2013年6月(ImageMagick-6.8.6-3)までの長きに渡る改良の末今の equalize に落ち着いたバージョンの流れをメモしておきます。

ヒストグラム平坦化とは何か、色味を維持しないとどうなるかの説明はこちらを参考にして下さい。

- PIL でカラー画像を Equalize(ヒストグラム平坦化)する時の注意
   - https://qiita.com/yoya/items/a11085f90f555b887cf6

# 画像サンプル

6.7 と 6.8 で挙動違くない？のツッコミ issue から画像を拝借。

|(c) https://imagemagick.org/discourse-server/viewtopic.php?t=23518 | ヒストグラム|
|---|---|
|![h3eVjuZ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/7389a166-1024-7815-41cf-7b907c546538.jpeg)|  ![hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/9468b7ec-9205-f33d-3078-ef9bce7129d9.png)|

# バージョン毎の結果

```
convert h3eVjuZ.jpg -equalize <version>-eq.png
convert <version>-eq.png histogram:<version>-hist.png
```

のバージョン毎の結果です。

|ImageMagick|変換画像|ヒストグラム|備考|
|---|---|---|---|
|〜 6.7.9-2 | ![6.7.9-2-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/a91500d8-ed23-ddc8-a77f-d82b715fcaf5.png)| ![6.7.9-2-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/e984f63e-05d9-af97-f6f4-72da99ce054d.png) |RGB別 equalize
|6.7.9-3 〜  6.8.1-0|![6.7.9-3-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/1c5019b0-adaf-4943-477d-146e53e1ae95.png) |![6.7.9-3-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/003df27e-bedb-14cc-7a7d-4d29d00c4df7.png)|大失敗|
|6.8.1-1 〜 6.8.3-9|![6.8.1-1-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/1905c61d-ad56-5103-f56d-4fcbd0ccd7eb.png)|![6.8.1-1-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/3e9a83a7-0940-a041-699a-e49eb805c73e.png)|まだ少し明るい|
|6.8.3-10|![6.8.3-10-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/1aa07237-aa24-72d5-a251-5b4a67481354.png) | ![6.8.3-10-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/8de7920a-0731-0971-6180-4db28bf91ced.png)|大失敗再び|
|6.8.4-0 〜 6.8.6-2 | ![6.8.4-0-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/492ee34a-65d7-ffc8-46ad-ebee7dd4f8c8.png) | ![6.8.4-0-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/a21b1c1a-8f82-a3c5-e5dc-f3feadc67b6d.png) |だいぶ改善|
|6.8.6-3| ![6.8.6-3-eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/da6b8610-0c9b-c477-5681-82742f119f87.png) | ![6.8.6-3-hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/00ac31b0-9c34-4455-a51b-71152ba68575.png)|完成|
Python MatplotLib で交点の座標をグラフ中に表示する方法

日本語でのmatplotlibでのグラフ中への交点表示方法があまり探しても出てこなかったのでサンプルソースとともに載せておきます。

ここでは例として$y1 = x^3$, $y2 = 3x^2$の交点を求め, 表示しています。

```python
import numpy as np
import matplotlib.pyplot as plt

x = np.array([i for i in range(10)])
y1 = x ** 3
y2 = 3 * x ** 2

# 交点の座標を取得
idx = np.argwhere(np.sign(y1 - y2) == 0)
# 交点をグラフにプロット
plt.plot(x[idx], y1[idx], 'ms', ms=5, label='Intersection', color='green')
plt.xlabel("x")
plt.ylabel("y")
# 交点の座標をグラフに追記
for i in idx.ravel():
    plt.text(x[i], y1[i], '({x}, {y})'.format(x=x[i], y=y1[i]), fontsize=10)
plt.plot(x, y1, color='red', label='y1')
plt.plot(x, y2, color='blue', label='y2')
plt.legend()
plt.show()
```
***

実行結果
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406474/8d58eefb-eba7-d461-357b-241778b55429.png)

***
少し見辛いですが, 交点の座標がグラフ中に表示されていることがわかるかと思います。
表示する位置はx, yを変えてあげると見やすくなると思います。

交点の座標取得では, y1とy2のxが同じである点の座標を比較して, 差が0であった時のx座標をidxに格納しています。


xのステップ数を1刻みではなく0.1刻みや0.01刻み等もっと細かくすれば, 小数点や$√$での交点の値でも取れるのではと思います。

何かご指摘やご意見等ございましたら是非お知らせください。
Microsoft FlowでRSS読み込みがBad Requestになる件

朝起きたら、Microsoft Flowで設定した本来動いているはずの処理が動いていないというトラブルに出くわしましたメモ。

# トラブルが起きていたFlow

トラブルが起きていたFlowは、RSSを使った非常に単純なもの

1. 特定サイトのRSSを取得する
2. 上記RSSの情報をBufferを使ってTwitterに予約投稿
3. 上記RSSの情報をBufferを使ってFacebookに予約投稿

で、ログを見てみると1の時点で400 Bad Requestが出て処理に失敗していた。

## 原因

Microsoft FlowのRSSリーダーは、一般的な他のRSSリーダーより厳格にRSSを読むようで、RSSにInvalidなデータが含まれていると解析に失敗し400 Bad Requestを吐きます。

どこがおかしいのか分からないときは、とりあえずW3Cのフィードバリデータを使うのが吉です。

* [W3C Feed Validation Service, for Atom and RSS](https://validator.w3.org/feed/)

今回自分の環境で起こっていた問題は、RSSの中に表現不能な文字が含まれていた。

とりあえずフィードバリデータを使って全てのエラーを修正したら、Flowが無事に動くようになりました。

# 対策

とりあえず、手順として最後に、「Flowの流れをdiscordに通知」というアクションを追加(予定/いつも常用するOfficeアカウントではないため、モバイル通知が使えない)。

また、可能であればMicrosoft Flow自体のエラーレポートを、自分へのメールなど対応可能なものに変更する。

Microsoft Flowは裏側で別のサーバで処理しているのもあってか、ときどき他のサービスと違う挙動をします。そのためHTTPエラーコードが予定のものと異なるなど、ときどき予想外の挙動をすることがあります。

APIのリファレンスなどに頼るだけでなく、多方面で情報収集をする必要があります。


・・・やっぱりFlowって、普通にプログラミングするより難しくない？
Vue3.x系で作ったアプリをFirebaseにデプロイするまでの流れ【初心者向け】

vue.jsでWebアプリを作ってそれをFirebaseにデプロイするまでにやったことをまとめました。

途中躓いたところが何個かあったので、備忘録として。


# 環境とかバージョンとか
* Mac OS Mojave(10.14.3)
* npm 6.9.0
* vue-cli 3.5.1
* firebase 6.5.0


# １．vue.jsで何かしらアプリを作る
まずはvue-cliというツールをインストールします。
こちらの記事を参考にさせてもらいました。

[Vue.js を vue-cli を使ってシンプルにはじめてみる](https://qiita.com/567000/items/dde495d6a8ad1c25fa43)

vueには2.x系と3.x系があり、firebaseにデプロイする際の手順で微妙に違いがあるそうです。
今回は最新の3.5.1を使いますので2.x系の話は割愛してます。

`$ vue --version`とかで確認しておくと吉。

`$ npm run build`を実行してdist配下にデプロイする用のファイルを置いておきます。

# ２．firebase側の準備
Firebaseに今回作成したアプリをデプロイする用のプロジェクトを作る必要があります。
GoogleアカウントでFirebase開き、コンソールから「プロジェクトを追加」をクリックします。

![スクリーンショット 2019-03-24 19.13.19.png](https://qiita-image-store.s3.amazonaws.com/0/159675/6d2a6ecf-86c5-ac8e-af8a-6c19de133905.png)

そして、firebaseにログイン。

```terminal
$ firebase login
```

ここでいろいろ英語で聞かれると思いますが、言われたとおりにハイハイ言っておきます。
（ブラウザに飛んで許可するか聞かれるはず）

ログインが終わったらプロジェクトIDをメモっておきます

```terminal
$ firebase list
┌───────────┬───────────────────────┬─────────────┐
│ Name      │ Project ID / Instance │ Permissions │
├───────────┼───────────────────────┼─────────────┤
│ Cash Book │ 　　プロジェクトID       │ Owner       │
└───────────┴───────────────────────┴─────────────┘
```

次にさっきのvueのアプリがあるディレクトリまで行き、initを実行。

```terminal
$ firebase init --project=[FirebaseのプロジェクトID]
```
AAでFIREBASEと表示され、つらつらと色々聞かれます。

```terminal
     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

/workspace/vue/vue-cli-test/test-prj

? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices.
 Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add, 
but for now we'll just set up a default project.

i  Using project hogehoge 

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory?
```

設定のあれこれを聞かれますが、基本的にはEnter連打でOK. (Y/n)で聞かれる質問はEnterを押すと大文字の方(Yes)を自動で選択してくれるようになっています。

ただし、`? What do you want to use as your public directory?`はvueのdistフォルダを指定しましょう。
（あとから変更可能です）

<font color="red">デフォルトではpublicフォルダが選択されますが、vueではdist配下にソースが格納されるのでdistに指定しなければいけません。</font>

# ３．firebaseにアプリをデプロイする
`$firebase deploy`でサーバーにアプリをデプロイします。
Google Cloud Speech API: Qwik Startの使い方メモ

### 概要
Googleの「ML Study Jams : Machine Learning 初心者向けトレーニングプログラム」の1つ
「Google Cloud Speech API: Qwik Start」をやってみたメモ

### 手順
[QWIKLABS のガイド](https://www.qwiklabs.com/focuses/588?catalog_rank=%7B%22rank%22%3A7%2C%22num_filters%22%3A3%2C%22has_search%22%3Atrue%7D&parent=catalog&search_id=1896374) どおり進めればよいだけだけど

~~~
{
  "config": {
      "encoding":"FLAC",
      "sample_rate": 16000,
      "language_code": "en-US"
  },
  "audio": {
      "uri":"gs://cloud-samples-tests/speech/brooklyn.flac"
  }
}
~~~

のまま送るとエラーになる
[公式リファレンス](https://cloud.google.com/speech-to-text/docs/reference/rest/v1/RecognitionConfig)
をみて

~~~
{
  "config": {
      "encoding":"FLAC",
      "sampleRateHertz": 16000,
      "languageCode": "en-US"
  },
  "audio": {
      "uri":"gs://cloud-samples-tests/speech/brooklyn.flac"
  }
}
~~~

としたら結果取得成功

### その他
公式サイト
https://cloud.google.com/speech-to-text/
を見ると、日本語を含む複数言語に対応済みなのはもちろん複数人の同時発話にも対応されそう
NEMを使ったサービスを作っててハマったところ

はじめまして、ゆーたろ[@yutaro_elk](https://twitter.com/yutaro_elk)と申します。エンジニア職に転職活動中です。主にフロントエンドをやってます。

ブロックチェーンの一種であるNEMで簡単なサービス（[StreetNEMS](http://streetnems.s3-website-us-west-2.amazonaws.com/)）を作ったさいハマったところなど記録しておきたいと思います。
##signerとsignatureを間違える
凡ミスです。

NEMのトランザクションはjsonデータで取得できます。
取引のトランザクションであるTransferトランザクションはこのようなjsonが返ってきます。

```json:TransferTransaction.json
{
  "meta":{
    "innerHash":{},
    "id":834509,
    "hash":{
     "data":"aaaaaaaaaaaaaaaaaaaaaaaaa"
    },
    "height":1146325
  },
  "transaction":{
    "timeStamp":69421490,
    "amount":1000000,
    //署名者の公開鍵
    "signature":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "fee":2000000,
    //受信者のアドレス
    "recipient":"NXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "type":257,
    "deadline":69507890,
    "message":{
       "payload":"dddddddddddddddddddddddddddddd",
       "type":1
   },
   "version":1744830465,
 //送信者の公開鍵
 "signer":"cccccccccccccccccccccccccccccccccccccccccc"
  }
 } 
```

その中から送信者の公開鍵を取得しようとして**signer**と**signature**を間違えてました…。signerが送信者の公開鍵で、signatureはトランザクション署名のことです。見た目が似てたので間違えました…

##ホスティングでのSSL対応

これが一番ハマりました。

最初はGithub Pagesを使ってホスティングをしようとしましたが、`ERR_SSL_PROTOCOL_ERROR`が出てしまいました。

これはNEMのAPIを叩く際、APIサーバーであるノードがSSL対応ではないうえでGithub Pagesが自動でSSL対応になっているためでした。

最終的な対応としてはホスティングは自動SSL対応ではないAWS S3でホスティングし、叩くノードもhttpのものを使っています。

###ノードをSSL対応にしたけど…
それまでに試したのはまずノードをSSL対応のものに差し替えました。xembookさんが[優良ノードのリスト](https://s3-ap-northeast-1.amazonaws.com/xembook.net/data/v3/node.json)を公開してくださっているのでそれを使ったり、あとは[nemlog](https://nemlog.nem.social/)さんのソースを拝見したり。しかしノード側の問題なのかちゃんと反応が返ってきませんでした…

これはいまいち原因があいまいなのでまた後日ちゃんと調べたいです。

###ホスティング先を変更した
次にノード側を変更せずいけるホスティングを探しました。Github Pagesを最初に選んだ理由が「簡単で安い」だったので、同じようなサービスであるFirebase、Netlifyを試してみました。しかし、どちらもやはりSSL対応が自動でされてしまいます。普段ならとても便利な機能なんでしょうが残念です。

最終的にAWS S3ならSSLじゃなくてもいけるということでそちらにしました。

---

こうしてみると、NEM自体でハマったことはあんまり無かったですね…（そのかわりSSLの部分はかなり長時間ハマっていて、根本的な解決にはまだ至っていないんですが…）

SSL対応については今後の課題として、解決したらまた記事にしたいと思います。
Linuxで、一部のディレクトリをユーザ間で共有する

Linuxで、一部のディレクトリのみ、特定のユーザ間でファイルを共有し、自由に読み書きできるようにする方法を記載します。
umaskと、ユーザが所属するグループ、set-group-IDビットなどを活用します。

また、samba経由でも、同じディレクトリを、読み書きできるようにします。

Debian 10で動作確認をしています。

# 1. ローカルユーザでの共有

### デフォルトの umask を 0007 にする

/etc/pam.d/common-session に次の行を追加します。

~~~
session	optional			pam_umask.so 
~~~

/etc/login.defs の UMASK の設定を007に変更します。

~~~
UMASK           007
~~~

### ファイル共有用のグループを追加する

~~~
sudo addgroup share
~~~

### ファイルを共有したいユーザを、追加したグループに所属させる

~~~
sudo usermod -a -G "share" user1
~~~

### 共有ディレクトリの所有グループとパーミッションを設定する

~~~
chgrp share /var/samba/share
chmod 2770 /var/samba/share
~~~

### 各サービスの umask の設定を行う

Debian 9までは pam の設定のみで効果があったのですが、 Debian 10 ではユーザごとに各サービスの umask の設定が必要なようです。

参考: https://unix.stackexchange.com/questions/254378/how-to-set-umask-for-the-entire-gnome-session/411060#411060

まず、dbus の設定をします。

~~~
systemctl --user edit dbus
~~~

内容は次のようにします。

~~~
[Service]
UMask=007
~~~

次に、gnome-terminal-server の設定をします。

~~~
systemctl --user edit gnome-terminal-server
~~~

同じく、内容は次のようにします。

~~~
[Service]
UMask=007
~~~

これで、ほとんどのアプリケーションの umask が 0007 になったはずです。

# 2. sambaでの共有
/etc/samba/smb.conf に以下の内容を追加します。

~~~
[share]
	path = /var/samba/share
	read only = No
	create mask = 0660
	directory mask = 0770
~~~

systemctl reload smbd を実行します。
［エラー対処法］Dockerが動かない［Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?］

## エラー内容
Dockerコマンドを叩くと以下のようなエラーが出てしまう。

```
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

## 原因/解決策
Dockerが起動できていない。
原因は、Dockerインストール後に起動させていないとか、Dockerを落としたのに起動処理を忘れているとか。
そのため、以下のコマンドで起動させれば解決する。

```
$ systemctl start docker
```

## 起動確認
コンテナ情報が表示された。

```
$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```
USキーボードのCapsLockキーを無効化してホームポジションのままでいろいろできるようにした

自分のブログからの転載です→[【Windows】USキーボードのCapsLockキーを無効化してホームポジションのままでいろいろできるようにした  |  東京消息](http://t1y.me/howto-make-capslock-useful/)

ブログでこの記事を書いた時にTwitterでそこそこの反応があったのでQiitaにも投稿してみました。__Qiita初投稿__やったね！

# 環境
PC: Lenovo Thinkpad X270 US配列
OS: Windows10 Pro 64bit
※CapsLockを無効または他のキーに割り当てるだけなら不要ですが、いろいろできるようにするためにはAutoHotKey必須です。

# 何がしたいのか
とにかくホームポジションからの移動を最小化したい。
具体的にはCapsLockキーと他のキーの組み合わせにホームポジションから離れたキーの機能を割り当てたい。
# USキーボード独特のCapsLock問題
JISキーボードだとそんなに難しいことをしなくても、AutoHotKeyだけでどうにかなりました。Shiftと同時押ししないとCapsLockがかからないので。

しかし__USキーボードはCapsLock単押しでも切り替わってしまう__ので、単純に同時押しのスクリプトを設定すると一応動作はするんですが、そのたびにCapsLockがオン・オフされてしまうという問題があります。
単押しでのCapsLockオンオフを無効化しつつ、AutoHotKeyでも使えるようにするというのがこの記事の目的です。
# レジストリで架空のF21キーに割り当て
なぜF13じゃなくてF21なのかは適当です。
13だと縁起悪い気がしたからっていうだけです。別にF13～F24の間ならなんでも良いと思う。
別にキーボードにないキーなら何でも良いんですが、USキーボードにないからといって変換キーや無変換キー、かなカナキーだとアプリケーションによっては余計な動作をしそうだったので、そもそも架空のキーに割り当てます。

# まずはキーコードを調べる
私はAutohotkeyを使っているので、下の記事を参考に一時的にキーコードを調べるスクリプトを設定。

http://did2.blog64.fc2.com/blog-entry-349.html

F21キーのスキャンコードは6Cということがわかったので、CapsLockの3Aと入れ替えるようにレジストリをいじります。

# レジストリに書き込む
下の記事を参考に、実際にレジストリを書き換えます。

http://bigbuddha.hatenablog.jp/entry/2017/01/04/072943

レジストリエディタを使って、

```HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
```
のディレクトリに新しいバイナリ値を作成します。

参考記事でCtrlのスキャンコードを入力している部分にF21キーのコード6Cを入れるだけ。
再起動後、CapsLockキーを押しても無効化されていることを確認。

念の為もう一度Autohotkeyのキー履歴を見てみると、ちゃんとF21キーとして認識されていました。
# AutoHotKeyでキーバインドを設定する
レジストリでリマップしたので、CapsLock単押しでもCapsLockは発動しません。
下記は実際に私が使っているAHKのスクリプトのうち、CapsLockキー関係のものです。TabやEnter、BackSpaceすら設定して、徹底的にホームポジションからの動きを最小限にするように考えました。

```
;CapsLock(sc03A)はF21(sc06C)にリマップ済み

;CapsLock+FでTabの動作
sc06C & f::Send,{Tab}  

;CapsLock+;でDEL、+:でBSの動作 
sc06C & sc028::Del 
sc06C & sc027::BS  

;CapsLock+SpaceでEnterの動作 
sc06C & Space::Send,{Enter}  

;CapsLock+hjklで上下左右の動作 
sc06C & h::Send,{Blind}{Left} 
sc06C & j::Send,{Blind}{Down} 
sc06C & k::Send,{Blind}{Up} 
sc06C & l::Send,{Blind}{Right}  

;CapsLockでコピペ等の動作 
sc06C & c::Send,^c 
sc06C & v::Send,^v 
sc06C & a::Send,^a 
sc06C & s::Send,^s 
sc06C & z::Send,^z 
sc06C & x::Send,^x
```
Glideappsにコメント/チャットのメッセージ追加を通知する機能が付いたので試してみた

　プログレアプリ(PWA)をGoogleスプレッドシートを使ってコーディングレスで作れるGlideに機能が追加されました。

　Glideappsには、コメント/チャットの機能があるのですが、更新されてもアプリを開いて見に行くまでわかりませんでした。

　今回、これらのメッセージ追加・更新をメールで通知する機能が付いたそうです。

[Chat & comment email notifications are now live](https://spectrum.chat/glideapps/accouncements/chat-comment-email-notifications-are-now-live~e6224996-6dcc-4ded-9839-666a8607d484)

![D5hdZ6dWsAENNzb.jpg large.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/f741a437-1e64-1c23-7f26-3dd215e70d30.jpeg)

## コメントしてみる

ん？
特にメールは飛んでこないですね...
既存のコメント機能には、自動的に付与されるわけではないのでしょうか？

## チャットを追加してみる

やっぱりダメですね。

すでに作ってあったアプリに追加するのではなく、テスト専用のアプリも作ってみましたが同じです。
違うメールアドレスで登録してやってみましたが、同じようにメール通知はありませんでした。

何かスイッチでもあるのかな？

それとも、浸透するまで時間がかかるのでしょうか？

## 通知は日に一回だそうです...

こんなメールが飛んできます。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513/4cf4590a-6727-fc20-f207-d7db9a226341.png)

できればリアルタイムの通知がほしいところですね。

## デフォルトで設定され、オフにするには

ユーザーが自分でオフにするしかない感じ。
オフにするのは通知メールの末尾にあるリンクを使うしかないようです。

## 関連ドキュメント
・[流行りのGlideでプログレアプリ(PWA)してみた](https://qiita.com/kinneko/items/548597770d93aa17c6cf)
・[プログレアプリGlideappsにchoice機能が追加されたので使ってみました](https://qiita.com/kinneko/items/99a67faa231226335ba6)
・[Glideappにコメント/チャットのメッセージ追加を通知する機能が付いたので試してみた](https://qiita.com/kinneko/items/654c2a1e6e13d9c9592c)
・[Glideappsでfav機能が評価中なので試してみた(リリースされました)](https://qiita.com/kinneko/items/d4fae3ae26d358b130ba)
・[「5分で作れる！Glideappsではじめる超簡単PWA」セッションで利用する予定のデモ動画とプレゼン資料](https://qiita.com/kinneko/items/2d15a7cb87cb17a483a7)
・[Glideで画像アップロードの機能のテストが開始されました](https://qiita.com/kinneko/items/6831572cf3cf12a4a4e3)
・[Glideのリスト表示で地図と連携表示する機能のテストが開始されました](https://qiita.com/kinneko/items/79e84181ab7c0bcef88d)
・[Glideで画面のリロードをさせるための対策](https://qiita.com/kinneko/items/dec896995aca30b91ec6)
mysqlの文字コード変更(メモ)

覚え書です

mysqlの文字コードをlatin1からutf8に変更するために/etc/my.cnfをいじったら、なぜかmysql自体が起動しなくなったのでdb作成後に文字コードを変更することにした

初めは

```bash:mysql
ALTER DATABASE [ database ] CHARACTER SET [ character set ] COLLATE[ collations ];
```

で変更してたが

```bash:mysql
SET [ variable_name ] = [ character set ];
```
こっちの方がやり易い
pipインストール時のアクセス拒否の対応メモ

### はじめに
掲題のことが発生したので備忘録

### 環境
Windows 10
Anaconda

###問題と対応
Anaconda環境でモジュールをpipでインストールした時に以下エラーが発生。権限の問題？

```python
pip install pyswams

Could not install packages due to an EnvironmentError: [WinError 5] アクセスが拒否されました。: 'C:\\Users\\XXX\\AppData\\Local\\Temp\\pip-uninstall-ywopbx45\\users\\XXX\\appdata\\local\\conda\\conda\\envs\\chemsyo\\lib\\site-packages\\scipy\\integrate\\lsoda.cp36-win_amd64.pyd'
Consider using the `--user` option or check the permissions.
```

--user をつけることで解決。

```
pip install pyswarms --user
```
Node.jsの学習方法【GW連投企画】

# 注意点
## いきなりチャットアプリは避けよう
Node.jsと言えば、websocketと相性が良いので
チャットアプリのバックエンドに良く採択されます。

しかし、MVCも理解していない入門の方が
チャレンジするとワケワカメになってしまう可能性があるので、
目的がwebsocketを使ったチャットアプリでも最初は
MVCのCRUD Webアプリで慣れましょう。

## Express無しでの習得は避けよう
理想的な順番はExpress無しのNode.jsからExpress等を使った
フレームワークですが、Expressがデファクトとなっており、
Node.jsのみでのチュートリアルは多くはないこととExpressがシンプルな
事もありそれほど問題ないのでいきなりExpressで雰囲気つかむのもOKです。

## mongodbじゃなくmysqlやposgreに対応できるようにしよう
主に海外サイトですがNode.jsと相性が良いmongodbが採択されたチュートリアルが多いですね。
国内ではmongodbの案件が少ないのでmysqlやposgreに書き換えるスキルを早めに身につけておくと
幅が広がります。

# 進めかた

[Node.js超入門[第2版]](https://www.amazon.co.jp/gp/product/4798055220/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)
Express無しのNode.jsからExpress有りのNode.jsへ、しかもmongodbじゃなくmysqlを使ってるので理想的な流れになってます。読了後にSequelizeをORMマッパーとして書き換えれると良い感じです。

[Node.js + Express で作る Webアプリケーション 実践講座](https://www.udemy.com/web-application-with-nodejs-express/learn/v4/overview)
より本格的なNode.jsアプリケーショnションを作れるようになります。

[The Complete Node.js Developer Course (3rd Edition)](https://www.udemy.com/the-complete-nodejs-developer-course-2/learn/v4/overview)
テストコード等本格的な事を学べます。

# 環境構築
Docker Tool BoxとNode.jsは相性が悪いので注意
[Rails] select, optionでinclude_blank（空白）とselectedを同時に設定する方法

select, option使用時に`include_blank（空白）`と`selected（初期値）`を
同時に設定したかったができなかった。

しかし、以下のように設定したら解決した。

```ruby:
 <%= select_tag なにか,
     options_for_select(値, selected: 値),
     include_blank: true,
     class: "example" %>
```

`options_for_select`設定時は、
<b>
`selected`：options_for_selectの第2引数
`include_blank`：select_tagの第3引数
</b>

に設定しなければならない。


それまでは、`selected`もselect_tagの第3引数に設定していた。

<br>

おわり
WebGLで整数頂点バッファーを使う

WebGLでは[WebGLRendering​Context​.vertex​Attrib​Pointer()](https://developer.mozilla.org/ja/docs/Web/API/WebGLRenderingContext/vertexAttribPointer)でバッファーオブジェクトの使用方法を指定します。`vertexAttribPointer`の`type`引数には`gl.SHORT`など整数のデータ型を指定できますが、シェーダー側では浮動小数点数としてしか受け取れないので、使用する際には以下のようにシェーダー側で型変換する必要があります。

```js
gl.bufferData(gl.ARRAY_BUFFER, new Int16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribPointer(0, 1, gl.SHORT, false, 0, 0);
```

```glsl:頂点シェーダー
#version 300 es

layout (location = 0) in float i_index;

vec3[3] POSITIONS = vec3[](
  vec3(-0.5, -0.5, 0.0),
  vec3(0.5, -0.5, 0.0),
  vec3(0.0, 0.5, 0.0)
);

void main(void) {
  gl_Position = vec4(POSITIONS[int(i_index)], 1.0);
}
```

---

WebGL2からは[WebGL2Rendering​Context​.vertex​Attrib​IPointer()](https://developer.mozilla.org/ja/docs/Web/API/WebGL2RenderingContext/vertexAttribIPointer)を使用すれば以下のようにシェーダー側で整数として受け取れるようになるので、型変換の必要がなくなります。(わかりづらいですが`Attrib`の後に`I`があります)

```glsl
layout (location = 0) in int i_index;
```

型付き配列の精度に応じて`vertexAttribIPointer`の`type`を決定します。例えば、`Int16Array`の場合は`gl.SHORT`を、`Int32Array`の場合は`gl.INT`を使用することになります。

```js
gl.bufferData(gl.ARRAY_BUFFER, new Int16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.SHORT, 0, 0);
```

```js
gl.bufferData(gl.ARRAY_BUFFER, new Int32Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.INT, 0, 0);
```

---

符号なし整数を使用する場合は16bit、32bitそれぞれ以下のようになります。

```js
gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_SHORT, 0, 0);
```

```js
gl.bufferData(gl.ARRAY_BUFFER, new Uint32Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_INT, 0, 0);
```


シェーダー側では次のように`uint`で受け取ることができます。

```glsl
layout (location = 0) in uint i_index;
```

---

サンプルのソースコードをgistに置いておきました。
https://gist.github.com/aadebdeb/5f2e70095762e24ab5f132925f67e3cd
powershellで標準入力の入力元をファイルへ変更するメモ

ローカル環境でPythonの標準入力を外部ファイルにするよう
リダイレクトしたかったのだけれど、
powershellだと、

``` powershell
hogehoge.py <  input.txt
```
しようとすると、

``` powershell
演算子 '<' は、今後の使用のために予約されています。
```
とエラーが出て使えなかったけれど以下で実行可能でした。

``` powershell
Get-Content input.txt | python .\hogehoge.py
```

＜コメント＞
このごろPythonに手を出し始めて、
手始めにpaizaの問題を、VSCode上で解こうとして、行き当たった問題でした。
Defold 公式アカウント、紹介記事のリンク一覧

# Defold 公式アカウント

* [Defold –2Dゲーム用に作られた究極のゲームエンジン](https://www.defold.com/japan/)
* [Defold game engine forum](https://forum.defold.com/)
* [defoldvideos \- YouTube](https://www.youtube.com/channel/UCrEYXG15n3V0Y8eK0RbCaLQ)
* [Defold Engine\(@defold\)さん \| Twitter](https://twitter.com/defold)
* [Defold \- ホーム \| Facebook](https://ja-jp.facebook.com/Defold/)

# 紹介記事

* 2016/01 Global Game Jam 2016 オープニング映像に登場
* 2016/03 Game Developers Conference 2016 正式発表
 * [GDC Vault \- King proudly presents Defold\! \(presented by King\)](https://www.gdcvault.com/play/1023484/King-proudly-presents-Defold-\(presented) 
 * [GDC Vault \- Learn About Defold The New Cross\-Platform Engine from King \(presented by King\)](https://www.gdcvault.com/play/1023487/)
 * [［GDC 2016］「キャンディークラッシュ」のKingが公開した完全無料のゲームエンジン「Defold」とは？ \- 4Gamer\.net](https://www.4gamer.net/games/032/G003263/20160317081/)
* 2016/05-06 CyberAgent ブログ
 * [2Dに特化した軽量ゲームエンジンDefoldでゲームを作る（前編） \| CyberAgent](https://creator.game.cyberagent.co.jp/?p=3782)
 * [2Dに特化した軽量ゲームエンジンDefoldでゲームを作る（後編） \| CyberAgent](https://creator.game.cyberagent.co.jp/?p=1578)
 * [「Defold」で作ったアプリをモバイルで実行する方法 \| CyberAgent](https://creator.game.cyberagent.co.jp/?p=4078)
 * [「Defold」でゲーム画面を作る方法 \| CyberAgent](https://creator.game.cyberagent.co.jp/?p=4157)
* 2016/07 第9回 SEGA GAME JAM
 * [海外のカンファレンスで得た最新情報をゲームジャムで試す！ セガ・ゲームジャムにおける最新ゲームエンジン「Defold」の活用で見えてきたもの：レポート｜gihyo\.jp … 技術評論社](http://gihyo.jp/news/report/2016/08/0501) 
* 2017/04 King Japan 説明会
 * [Kingはなぜ完全無償のゲームエンジン「Defold」を提供しているのか？　Defold説明会レポート \- GamesIndustry\.biz Japan Edition](http://jp.gamesindustry.biz/article/1704/17041303/)
 * [Kingに聞く，ゲームエンジンDefoldの哲学と日本における展望 \- GamesIndustry\.biz Japan Edition](http://jp.gamesindustry.biz/article/1704/17041901/)
[Swift] enumはprotocolに準拠できるので、例えばComparableによってシンプルに比較できる

**前提環境**

- Xcode 10.1
- Swift 4.2

---

Swiftのenumは、protocolに準拠させることで、いろいろな振る舞いを与えることができます。
これは実務では強力な機能であり、ちょっとした工夫によってコードをシンプルにできたりします。

例えば以下のようなことができます。

- Comparableに準拠することで、比較演算子を定義したり
- CaseIterableに準拠することで、allCases プロパティを通して全ての値をコレクションとして取得できたり

コードサンプルで表現するとこんな感じです。

```swift:Playground
import Foundation

/// Tシャツサイズ
enum TshirtSize: String, Comparable, CaseIterable {
    case xs = "XS"
    case s = "S"
    case m = "M"
    case l = "L"
    case xl = "XL"
    case xxl = "XXL"

    // Comparableに準拠すると、この関数を定義しなければならない（定義することで大小比較が可能になる）
    static func < (lhs: TshirtSize, rhs: TshirtSize) -> Bool {
        return lhs.order < rhs.order
    }

    var order: Int {
        // CaseIterableに準拠すると、allCasesで全caseの配列を取得できる
        return TshirtSize.allCases.firstIndex(of: self) ?? 0
    }
}

let m = TshirtSize.m
let l = TshirtSize.l
let xl = TshirtSize.xl

print("\(m < l)")   // true
print("\(l <= xl)") // true
print("\(m > xl)")  // false
```
DirectX11　ゲーム開発　ロックオンカメラを実装してみる　～その１～

# はじめに
DirectX11とVisualStudio2015を使ってこんな感じのロックオンカメラを作ってみました。![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400177/92d8e4a4-95d8-1261-664b-8b7f9b43cb97.png)
常に**プレイヤー(白い戦車)**と**<font color="Red">敵(赤い戦車)</font>**を写すカメラです 
今回はカメラの考え方とロックオンカメラについての解説をしたいと思います。


# 注視点と位置
今回作ったカメラクラスには、注視点と位置があります。
投影行列とかは省略

```c++:カメラクラス
class Camera
{
public:
    DirectX::XMFLOAT3	pos;				//	「位置(座標)」
	DirectX::XMFLOAT3	target;				//	「注視点」
  //========================省略===============================================
};
```
「位置」というのはその名の通りカメラのいる位置（座標）です。  

そして、私が最初に理解できなかったのは「注視点」です。
「最初はカメラの向いている方向ベクトル」だと思っていました。ですがこれは間違いです。
当時はこれがわからなくてとても苦戦しました。
「注視点」は「**点**」です。つまり、**ベクトルではなく座標**なんですね。
見ている方向ではなく見ている点だったわけです。
![注視点と位置の関係.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400177/e900758e-aacc-db74-2501-54e3d71aeea3.png)
（図が下手ですいません）
この図を見ていただくとわかると思いますが target（注視点）にプレイヤーの座標を渡せば常にプレイヤーを写してくれるようになります。

# ロックオン
さて、理屈が大体わかったところでいよいよロックオンカメラの解説に入ります。
「プレイヤーの座標を注視点に渡すとプレイヤーを写してくれる」ので、プレイヤーの代わりにエネミーの座標を渡せばエネミーを常に映してくれそうです。

```c++:Update関数
void Camera::Update(DirectX::XMFLOAT3* enemy_pos)
{
  target = *enemy_pos;  //注視点に敵の座標を代入。
}
```
ここで問題が発生します。このままだと、プレイヤーが画面外に出てしまうことがあります。
プレイヤーと敵を同時にカメラに収めるにはどうすればいいでしょうか。

今回は**プレイヤーと敵の距離のベクトルを使う**やり方で実装しました。
![ロックオンカメラ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400177/49b13403-54d5-fcec-09e8-af87376490ac.png)
要するに「**敵とプレイヤーを結んだ直線上にカメラを設置すればいいよね**」ってことです。
このやり方では、注視点にエネミーの座標と②ベクトルを足した値を、位置にプレイヤーの座標と③のベクトルを足したものを入れています。距離の値に好きな値を入れることでプレイヤーとカメラの距離を変えられるのが利点です。

ちなみに、プレイヤーとエネミーの座標が完全に一致するとカメラがバグります。理由は注視点と位置が重なっているためです。
よくわからない人はとりあえず**<font color = Red>注視点と位置は完全一致させない</font>**ことだけ覚えましょう。

```c++:Update関数
// カメラのy座標が0だと地面に埋まるため、1.0fを代入しています。
//yを高くすると見降ろしになります。
void Camera::Update (DirectX::XMFLOAT3 target_pos, DirectX::XMFLOAT3 player_pos, float distance)	//ロックオンカメラ
{
	// 単位ベクトル取得
	DirectX::XMFLOAT3 player_to_target = DirectX::XMFLOAT3(target_pos.x - player_pos.x, target_pos.y - player_pos.y, target_pos.z - player_pos.z);
	float length = sqrtf(powf(player_to_target.x, 2.0f) + powf (player_to_target.y, 2.0f) + powf (player_to_target.z, 2.0f));
	DirectX::XMFLOAT3 unitvec_player_to_target = DirectX::XMFLOAT3(player_to_target.x / length, player_to_target.y / length, player_to_target.z / length);

	//カメラ位置取得
	pos = DirectX::XMFLOAT3(player_pos.x - unitvec_player_to_target.x * distance, 1.0f, player_pos.z - unitvec_player_to_target.z * distance);

	//注視点取得
	target = DirectX::XMFLOAT3(target_pos.x + unitvec_player_to_target.x, target_pos.y + unitvec_player_to_target.y, target_pos.z + unitvec_player_to_target.z);
}
```
# まとめ
カメラの「注視点」と「位置」を中心にいろいろ話しました。
私もまだ勉強中でよくわかっていない部分もあるのですが、できるだけわかりやすく解説したつもりです。
勉強が進んで新しく発見した事があればまた記事にしたいなと思っています。
機械学習論文読みメモ_165

[Tracking Emerges by Colorizing Videos](https://arxiv.org/abs/1806.09594)
ラベルなしビデオを教師なし学習する事で、visual trackingを実現する手法を提案する。
時間方向の色情報の一貫性を利用する事で、参照フレームの色をコピーする事を通した
グレースケールビデオの色付けタスクをモデルに学習させる。
この学習を通して視覚的の領域のトラッキングをモデルは実現できるようになる。
このモデルはoptical flowよりも高性能を実現できる。

[Gradient Acceleration in Activation Functions][https://arxiv.org/abs/1806.09783]
Dropoutはニューロン同士のco-adaptationを防ぐ事により
過剰適合を防ぐ効果があると考えられてきた。
本論ではDropoutの効果に別の理由つけを提案する。
それは、dropoutは非線形活性化関数のsaturation areaに
入力に対する反応をより押し込むような勾配のaccelerationを
行っている、というものである。
この仮説に基づき、saturation areaへの押し込みを加速させる
gradient acceleration in activation function (GAAF)を提案し、
その効果を確かめた。

[Guided evolutionary strategies: escaping the curse of dimensionality in random search](https://arxiv.org/abs/1806.10230)
多くの機械学習における最適化でsurrogate gradientがtrue gradientの代わりに
用いられてきた。
本論では同様にしてrandom searchに関するsurrogate gradientを提案し、
gradient方向に張られる部分空間への探索を行う事で計算効率を改善する。
gradientは得られたサンプルに対してガウス分布でモデル化しながら計算を
行う。
良いデータ、悪いデータ、普通のデータ

データ処理をする場合、良いデータ、悪いデータ、普通のデータが問題になることがある。

その前に、業務目標(business goal)または最終目標(goal)が大事。

あるいは、制約条件(constraints)が大事。分野によっては要件(requirements)ということもある。

AとBの比較をしたいのか、
A,B,C,D,Eを順番にならべたいのか。
　その際に、同順位を認めるのか
　同順位は３つまで許容するか。

何が一番大きなシェアを占めているのか（上記、A,B,C,d,Eは何かがわかっている場合）
　シェアは50%までわかればいいか
　シェアは90%までわかればいいか
　シェアは99%までわからないといけないか

実害のある要因を１つでもいいからみつけたいのか
　想定できる半分以上の要因を洗い出したいのか
　想定できる90%の要因を洗い出したいのか
　想定できる99%の要因を洗い出したいのか

期待値の精度は１桁でいいか
　期待値の精度は２桁でいいか
　期待値の精度は３桁必要か

# good bad逆転

ある目的ではgood dataが、別の目的ではbad dataであり、
ある目的のbad dataが、別の目的ではgood dataである。

#生与件(raw data)
現地、現物で得た一次情報が大事。

誰かが、何かの目的で篩にかけた情報は、悪いデータ。

計算する上では良いデータのように見えても、価値はぐっと落ちる。

どういう測定方法をとると、どういうばらつきになるか。

#能動測定
受動測定か、能動測定か。
　能動測定の場合には、どのような測定方法をとったかがないとデータの価値がない。

データそのものではなく、データの測定方法がないデータが悪いデータ。

# まとめ

良いデータとは生データ。
悪いデータとは測定方法がないデータ。
普通のデータは、社会的な制度で作成し、公開しているデータ。
　良いデータであるか、悪いデータであるかは目標による。

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
C99 によるガウスの消去法

仕事用に書いた ガウスの消去法実装の抜粋です。より高速であったり高精度であったりする実装は他にあるでしょうが、お目汚しご容赦ください。

特徴は右辺に行列を使えるところでしょうか。右辺に単位行列を入れておくと逆行列が得られます。

# ソースコード

まず前向き消去です。

```c
// Performs Gauss-Jordan elimination to an augmented matrix [A|B] and
// transforms it to a reduced row echelon form.
float eliminate_forward(const size_t n, float a[restrict n][n],
        const size_t n2, float b[restrict n][n2], size_t p[restrict n])
{
    // Minimum absolute pivot value.
    float min_abs_pivot = FLT_MAX;

    // For each row:
    for (size_t i = 0; i != n; i += 1) {
        // Find the pivot.
        size_t pivot_row = i;
        float abs_pivot = fabsf(a[p[i]][i]);
        for (size_t j = i + 1; j != n; j += 1) {
            float abs_a_j_i = fabsf(a[p[j]][i]);
            if (abs_a_j_i > abs_pivot) {
                pivot_row = j;
                abs_pivot = abs_a_j_i;
            }
        }

        // Keep the minimum absolute pivot value.
        if (min_abs_pivot > abs_pivot) {
            min_abs_pivot = abs_pivot;
        }

        // Swap two rows so that the pivot is as large as possible.
        if (i != pivot_row) {
            const size_t w = p[i];
            p[i] = p[pivot_row];
            p[pivot_row] = w;
        }

        // Perform reduction.
        const float a_i_i = a[p[i]][i];
        for (size_t k = i; k != n; k += 1) {
            a[p[i]][k] /= a_i_i;
        }
        for (size_t k = 0; k != n2; k += 1) {
            b[p[i]][k] /= a_i_i;
        }

        // Perform elimination.
        for (size_t j = i + 1; j != n; j += 1) {
            const float a_j_i = a[p[j]][i];
            for (size_t k = i; k != n; k += 1) {
                a[p[j]][k] -= a_j_i * a[p[i]][k];
            }
            for (size_t k = 0; k != n2; k += 1) {
                b[p[j]][k] -= a_j_i * b[p[i]][k];
            }
        }
    }

    return min_abs_pivot;
}
```

次に後ろ向き消去です。

```c
// Performs the second part of Gaussian elimination to an augmented matrix
// [A|B} in a reduced row echelon form.
void eliminate_backward(const size_t n, float a[restrict n][n],
        const size_t n2, float b[restrict n][n2], const size_t p[restrict n])
{
    // For each row in the reverse order:
    for (size_t i = n; i != 0; i -= 1) {
        // Perform elimination.
        for (size_t j = i - 1; j != 0; j -= 1) {
            const float a_j_i = a[p[j - 1]][i - 1];
            for (size_t k = j; k != i; k += 1) {
                a[p[j - 1]][k] -= a_j_i * a[p[i - 1]][k];
            }
            for (size_t k = 0; k != n2; k += 1) {
                b[p[j - 1]][k] -= a_j_i * b[p[i - 1]][k];
            }
        }
    }
}
```

最後に合わせます。

```c
// Performs Gaussian elimination to an augmented matrix [A|B].
float eliminate(const size_t n, float a[restrict n][n],
        const size_t n2, float b[restrict n][n2], size_t p[restrict n])
{
    float min_abs_pivot = eliminate_forward(n, a, n2, b, p);
    eliminate_backward(n, a, n2, b, p);
    return min_abs_pivot;
}
```