OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニアのためのボックスモデル

ボックスの生成

HTMLの要素はどの要素もボックスと呼ばれる四角形の領域を生成する。ボックスは大きく分けてブロックボックスとインラインボックスの２種類に分けられる。これは、displayプロパティの値によってボックスの種類が決まる。

各HTML要素はブラウザのデフォルトスタイルシートによってdisplayプロパティのデフォルト値が指定されているので、それに伴ってデフォルトのボックスの種類も決まっているが、displayプロパティを変更する事でボックスの種類を帰る事ができる。

h1 {
  display: block;
  font-size: 2em;
  -webkit-margin-before: 0.67em;
  -webkit-margin-after: 0.67em;
  -webkit-margin-start: 0px;
  -webkit-margin-end: 0px;
  font-weight: bold;
}


ブロックボックスとは

displayプロパティの値がblockやtableなどの要素はブロックボックスを生成する。ブラウザのデフォルトでブロックボックスを生成する要素にはh1~h6,p,div,ul,ol,li,table要素などがある。
ブロックボックスは幅に関係なく、上から下へ縦方向に配置される。ブロックボックスの前後には改行が伴って、1つの段落としてレイアウトされると考えるとイメージがつきにくいかもしれない。
他にブロックボックスにはこのような特徴がある。
・幅（width)や高さ（height）を指定
できる。幅を指定しなければ親要素の幅全体に広がる。
・上下左右のmargin、paddingを指定できる。![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/915527ab-251c-1a99-20f3-c304ef010b54.png)



インラインボックスとは

displayプロパティの値がinlineや
inline-tableなどの要素はインラインボックスを生成する。ブラウザのデフォルトでインラインボックスを生成する要素にはspan,em,strong,img要素などがある。
インラインボックスは左から右へ横方向に配置される。インラインボックスの前後には改行は伴わず、行内の一部としてレイアウトされると考えるとイメージがつきやすいかもしれない。

他にもインラインボックスにはこのような特徴がある。
・幅（width）や高さ（height）を指定できない
・上下のmarginを指定できない。![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/56382b88-1ec3-cb95-3f46-2b816f6abd82.png)

※インラインレベル要素でもimgや、input、textarea要素のようにCSSで幅や高さを指定できる要素もある。このような要素は置換要素と呼ばれ、幅や高さを指定できるHTMLの属性（width, height, size, colなど）を持っている特徴がある。


インラインブロックボックス

displayプロパティの値がinline-block要素はインラインブロックボックスを生成する。インラインブロックボックスはインラインボックスと同じように横方向に配置されるが、ブロックボックスのように幅や高さ、上下のmarginを指定できるので横並びのナビゲーションなどのレイアウトに便利。


displayプロパティ
　主要なdisplayプロパティの値と生成されるボックスは以下のようになる。<img width="578" alt="667de1e9f88cebd4318f4718508026d5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/05a5500c-175c-b502-f373-5664c21291a9.png">


ボックスモデルとは

cssでレイアウトをする際には、ボックスモデルを理解する必要がある。cssの定義するボックスモデルは以下の図のように4つの領域で構成されている。![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/e0fa45d8-ea75-3050-9112-b73def4f832b.png)

参考元：https://nulab.com/ja/blog/nulab/css-basics-for-engineer-boxmodel/
画像の引用先：https://nulab.com/ja/blog/nulab/css-basics-for-engineer-boxmodel/
【Java】Java入門

#【Java】Java入門
「順次進行」「条件分岐」「繰り返し」の勉強までしました。



##実行
```java:Hello.java
class Hello {
    public static void main(String[] args){
        System.out.println("Hello");
    }
}
```
```:出力
Hello
````



##変数
```java:Variable.java
class variable {
    public static void main(String[] arg){
        int var = 1;
        System.out.println(var);
    }
}
```
```:出力
1
````



##配列
```java:Array.java
class Array{
    public static void main(final String[] args) {
        int[] arr = new int[] { 8, 12, 21 };
         System.out.println("朝食" + arr[0] + "時からです");
         System.out.println("昼食" + arr[1] + "時からです");
         System.out.println("夜食" + arr[2] + "時からです");
    }
}
```
```:出力
朝食8時からです
昼食12時からです
夜食21時からです
````



##条件分岐
```@nkojimaさん助言にて追記の方を参照してください.java
class Age{
    public static void main(String[] args){
   
      int humidity;
      humidity = 50;

      if (humidity >= 60){
        System.out.println("湿度が" + humidity + "％です");
        System.out.println("ジメジメしてます");
      }else if((humidity <= 60) && (humidity >= 40)){
        System.out.println("湿度が" + humidity + "％です");
        System.out.println("快適です");
      }else if(humidity <= 40) {
        System.out.println("湿度が" + humidity + "％です");
        System.out.println("カラカラしてます");
      }

    }
}
```
```:出力
湿度が50％です
快適です
````


```java:@nkojimaさん助言にて追記.java
2020-04-24 23:41

public class RelativeHumidity {
    public static void main(String[] args){

      int humidity;
      humidity = 50;

      System.out.println("湿度が" + humidity + "％です");

      if (humidity >= 60){
        System.out.println("ジメジメしてます");
      }else if((humidity <= 60) && (humidity >= 40)){
        System.out.println("快適です");
      }else if(humidity <= 40) {
        System.out.println("カラカラしてます");
      }

    }
}
````

##環境構築
windowsで[JDK](https://www.oracle.com/java/technologies/javase-downloads.html)とエディターの[VSCode](https://code.visualstudio.com/download)をインストール

##参考文献
この記事は以下の情報を参考にして執筆しました。
[キノコード / プログラミング学習動画のYouTuber](https://www.youtube.com/c/kinocode)
awk コマンドの浮動小数計算

こんにちは
awk コマンドで、```echo 2.3 | awk '($1*100)%10==0'``` のような浮動小数計算の結果は、厳密計算とは一致しないです（この条件は ```$1*100``` が ```230``` とはならず偽となります）。

```console
$ echo 2.3 | awk '($1*100)%10==0'
$
$ diff -u <(seq 2 .1 3) <(seq 2 .01 3 | awk '($1*100)%10==0')
 2
 2.1
-2.2
-2.3
 2.4
 2.5
 2.6
$
```


なお、Python でも同様となったので awk だけの問題ではないようです。

```console
$ diff -u <(seq 2 .1 3) <(seq 2 .01 3 | python3 -c 'import sys; [print(i, end="") for i in sys.stdin if (float(i)*100)%10==0]')
 2
 2.1
-2.2
-2.3
 2.4
 2.5
 2.6
$
```


### 対処方法

条件の書き方を ```int($1*100+0.5)%10==0``` と工夫し、今回の例では、一致を得られました。

```console
$ echo 2.3 | awk 'int($1*100+0.5)%10==0'
2.3
$ diff -q <(seq 2 .1 3) <(seq 2 .01 3 | awk 'int($1*100+0.5)%10==0')
$
```
C++のコンパイルから実行までを自動で行うシェルスクリプトを作った


最近競プロ人口がどんどん増えていますね。競プロきっかけでC++を始めたという方も多いのではないでしょうか。

今回はコマンドラインでC++のコンパイルと実行を行っている人に向けて、その２つを一気にやってしまうスクリプトを紹介します

## 作成したスクリプト

以下を`.bashrc`または`.zshrc`に追記してください。

関数名やコンパイルオプションなどは適宜変更していただければと思います。

```bash:.bashrc
function runcpp () {
    echo -e "[\e[34mx\e[0m] g++ -std=gnu++17 -Wall -Wextra -O2 $1 -o a.out"
    g++ -std=gnu++17 -Wall -Wextra -O2 $1 -o a.out

    result=$?
    if [ $result -ne 0 ]
    then
        echo -e "[\e[31m-\e[0m] compile failed"
    else
        echo -e "[\e[32m+\e[0m] successful complie"
        echo -e "[\e[34mx\e[0m] run ./a.out"
        ./a.out
    fi
}
```

実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211490/b29762b6-fad2-1d4e-7fe7-d2f1cb73744f.png)

## スクリプトの説明

スクリプトは次のように使います。

```sh
$ runcpp filename.cpp
```

中身の流れは

1. `g++`を実行
2. もしコンパイルに成功したら`./a.out`を実行、そうでなければ終了

というとてもシンプルなものです。しかしネット上にはコンパイル中なのか`a.out`を実行中なのかよく分からないものが多く「スクリプトの実行状況をわかりやすく表示」するものが見当たらなかったため作成しました。

まず、

```bash
    echo -e "[\e[34mx\e[0m] g++ -std=gnu++17 -Wall -Wextra -O2 $1 -o a.out"
    g++ -std=gnu++17 -Wall -Wextra -O2 $1 -o a.out
