OmniAICreator/Qiita-1.07M huggingface dataset:
CircleCIでcdk deployしようとしてAWSの認証でハマった２点

追記 2021/09/15 
* ハマり２の解決策で追加すべきものを追加
* おまけハマりを追加

# はじめに

CircleCIからaws cdkでデプロイ仕様とした時に、AWSの認証関連でハマった２点です。
CircleCIでの実行ですが、多分どのパイプラインサービスでも同じだと思います。

# 前提

* CircleCI用のIAMユーザー `circleci-user` を作成しCredentialsを生成しておく。
* `circleci-user` は必要最低限の権限とする。
* CloudFormation実行用のIAM Role `CFn-Role`を作成してcdkのオプションで指定する。


## ハマり１：cdkではProfileが必要

```
AWS_DEFAULT_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=AKxxxxxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxx

npm run cdk -- deploy --require-approval never
```

と実行しても以下のようなエラーになる。

```
DynamoCdkStack: deploying...

 ❌  DynamoCdkStack failed: Error: Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment
    at SdkProvider.resolveEnvironment (/home/circleci/work/Dynamo-CDK/node_modules/aws-cdk/lib/api/aws-auth/sdk-provider.ts:208:13)
```

## ハマり１の解決：Profileを設定する

どうやらProfileの設定は必須のようなので作成する。

```
AWS_PROFILE_NAME=prd
aws --profile ${AWS_PROFILE_NAME} configure set aws_access_key_id ${AWS_ACCESS_KEY_ID}
aws --profile ${AWS_PROFILE_NAME} configure set aws_secret_access_key ${AWS_SECRET_ACCESS_KEY}
aws --profile ${AWS_PROFILE_NAME} configure set region ${AWS_DEFAULT_REGION}

npm run cdk -- deploy --require-approval never --profile ${AWS_PROFILE_NAME}

```

## ハマり２： --role-arnを指定しても途中までは実行ユーザーの権限

最小権限の原則に則り `circleci-user` には`iam:PassRole`のみを設定して、cdkのオプションに`--role-arn`を指定したのですが、権限足りないエラーになりました。

```
npm run cdk deploy --role-arn" "************************************************************************** --require-approval never --profile ${AWS_PROFILE_NAME}

DynamoCdkStack: deploying...

 ❌  DynamoCdkStack failed: AccessDenied: User: arn:aws:iam::123456789012:user/circleci-user is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CDKToolkit/*
    at Request.extractError (/home/circleci/work/Dynamo-CDK/node_modules/aws-cdk/node_modules/aws-sdk/lib/protocol/query.js:50:29)

```

## ハマり２の解決：実行ユーザーにはいくつか権限が必要

cdkの--role-arnはターゲットとするStackに対する操作には使用されるが事前の「CDKToolkit」スタックからの情報取得やChangesetの作成までは実行ユーザーの権限で行われるようです。

`circleci-user`に以下の権限を付与します。

* ManagedPolicyの `AWSCloudFormationReadOnlyAccess`
* CDKToolkitスタック（`cdk bootstrap`で作成される）で作成されるS3Bucketに対する書き込み権限
* `cloudformation:CreateChangeSet`/`ExecuteChangeSet`/`DeleteChangeSet`権限（これは事前にStack名がわからないので` Resource:*`

## おまけハマり：謎のエラー

```
 failed: Error: This stack uses assets, so the toolkit stack must be deployed to the environment (Run "cdk bootstrap aws://unknown-account/unknown-region")
```

なんじゃこりゃ？と思ったら`cdk bootstrap`をそのAWSアカウントで実行していなかったためでした。
【速報】データサイエンティスト検定を受けてみた。（2021年9月14日）

# はじめに

2021年9月14日（火）に、データサイエンティスト検定を受検しました。この検定は、2021年9月11日（土）からスタートした新たな試験です。本記事では検定の概要と、私が実際に受検して感じた所感を書いていきます。
私は実務経験者ですが、初学者や実務未経験の方にも参考になるかと思います。
今後、受検を考えている方に少しでもお役立てできれば幸いです。

# なぜ受検したか？
私は30歳手前で未経験からデータサイエンティストを目指し、業務で必要な知識をその都度気合で習得してきました。
体系的に勉強した経験がないため、どの程度の知識があるか客観的に知りたかったのが一番の動機です。

# データサイエンティスト検定って何？
「そんなのは知ってるよ！」という方は読み飛ばしてください。
## 3行でまとめると
・データサイエンティストとしての実務能力と知識を証明するための試験だよ
・難易度は見習いレベルの基本的な内容が多いよ
・とはいっても、カバーすべき領域は結構広いよ

> 『データサイエンティスト検定™ リテラシーレベル』（略称：DS検定™ ★）とは、アシスタント・データサイエンティスト（見習いレベル：★）と数理・データサイエンス教育強化拠点コンソーシアムが公開している数理・データサイエンス・AI（リテラシーレベル）におけるモデルカリキュラムを総合し、実務能力と知識を有することを証明する試験です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652854/d6d8f13b-96a4-8538-a772-5188c357c532.png)

参考：https://www.datascientist.or.jp/dskentei/

# 検定概要
> - 受験資格	なし
- 実施概要	選択式問題
- 全国の試験会場で開催(CBT)
- 問題数80問程度
- 試験時間90分
- 出題範囲	スキルチェックリストの3カテゴリ（データサイエンス力、データエンジニアリング力、ビジネス力）の★１（見習いレベル）相当と数理・データサイエンス・AI（リテラシーレベル）におけるモデルカリキュラムを総合した範囲

参考：https://www.datascientist.or.jp/dskentei/


# 試験範囲
![スクリーンショット 2021-09-15 100057.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327405/7333af79-5d80-0f2c-d309-1496c7124f99.jpeg)
参考：https://www.datascientist.or.jp/dskentei/


# 検定の対象
> 本検定の受験対象者は以下のような方を想定しています。
・データサイエンティスト初学者
・これからデータサイエンティストを目指すビジネスパーソン
・データサイエンティストに興味を持つ大学生や専門学校生など

参考：https://www.datascientist.or.jp/dskentei/

