OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeで Rails + Mysql 環境作ってみた

## 動機
会社でRails案件を行うことになったので、docker-composeを使って開発環境の構築を行おうと思い手順書みたいに書いてみました。
なので、個々の説明は省きます
今回はlocal環境にあるRailsをdocker内に持っていって起動させることを目標にしてます。
サンプルコードは[こちら](https://github.com/takahiron/sample_docker)になります

## Rails
Railsは以前書いた[Macでrailsプロジェクト立ち上げ](https://qiita.com/takahiron/items/09bf1073b460c6fcd0fc)で行ったRailsを使用します。
上記Railsで`database.yml`に追記します。

```ruby:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: root # パスワード追加
  host: <%= ENV.fetch("DB_HOST_NAME") { "localhost" } %> # 追加
```

## Dockerfile作成
Railsドキュメントルートに`Dockerfile`を作成します。

```Docker:Dockerfile
FROM ruby:2.5.1-alpine
MAINTAINER admin
RUN cd /tmp \
  && apk --no-cache add \
    curl \
    curl-dev \
    nodejs \
    libstdc++ \
    libxml2-dev \
    libxslt-dev \
    linux-headers \
    mysql-client \
    mysql-dev \
    pcre \
    ruby-dev \
    ruby-json \
    tzdata \
    yaml \
    yaml-dev \
    bash \
    build-base \
    zlib-dev \
  && mkdir /sample_docker/
WORKDIR /sample_docker/
COPY Gemfile* /sample_docker/
RUN gem install bundler \
  && bundle install --clean --path /bundle
COPY . /sample_docker/
CMD ["bundle", "exec", "rails", "s"]
```
上記でRailsが起動できるOSやソース配置場所等を設定しています。

```yaml:docker-compose
version: '2.1'
services:
  rails_app:
    stdin_open: true
    build: .
    environment:
      DB_HOST_NAME: mysql
    volumes:
      - .:/sample_docker
      - bundle:/bundle
    ports:
      - 3000:3000
    links:
      - mysql
  mysql:
    image: mysql:5.6
    ports:
      - 3307:3306
    restart: on-failure
    environment:
      MYSQL_DATABASE: sample_docker_development
      MYSQL_ROOT_PASSWORD: root

volumes:
  bundle:
    driver: local
```
rails_app は`Dockerfile`の環境で動作しmysqlは別のimage環境で動作するようになります。
一番下にマウント処理を設定して、`driver: local`で明示的にlocal環境を見に行かせています。
これがないと、新たにGemfileにgemを追加した場合`docker-compose run bundle install`だけではgemが入らなず、いちいち`docker-compose build`しなければならないので面倒です。

## docker起動
dockerを起動する前にimageを作成します。

```
$ docker-compose build
```

その後、Railsで設定してあるDBとtableを作成します。

```
$ docker-compose run rails_app bundle exec rails db:create db:migrate
```
*  上記起動しなかった場合さきに`docker-compose up`を行ってから実行してみてください。

docker起動

```
$ docker-compose up
```

## 今後
まだまだ全然使いこなせていなんですが、今後は開発環境だけでなく本番環境でもdockerを使っていこうと思います。
チームで行うにはdockerを知っていないときついと思うので、どう共有するかも考えないといけないですね。
vscodeで正規表現置換　超個人的メモ

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
ファイル内でcmd+fで検索バーを開いた後、右の正規表現マークを押す。

上(img.*)(src=)
下$1data-src=
でエンターで
$1にimg.*が入る。

キャプチャーグループというやつらしい。
AWS CodeDeployで デプロイ設定を変えようとしたら、doesn't have permission to perform the following operation エラー

###AWS CodeDeployで デプロイ設定を変えようとしたら、エラーが出た

```
he service role arn:aws:iam::XXXXXXX:role/xxxxx doesn't have permission to perform the following operation: autoscaling:DescribeLifecycleHooks
```

え、roleもポリシーも変えてないのになんで？

###調べてみた


[困っとる人いた](https://stackoverflow.com/questions/39605476/the-service-role-arnawsiam20011470201role-deploy-doesnt-have-permission-to/39669691)

```
I have code-deploy set-up between by bit-bucket account and my Amazon AWS instance.
I am able to deploy to the test server everyday without issue.
But when i try to add the instance of our production server to the list of instances, i get the above error


Note: I have added this instance and successfully deployed the code in the past , i'm not sure why i get this error now.

Any directions/hints on how to solve this would be appreciated.
```

つまり、何も変えてないのにいきなりエラーになったよ。
同じ現象にあってる人に会うと嬉しい。

###そして解決方法
- autoscalingの権限があるポリシーを作成しましょう

autoscaling:DescribeLifecycleHooksって書いてあるけど、autoscaling全権上げた方が早い。


<img width="1138" alt="スクリーンショット 2018-07-17 10.59.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/9bbb6fd0-b36c-6c3e-8a93-4629ce466453.png">
<img width="1096" alt="スクリーンショット 2018-07-17 10.59.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/eb55b435-cc48-4dfa-769f-158f067978a5.png">

- roleに作成したポリシーをアタッチ

今回は`CodeDeployAutoscalingDescribeLifecycleHooks`という名前でroleを作成しました

<img width="1109" alt="スクリーンショット 2018-07-17 11.02.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/d002f71c-cfd6-2c54-5ecb-2139040235a9.png">


再度、CodeDeployで設定を変えて保存したら、保存できるようになりますよ
GitでGUIツールからCUIツールに切り替える際に抑えておきたいコマンドまとめ

#はじめに
ある日Gitでソースコード管理を行う際にGUIツールを使っていたところ、先輩から「勉強になるからCUIツールを使ってみたら」とアドバイスをいただきました。
そして実際にCUIツールを使ってみたところ案外悪くないと感じ、現在は勉強しながらCUIツールを用いています。
そこでこの記事では、現在GUIツールを用いている方が、CUIツールに切り替える際に最低限抑えておきたいコマンドをまとめてみました。

##クローン
まずはクローンです。クローンを行いたいディレクトリに移動し、
> git clone 「gitのcloneURL」

と入力すればOKです。

##ブランチとチェックアウト
次にブランチを生成しましょう。ブランチの生成は
> git checkout -b 「新しく生成するブランチの名前」

で現在のブランチを元に新たなブランチを生成することができます。なお、ブランチの一覧は
>git branch

で調べることができ、
>git checkout 「ブランチ名」

で移動することができます。また、開発が終了し、不要になったブランチは
>git branch -d 「消去したいブランチ名」

で消去することができます。

##コミット
チェックアウトしたブランチで開発を行ったら、コミットを行います。
まず、コミットする変更をステージングエリアに追加するには
>git add 「追加したいファイル名」

と入力します。変更が複数あり、まとめて追加したい場合は、
>git add .

と入力します。そしてコミットを行う際は
>git commit -m "「コミットメッセージ」"

と入力すればOKです。これらをまとめて一回で行いたい場合は
>git commit -a -m "「コミットメッセージ」"

と入力すれば可能です。

##プッシュとプル
コミットした内容をリモートにプッシュする際は
>git push「プッシュする送出先のリモート名」 「プッシュするブランチ名」

と入力します。送出先のリモート名は「origin」となっていることが多いかと思いますのでその場合は
>git push origin 「プッシュするブランチ名」

と入力すればOKです。

新たに開発を行う際は、再度リモートの内容をプルして反映させるかと思います。その際はプルしたいブランチにチェックアウトした後で、
>git pull 「プルしたいリモート名」 「プルしたいブランチ名」

と入力すればプルできます。

##その他
CUIツールにおいても当然ブランチやコミットの情報や履歴、差分を知ることができます。
> git status

ではコミット済みの変更があるかなど、現在のブランチの状態を知ることができますし、
> git log

ではコミットやマージなどのブランチの履歴を知ることができます。また、
>git diff

と入力するとファイルの変更の差分を知ることができます。
ここでは簡単に触れただけですが、これらのコマンドはオプションも多く、使いこなせるとより便利になりそうです。

#おわりに
CUIツールを用いる際に最低限抑えておきたいコマンドをまとめてみましたが、紹介したコマンドにもさらにオプションがあり、私自身もまだまだ学ぶことが多いように感じています。GUIツールを用いていた方がCUIツールに挑戦する際の助けに少しでもなれば幸いです。お読みいただきありがとうございました。
[Python小ネタ]同一カーソル位置で文字を連続でprintする

printする文字の前に`\033[A`をつけます。
そのままfor文でprintしてしまうと早すぎてわからないので、今回は`time.sleep`を使ってスピードを調整しています。
また、`\033[3{i}m`を使うことで、出力する文字に色もつけて遊べます。

```python:a.py
import time

print("連続で出力するよ\n")
for i in range(8):
    print(f"\033[A{i}")
    time.sleep(0.5)

print("色もつけてみたよ\n")
for i in range(8):
    print(f"\033[3{i}m\033[A{i}")
    time.sleep(0.5)

```

これを実行するとこんな感じで出力されます。

![a.gif](https://qiita-image-store.s3.amazonaws.com/0/171438/276a96a9-87a3-7a85-7d94-0be7cea677a2.gif)
git コマンド

gitのコマンド忘れやすいのでメモ
自由に使ってください。

### Gitの作業ディレクトリ作成
`$ git init`
## Gitの登録
`$ git config --global user.name "{Username}"`
`$ git config --global user.email {yourmail@example.com}`
Proxyは以下のコマンド
`$ git config --global http.proxy http://{id}:{pass}@{example.proxy}:8080`
`$ git config --global https.proxy http://{id}:{pass}@{example.proxy}:8080`

### もしくはエディタで編集（こっちの方が楽かも）
コマンドから編集する場合(vimを指定)
`$ git config --global core.editor 'vim -c "set fenc=utf-8"'`
次回からは
`$ git config --global -e`

直接変更する場合は
`$ vi ~/.gitconfig`

```ini:~/.gitconfig
[user]
        name = {UserName}
        email = {yourmail@example.com}
[http]
        proxy = http://{id}:{pass}@{example.proxy}:8080
[https]
        proxy = http://{id}:{pass}@{example.proxy}:8080
[core]
        editor = vim -c \"set fenc=utf-8\"
```
## よく使うモノ
### AddとCommit
`$ git commit -am "commit comment!"`

|オプション|意味|
|---|---|
|-a|既存ファイルをaddする|
|-m|コメントを残す|

※新しいファイルを作成した時は、commitのオプションaが効かないので
commitの前に`$ git add .`する必要がある。

### Log
gitのlogはバージョンを行ったり来たりする際に
大事なIDやコメントを確認するため頻繁に使用する
`$ git log`
おすすめは、ログの一行表示
`$ git log --oneline`

## Checkout
gitのceckoutは、古いバージョンに戻ってファイルの内容を確認したり
元の場所に戻ったりできる。
### 1. 戻りたいidを確認
`$ git log`

```shell-session
$ git log
commit f7a7cbf614862d468f7afdad4451c91e07911fae
Author: {user} <yourmail@example.com>
Date:   Tue Jul 17 09:58:52 2018 +0900
```
IDは一意に決まればいいので、他のIDとかぶっていなければ
先頭から5つくらいの数字で良い
### 2. checkoutで戻る
例として以下のidのように5つの数値のidで戻りたい場所を選択
`$ git checkout f7a7c`
### 3. checkoutで元のバージョンに戻る
`$ git checkout master`

## Remote
gitのremoteはリモート用のディレクトリが必要
今回はローカル環境のためurlの代わりにdirectoryを使用した{dir}で示す

|コマンド|意味|
|---|---|
|$ git init --bare --share|違うPCからも共有リポジトリのディレクトリ作成|
|$ git clone {dir} {作成するディレクトリ名}|$ git init --bare --shareで作成したディレクトリを指定してその作業ディレクトリを作成|
|$ git pull origin master|一度クローンで作成したディレクトリからリポジトリを更新する際に使用する|
|$ git push origin master|作業ディレクトリから共有リポジトリのディレクトリにリポジトリをpushする|
pushはcommitまでされたディレクトリ構成を取り扱うので
作業ディレクトリは、pushする前に最新状態にアップデート(`$ git commit -am "new commit"`)をする必要がある。
AWSソリューションアーキテクトアソシエイト（2018年2月リリース）受験ログ

AWS 認定ソリューションアーキテクト – アソシエイト（2018年2月リリース）を受けたメモ。

試験についてはこちら。

https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

## 経緯

6月上旬、受けてみようと思う。
7月上旬、試験を予約。
7月中旬、受験。

2018年8月12日までは旧版のテストも受けられる。違いはよくわからないが、せっかくなので新版を受けた。

||旧版|新版|
|---|---|---|
|時間|80分|130分|
|問題数|55問|65問|

問題数が18%増に対して時間は62%増なので、時間に余裕はありそうだけど、その分問題の難易度が上がっているのだろうか。

## 勉強開始前の自分のスキル

- IT業界歴10年以上、専門はJavaEEアプリケーション・サーバー。
- アプリケーションの開発経験はさほどない。
- AWSのアカウント自体は2010年に作成していたがほぼ放置。
- 業務でのAWS使用経験はなし。
- 数年前に[ドットインストール](https://dotinstall.com/)のAWSのチュートリアルをやってみた後、個人的に自由に使えるサーバーが欲しいときにEC2インスタンスをたまに使っていたくらい。
  - ちゃんとIAMユーザーでのMFAを設定していなかったら、アカウントが乗っ取られてEC2インスタンスが大量に起動され（マイニング？）、高額請求がきた経験あり。サポートに連絡して返金してもらえた。

## 情報収集

ネットにたくさん受験記がある。が、新版の受験記はまだ少なめかも。

[AWS ソリューションアーキテクトアソシエイト 受けてきました＆勉強法(2016/10版)](https://qiita.com/saitotak/items/188293d0655142e88483)

などを参照した。

## 勉強方法

### 書籍

とりあえず以下の本を読んだ。章末問題で実際の試験のイメージがわいた。

[合格対策 AWS認定ソリューションアーキテクト - アソシエイト](https://amzn.to/2MhXwKB)

次に以下の本を読みながら手を動かした。自分で作ってみると理解が深まるのでこれがよいと思う。

[Amazon Web Services パターン別構築・運用ガイド 改訂第2版](https://amzn.to/2KYfF3k)

改訂第2版ではあるものの、中盤のElastic BeanstalkのあたりからAWS側がアップデートされていて本の手順通りでは上手くいかず、試験日も迫ってきたので、後半は斜め読み。

### 問題集

ググるとでてくる以下の問題集をフリープランだけ実施。新版に対応しているのかわからなかったので有料プランまでは購入せず。

https://aws.koiwaclub.com/

### AWS Black Belt

いろいろな人の受験記で定番の教材としておすすめされているパワーポイントの資料。それぞれの分量が多いのでけっこう大変。模擬試験をやってみてよくわからなかったところだけ参照。

https://aws.amazon.com/jp/aws-jp-introduction/

### その他

仕事や勉強で製品を動かして検証する際に、なるべくAWSで動かしてAWSに慣れるようにした。

## 模擬試験

本試験2日前に模擬試験を受験。2160円。模擬試験は30分で25問。

||模擬試験|本試験|
|---|---|---|
|時間|30分|130分|
|問題数|25問|65問|

本番の方が時間に余裕はあるはず。

後で見返したい問題にフラグを付けておけたり、回答システムが本試験と同じなので、模擬試験はやっておいた方がよい。

終了後に問題の解説があるのかと思ったら、解説どころか問題すらみられなくなったので、スクリーショットをとっておけばよかったと後悔。

Amazon EFSを知らず模擬試験ではじめて目にした（上述の本で出てこない？）ので慌ててBlack Beltで勉強。

思ったよりもかなり難しいと思ったが、スコアは88%だったので、本試験もいけるかなと少し安心。

1. Design Resilient Architectures: 100%
1. Define Performant Architectures: 85%
1. Specify Secure Applications and Architectures: 66%
1. Design Cost-Optimized Architectures: 100%
1. Define Operationally-Excellent Architectures: 100%

## 本試験

16200円。7月中旬に受験。場所は銀座歌舞伎座の試験会場。受験者は20代30代の男性が多い。女性はいなかった。

模擬試験をやってみたときに、紙に構成図を書いて問題の環境を理解したいなと思っていたら、会場では紙とボールペンが配布されたのでよかった。

合格ラインは68%と最初のほうの画面に出てきた。

手応え的には6割がわかって、2割自信なく、後の2割は全くわからない感じ。暗号化キーの管理が勉強しておらず全然わからなかった。

EC2、VPC、S3、ELB、RDSなどインフラの基本的なところはちゃんと理解している必要があり、Elastic Beanstalkなど、新しめっぽかったりアプリよりっぽいやつはどんなサービスであるのかだけ理解していればよさそう。

30分くらい時間を残して試験を終了。結果はその場ですぐにわかるのかと思ったら、5営業日以内にAWS認定アカウントに結果が登録されて同時にメール通知とのこと。模擬試験のときに翌朝4時にメールが来ていたので、本試験も同じと予想。

予想通りに翌朝の4時にメールがきた。スコアは100-1000の範囲で、720以上で合格とのこと。916で合格。なお、全体のスコアは表示されるが、トピック別のスコアは表示されず、トピック別に目標レベルに達しているかだけ表示される。
【Git】Gitの運用方法

# 前置き
この記事はGitを今から運用で使って見たい、運用方法がわからないと思っている人向けの記事となります。
自分自身も完全に使いこなせているわけではないので他により良い方法があれば
コメント頂けると助かります。
※あくまで個人的に行なっている運用なので抜けがあるかもしれません！！

前提として基本的な言葉は理解しているとして話を進めます。

- マージ
- ブランチ
- プルリクエスト
- マスター　など…

# 大まかなフロー
役割として`PM(プロジェクトマネージャー)`と`PG(プログラマ)`の二つの作業に対してまとめて行きます
※場合によっては`PM`は`PL(プロジェクトリーダー)`になるかも

## issue作成(PM)
`PM`は`Git`の初期化が完了したら`issue`を作成します。(ここでの`issue`はタスクと同意義です)
作成するに当たって以下を取り決めます

- タイトル
    - 作業を行うファイルを記載。
    - 作業者がなるべく同じファイルを作業しないように調整が必要。
- 詳細
    - タイトルに記載したファイルに対してどのような作業を依頼したいかを記載
    - ある程度プロジェクトが進んできたら`現在の動作`と`期待される動作`の二つを記載
- ラベル
    - `issue`の内容がどういった内容かをラベリングします。
        - バグ
        - 実装
        - 修正
        - リファクタ　など
- マイルストーン
    - 作成した`issue`をいつまでに完了して欲しいかを記載します

- 担当者
    - 誰に作業して欲しいかを記載します

## ブランチ作成(PG)
`PG`は`PM`が作成した`issue`を確認してその番号の`ブランチ`を作成します。
`ブランチ`の名前は作業する担当の名前と`issue`番号で作成して下さい。(suzuki/#25 など)
作成した`ブランチ`で`issue`の作業を行います。
**この時に`ブランチ`と`issue`は必ず１：１の関係で作業を行って下さい。**

## プルリクエスト作成(PG)
`issue`に対しての作業が完了したら`PG`は`プルリクエスト`を作成します。
ここで必ず行って欲しいのが
***マスターを自分のブランチにマージする***
ということです。これがないと作業が出戻ったりする可能性があります。

作成するに当たって以下を記載します。

- タイトル
    - どの`issue`に対してのプルリクエストなのか、どのような作業を行ったかを記載し、`issue`がクローズされるように先頭に`close #25`のように記載します。

- 詳細
    - どのような作業を行ったかをより詳細に記載し、タイトルと同様に`close #25`のように記載します。

## マスターへマージ(PM)
`PM`は`PG`から`プルリクエスト`をもらったら中身をレビューします
問題点などがあった場合にコードにコメントを記載し
その`プルリクエスト`をクローズします。

また複数の担当者から同時に`プルリクエスト`をもらった場合は
同じファイルを作業していないかを必ずチェックしてください。
チェックがめんどくさい場合は一つの`プルリクエスト`を`マージ`後
他の`プルリクエスト`は全てクローズして他の作業者に
`マスター`を更新したので自分の`ブランチ`に`マスター`を`マージ`してもらうように
促します。

# まとめ
上記が大まかなフローとなります。
このサイクルを回せばどの担当者がどのブランチで何の作業をしているかが明白に可視化できて
タスク管理しやすいかと思います。
[Vim] Vim に Language Server Protocol クライアント機能を導入して Rubyの補完機能を復活させた

[YouCompleteMe](https://github.com/Valloric/YouCompleteMe) をしばらく前から使っていました。最近、MacOSXな環境で、Rubyの補完がうまく動かなくて、 `.` を入力した瞬間、 vim が死亡するようになってしまいました。原因は良くわかりません。とりあえず、死ぬのは困るので、 `--disable-rubyinterp` で、Vimをビルドしてました。

YouCompleteMe で、Ruby の補完ができなくなってしまったので、何か他に良い方法ないかとあちこちのサイトを眺めていて、 [deoplete.nvim](https://github.com/Shougo/deoplete.nvim) と [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) と [solargraph](https://github.com/castwide/solargraph) を組み合わせたら、行けるんじゃないかと思い、試してみました。

## deoplete.nvim

deoplete.nvim をインストールします。

```vimscript:.vimrc
if has('nvim')
  Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
  Plug 'Shougo/deoplete.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
endif
let g:deoplete#enable_at_startup = 1
```

## LanguageClient-neovim

[LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) は、Neovimやvim を language server protocol(LSP) に対応させるためのスクリプトです。 

```vimscript:.vimrc
Plug 'autozimu/LanguageClient-neovim', {
    \ 'branch': 'next',
    \ 'do': 'bash install.sh',
    \ }

" (Optional) Multi-entry selection UI.
Plug 'junegunn/fzf'
```

## 設定の追加

起動時に deoplete を有効にして、Rubyスクリプトを編集するときは、 solargraph が LSPサーバーとして動作するように設定します。


```vimscript:.vimrc
let g:deoplete#enable_at_startup = 1
let g:LanguageClient_serverCommands = {
    \ 'ruby': ['solargraph', 'stdio'],
\}
call deoplete#custom#var('omni', 'input_patterns', {
    \ 'ruby': ['[^. *\t]\.\w*', '[a-zA-Z_]\w*::'],
\})
```

## Python3 interface のインストール

Python3 interface をインストールします。

```bash
$ pip3 install neovim
```

## solargraph のインストール

```bash
$ gem install solargraph
$ yard gems
$ yard config --gem-install-yri 
```

## 動作確認

.rbファイルを開いて、 `cl` と入力すると以下のような候補が表示されます。

![2018-07-14-140807_536x203_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/209941/a8909845-3392-c0ee-7f46-e67ac2b58b6c.png)

## おわりに

もっと、色々いじると便利になるのかも知れませんが、今のところ、こんな感じで様子を見たいと思います。

他の言語でも [LSPなサーバー](https://microsoft.github.io/language-server-protocol/implementors/servers/)をインストールすれば、同じように使えると思いますが、そこは様子を見ながら切り替えたいと思います。
.j2 拡張子って何？

Ansible で Jinja2テンプレートファイルであることを示す拡張子。

単に「Ansibleのベストプラクティス」にこの拡張子でのファイル例が載っているだけ。

[Best Practices — Ansible Documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#directory-layout)

# Jinja2とは

python のためのテンプレート言語である。

>Jinja2 is a modern and designer-friendly templating language for Python 

[Welcome to Jinja2 — Jinja2 Documentation (2.10)](http://jinja.pocoo.org/docs/2.10/)

# 参考

特にJinja2本体側でこの拡張子が定義されているわけではなさそう。

- [python - Is there an idiomatic file extension for Jinja templates? - Stack Overflow](https://stackoverflow.com/questions/29590931/is-there-an-idiomatic-file-extension-for-jinja-templates)
- [pallets/jinja: The Jinja2 template engine](https://github.com/pallets/jinja)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【備忘録】cssでSPの横・縦によってスタイルを変更する

知ってたはずなのに忘れたので。

```css
@media screen and (orientation: landscape) {
   /* 横向きの場合のスタイル */
}

@media screen and (orientation: portrait) {
   /* 縦向きの場合のスタイル */
}
```
機械学習用の画像を集めるのにicrawlerを使いたいけどインストールできない方へ

# 概要

[機械学習用の画像を集めるのにicrawlerが便利だった](https://qiita.com/tkt989/items/84c6581dfa1d9a42dc2d)

を見て使ってみたかったけどインストール時にエラーが出る人への記事。

# 内容

```
mkl-fft 1.0.0 requires cython, which is not installed.
mkl-random 1.0.1 requires cython, which is not installed.
```

というエラーが出てきてインストールがうまくいかない。

# 結論

cythonのインストールが足りてないとのメッセージが出ているので以下のCommandで必要なものをインストールしましょう

```
pip install cython
```

良い機械学習ライフを

# 参考
- [機械学習用の画像を集めるのにicrawlerが便利だった](https://qiita.com/tkt989/items/84c6581dfa1d9a42dc2d)
wemosで生http

#概要
wemosで生httpリクエストを表示してみた。

#結果

```
GET /test HTTP/1.1
Host: 192.168.11.14
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: ja,en-US;q=0.9,en;q=0.8
```

#サンプルコード

```
#include <ESP8266WiFi.h>

const char * ssid = "001D736531AA_G";
const char * password = "";
WiFiServer server(80);
void setup() 
{
	Serial.begin(115200);
	delay(10);
	pinMode(2, OUTPUT);
	digitalWrite(2, 0);
	Serial.println();
	Serial.println();
	Serial.print("Connecting to ");
	Serial.println(ssid);
	WiFi.mode(WIFI_STA);
	WiFi.begin(ssid, password);
	while (WiFi.status() != WL_CONNECTED)
	{
		delay(500);
		Serial.print(".");
	}
	Serial.println("");
	Serial.println("WiFi connected");
	server.begin();
	Serial.println("Server started");
	Serial.println(WiFi.localIP());
}
void loop()
{
	WiFiClient client = server.available();
	if (!client)
	{
		return;
	}
	Serial.println("new client");
	while (!client.available())
	{
		delay(1);
	}
	String req = client.readStringUntil('\0');
	client.flush();
	String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>";
	s += "<body><textarea rows=10 cols=80>";
	s += req;
	s += "</textarea></body></html>\r\n\r\n";
	client.print(s);
	delay(1);
	Serial.println("Client disonnected");
}




```

以上。
ShellScriptでファイルの絶対パスを得るならreadlink

`readlink`がある前提であり、正確には「`ShellScript`なら」とは言えないか。


[bash で ファイルの絶対パスを得る - Qiita コメント:#comment-10d1b710bcf7df114cb7]

昔に自分でリンク張っておきながら忘れるんですよね。

[readlink コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/readlink.html)
(なので正確には `readlink -f`)


そして忘れたまま手動で判定しようと書きかけると、こう詰まる。


```sh:fish&nbsp;function
function test
    # 引数は処理対象ファイルひとつのみ(好きなだけ渡せたほうがいいけど)
    if test (count $argv) -ne 1
        echo "引数を一つ設定してください" $argv >&2
        return 1
    end

    set file $argv[1]

    # 引数で渡したファイルがなければエラー
    if test ! -f $file
        echo "ファイルを指定してください" $file >&2
        return 1
    end

    # 最初の一文字を見て、ファイル指定を絶対パスか相対(ホームからの)パスかを判定する    
    set first_str (string sub -l 1 $file)
    if      test "." = $first_str
        echo "相対パス"
        # pwdくっつける
    else if test "~" = $first_str
        echo "ホームからの相対パス"
    else if test "/" = $first_str
        echo "絶対パス"
    else
        echo "カレントのファイル"
        # pwdくっつける
    end
end
```

やりたかったことは、引数で渡されたファイルの親族？ディレクトリ。
兄弟や親のディレクトリへの操作をしたいと考えた。
`mv`や`cp`のように移動先を指定せず、一定のルールで処理先を決定させるようなもの。

例えば
`/tmp/original/hoge`
を
`/tmp/original_moved/hoge`
に移動させるような。

でも先頭一文字だけでは
`.config`などのドットファイルに対応できない。
`~hoge`などのファイルも作れるので、

二文字・三文字見て区切り文字まで見なければならないなと考えた。
`./`, `../`, `~/`なら相対・ホームパス。
どうにも筋が悪そう。
振り返れば最初に手動で判定しようとしたところから筋が悪いので、絶対パスの取得ぐらいはコマンドで取ろうという考えをすぐに持ちたいところ。
という失敗例でした。

絶対パスがとれたら

[`dirname`](http://www.atmarkit.co.jp/ait/articles/1801/26/news013.html)
から相対パスで遡って操作できそうと考えています。


[bash で ファイルの絶対パスを得る - Qiita コメント:#comment-10d1b710bcf7df114cb7]:http://qiita.com/katoy/items/c0d9ff8aff59efa8fcbb#comment-10d1b710bcf7df114cb7
ili9341の研究

#概要
ili9341を調べてみた。

#写真

![](https://qiita-image-store.s3.amazonaws.com/0/18104/09bb3f4b-52e5-c180-e18a-f0ae1b761220.jpeg)

#ピン配置


|uno	|LCD|
|:--|:--|
|SCL	||
|SDA　	||
|GND	|GND|
|D13　	|SD_SCK|
|D12　	|SD_DO|
|D11　	|SD_DI|
|D10　	|SD_SS|
|D9　　	|LCD_D1|
|D8　　	|LCD_D0|
|D7　　	|LCD_D7|
|D6　　	|LCD_D6|
|D5　　	|LCD_D5|
|D4　　	|LCD_D4|
|D3　　	|LCD_D3|
|D2　　	|LCD_D2|
|D1　　	||
|D0　　	||
|A0　	|LCD_RD|
|A1　	|LCD_WR|
|A2　	|LCD_RS|
|A3　	|LCD_CS|
|A4　	|LCD_RST|
|A5　	||


以上。
Docker チートコマンド集

Docker チートコマンド集

自分がよく使うコマンドをメモします。
適宜気づいたら更新予定。

# コンテナ内でコマンドの確認をしたい

コンテナでデバッグをしたい時などに利用する。
`-i`オプション(Keep STDIN open even if not attached)と`-t`オプション(Allocate a pseudo-TTY)を指定して`docker run`を実行する

```bash
$docker run -t -i nginx /bin/bash
root@1209bcb822d5:/# ll
bash: ll: command not found
root@1209bcb822d5:/# 
root@1209bcb822d5:/# exit
```

exit するとコンテナも終了する。(/bin/bashが終了しているので）
必要に応じて`-d`プションを付与してバックグラウンドで起動させて`docker exec`で確認することもする
この場合、exit しても終了しない。(docker run した時に起動した /bin/bash が終了しているということではないので）

```bash
$docker run -t -i -d nginx /bin/bash
c764a3b1d7427e3294452689024afc128ba59fb5e4643681907c0788fe6e4ee2

$docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c764a3b1d742        nginx               "/bin/bash"         53 seconds ago      Up 52 seconds       80/tcp              elegant_varahamihira

$docker exec -it c764a3b1d742 /bin/bash
root@c764a3b1d742:/# exit
exit

$docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
c764a3b1d742        nginx               "/bin/bash"         About a minute ago   Up About a minute   80/tcp              elegant_varahamihira
```

# 停止中のコンテナの一括削除


`docker ps`してうんぬんカンヌンしてましたが、`docker container prune`でも出来ることを最近知りました

[Prune unused Docker objects](https://docs.docker.com/config/pruning/)

>By default, all stopped containers are removed

```bash
# 停止中のコンテナを docker rm する
$docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
16d242caca39490d8ef88c1f571668aaefde9cd57060dc9147ff29cb01551af1

Total reclaimed space: 0B

# 確認なしで実行したいときは -f オプションを付与する
$docker container prune -f
Deleted Containers:
d52e1923319d1cba2b6bc917e7fbdba63a3e1c52b4280bc059e407f4f7830e2a
ded459c4d1e5cf7ca770bb8171d8dec28bf1a9a094f3d89d5f2a6253bbf24371

Total reclaimed space: 0B

```

`docker prune`はイメージやボリュームなど諸々使えそうで便利な感じがします。

参考にさせて頂いた記事

[Docker一括削除コマンドまとめ](https://qiita.com/boiyaa/items/9972601ffc240553e1f3)
bookdownで何か書くときのメモ

よく忘れるので。適宜更新（したい）。

## 用語

- YAMLフロントマター
    - Rmdファイルの先頭にYAMLで書く設定。`---`で囲まれている。一部の設定は別ファイルに分けることができる。
- `_bookdown.yml`
    - YAMLフロントマターに書くような設定をこの名前のファイルに書いておいても良い。`---`は不要。
- `_output.yml`
    - YAMLフロントマターの`output:`フィールドに書く内容をここに書いておいてもよい。`---`は不要で、`output:`も不要(その下の階層のフィールドから書く。

## 基本

### bookdownにしたい

YAMLフロントマターに以下の記述をした`index.Rmd`を用意する。

```yml
---
site: bookdown::bookdown_site
output:
  bookdown::gitbook: default
---
```

RStudio使用時は右上にBuildペインが出るので（出ない場合はRStudioを再起動してみる）Build Bookをクリックするか、Cmd+Shift+Bでビルドされる。

## 設定関係

### 対象とするRmdファイルの種類と順序を指定したい

デフォルトではワーキングディレクトリ内のファイルがファイル名順に使用される。サブディレクトリまで含める場合は`_bookdwon.yml`に`subdir: yes`を記述。また、ファイル名がアンダースコア`_`から開始するファイルは含まれない。

任意の順序、ファイルとしたい場合は`_bookdown.yml`に記述。

```yml:_bookdown.yml
rmd_files: ["index.Rmd", "01_intro.Rmd"]
```

次の形式でも良い。

```yml:_bookdown.yml
rmd_files:
  - index.Rmd
  - 01_intro.Rmd
```

### ページ(htmlファイル)の区切り方を変更したい

例えばセクションで区切りたければYAMLフロントマターに以下のように記述する。

```yml
output:
  bookdown::gitbook:
    split_by: section
```

`split_by`には以下の指定ができる。

- `rmd`: Rmdファイル単位で区切る。
- `none`: 区切らない(1つのhtmlファイルが生成される)
- `chapter`: 1番目のレベルのヘッダ(`#`)単位で区切られる。
- `section`: 2番目のレベルのヘッダ(`##`)単位で区切られる。
- `chapter+number`及び`section+number`: `chapter`、`section`とほぼ同じだが、生成されるファイル名に自動的に番号が付与される。

### 日本語PDFで出力したい

- [TinyTeXを使って10分で(R向けの)LaTeX環境を整える - Qiita](https://qiita.com/nozma/items/1c6b000b674225fd40d7)

## エラーへの対処

### Automatically generated filenames contain duplicated ones...

生成されたhtmlファイルのファイル名が重複している。

デフォルトでは、ファイルは第一レベルの見出し（`#`が1つのもの）から自動的に生成されるが、ここに日本語などのマルチバイト文字が含まれると無視される。そのため、見出しに日本語を使っているともれなくファイル名が重複してしまう。

これを防ぐにはいくつか方法がある。

まず、前述の`split_by`の変更。ファイル名の重複を防ぐ指定として例えば以下のような物がある。

- `split_by: rmd` htmlファイルは.Rmdファイル単位で生成される。ファイル名は.Rmdの名前を引き継ぐ。
- `split_by: chapter+number` 自動生成されたファイル名に連番が付与されるので、見出し名が重複してもファイル名の重複を避けられる。`section+number`も同様。

指定は例えばYAMLフロントマターで以下のように行う。

```yaml
output:
  bookdown::gitbook:
    split_by: rmd
```

他の方法として、見出しの識別子を手動で設定するというものもある。見出しに識別子が指定されていると、ファイル名の生成時には識別子が優先して使用される。例えば

```md
# いんとろ {#introduction}
```

と指定されていれば、`introduction.html`が生成される。

### The file _main.Rmd exists. ...

`_main.Rmd`を消す。

このファイルは、デフォルトのビルド方法（Rmdをマージしてからknitする）のときに何らかのエラーでビルドが完了しなかった場合に残ってしまう。このとき、エラーメッセージは`_main.Rmd`に対して出力されるので、エラーが何なのかを確認するためには`_main.Rmd`の中身を確認する必要がある。

### `_bookdown.yml` で不完全な最終行が見つかりました。

最終行は改行のみを含む行でなければならない。

## Rmd関係一般

### 文字に色を付けたい

`<font>`タグで。

```md
<font color="red">赤色</font>
```

### bibtexを使いたい

例えば`hoge.bib`などの名前でbibファイルを用意する。その後、YAMLフロントマターで

```yml
bibliography: [hoge.bib]
biblio-style: "apalike"
link-citations: yes
```

とする。

文献のキーを`key`とすると、`@key`でhoge(2018)形式、`[@hoge]`で(hoge, 2018)形式で表示される。

## TeX関係一般

（もはやRmd関係ない…）

### =の位置を揃えたい

alignを使う。

```
\begin{align}
y &= (x + 1)^2 \\
  &= x^2 + 2x + 1
\end{align}
```
PHPとHTMLを用いたフォームづくり①

##最終目標
HTMLとPHPをもとにしてデータベースと連携させたフォームを作る。
具体的には以下の4つのページから構成されている。

①情報記入画面
②情報確認画面
③情報入力完了画面
④データ表示画面

①に情報を記入→②で情報があっているのか最終確認
→③で情報の記入が完了しましたの表示→④で今まで記入されてきた情報の一覧表示

##今週の目標
ページの①と②を作成して、データの送信と取得させる。
具体的には以下の通りである。

1、情報記入画面を作成
・学籍番号フォーム：数字のみ
・名前フォーム：必須
・年齢フォーム：18～100までの選択肢を作り、そこから選ばせる。
・送信ボタン(②のページに上記の情報を送信)

2、情報確認画面の作成
・①で記入された情報の取得機能
・①で記入された情報の表示機能
・確認ボタン(③のページに情報を送信)
・修正ボタン(①のページに戻る)

##使用した知識
1、HTMLのフォーム作成知識
・<form></form>:このタグの内側でフォームを作成する
・<input>:具体的なフォーム欄を作成する時に用いる。綴じたぐはなし。
　・type:Inputタグの属性を決める。
　・name:Inputタグの名前を決める
・<select></select>:セレクトボックスを作るタグ 
・<option></option>:selectタグの中身を決めるタグ。
　・value：optionタグから送信先に送信する値を決定

2、PHPのループ処理知識

・`for($i=①;$i<②;$i+-③)`:繰り返しのループ処理。

  ・①:ここには変数の初期値を入力。1からループが始まって欲しいなら、(1)と入力。
　・②:ここには変数の上限値を入力。ループが100まで続いてほしいなら、100と入力。
　・③:ここには処理の後の変化値を入力。1ずつの変化は`($i++)`。

3、PHPの変数とループ処理とHTMLを組み合わせる知識
・echo:値を出力するコマンド
・セレクトボックスの中身の値にループ処理した変数を入れたい場合、以下の通りとな 
    ```
    for($i=18; $i<=100; $i++){
          echo "<option value='{$i}'>{$i}</option>" ;
    }
```
4、PHPのデータ送信と取得知識
・送信:formタグの中で送信先と送信方法を決める
　・action:データの送信先を記入。
　・method:データの送信方法を決める
・取得:データを取得したいページで以下のように記入

　　`echo $_POST['①']`

　・①:ここにはデータの取得先の値を記入
JS の「for...of」や C# の「foreach...in」でインデックスを使う方法を考える

`for(;;)`文はインデックスの指定や配列の長さが必要だったり、
終了条件を間違えたりするのでなるべく使いたくないです。

`for(;;)`を使わずにインデックスにアクセスするとなると、JS の場合、`Array.map`や`Array.forEach`など配列の反復処理、C# の場合、LINQ が思いつきます。
ただ、（個人的にですが）匿名メソッドのブロック本体に長々書くのもなんかしっくりきません。

```js
// arr <- 配列
arr.forEach((v, i) => {
  /*
   * 長くていろいろやる 
   * 
   * 
   */
})
```

[（C#の場合`List<T>.ForEach`が非推奨の理由もあるようです。）](https://qiita.com/chocolamint/items/d29d699ce27bcf685154)


そこで JS の`for...of`や C# の`foreach...in`でインデックスにアクセスする方法がないかなと考えてみました。。

## JavaScript の `for...of` でインデックスを使う

```js
const chars = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']

for (const { c, i } of chars.map((c, i) => ({c, i}))) {
  /*
   * 長くていろいろやる 
   * 
   * 
   */
  console.log(`文字:${c} index:${i}`)
}
```

```:結果
 文字:J index:0
 文字:a index:1
 文字:v index:2
 文字:a index:3
 文字:S index:4
 文字:c index:5
 文字:r index:6
 文字:i index:7
 文字:p index:8
 文字:t index:9
```

`map`でインデックスと要素を持ったオブジェクトの配列を作り、それを分割代入で受け取ります。

ラムダ式の戻り値のオブジェクト`{}`を囲む丸カッコ`()`は必須です。
メソッド本体が1ステートメントのラムダ式でオブジェクトを返す場合、
`()`で`{}`を囲まないと`{}`がラムダ式の本体のブロックとみなされます。

欠点としては`map`が即時実行のため、`map`と`for...of`の間で中間配列ができてしまいます。
極端に長い配列を処理する場合などメモリを圧迫する場合はやめたほうがよさそうです。

## C# の `foreach...in` でインデックスを使う方法

```c#
char[] chars = { 'c', 's', 'h', 'a', 'r', 'p' };
foreach (var (c, i) in chars.Select((c, i) => (c, i))) {
    /*
     *
     * なんか長い処理
     *
     */
    Console.WriteLine($"文字{c} index:{i}");
}
```

```:結果
 文字c index:0
 文字s index:1
 文字h index:2
 文字a index:3
 文字r index:4
 文字p index:5
```

LINQ の`Select`で要素とインデックスのタプルのシーケンスを作り、分割代入で受け取ってます。
LINQ は遅延実行なので、`Select`と`foreach`で中間配列が作られることはありません。

`Select`で匿名型`new { c, i }`のシーケンスを作ることもできますが、 JS と違い分割代入できません。`foreach`ブロック中で`x.c`のようにアクセスしなければならず、普通の`for(;;)`のほうがよさそうです。

```c#:x.のプリフィックスがイケてない...
char[] chars = { 'c', 's', 'h', 'a', 'r', 'p' };
foreach (var x in chars.Select((c, i) => new { c, i })) {
    /*
     *
     * なんか長い処理
     *
     */
    Console.WriteLine($"文字{x.c} index:{x.i}");
}
```
ポップアップメニューをスクリーンショットする

#####実行した環境
Ubuntu Stdio 18.04LTS

#####参考
PrintScreenキーでは撮れないスクリーンショットを撮る(Ubuntu12.04でコマンドによるタイマー撮影) 
http://blog.michinari-nukazawa.com/2013/12/different-method-screenshot-printscreen.html

やり方は、上記のやり方と同じですが、Ubuntuではスクリーンショット　アプリの種類が沢山あるようなので、端末から実行するコマンド名を調べなくてはいけません。

私はあまり詳しくないので、何のスクリーンショット　アプリがインストールされているのか調べました。

```shell-session
$ apt search screenshot

xfce4-screenshooter/bionic,now 1.8.2-2 amd64 [インストール済み]
  screenshots utility for Xfce
```

次に、撮影する領域　オプションで、アクティブウインドウにすると、端末だけがスクショされるので、画面全体 -f にします。

スクショするアプリと端末が重ならないように並べて、

```shell-session
$ sleep 5 ; xfce4-screenshooter -f
```

を実行し、5秒以内にアプリのポップアップメニューを開いて5秒経つのを待ちます。
5秒が短いなら、数値を大きくします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/5ac49189-d045-95fd-90a3-04e069814ec2.png)
よく使用するURLのメモ（HTML,CSSがメイン）

# .gitignore系の設定一覧

http://co.bsnws.net/article/300

# HTMLの効果系

## 特殊文字の一覧

http://www.shurey.com/js/labo/character.html

## 普通のHTMLをJade(pug)に変換するwebサービス

http://www.html2jade.org/

（↑のリンクが切れていたら）
http://html2jade.herokuapp.com/

## HTMLを記述するだけでidやclass名などが付加された状態でCSS(SCSSとかも)を生成してくれるサービス

https://css.miugle.info/

# cssの効果系

## 普通のcssをsassかscssに変換してくれるサービス

http://css2sass.herokuapp.com/

## イージングのアニメーションの動きを細かく設定できるサービス

https://matthewlein.com/tools/ceaser

## グラデーションの設定

http://www.colorzilla.com/gradient-editor/

## 影

### box-shadow（一応border-radiusも）

http://www.bad-company.jp/box-shadow/

### text-shadow

http://www.bad-company.jp/text-shadow/

## shadowやtransgormなどのジェネレーター

一覧で簡単に例を見ることができて、詳細で細かな設定も行える

http://ds-overdesign.com/

## cssで吹き出しを作りたいときに

吹き出し自体の位置は上・下・右・左の中央にあるので、吹き出し自体の縦・横移動は自分で触る必要あり。

http://www.cssarrowplease.com/

## リボンをcssで作成するときに

設定する数値がたくさんあって見にくい？

http://www.css3d.net/ribbon-generator/

# 画像の圧縮

webサービス：https://tinypng.com/

gulpで：https://qiita.com/MikaShirahama/items/ab91624709510c496e53

# font-awesome

## アイコン一覧
https://fontawesome.com/icons?d=gallery

## 読み込むとき(`<link>`のurl)

https://fontawesome.com/how-to-use/on-the-web/setup/getting-started?using=web-fonts-with-css
Bracketsの行間を調整する。

ヘルプ > 拡張機能のフォルダーを開く
から、インストールしたテーマのフォルダーを開き、cssあるいはlessファイルの末尾に

```css
.CodeMirror {
    line-height: 1.0;
}
```
と追加する。
（1.0の部分は好みで変える）
Material ProjectとCitrinationのAPIを使ったバンドギャップの比較

前回、投稿した記事([機械学習を使った半導体物性予測](https://qiita.com/funabashi800/items/6c0a8a09f66a7fde4230))ではMaterial ProjectのデータはPBEという汎関数が使用されているため、バンドギャップの計算精度が良くないため、予測ができないというご指摘があったため、今回はCitrinationという論文のバンドギャップの実験データをテキストマイニングによって収集したデータベースを使用します。

##目的
[Material Project](https://materialsproject.org/)による第一原理計算のバンドギャップデータと[Citrination](https://citrination.com/search/simple?searchMatchOption=fuzzyMatch)による実験値を比較する。

##動作環境

- Python 3.6.5:: Anaconda
- pandas 0.23.1
- pymatgen 2018.6.11
- matminer 0.3.7

```terminal:
$ pip install matminer
$ pip install pymatgen
```

##Citrination (実験値)


```python:
import numpy as np
import pandas as pd

# pandasの設定
pd.set_option('display.width', 1000)
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

import warnings
warnings.filterwarnings('ignore')

from matminer.data_retrieval.retrieve_Citrine import CitrineDataRetrieval

api_key = xxxxxxxxxxxxx # CitrinationのAPI key
c = CitrineDataRetrieval(api_key) 

df = c.get_dataframe(criteria={'data_type': 'EXPERIMENTAL', 'max_results': 100},
                     properties=['Band gap', 'Temperature'],
                    common_fields=['chemicalFormula'])
df.rename(columns={'Band gap': 'Experimental band gap'}, inplace=True) 
```

##Material Project (計算値)

```python:
from pymatgen import MPRester, Composition
api_key = yyyyyyyyyyy # Material ProjectのAPI key
mpr = MPRester(api_key) 

def get_MP_bandgap(formula):
    """Given a composition, get the band gap energy of the ground-state structure
    at that composition
    
    Args:
        composition (string) - Chemical formula
    Returns:
        (float) Band gap energy of the ground state structure"""
    reduced_formula = Composition(formula).get_integer_formula_and_factor()[0]
    struct_lst = mpr.get_data(reduced_formula)
    
    if struct_lst:
        return sorted(struct_lst, key=lambda e: e['energy_per_atom'])[0]['band_gap']
    
df['Computed band gap'] = df['chemicalFormula'].apply(get_MP_bandgap)
```

##結果

```python:
from matminer.figrecipes.plot import PlotlyFig

pf = PlotlyFig(df, x_title='Experimental band gap (eV)', 
               y_title='Computed band gap (ev)',mode='notebook', 
               fontsize=20, ticksize=15)
pf.xy([('Experimental band gap', 'Computed band gap'), ([0, 10], [0, 10])], 
      modes=['markers', 'lines'], lines=[{}, {'color': 'black', 'dash': 'dash'}],
      labels='chemicalFormula', showlegends=False)
```

![newplot.png](https://qiita-image-store.s3.amazonaws.com/0/266140/0087aba2-a91c-209f-7ac9-64c6a1c12571.png)

##参考

- [Matminer: example](https://hackingmaterials.github.io/matminer/#examples)
- [Matminer: An open source toolkit for materials data mining](http://perssongroup.lbl.gov/papers/ward-2018-matminer.pdf)
【自分用メモ】chromeの自動操作①（selenium IDE編）

ブラウザの自動操作やってみたかったので、その時のメモ。
こんな感じのことができるよーになる。
![7月-14-2018 19-13-46.gif](https://qiita-image-store.s3.amazonaws.com/0/98214/3b27b642-1683-81f9-1b1a-e9f6dae383b5.gif)

# 環境
・Mac OS High Sierra（10.13.2）
・Google Chrome 67.0.3396.99
・Selenium IDE 3.1.1

# selenium IDE とは
[公式ページ](https://www.seleniumhq.org/projects/ide/)参照。
そのうちまとめる。

# とりあえず動かす
最初のサンプルを動かすまで。
## selenium IDEのインストール
chromeのウェブストアからインストールするだけ。
https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd
<img width="245" alt="selenium_ide_chrome.png" src="https://qiita-image-store.s3.amazonaws.com/0/98214/59fbb830-1fae-ac4e-9906-131394f9d9cd.png">
そしたらブラウザの右上にseleniumIDEのアイコンが出てくるよーになる。
## 自動操作のシナリオを作る
サンプルのもので実現したかったのは下記のシナリオ。
1. googleの検索画面（ https://www.google.co.jp/ ）を開く
2. 検索キーワードに「selenium test」と入力する
3. 検索を実行する
## selenium IDE上でシナリオを作る
IDE上でシナリオを作るのに最低限必要な要素は３つ。
・ Command ： 「どんな」操作をしたいのか
・ Target ： 「どれ」に対して操作をしたいのか
・ Value ： 「なに」を入力値とするのか
今回のサンプルであればこんな感じ。

|No|Command|Target|Value|
|---|:---|:---|:---|
|1|open|https://www.google.co.jp/||
|2|sends key|q|selenium test|
|3|click|btnK||

## シナリオを動かす
先ほどの手順で作成したシナリオを動かしてみる。
①実行速度を指定（デフォルトは最高速度）
②実行ボタンを押下
<img width="315" alt="seleniumIDE.png" src="https://qiita-image-store.s3.amazonaws.com/0/98214/8e22b148-0d6d-a3a4-a8ae-b259e53b9fa4.png">

# 次書くこと
[デモサイト]( http://example.selenium.jp/reserveApp_Renewal/ )があるので、それで遊んだ結果をメモする。
要素としては、下記のものが含まれる。
・テキストボックス
・プルダウン
・ラジオボタン
・セレクトボックス
入力→確認→完了の画面遷移のシナリオも試す。
HackerRankでシェル芸を磨こう！

# シェル芸やってます？
みなさん！最近シェル触ってますか？
エンジニアだと何だかんだ使うことになるShell Script
awkとかsedとかサラっと使えるとカッコよくないですか！？

とはいえ個人ではあんまりサーバーいじることもなく、勉強する機会がない・・・！

## Hacker Rank
そんな中、面白い勉強法見つけたのでシェアします！
[Hacker Rank](https://www.hackerrank.com)というオンラインで色々なプログラミング問題を解けるサイトを使うのです！

問題はこんな感じです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/5d1321e7-772f-fd64-36dd-d615e5583525.png)
問題文が英語しかないのが難点ですが、例が非常に分かりやすいので苦手な人でも理解しやすいと思います

エディタもきれいです！
![2018-07-17_00h32_08.gif](https://qiita-image-store.s3.amazonaws.com/0/201242/f66a1562-9760-bc8d-345a-d85b5c3d6810.gif)

アルゴリズムや統計などのジャンル別に幅広い問題があり、好きな言語を選んで解くことができます。

## Linux Shell
しかも、Hacker RankにはLinux Shellの問題だけ集めた問題集があります！
[Linux Shell の問題一覧](https://www.hackerrank.com/domains/shell)

なかなか他の媒体でShellに特化した問題って見つからないので、すごく貴重です。
難易度もそれほど難しくはなく、慣れればワンライナーで解ける問題ばかりです。
手を動かして学びたい人は是非！

## みなさんのオススメ教えてください！
この方法でシェル勉強したらかなり面白かったです！
Hacker Rankの問題は週末で大体解いてしまったので、他にシェル芸勉強できるサイトありましたら教えてください！
またオススメの勉強法あればそちらも！
C言語　文字列連結

```c
#include <stdio.h>
#include <string.h>

void main() {

	char s1[11] = "こんにちは";
	char *s2 = "こんばんは";

	strcat(s1,s2);
	printf("%s\n", s1);

}

```
```
こんにちはこんばんは
```
Raspberry PiでGPIO制御する時の初期値設定(Python)

# はじめに

Raspberry PiでGPIO制御をしていた際にハマったことと解決方法です。

# 環境

* Raspberry Pi 3 Mobile B+
* Raspbian 9.4
* Python 3.6


# ハマったこと

GPIO制御の初期化時に、INPUT or OUTPUT を選択します。
このとき、初期値はHighまたはLow のどちらかとなりますが、その初期値が望まない値になります。

```python
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)     #初期値はHighがいいけど、Lowになっている
GPIO.setup(11, GPIO.OUT)    #初期値はLowがいいけど、Highになっている
GPIO.cleanup()
```

たとえば、下記のようなギャップが発生するため、動いてほしくない動作が発生する場合があります。
（プログラム実行時、最初の1回だけ余計なリモコン信号を発してしまう、など）

* 期待する初期値： Low
* 実際の初期値： High

# 解決方法

setupメソッドで初期値の設定ができました。

```python
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup(11, GPIO.OUT, initial=GPIO.LOW)
GPIO.cleanup()
```

# 参考

* https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/
これから作ってみたいもの備忘録

1：あるウェブサイトをクロールして、特定の箇所に表示される文字列を抜き出し、Excel形式で出力できるようにする。
出力先はExcelのファイル、また可能ならGoogleスプレッドシートへの出力ができるようにしたい。

さらに可能なら各ユーザーの出力結果を統合できるようにもしたい。

対象のウェブサイトはログインが必要であり
それぞれのユーザーの持つデータを取り出す事ができるか
また、対象のページはページ内でのボタンでの表示切り替えがあるので、単純にクロールかけて全部取れるかどうか、何かしらの工夫が必要かが現在の懸念

2：ユーザー投稿型のコミュニティサイトの構築
ユーザーが記事を書き、アップしたものに対して他ユーザーが評価をおこなえるサイトの構築。

タグなどを利用できるような入力欄と
XSS対策の実装がちゃんと行えるのかどうかが心配
webpack4でデフォルトのチャンク分割を確認する

- webpack 4.16.0


# 概要
webpack4のデフォ設定でチャンク分割がどのように行われるのか確認した。
ついでに分割されたチャンクがブラウザ上でlayzyloadされるかも確認したい。

[本家説明書](https://webpack.js.org/plugins/split-chunks-plugin/)では想像しにくいケースごとの説明が[この記事](https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366)で4パターン解説されていたので、それを[コードにして実際にバンドルしてみた](https://github.com/umezo/webpack-default-chunksplitting-confirmation)。


# 基本動作
https://webpack.js.org/plugins/split-chunks-plugin/#defaults

以下の条件を全部満たすとチャンクに分割される

1. 共有されているかnode_modules以下のモジュールである
2. 30kb以上である (minify, gzip前)
3. チャンクが要求されロードするときの同時リクエスト数が５以下である
4. ページ表示時の同時リクエスト数が3以下である

3と4はよくわからんかった。

# 実験

冗長なので１つ目のサンプルについてだけ。

エントリーポイントでは、テスト用のモジュールを[dynamic import](https://github.com/tc39/proposal-dynamic-import)する。
あとでランタイムでlayzyloadされるか見たいので、promiseの解決時にログを吐いておく。

```index.js
import('./chunk-a').then(() => { console.log('chunk-a loaded'); });
import('./chunk-b').then(() => { console.log('chunk-b loaded'); });
import('./chunk-c').then(() => { console.log('chunk-c loaded'); });
import('./chunk-d').then(() => { console.log('chunk-d loaded'); });
```

## 各チャンクの中身
- a react, react-dom, 適当なコンポーネントA
- b react, react-dom, 同B
- c angular, 同C
- d angular, 同D

## 条件確認
1. reactやangularはnode_modules以下のモジュールであり、複数のチャンクで利用されている。 (reactがaとb, angularがcとd)
2. reactもangularも30kb以上である。
3. チャンクに対してのロード数が本体とモジュールの2
4. ロード時のリクエスト数は1のまま (?ここ自信ない)


## バンドル結果
条件に該当するので、めでたくreactやangularが分割される。
`dynamic import` を明示したモジュールは強制的に分割されるっぽい。
`production` でバンドルしてしまったが、 `development` でやったほうが実験としては妥当だった・・・

```
 99K 0.js       react, react-dom
176K 1.js       angular
 129 2.js       chunk-d, ComponentD
 129 3.js       chunk-c, ComponentC
 134 4.js       chunk-b, ComponentB
 134 5.js       chunk-a, ComponentA
2.4K sample1.js
```

## ブラウザ上での動作
適当なHTMLをwebpack-serveでホストしてエントリーポイントを読み込んだ場合のネットワークの様子をgifアニメに記録した

![sample1.gif](https://qiita-image-store.s3.amazonaws.com/0/12657/f5801d42-8a96-6b43-2b06-36f235a979e0.gif)

順をおっていくと
1. エントリーポイントをダウンロードする
2. 分割されたモジュールをダウンロードする
3. reactが含まれる `0.js` のダウンロードが終わり chunk-a, chunk-b のプロミスが解決される
4. angularが含まれる `1.js` のダウンロードが終わり chunk-c, chunk-d のプロミスが解決される


# まとめ
webpackのチャンク分割の動作を確認した。
`dynamic import` すると条件に従って自動的に分割される。
ブラウザ上でlayzyloadもされる。

べんりー。
Ruby on Railsをインストールして簡単なwebアプリケーションを作成する(Ubuntu編)

# はじめに
Ruby on Railsをインストールして、簡単なwebアプリケーションを作ってみました。
本記事は、その記録です。

# 対象読者
Ruby on Railsを使ったことがなくて、どんな感じか触ってみたい人

# 必要なもの
- Ubuntu 18.04 LTS
- Ruby

Rubyをインストールされていない方は、「[Rubyのインストール方法〜Ubuntu編〜](https://qiita.com/idaidaidaida/items/66db61b78c42a8521c3b)」を参照してくださいませ。

# 内容
## １．Ruby on Railsをインストール
まずはRuby on Railsをインストールします。
Ruby on Railsを動かすのに必要なソフトウェアもあるので、それらも合わせてインストールします。

```
# Ruby on Railsの実行に必要なソフトウェアをインストール
$ sudo apt-get install sqlite3 libsqlite3-dev nodejs gem

# Ruby on Railsプロジェクトのライブラリ管理ソフトであるbundlerをインストール
$ gem install bundler

# Ruby on Railsをインストール
$ gem install rails --no-document
```

<details>
<summary>エラー「Command ‘gem’ not found」が表示される場合</summary>
gemがインストールできていないか、gemへのパスが設定できていないことが原因で発生するエラーです。
コマンドラインで「exec $SELL -l」と実行すると問題を解消できる可能性があります。
エラーが出た人は「exec」コマンドを実行してみてくださいませ。
</details>
## ２．簡単なwebアプリケーションを作成
ここでは、簡単なtodoアプリケーションを作成します。
Railsのscaffoldという自動生成コマンドを使えば、コーディング無しで簡単なCRUDアプリを作れちゃいます。

```
# Railsアプリケーションを作成する
$ rails new todoapp

# 上のコマンドで「todoapp」フォルダが生成されているので、そのフォルダに移動する
$ cd todoapp

# 生成したRailsアプリケーションの動作に必要なライブラリ群を一括インストールする
$ bundle install --path vendor/bundle

# 「scaffold」機能を使用してコードを自動生成する
$ rails g scaffold todo title:string body:text

# 「scaffold」で生成されたマイグレーション用のファイルを使用してDBにテーブルを作成する
$ rails db:migrate

# Webサーバーを起動する
$ rails s
```

ブラウザで「http://localhost:3000/todos」にアクセスするとtodoアプリケーションが表示されるはずです。

※todoアプリのイメージ
![todoアプリイメージ](https://qiita-image-store.s3.amazonaws.com/0/178845/d9c47c8f-3394-a693-fd13-550b8f70b676.png)
# 感想
本当に簡単にWebアプリケーションができてしまったので驚きました。
実用的なWebアプリケーションを作るにはまだ学習が必要ですが、最初の一歩のハードルが低いのは素晴らしいことだなと思います。

# 参考文献
[Ruby on Rails 4.2 を Windows にインストールする手順をかなり丁寧に説明してみました](https://www.oiax.jp/rails/zakkan/rails_4_2_installation_on_windows.html)
[Ruby on Rails 5 入門](https://dotinstall.com/lessons/basic_rails_v3/41803)
Docker上に簡易HTTPSサーバを構築する(Node.js)

HTTPSでデータのやりとりを確認したいときがあったので簡易的なHTTPSサーバを作成してみた。

## 環境

- Docker
    - Version 18.03.1-ce-win65 (17513)
- Node.js
    - v8.11.3
- npm
    - 5.6.0
- 使用Image
    - alpine

## コンテナを作成する

```
docker run --name server -itd -p 8443:8443 alpine
```
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/18fd6d6e-bd1b-ffea-74eb-8308c1ed80ca.png)

## コンテナ内にログインする

```
docker exec -it server /bin/ash
```
**ash**はalpineで使用されているシェル


- 参考サイト
    - https://qiita.com/yutaChaos/items/56dd7ea09d7e2b0d9173

![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/70d99522-7945-5450-5b98-3301ff874869.png)

## 必要なモジュールをインストールする

1.alpineのパッケージリポジトリから最新のインデックスを取得

```
apk update
```
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/a8cd53df-6aa1-8694-ec75-15bfaf1742d8.png)

2.Node.jsのインストール

```
apk add nodejs
```
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/d9cebbe5-749e-5986-c47a-6281b8f0715b.png)


3.npmのインストール

```
apk add npm
```
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/d4c8d835-fe94-2a92-90e2-2af679f60501.png)


4.opensslのインストール（HTTPSの証明書作成に必要）

```
apk add openssl
```
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/d30b9f72-ecc1-a5c5-be8a-3f26515264c0.png)

## 作業用ディレクトリの作成

```
mkdir work
cd work
```
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/da264b98-bf4d-e8b1-b508-cfa2803706b4.png)

## 証明書ファイル(pfxファイル)の作成

```
openssl genrsa 2048 > mysslserver.key
openssl req -new -key mysslserver.key -subj "/C=JP/ST=Tokyo-to/L=Shibuya/O=Company Name/OU=IT dept./CN=Company Dept CA" > mysslserver.csr
openssl x509 -days 3650 -req -signkey mysslserver.key < mysslserver.csr > mysslserver.crt
openssl pkcs12 -export -inkey mysslserver.key -in mysslserver.crt > mysslserver.pfx
```
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/7b8ca75b-d42c-f584-4c5f-44167d6857b0.png)

- 参考サイト
    - https://qiita.com/wan-liner/items/980a552e94dac0d935e2

## HTTPSサーバの作成

viで作成する。

```js:https.js
https = require('https');
fs = require('fs');
port=8443;
https.createServer({pfx: fs.readFileSync('mysslserver.pfx')}, function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(port);
console.log('Server running at port:' + port);
```

- 参考サイト
    - https://qiita.com/wan-liner/items/980a552e94dac0d935e2

## サーバの起動

```
node https.js
```

![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/36c65f8a-5727-76d7-e9e3-aad23126993e.png)

## 疎通確認

**https:localhost:8443**にアクセスして**Hello World**が表示されればOK

![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/252241/324962c0-fcac-85ed-0293-6f24855cc76d.png)
Markdown PDFでコード部分の日本語フォントがおかしい場合の対処法

# 概要

[Markdown PDF](https://github.com/yzane/vscode-markdown-pdf/blob/master/README.ja.md)でコード部分の日本語フォントがおかしい場合の対処方法。

# 環境

* Windows 10
* Visual Studio Code  1.25.1
* Markdown PDF(yzane.markdown-pdf) 1.2.0 (2018/05/03)

# 現象

コード部分、つまり、バッククォート3つで囲んだ部分の日本語の漢字部分のみ字形が違う。よく見てみるとどうも中国語のフォントっぽい（Ming～）（確認の「確」が違う字形だった）。

ので、フォントの優先順位の問題（Officeでたまにあった問題に近い？）と推測した。

# 対処

対処として、cssを書き換えるとうまくいった。

以下の例では直接変更している。

しかし、おそらくバージョンアップで上書きされるか無効になると思うので、正しい対処は、コピー変更したcssを、markdown-pdf.stylesなどで指定するのが望ましいと思われる。

* 場所 

```
C:\Users\XXXX\extensions\yzane.markdown-pdf-1.2.0\styles\markdown.css 
```

* 変更前

```css
code {
    font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; 
    font-size: 14px;
    line-height: 19px;
} 
```

* 変更後

```css
code {
    /* font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; */
    font-family: Menlo, Monaco, Consolas, "ＭＳ ゴシック", "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
    font-size: 14px;
    line-height: 19px;
} 
```
Udemyの素晴らしさを伝えたい

# TL;DR;
動画で技術を学習するならUdemy
（最初に断っておくと、別にUdemyの関係者でもなんでもないです）

## 新しい技術を学ぶときにどんな方法で勉強してますか

+ 技術本
+ ネットの記事
+ 社内Wiki

いろいろありますよね。

でも、
+ 重い本を持ち歩くの無理
+ 本を広げながらコード書くんしんどい
+ ネットの情報まとまってないしなー

とかめんどうがあるじゃないですか。

そこで最近流行っているのが一般的にMOOCと呼ばれる **動画学習** です。

## 動画学習のメリット
+ 操作の動きがわかる → 本の操作通りにやったつもりがちょっとミスっててあれこれ数時間かかるとかがない
+ PCがあれば勉強できる（PCモニタがあると余計に勉強が捗る）
+ 何よりまとまっている!!

## 動画学習プラットフォーム
+ Udacity
+ Coursera
+ Edx
+ Udemy

などなど、様々なプラットフォームがありますが、ここではUdemyを紹介します。

## Udemyのいいところ
+ すごくニッチな技術領域でもコンテンツがあったりする!
+ 日本語の講座も増えてきている
+ 字幕対応続々増加中

### ニッチなコンテンツ郡
他のプラットフォームはどちらかというと学問に関連したコース(機械学習、プログラミング等)がメインなのですが、
Udemyは個人で~~好き勝手に~~投稿しているので結構ニッチな動画があります。
例えば自分の場合だと、

+ Devops系(Ansible,Chef,Git等)
+ 分散システム系(Kafka,Spark,Cloudera等)
+ インフラ系(Linux,AWS,GCP等)

このように自分が勉強したいなーと思って検索をかけると意外とでてくるのは嬉しいですね。
（あまりに最先端だったり、世界で使われてなかったりするとないかも?）

### 日本語の講座
Udemyは元々外国のサービスだったので正直今でも英語の動画の数が圧倒的に多いのは事実です。

しかし、最近では日本語の講座が増えてきました。
例えば、
+ Python,Rを使ったデータサイエンスや機械学習講座
+ Java, RubyonRails、HTML,CSS,Javascript等のプログラミング
+ セキュリティ
関連はかなり日本語講座が恵まれてきています。
（今後も増えてくることを願うばかりです）

### 字幕対応
Udemyは長らく字幕に関しては投稿者がつけなければ字幕がなく、
日本人である自分も英語をリスニングしながら勉強するのは結構酷でした。。。

しかし最近はYoutubeのように英語の自動字幕機能が追加されてきています。
（特に評判のあるコースはほぼ間違いなくついていますね）
精度はどうなんだ・・・と思われるかもしれませんが、ぶっちゃけ今はほとんど問題ないです。
専門用語は一部うまく行っていないとこもあるのですが、基本文法の部分はきっちり字幕化できています。

なので、音声と字幕である程度英語も補完することができます。

でも、それでも英語はなあ・・・(´・ω・｀)
という人いますよねw

そんななか、、、

<img width="1260" alt="jimaku2.png" src="https://qiita-image-store.s3.amazonaws.com/0/121758/f42a7c97-8335-4bc9-f883-976034f2e84e.png">

<img width="1260" alt="jimaku1.png" src="https://qiita-image-store.s3.amazonaws.com/0/121758/76b73a5d-8193-c007-fe2f-7de51a913afc.png">

このように日本語自動字幕が徐々にスタートしてきています!
ぶっちゃけ精度はまだまだなのと、対応講座がまだ少ないので、これから感はあるのですが、
近い将来日本語字幕で勉強できる日も近いのかなとワクワクしています。

ちなみに自分はUdemyにそそのかされて150近いコースを買っていますwww

## 最後に
今でも本やWebサイトを使って技術の勉強はしていますが、
これに組み合わせて動画学習も入れることでより技術の理解を深めることができるようになりました。
コンテンツを提供してくださる偉大な講師の方々に感謝しつつ、いずれは自分もコンテンツを作って貢献できるようにがんばっていきたいと思います。
HTTP Strict Transport Security

# 事象

HTTPS の Web サイトを切り替えのため、一時的に HTTPS でのアクセスを遮断。

いったん HTTP でのアクセスを確認した後、 HTTPS でアクセスできるか確かめようとしたところ、 Chrome から見たときに HTTP でアクセスしようとしても、すぐに HTTPS にリダイレクト(?)される事象が発生。

なお、サーバ側では HTTP から HTTPS へのリダイレクトは設定していない。


# 原因

原因は HTTP Strict Transport Security (HSTS) という仕様によるものだった。

一度でも HTTPS でアクセスして、その時の Response header に `Strict-Transport-Security` を以下のように付けて返した場合、対象サイトへのアクセスは以降、必ず HTTPS で行われるようになる。 (HTTP で行えなくなる)

```
Strict-Transport-Security: max-age=31536000; includeSubDomains
```

ユーザの預かり知らぬうちに不意に HTTP に切り替わっていて、重要な情報が盗み見されることを防ぐのに有効な仕様で、もはや時代は HTTPS 必須化なので、あるべき仕様と言えます。


# TIPS

少なくとも Chrome の場合は、 HSTS の対象となったドメインを内部的に記録している。 (仕様的にはそうでないと実現できない)

もし手動でこの情報を編集したい場合は、以下のページから行う。

chrome://net-internals/#hsts

[Delete domain security policies] を実行することで、この制約を解除して、 HTTP でアクセス可能になる。(それでも消えない場合は、ブラウザ閲覧履歴を消す)

なお、 HSTS preload list という RFC 6797 には定義されていない仕様もあり、このリストに入ったサイトは、上記の [Delete domain security policies] でも制約を削除できない。
HSTS preload list は予め、サイトのドメインを登録フォームから登録しておくことで、チェックを通ったものは、 Chrome (および、その他のモダンブラウザ) にハードコードで HSTS の対象として追加され、数カ月後にリリースされたバージョンから反映されるようになる、というものである。

> References

- [RFC 6797 - HTTP Strict Transport Security (HSTS)](https://tools.ietf.org/html/rfc6797)
- [Strict-Transport-Security - HTTP | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security)
- [httpでアクセスしたいのにhttpsへリダイレクトされて悩んだ（HSTSまたはStrict-Transport-Securityの沼） - Qiita](https://qiita.com/tmasu/items/14632bf45cf05b90d0c9)
- [Chrome: how to stop redirect from http:// to https:// - Super User](https://superuser.com/questions/565409/)
- [HSTS Preload List Submission](https://hstspreload.org/)
- [Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#feat=stricttransportsecurity)