OmniAICreator/Qiita-1.07M huggingface dataset:
LINE Messaging APIで日本語メッセージを送信する際に400エラー２

LINE Messaging APIで日本語メッセージを送信する際に400エラーが発生する問題を解決するには、Spring BootのJavaアプリケーションで以下の方法を試すことができます:

1. 文字列のエンコーディングを確認する:
日本語テキストをUTF-8でエンコードしていることを確認してください。Spring BootのJavaアプリケーションでは、以下のように文字列をエンコードできます：

```java
String japaneseText = "こんにちは";
String encodedText = new String(japaneseText.getBytes("UTF-8"), "UTF-8");
```

2. リクエストヘッダーの設定:
Content-Typeヘッダーを正しく設定していることを確認します。

```java
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + channelAccessToken);
```

3. リクエストボディの構築:
JSONオブジェクトを正しく構築し、日本語テキストをエスケープします。

```java
JSONObject message = new JSONObject();
message.put("type", "text");
message.put("text", encodedText);

JSONArray messagesArray = new JSONArray();
messagesArray.put(message);

JSONObject requestBody = new JSONObject();
requestBody.put("to", userId);
requestBody.put("messages", messagesArray);
```

4. HTTPリクエストの送信:
RestTemplateを使用してHTTPリクエストを送信します。

```java
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
ResponseEntity<String> response = restTemplate.postForEntity(LINE_API_URL, request, String.class);
```

5. エラーハンドリング:
エラーが発生した場合に適切に処理するために、try-catchブロックを使用します。

```java
try {
    ResponseEntity<String> response = restTemplate.postForEntity(LINE_API_URL, request, String.class);
    // 成功時の処理
} catch (HttpClientErrorException e) {
    // エラー時の処理
    System.out.println("Error: " + e.getStatusCode() + " " + e.getResponseBodyAsString());
}
```

これらの手順を実装することで、Spring BootのJavaアプリケーションでLINE Messaging APIを使用して日本語メッセージを正常に送信できるはずです。エラーが解決しない場合は、リクエストの詳細やエラーメッセージを確認し、必要に応じてデバッグを行ってください。

Citations:
[1] https://qiita.com/tosumi-Qiita/items/dfdf4e1f255d2611f533
[2] https://31navi.com/line-bot-error/
[3] https://qiita.com/gptu/items/e89648d54720917f7156
[4] https://qiita.com/gptu/items/807ef1ada28827e88de4
[5] https://www.sun-m.co.jp/blog/tips/358.html
[6] https://qiita.com/s-tsuchida/items/b9752641bb6cd9bee1ed
[7] https://zenn.dev/joo_hashi/articles/38afa45afca4a8
[8] https://developers.line.biz/ja/docs/messaging-api/sending-messages/
[9] https://techtionary.jp/3540/
[10] https://note.com/singtaro/n/nbc42ab792de9
[11] https://smct.jp/support_02_003/
[12] https://teratail.com/questions/352320
[13] https://kinsta.com/jp/knowledgebase/400-bad-request/
[14] https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/
[15] https://www2.kobe-u.ac.jp/~tnishida/programming/GAS-03.html
[16] https://codezine.jp/article/detail/17654
【小ネタ/超便利】直接OutlookのCopilotで会議のスケジューリングが可能になっている

昨年夏のアップデートでメールから会議のスケジューリング（予定参照可能なメンバー間）が可能となっていました。気づかぬうちにOutlookのCopilotからスケジューリングできていたので共有です。

https://qiita.com/ponponmikankan/items/448f21ab960678bcd868

## 1.新しいOutlookまたはWeb版のOutlookでCopilotのチャットを開く
Copilotはだいたい右上にいます。右側からCopilotのチャットを開きましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/24696673-f9bc-70c9-0e73-9763bbc2b384.png)

## 2.メンバーを選ぶ
Business Chatと同じように、「/」を打つと予測がでてくるのでメンバーを選択します。
プロンプトでは「[$選んだメンバー]との1時間の会議を調整して」等と書きます。
すると直近の空いているスケジュールを出してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/9288f898-2822-41d8-7eb9-32d14c3e29bb.png)

### 調整画面の説明
* 「送信」
送信を押すとそのままCopilotが作った件名で会議のスケジュールが送信されます。
デフォルトではTeams会議となっています。

* 「編集」
編集画面では、予定表イベント画面がポップアウトで出て件名等を変更することができます。
会議の日程を再検索したい場合は日程を変更してから「時間の検索」を押すと再度確認することができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/c11508df-c007-4e7e-6e4c-2155d0333f80.png)

* 「表示」
表示を押すと自分の前後の時間のスケジュールがフォーカスされて表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/d596b4c0-b230-f090-c965-b19a7bab5ef4.png)

## ちょっと研究
ここからはちょっと研究してみました。

### チャットでそのまま再調整も可能
先ほどは予定表イベント画面で編集を行いましたがチャットで再調整も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/056eeea9-f7e4-ad8b-5be2-b517a490aa06.png)

### メンバーを指定せず平文でお願いするとどうなるか
ここで「〇〇さん」と指定しないで平文のまま打つと、最近やり取りした〇〇さんが出てきます。
同姓同名や誤送信等が怖い場合はきちんと指定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/7b76edb4-a471-f6b6-61cb-0da4a663b915.png)

### 4名以上で調整したいパターン
細かく検証していませんが、4名以上でも対応可能です。なぜか4名以上だと「事前入力済みのイベントフォーム」と表示され、さっきと少しアウトプットが変わってきますが、同じように調整が可能でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/81244023-2ad8-8408-cc84-3b0718eb9256.png)

### 会議や資料を添付した場合
メールから会議をスケジューリングする場合は、以下の記事のようにメールのこれまでの要約が表示されます。
しかし残念ながらチャットで指定しても件名にしか反映されませんでした。
別途チャットで「[$選んだ資料やメール]の要約を作って」と依頼してコピペする必要がありそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/bd0925d9-b846-1aba-2d61-f1173851f9ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/dd364649-27eb-88ab-79a1-0ba9078e853e.png)

https://qiita.com/ponponmikankan/items/448f21ab960678bcd868


というわけでひっそり（？）更新されていたOutlookのCopilotでした。
どの会社でも会議調整は永遠の課題と手間だと思うのでぜひ試してください！
React hooksまとめ

## React hooksまとめ

