OmniAICreator/Qiita-1.07M huggingface dataset:
Googleプロジェクト管理：デイリースクラム

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

[アジャイルマニフェストの原則][ref1]の1つに、

***<font color="MediumVioletRed">「情報を伝えるもっとも効率的で効果的な方法は、フェイス・トゥ・フェイスで話をすることです」</font>***

があります。スプリント中の対面イベント、デイリースクラムを通して、チームとコミュニケーションをとることについて説明します。

[ref1]: https://agilemanifesto.org/iso/ja/principles.html

# デイリースクラム

デイリースクラムは、スタンドアップと呼ばれることもあり、スクラムチームがその日の活動の同期と優先順位を決定するための時間である。

- ***<font color="MediumVioletRed">15分間</font>***
- ***<font color="MediumVioletRed">毎日同じ時間</font>***
- ***<font color="MediumVioletRed">同じ場所</font>***

で、各チームメンバーが次の質問に答えます。

- ***<font color="MediumBlue">昨日、私は開発チームがスプリントゴールを達成するために何をしましたか？</font>***
- ***<font color="MediumBlue">開発チームがスプリントゴールを達成するために、私は今日何をしますか？</font>***
- ***<font color="MediumBlue">私や開発チームが目標を達成するのを妨げるような障壁に何か気づきましたか？</font>***


デイリースクラムは、スクラムマスターに、少しの遅れで素早くチームの障壁を解除する機会を提供する必要があります。

***<font color="MediumVioletRed">『デイリースクラムは、スプリントバックログとスプリントゴールへの集中を強化する機会を作ります』</font>***

:::note info
公式のスクラムガイドでは、デイリースクラムは毎日行わなければならないとされていますが、私は、それよりも少ない頻度でミーティングを行っているスクラムチームを成功させてきました。私の現在のスクラムチームは1週間のスプリントで、1週間のうち2日デイリースクラムを行います。この方法は、私たちにとって非常に効果的であることがわかりました。あなたのチームにとって何がベストなのか、試してみてください。
:::

# Google エンジニアリング教育チーム プログラムマネージャー Sarah

プロジェクトマネージャーは、「データアナリストは、マーケティング担当者が何をしているかを知る必要はないだろう」と思いがちです。しかし、正直なところ、全員が毎週ミーティングに参加し、「これが今完成したもので、これが今取り組んでいるものです。今やっているのはこういうことです」と、ざっくばらんに話すことで、可視性と透明性が生まれ、仲間意識やチームワークが生まれます。

デイリースクラムのゴールは、レトロスペクティブのような長さではありません。できるだけ短くすることを意図しています。私は通常、15分から20分のスケジュールを組みますが、もっと短くてもかまいません。もし、特定のチームメイトやプロジェクト、プロジェクトの一部や進捗を妨げているものがあれば、その人たちやプロダクトオーナーと　***<font color="MediumBlue">さらに時間をとって</font>*** 、そのタスクに取り組み、それを解消するために何ができるかを確認する必要があるかもしれません。

デイリースクラムのもうひとつのポイントは、さまざまなタイムゾーンや場所にいる人たちと一緒に仕事をすることです。私がお勧めするのは、「午前11時（東部標準時）にやっても大丈夫か」という直感的な確認や調査を行うことです。というようなアンケートをとって、それがコンセンサスであることを確認してから、カレンダーに書き込んで、毎回全員が集まるようにすることです。 ***<font color="MediumBlue">締め切りが非常に厳しいプロジェクトで、毎日デイリースクラムを行う場合、私は、全員がそこにいることを義務付けるような文化は作らない</font>*** ようにしています。

毎日行われていることですが、プロジェクトの中には、他の時間帯より早く進むコンポーネントがあるかもしれません。デイリースクラムやその他打ち合わせにおいて、参加者の時間枠を守る優れた方法は、ミーティングの前にアジェンダを作成し、その横に何分のアップデートに割り当てたいかを書き出しておくことです。しかし、何か問題が発生した場合、私は通常、「話を途中で切るな」と言うようにしています。ステークホルダーやプロジェクトチームに対して、「あと2分です、終わりです」と言うのは、決していいやり方ではありません。でも、自然に会話が途切れるタイミングで、「実は、もう10～15分ほど別のことをする必要があったので、ピンを刺しておいて、後で時間があれば、また次のミーティングで話をしませんか？」と言えばいいのです。
二項係数と「n個からr個選んで並べる」の関係

二項係数と「n個からr個選んで並べる」の関係性について頭を働かせたので備忘として。

「n個からr個選んで並べる」は $${}_n P_r = \dfrac {n!}{(n-r)!}$$
二項係数は $${}_n C_r = \dfrac {n!}{r!(n-r)!}$$
つまり$${}_n P_r = {}_n C_r\times{r!}$$
となる。

これは具体例を当てはめると考えやすい。
1,2,3,4の数列から3個選んで並べる組み合わせを考える。
組み合わせの数は24通りとなるが、並び順を区別しなかった場合にいくつかの組み合わせはひとつにまとめられる。
今回は3個選んでいるため、並び順を区別しなかった場合の組み合わせの数に3の階乗を乗ずることで24になるはず。

より詳細に言うと、並び順を区別しなかった場合は{1,2,3}、{1,2,4}、{1,3,4}、{2,3,4}の4種類の組み合わせができる。其々は3の階乗(=6)通りの並び順を持つ。なので並び順を区別する組み合わせの数を求めると、
$$24=4\times{3!}$$
となる。

LaTexの記法は下記を参考にした。
- https://mathlandscape.com/latex-four-operations/
-  https://mathlandscape.com/latex-comb/ 
- http://xyoshiki.web.fc2.com/tex/binom.html
AWS App Runnerの環境変数にSSM Parameter Storeを指定する

# 背景
アップデートで、AWS App Runnerデプロイ時にAWS Secrets ManagerとSSM Pramaeter Storeの値を環境変数として取得することができるようになりました。

https://aws.amazon.com/jp/about-aws/whats-new/2023/01/aws-app-runner-secrets-configuration-aws-secrets-systems-manager/

SSM パラメータから値を取得するケースは結構ありそうなので試してみます。

## 前提
コンテナは作成、ECRにPush済みです。
環境変数$TEST_PARAMの値を画面に出力するコンテナを作成しました。
環境変数が設定されていない状態だとなにも出力されません。
![スクリーンショット 2023-01-25 160247.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/cd3abe7b-1fd4-a13c-5dfa-8ba47cbe769e.png)


## パラメータの作成
ssm パラメータの作成を行います。
`name：test-param`,`value：test-value`として作成しました。
```shell
$ aws ssm put-parameter \
    --name "test-param" \
    --type "String" \
    --value "test-value" 
```

## インスタンスロールの作成
App RunnerがSSM Parameter Storeにアクセスするためにインスタンスロールを作成し、ssmへのアクセス権限を付与します。
IAMのコンソールから以下の設定でロールを作成します。

信頼されたエンティティ
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "tasks.apprunner.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
RoleにアタッチするPolicy
```json
{
  "Statement": [
    {
      "Action": [
        "ssm:GetParameters"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:ssm:<region>:<aws_account_id>:parameter/<parameter_name>"
      ]
    }
  ],
  "Version": "2012-10-17"
}
```

## Serviceの作成
App Runnerのサービスを作成します。
環境変数欄で環境変数を設定します。
name：TEST_PARAM
valule：`arn:aws:ssm:<region>:<aws_account_id>:parameter/<parameter_name>`

![スクリーンショット 2023-01-26 115244.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/b98775bf-57fe-f61b-8dab-e51e975fc796.png)

インスタンスロールには先ほど作成したRoleを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/a978c9f4-9e07-e384-c4a5-21889ff109fd.png)

## 確認
デプロイ後、デフォルトドメインにアクセスすると、パラメータ値が取得されて表示されることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/43a4000a-901a-a92e-931d-d08ba3c475f7.png)

# 終わりに
ssm パラメータからパラメータ値を取得し、App Runnerの環境変数に配置するところまでを確認しました。
実際に試してみて。一度取得したパラメータ値から更新する場合はタスクを再デプロイしてパラメータ値を再取得する必要がありそうな点が気になりました。
余談ですがCopilotのmanifestでも試してみたのですが、うまくできなかったのでCopilotにはまだ未対応なのかもしれません。Copiloetで取得する場合は[Secrets機能][link-1]を使うのがベタかなと思います。

<!--以下リンク-->
[link-1]:https://aws.github.io/copilot-cli/ja/docs/developing/secrets/
Googleプロジェクト管理：スプリントプランニング

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# スプリントプランニングとは

スプリントプランニングは、スプリントの最初のイベントで、選択した長さに応じて、次の1週間から4週間の成功のためにチームをセットアップします。

スプリントプランニングでは、スクラムチーム全員が集まり、このスプリントでどれだけの時間や人などのキャパシティが使えるかを確認し、バックログからスプリント中にどの項目を行うかを特定します。これがスプリントバックログとなり、最終的にはスプリントゴールとなる。

# スクラムマスターの役割

この時、スクラムマスターはチームのコミュニケーションを促進し、イベントを通して以下の質問に答えます。

