OmniAICreator/Qiita-1.07M huggingface dataset:
【Environment modules】デフォルトで読み込むモジュールパスを設定する

# やりたいこと
コンパイラのスイッチング用途でよく使われているEnvironment modules[^1]ですが、新しくパッケージをインストールした際にはEnvironment modulesが認識できるようにモジュールファイルが格納されているディレクトリのパス(以下モジュールパス)を設定する必要があります。一般によく紹介されている方法としては`module use --append /path/to/modulefiles/dir`でモジュールパスを指定するというのがあります[^2]が、ユーザーごとに設定する手間を考えると、できれば採用したくはないところです。

本記事では、デフォルトで読み込むモジュールパスを設定する方法を紹介します。


# モジュールパスの追加方法
Environment modulesは、環境変数`$MODULEPATH`で指定されているディレクトリに存在するモジュールファイルを認識してくれます[^3]。ただし初期状態の場合には何も設定されていません。

```bash
user@pc:~$ echo $MODULEPATH
```

この時に`module avail`等のコマンドで認識できるのは、` /usr/share/modules/modulefiles`配下に置かれたモジュールファイルだけです。

```bash
user@pc:~$ module avail
-------------------------------------------- /usr/share/modules/modulefiles --------------------------------------------
dot  module-git  module-info  modules  null  use.own
```
したがって新規にモジュールファイルをデフォルトで認識させるためには、モジュールパスを環境変数`$MODULEPATH`に追加しなければなりません。環境変数$MODULEPATHのデフォルト値を設定する方法としては、`/etc/environment-modules`ディレクトリ配下の`modulespath`ファイルにモジュールパスを書き込むのが最もシンプルかなと思います。


ここでは例として、NVIDIA HPC SDKのモジュールパスを設定しています(NVIDIA HPC SDKの場合にはモジュールファイルが同梱されているので、今回はそのモジュールパスをそのまま設定しています)。
```bash
user@pc:/etc/environment-modules$ sudo vi modulepath
#  Modulepath initial setup
#  ========================
#
#  This file defines the initial setup for the module files search path.
#  Comments may be added anywhere, which begin on # and continue until the
#     end of the line
#  Each line containing a single path will be added to the MODULEPATH
#     environment variable. You may add as many as you want - just
#     limited by the maximum variable size of your shell.
#
#/usr/share/modules/versions                            # location of version files
#/usr/share/modules/$MODULE_VERSION/modulefiles # Module pkg modulefiles (if versioning)
#/usr/share/modules/modulefiles                         # General module files
/opt/nvidia/hpc_sdk/modulefiles
```
書き込み後に再度ログインし、環境変数`$MODULEPATH`が正しく設定されているか確認します。
下記のように書き込んだモジュールパスが表示されればOKです。
```bash
user@pc:~$ echo $MODULEPATH
/opt/nvidia/hpc_sdk/modulefiles
```
また`module avail`コマンドでモジュール一覧を表示すると、`/opt/nvidia/hpc_sdk/modulefiles`ディレクトリ直下のモジュールファイル群を正常に認識されていることが分かります。

```bash
user@pc:~$ module avail
------------------------------------------- /opt/nvidia/hpc_sdk/modulefiles --------------------------------------------
nvhpc-byo-compiler/23.1  nvhpc-hpcx/23.1  nvhpc-nompi/23.1  nvhpc/23.1

-------------------------------------------- /usr/share/modules/modulefiles --------------------------------------------
dot  module-git  module-info  modules  null  use.own
```

# まとめ
環境変数`$MODULEPATH`にモジュールパス追記することで、Environment modulesで当該ディレクトリを認識できるようになりました。

なお、デフォルトで参照されているディレクトリ` /usr/share/modules/modulefiles`にモジュールファイルを直置きする方法もありますが、この場合だと参照先のパッケージがアンインストールされた後もモジュールファイルが残ってしまうため、あまり宜しくありません。環境変数`$MODULEPATH`にモジュールパスを登録しておくのが無難かなと思います。