# 私のバックグラウンド
・文系未経験からデータサイエンティストを目指す
・データ分析歴4年
・データサイエンティスト系の資格は、特に持っていません
詳しくは下記を参照ください
[28歳、一念発起して未経験からデータサイエンティストを志した2年間の軌跡](https://qiita.com/toshiyuki_tsutsui/items/5b0956ceb1d7a3cb2d97)

# 受検に受けた勉強
本検定に向けて下記を1周しました。
・[公式テキスト](https://gihyo.jp/book/2021/978-4-297-12261-4)：5時間
・[対策アプリ](https://www.skillupai.com/ds-app/)：4時間
公式テキストの模試（45問）とアプリのオリジナル問題（90問）を解き、不正解だった分野を中心に勉強しました。

# 検定を終えての感想
試験内容の詳細は載せることができませんのでざっくり。あくまでも私個人の感想です。
## データサイエンス力
・公式テキストの語句の理解が**きちんと**できていれば問題なし
・基礎統計や高校レベルの数学力があれば問題なし
・統計検定やE資格の勉強した経験がある人にとっては楽勝かも。
偉そうに書いてますが、私は全然楽勝ではなかったです。

## データエンジニア力
・SQL,BI,機械学習,深層学習,自然言語処理の問題は即答
・データインフラ系に苦戦
・他の二つに比べると難易度が高め
実務で経験してきたところは割とできましたが、未経験＆勉強不足の箇所は何問か落としてしまいました。

## ビジネス力
・ビジネスというより、国語力や常識力が必要
・データサイエンス関係なくねって問題もちらほら
・公式テキストやアプリのオリジナル問題の方が良問
実務未経験者への配慮がある一方で、もう少し実務よりな出題があっても良かったのではという印象です。

## で、何点取れたの？
内緒です。合格していることを祈ります。

# やっておいた方がよさそうなこと
## 実務経験者
私のような実務からスタートした人間は、教科書的な基礎統計の数式理解や実務で扱ったことがない分野がどうしても弱いので、その部分は素直にがっつり勉強しておいた方がよさそうです。
## 実務未経験者・初学者
実務未経験者の方は、公式テキストやアプリの対策問題をがっつりやり込むのが良さそうです。
統計、SQL、機械学習・DL、サーバー、データベース、セキュリティ等々についてやや広めの範囲から浅めの内容が出題されました。専門書でがっつりやるよりも試験に特化した公式テキストやアプリを中心に取り組むほうが効率が良さそうです。
実務未経験者に不利な問題は多少捨てても合格ラインには達すると思われます。

# これからデータサイエンティストを目指す方へ
Twitter等では「超簡単で余裕だったw」「ノー勉だったけど9割取れた」みたいな感想をちらほら見かけますが、「これからデータサイエンティストを目指す初学者」にとっては、決して簡単ではありません。

理由としては、**扱う範囲がとても広い**ためです。
統計、SQL、機械学習・DL、サーバー、データベース、セキュリティ等々を初学者が体系的に勉強しようとすると膨大な時間がかかります。

本検定のために勉強し合格を目標にすることは、データサイエンティストになるためにプラスにはなりますが、近道ではないです。
職業としてデータサイエンティストを目指される方は、受検勉強に膨大な時間を費やすより、一度実務の現場に飛び込んで経験した方が、圧倒的に成長できる思います。
理想論ですが、受検勉強と実務を並行してどっちも頑張るのがおすすめです。

# おわりに
幅広い分野についてバランスよく出題されていて、データサイエンティストとしてどの部分に課題があるかを確認する良い機会でした。
公式テキスト等できちんと勉強していれば十分対応可能で受検のハードルは高くないの興味がある方は是非チャレンジしてみてください。
単一責任の原則@Laravel


単一責任の原則について調べていると「**クラスとメソッドは1つの責任だけを持つべき**」など諸々調べると出てくるが、概念的にはわかるもののいまいちコードに反映することができていなかったので、モヤっとしていた。
そんな時に、いい感じのサイトに出会えたので勉強がてらまとめておく。

いい感じのサイト↓
[Laravelベストプラクティス](https://github.com/alexeymezenin/laravel-best-practices/blob/master/japanese.md#%E5%8D%98%E4%B8%80%E8%B2%AC%E4%BB%BB%E3%81%AE%E5%8E%9F%E5%89%87)


## 実際にコードを見てみる

以下に登場するコードは上記のサイトから転記したものです。

### 単一責任の原則に反するコード

```php
public function getFullNameAttribute()
{
    if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
        return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}
```

あー。ifの条件がちょっと複雑だけどこうやって書いちゃうな..ってのが正直な感想です。
名前の作成の部分が、複雑でちょっと何しているかわかりにくいなとは思います。

「〜〜〜の修正お願い！」と頼まれても「えーと。ここのifの中身は〜〜〜」「なんか文字列結合しまくってるけどなんやろこれ?」ってなりそうな感じがします。

### 単一責任の法則に則ったコード

```php
// これがメイン
public function getFullNameAttribute()
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

// 認証認可関連
// ここもうちょいどうにかならんのか？と少し感じる
public function isVerifiedClient()
{
    return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
}

// 名前の取得①
public function getFullNameLong()
{
    return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
}

// 名前の取得②
public function getFullNameShort()
{
    return $this->first_name[0] . '. ' . $this->last_name;
}
```

感想としてすごいわかりやすいなーと思いました。

`getFullNameAttribute()`だけ読めば「ああなるほど」となります。

修正を加える際にも、「ここを修正すればいいな」「ここは今回は関係ないな」というのが明確にわかのではないかと思います。

## まとめ
綺麗なコードが書きたい。
[Java] 配列の書き方がスッキリわかる記事

配列の書き方がいろいろあって、混乱したので自分用にまとめました。


# この記事の対象読者

以下のコードが構文エラーになる理由がわからない人

```java
int[] ary;
ary = new int[]
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
```

このエラーの理由がわからない場合は、この記事を読めば頭が整理されてスッキリすると思います。
# 結論

配列を定義して使用するためには、以下の3つのステップが必要になります。

- 配列の宣言
- 配列の生成
- 要素の初期化

3番目の「要素の初期化」はなくてもエラーにはならないけど、
わかりやすいコードにするためにも、明記することが推奨されてます。

# 配列の宣言

まず最初に必要なのは、配列の宣言です。

こんなやつ。

```java
int[] ary;
```

```java
int ary[];
```

aryという変数名で配列を宣言してます。

上記はどちらも同じ意味です。
お好みでどうぞ。

また、intのところをStringやdouble等、他の型にすることもできます。
intで宣言したら、int型の要素しか入れることができません。

# 配列の生成

次に必要なのは、配列の生成です。
newを使うあれです。

```java
new int[要素数];
```
この記述により、配列に使用するメモリが確保されます。

## 実際の書き方

```java
int[] ary; // 配列の宣言
ary = new int[要素数]; // 配列の生成
```

## 1行で書くこともできます。

```java
int[] ary = new int[要素数]; // 配列の宣言 + 配列の生成
```

## エラーになるケース

- 要素数の省略
- 配列の宣言をしない

場合、構文エラーになります。

```java
// 要素数の省略
int[] ary;
ary = new int[]; // 構文エラー
```

```java
// 配列の宣言をしない
ary = new int[要素数]; // 構文エラー
```
# 要素の初期化
配列の生成をしただけでは、中身は空っぽです。
※正確には型に応じた規定値(intの場合は0)が入ってます。

配列として扱うために、配列に要素を入れてあげる必要があります。

## まとめて初期化
```java
int[] ary;
ary = new int[3] {1, 2, 3};
```
## ひとつずつ初期化
```java
int[] ary;
ary = new int[3];
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
```

## 1行で書く場合
配列の宣言から初期化まで1行で書くこともできます。

```java
int[] ary = new int[3] {1, 2, 3};
```
どれも使っても同じ結果になります。

# やりがちな間違い
```java
int[] ary; // 配列の宣言
ary = new int[3]; // 配列の生成
ary = {1, 2, 3}; // 配列の初期化
```

配列の宣言もされていて、要素数も指定されているし、問題がないように見えます。
ですが、これはエラーになります。

問題なのは3行目。

これで初期化ができているように見えますが、実は初期化できていません。
なぜなら、```ary```に入っているのは配列への参照情報だからです。

```{}```を使ってまとめて初期化したい場合は、```new int[]```と一緒に記述する必要があります。

ここまでが配列の書き方の基本です。

# 冒頭のコードはなぜエラー？
では、冒頭のコードはなぜエラーになるのでしょうか？
このコードです。

```java
int[] ary;
ary = new int[];
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
```
ここまで読んでいただいたらわかると思います。

そうですね。要素数が指定されていません。
正しくはこう。

```java
int[] ary;
ary = new int[3]; // 要素数を指定
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
```

これで正常に動作します。

# おまけ：省略記法
配列を扱うには上記の3ステップが必要なのですが、
Javaには省略記法というものが用意されています。

## 要素数の省略

```java
// 1行で書く場合
int[] ary1 = new int[] {1, 2, 3};

// 分けて書く場合
int[] ary2;
ary2 = new int[] {1, 2, 3};
```

```{}```を使用して同時に初期化する場合に限り、要素数を省略することができます。

## 配列の生成の省略

```java
int[] ary = {1, 2, 3};
```

配列の生成も省略してるし、参照情報を入れる```ary```に要素を直接代入しており、エラーが出る気がするのですが、こちらも正常に動作します。

これらの記法に限り、省略が許可されています。

ここは理屈ではなく、こういうものだと割り切って暗記すると、混乱しなくて済むと思います。

# まとめ
配列の書き方を自分なりにまとめてみました。
自分はこの考え方で、結構あたまの中がスッキリしたので、
少しでも理解の助けになればうれしいです。
辞書型を使って特定のデータを抜き出した

##はじめに
データ管理で下図のように、商品No.の検索から別シートにある情報を転記できたらいいのになと思った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/805cb358-8a3a-0c6c-211c-fb838cbb549a.png)

数が少ないうちはコピペなどで入力したらいいけど、データ数が膨大になったらめんどくさいのでpythonで自動化できないか試してみた。

##環境(Colabratory)
windows 10
Python 3.7.10
pandas 1.1.5

##内容
```python
#データの読み込み
import pandas as pd
import numpy as np

from google.colab import files
files.upload()

df = pd.read_csv('/content/dict.csv',encoding='SHIFT-JIS',index_col=0)
df.head()
```
こんな感じのデータ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/20ec054b-facd-3c36-ffd6-95ddff7fa2a7.png)

```python
#辞書型に変更
d_records = df.to_dict('index')
d_records
```
キー(インデックス)と値の紐づけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/35b8c8fa-43d2-83c6-cdcb-14f9a163a1c3.png)

```python
#選ぶインデックスのリスト
selects = [3,4,5,4,5,2,10,15]

#空のリスト
l_data = []

#ループを回して値を取得し、リストに入れていく
for i in range(0,len(selects)):
    select = selects[i]
    data = d_records[select]

    l_d = list(data.values())     
    l_data.append(l_d)

#リストをデータフレーム化
files_df = pd.DataFrame(l_data,columns=['code','number'])

#選んだインデックスと選ばれたデータを結合して保存
selects = pd.DataFrame(selects)
c_df =  pd.concat((selects,files_df),axis=1)
c_df.to_csv('tenki.csv', encoding='shift_jis')
```
想定しているものはできた。体裁は適宜自分でそろえる必要がありそう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/6382143f-ccb4-f56b-de27-2e32563e8226.png)