- ***<font color="MediumVioletRed">このスプリントの間に誰が利用できますか？</font>***
- ***<font color="MediumVioletRed">休暇やコンフリクトについて知っておくべきことはありますか？</font>***
- ***<font color="MediumVioletRed">平均ベロシティ、つまり過去に一回のスプリントでいくつのポイントやバックログアイテムを完成させることができたか？</font>***
- ***<font color="MediumVioletRed">この次のスプリントでチームが達成できること、達成すべきことは何ですか？</font>***
- ***<font color="MediumVioletRed">スプリントの最終ゴールは何ですか？</font>***
- ***<font color="MediumVioletRed">どのように仕事を終わらせるのか？</font>***
- ***<font color="MediumVioletRed">スプリント期間中、誰がどのタスクに責任を持つのか？</font>***

# Doneの定義

Doneの定義とは、ユーザーストーリーやバックログアイテムが完了したとみなされる前に完了しなければならない合意された項目のセットを指します。

Doneの定義には、

- ***<font color="MediumVioletRed">コードやソリューションが独立したピアグループによってレビューされていることが含まれます。</font>***
- ***<font color="MediumVioletRed">製品またはユニットがすべてのテスト要件（セキュリティやパフォーマンステストなど）に満たしている。</font>***
- ***<font color="MediumVioletRed">文書が完成している。</font>***
- ***<font color="MediumVioletRed">プロダクトオーナーが指定したすべてのユーザーストーリーの受け入れ基準を満たす。</font>***
- ***<font color="MediumVioletRed">最後に、プロダクトオーナーがユーザーストーリーを受諾する。</font>***

:::note info
このリストは包括的なものではないので、チームはこのリストに何が含まれるべきかを判断し、必要に応じて改善する必要があります。
:::

# スプリントバックログ

スプリントプランニングイベントの重要な成果物は、スプリントバックログです。スプリント バックログは、次のスプリントで完了することが確認されているプロダクトバックログ項目のセットです。言い換えれば、スプリントバックログは、プロダクトバックログから、その特定のスプリント中に完了することを目指すアイテムのサブセットである。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/44ca25fa-fa3c-070f-3a71-56d412c06134.png" width="600">

# スプリントゴール

スプリントゴールとは、チームが達成しようとする包括的な目標であり、チームがスプリントの理由を理解するのに役立ちます。これは、スプリントバックログにある項目の全体像からとらえる必要があります。

大きなスプリントゴールを特定することの利点は、別々の作業の流れに入れるのではなく、より広いチームの目標に集中することができることです。

例えば、Virtual Verdeが5月のスプリントとして以下の5つの項目を特定したとします。

- ユーザーは、盆栽を購入することができる。
- ユーザーは、ホームオフィスの装飾に関するオンラインディスカッションフォーラムにアクセスできる。
- ベンダー管理チームは、ベンダーの監査結果を追加することができる。
- ユーザーは、ホームオフィスアクセサリーを購入する際にクーポンを使用できる。
- カスタマーサポートは、商品とサポートチケットを結びつけることができる。

つまり、スプリントの目標は、

**「ホームオフィスに盆栽を設置したいと考えるユーザーに包括的な体験を提供すること」**

です。
React.js： JSXファイルのトランスパイル後のJavaScriptコードを確認する方法

React.jsでJSXファイルを作成した時、それがBabelでトランスパイルされた後のJavaScriptコードを確認したいと思いませんか？

実はできるんです。

Babelがどのように変換するか確認したいときは、Babel REPL

https://babeljs.io/repl

を使うことで、変換後のJavaScriptコードを確認できます。

このWebサイトでは、ページの左側に新しい構文のJavaScriptを記述すると、即座にBabelでコンパイルされて、ページの右側に結果が表示されます。

是非、ご活用ください。
ランダム量子回路ジェネレーターを作ってみた。

