OmniAICreator/Qiita-1.07M huggingface dataset:
一瞬でHTMLの構造を把握出来るChromeの拡張機能を紹介

# はじめに
こんにちは、RAOです。

WEBアプリケーション開発を行っている際

「この画面ってHTMLの構造どうなっているんだろう」
「なんかアイコンの位置ズレてる気がする、、」

って事よくあると思います。

こんなシーンに役立つChromeの拡張機能を紹介したいと思います。

本記事はHRBrain Advent Calendar 2023の17日目の記事です。

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

# UI Build Assistant
こちらが今回ご紹介するChrome拡張機能です。

https://chromewebstore.google.com/detail/ui-build-assistant/clbhieamajlakjobcoiheklaoldcjhjf?pli=1

それでは早速使ってみましょう。
今回はZennを例にします。（特に意味は無いです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/9a1f18cf-1492-f423-3418-533d1d20236d.png)

拡張機能をONにすると以下のようになります。少しびっくりしますがこれが正常です。
どうなっているか開発者ツールを除いてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/4327e199-31af-ce80-634d-d749ebaeee29.png)

ある要素を適当に選択してみると以下のスタイルが`!important`で上書きされていますね。
見る限り`background-color`と`outline`が設定されており、HTML要素が縁取られ輪郭がわかりやすくなっていますね。
2枚目の写真は1枚目の子要素なのですが`background-color`が少し濃くなっており、重なりも分かりやすくなっていることが見て取れますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/c3ca583a-231b-20f7-e843-ff81f1194252.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/e6ba9d2a-e3b8-5ac8-1717-88410fdf7bd5.png)

# 活用シーン
自分が活用しているシーンを紹介します。

以下の画像はZennの右上部分を拡大したものです。そして開発者ツールであるCSSを削除しています。

ぱっと見違和感がありますね。拡張機能をONにしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/36ab14d7-e79f-0bae-8b4c-d289c6609dd3.png)

アイコンやボタン類はまとめて一つの要素に囲まれており、虫眼鏡アイコンは親要素の中で上に位置していることが分かります。
ここから「親要素に`align-items: center;`が抜けているのでは？」という仮説を立てる事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/238f4f09-8844-60e5-8a0a-3122796e843a.png)

実際にスタイルを見てみるとチェックが外れています。（自作自演）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864822/169c791b-f77d-ed42-6327-4169cc011f0e.png)

このように

子要素が親要素のどこに位置しているのか？
どのようなHTMLの構造になっているのか？

を瞬時に把握することが出来ます。
開発者ツールの要素を選択して検査やコード上から遡ることは出来ますが、こちらの方がより直感的ですね。

# 終わりに
今回はHTMLの構造を把握できるChromeの拡張機能をご紹介しました。
この拡張機能のお陰で、HTMLの構造確認→開発者ツールでCSSをイジる→コードに転記のサイクルを高速で回すことが出来るようになりました。紹介したシーン以外にも色々活用シーンがあると思います。

株式会社HRBrainでは新しいメンバーを募集しています。

https://www.hrbrain.co.jp/recruit
JavaScriptの再帰関数とスタックオーバーフロー 　　　〜トランポリンに非同期処理を添えて〜 ①