# 参考
[^1]: [Environment Modules](https://modules.readthedocs.io/en/latest/)
[^2]: [Environment modulesのインストール](https://qiita.com/Ag_smith/items/f268ad27165a60aecd35)
[^3]: [Environment Modulesについて](https://www.nabe-intl.co.jp/takeruboost/environment-modules%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)
【Unity】テキストを１文字ずつ表示する方法

Unityを使ったゲーム開発において、テキスト表示は重要な要素の一つです。
しかし、一度に全てのテキストを表示すると、プレイヤーにとって読みづらいので
１文字ずつ表示するコードのメモです。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextDisplay : MonoBehaviour
{
    public float displaySpeed = 0.1f; // １文字の表示速度

    private Text textComponent;
    private string displayText;

    void Start()
    {
        textComponent = GetComponent<Text>();
        displayText = textComponent.text;
        textComponent.text = ""; // テキストを初期化
        StartCoroutine(DisplayText());
    }

    IEnumerator DisplayText()
    {
        foreach (char c in displayText)
        {
            textComponent.text += c;
            yield return new WaitForSeconds(displaySpeed);
        }
    }
}

```
ABC295回答メモ

0.はじめに
　先週の好成績で浮かれてたら、一転今回はAとCしか解けずに
　またレートが下がりました。
　B問題が難しいというか面倒だったので飛ばしてDを頑張りましたが
　後から考えたら、そんなでもなかったなと思いました・・。

1.A - Probably English
　単語をリストに登録して、１ずつif文でチェックしていく
　素直な実装でACでした。

　https://atcoder.jp/contests/abc295/submissions/40024421

2.B - Bombs
　試験時は解けずに、解説を見ても実装が思い浮かびませんでした。
　翌日改めて考えて解説とは違う感じで実装しました。

　【考え方】
　　爆弾枠をリスト(威力・座標)に保持し、壁マスについて
　　全爆弾リスト明細について距離を求め威力以下かをチェック
　　威力以下の時、壁を空きマスに変更

　考え方を変えたら、すんなり実装できACでした。

　https://atcoder.jp/contests/abc295/submissions/40065809

3.C - Socks
　Bより難易度低めで10分もしないで解けました。
　いろいろやり方はありそうですが、Ｃ問題レべルだと
　TLEも気にせず単純な実装で済みました。
　
　【考え方】
　　まず靴下を入れておく辞書と答えの変数を用意
　　リストを頭から読んでいき、色毎に辞書登録
　　辞書は色をキーに、1個目の時値を１
　　同一色の2個目の時は、値を0に戻し
　　答え変数に1を加算
　　最後に答え変数を表示。

　https://atcoder.jp/contests/abc295/submissions/40030975

4.D - Three Days Ago
　単純に実装してみましたが、TLEになってしまいました。
　解説読んでも今一ピンとこず、後日やらなそうな気はしますが
　後日ということで撤退しました。　

以上
androidでelixir

# 概要

androidでelixirやってみる。
構想編

# 手順

# androidタブレットを購入する。

|項目|仕様|
|:-|:-|
|購入|amazon prime|
|Brand	|‎ANTEMPER
|機種|k105?|
|OS|Android 9.0
|プロセッサー|MTK6580A7 4コア 1.3GHz
| ディスプレイ|10.1インチ1280x800 IPS LCD
|RAM | 2GB 
|ストレージ| 32GB 
|SIMカード|3G / 2G デュアルSIM サポート
|WIFI| 802.11a / b / g / n（2.4G）
|BT| BT4.0 
| FM |ok
|GPS|ok
|カメラ|5.0Mリアカメラ 2.0Mフ​​ロントカメラ
|サイズ|240.2 * 170.0 * 8.3mm
|重量|550g
|バッテリー|3.7V / 6000mAH



# wifiに、入る。

# userlandをインストールする。
ubuntu 22.04

# elixirをインストールする。

```
$ wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb

$ sudo apt-get update

$ sudo apt-get install esl-erlang

$ sudo apt-get install elixir

```


以上。
[Rails] 単数形リソースについて

[Rails] 単数形リソースについて

# はじめに

Railsは、RESTfulな設計を実現させるために、resourcesメソッドが存在しています。こちらを宣言するだけで、自動でRESTfulなルートとCRUD操作をするためのアクションを結び付けてくれるので大変便利なメソッドです。

ほとんどの場合は、こちらを使っていけばよいのですが、別の選択肢としてresourceメソッド (単数形リソース)というのがあります。今回はこちらについて紹介したいと思います。

## 使用環境
* Rails 7.0.4
* ruby 3.0.2

# 単数形リソースを選ぶ基準
単数形リソースを選ぶ基準としては、ユーザーがそのリソースに対して複数のリソースを必要としない場合で使うとよいと思います。



例えば、「商品」(/items)は、アプリを使用するユーザーにとって、複数のリソース(/items/1, /items/2 ...)を扱いたいので、これはresourcesメソッドを宣言するのがよいでしょう。

では、「現在ログインしているユーザのプロフィール」(/profile) ではどうでしょう。ユーザーにとっては、現在ログインしているのは、自分自身しかいません。
複数のプロフィールの一覧を表示するわけではないし、ほかのユーザーを扱う必要がないのでこの場合は、単数形リソース(`resource`)で作成するのがよいと思います。

このように、単数形リソースは、ユーザにとってひとつしか存在しないリソースをRESTfulに扱いたい場合に使うのがいいでしょう。

# 単数形リソースのルーティング定義の仕方
単数形リソースを宣言する方法は、resourcesメソッドとほぼ同様な方法で定義を行います。

例として、profileのshowアクションのみを宣言したいと思います。

```ruby:config/routes.rb
resource :profile, only: %i[show]
```
これで単数形リソースの宣言ができました。 `resource` と単数形を宣言すること、`profile` とこちらも単数を宣言することに注意してください。

こちらを宣言し `rails routes` でルーティングを確認すると、

```
prefix    Verb   URI Pattern          Controller#Action
profile   GET    /profile(.:format)   profiles/show
```
のような結果になります。

このように通常であれば、`items/:id(.:format)` のようにshowアクションには、idを必要としますが単数形リソースであるため不要となります。また、コントローラは、profilesと複数形になっていますが、これはコントローラは複数形、単数形どちらも同じコントローラに割り当てられるためこのようになっています。

# 単数形のヘルパーメソッド
ヘルパーメソッドについても複数形と同様に扱えますが、idを持たないため、showアクションなどに引数をとることはできません。そのため `profile_path` のように宣言すると、`/profile` を返すことになります。

# おわりに
今回は、単数形リソースについて説明をしてみました。idを参照する必要のないけどリソースを扱いたいことがいろんなところであると思いますので参考になればと思います。

### 参考にしたサイト
[Railsガイド](https://railsguides.jp/routing.html#%E5%8D%98%E6%95%B0%E5%BD%A2%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9)
Azure Automation の PAT 連携を Azure CLI でやってみた

以前、下記の記事を書きました。

https://qiita.com/mnrst/items/d6e10891f11c4e73b813

今回は、Azure Automation のソース管理と同期ジョブ設定で Azure Repos との PAT 連携を Azure CLI でやってみました。

## PAT 作成

https://learn.microsoft.com/ja-jp/azure/automation/source-control-integration#minimum-pat-permissions-for-azure-devops

こちらのドキュメント通りに、最小限のアクセス許可を付与した PAT を作成します。

|Scope|アクセスの種類|
|-|-|
|Code|Read|
|Project and team|Read|
|Identity|Read|
|User profile|Read|
|Work items|Read|
|Service connections|読み取り、クエリの実行、および管理|

## ソース管理と同期ジョブを設定

```bash:bash
# 環境変数をセット
prefix=mnrauto
pat=your_pat_here
commitid=$(git log --pretty=format:"%H" -1)

# ソース管理を設定
az rest \
  --method put \
  --url "$(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv)/sourceControls/${prefix}?api-version=2019-06-01" \
  --body '{
    "properties": {
      "repoUrl": "https://mnrsdev@dev.azure.com/mnrsdev/mnrsdev/_git/'${prefix}'",
      "branch": "main",
      "folderPath": "/",
      "autoSync": true,
      "publishRunbook": true,
      "sourceType": "VsoGit",
      "securityToken": {
        "accessToken": "'$pat'",
        "tokenType": "PersonalAccessToken"
      },
      "description": ""
    }
  }'

# 同期ジョブを設定
az rest \
  --method put \
  --url "$(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv)/sourceControls/${prefix}/sourceControlSyncJobs/$(uuidgen)?api-version=2019-06-01" \
  --body '{
    "properties": {
      "commitId": "'$commitid'"
    }
  }'

# 同期ジョブの状態を確認
az rest \
  --method get \
  --url "$(az automation account show \
  --automation-account-name ${prefix} \
  --resource-group ${prefix}-rg \
  --query id \
  --output tsv)/sourceControls/${prefix}/sourceControlSyncJobs?api-version=2019-06-01"
```

## 参考

https://learn.microsoft.com/ja-jp/rest/api/automation/source-control/create-or-update?tabs=HTTP
Jetson Ubuntu で Terminal が起動しなくなった際の一時的対処

# 背景
Jetson で PyTorch をビルドしていた際に、時間がかかる為に放置していたら・・
再起動がかかっていた。

どうやら容量不足で再起動になったらしい・・
ログインしてみると Terminal アイコンがサイドバーから消えてるし、起動も出来ない。

その際の、緊急対処策

元々、容量不足＆外付けSSDでビルド出来なくなったために、空Jetsonでビルドだけしようと思ったが、いろいろビルドしてたらまたもや同様の現象になった・・のかも・・ :(

# 試したこと
- 容量確保１G程度
- デスクトップに残っていた Terminal Icon 空の起動
- ショートカットでの Terminal 起動
- Software から 
    - Terminal(端末: Gnome-Terminal) を検索して、Launch
    - Remove 後に Launch
- Software から
    - TX-Terminal を Install してから <code>sudo apt-get install --reinstall gnome-terminal </code>

全部だめだったので、環境はあきらめつつ、ビルド継続する為
- **TX-Terminal でビルド継続 & Wheel だけ取得**

# あとがき
外部SSDでビルドしてた際に、意味不明な吹っ飛びで悩んだが・・結局これと同様に容量不足でどっかいかれてたのかも・・
Splunk: 計算済みフィールドの使い方


###### 実施環境： Splunk Free 8.2.2

 Splunk での検索において、あるフィールドをそのままではなく加工して扱いたい場合があります。
 eval コマンドを使用すれば加工はできますが、実はコマンドを使用しなくともフィールドを加工して利用できる機能があります。
それが今回紹介する、計算済みフィールド( calculated fields )という機能です。

### 1. 概要

例えば、ログ A において キロバイト単位で値が出力されるフィールド B があるとします。

このフィールド B についてギガバイト単位で値を扱いたい場合、値を1024で割ったフィールド C を作成すればギガバイト単位になります。

 eval コマンドを利用すればこのような操作ができますが、これをコマンドなしで実現するのが計算済みフィールドという機能です。

### 2. 設定方法

「設定」⇒「フィールド」を選択します。

![WS000536.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/59a287b8-fd2c-2402-0845-50322e69b9b4.jpeg "設定")

「計算済みフィールド」を選択します。

![WS000544.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/07ddf74b-4da8-402b-9bbb-7fffb5455c1f.jpeg "フィールド")

計算済みフィールドの一覧画面が開くので、右上の「新しい計算済みフィールド」を選択します。

![WS000545.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/7df2f9fb-75b0-8880-0dc8-81f33daa2446.jpeg "計算済みフィールド一覧1")

計算済みフィールドの設定を入力します。

![WS000566.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/1fb72da1-60fe-452a-1d87-f275b218c2d3.jpeg "計算済みフィールド作成")

ここでは以下の設定を入力します。
 Eval 式には、演算子だけでなく任意の評価関数( eval 関数, Evaluation functions )も使用可能です。

|項目名|値|
|:-|:-|
|宛先 App | search |
|適用先|ソース|
|名前付き| `/opt/splunk/var/log/splunk/metrics.log` |
|名前| `calc_gb` |
| Eval 式| `round(kb / 1024, 2)` |

これで計算済みフィールドが作成できました。

![WS000570.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/8555cae9-6b21-a405-9626-40f795afdb02.jpeg "計算済みフィールド一覧2")

### 3. 使用方法

試しに、以下の SPL で計算済みフィールドを使用してみましょう。

```Splunk:Splunk
index="_internal" source="*metrics.log" group=thruput name=thruput
| stats max(kb), max(calc_gb)
```

![WS000571.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/de49d6e3-a474-bb90-6327-77544c50df50.jpeg "SPL")

計算されたフィールド名`calc_gb`が存在していることがわかります。
TD　敵のスポーン機能を実装 1/2：一定時間でゲームオブジェクトを動的作成する

# 概要
敵をスポーンする機能を実装します。
今回の記事ではオブジェクトを動的生成するところから実装します。

以下gifアニメの様な動きを実装します。
１秒毎にオブジェクト（敵に該当する）を生成します。

![Spwan.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/7207af93-d3e9-3ec2-269b-90bc1f0605eb.gif)

# 開発環境

IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10


# 実装のポイント
一定間隔でメソッドを実行するためにはUpdateメソッドとTime.deltaを使っています。
Update毎にspawnTimerの値（最大値１）が減少していきます。
0以下になった時にオブジェクトを動的生成するメソッドが実行されます。
0になった時spawnTimerに1が代入され、再度同じ処理が実行されます。






# コード

```Spawner.cs
using UnityEngine;
    public class Spawner : MonoBehaviour
    {
        [SerializeField] private GameObject testGO;
        [SerializeField]  private  int enemyCount = 10;
        // Btw = Between
        [SerializeField] private float delayBtwSpawns;

        private int _enemiesSpawned;
        private float _spawnTimer;
        
        private void Update()
        {
            _spawnTimer -= Time.deltaTime;
            if (_spawnTimer < 0)
            {
                _spawnTimer = delayBtwSpawns;
                if (_enemiesSpawned < enemyCount)
                {
                    SpawnEnemy();
                    _enemiesSpawned++;
                }
            }
        }
        
        private void SpawnEnemy()
        {
            Instantiate(testGO, transform.position, Quaternion.identity);
        }
        
    }
```
# 参考
Time.deltaTime

https://docs.unity3d.com/ja/2021.2/ScriptReference/Time-deltaTime.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/32b7a43a-0055-37f8-6f84-b34535a9adf8.png)


Section3 8

https://www.udemy.com/course/learn-how-to-create-a-2d-tower-defense-game-in-unity-2020/learn/lecture/22895742#content

github commit 分

https://github.com/RYA234/2DTowerDeffenceMyLearning/commit/b4137bcd324995edcfc1bedb893050492992f038
お母さんでもわかるReact「レンダリング、JSX、Fragment」

## 大前提
大前提としてReactは、関数をコンポーネントとして扱っています。
つまり関数を一つのブロックとして、それをうまい具合に積み重ねてUIを作っていくということ。

## react-domの必要性
react-domをimportする理由を調べてみました。
どうやら、React要素をDOMにレンダリングするためのReactDOM.render()メソッドを使用することができなくなってしまうみたいです。
**※レンダリングとはReact要素（JavaScriptオブジェクト）をブラウザのDOMに変換して表示することを意味するので、「React要素をブラウザに表示することができない」**

ということでreact-domのimportはしましょう！

## レンダリングの方法
```jsx
//ReactDOMという名前でreact-domをインポートしている
import ReactDOM from "react-dom";

const APP = () => {
  return <h1>こんにちは！</h1>;
}

//これがレンダリング。ReactDOM.render(<レンダリングの対象 />, レンダリングする場所);
ReactDOM.render(<APP />, document.getElementById("root"));
```
上記はSPA（シングルページアプリケーション）の場合の記述方法です。
（SPAは基本HTMLlファイルが一つなのですが、複数ファイルになることもあるそうで、そのときはJSで必要なHTMLファイルを非同期で読み込むことができます。詳しくはもう少しわかってから共有します）

## JSXのルール
JSX（JavaScript eXtensible Markup Language）にはいくつかルールがあります。
①returnの中にHTMLを記述していくが、HTML要素が複数になる場合は`return()`の（）に記述していきます。
②return以降のHTMLは**親タグの兄弟要素は記述できない**


```jsx
const APP = () => {
  return (
    <h1>こんにちは！</h1>
    <p>清水です</p>
  );
}
```
このコードはエラーが出ます。
一番上の階層`div`が2つあるためです。
```jsx
const APP = () => {
  return (
    <div>
      <h1>こんにちは！</h1>
      <p>清水です</p>
    </div>
  );
}
```
このコードは問題ありません。
`<h1><p>`は兄弟要素ですが、一番上の階層`<div>`　が１つしかないためです。

## Fragment
上記の②を回避する方法が2つあります。
```jsx
import { Fragment } from "react";

const APP = () => {
  return (
    <Fragment>
      <h1>こんにちは！</h1>
      <p>清水です</p>
    </Fragment>
  );
}
```
```jsx
const APP = () => {
  return (
    <>
      <h1>こんにちは！</h1>
      <p>清水です</p>
    <>
  );
}
```
無闇に`<div>`を追加するのは可読性に欠けるので、有効な手段となります。
Functionとconstの宣言の違いに関してまとめてみた

## 2つの宣言方法について
まず、constで宣言される関数の宣言は、アロー関数式を使用している。
例えば以下のようなコードです。

```jsx
const MyFunctionComponent = (props) => {
  return <h1>Hello, {props.name}!</h1>;
}
```
一方、通常のfunctionを使用する場合には、以下のようなコードです。

```jsx
function MyFunctionComponent(props) {
  return <h1>Hello, {props.name}!</h1>;
}
```

## 違いはあるのか？
両方の宣言方法には、関数の機能上の違いはあまりない。しかし、アロー関数式は、関数の宣言を簡潔にするために一般的にはアロー関数が使われることが多いと思われる。
また、アロー関数式は、thisの動作についても異なる。以下例になります。

```jsx
class MyClass {
  myProperty = 'Hello, World!';
  
  myArrowFunction = () => {
    console.log(this.myProperty); // => "Hello, World!"
  }
  
  myFunction() {
    console.log(this.myProperty); // => "Hello, World!"
  }
}

const myInstance = new MyClass();

const arrowFunction = myInstance.myArrowFunction;
const regularFunction = myInstance.myFunction;

arrowFunction(); // => "Hello, World!"
regularFunction(); // => TypeError: Cannot read property 'myProperty' of undefined
```

arrowFunctionを呼び出すと、myPropertyの値が正常に出力されます。これは、アロー関数式ではthisキーワードが、関数が宣言された場所にバインドされるため。
一方、regularFunctionを呼び出すと、TypeErrorが発生します。これは、通常のfunctionではthisキーワードが、関数が実行されたコンテキストにバインドされるため。そのため、myFunction内でthisキーワードを使用すると、myInstanceオブジェクトを参照できないため、TypeErrorが発生。

### コンテキストにバインドするとは？
「コンテキストにバインドする」とは、thisキーワードがどのオブジェクトを参照するかを決定することを指す。
JavaScriptでは、thisキーワードは実行時に動的に決定される。thisキーワードは、どのオブジェクトが呼び出し元であるかによって異なるオブジェクトを参照することがあります。
以下コード例です。

```js
const myObject = {
  myProperty: 'Hello, World!',
  myMethod: function() {
    console.log(this.myProperty);
  }
};

myObject.myMethod(); // => "Hello, World!"
```

このコードでは、myObjectというオブジェクトを定義し、その中にmyPropertyとmyMethodという2つのプロパティを定義しています。myMethodは、functionを使用して定義される。

myMethodを呼び出すと、コンソールに"Hello, World!"が表示される。これは、myMethodが呼び出し元であるmyObjectオブジェクトがthisキーワードの参照先になっているため。

このように、thisキーワードが参照するオブジェクトは、呼び出し元によって異なるため、動的に決定される必要がある。
JavaScriptを初めて学ぶ6

ーイベント〜ブラウザ上でユーザーが行ういろんな動作のこと
ex) マウスをクリック、ボタンを押す、、、

ーイベントハンドラ〜イベント発生をきっかけに何らかの処理を実行する
ex)　マウスでボタンをクリック→Hello World!がconsoleに出力



・プロパティを使って、イベントとイベントハンドラを関連つける
→ オブジェクト名.onイベント名=()=>{
    イベントハンドラ
};

例えば
```html
...
<body>

    <input id="button" type="button" value="click!">
    <script src="main.js"></script>
</body>
```
```javascript
...
const e = document.getElementById('button'); 
e.onclick=() =>{ //クリックしたらeゲットして{}内を実行
    console.log('Clicked.');
}, false;

```

・loadイベント
関連付けられた要素を読み終わった時に発生するイベント。画像を含む、ページが完全に読み終わったことを検知して、何らかの処理を実行したいときに使う
```html
...
<body>

    <script src="main.js"></script>
</body>
```

```javascript
window.onload=()=>{ //Windowのページが完全に読み終わったら実行
    console.log('loadイベント!');
}
```
広告とか出てくるのはこれなのかな？

・addEventListener
要素オブジェクト.addEventListener(イベントの種類, ()=>{
    イベントハンドラ
}, false);

```html
...
<body>
    <input id="button" type="button" value="クリック">
    <script src="main.js"></script>
</body>
```

```javascript
const e=document.getElementById('button');
e.addEventListener('click', ()=>{ //('click')はイベントの種類
    console.log('Clicked!')
}, false);
```
tkinter PySimple GUIでWebアプリ作成

早速やってみます。

PySimpleGUIは標準ライブラリではないので、インストールします。

```ruby:
python3 -m pip install pysimplegui
```
```ruby:
Collecting pysimplegui
  Downloading PySimpleGUI-4.60.4-py3-none-any.whl (509 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 510.0/510.0 kB 9.3 MB/s eta 0:00:00
Installing collected packages: pysimplegui
Successfully installed pysimplegui-4.60.4
```

アプリ作成中に　
```ruby:
    import _tkinter # If this fails your Python may not be configured for Tk
    ^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named '_tkinter'
```
こんなのが出てきました。 
こちらの対応を検討します。
Power Apps のフォームコントロールで必須入力に漏れがあったらエラーメッセージを表示する


# はじめに

これまで何度か Power Apps のフォームコントロールについて触れてきました。

https://qiita.com/Takashi_Masumori/items/62637ba0c37d8e60cbf3

この際、この項目は入力必須にしたい、必須入力の項目が入力されていなかったらエラーメッセージを表示したり、データの送信が出来ないようにしたりしたいという相談をいただくことがあります。

そのため、今回は、例として、以下のアプリで、休暇理由がが入力されていない際、エラーメッセージを表示し、送信ボタンを押せなくする方法について説明したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/663daf1a-0f2b-7376-7a90-4d158a38fc73.png)

# 完成形

今回は、以下のような感じで、休暇理由が入力されていない際にエラーメッセージを表示し、また、ボタンを押せなくしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/15cbccc1-8871-10b6-2f73-05cf9cfd8a00.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/202d9d41-10d9-a71c-f7ed-cb3f0164b5c5.png)

# 入力必須の設定

フォームコントロールの項目を入力必須にするには、`[Required]`プロパティを true にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/4fe6fcbd-510f-114b-b393-60aec40a818a.png)


:::note
データソース側で入力を必須にしていない場合も、こちらで入力必須にできます
:::

# 必須入力に漏れがある場合エラーメッセージを表示

エラーメッセージは、ラベルを追加し、それっぽいエラーメッセージにして、色も赤あたりにしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/435a8c16-64d0-a4d4-ea99-ec7b0ab5f588.png)

そして、`[Visible]`プロパティを以下のようにします。
要は、Form コントロールの必須入力の項目がちゃんと入力されるかをチェックし、問題なければ表示しない、問題がある場合は表示するという感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f331ad6f-7f2b-52bd-dee8-fdf19f23e570.png)

```
If(FormNewRequest.Valid,false,true)
```

# 必須入力に漏れがある場合ボタンを押せなくする

こちらは、`[DisplayMode]`を以下のように変更します。
せっかくなので、エラーメッセージ用のラベルが表示されている際にボタンを押せなくするようにしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/59f79af1-b728-2d20-4a57-4281559d4b92.png)

```
If(lblError.Visible,DisplayMode.Disabled,DisplayMode.Edit)
```

これだけで完成です。非常に簡単ですね。

# まとめ

Power Apps のフォームコントロールで、必須入力の項目が入力されていなかったらエラーメッセージを表示し、データの送信が出来ないようにする方法について紹介しました。

簡単に実装できるため、フォームコントロールを利用する際は、このような方法を用いて、意図しない状態でデータが送信されないようにすることをご検討ください。
Googleデジタルマーケティング＆Eコマース：マーケティング・キャンペーンの成功を評価するための指標

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

# マーケティング・キャンペーンの成功を評価するための指標

マーケティング・キャンペーンでは、多くの指標をモニターすることができます。キャンペーンが成功したかどうか、どのように結論づけることができるでしょうか。

マーケティングキャンペーンの成功を評価するために使用するインサイトは、マーケティング目標またはゴール、およびキャンペーンが具体的に何を解決しようとしたかによります。しかし、主な成功要因は、設定されたパフォーマンスゴールを達成したかどうかということになるでしょう。

成功指標を理解するために、2つの例を使ってみましょう。

## 例１

最初の例では、マーケティング全体の目標として、

- ***<font color="MediumBlue">リードの数を増やす</font>***

というものがありました。

リードは、マイクロコンバージョンとして測定されました。マイクロコンバージョンとは、潜在顧客が購入の取引完了に向けて動いていることを示す完了した反応のことです。マイクロコンバージョンのパフォーマンス目標は、

- ***<font color="Darkcyan">Eメールのサインアップを20％増加させる</font>***

ことに設定されました。

#### メール

過去の経験から、メールリストに登録した人が購入を完了する確率は50％でした。そこで、マクロコンバージョンのパフォーマンス目標として、

- ***<font color="sienna">登録した人が購入を完了する確率を10％向上させ、60％にする</font>***

ことが設定しました。

次に、チャットボットの会話とブログページの訪問についても同様の目標が設定されました。

#### チャットボット

チャットボットは新しいものだったので、

- ***<font color="sienna">キャンペーン期間中に20回以上の会話を発生させる</font>***

ことを目標としました。

#### ブログページ

ブログページの訪問者数は最近40%急増したため、

- ***<font color="sienna">ブログページへの新規訪問者を20%増加させる</font>***

というパフォーマンスゴールが設定されました。マクロコンバージョンのパフォーマンスゴールが設定されました。

- ***<font color="sienna">チャットボットユーザーの30パーセントが購入を完了すること、ブログの新規訪問者の10パーセントが購入を完了する</font>***

ことが目標でした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/9c2ad7f9-73a9-e629-1053-45a140348aaa.png" width="700">

- メールについては、キャンペーンによりメール登録が21％増加しましたが、購入完了には効果がなく横ばいとなったようです。
- チャットボットの会話については、マイクロコンバージョンとマクロコンバージョンの両方の目標を達成または超過した。
- ブログページについては、マイクロコンバージョンとマクロコンバージョンの両方の目標がかなり大きく外れてしまいました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/cfa015d7-2692-8864-8739-668206a50191.png" width="700">

キャンペーンは成功したのでしょうか？

指標に基づくと、結果はまちまちでした。キャンペーンの一部は低パフォーマンスでしたが、他の部分は非常に成功しました。しかし、今後の課題としていくつかのことが明らかになりました。

- チャットボットは、コンバージョンのプルスルーがあるため、エンゲージメントを継続する必要があります。
- メールメッセージは、コンバージョンをより向上させるために見直され、修正される必要があります。
- ブログキャンペーンにあまり多くの時間やエネルギーを費やすべきではないことです。

## 例２

2つ目の例では、

- ***<font color="MediumBlue">平均注文額を2倍にする</font>***

ことで、オンライン販売を増加させるというマーケティング目標が設定されました。つまり、マーケティング施策を行う前の平均注文額は50ドルで、これを100ドルに引き上げることが目標でした。これはパフォーマンス目標にもなりました。

デジタル・マーケティング・キャンペーンでは、お客様がチェックアウト前やチェックアウト中に、クリックして追加の商品を見ることができるよう、ダイレクト・レスポンスを行いました。また、100ドル購入すると送料が無料になるキャンペーン広告も実施しました。

モニターした指標は、

- オンライン売上高
- 注文数
- 平均注文額
- 投資収益率（ROI）を維持するための売上単価
- 地域別の注文数
- 注文数の多い売れ筋商品
- 新規顧客とリピーターからの注文の比率

です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/dcae03da-6d78-5312-ae2d-7dbd2622b0c7.png" width="700">

- 平均受注額は45％増の95ドルで、目標の2倍には届きませんでしたが、全体的な傾向として、キャンペーンは大成功でした。
- オンライン販売の売上高は15パーセント、注文数は170件増加し、販売単価は3パーセント上昇し、地域別の注文数は変わりませんでした。
- 受注額の増加に貢献した売れ筋商品は、小型キッチン用品と電子機器であり、最後に、新規顧客とリピーターの受注比率が1〜1.4倍になりました。

:::note info
要約すると、この2つの例は、関心のある指標は常にマーケティングキャンペーンの目標によって決定されることを示しています。成功を評価するための指標は、全く異なるものでした。
:::
rake と rails の違い

Rails 5以降なら、railsとrakeのどちらのコマンドも同じ

### 参考
* [(Ruby on Rails)「rails db:migrate」でエラーが起きた話とその解決策 (all later migrations canceled:！？ Error: Table 'users' already exists？？) - ケースタディ！](https://keisuke-studyingit.hatenablog.com/entry/2020/08/06/200000#:~:text=%E3%81%93%E3%81%A1%E3%82%89%E3%81%AE%E3%81%94%E5%9B%9E%E7%AD%94%E3%81%AB%E3%82%88%E3%82%8A%E3%81%BE%E3%81%99%E3%81%A8%E3%80%81%E3%80%8CRails%205%E4%BB%A5%E9%99%8D%E3%81%AA%E3%82%89%E3%80%81rails%E3%81%A8rake%E3%81%AE%E3%81%A9%E3%81%A1%E3%82%89%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%82%E5%90%8C%E3%81%98%E3%80%8D%E3%81%A8%E8%80%83%E3%81%88%E3%81%A6%E3%82%82%E8%89%AF%E3%81%84%E3%81%9D%E3%81%86%E3%81%A7%E3%81%99%E3%81%AD%E3%80%82Rails%204%E4%BB%A5%E5%89%8D%E3%81%AA%E3%82%89%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%81%8C%E3%81%82%E3%81%A3%E3%81%9F%E6%A7%98%E3%81%A7%E3%81%99%E3%80%82)
Googleデジタルマーケティング＆Eコマース：Google AdsにおけるA/Bテスト結果をモニタリングする

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

# Google AdsにおけるA/Bテスト結果をモニタリングする

数字をより深く掘り下げることを楽しむ人もいれば、一度数字を持ち出すと興味を失ってしまう人もいます。パフォーマンス・マーケティングの分野で働くなら、キャンペーンのパフォーマンスについて意思決定するために数値データを使うことに抵抗がないことを学ぶことができます。

Google Adsで広告のバリエーションや入札戦略のA/Bテスト結果をモニタリングするとき、いくつかの統計的な結果が提示されます。

今回、これらの統計結果を紹介し、実験データを分析するための準備をします。数値に基づいて、テストした変更がキャンペーンに関連し、有益であるかを判断することができます。

# Google Adsの統計情報

実験結果をモニターしていると、次のような統計用語に出会うことがあります。

- 信頼水準  Confidence level
- 信頼区間（誤差の範囲から導き出される）Confidence interval (derived from a margin of error)
- 統計的有意性  Statistical significance

これらの用語の意味と実験について理解するために、さらに読み進めてください。

### <font color="MediumBlue">信頼水準</font>

実験結果に対してどの程度の確信が持てるか？

- 例えば、95%の信頼度とは、同じA/Bテストを100回行った場合、100回中95回は同じような結果が得られるという意味です。

信頼水準は通常、データを収集する前に選択されます。ほとんどの研究者は95％の信頼度を使用しています。Google Adsは、デフォルトでこの信頼度を実験に使用します。この信頼レベルに到達するためには、最低でも多くのユーザーがテストに参加する必要があります。そのため、信頼度95%の結果を得るために、通常少なくとも4週間は実験を行うことになります。

### <font color="MediumBlue">信頼区間</font>

全ユーザーに対してテストを実施することはできないため、A/Bテストの比較結果は、全ユーザーに対してテストを実施できた場合の結果の推定値であると言えます。

誤差とは、テスト結果と、より多くのユーザーでテストを行った場合に得られるであろう理論的な結果との間の、統計的に計算された差のことを指します。

信頼区間は、誤差を考慮した後の可能な値の範囲である。この範囲は、テスト結果 +/- 誤差のマージンです。

- 例えば、テスト結果がバリエーション間の差5%で、誤差が2%の場合、信頼区間は3%から7%になります。テストしたバリエーション間の差は、3%という低い値もあれば、7%という高い値もあり得ます。

Google Adsが結果の予想範囲をリストアップするとき、それは信頼区間を報告しているのです。

### <font color="MediumBlue">統計的有意性 </font>

統計的有意性とは、検査結果が偶然によるものか、そうでないかを判断することです。有意性が高ければ高いほど、偶然によるものは少なくなります。

Google Adsは、バックグラウンドで信頼度95%で統計計算を行い、結果が統計的に有意であるかどうかを知らせます。結果の横に表示される青い星（アスタリスク）は、テストした2つのバリエーションの間で、統計的に有意な変化があったことを示します。

# 実験例

下図のように、Google広告の「Huge Savings」広告のバリエーション実験（またはA/Bテスト）では、クリック数とインプレッション数が減少しました。クリック数は250で8％減、インプレッション数は12,139で11％減となりました。インプレッション数の減少には、95%の信頼水準で統計的に有意であることを示す青いアスタリスクが付けられています。クリック数とインプレッション数の両方が減少傾向を示しているため、このバリエーションをレスポンシブ検索広告に適用することは選択しないでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8efa3270-28a9-7377-9393-f345a7c1452d.png" width="700">

# 実験の実施時間

統計的に有意なテスト結果を得るためには、通常少なくとも4週間は実験を行う必要があります。より詳しいガイダンスが必要な場合は、A/Bテストのための多くのサンプルサイズ計算機がオンラインで利用可能です。AB Tastyのそのような計算機では、1日の平均訪問者数とテストの可能な期間を計算するためのバリエーションの数を入力することができます。

また、Eコマースの売上が通常通り変動することを考慮し、十分な期間実験を行う必要があります。例えば、日曜に最も売れ行きが良く、土曜に最も悪くなるのが通常のEコマースビジネスの場合、最低でも2週間、できればそれ以上の期間テストを行うことで、これらの変動がテスト結果に与える影響を軽減させることができます。

同様に、テスト中にプロモーションが発生した場合、テストを長く実施することで、プロモーションによるテスト結果の偏りを防ぐことができます。プロモーションは数日から数週間、ユーザーの行動を変化させるため、十分な期間実施しないと、広告バリエーションテストが通常よりも良いパフォーマンスを示すように見えることがあります。
【Android】電池残量の取得【kotlin】


起動時に、取得した端末の電池残量をTextViewに表示するようにします。

電池残量や充電中か否かなどを**BatteryManager**クラスで取得できます。
```
    private val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
        this.registerReceiver(null, ifilter)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val textView: TextView = findViewById(R.id.text_view)

        val battery: Int? = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL,-1)

        textView.text = batteryPct.toString()
    }
