OmniAICreator/Qiita-1.07M huggingface dataset:
【Amazon Linux 2023】メモ EC2からRDS(MySQL)に接続方法

# PC環境
- MacBook Pro (M1 Max, 2021)
- mac OS Monterey (ver 12.5)
- SSD 2TB
- RAM 32GB

# VPC EC2 RDS 設定手順
https://catalog.us-east-1.prod.workshops.aws/workshops/47782ec0-8e8c-41e8-b873-9da91e822b36/ja-JP/overview

# 作成後 EC2で使うコマンド
https://qiita.com/Bjp8kHYYPFq8MrI/items/734ac300c04e447edef3

# 注意
Amazon Linux 2023 で 
```
sudo yum install mysql
```
と打つと、
```
No match for argument: mysql
Error: Unable to find a match: mysql
```
が吐かれる。

## 対処法
```
sudo dnf -y localinstall  https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
```
```
sudo dnf -y install mysql mysql-community-client
```
の順にコマンドを打つ。
最後に
```
mysql -h {RDBのエンドポイント} -P 3306 -u {RDBユーザー名} -p
```
で繋がる。
![スクリーンショット_2023-04-20_16_55_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779582/7da121cd-3dd2-18dc-4244-c7f9abc393eb.png)

foo~~~~!!!!!!!!!
記事投稿の目的

# 挨拶とこの記事の目的
初めまして、Testapoと申します。
Qiitaの先駆者の皆様にはいつもお世話になっておりますが、自分で投稿するのは初めてです。

私は現在、Swift（SwiftUI）を勉強しておりますが、1年勉強した気がするのですが全然見につきません。
いろいろ考えて出た答えは、インプットするだけで全然アウトプットしてないじゃん、ということでした。

なので、勉強などで覚えたことをアウトプットしたり、作品を作ったら解説などをして自分に落とし込む用にアカウントを作りました。

プログラミングは超超初心者です。
Markdown記法とかいうのも知らなかったほどです。

そんな自分がプログラミングの世界に足を踏み入れていいものか、ましてやここに投稿してもいいのか悩みましたが、自分が成長するには情報を発信するしかないと思い投稿する次第です。

これからいろいろと投稿したり質問するかと思いますが、どうか皆様温かい目で見守ってくれると幸いです。

では、また次回。
#0 リベンジ (ハンドジェスチャーでドローンを操作する )

学部の3年生(2021年)の時に所属するゼミで2週間で何かしらの成果物を作るという課題が与えられました。同じゼミの子はunityやDlibなどを使用して作っていました。
その際に自分はドローンに興味があったのでドローンを使用した成果物を作ることにしました。作成したのはハンドジェスチャーを使用してドローンを操作するといったものでしたがgit hubに上がっているコードにドローンとパソコンを通信するコードとジェスチャーの場合分けのコードを追記するだけでした。（担当教員には参考にした物は提示しています。）

↓参考にしたコードです

https://github.com/Kazuhito00/hand-gesture-recognition-using-mediapipe


このような経緯があり今回は前回作成した時に思った改善点や別の技術を使用して一から作成していきたいと思います。

前回作成したものはmediapipeを使用しwebカメラで取得した映像からハンドトラッキングし学習モデルを通してジェスチャーを分類します。分類の結果に合わしてパソコンからDJI Tello(無印)にコマンドを送って操作するといったものでした。

この時にあった改善・変更したいと思った点を以下にあげます。
①ドローンにコマンドを送る際にある一定の時間(2秒ほど)を空けないと操作が行われなかった。
→操作するコマンドがドローンで実行される前に次のコマンドが送られてきて上書きされコマンドが実行されないのが原因かも。スマホとドローンを接続して操作する時は急な切り替えしなどもある程度はできていたので性能的にはできなくはないがSDKの限界があるのかもしれません。

②ドローンを操作するコマンドを送る際に「方向」と「距離(cm)」を指定して送るがジェスチャーで方向の指定はできたが距離はどの方向でも定数(20cmだったかな)にしていた。
→距離を可変にするためにデプスカメラなども考えたが値が張るので代わりにArduinoと超音波センサーを使用して距離を設定しようと思う。

③参考にしたコードのモデルはmediapipeで取得した座標を学習させていたがConv2D等を使用し画像から学習するとどうなるか試してみたい。
→GPUの有無も操作感に現れるかもしれないの検証するかも

随時、記事を書いていきますので長い目で見ていただけると助かります。
discord bot ヘルプコマンドの作り方

## はじめに

本記事は、discord botでヘルプのコマンドの実装方法を述べたものです。

## 対象読者

本記事は以下のような方を読者として想定しています。

- discord.pyまたはpycordでbotを作ったことがある（または作っている）
- 自分で良い感じのヘルプコマンドを作りたいと思っている
- コマンドを作るたびにヘルプコマンドを書き直すのが面倒だから楽に作りたいと思っている
- そもそもヘルプの作り方が分からない

また、本記事のコードはdiscord.pyとpycordのどちらでも動くコードのはずです。

## いざ作成！

discord.pyとそのフォークしたライブラリのPycordの両方で、ヘルプコマンドを作る専用のclassが用意されているのでそれを利用します。結論から言うと、以下のようなコードで実装できます。型が分かりやすいように、typingモジュールをインポートして型ヒントを記しましたが省略しても構いません。

```python
from typing import Mapping, Optional
from discord.ext import commands
import discord


class MyHelpCommand(commands.HelpCommand):

    def __init__(self):
        super().__init__(
            show_hidden=False, # 隠しコマンドを表示するかどうか
            command_attrs={"brief": "ヘルプを表示"} # ヘルプコマンドの説明
        )


    async def send_bot_help(self, mapping: Mapping[Optional[commands.Cog], list[commands.Command]]) -> None:
        """引数なしでヘルプコマンドを実行したときに表示されるヘルプメッセージ ($helpみたいな)

        Parameters
        ----------
        mapping : Mapping[Optional[commands.Cog], list[commands.Command]]
            ヘルプのためにユーザーから要求されたコマンドへのコグのマッピング。
            マッピングのキーはコマンドが属する Cog です。値がない場合は None になり、そのコグに属するコマンドのリストになります。
        """
        e = discord.Embed(title="ヘルプ", description="コマンドの使い方")

        cmds = mapping[None] # コマンドのリストを取得 (Cogを使わないのでNoneを指定)

        for command in (await self.filter_commands(cmds)): # 隠しコマンドを除外
            e.add_field(name=command.name, value=f'> {command.brief}', inline=False)

        await self.get_destination().send(embed=e) # ヘルプメッセージを送信


bot = commands.Bot(
    command_prefix="$",
    help_command=MyHelpCommand(),
    case_insensitive=True, # 大文字小文字を区別しない ($help と $Help は同じ)
    intents=discord.Intents.all() # botの権限
)

@bot.event
async def on_ready():
    """botが起動したときに実行されるイベント"""""
    print("ready")


@bot.command(
    name="hello",
    hidden=False,
    brief="挨拶をする"
)
async def hello(ctx: commands.Context):
    """$hello と実行すると挨拶をするコマンド"""
    await ctx.send("hello")


@bot.command(
    name="bye",
    hidden=True, # 隠しコマンド
    brief="別れ挨拶をする"
)
async def bye(ctx: commands.Context):
    """$bye と実行すると別れ挨拶をするコマンド"""
    await ctx.send("bye")


bot.run("token") # botを起動
```

補足ですが、`get_destination()`メソッドはヘルプコマンドが呼び出された場所を取得しています。

### 実行結果
![スクリーンショット 2023-04-20 162036.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2417130/3d5d9c00-17fc-8d75-9219-cfa737af4c7b.jpeg)

`$bye`コマンドを隠しコマンドに設定しましたが、動作自体はします。ただヘルプには表示されません。

## おわりに

自身でヘルプのメッセージをあらかじめ作っておいてコマンド実行時に送信する方法も良いのですが、それだとコマンドの機能を変更したときにわざわざヘルプコマンドのソースコードへ戻って書き直す必要があります。コマンドが多くなると管理も大変です。そこで、例に示した通りにコマンドの属性とループ処理を上手く活用することで、コマンドを実装したら同時にヘルプにもそのコマンドが反映されて、ヘルプのメッセージをわざわざ書く必要がなくなります。コグを使えばコマンドをグループ化できるので、より凝ったヘルプを動的にかつ簡単に実装できます。参考になれば幸いです。最後まで読んでくださりありがとうございました。

### 参考文献