# はじめに
初投稿になります、[株式会社 ONE WEDGE](https://qiita.com/organizations/onewedge)の [＠Shankou](https://qiita.com/shankou) です。

今回はJavaScriptの非同期関数の再帰処理についてのすごくふんわりとした解説記事になります。
アルゴリズムの専門家でも、言語の設計者でもない、主に先輩風を吹かせて後輩に読ませようと思って書いているだけの記事となりますので、間違いがあったら優しく指摘していただけると嬉しいです。主に初心者から中級者の方向けの内容になりますので、あまり深く突っ込まないでください。 

~~二重三重の予防線~~

Scalaを触っていた経験から、末尾再帰とトランポリンについてのぼんやりとした理解は持っていましたが、少し前に仕事で「JavaScriptで非同期関数の再帰呼び出し」を考えなきゃいけない機会がありましたので、知識の整理がてらちょっとまとめてみようと思った次第です。



# 再帰関数
再帰関数って何？ っていう初心者の方は、こちらの解説記事（ [再帰関数を学ぶと、どんな世界が広がるか](https://qiita.com/drken/items/23a4f604fa3f505dd5ad), [@drken](https://qiita.com/drken) ）が図説付きで分かりやすくておすすめです。

再帰関数の定義には大きく2つのポイントがあります。

1. 終了条件を持たなければならない
1. 状態を変えながら終了条件に進んでいかなければならない

これを満たすことができない場合、無限再帰ループと言って、いわゆる無限ループと同じ状態になってしまいます。

さて、問題となるのは再帰の回数が多くなるとスタックオーバーフローが発生するということです。そもそも、再帰処理というのはループで書き直すことができます。
先程の条件を読んだときに「これってループ処理じゃね？」思った人もいるでしょう。その通りです。そして、ループ処理というのはスタックを積むことがないので、オーバーフローが発生しません。

！！？？？？？

じゃあ、そもそもなんで再帰関数なんかを使うのかというと、再帰の方がスッキリ書けるという理由もありますが、その源流には関数型プログラミングの影響があったりします。

近年、オブジェクト指向と関数型の融合、イイトコドリのようなものが様々な言語で進んでいると思います。Javaでラムダ式や関数型インタフェースが導入されたりもしていますしね。

関数型プログラミングでは状態変数は最大悪です。そして、その代表悪がループで使われるカウンター「 i 」の存在です。
プログラミングを始めたばかりの頃にデバッグでグルグルと、今の「 i 」はいくつだ？ 配列のどこを指しているんだ？ みたいなことを追いかけた記憶があると思います。あれは「 i 」がそのときどきで変化する状態変数であるからこそ発生する問題です。
状態変数はバグの温床であり、状態変数を持たないだけでこの世に存在するバグの9割は消せます。（当社比）

近年のオブジェクト指向言語は、できるだけ余計な状態変数を持たないように論理フローを構築しましょうね、という感じで関数型の概念を取り込んでいる感じです（あってるよね？）。

そして、関数型では副作用のない小さな関数を作り、その組み合わせで大きな処理を構築するというのが基本的な考え方になります。再帰の考え方もこれと同じで、ループという大きな処理ではなく、小さな関数を組み合わせて(自身の再呼び出しを行うことで)全体を処理するという流れをとります。こういった考え方、手法を分割統治法というそうです。このあたりがループと再帰の考え方の違いになります。

さて、問題となるのは再帰の回数が多くなるとスタックオーバーフローが発生するということです。そもそも、再帰処理というのはループで書き直すことができます。ループ処理というのはスタックを積むことがないので、オーバーフローが発生しません。

！！？？？？？

break;

このままでは話がループして進まないので、それではどうやって再帰処理でのスタックオーバーフロー問題を解決するのか、という話に移ろうと思います。

一般的には末尾再帰による最適化という手法が取られます。

# 末尾再帰による最適化

末尾再帰による最適化というのは、末尾再帰を検知したコンパイラがスタックの累積をなくして処理の効率化を行ってくれるというものです。実装者は末尾再帰を意識して再帰関数を作ればいいということになります。

では、末尾再帰とはどういったものかというと、簡単に説明すれば自身の呼び出しで処理が終わっている再帰関数のことです。
あるあるですが、階乗を計算する関数をJavaScriptでの例で示します。

```js:
const factorial = (n) => {
  if (n === 0) return 1
  else return n * factorial(n - 1)
}

console.log(factorial(6)) // 720
```

普通に階乗を計算する再帰関数を作ると上記のようになると思います。「n * factorial(n - 1)」で自身を呼び出した結果を利用して、最後に計算をしてしまっている形です。これは「自身の呼び出しで処理が終わっている」ことにはならないので末尾再帰ではありません。

この関数に10000くらいを渡すとスタックオーバーフローが発生しました。

それではこの再帰関数を末尾再帰に書き直してみたいと思います。以下の通りです。

```js:
const factorial = (n, accumulator = 1) => {
  if (n === 1) return accumulator
  else return factorial(n - 1, accumulator * n)
}

console.log(factorial(6)) // 720
```

先程とは違い、「factorial(n - 1, accumulator * n)」 という自身の呼び出しで処理が終わっています。末尾再帰ではaccumulator（累算器、積算器、加算器）という途中計算を保持する変数がよく使われるそうです。途中計算を引数で渡し歩くことが末尾再帰を実装する上でのミソとなるんですね。

この関数に10000くらいを渡すとスタックオーバーフローが発生しました。

！！？？？？？

末尾再帰による最適化ですが、JavaScriptではまだまだサポートが追いついていません(執筆時点でSafariのみの限定対応だと思われます)。

では、末尾再帰による最適化が行われない場合はどうすればいいのか、というところで登場するのがトランポリンという手法になります。

意外と長くなったので[②に](https://qiita.com/Shankou/items/5e1e441feefb6a9ee3f6)続きます。

---

:::note info
社員の成長支えます。そう[ONE WEDGE](https://qiita.com/organizations/onewedge)ならね。
:::
Mistralをmlx変換して使ってみる

Appleが最近MLXという機械学習用のフレームレートリリースしたので、
MLXフレームワークMistral 7B変換してM1 ultra メモリ64Gで検証したいと思います。

# MLXとは

MLXは、Apple Silicon向けに設計された効率的かつ柔軟な機械学習用の配列フレームワークです。Appleの機械学習研究チームによって開発されました。Python APIはNumPyに非常に似ており、いくつかの例外を除いて、直感的に使用できます。また、Python APIに似たフル機能のC++ APIも提供しています。

今回はmlx使ってMistral 7BのモデルをApple Silicon最適化のモデルに変換して使います。

# Mistral 7B

Mistral 7BはフランスのAIスタートアップMistral AI社が開発した大規模言語モデルで、Sliding Window Attention(SWA)やGrouped-query attention(GQA)といった新しい注意メカニズムを採用することで、Llama 2などよりも小さいモデルサイズで高い性能が得られているとされています。8Gメモリーでも動くことができます。


# 変換して使う

## mlx-examples
``` shell
# mlx-examplesをダウンロード
git clone https://github.com/ml-explore/mlx-examples.git
cd mlx-examples/mistral
pip install -r requirements.txt
```

## Mistral 7Bモデルダウンロード

```shell
# 13.4Gあるので、時間かかります
curl -O https://files.mistral-7b-v0-1.mistral.ai/mistral-7B-v0.1.tar
tar -xf mistral-7B-v0.1.tar
```

## mlx使ってApple Silicon最適化のモデルに変換

``` shell
# モデル変換
python convert.py
```


## Mistral 7B使う

```shell

# prompt入れる。tokenはデフォルト100なので、-mで変更できます
python mistral.py --prompt "It is a truth universally acknowledged,"  --temp 0 -m 200
``` 


# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9564/b39c4dc3-ed0c-a1cb-cfc8-de12e5a2f482.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9564/8bbae87f-e533-e67e-2294-d4d3267d98c4.png)

m1 ultraは余裕で動くことができました。
図の通りGPUとメモリーがつかわれてることがわかります。
強いGPUもってるwindows PCがもってないので、比べることはできませんでしたが、
Mistral実行時に16wぐらいしか電力消費してるのを驚きました.


# ほか

mlx-examples内にもLLaMA2、Mixtral 8x7BとWhisperの変換例も書いてるのでそれも試せます。
LLaMA2:7bは8Gでも動きますが、Mixtral 8x7Bメモりだと100G以上メモリが必要です。

# 参考
https://github.com/ml-explore/mlx
https://github.com/ml-explore/mlx-examples
https://huggingface.co/mistralai/Mistral-7B-v0.1
bashでJava実行ワンライナー

# はじめに
こんにちは､絶賛Java修行中の@fsd-shoyaです｡
.javaファイルをすべてコンパイルして実行する｡というコマンドを毎度叩くのに嫌気が差したので､再利用可能なワンライナーを書いてみました｡

# 実行環境

```bash
$ echo $SHELL
/bin/bash
$ java --version
openjdk 21.0.1 2023-10-17
OpenJDK Runtime Environment (build 21.0.1+12-Ubuntu-222.04)
OpenJDK 64-Bit Server VM (build 21.0.1+12-Ubuntu-222.04, mixed mode, sharing)
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"
```
:::note info
WSL2を使用しています
:::

# 今回使用するコード
### 構成
本記事では複数ファイルをコンパイルして実行するため､2つのファイルを作成しています｡
<pre>app/
├── Main.java
└── sub
    └── Sub.java</pre>
### コード
```java:app/Main.java
package app;
import app.sub.Sub;
public class Main{
        public static void main(String[] args){
                Sub.helloworld();
        }
}
```
```java:app/sub/Sub.java
package app.sub;
public class Sub{
        public static void helloworld(){
                System.out.println("Hello, world");
        }
}
```

# Before
まずは今まで私が打っていたコードを見てみましょう｡
```bash:bash
javac app/Main.java app/sub/Sub.java
java app.Main
```
上記では､javacの引数にファイルを1つずつ追加しています｡
今回扱うjavaファイルは2つだけなので大変ではありませんが､今後ファイルが増えていくことを考えると､より短く､汎用性のあるコマンドで実行出来るのが望ましいです｡

# 改善してみる
それでは改善してみましょう｡
まずはカレントディレクトリ以下のすべてのjavaファイルを取得します｡
```bash:bash
find ./ | grep java
```
次に､上記コマンドの返り値をjavacの引数にします｡
```bash:bash
find ./ | grep java | xargs javac
```
最後に､javaを実行すると完成です｡
```bash:bash
find ./ | grep java | xargs javac && java app.Main
```
正しく実行されると､`Hello, world`と出力されるはずです｡
# After
出来上がったものがこちらになります｡
```bash:bash
find ./ | grep java | xargs javac && java app.Main
```
どんなにjavaファイルが増えてもこの1行で実行出来るようになりました｡
だいぶスッキリしましたね｡

# おまけ
無事1行に収まりましたが､毎度入力するのも大変です｡
そこで､シェルスクリプトにすることでより簡単に実行してみましょう！
appディレクトリのある場所でrunファイルを作成します｡
```bash:bash
vi run
```
```bash:run
#!/bin/bash
find ./ | grep java | xargs javac && java app.Main
```
runファイルの実行権限を付与して実行します｡
```bash:bash
chmod +x run
./run
```
正しく実行されると､先程と同様`Hello, world`と出力されます｡

# さいごに
いかがでしたでしょうか？

コンパイルして実行の2ステップを1行で済ますことが出来ました｡
Javaのみでなく､C言語などのコンパイル言語でも本記事を応用することで､コンパイルして実行することが出来るようになるかと思います｡
M1 MacbookでAMD版terraformをtfenvで管理する


# 概要
terraformでarm版で使えないproviderがあったので、M1 Macbookにamd版terraformをインストールを行い、tfenvで管理できるようにします。

## amd版terraformをインストール

今回は1.3.9をダウンロードしたいので、こちらをダウンロードしていきます。
```
$ wget https://releases.hashicorp.com/terraform/1.3.9/terraform_1.3.9_darwin_amd64.zip
```
直接ダウンロードしたい場合は以下のURLをクリックすると、versionごとのterraformをダウンロードすることができるサイトに飛びます。

https://releases.hashicorp.com/terraform/

zipファイルがダウンロードされるので、こちらを解凍します。
```
$ unzip terraform_1.3.9_darwin_amd64.zip
```
一応実行してみると、amd版だと表示されます
```
$ ./terraform version

Terraform v1.3.9
on darwin_amd64

Your version of Terraform is out of date! The latest version
is 1.6.6. You can update by downloading from https://www.terraform.io/downloads.html
```

## tfenvで管理する
上記でダウンロードしたamd版terraformだけでなく、arm版のterraformを使いたいケースがありました。
なのでamd版terraformをtfenvで管理するようにします。
tfenvは以下はApple silliconのMacbookの場合、`/opt/homebrew/Cellar/tfenv/${tfenv version}/versions/`配下で異なるversionのterraformを管理しています。
自分の環境の場合は以下になります。
```
$ pwd

/opt/homebrew/Cellar/tfenv/3.0.0/versions
```
その場でlsを実行するとこれまでtfenvでインストールしたversionごとのterraformが見れます。
```
$ ls
1.0.10/    1.1.0/     1.2.0/     1.5.4/
```
なのでこのディレクトリ内でamd版terraformのディレクトリを作成し、terraformのバイナリファイルを移動させればtfenvで管理することができます。

なのでこちらにディレクトリを作成します。
```
$ mkdir amd1.3.9

$ ls
1.0.10/    1.1.0/     1.2.0/     1.5.4/     amd1.3.9/
```
この段階で`tfenv list`を実行してみます。
```
$ tfenv list
  1.5.4
  1.2.0 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
  1.1.0
  1.0.10
* amd1.3.9
  ```
まだterraformのバイナリファイルを移動させてきていませんが、この段階で表示させることができます。もちろん`tfenv use`でamd1.3.9を指定すると、エラーになります。
```
$ tfenv use amd1.3.9
Version directory for amd1.4.0 is present, but the terraform binary is not! Manual intervention required.
```
ここで、amd版terraaformのバイナリファイルを移動させます。
```
mv ~/Desktop/test-terraform/terraform amd1.3.9
```
これで再度`tfenv use`を実行します。

```
$ tfenv use amd1.3.9
Switching default version to vamd1.3.9
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: amd1.3.9
```

terraformのバイナリファイルを格納したことで、無事に`tfenv use`が実行できました！
またterraformのversionも確認します。

```
$ terraform version
Terraform v1.3.9
on darwin_amd64

Your version of Terraform is out of date! The latest version
is 1.6.6. You can update by downloading from https://www.terraform.io/downloads.html
```

ダウンロードしたamd版であることが確認できました。
これでtfenvで管理することができるため、arm版とamd版のterraformを使い分けることができます。

# 終わりに
今回はかなり特殊な事例ですが、もし困っている方がいたら参考になればと思います。
【ChatGPT】の回答が以前と違う？


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

　今回は、ChatGPTの回答が、以前とは違うのを確認したので、注意喚起します。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　今回は、
　　注意喚起です。

　ChatGPTを使っていると、
　　わかることですが、
　　　同じプロンプトを与えても
　　　　生成される文章は
　　　　　固定化されていません。

　これは、
　　文章生成AIの仕組みを
　　　考えると、仕方ないことです。
　　　　詳しくは、お勉強してねw

　それでも
　　基本的に、
　　　回答内容は
　　　　変わりません。

　しかし、
　　それが変わる場合があります。

　ChatGPTの持つデータセットが
　　更新された場合です。

　これは、
　　教科書の内容が
　　　新しくなるのに似ています。

　社会科や歴史なんかは、
　　コロコロ変わりますよね。
　　　これは仕方ないことです。
　　　　歴史も、新事実は出てくる。
　　　　　それらをそのままに
　　　　　　しておけません。

　同じように
　　データセットも更新されます。

　ChatGPTは、2023/12/15現在で、
　　2021年9月までだった情報が
　　　現在は、3.5で、2022年1月。
　　　　　　　4で、2023年4月に
　　　　更新されています。

　これにより、
　　過去に入力したプロンプトの
　　　回答が、変化してきています。

　一例を示します。
***
***User***
「スマホ熱中症」とは、なんですか？

上記の問いが、あなたの知識の中に単語として存在しているかを答えてください。存在しない場合は、「最後に」に飛んでください。

上記の問いの回答を事実にもとづいて、出力してください。

最後に。

***ChatGPT（2023/10/11）***
「スマホ熱中症」という言葉は私の知識には存在しません。したがって、詳細な情報を提供できません。何か別の質問や情報が必要な場合はお知らせください。

***ChatGPT（2023/12/15）***
「スマホ熱中症」は、長時間スマートフォンを使うことで引き起こされる症状です。画面を見つめることによる目の疲れや、首・肩のこり、頭痛などが主な症状です。この状態は、適度な休憩や運動を取り入れることで緩和することができます。
***
　このように、
　　データセットが更新されて、
　　　その回答が変わってしまう。

　これは、
　　ちょっとした処理ならば
　　　許容できることかも
　　　　しれません。

　しかし、
　　業務上の決断を
　　　回答結果でするような
　　　　場合は、要注意です。

　お気を付けてください。

　今回は、ここまで。
Git rebase mergeの動作の差を確認した

# Gitが全くわからない

Git難しくないですか？

あるブランチの変更を別のブランチに統合するための手法がいくつか準備されていてどれ使っていいかわからん。

それぞれの特性が何なのか？今どっちを選択すべきか？

そんな疑問が一生ついてまわっていた。

ということで今回はmergeとrebaseについて調べてまた一つ成長していこうと思う。

## 登場人物

- mainブランチ
- featureブランチ

## mergeの基本

マージ(merge)とは`複数のものを統合して一つのものにする`という意味で、gitでも2つのブランチの変更内容をまとめるという操作をする。

featureブランチにmainブランチの変更コミットC3をmergeする場合は以下のようになる。

merge前
```
C1---C2---C3      : main
      \
      C4---C5     : feature
```

```sh-session
$ git merge main
```

merge後
```
C1---C2---C3           : main
      \
      C4---C5---C6     : feature
```

mainのC3コミットを取り込む際には新しいコミットC6が生成される。


ちなみにfeatureブランチにC4, C5コミットがない場合はfast-forward mergeとなり、C3コミットのまま取り込まれる


merge前
```
C1---C2---C3      : main

C1---C2           : feature
```

```sh-session
$ git merge main
```

merge後
```
C1---C2---C3           : main

C1---C2---C3           : feature
```

## rebaseの基本

rebaseとはベースを変更するみたいな意味を持つ（と思っています）。

rebase前
```
C1---C2---C3      : main
      \
      C4---C5     : feature
```

```sh-session
$ git rebase main
```

rebase後
```
C1---C2---C3                    : main

C1---C2---C3---C4---C5     : feature
```

このようにブランチの派生元の変更をベースに取り込んで現在のブランチの変更を追加したような形になる。

## じゃあ全部rebaseで良くない？

個人的にはrebaseは反対している。

理由は2つで

- 過去のコミットの履歴を変更するからリモートリポジトリにpushするときにforce pushになる
- コンフリクトを解消するのとても大変

### 過去のコミットの履歴を変更するからリモートリポジトリにpushするときにforce pushになる

upstreamブランチに対してpushする際に`failed to push some refs to`というメッセージを見たことある人は多いだろう。

これはブランチをpushする際にはfast-fowardであることが期待されていて、履歴が変更されると通常のpushはできなくなる。

その場合はforce pushする必要があるが、これはとても危険。

履歴が強制的に書き換わるためチーム開発なら全員のローカルリポジトリに影響を及ぼす。

可能な限りやめていただきたいところ。

### コンフリクトを解消するのとても大変

コンフリクトはエンジニア的に超嫌なワードだと思う。

以下の状況を考える。

rebase前
```
C1---C2---C3      : main
      \
      C4          : feature
```

C3とC4のコンフリクトがあった場合にrebaseの結果どうなるかを解説する。


```sh-session
$ git rebase main
```

アウトプット
```
Auto-merging {ファイル名}
CONFLICT (content): Merge conflict in {ファイル名}
error: could not apply {コミットハッシュ}... update {ファイル名}
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply {コミットハッシュ}... update {ファイル名}
```

はい、読んでるだけで嫌になりますね。

基本的にはファイルでコンフリクトが起きているので解消してから以下コマンドで進められます。

```sh-sesshon
$ git add {ファイル名}
$ git rebase --continue
```

アウトプット
```
Successfully rebased and updated refs/heads/feature.
```

はい、めでたくrebaseはできました。この状況でlogを確認するとブランチの履歴は以下のようになる。

rebase後
```
C1---C2---C3              : main

C1---C2---C3---C4         : feature
```

コンフリクトを解消することで同様にrebaseできました。

## 結論どっち使うか

正直理解しているならどっち使ってもOK。

gitの作者がコマンドとして作っているので、目的にあうコマンドを選びましょう。

自信のない方は一旦全部コミットしておけば後からの変更はなんとかやりやすい。

こっそり練習してgitのコマンドの意味と動きを確認しましょう！
割れ物注意

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の9日目の記事です。

# 割れ物とは

ガラス製品や瀬戸物ではなく、非合法的に配布・販売されているソフトウェアのことです。

【語源】 非合法的に配布・販売されているソフトウェアを英語で「Warez」ということから、日本では「ワレズ」、「割れず」、「割れ」、「割れ物」と表記されるようになった。

違法な物で注意すべき物でもあるから、そういう意味でも「割れ物注意」でした。

昔のソフトウェアはインターネットを通してライセンスをチェックする仕組みがなかったので、シリアルコードがあれば何回でもインストール可能でした。WindowsもWindows2000まではその仕組みだったため、一つのWindows2000のソフトウェアで何百台ものPCにインストールして著作権法違反で捕まる事案がちょいちょいありました。

まだ、秋葉原がオタクの街ではなく電気街だったときは、道端でOfficeなどのソフトウェアを格安で販売していたりしました。

# たまにトラップも

違法ではあるもの使う側にとっては無料や格安で使えるのはありがたいものの、たまにトラップがあり、Photoshopの割れ物をダウンロードしてインストールしようとしたら、ハードディスク全消しされた知人がいます。

ウィルスなど何仕込まれているかわからないので、賢明な皆様は不正規なものは使わない方がよろしいかと思います。
STUDIOを導入しました

[Globee Advent Calendar](https://qiita.com/advent-calendar/2023/globee) 18日目の記事です。

こんにちは。再びの登場失礼します、Globee２人目のデザイナー苗村です。
([前回記事はこちらです](https://qiita.com/snaemura/items/dea89ef3b612da552a92))

これまでデザインの領域でグラフィック・イラスト・動画等を具体化してきましたが、WEBデザイナーと名乗ったことは一度もありません。Globeeにジョインする前に2度、LPデザインをした経験がある程度。WordPress・HTML等の知見はないに等しいです。そんな私がSTUDIOを使ったお話しです。


## STUDIO
「WEB制作を、ノーコードで。」のコピーの通り、コーディング不要でドラック＆ドロップで簡単にWEB制作ができるツールです。
STUDIO ▶️ https://studio.design/ja

## 公開されたLP
### abceed法人サービス 
https://lp-corp.abceed.com/

### ABCEED ENGLISH
https://english.abceed.com/


## 導入の目的
開発部としてサービス(プロダクト)の開発にリソースを確保したいという点に尽きます。リソースの確保は多くの企業が悩む点ではないでしょうか。

## STUDIOを使う
### ❶Figmaでデザイン
今回はFigmaでデザイン作業を進めました。この段階でSTUDIOからデザインするパターンも少なくないと思いますが、今回はデザインが概ねOKとなってからSTUDIOで制作しました。
### ❷Figma to STUDIO
ざっくり言うと、Figmaのデザインデータをコピー&ペーストでSTUDIOへ持っていくプラグイン。Beta版で利用しましたが、現在は正式版がリリースされています。
[Figma to STUDIO](https://www.figma.com/community/plugin/1274345780965443906/figma-to-studio)

ある程度崩れないようにグループ化しておく等、コツはありますが、ペースト時にタブレット・モバイルの表示崩れは起こります。Beta版だからと言うわけでもなさそうです。
Figma to STUDIOは今後も更新されていくと思うので、更なる進化に期待します。

### ❸STUDIO
３ステップ目でSTUDIOで調整していきました。この段階でFigmaは素材書き出し用の下請けになります。作業のしやすさは冗談抜きで感動したのを覚えています。ほぼリアルタイムでプレビューに反映されるので、トライ&エラーがとにかく速いです。イメージしていたWEB制作のコミュニケーションコストがごっそりカットされます。
調子に乗ってアニメーションをつけ(空気感や印象はとても良い反面、表示速度や遅れがネックでした。特にモバイル)最終的に削除したのはここだけの話です。
ただ、全てが直感的に分かり、最も簡単に作業ができたわけではありません。チュートリアルや解説してくれているサイト等を参考に進めたのは事実です。



### 運用・課題
まだ公開されたばかりなので、様子を見ながら課題等に向き合っていくことになります。現状は一部STUDIOで運用できていないので、全てをSTUDIOで完結できる事が１つのゴールです。


## 個人的な楽しみと期待・まとめ
先日、LottieFilesからアニメーションをSTUDIOのWebサイトに埋め込めるようになったとの発表がありました。[Lottie × STUDIO](https://studio.design/ja/whats-new/lottie)
使い方次第で表現の幅は間違いなく広くなりそうですし、アニメーターの活躍の場もまた１つ増えたのかなと明るく捉えています。
より効果的、かつポジティブなビジュアルコミュニケーションが活発になるといいですね。

手軽に素早くWEB制作ができてしまうノーコードツールSTUDIOに感謝し、結びとさせていただきます。


## 採用情報
株式会社Globeeでは、現在エンジニア採用を積極的に行っています。まずはカジュアル面談にて弊社の「教育」にかける思いや「ものづくり」の考え方についてお話できればと思います。お気軽にご応募ください。
[株式会社Globee 採用ページ](https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc)
新卒エンジニアが可読性・保守性の高いコードを書くために意識したい「考え方/原理・原則」

この記事は[フリュー Advent Calendar 2023](https://qiita.com/advent-calendar/2023/furyu)の17日目の記事となります。

## はじめに
新卒エンジニアとして半年ほど経過した現在までにコードを書く中で、可読性・保守性の観点からレビューで指摘を受けることが多くありました。
そこで、「**いったい何を意識して書けばいいのだ？**」と思い、一冊の本を紹介いただき、読んでみました。
それが「principle of programming」です。
今回はこちらの書籍を読み、可読性・保守性を考慮するために必要だと感じた、「考え方/原理・原則」を5つ紹介します。

## 1. パルナスの規則
### パルナスの規則とは？
>- モジュールの利用者には、そのモジュールを利用するために必要なすべての情報を与え、それ以外の情報は見せない
>- モジュールの作成者には、そのモジュールを実装するために必要なすべての情報を与え、それ以外の情報は見せない

つまりどういうことか

あるモジュールに対して、**利用者**と**作成者**の立場になって利点を考えます。

### 利用者
モジュールを使用する際、**内部の構造を知らなくても使用できるようにする**というのが一文目の利点となります。
必要な情報を与えるだけで使用できるため、複数の場面で効果的に使用でき、**再利用性が高い**モジュールであると言えます。

### 作成者
モジュールを作成/変更する際、**利用者に影響を与えず実装を入れ替えることができる**というのが二文目の利点となります。
他機能への影響を限りなく少なくすることで、修正箇所が限定的となり、変更容易性が高く**保守性が高い**モジュールであると言えます。

### まとめ
パルナスの規則とは、各モジュールの独立性を高くし、再利用性・保守性を高く保つために必要な考え方です。
クラスやオブジェクトがそれぞれの責務を持ち、適切に分割されることで、再利用性・保守性が向上するのです!


## 2. 単一責任の原則
### 単一責任の原則とは？
> 1つのモジュールは1つだけの責任を持たなければならない

つまり、あるモジュールは**変更の理由が一つだけであるべき**ということです。
変更の理由が複数あるということは、責任が複数あると言えます。
１つのモジュールに対し複数の責任を持つ場合、それぞれの責任に変更が加わると他の責任にも影響が及ぶ可能性が高まります。
そうすると、変更容易性が低下し、結果的に**コード全体の保守性が低下**します。

単一責任の原則を守ることで、**柔軟で保守性の高いコードを構築できる**ということです。

### まとめ
実際の業務でコードを書く際も、この単一責任の原則はとても意識する様になりました。
また、研修中は一人でコードを書くことが多かったのですが、再利用性と変更容易性の向上という面では非常に効果を実感できました。
1モジュール1責任を意識して実装することで、他の影響を考慮せず使い回すことができます。

## 3. ソフトウェアエージング
### ソフトウェアエージングとは？
>ソフトウェアが時間の経過とともに劣化し、性能が低下する事象

つまりソフトウェアも高齢化するよねという考え方です。
ここで言いたいのは、何も高齢化するコードを無くそうということではありません。
そうではなく、**更新し続けることが重要だ**ということです。
また、その更新を予測した柔軟な設計にしておくことも重要となります。

そうすることで、ソフトウェアの高齢化速度を軽減し、健全性を維持できます。

### まとめ

私はこの考え方を取り入れ、新規実装を追加する際や、現在ある実装を修正する際、関係するコードをみるタイミングで、今ある実装をリファクタリングすることを意識するようになりました。
これをボーイスカウトの規則とも言います！
**来た時よりも美しく**ということですね。
「この実装こうした方が良くね？」「この実装イマイチやな、今の書き方はこうだ！」と思うことがあれば、どんどんボーイスカウトしていきましょう！

## 4. オッカムの剃刀
### オッカムの剃刀とは？
> ある事柄を説明するために、必要以上に多くの前提を仮定するべきでない

オッカムの剃刀は、科学や哲学において使用される一般的な原則のひとつです。
この原則は、同じ現象や事象を説明する複数の仮説や理論がある場合に、最も単純で少数の仮定を用いた説明が最も優れているとする考え方です。

この考え方はコードを書く上でも非常に役立つものとなります。
機能が同一である場合、よりシンプルな（余分なものを含まない）実装にするべきだということです。
そうすることで、読み手の思考負荷が減り、改善しやすいコードとなります。
つまり、可読性がよく保守性が高いコードと言えます。

### まとめ
この考え方は、実装方法を決める軸として役立ちます。
実装したい機能に対して、いくつか方法を考え、最終的に実装がよりシンプルとなるものを選択するようにすることで、可読性・保守性を担保できます。

ただ、注意する点として、**明確性**を考慮する必要があります。
テクニックを駆使して、パフォーマンス（シンプルさ）を少し上げる代わりに、可読性を低下させるようなトレードオフをしてはいけません。
読み手に実装の意図が分かりやすい**明確なコード**を書くようにしましょう。

そう言った点では、適度にコメント文を追記することも大切であると言えます。
コードを書く際、あくまで読み手は**コンピュータでなく人であることを意識すべき**です。

## 5. 階層原理
### 階層原理とは？
> 構造が階層であることにこだわる

つまりどういうことか

階層ごとに処理を取り決め、同じ種類の処理が異なる階層間に渡らないようにこだわると言うことです。
構造を階層的に整理することで、**読み手が全体を抽象化して理解することができるため、可読性が向上します**。
また、変更が発生した場合に、その**変更が影響する範囲が限定されるため、保守性も向上します**。

### まとめ

階層原理を意識することで、可読性・保守性の高いコードを書くことができます。
階層原理を適切にプログラムに適応する方法として、様々なアーキテクチャが存在します。
それぞれのアーキテクチャの特性を理解し、上手く取り入れることで、階層原理に基づいて機能や責務を適切に分離することができます。

## 最後に
新卒エンジニアとして、コードを書く際に意識すべき「考え方/原理・原則」をまとめてみました。
この記事でまとめたものは、ほんの一部に過ぎません。
ぜひ書籍や他の記事を読んでみることをお勧めします！
GitLab CICDでXserverに自動Deploy

# 何ができるの？
- GitLabのmainブランチにMergeすると、自動でXserverにデプロイされる。
- 今回は最低限の設定で、mainブランチの中身を自動デプロイする仕組みです。
- htmlなんかはこれをやると良いんじゃないでしょうか。


# こんな人向け
- GitLabを使っている
- Xserverのレンタルサーバーを利用している
- デプロイを手動でやっていている
- デプロイが手動なものだからミスが多い
- チーム開発している


# 設定ファイル
```.gitlab-ci.yml
variables:
  STAGE_HOST: [サーバーID].xsrv.jp
  STAGE_USER: [サーバーID]
  DEPLOY: /home/[サーバーID]/[ドメイン名]/public_html/[アップロード先のフォルダまでのパス]

stages:
  - deploy

deploy:
  stage: deploy
  before_script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - touch ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
    - ssh-keyscan -p 10022 $STAGE_HOST >> ~/.ssh/known_hosts
    - apt-get update
    - apt-get install -y rsync
  script:
    - time rsync -av --exclude='.gitlab-ci.yml' --exclude='.git/' -e "ssh -p 10022" --delete --checksum ./ $STAGE_USER@$STAGE_HOST:$DEPLOY
  rules:
    - if: '$SSH_PRIVATE_KEY && $CI_COMMIT_REF_NAME=="main"'
```

- [参考資料](https://qiita.com/Lich/items/3fc4506b09375e5e28e9)


# まとめ
- 今回はテストとしてGitLabのCiCDを使ってみました。
- シンプルだけど、実践的ですごく便利な機能です。
- 今後は、Rails, Laravelとデプロイするものを大きくしていき、Xserver以外にもデプロイできるようになりたいですね。
    - 特に、フレームワークのDeployは、permission関係の設定やその他のシェルコマンドなども必要なので色々と試行錯誤が必要そうです。
- とはいえ、静的サイトを自動Deployできるだけでも非常に便利です。
AI-102試験対策のまとめ「会話言語理解におけるNone intent(None意図)」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### 会話言語理解におけるNone intent(None意図)
* 下記のようなプロジェクトにとって重要ではない発話をNoneとして分類
    - 挨拶
    - はい/いいえの回答
    - 質問に対する番号での回答など
* 会話言語理解のすべてのプロジェクトに既定のNone intentが含まれる
* 必須の意図であり、名前の変更や削除が不可
* Noneと予測される必要がある発話がある場合は、トレーニングデータに同様の例を追加する必要がある
* None intentに誤検知の例を追加することも検討する必要がある
    - 例：フライト予約プロジェクトで「I want to buy a book」が「Book Flight(飛行機の予約)」意図と混同される可能性がある  
    ⇒下記などをNoneトレーニング発話として追加することで、予測を「Book Flight」ではなくNone intentにすることができる
        - 「I want to buy a book」
        - 「I love reading books」
* 発話がNone intentとして予測できるのは下記の場合
    - 上位のスコアリング意図のスコア < Noneスコアのしきい値
    - 発話がNone intentに追加された例に似ている場合

#### **Noneスコアのしきい値**
* 任意のプロジェクトでしきい値を設定可能
* 0.0～1.0の10進スコア
* しきい値スコアが高いほど、発話はトレーニングデータ内の例に似たものに強制的に設定される
* テストセットのモデル評価時、Noneスコアのしきい値は適用されない

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/language-service/conversational-language-understanding/concepts/none-intent

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「Azure AI Visionにおける配色の検出」**

https://qiita.com/fsd-jume/items/7f8b30259535e5b91cdc

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
【TypeScript基礎】型の定義

## はじめに
関数の型定義を詳しく理解していなかったので備忘録として書いておきます。誤っていたところがございましたら教えていただけますと嬉しいです。

## 学習したこと
### 型定義は基本的に変数に対して行う。
```js
let num: number = 0;
num = 10; //OK
num = "10" //NG
```
### 関数は以下のように使われる。
```js
// : void でreturnで帰ってくるものがない
// : 関数の型は(引数：　引数の型): 返却値の型　=> {}
const funcA = (num: number): void => {
  console.log(num)
}
```
### 関数コンポーネント自体に型をつける
こうすることで関数コンポーネントの中で使われている変数に対して型をつけることができる
```js
import React from "react";
import type { User } from "./types/User";
import { FC } from "react";

type Props = {
  user: User;
};

const UserCard: FC<Props> = (props) => {
  const { user } = props;
  return (
    <div>
      <dl>
        <dt>名前</dt>
        <dt>{user.name}</dt>
        <br />
        <dt>メール</dt>
        <dt>{user.email}</dt>
        <br />
        <dt>住所</dt>
        <dt>{user.address}</dt>
      </dl>
    </div>
  );
};

export default UserCard;
```
```js
export type User = {
  id: number;
  name: string;
  email: string;
  address: string;
};
```

## おわりに
 自分以外の人には意味のないかもしれない記事で申し訳ないです。
Podman + devcontainerでパーミッションエラーに対処する

# Podman + devcontainer のパーミッションエラーに対処

## 経緯

Docker Desktop の業務利用が有料化してから、Lima で代替していたのですが、
devcontainer で npm install すると lchown が Permission Error で実行できないというエラーにハマった末に、
諦めて Podman を導入することにしました。
しかし、Podman で devcontainer を作成するとまた別の Permission Error が発生しました。
またかよ、とうんざりしながら悪戦苦闘したのですが、その長きにわたる戦いの記録は端折って結論だけ書きます。

## 環境

- Mac M1
- VSCode

## devcontainer の作成

- VSCode に Dev Containers 拡張機能を入れておく。
- VSCode のショートカット Cmd + Shift + P でコマンドパレットを開き、`Open Workspace in Container`を実行する。
  - ![2023-12-15-10-53-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2807262/3b134e88-6233-ff8b-8920-21e19f4dc6a4.png)

- コンテナを作りたい Workspace を選択する。
- Node 環境を選択。その後 Node のバージョンや、追加で入れたい機能も選択する。
- コンテナが作られるが Permission Error が発生してしまう。
  - ![2023-12-15-11-04-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2807262/9cf57597-f294-7eb0-5177-5a4ac62822e4.png)


## devcontainer.json の編集

- ダイアログのボタン`Edit devcontainer.json Locally`を押下。
  - ![2023-12-15-11-06-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2807262/87097ad3-e5ff-c415-aadd-0fc8d836ee37.png)

- devcontainer.json を開き、`"remoteUser": "root"`という設定をコメントインする。

  ```json
  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  "remoteUser": "root"
  ```

- `"remoteUser"`の下に新しく設定を追加する。

  ```json
  "containerUser": "root"
  ```

- VSCode のショートカット Cmd + Shift + P でコマンドパレットを開き、`Open Workspace in Container`を実行する。
- コンテナが無事起動する。
  - ![2023-12-15-11-13-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2807262/3da1fcd6-7e05-9015-4c09-61011f423e23.png)
画像をGPT-4-Visionでプロンプト化してDALL-E3で再現してみる

# はじめに
いよいよ、gpt-4-visionがAzure OpenAI Serviceでも使えるようになりました。ので、何に使えるかは一旦置いておいて、以前からやりたかった**画像->プロンプト化->画像**をやってみたいと思います。以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/7f5ae4d6-e6ec-9020-49b4-64504adc036d.png)

なお、画像は[フリー素材のサイト](https://www.pexels.com/ja-jp/)から拝借しました。
使ったモデルはAzure OpenAI Serviceのgpt-4-visionとdalle-3です。

# とりあえず結果

どうでしょうか。結構いい感じに再現できているかなと。
（人種が逆になっていたり、ポーズが違っていたりしますが、このあたりはGPT-4Vの方のプロンプトをチューニングすればできそうな気もします）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/ab70f756-257c-5e05-a554-9e4563ed9fe7.png)

もう1個はちょっと残念なケースです。なんとなく雰囲気はとれてますけど、全体的におしゃれになりますね‥また向きがやっぱり難しい。色々ものがある画像の場合はプロンプトをちょっと変えないとダメそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/f51b2971-457b-b72b-daab-811e4dbd7597.png)

いずれも3~4回実施の上で一番それっぽいのを採用してます。

# GPT-4Vのプロンプト

今回の検証の肝である画像のプロンプト化はこんなプロンプトです。精度を少しでも上げるために英語にしてますが、日本語ですと「**画像に描かれている内容と同一のコンテンツを生成するために、DALL-Eを使用して詳細なプロンプトを書いてください。正確な再現を保証するために、オブジェクト間の関係や色についての詳細を含めてください。あなたならやれるはずです**」という感じです。

```python
user_prompt = "Please write a detailed prompt to generate content \
identical to what is depicted in the image using DALL-E.
Include details about the relationships of objects and colors \
to ensure accurate reproduction. You can do it if you try."
```

GPT-4Vの呼び出し実装については[公式](https://learn.microsoft.com/en-us/azure/ai-services/openai/gpt-v-quickstart?tabs=image&pivots=rest-api)をご参照ください。

# DALL-E3の実行

GPT-4Vの出力結果であるプロンプトをそのまま流します。Azure OpenAI Service経由の場合、フィルターにひっかかって生成されないことがあります。ので、何度か試す必要は結構ありました。

DALL-E3の呼び出し実装については[公式](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/dall-e-quickstart?tabs=dalle3%2Ccommand-line&pivots=programming-language-python)をご参照ください。

# まとめ

画像をプロンプト化して再度画像化してみました。それなりに再現できたケースもあればあんまりうまくいかなかったケースもありますが、総じてそれっぽいものの再現はできたかなという感じです。

利用シナリオをひねり出すとすると、プライバシーや著作権的なものが含まれている画像を、再生成することで似たようなクリーンな画像ができあがるというところでしょうか。顔出ししたくないけど、画像は上げたい場合なんかにも使えるかもしれません。

とはいえまだ画像生成側がそこまで指示に従ってくれないので、雰囲気再現ですが。今後画像生成の精度がさらに上がり、またGPT-4Vのプロンプト生成の方も指示をうまくチューンできれば何かに役に立つかもしれないけど、現状特に何か役に立つシナリオは正直あんまり思いつかないけどやってみたかった検証は以上です。

# 追記
これって下書きから画像を作成できるよね？という指摘があり取り急ぎやってみたものが以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/6cd5a42d-f93d-5038-4915-c30006bfb37e.png)

プロンプトは、下書きをリアル画像にして、っていう感じです。
```python
user_prompt = "Write out a prompt for DALL-E to generate the content \
depicted in the image as a hyper-realistic image."
```

意外にアイディアあるかもですね
Poetryをインストールする

# 概要
以下のpoetryの日本語バージョンのドキュメントの方法でpoetryをインストールしようとすると404エラーが帰ってくる。
https://cocoatomo.github.io/poetry-ja/

# 解決
以下の公式ドキュメントの方法でダウンロードする。
https://python-poetry.org/docs/

### Linux, macOS, Windows (WSL)
```bash
curl -sSL https://install.python-poetry.org | python3 -
```
注意: システムによっては、python が Python 3 ではなく Python 2 を指している場合があります。曖昧さを避けるため、常にpython3のバイナリを推奨します。

### Windows (Powershell)
```bash
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
```
Microsoft Storeを通じてPythonをインストールした場合は、上記のコマンドでpyをpythonに置き換えてください。
apt と apt-get のどちらを使えばいいのか？

# はじめに
Dockerファイルを読んだりすると、apt　apt-get　で統一されてない環境に遭遇することが多々あったので何か意図があるのか気になっていました。

公式とAWSから言及されているドキュメントをみつけたので掲載します。

個人的な結論としては、AWSのドキュメントを読んで二つのコマンドの違いを把握した上で、上位互換であるaptを使っていくようにしたいと思いました。

# 公式ドキュメントでは
正直これだけでは分かりませんでした。

抜粋
>Note:
>While apt is a command-line tool, it is intended to be used interactively, and >not to be called from non-interactive scripts. The apt-get command should be >used in scripts (perhaps with the --quiet flag). For basic commands the syntax >of the two tools is identical.

DeepL翻訳
>apt はコマンドラインツールですが、対話的に使用することを目的としており、 > 非対話的なスクリプトから呼び出されることはありません。apt-get コマンドはスクリプトで使用されるべきです (おそらく --quiet フラグ付き)。基本的なコマンドは、2つのツールのシンタックスは同じです。

# AWSのドキュメントでは

下記のリンク先の一部抜粋をします。

https://aws.amazon.com/jp/compare/the-difference-between-apt-and-apt-get/

## apt-get コマンドを apt コマンドに置き換えについて

> 既存の Linux スクリプトでは、apt-get コマンドを apt コマンドに置き換える必要はありません。これらは引き続き正常に動作し、apt-get は引き続きサポートされています。過去の apt-get コマンドの機能の一部は apt でわずかに変更されています。そのため、apt-get をスクリプトに残しておくことで、正しく動作するようになります。

## どっちを使うべきかについて
>平均的な Linux ユーザーは、プロジェクトや環境が必要としない限り、apt-get の代わりに apt を使うべきです。

## apt と　apt-get の比較表

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982130/6a349bd7-3d1f-21f7-14bf-6ac857c2b9ec.png)


# 結論
既存のスクリプトで使われている`apt-get`はそのまま使って、新規のスクリプトを書く際には`apt`を使うようにしたいと思っています。

`apt`だとCLIでコマンドを流した後の進行状況が分かること、`apt upgrade`を使用する場合に古いバージョンのパッケージが削除されることを抑えて置けばOKかなと思いました。

# 参考

https://ubuntu.com/server/docs/package-management

https://aws.amazon.com/jp/compare/the-difference-between-apt-and-apt-get/
卒業研究 

![スクリーンショット 2023-12-15 105817.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549857/9915a91d-6c8f-49c1-f1ac-e190239509e8.png)
初めまして！

私たちは卒業研究の一環としてWebアプリケーションを「Oshi More!」を開発しました。

このアプリケーションは、複数の外部アプリケーションを使用することなく、
推し活に関する全ての情報を一元的に管理することで利用者の推し活をより効率的にすることを目的としています。

開発言語はPythonを使い、flaskで開発しました。また、herokuにデプロイして公開しています。

このアプリケーションの公開により、ファン同士の交流を促していき、
利用者の推し活体験をより豊かにしていくことを目指しています!

皆さんのご意見やフィードバックをお待ちしております。ぜひ一度ご覧いただき、お楽しみください！

よろしくお願いいたします。

Oshi More!は以下のURLからアクセスできます。
URL:https://oshimore-90d6b34a7fa6.herokuapp.com/
ReactNativeでポップアップメニューの実装

# ReactNativeでポップアップメニューの実装

ReactNativeでポップアップメニューといえば [react-native-material-menu](https://github.com/mxck/react-native-material-menu) での実装がよく見つかるのですが、表示内容のカスタマイズはまずできない構造だったので、仕方なく [react-native-popup-menu](https://github.com/instea/react-native-popup-menu) に置き換えたというお話です。

## react-native-material-menu でアイコンがうまく配置できない

このあたりの [issues](https://github.com/mxck/react-native-material-menu/issues/42) でアイコン配置についての言及があり、配置はスペースで調整しているようです。
最初は気にしていなかったんですが、コードを良く調べてみると、MenuItemに渡したchildrenはTextの配下に入るようです。
どおりで、どうやっても右端にアイコンが配置できないわけだ...。
(現在、2.0.0になっていますが、未だにMenuItemのchildrenはText配下です)

このままでは到底デザインどおりの配置は無理なので、別のライブラリを探しました。


## react-native-popup-menu を使う

割と自由度が高そうなライブラリを見つけたのでポップアップメニューの類をそれに置き換えることにしました。


#### 1. 最上層になる部分を MenuProvider で覆う

以下は `react-native-material-menu` の `Basic Usage` にある実装サンプルです。
`react-navigation` を使っている場合は`NavigationContainer`を覆えば良さそうです。
後は中の画面で Menu 以下を追加するだけで簡単に実装できます。

```jsx:App.tsx
import { MenuProvider } from 'react-native-popup-menu';

export const App = () => (
  <MenuProvider>
    <YourApp />
  </MenuProvider>
);
```

#### 2. 表示するメニューの実装

ポップアップメニューを開くボタン込みで以下のような実装です。

```jsx:Menu.tsx
import {
  Menu,
  MenuTrigger,
  MenuOptions,
  MenuOption,
  renderers,
} from 'react-native-popup-menu';

function createMenu() {
  return (
    <Menu renderer={renderers.NotAnimatedContextMenu}>
      <MenuTrigger>
        <Text>メニュー</Text>
      </MenuTrigger>
      <MenuOptions
        customStyles={{
          optionsContainer: styles.options,
          optionWrapper: styles.option,
        }}>
        <MenuOption onSelect={() => alert('Hoge')} text='Hoge' />
        <MenuOption onSelect={() => alert('Fuga')}>
          <Text style={{color: 'red'}}>Fuga</Text>
        </MenuOption>
      </MenuOptions>
    </Menu>
  );
}

const styles = StyleSheet.create({
  options: {
    width: 300,
    marginTop: 10,
    marginLeft: -30,
    borderRadius: 8,
  },
  option: {
    minHeight: 48,
    padding: 8,
  },
});
```

**Menu**: ポップアップメニューの開始タグです。`renderer`で開き方を指定できます。例はアニメーションしないメニューです。パッと開く感じです。Popoverで吹き出し型、SlideInMenuで下から生えてくるメニューが出せます。

**MenuTrigger**: ポップアップを開くボタンです。テキスト以外にもなんでも置けます。テキストだけの場合は、`<MenuTrigger text='Menu' />` というふうにもできます。

**MenuOptions**: ポップアップの外枠です。これのマージンなどを調整するとボタンからの表示位置を調整できます。メニューの幅などもここに指定。(marginLeftにマイナス値を入れると、ボタンの左側に開きます)

**MenuOption**: ポップアップ内のリストです。一般的なView内配置になるので、よくあるテキスト左寄せ、アイコン右寄せみたいな作り込みのViewを渡しても大丈夫です。

以上の実装で十分過ぎるぐらいにポップアップメニューの実装は可能です。
この他、細かい設定が必要という場合は、[react-native-popup-menu](https://github.com/instea/react-native-popup-menu) のサンプルやドキュメントを読むと良さそうです。

## まとめ
凝ったデザインのポップアップメニューを作りたい場合は [react-native-popup-menu](https://github.com/instea/react-native-popup-menu) をおすすめします。
また、`MenuTrigger` には disabled 属性があるので、このタイミングでメニューを開かせたくないという場合にも有効です。
`MenuOption` も disabled 属性があるので、色々とコントロールし易いのではないでしょうか。
全角スペースを含むファイルパスをドラッグドロップでbatに渡すとファイルがないと言われる

## 事象
フルパスに全角スペースを含むファイルをドラッグドロップでbatに投げると `No such file or directory`

## 原因
`%1`でファイル名を取る場合、
・全角スペースを含む：全角スペース単位でsplitされて、最初の要素が`%1`となる。
・半角スペースを含む：splitされず、ダブルコーテで括られた形となる。

なんだこの仕様。

## 対応
`%*`で引数全体を取り、ダブルコーテを消す。
ただし、1ファイル前提。

```bat
set fullpath=%*
set fullpath=%fullpath:"=%
```
【後編】Javaでオブジェクト指向を学びなおす


前回の続きです！
継承、ポリモーフィズム編になります！

https://qiita.com/suda_imagitech/items/d9f3fc3327d306a0d8ec

# 1.継承（Inheritance）について
>継承は、既存のクラスから新しいクラスを作成する仕組みです。新しいクラスは既存のクラスの特性（データやメソッド）を継承し、必要に応じて追加や変更ができます。

これは覚えてるぞー
だけどしっかりコード化しよう

```java:java
// 親クラス（スーパークラス）
class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + "は食事している");
    }

    public void sleep() {
        System.out.println(name + "は寝ている");
    }
}

// 子クラス（サブクラス）
class Employee extends Person {
    public Employee(String name) {
        // 親クラスのコンストラクタを呼び出す
        super(name);
    }

    // 親クラスのメソッドをオーバーライド（上書き）
    @Override
    public void eat() {
        System.out.println(name + "は昼食を摂っている");
    }

    // 子クラス独自のメソッド
    public void work() {
        System.out.println(name + "は働いている");
    }
}

// メインクラス
public class Main {
    public static void main(String[] args) {
        // Employeeクラスのインスタンスを作成
        Employee employee = new Employee("開発太郎");

        // 継承したメソッドを呼び出す
        employee.eat();   // オーバーライドされたメソッドが呼ばれる
        employee.sleep(); // 親クラスのメソッドが呼ばれる

        // 子クラス独自のメソッドを呼び出す
        employee.work();
    }
}

```

```java:実行結果
//employee.eat();
開発太郎は昼食を摂っている

//employee.sleep(); 
開発太郎は寝ている

//employee.work(); 
開発太郎は働いている
```

EmployeeクラスはPersonクラスを継承しています。
継承することで定義していないsleep関数を実行することができます。（便利！！）

加えて親クラスの関数を上書き（オーバーライド）ができます。例で表すとeat関数。

# 2.ポリモーフィズム（Polymorphism）について
> ポリモーフィズムは、同じ名前のメソッドが異なるクラスで異なる振る舞いをすることを指します。これにより、異なるオブジェクトが同じメソッド名を共有できます。

文字読むと大体イメージつきますが、しっかりコード化。

```java:java
// 人（Person）クラス
class Person {
    public void makeSound() {
        System.out.println("こんにちは！");
    }
}

// 仕事をしている人（WorkingPerson）クラス - Personクラスを継承
class WorkingPerson extends Person {
    @Override
    public void makeSound() {
        System.out.println("仕事してます！");
    }

    // 仕事をするメソッド
    public void doWork() {
        System.out.println("働く");
    }
}

// 学生（Student）クラス - Personクラスを継承
class Student extends Person {
    @Override
    public void makeSound() {
        System.out.println("勉強してます!");
    }

    // 勉強をするメソッド
    public void study() {
        System.out.println("勉強する");
    }
}

public class Main {
    public static void main(String[] args) {
        // ポリモーフィズムの例

        // Person型の配列に異なる種類の人を格納
        Person[] people = new Person[3];
        people[0] = new WorkingPerson();
        people[1] = new Student();
        people[2] = new WorkingPerson();

        // 配列をループして各人の音を鳴らす
        for (Person person : people) {
            person.makeSound();

            // WorkingPersonクラスのdoWorkメソッドやStudentクラスのstudyメソッドにアクセスできない
            // person.doWork();  // コンパイルエラー
            // person.study();   // コンパイルエラー
        }
    }
}

```

```tex:実行結果
仕事してます！
勉強してます!
仕事してます！
```

なるほどねと
WorkingPersonクラスとStudentクラスは同じ親クラスを持ちそれぞれでmakeSound関数をオーバーライドします。なので同じ関数名だけど処理内容は違うと。

ポリモーフィズムは元々よくわかってなかったかも。
しっかり勉強になりました。

# 3.終わりに
今回学びなおしをして抜けていた部分やそもそも知らなかったことを知識として知ることができました。
これらに加えてデザインパターンの勉強もしていきたいと感じます。

# 4.予告
次の投稿日は2024年1月5日を予定しています！
年始！！
フィボナッチ数 (paizaランク D 相当)

https://paiza.jp/works/mondai/array_primer/array_primer__fibo

フィボナッチ数列をプログラムで表現する問題。
1番目は０，2番めは１，3番目以降は1番目と2番めの数の和・・・というやつ
そのままプログラミングした

```py
N = int(input())
ans = 0
num1 = 0
num2 = 0
for i in range(N):
    if i + 1 == 1:
        ans = 0
        num1 = 0
        print(ans)
    if i + 1 == 2:
        ans = 1
        num2= 1
        print(ans)
    if i + 1 > 2:
        ans = num1 + num2
        print(ans)
        num1 = num2
        num2 = ans

```
下手くそなプログラミングだなぁ。。。
答えを見てみた。
配列をうまく使っていた。
なので書き直し

```py
N = int(input())

A = [0] * N
A[0] = 0
A[1] = 1

for i in range(2, N):
    A[i] = A[i - 2] + A[i - 1]

print(*A,sep="\n")
```

今日はここまでで。
【VSCode+SpringBoot】SpringBootでAPIを作る③

前回↓

https://qiita.com/NaN-jp/items/61faa709dac6e000eea7

# はじめに
今回からSpringBootの実装に入る
まずはMVCモデルのひとつであるModelの作成

#### 📚そもそもMVCモデルとは？？
MVCモデルとはコードを管理する上で便利な**Model,View,Controller**の３つの頭文字をとった概念である。

### Model作成
まず部品であるModelを作成していきます
demo内にmodelフォルダを作成してその中に`Person.java`を作成します
```java:src/main/java/com/example/demo/model/Person.java
package com.example.demo.model;

import jakarta.persistance.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;

@Data
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private Integer age;
}
```
### ⚠️注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627466/4da8587f-bfe4-e2c3-d0b4-7d2dbc2b598d.png)
このようなエラーが出ている場合はpom.xmlの`<dependencies></dependencies>`内に以下を追記してください
```xml:pom.xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.8</version>
	<scope>provided</scope>
</dependency>
  ```
### ✨解説
@から始まる見慣れないものがあると思います
```java
@Data
@Entity
@GeneratedValue
@Id
@Column
```
これらは**アノテーション**と呼ばれるものです
SpringBootではアノテーションを前述することで動作や定義の決定を行うことができます

◎`@Data`はコンパイル時に後述のクラスに対してこれらのメソッドを生成します
* setter()
* getter()
* toString()
* equals()
* hashCode()

◎`@Entity`はJPAのエンティティクラスであることを定義します

◎`@GeneratedValue`は主キーの値の生成方法を指定します
> 今回は自動採番を採用しています

◎`@Id`はデータベースの主キーフィールドを宣言します
> データベース内の主キーに設定したものにつけるとよいです

◎`@Column`はエンティティの各フィールドにマッピングされる物理テーブルのカラム名を指定します
> データベース内のカラムであることを指定するものです

アノテーションに関しては以下の記事が参考になるのでぜひ見てみてください

https://segakuin.com/java/jpa/annotation.html

# さいごに
今回はModelを作成しました
次回はViewを作成しようと思います
Docker環境でPrisma Studioが開けない問題

# 問題点
Docker環境のNuxt3にPrismaをインストールしたが、「このサイトサイトにアクセスできません。」というエラーが発生し、Prisma Studioをローカル環境で開きませんでした。

# Docker環境
Dockerfile
```
FROM node:18-slim

ENV TZ Asia/Tokyo

WORKDIR /app

RUN apt-get update \
    && apt-get install -y \
    git \
    vim

```

docker-compose.yml
```
version: "3.9"

services:
  nuxt:
    container_name: nuxt
    build: docker/nuxt
    volumes:
      - ./front:/app:cached
      - nuxt_node_modules:/app/node_modules
    ports:
      - "80:3000"
      - "24678:24678"
    tty: true
    environment:
      - HOST=0.0.0.0
      - port=80
      - CHOKIDAR_USEPOLLING=true
    # 初期構築段階ではコメントアウトする
    command: sh -c "yarn && yarn dev"
volumes:
  nuxt_node_modules:

```

# 解決
docker-compose.ymlの以下の部分を追加することで、Prisma Studioを開きました。
```diff
ports:
 - "80:3000"
 - "24678:24678"
+- "5555:5555"
```

# 参考資料
https://qiita.com/A-Kira/items/5ce3e1bff34e179ebbc2

https://qiita.com/Ryo9597/questions/17fbcac39569b580e677
レガシーなアプリのアイコンを現代風にする

## 何がしたいか

macOS BigSurからアプリアイコンの形状が刷新されたのは記憶に新しいだろうが、まだ対応してないアプリも結構ある。しかし、それは少数派なので完全い悪目立ちしてしまうからなんとかしたい。

![スクリーンショット 2023-12-15 1.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/3cc4d386-fcfd-d1f8-b3d0-ad043f132e68.png)

## 解決策

自力でアプリアイコンを作って上書きします。もちろん権利関係があるのでこれを配布とかしたらNGです。

https://developer.apple.com/design/resources/

の下の方からProduction TemplatesのPhotoshop版を落とします。2023/12/15現在、macOS Montereyのところにあります。

![スクリーンショット 2023-12-15 2.15.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/33f9ad8a-c150-2675-411c-5fb285160bf1.png)

1024 pxのファイルを編集していきます。これはマスクをかけるだけです。Photoshopの扱い方に関しては技術記事の範囲外なので割愛します。

![スクリーンショット 2023-12-15 2.15.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/fa00956a-3705-0a50-1cf9-37519b381465.png)

![スクリーンショット 2023-12-15 2.36.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/972de877-87d6-c7b2-7d94-1a5b71211ef6.png)

## .icnsに変換

PNG to ICNSとかでウェブで検索して`.icns`に変換します。なんか変なサイトのリンク貼ってしまったら責任取れないので、リンクは省略します。ごめんなさい。なんでもできると思います。

できたアイコンは任意のフォルダに保管しておきます。

## アイコン変更

Finderのアプリケーションフォルダから変更したいアプリを右クリックし「情報を見る」をクリックします。

![スクリーンショット 2023-12-15 2.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/6ff50c46-bce8-7076-12f8-305e3295cb4b.png)

画像の矢印の先を目掛けてドラッグ&ドロップします。するとアプリケーションアイコンが変換されます。

## 起動した瞬間元に戻ってしまう時は…

ほとんどのアプリはこの操作でアイコンを変更できますが、稀に起動後にアイコンが戻ってしまうアプリがあるようです。（Qt系とか）

これに関しては諦めるしかなさそうですが、LaunchPadで表示される分には問題なく新しいアイコンで表示されているので妥協かなという感じですね。開いた時のDockアイコンのみ戻ってしまいますが…。
AWSCLIv1でクロスアカウントアクセスができなかった時の話

# 初めに
AWSでクロスアカウントアクセス設定をしていて詰まった話になります。
CLIv1を使用している方には参考になるかと思います。

# 前提
 アカウントA
 * クロスアカウント元
 * EC2からアカウントBのS3へアクセスしたい
 * awscliのバージョンは1.18.58
 * アカウントBへのassume-role権限を持つポリシーを持ったIAMロールがEC2へアタッチされている
 * credentialsとconfigの設定は以下

```:credentials
[profile名]
role_arn = "[クロスアカウント先のarn]"
credential_source=Ec2InstanceMetadata
```
```:config
[default]
region = ap-northeast-1
```

アカウントB
* クロスアカウント先
* アカウントAの信頼性ポリシーとS3アクセスを許可したポリシーを持つIAMロールがある

# 何が起こったか
アカウントAからアカウントBへS3のクロスアカウントアクセス設定をして、テストをしている際に
いつまでたっても応答がない状態となりました。
実行したときのコマンドは以下
```
aws s3 ls s3://[バケット名] --profile [profile名] 
```
# 試したこと
* --debugオプションの使用
    * ConnectTimeoutError: Connect timeout on endpoint URL: "https://sts.amazonaws.com/"
      と表示され、タイムアウトしていることが分かった
* aws sts get-caller-identity　の実行
    * オプションなしで実行しても応答がない
    * --regionオプションを追加してap-northeast-1を指定しても変化なし
* aws s3 ls の実行
    * オプションなし
         * 自アカウントのS3を表示
    * --profile オプションあり
        * 応答なし
* --endpoint-url オプションの追記
    * 東京リージョンにあるエンドポイントを指定する。
        * aws s3 ls　オプションなし
            * 応答あり、自アカウントのS3をlsで表示できた
        * aws s3 ls --profile 
            * 応答なし



# 原因
--endpoint-urlを指定した場合としなかった場合のデバック内容を見ていたところ、エンドポイントURLが異なることがわかりました。
指定しない場合は、グローバルのエンドポイント
指定した場合は、指定のエンドポイント
のように接続先が異なりました。

どうやらstsエンドポイントのデフォルト動作がCLI v1とv2で異なるようで、v1だとグローバルのSTSエンドポイントに送信し、接続制限に引っ掛かりタイムアウトしてしまうようです。

>・AWS CLI バージョン 2 はデフォルトで、現在設定されている AWS リージョンのリージョンエンドポイントにすべての AWS Security Token Service (AWS STS) API リクエストを送信します。
・AWS CLI バージョン 1 はデフォルトで、AWS STS リクエストをグローバル AWS STS エンドポイントに送信します。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-sts-regional-endpoint


# 結論
<font color="Red">__CLIのバージョンは最新版を使おう!__</font>
OpenAI API + LangChain + DataStax AstraDB + LangSmith + Streamlit サンプルアプリケーション紹介

## この記事について

DataStax社が公開している生成AI活用アプリケーションを紹介します。

## サンプルアプリUI

### OpenAI API利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/d609ba87-5ee8-6432-f690-2eefb34cb705.png)

OpenAIのAPIを使って、ユーザーの問い合わせに答えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/ce13ef62-455d-0a18-858a-744ab2e6ede4.png)

### RAG (Retrieval Augumented Generation)
それだけでは、あまり意味がありませんが、このアプリは、自分の持っているファイルの情報をOpenAIに使わせて、問い合わせを行うことができます。

いわゆるRAG (Retrieval Augumented Generation)の実装です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/b4caf359-3c5a-fd47-f819-ea89e05250a3.png)

このPDFファイルをアプリに登録しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/dd5ceb7c-25ab-05d2-7291-24ce87e3930d.png)

ファイルの参考文献の情報について問い合わせてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/47bfb876-5bcd-675d-886b-d1859df1983a.png)

このように、適切な回答を得ることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/f4a9119d-8670-e701-7bde-9d2a6ec9d9b5.png)

## Astra DB コントロールプレーン

先ほど登録されたファイルは、アプリによってベクトル化された上で、DataStax AstraDBに登録されています。

これがAstraDBの管理画面（コントロールプレーン）です。

「Data Explorer」画面で登録されたデータを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/4dca13f8-6bd1-64fa-2c4f-7d01094546a2.png)

ある列の「Search」ボタンを押すことで、その列のデータに類似したデータ順に並べる変えることでき、上位N件のみ表示することもできます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/e623776c-cdec-ca1d-9e3f-67c75a0e95f5.png)

## LangSmith

また、このアプリケーションは、LangChainを使って開発されています。

そして、LangChainを使ったアプリケーションのライフサイクル管理プラットフォームLangSmithとも連携しています。

以下がLangSmith上のこのアプリケーションのためのプロジェクトの画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/26235168-ff12-d352-c091-20cd3d47c3a9.png)

アプリケーション実行に関する各種トレース情報を見ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/87d6566b-d6bb-70dd-26c7-5be368152fff.png)

以下のように、OpenAIへのAPIコールの内容を確認することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/5f7a07e3-5e2b-e674-bf64-ebee5b3d22c9.png)

アプリケーション利用状況のモニタリングもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/ed26e97b-ae93-f53f-a1c6-00688fbdf36e.png)

## ソースコード

この記事で紹介したアプリケーションのソースコードは以下で公開されています。

https://github.com/qzg/streamlit-langchain