OmniAICreator/Qiita-1.07M huggingface dataset:
足跡・ねる7・非決定性有限オートマトンから決定性有限オートマトンへの変換

# はじめに
neruneruna7，あるいは ねる7 です．
学びの足跡．
今回は余分な前書きは書きません．

# 本文
非決定性有限オートマトンと決定性有限オートマトンにおいて，言語の識別能力は同一である．
$L(dfa) = L(nfa) = L(\epsilon-nfa)$
$L$は言語

非決定性有限オートマトンは決定性有限オートマトンに変換可能である．

変換するアルゴリズムは2つあるが，そのうちの1つについて考える
## 変換方法
以下の空動作を持つ非決定性有限オートマトンM1について考える
JFLAPの都合，$\epsilon$ではなく$\lambda$になっているが，気にせぬよう．
![a1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984876/c6f4cc1d-10e3-bd06-0579-ea0becf96bab.png)

```math
\begin{align}
M_{1} &= <Q,\Sigma,\delta,q_{0},F> \\
Q&= \{q_{0}, q_{1}, q_{2}\} \\ 
\Sigma &= \{0,1\} \\
\delta&: Q \times (\Sigma \cup \{\epsilon\}) = 2^{Q} 
\\
&\delta(q_{0},0)=\{q_{0}\},\delta(q_{0}, \epsilon)=\{q_{1}\} \\
&\delta(q_{1},0)=\{q_{2}\},\delta(q_{1},1)=\{q_{1}\}\\
&\delta(q_{2},0)=\{q_{2}\},\delta(q_{2},1)=\{q_{0}\}
\\
q_{0}&=q_{0} \\
F&=q_{2}
\end{align}
```
受理する語は，10，000001000,0100110,などがある．

この非決定性有限オートマトンオートマトンをもとに，決定性有限オートマトン$Md$を構成する

1. 初期状態からの空動作があれば，それらをまとめて$Md$の初期状態とする．
$\delta(q_{0},\epsilon)=\{q_{1}\}$より，$\{q_{0},q_{1}\}$を$Md$の初期状態とする．

2. つくった初期状態には$q_{0}$と$q_{1}$という2つの状態が含まれている．これらの状態から，遷移できる先の和集合及び空動作で遷移できる状態の集合を新たな状態として作る.ここで作った状態に対しても，それを行い，新たな状態を作れなくなるまで繰り返す．

```math
\begin{aligned}
\delta(q_{0},0) \cup \delta(q_{1},0) = \{q_{0},q_{2}\} \\
\{q_{0},q_{2}\}のうち，q_{0}からは空動作でq_{1}へ移動できるため，それを加えて \\
\delta(\{q_{0},q_{1}\},0)=\{q_{0},q_{1},q_{2}\}
\\
\\
\delta(q_{0},1) \cup \delta(q_{1},1) = \{q_{1}\} \\
\{q_{1}\}からの空動作はない \\
\delta(\{q_{0},q_{1}\},1)=\{q_{1}\}

\\
\\
\\

\delta(q_{0},0) \cup \delta(q_{1},0) \cup \delta(q_{2},0) = \{q_{0},q_{2}\} \\
\{q_{0},q_{2}\}のうち，q_{0}からは空動作でq_{1}へ移動できるため，それを加えて \\
\delta(\{q_{0},q_{1},q_{2}\},0)=\{q_{0},q_{1},q_{2}\}
\\
\\
\delta(q_{0},1) \cup \delta(q_{1},1) \cup \delta(q_{2},1) = \{q_{0},q_{1}\} \\
\{q_{0},q_{1}\}のうち，q_{0}からは空動作でq_{1}へ移動できるため，それを加えて \\
\delta(\{q_{0},q_{1},q_{2}\},1)=\{q_{0},q_{1}\}
\\
\\
\\
\delta(\{q_{1}\},0) = \{q_{2}\} \\
\{q_{2}\}からの空動作はない \\
\delta(\{q_{1}\},0) = \{q_{2}\} \\
\\
\delta(\{q_{1}\},1) = \{q_{1}\} \\
\{q_{1}\}からの空動作はない \\
\delta(\{q_{1}\},1) = \{q_{1}\} \\
\\
\\
\\
\delta(\{q_{2}\},0) = \{q_{2}\} \\
\{q_{2}\}からの空動作はない \\
\delta(\{q_{2}\},0) = \{q_{2}\} \\
\\
\delta(\{q_{2}\},1) = \{q_{0}\} \\
q_{0}からは空動作でq_{1}へ移動できるため，それを加えて \\
\delta(\{q_{2}\},1) = \{q_{0},q_{1}\} \\
\\
これ以上新たな状態は作れない

\end{aligned}
```

3. M1の受理状態を1つでも含む状態を，Mdでの受理状態とする
$F=\{\{q_{2}\}, \{q_{0},q_{1},q_{2}\}\}$

決定性有限オートマトンを構成できた．
![ad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984876/8d8a442f-e9e8-ad7e-ded5-eb16dabe947a.png)

## 感想
有限オートマトンはシンプルでわかりやすいオートマトンである．しかし，非決定性となると，動作を人力で追うのは辛かった（学ぶ上でどうしても自力で追って理解する過程を通らなければならない）．非決定性から決定性への変換も，理解するまではなんじゃこりゃと思った．
何かを有限オートマトンに落とし込むときは非決定性の方が楽だろうし，有限オートマトンをプログラムするときは決定性の方が楽なんだろうなと感じた．その間の変換が機械的にできるというのは，理解してしまえばとても便利なものだなと思う．

# 参考
- オートマトン・言語理論の基礎 著者：米田政明 広瀬貞樹 大里延康 大川知 出版：近代科学社
- 大学の講義
チャットAIの思考力と推論力をテストする質問集

# Level 1.

Q1. 和$a$,差が$b$となる2数はいくつですか?

A1. 答え: $\frac{a+b}{2},\frac{a-b}{2}$

解き方:
このような2数を$x,y$とおく. ただし,$x>y$とする.
このとき,
$x+y=a$
$x-y=b$
が成り立つから, これを解いて
$x=\frac{a+b}{2},y=\frac{a-b}{2}$
となるから, $\frac{a+b}{2},\frac{a-b}{2}$です.

Q2. アラビア数字690801にはまるく囲まれている部分は何個ありますか? 例えば80は3個です. 

A2. 6個

Q3. テキスト"35=183"の好きな部分に+,-, ×, ÷のうち好きな演算子を2つ加えて等式が成り立つようにしてください。

A3. $3×5=18-3$

Q4. ジョーカーを含まない52枚のトランプカードがあります. トランプのカードのスートの得点をハートは1, スペードは2, ダイヤは3, クラブは4とします. トランプのカードの得点はスートの得点の数とトランプの表す数の積です. 52枚のトランプの得点の和はいくつですか?

A4. 910点

解き方: 
ハートの得点の和: $1×1+1×2+\cdots +1×13\=1×(1+2+\cdots +13)$
スペードの得点の和: $2×1+2×2+\cdots +2×13\=2×(1+2+\cdots +13)$
ダイヤの得点の和: $3×1+3×2+\cdots +3×13=3×(1+2+\cdots +13)\$
クラブの得点の和: $4×1+4×2+\cdots +4×13=4×(1+2+\cdots +13)\$
なので,これらの和は
$$\begin{align}(1+2+3+4)×(1+2+\cdots +13) =10×\left(\frac{1}{2}×13×(1+13)\right)=10×91=910 \end{align}$$
となる. 

# Level 2. 
Q1. 半分に折ったとき比率が変わらない長方形をすべて求めてください. 

A1. $1:\sqrt{2}$の長方形のみである.

解き方: 
長方形の長さを$a$,$b$とする. ただし, $a>b>0$とする.
[1] 短辺を折った場合
$a$,$\frac{b}{2}$となるが,$a:b=a:\frac{b}{2}$を満たす$a,b$は存在せず比率が変わらない条件を満たせない.
[2] 長辺を折った場合
長方形の辺の長さは$\frac{a}{2}$と$b$となる.
$\rm{(i)}$ $\frac{a}{2}\geq b$のとき
$a:b=\frac{a}{2}:b$を満たす$a,b$は存在せず比率が変わらない条件を満たせない.

$\rm{(ii)}$ $\frac{a}{2}< b$のとき
$a:b=b:\frac{a}{2}$を計算して$a^2=2b^2$である.
$a>0,b>0$より$a=\sqrt{2}b$すなわち$a:b=\sqrt{2}:1$

以上から$1:\sqrt{2}$の長方形のみである.

Q2. 長さ1の針金の2点をランダムに選びます。選んだ点で針金を曲げたとき三角形が成立する確率は?
A2. $\frac{1}{4}$

Q3. 各桁がすべて素数の正の整数を「よい数」と呼ぶ。2乗すると5桁の「よい数」なる3桁の「よい数」をすべて求めてください. 
A3. 235

Q4. 5種類のフィギュアが入っているガチャは1/5の確率でどのフィギュアも出てきます.ガチャは1回100円です.すべて揃えるのに必要なお金の期待値はいくらですか？
A4. $\frac{3425}{3}円$


Q5. ディズニランドに来るお客さんは1グループあたり平均何人かを知りたいです.入場ゲート1人ずつに「今日何人で来ましたか?」と聞いて100人に調査した結果,
・20人のお客さんは2人組で来た.
・30人のお客さんは3人組で来た.
・50人のお客さんは5人組で来た.
と答えました.　1グループあたり平均何人と予想できますか?

A5. $\frac{10}{3}$

