OmniAICreator/Qiita-1.07M huggingface dataset:
[備忘録]　ロボットのプランナーについて紹介する発表会に参加した 

## はじめに
こんにちは，初投稿です．
ロボットのプランナーについて紹介する発表会にオンラインで参加しました．しかし，リアルタイムで参加することが時間の都合上できなかったため，後ほど配信されるYoutubeの動画を見ました．<br><br>なお，以下のリンクは参加した発表会の動画と概要です．
発表会のテーマ：ROS Japan UG #55 Planner特集！
主催者：ROS Japan User Group：https://rosjp.connpass.com/
Youtubeのリンク：https://youtu.be/GEslxRk_978?si=hYQhy9BFwF2CWkow
発表会の概要：https://rosjp.connpass.com/event/313794/





## 感想
非常に勉強になりました．今回の発表会はロボットのプランニングについて紹介されていて，全体的に研究寄りの内容でした．特にマニピュレーションは勉強になりました．


## 備忘録
以下は発表会の備忘録です．
- ROS1とROS2の違い
    - ROSとはplumbing+tools+capabilities+commnuityで構成されている
    - ROS1は情報が豊富，ROS2はROSのコンセプトを引き継いで再設計されたversion
    - ROS1はTCPROS，ROS2はDDSI-RTPS (UDP)
    - rqtはQtベースのデバッグフレームワーク<br><br><br>
       
- 基盤モデルによるロボットのパスプランニングと制御
    - 基盤モデルとはLLMといった言語モデルのこと
    - モダリティがインプットされて頭の中(言語)で考えてアクションを起こす
    - 環境や物体など，現在状態をどう言語に変換するか＝低レイヤ認識
    - マップ生成．報酬生成=高レイヤ認識
    - ViLD[1]による物体認識，CLIP[2]によるクラス分類をした上でその物体をどこにしまうか，どのようにしまうかを人間の好みを考慮しつつMMLでタスク計画
    - 認識APIや制御APIを準備した上でLLMを使ってロボットの制御のためのpythonコードを自動生成
    - MDETR[3]で物体検出，audioCLIP[4]で音認識を行う
    - ロボットになぜ動作が失敗したかをLLMでまとめさせて修正・再計画を行う
        - 速度とFootstep Planから各関節指令を計算する部分はシミュレーションで強化学習 (４足歩行ロボット)
    - 大規模なデータに基づいて構築された言語と画像列からグリッパの開閉やロボットの手先位置姿勢を出力する (ロボット基盤モデル)
    - VLMは文章を入れたら物体認識がすぐにできる　(学習不要)<br><br><br>

- ロボットマニピュレーションの作業・動作計画
    - RRT[5]による経路計画を行ってマグカップの取っ手を掴む
    - ロボットに教示が大変な時にプランニングを行う
    - OMPL[6]
        -  RRTが使われている
        -  ランダムサンプリングに基づくグラフ構造を生成
        -  ランダムサンプリングした所に点を打って経路を探す<br><br>

    - 逆運動学は難しい．手先の位置から関節角度を求めるとき
        - 複数の解が存在する
        - 解が求まらない
                    - 解けるもんだけ解く　 (解決案1)
                    - モンテカルロ法 (解決案2)
                    - ヤコビ行列や擬似逆行列によって逐次的に求める (解決案3)
        - 特異姿勢について(課題)
                    - オイラー角 (各座標軸周りの回転角)は回転の順序によって最終的な姿勢が異なる
                    - 姿勢によっては回転自由度が欠落してしまう
                    - クォータニオン　(4次元単位超球上の１点) <br><br><br>



- 車の自動運転 (Autoware)
    - ROSと似ている
    - 速度計算を行うモジュールが導入されている
    - 障害物や後続車を考慮してレーンチェンジのタイミングを計算して経路を生成
    -  複数の経路をサンプリングして最適解を選択
    - 実際の走行データを元にPlanningを学習して高い適応力を獲得する
        - CNNで軌道と走行状態を計算して最適化で後処理を行う
        - 学習された非線形車両モデルを使って，非線形最適制御を実行
                -  車の将来挙動を予測する<br><br><br>



- 植物工場向けロボットのためのプランニング
    - ロボットの運行スケジュールなどもブロックごとで管理
    - ブロックを増やしてスケールアップ<br><br>
    - ロボットの移動経路について
        - 有向グラフを活用した位置表現でロボットの行動を数学的に扱う
                - 回転方向によってはロボットが壁に衝突してしまう．そこで，有向グラフで方向を定義して解く
                - 経路計画はダイクストラ法を活用<br><br>



- ROS2のgazeboにはトラブルが多い件について
    - ROS1ではlidarの反射強度が埋め込めていた．
        - Ros2ではROS1とは違ってversionが不明
        - lidarのCPU rayがROS2にはない



# 参考文献
[1]"[論文メモ]ViLD: Open-vocabulary Object Detection via Vision and Language Knowledge Distillation"，https://yuiga.dev/blog/posts/vild_open-vocabulary_object_detection_via_vision_and_language_knowledge_distillation/
[2]"CLIP：言語と画像のマルチモーダル基盤モデル"，https://trail.t.u-tokyo.ac.jp/ja/blog/22-12-02-clip/
[3]"MDETRについて"，https://zenn.dev/ijiwarunahello/articles/c2d2c30e50da9f
[4]"AudioClip"，https://docs.unity3d.com/ja/2019.4/ScriptReference/AudioClip.html
[5]"PythonによるRapidly-Exploring Random Trees (RRT)パスプランニングサンプルプログラム"，https://myenigma.hatenablog.com/entry/2016/03/23/092002#google_vignette
[6]"OMPL"，https://ompl.kavrakilab.org/
初心者スクラムマスターの振り返り

数年前にほんの数か月だけスクラムマスターを任せてもらった時の経験を思い出して書いてみました。
後付けのところもあると思います。

# スクラムマスターって何をするもの？
初めにこの疑問を抱きました。
調べてみると、、

