OmniAICreator/Qiita-1.07M huggingface dataset:
初心者によるプログラミング学習ログ 136日目

# 100日チャレンジの136日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

136日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>136日目<br><br>技術書でjavascript学習<br>メンターさんのjavascriptの課題<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/javascript?src=hash&amp;ref_src=twsrc%5Etfw">#javascript</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1186030347382689792?ref_src=twsrc%5Etfw">October 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【メモ】Azure Analysis Servicesの可用性について

# はじめに
Azure Analysis Servicesの可用性を高める方式についてメモ
※記事内のリンクは引用です

# SLAについて

99.9 %

 https://azure.microsoft.com/ja-jp/support/legal/sla/analysis-services/v1_0/ 

日に2分弱は保証されていない時間が生まれるレベルですが、基幹系システムでなく情報系システムであれば問題ない水準です。

# 方式
ではさらに可用性を高めるための具体的方法ですが、冗長化を基本方針とします。
冗長化構成をとる方式として以下の2点の組み合わせが考えられます。

- マルチリージョン構成
- スケールアウト構成

## マルチリージョン構成
[Analysis Services の高可用性](https://docs.microsoft.com/ja-jp/azure/analysis-services/analysis-services-bcdr)

メインはこちらがアナウンスされています。
あらかじめ各地のリージョンにセカンダリのAnalysis Servicesを配置してダウン時にセカンダリにアクセスさせるようにします。
その際に[サーバー名のエイリアス](https://docs.microsoft.com/ja-jp/azure/analysis-services/analysis-services-server-alias)の機能を使うことでクライアントからはサーバの切り替えを
意識することなくアクセスさせることができます。

###同期の方式
冗長化をするうえで重要なのはデータの同期ですが下記の2つの方法がアナウンスされています。
> - モデルを他のリージョンの冗長サーバーにデプロイします。 この方法を使用する場合、プライマリ サーバーと冗長サーバーの両方のデータを並行して処理し、すべてのサーバーを確実に同期させる必要があります。
- プライマリ サーバーのデータベースをバックアップして、冗長サーバーで復元します。 たとえば、Azure Storage への夜間バックアップを自動化し、他のリージョンの他の冗長サーバーに復元できます。

また、下記の記事ではマルチリージョンをとりつつ、トラフィックマネージャを利用して、ユーザから近いリージョンのサーバに振り分けて負荷分散をする方式が紹介されています。
[Sending Users to the Geographically Nearest Azure Analysis Services](https://www.artisconsulting.com/blogs/greggalloway/2018/5/11/sending-users-to-the-geographically-nearest-azure-analysis-services)
![](https://images.squarespace-cdn.com/content/v1/55384d85e4b0c2d27e3e53d4/1526016029577-4DKEGCKZ4ANAL1ZYYUFI/ke17ZwdGBToddI8pDm48kAT4PfIm-WUJ0E8Giolfk8AUqsxRUqqbr1mOJYKfIPR7LoDQ9mXPOjoJoqy81S2I8N_N4V1vUb5AoIIIbLZhVYy7Mythp_T-mtop-vrsUOmeInPi9iDjx9w8K4ZfjXt2dnMgO7A6QMn7-fHGU31KU1ysKnNhZaLVqZTJLxxvpjCXCjLISwBs8eEdxAxTptZAUg/image002.png?format=1500w)

SLAから考えると1-{(1-0.999)の（冗長化リージョン数）乗}が期待できるレベルと考えます。


## スケールアウト構成
[Azure Analysis Services のスケールアウト](https://docs.microsoft.com/ja-jp/azure/analysis-services/analysis-services-scale-out)

同一リージョン内でクエリ応答のためのレプリカを作成します。
ただしこちらに関しては可用性が上がりそうではありますが、具体的な数字と冗長化の仕様ついての情報は明記されていませんでした。ラック障害には対抗できないかもしれません。
[ゼロから作るDeep Learning]ニューラルネットワークの学習 ~基本~ 数値微分の勾配式を実装してみた

#はじめに
この記事は**ゼロから作るディープラーニング 5章ニューラルネットワークの学習**を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。

#数値微分の勾配式
ニューラルネットワークの学習でパラメータを更新していくときに一番必要となるものが勾配です。
勾配とは、関数の各変数の偏微分を一つの配列にまとめたものです。
ニューラルネットワークの学習で必要になる勾配は、ニューラルネットワークの処理から損失関数までを一つの関数と、パラメータを変数と置いて、各パラメータごとに偏微分をしたものを一次元配列にまとめたものです。
この勾配を求める式が勾配式です。

今回は数値微分の勾配式を解説するために、簡単な多次関数を使いたいと思います。

```python
# 勾配式で代わりに使う簡単な二次関数
def func_2(x):
    return x[0] ** 2 + x[1] ** 2
```

実際にニューラルネットワークの学習で使うニューラルネットワークから損失関数までの関数も多次関数と捉えるので、上のような簡単な二次関数を使っても解説に影響はありません。

```python
def slopeing_grad(f, x):
    h = 1e-4
    grad = np.zeros_like(x)# 勾配の入れ物となる空(ゼロ)ベクトル作成
    if x.ndim == 2:# パラメータが複数ある場合の処理
        first = x.shape[0]
        second = x.shape[1]
        for fir in range(first):
            for sec in range(second):
                tmp_val = x[fir, sec]
                x[fir, sec] = (tmp_val) + (h)
                fxph = f(x) # f(x + h)の計算
                x[fir, sec] = (tmp_val) - (h)
                fxmh = f(x)# f(x - h)の計算
                grad[fir, sec] = (fxph - fxmh) / (2 * h)# 偏微分してゼロベクトルに格納
        return grad
    elif x.ndim == 1:# パラメータが一つしかない場合の処理
        for nid in range(x.size):
            tmp_val = x[nid] # 変数に入る値を取り出す
            x[nid] = (tmp_val) + (h)
            fxph = f(x) # f(x + h)の計算
            x[nid] = (tmp_val) - (h)
            fxmh = f(x)# f(x - h)の計算
            grad[nid] = (fxph - fxmh) / (2 * h)# 偏微分してゼロベクトルに格納
        return grad

slopeing_grad(func_2, [3.0, 0.0])
array([6., 0.])
```

上の実装ではまず、一次関数とその他の多次関数とを分けるためif文を使います。
勾配式で使うものは関数および、関数の各変数に入る値が入った配列です。
多次関数はどれだけ変数が増えても配列は２次元配列止まりなので、一次元配列の場合と２次元配列の場合で分けます。

次にfor文を使って、各変数を選択して全ての変数の偏微分を行います。
偏微分で得た値は最初に作ったからの配列に格納されます。

このような流れで勾配を求めていきます。
hive, Hadoopの環境構築でつまづいた話

Hadoopの勉強をするためにインストールをしようとしたのですが、つまづいて一日潰した話。
HadoopのチュートリアルやHiveの説明は一切行わないので、似たようなエラーでここにたどり着いた人の役に立てば、と思います。

## インストール環境

macOS Mojave

## インストールしたかったもの

Hadoop==3.2.1
hive==3.1.2

## 結論

Java8のインストールとHadoop, Hiveのguava-XX.X-jre.jarのバージョンを統一することで解決可能。

Java8のインストールはHomebrewで行います。
OracleのJavaは有償化されてしまったため、オープンソースのjdkをインストールします。以下のコマンドを実行すればOK。

```
brew cask install adoptopenjdk/openjdk/adoptopenjdk8
```
Hadoop, Hiveのインストールについては以下のコマンドでOK。

```
brew install hadoop
brew install hive
```


## 詰まっていた原因その1

Hadoopを使ってSQLライクにクエリを行いたかったため、Hadoop・Hiveをインストールすることに決めました。
HadoopはJavaのインストールが必須なため
以下のコマンドを実行して、javaをインストールしました。(これが原因だと気づかずに…)

```
brew cask install adoptopenjdk
```
上記コマンドでインストールされたjavaのバージョンは13。
しかし、現行の最新版であるHadoop(3.2.1)はJava８対応となっておりバージョンのズレが生じてしまっていました。

## 詰まっていた原因その2

その1に記したjavaのバージョン問題に気づいた後にjava8をインストールし直し、事態は解決にむかうかと思われました。
実際、Hadoopのチュートリアルとも言われるwordcountのプログラムは動きました。
しかし、Hiveのコマンドは一切動かず以下のエラーが出るばかり。

```
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/Cellar/hive/3.1.2/libexec/lib/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/Cellar/hadoop/3.2.1/libexec/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
	at org.apache.hadoop.conf.Configuration.set(Configuration.java:1357)
	at org.apache.hadoop.conf.Configuration.set(Configuration.java:1338)
	at org.apache.hadoop.mapred.JobConf.setJar(JobConf.java:536)
	at org.apache.hadoop.mapred.JobConf.setJarByClass(JobConf.java:554)
	at org.apache.hadoop.mapred.JobConf.<init>(JobConf.java:448)
	at org.apache.hadoop.hive.conf.HiveConf.initialize(HiveConf.java:5141)
	at org.apache.hadoop.hive.conf.HiveConf.<init>(HiveConf.java:5099)
	at org.apache.hadoop.hive.common.LogUtils.initHiveLog4jCommon(LogUtils.java:97)
	at org.apache.hadoop.hive.common.LogUtils.initHiveLog4j(LogUtils.java:81)
	at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:699)
	at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:683)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.hadoop.util.RunJar.run(RunJar.java:323)
	at org.apache.hadoop.util.RunJar.main(RunJar.java:236)
```

原因となっていたのは、HadoopとHiveの実行ファイルのバージョンが異なっていたことでした。
Hadoop側のguavaはguava-27.0-jre.jarだったのに対して、
Hive側のguavaはguava-19.0-jre.jar。
この相違が原因でコマンドの実行が妨げられていたのです。

## 参考になったURL
https://stackoverflow.com/questions/58176627/how-can-i-ask-hive-to-provide-more-detailed-error
Azure Logic App を使って「千曲川　氾濫」が含まれるツイートがされた際に通知してくれるシステムを作ってみた

災害時はツイッターの情報が役に立ったりします。個人ニーズにあわせた情報が二次災害を最小限に防ぐために使えるとしたら、もツイッターの情報が有益なのではないかと思い、Azure Logic App を使って「千曲川　氾濫」というキーワードが含まれるツイートがされた際に、メール通知してくれるシステムを作ってみます。

#Azure Logic App をデプロイ
作成方法はいくつかありますが、Portal からデプロイするのが一番楽でしょう。サーバーレスコピューティングはすぐにデプロイできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/ee7f92bc-ec13-8700-86ef-8ed09c055bea.png)

#Logic を作成する
作成すると、Logic App Designer が表示されます。普通は空のところから始めますが、既にTwitter をトリガーとするものは用意されているのでそれを使ってみましょう。以下のトリガー選択のところから「Twitter Trigger」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/edf20d02-c617-0c85-0578-eef3d100b0db.png)

Twitter Trigger を作成しようとすると、Twitter の認証画面がでます。これは Twitter API を使用とする際に出るもので、どのアカウントでも良いので認証を通しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/c33f1f40-f0eb-c36c-8165-24787eee01fa.png)

「千曲川　氾濫」を含む新しいツイートがされたことを3分に1度確認し、あればmail で通知するというロジックを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/2fd5d4f6-8ebe-5dba-51cb-9c65db4fc4d1.png)
作成できたら Save をして Run するだけで実行できます。

#試してみる
実際に動かしてみました。今回は私のoutlook のメールアドレスから、gmail にツイート情報が送信されるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/4af0466d-5611-0413-d20d-610d87819d45.png)