- [React hooksを理解する（useState）](https://qiita.com/kenta1760/items/b225a3c8367b202a56d7)
- [React hooksを理解する（useEffect）](https://qiita.com/kenta1760/items/1f3561dafbe0b9ab4b4e)
- [React hooksを理解する（useContext）](https://qiita.com/kenta1760/items/bd0c8fe1e9cf4454bb0a)
- [React hooksを理解する（useNavigate）](https://qiita.com/kenta1760/items/19ab2896342d5ab22ba5)
Nodejsで 日付文字列とTimeStamp値を変換するスクリプト


timeStamp値が必要となったため作った2本を記録しておく
コンソールからnodeで動くように作った
- toTimestamp.js
- fromTimestamp.js

## 使い方
・日本時間の日付から timestamp値を表示する

    $ node toTimestamp.js "2025/1/1 12:0:0"
    1735700400000
    
・timestamp値から 日本時間の日付を表示する

    $ node fromTimestamp.js 1735700400000
    2025/01/01 12:00:00

## コード

```javascript:toTimestamp.js
function toTimeStampFromJPstr(datetimestr) {
    // 日付文字列を分解
    const [year, month, day, hours, minutes, seconds] = datetimestr.split(/[-\/:\s]/).map(Number);
    // 東京（日本標準時）のタイムゾーンオフセット（JSTはUTC+9）
    const tokyoUtcOffset = 9 * 60 * 60 * 1000;
    // UTC時間に変換
    const utcDate = new Date(Date.UTC(year, month - 1, day, hours ?? 0, minutes ?? 0, seconds ?? 0));
    // JSTに調整
    utcDate.setTime(utcDate.getTime() - tokyoUtcOffset);
    return utcDate.getTime(); //unixtimeが欲しいならこれを1000で割ればいい
}

// 引数を取得
const args = process.argv.slice(2); // 最初の2つの要素（nodeとファイル名）は削除
if(args.length === 0) {
  console.error('引数が見つかりませんでした。');
}
// 例：引数の先頭を指定して適切に使用
const myArg = args[0];
const tokyoDate = toTimeStampFromJPstr(myArg);
console.log(tokyoDate);
```


```javascript:fromTimestampToJPstr.js
function fromTimestampToJPstr(timestamp) {
  const date = new Date(timestamp); //(unixTime * 1000); // ミリ秒に変換

  // UTCの日付から日本標準時(JST)に調整
  const jstOffset = 9 * 60 * 60 * 1000; // JSTはUTC+9
  const jstDate = new Date(date.getTime() + jstOffset);

  // 年、月、日、時、分、秒を取得
  const year = jstDate.getUTCFullYear();
  const month = jstDate.getUTCMonth() + 1; // 0から始まるため +1
  const day = jstDate.getUTCDate();
  const hours = jstDate.getUTCHours();
  const minutes = jstDate.getUTCMinutes();
  const seconds = jstDate.getUTCSeconds();

  // フォーマットされた日付文字列を作成
  return `${year}/${zz(month)}/${zz(day)} ${zz(hours)}:${zz(minutes)}:${zz(seconds)}`;
}
// 2桁0埋め
const zz = zerozero
function zerozero(n){
  return `0${n}`.slice(-2)
}

// 引数を取得
const args = process.argv.slice(2); // 最初の2つの要素（nodeとファイル名）は削除
if (args.length === 0) {
  console.log('引数が見つかりませんでした。');
} 
// 例：引数の先頭を指定して適切に使用
const myArg = args[0];
const tokyoDate = fromTimestampToJPstr(myArg * 1);
console.log(tokyoDate);
```
Laravel11を指定ディレクトリへプロジェクトフォルダ付きでインストールするコマンド

①以下の様に、プロジェクトフォルダを作成するディレクトリにカレントディレクトリを移動
　cd /Applications/XAMPP/xamppfiles/htdocs

②composer create-project laravel/laravel=11.x プロジェクト名

③
cd プロジェクト名
sudo chmod -R 0777 storage
sudo chmod -R 0777 bootstrap/cache

④database.phpにてデフォルトのDBをsqliteからmysqlに変

⑤.envファイルの以下のオプションを設定
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test01
DB_USERNAME=root
DB_PASSWORD=
KaliLinuxにtoucheggを手動でインストールする

## まえがき
gnomeの拡張機能のX11Gesturesを使って、トラックパッドで三本指スライドをした際、ウインドウを切り替える仕様にしようとしたときにtoucheggが入ってなく、使えなかったです。じゃあsnapかaptで入れよう、って実行したのですが、toucheggをインストールすることはできませんでした。手動インストールを試したんですけどエラー祭りになった末たどり着けたので書き残したいと思います。

## 本題
早速入っていきますが、まず前提として、SnapとGnomeが入っていることが条件です。
ではまずは依存関係のインストールです
```bash
sudo apt install build-essential cmake libudev-dev libinput-dev libcairo2-dev libglib2.0-dev libx11-dev libxtst-dev libxi-dev libxrandr-dev libgtk-3-dev
```
次にGithubのリポジトリからtoucheggのソースを直接取得してきます。
```bash
git clone https://github.com/JoseExposito/touchegg.git

cd touchegg
```
次に、何故か最新版だとエラーが出てmakeなどが実行できないため、バージョンを変えます。
```bash
git checkout 2.0.14
```
ではビルドに入っていきます。
まずCmakeLists.txtファイルを少し書き換えます。中にある`set(SYSTEM_CONFIG_FILE_PATH "$CMAKE_INSTALL_DATAROOTDIR}`の上の行に、以下の二行を追記します。
```text
set(CMAKE_INSTALL_FULL_SYSCONFDIR "/etc")
set(CMAKE_INSTALL_DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share")
```
約最後の行に`pkg_get_variable(SYSTEMD_SERVICE_DIR systemd systemdsystemunitdir)`とあると思いますが、その下に以下の二行を追加してください。こちらはディレクトリを指定してサービスファイルをインストールしています
```text
set(SYSTEMD_SERVICE_DIR "/lib/systemd/system")
message(STATUS "SYSTEMD_SERVICE_DIR=${SYSTEMD_SERVICE_DIR}")
```
buildフォルダを作成し、移動します。
```bash
mkdir build
cd build
```
ビルドシステムをひとつ上の階層にあるCMakeListsを使用し、ビルドシステムを構成します。
```bash
cmake ..
make
sudo make install　#システムへのインストール
```
システムサービスとしての管理が可能になっているはずなので、起動、自動起動を有効化します。
```bash
systemctl --user start touchegg
systemctl enable touchegg.service
```
以上で終了です。私はこの工程の中で色々別の操作をしてエラーを起こしましたが、シンプルに必要なものだけをまとめたので、大丈夫だと思います。ありがとうございました。
Rust の static assert

最近（いつから？）の bindgen でこんなコードが出力されていた。

```rust
#[repr(C)]
struct Foo {
    bar: u8,
    hoge: u32,
    piyo: u8,
}

const _: () = {
    use std::mem::offset_of;
    ["Foo size"][size_of::<Foo> - 12];
    ["Foo::bar"][offset_of!(Foo, bar) - 0];
    ["Foo::hoge"][offset_of!(Foo, hoge) - 4];
    ["Foo::piyo"][offset_of!(Foo, piyo) - 8];
};
```

構造体サイズやメンバのオフセットが間違っていたらコンパイルエラーになる（というか rust-analyzer が教えてくれる）。`["Foo size"]`は`[&str; 1]`で、`[size_of::<Foo> - 12]`が 0 になるようにしてるのね。（長さ 1 の配列`a`の`a[0]`にアクセスしてる）

UEFI スペックみながら構造体書いてたら、いつの間にかオフセットずれてて爆死なんてことが防げそう :blush:
【Blender】白黒テクスチャ1枚で作るMaterialノード

![Frame 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/45f3f472-b696-ea87-1e5a-9dc3a6161fa1.png)
### 白黒のテクスチャを再利用してMaterialを作ってみよう
株式会社GENEROSITYに所属しているCGデザイナー丸山です。

Shaderにもよりますが白黒のテクスチャはHeightやRoughnessのマップとして
使われることが多いですよね。
私はブラウザベースやゲームエンジンでのリアルタイムレンダリングを扱うことが多いため
1枚の白黒のテクスチャ様々なチャンネルに再利用してファイル容量を軽量化する
手法に馴染みがあるのですが、そういえばプリレンダであまり組んだことがないなぁと思い
今回は試しにMaterialを組んでいこうかとおもいます。

また、本記事はBlender中級者が対象です。

### 今回作るもの
![Bag02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/500766b2-24d3-023a-8da3-1454281803a6.png)


ショッピングバックをロゴののみで色を付けて、
エンボス加工っぽい表現を取り入れていきます。

### バージョン情報と必要な素材
・Blender(私は4.2を使用してます。)
・UV展開済み任意の3Dモデル
・上記のUVに合わせて作成したロゴの白黒テクスチャ

#### 完成形

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/5e11cb48-2bf5-0e8d-f5d1-5303ada83a47.png)

まずは完成版を載せていきます。
分かる人はこのつなぎ型を見るだけである程度わかると思いますが
さらに細かくノード別で解説を添えたものが下記になります。

完成版は簡素なのですが
最初はアルファはどこに挿せばいいかわからず
複雑怪奇なノードを組んだ果てにこちらに落ち着きました。
よければ参考にしてください。

ここからはさらに細かく項目別に解説していきます。

- BaseColor

![Frame 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/922ddd79-20d2-17ea-8a8e-c09392e09ca0.png)
①紙の質感をノイズで表現
BaseColorのベースとなる紙の質感作り。
紙がつるつる過ぎると偽物っぽくなってしまうので
部分にノイズの素材を乗算で乗せていきます。
BlenderのプリセットのNoiseTextureノード使用します。
Scaleを大きくして目を細かくしてニュアンス程度にとどめます。

②ノイズと色の合成
VectorMathのMultiplyにRGBノードとNoiseTextureノードを挿入。
よく使う型なので覚えておくと便利です。

③ロゴとベースの紙の色と質感を分ける
ロゴ部分はエンボス調にするのでノイズを載せたくないし
色も分けたいのでここから白黒マップを使って分岐を作ります。

今回頻出するのがこちらのConverter>Mixノードです。
ロゴを挿すのはFacパラメータです。
切り替わりの閾値を設定していきます。

Aは白部分、Bは黒部分に対応します。
BはRGBでノード内のUIで指定できます。

こちらをPrincipled BSDFのBase Colorに繋げばおわりです。

- Roughness
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/afec54bf-bc66-3aef-6195-d9254fa08879.png)


薄々お察しかもしれませんが
こちらもMixノードで白と黒のラフネスマップの強さを調整していきます。
ちなみに白と黒のマップをそのまま反転して使いたい場合は
InvertノードでもOKです。

- Normal
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901849/84cf3cc8-82ce-595e-5695-fe739a48c544.png)


Bumpノードに挿しHeightからNormalを出力することができますが…

この方法は凹凸の雰囲気がイマイチなので少し面倒ですが
白黒のテクスチャからPhotoshopなどでNormalマップを作成することをお勧めします。

https://modelinghappy.com/archives/17056#google_vignette

これで終了です。
この形は色々と使いまわせると思うのでご参考にどうぞ。

### テクスチャ使いまわしのメリットデメリット

#### メリット
参照元のテクスチャの変更で下流の工程がすべて差し替わるため、
表現の目的が明瞭な場合はこの作業工数を削減できることが多いと感じます。

#### デメリット
予想外の変更に弱いとい感じます。
共通のテクスチャを使いまわしているため物凄く微細な変更を求められると
ノードを組みなおすより描きなおした方がトータルの作業工数が抑えられることもあります。

#### バランスが大切
上記の性質を踏まえ
今回同じ白黒テクスチャを使いまわしていますが
読み込み元の素材は共通化していて、ノード自体は分けてあります。

処理別にわけることで難読化を防ぐこと、
今後テクスチャを差し替える可能性を見越して、などの意図があります。

プロジェクトに適した形で取り入れられるといいですよね。

#### おわりに
もっといい組み方がありましたら是非教えていただけると嬉しいです。
それでは、エンジョイBlenderライフ！
【Tailwind CSS】It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin. の解決方法

# はじめに 
`Next.j`sで`Tailwind CSS`をインストールした際に発生したエラーについての記事です。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# 問題
`Next.js`の公式ドキュメントに従って`Tailwind CSS`をインストールしました。

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

https://nextjs.org/docs/app/building-your-application/styling/tailwind-css

しかし、インストール後に以下のエラーが発生しました。
```
It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin. The PostCSS plugin has moved to a separate package, so to continue using Tailwind CSS with PostCSS you'll need to install `@tailwindcss/postcss` and update your PostCSS configuration
```

# 解決方法
`Tailwind CSS`のバージョン変更により、インストール方法が変わったようです。
以下のコマンドで必要なパッケージを追加した後、公式ドキュメントに従い設定を行うことで、エラーが解消されました。

```bash
npm install tailwindcss @tailwindcss/postcss postcss
```

https://tailwindcss.com/docs/installation/using-postcss

# 終わりに
`Tailwind CSS`の仕様変更により、従来のインストール手順ではエラーが発生することがあるようです。今後も最新の情報をキャッチアップしながら、適切な設定方法を学んでいきたいと思います。

# 参考

https://tailwindcss.com/docs/installation/using-postcss

https://stackoverflow.com/questions/79383705/cannot-build-frontend-using-vite-tailwindcss-with-postcss

『npx tailwindcss initでnpm error could not determine executable to runエラーが出る』Qiita

https://qiita.com/Sicut_study/items/6b0fb7388e265bdb11da
curlコマンド UTF-8でエンコード

curlコマンドで日本語を含むデータをUTF-8でエンコードして送信するには、以下の方法が効果的です：

1. ファイルを使用する方法:
post.json（名前はなんでもいいですが）にUTF-8で書き込み。で、こんなコードを書くと文字化けせずに書き込みができます。
```
curl -X POST -H "Content-Type: application/json" -d "@post.json" "http://localhost:3000/test" -v
```
[6]

この方法では、日本語を含むJSONデータをUTF-8でエンコードしたファイルを作成し、そのファイルを`-d "@ファイル名"`オプションで指定します。

2. エスケープシーケンスを使用する方法:
日本語文字列をUnicodeエスケープシーケンスに変換して送信します。例えば：

```
curl -X POST -H "Content-Type: application/json" -d '{"text":"\u3053\u3093\u306B\u3061\u306F"}' "http://example.com/api"
```

この方法では、「こんにちは」がUnicodeエスケープシーケンスに変換されています。

3. Windows環境での注意点:
Windows のコマンドプロンプトがいまだに SJIS (Shift-JIS) という古い文字コードで動作しているため[4]、追加の対策が必要です。

curl.exe -L yahoo.co.jp -o out.html[8]

このように`-o`オプションを使用して直接ファイルに出力することで、Windows標準出力の文字コード変換問題を回避できます。

4. PowerShellを使用する場合:
`japaneseString`は既に文字列なので、コード内でそのまま使用できます。`String.getBytes()`はプラットフォームのデフォルトエンコーディングを使用してバイト配列を作成します。これがUTF-8でない可能性があります。UTF-8でデコードすると文字化けが発生する可能性があります。

これらの方法を使用することで、curlコマンドで日本語を含むデータをUTF-8でエンコードして正しく送信できます。環境に応じて適切な方法を選択してください。

Citations:
[1] https://apidog.com/jp/blog/curl-utf8-decode-encode/
[2] https://askubuntu.com/questions/1247214/change-the-curl-response-encoding-for-some-characters
[3] https://ja.stackoverflow.com/questions/19068/watson-text-to-speech%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%92post%E3%81%A7%E9%80%81%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E4%B8%8B%E3%81%95%E3%81%84
[4] https://qiita.com/yamachan360/items/8c928738289cd518eec8
[5] https://wagavulin.hatenablog.com/entry/2015/10/18/060938
[6] https://cattail.co.jp/techcode/2879/
[7] https://www.codecode.xyz/curl_from_eucjp_to_utf8/
[8] https://qiita.com/yugo-yamamoto/items/19d74869a12d48468a6a
[9] https://stackoverflow.com/questions/24009119/utf-8-encoding-only-some-japanese-characters-are-not-getting-converted
[10] https://github.com/curl/curl/issues/6386
[11] https://uchy.me/blog/2024051003/
[12] https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB1080480
[13] https://qiita.com/laf/items/60f147cc736710535154
[14] https://tech.iimon.co.jp/entry/2024/12/13
[15] https://www.luftgarden.jp/blog/63/
LINE Messaging APIで日本語メッセージを送信する際に400エラー

LINE Messaging APIで日本語メッセージを送信する際に発生する400エラーを解決するには、以下の方法を試すことができます：

1. 文字列のエンコーディングを確認する：
   日本語テキストをUTF-8でエンコードしていることを確認してください。Spring BootのJavaアプリケーションでは、以下のように文字列をエンコードできます：

   ```java
   String japaneseText = "こんにちは";
   String encodedText = new String(japaneseText.getBytes("UTF-8"), "UTF-8");
   ```

2. 改行コードの処理：
   日本語テキストに改行が含まれている場合、それらを適切にエスケープする必要があります。改行コードを「\n」（エスケープされた改行コード）に置き換えてください。[1]

3. 特殊文字のエスケープ：
   日本語テキストに引用符（"）などの特殊文字が含まれている場合、それらを適切にエスケープしてください。Javaでは、StringEscapeUtils.escapeJava()メソッド（Apache Commons Langライブラリ）を使用できます。[2]

4. URLエンコーディングの確認：
   リクエストURLに日本語パラメータが含まれている場合、それらが正しくURLエンコードされていることを確認してください。Spring BootではUriComponentsBuilderを使用してURLを構築し、自動的にエンコードすることができます。[3]

5. Content-Typeヘッダーの設定：
   リクエストヘッダーに`Content-Type: application/json; charset=UTF-8`を設定していることを確認してください。

6. リクエストの構造を確認：
   LINE Messaging APIの仕様に完全に準拠したリクエスト構造になっていることを確認してください。特に、メッセージオブジェクトの形式が正しいか確認します。[5]

7. 文字数制限の確認：
   LINE Messaging APIには文字数制限があります。日本語メッセージが制限を超えていないか確認してください。

8. エラーログの詳細確認：
   Spring Bootアプリケーションのログを詳細に確認し、具体的なエラーメッセージを特定してください。これにより、問題の根本原因をより正確に把握できる可能性があります。

これらの方法を試しても問題が解決しない場合は、LINE Developersのドキュメントを再確認し、APIの最新の仕様や変更点を確認することをおすすめします。また、テストツールを使用してAPIリクエストを検証し、問題を特定するのも効果的な方法です。

Citations:
[1] https://qiita.com/tosumi-Qiita/items/dfdf4e1f255d2611f533
[2] https://31navi.com/line-bot-error/
[3] https://www.sun-m.co.jp/blog/tips/358.html
[4] https://note.com/singtaro/n/nbc42ab792de9
[5] https://apidog.com/jp/blog/http-error-400/
[6] https://techtionary.jp/3540/
[7] https://teratail.com/questions/352320
[8] https://smct.jp/support_02_003/
[9] https://zenn.dev/msksgm/articles/20240201-practice-of-spring-boot-client-exception
[10] https://gup.monster/entry/2019/03/06/033248
[11] https://qiita.com/yoshitaro-yoyo/items/03f0296f4ba7011d654f
[12] https://kinsta.com/jp/knowledgebase/400-bad-request/
[13] https://developers.line.biz/ja/docs/messaging-api/retrying-api-request/
電気関係も詳しいと幸せになれる話


ふと会社内で話をしていたのを又聞きした

「MacBookの充電器って重いよねー。毎回持ってこないといけないの面倒」

話を聞いてみると彼女は純正の電源アダプタしか充電できないと思ってたみたい。
私がAnkerの小型ACアダプタを使用していることを話したら目が点になっていた。

これ、以外とあると思っています。
ソフトウェア工学やら、プログラミングやら、状態管理やら、ソフト系には強いけど
ハードウェアや電気関係には結構疎いって人いるんじゃないかと思います。

・例えばType-Cは共通規格で純正以外でも使用できること
・Type-Cでもスマホ用15WとPC用60Wは違うこと
・HDMIケーブルはType-Cに変換できること

自分自身も電気工事士の資格持っている訳ではなく独学ですが、
それぞれの仕様や構造は理解しているつもりです。

ソフトウェアはハードウェアの上に成り立っているのでその理解していればいいのかなと。
というか最近はPC自作で作ることやPC分解もあんましないですもんね。。

PCや製品の内部構造理解しているとスキルアップにつながるかもよというお話でした。
【テスト技法】テスト設計アプローチ

# はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。
現在はRailsを勉強しているのですが、並行してソフトウェアテスト技法も学ぶことで、Railsチュートリアルの理解が深まるのではないかと考え、テスト技法の勉強を始めました。
今回学んだテスト設計アプローチについて、記憶が薄れないうちに簡単にまとめておきたいと思います。

ちなみに、テスト技法はUdemyで勉強しています。とても分かりやすいので、テスト技法を勉強したいと思う方はぜひ見てみてください。

https://www.udemy.com/share/102NaE3@Klm5Y802jzOOWemmUmgcZKwsmg5ZeKSLdssOdLltCQUeMwrYsLoBehQBwhoefOb3yw==/

## テスト設計アプローチ
テストには「正解」が常に存在するわけではなく、プロジェクトの状況に応じて判断が必要です。そこで役立つのが「テスト設計アプローチ」という考え方です。主に次の2つに分類されます。


* 契約によるテスト
* 防御的テスト

### 契約によるテスト
教材では以下のように定義されていました
> 事前条件の範囲内だけでテストを行うアプローチ
> 事前条件とは？⇒　渡される必要のある引数など、メソッド（ソフトウェアテストの用語ではモジュール）が正しく呼び出される際に満たすべき条件

では前回の記事で扱ったコードを見てみましょう
```ruby
if a <= 2
  # 処理
elsif a >= 10
  # 処理
else
  # 処理
end
```
ここで「a は自然数である」という設定があった場合、これが「事前条件」にあたります。
契約によるテストでは、この事前条件を満たす値、つまり自然数に対してのみテストを行います。


### 防御的テスト
教材では以下のように定義されていました
>事前条件の範囲外もテストを行うアプローチ

```ruby
if a <= 2
  # 処理
elsif a >= 10
  # 処理
else
  # 処理
end
```
「a は自然数である」という事前条件があったとしても、マイナスや小数点、分数、文字列など、想定外の値を渡したときの動作を確認するのが「防御的テスト」です。

## Railsのバリデーションを例に考える

Railsチュートリアルを進める中で実際に出てきた例をもとに、契約によるテストと防御的テストを考えてみましょう。

```ruby:user.rb
class User <ApplicationRecord
 validates :name, presence: true, length:{ maximum:50 }
end
```
`models/user.rb` では、`name` カラムに上記のようなバリデーションを設定しています。今回は、`length: { maximum: 50 }` に注目しましょう。

* **契約によるテスト**
例えば、`name` が **50 文字以内であれば有効で**あることを確認するテストが該当します。
事前条件として「`name` は文字列で、かつ 50 文字以内」という想定範囲内の値をテストします。

* **防御的テスト**
一方で、「name が空文字だった場合にどうなるか」や「50 文字を超えた場合」にどう動作するかといった、事前条件の範囲外や境界ギリギリのケースをテストします。こちらが防御的テストにあたります。




# まとめ
今回は、テストを設計する上での指針となる「テスト設計アプローチ」について解説しました。大きく分けると、

* 契約によるテスト
* 防御的テスト
の2つがあります。テストを設計する際にこれらを意識することで、テスト漏れを減らし、より網羅的なテストを行えるようになるでしょう。

次回は、もう少し具体的なテスト手法について紹介する予定です
原点に戻って約１アンペアのLチカから再スタート

# 原点に戻って約１アンペアのLチカから再スタート

TLP-A100とTLP-P055を使用して約1A出力のLチカやってみました。

<iframe width="793" height="1409" src="https://www.youtube.com/embed/aki_H-BJXnA" title="Lチカで初心を思い出すエンジニアの会話💡✨ #TLP-A100 #TLP-P055" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## ソースコード

```cpp
#define PIN_LED 5

boolean gLED;

void setup() {
  // put your setup code here, to run once:
  pinMode( PIN_LED, OUTPUT );
  digitalWrite(PIN_LED, LOW);
  gLED = false;
}

void loop() {
  // put your main code here, to run repeatedly:
  if ( gLED ) {
    gLED = false;
    digitalWrite(PIN_LED, LOW);
  } else {
    gLED = true;
    digitalWrite(PIN_LED, HIGH);
  }
  
  delay(1000);
}
plunkerでpodcast

# 概要
plunkerでpodcastやってみた。

# 参考にしたページ

https://qiita.com/katokonigiry/items/3c6442bfc3244f70bddc

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e88a3881-d267-a223-9ab4-3a2f7fc08f8e.png)



# サンプルコード

```

var playerupdater = null;
var playerupateinterval = 500;
$(function () {
  var thisfeed = "https://www.tsujileaks.com/?feed=podcast";
  feednami.load(thisfeed).then((feed) => {
    writeEpisodes(feed);
  });

});

function writeEpisodes(res) {
  var myarray = res.entries;
  var newhtml = "";
  for (var i = 0; myarray.length > i; i++) 
  {
    newhtml += '<div class="episode">';
    try 
    {
      newhtml += "<h3>" + myarray[i].content.title.content + "</h3>";
    } 
    catch (err) 
    {
      if (typeof myarray[i].title == "array") 
      {
        var thistitle = myarray[i].title[0];
      } 
      else 
      {
        thistitle = myarray[i].title;
      }
      newhtml += "<h3>" + thistitle + "</h3>";
    }
    newhtml += '<div class="player">';
    newhtml +=
      '<div class="timeline"><div class="playerprogress"><div class="scrubber"></div></div></div>';
    newhtml += '<div class="controls col-xs-12 text-center">';
    newhtml +=
      '<div style="margin-left: 7%;" class="previous col-xs-2 glyphicon glyphicon-step-backward text-center" title="next newer episode"></div>';
    newhtml +=
      '<div class="skipback flip glyphicon glyphicon-repeat col-xs-2 text-center" title="back 15 seconds"></div>';
    newhtml +=
      '<div class="play col-xs-2 glyphicon glyphicon-play text-center" title="play"></div>';
    newhtml +=
      '<div class="skipforward glyphicon glyphicon-repeat col-xs-2 text-center" title="forward 30 seconds"></div>';
    newhtml +=
      '<div class="next col-xs-2 glyphicon glyphicon-step-forward text-center" title="next older episode"></div>';
    newhtml += "</div>";
    //newhtml += '<audio id="episode' + i + '" preload="metadata">';
    newhtml += '<audio controls="controls" autobuffer="autobuffer" >';
    newhtml +=
      '<source src="' + myarray[i].enclosures[0].url + '" type="audio/mpeg">';
    newhtml += "Your browser does not support the audio element.";
    newhtml += "</audio>";
    newhtml += "</div>";
    newhtml +=
      '<p class="publishingnotes">Published: ' + myarray[i].pubDate + "</p>";
    newhtml +=
      '<p class="shownotes">Show Notes: ' + myarray[i].description + "</p>";
    newhtml += "</div>";
  }
  $(".playlist").html(newhtml);
  loadepisodes();
  flickerme();
}


```

# 成果物


https://embed.plnkr.co/plunk/FipTjN4nfNy7dwbz


以上。
RAGに代わる新しいアプローチ：Cache-Augmented Generation (CAG)の可能性


## はじめに

最近、大規模言語モデル(LLM)の外部知識を活用する手法として、Retrieval-Augmented Generation (RAG)が注目を集めています。しかし、RAGにはいくつかの課題があります。今回は、RAGに代わる新しいアプローチとして提案されているCache-Augmented Generation (CAG)について解説します。

## RAGの課題

RAGには以下のような課題があります：

- 検索の遅延が発生する
- ドキュメント選択のエラーが起こりうる 
- システムの複雑性が高い

## CAGとは

CAGは、これらの課題を解決する新しいアプローチです。主な特徴は：

1. 事前に関連するリソースをLLMのコンテキストにプリロード
2. ランタイムパラメータをキャッシュ
3. 推論時に追加の検索ステップが不要

特に、限定された知識ベースを扱うケースで効果を発揮します。

## CAGの動作の仕組み

CAGは以下の3つのステップで動作します：

### 1. 外部知識のプリロード
- 関連文書をLLMの拡張コンテキストウィンドウに合わせて前処理
- キー・バリュー（KV）キャッシュを生成
- 生成されたキャッシュをディスクまたはメモリに保存

### 2. 推論処理
- ユーザーのクエリと事前計算されたKVキャッシュを使用
- 実時間の検索なしで回答を生成
- 検索遅延とエラーを防止

### 3. キャッシュのリセット
- システムのパフォーマンスを維持するための効率的なキャッシュリセット
- 新しいトークンが追加された際の迅速な再初期化

## 実験結果と性能評価

研究チームはSQuADとHotPotQAデータセットを使用して、CAGと従来のRAGシステムの性能を比較しました：
- BERTScoreによる評価で、CAGは多くのケースでRAGを上回る性能を示しました
- 特に検索エラーが発生しやすい状況での優位性が顕著
- 標準的なin-context学習と比較して、生成時間が大幅に短縮

## RAGとCAGの比較

CAGの利点：
- 検索遅延の排除
- 検索エラーの最小化
- システムの単純化

一方で、以下のような制約もあります：
- コンテキストウィンドウのサイズに制限される
- 大規模な知識ベースには不向き

## 今後の展望

- より大規模な知識ベースを処理できるLLMの発展に伴うCAGの可能性拡大
- CAGとRAGを組み合わせたハイブリッドアプローチの研究
- コンテキストの完全性と柔軟性を両立する新しい手法の開発

## まとめ

CAGは、特定のユースケース（限定された知識ベース）において、RAGに代わる効率的な選択肢となる可能性があります。今後のLLMのコンテキストウィンドウの拡大に伴い、さらなる応用が期待されます。

<br>

👉 原文は[こちら](https://arxiv.org/abs/2412.15605?utm_source=pytorchkr&ref=pytorchkr)でご確認いただけます。
Use Apex in Transaction Security Policies



# the module 'Use Apex in Transaction Security Policies'

+ [I am unable to complete the module 'Use Apex in Transaction Security Policies'
](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000PeLGL)

:::note
Please check this article.

https://ryanwingate.com/salesforce/advanced-administrator/modules/enhanced-transaction-security/
:::

# Can't save policy. Duplicate Apex class name. Check that the first 25 characters of the policy name (excluding spaces) are different from those of an existing auto-generated Apex class name.

+ [Use Apex in Transaction Security Policies.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KCh1J)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/05305df5-eac1-e54a-8c3c-6958dfe73c90.png)

:::note
Try renaming the Apex class you created by mistake. 

Setup --> Apex Classes 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/04316a6c-39fd-5dd2-51bc-5073be0ea7f8.png)
:::
PrimeVue のコードの辿り方

ここ2年くらい PrimeVue を使い続けて身に着けたことをざっくりまとめました。

:::note warn
- 2025/01 時点での情報になります
- この記事では PrimeVue の導入手順は紹介しません
- 書いていくうちに普遍的な内容になってしまいました:astonished:
:::

## 最初に読むべき情報

公式ドキュメントを読みます。
PrimeVue は昨年メジャーバージョンが v3 から v4 に変わったため現在 v3 と v4 に関する公式ドキュメントが存在します。

↓ 最新（v4）のドキュメント：https://primevue.org/

https://primevue.org/

↓ v3 のドキュメント：https://v3.primevue.org/

https://v3.primevue.org/

↓ v3 から v4 への移行ガイド：https://primevue.org/guides/migration/v4/

https://primevue.org/guides/migration/v4/

これから新しく PrimeVue を始める場合、特に理由がなければ v4 がおすすめです。
- v3 には有るが v4 に無いといった機能はこれと言って無い（と思う）こと
  - 一部 v3 に存在したコンポーネントについて名前が変わったり、統廃合が行われてはいる
  - 詳しい情報は上記の移行ガイド内に書かれています
- v3 の頃はカラーモードの切り替えについてライトテーマ/ダークテーマのcssを読み込み直すといった作業が必要で、これが切り替え時の画面のチラつきの原因になっていました。。テーマに関する仕組み自体に更新が入り、v4 ではシームレスな切り替えができるようになりました
  - 詳しい情報はこちら ⇒ https://primevue.org/theming/styled/
- 各コンポーネントのドキュメントについて v4 の方が充実している（Pass Through に関する情報とか特にそう）

## 詰まったときに読むと解決するかもしれない情報

最近はあまり起きませんが、過去 v3 の頃は稀に公式ドキュメントには記載があっても実際には動作しないといったケースがありました（具体例について忘れてしまいましたが DataTable コンポーネントのパススルーに関連した話だった気がする。。）
ちゃんと設定したはずなのにうまく動かないと思った時は GitHub の公式リポジトリ内のソースを読んだり、解決済みを含む issue を漁ったりすると話題に上がっていることもあるかもしれません。

↓ 公式リポジトリ

https://github.com/primefaces/primevue/

うまく動かなかったときに公式リポジトリ内のソースを確認する場合ですが v3 と v4 でコンポーネント・ディレクティブの置き場所が異なります。

導入している PrimeVue が v4 の場合は最新の master ブランチを見ればいいと思います。
その中でコンポーネントなど主に見るべき情報は `packages/primevue/src` 内に存在します。

https://github.com/primefaces/primevue/tree/master/packages/primevue/src

導入している PrimeVue が v3 の場合は master ブランチではなく v3 というブランチを見ると良いと思います。その中で主に見るべき情報は `components/lib` 内に存在します。

https://github.com/primefaces/primevue/tree/v3/components/lib

その他、特定のバージョンにおける話の場合はそのバージョンのソースを確認するとより良いと思います。
リポジトリのリリース一覧画面から辿ることもできますが、以下のようなURLにアクセスすることで直接パッケージのバージョンに対応したソースへアクセスできます。

`https://github.com/primefaces/primevue/tree/[primevue パッケージのバージョン]`
エフェクター用の計算式

# はじめに
- 簡易エフェクターを作るのに使った数式をまとめてみました

# 音階と周波数
A4(ラ)から$x$音上の音の周波数は、

$ y=440*2^{\frac{x}{12}}$

逆関数
$x=12log_2(\frac{y}{440})$

# 再生時間(wavファイル)
$N$...データ部の長さ
$sample$...サンプリング周波数[Hz]
$ch$...チャンネル数
$bit$...ビット数[bit]
$T$...時間[s]

$T=\frac{8N}{sample * ch * bit}$

# BPMと間隔
$BPM$...BPM
$T$...拍子の間隔[s]
$n$...n分音符　(付点n分音符は、$\frac{3n}{4}$分音符)

$T=\frac{240}{n*BPM}$
# 調
元の調(1×#の数　-1×♭の数)が $p$ で、ピッチが $q$ 上がり、調号を$r$個付けた時の調は

$ ((p+7q+6+r)$ mod $12)-6$

長調から短調に変換...$r=-3$　短調から長調に変換...$r=3$
ただし、F#とD#m(ともに#×6)は$-6$になる

例：#×4の曲で、半音1つ上がるような転調をすると、
$((4+7*1+6+0) $ mod $ 12)-6=-1$
で、調号は♭×1になる。

プログラミングで使用する際は、
$ ((p+7q+6+r+1200)$ mod $12)-6$
のように、適当な12の倍数を足す。(負の数を避ける)

# ボイスキャンセラー
$f_L(t)$...左チャンネルの波形
$f_R(t)$...右チャンネルの波形

$\frac{f_L(t)-f_R(t)}{2}$または$\frac{f_R(t)-f_L(t)}{2}$　

左右別々の式を使うか、片方に遅延をかけるとモノラル化を避けられる

# コンプレッサー
$a$...定数

$f(t)|f(t)|^{a-1}$または$sign(f(t))|f(t)|^{a}$

音割れに注意

# フランジャー
$g(t)...$適当な周期関数

$\frac{f(t)+f(t+g(t))}{2}$

プログラミングでは、$t+g(t)$が範囲外にならないように注意

# 畳み込みリバーブ
$F$...フーリエ変換
$g(t)$...IRデータ(破裂音)

$F^{-1}[F[f]F[g]]$

(畳み込みの定理)

# 再生速度変更
$x$倍速　ピッチ$y$のとき、
- まず、波形($f(t)$)を任意の長さのフレームに分け、
$x*2^{-\frac{y}{12}}$個目ごとに取り出して繋げる
※フレーム間は補間する必要あり(ノイズが出る)
※フレームサイズうまく調節しないと不自然になるので注意
- $f(2^{\frac{y}{12}}t)$を取得する


何かあれば追加します
【React】基本的なHTMLをしっかりと理解していないと死ぬ話

## はじめに

死ぬは言いすぎましたね、すいません
Reactはコンポーネントベースのライブラリで、宣言的なUIを作成できる便利なツールですが、基本的なHTMLの理解が足りないと詰むことがあります。
今回は、私がHTMLの知識不足であったことを理由に
Reactのレンダリング挙動でハマった事例を紹介します。

## 事例：簡単なタスク管理アプリ
以下のコードは、タスクを追加・削除する簡単なToDoアプリです。

```jsx
import { useState } from "react";

const Example = () => {
  const [input, setInput] = useState('');
  const [tasks, setTasks] = useState([]);

  const setInputValue = (e) => {
    setInput(e.target.value);
  }

  const addTask = () => {
    setTasks([...tasks, input]);
    setInput('');
  }

  const doneTask = (e) => {
    setTasks(tasks.filter((task) => task !== e.target.value));
  }

  return (
    <>
      <h1>Reminder</h1>
      <input type="text" onChange={setInputValue} value={input}/>
      <button onClick={addTask}>addTask</button>
      {tasks.map((task) => (
        <>
          <p key={task}>{task}</p>
          <button onClick={doneTask} value={task}>完了</button>
        </>
      ))}
    </>
  );
};

export default Example;
```
### 以下のような挙動（※DB連携はしていないです）
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909033/f49d64fe-4a87-a7e1-e6a9-ea39bcc05203.gif)



## 修正前はどんな挙動でどんなコードだったか？

### 以下のようなコードでした
差分はinputとbuttonをformでラップしているかどうかの違いです
```jsx
import { useState } from "react";

const Example = () => {

  const [input, setInput] = useState('');
  const [tasks, setTasks] = useState([]);
  const setInputValue = (e) => {
    setInput(e.target.value);
  }
  const addTask = () => {
    setTasks([...tasks, input]);
    setInput('');
  }
  const doneTask = (e) => {
    setTasks(tasks.filter((task) => task !== e.target.value));
  }

  return (
    <div style={{ textAlign: "center", paddingTop: "20px" }}>
      <h1>Reminder</h1>
      <form action="">
        <input type="text" onChange={setInputValue} value={input}/>
        <button onClick={addTask}>addTask</button>
      </form>
    </div>
  );
};

export default Example;
```
## 挙動
タスクが正常に追加されない....?!
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909033/f3a3916e-50e9-40a2-02f2-33c919ef76f4.gif)

