OmniAICreator/Qiita-1.07M huggingface dataset:
【React】自作したUIライブラリを実際に他のリポジトリから使ってみる。

# はじめに

こんにちは、エンジニアのkeitaMaxです。

前回、自作して公開しましたReactのUIコンポーネントのライブラリを別のリポジトリから実際に使用してみようと思います。

https://qiita.com/keitaMax/items/8657d469e4d2dc094d75

# インストール

まずは別のリポジトリにいって以下コマンドでインストールします。

```
npm install react-ui-components-example
```

https://www.npmjs.com/package/react-ui-components-example

# 実際に表示させてみる

実際に表示させてみましょう。

以下のように`index.tsx`を追加しました。

```tsx:index.tsx
export const CountView = React.memo(() => {
  const { count, addCount } = useCountView()

  return (
      <Button variant="pink">テスト</Button>
  )
})
```

これを`npm run dev`でみてみるといかのようになります。

![スクリーンショット 2024-07-10 13.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/9a04f537-aa29-a19d-53fe-80515971a2a8.png)

コンポーネントはうまく読み込まれていそうですが。

CSSがきいていません。

# TailwindCSSを読み込む

これはコンポーネントのCSSを読み込んでいないのが原因なので、`src/pages/_app.tsx`に以下を追加します。

```tsx:src/pages/_app.tsx
import "@/../node_modules/react-ui-components-example/dist/style.css"
```

また、Storybookで見るためには、`.storybook/preview.ts`にも追加します。
```tsx:.storybook/preview.ts
import "@/../node_modules/react-ui-components-example/dist/style.css"
```

これで再度見てみると、

![スクリーンショット 2024-07-10 13.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/9467e539-45bf-1879-36d5-acc84613fc2a.png)

無事CSSが適応されました。

(もっといい方法ありそうなのでもし知っている人いたら教えていただけると助かります。)

# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！
PromiseからSuspenseに変換する

## 概要

Reactを使っていると、PromiseではなくSuspenseにしたいときが度々ありますが、都度変換のコードを書くのが面倒になったので汎用的な変換関数を作りました。

## コード

```typescript
import { useEffect, useRef } from "react";

/**
 * キーを定義したい場合、こちらに追記してください
 * 定義したキーのみ受け付けたい場合、 |から後ろを消してください
 */
type Key = 'test' | (string & {});

const result = new Map<Key, {
  timeoutId: number;
  value: unknown;
}>();
const waiting = new Map<Key, Promise<unknown>>;

type PromiseResult<FnType extends (...args: unknown[]) => Promise<unknown>> = Awaited<
  Promise<ReturnType<FnType>>
>;

/**
 * コンポーネントが破棄されたとき、cacheTime以内に同一のキーのコンポーネントがこない場合キャッシュを消します
 * cacheTimeを負の数にした場合、即座にキャッシュを消します
 */
export const promiseToSuspense = <T extends () => Promise<unknown>>(key: Key, promise: T, cacheTime = 100): PromiseResult<T> => {
  useEffect(() => {
    const cr = result.get(key);
    // 同一のキーのコンポーネントが来たので、キャッシュ削除をキャンセル
    if (cr && cr.timeoutId !== 0) {
      window.clearTimeout(cr.timeoutId);
      result.set(key, { timeoutId: 0, value: cr.value });
    }
    return () => {
      // cacheTimeに応じてキャッシュを消す
      if (cacheTime >= 0) {
        result.set(key, {
          timeoutId: window.setTimeout(() => {
            result.delete(key);
          }, cacheTime),
          value: result.get(key)?.value,
        });
      } else {
        result.delete(key);
      }
    }
  }, [cacheTime, key]);
  
  // キーが変更されたとき、前のキーのキャッシュを消す
  const keyRef = useRef(key);
  if (keyRef.current !== key) {
    result.delete(key);
    keyRef.current = key;
  }

  // キャッシュがあるか、promiseが解決されていない場合新しくpromiseを呼ばない
  const r = result.get(key);
  if (r) return r.value as PromiseResult<T>;
  if (waiting.has(key)) throw waiting.get(key);

  // promiseを呼び、結果をキャッシュする
  const p = promise();
  p.then(value => {
    result.set(key, { timeoutId: 0, value });
  }).finally(() => {
    waiting.delete(key);
  });
  waiting.set(key, p);
  throw p;
}

```

## サンプル

```tsx
const SampleComponent = () => {
  const promise = new Promise<boolean>((resolve) => setTimeout(() => resolve(true), 5000));
  const result = awaitToSuspense('test', () => promise);
  return <div>{result}</div>;
}

const ParentComponent = () => 
  <Suspense>
    <SampleComponent />
  </Suspense>;
```
[AWS #17] Lambda

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
こんにちは
今回もコンピューティングサービス分野である **「Lambda」** について紹介したいと思います。

:rolling_eyes:らむだ？「λ」ですか？
:upside_down:ギリシャ文字の「ラムダ」ではありません。AWS社が提供するFaaS型のサービスです
## Lambda
Lambdaとは **「ソースコードさえ用意すればそのプログラムを実行できる」** <font color="c00000">**サーバーレスのサービス**</font>です。プログラムを実行するための環境を構築や管理をする**必要がありません**。従って開発者はサービスの管理やメンテナンスから解放されて、**プログラム開発に注力する**ことができます。

:upside_down:サーバーレスでない環境の場合どうでしょうか？
アプリケーションを実行するためには、EC2インスタンスでWebサーバーを構築し、アプリケーションを実行するための環境を準備するなどやることが多くあります。

:rolling_eyes:でも「Lambda」は実行環境を準備する必要がなくソースコードを準備するだけでアプリケーションの実行が可能になるということですね。

:::note info
Lambdaでは、サーバーの構築や環境の準備が不要で<font color="c00000">**直ぐに開発を始められます**</font>
:::

### 言語のサポート
:rolling_eyes:「ソースコード」とありましたが、プログラムのことでしょうか？どんなプログラミング言語に対応しているのでしょうか


:upside_down:一例ですが「C#」「Go」「Java」「Python」「Ruby」が挙げられます。
Lambdaを使うために、特定の言語を改めて学習し直す必要はありません。**使い慣れている言語**で直ぐに始めることができます。

### メリット
Lambdaのメリットの一例を紹介します。

**・サーバー環境管理が不要である**
→上記でも記載しました通り、Lambdaは **「サーバーレス」** のためサーバーの構築管理がいりません。それにより<font color="c00000">**運用コストの削減**</font>に繋がります。

**・他のAWSサービスとの連携**
→一例ですがLambdaは、S3（バケツ）に格納されたデータを自動的に加工することができます。このように他のAWSサービスの操作を**自動化**することが可能です。


## おわりに
ちょっとしたまとめになります。

:::note info
LambdaはAWSが提供している <font color="c00000"> **「サーバーレス」を実現するため**</font>のサービスです
:::
:::note info
必要な時だけコードを実行し、リクエストの回数に合わせて <font color="c00000">**「自動スケール」**</font>をします
:::
:::note info
他のAWSサービスと<font color="c00000">**連携が可能**</font>です
:::

Lambdaを使うとAWSサービスの処理を簡単に自動化することができるということがわかりました。最後までお読みいただきありがとうございました！

>日頃より活用している参考書です。
>> **「参考書」**
[AWS認定クラウドプラクティショナー改定第3版](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[AWS Lambda](https://aws.amazon.com/jp/lambda/)
>
> **「参考元」**
[Lambdaで何ができるか？](https://www.stylez.co.jp/aws_columns/cloud-native_development_on_aws_and_serverless/what_is_aws_lambda/)
>
> **「Youtube」**
[【CLF-C02：AWSクラウドプラクティショナー】第21回 AWS Lambda (クラウドテクノロジーとサービス分野)](https://www.youtube.com/watch?v=Z5Mc4mMyRiE&ab_channel=AWS%E8%B3%87%E6%A0%BC%E5%AF%BE%E7%AD%96%E8%AC%9B%E5%BA%A7)
Bedrockの新機能「Prompt management in Amazon Bedrock」

Bedrockに新機能「 **Prompt management in Amazon Bedrock** 」が追加されました。🎉🎉🎉
現段階でプレビュー扱いで、東京リージョンでも使用できます。

https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-management.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/5d4e4f7d-8b88-5215-8dbc-3b0a1d71c8b7.png)

:::note
同時に追加されたPrompt flows for Amazon Bedrockについてはこちら

Bedrockの新機能「Prompt flows for Amazon Bedrock」
https://qiita.com/moritalous/items/a902f61093b112ba1bd7
:::

早速試してみました。

このような画面です。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/780dc9cd-045b-3829-5844-4ea008631814.png)

この部分にプロンプトを記述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/1db592c4-ff6d-0daa-70d0-795f55a1c453.png)

プロンプト中に変数を含めることができます。変数は「 **{{variable}}** 」のように波括弧2つで囲います。

変数は自動で認識され、下のエリアにリストアップされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/661cba62-2726-2ae9-09cc-bb87bf864970.png)

プロンプトをカスタマイズしてみました。変数が２つになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/a303a724-7b8a-7ec7-30aa-4afb043e8020.png)