```


# 参考
https://developer.android.com/training/monitoring-device-state/battery-monitoring?hl=ja
Googleデジタルマーケティング＆Eコマース：A/Bテストのための他のツール

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">


# A/Bテストのための他のツール

[Google AdsでA/Bテスト][ads]を行うことについて学びましたが、A/Bテストの機能を提供するツールは他にもあります。

[ads]: https://qiita.com/mapami/items/c4b956cf773fce86097e

- [AB Tasty](https://www.abtasty.com/): Pricing is available by custom quote
- [Convert](https://www.convert.com/): Free trial is available
- [Crazy Egg](https://www.crazyegg.com/ab-testing): Free trial is available (requires billing information)
- [Google Optimize](https://optimize.withgoogle.com/): Google Optimize is free while Google Optimize 360 is a paid subscription
- [Instapage](https://instapage.com/products/conversion-optimization): Free trial is available (requires billing information)
- [Optimizely](https://www.optimizely.com/products/intelligence/web-experimentation/): Pricing is available upon request
- [Unbounce](https://unbounce.com/product/features/unlimited-ab-testing/): Free trial is available (requires billing information)
- [VWO](https://vwo.com/): Free trial is available

# プロセスチェックリスト

どのツールを選ぶにせよ、以下はA/Bテストの取り組みを整理するのに役立つプロセスチェックリストです。

1. テストする変数を選択する。
2. テストの目的を明確にする。
3. コントロールとバリアントを明確に識別する。
4. キャンペーンまたはウェブページで実行されているA/Bテストがあなたのテストだけであることを確認します。
5. サンプルグループをランダムに分割する（A/Bテストプラットフォームで管理可能）。
6. 必要なサンプルサイズを決定します（A/Bテストプラットフォームで管理可能）。
7. 統計的有意性の信頼水準を決定する（A/Bテストプラットフォームで管理可能）。
8. A/Bテストプラットフォームを選択する。
9. 両方のバリアントを同時にテストする。
10. 十分なデータを収集するために、テストを十分な時間実行する。
11. テスト結果をテストの目標に照らして検討します。
12. テスト結果に基づき、適切なアクションを決定します。
13. 必要であれば、追加のA/Bテストを計画します。

# 追加のテスト

あなたは以前、単一のバリエーション（バリアント）に対するA/Bテストについて紹介されました。例えば、同じ広告やランディングページの2つのバリエーションをテストする実験を行うことができます。基本的なA/Bテストを提供する多くのツールは、追加のテストも提供しています。必要なテストを実行できるように、選択したツールの機能を知っておくことが重要です。その他のテストには、リダイレクトテストと多変量解析テストがあります。

### <font color="MediumBlue">Redirect tests</font>

リダイレクトテストは、別々のウェブページを互いにテストすることができます。これは、同じウェブページの変更をテストする基本的なA/Bテストとは異なります。リダイレクトテストでは、バナーのようなページ上の特定の要素ではなく、URLやパスによってバリアントが識別されます。リダイレクトテストは、2つの全く異なるランディングページをテストしたい場合、またはウェブサイトの完全な再設計に関与している場合に便利です。

### <font color="MediumBlue">Multivariate tests</font>

多変量テストは、ページ上の2つ以上の要素のバリエーションを同時にテストし、どの組み合わせが最良の結果をもたらすかを判断するために使用されます（多変量テストと呼ばれることもあります）。これは、1つの変数または変更のみをテストする基本的なA/Bテストとは異なります。多変量テストは、各要素の最も効果的なバリアントを特定しますが、バリアントを組み合わせたときにどのように機能するかについての洞察も提供します。これによって、バリアントの最適な組み合わせを特定することができます。
Googleデジタルマーケティング＆Eコマース：A/Bテストの効果的な計画

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

# 問題を定義する

A/Bテストは、ほぼすべてのデジタルコンテンツやデザイン要素に対して実施できます。しかし、広告の見出しからボタンの色まで、何をテストするにしても、まず実験のために具体的な問題や目標を特定する必要があります。

例えば、

- 低いコンバージョン率を改善したいとか、
- 新しい顧客ニーズを満たす方法を見つけたいとか

問題や目標が大きいと思われる場合でも、小さな変化から始めるのがベストです。小さな変更がパフォーマンスにどのような影響を与えるかを理解することで、より野心的な変更をテストするための基準値を得ることができます。

# A/Bテスト計画の要素

A/Bテスト計画の詳細は、企業やテストツールによって異なるかもしれませんが、効果的な計画の基本は同じであることが多いのです。以下は、A/Bテスト計画で見られるかもしれない一般的な要素の例です。

### <font color="MediumBlue">仮説</font>

何を実現したいのかが明確になったら、次は仮説を立てます。A/Bテストでは、仮説は「なぜ」「何を」「どのように」実験するのかを記述します。また、結果を予測するものでもあります。仮説は、調査やデータによって裏付けられ、一つの問題に焦点を当てる必要があります。

最低限、仮説は以下のことを記述する必要があります。

- テストが対処する問題または洞察
- 問題に対処するために何を変更する予定か
- 変更によって期待される影響や結果

例えば、ある企業がマーケティング用Eメールの受信者がウェブサイトをクリックする割合を増やしたいと考えているとします。データを調査した結果、購読者はメールの上部付近に表示される要素をクリックする可能性が高いと判断しました。A/Bテストの仮説は次のようになります。

- "お客様はメールの先頭付近の要素をクリックする可能性が高いことが分かったため、リンクの位置を変えることでクリック率・開封率が15％アップすると見込んでいます。”

強力な仮説があれば、テストの結果を報告し、ステークホルダーと洞察を共有することが容易になります。しかし、仮説を立てるプロセスも同様に重要です。それは、テストを行う理由を具体的に述べなければならないからです。もし、説得力のある仮説を立てるのが難しい場合は、テストを行う前にもっとデータを集めるべきということかもしれません。

### <font color="MediumBlue">バリアント</font>

仮説が立てば、チームはバリアントを計画し始めることができます。バリアントとは、A/Bテスト中にユーザーに提供するコンテンツの異なるバージョンのことです。

- バリアントAはオリジナルのコンテンツを表し、
- バリアントBは通常、何らかの意味のある方法で異なっています。

しかし、一般的には、1つのバリアントに対する変更の回数を制限することが望ましいとされています。一度に多くのことを変更すると、テスト結果を解釈するのが難しくなります。

例えば、メールマーケティングのシナリオでは、バリアントBのリンクはメッセージの一番上に移動されるかもしれません。しかし、このバリアントでは、新しいコールトゥアクション（CTA）テキストも含まれており、リンクがボタンに変わっていたらどうでしょうか？それぞれの変更の影響をどのように個別に測定するのでしょうか？変更をバリアントごとに限定することで、明確で実用的な結果を得られる可能性が高くなります。

:::note info
「失敗した」テストでさえ、貴重なデータを提供することができます。Bのバリアントが期待した改善をもたらさなかったとしても、それは必ずしもあなたの仮説が間違っていることを意味するわけではありません。あなたが望む結果を得るためには、別のバリアントをテストする必要があるかもしれません。
:::

### <font color="MediumBlue">メトリックス</font>

テストを開始する前に、チームは結果をどのように測定するかを決定する必要があります。テストごとにいくつかの指標を追跡することになるでしょうが、いくつかの指標は他の指標よりも重要でしょう。

メールマーケティングの例では、クリック・トゥ・オープン率（メールを開いた後、1つ以上のリンクをクリックした受信者の割合）が主要な指標となります。しかし、そのリンクをクリックした人のうち何パーセントが最終的に購買に至ったかを知るために、コンバージョン率も追跡する場合があります。

# 現在のパフォーマンスと改善見込み

成功の定義についても合意しておく必要があります。このテストでは、

- このテストでは、どれくらいの改善を望んでいるのか、あるいは期待しているのか。
- 5%の向上で十分ですか？10％ならどうでしょう？

設定する目標は野心的であってもかまいませんが、利用可能なデータに基づいて現実的なものでなければなりません。

# その他のテスト内容

A/Bテスト計画には、テストに関する他の重要な詳細も含めることができます。会社によってA/Bテスト計画書に記載する情報は異なりますが、基本的な計画書には以下のような内容が含まれることを覚えておいてください。

- テストの概要とその目的
- テスト対象のチャネル（例：Google Ads、Google Optimizeなど）
- テストするアセットの種類（例：ディスプレイ広告、ボタンコピー、など）
- テスト期間（開始日と終了日）
- バリアントごとのユーザー数
- 信頼度（テストを長く実施した場合にテスト結果が一貫性を保つと推定される確率）

# Activity Exemplar: Plan for A/B testing

https://docs.google.com/document/d/1Lg63zjtlNvUvW2oFTvcdVsxkKjmBTYCj2WiSUefTCmA/template/preview
Python3 で 騒音計を作ろう

# Python3 で 騒音計を作ろう

## 音楽を聴いていたら、隣家から苦情

自分が音楽を聞く自由と、近隣の方々が静かに暮らす自由を両立させたい

壁に遮音材と吸音材を貼ったところ、苦情の内容が
「音が漏れている」という表現から「重低音が聞こえる」に変わった。

## よっしゃ重低音対策しちゃうぞ

音漏れは60dBぐらいから聞こえる

重低音は40dBぐらいでも聞こえることが有る
というのを突き止めた。（長男が詳しかった）

床を通じて隣に伝わっているので、床とスピーカの間に遮音材を敷いた上で、さらに対策を行う。

## 重低音の部分の音量を把握したい

全域の音量の算出は、サンプルがネットに見つかった。

https://hotsmmrblog.com/noise-level-measurement_with_raspberry_pi_and_usb_mic/
ラズパイとUSBマイクを用いたデシベル計算、騒音測定器の作成【Python + pyaudio】

重低音部分はサンプルコードが見つからず。

## Facebookで質問してみた

ローパスフィルタというものを使えば、高音部分を消してくれるらしい、との回答を頂いた。（丹野さんに感謝）

ローパスフィルタ（英語: Low-pass filter: LPF、低域通過濾波器）とは、フィルタの一種で、なんらかの信号のうち、遮断周波数より低い周波数の成分はほとんど減衰させず、遮断周波数より高い周波数の成分を逓減させるフィルタである。

## 方針

1秒間、録音
そのデシベル数を算出（全域）
録音内容をローパスフィルタにかける
そのデシベル数を算出（重低音）
以上を無限ループさせる

## 全域の処理（抜粋）

```Python
        stream = p.open(format = FORMAT,
                        channels = CHANNELS,
                        rate = SAMPLING_RATE,
                        input = True,
                        frames_per_buffer = CHUNK,
                        input_device_index = INPUT_DEVICE_INDEX
                )

        # get specified range of data. size of data equals (CHUNK * (SAMPLING_RATE / CHUNK) * RECORD_SECONDS)
        data = np.empty(0)
        for i in range(0, int(SAMPLING_RATE / CHUNK * RECORD_SECONDS)):
            elm = stream.read(CHUNK, exception_on_overflow = False)
            elm = np.frombuffer(elm, dtype="int16")/float((np.power(2,16)/2)-1)
            data = np.hstack([data, elm])
        # calc RMS
        rms = np.sqrt(np.mean([elm * elm for elm in data]))
        # RMS to db
        db = to_db(rms, 20e-6)
        stream.close()