3分に一度回すようにロジックを組んでいるので、少し待ちます。
するとキーワードが含まれるツイートのメールが届きました！超簡単ですね！
CloudFrontの多段構成はできないようになっている

CloudFrontの多段構成を試みたところ、うまくいきませんでした。どうやらCloudFrontには制限が設けられているようです。

## やりたかったこと
- REST APIのアプリケーションと、静的なWebサイトを同じドメインで提供
- アプリケーションはECSにあり、ELBを通してアクセス
- 静的WebサイトはAWS Amplify Consoleにホスティング
- それぞれをCloudFrontのオリジンとして登録し、パスで振り分ける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37155/53b80346-1b3a-95b0-b0d3-fc947a114502.png)

## 403エラーが返ってきてしまう
Amplify Consoleに対するすべてのリクエストが403エラーになってしまいます。

```
403 ERROR
The request could not be satisfied.

Bad request. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner. 
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation. 
```

AWSのドキュメントを参照しても、原因に思い当たるところがありません。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/resolve-cloudfront-bad-request-error/

## 原因はCloudFrontのドキュメント外の仕様だった

CloudFrontはオリジンに対するリクエストの `Via` ヘッダーに次のような値を設定します。

```
Via: 2.0 f32d93db98d9cf41d6a5114f4ba1xyz.cloudfront.net (CloudFront)
```

この形式のヘッダーがリクエストに含まれていると、CloudFrontは前述のような403エラーを返します。
おそらく、CloudFrontをCloudFrontのオリジンとして指定されるのを防ぐためにこのような仕様になっているのでしょう。

### Amplify Consoleは内部的にCloudFrontを通して提供されている
Amplify Consoleのエンドポイントは、内部的にCloudFrontが使われています。
当初にやりたかったサイトの振り分けがエラーになってしまうのはこれが原因だったようです。

### ヘッダーを改変すれば制限を回避できる
仕様を逆手に取り、 `Via` ヘッダーを削除したり別の値を指定すればワークアラウンドとして機能しそうです。
実際には試していませんが、どうしても必要な場合は検討してみてはどうでしょうか。
php7.1から使えるnullableな型宣言について

タイプヒンティングが使えるようになるphp7系ですが、
php7.1はさらにパラメータや返り値の型宣言で ``nullable`` 指定ができるようになりました。

## Null許容型

型の前にクエスチョンマークをつけると、nullable であることを指定できます。
こうすることで指定型だけでなくnullも渡せるようになります。

### 関数の戻り値の場合
```php
<?php

function test_return(): ?string
{
    return 'hogehoge';
}

var_dump(test_return());

function test_return(): ?string
{
    return null;
}

var_dump(test_return());
```

```
出力結果
ーーーーー
string(8) "hogehoge"
NULL
```

上記のようにstring指定の型でもnullを返すことができます。

### 関数の引数の場合

```php
function test_dump(?string $name)
{
    var_dump($name);
}

test('hogehoge');
test(null);
```

```
出力結果
ーーーーー
string(8) "hogehoge"
NULL
```

上記のようにstring指定の型でもnullを渡すことができます。

ちなみに、

```php
test_dump();
```
で上記関数を呼び出した場合は、

``Too few arguments to function test_dump(), 0 passed in ... ``
が発生します。

なので、

```php
function test_dump(string $name = null)
{
    var_dump($name);
}
```

の定義とは違いますね。

## 参照

https://www.php.net/manual/ja/migration71.new-features.php
Firebaseによるpush通知[cordova]

cordovaプロジェクトでfirebaseからプッシュ通知をしたかったのですが、plugin導入でコケまくりました。
今回は私が成功した方法についてまとめました。

## 前提条件
- os: win32
- cordova: 9.0.0
- Node: v10.16.2
- npm: 6.10.3
- cordova-android: 8.1.0

## 流れ
1. cordovaプロジェクトファイルの作成
2. プラグインの導入
3. firebaseのプロジェクト作成
4. google-service.jsonを配置する 
5. メッセージの送信・受信

## プロジェクトファイルの作成
今回はvue.js OnsenUIによるプロジェクトを作成しました。

```vue init OnsenUI/vue-cordova-webpack プロジェクト名```
```cd プロジェクト名```
```npm install ```

プラットフォームの追加
私の場合アンドロイド端末による開発のためアンドロイドのみを追加しました。

```cordova plarform add android```

最後にビルドを行います
```npm run build ```
## プラグインの導入
cordova-firebaseのプラグインには「cordova-plugin-firebase」「cordova-plugin-fcm」などがあるがこれらではうまくいきませんでした。
私は「cordova-plugin-firebase-lib」を使用しました。

