OmniAICreator/Qiita-1.07M huggingface dataset:
ベースURLの設定方法

## ベースURLとは？

★相対パスの基準URL（例：http://localhost/）
★すべてのAPIパスは相対パス（よく忘れるから気をつける）
★すべてのAPIエンドポイントはベースURLを基準としている

# SwaggerのベースURLの設定方法

SwaggerのserversってところにベースURLを設定することができる

書き方はコチラ💁
[API Server and Base URL](https://swagger.io/docs/specification/api-host-and-base-path/)（公式ドキュメント参照）
[API Host and Base URL](https://swagger.io/docs/specification/2-0/api-host-and-base-path/)（公式ドキュメント参照）

例えば、本番環境のベースURLと検証用のベースURLを複数もつことができて、Swagger UIでこれを切り替えることができる。

### １、Swagger EditorのserversにAPIサーバのベースURLを指定する
### ２、Swagger UIにドロップダウンメニューで指定したベースURLを選択する

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/af9fdf76-8fc9-f941-7a7a-c2ca57f46c60.png)

:::note warn
すべてのAPIパスは、相対パスです。
:::
### ３、Swagger UIのテスト実行（省略）

詳しくは、コチラ💁[Swaggerでテストする方法](https://qiita.com/tetsuyamakabe/items/da6a9eb8aebc2911956d)
「Try it out」をクリック ⇒ 「Execute」をクリック

### ４、テスト結果の表示

![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/e8b8dc38-68d9-368b-2a50-3e4a6f7dafd5.png)


レスポンスの中に「**'http://api.example.com/v1/session/register' \**」があります。動作確認完了です。

APIサーバっていうとちょっとインフラって感じもしますね。

参考記事：

[API Server and Base URL](https://swagger.io/docs/specification/api-host-and-base-path/)
[API Host and Base URL](https://swagger.io/docs/specification/2-0/api-host-and-base-path/)
[Swagger（OpenAPI3.0）に入門する（基本構成編）](https://zenn.dev/marbull/articles/15d2670594ecbc)
[Web API入門#3 〜URIの基礎知識〜](https://qiita.com/s79ns/items/c4ec2db048fa3b13638e)
[swagger/OpenAPI 3.0で本番と検証用のURLを明示的に示す](https://shinkufencer.hateblo.jp/entry/2019/12/11/000000)
[OpenAPI (Swagger) 超入門](https://qiita.com/teinen_qiita/items/e440ca7b1b52ec918f1b)
ラムダ式の中では「実質的にfinalでない変数」は使えないらしい

# はじめに
業務でJavaのStream APIを書いたときにエラーが出たので調べたことをメモします。

# 問題
日付と値を持つオブジェクトのリストと、対象期間が与えられ対象期間内でリストにない日付のデータを補完する処理を書きました。

```java
List<Object> dateAndValList = List.of(); // 実際には検証したいオブジェクトのリスト
LocalDate startDate = LocalDate.parse("2024-01-01");
LocalDate endDate = LocalDate.parse("2024-02-01");

while(!startDate.isAfter(endDate)) {
    if (dateList.stream().filter(date -> date.isEqual(startDate)).count() < 1) {  
        // 補完する処理
    }
    startDate.plusDays(1);
}

```

StreamAPIを利用している行で以下のエラーが発生してしまいます。
```
Local variable defined in an enclosing scope must be final or effectively final
```

どうやら、ラムダ式の中で使う変数は「実質的にfinalな変数」である必要があるらしい。
実質的にというのはfinalで修飾されていなくても変更されない変数ならOK、ということのようです。

# 解決方法

以下のように修正しました。

```java
List<Object> dateAndValList = List.of(); // 実際には検証したいオブジェクトのリスト
LocalDate startDate = LocalDate.parse("2024-01-01");
LocalDate endDate = LocalDate.parse("2024-02-01");

while(!startDate.isAfter(endDate)) {
    LocalDate checkDate = startDate;
    if (dateList.stream().filter(date -> date.isEqual(checkDate)).count() < 1) {  
        // 補完する処理
    }
    startDate.plusDays(1);
}

```

# おわりに

だいぶ苦肉の策でした。
もっと良い方法があればぜひ教えてください。
Bearer認証の追加方法

## Bearer認証とは？

（読み方：ベアラーにんしょう・ベアラにんしょう）

>ログイン・パスワードでユーザー認証を行った際に、認可サーバーから発行されるアクセストークンを使って、APIのリクエスト時にAuthorizationヘッダにアクセストークンを含めて送信します。

（個人的にセッションの考えに似ている気がします🤔）

![パソコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/1e7c2bbf-94d2-9773-88e5-b1ef381a60c4.png)

《概要》
>①クライアントがログイン時にサーバーはアクセストークンを発行
②発行されたトークンをクライアントのブラウザ内のsessionStrageかlocalStrageに保存
③ページへのアクセス時にAuthorizationヘッダにトークンセットし、サーバーにRequest送信
④サーバーはトークンを確認し、有効ならリクエストされたページをレスポンス

# SwaggerのBearer認証

（準備）Swagger EditorにBearerトークンの明記をしないといけない。
書き方はコチラ💁
[Bearer Authentication](https://swagger.io/docs/specification/authentication/bearer-authentication/)（公式ドキュメント参照）
[Authentication and Authorization](https://swagger.io/docs/specification/authentication/)（公式ドキュメント参照）

### １、**Swagger EditorにBearer認証を定義する**

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/e49e168b-e4c0-50b6-7d07-280978e364c2.png)


### ２、Swagger UIで「Authorize🔓」「🔓」（南京錠）アイコンが表示される

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/cbca325b-7786-1d1d-b1f1-2cb3e8ab381e.png)


### ３、「Authorize🔓」または「🔓」アイコンをクリック

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/14a6e193-083b-cc64-e0b5-a9bef110ad77.png)

### ４、Value:の中に（例）sample_tokenを入力する

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/e8f06b83-da4d-43be-2bbc-fbfb1b63c8ce.png)


### ５、これでよければClose、もう一回やり直したいならLogout

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/dad61871-9adf-c03e-b9e2-3c75582a17dd.png)


### ６、Swagger UIのテスト実行（省略）

詳しくは、コチラ💁[Swaggerでテストする方法](https://qiita.com/tetsuyamakabe/items/da6a9eb8aebc2911956d)
「Try it out」をクリック ⇒ 「Execute」をクリック

### ７、テスト結果の表示

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/dd86bf7d-822b-6233-fb84-0b46f9876d3e.png)


レスポンスの中に「**'Authorization: Bearer sample_token'**」があります。動作確認完了です。

★開発ツールのネットワークタブの中の「Request Headers」からBearerトークンの確認ができるらしい（Swagger UIのページで開発ツールを確認したが、どこにもBearerトークンがなかった。これは実装しながら確認したいと思う）

トークンとか認証の通信（ネットワーク）は、実際のWEBアプリから目に見えるものではなく、イメージがつきにくいものです。

参考記事：
[様々な認証方式について(Bearer,Basic,Digest,Form,OAuth)](https://zenn.dev/kome471/articles/4b8ffc4aac0f6f)
[HTTP 認証](https://developer.mozilla.org/ja/docs/Web/HTTP/Authentication)
[Bearer認証について](https://qiita.com/h_tyokinuhata/items/ab8e0337085997be04b1)
[Bearer Authentication](https://swagger.io/docs/specification/authentication/bearer-authentication/)
[OpenAPI (Swagger) 3.0 で Bearer トークンの使用を定義する](https://riotz.works/articles/lopburny/2019/08/17/describe-bearer-scheme-in-openapi-3/)
vuetify3でテーブルを固定ヘッダーにしつつ無限スクロール機能をつけたい

vuetify3でテーブルを固定ヘッダーにしつつ無限スクロール機能をつけて実装しようとしたら少しハマったおはなし

## 今回やること
- テーブルを固定ヘッダーにしつつ、無限スクロール機能をつける
- vuetify3のDataTableとInfiniteScrollerを使って実装する

参考
data-table: https://vuetifyjs.com/en/components/data-tables/basics/
infinite-scroller: https://vuetifyjs.com/en/components/infinite-scroller/

## これで行けると思ったがいけなかったコード
data-tableをinfinite-scrollで囲んで実装できるかなと思った
```
<v-infinite-scroll :items="items" height="400" @load="loadItems">
    <v-data-table
      :headers="headers"
      :items="items"
      :items-per-page="-1"
      :fixed-header="true"　// ヘッダーを固定するプロパティ
      height="350"
    >
      <template #bottom /> <!-- ページネーションを削除している -->
    </v-data-table>
</v-infinite-scroll>

〜〜〜〜〜　loadItem()は追加のitemsをロードする関数　〜〜〜〜〜〜〜
```

↓テーブルを固定ヘッダーにすることはできるが、無限スクロール機能が壊れてしまう。。

![スクリーンショット 2024-02-05 18.06.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3300489/6664022e-4c9e-2ea8-6c35-646c889f7e72.png)

## 考えられる原因(予想)
- まず、DataTableでヘッダーを固定するにはfixed-header, heightプロパティを設定する必要があり、InfiniteScrollerもheightプロパティを設定する必要がある
- が、DataTableとInfiniteScrollerに設定したheightが競合してInfiniteScrollerのloadイベントがうまく検知できずにいるかもしれない


## どうやって解決するか
- DataTableの中のbodyを消して、tbodyを自作してそこに無限スクロールの機能を持たせる感じにしてあげる

↓こんな感じ

```
<v-data-table
  :headers="headers"
  :items="items"
  :items-per-page="-1"
  :fixed-header="true"
  height="350"
>
    <template #body />
    <template #tbody="{...slots}">
      <v-infinite-scroll tag="tbody" :items="slots.internalItems" @load="loadItems" empty-text="">
        <v-data-table-row
            v-for="item in slots.internalItems"
            :item="item"
            :key="item.key"
            :v-slots="slots"
        />
      </v-infinite-scroll>
    </template>
    <template #bottom /> <!-- ページネーションを削除している -->
</v-data-table>
```

これで一旦テーブルのヘッダーを固定しつつ無限スクロールの機能を実装することができた

## だがしかし、
なんかローディングの丸いやつが真ん中にいない。。。
![スクリーンショット 2024-02-06 18.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3300489/dd22a3c6-8f50-a873-6b70-4276c9999b20.png)

どうしよ。

## cssでゴリ押す
v-deepを使ってこのクルクルにcssを当てちゃいます
```
:deep(.v-infinite-scroll__side:last-child) {
  position: relative;
  top: 8px;
  bottom: 8px;
  display: table-row;
  height: 56px;
}

:deep(.v-infinite-scroll__side > .v-progress-circular) {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
```
すると、、、
![スクリーンショット 2024-02-06 18.45.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3300489/32e6430c-d3a3-51a4-ee63-4f967ec3b32f.png)

いい感じに真ん中行きました！ :tada: 

最後はこんな感で固定ヘッダーにしつつ、無限スクロール機能を実装できました! :tada: :tada: ![スクリーンショット 2024-02-07 18.50.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3300489/755dd90c-a92b-d2a7-0411-5e59068c4db2.png)

最後まで読んでくれてありがとうございます!! :bow: 誰かの参考になれば嬉しいです! :smile_cat:
ffmpegがGLIBCを要求しているが見当たらない時の対処法

discord.pyでVoiceClientを使っていたらffmpegがエラーを吐いた(おそらく今後も何度か出る)のでメモとして残しておく。

エラー:

```bash
ffmpeg: /nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6: version 'GLIBC_2.38' not found (required by /nix/store/i0jkvikpn3rp3n80hw06fsw06n1v8w81-libX11-1.8.7/lib/libX11.so.6)
ffmpeg: /nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6: version 'GLIBC_2.38' not found (required by /nix/store/i43ix7srp9r2c92s79qj4vkx0av3m1b9-libXcursor-1.2.1/lib/libXcursor.so.1)
ffmpeg: /nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6: version 'GLIBC_2.38' not found (required by /nix/store/wly9486arl4krf1nm4yic8wc848z28qn-cpplibs/lib/libstdc++.so.6)
ffmpeg: /nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6: version 'GLIBC_2.38' not found (required by /nix/store/hbksywp6j5zabm9j5yp8in1l7h524w7b-libxcb-1.16/lib/libxcb.so.1)
ffmpeg: /nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6: version 'GLIBC_2.38' not found (required by /nix/store/kl4j6fjadg3lqaqv8r9p1lsjrwmi4cz8-glib-2.78.3/lib/libglib-2.0.so.0)
```

ffmpegが特定のバージョンのGLIBC(GNU Cライブラリ)を要求しているが、そのバージョンがインストールされていないという意味

解決策:

```bash
nix-channel --update
nix-env -u
```

```bash
nix-env -iA nixpkgs.ffmpeg
```

間違いがあれば指摘してください。
Swaggerでテストする方法

結論：Swagger UIを使う

公式ドキュメント（Swagger UI）→https://swagger.io/tools/swagger-ui/

![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/cf02c76e-c201-30ec-8685-6b2f08c7105e.png)

Swagger UIは、OpenAPI仕様からインタラクティブなAPIドキュメントを自動的に生成するツールのこと

（特徴）
• ドキュメントから直接APIにリクエストを送信し、レスポンスを確認することができるインタラクティブなUI。
• カスタマイズが可能で、APIのドキュメントを美しく表示。
• 組み込みの認証メカニズムにより、安全なテストが可能。

★Swagger EditorとSwagger UIをDockerで立ち上げてローカル環境でテストする方法もある
詳しくはコチラ💁[Swagger UIとSwagger EditorをWebサーバで動かす](https://qiita.com/danishi/items/84ad8595db548db818d2)
（Dockerの知識不足なので割愛するけど、実際のAPIテストで試してみる予定）
★Swagger Editorの右側がSwagger UIにあたるのでGUIでテストしてみる

## １、Swagger Editorを開く

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/6a99e105-d57a-112c-fadf-a76800c48584.png)
Swagger UIは画面右側です

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/568ef4d7-8611-8650-12c1-80a43bdf8f3d.png)

名称は次のとおりです。
>**APIのエンドポイント**：APIのエンドポイントと概要を表示
**Try it out**：クリックすることでテストを行うことができる。クリック後にテスト用の入力エリアやボタンが表示される
**Parameters**：リクエストのパラメータ情報を表示。Try it outをクリックすると入力または選択可能
**Request body**：レスポンス情報の例を表示


## ２、「Try it out」をクリック

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/7b639c6a-69dc-5a24-55ba-7aeab6550959.png)


## ３、「Execute」をクリック

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/2f109fc3-354c-d4eb-9db3-fb11a38bb1f1.png)
APIのテストを実行

## ４、テスト結果の表示

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/ba587706-21e4-6dd1-e75c-8c09ac629723.png)


![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/833d59fb-d563-dfc4-38be-9cf72b9cd2b5.png)



名称は次のとおりです。
>**Executeボタン**：APIのテストを実行
**Clearボタン**：APIの実行結果をクリア
**コマンドエリア**：APIテスト時のCurlコマンド及びリクエストURLが表示
**Response body**：レスポンス結果を表示


参考記事：
[Swaggerの機能について詳しく説明](https://zenn.dev/minateru/articles/github-zenn-linkage-20240111-2)
[Swaggar UIの使い方](https://manual.nodeai.io/docs/berry/4/)
[開発効率を上げる！Swaggerの記法まとめ](https://techblog.zozo.com/entry/swagger_yaml)
[Swagger UIとSwagger EditorをWebサーバで動かす](https://qiita.com/danishi/items/84ad8595db548db818d2)
認証情報の取り回し

## **はじめに**
ログイン・ログアウト機能じゃなくて、全体的にユーザー認証情報をどのように持つのか？
バックエンドだけで実装するには？
セッションとかAPIトークンについて調べる

LaravelはAuth認証システムとして、passportとsanctum（読み方：サンクタム）を提供
• Laravel passportは OAuth2（読み方：オーオース）認証ベース
• Laravel SanctumはAPIトークンベース

[Laravel Sanctum](https://github.com/laravel/sanctum)を使ってAPIトークン（BearerToken　読み方：ベアラートークン）を使った認証とLaravelのセッション管理を使ったSPA認証のパターンが実装できる！

## **APIトークン機能とSPA 認証機能**

Laravel SanctumはAPIトークン機能とSPA認証機能という２つの機能がある

>Laravel Sanctumは、受信リクエストが自身のSPAフロントエンドから発信された場合にのみクッキーを使用して認証を試みます。Sanctumが受信HTTPリクエストを調べるとき、最初に認証クッキーをチェックし、存在しない場合は、Sanctumは有効なAPIトークンのAuthorizationヘッダを調べます。

## API認証

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/e0c8317c-a6c3-3268-034d-9a8ad031cd6b.jpeg)


APIトークン機能はJWT認証でよく使われるAPIトークンをAuthorizationヘッダを介して受信、HTTPリクエストを認証する

## SPA認証

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/0abdb850-9ece-863d-2a02-2814e4067067.jpeg)


![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/ec0c5091-b363-aaa7-96cb-5d8eda150f9d.jpeg)

SPA認証機能はトークンの代わりにクッキーベースのセッション認証サービスを使用。
WEB認証ガードを利用して、CSRF保護、セッション認証の利点が提供できるだけでなく、XSSを介した認証資格情報の漏洩を保護する

## CSRF対策について

APIモードで実装するために、CSRFトークンは使えない。そんな時、どうする？
→APIトークンを使う

参考記事：
[Laravel 10.x Eloquent：APIリソース](https://readouble.com/laravel/10.x/ja/eloquent-resources.html)
[Laravel 10.x Laravel Sanctum](https://readouble.com/laravel/10.x/ja/sanctum.html)
 [Laravel 10.x CSRF保護](https://readouble.com/laravel/10.x/ja/csrf.html)
[【Laravel】SanctumでAPIトークン認証の使い方とSPA認証との比較](https://qiita.com/104dev/items/0787a81f7dda892ce86a)
[一番分かりやすい OAuth の説明](https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be)
[OAuth アプリケーションと API トークンの違い](https://docs.vmware.com/jp/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-1EEC504F-CFE5-4030-8DCB-1201CECF8B45.html#:~:text=%E3%81%93%E3%82%8C%E3%82%89%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E3%80%81API,%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82)
[HTTP 認証](https://developer.mozilla.org/ja/docs/Web/HTTP/Authentication)
Laravel 10.xで使えるデータベース選定〜メリット・デメリット〜

Laravel 10.xで使用できるデータベースは下記の通りです。
>MariaDB 10.10+
MySQL 5.7+
PostgreSQL 11.0+
SQLite 3.8.8+
SQL Server 2017+

余談ですがLaravel-dynamodbっていうライブラリを使えば、Amazon DynamoDBを使うこともできるみたいです。難しそう。
（参考記事：[Laravel-dynamodbで使ってdynamoDBに接続してみる](https://zenn.dev/goemon/articles/2a78c3e52d40c8)）

Laravelで使用できる各データベースのメリット・デメリットは次の通りです。
（自分の知識と力量も合わせてまとめてみました😎）

## MySQL

https://www.mysql.com/jp/

世界で最も多く使われているオープンソースRDBMS

《メリット》
個人的に使い慣れている（理解できている）
正直、これしか使ったことがない。初心者向け
①動作が早い
②オープンソース
③多くのOSで動作する
④多くのプログラミング言語が対応している
⑤無償および有償の２つの形態がある

《デメリット》
MySQLは古い
• PostgreSQLに比べて機能が劣る
• 無償版では機能やサポートに限界がある
• Amazon RDSに使用するには多少の料金が発生

## PostgreSQL

https://www.postgresql.org/

MySQLと同じオープンソースのRDBMS。
日本では人気あり（読み方はポストぐれすキューエル）

《メリット》
個人的に名前は聞いたことがある程度で未知の領域。
MySQLよりも多くの機能を提供するオブジェクトリレーショナルデータベース管理システム（ORDMBS）
他のSQLデータベースよりも優れたデータの完全性と信頼性を提供
オープンソースで無償。

《デメリット》
• MySQLに比べてドキュメント不足
• 速度面では難あり

## MariaDB
https://mariadb.org/

MySQLと同じオープンソースのRDBMS。MariaDBはMySQLの修正版

《メリット》
AWSにデフォルトで入っている
MySQLに比べてスケーラブルで、クエリも高速（大規模なデータを管理するのに適している）
シーケンスストレージエンジンや仮想列、1 つのテーブルで複数のエンジンの使用など、MySQLにはない機能がある。
MySQLは古い。MariaDBは新しい。

《デメリット》
ある程度の知識が必要

## SQLite

https://www.sqlite.org/index.html

開発者にとって非常に使いやすいデータベースエンジンのひとつ（読み方はエスキューライト）

《メリット》
小規模システムの開発向け
完全無料・圧倒的な通信速度・バックアップ一瞬
基本構造はMySQLと共通
簡単に導入できてセットアップが簡単、構成ファイルなどの設定も不要
Amazon RDSサーバレスで料金を気にせずに開発できる

《デメリット》
セキュリティ面（ユーザ権限がないので自由にアクセスできてしまう）
型のルールが甘い
ドキュメント少なめ

## Microsoft SQL Server

https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads

Microsoft社の商用RDBMS

《メリット》
企業で利用されることが多いデータベース管理システムの１つ
Windows OSとの相性がよく、Windows Serverで利用されることが多い

《デメリット》
データベースは有償で使用し、ライセンス契約を結ぶ必要あり

以上、Laravel 10.xで使用できるデータベースのメリット・デメリットでした。

参考記事：
[Laravel 10.x　データベース：準備](https://readouble.com/laravel/10.x/ja/database.html) 
[MariaDB と MySQL の違いはなんですか?](https://aws.amazon.com/jp/compare/the-difference-between-mariadb-vs-mysql/)
[MySQL と PostgreSQL の違いはなんですか?](https://aws.amazon.com/jp/compare/the-difference-between-mysql-vs-postgresql/)
[【必読】小規模なシステム開発にSQLiteを使うべき5つの理由](https://wp-labo.com/sqlite-small-system-development/)
[AWSで爆安サーバレスRDBを構築する (個人開発向け)](https://zenn.dev/nixieminton/articles/dc041d5bc8c09f)
[SQL Serverとは？知っておきたい3つの特徴・メリット](https://products.sint.co.jp/topsic/blog/sql-server)

参考書籍：
[基礎からのMySQL](https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AEMySQL-%E7%AC%AC3%E7%89%88-%E8%A5%BF%E6%B2%A2-%E5%A4%A2%E8%B7%AF-ebook/dp/B075SSK52H/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2PKYKIZBOGXB6&dib=eyJ2IjoiMSJ9.hq4ePSB4RNSvIwHZpSbir0lkp51mu5RlAEwC_e0tyawanxrlF5LfuFVVZD378SuO6zT322f3h3om0duO7EmglCeZ-RecWUgzepQgMjffInJpG4R0wNodyS-SVpOoGL7JrLKjsJplcY4ahEu9CHAbJpTQHYPUbQX1tPckPEuCHL1Z7hgPMxU4PfeenFViaIrUTVaIRsuSyA2fO6iPvcEeC5_L_JGio9YAs18ehArE_ZI.u3OSpj6uSFu96ozJx_XJMGjbgL5pDb4OeBg2B7y8WeA&dib_tag=se&keywords=%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AEMySQL&qid=1705370879&sprefix=%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AEmysql%2Caps%2C169&sr=8-1)
【Flutter】Gridviewを使ってみる

こんにちは。
今回は、GridViewの使用方法を紹介します。

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)

itemCountでアイテム数を指定して、itemBuilderでは、表示するウィジェットを返します。
SliverGridDelegateWithFixedCrossAxisCountは固定列数で表示することができます。
crossAxisCountで列数を指定できます。
mainAxisSpacingとcrossAxisSpacingでグリッド間のスペースのサイズを指定することができます。
childAspectRatioでグリッドの高さを指定しています。


# 使用例
```dart

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> numberList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: GridView.builder(
          itemCount: numberList.length,
          itemBuilder: (context, index) {
            return Container(
              color: Colors.pink,
              child: Center(child: Text(numberList[index])),
            );
          },
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            mainAxisSpacing: 5,
            crossAxisSpacing: 5,
            childAspectRatio: 2.0,
          ),
        ));
  }
}


```

# 実行例
![スクリーンショット 2024-02-07 18.41.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/a47e79ed-769f-aee0-0f58-7737f3c981d1.png)


# 最後に
ここまで読んでいただき、ありがとうございました！
いいねしてくれたら、スキップして喜びます:heartpulse:
ESP-WROOM-02 DIP化キットを使って気象センサーを作る

　今回紹介するESP-WROOM-02 DIP化キットを使った気象センサーは、下記システムの右側の上下モジュールです。

![EspSensorModule_RaspiMonitorSystemOverview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/79d6e46d-15e0-7fcd-84f7-b0d64588f798.jpeg)

### 気象センサーモジュールの仕様

+ IoTデバイス: ESP-WROOM-02
    ※ ESP-WROOM-32も選択肢として有りましたが、Bluetoothは不要、下記のように組み込んで使うのでピンも最低限あればよく、かつ廉価であるのでこちらを採用。
+ 搭載センサー
    + BME280 センサー: 室内設置(気温・湿度・気圧)
    + サーミスタ: 室外設置 (外気温測定) ※分圧抵抗 10KΩ
+ MCP3002: ADコンバータ 10bit 2ch  
サーミスタの出力電圧測定用
※ESP8266のADC出力を1V未満に分圧する抵抗に近いものがなかったのでMCP3002を採用
+ 電源モジュール: ニッケル水素電池 (1.2v) x 4本 = 4.8v

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/8df3d69b-3728-1b03-83d8-27cd0dfb3e6a.jpeg">


### ESP-WROOM-02 DIP化キットを使ったIoT工作の書籍

+ 超特急Web接続! ESPマイコン・プログラム全集 [ CQ出版社 ]
ISBN978-4-7898-4704-9 ( 2019年4月1日　第2版発行)
    + 第１章 1 ESPスタータ・キット×ブレッドボードで作るＩｏＴ実験ポード
    ブレッドボードを使って実験用ボードを制作する
    + Appendix 2 いつまでも動く無人ＩｏＴを作る！ ESPマイコンのケチケチ運転術
    スタンバイ電流の小さい電源ICで間欠運転！ 6か月連続動作

![CQPub_ESP8260.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/4d6251ca-4896-4a93-4f1d-3f45a2b839e3.jpeg)

　**書籍で紹介しているレギュレータが入手できなくなっているので、著者のサポートページから上記①-BのPDFをダウンロードしました。
　最新のプログラムもGitHubで公開しているので、書籍自体は古くなっていますが解説も図入りでわかりやすいので持っていても損はないと思います。**

### 1. ESP-WROOM-02 書き込み用開発ボードの制作

#### 1-1. ブレッドボード上に組み立て

　PDF文書 ①-Bを元にブレッドボード上にESP-WROOM-02モジュールの書き込み用回路を組み立てし、書籍のサンプルをビルドしてWi-Fi接続の確認を行います。

<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/ca9bf6ef-14fb-4cf1-9fe6-40be8430d242.jpeg">

#### 1-2. 開発ボードをユニバーサル基板にハンダ付けする

　ブレッドボードで組んだ回路では、書き込み作業中に部品・配線が外れてしまい途中で書き込みに失敗することがあります。 プログラムの書き換えも頻繁にあるので下記のようにユニバーサル基板に回路をハンダ付けしました。

　さらに3.3Vの出力電源、I2Cポート、SPIポートをボードの下左端にまとめると実験作業の使い勝手が向上します。


![EspWroom02_1_DevBoard-A_085.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/1e3b7698-5c53-8c58-60ce-337e3ceaa0ce.jpeg)

### 2. ESP気象センサーモジュールの制作

#### 2.1 ケチケチ運転術・基本ボード (B) の製作

　ブレッドボード上にテスト用のWi-Fi通信機能プログラムの書き込みが終わったESP-WROOM-02 DIP化キットと安定化電源を配置し、 乾電池を繫いでWi-Fi通信機能が正しく動作するか確認します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/503447b0-8047-75cf-deec-6d76642f1fa2.jpeg">

#### 2.2 気象センサーモジュールの組み立て

　上記の 2-1 に加えセンサーモジュールの部品を配置し、実際にセンサーから取得したデータがWi-Fi経由でUDPパケットとして発信することを確認します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/7d1da75a-8f6f-9475-c22b-77624f394e4f.jpeg">

電池モジュールと気象センサーモジュールの配線

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/5fe1cbb3-4097-0cb8-3ce7-3b9f835ca4d8.jpeg">

全てのモジュールをケースに格納して気象センサーが完成

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/8df3d69b-3728-1b03-83d8-27cd0dfb3e6a.jpeg">


### 結論

　いつまでもブレッドボード上でしか実験できないようでは初心者から抜け出せません。**ちゃんとしたIoTシステムを構築するにはユニバーサル基板へのハンダ付けは避けて通れません。今回紹介した書籍のESPモジュールを使った回路は比較的容易に作ることができるものが多いのでハンダ付けはマスターしたほうが良いと思います。モジュールが完成したときの喜びはひとしおです。**

　次回は、今回作成した気象センサーモジュールで測定した気象データをUDPパケットで内部ネットワークにブロードキャストするプログラムを紹介する予定です。
【Flutter】SafeAreaでアプリのUIを改善する基本

## SafeAreaとは
SafeAreaは、アプリのコンテンツがデバイスの特定の領域によって隠れないようにするために使用されます。

これらの特定の領域には、デバイスのノッチ（画面上部の切り欠き部分）、ステータスバー（時刻やバッテリー残量が表示される上部のバー）、ホームインジケーター（画面下部の操作バー）などが含まれます。

SafeAreaウィジェットを使用することで、これらのシステムUIの周りに適切な余白を確保することができます。

https://api.flutter.dev/flutter/widgets/SafeArea-class.html

## 基本的な使い方
基本的には以下のようにすることで、SafeAreaは自動的にデバイスのシステムUI（ノッチ、ステータスバー、ホームインジケーターなど）を考慮した余白をコンテンツに適用できます。

```dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return const Center(
              child: Text('SafeArea'),
            );
          },
        ),
      ),
    );
  }
}
```

<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/7973e447-1e73-e207-6a81-2ea8fa592317.png">


## SafeAreaのカスタマイズ
### (1) top, bottom, left, right
これらのプロパティを使用して、特定の方向の余白を制御できます。
例えば、`bottom: false`と設定すると、下部部の余白が適用されず、コンテンツがホームインジケーターの直下まで伸びるようになります。

```diff_dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
+       bottom: false,
        child: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return const Center(
              child: Text('SafeArea'),
            );
          },
        ),
      ),
    );
  }
}
```

<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/b3f42b18-7aec-104f-246e-314a2a989c46.png">

### (2) minimum
minimumプロパティを使用すると、SafeAreaの最小の余白を指定できます。これは、デフォルトの余白よりも大きな余白を設定したい場合に便利です。
例えば、`minimum: const EdgeInsets.all(100)`と設定すると、すべての方向に最低100ピクセルの余白が確保されます。

```diff_dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
+       minimum: const EdgeInsets.all(100),
        child: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return const Center(
              child: Text('SafeArea'),
            );
          },
        ),
      ),
    );
  }
}
```

<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/ec25cbb6-b794-2bae-11e8-5f14c37b9f04.png">


### (3) maintainBottomViewPadding

maintainBottomViewPaddingプロパティは、キーボード表示時やデバイスの向きが変わった際などに、ボトムパディング（下部の余白）を維持するかどうかを制御します。

これについては使い道があれば本記事を更新します。。。
【Reactアプリ100本ノック】11 Quizz

![quizz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f6dff724-f928-3062-b96b-9eb81e51a781.png)
# はじめに

<h3>こんにちは！！ Watanabe Jin (@Sicut_study)です！</h3>

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

こちらの記事が嬉しいことに多くの方に見ていただきました。
そこで**React**が多くの初心者の方に注目されているんだなということを実感させられました。

私の記事では何度も言っている通り

<font color="red"><h4>最速で学ぶならとにかく何か作る</h4></font>

というのが大事になってきます。そこで **「Reactアプリ100本ノック」** というのに挑戦していこうかと思います。徐々に難易度を挙げていってどこまでお題を作りきれるかの腕試しでやっていただければと思います。

今回は実用的な楽しいアプリを作っていきます

# 前回のお題

https://qiita.com/Sicut_study/items/3bfdce97ca51b609eb02

# Reactアプリ100本ノックルール

- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する
- 要件をみたせばデザインなどは自由

# 11. Quizz

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/912f8d31-f542-2144-0b55-05241e88326e.png)


## 問題

早押しクイズアプリを作成します

## 目的

早押しクイズなので時間制限が必要になります。
カウンターで行ったカウントダウンを応用して実用的なアプリをつくります

## 達成条件

- クイズ問題が表示されている
- 10秒のカウントダウンがある
- 解答フォームがある
- 解答ボタンがある
- 解答ボタンを押したら答えが正解か不正解かを表示
- 解答ボタンを押したら解答時間と答えを表示
- 解答の表記ゆれ(例えばAが答えなら「えー」「a」も正解とする)


## 実際に解いてみた

![Peek 2023-12-04 15-27.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/9d472a5a-c238-56b6-8cdc-857fca7f7882.gif)


### 利用技術

- React
- TypeScript
- Vite
- Tailwind
- React Icon


解答時間 : 1時間

楽しく遊べるアプリを意識してUIをChatGPTを使って作りました
クイズは裏側で固定の問題を1問設定しており、表記ゆれにも簡単に対応しています

ここから応用するならクイズAPIを利用するのも良さそうです

https://poropi.dev/admin/index.php

また、手のマークはReactIconを用いて作っています。

# 次のお題

Comig Soon...

# おわりに

React100本ノックの記事を地道に上げていこうと思いますので、一緒に挑戦したい方は @Sicut_study をフォローいただけるととてもうれしく思います。
ここまで読んでいただけた方はぜひ**いいね**と**ストック**よろしくお願いします。

今週もプログラミング頑張りましょう！

![jisou-banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/217ea52d-8130-3266-0619-990fa968408a.png)

# おすすめ記事

https://qiita.com/Sicut_study/items/6bcdcdf8248eeffcc5ca

# About Me

Webエンジニア転身して1年間本気で勉強
転職ドラフトで高額オファーを複数獲得
そこでの経験からアウトプットやマインドセットの発信に強みがある
エンジニアをやりながら、起業に挑戦中
アイデア作りやパブリックスピーキングを得意としてる

■ Twitter
https://twitter.com/Sicut_study
■ Instagram
https://www.instagram.com/himariajin
■ Youtube
https://www.youtube.com/channel/UCBFrGAJhPuuaoLwUIHBILsA
■ TikTok
https://www.tiktok.com/@sicut_study
■ プログラミングコーチングJISOU
https://projisou.jp
■ 体験で学ぶ！JISOU
https://experience-learn.connpass.com/
■ 登壇依頼などご依頼はこちらから
himaria.jin.watanabe@gmail.com


# 参考

https://poropi.dev/admin/index.php

https://react-icons.github.io/react-icons/search/#q=hand
チャンネルの重要度を計算するCNN【SENet】



**原論文**
Squeeze-and-Excitation Networks
https://arxiv.org/pdf/1709.01507.pdf


# 結論
CNNにチャンネルの重要度をつける．その重要度は，画像によって異なる，動的なパラメータを使用する．


# 概要
画像認識モデルにCNNモデルがあるが，CNNモデルは入力画像が変化しても同じ値の重みを使用したカーネルを使用して計算する（静的なパラメータ）．これは，入力画像に対して，柔軟に適応できない状態である．



例えば，ある画像では，色が重要であったり，形状，テクスチャなど重要な要素が異なる．そのため，その入力画像にあった重みが大切である．入力画像によって異なる重みを持つことが動的なパラメータである．この動的なパラメータをCNNに付与する．




# モデル構造
SENetは，特徴量のチャンネルの重要度を決定する役割を持つ（色は重要度）．
チャンネルの重要度は，空間情報にGlobal Average Pooling（GAP）（$H \times W$の平均値）をすることで($H \times W \times C$)の特徴量を($1 \times 1 \times C$)に圧縮する．


圧縮後にF（ちょっとした計算）をしてチャンネルの重要度を決定する．各チャンネルの重要度を入力特徴量にかけて，入力特徴量のチャンネルの重要度を決定する．（上ルートの茶色の値が0の場合，そのチャンネルは重要でないので，入力特徴量の茶色の値は0になる．）




![スクリーンショット 2024-02-07 10.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/fc781e16-2453-f130-6458-3395a83717e6.png)


## F()の中身
以下の図2の右の図の右ルートがF()の構造であり，最初にGAP（Global pooling）し，FC層，，，，，sigmoidで右ルートの値を0~1に変換して，その値を入力特徴量の各チャンネルの重要度として計算している．つまり，F()は2層のFC層の後にsigmoidで0~1に値を変換している．



図2と図3は，論文で提案されているモデル構造例で，図２はSENet．図3は，SE-ResNetであり，ResNetのスキップ接続を付与している．この2つのモデルは，よく使用される．

![スクリーンショット 2024-02-07 10.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/7580988e-71c7-65bd-a435-3f5199552294.png)








# 実験
他にも色々なブロックの形状を試してみたよ．

![スクリーンショット 2024-02-07 10.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/e3624427-fc14-d6a4-8f53-d7a4de718b01.png)

結局シンプルな方がいいのかも．わかりやすいし．




# まとめ
今回は，チャンネルの重要度を計算するCNN【SENet】について解説した．CNNの構造に動的なパラメータを持つ機能を付けることで，入力画像に異なる柔軟な重みつけが可能になる．その機能を使用して，各チャンネルの重要度を求める．
Playwright始め方 インストール編

本記事はPlaywrightを始めるための備忘録的に書いたものです。記載内容はPlaywright本家のIntroductionのこちらのページ

https://playwright.dev/docs/intro

を簡単に日本語で書いたものになります。(2024/02/07時点)

# 事前準備

Nodejsのインストール。[volta](https://docs.volta.sh/guide/getting-started)などをインストールしてバージョン管理するのがおすすめです。（注：これは筆者の個人的意見）

System Requirementsは以下の通りです。

>Node.js 16+
Windows 10+, Windows Server 2016+ or Windows Subsystem for Linux (WSL).
MacOS 12 Monterey, MacOS 13 Ventura, or MacOS 14 Sonoma.
Debian 11, Debian 12, Ubuntu 20.04 or Ubuntu 22.04, with x86-64 or arm64 architecture.


# Playwrightのインストール

https://playwright.dev/docs/intro

のガイドに従ってinstallします。まずは下記コマンド。

```bash
npm init playwright@latest
```

- TypescriptかJavaScriptの選択
- テストフォルダの名前
- Github Action workflowを追加するか
- Playwrigh tbrowserをインストールするか

```
Choose between TypeScript or JavaScript (default is TypeScript)
Name of your Tests folder (default is tests or e2e if you already have a tests folder in your project)
Add a GitHub Actions workflow to easily run tests on CI
Install Playwright browsers (default is true)
```

を聞かれるのでそれに答えます。すると以下のファイルがインストールされます。

```
playwright.config.ts
package.json
package-lock.json
tests/
  example.spec.ts
tests-examples/
  demo-todo-app.spec.ts
```
# サンプルテストの実行

プロジェクトが作られるとサンプルコードが入っているのでそれを実行してみます。

> By default tests will be run on all 3 browsers, chromium, firefox and webkit using 3 workers. This can be configured in the playwright.config file. Tests are run in headless mode meaning no browser will open up when running the tests. Results of the tests and test logs will be shown in the terminal.

デフォルトでは3つのワーカーを使ってchromium, firefoxさらにwebkitの3つのブラウザの上でテストが走り、それは`playwright.config`ファイルで設定されているようです。で、実行してもブラウザが出たりしないheadlessモードで結果はターミナルに表示される。とのことです。

```bash
npx playwright test
```

## UI付きで実行したい場合

```bash
npx playwright test --ui
```

# Test Reportの表示

>After your test completes, an HTML Reporter will be generated, which shows you a full report of your tests allowing you to filter the report by browsers, passed tests, failed tests, skipped tests and flaky tests. You can click on each test and explore the test's errors as well as each step of the test. By default, the HTML report is opened automatically if some of the tests failed.

テストを実行するとHTML Reporterが作成されます。Reportでは全結果を見たり成功したテストや失敗したものをフィルタリングしたり、とにかく結果について見られますということですね。テストが失敗した場合、このレポートは勝手に開かれるようです。

```bash
npx playwright show-report
```

# Playwrightのバージョンアップ

```bash
npm install -D @playwright/test@latest
```

## 現在のバージョンの確認
```bash
npx playwright --version
```
OpsRamp Traces 試してみた

OpsRamp Traces (Beta) がリリースされたので、試してみました。

::: note warn
執筆時点では、Beta版
:::

# 概要
OpsRamp Tracesでは、OpenTelemetryのTrace情報を取り込み、可視化することが可能です。

# 構成
アプリケーションからOpsRamp社が提供しているTrace CollectorにTrace情報を送信し、Trace CollectorがOpsRamp SaaSにその情報を転送します。
![traces-architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/e42b9624-205b-7587-5c16-4f36863c312b.png)

Trace Collectorは、Agentおよびk8s PODで提供されています。
また、OpsRamp Gateway上で起動することも可能です。

# やってみた
OpenTelemetryのNodeJSの[Getting Started](https://opentelemetry.io/docs/languages/js/getting-started/nodejs/)で試してみました。
Getting Startedでは、Trace情報はコンソール出力されるため、Trace Collectorに送信するようにinstrumentation.tsを編集します。
Trace情報を送信するためには、[opentelemetry/exporter-trace-otlp-proto](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-proto)モジュールを使用します。
``` js: instrumentation.ts
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'http://<Trace Collector IP>:8082/v1/traces',
    headers: {},
  }),

  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
```

OpsRamp SaaS上では、以下のように見えます。(Infrastructure > Tracesから参照します。)
取り込んだTrace情報の一覧を参照することができます。
![trace_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/83263a79-a79f-941c-9d8e-1cf36789dbfd.png)

TraceおよびSpan情報を確認することが可能です。
![trace_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/ea8e38e5-63a5-6746-3a48-48dd246f20c6.png)

---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
C#.NETで配列の一番最後の要素を消す

# やり方

* ```Array.Resize()```
* Linqの ```Take()```

の2つのやり方があります。

```C#:サンプルコード
using System;
using System.Linq;

namespace Sampleple
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] hai_ = new string[4] {"たきな", "ちさと", "その他", "ほげえええ"};

            //最初の状態
            Console.WriteLine(string.Join(",", hai_));

            //やり方その1
            Array.Resize(ref hai_, hai_.Length - 1);
            Console.WriteLine(string.Join(",", hai_));

            //やり方その2
            hai_ = hai_.Take(hai_.Length - 1).ToArray();
            Console.WriteLine(string.Join(",", hai_));

            Console.ReadLine();
        }
    }
}
```

実行結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ba09f730-7882-8132-7b1a-b1b30bf9d9e5.png)

# コメント参照

より深い内容まで検討して頂いたコメントがあります。
この記事のコメントも参照下さい。

# 蛇足

Linqには最後の要素を取得する ```Last()``` があるし、参照渡しはあんまりやりたくないから ```Take()``` がおススメかな。

# 参考サイトさん

https://rksoftware.hatenablog.com/entry/2017/10/06/025921

# バージョン

Microsoft .NET Framework Version 4.8.09037
MinecraftのaccesstransformerのInfo

# はじめに
やぁやぁこんにちは。Never3924です。
今回はAccessTransformerについて。
これ日本語情報がほぼなくて困ってた。
1.20.4になるとなおさら...

[追記]
Googleで検索すると私の記事がトップに出るくらいには情報不足です。

# 本題
## AccessTransformerの場所
場所について解説。
```
META-INF
    ┗accesstransformer.cfg
```
ここに配置。
あと、build.gradleのminecraft -> accessTransformerオプションを~~コメントアウト~~ [アンコメント]()。
ない場合はここにコードを貼っておくからコピペ。
`accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')`

## 中身
### テンプレ
テンプレート。
```
<置き換えたいアクセス修飾子> <クラスパス> <番号>
```
[アクセス修飾子](https://www.tohoho-web.com/java/modifier.htm)は
public
protected
default
private
とか。

例えばEntityクラスのPortalTimeをpublicにしたいなら、
```config
public net.minecraft.world.entity.Entity f_19819_
```

このfield番号、なかなか曲者で。
わけがわからないの。
IntelliJのプラグイン入れたら(Minecraft resourceかMinecraft developmentかどっちかだと思う)
メソッド名で補完出るからそれで入力してね。
あとはgradleのリビルドすれば反映されるよ。

# 終わり
まぁこんなところで。
Modderの皆さんの助けになれば幸いです。
そんじゃまたー。
【Unity】Photon Fusion2で Failed to weave property * のエラーが発生する

# はじめに
Fusion2のNetworkArrayを使おうとした際に `Failed to weave property *` のエラーが発生したため、原因を調べてみました。

# エラー解消方法

プロパティに `setter` を入れるとこのエラーが発生するようです。

```c#
// 修正前
[Networked,Capacity(3)]
public NetworkArray<int> NetworkArray  { get; set; }

// 修正前
[Networked,Capacity(3)]
public NetworkArray<int> NetworkArray  { get; }
```
C#.NETで配列の一番最後の要素を取得する時はLinqのLast()を使うと便利

# やり方

```C#:サンプルコード
using System;
using System.Linq;

namespace Sampleple
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] hai_ = new string[3] {"たきな", "ちさと", "その他"};

            //System.Linqを使うと『要素数を取得して…』みたいなことせずにLast()だけで取得できるので便利。
            Console.Write(hai_.Last());
            
            Console.ReadLine();
        }
    }
}
```

実行結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/87074fca-b221-3a8a-3cc5-81f005970ea0.png)

# .NET 8.0以上ならインデックス演算子

下記は.NET Framework4.8での画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d52d76ce-dad2-5090-106b-9741748e0b33.png)

.NET 8.0以上ならもっと便利な『インデックス演算子』というものが使えるようです。

# 蛇足

やり方がすぐ思いつくロジックであっても『改めてググってみる』とか『ChatGPT君に聞いてみる』とかやると良いです。
自分が知らなかった『もっと便利なやり方』が見つかるかもです。

# 参考サイトさん

https://www.choge-blog.com/programming/carraygetlastelement/

# バージョン

Microsoft .NET Framework Version 4.8.09037
Salesforce Apex なんもわからんけど触ってみたいって人向け

## Salesforce Apex の始めかた


:::note info
Salesforce Apexは [クイックスタート](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_qs_HelloWorld.htm) を見れば`Hello World`できる。

:::

:::note warn
必ずどうなってもいいSandboxで作業すること！
:::

### まずはApexクラスを作成する
1. 設定のホーム画面で検索窓に「Apex」を入力して「**Apex クラス**」を選択
2. 「**新規**」をクリック
3. 以下のコードをエディターにコピペ
4. 「**Save**」をクリックして保存

`どうなってもいいリードの項目名` について、`FirstName`を使ってみる。
```java:MyHelloWorld
public class MyHelloWorld {
   public static void ChangeNameToHelloWorld(Lead[] LeadList) {
      for (Lead l :LeadList){
         l.どうなってもいいリードの項目名 = 'Hello World!';
      }
   }
}
```
&nbsp;
&nbsp;


### 次にトリガーを用意
1. 設定 > オブジェクトマネージャー > リード を開く
2. 左の「**トリガー**」を選択し「**新規**」をクリック
3. 以下のコードをエディターにコピペ（元のコードは削除）
4. 「**Save**」をクリックして保存

今回は`Lead (before update)` によって、リードレコード更新時に起動させる。
[トリガーはこの記事がとても分かりやすい：トリガ基礎](https://qiita.com/chanhly/items/e6db5814db9b0906a9bd)
```java:HelloWorldTrigger
trigger HelloWorldTrigger on Lead (before update) {

    Lead[] updateLeadList = Trigger.new;
    MyHelloWorld.ChangeNameToHelloWorld(updateLeadList );
    
}
```
&nbsp;
&nbsp;


### どうなってもいいリードレコードを更新してみる
- 名前に「**Hello World!**」が代入されていればOK
- なんか間違っている場合は保存するときにエラーが出る
- 保存できたけど名前が書き換わっていない場合、トリガーかクラスが機能していない

&nbsp;
&nbsp;


### テストクラスを用意する
:::note info
作ったApexクラスとトリガーをSandbox環境への影響なく、テストランできるのがテストクラス、<font color="red">**なのでリードレコードを更新する前に本来はやるべき**</font>
:::
1. 「**Apex クラス**」から「**新規**」をクリック（2回目）
2. 以下のコードをエディターにコピペ
3. 「**Save**」をクリックして保存

テストクラスの頭に`@IsTest` 付けてねって開発者ガイドで言われてます。

```java:HelloWorldTestClass
@IsTest 
private class HelloWorldTestClass {
    @IsTest
    static void validateHelloWorld() {

       // ここに新規レコード作成やレコード更新処理を書く（力尽きた）
       
    }    
}
```
【ST言語ことはじめ】タイマーを利用したランプの点灯制御

## はじめに

この記事では、タイマーの利用例について解説します。タイマーはPLCプログラミングにおいて非常に重要な機能であり、様々な制御処理に活用されます。

## 使用機材

|   |機種など   |
|:---:|------|
|PLC  |Q02CPU, QX41, QY41P, Q62P, Q38B    |
|アプリ  |GX Works 2    |

I/O割り付けは[こちら](https://qiita.com/so2/items/0f0cab2e324179718b89 "I/O割り付け表")を参照してください。

## タイマーの利用例

このサンプルプログラムでは、ボタン1が押されるとタイマーのカウントがスタートします。3秒後にタイマーの接点を利用してランプ１が点灯します。ボタン２でタイマーをリセットしています。

### サンプルプログラム:ラダー図

```batch:ラダー図
(+)                                               (-)
|    X1    X2                               M1      |
+----|↑|---|/|----------------------------(    )----+
|                                                   |
|    M1                                   T1 K30    |
+----| |----------------------------------(    )----+
|                                                   |
|    T1                                    Y71      |
+----| |----------------------------------(    )----+
|                                                   |
```

### サンプルプログラム：ST言語

ラダー図と同じ挙動に加えて、DPLに秒数を表示する回路を追加しています。

```st
IF X1 THEN
    M1 := TRUE;
END_IF;

IF X2 THEN
    M1 := FALSE;
    RST(TRUE, T1); (* 省略可能 *)
END_IF;

OUT_T(M1, TC1, 30); (* 3秒タイマー *)

Y71 := TS1;
K4Y40 := TN1; (* DPLに秒数を表示 *)
```

:::note info
OUT_T
以下の命令も同様の挙動となる
TIMER_M(M1, TC1, 30); 
:::

### まとめ

本記事では、タイマーの利用例について解説しました。タイマーはPLCプログラミングにおいて非常に重要な機能であり、様々な制御処理に活用されます。是非、実際のプロジェクトでタイマーを活用して効率的な制御を行ってみてください。
【ST言語ことはじめ】タイマーとカウンタの挙動について

### はじめに

この記事では、カウンターとタイマーの挙動の違いについて解説します。カウンターとタイマーは、PLC（プログラマブルロジックコントローラ）において重要な機能であり、その挙動の理解は制御システムの開発において不可欠です。

## 使用機材

|   |機種など   |
|:---:|------|
|PLC  |Q02CPU, QX41, QY41P, Q62P, Q38B    |
|アプリ  |GX Works 2    |

I/O割り付けは\[こちら\](https://qiita.com/so2/items/0f0cab2e324179718b89 "I/O割り付け表")を参照してください。

## サンプルコード

```st
(* カウンタはトリガーをFALSEにしてもカウンタがリセットされない *)
(* 入力信号が自動的にパルス処理されているようにみえて、じつは2スキャン以上ひろっている、、、っぽい *)
(* M0 := X1; とすると、カウントアップは一度だが、二行目のOUT_C(M0 AND CS1, のときにM0がTRUE判定されてしまう *)

PLS(X1, M0);

OUT_C(M0 AND CS2, CC3, 1);
OUT_C(M0 AND CS1, CC2, 2);
OUT_C(M0, CC1, 3);

IF CS3 OR X2 THEN       (* リセット方法3種 *)
    RST(TRUE, C1);      (* 条件によらず強制的にリセット。 *)
    RST(CS3 OR X2, C2); (* C3の状態によりリセット。おそらく王道。IF文の外に置いても機能する書き方 *)
    CN3 := 0; C3 := 0;  (*カウントは0になるがCS3がONのままになりカウントアップが機能しなくなる。 正:RST(CS3, C3); *)
END_IF;

K1Y40 := CN1; (* DPLにカウントを表示 *)
K1Y44 := CN2;
K1Y48 := CN3;

(* タイマーはトリガーをFALSEにするとカウントもリセットされる *)
(* 入力信号がパルス処理されない *)
(* タイマーのカウントを続けるためには自己保持などで条件を満たし続ける必要がある *)

IF X3 THEN
    M1 := TRUE;
END_IF;

IF X2 THEN
    M1 := FALSE;
END_IF;

OUT_T(X3, TC1, 50);
OUT_T(M1, TC2, 100);

K2Y50 := TN1; (* DPLに秒数を表示 *)
K2Y58 := TN2;
```

### カウンターの挙動

サンプルコードのカウンター部分では、カウンターの動作を確認できます。カウンターはトリガーがFALSEでもカウンターがリセットされず、入力信号が自動的にパルス処理されるように見えますが、実際には2スキャン以上で検出されている可能性があります。

### タイマーの挙動

一方、タイマーの部分では、タイマーはトリガーがFALSEになるとカウントもリセットされます。入力信号はパルス処理されませんが、タイマーのカウントを続けるためには自己保持などで条件を満たし続ける必要があります。

## まとめ

カウンターとタイマーは、PLCにおける重要な機能であり、それぞれ異なる挙動を示します。カウンターはトリガーがFALSEでもリセットされず、入力信号がパルス処理される可能性がありますが、タイマーはトリガーがFALSEになるとカウントがリセットされます。制御システムの開発において、これらの挙動を正しく理解することが重要です。
パブリックDNSとプロバイダDNSの応答速度を比較してみた

# はじめに
たいろーさんのvoicyラジオの中で「パブリックDNSを使うとネットが早くなるよ」という話があり、気になったので調べてみました。
https://voicy.jp/embed/channel/1232/704106

## そもそもDNSとは
DNS（Domain Name System）とは、IPアドレスとドメイン名を紐づけし、IPネットワーク上で管理するシステムです。

IPアドレス(例：17.253.144.10)とはコンピューターやネットワークを識別するためのものであり、それを文字で名づけたものをドメイン(例：apple.com)と呼んでいます。

![スクリーンショット 2024-02-07 17.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/2b23e843-71cc-9777-3abd-8c9b1403dc22.png)

### 発生しうる問題
表示しようとしているサイトのサーバーだけでなくDNSサーバーがダウンしていると通信できないということも発生します。
そしてプロバイダのDNSサーバーとの通信に時間がかかるとサイトの表示や通信が遅く感じるということもあります。

そこで**パブリックDNS**の登場というわけです。

## パブリックDNSとは
パブリックDNSとはインターネット上で誰でも自由に利用できるDNSサーバーのことです。
有名なのはGoogle Public DNSで応答速度が非常に速く、セキュリティ性も高いと知られています。

Google Public DNSの公式ページに記載されていますが、
IPv4とIPv6両方のDNSサーバを提供しています。

IPv4
8.8.8.8
8.8.4.4

IPv6
2001:4860:4860::8888
2001:4860:4860::8844

## パブリックDNSとプロバイダDNSの応答速度を比較してみる
digというコマンドを使って調べてみます。

digコマンドとは、domain information groperの略で、直訳すると「ドメイン情報の手探りツール」です。

dig コマンドを使用して特定のDNSサーバーに対するクエリの応答時間を測定する場合、OSのシステム設定でDNSサーバーを変更する必要はなくクエリを送信するDNSサーバーをコマンドライン上で直接指定できます。

### Google Public DNSの応答速度
```
$ dig @8.8.8.8 www.google.com
```

| 回数 | Query Time (msec) |
|---------|-------------------|
| 1       | 5 msec                |
| 2       | 5 msec                |
| 3       | 6 msec                |
| 4       | 12 msec                |
| 5       | 5 msec                 |

### プロバイダのDNSの応答速度
```
$ dig @x.x.x.x www.google.com
```
| 回数 | Query Time (msec) |
|---------|-------------------|
| 1       | 5 msec                |
| 2       | 5 msec                |
| 3       | 5 msec                |
| 4       | 4 msec                |
| 5       | 22 msec                 |

Macの場合はシステム設定のDNSサーバーにて設定している情報を確認できます。
![スクリーンショット 2024-02-07 9.28.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/4366d907-e4f9-357a-3234-dbbe85a0d2d1.png)


## 結論
~~体感できるほどの差はなかった！~~　←はキャッシュされているIPの可能性が高くそもそも比較方法も怪しいです。
調査したいDNSサーバーに各IPアドレスがキャッシュされているかの確認方法も分からないためそもそも比較は難しいとの結論です。勉強します。


## ならどこで使う？
フリーWifi等パブリックなWifiやネット環境の場合に速度やセキュリティの観点から使うのはいいかもしれません！
ただしパブリックDNSにもセキュリティが完全ではないので使用の際はご注意ください。
もちろんプロバイダ次第ではDNSサーバーの性能が違うのでまずは確かめてみるのも良いと思います。

参照：
https://traffics.jp/blog/dns-structure/

### 最後に
弊社では、経験の有無を問わず採用を行っています。
興味のある方は是非カジュアル面談しましょう！

https://jambo-support.com/recruit_engineer/
Debian 12: Ruby on Rails を使う

## 必要なソフトのインストール

```bash
sudo apt install ruby
sudo apt install ruby-dev
sudo apt install sqlite3
sudo apt install make
sudo apt install gcc
sudo apt install zlib1g-dev
sudo apt install git
```

```bash
sudo apt install libsqlite3-dev libssl-dev libreadline-dev libyaml-dev
```

## Ruby のバージョン

```text
$ ruby --version
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]
```

## Rails のインストール

```bash
sudo gem install rails
```

Rails のバージョン

```text
$ rails --version
Rails 7.1.3
```

## 動作確認

プロジェクトの作成

```bash
rails new railsapp
```

サーバーの起動

```bash
cd railsapp
rails s -b 0.0.0.0
```

```text
$ rails s -b 0.0.0.0
=> Booting Puma
=> Rails 7.1.3 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.1.2-p20) ("The Eagle of Durango")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 6610
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
```

ブラウザーで　http://IPアドレス:3000 にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/fafe6151-9a00-3a46-0d83-a8c1a053ed6c.png)

## bundle install を使えるようにする

```bash
sudo gem install bundler
sudo gem install bundle
sudo gem install minitest
sudo gem install irb
sudo gem install turbo-rails
```
Kubernetesの単体障害テストどうしようか悩んだ話

# Kubernetesの単体障害
Kubernetesの単体障害テストケースを書くことがあるのですが、Kubernetesを理解できていない方もおり、物理サーバーの障害のノリで言われることもしばしば。
定石をカスタムして選んでもらえれば、お互いハッピー（~~責任を押し付けられる~~）なので自分なりのパターンをまとめてみる。

# 前提
OKE環境前提で考えていますが、VMWareやほかのクラウドにも応用は効くと思います。
単体障害と一口に言っても、考え方が色々あると思うので、入り口の参考程度に。


# Podの単体障害を発生させるには
## 強制削除
```
kubectl delete pods <pod> --grace-period=0 --force
```

メリット：自動で復旧する。
デメリット：複数Podになると面倒（複数Podが落ちる場合は単体障害とは呼ばない気はするが）

## スケールする
```
kubectl scale deployment --replicas=0 <deployment>
```

メリット：同じコマンドで復旧できるので、復旧が楽。
デメリット：Podの正常終了を障害と呼ぶのか？

## 負荷をかける
外部からリクエストを大量に投げてPodをハングさせる。
※requestリソースが設定されていないとノードが落ちるので注意

メリット：障害として考えられるトリガー。
デメリット：そもそもリクエストを受け付けるPodしかできない。負荷をかける準備が面倒。

## サイドカーコンテナのみの単体障害
おそらく、厳しい。
Pod単位までしか無理。

# ノードの単体障害を発生させるには

## インスタンス終了
つまり電源を切ってしまう。一番確実。

メリット：楽。クラウドならインスタンスを再作成ですぐに復旧。
デメリット：特に思いつかない。

## ファイアウォール等を変更
つまりネットワークの疎通をできなくしてしまう。

メリット：NW障害として考えられるシナリオ。
デメリット：NW周りの設計把握が必要。事故りそう。

## 負荷をかける
外部からリクエストを大量に投げてPodをハングさせる。
もしくは、高負荷なPodをデプロイする。
※requestリソースの設定は意図的にノードが壊れるようにする。

メリット：（リソース設計が甘いと）障害として考えられるトリガー。
デメリット：テスト手順や復旧手順を間違えると被害が広がる。

## プロセスkill
kubeletをプロセスkillする。

書いておいてなんだが、思いつき。
今度機会が合ったらやってみます。
OpenAI API Function callingを使ってみて分かった仕様をまとめていく

# はじめに
最近ちょくちょくOpenAI APIのFunction callingを触ってみて、実際に触ってみて初めてわかるような挙動がいくつかあったので、ここにまとめていこうと思います。
元は社内向けにしゃべった内容で、サンプルコードを載せられず分かりづらいところが多々あるかと思います🙇🙇🙇


### 引数も普段のChatと同じように生成しているので、Streamやtemperature、当然モデル精度等の影響を受ける
一番わかりやすい例は、「streamをオンにすると引数もstreamで渡される」事です。詳しくは[こちらの記事](https://qiita.com/ry-na/items/b201ce2a79c428b7402b)で書いているので合わせて読んでいただけるとわかりやすいかと思います！
また、temperatureを下げることで回答のバラつきが下がり、関数がランダムに呼ばれづらくなります。


### functionが呼ばれない場合、普通に回答が返ってくる
上の例を見ると思うのが、Function callingの呼び出しと回答箇所でパラメータやモデルを分けたい！だと思います。その場合一工夫必要で、該当する関数がない時に呼び出すデフォルトfunctionを定義して、その関数から再度APIを呼び出すアプローチが良いかと思います。

### JSON Schema形式、引数の型もJSON Schemaに乗っとる
![スクリーンショット 2024-01-31 10.45.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166306/f0878c85-7291-5a0e-5212-ec71bd241d66.png)
タイトルの通り、Function callingの定義はJSON Schema形式です。ですので、引数の型もJSON Schemaにのっとります。
公式ドキュメントでもあまりアピールされていないので、地味に見落としがちな場所かと思います。

「openai api function calling 引数 型」みたいに調べて地味に遠回りしてしまったので、メモっておきます
![スクリーンショット 2024-01-31 10.49.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166306/544478f8-b8c8-9645-1225-7b89e12e6829.png)
英語でググってもフォーラム、公式ドキュメント(↑の)の順で引っかかるので、利用できる型を解説している公式ドキュメントはなさそうです。

### Function callingもプロンプトの一種、関数が呼び出されなくてもアウトプットに影響する
一番わかりやすい例で言うと、「関数を呼び出すかを利用者に質問する」ことです。利用者がプロンプトインジェクションを行わなくても、関数名が晒されるケースはたまにあります。
これは完全に感覚なので余談ですが、Function callingで利用した単語が、回答に出てきやすくなるような気がしています。たとえば、"SNS"という単語を`description`に入れておくと、回答に"SNS"と若干出やすくなるような

### 違いがわかりづらい関数を並べると、先に定義した関数が呼ばれる
関数A, Bどちらを利用すればいいか分かりづらい場合、上に並べた関数Aが呼ばれる仕組みになっているようです。

# 終わりに
体験してみて分かった具体的な仕様と、感覚的な所まで書いてみましたがいかがでしたでしょうか？
Function calling自体は非推奨になり、toolsとしての利用が推奨されていますので記事としては少々遅いかもしれません。ですがtoolsでも重なる箇所は多いと思うので、誰かの参考になれば幸いです。