OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeで建てたコンテナ間の通信方法

# はじめに
個人開発でDockerとdocker-composeを使って構築しようとした際、フロントエンドとバックエンドをそれぞれのコンテナで立ち上げたとき、**コンテナ間で通信をする方法**がすぐにわからなかったので、その方法について共有させて頂きます🙏

:::note warn
今回は**コンテナ間の通信のみ**説明をします。Dockerやdocker-composeの詳細な使用方法については**説明しません**。あらかじめご了承ください。
:::

# 方法
とてもシンプルで、`docker-conmpose.yml` で作成した**サービス名**と、**使用したいポート**を指定するだけで可能です。
今回はNode.js上でサーバーを動かすことができるライブラリ`Express.js`を使用し、`express`と`web`というサービス名でコンテナを構築しようと思います。

```yaml:docker-compose.yml
services:
    express:
        build: ./express
    # ...以下省略...
    web:
        build: ./web
```

`express`の方では、[Express.js公式サイト](https://expressjs.com/ja/starter/hello-world.html)の**Hello Worldの例**を使用します。

```javascript:app.js
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```
その後、`docker-compose up`等でコンテナを起動し、`web`コンテナのターミナルで`curl express:3000`と入力すると、`Example app listening on port 3000`が返ってくると思います！

# 最後に
ネットで調べてみると、`docker-compose.yaml`で`networks`というのを定義する必要があるとか、必要ないとか、なかなか思うように辿り着かなかったですが、私がインターンさせて頂いている会社の中で、コンテナ間の通信をこのように行っていたので、とても衝撃を受けました。
中国前職の紹介：DB初心者向けのデータウェアハウスとデータレイクの紹介

私の前職では、中国の大手製造業企業でデータエンジニアとして働いていました。主にデータベースの管理やデータ開発、データ分析を担当していました。それでは、データウェアハウスとデータレイクという概念を説明しましょう。

# 01 - データウェアハウス
データウェアハウスとは何でしょう？

それは、複数のデータソースを一つにまとめた構造化ストレージで、ビジネスインテリジェンス分析をサポートし、ビジネス決定と商業的洞察を支援するデータ分析プラットフォームを提供します。

### 重要なポイント：
（1）構造化：データは構造化され、一般的にはテーブル形式で保存され、事前に定義されたスキーマに従います。
（2）履歴データ：完全な履歴データを強調し、時間軸に沿ったトレンド分析を支援するデータレポートを提供します。
（3）強力なクエリと分析能力：高速なクエリと分析能力を提供し、複雑なクエリステートメントを効率的に実行できます。
（4）データ統合：複数のビジネスデータソースを一つの完全で統一されたビューに統合し、複雑なビジネスロジック分析をサポートします。
（5）ディメンションモデリング：通常、ディメンションモデリング（例えばスター・スキーマやスノーフレーク・スキーマ）を使用して、効率的なクエリをサポートするデータモデルを構築します。

### データウェアハウスの価値：
（1）データ統合：企業内では、データは通常、異なるシステムや部署に分散し、異なる形式と構造で存在しています。データウェアハウスは、これらのデータを統一されたストレージに統合することで、データの孤立問題を解消し、企業が自社のビジネス状況をより包括的に理解することを可能にします。
（2）高性能のクエリと分析：最適化されたデータ構造とクエリエンジンを使用してユーザのクエリリクエストに迅速に対応し、複雑なデータ分析やデータマイニングをサポートします。これにより、企業はビジネスデータをより効果的かつタイムリーに利用することができます。
（3）データ品質管理：データのクリーニング、検証、修正を行い、データの精度と一貫性を向上します。
（4）データのセキュリティ保証：センシティブ/コアデータに対するアクセス制御と暗号化を行い、企業のコアデータ資産を保護します。
（5）ビジネスインテリジェンスと意思決定支援：データウェアハウスを通じて、企業は各種のレポートやダッシュボードを作成することができ、さらに下流のアルゴリズムモデルに接続することも可能です。これにより、経営陣やビジネス担当者はビジネス状況をよりよく監視し分析し、タイムリーに決定を下すことができます。

## 02 - データレイク
データレイクとは何でしょう？
データレイクは、大量の原始データ、非構造化データ、または構造化データを保存できるストレージ構造です。データウェアハウスとは異なり、データレイクでは、組織が原始形式のままデータを保存することが可能で、各種のデータタイプをサポートします。これにより、データの探索、分析、処理に対して柔軟な環境が提供されます。

### 重要なポイント：

(1) 原始で多様なデータ：データレイクは、原始の未処理データを保存します。これには、構造化データと非構造化データの両方が含まれます。
(2) スケーラビリティ：高度にスケーラブルなストレージソリューションであり、大量のデータを処理できます。(3) 読み取り時スキーマ：データウェアハウスとは異なり、データレイクは通常、読み取り時にスキーマを適用する方法を採用しています。これにより、ユーザーはデータを分析する際に構造を適用することができます。
(4) 柔軟性：様々なデータ形式を収容できるため、多くの種類のデータの保存に適しています。
(5) 探索的分析：探索的データ分析をサポートし、データサイエンティストやアナリストが事前に定義された構造なしでデータを探索することを可能にします。

### データレイクの実際の使用シーン：
(1) ビッグデータと非構造化データ：大量の非構造化データや半構造化データを処理する場合。
(2) データ探索とデータディスカバリ：データサイエンティストやアナリストが一時的にデータを探索し、洞察を発見することを組織が許可する場合。
(3) データアーカイブと長期保存：大量のデータをアーカイブし、コンプライアンス、履歴分析、または将来の使用のために保存する必要がある場合。
(4) 分析用データレイク：異なるデータソースを処理し分析するための分析ツールとフレームワークを統合する場合。
(5) データレイクを中央ストレージリポジトリとして：特定のユースケースに対して、さまざまなデータタイプを保存する中央ストレージリポジトリを構築することを考慮する場合。
(6) 機械学習と高度な分析：異なる構造を持つ大規模なデータセット上で機械学習モデルと高度な分析を利用する場合。

## 03 - データレイク vs データウェアハウス
#### 1.データの性質：
- データレイク：原始データや非構造化データ、多様なデータタイプに非常に適しています。
- データウェアハウス：事前に定義されたスキーマが必要な構造化データに最適です。

#### 2.アーキテクチャ：
- データレイク：読み取り時スキーマを採用し、分析の過程でデータを柔軟に構築することを可能にします。
- データウェアハウス：事前に定義された構造を持つ書き込み時スキーマを採用します。

#### 3.クエリパフォーマンス：
- データレイク：データの組織とインデックスにより、クエリパフォーマンスは異なる場合があります。
- データウェアハウス：クエリの高速性を最適化するように設計されています。

#### 4.データ統合：
データレイク：原始データを保存し、統合と探索に適しています。
データウェアハウス：さまざまなソースからの構造化データを統合します。

#### 5.スケーラビリティ：
データレイク：大量のデータを処理するために設計された高度にスケーラブルなソリューションです。
データウェアハウス：スケーラブルですが、大規模なデータセットに対するスケーリング戦略が必要な場合があります。
投稿カテゴリを表示するWordPressカスタム関数の作成

WordPressで投稿のカテゴリを取得し、ウェブページに表示する方法を詳しく解説します。

```php
function get_post_category($anchor = true) {
    $category = get_the_category();
    if ($category[0]) {
        if($anchor) {
            echo '<a href="' . get_category_link($category[0]->term_id) . '">' . $category[0]->cat_name . '</a>';
        } else {
            echo $category[0]->cat_name;
        }
    }
}
```

## 関数パラメータを設定

```php
get_post_category($anchor = true) 
```

`$anchor` のパラメータは真偽値を取り、 `$anchor = true` のように記述することにより、デフォルト値を`true` に設定しています。

関数を使用するときに、引数を`true`または`false`と値を変更することによって、カテゴリ名のリンクとして表示するかどうかを変更することができます。

## カテゴリの取得

```php
get_the_category()
```

`get_the_category()`関数を使用して現在の投稿に関連付けられたカテゴリのリストを取得します。この関数はカテゴリオブジェクトの配列を取得します。

※参考
[get_the_category() – Function | Developer.WordPress.org](https://developer.wordpress.org/reference/functions/get_the_category/)

### ※point

各カテゴリオブジェクトには、カテゴリの名前 (`cat_name`)、ID (`term_id`) などの情報が含まれています。

```php
$category = get_the_category();
$cat_name = $category[0]->cat_name; // カテゴリの名前を取得
$term_id = $category[0]->term_id; // カテゴリのIDを取得
```

このように指定することにより、オブジェクト内の詳細情報を取得することができます。

## カテゴリの存在確認

```php
if ($category[0]) {
```

この行では、取得したカテゴリの配列が空でないかを確認しています。`$category[0]`は配列の最初の要素、つまり最初のカテゴリを指します。最初のカテゴリが存在する場合のみ、次のステップに進みます。

## リンクとしての表示

```php
if($anchor) {
    echo '<a href="' . get_category_link($category[0]->term_id) . '">' . $category[0]->cat_name . '</a>';
} else {
    echo $category[0]->cat_name;
}
```

`$anchor`が`true`の場合は、
`echo '<a href="' . get_category_link($category[0]->term_id) . '">' . $category[0]->cat_name . '</a>';` 
の行が実行され、カテゴリ名はリンクとして表示されます。

`$anchor`が`false`の場合は、
`echo $category[0]->cat_name;` 
の行が実行され、単にカテゴリ名をテキストとして表示します。

### ※point①

```php
get_category_link($category[0]->term_id) 
```

 `$category[0]->term_id` を使って最初のカテゴリのIDを指定しています。

このカテゴリIDを`get_category_link()`関数の引数にわたすことで、そのカテゴリIDに対応するカテゴリアーカイブページのURLを生成します。

ちなみに、`get_category_link($category[0])`としてカテゴリオブジェクトを直接渡すこともでき、これもカテゴリのIDを指定したことになり、同様にカテゴリアーカイブページのURLを生成します。 

※参考
[get_category_link() – Function | Developer.WordPress.org](https://developer.wordpress.org/reference/functions/get_category_link/)

### ※point②

```php
'<a href="' . get_category_link($category[0]->term_id) . '">' . $category[0]->cat_name . '</a>';
```

PHPにおいては、「’ ‘」（シングルクォーテーション）や「” “」（ダブルクォーテーション）、「.」（ドット）を使って基本的な文字列を操作します。

#### 「’ ‘」や「” “」で囲う理由
PHPでは、シングルクォーテーション(’ ‘)またはダブルクォーテーション(” “)を使って文字列を定義します。シングルクォーテーションで囲まれた文字列は、その中の内容を完全にリテラル（そのままの文字列）として扱います。つまり、変数の内容やエスケープシーケンス（例えば`\n`や`\t`など）が展開されることはありません。これに対して、ダブルクォーテーションで囲むと、文字列内に含まれる変数はその値に置き換えられ、エスケープシーケンスも解釈されます。 

#### 「.」でつなぐ理由
PHPにおいて、「.」は文字列連結演算子として機能します。この演算子を使用することで、二つ以上の文字列を結合して一つの文字列を作ることができます。
    

## 関数の使用例

```php
<div class="entry-label"><?php get_post_category(true) ?></div><!-- /entry-item-tag -->
```

```php
<div class="entry-item-tag"><?php get_post_category(false) ?></div><!-- /entry-item-tag -->
```

この様に使用して、リンク付きまたはリンクなしのカテゴリ名を条件に応じて表示することができます。
Flutter ボタン系Widgetまとめ

久しぶりにFlutterで開発するとき、ボタン系のWidgetがわからなくなるのでまとめてみる。
まとめる対象は、material.dart内からピックアップし、Web上で確認できるようにしました。

- [DrawerButton](https://api.flutter.dev/flutter/material/DrawerButton-class.html)
- [DropdownButton](https://api.flutter.dev/flutter/material/DropdownButton-class.html)
- [ElevatedButton](https://api.flutter.dev/flutter/material/ElevatedButton-class.html)
- [FilledButton](https://api.flutter.dev/flutter/material/FilledButton-class.html)
- [FloatingActionButton](https://api.flutter.dev/flutter/material/FloatingActionButton-class.html)
- [IconButton](https://api.flutter.dev/flutter/material/IconButton-class.html)
- [MenuItemButton](https://api.flutter.dev/flutter/material/MenuItemButton-class.html)
  - [SubmenuButton](https://api.flutter.dev/flutter/material/SubmenuButton-class.html)
- [OutlinedButton](https://api.flutter.dev/flutter/material/OutlinedButton-class.html)
- [PopupMenuButton](https://api.flutter.dev/flutter/material/PopupMenuButton-class.html)
- [RadioMenuButton](https://api.flutter.dev/flutter/material/RadioMenuButton-class.html)
- [SegmentedButton](https://api.flutter.dev/flutter/material/SegmentedButton-class.html)
- [TextButton](https://api.flutter.dev/flutter/material/TextButton-class.html)
- [ToggleButtons](https://api.flutter.dev/flutter/material/ToggleButtons-class.html)

参照先: https://api.flutter.dev/flutter/material/material-library.html

## 作成したWebページ

https://flutter-sample-ui.web.app/

## 参考文献

- [material library](https://api.flutter.dev/flutter/material/material-library.html)
- [【Flutter】Web アプリを🚀爆速🚀で Firebase Hosting にデプロイする](https://zenn.dev/pressedkonbu/articles/deploy-flutter-web-app-with-firebase-hosting)
【ChatGPT＋DALL-E3】自撮り写真から肖像画を作成


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

　今回は、お遊びで、自撮り写真から肖像画を作成しました。

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

　まずは、ニュース。

　Meta社が生成AI『Meta AI』を
　　リリースしました。
　　　中身は『Llama 3』だそうです。

　Facebook上で
　　気になる記事があったら
　　　質問できる、とか。

　Messengerアプリ、
　　Instagramメッセージの中で
　　　直接使用可能、とか。

　画像生成ができる、とか。
　　それを編集できる、とか。
　　　それをアニメ化できる、とか。

　もちろん、文章作成、要約も可能。
　　Web検索（Bing使用）は
　　　出典元も辿れる。

　残念ながら
　　現在、インドとアメリカからの
　　　アクセスに限定されている
　　　　そうです。

　また、画像生成は
　　以前のBing ImageCreatorのように
　　　プロンプトから画像生成する
　　　　形のようです。
　　　　　ChatGPTのように
　　　　　　やり取りはして
　　　　　　　いませんでした。

　詳しくは（それほどでもないが）
　　以下を参照してください。
[とうとうインスタにもAI機能が追加](https://x.com/chatgptair/status/1781805095145120005?t=c1POaxHszhHrSF9r8-3oXA&s=03)
***
　おととい（2024/04/19）の記事
[【ChatGPT＋DALL-E3】画像を与えたら、左右が違う？](https://qiita.com/kabumira/items/64005a0f915f87f1e657)
　　の追加情報です。

　シンボルマークの
　　上下左右が手に入ったので、
　　　画像解析させてみました。

　方向を12時間時計で
　　答えさせました。

　上下左右の画像を
　　ChatGPTに与えたところ
　　　上　12時
　　　下　6時
　　　右　9時
　　　左　3時
　　　　と答えました。

　やっぱり、左右が違いますね。

　作品制作では、
　　ご注意のほどを。
***
　本題です。

　お遊びですw

　自分の顔を
　　自撮りして
　　　どうなるかな？と
　　　　やってみました。

　自撮り写真は
　　ご勘弁のほどを(笑)

　プロンプトは
　　「この人物を再現してください」

　で、描かれたのがこちら。
![1713668163839.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/a6526c88-5b2b-5b4d-1146-d412fda23202.jpeg)

　顔の線は似てるかな？

　でも
　　こんなイケオジじゃないし😅

　とりあえず、
　　油絵風にしてみました。

　全然なりません。

　そこで、
　　ゴッホ風に。
![converted_image (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/28196eb2-16a8-6036-3099-d6417d77964f.jpeg)

　おお、良さげ。

　ほかにも
　　ダ・ビンチとか
　　　フェルメールとかを
　　　　指定してやりましたけど
　　　　　面白くはなかったです。
　　　　　　全部同じで。

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

　今回は、ここまで。
レストランのシェフに、IT系個人事業主の仕事を相談してみた話

# はじめに
昨晩は、よく行くレストランへ行ってきました。そこで、人生相談というか、個人事業主やってるんですよ～どうやって広報したらいいですかね～という相談？雑談？をさせてもらいました。
もう１０年近く通っているので、シェフとはいつもいろんな雑談をしてもらえる関係ですｗ

そこのシェフは、**都内のとある町を中心にすべて異なるタイプの飲食店を５店舗も出していている敏腕経営者、兼現役シェフ**。４０代。飲食店の３年継続率が３０％（７０％が廃業）と言われている中、店舗が増えているという成功者です。

私はざっくり言うとIT関係が得意なのですが、シェフは逆に、IT関係はほぼわからないです。まぁ当たり前です。仕事で使わない知識なんて、ほぼいらないです。私は逆に、フライパンで魚をふっくら上手に焼く焼き方は知らないしできない。
シェフは、パソコンを効率よく使えなくても魚は上手に焼けるし、IT関係の人は、魚は上手に焼けないけどパソコンは効率よく使えるというだけの話ですね。

そんな方ですが、**経営者視点でIT系の一個人の経営ってどうっすか**と相談してみたところ、私としてはとてもためになるお話を伺えたので、そのお話を共有します。

# IT系の個人経営について、レストランシェフからアドバイス

## そもそも仕事って一般的に
そもそも仕事って、できない人の代わりにやってあげて、その対価としてお金をいただくということ。なので、人と触れ合う機会が少ないということは、できない人と触れ合う機会が少なく、対価のお金をもらえる機会も少なくなる。
だから、同業種・異業種問わずたくさんの人と会ってお話を聞いて、課題や解決方法を知ることが大事。

## 非IT系の世界

話をIT関係に絞ると、一般的には苦手で誰かにやってもらいたいと思う人は山ほどいる。特に一個人から見たら、世間の１０％の人しか困っていなくても、人数は十分。対応しきれないくらい。

そういう人たちは、ChatGPTで売り上げの分析もできるなんてニュースは入ってこない。ウィルスソフトはどうすべきとか、パソコンを買うときグラフィックボードが必要かとか、Google Spread Sheetを使えば無料でできるとか、知るわけない。

一方でIT関係者は、そういう人たちがどこで困っているか、躓いているかわかっていない。「こんなこと誰でもできる」と思って、知識の価値を軽く見ている。
IT関係者は、IT関係者が知る課題を解決しようとするから、非IT系の人たちの課題は、ボリュームは１０％と小さいながらも解決されないまま残っている。

## IT関係の仕事を、一個人が広める方法の案

IT系の大企業は、個人でなく企業がターゲット（BtoB）のことが多く、個人（BtoC）でも１０％の人でなく、９０％の人を狙った施策を立てる。
だからIT系の個人事業主は、個人（BtoC）の１０％の人を顧客の対象とするといいんじゃないか。

その入り口は、最初は口コミ。親戚や知り合い、その人に紙ベースの広告を渡して広めてもらう。得体の知れない他人に、いきなり個人の情報を開示して見てもらうのは抵抗があるから。

内容は、パソコン周辺の利用サポートから始め、いろいろな相談に乗って信頼を得て、小さな業務の効率化やシステム化の案件などにつなげる。
パソコンサポートとは、パソコンを買うときに一緒に行くとか、重くて調子が悪いのを見てみるとか、購入し続けているソフトの要否とか。

# それを踏まえて自分ができること

大体、そんな話を伺えました。じゃ今の自分を振り返ってどうか。

今は、自分が前にいた会社の業種で使えるシステムを作ってます。その人たちはみんな使うし便利になるよねというものを。売れるかもしれないし、売れないかもしれない。そのリスクがある状況下で、広告や、マネタイズをどうするか、そのシステムをしっかり考えて作らないといけない。

今の私は、もっとBtoCに振った方がいいなって思いました。
正直、パソコンの対応は泥臭い。IT系の会社の中の情シス（仕事で使うパソコンの調達から環境構築、運用）をやっていたけど、それですらそう思ったので。でもやる。

口コミで広めるためには、自分がなにができるか、何をやってきた人なのかをわかりやすくまとめないと。
ホームページを作るとか、チラシはどのサイズかとかそういう以前に、その目的で見る情報がまとまってないなと思ったので、まずはそこから。

ちなみに、私が軽視してしまっているのは、一般の人よりは「パソコンに詳しい」という能力。例えば、調子が悪い時に見ること、新しいパソコンを買うときに自分に必要十分な機能を判断することとか。
だけどお話を聞くと、そこは使えるなーと思ったのでわかりやすいようにしないといけない。

そして紙で名刺かチラシを作って配る。

一歩ずつやっていきます。

# おわりに
この記事は、日記として書いているnote用に書いたものですが、IT関係者も知ると嬉しい人もいるかもと思って、コピペでマルチポストさせていただいています。
文章が長いのは、そういった背景からでした。お付き合いいただきありがとうございました。

Qiitaを読んでる方は、「パソコンに詳しい」人が多いと思いますが、その情報を軽視せずに、周りを助けたりお金を稼いでもらえたらと思います！
【シリーズすごいぞiQｰF】初めてのラベルプログラムでつまずいたこと

:::note warn
本記事はラダー言語を対象として記述しています。
本記事中に登場するファンクションブロックは全てサブルーチン型を想定しています。
:::

## この記事の対象
+ FX3シリーズでのラダープログラミング経験者
    + 構造型では無い形式、ここではデバイスプログラムと呼ぶ
+ iQ-Fシリーズのラベルをちょっと使ってみようと考えている方

## はじめに
ラベルを使用したプログラムは非常に便利なのですが、デバイスプログラムから移行する際にいくつかつまづいた点があったので記事にしました。

## グローバルラベルとローカルラベルの使い分けをどうするか
これは例外はありますが単純に下記で区分けしました

### グローバルラベルの用途
+ プログラムブロックの外部に入出力する必要があるもの
    + I/Oデバイスを割り付けるもの
    + GOT（HMI）に表示するもの
    + ネットワーク通信など、リンクリフレッシュデバイスを割り当てるもの
    + 他のブログラムブロックへ伝達する情報

大量のラベルを定義する必要がある場合、この部分はラベルを使用せず従来通りデバイスを使用する方法を好む方もいるかも知れません。

ここには記載しませんが構造体と配列を使用して先頭だけ指定すればあとは全て連番でデバイスが割付くテクニックなどを使用すれば、ラベルエディタでラベルにデバイスを割り当てた方がデバイスを入れ替える際などスムーズに行えます。

### ローカルラベルの用途
+ プログラムブロックの内部のみで使用する
+ 外部からは参照できず、別々のプログラムブロックに同じ名前のローカルラベルが存在しても良い
+ 計算の途中経過だったり、順次動作の進行状況だったりを示すラベルを配列で適当に5個とか10個とか素早く確保できるのでとっても楽ちん

## ラベルでは連続したデータをどのように扱うか
### 配列を使用する
デバイスプログラムの場合、乗算命令など命令によって先頭になるデータデバイスを指定すれば勝手に連番で結果が出力されていました。

そのような場合、ラベルプログラミングでは配列を使用します。
複数のデバイスにまたがって結果が返ってくる命令ではラベル配列を使用すると覚えましょう。

なお、16bit乗算命令などは結果を32ビット型ラベル（配列で無い）に入れることも16ビット型配列ラベルに入れることも可能です。

### 構造体を使用する
配列は同じデータ型を連続した番号で扱えるようにした集合ですが、ラベルでは構造体という違うデータ型をまとめた集合も取り扱えます。

構造体はデバイスプログラムでは類似する要素が無かったので、ここではこれ以上取り扱いません。

## 基本データ型について
ワードについて、［符号付き］と［符号なし］のどちらを使うべきか最初は悩んでいたのですが、今はとりあえず［符号付き］を標準にしています。

## クラスについて
### CONSTANTの使い道
+ 盤面にHMI(GOT)が無く、調節計とPLCが通信しているというシステムで設定値をまとめるために使用した
+ ものの本によると数字だと置き換え操作で意図せぬ置き換えが発生するのでそれを防ぐために定数を使用すると記載あり
### RETAIN（ラッチ）の注意事項
+ ラッチラベルにデバイスを割り付ける場合はラッチデバイスを割り付ける
+ デバイスを割り付けない場合、プログラム書き換え時に注意が必要
    + SM9353 OFF時　RETAINラベルもクリアされる
    + SM9353 ON時　 RETAINラベルは保持
+ CPUパラメータを書き換えた場合、SM9353にかかわらずラッチラベルもリセットされる
    + 不都合ある場合は必ずデバイスで保持するようにプログラムしましょう
### PUBLICの使い方
ファンクションブロックのみで使用できるクラスです。
構造体型ラベルとして
「ファンクションブロックのインスタンス名.PUBLICラベル名」
でファンクションブロックの外で使用することができます。
### IN_OUTの使い道
ファンクションブロックのみで使用できるクラスです。
ST言語の本を読むと配列や構造体をファンクションブロックに引き渡すのが一般的な使い方みたいです。
オムロン調節計のプログラムレス通信デバイスを処理するファンクションブロックを作成したのですが、リードオンリーとリードライトが混ざっている30点の通信データを構造体で引き渡した時、便利だなと思いました。
+ タイマーカウント値などファンクションブロックの内部発生的な値を保持したいときにそれらをデバイスと関連付けるために使用できます

## ラベルの命名について
入力補完が効きやすいので原則はスネーク記法を採用しています。
下記を判定する記号がラベル名に入るようにしています。
+ グローバルかローカルか
+ 構造体か
+ 基本データ型は何か
+ 配列か

プログラムを組むときに見分けが付くという面より、入力時に絞り込みが効くという面でのメリットを大きく感じています。
「配列か」に関しては入力補完は関係ないのですが、添え字要るんだったっけ？と迷うことが結構発生したので付けるようにしました。

デバイス番号も人に伝えるときにIDとして非常に優秀だったので場合に応じてラベル名にもID要素が要るかなと考えています。

## ラッチラベル容量の心配
初期設定では1Kと少なめですが、ラッチラベルにラッチデバイスを割り付けるとラッチラベルの容量は消費しないので心配する必要はありませんでした。

私の組み方ではラッチが必要なものはGOTに表示させるものが主なのでほぼ必ずデバイスが割り付く格好になります。

2024/05/11追記
ユーザーFBはインスタンス1ヶにつき最低でもラッチラベル16ワードが予約領域として必ず消費される仕様です。

:::note warn
初期設定では最大で64個までユーザーFBのインスタンスを生成ができます。
それ以上必要な場合はCPUパラメータの変更が必要になりますが、FX5UJはラッチラベルエリアの変更ができないので注意が必要です。
:::

## おわりに
ラベルを使用するにあたって心理的につまずいたことをつらつらと書きました。
新しいことに挑戦するのに
「全部オッケー大丈夫！」
とはなかなかなりませんよね。

+ 2025/04/02
    + RETAIN（ラッチ）の注意事項にCPUパラメータ書き換え時について追記
    + IN-OUTでの値の保持についてついき
## 過去記事一覧
+ [過去記事一覧](https://qiita.com/fujiteruo/items/af2459d320e8109963db)
OpenAI の Assistants API の新バージョン v2（現時点でベータ版）に関する情報を見てみる

## はじめに
本記事執筆時点（2024/4/21時点）ではベータ版となっているようですが、OpenAI の Assistants API に新バージョンのものが出たらしいので、それを見てみたという話です。

### v2 に関する公式ドキュメント
OpenAI公式ドキュメントでは以下に情報が掲載されています。

●What's new in the Assistants API - OpenAI API
　https://platform.openai.com/docs/assistants/whats-new
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/8ab545db-cd0a-936c-9ae5-f85a9711db5a.png)

### v1 から v2 への移行について
合わせて、v1 から v2　へ移行する場合のガイドも出ているようです。

●Migrating from v1 to v2 - OpenAI API
　https://platform.openai.com/docs/assistants/migration

## v2 に関する説明をいくつか見てみる
それでは、v2 に関する説明をいくつか見てみます。

ざっと見た感じでは、一部の内容は、「これまで他の API ではできていたことが、Assistants API でもできるようになった」という内容があるようでした。

### File Search
公式ドキュメントの箇条書きで、最初に登場していたのが以下の「File Search」です。

●File Search - OpenAI API
　https://platform.openai.com/docs/assistants/tools/file-search?context=streaming

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e75bac1c-e441-d299-1c52-e3e2a83dcc66.png)

1アシスタントあたり 1万までのファイルを扱うことができ、それを高速に検索できたりするようです。

### トークンの最大数の制御
コストを管理する際に関係してくる機能が追加されたようです。
具体的には、Assistants API を実行した際の、1回あたりで使用するトークン数の最大値を設定できるようです。

### tool_choiceパラメータ
「file_search、code_interpreter、function」などを実行する際に設定できるパラメータで「tool_choice」が追加されたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ae9e9d7a-183c-2613-d8c5-238c5206cfef.png)

これを設定することで、ツールの選択を任意のものに指定できるようです。

### 会話履歴のロール設定やパラメータ設定関連
会話履歴を作成する部分のロールの設定で assistant を指定できるようになったようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4c54d456-a220-5394-f332-4c5126fe77d6.png)

また、モデルの設定パラメータで、temperature、response_format (JSON mode)、top_p などの、ポピュラーなパラメータがサポートされるようになったようです。

### ファインチューニングされたモデルの利用
Assistants API で、ファインチューニングされたモデルが利用できるようになったようです。その際、対象にできるモデルは「gpt-3.5-turbo-0125」をファインチューニングしたもののみになるようです。

### SDK関連など
Node.js と Python の SDK に、ストリーミング・ポーリングのヘルパーが追加されたようです。

また、上記で話が出てきているストリーミングは、今回の v2 で利用可能になった状況のようです。

## おわりに
OpenAI の Assistants API の新バージョンの情報を見てみました。

今回はまずは情報を見てみただけでしたが、今後、実際に API を試してみようと思います。
VScodeの拡張機能 Live Serverの簡単な使い方

こんにちは、学生プログラマーのねむaと言います.
簡単に自己紹介をしたいと思います.
ねむaです.いくつかのグループなどで活動しています.
主に使用している言語は. Python.JavaScript.C#.C.とかです.
さて自己紹介はこのぐらいにして本題に行きましょう

## まず準備からしましょう
必要なもの
・Visual Studio Code
・Live Server(拡張機能)

## まずVisual Studio Codeをインストールしましょう
この[インストールできるサイト](https://azure.microsoft.com/ja-jp/products/visual-studio-code)でインストールしてください.

無事インストールができたら起動してみましょう.
起動すると英語だらけだと思いますので
![スクリーンショット 2024-04-21 112408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490153/b0d433f3-3305-dd63-9d63-96442133d2c4.png)
ここを開いて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490153/951cb286-7847-3b27-ba36-c72c962090c7.png)
この拡張機能をダウンロードして再起動してみてください。
正常にダウンロードできてれば日本語になってると思います。

## Live Serverをダウンロードしよう
先ほど日本語にする拡張機能をダウンロードしたと思います
同じところで`Live Server`と検索してください
検索したらこれがでてくると思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490153/afd3e2e5-95f8-acc7-20f8-64dc455bb967.png)
これと同じものをダウンロードしてください

## Live Serverを使ってみよう
自分の好きな名前でフォルダーを作ってください

私は`site`という名前で作りました
フォルダーを開い`index.html`というファイルを作ってください

`index.html`ファイルを開いて以下のコードを書いてみてください
```html:html
<!doctype html>
<html lang="ja">
    <hear>
        <meta charset="UTF-8">
        <title>LIve Serverの使い方</title>
        <meta name="description" content="aaaa">
    </hear>
    <body>
        <h1>Live Serverの簡単な使い方</h1>
        <p>ちゃんと読んでね</p>
    </body>
</html>
```
このコードを書いてみてください
そしてこのように右クリックで開いてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490153/ef734cd5-4578-ecf2-d7db-48c941c04c41.png)
そしたら`Open with Live Server`というのを右クリックしてみてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490153/e723ae6f-27a8-8c89-06cc-56f99199ba07.png)
自動的にサイトに飛ばされると思います
`Open with Live Server`を使ってる間はコードを編集して保存するとサイト側も自動で変わります
そして止めるときは`Stop Live Server`をクリックして止めてください

これにてLive Serverの説明は終わりです

## 最後に
今回はVScodeの拡張機能のLive Serverを紹介しました
これから定期的に投稿していきたいと思います
次回はPythonかJavaSript関係の記事を書いていきたいと思います

自分はまだ学生なので言葉が足りない部分などがあると思いますがご了承ください
誤字脱字間違いがあった場合連絡してくれると嬉しいです
Discord:nemuadesu
仕事の連絡又はお問い合わせメール:nemusan40@gmail.com
Qiskit 1.0.0の量子プログラミング(シミュレータ編)

# Qiskit 1.0.0の量子(シミュレータ)プログラミング
Qiskit1.0.0 のリリースによりqiskitモジュールから “IBMQ” “execute” ”Aer”といった旧版でよく使っていた属性が削除されてしまいました。※[Qiskit 1.0.0 Release note](https://github.com/Qiskit/qiskit/releases/tag/1.0.0)
それにより、量子プログラミング方法について書籍に記載されているものが通用しなくなったりと(自分的には)大きく変わったと感じています。
例えば、シミュレータの設定(旧版ではAerを利用)やproviderの設定方法(旧版ではIBMQを利用)や回路の実行方法(旧版ではexecuteを利用)です。
そこで今回「[Migrate from qiskit_ibm_privider](https://docs.quantum.ibm.com/api/migration-guides/qiskit-runtime-from-ibm-provider)」を参照し、改めて上記属性やオブジェクトの使い方を見直しました。その内容をここに記載致します。


# シミュレータを使っていて私が感じた旧版Qiskitと新版Qiskit間の違い。
## 旧版Qiskit
1 &nbsp;&nbsp;シミュレータを準備する際に、シミュレータオブジェクト(Aer)からバックエンドオブジェクトを得る
2 &nbsp;&nbsp;構築回路の実行時、実行関数(execute)にバックエンドオブジェクトを伝える

## 新版Qiskitでは
1' &nbsp;&nbsp;qiskit_ibm_providerオブジェクトからシミュレータを指定してproviderオブジェクトを得て、このproviderオブジェクトからバックエンド情報を得る
2' &nbsp;&nbsp;バックエンドオブジェクトを使ってシミュレータを動かす。


## コード例

# 宣言
from qiskit_ibm_provider import IBMProvider
from qiskit import QuantumCircuit, transpile
from qiskit.visualization import plot_histogram

# 回路形成
circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw('mpl')

# 実行マシン構築(今回はシミュレータ)
provider = IBMProvider()
backend = provider.get_backend("ibmq_qasm_simulator")

# 回路実行
transpiled_circuit = transpile(circuit, backend=backend)
job = backend.run(transpiled_circuit)
print(f" > Counts: {job.result().get_counts()}")
plot_histogram(job.result().get_counts())




## 実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/9eda5176-7d44-b675-37a0-0561abfbccdf.png)


## 参照
[Qiskit 1.0.0 Release note](https://github.com/Qiskit/qiskit/releases/tag/1.0.0)
[Migrate from qiskit_ibm_privider](https://docs.quantum.ibm.com/api/migration-guides/qiskit-runtime-from-ibm-provider)
Next.jsでダークテーマを選択すると描画時にちらつきが生じる問題

## はじめに(背景)

私のポートフォリオではライトテーマとダークテーマを切り替えできるようにしています。

https://www.piny940.com

ただ、どちらのテーマを選択しているかを localStorage に保存していたため、initial rendering の段階ではライトテーマで描画され、JS が読み込まれてからダークテーマに切り替わるという問題がありました。

JS の読み込みには 0.数秒かかるため、画面を描画する際にちらつきが発生するという問題が有りました。

そこで今回は cookie を使ってこのちらつきの問題を解消した話を紹介しようと思います。

実際のコードは Github で公開しているので参考程度にどうぞ

https://github.com/piny940/portfolio

## 環境

- Next.js 14.1.4
  - Pages Router の前提で書いていますが、App Router でも同様の方法で実装できます。

## 解決策

選択中のテーマを cookie に保存することで、サーバーサイドでのレンダリング時にも選択中のテーマを取得できるようにしました。cookie に保存されたデータは`getServerSideProps`で取得することができます。

```ts
export const getServerSideProps: GetServerSideProps<HomeProps> = async (
  ctx
) => {
  const theme = (ctx.req.cookies.theme ?? "light") as Theme
  return {
    props: {
      initialTheme: theme,
    },
  }
}
```

Bootstrap では`html`タグに`data-bs-theme`属性を追加する必要があります。ただ、`html`タグが書かれている`Document`コンポーネントでは`getServerSideProps`を使うことが出来ないため、`getInitialProps`を使って`Document`コンポーネントにテーマを渡すことにしました。

```ts
interface MyDocumentProps extends DocumentInitialProps {
  initialTheme: Theme
}
function MyDocument({ initialTheme }: MyDocumentProps) {
  return (
    <Html className="bg-body text-body" data-bs-theme={initialTheme} lang="ja">
      ...
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}
MyDocument.getInitialProps = async (
  ctx: DocumentContext
): Promise<MyDocumentProps> => {
  const initialProps = await Document.getInitialProps(ctx)
  const req = ctx.req as IncomingMessage & {
    cookies: Partial<{
      [key in string]: string
    }>
  }
  const initialTheme = (req?.cookies?.theme ?? "light") as Theme

  return { ...initialProps, initialTheme }
}
```

クライアントサイドでテーマを切り替える際には、cookie に選択中のテーマを保存するようにします。

```ts
useEffect(() => {
  if (typeof window === "undefined") return
  document.cookie = `theme=${theme};path=/`
}, [theme])
```

## 最後に

今回は cookie を使ってダークテーマ選択時に生じる画面のちらつきを解消しました。ただ、この方法は SSG では使えないため、もっといい方法はないのかなぁと感じています。
こんな方法もあるよ、という情報があれば教えていただきたいです。

## 参考文献

https://dev.to/tusharshahi/react-nextjs-dark-mode-theme-switcher-how-i-fixed-my-flicker-problem-5b54
KotlinFest2024で気になる登壇まとめ part2

# はじめに
皆さんが応募されている登壇で魅力的なものが多すぎて一つの記事ではまとめられなかった為、以下の続きです！

https://qiita.com/YuukiYoshida/items/426716e2ab7d751f11a1

# よりよい Kotlin コードを書くためのライブコードレビュー by munetoshiさん

https://fortee.jp/kotlin-fest-2024/proposal/9bce31a0-fa64-430f-a08a-fa95b0ca46d9

読みやすいコードを書くという点は全言語共通の課題ですが、kotlinにおいてどういった点に注意し日常的にコードレビューされているかというのは、非常に興味のある点です。
去年のkotlinFestの資料を交えながらご説明いただけるということで、復習も兼ねて聞いておくとより深く学べるセクションになるのではないでしょうか？

# Kotlin Multiplatform開発の世界 by kigawaさん

https://fortee.jp/kotlin-fest-2024/proposal/236c59f3-f8b3-4ee7-8d33-e5a2b924d6df

マルチプラットフォーム関連のお話は個人的に必読だと思っています。
というのも現状市場的にマルチプラットフォーム関連の技術が改めて伸びてきており、触れておいて損のない技術だからですね。
また、弊社でもKMPでの実装を考えているという点も大きな理由の一つです、私自身も軽く触れた程度なのでこれを機に学びを深められたらと思います。

# コードレビューで学ぶ！Kotlinオブジェクト指向デザインパターン by Akihiko Satoさん

https://fortee.jp/kotlin-fest-2024/proposal/8af52f3e-0409-4acb-9615-c2c8a358d034

先ほどもコードレビューの登壇をあげましたが、こちらはデザインパターンの視点に立ってのコードレビューということで両方視聴すればもう隙のないレビューが行えそうですね！
個人的にもデザインパターン視点でのレビューは重要だと考えていますので、より深く理解するためにも登壇が決まったら視聴させていただきたいです。

# Kotlin製自作OSSを5年運用してきた経験を振り返る by 小山 健太さん

https://fortee.jp/kotlin-fest-2024/proposal/395cf3df-9db2-4f65-bbde-10b23b4f3c73

つい最近OSSについて社内で話していたところだったので、非常にホットな登壇ということで登壇が決まれば是非視聴させていただきたい内容です。

# Androidエンジニアに向けたKMPライブラリのご紹介 by 森 幸浩さん

https://fortee.jp/kotlin-fest-2024/proposal/7ff9a363-3784-419a-bc69-95cb2230a9e5

やはり注目の技術であるKMPに対する登壇は多いですね、どれも視聴必須な内容で選ぶのに苦労してます(笑)
KMPを採用するとなると問題に上がるのがライブラリの選定ですよね、そんな中でのこちらの登壇はまた他のKMPに関する登壇と視点が違って非常に興味深い内容です。

# 今こそ始めたい！Compose Multiplatform by OGIさん

https://fortee.jp/kotlin-fest-2024/proposal/eb074789-3f26-4175-ab2a-0b1dd727d7c2

やはりマルチな開発の登壇はより一層興味深く感じますね、Composeをさまざまなプラットフォームへ展開できることはプロジェクトによっては非常に多くのメリットを受けられる可能性がありますし、一度理解を深めておいて損のない技術かと思います。

# さいごに
本当に魅力的な登壇が多すぎて記事では伝えきれません(笑)
もちろん全てが採用されるわけではないですが、応募されている登壇の一覧を見るだけでもどんな技術が注目されているかや、現状の課題感なども垣間見えますので、是非一度参照してみることをお勧めします。
GitHub でフォークしたリポジトリに、フォーク元の更新を反映して最新の状態にする方法

# GitHub でフォークしたリポジトリを最新の状態に更新する方法

## はじめに

GitHub でオリジナルのリポジトリからフォークしたリポジトリを管理していると、オリジナルのリポジトリで更新があった場合、自分のリポジトリにその変更を反映したくなることがあります。この記事では、フォークしたリポジトリを最新の状態に更新する方法を解説します。

## 手順

1. ターミナルを開き、フォークしたリポジトリのディレクトリに移動します。

```
cd /path/to/your/forked/repository
```

2. リモートリポジトリの一覧を確認します。

```
git remote -v
```

通常、`origin` というリモート名でフォークしたリポジトリが登録されています。

3. オリジナルのリポジトリをリモートリポジトリとして追加します。慣例として、`upstream` という名前を使用します。

```
git remote add upstream https://github.com/original/repository.git
```

4. オリジナルのリポジトリから最新の変更を取得します。

```
git fetch upstream
```

5. 現在のブランチ（通常は `main` または `master`）に切り替えます。

```
git checkout main
```

6. オリジナルのリポジトリの変更を自分のリポジトリにマージします。

```
git merge upstream/main
```

7. マージした変更をフォークしたリポジトリにプッシュします。

```
git push origin main
```

以上の手順で、フォークしたリポジトリがオリジナルのリポジトリと同期され、最新の状態になります。

## 注意点

- オリジナルのリポジトリで大幅な変更があった場合、マージ時にコンフリクトが発生することがあります。その場合は、コンフリクトを解消してからマージを完了させる必要があります。
- フォークしたリポジトリで独自の変更を加えている場合、オリジナルのリポジトリの変更を取り込むと、それらの変更が上書きされる可能性があります。必要に応じて、別のブランチで作業するなどの対応が必要です。

## まとめ

GitHub でフォークしたリポジトリを最新の状態に更新するには、オリジナルのリポジトリをリモートリポジトリとして追加し、変更を取得してマージする必要があります。この手順を踏むことで、オリジナルのリポジトリで加えられた更新を自分のリポジトリに反映させることができます。
Small talk TypeScript

# Reference
http://blog.kueiapp.com/en/programming/easy-talk-typescript/

# What is TypeScript
TypeScript was first published at version 0.8 in 2012 by Microsoft, and made version 1.0 in 2014 with more types supported. The purpose to develop TypeScript is to solve problems that JavaScript is hard to be maintain on large and complex application development. TypeScript was made based on ECMAScript standard with supporting class-based programming, syntactical superset and static typing system.

<img src="http://blog.kueiapp.com/wp-content/uploads/2022/06/main-qimg-efbf627e4d9d15ed4c58b7f26ff7a63c.png" />

# Superset
Simply to say, TypeScript is a superset or a wrapper to JavaScript. It contains the latest ES6 (ECMAScript 2015) syntax of JavaScript and strict types to maintain reliable codes. With TypeScript compiler, every TypeScript codes (.ts) will be translated to JavaScript codes (.js) for execution.


# Run a TS file
To execute a ts file, the first of first thing is to install TypeScript into your environment by installing Node and NPM system in advanced.

```
npm install -g typescript
```

Then you can create any file with .ts extension by any text editor such as vim editor using your terminal, and type console.log('hello') into the .ts file for testing.

```
// commands
vim hello.ts

// in hello.ts
console.log('hello')
```

It’s time to execute the .ts file. Remember, any .ts file should be transferred to .js file for execution. Run tsc hello.ts in your terminal, then you will see a hello.js file be created into the same folder. To run the file, use NodeJS to run your .js file in the terminal.

```
// command 1
tsc hello.ts

// command 2
node hello
```

# Setting for your new project
The simple example above is to run a single file by tsc command. However, in real case, we usually create a lot of file within a project folder. We can then create a file called tsconfg.json in root of project to set up our compiler for the project, so that TypeScript compiler can read all .ts file in our project folder and sub-folders automatically.

```
{
  "compilerOptions": {
    "target": "ES2018", // transfering target
    "module": "ESNext", // JS module mode
    "moduleResolution": "Node",
    "importHelpers": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "types": ["@types/node"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}
```

# References
http://blog.kueiapp.com/en/programming/easy-talk-typescript/
http://blog.kueiapp.com/ja/nodejsのパーウワー/
Go言語でブロックチェーンのシステムを作成する（その５）

## はじめに
前回は、nonceの実装までやりましたが、今回はマイニングの実装をしていきます。

- 前回までの記事

https://qiita.com/jun_11/items/a1adf93ba02292321b25

https://qiita.com/jun_11/items/259f0a777e12b3fa1b32

https://qiita.com/jun_11/items/61adfc340792cdb2af08

https://qiita.com/jun_11/items/88f9a40648444b597529

- バージョン
  - Go 1.22.0

## マイニングとは
マイニングとは、トランザクションを確認し、新しいブロックをブロックチェーンに追加するプロセスです。
具体的には、以下のステップが含まれます。
1. トランザクションの収集
2. nonceの計算（プルーフ・オブ・ワークの計算）
3. ブロックの追加と報酬の受け取り

1.では、未確認のトランザクションを収集し、新しいブロックにまとめます。
2.では、前回の記事で実装した、nonceを求める計算を行います。そして、正しいハッシュ値を見つけたマイナーは、そのブロックをネットワークに提出できます。
3.では、2.で提出したブロックが他のネットワーク参加者によって受け入れられると、そのブロックはブロックチェーンに追加されます。マイナーはトランザクション手数料の形で、新たに発行される暗号通貨を受け取ります。

## 実装
### マイニングの実装

```golang
const (
	MINING_SENDER     = "THE BLOCKCHAIN"
	MINING_REWARD     = 1.0
)

type Blockchain struct {
	transactionPool   []*Transaction
	chain             []*Block
	blockchainAddress string  // 追加
}

func NewBlockchain(blockchainAddress string) *Blockchain {  // 引数を追加
	b := &Block{}
	bc := new(Blockchain)
	bc.blockchainAddress = blockchainAddress  // 追加
	bc.CreateBlock(0, b.Hash())
	return bc
}

func (bc *Blockchain) Mining() bool {
	bc.AddTransaction(MINING_SENDER, bc.blockchainAddress, MINING_REWARD)
	nonce := bc.ProofOfWork()
	previousHash := bc.LastBlock().Hash()
	bc.CreateBlock(nonce, previousHash)
	return true
}
```
まず、MINING_SENDERとMINING_REWARDの定数を定義しています。
MINING_SENDERは、マイニングした時の報酬をマイナーに送る送信元で、MINING_REWARDは、マイニングした時の報酬の値です。
BlockchainのstructにblockchainAddressを追加します。これは、マイナーに報酬を送るときに、マイナーのaddressを登録していないと報酬が送れないので、Blockchainにアドレスを登録するようにします。
これにより、NewBlockchainを実行するときに、引数としてblockchainAddressを渡して登録するように変更します。
Miningでは、まず、AddTransactionでマイナーに報酬を渡すtransactionsを追加しています。次に、前回実装したProofOfWorkを実行して、nonceを求めます。そしてCreateBlockに、ここで求めたnonceとpreviousHashを渡して、ブロックを追加しています。

## おわりに
今回は、マイニングの実装をしていきました。
これで、ブロックチェーンのシステムの基本的な機能は実装できました。

# 参考

https://www.udemy.com/course/go-blockchain/?couponCode=ACCAGE0923
PHP include_pathの設定

# PHPにinclude_pathを追加するには

## 対象者
・　include_pathの追加方法が分からない
・　そもそもphp.iniってどこにあるんだっけ？

## PHPバージョン
PHP 8.2.18
## OS
macOS sonoma v14.4.1

<!--
## 背景
Build in Serverを用いてローカル環境でサーバーを立ち上げたが、以下の警告が出力された．
```
Warning: include(/Users/xxxx/Documents/src/quiz/html/../templete/question.tpl.php): Failed to open stream: No such file or directory in /Users/xxxx/Documents/src/quiz/html/question.php on line 5

Warning: include(): Failed opening '/Users/xxxx/Documents/src/quiz/html/../templete/question.tpl.php' for inclusion (include_path='.:/opt/homebrew/Cellar/php@8.2/8.2.18/share/php@8.2/pear') in /Users/xxxx/Documents/src/quiz/html/question.php on line 5
```
参照先の外部ファイルがドキュメントルート外にあり、php.inファイルにinclude_pathが設定されていないため、読み込めないみたい．
-->


## php.iniファイルってどこにあるの？
phpファイルを探す方法はいくつかありますが、コンソールで確認してみましょう．
(webで確認する方法もありますが、やってることは同じです．)

```diff_php
$ php -r "echo phpinfo();" | grep "php.ini"
Configuration File (php.ini) Path => /opt/homebrew/etc/php/8.2
Loaded Configuration File => /opt/homebrew/etc/php/8.2/php.ini
```
phpinfoを見れば記述があるのですが、量が多いので、"php.ini"でgrepしています．

場所が分かったので、ファイルを見てみましょう．
今は、include_pathを確認したいので、以下のコマンドで確認してみます．
```diff_php
$ cat /opt/homebrew/etc/php/8.2/php.ini | grep include_path
;include_path = ".:/php/includes"
;include_path = ".;c:\php\includes"
; PHP's default setting for include_path is ".;/path/to/php/pear"
; Enables or disables file search in include_path optimization
```
先頭の「;」は全てコメントアウトなので、実質現在はinclude_pathが全く設定されていない状態になります．
では、編集しましょう．
iniファイルはテキストエディタで編集可能ですので、お好きなエディタ等で編集してください．
```diff_php
$ open /opt/homebrew/etc/php/8.2/
```
上記のコマンドでファイルが存在するディレクトリを開いて、ファイルを編集しましょう．
Windows で opendir を使う (dirent)

## これなに
いまどき Windows (Visual Studio) で C 言語だけでファイル操作をしたい！っていう縛りプレイの人向けの記事です。

Windows で C 言語 (but not C++) を学ぼうとすると `wchar_t` とかいうクソ時代遅れなインターフェースと格闘するハメになって無駄に初学者が悩むので、ファイル/フォルダ操作くらい `char *` でやらせてくれ、という話です。

## 縛りプレイしたくないけど？

現代の C++17 を使ってください。Modern C++ さいこう。

```cpp
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
	std::string path = "/path/to/directory";
	for (const auto& entry : fs::directory_iterator(path))
		std::cout << entry.path() << std::endl;
}
```

(そもそも C/C++ じゃなくて C# とか Rust とかを使えという説もある)

## それでも私は C がいい (本題)

https://github.com/tronkko/dirent を使ってください。
これは Linux 系で使われる `opendir` 系の関数 (dirent.h) を Windows 上に実装したもので、中で `FindFirstFileExW` とかを呼び出して `wcstombs_s` で `wchar_t` を `char *` に変えてくれてます。

### インストール方法

1. https://github.com/tronkko/dirent/blob/master/include/dirent.h をコピー
1. 「プロジェクト」→「新しい項目の追加」![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700889/9a9c402d-8b98-69e6-c1ad-34182e7760be.png)
1. 「ヘッダーファイル」を選んで `dirent.h` として追加 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700889/054fcac3-a986-7a6e-a9f4-81066ac5eb20.png)

1. コピーした内容を `dirent.h` に貼り付け

### 使い方

`#include "dirent.h"` でインクルードできます。
注意として、`#include <locale.h>` して `setlocale(LC_CTYPE, "jpn");` しておかないと日本語が `?` に化けます。

```c
#include <stdio.h>
#include <locale.h>
#include "dirent.h"

int main(int argc, char* argv[]) {
	setlocale(LC_CTYPE, "jpn");
	char* dirname = argc < 2 ? "." : argv[1];

	DIR* dir;
	struct dirent* ent;
	dir = opendir(dirname);
	if (dir == NULL) {
		printf("%s not found\n", dirname);
		return -1;
	}
	while ((ent = readdir(dir)) != NULL) {
		switch (ent->d_type) {
		case DT_DIR:
			printf("%s (フォルダ)\n", ent->d_name);
			break;
		case DT_REG:
			printf("%s (ファイル)\n", ent->d_name);
			break;
		}
	}
	closedir(dir);

	return 0;
}
```

## わしゃわけのわからんライブラリは使わん！
という人は素直に `windows.h` から `FindFirstFileExW` とかを直に使ってください。

## References

https://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c

https://qiita.com/hazigin/items/b2303348d966e2fcea0c
フォルダからドキュメント画像を移動する参考プログラム

## 本記事の概要
以下の記事で紹介している２クラス分類モデルをもとに、任意のフォルダからドキュメント画像を別のフォルダに移動するプログラムである。

[２クラス分類：写真画像とドキュメント画像を分類するAIアプリ](https://qiita.com/jscodermd/items/f2e4d187c2c2d6d80afa)
風景や人物と言った一般的な写真画像と、スクリーンショットや文書等を撮影したドキュメント画像をCNN画像認識技術を用いて分類するモデル。

本プログラムの概要イメージ
![移動プログラム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/3497c223-d462-9825-5574-603a949589c5.png)

全体の概要説明については、以下の記事を参照のこと。
[CNN画像解析：一般的な写真画像とドキュメント画像を分類するプログラムを作成](https://qiita.com/jscodermd/items/aedafe92783794a9d6c6)

## 開発環境
Python3.11.5
Windows 11

## 動作イメージ
一般画像とドキュメント画像が保存された、任意のフォルダを、分類対象とする。
![分類対象フォルダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/f43d3b05-4b84-61c7-b7f1-af5272cec25c.png)
移動プログラムを実行すると、移動先フォルダ「img_doc」が作成される。ドキュメント画像が同フォルダに移動し、元のフォルダには一般画像ファイルが残る。
![分類対象フォルダ_after2_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/4e44fded-f28c-dbef-9360-4de9d7a2ad68.png)

フォルダ「doc_img」の中身。ドキュメント画像が移動している。
![分類対象フォルダ_inner2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/991013b2-d1ec-5857-d75f-cd549206d142.png)

:::note info
真ん中行の左側、Francisco_Goya_143.jpgはドキュメント画像ではなく、アート画像なので、誤り。３クラス分類のモデルを使えば、こういう誤りは起こりにくくなると思われる。
:::

## 使い方
①任意のフォルダに、学習モデルを保存したファイルmodel.h5と、プログラムファイルのapp_main3.pyを配置する。
~~~
任意のフォルダ/
　├ model.h5
　├ move_doc_img.py
~~~

:::note info
model.h5は前述の２クラス分類の学習モデルを保存したファイルをあらかじめ用意すること。
:::
②move_doc_img.pyのソース内で、以下の部分を書き換える。
dir_nameは、整理したいフォルダを絶対パスで記載する。バックスラッシュ(\\)はスラッシュ(/)にする。
folder_nameにはドキュメント画像を移動するフォルダ名を記載する。
~~~python
dir_name = 'C:/aidemy/test'
folder_name = "doc_img"
~~~

:::note warn
簡易的なプログラムで例外処理を入れていないので、分類対象フォルダの誤りや、移動先フォルダの重複に注意すること。
:::

③コマンドプロンプトを起動し、プログラムファイルを配置したフォルダに移動し、move_doc_img.pyを実行する。
~~~
py move_doc_img.py もしくは python move_doc_img.py
~~~

## プログラム内容
move_doc_img.py
~~~python
import os
from werkzeug.utils import secure_filename
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
import shutil
image_size = 50

ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

#学習済みモデルをロード
model = load_model('./model.h5', compile=False)

dir_name = 'C:/aidemy/test'
folder_name = "doc_img"
# ファイルパス
path_org = os.listdir(dir_name) 
#print(path_org)

if os.path.isdir(dir_name+"/"+folder_name) == False:
  os.makedirs(dir_name+"/"+folder_name)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

for i in range(len(path_org)):
    filename = path_org[i]
    if allowed_file(filename):
        filepath = os.path.join(dir_name, filename)

        #受け取った画像を読み込み、np形式に変換
        org_img = image.load_img(filepath, target_size=(image_size,image_size))
        img = image.img_to_array(org_img)
        data = np.array([img])
        #変換したデータをモデルに渡して予測する
        result = model.predict(data)[0]
        if(result[0] > 0.5):
            print( "これは ドキュメント画像 です",filename)
            # ドキュメント画像を指定フォルダに移動する
            shutil.move(dir_name+"/"+path_org[i], dir_name+"/"+folder_name)


~~~
UNION ALLとORDER BYの組み合わせ

## 最後のUNION ALLのselect文にorder byがある場合
UNION ALL後にすべてを結合した次にorder byによりソートが実施される。
## それぞれのUNION ALLにorder byがある場合
それぞれのUNION ALL内でソートされた後に結合が行われる
UT　カバレッジ率100%にする

## UTとは
1つのプログラムが期待通りに確認する作業のことです。
## カバレッジ率とは
プログラムの処理の網羅率を言っています。すべての処理をカバーしている場合は100%になります。
## カバレッジ率を100%にするには　条件分岐をすべてカバーする
if文の条件式に対して真のケースと偽のケースを用意する必要があります。
下記プログラムの①の条件式を全て満たすには、resultが100のケース（真)と100以外のケース(偽)が必要です。
②の条件式を全て満たすには、rseultが300または200のケース(真)と300と200以外のケース(偽)が必要です。
③には上記以外のケースが必要です。

```java
int result = 100;
①if (result == 100) {
特定の処理を実行;
} ②else if(result == 300 || result ==200){
特定の処理を実行;
}③else {
特定の処理を実行;
}
```

条件式を満たすことができない場合があります。それは条件式が100と100以外の場合で以外がelseではなく、else ifで終わってしまっているケースです。
この場合、else ifの条件式を満たすには100以外(真)と100(偽)のケースが必要です。しかし、else ifの前で100の場合は真であるという条件式が用意されているため、else ifに届く値はすべて100以外のため、else ifの条件式を満たすことができないという事象が発生しています。そのため、if文を使用し、複数の条件式が存在する場合は可能な限りelseで閉じるようにしましょう。

## JUnit
### JUnitとは
JUnitを使用することで手軽に単体テストを実施することができ、カバレッジ率を確認できます。

### JUnitを使用したUTの仕方について
①INPUTの設定
②テストしたい処理を流す
③期待値の確認

①では、まずCollectionやインスタンスに値を格納します
②では、確認したい処理をMockした状態で流します。
③アサーションで実施した処理の戻り値が期待値通りか確認します。

### Mockとは
Mockを使用することで、確認したい対象物を疑似的に用意することができます.
Mockを使用しない場合、確認したいことができないためUTでは必要なものです。
Mockを使用する際は実施前に下記の入力することが必要です。
@ExtendWith(MockitoExtension.class)
Mockitoを使用することを宣言します。
@Mock
Mockしたいインスタンス等を定義します
@InjectMocks
@Mockで定義したインスタンス等が格納されるインスタンスを定義します。

### 期待値の確認
assertThatや例外処理の出力内容を確認したい場合はassertThrows、voidで戻り値がない場合はdoThrowなどを使用する。
whenやMockを使用をアサーションに含める場合は、模擬する範囲がきまっているため、範囲を考えながら行うことが必要です。

#### MyBatisが記載されている場合はカバレッジ率を把握できないケースがある
ローカル環境では確認できるが、それ以外の場所では確認できないというケースが発生することがある。そのため、ロジックを確認するためのUTとSQLを確認するためのUTを実施する必要が発生することがある。

##### MyBatisとは
インスタンスとRDBを紐づけるフレームワークの1つ。MyBatisによりDBから取得したデータをインスタンスに格納するなどできる。
vbsでモニタのシリアル番号などの情報取得

https://stackoverflow.com/questions/72171289/serial-numbers-from-monitors

```vbs:qiita.vbs
Sub getMonitors()
    Dim m
    Dim c
    
    'https://learn.microsoft.com/ja-jp/windows/win32/wmicoreprov/wmimonitorid
    
    For Each m In GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\.\root\WMI").ExecQuery _
        ("SELECT * FROM WmiMonitorID")
        
        Debug.Print "InstanceName:" & m.InstanceName
        Debug.Print "Active:" & m.Active
        
        Debug.Print "ManufacturerName[]:";
        For Each c In m.ManufacturerName
            Debug.Print Chr(c);
        Next
        Debug.Print
        'Debug.Print "ManufacturerNameLength:" & m.ManufacturerNameLength
        
        Debug.Print "ProductCodeID[]:";
        For Each c In m.ProductCodeID
            Debug.Print Chr(c);
        Next
        Debug.Print
        
        Debug.Print "SerialNumberID[]:";
        For Each c In m.SerialNumberID
            Debug.Print Chr(c);
        Next
        Debug.Print
        
        Debug.Print "WeekOfManufacture:" & m.WeekOfManufacture
        Debug.Print "YearOfManufacture:" & m.YearOfManufacture
        
        Debug.Print "UserFriendlyName[]:"
        'For Each c In m.UserFriendlyName
        '    Debug.Print Chr(c);
        'Next
        Debug.Print
        
        'Debug.Print "UserFriendlyNameLength:" & m.ManufacturerNameLength

        Debug.Print
        
    Next
End Sub
```

:::note info
出力結果
InstanceName:DISPLAY\PHLC217\4&f6e7055&0&UID224795_0
Active:True
ManufacturerName[]:PHL             
ProductCodeID[]:C217            
SerialNumberID[]:11xxxx            
WeekOfManufacture:12
YearOfManufacture:2020
UserFriendlyName[]:

:::
Nuxt3+Quasarのプロジェクトでアイコンライブラリを読み込む

`nuxt-quasar-ui`で、Material IconsやFont Awesomeなどのアイコンライブラリを使用する方法に読み込む方法に少しハマったのでメモ。

https://nuxt.com/modules/quasar

## 結論
`nuxt.config.ts`にて、`defineNuxtConfig`内の`quasar.extras.fontIcons`に使用したいライブラリの名前を指定するだけ。
```typescript
export default defineNuxtConfig({
  ...
  modules: ["nuxt-quasar-ui"],
  quasar: {
    extras: {
      fontIcons: ["fontawesome-v6"],
    },
  },
});

```

```vue
<q-icon name="fa-brands fa-ambulance" />
```

`name`に渡す値の形式はライブラリによって異なる。


https://quasar.dev/vue-components/icon/#webfont-usage

## ハマったポイント
以下のインストール手順では、`/quasar.config`という設定ファイルに設定を書く方法が紹介されている。
https://quasar.dev/options/installing-icon-libraries#installing-webfonts

ただし、この`/quasar.config`はQuasarのCLIを使ってQuasarをインストールしている場合に読み込まれるファイルらしい。

https://quasar.dev/quasar-cli-webpack/quasar-config-file/


`nuxt-quasar-ui`を使っている場合は、冒頭に書いたように`nuxt.config.ts`の`quasar`の欄に設定を記述する必要がある。
文化庁「AIと著作権に関する考え方について」（令和６年４月）を読んで気になったところ

# 文化庁の新ガイドライン解説：AIと著作権ってどうなってるの？

2024年4月に文化庁から発表された「AIと著作権に関する考え方について（概要）」、これがけっこう話題になってますよね。実施にクリエイターなどから意見をもらったりした改訂版ということらしいです。
「AIって便利だけど、著作権ってどうなってるの？」って思う人も多いはず。今回はガイドラインを読んで気になった点を解説してみます。法律に関しては詳しくないので、**あくまで私の解釈ということでご注意お願いします**　詳しくはガイドライン本文を参照し、専門家に相談してください。


### 本文
文化審議会 著作権分科会 法制度小委員会「AIと著作権に関する考え方について」。詳しくは[こちら](https://www.bunka.go.jp/seisaku/bunkashingikai/chosakuken/pdf/94037901_02.pdf)をご覧ください。


## AI学習データと著作権法（p5~7）

まず、AI学習データっていうのは、AIが賢くなるために必要なデータのこと。例えば、AIに絵を描かせたいなら、たくさんの絵を見せて「こういうのが絵だよ」と教えるわけです。これについて、新しいガイドラインでは「著作物を楽しむわけではないから、許諾なしでOK」と明言されています。つまり、**AIが学ぶためにデータを集める行為は自由に行える**というわけですね。


## 著作権法と「創作的表現」vs「アイデア」

Xなどでみなさんの反応をみていると、このポイントが一番注目されているっぽいですね。著作権法では、「創作的表現」は保護されますが、「アイデア」そのものは保護されません。この区別が重要なポイントとなっています。例えば、**特定の「作風」が似ていたとしても、それだけでは著作権侵害にはならない**のです。

なぜこの区別が大事なのかというと、**著作権法は具体的な表現を保護することで創作者の権利を保障するため**です。 たとえば、同じテーマやアイデアを扱っていても、表現方法が異なればそれぞれ独立した作品と見なされます。したがって、一般的な「作風」を模倣したとしても、それが具体的な創作物の「表現」をコピーしていなければ、著作権侵害とは見なされないわけです。

## 生成AIで作った作品を売るときの注意点（p11,12）

例を出してみます。私がAIを使ってとってもオシャレなイラストを作ったとします。このイラストがたまたま有名なアニメのキャラクターに似ていた場合、それを商品として売るのはアウトかもしれません。なぜなら、そのアニメの著作権を侵害することになるからです。
でも、もし**AIが全く新しい、誰にも似ていないキャラを創造したなら、その販売は問題ない**とされています。ただし、**知らず知らずのうちに似てしまった場合でもアウトになることもある**ので、その辺は要注意です。「知らなかった、悪気がなかった」や「プロンプトで具体的に指示したわけではない」では済まされないです。

## 著作権侵害したら誰が責任を取るの？（p14）

これが結構大事なポイント。AIが作ったものがたまたま他の作品と似ていて著作権侵害になった場合、その**責任はただAIを使っただけのユーザーだけではなく、AIの開発者や提供者にも及ぶことがある**とガイドラインで明らかにされました。


## 最後に
というわけで、AIと著作権について書いてみました。AIの進化はとめどなく進んでいますが、その使い方には配慮が必要みたいですね。本文中にも「判例や海外の対応も参考にしながら引き続き考え方の見直しを行う」とあり、このあたりの解釈も日々更新されると思いますので、必ず最新の情報をチェックするようにしてください。
SupabaseとNext.jsを使った開発をするまで


最近GAとなったSupabaseを使ってNext.jsでアプリを作るための開発環境を作っていきます。

## いちばん簡単な方法

実はSupabaseがGAになったタイミングで、公式より `Supabase Bootstrap` というものが提供されています。

これを使うとコマンド1つでSupabaseとNext.jsの開発環境が構築できます。

```bash
supabase bootstrap
npx supabase@latest bootstrap
bunx supabase@latest bootstrap
```

```bash
bunx supabase@latest bootstrap
Enter a directory to bootstrap your project (or leave blank to use /home/user/dev): test

    Which starter template do you want to use?

    1. embeddings [AI Inference in Supabase Edge Functions.]
  >  2. nextjs [A Next.js App Router template configured with cookie-based auth.]
    3. expo [An Expo React Native User Management starter.]
    4. flutter [A Flutter User Management starter.]
    5. swift [A Swift User Management starter.]
    6. rbac [A Next.js RBAC Slack clone starter.]
    7. @basejump/nextjs [A Next.js starter with personal accounts, teams, permissions and Stripe billing]
    8. scratch [An empty project from scratch.]
```

こちらのコマンドについての詳細は[Supabaseのブログ](https://supabase.com/blog/supabase-bootstrap)に記載されています。

https://supabase.com/blog/supabase-bootstrap

Supabaseをローカルで立ち上げるために必要な準備も済んでいるので正直これで十分です。

## 手動で作る方法

前述の方法とは別に、何かしらの理由で手動で開発環境を構築したい方は以下の手順で環境構築できます。

### Next.jsのプロジェクトを作成

```bash
bunx create-next-app@latest -e with-supabase
```

おなじみの `create-next-app` でプロジェクトを作成します。

### Supabaseの準備

今回は開発環境なのでローカルでSupabaseを立ち上げる準備を行います。

ドキュメントはこちら:

https://supabase.com/docs/guides/cli/local-development

ドキュメントにも記載がありますが、Dockerが動作する必要があるので、Docker Desktop等のインストールを行ってください。

```bash
bunx supabase@latest init
```

こちらのコマンドでプロジェクトルートに `supabase` というディレクトリが出来上がります。

```bash
bunx supabase@latest start
```

上記のコマンドでローカルにSupabaseが立ち上がります。
最初はイメージのダウンロードが行われるので少し時間がかかります。

Supabaseが立ち上がると、開発に必要な値が表示されます。

```bash
Started supabase local development setup.

         API URL: http://127.0.0.1:54321
     GraphQL URL: http://127.0.0.1:54321/graphql/v1
          DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
      Studio URL: http://127.0.0.1:54323
    Inbucket URL: http://127.0.0.1:54324
      JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
        anon key: eyJ.......
service_role key: eyJ.......
```

ここに表示されている `Studio URL` がSupabaseの管理画面です。
見慣れた画面が表示されると思います。

![](https://raw.githubusercontent.com/Gardenia-710/articles/main/images/2024-04-21-01.png)

### Next.jsでSupabaseを使う

Next.jsでSupabaseを使うためのやり方も細かくドキュメントに記載があります。

https://supabase.com/docs/guides/getting-started/quickstarts/nextjs

上記を参考に、Supabaseのクライアントをインストールして、設定を行います。

`SUPABASE_URL` と `SUPABASE_ANON_KEY` は先程の `supabase start` で表示された値を使います。

## まとめ

ほんの数週間前までは手動で環境構築をしていたのでこの記事をまとめてましたが、SupabaseがGAになり、Bootstrapが提供された今、僕はおそらく手動で構築することはなくなるんじゃないかなと感じています。

もちろん、Bootstrapを使わずに手動で構築することも可能ですし、その方がより理解が深まると思います。

とは言いつつSupabaseを完全に使いこなせているわけでもないのでこれを期にもっと勉強していきたいと思います。

ありがとうございました。
Function callingを使おう

# Function Callingとは
生成AI界隈でのFunction callingを知ってますか？単にあるプログラムが関数を呼び出すわけではありませんね。GPTを代表とする生成AI（以降AI）が、ユーザーまたはClientとなるプログラムからの問い合わせに応じて何を実行するかを決める方式をFunction callingと呼びます。Function callingにより、AIが呼び出すFunctionを選択することができます。

人間とAIの以下の会話で説明しましょう。

```
[人間]：明日大阪へ出張するから、梅田駅の近くのホテルを予約して。
[AI]（旅行サイトのWebAPIを実行し、梅田駅付近のホテルを収集）はい、〇〇ホテルと□□ホテルが空いています。それぞれ一泊の料金は・・・。〇〇ホテルにお一人、1泊でよろしいでしょうか。
[人間]：うん、それで。
[AI]（旅行サイトのWebAPIを実行、予約処理実行）〇〇ホテルを予約しました。
[人間]：傘は必要かな。
[AI]：（天気予報のWebAPIを実行し、大阪の明日の天気を取得）明日の大阪は快晴の予報のため傘をお持ちになる必要はありません。
```

AIは人間が要求することを正しく認識したうえで、適切なWebAPIを実行することができています。これまで秘書がやっていた業務の一部を置き換えているようですね。

現時点では秘書ほど賢いAIや、AIに向けて適切なWebAPIを公開しているWebサイトは少ないと思われますが、Function callingがこのようなやり取りを実現するのに役立つ技術であるといえます。出張などの一般的な問い合わせに限らず、医療、プログラミング、教育、デザインなど幅広い領域でFunction callingが役立つと考えられます。

# MVCからMVAへ
Microsoftも幾つかのセミナーでMVCからMVAを謳っています。Model-View-ControllerのControllerをAIに置き換えることで、より柔軟性を持ったシステムを構築できる可能性を示しています。（一方でAIをシステムに含めることで同じ入力に対する出力が一定でなくなるという副作用があり、適用する際に考慮が飛うようです）

AIが適切なModelを呼び分けることで、あらかじめどのモデルを実行すべきかプログラムとして記述する必要がなくなります。プログラマがあらかじめ定義するのはModelの役割と使い方のspec（OpenAPI形式など）を記述し、AIに対してendpointを公開するのみです。(認証をどうするかなど細かいところはありますが、MVCと概ね同様の考慮が必要)

2/20 の東京でのイベント：「MVC から MVA モデルへ：生成 AI を組み込んだ次世代 AI 駆動アーキテクチャ設計思想 / From MVC to MVA Model」

https://envision.microsoft.com/ja-JP/sessions/d14d6505-3f47-4852-a128-dd0748ee41bb

4/16 大阪でのイベント：「[A3] MVC から MVA モデルへ：生成 AI を組み込んだ次世代 AI 駆動アーキテクチャ設計思想」

https://msevents.microsoft.com/event?id=4009020836

# OpenAIの例
さて、Open AIのdocにもFunction callingの項目があります。

https://platform.openai.com/docs/guides/function-calling

OpenAI APIを使いながらFunction callingを使ってみましょう。