OmniAICreator/Qiita-1.07M huggingface dataset:
【Kubernetes】Kubernetesの概要について　no.1

![名称未設定のデザイン (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/02dc910e-c2ab-8dfd-30a2-e49ffc180768.png)

こんにちは。まゆみです。

Kubernetesについての学習について、備忘記録を兼ねて記事にしていこうと思います。

今回は第1回目のKubernetesについての記事になります(前回、Kubernetesのツールの1つ『minikube』のインストール方法について書かせていただきました。)

今回の記事では、Kubernetesの大まかな概要を書いていこうと思います

では、さっそく始めていきますね。

#Kubernetesでできること

KubernetesはDocker Containerの代わりになるものではなく、

<font color="Red">Docker Containerと共に働き</font>、主に以下のようなことをしてくれる便利なツールです。

<ul>
<li>Containerがクラッシュした時に自動的に新しいものにしてくれる</li>
<li>トラフィックが増えた時に自動的にContainerを増やしてくれる</li>
<li>複数のContainerを使っているのなら、トラフィックを均等に分配してくれる</li>
</ul>

今までDockerを使ってサービスを立ち上げてきたと思いますが、例えば

>Containerの数が100くらいになって手作業でマネージメントするには限界が出てきた。

>夜中の3時にトラフィックが急増するので、その時インスタンスを増やしたいんだけど。。。

と言った時に、一つづつ手作業でContainerを実行したり削除したりリスタートさせたりするのは大変だと思います。

そのような時に役に立つツールが『Kubernetes』になります

#どうしてKubernetesなの？

前のセクションでKubernetesができることを書かせていただきました。

ただ、AWSを学習したことがある方なら

<font color="Red">『それって、AWSのECSでできることやん？！』</font>

と思われたと思います。

AWSのサービスECSも、自動化するツールの選択肢の一つとして良いと思います。

しかし、<font color="Red">AWSのサービスではAWSのルールに従ってサービスを使わなければいけません。</font>

ゆえに、もし違うクラウドサービスを使いたくなった時にまた一からやり直さなければいけなくなってしまいます。

そこで、Kubernetesの出番です。

#Kubernetesで使われる用語

![見出しを追加 - 2021-07-16T115415.938.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/6cc05d4d-88ba-d38b-6245-f8d828c65648.png)

##Pod
 
Kubernetesの構築の中で最小の単位が『pod』と呼ばれるものになります

Podがその中にContainerを抱えています。

Podの中のContainerは1つだけのことも、複数あることもあります。

##Worker Node

Worker Node はどこか遠くのクラウド上にある、あなたのマシーンのようなものです。

AWSのEC2インスタンスのようなものですね。

Worker Nodeの中のPodの中にあるContainer化されたアプリケーションを実行する事ができます

ゆえに、Worker Node は最低1つ以上は必要です。(さもないとpod、つまりContainerを実行する場が無いということなので。。。)

Worker Nodeの中に、

>コピーした同じpodを置くことも(アップスケーリングする場合)

>または全く違うpodを置くこともできます。


Worker Node はもちろん複数使用することも可能です。


また、Worker Nodeとpodをどちらも複数利用するとき、podはWorker Nodeに均等に分配されます。

Worker Nodeにインストールする『kubelet』はWorker NodeとMaster Nodeのコミュニケーションツールになります

##Master Node

Worker Node やpodをコントロールするものが、Master Node と言われます。

そのMaster Nodeのなかにインストールされる主なソフトウェアを紹介します

###Scheduler

新しいpodが必要となる状況になった時、そのpodがどのWorker Nodeで作られるべきかなどを司ります。

###Kube-Controller-Manager

Worker Nodeを全体的に管理する役割を持ったものです。

正しい数のpodが実行されているかなどを確かめます。


##Cluster

上記のもの全てを包括したものが『Cluster』と言われるものになります

Clusterの中で、上記のコンポーネントが結びつなげられています


また、ClusterはKubernetesが用意してくれるものではなく、<font color="Red">あなた自身が準備をしなければいけません。</font>

Kubernetesはあなたが作ったClusterを利用するだけです。

#まとめ

今回の記事はこのあたりで締めくくらせていただきます。

次回の記事からはより具体的な内容に進んで行こうと思います<(_ _)>
JavaScript クラス

#クラス

モノを生成するための設計図をクラスと言います。

class クラス名　　{

}で表します。クラス名は大文字で書かれることが好まれています。
そうすることで、インスタンスは小文字で書くことができ、
クラスとインスタンスで同じ単語を使っても被らなくなります。


#インスタンス

上記で設定したクラスからオブジェクトを生成します。
クラスから生成したオブジェクトをインスタンスと言います。

インスタンスの生成方法は
new クラス名();です。

#コンストラクタ

クラスの中にconstructor() {}と記述することで、
インスタンス生成時にコンストラクタの中身を出力することができます。

コンストラクタに中にthisを使うことでプロパティを生成することができます。
thisはインスタンスを表していると思って下さい。

また、インスタンス毎に値を変える時はconstructor()のカッコに
引数を定義して下さい。

```JavaScript
class Animal {
  constructor(name, age) {
   this.name = name;
   this.age = age;
  }
}

const animal = new Animal("ジョン",8);
console.log(`名前: ${animal.name}`);
console.log(`年齢: ${animal.age}`);
```

#メソッド

メソッドはインスタンスの動作を表しています。
また、処理をまとめるとも表現します。

クラスの中でメソッド名() {}と表します。
メソッド内で変数を使う時はthisを使います。

メソッド内で他のメソッドを呼ぶ時もthisを使います。
this.メソッド名();

```JavaScript
class Animal {
 constructor(name,age) {
  this.name = name;
  this.age = age;
  }

 greet() {
  console.log("こんにちは");
 }

 info() {
  this.greet();
  console.log(`名前は${this.name}です`);
  console.log(`${this.age}歳です`);
 }
}

const animal = new Animal("ジョン",8);
animal.info();
```

#継承

既にあるクラスをもとに、新しくクラスを作る時は継承を行います。
例えば上記のようにanimalクラスからdogクラスを作る時は
class Dog extends Animal {}を使います。
このようにclass 新しいクラス extends 元のクラスで継承を行います。
元のクラスを親クラス、新しいクラスを子クラスと呼びます。

継承すると全ての機能が使えるようになります。
なので、今回だとinfoメソッドなどが使えるようになります。

#オーバーライド

継承をした際にどちらのクラスにも同じメソッドがある場合、
どちらのメソッドが採用されるのでしょうか。

それは子クラスのメソッドが採用されます。
このことをオーバーライドと言います。

同様にコンストラクタもオーバーライドできます。
その時、同じ箇所はsuperを使って表します。

```JavaScript
class Animal {
 constructor(name,age) {
  this.name = name;
  this.age = age;
  }

 greet() {
  console.log("こんにちは");
 }

 info() {
  this.greet();
  console.log(`名前は${this.name}です`);
  console.log(`${this.age}歳です`);
 }
}

class Dog extends Animal {
 constructor(name,age,breed) {
  super(name,age)
  this.breed = breed;
  }

 info() {
  console.log(`名前は${this.name}です`);
  console.log(`犬種は${this.breed}です`);
  console.log(`${this.age}歳です`);
  const humanAge = this.getHumanAge();
  console.log(`人間年齢で${humanAge}歳です`);
  }

  getHumanAge() {
    return this.age * 7;
  }
 }

const dog = new Dog("レオ", 4,"チワワ");
dog.info();
```

#最後に

初心者ですので、拙い文章や書き方だと思いますが、最後まで見て頂き
ありがとうございました。もし、ご指摘等がございましたらよろしくお願い致します。
bigquery schema 

# create table
```
bq mk --time_partitioning_type=DAY
--require_partition_filter
--schema test_table.schema
--table sample_project:test-data-set.test_table
```

# update table schema
```
bq show --schema --format=prettyjson sample_project:test-data-set.test_table > ./test_table.schema

vi test_table.schema

bq update sample_project:test-data-set.test_table test_table.schema
```
Github/labで特定のpull/merge requestをローカルで確認する方法

#はじめに
自分自身初めてのコードレビューをすることになり、別の人のコミットをローカルでしっかりと確認したいと思った時に、わからなかったのでここに書き留めます。

#Githubからローカルにpull requestをfetchする方法
以下の記事を参考にすると、
[Checking out pull requests locally](https://docs.github.com/en/github/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally)

```
$ git fetch origin pull/ID/head:BRANCHNAME
```
####具体例
"just adding stuff" #24  john/11-add-stuff => dev

```
$ git fetch origin pull/24/head:john/11-add-stuff
```
この後、ローカルでgit checkoutしていただければ、別のコミッターのコードを確認することができます。

#Gitlabからローカルにmerge requestをfetchする方法
参考：　 [stack overflow - How to checkout merge request loacaly](https://stackoverflow.com/questions/44992512/how-to-checkout-merge-request-locally-and-create-new-local-branch)

```
git fetch origin merge-requests/REQUESTID/head:BRANCHNAME
```
Githubと少し違いかつ参考の資料が少ないため、ちょっと迷いました。

#終わり
間違いやもっと役に立つ情報があれば、共有して頂けると嬉しいです。そして、この記事が誰かの役に立てば幸いです。
(SQL文)集計/結合/絞り込み/グループ化の実行順

### SQLデータ抽出で、書く順番と実行順を整理する

SQLデータ抽出課題で、SQL文を見ても状況が追えなくなってしまったので、
書く順番と実行順をまとめたところ、理解することができました。

**SQLは取得するテーブルを形成してから検索が実行される！**

**書く順番**
SELECT　カラム, 集計関数（集計）
FROM　テーブル名
JOIN （結合）
WHERE　条件（検索・絞り込み）
GROUP BY　カラム, カラム（グループ化）

**実行順**　
FROM　テーブル名
JOIN（結合）
WHERE　条件（検索・絞り込み）
GROUP BY　カラム, カラム（グループ化）
SELECT　カラム, 集計関数（集計） ※上にあるカラム以外を取るとエラー
Cookieの同意後にGAのトラッキングを開始する

# はじめに
GDPRが施行されてから数年経ち、いろいろなサイトでCookieの同意を求めるポップアップやダイアログ表示が増えてきました
そしてちょっと前に筆者もGDPR対応を求められたので、そのときに調査/実装したことの備忘として残します

# まず結論
GAのみの使用に関わらずOneTrust、osano等の外部サービスを使用することを__オススメ__します
PMやDRに相談してできるだけ勝ち取ってください！

なおそれぞれの使い方については調べれば出てくると思いますので割愛します
[OneTrust]
https://www.onetrust.com/
[osano]
https://www.osano.com/

これから書くことはもし何か宗教的な理由で外部サービスが使えなかったり、どうしてもスクラッチが良いという人向けです
（ただしGAのみの使用に限る）

# 実装
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="KKmWEgB" data-user="d2cdot_suto" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/d2cdot_suto/pen/KKmWEgB">
  GA tracking control</a> by d2cdot_suto (<a href="https://codepen.io/d2cdot_suto">@d2cdot_suto</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

現状、gtagを入れていなかったり、GAのIDが仮なのでボタンを押下しても何もおきません

このコードでキモとなるのは `window[GAID]` の部分です
許可する場合は `false` にし、拒否する場合は `true` をセットします
これによりトラッキングをスイッチすることができます

（この設定は GoogleAnalytics の高度な設定に記載されています）
参考：https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced?hl=ja#optout


# まとめ
以上のような形で、GAのみ利用時のGDPR対応？をしました
やはりGAのみの使用に関わらずOneTrust、osano等の外部サービスを使用することを__オススメ__します
（もし運用していく中でcookieを使うサービスが増えたら...と思うとスクラッチはメンテナンスが大変です）

なお導入による不具合等については責任を持てませんので自己責任でご利用ください

# 参考リンク
https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced?hl=ja#optout

https://hyper-text.org/archives/2018/05/google_analytics_cookie_opt_in.shtml
rs232の実験メモ2

# HWからシリアルコンソールへのデータ送信

## 必要となるハードウェアの実装

### マイコン側ロジック
マイコン側はTTLレベルかつ正論理でデータを送信できるよう、以下にようにコードを実装する。
9600bps での動作を前提に、1クロックが104usとしてマクロを宣言する。
実際にはデータの取り出し・ビット操作にも時間を使うので、コード中で多少の調整を行っている。

```
#include <xc.h>
#include <stdint.h>
#define CLKus 104

void send1byte(uint8_t msgByte){
    uint8_t itr;
    uint8_t bit;
        
    // start bit            
    GPIObits.GP2 = 0;
    __delay_us(CLKus -2.5);

    for( itr = 0; itr < 8; itr++){
            bit = msgByte & 0x1; // for better timing calculation
            GPIObits.GP2 = bit;
            __delay_us(CLKus -11);
            msgByte >>= 1;
    }
    __delay_us(2.5);
        
    // stop bit
    GPIObits.GP2 = 1;
    __delay_us(CLKus);
}
```


### レベルコンバータの実装
正論理TTLでの入力を、rs232では負論理で取り扱う必要がある。
[前回](https://qiita.com/NoIshii/items/0d026b7c8c19142c8401 "rs232の実験メモ1")の記載通り負電圧を対向のrs232ポートのTxDから借りるので、回路は以下のようになる。
![circuit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606167/203f6cda-883a-ba66-c519-c6ab82671f72.png)

## 動作確認
`cu`、`minicom`等を用いて、使用するrs232ポートに 9600bps, 8N1 動作を設定する。
レベルコンバータは簡易な回路ではあるが、この程度の速度であれば問題無く動作する模様である。
Anaconda3 でプロキシ (fiddler) を使う場合の設定

## まえがき
Anaconda3 2021.05 バージョンを普通にインストールした所、起動しませんでした。
プロキシ（Fiddler)を使う場合は設定が必要ですが、設定してもエラーに。
調べた所 urllib3 のライブラリに不具合がありバージョンダウンする必要が（現状は）ありそうです。

※以下 conda でパッケージ管理しています、pip でもインストールできますがどちらかに合わせたほうが良いです。

## エラーの内容
```
ValueError:check_hostname requires server_hostname
```

## プロキシの設定
- Anaconda Prompt で conda 情報を確認

```console
(base) C:\WINDOWS\system32>conda info
```

- user config file (個人ユーザの場合), poplulated config files (全体ユーザの場合) の箇所に記載の .condarc を編集 

デフォルトは C:/Users/＜Username＞/.condarc

```.condarc
channels:
  - defaults
show_channel_urls: True
allow_other_channels: True
proxy_servers:
  http: http://127.0.0.1:8888
  https: https://127.0.0.1:8888
ssl_verify: False
```
上記の proxy_servers の箇所を編集

- Anaconda Prompt で 設定を確認

```console
(base) C:\WINDOWS\system32>conda config --show proxy_servers
proxy_servers:
  http: http://127.0.0.1:8888
  https: https://127.0.0.1:8888
```

## urllib3 のダウングレード
- Anaconda Prompt で実行

```console
(base) C:\WINDOWS\system32>conda install urllib3=1.25.11
```

- インストールを確認

```console
(base) C:\WINDOWS\system32>conda list urllib3
# packages in environment at :
#
# Name                    Version                   Build  Channel
urllib3                   1.25.11                    py_0    defaults
```

## Anaconda Navigator 起動
Anaconda Navigator を起動して、無事起動すれば完了です。
お疲れさまでした！

## 参考サイト
https://stackoverflow.com/questions/66642705/why-requests-raise-this-exception-check-hostname-requires-server-hostname
CMSとは？ＣＭＳの３種類の簡単説明！

CMSは、Webサイト構築に関連してよく参照される一般的な用語です。 では、CMSとは何ですか？ それはどのように動きますか？ どのように使用しましたか？ なぜCMSを使用するのですか？ どのような種類のCMSがありますか？上記の問題はすべて、信頼できる情報源から編集した以下の記事で詳細に回答されます。 

**CMSとは何ですか？**
CMSは、**コンテンツ管理システム**（Content Management System）の頭字語です。**CMSには、ニュース、画像、ビデオ、カテゴリ、連絡先情報など、情報およびWebサイトコンテンツのすべてのアクティビティを制御する機能があります**。 
CMSは、管理時間、運用、保守のコストを節約するため、今日多くの企業がCMSを使用しています。 会社であるだけでなく、今では多くの個人ブログがあり、CMSを使用したソリューションにより、Webサイトの構築とコンテンツの管理が容易になります。 その上、それはまたWebサイトを構築する費用を節約します。 

**CMSはどのように動きますか？**
CMSは、Webサイトの機能を担当するすべての人が使用しなければならない場所です。 CMSに関しては、Webサイトの管理者部分として理解できます。 すべてのウェブサイトデータを管理する場所です。 

**CMSの基本的な機能**
CMSには次の基本機能があります。 
・バージョン管理 
・コンテンツ管理 
・サイトマップ 
・検索 
・ユーザー権限管理 
・WYSIWYG機能 
・ホームページ更新し 
...

**3種類のCMS**
デジタル環境の発展に伴い、CMSの種類も多様化しています。 

**1. 従来のCMSモデル**
従来のCMSモデルは、バックエンドをWebサイトのフロントエンドに接続します。 CMSバックエンドの管理は、同じコンテンツ配信システムまたはフロントエンドにバインドされています。 Webサイトのバックエンドでコンテンツを作成および公開する編集者は、Webサイトの訪問者に表示される内容に取り組んでいます。 さらに、すべてのWebサイトの設計およびカスタマイズアプリケーションもバックエンドに保存されます。 
**従来のCMSは、次の主要な機能を組み合わせています。**
・ユーザーインターフェイスは、公開されたコンテンツをHTMLページに表示します。 
・コンテンツ管理バックエンド 
・コンテンツストレージデータベース 
・スキーマデザインを作成および適用するためのアプリケーションが含まれています。 

**2. デカップリングCMS**
デカップリングCMSは、Webサイトのバックエンドとフロントエンドの管理を2つの異なるシステムに分割します。 分離されたCMSモデルでは、コンテンツ管理システム（バックエンド）は配信コンポーネント（フロントエンド）とは別に動作します。 これは、コンテンツがWebページのバックエンドで作成および編集される場合を意味します。 APIを介して渡され、別のフロントエンドシステムで公開されます。 
**デカップリングCMSモデルには次のものが含まれます。**
・フロントエンドコンテンツ公開インターフェースは事前定義されており、APIを介してコンテンツ管理バックエンドに接続されています。
・コンテンツストレージデータベース 
・管理インターフェースには、編集者がコンテンツを簡単に作成および管理できるようにするアプリが含まれています（プラットフォームによって異なります。
・コンテンツは任意のデバイスに公開できます 。

**3. ヘッドレスCMSモデル**
ヘッドレスCMS構造は、デカップリング CMSアーキテクチャに似ていますが、公開用のフロントエンドシステムがありません。多くの開発者は**[ヘッドレスCMS](https://kaopiz.com/ja-blog-what-is-headless-cms-2021/)**に人気を持っていますが、それはあなたのマーケティング活動を傷つける可能性があります。ヘッドレスCMS環境では、システムに小さなコンテンツを編集および管理する機能があります。次に、WebサービスまたはAPIに公開して、インターネットにアクセスできる任意のシステムにコンテンツを配信できるようにします。したがって、ヘッドレスCMSは、同じコンテンツをWebサイト、アプリケーション、モバイルデバイス、またはモノのインターネット（IoT）を介して接続された任意のデバイスに公開できます。その理由は、コンテンツが事前定義されたコンテンツ構造にバインドされていないためです。 
**ヘッドレスCMSには次のものが含まれます。**
・コンテンツ管理バックエンド（コンテンツ管理バックエンド） 
・API 
・事前定義されたフロントエンドコンテンツ公開インターフェースはなく、IoT経由で接続された任意のデバイスに公開できます 
・多くのCMSプラットフォームは、コンテンツの設計、開発、および展開をITに依存する必要がなくなりました。デカップリングCMSにより、マーケティング部門は独立して運営でき、一度作成してどこにでも展開できるようになります。 

**結論**
今日、CMSを使用すると、プログラミングやコードを理解していなくても、ほとんどの人がWebサイトを作成できます。 この記事が、最高のCMSプラットフォームであるCMSとは何かを理解するのに役立つことを願っています。 このリストを使用すると、個人のブログ、さらには販売ビジネスのWebを開発するのに適したCMSを自分で選択できます。
Docker超初級編　Downloadとインストールの確認


①
>https://www.docker.com/
へアクセス
![20210716-111744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/1753b4d9-ce6d-d199-95c5-44ecb8711ac8.png)


②右上の「Get Started」をクリック

私のPCはMacなので
![20210716-112139.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/771f9f25-2735-06bd-5828-6030805973cf.png)

Download for Macを選びますが、マウスをホバーさせるとWindowsも現れます。


③アプリをダウンロード
![20210716-112403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/9254e90a-a8b0-f7a4-31c5-941e97dbe286.png)


④ダウンロードファイルをクリックして実行
![20210716-112553.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/98b94349-6526-9174-6bdb-e43ae7f52362.png)


⑤インストールを開始するには鯨マークをフォルダへドラッグ&ドロップ
![20210716-112403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/87eb6729-d2c8-81c4-e6a0-477affdb127d.png)


⑥おわったら、ターミナルで「docker run hello-world」を入力し、[Hello from Docker!]とでればインストール完成です。

```rb
MacBook-Air ~ % docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete 
Digest: sha256:df5f5184104426b65967e016ff2ac0bfcd44ad7899ca3bbcf8e44e4461491a9e

Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
CO2センサーデータ比較

3種類のCO2センサーのデータの比較を行いました。

##使用CO2センサー
| 型名 | メーカー | 測定範囲|
|:----|:---------|:-------|
|SCD30|Sensirion|0～40000 ppm|
|SCD41|Sensirion|400～2000ppm|
|MHZ-19C|Zhengzhou Winsen Electronics|400～5000ppm|

##比較グラフ
[センサーデータExcelデータ] (https://drive.google.com/file/d/1w5Z1VDmYSdw6Fbbtub26gu3Ms06fpHlc/view?usp=sharing) (このグラフのExcelデータです)
![CO2センサー比較.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99249/14e7d868-1aae-0935-9a07-6168ba70b003.jpeg)

##評価
今回の計測は2021年7月15日 00:00 ～ 16日9:00 までと1日程度ですが、
3つのセンサーに大きなばらつきは無く取得データに±補正をかけるとほぼグラフが重なりそうです。
(物差しとなる計測器が無いのでどれを基準にするかの問題はありますが)

**MH-Z19C**と**SCD30**のデータがほぼ同じなのも正直おどろいています。
この2つのセンサーは***非分散型赤外線吸収法方式(NDIR)***という同じ方式となっています。
価格差から考えるとMH-Z19Cのコストパフォーマンスが高いことになります。

SCD41に関しましても期待以上の結果となりました。
このセンサーは他のセンサーに比べるとすごく小さいので、**小型のCO2計測器**を作ることが出来そうです。

今回のデータは参考程度にとらえてください。
性能を保証するものではありません。
Flexboxで特定の要素を下揃えしようとしたらひっかかった話

### はじめに
初めまして r-higaと言います。システムの部署にいますが、普段はwebデザインをメインにフロントコーディングも少し行ってます。

今回はタイトルの通りflex-directionでリストカセット内のボタン位置を揃えようとしたら、ちょっとしたところでひっかかりもったいないオバケに時間を食べられてしまったので、備忘録として残しておきます。


### 結論
可変するカセット内にflex-directionをかけて要素を固定する場合は「margin: auto;」が必須でした。

### 詳細
真ん中部分のテキストが可変するリストカセットで、同行内の一番長いカセットに合わせて伸縮、ボタンが下部に固定されるレイアウトです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748330/68038b0c-d550-327c-a1dd-c05fd95bfb21.png)



で、引っ掛かったのがここ
レイアウト的に中央部分のテキストが可変のため、高さをpxや%などで固定せずにどうにか高さを持たせるために試行錯誤してました。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748330/d05f17f4-056e-b49e-c9e6-1204599dda8a.jpeg)



flexの縦並びの順番を決められるflex-directionの「column」なら、特定の要素が固定されて揃うだろう、となぜか思い込み下記だけを追加してました。今思うと絶対求めるレイアウトにならないのにね

```
li{
　display: flex;
　flex-direction: column;
}
```

追加後にウッキウキで確認すると、あれ？揃って…ない？
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748330/1e43e2c1-787a-1ca0-cce1-99c1e028be73.jpeg)


それもそのはず、flex-directionは「上から順番に並べるだけ」のプロパティなので、固定するには他のプロパティを追加しないといけないことを理解してなかったのでした…
これで固定されなかったので、テキストのタグにheight:100%;つけたり（すごく縦に伸びた）、ボタン要素をpositionで固定したり（テキストの上にボタンが乗る状態になりあれこれプロパティ追加しまくり）しましたが上手くいかず、最終的には固定したい要素に下記をつけることで解決しました。

```
.btn{margin-top: auto;}
```

基本の「margin:auto;」じゃん…！

「auto」だと指定した方向の余白がmarginの扱いになるので、今回のような可変のレイアウトにはすごく便利！
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748330/498615f7-f3a7-707a-5db5-ca69239d1e16.jpeg)



最終的なものがこちら
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="mdmrKpw" data-user="ion_neko" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ion_neko/pen/mdmrKpw">
  flexboxのあれ</a> by ion_neko (<a href="https://codepen.io/ion_neko">@ion_neko</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
※IE11も対応範囲の場合は「width: calc()」からcalcを削除してpxか%で指定してください


いや～完成してよかった！！

### おわりに
Flexbox好きなので使用してましたが、意外と特性をわかってませんでした。「わかっているつもり」って結構危ないと理解（わか）らされました…もっと勉強します

### 参考資料
colis（最終閲覧日：2021年7月12日）

https://coliss.com/articles/build-websites/operation/css/flexbox-aligning-with-auto-margins.html
cannot bind packed field 'foo.Foo::val[0]' to 'int&'

```c++
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif

#include <stdio.h>
PACK(struct Foo{int val[1];});
void run(const int &x){puts("const");}
void run(int &x){puts("non-const");}
int main(){Foo foo;run(foo.val[0]);}
```

GCC9以降だと、このコードで表題のエラーが出る。
GCC8、Clang4/9/11, Open64 5.0、ICC 2021.3[^1]、ICPX(DPC++) 2021.3、MSVC2010[^2]だと出なかった(すべてnon-constに解決される)。

static_cast\<int\>をすることでconst intに解決されるようになる。

[^1]: 念のため書いとくとICC 2021以降は無料
[^2]: 手元に環境がなかったのでこどふぉのcustom invocationを使わせていただいた
batを作ってみたメモ１

毎日同じサイトを立ち上げるのが面倒だったのでbat叩いたら立ち上がるようにしてみた。
batファイルはコマンドプロンプトに実行させたい命令をテキストファイルに書いたもので、unix系ではシェルスクリプトに相当するらしい。

**環境**　windows 10
**エディタ** VSCode

```routine.bat
@echo off
start chrome URL 
start outlook.exe
if exist "PATH*.xls" (start "" "PATH\hogehoge.xls") 
echo SetUp...
pause
```
これを実行すればchromeとoutlooxとexcelが立ち上がる。
 
VSCodeの標準はUTF-8だが、コマンドラインでテキストを扱う場合sjisが標準らしい。
そこでVSCodeのワークスペースに追記して、batファイルをsjisで開いたり保存したりしてもらうようにした。

```hoge.code-workspace
"settings": {
        "[bat]": {
            "files.encoding": "shiftjis"
        }
    }
```
これでワークスペース内のbatファイルはVSCodeが勝手にsjisでやってくれる。

ログインも自動化しようとwsl2上にpython+seleniumしようとしたけど環境構築失敗したのでそのうち再挑戦します。
保存した画像をImage OptimとAutomatorで自動で最適化する【Mac限定】


# はじめに
画像のサイズは、Webサイトのパフォーマンスに直結してきますし、画像を管理するにも不要なメタデータなどは極力取り除くなどしてサイズを抑えたいものです。

しかし、いちいち画像を最適化するは面倒くさいので、今回はその作業をAutomatorとImageOptimを使用して自動化する方法を紹介します。

# ImageOptimとは
ImageOptimは、画像の容量を削減するアプリケーションで、オープンソースソフトウェアとして公開されています。Macのデスクトップアプリケーションと、Webサービスの2種類が公開されています。

JPEGminiやpngquantなど、他にも似たようなツールはありますが、PNGやJPG、SVGなど複数の画像形式に対応しているImageOptimで一本化するのがおすすめです。。

# ImageOptimのインストール

下記リンクからダウンロードしてインストールしてください。

[ImageOptim](https://imageoptim.com/mac)

ちなみに、App Storeにもアプリとして存在しますが、有料だったりスクリプトが動かなかったりするので、大元であるこちらのサイトからインストールすることをおすすめします。

# Automatorワークフローの作成
Automatorで新規に**フォルダアクション**でワークフローを作成します。
今回はブログ用に、下記のように画像を最適化するだけのワークフローを作成しました。

ワークフローの流れはこの様になっています。
①指定したフォルダに画像を保存
②ファイルの種類でフィルタ(画像のみ）
③別の指定フォルダに画像のコピーを作成
④ImageOptimで最適化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416412/d4036d24-db35-a156-087d-b34169d1a8cd.png)

スクリプトの引数を`$＠`で指定しているため、複数の画像にも対応できます。
また、ImageOptimのUIを表示させたくない場合は、下記のように書き換えることで可能です。

`/Applications/ImageOptim.app/Contents/MacOS/ImageOptim "$@"`

# 動作確認
今回はスクリーンショットの保存フォルダをしていしたため、スクリーンショットをとると自動で画像の容量を削減することが確認できました。

![ImageOptim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416412/9caff37e-6c80-9c06-fe45-5545ba4ee58f.gif)
Git で最初に設定する Config

```bash
git config --global user.name "User Name"
git config --global user.email "user.name@example.com"
## エイリアス
git config --global alias.co "checkout"
git config --global alias.b  "branch"
git config --global alias.bd "branch -d"
git config --global alias.f  "fetch -p"
git config --global alias.s  "status"
git config --global alias.log1  "log --oneline --graph"
git config --global alias.log2  "log --graph --date-order -C -M --pretty=format:'%C(bold blue)%h%C(reset) %C(green)%ad%C(reset) %s %C(green)[%an]%C(reset) %C(yellow)%d%C(reset)' --date=format:'%Y-%m-%d %H:%M'"
git config --global alias.log3  "log2 --all"
git config --global alias.localprune '!git branch --merged | grep -v \* | xargs git branch -d'
# その他
git config --global push.default current
git config --global core.editor "$(which vim)"
```
SQLAlchemyのwith_loader_criteria句を使うと地味に便利(>=1.4)

## 何これ
SQLAlchemy 1.4以上で使える `with_loader_criteria()` オプションを使うとかなり楽になる
(2021年3月にリリースされました-> [Changelog](https://docs.sqlalchemy.org/en/14/changelog/changelog_14.html#change-1.4.0))

## 良い事
 - One to ManyでJOINする相手のテーブルをfilterしたい時に記述量が減る
 - `lazy` の指定によらず何にでも効いてくれる

## 例
チャットルームとチャット参加者を管理するテーブルがあったとします。
また、2者の関係は `relationship('ChatJoinedUser', backref="chat_rooms", lazy='joined')` で定義されています。

```py
chat_rooms = session.query(ChatRoom).filter(and_(
    ChatRoom.account_id == current_user.account_id,
    ChatRoom.is_ended == False
)).options(with_loader_criteria(
    ChatJoinedUser, ChatJoinedUser.attending_status != AttendingStatus.leaving)).all()
```

```sql
SELECT 
  (中略)
FROM 
  chat_rooms 
LEFT OUTER JOIN 
  chat_joined_users AS chat_joined_users_1 
ON 
  chat_rooms.chat_id = chat_joined_users_1.chat_id 
AND 
  chat_joined_users_1.attending_status != 'XXXXXX' 
WHERE 
  chat_rooms.account_id = 'YYYYYY' 
AND 
  chat_rooms.is_ended = false
```

発行されるクエリはこんな感じになる。
SQLAlchemyはeager loading（積極的読み込み）に関するテクニックがバージョンによって違ったりrelationshipによっては使えなかったりするので、この関数が出てきてだいぶ楽になった。
【Ruby】discordの対話botを作成する

# はじめに
ゲーマーには必須アプリとも呼ばれるdiscordにて、<del>究極の暇つぶし</del> 勉強のために対話botをつくってみました。
今回はA3RTというサービスのAPIを使用しています。
Rubyでのbot作成記事が少なかったため、何かしらの参考になれば幸いです。
# 事前準備
下記の準備は完了しておいてください。
・Discord bot作成
[こちらの記事](https://qiita.com/tomynomint/items/4f35b281ec09eae3c1d2)で丁寧に説明されておりましたので、割愛いたします。

・A3RT APIライセンス発行
[ここから](https://a3rt.recruit-tech.co.jp/product/talkAPI/registered/)A3RTのTalkAPIライセンスを発行できますので、案内に沿って発行を行います。
必要なものはメールアドレスのみなので、簡単に発行できます。

・開発環境にdiscordのgemをインストール
```gem install discordrb```
https://github.com/discordrb/discordrb
#開発
###Discordメッセージ取得部作成
```ruby:bot.rb
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'botのトークンを記載',
  client_id: 'botのIDを記載'

# 何かメッセージが送信されたら実行
bot.message do |event|
  event.respond 'hogehuga!'
end

bot.run
```
①必要事項の記入
上記テンプレートに下記の環境変数を記載してください。
・token
・id

②イベント発火
テキストチャンネルで適当な文字を入力すると「hogehuga!」と返してくれるようになります。
現状では単なるhogehugaボットなので、ここから命を吹き込んであげたいと思います。
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/e7829dc1-1eea-1cb7-96e9-b792121c6fe6.gif)


###API通信部作成（POST）
```ruby:bot.rb
require 'discordrb'
require 'uri' #HTTP通信をするため追加

bot = Discordrb::Commands::CommandBot.new token: 'botのトークンを記載',
  client_id: 'botのIDを記載'

#A3RTのAPI URLとライセンスキーを記載
api_url = "https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk"
api_key = "ライセンスキー"

bot.message do |event|

  #Discordチャットのメッセージを取得
  get_message = event.message.to_s

　#API通信
  uri = URI.parse(api_url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  req = Net::HTTP::Post.new(uri.path)
  req.set_form_data({'apikey' => api_key, 'query' => get_message})
  res = http.request(req)
  result = JSON.parse(res.body)

　#レスポンスの取得
  message = result["status"] == 0 ? result["results"][0]["reply"] : "error";

  event.respond message
end

bot.run
```
①必要事項の記入
下記要点を記入してください。
・api_url（共通です）
・api_key（事前に発行したTalkAPIライセンスキー）

この状態でメッセージを入力すると、正常に稼働すれば下記形式でレスポンスが返ってきます。

```js
{
	status: 0,
	message: "ok",
	results: [{
		perplexity: 2.3688167429546714,
		reply: "おはようございます"
	}],
}
```
###動作確認
![Animation1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/a48d0d48-149a-50fc-c77e-f04b853d0c71.gif)
（天気と趣味は会話の鉄板ネタです。）
まぁまぁドライな対応ですが、なんとなく会話はできていそうです！
#最後に
一昔前にLINEでお喋りbotがでたときは半日もお喋りしていたことを思い出します。。。
最近ではお喋りbotが当たり前になってきて、簡単に自作できるようになり時代の流れの速さを実感しますね。。。
ちゃんと会話になっている点も多いので、是非作ってみてはいかがでしょうか！
GitHubのコントリビュート数にプライベートリポジトリへのコントリビュートを追加する

最近、エンジニアの転職系のサイトでGitHubのコントリビュート数を取得されたり、エンジニアのアピールポイントの1つとしてGitHubのコントリビュート数が使われることがあります。

仕事でバリバリGitHubを使っている場合、下記のように平日はほぼ緑になっていると思います。
下記は私の直近1年間のコントリビュートです。

![スクリーンショット 2021-07-16 9.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/f696ae89-b2f5-da2a-58b9-39caf8c2740b.png)

ただ、仕事で使っている場合、コミット先はプライベートリポジトリであることが多いと思います。
その場合、デフォルト設定のままで匿名ユーザーが閲覧すると、パブリックリポジトリに対するコントリビュートだけになってしまいます。
下記は先ほどと同じ期間を未ログインで閲覧したコントリビュートです。

![スクリーンショット 2021-07-16 9.26.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/6134f9d1-cc57-fe10-476f-b11a8edf93a3.png)

コントリビュート数だけでスキルが判断できるわけではないですが、せっかくバリバリ使っているなら、他人からスカスカに見られるのはちょっともったいないですよね。

実はこれ、設定で簡単にプライベートリポジトリのコントリビュート数も表示することができます。
コントリビュート数の右上にある"Contribution settings"をクリックし、"Private contributions"をONにするだけです。

![スクリーンショット 2021-07-16 9.35.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/aa38f246-faf4-cd53-701d-c30af3dca93f.png)

たったこれだけの設定で、誰が見た場合でもプライベートリポジトリのコントリビュート数が含まれた状態で閲覧できるようになります。

※この設定を行ってもプライベートリポジトリに対するコントリビュート数が加算されるだけで、Contribution activityなどに具体的な内容は表示されません。
数だけでも表に出たらまずい場合は設定しないようにしましょう。
Excel VBAで指定の文字列を改行や水平タブに自動変換する方法

今回はExcel VBAを用いて指定の文字列を改行や水平タブに自動変換する方法を解説します。

#自動マクロ作成の背景
私自身、運用監視業務をやっていたのですが、監視ツール独特の文字コードが存在しており、検知メッセージの文字列を手動で変換していたことで工数に無駄があった。
なので指定の文字列を自動変換できないか模索してみたところ、VBAでExcelの文字コードに変換するマクロを作成することで文字列を自動変換できると考えた為、マクロを作成した。

#前提条件
- Windows10を使用
- PCはDELLを使用
- Excelを導入していること。
- マクロを有効化していること。

#料金
無料で実施可能。

#自動化の概要
- 指定の文字列をExcelの文字コードに変換するVBAを書き込む。
- Excelのショートカットキーを新たに作成し、ショートカットキーにVBAマクロを割り当てる。
- 「改行」の文字列を削除し、改行する。
- 「水平Tab」の文字列を削除し、水平TABに変換。
- 「垂直TAB」の文字列を削除し、垂直TABに変換。

#手順
VBAの画面で以下コマンドを入力する。

####コマンドについて解説
- 「マクロ名を入力」の部分に任意のマクロの名前を入力する。
- Keyboard Shortcut:に新たに任意のショートカットキーのキーを入力する。
<br>※下記サンプルコマンドではCtrl+jとしている。
- 「ActiveCell.Replace What:=""」のダブルクォーテーションの間に変換したい文字列を入力する。
- 「& Chr(数字) &」で変換したいExcel文字コードを入力する。
<br>※Chr(10)は改行、Chr(9)は水平TAB、Chr(11)は垂直TABの文字コードとなる。


```vb
Sub マクロ名を入力()
'
' マクロ名を入力 Macro
' マクロ名を入力
'
' Keyboard Shortcut: Ctrl+j
'
    ActiveCell.Replace What:="改行", Replacement:="" & Chr(10) & "", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False
    ActiveCell.Replace What:="水平TAB", Replacement:="" & Chr(9) & "", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False
    ActiveCell.Replace What:="垂直TAB", Replacement:="" & Chr(11) & "", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False
End Sub
```
#動作確認

１、以下サンプルメッセージをExcelにコピペして下さい。

```
aaaaaaaaa改行aaaaaaaa改行改行aaaaaaaa水平TABaaaaaaaa垂直TABaaaaaaa
```

２、コピペしたセルを選択した状態で新しく作成したショートカットキーを入力する。
今回はCtrl+jを入力
![aaaaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/bfee233f-7238-2ba8-9026-4529fd36ad4a.png)
３、下記のように文字列が変換したことを確認。
![bbbbbbbbbbbbbbbbbbbbb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/5d5a53c8-8d6f-7b40-984c-868f626f21bc.png)

４、改行は一目で確認できるがTABの変換はExcel上では確認できないのでメモ帳へコピペして以下のように表示されたことを確認。
※メモ帳上では目視で垂直タブに変換されておりませんが、実際には変換されております。
![ccccccccccccccc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/fdcb9d63-5f9a-6027-9962-9bf670159938.png)

#終わりに
今回はExcel VBAを用いて指定の文字列を改行や水平タブに自動変換する方法を解説しました。
VBAは今まで使ったことが無く現場の業務改善をきっかけに初めて使いました。
もっとVBAの技術を深く学べばより自動化の幅が広がりそうなので、今後もVBAの勉強を進めていきたいと思います。
この記事が少しでもお役に立てれば幸いです。
SAKURAエディタでマクロを使う方法

LINUX環境で使用するSQLファイルをVBAで大量に作って意気揚々と実行コマンドを叩いたところ、エラー発生！メッセージを調べたところ、どうも文字コードをUTF-8で、改行はLFになっていないといけないようでした。一応SAKURAエディタで「名前を付けて保存」すれば変換できて実行できるようになったけど、大量にあるのでいちいち手作業で保存していくのはめんどくさい....。というわけで一括で変更する方法を調査してみました！

以下のように

```sakuramacro.bat
cd C:\Users\username\OneDrive\デスクトップ\sakuramacro
for %%a in (*) do (call :method %%a)
exit
:method
"C:\Tools\sakura\sakura.exe" %1 -M=C:\Users\username\OneDrive\デスクトップ\sakuramacro.mac
goto :eof
```

ファイルしまっているフォルダパス、サクラエディタのインストール先とか↓で作ってるマクロファイルの場所とかは自分のPCの環境によるので確認しておいてください。
続けて中身の操作を記述するmacファイルを作ります。多分マクロの略なのかな？

```sakuramacro.mac
S_ReplaceAll('\\r\\n','\\n',60); //開業コードをすべて置換
S_ReDraw(0); //再描画
S_SelectAll(0); //すべて選択
SJIStoUTF8(0); //文字コード変換
FileSave( ); //上書き保存
WinClose( ); //閉じる
```

以上です。sakuramacro.batをダブルクリックで実行するとフォルダの中に格納したSJISのSQLファイルが変換されてゆきます。念のためですが、変換したいファイル以外は入れないようにしましょう。↑に書いている書き方だとエクセルでも何でも開いてしまうので、高確率でファイル破壊されます。

今回は文字コードと改行の変換だけでしたが、正規表現とか使って簡単な文章校正とかもできるかもしれません。
ちなみにVBAでUTF-8かつLFのファイルを作成したい場合はADODBという拡張機能を有効にすれば実現できますので、今回紹介したのはSAKURAエディタでもマクロ使えるよってことに絞ったものになります。
2.8(易) 期待値の性質

## 方針

f_Y(y)=f_Y(-y)より分布は左右対称．その中心が期待値である．

## 答案

y=x-muとおくと，f_Y(y)=f_Y(-y)より，

```math
\mathbb{E}_{Y\sim f_Y}[Y]=0\Rightarrow\mathbb{E}_{X\sim f_X}[X]=\mu
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
lambda × SNS クロスアカウント設定

# SNSアクセスポリシー
[![Image from Gyazo](https://i.gyazo.com/837a912afea6933829cb482d21a419b5.png)](https://gyazo.com/837a912afea6933829cb482d21a419b5)

# lambda IAMロール
[![Image from Gyazo](https://i.gyazo.com/935c49b996f5b1b1eefe13bb9acc3a7c.png)](https://gyazo.com/935c49b996f5b1b1eefe13bb9acc3a7c)

# lambda作成
[![Image from Gyazo](https://i.gyazo.com/d0769f94b473f9bba3a41613b67519d0.png)](https://gyazo.com/d0769f94b473f9bba3a41613b67519d0)

# lambdaコード
[![Image from Gyazo](https://i.gyazo.com/4d182a90b980a9cbb495c382bad0ac08.png)](https://gyazo.com/4d182a90b980a9cbb495c382bad0ac08)

```
var aws = require('aws-sdk');

var sns = new aws.SNS({
   apiVersion: '2010-03-31',
   region: 'ap-northeast-1'
});

function timer(ms, name) {
  console.log(`name: ${name} start!`)
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), ms)
  })
}

exports.handler = async function(event, context) {
    console.log('publish start')
    await timer(1000, publish(event, context));

    function publish(event, context) {
        sns.publish({
            Message: 'Message',
            Subject: 'Message title ' ,
            TargetArn: 'arn:aws:sns:region:accountId:別アカウント'　// 別アカウントSNSのArn 
            }, function(err, data) {
                if (err) {
                    console.log(err.stack);
                    return "failed publish".err.stack;
                }
                console.log('publish sent');
                console.log(data);
        });
    }
};
```

# 参考文献
 - [Lambda (runtime Node.js 8.10) から SNS へ publish してメール送信する](https://qiita.com/kkam0907/items/a69d5f483d2be961683c)
Amazon RDS Performance Insights とは

## 勉強前イメージ

アクセス量とかをグラフで見れるようにするやつ？

## 調査

### Amazon RDS Performance Insights とは

データベース負荷のモニタリングを行う機能で
グラフなどでDBの負荷状況を確認できたり、SQLのクエリが見えるので問題が起こった際に調査がしやすいという点があります。
費用については7日分の履歴は無料で見れますが、それ以降は有料になります。
最長で2年データを保持することが可能です。

### Performance Insights の確認方法

RDS > データベース > モニタリング の
以下のモニタリングをクリック、 パフォーマンスインサイトがあるので
こちらから確認することが出来ます。

今回手持ちの適当なRDSで見たら設定してなかったので見れなかったですが、
設定したら下記の画像が黒文字になります。

![1RDS Management Console - Google Chrome 2021-07-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/fea30317-cf0a-1873-b3e9-e2434525eaef.png)

DBを構築する際に 追加設定 > Performance Insights があり
それを有効にすると見れるようになります。
今回使ってたのがmysqlの無料利用枠のテンプレートを使ってたので、なかったですが
本番稼働用などであれば以下のような設定があります。

![2RDS Management Console - Google Chrome 2021-07-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/53870081-8f56-0ada-fc59-c690832f038d.png)

## 勉強後イメージ

ちらっとパフォーマンスインサイト見たことあるけど、
グラフで接続数見えたり、実行されてたSQL(多いやつ)見えてたり
ちょっと確認するには良いかも。
ちゃんと使ってないから、もっとちゃんと見れる機能もあるはず

## 参考

- [Performance Insights の有効化と無効化](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_PerfInsights.Enabling.html)
- [Performance Insights の料金](https://aws.amazon.com/jp/rds/performance-insights/pricing/)
2.7(難) 連続確率変数の期待値と分布関数の関係

## 1.方針

初見で解くのは不可能．

```math
\begin{align}
x=
\begin{cases}
\int_0^xdt,\ \ \ \ \ \ \ \mathrm{if}\ 0<x\\
-\int_x^0dt,\ \ \ \ \mathrm{if}\ x<0
\end{cases}
\end{align}
```

であることを用いる．

## 1.答案


```math
\begin{align}
\mathbb{E}_{X\sim f_X}[X]&= \int_{-\infty}^\infty xf_X(x)dx\\
&= \int_0^\infty xf_(x)dx+\int_{-\infty}^0xf_X(x)dx\\
&= \int_0^\infty\{\int_0^xdt f_X(x)\}dx+\int_{-\infty}^0\{-\int_x^0dtf_X(x)\}dx\\
&= \int_0^\infty dx\int_0^xdtf_X(x)-\int_{-\infty}^0dx\int_x^0dtf_X(x)\\
&= \int_0^\infty dt\int_t^\infty dxf_X(x)-\int_{-\infty}^0dt\int_{-\infty}^tdxf_X(x)\\
&= \int_0^\infty\{\int_t^\infty f_X(x)dx\}dt-\int_{-\infty}^0\{\int_{-\infty}^tf_X(x)dx\}dt\\
&= \int_0^\infty \{1-F_X(x)\}dx-\int_{-\infty}^0F_X(x)dx
\end{align}
```

## 2.方針

逆関数になっているのは嫌なので，

```math
\begin{align}
x=F^{-1}_X(t)&\Leftrightarrow t=F_X(x)\\
&\Leftrightarrow t=P[X\leq x]
\end{align}
```
と置換する．t→xの置換のため，

```math
\frac{dt}{dx}=f_X(x)\Rightarrow dt=f_X(x)dx
```

を用いる．

## 2.答案

x=F^-1(t)と置換する．

```math
\int_0^1F_X^{-1}(t)dt=\int_{-\infty}^\infty xf_X(x)dx=\mathbb{E}_{X\sim f_X}[X]
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
Denoでshift-jisのテキストを読み書きしたい

# 読み込み

utf8なら`Deno.readTextFile`で読める。

```ts:utf8
const str = await Deno.readTextFile("hello.txt");
```

utf8以外なら`TextDecoder`を使う。
エンコーディング一覧 → [TextDecoder.prototype.encoding](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/encoding)

```ts:shift-jis
const bytes = await Deno.readFile("hello.txt");
const decoder = new TextDecoder("shift-jis");
const str = decoder.decode(bytes);
```

# 書き込み

utf-8なら`Deno.writeTextFile`で書ける。

```ts:utf-8
const str = "悔しいと思うならまだ戦えるね";
await Deno.writeTextFile("hello.txt", str);
```

shift-jisの場合はTextEncoderを使う。
...と言いたいところだけどTextEncoderはutf8にしか対応してないんや。
「他→utf8」はまぁいいけど「utf8→他」はいろいろあるらしいから。

https://gihyo.jp/admin/serial/01/charcode

今回はSkypackで [encoding.js](https://github.com/polygonplanet/encoding.js) を使ってエンコードする。

```ts:shift-jis
import encoding from 'https://cdn.skypack.dev/encoding-japanese';

const str = "あなたが青く見えるなら、りんごもうさぎの体も青くていいんだよ";
const utf8Encoder = new TextEncoder();
const utf8Bytes = utf8Encoder.encode(str);
const sjisBytesArray = encoding.convert(utf8Bytes, {from:"UTF8", to:"SJIS"});
const sjisBytes = Uint8Array.from(sjisBytesArray);
await Deno.writeFile("hello.txt", sjisBytes);
```

...一応書き込めたっぽいけど間違ってるかもしれない。間違ってたら教えてください。
~~てか、shift-jis読むことはあっても書き込むことはないや...~~

# 参考

https://scrapbox.io/deno-ja/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80

https://scrapbox.io/deno-ja/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%82%80

https://doc.deno.land/builtin/stable

https://developer.mozilla.org/ja/docs/Web/API/TextEncoder
なぜ企業は大規模開発を選択してしまうのか

「『アジャイル vs ウォーターフォール』からプロジェクト管理を考える」という記事にてウォーターフォールであっても分割すれば問題は解決するかもしれないという話を書きました。しかし、プロジェクトの分割は現実にはなかなか難しいのも事実です。分割すればプロジェクトの成功率が上がるのことは明らかに見える（そしてアジャイル開発を導入するよりも変化に対応するコストをかけなくてよいという利点がある）にも関わらず、なぜ企業は大規模開発を選択してしまうのでしょうか。

https://qiita.com/hidekatsu-izuno/items/1f6aae12cc4d134aefd6

今回もちょうどよい論文がないか探してみたのですが……探し方が悪いのかぜんぜん見つかりません。[^1] そこで、この記事では私の業務システム開発の過去の経験から「なぜプロジェクトの分割が難しいのか」という理由を列挙したうえで、解決策を考えてみたいと思います。

[^1]: もし知っていたら教えていただけると幸いです。

## なぜ、プロジェクトの分割は難しいのか

### システム間連携が多すぎる

特に業務系基幹システムにはその傾向がありますが、システムの連携機能が数十どころか数百あることも珍しくありません。プロジェクト対象のシステムをリプレースする場合には、そこに繋がっているシステム全体に影響がないように移行する必要があります。

単に連携先の切り替えだけの話であれば、分割しての移行も可能ですが、支払や在庫のようにトランザクションの状態が重要な場合には、旧システムと新システムを並行稼動させることは困難になります。実際には連携方法の変更（例：FTP から SFTP）であったり、項目の変更も同時に行われることになりますので、新システムから新旧ふたつのレイアウトでファイルを出力するようなことも必要になるかもしれません。

### 予算枠の調整が難しい

企業が情報システムを作るということは投資をすることに他なりません。投資に対する効果を元に予算枠を決め、その中で実施する必要があります。プロジェクトを分割するということは、後回しにする部分については予算枠が決められないということになります。

最終的に分割前のプロジェクトで計画された内容すべてを実現しないと効果が出ない（例えば、旧システムの維持に大きなコストがかかっており、新システムに完全に切り替わらないとメリットがでない）場合には、最終的な着地点が見えないと予算枠の申請ができなくなってしまいます。

また、予算枠が先に決める必要があるなら、金額、期間を達成する責任を開発ベンダーに負わせる一括請負契約を選択する以外の選択肢は難しくなります。

### リリース日の調整が難しい

特に業務システムでは、会計年度や繁忙期との兼ね合いで、ユーザー側がテストできる期間やリリースできる日程に制限があることがよくあります。ハードウェアやミドルウェアの保守期限のため、現行システムを維持できる期間にも限りがあるかもしれません。このような状況では、プロジェクトを分割したところでリリース日は変わりません。これでは、プロジェクトを分割する意味は薄れてしまいます。

プロジェクト期間がベームの法則（工数の立方根で決まる）に従って決まるとされています。この場合、工数を半分にしたところで期間は20%程度しか短縮できません。例えば 100人月、標準工期 11ヶ月のプロジェクトを分割し50人月、工期5.5ヶ月の2プロジェクトとしたいところですが、標準工期はそれぞれ9ヶ月までしか縮まりません。この場合、開始が2ヶ月ずれた9ヶ月間のスケジュールが並走するだけということになります。これでは、むしろプロジェクトを分割したことによる影響（2回移行やリリースが必要など）の方が心配になってきます。2ヶ月しかずらせないのなら、リリース日をまとめてしまおうと考えるのは自然なことです。

### 利用者、利用部署への周知・教育が難しい

あまり重要でない機能を分割してリリースするのであればともかく、主となる機能が徐々に新システムに切り替わっていくというのでは、利用者側もどちらのシステムを使えばいいのかわからなくなってしまいます。

新システムの導入を推進する情報システム部的な立場であれば、一度の通知、教育で済ましてしまいたいと思うのは当然でしょう。

## どうやったら分割できるのか

### 業務の違いで分割する

業務の種類が異なればデータの接点も少なくなることが期待できます。業務の違いでサブシステム化し、サブシステムごとに独立性を持たせることで、プロジェクトを分割するという考え方ができます。

とはいえ、これも言うは易し行うは難しです。すでに現行システムが大規模でモノリシックな作り方になっている場合は、サブシステムを独立させても徐々にリリースさせるということが難しいため、次のシステム更改ではプロジェクトを分割できても、今のプロジェクトを分割することは難しいでしょう。

開発という側面でも難しさがあります。まったく必要がないにもかかわらず、データベースを分割したり、マイクロサービス化したり、など、システムを複雑化させてしましまうかもしれません。疎結合になるというメリットが得られても、マスタ情報の配信・同期が必要になったり、分散トランザクション制御が必要になるのでは、プロジェクトの難易度が跳ね上がってしまいます。

### 機能性の違いで分割する

分析系と登録系の機能で分割するのもひとつの考え方です。登録系のシステムでは、データ反映のリアルタイム性が重要な役割を果たしますが、分析系のシステムではそこまでセンシティブではありません。登録系機能の設計・開発を優先し、分析系機能の設計・開発とは切り離すことは可能です。

最近では、Google BigQuery や Amazon Redshift、Snowflake といった BI 用データベースが簡単に構築できるようになり、PowerBI、Tableau、QuickSight のようなツールで簡単に集計・加工できるようになりました。分析系はいったんそれらのツールにお任せすることにすれば、登録系機能の開発に注力できます。

しかしこの考え方にも難点はあります。一般に業務設計ではアウトプットの分析こそが重要です。分析系機能の設計なしに登録系機能を設計することができるのか悩ましいところです。

### 工程で分割する

要件定義～基本設計で全体の設計を行いプロジェクトの分解点を明らかにした上で、詳細設計以降、プロジェクトを分割し実行するという考え方もあります。

開発側としては合理的ではありますが、要件定義～基本設計というフェイズを分割して契約することが前提となります。それでも、すべてを準委任の元でアジャイル開発するよりは現実的な解決策となるかもしれません。
金融知識


```ruby:金融知識
金利スワップ
　同じ通貨で異なる金利を交換する取引
　固定<->変動
　元本の交換は行わないが利息計算を行うための
　元本を想定元本と言う
スワップを用いた金融商品
　リバースフローター債
　リバース•デュアル•カレンシー債　
ポジション
　未決済のまま残った約定のこと
建玉
　ポジション
```
OpenCVでFPSを制御できない時に無理矢理FPSを下げる方法

# はじめに

普通の Webカメラ を購入すればあんまり発生しないんですが、一部「OpenCV で FPS を下げることができないカメラ」が存在します。
理由などはわかりませんが、そういったカメラで FPS を下げたい時に使用できると思います。

必要とされている方がいらっしゃればニッチな内容となりますが、一読してみてください。

# OpenCV で FPS を下げる一般的な方法

こちらは一般的な方法かと思います。

```python
import cv2

cap = cv2.VideoCapture(0)

# カメラ設定のFPS
print('original_FPS: ' + str(cap.get(cv2.CAP_PROP_FPS)))  # original_FPS: 20

cap.set(cv2.CAP_PROP_FPS, fps)

# 設定変更後のFPS
print('setting_FPS: ' + str(cap.get(cv2.CAP_PROP_FPS)))   # setting_FPS: 20
```

# 無理矢理 FPS を下げる方法

では、OpenCVを使用しないで、無理矢理 FPS を下げる方法を説明していきます。
カメラ初期値 30FPS を ```time.sleep()``` を用いることで、15 FPSにする方法を解説します。

### 解説

① 30FPSのとき、1フレーム取得するのにかかる時間は 33.3ms （1s / 30FPS）

② 15FPSのとき、1フレーム取得するのにかかる時間は 66.6ms （1s / 15FPS）

①と②の差は 33.3 ms で、__30FPSから33.3ms待機すれば15FPSと同じスピード__でフレームを取得することになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/c5ddb115-c9ea-e575-b232-3483dea4c68b.png)



### 手順

1. カメラ初期値のFPS（original_fps）と設定したいFPSの値（setting_fps）から 1フレームあたり調整時間（adjusting_time）を計算する
2. カメラ取得ループの中で フレーム毎に調整時間（adjusting_time）待機する



### ソースコード

```python
import cv2
import time

cap = cv2.VideoCapture(0)

change_fps_flag = True

# カメラ初期値のFPSと設定したいFPSの値から 1フレームあたり調整時間（adjusting_time）を計算
if change_fps_flag:
    original_fps = cap.set(cv2.CAP_PROP_FPS, fps)  # 30
    setting_fps =  15
    # 調整時間
    adjusting_time = 1 / setting_fps - 1 / original_fps  # 0.33333...

while cap.isOpened():
    ret, frame = cap.read()

    if change_fps_flag:
        # 毎フレーム、33.3ms待機する
        time.sleep(adjusting_time)
```



# まとめ

「OpenCV で FPS を下げることができないカメラ」 かつ 「FPSを下げないといけない」 というニッチだけど独自性はあるのかなぁと思って記事を書いてみました。
どなたかのお役に立てればいいなと思います。

---
### 会社紹介

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

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
【備忘録】ER-XでL2TPクライアントの設定をする（未完成）

EdgeOS2.0.9でL2TPクライアントの設定ができるようなので試してみた。

## L2TPサーバーへの接続設定

下記の設定を行う

```
set interfaces l2tp-client l2tpc0 authentication user-id <L2TPの接続ユーザー>
set interfaces l2tp-client l2tpc0 authentication password <L2TPの接続パスワード>
set interfaces l2tp-client l2tpc0 mtu 1400
set interfaces l2tp-client l2tpc0 server-ip <VPNサーバーのIP>
set interfaces l2tp-client l2tpc0 require-ipsec

set vpn ipsec esp-group L2TP-PSK-NAT pfs disable
set vpn ipsec esp-group L2TP-PSK-NAT mode transport
set vpn ipsec esp-group L2TP-PSK-NAT proposal 1 encryption aes256
set vpn ipsec esp-group L2TP-PSK-NAT proposal 1 hash sha1
set vpn ipsec ike-group L2TP-PSK-NAT dead-peer-detection action restart
set vpn ipsec ike-group L2TP-PSK-NAT proposal 1 encryption aes128
set vpn ipsec ike-group L2TP-PSK-NAT proposal 1 hash sha1
set vpn ipsec site-to-site peer <VPNサーバーのIP> authentication mode pre-shared-secret
set vpn ipsec site-to-site peer <VPNサーバーのIP> authentication pre-shared-secret <ipsecの認証鍵>
set vpn ipsec site-to-site peer <VPNサーバーのIP> ike-group L2TP-PSK-NAT
set vpn ipsec site-to-site peer <VPNサーバーのIP> local-address default
set vpn ipsec site-to-site peer <VPNサーバーのIP> tunnel 1 esp-group L2TP-PSK-NAT
set vpn ipsec site-to-site peer <VPNサーバーのIP> tunnel 1 local port l2tp
set vpn ipsec site-to-site peer <VPNサーバーのIP> tunnel 1 protocol udp
set vpn ipsec site-to-site peer <VPNサーバーのIP> tunnel 1 remote port l2tp

commit
save
```

## 結果

* サーバーへの接続は成功
* IPアドレスも取得できた
* インターネットに繋がらなくなった

## 考察

ゲートウェイかNATの設定が必要？
Windowsでは接続後にIPがサーバーのアドレスとして正しくネット接続ができているので、ルーティングの問題っぽい？

## 参考サイト

* https://www.labohyt.net/blog/gadget/post-5451/
* https://community.ui.com/releases/EdgeMAX-EdgeRouter-Firmware-v2-0-9-v2-0-9/d75f346d-d734-4026-97a8-7b2d5cc4e079
2021/07/14開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[Infra Study 2nd #3「いまさら聞けないIPv6ネットワーク」](https://forkwell.connpass.com/event/215799/)|[Forkwell](https://forkwell.connpass.com/)|654||
|:two:|[【LT満員御礼！】UI/UXデザイナーLT会 - vol.4 #uiuxdesignerslt](https://rakus.connpass.com/event/215913/)|[ラクス](https://rakus.connpass.com/)|348|360|
|:three:|[第9回 MLOps 勉強会 Tokyo (Online)](https://mlops.connpass.com/event/215133/)|[MLOps](https://mlops.connpass.com/)|339|500|
|:four:|[もしあなたが『アクセシビリティ試験』をやることになったら WP ZoomUP #68](https://wpzoom.connpass.com/event/216009/)|[WP ZoomUP](https://wpzoom.connpass.com/)|286|350|
|:five:|[プロダクトチーム全職種集合！1職種を10分で完全理解する祭](https://smarthr.connpass.com/event/216409/)|[株式会社SmartHR](https://smarthr.connpass.com/)|208|210|
templateをtemplateらしく使う

```html:index.html
<template></template>
```
テンプレートタグなるものを使いたいとき、調べた限りだとcloneして要素にデータを挿入してappendChildするように、ということだった。
参考 : [Qiita - template要素の使い方、知ってます？](https://qiita.com/saka212/items/ac77e778b7e323749e61 "template要素の使い方、知ってます？")
この「要素にデータを挿入」の処理が気に入らず、テンプレートらしく使う方法を考えたのでメモ。

##templateをこういう感じで書きたい
```index.html
<ul id="my_list">
	<template id="my_template">
		<li class="{{class_name}}">
			<a href="{{url}}">
				<h1>{{title}}</h1>
				<p>{{text}}</p>
			</a>
		</li>
	</template>
	<!--ここにリストを追加したい-->
</ul>
```

##こんな感じで書けばいけました

```template_to_html.js
var obj = { //追加したいデータ
	class_name: 'list_item',
	url: 'https://qiita.com',
	title: 'タイトル',
	text: '本文'
};

//テンプレートから書き込みデータを作成
function template_to_html(template_id,obj){
	//文字列としてテンプレートのinnerHTMLを取得
	var str = $(template_id)[0].innerHTML;
	//{{}}で囲まれた文字列を検索するための正規表現
	var reg = /{{[a-zA-Z1-9_\-]*}}/g;
	var arr,replaced = str;
	while((arr = reg.exec(str))!==null){
		//{{}}で囲まれた文字列をobjのキーとして置換
		var key = arr[0].replace('{{','').replace('}}','');
		replaced = replaced.replace(arr[0],obj[key]);
	};
	return replaced;
};

//書き込み処理
$('ul#my_list').append(template_to_html('#my_template',obj));
```

##実行結果
```result.html
<ul id="my_list">
	<template id="my_template">
		<!-- 中略 -->
	</template>
	<!--こういう感じで追加される-->
	<li class="list_item">
		<a href="https://qiita.com">
			<h1>タイトル</h1>
			<p>本文</p>
		</a>
	</li>
</ul>
```

##補足
- objのキーと{{}}内の文字列を揃えるのが大事。
- objを配列に入れて、書き込み処理をぐるぐる回せば連続で追加できる。
- 正規表現の書き方とかreplaceの仕方とかもっとスマートな書き方があるかも。innerHTMLで文字列として取得して置き換えるというのがポイント。
- appendのところをjQuery使わずにappendChildとすると、文字列として挿入されてしまう。htmlとして挿入できれば、脱jQueryも可。

##修正
- 21/7/16 11:00 正規表現で-と_を使えるように修正しました。
Rubyのバージョン変更について

# 概要
Rubyのバージョンの変更の仕方をお伝えします。

# 注意
現場では頻繁にバージョンを変えたりしないので、この点は気をつけてください。

# rbenvを最新のバージョンに更新
それぞれ見ていきます。

```
$ rbenv  install --list  #インストールできるバージョンの確認
```
```
$ brew upgrade ruby-build #rbenvを最新の状態にする
```
```
$ rbenv install 2.7.2  #バージョンを2.7.2に更新する場合
```
```    
$ rbenv rehash      #インストール完了後に実行
```
```
$ rbenv versions    #バージョン確認
```
```
$ rbenv local 2.7.2    #バージョンを2.7.2に指定
#rbenv versionsを実行して2.7.2の横に*がついていればOK
```

# 簡単なやり方
Railsで開発をしていると```.ruby_version```というファイルがあるはずです。
ここを変えたら自動で変わります。
```.ruby_version
2.7.1
```

      
# 資料

https://qiita.com/tkc310/items/9c9a6ccc110b159b967b
RUNNING LEAN 3章

# 本記事の目的

書籍「RUNNING LEAN 実践リーンスタートアップ」を読んだ学びをアウトプットすること。

# 3章のまとめ

- [見込み客を複数定義して、BMCを書け。](#見込み客を複数定義してbmcを書け)
- [実際にやってみろ。](#実際にやってみろ)


# 見込み客を複数定義して、BMCを書け。
**ポイント**
- 顧客とユーザーを区別すること。
>製品にお金を払ってくれる人が「顧客」、「ユーザー」はお金を払わない。

- 顧客セグメントを細かく分けること。
>あらゆる人をターゲットにした製品を効果的に設計・構築・出荷することはできない。
広く受け入れられる製品を目指していても、最初は特定の顧客を念頭に置かなければならない。

- 最初はすべてを1枚のキャンバスにまとめること。
>最初はキャンバスを1枚だけにして、顧客セグメントごとに色分けすることで、すべてを1枚に可視化する。
そこから必要に応じてキャンバスを分割する。

- 顧客セグメントごとにリーンキャンバスを書く。
> ビジネスモデルの要素は顧客セグメントによって大きく異なる。

# 実際にやってみろ。
ハンズオン形式でオンラインでLean Canvasを作れるツール。
本書でも紹介されている。

https://leanstack.com/leancanvas

**Lean Canvasを作成するためのヒント**

- 15分で書くこと。
- 空欄があってもいい。
- 簡潔に書くこと。
- 今わかる範囲で考えること。
- 顧客主導型で考えること。
- 課題と顧客セグメントから埋める。
    - 上位1~3位の課題を挙げる。
    - 既存の代替品を列挙する。
    - ユーザーを特定する。
    - アーリーアダプターを特定する。
- UVPを埋める。
    - 変わったものにする。
    - ただし、その違いが重要なものに限る。
    - アーリーアダプターをターゲットにする。
    - 成功ストーリーに注目する。
     - 機能は「プロがデザインしたテンプレート」
     - 利点は「見栄えのいい履歴書は目立つ」
     - 成功ストーリーは「念願の職につく」
    - 言葉をよく選んで使う。
     - 継続的に使用する鍵となる言葉。
     - 検索エンジン最適化のランキングを上げるようなものがいい。
    - 誰が・何を・なぜに答える。
    - 優れたUVPを研究する。
     - Apple
     - 37signals
     - FreshBooksなど
    - ハイコンセプトピッチを作る。
     - Youtube:「動画用のFlickr」
     - エイリアン（映画）:「宇宙のジョーズ」など
    - 効果的なUVPを作る公式

> 即効性のある明快な見出し = 顧客が望む結果 + 明確な期限 + それが達成されなかった場合の代替案

- ソリューションを埋める。
- チャネルを埋める。
 - インバウンド
 - アウトバウンド
- 収益の流れとコスト構造を埋める。
 - 収益の流れ
     - 無料登録から始めるのではなく、初日から課金すべき。
     - 価格設定については以下を参照。
     - [Don't just roll the dice](http://neildavidson.com/downloads/dont-just-roll-the-dice-2.0.0.pdf)
 - コスト構造
     - 30~50人にインタビューするのにかかるコストは？
     - MVPを構築してローンチするまでにかかるコストは？
     - 固定費と変動費の両面から見たバーンレートは？
     - 損益分岐点は？
  - 主要指標を埋める。
      - デイブ・マクルーアの海賊指標
  - 圧倒的な優位性を埋める。
      - 内部情報
      - 正当な「専門家」の支持
      - ドリームチーム
      - その人の信頼性
      - 巨大なネットワーク効果
      - コミュニティ
      - 既存顧客
      - SEOのランキング




# 次回記事投稿

4章から手法的な議論がメインになり、
ドキュメント化より実践することに重点を置いたため、更新をお休みしています。
本書が気になった人はぜひ読んでみてください。

# 前回記事

https://qiita.com/KentaroJay/items/82f175cf8c29bb64b1bd