OmniAICreator/Qiita-1.07M huggingface dataset:
laravel-database-autodoc パッケージを作成した

数カ月前から仕事でLaravelを扱うようになって3ヶ月。初めてphpのパッケージを作って公開したのでメモがてらに投稿する。

## 何をつくったか?

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132049/7b13d667-2c10-81ab-bad0-e4199e595a05.png)

https://packagist.org/packages/yhirano55/laravel-database-autodoc

## なぜつくったか?

- データベースのスキーマを確認するのが面倒だったので、**機械的にすべてのテーブル定義をマークダウンファイルに出力**するartisanコマンド。
- `php artisan migrate` を実行したら、CommandFinishedイベントを拾って、ドキュメント生成のコマンドが実行される。
- dev dependencyにインストールするだけで、**コマンドの使い方などを覚える必要もなく、ドキュメントを生成/更新してくれる代物**です。

👇こんなマークダウンが自動生成される👇

![Screenshot from 2020-08-11 13-03-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132049/b1bc060d-e2b5-a6f8-66fd-52971ef391bb.png)

## どのようにつくったか?

手順は以下:

1. Packagistにアカウント登録・GitHubアカウントと連携・2FAを設定
2. composer init
3. てきとうなlaravel appに、ローカル環境にあるパッケージをインストール
4. コマンドやイベントリスナーを実装して、サービスプロバイダーを作成
5. アプリケーション側から動作することを確認
6. GitHubにリポジトリを作って、packagistでsubmitしたら公開された

#### Packagistアカウントを準備