```
## ローパスフィルタ
```python
    import numpy as np
    from scipy.signal import butter, lfilter, freqz
    import matplotlib.pyplot as plt

    def butter_lowpass(cutoff, fs, order=5):
        nyq = 0.5 * fs
        normal_cutoff = cutoff / nyq
        b, a = butter(order, normal_cutoff, btype='low', analog=False)
        return b, a

    def butter_lowpass_filter(data, cutoff, fs, order=5):
        b, a = butter_lowpass(cutoff, fs, order=order)
        y = lfilter(b, a, data)
        return y

    # Setting standard filter requirements.
    order = 6
    fs = SAMPLING_RATE
    cutoff = 100.0　　　　　　　　　　# 100Hz以下が重低音ということで、ここは 100.0

    b, a = butter_lowpass(cutoff, fs, order)
```
## これを組合せて、全域・重低音のdB算出

いい感じに妥当な数字が出た。

![RasPi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63311/d2666acf-b589-6e2a-b76f-4c7cfb863b47.jpeg)

## 動作イメージ

大きさに応じて色付けして、隣家に聞こえるレベルを赤表示にした。

![Sample01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63311/b6e9e46b-41b1-75dc-46d1-549a765a2ef6.jpeg)

## ダウンロード・入手したい人向けの情報

https://tanaka-cs.co.jp/NoiseMeter.html
ここで販売しています。（誰も買わないけど）

https://github.com/hidemune/sound-level-meter
ここでテストコードを公開しています。

## ダイナミックマイクとコンデンサマイク

コンデンサマイクは、重低音のノイズが乗る？
（中華の安価なもの）

ダイナミックマイクのほうがノイズが少ない？
（Shureの高価なものと中華の安価なもの両方）

上記の原因として考えられるものは何だろう。。？

## コンデンサーマイクとダイナミックマイクのおおまかな特徴

ダイナミックマイク：電源不必要、丈夫で比較的湿度に強い、感度が低い、⇒比較的安価

コンデンサーマイク：電源必要、振動や湿気に特に弱い、感度が高い、⇒比較的高価

電源部分がノイズの原因になりやすい？
感度の問題は、音漏れの閾値が妥当ならあまり問題はないかも

## とりあえず、苦情は来なくなったので成功

おめでとう〜 ぱちぱち


以上です。最後まで読んでいただき、ありがとうございました。
chatGPTに走り書きの抽象的なサービス発想からQiita向けに記事を書いてもらってみた

# 0.chatGPTだけではまだまだ具体的なサービス設計は難しそうだ
下記の記事にあるサービス発想を再度chatGPTに、Qiitaに適した文章に再編成してもらいました。

https://qiita.com/ryotashona/items/5332dce2efe5a919e0a8

結果、今現在は僕らの仕事は必要みたいです。

肝心の今までにない方向へのサービス思想/意義が向け落ちて、一般的なサンクスカードサービスの内容になってます。

以下、chatGPTの出力です。

# タイトル:
サンクスカードを活用した感謝のコミュニケーションアプリの開発
# タグ:
サンクスカード, 感謝, コミュニケーション, ウェブアプリ, モバイルアププリケーション, 開発, React, Node.js, MySQL
# 1. はじめに
最近「サンクスカード」を目にする機会があった。これをもとに、感謝のメッセージを簡単に送受信できるウェブアプリやモバイルアプリを開発するアイデアを考えてみた。
# 2. アプリの機能
サンクスカードのデザインを選択できる
メッセージを入力し、相手に送信できる
受信したメッセージを一覧で確認できる
ユーザー間で感謝のメッセージを共有できる
# 3. 使用技術
フロントエンド: React / Vue.js / Angular
バックエンド: Node.js / Django / Ruby on Rails
データベース: MySQL / PostgreSQL / MongoDB
API: RESTful API / GraphQL
# 4. 開発手順
アプリの要件定義と設計
フロントエンドとバックエンドの環境構築
データベースの設計と実装
APIの設計と実装
フロントエンドの実装
テストとデバッグ
デプロイ
# 5. まとめ
感謝のコミュニケーションを促進するアプリを開発することで、人々のつながりを強化し、ポジティブな効果をもたらすことが期待できます。技術者として、私たちが持っているスキルを活用して、社会に貢献するプロジェクトを作成しましょう。
# 6. UI/UXの重要性
感謝のコミュニケーションアプリを開発する際に、UI/UXは非常に重要な要素です。使いやすく、直感的なデザインを追求することで、ユーザーが感謝のメッセージを簡単に送信できるようになります。また、デザインが魅力的であれば、アプリの利用率も向上するでしょう。
# 7. セキュリティとプライバシー
アプリで送受信されるメッセージは、ユーザーの感情が込められたものです。そのため、セキュリティとプライバシーの確保が不可欠です。データの暗号化や、アクセス制限の実装など、セキュリティ対策を十分に行いましょう。
# 8. 継続的な改善とアップデート
アプリをリリースした後も、継続的な改善とアップデートが重要です。ユーザーのフィードバックを受け取り、問題点を修正し、新機能を追加することで、アプリの価値を高めることができます。
# 9. まとめ
サンクスカードを活用した感謝のコミュニケーションアプリを開発することで、感謝の気持ちを簡単に伝えられるツールを提供することができます。技術者として、私たちが持っているスキルを活用して、社会に貢献するプロジェクトを作成しましょう。
感謝のコミュニケーションを変える: サンクスカードから学ぶ

# 注意：この記事はchatGPTに章立て、再構成してもらいました
走り書きの文章をどの程度、タイトル付け・タグ付け・章立てできるか試してみました。
これがChatGPTに入力した元文章です

<details><summary>元文章</summary>

```rb
最近「サンクスカード」を目にする機会があった。
以前の自分なら「くだらないことしているなぁ」と思うだけだった。
いや、今もそうも思っているがそれだけではなく「これが存在するということは、必要としている人がいる。世の中に需要がある」と感じ取れるようになった。