おはようございます。
[株式会社インスパイアサーチ](https://www.inspiresearch.io)の加藤 翼です。

昨日、ランダムに量子回路を作るPythonスクリプトを作ったので、公開します。
とてもシンプルなスクリプトで、一回走らせると、10個ランダムに量子回路を生成してくれます。

使ったのはQiskitです。
[ソースコードはGitHubにも公開しました。](https://github.com/stingraze/qiskit-random-circuit-generator)

```python3
#(C)Tsubasa Kato - Inspire Search Corporation 1/26/2023 16:17PM
#Referenced: https://qiskit.org/documentation/stubs/qiskit.circuit.random.random_circuit.html
from qiskit import QuantumCircuit, assemble, Aer
from qiskit.circuit.random import random_circuit
sim = Aer.get_backend('aer_simulator')
x = 1
#Create 10 random quantum circuits
while (x < 11):
    print("Count:" + str(x))
    circ = random_circuit(2, 2, measure=True)
    print(circ)
    x = x + 1
```
量子コンピュータのエンジニアさんが、量子回路を設計する際に、回路を作る際のインスピレーションになるかもしれないなと思いました。

YouTubeに実際走らせている動画をアップロードしました。下のサムネイルをクリックするとYouTubeの動画に飛びます。
[![Qiskit Random Circuit Generator](http://img.youtube.com/vi/CydEKmbkaeI/0.jpg)](http://www.youtube.com/watch?v=CydEKmbkaeI)

加藤 翼

[Twitter](https://twitter.com/_stingraze)
[LinkedIn](https://www.linkedin.com/in/tsubasakato/)
Googleプロジェクト管理：スプリント

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# スプリント

スプリントはイテレーションとも呼ばれ、チームの全体的なリズムを提供し、スクラムの5つのイベントの1つである。スプリントは、フィードバックを素早く得ることができ、チームのコラボレーションを促進し、スクラムチームがより集中できるようにします。

スプリント内では、チームの過去の能力に基づいて作業量が計画され、スプリントプランニングイベントで準備される。

各スプリントは、

- プランニング
- 実行
- 納品
- レトロスペクティブ

のすべてがこの一口サイズのパッケージに包まれたミニプロジェクトであると考えるのがよいでしょう。スプリントはScrumにとって非常に重要であり、他の4つのスクラムイベントはスプリントを中心に回っている。

スクラムガイドでは、

- スプリント（そのもの）
- スプリントプランニング
- デイリースクラム
- スプリントレビュー
- スプリントレトロスペクティブ

の5つのイベントを厳密に定義しています。

# スプリント期間中

- ***<font color="MediumVioletRed">スプリントゴールを危険にさらすような変更はしない</font>***
- ***<font color="MediumVioletRed">品質が低下しないこと</font>***
- ***<font color="MediumVioletRed">プロダクトバックログは必要に応じて改良されること</font>***
- ***<font color="MediumVioletRed">スコープを明確化し、プロダクトオーナーと再交渉することができること</font>***

:::note info
スプリントは、製品目標に向けた進捗を少なくとも毎月ごとに点検し、適合させることで、予測可能性を高めます。
:::

:::note warn
スプリントゴールが時代遅れになれば、スプリントはキャンセルされるかもしれない。スプリントを中止する権限を持つのは、プロダクトオーナーだけである。
:::

# タイムボックス

それぞれのスクラムイベントに対して推奨される期間、つまりタイムボックスが存在します。タイムボックスはスクラムにおいて重要な概念です。

例えば、

- ***<font color="MediumVioletRed">優先順位付けを促す緊急性の感覚を生み出す</font>***
- ***<font color="MediumVioletRed">生産性を向上させる集中の窓を提供する</font>***
- ***<font color="MediumVioletRed">チームの仕事のリズムを予測可能にする</font>***

などの利点があります。

スプリントのタイムボックスは、 ***<font color="MediumBlue">1週間から4週間</font>*** の範囲で設定することができます。どのように選択すればよいのでしょうか？それは、3つの考慮事項があります。

- ***<font color="MediumBlue">変更の頻度</font>*** をどの程度に想定しているかを考えます。要件はどのくらいの頻度で変更される可能性がありますか？もし、毎週新しい要求が出てくるようなプロジェクトであれば、スプリントの期間を1週間にして、より頻繁に適応できるようにするのがよいでしょう。もし、ニーズが安定しているのであれば、スプリントの期間を長くしても問題ないでしょう。
- 開発者がバックログ項目を開発するために ***<font color="MediumBlue">どれだけの集中時間</font>*** を必要とするかを考えてみましょう。もし、価値のあるものを作るのに、ほとんどの活動の基本的な努力が少なくとも1週間必要だとしたら、スプリントの長さは、チームが危機感を持たずに実行できるように、少なくとも2週間であるべきでしょう。
- 製品の納品に ***<font color="MediumBlue">どれだけのオーバーヘッド</font>*** がかかるかを考えることです。もし、あなたの成果物やソリューションが、多くのステークホルダーとの大規模なレビューを必要としたり、数日かかる厳格なテストや品質保証のプロセスを経たりする場合は、スプリントの長さにそれを考慮し、代わりに3週間や4週間といったより長いスプリントを選択すべきです。

# スプリント期間の調整

スクラムの多くのことと同様に、万能ではありません。もしスプリントの長さを決めて、何回かスプリントをしているうちに長すぎたり短すぎたりしたら、いつでも変更することができます。

- スプリントの期間が長すぎると、スプリントゴールは無効となり、複雑さが増し、リスクが増大する可能性があります。
- より短いスプリントは、より多くの学習サイクルを生み出し、コストと労力のリスクをより小さな時間枠に制限するために採用することができます。


例えば、毎週多くの変化や新しいリクエストがバックログに入ってくることを想定して、スプリントの長さを1週間にしていますが、しばしば作業が完了するまでに1週間以上かかることがあります。その矛盾を反省し、スプリントの長さを2週間に変更することができます。
niceコマンドについて

niceコマンドについて

「nice」というコマンドは、コンピュータで動作するプログラム（アプリケーションやタスクなど）の優先順位を変更するために使用されます。

例えば、あなたがスマートフォンでゲームをプレイしているときに、バッテリーが減りすぎるのを防ぐために、ゲームのアプリケーションの優先順位を下げることができます。

このように、「nice」コマンドを使用することで、コンピュータのリソース（メモリやCPUなど）を効率的に使用することができます。

使い方は簡単で、「nice」の後に、優先順位を変更したいプログラムのコマンドを入力します。 例えば、「nice -10 gimp」と入力することで、GIMPという画像編集ソフトの優先順位を下げることができます。

簡単に言うと、「nice」コマンドを使うことで、自分の使っているプログラムの優先順位を変えることができ、コンピュータのパフォーマンスを最適化することができます。

「nice」コマンドを使用するには、ターミナルアプリケーションを開きます。その後、「nice」の後に優先順位を変更したいプログラムのコマンドを入力します。そして、優先順位を変更する数値を入力します。

数値は、-20から19までの値を取ります。-20が最高の優先順位で、19が最低の優先順位です。例えば、「nice -10 gimp」と入力することで、GIMPという画像編集ソフトの優先順位を下げることができます。


使い方
実際に使用する際に例を示します。

「nice」コマンドを使用するには、ターミナルアプリケーションを開きます。その後、「nice」の後に優先順位を変更したいプログラムのコマンドを入力します。そして、優先順位を変更する数値を入力します。

数値は、-20から19までの値を取ります。-20が最高の優先順位で、19が最低の優先順位です。例えば、「nice -10 gimp」と入力することで、GIMPという画像編集ソフトの優先順位を下げることができます。

実際に使用する際に例を示します。

例1:

$ nice -10 gimp
これは、GIMPの画像編集ソフトを優先度-10で実行することを意味します。

例2:

$ nice -5 firefox &
これは、Firefoxブラウザを優先度-5でバックグラウンドで実行することを意味します。

これらの例は、「nice」コマンドの使用方法の一例です。優先度の数値は、実際の環境や目的に合わせて調整する必要があります。

「nice」コマンドを使用することで、コンピュータのパフォーマンスを最適化し、必要なプログラムがスムーズに動作するようにすることができます。
顧客分析の手順 - 分析の対象を特定する（セグメント）

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）

# 顧客分析の手順

## 第8回： 分析の対象を特定する（セグメント）
前回までで、顧客分析の対象データとしてまず単一の表（分析データセット）を準備し、これを用いて分析を実施していく手順を示してきました。ここではこのようにして得られた単一の表を、特定変数に基づいて分割する方法について整理します。


### 単一変数を用いた分割
非常にシンプルな例として、たった 1つの変数を利用して、顧客をいくつかのグループに分岐するケースが考えられます。性別で 2つのグループに分割する、口座残高額の多、中、少から 3つのグループに分割する等です。このように分割することによって、例えば「女性に特有の購買行動」や「残高の多い、つまり高貯蓄層に特有の金融行動」を理解することが可能となります。

### 複数変数を用いた分割
このような分割を発展させていくと、複数の変数を用いて分割することも考えられます。「女性で 20歳代のセグメント」、「残高が多く、投資商品を契約しているが、ローン商品は契約していないセグメント」のような形です。これによって、顧客数は絞り込まれますが、セグメント内の顧客の近似性は増加していきます。つまり「より似たような顧客」が同一セグメントに含まれるようになり、セグメントに対するイメージも具体的になってきます。

テクニック的には、複数の選定基準を設定し、これに該当する顧客を抽出します。「女性で 20歳代のセグメント」であれば、「性別が女性（AND）年齢が 21歳から 30歳」といった形式で表され、複数の選定基準は AND、OR等で結ぶことによって条件が接続されます。

### 生活に着目したセグメンテーション
このような手法を高度化させたとき、その一つの究極形は、「生活シーン」、「生活スタイル」、「生活ステージ」に基づいたセグメンテーションであると考えます。本来の分析対象である顧客は、何らかの生活を送っており、この生活上の欠落がニーズとなり、このニーズを満たすものとして企業が提供する商品やサービスが提供されます。従ってこの生活を基準に類似の顧客を分類することができれば、同一セグメントに属する顧客は同一のニーズを有している可能性が高く、同じメッセージや同じアプローチが効く可能性が高くなります。

この中で「生活シーン」は、日常の中で良く見られる風景に喩えられ、これを形作るような顧客属性、もしくは指標値を有しているか否かによって区別されます。例えば朝食のシーン、オフィスで働くシーン、海外旅行に出かけるシーン... 等がその代表例です。

そしてこの生活シーンの中でどのような嗜好性やルールを有しているかを「生活スタイル」と呼びます。和食を好む、便利なオフィスツールを積極的に活用する、ヨーロッパ旅行よりもアジア旅行を好む... 等が生活スタイルです。

そしてこのような生活シーン、生活スタイルに大きく影響を与えるのが生活ステージです。主婦、会社員、会社役員といった社会的な位置づけが生活ステージの代表的なものであり、より細かく考えれば同じ主婦でもお子さんがいらっしゃるか否か、お子さんが大学入学を控えているか否か等によってもステージは異なります。

（「生活シーン」、「生活スタイル」、「生活ステージ」については、別稿「ポストCRM を読み解く 10 のキーワード」内の各回を参照下さい。またセグメンテーション手法やコンセプトの詳細については「セグメンテーション/ターゲティング」にて記述していますので、併せて参考にしてください。）



### 複数セグメント間の関係
このような形でいくつかセグメントを作成していった場合、セグメントとセグメントの関係に関してもいくつかの作成ポリシーが生まれます。シンプルなセグメンテーションの場合、セグメントA（例: 女性）とセグメントB（例: 男性）は互いに排他的であり、その総和が顧客の全体となり、包括的に全ての顧客を把握します。一見するとこれは分かりやすい分類です。

しかしながら顧客群本来の姿に基づいてセグメンテーションを実施しようとした場合、必ずしも包括的である必要もなく、また重複も発生します。例えば、「婦人服専門購入顧客」、「紳士服専門購入顧客」の 2つのセグメントが管理対象であれば、それ以外は「その他」として考えれば良いかもしれません。またこの 2つのセグメントと重複する形で「生活用品購入セグメント」が管理対象となるかもしれません。

管理の方法としてはいずれの場合も一長一短あり、特にどちらかの方法に固執する必要はありませんが、どのような作成ポリシーで作成されたセグメントであるかは理解した上で活用する必要があります。


### セグメントの管理方法
また、実質的にそれぞれの顧客が属しているセグメントを識別する方法として、前述した選定基準による管理方法と、顧客に直接セグメント番号を割り当てる方法の 2つがあります。前者を利用する場合には、最新の顧客データを対象としてセグメントを理解することが可能です。例えば「預金額 > 1,000万円以上」のセグメントを理解するのであれば、セグメント番号を一旦割り当ててしまうと、その後、ある所属顧客の預金額が 1,000万円を割った場合に困ることになります。

一方、直接セグメント番号を割り当てることによって、理解が容易になる場合もあります。例えば「買上金額ランク」を毎年付与し、履歴で管理していくことによって、ランクアップ、ランクダウンのトレンドを明らかに出来ます。これに関しても、一長一短あるため、目的に応じて適した方法を選択します。



次回は、このようにして得られたセグメントを特徴付け、セグメントの特徴を理解するための方法について解説します。


#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
neosでlogix その95

# 概要
neosでlogixやってみる。
logixを、俺コードで表現してみる。

# 参考にしたページ

https://www.youtube.com/watch?v=EVf7-DFFyTM&list=PLJmSRkH6nodSslKeIgMaOcXtUeqVw8tAC&index=19


# 俺コード

```
NeosButton = ButtonEvents
	|> GetSlot
	|> FindCharactorController
	|> ApplyCharactorImpulse 0 100 0

```

以上。
rndcコマンドについて

●rndc（remote name daemon control）
namedの設定や管理を、ローカルやリモートから行えるコマンド。

BIND9ではnamedのインストールとともに「/usr/sbin/rndc」としてインストールされており、「/etc/named.conf」（named側）と「/etc/rndc.conf」（rndcホスト側）に共通鍵の設定を行い、アクセスを許可。

●rndcコマンドの書式

rndc [オプション] サブコマンド

主なサブコマンド
・status namedの状態を表示
・reload サーバの設定を再読み込みする(問い合わせ等は失われない)。ゾーンを指定した場合は、単独のゾーンだけ再読み込み可能。
・halt namedを直ちに停止
・stop 動的な更新等を保存してからnamedを停止
セキュリティ意識高い人は知っているWi-Fiのアレコレ

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はWi-Fiの仕組みについて更に詳しく調べてみましょう！

![インスタスライド_202301091.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/fe30a742-6413-fd43-022f-45113efcfacd.gif)


# Wi-Fiについて
「ワイファイ」と読む。
正式表記は「Wi-Fi」です。
無線LAN＝WiFiと思っても良いと思います。

# Wi-Fiの最大速度
最新の機器では最大伝送速度が 300 Mbpsです。

インターネットがG回線でもWiFiは、300Mが最速になります。

# SSIDとは
無線 LAN ネットワークを識別するための名前
この識別用の名前を SSID と呼ぶ。
Service Set Identifier
SSIDで接続先を選択できます。

# セキュリティ
SSIDは誰でも見ることができます。
そのため、誰でも接続可能になります。
それを防ぐためには、セキュリティを設定する事が重要です。

自宅のwifiには、パスワードを必ず設定する事！

# Wi-Fiの暗号化の種類
・WEP　
　　もっとも良く普及しています

・TKIP　
　　WEPの２倍の鍵の長さで暗号化

・AES
　　最も暗号化強度が高い

# Wi-Fiの認証の種類
・PSK　
　　共有鍵方式

・認証サーバー方式　
　　専用のサーバーで行うのでPSKよりセキュリティレベルが高い

# Wi-Fiセキュリティ規格「WPA」
・WPA
標準の暗号化方式としてTKIPを採用したセキュリティ規格です。

・WPA2
標準の暗号化方式にAESを採用したセキュリティ規格です。

# Wi-Fiセキュリティ
自宅のWi-Fiでは、WPA2を利用し

SSIDは非公開にするのがおすすめです

# まとめ
ー　 「ワイファイ」と読む

ー　最大速度は300Mbps

ー　暗号化、認証方式は色々ある

ー　SSID非公開、WPA2の利用がおすすめです

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
【Firebase】DocumentReference型のフィールドの変更を確認する際の注意点

特定のパスのコレクションに存在するドキュメントの内容が更新された場合に、その更新されたものが`DocumentReference`だったら古いものを削除するバックグラウンド関数を実装しました。

```ts
export const updateUser = functions
    .region(REGION)
    .firestore.document("users/{userId}")
    .onUpdate(async (snapshot, context) => {
        const oldData = snapshot.before.data();
        const newData = snapshot.after.data();
        
        if (
            "imageRef" in oldData &&
            "imageRef" in newData &&
            oldData.imageRef != newData.imageRef &&
            oldData.imageRef != null &&
            newData.imageRef != null
        ) {
            // 古いimageRefを削除する
            // ...
        }
    });
```

しかし、上記の条件だと、`imageRef`が更新されていないにもかかわらず現在の`imageRef`が参照するドキュメントが削除されてしまう現象に見舞われました。

実は、上記の条件の部分で１箇所だけ必ず`true`になってしまう部分があります。

それがこちらです。

```ts
oldData.imageRef != newData.imageRef
```

もし、値に変更がないか比較したいのであれば、次のように`path`を比較するべきなのでした。

```ts
oldData.imageRef.path != newData.imageRef.path
```

最終的な条件文は次のとおりです。

```ts
const oldData = snapshot.before.data();
const newData = snapshot.after.data();

if (
    "imageRef" in oldData &&
    "imageRef" in newData &&
    oldData.imageRef.path != newData.imageRef.path &&
    oldData.imageRef != null &&
    newData.imageRef != null
) {
    // 古いimageRefを削除する
    // ...
}
```

みなさんも`DocumentReference`型のフィールドを比較するときは、`path`まで含めて比較するようにしましょう。。。さもないと僕みたいに時間を溶かすことになります。。。
ストロングパラメータ

# １．ストロングパラメーターとは
- パラメーターを受け取る際に指定したキーをもつパラメータを受けとるように制限をかけるものです
- 制限がないと登録されるべきではない、カラムのデータが送られてきた場合に、そのデータが保存されてしまいます

# ２．基本の記述
```:○○○_controller.rb
private
  def message_params
    params.require(:モデル名).permit(:保存させたいカラム名).merge(カラム名: 追加したいデータ値)
  end
```

### ２−１．require(:モデル名) メソッド
- モデル名の部分には、今回送られてきたデータはどこのテーブルに保存したいのかを記載します。

### ２−２．permit(:カラム名)　メソッド
- カラム名の部分には、今回送られてきたデータはどのカラムに保存したいのかを記載します。
- `permit(:カラム名1, :カラム名2)`のように複数カラムを指定することも可能です。

### ２−３．.merge(カラム名: 追加したいデータ値)　メソッド
- ユーザーから受け取ったデータにはないけれど、追加したい値はmergeメソッドで追加できます。
- 例えば旅行先を投稿する機能があったとして、新規投稿する際に、ユーザーから送られる情報は、`locationとtitle`のみだったとします。
この場合、どのユーザーが投稿するかの情報は送られてきていません。
そこで、こちら側でログイン情報から`user_id`をとってきて登録しておきます。

# 最後に
かなり簡潔にまとめると
`require`（テーブルを指定）
どのテーブルの値をうけとりたいのか
`permit`（カラムの指定）
受け取りたい値の指定をしておく
`merge`（指定したテーブルにはないカラムを指定）
requireで指定したテーブルにはない値を指定したい
となります。
matchHeight.js でつまづいたこと

## なぜ matchHeight.js を使用したか
業務を進める中で、子要素の高さを揃える必要が出てきました。
CSSのFlexboxは便利なのですが、子要素まで高さを揃えることはできません。
テーブルレイアウトにすれば揃えることはできますが、
そうするとソースコードが見にくくなること、
対象のサイトがレスポンシブであることを考慮した上で、
HTMLのメンテナンス性を保つため「matchHeight.js」を使用することにしました。

## 問題点
例えば、以下のように横着して一括で要素を指定すると高さが揃いません。
（要素を一つずつ比較参照するのではなく、指定した全ての要素を同じ高さにしようとして、うまく動かないようです。）
```js:
$(function(){
    $('h2, p, dt, dd').matchHeight();
});
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PoBeVOL" data-user="codetan" 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/codetan/pen/PoBeVOL">
  matchHeight (fail)</a> by Yuki T (<a href="https://codepen.io/codetan">@codetan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 解決策
要素を配列で指定しておき`forEach`で回すことによって、
一つずつ`matchHeight`をかけていくようにすると高さを揃えることができました。
```js:
$(function(){
    const tgtSelectors = ['h2', 'p', 'dt', 'dd'];
    tgtSelectors.forEach(function(tgtSelector){
        $(tgtSelector).matchHeight();
    });
});
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzjLgWb" data-user="codetan" 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/codetan/pen/YzjLgWb">
  matchHeight (succeed)</a> by Yuki T (<a href="https://codepen.io/codetan">@codetan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 最後に
初歩的なミスだと思いますが、備忘録の意味も込めて残しておきます。
見えてきた時空間と宇宙の構造？

#
**AdS/CFT対応からは時空の構造と宇宙の成り立ちが類推できそう**

# AdS/CFTとホログラフィック原理

AIと量子コンピュータの話をしてたはずなんだけど、Googleとかが「EPR=ER」みたいな話を始めたり、自分の昔からあっためてた意識の仮説と先端のAdS/CFT対応やそこからの宇宙の成り立ち的な話までテンソルネットワークの最適化演算の話から綺麗に繋がっていて。

この世界の構造がAdS/CFT対応とホログラフィック原理からなる、という現代物理ではかなり注目の仮説は、量子もつれが量子コンピュータになるとかの話がとても小さく見えるレベルで、前回見たように、ディラックの海や、シリコン液滴から類推されたHQFT理論やとも基本的には同一とみなせる時空間の描像となっていたね。またテンソルネットワークのAdS構造への最適化を通じて、意識の情報空間も生み出せる情報処理と構造を持てることも自分は仮説を唱えてる。

念の為この時空の構造の簡単な想定をもう一度記載すると、この我々のいる3次元の全宇宙空間は、AdSに当たる5次元のバルク(中身)と、その表面のホログラフィック面(水面)とその外側からなる系の、水面(3次元だけど表面)部分であり、そこでは界面の波だけが存在し、AdSのバルクと接続して揺れ動いている部分だ、という事になる。(これは物質波や電磁波などの波として考えられる。この振動周波数がエネルギーと同値なのも当然になるね)

![Iizk6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/1d00b841-0e89-18da-1376-18bc4bfada0c.png)
【外側の表面が我々の宇宙】

また、ディラックの海の元々の描像や実際の物質と反物質の対消滅の振る舞いからすぐわかるように、水面(3次元の宇宙)を挟んで、通常物質の量子が存在する側(内部？)と、反物質の量子が全空間を埋めつくしている側(外部？)があって、その間に境界としての水面である我々の空間が存在していると考えられる。これも実際にディラックの元々の主張どおりだ。

そうすると、我々の宇宙がビッグバンで誕生して膨張してる、と言う描像はまさに、反物質で満たされた宇宙誕生前の所から、ある瞬間に点の現宇宙が現れ、それが膨張した、と見なせる。

これは高次元の常物質のバルク(量子はこの3次元でなく、AdSのバルクにあるよ)が誕生して、それが5次元空間上で膨らんだ、ので、その表面の我々の宇宙が広がった、と見なせるよね。

つまりAdSのバルクはまるで反物質で満たされた空間がある時「沸騰して」気泡ができるように誕生して、その大きさを一気に広げている、とも見なせるんじゃないか、と考えられる。

その描像は今までの議論、ディラックの海やHQFT、そしてAdS/CFT対応とも全く矛盾しない。そして、ビッグバンも宇宙の膨張もこの描像だけで説明が付くよね。そして、ビッグバン時の超光速の拡大(インフレーション)に関しても、バルクの拡大は表面の媒質の波(それが光)とその時間には影響されないと考えられるから矛盾しない。

# この世界に反物質が少ない理由が

そして面白いことに、この描像ならなんだけど。

今のAdS側が通常物質(高位の本来の量子で、この世界で観測される影ではない事に注意)で満たされているのは、ビッグバンでできた泡が元々反物質の巨大バルク中に発生した逆の領域なんだから当然なんだよね。

つまり、この考え方を取れば、

**この宇宙に反物質が少ない理由が一撃で説明できちゃうんだよね。**

# 今の宇宙の膨張も

その上なんだけど。宇宙が膨張しているのは、バルクの気泡の膜(3次元の水面)がどんどん広がってる訳だけど、それは中のAdSバルクの体積(超体積)が増えてるからなんだろう、と直ぐに類推ができる。

そして。そのAdSの高次元の中の「もの」の持つ総計のエネルギーが「ダークエネルギー」と考えればいいんだね。元々ダークエネルギーがどうしてあるのか、どこにあるのか、どうして宇宙を膨張させているのか、全く分からないと思うけど、この説だとちゃんとAdSバルクの持つエネルギーとして定義ができるし、宇宙膨張が完全に説明できるって事。

![cosmic-pie_planck-1-500x500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/d4c4d6bd-1af6-c1ba-2b80-28598ee8accf.png)

特に高次元だからといっても完全に別の物理が作用している必要は無い。座標系や系内の信号伝達速度(3次元なら光速)は違っていると思われるし、その超体積が表面(＝3次元空間)のどこにどう現れているかはまだ全く不明だけど。光速に当たる数値が変わるのは水中や水面での音速が違うようなものだ。次元と媒質が違えば当然光速度不変原理は変わっても問題ないよ。

# ビッグバンと反物質の少なさ、宇宙の膨張の機構

さっきふと思いついたんだけど、ビッグバンの成り立ちとこの世界に反物質が少ない理由がこうやって説明できる。膨張宇宙も分かるし。

そして今の膨張に関しても、例えば、外側の反物質バルクに僅かに含まれる常物質がこの世界を通って、泡の内部のAdSバルクに吸収されて大きくなってるのかも、だし、それってまさにブラックホールの拡大、あるいは蒸発に似た現象かもとも思える。

そうやって常物質の量がこの宇宙のAdSバルク側で次第に増えていく、のでその圧力？でこの表面宇宙は膨張する。一見物質が増えたら重力が増えて収縮しないとおかしいでしょ？？って、思うかもなんだけど、そうじゃないんだよ。バルクの内部に常物質が入ったら、バルクの5次元的体積が増えるから、この風船、水面、ホログラフィックである宇宙は膨張するんだよ。

だからこのモデルは基本全く矛盾なく、ビッグバン、その光速を超えた膨張、今の宇宙膨張、までちゃんと再現が出来るだろうと考えられるよね。うおー！！！🤔😂🤟

色んな考察をしてると楽しいね。少なくても大きな矛盾は無いだろうと思ってる。まあ研究者だとヨタ話に感じるのかもだけど、定性理論でもアインシュタインは相対論を作ったからね。こういう発想で色々まだまだ考えられそうに思ってるよ。いやー面白くて止まらないわ😂🤔
【Unity】知っていればよかった3Dモデル販売神サイト３選！！！

# はじめに
僕は、都内の某私立<font color="red">文系</font>大学生の１年生です。
UnityとC#でARコンテンツ開発を主として活動しており、サブでWebアプリ開発も行っています。僕についての紹介はこちらから！
https://qiita.com/RyuseiItoh/items/80cc0f3c419b0d5a5e6b
# 開発に必要なモデルはどこから～
## (1)販売サイトから購入する！
3D・2Dオブジェクトなどの素材は多くのサイトで0円から販売しています！
かなりのクオリティの素材がタダで販売していることも多く、先ずこちらの導入を検討してみましょう！！


## (2)自分で作る！
Blenderなどの3DCGアニメーションを作成するための統合環境アプリケーションを利用するのが一般的です！！
ただ、習得にも一定の時間を要するため、こちらの手段を利用するならばそれなりの理由が必要でしょう！

# 神販売サイト３選！！
## (1)Unity Asset Store
**The王道**ですね！！
Unityでアセットを集めるならまず訪れるべき神サイト！！
面倒な設定は全くなし、Unityをボタン１つで開き素材をインポートできるこの流動性が
ほんとに感動級です！！

とてつもないアセットの数が揃っており、星５を付けられたアセットだけを見ても
数万個以上の物が用意されています！！

セールも行われているので是非利用してみてください！！
アセットストアのリンクはこちらから：https://assetstore.unity.com/top-assets/top-download?locale=ja-JP

**良い点**：Unityとの相性最高！アセットの量がとてつもなく多い！
**懸念点**：基本英語で表記されているということなどが挙げられると思います！


　　　　　　　　　　　　　　〇参考動画乗っけておきます！！
<iframe width="560" height="315" src="https://www.youtube.com/embed/1j5tDWd3lVI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## (2)CGtrader
CGtraderは海外のサービスです！！
こちらは３Dオブジェクトのみを販売しているサイトです！！

個人的にはこのサイトで売られているアセットがとても刺さります！！
なんというかグッとくるものがあるんですよね！！
サイトでこんな曖昧な表現はよくないですね！笑笑

**良い点**：ジャンルが幅広く、クオリティがかなり高いこと！
**懸念点**：海外のサービスなので自然環境にあるようなイメージのオブジェクトは海外仕様ばかりで日本っぽいものはあまりないことやアセットストアに比べ問題が起きた時の資料が少ないなどですね！

　　　　　　　　 〇一応動画は乗っけますが字幕もスペイン語しかありません！
<iframe width="560" height="315" src="https://www.youtube.com/embed/ihszod-lmk4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## (3)Adobe Stock 
出ました！！**天下のAdobe**！！
僕自身
Premiere ProやPhotoShopをよく利用するのでめちゃお世話になってます！！
学生なので月**2000円**程ですべてのアドビの機能が利用できるのがとても強い！！

そんな最強のAdobeさんから３Dモデル買えちゃうんです！！
しかもなんと！！！超プロが作ったアセットが全て商用利用出来ちゃうんです！！
さすがというところでしょうね！！

**良い点**：全素材が商用利用可能でクオリティがとても高いこと！
**懸念点**：支払方法が様々で少しわかりにくいこと！

　　　　　　　　　　　　　　　〇Adobe Stockの紹介動画です！！

<iframe width="560" height="315" src="https://www.youtube.com/embed/1R2bbyLgaug" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>



# おわりに
皆さんいつも最後までご覧いただきありがとうございます！！嬉しいです！

本日の記事はどうでしたでしょうか！！
僕は基本アセットストアで買うのですが、CGtraderもいい味があるなぁって思ってます！！

これからももっともっと皆さんの役に立つ投稿になるよう頑張ります！！
次回もお楽しみにしていてくださいっ！！
バッチを作成！

## バッチを作ろう
バッチってなんですか！コマンドだよ！
コマンドってなんですか？ポチッてしたらできるやつだよ！

① バッチの処理内容を記述するファイルを作成。
（app/Console/Commands/にファイルが作成される）

```console
$ php artisan make:command コマンドの名前
ex) $ php artisan make:command UpdateAge
```


② 作成したバッチファイルを編集。
```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class UpdateAge extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:①コマンドを書く';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '②コマンドの説明を書く';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        ③ここに処理をかく

        ④↓書いた処理が終わったらログがでるようにする。（ログが確認できて安心）
        \Log::info('age was updated.');
    }
}

```
①コマンドを書く
コマンドを実行するときに使います。
スネークケースで書いてます。
ex) update_age

②コマンドの説明を書く
誰がみてもわかりやすいように書くと、後々楽です。
ex) '現在の年齢に更新する'

③ここに処理をかく
ポチッとした後、されて欲しい処理を書きます。

④↓書いた処理が終わったらログがでるようにする。
これは厳密には無くて良いんですが、コマンドがちゃんと実行されているか確認できるので便利です。
設定にもよりますが、backend/storage/logs/にログが記述されます。

## できたコマンドを確認
```php
$ php artisan list
Laravel Framework x.x.x
    :
    :
    :
 command
  command:update_age  現在の年齢に更新する

```
これで`$ php artisan command:update_age`でコマンド実行できることが確認できました。

## 外部からコマンドが使えるように
コマンドが増えていくと、いちいち一つずつコマンド実行するのは面倒です。
そこで`$ php artisan schedule:run`で登録しているコマンド全てが実行されます。

登録は、プロジェクト内の下記だけ！
```backend/app/Console/Kernel.php
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        \App\Console\Commands\UpdateAge::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // ->dailyAt('2:00')で、毎日2時にコマンド実行されます。
        // 詳しくはこちら https://readouble.com/laravel/8.x/ja/scheduling.html
        $schedule->command('command:update_age')->dailyAt('2:00');
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

```
Rails Sprockets::Rails::Helper::AssetNotFound の解決に色々頑張った話

# 始めに
仕事終わりにRails触るぞと思ってrails sをしてlocalhostにアクセスしようとしたらタイトルの通りトラブったので備忘録です。記事を調べた時にどれもこれも本番環境の話をしていたのでここでdevelop環境でエラーが起きた時の解消法を記事にしました。

# 起きた現象
画面のスクショを取り損ねたのでコピペ文章を貼ります。
```エラー:エラー
Rails Sprockets::Rails::Helper::AssetNotFound in Stations#index

The assets "application.css" is not found in the assets pipeline.
```
昨日は特に問題なく起動できたのになぜなんだ……application.cssなんて全く弄っていないが？　ということで色々調べてみたのですが、どうもアセットパイプライン周りのエラーっぽいことがわかりました。ということで行った対処がこちら。
```ターミナル
$ bundle exec rake assets:clean
$ bundle exec rake assets:precompile
```
これで無事再びlocalhostにアクセスしたら開けるようになりました。
ESP32のタッチセンサ機能で水位センサを実験

水槽の水位を測って、ポンプを動かしたい。

マイコンで測るには電極を水に挿して抵抗値を測れば簡単に値が取れる。しかしながらちょっと動かすだけならいいけど長期で動かすと電蝕の問題が発生する。

これと同様の問題は土壌センサでもあって、簡単な電極は何ヶ月も経つと腐食する。
と、秋月電子でこういったものがあるのに気がついた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4b5d5270-9ae2-ff3c-6504-ca00fe9327f0.png)
静電容量式だと腐食の問題は発生しない。では、同じ原理で水位も測れないかな?

ESP32で、簡単なタッチセンサ機能がある。
以下のスケッチで試してみた。


```
void setup()
{
  Serial.begin(115200);
}

void loop()
{
  Serial.println(touchRead(T0));
  delay(500);
}
```


# 環境

- 2023/01/27 00:00-01:00
- 湿度 40〜44%
- 気温 17℃
- Arduino 開発環境 1.8.19
- esp32 by Espressif Systems Version 2.0.4
- WROOM32 (WEMOS LOLIN 32)

# 実験
今回は、簡単にピン4にジャンパーケーブルをつなげた。導体を水に濡らさないように、ループの部分を水に浸すように考えてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c59b94da-98a9-3d4b-b726-a6cb6be27b83.png)

この状態で、値を取る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ba418e47-9de5-a006-8745-308785587055.png)

水に沈めたら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3d52aee4-9d42-4a0b-be87-d87d4adbfd3e.png)

値が変化しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5eb17750-48e2-abf4-26c1-a32111fea728.png)