[公式ドキュメント](https://discordpy.readthedocs.io/ja/latest/ext/commands/api.html?highlight=help%20command#helpcommand)
ORDS22でORDS_PUBLIC_USERのパスワードが期限切れになってハマった件

Oracle Database のパスワード有効期限を無期限に変更し忘れていて、ORDS_PUBLIC_USER が期限切れになってしまった。
ORDS_PUBLIC_USER のパスワードを再設定して期限切れ状態を解除したが、相変わらず ORDS からはデータベースに接続できなかった。
以下のようなコマンドで ORDS にデータベースパスワードを再設定したら接続できるようになった。
```
ords --config C:\hoge config secret db.password
```
※入力プロンプトが表示されて2回入力する。

ちなみにデフォルトだと有効期間180日＋猶予期間7日の187日後に期限切れになるようです。
プリザンターの親テーブルでリンクテーブルのソートを設定画面からやる方法

# はじめに
今回はAテーブル(親テーブル)とBテーブル(子テーブル)という前提でAテーブルのリンクテーブルをあらかじめ設定画面から設定した内容でソートする方法を記載いたします。

# 設定する方法
下記手順で設定することができます。
## 手順
1. Bテーブルの「管理 > テーブルの管理 > ビュータブ」から新規作成ボタンをクリックします。  
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/6d9a334a-09ef-299d-83d6-f98d83e2c20c.png)
2. ソータタブのソート条件を「ソート対象」の「昇順or降順」を指定していただき、追加ボタンをクリックしていただきます。  
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/520585b9-13db-6617-7a72-28e9e0cdef1d.png)
3. 上記、ビューの設定が完了しましたら、同テーブルの「管理画面 > リンクタブ」の「既定のビュー」で先ほど作成したビューを指定してください。  
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/9ca86a32-e816-8aa7-c890-490ca827c7d2.png)
4. Aテーブルの編集画面を開いていただくと、リンクテーブルが勝手に設定したソード順になっているはずです。  
ビューを作成しますと自動的に既定のビューが表示されます。もし、既定のビューが表示されない場合、画面のリロードをしていただくと表示されます。

# さいごに
今回は実装をすることなくソートを行うことができました。プリザンターがノーコードになるのは意外と近いかもしれませんね！
git stash

# git stashとは
git stashは、Gitの機能の一つで、変更内容を一時的に保存することができる機能です。
作業中に途中で修正内容をコミットするのは望ましくない場合があります。

例えば、作業中に別のタスクに切り替えたい場合や、変更内容が未完成である場合などです。

こうした場合に、git stashを使うと、現在の変更内容をスタッシュ（一時的に保存）することができます。スタッシュした内容は、後で再び取り出すことができます。これにより、作業中に他のタスクに切り替えたり、未完成の変更内容を一時的に保存したりすることができます。

使うコマンドは以下の通り。
| コマンド | 内容 |
|:-:|:-:|
| git stash save -u "実験中"  　　　　　| 現在の作業を一時的に退避できる。-uをつけることで新規ファイル作成も一緒に退避する。 |
| git stash list | 退避させているリストを表示する。 |
| git stash apply stash@{n} |番号を指定して、現在のブランチに退避している作業を取り込む。指定しないと最新が取り込まれます。   |
|git stash pop@{n}   |番号を指定して、特定の作業を削除することができます。指定しないと最新が削除されます。  |
|git stash clear   | 退避した作業を全て削除する。  |

保存はローカルにされるので、他人と共有したり、PC自体が壊れた場合は取り出せなくなるので、できる限り早くリモートにpushしましょう。
AWS ArtifactにおけるSOCレポートの勘違いしやすいこと

# 始めに

社内の監査資料としてAWSのSOCレポートが必要になったものの、
"AWS Artifactで出力するレポート"くらいしか理解しておらず
実務でいざ必要になったら、「そもそもSOCレポートって何？」ってなったので
今回備忘も兼ねて内容を簡単に記載しようと思います。

# SOCレポートとは

そもそもSOCレポートとは「System and Organization Controls」の略で
外部委託先の内部統制の状況を確認する為に使用される報告書のことです。
なので、SOCレポートは別にAWS独自のサービスというわけではなく
**世間一般的に内部統制について第三者からの評価をうけた報告書**を言うみたいですね。

報告書の公開の範囲はSOCの種類に応じて異なっており、
SOC1,SOC2,SOC3と3種類あります。
それぞれの内容についての詳しいことは以下記事がかなり分かりやすく
まとめてくださっているので、こちらを確認いただければと思います。
https://dev.classmethod.jp/articles/soc2_overview/

# AWS ArtifactにおけるSOCレポートとは

さて、このSOCレポートですが、AWSのSOCレポートは年に2回
4月～9月のものが11月中旬に、10月～3月のものが5月中旬に発行され
これはAWS Artifactというサービスの利用を開始することで
アカウントごとにダウンロードできます。(無料です)

ここで間違えやすいのですが
AWS ArtifactでダウンロードできるSOCレポートは
**AWS社が第三者機関から内部統制について評価を受けた報告書であり、
自社のAWSアカウントにおけるセキュリティやシステムの可用性などの
統制を評価したものではない**ということです。

なので、各AWSアカウントごとにこのSOCレポートを出力しても
アカウントを識別するためのウォーターマーク(透かし)以外は
同じ内容になるはずです。

私は最初各アカウントで稼働しているシステムについて
コンプライアンス的な観点での評価をしてもらったレポートなのかと
思っていましたが、冷静に考えるとサードパーティー製品まで
確認しきれないと思うのでそんなわけはないですね。

また、このSOCレポートをダウンロードするためには一部
AWSとのNDA(秘密保持契約)が必要になるので
AWSのSOCレポートを社外に共有したい場合は
AWS Artifact からダウンロードした AWS コンプライアンス
レポートの 1 ページ目に記載されている利用規約をよく読んでから
共有可能かどうか確認すべきかと思います。(全部英語ですが)


# 最後に

こういうのはシステムに直接関係しない分参考になる記事が
少なかったので、今回自分が調べた範囲でまとめてみました。
SOCが必要になった皆様に届くと幸いです。

また、今回の記事の内容で間違い等ございましたら
お手数ですが(優しめに)ご指摘いただけますと幸甚です。

以上！
FlaskでREST API CRUD作成。 Curlで結果表示。

### ■完成
・左側画面：サーバーのリクエスト結果
・右側画面：コマンド & コマンド結果表示（Curl）

● post
![スクリーンショット (701).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/afbadec0-84e2-45c3-348d-58f975d9cca4.png)
● put
![スクリーンショット (702).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/d6d8c931-1521-da2c-5b85-a6912cd23627.png)
●delete
![スクリーンショット (703).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/9c52bbdf-7948-7e95-1cbc-3a2f6ce2b102.png)

### ■ソースコード
```python app.py

from flask import Flask, jsonify, request
app = Flask(__name__)

app.config['JSON_AS_ASCII'] = False  # JSONでの日本語文字化け対策

# 大本データ　※ここに、データを追加したり、削除したりしていく。
items = [{'id' : 1, 'name': 'tossy_01', 'price': 1024}, {'id':2, 'name': '夏目智徹', 'price': 8888888888}]

# （表示）GETメソッドで全てのアイテムを返すエンドポイント
@app.route('/items', methods=['GET'])
def get_items():
    return jsonify({'items': items})

#（登録） POSTメソッドで新しいアイテムを作成するエンドポイント　
@app.route('/items', methods=['POST'])
def create_item():
   # JSONを受け取る
    json = request.get_json()
    
    # JSONをパースする
    name = json['name']
    price = json['price']
    item = {'name': name, 'price': price}
    item_id = len(items) + 1
    items.append(item)
    
     # 返却用ディクショナリを構築
    item['id'] = item_id
    return jsonify(item)  # JSONをレスポンス


# （検索）GETメソッドで特定のアイテムを返すエンドポイント
@app.route('/items/<string:item_name>', methods=['GET'])
def get_item(item_name):
    for item in items:
        if item['name'] == item_name:
            return jsonify(item)
    return jsonify({'message': 'エラー 404.'}), 404

#（更新） PUTメソッドで特定のアイテムを更新するエンドポイント
@app.route('/items/<string:item_name>', methods=['PUT'])
def update_item(item_name):
    for item in items:
        if item['name'] == item_name:
            item['price'] = request.json['price']
            return jsonify(item)
    return jsonify({'message': 'エラー 404.'}), 404

#（削除）DELETEメソッドで特定のアイテムを削除するエンドポイント
@app.route('/items/<string:item_name>', methods=['DELETE'])
def delete_item(item_name):
    for item in items:
        if item['name'] == item_name:
            items.remove(item)
            return jsonify({'message': 'deleted OK'})
    return jsonify({'message': 'エラー 404.'}), 404

if __name__ == '__main__':
    app.run(debug=True)



```
プリザンターのエクスポート方式「URLを自分にメール」を設定した際のセキュリティー対策について