オプション設定ですが、モデルを選んでパラメーターの設定が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/7cb4e261-11e2-59b5-6ce3-6453cd8cbec7.png)

モデルを選択すると、右側のエリアでテストを行うことができます。変数に値をセットして実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/3b220b44-0140-a9a7-d2f8-e8f0252e2a29.png)

期待通りの動作になるか確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/52388db4-629e-0d96-f983-feffeafacb9d.png)

比較モードを使うと、作成中のプロンプトと、別のプロンプトを並べて確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/187a009d-796d-7bf6-b40c-2a4cdd881bf7.png)

作成したプロンプトは、まずドラフトとして保存し、その後バージョン番号をつけることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/af954ab3-46a4-d190-ba2e-15723e1b8197.png)

派手な機能ではないですが、必要な機能ですね。

ドキュメント上はConverse APIで指定できるとありましたが、現時点で指定方法がわかりませんでした。
ソリューションアーキテクトに求められる視点(9/14)　AWS Resource Access Manager （RAM)

## はじめに
ソリューションアーキテクトに求められる視点を整理してみました。

今回は、**Resource Access Managerです。具体的には、「共有可能なリソースタイプ」** にフォーカスしました。実務でも試験でも、ご参考にして頂けましたら、幸いです。



## **アーキテクトに求められる視点**
複数のチームで構成される会社のAWSアカウント構造を設計しています。
オンプレミスネットワークに接続されているVPCを必要としています。

**Resource Access Managerを使用して共有すべきものは、「サブネット」「トランジットゲートウェイ」のどちらですか？**

## **ソリューション**
共有可能なリソースタイプとしては、どちらも選択できます。

サブネット ec2:Subnet
Transit Gateway ec2:TransitGateway

https://docs.aws.amazon.com/ja_jp/ram/latest/userguide/shareable.html

**しかし、「オンプレミスネットワークに接続されているVPCを必要としている」ので、Resource Access Managerを使用して共有すべきものは、「サブネット」です。**

:::note info
**活用シーン**
**VPCサブネットの共有** 
複数のアカウントで同じVPCサブネットを使用することで、ネットワーク設定を一元管理し、セキュリティグループやルートテーブルの設定を統一できます。
**ライセンス設定の共有** 
AWS License Managerを使用して、ライセンス設定を複数のアカウントで共有することで、ライセンスの一元管理とコスト削減が可能です。
**ファイアウォールポリシーの共有** 
AWS Network Firewallのファイアウォールポリシーを共有することで、複数のアカウントで統一されたセキュリティポリシーを適用できます。
:::

## Resource Access Managerまとめ

| 特徴                                    | 説明                                                                                       |
|-----------------------------------------|------------------------------------------------------------------------------------------|
| リソースの効率的な共有                  | 複数のAWSアカウント間でリソースを共有出来る。リソースの重複を避け、コストを削減し、管理の手間を減らせる。 |
| セキュリティとアクセス制御の強化        | IAMポリシーを使用して、共有リソースへのアクセスを細かく制御出来る。必要な権限だけを付与し、セキュリティを強化出来る。 |
| 組織全体でのリソース管理                | AWS Organizationsと連携することで、組織内の複数のアカウント間でリソースを簡単に共有出来る。組織全体でのリソース管理が簡単になる。 |
| コスト効率の向上                        | リソースを共有することで、各アカウントが個別にリソースを持つ必要がなくなり、コストの削減出来る。例えば、共有されたVPCサブネットやライセンス設定を使用することで、コスト効率が向上する。 |
| 運用の簡素化                            | リソースの一元管理が可能になるため、運用の手間を減らせる。                                           |
| 柔軟なリソース共有                      | AWS RAMは、さまざまなリソースタイプ（VPCサブネット、ライセンス設定、ファイアウォールポリシーなど）を共有することが出来る。 |
| クロスアカウントの作業が出来る          | 異なるAWSアカウント間でリソースを共有することで、クロスアカウントの作業をプロジェクトやチーム間で行える。                   |
| スケーラビリティ                         | リソースのスケーラビリティが楽になる。例えば、共有されたリソースを使用することで、必要に応じてリソースをスケールアップまたはスケールダウンすることが容易になる。 |



#### ソリューションは、あくまで、一例です。他の解決方法もあるので、参考程度にしてください。

#### 読んでいただき、ありがとうございました。
私がプログラミングに集中したいときにやっていること

# はじめに
本記事はQmonus Value Streamの投稿キャンペーン記事です。

# 集中するために
私はそもそも本業プログラマではなく、趣味でプログラミングをやっているのですが、たまーに自分がやっているプロジェクトの進行が遅いときなど、どうしても集中しないといけないことがあります。
そんなときに私がやっていることをご紹介させていただきます。何かの助けになれば、と。

## 音楽
Spotifyで音楽を流します。邦楽だと日本語の歌詞で頭に入ってきてしまい逆にじゃまになるので歌詞がない曲もしくは洋楽を選んでいます。
個人的に好きなのはTobuだったりAviciiだったりします。もしご興味あれば聞いてみてください（布教）。

ただし、多少複雑なアルゴリズムなんかを考えるときにはそんな曲でさえもじゃまになることがあります。そういうときは素直に曲を止めましょう…。もしくは紙かなんかに書いて思考を整理するとやりやすいです。

## 飲み物を近くに置く
集中してるとどうしても喉が渇きます。しかし、喉が渇くたびに冷蔵庫かどこかに飲み物を取りに行くのは億劫でしょう。なので、私はできるだけ手元に飲み物を置くようにしています。ただ、ノートPCでプログラミングしているときに倒れやすいカップを置いておくと致命的なことになる可能性がありますのでそこには気をつけてください。

## 疲れたときは素直に横になる
今まで動いていたコードが機能を追加すると動かなくなる、よくあることですよね。
こういうときは素直に寝ましょう。コードが行き詰まったときも素直に横になったら思ったよりも簡単にアイデアが浮かんでくることがあります。

## アイデアを紙に書き出す
非効率的だと思われるかもしれませんが実は効率的だったりします。もちろんひたすら書くほうがやりやすい、という方もいると思いますが、それで集中できないのなら試してみるのもおすすめです。
アイデアがうまく整理されますよ！

## 動画を見る
いわゆるコメディー系がおすすめです。プログラミングでイライラしていた頭がリフレッシュできますよ。

## 人のコードを見る
正確にいいましょう、「パクる」です。Stackoverflowであったり、GitHubであったり。
検索したらちゃちゃっと見つかったりします。
完全に当てはまるのが見つからなくてもアイデアをもらえることはありますし、最悪ChatGPTに投げればある程度までの問題ならばサクッと解決しちゃいます。

## 甘いものを食べる
甘いものは正義です。研究で甘いものを食べると逆に集中できない、というのがあるそうですが私は断固として主張します、「そんなことはない」と。
イライラが治りますしスッキリできて集中できます。ただ、手がベタベタするといけないのでラムネとかがおすすめです。

## 部屋の温度を下げる
温度が高かったり湿度が高いと集中できません（私だけですか？）。寒すぎるのも考えものですが、ちょっと涼しいぐらいが動きやすいのではないでしょうか。

## 一回違うことをやってみる
全く違うことをやると頭のリフレッシュにも繋がります。
ただ、そっちのほうに気を取られると逆にリフレッシュできないのでササッと片付けるのがおすすめです。

## 外に出る
海外に「Go touch grass」というミームがあるように（？）、外に出ると集中力が高まります。特に緑にふれるのが重要です。