これはたぶん、自分の鬱経験があったことで、考え方が変わったのだろうと思う。
辛かった事は実感としてあるが、その当時自分がどう感じていたかはハッキリ思い出せない。
が、あの頃の自分にホントに感謝している。極端な決断を踏みとどまってくれてありがとうと。
理解できない思いについて感謝をするということが出来るようになったのだろう。

前々から他人の認識なんて理解できない。し、理解したところで無意味だと思っていた。考慮することは必要だが。
結果、「くだらない」は「くだらない」で止まっていた。思考停止していた。
それを積極的に対外的に批判するようなことはしないが。

今なら「これを大切に思う人がいる」ということが飲み込める。
飲み込めることで、「需要がある」と変換できる。理解できる。
需要があると理解できるいうことは、ビジネスチャンスにつながるということだ。

既に「サンスクカード」「ありがとうを伝えること」ような仕組みは提供されている。
例えば、ホテル利用者がホテルに対してカードをおいておくような。

逆にホテル利用後に清掃などをする人から、その部屋の利用者に「きれいに使ってくれてありがとう」というようなことは見たことがない。
もちろん、利用者がレビューを書いて、それにホテル側がレスを付けるようなケースはあるが、それああくまで利用者マターだ。

これをもっと手軽にかつ、押し付けでもなく、リピーター狙いとも受け取られず（もちろんビジネス的にはリピーター獲得が見込めることを売りとするが）自然とコミュニケーションが出来るようなサービス作れは、いい意味で社会が変わるかもしれない。
世の中にありがた迷惑をいうものがある。旅館で利用者が布団を畳んで帰る様な。清掃側は布団を再度広げる必要があるので、畳まない方が楽と聞いたことがある。（間違いかもしれないが。。。）
感謝とともに、これを自然な形で伝えられれば、お互いの負荷が減るかもしれない。