## 原因
正常に動作するコードとの差分はformも有無なのでそこに原因があると推測
よく見るとURLにクエリが....(あ.....)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909033/eb8db12f-930a-0ca2-1ece-050281641931.png)


formタグはHTTPメソッドやactionを設定してページ遷移やデータの受け渡しを可能にするんでしたね
今回の場合クエリに空文字が渡されそのURLが再読み込みされるため
下の画像のトップレベルコンポーネントである
Example
が再実行されコンポーネント全体が再レンダリングされてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909033/d938a5eb-0eeb-d0cf-49aa-389db168c071.png)

そのため、タスクを追加しても初期化状態に戻ってしまうのです。

## まとめ



Reactを使う際、以下のポイントに気をつけましょう。



1. `form` を使用するときは `onSubmit`や各属性を適切に使う。

2. HTMLの基本動作を理解していないと、Reactの挙動にハマることがある。



Reactを使う前に、HTMLとDOMの基本的な動作を理解しておくことが、スムーズな開発につながります！！
初心に戻って約１AのLチカから再スタート

# 原点に戻って約１アンペアのLチカから再スタート

TLP-A100とTLP-P055を使用して約1A出力のLチカやってみました。

## ソースコード

```cpp
#define PIN_LED 5

boolean gLED;

void setup() {
  // put your setup code here, to run once:
  pinMode( PIN_LED, OUTPUT );
  digitalWrite(PIN_LED, LOW);
  gLED = false;
}

void loop() {
  // put your main code here, to run repeatedly:
  if ( gLED ) {
    gLED = false;
    digitalWrite(PIN_LED, LOW);
  } else {
    gLED = true;
    digitalWrite(PIN_LED, HIGH);
  }
  
  delay(1000);
}
所有者のまとめ

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)

--------------


+ [各レコードの「所有者を変更」のマークを押すとフローを通さずに変更出来てしまいます。 所有者変更をかけたいときにフローを起動させる方法をご教示いただけないでしょうか。 ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KgjTX)

:::note
このアイコンを上書きできるとは思えないですね。 

所有者の数式項目を作って表示されている標準の所有者の項目と置き換えることで、このアイコンを表示させないようにすることはできそうです。 

I created a formula field to capture the owner's first and last name. I then replaced the native field in all active page layouts and compact layouts. 

https://ideas.salesforce.com/s/idea/a0B8W00000Gdj2FUAR/communities-remove-change-owner-icon-when-field-is-readonly-to-the-profile
:::

# 個別の回答

+ [取引先の所有者を変更した時に、商談の所有者を変更するトリガー](https://qiita.com/Keiji_otsubo/items/f7890cc40d329a46007c)
+ [取引先の所有者が変更された場合に取引責任者の所有者も変更する](https://qiita.com/Keiji_otsubo/items/5e4c0aeb12f11d6785b7)
+ [取引先の所有者を変更する](https://qiita.com/Keiji_otsubo/items/df64f43b8248603a725d)
+ [リードが変換された後で、リードの客の所有者を変更できますか?](https://qiita.com/Keiji_otsubo/items/6edd032d129ca6230ea7)
+ [ケースにアップロードしたファイル(ContentDocument)の所有者をケースの所有者に変更したい。](https://qiita.com/Keiji_otsubo/items/3fb66005bb8f0cf63bdb)
AmazonLinux 2023にCerbotを入れてSSL化するまでの流れ

## AmazonLinux2023にCerbotを入れる流れを毎回忘れるので備忘録

#### ①システムのパッケージ更新を忘れずに
`sudo dnf update -y`

#### ②cerbotのインストール
標準パッケージにcerbotが含まれているそうなので、余計なインストールはせずに素直に以下のコマンドを叩く
今回はNginxを使うので、nginx向けのパッケージをインストール
`sudo dnf install -y certbot python3-certbot-nginx`

#### ③SSL化の実行
早速ドメインをSSL化する、以下のコマンドでドメインをSSL化できる
-dはドメインの指定なので、SSL化するドメインをその後ろに入れてあげる
`sudo certbot --nginx -d example.com -d www.example.com`

途中メールアドレスを聞かれるので、普段使っているメールを入れるといいと思う
証明書の有効期限が近づくとメールで通知してくれるのはありがたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997711/19c9d1bd-500e-cf28-724d-c788958e78ef.png)

その後色々聞かれるので、"Y"を入力して進めていく

Successfullyと出たら証明書が発行されているので、確認しにいくと有効化されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997711/4f80b849-75ed-5fa3-0e57-7a289c3a5b6b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997711/871923ca-4a39-7e82-5105-033620fd607b.png)

④証明書の自動更新
証明書の自動更新をしておくと、忘れずに済むので結構便利
以下のコマンドで、自動更新ができるかどうかをまずはテスト
`sudo certbot renew --dry-run`

Congratulationsと出たらうまくいっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997711/a7f38041-0f63-7bf0-de30-0c203954fbd1.png)

crontab -eコマンドでcronを設定しよう
これは定期実行をさせるための機能で、あるタイミングで更新コマンドを実行させるために使う
`sudo crontab -e`

とりあえず、2ヶ月に1回午前3時のタイミングで更新するように設定
この辺りの詳しい解説はネットに落ちてるから見てみるといいかも
`0 3 1 */2 * /usr/bin/certbot renew --quiet`

以下のコマンドの入力で設定値が適用されていたら完成
`crontab -l`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3997711/126bfa40-8924-c83e-c794-1d6c4326e4ea.png)

これでSSL化が無料で行える
突然"Docker"は壊れている と言われた

Mac（14.7.2）を再起動したら突然「"Docker"は壊れているため開けません。ゴミ箱に入れる必要があります。」といわれた。

![スクリーンショット 2025-01-29 13.09.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547099/5075a267-f94f-df38-b689-73f28b264b5a.png)



Workaroundコマンドを実行したら、無事にDockerを起動できた。

https://github.com/docker/for-mac/issues/7520
最安はどこ？送金手数料ゼロも！主要ブロックチェーン徹底比較

# 🚀 ソラナより送金手数料が安いブロックチェーン（手数料安い順）

ブロックチェーン技術の進化により、送金手数料が低いネットワークが増えています。本記事では、ソラナ（Solana）を基準に、さらに低コストまたは無料で送金可能なブロックチェーンを比較し、それぞれの特徴やコード例を紹介します。手数料は日本円換算で分かりやすく説明し、**手数料が安い順**に並べ替えました。

---

## 💎 Nano（ナノ）
- **💰 手数料**: **完全無料**。
- **⚙️ 特徴**: 独自の「ブロックラティス」構造を採用し、高速かつ無料の取引が可能。
- **🎯 用途**: マイクロペイメントや日常的な取引に最適。

---

## 🏆 Tron（トロン）
- **💰 手数料**: 平均 **0.00013円**（0.000001ドル換算）。
- **⚙️ 特徴**: 毎日5,000ポイントの無料帯域幅で最大15回まで無料送金可能。
- **🎯 用途**: スマートコントラクトやトークン転送。

---

## 🌐 Stellar（ステラ）
- **💰 手数料**: 平均 **0.00045円**（0.0000035ドル換算）。
- **⚙️ 特徴**: クロスボーダー送金に特化した設計で、銀行口座を持たない人々にもアクセス可能。
- **🎯 用途**: 国際送金や小額決済。

---

## 🌟 ソラナ（Solana）
- **💰 手数料**: 平均 **0.03円**（0.00025ドル換算）。
- **⚡ 特徴**: 高速なトランザクション処理能力（1秒間に数千件）。
- **🎯 用途**: DAppsやスマートコントラクトに最適。

### **ソラナでの送金コード例（JavaScript）**
```javascript
const web3 = require("@solana/web3.js");