>スクラム・マスターは、スプリントと呼ばれる時間制限のあるイテレーションに焦点を当てた、軽量のアジャイル・フレームワークであるスクラムの進行役です。スクラム・マスターは進行役として、スクラム・ガイドにあるように他のチーム・メンバーのコーチ、またはサーバント・リーダーの役割を果たします。
>[スクラム・マスターとその責任とは？](https://www.atlassian.com/ja/agile/scrum/scrum-master)

>スクラムマスターは、スクラムチームとより広範な組織がスクラムの理論と実践を理解し、適用するのを助けるファシリテーターとコーチの両方の役割を果たします。
>チームが目標を達成する上で妨げとなる可能性のある障害や気の散る要素を巧みに取り除くことでスクラムチームがより効果的に作業できるようにし、スクラムチームとチーム外の個人やチームとの連絡役を務めます。
>[スクラムマスターの役割と責任範囲、資格認定](https://www.lucidchart.com/blog/ja/scrum-master-skills-and-responsibilities)

役割としては主にこのような感じでしょうか。

- チームリーダー
- スプリントを上手く進行させる責任を持つ
- 中立的な立場から奉仕精神を持ってチームをより良い方向へ導く
- チーム外部との連絡役

ポイントは、 **上から目線でなく、伴走してチーム運営を行う** …っぽい、ということのようです。

# 実際のチーム構成と担当業務
自社内チームにPO(プロダクトオーナー)がいましたので、実質はその方がチームリーダーのようなことをしていました。
スクラムマスター(仮)であった自分の実際の業務は、

- スプリントで開発するポイントの予実管理
- スプリント計画時に一緒に行う振り返りの進行
- 勉強会の主催

でした。
自分が特に気になったのは、振り返りについてです。

# 良くなかった点
どのように振り返りを行っていたかと言うと、ミーティングの中で以下の順番でやっていました。

1. 次スプリントのタスクを割り振る
1. 振り返りを行う

今思うと、この順番ってあまり良くなかったように思います。
何故かというと、例えばKPTのTに *「次スプリントのタスク」を挙げる人がいた* からです。

「振り返り」というと、反省点を挙げてそれを解決する方法を提案したり、皆で解決案を考えたりするためにあると思います。
それを理解していない(やろうとしていない？)人がいたのも原因だとは思います。
ただ、これではやった感だけは出てしまいます。
振り返りの時間は形骸化してしまいました。。。

# どう解決しようとしたか？
それを払拭するために、POさんから、「フレームワークをKPTからYWTに変える」という指示があったりしました。
直接の解決にはなりませんが、振り返りとは何なのか改めて説明したり、もっと良いやり方を考えたりするためには良いことだったと思います。

フレームワークの変更にプラスして、自分なりに以下のようなことを実践してみました。

1. `Y(やったこと)　→　W(やったことからわかったこと)　→　T(わかったことをより良くするため、改善するために次にやること)`　の流れをわかりやすくするため、Excelシートの1行につき1項目入力する
1. 上記をまず自分で実践し、例として説明する

それまでは前任のスクラムマスターさんのやり方を引き継いで、Web会議のチャットに自由な形式で書き込んでもらっていました。
これを止めて①のExcelシートを用意して書いてもらい、画面共有するようにしました。

また、振り返りの良い例が無いことも原因だと思ったので、まずは自分がこれが良いと思うやり方を実践してみせるようにしました。

# 結果は…
残念ながら、やったことの結果が出る前に、自分は病気で退場してしまいました。
良い振り返りができるようになっていたら良いな…。

しかし、 **伴走してチーム運営を行う** ということを意識して、自分から見本を見せようとできたのは、良い経験になったと思います。
Javaのパーマネント領域（PermGen）について

## はじめに

Javaのメモリ管理にはさまざまな領域があります。その中でも、パーマネント領域（Permanent Generation、通称PermGen）は特に重要です。

## PermGenの役割

パーマネント領域（PermGen）は、Javaヒープの一部で、以下のような永続的なデータを保存するために使用されます。

- **クラスメタデータ**: クラスのロード時にJVMによって生成されるメタデータ。クラスのバイトコード、メソッド情報、フィールド情報などが含まれます。
- **インターナの文字列プール**: `String`クラスのインターナ文字列（`interned strings`）。
- **静的変数**: クラスの静的変数もPermGenに保存されます。

## PermGenの構造

PermGenはヒープ領域とは異なり、Garbage Collection（GC）による管理が複雑です。通常のヒープ領域が若い世代（Young Generation）と老いた世代（Old Generation）に分かれているのに対し、PermGenは以下の2つの領域で構成されます。

1. **Class Area**: クラスのメタデータを保存します。
2. **Non-Class Area**: クラス以外のデータ（インターナ文字列など）を保存します。

## PermGenの問題点

PermGenにはいくつかの問題点があります。

### メモリ不足（OutOfMemoryError: PermGen space）

PermGenのサイズは固定されており、動的に拡張できません。そのため、多数のクラスを動的にロード・アンロードするアプリケーションでは、PermGenのメモリ不足が発生することがあります。このエラーは次のような場合に発生します。

- 大量のクラスをロードする場合
- クラスのアンロードが適切に行われない場合
- デプロイメントサイクルが頻繁な場合（特にWebアプリケーション）

## Java 8以降の変更点

Java 8では、PermGenが廃止され、新たにメタスペース（Metaspace）という領域が導入されました。メタスペースは、以下の点でPermGenと異なります。

- **サイズの自動調整**: メタスペースは、必要に応じて動的に拡張されます。これにより、PermGenで発生していたメモリ不足の問題が解消されます。
- **ネイティブメモリの利用**: メタスペースはヒープ外のネイティブメモリを使用します。

### メタスペースの利点

- **OutOfMemoryErrorの減少**: 動的なサイズ調整により、メモリ不足の問題が大幅に減少しました。
- **GCパフォーマンスの向上**: メタスペースはヒープ外メモリを使用するため、GCの負荷が軽減されます。

### メタスペースの設定

メタスペースのサイズは以下のように設定できます。

```sh
-XX:MetaspaceSize=<size>
-XX:MaxMetaspaceSize=<max size>
```

例:

```sh
-XX:MetaspaceSize=128M
-XX:MaxMetaspaceSize=512M
```

## PermGenとメタスペースの比較

| 特徴              | PermGen                                | メタスペース                         |
|-------------------|----------------------------------------|--------------------------------------|
| メモリ割り当て    | 固定サイズ                             | 動的に拡張                          |
| メモリの場所      | ヒープ内                                | ヒープ外のネイティブメモリ           |
| エラー            | OutOfMemoryError: PermGen space       | OutOfMemoryError: Metaspace         |
| パフォーマンス    | GCに悪影響を与えることがある           | GCパフォーマンスが向上               |

## まとめ

Javaのパーマネント領域（PermGen）は、クラスメタデータや静的変数などの永続的なデータを保存するための重要なメモリ領域です。しかし、その固定サイズとGCパフォーマンスの問題から、Java 8ではメタスペースに置き換えられました。メタスペースは動的にサイズを調整できるため、PermGenの問題を解消し、GCのパフォーマンスを向上させています。
競プロ　入力の受け取り方法まとめ【Python】

## はじめに
競技プログラミングやプログラミングの練習問題で一番初めにつまづいたのが入出力の方法だったので、今回は入力の受け取り方についてまとめました。
出力方法についての記事は[こちら](https://qiita.com/cbet/items/79abf9ab0c6938a160d5)
## 基本の関数
### input()関数
 **input()** は１行を文字列として読み込む関数である。
以下のように「1 2 3」と入力したとき、文字列 ’1 2 3’ と読み込む。
```Python:
# 1 2 3

a = input()
print(a)

# 1 2 3
```

## 空白区切りの文字 n 個の入力を n 個の変数に格納する
 **split()** 関数を用いて、入力された文字列を空白区切りを基準に分割する。
以下のように「1 2 3」と入力したとき、各変数に各入力値を格納する。
```Python:
# 1 2 3

a, b, c = input().split()
print(a)
print(b)
print(c)

# 1
# 2
# 3
```

## 空白区切りで文字列のリストを取得する
 **a = input().split()** と記述したとき、入力された文字列は空白区切りで分割されてリスト a の要素として格納される。
```Python:
# 1 2 3

a = input().split()
print(a)

# ['1', '2', '3']
```

## 入力された数値を整数に変換して格納する
数値を入力しても、 **input()** では文字列として読み込まれる。
そこで以下のように **int()** で囲んで変換する。
```Python:
# 1

a = int(input())
print(a)

# 1
```

## 空白区切りの数値 n 個の入力を整数に変換して n 個の変数に格納する
以下のように **map()** を用いて整数に変換する。
```Python:
# 1 2 3

a, b, c = map(int, input().split())
print(a)
print(b)
print(c)

# 1
# 2
# 3
```

## 空白区切りで整数のリストを取得する
 **int()** の引数にリストは指定できないので、a = int( input().split() ) とは記述できない。
 そこで以下のように **list()** を用いて格納する。
```Python:
# 1 2 3

a = list(map(int, input().split()))
print(a)

# [1, 2, 3]
```

## 複数行の入力を読み込み、リストに格納する
n 行の入力を読み込むとする。
以下のように for の内包表現を用いて記述する。
```Python:
# 3
# one 1
# two 2
# three 3

n = int(input())
a = [input() for _ in range(n)]
print(a)

# ['one 1', 'two 2', 'three 3']
```
 **a = list(input() for _ in range(n))** と記述することもできる。

## 複数行の入力を二次元配列に格納する
a = input().split()と記述したとき、空白区切りで分割されてリスト a の要素として格納されるので、以下のように記述すると、勝手に二次元配列になってくれる。
```Python:
# 3
# one 1
# two 2
# three 3

n = int(input())
a = [input().split() for _ in range(n)]
print(a)

# [['one', '1'], ['two', '2'], ['three', '3']]
```

## 複数行の各行に対して処理を行う場合の入力（リストとして保持しない）
各行の値に対して処理を行う場合は内包表現を使わずに処理を記述する。
```Python:
# 3
# 1 2
# 2 1
# 1 2

n = int(input())
a = []
for _ in range(n):
    n, m = map(int, input().split())
    if n > m:
        a.append(n)
    else:
        a.append(m)
print(a)

# [2, 2, 2]
```
Django REST frameworkのCORS設定

## 1. やりたいこと


Django REST frameworkで作ったAPIについて、Reactで作成したSPAからGETリクエストを送ったところ、以下のようなエラーがでました


```
Access to fetch at 'http://127.0.0.1:8000/articles/' from origin 'http://127.0.0.1:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/5f396313-09b0-bf6d-289e-57d50331c655.png)


CORS policyによりブロックされたとありますので原因は許可されていないクロスオリジンからのデータ取得がDjangoによりブロックされているのだと分かります

本記事ではこれを解決する方法をまとめます


## 2. CORSとは


CORSとはCross-Origin Resource Sharingの略で、OriginはURL+portのことですから、CORSは異なるOriginへのリソース共有を示す言葉です。悪意のあるサイトが他のサイトのデータを不正に取得するクロスサイトリクエストフォージェリ(CSRF)のような攻撃を防ぐためにブラウザにはこれをブロックする仕組みが標準適用されているので、適切に設定せずにAPIを取りに行くと先ほどのようなエラーが出ます


例えばCookieによってログインが維持されている状態のままで悪意のあるサイトを踏んだとき、悪意のあるサイトがログインしないと読めない情報を取得してよそに送ってしまうのを防ぐというような目的で、原則として別Originからの情報取得をブラウザが禁止しているわけです


その為、今回のように別OriginにあるサーバーのAPIを取得する際には、APIサーバー側でどのOriginからのアクセスを許可するか設定しておく必要があります。実際に取得する際にはブラウザがAPIサーバーから許可するOriginの情報を書いたCORSヘッダーを受け取って、現在のOriginが許可されていればAPIサーバーにリクエストを実行するという手順でこれを実現します


## 3. django-cors-headersパッケージをインストールする


Django側でCORSヘッダーを扱えるようにするパッケージをインストールします


```terminal:terminal
pip install django-cors-headers
```


## 4. settings.pyに設定を書く


### 4-1. INSTALLED_APPSに追加


以下でDjangoがcorsheaderを使うようになります


```python:setting.py
INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]
```


### 4-2. MIDDLEWAREを追加


ミドルウェアにCorsMiddlewareとCommonMiddlewareを追加します


```python:setting.py
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]
```


### 4-3. CORSポリシーを設定


#### 特定のOriginを許可する場合


許可するOriginをリストで書いていけば許可してくれます


```python:setting.py
CORS_ALLOWED_ORIGINS = [
    'http://127.0.0.1:5173',
]
```


#### すべてのOriginを許可する場合


一般公開するAPIのような場合は以下ですべてのOriginを許可しちゃいます
ウェブアプリのバックエンドとして使う用途だとこちらは使わないと思います


```python:setting.py
CORS_ALLOW_ALL_ORIGINS = True  # すべてのオリジンからのアクセスを許可
```


### 5. 再起動する


あとはDjangoを再起動したら完成です
Dockerコンテナのログローテート設定


# 概要

コンテナのログは、以下のコマンドで確認んできる。

```
docker logs -f コンテナ名orコンテナID
```
そしてこれは、dockerホストの
```
/var/lib/docker/containers/コンテナID/コンテナID-json.log
```
に記載されている。
コンテナの運用をしているとこのログがどんどんたまってしまいサーバのディスクを圧迫する恐れがある。そのためログの管理、ログローテートの設定を行う必要がある。

設定させる方法はいくつかあるので、こちらに記載する。

## 全体的にログローテートの設定を行う

以下のようにファイルを編集する。
```
vi /etc/docker/daemon.json
```
そして`log-opts`を設定する、
以下のような設定だと、

- 20Mバイトのログを、
- 10世代まで
保持するという内容である。
```:daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "20m",
    "max-file": "10"
  }
}
```
その後、以下のようにdockerのサービスを再起動する。
```
sudo systemctl restart docker.service
```
これにより、このdockerホスト上で動くコンテナ全体に、上記の内容で設定したログローテートが適応される。

## docker-composeで設定する。

docker-compose.ymlに記載して設定する場合は以下の通り。今回はnginxのコンテナを例に実行している。loggingという内容の中に設定する事で可能になる。

```
version: '3'
services:
  app:
    image: nginx:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    volumes:
      - ./src:/var/www/html
    ports:
      - 80:5412
