OmniAICreator/Qiita-1.07M huggingface dataset:
【Java】CVE-2021-44228のLog4j脆弱性について調べてみた


話題になっていたので調べてみました。

## 脆弱性の内容について

NISTが出している脆弱性情報を参照しました。
https://nvd.nist.gov/vuln/detail/CVE-2021-44228

大まかな特徴としては以下

* Log4j2 <=2.14.1 までのバージョンで起きる脆弱性である。
* JNDI Lookupの機能を使ってログメッセージからLDAPのプロトコルを使って外部から悪意のあるプログラムが実行される可能性がある。
* 実行できるプログラムの内容は特に制限がない

なので、非常に重大なセキュリティホールとして発表されています。

## 脆弱性に対する対策

Log4jのバージョンによって対策方法が色々あるみたいです。

・Log4jのバージョンを最新バージョンにアップデートする
Apacheのコミュニティからすでにパッチ修正がかかったバージョンがリリースされているので、アプリケーションの仕様などでLog4jのバージョンを固定する必要がなければ最新版へアップデートすることで対策できます。
[Log4j – Apache Log4j Security Vulnerabilities](https://logging.apache.org/log4j/2.x/security.html)

・2.14-2.10までのバージョンの場合
Java起動時の変数で`log4j2.formatMsgNoLookups=true`に設定することで問題となっているJNDILookupの機能を無効化できます。

・2.10以前の場合（2.0-beta9 to 2.10.0）
設定できる定数がないためJNDILookupのクラスファイルを削除が必要です。

以下コマンドが出されているのでJarから対象クラスファイルを削除方法が提供されています。

`zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class`


## その他関連情報

### JNDI is 何？
JNDIは “Java Naming and Directory Interface”というAPIの略語でJavaが持つ名前空間を検索する際に使うもの

JNDIがあることでJavaからLDAPやDNSなどのプロトコルを個別に実装することなく使うことができます。

[第 10 章  JNDI リソース](https://docs.oracle.com/cd/E19823-01/819-1551/jndi.html)
[Lesson: Overview of JNDI (The Java™ Tutorials > Java Naming and Directory Interface)](https://docs.oracle.com/javase/tutorial/jndi/overview/index.html)

### マイクラサーバーではなにか対処方法ある？

MineCraftもJavaEditionはLog4jを使っているのでセキュリティの脆弱性についてブログ記事が出ていました。

[Important Message: Security vulnerability in Java Edition | Minecraft](https://www.minecraft.net/ja-jp/article/important-message--security-vulnerability-java-edition)

対処方法は公式側で準備した記事が掲載されているのでまずこっちを確認するが良いと思います。

[Security Vulnerability in Minecraft: Java Edition – Home](https://help.minecraft.net/hc/en-us/articles/4416199399693-Security-Vulnerability-in-Minecraft-Java-Edition)

## 参考情報

[Log4Jゼロデイ脆弱性の概要と手法・対策方法](https://qiita.com/cronree_91/items/0a18809c1dac2a6f9452)

[Apache Log4j2 2.14.1 Remote Code Execution](https://packetstormsecurity.com/files/165225/Apache-Log4j2-2.14.1-Remote-Code-Execution.html)
[logging.apache.org:configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html)
[Apache Log4j Security Vulnerabilities](https://logging.apache.org/log4j/2.x/security.html)
変数に入れた種類のインスタンスを作るには

　プロデルでは，これはエラーである。

```プロデル
山とは
	【高さ】は，0。
終わり

あは，山
富士山というあを作る
```

しかしこれをどうしてもやりたいことはよくある。これを実現するためには，`型情報を取得する`と`インスタンスを作る`を併用すれば良い。

```プロデル
山とは
	【高さ】は，0。
終わり
ビルとは
	【高さ】は，0。
終わり
あは，山
富士山は，あから型情報を取得したものからインスタンスを作ったもの
あは，ビル
ヒューリック神谷町ビルは，あから型情報を取得したものからインスタンスを作ったもの

富士山の高さは，3776
ヒューリック神谷町ビルの高さは，「11階」
富士山の高さを報告
富士山から型情報を取得したものを報告
ヒューリック神谷町ビルの高さを報告
ヒューリック神谷町ビルから型情報を取得したものを報告
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/87fca579-d954-a534-08ca-f65b7df027a2.png)

　これのありがたみはこれ。

```
いは，｛富士山，ヒューリック神谷町ビル｝
うにいをそれぞれ繰り返せ
	うの高さを報告。
繰り返し終わり
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/1c6f8857-96b9-b030-5e6a-68c9f5f949a5.png)
Azure Front Door で Basic認証する

### 何に使う？

サイトの正式公開前に関係者だけで評価したいなどのユースケース

### 制限等

- App Service なら X-Azure-FDID でロックダウンし、`*.azurewebsite.net`への直接アクセスを防ぐことは出来る

https://docs.microsoft.com/ja-jp/azure/frontdoor/front-door-faq#--------------azure-front-door-------------------------

- しかし、Blob Storage による Static website などの場合は上記は使えないので`*.web.core.windows.net` へのアクセスは防げない(現状の無印 Front Door で何か良い方法があったら教えてください)。これは2021/12現在はまだプレビューだが Private Link を使えば保護できるっぽい(まだ私は試してない)。

https://docs.microsoft.com/ja-jp/azure/frontdoor/standard-premium/concept-private-link

![](https://docs.microsoft.com/ja-jp/azure/frontdoor/media/concept-private-link/front-door-private-endpoint-architecture.png)

- 残念ながら Front Door だけでは構成することができず、401 Authorization Requiredを返すことのできる Webサイトが必要。理由は後述。

### 構成

「ルール エンジンの構成」を使い、リクエストヘッダーに

```
Authorization: Basic xxxxx
```
が存在しない場合、

```
HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic realm="hogehoge"
```
を返すサイト(バックエンドプール)に転送する。
「ルール エンジンの構成」では要求ヘッダー、応答ヘッダーを書き換えることは出来きるので、応答ヘッダーとして`WWW-Authenticate`を返す事はできるが、残念ながらレスポンスコードの操作はできないので何らかの401応答サイトが必要。

![frontdoor-basic-auth.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/bb738ea5-e774-fc05-ac90-cfceab1ef410.png)

#### 401応答サイトに関して

これは特に Azure である必要もないし、実際にサービスを行うサイト(App Service等)の特定パスに Basic認証をかける様にしてバックエンドプールとして定義しても良いと思う。自分はテスト的に行ったので、既存の外部サイトを用いた。App ServiceやDocker上の各種Webサーバーでの方法は検索すればすぐに見つかると思うのでここでは触れない。

### 設定

#### Front Door デザイナー

詳細は省くが、バックエンドプールとして `hoge` と `basicAuth` を用意した。`/*`へのアクセスが `hoge`バックエンドに回る設定。`basicAuth`は既存で運用しているBasic認証ありの外部サイトを指定した。

![スクリーンショット 2021-12-11 14.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/ad739e30-76e5-57ce-3cb8-07fe8278ac46.png)

#### ルール エンジンの構成

すでに説明した通り、`Authorization`要求ヘッダーが`Basic xxxx`と等しくない場合は、ルーティングの構成を`basicAuth`バックエンドプールに回すようにしてるので401と`WWW-Authenticate`が返される。結果としてブラウザー側にばBasic認証のダイアログが表示され、次のリクエストからは`Authorization`ヘッダーが付与されたリクエストが送られてくる。

![スクリーンショット 2021-12-11 14.11.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/ff71bf0d-e988-1198-bef5-e651d19b434c.png)

なお画面キャプチャのサンプルの値は username=user, password=pass の値になる。念の為導出方法を。

```
$ echo -n user:pass | base64
dXNlcjpwYXNz
```

#### SPAの場合(おまけ)

よくある、Frontend SPA + Backend APIの様な構成で、外部で認証してJWTを取得し、APIを呼び出す(`Authorization: Bearer`)構成の場合は、Frontend側だけにルールエンジンとの関連付けを行い、API側はには関連付けは行わないこと。と言っても前述の通り Blob Storage Static website の場合、直接アクセスをどう防ぐか問題が出てくるんですが…。（ご存知の方教えてください）
Next2D Player入門

これまで、`NoCode Tool`の紹介をしてきましたが、今日からは`Next2D Player`の紹介をさせてもらえたらと思います。
Next2Dプロジェクトの根幹のライブラリで、レンダリングエンジン・各クラス毎の機能が実装されています。
`NoCode Tool`はこれらの機能をプログラマーのようにコードを書かなくても直感的に操作できる事を目的としています。
プログラミングができる方であれば`Next2D Player`に直接コードを書く事で多彩な操作が可能になります。

# NoCode Toolとの連携

NoCode Toolで作成したアニメーションをJSON形式で書き出しデータはPlayerで読み込みが可能です。

## 簡易的な読み込みサンプル

NoCode Toolで書き出したJSONをPlayerから読み込みます。

## 事前技術共有
第二引数はオプションを設定できます。

プロパティ名|型|デフォルト値|説明
---|---|---|---
base | string | empty | 相対パスでJSONを取得する場合、ここで設定したURLがrootとして適用されます。絶対パスの場合はここで設定したURLは適用されません。
fullScreen | boolean | false | Stageクラスで設定した幅と高さを超えて画面全体に描画されます。
tagId | string | empty | IDを指定すると、指定したIDのエレメント内で描画を行います。
bgColor | array [R,G,B,A] or false | false | 背景色の[R,G,B,A]の配列は0～255で指定できます。falseは無色透明です。

```javascript
next2d.load("wave_a_hand.json", {
    "base": "https://next2d-demonstration.herokuapp.com/json/",
    "tagId": "container"
});
```

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="js,result" data-slug-hash="rNGMrZG" data-user="next2d" 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/next2d/pen/rNGMrZG">
  [Next2D Player] Sample of reading a static JSON file</a> by Next2D (<a href="https://codepen.io/next2d">@next2d</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 動的な連携

```javascript
const { Loader }     = next2d.display;
const { URLRequest } = next2d.net;
const { Event }      = next2d.events;

// RootのMovieClipを作成
const root = next2d.createRootMovieClip(240, 240, 12, {
    "base": "https://next2d-demonstration.herokuapp.com/json/",
    "tagId": "container"
});

const request = new URLRequest("wave_a_hand.json");

const loader = new Loader(request);
loader
    .contentLoaderInfo
    .addEventListener(Event.COMPLETE, (event) =>
    {
        root.addChild(event.currentTarget.content);
    });

loader.load(request);
```

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="js,result" data-slug-hash="VwMKGEv" data-user="next2d" 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/next2d/pen/VwMKGEv">
  [Next2D Player] Sample of reading a dynamic JSON file </a> by Next2D (<a href="https://codepen.io/next2d">@next2d</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

どちらも呼び出すJSONは同じですが、動的なサンプルはイベントの設定やその後の拡張などが可能になります。
明日は、動的な読み込みを行うLoaderクラスの紹介ができればと思います。
STM8S103F3P6ボードを試してみる

MH-tinyボードに続く安物買いの銭失いとなるかシリーズ第2弾です。

今回はstm8s103f3p6ボード、stmの8bitシリーズになります。
現在Aliでお値段￥125です。(半導体不足前は100円以下だったでしょう)

https://ja.aliexpress.com/item/32819499209.html

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/c5719a41-81bc-9fd8-7d4b-f2a79b4ceeb1.png" width=400 /> 


届いたのでさっそく開封の儀といきます。


### Arduinoで遊ぶ

Arduinoで使えるようにサポートがあるのでここの手順にセットアップを行います。

https://tenbaht.github.io/sduino/

環境設定→追加のボートマネージャのURLに`https://github.com/tenbaht/sduino/raw/master/package_sduino_stm8_index.json`を貼り付けてOKをします。

次にツール→ボードマネージャを開いて`Sduino STM8 ~`をインストールします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/6ca32f38-7d63-3bc1-c0a7-423831bbf304.png" width=400 /> 

インストールしたらボードでSTM8S103F3 Breakout Boardを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/a6b0a422-82a2-cdfc-a9c2-901f57611f05.png" width=400 /> 

ボードを選んだらSTM8S103F3 用のBlinkをサンプルから選びます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/548685bd-0e8e-f596-3bdc-8b95627c2faf.png" width=400 /> 

どこのご家庭にもあるSTLinkV2とボードを結線したら書き込み装置でSTLinkV2を選択して書き込みます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/8773f00c-5e9b-be80-2c29-bf3c66ed0682.png" width=400 /> 

動きました。
サンプルも豊富ですし色々と遊べるかもです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146663/d390b95a-9b8a-90d5-32bb-463a2e9c4c4a.png" width=400 /> 

ただBlack pillとかはSTM32用のAruduinoブートローダーを書き込めばUSBケーブル経由でスケッチを書き込みできますが、
なかったのでSTLink経由での書き込みがめんどいなぁと思いました。
こちらの方が安いけどピン数も多いし個人的にはMH-tinyがいいかなと😅

以上、簡単なレポートでした。
<備忘録> Ruby on Railsのminitestを少しだけ見やすくする方法。

# Ruby on Railsのテストをちょっとだけ快適に。
初心者独学中の者です。
テストの結果に色をつけます。
使用するGemは`minitest`です。

## 環境
* macOS      Monterey 12.0.1
* Ruby       3.0.3
* Bundler    2.2.32
* Rails      6.1.4.1
* minitest (5.14.4)

before
![スクリーンショット 2021-12-11 15.07.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344199/09c39127-8b1e-520c-b212-28d1c08f9890.png)
テストが通っているのかどうか分かりずらい。
そこで色をつけて見えやすくします。

## test_helper.rbに書き込む
```ruby:test_helper.rb
require "minitest/reporters"
Minitest::Reporters.use!
```

after
![スクリーンショット 2021-12-11 15.07.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344199/15902afd-dff5-d222-c616-695fba4262f1.png)

以上、少しだけ見えやすくなりました。

間違っているところがあれば是非教えてください。
よろしくお願いします。
Page Without Valid React Component(Next.js)

# 症状
next buildを実行したところ、下記エラーが出た。

```
next build
...
> Build optimization failed: found page without a React Component as default export in
pages/top

See https://nextjs.org/docs/messages/page-without-valid-component for more info.

info  - Collecting page data .
```

# 解説
[https://nextjs.org/docs/messages/page-without-valid-component](https://nextjs.org/docs/messages/page-without-valid-component)

### なぜこのエラーが起きるか

- ビルド出力の分析中に、有効なReact Componentをexportしていないページが見つかった。
- これは、ページがレンダリングされたときにエラーになるため、ハードエラーであり、ビルドのパフォーマンスを低下させる。

### 対処法

- exportではなく、React Componentでexport defaultを使用していることを確認する。
- 既にexport defaultを使用している場合は、返される値が有効なReact Componentであることを確認する。
PythonのインストールをHomebrewからpyenvにする


# 概要
気付いたら動かなくなっていたので、ついでにPythonのインストール方法を変更した際のメモです。

**最終更新日**
2021年12月11日

**環境**
macOS Catalina 10.15.7
anyenv インストール済み

# Homebrewからアンインストール

```
% brew uninstall python
Error: Refusing to uninstall /usr/local/Cellar/python@3.9/3.9.9
because it is required by cairo, fontforge, glib, gobject-introspection, harfbuzz and pango, which are currently installed.
```

依存モジュールもアンインストールします。
アンインストールしようとすると、他のモジュールに利用されていて同じエラーが出るので、エラーのでない物を探して末端のものから順番にしていきます。

```
% brew uninstall fontforge
% brew uninstall pango
% brew uninstall harfbuzz
% brew uninstall gobject-introspection
% brew uninstall cairo
% brew uninstall glib
% brew uninstall python
```
# anyenvからpyenvをインストール

```
% anyenv install pyenv
...省略
Install pyenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```
ターミナルを再起動します。
pyenvが動くか確認します。

```
% pyenv install -l
Available versions:
  2.1.3
  2.2.3
... 省略
```

# pyenvからPythonをインストール

初期化しておきます。

```
% eval "$(pyenv init -)" 
```

この時は3.10.1が最新だったので、3.10.1を入れます。

```
% pyenv install 3.10.1
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.10.1.tar.xz...
... 省略
```

インストールできたか確認します。

```
% pyenv versions
* system (set by /Users/****/.anyenv/envs/pyenv/version)
  3.10.1
```

利用バージョンを指定します。

```
% pyenv global 3.10.1 
```

できたか確認します。

```
% python --version
Python 3.10.1
```

無事にできました。

# おまけ
percolを入れ直し。

```
% sudo pip install percol
```
node-red-contrib-firebase-adminを設定してRealtime Databaseを使う

[node-red-contrib-firebase-admin](https://flows.nodered.org/node/node-red-contrib-firebase-admin)のクレデンシャルを設定して、FirebaseのRealtime Databaseをenebularで使ってみます。

# 作成例

![image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/79447c85-0434-7026-feaf-e1d421e16236.png)


# 用意するもの

- Firebase
    - プロジェクトが作成済みであること
    - Realtime Databaseが作成済みであること（開始モードはテスト、ロックどちらでも可）
- enebular
    - プロジェクトが作成済みであること

# 手順

## Firebase

### サービス アカウント用の秘密鍵ファイルを生成する

**すでに秘密鍵ファイルを生成して所有しているならば、この手順はスキップできます。**

1. Firebase コンソールで、[設定] > [サービス アカウント] を開きます。
1. [新しい秘密鍵の生成] をクリックし、[キーを生成] をクリックして確定します。
1. キーを含む JSON ファイルを安全に保管します。

#### image-1

![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/5d2c5887-0b9a-72db-de8d-cc808f38ec94.png)


## enebular

### node-red-contrib-firebase-adminをインストールする

1. 編集したいフローを開きます。
1. [パレットの管理] > [ノードを追加] で `node-red-contrib-firebase-admin` を検索して、インストールします。

#### image-2

![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/cb711328-1a2e-33f2-d53a-798f2a4ddbb0.png)



### 新規に firebase-config を追加する

1. パレットの`rtdb get` ノードをワークスペースに配置します。
1. `rtdb get` ノードをダブルクリックして、ノードを編集します。
1. [Credentials] の鉛筆アイコンを、`新規に firebase-config を追加` の状態でクリックして設定画面を開きます。
1. [image-1](#image-1)で取得したクレデンシャルを入力します。
    1. [Firebase Service Account Credentials] にJSONファイルの内容を丸ごと貼り付けます。
    1. [Firebase Database URL] に `databaseURL` を貼り付けます。
1. [追加]ボタンをクリックして保存します。

#### image-3

![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/5ba666a4-bfa1-ca55-d5d5-49e711382e03.png)


### Realtime Databaseのデータを取得する

まずダミーデータとして、Realtime Databaseに以下のような適当な値を保存しておきます。

```
{
  "parent": {
    "child1: "happy"
  }
}
```

1. `inject` ノードのpayloadにJSON形式で、`{"path":"parent"}` と入力します。
1. `inject` ノードと`rtdb get` ノードをつなげます。
1. フローを保存します。

取得できました :tada:
Vueのコンポーネントパターン

この記事は ユニークビジョン株式会社 Advent Calendar 2021 11日目の記事です。

今回は社内でよく使われるVueコンポーネントを切り分けるパターンについて説明します。

最終的には一つの責務にまとまるようにコンポーネントを分けます。
以下に上げるのはその責務の分ける一種の基準になると考えてください。

コンポーネントをどう分けるか判断に迷ったときの手助けになればと思います。

# スタイルコンポーネント
スタイルを提供するコンポーネントです。
`border`や`color`等見た目に関わる要素を持たせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/cf304148-71f1-4dec-3f61-e43d7aaab6f1.png)


# レイアウトコンポーネント
レイアウトを提供するコンポーネントです。
`flex`の設定や`margin`等レイアウトに関わる要素を持たせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/9a9e0736-95cd-8ebb-426e-f3fdbe25a1e6.png)

```vue
<!-- 以下に上げるclassはtailwindcssに準拠します -->
<template>
  <div class="flex flex-col items-start">
    <div class="w-full">
      <slot name="header" />
    </div>
    <div class="w-full">
      <slot name="content" />
    </div>
  </div>
</template>
```

# 機能コンポーネント
機能を提供するコンポーネントです。
動きや制御に関わる要素を持たせます。
これはスクリプトのみの記述で完結する事があるので、Vue3ではComposition APIを使えばコンポーネントを作る必要すら無いかもしれません。

```typescript
function useRequestButton(action: () => Promise<void>) {
  const disabled = ref(false);

  async function onClick() {
    try {
      disabled.value = true;
      await action();
    } finally {
      disabled.value = false;
    }
  }

  return {
    disabled,
    onClick,
  };
}
```

# 単一フィールド入力コンポーネント
特定の項目専用に作られた入力コンポーネントです。
選択リストのような入力項目は項目ごとに表示名、順序、値の要素を持つため専用のコンポーネントに切り出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/cdf02a7b-3ae8-a2bd-858f-43fd3ff9fc44.png)

# 表示コンポーネント
シンプルな表示処理を行うコンポーネント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/dcdc0940-cf31-886d-aa5f-67654a22efc5.png)


# 入力フォームコンポーネント
入力フォームとなるコンポーネント
新規登録、編集画面等で使います。
新規登録、編集では同じ項目を要求することが多いので、基本的にどちらでも使えるようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/aa4253d7-f1c0-a73d-7317-bec768d01075.png)


# 表示切り替えコンポーネント
条件により表示するコンポーネントを切り替えるコンポーネント
例えば参照モード、編集モードと切り替えを実現するときに利用します。

```vue
<template>
  <ComponentA v-if="type==='a'" />
  <ComponentB v-else-if="type==='b'" />
  <ComponentC v-else-if="type==='c'" />
</template>
```

# リストアイテムコンポーネント
`v-for`で繰り返すコンポーネントです。
テーブルの１行等がこれに当たります。
表示するデータが多くなるとコンポーネントを切り出さないと管理が大変になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531073/d3b5cd4a-69e3-5373-7b34-ad6eada5a536.png)

# Organismsコンポーネント
Atomicデザインから名前を借りました。
ある程度のまとまりを持ったコンポーネントです。
画面のデザインからある程度まとまっていると感じる要素をまとめます。

# ページコンポーネント
ページの大元になるコンポーネントです。
Routerに登録するのはこのコンポーネントです。
最終的にはここにすべてが集約されます。
かどうかを判定する手順の使い方

　プロデルの手順は原則として動詞で書かねばならないが，これがかえって不便なこともある。例えば，何かの状態を確認する際に，

```プロデル
もし○○が××であるか確認したものが○なら
・・・
もし終わり
```

などと書くのはくどい。
　そこで用意されているのが，`かどうかを判定する手順`である。

## かどうかを判定する手順の呼び出し方

```プロデル
山かどうかを判定する手順
	○を返す
終わり
```

　このような手順を作成し，いくつかの呼び出し方を試した。

```プロデル
山を報告			ーーOK
山かを報告			ーーOK
山かどうかを報告	ーーOK
山かどうかを判定したものを報告	ーーエラー
山ぶどうを報告		ーーOK
```

　シンタックスハイライトを見るに，「山」が手順名であり，送り仮名は自由なので，その後ろのひらがなは何でもありなのだと思われる。4番目がエラーなのは，「山かどうか」でもう結果が返ってきてしまい，それを更に「判定する」手順に入れようとしているためである（言うまでもなくこの書き方をすることはないのだが）。

　なお，`かどうかを判定する手順`も通常通り実補語を取れる。

```プロデル
「町田市」が，「東京都」に，あるかを表示

［市町村］が，［都道府県］に，あるかどうかを判定する手順
・・・
終わり
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/09c55cc9-4f39-ccf2-0bab-1b6317b60ca3.png)
入力ダイアログの選択肢をExcelで管理する

#はじめに

仕事で選択肢をエクセルにて管理することがあったので、
とても自分のやりたかったことにマッチした記事が見つかったので、その記事を見ながら実際に作ってみました。

#　これで何がどうなるのか
Excelで選択肢や情報を管理できることにより、
入力ダイアログを書き直したりせず、情報の閲覧、管理が容易になります。

#参考文献

こちらの記事の内容を自分なりに実践しました。
とても勉強になりました。ありがとうございます。

 https://jsdg.org/blog/rpa013/

#実際にやってみた

##Excelを準備する

今回は、こんなのを用意しました。（ブック名：果物表）

選択肢リンゴ・バナナ・オレンジから選んで、
その果物の持っている情報を出力してみます。


シート「果物一覧」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/335ac52a-1805-d833-766d-90986a015d80.png)

##ワークフローを作る
ワークフローを作ってみました。
こんな感じになりました。

※Excelアプリケーションスコープ内でファイルを読み込むなどの部分は省略しています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/c8cb3826-a208-57b8-c45c-fe9569fa6780.png)

##　ワークフロー内の説明
### DTの各行をコレクションに追加
Excelから読み込んだデータテーブルの中身である果物の「名前」をコレクションに追加、変数名を「果物名」としています。（プロパティ下記画像参照）
ここで、入力ダイアログ表示時の選択肢を作っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/b71971dd-49dc-1823-49c2-5d396edc96e5.png)

### 入力ダイアログ
先ほど追加していたコレクション「果物名」をString型の配列に変換することによって、
選択肢として使用しています。
このダイアログで選択した結果は、変数「果物選択結果」に格納しています。
（プロパティ下記画像参照）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/0041cffd-2861-37e6-a474-d2ebf3b559f4.png)

###　代入
しれっと代入とシンプルな名前にしていますが、ここが一番の要です。
果物一覧DTから果物の「名前」でSelectした結果を変数名「果物一覧」という
DTに格納しています。
実際の式がこちらです。

```
果物一覧DT.Select("名前 = '" + 果物選択結果 + "'").CopyToDataTable
```

恥ずかしい話ですが、ここの`や”の抜けが多くて想定通りの結果とならず大変苦労しました…

###　データテーブルを出力・1行を書き込み

Selectした結果を出力しているだけなので、説明は省略します。

#　実際に動かしてみる

1.今回はリンゴを選択します。選択後、OK押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/e97d1a2b-d276-7888-2406-d58c6308d669.png)

2．選択した果物の情報が出力されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/86b944ee-1e22-eada-2e87-8f2c06fefaec.png)

#　選択肢を増やしてもちゃんと動くか

追加要素として、メロンを追加してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/c1aabe74-eb37-3520-c67d-f310d2f7c8e3.png)

選択肢が4つになったので、ラジオボタン方式からプルダウン形式になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/d1e6628d-a731-6db9-e3c8-c7b0494977e4.png)

もちろん選択できますし…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/67a73b61-8728-907f-8e63-1d9d14375d50.png)

ばっちり、情報も取得できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/e10cb00b-9cc8-176e-c59e-0551d4abd7c9.png)


# おわりに

構成ややりたいこと自体は単純ですが、それを実現するまでにかなり時間がかかったなと思いました。かけた時間を無駄にしないためにも、こうして調べた結果を自分の言葉で整理、記録として残すことは成長にとても大切だと痛感しました。
[Datadog] 本番サイトに手を入れずにRUMを試す方法

Datadog Advent Calendar 1日目で紹介されていましたとおり、RUM(Real User Monitoring)のSession Replayという機能が正式公開されています。

https://qiita.com/ykmori/items/4c071d5371cf021e67c2#session-replay

見ていただいた方が早いと思います。こんな感じです。2倍速再生にしているので忙しいです。
![2021-12-11_13-43-45.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325973/06ef2b86-1ea1-50da-acc6-c3c1c6443766.gif)
ユーザーがブラウザ上でWebサイトをナビゲートする様子が、動画のように再現されています。実際に動画で記録しているわけではなく、表示しているページの要素や遷移、マウスの操作などが記録されていて、それがDatadogに送られてDatadog側で再現されています。

RUMとはReal User Monitoringの略で、UXモニタリングというカテゴリーに入る監視です。サービス提供者が直接手の届かないユーザーの環境でのWebサイトの状況が観測できるという点で、最近とても関心を集めているように思います。イメージとしては、ブラウザの開発者ツールで見られる情報の一部をDatadogに送るようなイメージです。上記のWikipediaのトップページのロードの状況は以下のように見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325973/d110942d-64a5-50df-ed89-ea8a035f226e.png)
ページを構成する要素をダウンロードするのにどのくらいの時間がかかっているかが分かり、ユーザー体験の良し悪しが[Core Web Vitals](https://developers-jp.googleblog.com/2020/05/web-vitals.html)で示されています。このように様々な環境からアクセスしているユーザーがどのようなパフォーマンスでサイトを見ているのかが定量的に観測できます。

具体的な仕組みとしては、各WebページでDatadog提供のJavaScriptを読み込んで、RUMを起動し、データを収集して、各ブラウザから直接Datadogに送るようになっています。同様の手法を使っているツールとしてはGoogle Analyticsが有名ですが、Google Analyticsがマーケティングやキャンペーンの実施に特化しているのに対し、DatadogのRUMはWebページのパフォーマンスやエラーの解析に重点を置いていると考えて良いかと思います。

では、いざ試してみようという段階になると、WebページにRUMを組み込んでいく必要があります。ですが、テスト環境ならまだしも本番環境にいきなり入れるということにはならないかと思います。そこで、まずはRUMやSession Replayがどんなもので、何が見られて、何がわかるのかといったことを最短で体感していただくために、Chromeの拡張をご用意しました。この拡張によりWebページにDatadogのRUMのJavaScriptが差し込まれて、そのブラウザからのアクセスだけRUMが有効になります。これを使って上のGIFアニメのように、本番サイトに変更を加えることなくRUMを試すことができます。なお、これはDatadogが提供するものではなく、筆者個人で作成公開しているものです。

https://github.com/shigeya-dd/rum-chrome-extension

こちらがChrome拡張のレポジトリで、開発者モードで読み込むようになっています。実質数行のファイルが2つだけという簡素な内容ですので、何をやっているかは分かりやすいかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325973/10e07eb7-c312-e763-2e5d-2215ac59ffc3.png)
ぜひみなさんの本番サイトでもRUMを試してみてください。
なお、同僚氏がこのChrome拡張を進化させてChrome Web Store版の開発に取り組んでいますので、そちらもぜひお楽しみに。

