OmniAICreator/Qiita-1.07M huggingface dataset:
会議についてのちょっとした纏め

会議をテーマにした背景
・最近多いのと自信上手く進めれてない＆話せないってことをヒシヒシと感じている。（表）
・みんなの技術を勉強したい。（裏）

## ①そもそもなぜ効率的ないい会議が重要か

タイムイズマネー
人は会議によって評価され会議によって出世する
年齢上がればチャンスの重要性が上がる

・問題点
社内会議の問題点について最も高いのは
「会議が長い」
「似たような会議が多い」
「延々と議論ばかりして結論が出ない」

・効率的ないい会議
効率的な会議というのは、その会議を行うことによって新たな解決策を見出すことができ、
同時に仕事の速度が上がる会議のこと。
自由に意見を言い合うことができ、また次のゴールを設定できるようになることが理想。

## ②会議の種類
・意思決定：案件に対して承認してもらう。
・情報共有：朝会やチームMTGなど
・アイデア出し/ワークショップ：改善会等

## ③会議前
・目的は何か（表向きの目的、裏向きの目的）
　（表）出してる案に対して承認を貰う（戦争でいうところの世界平和）
　（裏）隠れた目的を隠れて伝える（資源調達、戦力アピール）

裏の目的が重要

0. 目的
1. 資料は事前に配布する
2. 使う機材の操作方法を理解しておく
3. 参加者を厳選する
4. 発言のルールを決める

参考
事前準備で必要なのは、会議の目的共有、情報共有、問題提起、
そして必要があれば参加者への宿題のアナウンスをしておくことです。
会議に参加してもらってから説明するのではなく、すぐに議論が始められるような環境を整えておきましょう。

・オーディエンスを知る
　大きな影響力を持ってる人に話を通しておく（海外で日本人が戦えない理由の一つ）

・説明する内容はストーリーをスケルトンデッキで纏める
　できてから後で組み替えよと思っても難しいので
　タイトルでストーリーをまず組む
（自己紹介→マイナス要素→提案内容→結果）

・３回リハする
　話すことに集中せずに相手のリアクションを見て方向性を調整できるようになる。

## ④会議中

■**会議の目的とゴールを宣言する**
「この会議が何のために行われるのか（情報共有、意思決定、ブレインストーミングなど）」
「何を行えばネクストアクションにつながるのか（ゴール）」の2つを伝えましょう。

■**時間に沿ってアジェンダを進める**
目的とゴールが共有できれば、あとは時間通りにアジェンダを進めていきましょう。
議論が脱線する・盛り上がりすぎる・盛り上がらなさすぎるなどの問題が発生した場合に対応するのも司会の役割です。
時間通りにアジェンダを進めていくのは重要ですが、きちんと1つずつ結論が出てから次のアジェンダに移るようにしてください。会議参加者同士で「結論はどっちだったか？」という話になってしまうようではいけません。
必ずアジェンダが終わるごとに結論を伝えてからアジェンダを変えるようにしましょう。

■**ファシリテーションスキルを活用する**
（ファシリテーションとは集団活動をスムーズに進行し、成果が出せる状態に舵取りをすること）
・ポイント1 ：参加者の発言を肯定する
・ポイント2 ：話題からそれた際にきちんと戻す
・ポイント3 ：会議の最後に結論をまとめる

　集中していないように見られるため、極力PCを見ない。（議事録係以外）

## ⑤会議後
　全部メモった議事録は要らない。

　**What / By who / By when**
　何を議論したか、決まったこと / 誰がやるか / いつまでにやるか
Node.js update 手順 for Mac