U字型に折った状態で、先端から何センチ水に浸したときの値の変化
|0|1|2|3|4|5|6|7|8|9|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|81|71|67|64|62|60|59|58|57|56|

割と取れてますね。

# 値のゆらぎ

静電容量式は、環境によって値がどんどん変わっていきます。なので絶対値で取るのはダメで、変化量で判定する必要があります。
しかしながら、今回は水にずっとじゃぼ漬けして使いたいのでドリフトなどをいかにするとキャンセルできるかな?

まず、静電容量ですがGPIO4の値を測っています。何に対しての値かな?
基準レベルを設定するのが良くないかな、ということで水面をGNDに導通させておくのがいいでしょうか?
しかしながら今回は水面GNDではなく、GPIO4とGNDの並行線でプローブを作ってみることにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d49c69a9-ef30-f331-aeed-8c67e4276ed3.png)
水深よりは、水面に接触しているかどうかをより知りたいので、先端を単なるU字型ではなく♡型にしてみました。これをGPIO4とGNDに差し込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/69358cf4-a1f6-b8e4-fbee-cc5e31eb8aba.png)

この状態での測定値は55。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f499f466-e467-c70b-f9a5-f21fa3e2b660.png)

水に思いっきり浸けた状態では35になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2aa1d81a-24e3-0f8c-cb03-da889c435d32.png)