Q6. 「山口とは友達だ。私は山口と岡山に行ったことがある。」を英訳してください。

Q7. A. 熱硬化性プラスチックはかたく、熱や薬品に強いことから、調理器具などに使用されている。
B. 熱硬化性プラスチックは、調理器具などに使用することから、かたく、熱や薬品に強い。
A,Bの文の表す内容の意味は論理的に一致するか一致しないか答えてください。
OpenAI Deno SDKを試してみる🦕

# はじめに
OpenAI Deno SDKがリリースされたって！？
試してみるしかないでしょ…！
https://twitter.com/kt3k/status/1730482306559955249

#  ざっくり調べてみる
https://github.com/openai/openai-deno-build
> This is a build produced from https://github.com/openai/openai-node – please go there to read the source and docs, file issues, etc.

なるほど！nodeのライブラリからできたものなのね。

#  試してみた
以下を記述し実行！
```
import OpenAI from "https://deno.land/x/openai@v4.25.0/mod.ts";
import "dotenv";

const openai = new OpenAI({
  apiKey: Deno.env.get("OPENAI_API_KEY"),
});

async function main() {
  const chatCompletion = await openai.chat.completions.create({
    messages: [{ role: "user", content: "Denoの素晴らしい点をいくつか挙げて。" }],
    model: "gpt-4",
  });
  console.log(chatCompletion.choices[0]?.message?.content);
}

main();
```

返答
```
1. セキュリティ: Denoはデフォルトで安全を重視し、スクリプトはどんなネットワークアクセスも、ファイル、環境変数、さらには他のスクリプトへのアクセスを許可しません。

2. TypeScriptの組み込みサポート: DenoはTypeScriptを直接サポートしており、追加のツールなしで書き始めることができます。

3. 単一の実行可能ファイル: Denoはただ一つの実行可能ファイルであり、Node.js のような依存関係の問題はありません。

4. 組み込みの依存性検査とバンドラ: Denoには依存性を解決し、コードをバンドルする組み込みのツールがあります。

5. モジュールの取り扱い: Denoは、コードの依存性を管理するための新しい方法を導入しています。それはURLで参照されるESモジュールに基づいています。

6. パッケージマネージャーの不要性: Denoはnpmのようなパッケージマネージャーを必要とせず、依存性はURLまたはファイルパスで直接インポートされます。

7. top-level await: Denoでは、非同期操作を待つために明示的に関数をラップする必要はありません。

8. 標準ライブラリ: Denoは、Node.jsが長らく欠けていた広範な標準ライブラリを提供します。
```

試しにストリーミングも
```
~ 省略 ~

const encoder = new TextEncoder();

async function main() {
  const stream = await openai.chat.completions.create({
    model: "gpt-4",
    messages: [{ role: "user", content: "Denoの素晴らしい点をいくつか挙げて。" }],
    stream: true,
  });
  for await (const part of stream) {
    Deno.stdout.write(encoder.encode(part.choices[0]?.delta?.content || ""));
  }
  Deno.stdout.write(encoder.encode("\n"));
}

main();
```

いい感じですね～
![g2l0HVQRxmlQdj5Q.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511806/8fe81228-1aa6-f0a9-094e-4ae0a8f94b9b.png)

# おわりに
割と簡単に扱えて楽しいです🦕
もともとnodeのライブラリを使っている方はすぐ使いこなせるかもですね！
https://github.com/openai/openai-node


弊社開発課のXも是非フォローしてね🦕💨

https://twitter.com/tech_cin
🦕Denoにおける環境変数の扱いについて~Supabaseと接続してみよう~🦕

# はじめに
Denoで環境変数を扱うとき、どう読み込ませればいいんだろ？と思っていた時代があったので、そんな時代のお話を記事として残しておこうと思いました🦕
もし間違えがありましたらお気軽にご指摘ください～！

# この記事の対象者
- Deno触りたてほやほやの人
- Denoにおける環境変数の設定・読み込みを知りたい人
- DenoとSupabaseを繋げたい人

# お話しないこと
- Supabaseでのプロジェクト作成方法

# 環境
- deno 1.38.4
- typescript 5.2.2
- fresh 1.5.4

# 準備
## 使用する値を保存
保存しておいてほしいのはデータベースのパスワードとホスト名になります。
前述したように、ここではプロジェクトの作成方法は説明しないため、下記を参考にするといいでしょう。
https://qiita.com/pikimaru/items/5e51d36250c288b8b6dc

- パスワード：プロジェクト作成時に使用したデータベースのパスワード
- ホスト名　：プロジェクト作成完了後、サイドバーの Project Settings → Database → Connect to your database directlyに記載してあるホスト名

## 使用ライブラリの追加
postgresを扱うライブラリ
https://deno.land/x/postgres@v0.16.1

環境変数を扱うライブラリ
https://deno.land/std@0.212.0/dotenv/mod.ts

それぞれ追加したら、import_map.json に追記しておきます。
※ URLインポートの場合は記載しなくてもいいよ！
```import_map.json
{
  "imports": {
    "postgress": "https://deno.land/x/postgres@v0.16.1/mod.ts",
    "dotenv/": "https://deno.land/std@0.212.0/dotenv/mod.ts",
  }
}
```

# 環境変数の設定
.envファイルを作成して、下記のように記載します。
※PostgreSQL のデフォルトポートは 5432 のため、デフォルト値を記載しておきます。
```.env
DB_USER=postgres
POSTGRES_DB=postgres
DB_PORT=5432
DB_PASSWORD=${データベースのパスワード}
DB_HOST=${ホスト名}
```

# 環境変数の読み込み～Supabaseと接続
```
import { Client } from "postgress";
import "dotenv";
 
const client = new Client({
  user: Deno.env.get("DB_USER"),
  database: Deno.env.get("POSTGRES_DB"),
  hostname: Deno.env.get('DB_HOST'),
  password: Deno.env.get('DB_PASSWORD'),
  port: Deno.env.get('DB_PORT'),
});

await client.connect();
```
これで接続できました！
あとは
```
await client.queryObject<${interface}>(...
```
とかで必要なクエリ書いたりすればデータを参照したり更新したりが可能になります。

# おわりに
いかがでしょうか？
かなり限定的な記事となりましたが、少しでも参考になれば幸いです🦕
良きDenoライフを🦕🦕💨

弊社開発課のXも是非フォローしてね🦕💨

https://twitter.com/tech_cin
【図解!?】DenoのFreshで採用されているIslandArchitectureの使いどころを考えてみる【🦕🍋】

# はじめに
あなたは恐竜、好きですか？
私は大好きです。特にブラキオサウルス🦕！

そんな感じで最近少しずつDenoを触る機会が増えたので、学習の一環として記事を書こうと思いました。
（投稿初心者のため拙い文章かもですが、お付き合いただけますと幸いです🦕）
もし間違えがありましたらお気軽にご指摘ください～！

# この記事の対象者
- IslandArchitectureって何よ
- なんとなく知ってるけど使いどころは知らん

# IslandArchitectureとは🏝
**必要な時に必要なところで必要なだけJSを**
IslandArchitectureとは、ページ全体の静的な部分を「海」、JSが必要な動的な部分を「島」にたとえてレンダリングする手法のこと。
図に示すとこんな感じ。
![イラスト156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511806/70036b3c-1763-a85a-3819-7315c58d9e62.png)


# なんでこの手法が生まれたか
**要件に関わらずなんでもかんでもページ全体でJSを読み込ませると遅いやろ！！！**
ほんの一部分にしかJSを使用していないのに、共通してJSを読み込ませていることでパフォーマンスを下げてげてしまっている。そんなことはないだろうか。
そんな課題を解決するために生まれました。
似たようなものとして、PHP（Laravelなど）で作られたものが該当します。
PHPでは静的な部分をサーバサイドでレンダリングし、動的な部分はクライアントサイドのJSを書いて実行しているためです。

# 使いどころ
## 早く表示させたいサイト
IslandArchitectureのメリットは何といっても静的コンテンツのロードが早く、必要な部分だけが動的に更新されるため、サイトのパフォーマンスが良くなること。
UX重視・パフォーマンス重視！であれば採用してもいいでしょう。

## 動的な部分が限られてるサイト
インタラクティブな要素が少ないブログサイトやニュースサイトには適していますね。