// 接続設定
const connection = new web3.Connection(web3.clusterApiUrl("devnet"), 'confirmed');

// ウォレット作成
const from = web3.Keypair.generate();
const to = web3.Keypair.generate();

(async () => {
    const transaction = new web3.Transaction().add(
        web3.SystemProgram.transfer({
            fromPubkey: from.publicKey,
            toPubkey: to.publicKey,
            lamports: web3.LAMPORTS_PER_SOL / 100, // 0.01 SOL
        })
    );

    const signature = await web3.sendAndConfirmTransaction(
        connection,
        transaction,
        [from]
    );
    console.log('Transaction Signature:', signature);
})();
```

---

## 💎 イーサリアム（Ethereum）
- **💰 手数料**:
  - 低負荷時: 約 **130円**（1ドル換算）。
  - 高負荷時: 約 **650円**（5ドル換算）。
- **⚙️ 特徴**: スマートコントラクトやDeFiアプリケーションに強み。
- **🧮 手数料計算**: ガス価格 × ガス使用量。

---

## 🏆 ビットコイン（Bitcoin）
- **💰 手数料**:
  - 低負荷時: 約 **130円**（1ドル換算）。
  - 高負荷時: 約 **1,300円**（10ドル換算）。
- **🔒 特徴**: 最も普及している暗号資産で、セキュリティが高い。
- **🎯 用途**: 大規模な価値移動やストアオブバリュー。

---

## 📊 比較表

| 🌐 ブロックチェーン | 💵 平均手数料       | ⚡ トランザクション速度 | 📝 特徴                          |
|------------------|----------------|--------------------|-----------------------------|
| Nano             | 無料           | 高速               | 手数料ゼロで環境に優しい         |
| Tron             | 0.00013円      | 高速               | 無料帯域幅で低コスト実現         |
| Stellar          | 0.00045円      | 高速               | 国際送金に特化                 |
| ソラナ           | 0.03円         | 高速               | DAppsやNFT向け                 |
| イーサリアム      | 130～650円     | 中速               | スマートコントラクト対応         |
| ビットコイン      | 130～1,300円   | 遅い               | セキュリティと普及率が高い       |

---

## 🔗 テスト用ウォレットアドレス

以下はテスト用ウォレットアドレスです。興味がある方は少額で送金を試してみてください。

- **💸 Nano アドレス (XNO)**:
`nano_3948w6cfobqpwyf4b91eq1hn4d5154pqwukd55pgqwuknr1pjmr57me6unqg`  
- **💸 Tron アドレス (TRX)**:
`TYkKF5C6oQfKnxsWpfB8PmSg2waaiH48cJ`  
- **💸 Stellar アドレス (XLM)**:
`GCSMWCACKVEZ737GZAV4AJRFL52ZZKVQ7M3B3KYY64JJGOAO2GDYKABO`  
- **💸 Solana アドレス (SOL)**:
`EnPFbqDbF67rU9mAPvfgh4YYtncJNbFQ9NLQ5R6z5S2f`  
- **💸 Ethereum アドレス (ETH)**:
`0x5CDA2F68f59F641B00aD172475c3d5fC10321174`  
- **💸 Bitcoin アドレス (BTC)**:
`bc1qmtchyeta2w5guyqswd5wnka62zwc4qqya5zrf4`

---

## ✅ 結論

NanoやTron、Stellarはソラナよりもさらに低コストで送金可能な選択肢です。一方、イーサリアムやビットコインは高コストですが、それぞれ独自のユースケースがあります。エンジニアとしてはプロジェクトの要件やユースケースに応じて最適なブロックチェーンを選びましょう！ 😊
いにしえのCPU逆アセンブラ、詰め合わせセット

------------------------------------------------------------
	これは、クラシカルなCPU(i8086exe/Win3.1/Win32/WinCE)
    x86/MIPS/ARM32/SH2 向けのバイナリー解析用・逆アセンブラです。
------------------------------------------------------------

# 概要：
・DISWIN は、WindowsのNE(New Executable)フォーマットおよび、
  PE(Portable Executable)フォーマットの実行ファイルを解析するツールです

 i8086/80386～80586 と、WindowsCEの MIPS / ARM32 / SH2 の実行ファイル(exe)
 に対応しています。

 自分の作成したexeであれば、シンボル情報の読み込みを行なってラベル名表示も出来ます。
 
 NE/PEフォーマット以外に、ROMのようなフォーマットを持たないバイナリーも一応入力
 が可能です。

# 公開リポジトリ

https://github.com/iruka-git/DISASM_Classic

-----------------------------------------------------
# ビルド方法:

・おそらく、32bit環境のgcc (Win32/Linuxいずれか)が必要です
・make でビルドします。
・x86_64環境のgcc (64bit) では正常な実行ファイルが得られないようです。

・いずれ 64bit gcc環境でリビルド出来るようにする予定ですが、~~未着手です。~~

・一応、diswin,disr3000,disshはx64 linux gccでビルド出来るようになっています。


-----------------------------------------------------
# Diswin 0.19 の概要

 
 *  ＤＩＳＷＩＮ（Ｗｉｎｄｏｗｓ用逆アセンブラ）
 
 *  Borland-C++ 4.0J/3.1 or Turbo-C 2.0  LARGE MODEL 
 *    Compile option= -O -ml -w-rvl -w-pro
 *
 *  使い方：
 *      DISWIN -Option filename[.EXE .DLL]
 *  オプション：
 *   -b    セグメント化されたバイナリーを出力する
 *   -s    逆アセンブルソースファイルを出力する
 *   -u    逆アセンブルリストを大文字で出力
 *   -t    エントリーテーブルを表示するモード
 *   -r    リロケーション情報を表示するモード
 *   -x    ＥＸＰＯＲＴされたエントリーのリストのみ表示する
 *   -v    verbose mode
 *
 *  注意：
 *      ラージモデルが前提.
 *

# なんで、いまごろ、いにしえなの？

- ちょっと自分で使う用事ができてしまったため、Diswin19を掘り起こしてみました。
- おまけで、MIPS/ARM32/SH2も付いてます。
- i8086/286/386/486/586 (Pentium) は、もはやれがしー

# SC/MP とかないの？

- よくぞ聞いてくれました。
- SC/MP-IIエミュレーター上で動くセルフ逆アセンブラは、ありまーす。

https://github.com/iruka-git/SCMP2monitor

```
 ./scmp2.exe -q moni2.bin
 * SC/MP-II Monitor *
 >l
 0000 08          NOP
 0001 31          XPAL P1
 0002 C4 80       LDI  #80
 0004 31          XPAL P1
 0005 35          XPAH P1
 0006 C4 FF       LDI  #FF
 0008 35          XPAH P1
 0009 C4 FE       LDI  #FE
 000B C9 00       ST   00(P1)
 000D 37          XPAH P3
 000E C4 01       LDI  #01
 0010 37          XPAH P3
 0011 33          XPAL P3
 0012 C4 CF       LDI  #CF
 0014 33          XPAL P3
 0015 3F          XPPC P3
 >