```

## docker runコマンドで設定する
docker runコマンドは運用ではあまり使わないかもしれないが、設定する場合は以下のようにオプションを設定する。
```
 sudo docker run -d --rm --log-opt max-size=100k max-file=3
```


# 参考サイト
実はこのlog-optのオプションは、--log-driverに指定するログドライバによって設定できる内容が変わるため、オプションの内容をhelpなどで調べてもよくわからない。今回はjson logging driverを設定しているので、以下リンク先を確認する。

https://docs.docker.com/config/containers/logging/json-file/#options
 
なお、ログドライバについては以下を参考にする。

https://docs.docker.com/config/containers/logging/configure/
爆速でshadcn/uiを使ってダークモードボタンを作る

Next.jsとshadcn/uiを使うとダークモードのトグルボタンが爆速で作ることができるので紹介します。


### `next-themes`をインストール
```zsh:zsh
bun add next-themes
```

### テーマプロバイダーを作成

```tsx:components/theme-provider.tsx
"use client"

import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
```

### テーマプロバイダーを`layout.tsx`に配置
```tsx:layout.tsx
import { ThemeProvider } from "@/components/theme-provider"
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body className={inter.className}>
      <ThemeProvider
            attribute="class"
            defaultTheme="system"
            enableSystem
            disableTransitionOnChange
          >
            {children}
          </ThemeProvider>
        </body>
    </html>
  );
}

```

### トグルボタンコンポーネントを作成
```tsx:mode-toggle.tsx
"use client"