##まとめ
今回は試しのためデータ数を少なくしているが、多くなってくるとより便利に使えそう。
データは下記にアップ。
https://github.com/dem-kk/File/tree/main/dict
##参考
https://techacademy.jp/magazine/15639
https://www.delftstack.com/ja/howto/python/python-convert-dictionary-to-list/
[Rails]MVCについて自分の言葉でまとめてみる

先日、RailsのMVCについて説明する機会があったときに、
（緊張も相まって）全く日本語にならず、
「言語化できないって理解してるつもりでも理解できてないってことだな」
と猛反省したので、全くRailsを知らない人にも伝わるように、改めてまとめてみることにしました。
誤っている部分などありましたらご指摘いただけますと幸いです。

#MVCとは
Model　/ View / Controller の頭文字をとってMVCです。
Railsなど、Webアプリケーションを作るときに使うフレームワークの多くが、
このMVCの構造によって成り立っています。

#Modelとは
そのアプリケーションのデータベースの窓口のようなものです。
基本的にはデータベースの各テーブルに一つあって、データベースとのやりとりをしてくれます。

#Viewとは
Webアプリケーションの見た目の部分です。

#Controllerとは
アプリケーションがどう動くかをここで決めています。
（ほとんどが）各Modelに紐づいていて、そのModelにまつわる動きをコントロールしています。

動きをコントロール：Modelにお願いしてデータをとってきたり、そのデータを反映させたviewを返したりしています。

#Routerとは
いきなり出てきましたが、こちらもアプリケーションにとって大切な役割を担っています。
クライアントから渡ってきた、URLとHTTPメソッドから、どのControllerのどのActionを取るか、という指示を出している、案内板みたいなものです。

#ざっくりまとめると
* クライアントからあったリクエストに応じて、
* Routerが「こっちのControllerのこのActionを動かすんだよー」と指示。
* Routerから指示があったControllerが指示されたActionをする。
（Modelを介してデータをやりとりしたり、Viewにデータを渡したり）
* ControllerがActionした結果を、人に見やすい形でViewで表現する。


#参考
[Railsガイド](https://railsguides.jp/getting_started.html#mvc%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B)
manjaro linux　のパソコンを　wifi ルーターにする　create_ap　 systemctl　

https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff

のとおりです


manjaroでしました

yay -Sy create_ap-git


使用したUSB　wifiは

![Photo Marker_20210915_112000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/bf9763e3-1ebc-1550-7f0e-76afe89dc143.jpeg)


```
#  cat /etc/systemd/system/ap.service
[Unit]
Description = wifi access point

[Service]
ExecStart = /home/jaro/ap.bat
Restart = always
Type = simple

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


```
# cat /home/jaro/ap.bat
#!/bin/sh

create_ap --isolate-clients wlp0s29u1u2 enp0s26u1u1 AP 12122345

```



元

```
# ifconfig 
enp0s26u1u1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.90.230  netmask 255.255.255.0  broadcast 192.168.90.255

enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.30.1  netmask 255.255.255.0  broadcast 192.168.30.255

wlp0s26u1u2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
      

```

systemctl start ap.service
すると



```
]# ifconfig 
enp0s26u1u1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.90.230  netmask 255.255.255.0  broadcast 192.168.90.255
      

enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.30.1  netmask 255.255.255.0  broadcast 192.168.30.255
 


wlp0s29u1u2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500 <--ここです
        inet 192.168.12.1  netmask 255.255.255.0  broadcast 192.168.12.255




```

以下のように動いてます


![Photo Marker_20210915_142004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/19712639-1125-3e1c-e462-db69f63a413c.jpeg)
ラズパイで部屋のCO2濃度を測定する

#本記事の内容
- ラズパイで二酸化炭素濃度を測定する。

家に眠っていたラズパイを引っ張り出してきた理由は、
換気により二酸化炭素濃度を測定してみたかったからです。

いざやってみます。

#実施環境
- Windows 10
- TeraTarm Version 4.9.4
- Raspberry Pi 2 Model B
- PLANEX 無線LAN子機 GW-USNANO2A ※Wi-Fi通信のための利用
- MH-Z19B ※二酸化炭素濃度測定用センサー
- GPIOケーブル メス-メス ※MH-Z19BとGPIOピンを接続するために使用
- 家庭内の無線LANネットワーク環境にて実施

#手順の流れ 
1. Raspberry PiにMH-Z19Bを接続する
2. TeraTarmでsshログインする
3. シリアル通信を有効にする
4. TeraTarmでsshログインする
5. 二酸化炭素濃度測定用ライブラリーのインストール
6. 二酸化炭素濃度の測定

## 1. Raspberry PiにMH-Z19Bを接続する
ラズパイとセンサーの接続は、[こちらを参考](https://pypi.org/project/mh-z19/)にさせていただきました。

センサーはこちら。
![IMG20210915110527 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/3fae934b-f537-380b-7341-d6bb1a2bb54e.jpeg)


こちらがラズパイにセンサーを接続した後の状態。
![IMG20210915110351 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/d7ead58d-3c1f-eef6-8571-20e03ef9961a.jpeg)


## 2. TeraTarmでsshログインする

WindowsにてTeraTarmを起動して、ラズパイにSSH接続する。

## 3. シリアル通信を有効にする

`sudo raspi-config`コマンドを実行する。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/04a9c96e-2a13-5497-dff3-d2fc6236b917.png)
3.Interface Optionsを選択する。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/ec1c7e8b-d2dd-5e57-b7e9-c25fbb7a023a.png)
P6 Serial Portを選択する。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/1fc56618-e10a-109e-d0a2-e2b68ebd0453.png)
Noを選択する。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/64e27900-88f7-d49c-fff4-c0a4c984fa38.png)
Yesを選択する。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/2a8b250d-0f00-969f-71be-f25f865d5afe.png)
OKボタンを選択する。

![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/2068ad1e-b8d8-7621-f4f1-444be1cdf017.png)
Finishを選択する。

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/2ebd3127-a53b-b1b4-7792-0dd5669b00c9.png)
Yesを選択し、ラズパイの再起動により設定を有効化する

## 4. TeraTarmでsshログインする

再起動が完了したらWindowsにてTeraTarmを起動して、ラズパイにSSH接続する。

## 5. 二酸化炭素濃度測定用ライブラリーのインストール

二酸化炭素濃度測定用ライブラリーが公開されているので、こちらを活用する。
[Read CO2 concentration from mh-z19 sensor on the Raspberry Pi & handle it. Detect Raspberry Pi model automatically and read the value from an appropriate serial device.](https://github.com/UedaTakeyuki/mh-z19)

パッケージのインストール

	pi@raspberrypi:~ $ sudo pip install mh-z19

パッケージがインストールされたことを確認する。

	pi@raspberrypi:~ $ python -m pip list | grep mh-z19
	mh-z19             3.0.2

## 6. 二酸化炭素濃度の測定

`sudo python -m mh_z19`で確認する。

部屋を閉め切った状態で測定した結果。

	pi@raspberrypi:~ $ sudo python -m mh_z19
	{"co2": 603}
	pi@raspberrypi:~ $

換気をした状態で測定。

	pi@raspberrypi:~ $ sudo python -m mh_z19
	{"co2": 404}
	pi@raspberrypi:~ $

換気をした状態での値が低いような気もするが、目安としては活用できそう！
これから取得したCO2濃度のデータを可視化する方法を考えて行く。

手順は以上。


# 参考文献
本記事の作成に当たり、以下の情報を参考にさせて頂きました。
- [Raspberry Pi 4とMH-Z19Bで二酸化炭素濃度を計測してみた](https://dev.classmethod.jp/articles/raspberry-pi-4-b-mh-z19b-co2/)
- [mh-z19 CO2 concentration sensor library for All models of Raspberry Pi](https://pypi.org/project/mh-z19/)
【Python】importが必要なPythonをAWS Lambda へ移行してみた　事前準備編

#はじめに
昨日、macOSのcronで自動実行するためにmacOSの省電力モードをOFFにすると1ヶ月で1,200円程度電気代がかかるのでは!?という記事を書きました(あくまで試算です)

https://qiita.com/hirockio2206/items/2ce4fcac798a21ad40b4

やはり、オンプレ運用はよくないと。これからはクラウドっしょ！
ただ、AWS Lambdaってよくわからん。
って思っている方いますね？(私)

ってことで本日はAWS Lambda へPython実行環境を移行にチャレンジしてみました。
少し長くなるので、事前準備編とLambda編とEventBridge編で分けて投稿します。

#環境
・既にAWSのアカウントを持っている(お持ちでない方でもすぐ発行できますよ。)
・Python3.9
・macOS Catalina10.15.7
・定期実行したいpythonがある

#事前解説
今回はサンプルとして、ccxtという複数の仮想通貨取引所のAPI操作が集約されたライブラリをAWS Lambdaで実行したいと思います。

AWS Lambdaにはデフォルトではccxtがインストールされていません。
またmacOSならターミナルで簡単にpip3コマンドでccxtをインストールできますが、残念ながらAWS Lambdaにはインストールできません。なので、みなさんが一生懸命作ったpythonプログラムの1行目のimportコマンドでいきなりエラーになります。

```
import ccxt　→エラー発生
```

```
{
  "errorMessage": "Unable to import module 'lambda_function': No module named 'ccxt'",
  "errorType": "Runtime.ImportModuleError"
}
```

この時点でAWS Lambda へPython実行環境を移行を諦める人多いと思います。(私)
でも今日は諦めません。だって電気代高いんだもん！

ではどうすればいいのか。簡単に書きます。

◆事前準備編◆
　1.macOSのデスクトップにtempフォルダを作る
　2.tempフォルダにccxtをpip3でインストールする
　3.既に作ったpythonプログラムを lambda_function.py  へリネームしてtempフォルダに入れる
　4.lambda_function.py の先頭に指定プログラムを追記する
　5.ターミナルでzipでまとめる

◆Lambda編◆
　6.AWSへログインし、5をアップロードする

◆EventBridge編◆
　7.EventBridge (CloudWatch Events)に定期実行ルールを登録する

####今回は1-5までを説明します。(次回以降で6-7)

#手順
####1.macOSのデスクトップにtempフォルダを作る
　1-1.ターミナルを起動します。pwdコマンドで自分がどこにいるか確認します。

```
% pwd
/Users/Hiroki
```

　1-2.デスクトップに移動します。

```
% cd /Users/Hiroki/Desktop
Desktop %
```
　1-3.デスクトップにtempフォルダを作ります。

```
Desktop % mkdir temp
```

　1-4.tempフォルダに移動します。

```
Desktop % cd temp
temp %
```

####2.tempフォルダにccxtをpip3でインストールする

　2-1.ccxtをフォルダ指定してインストールします。

```
temp % pip3 install ccxt -t ./
```

　2-2.デスクトップにあるtempフォルダにccxtフォルダがあるか確認します。

####3.既に作ったpythonプログラムを lambda_function.pyへリネームしてtempフォルダに入れる
![スクリーンショット 2021-09-15 10.33.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1966337/90cb8f72-564d-3a12-13c4-b811d2976258.png)

####4.lambda_function.py の先頭に指定のプログラムを追記する

```lambda_function.py 
def lambda_handler(event, context):
    return {
    }