```

・ Cで書いた奴はないのか？

SC/MP-II エミュレータのデバッグ用に、ステップ実行ログを逆アセンブルしてログに吐く機能があるので、そこを使えばできるとおもう・・

そもそも、このセルフ逆アセンブラは、C記述から落とし込んだ奴なので。
processingとfisicaでアクションゲームのベースを作る

# はじめに
　Processingでゲームを作る場合、自分でいちから書く方法と、なんらかのライブラリを使う方法があります。宇宙空間を漂うシューティングゲームとかであれば、動きと衝突判定だけなので、自力でも楽ですが、アクションゲームとなると、衝突時の動きを計算するのがとてもに大変です。
　なのでfisicaライブラリを使った場合、アクションゲームはどう書けばいいのか、というサンプルを示します。

# 環境
MacOS 13.4.1
Processing 4.2
Fisica

# 物理でうごかす
　fisicaを使ってカーソルキーでキャラクタを動かそうとする場合、キャラクタの位置を直接操作するのではなくて、「力を加えて」、加速度->速度->位置、とfisicaの物理計算に合わせる必要があります。直接、位置を指定すると、予期せず、壁にめり込んだりすることが生じます。より具体的には、次の命令を使って操作します。（細かな違いはわかりませんでした）
addForce()
addImpulse()

# サンプル
白い正方形をカーソルキーとスペースキーで操作して、のぼったりするサンプルです。
物理パラメータは、いい感じに調整済みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/235241f8-5341-a09e-87cf-4d3635552f30.png)













# コード

気づき：
　getMassはあるけど、setMassはなく、サイズで質量が決まる。質量を変えたいときはどうするのかというと、setDensityで濃度調整によって実現する。

　キー入力は「key」と「keycode」の変数の中身は、最後に押された一つしか保持されないようで、カーソル移動しながらジャンプ（スペース）すると、カーソル移動ができなくなり、押し続けているのに、押されてない判定になってしまう。
　なので、各キーに対し、boolean変数を用意して、keyPressedとkeyReleasedでtrue,falseを制御している。


```java
import fisica.*;