そんなことをふとおもった。
```
</details>
以下、cahtGPTが出力した章立て/本文です。

(追記：再度同じ内容を入力したらブラッシュアップされました)

# 1. はじめに
最近「サンクスカード」を目にする機会があった。以前の自分なら「くだらないことしているなぁ」と思うだけだったが、今では「これが存在するということは、必要としている人がいる。世の中に需要がある」と感じ取れるようになった。

# 2. 考え方の変化
これはたぶん、自分の鬱経験があったことで、考え方が変わったのだろうと思う。辛かった事は実感としてあるが、その当時自分がどう感じていたかはハッキリ思い出せない。しかし、あの頃の自分に本当に感謝している。

# 3. 他人の認識
前々から他人の認識なんて理解できない。しかし、今なら「これを大切に思う人がいる」ということが飲み込める。飲み込めることで、「需要がある」と変換できる。理解できる。

# 4. ビジネスチャンス
需要があると理解できるということは、ビジネスチャンスにつながるということだ。既に「サンスクカード」「ありがとうを伝えること」のような仕組みは提供されている。

# 5. サービスのアイデア
逆にホテル利用後に清掃などをする人から、その部屋の利用者に「きれいに使ってくれてありがとう」というようなことは見たことがない。これをもっと手軽にかつ、押し付けでもなく、リピーター狙いとも受け取られず自然とコミュニケーションが出来るようなサービスがあれば、社会が変わるかもしれない。

# 6. お互いの負荷を減らす
世の中にありがた迷惑というものがある。旅館で利用者が布団を畳んで帰るようなケースなど。感謝とともに、これを自然な形で伝えられれば、お互いの負荷が減るかもしれない。

# 7. まとめ
そんなことをふと思った。サンクスカードや感謝のコミュニケーションを通じて、人々がお互いに理解し合い、負荷を減らすことができる社会を目指していくことは大切だ。そして、それがビジネスチャンスにもつながる可能性がある。今後も感謝のコミュニケーションを大切にし、さらなるアイデアやサービスが生まれることを期待したい。
Googleデジタルマーケティング＆Eコマース：Google AdsでA/Bテストを実行する

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

# A/Bテスト

A/Bテストは通常、広告やWebページの新しいバージョンが元のバージョンと比較して指標を向上させるかどうかをテストすることを学びます。

広告のバリエーションでは、URL、見出し、”Call to action”の変更など、広告の変更をテストすることができます。例えば、

- 見出しを「在庫があるうちに今すぐ行動」から「大幅値引き、期間限定キャンペーン」に変更すると、複数のキャンペーンの広告で売上にどのような影響があるかをテストすることができます。
- ”Call to action”を「今日買う」から「今すぐ買う」に少し変更するだけでも、テストが可能です。

しかし、すべての変更にテストが必要なわけではありません。最初に十分なテストを行わずに広告のテキストを少し変更することは、確かに合理的です。

# 広告バリエーションテスト
代替見出しの最初の例を使用して、Google AdsのA/Bテストの一種である広告バリエーションテストを設定してテストする方法を説明します。現在または既存の見出しが "在庫があるうちに今すぐ行動" であると仮定します。

### Step1
Google Adsのキャンペーンページで、「すべてのキャンペーン」をクリックし、ナビゲーションパネルで「実験」をクリックします。

### Step2

次に、プラスアイコンを選択して、新しい広告バリエーションを作成します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d999573c-4e75-95a5-4676-1fb778e561a2.png" width="700">

### Step3

この広告バリエーションをすべてのキャンペーンに適用するか、またはこのバリエーションが影響を与えるキャンペーンを選択します。ここでは、このバリエーションがすべてのキャンペーンに適用されると仮定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/204ecce9-cc06-7ddf-52bd-9ec7229d49b0.png" width="500">

### Step4

次に、テキストを更新することと、編集対象が「ヘッドライン」であることを選択します。

### Step5

最後に、バリエーションの見出しのテキストとして、「大幅値引き、期間限定オファー」と入力します。このバリエーションを「Huge Savings」と名付けましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5fe0bfde-e822-211c-8ee9-18a1fd5da510.png" width="500">

デフォルトの開始日と終了日を使用して30日間実施し、テストの分割はデフォルトの50パーセントのままにしておきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/ebe5a79c-692d-6cf9-3370-6c231b5c6630.png" width="500">

バリエーションを作成するには、"バリエーションを作成 "をクリックします。この広告バリエーションのA/Bテストが実行されると、広告バリエーションテーブルに結果が表示されます。

# テーブルでの結果

以下は、テーブルで結果がどのように表示されるかの一例です。クリック数やインプレッション数などの指標は、テーブルを横切るように移動しているのがわかります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5ab7bb79-8d9b-c8e4-1918-c2e56aaf1c1c.png" width="700">

各指標には、プラスまたはマイナスのパーセントが表示され、テストした2つのバリエーションの間にどれだけの変化があったかが分かります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f0e768a9-7e1f-275e-f19f-4cafa0441905.png" width="500">

- ここで注目したいのは、青い星が付いたパーセンテージです。これらの星は、テストした2つのバリエーション間で統計的に有意な変化があったことを示します。
- 多くの指標に星印が表示されている場合は、新しいバリエーションを恒久的な広告の変更にすることを検討するとよいでしょう。

:::note info
すべての変更またはバリエーションをテストする必要はないことを覚えておいてください。A/Bテストには時間と予算がかかるため、テストする広告を戦略的に選択することが重要です。このような判断は、チームごとに異なるものです。
:::
JavaScript の関数の引数に {value1, value2} が指定される場合の挙動を調べてみた

## 追記: 2023-03-26
該当の記法は、`分割代入 (Destructuring)` と呼ばれ、ES2015 に追加された言語仕様ということを教えてもらいました。
- [Destructuring](https://babeljs.io/docs/learn/#destructuring)
- [分割代入](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

わからないので調べようにも、"javascript {} 代入" では満足な検索結果は得られなかったので、JavaScript を独習している人にとって優しくないよね。

## 何がわからないかというと
例えば、このページ [Basic Features: Pages | Next.js](https://nextjs.org/docs/basic-features/pages) に記載されているサンプルコードで、

```javascript
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