```
おまじないです。

![スクリーンショット 2021-09-15 10.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1966337/c0c54870-fe7c-6eb1-6778-c8a7ff1c4f01.png)


####5.ターミナルでzipでまとめる

```
temp % zip -r zip_file ./*
```
tempフォルダの中に　zip_file.zip　というファイルがあれば成功です。

#最後に
うまく事前準備できましたでしょうか。
次回はAWSへアップロードして、定期実行を設定していきます。
AWSアカウントをお持ちでない方はご準備をお願いします。

ご参考になれば幸いです。

続き↓

https://qiita.com/hirockio2206/items/4f3d57ae8291bad31004

続き↓

https://qiita.com/hirockio2206/items/bfebfba8f1fc4012f1bb
【GWS】コンテキストアウェアアクセスについて

コンテキストアウェアアクセスのことについてしらべていて、わからないことがいろいろあったので、とりあえず調べたことをまとめました。

事の発端は「BCEでセキュリティチェックに失敗したデバイスをはじけるか？」という疑問から。

前に、Googleの人に話を聴いた時は、その機能はあると言ってた気がしたんですが、今回コンテキストアウェアアクセスをみてみたら、それらしい機能はない。
サブネットIP、OS、接続元の国、設定したアクセスレベル、許可したデバイスのみなど。
https://support.google.com/a/answer/9262032?hl=ja
※他の機能でできる可能性も考えましたが、その場合、BCEの機能の範疇ではなくなると思いました。

で、デバイスの暗号化という項目もあったので、それについてしらべたりもしました。
デバイス暗号化は、device encription。windowsにもあるけど、GWSにもこの機能がある。
https://support.microsoft.com/ja-jp/windows/%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AE%E6%9A%97%E5%8F%B7%E5%8C%96-windows-ad5dcf4b-dbe0-2331-228f-7925c2a3012d#ID0EBBD=Windows_10

以下がデバイスの暗号化の解説があるページ。
https://support.google.com/a/answer/7422256?hl=ja
https://support.google.com/a/answer/6328676#encryption&zippy=
https://support.google.com/a/answer/9587667#zippy=%2C%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%A6%81%E4%BB%B6%E3%82%92%E5%90%AB%E3%82%80-%E3%81%A4%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%AC%E3%83%99%E3%83%AB

要は、デバイスをロック解除したときにだけデータを読み取れるように、デバイスでデータの暗号化を必須にするということみたいなんだけど、これは冒頭の「BCEでセキュリティチェックに失敗したデバイスをはじけるか？」という話からそれるので、この機能はちがう。

脅威からの保護というところで、以下のページにいきついた。
https://support.google.com/a/answer/10104463?hl=ja

以下のような実装もできるので、脅威を防ぐこともできる。
例1：drive.google.comからのファイルのダウンロードをブロックする
例2：30を超えるメールアドレスを含むChromeダウンロードについて警告する
例3：30を超えるメールアドレスを含むChromeアップロードをブロックする
https://support.google.com/a/answer/10104358#zippy=%2Cexample-warn-of-a-chrome-download-that-contains-more-than-email-addresses%2Cexample-block-a-chrome-upload-that-contains-more-than-email-addresses

でも、Chrome Enterprise Connectorsというものも必要らしく、GCPの基本機能では使えない感じ。
https://support.google.com/a/answer/10104463?hl=ja
しかも、この情報を元にIAPを介して接続可能か不可能かを判定する機能があるかもわからない。

###結論
「BCEでセキュリティチェックに失敗したデバイスをはじけるか？」
という機能が具体的にはどれにあたるかわからなかった。
多重共線性

## この記事を読んで分かること
- 多重共線性とは何か
- これが起こるとどうなるのか
- どのようなモデルや状況で起こるのか
- これを解消するためにはどうすればいいのか. 

## 多重共線性とは
多重共線性とは、データの中に相関が強いものが含まれていて、重回帰分析の性能が低下してしまうこと。  
重回帰分析以外のモデル、決定木やsvm, ニューラルネットなど機械学習モデルに関しては起こらない。  
理由を簡単に補足すると、これらのモデルは$y=a_1*x_1+a_2*x_2 \cdots a_n*x_n$のような関係式で表現されないためである。  

相関を簡単に説明すると、あるデータ間で似たような傾向を持つということである。  
また、相関の強さを表現する指標に**相関係数**というものがある。これは次の節で紹介する。  
ここで多重共線性が起こりうるデータの例をあげる。  
例えば、日本においては、年収と年齢は相関関係にある。[国税庁のサイト](https://www.nta.go.jp/publication/statistics/kokuzeicho/minkan1998/menu/03.htm)より引用  
つまり、年齢が大きいほど年収は大きい。  
![salary.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711801/ed443295-a1ff-27ee-b5b1-6173bb05586f.gif)

グラフで表現する場合、相関係数が大きいものはy=xに近く、小さいものは、y=-xに近い。また0の場合は、傾向が見られないようなランダムな配置になっている。
相関の強さとしては、絶対値をとって1に近いもの。つまり相関係数が小さいものも多重共線性が起こりうるので注意が必要である。    

## 相関の大きさを表現する値（相関係数）

相関係数には、いくつかの種類がある。皆さんが高校までで習って一般的に知っているものはピアソンの相関係数である。  
これらに共通する特徴としては、

- -1~1の範囲を取る実数。
- 値が大きい(1に近い）ほど相関が大きく、小さいほど相関が小さい。
- 相関の強さは、**絶対値を取ったときに値が大きいもの**である。(最小が０、最大が１）

これらのうち、ピアソンの相関係数と、スピアマンの順序相関について簡単に説明する。  
前者は、一般的によく使う指標。後者は、変数にカテゴリが含まれているときによく使うものである。  

### ピアソンの相関係数
一般的に使われている尺度がピアソンの相関係数。  
これは、2つの連続変数間の線形関係を評価する。一方の変数が変化したときにもう一方の変数が比例して変化する場合、関係は線形になる。  
この指標は、-1~1の間を動き、大きいほど相関が正であるという。  
強さを知りたいときは、絶対値をとって1に近いほど強いという。

### スピアマンの相関係数
次に紹介するのが、スピアマンの順序相関係数。  
こちらは一言で言うと、カテゴリ変数に対しても相関を見れるというもの。  
上記のピアソンの相関係数は、連続値についてのみ定めたものだが、こちらの相関係数は、カテゴリ変数である順序尺度の変数についても定義できる。

![soukan.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711801/5a64baa4-4f25-89f4-7738-b4e9de9c7040.gif)

[引用元](https://www.toukei.metro.tokyo.lg.jp/manabou/tyuu/sirou2/tokutyou2/ma1206t24b.htm)

## 多重共線性があると起こること
多重共線性があると、相関が強いデータ間の挙動がおかしくなり、モデルの安定性が欠如してしまう。 
解釈としては、変数が一つ足らない(同じものが二つ入っているため)のでうまく方程式を解くことができないと解釈できる。  
 
ランダムシードを変えるごとに、モデルの性能が大幅に変化してしまい、試行ごとに異なった性能のモデルとなってしまう。  
これでは、汎化性能と言った話はできそうもない。  

## 多重共線性の解消法
非常にシンプルだが、***相関が強いデータを取り除けば***良い。  
相関の強さについてだが、相関係数というものを見るのが一般的である。  

ここで、相関が強いはどの程度かという疑問が挙げられるだろうが、一般的な回答は現在存在しない。   
なので各自で判断する必要がある。  
また、これは必ず取り除かなければいけないというよりも、取り除いた方が性能が良くなるなら取り除くべきである、程度なので注意が必要である。（一般的には、変数は多いほどいいので（情報量が多いから）、不必要に取り除かなくて良い）

### どうしても両方使いたい場合
どうしても片方を削除せず、両方使いたい場合の対処としては、主成分分析を行うと良いかもしれない。  
これによって、複数の変数を一つにまとめることができ、両方を考慮しつつより良いモデルの構築ができる。

## まとめ
多重共線性は重回帰分析に起こる現象。  
これが起こるとモデルの汎化性能が下がる。  
解消するためには、相関が強い変数を除けば良い。 

## 参考文献  
- https://teratail.com/questions/215939  
- https://support.minitab.com/ja-jp/minitab/18/help-and-how-to/statistics/basic-statistics/supporting-topics/correlation-and-covariance/a-comparison-of-the-pearson-and-spearman-correlation-methods/
- https://toukeier.hatenablog.com/entry/2019/09/07/200648
- https://www.albert2005.co.jp/knowledge/statistics_analysis/multivariate_analysis/multiple_regression
Google API Refresh Tokenを取得するまで

いつも調べるので、メモ

## とりあえず↓これみとけ
https://qiita.com/chenglin/items/f2382898a8cf85bec8dd

## ↓をブラウザで開く
```
https://accounts.google.com/o/oauth2/auth?client_id=[クライアントID]&redirect_uri=http://localhost:3000&scope=[スコープ]&response_type=code&access_type=offline
```

※スコープが複数ある場合はスペース区切り


## ↓をcurl
上でリダイレクトされたクエリーパラメータのcodeをURLデコードして

```
curl -d client_id=[クライアントID] -d client_secret=[クライアントシークレット] -d redirect_uri=http://localhost:3000 -d grant_type=authorization_code -d code=[上で取得できたcode] https://accounts.google.com/o/oauth2/token
```
初学者こそ英語教材でプログラミングを学んだ方がいいかも

初学者である僕がプログラミング学習との向き合い方を再考させられる体験があったので、ポエムとして軽く書いておきます。テックな記事でないので、その点悪しからず。

僕はいま独学でReactを勉強しているのですが、公式ドキュメントだけだとどうしても厳しいし、何かいい教材は無いか、、そう思っていた時に、普段は避けていた英語圏の動画が目に留まりました。

YouTubeのこの動画です↓

https://www.youtube.com/watch?v=Dorf8i6lCuk&t=3631s

なんとなく、これをやってみることにしました。
一通り終えてみて**「日本語の教材より英語の方がわかりやすくね？」**と思ってしまいました。ちなみに僕は英語はほぼわかんないです。中学英語ですら怪しいレベル。

じゃあなぜ、わかりやすいと思ったのか？
英語でプログラミングを学ぶことについて僕なりの発見がありました。

## "日本語"でプログラミングを学ぶことの難しさ
僕たちは「プログラミングを始めるぞ！」ってなった時にはひとまず、日本語のドキュメントなり教材なりをあたりますよね。ほとんどの人がそうのはず。

当然母語だからこそ全ての情報を読み取れる（聞き取れる）わけですが、初学者の段階においてはこれがかえって仇となるケースもある。そんな話です。


### ■俺は"言葉"に支配されっぱなしだけど、皆はどう？

僕はプログラミング学習を進める中で、**「学んだことが理解できていない」**という初学者にとってある程度スルーすべき事象に対して、**「正面からぶつかり過ぎてしまう」**ことが非常に多いです。

というのも僕は何かを学ぶ際、言葉の意味を理解し納得できるまで立ち止まってしまうという癖があります。その割には理解力が低いのでいつまでたっても学習が進まない。当然手を動かす時間も減ってしまうわけです。(👺ワーキングメモリが低い！)

とくにプログラミングの”概念”を学ぶ際に、「なぜそうなるのか」「これにはどういう意味があるのか」みたいなことをいちいち深掘りしていると、本当に疲弊してしまいます。（多分、初学者が一番考えてはいけないことです）

そして言葉の意味や定義に支配されてしまうあまり、
**手を動かすことがおざなりになってしまう、あるいは手を動かすことを辞めてしまう**
こういった悪循環に陥ることが良くあります。

### ■「とにかく手を動かすべき」なのは分かってるつもりだけど...

プログラミングの学習というのはある種の説明地獄です。
だからこそ、**完全に理解できてなくてもいいからまずは一度手を動かして何か完成させる**
のが上達の近道だと言われているのだと思います。

つまりは、一度フカン視点で全体感を掴むことが大切。

わかっちゃいるんですけどね。。
僕は、説明されたものはできるだけクリティカルに理解しなければいけない気がする。そうでなければ先に進んだことにはならないのではないか、こういう**病的な強迫観念**に襲われてしまう。

分からないことに対して能動的になれるのは良いことだと思うのですが、僕の場合は少しやり過ぎ、考え過ぎの傾向が強いです。

まあ、こういう人もいるわけです。


## 英語で学習してみて良かったと思うこと

冒頭で述べた通り、YouTubeに転がっている英語のReactチュートリアル動画をやりました。ここからはその感想です。

### ■とにかく手を動かすことに専念できた
だって何言ってるかほとんど分からないんだもの。（笑）
しかし見まねで一緒に手を動かしていると、「何をしようとしているのか」が**ふんわりと**掴めることに気づきました。（Reactに関しては若干の前知識はあった）

たとえば「props」というものが出てきた時
**「props」ってなんだろう？**とかいちいち反応する必要はなくて、何回も書いているとさすがになんとな～く役割がわかるようになってきます。
その時点で「props」をクリティカルに理解している必要はないし、そもそもそう思うこと自体が**初学者の傲慢でしかない**という風にすら思いました。

少なくともビギナーの段階においては、
**・ほぼ何言ってるか分かんねえけど、ところどころ知ってる単語や表現があるから何となくわかる**
**・黙って書け、雰囲気を味わえ**
こういった *Don't think, feel.* な環境のほうが健全なのではないか？

そしてなにより、曲がりなりにも自分で書いたコードが動くのは気持ちいい！！ということも改めて実感しました。


### ■ちょうどいい感じに能動的になれる
「手を動かしていく中で何回も出てくるけど、いまいちわからないな～」と思ったところだけ都度ググるということをやりました。逆にいちいち調べずにスルーしているところもたくさんある。でも今はそれでいいんです。このくらいの情報密度でいい。

何より、**自分で書いて動かした後に意味を調べるほうが圧倒的に理解は早まる**ということを体感しました。

### ■英語アレルギーも改善される（多少はね？）
そもそもほとんどのプログラミング言語は英語主体で作られているわけなので、英語がきちんと読める、聴けるに越したことはないです。
英語のレクチャー動画を見るだけで英語がマスターできるわけではありませんが、英語圏の"言い回しやノリ"みたいなものを肌で感じることはできます。これはプログラミングの学習に限らず結構でかいメリットだと思います。

### ■日本語での補完は必須
英語教材でのプログラミング学習はあまり深く考えず手を動かすことに集中できるので、全体感を掴むのにはうってつけです。ただし、細かい部分はさすがにわかんないままです。

なので、ある程度手を動かしてその言語やフレームワークの雑感を掴んだら、細かい部分は日本語のリソースで補完していく。こういう感じで学習を進めていくのがいいんじゃないかと思います。


## 話をまとめる

この記事で言いたいことをまとめると、

- 物事を一度に全部理解しようとするのはある種の傲慢
- プログラミング学習は日本語（母語）にこだわらなくていい
- 言葉に支配されたら終わり
- ようつべでよく見る英語のプログラミング動画はガンガン使うべき

こんな感じです。

僕みたいに不器用な思考回路の持ち主も中々いない思いますが、もし共感する部分があれば是非YouTubeに転がっている英語のプログラミングレクチャーを試してみてください。

**言葉が全部分からない方が良いこともあるんです。**

ちなみに、ロシアとか東欧系の、未知の言語の動画はさすがにキツかったです（笑）

なにか思うことがあれば是非コメントにお寄せください。
~~本質的には言語の問題ではなく、筆者の性質・理解力に問題があるんじゃね？~~

～それでは～
AWS lambda＠Edge単体テスト（イベントテンプレート）

AWS lambdaを書く時、いちいちデプロイしてテストしてました。

実際どういうリクエストが来るかはある程度イベントテンプレートでまかなえるようです。
lambda@edgeを書いていて、デプロイなどがとても面倒でしたが、これでかなり進みました。

以下の画像は`cloudfront-normalize-querystring-to-improve-cache-hit`というテンプレートです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/00c80761-4629-87d1-e7fb-5760718bea81.png)

単純にCloudfrontにGetリクエストが来たような感じですかね

```
curl https://[CFドメイン]/test?size=LARGE&color=RED
```


実際に受け取るeventと比較してキー名などは一致してるみたいなので、使えそう.

もしCookieをつけるなら以下のようなものを`headers`ブロックに追加してあげれば良さそう。

```
"cookie": [
　　{
　　　　"key": "cookie",
　　　　"value": "aaaaa=hogehoge; hoge=200000; status=200"
　　}
],
```
[WIP] Nextjs で react-json-viewで `window is not defined` がでたときの対処　


詳細は後ほど書く。（必ず）

![スクリーンショット 2021-09-13 3.41.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/8f579222-6f8a-8074-507a-02b3fac01d67.png "スクリーンショット 2021-09-13 3.41.12.png")


対策

以下のようにdynamic importを使う

```
import React from 'react'
import { ScrollBox } from '../Common/ScrollBox'
// import ReactJson from 'react-json-view'
import dynamic from 'next/dynamic'
// `window is not defined`対応のため、Dynamic Importを使っています。 https://zenn.dev/ninomium/articles/5fed8af69640a6
const ReactJson = dynamic(() => import('react-json-view'))
// import { CodeDebugger } from '../CodeDebugger'

interface Props {
  src?: any
  width?: string
  height?: string
}

const ReactJsonViewContainer = ({ src = null, width = '100%', height = '100%' }: Props) => {
  // console.log(src, 'json')
  //
  return src ? (
    <ScrollBox width={width} height={height}>
      <ReactJson src={src} />
      {/* {CodeDebugger(src)} */}
    </ScrollBox>
  ) : null
}

