OmniAICreator/Qiita-1.07M huggingface dataset:
OpenFOAM v8 Docker Image on Macのカスタマイズ

# はじめに
[OpenFOAMv8(Foundation版)](https://openfoam.org/)をMacにインストールした後，イメージをカスタマイズする方法をここにまとめておきます。
インストールなどの詳細はこちらの[Qiitaページ](https://qiita.com/posa/items/d7a79544d1ecd14f739d)やこちらの[cfdengineのページ](https://www.cfdengine.com/blog/how-to-install-openfoam-anywhere-with-docker/)も参考になると思います。

# Dockerのインストール

[Dockerサイト](https://hub.docker.com/editions/community/docker-ce-desktop-mac)から，Docker Desktopをダウンロード，インストールします。ここでは特筆事項はありません・・・（楽でいいですよね）。

インストールが終了しましたら，Docker Desktopを起動します。こんな感じで右上にクジラマークが現れます。

![Screen Shot 2020-10-17 at 23.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/044cabb6-de45-8029-18c5-b92f300b3e92.png)

# OpenFOAMv8のインストール
Foundationにある[Foundation](https://openfoam.org/download/8-macos/)に従ってインストールします。`openfoam`というディレクトリを作成し，その中で，以下のコマンドを打ち込みます。

```haml:本家から抜粋
sudo curl --create-dirs -o /usr/local/bin/openfoam8-macos http://dl.openfoam.org/docker/openfoam8-macos
sudo chmod 755 /usr/local/bin/openfoam8-macos
```

# OpenFOAMコンテナ
`openfoam`のディレクトリ内で以下のコマンド（スクリプト）を実行することにより，OpenFOAMの環境が立ち上がります。

```bash
openfoam8-macos
```
これでblockMeshやsolversが使えるようになっています。

# イメージのカスタマイズ
まず，イメージのIDを確認します。

```bash
docker images
```

![Screen Shot 2020-10-16 at 22.37.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/e99b715c-01de-ed30-a2da-35c8d142c2be.png)

この__Image ID__をメモしておきます。その後，rootでImageを立ち上げます。

```bash
docker run -it -u=root <Image ID>
```

スクリプトで立ち上げた場合は，aptなどでアプリをインストールしても，記録されません。が，rootで起動した場合はカスタマイズや各種設定変更はコンテナに記録されます。この状態で自分の所望のアプリをインストールします。

その後，コンテナを停止（ログアウト），__Container ID__を確認します。

```
docker ps -a
```

変更を加えたコンテナをイメージにcommitさせます。

```
docker commit <container ID> <Repository>
```
`Repository`ですがデフォルト設定を活かし，`openfoam/openfoam8-graphical-app`としておくのが良いです。ここで`Repository`を自分の好きな名に変えることも可能ですが，その際は起動スクリプト`/usr/local/bin/openfoam8-macos`内のDOCKER_IMAGESを修正する必要があります。

たとえば，Repositoryをopenfoam8としたいのであれば，

```bash:example
docker commit <container ID> openfoam8
```
```bash:openfoam8-macos
DOCKER_IMAGE='openfoam8' 
```
とします。

個人的には，`lv`, `gmsh`，`git`, `htop`, `python3.8`, `ffmpeg`, `cmake`, `gfortran`, `python3-pip(numpy, pandas, torch, tensorflow, scikit-learn, Pillow, matplotlib)`は入れておくと便利かなと思います。[^1] [^2]
以上でカスタマイズは終了です。お疲れさまでした。

[^1]: torchインストール時に[ここ](https://github.com/pytorch/pytorch/issues/1022)にあるようなエラーでインストールできないという事象が発生しました。torchを[ここ](https://files.pythonhosted.org/packages/38/53/914885a93a44b96c0dd1c36f36ff10afe341f091230aad68f7228d61db1e/torch-1.6.0-cp36-cp36m-manylinux1_x86_64.whl)から直接ダウンロードし，pip3でインストールすることにより解決できます。または，`pip --no-cache-dir install torch`としても解決することができます。

[^2]: calculix-cgx, pkg-config



# 最後に
OpenFOAMのDockerイメージのカスタマイズ方法をまとめたサイト，ページが見当たらなかったこともあり，ここにまとめてみました。まだ，Dockerの使い方を理解できていない，使い切れていないこともあり，ベストなやり方であるかは分かりません・・・。より良いやり方があれば，ご指摘いただければ嬉しいです。
Ansible 初心者がplaybook～roleを学ぶ ① 検証用VM作成

Ansibleで単一playbookからroleを使った構成を学ぶまでに行ったことを記述します。

<注意>この記事では、
環境作りを記載しているため、Ansibleはまだ出てきませんので、ご了承ください。

検証を行うPCは、Windows10でvirtualbox、vagrantを用いて
環境構築を行う一貫として一旦、空のVM作成をゴールとしています。

###1. virtualbox,vagrantのインストール
参考記事：https://qiita.com/tarosaiba/items/a2769c8152dd3702778e

###2. virtualbox(vagrant)でVMを3つ作成する。

|vm name|ip address|os|memory|cpu core|
|:-:|:-:|:-:|:-:|:-:|
|ansible|192.168.16.11|centos7.2|2GB|1core|
|web|192.168.16.12|centos7.2|2GB|1core|
|db|192.168.16.13|centos7.2|2GB|1core|

#####2-1. デスクトップにフォルダ作成
   　　Desktop配下　
　　　　・Ansible-test/vagrant-ansible
　　　　・Ansible-test/vagrant-Web
　　　　・Ansible-test/vagrant-db
![Ansible1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664515/119faa8d-b92d-72a4-ba0a-14e8344195b0.png)
　
#####2-2.  コマンドプロンプトでvagrantのbox（centos7.2)を追加する。
    > vagrant box add centos7.2 https://github.com/CommanderK5/packer-centos-template/releases/download/0.7.2/vagrant-centos-7.2.box
    > vagrant box list
     centos7.2 (virtualbox, 0) 　　　　　 << box:centos7.2が追加された。

#####2-3.  コマンドプロンプトでvagrantfileを作成　（vm:ansibleの場合）
　※db,webの場合は『移動先フォルダ』変わるので注意！！
    
    > cd C:\Users\{ユーザ名}\Desktop\Ansible-test\vagrant-ansible
    > vagrant init

以下のように、vagrantfileが生成される。
![Ansible2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664515/fc45579e-0c42-cbbd-6be1-28c99f85459f.png)

#####2-4. vagrantfileをメモ帳で中身を削除して以下のように編集する。
![Ansible3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664515/1e692917-14d1-961e-1deb-7186b84bbafb.png)

```shell

<ansible:コピペ用>
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos7.2"

# VMのIPアドレスを設定(host only adpter) 
 config.vm.network "private_network", ip: "192.168.16.11" 

# os上でのVM名指定
 config.vm.hostname = "Ansible"

# VM名指定（virtualbox上の名前）、メモリサイズ指定
 config.vm.provider :virtualbox do |vb|
     vb.name = "Ansible"
     vb.memory = "2048"
     end
end
```
#####2-5.　『web』、『db』も同様に、2-3．～2-4．を繰り返す。
★注意2-4．vagrantfileをdb、webで、それぞれ以下パラメータ部分修正する！

```shell
<dbの場合、以下のパラメータを修正>
config.vm.network "private_network", ip:"192.168.16.12"
config.vm.hostname = "db"
vb.name = "db"

<webの場合、以下のパラメータを修正>
config.vm.network "private_network", ip: "192.168.16.13" 
config.vm.hostname = "web"
vb.name = "web"
```
#####2-6．VM作成（vm:ansibleの場合）※db,webの場合は『移動先フォルダ』変わるので注意！

``` 
> cd C:\Users\{ユーザ名}\Desktop\Ansible-test\vagrant-ansible　
> vagrant up
``` 
※vagrant up実行した際に
  Host only adpter追加のポップアップ[virtualbox interface]が出た場合はOKする。
　
####2-7．db,webも2-6の作業を行う。
virtualboxに空VMが3台作成されたらゴール
![Ansible4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664515/8c75589c-a961-07d3-5f27-c8959814141f.png)

-追伸-
ビルド＆デストロイを容易にするためにWindowsのbat化させました。
何かの機会に公開するかもです。以降の手順作るのに創造と破壊を繰り返すことになったため…。

####次回Link>>[Ansible 初心者がplaybook～roleを学ぶ ② Ansibleインストール](https://qiita.com/showa-engine/items/3cf27ed02d135fc8a87f)
GCPコンソールのpythonアップデートで詰まっている②（解決編）

#前回のあらすじ

aptが動けるようにした
pipを入れた
pyenvを入れた
pythonをインストールできない！←ここ

#前回出ていたエラー（おさらい）


```
$ pyenv install 3.7.4
Downloading Python-3.7.4.tar.xz...
-> https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
Installing Python-3.7.4...
BUILD FAILED (Ubuntu 16.04 using python-build 1.2.21)
Inspect or clean up the working tree at /tmp/python-build.20201015120257.27370
Results logged to /tmp/python-build.20201015120257.27370.log
Last 10 log lines:
    sys.exit(ensurepip._main())
  File "/tmp/python-build.20201015120257.27370/Python-3.7.4/Lib/ensurepip/__init__.py", line 204, in _main
    default_pip=args.default_pip,
  File "/tmp/python-build.20201015120257.27370/Python-3.7.4/Lib/ensurepip/__init__.py", line 117, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/tmp/python-build.20201015120257.27370/Python-3.7.4/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip._internal
zipimport.ZipImportError: can't decompress data; zlib not available
Makefile:1132: recipe for target 'install' failed
make: *** [install] Error 1

```


#参考にしたサイト

「Ubuntu16.04でpyenv3.7系の環境構築にひたすら躓いた話」
https://qiita.com/kenta_ojapi/items/6b19e0c05b268f3e74da

「【pyenv】ubuntu16.04でのpython環境の構築」
https://qiita.com/banaoh/items/00aea13fe045fab7e8ba

#実際の手順

```
$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
```

https://github.com/pyenv/pyenv/wiki/Common-build-problems を見ろとのことなので、こちらに記載のある以下のコマンドにて解決。
というコメントを信じて詠唱。
中身は全く理解していないが、必要なものをインストールしてくれるのだろう。

再度Pythonインストールも、失敗。
zlibがないと言われるのでインストール

```
sudo apt-get install zlib1g-dev
```
インストール失敗。やたら時間がかかるのに結局失敗するのが痛い。

```
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
```

とあったので、bzip2　libを個別にインストール。

すると、うまくいった。

```

Installed Python-3.7.4
```

を見たときの達成感と言ったら無い。

#今後

ゴールしたみたいなテンションでここまで作業した＆書き記したが、
APIを使って何か作る、というのがゴールなので、
まだスタート時点にやっとたどり着いたぐらいである。

また気合を入れて向き合う必要がある。
AtCoder 生活　97日目

[前回]()

#97日目
今回はABC178のA〜C問題をときました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC178|A|◯|45秒|
|ABC178|B|◯|2分23秒|
|ABC178|C|✕|68分47秒|


##[ABC178](https://atcoder.jp/contests/abc178)

###A

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int x;
    cin >> x;
    if(x == 1)cout << 0 << endl;
    else cout << 1 << endl;
}

```

解くのにかかった時間：45秒

###B

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll a,b,c,d;
    cin >> a >> b >> c >> d;
    ll ans = max({a*c,a*d,b*c,b*d});
    cout << ans << endl;
}

```

解くのにかかった時間：2分23秒

###C

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const ll MOD = 1e9+7;

int p(int x,ll n){
    ll a = x;
    rep(i,n-1){
        a = a*x%MOD;
    }
    return a;
}

int main(){
    ll n;
    cin >> n;
    ll a = p(10,n);
    ll b = p(9,n);
    ll c = p(8,n);
    ll ans = (a - b - b + c)%MOD;
    ans = (ans + MOD)%MOD;
    cout << ans << endl;
}

```

解くのにかかった時間：68分47秒
感想：最後にMODを足してMODで余りを出す理由を知りたい


###最後に
Cの回答がなぜこれで通るのかわからなかった
【StereoDepth】StereoNet :高速Stereo Matching！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c4771650-a325-0cb3-3dd6-d9802ade7a33.png)

StereoNetが[GC-Net](https://qiita.com/minh33/items/1cbcba8f40841997938f)よりメチャクチャ早かったからその理由を見ていきたい。


<h1>Feature Extraction</h1>
Feature Mapの解像度を小さくする
1. 大きなreceptive field＝＞texture lessの場所に役立つ
2. feature vectorをコンパクトに出来る。

<h1>Cost Volume</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b0da4afa-d97c-e435-6972-55f0f978ba53.png)
ほとんどの計算時間が3D convolutionに使われる。
入力の画像を小さくする事で粗いが早くDisparityを求める事が出来る。


<h1>Hierarchical Refinement: Edge-Aware Upsampling</h1>
Cost Volumeで得た粗いDisparityを出力の解像度までupsamplingする。
color画像とupsampleしたDisparity Mapを結合し、ネットワークでDisparityを再度推定する。
color画像からedgeなどを見つけて、refineしてくれる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/724c554d-7b62-0599-e69a-08cfe3e59512.png)


<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/49f3e72c-38f5-a018-6207-443956945eec.png)
k = 8で0.015sの速度が出た。しかし精度はそこまで低下していない。

<h1>結論</h1>
Cost Volumeの3D Convolutionを小さくすれば計算は早くなる。


<h1>参考文献</h1>
StereoNet: Guided Hierarchical Refinement for Real-Time Edge-Aware Depth Prediction
https://openaccess.thecvf.com/content_ECCV_2018/papers/Sameh_Khamis_StereoNet_Guided_Hierarchical_ECCV_2018_paper.pdf
javascriptのLocalStorage を使ってお気に入り機能を自作してみた ③実装編-組み込み-

# どうも7noteです。プラグインより多機能なお気に入り機能を作成。前回の続き

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/jsfavorite-3/
[初学者] AWS デプロイ時のエラー解決に役立ちそうなコマンドや知識

###背景
AWSへのデプロイ時に多くのエラーに悩まされたため、記事にまとめようと思いました。
私と同じような初学者の方の役にたてば嬉しいです！


---
###構成
私自身はRuby on Rails, VPC/EC2（Nginx,Unicorn）/RDS(PostgreSQL)/Route53/ALBを使用してデプロイしました。
デプロイ時に参考にした記事
https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce
https://qiita.com/Yuki_Nagaoka/items/1f0b814e52e603613556

---
###共通

psコマンドを使用することでプロセスを確認することができます。
psコマンドについて参考にした記事
https://eng-entrance.com/linux-command-ps

```
$ ps -x 　　　　　　　　　　　#現在実行中のプロセスを確認するコマンド
```

- - -
###アプリケーション関連
デプロイ先のアプリケーションで`we're sorry, but something went wrong.`と表示されてしまった場合。アプリに問題があるか確認します

```ruby:サーバー環境　/var/www/rails/アプリ名
$ cd log
$ tail -n 30 production.log
```
エラーの記載があるとアプリケーションに問題があります。特にエラーの記載がなければ、Webサーバーの設定に問題があり、正常にデプロイできていない可能性が高いです。

---
###nginx関連

・nginxが起動しているか確認

```ruby:サーバー環境
$ sudo systemctl status nginx
```
`Active: active (running) ` と表示されていれば起動しています。

・再起動コマンド

```ruby:サーバー環境
$ sudo service nginx restart
```

・nginxのファイルにエラーがあるか確認

```ruby:サーバー環境
$ sudo nginx -t
```

エラーがある場合はエラー箇所を教えてくれる便利なコマンドです。特にnginxのファイルに問題がなければこのように表示されると思います。
`nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful`


---
###Unicorn関連

Unicornのログを確認するコマンド。
よくあるエラーとしては、不要なプロセスが残っている場合に発生する `Already running on PID:(プロセス番号)`が挙げられると思います。



``` ruby:サーバー環境/アプリのディレクトリ 
$ cat log/unicorn.log -n
```

Unicornのプロセスの確認コマンド

```ruby:サーバー環境
$ ps -ef | grep unicorn | grep -v grep
```

Unicornのプロセスを終了するコマンド
 `Already running on PID:(プロセス番号)`のエラーが発生した際は、こちらのコマンドで不要なプロセスを消すことでエラーが解決すると思います。

```ruby:サーバー環境
$ kill (プロセス番号)
```

---
###PostgreSQL関連

PostgreSQLが起動しているか確認するコマンド
` Active: active (running) `となっていれば起動しています。

```ruby:サーバー環境
$ systemctl status postgresql.service
```

PostgreSQLを起動させる

```ruby:サーバー環境
$ sudo systemctl enable postgresql
$ sudo systemctl start postgresql
```

---
###その他
####GoogleChrome, http関連
GoogleChromeでデプロイしたアプリケーションにアクセスすると、強制的にhttps（https化未実施の時）にアクセスして、アプリケーションが開きませんでした。
解決策は、Chromeの履歴→閲覧履歴データの削除→キャッシュされた画像とファイルにチェックを入れ、履歴データを削除することでした。

下記のコマンドでレスポンスを確認することができます。
webサーバのファイルにエラーもなく、curlコマンドでレスポンスがしっかりと返って来るのに、httpsにリダイレクトしてしまう場合は、この問題の可能性もあります。


```
$ curl http://example.com 　　#http://example.com はアプリのドメイン。
```

また、httpで接続する場合は
`config.force_ssl = false`にしておく必要があります。

```ruby:config/environment/production.rb 
$ config.force_ssl = false 
```


####https化
当初はWebサーバーのファイルを編集することで、https化をしようと考えましたが、AWSのALBというサービスを使用する方がhttps化は容易であると知ったため、ALBを使用しました。初学者の方でhttps化に手こずっている方は、ALBを使用するのが個人的におすすめかなと思います。
ALBを使用することで、httpリクエストをhttpsにリダイレクトすることができます。

[htttps化の参考にした記事]
https://aws.amazon.com/jp/premiumsupport/knowledge-center/elb-redirect-http-to-https-using-alb/
https://dev.classmethod.jp/articles/alb-redirects/
この他にも「ALB https リダイレクト」と検索すると参考になる記事がたくさん出てきます！
ボタンを押すとブラウザに画像を表示できる

### ボタンを押すとブラウザに画像を表示できるようにする
canvas要素を指定してキャンバス上に表示したい画像を表示します。（別にcanvas要素以外の要素でも問題ありません）

canvas要素にid属性を指定して後でjavascriptで取得できるようにします。
2つのbutton要素にはonclick属性を指定して、ボタンをクリックしたときにそれぞれ関数が発火するようにします。appearメソッドを発火させたときは指定した画像を表示して、disappearメソッドを発火させたときは表示した画像を消去できるようにします。
img要素にはsrc属性に表示したい画像を設定して、id属性を指定して後で取得できるようにします。style属性には「display: none;」を指定してappear関数が発火するまで表示されないようにします。

```
<body>
  <canvas id="canvas" width="500" height="500"></canvas><br>
  <button onclick="appear()">表示</button>
  <button onclick="disappear()">非表示</button>
  <img src="#" id="img1" style="display: none;">
</body>
```

script要素内では、変数ctxを定義します。

appear関数内は定数canvasにbody内のcanvas要素を取得させ、変数ctxに代入してcanvas要素に画像を表示する準備をします。
変数imgにbody要素内のimg要素を取得させ、「drawImage( )」メソッドでキャンバスに画像を表示させます。
「drawImage(image, x, y, w, h)」メソッドはimageの部分に「img要素かvideo要素かcanvas要素」を指定できます。今回は静止画の表示なので「let img = document.getElementById("img1");」で代入したimgを指定します。xはキャンバスの左上隅からのx座標、yはキャンバス左上隅からのy座標、wは表示する画像の横幅、hは表示する画像の縦幅を指定します。
勘違いしやすいところですが、数学で学ぶ座標は中心から右に向かうとxが増え、上に向かうとyが増えますが、canvasを使うときはcanvasの左上隅が座標（0,0）で右に向かうとxが増えるのは同じですが、yは下に向かうと増えます。

disappear関数内は1行だけですが、「clearRect( )」メソッドで表示した画像を消去しています。
「clearRect(x, y , w, h)」メソッドは指定した（x, y）座標からwで指定した横幅、hで指定した縦幅分、四角形の形でクリアすることができるメソッドです。

```
  <script>
    let ctx;

    function appear() {
      const canvas = document.getElementById("canvas");
      ctx = canvas.getContext("2d");

      let img = document.getElementById("img1");
      ctx.drawImage(img, 100, 100, 300, 300);
    }

    function disappear() {
      ctx.clearRect(0, 0, 500, 500);
    }
  </script>
```

以下のコードをコピーして、ファイルに貼り付ければ試すことができます。（body内img要素のsrc属性の#はお持ちの画像に変更してください。drawImageメソッド内のw,hもお持ちの画像のアスペクト比に合わせて変更してください）

```
<!DOCTYPE html>

<html>

<head>
  <meta charset="UTF-8">
  <title>image</title>

  <style>
    button {
      width: 100px;
      height: 30px;
      margin-right: 10px;
    }
  </style>

  <script>
    let ctx;

    function appear() {
      const canvas = document.getElementById("canvas");
      ctx = canvas.getContext("2d");

      let img = document.getElementById("img1");
      ctx.drawImage(img, 100, 100, 300, 300);
    }

    function disappear() {
      ctx.clearRect(0, 0, 500, 500);
    }
  </script>
</head>

<body>
  <canvas id="canvas" width="500" height="500"></canvas><br>
  <button onclick="appear()">表示</button>
  <button onclick="disappear()">非表示</button>
  <img src="#" id="img1" style="display: none;">
</body>
</html>
```
tkinterでコンボボックスの変化によって動きを変える

ソースコードは以下になります。

```python 
import tkinter
from tkinter import ttk

colors = ['Red', 'Green', 'Blue']
subcolors = ["Black", "White"]


def add_combobox_subcolors():
    def inner(self):
        cb_subcolors.config(values=subcolors)
        cb_subcolors.set(subcolors[0])
        cb_subcolors.pack()

    return inner


root = tkinter.Tk()
root.geometry("200x200")
root.title("Color Picker")

cb_subcolors = ttk.Combobox(root, values=colors, width=10, state='readonly')

cb_colors = ttk.Combobox(root, values=colors, width=10, state='readonly')
cb_colors.set(colors[0])
cb_colors.bind('<<ComboboxSelected>>', add_combobox_subcolors())
cb_colors.pack()

root.mainloop()
```

colorsのコンボボックスの選択を変えるとサブカラーのコンボボックスが出現します。
colorsのコンボボックスの選択時にサブカラーのコンボボックスが持つリストも代入しているので、
最初のコンボボックスで選択された要素によって追加するコンボボックスの内容を変えたい場合に有効です。

最後まで読んでいただきありがとうございました。
またお会いしましょう。
KeyURIFormatに対するGoogleAuthenticatorとIIJ Smartkeyの挙動

* Google Authenticatorは、algorithm, digits, periodは無視される。
* IIJ Smartkeyは対応。

# デフォルト値
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
https://www1.auth.iij.jp/smartkey/uri_v2.html

| parameter | Google Authenticator | IIJ Smartkey |
|:-:|--:|--:|
| algorithm  | SHA1  | SHA1 |
| digits  | 6  |  6 |
| period  |  30 |  30 |

# Google Authenticator をインストールしていれば、otpauthリンクがブラウザから読み込める
テスト用に以下を載せてみる。

| Google Authenticator Version | IIJ Smartkey |
|:-:|:-:|
|5.1.0 |2.1.4

※追記：Qiitaではotpauthリンクはエスケープされてしまってダメでした。
→[CodeSandBox](https://codesandbox.io/s/intelligent-sun-5j9sm?file=/index.html)に作りました。

* base
[RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC](otpauth://totp/test1:siersetup1@example.com?secret=RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC&issuer=test1&algorithm=SHA1&digits=6&period=30)

* Period 30→15
[RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC](otpauth://totp/test2:siersetup2@example.com?secret=RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC&issuer=test2&algorithm=SHA1&digits=6&period=15)

* algorithm SHA1→SHA256
[RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC](otpauth://totp/test3:siersetup2@example.com?secret=RRORAXAO5UU5METGC6PHMVQ3HHEFEDZC&issuer=test3&algorithm=SHA1&digits=6&period=15)

リンクからすべて生成されるが、おそらくすべて、同じ値で、同じ更新間隔になるだろう。

# 結果
| アプリ | 表示値の違い |
|:-:|:-:|
| Google Authenticator | すべて一致 |
| IIJ Smartkey  | すべて不一致 |
GoogleAuthenticatorは仕様どおり、オプション群は効いておらず、結果はいずれもやはり同じでした。
IIJ Smartkeyは、仕様通り、オプション群はすべて効いており、3つのリンクそれぞれから生成される値はすべて異なりました。

※Google Authenticatorはキャプチャが禁止されているようで取れず（当たり前）。
ABCの昔の問題を解いてみる(ABC 005 D)


#[AtCoder ABC 005 D](https://atcoder.jp/contests/abc005/tasks/abc005_4?lang=ja)

これまで研究が忙しいとか何とか理由をつけて競プロを長いことサボりまくっていたが、この前のARCで少し熱を取り戻したのでABCの古い問題を解いてみることにした。
加えてこれまで基本Pythonを使い続けてきたが、最近C++にちょっと慣れてきたのでこの際全部C++で書いてみる事にした。慣れてる人からみると、「へっ、汚ねえコードだ(某王子)」って思うかもしれないが所詮自分用のメモだしOKや

ABC005D(問題の詳細は[リンク先](https://atcoder.jp/contests/abc005/tasks/abc005_4?lang=ja)で見てください)
たこ焼きに関する問題です。(語弊)

関西出身でたこ焼きとともに成長してきた(?)身としてこれは是非とも解きたい。
##解法
<b>これは２次元の累積和ですね間違いない(脊髄反射)。</b>

とりあえずまずは入力部と累積和の部分を書いてみよう(見切り発車)。

```C++
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

int main(){
    int N;
    cin >> N;
    vector<vector<ll> > D(N+1, vector<ll>(N));
    
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            cin >> D[i][j] ;
        }
    }
    vector<vector<ll> > CS(N+1, vector<ll>(N+1)); /*CSはCumulative Sum(累積和)のつもり */
    
    for(int x = 0; x < N; x++){
        for(int y = 0; y < N; y++){
            CS[x+1][y+1] = CS[x][y+1] + CS[x+1][y] -CS[x][y] + D[x][y];
        }
    }
}
```

CS[x][y]は長方形[0,x), [0,y)内のDの総和。

今欲しいのは長方形の面積が「P以下」という縛りの元での最大値だから、面積「P」の長方形のそれを全部あげてみる。
(※さも簡単にわかったふりをしてるがここまででかなりの思考時間を費やしている)

```C++
    vector<ll> maxval(N*N); /*配列のi番目に面積iの長方形で総和が最大のものを収納*/
/*xlはxlow, xhはxhighのつもり、なんでもいいが*/
    for(int xl = 0; xl < N; xl++){
        for(int xh = xl + 1; xh <= N; xh++){
            for(int yl = 0; yl < N; yl++){
                for(int yh = yl + 1; yh <= N; yh++){
                    ll P = (xh-xl)*(yh-yl);
                    ll sum = CS[xh][yh] -CS[xl][yh] -CS[xh][yl] + CS[xl][yl];
                    maxval[P] = max(maxval[P],sum);
                }
            }
        }
    }
```

正直に告白すると最大値を更新するところを忘れててなんで上手くいかないんだ！？と長い時間苦しんでた。

ここまでくればあとは面積「P以下」での最大値に各maxval[i]を更新する。これは次のようにすれば良い。

```C++
    for(int i=0; i<N*N; i++){
         maxval[i+1] = max(maxval[i+1],maxval[i]);
    }
```
あとは各店員さんのPについてmaxvalを表示すればOK

```C++
    ll Q;
    cin >> Q;
    vector<ll> P(Q);
    for(int i=0; i<Q; i++){
        cin >> P[i];
    }
    for(int j=0; j<Q; j++){
        cout << maxval[P[j]] << endl;
    }
```
これで元の問題の入力例２

```C++
3
3 2 1
2 2 1
1 1 1
3
1
4
9
```
を入れると

```C++
3
9
14
```
と正しい解が得られた。

他にもパッと解がわかる例を入れてみると

```C++
5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
4
1
4
3
2
```
で

```C++
9
32
24
17
```
になったので大丈夫そうだ。

#感想
この店はたこ焼き器を買い直すべきである。
pygameを用いてパズル＆ドラゴンズのドロップを操作するゲームをこれから作る

今回、ある程度python、pygameを学んできたところで何かひとつ作ってみようと思い、
自分の好きなゲームであるパズドラを簡易であるが作ってみることにした。
進捗状況は随時更新していきたい
(ちなみに創作物は初めてです)

まずは、画像を動かせるようにした

```python:paz.py
for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
    elif event.type == MOUSEBUTTONDOWN:
        mousedown = True
    elif event.type == MOUSEMOTION:
        if mousedown:
            x,y = event.pos
            #マウスと画像の位置が一致するようにx、yを調整
            x -= int(image.get_width() / 2) 
            y -= int(image.get_height() / 2)
    elif event.type == MOUSEBUTTONUP:
        mousedown = False
```
MOUSEBUTTONDOWNでマウスを押した時
MOUSEMOTIONで移動している時
MOUSEBUTTONUPでマウスを離した時
を考える。
これではただ動かしているだけでパズドラらしさがないので、
次は、話したときにブロックにはまるようにしてみる
Cityscapes datasetのlabelなど

## 概要
* 以下に書いてある通り
https://www.cityscapes-dataset.com/dataset-overview/#class-definitions
  * ただしidは不明
* コード上は以下
https://github.com/mcordts/cityscapesScripts/blob/25e802b9f8afe03e64c9c80f58dc96aed6b1f559/cityscapesscripts/helpers/labels.py#L62-L99

* taskごとにまとめると以下


## Semantic Segmentation

19のclass。また実装上は「背景(19のどれにも属さない)」を合わせた20を使う。

| id | name |
|:-:|:-:|
| 7 | road | 
| 8 | sidewalk |
| 11 | building |
| 12 | wall |
| 13 | fence |
| 17  | poll |
| 19 | traffic light |
| 20 | traffic sign |
| 21 | vegetation |
| 22 | terrain |
| 23 | sky |
| 24  | person  |
| 25  | rider  |
| 26  | car  |
| 27  | truck  |
| 28  | bus  |
| 31  | train  |
| 32  | motorcycle  |
| 33  | bicycle  |


## Instance Segmentation

全部で8種

| id | name |
|:-:|:-:|
| 24  | person  |
| 25  | rider  |
| 26  | car  |
| 27  | truck  |
| 28  | bus  |
| 31  | train  |
| 32  | motorcycle  |
| 33  | bicycle  |
Nuxt.jsでpictureタグのコンポーネントを作る

# 手順1
http://scottjehl.github.io/picturefill/
ここでjsをダウンロードして、`static/assets/js/picturefill.min.js`に配置

# 手順2
`nuxt.config.js`でjsファイルを読み込ませる

```javascript:nuxt.config.js
export default {
  head: {
    script: [{ src: '/assets/js/picturefill.min.js', async: true }]
  }
}
```

# 手順3
イメージコンポーネントの作成

```html:components/atoms/photo.vue
<template lang="pug">
.a-photo
  template(v-if="res")
    picture.a-photo-picture
      source(v-bind="bindSource")
      img.a-photo-img(v-bind="bindImg")
  template(v-else)
    img.a-photo-img(v-bind="bindImg")
</template>

<script>
export default {
  props: {
    src: {
      type: String,
      required: true
    },
    alt: {
      type: String,
      required: false,
      default: ''
    },
    ext: {
      type: String,
      required: false,
      default: 'png'
    },
    res: {
      type: Boolean,
      required: false,
      default: false
    },
    static: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  computed: {
    breakPoint: () => 768,
    bindSource() {
      return {
        srcset: this.static
          ? `/assets/image${this.srcset('pc')}`
          : require(`~/assets/image${this.srcset('pc')}`),
        media: `(min-width: ${this.breakPoint}px)`
      }
    },
    bindImg() {
      return {
        srcset: this.static
          ? `/assets/image${this.srcset('sp')}`
          : require(`~/assets/image${this.srcset('sp')}`),
        alt: this.alt
      }
    }
  },
  methods: {
    srcset(type) {
      return `${this.src}${this.res ? '_' + type : ''}.${this.ext}`
    }
  }
}
</script>

<style lang="stylus" scoped>
.a-photo
  line-height 0

.a-photo-picture
  display block

.a-photo-img
  width 100%
  height auto
</style>
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
【JavaScript】連想配列の配列に対して、同じkeyの値を足し合わせたい

## やりたいこと

下のような連想配列（オブジェクト）の配列があったときに、同じkeyの値の合計を求めたいことがありました。(きれいなデータを想定しています。valueはすべて数値です。)

```javascript
const objs = [
    {key1: 100, key2: 200, key3: 300},
    {key1: 100, key2: 150, key3: 100},
    {key1: 100, key3: 200, key4: 100},
]

sumObjects(objs)
// {key1: 300, key2: 350, key3: 600, key4: 100}
```

シンプルに書けないかと考えてはみたのですが、うまい書き方が見つかりません（Python3.9のように単純に足す(+)ことはできない）。

なので、結局
「結果を入れる空の連想配列を用意して、配列の中の連想配列を１コずつ見ていく。その中のkeyごとに値を足していく。」
という手続きをそのまま書きました。

## やったこと

```javascript
function sumObjects(objs) {
    return objs.reduce((res, obj) => {
        for (key in obj) {
            key in res? res[key] += obj[key]: res[key] = obj[key]
        }   
        return res 
    }, {})
}
```
とりあえず書いてしまいましたが、もっとうまい書き方を募集中です。

※ @standard-software さんに指摘いただいた内容を修正しました。(2020-10-17 06:11追記)
　 修正前のコードは`reduce`に初期値が指定されておらず、引数のオブジェクトを破壊していました。

## 気を付けたこと
・４行目、`res[key] += obj[key]`だけで大丈夫かなと思ったのですが、連想配列に存在しないキーを指定すると`undefined`となり、足した結果が`NaN`となってしまいダメでした。

## 終わりに
たぶん、Pythonの`collections.Counter`のように、この問題に適した道具があるんだろうなと思いつつ書きました。
良い方法を見つけたら書き足したいと思います。

※ いただいたコメントがとても良い内容ばかりです。(2020-10-17 06:11追記)
　 本文よりもむしろコメント欄のほうを見てもらいたい気持ちでいっぱいです。ぜひどうぞ！

以上、お読みいただきありがとうございました。
エンジニア転職への第一歩

と、大袈裟にタイトルを付けてみたが
日々の学習のアウトプットやプログラミング関連の情報を
定着させる目的で投稿することにした。

生を受けて今年で29年目。
今まで日記すらまともに書いたことがなく、
学生の頃の読書感想文すら毎年泣きながらやっていた自分からすると
思ったこと、感じたことを文章化することが難しいと感じる、今日この頃。

だが、この年で効率よく知識やスキルを身につけるには
何にせよ”アウトプット”が大事だと言うことを知り、
アラサーになってようやく動き出す。

こういった些細な自己発信も
これからの時代を生き抜くには必要だろう。

まずは、週に1記事投稿を目標に習慣化し継続していきたい。
バケットソートとは？メリデメとコード実例

#バケットソートとは？
各要素の数をカウントし、その要素を入れる配列番号を特定して、順に挿入していくソート方法。

用意する配列は２つ。

**(1)カウンタ配列**
各要素が何個あるかカウントする。


**(2)ソート結果を入れる配列**
ソートしたい配列と同じ要素数を持った配列を用意し、(1)で特定した要素を個数分だけ挿入していく。


<br>
**▼バケットソートのイメージ**
[1,3,2,1,2,1]の配列の場合

1,2,3の入れ物（バケツ）を用意し、そこに各要素を入れて数をカウントする。（例：１は３つ、２は２つ、３は１つ）

その要素を順に並べていく。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/fc3169ba-71bd-6d84-7a0f-330b5853ad7d.png)


>[参考：wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%82%BD%E3%83%BC%E3%83%88)



##バケットソートのメリデメ
###・メリット
直感的でわかりやすい。計算量ベースでは最速のソートアルゴリズム。

最大値が小さく、同じ数値が何度も重複する場合に効率的なソート。


###・デメリット
元の配列の最大値が大きい場合、その最大値分のバケツを用意しなければいけない。

下記条件の時には使えない。
・整数以外（小数点を含む）
　┗ バケットを用意できないため

・最大値が大きすぎる
　┗ カウンタ配列のメモリ使用量が膨大になってしまうため


<br>
**▼デメリットの例**（無駄なバケツが発生することを明示的に理解する）

list=[1,2,1,10]を並び替える場合
3~9は存在しないが、その分のバケツも用意しなければならない。

|バケツ：| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|要素の数：| 2  | 1  | 0  | 0  | 0  | 0  | 0  | 0  | 0  | 1  |

最大値が小さければソートは早いが、**最大値が大きくなればなるほど用意するバケツの数も増える**。



<br>
##バケットソートのコード実例

```python:
def bucket_sort(arr):
  arrc = [0]*(max(arr)+1)

  #カウンタ配列の作成。0始まり。0番目は常に０
  for i in arr:
    arrc[i] += 1

  #ソート結果を入れる配列を用意
  ans=[]

  for j in range(1, len(arrc)):
    ans.extend([j]*arrc[j])
  
  return ans 
```

配列を足し合わせるextendを使う。
※appendは１つのまとまった要素として追加されるため、ここでは使えない。


```python:確認
list=[8,3,1,2,3,3,10,7,6,7]
bucket_sort(list)

#[1, 2, 3, 3, 3, 6, 7, 7, 8, 10]
```



<br>
###extendを使わない方法

```python:
def bucket_sort2(arr):
  arrc = [0]*(max(arr)+1)

  #カウンタ配列の作成。0始まり。0番目は常に０
  for i in arr:
    arrc[i] += 1

  #ソート結果を入れる配列を用意
  ans=[]

  for j in range(1, len(arrc)):
    ans = ans+[j]*arrc[j]
  
  return ans
```

各バケットは同じ深さのため、単純に足していく。

```python:確認
list=[8,3,1,2,3,3,10,7,6,7]
bucket_sort2(list)

#[1, 2, 3, 3, 3, 6, 7, 7, 8, 10]
```



<br>
###累積和から挿入位置を決めていく方法
カウンタ配列を累積和に変換し、指定の要素を挿入する場所を見つけていく。

要素が重複している場合も考慮して、右から挿入したら、その要素が挿入される場所を-1する。


```python:
def bucket_sort3(arr):
  #配列内の最大値の数だけ要素数がある配列を作る。
  #累積和を求める時に、-1の要素を参照するため0からカウントする。
  arrc = [0] *(max(arr)+1)

  #配列の要素の数をカウント
  #指定の配列番号に１を足していく
  for i in arr:
    arrc[i] += 1

  #カウントを累積和に変換する。
  #現在の要素に一つ前の要素を足して、置き換えていく
  for j in range(1, len(arrc)) :
    arrc[j] = arrc[j] + arrc[j-1]
  
  #ソート結果を入れる配列を作る。配列の要素数は元の配列と同じ
  arrs = [0]*len(arr)
  
  #元の配列の要素を一つづつ取り出して、何番目に入るか調べて挿入していく
  for i in arr:

    #iを何番目に挿入するか調べる。ソート後の配列は0が不要のため、-1した場所に挿入する
    #同じ数が複数ある場合は一番右側から左に向かって埋めていく
    arrs[arrc[i]-1] =i
   
    #同じ要素が複数ある場合を考慮し累積和から、自分iの要素の数を一つ減らす
    arrc[i] -= 1

  return arrs
```

```python:確認
list=[8,3,1,2,3,3,10,7,6,7]
bucket_sort3(list)

#[1, 2, 3, 3, 3, 6, 7, 7, 8, 10]
```

教材で累積和を使う方法が紹介されていたので処理を紐解いてみたが、正直、直感的にわかりにくい。
Git hub でプルしようとするとPermission denied(publickey)エラーが出てしまう場合の対処法

Git　habでプルをしようとしてコマンド実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693241/0d1f393d-69c8-683a-b78f-a1c2a7d90bb2.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693241/8389df3b-2f18-1cd6-540b-f6ae6887f2f6.png)

このようなエラーが出てしまいます。

その場合は、ターミナルから

```
% git pull
```

を実行しましょう。

その際、
`fatal: not a git repository (or any of the parent directories): .git`

のエラーが出た場合は、

```
% ls -a  
```
で戻って

`.git`があるところまで、戻りましょう。場合によっては２階層くらいあるかもしれません！

`.       ..      .git    mysite  venv`

この表示になったら、先ほどのコマンド実行してください。
Azure Static Web AppsでVue.jsをはじめーる

※2020年10月16日 21時23分 (JST)の記事です

Chrome拡張機能をいれる
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=ja

gachimoto-vue-appで作成

git cloneする

Project setup

~~~
npm install
~~~
Compiles and hot-reloads for development

~~~
npm run serve
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/61d0b3da-533a-c219-d1c2-6a582adc46b1.png)

Chromeからアクセスしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/47bbfe0a-033c-df6b-ea0d-715590d8d7e5.png)

~~~index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app">
      <h1> {{ product }} are in stock. </h1>
    </div>

    <script src="https://unpkg.com/vue"></script>
    <script src="main.js"></script>
    <!-- built files will be auto injected -->
  </body>
</html>
~~~

~~~main.js
const app = new Vue({
  el: '#app',
  data: {
    product: 'Boots'
  }
})

/**
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
*/
~~~

main.jsを変更したらサーバーを再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/3b19cc95-dbf2-98be-b73b-e8f6618b8ad6.png)

imageの貼り方
https://greko-engineer.hateblo.jp/entry/2020/03/05/231242

表の作り方など
https://www.sejuku.net/blog/83489

Azure Static Web Appsを作成
作ったVueを割り当てる
https://docs.microsoft.com/ja-jp/azure/static-web-apps/getting-started?tabs=vue

ページが見えたら完成

ナビゲーションを作成
https://kuroeveryday.blogspot.com/2016/10/vuejs-vue-router-navigationbar.html

npm install --save vue-router

CH9 VueRouter で SPA を構築
CodeSandbox の雛形があってわかりやすい！

https://cr-vue.mio3io.com/guide/chapter9.html#s48-%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AAspa%E6%A7%8B%E9%80%A0

Route53で作ったカスタムドメインの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/738170cf-53e0-8791-6401-d37f0d04da4d.png)

https://www.vuemastery.com/courses/intro-to-vue-js/vue-instance/
【python】input()の使い方

#input()とは
__入力__である。
#input()の使い方

例として入力に1を入れたコードを書く。

```python:
a = input()

print(a)
#1
#1
```

以上のように__入力した数__である__<font color="red">1</font>__が__input()__になっていることが分かる。

#input()の型
__input()__に入る__文字の____<font color="red">型</font>__を見てみる。intなのかfloatなのかstringなのか。

```python:
a = input()

print(type(a))
#1
#<class 'str'>
```

以上の例から、__入力した値の型__は__string(文字)__になっていることが分かる。

#input()をintの型に変更

__input()__を__intの型__に変更するコードを以下に書く。

```python:
a = int(input())

print(type(a))
#1
<class 'int'>
```
以上のようにinput()に入力した1がint(数字)の1になっていることが分かる。

#intにしないときのエラー
input()に数字を入れてそのまま足し算をしてもエラーになる。

以下がその例。

```python:
a = input()

b = a + 1

print(b)
#1
Traceback (most recent call last):
  File "practice.py", line 3, in <module>
    b = a + 1
TypeError: can only concatenate str (not "int") to str
```

これは__入力した1が数字の1ではなく文字の1__だと認識されている。
そのため、__入力した1を数字の1に直す__必要がある。
AWS WAF概要

AWS WAFの概要記事。

## AWS WAFとは

* AWSが提供するWAF(Web Application Firewall)。
  * WAFとは...
        * Webアプリケーションの脆弱性を突いた攻撃からWebアプリケーションを守るためのセキュリティ対策ソリューション。
        * 一般的なWebアプリケーションに対する攻撃手法(SQLインジェクションやXSSなど)からWebアプリを保護する。
        * 利用形態には、ソフトウェア、ハードウェア、サービスなどがある。
        * L7保護のためのもので、L3/L4保護のためのファイアウォールとは異なる役割を持つ。
* CloudFront、 ALB、API Gatewayにアタッチして利用する。

## 提供機能

* **悪意のあるリクエストのブロック**
  * SQLインジェクション、クロスサイトスクリプティングなど。
  * AWSや他のパートナーが提供するマネージドルールに基づいたブロック処理。
* **カスタムルールに基づいたWebトラフィックのフィルタ**
  * ルールベースフィルタリング
    * IPベース、正規表現・文字列
    * サイズ制限
  * ルール判定結果に応じたアクション(アクセス許可/拒否)
* **モニタリングとチューニング**
  * CloudWatchと連携した状態の可視化・アラート。

## 概念

![AWS_WAF_Concept.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/6b0c0be1-f573-c54f-4e50-4637b24868d9.png)

* **ルール**
    * リクエスト(攻撃)に対する戦略を定義する設定。
        * **ステートメント**：リクエストの検査条件
        * **アクション**：条件に一致した際のリクエストの処理方法。ALLOW(許可)/BLOCK(拒否)/COUNT(カウント)の3種。
* **ルールグループ**
  * 複数のルールをまとめて管理する際の単位。
* **Web ACL**
  * CloudFront、ALB、API Gatewayへの設定単位。
    * １リソースあたり１ACLの設定が可能。
    * 同一ACLを複数のリソースで共有可能。
  * ルール/ルールグループを包含管理。



### ステートメント

#### **判定内容**

* リクエスト発生国の一致 
* リクエスト送信元IPアドレスの一致
* サイズ制約 
* SQL injection
* XSS injection
* 文字列の一致 
* 正規表現パターンセット

#### **判定対象**

* リクエストヘッダー  
* HTTPメソッド 
* クエリ文字列
* 単一クエリパラメータ
* すべてのクエリパラメータ
* UR
* Body

### ルール
#### レートベースルール
* 5 分あたりの同一IPからのリクエスト数が設定閾値を超過した場合、Block/Countする。 
* 5 分あたりの閾値の設定範囲は、100 〜 20,000,000。
* ルール作成時にRate-based Ruleを選択。 
* 全リクエストを対象にするか、ステートメント内の条件に一致したリクエストだけを対象にするかを選択可能。

#### AWS Managed Rules for AWS WAF (AMR)

* AWS WAFに組み込み可能なルールセット。
* AWS Threat Research Team (TRT)が作成及びメンテナンス。
  * OWASP Top 10 をメインに対応。
* WAF Capacity Unit(WCU) は消費するが、それ以外の追加費用は不要。
  * WCU:WAFのルールに対する処理コストの考え方。
  * ルールに応じて、消費するWCUは異なる。

## AWS WAF導入(Web ACL設定)の流れ
1. Web ACL名の入力と適用対象AWSリソースの選択。
2. ルールの設定。
   1. 利用ルールの選択(+AWS マネージドルール追加)
   2. デフォルトアクション(Allow/Block)を選択
   3. ルールの適用順序を設定
3. CloudWatchメトリクスを選択。
4. 設定内容を確認し、作成完了。

## 参考情報

* [[AWS Black Belt Online Seminar]AWS WAFアップデート サービスカットシリーズ ](https://d1.awsstatic.com/webinars/jp/pdf/services/20200324_AWS_BlackBelt_AWS_WAF_Update.pdf)

* [AWS WAFを完全に理解する ~WAFの基礎からv2の変更点まで~](https://dev.classmethod.jp/articles/fully-understood-aws-waf-v2/)
【HTML】buttonタグでリンクを貼る方法

#プログラミング勉強日記
2020年10月16日
HTMLでコードを書いてるときにbuttonタグでリンクを埋め込みたいと思ったのでその方法を備忘録としてまとめる。

#方法
　buttonタグはクリックできるボタンを作るもので、基本的な書き方は以下のようになる。

```html:基本的な書き方
<button>表示させる内容</button>
```

　buttonタグを使ってリンクを貼る場合はonclick属性を以下のように追加する。

```html:buttonタグでリンクを貼る方法
<button onclick="loction.href='リンク先のURL'">->location</button>
```

```html:具体例
<button onclick="location.href='https://qiita.com/mzmz__02'">Qiita マイページ(buttonタグで)</button>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/1f9e77a3-95b6-3175-3da5-f4cf6d2c2ff3.png)


#他の方法でリンク先をbutton風にする

```html:HTMLファイル
<a href="https://qiita.com/mzmz__02">Qiita マイページ(aタグで)</a>
<br><br>
<a class="button" href="https://qiita.com/mzmz__02">Qiita マイページ(aタグでスタイルを使って)</a>
<br><br>
<input type="button" onclick="location.href='https://qiita.com/mzmz__02'" value="Qiita マイページ(input buttonで)">
<br><br>
<button onclick="location.href='https://qiita.com/mzmz__02'">Qiita マイページ(buttonタグで)</button>
```

```css:CSSファイル
.button {
  display: inline-block;
  border-style: solid;
  color: black;
  background-color: rgb(225, 224, 224);
  border-width:1px;
  border-color: darkgray;
  text-decoration: none;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/af4b0895-f5ef-56ef-745d-925a562810ca.png)
gasとlinebotのデバッグについて

##問題:
gasでlinebotを開発する際にdopost(e)を経由するデバッグができない点

##解決策:
function logを作成して通信によって受信する変数等をスプレッドシートに転記してエラーの発見をする

##ソースコード:

```typescript:log.gs
function log(message){
  var spreadsheet = SpreadsheetApp.openById('シートID');
  var ss = spreadsheet.getSheetByName('シート名');
  ss.appendRow([message]);
}
```

##使用例:

```typescript:test.gs
function doPost(e){
  if (typeof e === "undefined"){
    //eがundefinedの場合動作を終了する
    return;
  } 

  //JSON文字列をパース(解析)し、変数jsonに格納する
  var json = JSON.parse(e.postData.contents);
  log(json)

  //受信したメッセージ情報を変数に格納する
  var reply_token　= json.events[0].replyToken; //reply token
  log(reply_token)
  var messageId = json.events[0].message.id; //メッセージID
  log(messageId)
  }

function log(message){
  var spreadsheet = SpreadsheetApp.openById('シートID');
  var ss = spreadsheet.getSheetByName('シート名');
  ss.appendRow([message]);
}

```

##使用例結果:
log(変数)と記した部分の変数がスプレッドシートの特定のシートに順番に転記されていきます

##今後の展望:
gasとlinebotのデバッグについて追記する
デバッグシートの作成と共有

##最後に:
少しでも役にたてば幸いです、読了ありがとうございました。

現在私は個人事業主として下記のサイトの事業を取り進めております。(サイトはまだ作成して間もないのでまだガタガタです、、)
ホテルの自動チェックインのラインでの実装や、rpaの制作をメインに進めています。
作業の自動化等にご興味があれば是非ご連絡ください。何卒よろしくお願いいたします。
https://senren.work/
ChromeOSでPHP開発

ChromeOSのLinux(Crostini)を使って開発マシンに仕上げる方法のメモ。

> (メモ) PlayStoreが使える環境のChromeOSであればAndroidアプリのTermuxを使うほうが開発環境を作るには適していると思った。[こちらを参照♪](https://qiita.com/kujirahand/items/8e34e05e7296134b55cd)

以下、ChromeOS 86に基づいた内容。

# [1] Linux(Crostini)を有効に

ChromeOSの設定から、Linux(beta)「Crostini」を有効に。

# [2] Port転送を有効に

Port転送で例えば、8888を有効にしておく。

# [3] aptでPHPをインストール

```sh
sudo apt update
sudo apt install php php-mbstring php-sqlite3
```
# [4] phpのテストサーバーを起動

開発したいWebアプリのディレクトリにcdで移動。
その上で、PHPの開発用サーバーをポート8888で起動する。

```sh
php -S 0.0.0.0:8888
```
# [5] 自身のIPアドレスを調べる

自身のIPアドレスを調べる。

```sh
sudo ifconfig | grep "inet "
```

# [6] ChromeOSのブラウザでアクセス

ChromeOSのブラウザで上記IPアドレスにアクセス。

# [7] vimなどで開発

vimなどで開発してブラウザを更新すれば、反映される。
RSpec導入後、モデルの単体テストコードを書き始めるまで

#はじめに
RSpecの導入までの流れは、[こちらからどうぞ](https://qiita.com/TerToEer_sho/items/472e14df6fbb8e83ebf9)

##流れ

1. FactoryBotの準備
2. テストコードを記述するファイルの生成
3. 記述の型



###1. FactoryBotの準備
ディレクトリとファイルを用意する。
ex)userモデルのFactoryBotなら、spec/factories/users.rb


```ruby:spec/factories/users.rb

FactoryBot.define do
  factory :user do
    email {Faker::Internet.free_email} #例
    #以下、同じように必要なFakerを記述
  end
end
```

:userの部分が、spec/models/user_spec.rbでFakerを呼び出すときに使う。

Fakerの細かい使い方は、[FakerのGitHubへ](https://github.com/faker-ruby/faker)


###2. テストコードを記述するファイルの生成

ターミナルで、

```bash
rails g rspec:model モデル名
```

このコマンドにより、
spec/models/モデル名_spec.rb
のファイルが生成される。


ファイルの中に初めから、

```ruby:spec/models/user_spec.rb
RSpec.describe User, type: :model do
  pending "add some examples to (or delete) #{__FILE__}" #この行は削除
end
```

このようなコードが入っている。２行目のコードは削除して構わない。
（上の例は、モデル名にuserを指定したもの）

###3. 記述の型

```ruby:spec/models/user_spec.rb
RSpec.describe User, type: :model do
  describe '何をテストするのか（例）ユーザー新規登録' do
    before do
      @user = FactoryBot.build(:user) #userモデルを例にすると、userのFactoryBotを呼び出し
    end
    it "具体的なテスト項目（例）メールアドレスが必須であること" do 
    end
  end
end
```
（同じく上の例は、モデル名にuserを指定したもの。）

　.build(:user)←:userがFactoryBotから呼び出されている。

`it`と`do`の間にexampleを入れる。
`do~end`の間に、コードを記述する。
JavaScriptで配列をインデックス付きで逆順でループする

以前「[Google Apps Scriptでの業界ニュース通知を社内で運用した話](https://qiita.com/ninomiyt/items/bf6c2e344daeaf5bf786)」に書いた通り、[GoogleAppScript](https://developers.google.com/apps-script)を使って業界ニュースを通知しています。

簡単に言うと、「**SpreadSheetにあるURLをクローリングして、新しいニュースがあれば通知し、通知済みのニュースを別のシートに書き出す**」ような仕様です。他のシートの同じ行に書き出すため、次のようなコードで実装されています。

```javascript
/**
 * 処理を実行する。
 * @throw クローリングで1つ以上エラーが発生した場合
 */ 
function myFunction() {
  var parsers = createParsers();
  var errors = [];
  readConfig().forEach(function(config, i) {
    if (config['skip']) return;
    try {
      var latest_news = fetchLatestNews(config['title'],
         parsers[config['parser']], [config['feed']], config['charset'], i + 1);
      postNews(latest_news, config);
    } catch (err) {
      errors.push(config["title"] + "のニュース通知で次のエラーが発生しました: " + new String(err));
    }
  });
  notifyErrors(errors);
}
```

ただし、これでは「先に追加したニュースソースほど先に通知される」ため、「（先に追加されたニュースソースのほうが重要度が高い傾向があるため）チャットを表示したときに重要度が低いニュースが表示されてしまう」という問題点がありました。そのためインデックスを含めて逆順にループする必要があり、`reverse`メソッドで配列を逆順にするだけでは対応できません。

[こちらのstackoverflow](https://stackoverflow.com/questions/32682962/javascript-loop-through-array-backwards-with-foreach)によると、`reduceRight`というメソッドで逆順のイテレーションが可能なようです。

```javascript
const array = ['alpha', 'beta', 'gamma'];
array.reduceRight((_, elem) => console.log(elem), null);

// この方法は、インデックスは逆順にならないことが利点
array.reduceRight((_, elem, i) => {
  console.log(elem);
  console.log(i);
}, null);
```


先程のコードは、次のようなコードに書き換えました。

```javascript
/**
 * 処理を実行する。
 * @throw クローリングで1つ以上エラーが発生した場合
 */ 
function myFunction() {
  var parsers = createParsers();
  var errors = [];
  // 重要なニュースを後に通知するためreduceRightを使う
  readConfig().reduceRight(function(_, config, i) {
    if (config['skip']) return;
    try {
      var latest_news = fetchLatestNews(config['title'],
         parsers[config['parser']], [config['feed']], config['charset'], i + 1);
      postNews(latest_news, config);
    } catch (err) {
      errors.push(config["title"] + "のニュース通知で次のエラーが発生しました: " + new String(err));
    }
  }, null);
  notifyErrors(errors);
}
```

ちなみに、先程のコードでは、実装した当時は利用できなかったという理由で利用していませんが、GoogleAppScriptの現在の仕様では`const`やアロー関数は利用できます。積極的に使っていきましょう。

## 参考記事

* [Javascript - Loop through array backwards with forEach](https://stackoverflow.com/questions/32682962/javascript-loop-through-array-backwards-with-foreach)
俺のQMK（とChibiOS）メモ　ただしSTM32専用

# MPUの型番による違い

`lib/chibios/os/common/ext/ST/`以下のヘッダファイルに書いてある。

問題は、全型番が網羅されているわけではないこと。自分の型番がないときは近いものを見ることになる。が、これはどうもSTM32CubeMX（ST製ツール）が自動生成したヘッダファイルらしい。ChibiOS内では使われていないらしいマクロがある。たとえば`FLASH_BANK1_END`。Flashのサイズだけ違う型番ならここを変えればいいのかな？　と思うが、ほかのところで使われている様子がない。

# STM32CubeMXのインストール…ができなかったのでprevious version

もしJavaランタイムがなければOpenJDK8をインストール。

cmd.exeをAdministratorモードで開いて、`java -jar SetupSTM32CubeMX-6.0.1.exe`

信じられないほど時間がかかる。もしかしてダウンロードしてる？　230MBもあるインストーラなのに？

今度は普通のcmd.exeで`C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX`で`java -jar STM32CubeMX.exe`

→スプラッシュスクリーンが消えたあとhalt。なんじゃこりゃ。

しょうがないのでバージョンを下げて5.6.1で同じようにしたら動いた。

# STM32CubeMXの自動生成コードはChibiOSとは似てるけど違うけど参考になる

Makefileプロジェクトを自動生成してみた。

自動生成コードのいいところ：使うところだけ切り出してある場合が多いので、ChibiOSより探しものに便利。特にMakefile。

全型番を網羅していないのは、ヘッダファイルではSTM32CubeMXも同じ。違うのはLDSCRIPTで、STM32CubeMXはFlashサイズ違いにLDSCRIPTで対応している。しかしChibiOSのLDSCRIPT（`lib/chibios/os/common/startup/ARMCMx/compilers/GCC/ld/`にある）には欠けている型番がある。たとえばSTM32F072x8。この場合、QMKのkeyboardの`rules.mk`で`MCU_LDSCRIPT`で独自のLDSCRIPTを指定するらしい。`keyboards/xiaomi/mk02/rules.mk`参照。

ポエム：MPUの型番は掛け算なので、自動生成するSTM32CubeMXはこれでいいとして、ChibiOSはヘッダファイルやLDSCRIPTの構成を工夫しないとつらいのではありませんか？

# GCC拡張

QMKは`__attribute__ ((weak))`というGCC拡張を大前提に設計されているらしい。

普通のリンカは同名の関数定義が複数あるとエラーを吐く。しかしELFにはWeak symbolなるものがあって、通常の関数定義（Strong symbol）はWeak symbolを上書きできる。[参照](http://blueeyes.sakura.ne.jp/2018/01/10/761/)

[Custom Matrix](https://beta.docs.qmk.fm/using-qmk/hardware-features/custom_matrix)が関数定義だけでできるとは一体どういうトリックなのか？　と思ったら、こういう仕掛けだった。

# `#define`のインデント

何気なく`chconf.h`をclang-formatでフォーマットしたら、地獄めぐりをさせられた。問題は`lib/chobios/os/rt/rt.mk`の

```Makefile
CHCONF := $(strip $(shell cat $(CHCONFDIR)/chconf.h | egrep -e "\#define"))
```

なんとgrepで`#define`という文字列を探している。そのためマクロをインデントして`#  define`とするとコンパイルエラーになる。エラーになってくれるならまだいいほうで、黙って変な動作をして、地獄の底を引きずり回されることもあるだろう。
[Swift] forとifを入れ子にするよりfor whereを使おう

随分前からある構文ですが、私は最近気づいたので改めて書きます。
Swiftを書いていると時折こういうコードを書く必要が出てきます。

```swift
var count = 0
for i in 0..<n{
    if condition(i){
        count += 1
    }
}
```
`for`の直下に`if`があり、かつ`else`がない場合です。

でも`where`を使えばこう書けます。

```swift
var count = 0
for i in 0..<n where condition(i){
    count += 1
}
```
意味は簡単で、`where`節が条件を指定しています。こう書くことでネストが1つ減るだけでなく、考えている条件もわかりやすくなります。
最適化のおかげでパフォーマンス上の影響は全くないので、積極的に使っていくべきだと思います。
ask data

#ask data概要

- 言語でデータの可視化ができる
    - 可視化はドラッグアンドドロップだけでない
- ダッシュボードへの埋め込みも可能
- twbxの状態だと使えない。データソース単体でパブリッシュする必要あり。
- 管理者のほうでaskdataを有効化する必要あり。
- パフォーマンスは2000万くらいで２，３分かかる。WEB編集と同じくらいの負荷。
- エクスプローラー、クリエーターのみ利用可能
- データの項目からその項目の内容がみられる。
- とりあえず見たい項目を打ち込むと候補として集計方法を提案してくれる。
- 表示された状態でグラフの形を変更することも可能
- askdataでした質問を他者に共有することも可能。
- 地図での表現も可能
- URL共有の際、URLからのリンクでアクセスするとVizがみられる（通常のViz）

#ask dataの事前準備

- 質問の種類予想
- データソース簡素化
    - 不要データ削除、抽出が良い
- フィールドのプロパティ
    - 項目名わかりやすく、データ型も適当に設定

#今後の展望

- 日付け範囲の指定
- 積み上げ棒とか新しいグラフにも対応していく
- 管理ビューでaskdataで何を検索したかがみられるようになる

#質問

- Viewerでもダッシュボードに埋め込んでいたらaskdata使えるか

A.見られない（データソースへのアクセス権がないため、そもそもデータソースにアクセスできない）
【Laravel】whereHasでリレーションのネスト先を検索条件として指定する方法。

自分用のメモとして残します。


リレーションのネスト先。
言い方を変えるとリレーション先のリレーション？のフィールドをwhereHasで検索する方法です。

#■やり方
リレーションの定義は割愛させていただきます。
withと同じようにピリオドでリレーションのチェーンをします。

```php
$query->whereHas('user.phone', function($query) use($cond) {
    $query->where('phonename', $cond['phonename']);
});
```
【Docker】php artisan migrate エラー（SQLSTATE[HY000] [2002]）

環境：Mac
　　　Laravel 6.x系
　　　Mariadb

php artisan migrate　実行時に以下のエラーが表示される。

```
Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known (SQL: select * from information_schema.tables where table_schema = database and table_name = migrations and table_type = 'BASE TABLE')
```
 
上記エラーメッセージの一部をコピペして検索すると「.envファイル」修正の対策がでてきたが、
私の場合は、どれも設定済みであったので、解決には至らなかった。
その後も検索し続け、やっと解決したので備忘録として。
結果として、ごく初歩的なミスでした。。。

以下簡単な流れ。
①コンテナに入る
②コンテナ内で「php artisan migrate」を実行
③違うエラーメッセージが表示される
④エラーメッセージの内容を確認し、訂正する

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

①コンテナに入る

```
$ docker-compose exec app bash
```

②コンテナ内で「php artisan migrate」を実行

```
[app] php artisan migrate
```

③違うエラーメッセージが表示される
おそらく、記載ミス等の指摘がされている内容が表示されるかと思う。

④エラーメッセージの内容を確認し、訂正する
③で表示されたエラーメッセージを読み取り、対象ファイルの修正を行う。

私の例：エラーメッセージ内に「255」の記載あり。
　　　　migrationファイル内のtableのcreateで、以下のように記載していたのが原因
　　　　修正後、問題なく、php artisan migrate できた。。。

```
#誤り（デフォルトで255のため不要）
$table->string('title',255);

#修正後
$table->string('title');
```

恥ずかしいミスだが、これが誰かの役に立てば幸い！！！！！！
Pythonで学ぶ音源分離（機械学習実践シリーズ）のソースコード

ビームフォーミングのコード自前で書いていたけど、色々な手法が記載されている。

散々探していい例がないなと思っていたけど、いいのがあったのでメモ

[Pythonで学ぶ音源分離](https://github.com/masahitotogami/python_source_separation)
slackのリアクションを監視してHasura経由でReact画面をリアルタイムに更新する

Slackのメッセージのリアクションを監視して、ReactのUIにリアルタイムに反映させたい。
![スクリーンショット 2020-10-16 17.35.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/c50ce4ad-a826-410f-1ec8-1c7567a52ff9.png)

やることは大きく分けて以下の３つ

- slackのメッセージにおけるリアクションの監視
- 対象メッセージのリアクション回数の更新
- ReactのUIに反映


##slackのメッセージにおけるリアクションの監視
slack APIの**Event Subscriptions**を使う。
###URLの指定
エンドポイントをここに入力。
今回はFlaskで事前に用意したエンドポイントを利用。
このエンドポイントでslackからjsonを受け取ってHasuraにクエリを投げる。
###発火条件の指定
**Subscribe to events on behalf of users**で発火条件を指定する。
今回は、リアクションが押された時に発火させたいので、以下の二つを有効にする。

- reaction_added
- reaction_removed

これでリアクションがあった時にエンドポイントにjsonが投げられる。


##対象メッセージのリアクション回数の更新
Flaskで処理を行う。
今回は、指定のチャンネルのメッセージのリアクションのみ監視したかったため、チャンネル名でフィルターをかける。
次に、受け取ったjsonの中にメッセージのユニークなidが入っているので、これを元にHasuraの方にクエリを投げてリアクション回数を取得する。
その後、reaction_addedかreaction_removedでそのリアクション回数を増減させて最後にmutation。


##ReactのUIに反映
apollo-clientを使ったsubscriptionは公式documentに沿えばok。



###参考
Setting up GraphQL subscriptions using apollo-client
https://hasura.io/docs/1.0/graphql/core/guides/integrations/apollo-subscriptions.html#write-your-subscription

Create Subscription and Render Result
https://hasura.io/learn/graphql/react/subscriptions/3-create-subscription/