こちらのプラグインを導入する際は、「cordova-cli」「cordova-android」「cordova-ios」によって入れるプラグインバージョンが多少異なります。

私は以下のサイトを参考にしました。
https://github.com/wizpanda/cordova-plugin-firebase-lib/tree/v5.1.1

「cordova-android」「cordova-ios」のバージョンはプロジェクト内のpackage.jsonから確認できます。

私が導入したプラグインは次に3種類です。

```cordova plugin add cordova-plugin-firebase-lib```
```cordova plugin add cordova-plugin-androidx```
```cordova plugin add cordova-plugin-androidx-adapter```

最後に、```cordova run android```でアプリを起動

## firebaseのプロジェクト作成
1. 「プロジェクトを追加」から新規のプロジェクトを作成する

2. プロジェクトの名前を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429746/14943023-283c-bdde-2c85-fa5b3566b26f.png)
3. firebaseプロジェクト作成後、アプリの追加
今回はアンドロイドを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429746/00e94a0c-e475-fa31-47d7-818c2260774d.png)

(アンドロイドパッケージ名は作成したプロジェクトファイルの「config.xml」から参照)

 4.google-service.jsonをダウンロードずる。
ダウンロードしたらその後は[次へ]→[このステップをスキップ]を選択

## google-service.jsonを配置する
cordovaプロジェクトフォルダの直下に配置します。

## メッセージの送信・受信
firebaseからメッセージを作成し、送信します。
[Cloud messageing]→[Send your first message]

通知の作成を行う。
通知のタイトルとテキストを設定し、ターゲットの設定をする

ターゲットはアプリ選択の項目にアンドロイドパッケージ名を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429746/532b5a64-04c6-2890-b7c8-6e1da4e0b50a.png)

設定後、確認をクリックする。
起動しているアプリからプッシュ通知を受信することができます。

## 参考文献
https://github.com/wizpanda/cordova-plugin-firebase-lib/tree/v5.1.1
【Rails】MySQL5.6 完全アンインストール(Mac)

#経緯
railsで新しいアプリケーションを立ち上げる際の

```
$ rails _5.2.3_ new xxx -d mysql
```
や、データベース作成時の

```
$ rails db:criate
```
を実行した際に
エラーが頻発し、対処に困りました。

一度、綺麗に整理してやり直した方がいいという結論に達し、
完全なアンインストールをすることになりました。

以下は、スクールで質問しながら実施したメモとなります。
調べると、他にも方法があるみたいですが、参考になれば幸いです。


#手順

```
$ brew uninstall mysql@5.6

$ brew cleanup

$ sudo rm -rf /usr/local/var/mysql

$ sudo rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

```


#その他
以下のブログも参考にさせて頂きましたので、掲載させていただきます。
https://ameblo.jp/tcexternal/entry-11937950845.html

```
※まずはmysqlを停止する
 システム環境設定からmysqlをクリックし、ダイアログの「Stop MySQL Server」をクリック。
 ダイアログに「The MySQL Server Instance is stopped」と表示されれば停止完了

# sudo rm -rf /usr/local/mysql
（エイリアスを削除）

# sudo rm -rf /usr/local/mysql-5.6.21-osx10.8-x86_64
（本体を削除）

# sudo rm -rf /Library/StartupItems/MYSQLCOM
（スタートアップ設定を削除）

# sudo rm -rf /Library/PreferencePanes/MySQL.prefPane
（システム環境設定のアイテムを削除）

# sudo rm -rf /Library/Receipts/mysql-.pkg
（インストールパッケージを削除、無い場合もある）
```
Docker ComposeでDBへの接続確認後にDjangoを起動する

Docker Composeで`web`にDjango、`db`にデータベース(今回はmysql)を定義した場合に`depends_on`オプションを利用してもdbが起動しきれずにwebが起動してしまい、webからのdbへの接続でwebが異常終了してしまう現象にハマってしまった。回避策としてDjango経由でdbのヘルスチェックを行ってからwebを起動するように対応したのでメモとして残してみました。

## 対応内容

こんな感じの`docker-compose.yml`があった場合、webとdbがほぼ同時に起動してしまう。

```
version: '3.7'

services:
  web:
    build: .
    ports:
      - "3033:3033"
    command: uwsgi --http :3033
    depends_on:
      - db

  db:
    image: mysql:8.0.17
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "3306:3306"
    volumes:
      - ./mysql:/var/lib/mysql
      - ./sql:/docker-entrypoint-initdb.d
```

Django経由でdbへのヘルスチェックをするシェルスクリプト(`db_healthchecker.sh`)を下記のように作成。Djangoの`manage.py`と同じ階層へ設置する。接続失敗した場合は3秒毎に10回リトライする。

```
#!/bin/bash

retry_counter=10
is_result=0
exit_code=1

for ((i=0 ; i<$retry_counter ; i++))
do
  echo 'exit' | python manage.py dbshell
  exit_code=$?
  if [ $exit_code = 0 ]; then
    echo 'Success: Connected to Database!!'
    is_result=0
    break
  else
    echo 'Error: Unable to connect to database.'
    echo 'exit code: ' $exit_code
    is_result=1
    sleep 3
  fi
done

if [ $exit_code -ne 0 ]; then
  echo 'Failed connect to database!!'
fi

```

`docker-compose.yml`の`web command`に`db_healthchecker.sh`を組み込む。

```
version: '3.7'

services:
  web:
    build: .
    ports:
      - "3033:3033"
    command: >
      bash -c "chmod 777 ./db_healthchecker.sh &&
        ./db_healthchecker.sh &&
        uwsgi uwsgi.ini --socket :3033"
    depends_on:
      - db

  db:
    image: mysql:8.0.17
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "3306:3306"
    volumes:
      - ./mysql:/var/lib/mysql
      - ./sql:/docker-entrypoint-initdb.d
```

これで`docker-compose up`で起動するとdbへ接続できるようになってからwebが起動してくれる。

## その他

もっとシンプルな方法があったら教えて欲しいです。
/-/ というハイフンを含むURL

週刊誌などのニュースサイトのURLを見ると

`https://{ドメイン}/articles/-/XXXXXX`
というようなURLを見かける。<br><br>

1つのニュースサイトだけでなく、ちらほらと別のニュースサイトでも見かけるのが、パス中(ディレクトリ名)に`-`を使っていること。<br><br>

記事を見てると分かるが、例としてURLを上げると

`https://toyokeizai.net/articles/-/307139`

`https://toyokeizai.net/articles/comment/307139`

というようにハイフンのパスは、記事のコメントのページを示すURLに変形することができる。

推測だが、ディレクトリの階層を同じにすることで管理しやすくするためだと思われる。<br><br>


コメントのページだけではなく、画像プレビューページやプリント用ページのパスにもなる。

`https://www.jprime.jp/articles/photo/16250`

`https://president.jp/articles/print/28421`
<br>

モバイル端末向けページ(AMP)のパスもある。

`https://gendai.ismedia.jp/articles/amp/50183`


## 閑話

### ちなみに

`https://www.jprime.jp/articles/photo/16250`
`https://www.afpbb.com/articles/-/3171249?pid=20032237`

とかの記事にある写真のURLは

`https://jprime.ismcdn.jp/mwimgs/3/a/-/img_3a0617b530873257d1d11636eaf4657d569852.jpg`
`https://afpbb.ismcdn.jp/mwimgs/6/8/80h/img_6896a0067eb1185ef27c708f1399b5b273807.jpg`

という風に違う出版社なのにURLが似ているということ。