export default ReactJsonViewContainer

```


参考
[Next.jsで`window is not defined` を解決する(依存ライブラリ対応)](https://zenn.dev/ninomium/articles/5fed8af69640a6)
puppeteer用のDockerFile (alpine)

ブラウザー操作を自動化して情報取得するためにpuppeteerを使いはじめました。alpineベースで日本語対応まで動作確認したものをここで公開しておきます(2021/9現在）

いろいろやっていたら今は[Playwright](https://playwright.dev)の方が流行のようなのでそちらも書きました(2021/9/15)

https://qiita.com/bellx2/items/cd99c39bcb9e46b969a1

## Dockerファイル

- 日本語対応のためにフォントを追加しています。

```docker:DockerFile
FROM alpine

# Installs latest Chromium package.
RUN apk add --no-cache \
      chromium \
      nss \
      freetype \
      harfbuzz \
      ca-certificates \
      ttf-freefont \
      nodejs \
      yarn

RUN apk add --no-cache curl fontconfig \
  && curl -O https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \
  && mkdir -p /usr/share/fonts/NotoSansCJKjp \
  && unzip NotoSansCJKjp-hinted.zip -d /usr/share/fonts/NotoSansCJKjp/ \
  && rm NotoSansCJKjp-hinted.zip \
  && fc-cache -fv

# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
    PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Puppeteer v10.0.0 works with Chromium 92.
RUN yarn add puppeteer@10.0.0
```

## サンプル

```js:yahoo.js
const puppeteer = require('puppeteer')

;(async () => {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage'
    ]
  })

  try {
    const page = await browser.newPage()
    await page.goto('https://www.yahoo.co.jp/')
    await page.screenshot({ path: 'yahoo.png', fullPage: true })
  } catch (e) {
    console.error(e)
  } finally {
    browser.close()
  }
})()

```

# 参考

https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker
Windows10でWindowsUpdateを任意のタイミングで実行するために自動更新を停止する

#はじめに
WindowsServerではなく、Windows10でシステム運要をしているとどうしても自動更新と再起動が計画外で動いてしまうのが困ります。
ここでは自動インストールを停止させる方法を記載します。
セキュリティ上パッチは絶対にあてるべきなのでなるべく早く手動で当てるようにしましょう。
システムで使うものはHyperVなどで仮想化しておけば、パッチ充てる前にスナップショット取るなどの運用が出来て便利です。

##1.「自動更新を構成する」を有効にする
※Windows10のPro版を想定しています。

1.「Windows」＋「R」を押して「gpedit.msc 」と入力し、OKを選択します。
![windows10up01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/502f2fa9-5a77-e4c3-bbde-b0194efec396.png)

2.コンピュータの構成>管理用テンプレート>Windowsコンポーネント>Windows Update を開きます。
![windows10up02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/f0870d05-2286-3a52-813c-df6417a238f7.png)

3.「自動更新を構成する」を有効にして、「3-自動ダウンロードしインストールを通知」を選択してOKをクリックする。
![windows10up07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/169169b7-e883-7829-6d08-96f8d0da5c90.png)

これを実施しておかないと次の2つの設定が有効になりません。

##2.「自動更新を直ちにインストールすることを許可する」を無効にする
![windows10up08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/315d4663-8c91-1215-bd40-e8d1f47ff89d.png)

##3.「スケジュールされた自動更新のインストールで、ログオンしているユーザがいる場合には自動的に再起動しない」を有効にする
![Snipaste_2021-09-15_14-14-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/71762408-9563-507f-88a9-6d8f68b85b7f.png)
これで勝手に再起動しなくなるはず。


##4.設定の確認
1.Windowsボタンをクリックして、設定をクリックします。
![windows10up04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/1ae93836-b9ae-a5e4-67e7-ec4333f48af3.png)

2.一番下にある、「更新とセキュリティ」をクリックします。
![windows10up05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/dcd9ab4f-2194-6a6c-f92e-678ba6cdc725.png)

3.「一部の設定は組織によって管理されています」と表示されればOKです。
![windows10up06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989393/564529b1-78c8-d1e4-5128-cb03c2159a70.png)

環境によってはWindows10のボリュームライセンス等を契約していてる場合もあると思いますので、OSの費用削減のためWindows10Proを利用してみてもよいのではないでしょうか？
(その分この設定のようにこまごまとしたことを実施しなければいけないのですが・・・)
GitHub Actionsで複数のDockerfileをまとめてビルド

# 要約

単一のGitリポジトリ（モノレポ）でマイクロサービスを管理する場合，複数のDockerfileをまとめてビルドする必要がある．この記事ではGitHub Actionsで複数のDockerfileをまとめてビルドし，GitHub Container Registry(ghcr.io)へプッシュする方法を述べる．

[動作例](https://github.com/cdsl-research/doktor-v2/actions/runs/1232946651)を以下に示す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/eb38fae7-9b3a-8278-fde7-fad6ea08880a.png)

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/60184690-3d2d-00bc-2cb8-4760d1a872a8.png)

# ディレクトリ構成

ビルドするDockerfileとプロジェクトのディレクトリ構成を以下に示す．プロジェクトルートの配下にあるauthor, front, front-admin, paper, thumbnailがそれぞれのサービスをあらわす．各サービスのコンテナイメージをビルドする場合，それぞれのディレクトリ(例: author)へ移動し，`docker build`を実行する必要がある．

```
.
├── author
│   ├── Dockerfile
│   ├── main.py
│   └── requirements.txt
├── front
│   ├── Dockerfile
│   ├── main.py
│   └── requirements.txt
├── front-admin
│   ├── Dockerfile
│   ├── main.py
│   └── requirements.txt
├── paper
│   ├── Dockerfile
│   ├── main.py
│   ├── requirements.txt
└── thumbnail
    ├── Dockerfile
    ├── main.py
    └── requirements.txt
