OmniAICreator/Qiita-1.07M huggingface dataset:
Chrome TLS 関連 TIPS

TLS 関連の Chrome の TIPS を 2 つほど紹介します。 (macOS で確認しています。 Windows など他 OS では挙動未確認)

## オレオレ証明書を一時的に信用する

正式な認証局の署名が入っていない、オレオレ証明書を使ったページに HTTPS でアクセスした場合、ブラウザがアクセスを拒否してきます。

証明書の期限切れなどの場合には、 Chrome では `Advanced` menu に `Proceed to xxx (unsafe)` link が出現するので、これを押せば進めます。

![chrome_tls_error_page_001.png](https://files.tearoom6.biz/fa7365e1-75ba-49a2-b310-bf763fdc4d9f.png)

しかし、不正な証明書などの場合で、これが出てこない場合があります。

![chrome_tls_error_page_002.png](https://files.tearoom6.biz/bb818339-8059-4914-bba3-85fab300d442.png)

(https://badssl.com/ っていうサイトで、いろいろな証明書の不具合のサンプルが置かれているので、それぞれどのような表示になるのか確かめてみるといいと思います)

このような場合 Chrome で対象のページを開いて、フォーカスがあたっている状態で、 `thisisunsafe` (現在最新の Chrome 83 の場合) とタイプしてください。
すると、あら不思議、ブロックが解除されて、ページに進めるようになります。

また、逆に、この bypass keyword による効果を解除したい場合は、ブラウザ URL 欄の "Not Secure" リンクをタップして出てくるダイアログ中の `Re-enable warnings` リンクをクリックすることで、この一時的な信用状態をリセットできます。

![chrome_site_information_dialog_001.png](https://files.tearoom6.biz/d27e71bf-c920-45e6-a189-602b38f10588.png)

なお、 masOS の場合だと Keychain Access にオレオレ証明書を登録する方法のほうが、よりよいのではないかと思います。その方法の解説は [開発環境の自己証明書をブラウザに信頼させる | スターフィールド株式会社](https://sterfield.co.jp/programmer/%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%81%AE%E8%87%AA%E5%B7%B1%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E4%BF%A1%E9%A0%BC%E3%81%95%E3%81%9B%E3%82%8B/) に譲ります。

ただし、その場合は、絶対に信用できない人にオレオレ証明書をバラまかないように注意してくださいねｗ

> References

- [ssl - Getting Chrome to accept self-signed localhost certificate - Stack Overflow](https://stackoverflow.com/questions/7580508/)
- [security - Does using 'badidea' or 'thisisunsafe' to bypass a Chrome certificate/HSTS error only apply for the current site? - Stack Overflow](https://stackoverflow.com/questions/35274659/)


## 現在アクセスしているページの証明書をローカルに保存する

Chrome で現在アクセスしている URL の証明書をローカルにダウンロードしたい場合、ブラウザ URL 欄の鍵マークをタップして出てくるダイアログで、 `Certificate` を選択します。

![chrome_site_information_dialog_002.png](https://files.tearoom6.biz/0b842f9c-dcb9-46d9-a1de-7e552b3a7aee.png)

すると、以下のようなダイアログが開くので、ここの証明書画像を macOS の場合 Finder (デスクトップとかでもいいです) に drag & drop してください。

![chrome_tls_certificate_dialog.png](https://files.tearoom6.biz/246f47fc-aa00-4c68-9dc1-41b794770202.png)

すると、あら不思議、証明書ファイルが、該当のディレクトリにダウンロードされます。

ちょっと操作方法がマニアックで他にも方法ありそうな気がするので、あったらぜひ教えてほしいです...!

> References

- [How to save a remote server SSL certificate locally as a file - Super User](https://superuser.com/questions/97201/)
【プログラミング初心者】Swift基礎~if文・switch文~

# はじめに
今回は条件判定のために必要な構文、**if文**と**switch文**の書き方について紹介します。
条件文は多少書き方の違いはありますがSwift以外の多言語全てで使用されるプログラムの基本構文の１つです。
この投稿で書き方をしっかりと覚えておいてください。

# 条件文とは
プログラムでは異なる条件毎に処理を分岐させアプリを制御します。

例えば現実的な例としてマンガアプリで考えてみます。
そのアプリで購入したマンガを表示する処理を実装するとしましょう　。
その場合マンガのページを表示するにはどのような条件が考えられるでしょうか？

対象のマンガは購入済みかどうか、未購入の場合は購入するためのアプリ内マネーが足りているかどうか、通信エラーが発生したかどうか、etc.
考え出すとキリがありませんが、こういった考えられる状況全てに対して条件分岐させそれぞれ異なった処理を実装していく必要があります。

こういった場合に条件文と呼ばれるif文やswitch文を使用して制御していきます。

# if文
それでは具体的な書き方を紹介していきます。
構文としては以下の通りです。

```swift
if 条件 {
    条件が真の場合の処理
} else {
    条件が偽の場合の処理
}
```
条件には`Bool`型を入れる必要があります。

`if`に与えた条件が`true`の場合最初の処理ブロックに入ります。
`false`となった場合は`else`の処理ブロックに入りそれぞれの処理を実行します。
またそれぞれの処理ブロックはどちらか片方しか実行されず、`if`に入った場合`else`は実行されません。

条件は`Bool`であれば変数、メソッド、式と何でも構いません。

```swift
// 変数
let boolValue = true
if boolValue {
    print("boolValue is true")
} else {
    print("boolValue is false")
}
// 式
let intValue = 1
if intValue == 1 {
    print("intValue is 1")
} else {
    print("intValue is not 1")
}
// メソッド
func boolFunction() -> Bool {
    return true
}

if boolFunction() {
    print("boolFunction() is true")
} else {
    print("boolFunction() is false")
}
```
`else`は必須ではなく`if`のみでも使用できます。

```swift
if value > 0 {
    print("０より大きい")
}
```
また`if`文同士繋げることも可能です。

```swift
if value > 10 {
    print("10より大きい")
} else if value < 10 {
    print("10より小さい")
} else {
    print("それ以外")
}
```
条件は`Bool`あればいいので、論理演算子を使って複数の条件を組み合わせることができます。

```swift
if value >= 0 && value < 10 {
    print("0以上10未満")
} else {
    print("それ以外")
}
```

# switch文
Swiftの`switch`はかなり汎用性が高く、数多くの書き方があります。
今回は基本となる書き方のみを紹介します。

基本構文は以下となります。

```swift
switch 値 or 式 {
case 値１:
    値１の場合の処理
case 値2:
    値2の場合の処理
...
default:
    caseに当てはまらなかった場合の処理
}
```

具体的な実装は以下のようになります。

```swift
let value = 0
switch value {
case 0:
    print("0です。")
case 1:
    print("1です")
case 2:
    print("2です")
default:
    print("それ以外です")
}
```
このように`switch`に与えた値`value`に対して判定を行ないます。
`if`との違いは条件ではなく値そのものに対する判定ということです。

当てはまる`case`から次の`case`までの間の処理が実行されます。
それ以外の処理は実行されません。
（他言語を触った人からすると`break`がないのに次が実行されないことに違和感があるかもしれません。Swiftでは`break`は不要です。）

`switch`に与える型は値の判定ができれば構いません。
とはいえ値の判定ができるのは数値型、文字列型、列挙型くらいで、現実的に使うのはこのあたりの型になるかとは想います。

１つの`case`に複数指定することも可能です。

```swift
let club = "野球"
switch club {
case "野球", "サッカー", "テニス":
    print("運動部です")
case "吹奏楽", "茶道":
    print("文化部です")
default:
    print("未定義の部活です")
}
```
また数値の場合`(数値1…数値2)`とすることで範囲によって条件を分岐させることも可能です。

```swift
let score = 80
switch score {
case (80...100):
    print("優")
case (70...79):
    print("良")
case (60...69):
    print("可")
case (0...59):
    print("不可")
default:
    print("未定義")
}
```
以上のように値に対して判定を行ない、当てはまる`case`の処理を実行するのが`switch`文です。
いくつか例を紹介しましたがまだまだ使い方は色々あります。
条件判定する際は調べてみてください。

# 最後に
今回はプログラミングする上では欠かせない条件分岐の方法として`if`と`switch`を紹介しました。
どちらも似たようなものですね。
実際`switch`を`if~else if~...`と条件分岐を行っても同じ結果が得られます。
プログラムを管理しやすい方、ミスが起きにくい方を状況に応じて選んでいきたいところです。

今回の内容は以上です。
本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載は以下にまとめていますのでそちらも是非もご覧ください。
http://naoyalog.com/
Amazon Rekognition とは

#Amazon Rekognition とは
> Amazon Rekognition では、イメージ分析とビデオ分析をアプリケーションに簡単に追加することができます。Amazon Rekognition API にイメージやビデオを指定するだけで、このサービスによってモノ、人物、テキスト、シーン、アクティビティを識別できます。不適切なコンテンツも検出できます。Amazon Rekognition は、高精度な顔分析、顔比較、および顔検索機能も備えています。顔の検出、分析、比較は、ユーザー検証、カタログ作成、人数計数、公共安全など、多岐にわたって活用できます。

##Amazon Rekognition の仕組み
> Amazon Rekognition には 2 つの API セットがあります。Amazon Rekognition Image はイメージ分析に、Amazon Rekognition Video はビデオ分析に使用します。

#センサー、入力イメージ、ビデオのベストプラクティス
##Amazon Rekognition Image オペレーションのレイテンシー
> イメージが含まれている Amazon S3 バケットのリージョンと Amazon Rekognition Image API オペレーションで使用するリージョンが一致している必要があります。
> イメージのバイトを使用した Amazon Rekognition Image オペレーションの呼び出しは、イメージを Amazon S3 バケットにアップロードしてから、アップロードされたイメージを Amazon Rekognition Image オペレーションで参照するよりも高速です。
> イメージがすでに Amazon S3 バケットにある場合、Amazon Rekognition Image オペレーションで参照すると、イメージのバイトをオペレーションに渡すよりも高速になる可能性があります。


イメージのバイトを使用した Amazon Rekognition Image オペレーションの呼び出し > イメージを Amazon S3 バケットにアップロードしてから、アップロードされたイメージを Amazon Rekognition Image オペレーションで参照する
【AWS SAP】ブルーグリーンデプロイメント【予備知識編】

##AWS SAP取得に向けて予備知識としてあった方が良いもの

・ブルーグリーンデプロイメント

##ブルーグリーンデプロイメントとは
ブルーとグリーンという2つの環境を用意する。
ルーティングは片寄しておく。
例えば、ブルー側でサービスが本番稼働している場合、もう1つの環境（グリーン）で新しいアプリケーションをデプロイし、ルーティングの向け先をグリーンに振り向けることでバージョンアップを行うという手法のこと。

問題が発生した場合は、ルーティングの向け先を戻し切り戻しを行います。

以下サイトの内容が非常に分かりやすかったです。
https://www.google.co.jp/amp/s/cloudpack.media/25426/amp
Pythonでしりとりゲームを作ってみる

# まずは出来そうなところから書いてみる
```python:shiritori.py
#しりとりができるプログラムを書いていく
#一応確認のため、しりとりは単語の最後の一文字から始まる単語を言い合うゲーム
#勝敗は単語の最後の一文字が「ん」の単語を言ったプレイヤーが負けとなる
#つまり勝つ方法は相手が負けるのを待つということになる
#違う言い方をするならばボキャブラリーが豊富な方が勝ちやすいということになる

print("しりとりゲームスタート！")

#入力した単語の最後の一文字を取得する処理
str = input()
print(str[len(str) - 1])
```
# 次に実装すべき処理は？
- 取得した最後の一文字を頭文字にして相手が単語を発する
- また自分が単語を入力する
- 上記２つを「ん」がつくまでループさせる

# 現時点で想定される課題
- 辞書をどう用意するのか
- 相手（CPU）がどのタイミングで負けてくれるのか
- 普通のしりとりで終わらない何かしらの要素は？

# 今後の予定
- とりあえず考え中です・・・
【AWS SAP】Amazon Workdocs【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第13弾
以下サービスについて覚えておいて損はありません。

・Amazon Workdocs

##Amazon Workdocsとは
コンテンツの作成、編集、共有が可能。
Workdocsアカウントを持たないユーザに対しては、ReadOnlyで共有できます。

イメージとしては、dropboxやboxのようなサービスです。

(以下、公式サイトより)
> Amazon WorkDocs はコンテンツの作成、ストレージ、コラボレーション用の安全なフルマネージド型サービスです。Amazon WorkDocs を使用すると、コンテンツの作成、編集、共有が簡単になります。また、AWS 内に一元管理で格納されるため、どこからでも、どんなデバイスからでもアクセスできます。Amazon WorkDocs では他のユーザーとのコラボレーションが容易になり、コンテンツ共有、豊富なフィードバックのやりとり、文書の共同編集を簡単に行えます。また、Amazon WorkDocs を使用してファイル共有をクラウドに移行することにより、古いファイル共有インフラストラクチャを不使用にすることができます。Amazon WorkDocs はお客様の既存システムと統合可能なうえ、豊富な API が利用できるため、独自のリッチなコンテンツを持つアプリケーションの開発が実現できます。Amazon WorkDocs は AWS 上にビルドされるため、お客様のコンテンツは世界最大のクラウドインフラストラクチャで保護されます。
Salesforceでチャット部屋作ってみた

# 今回の目的
　変更データキャプチャを使用すればSalesforceのデータの作成・更新をリアルタイムで受け取れるというのを知ったので、試してみるついでにチャット部屋を作ってみました。

#できたもの
<img width="957" alt="pic1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/3904090e-499c-8d8f-bfdc-53824c21906f.png">
<img width="956" alt="pic2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/36479ff3-51c6-b430-6376-09b15b731b34.png">
<img width="958" alt="pic3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/c5b71504-6447-fe58-ff8b-76aa3ada6f3c.png">
<img width="959" alt="pic4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/c7c05c2b-03c4-5667-04e6-76f6ed39fc89.png">

画面録画のソフトの関係上、1タブしか録画ができないので、Gifは1ユーザの画面のみ
![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/bc0468e9-1149-6413-150d-676977b787dc.gif)



このようなチャットの画面を作ることが出来ました。
ユーザー側は画面の更新など、操作を完全に行わなくとも別ユーザからのメッセージを受信できます。
仕組みとしては
1.送信でメッセージレコードをデータベースInsertする
2.変更データキャプチャでデータベースの変更をキャッチする
2.JSの処理実行
という仕組み出来ております。

#結論
　意外と簡単に作成することが出来ました。データベースの変更をリアルタイムで検出して、動かせるのはかなりいいですね。今後、いろいろなものに活かせるような気がします。

###参考
[変更データキャプチャと非表示ユーリティティ項目を用いてプッシュ通知を実現する](https://qiita.com/shunkosa/items/176a6d9bc4d482f46f25)
【AWS SAP】AWS Discovery Service【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第12弾
以下サービスについて覚えておいて損はありません。

・AWS Discovery Service

##AWS Discovery Serviceとは
オンプレミスで稼働しているサーバの各情報を取得し、アセスメント・分析を行うための支援をしてくれる。

移行時、情報収集に苦労する場合があるがADSを利用すると楽に情報収集が可能です。

・収集したデータはAWSのDBに安全に保持
・データを収集するにあたりエージェントのタイプが2つある

＊エージェントレス
osパッケージなどは取得不可。

＊エージェントベース
サーバにエージェントをインストールし、情報を収集。サーバ上の詳細な情報(パッケージ、プロセス、ネットワーク通信など)を収集できます。
1つの母集団から抽出した標本から，母平均μ，母分散σを推定する方法



  

# １．この記事でまとめたいこと

1つの母集団から無作為にn個の標本を抽出し，その標本から母集団の母数（平均$\mu$や分散$\sigma^2$）の区間推定を行う方法。絵でいうと下記。
<img width="400" alt="1_mission.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/39a7dfff-35fc-40dc-6f12-6831e4dbab91.png">

  

# ２．まとめた背景

参考書などで勉強していたところ，下記のような色々なケースの区間推定の方法が出てきた。

   -  母集団の分布・・・既知／未知 
   -  母分散・・・既知／未知 



それぞれのケースで，新たに定義する確率変数や，その確率変数が従う分布（標準正規分布/t分布/カイ二乗分布）が異なっており，覚えられなかった。まとめていくと，**共通する考え方**が見えてきた。


  

# ３．共通する考え方

どれもこの①～③の流れで区間推定を行っている。
<img width="400" alt="3_CommonFlow.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/124f7e33-4a70-e8ff-a173-18d63ba46c11.png">


# ４．各ケースと共通する考え方に照らし合わせると


下図のように，全て共通する考え方で，区間推定を行うことができる。赤字がポイントだと思う。
図中の★部分は，５章で記載する。


  <img width="" alt="4_practice.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/425e9b02-6754-61b5-fb0a-0722e020425e.png">

  

# ５．４章の図中の★部分についての説明

## ５．１．★１について


対比を取ると，このような感じになる。
  <img width="" alt="5_1_chi.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/c3124edd-31d2-218e-798f-3b6ef0768589.png">


標本平均を使うとなぜ自由度が1下がるのかについては，下記サイトで理解することができた。
@takayan4さん教えていただきありがとうございました。

・高校数学の美しい物語
https://mathtrain.jp/chinijoproof




## ５．２．★２について
  
<img width="600" alt="5_2_t.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/44fcdf4e-2317-8dc2-d1b2-52ac668f76f1.png">

# ６．おまけ（確率密度関数）


関連する確率密度関数をMATLABでプロットしてみた。
本コードを実行するには，Statistics and Machine Learning Toolboxが必要です。



## ６．１．正規分布とt分布


t分布の自由度を増やすと，標準正規分布に近づいていく。
これは，nが大きくなると，不偏分散が母分散に近づいていくため。



```matlab:Code
xrng = [-3,3];
fplot(@(x) normpdf(x,0,1),xrng,'DisplayName','Standard Normal Distribution') % 標準正規分布
hold on
fplot(@(x) tpdf(x,5),xrng,'DisplayName','t Distribution with \nu=5')      % 自由度5のt分布
fplot(@(x) tpdf(x,10),xrng,'DisplayName','t Distribution with \nu=10')    % 自由度10のt分布
legend
hold off
```

![figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/aec92cae-a095-26d1-4af0-a885d00f1e61.png)




## ６．２．カイ二乗分布

```matlab:Code
xrng = [0,20];
fplot(@(x) chi2pdf(x,1),xrng,'DisplayName','\nu=1') %自由度1のカイ二乗分布
hold on
fplot(@(x) chi2pdf(x,2),xrng,'DisplayName','\nu=2') %自由度2のカイ二乗分布
fplot(@(x) chi2pdf(x,3),xrng,'DisplayName','\nu=3') %自由度3のカイ二乗分布
fplot(@(x) chi2pdf(x,5),xrng,'DisplayName','\nu=5') %自由度5のカイ二乗分布
fplot(@(x) chi2pdf(x,10),xrng,'DisplayName','\nu=10') %自由度10のカイ二乗分布
legend
hold off
```


![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614756/80440b28-4dfe-1f00-de70-0f070412de84.png)



# ７．参考文献


・マセマ出版社　統計学キャンパス・ゼミ 改訂5
https://www.mathema.jp/product/統計学キャンパス・ゼミ-改訂5/

・ヨビノリ　確率統計　推定・検定入門
https://www.youtube.com/playlist?list=PLDJfzGjtVLHmx7qMP410-9gx0weC9d90X

・高校数学の美しい物語
https://mathtrain.jp/chinijoproof
【AWS SAP】AWS SQS FIFO【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第11弾

以下のサービスについて覚えておいて損はありません。

・AWS SQS FIFO

##AWS SQS FIFOとは
重複削除、単一実行、順序取得に対応。

FIFOでないSQSでは以下のデメリットがある。
・順番が保証されない
・メッセージが重複する可能性がある
・呼び出し側が2回呼んだら、2回実行しちゃう

一方で、FIFOキューでは、
・順番が保証される
・複数回実行しません
・同じ呼び出しをしたら削除します。

(以下、公式サイトより)
> FIFO (先入れ先出し) キューは、オペレーションやイベントの順序が重要である場合、または重複不可の場合などにアプリケーション間のメッセージングを強化します。たとえば、次のような場合です。
ユーザーが入力したコマンドが正しい順序で実行されていることを確認します。
価格の変更を正しい順序で送信して、正しい製品価格を表示します。
アカウントを登録する前に受講者がコースに登録できないようにします。
FIFO キューはまた、1 回だけの処理を提供しますが、1 秒あたりのトランザクション (TPS) は制限されます。
GitHub Actions APIでJobを再実行する

GitHub ActionsのAPIを利用してJobを再実行する方法を解説します。

手順としては

1. アクセストークンを発行する
2. cURLコマンドでURLへPOSTする

になります。

実際に動いているリポジトリは[こちら](https://github.com/ansible-roles-matsumura/sl)です。


## このエントリーの意図

GitHub Actions APIでWorkflow rerunが動かない人向けです。[Workflow runs | GitHub Developer Guide](https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow)

## アクセストークンを発行する

「**プロフィールアイコン**」→「**Settings**」→「**Developer settings**」→「**Personal access tokens**」→「**Generate new token**」




<img width="1920" alt="スクリーンショット 2020-06-03 21.55.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/497313e0-4b21-7db5-2fda-2908599fa3e1.png">
<img width="1920" alt="スクリーンショット 2020-06-03 21.58.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/5f9e1497-013c-317b-e177-786fb5a0480f.png">
<img width="1920" alt="スクリーンショット 2020-06-03 22.00.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/d42c4ca7-20fe-b470-a1c3-a6d619979e66.png">
「**repo**」と「**workflow**」にチェックを入れ「**Generate token**」をクリックする
<img width="1920" alt="スクリーンショット 2020-06-03 22.08.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/c7e9e7a4-65c6-6722-c641-88b2c0d4a99c.png">
<img width="1920" alt="スクリーンショット 2020-06-03 22.09.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/a6dbf886-1296-6d64-4092-bc9d75c97fe8.png">
<img width="1920" alt="スクリーンショット 2020-06-03 22.06.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/f8cbcbef-6000-c825-8517-54c64cd313b6.png">


## GitHub Actionsを実行するファイル


「on」エレメントに「deployment」を指定します。push時にもWorkflowを実行したい場合は両方記述しておきます。

```yaml:.github/workflows/test.yml
---
name: trailing whitespace
on: [deployment, push]

jobs:
  trailing-whitespace:
    name: Find Trailing Whitespace
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: harupy/find-trailing-whitespace@master
```

## Workflowを再実行する

以下のコマンドで実行します。

```console
curl -X POST \
  -H "Authorization: token xxxxxxxxxxxxxxxx" \
  -d '{"ref": "master", "environment": "periodic execution"}' \
  https://api.github.com/repos/${username}/${reponame}/deployments
```

コマンドの詳しいオプションは[Deployments | GitHub Developer Guide](https://developer.github.com/v3/repos/deployments/)で確認する事ができます。

## 参考サイト

- [テストだけでなく、デプロイもGithubで！SlackとGithub Deploymentを使ったGithub Actionsの実行方法 - Qiita](https://qiita.com/sadayuki-matsuno/items/91789798e062b881bc00)
- [Deployments | GitHub Developer Guide](https://developer.github.com/v3/repos/deployments/)
- [Workflow runs | GitHub Developer Guide](https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow)
- [ansible-roles-matsumura/sl | GitHub Actions](https://github.com/ansible-roles-matsumura/sl)
【AWS SAP】AWS EBSのタイプ【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第10弾
以下の違いについて覚えておいて損はありません。

・プロビジョンド IOPS SSD
・スループット最適化 HDD
・最適化インスタンス

##プロビジョンド IOPS SSDとは
I/Oの性能を保証する。

(以下、公式サイトより)
> プロビジョンド IOPS SSD (io1) ボリュームは、ランダムアクセス I/O スループットにおけるストレージパフォーマンスと整合性が重要な、I/O 集約型ワークロード (特にデータベースワークロード) のニーズを満たすように設計されています。バケットとクレジットのモデルを使用してパフォーマンスを計算する gp2 とは異なり、io1 ボリュームでは、ボリュームの作成時に一定の IOPS レートを指定できます。Amazon EBS は、プロビジョンドパフォーマンスを 99.9% 提供します。

##スループット最適化 HDDとは
SSDほどの性能を必要とせず、コスト削減したい場合に利用。

(以下、公式サイトより)
> スループット最適化 HDD (st1) ボリュームは、IOPS ではなくスループットでパフォーマンスを示す、低コストの磁気ストレージに使用できます。このボリュームタイプは、Amazon EMR、ETL、データウェアハウス、ログ処理など、サイズの大きなシーケンシャルワークロードに適しています。ブート可能な st1 ボリュームはサポートされていません。

##最適化インスタンスとは
EC2-EBS間通信において、独立した帯域を確保。他のトラフィックの影響を受けない。

(以下、公式サイトより)
> Amazon EBS– 最適化インスタンスは、最適化された設定スタックを使用し、Amazon EBS I/O に対して追加の専用の容量を提供します。この最適化は、Amazon EBS I/O とその他のインスタンスからのトラフィック間の競合を最小化することで、EBS ボリュームの高パフォーマンスを提供します。
EBS 最適化インスタンスは、Amazon EBS に専用の帯域幅を提供します。EBS 最適化インスタンスにアタッチした場合、汎用 SSD (gp2) ボリュームは、対応するベースラインパフォーマンスとバーストパフォーマンスを 99 % の時間で実現するように設計されています。また、プロビジョンド IOPS SSD (io1) ボリュームは、対応するプロビジョンドパフォーマンスを 99.9 % の時間で実現するように設計されています。スループット最適化 HDD (st1) と Cold HDD (sc1) の両方で、99% の時間はバーストスループットの 90% のパフォーマンス安定性が保証されます。毎時間、予測合計スループットの 99% 達成を目標に、準拠しない期間はほぼ均一に分散されています。
【Raspi4；サウンド入門】pythonで音入力を安定して記録する♪

音入力は何度か取り上げてきたが、今回Rasipi4でも安定してずーっと入出力出来るようになったので、まとめることとしました。
肝心なことは以下の参考1.のとおりです。なお、昨年は参考2.のようなことやって遊んでいました。
今年はこのあと少し違うことやろうと思っています。
【参考】
1.[PyAudio Input overflowed](https://stackoverflow.com/questions/10733903/pyaudio-input-overflowed)
2.[【Scipy】FFT、STFTとwavelet変換で遊んでみた♬～⑦リアルタイム・スペクトログラム；高速化](https://qiita.com/MuAuan/items/6c2ab8497409bac6304e)

###肝心なこと
つまり、読み込むとき以下のおまじないを記載するとオーバーフローが発生しなくなり、延々記録できるようになりました.
※この記事はRasipi4でもこれが解決できたというお話です

```py
# -*- coding:utf-8 -*-
import pyaudio
import matplotlib.pyplot as plt
import numpy as np
import wave
import struct
```
読み込んだ音を以下の関数でwavファイルで保存する。

```py
def savewav(sig,sk):
    RATE = 44100 #サンプリング周波数
    #サイン波を-32768から32767の整数値に変換(signed 16bit pcmへ)
    swav = [(int(32767*x)) for x in sig] #32767
    #バイナリ化
    binwave = struct.pack("h" * len(swav), *swav)
    #サイン波をwavファイルとして書き出し
    w = wave.Wave_write("./wine/"+str(sk)+".wav")
    params = (1, 2, RATE, len(binwave), 'NONE', 'not compressed')
    w.setparams(params)
    w.writeframes(binwave)
    w.close()
```
音の入出力をTrueにしています。
音声（センテンス）を入力するので、長め（102400/44100＝2.3sec）に録音します。

```py
RATE=44100
p=pyaudio.PyAudio()
N=100
CHUNK=1024*N
stream=p.open(format = pyaudio.paInt16,
        channels = 1,
        rate = RATE,
        frames_per_buffer = CHUNK,
        input = True,
        output = True) # inputとoutputを同時にTrueにする
```
そしていよいよ連続録音開始です。exception_on_overflowをFalseにしています。sigを32768で除しています。

```py
sk=0
while stream.is_active():
    input = stream.read(CHUNK, exception_on_overflow = False)
    print(len(input))
    sig =[]
    sig = np.frombuffer(input, dtype="int16") / 32768
    savewav(sig,sk)
    fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 4, 4*2))
    lns1=ax1.plot(sig[0:1024] ,".-",color="red")
    ax1.set_xticks(np.linspace(0, 882, 3))
    ax1.set_ylabel("sig0")
    ax1.set_title('short plot')
    lns2=ax2.plot(sig[0:CHUNK], "-",color="blue")
    ax2.set_xticks(np.linspace(0, 44100*2, 5))
    ax2.set_ylabel("sig1")
    ax2.set_title('long plot')
    ax1.grid()
    ax2.grid()
    plt.pause(0.5)
    plt.savefig("./wine/sound_{}.png".format(sk))
    plt.close()
    sk+=1
    output = stream.write(input)
```
あー、えー、いー。。の連続測定結果
x-軸のメモリ；４４１００=１sec
![sound_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/8e040d7f-30ec-fe38-ac5b-5d8a8953e94f.png)
![sound_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/adee2abe-db2c-082e-5797-9037b1199760.png)
###まとめ
・連続測定が可能になった

・音関係でR-python連携をしたいと思う
Macの日本語キーボード環境でのAlacrittyの文字サイズ拡大ショートカットについて

## デフォルトキーバインドの確認
デフォルトでは`Cmd-=`にショートカットが割り当てられていると思うのですが、
おそらくMacの日本語キーボード環境でAlacrittyの文字サイズ拡大が設定変更なしだとできません。

```
|         Key0,     ModifiersState::CTRL;  Action::ResetFontSize; |
|         Equals,   ModifiersState::CTRL;  Action::IncreaseFontSize; |
|         Add,      ModifiersState::CTRL;  Action::IncreaseFontSize; |
|         Subtract, ModifiersState::CTRL;  Action::DecreaseFontSize; |
|         Minus,    ModifiersState::CTRL;  Action::DecreaseFontSize; |
```

https://github.com/alacritty/alacritty/blob/49a1ac96f4a1bcd40af0ed4f89e92aa8f74077db/alacritty/src/config/bindings.rs#L474-L488

間違えて文字サイズ小さくした時(`Cmd--`)は、`Cmd-0`で文字サイズリセットでも事足りますが、
モニターの解像度が変わったときなど、やはり拡大はできたほうがいいですよね。
（外部キーボードを使っている場合にはAddキーを使うのもありですが...）

## 設定追加
下記のようにalacritty.ymlに設定を追加すると`Ctrl-=`でも拡大ができるようになります。

```
key_bindings:
  - { key: Minus,   mods: Command|Shift, action: IncreaseFontSize }
```

日本語キーボードのShiftを押した状態のMinus(`-`)キーは`=`なので、これで`Cmd-=`が効くようになります。
Alacritty側に改善してもらいたいところですが、一旦はこれでも大丈夫そうです。
アウトプットの力

#Qiitaにとにかくアウトプットしてしまえ
アウトプットを前提としたインプットでこれだけ変わる。
　・アウトプットするだけで、記憶に残る
　・自分の記事を相手に伝えるため表現力が鍛えられる
　・誰にも迷惑かけないhttps://qiita.com/qiitadaisuki/items/2160a390ce91283707a1

#そうわ言っても、躊躇してしまう
登録して記事を書くまで1時間。毎日人はたくさんの知らないことにぶつかり、なやみ、発見をしていく。それを成長というのであれば、そうもとらえられる。ひたすらゲームすることも、映画を見ることも、youtubeで時間をつぶすことも、ドラマやテレビを楽しむことも悪くない。間違いじゃない。

人は何のために生きるのか。仕事に追われる私たちは、書くことで考えを整理できることもある。

#話そう、雑談しよう、コミュティを作ろう
さぁ、あなたが思っている以上に、人はあなたのことなどどうでもいい。あなたに何があっても助けないし、あなたが死のうとかまわない。本当に親密になっている関係は家族や、親友のごく数人だ、このネットワークの世界でつながっている気になっている暇つぶし集団を相手にしている暇はない。さぁ世界を飛び出して、新しい世界に入っていこう。
【Swift】KVOでUserDefaultsの値の変更を監視する

## KVOとは
KVO(Key Value Observing)の略名になります。
その名の通り、オブジェクトの値を監視する為に用いる技術です。
値の更新や削除などの変更を検知することができとても便利です！

## UserDefaultsの値の変更を監視する
`UserDefaults`の値を`dynamic`で取得する

```swift
// 今回はIntの値を扱っています
extension UserDefaults {
    @objc dynamic var translateLimit: Int {
        return integer(forKey: keyName)
    }
}
```

監視する処理

```swift
var observer: NSKeyValueObservation?

private func setKVO() {
    observer = UserDefaults.standard.observe(\.translateLimit, options: [.initial, .new], changeHandler: { [weak self] (defaults, change) in
        // 行いたい処理を書く
    })
}
```

これで監視の処理は完了！
簡単だしとても便利。

#### 補足
`@objc dynamic`で宣言したKeyの名前と、UserDefaultのKeyの名前が一致しないと、値を参照できず正常に動きません。
Googleのクライアントライブラリをimportしているプログラムをpyinstallerで.exe化する

Google Speech to Textを使ったプログラムを.exe化する必要があったのだが、ハマったのでメモ。
 
#環境
OS Windows10
(pipenvにて)
Python 3.7.4
pyinstaller 3.6

#実行したコマンド
***test.pyを.exe化する。***と仮定すると、

```
pyinstaller test.py --onefile
```

#ERROR1
まず、普通に実行すると以下のようなエラーが出る

```
pkg_resources.DistributionNotFound: The 'google-cloud-core' distribution was not found and is required by the application
```

このエラーに関しては起動時に`--additional-hooks-dir`オプションを使用して、以下のようなファイルを作成し、フォルダへのパスを与えれば解決する。というような記事をよく見かけるが、***自分の環境では解決しなかった。***

```hook-google.cloud.py
from PyInstaller.utils.hooks import copy_metadata
try:    datas = copy_metadata('google-cloud-core')
except: datas = copy_metadata('google-cloud-speech')
```

↓このエラーが出る

```
    assert self.hook_module_name not in HOOKS_MODULE_NAMES
AssertionError
```



この問題に関しては普通に、google-cloud-coreを改めてインストールすると解決した。。。

```
pip install google-cloud-core
```

#ERROR2
google-cloud-coreをインストールしたあとは、実行出来て.exeも生成されるのだが、生成された.exeを実行すると今度は以下のようなエラー(というかException?)が出る。

```
Exception ignored in: 'grpc._cython.cygrpc.ssl_roots_override_callback'
E0603 18:31:14.600000000 16632 src/core/lib/security/security_connector/ssl_utils.cc:482] assertion failed: pem_root_certs != nullptr
```

ライセンスの認証周りっぽい。
こちらは、test.pyと同階層にhooksというフォルダを作成し、その中に以下にようなファイルを作成して設置したとすると、

```hook-grpc.py
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('grpc')
```

以下のようなコマンドでビルドしなおせば出なくなる

```
pyinstaller test.py --onefile --additional-hooks-dir=./hooks/
```

#参考
https://github.com/pyinstaller/pyinstaller/issues/3935
https://teratail.com/questions/201443
https://teratail.com/questions/118297
https://qiita.com/akitooo/items/eb82a5f335d8ca9c9faf
https://stackoverflow.com/questions/54634035/my-pyinstaller-is-giving-assertion-error-when-i-execute-it
https://stackoverflow.com/questions/40076795/pyinstaller-file-fails-to-execute-script-distributionnotfound
https://www.bountysource.com/issues/86848733-pyinstaller-3-6-assertionerror
https://github.com/googleapis/google-cloud-python/issues/5774
【AWS SAP】Route53の4つのルーティングポリシー【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第9弾
以下の違いについて覚えておいて損はありません。

・加重ラウンドロビン
・レイテンシーベースルーティング
・位置情報ルーティング
・フェイルオーバールーティング


##加重ラウンドロビンとは
各レコードに重み付けをし、任意の名前に対するクエリに指定された比率で異なる値を応答。

##レイテンシーベースルーティングとは
クライアントが任意の名前にアクセスした際、レイテンシーが小さくなるような近場のリージョンから応答。

##位置情報ルーティングとは
クライアントのIPアドレスを元に、チリデータベースでクライアントの接続地域を特定。
地理的に近い場所から応答。

##フェイルオーバールーティングとは
ヘルスチェックでNGだった場合に、冗長構成であれば片寄するといったことが可能。

参考)
ルーティングポリシーの選択
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/routing-policy.html
S3に保存されているgz圧縮されたjson形式ログを確認する

# 概要
アプリケーションログやDBログなどS3にgz形式で保存した場合のログの確認方法についてまとめます。

# 前提
- AWS CLIが使用できる

本記事ではバケット内のファイルをダウンロードしておりますが、jsonなどのテキストファイルであればS3 SelectやAthenaも選択肢に入れておくと良いです。

# 今回使用するもの
AWS S3
ターミナルなどの

# 方法
## 1. ダウンロードする

`ダウンロードする前にダウンロードしたいフォルダに移動しておきましょう。`

### まずはS3内のバケットを確認

```
aws s3 ls
```

下記のようにバケットが表示されます

```
2020-01-17 20:36:54 バケットA
2020-01-17 21:42:54 バケットB
```

### ダウンロード

```
aws s3 sync s3://バケットA ./
```
バケットAの中身全てローカルにダウンロードされます

## 2. ログを確認する

```
find {フォルダA} -type f | xargs gzcat | jq | grep [検索したい文字列]
```

gz圧縮、json形式
などのファイルであれば使用できると思います

### コマンド解説

- find {フォルダA} -type f
    - フォルダA以下のファイルを取得
- xargs
    - `コマンドA | xargs コマンドB` → コマンドAの結果をコマンドBに渡す
- gzcat
    - gz形式を解凍
    - ここではfindで取得したgz形式のファイルを解凍している
- jq
    - json形式であればきれいに整形してくれる
    - [こちらを参考](https://qiita.com/bunty/items/a769ebabbdd324ff0d6f)
- grep
    - 最後は検索したワードで絞りこみ
【プログラミング】吾輩は関数である名前はまだない


# はじめに

この記事ではチョットキニナル
プログラミングワードについて書いています。

--------------------------------

# ラムダ式

初めてラムダ式と聞いて
ピンと来ませんでしたが
ラムダ式とは要するに

「無名関数」を表現する為の
書き方のことである。

--------------------------------
# 無名関数

英語だといろんな呼び名があるみたいです。

nameless function
anonymous function

--------------------------------

# 無名関数とは

その名の通り
***名前を持たない状態で定義される関数のこと***

通常の関数の場合は以下のような定義方法を使うと思う。
PHPで例を出すと

``` PHP
<?php
  function add($args1, $args2) {
    return $args1 + $args2
  }
  $result = add(1,2);
  echo $result;
  //3
?>
```

--------------------------------

# 無名関数で定義すると

名前がない状態で定義されるが
変数に代入したときに関数オブジェクトに化ける。  
この時初めて関数名を持つことができる。

``` php
<?php
  $add = function ($args1,$args2){
      return $args1 + $args2;
  };

  $result = $add(1,2);
  echo $result;
  //3
?>
```

--------------------------------

# どんなときにつかう

周りを見渡す限りでは
**主にイベントプロシージャに使われている。**
ような気がする。

というのも
イベントプロシージャは別で定義するより
すぐその場で書いてしまったほうが
よかったりする。

C#では
コマンドボタンオブジェクトに
イベント登録を行うとき使う。

--------------------------------
# 使うことのメリット

・関数を定義しないのでコンパクトであること
・定義済の関数名に依存しないこと
・コールバック関数として利用しやすいこと

--------------------------------
# まとめ

今回はラムダ式について書きました。
うまく扱えれば
ベーシックな関数定義を増やすことなく
関数を定義できます。
ただ、増やしすぎても
保守上の観点からはとても良くないので
適切に扱いましょう。

# 訂正
【無名関数で定義すると】の
関数閉包の例として取り上げたコードについて


「こういった処理を**クロージャ（関数閉包）**という。変数に関数を包み込むという感じかな。」

と記載させていただきましたが
関数閉包の場合は関数オブジェクトを返して
変数に代入する場合でした。

ご指摘くださった方(https://qiita.com/tadsan)
誠にありがとうございました。

--------------------------------
# 参考資料
[ラムダ式 (C# プログラミング ガイド)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions)

--------------------------------
#おわり
--------------------------------
PRML　演習問題 3.5（基礎）　解答 

## 問題
>付録Eに示したラグランジュ未定乗数法を用いて、正則化誤差関数(3.29)の最小化と、正則化されていない二乗和誤差(3.12)の制約条件(3.30)下での最小化が等価であることを示せ。そして、パラメータ$\eta$と$\lambda$の関係を議論せよ。

## 解答
正則化誤差関数

```math
\begin {align*}
\frac{1}{2} \sum_{n=1}^{N}\left\{t_{n}-\mathbf{w}^{\mathrm{T}} \boldsymbol{\phi}\left(\mathbf{x}_{n}\right)\right\}^{2}+\frac{\lambda}{2} \sum_{j=1}^{M}\left|w_{j}\right|^{q}
\tag{3.29}
\end {align*}
```  

(3.29)を最小化することと、

```math
\begin {align*}
E_{D}(\mathbf{w})=\frac{1}{2} \sum_{n=1}^{N}\left\{t_{n}-\mathbf{w}^{\mathrm{T}} \boldsymbol{\phi}\left(\mathbf{x}_{n}\right)\right\}^{2}
\tag{3.12}
\end {align*}
```  

```math
\begin {align*}
\sum_{j=1}^{M}\left|w_{j}\right|^{q} \leqslant \eta
\tag{3.30}
\end {align*}
```  

正則化されていない二乗和誤差(3.12)を制約条件(3.30)の下で最小化することは等価であることを示せばよい。
まず、(3.30)は式を変形してやると、

```math
\begin {align*}
\ - \frac{1}{2}\left(\sum_{j=1}^{M}\left|w_{j}\right|^{q}-\eta\right) \geq 0 \\
\tag{3.30.1}
\end {align*}
```  

と書き直すことができる。(3.12)を(3.30.1)の条件下で最小化することはラグランジュの未定乗数法を用いると、

```math
\begin {align*}
L(\mathbf w, \lambda) = \frac{1}{2} \sum_{n=1}^{N}\left\{t_{n}-\mathbf{w}^{\mathrm{T}} \boldsymbol{\phi}\left(\mathbf{x}_{n}\right)\right\}^{2} + \frac{\lambda}{2}\left(\sum_{j=1}^{M}\left|w_{j}\right|^{q}-\eta\right)
\tag{ex3.5.1}
\end {align*}
```  

```math
\begin {align*}
\left\{\begin{aligned}
-\frac{1}{2}\left(\sum_{j=1}^{M}\left|w_{j}\right|^{q}-\eta\right) & \geq 0 \\
\lambda & \geq 0 \\
-\frac{\lambda}{2}\left(\sum_{j=1}^{M}\left|w_{j}\right|^{q}-\eta\right) &=0
\end{aligned}\right.
\tag{ex3.5.2}
\end {align*}
```  

(ex3.5.1)で表される$L(\mathbf w, \lambda)$を(ex3.5.2)の条件下で$\mathbf w$に対して最小化することと等しい。
$L(\mathbf w, \lambda)$の$\mathbf w$における最小化を考えると$\frac{\lambda\eta}{2}$の項は無視することができる。そのため正則化誤差関数(3.29)の最小化と、正則化されていない二乗和誤差(3.12)の制約条件(3.30)下での最小化が等価であることが示された。

また、$L(\mathbf w, \lambda)$を最小化するような$\mathbf w$を$\mathbf w^*$とすると、(ex3.5.1)を$\lambda$で偏微分してやることにより、

```math
\begin {align*}
\sum_{j=1}^{M}\left|w^*_{j}\right|^{q} = \eta 
\tag{ex3.5.3}
\end {align*}
```  

となる。このことを図によって説明したのがPRML本文における図3.4である。
C++11 で std::vector<T> な変数から型 T を取得する

## 背景

`std::vector` ということがわかっている変数から, 型 T を抽出したい.

## 方法

```c++
std::vector<float> a;

using t = decltype(*a.begin());

static_assert(std::is_same<t, float>::value == true, "type must be float");
```

`*a.data()` でもいいかもしれません.

`a[0]` でも OK でした.

https://stackoverflow.com/questions/1665018/memset-on-vector-c

配列のインデックスを取るのは, カラの配列時 seg fault しそうでちょっと抵抗がありますが, sizeof はコンパイル時の処理だからか, 実のところカラの配列に対して行っても実行時問題ありませんでした(asan でも問題なかった)


## おまけ

`std::vector<float *>` など, ポインタの可能性のあるときからポインタ除去した型がほしい.

`std::remove_pointer` を使います.

https://en.cppreference.com/w/cpp/types/remove_pointer

ポインタで無い場合はなにもしないので汎用に使えます.

ただ, この場合 `std::decay` と組み合わせないとうまくいかないです.

decayメタ関数
https://faithandbrave.hateblo.jp/entry/20120416/1334563367

C++ Get Vector type
https://stackoverflow.com/questions/12490508/c-get-vector-type/53259979#53259979

こんな感じになります.

```
std::vector<float *> b;
using t = std::remove_pointer<std::decay<decltype(*b.begin())>::type>::type;
// => t = `float`
```

この場合, `std::vector<float[2]> b` なケースでも `float` が型として取得できます!
[Ansible] Python3インタプリタで、Centos7にdnfをインストールする

# [Ansible] Python3インタプリタで、Centos7にdnfをインストールする

## dnfとは

[fedora公式ページ](https://fedoraproject.org/wiki/DNF?rd=Dnf)

- Dandified Yum(ダンディファイド ヤム)とも言うらしい
- Fedoraのパッケージ管理システム(バージョン22からデフォルトになった)
- RHEL7,CentOS7でも使用できる(`yum install -y dnf`)
- RHEL8,CentOS8では標準でインストール済み

簡単に言うと、`dnf`は`yum`の後継種であり、CentOS8からは`yum`ではなく`dnf`がデフォルトとなる。
CentOS8でも`yum`コマンドは使えるが、`dnf`へのシンボリックリンクになっているだけである。

## なぜyumではなくdnfを使うのか

2020/1/1にPython2.Xのサポートが終了した。

- yumは、python2.Xでしか動作しません
- dnfは、python2.x or 3.Xで動作します

なのでこれからは`dnf`とが主流となっていく。

## (まずは)手動でCentOS 7にインストールしてみる

CentOS 7.XのDockerコンテナにdnfをインストールする。

```
[dnfuser@localhost ~]$ docker run -it --rm centos:7 bash

[root@3b4a088d7e6f /]# yum update -y
[root@3b4a088d7e6f /]# yum install -y epel-release
[root@3b4a088d7e6f /]# yum install -y dnf

[root@3b4a088d7e6f /]# head -n1 /usr/bin/dnf
#!/usr/bin/python2
```

どうやらCentOS7.Xの`dnf`はpython2.Xで動いている様子。
python3.Xをインストールした後にも試したが、`dnf`は2.Xになってしまう。

## Ansibleでdnfをインストールする

<https://docs.ansible.com/ansible/latest/modules/dnf_module.html>

インタプリタがPython2.Xであれば、すんなりインストールできる。

```yml:playbook.yml
- name: Install epel-release
  yum:
    name: epel-release
    state: present
  become: yes

- name: Install dnf
  yum:
    name: dnf
    state: present
  become: yes
```

1. yumモジュールでdnfをインストール
2. その後のタスクはyumモジュールをdnfモジュールに変更すれば使用できる

### (本題)Ansibleのインタプリタをpython3.Xにしている場合

```cfg:ansible.cfg
[default]
ansible_python_interpreter=/usr/bin/python3
```

上記のように、デフォルトでPython3.Xのインタプリタを使用している場合は、無理やり2.Xに戻す必要がある。

```yml:playbook.yml
- name: Install dnf for Centos7
  block:
    - name: Change interpreter
      set_fact:
        ansible_python_interpreter: "/usr/bin/python"

    - name: Install epel-release
      yum:
        name: epel-release
        state: present
      become: yes

    - name: Install dnf
      yum:
        name: dnf
        state: present
      become: yes
  when:
    - ansible_distribution_major_version | float < 8
```

その後のタスクでもインタプリタは2.Xになる。

## 最後に(Ansibleインタプリタ ベストプラクティス)

Ansible 2.12 ver.では、デフォルトのインタプリタの振る舞いが変わるらしい。
(多分Python3.Xが優先的に選ばれるのであろう)

参考）
<https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html>
<https://rheb.hatenablog.com/entry/ansible_interpreter_discovery>

現行ver.(2.9)ではデフォルトで`/usr/bin/python`が指定されるので、OSによって使用されるPythonのver.が違う場合がある。
2.12 ver.が待てなくて、`dnf`コマンドを使いたい人のベストプラクティスは以下のようになった。

### 諦めてデフォルト(Python2.X)のインタプリタを使用する

1. Ansibleに関しては、デフォルトの`/usr/bin/python`を使用して、Python2.Xを使い続ける
2. yumモジュールではなく、dnfモジュールに統一する

「別にPython2.Xでいいよ」と言う人は、デフォルトのインタプリタを使用すれば問題ない。

### どうしてもPyhton3.Xのインタプリタを使用したい場合

**CentOS7.Xのホストに対して、inventoryでPython2.Xインタプリタを指定する**

```yml:inventory.yml
all:
  children:
    centos7:
      hosts: centos7-1
      vars:
        ansible_python_interpreter: /usr/bin/python # /usr/bin/python2 でもOK
```

CentOS7だけグルーピングしておけば、簡単に実装できそう。

**Playbookで強制的にインタプリタを2.Xに変更する**

```yml:playbook.yml
- name: Change interpreter
  set_fact:
    ansible_python_interpreter: /usr/bin/python
```

ちなみに私は、Python3.Xがデフォルトになるのに備えて、こちらを採用している。
Mac High Sierra 10.13.16でpipがssl errorで動作しなくなったとき

Mac High Sierraでpipの動作がおかしくなり、その内容と対処方法を記載します。さてしかしLibreSSLからOpenSSLに変更することは正しいのかどうかはわかりませんが、まずはこのまま運用してみます。
* * *
pipのバージョンが9.0.1と古く、最新の20.1.1にしようと思いました。
先にhomebrewをアップデートとアップグレードを完了させて、
pip install --upgrade pip
を行うと、
pip is configured with location that require TLS/SSL, however that ssl module in Python is not available.
というエラーが表示されました。
pipにはTLS/SSLが必要だと言うことを言ってますね。homebrewを最新にした行為が何らかの不具合を起こしたのかどうかは不明です。

さてpip install --upgrade pip成功までの対処方法は次のとおりです。
１．まずは現在のopensslのバージョンを確認しました。
$ openssl version
LibreSSL 2.2.7
自分のマックHihg Sierraは　LibreSSLを使っているようです。調べたらHigh Sierraから採用しているとの事。
２．OpenSSLをインストールします。
$ brew install openssl
３．インストールしたOpenSSLはどうなっているのか見てみます。
$ brew info openssl
openssl@1.1: stable1.1.1g (bottled)[keg-only]
keg-onlyとはhomebrew用語でCellarフォルダだけにインストールされたフォミュラーで、 /usr/local/にリンクはしていないという意味。brew linkを使うとリンクするらしい。
他に書いてあることを読むと、
if you need to have this software first in your path run:というところがある。パスを通さねばならないということらしい。
４．ではパスを通します。
$ echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile

５．OpenSSLに切り替えます。
$ brew switch OpenSSL 1.1.1g
しかしまた別のエラーが。
OpenSSL does not have a version “1.1.1g” in the Cellar.
OpenSSL’s installed versions: 1.0.2h_1, 1.0.2j, 1.0.2k, 1.0.2l, 1.0.2o

brew linkをしなければ行けなかったのかと思うが、めんどくさいので、ここで書かれている＊おそらく）古いバージョンの５つから選んで再実行してみよう。
$ brew switch OpenSSL 1.0.2h_1

Cleaning /usr/local/Cellar/OpenSSL/1.0.2o

Cleaning /usr/local/Cellar/OpenSSL/1.0.2h_1

Cleaning /usr/local/Cellar/OpenSSL/1.0.2k

Cleaning /usr/local/Cellar/OpenSSL/1.0.2l

Cleaning /usr/local/Cellar/OpenSSL/1.0.2j

Opt link created for /usr/local/Cellar/OpenSSL/1.0.2h_1

という表示が出て成功したようです。

６．では最後にpipをアップグレードします。
$ pip install —upgrade pip
Successfully uninstalled pip-9.0.1
Successfully installed pip-20.1.1

というわけでpipは最新バージョンにアップグレードできました。
【AWS SAP】Route53のヘルスチェックおける正常性確認について【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第8弾

・Route53のヘルスチェックにおける正常性確認について

##Route53とは
DNSサービス。

(以下、公式サイトより)
> Amazon Route 53 は、可用性と拡張性に優れたクラウドのドメインネームシステム (DNS) ウェブサービスです。Amazon Route 53 は、www.example.com のような名前を、コンピュータが互いに接続するための数字の IP アドレス (192.0.2.1 など) に変換するサービスで、開発者や企業がエンドユーザーをインターネットアプリケーションにルーティングする、きわめて信頼性が高く、コスト効率の良い方法となるよう設計されています。Amazon Route 53 は IPv6 にも完全準拠しています。

##Route53のヘルスチェック
エンドポイントをモニタリングするヘルスチェックを作成すると、エンドポイントが正常であるかどうか確認します。

##エンドポイントの正常性確認

・HTTP/HTTPS ヘルスチェック
HTTP ステータスコード 2xx または 3xx でエンドポイントが応答する必要がある。

・HTTP/HTTPS 文字列チェック
文字列は5,120 バイト内に出現している必要があります。

(以下公式サイトより)
> HTTP/HTTPS ヘルスチェック – Route 53 が、エンドポイントとの TCP 接続を 4 秒以内に確立できることが必要です。加えて、接続後 2 秒以内に、HTTP ステータスコード 2xx または 3xx でエンドポイントが応答する必要があります。
注記
HTTPS ヘルスチェックでは SSL/TLS 証明書が検証されないため、証明書が無効または期限切れの場合でもチェックが不合格になることはありません。
TCP ヘルスチェック - – Route 53 が、エンドポイントとの TCP 接続を 10 秒以内に確立できることが必要です。
HTTP/HTTPS ヘルスチェックと文字列一致 – HTTP/HTTPS ヘルスチェックと同様に、Route 53 はエンドポイントとの TCP 接続を 4 秒以内に確立し、そのエンドポイントが接続後 2 秒以内に 2xx または 3xx の HTTP ステータスコードで応答する必要があります。
Route 53 ヘルスチェッカーは、HTTP ステータスコードを受信した後 2 秒以内にそのエンドポイントからレスポンスボディを受信する必要があります。Route 53 は、指定された文字列をレスポンスボディで検索します。その際、検索文字列全体が、レスポンス本文の最初の 5,120 バイト内に出現している必要があります。それ以外の場合、エンドポイントはヘルスチェックで不合格となります。Route 53 コンソールを使用している場合は、[Search String] フィールドに文字列を指定します。Route 53 API を使用している場合は、ヘルスチェックの作成時に、SearchString 要素で文字列を指定します。
AtCoder 生活　73日目

[前回](https://qiita.com/flandrescarlet237/items/9f9e1150c5620ef29b7d)

#73日目
今回は茶色diffの問題を3問解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|Code Formula 2014 本選|C|✕|44分55秒|
|ABC045|B|◯|37分39秒|
|ABC058|C|✕|78分36秒|


##[Code Formula 2014 本選_C](https://atcoder.jp/contests/code-formula-2014-final/tasks/code_formula_2014_final_c)

```c++

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

const int INF = 2e9;

int main(){
    string s;
    getline(cin,s);
    s.push_back(' ');
    set<string> st;
    int s = s.size();
    int pos = 0;
    while(pos < l){
        if(s[pos] == '@'){
            string t = "";
            while(pos++ < l && 'a' <= s[pos] && s[pos] <= 'z'){
                t += s[pos];
            }
            if (t.size() > 0) st.insert(t);
        }
        else pos++;
    }
    for(auto x : st) cout << x << endl;
}

```

解くのにかかった時間：44分55秒
感想：getline(cin,s) の存在を初めて知った。知らないことがどんどんでてくる


##[ABC045_B](https://atcoder.jp/contests/abc045/tasks/abc045_b)

```c++

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

const int INF = 2e9;

int main(){
    vector<string> s(3);
    rep(i,3) cin >> s[i];
    map<char,string> mp;
    mp['a'] = s[0];
    mp['b'] = s[1];
    mp['c'] = s[2];
    char now = 'a';
    while(true){
        char n = mp[now][0];
        if(mp[now].size() == 0){
            char ans = now - 32;
            cout << ans << endl;
            return 0;
        }
        mp[now] = mp[now].substr(1);
        now = n;
    }
}

```

解くのにかかった時間：37分39秒
感想：この書き方が一番書きやすく感じた。mapが便利


##[ABC058_C](https://atcoder.jp/contests/abc058/tasks/arc071_a)

```c++

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

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    vector<map<char,int>> d(n);
    rep(i,n){
        string s;
        cin >> s;
        rep(j,s.size()){
            d[i][s[j]]++;
        }
    }
    map<char,int> m = d[0];
    for(auto x:m){
        char k = x.first;
        rep(i,n) m[k] = min(m[k],d[i][k]);
    }
    for(auto x:m){
        rep(i,x.second) cout << x.first;
    }
    cout << endl;
}

```

解くのにかかった時間：78分36秒
感想：前回解いたことあったらしいが全然覚えていなかった


###最後に
茶色diffの問題でも二回目の問題は解けるようにしておきたい
【NestJS/TypeORM】テスト時のDBデータのクリーンアップ

# 環境

- [NestJS 7.0.7](https://nestjs.com/)
- [nestjs/typeorm 7.0.0](https://github.com/nestjs/typeorm)
- [typeorm 0.2.25](https://github.com/typeorm/typeorm)

# 追記（2022-04-11）

以下の方法で暫く運用していましたが、`await getConnection().synchronize(true)` の処理に時間がかかり、テストの実行時間が伸びてしまったため、利用を止めました。
現在は、テスト毎に異なるデータを生成するようにしています（テストデータの削除は行わない）。

# これ一発

```typescript
  afterEach(async () => {
    await getConnection().synchronize(true)
    // multiple database 環境で、default 以外の DB を使っている場合は DB 名を指定する。
    // await getConnection('connectionNameComesHere').synchronize(true)
  })

  // これも忘れずに
  afterAll(async () => {
    module.close()
  }
```

参考にさせてもらったのは[こちら](https://github.com/nestjs/nest/issues/409#issuecomment-390569628)。
ドキュメントは[こちら](https://orkhan.gitbook.io/typeorm/docs/connection-api)。

# 他のやり方

今までは以下のようにテーブルごとに delete していましたが、抜け漏れがあったり、外部参照で順番を気にする必要があったりして少し面倒でした。

```typescript
  afterEach(async () => {
    await fooRepo.delete({})
    await barRepo.delete({})
  }
```

# 注意

```
jest -w 2
```

という感じで、multi thread でテストを実行していましたが、データを削除しているので当然 conflict が発生してしまいました。
今は single thread にしています。

```
jest -w 1

// または

jest --runInBand
```
Vim で IME をいい感じに使う

## 概要

Vim で期待しない IME のオン、オフを避けるための設定。
[vim-jp Slack](https://vim-jp.org/docs/chat.html) で質問して、現状このようになった。

## 環境

* Vim: [gvim 8.2.0884](https://github.com/vim/vim-win32-installer/releases/tag/v8.2.0884)
* Windows 10

## 設定

[動作](#動作) になるような設定を vimrc へ記載。

```vim
let s:lastiminsert = 0
" IMEの状態を保持しておく、置換モードではIMEの状態を保持しない
" 置換モードではIMEの状態を保持しない。置換モードではIMEオフなので、置換モード後の挿入モードが常にIMEオフになることを避ける
autocmd InsertLeave * if v:insertmode !=# 'r' | let s:lastiminsert = &iminsert | set iminsert=0 | endif
" IMEの状態を復帰する。改行時には続けてIMEオンのままにしたいため。
" 挿入モード（IMEオン）→ノーマルモード→挿入モード（IMEオン） となるが。これはむしろできなくていい
" 置換モードではIMEの状態を復帰しない
autocmd InsertEnter * if v:insertmode ==# 'i' | let &iminsert = s:lastiminsert | endif
```

## 動作

```
凡例：
- IME ON：背景色 Lime
- ポイントの状態：文字色 赤
```

1. IME がオンの状態の挿入モードからノーマルモードに戻って、再度挿入モードに入ったら IME はオンのまま

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/a1b3428b-8a56-c477-7edf-22bf463e3922.png)


2. IME がオンの状態の挿入モードで改行しても IME オンのまま

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/503017a5-cf12-da29-390e-285c2c6ba3a8.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/7af4ab33-3b5d-ea01-0b2f-95d5d02ef5f8.png)


3. 1 文字置換、置換モードに入ったら IME はオフ

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/df26bae0-6b00-ba32-f945-bdaf10771a3d.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/c5fd9cd2-f628-ec4e-4b6e-bd27dbfbf65d.png)


4. コマンドラインモードに入ったら IME はオフ

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24711/006809b9-71db-d139-7d9f-0a72575ab012.png)
【Pythonやってみた！】iPad ProでKaggleに投稿できる？


##目的
iPad Pro 2020でKaggleに投稿できたので、その方法を共有する。
##背景
iPad Pro 2020を最近購入し、
「これで機械学習を勉強できたら最高なのに、、、」
と思ったが、ネット上では「できた」「できない」と色々言われているので、
実際はどうかを試そうと思った。
##実行環境
端末：iPad Pro 2020（11インチ）
キーボード：Magic Keyboard
ブラウザ：Chrome
##前提
Kaggleにログインできる
※今回はログイン方法は説明しません
##参考

https://www.codexa.net/kaggle-titanic-beginner/

##方法
①ChromeでKaggleのページに行く
②Notebookを作成する
③コーディングする
④Save＆Commit
⑤Submitするページに行く
⑥Submit
##①ChromeでKaggleのページに行く
Kaggleにログインし、Competitionsページに行く。
参加するコンペを選択。（今回はTitanicを例にします。）
<img width="1194" alt="スクリーンショット 2020-06-03 20.09.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/cb36d251-18f1-f546-13a5-8824372ed0fb.png">

##②Notebookを作成する
PythonをコーディングするNotebookを作成する。
<img width="1194" alt="スクリーンショット 2020-06-03 20.13.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/412e40d8-3a27-01a4-d9c5-ccbfcf12441e.png">
<img width="1194" alt="スクリーンショット 2020-06-03 20.14.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/f86624c6-7e5d-c68d-177a-a3286479fe72.png">
##③コーディングする
タイトルを変えることができます。
（今回はコーディングについては省略します。）
<img width="1194" alt="スクリーンショット 2020-06-03 20.50.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/f50363c7-2d24-e2f7-2bde-1f7db9eb2fa0.png">
##④Save&Commit
Saveを選択する。
<img width="1194" alt="スクリーンショット 2020-06-03 20.54.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/b5a3c80d-5474-94f4-2b1a-d9360fc42550.png">
Save&Commitを選択し、Saveする。
<img width="693" alt="スクリーンショット 2020-06-03 20.55.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/b088e735-e6cb-f9f5-71bf-5f4437d2544c.png">
<img width="895" alt="スクリーンショット 2020-06-03 20.58.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/b7978c14-3fa7-8030-d942-3bd51e766488.png">
##⑤Submitするページに行く
編集ページから戻る。
<img width="1194" alt="スクリーンショット 2020-06-03 20.59.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/115a2ab6-c236-ff02-6c47-ae1c94dae234.png">
先程作成したNotebookを選択する。
<img width="1194" alt="スクリーンショット 2020-06-03 21.01.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/1486ba7f-1ce9-e9bc-571b-be6f59848822.png">
##⑥Submit
Outputを選択する。
<img width="1194" alt="スクリーンショット 2020-06-03 21.02.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/b7f2c767-b509-965a-130f-a0ffa4a76a26.png">
Submitを選択する。
<img width="1194" alt="スクリーンショット 2020-06-03 21.03.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/937b66fc-eb3b-2a6c-7e0f-dee003e99dd4.png">
Kaggleに投稿できました！
<img width="1194" alt="スクリーンショット 2020-06-03 21.04.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573636/95c0145b-b475-18e6-c833-53acefcb23f9.png">

##まとめ
今回は、iPad pro 2020でKaggle投稿にチャレンジしてみました。
結果はKaggle投稿ができる！ということがわかりました。
キーボードはあった方が良いと思います。
ますますデータ分析のモチベーションが上がりました！
【AWS SAP】ElastiCacheのMemcachedとRedisの違い【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第7弾
以下の違いについて覚えておいて損はありません。

・ElastiCache Memcached
・ElastiCache Redis

##Memcachedとは
マルチスレッドで動作する。
CPUのコア数を上げると、パフォーマンスも上がる。

(以下、公式サイトより)
> 以下がお客様の状況に当てはまる場合は、Memcached を選択します。
できるだけシンプルなモデルが必要である。
複数のコアまたはスレッドを持つ大きなノードを実行する必要がある。
システムでの需要の増減に応じてノードを追加または削除するスケールアウトおよびスケールイン機能が必要である。
データベースなどのオブジェクトをキャッシュする必要がある。

##redisとは
シングルスレッドで動作する。

(以下、公式サイトより)
>以下の状況が当てはまる場合は、Redis を Redis 用 ElastiCache のバージョンと共に選択します。
Redis 用 ElastiCache バージョン 5.0.0 (拡張)
プロデューサーが新しいアイテムをリアルタイムで追加できるようにし、コンシューマーがブロッキングまたはノンブロッキングの方法でメッセージを使用できるようにもするログデータ構造である Redis ストリームを使用します。
【TypeORM】プレースホルダーを使う時の地雷

# 環境

- [typeorm 0.2.25](https://github.com/typeorm/typeorm)

# 再現コード

```typescript
  function findOneByBarAndId(
    bar: Bar
    id: number // foo の id （コード内参照） 
  ): Promise<Foo | undefined> {
    const queryBuilder = this.fooRepo
      .createQueryBuilder('foo')
      .innerJoinAndSelect('foo.bars', 'bar')
      .where('foo.id = :id', { id })
      .andWhere('bar.id = :id', { id: bar.id }) // ここに地雷があります
      .getOne()
  }
```

# 地雷

`id` が被っているため、前の `id` の値も後の値（ここでは `bar.id`）が使われてしまいます。
最初のプレースホルダー部分を `{ id: id }` としても駄目です。

DBのログを有効（`logging: true`）にして、 同じ値が使われていたのを見て気が付きました。

# 地雷回避方法

プレースホルダー名を変えましょう。

```typescript
-      .andWhere('bar.id = :id', { id: bar.id })  // 地雷
+      .andWhere('bar.id = :barId', { barId: bar.id }) // 回避
```

# ドキュメント

https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#using-subqueries
に書かれていました。

> Note: do not use the same parameter name for different values across the query builder. Values will be overridden if you set them multiple times.
WSL2上（Ubuntu 20.04LTS）でRails環境を構築しようとしたら躓いて転んだ

#何をしようとしたのか？
Windows10 20H1が来たのでWSL2を用いてRails環境を整えようと思った。
Ubuntu 20.04LTSを入れて、あれこれ設定していたら想定外のところで躓いて転んだ。

# 何があったのか？

- Rubyのインストールはできた
- gemでRailsもインストールできた
- MariaDBもインストールできた
- 普通に起動させよう

```
$sudo systemctl start mysql
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to create bus connection: Host is down
```
なんかエラー出た。

# なんで？
WSL2はsystemdがサポートされていないらしい（厳密には存在するらしいが無効化されている）。
仮に有効化させてもPID 1で起動できないので、事実上systemctlは使えない。

#対策
[WSL2でSystemdを使うハック](https://qiita.com/matarillo/items/f036a9561a4839275e5f)を参照してみた。
その中でも一番楽そうなgenie コマンドを使ってみることに。
https://github.com/arkane-systems/genie/

#実行
割と長めの前準備があるが、最終的には以下のコマンドを実行することになる。

```
sudo apt install systemd-genie
```
以下準備メモ

- [.NET Core のインストール](https://docs.microsoft.com/ja-jp/dotnet/core/install/linux-package-manager-ubuntu-1910) にアクセス
- dotnet-runtime-3.1をインストール
- [wsl-translinux](https://packagecloud.io/arkane-systems/wsl-translinux)にアクセス
- Quick installの欄のスクリプトを実行
- 上記コマンドを実行

#あれ？
実行してみるとわかるが、404エラーを返されてインストールに失敗する。
何故かと思ったらまだUbuntu 20.04LTS向けのパッケージが存在しないのである。
なんという……。


# 結論
現状DebianかUbuntu 18.04LTSを使おう。
【Rails】deviseでのセッションタイムアウト設定

# deviseでのセッションタイムアウト設定

### 目次
0. セッションタイムアウトを設定するメリット
1. セッションタイムアウトを設定するデメリット
2. deviseでのセッションタイムアウト設定

## 1. セッションタイムアウトを設定するメリット
1. セッションの盗用などの不正行為の対策になり、安全にアプリケーションを運用することができる
2. 利用ユーザーのステータスを判定することによって、サーバー側の負担を軽減させることができる

## 2. セッションタイムアウトを設定するデメリット
1. 入力フォームなどで、一度中断をし、再開後に入力を行うことができないこと
2. ログイン状態が切れる回数が多いと、ユーザーが再度ログインする必要があるので、アプリケーションの使い勝手が悪いと判断されてしまうこと

## 3. deviseでのセッションタイムアウト設定

### 3-1. Deviseのセッションタイムアウトを設定

以下の記述を入力しましょう。
（コメントアウトされているので、コメントを解除すればOK）

```config/initializers/devise.rb
config.timeout_in = 30.minutes
```

### 3-2. Userモデルに「timeoutable」を設定
以下の記述を入力しましょう。

```app/models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,...省略...:timeoutable
end
```

※ テストを行う際は1分で設定することがおすすめです。

以上でdeviseでのセッションタイムアウト設定になります。