## ゲームする・遊ぶ
リラックスできます。もちろん遊びすぎるのは良くないですが、疲れを軽くしてくれるのと肩の力を抜くのにも役立ちます。
区切りをつけたいのでターン制のゲームがおすすめかも。

## GitHub Actionsを有効活用する
急に方向性が変わりましたが便利です。余計な作業に時間を割かないで問題なくなります。
作るのはめんどくさいかもしれませんがChatGPTに投げればあらかた片付きます。

# 結論
これは私のやり方でしか無く、人によっても集中方法は異なると思います。もしこれおすすめ！みたいなしゅうちゅ方法があれば教えていただけると嬉しいです。
爆速でエクセルの複数シートを一括作成する方法まとめ

複数のシートを一括作成する方法をまとめました。

### エクセルのピボットテーブルを使う
ピボットテーブルのレポートフィルターページの表示
※ゴミセルとゴミシートの削除が必要になります。

***参考文献***

https://note.com/office_haru/n/n35ab7211eece

### pythonのopenpyxlを使う

pythonのopenpyxlの機能とループを組み合わせて複数シートの追加ができます。

https://qiita.com/momomoge/items/9f321871ef8d0dc8acc7
(しくみ)白黒128x64の画像から任意の1Dot(ドット)を求める(SSD1306等)(座標)


目的
水平走査線フォーマットで格納されたROM等から
任意の座標x,yでその座標のDotを0か0以外で求める

画像サイズは、128x64ドットとする。
1ピクセル当たりのビットサイズは、白黒のみの1ビットである
格納単位は、バイト単位とする。バイトは、8ビットとする
水平方向に16バイト使用する
垂直方向は、16バイトづづ1つ繰り上がる




図1


ポインターの値は、yを16倍とxを8で割ると求まる。


![o_coq203.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e3ade5f3-bd59-d83e-1888-53b9ca0a7215.jpeg)



図2

バイトからのビットの取り出しは、xのあまりをnとして2のn乗を掛けた物とする
その値から0から数えて7ビット目だけをとりだす。


![o_coq202.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3d9cbe59-f7e9-82c8-c776-248914a697f6.jpeg)



実際のメインプログラム





```c++


いろいろ

//↓開始　全画面のメイン処理
a = pgm_read_byte_near( ch_data7 + (y << 4 ) + (x >> 3) ) << (x & 0x07);
a = a & 0x80;
//↑終了

いろいろ


```


https://qiita.com/caa45040/items/e322de00db644bfb4c01


●おまけ

https://qiita.com/caa45040/items/f2a6294b5989c6571f81
# UnityでiOSアプリをビルドする方法を完全ガイド！

今回は、Unityで作ったゲームをiPhoneやiPadで動かすために、iOSアプリとしてビルドする方法をステップバイステップで解説。
これを読めば、あなたもすぐにiOSデベロッパーの仲間入りです！

## 必要なツールと環境を揃えよう

まずはじめに、以下のツールと環境が必要です：

- **Unity**：最新バージョンをインストールします。

- **Xcode**：Macユーザーの必須ツールです。
App Storeから入手できます。

- **Apple Developerアカウント**：iOSアプリを実機でテストするために必要です。


### Unityのインストールと設定

Unity Hubを使って最新のUnityをインストールしましょう。
iOSプラットフォーム用のモジュールも追加してください。


### Xcodeのインストール

Macユーザーであれば、App StoreからXcodeをダウンロードします。
最新バージョンを使用しましょう。


### Apple Developerアカウントの登録

Appleの公式サイトでDeveloperアカウントを登録します。
これでiOSアプリをデバイスでテストする準備が整います。


## Unityプロジェクトの設定

次に、UnityプロジェクトをiOS用に設定します。


### ビルド設定を確認しよう

まずは、Unityの「File」>「Build Settings」を開きます。
プラットフォームを「iOS」に変更し、「Switch Platform」をクリックします。
これでプロジェクトがiOS用に設定されます。


### Player Settingsの調整

ビルド設定画面で「Player Settings」をクリックし、アプリの名前やバージョン、バンドルID（「com.companyname.appname」形式）などを設定します。


## Xcodeでビルドとデプロイ

Unityで設定が完了したら、次はXcodeでビルドしてデバイスにデプロイします。


### Xcodeプロジェクトの生成

Unityのビルド設定画面で「Build」ボタンをクリックすると、Xcodeプロジェクトが生成されます。
数分かかることがありますが、完了したらXcodeでプロジェクトを開きましょう。


### 必要なフレームワークとライブラリの確認

Xcodeでプロジェクトを開いたら、必要なフレームワークとライブラリが正しく追加されているか確認します。
Unityが自動で追加してくれることが多いですが、特定の機能を使う場合は手動で追加することもあります。


### 署名とプロビジョニングプロファイルの設定

プロジェクトのターゲット設定で、署名とプロビジョニングプロファイルを設定します。
Apple Developerアカウントで作成したプロファイルを使って、適切なチームを選択しましょう。


### デバイスへのインストールとテスト

設定が完了したら、実際のiOSデバイスにアプリをインストールしてテストします。
デバイスをMacに接続し、Xcodeの「Run」ボタンをクリックすると、アプリがビルドされてデバイスにインストールされます。
インストールが完了したら、デバイス上でアプリを起動して動作を確認しましょう。


## トラブルシューティング

ビルドやデプロイの過程でエラーが発生することがあります。
ここでは、一般的なエラーとその対処法について解説します。


### ビルドエラーの解決方法

ビルド中にエラーが発生した場合、エラーメッセージをよく読み、問題の箇所を特定します。
必要なフレームワークやライブラリが不足していることが原因であることが多いです。
エラーメッセージに従って、必要な項目を追加しましょう。


### デプロイ時の問題解決

デプロイ時にエラーが発生する場合、プロビジョニングプロファイルや署名の設定が正しいか確認します。
また、デバイスが開発モードに設定されているかもチェックしましょう。
デバイスが開発モードになっていない場合、Xcodeから設定することができます。


## まとめ

- **UnityとXcodeの準備をしっかりと行うことが重要**
- **UnityプロジェクトをiOS用に設定する**
- **Xcodeでビルドしてデバイスにインストールする**
- **エラーが発生したらエラーメッセージを読み、適切に対処する**

これで、Unityを使ってiOSアプリをビルドする方法がわかりましたね！自分のゲームがiPhoneやiPadで動くのを見ると、とても楽しいですよ。
ぜひチャレンジしてみてください！

参考

https://feynman.co.jp/unityforest/unity-introduction/tips/unity-ios-play/
【Pybulletサンプル解説】変形可能なボックスを生成【reduced_deformable_cube.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、reduced_deformable_cube.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/reduced_deformable_cube.py)）

本コードを実行すると、「変形可能なボックス」の上に「剛体のボックス」を生成されます。

![reduced_deformable_cube.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/9edacd33-1d75-94e1-7983-133427a42f42.gif)


# 使用している機能
本コードは、以下の機能を使用して「変形するオブジェクトが生成可能なワールドに設定」「urdfファイルからオブジェクトの生成」を実現できます。

## 変形するオブジェクトが生成可能なワールドに設定
`resetSimulation` 関数を使用することで、シミュレーションをリセットできます。
```python
pybullet.resetSimulation(mode)
```
- `mode`：どのモードでシミュレーションをリセットするか
  - `RESET_USE_REDUCED_DEFORMABLE_WORLD`の場合「変形するオブジェクト」が生成可能になります。

## urdfファイルからオブジェクトの生成
`loadURDF` 関数を使用することで、urdfファイルからオブジェクトを生成できます。
```python
pybullet.loadURDF(urdfFile, position)
```
- `urdfFile`：生成するオブジェクトのurdfファイル
  - ワールドが`RESET_USE_REDUCED_DEFORMABLE_WORLD`の場合、変形するオブジェクトを生成できます
- `position`：オブジェクトの生成位置

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
from time import sleep
import pybullet_data

# PybulletをGUIモードで接続
physicsClient = p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# シミュレーションを「変形可能なオブジェクトを生成可能なワールド」にリセットする
p.resetSimulation(p.RESET_USE_REDUCED_DEFORMABLE_WORLD)

# カメラの位置/姿勢をリセット
p.resetDebugVisualizerCamera(4,-40,-30,[0, 0, 0])

# 重力を設定
p.setGravity(0, 0, -10)