先端をちょとだけ水に浸けた値は44。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e489f73a-d177-c3f8-fbe5-dcb9a6594915.png)

一旦引き出して、水滴が付いている状態は49。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9d4b9b19-7d2e-2722-b0ed-cff965e8f018.png)

水滴を拭いて、水に浸けた深さ(cm)と値を測定しました。
|0|1|2|3|4|5|6|7|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|51|45|43|40|39|38|36|35|


# 暫定まとめ

- シングルラインプローブ、GNDとペアにしたプローブ、両方で水位を検出できる。
- GNDとペアにしたプローブが安定性が増すかどうかはこれだけの実験では不明
- ♡型が効果があるかどうかもこれだけの実験では不明
- 水面から1cm沈めた状態で10%程度値が下がる
- 更に5cm沈めた状態で15〜20%程度値が下がる
- 深さを増すに従い値の変化は小さくなる

これを元に水位を検出するのはまだアレで、少なくとも安定性を調べないといけません。
この状態で、しばらく測定を続けていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1b416595-a22f-ebdd-2cf2-d7d9d7e2c480.png)
Rubyで本気で考えるnil safe

※ 本記事の内容は[作者のブログ](https://www.fumi-blog.link/articles/hz3ekqyxyyiv)にも書いているのでこちらも応援お願いします🙇‍♂️

## はじめに
以下のようなclassを考えます

``` ruby
class Person
   attr_accessor :first_name, :last_name
   def full_name
     last_name + first_name
   end 
 end
```

このクラスは、苗字と名前を与えると、full_name関数でそれを合わせた形で取り出すことができます

``` ruby
person = Person.new
person.last_name = '山田'
person.first_name = '太郎'
puts person.full_name # 山田太郎
``` 

では、以下の場合はどうでしょうか

``` ruby
person = Person.new
puts person.full_name
```

実行すると以下のようなエラーが出てしまいました

``` ruby
`full_name': undefined method `+' for nil:NilClass (NoMethodError)
		last_name + first_name
```

## nil safeについて
一般的にプログラミング言語には、何も入っていないことを表すnull (Rubyの場合はnil)という概念があります

変数の中にnullが入ることを考慮せずに処理を書いた場合、意図しないエラーを起こすことがあります (一般的にヌルポと言われるものもこの一部です)
上の例の場合、last_name (およびfirst_name) にnilが入ってしまっているため、エラーが出てしまっているわけです

逆にnullが入ることを考慮し、nullが入っても動く仕組みにすることを **null safe** (Rubyの場合はnil safe)と言います

## rubyにおけるnil safe4パターン
では、上記でエラーを回避するための仕組みを考えてみましょう


### [パターン1] begin rescue
エラーが出る前提の元、エラーが出た場合の処理も記述する、と言う方法です

``` ruby
def full_name
  begin
    last_name + first_name
  rescue
    ''
  end
end 
```

エラーは出ない反面、begin rescue間のエラーを握り潰してしまう（どんなエラーが出たかを考慮しない）という意味ではかなり雑な対処法と言えます。


### [パターン2] nil判定
1つ１つの変数でnilかどうかを判定してあげるパターンです

``` ruby
def full_name
  (last_name || '') + (first_name || '')
end 
```


これはシンプルにかけて良さそうですね

ただし、rubyはfalseとnil以外を全て真値として判断してしまうため（本筋とは外れますが）こんな意地悪なことをされてしまうとエラーになります

``` ruby
person = Person.new
person.last_name = true
person.first_name = '太郎'
puts person.full_name
```

[実行結果]
``` ruby
`full_name': undefined method `+' for true:TrueClass (NoMethodError)
		(last_name || '') + (first_name || '')
		                  ^
```
動的型付言語の宿命ではありますが、この場合は（想像している以外の値を入れられているため）エラーを出すのが正しいのかもしれません



### [パターン3] to_s method
rubyにおいてnilはclassです

その特性を上手く活かすとこういう回避の仕方もできます

``` ruby
def full_name
  last_name.to_s + first_name.to_s #nil.to_sは空文字を返す
end 
``` 

これはnil classが to_s(文字列変換)のメソッドを持っているためです

ちなみに先ほどの意地悪な例はこのパターンだとエラーを出さずに通りますが、これは良い場合と悪い場合がありそうです

``` ruby
person = Person.new
person.last_name = true
person.first_name = '太郎'
puts person.full_name # true太郎
```

###  [パターン4] safe navigation operator
いわゆる「 **ぽっち演算子** 」 と呼ばれる方法です

``` ruby
def full_name
  last_name&.+ first_name
end 
```


この&.は **左側にある変数がnilの場合には処理を実行せずにnilを返す** というものです

(したがってfull_nameはlast_nameがnilの場合はnilを返します)

ただし、逆に言えば以下のような場合は結局再度nil safeを考慮しないといけなくなるため、問題を先送りにしているだけとも言えます

``` ruby
person = Person.new
puts person.full_name + 'さん' # full_nameがnilを返すためここでエラーになる
```

## まとめ
- rubyのnil safeには様々な方法がある
- どれも一長一短なので、場合によって使い分けることが重要

上手く使い分けて安全性の高いプログラムを作れるようになりたいものです
StableDiffusionに使われているVAE（変分オートエンコーダー）, U-Netについて解説

こんにちは、すきにーです。

去年発表されたStableDiffusionに 使われている vae と U-Net について書きたいと思います。 

①VAEとは
VAEは教師なし学習であるオートエンコーダーの一種です。
オートエンコーダーとは、入力されたデータを一度圧縮し、重要な特徴量だけを残した後、再度もとの次元に復元処理をするアルゴリズムのことを言います。
入力したデータの次元数をいったん下げ、再び戻して同じデータを出力するので、次元圧縮によく使われます。

オートエンコーダーとVAEの違いは、隠れ層の潜在変数に確率分布を使っているかどうかです。
オートエンコーダーの隠れ層には圧縮された特徴量が潜在変数として存在します。Xというデータを入力したら、隠れ層にはXの圧縮された特徴量が入っているということですね。
VAEの隠れ層では、潜在変数を取得するのに確率分布を使っています。

オートエンコーダーの出力層では、隠れ層の潜在変数を使って元のデータを作成しています。
この流れでVAEはオートエンコーダーのデコーダー部分を使って画像を生成しています。その時に使用する潜在変数を確率分布を使って取得しているという流れです。


②U-netとは
U-Netは、セマンティックセグメンテーション用のモデルです。

図を見るとわかるようにUの字の構造になっていることから、U-netと名付けられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116479/d26fc105-891d-fd13-71f4-1cc6ccd38ac6.png)

U-netはエンコーダーとデコーダーから成るモデルです。
エンコーダー部分で畳み込み、特徴の抽出を行っています。
デコーダー部分では、エンコーダーによって抽出された特徴を受け取り、逆畳み込みを行います。
逆畳み込みでは通常の畳み込みの逆の処理を行います。
逆畳み込みによって特徴マップを大きくします。これをアップサンプリングといいます。

U-netはエンコーダーの特徴マップをデコーダーの特徴マップに連結させるのが特徴になります。
連結させることで、エンコーダーの情報をデコーダーに伝え、分類精度を高めることができます。

参考
オートエンコーダー_Auto Encoder (Vol.21)
https://products.sint.co.jp/aisia/blog/vol1-21

VAE
https://ai-kenkyujo.com/term/what-is-vae/

U-Netとは | スキルアップAI 
https://www.skillupai.com/blog/tech/segmentation2/
ターミナルからVSCodeでファイルやディレクトリを開く方法

# 手順
手順1: VSCoddeで`Command＋Shift＋P`でコマンドパレットを開く
![スクリーンショット 2023-01-27 0.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/99122d03-b643-1bb0-02d4-a388f09632b3.png)


手順2: `shell`と入力し、Enterキーを押下
![スクリーンショット 2023-01-27 0.18.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/d05a84b9-a405-a295-c8bf-709a4545b51f.png)


手順3: 下記の表示が出ればOK
![スクリーンショット 2023-01-27 0.18.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/d4d195c9-9238-9b67-162b-cea3b9a424fd.png)

ここまで来たらターミナルから下記のコマンドを打つとVSCodeで任意のフォルダを開くことができます。
```terminalターミナル
$ code hoge(ファイルorディレクトリ名)
```
PureScript のフレームワーク Halogen をさわってみるゼ

# 初めに

Haskell と Elm をさわっている人が PureScript をさわってみる記事です

以下のようなカウンターを作ります。

https://dsaikawa.github.io/purescript-halogen-test/public/

# PureScript を動かす

以前作成した PureScript のリポジトリをもとに始めていきます。

https://github.com/dsaikawa/purescript-initial

以下の手順で取り敢えず PureScript 動かせます👏
```shell-session
$ git clone https://github.com/dsaikawa/purescript-initial purescript-halogen-test
...
$ cd purescript-halogen-test
$ npm install
...
$ npm run start
...
[info] Build succeeded.
🍝
$
```

# いざ Halogen を使ってみる🥳

Halogen インストール
```shell-session
$ npx spago install halogen
...
$
```

`/src/Main.purs` を書き換える
[Halogen Guide](https://purescript-halogen.github.io/purescript-halogen/guide/) からのコピペです
よくあるカウンターのサンプルです

```haskell
module Main where

import Prelude

import Effect (Effect)
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.VDom.Driver (runUI)

main :: Effect Unit
main = HA.runHalogenAff do
  body <- HA.awaitBody
  runUI component unit body

data Action = Increment | Decrement

component =
  H.mkComponent
    { initialState
    , render
    , eval: H.mkEval $ H.defaultEval { handleAction = handleAction }
    }
  where
  initialState _ = 0

  render state =
    HH.div_
      [ HH.button [ HE.onClick \_ -> Decrement ] [ HH.text "-" ]
      , HH.div_ [ HH.text $ show state ]
      , HH.button [ HE.onClick \_ -> Increment ] [ HH.text "+" ]
      ]

  handleAction = case _ of
    Increment -> H.modify_ \state -> state + 1
    Decrement -> H.modify_ \state -> state - 1
```

バンドルしていきます

```shell-session
$ npx spago bundle-app -y -t public/index.js
...
$
```

`/public/index.html` を作ります

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Halogen App</title>
    <script src="./index.js"></script>
  </head>
  <body></body>
</html>
```


# 開発の準備をする

- live-server
- npm-run-all

の2つを使ってホットリロードをさせて開発の環境を揃えていきます

まずはインストール
```shell-session
$ npm install live-server npm-run-all
...
$
```

package.json の script の部分を以下のように書き換えます

```json
"scripts": {
    "start:script": "npx spago bundle-app -t ./public/index.js -w",
    "start:live-server": "npx live-server public",
    "start": "run-p start:*",
    "build": "spago build"
  }
```

```shell-session
$ npm start
...
```

でホットリロードが行えるので開発が楽になると思います！

# 最後に

実際に動かすことができました、次は Halogen を使って色々作っていきたいと思います😘
Linux Mint 21.1 で phpLiteAdmin v1.9.8.2 を使う

Linux Mint 21.1 (Ubuntu 22.04ベース)

```
sudo apt install php8.1-cli
sudo apt install php-sqlite3
sudo apt install php-pdo-sqlite
sudo apt install php-mbstring

curl -OL https://bitbucket.org/phpliteadmin/public/downloads/phpLiteAdmin_v1-9-8-2.zip
unzip -d phpLiteAdmin phpLiteAdmin_v1-9-8-2.zip 
```

phpliteadmin.php修正
PHP 7.4以降get_magic_quotes_gpc()が廃止されているため492行から505行をコメントアウト(PHP5.4以降常にFALSEのため処理自体が不要と思われる)
PHPのバージョンかCLIのため？(原因調べられず)定義前のクラスのnewが出来ないようなのでMicroTimerクラス(5989行〜6021行)を使用前(476行より前)へ移動

```
cd ~/sqlite/
php -S 127.0.0.1:8080 ~/phpLiteAdmin/phpliteadmin.php
```


備考

sudo apt install php
でインストールするとapache2等もインストールされるようだったためphp8.1-cliを指定
Pythonチートシート - TKinterウィジェットの使い方一覧

Pythonを使ったGUIアプリを作りたいと考え、TKinterウィジェットの使い方一覧をまとめたアプリを作ってみました。後ほど実用的なアプリができたら公開しようと思います。

https://docs.python.org/3/library/tkinter.html

## 基礎となるTKinterウィジェット
以下のウィジェットを実際に作って1つのアプリに纏めてみました。
・ラベル、ボタン、インプット、エントリー、テキスト、スピンボックス、スケール
・チェックボックス、ラジオボタン、リストボックス

![スクリーンショット 2023-01-26 233414.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/e73117e3-25a1-92f9-f4c9-47b58054fa26.png)

## 実際のコード

```python
import tkinter as tk

#ウィンドウのタイトル+サイズ
window = tk.Tk()
window.title("GUI Program")
window.minsize(width=500, height=600)

#ボタンなどに使う関数
def button_clicked():
    print("I got clicked!")

    #インプットのテキストを取得 → ラベルのテキストを変更
    new_text = my_input.get()
    my_label.config(text=new_text)

#基礎となるTKinterウィジェット
#ラベル、ボタン、インプット、エントリー、テキスト、スピンボックス、スケール
#チェックボックス、ラジオボタン、リストボックス

#ラベル
#文字型を画面に表示する。label.configメソッド等で内容を変更できる
my_label = tk.Label(text="I am a label", font=("Arial", 24, "bold"))
my_label.pack()
#my_label.pack(side = "left")


#ボタン
#ボタンを押すことで、関数をつかって他のウィジェットを操作する
my_button = tk.Button(text="Click Me!", command=button_clicked)
my_button.pack()


#インプット
#ボタンなどで取得する用の文字列を記載する。
my_input = tk.Entry(width=10)
my_input.pack()
#print(my_input.get())


#エントリー
entry = tk.Entry(width=30)
entry.insert(tk.END, string="Default text")
entry.pack()


#テキスト
text = tk.Text(height=5, width=30)
text.focus()
text.insert(tk.END, "Default text - multiple line entry")
text.pack()


#スピンボックス
#スピンボックスがどの値かを取得する
def spinbox_used():
    print(spinbox.get())
spinbox = tk.Spinbox(from_=0, to=10, width=5, command=spinbox_used)
spinbox.pack()


#スケール
#スケールがどの値かを取得する
def scale_used(value):
    print(value)
scale = tk.Scale(from_=0, to=10, width=20, command=scale_used, orient=tk.HORIZONTAL, variable = 5)
scale.pack()

#チェックボタン
def checkbutton_used():
    print(checked_state.get())

checked_state = tk.IntVar()
checkbutton = tk.Checkbutton(text="Is on?", variable=checked_state, command=checkbutton_used)
checked_state.get()
checkbutton.pack()


#ラジオボタン
#ラジオボタンに割り振られた変数を関数で処理する際に使う
def radio_used():
    print(radio_state.get())

radio_state = tk.IntVar()
radiobutton01 = tk.Radiobutton(text="Option01", value=1, variable=radio_state, command=radio_used)
radiobutton01.pack()

radiobutton02 = tk.Radiobutton(text="Option02", value=2, variable=radio_state, command=radio_used)
radiobutton02.pack()


#リストボックス
def listbox_used(event):
    print(listbox.get(listbox.curselection()))

listbox = tk.Listbox(height=4)
fruits = ["Apple","Pear","Orange","Banana"]
for item in fruits:
    listbox.insert(fruits.index(item),item)

listbox.bind("<<ListBoxSelect>>", listbox_used)
listbox.pack()
window.mainloop()

#メインループを実行
window.mainloop()


```
「９マス」で悩まず書ける文章術

https://www.amazon.co.jp/%E3%80%8C9%E3%83%9E%E3%82%B9%E3%80%8D%E3%81%A7-%E6%82%A9%E3%81%BE%E3%81%9A%E6%9B%B8%E3%81%91%E3%82%8B%E6%96%87%E7%AB%A0%E8%A1%93-%E5%B1%B1%E5%8F%A3-%E6%8B%93%E6%9C%97/dp/4862806767/ref=sr_1_1?adgrpid=100232155901&gclid=CjwKCAiA5sieBhBnEiwAR9oh2l5NoO5MVaGZl-C2jqMTll3xSLcEmm9fBIxIn-XAU5FV1zUZQxO29xoCp-gQAvD_BwE&hvadid=618621948679&hvdev=c&hvlocphy=1009255&hvnetw=g&hvqmt=b&hvrand=16997991321907708175&hvtargid=kwd-914925722761&hydadcr=26827_11716764&jp-ad-ap=0&keywords=9%E3%83%9E%E3%82%B9%E3%81%A7+%E6%82%A9%E3%81%BE%E3%81%9A%E6%9B%B8%E3%81%91%E3%82%8B%E6%96%87%E7%AB%A0%E8%A1%93&qid=1674742620&sr=8-1

背景
仕事で記事を書く機会があったのですが、「いい文章を書くにはどうしたらいいんだ！？」という悩みがあり、それを解決することができそうな内容だったので、手に取ってみました。

本書のテーマ
「９マス」で情報収集、情報整理、文章作成まであらゆるシーンに活用できる。情報を可視化する技術を身につけ、自分の感情をうまく文章に表現する。

個人的なポイント
１，
文章の書き方に正解はないし、人の目を気にする必要はない。自分の魅力を伝えたいなら、まず自分を疑わないことから。

２，
読ませる文章にはwhyが大事。なぜかというと、物事の核心に迫るから。

３，
うまい文章＝目的を達成できる文章。あまり高すぎる目標を持ってもいけない。実現可能な目標がいい。

４，
いい文章には必ず、感情や気づきが入ってる。「出来事×感情型テンプレ」を使う。

５，
文章もPDCAを意識して書く。書いたらその結果を検証することが大事。

６，
マイナス地点から始める話のほうが聞き手、読みては感情移入しやすい。人生に迷っていた→でもこの出会いで人生が変わった　こんな流れがあるといい。自分のことを振り返るとあまりマイナス地点から話すことはなかったかもしれない。

１番心に残ったこと
「人の目を気にしない」ということが一番胸に刺さりました。私は文章を書くとき、上司や見る人の目ばかり気にしていましたが、そうではなく自分の魅力を伝えたり、目的を達成することに重きを置くべきでした。人の目を気にしていると目的がずれてしまう。そうなっては記事を書く意味がないので、まずはこのマインドを変えることが大事だと改めて実感しました。

やること
この本には、たくさんのテンプレートが掲載されています。
なにか文章を書くときにはこちらのテンプレートを活用し、ぶらっすアップしていきたいと思います。

まとめ
他にもいい文章を書くにはどうしたらいいかという関連の本を読んでいましたが、文脈やロジカルにという内容が多かったです。
この本はまた違った視点から書かれていて非常に勉強になりました。
あと、私は本を読むとき、９この学んだことをピックアップしているのですが、「９マス」が共通項泣きがしてなんとなく親近感を覚えました。
楽しく文章を書きたいという方にはおすすめの本です。
PythonでRaspberryPiで撮影したカメラ映像をリアルタイム転送する

# はじめに
本記事は備忘録の一部です。
![Fig.1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629378/e2b80505-44b4-feff-715f-e41c0429a513.jpeg "[Fig.1]カメラを搭載したRaspberryPi4")

**監視カメラ**でも作ろうかと過去のコードをぴっぱり出したところ、コピペでは動作しなくなっていたので、最近の仕様変更に合わせたコードへの修正となります。

具体的には、**RaspberryPi**で取得したデータをほかのデバイス(Pythonが動くもの)で表示させるというものになります。

本コードは拡張性が高く、**リアルタイム映像をAI・機械学習等の処理**にかけるときに別のサーバー上で処理ができるので大変重宝しております。**簡易監視カメラ**にもなりますし、**Python**で書かれているのでNAS等に動画を保存しておくことも可能です。可能性は無限大と言えますね！

中華のIPカメラでやれよって話ですけどね。

# 目標

![Fid.2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629378/163fe451-4975-1aec-2481-268e64ec9463.png "RaspberryPiで所得した映像を、別のデバイスで表示させる")
本記事では映像の転送に**Python3.7**を使用しております。いまだにRaspberryPiの標準装備だったので採用しました。
ライブラリには**Socketserver**と**OpenCV**を利用しております。
ハードウェアには自宅に転がっていた**RaspberryPi4**と**Windows10PC**を利用しています。
カメラは選択さえすれば良いのでUSBカメラでもOKです。

# コード

まずカメラ側、RaspberryPi側のコードです。
とはいっても単にSocketserverでサーバーを建ててOpenCVで圧縮した映像のデータを転送するだけです。
```Python3:server.py
import socketserver
import cv2
import sys

HOST = "192.168.XXX.XXX"  # ここはRaspberryPiのIPアドレスを入力
PORT = 5569


class TCPHandler(socketserver.BaseRequestHandler):
    videoCap = ''

    def handle(self):
        ret, frame = videoCap.read()
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 100]  # この値100は映像の質の値
        jpegs_byte = cv2.imencode('.jpeg', frame, encode_param)[1]
        self.request.send(jpegs_byte)


videoCap = cv2.VideoCapture(0)
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer((HOST, PORT), TCPHandler)

try:
    server.serve_forever()
except KeyboardInterrupt:
    server.shutdown()
    sys.exit()
```

この程度のコードにClass分けなどしたくないのですが、Socketserverのドキュメントには使い方としてこの書き方をしていたため、致し方なくそのまま利用です。

して受信側のコードは以下の通りです。

```Python3:client.py
import socket
import numpy
import cv2

HOST = "192.168.XXX.XXX"  # ここはRaspberryPiのIPアドレスを入力
PORT = 5569


def getimage():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))

    buf = []
    recvlen = 100

    while recvlen > 0:
        receivedstr = sock.recv(1024*8)
        recvlen = len(receivedstr)
        buf += receivedstr
    sock.close()
    recdata = numpy.array(buf, dtype='uint8')
    return cv2.imdecode(recdata, 1)


while True:
    img = getimage()
    cv2.waitKey(5)  # 少し待ってやらないと映像が生成される前に次の処理が来て映像が映りませんでした。
    # img_90deg = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) # 映像が時計方向90度に曲がっていた場合
    cv2.imshow('Capture', img)
```
後はそれぞれを起動させて各々アクセスするだけです。

# まとめ
![Fig.3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629378/c5cd46f1-b79b-c5b1-dedb-85f245a4d5a0.png "動作中")

実際に動作させているとこんな感じでWindowが出て映像をリアルタイムで表示します。
しかしこの場合はオートフォーカス機能がなく、ぼやぼやの映像が映し出されてますね。
ちなみにテストで24時間連続で稼働させてみましたが、特にエラーを吐くこともなく今のところ順調に接続されています。

過去のコードと比較していくつか小さな変化はあるのですが、最も大きかったのは**cv2.waitKey(5)** これでした。いままでRaspberryPi3で利用していた時にはこの行は不要だったのですが、4になってから処理速度が劇的に向上して、映像が形成される前に通信処理が済んでしまうため映像が中々出てきませんでした。
皆さんは自身の利用するデバイスに応じてこの値を弄ってみてください。

セオリー的には処理の遅いハードウェアにwaitって入れるものですけど、いやはや処理が早すぎるってのも罪ですね。