ところで、Session Replayのようにユーザーの操作や画面が全部見えてしまって大丈夫だろうか？という懸念が出てくると思いますが、デフォルトでは、ユーザーのフィールドへの入力文字列をマスクするモードになっています。一番厳しいモードでは文字を全てマスクするようになっていますので、適切なプライバシー設定が可能になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325973/ddfcf87f-5dbd-8f9d-605e-208075afbe2a.png)
以上Datadog RUMを本番サイトに手を入れずに試す方法をご紹介しました。
Happy Datadogging!
ユニークインデックスとユニーク制約の違い

この記事によると、基本的に同じものみたい。

> Under the hood a unique constraint is implemented the same way as a unique index - an index is needed to efficiently fulfill the requirement to enforce the constraint. Even if the index is created as a result of a UNIQUE constraint, the query planner can use it like any other index if it sees it as the best way to approach a given query.

> *https://dba.stackexchange.com/a/147*
Unityのプロジェクト管理：すいのゲームを作ろう（第3回）

Unityでゲーム作る前に私がどんな風にプロジェクトを管理しているのかを説明します。

#Utniyのプロジェクト
![スクリーンショット 2021-12-11 135411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/f0859b41-b6d7-8d78-1b30-c7d0ccbaf130.png)
私がゲーム作り始める時は図のようにゲーム制作用のテンプレを作っているのでそれを利用しています。UnityProjectにはUnityでのファイルを保存しています。素材はゲームで使用する素材を、AdobeにはPhotoshopやillustratorのプロジェクトを入れています。Clipstudioもクリスタのプロジェクトを入れています。BuildはUnityで作成したゲームのビルド先をここに指定しています。Game情報はGooglePlayで登録するための情報を管理しています。クラス図はプログラム作成の時にクラス図を書くことで全体のコードのバランスを考えています。ゲーム仕様書はこのゲームは誰に向けているものなのか、テーマは、どこが面白いのか、ゲームの企画となっています。第2回であったゲームの進捗もここで管理しています。