# テクスチャを読み込み
tex = p.loadTexture("uvmap.png")

# 床のオブジェクトを生成
planeId = p.loadURDF("plane.urdf", [0,0,-2])

# 剛体のボックスを生成
boxId = p.loadURDF("cube.urdf", [1,1,5],useMaximalCoordinates = True)

# 変形可能なボックスを生成
cube = p.loadURDF("reduced_cube/reduced_cube.urdf", [1,1,1])

# 変形可能なボックスにテクスチャを設定
p.changeVisualShape(cube, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)

# sdfのボクセルのサイズを0.25に設定
p.setPhysicsEngineParameter(sparseSdfVoxelSize=0.25)

# リアルタイムシミュレーションモードをOFFにする
p.setRealTimeSimulation(0)

# pybulletが接続されている間ループを繰り返す
while p.isConnected():

  # シミュレーションを一時刻分進める
  p.stepSimulation()

  # カメラ画像を取得
  p.getCameraImage(320,200)

  # 重力を設定
  p.setGravity(0,0,-10)
```
【Pybulletサンプル解説】変形するオブジェクトを生成【reduced_deformable_torus.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、reduced_deformable_torus.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/reduced_deformable_torus.py)）

本コードを実行すると、「剛体のオブジェクト」と「変形するオブジェクト」が生成されます。

![reduced_deformable_torus.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/26d780f9-f204-5bce-3af8-6620dfca82be.gif)


# 使用している機能
本コードは、以下の機能を使用して「変形するオブジェクトが生成可能なワールドに設定」「urdfファイルからオブジェクトの生成」を実現できます。

## 変形するオブジェクトが生成可能なワールドに設定
`resetSimulation` 関数を使用することで、シミュレーションをリセットできます。

```python
pybullet.resetSimulation(mode)
```
- `mode`：どのモードでシミュレーションをリセットするか
  - `RESET_USE_REDUCED_DEFORMABLE_WORLD`の場合「変形するオブジェクト」が生成可能になります。

## urdfファイルからオブジェクトの生成
`loadURDF` 関数を使用することで、urdfファイルからオブジェクトを生成できます。

```python
pybullet.loadURDF(urdfFile, position)
```
- `urdfFile`：生成するオブジェクトのurdfファイル
  -  ワールドが`RESET_USE_REDUCED_DEFORMABLE_WORLD`の場合、変形するオブジェクトを生成できます
- `position`：オブジェクトの生成位置


# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
from time import sleep
import pybullet_data

# PybulletをGUIモードで接続
physicsClient = p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# シミュレーションを「変形可能なワールド」にリセットする
p.resetSimulation(p.RESET_USE_REDUCED_DEFORMABLE_WORLD)

# カメラの位置/姿勢をリセット
p.resetDebugVisualizerCamera(4,-40,-30,[0, 0, 0])

# 重力を設定
p.setGravity(0, 0, -10)

# テクスチャを読み込み
tex = p.loadTexture("uvmap.png")

# 床のオブジェクトを生成
planeId = p.loadURDF("plane.urdf", [0,0,-2])

# キューブを2つ生成
box1 = p.loadURDF("cube.urdf", [1,1,3],useMaximalCoordinates = True)
box2 = p.loadURDF("cube.urdf", [0,3,2],useMaximalCoordinates = True)

# 変形するオブジェクトを生成
reduced_obj1= p.loadURDF("reduced_torus/reduced_torus.urdf", [1,1,1])

# 変形するキューブにテクスチャを適用
p.changeVisualShape(reduced_obj1, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)

# 変形するオブジェクト（2つ目）を生成
reduced_obj2 = p.loadURDF("reduced_torus/reduced_torus.urdf", [1,2,1])

# 変形するオブジェクト（2つ目）にテクスチャを適用
p.changeVisualShape(reduced_obj2, -1, rgbaColor=[1,1,1,1], textureUniqueId=tex, flags=0)

# sdfのボクセルのサイズを0.25に設定
p.setPhysicsEngineParameter(sparseSdfVoxelSize=0.25)

# リアルタイムシミュレーションモードをOFFに設定
p.setRealTimeSimulation(0)

while p.isConnected():
  # シミュレーションを一時刻分進める
  p.stepSimulation()

  # カメラ画像を取得
  p.getCameraImage(320,200)

  # 重力を設定
  p.setGravity(0,0,-10)
```
【Eclipse/Git】リモートリポジトリをクローンしてプロジェクトを作成する

GitHubにあるリモートリポジトリをクローンして、Eclipseでプロジェクトを作成する（隠しファイルの.projectファイルを追加する）操作を覚えるための自分用メモです。

# Gitリポジトリーから操作する方法
Eclipseのパースペクティブを「Git」にして、Gitリポジトリーの「Gitリポジトリーをクローンし、このビューへ追加」を選択します。

あとは、「クローンURI」を選択し、クローンしたいリモートリポジトリを指定してクローンの操作を完了させます。

クローンが完了したら、「ファイル」→「新規」→「プロジェクト」から作成したいプロジェクトを選択し、「デフォルト・ロケーションを使用」のチェックを外して、ロケーションにクローンしたローカルリポジトリのルートディレクトリを指定してプロジェクトを作成できます。

# ファイル→インポートから操作する方法
上記の方法以外にも、インポートから操作する方法もあります。

Eclipseで「ファイル」→「インポート」→「Git」→「Gitからプロジェクト」→「クローンURI」を選択し、クローンしたいリモートリポジトリを指定します。

次に、ローカルリポジトリを作成するディレクトリを指定したら、「次へ」→「新規プロジェクト・ウィザードを使用してインポート」を選択してクローンの操作を完了させます。

あとは、作成したいプロジェクトを選択し、「デフォルト・ロケーションを使用」のチェックを外して、ロケーションに先ほどクローンしたローカルリポジトリのルートディレクトリを指定してプロジェクトを作成できます。
【Pybulletサンプル解説】Pybulletの基礎的なコード【hello_pybullet.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、hello_pybullet.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/hello_pybullet.py)）

本コードを実行すると、r2d2のモデルが生成されます。

![hello_pybullet.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/96de376c-f720-cc57-ce5a-a20de7a9a74d.gif)

本コードでは、「Pybulletへの接続」「重力の設定」「urdfモデルの生成」「リアルタイムシミュレーションモードの設定」などPybulletでよく使う基礎的な機能が使用されています。

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
from time import sleep
import pybullet_data

# PybulletにGUIモードで接続
physicsClient = p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 重力を設定
p.setGravity(0, 0, -10)

# 床のオブジェクトを生成
planeId = p.loadURDF("plane.urdf")

# キューブの位置、姿勢を指定して生成
cubeStartPos = [0, 0, 1]
cubeStartOrientation = p.getQuaternionFromEuler([0, 0, 0])
boxId = p.loadURDF("r2d2.urdf", cubeStartPos, cubeStartOrientation)

# 生成したキューブの位置、姿勢を取得
cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId)

# リアルタイムシミュレーションモードをOFFにする
useRealTimeSimulation = 0
if (useRealTimeSimulation):
  p.setRealTimeSimulation(1)

while 1:
  if (useRealTimeSimulation):
    p.setGravity(0, 0, -10)
    sleep(0.01)
  else:
    # シミュレーションを1時刻分進める
    p.stepSimulation()
```
【Pybulletサンプル解説】最大速度を設定し、関節を位置制御【motorMaxVelocity.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、motorMaxVelocity.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/motorMaxVelocity.py)）

本コードを実行すると、

![motorMaxVelocity.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/d815cb0c-fe6d-fc61-0467-900511643613.gif)


# 使用している機能
本コードは、以下の機能を使用して「関節のモータ制御」を実現しています。


## 関節のモータ制御
`setJointMotorControl2` 関数を使用することで、オブジェクトのジョイントを制御できます。

```python
pybullet.setJointMotorControl2(objectId,
                        jointIndex,
                        mode,
                        targetPosition,
                        targetVelocity,
                        force,
                        positionGain,
                        velocityGain,
                        maxVelocity)
