OmniAICreator/Qiita-1.07M huggingface dataset:
自動運転を体験してきた！

このブログは「RPA Advent Calendar 2024」の１日目 の記事です。

[≫ 明日の記事はこちら](https://qiita.com/Kerdy/items/cc8ce3249fca06338e41 "WinActorでPythonライブラリを使う方法")

https://qiita.com/advent-calendar/2024/rpa

# 自動運転車両の定期運行が始まると聞いて
実は近所に、[**STATION Ai**](https://stationai.co.jp/info) なる施設ができまして。
[**あいち自動運転シャトル**](https://ssw.web.docomo.ne.jp/trmi2024/) という自動運転の実証実験が始まるということがニュースに出てからは、かなりチェックしておりました。

……なぜかって？
それはこの **アドベントカレンダーのネタになる** と思ったからです！

最先端の自動化の技術にも触れられて、ネタにもなるなんて一石二鳥じゃんと思いながら、予約を入れさせていただきました♪
# 予約の流れ
運行カレンダーで空き状況を確認してから、別の予約サイトにて申込する流れでした。
利用される場合は、[**利用詳細**](https://ssw.web.docomo.ne.jp/trmi2024/files/detail.pdf) をよーく確認したほうがよさそうです。

私と同乗した人たちの中には事前にルールを確認していなかった人もいて、イライラしている方もいました。（ちゃんと明記はされている内容でしたが……私も確認できていなかった😅）

特設サイトの作りや予約の仕方や確認メールなどの **情報への導線** が分かりづらかった印象です。（前日の事前確認メールだと迷惑メールに振り分けられる場合もあった）

ここは改善の余地があるところでしたね。
# 乗車について
予約の日になったら、STATION Aiの指定の乗車場で待機です。
特に看板での案内がなかったので、駐車場を探しての乗車になりました。
詳細案内には明記されていたので迷わなかったですが、標識的なものはあってもいいかなと思いました。

予約時間の５分前になったら乗車可能となります。
１枠４席あるのですが、奥から詰めての乗車になりました。
席についたら、目の前の「チェックイン」用のQRコードを読み取って、出発時間まで待ちます。

ちなみに予約通りに人が来ない場合は前の席に移動可能となります。
ちょうど前の席に座るチャンスをいただけたので席を移動して楽しませていただきました！
# 車の中では
後部座先用に、中央上部にモニターが設置してあり、自動運転車両が現在どういう判定をしているかが常に表示されていました。

判定内容については、信号の表示状況、人間の判定、それ以外の物体の判定という３点を見ている感じでした。

最後の項目は車両の判定ではないのか？と思われるかもしれませんが、道路付近に出ていた工事の看板にも反応していたので、そういう判定なのかな？と感じた次第です。

でもそれらの情報をうまく処理して最善の判断をしていました。（詳しい技術は分かっていませんが単純にスゴイ！）

運転中のドライバーは手を添えているだけでした。
あくまで実証実験なので、実験に専念なさっているため、乗車している我々はお声がけできないルールになっておりました。
あくまで実験にお邪魔しているだけの見学者なので当然ですね！

今回の道路状況は、道路工事中の場所を通る場面が多かったです。
時期が時期なので仕方ない感じですね。
また、土地柄(？)というべきか都会独特というべきか……細い路地や車線変更で無理くり割り込んでくる場面もありました。
こういった場面では、うまく対応できていたのでさすがという感じです。
# 試乗してみた感想
ひとことで言うと、「運転免許とりたてのドライバー」という感じでした。
乗り心地は普通でしたが、急な変化に対応できる分ブレーキをよくかけていた印象です。

また、人間でも迷う状況に対しては、自動運転車両も迷っている感じでした。
中途半端な場所で止まるといったことがありましたが、そのあとも対応に迷っている感じでした。
この点に対しては人間のアシストや追加の学習が必要だなと感じた点です。

一方、このタイミングで加速するのか～！という場面もありました。
もちろん危険がない状態と判断して効率よく加速しただけの場面だったと思うのですが、逆にいうと人間はこの点で無駄に時間をかけている部分なのかな？と勉強になる部分もありました。

なかなか興味深くて面白い体験ができました！
実験期間間近だと学習データが貯まっているはずなので、ほぼ自動運転になっているのか気になるところですね✨👀
乗り比べてみたいところです😆
# 降車について
到着前に「アンケート」用のQRコードを読み取っておきます。
もちろん乗車中に回答でも、降車後にゆっくり回答でもOKだそうです。
到着するとドアが開くのでここで降車になります。

降車場への運転はドライバーの方が操作されている感じでした。
周囲の状況によっては細かい判断が必要なようです。
# まとめ
このような感じで、なかなかに興味深い体験ができました！
もし機会があったら、実証実験に立ち会ってみていただくことをお勧めいたします😆
# 参考
https://ssw.web.docomo.ne.jp/trmi2024/

https://stationai.co.jp/info

https://x.com/STATIONAi_JP
atcoder練習(2024.11.30)

# 問題
https://atcoder.jp/contests/abc375/tasks/abc375_a

N個の座席が並んでおり、座席には1,2,…,Nの番号が付けられています。
座席の状態は#,.からなる長さNの文字列Sによって与えられます。
Sのi文字目が#のとき座席iには人が座っていることを表し、Sのi文字目が.のとき座席iには人が座っていないことを表します。
1以上N−2以下の整数iであって、以下の条件を満たすものの個数を求めてください。
座席i,i+2には人が座っており、座席i+1には人が座っていない

## 制約
N は 1 以上 2×10**5 以下の整数
S は #, . からなる長さ N の文字列

## 入力
入力は以下の形式で標準入力から与えられる。
N
S

## 出力
答えを出力せよ。

## 入力例 1
6
#.##.#

## 出力例 1
2

i=1,4 が条件を満たすので、答えは 2 です。

## 入力例 2
1
#

## 出力例 2
0

## 入力例 3
9
##.#.#.##

## 出力例 3
3


# 回答
```Python
n = int(input())
s = input()
key = 0
i = 2

while i < len(s):
  if s[i-2] == "#" and s[i-1] == "." and s[i] == "#":
    key += 1
  i += 1
  
print(key)
```

# 参考

# 備考
- とりあえず正解した。とにかく動いたから問題なし。
- andが二つ連なっているのが若干違和感。もう少しスマートにできないかな。
- よくよく考えたら、for文の方が良くない？こういうところが手当たり次第に見つけた選択肢に食らいつくところだと思う。もう少し巨視的な視点で物事をみる訓練をしたい。
- 他の人のコードを見る限りやっぱりfor文で書いている。あと、条件式のところはまとめて"#.#"で検索をしている。確かにそっちの方がスマートな気もする。
AtCoder Beginner Contest 176 A - Takoyakiメモ（python）

これは初心者によるatcoderで間違えた問題のメモです。指摘などありましたらコメントをお願いします。以下常体。
## 問題
[AtCoder Beginner Contest 176 A - Takoyaki](https://atcoder.jp/contests/abc176/tasks/abc176_a)
## 考察
求めるのは`N/X`の切り上げに`T`をかけた数である。
`N/X`の切り上げは`((N+X-1)//X)`で求められる。それにTをかければよい。なお、自分は計算部分を関数で実装した。
## ACコード
```py
def bake(n,x,t):
    times = (n+x-1)//x
    return times * t


n,x,t=map(int,input().split())

print(bake(n,x,t))
```
VSCodeのサジェスト選択キーの割り当て変更

# はじめに
とある日のコーディングをしていたところ，突然サジェストを選択するために`Enter`を押下すると改行が入力されるように……
サジェストを選択したつもりが改行が入力されるせいで，わざわざカーソルで選択する必要が……


# 結論
VSCodeの`Editor: Accept Suggestion On Commit Character`と`Editor: Accept Suggestion On Enter`の設定を確認しましょう．

![スクリーンショット 2024-11-30 15.11.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693436/e30be42a-ca24-12a3-eb43-0778fbf9e778.png)

なぜ突然設定が変わったのかについては疑問が残るところですが，解決策が分かってよかったです．
調べ方が悪かったのか記事が中々見つからず，設定を虱潰しに見直し，15分も無駄にしてしまいました．


# 最後に
恥ずかしながら初めてサジェストの選択が`Tab`でもできることを知りました．
普段使用する言語がPythonということもあり`Tab` = 「インデント挿入」のイメージが強かったので……（言い訳）
もしも私がAVD監視をすることになったら


# 背景
会社のシステム担当として次期のPC環境がAVDになる予定
このままいくと私はAVD管理者
システムが何かあった時に備えてAVDを監視しておく必要がある
しかし、監視設定などしたことがないのでどうしたらよいか調査してみることに
※ある程度基本的なAVDの知識はある

# とりあえずググる

検索フォーム　「AVD 監視」
個人ブログや、企業が書いているブログを見てみる
重大なエラー類を拾ってメール発行させればよさそう

ただ、監視対象というか種類が多くて何がなにやら
ということで、次は監視項目を勉強しなくてはならない

# 監視項目の検討

・正常性関係（ホストプール,AVD自体のサービスに係る項目,セッションホスト)
    ⇒管理者が状況把握と対応しないといけないので通知
 
・CPU使用率関係
    ⇒私がスペックアップとかしないとなので通知
 
・ネットワーク関係
    ⇒どうせそんにすぐ解消できないだろうから無視
    ⇒電話きたらportalから見てみよう
 
・ユーザプロファイル関係（容量とか、サービス自体の稼働状況）
    ⇒ユーザプロファイルのエラーはユーザが気づきにくそうなので監視
        例：作業したはずのファイルが次の日ロスト。しかし朝の時点で気づかない。みたいな
    ⇒プロファイル管理するためのストレージも含めてかな

公式ドキュメントはこのあたり
https://learn.microsoft.com/ja-jp/azure/virtual-desktop/insights-costs

結局メールが来てからどれが何に該当するか分からないので、チートシートみたなものがあるとよさげ
あとは使いながら調整かな

# 料金は？

事前にいくら費用がかかるか会社へ説明するために料金の整理が必要

公式サイトを見たけど諦めたくなるくらい複雑
https://azure.microsoft.com/ja-jp/pricing/details/monitor/

各単語の意味がわからないので、単語を軽くぐぐったりして勉強
LogAnalyticsに保存されたデータの容量で課金される様子
運用のしかたなどで変わりそうなので、諸々込みでログが 約600円/GB ＋αくらい？
メール：1 か月あたりメール 1,000 通　無料

Azure Monitorを試したことがある人いたら、実際の請求値と監視項目から類推できるけどそんな知り合いは私にはいないし。
「実際どれくらいアラートがでるかわからないので、試してみないとわからない。」とした上でざっくり積んでおくのがよさそうかな。

あとは徐々に最適化することにする。
保有期間は1年くらいだとどれくらいのログになるか測定したり、監視の必要なさそうだなーってやつは消したり。

# 最後に
AVDの監視について軽く勉強した際の備忘録でした。
監視する人の気持ちで勉強してみようと思ってこういった記事になりました。
Azure portal上で設定する機会があれば別途投稿します。

具体的なことは参考文献のブログが非常にわかりやすかったのでおすすめです
また、「参考になった！」「これもあったほうがいいのでは？」というコメントがあればぜひよろしくお願いいたします。
※ガラスのハートです。優しく教えていただけると嬉しいですm(_ _"m)

# 参考文献
[AVDで攻めのアラート設定を試す！](https://www.cloudou.net/azure-virtual-desktop/avd051/)(ブログ更新日2024/5/29,参照　2024/11/29)
ブラウザを使ってDNS over HTTPS（DoH）を体験する

# はじめに
HTTP(S)を通信経路として名前解決を行うプロトコルが[DNS over HTTPS（DoH）プロトコル](https://tex2e.github.io/rfc-translater/html/rfc8484.html)です。DoHをブラウザで体験してみます。

# まずは体験
百聞は一見にしかず，を体現するようなプロトコルです。まずは体験ということで，以下のリンクをクリックしてください。

https://dns.google/resolve?name=www.google.com&type=A

DNSサーバからの応答がJSONとして返ってきます。

```
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "www.google.com.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "www.google.com.",
      "type": 1,
      "TTL": 300,
      "data": "172.217.25.164"
    }
  ],
  "Comment": "Response from 216.239.36.10."
}
```

これは便利。

# DoHの利点
- 通信経路上の改ざんを防止できる
- キャッシュDNSサーバの真正性を保証できる
- JSONなので，アプリケーションで扱いやすい
- イントラネットなど内部から直接インターネット上のDNSサーバにクエリできない環境でも，HTTPSが通っていれば名前解決のテストができる
などなど
LinuxボードMilk-V Duo上でpythonブロックプログラミング

## はじめに
　Scratchなどでよく知られるブロックプログラミング環境で用いられる言語には、独自のものが多く、汎用性の高い言語としてArduino IDEで利用される言語が多いようです。
　Pythonのプログラミングをブロックプログラミングで行う環境は、私の調べた限りでは、今回紹介する「Mind+」やMicroPythonを利用するM5Stack用の「uiflow」があります。
　ここでは、安価に入手可能なLinuxボードのMilk-v DuoとMind+との組み合わせでつくる、Pythonブロックプログラミング環境を紹介します。本稿で使用するMilk-v Duoの環境は、「Buildrootでsftpサーバーをビルド」で紹介した、sftpサーバー搭載の環境です。事前に環境構築を行ってください。

　本稿には、「Unagi.py 勉強会57枚目@スイーツバンク」の発表内容を含みます。

https://pycon-shizu.connpass.com/event/311185/

## Milk-V Duo
　このボードには、CVTEK CB1800BというRisc-vのCPUが搭載されており、RAMは６４MB、外部記憶としてマイクロSDカードを利用することが可能です。

https://milkv.io/ja/duo
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/287115fb-761c-71fb-ab1d-b9a7fc338a8d.png)

　有線LANのコネクタのついたボードを追加することで、10/100 Mbpsでイーサーネットに接続可能です。　 
以下の特徴があります。
・コミュニィティ主体で展開
・情報の鮮度が短い（すぐ、自動でパッチが当てられなくなる、ソースへのマージを待つ方が時間の節約）。
・情報の主な言語が中国語（ソフトはBaidu、ハードはOshwhub、利用にはWeChatのIDが必要）
・Raspberry pi (pico)の情報や周辺機器を転用可能
・オープンハードウェアとオープンソフトウェア
・Linuxのリソース
・pinpongライブラリを介してPythonで制御

## Mind+
　ブロックプログラミング環境のMind+のデスクトップ画面です。
 
 https://mindplus.cc/en.html
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/32c07083-c340-b7fc-e9c8-30c67f98b12d.png)

　以下に示すように、中央部分にブロックプログラミング部分があり、そのPythonソースファイルが右上部分に表示されます。Linuxボードとの通信はシェルに表示され、その表示は画面右下に表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/4d9e3a87-9b57-dd1e-e439-f812903bbaa4.png)

 
## 今回構築したシステム
　Milk-v DuoのLinuxボードにLCDと気温・湿度センサを接続したLinuxサーバーと、Mind+の動作するGUIマシンとは、USBケーブルで接続されています。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/9bcd8116-7a0a-0696-3ffe-af781953743c.png)

　　GUIマシンからLinuxサーバー側は、RNDIS接続されており、TCP/IPで通信します。サーバー上でのプログラムの動作は以下の様になります。
1.	デスクトップマシン上でプログラミング
2.	サーバーにプログラムを転送
3.	サーバー上でプログラムを実行
4.	実行結果が、サーバー上のディスプレイに表示
Linuxサーバー側には、以下の機能があります。
・SSHサーバー
・Sftpサーバー
・Pythonで制御できるGPIO端子
・RNDIS（あるいはEthernet）
GUIマシンとして、Windows、MacOS、デスクトップ環境のあるLinuxマシンが利用可能です。
## Linuxサーバー側の設定
MIND+との間のファイル転送に必要な設定を行います。
Rootでファイル転送することが前提になっています。
Mind+は、Linuxサーバーの特定のディレクトリにプログラムを転送します。特定のディレクトリである
“/usr/local/lib/python3.7/dist-packages”
を作成します。
あるいはPython3.7をインストールします。上記のディレクトリは、Pythonインストール時に作成されます。
## おわりに
　ここまでの設定で、GPIO搭載の安価なLinuxボード「Milk-V Duo」用のPythonプログラムをビジュアルプログラム「Mind+」で実現することができました。
　今回の説明は、USB接続経由でRNDISが利用可能で、ROOTでsftpファイル転送可能なLinuxボードなら適用可能です。
　例えば、Raspberry pi zeroシリーズにも適用可能です。
　また、PythonのプログラムはLinuxサーバー側に保存されます。サーバー起動時に、保存されているPythonプログラムを起動できるよう設定しておくと、GUIマシン無しで動作の実演が可能です。
Buildrootでsftpサーバーをビルド

## はじめに
　GPIO搭載の安価なLinuxボード「Milk-V Duo」を2023年から使用しており、様々なプロジェクトを実施してきました。

https://milkv.io/ja/duo

　これらの成果は、秋葉原ロボット部のアドベントカレンダーで公開しています。

https://qiita.com/advent-calendar/2023/milkvduo　

　このボードで動作するPythonプログラムをビジュアルプログラミング環境で行いたく、実験を行っていました。具体的には、「ビジュアルプログラミング」で「フィジカルコンピューティング」を行う環境の構築です。以下の記事の続きに、なります。

https://qiita.com/kazueda/items/e5fede4d24403b3c1b67


　本稿には、「鹿児島Linux勉強会2024.2」での発表内容を含みます。
 
https://kagolug.connpass.com/event/309453/

## ビジュアルプログラミング環境のMind+
　ビジュアルプログラミングは、Windows10上で動作する「Mind+」を想定しています。

https://mindplus.cc/en.html

以下の特徴があります。
・Scratch3.0から派生
・ブロックを使ったビジュアルプログラミング環境
・対応言語は、Arduino CとPython
・ブロックプログラムをテキストファイルに
・対応マイクロコントローラは、Arduino、microbit、ESP32ベースのデバイス等
・Debian OSで動作するUNIHIKER
　Linuxの動作するボードが含まれていますので、Milk-v duoでも使えるかもしれません。
## Milk-vでsftpをサポートする
「Milk-V Duo」はSCPプロトコルのみサポートしているので、Mind+の使用するsftpプロトコルを追加する必要があります。
　設定には以下のものがあります。
1. SSHサーバーの「dropbear」とsftpサーバーの「gesftpserver」の組み合わせ
2. SSHサーバーの「dropbear」とsftpサーバーの「openssh-sftp-server」との組み合わせ
3. SFTPプロトコル対応のSSHサーバーの「openssh-server」
　ここでは、を設定することにします。

## buildrootのdefconfigの修正
　「milkv-duo_musl_riscv64_defconfig」に以下の項目を追加します。
```
BR2_USE_WCHAR=y
BR2_TOOLCHAIN_HAS_THREADS=y
BR2_USE_MMU=y
BR2_PACKAGE_LIBICONV=y
BR2_ENABLE_LOCALE=y
BR2_PACKAGE_GESFTPSERVER=y
```
　実際にビルドしてみると、Python2がないと表示されてビルドに失敗します。
　さらに、Python3ではなくPython2を使う場合も、ビルドに失敗します。
## gesftpserver.mkへのパッチ
「gesftpserver.mk」にパッチを当てて、 Python2を探さないようにします。

https://git.buildroot.net/buildroot/commit/?id=422fd73fadfbe33523e1687f90bbfecd3f7ab5d5

パッチは以下の通りです。
```
@@ -23,6 +23,10 @@ GESFTPSERVER_DEPENDENCIES += \
$(if $(BR2_ENABLE_LOCALE),,libiconv) \
$(if $(BR2_PACKAGE_OPENSSH),openssh)

+# Python on the host is only used for tests, which we don't use in
+# Buildroot
+GESFTPSERVER_CONF_ENV += rjk_cv_python24=false
+
# openssh/dropbear looks here
define GESFTPSERVER_ADD_SYMLINK
ln -sf gesftpserver $(TARGET_DIR)/usr/libexec/sftp-server
```

https://lore.kernel.org/buildroot/20210626123120.1FA99801B3@busybox.osuosl.org/T/

パッチを当てたのち、buildrootをビルドします。
```
$ cd builroot-2021.05
$ make clean
$ make milkv-duo_musl_riscv64_defconfig
$ make all
```
なお、milk-vのbuildrootのビルドの仕方は、以下のurlで説明しています。

https://github.com/milkv-duo/duo-buildroot-sdk

## 動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/2b5b375a-2ac0-08d9-e548-6920e06472ea.png)

　Gesftpserverが起動し、Mind+で作成したpythonのソースファイルが転送されて、milk-v上で作成したpythonプログラムが動作していることがわかります。

## おわりに
　Risc-VのCPUを搭載したMilk-vボード用pythonプログラムをMind+で作成する環境が構築できました。
　Milk-v以外にも、Risc-VのCPUを搭載したボードが多数販売されているので、python用ビジュアルプログラミング環境を検討されている方には、おすすめです。
GUDドライバを使ってRaspberry pi picoでLinux用USB接続2.8インチミニサブディスプレイ

## はじめに
　GUDドライバの実験でRaspberry pi picoを使ったミニディスプレイの発表準備を行っていると、Interface誌2023年12月号に様々なLCDをつないでUSB接続のディスプレイにする記事があることに気づきました。

https://interface.cqpub.co.jp/magazine/202312/

https://interface.cqpub.co.jp/wp-content/uploads/if2312_188.pdf

　「LILO&東海道らぐオフラインミーティング 2024-01-28」の発表後、さっそく雑誌を取り寄せて内容を確認しました。
　記事で対応しているLCDは以下のものです。
　Pimoroni製のPico Display Pack

https://shop.pimoroni.com/products/pico-display-pack?variant=32368664215635

　1.14インチのIPS LCD搭載のRaspberry pi pico用のボードです。4個のボタンとRGBLEDも搭載されています。

https://shop.pimoroni.com/products/pico-display-pack-2-0?variant=39374122582099

　2.0インチ（320x240）のIPS LCDディスプレイ搭載のRaspberry pi pico用ボードです。4つのボタン、RGB LED、それからPicoプロジェクトに使えるスペースも用意されています。

　Waveshare製の2.8inch Touch Display Module for Raspberry Pi Pico

https://www.waveshare.com/pico-restouch-lcd-2.8.htm

　262千色、320x240のSPI接続可能な、Raspberry pi pico用2.8インチタッチディスプレイです。
　ここでは、Waveshare製の2.8inch Touch Display Module for Raspberry Pi Picoの使用例を紹介します。

## UF2ファイルのビルド
　私は、/home/kazueda/rpipicoで作業を行っています。
　記事中に掲載のダウンロードサイトから、ソースファイルを含む圧縮ファイル、IF2210TS.zipをダウンロードします。
　ダウンロードしたファイルを解凍すると、IF2210TSディレクトリが生成します。IF2210TSディレクトリに移動して、pico-sdkをgit cloneします。
　その後、pico-sdkディレクトリに移動します。
 ```
$ cd pico-sdk
```
　サブモジュールをアップデートします。
```
$ git submodule update –init
```
 「gud-pico/libraries/gud_pico/usb_descriptors.c」の修正
の修正を行います。
「.wMaxPacketSize.size = CFG_GUD_BULK_OUT_SIZE,」
を
「.wMaxPacketSize = CFG_GUD_BULK_OUT_SIZE,」
と修正します。
　最後に、UF2ファイルの作成です。
```
$ ./build.sh
$ make
```
 私の場合、
 ```
/home/kazueda/rpipico/IF2210TS/gudpico/build/examples/pico-display
```
のディレクトリに
pico_display.uf2
が生成します。
「 pico_display.uf2 」をRaspberry pi picoにペーストすると、Raspberry pi pico側の準備は終了です。
　「2.8inch Touch Display Module」に接続して、USBケーブルを介してLinuxマシンに接続します。
## ディスプレイの動作状況
Ubuntu22.04のデスクトップ環境で無事映りました。Ubuntu（デフォルト）、つまりデフォルトのリッチなUnity環境です。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/c28c9d00-78c4-818b-6264-3e6070a264a4.png)
```
$ uname –a
```
を使って、システムの状態を見ると、以下の様になっています。
```
Linux kazueda-U700 6.5.0-25-generic #25~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Feb 20 16:09:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
```
　一方、Raspberry pi OSは緑のままで、デスクトップは表示されません。PIXELを使用しています。
 　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/f631de2b-3604-9fb1-802f-fe584d5212c5.png)
　こちらも、
 ```
$ uname -a
```
を使って、システムの状態を見ると、以下の様になっています。
```
Linux raspi4 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr  3 17:24:16 BST 2023 aarch64 GNU/Linux
```
 デスクトップ環境を選ぶのかもしれません。
## おわりに
　Linuxカーネルのバージョンが5.15以上のデスクトップ環境だと動作するとの説明でしたが、ディスプレイマネージャ依存があるのかもしれません。
　Interface誌2023年12月号の記事にはGUDドライバの仕組み等の解説がありますので、GUDドライバの資料として手元に置いておくのがいいでしょう。
FreePSXBootをPicoMemCardで利用して、初代プレステで自作ソフトを動作させる

## はじめに
　FreePSXBootをPicoMemCardで利用すると、初代プレイステーション（以降、初代プレステ）で自作ソフト（以降、homebrew）を動作させることが可能となります。
　メモリーカードのファイルシステムの勉強になりますので、早速試してみます。
## FreePSXBootとは
　FreePSXBootはメモリーカードから起動するhomebrewです。

https://github.com/brad-lin/FreePSXBoot

　　FreePSXBootを使うと、メモリーカード上に保存した自作ソフトを起動することができます。他にいろいろなことができますが、ここでは、自作ソフト動作に必要な情報のみを紹介します。
　FreePSXBootは初代プレステの型番ごとに設定が異なります。ここでは、SCH-5500での起動を目標とします。
## 自作ソフト起動可能なメモリカード用イメージファイルの作成
　FreePSXBoot本体と自作プログラムから、メモリーカードのイメージファイルを作成する必要があります。
　メモリーカードには最大112 kBのファイルを保存可能ですが、FreePSXBoot本体と自作プログラムをあわせて、112 kBにする必要があります。
　Gitcloneしたディレクトリのbuilderディレクトリに移動します。このディレクトリでmakeを行うと、builderプログラムが生成します。
　このディレクトリに、メモリカードに保存したい自作プログラム、今回は、test.psx-exeを置きます。私の使用するプレステの型番の、SCPH-5500を例に、次の操作を説明します。
　コマンドプロンプトで
```
$ builder -model 5500 -in text.psx-exe -out test.mcd
```
と入力します。
　設定に問題が無いと、「test.mcd」というファイルが生成します。
 　bulderプログラムのオプションは以下の通りです。
「-model 5500」はSCPH-5500で使用するとの意味です。
「-in test.psx-exe」は「test.psx-exe」というプログラムを含めるとの意味です。
「-out test.mcd」は「test.mcd」という名のメモリカードイメージを作成するとの意味です。
　今回説明していない、オプションは、

https://github.com/brad-lin/FreePSXBoot/tree/master/builder

の「REDAME.md」に説明があります
## メモリカードイメージをメモリカードに保存して起動
　test.mcdを保存したメモリーカードの差し込まれたプレステのCDドライブのふたを開けたまま、起動すると、メモリカードかCDドライブかの選択画面が表示されます。メモリカードを選択すると、画面の左から右に色が変化し、builderコマンドを使って保存した自作プログラムが起動します。
## おわりに
　初代プレステ実機で、自作プログラムを起動する方法を紹介しました。メモリカード内にプレステを起動するFreePSXBootのプログラムと自作プログラムを保存するので、あまり大きな自作プログラムを起動するのには、適した方法ではありません。
　最大112 kBの自作プログラムをメモリカードから起動する方法もありますので、そちらも参照してください。
cloudflare workersでリバースプロキシしたメモ

ドメインをcloudflareで購入した
github pagesからcloudflare pagesに移行した
ここで、github pagesはリポジトリをサブディレクトリとしてホストするのに対して、cloudflare pagesはサブドメインとしてホストする
これによりそのままリポジトリを紐付けるだけでは移行ができなかった

cloudflare workers 1つでこれを解決した

新規cloudflare workersを作成し、カスタムドメインとして購入したドメインのルートをサブドメイン無しで紐付ける
コードは以下の通り

```js
const
d={
  'petit.mcbeeringi.dev':'/petit',
  'dotfiles.mcbeeringi.dev':'/dotfiles',
  'mcbeeringi.github.io':'/ghp',
  'pages.mcbeeringi.dev':''
};

export default{
  fetch:req=>(async(
    r2u=x=>new URL(x.url),r=r2u(req),rp=r.pathname,li=Object.entries(d),
    rd=(x,{le='',tr='',q=x})=>new Response(null,{status:301,headers:{Location:le+x.pathname+tr+q.search+q.hash}})
  )=>li.reduce((a,[,x])=>a||x==rp,0)?rd(r,{tr:'/'}):
    (x=>x.redirected?rd(x=r2u(x),{le:d[x.hostname],q:r}):x)(await fetch(new Request(
      li.reduce((a,[i,x])=>a||new RegExp(`^${x}/`).test(rp)&&'https://'+i+rp.slice(x.length),''),{...req}
    )))
  )()
};

```

プロキシしたいディレクトリと宛先を定義、
合致した場合は宛先にリクエストを飛ばしてそのレスポンスを横流しする
リクエストがディレクトリそのものを指定かつ末尾に/が無い場合は/をつけるリダイレクトを返す(これが無いとurlの整合が取れない)
宛先にてリダイレクトが発生した場合はリダイレクト先を301で返す
searchやhashはリクエストそのままをレスポンスにつける

かれこれ1ヶ月ほど問題なく動作している
参考までに
【Ruby】IOクラスのファイルポインタを理解する

# はじめに

こんにちは！アメリカの大学で語学を学びながら、独学でソフトウェアエンジニアを目指している者です。
今回は、RubyのIOクラスを学ぶ中で登場するファイルポインタの概念について解説します。
普段の変数操作では意識することがなかったファイルポインタが、なぜファイル操作で必要になるのかを理解し、実際の操作方法も紹介したいと思います。


# ファイルポインタとは？

### メモリ上のデータ vs ファイルのデータ
Rubyでは、文字列や数値などの変数を操作する際、メモリ上で全てを自由に扱えます。
しかし、ファイルはディスク上のリソースとして扱われるため、効率的なアクセスが求められます。
ここで登場するのがファイルポインタです。

まずはよく見るようなメモリ上のデータ、つまり変数操作をする例です。
```ruby
a = "Hello world"
puts a  # => Hello world
puts a  # => Hello world
```
この場合、データは常に変数 a に格納されており、何度でも出力できます。
<strong>変数はすでにメモリ上に展開されているため、アクセス時に位置管理を行う必要がない</strong>のです。

続いて、変数ではなくファイルのデータを操作する例を見てみましょう。
```ruby
File.open("example.txt", "r") do |file|
  puts file.read  # ファイル全体を読み込む
  puts file.read  # すでにファイルの終端にいるため、何も出力されない
end
```
最初の file.read でファイル全体を読み込むと、2回目の file.read では何も出力されません。
<strong>ファイルは外部リソースであるため、現在の読み込み位置をファイルポインタで管理する必要があります。</strong>
これにより、次のデータがどこから読み込まれるかが決定されるのです。

### ファイルポインタが存在する理由
ファイルポインタは、効率的なデータアクセスを可能にするためのものです。
ファイルは「ストリーム」として扱われます。
ストリームとは、データを順次処理するための仕組みです。
ファイルは一度にすべてをメモリに読み込むのではなく、ポインタによって管理された位置から必要なデータを少しずつ取り出します。
これにより、大きなファイルでもメモリ効率よく操作できます。

# ファイルポインタを操作するメソッド 
| 　ポインタの説明　| 説明                                                          | 
|:-------------:|:-------------------------------------------------------|
|`pos`|	現在のファイルポインタの位置を取得・設定する
|`seek`	|ファイルポインタを任意の位置に移動する                           |
|`rewind`	|ファイルポインタをファイルの先頭に戻す                     |	


### `pos` メソッド
`pos` は現在のファイルポインタの位置を取得したり、任意の位置に設定するために使います。
```ruby
File.open("example.txt", "r") do |file|
  puts "現在の位置: #{file.pos}"  # => 0（ファイルの先頭）
  file.read(5)
  puts "読み込み後の位置: #{file.pos}"  # => 5（5バイト読み込んだ後）
end
```
### `seek` メソッド
`seek` を使うと、ファイルポインタを任意の位置に移動できます。
```ruby
File.open("example.txt", "r") do |file|
  file.seek(10)    # ファイルの10バイト目に移動
  puts file.read   # そこからデータを読み込む
end
```
また、オプションを使って、先頭からの相対位置だけでなく、現在位置やファイルの末尾からの移動も指定できます。

| 　オプション　| 説明                                                          | 
|:-------------:|:-------------------------------------------------------|
|IO::SEEK_SET	|ファイルの先頭からのオフセット
|IO::SEEK_CUR	|現在の位置からのオフセット                   |
|IO::SEEK_END	|ファイルの末尾からのオフセット                  |	
```ruby
file.seek(10)                 # 先頭から10バイト進む（デフォルト）
file.seek(5, IO::SEEK_CUR)    # 現在位置から5バイト進む
file.seek(-10, IO::SEEK_END)  # ファイル末尾から10バイト戻る
```

### `rewind` メソッド
`rewind` を使うと、ファイルポインタをファイルの先頭に戻すことができます。
```ruby
File.open("example.txt", "r") do |file|
  file.read(10)
  puts "現在の位置: #{file.pos}"  # => 10
  file.rewind
  puts "リセット後の位置: #{file.pos}"  # => 0
end
```

## ファイルポインタの活用例
以下のコードでは、`seek` と `rewind` を組み合わせてファイル内の特定位置を操作する方法を示します。
```ruby
# example.txt には "Hello world" と記載されています
File.open("example.txt", "r") do |file|
  file.seek(6)      # "world" の "w" に移動
  puts file.read(5) # => world
  file.rewind       # ファイルの先頭に戻る
  puts file.read(5) # => Hello
end

```
出力結果は以下の通りです
```ruby
world
Hello

```
# まとめ
ファイル操作では、データの読み書き位置を管理するためにファイルポインタが重要な役割を果たします。
RubyのIOクラスには、ファイルポインタを操作するための便利なメソッドが多数用意されています。

* `pos`: 現在の位置を確認・設定
* `seek`: 任意の位置に移動
* `rewind`: ファイルの先頭に戻す
ファイルポインタを適切に活用することで、柔軟で効率的なファイル操作が可能になります。
[ブラウザ] あらためてDOMについて整理する

## 学習のモチベーション

私は普段の業務の中で、どちらかというとサーバーサイド, DBレイヤ寄りの実装を行う事が多く、クライアント周りの知識が乏しいです。

それでも依頼されれば簡易的なJSの実装を行ったりはしますが、いまいちDOMという概念を自分の中で明確に言語化できていないまま、雰囲気でDOM操作をしたりしていました。

さすがに、Webエンジニアを自称する人間としてDOMとは何なのかくらいは自分の言葉で説明できる必要があるなと思い、学習・執筆に至った次第です。

## DOMとは何なのか

`DOM（Document Object Model）`は、Webページの構造をプログラムで操作できるようにしたインターフェースです。

簡単に言うと、「**HTMLやXML文書をプログラムで扱うためのオブジェクト**」です。

### 参考文献

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model

## DOMの役割

なるほど、ではDOMという概念が存在する事で、我々開発者はどのようなメリットを享受できるんでしょうか。

DOMが存在する事で、以下のようなメリットを享受できます。

1. 文書の構造を表現する
DOMはウェブページのHTMLやXMLをツリー構造として表現します。
これによってページは構造化され、各要素（例：見出し、段落、画像など）にアクセスしやすくします。
    
2. プログラマブルになる
JavaScriptなどのプログラム言語で、HTMLやCSSを変更したり操作したりするために、DOMが使われます。
例えば、ボタンをクリックしたときに、特定のテキストを変更することができます。
    
3. 動的なウェブページを実現する
DOMを通じて、JavaScriptで要素を追加、削除、変更することで、インタラクティブで動的なウェブページが作れます。

## DOMの基本構造と構成要素

### **DOMの基本構造**

DOMは、ツリー構造（階層構造）で表現されます。このツリーは`ノード（Node）`という単位で構成されています。

具体例として、HTMLとDOMツリーそれぞれを表現してみます。

```html
<!DOCTYPE html>
<html>
  <head>
    <title>DOMの例</title>
  </head>
  <body>
    <h1>Hello World！</h1>
    <p>これはサンプルのHTMLです。</p>
  </body>
</html>
```

上記のHTMLに対応するDOMツリーは、以下のような構造になります。

```bash
Document
 ├── html
      ├── head
      │     └── title ("DOMの例")
      └── body
            ├── h1 ("Hello World！")
            └── p ("これはサンプルのHTMLです。")
```

では、DOMはどのような要素から構成されるのでしょうか。

### DOMの構成要素

DOMは以下の種類の`ノード（Node）`で構成されています。

1. 要素ノード（Element Node）
HTMLタグ（例：`<html>`, `<h1>`, `<p>`）を表します。
DOM操作の中心的な存在で、親子関係や属性を持つことができます。
    
2. テキストノード（Text Node）
要素ノード内に含まれるテキスト（例：「Hello World！」）を表します。親ノードを持ち、テキストデータを保持します。
    
3. コメントノード（Comment Node）
HTMLのコメント（例：`<!-- コメント -->`）を表します。ページには表示されませんが、開発者向けの情報として存在します。
    
4. ドキュメントノード（Document Node）
DOMツリーの最上位にあるノードです。`document`オブジェクトとしてアクセスでき、ページ全体を表します。
    
## まとめ

DOMとは、HTMLやXML文書をツリー構造として表現し、プログラムで操作できるようにするモデルです。

DOMが提供される事によって、我々Web開発者はノードにアクセスする事ができ、エンドユーザーに対してインタラクティブなWebページの提供を実現する事ができます。

[先述の参考文献](https://www.notion.so/DOM-14e28660a309805ea7d8dc24cff89e8c?pvs=21)は、DOMについて非常にわかりやすくまとめられています。ぜひ一度目を通してみるとよいでしょう。
1.Learn-Discord.サーバー作成の基本


Discord初心者向けにサーバー運営の基本を載せるだけです。（書きかけでも頻繁にコミットしてます。）  
ここではWindowsで行うのでほかのデバイスだとできないことや違うところがあるかもしれません。  
## 1. サーバー作成
左側サーバー一覧の下の+からの作成画面で簡単な質問と名前を決めてサーバーを作成できます。  
<a href="https://gyazo.com/caf92d826937a883d3734b386547c246"><img src="https://i.gyazo.com/caf92d826937a883d3734b386547c246.png" alt="Image from Gyazo" width="300"/></a>  
<a href="https://gyazo.com/7c3eec1532c6929c64cb6a14f7277358"><img src="https://i.gyazo.com/7c3eec1532c6929c64cb6a14f7277358.png" alt="Image from Gyazo" width="500"/></a>  
  
## 2. チャンネル管理
左上のチャンネル名をクリックするとチャンネル作成やカテゴリー作成ができます。  
なるべくわかりやすく見つけやすいチャンネル名や構成にしましょう（やり方は慣れです。）  
（自鯖のケース）  
<a href="https://gyazo.com/743225b3858fdd2eecf6317dabfc3514"><img src="https://i.gyazo.com/743225b3858fdd2eecf6317dabfc3514.png" alt="Image from Gyazo" width="150"/></a>  
  
## 3. ロール管理  
ロール設定は、サーバー設定⇒ロールから設定ができます。  
管理者や運営仲間へ権限を付与したり、役割を役割を表したりするのに使用できます。  
BOTやモデレーターなどがロールを操作する場合、たとえロール管理の権限を与えていても、自分がついている一番上のロールより下のロールしか操作することができないので必要な分だけ上にあげましょう。    
（自鯖の構成の場合、ゲームのランクなどもロールとしてつけて募集の際にメンションできるようになっている。）  
<a href="https://gyazo.com/7692c60d2daa38b4c03d58e3dbf4e36c"><img src="https://i.gyazo.com/7692c60d2daa38b4c03d58e3dbf4e36c.png" alt="Image from Gyazo" width="250"/></a>    
  
以上サーバー作成の基本でした。   
補足、誤字脱字などがあれば教えていただけると嬉しいです！
OpenAMとは？SSOの基本と導入ポイントを解説

## はじめに
IT環境の進化に伴い、複数のシステムやアプリケーションを利用する場面が増えています。その中で、ユーザーが毎回異なる認証情報を入力する煩わしさを解消するために注目されているのが、シングルサインオン（SSO）です。本記事では、オープンソースのSSOツールとして知られる **OpenAM** の基本情報、特徴、導入時のポイントについて解説します。

---

## OpenAMとは？
**OpenAM** は、ForgeRockが提供していたオープンソースのアクセス管理ソリューションで、以下のような機能を備えています。

- **シングルサインオン（SSO）**：一度の認証で複数のシステムにアクセス可能。
- **多様な認証方式**：LDAP、OAuth2、SAML、OTPなど、様々な認証プロトコルをサポート。
- **柔軟なポリシー管理**：アクセスルールを細かく設定可能。
- **高可用性**：クラスタリング対応で大規模環境でも利用可能。

現在、OpenAMのオープンソースプロジェクトは終了していますが、フォークプロジェクトや代替ソリューションが存在します。

---

## OpenAM導入のメリット

### 1. ユーザー体験の向上
ユーザーが複数のシステムにわたって一度のログインで利用できるため、利便性が向上します。

### 2. セキュリティ強化
一元管理された認証システムにより、不正アクセスを防止しやすくなります。

### 3. 管理コストの削減
認証情報やアクセス管理を統合することで、運用負荷が軽減されます。

---

## 導入時のポイント

### 1. 要件の明確化
- どの認証プロトコルを利用するか（例：SAML、OAuth2など）。
- 対応するアプリケーションやシステムの洗い出し。

### 2. インフラ設計
- 高可用性を実現するためのクラスタリング。
- 負荷分散を考慮したサーバー構成。

### 3. カスタマイズの計画
- 独自のログイン画面やカスタム認証機能の開発。
- APIやスクリプトによる柔軟な拡張。

---

## OpenAMを学ぶための参考記事

1. **OpenAMの概要と特徴**  
   - [かもめエンジニアリングのブログ](https://solution.kamome-e.com/blog/archive/blog-opensource-20221026?utm_source=chatgpt.com)  
     OpenAMの基本的な仕組みや導入事例について解説しています。

2. **シングルサインオン技術解説**  
   - [CodeZineの記事](https://codezine.jp/article/detail/6318?utm_source=chatgpt.com)  
     SSO全般とOpenAMの技術的な詳細が記載されています。

3. **OpenAM初歩ガイド**  
   - [Qiitaの記事](https://qiita.com/keomo/items/7a69e86bfaa4a563610a?utm_source=chatgpt.com)  
     OpenAMの導入手順や活用法について初心者向けにまとめられています。

---

## おわりに
OpenAMは、柔軟なアクセス管理機能を持つ優れたツールです。現在は公式のサポートが終了していますが、フォークプロジェクトや他のオープンソースソリューションを活用することで、同様の機能を実現できます。本記事を参考に、ぜひSSO導入の第一歩を踏み出してみてください。
OSPFのルーター

# OSPFはAS内を各領域に分ける
>インターネットのASの多くは、自らが巨大になり監視するのが難しくなってきている。こうした巨大なスケールに対応するために、OSPFは`ASを番号付きの領域（area）に分割できる`ようになっている。それぞれの領域は、`一つのネットワーク`か、あるいは`隣接するネットワークの集合`である。領域は重複しないが全てを覆う必要はない。すなわち、`いくつかのルーターがどの領域にも属していないということもあり得る`。
# 
### 領域内にある　内部ルーター
>`完全に領域内`にあるルーターは、内部ルーター(internal router)と呼ばれる。領域は`独立ネットワークを一般化`したものである。`ある領域の外では、その領域の形態や詳細を知ることができない`。この性質は`大きな規模でのルーティング`に役立つ

### ASからASへパケットが通る　バックボーン領域
>各ASは`バックボーン領域(backbone area)`を持っており、これは領域０と呼ばれている。また、`この領域にあるルーターをバックボーン・ルーター(backbone router)`と呼ぶ。すべての領域はこのバックボーンに接続されているので、`あるAS内の任意の領域から、そのAS内の任意の他の領域へバックボーンを通っていくことができる`。

### 領域の境目にある　領域境界ルーター
>2個以上の領域に繋げられているルーターを`領域境界ルーター(area border router)`と呼ぶ。これらのルーターは、`必ずバックボーンの構成要素にもなっていなければならない`。

#### サマリーをもとに最適な領域境界ルーターを見つける
>領域境界ルーターの働きは、個々の領域ごとにパケットの転送先をまとめて、接続されている他の領域へその`サマリー（各領域で得られたパケット転送先をまとめたもの）を渡す`ことである。今サマリーはコスト情報を含んでいるが、`一つの領域内のトポロジの詳細を全て含んでいるわけではない`。コスト情報を渡すことで、他領域内のホストはある領域へ入る（パケットを送信する）際に用いる`最適な領域境界ルーターを見つける`ことができる。

### スタブ領域
>ある領域外にある宛先へのルートは必ず「境界ルーターへ向かえ」という命令と共に始まる。こうした領域をスタブ領域(stub area)と呼ぶ。

### 外部ルーターへのルートを示す　AS境界ルーター
>他のAS上にある外部の宛先へのルートを、そのAS境界ルーターを含む領域へ導入するものである。その際の外部経路は、先ほどのAS境界ルーターを通り、いくらかのコストを伴って到達することができるルートとして出てくる。

# 感想
内容をまとめられなかったが、こういうものがあることを知っておこう。
10分で完成！Edgeの拡張機能を使ってIDとパスワードを自動入力


# 作成した経緯

Slerで様々な企業に出向する中で、企業によっては Edgeのパスワード保存機能や自動入力機能が使えない ケースがあります。しかし、複数のツールのログイン画面で 長いIDとパスワードを毎回入力するのは非常に手間 です。

そこで、今回は **Edgeの拡張機能** を利用して、IDとパスワードを自動入力するツールを作成しました。

Qiita と公式リファレンスを参考にしながら作成し、実際に動作確認が取れたので、共有します。

---

## 注意点

- ソースコードや `data.csv` は他人に見られると **パスワードが漏洩** する可能性があります。
- **ローカル環境の他人に見られないフォルダ** に保存して使うことをおすすめします。
---

## 実際に作ったもの
![2024-11-25_20-31-33](https://github.com/user-attachments/assets/3bd0d59b-0db2-445d-9049-dd0b1f97e709)
以下は作成した拡張機能の内容です。コードは[GitHub](https://github.com/alta-jp24/EdgeAutoInput)にもそのままアップロードしています。

### **ファイル構成**

```
extension/
├── manifest.json
├── script.js
```

### **manifest.json**

```json
{
    "manifest_version": 3,
    "name": "Auto Login",
    "version": "1.0.0",
    "description": "自動でIDとPWを入力",
    "content_scripts": [
      {
        "matches": ["https://qiita.com/login*"],
        "js": ["script.js"]
      }
    ]
}
```

### **script.js**

```javascript
const id = "AAA";
const pw = "BBB";

// ID入力
const identityField = document.querySelector('input[name="identity"]');
if (identityField) {
    identityField.value = id;
}

// PW入力
const passwordField = document.querySelector('input[name="password"]');
if (passwordField) {
    passwordField.value = pw;
}

// 入力完了の通知
alert('入力されました');
```

---

## `data.csv` を利用するバージョン

IDとパスワードを `data.csv` に分けたバージョンも作成しました。  
こちらの方が便利なので、**現在はこちらを利用しています**。

### **manifest.json**

```json
{
    "manifest_version": 3,
    "name": "Auto Login",
    "version": "1.0.0",
    "description": "自動でIDとPWを入力",
    "content_scripts": [
      {
        "matches": ["https://qiita.com/login*"],
        "js": ["script.js"]
      }
    ],
    "web_accessible_resources": [
      {
        "resources": ["data.csv"],
        "matches": ["https://qiita.com/*"]
      }
    ]
}
```

### **script.js**

```javascript
fetch(chrome.runtime.getURL('data.csv'))
    .then(response => response.text())
    .then(csvText => {
        const id = csvText.split(',')[0];
        const pw = csvText.split(',')[1];

        // ID入力
        const identityField = document.querySelector('input[name="identity"]');
        if (identityField) {
            identityField.value = id;
        }

        // PW入力
        const passwordField = document.querySelector('input[name="password"]');
        if (passwordField) {
            passwordField.value = pw;
        }

        // 入力完了の通知
        alert('入力されました');
    });
```
# GitHub
https://github.com/alta-jp24/EdgeAutoInput
Visual Studio CodeでAWS SAM触ってみた

# 概要
以下ハンズオンで学習を行なっていたが、ハンズオン内では、Cloud9を使用していた。
[AWS Hands-on for Beginners - Serverless #2](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Serverless-2-2022-confirmation_009.html)

しかし、現在(2024/11/30)、Cloud9は新規利用不可。
別の手段でハンズオンを進める必要があるため、VSCodeにAWS Toolkitを入れてみた。
※実行環境はMac

# 手順
1. VSCodeの拡張機能から「AWS Toolkit」をインストール
2. 同時にAWS CLI、SAM CLIをインストール
3. CMD+Shift+PでExplorerを開いて、AWS: Create Credentials Profileを実行
4. アクセスキーとシークレットアクセスキーを入力(そもそもアクセスキーが無い場合は、IAMからアクセスキーを作成)
:::note warn
リージョンの設定
CMD+Shift+PでExplorerを開いて、Show or Hide Regionsを実行し、リージョンを設定できる
:::

# サンプルプログラムをVSCodeで実行
1. Lambda+SAM templete作成
CMD+Shift+PでExplorerを開いて、Create Lambda SAM Applicationを実行
![スクリーンショット 2024-11-30 10.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344952/b3e96645-435b-e400-5083-1a8c43ebc39c.png)

2. デプロイ
CMD+Shift+PでExplorerを開いて、Deploy SAM Applicationを実行
手順に従い、スタックやS3バケットは新規作成(既に作成済みなら指定する)
 ![スクリーンショット 2024-11-30 10.35.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344952/b78bd18b-76c9-bb29-e53a-e3865141de13.png)

3. 確認
マネジメントコンソールからS3のバケットに、tempelteファイルが保存されていることを確認
マネジメントコンソールからLambdaが作成されていることを確認。API Gatewayがトリガーとなっていることを確認。

4. テスト
デプロイされたAPIのURLを開くと問題なく、動いていることを確認
![スクリーンショット 2024-11-30 11.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344952/5b967d8a-8800-127a-1388-c33e870ecc49.png)

5. 最後に
ハンズオン通りのyamlとLambdaを作れば動くはず(試してない)
スタックを削除すればSAMでデプロイしたものは全て削除できるが、S3バケットは削除されないので、直接削除しましょう
IBM i あるあるSQL（数値型の日付時刻）

## IBM iの日付、時刻のデータベース表現

**IBM i** のデータベースはとても歴史があり、かなり古い時代から使用されています。最近（特にモダンなアプリを制作するケースや外部連携）では、**IBM i** データベースのフィールド型に**日付型／日時型**を使用することも増えてきましたが、日付や時刻を表すのに根強く残っているのは以下の様な数値型を使用するケースです。

- 年月：`6S 0`※S:ゾーン10進数
- 日付：`8S 0`
- 時刻：`6S 0`

**IBM i**においてモダンなアプリ開発を行う際に、それらフィールドを含むデータベースを使用している時、日付算術等でよく使う **SQL** を今回はご紹介します。

## 年月：`6S 0` から`8S 0`の1日を取得する
これはとても簡単で桁上げして、１を加算するだけです。
以下の **SQL** になります。

```sql:数値年月から数値1日を取得する
SELECT
 (YM01 * 100 + 01) AS DT01
 FROM
   ( SELECT 202412 AS YM01
       FROM SYSIBM.SYSDUMMY1  )
;
```
![2024-11-30_123940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/1e6dc825-05f8-926a-3fb8-ea9b42c0075a.png)


## 年月：`6S 0` から`D 日付型`の1日を取得する
少し複雑ですが、日付型へ変換（キャスト）するために `DATE関数` を使用します。日付型へのキャストには区切記号 `-` で区切必要があるので `SUBSTR関数` で必要桁数に区切っています。
以下の **SQL** になります。

```sql:数値年月から日付型1日を取得する
SELECT
  DATE(SUBSTR(DT01 ,1,4) 
    || '-' || SUBSTR(DT01 ,5,2) 
    || '-' || SUBSTR(DT01 ,7,2) 
  ) AS DT10
  FROM
  ( SELECT
   (YM01 * 100 + 01) AS DT01
   FROM
     ( SELECT 202412 AS YM01
         FROM SYSIBM.SYSDUMMY1  )
  )       
;
```
![2024-11-30_124644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/155c042b-393a-0009-77fb-6aa8b8a51c92.png)

## 年月：`6S 0` から`8S 0`の末日を取得する
末日を取得するには `LAST_DAY` 関数を使うことができます。一旦日付型形式の”1日”を作成します。その後、`LAST_DAY` 関数を通し末日の日付型を取得したら `CHAR` 関数で文字列へキャストします。`REPLACE` 関数を使い区切記号 `-` を除去し、`DECIMAL` 関数で10進数へキャストすれば、数値8桁の末日が取得できます。
以下の **SQL** になります。

```sql:数値年月から数値末日を取得する
SELECT
 DECIMAL(REPLACE(CHAR(LAST_DAY(SUBSTR(YM01, 1, 4)
         || '-' || SUBSTR(YM01, 5, 2) || '-01')), '-', '')) AS DT01
 FROM
   ( SELECT 202502 AS YM01
       FROM SYSIBM.SYSDUMMY1  )
;
```
![2024-11-30_130516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/829aad9a-631d-f38d-3ce6-c58f6f4284d7.png)


## おまけ - 今日の：`日付型`を取得する
今日を取得するには、特殊レジスタ `CURRENT DATE` を使う事ができます。
以下の **SQL** になります。
```sql:今日の日付を取得する
SELECT
 CURRENT DATE AS DT10
  FROM SYSIBM.SYSDUMMY1
;
```
![2024-11-30_125753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/569652bf-a987-f555-6a6f-05af552bbca8.png)

これを、数値型へキャストすれば数値型のシステム日付を取得できます。
**IBM i** では結構この様な **RPG,CL** で当たり前にやってることが 「**SQL** ではどうすんの？」系は多くあります。また機会があったら別のケースも紹介します。
EC2インスタンスで2TB以上のEBSを割り当てる際の注意点

## 背景

AWS EC2でWindows Serverをセットアップしている際、特定のインスタンスサイズのEC2に対して2TB以上のEBSを割り当てようとすると、2TBを超える容量が認識されないという問題に遭遇しました。本記事では、その原因と解決策について解説します。

## 問題の概要

特定のインスタンス（例：i3.large）でWindows Serverに2TB以上のEBSボリュームを割り当てた際、以下の問題が発生しました：

- ディスク管理ツールでボリュームを確認すると、2TB以上の領域が利用できない。
- 割り当てたEBS自体は正常に作成されているが、OS側で制限されているように見える。

## 原因

調査の結果、問題の原因は以下の通りでした：

1. **EC2インスタンスがBIOS経由で起動していたこと。**
2. **BIOS経由で起動する場合、Windows OSのディスク形式が自動的にMBR（Master Boot Record）形式になること。**
   - MBR形式のディスクは最大で2TBまでの容量しかサポートしていません。詳細は[Windows公式ドキュメント](https://learn.microsoft.com/ja-jp/troubleshoot/windows-server/backup-and-storage/support-for-hard-disks-exceeding-2-tb)に記載されています。
3. **MBR形式では2TB以上のディスク容量を認識できないため、GPT（GUID Partition Table）形式に変更する必要があること。**

そのため、2TB以上のディスクを使用するには、MBR形式ではなくGPT形式を使用する必要があります。

## 解決策

解決策として、以下の2つが考えられます。

### 1. ディスクをGPT形式に変更する

以下の手順でMBR形式のディスクをGPT形式に変更します：

1. EC2インスタンスにログインする。
2. **ディスクの管理ツール**を開く。
3. 該当のディスクを右クリックし、「**ボリュームの削除**」を選択して既存のパーティションを削除します（**注意**：データはすべて消去されます）。
4. 再度ディスクを右クリックし、「**GPTディスクに変換**」を選択。
5. 新しいパーティションを作成してフォーマットします。

これにより、2TB以上のEBSボリュームが正常に認識されるようになります。

PowerShellでも以下のコマンドで実行可能です。

```powershell
# 管理者権限でPowerShellを実行してください

# 現在のディスク情報を確認
Get-Disk

# 対象のディスク番号を設定（適切なディスク番号に変更）
$DiskNumber = 1

# ディスクをクリアしてGPTに変換し、新しいパーティションを作成
Clear-Disk -Number $DiskNumber -RemoveData -Confirm:$false
Initialize-Disk -Number $DiskNumber -PartitionStyle GPT
New-Partition -DiskNumber $DiskNumber -UseMaximumSize -AssignDriveLetter | 
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "<ドライブ名>" -Confirm:$false
```

### 2. UEFI経由で起動する

別の解決策として、インスタンスをUEFI経由で起動する設定に変更します。UEFIはGPTディスク形式をサポートしているため、2TB以上のディスクを制限なく利用できます。

#### UEFIでの起動要件

1. **OSがUEFIをサポートしていること**  
   Windows Server 2012以降はUEFIをサポートしています。（※EC2側がUEFIをサポートしていないとBIOS経由になります。）

2. **EC2インスタンスタイプがUEFIをサポートしていること**  
   すべてのインスタンスタイプがUEFI起動をサポートしているわけではないため、事前に確認が必要です。


以下のAWS CLIコマンドで、インスタンスタイプがUEFIをサポートしているか確認できます：
```bash
# 1. i3.largeの場合

aws ec2 describe-instance-types --instance-types i3.large --query "InstanceTypes[0].SupportedBootModes" --output table

-----------------------
|DescribeInstanceTypes|
+---------------------+
|  legacy-bios        |
+---------------------+
```
```bash
# m6i.largeの場合
aws ec2 describe-instance-types --instance-types m6i.large --query "InstanceTypes[0].SupportedBootModes" --output table

-----------------------
|DescribeInstanceTypes|
+---------------------+
|  legacy-bios        |
|  uefi               |
+---------------------+
```

結果に`uefi`と表示されていれば、そのインスタンスタイプはUEFIをサポートしています。

## まとめ

Windows Serverで2TB以上のEBSを使用する場合、以下の点を確認してください：

1. ディスクがGPT形式であること。
2. インスタンスタイプがUEFIをサポートしていること。
3. OSがUEFIに対応していること。

これらを満たしていない場合、MBR形式の制限により2TB以上のディスク容量を使用できません。UEFI起動とGPT形式を正しく設定することで、この問題を回避できます。

検証などで小さいサイズを割り当てていて、商用環境になった際にこの問題に直面することも考えられます。参考になりましたら幸いです。
atcoder練習(2024.11.30)

# キーワード

# 問題
https://atcoder.jp/contests/abc376/tasks/abc376_b

## 問題文
注：この問題はF問題とほぼ同じ設定です。
本文中で太字で示されている部分および制約のみが異なります。
あなたはあるリングを両手で握っています。
このリングはN (N≥3)個のパーツ1,2,…,Nによって構成されており、パーツiとパーツi+1(1≤i≤N−1)、およびパーツ1とパーツNがそれぞれ隣接しています。
最初、左手はパーツ1を、右手はパーツ2を握っています。
あなたは、1回の操作で以下のことを行えます。
片方の手を、今握っているパーツに隣接するいずれかのパーツに移動する。
ただし、移動先にもう一方の手がない場合に限る。
以下の図は、初期状態およびそこから行える操作と行えない操作の例を示したもので、リングの各パーツに書き込まれた数はそのパーツの番号を、Lと書かれた丸は左手を、Rと書かれた丸は右手を示しています。
あなたは今から与えられるQ個の指示に順番に従う必要があります。
i (1≤i≤Q)個目の指示は文字Hi​および整数Ti​によって表され、その意味は以下の通りです：操作を何回か（0回でもよい）行うことで、Hi​がLならば左手、Rならば右手が、パーツTi​を握っている状態にする。
このとき、Hi​によって指定された手ではない方の手を動かしてはならない。
なお、達成可能な指示しか与えられないことが保証されます。
詳細この問題の設定の下では、各iについて、i個目の指示に従う直前でのそれぞれの手の位置が一意に定まることが証明できます。
このとき、左手の位置をパーツli​、右手の位置をパーツri​とおくと、Hi​=LならばTi​≠ri​が、Hi​=RならばTi​≠li​がそれぞれ保証されます。

すべての指示に従うために必要な操作回数の合計の最小値を求めてください。

## 制約
3≤N≤100
1≤Q≤100
Hi​ は L または R
1≤Ti​≤N
N,Q,Ti​ は整数
達成可能な指示しか与えられない（詳細は問題文を参照してください）

## 入力
入力は以下の形式で標準入力から与えられる。
N Q
H1​ T1​
H2​ T2​
⋮
HQ​ TQ​

## 出力
すべての指示に従うために必要な操作回数の合計の最小値を出力せよ。

## 入力例 1
6 3
R 4
L 5
R 6

## 出力例 1
8

以下のように操作を行うことで、Q 個の指示すべてに順番に従うことができます。
右手をパーツ 2→3→4 と移動させることで、1 番目の指示に従う。
左手をパーツ 1→6→5 と移動させることで、2 番目の指示に従う。
右手をパーツ 4→3→2→1→6 と移動させることで、3 番目の指示に従う。
このとき行う操作回数の合計は 2+2+4=8 であり、これが最小です。
（3 番目の指示に従う際に右手をパーツ 4→5→6 と移動させることはできないことに注意してください。）

## 入力例 2
100 2
L 1
R 2

## 出力例 2
0

操作を 1 度も行わずに指示に従うことができる場合もあります。

## 入力例 3
30 8
R 23
R 26
R 29
L 20
R 29
R 19
L 7
L 16

## 出力例 3
92


# 回答
```Python
n, q = map(int, input().split())
list = []
for i in range(q):
  h, t = input().split()
  list.append([h, int(t)])
print(list)
L = 1
R = 2
key = 0
a=0
b=0


for i in list:
  a_flag = True
  b_flag = True
  if i[0] == "R":
    a=b= i[1] % n
    while a != i[1] or b != i[1]:
      if a_flag == True:
        a = (a + 1) % n
        if a == L:
          a_flag = False
      if b_flag == True:
        b = (b + 1) % n
        if b == L:
          b_flag = False
      key += 1
  if i[0] == "L":
    a=b= i[1]
    while a != i[1] or b != i[1]:
      if a_flag == True:
        a = (a + 1) % n
        if a == R:
          a_flag = False
      if b_flag == True:
        b = (b + 1) % n
        if b == R:
          b_flag = False
      key += 1
      
print(key)
```

# 参考

# 備考
- 供養です。一生懸命書いたのに実行時間超過で実行できませんでした。そもそも意図した挙動になっているかどうかも分かりません。
- なんとなく今のままの学習で良いのかよくわからなくなっていた。確かにコードを書けるようになったが、綺麗なコードは書けないし、ほんとにそれっぽいコードを書けるようになったという感じ。
- 具体的に一つの問題に対して、あれがこうでとかを考えるより、もう少し抽象論を理解した方がいい気がする。今の所頭の中でプログラムが全然整理できていない。もう少し頭の中を整理して、問題に対して様々な解決策を検討して、その中のベストプラクティスを考えるようにしたい。
- 現状は一つ解決策を見つけたらそこにしがみつくしかない。とはいえ、具体の蓄積が抽象だし、解決策の選択肢を増やすには、解決策を知るしかない。
- もう少し、人のコードをよく読んで、感動する時間を多く作りたい。
LibreSSLのこれまでを振り返る（後編）


## LibreSSL 3.1.z

## LibreSSL 3.2.z

## LibreSSL 3.3.z

## LibreSSL 3.4.z

## LibreSSL 3.5.z

## LibreSSL 3.6.z

## LibreSSL 3.7.z

## LibreSSL 3.8.z

## LibreSSL 3.9.z

## LibreSSL 4.0.z
学習済みモデルのpthファイルを軽量化する

ディープラーニングモデルは年々サイズが大きくなり、GPUメモリも大きな容量が必要となっています。
Pretrainedモデルのpthをロードする際に、CUDA out of memory となることもしばしばですね。
ここでは学習時に保存されたオプティマイザの状態を削除したpthファイルを作成することでそれを回避できる場合があるので方法を紹介します。
(もちろんGPUリソースを湯水のごとく使えるならそれが一番ですね!)

### 解決方法
以下のコードで、オプティマイザの状態を削除した軽量なチェックポイントを作成しますのが：
```python
import torch

# 保存されたチェックポイントファイルのパス
checkpoint_path = "path/to/your_checkpoint.pth"
new_checkpoint_path = "path/to/new_checkpoint.pth"

# チェックポイントをCPUでロード
checkpoint = torch.load(checkpoint_path, map_location="cpu")

# オプティマイザの状態を削除
if "optimizer" in checkpoint:
    del checkpoint["optimizer"]

# 新しいチェックポイントとして保存
torch.save(checkpoint, new_checkpoint_path)
```

### 効果
軽量化することで、ややVRAMが少ないGPUでもモデルをロードできる場合があります。
学習は強力なGPUで行い、推論はやや非力なGPUで作業するといったかたちで、マシンリソースの使い分けができるメリットもあります。
(私のケースでは24GB強のチェックポイントが、10GB弱になりました)

### 注意
学習時にもこの方法が使うこともできますが、学習の連続性については採用するオプティマイザによって影響が異なります。特に学習の中断・再開時にはご注意ください。
[こちらの記事](https://qiita.com/Takayoshi_Makabe/items/00eea382015c9d13911f)が参考になりました。
Google Cloudプロジェクトで特定ドメインを持つアカウントにIAM Deny Policyを適用する方法

::: note info
これは [ZOZO Advent Calendar 2024](https://qiita.com/advent-calendar/2024/zozo) カレンダー Vol.9 の 8日目の記事です。
:::

# はじめに
本記事では、IAM Deny Policyを導入する際に、特定のドメインを持つアカウントのみを対象にルールを適用する方法をご紹介します。  
ここではGoogle WorkspaceやCloud Identityを利用してGoogleアカウントを管理し、Googleアカウントが特定のドメインを持つケースを前提としています。


# IAM Deny Policyとは
Identity and Access Management（IAM）のDeny Policyを導入すると、指定したGoogle Cloudリソースへのアクセスにガードレールを設定できます。  
例えば、Organiaztion全体で特定のリソースに対する特定の権限を拒否するDeny Policyを導入したとします。Deny Poilcyの導入によりOrganization配下のProject内で権限が付与されていたとしても、権限を使用できないという状態になります。

IAM Deny Policyについての詳細は[公式ドキュメント](https://cloud.google.com/iam/docs/deny-overview?hl=ja)をご参照ください。

# 特定ドメインを持つアカウントにDeny Poilcyを適用する方法
## IAM v1 APIとIAM v2 APIの違い
通常のAllow Policy（権限付与）の適用にはIAM v1 APIを利用します。一方で、Deny Policy（権限拒否）を適用するには、IAM v2 APIを利用する必要があります。  

IAM v1 APIとIAM v2 APIではプリンシパルタイプごとの識別子が異なります。
IAM v1 APIでは特定のドメインを指定することが可能ですが、IAM v2 APIでは直接的にドメインを指定することができません。

例えば、OrganizationのGoogleアカウントが`hoge.com`というドメインを持っていたとします。この場合、IAM v1 APIを利用するAllow Policyでは次のように適用対象として特定ドメインを持つアカウントを指定可能です。

```bash
domain:hoge.com
```

IAM v2 APIで特定のドメインに紐づくGoogleアカウントを対象とする場合は、ドメインの代わりにCloud IdentityのCUSTOMER_IDを指定する必要があります。このCUSTOMER_IDはGoogle WorkspaceやCloud Identityに申し込むとアカウントに対して一意に割り当てられるようになっています。

IAM v2 APIを利用するDeny Policyでは。次のように対象のドメインに紐付くCUSTOMER_IDを適用対象とすることで、特定ドメインを持つアカウントを指定可能です。

```bash
principalSet://goog/cloudIdentityCustomerId/<CUSTOMER_ID>
```

またCUSTOMER_IDは次のコマンドで確認可能です。

```bash
gcloud organizations list                                                              

# ↓出力例
DISPLAY_NAME            ID  DIRECTORY_CUSTOMER_ID
hoge.com      <ORGANIZATION_ID>         <CUSTOMER_ID>
```

## 特定ドメインへのDeny Policyの適用
特定ドメインへのDeny PolicyのTerraformでの適用例が以下になります。

ここではgcloud CLIのコマンドで取得したCUSTOMER_IDをCloud Secret Managerに保存し、dataリソースとして参照しています。
Organization自体は[google_organizationリソース](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization)として参照でき、リソースの属性としてCUSTOMER_IDを取得することもできるので、どちらの方法も取れるかと思います。

```tf
resource "google_secret_manager_secret" "organization-customer-id" {
  secret_id = "organization_customer_id"
  replication {
    auto {}
  }
}

data "google_secret_manager_secret_version" "organization_customer_id" {
  secret  = google_secret_manager_secret.organization-customer-id.id
  version = "latest"
}

resource "google_iam_deny_policy" "deny-bigquery-run-job" {
  for_each = toset([
    "apply-deny-policy-target-project-id",
  ])
  parent       = urlencode("cloudresourcemanager.googleapis.com/projects/${each.value}")
  name         = "deny-bigquery-run-job"
  display_name = "Deny BigQuery Run Job"
  rules {
    deny_rule {
          denied_principals = ["principalSet://goog/cloudIdentityCustomerId/${data.google_secret_manager_secret_version.organization_customer_id.secret_data}"]
      denied_permissions = [
        "bigquery.googleapis.com/jobs.create",
      ]
    }
  }
}
```

上記をapplyすると対象プロジェクト内で特定ドメインを持つアカウントにIAM Deny Policyを導入できます。
ここでは`apply-deny-policy-target-project-id`のProject内では、指定したCUSTOMER_IDに紐付くドメインを持つGoogleアカウントはBigQueryのJobを作成することができなくなります。
LibreSSLのこれまでを振り返る（前編）

## LibreSSL 2.0.z

## LibreSSL 2.1.z

## LibreSSL 2.2.z

## LibreSSL 2.3.z

## LibreSSL 2.4.z

## LibreSSL 2.5.z

## LibreSSL 2.6.z

## LibreSSL 2.7.z

## LibreSSL 2.8.z

## LibreSSL 2.9.z

## LibreSSL 3.0.z
KBC-80SAを作ってみた

ワンダーキットが40年位前に販売していた、KBC-80SAを作ってみました。

もともとRAM､ROM共に最大8Kバイトですが、32Kバイトに変更します。これに伴いデコーダーはTTLではなくGALで作ります。何箇所かパターンカットしてジャンパーを飛ばしました。

以前日米商事さんで108円で手に入れたLH0080Bがあるのでクロックは6MHzにします。発信器もジャンクで手に入れたストックがありました。

GALはDOSBOXでEQN2JEDでEQNをJEDにして、galprogで焼きます。galprogは以前Visual StudioでビルドしたWindowsのバイナリを使いました。

GALの下駄はLS32とLS139のピンから足を取ります。LS32とLS139の間隔がピッチがDIPの半分だったのでハーフピッチの基板を使いました。

EQNファイルはこんな感じです。

```
title    KBC-80SA 
pattern  Z80 
revision A 
author   yamori813 
date     11/11/24 
chip kbc gal6001 

; The following pin list order mustly be followed strictly: 
; 1. device pins 1 to 24 
; 2. slmc 7 to slmc 0 
; 3. buried feedback (OLMC 14) to buried feedback (OLMC 23) 

; pins 1  2  3  4  5  6  7  8  9  10  11  12 
; pins 2  3  4  5  6  7  9  10 11  12  13  14 
       i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 gnd 

; pins 13   14  15  16  17  18  19  20  21  22  23  24 
; pins 16   17  18  19  20  21  23  24  25  26  27  28 
       oclk o14 o15 o16 o17 o18 o19 o20 i21 i22 i23 vcc 

; slmc7 slmc6 slmc5 slmc4 slmc3 slmc2 slmc1 slmc0 
  nc    nc    nc    nc    nc    nc    nc    nc 

; buried feedback to AND array from OLMCs. 
; bur14 bur15 bur16 bur17 bur18 bur19 bur20 bur21 bur22 bur23 
  nc    nc    nc    nc    nc    nc    nc    nc    nc    nc 

; specify the User Electronic Signature (UES) 

@ues kbc
  ; 8 ues bits are used per character. 

equations 

; ILMC         : asynchronous inputs. 
; IOLMC        : asynchronous feedback to AND array. 
; SLMC         : not used. 
; OLMC 14-18   : asynchronous outputs (output always enabled). 
; OLMC 19-23   : D-type registered outputs (output always enabled). 
;      buried feedback of OLMCs not used. 
; asynch reset : not used (default is registers cannot be reset).  

;ROM CS(20) = MREQ(19) | A15(5)
o14 = i1 | i2
;RAM CS(29) = MREQ(19) | /A15(5)
o15 = i1 | /i2

; PPIO
;IOW(36) = IORQ(20) | WR(22)
o16 = i3 | i4
;IOR(5) = IORQ(29) | RD(21)
o17 = i3 | i5

;PPI0 CS(6) = A3(33) | A2(32) | A6(36) | A7(37)
o18 = i6 | i7 | i8 | i9

;PPI1 CS(6) = A3(33) | /A2(32) | A6(36) | A7(37)
o19 = i6 | /i7 | i8 | i9

;RESET PPIO(35)
;o20 = /i10

; end of example 5 
```

RAMはSOPの物を変換基板でDIPにしています。秋月の変換基板は少し大きいのでやすりで削りました。

最終的にはEPROMにするつもりですが、確認にはFlashを使います。

![IMG_20241130_114659.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/84374913-6f80-7208-0309-bce35e0259f7.jpeg)

PLCCの下駄はRAMとあたるので、細ピンソケットで上げました。一時的なものなので、切らず使いました。

GALのデコードを確認するアセンブラを書きます。

```
        ORG 0
        LD SP,9000H
INIT8255:
        LD A,10000000B
        OUT (007H),A
        CALL SLEEP
LOOP:
        LD A,0FFH
        OUT (004H),A
        CALL SLEEP
        CALL SLEEP
        LD A,00H
        OUT (004H),A
        CALL SLEEP
        JP LOOP

SLEEP:
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        RET
```

zmacでアセンブルしてddでflashのサイズにして、flashromで焼きます。この作業はFreeBSDで行いました。

IORQと8255のPA3はこうなりました。

![NewFile2 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e047b68b-9ac9-6994-3505-768e1c074d5a.jpeg)

リセットモジュールのMN1280を使いましたが、小さいコンデンサーでは正常にリセットされないので、電解コンデンサーを入れました。MN1280は意味無いかもしれません。

8255のリセットはグランドに落としました。
【ChatGPT】文章生成で指定文字数を守らせるPromptのご紹介です。


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

　今回は、文章生成で指定文字数を守らせるPromptのご紹介です。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)

***
　ニュースもないので、
　　さっそく【本題】です。

　今回は、
　　文章生成で
　　　指定文字数を守らせる
　　　　Promptのご紹介です。

　通常、
　　文字数を指定して、
　　　出力させようとしても、
　　　　生成AIは守ってくれません。

　これは、
　　生成AIが、
　　　文字数をプログラム的に
　　　　数えているわけではなく、
　　　　　トークン単位で考えている
　　　　　　ためです。

　そのため、
　　たいていの場合は、
　　　指定文字数よりも
　　　　かなり少ない感じで
　　　　　出力します。

　これは
　　記事を書く上では、
　　　困りものでした。

　今回は、
　　これをなんとかする
　　　ためのPromptをご紹介します。

　すぐるさんという方が
　　ポストしてくださいました。
　　　[すぐるさんポスト](https://x.com/SuguruKun_ai/status/1860474550737338585?t=lQ1IUm_s6wGxDqM_IAfwjA&s=19)

　簡単に説明しますと、
　　このPromptは、
　　　Code Interpreterを
　　　　使用しています。

　そう、このPromptは
　　Code Interpreter環境下で
　　　Pythonを使って、
　　　　文章量を算出しているのです。

　で、
　　指定文字数を越えるまで
　　　処理を繰り返すのです。

　こちらが、
　　そのPromptです。
　　　ちなみに、可読性高めています。
　　　　基本は変えていませんよ😅
```Text:指定文字数を守らせるPrompt
文章生成をする際、必ずPythonコードを使用して、生成した文章の文字数を正確にカウントしてください。 

Step 1: 文章を生成する
　まず、生成する文章を考え、その内容をPythonコードに入力します。以下のコード例を使用して、文章を生成してください。
 例: text = "ここに生成した文章を入力してください。" print(len(text)) 

Step 2: 文字数をカウントする
　生成した文章の文字数をカウントし、目標文字数に達しているかどうかを確認してください。上記のコードでlen()関数を使用して文字数を取得します。

Step 3:調整する
　生成した文章が目標文字数を満たしていない場合は、文章をより長く調整し、再度Pythonコードを実行して文字数をカウントします。
　このプロセスを、目標文字数を満たすまで繰り返してください。

Step 4: 最終確認と提出
　最終的に目標文字数に達したら、以下を提出してください： 
　・最終的な文章（文章はコードブロックに出力してください）
　・その実行結果（文字数）
　・Pythonコードは不要。

目標とする文字数：
目標文字数=xxxx文字

作成したい文章： 
{ここに作成したい文章内容を入力する}  
```

　これを使う前に
　　作成したい文章での
　　　出力をしてみてください。
　　　　内容を確認してからの方が
　　　　　意図に沿った出力が
　　　　　　得られると思います。

　最後のところの
　　目標文字数と
　　　作成したい文章を
　　　　指定してください。

　1000文字で
　　ChatGPTについて
　　　書き出したところ、
　　　　四回繰り返しました。

　オーバーするまで続きますので、
　　100文字オーバーもありえます。

　それから、まだありませんけど、
　　場合によっては、
　　　Code Interpreterの処理時間を
　　　　オーバーしてダメになる
　　　　　可能性もあります。

　　その場合は、
　　　再度、生成を
　　　　お願いします。

　なお、
　　出力のフォーマットは、
　　　やるたびに変わります。

　　段落で切ったり、
　　　改行もしなかったり、と。

　　次のPromptで
　　　読みやすくなります。
　　　　ただし、文字数に関しては
　　　　　考慮されません。
```Text:文章を読みやすくPrompt
この文章を読みやすくMarkdown形式で書き出してください。
```

　また、出力された内容の最後に
　　“``` [❶] (code://python)”と
　　　書き込まれることもあります。

　これはPythonコードの残りカスです。
　　文字数には含まれていません。
　　　確認しました。

　手作業で
　　カットしてください。

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

　今回は、ここまで。