FWorld world;
FBox me;  //自分

boolean L_key, R_key;//キャラクタ左右操作用、trueのときは押されてる

void setup() {
  size(1280, 720);//16:9(HD)

  Fisica.init(this);
  world = new FWorld();
  world.setEdges();

  // blockを作成(x,y,w,h)
  addBlock( 400, 600, 200, 20);
  addBlock( 700, 500, 200, 20);
  addBlock(1000, 400, 200, 20);
  addBlock( 800, 300, 100, 20);
  addBlock( 600, 200,  50, 20);

  //自分(x,y)
  me = me(200, 500);

  //重力
  world.setGravity(0, 100);
}

void draw() {
  background(255);
  
  if(L_key){
    me.addForce(-200, 0);
  }
  if(R_key){
    me.addForce(200, 0);
  }

  //５回進めて、１回描画
  world.step();
  world.step();
  world.step();
  world.step();
  world.step();
  world.draw();
}

void keyPressed() {
  //速度Yが0のときだけジャンプ
  if ( key == ' ') {
    if (me.getVelocityY()==0) {
      me.addImpulse(0, -200);  //me.addForce(0, -10000);
    }
  }
  
  //左右移動準備
  if (key == CODED) {
    if (keyCode == LEFT) {
      L_key = true;
    }
    if (keyCode == RIGHT) {
      R_key = true;
    }
  }
}