```

- `objectId`：オブジェクトのID
- `jointIdx`：関節のインデックス
- `mode`：関節の制御モード
    - 今回の場合 `POSITION_CONTROL`（位置制御モード）で設定
- `targetPosition`：目標位置
- `targetVelocity`：目標速度
- `force`：力
- `positionGain`：位置ゲイン
- `velocityGain`：速度ゲイン
- `maxVelocity`：最大速度

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# PybulletにGUIモードで接続
p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# カートポールのオブジェクトを生成
cartpole = p.loadURDF("cartpole.urdf")

# リアルタイムシミュレーションモードに設定
p.setRealTimeSimulation(1)

# カートポールを1番目のジョイントをモータ制御
p.setJointMotorControl2(cartpole,
                        1,
                        p.POSITION_CONTROL,
                        targetPosition=1000,
                        targetVelocity=0,
                        force=1000,
                        positionGain=1,
                        velocityGain=0,
                        maxVelocity=0.5)
                        
while (1):

  # 重力を設定
  p.setGravity(0, 0, -10)

  # ジョイントの位置と速度を取得、表示
  js = p.getJointState(cartpole, 1)
  print("position=", js[0], "velocity=", js[1])
  
  time.sleep(0.01)
```
Javaで「文字列の中で指定した文字または文字列が出現するインデックスを取得する」の動作を確認してみた

# 概要

Javaで「文字列の中で指定した文字または文字列が出現するインデックスを取得する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/string/index18.html

# 実装

以下のファイルを作成しました。
```JSample18_1.java
class JSample18_1{
  public static void main(String[] args){
    String str = "Hello World";
    System.out.println(str.indexOf((int)'o'));
    System.out.println(str.lastIndexOf((int)'o'));
  }
}
```

```JSample18_2.java
class JSample18_2{
  public static void main(String[] args){
    String str = "東京都と京都府";

    System.out.println(str.indexOf("京都"));
    System.out.println(str.lastIndexOf("京都"));
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample18_1.java 
$ java JSample18_1 
4
7
```

```
$ javac JSample18_2.java 
$ java JSample18_2 
1
4
```

# まとめ

何かの役に立てばと。
このアカウントについて / 環境情報

このアカウントでは、私が個人の趣味でラズパイ5を自宅サーバーとして運用するにあたり行った作業のログになります。
なのでほとんどがラズパイ関連の投稿になると思います。

# デバイス・システム情報(2024/7/11時点)
```
$ cat /proc/device-tree/model
Raspberry Pi 5 Model B Rev 1.0
```
メモリは8GB, ストレージはNVMEの256GBSSDを積んでます
```
$ uname -a
Linux genraspi5 6.6.31+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.6.31-1+rpt1 (2024-05-29) aarch64 GNU/Linux
```
```
$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```

# その他の環境について
- ドメインを購入して運用
- cloudflareのトンネル使って外部からアクセス
- SSHはVSCodeのRemote Explorerから(ファイル編集もCodeコマンド)

# とりあえず入れたコマンド
Raspbianは最初から割と入っていそう(curl, unzip, tar, git等)
とりあえずdigとtreeを入れてみました
```
$ sudo apt install -y dnsutils tree
```
あとは.bashrcには
```
bind 'set completion-ignore-case on'
```
これはターミナル上で大文字打たなくても、自動でタブ補完してくれます。
React アプリケーションの広い範囲で palt-typesetting を使う

## この記事の概要

Web での組版は DTP と比べるとどうしても自由度が低いです。

そんな中でも、日本語の組版のアレコレ（和欧混植やツメ組みなど）に対応したライブラリがありました。

https://github.com/yamatoiizuka/palt-typesetting

サンプルでは特定箇所で使う用のコンポーネントとなっていますが、React アプリケーションの広い範囲で使うとき用のコードについて記事にしました。

:::note warn
1 ページの文字量がかなり多い場合など、どうなるのかは検証していません。
あくまで、まずは広く適用してみたいと思って試した記事です。
:::

## 最上位のページやレイアウトコンポーネントでの指定

ここでは`App.jsx`で指定するとします。

```jsx:App.jsx
import { useEffect } from 'react'
import './App.css'
import Typesetter from 'palt-typesetting'
import 'palt-typesetting/dist/typesetter.css'

function App() {
  useEffect(() => {
    const typesetter = new Typesetter()
    typesetter.renderToSelector('#root')
  }, [])

  return (
    {/* ルーティング設定や children の受け取り */}
  )
}

export default App
```

最低限としてはこれで完了です。

|  | 通常 | palt-typesetting 使用 |
| --- | --- | --- |
| パターン 1 | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1437c8ec-94a9-8198-611e-9baf5dc6c48d.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/420dd24e-ffb8-dae4-4a81-51d58365c281.png) |
| パターン 2 | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/46275c84-dc86-f88a-61c0-706f5648357a.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/63fb24f7-636d-ab63-3e4b-1e942d502cb8.png) |
| パターン 3 | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/4b1a70ef-fb8d-b23f-b53b-a41e02d406a4.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1da00626-a057-023f-073f-9178d79cafe8.png) |

通常と比べて気持ちのいいアキ量・改行になっていると思います。

自分なりの設定などがある場合はドキュメントにあるのと同様に指定します。

```diff_jsx:App.jsx
  import { useEffect } from 'react'
  import './App.css'
  import Typesetter from 'palt-typesetting'
  import 'palt-typesetting/dist/typesetter.css'
+ import './global.css'

  function App() {
    useEffect(() => {
      const typesetter = new Typesetter()
      typesetter.renderToSelector('#root')
    }, [])

    return (
      {/* ルーティング設定や children の受け取り */}
    )
  }

  export default App
```

```css:global.css
.typesetting-wrapper {
  /* 全体にかかるルール */
}

.typesetting-latin {
  /* 英数字だけにかかるルール */
}

/* などなど */
```

## 実際に使うなら

DTP か Web かを問わず、文字をすべてツメ組にすることはあまりありません。

あくまで上記の内容はコンポーネントにして一部にだけ適用するのではなく、アプリケーションに広く適用するなら……と思ってコードを書いてみたものです。

実際に使うとしたら、記事ページのうちタイトルや見出しはすべて palt-typesetting を適用、本文はベタ組のまま、などがリアルな範囲かと思います。

見出しに id や class がついているのであれば`renderToSelector()`でそれを指定すれば OK です。

## BudouX との比較

似たようなライブラリとして BudouX を思い浮かべた方もいるかもしれません。

https://github.com/google/budoux

大きめの違いとして感じているのは、BudouX は`wbr`での分割のみで、palt-typesetting は分割したテキストを`span`で囲っている点です。

自分で色々とカスタムしたい場合は palt-typesetting の方がやりやすいように思っています。
FTPサーバーソフトFileZillaのインストールの際に参考にしたサイト

<h1>FTPサーバーソフトFileZillaのインストールの際に参考にしたサイト</h1>
<a href="https://z-marketing.net/ftp-filezilla/
">【Mac向け】FileZillaのインストールから使い方まで徹底解説</a>
【Pybulletサンプル解説】デバッグスライダーで重力の方向を変更【manyspheres.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、manyspheres.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/manyspheres.py)）

本コードを実行すると、デバッグスライダーに指定された方向に重力を変更することができます。

![manyspheres.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/181d55db-02d4-1466-9122-0d29fe27b10f.gif)


# 使用している機能
本コードは、以下の機能を使用して「デバッグスライダーの設定」「デバッグスライダーの値の取得」を実現しています。


## デバッグスライダーの設定
`addUserDebugParameter` 関数を使用することで、デバッグ用のスライダーを設定できます。

```python
debugSliderId = p.addUserDebugParameter(paramName, minVal, maxVal, initVal)
```
- `debugSliderId`：デバッグスライダーのID
- `paramName`：パラメータの名称
- `minVal`：パラメータの最小値
- `maxVal`：パラメータの最大値
- `initVal`：パラメータの初期値

<br>

今回は、重力を設定するために使用します。

```python
# 重力の方向を設定するデバッグスライダーを設定
gravXid = p.addUserDebugParameter("gravityX", -10, 10, 0)
gravYid = p.addUserDebugParameter("gravityY", -10, 10, 0)
gravZid = p.addUserDebugParameter("gravityZ", -10, 10, -10)
```

## デバッグスライダーの値の取得
`readUserDebugParameter` 関数を使用することで、デバッグスライダーの値を取得可能です。

```python
paramVal = pybullet.readUserDebugParameter(debugSliderId)
```
- `paramVal`：デバッグスライダーで設定された値
- `debugSliderId`：デバッグスライダーのID