Macにインストールして普段使用しているNode.jsのバージョンが古くなったのでアップデートした時の備忘録。
# 使用するミドルウェア
```
Homebrew ・・・　Mac OS のパッケージマネージャー
nodebrew ・・・ Node.js のバージョン管理ツール
Node.js ・・・ JavaScript 実行環境
npm ・・・ Node.js のパッケージマネージャー
```
# 現状のバージョン確認
### Homebrew
```
$ brew -v
Homebrew 3.3.16
```
最新版は[こちら](https://github.com/Homebrew/brew/releases)　// 3.4.11(2022/05/22時点)
### nodebrew
```
$ nodebrew -v
nodebrew 1.1.0
```
最新版は[こちら](https://formulae.brew.sh/formula/nodebrew)　// 1.2.0(2022/05/22時点)
### Node.js
```
$ node -v
v14.17.0

$ npm -v
6.14.13
```
最新版は[こちら](https://nodejs.org/ja/)　// 16.15.0(2022/05/22時点)
# 最新バージョンへアップデート
### Homebrew
```
$ brew update

~~ 省略 ~~

You have 56 outdated formulae installed.
You can upgrade them with brew upgrade
or list them with brew outdated.
```
ちょっと時間かかります。
終わったら再度バージョン確認。
```
$ brew -v
Homebrew 3.4.11
```
### nodebrew
```
$ brew upgrade nodebrew

~~ 省略 ~~

==> Upgrading nodebrew
  1.1.0 -> 1.2.0
```
終わったら再度バージョン確認。
```
$ nodebrew -v
nodebrew 1.2.0
```
# Node.js インストール
Node.jsはnodebrewを使ってインストールします。
現在インストールできるNode.jsのバージョンを確認します。
```
$ nodebrew ls-remote

~~ 省略 ~~

v16.0.0   v16.1.0   v16.2.0   v16.3.0   v16.4.0   v16.4.1   v16.4.2   v16.5.0
v16.6.0   v16.6.1   v16.6.2   v16.7.0   v16.8.0   v16.9.0   v16.9.1   v16.10.0
v16.11.0  v16.11.1  v16.12.0  v16.13.0  v16.13.1  v16.13.2  v16.14.0  v16.14.1
v16.14.2  v16.15.0

v17.0.0   v17.0.1   v17.1.0   v17.2.0   v17.3.0   v17.3.1   v17.4.0   v17.5.0
v17.6.0   v17.7.0   v17.7.1   v17.7.2   v17.8.0   v17.9.0

v18.0.0   v18.1.0   v18.2.0

io@v1.0.0 io@v1.0.1 io@v1.0.2 io@v1.0.3 io@v1.0.4 io@v1.1.0 io@v1.2.0 io@v1.3.0
io@v1.4.1 io@v1.4.2 io@v1.4.3 io@v1.5.0 io@v1.5.1 io@v1.6.0 io@v1.6.1 io@v1.6.2
io@v1.6.3 io@v1.6.4 io@v1.7.1 io@v1.8.1 io@v1.8.2 io@v1.8.3 io@v1.8.4

io@v2.0.0 io@v2.0.1 io@v2.0.2 io@v2.1.0 io@v2.2.0 io@v2.2.1 io@v2.3.0 io@v2.3.1
io@v2.3.2 io@v2.3.3 io@v2.3.4 io@v2.4.0 io@v2.5.0

io@v3.0.0 io@v3.1.0 io@v3.2.0 io@v3.3.0 io@v3.3.1
```
インストール可能なバージョンがたくさん出てきます。
今回は[こちら](https://nodejs.org/ja/)で確認できる現時点（2022/05/22時点）の推奨版`16.15.0`をインストールします。
```
$ nodebrew install-binary v16.15.0

Fetching: https://nodejs.org/dist/v16.15.0/node-v16.15.0-darwin-arm64.tar.gz
################################################################################################### 100.0%
Installed successfully
```
利用可能なバージョンリストを表示。
```
$ nodebrew list
v14.17.0
v16.15.0

current: v14.17.0
```
使用するバージョンを指定。
```
$ nodebrew use v16.15.0
use v16.15.0
```
終わったら再度バージョン確認。
```
$ node -v
v16.15.0

$ npm -v
8.5.5
```
npm も自動的にアップデートされているようです。
# まとめ
数年後または数ヶ月後にアップデートすることになるので備忘録としてまとめました。
ぜひご参考ください。
# 参考にしたサイト
https://qiita.com/Hide-Zaemon/items/cbb4497237843a729994
Vue 2.6でAnimated画像のアニメーションを再起動

# Vue 2.6でAnimated PNGまたはGIFのアニメーションをコンポネントの再表示・アップデートの時に再起動
UIはアニメーション画像（PNGまたはGIF）を表示する必要があり、一番簡単な方法は`img`タグを使用することです。

問題は、無限ループがない場合、アニメーションが最後のフレームで停止することです。
## VueのSFC（シングル・ファイル・コンポネント）
正方形のコンテナの中央にアニメーション画像を表示します。
### コンテナ
ここでは、コンテナの`position`スタイルプロパティを`relative`に設定するだけです：
```JavaScript:sample.vue
    <div
        style="position: relative; background-color: #ECECEC; height: 150px; width: 150px; overflow: hidden;"
    >
    </div>
```
※ また、アニメーションがコンテナの境界を越えないように、`overflow`を`hidden`に設定しました。
### 画像
##### 画像を中央に配置
 -　画像の`position`スタイルプロパティを`absolute`に設定し、コンテナの中央に配置します。
 -　画像を半分のサイズに変換して、画像中央をコンテナの中央に配置します。

```JavaScript:sample.vue
        <img
            style="
                position: absolute; 
                top: 50%; 
                left: 50%; 
                transform: translate(-50%, -50%);
            "
        />
```
##### 画像のサイズ変更
- `height`の高さに`scale`のスケールファクターを掛けます
- `width`の幅に`scale`のスケールファクターを掛けます
```HTML:sample.vue
        <img
            ...
            :height="animation.height * animation.scale"
            :width="animation.width * animation.scale"
        />
```
##### 画像の設定
- アニメーション画像のパスを設定します。
- `img`タグへの`Vue`の`ref`を設定します。
```JavaScript:sample.vue
        <img
            ref="image2D"
            ...
            :src="animation.image_path"
            ...
        />
```
### コンポネントのコード
コンポーネントの`props`から画像のパス、高さ、幅、スケールを取得する必要があります
```JavaScript:sample.vue
<script>
import Vue from 'vue'
export default {
  name: "Sample",
  props: {
    animation: {
      required: true
    },
  },
}
</script>
```
###### mountedのライフサイクルフック
コンポーネントがレンダリングされるときに呼び出されます。

アニメーションを再開するには、画像コンテンツを非同期でリセットする必要があることに注意してください。
```JavaScript:sample.vue
  mounted() {
    requestAnimationFrame(() => {this.$refs.image2D.src = this.$refs.image2D.getAttribute('src')});
  },
```
###### updatedのライフサイクルフック
一部のプロパティ情報が別のコンポーネントで変更されたときに呼び出されます。 私プロジェクトでは、画像の縮尺を変更するためのボタンを備えたコンポーネントがありました。

アニメーションを再開するには、画像コンテンツをリセットする必要があります。
```JavaScript:sample.vue
  updated() {
    this.$refs.image2D.src = this.$refs.image2D.getAttribute('src')
  }
```
## まとめたコード
最後に、サンプルコードの全て：
```JavaScript:sample.vue
</template>
    <div
        style="position: relative; background-color: #ECECEC; height: 150px; width: 150px; padding: 25%; overflow: hidden;"
    >
        <img
            ref="image2D"
            style="
                position: absolute; 
                top: 50%; 
                left: 50%; 
                transform: translate(-50%, -50%);
            "
            :src="animation.image_path"
            :height="animation.height * animation.scale_y"
            :width="animation.width * animation.scale_x"
        />
    </div>
</template>
<script>
import Vue from 'vue'
export default {
  name: "Sample",
  props: {
    animation: {
      required: true
    },
  },
  mounted() {
    requestAnimationFrame(() => {this.$refs.image2D.src = this.$refs.image2D.getAttribute('src')});
  },
  updated() {
    this.$refs.image2D.src = this.$refs.image2D.getAttribute('src')
  }
};
</script>
```
Hammerspoon で ShiftIt なウィンドウ制御

1. [公式サイト](http://www.hammerspoon.org/)からHammerspoonをダウンロードし、~/Applications ディレクトリへドラッグアンドドロップ
1. Hammerspoonを起動し、メニューバーアイコン -> Preferences...
1. 「Launch Hammerspoon at login」をチェックする
1. 「Enable Accesibility」を押して、Macの設定からHammerspoonにアクセス権を与える
1. キーバインドを設定

```lua:~/.hammerspoon/init.lua
hs.window.animationDuration = 0
units = {
  right50       = { x = 0.50, y = 0.00, w = 0.50, h = 1.00 },
  left50        = { x = 0.00, y = 0.00, w = 0.50, h = 1.00 },
  top50         = { x = 0.00, y = 0.00, w = 1.00, h = 0.50 },
  bot50         = { x = 0.00, y = 0.50, w = 1.00, h = 0.50 },
  righttop      = { x = 0.50, y = 0.00, w = 0.50, h = 0.50 },
  lefttop       = { x = 0.00, y = 0.00, w = 0.50, h = 0.50 },
  rightbot      = { x = 0.50, y = 0.50, w = 0.50, h = 0.50 },
  leftbot       = { x = 0.00, y = 0.50, w = 0.50, h = 0.50 },
  maximum       = { x = 0.00, y = 0.00, w = 1.00, h = 1.00 }
}

mash = { 'ctrl', 'cmd' }
hs.hotkey.bind(mash, 'right', function() hs.window.focusedWindow():move(units.right50, nil, true) end)
hs.hotkey.bind(mash, 'left', function() hs.window.focusedWindow():move(units.left50, nil, true) end)
hs.hotkey.bind(mash, 'up', function() hs.window.focusedWindow():move(units.top50, nil, true) end)
hs.hotkey.bind(mash, 'down', function() hs.window.focusedWindow():move(units.bot50, nil, true) end)
hs.hotkey.bind(mash, 'i', function() hs.window.focusedWindow():move(units.righttop, nil, true) end)
hs.hotkey.bind(mash, 'u', function() hs.window.focusedWindow():move(units.lefttop, nil, true) end)
hs.hotkey.bind(mash, 'k', function() hs.window.focusedWindow():move(units.rightbot, nil, true) end)
hs.hotkey.bind(mash, 'j', function() hs.window.focusedWindow():move(units.leftbot, nil, true) end)
hs.hotkey.bind(mash, 'm', function() hs.window.focusedWindow():move(units.maximum, nil, true) end)
```
【初心者】AWSを使ったサーバー学習

はじめに
-
全くの初心者からAWSを使い始めて1か月ほど経過しました。
具体的にこれまで何をしたのかを紹介します。

同じように初心者で何をすればいいのか
困っている人は参考にしてみてください。

実践したこと
-
上から順番に実施していきました。

1. EC2を使ってインスタンスを立ち上げよう
2. Apacheのインストールしてみよう
3. ユーザーの作成とパスワードの設定をしよう
4. 2台目のインスタンスを立ち上げてpingで疎通確認してみる 
5. SSH接続（パスワード認証）をしよう。（インスタンスを2台起動しておく必要あり）
6. SSH接続（公開鍵認証）をしよう
7. ファイルの転送をしよう
8. ログイン制限をしてみよう
9. ansibleってなんだろう。調べてみる
10. ansibleのインストールしてみよう
11. playbookをつかってディレクトリを作成しよう
12. playbookをつかってユーザー作成とパスワード設定をしてみよう
13. playbookのplayとtaskってなんだろう。調べてみる。
14. playbookをつかってユーザー作成と鍵交換をしてみよう
15. NFSサーバーを構築してみよう。

おわりに
-
ざっとこんな感じになります。
全くわからない状態よりかは多少分かるようになってきました。

『こんな練習方法もあるよ』っていう意見があればぜひ教えてください。
Text to speech with python

# 初めに

PythonでText to Speechを実装してみました。

# 設置

https://pypi.org/project/pyttsx3/

```python
pip install pyttsx3
```
If you are ubuntu user, you need to install libespeak-dev package.

```
sudo apt install libespeak-dev
```

# 使い方
とても簡単です。

```python
import pyttsx3
#初期化
engine = pyttsx3.init()

#声の選択
voices = engine.getProperty('voices')
engine.setProperty('voice',voices[0].id)

#喋りのレートを設定
engine.setProperty('rate', 150)

#喋らせる
engine.say('おはようございます！')

engine.runAndWait()
```

Voiceの確認。個人のパソコンの環境によって異なります。下記のプログラムでどんな言語に対応する声が用意されているか確認が可能です。

```python
import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')

print(len(voices))

for voice in voices:
    print(f'voice: {voice.name}')
    print(f'id: {voice.id}')
    print('')
```
私の環境では、三つの言語、声が用意されていました。

index[0] : 日本語　ハルカさん
index[1] : 英語　Ziraさん
index[2] ：韓国語　Heamiさん

```python
3

voice: Microsoft Haruka Desktop - Japanese
id: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_JA-JP_HARUKA_11.0

voice: Microsoft Zira Desktop - English (United States)
id: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_ZIRA_11.0

voice: Microsoft Heami Desktop - Korean
id: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_KO-KR_HEAMI_11.0
```


使い勝手を良くするため、speak関数を定義します。

```python
def speak(str):
    engine.say(str)
    engine.runAndWait()
```

#　全体コード

```python
import pyttsx3

#初期化
engine = pyttsx3.init()
voices = engine.getProperty('voices')
#声の選択
engine.setProperty('voice',voices[0].id)
print(voices[0].id)

#喋りのレートを設定
engine.setProperty('rate', 150)

def speak(str):
    engine.say(str)
    engine.runAndWait()

speak('おはようございます。')
speak('巨人軍は永久不滅です。')
speak('横浜ベイスターズ、頑張ってください。')

```
Azure Functions (Python, pytest)でカバレッジを可視化する方法

[こちらの記事](https://qiita.com/moshi/items/21a6ff0a20cd840f71ea#%E3%82%AB%E3%83%90%E3%83%AC%E3%83%83%E3%82%B8%E5%8F%AF%E8%A6%96%E5%8C%96%E5%AE%9F%E8%A1%8C)を参考に、Azure Functions (Python)のプロジェクトでも可視化できないか試行錯誤しました。

## 要点

`.vscode\settings.json`の`python.testing.pytestArgs`には`--cov=.`を指定する。

### 補足

`--cov`にはソースコードのフォルダーを指定するものと思っていました。
そのため、AzureFunctionsの関数別のフォルダー名を複数指定していました。
それだと、Visual Studio Code上でカバレッジが可視化されませんでした。
拡張機能 coverage-gutters の Github Issuesで質問したところ、
開発者の方が確認してくださり、回答をいただけました。

URL: <https://github.com/ryanluker/vscode-coverage-gutters/issues/373>

それから、Pythonの仮想環境ではなく、ローカルのPythyonに[coverageパッケージ](https://pypi.org/project/coverage/)も必要なようです。

## サンプル

今回調べたことを元にサンプル プロジェクトを作成しました。
Azure Functions（Durable）のHTTPスターター、オーケストレーター、アクティビティのサンプル関数のテストコードとカバレッジの設定を行ったものです。

URL: <https://github.com/ecormaksin/azure-durable-functions-pytest-coverage-sample>
オブジェクト指向 メモ

# 概要

- オブジェクト指向の考え方を簡単に図にしたのでメモとして残す。

# 簡単なまとめ

![other__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f5a805eb-5852-39fa-e635-7f4d17ccf852.png)
DOSバッチファイルで一括リネームスクリプト

自分用sendto
DOSバッチファイルの評価用一括リネームスクリプト
　*windows10環境で動作確認

複数の画像や音楽や圧縮ファイルがあって、
自分の評価をファイル名に付けときたかったんですよね

”出来るだけ簡単に”

このSSS.batを元にss.batやs.batなどを作っておけば
リネームがはかどるー

~~~SSS.bat
@echo off
rem エクスプローラーのパスでshell:sendtoって入れてそこに置くと右クリックの「送る」に表示される
rem こいつにファイルを送るとSSS_を頭につけてリネームする
rem rename文１行だけだと１ファイルだけ、それ以外でファイル数分ループさせる

%~d1
cd %~dp1

:loop
  if "%~1" == "" goto end
  rename "%~n1%~x1" "SSS_%~n1%~x1"
  shift
  goto loop
:end
~~~


ちなみに機種依存文字に悩まされるときには
chcp 65001
こんな感じのをあたまに入れるといいです

65001	UTF-8
932	Shift-JIS
1200	UTF-16

依存文字対策はこちらで発見しました、助かる
https://nayutari.com/batch-utf8
[Udemyで勉強]Raspberry Pi でCO2モニタリングして換気してリモートワークの集中力UP！

# はじめに
[Udemyで勉強] シリーズです。

前回の記事（[[Udemyで勉強] Raspberry Piで物体検出！](https://qiita.com/sasuke_sss/items/9d9f52b9015cc84719d0)）では、RaspberryPi を購入して、物体認識を行いました。
RaspberryPiをせっかく購入したので、またこれを使って何かをやりたいなぁ……と思っていたところ、こんなコースがUdemyのおすすめに出てきて、今流行りの感染症対策とか、換気に役立つみたいでちょっと興味が惹かれて買ってみました。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/a12368ee-7438-07c3-9c53-e7ac56bdec09.png)

説明を見ると、前回購入した RaspberryPi 3B+でも大丈夫とのこと。(動画中では4Bを使ってるとのこと)

あとは、CO2-miniという、CO2センサーが必要らしい……。

プレビュー動画内の解説だと、「CO2-miniはコロナ禍の影響で品薄になっていて、安く買えるAmazonやヨドバシ.comでは売り切れてます」と言われていましたが、Amazonを見てみたら在庫が復活していました。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/11aa17a3-98df-dbfe-52bf-c7678827b76e.png)
ということで、これを購入。

# 動画視聴

動画を視聴すると、最初の方の章は、RaspberryPiの初期設定や、PCとの接続方法が解説されていましたが、前回の別の動画で学習済み＆設定済みなので、流し見しました。

RaspberryPiにCO2センサーをUSB接続し、既に用意してあるプログラムを実行するだけで、無事にCO2センサーからの値を読み取ることができました。
![PXL_20220420_064023618.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/48d785e3-b6c7-b37a-bbac-8cf823b281f8.jpeg)

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/9858cc0d-a040-9328-6d1c-fad4e4e31b52.png)

それから、CO2センサーで読み取った値をGoogleスプレッドシートに書き込むのですが、その部分は知識が無かったので勉強になりました。

# 計測

在宅中に自室（10畳ぐらい）で計測してみました。部屋には自分一人だけが在室。(もちろん途中でトイレ行ったり休憩行ったりして部屋出ることもあり）

## 換気しない場合
窓を全く開けずに換気しなかった場合。
約10分間隔で計測した結果が以下でした。
![9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/3496c488-48c2-3fc6-ad8c-096709e01eed.png)
どんどんCO2濃度が増えていき、15時から18:30までの約3時間半ぐらいで、952から1925ppmまで、1000近く増えました。

### 睡眠中
また、別の日に、寝る直前に窓を開けて換気して800ぐらいに下げておいて、その後、窓を閉めて、約6時間後に起床後に確認すると、2000近くになっていたこともありました。

## 換気した場合

窓を開けて換気した場合。基本的にずっと窓開けっ放しで計測。

![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/898cd9dc-edd9-b532-071f-200b18761b8f.png)

窓開けてると、CO2は全然増えません！15時から17時までの2時間ぐらいずっと窓を開けていましたが、550～650ppmあたりで推移しています。換気しない場合のように、どんどんCO2濃度が増えていくという現象は起きていません。
（後半グラフがジグザグしているのは、休憩で部屋を出て戻ってきたりしたせいです。また、最後は寒くなって、窓を閉めたのでグラフの最後が跳ね上がっています）

換気したらCO2濃度は増えないことがわかりました。大成功！
……と思ったのですが、いかんせん窓開けっ放しだと寒い！ガンガン室温も下がります！長時間は開けれてられません！
この日(4月27日)の気温が最高15.3℃、最低11.3℃でした。（北海道なので…）

### 再計測
1ヶ月後の5月20日にまた計測してみました。この日は前回(4/27)よりも暖かかった(最高21.4℃、最低13.8℃)ので、15時～19時までの4時間近く、ずっと窓開けっ放しにできました。
![12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/b7861590-c70d-415d-ac0c-66278732731d.png)
ほとんどの時間で、600ppm以下を維持できています。

# まとめ
自室だと1人しかいないので、コロナ感染対策というよりも、眠気対策ですね。

グーグル検索するとCO2-miniを使っての眠気対策の記事がいろいろHITします。
そもそも、どれくらいのCO2濃度に保てば良いのだろう？と、調べていましたが、この記事によると、

https://www.watch.impress.co.jp/docs/series/itsmo/1297260.html

> 1,500ppmくらいで眠くなるという記述も見つけましたが、もっと高い数値を例示している文章もあります。また、人によっても体調によっても異なるようです。
>
>できれば室内は1,000ppm以下に抑えた方がいいのは確かですが、事務所衛生基準規則では5,000ppm以下ですし、1,000ppmを少し超えたくらいでは目くじらを立てるほどではなさそうです。

と書いてありました。

個人的には、2,000ppmまで行くと「確かに眠たくなるな」と感じます。
暖かい季節はずっと窓開けておいても大丈夫だけど、自分の住んでる地域的に、春秋冬の寒い時期は窓開けると部屋も寒くなるから窓開けっ放しにできないので、その時期は夏季と比べて、こまめな換気の重要性は増すなぁと感じました。
Dnsmasqがうまく応答しない時の確認メモ

DnsmasqをUbuntuでサクッと入れて、LAN上のDNSサーバーと使おうとしたが、応答が動いていないようだった。

プロセスは稼働中、つまりConfにエラーは無し。
FW(ufw)も止めている。

OCPを入れた時はこんなに難儀しなかったのに・・・と試行錯誤の末、

設定ファイル/etc/dnsmasq.confに以下がないことが原因だった。

```
listen-address=127.0.0.1,192.168.200.140(<-自IFのIP）
```

結構、この記述なくても動いている的なサイトが多いですがこのOSのこのバージョンだからなのか、これが必要でした。
nRF52シリーズで Nordic UART Service を Multi モードで使う

***はじめに***
 nRF52 の BLE 機能を用いて 文字列を 複数のnRF52(peripheral側) から ホストとなる1台のnRF52(central側) に送ることを試みた。

 なお、nRF52 のサンプルコードに
 [SDK\examples\ble_central\ble_app_multilink_central] がある。このサンプルコードと
 [SDK\examples\ble_peripheral] を用いれば、複数のperipheral側から　Button を押すと Central側に その結果が反映される。
 参考：[https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.1.0%2Fble_sdk_app_nus_eval.html](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.1.0%2Fble_sdk_app_nus_eval.html)

このサンプルコードでは、文字列を送ることが出来ない。

 一方で、サンプルコードに
 [C:\nRF5_SDK_17.1.0_up20220520\examples\ble_central\ble_app_uart_c] と
 [C:\nRF5_SDK_17.1.0_up20220520\examples\ble_peripheral\ble_app_uart] がある。
これは、1台のnRF52(Central側) と 1台のnRF(peripheral側)間で nus(Nordic UART Service) を用いて
文字列の送受信を行うサンプルであり、複数台のnRF(peripheral側)から1台のnRF52(Central側) への送受信は、不可能である。
参考：[https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.1.0%2Fble_sdk_app_nus_eval.html](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.1.0%2Fble_sdk_app_nus_eval.html)

----
***サンプルコード修正のポイント***

nRF52 に記載の２種類のサンプルコード
 [SDK\examples\ble_central\ble_app_multilink_central] と  [SDK\examples\ble_peripheral] をミックスさせて
コードを修正した。

ポイントとなるのは、nus を定義しているマクロを変更する必要がある。加えて、関連する項目の修正。

補足： [SDK\examples\ble_peripheral] をベースにすると動作が不安定になり
       [SDK\examples\ble_central\ble_app_multilink_central] をベースに修正を加えると動作が安定する。
       原因は、不明。

修正前
~~~main.c
BLE_NUS_C_DEF(m_ble_nus_c);

static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
    ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);
}
|
    err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
|
    err_code = ble_nus_c_init(&m_ble_nus_c, &init);
    APP_ERROR_CHECK(err_code);
|
~~~

修正後
~~~main.c
BLE_NUS_C_ARRAY_DEF(m_ble_nus_c, NRF_SDH_BLE_CENTRAL_LINK_COUNT);

static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
    ble_nus_c_on_db_disc_evt(&m_ble_nus_c[p_evt->conn_handle], p_evt);
}
|
    err_code = ble_nus_c_handles_assign(&m_ble_nus_c[p_gap_evt->conn_handle], p_ble_evt->evt.gap_evt.conn_handle, NULL);
|
    for (uint32_t i = 0; i < NRF_SDH_BLE_CENTRAL_LINK_COUNT; i++)
    {
        err_code = ble_nus_c_init(&m_ble_nus_c[i], &init);
        APP_ERROR_CHECK(err_code);
    }
|
~~~

---
☆2022年 5月23日(月) 午前10時15分 初版(Ver1.00) 作成

---
【高校数学】点と直線(線分)の距離の求め方　3次元


# はじめに
こんにちは。takenakadxです。

私は、趣味でゲーム開発をしているため、高校数学レベルの線形代数学に触れることがあります。しかし、数学があまり得意ではないので、ネットから数式をコピペしてくることがほとんどです。

今日もゲームの実装に「3次元で点と直線の距離を求める関数」を実装する必要に迫られた為、ネットからコピペしようと探してました。
しかし、2次元での点と直線の距離を求める公式などは見つかるのですが、3次元バージョンが見つからなかったので、自分で実装しました。
備忘録としてここに残しておこうと思います。

直線と点の距離を求める場合は次の2つの方法があります。
- 直線の媒介変数表示を利用して解く方法
- 三角形を仮定して解く方法

それぞれについて説明していきます。
# 直線の媒介変数表示を利用して解く方法
はじめに、問題設定を行っておきます。

ある点 P(座標$\vec{p}$)と直線Lが3次元ユークリッド空間上にあるとして、直線Lは点$X_0$(座標$\vec{x_0}$)を通り、$\vec{v}$に平行な直線とします。

![baikai.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305662/6199c840-9dd5-8e5e-4740-d327d7b58292.jpeg)


この時、点Pと直線Lの距離を求めていこうと思います。

まず、直線L上の点の座標を求めておきます。直線L上の任意の点は媒介変数tを用いて
``` math
L : t \vec{v} + \vec{x_0} 
```
と表せます。

次に、点Pと直線Lが最も近くなる点をC(座標は直線状の点であるので$t_c \vec{v} + \vec{x_0}$で表せる)とします。
すると、ベクトル$\vec{PC}$とベクトル$\vec{v}$は直交するので次式が成り立ちます。

``` math
\vec{v} \cdot \vec{PC} = 0 \tag{1}
```

ここで、ベクトル$\vec{PC}$は点Pの座標と点Cの座標の差であるので
``` math
\vec{PC} = \vec{p} - (t_c \vec{v} + \vec{x_0})
```
となり、これを(1)に代入して$t_c$について整理すると

``` math
t_c = \frac{1}{|\vec{v}|^2} \vec{v} \cdot (\vec{p} - \vec{x_0})
```

これによって点Cの座標が導出できたので、点Cと点Pの距離は
``` math
|(\vec{p} - \vec{x_0}) - \frac{1}{|\vec{v}|^2} \vec{v} \cdot (\vec{p} - \vec{x_0}) \vec{v}| \tag{2}
```

で求まる。

# 三角形を仮定して解く方法
![baikai.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305662/29d04c5a-5f6b-375f-7569-0008bf535710.jpeg)


図のように、直線状に任意の点A,Bを作り、三角形を仮定して解く。
内積の定義より、$\cos \theta $は
``` math
\cos \theta = \frac{\vec{a} \cdot \vec{b}}{|\vec{a}||\vec{b}|} \tag{3}
```
また、三角関数の定義より次が成り立つ。
``` math
\sin \theta = \frac{|\vec{c}|}{|\vec{b}|} \tag{4}
```

三角関数の法則 $\cos^2 \theta + \sin^2 \theta = 1$と(3)、(4)により、
``` math
\frac{(\vec{a} \cdot \vec{b})^2}{(|\vec{a}||\vec{b}|)^2} + \frac{|\vec{c}|^2}{|\vec{b}|^2} = 1
```
となるので、これを$|\vec{c}|$について解けば

``` math
|\vec{c}| = |\vec{b}| \sqrt{1-\frac{(\vec{a}\cdot\vec{b})^2}{(|\vec{a}||\vec{b}|)^2}} \tag{5}
```

# それぞれのやり方が同じかどうかを確かめる。
図を見比べれば分かるが、
- $\vec{v} = \vec{a}$
- $\vec{p} - \vec{x_0} = \vec{b}$
である。

(2)式にそれらを代入してみると、
``` math
|\vec{c}| = | \vec{b}  - \frac{\vec{a} \cdot \vec{b}}{|\vec{a}|^2} \vec{a} | = ||\vec{b}|\vec{e_b} - \vec{e_a}\cdot(|\vec{b}|\vec{e_b}) \vec{e_a}| = |\vec{b}| |\vec{e_b}-(\vec{e_a}\cdot\vec{e_b})\vec{e_a}| \tag{6}
```
であることが分かる。ここで、各ベクトルの大きさが1になったベクトルを$\vec{e_a},\vec{e_b}$で表している
($\vec{v} = |\vec{v}|\vec{e_v}$)

ここで、ベクトルの大きさの公式($|\vec{v}| = \sqrt{\vec{v}\cdot\vec{v}}$)を思い出すと、(6)式は

``` math
|\vec{b}||\vec{e_b}-(\vec{e_a}\cdot\vec{e_b})\vec{e_a}| = |\vec{b}|\sqrt{(\vec{e_b}-(\vec{e_a}\cdot\vec{e_b})\vec{e_a})\cdot(\vec{e_b}-(\vec{e_a}\cdot\vec{e_b})\vec{e_a})} = |\vec{b}| \sqrt{X}
```

ここで、平方根の中身$X$は

``` math
X = \vec{e_b}\cdot\vec{e_b} + \vec{e_a}\cdot\vec{e_a} (\vec{e_a}\cdot\vec{e_b})^2 -  2(\vec{e_a}\cdot\vec{e_b})^2 = 1 - (\vec{e_a}\cdot\vec{e_b})^2 
```

これより、
``` math
|\vec{c}| = |\vec{b}|\sqrt{1-(\vec{e_a}\cdot\vec{e_b})^2 } = |\vec{b}|\sqrt{1-\frac{(\vec{a}\cdot\vec{b})^2}{(|\vec{a}||\vec{b}|)^2} }
```

となり、(5)式と(2)式が等価であると分かる。

# まとめ
色々、数式が出てきて分かりにくかったと思うが、まとめると次のようになる。

点$\vec{x_0} $を通り、$\vec{v}$に平行な直線と点$\vec{p}$との距離は、(2)式によって与えられ、
それと等価な式として(5)式も利用できる。
Gemをインストールする時に関連するGemを自動でインストールする

Rubyでは標準でRubyのライブラリを管理するRubyGemsというコミュニティがあり、gemというコマンドを使用することでRubyGemで管理されているライブラリを取得できます。

RailsではGemfileというアプリケーションで使用するGemの情報を記述している管理ファイルです。
Gemfileにgemコマンドの後ろに取得したいGem名を記述し(既に取得しているGemのバージョンの変更も可)、installを実施することができますが、Gemは様々なGemが複雑に関連して動作する為、取得したいGemと関連するGemも取得する必要がある場合がある。


インストールを実施する際
```ターミナルの作成中アプリのディレクトリ
% bundle install
```
このコマンドを使うと取得したいGemに関連するバージョンのGemを一緒にインストールしてくれる。
これはbundlerというGemが働いてくれている。

:::note info 
bundlerというGemを使うと関連するGemファイルも一緒に取得してくれる
:::
PHP_CodeSnifferのコーディング規約をカスタマイズする方法

## 最初に
この記事は[PHP_CodeSnifferの導入方法と解説](https://qiita.com/Ken_tk/items/7c8681bf5a78f86db965)の続きになります。

## コーディング規約をカスタマイズする
コーディング規約をカスタマイズをするには
下記の場所から**各種規約ルールを書き換える**必要がある。

- [**CakePHP Code Sniffer**](https://github.com/cakephp/cakephp-codesniffer)
`vendor\cakephp\cakephp-codesniffer\CakePHP`

- [**PHP_CodeSniffer**](https://github.com/squizlabs/PHP_CodeSniffer)
`vendor\squizlabs\php_codesniffer\src\Standards`

```xml:ruleset.xml
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="CakePHP">
    <description>CakePHP coding standard</description>

    <config name="installed_paths" value="../../slevomat/coding-standard,../../../slevomat/coding-standard,../vendor/slevomat/coding-standard"/>

    <exclude-pattern>\.git</exclude-pattern>
    <exclude-pattern>/*/tmp/</exclude-pattern>
    <exclude-pattern>tests/*/templates/*</exclude-pattern>

    <!-- PSR12 Standard -->
    <rule ref="PSR12">
        <exclude name="PSR12.Files.FileHeader.SpacingAfterBlock"/>
        <exclude name="PSR12.Files.FileHeader.IncorrectOrder"/>
        <!--
        Property and method names with underscore prefix are allowed in CakePHP.
        Not using underscore prefix is a recommendation of PSR2, not a requirement.
        -->
        <exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/>
        <exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
    </rule>

    <!-- Relax rules from PSR12 -->
    <rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
        <exclude-pattern>*/config/Migrations/*</exclude-pattern>
    </rule>
    <rule ref="PSR1.Files.SideEffects">
        <exclude-pattern>*/config/*</exclude-pattern>
        <exclude-pattern>*/tests/*</exclude-pattern>
    </rule>
    <rule ref="PSR1.Methods.CamelCapsMethodName">
        <exclude-pattern>*/src/Controller/*</exclude-pattern>
        <exclude-pattern>*/src/Command/*</exclude-pattern>
        <exclude-pattern>*/src/Shell/*</exclude-pattern>
        <exclude-pattern>*/tests/*</exclude-pattern>
    </rule>

    <!-- Additional sniffs outside of PSR12 -->
</ruleset>

```

## コーディング規約の場所を変更
コーディング規約の場所を変更する場合は
`installed_paths`に追加します。
vendor配下に置きたくない場合などに活用できます。
```
$ phpcs --config-set installed_paths /path/to/one,/path/to/two
```

## デフォルトのコーディング規約の設定
デフォルトの標準を変更する場合は、
`default_standard`を設定します。
```
$ phpcs --config-set default_standard CakePHP
```

## 最後に
各プロジェクトにおいて、コーディング規約を定義する場合は
PHP_CodeSnifferを揃えなければエラーが正しく表示されないため、おすすめです。

## 参考
https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options
[Laravel migration]開発途中で削除カラム追加になった時も同じファイルで対応したい場合の方法

## この記事について
よくLaravelの開発でDBカラムの変更を行う際に、
プロジェクトが始まった時はA〜Cのカラムだけだったんだけど、
開発を進めていくうちにDのカラムも変更しないといけなくなった・・・
だから開発開始当初につくったマイグレにカラムを追加したい。
でもマイグレをもう流してしまってDBに変更が反映されているので、
`php artisan migrate:rollback` -> `php artisan migrate` 
でマイグレ流し直すと既に変更のあったカラムとマイグレに齟齬があり、
マイグレーションがエラーになる。。。
なんてことが良くある人もいるかと思います。
そんな時に思いついた解決策を今回は載せてみようと思います！


## コード
今回はカラムを削除した場合の例で記載させていただきました。
以下は製品テーブルの不要なカラムを削除するという例です。
カラムがあったら削除するという様な判別用のClosureを用意しておきそのClosureに削除対象カラムを指定してあげることで
開発中に削除カラムが追加になったとしてもこのファイルにそのカラムを追加して
`php artisan migrate:rollback` -> `php artisan migrate` をしてあげればマイグレのファイルを不用意に追加しなくても良くなります！
```php
public function up()
{
    // 開発の過程で削除対象カラムが変更にった場合に同じマイグレを流し直したいため存在チェック＆削除のClosureを定義しておく
    $dropColumnIfExists = function (Blueprint $table, string $column) {
        Schema::hasColumn('products', $column) && $table->dropColumn($column);
    };

    Schema::table('products', function (Blueprint $table) use ($dropColumnIfExists) {
        $dropColumnIfExists($table, 'column_2');
        $dropColumnIfExists($table, 'column_3');
        // 開発中に column_4 が入らなくなったらここに追加すればファイル追加しなくてもよくなる
        $dropColumnIfExists($table, 'column_4');
    });
}
```

## 終わりに
こんなコード全く需要ないかもしれないですが、誰かのお役に立てたら幸いです。
node(ts)でlambdaを非同期で起動

# はじめに
@aws-sdk/client-lambdaを使った具体例があまり見つからなかったので、自分の再利用時用に簡単な例をという感じでの記事です。

※ローカル実行したサンプルです。

# 環境
- node:v16 (ts)
- @aws-sdk/client-lambda
    - LambdaClient
    - InvokeCommand
    - InvokeCommandInput

``` yarn add @aws-sdk/client-lambda```

# 実行権限　（未検証）
※ローカルで試したので検証していないですが、AWS上で実行する場合は、実行元に下記のようなロールが必要なはず。
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PermissionToInvoke",
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxx:function:LambdaFunction"
    }
  ]
}
```

# 実装
```
import {
  LambdaClient,
  InvokeCommand,
  InvokeCommandInput
} from '@aws-sdk/client-lambda'

async invoke(bucketName:string, key:string) {
  
  const lambdaClient = new LambdaClient({
    region: "ap-northeast-1",
  });

  // s3のObjectCreateで発火するリクエストの一部を擬似的に作って試した。
  const payload =
    JSON.stringify({
      Records: [
        {
          s3: {
            bucket: {
              // name: "test-bucket"
              name: bucketName
            },
            object: {
              // key: "images/upload/sample1.webp"
              key
            }
          },
        }
     ]
    })
   const params: InvokeCommandInput = {
      // xxxxxx = AWSアカウント名
      // LambdaFunction = 起動するlambda名（lambdaのarn指定で実行可能）
      FunctionName: "arn:aws:lambda:ap-northeast-1:xxxxxx:function:LambdaFunction",
      InvocationType: "Event", // 非同期
      Payload: Buffer.from(payload)
    };
    const command = new InvokeCommand(params);
    await lambdaClient.send(command)
}
```

# 所感
実装できるとあっさり。
最初の例がInvokeCommandじゃなく、よく読まずに使おうとしてリクエストが想定と違うなーで少し詰まったくらい。

aws-sdkのv3系、実行方法はあるけどパラメータを指定した実行例があまり見つからないので、個人的に例が欲しいところです。
（それくらい仕様書 or プログラム見てパッとやれよって話なのかもですけど、、、）

# 参考
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-lambda/
https://github.com/aws/aws-sdk-js-v3/issues/2252
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html
https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/models/models_0.ts#L3913
RailsのAction Cableで任意のメッセージ形式でやりとりする

## 背景

REST API, WebsocketのAPIを提供するとあるサービスのMockを素早く作るため、Railsを選定したが、メッセージの形式がRailsと合わなかった。

メッセージ送信では、 `command`, `data`, `identifier`を送る必要があるが、

```json
{                        
  "command": "message",  
  "data": "{\"message\":\"test message\",\"action\":\"speak\"}",
  "identifier": "{\"channel\":\"RoomChannel\"}"
}
```

例えば、　`command` をやめて　`cmd` だけで任意のアクションを指定できるようにしたい。


## 注意

今回はローカル起動用のMockの作成を目的としていたためoverrideを試しました。
副作用の検証まではしていませんし、通常はRailに乗る方が良いので使い所は注意しましょう。


## サーバーが受け取るメッセージを任意の形式に変更する

[ActionCable::Conection::Subscriptions#execute_command](https://github.com/rails/rails/blob/v7.0.3/actioncable/lib/action_cable/connection/subscriptions.rb#L15-L26) で受け取る `data` を元に、　`command` を決める。

例えば以下のような感じにOverrideする。

```ruby
module ActionCable
  module Connection
    class Subscriptions
      def execute_command(data)
        if %w[create_message delete_message].include?(data['cmd'])
          perform_action({
            'command' => 'message',
            'identifier' => identifier(data),
            'data' => data.merge({ 'action' => data['cmd'] }).to_json
          })
        else
          logger.error "Received unrecognized message_type in #{data.inspect}"
        end
      rescue Exception => e
        @connection.rescue_with_handler(e)
        logger.error "Could not execute command from (#{data.inspect}) [#{e.class} - #{e.message}]: #{e.backtrace.first(5).join(' | ')}"
      end

      private

      def identifier(data)
        # ...
      end
    end
  end
end
```


## クライアントに送信するメッセージを任意の形式に変更する

例えばチャンネルのアクションで　`broadcast` する場合。
こちらは [ActionCable::Channel::Base#transmit](https://github.com/rails/rails/blob/v7.0.3/actioncable/lib/action_cable/channel/base.rb#L211-L220) なので　`app/channels/application_cable/channel.rb` 等でoverrideできる。

例えば、以下の例ではチャンネル側で送信したメッセージをそのままの形式で送信する。

```ruby
module ApplicationCable
  class Channel < ActionCable::Channel::Base
    private

    def transmit(data, via: nil)
      status = "[Extended] #{self.class.name} transmitting #{data.inspect.truncate(300)}"
      status += " (via #{via})" if via
      logger.debug(status)

      payload = { channel_class: self.class.name, data:, via: }
      ActiveSupport::Notifications.instrument('transmit.action_cable', payload) do
        connection.transmit data
      end
    end
  end
end
```

他にも以下は `app/channels/application_cable/` 下の　`ApplicationCable::Xxx` でoverrideできる。

* 購読時のメッセージ : [ActionCable::Channel::Base#transmit_subscription_confirmation](https://github.com/rails/rails/blob/v7.0.3/actioncable/lib/action_cable/channel/base.rb#L284-L293)
* PINGのメッセージ : [ActionCable::Connection::Base#beat](https://github.com/rails/rails/blob/v7.0.3/actioncable/lib/action_cable/connection/base.rb#L125-L127)

## その他

* PINGの間隔 : [ActionCable::Server::Connections::BEAT_INTERVAL](https://github.com/rails/rails/blob/v7.0.3/actioncable/lib/action_cable/server/connections.rb#L8)
非同期通信ではない、POSTリクエストをする関数

## はじめに

Form送信を活用して、非同期通信ではなく、POSTリクエストする方法を紹介します。

他のサービスと連携する実装をしていて、AJAXリクエストではなく、リダイレクトを期待されており、POSTリクエストをしたい時などに使えます。

## コード

```formPost.ts
const formPost = (value, url) => {
  const form = document.createElement("form");
  form.method = "POST";
  form.action = url; //`https://xxxxxxxx`;

  const input = document.createElement("input");
  input.type = "hidden";
  input.name = "submitValue";
  input.value = JSON.stringify(value);
  form.appendChild(input);

  form.style.display = "none";
  document.body.appendChild(form);
  form.submit();
};
```

## 解説

「仮想的なformを作成し、値を入れて、formを送信する」関数です。

処理の流れ
1. formを作成する
1. formのメソッド(POST)と送信先を設定する
1. inputを作成する
1. inputにnameとvalueを設定する
1. formの中に作成したinputを入れる
1. formをみえないように設定する
1. 自分のサービスのHTMLの中に作成したformを入れる
1. formを送信する

`JSON.stringify(value)`で1つの文字列にしており、
`{submitValue: valueを文字列にしたデータ}`({name: value})を送信しています。
文字列に変換しているので、受け取る側では、`JSON.parse`が必要です。

## 改修案

valueがオブジェクトの時、valueを配列に変換しループして複数のinputを作成する方法もできそうです！
そうすると、JSON. stringifyやJSON.parseが不要になりそうです。
【保存版】Qiitaの記事作成が楽になる方法まとめ

Qiita記事作成に役立つ記事やコマンドなどをまとめました．

# 前提
windows11を使用しています．
コマンドはWindowsのみ記述しています．
# スクリーンショット
矩形選択: win + shift + s
スクショしたあとはgithubのissue作成のページにペーストすれば，画像をurl化できます．

# markdown記法

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

忘れがちなmarkdown記法についてのチートシート．

# 書き方

https://qiita.com/t12u/items/8c28484100dfd3a6351b

文章構成の考え方や具体的な方法論が書かれていてとても参考になります．
初めて記事を書く人は引用のマナーの部分は特に読んで頂きたい．

https://help.qiita.com/ja/categories/qiita/

意外とみんな見ない公式ページ．記事投稿のガイドラインや役立つ機能が書いてあるのでおすすめ
Androidアプリを開発する #3（画面遷移）

# はじめに
今回は画面遷移の部分を作成していきます。前回の記事はこちらから

https://qiita.com/sekkenn1102/items/16fcf2a040378e1c27a4

# 画面を遷移させる
### 画面を遷移させる前に
* 前回までMainActivityファイルに登録画面、ListActivityに初期画面を作成してきましたが、
登録画面のActivity名がMainなのは少しおかしいので、
MainActivity.kt　　→　SubmitActivity.kt
activity_main.xml　→　activity_submit.xml
にリファクタリングしています.

### 遷移部分を作っていく
* 画面を遷移させるには遷移させるボタンがあるxmlファイルに対応する名前のkotlinファイルを編集していきます.今回の場合は、activity_list.xmlファイル内にある「＋」ボタンを押すとactivity_submit.xmlへ遷移する予定なので、ListActivity.ktのファイルを編集していきます.コメントで記述している通り、createBtnの部分はxmlファイルで「＋」ボタンに
登録したidになります.

```ListActivity.kt
class ListActivity : AppCompatActivity() {
    private lateinit var binding: ActivityListBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityListBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //createBtnは押下予定のボタンid
        binding.createBtn.setOnClickListener {
            val intent = Intent(application, SubmitActivity::class.java)
            startActivity(intent)
        }
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1700794/950d4a21-e153-6bd8-c889-3733d40ae8e3.png)

* また、登録画面から「一覧へ」のボタンを押下して最初の画面へ戻る想定なので、そちらも追加していきます.
```submitActivity.kt
class SubmitActivity : AppCompatActivity() {
    private lateinit var binding: ActivitySubmitBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySubmitBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //listBtnは押下予定のボタンid
        binding.listBtn.setOnClickListener {
            finish()
        }
    }
}
```
* 最初に遷移する際に 「startActivity」で画面をスタートしているので戻る際は「finish()」でスタートした画面を終了させます.これで最初の画面から遷移させて戻ってくるとこまでできました.

# おわりに
* 今回は画面遷移に関して記事にしました.前回の最後でDBの準備もやりたいみたいなことを言っていましたが、複数の話題を取り扱うと記事内容が散らかる気がしたのでここで区切ります.近いうちにDB関連のみを扱ったものを投稿するので次回もお楽しみに！

# 参考資料まとめ
* 画面遷移関連の資料

https://qiita.com/atr/items/cc5d2a1eff9a0ba44990

https://akira-watson.com/android/kotlin/view-binding.html

https://akira-watson.com/android/kotlin/activity-transfer.html
映画にでてくるユーザーインターフェースがかっこいい

## はじめに

**映画007やミッションインポッシブル**などのスパイ映画が好きです。
もっと言うと、スパイ映画には必ず登場する主人公を支えるハッカー的な立場の面々が好きです。（007だと「Q」とかMIだと「ルーサーやベンジー」）

もはや彼らの存在がなければ、主人公はまともに行動できない、という感じです。映画なのでなんでもありというところもありますが、単純にカッコイイです。


## 映画にでてくるUIをまとめたサイト

映画のUIは、先取りなところがあるので、以下のような趣旨でまとめているサイトがあります。

> 「デザイナーやクリエイターが、巧妙で興味深いUIを将来的に開発するためのインスピレーションを得られること」を目的に、映画・ゲーム・コンセプトデザイン・現実のシステムから集められたユーザーインターフェース(UI)のデザインをまとめたサイト

https://www.hudsandguis.com/

HUDS+GUIS紹介記事：https://gigazine.net/news/20220422-huds-guis/

こちらは2015年までですが、Movie UIをみることができます。

https://www.saji8k.com/kit-fui/movie/

例：Mission: Impossible - Rouge Nation(2015)
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/2b762f5c-7a17-cca2-edf1-0138cf0399e3.png)

テクノロジーに限らないとは思いますが、次のような名言もありますね。

> 人間が想像できることは、人間が必ず実現できる　by ジュール・ヴェルヌ

## 一番手軽にハッカー気分を満喫する

hollywood というコマンドで「映画に出てくるハッカーっぽい画面」を端末に表示することができるのは、有名かと思います。こちらのYoutubeでも見ることができます。ミッションインポッシブルのテーマが一層気分を盛り上げてくれます。
[Hollywood Technical Melodrama](https://www.youtube.com/watch?v=rVMn3xk5mcY)

https://linuxfan.info/hollywood

https://qiita.com/gotchane/items/a6c475263a7c0e47a0b0


## Windowsターミナルの画面分割で各種情報を表示する

次にWSL2（Ubuntu-20.04）環境で、Windowsターミナルを使用して画面分割し、各種情報を表示してみます。

画面いっぱいに情報を表示して、各種システム監視し難しいことをやってる風。
しかし表示しているのは、TOP関連コマンド＋Matrixということで、実際、特に何もしていない。。

![Screenshot_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/93631ba2-3637-507f-4a60-483401207cac.png)

#### 以下、TOPコマンドの代わりになるコマンド紹介

- glances

https://github.com/nicolargo/glances

- htop

https://github.com/hishamhm/htop

- vtop

https://github.com/MrRio/vtop

- bashtop

https://github.com/aristocratos/bashtop

- gtop

https://github.com/aksakalli/gtop

- gotop

https://github.com/cjbassi/gotop

- cmatrix

　インストール
~~~
sudo apt install cmatrix
~~~

![Screenshot_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/3b1086e5-61a8-d202-3036-16bd61434cf1.png)


## おまけ：ウィンドウ調整は、PowerToy「FancyZones」が便利

PowerToyは、正式版(v1.0)になっておらずbeta版ですが、とても便利な機能が詰まっていると個人的に思います。

https://docs.microsoft.com/ja-jp/windows/powertoys/

FancyZonesの他に **KeyboardManager・ImageResizer** などはとっても便利。


## 参照URL
- [topコマンドの代わりになるもの](https://wonderwall.hatenablog.com/entry/2017/08/16/115236)
volume使用時のPermissionError

# 環境
- WSL2 - Ubuntu20.04
- Docker 20.10.1
- ruby 3.1.2
- rails 6.1.5
# 問題
Volumeを使いローカルにデータを保管すると，フォルダがroot権限で作成される．
# 原因
DockerはWSL環境ではユーザーを指定していない限りコンテナがrootユーザーで実行される．
ちなみにMacOSではこの問題は起こらず，コンテナはローカルユーザーで実行されるらしい．
個人的にDockerの主なメリットにOS間の差異の吸収があるのに［それどうなの？」と感じる．
今後改善されていくのかな？知っている方はコメントお願いします．
# 対策
Docerfileのentrypointでユーザー作成と権限変更を行う

```Dockerfile:Dockerfile
FROM ruby:3.1.2

# yarnインストール用に追加
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \

  && apt-get update -qq \
  && apt-get install -y nodejs postgresql-client yarn
WORKDIR /app
COPY / /
RUN bundle install

# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
```

```sh:entrypoint.sh
set -e

# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /app/tmp/pids/server.pid

#ユーザーIDの追加，グループIDの変更
echo "Starting with UID : $USER_ID, GID: $GROUP_ID"
useradd -u $UID -o user
groupmod -g $GID user

#権限変更
chown -R user:user /app
chown -R user:user /Gemfile /Gemfile.lock

# コンテナーのプロセスを実行する。（Dockerfile 内の CMD に設定されているもの。）
exec "$@"
```

コンテナ内ではユーザーおよびグループはIDを参照するため，名前はローカルと違っても大丈夫です．
あとはDockerComposeで環境変数を渡します．
```yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0.29
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - ./db/mysql_data:/var/lib/mysql

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    env_file:
      - web.env
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
```

```web.env
UID=<自分のユーザーID>
GID=<自分のグループID>
```
.envに直接IDを書き，コンテナに渡しています．
シェルスクリプトを起動させ，自動でローカルの変数を渡すこともできますが，個人開発ならこれで十分だと思います．
Securing Your Users' Identity Challenge

[Trailhead関係　個別の課題別 に戻る](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)


# We couldn't find a user's successful login using multi-factor authentication. Make sure you successfully log in at least once and that you are prompted for a second form of authentication

+ [Secure Your Users' Identity](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDKH3)
+ [We couldn't find a user's successful login using multi-factor authentication. Make sure you successfully log in at least once and that you are prompted for a second form of authentication.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000075w6Fe)

:::note
Reset your password once you have enabled your authentication for your user name and you will be prompted to authenticate your device once more. 

https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDKH3
:::

+ [Secure Your Users’ Identity](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PfQL7)

:::note
Had same issue and did this badge just with another org, and it worked. I assume it's because i messed up my domain before, when I cchanged url for my org
:::
TriggerVolume  メモ

* TriggerVolumeとは
衝突検出が可能なみなない3Dシェイプのことを指す

 * Appleのドキュメント

https://developer.apple.com/documentation/realitykit/triggervolume

* 持っているコンポーネント
トランスフォームコンポーネント
同期コンポーネント
コリジョンコンポーネント

モデルコンポーネントを持っていないので、単体としてレンダリングすることはできないが、トランスフォームコンポーネントを持っているので任意の場所に配置し、コリジョンコンポーネントで衝突検知をすることができる。
衝突検知のみにタスクを特化しているので効率的になる。

TriggerVolumeの引数にはShapeResourceでトリガーボリュームの形状を指定することができる。
また、複数の形状を配列という形で指定することもできる。


```swift
init(shape: ShapeResource, filter: CollisionFilter)
```
登山コミュニティ用アプリ開発（構想）

# 内容

趣味でやっている登山サークルの、コミュニケーション力をＵＰすること
サークル　https://www.facebook.com/kansaitozan
ブログ　https://arafo40tozan.hatenadiary.jp/entry/2022/05/22/122018

# 課題
SNS上の人間関係の構築なので、いろいろ手続きがあり大変だ。
YAMAPなどのアプリはあるが、このアプリだけではカバーしきれない。

## 今やっているフロー

以下はイベント企画としての自分のタスク

１）最初に集合場所と時間に目途を付ける
２）ＹＡＭＡＰでコースプランを入力
３）調整さんを使って、いくつかのアンケートを実施
４）FACEBOOKイベントに投稿して、メンバーを招集する
５）メッセンジャーグループを作って参加者を確定する
６）ニックネーム登録を促して、チームを盛り上げる
７）下見のつぶやきをして、参加者を募る

# 実装したいこと

１）顧客ニーズの可視化

　ネットワークＸを使って、イベント参加者の関係を可視化したい
　
２）参加者の特徴抽出
　
　FACEBOOKの投稿をデータベース化して、参加者のラベリング、特徴をＡＩ学習


# 開発ニーズ

　別途で特許文書のNLPタスクを業務でやっている
　手法としては、CYTOSCAPEでの表示と、特徴量をワードクラスタで表示
（仕事と趣味の用途で、どちらも技術要素は共通する。Qiitaでは趣味の用途で記事を書いている）

# 開発プラットフォーム

　jupyter-lab（python)

１）コントローラはPYTHON　→　シンプルＧＵＩとする(WEB/デスクトップ）　
２）cytoscapeのAPIで可視化
３）WORDCLOUD-APIをFAST-APIで立てる

# 将来構想

このアプリは最終的には、REACT+NATIVEにて、スマホアプリにすること

# その他

写真画像の若返り加工
Youtube動画の投稿フロー

# 目標

HPアクセス数増大　→　アフェリエイト収入
YOUTUBE動画　→　チャンネル登録、アクセス収入

登山を通じて、人脈ネットワークを作り、超高齢者社会の最大エンターテイメントビジネスとする。
プロパティの説明に使ったコードが気に入ったから残しておくだけ

``` C#
using System;

public class Test
{
	public static void Main()
	{
		Circle circle = new Circle();
		
		
		Console.WriteLine("--- Set Radius");
		circle.Radius = 3;
		Console.WriteLine(circle);
		Console.WriteLine();
		
		Console.WriteLine("--- Set Diameter");
		circle.Diameter = 5;
		Console.WriteLine(circle);
		Console.WriteLine();
		
		Console.WriteLine("--- Set Circumference");
		circle.Circumference = 16;
		Console.WriteLine(circle);
		Console.WriteLine();
		
		Console.WriteLine("--- Set Area");
		circle.Area = 12;
		Console.WriteLine(circle);
		Console.WriteLine();
	}
}

class Circle {
	public double Radius { get; set; }
	
	public double Diameter {
		get => Radius * 2;
		set => Radius = value / 2;
	}
	
	public double Circumference {
		get => Diameter * Math.PI;
		set => Diameter = value / Math.PI;
	}
	
	public double Area {
		get => Radius * Radius * Math.PI;
		set => Radius = Math.Sqrt(value / Math.PI); 
	}
	
	public override string ToString() {
		return string.Join('\n', new string[]{
			$"Radius = {Radius}",
			$"Diameter = {Diameter}",
			$"Circumference = {Circumference}",
			$"Area = {Area}",
		});
	}
}
```
【JavaScript】falsyな値

JavaScriptにおいてfalseと扱われる(`falsy`な)値には以下が存在する。

|値|説明|
|--|--|
|false|true、falseのfalseキーワード|
|0|数値0|
|-0|数値-0|
|0n|BigInt値0|
|""|空文字列|
|null|何も存在しないこと|
|undefined|宣言のみされた変数などの未定義値|
|NaN|どの数値とも一致しない特性を持つNumber型の値|

```js
if (false) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if (0) {
  console.log('trueです');    
} else {
  console.log('falseです'); 
}
// => falseです

if (-0) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if (0n) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if ("") {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if (null) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if (undefined) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです

if (NaN) {
  console.log('trueです');    
} else {
  console.log('falseです');    
}
// => falseです
```
4K対応ホームページ制作メモ part6 写真

## うちの会社には誰一人にも給料（役員報酬も）出ていません

どんな会社かは想像でるかもしれません

## バックナンバー

https://qiita.com/nanakochi123456/items/532e801b56d023a70dc5

https://qiita.com/nanakochi123456/items/7a0756b33d42c3a76503

https://qiita.com/nanakochi123456/items/95dbaff738d4654aee54

https://qiita.com/nanakochi123456/items/1475e8c4ce7a9d43ad1d

https://qiita.com/nanakochi123456/items/2a200c2f46e5608740bb

## 写真

うちの会社は2013年に設立しています。

１円も誰一人にも給料もらわず、（どころか、毎年数千円徴収している）100人超いる、すごくないですか？ある意味

そんな会社なわけなのですが

その会社の記録の写真を4Kディスプレイに実際に画像をはめ込んでみたら、かなり荒いという結果でした

### 入稿された写真解像度一覧
- 1049x701
- 800x600
- 917x612（更に拡大の痕跡がある）
- 1129x696
- 4928x3264
- 1204x903
- 4032x3024
- 3072x2304
- 2304x1728
- 898x598
- 1204x903
- 759x654
- 747x674
- 2048x1536
- 1204x903
- 1024x768
- 1200x900
- 2304x1728
- 2272x1704
- 1082x560
- 557x754 （正直言えばこれは写真とりなおしてほしい）
- 400x280（無理ゲー）

低いのが多い

## 写真の特徴
- ローカルファイルで保存されたものはほとんどない
- SNS用に加工され、アップロードされ、SNSからダウンロードされ、SNSで劣化している写真が多い

しかし、ごくわずかにきれいな写真もある。富士山登頂成功とか

意外とYoutubeの埋め込みも4Kにフィットするように、(JavaScriptで）かなり拡大するようになっているが、その埋め込みにある画像がかなりきれいに拡大されていたりもします


## 解像度アップサービスはあるものの

かなり前に今回の4Kリニューアルのための準備画像の一部として利用したものの、
有料サービスを利用しても、思うように鮮明にアップすることができず
結局ぼけている、ということで、どうしようもない

あくまでやったほうが1%～2%よくなる程度なので、再課金は見送った

## ついでに地上波テレビをほぼフル4Kで見る
無理やりリモートデスクトップで4K画面（最大化）でめざましテレビを見ているものの
荒いっちゃ荒いけど、そうひどくはなく、自然に見れる程度

:::note info
5GBEで接続していますが、そんなに帯域使用していないのに、
4KでRDPすると結構フリーズします
:::

## 圧縮パラメータも確認してみる
```
	convert file.jpg -resize 1920 ../file.jpg
	cd ..
	guetzli --quality 84 file.jpg ../file.jpg
	cwebp -quiet -q 78 -z 9 file.jpg -o ../file.jpg.webp
	avifenc -j 16 -s 0  --min 15 --max 63 --minalpha 63 --maxalpha 63 file.jpg ../file.jpg.avif
```
変なことしてないし問題はないはず。きっと

## ってことはうちの会社の画像が悪い

確かに会社といえば会社だが、アマチュアレベル以下の気分の写真ぐらいしかない

オリジナルでさえ、ピントがごくわずかにずれているのもある。

みんなスマホ撮影だから、こういうのは仕方ないか。。。。


:::note info
元カノが写真送ってくれることがあったけど、相当音痴だけじゃなくて、相当写真のピントがあってなかったなの
:::

## とりあえず対策をとろうとした

会社の記録（の生データ）を保管するバックオフィスも必要かなと感じられました。

## 結論
4Kにはめてみて荒い写真ではあるので、余裕でデザイン会社でもないので、低クォリティーの写真をそのまま使うが、
差し替えられる写真があったら、よりきれいなのにするべきと

ただ、4K対応しているだけで、そこまで美を求めてるわけでもないので
（レンティナディスプレイには対応してない、対応方法は知ってるがあえて除外）
今のままでいいのかどうなのかな、仕方ないかな、ってレベルです。

:::note info
そもそも、低クォリティーがうちの会社の1つの売りでもあったりします
:::
Simulinkファイルをフリーソフトで開いてみる

Simulinkファイルをフリーソフトで開けないか探してみた。Nspで開くらしい。

http://cermics.enpc.fr/~jpc/nsp-tiddly/mine.html

![NSP1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/43e0081c-ac5a-6a66-9e3f-816257ae8380.png)

インストールして、コマンドラインにscicos()と入力するとscicosが起動するので、ファイルメニューのMdl or Slx Importでファイルを開く。ここからいくつか試してみた。

https://www.jcbrolabs.org/simulink-models

表示はできるようだ。

![Nsp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/1c579cc0-1475-c8e9-c86d-69013288f366.png)

実行もものによってはできる。

![Nsp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/391148c5-5e95-92e0-5890-222754689970.png)

大抵はエラーが出る。特に回路部品は変換ができないみたいだ。

![NSP3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/8c9ff91e-c00d-688b-ba6d-670456b1207b.png)

ScilabにもSimulinkのコンバータがあるらしい。

http://forge.scilab.org/index.php/p/simulink2xcos/

これも試してみた。Ver.6系以降のScilabを管理者権限で実行する。ファイル（DESCRIPTION）が入っていないので、マクロのひな型から持ってきて適当に編集して付け加えるとコンパイルは通り、マクロとして登録もできる。

atomsInstall('simulink2xcos.zip')とすればよい。

実行するには、macros ディレクトリまで下りて行って、exec simulink2xcos.sce　とすればよさそうだが、.slxファイルを選択するダイアログが表示されるものの、残念ながら動かなかった。

![Simulink2Xcos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200022/afa81ca6-b707-3e37-ee1a-f09b0b7c45c7.png)
Customize How Records Get Approved with Approvals 2


[Trailhead関係　個別の課題別 に戻る](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)

[Customize How Records Get Approved with Approvals](https://trailhead.salesforce.com/ja/content/learn/modules/business_process_automation/approvals)


# 「保留中」に設定されているアカウントタイプが見つからないというエラーが表示され続けます

[承認プロセスの課題](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000H1O8J)
Formulas and Validations > Use Formula Fields


[Use Formula Fields](https://trailhead.salesforce.com/en/content/learn/modules/point_click_business_logic/formula_fields)

# EndDateが見つからない

[こんにちは。契約の有効期限が切れるまでの残り日数を計算する数式フィールドを作成するのに問題があります。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FUm1g)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3e0f0900-8ecc-76b9-3299-dece4d741983.png)