#素材の管理
![スクリーンショット 2021-12-11 140438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/e36ede23-008e-c659-a7b7-8b22b68dc205.png)
素材の管理はこんな感じです。AndroidDevはストアにあげるときに宣伝用と登録用に使用する素材をいれておきます。Iconはアプリのアイコンです。Imageはゲームで使用する2D画像はすべてここです。Modelは3d用です。AudioはBGMとSE。Fontはフォントですね。ただフォントはしっかりと管理すべきだと思っています。Fontが無料で使えるものなのか、そしてどういう形なのか管理するのが複雑になりがちです。私はエクセルに一覧を作って、このゲームでは使っているかをどうかを管理しています。

#バージョン管理
https://www.sourcetreeapp.com/
バージョン管理についてはソースツリーというソフトを使用しています。主にプログラムソースの管理をこのソフトで行っています。同じような機能を持つソフトは他にもあると思いますので自分に合ったものを使うのが良いと思います。

#Unityのプロジェクト
Unityのプロジェクトテンプレ作成し、それを利用しています。ファイル構成には諸説あると思いますが私の例を紹介します。
![スクリーンショット 2021-12-11 141557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/daf37581-8eb7-bc55-9a12-931d05b6e369.png)
一番上の階層はシンプルです。Projectに自分のファイルを入れていきます。
![スクリーンショット 2021-12-11 142128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/f783408d-146b-d335-6364-621be717bf0e.png)
Project内は細かく素材ごとにフォルダ分けして管理しています。SceneついてはSceneファイルを入れいています。そのほかは名前の通りに管理しています。