import * as React from "react"
import { MoonIcon, SunIcon } from "@radix-ui/react-icons"
import { useTheme } from "next-themes"

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function ModeToggle() {
  const { setTheme } = useTheme()

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline" size="icon">
          <SunIcon className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
          <MoonIcon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          <span className="sr-only">Toggle theme</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => setTheme("light")}>
          Light
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("dark")}>
          Dark
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("system")}>
          System
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}
```

### 完成
作成した`ModeToggle`コンポーネントを設置すると以下のようなボタンが作られます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779963/53e35179-faa6-5e99-6090-3019a5b52b14.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779963/5e730059-2822-0a0d-bef9-73426ad01c46.png)



参考

https://ui.shadcn.com/docs/dark-mode/next
FreeTypeSharpを使った文字列描画（byte配列で読み込む）

# 1. 前回の内容
https://qiita.com/fumifumi0453/items/eb70d106f6db48e5495d

# 2. 目標
　フォントをファイル指定するのではなく、byte配列で指定する。
　これによってファイルの暗号化に対応でき、利用可能なフォントを増やすことができる。

# 3. ソース
https://github.com/fumifumi0453/SimpleFreeTypeSharp

# 4. 変更点
### 4.1.ImageFont
　バイト配列を受け取るSetFont(byte[])メソッドを追加
　内部でFT.FT_New_Memory_Face(FT_LibraryRec_*, byte*, IntPtr, IntPtr, FT_FaceRec_**)メソッドを呼び出している。
　FT.FT_New_Memory_Faceメソッドの第二引数がフォントデータのbyte配列の先頭アドレスになる。
　当然アンマネージドメモリで取得する必要があります。　
　そのため、Marshall.AllocHGlobal(int)メソッドでメモリを確保、配列のコピーを行っています。
 また、確保したメモリを開放するためにIDisposableインターフェイスを実装しています。
~~~C#:ImageFont
    public unsafe class ImageFont : IDisposable
    {
        private IntPtr _FontMemory = IntPtr.Zero;

        // (......省略)
        
        public void SetFont(byte[] data)
        {
            FT_FaceRec_* face;

            _FontMemory = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, _FontMemory, data.Length);

            var error = FT.FT_New_Memory_Face(FTL_Library.Native, (byte*)_FontMemory, (IntPtr)data.Length, IntPtr.Zero, &face);

            if (error != FT_Error.FT_Err_Ok) throw new FreeTypeException(error);

            SetFont(face);
        }

        // (......省略)

        public void Dispose()
        {
            if (_FontMemory != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(_FontMemory);
                _FontMemory = IntPtr.Zero;
            }
        }
    }
~~~

### 4.2. その他のクラス
　ImageFontを作成するTextTextureFactoryクラスにてbyte配列に対応したLoadFontメソッドを追加

# 5. おわりに
　今回の対応で一般的なフリーフォントの利用条件をクリアできたと思う。
　そのため、文字列の描画に関しては一旦完成とする。

# 6. 続き
https://qiita.com/fumifumi0453/items/3ccf9be78b5f456af143
【React×TypeScript】クラスの基本的な考え方と作成方法をざっくり説明

# はじめに
React学習を始めて早4カ月、クラスをよくわからないまま使っていたので簡単にまとめます。
# クラスとは？
**関連するデータとその操作をまとめて管理するためのテンプレート・設計図** みたいなものです。**一度作成しておけば使いまわすことができます。**

こちらはRubyの記事ですが、クラスの説明がめちゃくちゃわかりやすいです。

https://pikawaka.com/ruby/class

# クラスの作成方法


**Reactでは`constructor`を利用して、クラスの各プロパティを設定します。**

下記に例を示しました。
今回はArticleというクラスに、author(著者名) ・title(タイトル)・ contents(記事の内容)という3つのプロパティを設定しています。

```tsx:tsx
export class Article {
  constructor(
    public author: string,
    public title: string,
    public contents: string,
  ) {}
}
```

# おわりに
ドキュメント等を読んでもイメージがわかなかったのですが、何度か使ってやっと掴めてきました。愚直に手を動かしていくしかない。。
Jupyter NotebookがVSCodeで開かれてしまう

# はじめに
こんにちは、ユーゴです。今回は、Jupyter Notebookを使用していた時に起きた課題について紹介します。
私はすぐに原因に気づけましたが、沼にハマっている人の助けになれれば嬉しいです。

# 課題
ターミナルから、以下のコマンドを実行

```bash
jupyter notebook
```

すると、jupyterがvscodeで開かれる

![jupyterがvscodeで開かれる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/7de42688-65e9-f8bc-b16e-a30e9405a6a0.png)

# 原因
どれでもいいですが、htmlファイルの情報を見ると、「このアプリケーションで開く」がVSCode選択されているのが分かります。
![原因.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/f2789118-a011-5f57-9ec2-ba6d68467727.png)
htmlファイルをVSCodeで編集したいために、設定を変えた記憶はございませんか...？

# 解決策
Google Chrome、もしくはお好みのブラウザにしましょう。
そして、「すべてを変更...」をクリックします。
![修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/30bfbac5-85e1-2e99-e2ab-9d42bfb53488.png)

# 終わりに
いかがだったでしょうか。今回は、Jupyter NotebookがVSCodeで開いてしまう問題について紹介しました。
自分は設定を変えたのが直近だったことと、運よく勘が冴えていたので、原因が直ちに分かりました。しかし、最初からJupyter Notebookでこのような事態が発生した方や、かなり前に設定を変えたことを忘れた方は、沼にハマっているかもしれません。そんな方の助けになっていると幸いです。
お役に立てましたら、いいね, LGTML, フォローなどよろしくお願いします！
Express-sessionとRedisでセッション管理したい

# 対象読者
- express-sessionでセッション管理を実装したい
- サーバーを再起動するたびにセッション情報が消えてしまって困っている
- redisを使いたい
- connect-redisの使い方がわからない
# 問題
セッション管理をexpress-sessionでやろうとしたけれど、サーバーを再起動させるたびにセッション情報が消えてしまってました。
デプロイする度にユーザーはログインし直さないといけなくて不便なので、何とかする必要がありました。

# 解決
Redisを導入して、セッション情報をRedisに格納するようにしました。
```
npm install redis connect-redis
```

# Redisについて
![redis_logo-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601978/3e4591fd-6651-4039-4936-e6dc2cbd06a3.png)

- メモリ上にデータを保存できる辞書型DB
- express-sessionだけだと、アプリを再起動する度にセッション情報が破棄されてしまう
    - が、Redisはexpress-sessionとは独立しているので、影響を受けずにセッション情報は保持されたままになる。

# 勘違いしていたこと
Node.jsにredisをインストールするんですが、それだけでRedisが使用できると勘違いしてました。。

実際にはアプリとは別にOSにRedisをインストールする必要がありました。

インストール方法はこちらを参照してください。
https://weblabo.oscasierra.net/redis-windows-install/

インストールしたらredis-server.exeでRedisを起動する必要があります。

初期状態ではパスが通っていないので、環境変数でPATHに、C:\Program Files\Redis（Redisがインストールされているパス）を追加するとパスが通って、どこからでもredis-server.exeが実行できるようになります。

```
redis-server.exe --service-run //--service-runを付けると実行してもコマンドプロンプトが閉じない

//起動したかの確認
redis-cli
ping
//PONGと表示されれば起動の確認OK
```
これでRedisが使用できる状態になります。

# コード実装
## app.js

```javascript
const express = require("express");
const path = require("path");
const cors = require("cors");

const session = require("express-session");
const passport = require("passport");
const RedisStore = require("connect-redis").default;
const { createClient } = require("redis");
const redisClient = createClient();

redisClient.connect().catch(console.error);
const redisStore = new RedisStore({
  client: redisClient,
});

const dotenv = require("dotenv");
const envFile = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : ".env";
dotenv.config({ path: envFile });

const app = express();

// セッションを開始したときのクッキーへの送信とRedisへの登録の設定
app.use(
  session({
    secret: process.env.SESSION_SECRET_KEY,
    resave: false,
    saveUninitialized: true,
    cookie: { maxAge: Number(process.env.SESSION_COOKIE_MAX_AGE) },
    store: redisStore,
  })
);
app.use(passport.initialize());
app.use(passport.session());