<br>

今回は、デバッグスライダーに設定された重力の値を取得しています。

```python
  # デバッグスライダーから値を取得し重力に設定
  gravX = p.readUserDebugParameter(gravXid)
  gravY = p.readUserDebugParameter(gravYid)
  gravZ = p.readUserDebugParameter(gravZid)
```

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# Pybulletに共有メモリモードで接続
conid = p.connect(p.SHARED_MEMORY)

# 接続に失敗したら、GUIモードで接続
if (conid < 0):
  p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 内部シミュレーションフラグをリセット
p.setInternalSimFlags(0)

# シミュレーションをリセット
p.resetSimulation()

# 床のオブジェクトを生成
p.loadURDF("plane.urdf", useMaximalCoordinates=True)

# トレイのオブジェクトを生成
p.loadURDF("tray/traybox.urdf", useMaximalCoordinates=True)

# 重力の方向を設定するデバッグスライダーを設定
gravXid = p.addUserDebugParameter("gravityX", -10, 10, 0)
gravYid = p.addUserDebugParameter("gravityY", -10, 10, 0)
gravZid = p.addUserDebugParameter("gravityZ", -10, 10, -10)

# ソルバーの反復回数を設定
p.setPhysicsEngineParameter(numSolverIterations=10)

# 接触分離の閾値を設定
p.setPhysicsEngineParameter(contactBreakingThreshold=0.001)

# レンダリングを無効化
p.configureDebugVisualizer(p.COV_ENABLE_RENDERING, 0)

# 10×10×10のグリッドに小さな球体を生成
for i in range(10):
  for j in range(10):
    for k in range(10):
      ob = p.loadURDF("sphere_1cm.urdf", [0.02 * i, 0.02 * j, 0.2 + 0.02 * k],
                      useMaximalCoordinates=True)

# レンダリングを有効化
p.configureDebugVisualizer(p.COV_ENABLE_RENDERING, 1)

# 重力を設定
p.setGravity(0, 0, -10)

# リアルタイムシミュレーションを設定
p.setRealTimeSimulation(1)

while True:
  # デバッグスライダーから値を取得し重力に設定
  gravX = p.readUserDebugParameter(gravXid)
  gravY = p.readUserDebugParameter(gravYid)
  gravZ = p.readUserDebugParameter(gravZid)
  p.setGravity(gravX, gravY, gravZ)
  
  time.sleep(0.01)
```
Ruby 3.3 リファレンスマニュアルのEnumerableモジュールの概要を要約してみる※備忘録

私自身、リファレンスを見ることをしていなかったことを見直し、改めてリファレンスを見ながらRubyを学習しようと思い、早速mapメソッドが気になったので、以下のリファレンスを見てみることにした

Ruby 3.3 リファレンスマニュアル  ライブラリ一覧  組み込みライブラリ  Enumerableモジュール
https://docs.ruby-lang.org/ja/latest/class/Enumerable.html#I_ALL--3F

しかし読んでみると早速、要約で詰んでしまった。
<以下要約>
繰り返しを行なうクラスのための Mix-in。このモジュールのメソッドは全て each を用いて定義されているので、インクルードするクラスには each が定義されていなければなりません。

Array, Hash, Range, Enumerator等のクラスで、 Enumerableモジュールはインクルードされています。ただし、効率化のため、そのクラスでEnumerableと同名･同等の機能を再定義(オーバーライド)しているケースも少なくなく、特にArrayクラスでは同名のメソッドを再定義していることが多いです。

ただ、今回は諦めずに読み進める決意をした。

1.まずMix-inについては、Rubyのmoduleという機能があり、これは名前空間とMIX-INという機能を持っている。
これは、同じクラス名などがあった場合に別の名前にする機能を持ち、さらに、MIX-INは、module名をクラス内でinclude Enumerable(モジュール名)することで、moduleのメソッドを利用できることを表している。

2.「このモジュールのメソッドは全てeachを用いて定義されている。」とはつまり、eachメソッドで繰り返し処理をすることを前提に作られたメソッドだから、eachメソッドを利用したクラスを作成してね！また、その時は、クラス内でeachメソッドを実装し、そのメソッドで要素の繰り返し処理を行うようにしてね！ということ

3.「Array, Hash, Range, Enumerator等のクラスで、 Enumerableモジュールはインクルードされています。」
上記の標準クラス(型とも捉えていい)は、クラス作成時にEnumerableモジュールをincludeしているからすぐにEnumerable内のメソッドを利用できることを表している。

4.ただし、効率化のため、そのクラスでEnumerableと同名･同等の機能を再定義(オーバーライド)しているケースも少なくなく、特にArrayクラスでは同名のメソッドを再定義していることが多いです。
これは、Enumerableモジュールをincludeして、例えば、Arrayクラスなどのmapメソッドも同名のメソッドだけど内部の処理はオーバーライド(再定義)しているから完全に一致はしていなことを表している。

このように読み進めることで、Enumerableモジュール内のメソッドの概要を掴むことができました。リファレンスを読解することで、Rubyの奥深さを知る良いきっかけになったと思います。
【Pybulletサンプル公式】ソフトボディのオブジェクトの生成【load_soft_body.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、load_soft_body.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/load_soft_body.py)）

本コードを実行すると、ソフトボディのオブジェクトが生成されます。

![load_soft_body.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/98c27431-aa85-8ff4-b0d2-b5d45851cda8.gif)


# 使用している機能
本コードは、以下の機能を使用して「ソフトボディのオブジェクトの生成」を実現しています。

## ソフトボディのオブジェクトの生成
`loadSoftBody` 関数を使用することで、ソフトボディのオブジェクトを生成できます。

```python
softBodyId = p.loadSoftBody(objectFile)
```
- `softBodyId`：ソフトボディのオブジェクトのID
- `objectFile`：ソフトボディのオブジェクトのファイル

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
from time import sleep
import pybullet_data

# PybulletをGUIモードで接続
physicsClient = p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 重力を設定
p.setGravity(0, 0, -10)

# 床のオブジェクトを生成
planeId = p.loadURDF("plane.urdf", [0,0,-2])

# ボックスのオブジェクトをベースリンクを固定した状態で生成
boxId = p.loadURDF("cube.urdf", [0,3,2],useMaximalCoordinates = True)

# ソフトボディのウサギのオブジェクトを生成
bunnyId = p.loadSoftBody("bunny.obj")#.obj")#.vtk")

# リアルタイムシミュレーションを有効化
useRealTimeSimulation = 1
if (useRealTimeSimulation):
  p.setRealTimeSimulation(1)

# 床とボックスの動力学情報を取得
print(p.getDynamicsInfo(planeId, -1))
print(p.getDynamicsInfo(boxId, -1))

# ボックスの重量を10kgに変更
p.changeDynamics(boxId,-1,mass=10)

# pybulletが接続されている間、ループを接続
while p.isConnected():

  # 重力を設定
  p.setGravity(0, 0, -10)
  
  if (useRealTimeSimulation):
    sleep(0.01)  # Time in seconds.
  else:
    p.stepSimulation()
```
逆引き：Astro による出したい範囲に合わせた draft 設定

## この記事の概要

Astro を使い、かつコンテンツコレクションでコンテンツを管理している際、フィルタリングの方法はドキュメントに書いてあります。

https://docs.astro.build/en/guides/content-collections/#querying-collections

https://docs.astro.build/en/guides/routing/#excluding-pages

ただ、どういう場面でどうすると良いかはパッと読んだだけでは分かりづらかったので、逆引き的に整理しました。

## パターン

- 本番のビルドにも開発環境にも含めるが、トップページや記事一覧ページからは除外したい
- 本番のビルドには含めたくないが、開発環境には含めたい
- 本願のビルドにも開発環境にも含めたくない

## 前提

コンテンツコレクションが以下のように定義されているとします。

```ts:src/content/config.ts
import { z, defineCollection } from 'astro:content';

const postCollection = defineCollection({
  type: 'content',
  schema: z.object({
    // 色々なコード
    draft: z.boolean(),
  }),
});

export const collections = {
  'post': postCollection,
};
```

## 本番のビルドにも開発環境にも含めるが、トップページや記事一覧ページからは除外したい

トップページや記事一覧ページを作るファイルがあると思います。

例えば`https://example.com/posts`というページに記事一覧があるとします。

この場合、以下のようなコードを書きます。