void keyReleased(){
  if (key == CODED) {
    if (keyCode == LEFT) {
      L_key = false;
    }
    if (keyCode == RIGHT) {
      R_key = false;
    }
  }
}

void addBlock(int x, int y, int w, int h) {
  FBox b = new FBox(w, h);  //サイズ
  b.setPosition(x, y);      //位置
  b.setFill(212, 72, 32);   //色
  b.setStatic(true);        //固定
  b.setFriction(0.2);       //摩擦抵抗
  b.setRestitution(0);      //反発係数
  b.setName("block");       //名前
  world.add(b);
}

FBox me(int x, int y) {
  FBox c = new FBox(40, 40); //サイズ
  c.setDensity(0.25);        //サイズが20x20のときdensity=1なので、40x40のときdensity=0.25にします。
  c.setPosition(x, y);       //位置
  c.setFill(255, 255, 255);  //色
  c.setVelocity(0, 0);       //速度
  c.setDamping(0.3);         //減衰（空気抵抗）
  c.setFriction(0.2);        //摩擦抵抗
  c.setRestitution(0);       //反発係数
  c.setName("me");           //名前
  c.setRotatable(false);     //回転させない
  world.add(c);
  return(c);
}
```

# 画像を貼りたいとき
FBoxのattachImageメソッドを使います。
画像が伸びるのを避けるには、細かくブロックを分ける必要があります。

参考

https://qiita.com/hextomino/items/c3b8418c74d10a79b51b
【DOM操作】

# DOMとは
・webサイトに動きをつけるにはDOM動作の理解が必要
DOMとは、HTMLドキュメントをオブジェクトのように扱える仕組みのこと。
DOMを使えばJavaScriptからHTML要素を取得・作成・更新・削除するといった操作ができるようになる。

# DOM操作の仕組み
ブラウザはHTMLファイルを読み込むと、自動的に以下のようなDOMツリーを生成する
DOMツリーを構成する各要素はノードと言われる
JavaScriptは各種メソッドを使ってこれらのノードにアクセスすることで、HTML要素の取得・作成・更新・削除などを行うことができます。これがDOM操作の仕組みです。

DOM操作の仕組みをまとめると、
①ブラウザがHTMLファイルを読み込むと、自動的にDOMツリーを生成する
②DOMツリーが生成されると、documentオブジェクトが使えるようになる
③ documentオブジェクトを使うと、JavaScriptでDOM操作ができる

※windowオブジェクトはJavaScriptが扱うオブジェクトの最上位に位置している
中には様々なオブジェクトやメソッドが入っている

DOM操作を行うときはまず、「どのHTML要素に動きを加えるか」という「操作の対象」を取得しなければならない＝HTML要素を取得しないとDOM操作ができないということです。

★HTML要素を取得するための主なメソッド★

・getElementById()：HTML要素をidで取得する
・getElementsByClassName()：HTML要素をclassで取得する
・querySelector()：HTML要素をCSSセレクタで取得する（最初の１つ）
・querySelectorAll()：HTML要素をCSSセレクタで取得する（すべて）

★DOM操作でHTML要素を作成するためのメソッド

・createElement()メソッド：HTML要素を新しく作成する
```javascript
//新しくli要素を作成し、定数に代入する
const li = document.createElement('li');
```

・textContent/ innerHTMLプロパティ：HTML要素にテキストを追加する
JavaScriptでHTML要素を作成した場合、ブラウザに表示するにはそのHTML要素を
documentオブジェクトに追加する必要がある
```javascript
//作成したli要素にテキストを追加する
li.textContent = 'VavaScriptで新しく作成したリスト';
li.innerHTML = '<a href="#">JavaScriptで新しく作成したリスト3</a>';
```
・appendChild()メソッド：作成したHTML要素を子要素として末尾に追加する
作成したHTML要素をdocumentオブジェクトに追加するには上記のメソッドを使用する
```javascript
//ul要素の末尾にli要素を追加する
document.querySelector('ul').appendChild('li');
```
時間ではなく、成果物の量で見積もる

アジャイルにソフトウェアを開発しようとする場合 (特に、スクラムを採用する場合)、多くのチームは「ストーリーポイント」などと呼ばれる抽象的な単位で作業を見積もると思います。この時、単純に時間の単位を相対化しただけで見積もろうとするのがよくあるパターンだと思いますが、時間よりも成果物の量を相対化した方がより正確に見積もれるのではないかという仮説が最近私の中に浮かんだのでその話を書きます。

# よくある時間ベースの相対見積もり

まず、一般的に普及していると思われる、時間ベースの相対見積もりのやり方はこんな感じだと思います。

- 「先週機能 A を実装するのにかかった時間を 5 ポイントとすると、来週機能 B を実装するのにかかる時間は何ポイントくらいですか」
- あるいは少し言い回しを変えて、「先週機能 A を実装するのにかかった時間と比べて、来週機能 B を実装するのにかかる時間は何倍くらいですか」

これはこれで悪くないのですが、時間を見積もりの尺度として使っているところにまだ不確かさが残っていそうな気がします。例えばある人は「機能 B は機能 A と同じくらいだ」といい、別の人は「機能 B は機能 A の 2 倍くらいだ」というかもしれません。このような見積もりのズレが起きた時、どのように擦り合わせますか? 単純に平均をとってそれを最終的な見積もりとするというやり方もあるでしょうが、もっと作業内容に関して深く吟味して擦り合わせたいと思ったときに「何となく機能 B は機能 A よりも大変そう」とか「いや機能 A よりも簡単でしょ」とか主観的に主張し合うだけでは正確さに対して全員が自信の持てる結論にたどり着けなそうですよね。

# 成果物の量で見積もる

そこで私が思ったのは、時間を基準に見積もるのではなく、作業が生み出す成果物の量を基準に見積もった方が、ズレを擦り合わせやすく正確さに自信が持てやすいのではないかということです。例えばこんな風に聞きます。

- 「先週機能 A を実装するのに 100 行のコード修正が必要でした。では、来週機能 B を実装するのに何行くらいコーディングが必要ですか」

このように、実際に作らなければいけない成果物がどんなものかを想像しながら語ることで、より客観的で統一された基準で見積もることができると思います。

「機能 B は機能 A と同じくらい仕様が複雑だから、コーディングする行数も大体同じでしょう」「いや、機能 B は既存の共通処理を呼び出すだけで実装できるから、コーディングは 10 行くらいで済む」みたいな議論をする方が、「時間がかかりそう」「かからなそう」と言い合うだけよりも、より正確に見積もれそうな気がしませんか。

このような成果物ベースの見積もりで重要なのは、最終的な成果物だけでなく、全ての作業の中間生成物を含めて見積もることです。そうすることで、実際にやらなければならないだろう作業を洗い出し、見積もりの精度を高めることができます。どんな中間成果物が必要になるかは現場によってまちまちだと思いますが、よくあるソフトウェア開発現場だと以下のようなものを成果物として想定することになりそうです。

- 仕様や設計を検討するために行う会議の議事録の量
- 作成・更新しなければならない設計書や仕様書の量
- 機能を実装するためのコーディングの量
- 自動テストを追加・修正するためのコーディングの量
- 実施する手動テストの量
- ユーザー向けのリリースノートやマニュアルに記載する文章の量
- チーム内で作業状況を連絡したり課題を相談し合ったりするためのコミュニケーションの量

成果物はまだ他にもあるかもしれませんが、実際に行う**全て**の作業に対して対応する成果物を考えて、それらを見積もることが大切です。そうすることで、見積もり時の考慮漏れや認識のズレを減らすことができます。

## 成果物を生まない作業

上記の見積もり方法だと、結果が成果物として現れない作業は見積もりに反映されないことになります。私はそれでよいと思っています。

例えば「設計について一人で考える」という作業がある場合、考えた結果を図や文章としてまとめるならばそれが成果物になります。ちゃんとした文書の体裁をとらずに、適当にメモ用紙とかにラフな図を描くだけで終わりという場合もあるかもしれませんが、その場合でもそのメモ用紙を成果物とみなしてよいと思います。しかし、考えた結果がどこにもアウトプットされず、作業者の脳内にしかないのであれば、その作業 (の成果物) は見積もりに含めなくて構いません。その理由は二つあります。

一つ目の理由は、具現化されない成果物の分量を見積もるのは、時間を基準に見積もるのと同じく、抽象的で、擦り合わせにくいからです。どうせちゃんと見積もれないのだから、見積もらなくてよいです。

もう一つの理由は、具現化されない成果物には価値がないからです。作業の結果が脳内にしかないのであれば、それが他の誰かの役に立つことはありません。作業の結果は、その成果物が他の何かに活用されることによって初めて価値があるのです。私たちは、そのような価値ある成果物を生み出すために作業をするのであり、価値ある成果物だけを見積もるべきです。

例えば設計を考えた後にコーディングするのを一人でやるとします。考えた結果の設計はコードに反映されるでしょうが、成果物はあくまでも書かれたコードだけです。「設計について考えてからコーディングする」のも「いきなりコーディングする」のも他人から見たら判別できないので、作業の内容は無視して、アウトプットされた成果物だけに着目すればよいです。それでもやっぱり設計作業の部分も見積もりたいと思うなら、設計結果をどんな成果物として具体化できそうか議論すべきです。