```

とすることで`$1`で取得した名前のcppファイルをコンパイルします。
`echo`コマンドに`[\e[34mx\e[0m]`とごちゃごちゃした部分がありますが、ANSIエスケープシーケンスというものを使ってターミナルでの出力に装飾をしています。この場合は`[x] g++ -std=gnu++17 -Wall -Wextra -O2 $1 -o a.out`と出力し`[x]`の`x`は青色で表示します。

次に

```bash
    result=$?
    if [ $result -ne 0 ]
    then
        echo -e "[\e[31m-\e[0m] compile failed"
    else
        echo -e "[\e[32m+\e[0m] successful complie"
        echo -e "[\e[34mx\e[0m] run ./a.out"
        ./a.out
    fi
```

ですが、まずresult変数に`$?`という値を代入しています。`$?`は直前に行ったコマンドの返り値が入っています。今回「直前のコマンド」というのはg++コマンドのことですね。g++の場合コンパイルに成功していたら`0`が返ってきます。

そしてresultの値が`0`でないか、そうでないかで分岐しています。（`-nq`は`not equal`の略ですね）

 - `0`でなければ`[-] complie failed`と出力して終了します。
 - `0`であれば`[+] successful complie`と出力して、すぐさま`a.out`を実行します。

## 終わりに

単純なスクリプトですが便利ですのでぜひ使ってみてください！
また応用すれば他の言語のコンパイル&実行も同様に自動化できると思いますので試してみてください
【Day60】積み上げ日記

##予定
■Udemy（有料教材）
－セクション14,15,16
■HOMEボタンを押したとき画面遷移
■○か×をカウントする

##完了
■Udemy（有料教材）
−セクション１４

##学習時間
４h

##学習ポイント
■HOMEボタンを押したとき画面遷移
- dismissで戻れる
■○か×をカウントする
■アプリを消した時でも、記録が保存されるようにする
■最高得点を反映させる
■最高得点が更新された時に効果音を発生させる
■○か×を押した時、効果音を発生させる

##疑問点
■prepare for segue
－値を渡すためのメソッド	
■プロトコル
－どういう時に使うのか
－書き方

##ひとこと
細かく時間を区切って、それに合わせて学習計画を立てる。
1日の目標の立て方が悪い。「セクション○○まで」じゃなく、「この機能を作る」など実用的に形にできる物を目標に設定する！
Pythonで環境変数を読み込むときはpydanticを使うと便利

アプリケーションを実装する際、環境変数の扱いって微妙に面倒ですよね？

Pythonで実装する際、[pydantic](https://pydantic-docs.helpmanual.io/)というライブラリを使うと、デフォルト値をセットしたり、int型にキャストしたり、 `.env` から値を読み込むなどの処理を簡単に実装することができます。今回の記事ではそれらのサンプルコードを紹介します。

ちなみに、pydanticは環境変数を読み込むだけのライブラリでは無く、型アノテーションを利用してクラスを定義できるライブラリで、他にも例えばjson形式のデータをクラスにキャスト・バリデーションすることができます。他の機能についてまとまって読みたい方は、次の記事を読んでください。

[Pydantic 入門](https://qiita.com/0622okakyo/items/d1dcb896621907f9002b)


# 環境変数を読み込む

次のような環境変数がセットされているとします。

```bash
# bash形式
export REDIS_HOST_NAME=localhost
export REDIS_PORT=6379
```

pydanticを使えば、次のようなコードで読み出せます。

```python
from pydantic import BaseSettings

class Settings(BaseSettings):
    redis_host_name: str
    redis_port: int

settings = Settings()
 
print(settings.redis_host_name)
# => localhost
print(settings.redis_port)
# => 6379
print(type(settings.redis_port))
# => <class 'int'>
```

もし環境変数がセットされていない場合や、型キャストに失敗した場合はバリデーションエラーを出してくれます。

```
pydantic.error_wrappers.ValidationError: 1 validation error for Settings
redis_port
  value is not a valid integer (type=type_error.integer)
```


# dotenvを利用する

開発中、環境変数を設定するのを簡略化するため `.env` というファイル形式を利用できます。node.jsの記事ですが、こちらがわかりやすいと思います。

[環境変数の代わりに .env ファイルを使用する (dotenv)](https://maku77.github.io/nodejs/env/dotenv.html)

まず、 `pip install python-dotenv` か `pip install pydantic[dotenv]` で[python-dotenv](https://pypi.org/project/python-dotenv/)も併せてインストールする必要があります。

次のような `.env` ファイルがあるとすると、

```bash:.env
REDIS_HOST_NAME=localhost
REDIS_PORT=6379
```

次のようなコードで読み込むことができます。

```python
from pydantic import BaseSettings

class Settings(BaseSettings):
    redis_host_name: str
    redis_port: int

    class Config:
        env_file = '.env'

settings = Settings()
```


# 更に詳しい機能

これで普段の開発でよく使う環境変数関連の便利な機能は紹介できたと思います。更に知りたい方は、公式ドキュメントの該当項目を読んでみてください。


[Settings management - pydantic](https://pydantic-docs.helpmanual.io/usage/settings/)
【AWS】Amazon Lightsailって、なに？

# ざっくり言うと、簡易版AWS
![005b02cf-baf5-eb5f-9e83-ab2059e0fc61.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622473/a03d63f6-be0e-db97-5fa0-e20a8bcbd7da.png)

### AWSサービスの一つ
AWSには、いろいろなサービスが存在していて、
例えば、よく聞くものとして、

- EC2(仮想サーバー)
- S3(ストレージ)
- RDS(データベース)

などなどあります。
これらを個別に設定し組み合わせていくことにより様々なインフラ構築やプロダクト開発が可能となりますが、
使いこなすにはそれなりに学習コスト、また運用には金銭的コストがかかってきたりします。
(初年度無料枠とかはあるにしても)
もっとライトに、それら主要なサービスの一部をセットで気軽に、比較的低コストで利用できるようにした、
まさに**簡易版AWS**、それが**Lightsail**です。

### とりあえず、いくら？

細かいこと抜きにして、最低限で言ってしまえば、
月/3.5 アメリカ合衆国ドル
ざっと、**月額380円**くらい。(1ドル108円換算)
しかも**初月無料**。

このくらいの値段なら気楽に試せそうですね。

### どんなことができる？

- **ポチっと**インスタンスから作成できる。
- WordPress, Node.js, Nginxなど、いくつかのアプリも**ポチっとプリインストール**できる
- SSHキーペアの作成、**SSHログイン**できる
- MySQLなど**DB**が使える(別途費用)
- 固定IPにできる(**基本無料**)
- **ドメイン割り当て**できる(ドメイン取得は別途)
- ロードバランサーで**負荷分散**できる(別途費用)
- ファイアウォールで**ポート制御**できる
- スナップショットで**バックアップ**取れる
- メトリクスグラフでCPU使用率監視と**アラームの設定**ができる

ざっとこんな感じですが、いかがでしょうか？
**AWS本格利用の前段階**として、また**スキル練習場所**としてもぜひ利用してみてください。

**Amazon Lightsail**
**https://aws.amazon.com/jp/lightsail/**
Failed to execute command 'export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin; export LANG=C.UTF-8; monit -t 2>&1' with exit code '1'【RaspberryPi3】【OpenMediaVault5】

#概要
RaspberryPiをNAS化するためにOpenMediaVault（OMV)をインストールしていじっていたら、途中から
`Failed to execute command 'export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin; export LANG=C.UTF-8; monit -t 2>&1' with exit code '1'`
というエラーをOMVが吐くようになってしまいました。
いろいろ検索してエラーをなくすことができたので、やったことをメモします。
#環境
Raspberry Pi 3 Model B+
Rasbian Buster Lite
OpenMediaVault5
#症状
RaspberryPiにUSB接続したHDDをOMV上でマウントし、変更を適用しようとするとタイトルのようなエラーが出てしまいました。
うろ覚えですが、一度OMVでマウントしたHDDを別PCでフォーマットし直し、再度接続してOMV上でマウントしようとしたところ、このエラーが出るようになった気がします。
#原因
確証はありませんが、同じデバイスIDのHDDを過去にマウントしたときの設定が残っていてそれと干渉しているのではないかと推察されます。
#解決方法
下記を参考に、OMVの設定ファイルなどから不要なHDDに関する情報を削除することで解決しました。
[https://forum.openmediavault.org/index.php?thread/26647-failed-to-execute-command-export-path-bin-sbin-usr-bin-usr-sbin-usr-local-bin-us/](https://forum.openmediavault.org/index.php?thread/26647-failed-to-execute-command-export-path-bin-sbin-usr-bin-usr-sbin-usr-local-bin-us/)
##1. /etc/openmediavault/config.xml
RaspberryPiにsshして`/etc/openmediavault/config.xml`をエディタで開きます。
<mntent>タグを検索して見ると`dev-disk-by-label-[HDDの名前]`みたいな感じでマウントされるデバイスがリストされています。
ここに接続していないはずの不要なHDDに対応する要素があればそれを削除し、ファイルを保存します。
なお`dev-disk-by-id-[HDDの名前]`のようにidで名付けされている可能性もあります。
##2. /etc/monit/conf.d/openmediavault-filesystem.conf

`/etc/monit/conf.d/openmediavault-filesystem.conf`をエディタで開きます。
1で削除したHDDと対応する下記のような記述があると思います。これをすべて削除します。

```
check filesystem filesystem_srv_dev-disk-by-label-[HDDの名前] with path "/srv/dev-disk-by-label-[HDDの名前]"
  if space usage > 85% for 5 times within 15 cycles
    then alert else if succeeded for 10 cycles then alert


check program mountpoint_srv_dev-disk-by-label-FileA with path "/bin/mountpoint '/srv/dev-disk-by-label-[HDDの名前]'"
  if status != 0 then alert
```

参考ページの１人めの回答者は２のあとにrebootすれば解決するはずと書いていたのですが、僕の環境ではそれで解決しなかったので、３に続きます。
##3. /srv/
`/srv/`に移動します。
ここにはHDDをマウントさせるディレクトリが格納されています。
１で削除したHDD名に対応するディレクトリがあればそれを削除してください
##4. monit再起動

'service monit start'でmonitを再起動します。sudoをつける必要があるかもしれません。
その後OMVで再度適用を試みたらエラーが出なくなりました。
#おわりに
僕も細部は理解できていないので、ふわふわした説明になっており恐縮です。
まったく同じ状況の方がいれば少しは参考になるかとおもい、メモを残させていただきました。
なにかの一助になれば幸いです。
SendGrid Parse Webhookで無料でメール受信(Ruby on Rails 5.2)

Railsで作成中のWebアプリケーションにSendGridを使用しています。SendGridを通じてメールを「送信」する方が多いと思いますが、「Inbound Email Parse Webhook」を利用してアプリケーションでメールを受信することにも使用できます。

SendGridでのメール「受信」について記事が少ないような気がしましたので記録に残しておきます。

##環境は以下の通りです。 

・Ruby2.5.7　※他の言語でも可能

・rails5.2　※他のフレームワークでも問題無し

・Cloud SQL (PostgreSQL)　※他のDBでも問題なし

・Webサービス自体のサーバー:Google App Engine Standard

・独自ドメイン利用

##目次
大まかなデータ処理の流れ
利用例
実装手順
ハマったポイント
実装に参考にさせていただいたページ

##大まかなデータ処理の流れ
①誰かから独自ドメインのメールに送られてきたメールをSendGridで一度受けてもらい

②SendGridのAPIに自分のWEBサービスにJSON形式でPostしてもらう

③Postされたデータ内容を自らのWebアプリケーション（自分の場合はRails）でPostgreSQLに保存（たまたまPostgreSQLを利用しているだけでなんでも構いません）

④必要に応じて保存されたデータをViewから内容を確認できる

という仕組みです。

メール内容は「to」「 from」「text」などのパラメーターで送られてきますので、そのパラメーターをコントローラーで処理します。

##利用例
・送信者のメールアドレスにより処理を分岐させることや

・日記をメールでつける

・メーリングリストのように送られたメールを転送

などセキュリティーは要注意ですが実現可能です。

##実装手順
前提：SendGridはアカウント登録済み、ドメイン認証済み

※受信はFreePlanでも何通でも無料（2020年4月現在）

以下のABCの設定が必要です。

###A:SendGrid側の設定（2点）

ホーム画面→セッティング→Inbound Parse→Add Host & URLから

####Ⅰ　Postして欲しいURLを指定

例：自分のWebサービスのURL＋「email_parse」 など任意のURLを設定

####Ⅱ　どのドメインへのメールを処理するか

※サブドメイン指定可能ですがユニークである必要があります。

※@より前の部分にかかわらず指定したドメインあてのメールが全てPostされますので私はサブドメインで設定しました。

###B:DNSプロバイダーの設定（1点）

SendGrid でメールを受け取ることを許可するため、お名前.comなどでDNS登録が必要です。MXレコードを「mx.sendgrid.net.」「priority 10」 で設定

###C:Webアプリケーション側の設定

####Ⅰ　SendGrid上で設定したURLをroutesに設定

####Ⅱ　メールが届き次第sendgridからPostされます。
parameter はparams[:to] params[:from] params[:text]などでメールの内容が取得できますのでDBに保存するなり好きな処理が可能になります。

しかしメールアドレスにより処理したい場合、params[:from]では「氏名＋<"aaa@bbb.com">」のような形で送られてくることもありますので、メールアドレスのみを取得したい場合は「params[:envelope]」から取得できました。

##ハマったポイント
①GriddlerというGemが用意されていますが、チュートリアル通り実装しても500エラーが出てくるので利用を諦めました。

※500エラーとしか内容が確認できず手っ取り早く自分で処理しようと思いました、、

②rails 5.2 がパラメーター化されたJsonデータの処理に詰まりました

params[:something] で取得するデータの型はJsonでもHashでもなくActionController::Parametersです。開発環境のターミナル上でParameter {ここに内容が入ってます}と表示されているデータがそれにあたります。sendgridからjson形式で送られるデータをrailsが自動で変換するはずです。その際にメタ文字をエスケープする「\」や改行を意味する「\n」などが入ります。例えば以下のような形式で送られてきます。

```
Parameters: 
{"envelope"=>"{\"to\":[\"aaa@bbb.com\"],\"from\":\"ccc@ddd.com\"}"}
```

このような場合で「aaa@bbb.com」のみを取得したい場合でも、直接params[:email][:to]のような形ではアクセスできませんでしたので①〜③の順を追って処理しました。

①

```
atesaki = params[:email] で
{\"to\":[\"aaa@bbb.com\"],\"from\":\"ccc@ddd.com\"}　のみを切り出し
```

②

①の形になればJsonとして認識されるのでJson→Hashへ変換します。=変換することにより不要な「\」や「\n」の部分がなくなります。

```
hash = JSON.parse(atesaki, symbolize_names: true)
```
※JSON.parse(json 形式のデータ)の オプションで, symbolize_names: trueを入れるとhash[:to]で受け取ることができる。

※ symbolize_names: true無しの場合hash["something"]で値を受け取ることができる。

③

まだ取得できたデータの["aaa@bbb.com"]は配列なので

```
address = hash[:to][0]
```

として配列のn番目のデータを指定してようやく"aaa@bbb.com"のみを抽出できました。

　※これは自分の基礎知識不足で本来ハマるポイントでは無いのかもしれません、、、が同じポイントで悩む方のために共有しておきます。

###実装に参考にさせていただいたページ
https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/
プログラマ脳を鍛える数学パズルQ08 優秀な掃除ロボット

#問題概要
前後左右に動く掃除ロボットが12ステップで移動できる経路のパターン数を求める。ただし同じ場所は2回通らないこととする。

#Code
深さ優先探索。再帰を使って書く。

```python
N = 12 #動く回数

def dfs(path):
    if len(path) > N:
        return 1
    cnt = 0 #パターン数
    for d in [(0,1), (0,-1), (1,0), (-1,0)]:
        next = path[-1][0] + d[0], path[-1][1] + d[1]
        if next not in path:
            cnt += dfs(path + [next])
    return cnt

print(dfs([(0, 0)])) #初期位置を(0, 0)とする
```

#ToDo
Pythonの再帰は遅いらしい。スタックを使って書いたほうが早いか？
C# 基礎プログラミング100本ノック～26-30本目～ 

#こんばんは

本日も基礎プログラミング100本ノックやっていきます！

前回→[21-25本目](https://qiita.com/K_Hisui/items/5669409b4a0dccd66db6)
次回→[31-35本目](https://qiita.com/K_Hisui/items/e2cf0f31e92356bcb279)

#26本目
>整数値を入力させ、その値が1ならone、2ならtwo、3ならthree、それ以外ならothersと表示するプログラムをswicth-case文を使って作成せよ。

~~~Sample.cs
Console.Write("input num : ");
int num = int.Parse(Console.ReadLine());

string result;

switch (num)
{
    case 1:
        result = "one";
        break;
    case 2:
        result = "two";
        break;
    case 3:
        result = "three";
        break;
    default:
        result = "others";
        break;
}

Console.WriteLine(result);
~~~


#27本目
>整数値を入力させ、1からその値までの総和を計算して表示するプログラムを作成せよ。ただし、0以下の値を入力した場合は0と表示する。

~~~Sample.cs
Console.Write("input num : ");
int num = int.Parse(Console.ReadLine());

int result = 0;

if(num > 0)
{
    for(int i = 1; i <= num; i++)
    {
        result += i;
    }
}
else
{
    result = 1;
}

Console.WriteLine(result);
~~~


#28本目
>整数値を入力させ、その値の階乗を表示するプログラムを作成せよ。ただし、0以下の値を入力した場合は1と表示する。

~~~Sample.cs
Console.Write("input num : ");
int num = int.Parse(Console.ReadLine());

int result = 1;

if(num > 0)
{
    for(int i = 1; i <= num; i++)
    {
        result *= i;
    }
}

Console.WriteLine(result);
~~~



#29本目
>整数値を5回入力させ、それらの値の合計を表示するプログラムを繰り返しを使って作成せよ。

~~~Sample.cs
int[] nums = new int[5];

for(int i = 0; i < nums.Length ; i++)
{
    Console.Write("input No." + (i+1) + " num : ");
    nums[i] = int.Parse(Console.ReadLine());
}

int result = 0;

foreach (var num in nums)
{
    result += num;
}

Console.WriteLine(result);
~~~

30本目
>整数値を入力させ、その個数だけ*を表示するプログラムを作成せよ。入力値が0以下の値の場合は何も書かなくてよい。

~~~Sample.cs
Console.Write("input num : ");
int num = int.Parse(Console.ReadLine());

string result = "";

if (num > 0)
{
    for (int i = 1; i <= num; i++)
    {
        result = result + "*";
    }
}

Console.WriteLine(result);
~~~


#リンク
[基礎プロI 100本ノック 基礎編](http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocks.html)
Cent OS 8にTomcat 9をインストール

#はじめに
CentOS-8.1.1911-x86_64を「最低限のインストール」でインストールした環境にTomcat 9をインストールします。
JAVAを事前にインストールしておく必要があります。
JAVAのインストールは[こちら](https://qiita.com/t_skri/items/35cf3df2d8ef73cd5666)を参考にして下さい。

#ユーザー作成
```Bash
useradd -s /sbin/nologin tomcat
```

#ダウンロード
```Bash
curl -O http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/tomcat/tomcat-9/v9.0.34/bin/apache-tomcat-9.0.34.tar.gz
```

#展開・ファイル移動

```Bash
tar xvzf apache-tomcat-9.0.34.tar.gz -C /opt
ln -s /opt/apache-tomcat-9.0.34 /opt/apache-tomcat
chown -R tomcat. /opt/apache-tomcat-9.0.34
```

#パスを通す

```Bash
echo "export CATALINA_HOME=/opt/apache-tomcat" > /etc/profile.d/tomcat.sh
source /etc/profile
```

#サービス定義ファイルを作成
```Bash
vi /etc/systemd/system/tomcat.service
```

```tomcat.service
[Unit]
Description=Apache Tomcat 9
After=syslog.target network.target

[Service]
User=tomcat
Group=tomcat
Type=oneshot
PIDFile=/opt/apache-tomcat/tomcat.pid
RemainAfterExit=yes

ExecStart=/opt/apache-tomcat/bin/startup.sh
ExecStop=/opt/apache-tomcat/bin/shutdown.sh

[Install]
WantedBy=multi-user.target
```

#権限付与

```Bash
chmod 755 /etc/systemd/system/tomcat.service
```
#ファイヤーウォールの設定

```Bash
firewall-cmd --add-port=8080/tcp --zone=public --permanent
systemctl restart firewalld
```

#起動

```Bash
systemctl start tomcat
```

#再起動

```Bash
systemctl restart tomcat
```

#停止

```Bash
systemctl stop tomcat
```

#自動起動設定

```Bash
systemctl enable tomcat
```

#バージョン確認

```Bash
/opt/apache-tomcat/bin/version.sh
```

```
Using CATALINA_BASE:   /opt/apache-tomcat
Using CATALINA_HOME:   /opt/apache-tomcat
Using CATALINA_TMPDIR: /opt/apache-tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /opt/apache-tomcat/bin/bootstrap.jar:/opt/apache-tomcat/bin/tomcat-juli.jar
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Server version: Apache Tomcat/9.0.34
Server built:   Apr 3 2020 12:02:52 UTC
Server number:  9.0.34.0
OS Name:        Linux
OS Version:     4.18.0-147.8.1.el8_1.x86_64
Architecture:   amd64
JVM Version:    11.0.7+10
JVM Vendor:     AdoptOpenJDK
```

#動作確認
http://hostname:8080/docs/
にアクセスして以下のページが表示されればOKです。

![tomcat-docs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/76bddf82-fd1e-33e7-f49c-14d74c236c52.jpeg)

#まとめ
以上でインストール出来ました。
【メモ書き】Node-Red構築

# 　前置き
　　Webアプリを作りたいけど環境構築が素人には難しい。
　　Node-Redは環境構築、開発、運用が簡単のため使用することにした。

## １．環境構築
　VMWware ESXi上にサーバを構築した。

　◆ サーバスペック
　　開発環境と検証環境を用意したいので余裕のある構成にした。

　　OS 　Ubuntu Linux (64 ビット)
　　CPU　2 Core
　　MEM　4GB
　　SSD　64GB

## ２．インストール手順
　　公式ドキュメントに記載されている手順通り実行する。
　
　・公式ドキュメント
　　https://nodered.jp/docs/getting-started/raspberrypi


◆　Node-Redインストール

```
　　bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
```

## ３．Node-Red起動方法

◆　Node-Red起動

```
　　node-red-start
```

<br>
◆　スタートアップ登録

```
　　sudo systemctl enable nodered.service
```

<br>
◆　複数起動したい場合

　　一時的に環境を増やしたい場合は以下のようにコマンドを実行する。

　　node-red -p [ポート名] -u [保存ディレクトリ]

```
　　node-red -p 1881 -u ~/2ndUser
```
【Rails小技】HerokuでSSL化強制させる方法【瞬速】

今日は友人にherokuに上げたサイトを見てもらいました。

わし「これ作ったんだよ〜！見てよ！」

友人「ちゃんと機能作れてるやん〜。あれ、でもSNS認証がsomethinbg went wrongになってるよ」

わし「( ᵕ̩̩ㅅᵕ̩̩ )」
<br>

再度確認してみると、Google認証はエラーメッセージを吐いてくれてました。
<br>


google「400: redirect_uri_mismatch　あーだこーだあーだこーだ」
<br>


わし「あれ〜なんか認証URLが間違ってるっぽいぞ。でもちゃんと認証URLもあってるような気が…( ᵕ̩̩ㅅᵕ̩̩ )」
デベロッパーサイトでOAuthのコールバックURLを確認し、APIキーも再入力したし、なんで…

と思っていたら、URLのところに「保護されていない通信」の文字が…あれ、herokuって基本SSL化されてるはずでは…
よく見るとURLが「http://」から始まっていました。結局僕のタイポでした。
これを「https://」に打ち直したらSNS認証は上手くいきました。めでたしめでたし…

##いい機会なのでSSL化強制しよう

ただのタイポで解決できてよかったですが、どんな時もSSL化できていないと危険です。
仮にhttpでアクセスされてもいいように、httpsへ強制的にリダイレクトさせたいです。

Railsでは以下の一行をコメントアウトすることでSSL化強制することができます。

```rb:config/environments/production.rb
Rails.application.configure do

  ・・・

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  config.force_ssl = true

  ・・・

end

```

鬼のように便利ですね〜

##独自ドメインだともうちょっと手間がかかりそう

今回はrails + herokuapp.comの場合の手段ですが、独自ドメインを取得した場合はもっと大変そう。
.htaccessとか色々勉強しなければなりませんね…という新たな課題も見つかりました。
フレームワークもいいけど、そもそもネットワークの知識が必要だなぁ〜って思いました。

おわり
ソフトウェアデザインの哲学について

高尚なタイトルだけれど、なんのことはない「アジャイル」と「DevOps」についてのまとめ。

どちらの概念もたくさんの方法論やツールがつきまとって、結局それらが何なのかがとても見えにくい気がする。根本となる哲学や世界観を理解すれば、どうして奴らがこうした方法論を重視するのかが少しは理解しやすくなるかもしれない。

# アジャイルの世界観と哲学

アジャイル開発なる概念に通底するのは「**予測不能性**」という世界観だと思う：

> 「本当に」どのような価値が必要とされているのかは、実際にものが動くまで（もしかすると動いた後も）誰にもわからない。

上の原理は、「顧客本人が言っていることをそのまま実装しても、顧客がほんとうに欲しかったものは手に入らない」というよくある出来事が反映されている。

その上でアジャイル開発では（他の開発手法もそうだけれど）、「**たとえ不確かであっても、顧客にとって重要な価値を発見し、提供する**」という使命を至上命題として掲げる。

予測不能な現実のなかでこの至上命題を実現するには、どうしたらよいのか？そのための方法論として提起されているのが、いわゆる数々の「アジャイル手法」であるといえる。これらの手法の背後にあるアプローチは、基本的には

- 顧客と開発チームとのやりとりを密にする
- 顧客の要望に応じて柔軟にソリューションを変えていく

ということだろう。頻繁に「そこそこ動くソリューション」を顧客に見せて、その都度得たフィードバックをベースにして方向性を修正していくことで、開発しているものが「顧客がほんとうに欲しいもの」に近づいていく（はず）、というのがアジャイル開発の基礎になっていると思う。

# DevOpsの哲学

DevOpsはアジャイル開発の考え方と近いようにも思えるけれど、おそらくその世界観の根本には「**流動性**」があると思う：

> この世界は日々変化しており、昨日正解に思えた戦略が今日は間違いになっている可能性がある。

この種の要求によくある例としては、サービスが大規模化しても性能がスケールするようにしてほしいとか、（多少違うかもしれないけれど）バグがあったときにすぐパッチを当てられるようにしてほしいとか、そういうものが挙げられると思う。

その中でDevOps的な価値観では、「**外部環境とのミスマッチ・誤差を迅速に検出して、機敏に対応する**」ということを根本命題として掲げる。

この命題を実現するための方法論が、いわゆる「DevOps的」な手法であるといえる。基本的には、

- 運用・モニタリング手法を含めた設計
- ビルド・デプロイの自動化

というアプローチがとられるだろう。問題の検出や性能のモニタリングをするための（運用）手法を含めてソリューションを設計することで、問題の検知が速やかに開発チームの稼働につながるようにする。そして自動化を通じて、問題検知からソリューション更新までの時間をできるだけ短くする、という戦略が「DevOps的」なのだと思う。

# おわりに

それだけ。基本的にはWikipediaにも書いてあるような内容だけれど、読むたびにわけわからなくなるので書いた。

個人的には、ほんとうに難しいのは実際には「誰がこのソリューションの利害関係者（ステークホルダ）なのか？」「利害関係者はどのような感想や要望を持っているのか？」といった点を明らかにする方法なのではないかと思うけれど、それはまあ「次のステップ」ということになるのだろうか…。
基本情報処理技術者試験

基本情報処理技術者試験の「情報セキュリティ」「データベース」「プロジェクトマネジメント」を解いた。

先日、「解いたことのないセクションを一度解いておこう」と決めたので実行した。

解いた問題は「令和元年度　基本情報処理技術者試験　午後　問題」から抜粋した。

「情報セキュリティ」
---
これは問１の必須問題で、これは得意分野だった。

テレワークを題材にしたネットワーク構築の問題で、IP アドレスの取りうる範囲でアクセスの許可・拒否を振り分ける問題だった。４／４ (正解 ／ 問題数) ：100% だった。

これは何度か解いてる問題だったので、しっかり理解しながら取り組んだ。まずは日本語の文章をしっかり読んで、そこに合わせてIPアドレスの割り振り、フィルタリングの許可・拒否を決めていけば問題なく解けた。

「データベース」
---
この問題は、前半の２，３問は特に予備知識が無くとも解ける問題だった。やはり日本語をよく読んでから適切なSQL虫食い部分に選択肢を当てはめれば良いものだった。
ただ後半は、解けないことはないが実際にSQLを触った経験があったほうがスムーズに解けるように感じた。実務に役立つかどうかはわからないが、文法をペーパーで覚えるのも、回答する分には有効だと思う。２ ／ ５ (正解 ／ 問題数)：40% だった。

「プロジェクトマネジメント」
---
これまた同じで、文章を読んで与えられた値を使って計算すれば、前半は難なく解ける。後半はちょっと混乱するが、表の読み方や用語をしっかり頭に落とし込めば解いていけるように思う。
axiosのレスポンスにおける日付をDateに自動的に変換する

OpenAPI Generator の `typescript-axios` で吐き出した apiClient がDate型としてアノテーションしてるのに、実際はstringで返ってきて、型の辻褄あわせするためにやった。
但し、空文字の時など考えるとちょっと怪しいので注意。
また、文字列として明示的にISO8601っぽいカラムを入れた場合にも勝手にDateになっちゃうので、その場合にも問題が起きる可能性あり。
そういうケースでは、リクエスト毎にtransformResponseを渡して、その歳にdateとしてパースするカラム名を明示的に渡す、などする事で解決できる可能性が高い。

```typescript
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function dateParseChallenge(key: string, val: any) {
  if (typeof val === "string") {
    const time = Date.parse(val);
    if (!Number.isNaN(time)) {
      return new Date(time);
    }
  }
  return val;
}

const axiosClient = axios.create({
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  transformResponse: (data: any) => {
    if (typeof data === "string") {
      try {
        return JSON.parse(data, dateParseChallenge);
      } catch (e) {
        // Ignore error
      }
    }
    return data;
  }
});
```

参考: https://github.com/axios/axios/blob/16b5718954d88fbefe17f0b91101d742b63209c7/lib/defaults.js#L57
Numpy退場？！Sympyで行列を偏微分

##更新履歴
2020.4.28.加筆：スカラー関数をベクトルで微分

##はじめに
こんばんは，老技術者です。
私の時代はまだまだ終わりませんよ。
でも，行列演算といったらNumpyでしょという時代は終わったようです。
その名もSympy（まさか新pyじゃないと思う）！

##Sympyで行列を偏微分とかいろいろ
とりあえずこんなことできる。


```Python:
#%%
import sympy as sym
from IPython.display import Math, display

# 変数を定義
(x, y, p, q) = sym.symbols("x y p q")
# 行列を定義
A = sym.Matrix([
    [x,2*x,3*x],
    [4*x,5*x,6*x]
])
display((Math(f"A={sym.latex(A)}")))
B = sym.Matrix([
    [y,y],
    [4*y,5*y],
    [7*y,y]
])
display((Math(f"B={sym.latex(B)}")))
# ベクトル関数を定義
xy = sym.Matrix([
    [x,y]
])
display((Math(f"xy={sym.latex(xy)}")))
pq = sym.Matrix([
    [3*x*y,2*x+y]
])
display((Math(f"pq={sym.latex(pq)}")))
# スカラー関数を定義
f = x**2

#行列同士の掛け算
C = A * B
display((Math(f"C=AB={sym.latex(C)}")))

#行列のx,yに数値を代入
C1 = C.subs({x:10, y: 20})
display((Math(f"C(10,20)={sym.latex(C1)}")))

#行列をxで偏微分
dCdx = sym.diff(C, x)
display((Math(r"\frac{\partial C}{\partial x}"f"={sym.latex(dCdx)}")))
#行列をyで偏微分
dCdy = sym.diff(C, y)
display((Math(r"\frac{\partial C}{\partial y}"f"={sym.latex(dCdy)}")))

#スカラー関数をベクトルで微分
dfdxy = sym.diff(f, xy)
display((Math(r"\frac{df}{dxy}"f"={sym.latex(dfdxy)}")))
#ベクトル関数をベクトルで微分
dpqdxy = sym.diff(pq, xy.T)
display((Math(r"\frac{dpq}{dxy}"f"={sym.latex(dpqdxy)}")))
#スカラー関数を行列で微分(エラーが出ます)
# dfdA = sym.diff(f, A)
# display((Math(r"\frac{df}{dA}"f"={sym.latex(dfdA)}")))

```

Visual Studio Codeで1行目の#%%からコピペなり写経なりしてみてほしい。
1行目の#%%はVS CodeがJupyter notebookに変わるおまじないだ。
普通に実行なんてやっちゃだめですよ。
下図にあるRun Cellってのをつついてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/fc06dc51-1107-bc4d-909f-63954af84166.png)

すると，こんなのが出てくるんですよ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/762775bc-f7d7-7762-0944-d9637eb3c18c.png)


行列の要素は数字でももちろん良いのですが，上の例のように文字でも良いし
演算も文字込みでやってくれる。
さらにこの文字（変数）に数値を代入できるし，数式を入れる田中さんのような
変態もいる…
ベクトルで微分も可能なので，バックプロパゲーションの連鎖律を教えるときに
使えそう。
ということで昼飯食ってきます。
Wordpressでpre_get_postsで記事を取得する際ACFの繰り返しフィールド内のデータを条件に加える方法

例えば繰り返しフィールド（event）で、開催日（start)、終了日（finish）をカスタムフィールドで設定して
現在日付がそれらの間だった時の記事を取得させる場合

```query.php
function change_posts_per_page($query) {
	//管理画面のメインクエリーとメインクエリーじゃないときは処理しない
	if (is_admin() || !$query->is_main_query()) return;

	// 特定のクエリにて処理
	if ($query->is_category() || $query->is_tag() || $query->is_search()) {
		// 20件取得
		$query->set('posts_per_page', 20);
		// 本日日付取得
		$today = date_i18n('Ymd');
		// SQLを変更させるフラグとして設置
		$query->set('wildcard_meta_key',true);
		$query->set(
			'meta_query', array(
				array(
					'key' => 'event_%_start',
					'value'   => $today,
					'compare' => '<='
				),
				array(
					'key' => 'event_%_finish',
					'value'   => $today,
					'compare' => '>='
				),
				'relation'=>'AND'
			)
		);
		
	}
	

}
add_action( 'pre_get_posts', 'change_posts_per_page' );

// リピータ部分のワイルドカード対応
function my_posts_where_wildcard( $where, $query ) {
	if ( $query->get( 'wildcard_meta_key' ) ) {
		$where = str_replace( 'meta_key =', 'meta_key LIKE', $where );
	}
	return $where;
}
add_filter( 'posts_where', 'my_posts_where_wildcard', 10, 2 );
```

とfunctions.php系に記載する。
wildcard_meta_keyを設定しているのは複数meta_query系処理を追加させた場合に、
繰り返しフィールドを対象としないものを除外させるため。
[WordPress] Sentry で開始する WordPress エラー監視

![banner-772x250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/e6e16b89-757f-073c-d4e2-fcf2edd8bf82.png)

WordPress への [Sentry](https://sentry.io/welcome/) の導入がすごく簡単でした。
用意されてる[プラグイン](https://wordpress.org/plugins/wp-sentry-integration/)をインストールして有効化するだけ。

# Sentry

まず[サインアップ](https://sentry.io/signup/)しましょう。
GitHub アカウントや Google アカウントでのサインアップもできます。

サインアップしたらプロジェクト作りましょう。
プラットホームは PHP と JavaScipt で

# WordPress への導入

プラグインの新規追加から「wp-sentry-integration」を検索してインストールし有効化
<img width="636" alt="スクリーンショット 2020-04-23 20.33.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/d95357a6-6a42-c15e-8fbf-57ff2e04b4c4.png">

プラグイン有効化したら wp-config.php に以下を追加します。

```
define('WP_SENTRY_DSN', 'https://xxxx@o000000.ingest.sentry.io/0000000');
define('WP_SENTRY_PUBLIC_DSN', 'https://xxxx@o000000.ingest.sentry.io/0000000');
```

`WP_SENTRY_DSN` と `WP_SENTRY_PUBLIC_DSN` に設定すべき値は、Sentry のダッシュボードでプロジェクトの「Settings」 - 「Client Keys (DSN)」から取得できます。
PHPプロジェクトのキーを `WP_SENTRY_DSN` に、JavaScriptプロジェクトのキーを `WP_SENTRY_PUBLIC_DSN` にセットします。

設定終わったら WordPress 管理画面の「ツール」-「WP Sentry Test」からエラーメッセージの送信テストができます。
<img width="871" alt="スクリーンショット 2020-04-23 20.41.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/15430f8f-3139-68bc-5c9f-e8503cb68475.png">

Sentry のダッシュボード見るとエラー発生したことが記録されてるよ、やったー
<img width="1434" alt="スクリーンショット 2020-04-23 20.42.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25964/cb861cfa-dcb4-09c4-f921-1b1e6acc7aa0.png">

Sentry のダッシュボードで、Slack連携とか設定できるので安心ですね。
【ajax】jquery-ui-rails,ajaxでオートコンプリート機能を実装


#オートコンプリートについて
**オート（自動）コンプリート（完全）**
検索バー等でよくある入力の自動補完です。
ajaxで非同期通信を行い、入力の1文字目をサーバーに送信し、予測される選択肢がテキストボックスの下に表示されるよう実装していく。

#jQueryの導入
>gem 'jquery-rails'
gem 'jquery-ui-rails'

gemfileに追加し、bundle install


```js:application.js
//= require jquery
//= require rails-ujs
//= require jquery-ui
//= require_self
//= require_tree .
```
```css:application.css
  *= require jquery-ui
```
それぞれ追加する。
このrequireの部分は、書く上下の順番によってもうまく読み込まれるかが変わってくるので、色々と試した。
#HTMLのinputタグにidを設定
```erb:_header.html.erb
<span class="input-group">
  <input type="text" name="search" class="form-control" id="form" placeholder="Search…" >
  
  <span onclick="FormSubmit();" class="input-group-search">検索</span>
</span>
```
**id="form"**を設定

#JavaScript
```js:suggest.js
$("#form").autocomplete ({//①
  source: function (req, resp) {
    $.ajax({//ここから下がajaxの処理
      url: '/suggest',
      type: 'GET',
      dataType: "json",
      data: { keyword: req.term },//②
      success: function(o){
        resp(o);
      },
      error: function(xhr, ts, err){//③
      resp(['']);
      }
    });
  }
});


$('.dropdown').change(function () {//④
  $(this).addClass('open');
});
```
①　id名formが設定された箇所にautocompleteを実装していく
②　req.termとすることで、入力値をサーバーに送る事ができる。
③　ajaxのリクエスト失敗時には、そのエラーに関する情報を3つの引数で受け取る。その内容を取得する方法は、こちらの記事で確認する事ができた。[【jQuery】Ajaxのエラーレスポンスをパースする方法](https://remotestance.com/blog/2687/)
④dropdownクラスの要素内に変更があった場合に、openクラスを追加する事で、選択肢をクリックした後もフォームが消えないようにする事ができた。

```js:custom.js
jQuery(document).ready(function () {
  $('.dropdown,.ui-autocomplete').hover(//⑤
    function () {
      $(this).addClass('open');
    },
    function () {
      if (!$(this).hasClass('not-remove')){//⑥
        $(this).removeClass('open');
      };
    });
});

```
⑤jQueryのhoverメソッド： 対象要素.hover( 関数１, 関数２ ) という書き方をする。
参考:[jQueryのhover()を活用したマウス操作まとめ！](https://www.sejuku.net/blog/40005)
⑥検索バーの、ドロップダウンを設定している要素に、not-removeクラスがついていない場合（ifの否定文）のみ実行する事で、検索バーから選択肢へマウスカーソルを移動させて選択できるようにした。

#ルーティング
```rb:route.rb
get 'suggest',   to: 'suggests#search'
```

#コントローラー
```rb:suggests_controller.rb
class SuggestsController < ApplicationController
  SUGGEST_MAX_COUNT = 5
  def search
    api_suggest = ApiSuggest.new
    @suggests = api_suggest.suggest(params[:keyword], SUGGEST_MAX_COUNT)
    respond_to do |format|
      format.json { render suggest_path, json: @suggests }
    end
  end
end

```





サーバー側の実装については、今後gemのGrapeを導入し、API等を作成していく中で更に詳しく記録していく予定です、、

#終わりに
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございます。
FlutterでSingleton(シングルトン)が複数作られてしまった話

## 発生した問題

Flutterで以下のようなシングルトンのクラスを作って、複数のファイルで呼び出そうとしたら、`user` インスタンスがなぜか2つ作られてしまいました。
(printの中身が2回呼び出された)

```user.dart

class User {
  static User _userInstance;
  final String uid;

  factory User(String uid) {
    if (_userInstance == null) {
      print("userインスタンスを生成します");
      _userInstance = new User._internal(uid);
    }
    return _userInstance;
  }

  User._internal(this.uid);
}
```

## 環境

- macOS Catalina 10.15.1
- Android Studio 3.6.1
- Flutter 1.17.0


## 結論

2個目の `user` インスタンスが生成されている場所の `import` するときのファイル名が大文字になっていました。これを `user.dart` に修正することで解決しました。

```small.dart
// 本来はこっちが正しい
import "package:sample/user.dart";
```

```large.dart
// 何故か大文字になっている
import "package:sample/User.dart";
```

## 補足

packageの呼び出しの問題かなと思い、 `import` している箇所を見てみましたが、 `packeage:...` の書き方で統一していたので特に分からずでした。

その時にこちらの記事を見つけて、やはり `import` にtypoがあるのではないかとあたりをつけたら、 `User.dart` が大文字になっているのを発見したというしだいです。
https://qiita.com/kainos/items/da51695f2fc11005167b

アプリ開発に限らず、大文字小文字はハマりどころではありますが、別の言語でアプリ開発をしている時には、パスカルケースで開発をしていたので、地味にハマってしまいました。
(Flutterの時にはちゃんとスネークケースを使っています)

Android Studio でも特に警告は出なかったので、いい知見を知っている人がいたらぜひご教授ください！m(_ _)m
ChemTHEATREでPython学習

![ChemTHEATRE_YOKO_color.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261241/71f38b4f-462e-115c-95de-5fef560d261d.jpeg)

#ChemTHEATREとは

[ChemTHEATRE (chem-theatre.com)](https://chem-theatre.com)とは，生物・非生物を問わない環境媒体中の化学物質濃度を，環境媒体に関するメタデータとともに収録したデータベースです。データソースは学術論文をはじめ，国や公的機関による調査結果も含みます。
詳細は[ChemTHEATREのウィキサイト](https://chem-theatre.com/pukiwiki/index.php?FrontPage)まで。

#Pythonでモニタリングデータの解析＆可視化をやってみる

ChemTHEATREに登録された実際のモニタリングデータを使ったデータ解析や可視化について，初心者向けに説明しています。

| 章 | 内容 | 掲載年月日 |
| ---- | ---- | ---- |
| [Part1](https://qiita.com/kein613/items/9583c76f010aab9f356d) | 基本統計量，箱ひげ図 | 2020/04/13 |
| [Part2](https://qiita.com/kein613/items/8496b057b6536db6c3ba) | 点推定，区間推定，信頼区間，推定結果の可視化 | 2020/04/23 |
| [Part3](https://qiita.com/kein613/items/16c518e6e78cb1b9321c) | 主成分分析 | 2020/04/24 |
| Part4 | 自己相関，時系列予測 |  |
| [Part5-1](https://qiita.com/kein613/items/24160b820d1e6e714c46) | データの地図上へのプロット | 2020/05/11 |
| Part5-2 | データの地図上へのプロット |  |
| Part6 | 仮説検定，2標本t検定，無相関検定 |  |
| [番外](https://qiita.com/kein613/items/3f00958f3491c9248fff) | 有機フッ素化合物のデータをQGISで地図上にプロットする | 2020/06/19 |

テキストは順次アップしていきます。

#ChemTHEATREからのデータのエクスポート

上記のデータ解析をするにあたり，ChemTHEATREで必要なデータを検索し，テキストファイルとしてエクスポートします。

![sample_search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261241/9d5aad63-9d0e-0435-36e9-bb26ca18842a.png)

1. [ChemTHEATRE](https://chem-theatre.com)のメニューバーから「Sample Search」を選択する。
2. 試料に関する情報（生物・非生物，化学物質，採取地点，採取年月日，フリーワード）で絞り込む。
3. 「Search」ボタンをクリックすると，条件に合致する試料の一覧が出力される。
4. 「Export samples」で試料の情報が，「Export measured data」で目的の化学物質の測定値が，タブ区切りのテキストファイルとして出力する。

エクスポートしたファイルを任意のディレクトリに保存して，解析に使用してください。
セキュリティーを犯す攻撃パターンとphpでの対策

#攻撃手法
###①XSS
目的のサイトに対して、直接情報を送って、攻撃(サイトに表示、データを攻撃側に送信)。ユーザからのデータを表示されるサイトが対象

対策
入力フィルタ、出力エスケープ

入力面
array_key_exist()で第二引数のキーに第一引数に相当するものがあるか調べる。つまり入力された値をそのまま許可しないようにするためのもの。

出力面
formなどで入力された値をHTMLに出力される前にエスケープする。そのようにすることで、HTMLに出力された時に中身がHTMLタグとして読み込まれないようにするためである。HTML上に出てしまうphpの変数にはエスケープして表示させたないといけない。


###②CSRF
ユーザーが意図せず、自分のサーバ側を攻撃してしまう。cookiesにログイン情報が残っている状態の時、本来のアプリと別の場所で悪意のあるリンクを押した時に、そのリンクからアプリのDBアクセスをして変更をしようとする事。

対策
sessionを利用する。sessionはURLをまたいでファイルが変わっても、値が残るような配列。

アプリのページが立ち上がれば、トークンを作成し、SESSIONの中に格納する
↓
それを以下のようにHTMLのformに隠して挟み込む

```php

<input type="hidden" id="token" name="token" value"<?= h($_SESSION['token']);?>">
#h（）はエスケープ
```
↓
サーバ側で、送られてきた$_SESSION['token']と、作成したtokenが同じ値になるかどうかを調べる。
同じならば全ての送られてきた値が、正常の送信と判断する。

###③SQLインジェクション
クエリが記述されるページに対して、データを送って不正なクエリを作成させること

対策
PDOオブジェクトでクエリをセットする時に、段階を分けることで可能にする。

:で仮の変数を使ってクエリを作成する
⬇️
prepareでクエリをPDOオブジェクトにセットする。これによって作られるのはPDOステートメントクラス。
⬇️
PDOステートメントインスタンスにbindValueやbindParamで仮の変数に値を入れて、クエリを正常な形にする
⬇️
PDOステートメントインスタンスにexecuteで実行


###④セッションハイジャック
ユーザーのsession_idを盗み、それを使用してアクセスする。
[基礎編] Docker でイメージ作成からビルド、実行まで


# 議題
> 以下はdockerのイメージを自分で作成する方法です

# 前提
> Docker初心者向けドキュメントです

## インストールまだの人はこちらから
[https://qiita.com/RIKIgigasu/items/c5ea6941768411c67531](https://qiita.com/RIKIgigasu/items/c5ea6941768411c67531)

> 特にWin10 home の方は、docker for Windows は落とせません。docker toolbox を落として環境整備になります。HyperVの仮想が使えないのでもともとoracle 仮想ソフトを入れていた方は、oracle仮想ソフトの入れ替え必要 ⇒これしないとdocker とのバージョンが合わなくホストとのマウントできませんので注意。


# 実践
```shell                                                             
$nano Dockerfile  
```
> Dockerfile 作成のエディタが開かれる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/d55750a4-6c17-a2e8-a4b1-b42be58d0f90.png)

```shell
FROM alpine
CMD ["echo","hello"]
```

> 保存してビルドします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/42ef97d7-446e-32d4-324c-fbb02afaab53.png)

> 実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/f1479516-56a5-761c-e278-94e081c14bac.png)

> docker run のあとのシリアルぽいネームがイメージID
> 覚えられないと思うのでこのイメージIDをリネームができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/861b2f37-7f5c-d7c1-e743-d018099f09ef.png)

> リネーム前の実行結果と同じであることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/7a118b0b-dd05-8923-bdd3-80a5e35c9212.png)

# まとめ
・Docker は処理が終わったらコンテナはすぐ終わる
・仮にコンテナを継続させたい場合は「-t」をつけて実行
知っておくと便利な論理プロパティ、ボックスモデルのこれからの方法


CSSの論理プロパティにおける考え方CSSのボックスモデルについて説明する時、下記のような図がよく使用されている。
<img width="395" alt="711ad00a1d94df7f330109c4c8f516d5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/74fb6483-7dda-cab6-efa9-a11b82af6e4b.png">

確かにこの図は当時の正しいもので、もちろん今でもそうだが、margin-left、padding-right、border-topのような物理プロパティは最後の日が来るかもしれない。
新しい論理プロパティを使い始めるには、left/rightやtop/bottomについて考えるのをやめて、それらをinline-start,inline-end, block-start、block-endに置き換える必要がある。
![2019010502-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/e587b663-e50d-a946-733e-10978632bf07.png)


インライン軸

英語を例にする。読む方向は左から始まり、右側で終わる。これはプロパティのインライン要素。「display: inline;」で配置された要素を考えた時、想像するのはとても簡単。各アイテムは行に沿って表示される。

例：padding-inline-startだと、言語が始まる側のpaddingになる。

・英語の場合
  padding-inline-startは、padding-leftと同じ
・アラビア語の場合
  padding-inline-startは、padding-rightと同じ
・日本語の場合
  padding-inline-startは、padding-topと同じ


ブロック軸

topとbottomのプロパティだと、topがwebサイトの始まり、bottomが終わり。覚えておくのは非常に簡単。「display: block;」の要素が複数上から順に積み重なっていると想像してみる。


新しいボックスモデルのプロパティ

インラインとブロック軸をある程度理解したところで、新しいボックスモデルのプロパティを確認しておく。

英語の場合、プロパティは下記のようになる。

margin
  ・margin-block-start = margin-top
  ・margin-block-end = margin-bottom
  ・margin-inline-start = margin-left
  ・margin-inline-end = margin-right
padding
  ・padding-block-start = padding-top
  ・padding-block-end = padding-bottom
  ・padding-inline-start = padding-left
  ・padding-inline-end = padding-right
border
  ・border-block-start = border-top
  ・border-block-end = border-bottom
  ・border-inline-start = border-left
  ・border-inline-end = border-right



論理ディメンション

widthとheightのプロパティもこの新しい方法に合わせて対応する必要がある。インラインとプロパティ軸を理解したら、ディメンションを理解するのも簡単。英語では、widthプロパティはinline-sizeに、heightプロパティはblock-sizeに置き換える。


日本語のように上から下の言語の場合、逆になる。
　・widthは、block-sizeに
　・heightは、inline-sizeに
min/maxは、プロパティの開始時にmin/maxを追加するだけ。
　・min-inline-size: 300px; max-block-size: 100px;![2019010502-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/12397339-f116-01ce-46b9-3f98c4132225.png)


参考元：https://coliss.com/articles/build-websites/operation/css/new-css-logical-properties.html
margin-blockについて

margin-blockはCSSのプロパティで、論理的なブロックの先頭と末尾のマージンを設定する。これは要素の書字方向やテキストの向きに応じて。物理的なマージンに変換される。


/* <length> 値 */
margin-block:  30px 30px; /* 絶対的な長さ */
margin-block: 2em 2em; /* 直近のブロックコンテナーの大きさに対する相対値 */
margin-block: 20px; /*先頭と末尾の両方を設定 */

/* キーワード値 */
margin-block: auto;

/* グローバル値 */
margin-block: inherit;
margin-block: initial;
margin-block: unset;


これらの値は、margin-topとmargin-bottom,またはmargin-rightとmargin-leftプロパティに、writing-mode,direction,text-orientationで定義された値にしたがって対応する。


値は、margin-block-startとmargin-block-endで個別に設定することができる。インライン方向のプロパティはmargin-inlineで、margin-inline-startとmargin-inline-endを設定する。


構文

値：margin-blockプロパティは、margin-leftプロパティと同じ値をとる。

形式文法：<'margin-left'>{1,2}



例

HTML
<div>
  <p class="exampleText">Example text</p>
</div>


CSS

div {
  background-color: yellow;
  width: 120px;
  height: 120px;
}

.exampleText {
  writing-mode: vertical-rl;
  margin-block: 20px 40px;
  background-color: #c8c800;
}


参考元：https://developer.mozilla.org/ja/docs/Web/CSS/margin-block
Ubuntu Kazamで作った動画をiPadで使う

## そのままではつかえない
iPadでは`mp4`をサポートしていると読んだので、Linuxで作った動画をiPadに移せば普通に使えるだろうと思っていたら、
iMovieには影も形も出てこない。ファイルアプリで見てみると、ファイルは認識されるもののプレビュー不可。
他の動画編集ソフトでももちろん使えなかった。。

## VLCで変換するとOK
`mp4`の音声部分を`AAC`にすればOKで、VLCでそれができるというブログを見たので、やってみるとうまく行った。

## ffmpegでできないか
VLCはGUIの奥深くまでいかないと変換できず、動画ごとにやるのはきついので、ffmpegで出来ないか試してみた

```bash
$ ffmpeg -i src.mp4 -vcodec libx264 -acodec aac out.mp4
```
が、ダメだった。。

## うまくいくファイルと、うまくいかないファイルを比較
何がおかしいのか調べるために、ffmpegで動画ファイルの属性を出力して比較してみた。

### Audio
Audioは、うまく行かない方は`mp3`で、うまく行く方は`AAC`になっている。問題なさそう。。

```bash
# うまくいくファイル
$ ffmpeg -i working.mp4 2>&1|grep Audio:
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 21 kb/s (default)

# うまくいかないファイル
$ ffmpeg -i not-working.mp4 2>&1|grep Audio:
    Stream #0:1(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, mono, s16p, 40 kb/s (default)
```

### Video
Videoの方では大きな違いが見付かった。うまく行く方は`yuv420p`、うまく行かない方は`yuv444v`になっている！

```bash
# うまく行くファイル
$ ffmpeg -i working.mp4 2>&1|grep Video:
    Stream #0:1(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1898x1400 [SAR 1:1 DAR 949:700], 284 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)

# うまくいかないファイル
$ ffmpeg -i not-working.mp4 2>&1|grep Video:
    Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p(tv, bt709), 1898x1400 [SAR 1:1 DAR 949:700], 599 kb/s, 30 fps, 30 tbr, 3k tbn, 60 tbc (default)
```

## 動いた！
ググると、`-pix_fmt yuv420p`で`yuv420p`を指定できるようなので、そのオプションを追加したところ動いた。

```bash
$ ffmpeg -i src.mp4 -vcodec libx264 -pix_fmt yuv420p -acodec aac out.mp4
```
#Ruby Json parse + object_class ( NameError: no member 'xxx' in  ) ( e.g Struct )

- JSON paras するときの object_class の指定だと、 Struct に定義していないキーが JSON に含まれる場合に、エラーを起こしてしまうようだ ( initialize するときに余計なキーが指定されるわけだから、当たり前か )
- object_class の指定に任せず、Struct を直接利用すれば、頑張って必要なキーだけで Struct を組み立てる事はできる
- 他になにか良い指定ないんだろうか

```rb
require "JSON"

# OK
User = Struct.new("User", :id, :name, :email)

json_string = { id: 1, name: "Alice", email: "aaa@example.com"}.to_json

user = JSON.parse(json_string, object_class: User)
# => #<struct Struct::User id=1, name="Alice", email="aaa@example.com">


# NG
# undefined Struct key in JSON
User = Struct.new("User", :id, :name, :email)

json_string = { id: 1, name: "Alice", email: "aaa@example.com", undefined_key: "xxx"}.to_json

user = JSON.parse(json_string, object_class: User)
# NameError: no member 'undefined_key' in struct

# OK
# generate struct by yourself
User = Struct.new("User", :id, :name, :email)

json_string = { id: 1, name: "Alice", email: "aaa@example.com", undefined_key: "xxx"}.to_json

user_attributes = JSON.parse(json_string)
# => {"id"=>1, "name"=>"Alice", "email"=>"aaa@example.com", "undefined_key"=>"xxx"}

User.new(user_attributes["id"], user_attributes["name"], user_attributes["email"])
# => #<struct Struct::User id="xxx", name="zzz", email="aaa">

```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3086











<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Python】MeCabで形態素解析

NLPに使うデータの前処理に形態素解析を使うことがあるのでまとめる。

# MeCabとは？
オープンソースの日本語の形態素解析エンジンです。

>現GoogleソフトウェアエンジニアでGoogle 日本語入力開発者の一人である工藤拓によって開発されている。名称は開発者の好物「和布蕪」から取られた。

[Wikipediaより引用](https://ja.wikipedia.org/wiki/MeCab)

# 環境
- macOS Catalina
- Python 3.7.2
- pip 19.1.1
- Homebrewをインストール済み

# インストール
MeCab本体をインストールする。

```bash
$ brew install mecab
```

MeCabの辞書をインストールする。

```bash
$ brew install mecab-ipadic
```

MeCabがインストールされたか確認する。

```bash
$ mecab --version
mecab of 0.996
```

試しに形態素解析をしてみる。

```bash
$ mecab
試しに形態素解析をしてみる。
試し	名詞,一般,*,*,*,*,試し,タメシ,タメシ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
形態素	名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析	名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し	動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
て	助詞,接続助詞,*,*,*,*,て,テ,テ
みる	動詞,非自立,*,*,一段,基本形,みる,ミル,ミル
。	記号,句点,*,*,*,*,。,。,。
EOS
```

**形態素解析**という単語が**形態素**と**解析**に分解されてしまっている。
これを解決するために、最新の辞書である**mecab-ipadic-NEologd**をインストールする。
まずは辞書データをGitHubからCloneする。

```bash
$ git clone --depth 1 git@github.com:neologd/mecab-ipadic-neologd.git
```

Cloneしたリポジトリに移動してinstallを実行し、確認画面でyesを選択する。

```bash
$ cd mecab-ipadic-neologd
$ ./bin/install-mecab-ipadic-neologd -n
yes
```

-dオプションで辞書を指定して再び、試しに形態素解析をしてみる。

```bash
$ mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/
試しに形態素解析をしてみる。
試しに	副詞,一般,*,*,*,*,試しに,タメシニ,タメシニ
形態素解析	名詞,固有名詞,一般,*,*,*,形態素解析,ケイタイソカイセキ,ケイタイソカイセキ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し	動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
て	助詞,接続助詞,*,*,*,*,て,テ,テ
みる	動詞,非自立,*,*,一段,基本形,みる,ミル,ミル
。	記号,句点,*,*,*,*,。,。,。
EOS
```

無事、**形態素解析**という１単語になりました。

# Pythonで使う

python用のライブラリをインストールする。

```bash
pip3 install mecab-python3
```

あとはコードを書いて動かしてみる。

```python
import MeCab

mecab = MeCab.Tagger ('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
print(mecab.parse('試しに形態素解析をしてみる。'))


試しに	副詞,一般,*,*,*,*,試しに,タメシニ,タメシニ
形態素解析	名詞,固有名詞,一般,*,*,*,形態素解析,ケイタイソカイセキ,ケイタイソカイセキ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し	動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
て	助詞,接続助詞,*,*,*,*,て,テ,テ
みる	動詞,非自立,*,*,一段,基本形,みる,ミル,ミル
。	記号,句点,*,*,*,*,。,。,。
EOS
```
Bootstrapの導入時にGoogle Mapが表示されない

## 事象
Google Mapを導入、正しく動く事を確認後、見た目を修正する為にBootstrapを導入し
見た目を整え終えたところ、Google Mapが表示されない問題を発見しました。

* ローカル・本番環境共に表示されなくなった
* 急に表示されなくなったのでGoogle Map API周りが問題だと2週間程原因究明に当たりましたが原因不明....
* Google Mapが正しく表示されていたbranchからcloneして確認すると正しく表示されたのでAPI周りではないと判断
* 原因はBootstrap周りだと特定し原因調査

## 環境
Ruby 2.6.3
Rails 5.2.3

## 表示されないソース
Map表示部

```
<div class="map_area">
  <div id="map"></div>
</div>
```

CSS

```
body {
  min-height: 100%;
}

.map_area{
  height: 400px;
}

#map{
  height: 90%;
  margin-left:auto;
  margin-right:auto;
  text-align:left;
  width: 50%;
}
```

## 参考記事
[Bootstrap3(Honoka) + Google Map APIでMapが正常に表示されない問題について](http://shopetan.hatenablog.com/entry/2015/07/04/000744)
[Bootstrap + Google Mapsで画像が表示されない不具合](https://techracho.bpsinc.jp/morimorihoge/2012_12_17/6446)

## 解決したソース

CSS

```
// 追加したコードのみ記載

html {
  height: 100%;
}
```

<img width="1031" alt="スクリーンショット 2020-04-23 19.29.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625796/1610e306-8cf1-738c-272e-69c79fc95c33.png">

表示された！！！
## 原因
>親要素にheightの大きさに関する記述が明示されていないのが問題なのだと思います

と先ほどの記事に書いていましたが`body{min-heigth: 100%}`で指定しているのに何故だろう....
そして表示されなかった当時の状態にコードを戻しても再発しませんでした......

一応解決しましたが、個人的にモヤモヤが残る結果になってしまいました。
まだまだ理解が浅い未熟者ですが、誰かの役に立てれれば幸いです。