```jsx:src/pages/posts/index.astro
---
import { getCollection } from 'astro:content';
const entries = await getCollection("post", ({ data }) => {
  return import.meta.env.PROD ? data.draft !== true : true;
});
---

<ul>
  {entries.map(entry => (
    // 詳細なコード
  )}
</ul>
```

これで、記事一覧ページには表示されないものの、直接記事の slug を含めた URL を叩けば記事が見れます。

## 本番のビルドには含めたくないが、開発環境には含めたい

先ほどのコードとほぼ同じで、書くファイルを変えるだけで済みます。

`https://example.com/posts/{slug}`という URL で作るとして、開発環境では表示や一覧を確認したいものの本番には含めない場合は以下です。

```jsx:src/pages/posts/[slug].astro
---
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
  const entries = await getCollection("post", ({ data }) => {
    return import.meta.env.PROD ? data.draft !== true : true;
  });
  return entries.map((entry) => ({
    params: { entry: entry.slug },
    props: { entry },
  }));
}
---

{/* マークアップ部分 */}
```

これで、開発環境では記事ページ自体にも一覧ページにも表示されるものの、本番には出なくなります。

## 本願のビルドにも開発環境にも含めたくない

最も簡単で、ファイル名の先頭に`_`をつけるだけです。

コンテンツコレクションで管理しているとしたら`src/content/post/somt-post.md`を`src/content/post/_somt-post.md`に変えるだけです。
【Pybulletサンプル解説】モデルの読み込み時間をログに出力【loadingBench.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、loadingBench.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/loadingBench.py)）

本コードを実行すると、「モデルの読み込みにかかった時間をログファイルに記録」することができます。

![loadingBench.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/45df1c68-c8c0-afb7-2de1-674f5face27e.gif)


# 使用している機能
本コードは、以下の機能を使用して「ログの記録の開始」「ログの記録の停止」を実現しています。

## ログの記録の開始
`startStateLogging` 関数を使用することで、ログファイルの記録を開始できます。

```python
timinglog = pybullet.startStateLogging(pybullet.STATE_LOGGING_PROFILE_TIMINGS, logFile)
```
- `timingLog`：ログのID
- `STATE_LOGGING_PROFILE_TIMINGS`：操作がされたタイミングのログを記録するモード
  - どの処理にどの程度の時間がかかっているかを解析可能
- `logFile`：ログファイル  



## ログの記録の停止
`stopStateLogging` 関数を使用することで、ログの記録を停止できます。

```python
pybullet.stopStateLogging(timinglog)
```
- `timingLog`：記録を停止するログのID


# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# PybulletをGUIモードで接続
p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# シミュレーションをリセット
p.resetSimulation()

# ログの記録を開始
timinglog = p.startStateLogging(p.STATE_LOGGING_PROFILE_TIMINGS, "loadingBenchVR.json")

# レンダリングを無効化
p.configureDebugVisualizer(p.COV_ENABLE_RENDERING, 0)

# 床のオブジェクトを生成
print("load plane.urdf")
p.loadURDF("plane.urdf")

# r2d2のオブジェクトを生成
print("load r2d2.urdf")
p.loadURDF("r2d2.urdf", 0, 0, 1)

# キッチンのオブジェクトを生成
print("load kitchen/1.sdf")
p.loadSDF("kitchens/1.sdf")

# プレートのオブジェクトをy座標を変更して100回生成する
print("load 100 times plate.urdf")
for i in range(100):
  p.loadURDF("dinnerware/plate.urdf", 0, i, 1)

# レンダリングを有効化
p.configureDebugVisualizer(p.COV_ENABLE_RENDERING, 1)

# ログの記録を停止
p.stopStateLogging(timinglog)
print("stopped state logging")

# カメラ画像を取得
p.getCameraImage(320, 200)

while (1):
  # シミュレーションを一時刻分進める
  p.stepSimulation()
```
XmlSerializerを使うと全く関係のない箇所でDllImport属性が失敗する

# XmlSerializerを使うと全く関係のない箇所でDllImport属性が失敗する
**※注意 完全に原因が分かったわけではないが、なぜかこうするとうまくいく系の備忘録です。**

アプリの構成
a.exe ← C#
b.dll ← C#
c.dll ← C++

a,b,c全部自作のものであるとする。

## 実装
1. aの中に`XmlSerializer`を使った処理を書く
2. bの中でcのメソッドを`DllImport`を使って書く
3. c内にはstdcallの`_declspec(dllexport)`で適当な処理を書いておく

## デバッグした時の流れ

1. b.dll、c.dllがロードされる
1. アプリケーションの設定としてxmlに保存していたのをアプリケーションの最初の方で読みだす
1. ここで`XmlSerializer`のコンストラクタ内で`FileNotFoundException`が発生する（シリアライズのためのDLLを作成するオプションがオフのため作ってない）
1. 内部的にはそのまま例外処理が行われるのでアプリケーション側ではそのまま処理が続行する
1. **ここでなぜかc.dllがアンロードされる**
1. その後aからbのメソッドを呼ぶ
1. bはcのラッパーライブラリなので内部的には`DllImport`属性のついたメソッドをそのまま呼ぶ
1. `DllNotFoundException無効なアドレスにアクセスしようとしています。`という例外が発生して落ちる


## 対処法
### その１
`XmlSerializer`を使う処理の前に`DllImport`属性のついたメソッドを読んでおく。
一回呼んでおくとアンロードされないっぽい。

### その２
`XmlSerializer`のコンストラクタ内で`FileNotFoundException`を発生させないためにシリアライズ用のDLLを作成しておく。


以下Copilotに質問した時の返答
1. **DLL の生成オプションを有効にする**:
プロジェクトのプロパティからビルド設定に移動します。
「シリアル化アセンブリの生成」オプションをオンにします。
これにより、必要な DLL が生成されます。
2. **csproj ファイルを直接編集する**:
csproj ファイル内に <SGenUseProxyTypes>false</SGenUseProxyTypes> を追加します。
このオプションは UI で設定できないため、直接ファイルを編集する必要があります。
3. **ビルド後イベントで sgen.exe を呼び出す**:
sgen.exe を呼び出して DLL を生成する方法もあります。
Visual Studio のインストール環境によっては、ビルド後イベントのパスを調整する必要があるかもしれません。

私は１だけだと作成されなかったので２も行う必要がありました。特殊事例のためおま環の可能性が高いです。
dllがアンロードされる原因まではわからなかったのでもしかすると他の要因でダメになってるのかも・・・。

以上
【Pybulletサンプル解説】オブジェクトにテクスチャを適用【projective_texture.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、projective_texture.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/projective_texture.py)）

（コメントアウトを外し）本コードを実行すると、指定したオブジェクトにテクスチャを適用可能です。

![projective_texture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/d8c07a74-fd78-e0d3-07da-14f1179a7d15.gif)


# 使用している機能
本コードは、以下の機能を使用して「テクスチャの読み込み」「テクスチャの適用」を実現しています。

## テクスチャの読み込み
`loadTexture` 関数を使用することで、テクスチャを読み込むことが可能です。

```python
textureId = pybullet.loadTexture(textureFile)
```
- `textureId`：テクスチャのID
- `textureFile`：テクスチャのファイル（今回の場合、jpgファイルを読み込み）

## テクスチャの適用
`changeVisualShape` 関数を使用することで、オブジェクトにテクスチャを指定することができます。

```python
pybullet.changeVisualShape(objectUniqueId, linkIndex, textureUniqueId)
```
- `objectUniqueId`：テクスチャを適用するオブジェクトのID
- `linkIndex`:オブジェクトのリンクのインデックス（ベースリンクの場合、-1）
- `textureUniqueId`：テクスチャのID

<br>

今回のサンプルコードの場合、該当箇所がコメントアウトされているため、実行したい場合はコメントを外してください。

```python
# 指定したオブジェクトにテクスチャを適用
#p.changeVisualShape(objectUniqueId=0, linkIndex=-1, textureUniqueId=textureId)
#p.changeVisualShape(objectUniqueId=1, linkIndex=-1, textureUniqueId=textureId)
```

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
from time import sleep
import matplotlib.pyplot as plt
import numpy as np
import pybullet_data

# GUIモードでPybulletを接続
physicsClient = p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 重力を[0,0,0]に設定
p.setGravity(0, 0, 0)

# 床のオブジェクトの位置/姿勢を設定（なぜかbearと記載されている）
bearStartPos1 = [-3.3, 0, 0]
bearStartOrientation1 = p.getQuaternionFromEuler([0, 0, 0])

# 床のオブジェクトを生成
bearId1 = p.loadURDF("plane.urdf", bearStartPos1, bearStartOrientation1)

# クマのオブジェクトの位置/姿勢を設定
bearStartPos2 = [0, 0, 0]
bearStartOrientation2 = p.getQuaternionFromEuler([0, 0, 0])

# クマのオブジェクトを生成
bearId2 = p.loadURDF("teddy_large.urdf", bearStartPos2, bearStartOrientation2)

# テクスチャを読み込み
textureId = p.loadTexture("checker_grid.jpg")

# 指定したオブジェクトにテクスチャを適用
#p.changeVisualShape(objectUniqueId=0, linkIndex=-1, textureUniqueId=textureId)
#p.changeVisualShape(objectUniqueId=1, linkIndex=-1, textureUniqueId=textureId)

# リアルタイムシミュレーションモードに設定
useRealTimeSimulation = 1
if (useRealTimeSimulation):
  p.setRealTimeSimulation(1)

while 1:
  if (useRealTimeSimulation):

  　# カメラデータを取得
    camera = p.getDebugVisualizerCamera()
    viewMat = camera[2]
    projMat = camera[3]

    # カメラ画像を取得
    p.getCameraImage(300,
                     300,
                     renderer=p.ER_BULLET_HARDWARE_OPENGL,
                     flags=p.ER_USE_PROJECTIVE_TEXTURE,
                     projectiveTextureView=viewMat,
                     projectiveTextureProj=projMat)
    
    # 重力を[0,0,0]に設定
    p.setGravity(0, 0, 0)
  else:
    p.stepSimulation()
```
[Rails] Rspec_Anonymous Controllerを使用して、Application Controllerのテストをしよう！