# 使わないどころ
## 動的な部分がほとんどのサイト
そもそもIslandArchitectureはMPAベース。
動的な部分が多い場合は、SPAで作るほうが良いかも！
参考→[SPAとMPAって何が違うの？SPAにしたほうがいい？](https://scrapbox.io/vue-yawaraka/SPA%E3%81%A8MPA%E3%81%A3%E3%81%A6%E4%BD%95%E3%81%8C%E9%81%95%E3%81%86%E3%81%AE%EF%BC%9FSPA%E3%81%AB%E3%81%97%E3%81%9F%E3%81%BB%E3%81%86%E3%81%8C%E3%81%84%E3%81%84%EF%BC%9F)

## 規模が小さめなサイト
ページの速度よりリリースの速度を重視する場合はメリットが少ないです。
IslandArchitectureの設計・実装に頭を悩ますよりも別のことに頭を使いましょう。

# おわりに
なんにでも言えますが良い悪いではなく**要件次第**なので、うまく活用してみてはいかがでしょうか？
みなさんも興味が湧いたら是非freshを触ってみてください！
IslandArchitectureは[Astro](https://docs.astro.build/ja/concepts/why-astro/)も採用しているので、そちらも触ってみてもいいかもですね～

弊社開発課のXも是非フォローしてね🦕💨

https://twitter.com/tech_cin

# 参考
https://fresh.deno.dev/
https://qiita.com/oekazuma/items/87923acea03990fd71a2
https://deliv.tech/2020/11/10/mpa-vs-spa/
Forge 1.7.10 開発 自分用殴り書き

マジで誰も記事にしていないので、次回自分が環境構築を悩まないようにメモしておく。殴り書きなので悪しからず。
12時間以上寝ずにぶっ通しで忘れないうちに書いているので間違っていることや、無礼、誤字脱字があるかも。

1.7.10で開発したいよね。ロマンだよ。古のマインクラフターたちは1.7.10にこだわる。

まず普通に環境構築する。

javaインストールする
jre-8u271-windows-x64.exe

jdkインストール
jdk-17.0.4_windows-x64_bin.exe

intel jidea communityをjetbrains toolboxでインストール。

forge公式のやつでmdkやろうとするとリンク切れか何かでプログラムが動かんくなるから有志で
作られたこれで開発する。最初からこれを使えば楽。
https://github.com/anatawa12/ForgeGradle-example

これで普通に動くなら解決。



# 動かない時の対処法一覧 (従来の開発状況の回復方法)
gradle-wrapper.properties 下記((7.4.2))を最新に。
```
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
```


build.gradle
```java
buildscript {
    repositories {
        maven { url = "https://jcenter.bintray.com/" }
        maven {
            name = "forge"
            url = "https://maven.minecraftforge.net/"
        }
        maven {
            name = "sonatype"
            url = "https://oss.sonatype.org/content/repositories/snapshots/"
        }
    }
    dependencies {
        classpath ('com.anatawa12.forge:ForgeGradle:1.2-1.1.+') {
            changing = true
        }
    }
}
```


gradle側を変更するコマンド gradle階層で使える
```
gradlew wrapper --gradle-version=7.4.2
```

pcのjavaのバージョンとプロジェクトのgradleのバージョンを合わせる。
↓
Java version	Gradle version
8	2.0
9	4.3
~省略~	
16	7.0
17	7.3
18	7.5
19	7.6
20	8.1

# InteljIdea側 設定
project structure
project SDK 1.8

source languege level
project default

dependecies sdk 1.8

gradle 関連設定
1.8

# 終わりに
マジで忘れない用の適当なメモなのでいずれちゃんとした記事にするか、新しい記事、それか動画にする。

# 参考様
https://qiita.com/TT-RR/items/6866be865c4ab2118030#3%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%ABupdate%E3%81%99%E3%82%8B

https://www.tntmodders.com/tutorial/env2-1710/comment-page-2/#comments

http://logiclab.blog.jp/archives/57723545.html

https://zenn.dev/toliner/articles/fdb9d2fc1e0df0aace5a#%E8%A6%81%E7%B4%84
PHP デバッグ

```php
<?php
$log = array(
    "x1" => "y1",
    "x2" => "y2",
    "x3" => "y3"
);

//バッファ出力開始
ob_start();
//配列をダンプ
var_dump($log);
//バッファの内容を変数に代入
$dump = ob_get_contents();
// バッファ終了
ob_end_clean();
error_log($dump,3,'./dump.txt');

error_log(var_export($log, true), 3, "./export.txt");
error_log(print_r($log, true), 3, "./r.txt");
```
JavaScript（php smarty内 .tpl 記述） ラジオボタン、テキストエリア 制御

## ■完成イメージ
・ラジオボックス（香炉）デフォルト、連絡事項に記述無し
・テキストエリア（連絡事項）
![スクリーンショット (924).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/ab05efe8-21ac-cf11-a637-3f5a9dc53d02.png)

・ラジオボックス（香炉）香炉有りの場合は、連絡事項に追記
・テキストエリア（連絡事項）
![スクリーンショット (925).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/2f0f2098-bf2d-3e41-a33b-f818c02279a0.png)

※香炉以外の他にラジオボタンが３つ

## ■ソースコード
```javascript main.js

// === コンテンツをロードしたら実行
document.addEventListener("DOMContentLoaded", function() {

    document.querySelectorAll('input[name="kouro_kubun"]').forEach(function(radio) {
        radio.addEventListener('change', updateTextarea);
    });

    document.querySelectorAll('input[name="death_weight_tmp"]').forEach(function(radio) {
        radio.addEventListener('change', update_Death_Wight);
    });

  
document.querySelectorAll('input[name="Machi_show"]').forEach(function(radio) {
        radio.addEventListener('change', update_Machi_show);
    });

    update_Death_Wight();

    update_Machi_show();

});

function updateTextarea() {
    var kouroKubunValue = document.querySelector('input[name="kouro_kubun"]:checked').value;
    var textarea = document.querySelector('textarea[name="stuff_info"]');
    var currentTextareaValue = textarea.value;

    currentTextareaValue = currentTextareaValue.replace(/香炉：香炉有り\n/g, '');

    if (kouroKubunValue === '1') {
        textarea.value = currentTextareaValue + '香炉：香炉有り\n';
        console.log("連絡事項：：：" + textarea.value + "\n");
    } else {
        textarea.value = currentTextareaValue;
    }
}

function update_Death_Wight() {
    var death_weight_tmp_Value = document.querySelector('input[name="death_weight_tmp"]:checked').value;
    var textarea = document.querySelector('textarea[name="stuff_info"]');
    var currentTextareaValue = textarea.value;

    currentTextareaValue = currentTextareaValue.replace(/体重：100kg 以下\n|体重：100kg 以上\n/g, '');

    if (death_weight_tmp_Value === '0') {
        textarea.value = currentTextareaValue + '体重：100kg 以下\n';
        console.log("連絡事項：：：" + textarea.value + "\n");
    } else if (death_weight_tmp_Value === '1') {
        textarea.value = currentTextareaValue + '体重：100kg 以上\n';
        console.log("連絡事項：：：" + textarea.value + "\n");
    }
}

function update_Machi_show() {
    var Machi_show = document.querySelector('input[name="Machi_show"]:checked').value;
    var textarea = document.querySelector('textarea[name="stuff_info"]');
    var currentTextareaValue = textarea.value;

    currentTextareaValue = currentTextareaValue.replace(/待合室利用：小さい部屋\n|待合室利用：大きい部屋\n/g, '');

    if (Machi_show === '1') {
        textarea.value = currentTextareaValue + '待合室利用：小さい部屋\n';
        console.log("連絡事項：：：" + textarea.value + "\n");
    } else if (Machi_show === '2') {
        textarea.value = currentTextareaValue + '待合室利用：大きい部屋\n';
        console.log("連絡事項：：：" + textarea.value + "\n");
    } else {
        currentTextareaValue = currentTextareaValue.replace(/待合室利用：小さい部屋\n|待合室利用：大きい部屋\n/g, '');
        textarea.value = currentTextareaValue;
        console.log("連絡事項：：：" + textarea.value + "\n");
    }
}

```
JavaScript の && 演算子は true/false を返すとは限らない

# はじめに
React Hook Form のサンプルを見ていたら、こんなコードがありました。

:::note info
というか、React 本家のチュートリアルにもありますね。
https://ja.react.dev/learn/conditional-rendering#logical-and-operator-
:::

```react:エラーがあれば&&の右を出力
{errors.exampleRequired && <span>This field is required</span>}
```

普段 JavaScript を書かない立場としては、すぐには理解できませんでした。
入力チェックの結果、エラーがある場合ならこういう挙動のはず。
1. `errors.exampleRequired` に何らかのオブジェクトが入っている
1. `true` と評価される
1. 右オペランドが評価される
    1. 右オペランドが `true` と評価されれば、`true` が返される
    1. 右オペランドが `false` と評価されれば、`false` が返される

入力チェックの結果、エラーがない場合ならこうなるよね？
1. `errors.exampleRequired` が `undefined`
1. `false` と評価される
1. 右オペランドを評価せず、`false` が返される

どちらにせよ、`true`/`false` のいずれかが返されるので `<span>This field is required</span>` は出力されないように思えます。
正しく動作させるなら、普通に考えればこうなるかなと。

```react:条件演算子を使うよね
{errors.exampleRequired ? <span>This field is required</span> : ''}
```

JavaScript の `&&` 演算子が Java などと比べて特殊なので、確認してみます。

# && 演算子の基本
JavaScript も C 言語の流れを汲んでいる（基本的な文法の面では）ので、基本的には同じです。

- AND（論理積）を求める
- ショートカット演算子なので、左オペランドを評価して式全体の結果が確定すれば、右オペランドは評価しない

```javascript:論理積を求める
const t1 = true;
const t2 = true;
const f1 = false;
const f2 = false;
t1 && t2    // true
t1 && f2    // false
f1 && t1    // false, f1 を評価した時点で全体の結果が確定するので t1 は評価されない
```

# ちょっと変わった使い方
MDN を見ると、以下のような説明があります。

> 一般的には、この演算子は左から右に向けて評価した際に最初の偽値のオペランドに遭遇したときにはその値を、またはすべてが真値であった場合は最後のオペランドの値を返します。

つまり、論理演算子なので常に `true`/`false` の真偽値を返すと思いがちですが、実際には以下のような挙動となっています。
- 左オペランドが `false` として扱われる値の場合: 左オペランドを返す
- 左オペランドが `true` として扱われる値の場合: 右オペランドを返す

上記の挙動に当てはめた結果、真偽値型の場合は我々のよく知る挙動となっているわけですね。

ということで、真偽値型以外に適用するとこんなことが起こってしまうわけです。
直感に反しますよね。

```javascript:田中さん AND 里田さん -> 里田さん
const tanaka = '田中まさひろ';
const satoda = '里田まい';

tanaka && satoda  // '里田まい'
```

## では最初の例は？
```react:エラーがあれば&&の右を出力
{errors.exampleRequired && <span>This field is required</span>}
```

以下の挙動となります。

### 入力チェックの結果、エラーがある場合
1. `errors.exampleRequired` に何らかのオブジェクトが入っている
1. `true` と評価される
1. 右オペランドが返されて、メッセージを出力

### 入力チェックの結果、エラーがない場合
1. `errors.exampleRequired` は `undefined`
1.  `false` と評価される
1.  左オペランドが返されて、`undefined` なので React は何も出力しない

# まとめ
Java などの、型を厳密に扱う言語に慣れていると JavaScript の `&&` の挙動は不思議に思えますね。
ですが、ドキュメントをしっかり読めば説明はあるので、注意して少しずつ慣れていきましょう。

この記事は、[私のブログ](https://yagamo-style.com/2024/js-logical-and/) にも投稿しています。

# 参考
- [論理 AND 演算子 (&&): 条件付きレンダー – React](https://ja.react.dev/learn/conditional-rendering#logical-and-operator-)
- [論理積 (&&) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND)
今更ブラウザの仕組みを勉強しはじめる

# はじめに
Webエンジニアとして満２年を経て振り返ってみると、CGIとかレンダリングとかDOMとかなんとなく分かった気でいるものがかなりあるなと反省しました。もし誤表記や疑問点等ありましたら、ご指摘をよろしくお願いします。

# 今更ブラウザの仕組みを勉強しはじめる

## Webブラウザの基本概念

### Webブラウザの役割と機能
Webブラウザは、インターネット上の情報にアクセスし、それをユーザーに表示するためのソフトウェアです。ユーザーがURLを入力すると、ブラウザはそのアドレスに対応するWebサーバーにリクエストを送信し、サーバーから送られたデータ（HTML、CSS、画像、動画など）を取得します。ブラウザの主な機能は、このデータを解析し、ユーザーに理解しやすい形式で表示することです。これにより、ユーザーはWebページを閲覧したり、オンラインでの様々な活動を行うことができます。

### HTTPプロトコルと通信
WebブラウザとWebサーバー間の通信は、HTTP（Hypertext Transfer Protocol）というプロトコルを通じて行われます。HTTPはインターネット上で情報をやり取りするための基本的なルールを定めており、ブラウザがサーバーにリソースの要求を行い、サーバーがそれに応答する形式を取ります。例えば、ブラウザがWebページを要求すると、サーバーはHTML文書や関連するCSSファイル、画像などをブラウザに送信します。

### レンダリングの概要
レンダリングプロセスは、ブラウザがWebサーバーから受け取ったデータを解析し、画面上に表示する一連のステップです。このプロセスは主にHTMLの解析から始まります。ブラウザはHTMLを解析してDOM（Document Object Model）ツリーを構築し、次にCSSを適用してページのスタイルを決定します。JavaScriptはこのプロセスに介入し、ページの動的な挙動やユーザーインタラクションに応じた変更を可能にします。最終的にレンダリングエンジンはこれらの要素を組み合わせ、ユーザーに対して視覚的にリッチなWebページを生成し表示します。

## Webブラウザの技術要素

### CGIの理解と応用
CGI（Common Gateway Interface）は、Webサーバー上でプログラムを実行し、動的なコンテンツを生成するための技術です。CGIスクリプトは、サーバー側で動作し、ユーザーからのリクエストに応じてHTMLページを動的に生成したり、データベースとのやり取りを行ったりします。例えば、フォームからの入力を受け取り、それに基づいてデータベースを検索し、結果をWebページとしてユーザーに返すプロセスは、CGIを通じて実現されます。CGIは、Webアプリケーションの初期の形態として広く利用され、現在でも多くのシステムでその基本原理が活用されています。

### DOMの構造と操作
DOM（Document Object Model）は、HTMLやXML文書のためのプログラミングインターフェースです。DOMは文書をノードのツリー構造として表現し、各ノードは文書の一部（例えばタグ、属性、テキストなど）を表します。WebブラウザはHTML文書を解析してDOMツリーを構築し、このツリーを通じて文書の内容を操作します。JavaScriptを使用することで、開発者はDOMを動的に変更でき、これによりユーザーのアクションに応じてページの一部を更新したり、新しいコンテンツを追加したりすることが可能になります。

# おわりに
表面的かもしれませんが、どのようにしてWebサイトが表示されているのかふわっと理解することができました。これを適当に理解したまま3年目を過ごす羽目にならずよかったです。（個人の主観）フロントエンド・バックエンド問わず、UIUXを考える上では良い経験となりました。

ここまで読んでいただきありがとうございました。
stimulusを用いてテーブルのtdタグ全体をリンクにする方法

私は現在、未経験からのエンジニア転職に向けてプログラミングスクールで学習をしている、いしかわと申します。

現在PFを作成していますがテーブルを描写した際に、`stimulus`を用いてテーブルの子要素全体をリンクにした内容をアウトプットとしてこちらの記事にしました。
どなたかの参考になれば幸いです。

:::note warn
プログラミング初学者なので、内容に誤り等ある可能性があります
誤りがありましたら教えてくださると幸いです
:::

環境
ruby 3.2.2
Ruby on Rails 7.0.8
stimulus 3.2.2
tailwindcss 3.3.6
daisyUI 3.9.6

# 実装
daisyUIの`tableクラス`を用いてテーブルを以下のように作成しています
```html:HTML
<tbody>
    <% @completed_requests.each_with_index do |request, index| %>
    <tr class="hover text-center" >
        <td><%= index + 1%></td> <!-- No. -->
        <td><%= request.name %></td> <!-- request.name -->
        <td><%= request.user.profile.name %></td> <!-- requestを作成したuserのname -->
        <td><%= l request.created_at %></td> <!-- requestの生成日時 -->
    </tr>
    <%end%>
</tbody>
```
このHTMLを以下のように修正します
```html
<tbody>
    <% @completed_requests.each_with_index do |request, index| %>
    <!-- <tr>タグ内容を以下のように修正 -->
    <tr class="hover text-center" data-controller="link" data-action="click->link#go" data-url="<%= group_request_path(params[:group_id], request) %>"
        <td><%= index + 1%></td>
        <td><%= request.name %></td>
        <td><%= request.user.profile.name %></td>
        <td><%= l request.created_at %></td>
    </tr>
    <%end%>
</tbody>
```
```
# tr要素がlink_controller.jsにバインドされることを示している
data-controller="link"

# tr要素内でクリックイベントが発生したときにlink_contorller.jsのgoメソッドを実行する
data-action="click->link#go"

# tr要素内にdata-urlというカスタムデータ属性を設定している
data-url=""
```




link_contorller.jsを作成します
```javascript:link_controller.js
import { Controller } from "stimulus";

export default class extends Controller {
  // goメソッドを定義
  go(event) {
    event.preventDefault();

    const url = event.currentTarget.dataset.url;

    if (url) {
      window.location.href = url;
    }
  }
}
```
```javascript
go(event) {
// 省略
}
```
`goメソッド`はHTML内の`data-action`属性を監視して特定のイベントにバインド(関連付け)されます
今回はHTMLで`data-action="click->link#go"`としているため、クリックイベントにバインドされます

```javascript
const url = event.currentTarget.dataset.url;
```
イベントが発生した要素(`event.currentTarget`)の`data-url`からURLを取得します
`dataset.url`は`data-url`にアクセスするための方法です
つまり`event.currentTarget`はクリック（イベント）が発生した要素、trタグを示しており、そのtrタグから`dataset`を使ってHTMLの`data-url=""`の内容を取得しています

```javascript
if (url) {
    window.location.href = url;
}
```
取得したURLが存在する場合、現在ウィンドウの場所(`location.href`)をそのURLに変更します。これによりページが指定されたURLに遷移します

---

実装はこれで終わりなのですが、当初は下記のようにlink_controller.jsを記述してうまく変数urlの値を取得できませんでした

```javascript:失敗ver
import { Controller } from "stimulus";

export default class extends Controller {
  go(event) {
    event.preventDefault();
    const url = this.data.get("url");
    if(url) {
      window.location.href = url;
    }
  }
}
```
発火はしているのですが`console.log(url)`を追記して実行しても`null`が帰ってくるだけでした…
`data-url`の値をデバッグしても`null`が返ってきてしまいました…
もしうまく動作しない原因がわかる方がいればコメント等で教えていただけると嬉しいです
Virtual box Ubuntu トラブルまとめ(社内用)

# トラブル一覧
1. terminalが開かない(terminal is not worked as usal)
1. sudo コマンドが使えない

## 1.terminalが開かない
- Reference 記事

https://qiita.com/towamz/items/2052f08e9e1af4068a56

:::note info
インフォメーション
- Virtual box 7.10 にUbuntu 20.04LTSをインストール
- ROSの最終版 Noeticを突っ込むため
:::
### 手順
- 記事にある通り、alt + ctrl + F3を押下で仮想コンソールに入ります。
- 記載どおりに実行します

:::note info
補足
- 今回はこの方法でも復活しませんでした・・・
- 以下に当方の環境で追加した作業を加えます。
:::

### Ubuntu Desktop
1. setting -> Language and Region をOpen
1. Manage Installed Languages
![Screenshot from 2024-01-23 12-53-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/c0be4f15-0b94-a30b-263e-868ac2c4608e.png)
3. こちらは正常なのですが、EnglishでUTF-8設定した英語（この際オーストラリアは気にしないでください。普通はUnited Statesだとおもいます）の下のEnglishがグレーアウトしていないことを確認
3. ダミーでも構わないので、他の言語を選んだりしてEngslishが黒くなるようにします

## 結果、解決
- 無事にターミナルを開くことができました。

# sudo　コマンドが使えない
## s not in the sudoers file. This incident will be reported
- @gaia003 さんの記事が一番簡単でした。

https://qiita.com/gaia003/items/f882e2d10f536e3e9a22

- alt + ctrl + F3を押下で仮想コンソールに入ります。
- 記載どおりに実行するのみ

### ポイント
> 仮想コンソールではrootでログイン
> /etc/sudoers　に自分のユーザを追加

```Ubuntu:コンソール

 usermod -G sudo '権限を追加したいユーザ'

 ```

 # まとめ
 - 普通にLinux(Ubuntu)を使ったので、Virtualboxでこういうことがあることは知りませんでした。
 - 社内非公認FAQなので、ほとんど備忘録になるんだろうなという感じです。

<details><summary>En</summary>

You can find similar topic in the  net, but Hope it will be helped your troubleshooting.

</details>
Windows11：ノート型パソコンを, たたむと, スリープになり解除されない・・・

　Windows11 ノート型パソコンを 26,000円(＋税) で, 購入して, すぐに ｢カベ｣ に, ぶちあたりました (o'(ェ)')_💻
<br>

　それは・・・カバーをたたむと, <font color="#FF0000">**画面が真っ暗になり, 戻らない・・・**</font>そんな方に向けた ｢解決策｣ です ✨
<br>




## 【スリープ状態ではなかった】

　まず, カバーをたたみ, 画面が真っ暗になるのは ｢<font color="#FF0000">**スリープ状態**</font>｣ と ｢<font color="#FF0000">**休止状態**</font>｣ の２つがあります。
 
  ですので, このことを知らないと ｢スリープ状態の解除｣ として, 検索してしまいます。この場合, もし ｢休止状態｣ が問題の原因であるときは, 解決策が見つからないことが多いです。ぼくの場合が, そうでした。それでは ｢休止状態：画面が真っ暗になる｣ のを, 解除してみましょう。
<br>


## 【休止状態の解除】

### ① ｢コントロール・パネル｣ をクリックします。
![スクリーンショット (119).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680561/1bd9a662-dd58-290f-c9ae-256540078b12.png)
<br>

### ② ｢電源オプション｣ をクリックします。
![スクリーンショット (123).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680561/bee81de8-ebec-64ae-3f5a-af40c9667543.png)
<br>

### ③ ｢カバーを閉じたときの動作の選択｣ をクリックします。
![スクリーンショット (124).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680561/022fdcef-b534-7919-47c2-aeb8f91956ce.png)

<br>

### ④ ｢休止状態｣ から ｢何もしない｣ に変更します。
![スクリーンショット (125).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680561/63fdc28b-f1d6-07a4-8e8d-5d0e460699ed.png)

<br>

　これで, カバーを閉じても ｢何もしない｣ ので, 画面が落ちた状態にはなりません。設定 ｢完了｣ です✨ お疲れさまでした✨
<br>
<br>
自作したgymnasiumのカスタム環境を登録し、別ファイルから使用する方法

# はじめに
この記事では、OpenAIによる強化学習のためのAPIであるgymnasiumにて自作のカスタム環境を登録し、その環境を使うための一連の流れをまとめています。簡単な流れとしては、
1. [ディレクトリ構造を正しく設計する](#1ディレクトリ構造を正しく設計する)
1. ["setup.py"と"__ init __.py"を形式に沿って作成する](#2setuppyと__-init-__pyを形式に沿って作成する)
1. [pip installを行ってローカルにカスタム環境を登録する](#3pip-installを行ってローカルにカスタム環境を登録する)
1. [使用したいファイルにてimportし、"env.make"によって環境を落とし込む](#4使用したいファイルにてimportしenvmakeによって環境を落とし込む)

となっています。以下では一つずつ詳しいやり方を載せていきます。

## 1.ディレクトリ構造を正しく設計する
作成したカスタム環境は後にpip installにてpcのローカルに登録します。そのためには、フォーマットに沿ったディレクトリ作りをしておく必要があります。具体的には、
```java:ディレクトリ構造
custom-gym-examples/
    README.md //無くても可
    setup.py
    custom_gym_examples/ //ハイフンは禁止
        __init__.py //resister関数はここで定義
        envs/
            __init__.py //空っぽでOK
            customEnv.py
```
となります。


この形式で作成しておけば、後に"custom_gym_examples"という名前のパッケージをローカルに登録でき、好きなpythonファイルにimportすることができます。


ちなみに、それぞれのディレクトリ名と環境をのものを記述するpythonファイル名に指定はありません。

## 2."setup.py"と"__ init __.py"を形式に沿って作成する
setup.pyは以下のように記述してください。
```python:setup.py
from setuptools import setup

setup(
    name='custom_gym_examples', #同層のディレクトリ名
    version='0.0.1',
    install_requires=[
    #gymnasiumやpygameなど用いたパッケージを記述
    ],
)
```
__ init __.pyは以下のように記述してください。
```python:__init__.py
from gymnasium.envs.registration import register

register(
    id='CustomGymEnv-v0', #好きな環境名とバージョン番号を指定
    entry_point='custom_gym_examples.envs:CustomGymEnv',#CustomEnvはcustomEnv.pyの中のクラス名
)
```
注意すべきはentory_pointの値です。
アンダーバーなどややこしい部分が多いのでしっかりと構造の中のどこを持ってきているか確認してください。

特に、:の後ろはファイル名ではなくクラス名であることに注意が必要です。

## 3.pip installを行ってローカルにカスタム環境を登録する
ここまでで、環境の整備はすべて終了です。pip installを行ってローカルに登録していきましょう。

まずはcustom-gym-examplesディレクトリまで移動してください。そこから以下のコマンドを順に行っていきます。
```terminal
cd ..
pip install -e ./custom-gym-examples
```
Successfully installed CustomGymEnv (←登録した環境名)と表示されたら成功です！！

（ここはアンダーバーではなく、ハイフンの方のディレクトリ名であることに注意してください）

## 4.使用したいファイルにてimportし、"env.make"によって環境を落とし込む
最後に実際に使っていきましょう。importとgym.make()関数を使うことで使用することができます。
```python
import gymnasium as gym
import custom_gym_examples #ここはアンダーバーの方
import time

env = gym.make('CustomGymEnv-v0')
```

これでenv変数の中に自作したカスタム環境を構築することができました。
あとは煮るなり焼くなり自由に使えます！では！！

## 参考文献
[gymの公式ドキュメント](https://www.gymlibrary.dev/content/environment_creation/)
AndroidでRealmのテーブルデータを確認する

# 背景
Android StudioでRealmのテーブルを確認したい。

# 環境
Android Studio Hedgehog | 2023.1.1
![スクリーンショット 2024-01-23 12.36.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/f5eb72a9-0552-c61f-ba4c-b6c1a50d059d.png)


## Realmテーブルの確認方法
### Device Explorerからdefaults.realmを取得
View > Tool Windows > Device Explorer
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/70d94a87-521e-c260-58a2-d07cbeb69213.png)

デバイスのエクスプローラーを掘っていく

data > data
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/7e0fb2b3-002c-9d38-ac6c-954f6aee4c9a.png)

アプリパッケージ名 > files > default.realm
![q2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/cdba6534-20d8-44cb-8ed2-df84064e9cf6.png)

default.realmを保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/7a7013dc-c6b9-1d96-1661-fa4b4d4cccef.png)

### default.realmをRealm Studioで開く
先程保存したdefaults.realmをRealm Studioで開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/91757b37-006f-336a-dca5-9b507d092d66.png)

テーブルデータを確認できる
![q3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/dd777295-f9f0-1a2e-d898-78bc599f55dd.png)

## 参考
Realmを使ってみよう(Android編)
https://kumaskun.hatenablog.com/entry/2022/02/07/003313
【AWS】EventBridgeがEC2を自動停止しなくなった

## EventBridgeに登録したEC2が自動停止しない！！
EventBridgeにEC2の夜間自動停止をスケジュールしていたはずなのに、停止しなくなっていたことに気づきました。
以前は大丈夫だったのに！無駄金かかっているじゃん！なぜだ！？

ハマったので供養のため残しておきます。

## （今回の）結論
ターゲットのInstanceIdsに、終了済（削除済）のインスタンスが含まれていたためでした。
画像の赤枠のインスタンスは存在しませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620254/f26ab6e9-9756-552a-840e-a1bff8ede633.png)

インスタンスごとにスケジュールを登録するか、エラーを監視するのが良さそうです。

## 調べたこと
* とりあえず目の前で実施し、自動停止が動いていないことを確認
* ターゲットが正しいか
* ロール/ポリシーが正しいか
* CloudTrailのログ確認　←さらっとエラーコードが出力されていることに気づく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620254/48996771-37de-8659-ce88-10dbc9935f65.png)
SMCの同期したデータソース（Synchronized Data Extensions）へ同期項目を新規追加できない？！

## 事象
SMCの同期したデータソース（Synchronized Data Extensions）で、同期項目を新規追加したいですが、選べないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/ed6ea20b-b09c-c891-c7dc-246192c723ce.png)

## 原因
Sales CloudまたはService Cloud側は、MC Connectユーザのプロファイルがその項目へのアクセス権限を持っていないからです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/b566e72d-8746-069c-bdef-47ff3603a295.png)

## 対策
FLS（項目レベルセキュリティ）をつけましょう。
意外に簡単ですが、すぐに思いつかなくて、調査には時間がかかってしまいました！
【Swift】throwsってなんやねん

# 目次
[1.throwsってなんやねん](#1-throwってなんやねん)
[2.実例](#2-実例)
[3.おわりに](#3-おわりに)

# 1. throwsってなんやねん
他言語経験者からすると、Swiftの`throws`って？？となりませんか笑
本記事では、`throws`を実例をもとに解説してみます。
一言で言うと`エラーを投げまっせ`みたいな宣言をしているんでしょうかね。。

# 2. 実例
条件
ここでは割り算の結果が以下の場合について考えます。
- ３で割り切れる：threeError
- 7で割り切れる:sevenError
相当3や7で割り切れることに対して不満があるみたいです笑

早速コードです。
成功パターン
~~~swift:throw.swift
import Foundation

enum Errors: Error {
 case threeError
 case sevenError
}
func checkErrors(a: Int, b: Int) throws {
    let answer = a / b
    if answer % 3 == 0 {
        throw Errors.threeError
    }

    if answer % 7 == 0 {
        throw Errors.sevenError
    }
}

do {
    // エラーの可能性のあるメソッドの呼び出し
    try checkErrors(a: 21, b: 21)
    print("処理成功")
} catch {
    print("処理失敗")
    print(error)
}

~~~
結果
~~~
処理成功
~~~

失敗パターン
~~~swift:throw.swift
import Foundation

enum Errors: Error {
 case threeError
 case sevenError
}
func checkErrors(a: Int, b: Int) throws {
    let answer = a / b
    if answer % 3 == 0 {
        throw Errors.threeError
    }

    if answer % 7 == 0 {
        throw Errors.sevenError
    }
}

do {
    // エラーの可能性のあるメソッドの呼び出し
    try checkErrors(a: 21, b: 7)
    print("処理成功")
} catch {
    print("処理失敗")
    print(error)
}
~~~
結果
~~~
処理失敗
threeError
~~~
解説
- エラーを返す可能性のある関数につけます
- 引数を書きおわった後にくっつけます
- `do~catch`とセットで使います※これがなくてもOK！だけどエラーが無視される

# 3. おわりに
いかがでしたでしょうか。私は他言語経験者なのでいまだに`throws`の考え方に慣れません。
ありがとうございました！
【エンジニアリング】直交性(Orthogonality)とは?

## はじめに

良いコードを書くためにどのようなことを考えたことがありますか？この目標を達成するために大きな助けとなる概念があります。それが「直交性（Orthogonality）」です。直交性は、私たちが日々直面するコードの複雑さやメンテナンスの難しさを解決するのに大きな助けとなります。今日は、効率的でメンテナンスが容易なコードを書くために役立つ直交性という概念についてお話しします。

## ****直交性とは？****

直交性（Orthogonality）はもともと数学で、二つのベクトルが互いに独立しているときに使われる用語です。ソフトウェア開発の文脈では、システム内の構成要素が互いに独立して効果的に動作するように設計することを意味します。この概念は、ソフトウェアの一部が変更されても他の部分に与える影響を最小限に抑え、メンテナンスが容易で拡張性の高いシステムを作ることを目指します。

<div align="center">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529304/067bac09-b247-8428-8347-a9e015a67a33.png" alt="属性" title="タイトル">
</div>

## **直交性が重要な理由**

### **1. エラーの最小化**

直交的なシステムは、エラー発生時にその影響を最小限に抑えることができます。これは各構成要素が独立して動作するため可能です。エラーの影響を限定的な範囲に抑えることができるため、デバッグが容易になり、システムの全体的な安定性が向上します。

### **2. メンテナンスの容易さ**

直交性を持つシステムはメンテナンスがはるかに容易です。一つの構成要素の変更が他の構成要素に大きな影響を与えないためです。

### **3. 拡張性の向上**

直交的な設計はシステムの拡張を容易にします。新しい機能が追加されるとき、既存のシステムに大きな変更を加えずに統合することができます。

## **直交性を実現する方法**

### **1. モジュール化・単一責任原則**

システムを小さく独立したモジュールに分割し、各モジュールが一つの機能のみを担当するようにします。これにより、一つのモジュールの変更が他のモジュールに影響を与えません。

### **2. 明確なインターフェースの定義**

モジュール間の相互作用は、よく定義されたインターフェースを通じて行われるべきです。これにより、内部実装が変更されても他のモジュールに影響を与えません。

### **3. 依存関係の最小化**

各コンポーネントはできるだけ互いに独立しているべきです。依存関係が多いと、一部の変更が他の部分に大きな影響を与える可能性があります。

## **直交性の実際の適用例**

実際に直交性を適用する具体的な例を見てみましょう。

1. **サービスとデータアクセス層の分離**: データベース層を抽象化することにより、データベースの変更がサービスロジックに影響を与えないようにすることは、システムの各部分を独立して維持する上で重要です。ORM（Object-Relational Mapping）の使用はこのような分離を実現し、データベースの変更（例: スキーマ変更、データベースシステムの交換など）がサービスロジックに与える影響を最小限に抑えます。
2. **フロントエンドとバックエンドの分離**: これは、ユーザーインターフェース（UI）とサーバーサイドロジック間の明確な区分を提供します。このような分離は、フロントエンドエンジニアとバックエンドエンジニアがそれぞれの領域で独立して作業を進めることを可能にし、一方の領域での変更が他方の領域に与える影響を減らします。また、APIを通じた通信は、これら二つの層間の明確なインターフェースを提供します。
3. **マイクロサービスアーキテクチャ**: 各マイクロサービスが特定の機能を独立して実行することにより、サービス間の依存関係を最小限に抑えます。マイクロサービスはそれぞれ独立して開発され、展開されることができ、これにより全体のシステムの柔軟性が向上し、変化により適応しやすくなります。サービス間の通信はAPIを通じて行われ、これによりサービスが相互に干渉せずに協力する体系を提供します。

## 結論

直交性に従うことで、システムはより堅牢で柔軟で、拡張可能になります。すべてのエンジニアがこの原則を理解し、適用できるよう努力することが重要です。これにより、より良いソフトウェア製品を作ることができます。

ソフトウェア開発の世界で直交性は常に重要な位置を占めており、これを上手く活用することが私たちのコードを一段階アップグレードする鍵と言えるでしょう。

皆さんのプロジェクトでも、どのように直交性を適用できるか考えてみてください。きっと大きな助けになるはずです。Happy coding! 🚀

## 参考
- The Pragmatic Programmer - Orthogonality
【ChatGPT有】URLから記事を読み込み、いくつか尋ねました。


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

　今回は、URLから記事を読み込み、いくつか尋ねました。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。

あしからず。
:::

　先日、
　　芥川賞を受賞された
　　　九段理江さんが
　　　　“ChatGPTなどの
　　　　　生成AIを使って
　　　　　　書いた”ことで、
　　　　　　　国内外から
　　　　　　　　声が届いています。
[生成AIを利用して書かれた第170回芥川賞受賞の九段理江「東京都同情塔」が海外でも話題に](https://t.co/qxp0kQy8ut)

　この記事をネタに、
　　やってみますw

　GPT-4で行ないます。

　では、
　　やり取りをどうぞ。

　なお、
「記事の全文は[こちら](https://gigazine.net/news/20240122-rie-kudan-reveals-use-chatgpt/)でご覧いただけます」
　　という文言が
　　　毎回出力されるので
　　　　カットします。

　また、
　　英語で出力されたところもあり、
　　　日本語での出力をその都度
　　　　指示したので、
　　　　　カットしてあります。
***
***User***
下記のURLの記事を読み込んでください。質問や指示はあとから行ないます。

https://gigazine.net/news/20240122-rie-kudan-reveals-use-chatgpt/

***ChatGPT***
GIGAZINEの記事では、第170回芥川賞を受賞した九段理江の作品「東京都同情塔」が、日本国内外で注目を集めていることが紹介されています。九段理江は、この小説の執筆にテキスト生成AI「ChatGPT」を利用したことを明らかにしました。この事実は、作品の質を評価する声や、文学におけるAI利用の倫理的な問題を議論する声など、さまざまな反応を世界中で引き起こしています。詳細はGIGAZINEの記事で読むことができます。

***User***
この記事の中で、彼女を取り上げた海外の報道機関を教えてください。箇条書きでお願いします。

***ChatGPT***
記事には、九段理江さんを取り上げた海外の報道機関は以下の通りです：

- 「ニューヨーク・タイムズ」
- 「BBCニュース」
- 「ガーディアン」

***User***
記事で触れられた賛否両論の詳細をを箇条書きで教えてください。

***ChatGPT***
記事で触れられた賛否両論のポイントは以下の通りです：

- **賛成派**:
  - AIの使用は新しい文学の形態を生み出す革新的な手法。
  - AIを利用した作品の質の高さが評価されている。

- **反対派**:
  - 文学作品にAIを使用することに対する倫理的な懸念。
  - 伝統的な作家の役割や創造性に関する問題提起。

***User***
著名人の名もあったようですが、教えてください。

***ChatGPT***
記事では、作家のスティーブン・キングが九段理江さんの作品とその執筆手法について言及しています。キングは、AIを使った文学作品についての自身の意見を表明しています。

***User***
彼の意見を教えてください。

***ChatGPT***
スティーブン・キングは、AIを使った文学作品について肯定的な意見を示しています。彼は、AIが文学の域においても創造的な貢献をもたらす可能性があると見ており、この新しい手法に対して興味と好奇心を持っている様子が伺えます。
***

　最後のスティーブン・キングの
　　ところなんですが、
　　　別の著名人が出てきたので
　　　　みなさんもご注意ください。

　同じようなことをする際は、
　　記事に必ず目を通して
　　　チェックしてください。
***
　さて、
　　九段理江さんが
　　　ChatGPTなどの生成AIを
　　　　使用したことについて少々。

　まず、
　　私は、否定派ではありません。

　でも
　　すべてを書かせることに
　　　ついては賛成できません。

　“人間が読むものは
　　人間が書くべきだ”と考えます。

　もちろん、
　　書いたものを
　　　添削するなどは
　　　　逆に、使って欲しい。

　どの方面でもそうですが、
　　“生成AIはツールだ”と
　　　いうことを
　　　　理解されていない気がします。

　よく
　　反対派が言うことを
　　　聞いていると、
　　　　ひとりの人間のようなもの
　　　　　として言っている気が
　　　　　　してきます。

　小説を書くのに、
　　今どき、原稿用紙に
　　　手書きするのは
　　　　ごく限られた作家です。

　誰もが
　　パソコンやスマホを
　　　使って書いています。

　「それを否定するのか？」を
　　否定派の人には、考えて欲しい。

　今回は、ここまで。
Create presentations based on my Excel file

[***Create presentations based on my Excel file***](https://marketplace.uipath.com/ja/listings/generate-a-use-case-slide)
***PowerPoint でつくったテンプレートのスライドに、EXCELで用意したデータを転記してくれるロボットです。***
UiPath Assistant の Marketplace のタブからダウンロードできて、すぐに使えるオートメーションです！

「***Create presentations based on my Excel file***」
![createPptFromExcel.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/db0e6b78-067a-75d0-99ef-2e9375a70db2.jpeg)

インストール後、ロボットを実行すると次のダイアログが表示されます。

![createPptFromExcel2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/315f790e-4452-8607-0960-9ea93b3b1799.jpeg)

ユースケースのプレゼン資料をEXCELのデータをもとに自動作成する目的でつくられたロボットのため、「I need to prepare inputs」から始めると、ユースケース用のテンプレートしか出力されません。

今回、わたしは独自のテンプレートで使いたいので、まずはテンプレートを作成します。

Document Understanding のテスト帳票を大量に作成するため、次の様なテンプレートを用意します。

![createPptFromExcel3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/af931f0f-4e25-c19f-9e7a-11995391d090.jpeg)

::: note
ポイントは一つ！
***EXCELから転記したい項目は「{{項目名}}」の様に2重の波括弧で囲うこと***
:::

次に、転記したい項目値を含む入力EXCELを準備します。

![createPptFromExcel4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/61a878f5-40f8-f8f9-d1e3-1fc6fdedb649.jpeg)

PowerPoint のテンプレートとEXCELの入力ファイルができたら、ロボットを起動し以下を指定します。
- Input file - 入力EXCELのフルパス
- PowerPoint template - PowerPoint のテンプレートのフルパス
- Output folder - 転記が完了した PowerPoint のファイルを出力するフォルダのフルパス

![createPptFromExcel5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/1f3c9371-454b-96c7-ab76-45e4ab9a5e34.jpeg)

「Create presentations」ボタンをクリックすると、PowerPoint のテンプレートが起動し、画面の左上から順にプレースホルダに値が入っていきます！
テストレコードは2件なので、同転記処理が2回おこなわれた後に処理完了画面は表示されます。

![createPptFromExcel5_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/ab5cf5ed-c8c6-6921-af2b-eee2108691b2.jpeg)

（成果物例1）
![createPptFromExcel6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/68f6960e-4afe-e282-32ed-40c55a2b3116.jpeg)

（成果物例2）
![createPptFromExcel7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/27cf7064-4c13-5df8-2780-dbea144d6016.jpeg)

処理後のEXCELには「Status」カラムが増えており、「Created 01.22」と作成日の情報などが入るようです。
そこで、レコードを1本増やして再実行すると

![createPptFromExcel9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/f56f9ff5-295a-b908-5954-d8ec7cc80a72.jpeg)

想定通り、***新規追加したレコード分のみ*** PowerPoint の転記済みファイルが出力されました！

（成果物例3）
![createPptFromExcel10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/a215ed70-d799-812c-5894-555dd203a659.jpeg)

::: note warn
残念ながら、出力ファイル名を指定するオプション（Get column）で入力EXCELのカラム名を指定することはできませんでした。
英字のみのカラム名を用意しても結果は変わらなかったので、原因は不明。
このため、***出力ファイルの名称は単純な連番となります。***
1.pptx
2.pptx
3.pptx
・・・
レコードを追加してリトライをかける際などは、***先に出力した分が強制上書きとなるので退避してから実行するようご注意ください。***

![createPptFromExcel11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/1044ba21-cffe-d444-31fc-5f05640f3d1b.jpeg)
:::

いかがでしたでしょうか。
AIトレンドな昨今、モデルの学習またはテスト用のドキュメントを手軽に用意したいとおもう方も多いのでは？
UiPath があれば簡単に大量のテストドキュメントもつくれます☀
興味の沸いた方は https://marketplace.uipath.com/ja にアクセスして便利なコンポーネントを是非他にも探してみてください(*´Д｀)
Rails APIエンドポイントの作成：基本操作

## **はじめに**
この記事では、Railsを使用して基本的なAPIエンドポイント（POST、PUT、GET、DELETE）を作成する方法をメモっぽく記載しておきます。

## **必要なもの**
- Ruby on Rails
- RESTful APIに関する基本的な理解

## **ステップ 1: Railsのセットアップ**
まずは、新しいRailsプロジェクトを作成する。ターミナルで以下のコマンドを実行

```bash
rails new my_api_project --api
cd my_api_project
```

このコマンドにより、API専用のRailsプロジェクトが作成される。

## **ステップ 2: モデルの作成**
今回はブログの記事を管理するための`Article`モデルを作成します。次のコマンドを実行

```bash
rails generate model Article title:string body:text
rails db:migrate
```

## **ステップ 3: コントローラの設定**
`Articles`コントローラを作成し、CRUD操作（作成、読み取り、更新、削除）を実装します。

```bash
rails generate controller Articles
```

`app/controllers/articles_controller.rb`に以下のようなメソッドを追加。

```ruby
class ArticlesController < ApplicationController
  # 各メソッドの実装
end
```

## **ステップ 4: ルーティングの設定**
`config/routes.rb`にルートを設定して、リクエストをコントローラのアクションに分けます。

```ruby
resources :articles
```

## **ステップ 5: 各アクションの実装**
- **POST (Create)**: 新しい記事を作成する。
- **GET (Read)**: 一覧表示や特定の記事を取得する。
- **PUT (Update)**: 既存の記事を更新する。
- **DELETE (Destroy)**: 記事を削除する。

各アクションの詳細なコードは以下の通り（例として`create`アクション）。

```ruby
def create
  @article = Article.new(article_params)
  if @article.save
    render json: @article, status: :created
  else
    render json: @article.errors, status: :unprocessable_entity
  end
end
```

## **ステップ 6: テスト**
Postmanなどのツールを使用して、APIが正しく動作していることを確認する。

期待したレスポンスが帰ってくれば成功！お疲れ様でした！！
Pythonでプログラムを継続的に実行させる方法


### 概要

Python でプログラムを継続的に実行させる方法はいくつか存在します。このドキュメントでは、プロフェッショナルなコーダー向けに、それぞれの方法の詳細とコード例、応用例を紹介します。

### 選択肢

**1. 無限ループ**

* 基本的な手法ですが、効率が悪くリソース消費が激しい可能性があります。
* コード例:

```python
import time

while True:
    print("タスクを実行します")
    time.sleep(5)  # 5秒おきに実行
```

* 応用例:
    - センサーデータの定期的な収集・送信
    - ウェブサイトの定期的な監視と通知
    - ゲームのメインループ

**2. スケジューリングライブラリ**

* 複雑なスケジュール設定や並列実行が容易に実現できます。
* コード例 (schedule):

```python
import schedule
import time

def my_job():
    print("タスクを実行します")

schedule.every(10).seconds.do(my_job)  # 10秒おきに実行

while True:
    schedule.run_pending()
    time.sleep(1)
```

* 応用例:
    - メールの定期送信
    - SNSへの投稿予約
    - データのバックアップ

**3. OS のジョブスケジューラ**

* システムレベルでの制御に適しています (Cron, Task Scheduler)。
* コード例 (Python から crontab を編集):

```python
import crontab

cron = crontab.CronTab(user=True)
job = cron.new(command='python my_script.py')
job.setall('0 */2 * * *')  # 2時間おきに実行
cron.write()
```

* 応用例:
    - 夜間バッチ処理
    - システムメンテナンス
    - ログファイルのローテーション

**4. バックグラウンドプロセス**

* システム起動時に自動起動するプログラムに適しています。
* コード例 (daemonize モジュール):

```python
import daemon
import daemon.pidfile

with daemon.DaemonContext(
    pidfile=daemon.pidfile.PIDLockFile('/tmp/my_daemon.pid')
):
    while True:
        # 処理を実行
        time.sleep(60)
```

* 応用例:
    - システム監視エージェント
    - ログ収集デーモン
    - ネットワークサービス

### プロフェッショナルなアプローチ

- **マルチスレッド/マルチプロセス:**
    - 大量データの並列処理、CPU負荷の高い処理の分散に有効。
- **非同期プログラミング:**
    - I/O 待ちの多い処理の効率化に役立ちます。
- **エラー処理/ロギング/モニタリング:**
    - 障害の検知と対応、運用状況の把握に不可欠です。

### 選択の指針

タスクの性質、運用環境を考慮し、最善の方法を選択・実装してください。
Azure コンテナー インスタンスでコンテナー レジストリ に登録したDockerイメージを起動する

Azure コンテナー インスタンスでコンテナー レジストリ に登録したDockerイメージを起動する手順を解説します。  

## 👇これより先は下記記事の内容を前提とします

[Azure VM で Docker イメージを作成して Azure コンテナー レジストリ に登録する](https://docs.saurus12.com/azure/docker_registory)

## リソースグループの作成

```text
az group create^
 --name container_resource_group^
 --location japaneast
```

## コンテナー インスタンスの起動

👇コンテナー インスタンスの起動  
`--registry-username`と`--registry-password`には、[Azure VM で Docker イメージを作成して Azure コンテナー レジストリ に登録する](https://docs.saurus12.com/azure/docker_registory)で取得した**コンテナー レジストリログイン情報**を指定します。  

```text
az container create^
 --resource-group container_resource_group^
 --name webservercontainer^
 --image containerregistory01.azurecr.io/webserver:latest^
 --dns-name-label webserver^
 --ports 80^
 --registry-username containerregistory01^
 --registry-password **********
```

👇アクセスFQDNの取得

```text
az container show^
 --resource-group container_resource_group^
 --name webservercontainer^
 --query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}"^
 --out table
```

下記のような出力が得られます。  

```text
FQDN                                   ProvisioningState
-------------------------------------  -------------------
webserver.japaneast.azurecontainer.io  Succeeded
```

ポート80番を公開していますので、下記がアクセスURLになります。  

```text
http://webserver.japaneast.azurecontainer.io/
```

👇ブラウザアクセスイメージ  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708851/bdbcbfe5-f97b-feb6-5ff2-d9b8b7210dda.png)

👇コンテナ出力へのアクセス  

```text
az container attach^
 --resource-group container_resource_group^
 --name webservercontainer
```

下記のような出力が得られます。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708851/107efa9d-48e7-e93c-c575-9b6235e8d380.png)

👇コンテナー インスタンスの削除  

```text
az container delete^
 --resource-group container_resource_group^
 --name webservercontainer
```

## ユーザー割り当てマネージドIDによるAzureリソースへのアクセス権限付与

ユーザー割り当てマネージドIDによるAzureリソースへのアクセス権限付与する手順は下記記事参照下さい。  
[ユーザー割り当てマネージドIDによるAzureリソースへのアクセス権限付与](https://docs.saurus12.com/azure/user_manage_id)

## 👇関連記事

- [Azure CLI で Ubuntu のVMを起動/削除する](https://docs.saurus12.com/azure/ubuntu_vm)
- [Azure VM で Docker イメージを作成して Azure コンテナー レジストリ に登録する](https://docs.saurus12.com/azure/docker_registory)
- [ユーザー割り当てマネージドIDによるAzureリソースへのアクセス権限付与](https://docs.saurus12.com/azure/user_manage_id)

## 👇参考URL

- [クイック スタート:Azure CLI を使用してコンテナー インスタンスを Azure にデプロイする](https://learn.microsoft.com/ja-jp/azure/container-instances/container-instances-quickstart)
- [az container create](https://learn.microsoft.com/ja-jp/cli/azure/container?view=azure-cli-latest#az-container-create)

## 本記事へのリンク

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708851/9b279686-62dd-123b-20f5-4b8459451d51.png)

### [https://docs.saurus12.com/azure/docker_container_create](https://docs.saurus12.com/azure/docker_container_create)

[keywords]  
Azure コンテナーインスタンス コンテナーレジストリ Docker

[Azure コンテナー インスタンスでコンテナー レジストリ に登録したDockerイメージを起動する](https://docs.saurus12.com/azure/docker_container_create)

更新日:2024年01月23日
Blazor WebAssemblyのベンチマークをとってみた

.NETの新しいWeb技術であるBlazor、大きくBlazor ServerとBlazor WebAssemblyの2種類の動作形態があることは皆さんご存知（？）ですね。そして.NET 8では、これにさらに[様々な新機能も追加](https://learn.microsoft.com/ja-jp/aspnet/core/release-notes/aspnetcore-8.0?view=aspnetcore-8.0)されてきています。

今回はこのうちBlazor WebAssemblyの実行パフォーマンスについて検証してみます。

# WebAssemblyは速いだろうと思っていたな？

まず最初に、WebAssemblyは下記[Wikipedia](https://ja.wikipedia.org/wiki/WebAssembly)の解説にもあるとおり、ネイティブ（バイナリ）相当のコードが実行されるため速い！というイメージがありますね。
> ネイティブコード相当の高速性・隔離環境でのメモリ安全な実行による安全性・仮想マシンによるハードウェア/プラットフォーム可搬性・ソースプログラミング言語中立性などを特徴とする。

それを期待してベンチマークをとってみたのが、2023年に登壇した[BuriKaigi](https://toyama-eng.connpass.com/event/265774/)でのことでした。
下記のような、モンテカルロ法で円周率を近似計算するプログラムを走らせてみて、

```C#
private static double MontePi(int n)
{
    var rand = Random.Shared;
    var count = 0;
    if (n < 1) return 0;
    for (int i = 0; i < n; i++)
    {
        var x = rand.NextDouble();
        var y = rand.NextDouble();
        if (x * x + y * y <= 1)
        {
            count++;
        }
    }
    return 4.0 * count / n;
}
```

結果、こちらのようにJavaScriptの約20倍遅いという、惨敗といえるベンチを叩き出していました。
```
モンテカルロ法 円周率近似計算
50,000,000 サンプル

Blazor WebAssembly
9586 ms
9594 ms
9500 ms

JavaScript
521 ms
536 ms
537 ms
```

# 1年を経て逆転！？

そして翌2024年の[BuriKaigi](https://toyama-eng.connpass.com/event/303732/)で、このようなツイートを目にします。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">昨日はたくさんのセッションと美味しい鰤をどうもありがとうございました!<br>一点余談ですが Blazor WebAssembly は遅いです。理由は MSIL をインタープリタで実行するからです。インタープリタが Wasm 上で走ってます。AOT すると改善されます。Wasm自体はそれなりに速いです。<a href="https://twitter.com/hashtag/burikaigi_h?src=hash&amp;ref_src=twsrc%5Etfw">#burikaigi_h</a> <a href="https://twitter.com/hashtag/burikaigi?src=hash&amp;ref_src=twsrc%5Etfw">#burikaigi</a> <a href="https://t.co/Fq6P3OMhGp">pic.twitter.com/Fq6P3OMhGp</a></p>&mdash; @jsakamoto (@jsakamoto) <a href="https://twitter.com/jsakamoto/status/1748879026691907828?ref_src=twsrc%5Etfw">January 21, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[Blazor WebAssemblyのAOTコンパイルによる高速化とAzure Static Web Appsへのデプロイ](https://qiita.com/kaorumori/items/88d836fab1fcbbbb7114) の記事を参考に、ベンチマークしていたプロジェクトを再ビルドします。

具体的には、下記2つの手順で完了です。
1. VisualStudioを終了させた状態で、コマンドラインから`wasm-tools`ワークロードをインストールする
```
> dotnet workload install wasm-tools
```

2. VisualStudioを起動し、Blazor WebAssemblyプロジェクトの `ビルド > 全般 > 公開時にAhead Of Time(AOT)コンパイルを使用する` にチェックを入れる

これで再度ベンチマークしてみた結果がこちら。
それでもJavaScriptには及ばないとはいえ、AOTなしに比べて圧倒的なパフォーマンスを得ることができました！
```
モンテカルロ法 円周率近似計算
50,000,000 サンプル

WebAssembly AOTなし
9586 ms
9594 ms
9500 ms

WebAssembly AOTあり
1112 ms
1047 ms
1034 ms

JavaScript
521 ms
536 ms
537 ms
```

# とはいえ
このように、AOTを有効にすることで圧倒的パフォーマンスを得ることには成功しましたが、[.razorページに当てていたcss](https://learn.microsoft.com/ja-jp/aspnet/core/blazor/components/css-isolation?view=aspnetcore-8.0)が一部無効になっていたり、少なくともReflectionが使えなくなるはずだったり、ノールックで採用できるものではなさそう、ということも分かってきました。
あと、バイナリサイズも大きくなるようなので、ページの初回ロードでユーザーを待たせるというデメリットもありますね。

これらデメリットを補って余りあるパフォーマンスであるとも考えられるので、状況さえ許せば積極的に採用していきたいものではありますね！
firebase deployでCannot deploy a web framework to hosting because the experiment webframeworks is not enabledエラーが出る

# はじめに

firebaseのデプロイを別のPCで行うときに躓いたところをまとめます

# 問題

```
$ firebase deploy
```

デプロイしようとするとエラーが発生してしまった

```
Cannot deploy a web framework to hosting because the experiment webframeworks is not enabled. To enable webframeworks run firebase experiments:enable webframeworks
```

# 解決方法

以下を実行したらデプロイできるようになった

```
$ firebase experiments:enable webframeworks
```

# おわりに
よく理解はしていないが解決できたのでよかったです