```
これでうまく行きました。
connect-redisの扱いは情報が錯乱していたので、[本家のドキュメント](https://www.npmjs.com/package/connect-redis)を参考にするといいです。

# まとめ
これでサーバーアプリの再起動やデプロイをしたときなどでも、セッション情報がリセットされることがなくなって、ユーザーフレンドリーになりました。
俺流、障害分析フレーム、障害分析はこれで行ってます

運用保守業務をしていると、テスト機のつもりが本番機で、そこでデータを消しちゃいましたとか、アプリの修正したけれど丸め計算し忘れて誤請求になったとか、そんな話はまぁまぁ出くわします。
で、再発防止に向けて障害事象を整理、分析していくのですが、ここで、俺流の障害分析フレームを紹介します。

# 障害事象整理表の初回作成
障害を状態遷移表で整理していると考えて下さい。
まだこの段階では分析しないです。「時系列」で「事象」を言葉にし、関係者が「行動したこと」を言葉にします。書いている最中に分析脳が働いて、「行動しなかったこと」に気づくことがあるので、それも書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76786/0bff0f7b-c9e0-673f-d6e5-1dd55a5aaf9b.png)

# 障害分類ラベル付与
関係者の行動を記載したセルに着目し、下記の障害分類ラベル付与の観点で、そのセルにラベルをつけます。
状態遷移表を整理していくのと同じように、実行すべきアクションの抜け漏れがあったら、本来実行すべきだったアクションをセルに追記します。そのセルには「ラプス」のラベルが付与される、みたいな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76786/dfdec53e-ec06-c7a9-7dc9-39f3beddf8b3.png)

# 障害原因探索
障害分類ラベルを手掛かりに原因を深堀します。
深堀するときに次のような観点で深堀します。ざっくりした観点ですが、議論のとっかかりとしてこのような観点の発言をして考えていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76786/ecc4d712-11b1-459f-9bb9-021e0928a542.png)

# 例えばこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76786/304818dd-4c4e-0419-2581-224a2271e334.png)
【Android】ViewPager2を使用したの実装方法まとめ （インジケータ表示、View更新の最適化、無限スクロール）

## 実装したいもの
- 横方向にスクロール可能なUIを作成する
- ページ数に連動したインジケーターを表示する
- 無限にスクロール

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1327135/f273965d-a773-435b-413c-820acbf50a85.png" width="200" />

## スクロール可能なUIとインジケーターを作成する
- [ページ数に連動したドットインジケーターの作成方法](https://dharmeshbasapati.medium.com/working-with-viewpager2-23424111aec1)
    - `TabLayout`をインジーターとして使用する（`TabLayoutMediator`）
    - **ただし、無限スクロールと併用することは、この方法では自分が試した限り不可能であった（後述）**

## ViewPager2のView更新を最適化する
- [DiffUtilを使用した方法](https://medium.com/@domen.lanisnik/efficiently-updating-recyclerview-items-using-payloads-1305f65f3068)
    - データの差分を算出し、その差分のみをView更新することができる
    - 表示データを定期的に更新する際、点滅エフェクトが走らないようにしたい場合にも有用
- [TabLayoutの属性のまとめ](https://itnext.io/android-tablayout-and-tabitem-268ac06ba966#e653)
    - インジケーターのドット間隔を調整するなど、UIの調整方法を調べる際に有用

## 無限スクロールの実装
- [方法１：ItemListの前後にフェイクデータを追加する方法](https://qiita.com/leb397/items/b78b8f526e86d7699dea)
    - 実装がやや複雑
    - DiffUtilとの併用が可能（AsyncListdDfferにもフェイクデータを追加すればよい）
    - スクロール時に少し引っかかる感じがある
- [方法２：ItemListSizeをInt.MAX_VALUEなど、大きな値を設定する方法](https://satoshun.github.io/2019/10/viewpager2-loop/)
    - 実装がシンプルで動作も軽量
    - **DiffUtilとの併用ができなかったため、Viewの更新が不要な場合に適している**
    - スクロール時は滑らか
Javaで「単項マイナス演算子」の動作を確認してみた

# 概要

Javaで「単項マイナス演算子」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/ope/index2.html

# 実装

以下のファイルを作成しました。
```JSample2_1.java
class JSample2_1{
  public static void main(String[] args){
    int num = 10;

    System.out.println(+num);
    System.out.println(-num);
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample2_1.java 
$ java JSample2_1 
10
-10
```

# まとめ

何かの役に立てばと。
【ChatGPT＋DALL-E3】GPTsのDALL-Eをちょこっと紹介


　どうも、カーブミラーです。

　今回は、GPTsのDALL-Eをちょこっと紹介します。アップデートされたようなので。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　昨日（2024/05/24）も
　　書きましたが、
　　　昨日で、Qiita投稿一周年です。

　ほぼほぼ
　　ChatGPTでしたね。

　有益な情報を
　　提供できたか
　　　怪しいところですが、
　　　　書き続けました。

　ここからも
　　頑張って続けていこう
　　　と思っております。

　よろしくお願いします🙇
***
　さて、本題です。

　今日は、
　　GPTsのDALL-Eをご紹介。

　これは
　　GPTストアの最初期に
　　　OpenAIで作られたものです。

　以前にも
　　書いたことがあるのですが、
　　　改良されていました。

　こちらが
　　そのスクショになります。
![Screenshot_20240525-123753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/056f03fa-58ad-fe6d-47f3-f03a91406658.png)

　入力枠の上に、
　　日本語で
　　　彫刻、
　　　鉛筆スケッチ、
　　　✘、
　　　アスペクト比
　　とボタンが並びます。

　アスペクト比は
　　正方形、ワイド画面、縦型
　　　を選べます。

　彫刻、鉛筆スケッチは
　　✘をタップするごとに
　　　変わっていきます。
　　　　プルダウンメニュー
　　　　　じゃありません😅

　そこから
　　選んで、タップすると
　　　入力枠にその文字列が
　　　　入力されます。

　続けてタップしていくと
　　“,”で区切られます。

　画風をコントロールするために
　　あるような気がしますね。

　初心者の方には
　　ありがたい機能
　　　かもしれません。

　生成画像も
　　毎回、二枚ずつ出てきますし。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
架空レストランHPの制作過程 Part4 Figmaでデザイン＆プロトタイプ作成編

前回の記事

https://qiita.com/yamashee/items/5069caca62af96d61315

今回はワイヤフレームを頼りに、Figmaでデザイン＆プロトタイプを作っていく制作過程です。

個人的にこのフェーズが最も苦労しました。
私はデザインセンスはそんなになので、他サイトを~~パクr~~参考にしつつ、作っていきました。

文章内容考案や写真選別も自分で行う必要があるので大変でした。
とはいえ自分で好き勝手作れるので結構楽しい作業でもあります。

近年はスマートフォンからのウェブサイト閲覧が主流なので、デザインはモバイル端末の幅から作成しました。
## 写真選別
料理の写真はフリー画像から探しました。
特に、[O-DAN](https://o-dan.net/)という、複数のフリー画像サイトを横断して検索できるサイトからメインで探しました。

参考↓

https://qiita.com/yamashee/items/7163264fcc326ceef0cd

## オートレイアウト機能
FigmaでWebサイトやアプリをデザインしてくうえで、便利なのが**オートレイアウト機能**です。
オートレイアウト機能は、cssのflexboxをノーコードで作り上げていくイメージです。
最近ではflex: wrapやmin-widthも設定できるようになり、より便利になりました。

↓このように、ボタンクリックだけで簡単にflexレイアウトを実現できます。
![autolayout.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/584bf173-c4ae-9183-f721-310d08cce160.gif)

## コンポーネント機能
Figmaの**コンポーネント機能**は、デザインの再利用性を高めるために作成した部品のことです。

イメージとしてHTMLのインクルードが近いかと思います。

ページが大量によるサイトや複雑なアプリを製作する時は、同じ親元から呼び出すことで品質の担保ができます。
パーツを編集したいとなった場合も、親元コンポーネントのみを編集することで、子コンポーネントすべてに反映されます。

要素を選択し、画面中央上部のCreate Compornentボタンをクリックすれば、選択した要素がコンポーネント化されます。
![compornent.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/c92f396d-569f-d1ba-1029-9d81c425f7d1.jpeg)
参照元：[Figma Tutorial: Components - The Basics](https://youtu.be/k74IrUNaJVk?si=KcKc_rH8bxCuBcCp)

今回はトップページのみの制作なので、アコーディオンパネルやタブ切り替えなどの動的機能にのみコンポーネントを活用しました。

そしてこんな感じでデザインが出来上がりました
![design.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/a62c3411-a49f-345d-f8c8-1eff1eeb5d17.jpeg)


## プロトタイプ
Figmaでは、**ノーコード**でプロトタイプを実装することができます。
リンクを共有すれば、Figmaに登録していない人でも簡単に閲覧できます。
もちろん限定公開にすることも可能です。アカウントさえ登録すれば、共同編集も可能です。
まあいろいろやろうとしたら課金が必要になってきますが・・・

紹介したオートレイアウトやコンポーネント機能を覚えれば、ディレクターやデザイナーでもプロトタイプをノーコードで制作＆クライアントに共有することができます。

[今回Figmaで作成したプロトタイプ](https://www.figma.com/proto/CygmvJ3D2BputQ3FSkGUwf/%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0?node-id=133-159&t=xjpubGsvSNlHBGm4-1&scaling=scale-down&page-id=0%3A1&starting-point-node-id=133%3A159)
　
次回は、figmaで作成したデザインをReactで作っていきます。

次の記事↓

https://qiita.com/yamashee/items/94afa64f0db9ff3820df
【AWS】APIGatewayに Cognitoのオーソライザーを付けて、リクエストを制限する

フロントエンドで認証を付ける際、Amplifyライブラリを使用して、CognitoでAuth0認証を付けることがあると思うが、Cognitoでjwt Tokenを受け取り、APIGatewayで認証を付ける方法を紹介する。

1. APIGatewayのコンソール画面を開く
1. 修正したいAPIを開く
1. 左メニューのオーソライザーを開く
   ![cognitoapigateway1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/4062c866-c7d3-528c-2ba2-2f583eee39a5.png)
1. オーソライザーを作成を押す
1. オーソライザー名を入力する
1. オーソライザーのタイプをCognitoにする
1. Cognito ユーザープールを選択する
1. トークンのソースにAuthorizationと入力する
  ![cognitoapigateway3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/6f7f331e-d49a-2ebe-9922-ecd3d236b53a.png)
1. オーソライザーを作成を押す
1. リソースを開き、CORS を有効にするを押す
   ![cognitoapigateway2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9ea7086b-25fc-1a8f-b1ef-c11a340624f0.png)
1. API をデプロイを押す

認可は、Cognito ID Poolのロールで制御できる。


## まとめ
Cognitoのオーソライザーを用いて、APIGatewayに認証・認可を付ける方法を紹介した。
Spring Boot において application.properties を環境ごとに切り替える

## application.properties とは？
Java のフレームワークである Spring Boot で設定情報をキーバリュー形式で記載できるファイルのこと。__この設定情報は JVM のシステムプロパティとして設定される。__

```properties:application.properties
sample.properties=sample
```
 ```java:java sample
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class SampleApplication {
    private final Environment env;
    public DemoApplicationRunner(Environment env) {
        this.env = env;
    }

    public String sample() {
        return env.getProperty("sample.properties");
    }
}
 ```
上記の例では  "sample" という文字列を取得している。

## 読み込むファイルを選択できる
application-(環境名).properties と命名し、JVM のプロパティ spring.profiles.active に環境名を設定することで、読み込むファイルを選択できる。
その際、環境名を付与していないファイルは常に読み込まれる。
 
 **以下の構成において、spring.profiles.active=dev とした場合、
 ・application.properties
 ・application-dev.properties
の 2 つが読み込まれる**
 ```directory:ディレクトリ構成
|--src/main
|  |--java
|  |  :
|  |--resources
|  |  |--application.properties
|  |  |--application-dev.properties
|  |  |--application-prod.properties
 ```

###### application.properties が常に読み込まれることを利用して、spring.profiles.active を設定することもできる。

```properties:application.properties
spring.profiles.active=dev
```


## 環境変数を使用した application.properties の切り替え
${ENVIRONMENT_VARIABLE} とすることで application.properties では環境変数を使用できる ( : を使用してデフォルト値を設定できる )。

```properties:application.properties
spring.profiles.active=${SPRING_PROFILES_ACTIVE:defaultEnvName}
```

環境変数を適切に設定しておくことで、プログラムの起動時に毎回プロパティを設定する必要がなくなる。

##### reference
https://docs.spring.io/spring-boot/docs/1.2.0.M1/reference/html/boot-features-profiles.html
Jupyter Notebook を関数化するライブラリを作成しました

## はじめに

Jupyter Notebook で作成した一連の処理を関数化できるライブラリ[`nbtof`](https://github.com/Nodaka/nbtof/tree/main)を作成しました. `#@~` マークを Notebook の各セルに記述するとNotebook の処理に対応した関数が取得できます. 例えば, 以下の **sample.ipynb** を関数化する時は

**sample.ipynb**

```python
#@param
a = 1
b = 1
```
```python
c = a + b
```
```python
#@ignore
print(a, b, c)
```
```python
#@return
c
```

下記を実行することで関数化された **sample.py** を取得することができます.

```python
import nbtof

nbtof.nbtof_generate(
    notebook_name='sample.ipynb',
    func_py_name='sample.py',
    )
```

**sample.py**

```python
def sample(a, b):
    c = a + b
    return c
```

`nbtof`を利用することで, 

1. Jupyter Notebook で処理過程を確認しながらプログラム作成
1. 関数化して他のプログラムで利用
1. 原因が分かりにくいエラーに遭遇したら元の Notebook で途中の処理を確認しながら原因調査
1. Notebook を修正して即関数化

という手順でバグ修正を効率化できると思います. 

## インストール方法
PyPI から下記でインストールできます.

```
$ pip install nbtof
```

## 利用方法

### マーク一覧
Jupyter Notebook の各セルの最初に対応する`#@~`マークを付けて `nbtof.nbtof_generate()`を実行すると所望の関数化された python ファイルを取得できます. `#@~`マークが無いセルは関数内の処理として関数内に記述されます.

| マーク | 説明 |
| ---- | ---- |
| `#@param` | セル内の変数名は関数の引数になります. Jupyter Notebook内で割り当てられた値は無視されます.|
| `#@default` | セル内の変数名は関数の引数になります. Jupyter Notebook内で割り当てられた値はデフォルト値になります. |
| `#@args` | セル内の変数名が関数の可変長引数 *args の名前になります. Jupyter Notebook内で割り当てられた値は無視されます.|
| `#@kwargs` | セル内の変数名が関数の可変長引数 **kwargs の名前になります. Jupyter Notebook内で割り当てられた値は無視されます. |
| `#@return` | このマークの次の行が関数の戻り値になります. |
| `#@ignore` | このマークがついたセル内の記述は無視されます.Jupyter Notebook内だけで処理過程を確認したいときに使用してください, |
| `#@help` | セル内の内容は Docstring になります. |
| `#@advance` | セル内の記述は関数の宣言前に直接記述されます. インポート等に利用してください|
| `#@r_advance` | セル内の `#` が記述された行は関数の宣言前に `#` が外されて記述されます. 相対インポート等に利用してください |
VSCodeでファイル検索がもっと便利になるかもしれないツール

VSCodeで「ctrl + F」でファイル検索するとき、
エクスプローラ上でフォルダ展開していないと、
検索したいファイルがどこにあるかわからなくて困った...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261995/0b46f155-1e39-e344-80e6-b632ef133618.png)

そんなときは、この「すごいツール!」(小並感)を用いてファイル検索をおこなうと、目的のファイルがどこにあるかを調べることができる。


これが「すごいツール!」のソースコード.
```python
"""VSCodeでファイル検索を行う用の検索するモジュール"""
import glob
import os
import sys

from termcolor import colored


def search_file(path: str, target_file_name: str) -> tuple:
    """
    Get the path name of the file name you want to search.
    Args:
        path: Directory of the file you want to search.
        target_file_name: File name you want to search.
    return:
        the full path of the searched file
    """
    file = tuple(filter(lambda files: target_file_name in files,
                        glob.glob(path + '/**', recursive=True)))
    return file


if __name__ == '__main__':
    current_dir = os.getcwd()
    try:
        target_file = input(colored('検索したいファイル名を入力: ', 'light_green'))
        find_file = search_file(current_dir, target_file)
    except (FileNotFoundError, ValueError, TypeError, IndexError) as exc:
        print(colored(f'{exc} が発生.', 'light_red'))
    else:
        if any(find_file):
            print('検索結果:', colored(*find_file, 'light_yellow'))
        else:
            print(colored('要素が見つかりません。', 'light_yellow'))
    finally:
        sys.exit()

```

1. 実行方法
VSCodeを実行中に、「ctrl + @」でターミナルを起動し、可読性を向上に用いているライブラリをインストール。
```powershell
python -m pip install termcolor
```

2. 起動方法
以下のコマンドを実行。
```poweshell
python searcher.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261995/8b748a99-60e0-2581-f645-a5fa81c1a906.png)


「検索したいファイル名を入力：」に検索したいファイル名を入力し、力強くエンターキーをターンっ!!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261995/9c69714c-4267-cf13-6936-84c20b177677.png)


すると、検索結果が得られ、目的のファイルがどこに存在するかのパスを取得できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261995/3106e4f4-40f0-01da-2308-8cfe2b11a049.png)

この「すごいツール!(小並感)」を使ってより効率的な開発を行うえるようになることでしょう。

おしまい。
Auroraのストレージについて

# 背景

Auroraのストレージの監視項目について検討していた時に、ふと以下の疑問が湧き上がりました。

**「Auroraのストレージって自動拡張なはずなのに、監視する必要ってあるのかな？」**

調査していくうちに興味深いことがわかったので備忘録として残しておこうと思います。

# Auroraのストレージについて

Auroraのストレージには実は2種類のストレージが存在しています。

> ・クラスターボリューム
> ・ローカルストレージ

自動拡張されるストレージは「クラスターボリューム」の方で、「ローカルストレージ」はインスタンスサイズによって決定されるため拡張する際にはインスタンスサイズの変更が必要になります。 *1

2つのストレージの違いについては以下の表にまとめてみました。

|  | クラスターボリューム | ローカルストレージ |
|---------------|---------------|---------------|
| 特徴 | 各インスタンス専用のストレージ | 複数インスタンスで共有可能 |
| 用途 | エラーログ、一般ログなどの保管 | データの保管 |
| 容量 | インスタンスサイズに依存 | 最大128TiBまで拡張可能 |
| 拡張 | インスタンスサイズの変更 | 自動で拡張 |
| 容量 | 基本は固定 | ストレージの容量によって変動 |

# 各ストレージと監視項目との対応

Auroraのストレージ監視項目としては主に以下の3つが存在しています。

> ①AuroraVolumeBytesLeftTotal (MySQL限定)
> ②VolumeBytesUsed
> ③FreeLocalStorage

名前から想像がつくと思いますが、①と②がクラスターボリュームの監視項目で③がローカルストレージの監視項目になります。

具体的な使い分けについては以下を基準に考えると良いかもしれません。


**①サービスへの影響を確認したい**

→FreeLocalStorageを監視しましょう。

**②AWS利用料の高騰を確認したい**

→AuroraVolumeBytesLeftTotal、VolumeBytesUsedを監視しましょう。

# 参考
*1.[ローカルストレージの容量について](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html#AuroraMySQL.Managing.TempStorage)
TypeScript勉強してみた②

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

**「いいね」か「ブックマーク」**
を頂けると僕のモチベーションアップになります！:thumbsup:
少しでも気に入っていただけたらよろしくお願いいたします！:thumbsup:


# 今回の目的
TypeScriptがわからなくてやばたにえんなので、ハンドブックで学んでみました。
（前回）

https://qiita.com/mr_noppo/items/da5cc18717c84df7d656

# 主に参考にさせていただいた記事

https://www.typescriptlang.org/docs/handbook/intro.html

# TypeScript ハンドブック
この章を読んでできるようになること
・よく使われるTypeScriptの構文とパターンを読んで広く浅く理解する
・重要なコンパイラオプションの効果を説明する
・ほとんどの場合、型システムの動作を正しく予測する

# 基礎

### 静的型チェック
javaScriptだと実行するまでどちらがエラーになるか分からない。
```js
// 文字列だったら動作する
message.toLowerCase();
// 関数だったら動作する
message();
```
もし下記のように定義していた場合、関数呼び出しでエラーになる。
```js
const message = "hello";
```
これがTypeScriptの場合、記述時点で警告してくれます。
```ts
//Type 'String' has no call signatures.
message();
```

### 存在しないプロパティ名
下記の場合でもTypeScriptなら実行前に警告してくれる。
```ts
const user = {
  name: "Daniel",
  age: 26,
};
user.location;
```
TypeScript
```ts
// Property 'location' does not exist on type '{ name: string; age: number; }'
```
JavaScript
```js
// returns undefined
```

### スペルミス
```ts
// Property 'toLocaleLowercase' does not exist on type '"Hello World!"'.
// Did you mean 'toLocaleLowerCase'?
announcement.toLocaleLowercase();
 
// 正しいスペル
announcement.toLocaleLowerCase();
```

### 関数呼び出しミス
```ts
function flipCoin() {
  // 本来は、Math.random()で呼ばなくてはいけない
  // Operator '<' cannot be applied to types '() => number' and 'number'.
  return Math.random < 0.5;
}
```

### 論理ミス
```ts
const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {
  // ...
} else if (value === "b") {
  // aしか来ないのにbであることを判定しているため
  // This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.
}
```

### コード補完
エラー解消を提案するクイックフィックスなど、VSCodeはデフォルトで補完されるよにサポートされてます。

### tsc(TypeScriptのコンパイラ）
tscコマンドはtsファイルをコンパイルしてjsファイルを生成する
```bash
tsc hello.ts
```
エラーがあるまま実行すると下記のようなエラーを出します。
例：引数が二個必要なのに一つ指定で呼び出した場合
```bash
hello.ts:5:3 - error TS2554: Expected 2 arguments, but got 1.

5   greet("Brendan");
    ~~~~~