export async function getStaticProps() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  }
}
```
の
```javascript
export default function Blog({ posts }) {
```
に記述されている `({ posts })` がどういう挙動なのかわからなかった。

## ということで、挙動を確認してみた

次のコードを　[JSFiddle](https://jsfiddle.net/)　で動作させてみた。

```javascript
var test = 1;
var hoge = 'fuga';
var example = {
    name: {
        test,
        test1: test,
        hoge,
        fiz: 'buzz',
    },
};

console.log(example);
console.log('example.name.test has ' + example.name.test);
console.log('example.name.fiz has ' + example.name.fiz);
var {test1} = example.name
console.log('test1 has ' + test1);

func1 = function(obj) {
    console.log('func1 prints out ' + obj.hoge);
}

func2 = function({ hoge, test }) {
    console.log('func2 prints out ' + hoge);
}

func1(example.name);
func2(example.name);
```
`cosole.log()` の出力結果は下記の通り。

```
{
  name: {
    fiz: "buzz",
    hoge: "fuga",
    test: 1,
    test1: 1
  }
}
"example.name.test has 1"
"example.name.fiz has buzz"
"test1 has 1"
"func1 prints out fuga"
"func2 prints out fuga"
```
## 感想

```javascript
export default function Blog({ posts }) {
```

の挙動はなんとはなく想像は出来た。

しかし、次のような記述をする場合、

```javascript
var {test1} = example.name
```
他の言語だと、

```javascript
test1 = {
  fiz: "buzz",
  hoge: "fuga",
  test: 1,
  test1: 1
}
```
というような挙動を想定してしまう。

スプレッド構文とはまた違うのだろうし、この記法の正式な名称は何だろうか？｀
[TypeScript] [JEST] 型チェックするためのCustomMatcher

TypeScriptでライブラリとかを作っていると関数の返値の型のテストをしたくなります。

そこで便利なJESTのCustomMatcherを用意しました。

https://www.npmjs.com/package/jest-to-equal-type?activeTab=versions

※最近似たような記事を見たかもしれません。

[[Deno] TypeScriptの "型定義" をテストする方法（testing/typesモジュール）](https://qiita.com/access3151fq/items/26823add1e5407155c6e) 

が、パクったわけでもインスパイアされたわけでもなく、1年ちょっと前から公開済みなんです。

が、記事を見て宣伝したくなったことは否定しません。

## 使い方

よくあるように、パッケージをインストールして、

```cmd
> npm i -D jest-to-equal-type
```

importして、

```ts
import 'jest-to-equal-type';
```

Matcherを呼び出します。

```ts
// テスト対象の関数
declare function sampleFunction(): string;
declare function sampleFunction(a: number): boolean;
declare function sampleFunction(a: string): number;

// テスト
describe('return type check', () => {
  test('no arguments', () => {
    // expectで指定した値、もしくは関数の返値とtoEqualTypeの型パラメータに指定した型が一致するかどうかをチェック
    expect(() => sampleFunction()).toEqualType<string>();
  });
  test('a string argument', () => {
    expect(() => sampleFunction('abc')).toEqualType<boolean>();
  });
  test('a number argument', () => {
    expect(() => sampleFunction(123)).toEqualType<number>();
  });
});
```

チェックしているのはTypeScriptのコンパイラであって、実際にはtoEqualTypeは何もしていなかったりしますが…

## テストに失敗する場合

もし一致しない場合はコンパイラがエラーを吐きます。このときのエラーメッセージで一致しなかった型の情報を表示するように一工夫してあります。

たとえば、上記の例でいえば2番目と3番目のテストで引数を逆に渡してしまっているので、型が一致しません。

一致しない場合には`toEqualType`の引数を異常な型にしてしまうことでエラーになるようにしているのですが、このときの型に一致しなかった二つの型およびメッセージを載せています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122792/617d0930-f9d2-1776-193c-2bf073e39125.png)

JEST実行時にもエラーメッセージに型情報が載っています。

```plaintext
    test/optionalist.test.ts:1471:5 - error TS2345: Argument of type '[]' is not assignable to parameter of type '[] & { message: "型が一致していません"; expected: boolean; received: number; }'.
      Type '[]' is not assignable to type '{ message: "型が一致していません"; expected: boolean; received: number; }'.

    1471     expect(() => sampleFunction('abc')).toEqualType<boolean>();
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

ただし、TypeScriptのエラーメッセージでは中の型情報はちょっと長い(?)とすぐ省略されてしまうので注意が必要です。

一致しないのはわかったけどどこが一致してないんだよ…ということが多発しがちですので、ある程度細かい単位でテストすることをおすすめします。
Quest2 でファイルが読めなくなった。(Unity使用)

# 事象

Quest2 でファイルが読めなくなった。
以前同じような現象に陥りこちらの方法で解決した。

https://qiita.com/colllet/items/5ab293c52f4bd4e2ecbb



しかしまた読めなくなってしまった。

unity 2019.4.16f1

# 解決
ProjectSetting→Player→書き込み許可　を[Extrnal(SDcard)] にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912815/88b0df5b-2448-5365-ec29-00deaccc6a7f.png)

[Quest２でファイルが参照できない問題の解決法](https://qiita.com/colllet/items/5ab293c52f4bd4e2ecbb)で行っている権限付与を前提として今回の措置を行う必要があった。
前はinternalで行けたのに。。何ならinternalじゃないとビルド出来なかったのに。。
Questの何かが変わったのか。androidの何かが変わったのか。
Unityの何かが変わったのか。単に何かを忘れているだけなのか。
zfs作業メモ

$ sudo zpool create -f -o ashift=12 -m /mnt/tank tank ata-WDC_WD60EZAX-00C8VB0_WD-WX42AC2RZ67S

$ zpool status
  pool: tank
 state: ONLINE
config:

	NAME                                        STATE     READ WRITE CKSUM
	tank                                        ONLINE       0     0     0
	  ata-WDC_WD60EZAX-00C8VB0_WD-WX42AC2RZ67S  ONLINE       0     0     0

$ sudo mkdir /mnt/filesrv_admin
$ sudo mount -o user=***,vers=3.0 //***/filesrv_admin /mnt/filesrv_admin
$ rsync -av --progress -t /mnt/filesrv_admin/ /mnt/tank/filesrv_admin/

環境）
linuxMint

参考）
https://wiki.archlinux.jp/index.php/ZFS
https://kirishima.it/mt/2020/02/freenas_113_setup.html
https://qiita.com/bezeklik/items/22e791df7187958d76c1
https://islandcnt.exblog.jp/241208919/