```

# 構成ファイル

GitHub Actions用の構成ファイルを次に示す．`jobs.<job_name>.strategy.matrix.target`にターゲットを列挙する．コンテナレジストリはGitHub Container Registy(ghcr.io)に設定した．コンテナへ付与するタグはGitのコミットハッシュを使った．コンテナのビルド時のターゲット(context)とタグ名を変数 `matrix.target` で組み立てることで複数のコンテナイメージのビルドを実現した．

```yaml:image-build.yml
name: Build container images
on:
  push:
    branches:
      - master

jobs:
  build-and-push:
    runs-on: ubuntu-20.04
    permissions:
      contents: read
      packages: write

    # 複数のDockerfileが配置されたディレクトリを列挙
    strategy:
      matrix:
        target: ["author", "front-admin", "front", "paper", "thumbnail"]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to the Container registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set image tag for master
        if: github.ref == 'refs/heads/master'
        run: |
          COMMITID=$(git rev-parse --short ${{ github.sha }})
          echo "DOCKER_TAG=master-${COMMITID}" >> $GITHUB_ENV

      # 並列でContainer Imageをビルド
      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: ./${{ matrix.target }}
          push: true
          tags: ghcr.io/cdsl-research/${{ matrix.target }}:${{ env.DOCKER_TAG }}
```

# おわりに

GitHub Actionsでのコンテナイメージの並列ビルドが思った以上に簡単にできた．`target`に指定するDockerfileの存在するサブディレクトリを自動的に検出できるとハードコードが必要なくなり良いと思った．
Fundamental Statistics for Data Science (Part 01)

This article series will present some of the statistical concepts you need to learn when paddling down the data science exploration.
 While you are beginning your data science or analytics journey, having statistical awareness will assist you in leveraging data insights. We cannot underrate the significance of statistics in data science and data analytics.

Acknowledging the fundamentals of statistics will empower you to think better and be creative when utilizing the data to solve issues.

###### 1) Population and Sample
In statistics, populations mean the set of all the observations. It is usually very large. Moreover, a sample is a subset of observation from the population, ideally true population representation.
Researching with an entire population is impossible most of the time. So researchers use subset (sample) rather than the entire populations for an experiment. For accurate results, the sample should represent the population, which is termed an unbiased subset. There are several sampling methods for getting samples from populations.

![16452707.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579376/fc04c599-f8b3-0582-d357-7c1413eee9bb.jpeg)

Image Source: https://www.vectorstock.com/royalty-free-vector/sample-from-population-statistics-research-survey-vector-16452707

###### 2) Random Variable
In mathematics, we used variables. However, here it is a bit different. So forget about the mathematical definition. A random variable is used to save the outcomes of a random process. For example, when flipping a coin, random variable X can be head(1) or tail (0). When throwing a dice, random variable X can be 1,2,3,4,5,6.

###### 3) Sample Space
![Tex2Img_1630311051.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579376/0aa8a4a2-71c5-0b6c-e9a6-0c857bc9a51c.jpeg)

Think about throwing dice, and it can give six possible outcomes. Values can be 1,2,3,4,5, or 6. {1,2,3,4,5,6} this set of all possible outcomes defined as sample space of a experiment. 

###### 4) Probability
Chance (Likelihood) of getting a particular outcome of an event is defined as probability. Let us think about the same example above, throwing a dice. So we know that X={1, 2, 3, 4, 5, 6}. So the sample size is six.

Likelihood (probability) of getting 4 when can be written as;
**P(X = 4) = 1/6**

Similarly, probability of getting an even number can be written as;
**P(X = even number) = 0.5**

It is important to note that, for an event probability range should be within [0,1]

Let's continue from part 02

*本記事は @qualitia_cdevの中の一人、@nuwanさんが書いてくれました。
*This article is written by @nuwan a member of @qualitia_cdev.
Python開発環境設定・確認のメモ

```:Pythonバージョンの確認
python -V
```

```:環境の一覧表示
workon
```

```:環境「azure」のアクティブ化
workon azure
```

```:pip自体をアップグレード
pip install --upgrade pip
```

```:インストール済みのパッケージの一覧表示
pip list
```

```:環境「azure」の非アクティブ化
deactivate
```

```:環境「azure2」の作成
mkvirtualenv azure2
```

```:環境「azure2」の削除
rmvirtualenv azure2
```

# 導入

```bash
sudo pip3 install virtualenv
sudo pip3 install virtualenvwrapper
vim ~/.profile
```

```bash:.profileに追記
source /usr/local/bin/virtualenvwrapper.sh
export WORKON_HOME=~/.virtualenvs
```
GETリクエストするときは、リクエストボディを使わないでね

# 結論
GETリクエストするときは、リクエストボディではなくクエリストリングかパスパラメータを使いましょう。(掲題どおり)

# ハマったこと

クライアント側はこのように呼び出し(ちなみにReactでAmplifyを使っています)

```react:apiCall.tsx
import { API } from "aws-amplify";

export const hoge = async (
  hogeId: string
): Promise<void> => {
  const apiName = "hogeAPI";
  const path = "/";
  const params = {
    body: {
      hogeId: hogeId,
    },
  };
  return await API.get(apiName, path, params);
};
```

APIはLambdaを使います。Lambda側ではこのように受け取り

```js:lambda.js
exports.handler = async (event) => {
  const parameter = JSON.parse(event.body);
  const hogeId = parameter.hogeId
  // あとは割愛
}
```

ただこれでAPI呼び出すと502。CloudWatchログを見てみると、bodyがnull。

GETで呼び出しするのにbody指定なのが良くない。

正しくはこう。

```react:apiCall.tsx
import { API } from "aws-amplify";