  hello.ts:1:24
    1 function greet(person, date) {
                             ~~~~
    An argument for 'date' was not provided.


Found 1 error in hello.ts:5
```


# 次回の予定
https://qiita.com/mr_noppo/items/fef33cb1e6d59dc07197
PostgreSQLの実行計画の読み方:SQLチューニング#5

### 実行計画とは

PostgreSQLなどのDBMSがSQL文を実行する手順書。

### 実行計画の取得方法

例えば以下のように実行計画を取得したいSQLの前にEXPLAINをつける。

```
EXPLAIN ANALYZE SELECT * FROM address
```
pgAdmin4では以下のように出力される

![pgAdminで実行計画.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/703622cf-016c-5957-4f0a-b7e7db179385.png)

### 実行計画1行ずつの意味

3行出力されて1行目はこちら

```
Seq Scan on address  (cost=0.00..15169.77 rows=124677 width=832) (actual time=0.285..173.450 rows=124677 loops=1)
```
・Seq Scan
プラン演算子という、データの探し方のようなことを取り扱う演算子の1つ。テーブルフルスキャンを指していることを示す。

・cost 
処理完了までにかかるコスト

・rows
返却される検索結果の行数

・width
返却される1行当たりの長さ

2行目はこれ

```
Planning Time: 4.876 ms
```

・Planning Time
実行計画生成、最適化に要した時間

3行目はこちら

```
Execution Time: 177.293 ms
```

・Execution Time
実行時間

Planning TimeとExecution Timeは
ANALYZEオプション使用時に表示される
【SwiftUI】高さ可変のTextEditor

# 完成イメージ
- 入力が空の場合はプレースホルダーを表示
- 改行した分だけ高さが変化する

# コード
```: swiftUI
import SwiftUI

struct DynamicHeightTextEditorView: View {
    // 入力するテキスト
    @Binding var text: String
    // プレースホルダーの文字
    let placeholder: String
    // 最大の高さ
    let maxHeight: CGFloat

    var body: some View {
        ZStack(alignment: .leading) {
            // テキストエディター
            HStack {
                if text.isEmpty {
                    Text(placeholder)
                        .foregroundColor(.gray)
                } else {
                    Text(text)
                }
                Spacer(minLength: 0)
            }
            .allowsHitTesting(false)
            .foregroundColor(.clear)
            .padding(.horizontal, 5)
            .padding(.vertical, 10)
            .background(
                TextEditor(text: $text)
                    .offset(y: 1.8)
            )
        }
        .padding(.horizontal, 10)
        .frame(maxHeight: maxHeight)
        .fixedSize(horizontal: false, vertical: true)
        .background(Color.white)
        .mask(RoundedRectangle(cornerRadius: 18).padding(.vertical, 3))
    }
}


#Preview {
    struct PreviewView: View {
        @State private var text: String = ""

        var body: some View {
            HStack {
                DynamicHeightTextEditorView(
                    text: $text,
                    placeholder: "入力してください。",
                    maxHeight: 200
                )
            }
            .padding()
            .background(Color.mainColor)
        }
    }
    return PreviewView()
}
```

# 参考資料
今回こちらの記事を参考にさせていただきました。`text`が空の時にプレースホルダーが表示されなかった点を修正しました。

[【SwiftUI】チャットアプリのような動的な高さの TextEditor を実装する](https://qiita.com/GleamingCake/items/167d624ec932aa2d71a5)
任意のアスペクト比を完全にサポートするLLaVA-UHDモデル

※ このページは「LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images」の要約になります。

## このページでわかること
- LLaVA-UHDは、任意のアスペクト比と高解像度画像を効率的に認識するための大規模マルチモーダルモデル
- 画像を可変サイズのスライスに分割してエンコードし、圧縮モジュールと空間スキーマを活用
- 従来のモデルよりも優れた性能を示し、特にテキストVQAで精度向上を達成

## 対象読者
- 視覚と言語の統合に関する先進的な技術やアルゴリズムに興味がある人
- 高解像度画像処理や任意のアスペクト比に対応する効率的なモデルの設計と実装に関心がある人

##  の問題点

従来の大規模マルチモーダルモデル（LMM）が画像を固定サイズや低解像度で処理することに伴う以下の問題です：

1. **適応性の欠如**：従来のLMMは、画像を固定サイズ（例えば1:1のアスペクト比）や低解像度で処理するため、さまざまなアスペクト比や高解像度の画像を効果的に扱うことができない。このため、画像の形状が歪んだり、内容がぼやけたりする問題が生じる

2. **効率性の問題**：高解像度画像を直接エンコードするには大規模な計算コストがかかり、また視覚エンコーダから生成される多くのトークンを処理することがLLMにとって負担となるため、効率的な画像処理が困難

3. **正確性の問題**：視覚エンコード戦略の不適切さが原因で、モデルが画像の内容を正確に認識できず、誤ったテキスト応答（事実に基づかない応答）を生成するリスクがある。これは特に細かいオブジェクトの理解や光学文字認識（OCR）において顕著


## LLaVA-UHD
### LLaVA-UHD とは？
LLaVA-UHD（LLaVA-Universal High-Definition）は、高解像度画像と任意のアスペクト比の画像を効率的に認識できる大規模マルチモーダルモデル（LMM）です。LLaVA-UHDは、画像をより小さな可変サイズのスライスに分割し、これを効率的にエンコードする新しい戦略を採用しています。また、視覚トークンを圧縮し、LLM（大規模言語モデル）に適した形式で配置することにより、計算効率と精度を向上させています。

### LLaVA-UHD のメリット
1. **適応性の向上**：LLaVA-UHDは、画像を可変サイズのスライスに分割することで、任意のアスペクト比と高解像度の画像に適応できる
2. **効率的な計算**：圧縮モジュールを使用して視覚トークンを圧縮し、計算コストを低減しています。これにより、従来モデルと比較して高解像度画像を処理する際の計算効率が向上する
3. **精度の向上**：高解像度の画像を正確にエンコードすることで、特に細かいオブジェクトの理解や光学文字認識（OCR）において優れた精度を実現する

### LLaVA-UHD のアーキテクチャ

LLaVA-UHDのアーキテクチャは、以下の3つの主要なコンポーネントから構成されています。

1. **画像モジュール化戦略（Image Modularization Strategy）**
2. **圧縮モジュール（Compression Module）**
3. **空間スキーマ（Spatial Schema）**

#### 1. 画像モジュール化戦略
高解像度画像をより小さな可変サイズのスライスに分割します。この戦略により、以下のメリットがあります：
- **効率的なエンコード**：画像を適切なサイズのスライスに分割することで、視覚エンコーダの負荷を軽減し、効率的に画像を処理できる
- **適応性**：スライスのサイズは可変であり、画像のネイティブ解像度やアスペクト比に適応します。これにより、パディングや形状の歪みを避けることができる

スライスの分割方法は、画像の解像度（W × H）と視覚エンコーダの標準解像度（w × h）に基づいて決定されます。スライスの数は計算され、可能な分割方法（m × n）が評価されます。最適な分割方法は、視覚エンコーダの標準設定からの逸脱が最小となるように選択されます。

#### 2. 圧縮モジュール
視覚エンコーダから出力される視覚トークンを圧縮し、LLMに適した形式で提供します。このモジュールは以下の特徴があります：
- **Perceiver Resampler**：視覚トークンを固定数のクエリベクトルに圧縮し、クロスアテンションを使用して効率的に処理します。これにより、従来のMLPベースの方法よりも少ない計算コストで視覚情報を圧縮できる
- **固定トークン数**：視覚トークンの数は画像の解像度に依存せず、固定された数に保たれます。これにより、高解像度画像の処理が効率化される

#### 3. 空間スキーマ
圧縮されたスライストークンをLLMに適切に伝えるためのスキーマです。具体的には、スライスの位置情報をLLMに伝えるための特別なトークンを使用します。
- **カンマ（,）と改行（\n）トークン**：スライスの行を区切るためにカンマ、行間を区切るために改行を使用します。これにより、LLMはスライスの位置情報を理解しやすくなる

### LLaVA-UHD の性能
LLaVA-UHDは、9つのベンチマークで従来のLMMを上回る性能を示しています。特に、テキストVQA（Visual Question Answering）では6.4ポイントの精度向上を達成しています。また、計算効率も高く、LLaVA-1.5と比較して94%の推論計算コストで6倍の解像度（672×1088）をサポートしています。これにより、低解像度画像に起因するぼやけや歪みを回避し、精度の高い画像認識を実現しています。

## まとめ
以上がLLaVA-UHDの要約でした。LLaVA-UHDは話題になっていたマルチモーダルモデルですが、GPT-4VはOCRの精度が悪いと思っていたのでその解決になるようなモデルであれば嬉しいですね。

おわり。
html radioの使い方 JavaScript含む

 Radi Button の具体的な使い方を提示します。
 group化、送信の具体例などを記載します。
 gloop1とgloop2は　&lt;table&gt;&lt;tr&gt;&lt;td&gt;gloop1&lt;/td&gt;&lt;td&gt;gloo2&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;で省スペースも可能です。
 具体的な表示
 ![スクリーンショット 2024-05-25 101447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/b855576a-fde6-b888-6603-60b02f182ec0.png)
```HTML test0.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">

    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="description" content="たっちゃん,studio。">
<title>my_test0</title>
<style>
    body {
        background-color: #f0f0f0;
        color: #000;
        font-size: 16px;
        margin: 10px;
    }
    fieldset {
        width: 300px;   
        padding: 10px;
        margin: 10px;
    }
    legend {
        padding: 5px;
        background-color: #f0f0f0;
    }
    label {
        display: block;
        margin: 5px;
    }
</style>
<script src="my_test.js"></script>
</head>
<body>
    <!--test-->
    <form name="form1"><fieldset>
        <legend>Select form1 a maintenance drone:</legend>
        <label><input type="radio" name="test" checked onchange="gloop1(1);">選択肢1A</label>
        <label><input type="radio" name="test" onchange="gloop1(2);"">選択肢1B</label>
    </fieldset></form>
    <form name="form2"><fieldset>
        <legend>Select form2 a maintenance drone:</legend>
        <label><input type="radio" name="test" checked onchange="gloop2(1);">選択肢2A</label>
        <label><input type="radio" name="test" onchange="gloop2(2);">選択肢2B</label>
        <label><input type="radio" name="test" onchange="gloop2(3);">選択肢2C</label>
    </fieldset></form>
    <form name="all_master"><fieldset>
        <legend>select receive</legend>
        <input type="button" value="test" onclick="ok_gloop();"><br>
    </fieldset></form>
    <!--test end-->
</body>
</html>
```
``` JavaScript my_test.js
// test 2024/05/25
// Path: my_test.js
/* mt note: this is a test */

let global_gloop1 = 1;
let global_gloop2 = 1;
function gloop1(nomber){
    global_gloop1 = nomber;
    alert(global_gloop1);
}
function gloop2(nomber){
    global_gloop2 = nomber;
    alert(global_gloop2);
}
function ok_gloop(){ // button
    alert("gloop1: " + global_gloop1 + " gloop2: " + global_gloop2);
}

```
答え
![スクリーンショット 2024-05-25 105202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/ac41697c-b061-38ea-6550-ead47ab1501d.png)
もちろん、onchange="gloop1('選択肢1A');"
として、受け側も文字列にすれば、簡単に出来ます。
![スクリーンショット 2024-05-25 105912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/b9e31462-065f-a65b-b2b3-865b0dd1d592.png)

と言う事で、まとめてみました。
比較演算子 in と not in の使い方【Python】

## 比較演算子 in と not in を用いて、ある要素が含まれるかどうかを判定する
### 基本的な使い方
以下のような形で記述する。
![Python 画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780127/3119899f-db31-bab2-c4a8-3a3842dd9476.png)
    in 演算子と not 演算子では in 演算子が優先されるため、not 要素 in 集合 と記述する際に、括弧は必要でない。

要素 a , 集合 B とする。
a が B に含まれるとき、a in B は True 、a not in B は False を返す。
a が B に含まれ**ない**とき、a in B は False 、 a not in B は True を返す。
### if 文での使い方
bool値（True / False）を返す比較演算子なので、if の後にそのまま記述できる。
```Python:
list = [0, 1, 2, 3]
i = 2
if i in list:
    print(f'{i} は含まれる')
else:
    print(f'{i} は含まれない')

# 2 は含まれる
```
### in 演算子と文字列
in, not in を用いると、部分文字列であるかそうでないかの判定ができる。
```Python:
string = 'The quick brown fox jumps over the lazy dog.'
i = 'row'
if i in string:
    print(f'{i} は含まれる')
else:
    print(f'{i} は含まれない')

# row は含まれる
```
Databricks にて共有アクセス モードを利用した場合の Pandas から Spark データフレームへの変換エラー：CANNOT_ACCEPT_OBJECT_IN_TYPE

## 概要

Databricks にて共有アクセス（shared access mode）モードを利用して、 int64 のカラムをもつ Pandas を double 型のスキーマを指定して Spark データフレームに変換すると下記のようなエラーとなるようです。本エラーは今後の Databricks の機能アップデートにより解消されるかもしれませんが、備忘録として残しておきます。対応方法としては、Pandas にて int64 を double に変換する方法とシングルユーザーアクセスモードを利用する方法があります。

> PySparkTypeError: [CANNOT_ACCEPT_OBJECT_IN_TYPE] `DoubleType()` can not accept object `1` in type `int`.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/74852664-73c1-e02b-fd24-d2201e1bb801.png)

## エラーの再現方法

### 1. 共有アクセス（shared access mode）モードのクラスターを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/de092eda-e982-48fc-d6b0-5089bbfa78ca.png)

### 2. Pandas から Spark データフレームへの変換を実施してエラーとなることを確認

```python
import pandas as pd

# int64 型のカラムを持つデータフレームを作成
pdf = pd.DataFrame({
    'numeric_col': pd.Series([1, 2, 3], dtype='int64')
})

# Pandas から Spark データフレームに変換
sdf = spark.createDataFrame(
    pdf,
    "numeric_col double",
)

sdf.display()
```

## 対応方法

### 1. Pandas にて int64 を double に変換する方法

```python
import pandas as pd

# int64 型のカラムを持つデータフレームを作成
pdf = pd.DataFrame({
    'numeric_col': pd.Series([1, 2, 3], dtype='int64')
})

# numeric_col を double 型に変換
pdf['numeric_col'] = pdf['numeric_col'].astype('float64')

# Pandas から Spark データフレームに変換
sdf = spark.createDataFrame(
    pdf,
    "numeric_col double",
)

sdf.display()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/63808f8f-edb6-da42-e093-17179c0fdcd6.png)

### 2. シングルユーザーアクセスモードを利用する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e89a2419-839e-024a-16d7-b473d600eb06.png)

```python
import pandas as pd

# int64 型のカラムを持つデータフレームを作成
pdf = pd.DataFrame({
    'numeric_col': pd.Series([1, 2, 3], dtype='int64')
})

# Pandas から Spark データフレームに変換
sdf = spark.createDataFrame(
    pdf,
    "numeric_col double",
)

sdf.display()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f798b928-8891-6ab2-3df8-108175053a63.png)