#Scriptの管理
![スクリーンショット 2021-12-11 141717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/32b4bdc5-ebae-7227-127d-bf1c5a4cddfd.png)
ソースについてはこのように管理しています。基本的にSceneごとに使用するScriptを分けて管理するようにしています。どんなゲームでもタイトルと遊ぶ（Game）シーンは存在するのでテンプレで作ってあります。シーンが増える際はOtherSceneをコピーして増やしていきます。
BaseUtilはこのゲームだけではないすべてのゲームで利用できるようなシステムをここで管理しています。Testはテスト用のScriptを入れていきます。
ここで注意しているのはシーンのファルダに入れるScriptはBaseUtilを継承し、独立していることです。TitleSceneにあるシステムをGameSceneで使うことはないようにしています。プログラムをやっている人は当然だと思いますが、自分のルールとして必ず守っています。
Run DynamoDB Local on docker-compose.yml or Earthfile.

# DynamoDB Local
## On docker-compose.yml
```yml
version: "3.9"
services:
  dynamodb:
    image: amazon/dynamodb-local:1.17.1
    ports:
      - 8000:8000
    command: -jar DynamoDBLocal.jar -dbPath /data -sharedDb 
    volumes:
      - $PWD/data:/data
```

## On Earthfile
### [What is Earthly?](https://earthly.dev/)
[Earthly is often used by elixir library development](https://github.com/elixir-ecto/ecto_sql/blob/master/Earthfile)

```makefile
db:
    ARG DYNAMODB_VER="1.17.1"
    LOCALLY
    VOLUME "$PWD/data:/data"
    WITH DOCKER \
        --pull "amazon/dynamodb-local:$DYNAMODB_VER"
        RUN set -e; \
            timeout=$(expr $(date +%s) + 30); \
            docker run -v $(pwd)/data:/data --name dynamodb -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -dbPath /data -sharedDb;
    END
```
真偽値と文字列の足し算

　他の言語でもよくある，`""`がTrueなのかFalseなのか，という問題と，Perlがやってくれる`'100個'+50==150`ができるかを調べた。

## 結論

　「無」は×になる。「あ」＋「い」は0になる。

|式|結果|
|---|---|
|無|×|
|「無」|×|
|「」|×|
|「○」|○|
|「×」|×|
|0|×|
|0.0|×|
|「0」|×|
|「0.0」|×|
|真|○|
|偽|×|
|「真」|○|
|「偽」|×|

|式|結果|型情報を取得したもの|
|---|---|---|
|1|1|整数|
|1＋「あ」|1|倍浮動小数|
|1＋「1」|2|倍浮動小数|
|「1」＋「1」|2|倍浮動小数|
|「あ」＋「い」|0|倍浮動小数|
|「1個」＋「1本」|0|倍浮動小数|

## コード

```プロデル
もし無なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「無」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「○」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「×」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「0」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「0.0」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし0なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし0.0なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし真なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし偽なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「真」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
もし「偽」なら
	「真」を報告
でないなら
	「偽」を報告
もし終わり
［1］から型情報を取得したものを報告。
1を報告
［1+「あ」］から型情報を取得したものを報告。
1+「あ」を報告
［1+「1」］から型情報を取得したものを報告。
1＋「1」を報告
［「1」＋「1」］から型情報を取得したものを報告。
「1」＋「1」を報告
［「あ」＋「い」］から型情報を取得したものを報告。
「あ」＋「い」を報告
［「1個」＋「1本」］から型情報を取得したものを報告。
「1個」＋「1本」を報告
```
useEffectってなんじゃらホイ

#はじめに

Next.jsのコーディングをしていて、useEffectの動きが今ひとつ分かりませんでした。
そこで、テストプログラムにログを仕込んで、動きを確認してみました。


#useEffectとは

・初回表示時に必ず呼ばれる
・useStateが更新されるたびに呼ばれる
・引数を指定しないと、（ファイル内の？）全てのuseStateが更新される毎にCallされる
・第二引数で、useStateを指定できる。指定したuseStateが更新された時だけ、useEffectが呼ばれる

#Callされる順番

例えば、以下のソースコードを実行するとき

```JavaScript
import * as React from 'react';
import {useState, useEffect} from 'react';

export default function Test(){

    console.log("Test() Called");

    useEffect(() =>{
        console.log("useEffect called!!");
    });

    return(
        <>
            {console.log("return called")}
        </>
    )
}
```
初回表示時、

①Test()

②return

③useEffect

の順に表示される。

#useStateを絡めた順序

次に、useStateを絡めた以下のソースコードを実行するとき

```JavaScript
import * as React from 'react';
import {useState, useEffect} from 'react';


let count = 0;
export default function Test(){

    console.log("Test() Called");

    const [add, setAdd]     = useState(0);   //たし算用

    const changeAdd = (e) => {
        count++;
        setAdd(() => count);
    }

    useEffect(() =>{
        console.log("useEffect called!!");
    });

    return(
        <>
            {console.log("return called")}
            <button type="button" onClick = {changeAdd} label={"PiroPiro"} >たし算</button>
        </>
    )
}
```


useStateを更新すると、再び

①Test()

②return

③useEffect

の順にCallされる。

その後、値に変化があれば
再び①〜③の順にCallされる。

もし、値に変化がなければ

④Test()

⑤return()

の順にCallされ、その後はボタンを押しても何も呼ばれなくなる。


#useEffectの引数

・第１引数には、関数を指定

・第２引数に設定した値によって、挙動が変わる

以下のソースコードで確認

```javascript
import * as React from 'react';
import {useState, useEffect} from 'react';


let count = 0;
export default function Test(){

    console.log("Test() Called");

    const [add, setAdd]     = useState(0);   //たし算用
    const [mult, setMult]   = useState(0);   //かけ算用

    //たし算する関数
    const changeAdd = (e) => {
        count++;
        setAdd(() => count);
    }

    //かけ算する関数
    const changeMulti = (e) => {
        count *= 2;
        setMult(() => count);
    }

    useEffect(() =>{
        console.log("初回のみuseEffect called!!");
    },[]);

    useEffect(() =>{
        console.log("どんなときもuseEffect called!!");
    });

    useEffect(() =>{
        console.log("たし算時のみuseEffect called!!");
    },[add]);

    useEffect(() =>{
        console.log("かけ算時のみuseEffect called!!");
    },[mult]);

    return(
        <>
            {console.log("return called")}
            <p>たし算の計算結果は{add}です</p>
            <p>かけ算の計算結果は{mult}です</p>
            <button type="button" onClick = {changeAdd} label={"PiroPiro"} >たし算</button>
            <button type="button" onClick = {changeMulti} label={"PiroPiro"}>かけ算</button>
        </>
    )
}

```

###第２引数について

・指定しない場合・・・全てのuseStateの更新状態を見て、変化があれば第一引数の関数をCall
・[　]を指定した場合・・・初回のみCall
・useStateの値を指定した場合・・・指定したuseStateの値が変化した場合のみ、Callされる。


以上です。
間違いや気づいた点などありましたら、コメントいただけますと助かります！！
p5.jsの関数まとめ part.10 sin()

この記事は Qiita p5js アドベントカレンダー11日目の記事です。

## これはなに
p5.jsが用意している関数について理解を深める記事です。
今回は三角関数のsin()について。

## sin()
三角関数のsin()です。sin, cos, tanのsinです。懐かしい。
渡された角度のsinθを計算して出力するというものです。
これを利用することで周期を利用した表現が可能となります。

### リファレンスより
> 角度のサインを計算します。この関数は、現在の angleMode を考慮します。値は -1 から 1 の範囲で返されます。（DeepL翻訳）

sin()では角度(angle)を引数に渡すのですが、**angleMode**というものがあるのを知りました。
リファレンスをみてみると`RADIANS`と`DEGREES`の二つがあるようです。
これは`ラジアン(弧度法)`と`度(度数法)`の違いみたいで、例えば360度はラジアンに直すと6.28...となります。
setup()内で使いやすい方を選択しましょう。

### Type
```typescript
sin(angle: number): number;
```
引数

 - angle sinθを計算するための角度

### よく分からないのでリファレンスのコードをみる
sin()の仕組みが全然分からないのでリファレンスのサンプルコードを読み解いていくことにします。

```javascript
let a = 0.0;
let inc = TWO_PI / 25.0;
for (let i = 0; i < 25; i++) {
  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);
  a = a + inc;
}
```

実行結果
![スクリーンショット 2021-12-11 2.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/a14e524b-6611-ee86-cff4-ca8024a1f0ec.png)


まずsin()の引数`angle`となる変数`a`を定義しています。

```javascript
let a = 0.0;
```

続いて`inc`という変数を定義しています。
多分incはincremental（増加分）の略。

```javascript
let inc = TWO_PI / 25.0;
```
さて、`TWO_PI`がよく分からないのでリファレンスを読みます。
> TWO_PIは、値が6.28318530717958647693の数学定数です。これは、円の円周とその直径の比率の2倍です。これは、三角関数sin（）およびcos（）と組み合わせて使用すると便利です。

ということでこれは円周率(3.14....)の２倍の数であるということが分かりました。
つまり度数法に直せば0~360°の一周期分、そしてそれを25等分しているのが分かります。

次にfor文が入ります。
25回繰り返しているのは周期を25等分しているので、その数だけline()を実行するためです。
なんとなく25は定数化してほしい。

```javascript
for (let i = 0; i < 25; i++) {
  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);
  a = a + inc;
}
```

for内のline()からみていきましょう。

```javascript
line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);
```

まずx座標をみると、x1, x2共に変数`i`に`4`をかけた値が渡されています。
この`4`という数字は線の隙間をいい感じに空けるためにあると思われます。

次はy座標。y1は`50`ですがy2は`sin(a) * 40.0)`という数式が渡されています。
sinは`-1`から`1`の間で値が返るので、`* 40`でy座標を調節しているのもポイント。

では`sin(a) * 40`がどんな数値になっているのかをコンソールに出力してみましょう。
なお一度通るごとに`a = a + inc`で`a`に1周期を25等分した度数が足されていきます。

```javascript
for (let i = 0; i < 25; i++) {
  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);
  a = a + inc;
  // コンソールに出力
  console.log(`${i + 1}回目: ${sin(a) * 40.0}`)
}
```
出力結果がこちら

```console
1回目: 9.947595486594192 
2回目: 19.270146964068612 
3回目: 27.38188423714755 
4回目: 33.773117020080605 
5回目: 38.04226065180614 
6回目: 39.921069137130864 
7回目: 39.291490029147546 
8回目: 36.19308209864079 
9回目: 30.82052971103158 
10回目: 23.51141009169894 
11回目: 14.724982107387142 
12回目: 5.013329342572199 
13回目: -5.013329342572137 
14回目: -14.724982107387083 
15回目: -23.51141009169889 
16回目: -30.820529711031554 
17回目: -36.19308209864077 
18回目: -39.291490029147546 
19回目: -39.921069137130864 
20回目: -38.04226065180613 
21回目: -33.77311702008058 
22回目: -27.381884237147503 
23回目: -19.27014696406855 
24回目: -9.94759548659411 
25回目: 9.67842359708362e-14 
```
プラスからマイナスへ数値が緩やかな規則正しい波を描いていることが分かります。
このy座標をline()に当てることで、上記画像のような形がつくられているのですね。

## あとがき
いろいろ調べていたらsin()はcos()と併用して(x, y)を求めると表現の幅が広がることが分かってきました。
ですが`TWO_PI`を組み合わせることによって1周期を作成している点など、数学的な知識を求められます。
一回この辺を勉強しなおそう...。

## 参考
[p5.js reference | sin()](https://p5js.org/reference/#/p5/sin)
[p5.js reference | angleMode()](https://p5js.org/reference/#/p5/angleMode)
M1 MacでTensorFlowをインストールする際の注意事項

M1 MacでTensorFlowをインストールする際の注意事項
--------

M1 MacでTensorFlowをインストールする場合、`tensorflow-macos`をpipに指定します。ただ、その場合HDF5関連のライブラリが見つからないというエラーになることがあります。

その場合は、以下のようにbrewでhdf5をインストールし、`HDF5_DIR`の環境変数を設定すると正常にインストールできます。

```
brew install hdf5@1.8
export HDF5_DIR=/opt/homebrew/Cellar/hdf5@1.8/1.8.22_2

pip install tensorflow-macos
```

tensorflow-macosのインストール時に`grpcio`のコンパイルでエラーになる場合は、以下で対応できるかもしれません。

```
export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1

pip install grpcio
```

# 参考文献

* https://github.com/grpc/grpc/issues/25082
金融系SIerからエンジニアになってみて

#新卒で入社した

私は新卒でシステム開発会社に入社して、金融系SIerとして2年半程勤務しておりました。現場に常駐するSESという形態で勤務しており、現場ではそれなりに評価されて、単価も上がりました。しかし、バックオフィスにて相対的に評価されるため、単純に勤続年数に応じた給与体制でした。

#現場を変えたかった

現場では、COBOLやPL-Iなどの言語を用いて、クレジットカードのオーソリシステム開発をしておりました。元々クレジットカードの仕組みや技術について興味があったため満足していましたが、エンジニアとして働いているからには、OSSを使用した現場にも行ってみたいと思いました。

#転職を考えた

私は新しい現場に行きたい旨を伝えましたが、良い返事をもらう事はできませんでした。当時私の単価は70万円だったのに対し、未経験のC言語やJavaの案件では、45万円程度になってしまうため厳しいと言われたのです。これはSESという形態では良くあることですが、当時の私は納得ができずに退職しました。

#何をしていいかわからなかった

退職したのは良いものの、コネも経験もなくて、何から始めて良いかわかりませんでした。参考書を買ってPHPやJavaを触ってみたのですが、そこから仕事に繋がるビジョンが全く浮かばないのです。そんな時に、ネットで調べて辿り着いたのがポテパンキャンプでした。

#ポテパンキャンプに入った

まずは入校前にPROGATEで基礎を勉強し、入校後はRailsを使用したアプリケーション開発を行いました。何をすればわからない状況で、独自のカリキュラムで道標をくれた事が何より良かったです。課題自体もきちんと理解していないと先に進めないので、かなり勉強になったと思います。

#これでWebエンジニアに...

私はポテパン課題はこなしたものの、ポートフォリオをまともに作っておらず、企業もかなり絞っていたので、転職活動は難航しました。ポテパン課題のクリアは通過点であり、卒業後に転職活動をするのも仕事をしていくのも自分だと言うことを改めて学びました。

#Webエンジニアになった

約2ヶ月間転職活動をして、内定を頂いた会社に転職しました。十数社受けて初めての内定だったので、本当に嬉しかったことを今でも覚えています。Webエンジニアになってから2年半が経ちました。2社ほど転職して、今はDtoCプラットフォームを提供する自社開発企業にいます。キャリアも年収も大幅にあがり、充実したエンジニアライフを送っています。

#エンジニアになろうとしてる方へ

私はWebエンジニアに転職をして、本当に良かったと思っています。これからエンジニアになろうとしてる方は、2つほど意識してもらいたいことがあります。まずは、スクールは通過点であって、最後は自分の力で内定をもらう必要があるということ。そして、エンジニアになった後も、努力を続けないとステップアップできないこと。当たり前のことですが、とても大事なことなので忘れないでください。

#結局ポテパンはいいの？

私が最初の転職で苦労したのは、自分の努力が足りなかっただけです。未経験でも努力をすれば必ず転職出来ますし、ポテパンは最後までちゃんとサポートしてくれました。課題のレベルも高く、現役エンジニアがコードレビューを行ってくれるので、未経験エンジニア転職なら間違いなくおすすめです。
NEDITの操作方法まとめ２

######　　　　以下は、ACOSの日本語エディタ（NEDIT)の操作方法を記載する自分のメモ２
##　　　　　　　はじめに

  __<font color="blue">　【ACOS（Advanced Comprehensive Operating System）】</font>とは__　日本電気（NEC）製のメインフレームという大型の汎用機のOSです。

#####　　このメモは、ACOSで使用する対話情報処理システム(ATSS)の日本語エディタ（NEDIT)のコマンドまとめです。

###○<font color="blue">行サブコマンド</font>（操作したい行の1桁目～6桁目に記載する）

#####・指定した1行をコピーして、サブバッファへコピーする
      KB

#####・指定した範囲の行をコピーして、サブバッファへコピーする
      KKB～KKB

#####・指定した1行を切り取って、サブバッファへ張り付ける
      MB

#####・指定した複数行を切り取って、サブバッファへ張り付ける
      MMB～MMB

#####・指定した行の下にサブバッファへから貼り付ける
      PB

###○<font color="blue">サブコマンド</font>（SCMD ==> に記載する）


#####・新しくエディタを開く
      *NEDIT

#####・新しくエディタを画面下半分に開く
      SPN 'ライブラリ（メンバー名）'

#####・アクティブになっている画面表示を終了する
      SPF

#####・操作できるエディタの画面を切り替える
      SW

#####・サブバッファの内容を書き込みできる
      SB

#####・サブバッファの書き込みを終了する
      E

#####・サブバッファを追加モードにする
      STN

#####・サブバッファを上書きモードにする
      STF


##　　　　　　NEDITの操作方法まとめ１
　　　https://qiita.com/nano357/items/8db907fb6106000865d8
yarnでnuxtプロジェクト作成を実行すると失敗する

## 環境
yarn：1.22.11
mac：M1

## create nuxt-appでプロジェクトの作成が失敗する
`yarn create nuxt-app nuxt`でプロジェクトを作成しようとすると、エラーが発生して失敗する。

プロジェクト作成時の選択

```
? Project name: nuxt
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git
```

発生したエラーがこちら。ぱっとみよく分からない。。

```
yarn install v1.22.11
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

/Users/hogehoge/.config/yarn/global/node_modules/sao/lib/installPackages.js:108
throw new SAOError(`Failed to install ${packageName} in ${cwd}`)
^

SAOError: Failed to install packages in /Users/hogehoge/work/myapp/nuxt
at ChildProcess.<anonymous> (/Users/hogehoge/.config/yarn/global/node_modules/sao/lib/installPackages.js:108:15)
at ChildProcess.emit (node:events:378:20)
at maybeClose (node:internal/child_process:1067:16)
at Process.ChildProcess.\_handle.onexit (node:internal/child_process:301:5) {
\_\_sao: true
}
error Command failed.
Exit code: 1
Command: /usr/local/bin/create-nuxt-app
Arguments: nuxt
Directory: /Users/hogehoge/work/myapp/
Output:

```


## 解決策

使用していたnodeのバージョンを確認したところ、15系のバージョンを使用していたので、安定バージョンに切り替えて`yarn create nuxt-app nuxt`を実行したら正常にプロジェクト作成できました.

```
$ node -v
v15.11.0

$ nvm use v16.13.1  

$ node -v
v16.13.1

$ yarn create nuxt-app nuxt
create-nuxt-app v3.7.1
✨  Generating Nuxt.js project in nuxt
? Project name: nuxt
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git

🎉  Successfully created project nuxt

  To get started:

	cd nuxt
	yarn dev

  To build & start for production:

	cd nuxt
	yarn build
	yarn start

✨  Done in 54.93s.
```
[ServiceNow]Referenceのリンク集

最近、GlideRecordやGlideSystemのReferenceがグーグル検索したときに引っ掛からなくなっています。
developerサイトからいちいち探すのも不便なのでリンク集を作成しました。

これのリンクも欲しい等ありましたらコメントいただけたら追加します。

###リンク
GlideForm
[Tokyo](https://developer.servicenow.com/dev.do#!/reference/api/tokyo/client/c_GlideFormAPI)　[San Diego](https://developer.servicenow.com/dev.do#!/reference/api/sandiego/client/c_GlideFormAPI)　[Rome](https://developer.servicenow.com/dev.do#!/reference/api/rome/client/c_GlideFormAPI)

GlideSystem
[Tokyo](https://developer.servicenow.com/dev.do#!/reference/api/tokyo/server/no-namespace/c_GlideSystemScopedAPI)　[San Diego](https://developer.servicenow.com/dev.do#!/reference/api/sandiego/server/no-namespace/c_GlideSystemScopedAPI)　[Rome](https://developer.servicenow.com/dev.do#!/reference/api/rome/server/no-namespace/c_GlideSystemScopedAPI)

GlideRecord
[Tokyo](https://developer.servicenow.com/dev.do#!/reference/api/tokyo/server/no-namespace/c_GlideRecordScopedAPI)　[San Diego](https://developer.servicenow.com/dev.do#!/reference/api/sandiego/server/no-namespace/c_GlideRecordScopedAPI)　[Rome](https://developer.servicenow.com/dev.do#!/reference/api/rome/server/no-namespace/c_GlideRecordScopedAPI)
始めようゲーム制作：すいのゲームを作ろう（第2回）


#ゲーム流れ
さあ、ゲーム作りを始めよう！といいたいところですが、まずはゲーム作りの一連のやることリストを確認してみましょう。リストはエクセルにて管理しています。
![スクリーンショット 2021-12-11 130632.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/c67c9dcc-907e-b6a2-6d12-9a0753a810e8.png)
どれだけかかったを管理することで次回作を作る時、どれだけ時間が掛かるのかの目安となります。
ものによってかかる時間も様々ですが見ての通りやるこが多いですね。なによりもあきらめないことがゲーム作りで大切な要素だと思っています。

#ゲーム企画しよう
では実際にゲーム作りを始めましょう。まずはどんなゲームするかです。なんでもいいですが個人ゲーム開発なのでとにかく簡単につくれるものがいいです。自分が簡単に作れると思っているゲームでもいざ作ってみると簡単にはつくれないです。とにかく簡単に、簡単にを心がけます。まず作ってみて、作ったゲーム遊びながら面白い要素を足していくやり方がいいと思っています。

とりあえず今、私は英語に興味をもっています。なので英語に関係するゲームを作ろうと思います。英語のゲームを1から考えても良いと思いますが、おすすめはテーマが決まればそのテーマで検索して同じテーマのゲームを遊んでみることです。遊んでみて面白いところや、ゲームバランス、作風等学ぶべきところがたくさんみつかると思います。そのうえで自分のゲームを考えると良いでしょう。

その後、自分のアイディアを出して形にしていきます。最近だとIpadを利用し、始めのイメージを考えます。Conceptsというアプリは無限にキャンパスの大きさが広げることができるので、アイディアを出すには適しています。始めのイメージはこんな感じにしました。
![アップルランイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/ba17f1d1-b309-710b-a9df-1a3d08a6d428.jpeg)

リンゴが道を走っていって、Appleと書かれたテープや木を通りぬけるゲームになります。もしOrengeと書かれていたら下のボタンを押して走っている果物をきりかえます。果物と文字同じであれば通り抜けることができ異なっているとゲームオーバーとなります。単語と絵を様々用意することで、拡張性もありそうです。

#ゲームの手触り
ゲームでは手触りがとても大切です。手触りとは遊んでいて楽しいと感じる感覚です。例えばジャンプ一つにしてもそのジャンプがマリオのように空中で移動できるものなのか、それとも魔界村のように移動ができないものなのか、そしてそのジャンプの速さ、高さ、様々な要素で成り立っています。その中で楽しいと感じる感覚を選ばなければなりません。

人は快感を感じる感覚があります。イージングのなかでもeaseInOutExpoやeaseoutCircといった、あるしきい値を超えた時に勢いよく変化するものに快感を感じます。身近の物でボタンのクリック感がそれにあたります。
特にアクションゲームはそういう細かい部分の調整がされているので自分で研究して見ると面白いと思います。
今回の私のゲームでも、文字が書いてあるラインを通り抜けるときにプチンとちぎれるのような感覚を表現出来たら楽しいのではないかと考えました。
nodebrewのインストール方法

## 最初に打つコマンド
```
$ curl -L git.io/nodebrew | perl - setup
```

## .bash_profileにパスを通すために設定を記述する。
```
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```

## .bash_profileの変更を適用させる。
```
$ source ~/.bash_profile
```

## nodebrewがインストールされているのか確認する。
```
$ nodebrew help
nodebrew 1.1.0

Usage:
    nodebrew help                         Show this message
    nodebrew install <version>            Download and install <version> (from binary)
    nodebrew compile <version>            Download and install <version> (from source)
    nodebrew install-binary <version>     Alias of `install` (For backward compatibility)
    nodebrew uninstall <version>          Uninstall <version>
    nodebrew use <version>                Use <version>
    nodebrew list                         List installed versions
    nodebrew ls                           Alias for `list`
    nodebrew ls-remote                    List remote versions
    nodebrew ls-all                       List remote and installed versions
    nodebrew alias <key> <value>          Set alias
    nodebrew unalias <key>                Remove alias
    nodebrew clean <version> | all        Remove source file
    nodebrew selfupdate                   Update nodebrew
    nodebrew migrate-package <version>    Install global NPM packages contained in <version> to current version
    nodebrew exec <version> -- <command>  Execute <command> using specified <version>

Example:
    # install
    nodebrew install v8.9.4

    # use a specific version number
    nodebrew use v8.9.4
```

このようにnodebrewに関するコマンドが一覧で表示されていれば正常にnodebrewがインストールされている。
ラズパイにRTCを追加する

センサーからデータを収集してデータを記録するときに日時と一緒に記録するとお思います。
自分も色々とセンサーを繋げて遊んでいるのですが、必ずネットワークに接続されている環境とは限りません。
ラズパイの場合、RTCを内蔵していないのでネットワークに接続していないと正確な時刻を使うには、起動後に手動で毎回設定する必要があります。
それは、面倒なのでラズパイに接続できるRTCを買ってきました。
ラズパイの電源が入っていない状態でも電池を使って日時をカウントしています。

# 今回購入したRTCモジュール

今回は、Seeed Studioの２種類のモジュールを購入しました。
１つはPi RTCという製品で、もう一つは高精度Pi RTCとなります。
両方とも電池はCR1225かCR1220を使います。
近所のスーパーにはCR1220しか売っていなかったので、今回はCR1220を使います。
CR1225とCR1220の違いは厚みが0.5mm違うそうです。
（CR1225の少し厚い）

|![スクリーンショット 2021-12-11 12.39.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/297c29f2-a6e9-459f-9dc5-99658901d817.png)|
|:-:|


### Pi RTC

https://www.seeedstudio.com/Pi-RTC-DS1307.html

### High Accuracy Pi RTC

https://www.seeedstudio.com/High-Accuracy-Pi-RTC-DS3231.html

### メーカーのドキュメント

https://github.com/Seeed-Studio/pi-hats/tree/master/RTC-HAT

# High Accuracy Pi RTCを接続

### ドライバの取得
```shell-session:
$ mkdir rtc
$ cd rtc
$  git clone https://github.com/Seeed-Studio/pi-hats.git
Cloning into 'pi-hats'...
remote: Enumerating objects: 394, done.
remote: Counting objects: 100% (135/135), done.
remote: Compressing objects: 100% (91/91), done.
remote: Total 394 (delta 66), reused 71 (delta 44), pack-reused 259
Receiving objects: 100% (394/394), 10.28 MiB | 2.71 MiB/s, done.
Resolving deltas: 100% (181/181), done.
```

### ドライバのインストール

```shell-session:
$ cd pi-hats/tools
$ sudo ./install.sh -u rtc_ds3231
Uninstall rtc_ds1307 ...
Uninstall rtc_ds3231 ...
Uninstall adc_ads1115 ...
Enable I2C interface ...
Install rtc_ds3231 ...
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージは「削除」されます:
  fake-hwclock
アップグレード: 0 個、新規インストール: 0 個、削除: 1 個、保留: 13 個。
この操作後に 32.8 kB のディスク容量が解放されます。
(データベースを読み込んでいます ... 現在 104235 個のファイルとディレクトリがインストールされています。)
fake-hwclock (0.11+rpt1) を削除しています ...
man-db (2.8.5-2) のトリガを処理しています ...
Synchronizing state of fake-hwclock.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable fake-hwclock
Unit /etc/systemd/system/fake-hwclock.service is masked, ignoring.
#######################################################
Reboot the system to take a effect of Install/Uninstall
#######################################################
```

### High Accuracy Pi RTCの接続

ドライバのインストールが完了したら、ラズパイをシャットダウンして、RTCのHATをつけて、起動します。

#### High Accuracy Pi RTCのピン配列

![スクリーンショット 2021-12-11 13.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/820e3981-3b37-9d07-4525-e21238a8c36a.png)

ラズパイのPINに合わせてHigh Accuracy Pi RTCを接続します。

![262996069_339511154211890_3993892213100881488_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/ffc3a018-0a4b-3185-48da-56aaa941a0ed.jpeg)


### 動作確認

インストールされているドライバの確認

```shell-session:
$ ./install.sh -l
rtc_ds1307    : not installed
rtc_ds3231    : installed
adc_ads1115   : not installed
```

ハードウェアクロックの表示

```shell-session:
$ sudo hwclock -r
2021-12-11 13:18:35.921227+09:00
```

ハードウェアクロックを使ってシステム時間を設定

```shell-session:
$ sudo hwclock -s
```

システム時間を使ってハードウェアクロックを設定

```shell-session:
sudo hwclock -w
```

ドライバのインストールスクリプトが全てやってくれるので、インストール自体は簡単に終わりました。
普通のPi RTCの方も同じように簡単に使える状態になると思います。
[Android]build.gradleに出てくる構文たち

##この記事は
Gradleについてのドキュメントは、Groovyの構文を理解している前提で、話が進んでいるので、おいおい！とずっと思ってました。
ここでは、そこの補完として役に立てば幸いです。

##解説
### plugins {}
Gradleの拡張機能は、ここで定義します。
Gradleは、色々なプラットフォームに対応するべく細かい部分はpluginを通じて補完するようになっています。
Androidでは、下記プラグインによりAndroid特有のビルドオプションを設定することを可能にしています。

```gradle
id("com.android.application")
```

### buildScript {}
このブロック内では、buildに関する諸々の設定を記述します。
ざっくりと「設定」と把握しておけば大丈夫そうです。

### repository {}
ここでは、依存関係に追加したライブラリ等の検索やダウンロードに用いるリポジトリを定義するブロックです。
代表的なのは、mavenCentral()やgoogle()ですね。

### android {}
Android固有のビルド設定をするブロックです。

### dependencies {}
ここでは、ビルドするときに使う依存関係を定義するブロックです。

### allProject {}
全てのモジュールで用いるrepositoryを設定するブロックです。

##参考
https://developer.android.com/studio/build?hl=ja
ユーザーを理解してプロダクトをつくるということ

これは [株式会社ACCESS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/access) 11 日目の記事です！
こんにちは、@yocidama です！今年も豚汁の美味しい季節になりましたね🐷

突然ですが、みなさんのつくっているプロダクトのユーザーってどんな人ですか？
今つくっているその機能、ターゲットユーザーにとって価値のあるものになっているでしょうか。

プロダクト作りにはユーザー理解が不可欠ですが、今でも「完全にユーザー理解したぜ…」という気持ちになれません。
そこで今回は、ユーザー理解への苦悩やユーザーとどう向き合っているかについて書きます。


## 「ユーザー視点」のユーザーって誰…？

ときどき「ユーザー視点でテストしてください」と言われることがありますが、"ユーザー視点で"のユーザーって誰？と思うことがあります。
わたしは、依頼されるプロダクトのユーザーじゃないことが多いので真の意味でユーザー視点でテストすることができません。
こんなときはどんな情報があればそのユーザーに近づけるかを考え、その情報集めをします。

#### ユーザー情報の集め方

##### 誰が使うのか

業種、性別、年代、家族構成、生活スタイル、どんなことで困っている人なのか…など様々な角度からユーザー情報を集めましょう。
たとえば 「60代女性スマホ操作に不慣れな人」が使うとすれば以下観点が気になってきます。

 - 文字サイズが小さすぎると見えないかも
 - わかりやすい文言になっているか、誤解を招く文言になっていないか
 - お問い合わせはわかりやすいところにあったほうがいいだろう
 

##### いつ、どこで、どんな時に使うのか

 - この機能はいつ使うのか、日中使うのか、夜間に使うのか。
 - 屋内で使うのか、屋外で使うのか。
 - 何してるときに使うのか。

などなど。


## ユーザーの気持ちを完全に理解することはできない

お問い合わせに寄せられるメールや、ストアのレビューコメント、アンケート結果などを読んだだけでうちのユーザーってこうだから〜と分かった感じになっていないか定期的に自分を戒めています。
それはユーザー自身も自分の環境を正しく把握できていないことがあるため、そのユーザーの書いた文章だけでは正確に伝わらないことがあるためです。
そんな時はたしからしいデータを見たり、それをチームに共有して異なる視点で見てもらうことが大切です。


### データ例

- ユーザーが使っている機種やOSバージョンの割合
    - 使っている機種の価格帯やメーカーのターゲット層から何かが見えることもある
- ユーザーが一番やっている操作
- 定期購入の契約数、解約数
    - 解約理由も書いてくれる場合がある
- 出した機能が使われているのか、離脱率はどうか

などなど。



## おまけ：受託開発におけるエンドユーザーの前の大きな壁、顧客

エンドユーザーにとってはどっちでもいいところだけど、顧客の気になるポイントがあったりします。
大抵、顧客指摘がきて修正しないといけなくなるので顧客が言ってきそうなポイントを抑えて指摘を防げるのであれば対策しておきたいところです。

#### 顧客情報の集め方

##### 直接やりとりしているPMや営業担当に聞く

「このお客様どういうところを気にされてますか？」とだけ聞けばいいです。

##### チャンスがあれば顧客とのミーティングに参加して直接観察する

こっちが早いです。顧客の顔を直接見たほうが自分の中の情報に彩りが増すのでお願いしてみましょう。


## さいごに

- ユーザーに直接会えない＆自分がターゲットユーザーじゃない場合、ユーザー情報を手当り次第集めて想像しましょう。
- 自分がターゲットユーザーでない場合はそのことを忘れないことが大事です。自分の意見 = ユーザーの意見になるとは限りません。
- ユーザーにとって何が一番大事なのかぶっちゃけプロダクトを出してみないとわからないことも多いです。早く使ってもらう→フィードバックをもらう→改善するのサイクルを回していくようにしましょう。

明日は @kiito1000 さんです！