export const hoge = async (
  hogeId: string
): Promise<void> => {
  const apiName = "hogeAPI";
  const path = "/?hogeId=" + hogeId;
  const params = {};
  return await API.get(apiName, path, params);
};
```

Lambda側は下記。
このとき渡ってくる`queryStringParameters`の中身を見ると、一見JSON文字列のように見えて、値の部分がダブルクオートで囲まれていないため、このまま`JSON.parse`するとエラーになってしまう。
一度`JSON.stringify`するといい。

```js:lambda.js
exports.handler = async (event) => {
  const parameter = JSON.parse(JSON.stringify(event.queryStringParameters));
  const hogeId = parameter.hogeId
  // あとは割愛
}
```

これで呼び出し成功。
GETでリクエストボディ指定しちゃダメなのは基本ですが、よく忘れてハマってしまうため備忘録メモ。

蛇足だがReactでAPIコールするときはこんな感じで呼び出せばいい。

```react:client.tsx
import hoge from "path/to/apiCall";
hoge("hogeId")
    .then((res) => {
      console.log("success");
    })
    .catch((e) => {
      console.error(e);
    });
```

もっといい書き方がある気がしているので、あくまで参考程度でお願いします。
動画で学ぶJHipster (6) fakerの削除

# 参考動画
https://www.youtube.com/watch?v=6lf64CctDAQ

# fakerの削除
(動画の6:00ごろ～)
データを自動生成してくれるfakerですが、（動画の流れで）削除します。

削除する方法は、
`src/main/resources/config/application-dev.yml`の、以下の部分のfakerを削除して、

```
  liquibase:
    # Remove 'faker' if you do not want the sample data to be loaded automatically
    contexts: dev, faker
```
下記のようにします。

```
  liquibase:
    # Remove 'faker' if you do not want the sample data to be loaded automatically
    contexts: dev
```

さらに、`./mvnw clean`を実行します。すると、H2 databaseに入っているデータが削除されます。

その後、mvnwで再起動すると、以下のようにデータが消えた状態になります。
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/213c590e-18a4-14f3-611a-cdeef880baf5.png)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/89036c5a-cecb-49f1-29cf-6e0771efb722.png)
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/3f96ae17-047b-d999-868e-10697a82b9de.png)

# コード
https://github.com/sayuu-tf/learning_jhipster_3/commit/5b9c2f188022bb0e4323da5247512bb592f82cc2
メモ：Shell Script

# 概要
Shell Scriptのメモです。

# ファイルの1行にIDが書いてあるのを10個ずつ1行にまとめる

```bash
#!/bin/bash                                                                                                                                                     
DATA=`cat ./aaa`
MAX1LINE=10
COUNTER=0
COMBINE=""
while read line
do
    if [ `echo "${COUNTER}%${MAX1LINE}" | bc` -ne 0 ] ; then
        COMBINE=`echo ${COMBINE}, ${line}`
    else
        if [ ${COUNTER} -ne 0 ] ; then
           echo ${COMBINE},
        fi
        COMBINE=`echo ${line}`
    fi
    COUNTER=`echo "${COUNTER}+1" | bc`
done << FILE                                                                                                                                                    
$DATA                                                                                                                                                           
FILE                                                                                                                                                            
echo ${COMBINE}

echo " >> lines=["${COUNTER}"]"
```

# メモ
- [Bash の構文: 関数から戻り値を返す | まくまくLinux/Shellノート](https://maku77.github.io/linux/syntax/return-value-from-function.html)
- [Array Loops in Bash](https://stackabuse.com/array-loops-in-bash/)
【AWS】AWSでデプロイ後にhttps化する方法


#対象者

* AWSでデプロイをおこなった方
* https化したい方


#目的

* 　https化してWebサイトのセキュリティをより強固にする

#実際の手順と実例
###1.　httpとhttpsの違い

２つの違いは
**通信内容が暗号化されているかどうか**です。
httpのままだとSSLが未導入であるということになります。

#####SSLとは
* インターネット上の通信を暗号化する技術のこと

https://ds-b.jp/media/what-is-https/


###2.前提

* AWSでデプロイしていること
* nginxがインストールされていること
* EC2でAmazon Linux **2**で環境構築していること

[Amazon Linuxのもつ特徴7つ｜AWSとの関係も解説](https://www.fenet.jp/infla/column/technology/amazon-linux%E3%81%A8%E3%81%AF%EF%BC%9Famazon-linux%E3%81%AE%E3%82%82%E3%81%A4%E7%89%B9%E5%BE%B47%E3%81%A4/#%E3%80%8CAmazon_Linux%E3%80%8D%E3%81%A8%E3%81%AF%EF%BC%9F)


###3.CertBotを利用してhttps化する

####1.EC2のセキュリティにhttpsを追加

* EC２に紐付いているセキュリティグループを選択
* インバウンドルールにhttpsを追加します。

####2.nginxのconfファイルを編集

Terminalに以下のコマンドを打ってファイルを開きます。

````Terminal.
vi /etc/nginx/conf.d/アプリケーション名.conf
````

`````/etc/nginx/conf.d/アプリケーション名.conf
:
:

server {
  server_name  ドメイン名;
  root /home/ec2-user/nginx-puma-deploy/public;

  access_log  /var/log/nginx/access.log  main;
  error_log /var/log/nginx/error.log;

  sendfile            on;
  tcp_nopush          on;
  tcp_nodelay         on; 
  keepalive_timeout   65;
  types_hash_max_size 2048;
  client_max_body_size 100M;
  include             /etc/nginx/mime.types;

  location / {
      proxy_pass http://puma;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_redirect off;
      proxy_connect_timeout 30;
      proxy_set_header X-FORWARDED_PROTO https; #これを追加
  }

:
:
`````

※　viコマンドに関してはこちら

https://qiita.com/nao0725/items/73f844241d476a7ed8c2


####3.Certbotを実装

開発環境のターミナルから
**EC2にSSH接続をして**
下記のコマンドを順に打ってください

```
$ cd 
$ sudo wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
$ sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
$ sudo yum-config-manager --enable epel*
$ sudo yum install -y certbot python2-certbot-nginx
$ sudo certbot --nginx
```

最後のコマンド実行後下記５つの質問があります。
（Terminalには英語で表示されます。）

````Terminal.
1.緊急時の通知用メールアドレスを入力 し、［Enter］キーを押す
2.利用規約への同意が表示されるので、「Y」と入力 して［Enter］キーを押す
3.Electronic Frontir Foundationへのメール共有を訊かれるので、「N」と入力 して［Enter］キーを押す
4.対象ドメインを確認し、数字をカンマ区切りで入力して［Enter］キーを押す
5.HTTPへのアクセスをHTTPSに自動リダイレクトを訊かれるので、「2」と入力 して［Enter］キーを押す
``````

下記のように表示されれば、https化完了です！

```Terminal.
Congratulations! You have successfully enabled https://hoge.com 
````

#####Certbotとは
* 無料かつ自動でSSL証明書を発行できるツールです。

https://avinton.com/academy/creating-ssl-certificate-by-certbot/

#参照

* [Certbotを使ってSSL証明書を発行し、HTTP通信を暗号化しよう](https://avinton.com/academy/creating-ssl-certificate-by-certbot/)
* [httpsとhttpの違い](
https://ds-b.jp/media/what-is-https/)
* [Amazon Linuxのもつ特徴7つ｜AWSとの関係も解説](https://www.fenet.jp/infla/column/technology/amazon-linux%E3%81%A8%E3%81%AF%EF%BC%9Famazon-linux%E3%81%AE%E3%82%82%E3%81%A4%E7%89%B9%E5%BE%B47%E3%81%A4/#%E3%80%8CAmazon_Linux%E3%80%8D%E3%81%A8%E3%81%AF%EF%BC%9F)
【Rails】Data Confirm Modal - backdrop

# backdrop とは

直訳すると劇場幕のことで、Webではモーダルを開いたときの背景の黒いところのことを言います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/92b710bb-801a-a907-c6a7-e9a50cffd2e3.png)

# backdropをクリックしてもモーダルが非表示にならない方法

```javascript
dataConfirmModal.confirm({
  title: 'Are you sure?',
  text: 'Really do this?',
  commit: 'Yes do it',
  cancel: 'Not really',
  zIindex: 10099,
  onConfirm: function() { alert('confirmed') },
  onCancel:  function() { alert('cancelled') },
  onHide:    function() { alert('hidden') },

  // これを追加することで、backdropをクリックしてもモーダルが非表示にならない
  backdrop: 'static'
});
```

# 参考
* GitHub ifad / data-confirm-modal
    * https://github.com/ifad/data-confirm-modal

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/