OmniAICreator/Qiita-1.07M huggingface dataset:
nの導入方法（nodeのバージョンをnで管理する）

```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G2022
```

##結論

- `export PATH=$HOME/.nodebrew/current/bin:$PATH` をコメントアウト
- `export PATH=$HOME/bin:$PATH`を追記
- ターミナルを再起動

```
vim .bash_profile
# nodebrew
# export PATH=$HOME/.nodebrew/current/bin:$PATH　←（コメントアウト）
export PATH=$HOME/bin:$PATH ←（npm install -g n　した後に追記した）
```

## インストール
まず、node.jsがインストールされていなければ、homebrewでインストールします。

```
brew install node
```

次にnpmでnをインストール

```
npm install -g n
```

## nを使ってみる
### バージョンの一覧表示

```shell-session
$n list
$n commmand not found
```

- PATHが通っていないためnが入っているディレクトリを調べる。
- /Users/#{name}/bin/nいかに入っているようだがそこにPATHが通っていないことが原因では？

##bin配下を確認
```
$ ls ~/bin/
#n発見
```

##vim .bash_profile でPATHを通す（export PATH=$HOME/bin:$PATH）

```
vim .bash_profile
# nodebrew
export PATH=$HOME/.nodebrew/current/bin:$PATH　←（すでに書いてあったPATH）
export PATH=$HOME/bin:$PATH ←追記したPATH
```

##ターミナル再起動
```
$ n list
#Permission denied
$ sudo n list
$ sudo n latest
〜〜〜
#挙動がおかしい。先に書いたPATHが読み込まれたせいでうまく行っていないみたい。
#先にとしたPATHをコメントアウトしよう。
```

```
vim .bash_profile
# nodebrew
# export PATH=$HOME/.nodebrew/current/bin:$PATH　←（コメントアウト）
export PATH=$HOME/bin:$PATH ←（npm install -g n　した後に追記した）
```

##ターミナルの再起動
##コマンドを実行して確認(成功)
```
$ n list
node/14.5.0
```