# はじめに
`ApplicationController`では、ユーザーのロール（役割）に対して、アクセス制御を行っていると思います。
では、そのアクセス制御をテストしようと思った時に、どのように実装しますでしょうか？

- requestテストでやろう！
    - でも、`ApplicationController`へのルーティングは通っていないよね...
- アクセス制御をしている箇所を`Concern`に切り分けて、単体テストでやろう！
    - これは結構良さげ
    - ただ、切り分けるほどの処理の大きさでもない...

上記のように、色々と模索すると思います。
その中で、`AnonymousController`を使用すれば、実装を変えずにテストすることができます。

今回はその内容をアウトプットいたします。

:::note warn
Rails5からは、`request spec`が推奨されています。
今からは、`controller spec`になるので、ご了承ください。
:::

https://qiita.com/t2kojima/items/ad7a8ade9e7a99fb4384

# AnonymousController とは
https://rspec.toolboxforweb.xyz/ja/docs/rspec-rails/controller_specs/anonymous_controller

`controller`メソッドを使用して、匿名コントローラーを作成することができます。
明示的にコントローラーを渡すこともできますし、ルーティングも自動に設定してくれます。


# 実装
```rb
require 'rails_helper'

RSpec.describe ApplicationController, type: :controller do
  controller(ApplicationController) do
    def index
      render plain: "OK"
    end
  end

  describe '#authorize_access' do
    before do
      sign_in test_user
    end

    subject { get :index }

    context 'when the user has permission' do
      let(:test_user) { create(:test_user, role: 'editor') }

      it 'returns http success' do
        is_expected.to have_http_status(:success)
      end
    end
  end
end
```

## 解説
今回の例では、`ApplicationController`の`before_action`で定義しているメソッドをテストしています。（※ アクセス制御の部分）

`get :index`を実行すると、実際の`ApplicationController`を実行してくれます。
なので、すごくテストがしやすいです。

以下にも、解説や注意点をまとめました。

### `type: :controller`は忘れずに
ここを、`type: :request`にしていると、`controller`メソッドは使用できません。
`type`は、`controller`を必ず指定しましょう。

### ルーティングは自動で設定される
`controller`メソッドを使用して、匿名コントローラーを作成しているので、ルーティングの設定が必要になるかと思っていました。
ただ、親切に、`AnonymousController`は、自動で設定してくれます。
`※ 明示的に、ルーティングの設定を記載しても問題ありません。`

今回だと、`index`メソッドを用意したので、`get :index`と実装すれば、通るようになります。

### controllerへの引数を渡すこともできる
今回は`describe`で指定しているコントローラーと差異はないので、`controller(...)`と引数を渡さなくても、問題ないかと思います。
ただ、明示的に渡して、特定のコントローラーで実装することも可能です。

### Deviseの設定は、`rails_helper`に忘れずに （※ この記事限定）
今回の実装例では、`sign_in`メソッドを使用しています。
これは、Deviseのヘルパーメソッドになるので、`controller spec`で使用できるように、設定が必要になります。

```rb: spec / rails_helper.rb
config.include Devise::Test::ControllerHelpers, type: :controller
```

上記を忘れずに設定しましょう。


# まとめ
実装始めは、`type`を`request`にしていて、`controller`メソッドが使用できず、悪戦苦闘していました...。
ただ、実際に使用してみて、`ApplicationController`のテストには、すごく向いているなと思いました。

他のコントローラーのテストは、`request spec`で十分です。
今回は、`AnonymousController`で実装しましたが、他にも良い実装があれば、教えていただきたいです。

最後までご覧いただき、ありがとうございました。
SharePointリストに存在するはずの項目がPowerAutomateで取得できない

PowerAutomateを利用して作成したワークフローを運用している中で遭遇した問題です。

# Problem

SharePointリストに存在するはずの項目（レコード）が、PowerAutomateで取得できない。
正確に言うと、取得できる項目とできない項目がある。
リストの項目数は6,000件を超えている。

SharePointコネクターの「複数の項目を取得」アクションを使用し、フィルタークエリで列の値を指定して対象の項目を絞り込む。
すると同じ列に対する条件値であっても、値次第で対象の項目が取得できるケースとできないケースが生じる：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/b801997f-8219-1e6c-1570-c3fe48a4be8a.png)

PowerAutomateでは取得できない項目であるが、SharePointの画面はもちろん、PowerAppsからもアクセスできる。

リストの設定画面を見ると、以下のようにやや気になるメッセージが表示されているが・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/093ce0b5-cf9a-beac-bce1-5acf2e83d9bf.png)

> このリスト内のアイテム数がリスト ビューのしきい値 (5000 アイテム) を超えています。サーバーに過度な負荷がかかる原因となるタスク (リストの全アイテムを対象としたタスクなど) は、現在禁止されています。

フィルタークエリがこの「禁止」に該当するのか・・・　ただこれが仮に該当するとしても、5000件という制限は、リストで管理しているデータの性質上容易には受け入れられない。

# Solution

当該SharePointリストの項目の検索に利用する列（カラム）にインデックスを付加する。

リストの設定画面の前述の警告の下にある「大きなリストやライブラリを使用して、アイテムを即座に表示する方法を説明します。」というリンクをクリックすると表示される「SharePointのヘルプ」のアドバイスにしたがって、フィルタ条件に使用する列（カラム）に対してインデックスを追加してみる：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/e168b78c-91e6-dffd-44b7-2a43e7db0e70.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/3a8ca9c0-5b3a-b906-a9e6-cb46aea2ad96.png)

さいわいにも今回の問題はこれで解決。

:::note info
前述の「SharePointのヘルプ」は英語ですが、公式リファレンスの1ページ「[大規模なリストとライブラリを管理する](https://support.microsoft.com/ja-jp/office/%E5%A4%A7%E8%A6%8F%E6%A8%A1%E3%81%AA%E3%83%AA%E3%82%B9%E3%83%88%E3%81%A8%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B-b8588dae-9387-48c2-9248-c24122f07c59)」として日本語化もされています。
いずれにせよ、説明を読む限り、閾値を超えた項目数のリストを操作したときに起こりうる事象はエラーということですが・・・実際には「エラー」として問題が顕在化せず、「なぜか項目が取得できない」という問題も起こり得るようです。
また今回事象が確認されたリストの項目数は事象検知時点で6,000件を超えていますが、資料にある5,000件の閾値を超えたのはかなり以前のことであり、事象発生のタイミングとは一致しません。
:::