# はじめに
プリザンターでエクスポートをする際、エクスポートが終わった段階でメールで通知を送すことができます。これはエクスポート方式をURLを自分にメールに設定することで実現可能です。設定方法は[テーブルの管理：エクスポート](https://pleasanter.org/manual/table-management-export)をご確認ください。今回は設定ができている前提で、セキュリティ問題を解決するSQLをご紹介いたします。

# SQL
```SQL
delete from [Binaries]
where [BinaryType] = 'ExportData'
and [CreatedTime] < dateadd(week,-1,getdate())
```

# 解説
まず、上記の設定をすると「Binaries」テーブルの「BinaryType」列に「ExportData」としてデータが蓄積されます。その際、1週間以上前のエクスポートデータは誰も使用することないということから、そのまま蓄積させるのはDBがひっ迫しますし、セキュリティ上あまりよろしくないため、DELETE分を使って削除するというSQLを作成しました。上記のSQLはBinariesテーブルのBinaryType列がExportDataである行を取得し、今日から1週間以上前のレコードは削除するというSQL文です。
【ニコメア】ニコニコ動画の動画情報を取得するAPIの解説(2023年4月版)

:::note warn
このAPIは2024年1月28日でこのAPIも終了しました
2024年1月現在は下記の記事の方法で取得して下さい
:::

https://qiita.com/vram/items/d70ed02b308fd9e70b2e
 # はじめに
ニコニコ動画の動画IDから動画情報を取得する方法として
 https://api.ce.nicovideo.jp/nicoapi/v1/video.info
というAPIが使用されていましたが
実はこのAPIは3DSから呼ばれるものなのです

# 終わりは突然に
ニコニコ動画では長らく3DSでの視聴も可能でしたが2023年3月31日で終了しました
このためこのAPIが使えなくなってしまいました



# 代わりのAPIは？
ではこれに代わるAPIはあるのかというと
https://ext.nicovideo.jp/api/getthumbinfo/
というAPIがあります。
しかしこのAPIは **JSON** ではなく **XML** で返ってくるためちょっと不便なのとコメントを取得するための **スレッドID** を取得する事が出来ません

# さらなるAPIを探して
ニコニコ動画の視聴時の通信を監視してどのAPIが使われているのかを確認しましたが見つかりません、かなり強敵のようです。※Googleのブラウザに標準で付いてる機能です
ですがここで面白いことがわかりました。
動画視聴時の通信で動画情報を呼び出したときの情報がGoogleの方になぜか残っていました。
Google先生さすがです。

# 新APIの仕様
新しいAPIはこれです
```url.xml
https://www.nicovideo.jp/api/
```
なんかシンプルです。
呼び出すための仕様がありますのでそれを説明すると
```url.xml
https://www.nicovideo.jp/api/watch/v3_guest/
```
動画視聴のための **watch** と バージョン3の情報をゲストとして取得するための **vs_guest** を追加

まだまだ必要です

この後に **sm** で始まる動画ID とユーガーが使用するフロントエンドIDやフロントエンドバージョン番号、さらにトラックIDが必要です。

```url.xml
https://www.nicovideo.jp/api/watch/v3_guest/[smで始まる動画ID?_frontendId=[フロントエンドID]&_frontendVersion=[フロントエンドバージョン]番号&actionTrackId=[トラックID]
```

### トラックID
トラックIDは24文字分の文字列です
文字列は呼び出す度にランダムで生成する必要があります。

最初の10文字は大文字小文字を含める英数字です
次はアンダースコア「_」を1文字
最後は13桁の数字
これを組み合わせた24文字がトラックIDになります

呼び出し方をそのまま書いてしまうとサーバーに迷惑ですので記載していません
呼び出し方さえ説明すれば誰でもアクセス出来ますがこのAPI、現時点でまだ動画視聴側が対応していないようなデータも返してきます。
なお短い時間内に何度もアクセスすると一定時間のアクセス禁止を喰らうと思いますので注意して下さい。
（私はやっていませんがニコニコ動画のAPIはおよそこういう仕様です）

# 返り値の解説
呼び出しに成功すると大量のデータが送られてきます。
```receive.js
  "meta":{
    "status":200
  },
```
ステータスが200なら成功
```data.js
  "data":{
    "ads":null,
    "category":null,
    "channel":null,
```
あとは **data** の中に色々あります
この辺は将来使うデータっぽい

```client.js
    "client":{
      "nicosid":"ニコニコのIDが入る",
      "watchId":"smで始まる動画IDが入る",
      "watchTrackId":"呼び出しに使ったIDが入る"
    },
```
内部IDとかが返ってきます、呼び出す時に使ったトラックIDも返ってきます

```comment.js
    "comment":{
      "server":{
        "url":"コメントサーバーへのアクセス方法が入る"
      },
      "keys":{
        "userKey":""
      },
      "layers":[
        {
          "index":0,
          "isTranslucent":false,
          "threadIds":[
            {
              "id":スレッドIDが入る,
              "fork":1,
              "forkLabel":"owner"
            }
          ]
        },
```
 **comment** のところで親切にコメントサーバーへのアクセス方法まで書いてくれています
**threadIds** のところにコメントを取得する時に使うスレッドIDが入ります
なぜかコメントの大グループにメイン、オーナー、イージーがあります

何がデータの量を増やしているのかというと **簡易コメント** のデータがものすごく多くなっています。さらに簡易コメントとニコニコ大百科がつながっているようです。

視聴するときのプロトコルが複数あったり、解像度情報も複数あるなど盛りだくさんのデータです。

**いいね** はこちらのAPIからの呼び出しで取得出来ているので結構最近のAPIと思われます

# おわりに
簡単に新APIを解説してみましたがこんなこと手動でしなくてもツールもあるのでそっちを使った方が楽です。

https://commons.nicovideo.jp/material/nc289171
GAS 制限 まとめ

## はじめに

GASの制限について、まとめられている記事が無かったので作成しました。  
GAS開発をしている方は、ストックしておくと便利だと思います。

↓ソースはこちら
https://developers.google.com/apps-script/guides/services/quotas  

## 制限一覧

`2023/04/20`　時点

| 機能 | 一般（gmail.com など） | Google Workspace |
| - | - | - |
| カレンダーの予定の作成 | 5,000 / 日 | 10,000 / 日 |
| 連絡先の作成 | 1,000 / 日 | 2,000 / 日 |
| 作成したドキュメント | 250 / 日 | 1,500 / 日 |
| 変換したファイル数 | 2,000 / 日 | 4,000 / 日 |
| 1 日あたりのメール受信者 | 100* / 日 | 1,500* / 日 |
| ドメイン内の 1 日あたりのメール受信者数 | 100* / 日 | 2,000 / 日 |
| メールの読み取り/書き込み（送信を除く） | 20,000 / 日 | 50,000 / 日 |
| グループの読み取り | 2,000 / 日 | 10,000 / 日 |
| JDBC 接続 | 10,000 / 日 | 50,000 / 日 |
| JDBC 接続の失敗 | 100 / 日 | 500 / 日 |
| プレゼンテーションの作成 | 250 / 日 | 1,500 / 日 |
| プロパティの読み取りと書き込み | 50,000 / 日 | 50 万 / 日 |
| スライドの作成 | 250 / 日 | 1,500 / 日 |
| スプレッドシートの作成 | 250 / 日 | 3,200 / 日 |
| トリガーの合計実行時間[*1](#1) | 90 分 / 日 | 6 時間 / 日 |
| URL 取得の呼び出し[*2](#2) | 20,000 / 日 | 100,000 / 日 |
| 静的地図のレンダリング | 1,000 / 日 | 10,000 / 日 |
| Google マップのルートクエリ | 1,000 / 日 | 10,000 / 日 |
| Google マップのジオコード呼び出し | 1,000 / 日 | 10,000 / 日 |
| 通話を翻訳 | 5,000 / 日 | 20,000 / 日 |
| Google マップの高度サンプルのクエリ | 1,000 / 日 | 10,000 / 日 |
| Apps Script プロジェクト | 50 / 日 | 50 / 日 |

#### *1

以下の条件の場合
・トリガー：1分(m)毎に起動　
・GASの処理時間：10秒(s)

1d = 24h * 60m = 1440m
1440m * 10s = 14400s / 60 =  240m

トリガーの合計実行時間 = 240 分 / 日

#### *2

`UrlFetchApp.fetch(URL [, パラメータ])`を使用できる回数  
APIを活用する際のPOSTやGETで使用する    

## その他制限

以下はユーザによって変わらない制限になります。  

| 機能 | 制限 |
| - | - |
| スクリプト ランタイム[*3](#3) | 6 分 / 実行 |
| カスタム関数のランタイム | 30 秒 / 実行 |
| 同時実行 | 30 / ユーザー |
| メール添付ファイル | 250 件 / 通 |
| メール本文のサイズ | 200 KB / メッセージ |
| メール 1 通あたりのメール受信者数 | 50 件 / 通 |
| メールの添付ファイルの総サイズ | 25 MB / メッセージ |
| プロパティ値のサイズ | 9 KB / 値 |
| プロパティの合計保存容量 | 500 KB / プロパティ ストア |
| Triggers | 20 / ユーザー / スクリプト |
| URL 取得レスポンス サイズ | 50 MB / 呼び出し |
| URL 取得ヘッダー | 呼び出しあたり 100 件 |
| URL 取得ヘッダーサイズ | 8 KB / 通話 |
| URL 取得の POST サイズ | 50 MB / 呼び出し |
| URL 取得 URL の長さ | 2 KB / 呼び出し |

#### *3

GASの処理時間のこと

## アカウント料金

念の為料金についても記述しておきます

- 一般ユーザアカウント
  - 基本料金無料
  - gmail.comを所持していればOK
  - 法人利用も可能(セキュリティ保護をするならば有料アカウント推奨)

- Google Workspaceアカウント
  - 1人当たり月680円(Business Starter)
  - 14日間の無料試用期間がある。
  - Business Starter,Business Standard,Business Plus,Enterprise
    上記の4つのプランがあり、順番に料金&サービスが増えていく。
  - [参考](https://workspace.google.com/intl/ja/pricing.html)

## 所感

天下のGoogle様だけあって、無料範囲が非常に広い印象。  
(個人開発する分には非常に助かります)  

大規模なサービスを作るとしたら、現時点でGASでは不安なので、  
個人的にはわざわざ有料でやるメリットは薄いと感じます。  

ただWorkSpaceアカウントにはその他にも特典が沢山あるので、  
そちらも考慮すると良いかもしれません。
kaggle notebookにおいてTensorFlow&PyTorchモデルを用いた際のメモリーエラー解消法

Qiita 初投稿
kaggleのIceCube - Neutrinos in Deep Iceコンペにてソロでシルバーメダルを獲得した際に苦労した点をメモ。

#背景
kaggleのコンペにおいてTensorFlowで作成したモデルとPyTorchで作成したモデルを用いてアンサンブルを行ったら精度が向上した。
しかし、いざsubmitしてみたらOut of Memoryとエラーが表示された。
TensorFlowのモデルで予測した後、下記のコードで余分なメモリーの解放を試みるがダメだった時の解決法のメモ。
```python:メモリーエラーが解決しなかったコード

from numba import cuda

device = cuda.get_current_device()
device.reset()
```
#解決策

```python:
%%bash
source activate base

python tensorflow.py
```
最初に、TensorFlowのモデルでの予測のコードはtensorflow.pyに記述しておき、conda環境にて予測を行う。
```python:

from numba import cuda

device = cuda.get_current_device()
device.reset()
```
その後メモリーを解放してからPyTorchのモデルによる予測を行うとメモリーエラーは解消された。
どうやらGPUメモリをリセットしても残っている何かがあるらしい:rolling_eyes:
GitHub ActionsでAmazon S3にReact appをビルド、デプロイする

難しいことはいらない。
これだけである。


```yml:deploy-react.yml
name: deploy-react

on:
  push:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x]

    steps:
    - uses: actions/checkout@v3

    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ secrets.AWS_REGION }}
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}

    - name: Build
      working-directory: ./web
      run: |
        yarn install
        yarn build
    - name: Deploy app build to S3 bucket
      run: aws s3 sync ./web/dist/ s3://static-skhole-20230325 --delete

```

* 各`secrets`は予めリポジトリの`Settings > Secrets and variables`から追加しておかなければならない。
* Reactのプロジェクトはルートディレクトリではなく`web`ディレクトリにあることを想定している。
* `aws s3 sync`の引数にはビルドしたReactアプリのパスを渡す。今回は`dist`としているが、`build`を指定する場合も多い。
Ubuntuでも箱庭で機械学習するやつを動かそう

こちらの記事の焼き直しですが，Ubuntu（Linux）での環境構築を整備したので，ついでに記事にしときます．

https://qiita.com/kanetugu2018/items/c292ea92ef087bc5e68a

# 環境構築
UnityHubとBlenderをインストールします．
## UnityHub
```bash
sudo sh -c 'echo "deb https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unityhub.list'
wget -qO - https://hub.unity3d.com/linux/keys/public | sudo apt-key add -
sudo apt update
sudo apt-get install unityhub
```

## blender
Blenderのページから[https://www.blender.org/](https://www.blender.org/) Blenderをダウンロードしてきます．保存先は適当なフォルダで大丈夫です．以下x.x.xは適宜バージョンに読み替えてください．

```bash
tar xfv blender-x.x.x-linux-x64.tar.xz
sudo mv blender-x.x.x-linux-x64 /opt/
cp /opt/blender-x.x.x-linux-x64/blender.desktop 
sudo ln -s /opt/blender-x.x.x-linux-x64/blender /usr/local/bin/blender
~/.local/share/applications/
nano ~/.local/share/applications/blender.desktop
```

```bash:blender.desktop
Exec=/opt/blender-x-x-x-linux-x64/blender %f
Icon=/opt/blender-x.x.x-linux-x64/blender
```

# setup
### terminal A (hakoniwa-base)

```bash
git clone -b ai --recursive https://github.com/toppers/hakoniwa-base.git
cd hakoniwa-base
bash native/template/runtime/ai/linux/install.bash
```

### terminal B (ros2sim)

```bash
git clone -b unity-asset --recursive https://github.com/toppers/hakoniwa-ros2sim.git
cd hakoniwa-ros2sim
bash docker/run.bash
---(on docker)---
bash hako-install.bash cpp
```
引き続きこれらのターミナルで作業するので閉じずに残しておきましょう．

# Simulation

### unity
UnityHubの画面からOpenボタンを押し，フォルダ選択からプロジェクトのフォルダの hakoniwa-ros2sim/unity/tb3 を選択します．初回はUnity Editor 2021.3.7f1のインストールを問われるので，そのまま従いインストールしましょう．

次にUnity Editor下部のProjectビューから，Assets/Scenes/Transportを選び「Shm_Configurator.unity」を開きます．その後メニューから「Window/Hakoniwa/Generate」を選択すると設定ファイルが生成されます．

### terminal B
先ほどのTerminal Bで再度hakoniwa-install.bash cppを実行すると先ほど生成された設定ファイルを使っていろいろとええ感じに設定してくれます．

```bash
---(on docker)---
bash hako-install.bash cpp
```

### terminal A
続いてterminal Aに戻り，箱庭のコア機能と制御プログラムを起動します．
```bash
bash native/template/runtime/ai/linux/run.bash
```

### unity
制御プログラムが動いた状態でシミュレーションを開始します．順番を間違うと落ちるので注意です．
まずSceneをSimulation用のものに切り替えます．Projectのウィンドウから，Assets / Scenes / Transport / Simulation.unityを選択して開いてください．
続けて実行ボタン（▷）を押します．画面が実行モードに切り替わり［開始］ボタンとシミュレーション時間が表示されます．
［開始］ボタンを押すとシミュレーションが始まります．初期のうちは学習が進んでおらず，少し動いてはリセットを繰り返しますが，イテレーションが進むと徐々に賢くなってきます．

## プログラムの編集
制御プログラムは ``` hakonwa-base/workspace/dev/ai/ai_qtable.py```がエントリになっています．
そこまで長いプログラムでもないので，ぜひ改造して遊んでみてください！
Vue3のProviderパターン


Vue3のProviderパターンは、typescript環境は結構見かけたのだが
javascript環境でのはあまり見つからず、
試しに作ったローディングスピナーをメモとして残しておく

ちなみにLoadingSpinner.vueのCSSはタグだけ書いて
chatGPTにCSSだけいいように出力してもらったものなので注意

## ディレクトリ構成
```
├ components
| └ LoadingSpinner
|    ├ LoadingSpinner.vue
|    └ loadingStore.js
├ App.vue
└ Chilled.vue

```


## 各ファイルのソース

```vuejs:LoadingSpinner.vue
<template>
    <div v-if="store.isActive() === true">
        <div id="loading-overlay" class="loading-overlay">
            <div class="loading-spinner"></div>
        </div>
    </div>
</template>

<script setup>
import {inject} from 'vue'

import {key} from "./loadingStore.js"
const store = inject(key);

</script>
<style scoped>

/* ローディングスピナーとオーバーレイのスタイル */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 999;
}

.loading-spinner {
    display: inline-block;
    width: 50px;
    height: 50px;
    border: 3px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top-color: #fff;
    animation: spin 1s ease-in-out infinite;
    -webkit-animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

@-webkit-keyframes spin {
    to {
        -webkit-transform: rotate(360deg);
    }
}
</style>
```

```javascript:loadingStore.js
import {ref} from 'vue'

const state = ref(false)
const hide = () => {
    state.value = false;
};

const show = () => {
    state.value = true;
};

const isActive = () => {
    return state.value;
};

export const store = {
    state,
    hide,
    show,
    isActive
}

export const key = Symbol('LoadingSpinner')
```


```vuejs:App.vue
<template>
    <div>
        <Chilled></Chilled>
        <LoadingSpinner/>
    </div>
</template>

<script setup>
import {provide} from "vue";
import Chilled from './Chilled.vue'
import LoadingSpinner from './components/LoadingSpinner/LoadingSpinner.vue'
import {key, store} from './components/LoadingSpinner/loadingStore'

provide(key, store);

</script>

<style scoped>

</style>
```



```vuejs:Chilled.vue
<template>
    <div>
        <button @click="handleClick">ローディング</button>
    </div>
</template>

<script setup>
import {inject} from 'vue';
import {key} from './components/LoadingSpinner/loadingStore'

const loadingStore = inject(key);
const sleep = (second) => new Promise(resolve => setTimeout(resolve, second * 1000))

const handleClick = async () => {
    loadingStore.show();
    await sleep(2);      //2秒間だけsleep
    loadingStore.hide();
}

defineExpose({
    handleClick
});
</script>
```
[翻訳] Nuxt - Announcing 3.0

Nuxt 3.0.0の最初の安定版がリリースされたことを発表できることに興奮しています✨

Nuxt 3は、Vite、Vue3、Nitroに基づくNuxtフレームワークのモダンな書き直しであり、第一級のTypeScriptサポートを備えています。また、Vue開発のための楽しいフルスタック開発者エクスペリエンスを実現するために、2年以上の研究、コミュニティフィードバック、イノベーション、実験の結果です。
[ドキュメントで詳細を読む](https://nuxt.com/docs/getting-started/introduction)

### APIの安定性
Nuxt 3.0.0は安定した本番向けAPIと50以上のサポートされたモジュールを、コミュニティとNuxtチームがNuxt Kitを使って構築し提供しています。
すべてのコンポーザブル、ファイルシステムの規約、および設定は、Nuxt 3.0.0と互換性があることが保証されています。メタフレームワークの性質上、基礎となる依存関係（vite、rollup、nitropack）をアップグレードすると、一部の変更が発生する場合があります。新しいNuxt KitとSchemaツールのおかげで、ドキュメント化された機能を使用している限り、これらのアップグレードは後方互換性があります。KitとSchemaは将来の互換性も保証します。これにより、Nuxtの次のメジャーバージョンを計画するのがより迅速になります。

### ブラウザと Node.js のサポート

Nuxt 3 は公式に、最新のブラウザのみをサポートしています。 "コアブラウザセット" は、特定の制約がない場合に、ほとんどの開発者がほとんどの場合に必要とするものであると私たち（および web.dev チーム）が考えているものです。使用率、開発者の期待、エコシステム内の既存のサポートを考慮しています。コアブラウザセットは、Chrome、Firefox、Edge の直近の 2 つのメジャーバージョンと Safari の直近の 1 年間のサポートを対象としています。

サーバーサイドでは、Nuxt 3 は現時点で Node.js 14、16、18、19 をサポートしています。私たちは、すべての人に最新の LTS リリースの Node.js を使用するよう推奨しています。メジャーなデプロイメントプラットフォームが広く採用されたら、私たちはそれらを押し出します。これは、Nuxt の非メジャーリリースで Node.js チームによってサポートされている限り、Node.js チームがサポートするバージョンを Nuxt で引き続きサポートすることを意味します。14.x は間もなくサポートが終了するため、可能な限り最新の 18.x にアップデートすることを強くお勧めします。

### 私たちはコミュニティが大好きです

Nuxt は、素晴らしいコミュニティが毎日素晴らしいモジュール、フィードバック、貢献をしてくれるおかげで今日のようになりました。参加するには、私たちのコミュニティドキュメントを確認してください！

### 未来へ

Nuxt 3 のリリースは、私たちにとって大きなマイルストーンであり、Nuxt 3 でエンタープライズプロジェクトを構築するユーザーに新しいアイデアと信頼を提供する未来に向けた堅牢な基盤を開くものです。サーバーコンポーネントアイランド、WebSocket レイヤー、新しいデプロイメントプリセット、改善された CLI と DevTools とテストインフラなどが挙げられます。更新のためのロードマップページと GitHub ディスカッションをチェックしてください。
NuxtLabsでは、Nuxt 3をベースにした新しい製品やソリューションの開発が進んでいるとのことです。今後の情報に注目し、楽しみにしていてください。
vue3で追加された新しい機能やアプローチ

Vue 3 には、いくつかの新しい機能やアプローチが導入されています。以下にいくつか例を挙げます。

### Composition API
Vue 3 では、Composition API と呼ばれる新しい API が導入されました。これは、より関心のある機能をグループ化することができるようにすることで、コンポーネントの可読性を高めるために作成されました。また、再利用可能なロジックを作成し、コンポーネントをより機能的にすることもできます。

### パフォーマンスの改善
Vue 3 では、仮想 DOM の実装が改善され、レンダリング速度が向上しました。また、メモリ使用量も削減され、ページのパフォーマンスが向上しました。

### TypeScript のサポート
Vue 3 では、TypeScript のサポートが改善されています。コンポーネントやプロパティに型を付けることができるため、開発者がより安全かつ迅速にアプリケーションを構築できます。

### ディレクティブの改善
Vue 3 では、ディレクティブの扱い方が改善されています。例えば、v-model ディレクティブは、自動的に書き換えられるため、コンポーネントのリファクタリングが容易になりました。

### Tree shaking の改善
Vue 3 では、Tree shaking が改善され、不要なコードを削除することができます。これにより、アプリケーションのバンドルサイズが削減され、ページの読み込み速度が向上します。

これらは、Vue 3 で追加されたいくつかの新しい機能やアプローチの例です。Vue 3 のリリース以降、開発者はこれらの機能を活用して、より高速で効率的なアプリケーションを開発することができます。
SSL証明書の整合性チェックのためのナレッジ

それぞれコマンド叩いて出力されるハッシュ値が同じであることを確認する。

## SSL証明書と秘密鍵

```bash
openssl x509 -noout -modulus -in /path/to/ssl.crt | md5sum
# > ハッシュ値 
openssl rsa -noout -modulus -in /path/to/private.key | md5sum
# > ハッシュ値 
```

## SSL証明書と中間証明書
```bash
openssl x509 -issuer_hash -noout -in /path/to/ssl.crt
# > ハッシュ値 
openssl x509 -subject_hash -noout -in /path/to/interCA.cer
# > ハッシュ値 
```

おわり。
最近TypeScriptが流行っている理由

### 型システムの導入による開発効率の向上

TypeScriptはJavaScriptに静的型付けを追加することで、開発効率を向上させます。型を使うことで、変数や関数の入力や出力の型を事前に宣言することができます。これにより、コンパイル時にエラーを見つけることができ、バグを事前に防止することができます。また、IDEなどのツールにより、型の情報を利用して、コード補完やエラーチェックなどのサポートを受けることができます。

### AngularやReactなどのフレームワークの採用による影響
AngularやReactなどのフレームワークがTypeScriptを採用していることも、TypeScriptの流行を促進しています。これらのフレームワークは、TypeScriptによって開発効率を高め、コードの品質を向上させることができます。

### JavaScriptエコシステムの発展に伴う需要の増加
JavaScriptエコシステムがますます発展していることも、TypeScriptの需要を増加させています。JavaScriptには様々なライブラリやフレームワークがあり、その使用範囲が広がっています。そのため、より高度なJavaScriptプログラミングのニーズが高まり、TypeScriptのような言語が求められるようになっていると言えます。

これらの理由から、TypeScriptは最近急速に流行していると言えます。
今更C#におけるメモリ管理の勉強をする



# 始めに

今までC#におけるメモリ管理のことを意識しないままUnityでの開発を行ってきたのですが、就活をするにあたりこのままではよくないなと思って馴染みのあるC#のメモリ管理について再度勉強をすることにした。

今回はこちらの資料を参考にさせていただきました↓

[https://ufcpp.net/study/computer/MemoryManagement.html?key=stack#stack](https://ufcpp.net/study/computer/MemoryManagement.html?key=stack#stack)

### 【スタック】

積み上げるという**言葉通りデータ領域を積み上げていく形で管理する方式**。

最後に確保した領域を最初に開放する。

### 【ヒープ】

任意サイズのデータ領域を、**任意の順序で確保/解放する方式**。（スタックが整然と積み上げていくイメージなのに対して、ヒープは乱雑に山積みされているイメージ）

ヒープは以下のような場合に利用する。

- データを必要とするスコープ(データの利用範囲)がはっきりしない場合
    - 例：データがさまざまな箇所から参照されている場合
- 実行時にしかサイズが確定しない場合
    - 例：利用者からの入力に応じてサイズを変える必要がある場合
- 必要サイズがかなり大規模な場合

ローカル変数はスタック上に値を置く。

それが「値型」の場合、**値すべてがスタック上**に置かれる。

 一方、「参照型」の場合、**実際の値はヒープ上に置かれ、そのヒープ上の場所への参照情報（「ポインター」 ）だけがスタック上に**置かれる。

### 【ヒープの管理方法】

ヒープを利用するときに**メモリリーク(**用済みのデータ領域を解放しないでそのままにしておくこと**)**や**二重解放**(すでに解放済みの領域を再度解放しようとすること)と呼ばれる問題を起こしてしまうことがある。そんな大変なヒープの管理を自動化してくれる手法の内の1つが**ガベージ・コレクション。**

### 【ガベージ・コレクション】

定期的に用済みのデータがないかを調べて、あった場合には解放をしてくれる。

(ガベージ・コレクションにはいくつか方式があるがここでは扱わない。別記事でいつかまとめたい)

C#はガベージコレクションを使える言語なのでメモリ管理は**基本的には**ガベージ・コレクションに任せた方が手動よりも高性能。

が、ガベージ・コレクションを利用すると**処理が走ったタイミングで負荷が1点集中する**ため重くなることがあるうえに、ガベージ・コレクションは**いつ処理が走るかわからない**。そのため、急にガベージ・コレクションが走り、一時的に性能が落ちることがある。

そこで、

**ガベージ・コレクションを明示的に行う方法ってないのかな…**

って思って調べてみたらちゃんとあった。

以下ガベージ・コレクションを明示的に行う方法

[https://learn.microsoft.com/ja-jp/dotnet/api/system.gc.collect?view=net-7.0](https://learn.microsoft.com/ja-jp/dotnet/api/system.gc.collect?view=net-7.0)

じゃあ

**ガベージ・コレクションを強制的に走らせない方法はないのかな…**

って思って調べたら以下のドキュメントを発見した。

[https://docs.unity3d.com/ja/2020.3/Manual/performance-disabling-garbage-collection.html](https://docs.unity3d.com/ja/2020.3/Manual/performance-disabling-garbage-collection.html)

ドキュメントからの引用になるが、

> ガベージコレクションを無効にするのはアプリケーションの中でも短い時間、パフォーマンスが重要な部分だけで、必要なメモリの割り当て量を計算して制御することができる場合にすべきです。その後、すぐにガベージコレクションを有効にし、プロジェクトを頻繁にプロファイルして、マネージヒープが大きくなりすぎる原因となる追加のマネージアロケーション (割り当て) が発生しないようにする必要があります。
> 

とある通り、ガベージ・コレクションを無効にするタイミングはかなり慎重に選ばないといけないし、その後の処理もしっかりとケアしてあげないといけない。

明示的に無効、有効にすることはできるが適切な処理を加えないとまずいよって話なのでほんとに特になにも問題がない場合はガベージ・コレクションを明示的にいじる必要はない。

そんなガベージ・コレクションにも限界はある。

ガベージ・コレクションが「このデータはもういらないから解放しよう」って判定するのはあくまでも「**有効な領域から参照されていないデータ**」なので必要がないのに参照し続けると判定されずに解放されない。

例えば、寿命の長い(ずっと使い続けている)メモリ領域から、寿命の短いメモリ領域を参照している場合、本来ならすぐに解放していいはずの寿命の短いメモリ領域が寿命の長い領域に合わせていつまでも解放されないで残ってしまう。

# 最後に

Unity、C#を学び始めたころからもっとちゃんとここら辺の勉強をしておけばよかったなと後悔していますがそんなこと言っても仕方がないので今からでも勉強していきます。

読んでくださりありがとうございました。
引き続き頑張ります。
ChatGPTはコンテンツマーケティングのあり方をどのように変えるか？

ChatGPTのようなAIモデルは、コンテンツマーケティングに大きな影響を与える可能性があります。以下に、ChatGPTがコンテンツマーケティングのあり方を変える可能性のある点を挙げてみます。

### より高品質なコンテンツが提供されるようになる
ChatGPTは自然言語処理の技術を使って、高品質な文章を生成することができます。このため、記事コンテンツ提供メディアがChatGPTを活用することで、より高品質なコンテンツを提供することができるようになるでしょう。

### より多様なコンテンツが提供されるようになる
ChatGPTは様々なトピックやジャンルに対応することができます。そのため、記事コンテンツ提供メディアがChatGPTを活用することで、より多様なコンテンツを提供することができるようになるでしょう。

### より効率的なコンテンツ制作が可能になる
記事コンテンツ提供メディアがChatGPTを活用することで、より効率的なコンテンツ制作が可能になります。ChatGPTは短時間で大量の文章を生成することができるため、記事のライティングや翻訳などの作業に活用することができます。

### より個別化されたコンテンツが提供されるようになる
ChatGPTは、ユーザーの入力に応じて、個別に文章を生成することができます。そのため、記事コンテンツ提供メディアがChatGPTを活用することで、より個別化されたコンテンツを提供することができるようになるでしょう。

以上のような変化が予想されますが、ChatGPTはまだ発展途上の技術であるため、具体的な変化は今後の発展によって変わってくる可能性があります。
ファイルパスの書き方（カレントディレクトリとルートディレクトリ）

相対パスを指定する時、"./"の意味を勘違いしていたのでメモ。

結論："./"の意味は、カレントディレクトリの中という意味。

例えば以下のようなディレクトリ構成の場合
※publicフォルダがルートディレクトリ
![ディレクトリ構造.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/f71aeaa8-29b0-817d-6b8d-b71eaf3b4a00.png)

＜view/players/index.htmlでpublic/js/script.jsを呼び出したい場合＞
正解：/js/script.js
★先頭が"/"の場合、ルートディレクトリを示す。

私の間違え：./js/script.js
先頭が"./"の場合、カレントディレクトを表しているが、
意味合いとしては"カレントディレクトの中"という意味になる。
→絶対パスで表すと、view/players/js/script.js になってしまう。

参考サイト：
https://www.tohoho-web.com/ex/draft/path.htm
駆け出し🔰

こんにちは🌞
駆け出しエンジニアとして一歩踏み出し、Qiitaを始めてみました。
これから大変なことが山ほどあるかと思いますが、そんな時初心を思い出せるようにここに決意表明しようと思います🙌✨

👩‍💻エンジニアを目指したきっかけ
SEの友人が飲み会で20-30分でサイコロ(しかも音もでる！)を作っていて、素直にかっこいいと思い、そこから興味を持ちました。

👩‍💻目指すエンジニア像
長年学習してきた英語を活かし、ゆくゆくは海外からの案件にも対応できる、グローバルなエンジニアになりたい！！

👩‍💻今勉強していること
→技術
・HTML 
・CSS
・JavaScript
・Ruby
・Ruby on Rails
・Photoshop
・Illustrator

→資格
・基本情報技術者(目標:2023年中に取得)
・webデザイン技能検定(目標:2024年6月取得)
・CCNA(目標:2024年中に取得)

👩‍💻作成したいもの
・友人のタトゥーショップのwebサイト
・実家のお店のwebサイト
・自分のポートフォリオサイト


大人になってから、机に向かって勉強するとは去年まで思っていたなかったけれど知らないことが沢山あって日々勉強で楽しい毎日です✨
駆け出しの方、ぜひ一緒に頑張りましょう🙋‍♀️🔰
ChatGPTはワールドトリガーを知らないのか

# ブラウザ版のChatGPTとWikipedia＋APIで回答精度を比較

ブラウザ版のChatGPTと、Wikipediaのページをプロンプトに与えたAPI版で、漫画「ワールドトリガー」の基本的な知識を正確に回答できるか、雑ですが検証してみました。

## ブラウザ版(`GPT-3.5`)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311319/f25e93c8-d7b2-261d-6413-a200d309c5e0.png)

・・・
三雲修が主人公ということと、ボーダーに所属している情報は正しいものの、
家族については誰ひとり合っていない結果に…
似たようなタイトルの他の漫画やアニメがあるんでしょうか…



## ブラウザ版(`GPT-4`)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311319/1cdc9bb2-8e63-6e31-3133-d275b3d01189.png)

GPT-4でもダメでした・・・
（雨取）千佳は惜しいのですが、こちらも全員不正解…
GPT-3.5とも異なる結果なので、他に似たようなタイトルの漫画があるわけでもないのかも。

人物（修）と所属（ボーダー）の関係は学習しやすいのでしょうか。

## Wikipedia＋API (`gpt-3.5-turbo`)

こちらの<a href="https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb">notebook</a>を参考にして、APIで試してみました。
以下のWikipediaのページ情報をプロンプトに加えました。

https://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC

`openai.ChatCompletion`で同じ質問をしてみた結果、、、（実際の出力には改行は含まれません）

```
三雲修の家族は、母親の三雲香澄と元家庭教師である兄の雨取麟児、
そして彼の妹である雨取千佳です。
```

- :white_check_mark: 父親の記載が無くなった
- :white_check_mark: 母親の名前が正確に
- :warning: 雨取麟児が兄に
- :warning: 雨取千佳が妹に

それぞれの名前自体は実際の登場人物のものになりましたが、名字の異なる兄と妹がいる設定になってしまいました…

## 感想
今回の質問内容自体は最近の情報ではなく、ChatGPTの事前学習に含まれていてもよい内容なので、Google検索など外部ツールを組み合わせたり、ファインチューニングが必須というわけではないと思いますが、LangChainの勉強も兼ねて次回試してみたいと思います。
<Stack Monitoring②> Oracle Databaseを監視する

オンプレミスやクラウド上のOracle Databaseを監視する方法として、OCIでは下記2つのサービスを使用することができます
- [Database Management](https://qiita.com/western24/items/c391afbf51951424b35f) 
- Stack MonitoringによるDatabaseのメトリック監視　

Database Managementは、総合的なOracle Databaseのリソース・パフォーマンス監視サービスとして独立して提供され、今回紹介するStack Monitoringと同等のメトリック監視の機能も内包されています
一方でStack Monitoringは、Oracle Databaseに限らずOSやミドルウェア等のメトリックを幅広く監視するサービスとして提供され、Windows、SQL Server、Weblogicといった対象の監視も可能です

監視対象がOracle Databaseの場合、用途に応じて使い分けるのが良いかと思います
例えば、死活監視、CPU、Diskといったリソースの枯渇に対するアラート通知までというだけあればStack Monitoringのみ、DBのアクティブ・セッションやSQLレベルで詳細にパフォーマンス分析が必要ということであればDatabase Managementを使用等

ここでは、Stack MonitoringでOracle Databaseを監視する手順を紹介します

## Oracle DatabaseのOSを監視
まず最初に、対象となるOracle Databaseのサーバーに管理エージェントをインストールことが必要。手順は[こちら](https://qiita.com/western24/items/409d93b911c7094f5137#%E7%AE%A1%E7%90%86%E3%82%A8%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%B3%E3%83%88%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)を参照
- インストール完了後、OCIメニューから監視及び管理 -> 管理エージェント-> エージェントにある追加されたDBサーバーのエージェントを選択し、Stack Monitoringのプラグインをデプロイする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/965002ce-2921-b236-6b0f-9e9bbb6c8c44.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b2d32a22-a89f-4051-2dec-a8224e290487.png)

- 有効化後しばらくすると、OCIメニューからAPM -> スタック・モニタリング -> 完全モニタリングにプロモートにDBサーバーのホストが表示されるので、プロモートを実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/997ac8fe-4416-73d8-8576-23da6dc5c624.png)

- プロモート実行後、スタック・モニタリング　-> すべてのリソースに対象のDBサーバーのホストが表示されるようになり、CPUやメモリといった基本的なOSメトリックを参照できるようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/c103aedb-24a4-6679-b725-2c2ac19e7173.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/27c2370a-059f-536f-1daf-41335f1c643f.png)


## Oracle Databaseインスタンスの監視
- OCIメニューからAPM -> スタック・モニタリング -> リソース検出から新しいリソースの検出をクリックする。リソース・タイプをOracle Databaseを選択し下記を入力し検出を実行 (※MTAの場合はCDB)
リソース名 -> 任意、管理サーバー・ホスト -> DBのホスト名
ポート -> リスナーのポート、サービス名 -> リスニングしているサービス名
プロトコル -> TCP、監視ユーザー名/パスワード (※特にこだわりがなければSYSTEMやSYS)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/e61686f2-a7e8-e888-bc00-a532409ff152.png)


- 検出が成功すると、チャートからOracle Database用の39種類メトリックを参照することができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/72235953-134e-ca18-6f3f-f1cb3d4ad0fc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/d7c7c23f-ed73-1f45-b1d0-3a9d673c0b8a.png)


- PDBの場合は、リソース・タイプをプラガブルDBを選択し、先に作成しておいたCDBを指定する。PDBの場合も39種類のメトリックが参照できCDBとの違いはない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/241851a2-ee03-aa8c-6168-0533bdc60b2a.png)

これらのメトリックは、メトリック・エクスプローラーでも参照することができるので、しきい値を設定してアラートするということのも可能です。[こちら](https://oracle-japan.github.io/ocitutorials/intermediates/monitoring-resources/)を参照

まだまだサポート対象となるリソースが少ないStack Monitoringですが、随時新しいターゲットが追加されています。OCIリリース・ノートから最新のサポート状況を定期的にチェックしてみると良いかもしれません。
ASP.NET Core で空の配列がnullになってしまう場合の対処方法

JavaScript上では空の配列なのに、サーバに送信されるとnullになってしまう。この原因を探るために、ASP.NET Core MVCのControllerが、クライアントからのpostをどのように引数のモデルにバインドするかについて調べた結果をまとめておく。

# やろうとしていること

クライアント（JavaScript）から以下のようなデータを送信したい。

```json
{
	prop1: 123,
	prop2: "abc",
	list: [],
}
```

ASP.NET Core MVC側では以下のように受け取りたい。

```C#
public async Task<IActionResult> Update(MyModel model)
{
    foreach( var item in model.list)  // ★ここでNullReferenceExceptionが起こる
    {
        // item に対する処理
    }
}
```

model.list == null の時に何もしないif文を追加するか、以下のようにNull合体演算子を使えば例外を回避できるが面倒だしコードも読みづらくなる。

```C#
public async Task<IActionResult> Update(MyModel model)
{
    foreach( var item in model.list ?? new List<MyList>()) 
    {
        // item に対する処理
    }
}
```

# 気になる点

- list が null にバインドされてしまう。どうして空の配列のままにならないのか？
- ASP.NET Coreのモデルバインディングで何か設定があるのか？

# 原因（調べた結果）

- ASP.NET Coreは規定で`application/x-www-form-urlencoded`、つまりフォーム形式のデータをバインドする。
- その為、JavaScript側でも、`application/x-www-form-urlencoded`で送信している（`$.post`を使用）。
- しかし、`application/x-www-form-urlencoded`形式では空の配列を表現できない為、そもそもlistプロパティが送信されず、受け取り側でnullとして認識する。
- つまり、これはASP.NET Coreのモデルバインディングの問題ではなく、JavaScript側の送信時の問題だった。

# 解決策

フォーム形式ではなく、JSONデータとして送信すれば良い。JSONデータの場合、空の配列を正しく表現できる為、空の配列のまま送信され、受け取り側でも正しく受け取れる。

しかし、その為には、アクションメソッドの引数に`[FromBody]`属性を付ける必要がある。FromBody属性は、その引数をリクエストボディからバインドしようとする。この時JSON形式のデータをバインドすることができるようだ。

```C#
public async Task<IActionResult> Update([FromBody] MyModel model)
```

送信側のJavaScriptは、以下のようにする。

```javascript:$.ajaxでjson送信
const sendData = {
	prop1: 123,
	prop2: "abc",
	list: [],
}

const response = await $.ajax({
	url: url,
    method: "POST",
    contentType: "application/json",
    data: JSON.stringify(sendData),
});
```

fetchを使う場合は以下のようにする。

```javascript:fetchでjson送信
const response = await fetch(url, {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
    },
    body: JSON.stringify(sendData),
});
const ret = await response.json();
```

尚、これまでは以下のように`$.post`を使っていた。`$.post`は規定で `application/x-www-form-urlencoded` でオブジェクトを送信してくれるようだ。

```javascript:$.postでform送信
const sendData = {
	prop1: 123,
	prop2: "abc",
	list: [],
}

const response = await $.post(url, {
    model: sendData,
});
```

上記の場合、アクションメソッドに`[FromBody]`を付けているとエラーになる。

# 余談

ちなみに、ASP.NET MVCの頃は、FromBody等付けなくとも、フォーム形式でもJSON形式でも自動的に判断してバインドしてくれていた。
その記憶があった為、少し混乱したが、ASP.NET Coreになってその辺の仕様がセキュリティの観点から見直されたようだ。
現在では、JSON形式でもフォーム形式でもどちらでも受け取れるようなアクションメソッドを作るには、カスタムバインディングを作成して自力で対応するしかない。

詳細はこちらの記事が詳しい。

https://andrewlock.net/model-binding-json-posts-in-asp-net-core/
提案依頼書（RFP）チェックリスト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/9bbfef21-ee09-3106-09ca-40a9120e0536.png)

<h2>1. 提案依頼書チェックリストとは

提案依頼書（RFP）チェックリストは、RFPの作成と完了に必要なステップ、情報、文書をカタログ化したものです。RFPチェックリストを使用することで、戦略的ソーシングおよび調達マネージャーは、一貫性の向上、リスクの軽減、RFPプロセスの整理が可能になります。

<h3> 2種類のRFPチェックリスト： 1つはあなた用、もう1つはベンダー用

調達担当者であれば、RFPを作成・管理する際に、包括的で時系列的なToDoリストがどれほど役立つかをご存じでしょう。同様に、ベンダー候補も、RFP文書に含まれる提案書チェックリストが役に立ちます。この外部向けチェックリストは、ベンダーが最終的なRFPのコンプライアンスレビューを行う際に、RFPの要件を段階的に説明するのに役立つものです。

RFPチェックリストは、複雑な書式、回答、文書化要件がある戦略的ソーシングRFPに追加すると、特に役立ちます。実際、ベンダー向けのRFPチェックリストを含めることは、提案書の品質と全体的なコンプライアンスを向上させる簡単な方法です。

この記事では、主に調達実務者のプロセス管理に役立つ社内用RFPチェックリストに焦点を当てます。しかし、以下ではその両方の例を紹介します。

<h2> 2. 4 RFPチェックリストのメリット

<h3> 2.1. 一貫性の向上

デジタルトランスフォーメーションによって調達チームの意思決定の方法が変化し続ける中、データはプロセスにとってますます重要になります。RFPのタイムラインから提案書の価格表まで、各ベンダーの回答には何百ものデータポイントが含まれており、一貫性が重要です。一人のチームであれ、大勢のチームであれ、RFPから次のRFPまで同じプロセスを踏むことは、正確で信頼できるデータを収集するために極めて重要です。したがって、プロセスを標準化し、一貫性を確認することは、非常に重要な優先事項です。

<h3> 2.2. 情報の一元化

RFPソフトウェアを使用してRFPプロセスを一元化していない場合、文書の検索に多くの時間を費やしていることに気づくかもしれません。RFPツールキットと同様に、RFPチェックリストは、重要なテンプレート、ガイド、添付書類、補遺にリンクさせることができます。例えば、チェックリストと要件発見アンケート、RFP採点ガイド、賞状テンプレートなどとのリンクを検討してください。

<h3> 2.3. リスクを低減

RFPプロセスの多くのステップは、お客様のビジネスを保護するために存在します。ベンダーの多様性に関する質問から、ベンダーのリスク評価まで、正しい情報や質問を誤って省略すると、大きな損害が生じる可能性があります。そのため、RFPチェックリストを使用することで、各リクエストに必要不可欠なポリシーや条項がすべて含まれていることを確認できます。

<h3> 2.4. 追記事項の削減

RFPが発行された後に、変更が生じることはよくあることです。残念ながら、この場合、プロセスを公正かつ効果的に維持するために、補遺を作成し、ベンダーに発行しなければなりません。RFPチェックリストを使用すれば、最初のRFPにすべての内容が含まれていることを確認できるため、発行しなければならない補遺の数を減らすことができます。

▼「RFP」についてもっと知りたい方はこちらの記事もご参照ください。
https://miichisoft.com/what-is-rfp-easy-to-understand-explanation-of-requirements-andsamples/

Website: https://miichisoft.com/
プログラミングでどうしても理解できなかったソースコードの意味をAIのBardやChatGPTで理解する方法！

# AIでソースコードを理解する
私はプログラミング初心者です。今日までプログラミング学習サイトでコードを写経してました。けれどあとでコードを見ても全く意味が分かりません。１文の意味を理解しようと、ネット検索してもソースコードの解説が的を外れており（私のレベルが低いだけかもですが・・・）頭に入らない・・・。何度読んでもプログラミング技術を有効活用できる最高の武器であるソースコードを解読できないつらさが続きました。英語での記事を読むといいよとか検索して調べればわかるとちまたでは聞きます。ですが、私はどうしても日本語での解説がほしかったし、端的に正解を述べてくれるものがほしかったです。普通の記事では理解不能でした。ソースコードを読み解く技術そのものを理解したい人は例えばまず次の記事を読んでみてください。<p><a href="https://qiita.com/zizynonno/items/3a14fe6cbf52451a366c">ソースコードを読むための技術（チートシート）</a></p><p><a href="https://boukenki.info/sorce-code-oikata-yomikata-houhou-kotu-matome/">ソースコードの追い方、読み方の方法やコツをまとめておく</a></p><p><a href="https://zenn.dev/okmttdhr/articles/78af1e87cbd9d0">大規模なソースコードを理解する</a></p>
上のようなリンク先の記事を「読んでも理解できないです。ソースコードをそのものの意味が端的に知りたい。人に聞きたいけど聞く機会がない」などの方はこのまま読み進めてみてください！きっと役立つと思います。
# AIをプログラミングに利用しよう
　わかる人に聞きたいけど聞けない場合、ソースコードの意味を単刀直入に知りたい方のための有力な解決策がわかりました！BardやChat GPTなどのAIに１文ごとに質問することです！私はPython3を学習しておりますのでその言語を用いてデモを以下にします。
例えば「def known(self, unknown)」というソースコードがわからないとします。そのコードをそのままChatGPTにぶっこんで「def known(self, unknown)はPython3で何を意味する」と質問します。時短のために敬語は使いません。１文全部入力してみたら回答を日本語で説明してくれます。ソースコードの文章全体での解説もしてくれるようなのでソースコードの全部がわからないときはそのまま全部入力してみましょう。

![スクリーンショット (785).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291948/8a85eccb-44f6-2f52-5fd7-c2b85b3e0243.png)



Google Bard でも質問してみました！つたない英語で文を作ってみます。「def known(self, unknown)　means in PYTHON3」と質問しました。ちなみに回答は英語です。![スクリーンショット (783).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291948/8f193a0c-88f2-e09c-3eec-52b7ca0f5662.png)

同じ質問をするとChatGPTは１つの観点でのみ回答してくれるのに対して、Google Bardは３つの違った観点で回答してくれるのが売りのようです。違う観点で説明されたほうが内容が深まりますね。Bardはコードのコメントも書いてくれます。ソースコードまるまる全部の１文ごとの全文対象の解説コメントもしてくれます。ソースコード1文ごとにすべてのソースコードに#でコメント解説してくれます！けれどBardは英語でしか対応してないので日本語でのリリースを待ちどおしいですね！

個人的には2つのBardとChatGPTに聞くことでセカンドオピニオン的な感じで使うことで理解度と正確性を担保しようとしております。そのためにBardとChatGPTの2つを併用して使っています。

ChatGPTを使用した場合の詳しい記事は以下がよいです↓<p><a href="https://note.com/fladdict/n/n5d3a9c47aa3d">AIにコードまるごと解説してもらうと、界王拳100倍すぎる件</a></p>

注意：プログラミング学習サイトでの情報漏洩のリスクの説明がある場合は規約を守り、ソースコードをそのまま入力することはやめましょう。

では、楽しんでください！
Obsidian と Notion を比較した場合、それぞれメリットとデメリット

ObsidianとNotionは、両方ともプロダクティビティツールであり、それぞれのユースケースに応じてメリットとデメリットがあります。

### Obsidianのメリット

- ローカルで動作するため、ネットワーク接続が必要なく、安全性が高く、プライバシーが保護されている
- Markdown言語により、ファイル形式がシンプルで移植性が高く、互換性が高い
- ファイル間のリンク機能が強力で、複数のノートを組織的に管理できる
- プラグインにより、多様な機能を拡張することができる

### Obsidianのデメリット

- その高度なカスタマイズ可能性から、初心者には使い方が難しいことがある。
- ビジュアルな要素が少なく、Notionのような豊富なブロックエディター機能はない。

### Notionのメリット

- 豊富なブロックエディター機能により、ユーザーは直感的かつ視覚的にノートを作成、編集することができる
- カスタマイズ可能なテンプレートが多数あり、チームのコラボレーションを容易にすることができる
- データベースの機能を使用して、タスクリストやプロジェクト管理などのタスクを追跡することができる

### Notionのデメリット

- オンラインツールであるため、ネットワーク接続が必要であり、プライバシー保護の問題がある
- 使い方が簡単な反面、ブロックの多様性が過多で、使いこなすにはやや時間がかかる場合がある
- プレミアムプランにおいて、個人ユーザーにとって高価な場合がある

以上のように、ObsidianとNotionにはそれぞれのメリットとデメリットがあり、ユースケースに合わせて選択することが望ましい
Google Bard ガイドブック

# Bard
Googleの大規模言語モデル

# 触った感じ
日本語は喋れない？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/84c3ed60-3a9e-8356-58ad-c39cc2833d03.png)
「はい、日本語で話せます」とおっしゃいながらバリバリ英語でお話されるようです

プログラミングに関して
「discord.jsでdiscord Botを作れ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/82fa0d22-58dc-a939-8b08-ed41cd645782.png)
これはだめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/fc5a5aa5-04a8-0724-4df0-f52caf147528.png)
なぜかこれはOK
どういう違いが？
コードを見た感じおそらくChat GPTのほうがコーディングは強いと思われる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/2771818f-e996-d457-7a3c-a86447d3fad2.png)
翻訳はできないよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/ad91a9ba-c1aa-bee8-9312-471acd5d1059.png)

時事ネタに関してはあんまり強くないかもしれない
多分混同しちゃってる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/e20eeaba-0f02-35e3-0e0f-f661ce6b6680.png)
う〜ん…
constに代入しているプログラムなのですが…
もしやコーディングはかなり苦手なのか…と思いきや
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/7072c16c-038f-ab97-f23e-c5c872a0681c.png)
エラーあるよ、と指定してあげれば間違ってます、とわかってくれました。