###参考にした記事（いつもありがとうございます。）
---
[nodeのバージョンをnで管理する](https://qiita.com/bigplants/items/2d75bf552e0da4a7e822)
[n: command not found で困ったとき](https://qiita.com/Furuta03/items/01501baa8b743e6db06b)




















初心者おばちゃんの簡単jQueryスクロールボタン

##初心者おばちゃんの簡単jQueryスクロールボタン
いろいろと探してみて、一番スムーズにスクロールしてくれるスクロール・トゥ・トップ、そしてダウンのやり方をご紹介します。そのままコピペして使ってもしっかり動きます。

###CSSの設定

        .back-to-top {
            position: fixed;
            left: 0;
            bottom: 85px;
            display: none;
            -webkit-transform: rotate(270deg);
            -moz-transform: rotate(270deg);
            -o-transform: rotate(270deg);
            -ms-transform: rotate(270deg);
            transform: rotate(270deg);
        }

        .back-to-down {
            position: fixed;
            right: 0;
            bottom: 85px;
            display: none;
            -webkit-transform: rotate(90deg);
            -moz-transform: rotate(90deg);
            -o-transform: rotate(90deg);
            -ms-transform: rotate(90deg);
            transform: rotate(90deg);
        }
「rotate(90deg)」で飛行機のアイコンが上向きに飛ぶようにしてます。


###javascript（jQuery）


        $(document).ready(function(){
	        $(window).scroll(function () {
			        if ($(this).scrollTop() > 500) {
				        $('#back-to-top').fadeIn();
			        } else {
				        $('#back-to-top').fadeOut();
			        }
		        });
		        $('#back-to-top').click(function () {
			        $('body,html').animate({
				        scrollTop: 0
			        }, 400);
			        return false;
		        });
        });
        $(document).ready(function(){
	        $(window).scroll(function () {
                if (($(this).scrollTop()+800) > $('#down').height()) {
                    $('#back-to-down').fadeOut();
                } else {
                    $('#back-to-down').fadeIn();
                }
                });
		        $('#back-to-down').click(function () {
                    $('body,html').animate({
                        scrollTop: $('#down').height()
			        }, 400);
			        return false;
		        });
        });
###HTML

    <div class="container" id="down">
        <div class="container">
            <main role="main">
            </main>
        </div>
        <a id="back-to-top" href="#" class="btn btn-dark btn-sm back-to-top" role="button">Top&#8195<i class="fa fa-fighter-jet"></i></a>
        <a id="back-to-down" href="#" class="btn btn-dark btn-sm back-to-down" role="button">Down&#8195<i class="fa fa-fighter-jet"></i></a>
    </div>
ここでは、最初の「class="container"」ですべて真ん中に持ってきて、次の「class="container"」でメインを真ん中にもってくる。そうするとメインの外側でボタンがついてくれるので、デバイスを選ばず表示してくれると思ってこうしてます。
まだまだCSSわかんないことばかりで大変。
初心者には初心者なりの疑問があります。「こんなこともわからないのか！」となる部分が往々にしてつまずく場所になったります。

実際にどう動くのかはこちらのサイトから「test」のアカウントで入って確認してみてください。
https://oboero3.azurewebsites.net/
ngrok でトンネリング中の URL を取得する shell command ( curl, jq 使用 )

手軽にローカル環境を公開できる [ngrok](https://ngrok.com/) をよく使うのですが、無料版だと毎回実行ごとに トンネリングURL （公開URL） が変わってしまってなにかとめんどくさい。
ngrok コマンドを実行中のteminalから値をコピーすればいいんだけど、めんどくさい。

# この記事で分かること / 分からないこと
#### 分かること
[ngrok](https://ngrok.com/) でトンネリングされる URL を **1コマンドで取得する** 方法
※ `curl` コマンドと [`jq` コマンド](https://stedolan.github.io/jq/) を使用します。

#### 分からないこと
[ngrok](https://ngrok.com/) でトンネリングされる URL を **なんとか固定する** 方法
こちらが知りたい場合はこちらの記事などが参考になると思います。（未検証）
https://qiita.com/miso_develop/items/bdcf15489b069ba1fa61

## 結論
```shell
curl -s localhost:4040/api/tunnels|jq -r ".tunnels[0].public_url"
```
※ 管理用 Web Interface が `localhost:4040` で動作している場合

#### 解説的なやつ
ngrok が標準で搭載している、 [Client API](https://ngrok.com/docs#client-api) を使っています。
そうなんです。 ngrok さん自前でAPIを用意してくれています。ありがたやぁ〜。
ngrok を起動すると、標準では `localhost` の `4040` ポートで管理用 Web Interface を同時起動してくれます。 この時、`localhost:4040/api/tunnels` に GETリクエストすると、 現在起動中のトンネルの状態をJSON で返してくれます([ngrok-documentation](https://ngrok.com/docs#list-tunnels))。 これを `jq` で処理します。 

### （蛇足） 毎回上のやつ打つのもめんどいやん？
alias 使ったらOK

```shell:bashrcとか
alias ngrok_url="curl -s localhost:4040/api/tunnels|jq -r \".tunnels[0].public_url\""
```

これで1コマンドで出せます。

```shell:1コマンドで表示
$ ngrok_url
https://XXXXXXXXXXXX.ap.ngrok.io
```
#### (蛇足の蛇足） mac 利用者なら `pbcopy` 使ってクリップボードにコピーできます

```shell
$ ngrok_url|pbcopy
```
=> クリップボード上にコピーされる

##### 追記
私よりも先に考えついた人がいらっしゃったようです。 （初出の明示）
https://gist.github.com/rjz/af40158c529d7c407420fc0de490758b#gistcomment-3309439
https://easonwang.gitbook.io/web_advance/ngrok-shi-yong
https://gist.github.com/VMuliadi/3784123bf63d517f66c6a16bda591317
Heroku Buildpacks PHP Apache 設定まわりまとめ

Heroku に Buildpacks でデプロイするときの開発環境として、[Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) ではなくコンテナがほしいと思い
Heroku CLI や Buildpacks を解析して Docker イメージを自作したときのメモです。

ちなみに、自作した Docker イメージはこちらです:
[futureys/heroku-php-apache2 - Docker Hub](https://hub.docker.com/r/futureys/heroku-php-apache2)

## ドキュメントルートが決まるしくみ

Heroku CLI での Apache のドキュメントルートは
`Procfile` で定義している `heroku-php-apache2` コマンドのパラメーターで決まります。

```console
web: $(composer config bin-dir)/heroku-php-apache2 -v web/
```

このパラメーターは次の Shell Script で環境変数に設定されます。
[heroku-buildpack-php/heroku-php-apache2 at fd5ac6063236102038d06f91b938b62b6e60080f · heroku/heroku-buildpack-php](https://github.com/heroku/heroku-buildpack-php/blob/fd5ac6063236102038d06f91b938b62b6e60080f/bin/heroku-php-apache2#L313)

※ $# は引数の数の意味
参考: [シェルスクリプト パラメータ キーワードパラメータ](http://www.redout.net/data/shellscript4.html)

この環境変数は次の Apache conf ファイルでドキュメントルートの設定に使われます。
[heroku-buildpack-php/heroku.conf at fd5ac6063236102038d06f91b938b62b6e60080f · heroku/heroku-buildpack-php](https://github.com/heroku/heroku-buildpack-php/blob/fd5ac6063236102038d06f91b938b62b6e60080f/conf/apache2/heroku.conf#L47)

`heroku-php-apache2` コマンドは
上記の独自の Apache conf ファイルを持っており、
Heroku CLI 実行時にはこの conf ファイルが使われるようです。

`heroku-php-apache2` コマンドは
アプリケーションの composer.json の require-dev でインストールします。
[heroku/heroku-buildpack-php - Packagist](https://packagist.org/packages/heroku/heroku-buildpack-php)
参考: [Customizing Web Server and Runtime Settings for PHP | Heroku Dev Center](https://devcenter.heroku.com/articles/custom-php-settings#how-applications-are-launched-during-dyno-boot)

## Apache のデフォルトの php-fpm の設定ファイルは削除します

Heroku CLI の local コマンドでサービスを起動する場合は
デフォルトの php-fpm の設定ファイルは使わないので削除します。
[ansible-role-heroku-cli-amazon-linux/set_up_for_local_command.yml at ed10abc53a1ccf7ffbb869760aac0a5d77f33aa8 · yukihiko-shinoda/ansible-role-heroku-cli-amazon-linux](https://github.com/yukihiko-shinoda/ansible-role-heroku-cli-amazon-linux/blob/ed10abc53a1ccf7ffbb869760aac0a5d77f33aa8/tasks/set_up_for_local_command.yml#L27)
XSERVER（エックスサーバー）でGitをインストールする



エックスサーバーでgitをインストールするときに2ヶ所ほどハマったのでメモ。

参考にしたサイト
https://qiita.com/chr/items/aaa5a0e005958c7a9a16
https://teratail.com/questions/25891

#gettextのインストール

    #インストールディレクトリ
    $ mkdir ~/opt

    #作業ディレクトリ
    $ mkdir ~/sysad

    $ cd ~/sysad
    #バージョンを指定するとエラーにならない。最新版をwgetすると404になった。
    $ wget http://ftp.gnu.org/pub/gnu/gettext/gettext-0.20.1.tar.gz
    
    #移動
    $ cd gettext-0.20.1
    $ ./configure --prefix=/home/[サーバID]/opt
        
    #コンパイル いらなかったかも？
    $ make

    #インストール
    $ make install

    ##インストールされたか確認
    $ ~/opt/bin/gettext --version

#gitのインストール

    #git install
    $ cd ~/sysad/
    $ wget https://codeload.github.com/git/git/zip/master
    $ unzip master
    $ cd git-master
    $ autoconf
    $ ./configure --prefix=/home/[サーバID]/opt

    #msgfmtが入っていないとエラーになるので -i　でエラーを無視する
    $ make -i all
    $ make -i install
    
    ##インストールされたか確認
    ### git version 2.11.GIT
    $ ~/opt/bin/git --version

あとはgitのパスを通してあげるといいと思います。
[python] np.arangeで任意の刻みの日付配列を作る

# モチベ
任意の刻みの日付配列を作りたい

# コード
```python
# 3ヶ月刻み
np.arange('2000-01', '2002-02',np.timedelta64(3,'M'), dtype='datetime64')
# ['2000-01' '2000-04' '2000-07' '2000-10' '2001-01' '2001-04' '2001-07' '2001-10' '2002-01']

# 2年刻み
np.arange('2010', '2018',np.timedelta64(2,'Y'), dtype='datetime64')
# ['2010' '2012' '2014' '2016']

# 1分刻み
np.arange('2000-01-01 10:00:00', '2000-01-01 10:05:00',np.timedelta64(1,'m'), dtype='datetime64')
#['2000-01-01T10:00:00' '2000-01-01T10:01:00' '2000-01-01T10:02:00' '2000-01-01T10:03:00' '2000-01-01T10:04:00']

# おまけ # '2010'しか指定しなくても実際は細かい値を持ってます
np.datetime64('2010')==np.datetime64('2010-01-01 00:00:00')  # True
np.datetime64('2010')==np.datetime64('2010-01-01 00:00:01')  # False
```
numpyのdatetimeの方が慣れると使いやすそう

# 参考
https://numpy.org/devdocs/reference/arrays.datetime.html
Docker ComposeでLaravel開発環境を構築その壱

Docker環境を作ってみよう！・・・と思い立ったので、作ってみました。
[Docker＋Amazon LinuxでLaravel開発環境を構築](https://qiita.com/_bobtabo_/items/c5f92346bb47eddb7a56)

でも、OSイメージにインストールしまくるのは、Dockerの本来の使い方じゃないんだろうな。
ということで、Docker Composeでの環境構築を、コピペできるように纏めました。

# マシンスペック
* Mac mini 2018
* macOS Catalina（10.15.x）
* Intel Core-i7 3.2GHz 6コア
* メモリ 32GB
* SSD 512GB

# Docker環境
* Nginx 最新版
* PHP（PHP-FPM）7.2.x
* MySQL 5.7.x
* Composer 最新版
* Laravel 5.6

# やること
* Docker Composeで環境構築

# 補足
各環境を行ったり来たりするので、下記のように記載します。

```
[Mac]$ MacのターミナルでMac内の作業
[PHP]$ MacのターミナルからPHPコンテナに接続して作業
```

# 前提
Dockerはインストール済み

# コンテナ作成
コンテナ定義を作りました！
[https://github.com/bobtabo/docker](https://github.com/bobtabo/docker)

```
[Mac]$ cd <任意のディレクトリ>
[Mac]$ git clone https://github.com/bobtabo/docker.git
[Mac]$ cd docker
[Mac]$ docker-compose up -d
・・・
Creating mysql ... done
Creating php   ... done
Creating nginx ... done
```

##### 作成されるホストOS（Mac）のマウントポイント

```
~/Work/MountPoint/docker/home -> /home/docker
~/Work/MountPoint/docker/db/data -> /var/lib/mysql
```

※参考
[Concrete5 on Nginx + php7-fpm を docker-compose でやってみた](https://qiita.com/hidekuro/items/6f8ee3217b98e93a0276)
[docker-compose を使って（なるべく）公式イメージで PHP 開発環境を作った](https://qiita.com/hidekuro/items/46c00dec350c4a37fbb1)
[PHPの公式DockerイメージでUNIXソケット通信しようとして罠にハマるの巻](https://yoshinorin.net/2017/03/06/php-official-docker-image-trap/)
[docker-composeでunixソケットを使った、Nginx、php-fpmコンテナを作る](https://qiita.com/yCroma/items/c22d948b4393fbc96f53)

### Laravelのインストール

LaravelインストールをDockerfileに書くと、コンテナ起動時に毎回インストールが走るらしい。
どの記事を読んでもLaravelは別作業なのは、そういう事だったのか。
何か効率が良い方法はないものか、、、また今度考えよう。
ということで、コンテナの中に入って、Laravel環境を作成します。

```
[Mac]$ docker-compose exec --user 1000 php bash
[PHP]$ pwd
/home/docker

[PHP]$ composer create-project --prefer-dist laravel/laravel laravel "5.6.*"
[PHP]$ cd laravel
[PHP]$ composer require --dev barryvdh/laravel-ide-helper
[PHP]$ composer require --dev squizlabs/php_codesniffer
[PHP]$ chmod -R 777 storage
[PHP]$ chmod -R 777 bootstrap/cache

[PHP]$ vi .env
★DB設定を置換
:%s/DB_HOST=127.0.0.1/DB_HOST=mysql/g
:%s/DB_DATABASE=homestead/DB_DATABASE=hoge/g
:%s/DB_USERNAME=homestead/DB_USERNAME=fuga/g
:%s/DB_PASSWORD=secret/DB_PASSWORD=docker#DOCKER1234/g
:wq

[PHP]$ php artisan migrate
[PHP]$ php artisan db:seed

[PHP]$ mkdir bin
[PHP]$ vi bin/clear-laravel.sh
★下記を点線内をコピペ
---
#!/bin/bash
php artisan view:clear
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan clear-compiled
php artisan config:cache
composer dump-autoload
php artisan ide-helper:generate
php artisan ide-helper:models -N
php artisan ide-helper:meta
find . -name '._.DS_Store' -type f -ls -delete
---
:wq
[PHP]$ chmod 755 bin/clear-laravel.sh
[PHP]$ bin/clear-laravel.sh
```

### 動作確認（Macのhosts編集）
```
[Mac]$ sudo vi /private/etc/hosts
★下記を点線内を追記
---
127.0.0.1 laravel.local
---
:wq
```

### ブラウザで動作確認
http://laravel.local/

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/3f735218-18a5-d1c0-d8dc-c433bf65cad7.png)

# コンテナ削除

```
[Mac]$ docker-compose down --rmi all --volumes
```

※参考
[《滅びの呪文》Docker Composeで作ったコンテナ、イメージ、ボリューム、ネットワークを一括完全消去する便利コマンド](https://qiita.com/suin/items/19d65e191b96a0079417)
【Python】データサイエンス100本ノック（構造化データ加工編） 006 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/GVwgC7-pgno)もしています。

##問題
P-006: レシート明細データフレーム「df_receipt」から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上数量（quantity）、売上金額（amount）の順に列を指定し、以下の条件を満たすデータを抽出せよ。
- 顧客ID（customer_id）が"CS018205000001"
- 売上金額（amount）が1,000以上または売上数量（quantity）が5以上

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']] \
.query('customer_id == "CS018205000001" & (amount >= 1000 or quantity >=5)')
```

##出力
|  | sales_ymd | customer_id | product_cd | quantity | amount |
|--:|--:|:--|:--|--:|--:|
| 36 | 20180911 | CS018205000001 | P071401012 | 1 | 2200 |
| 9843 | 20180414 | CS018205000001 | P060104007 | 6 | 600 |
| 21110 | 20170614 | CS018205000001 | P050206001 | 5 | 990 |
| 68117 | 20190226 | CS018205000001 | P071401020 | 1 | 2200 |
| 72254 | 20180911 | CS018205000001 | P071401005 | 1 | 1100 |

##解説
・PandasのDataFrame/Seriesにて、列を指定しつつ、指定した行のうち、複数の条件に当てはまる行を確認する方法です。
・列情報を絞り、かつ、行を指定して、かつ、複数の条件に当てはまる情報を確認したい時に使用します。
・**or条件は、「|」パイプライン（vertical bar）を用いて表現します。**
・**'<データ名>[['<列名A>','<列名B>','<列名C>']].guery('<列名A> == "<行情報A>" & <列名B> >= 1000 | 列名C >= 5')'**で、指定した列(列名A,列名B,列名C)のうち、「列名A が指定した 行情報A に該当する行で、かつ、列名B が1000以上」、あるいは、「列名A が指定した 行情報A に該当する行で、かつ、列名C が５以上」の行を表示します。

※ちなみに、以下のコードのように「|」を「or」にしても、同じ結果になります。

```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']] \
.query('customer_id == "CS018205000001" & (amount >= 1000 or quantity >=5)')
```
ServletでJSPからパラメータの受け渡し

#はじめに
今回は[EclipseでServletプログラムを作成する](https://qiita.com/tatufut/items/a181776ce407ce44dbfd)の続きを行います。
今回目指すのはJSPで入力した値をServletで取得してJSPに渡すことを目指します。
※JSTLを使用した方が容易に実装できますが今回は簡単な処理なため使用しません。

##実行環境
- Eclipse4.16 
- Tomcat9
- Java11

##JSPからServletへ受け渡し
まずはJSPを編集します。

```jsp:sample.jsp
<form action="/SampleTest" method="post">
  <input type="text" name="param">
  <input type="submit" value="登録">
</form>
```
inputタグのname属性でServletで受け取るための名前を設定します。

次にServletのdoPostメソッドを編集します。

```java:SampleTest.java
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8"); // 文字化けしないように文字コードを設定。
		String param = request.getParameter("param"); // JSPのname属性を設定した入力値を取得する。
		request.setAttribute("param", param); // JSPに渡すためにparamという変数に設定する
		request.getRequestDispatcher("/WEB-INF/view/sample.jsp").forward(request, response);
	}
```
これでJSPへ渡す準備は整いました。

最後にJSPで受け取る処理を記述する。

```jsp:sample.jsp
<form action="/SampleTest" method="post">
  <input type="text" name="param">
  <input type="submit" value="登録">
</form>
<%= request.getAttribute("param")%>
```
`スクリプトレット(<% Javaコード; %>)`はJSPファイルでJavaのコードの使用が出来る
`スクリプト式(<%= Javaコード %>)`を使用して変数やメソッドの戻り値などを出力する。

##実行
ここまで出来たらサーバーを起動する。
入力値を入力し登録ボタンを押下すると
**下に入力値が表示されれば成功！**

#最後に
これで前回と合わせてServletの基礎を学びました。
次回からWebアプリケーションを作成します。
AWS CLI v2 をmacOSにインストールとzshコマンド補完

## AWS CLI v2について

AWS CLIのバージョン２が、2020年2月に一般利用となっています。
v1からいろいろと更新されていますが、日常的に使うものとしてはコマンド補完が最も大きいと思います。

[AWS CLI v2 が一般利用可能となりました \| Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/aws-cli-v2-is-now-generally-available/)

v2のインストールとコマンド補完の手順を以下に示します。

## 確認した環境

以下の環境で動作確認を行いました。

* macOS 10.15
* zsh

## インストール手順

以下のページを参考にしています。
[macOS での AWS CLI バージョン 2 のインストール \- AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html)

### AWS CLI バージョン1のアンインストール

バージョン1がインストール済みの場合、アンインストールすることが推奨とされています。

```bash
pip uninstall awscli
```

### コマンドラインからインストール（すべてのユーザーを対象に）

今回の手順では、コマンドラインから全てのユーザーを対象にインストールします。

```bash
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
```

GUI、あるいは現在のユーザーのみを対象にインストールする場合は[公式ページ](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html#cliv2-mac-install-cmd)を参照ください。


## コマンド補完

以下のページを参考にしています。
[コマンド補完 \- AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html)
### [シェルを識別する](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-shell)

以下のコマンドにより使用しているシェルを特定します。
このドキュメントではzshについて記述しています。他のシェルを使用している場合は、[公式ページ](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html)の手順を直接参照ください。

```bash
echo $SHELL
# 例→ /bin/zsh
```

### [AWSコンプリケータを見つける](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-completer)

AWS コンプリケータのパスを取得します。

```bash
which aws_completer
# 例→ /usr/local/bin/aws_completer
```

### [コンプリケータのフォルダをパスに追加する](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-path)

`~/.zshrc`をテキストエディタで開いて、以下を追記します。

```bash
autoload bashcompinit && bashcompinit
complete -C '/usr/local/bin/aws_completer' aws
```

設定を有効にするために、新しいコンソールを開くか、以下のコマンドを実行します。

```bash
source ~/.zshrc
```

### [コマンド補完のテスト](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-test)

コマンドの一部を入力して、Tabを押して使用可能なコマンドを表示します。

```bash
aws s[TAB]
s3                     serverlessrepo         sqs
s3api                  service-quotas         ssm
s3control              servicecatalog         sso
sagemaker              servicediscovery       sso-oidc
sagemaker-a2i-runtime  ses                    stepfunctions
sagemaker-runtime      sesv2                  storagegateway
savingsplans           shield                 sts
schemas                signer                 support
sdb                    sms                    swf
secretsmanager         snowball               synthetics
securityhub            sns
```
Data Robot 犬猫分類　ワンちゃんと猫ちゃん違いがわかるのかやってみた

###Datarobot を利用して犬猫分類をやっみる
DATA　は　googleがデータセットを提供してくれるのでそれを利用
####猫 約100セット
![Abyssinian_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/4e0316f1-d197-6469-88ef-96f9395e7073.jpeg)
![Abyssinian_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/8bcbbd5b-c00e-0ee8-e50b-b35d9d5a629f.jpeg)
![Abyssinian_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/e3d507b2-c128-9149-f9ff-0cc3db3ecbca.jpeg)
![Abyssinian_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/13e5e3ee-2305-4a1a-8da5-3e3c865931b3.jpeg)
![Abyssinian_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/a08c1d1c-847a-e357-3281-182091df8bf1.jpeg)

####犬　100セット
![american_pit_bull_terrier_42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/4a79105f-37e5-fb7c-dcfc-7e845b46f190.jpeg)
![american_bulldog_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/cf5edcbe-053d-d2f3-d796-879dd0f55c6a.jpeg)
![american_bulldog_13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/9fceecaf-a141-74d6-d0ea-1099ef5e5d09.jpeg)
![american_bulldog_132.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/1a9c704c-63f0-6c85-c98c-e063b3f20f86.jpeg)
![american_bulldog_141.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/1d4d0905-502b-edc3-ee34-f7a3013c8ed6.jpeg)
![american_pit_bull_terrier_35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/c2a26d66-1980-0ae9-0d63-809688609867.jpeg)
![american_pit_bull_terrier_37.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/581c7532-478e-7cba-1906-4e9c35823e7c.jpeg)

データを読み込ませて分析
リフトチャート
![犬と猫.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/b34f812b-e9a4-8f9f-886d-4e41bd91295c.jpeg)
サマリー
![犬と猫2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/9495b9d8-4e02-bea0-1632-d04bb5144b14.jpeg)
AIの目　分類
![犬と猫3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/b050bab6-b365-ffac-0abe-580adf37bafd.jpeg)
特徴量インパクト
![犬と猫4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/102df434-eff2-07ba-b30c-81bd9fb1b76a.jpeg)
分類2
![犬と猫5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/f2441520-7e34-1f30-4051-9038fd5025c3.jpeg)
AIは何を見ているか？
![犬と猫6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/fb005fd1-67fa-cc6c-64e5-1f8da2cc8baa.jpeg)
ブループリント　流れの説明
![犬と猫7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/4333368e-f92d-7d96-404b-429f824d53a3.jpeg)
![犬と猫8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/92b405bb-37ed-8876-b0ea-81e2734c3016.jpeg)
![犬と猫9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55742/863cfd65-400f-391a-f6c1-b171629d712f.jpeg)

分類できました。
このあと分析テストしてみました。できてます。
また画像分類　してみます。
beautiful soupを使ってみた際の備忘録

##使ってみた
`pip install beautifulsoup4`でインストール
パーサー?なるものはデフォルトでいいかなと思って、`lxml`とかは使わずデフォルトで備わっている`html.parser`を用いた。

```python
import requests
from bs4 import BeautifulSoup
url = input()
html = requests.get(url)
soup = BeautifulSoup(html.content, "html.parser")
```

基本はこれで良いはず。

###検索
・id検索(検索できるものは一つ
`soup.find(id="id名")`
・css selector検索(検索できるものは一つ
`ing.select_one("css selector名")`

検索に一致する全ての要素を見つける時は
idなら
`find_all(id名)`
css selectorなら
`select(.class属性名)`
参照:[Beautiful Soup のfind_all( ) と select( ) の使い方の違い]
(https://gammasoft.jp/blog/difference-find-and-select-in-beautiful-soup-of-python/)

`<h3 class="A B">`のような(class属性を複数持っている)物をselectで検索する時は`select_one(.A.B)`をする。

###参考にしたサイトのURL
[cssセレクタについて](https://gammasoft.jp/support/css-selector-for-python-web-scraping/)
[タグ検索とcssセレクタ検索の例が載っている](https://imabari.hateblo.jp/entry/2016/08/20/101006)


##追記
###前方一致、後方一致、部分一致(20/09/12)
[前方, 後方, 部分一致セレクタ](https://qiita.com/shuhei/items/0d8d925acd48afefdb57)
[python] datetimeの差の月数、年数の算出


# モチベ
datetime型の加減算をするとtimedelta型が返ってきますが、日より細かい属性しか持っておらず、月や年の計算をするときに毎度つまってググってました。なのでまとめておきます。

# コード
・日付と月数の加減により、新たな日付を生成(relativedeltaを使う※timedeltaでは月は扱えない)
・２つの日付の差の月数、年数を求める（monthmodを使う）

```python
# 開始日時をdatetime型で作る  -----------
from datetime import datetime
dt1 = datetime(2018,5,6)  # datetime.datetime(2018, 5, 6, 0, 0)

# 開始日時に任意の月数、日数を加えて新たな日付を生成 -----------
from dateutil.relativedelta import relativedelta
dt2 = start + relativedelta(months=20, days=25)  # datetime.datetime(2020, 1, 31, 0, 0)

# ２つの日付の差を、日単位で求める -----------
dt_dif = (dt2 - dt1)  # datetime.timedelta(days=635)
print(dt_dif.days)  # 635
# print(dt_dif.months)  # errorになります

# ２つの日付の差を、月単位/年単位で求める -----------
from monthdelta import monthmod  # エラー出たら pip install MonthDelta
mmod = monthmod(dt1, dt2)  # (monthdelta(20), datetime.timedelta(days=25)) <-タプル（リストみたいなもん）

## 月数差（余りは切り捨て）
print(mmod[0].months)  # 20

## 年数差（余りは切り捨て）月数差を12で割ります。月の日数は色々ですが、年の月数は常に12なのでこれでok
print(mmod[0].months//12)  # 1
```

# 参考
https://pythonhosted.org/MonthDelta/
Python入門勉強　～タプルを使った販売データの出力～

#目標設定

2020/0719
PyQを使った勉強のアウトプットのために
自分の学習記録を残しておくこと＋自分の同じ立場の人にも読んでもらえるようなものを目指します。

原則的に学習に以下を意識します。
・基礎ばかりやらないで、基礎が終わり次第簡単なアプリケーション、ツールの作成に取り掛かる
・わからないところは、ささっと調べて、調べてもわからない場合は先に進む。
・プログラミングはあくまで自分の作りたいものを作る道具でしかないことを意識する。
・目標を明確に設定して期間も意識した学習をする。

小目標
PyQのカリキュラムを終わらせる。
現在：コンテナを学ぼう

大目標
Pythonでアプリケーションを作る。

#タプルを使った販売データの出力

###タプルとは？
タプルは、リストや辞書型といった複数の要素を管理するデータ型の一種。

・要素を追加・削除・変更できない
・() と , がトレードマーク
・使用メモリがリストに比べて小さい*
・多くの場合でリストよりタプルの方が早く演算できる*
・リストや辞書型と併用できる
・list() と tuple() 関数でデータ型は変更できる


問題：顧客IDが10以下で、販売額が100円以上のデータを出力してください。

コード
"""
sales = ((1, 100), (2, 30), (7, 150), (11, 120), (10, 100))

for sale in sales:
    if sale[0] <= 10 and sale[1] >= 100:
        print(sale)

"""

出力
"""
(1, 100)
(7, 150)
(10, 100)
"""


##集合のメソッド

集合（set）はリストに似たデータ構造ですが、以下の特徴があります。

・リテラルは、{'art', 'box'}のように波括弧を用います。
・イミュータブル（変更不可）なものしか入りません。
・同じものは1つだけ持てます。複数追加しても1つになります。
・順序がありません。イテラブルとして取得すると実行のたびに順番が変わることがあります。
・集合同士の演算があります。
・リストより探索が高速です。


集合のメソッド（追加・更新・削除）

add(item)
itemを追加します。

update(iterable)
イテラブルiterableの要素全てを追加します。

clear()	
全ての要素を削除します。

pop()
何れかの要素を削除し返します。

remove(item)
itemを削除します。itemが存在しないとエラー（KeyError）になります。

discard(item)
itemを削除します。itemが存在しなくてもエラーになりません。

"""
items = {'art'}
print("items:", items)

# 1要素を削除
result = items.pop()
print("items.pop():", result)
print("items:", items)

# リストを追加
items.update(["egg", "fog"])
print("items.update(['egg', 'fog'])")
print("items:", items)

# 全削除
items.clear()
print("items.clear()")
print("items:", items)

# 追加
items.add("doll")
print("items.add('doll')")
print("items:", items)

# 削除
items.remove("doll")
print("items.remove('doll')")
print("items:", items)
"""

#出力
items: {'art'}
items.pop(): art
items: set()
items.update(['egg', 'fog'])
items: {'fog', 'egg'}
items.clear()
items: set()
items.add('doll')
items: {'doll'}
items.remove('doll')
items: set()
【入門】IAMを利用したAWSリソースにアクセスする仕組み

# はじめに
AWSを利用してシステム開発をする際やAWSアソシエイト試験の勉強をしている際に、「AWSのリソースにアクセスするためにはIAMの制御が必要とあるけど、IAMは実際にどう利用されているんだ？」と気になったので調べてみました。AWS初心者なので、間違ってましたらご指摘頂けると助かります。

# IAMを利用したAWSリソースにアクセスする流れ
#### AWSリソースにアクセスする仕組み
AWSのBlackBeltのIAMドキュメントによるとAWSリソースにアクセスするための仕組みは以下のようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555434/8e6b71ed-30f9-866b-07f7-69493afe617d.png)
1. プリンシパル
2. 認証
3. リクエスト
4. 認可
5. アクション/オペレーション
6. AWSリソース<br>
例を用いてこの順番に沿って記載していこうと思います。

#### ケース1:EC2インスタンスからS3のデータを更新する仕組み
1. EC2がS3にアクセスしようとする。
2. EC2に付与されているIAMロールに基づいてAWS STSが働き、STSが一時的に利用可能な認証情報であるCredentials(アクセスキー、シークレットアクセスキー、トークン)を払いだす。
3. 取得したCredentialsを元にS3にアクセスする。
4. S3はロールにアタッチされているポリシー(アイデンティティベースのポリシー)やリソースにアタッチされているポリシー(リソースベースのポリシー)やACLなどのその他のポリシーを元に認可を実施する。<br>
5. EC2にてS3のデータを更新するオペレーションを実施する。
6. S3のデータが更新される。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555434/209f803a-df8f-940a-da3a-128394651e15.png)

#### ケース2:開発者アカウントを利用して本番環境のS3データを更新する仕組み
0. 前提として、開発者アカウントには本番アカウントのs3-roleの引き受けを許可するポリシーが設定されており、本番アカウントにはs3-roleを誰が引き受けられるか定義した信頼ポリシーがs3-roleに設定されている。
1. 開発者が本番環境のS3データを更新しようとする。
2. 開発者アカウントのアクセスキーによる認証が実行され、s3-roleを引き受け、一時的な認証情報であるCredentials(アクセスキー、シークレットアクセスキー、トークン)をを開発者アカウントが取得できる。
3. 取得したCredentialsを元にS3 APIの呼び出しを行う。
4. S3はロールにアタッチされているポリシー(アイデンティティベースのポリシー)やリソースにアタッチされているポリシー(リソースベースのポリシー)やACLなどのその他のポリシーを元に認可を実施する。
5. S3 APIにてデータを更新するオペレーションが実施される。
6. S3のデータが更新される。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555434/d86e0419-274a-e861-72eb-64dc9f84dfba.png)<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555434/13bf2ea8-92ef-d690-e1ef-fd022d0baf73.png)

# 最後に
IAMを利用したAWSリソースにアクセスする仕組みをまとめてみました。業務でもAWSを利用しているのですが、AWS STSが重要な役割を果たしているとは露知らず、新たな発見でした。

# 参考元
・BlackBeltのIAMドキュメント:<br>https://d1.awsstatic.com/webinars/jp/pdf/services/20190129_AWS-BlackBelt_IAM_Part1.pdf
・アイデンティティベースのポリシーとリソースベースのポリシーについて:<br>https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_identity-vs-resource.html
・IAM Roleを理解する
http://blog.serverworks.co.jp/tech/2018/02/16/understarnd_iam_role/

記事内に誤りがあればご指摘いただけると嬉しいです！
JSON Serverを利用してみる

# json-server をインストール

```
$ npm install -g json-server
```

# json ファイルを用意する
```json
{
    "data" : [
        {
            "id": 1,
            "name": "apple",
            "price": 100
        },
        {
            "id": 2,
            "name": "orange",
            "price": 200
        }
    ]
}
```

# json を登録する
```
$ json-server list.json

  \{^_^}/ hi!

  Loading list.json
  Done

  Resources
  http://localhost:3000/data

  Home
  http://localhost:3000
```

http://localhost:3000/data にアクセスすると json が返る。

---

# POSTリクエストに対してresponseを返す

*  middleware を咬ませて GET と見せかける。

```middleware.js
 module.exports = function (req, res, next) {
  if (req.method === 'POST') {
      req.method = 'GET' // GETに偽装
      // req.url += '_post' // アクセス先をPOST用に変更
  }
  next()
}
```

* 起動する

```
$ json-server -w db.json -m middleware.js
```
【解決】sinatra-validationの書式が変わってて苦労したメモ

# 問題
少し前に作ったsinatraアプリを流用したら、validationでエラー発生。

# 結論
[dry-validation](https://dry-rb.org/gems/dry-validation/) のバージョンが変わって、書式が変わっていた模様

## 流用元のコード
```ruby
post '/hoge' do
    validates {
        required(:fuga).filled(:string).format?(DATE_FORMAT)
    }
    ...
    200
end
```

## 修正後のコード
```ruby
post '/hoge' do
    validates{
        params{
            required(:fuga).filled(:string, format?: DATE_FORMAT)
        }
    }
    ...
    200
end
```

# その他
* sinatra-validationはdry-rbの中のdry-validationを使いやすくしてくれているもの、らしい
  * [sinatra-validation](https://github.com/IzumiSy/sinatra-validation) 
     * ↑のサンプルがちょっと古い模様
  * [dry-rb](https://dry-rb.org/)
     * 色々揃いすぎてて把握するのが大変
  * [dry-validation](https://dry-rb.org/gems/dry-validation/)
     * ここのドキュメントも掘り進めるのは大変
* dry-validationのソースコードも見たけど、格調高くてワタシには読み解けず。。
【解決】dropzone.js でサムネイル画像が正方形になってしまう問題→元画像の縦横比(ratio)でサムネイルを表示する方法

# dropzone.js では、サムネイル画像の縦横比がスクエア（正方形）になってしまう。
というか、ピクセル数でしか指定できない。


##縦長か横長か、どちらが長いか確定している場合

長い辺が確定している場合は、長い方を最大値にすることはできるようだ。

オプションを下記のように指定する。

```
 var myDropzone = new Dropzone('div#dropImages', { 
      thumbnailWidth: null,
      thumbnailHeight: 300
 }
```
または　縦横が逆のときは下記。

```
      thumbnailWidth: 300,
      thumbnailHeight: null
```

しかし、どちらが長辺か確定していない場合は、記述がなかった。

##どちらが長辺か確定していない場合

後記の参考URLにあった例をもう少しいじって、
オプション内で手動で計算したらできた。

###長辺が300pxになる例。


```
 var myDropzone = new Dropzone('div#dropImages', { 
      previewsContainer: ".dropzone-previews",
      acceptedFiles: "image/png,image/jpeg",
      maxFilesize: 10,
      thumbnailWidth: 300,
      thumbnailHeight: 300,
      resize: function(file) { // thumbnail keep image ratio
        var resizeInfo = {
            srcX: 0,
            srcY: 0,
            trgX: 0,
            trgY: 0,
            srcWidth: file.width,
            srcHeight: file.height,
            trgWidth: (file.width>file.height?this.options.thumbnailWidth:this.options.thumbnailWidth*(file.width/file.height)),
            trgHeight: (file.width>file.height?this.options.thumbnailHeight*(file.height/file.width):this.options.thumbnailHeight),
        };
        return resizeInfo;
      }
    })
```

無事解決した。

私の３時間の集中力がみんなの時短につながりますように。

参考url)
https://stackoverflow.com/questions/22740117/dropzone-resize-function
上記URL内に追記する権限がなかったため、qiitaこちらに記載することにした。
Webページに載っている特定のデータをwgetで一括ダウンロードする

一つ一つクリックしたらダウンロードできるけど、wgetで一括ダウンロードしたいと友人に聞かれたときのことをメモ。

BIの分子データを載せているサイトらしい、以下のサイトからダウンロードする。
https://www.ebi.ac.uk/arrayexpress/experiments/E-MTAB-8581/files/

# 手順
以下のコマンドでダウンロードできた。
<pre>$ wget -r -l 1 -A txt,gz -w 1 -nd https://www.ebi.ac.uk/arrayexpress/experiments/E-MTAB-8581/files/</pre>

# 解説
`-r -l 1`
---
`-r`でリンク先にリンクがあればダウンロード、そこにまたリンクがあればダウンロード、、、と再帰的にダウンロード。
`-l`でリンクをたどる回数を指定。`1`を指定することで、そのWebページに貼ってあるリンクのみを複数ダウンロードする。


`-A txt,gz`
---
`-A`でダウンロードする拡張子を指定する。ここでは`txt`と`gz`を指定。

`-w 1`
---
ダウンロード処理の間隔を一秒開ける。ダウンロード先の負担を軽減するために一応指定

`-nd`
---
同一のディレクトリへのダウンロードを指定。
これがないとWebページの`/home/index/hoge/`のようにURLの階層通りにダウンロードが行われる。

# 参考
- [【 wget 】コマンド――URLを指定してファイルをダウンロードする：Linux基本コマンドTips（24） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1606/20/news024.html)
- [ウェブページにリストアップされているpdfファイルをwgetでまとめてダウンロードする方法 - Wolfeyes Bioinformatics beta](http://yagays.github.io/blog/2012/10/10/shut-the-fuck-up-and-download-all-pdf-files/)
font-sizeにvwを使うんじゃねぇ！！

強気タイトルでごめんなさい。

最近のモバイルページのサイズ指定に思うところがあったので投稿させていただきます。

twitterで流れてきて気になったのですが、どのデバイスで見ても同じように見えるようにとサイズ指定をvwを使われるケースが多くなってきているそうな。
これ、やる気持ちはすごくわかるんですよね。
けどちょっと待ってくれ、本当にそれでいいのか？という内容の記事です。


# なぜvwを使うのか
上にも書かせてもらったように、vwでサイズ指定してあげるとどのデバイスでみた時にも同じような見え感になるからという理由でvwを採用している方が多いかと思います。
デザイナーに用意していただいたものそのままで再現できますもんね。

僕もちょっと前には「vw最高やん」とSPのcssにはほぼ全てのサイズ指定をvwでやっていた時期がありました。
けどこれに疑問を持ち始めた原因が、Nexus7という端末です...


# 何がおこったのか
僕の日頃担当させていただているサイトでは、横幅768px（iPadサイズ）を境にしてPCとSPの2パターンをmediaqueryで切り替えて実装しています。

当時、PCにはサイズ指定をpxで絶対指定しつつ、SPの方はvwを使っており、
vwの計算をいちいちするのも時間がかかるのでpx↔︎vw変換表なんてものをExcelで作って印刷したものを手元において「スピーディーにコーディングできてるわ！」と浮かれていたものです。

ところが実家に帰った時に使われていたNexus7（横幅600px）という端末でページをみた時に感じちゃったんですよね。
「**デケェ...**」

サイズ的にNexus7ではSPレイアウトが表示されます。
別にデザインが崩れたりしていたわけじゃないんですけど、
不必要に文字サイズが大きくなりすぎているのが気になってしまいました。
そしてこれを機にvw指定を見直すことになったわけです。


# vwの良くない点
#### タブレットの利点を無くす
タブレット系のデカめ端末の利点って、スクロールをしなくても1画面で多くの情報を同時に見えることだと思うんですよね。
けどこれをvwで指定しちゃってると普通のケータイと見えるのと変わんなくなってその利点が死ぬ。

まあ僕のきっかけになったNexus7はもう古い端末なんでそんなに気にしなくてもいいかもですけど、情報が多く見えるって利点を無くしちゃうのはあんまりよろしくないかと。

#### retina対応
僕は綺麗なページが好きです。
綺麗なページを作るためなら多少めんどくさくてもretina対応させるために、画像サイズを2倍で用意してcssで半分のサイズに縮めて表示ってことをやってます。この元画像の半分サイズってのが大事でそれを実現するにはpxで絶対指定してあげるしかないかと思ってます。

じゃあ画像のサイズ指定だけpxで他はvwを使って...てしちゃうと次は端末によってトンマナが合わなくなってきちゃいます。
例えば、特殊なフォントを使いたい部分ってhtmlじゃなくて画像で対応することってありますよね。けど画像サイズは固定なのに、文字サイズはvwだと何が起こるでしょうか？
特殊フォントって見出しとかに使ったりすることが多いんですよね。見出しより普通のテキストがデカい！みたいなことが起こり得るわけです。

#### めんどくさい。
px使いに戻って振り返ると、やっぱりいちいちPSDとかXDに指定されてるpxをvwに変換して、、、ってめんどくさいよなと。
めんどくさくてもそれで綺麗なページができるなら僕はやりますよ！
けど上の問題を抱えながら時間をかけてまでやることじゃねーという結論に至りました。


# まとめ
vwが良くない理由を書かせていただきましたが、px指定にも問題はあるなとは感じでます。
端末によって嫌な位置で改行されることになっちゃって悩んだりとかね。

結局僕は上のようなことで悩んだ結果px指定に戻ったワケなんですけど、世間的にはあまり絶対指定にポジティブな意見が見えなかったのでどうなんでしょう。

閲覧ありがとうございました。

# ps
font-sizeにmax-sizeが指定できたりすると結構解決できたりするのかなとか思ったりします。
mediaqueryのパターン分けを2つより増やすってのはむずかしいです、工数的に。やってるとこもあんまり見かけないですよね。
タイトルに「font-sizeに..」って書いちゃったんですけど、font-sizeに限らずvw指定やめようって記事になっちゃいました。
Jenkins をローカルでさらっと使うための手順

## ローカルで Jenkins を動かす目的
組織のポリシーで CI サービスを使わせてもらえず、サーバーも立てさせてもらえないときの最終手段です。

次の順序ですすめます:

1. ローカル PC で Jenkins を動かし、デプロイを Jenkins で自動化します
2. 社内 LAN 経由で HTTP アクセスできるよう Jenkins を公開し、周りにデプロイジョブを使わせてあげます
3. テストを自動化し、実行を Jenkins に任せます
4. 静的解析など、レポートのためのジョブを中心に追加して周りに Jenkins のレポートを公開します

これをやると、大体どんな組織でも徐々にワークフローが Jenkins に依存するようになり、
「CI・CD をちゃんとやろう」という流れになります。

## ローカルで Jenkins のサービスを起動する方法

### Docker が使える場合

1.
次の `docker-compose.yml` を用意します:

```yaml
---
version: "3.8"
services:
  image: jenkins/jenkins:lts
  volumes:
    - jenkins_home:/var/jenkins_home
  ports:
    - 8080:8080
    - 50000:50000
```

これは[公式の docker コマンド](https://github.com/jenkinsci/docker/blob/master/README.md#usage)を Docker Compose に置き換えたものです。

Jenkins の公式イメージはこちらになります:
[jenkins/jenkins - Docker Hub](https://hub.docker.com/r/jenkins/jenkins/)

Docker Hub 公式は、Jenkins 公式のイメージに移行したため、更新終了し、非推奨となりました。
[jenkins - Docker Hub](https://hub.docker.com/_/jenkins)

動作の詳細は GitHub の README.md を参照します:
[jenkinsci/docker: Docker official jenkins repo](https://github.com/jenkinsci/docker/blob/master/README.md#usage)

### Docker が使えない場合

以下は Windows の場合の説明を行います。
Windows にJenkins をインストールすると、`IIS` のサービスとして起動することになります。

#### Chocolatey が使える場合

```console
choco install -y jenkins
```

参考: [Chocolatey の使い方 | ultra code](https://futureys.tokyo/how-to-use-chocolatey/)

#### Chocolatey が使えない場合

この場合も、インストールに特に面倒なことはありません。
インストーラーをダウンロードして実行するだけでインストールできます。
[Jenkins download and deployment](https://www.jenkins.io/download/)

## Jenkins のサービスの port を変更する方法

Web サービスなどを開発していると、
テストのために起動する開発中のサービスの port と競合してしまう可能性があります。
Docker の場合は port のマッピングを簡単に変えられるので問題ありませんが、
ここでは Docker を使わない場合、Jenkins のサービスの port を変更する手順を説明します。

### 手順

1.
次のファイルを、管理者権限で起動した Visual Studio Code で開きます:
`C:\Program Files(x86)\jenkins\jenkins.xml`

2.
ファイルを `8080` で検索し、`58080` に書き換えます。
(`0`-`49151`まではだいたい使用するアプリが決まっているため。)
参考: [TCPやUDPにおけるポート番号の一覧 - Wikipedia](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)

## Jenkins の設定を YAML で管理する方法

そのうち、Jenkins のサーバーを立てることになったとき、
ローカルから設定などを移し替えるのを楽にするために、
Jenkins の設定は YAML で管理するようにしておくことをおすすめします。

### 手順

1.
`Jenkinsの管理` -> `プラグインの管理` -> `利用可能` タブ をクリックします

2.
`Configuration as Code` と `Configuration as Code Support` にチェックを入れます

3.
`ダウンロードして再起動後にインストール` ボタンをクリックします

4.
`Jenkinsの管理` → `Configuration as Code` をクリックします

5.
`Path or URL` に以下を入力して `Apply new configuration` ボタンをクリックします

```
~/workspace/jenkins-yaml/jenkins.yaml
```
rpm -qa を実行した際にパッケージ名のみを表示するには

## 実現したいこと

rpm -qaを実行した際に

```
$ rpm -qa | sort | grep -e xz
xz-5.2.5-1.fc32.x86_64
xz-libs-5.2.5-1.fc32.x86_64
```
上記の様なパッケージがあった場合、以下のようにパッケージ名のみを表示させたい

```
## これを
xz-5.2.5-1.fc32.x86_64
xz-libs-5.2.5-1.fc32.x86_64

## このように
xz
xz-libs
```


## 実行コマンド

```
rpm -qa --qf "%{NAME}\n"
```

## 補足

バージョン番号も出したいとき

```
rpm -qa --qf "%{NAME}-%{VERSION}\n"
```

## 情報源

https://www.redhat.com/archives/rhl-list/2005-November/msg00394.html
Spring Boot本レビュー: まとめ

# まとめ

[Spring Boot書籍レビュー](https://qiita.com/tags/springboot%e6%9b%b8%e7%b1%8d%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc)してきましたが、その上で、私の考えるベストSpring Boot入門手順はこちらです:

1. Kindle Unlimitedで読める(通常価格は現在時点で780円)「[Spring Boot 2 入門: 基礎から実演まで](https://qiita.com/write_once_run_anywhere/items/43ec78ce851f9b1be410)」を読みつつ手を動かして作ってみる。
1. 物足りないなら[公式ガイド/チュートリアル](https://spring.io/guides)に機能紹介を兼ねたアプリケーションの作り方が紹介されているのでこちらも作ってみる。
1. 公式リファレンス(後述)を読んで理解を深める。
    1. 難しく感じるうようであれば[Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発](https://qiita.com/write_once_run_anywhere/items/32d70409c55ffb3d42c2)を併読する。


# 付録: 公式リファレンス

Spring Boot開発を行っていく上でよく参照するリファレンスのリンクをまとめておきます。
(たくさんありますが、よく見る箇所というのは限られているので慣れてくると大変というわけでもないです)

- [Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/): https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
    - ちなみに、SpringプロジェクトのリファレンスのURL、 `current` の部分をリリース番号(例えば `2.3.1.RELEASE`)にするとそのバージョンのものが見られます。
    - また、 `htmlsingle` の部分を `html` に変えるとセクションごとにページが分かれたリファレンスが見られます。
- [Spring MVC](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html)
- [Spring Security](https://docs.spring.io/spring-security/site/docs/current/reference/html5/)
- [Spring Data](https://spring.io/projects/spring-data/)
    - [Spring Data JPA](https://spring.io/projects/spring-data-jpa)
- [Thymeleaf](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html)([日本語版](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html))
- [Thymleleaf+Springインテグレーション](https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html)
- [MyBatis](https://mybatis.org/mybatis-3/ja/index.html)
- [JPA; Hibernate ORM](https://hibernate.org/orm/documentation/)
- [Bean Validation; Hibernate Validatior](https://hibernate.org/validator/documentation/)
- 上記外の[Spring Frameworkリファレンス](https://spring.io/projects/spring-framework)だと、 [Testing](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html) や [Core](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html)も

Springプロジェクトの、Spring Boot以外のリファレンスを参照する必要もあれば、Springプロジェクト外のリファレンスを参照する必要もある、というのがミソです。

また、Javadocコメントも比較的濃い情報が書いてあったりするので[^1]、そちらも参照することになります。

[^1]: 私は元々JBoss系(Java EE)でやっていたのですが、あっちは基本Javadocコメント役に立たなかったのでSpringに来て初めてコメント見たとき非常に驚き😲ました
世界中の AWS, Azure, GCP, CDNデータセンターへ一斉にパフォーマンス計測！高い日本のデータセンターじゃなくても良いかもね！

**グローバルプロジェクトでは必見！　測定を見ているだけでも楽しかったです！
各クラウドサービス毎、お勧め順に並べています。**

#全世界のAWSへ

【お勧め！】順番に自動測定、ソート可　(dynamodb.{}.amazonaws.com)
**https://ping.psa.fun/**
![AWS1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/cbb1aefd-a7b8-4173-5085-dff3bff527d8.png)

【お勧め！】一斉調査、任意でソート可　(ec2.{}.amazonaws.com/ping)
**https://cloudpingtest.com/aws**
![AWS3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/b94d8aef-9c1d-bc9e-4156-8c570d8fe0c5.png)

【お勧め！】順番に自動測定、自動ソート
**https://www.cloudping.cloud/aws**
![AWS4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/86e2451a-8564-e2a8-88e3-9880fbc0e762.png)


順番に自動測定
**https://www.cloudping.info/**
![AWS2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/0eaa991d-a6f0-faec-773c-1c77bc426f29.png)

#全世界のAzureを一斉計測してくれるツール達

【お勧め！】　一斉調査、平均で速い順にソートしてくれる　
**https://azurespeedtest.azurewebsites.net/**
![Speed1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/bb60c779-df0e-5406-bd85-733796227c0e.png)

【お勧め！】一斉調査、任意でソート可 ({}.blob.core.windows.net/public/callback.js)
**https://cloudpingtest.com/azure**
![Speed3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/ae9175e2-f8dc-a75f-614c-8066dfef1172.png)

任意のデータセンターへ一斉調査
**https://www.azurespeed.com/Azure/Latency**
![Speed2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/9353495e-7a31-f862-ed60-194e727b2558.png)

#全世界のGCP
【お勧め】一斉調査、短時間で自動ソート (ping f1-micro)
**http://www.gcping.com/**
![GCP2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/2808b8fc-e06e-8f86-f248-2c26ead93670.png)

【お勧め】一斉調査、任意でソート可({}-gce.cloudharmony.net/probe/ping.js)
**https://cloudpingtest.com/gcp**
![GCP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/867b7ca6-516c-c799-3b87-a5504d9de383.png)

#最寄りのCDNの計測
【お勧め】**https://www.cloudping.cloud/cdn**
![CDN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/afbc76e5-85bb-4d01-f712-1af196f7d108.png)

#安い場所はどこか教えてくれるツール
Azure VMの場合
**https://www.azurespeed.com/Information/AzureVMPricing**
![Speed4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/b04a33bc-4d25-17ce-1eb0-01185354ddc2.png)
シェルスクリプトの説明をコメントで書いてコマンドラインでヘルプとして表示する

# Motivation

実行可能なシェルスクリプトを書く際、なるべく `-h` や `--help` のような引数でヘルプメッセージを表示できるようにしておきたい派です。
以前はPOD形式[^1]でファイル末尾にドキュメントコメントを書き、 `pod2text` を実行して表示していたのですが、以下の理由でやり方を変えたいと思いました:

[^1]: https://perldoc.perl.org/perlpod.html

- どちらかといえばファイルの先頭に書きたい
- PODで書くと行数が長くなりがち
- 最近、PODを書く機会がほとんどないので、毎回記法を忘れている
- `pod2text` がどの環境でも動くという前提は置かない方がいいかもしれない（？）[^2]

[^2]: ちゃんと調べきれてはいないのですが、最近クラウドに立てたVMとかには入ってなかったような…

2ヶ月前ぐらいから悩んでいましたが、ようやくこれでよいかなというやり方にたどり着きました。

ヒアドキュメントで十分という人には無用のやり方かもしれませんが、以下で示すようなやり方にしておけば、スクリプトのフォーマットを揃えることができるでしょう。

# 動作確認環境

 OS | Bash | AWK
----|------|-----
 Ubuntu 18.04 | v4系 | mawk 1.3.x
 Ubuntu 20.04 | v5系 | mawk 1.3.x
 macOS Mojave | v5系 | v20070501
 macOS Catalina | v5系 | v20070501

# 結論

シェルスクリプト内に、次のようなhelp関数を定義することにしました:

```sh
# bash
help() {
  awk 'NR > 2 {                          # シバンは出力しない
    if (/^#/) { sub("^# ?", ""); print } # /^#/ にマッチしたら "^# ?" を取り除いて出力
    else { exit }                        # /^#/ にマッチしなくなったら終了
  }' $0 # 実行スクリプト自身を引数に取る
}
```

中でawkコマンドを呼び出して、マッチする行をヘルプメッセージとして出力します。

AWKに依存する形になりますが、POSIXの仕様を逸脱しなければ、pod2textに依存するよりはポータブルなのではないかな、と考えています。

※AWKスクリプトをもっと短く書けないの？ という方は[コメント欄](#comments)をご確認下さい。

# 動作例

下のようなシェルスクリプトを書いて、ヘルプを表示してみます。

```sh:help-demo.sh
#!/usr/bin/env bash
#
# help-demo.sh
# ============
#
# Demo script to show help by shell function using AWK.
#
# Usage:
#
#     help-demo.sh [-h|--help]

# Function help() shows help
help() {
  awk 'NR > 2 {
    if (/^#/) { sub("^# ?", ""); print }
    else { exit }
  }' $0
}

# help関数を実行
help
```

ヘルプ表示結果:

```
$ ./help-demo.sh --help
help-demo.sh
============

Demo script to show help by shell function using AWK.

Usage:

    help-demo.sh [-h|--help]
```

こんな感じでMarkdown形式で書いておけば、そのままREADMEに使うこともできそうですね。

# 他のやり方

上の結論に至るまでに、下に挙げた参考記事などを見ながら、どうしようかと考えていました。

1つ目の参考記事にあるように、sedコマンドを用いても同様のことは実現できるようでしたが、sedのスクリプトに馴染みがなく、すぐに習熟できる気がしなかったため、AWKを使うことにしました。
（AWKスクリプトの方がhuman readableな気がしました。）

以上です。

# 参考記事

- [シェルスクリプトでヘルプメッセージをコメントに書いて表示する - Qiita](https://qiita.com/ngyuki/items/673d6cb3b36360eaf5cc)
- [自作シェルスクリプトにヘルプやらバージョンメッセージを実装？する面白い方法があった - Qiita](https://qiita.com/TomKid/items/ab49f8d0cd15b18e5e4a)

# AWKの資料

- [awk - POSIX Documentation](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html)
- [AWK | progrhyme's Tech Notes](https://progrhy.me/tech-notes/a/cli/awk/) ... 筆者のメモ書き

# 脚注
【ReportAsSingleViolation】そのカスタムバリデーションを車輪の再発明にならないために【既存アノテーションをまとめる】

# なぜSpring Bootで独自のバリデーションを作りたいの？
API開発を複数人で進めていると、APIで同じ項目が出てきます。

- 注文番号（orderNo）
- 商品コード（itmCd）
- 管理番号（mngNo）
- ユーザーID（usrId）
- 等々...

同じ項目であれば、同じアノテーションでバリデーションする事が当たり前。でも、ドキュメントやルールの周知を頑張っても意思疎通がとりきれずアノテーションがズレたものがポロポロと。。

そんなときの解決策の1つとして、カスタムバリデーションがあると思っています。

# カスタムバリデーションのパターン
大きく分けて、２つあると思っています。

- 完全オリジナルなロジックが必要なもの
- 既存バリデーションの組み合わせで済むレベルのもの

**後者を作成するとき、自前でロジックを組んでいませんか？**

**`@ReportAsSingleViolation`**の利用検討をお勧めいたします。

# ReportAsSingleViolation
一言でいうと**「アノテーションをまとめるアノテーション」**

どうゆうことか、以下ソースの後にポイントを記載します。

~~~ java:UsrId.java
@Documented
@Constraint(validatedBy = {})
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Size(min = 8, max = 10)
@Pattern(regexp = "^[a-zA-Z0-9]*$")
@ReportAsSingleViolation
public @interface UsrId {

    /** エラーが発生した場合のエラーメッセージ. */
    String message() default "ユーザーIDが正しく設定されていません";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}
~~~

## Constraint(validatedBy = {})
`{}`なんです。
やりたいことが既存の組み合わせで完結する場合、ロジックを記述する**バリデータークラスは必要ありませんよね。**
実際、このカスタムアノテーションはアノテーションの組み合わせだけで完結しています。

## message() default "xxx"
`@ReportAsSingleViolation`を利用するとデフォルトメッセージが機能します。これがすごい。
バリデーション動作時には`@Size`と`@Pattern`それぞれのメッセージ２つは出力されず、自分が設定したメッセージだけが出力されます。
**つまりアノテーションがまとまっているんです。**

# さいごに
`@ReportAsSingleViolation`を作ればファイル1つでカスタムバリデーション完成です。

カスタムバリデーションって難しそうだから忙しいし、今のプロジェクトへの適用は後回し。。という固定概念を破壊するくらいの手軽さ。

しかし効果はしっかり発揮します。
サンプルではユーザーID 項目を使う複数のDTOクラスやGETパラメータに以下がバラまかれるのを防ぎました。
- `@Size(min = 8, max = 10)` 
- `@Pattern(regexp = "^[a-zA-Z0-9]*$")`

ルールとして`@UsrId`を使おう！というのは必要になります。ですが、特定の引数を付けたバリデーション利用を徹底してください。というルールよりはマシではないか思っています。


是非お試しくださいませ。
新品のMacにとにかくanacondaをインストールする

# 0. はじめに

PCを新調するたびにanacondaをMacに入れる方法をいつも調べてしまうので書き留めています。開発業務じゃなくても入れておくと何かと便利なので。

以下のステップでインストールします。

1. pyenvのインストール
2. anacondaのインストール

# 1. pyenvのインストール

pyenvをgithubからクローンします。
gitを初めて使うときはcommand line toolsのインストールを促されるかも。

```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

pyenvのパスを通しておきます。

```bash
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zprofile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zprofile
$ echo 'eval "$(pyenv init -)"' >> ~/.zprofile
```

これでpyenvが使えるようになるのでターミナルを再起動しておきます。

# 2. anacondaのインストール

インストール可能なanacondaを以下のコマンドで確認します。

```bash
$ pyenv install --list | grep anaconda
```

以下のコマンドでanacondaをインストールします。

```bash
$ pyenv install 入れたいバージョンのanaconda
```

いつも使うはずなのでグローバルに設定しておきます。

```bash
$ pyenv global ↑で入れたバージョンと同じもの
```

以上
【React】webpackエラー解決方法"Plugin/Preset files are not allowed to export objects, only functions."

#発生しているエラー

```shell

ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Plugin/Preset files are not allowed to export objects, only functions. In /Users/program/Electron/electron-quick-start/electron_hello/node_modules/babel-preset-es2015/lib/index.js
    at createDescriptor (/Users/program/Electron/electron-quick-start/electron_hello/node_modules/@babel/core/lib/config/config-descriptors.js:178:11)
    at items.map (/Users/program/Electron/electron-quick-start/electron_hello/node_modules/@babel/core/lib/config/config-descriptors.js:109:50)
    at Array.map (<anonymous>)
hain.js:67:36)
    at buildRootChain.next (<anonymous>)
    at loadPrivatePartialConfig (/Users/program/Electron/electron-quick-,,,
```

#解決方法

```webpack.config.js
const path = require('path')
const webpack = require('webpack')

const externalPlugins = new webpack.ExternalsPlugin('commonjs', [
    'app',
    'auto-updater',
    'browser-window',
    'content-tracing',
    'dialog',
    'electron',
    'global-shortcut',
    'ipc',
    'menu',
    'menu-item',
    'power-monitor',
    'protocol',
    'tray',
    'remote',
    'web-frame',
    'clipboard',
    'crash-reporter',
    'screen',
    'shell'
])

module.exports = {
    entry: {
        index: path.join(__dirname, 'src', 'index.js')
    },
    output: {
        path: path.join(__dirname, 'out'),
        filename: '[name].js'
    },
    devtool: 'cheap-module-eval-source-map',
    target: 'node',
    module: {
        rules: [
            {
                test: /.js$/,
                loader: 'babel-loader',
                options: {
                    presets: ['es2015', 'react']
                }
            }
        ]
    },
    plugins: [
        externalPlugins
    ]
}
```

上記ファイルの、```presets: ['es2015', 'react']```を```presets: ['@babel/preset-env']```に変えるだけ！


#最後に
私はこの沼に数時間はまりました、、、