[Packagist](https://packagist.org/) は、RubyでいうところのRubyGems、JavaScriptでいうところのnpmで、要はPHP向けのレジストリです。やることはごく簡単で以下の通り:

- アカウント登録
- GitHubとアカウント連携
- 2FAを設定

#### パッケージを作成

```
$ mkdir mylib && cd mylib
$ composer init
```

`composer.json` を作った後、以下を設定した:

- 依存関係（今回はlaravel用のライブラリなのでlaravelを設定。セマンティックバージョニングは5.7以上にする）
- オートロード（autoload => psr-4にロードするディレクトリを指定）

#### 適当なlaravel appにインストール

ローカルパッケージとしてインストールする。以下の記事が参考になった:

https://qiita.com/suin/items/d24c2c0d8c221ccbc2f3

- pathの指定が相対パスだったが、絶対パスにしないとうまくインストールされなかった。
- キャッシュのせいなのか、 `composer install` だけではうまくインストールされず、 `composer update` を実行する必要があった。

動作確認はtinkerで、 `Foo\Bar\LibraryClass` をnewして、hello worldする程度でよい。

#### コマンドやイベントリスナーを実装して、サービスプロバイダーを作成

- コマンドのコードは [こちら](https://github.com/yhirano55/laravel-database-autodoc/blob/master/src/Commands/GenerateDocumentCommand.php)
    - Laravel/frameworkのコンソールの実装を参考に雰囲気で書いた。
    - コード見ればわかるが、`information_schema.tables` の内容を素朴に書き出している。
    - MySQL以外で動作確認していないので、SQLiteやPostgresで動作するかは試していない（OSSなので、もし必要ならば必要だと思った方が実装すればよさそう）
- イベントリスナーのコードは [こちら](https://github.com/yhirano55/laravel-database-autodoc/blob/master/src/Listeners/CommandFinishListener.php)
    - migrateの実行をフックしたかったのだが、どのようにやるべきか調べて、コマンド実行前と実行後にイベントがディスパッチされるので、それを拾って、`Artisan::call()` で実行すればよいのだなと、これもLaravel/frameworkを読んで知った。

サービスプロバイダーは、 `composer.json` の extra => laravel => providers にプロバイダークラスを設定すると、アプリケーション側から自動検出されるようなのでこれを使った。

#### アプリケーション側から動作することを確認

これはそのまんま。

#### GitHubにリポジトリを作って、packagistでsubmitしたら公開された

- GitHubにpublicリポジトリを作って、そこにpush。その後、packagistからリポジトリのURLをSubmitすると公開された。
- 公開後、クロールしているのだなと興味深かった。

## 感想

- 所要時間は2時間程度。
- ローカルパッケージが反映されず苦戦した。
- アプリがコンテナだと当然ローカルパッケージは読み込めないので注意するといい。
- 今回はファイルを生成するだけのコマンドなのでテストは書いていない。
- Laravel/frameworkにパッチを書きたいので、後日テストの所作も調べたい（普通にphpunitだろうけど）
- 普段はRubyやJavaScriptを書くことが多いけれど、phpやlaravelもなかなか面白い。

作ったパッケージはテーブル定義を確認するときブラウザからも見れるので、それなりに便利に利用できています。

```
$ composer require --dev yhirano55/laravel-database-autodoc
```

でインストールできるので、もしよかったらメンテしているLaravelアプリケーションに導入してみてください。
初心者でもできる！かっこいいコミットメッセージの作り方

#はじめに
どうやらGitHubのコミットメッセージにも命名規則のようなものがあるらしいです
全く知らなかったので見返せるようにメモを残します

こちらの記事を参考に日本語訳しています
https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type


#コミットメッセージ

下記のようにコミットメッセージを入力します
>タイプ(ファイル名):作業内容
例）feat(hello.txt):ファイル追加

|タイプ| 意味 |
|:-:|:-:|
| add  |  新機能・新規ファイル追加 |
|  chore |  ツール等で自動生成されたもののコミット |
|  fix |  バグ修正 |
|  update |  バグではない機能修正 |
|  change |  仕様変更による機能修正 |
|  style |  空白、セミコロン、行、コーディングフォーマットなどの修正 |
|  refactor | リファクタリング  |
|  delete |  ファイルの削除、コードの削除 |
|  test |  新しいテストの追加、既存のテストの修正 |
|  docs | ドキュメントのみ修正  |

とりあえず`fix,add,update,delete,style`くらいが使えればいいかな？


#ブランチ名

ブランチ名もできれば上記のような命名規則に従うといいみたいです
Anaconda仮想環境を構築する

python初心者が、地球科学系の研究者に必要な環境の構築を目指しています。

# アンインストール & 再インストール
こちらの記事にしたがって、再インストール。
https://qiita.com/opankopan/items/5171116b1727c3907e86

今回インストールしたのは、**python3.7**です。
(python-cdoがまだpython3.8に対応していないから。)
https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh

PATHの設定をし直す。

```bash:~/.bashrc
export PATH=/home/[myname]/local/anaconda3/bin:${PATH}
```

# 仮想環境の構築

```bash:
conda create -n [name] python=3.7.4
```

環境の切り替えは、

```bash:
conda activate [name] # 起動
conda deactivate # 終了
```

名前をかえたくなったら、
https://qiita.com/TyaoiB/items/b858430c289767cb04be

# 導入したパッケージ
## condaで導入したパッケージ
`conda install -c conda-forge`でインストールすると、適したバージョンを探してくれる。オプション`-y` をつけると、一気にインストールしてくれる。

- python-cdo
- netcdf4
- xarray
- numpy
- pandas
- seaborn
- cartopy -> cdoをダウングレードすることに。先に入れておかないとあとで他のパッケージとconflict起こす。
- cmocean
- branca 
- folium 
- squarify 
- wordcloud
- ipython
- jupyter
- jupyterlab
- plotly
- statsmodels 
- scipy 
- pillow
- click
- conda
- paramiko

## pipで導入したパッケージ
- datetime
- geoplotlib
- janome
- gtool3
- pip install matplotlib==3.2.2 ->新しいversionだと[basemap](##basemap)が動かないので注意！(参考:http://ebcrpa.jamstec.go.jp/~yyousuke/matplotlib/info.html)
- netCDF4 -> errorが出たから入れたけど、condaでinstallしたのと何が違うの？？

## basemapの導入
以下に従った。
https://www.iwass.co.jp/column/column-12.html
Docker × Laravel メールの送信処理をローカルで確認する

ウェブサーバー、アプリケーションサーバー、データベースサーバーが用意されていれば最低限Laravelを動作させることはできますが、実際に開発を進めてくるとメールを送信する処理を書くことが多くあります。

ローカルでのメール確認のためにメールサーバーを用意して、たくさんのメールアカウントを作って、メールを送信して、各メールアカウントでログインして確認...するのはとても非効率です。

そこでメール送信テストツールのMailHogというツールが公式のDockerイメージが提供されています。
こちらを利用すると実際にメールを送信することなく、メール内容をWeb UIで確認できます。

## MailHog

開発者向けのメールテストツール

- https://github.com/mailhog/MailHog
- https://hub.docker.com/r/mailhog/mailhog

## 前提

[最強のLaravel開発環境をDockerを使って構築する【新編集版】](https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4)

当記事は上記の記事の補足になる記事です。

## Laravel環境構築

```shell-session
$ git clone git@github.com:ucan-lab/docker-laravel.git
$ cd docker-laravel
$ make create-project
```

まずはサクッと環境構築します。

## 環境

- PHP 8.1.5
- Laravel 9.9.0

## 手順

### docker-compose.yml を編集する

```
$ docker compose down
```

※`docker-compose.yml` や `Dockerfile` を変更する場合は予めコンテナを破棄しておくと良いです。

```yml:docker-compose.yml
services:
  mailhog:
    image: mailhog/mailhog
    ports:
      - target: 8025
        published: ${MAILHOG_PUBLISHED_PORT:-8025}
        protocol: tcp
        mode: host
```

`mail` サービスの設定を `services` 配下に追記します。
特にカスタマイズは必要ないので、公式の[MailHogイメージ](https://hub.docker.com/r/mailhog/mailhog)をそのまま利用します。

```shell-session
$ docker compose up -d
```

コンテナを作成して起動します。

```
$ docker compose ps
        Name                       Command              State                 Ports              
-------------------------------------------------------------------------------------------------
docker-laravel_app_1    docker-php-entrypoint php-fpm   Up      9000/tcp                         
docker-laravel_db_1     docker-entrypoint.sh mysqld     Up      0.0.0.0:3306->3306/tcp, 33060/tcp
docker-laravel_mail_1   MailHog                         Up      1025/tcp, 0.0.0.0:8025->8025/tcp 
docker-laravel_web_1    nginx -g daemon off;            Up      0.0.0.0:80->80/tcp 
```

`mail` のコンテナが起動していればokです。

### src/.env

`.env` の環境設定ファイルが下記の値になっていることを確認します。

```.env
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_FROM_ADDRESS="hello@example.com"
```

※デフォルト値です。

## メール送信テスト

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

http://127.0.0.1:8025

![ScreenShot 2020-08-10 2.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/12bc05e5-321c-079e-57d8-888fc7684613.png)

![ScreenShot 2020-08-10 2.04.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/96b37453-8bab-6510-83a4-352d3a538d60.png)

## 参考

- [Laravelとdockerの開発環境でMailHogを使ってメール送信する](https://qiita.com/ucan-lab/items/c169258d730a44b76221)
[Rust] PyO3でエラーを返す

Rust で PyO3 を用いて Python 用ライブラリを作成していたのですが, ある関数の入力に関して制約があり (例えば平方根は入力が非負でなければいけない, のような), その制約を満たさない場合にエラー (`ValueError`) を返す方法がわからず手間取りました. 半年くらい後にきっとまた同じことをググる羽目になるんじゃないかと思いますが, それは面倒なのでわかったことをまとめておきます.

※本記事は Rust 1.45.2, PyO3 0.11.1 を使用して2020年8月に動作確認しました.

# 本論

こんな感じになると思います[^1].

[^1]: これは例示のためのコードなので, `NaN` は? とか, `if else` を使えば `return ` 不要, などの突っ込みを入れないでください.

```rust
#[pyfunction]
fn sqrt_rs(value: f64) -> PyResult<f64> {
    if value.is_sign_negative() {
        return Err(pyo3::exceptions::ValueError::py_err(
            "sqrtに負の値が入力されました. 非負の値を入力してください."
        );
    }

    Ok(value.sqrt())
}
```

他にも `pyo3::exeptions` に様々なエラー型が定義されています. 使い方はすべて同じで, `py_err` 関数を呼べば良いです.

* https://docs.rs/pyo3/latest/pyo3/exceptions/index.html

# 解説

Python 側に露出する関数は Rust 側では `PyResult<T>` 型を返しますが, この型は何かというと `PyResult<T> = Result<T, PyErr>` です. ですからエラーが発生したら `PyErr` 型のインスタンスを生成し, `Err` で包んで `return` すればよさそうです. それで, `PyErr` 型ってなんでしょう?

PyO3 では Python の様々なエラー型 (`ValueError` や `TypeError` など) をモジュール `pyo3::exceptions` 内で定義しています. これはすべて Rust 側でも異なる型なので, そのままでは扱いがやや面倒です. そこで PyO3 では様々なエラー型とその値を保持するラッパー構造体 `PyErr` を用意しています. 各エラー型には `PyErr` 型を返す `py_err` 関数が付随していて, これに引数としてその値を渡すことで欲しいエラー型インスタンスを包んだ `PyErr` インスタンスが取得できます.

# 参考文献

* https://pyo3.rs/v0.11.1/exception.html
* https://docs.rs/pyo3/0.11.1/pyo3/struct.PyErr.html
システム監査における　監査手続

平成31年春期 午前問題58

システム監査における"監査手続"として，最も適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/f05408d3-1e87-5573-b39a-b2dfe799f910.png)


１、監査手続とは、
システム監査人が十分かつ適切な監査証拠を入手するための手続のことをいい、予備調査と本調査に分けて実施されます。監査手続で入手した監査証拠は、システム監査報告書に記載する事項の裏付けとなります。
監査手続の手法には、チェックリスト法、ドキュメントレビュー法、インタビュー法、突合・照合法、現場調査法などがあります。


２、監査報告書作成の手順
監査結果を受けて，監査報告書に改善勧告を記述する手順


３、監査計画の立案の手順
監査計画の立案や監査業務の進捗管理を行うための手順


４、監査業務の体制構築の手順
監査テーマに合わせて，監査チームを編成する手順


参照：
https://www.ap-siken.com/kakomon/31_haru/q58.html
システム開発の受入テスト

平成31年春期 午前問題57

システム開発委託先(受託者)から委託元(委託者)に納品される成果物に対するユーザ受入テストの適切性を確かめるためのシステム監査の要点はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d754a5e4-c06e-eede-26c1-3c1a1abbff59.png)


１、受入テストは、委託元で行う
委託先から納品された成果物に対する受入テストは、委託元によって作成されたテスト計画をもとに委託元で行っていることが重要です。もしそうでなければ受入テストに受託側が関与することになり、成果物の不具合を見逃してしまう可能性が高まるからです。

２、受入テスト計画は、委託元で作成する
※受託者から納品された成果物に対して，委託者が要件定義に基づきユーザ受入テストを実施していること
　→ここは、多分、要件定義に基づき、テスト計画書を作成して、テストするだろう。直接に要件定義書によりテストするのはないですね。

３、監査人が受入テスト計画を策定することはありません


参照：

https://www.ap-siken.com/kakomon/22_haru/q59.html

https://www.ap-siken.com/kakomon/31_haru/q57.html
certbot でできるSSL化 (ubuntu 18.04)

# この記事について
EC2上のubuntu 18.04でSSL化対応を行う機会があったので、メモとして残します。
ウェブサーバーはNginxです。

# Certbotインストール
Certbotは無料でSSL証明書を発行できるツールです。
Let’s Encrypt認証局で証明書の発行が行われます。その間をCertbotが取り持ちます。
ターミナル上で以下を実行します。

```
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx
```

# SSL証明書発行
上記でcertbotのインストールが完了です、続いて証明書を発行します。

```
sudo certbot --nginx -d ドメイン名
```
途中、登録用メールアドレスの入力や規約への同意が求められます。

# confへ設定
証明書発行後nginxのconfに設定を書き込みます。

```
listen 443 ssl;
ssl_certificate     /etc/letsencrypt/live/ドメイン名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;
```

# 証明書更新
証明書期限は90日間なので頻繁に証明書更新を行う必要があります。(cronに設定してしまった方が良いかもです。。)
更新は以下コマンドで完了します(期限が30日未満の証明書の更新を行います)

```
sudo certbot renew 
```
pub globalで入れたパッケージをupgradeする

`pub global`で入れたパッケージをupgradeする方法について。`pub global upgrade`のようなコマンドはないのですが、以下のように`activate`コマンドを実行することでアップグレードできます。

```
$ pub global deactivate パッケージ名
```

ちなみに、現在 activated なパッケージの一覧は、以下のコマンドで確認できます。

```
$ pub global list
（以下は例）        
devtools 0.2.4
fvm 1.1.5
stagehand 3.3.1
webdev 1.0.1
```



## 参考

https://github.com/dart-lang/pub/issues/1079
nginxを利用して、tomcatのログをブラウザからダウンロードできるようにする

本記事では、tomcatがすでにサーバー上で動いていることを前提に、nginxを利用してブラウザ上からtomcatのログをダウンロードできるようにする方法を記載します。

簡単に導入でき、かつログを見るためにわざわざサーバーにsshをする必要がなくなるという利点があります。

動作はUbuntu18.04で確認しています。

# nginxをインストール

```
sudo apt-get update
sudo apt-get install nginx
```

`systemctl status nginx` を実行し、**active**になっていることを確認できれば、正常にインストールされています。

```
$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-08-11 02:04:32 WIB; 1h 55min ago
（以下略）
```

# nginxの設定

`nginx.conf`を編集します。

```
sudo vi /etc/nginx/nginx.conf
```

編集内容は以下の通りです。

## `server`コンテキストを追加

`http`コンテキストの中に、`server`コンテキストを追加します。

```nginx.conf
...
http {
  ...
  server {
    listen 8888; # portは任意で変更してください。

    location /logs {
      alias /path/to/logs; # tomcatのログがあるディレクトリを指定します。
      autoindex on; # autoindexオプションでファイルのリストを表示できるようにします。
    }
  }
}
```

## `user` `worker_processes`の設定を変更（任意）
* `user`は、普段sshで利用しているユーザーを指定しておくと、`403 Forbidden`になるのを事前に防げます。
  * 何らかの事情で`user`を変更しない場合、は、後述の方法でも回避できます。
* `worker_process`はnginxが実行する際のworkerの数を指定する設定です。デフォルトでは`auto`になっているのですが、ログをダウンロードするのみであれば（よほどの大人数でサーバーを利用していない限りは）1つで十分なので`worker_processes 1;`としておくことで余計なリソースを使わずに済みます。

## 設定の確認

設定終了後、`nginx -t`を使って設定が正しいかどうかチェックできます。

```
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

正しく設定できていれば、`systemctl reload nginx`で設定をリロードし、ブラウザで表示できているか確認します。
http://<サーバーのIPアドレス>:8888/logs
ログの一覧が表示できていれば、設定完了です。

# 補足：`403 Forbidden`エラーが表示される場合

ユーザーを上記通りに指定しなかった場合、`www-data`ユーザーでworkerプロセスが動いています。

```
$ ps aux | grep nginx
root     21681  0.0  0.0 141252  7084 ?        Ss   02:04   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
# www-dataユーザーでworkerが実行されている
www-data  22293  0.0  0.0 143864  7224 ?        S    04:00   0:00 nginx: worker process
username  22338  0.0  0.0  14428  1048 pts/1    S+   04:42   0:00 grep --color=auto nginx
```

しかし、ファイルの所有者は`www-data`ではないため、nginx上からファイルが見れない、という事象になります。

```
$ ll /path/to/apache-tomcat/ #apache-tomcatフォルダ直下にlogsフォルダがあるという前提
（略）
drwxr-x--- 2 username username       4096 Agu  7 00:48 logs/
```

nginxのユーザーを変更せずに対応したい場合、logsフォルダにReadの権限を与えることで`403 Forbidden`エラーが起きるのを回避できます。

```
# Read権限を再帰的に付与
chmod -R o+r /path/to/logs
# フォルダ遷移するには実行権限が必要なので、併せて付与
chmod o+x /path/to/logs
```

# 参考
* http://nginx.org/en/docs/http/ngx_http_autoindex_module.html#autoindex
pictweetをherokuにデプロイできた

# Herokuにデプロイしよう
　個人アプリを作成する前に、Herokuの環境を整えようと思い、
　スクールで作成したpictweetをデプロイしてみました。

# カンタンでした
　完全に「人の褌で相撲を取る」状態。
　申し訳ないので、自分のために記録しておきます。


# 参考にさせていただきました

### 【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
- アプリの作成〜環境整備
- Gitの登録〜使用開始、コミット方法
- Herokuの登録〜使用開始
- デプロイ〜エラー対処少々

親切過ぎました。正直、少しの知識があればこれだけでOK。
非常に助かりました。

### Herokuにpushしたらprecompile assets faild.が。pushできたと思ったらApplication Errorが。解決するまで。
https://qiita.com/hellojtokyo/items/ef1d4a390f8cbb06f6b7
デプロイの際にエラーが出ました。
こちらの記事を参考にさせていただき、スムーズにクリア！
ポイントは「ログをじっくり見る！」
ありがとうございました！！

### Uglifier::Error: Unexpected character '`'　Herokuデプロイ時のエラー解消方法
https://qiita.com/mikd/items/e10805343f2d7534d52c
上記エラーの詳細がこちら。
じっくりログを見て行った先の内容です。
こちらもスムーズにクリア！

### herokuにgit pushしたURLを開くと、Method Not Allowed と表示されてしまう
 https://qiita.com/kodai_0122/items/a1f01b18bb3e0ddde62a
デプロイ成功後に、一瞬ヒヤッとしたエラー。
とても単純だけど、間違えそうなエラーでした。
FreeRTOSをGoogleTestでUnitTestする with CMake

# 概要
[CMakeを使って、FreeRTOS最小構成のVisualStudioプロジェクト作る](https://qiita.com/azuki_bar/items/fc7ee06dad935a466779)
[CMakeで作るようにした既存のVisualStudioプロジェクトに、GoogleTestを追加する](https://qiita.com/azuki_bar/items/246ec2ce1164df595ac0)
を使って
FreeRTOSをGoogleTestで走らせてみます。

# 手順
## FreeRTOS動作コード
FreeRTOSのカーネルオブジェクト生成、スケジューラ起動をユニットテストの裏で走らせます。
タスクを1つ生成して、"Task 1 is running"を表示させ続けるコードにしておきます。

```c:test_freertos.c
#include "test_freertos.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

/* Used as a loop counter to create a very crude delay. */
#define mainDELAY_LOOP_COUNT		( 0xffffff )

/* The task functions. */
void vTaskSample(void* pvParameters);

void drive_freertos(void)
{
    /* Create one of the two tasks. */
    xTaskCreate(vTaskSample, "Task 1", 1000, NULL, 1, NULL); /* We are not using the task handle. */

    /* Start the scheduler to start the tasks executing. */
    vTaskStartScheduler();

    for (;; );
    return 0;
}
void vTaskSample(void* pvParameters)
{
    const char* pcTaskName = "Task 1 is running\r\n";
    volatile uint32_t ul;

    /* As per most tasks, this task is implemented in an infinite loop. */
    for (;; )
    {
        /* Print out the name of this task. */
        printf(pcTaskName);

        /* Delay for a period. */
        for (ul = 0; ul < mainDELAY_LOOP_COUNT; ul++)
        {
            /* This loop is just a very crude delay implementation.  There is
            nothing to do in here.  Later exercises will replace this crude
            loop with a proper delay/sleep function. */
        }
    }
}
```

## SetUpで `drive_freertos` をスレッドで動かす
ユニットテスト実行の間、FreeRTOSを動作させます。
先ほど定義したdrive_freertosをSetUpで動かしdetachします。(SetUpに関してはgoogletestのドキュメント参照にしてください。ユニットテストの前の準備です。)
※ FreeRTOSはCコードなので `extern "C"` で囲ってあります。

```c++:freertos_unittest.cpp
#include <thread>
#include "gtest/gtest.h"
extern "C"
{
#include "test_freertos.h"
}

class FreeRtosUnitTest : public testing::Test {
protected:
	void SetUp() override {
		std::thread th_freertos(drive_freertos);
		th_freertos.detach();
	}
	void TearDown() override {
	}
};
```

## ユニットテストの実装
バックグラウンドでFreeRTOSタスクが動作していることを買う人するためにsleepを入れています。

```c++:test_sample1.cpp
TEST(FactorialTest, HandlesZeroInput) {
    EXPECT_EQ(1, 1);
}

TEST_F(FreeRtosUnitTest, Sample1) {
    _sleep(100);
    EXPECT_EQ(1, 1);
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    int ret =  RUN_ALL_TESTS();
    return ret;
}
```

実行結果は以下のようになります。
ユニットテストの間に、FreeRTOSタスクが動いていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/91b12fbc-f347-faee-9522-c9d2db8471a4.png)

後はこれを応用して
FreeRTOSアプリケーションのIF経由でテストするようなテストドライバを書けばよいです。

## 上記のコード
CMakenのファイルとか全体的に動かしただけなので汚いですが、、
https://github.com/azukibar0713/cmake_freertos_visualstudio/tree/54f9b66d30bc763bf1a041401851b64bf563c6f4
buildフォルダ以下で `cmake ..` して、作成されたslnファイルを立ち上げれば動きます。
Combine で非同期処理を直列で実行する(flatMap)

## はじめに
Combineを利用していて、RxSwiftでできていたことをどうすればできるか迷ったため調べた際のメモ

## やりたいこと

通信処理Aして、その値を元に非同期処理Bを実行したい。
例)ユーザー情報取得し、その情報をローカルの保存領域に保存する。等

## 環境
Xcode 11.6
Playground

## 結果

RxSwiftと似た形でflatMapを利用すればできる。
同期的に実行するには `maxPublishers: .max(1)` を指定する。

```swift:Playground

var cancellables = Set<AnyCancellable>()

// 非同期処理A
func asyncAAA() -> Future<String, Error> {
    Future<String, Error> { promise in
        // 非同期の処理
        DispatchQueue.main.async {
            print("\(#function)")
            promise(.success("AAA"))
        }
    }
}

// 非同期処理B
func asyncBBB(string: String) -> Future<String, Error> {
    Future<String, Error> { promise in
        // 非同期の処理
        DispatchQueue.main.async {
            print("\(#function) value:\(string)")
            promise(.success(string + "BBB"))
        }
    }
}

// 実行部
asyncAAA()
    .flatMap(maxPublishers: .max(1)) { (value) -> Future<String, Error> in
        asyncBBB(string: value)
    }
    .sink(receiveCompletion: { (completion) in
        print("sink(receiveCompletion: \(completion))")
    }) { (value) in
        print("sink(value: \(value))")
    }.store(in: &cancellables)


```

```console:console
asyncAAA() // 非同期処理Aを実行
asyncBBB(string:) value:AAA　// 非同期処理Aの結果をもとに非同期処理Bが実行
sink(value: AAABBB) // 非同期処理Bの実行結果をsink先で受け取り
sink(receiveCompletion: finished) // Streamの終了
```

## 思考フロー

#### RxSwiftのflatMapはCombineでどう表現するか？
[公式ドキュメント](https://developer.apple.com/documentation/combine/publishers/merge/flatmap(maxpublishers:_:)-2z9wm) でflatMapの役割を確認。
上流のPublisherを変換する役割を担っているため、同じようなことができそう。

> Transforms all elements from an upstream publisher into a new publisher up to a maximum number of publishers you specify.

#### `maxPublishers` は何か？
`maxPublishers` は同時実行回数を指定します。
処理中に割り込みで新規イベントを受け付けないようにするため `.max(1)` を指定しています。
詳細な動作は @yimajo さんの [CombineのflatMapで実行数を制御する](https://qiita.com/yimajo/items/f8968c1936a921a72a17) にとてもわかり易くまとまっていました。
Ubuntu LTS 20.04 でスピーカーが音が出なかった件について

# Ubuntu LTS 20.04 でスピーカーが音が出なかった件について
初投稿の記事です.
拙いところもあると思いますが, なにかの助けになればと思います.

最近使い始めたUbuntu 20.04 でスピーカーが認識されているにもかかわらず音が出ないという問題が発生しました.
極めて困りましたね.

使用しているスピーカーは JBL Pebbles USB接続で特にドライバーなどの設定がいらないものです.

接続をした後サウンド設定上で認識はされており, なおかつ音量バー上ではきちんと音が出ているはずなのですが, 実際スピーカーからは音が出ていないという珍妙極める現象でした.

## 解決法
結論からいいますとalsamixerを使いました.
以下のコマンドを実行します.
```sudo alsamixer```
すると以下のような画面が出ます.
![Screenshot from 2020-08-10 15-47-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689504/60b3ca2d-007b-64ac-48dd-36b9ec69e29a.png)

環境によりけりですが, いくつかのサウンドカードから一つが選ばれて出てくるはずです.
F6を押してサウンドカード選択を行います.　今回は JBL Pebblesを選択します.

![Screenshot from 2020-08-10 15-47-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689504/a27548a4-2960-79e3-050f-8c608e5a3bbc.png)
僕の場合出力側であるPCMの規程値が０(Mute)になっていたので, 上記画像の通り音量を上げました.
(余談ですが, JBLはもとの音量が極めて大きいのでここで小さめに設定しておくことで調整がしやすくなります)

あとはescキーで終了して設定完了です.
ESP32とArduino UNO(ATMEGA328P)の処理速度比較

#ESP32とarduino UNOの処理速度の比較
grbl_ESP32を買う前に、GRBLをarduino unoとESP32に書き込んで
Laser GRBLを使って処理速度の比較をしてました。
（ステッピングモーターつながずに）

ESP32の処理速度がUNOに比べて3～4倍速いことがわかったのでgrbl_ESP32ボードを買うことを決心しました。

UNOで処理した場合（かかった時間は4分。LaserGRBL上では54秒と推測している）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664748/d55afb40-185f-7e27-c120-28f495013c78.png)

grbl_ESP32で処理した場合（実際に動かしている。1分で終了）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664748/14ed336d-c86c-b4c4-d9bf-eb43180b4d0d.png)

見ていると特に空白区間の移動処理に違いがある。
UNOは長い距離を移動させるのに処理時間がかかっている。
空白の長距離移動はGコードとしては1行だが、内部での座標処理に負荷がかかっていると考えられる。

さすがデュアルコア32ビット。（ESP32）
[SwiftUI]R.swiftを使えるようにする



[R.swift](https://github.com/mac-cain13/R.swift)ではまだSwiftUIに対応していないのですが、本家issueに対策があったので書いてみました。
実際に使ってみたところ、かなり快適です。


```swift
import Rswift
import SwiftUI

extension FontResource {
    func font(size: CGFloat) -> Font {
        Font.custom(fontName, size: size)
    }
}

extension ColorResource {
    var color: Color {
        Color(name)
    }
}

extension StringResource {
    var localizedStringKey: LocalizedStringKey {
        LocalizedStringKey(key)
    }

    var text: Text {
        Text(localizedStringKey)
    }
}

extension ImageResource {
    var image: Image {
        Image(name)
    }
}
```

使う際は以下のようにする。

```swift
let font = R.font.myFunnyFontBold.font(size: 35)
let color = R.color.listItemTitle.color
let text = R.string.localizable.hello_world.text
let image = R.image.random_image.image
```

https://github.com/mac-cain13/R.swift/issues/600
不要なデータベースの削除方法(MySQL)

# はじめに
スクールのカリキュラムやドリルで作成した不要なデータベースを削除する際にいろいろと調べましたので、備忘録として残しました。
(誤って削除したデータベースは元に戻せないと思ったほうがいいので、コマンドの実行は自己責任でお願いします。)

# 作業手順

## MySQLにアクセス
以下のコマンドでMySQLにアクセス。（どのディレクトリでも構いません）

```
$ mysql -u root -p
```
パスワードを聞かれるので入力。設定してない場合は「Enterキー」を押して接続。

## DB一覧を確認

まずは「SHOW DATABASES」でDBの一覧を確認。

```
mysql> SHOW DATABASES;
```

一覧が表示される。

```
+-----------------------------------+
| Database                          |
+-----------------------------------+
| test_development                  |
| exp-pictweet_development          |
| exp-pictweet_test                 |
| memo_app_development              |
| memo_app_test                     |
+-----------------------------------+
```

## 削除したいデータベースを指定して削除

```
mysql> drop database test_development;
```
「Query OK」の表示が出れば成功。

```
Query OK, 3 rows affected (0.17 sec)
```

再度「SHOW DATABASES」で削除できているか確認。

```
+-----------------------------------+
| Database                          |
+-----------------------------------+
| exp-pictweet_development          |
| exp-pictweet_test                 |
| memo_app_development              |
| memo_app_test                     |
+-----------------------------------+
```

# 削除できない場合

エラーになる場合は以下の内容を確認しましょう。

１． SQL構文のエラー（データベース名に**「  -  (ハイフン)」**を入れているなど）
２． 削除したいＤＢのフォルダの中に、自分で作成したファイルがないか

## 1.SQL構文のエラー
「exp-pictweet_development」を削除しようとすると以下のエラーで出ます。

```
mysql> drop database mooovi-exam1_development;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-exam-pictweet_development' at line 1
```

SQL構文エラーとなる要素（今回は「-」）が含まれている場合は、**バッククォート(`)**でデータベース名を囲む必要があります。

```
mysql> drop database `exp-exam-pictweet_development`;
Query OK, 8 rows affected (0.09 sec)
```
バッククォート(`) = [shiftキー]＋[@]
※シングルクォートではないので注意

## ２． 削除したいＤＢのフォルダの中に、自分で作成したファイルがないか

DBフォルダ内に自分で作成したファイルがあると削除できません。
取り除くことで、削除できるようになります。

## それでもできなければ…

原因がわからない場合、データベース情報が保存されているディレクトリを丸ごと削除する方法もあるみたいです。


[データベースが削除できない](https://pankuzu.hatenadiary.org/entry/20090224/1235435545)


## 参考記事
[MySQL データベースの削除](https://qiita.com/daijiro_maeyama/items/51c18e451dc3e1fe4c57)
WebRTCで快適な画面共有を 基本編

友人にゲーム画面を共有することが多いのですが、SkypeでもDiscordでもZoomでもSteamのブロードキャストでも、低解像度だったり、解像度は取れていてもビットレートの関係で文字すら読めなかったり(画質が悪い)、遅延がそこそこ長かったりします。
配信知識ゼロから、この一週間で勉強したので、諸々まとめです。
**この記事はやり方を説明するものではないのであしからず。**
#高画質、低遅延配信がしたい！
まあ普通にYoutubeに限定配信してURLを友人に教えれば見る側で手軽に画質変えられるし便利なんですけれど.... なんか自分でやりたくなってしまいました。
ポートの開放ができるなら、RTMPをグローバルIPで外からアクセスさせたり、HLS,MPEG-DASHでCMAF chunkを活用したりと選択肢はあります。
しかし**自分の環境下ではポートの開放ができない**ので、動的に空いてるところを使ってもらうためにブラウザ上でWebRTCを試してみました。
WebRTCのページ共有にngrokを使いましたが、友人側にhtmlを渡してローカルサーバを立ててもらえば不要です。ローカルかhttpsであればいいので、当然Github Pagesとかでもいいです。
ひとまずXSplit Broadcasterを入力として使います。ロゴ入りますが無料でも十分です。
OBS Virtual cameraでもいいですが、XsplitはCPU使用率OBS比で3割くらいで済みます。
今回はSkyway SDKを使わせていただきました。(TURN月500GBまでなら無償で使える)
自分は一対一の共有を想定していたため、TURNサーバの使用のみでSFUはオフにしました。
※テストしたら、自分と友人の場合はTURNサーバオフでも通信できました。
この場合シグナリングサーバとSTUNサーバしか使っていないので、シグナリング月５万回までは制限なしで使えます。最終的にはここも自分で実装予定ですが。
#いきなり問題発生
やけに画質が悪い。
配信ソフトのプレビューは綺麗だし、仮想カメラを他の配信ソフトに入力して見ても綺麗だったので、ブラウザ側の問題と認定。

どうも、デフォルトの帯域がそこまで広くなく、それを超えるものはブラウザ側で自動的に圧縮され、画質が悪くなるようで....恐らく1.5Mbps程度で調整されていました。環境次第？
ブラウザのデフォルトにも、おそらくSkyway SDKのデフォルトにも制限はあるんじゃないかな。
FPS維持優先で、画質が先に悪くなる印象。

##１. 入力ソースの解像度はちゃんと指定しないと圧縮される
getUserMediaでは幅、高さ、フレームレートを指定可能で、理想値を指定したり、最低値最大値の指定ができます。
何も書かず指定だけすると、理想値(ideal)と見なされます。
正直、理想値を下回る分には問題なさそうなので自分の環境で出力し得る最大を入れればいいです。
ソースではとりあえずHD 60fpsで指定してます。
とりあえずこれでプレビューする分には高画質で見れるはずです。
(chrome://media-internals/ で見た感じ、OBS cameraやXsplitの仮想カメラ機能は30fpsまでらしいですが、メディアソースのFPSは60ですし見た目で明らかに60fps対応です。
chromeの画面キャプチャも60fpsは対応してます)

##2. 送るデータの最大ビットレートも指定しないと圧縮される
プレビューは綺麗だけどいざ通信を開始して受信した映像を見ると相変わらずの画質でした。
今度は送信する際になにか制限が掛かっているはずです。
SDPで帯域を指定するには、今回はSkywayのコードを書き換える必要があったり....?
幸いオープンソースなので覗いたところ、javascriptのコードに直に書き込まず、htmlでオプションを追加するだけでした。コードでは14000kbpsにしてあります。まぁ14Mbpsですね。
一応最大ビットレートの指定らしいですが、挙動としては制限というよりもリクエストに過ぎないような気がします。
また、通信途中に帯域変える場合はSDPを弄るのかな？ これはまた別の機会に。

#コード
ありふれてますが一応、htmlのコード [**github**](https://github.com/hinawakasonoko/desktop-tutorial/blob/master/RTC-test.html)
プレビューしやすくするためにオート再生、コントロールは初めからオン。
htmlやjavascriptにはまだ詳しくありませんが、Skywayのリファレンスを見ればほとんどの人が作れるかと。

こいつの問題は、通信しだしてからのメディア変更に対応できないのを無理やり再接続で対応させているということ。
SFU通信の場合などはreplaceStream()が使えるみたいなんですがP2Pだとよくわからず力業です。いろいろ試してみます。
また、共有停止にlocalStream.getVideoTracks()[0].enabled = false; を使うとあくまでミュートでしかなく、元々HD60fpsで送信していた場合、HD60fpsの黒い画面を引き続き送るためビットレート的にはほぼ停止できますが、開封負荷により負荷は下がらない。
ちゃんと停止させる場合はlocalStream.getVideoTracks()[0].stop(); でOK。
今後変わる可能性は大いにあり。
画面共有のほうは共有停止ボタンが出るのでそれ押しても停止できます。

##感想
現在欧州にいますが、東京の友人にTime isを共有して遅延を確認したところ、2秒未満でした
だいぶすごい。しかも電話が同じくらい遅延しているので会話している時は遅延0の感覚です(笑)
加えて、分かりやすく画質方向での改善が大きい。
まあ世の中の画面共有全部これにしたら輻輳の危険性が高まりますがね....
自分も友人もマシンパワーやネットワーク速度を考慮しないで済む環境なのでそこは楽でした。
CMAF chunkによる低遅延HLSでもなんでもそうですが、基本的に低遅延と負荷はトレードオフなのでそれなりにCPU負荷使いますね。特に双方向共有を一つのPCで横に並べて行うと顕著です。
次回はSkyway SDKなしでやってみる感じです。
その後はWebRTCというかP2Pでの画面共有についてもう少し詰めていきます。敢えて遅延があるほうが話しやすい場合もあるので、接続時に遅延を選択できたりすると面白いかも？(受信側でバッファする感じでしょうか)
API周りの理解が皆無で根拠が薄いので、仕様と異なる場合はぜひコメントしてください！
##参考
便利な機能 chrome://webrtc-internals (ローカルリソースなのでリンクは組み込めません)送信ビットレートとかTURNサーバを経由しているどうかなど見れます
Skyway https://webrtc.ecl.ntt.com/
Skyway リファレンス https://webrtc.ecl.ntt.com/api-reference/javascript.html
Windows10 Home環境でのDockerインストール

Windows10 Home環境では、Hyper-Vを利用できないため、Dockerを利用するのは、Windows Pro環境より少々面倒です。以下はWSL2を利用してDockerをWindows Home環境にインストールする手順を示します。

# Windows Homeのアップグレード

WSL2を利用するには、Windows Homeがversion 2004, Build 19041以上である必要がありますので、そうではない場合は、Windows Updateを利用してアップグレードする必要があります。

以下の手順でWindows Homeのバージョンを確認できます。

- **Windowsロゴキー** + **R** で「ファイル名を指定して実行」ダイアログを開く
- 「名前」欄に**winver**を入力し、「OK」ボタンを押す

Windows Homeのアップグレード手順は以下です。

- 「スタート」ボタン→「設定」の順にクリックする
- 表示された「設定」画面の 「更新とセキュリティ」をクリックする
- バージョンアップできる場合は「Windowsの次のバージョンが利用可能になりました。…」のようなメッセージが表示されるので、「**ダウンロードしてインストール**」リンクをクリックして、後はインストーラーの指示のとおりに進めばよい

# WSL2のインストール

- **Windowsロゴキー** + **S** で「Windows検索ボックス」を表示
- 検索欄「**pw**」を入力し、「Windows PowerShellアプリ」が表示されるので、「**管理者として実行**」をクリック
- PowerShellのCLIに「`dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart`」を入力し、実行
- [wsl2-kernelの更新手順](https://docs.microsoft.com/en-us/windows/wsl/wsl2-kernel)に従って、wsl2-kernelを更新する（この手順がないと、次の手順で「**Error: 0x1bc**」エラーが出ることがあります。また、BIOS レベルでのハードウェア仮想化をBIOS 設定で有効にする必要があります。メーカーによって設定方法が違いますので、メーカーのマニュアルに従って対応してください。）
- PowerShellのCLIに「`wsl --set-default-version 2`」を入力し、実行

WSL2のインストール手順は[マイクロソフトドキュメント](https://docs.microsoft.com/en-us/windows/wsl/install-win10)にもあります。

# Docker Desktop のインストール

- [Git for Windows](https://git-scm.com/download/win)をダウンロードし、インストーラーの指示通り、Git for Windowsをインストールする（各インストール画面の選択はすべてデフォルト選択で問題ありません。Dockerのチュートリアル実施に必要となります。Dockerのチュートリアルを実施しない方はこの手順をスキップしてかまいません。）
- [Docker Desktop for Windows](https://hub.docker.com/?overlay=onboarding)をダウンロードし、こちらの[手順](https://docs.docker.jp/docker-for-windows/install-windows-home.html)に従い、Docker Desktopをインストールする
- 初期化が完了すると、Docker Desktop は開始チュートリアルが起動されるので、その手順のとおり、Runの手順まで進む
- ブラウザを立ち上げてアドレス欄に「localhost]を入力し、dockerの「Getting Started」ページが正しく表示されたら、OK
h:buttonタグのonclick属性にEL式を書いて失敗した

- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
    - openjdk version "11.0.7" 2020-04-14 LTS
    - JSF 2.3.9

# 事象 : ページを表示したらHTTPSステータス500になった

```bash:Eclipseのコンソールのログ
2020-08-10T15:17:17.299+0900|警告: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
javax.faces.application.ViewExpiredException: viewId:/base.jsf - ビュー /base.jsf を復元できませんでした。
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:194)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:109)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
    at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:707)
...省略...
```

# 原因 : h:buttonタグのonclick属性にEL式を書いているから
```xml:base.xml
...省略...
<h:button value="アップロード" onclick="#{uploadBean.onClick}"/>
...省略...
```

```java:UploadBean.java
...省略...
/**
 * onClick属性用に出力するJavaScriptコードを取得する.
 * @return JavaScriptコード.
 */
public String getOnClick() {
    StringBuilder builder = new StringBuilder();
    builder.append("window.open('upload.jsf");
    // ...省略...
    return builder.toString();
}
...省略...
```

EL式を書くとうまくいかない理由がよくわからない・・・・ドキュメントに書いてあることが何を言いたのかよくわからないからだろうか？
誰かわかりやすく説明してほしい・・・。

> The entire target URL string must be processed by a call to the encodeResourceURL() method of the ExternalContext. The name of the UIParameter goes on the left hand side, and the value of the UIParameter on the right hand side. The name and the value must be URLEncoded. Each UIParameter instance is separeted by an ampersand, as dictated in the URL spec. The final encoded result will be written out to the onclick attribute of the button as "window.location.href = ''". If the developer has specified a custom onlclick the window.location.href name/value pair will be appended at the end of the developer specified script. 
> [button(JSF 2.1 View Declaration Language: Facelets Variant)](https://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/h/button.html)

(ざっくり訳)
ターゲットURLは、ExternalContextのencodeResourceURLメソッドへの呼び出しによって処理される必要があります。
UIParameterの名前は左側に表示され、UIParameterの値は右側に表示されます。名前と値はURLEEncodedでなければなりません。各UIParameterインスタンスは、URL仕様の指示に従ってアンパサンドで区切られます。
エンコードされた最終結果は、ボタンのonclick属性に"window.location.href = ''"として書き出されます。
開発者がonlclickを指定した場合は、window.location.hrefの名前と値のペアがスクリプトの最後に追加されます。

## 対応 : inputタグのtype="button"に変える
```xml:base.xml
...省略...
<input type="button" value="アップロード" onclick="#{uploadBean.onClick}" />
...省略...
```

### 疑問 : h:buttonタグのonclick属性にEL式を書いてうまくいくこともある

```xml:upload.xml
<h:button value="OK" onclick="submit('#{uploadBean.key}');" />
```

```java:UploadBean.java
...省略...
    public String getKey() {
        return "formId:file";
    }
...省略...
```

```html:出力
<input type="button" onclick="submit('formId:file');window.location.href='/tryJsf/upload.jsf'; return false;" value="OK">
```
Firebaseでユーザー認証を行うときのメソッド

# Firebese Authのメソッド

## 1. createUserWithEmailAndPassword()
文字通りメールアドレスとパスワード認証でユーザーを作成するメソッド 
引数に`email`,`password`を受け取る
戻り値はPromis

```
 .then(result => {
        const user = result.user
```
とすると`user.uid`などで取得しやすい

### firestoreに登録する場合

```
if (user) {
          const uid = user.uid
          const timestamp = FirebaseTimestamp.now()
          const userInitialDate = {
            created_at: timestamp,
            email: email
            uid: uid,
            updated_at: timestamp,
            username: username
          }

          db.collection('users').doc(uid).set(userInitialDate)
            .then(() => {
              dispatch(push('/'))
            })
        }
```
とすることでusersコレクションに登録される。ちなみに`db`の中身は`firebase.firestore()`になっていて、処理が完了するとルートパスに戻る。

## 2.signInWithEmailAndPassword()
上記で作成したアカウントにログインするメソッド
引数にemail, passwordを受け取る
上記同様に実行結果を定数に入れることで扱いやすくなる
firebase Authでサインインした場合アプリ側にもstateを更新する必要があるので、以下のようにする

```
if (user) {
          const uid = user.uid

          db.collection("users").doc(uid).get()
            .then(snapshot => {
              const data =snapshot.data()

              dispatch(signInAction({
                isSignedIn: true,
                uid: uid,
                username: data.username
              }))
              dispatch(push("/"))
            })
        }
```
データベースからuidが一致する情報を引っ張り、`signInAction`を実行しreduxのstateを変更している(reduxではactionsは変更を伝える役割で実際にはreducersがどう変更するか決めている)
jsGridの使い方について

# jsGridとは
> jsGridは、jQueryに基づく軽量のクライアント側データグリッドコントロールです。挿入、フィルタリング、編集、削除、ページング、ソートなどの基本的なグリッド操作をサポートしています。jsGridは柔軟で、その外観とコンポーネントをカスタマイズできます(http://js-grid.com/)。

# jsGridができること
公式から一部紹介します。
- フィルタリング
- データ編集(レコードの追加、更新、削除)
- ページング
- 並び替え

# 環境構築
今回はCDNを使います。
一つのファイルにまとめていますが、複数ファイルに分けても問題ありません。

## ファイルの中身
まず、初めにcdnリンクを記載していきます。

```html:index.html
<html>
  <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
  <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
  <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
  <!--ここから下にこの後、記載します-->
</html>
```

次に、jsGridを適用させたい箇所を指定します

```
<div id="jsGrid"></div>
```

最後に、グリッドを作成します

```
<script>
    var clients = [
        { "Name": "Otto Clay", "Age": 25, "Country": 1, "Address": "Ap #897-1459 Quam Avenue", "Married": false },
        { "Name": "Connor Johnston", "Age": 45, "Country": 2, "Address": "Ap #370-4647 Dis Av.", "Married": true },
        { "Name": "Lacey Hess", "Age": 29, "Country": 3, "Address": "Ap #365-8835 Integer St.", "Married": false },
        { "Name": "Timothy Henson", "Age": 56, "Country": 1, "Address": "911-5143 Luctus Ave", "Married": true },
        { "Name": "Ramona Benton", "Age": 32, "Country": 3, "Address": "Ap #614-689 Vehicula Street", "Married": false }
    ];
 
    var countries = [
        { Name: "", Id: 0 },
        { Name: "United States", Id: 1 },
        { Name: "Canada", Id: 2 },
        { Name: "United Kingdom", Id: 3 }
    ];
 
    $("#jsGrid").jsGrid({
        width: "100%",
        height: "400px",
 
        inserting: true,
        editing: true,
        sorting: true,
        paging: true,
 
        data: clients,
 
        fields: [
            { name: "Name", type: "text", width: 150, validate: "required" },
            { name: "Age", type: "number", width: 50 },
            { name: "Address", type: "text", width: 200 },
            { name: "Country", type: "select", items: countries, valueField: "Id", textField: "Name" },
            { name: "Married", type: "checkbox", title: "Is Married", sorting: false },
            { type: "control" }
        ]
    });
</script>
```

## 出力結果
下記のようなグリッドが表示されます。
![スクリーンショット 2020-08-10 15.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554111/3c5a2157-9427-7ddd-377d-5d06ff351ba3.png)
今回は表示するデータをあらかじめ用意していますが、動的なデータを表示することも可能です。

# 参考リンク
公式：http://js-grid.com/
nanoをvimにする

# 備忘録
ubuntuでcrontabの編集を行うと毎回nanoが出てくるのでエディタの設定変えておく

```
select-editor
```

```
Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny

Choose 1-4 [2]: 3
```
Visual Studio Code + WSL2でGo開発環境構築

WindowsからTeraTerm等のターミナルソフトを使って、Linuxサーバにssh接続し、Linux上で開発をすることは、一般的に行っていると思う。しかし、Windows用のVS CodeのIntellisenseやdebug機能を使いたい！と思うこともよくある。そんなことが、WSL2を使うことで簡単にできちゃうので、紹介してみる。

## インストール
### Remote Development Extention
VS Codeの画面左側の`Extensions(Ctrl + Shift + X)`メニューで、`Remote Development`を検索し、インストール。とっても簡単。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/e1064208-ba60-ac63-65fe-aa650728f9c2.png)

### WSL2 + Linux Distribution
ググればわかりやすいページがたくさんヒットするので、頑張りましょう。なお、私も書いてたりします。
[Windows 10でLinuxを使う(WSL2)](https://qiita.com/whim0321/items/ed76b490daaec152dc69)

### Go tools
WSL2上のLinuxにGo Toolsをインストールする。Distributionで用意しているパッケージでもいいかもしれないが、私は何となく最新版をインストールした。[Getting Started - The Go Programming Language](https://golang.org/doc/install)を見れば、簡単にインストールできる。
インストール後、`$HOME/.profile`に以下のPATH設定をお忘れなく。

```
GOPATH="$HOME/go"
PATH="$PATH:/usr/local/go/bin:$GOPATH/bin"
```

## Go on Linux on WSL2
### モジュール初期化
Linux上で、以下のコマンドを実行し、モジュールの初期化を行う。

```
mkdir hello
cd hello
go mod init hello
```

### VS Code起動
上記で作成した`hello`ディレクトリで、以下のコマンドを実行。Windows上でVS Codeが`hello`ディレクトリをオープンした状態で起動する。

```
code .
```

VS Codeの画面左下に`WSL: XXXXX`と表示されていれば成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/27189bb8-bd49-00f1-4f33-18ce530a825c.png)

### Go Extentionのインストール
VS Codeで、`hello.go`を作成すると、`Go Extention`のインストールを勧められるので、`Install`をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/38062910-dd5e-7b47-43ae-e4011c66893c.png)

インストール完了後、`Reload Required`をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/1300b08f-80cc-61f5-63a8-1e2b81b22d11.png)

この後、ソースコードの編集、実行時に`Update`や`Install`の問い合わせが何回かあるが、基本的に言われるがままに実行する。

### Go build
ソースの編集後、`Ctrl + F5`で、コマンドパレットが開くので`Go`を選択。

```golang:hello.go
package main

import (
	"fmt"
)

func main() {
	msg := "Hello, Wold!"
	fmt.Println(msg)
}
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/098547c9-252d-6f28-a258-e9def2e33851.png)

下記のように、`DEBUG CONSOLE`に`Hello, World!`と表示されればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/c646dd0b-b8c7-3f1c-915f-85dc54610aa1.png)

`Ctrl + F5`を実行するたびに、`Go`を選択するのは面倒なので、画面左の`Run(Ctrl + Shift + D)`メニューをクリックし、`create a launch.json file`をクリックし、コマンドパレットから`Go`を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/75cdbaa2-61da-5083-8ded-0ad766a4979f.png)

`launch.json`ファイルが開くが、編集は不要なので、そのまま閉じる。これで、`Ctrl + F5`実行時の問い合わせがなくなる。

### Debug
`F5`キーによりデバッグもできる。ソースコードの行番号の左側をクリックすることでブレークポイントを設定。`F5`キーを実行すると、デバッグ開始しブレークポイントで処理が止まる。あとは、`Continue(F5)`、`Step Over(F10)`、`Step Into(F11)`等で遊びましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253975/7f2bbfe4-6121-3aa2-a166-621e9dfc5ed3.png)


## リンク
* [The Go Programming Language](https://golang.org/)
* [Remote Development Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
* [Go Extension](https://marketplace.visualstudio.com/items?itemName=golang.Go)
JupyterLabでコード補完（jupyterlab-kite）

# JupyterLabとは
- Jupyter notebookの後継で、いろいろな機能が追加されている
- 参考：https://qiita.com/kirikei/items/a1639954ce5ccaf7ac3c

# JupyterLabの課題
- デフォルトではTabを押さないとコード補完（autocomplete）されない
- そのため、いくつかコード補完のextentionが提案されている
- ここでは、jupyter-kiteについて紹介する

# jupyterlab-kiteとは
- AIコーディング支援kiteのjupyterlab拡張
    - https://github.com/kiteco/jupyterlab-kite
- Tab等のキーを押さなくとも、**完全自動**で、コード補完が行われる。
    - jupyterlab-lspでは、.(ドット)のタイプが必要だったが不要！
        - https://qiita.com/fugaga/items/10553501a9fc69d92206
    - notebookのhinterland相当のものがなかった中、ようやく出てきた感がある。そしてhinsterlandよりもすごい。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630200/dea7bccb-1991-85c7-41cc-66aef7919ee0.png)

# jupyterlab-kiteのインストール方法
## 概要
- CUIだとエラーが出るが無視しても動作する
- アカウント作成やログインをしなくとも動作する

## 検証環境
- ubuntu (Windows10 WSL)
- anaconda
- python(3.8)
- jupyterlab(2.2)

## インストール方法
### conda環境の準備

```
conda create -n jupyter_test python=3
conda activate jupyter_test
```

### kiteのインストール

```
bash -c "$(wget -q -O - https://linux.kite.com/dls/linux/current)"
```

ここで、以下のエラーが出るが無視する

```
[installer] error enabling kite-updater.timer. exit status 1, output: 'Created symlink /home/xxxx/.config/systemd/user/basic.target.wants/kite-updater.timer → /home/xxxx/.config/systemd/user/kite-updater.timer.
Failed to connect to bus: No such file or directory
'
ROLLBAR error failed to enable updater service [install error enabling kite-updater.timer exit status 1 Created symlink /home/xxxx/.config/systemd/user/basic.target.wants/kite-updater.timer → /home/xxxx/.config/systemd/user/kite-updater.timer.
Failed to connect to bus: No such file or directory
 Linux DESKTOP-HDE6IOT 4.4.0-18362-Microsoft #836-Microsoft Mon May 05 16:04:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux
]
dropping rollbar event due to filtering
[installer] registering kite:// protocol handler
[installer] error installing kite protocol handler. exec: "xdg-mime": executable file not found in $PATH, output: ''
ROLLBAR error failed to enable kite:// protocol handler [install error running 'xdg-mime default kite-copilot.desktop x-scheme-handler/kite' exec: "xdg-mime": executable file not found in $PATH  Linux DESKTOP-HDE6IOT 4.4.0-18362-Microsoft #836-Microsoft Mon May 05 16:04:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux
]
dropping rollbar event due to filtering
[installer] kite is installed! launching now! happy coding! :)
[installer] run /home/xxxx/.local/share/kite/kited
[installer]     or launch it using the Applications Menu
Removing kite-installer
```


### jupyterlab,jupyter-kiteのインストール

```
conda install -c conda-forge jupyterlab nodejs
pip install jupyter-kite
jupyter labextension install "@kiteco/jupyterlab-kite"
```

### jupyterlabの起動

```
jupyter lab
```
scipy で cubic データ補間のメモ

## 背景

* データ点を通る補間をしたい
* (optional)データ点が範囲外のところも補間してほしい(extrapolate)

## scipy

ちょうどよく `scipy.interpolate.interp1d` があります. 

https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html

```py
x = ...
y = ...

f = scipy.interpolate.interp1d(x, y, kind='cubic', fill_value='extrapolate')
```

f はオブジェクトなので, 実際には

```
z = ...

matplotlib.pyplot.plot(z, f(z))
```

みたいな感じで使います.

# TODO

* [ ] catmullrom 曲線をためす
  * numpy, scipy には標準では実装されていない
配列内にあるオブジェクトを取り出して、スタイル要素に適用する。

#やること
配列の中にあるオブジェクトの色要素を取り出して、表示させる文字の色にオブジェクトの色要素を割り当てるプログラムです。

##ソースコード
全体のソースコードは以下の通りになります。（headタグやvueの読み込み箇所は省きます。）

HTMLファイルのソースコード

```vue
        <div id="app">
            <ul>
                <li v-for="(addColor,index) in colors">
                    <span :style="colors[index]">
                        {{addColor.color}}
                    </span>
                </li>
            </ul>
        </div>
```

jsファイルのソースコード

```javascript

var app = new Vue({
    el: "#app",
    data: {
        colors: [
            {
                color: "red",
            },
            {
                color: "blue",
            },
            {
                color: "green",
            },
        ],
    },
});

```


##ソースコードの解説
コードを書く順番で見ていきます。
###色データの作成

```javascript
data: {
        colors: [
            {
                color: "red",
            },
            {
                color: "blue",
            },
            {
                color: "green",
            },
        ],
    },
```

配列の中に３つのオブジェクトがある状態です。
具体的に説明すると`data`の中に`colors`という名前の配列があり、その配列の中のオブジェクトに`color`というキーの名前と文字列が入っています。

###配列の中身を一つずつ取り出して、表示させている。（反復処理、リストレンダリング）

```vue
<!-- (オブジェクト,インデックス番号) -->
<li v-for="(addColor,index) in colors">
～
</li>
```
`colors`配列の中から、オブジェクトとインデックス番号を引数として取り出しています。

###オブジェクト内にある文字列を取り出して、スタイルで色を割り当てる。

```vue
<span :style="colors[index]">
    {{addColor.color}} <!-- オブジェクト内になる文字列を表示 -->
</span>
```
`vue`で`style`属性の操作を行うため、`v-bind`をつけます。
その`style`属性の中で、配列の中身をインデックス番号で指定することによって、指定した先にあるオブジェクトを取り出しています。その結果、表示させている文字色に合わせて色のスタイルが割り当てらるようになります。
![Qiita ２回目.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689023/cdb9971b-a6a3-3b2d-117a-8f6f994ac2b9.jpeg)

#最後に
基礎のv-ifやv-forだけでも、簡単なことから複雑なことまでたくさんのことができるので、これからどんどん挑戦していきたいと思います。

最後まで読んでいただきありがとうございました。
この記事が少しでもあなたのお役に立てば幸いです。
DynamoDB Local で pythonを使っての採番処理の作成 準備編

## 概要

pythonの採番処理を作成するときにDynamoDBを使うときに開発中に実際のDynamoDBを使うのは・・・という場合DynamoDB Local を使っての開発すると思うのでその方法をまとめていきます。
まずは準備としてdockerのコンテナを作ってテーブルの作成まで行います。

## 事前準備
* dockerをまず導入します。windows Homeの場合は **Docker Quickstart Terminal** を使います。
* aws cli もインストールします。
    * aws cli インストール後 aws config で設定を行います。**region** , **aws_access_key_id** は設定してください。後続の処理でコマンドが実行できないため。値は適当でも大丈夫です。

## docker fileの設定
* データを永続化させるため [こちら](https://qiita.com/okashoi/items/f1c757279574d37b812e)を参考にdocker-compose.yml,Dockerfile を作成します。実際に使ったのは以下のものです。

* docker-compose.yml

```yml
version: '3.7'

services:
  dynamodb:
    build: ./dynamodb
    volumes:
      - dynamodb_data:/home/dynamodblocal/data
    ports:
      - 8000:8000
    command: -jar DynamoDBLocal.jar -dbPath ./data

volumes:
  dynamodb_data:

```
* Dockerfile

```
FROM amazon/dynamodb-local

WORKDIR /home/dynamodblocal

# UID=1000 → DynamoDB Local の実行ユーザ
RUN mkdir data && chown -R 1000 data
```

* **docker-compose up** のコマンドを使うとコンテナが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657697/8e320f0e-adeb-49a6-6255-05d4831755b2.png)


## テーブルの作成
* [こちら](https://dev.classmethod.jp/articles/development_environment_using_dynamodb_local/)を参照にまずスケルトンJSONを作成します。以下のコマンドを実行します。
    * aws dynamodb create-table --generate-cli-skeleton > skel_dynamodb_create-table.json
* jsonファイルにテーブル定義を作成します以下のように作成しました。

```json
{
    "AttributeDefinitions": [
        {
            "AttributeName": "sequence_key",
            "AttributeType": "S"
        }
    ],
    "TableName": "sequences",
    "KeySchema": [
        {
            "AttributeName": "sequence_key",
            "KeyType": "HASH"
        }
    ],
    "BillingMode": "PROVISIONED",
    "ProvisionedThroughput": {
        "ReadCapacityUnits": 1,
        "WriteCapacityUnits": 1
    }
}
```

* 以下のコマンドでテーブルを作成します。
    * aws dynamodb create-table --cli-input-json file://skel_dynamodb_create-table.json  --endpoint-url http://localhost:8000
        * **Docker Quickstart Terminal** の場合はlocalhostをIPに変えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657697/0b004831-f8a9-dc5c-d76e-4529a52bd43a.png)

* コンテナのほうでアクセス権がない場合は以下のようなエラーログが出るので注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657697/bdcd25f2-2d3f-0add-1a91-7f9e64a5857c.png)

* テーブルが作成されたかの確認は **DynamoDB shell** から行えます。
* http://localhost:8000/shell/ にアクセスすることでブラウザ上で確認ができます。
    * **Docker Quickstart Terminal** の場合はlocalhostをIPに変えてください。
    * CTRL+スペースキーで補完ができるので適当にやってみるといいかも
* 下記のコマンドで作成されているテーブルの確認ができます。テーブルを作成したときのリージョンとAWS Access key を合わせないとみることができないので設定を忘れずに。
    * リージョンを `ap-northeast-1` に設定していますがこちらはawsconfigでの設定値に合わせてください。
    * 右上の方の歯車のアイコンでaws_access_key_id を設定してください。

```
dynamodb.config.update({
 region: "ap-northeast-1"
})
dynamodb.listTables().eachPage(function(err, data) {
    if (err) {
        ppJson(err); // an error occurred
    } else if (data) {
        ppJson(data);
    }
});
```