Web閲覧はできるみたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/8a57425e-b46e-7d8d-d00f-cb9cbcd26f77.png)
私のTwitterから情報を掘り出してきてくれました
（なお一回目はありませんと言われました。「yes it is」といえば生成してくれました）
なんか間違ってますけどね

# Bardが変なことを言い出したら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920761/d6f53ce6-a3a2-8bc7-b2f2-42ac85fd8085.png)

だいたい「forget all」などと入力したら治ります

多分追記する
AccessのVBAでコンボボックスの選択肢数に応じて初期化

# 概要

コンボボックスの選択肢をVBAで動的に生成。

そして…

* 選択肢が1つだけなら、その値を選択状態にしておく。
* 選択肢が2つ以上なら空の選択肢を追加して、その値を選択状態にしておく。

のような切り替え。

# コンボボックスの動的設定

詳細は下記参照。

https://qiita.com/waokitsune/items/cc861fb12d987074cf45

# サンプル（列が1つ）

```vb
'フォーム開いた時の動作。
Private Sub Form_Open(Cancel As Integer)

    'フォーム上に『cmb_1』という名前のコンボボックスがある前提。
    
    '選択肢を動的に設定。
    Me.cmb_1.RowSourceType = "Value List"
    Me.cmb_1.RowSource = ""
    Me.cmb_1.ColumnCount = 1
    
    '選択肢追加。
    Me.cmb_1.AddItem "あ"
    
    '下記コメントアウトを外すかどうかで動作が変わる。
    'Me.cmb_1.AddItem "い"
    
    '選択肢の数によって初期選択などの切替。
    If Me.cmb_1.ListCount = 1 Then
        Me.cmb_1.Value = Me.cmb_1.ItemData(0)
    Else
        Me.cmb_1.AddItem ""
        Me.cmb_1.Value = ""
    End If
    
End Sub
```