```math
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```
$\textsmall{(/3/a/-/のハイフンは何かというと、サムネのパスになるらしい}$
$\textsmall{//jprime.ismcdn.jp/mwimgs/3/a/226/img_3a0617b530873257d1d11636eaf4657d569852.jpg}$
$\textsmall{。)}$<br><br><br>


大抵の日本向けの出版社のニュースサイトは「Japan Business Press Co., Ltd.」のサイト運用システムを使っていると推測。

* [Site report for www.jprime.jp](https://toolbar.netcraft.com/site_report?url=www.jprime.jp "Site report for www.jprime.jp")
* [Site report for afpbb.com](https://toolbar.netcraft.com/site_report?url=afpbb.com "Site report for afpbb.com")


### 記事とコメントページのパス 他のサイトの例

<b>amazonの場合</b>

商品ページ
`https://www.amazon.co.jp/dp/B00GNPUKCY`

レビューページ
`https://www.amazon.co.jp/gp/customer-reviews/REHELFAMZMEFX`

そのレビューの常設リンク
`https://www.amazon.co.jp/review/REHELFAMZMEFX`
Windowsで手動ルーティング設定/ARPテーブル設定

Windowsで手動ルーティングやARPテーブル設定をするときのメモ。

環境はWindows7/Windows10。

# ルーティング

### route add コマンド
宛先が 100.100.100.1/32 のパケットは 30.30.30.1 がゲートウェイだよ。使用するインタフェース番号は 24 だよ、という設定をするコマンド。（管理者権限で実行）

```console
route add 100.100.100.1 mask 255.255.255.255 30.30.30.1 if 24
```

ifオプションに指定するインタフェース番号は、netsh interface ipv4 show interfaces で確認できる。

```console
c:\> netsh interface ipv4 show interfaces

Idx     Met         MTU          状態                 名前
---  ----------  ----------  ------------  ---------------------------
 24           5        1500  disconnected  イーサネット
 30          65        1500  connected     Wi-Fi
```


# ARP

### netshでARPテーブル指定
100.100.100.1 のMACアドレスは 01-02-03-0A-0B-0C だよ、という設定をするコマンド（管理者権限で実行）

```console
c:\> netsh interface ipv4 set neighbors "インターフェース名" 100.100.100.1 01-02-03-0A-0B-0C
```

<br>
ここでいう"インタフェース名"は "イーサネット" などが入る。
route add でも使用した netsh interface ipv4 show interfaces で確認できる。

```console
c:\> netsh interface ipv4 show interfaces

Idx     Met         MTU          状態                 名前
---  ----------  ----------  ------------  ---------------------------
 24           5        1500  disconnected  イーサネット
 30          65        1500  connected     Wi-Fi
```

### arp -sでARPテーブル指定
古いWindows(Vistaとか)だと arp -s でARPテーブルの手動設定をするらしい

```console
c:\> arp -s 100.100.100.1 01-02-03-0A-0B-0C
```

<br>削除は -d

```console
c:\> arp -d 100.100.100.1
```
VBAでそのたマクロなしEXCELをコントロール

'クラスモジュールclsAppを追加する
Option Explicit
Public WithEvents XL As Application


Private Sub XL_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
On Error GoTo handler:
     Application.EnableEvents = True
     'do someting you want in new excel that no macro
handler:
End Sub

'ThisWorkBook下記ソース追加

Dim xlApp As New clsApp

Private Sub Workbook_Open()
    Set xlApp.XL = Application
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Set xlApp.XL = Nothing
End Sub
bashで複数選択のメニューを作る

検索してもあまり情報が出てこなかったので、自分用にメモ。

#### 関数

```bash
multiple_select() {
  local PS3="$1（複数選択する場合は、半角スペースを開けてください）> "
  local items="$2 exit"
  local itemarray=($items)
  local itemlen=${#itemarray[@]}
  local regex='^[1-9][0-9]*$'
  local res=''

  select selection in $items; do
    for i in $REPLY; do
      if ! [[ $i =~ $regex && $i -le $itemlen ]]; then
        echo "入力値が不正です。" 1>&2
        return 1
      fi
      if [ $i -eq $itemlen ]; then
        echo ""
        return 0
      fi
      # 設定済みの場合は無視する
      if [[ $res == *"${itemarray[i-1]}"* ]]; then
        continue
      fi
      res+=" ${itemarray[i-1]}"
    done
    echo $res
    return 0
  done
}
```

#### 使い方

```bash
my_favorite_fruits=`multiple_select \
  "好きな果物は何ですか？" \
  "りんご みかん いちご バナナ"` \
|| exit 1
```

#### 出力

```console
1) りんご
2) みかん
3) いちご
4) バナナ
5) exit
好きな果物は何ですか？（複数選択する場合は、半角スペースを開けてください）> 1 2 2 4 1 4 4
りんご みかん バナナ

1) りんご
2) みかん
3) いちご
4) バナナ
5) exit
好きな果物は何ですか？（複数選択する場合は、半角スペースを開けてください）> a
入力値が不正です。
```
もしもMacintosh HDを削除してしまったら...?

### Macintosh HDを削除してしまった~ !!!
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/08db6e16-22e5-87ad-8324-21b1fdac134e.jpeg" width=50%>

出典 : [iMacを立ち上げたら、はてなマークのフォルダが点滅した時の対処法](https://etoile-studio.com/troubleshooting/how-to-deal-with-question-folder-on-imac-display/)

って人がこの記事を見ているかと思いますが(笑).

自分はOS初期化の際にやってしまいましたね...orz
普段から適当な操作しているからでしょう...

起動しても永遠に「?」マークのアイコンが点滅を繰り返すばかり...
自分の症状の場合は以下で解決できました.
**自己責任で試してみてくださいね!**


1. 起動時に`command + R`押し続けてリカバリーモードにする.
2. おそらく地球儀が回っているアイコンが出て, 何十分か待たされます.
3. 何故か英語表記になりました. とりあえずWi-Fiに接続します.  
(**ここで OS reinstall を選択してはならない**. OS reinstallを選び, 進めたところでinstallするHDが選択肢に出てこない. 本来ならここに"Macintosh HD"が出るはず. これをやると何故か後戻りできず強制終了すると再度2から始まるので注意.)
4. disk utilityを選び, Apple SSDのところでパーティションの分割をする. 基本はMaxの容量を, Mac OS Extended (Journaled)を選択して名前を"Macintosh HD"にする.
5. OS reinstallを選ぶと, installするHDに4で作成したHDが出てくるはず.
6. installする. ただし, OSはOS X El Capitanしかない. 仕方なくこれをinstallする.
7. installしてから再度upgradeの形でmacOS Mojaveをinstallする. これも1.5時間くらい待たされる.

なんだかんだで3時間以上食います. 消さないように気をつけましょうね...
【えらい立派なブラウザ】コードレビューをすりぬけてIEユーザーを煽る方法【使っとりはりますなぁ。】

ようおいでやす。
あんたらもIEに苦労しはってんやなぁ

うちはたくお申します。よろしゅうたのんます。

IE使こてるユーザになんぎしてるからきつーく注意してやりたいんやけど、コードレビューでバレるとリリースできんさかい、バレへん方法をおせーるで。

いけずな上司やレビュワーも気付きまへんさかい、あんじょう使こてや。

## かいらし方法

```js

alert("えらい立派なブラウザ使っとりはりますなぁ。");
```

かいらしいどすなぁ…
こんなん、すぐに見つかってお灸すえられるでぇ??

## あほくさい方法

```js
alert("\u3048\u3089\u3044\u7acb\u6d3e\u306a\u30d6\u30e9\u30a6\u30b6\u4f7f\u3063\u3068\u308a\u306f\u308a\u307e\u3059\u306a\u3041\u3002");
```

さっきよりはマシなりはりましたけど、あほくさいコードどすなぁ…
ちっこいプルリクやと目立って見つかりはるで??

## ぼちぼちな方法

```jsx
const icon = "YWxlcnQoIuOBiOOCieOBhOeri+a0vuOBquODluODqeOCpuOCtuS9v+OBo+OBqOOCiuOBr+OCiuOBvuOBmeOBquOBgeOAgiIpOw==";
const decoded_utf8str = atob(icon);                                                                                 
const decoded_array = new Uint8Array(Array.prototype.map.call(decoded_utf8str, c => c.charCodeAt()));               
const decoded = new TextDecoder().decode(decoded_array);                                                            
                                                                                                                    
return (                                                                                                            
  <img onLoad={ eval(decoded) } />                                                                                  
);                                                                                                                  
```

きょうびevalとonLoadは不自然おまへんか??
どんくさい人がレビューしたらうまくいくかもせぇへんなぁ。

## はんなりな方法

```jsx
// APIなどのレスポンスで仕入れとくんどすえ
const response = '{"beacon":"YWxlcnQoIuOBiOOCieOBhOeri+a0vuOBquODluODqeOCpuOCtuS9v+OBo+OBqOOCiuOBr+OCiuOBvuOBmeOBquOBgeOAgiIpOw=="}' 
const json = JSON.parse(response)                                                                                                    
const beacon_utf8str = atob(json.beacon);                                                                                            
const beacon_array = new Uint8Array(Array.prototype.map.call(beacon_utf8str, c => c.charCodeAt()));                                  
const beacon = new TextDecoder().decode(beacon_array);                                                                               
(new Function(beacon))()                                                                                                             
                                                                                                                                     
return (                                                                                                                             
  <img src={ beacon } style={ { width: "1px", height: "1px" } } />                                                                   
);      
```

「Webマーケチームが計測したい言いはるんで、1pxビーコン入れたどす」って言うたらまずバレんさかい、これでどうえ??
ほんまえげつない人やわぁ。


## まとめ

「ぶぶ漬けでもどうどす？」
Pythonで素数列挙

#概要
Pythonで素数を列挙する
# コード

```python:sosuu.py
sosuu=[2];A=10000
for L in range(3,A):
    chk=True
    for L2 in sosuu:
        if L%L2 == 0:chk=False
    if chk==True:sosuu.append(L)
print(sosuu)
```
#追記
コメントにて、もっと見やすくて早い書き方ができるとのアドバイスをいただきました！ありがとうございます！

```python:sosuu_faster.py
sosuu = [2]
A = 100000
for L in range(3, A, 2): # 2 以外の素数は奇数なので
    for L2 in sosuu:
        if L % L2 == 0:
            break # 素数でないことがわかったらそれ以上ループする必要はない
    else: # break で抜けることがなかったら L は素数（Python 特有の制御構文）
        sosuu.append(L)
print(sosuu)
```

また、内包表記を使用できるとのコメントもいただきました！ありがとうございます！

```python:sosuu_comprehension.py
sosuu = [2]
A = 100000
for L in range(3, A, 2): # 2 以外の素数は奇数なので
    if all(L % L2 != 0 for L2 in sosuu):  # すべての既存素数で割り切れなかったら素数
        sosuu.append(L)
print(sosuu)
```
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails 〜みたいなエラーの解決

##環境
NodeJS
MySQL

##状況
別環境へのデータの復元的な処理を作ってて、
自動的にいろんなテーブルにinsertするような仕組みにしようとした中で出たエラーです。


## エラー内容

```
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (db_dd.tenant, CONSTRAINT <font color="DeepPink">dataFileRelation</font> FOREIGN KEY (code, nm) REFERENCES <font color="DeepPink">hogeFile</font>  (code, e_nm))    0.000 sec

```

## 解決方法
今回はhogeFileテーブルのカラムの外部キーがdataRelationテーブルにあるので、先にdataFileRelationテーブルをinsertしてしまうとhogeFileテーブルで参照できなくなり、不整合なデータとなってエラーとなるので、先にhogeFileテーブルのレコードを先にinsertする必要がある。
LaravelでjQueryメモ

# はじめに
メモいろいろ。
jQueryが多い。

# バージョン指定

コンポーザーでプロジェクトを作るときバージョンを指定しないと自動で最新のバージョンになる。

バージョンを指定しない↓

```:ターミナル
composer create-project --prefer-dist laravel/laravel memoapp
```

バージョンを指定↓

```:ターミナル
composer create-project --prefer-dist laravel/laravel memoapp 5.7
```

バージョンを確認↓

```:ターミナル
php artisan --version
```


# post()
jQueryのpostメソッド。
画面遷移なしでのDB処理に使った。

```php:test.blade.php
<form id="post">
  @csrf
  <input type="hidden" name="data1" value="こんにちは">
  <input type="text" name="data2">
</form>
<button onclick="postAction()">post</button>

<script>
  const postAction = () => {
    $.post("home", $("#post").serialize())
    .done(function(data){
      console.log(data);
    }).fail(function(data) {
      console.log("失敗");
    });
  }
</script>
```

フォームを用意しておいてスクリプトでpost、画面遷移をせずにコントローラー側で処理を行える。

ボタンでメソッドを呼びformを指定してpostしている。
`done()`でpost完了後の処理を、dataでコントローラー側でreturnした値を受け取れる。
`fail()`で失敗した時の処理を行う。

ここでの`home`はルーティングで指定した値、URL等。

```php:test.blade.php
<script>
  $csrf_token = '<?php echo csrf_token(); ?>';
  const deleteMemo = memo => {
    if (confirm("削除ok?")) {
      $.post("delete", {"id" : $(memo).val(),  "_token" : $csrf_token})
      .done(function(data) {
        toastr.success('メモを削除しました');
      });
    }
  }
</script>
```

フォームを用意しないでpostすることもできる。
postの第二引数で送る値を用意している。

自分用に少し具体的なまま。

# submitセレクター

```javascript:スクリプト内
// ボタンを押せなくする
$(":submit").prop("disabled", true);
// 戻す
$(":submit").prop("disabled", false);
```

submitタイプのbtnやinputを指定できる。

上記の[post()](#post)を使った時、処理待ちの間ボタンを押せないようにしたかった。

たくさんボタンがあっても一括で封印できて楽だった。



# parents() find()
いっぱい使った。
ボタンがたくさんあって押したボタンの親要素内でなんかしたいときとか。

```html:ボディ
<div>
  <div class="oya">
    <div>
      <div>
        <p class="memo">ここを書き換えたい</p>
      </div>
    </div>
    <div>
      <button onclick="kakikae(this)">ボタン</button>
    </div>
  </div>

  <div class="oya">
    <div>
      <div>
        <p class="memo">ここは書き換えたくない</p>
      </div>
    </div>
    <div>
      <button onclick="kakikae(this)">ボタン</button>
    </div>
  </div>
</div>
```

こんなとき。

```javascript:スクリプト
const kakikae = btn => {
  $parent = $(btn).parents(".oya").get(0);
  $($parent).find(".memo").text("完了");
}
```

上のボタンを押せば上のpタグだけを書き換えられる。




# muuri
動きが楽しい。
https://tr.you84815.space/muuri/index.html
https://coliss.com/articles/build-websites/operation/javascript/responsive-grid-layouts-muuri.html

見よう見まねで理解が怪しいので紹介だけ。



# おわり
いったんおわり。
Pythonistaで指紋認証

# 概要
Pythonistaで指紋認証をしただけ
# コード
```python:touch_id.py

# coding: utf-8
from objc_util import *
import threading

NSBundle = ObjCClass('NSBundle')
LocalAuthentication = NSBundle.bundleWithPath_(
	'/System/Library/Frameworks/LocalAuthentication.framework')
LocalAuthentication.load()
LAContext = ObjCClass('LAContext')

class AuthFailedException(Exception):
	pass
	
class AuthCancelledException(AuthFailedException):
	pass

class AuthTimeoutException(AuthFailedException):
	pass

class AuthNotAvailableException(AuthFailedException):
	pass

class AuthFallbackMechanismSelectedException(AuthFailedException):
	pass


def is_available():
	context = LAContext.new().autorelease()
	return bool(context.canEvaluatePolicy_error_(1, None))


def authenticate(reason='', allow_passcode=True, timeout=None):
	if not is_available():
		raise AuthNotAvailableException('Touch ID is not available.')
	policy = 2 if allow_passcode else 1
	context = LAContext.new().autorelease()
	event = threading.Event()
	result = {}

	def callback(_cmd, success, _error):
		result['success'] = success
		if _error:
			error = ObjCInstance(_error)
			result['error'] = error
		event.set()

	handler = ObjCBlock(
		callback, restype=None, argtypes=[c_void_p, c_bool, c_void_p])
	context.evaluatePolicy_localizedReason_reply_(policy, reason, handler)
	if not event.wait(timeout):
		context.invalidate()
		raise AuthTimeoutException('Timeout')
	success = result.get('success', False)
	error = result.get('error')
	if success:
		return True
	elif error:
		error_code = error.code()
		if error_code == -2:
			raise AuthCancelledException('Cancelled by user')
		elif error_code == -3:
			raise AuthFallbackMechanismSelectedException(
				'Fallback authentication mechanism selected')
		else:
			desc = error.localizedDescription() or 'Unknown error'
			raise AuthFailedException(desc)
	else:
		raise AuthFailedException('Unknown error')


# 例
def main():
	try:
		reason = 'We need you fingerprint.'
		authenticate(reason,allow_passcode=True)
		print('Success!')
	except AuthFailedException as e:
		print(e)


if __name__ == '__main__':
	main()

```
# 感想
Pythonista強い！
【JavaScript】配列の操作まとめ

#先頭に追加したい → unshift()

```JavaScript:サンプル
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
ary.unshift("マイケル")

console.log(ary)
```
```:実行
>>> ["マイケル", "佐藤", "鈴木", "田中", "石川", "水野"]
```


#末尾に追加したい → push()

```JavaScript:サンプル
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
ary.push("マイケル")

console.log(ary)
```

```:実行
>>> ["佐藤", "鈴木", "田中", "石川", "水野", "マイケル"]
```

#位置を指定して追加したい → splice(開始インデックス, 削除する要素数, 挿入する要素)

```JavaScript:サンプル１
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
ary.splice(2, 0, "マイケル")

console.log(ary)
```
```:実行
>>> ["佐藤", "鈴木", "マイケル", "田中", "石川", "水野"]
```

第一引数で、追加したい配列のインデックスを指定しています、今回は２なので、"田中"がいる場所に追加します。

※インデックスは、０から始まります。

第二引数で、削除する要素数を指定します、開始インデックスから数えます。



```JavaScript:サンプル2
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
ary.splice(2, 1, "マイケル")

console.log(ary)
```
```:実行
>>> ["佐藤", "鈴木", "マイケル", "石川", "水野"]
```

このコードでは、"田中"が消えました。

```JavaScript:サンプル３
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
ary.splice(2, 1, "マイケル", "ロビンソン")

console.log(ary)
```
```:実行
>>> ["佐藤", "鈴木", "マイケル", "ロビンソン", "田中", "石川", "水野"]
```

第三引数以降は、いくらでも指定することができ、順に要素として追加されていきます。

#ここで問題です！
以下のコードを実行すると何が表示されるでしょう？？

```JavaScript:サンプル
var ary = ["佐藤", "鈴木", "田中", "石川", "水野"]
var a = ary.splice(2, 1, "マイケル", "ロビンソン")

console.log(a)
```

わかりましたか？？

正解は。。。。。

```:実行
>>> ["田中"]
```

splice関数を実行して変数に代入されるのは、削除された要素なんですね。。。

職場で、上司に問題出されて、わからなかったので、記事にしてみました！

以上です！
Blenderから出力したFBXをPlayCanvasにインポートした際に画像データがエラーになる問題

**Blenderで書き出したFBXがPlayCanvasへインポートした際に、エラーを起こす原因について**![blender_fbx2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/785310bf-ec70-0d2d-ce6c-750118137ba7.png)
上記画像は、赤ピンクのラインが出ている画像データがエラーになっている状態。fbxに付けた名前.pngの0バイトファイルが自動生成される。
##原因
フォルダ階層の問題。
blender上でマテリアルにアサインするtextureデータが、blenderファイルがある"**同じ階層**"に無いと起こる現象のようです。![blender_fbx3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/82fa4211-d203-5a6b-df6d-9b980d90d9b3.png)

上記の様にtextureが別フォルダにある状態で、blender上のマテリアルに画像をアサインすると発生します。![blender_fbx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/b27b8c73-36b6-8487-8905-292b21d47c1d.png)
##解決方法
textureフォルダから使用する.png等をblenderファイルがある同じ階層に置いておき、ファイル指定する。![blender_fbx4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/f99cd063-5a00-413d-0397-956fb0c8f185.png)
![blender_fbx5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/ccabc5ed-5144-1995-3410-74e4d92298b4.png)
これで、画像データのエラーは回避できます。
JavaScriptで整数除算演算子を実現する

# 何をしたい？
割り算で小数点以下を切り捨てるようにしたい

# javascriptでの割り算

JavaScriptで整数同士の割り算を行った場合小数点以下まで出力されてしまいます。
CやC++で整数同士の割り算を行った場合小数点以下は切り捨てられるようになっています。

```javascript
console.log(23 / 10);
> 2.3
```

`2.3`を`2`と出力されるようにしたい

# 解決策1

`Math.floor()`を使用する。
参考: [Math.floor()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/floor)

```javascript
console.log(Math.floor(23 / 10));
> 2
```

# 解決策2

ビット演算子`| (ビットごとの OR)`を使用する。
参考: [Bitwise_OR](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR)

```javascript
console.log(23 / 10 | 0);
> 2
```

# ベンチマーク

パフォーマンスを求めた場合、ビット演算子を使用した方が早そうな感じはする(計測方法が間違ってたらごめんなさい)

```javascript
const startTime1 = performance.now();
for(let num = 0; num < 100000; num ++) {
    console.log(Math.floor(23 / 10));
}
const endTime1 = performance.now();


const startTime2 = performance.now();
for(let num = 0; num < 100000; num ++) {
    console.log(23 / 10 | 0);
}
const endTime2 = performance.now();

console.log(`Math.floor(23 / 10): ${endTime1 - startTime1}`);
console.log(`23 / 10 | 0: ${endTime2 - startTime2}`);

// 1回目
> Math.floor(23 / 10): 1766.8149839937687
> 23 / 10 | 0:         1773.3923920094967

// 2回目
> Math.floor(23 / 10): 1794.4279589951038
> 23 / 10 | 0:         1724.0651339888573

// 3回目
> Math.floor(23 / 10): 1811.3405220210552
> 23 / 10 | 0:         1716.2479899823666
```
Promising Hair Transplant Centre in Punjab

Those who have lost their hair due to genetic reasons and those who have lost their hair due to head injury in an accident, can get the hair transplanted. In addition, women who have sparse hair can also get their hair transplanted.
But individuals who do not have enough donor hair sites in their head cannot have hair transplanted. Apart from this, people who have surgery or bruises in the head, where only light hair is grown, they also cannot get a hair transplant. Hair transplant is also not recommended for those who have hair loss after medication or chemotherapy.
Get in touch with Profile hair transplant which is considered to be one of the best places to get in touch with a renowned hair transplant experts and get and have [hair transplant in Ludhiana](https://profilehaircentre.in/).
**Name**: Profile Hair Centre - Hair Transplant in Ludhiana, Punjab, India
**Location**: #47-B, Tagore Nagar, Opposite, Rose garden, Ludhiana, Punjab 141001
**Contact**: 098144 57148
Pythonで時系列解析(因果推論)


Pythonの`statsmodels==0.10.0`を用いて、主に因果推論のやり方をメモ程度に書きました。
それぞれの説明は全くないですがご容赦下さい。

## 単位根検定

Augmented Dickey-Fuller 単位根検定

```.py
from statsmodels.tsa.stattools import adfuller

results = adfuller(x) # x: array_like, 1d
stat = results[0]     # 統計量
pvalue = results[1]  # p値
```
pvalueが基準(0.05など)より小さい場合、単位根過程であるという帰無仮説が棄却

参考:
https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.adfuller.html


## 共和分検定

Augmented Engle-Granger two-step 共和分検定

```.py
from statsmodels.tsa.stattools import coint

results = coint(x, y) # # x, y: array_like, 1d
stat = results[0]     # 統計量
pvalue = results[1]  # p値
```

pvalueが基準(0.05など)より小さい場合、共和分の関係にないという帰無仮説が棄却

参考:
https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.coint.html

## グレンジャー因果性検定
### 前提
下のブログにあるように、以下のようなステップを踏んでから因果性検定を行います


https://tjo.hatenablog.com/entry/2013/08/16/095536
>1. VARモデルを推定する前に、まず個々の原系列に対して単位根検定を実施する
2. そもそもただの回帰関係が見たいだけなら、気にせずVARモデルを計算して良い
3. 単位根過程が混ざっていなければ、そのままVARモデルを計算して因果性分析まで行って良い
4. 単位根過程が混ざっていたら、まず共和分関係（ランク）を推定する
5. 共和分関係がなければ、差分系列に対してVARモデルを推定して因果性分析まで行って良い
>6. 共和分関係があったら、VECMを推定してからVARモデルに変換して初めて因果性分析を行える

単位根検定、共和分検定は上で説明したように行ってください。
VECMモデルに関してはたぶんいつか追記します。

以下では、上のステップを踏んだ後のVARモデルを推定して因果性分析をするところについて書きます。


### その１
####VARモデルで近似して、icがもっとも低くなる次数を見つけてから因果性検定

```.py
from statsmodels.tsa.vector_ar.var_model import VAR

maxlags = 100
model = VAR(x) # x: ndarray (data数, column数)
selected_orders = model.select_order(maxlags).selected_orders
# e.g. selected_orders = {'aic': 91, 'bic': 7, 'fpe': 91, 'hqic': 10}
results = model.fit(selected_orders['aic'])
test_results = results.test_causality(causing=0, caused=1)  # x0=>x1への因果を検定
pvalue = test_results.pvalue
```
pvalueが基準(0.05など)より小さい場合、グレンジャー因果がないという帰無仮説が棄却

参考:
https://www.statsmodels.org/dev/generated/generated/statsmodels.tsa.vector_ar.var_model.VARResults.test_causality.html#statsmodels.tsa.vector_ar.var_model.VARResults.test_causality

### その２
####VARモデルの次数を決めうちで因果性検定
次数が決められるときは、もっと簡単にできるっぽいので一応書いておきますが、その１でやればいいと思います。

```.py
from statsmodels.tsa.stattools import grangercausalitytests

maxlag = 30 
results = grangercausalitytests(x, maxlag) # x: 2darray (data数, 2), x[:,0] => x[:,1]への因果を検定 
stat = results[0]     # 統計量
p_value = results[1]  # p値
```
p_valueが基準(0.05など)より小さい場合、x1=>x2のグレンジャー因果がないという帰無仮説が棄却

参考:
https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.grangercausalitytests.html


## インパルス応答
VARモデルを推定するところまでは、グレンジャー因果性のその１と同じです。

```.py
maxlags = 100
model = VAR(x) # x: ndarray (data数, column数)
selected_orders = model.select_order(maxlags).selected_orders
# e.g. selected_orders = {'aic': 91, 'bic': 7, 'fpe': 91, 'hqic': 10}
results = model.fit(selected_orders['aic'])

period = 25
irf = results.irf(period)
irf.plot()
```

![スクリーンショット 2019-10-25 18.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235370/6264feff-6233-0012-f65b-213a903a9fea.png)

こんな感じの図が出るはず
create-react-app v3で.eslintignoreを有効にする

## TL;DR

設定上書きツール[craco](https://www.npmjs.com/package/@craco/craco)使って、`.eslintignore`をeslint-loaderが読み込むようにする

## 手順

cracoのインストール

```sh
yarn add @craco/craco
```

npm scripts更新

```diff
"scripts": {
-   "start": "react-scripts start",
+   "start": "craco start",
-   "build": "react-scripts build",
+   "build": "craco build"
-   "test": "react-scripts test",
+   "test": "craco test"
}
```

`craco.config.js` と `.eslintignore`を`package.json`と同じ階層におく

```js
// 以下コピペ
const { ESLINT_MODES } = require('@craco/craco');

module.exports = {
	eslint: {
		mode: ESLINT_MODES.file,
		loaderOptions: eslintOptions => {
			return { ...eslintOptions, ignore: true };
		}
	}
};
```

```
# .eslintignore例
src/grpc/**/*
```

## 役立った場面

create-react-app + typescriptで生成したプロジェクトで、gRPC-webのコードを利用しようとしたとき
RDSのSSL証明書更新状況を確認する

> 現在の CA 証明書は、2020 年 3 月 5 日に期限切れになります。そのため、有効期限の最後の日に中断しないように、できるだけ早い時期に (遅くとも 2020 年 2 月 5 日までに) この変更を完了することを推奨します。変更を完了しない場合は、2020 年 3 月 5 日以降はアプリケーションが SSL/TLS を使用して RDS DB インスタンスに接続できません。

 
> CA 証明書を rds-ca-2019 に設定することにより、以下のコードで mydbinstance を変更します。変更は、--no-apply-immediately を使用して次のメンテナンスウィンドウ中に適用されます。今すぐ変更を適用するには、--apply-immediately を使用します。このオプションを選択すると停止します。

## Linux、OS X、Unix の場合:

```
aws rds modify-db-instance \
    --db-instance-identifier mydbinstance \
    --ca-certificate-identifier rds-ca-2019 \
    --no-apply-immediately
```

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL-certificate-rotation.html より

実際にメンテナンスウィンドウにセットされたかは、なぜかマネジメントコンソールに表示がされません。

コマンドで確認するには以下のようにして確認をします。

```
aws rds  describe-db-instances | jq '.DBInstances[] | {id: .DBInstanceIdentifier, pendign: .PendingModifiedValues}'
```

idとPendingModifiedValuesの状態をセットで確認することができます。

参考

https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html#output
【勉強用】Linuxコマンドの標準入力と標準出力を初心者視点から

##免責事項
この記事は初心者視点でザックリとした説明をしています。正確性に欠ける可能性がございますが、ご了承ください。「明らかに違うよ」ということがありましたら、ご指摘くださると幸いです。

##環境
OS：最新版ではないMacOS
VirtualBox：5.2.26
Vagrant：2.2.6
Ubuntu：ubuntu/bionic64 v20181129.0.0


##目次
1. Linuxコマンドとは
2. 標準入力・標準出力とは
3. 標準入力・標準出力で便利なコマンド

#1. Linuxコマンドとは
「コマンド」とは直訳すると「命令」を意味し、キーボードで入力して、「コンピュータに命令」をすることです。
Linuxコマンドはキーボードを使ってLinuxを操作することを意味します。


（Linuxを操作するためには、GUI上でマウスを使って操作するか、CLI上でコマンドを使って操作するのかの2つの手段があります。
しかし、一般的にLinuxを操作する場合[^1]、CLI上でコマンドを使って操作することが多いのでコマンドをしっかりと覚えなくてはなりません。

[^1]: サーバーを操作する場合など


Linuxコマンドは使う場面があったら、その都度検索をして調べて覚えるのが良いでしょう。


#2. 標準入力・標準出力とは
Linuxのコマンドには、1つの入口と2つの出口があります。
1つの入口が標準入力、2つの出口が標準出力と標準エラー出力です。

#####標準出力
例えば、コマンドで以下のように入力すると

```
echo 'Hello World'
```
以下の結果が返ってきます。

```
Hello World
```

これはキーボードで、echo 'Hello World'と標準入力し、Hello Worldと標準出力されたことを意味します。


#####標準エラー出力
次にコマンドで以下のように入力すると

```
//helloというディレクトリを作成
mkdir hello
//helloディレクトリを削除しようとする
rm hello
```
以下の結果が返ってきます。

```
rm: cannot remove ‘hello’: Is a directory
```
これはキーボードで、rm helloと標準入力し、rm: cannot remove ‘hello’: Is a directoryと標準エラー出力されたことを意味します。

以上の例のように、Linuxのコマンドは「標準入力をうけて、標準出力と標準エラー出力を出す」という仕組みになっています。

#3. 標準入力・標準出力で便利なコマンド
###リダイレクト
リダイレクトとは、コマンドの最後に > 出力先ファイル と記述することで標準出力をファイルに保存する機能です。

```
//helloディレクトリ上に移動
cd ~/hello
//helloディレクトリに新しいディレクトリa, bを作る
mkdir ~/hello/a
mkdir ~/hello/b
//helloの中身を出力
ls
> a b
//helloディレクトリの中身をls-output.txtに保存
ls > hello/ls-output.txt
// ls-output.txtの中身を表示
cat hello/ls-output.txt
> a b
```
ちなみに、以下の記法もあります。

- コマンド >> ファイル ...出力がファイルに追記されます。（元のファイル内容の後ろに新しい出力結果が追記される）
- コマンド 2> ファイル　...標準エラー出力をファイルに保存。
- コマンド > ファイル 2>&1 ...標準出力と標準エラー出力の両方をファイルに保存。

※数字の意味について
Linuxには、OSが入出力を識別するための「割り振り番号」識別子がついていて、それぞれ以下を意味します。
・0...標準入力
・1...標準出力
・2...標準エラー出力

###パイプ
パイプとは、記号 | でコマンド同士をつないで、1つ目のコマンドの標準出力を、2つ目のコマンドの標準入力とすることができる機能です。

```
ls | cat > ls-output.txt
```
以上のコマンドは、
① lsで現在いるディレクトリの中身を出力する。
② ①の出力をcatの標準入力とする。
③ catで一覧表示された現在のディレクトリの中身をls-output.txtに保存する。
という意味になります。

ちなみに以上の流れを簡単に書き換えると

```
ls | tee ls-output.txt
>a b
```
になります。
teeは、標準入力の内容を標準出力とファイルに出力するコマンドです。
オプションで-a（オプション--append）をつけると上書きではなくファイルに追記する。

###grepコマンド
grepコマンドは、第一引数に「含まれるかどうかを判定する単語」を、第二引数に「検索したいファイル名」を入力して検索する機能です。
パイプによって標準入力がある場合には、第二引数を省くこともできます。
第一引数を正規表現にして検索することもできます。

```
ls | grep a
```
以上のコマンドは現在いるディレクトリの中身一覧の中で、aという文字が含まれているディレクトリorファイルがあるか検索しています。
aという文字が含まれているディレクトリorファイルが存在したら、そのディレクトリorファイルが出力されます。

```
ls | grep -s a
```
以上のコマンドは-sオプションをつけ、aという文字が**含まれない**ディレクトリorファイルがあるか検索しています。


##参考
「N予備校 プログラミングコース」
https://www.nnn.ed.nico/
「５分で一通り理解できる！Linuxのリダイレクト 使い方と種類まとめ」
https://eng-entrance.com/linux-redirect
「パイプ「|」を使って 複数のコマンドを組み合わせる」
https://webkaru.net/linux/commands-pipeline/
PHP Slim 環境構築(15) ECS(手動で設定するFargate編)

# PHP Slim 環境構築(15) ECS(手動で設定するFargate編)


## Introduction

[前回](https://qiita.com/dynamitecoolguy/items/1074132b8b082910abcf)は、コンテナをECS(EC2インスタンス)で動作させてみました。
今回は、EC2インスタンスからFargateに変更して同様に構築します。

この一連のシリーズは、自分への備忘録が第一目的のため、相当不親切です。
申し訳ございません。
しかし、もはや、Slimと関係ないですね。

## AWS

### ECR

前回と同じです。
このリポジトリのURIは、`<<AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo` になります。

### ビルド

これも前回と同じです。すでにビルド済みのイメージがECRに登録されているものとします。


### IAM(ロールの作成)

前回作成したhoge-ecs-userと同様です。
これは、一応新規で作ることにします。なお、前回も書きましたが、これでは権限が強すぎですね。

|パラメータ|値|
|:--|:--|
| ロール名 | fuga-ecs-user |  
| AWSサービス | Elastic Container Service Task |
| ポリシー | AmazonRDSFullAccess, AmazonDynamoDBFullAccess, AmazonS3FullAccess |



### EC2(ターゲットグループ)

ロードバランサの設定前に、そのターゲットグループを設定しておきます。
EC2インスタンスを使ったECSと異なり、ターゲットの種類はIPになります。

|パラメータ|値|
|:--|:--|
| 名前 | fuga-target |
| ターゲットの種類 | インスタンス |
| ポート | 3128 | 
| ヘルスチェック | http /favicon.ico | 



### EC2(セキュリティグループ)

前回と同じく、以下の二種類のアクセスに対するセキュリティグループを定義します。

* ロードバランサへのアクセス

外部からのhttp(s)のアクセスです。

|パラメータ|値|
|:--|:--|
| 名前 | fuga-http-sg |
| インバウンド | 80(0.0.0.0/0), 443(0.0.0.0/0) | 


* Dockerコンテナへのアクセス

Fargateへのアクセスです。ロードバランスのIPアドレスレンジを指定します。
なお、EC2では動的ポートマッピングを使用していたので可能性のあるポートの範囲を指定していましたが、今回はNginxのポートをそのまま指定します。

|パラメータ|値|
|:--|:--|
| 名前 | fuga-instance-sg |
| インバウンド | 3128(ロードバランサのVPC) |

### AWS Certificate Manager

SSLを使う場合は、こちらで証明書を発行します。今回も説明は割愛します。

### EC2(ロードバランサ)

ALBの設定を行います。これはEC2もFargateも変わりません。

|パラメータ|値|
|:--|:--|
| 名前 | fuga-alb |
| スキーム | インターネット向け |
| リスナー | 80, 443(証明書が必要です) |
| AZ | ap-northeast-1a, 1c, 1d全部 |
| セキュリティグループ | fuga-http-sg |
| ターゲットグループ | fuga-target |

### ECS(クラスター)

これはEC2インスタンス用のクラスターよりも、かなり単純になります。

|パラメータ|値|
|:--|:--|
| クラスターテンプレート | ネットワーキング |
| クラスター名 | fuga-cluster |


### ECS(タスク定義)

ECSで生成されたインスタンスにDockerコンテナを載せるためのタスク定義を行います。
EC2インスタンス用と違うのはネットワークモードと、タスクメモリとタスクCPUが指定しなければいけない、ポートマッピングがコンテナ側のみ(ネットワークモードの違い)ぐらいです。

|パラメータ|値|
|:--|:--|
| 起動タイプ | FARGATE |
| タスク定義名 | fuga-task |
| タスクロール | fuga-ecs-user |
| ネットワークモード | awsvpc |
| タスク実行ロール | ecsTaskExecuteRole(自動生成される) |
| タスクメモリ | 0.5GB (本当はちゃんと設定する。とりあえず最低値) |
| タスクCPU | 0.25vCPU (本当はちゃんと設定する。とりあえず最低値) |
| コンテナ名 | fuga-container |
| イメージ | &lt;&lt;AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest |
| メモリ制限 | 設定なし |
| ポートマッピング | コンテナ(3128) (ホスト側のポート指定はなし) |


### ECS(サービス追加)

タスクを元にECSにサービスを追加します。

パブリックIPをDISABLEDにすると、ECRからイメージが読み込めませんでした。
VPCエンドポイントを指定したりするなどが必要かもしれませんので、今後調査したいところです。

|パラメータ|値|
|:--|:--|
| 起動タイプ | FARGATE |
| タスク定義 | fuga-task |
| クラスタ | fuga-cluster |
| サービス名 | fuga-service |
| サービスタイプ | REPLICA |
| タスクの数 | 1 |
| デプロイ | ローリングアップデート |
| ロードバランサー | fuga-alb |
| セキュリティグループ | fuga-instance-sg |
| パブリックIPの自動割り当て | ENABLED |
| プロダクションリスナーポート | 80 |
| ロードバランス用のコンテナターゲット | fuga-target |
| AutoScaling | 無効 |

### 次

次はCI/CD周りです。
GitHubを二段階認証に変更したらやること

とあるプロジェクトでGitHubのログインを二段階認証にすることを求められたので変更した。色々エラーったのでメモ

# 要点

二段階認証に変更するとgitの通信プロトコルがhttpsからgitに変わる仕様になっているっぽい。httpsで通信してたなら設定の変更が必要。もともとgitなら気にしないでいいはず

# やること

#### SSH Keyの登録

まず`ssh -T git@github.com`で確認。うまくいかなかったら登録しなきゃ〜

そのへんはこの記事が詳しい
https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000
公式はたぶん[ここ](https://help.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)

でもなんか、 `~/.ssh/config`に書く内容が上記の記事ではおかしかったので[ここにあるように修正](https://kimiyuki.net/blog/2018/06/09/github-ssh-permission-denied/)

#### 既存Gitプロジェクトの接続先URLを変更

`.git/config`の設定をhttpsからgitへ変更する必要がある。

```
git remote set-url origin git@github.com:hoge/repo.git
```

晴れてgit通信ができるようになったんとちゃいますかね。でも毎回パスワード聞かれません？公開鍵の
こうすれば問題なくなるみたいです。

```
ssh-add ~/.ssh/id_rsa
```
https://qiita.com/gdtypk/items/172d42c10761f5ef2387

わーい