選択肢が1つだけなら下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/32947ffb-edb8-6c62-120d-551b5191c754.png)

選択肢が2つなら下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/612a9539-8ab0-9728-7403-d000fe9b4414.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3535388e-d84a-ec4a-cb8d-1ffde5af9fc7.png)

# サンプル（列が2つ）

```vb:
'フォーム開いた時の動作。
Private Sub Form_Open(Cancel As Integer)

    'フォーム上に『cmb_1』という名前のコンボボックスがある前提。
    
    '選択肢を動的に設定。
    Me.cmb_1.RowSourceType = "Value List"
    Me.cmb_1.RowSource = ""
    Me.cmb_1.ColumnCount = 2
    
    '選択肢追加。
    Me.cmb_1.AddItem "あ;あです;"
    
    '下記コメントアウトを外すかどうかで動作が変わる。
    'Me.cmb_1.AddItem "い;です;"
    
    '選択肢の数によって初期選択などの切替。
    If Me.cmb_1.ListCount = 1 Then
        Me.cmb_1.Value = Me.cmb_1.ItemData(0)
    Else
        Me.cmb_1.AddItem ""
        Me.cmb_1.Value = ""
    End If
    
End Sub
```

選択肢が1つだけなら下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/270c574d-b5b3-da9f-cb83-d0398f45251b.png)

選択肢が2つなら下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ff06b64d-05b9-fbe1-6211-1ecd470d35f7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f170eacc-2ca1-02ef-9f4e-409fee58daf0.png)

# ポイント

## 選択肢の『数』を変数で持っておく必要は無い

```Me.コンボボックスの名前.ListCount``` で取得できる。

## 選択肢の『値』を変数で持っておく必要は無い

一番上の選択肢でよければ ```Me.コンボボックスの名前.ItemData(0)``` でよい。

## 列数に依存しない

前述のサンプルたちを参照。

# 参考サイトさん

https://waq3-travelog.com/select-the-first-row-in-advance/

# バージョン

Windows 10 Pro 22H2 19045.2846
Microsoft Access for Microsoft 365 MSO (バージョン 2303 ビルド 16.0.16227.20202) 32 ビット