OmniAICreator/Qiita-1.07M huggingface dataset:
[Django-Ninja] Schemaに定義したaliasの名前をレスポンスに使用する

# まえがき
先日Django-Ninjaでバリデーションエラーをハンドリングする記事を書きました。
その記事の一番最後で、

>これ書いている途中で色々試してたら、Python組み込みの型の名前を **レスポンスしなくちゃいけないときとかどうしよう** って悩みが生まれてしまいました。
>listっていうキーを含んだJSONをレスポンスしたいけど、Schemaでlistっていうフィールド名は使っちゃまずいし。
>aliasをFieldに設定してみたけど、思ってた挙動とは違ったし。
>どうしよう。わかんない。 誰か教えてほしい。

ていう疑問を書いてたんですけど、Django-NinjaのGitHubを読んでたら解決方法が載っていたので、早速試す。

https://qiita.com/bachikawa/items/2905c0f284220264ec92


# 解決策
`by_alias=True`を指定してあげるといいみたいです。
Django-Ninjaの内側(?)で動いているPydanticは、デフォルトでは`by_alias`はFalseなんだそう(当然か)。

# 実装
実装方法は2パターン見つけました。
1つは全体に作用する方法で、もう一つはViews.pyで定義する関数別に設定する方法。
それと、もう一つRouterクラス別に一括で設定する方法もあるみたいです。
それについては参考にしたIssueを見てみてください……。

## レスポンスSchema

```python
class TestOut(Schema):
    id: int = Field(
        description="ID",
    )
    str_: str | None = Field( # フィールド名は`str_`
        alias="str", # aliasは`str`
        description="your message.",
    )
```

## 1つめ
全体に作用するものです。
urls.pyでURLにAPIを渡す際に、API全体の(APIに含まれる全Routerの?)by_aliasをTrueにする。

```python
api = NinjaAPI(renderer=ORJSONRenderer())

def set_all_by_alias(api):
    for _pth, router in api._routers:
          for view in router.path_operations.values():
               for op in view.operations:
                     op.by_alias = True

set_all_by_alias(api)
```

## 2つめ
個別に作用するものです。
Views.pyで`@router.get()`を使う際に、by_aliasをTrueにする。

GitHubでは`@router.get()`でサンプルコードが書かれていたんですけど、手元で試したら`api.get("", by_alias=True)`でも大丈夫でした。
Django-Ninjaを見てみるとdefault_routerというものがNinjaAPIの内側にあるようなので、それが勝手に使用されているのかな。
（適当言ってます。`api.get()`と`api.default_router.get()`は同じなのかな。）

```python
@api.get("", by_alias=True)
def test(request, parameters: Query[TestIn]):
    return {
        "id": parameters.id,
        "str": parameters.value, # レスポンスのdictではキーにaliasの方を使用してる！
    }
```

# 結果
こうなりました。
ちゃんとaliasが効いてレスポンスのキーがstrになってる。
## by_alias=Falseの状態
フィールド名に使用している`str_`(アンダースコアが付いてます)がそのまま返っていますね。
これが嫌でなんとかaliasをレスポンスに使えないかなと悩んでました。

```json
{"id":1,"str_":"!!TESTING!!"}
```

## by_alias=Trueの状態
ちゃんとaliasで定義した`str`がレスポンスに使われてます。
やったあ。
```json
{"id":1,"str":"!!TESTING!!"}
```

# あとがき
意外と単純でした。
少し躓いたのは、Views.pyでreturnするdictのキーをaliasで定義した名前にしなくちゃいけないところです。
これをしないでフィールド名のほうをキーに使用すると、レスポンスSchemaでバリデーションエラーが起きちゃいました。

GitHubというか、モジュール自体の実装やIssues, Discussionsを見ることって大切だなって思いました。
私なんかが悩んでることって、当然他の誰かも悩んでいますよね。そりゃ。
矮小な悩みすぎて私以外悩んでいない場合もありそうですけど……。

テストコードを書いた経験が少なくて、pytestのmockとかfixtureとか、あとtoxあたり(toxってなに)が全然わからない。
それが超直近の悩みです。仕事上の。

そんなかんじです。悩んでばかりだ。

じゃあね。

# 参考
https://github.com/vitalik/django-ninja/issues/469

https://github.com/vitalik/django-ninja/issues/828
Grok-1をローカルで動かすとどうなるか

「イーロン・マスクの生成AI「Grok-1」、オープンソース化」ということで、3月11日にGPT-3を超える、3140億パラメーターのMoEがオープンソースとしてリリースされました。

GitHubやHuggingfaceからダウンロードできるようになっているので、自分の環境で動作するかどうか、確認してみました。

私の使っているGPUは、RTX 4060Ti 16GB で、ミッドレンジのものになると思います。
これで動作するのでしょうか。

# Grok-1のスペックについて
```
Parameters: 314B
Architecture: Mixture of 8 Experts (MoE)
Experts Utilization: 2 experts used per token
Layers: 64
Attention Heads: 48 for queries, 8 for keys/values
Embedding Size: 6,144
Tokenization: SentencePiece tokenizer with 131,072 tokens
Additional Features:
Rotary embeddings (RoPE)
Supports activation sharding and 8-bit quantization
Maximum Sequence Length (context): 8,192 tokens
```


Parameters: 314B　3140億のパラメーターは、オープンソースの中では最大になると思います。
Architecture: Mixture of 8 Experts (MoE)
８つのモデルが協調して動作するということです。
モデルの構造が分からないので、LayerからEmbedding Sizeの数字が大きいのか小さいのかよく分かりません。QKVは小さいように思えますが、どうなのでしょうか。


# 環境構築
## 実行環境
WSL2を使う。
最新のCUDA Toolkitが必要
cuDNNも必要

## リポジトリのコピー
```
git clone https://github.com/xai-org/grok-1.git
cd grok-1
```
## 仮想環境の設定と初期化
```
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
JAXが正しく入らないので、以下を実行
```
pip install -U "jax[cuda12_pip]==0.4.25" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
```

## モデルのダウンロード
```
pip install huggingface_hub[hf_transfer]
huggingface-cli download xai-org/grok-1 --repo-type model --include ckpt-0/* --local-dir checkpoints --local-dir-use-symlinks False
```
15:13 開始
16:22 終了

約70分
モデルファイルは、トータルで310GBとなっています。ファイル数が770です。

## 実行
```
python run.py
```

## 結果
全く動きません。

まず、デフォルトでは８つの演算デバイスを使用します。要するに、GPUが8つ必要です。
設定を変えて、１つのGPUで動かそうとしました。
local_mesh_config=(1,1) に変更

モデルファイルのロードで、メモリが足りないです。（OSError: [Errno 28] No space left on device: './checkpoints/ckpt-0/tensor00000_000' -> '/dev/shm/tmp_d8pupbr'）

モデルをロードする前に、すでに15GB程度の消費がありましたが、何で使ったのかが分かりません。
モデルファイルはトータルで310GBなので、8枚にロードするとすると、一枚あたり39GBということになります。一般向けのGPUじゃ無理ですね。A100あたりを8枚使うと、余裕で動きそうです。

ということで、クラウドサービス等で動かす場合は、課金に注意というところでしょうか。
Python フォーマット文字列からプレースホルダ名etcを取得する

## 問題意識

たとえば 
```python
greeting = "My name is {name}, inmate number {number:04d}"
```
のような文字列を考える。`greeting.format(name='Shohei', number=17)`のようにすれば、`name`あるいは`number`というプレースホルダに明示的に値を与えることもできるし、通常の文字列の代わりにf-stringにすればスコープから`name`や`number`といった名前を引っ張ってきてくれる。

せっかくなのでconfig fileなんかから引っ張ってきた設定も、この方式でフレキシブルにフォーマットできるようにしたい。

もちろん実際に使うときには
```python
cfg = dict(...)

...

text = greeting.format(**cfg)
```
のようなかたちで使えば良いけれど、実際に`format()`メソッドを**呼ぶ前に**、`cfg`の中に対応したキーが想定された型で入っているかをチェックしたい。

具体的には、たとえば上の`greeting`の場合、このフォーマット文字列から
- `name`という変数が必要
- `number`という変数が、整数に変換できる型で必要

という情報を引き出したい。

## stringモジュールの利用

そこで使うのは、`format()`メソッドの内部（関連？）実装である[`string`モジュール](https://docs.python.org/3/library/string.html)になる。

[`string.Formatter`クラス](https://docs.python.org/3/library/string.html#string.Formatter)がフォーマッティングにかかわる諸々の作業を抽象化してくれている。今回の場合、`parse`メソッドを使う：
```python
>>> import string
>>> 
>>> greeting = "My name is {name}, inmate number {number:04d}, cheers!"
>>> 
>>> fmter = string.Formatter()
>>> fmter.parse(greeting)
<formatteriterator object at 0x10125b7e0>
>>> for elem in fmter.parse(greeting)
...     print(elem)
...
('My name is ', 'name', '', None)
(', inmate number ', 'number', '04d', None)
(', cheers!', None, None, None)
>>> 
```
`parse`メソッドは、4-tupleのイテレータを返す。各tupleは(_literal_, _field_, _spec_, _conversion_)の形式になっている：

- _literal_: プレースホルダの前にあるリテラル文字列
- _field_: プレースホルダに指定された名前
- _spec_: フォーマット形式
- _conversion_: （現段階では、どういうときに出てくるかちょっとよくわからなかった）

## その他参考

- [PEP 3101](https://peps.python.org/pep-3101/) 意外と知らないことがあった
AWS Certified Solutions Architect – Associateを受験した

## はじめに
AWS実務未経験の私がAWS Certified Solutions Architect – Associateを受験しました。
試験の概要ついては以下をご覧ください。
[AWS Certified Solutions Architect – Associate](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)

## 結果
結果は以下の通りとなります。
ギリギリの合格かなと思っています。
![awsアソシエイト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659733/1f8b4418-72e6-66d1-f8cd-b6034c6bb74b.png)


## 背景
1\.現在、インフラ系のお仕事をしており、クラウドについて学習がしたくAWSに興味を抱いた。

2\.AWSクラウドプラクティショナー認定試験に合格してもっとAWSに興味が湧いたため（沼にハマった）。

3\.AWSを使って仕事をして自分の世界を広めたいと感じた。


## 前提
・社会人2年目
・AWS実務未経験
・Udemyでハンズオン学習の経験はある。
・AWS Certified Cloud Practitioner（CLF）には合格してる（2023年12月）
・一応IT系の会社でSEをやってます。

## 学習コンテンツ
・[AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト - アソシエイト　改訂第3版 (AWS認定資格試験テキスト) ](https://www.amazon.co.jp/AWS-E8-AA-8D-E5-AE-9A-E8-B3-87-E6-A0-BC-E8-A9-A6-E9-A8-93-E3-83-86-E3-82-AD-E3-82-B9-E3-83-88-AWS-E/dp/4815617945/ref=dp_ob_title_bk)
→参考書として使用しました。

・[AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/course/aws-and-infra/?couponCode=JPLETSLEARNNOW)
→CLFを受験した後、こちらを受講して、AWSを使った基本的なサービスの使用法を学び、実際にWordPressブログを構築できました(削除しましたが)。

・[【SAA-C03版】これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座](https://www.udemy.com/course/aws-associate/?couponCode=JPLETSLEARNNOW)
→AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得より多くのサービスをマネジメントコンソールを通して学習できました。

・[【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/?couponCode=JPLETSLEARNNOW)
→試験2週間程前に購入し、ひたすら過去問を解き間違箇所やあやふやな箇所をノートにまとめた。
 演習テスト1.2は一回目で合格水準に達したが、それ以外は二週目で合格点に達しました。

## 大事だなと思った観点
#####  
あまり具体的には言えませんが、CLFとは違い、サービス単体で出題されてことが数問のみで多くが複数のサービスを使った問題が多かった。
これはアナログ的な考えかもしれないですが、実際に設計図のようなものを紙で書いてみるのが効果抜群だった気がします。
また、もっとあると思いますが個人的には以下の考え方が改めて大事だなと感じました（皆さんも同じだと思うが）。

1\.適切なセキュリティ設定

試験概要の「セキュアなアーキテクチャの設計」に当たりますね。やはり、AWSを使うなかで適切なセキュリティ設定は大事です。
またサービスを利用するにしても権限を付与していないと、他のサービスと連携ができないなどあるため、どのようにサービスに設定を加えて連携ができるかなどを学習した方が良いかも。

2\.障害に強い設計法

 試験概要の「弾力性に優れたアーキテクチャの設計」に当たりますね。
 リージョンやアベイラビリティゾーンかで各サービスの設定をするかが変わってきます。
 そのため、リージョン単位なのかアベイラビリティゾーン単位なのかを判断して耐障害性に対応する設定を学習したら良いかもです。

3\.運用をなるべく自身で行わない設計
 こちらも試験概要の「弾力性に優れたアーキテクチャの設計」に当たるかなと考えています。
 なるべく、フルマネージドサービスを使って運用を楽しようという考えやサービスの選定が大事かもです（主にFargate）。

4\.使用状況応じたコスト最適化
試験概要の「コストを最適化したアーキテクチャの設計」に当たりますね。
短期で利用するのか長期で利用するのか、キャパシティーは予測できるのか等で利用するサービスの料金設定方法が変わってきます。
どの設定が最適かを選定する必要があるため、各サービスの料金設定方法を学習した方が良いかもです。

5\.高パフォーマンスを出す設定
試験概要の「 高パフォーマンスなアーキテクチャの設計」に当たりますね。
こちらでは主にEBSのボリュームタイプやEC2のインスタンスファミリー等をどれにしたらよいかを選定する必要があります。
そのため各サービスの「この設定にすればこの性能を発揮できる」というのを学習したら良いかもです。



## 最後に
このような、資格試験に合格できたのは周りが刺激を与えてくれたからだと思っています。
ありがとうございます！

私はAWSを仕事で使ったことがないですが。2か月半程かけましたが、合格することができました。
後々AWSが提供している試験ガイドを見ると確かにどれも大事な観点だなと感じ、さらに学習意欲が湧きました。
今後は、会社にAWSを使った案件に参画できないかを相談したいです。

この記事を読んで「役に立った」をいう人が一人でもいましたら、この上なく幸せです。

最後までお付き合いいただきありがとうございました。
eguiでbaslerのビューアを作ってみる

試験勉強中についつい部屋の掃除を始めてしまうとか、いわゆる現実逃避ですね。今回はそんな感じのものです。Rustは勉強中なので全然違う話ではないのですが、興味本位というのは否定できません。

# Rustでビューアを作る
こんにちは。お試しで作ったものの結局使われることが無かったもの供養シリーズです。

今回はRustで、GUIで、FA用カメラとしては有名なBaslerのビューアを作ってみました。RustでGUIというだけでも挑戦的なんじゃないかと思いますが、[Dear ImGui](https://github.com/ocornut/imgui)を気に入って使っているのでその系統の[egui](https://github.com/emilk/egui)を使っています。

完成したものは[GitHub](https://github.com/ishikawakouji/egui-pylon)にあります。ご参考まで。

# 準備
Rust と egui の準備は特に問題ないかと思います。

BaslerはpylonというSDKがあるので、Cなどからは容易に利用することが可能です。Rustだとどうするのかなぁと思って探したら、ラッパーがありました。[pylon-cxx](https://github.com/strawlab/pylon-cxx)を使います。

その他いろいろ追加する必要がありますが、最終形状は以下になっています。
```toml
[dependencies]
anyhow = "1"
eframe = {features = [
  "__screenshot", # __screenshot is so we can dump a screenshot using EFRAME_SCREENSHOT_TO
]}
#egui_extras = {"0.22.0" , features = ["image"]}
env_logger = "0.10"
itertools = "0.11.0"
log = "0.4.19"
pylon-cxx = "0.3.4"
```
eguiを利用するだけだったら、もっとシンプルに用意できたかもしれませんが、そこまでやっていません。

# 難所
カメラのインスタンスを構造体に収めたいと思ったので pylon-cxxとはちょっと違う感じになったのですが、ここが苦労の始まりでした。

構造体を初期化するときに、オブジェクトとその参照の両方を必要としていて、コンパイラが許してくれません。Rustではどうするの？みたいな質問も見ます。結局こちらを参照しました。

https://medium.com/@reduls/refers-other-field-in-the-same-struct-in-rust-777bb2075b8c

根本的な解決策にはなっていませんが、```unsafe``` を使います。

```rust
    let pylon = pylon_cxx::Pylon::new();
    let lefp: &'cam _ = unsafe { &*(&pylon as *const _) };
    let camera = pylon_cxx::TlFactory::instance(lefp)
        .create_first_device()
        .unwrap();

    Self { camera, pylon }
```

そういう訳なので、この構造体を削除する時も注意が必要なようで、なんとなく消える順番に書くのがよさそうです。

```rust
struct GrabApp<'cam> {
    // メモリを開放して欲しい順？にフィールドを記述
    camera: InstantCamera<'cam>,
    #[allow(dead_code)]
    pylon: Pylon,
}
```

その他、日本語表示のいろいろも加えてあります。

# 動かし方
pylon SDKにはエミュレータが内蔵されており、本物のカメラが無くてもお試しができます。環境変数を設定してください。数字はエミュレータの個数です。1個でも大丈夫です。

```dosbatch
PYLON_CAMEMU=2
```

エミュレータは白黒なので、これ前提のコードになっています。表示はRGBのカラー表示なので、バッファの順番を間違えなければ、カラーでも表示できると思います。

# おわりに
C++ で ImGui を使ったビューアはここまで苦労しませんでした。でも、個人的にはRust使えて、GUIもなんとかなったので、満足です。
【UiPath】開発時に気をつけているポイントについて

# はじめに
UiPath Studioを用いてのRPA開発を行っております。
業務担当者と要件ヒアリングを実施して本番リリースするまで、認識合わせのための時間を多くいただいております。
業務担当者側では、自身の業務について熟知しておりますが、RPA化に伴いチェックポイントを落とし込めないケースが多々あると思いました。
過去の開発経験でチェックまたは説明したほうがよいポイントをナレッジとして残します。

# この記事の対象者
- UiPath初学者

# 気をつけているポイント

### 入力値と取得値チェック
ロボでデータ入力を行うケースは多々あります。システムのデータ検索条件の入力・既存データ更新等で入力処理を行われると思いますが、「ロボでデータ入力 → 入力したデータ取得」の工程を入れるようにしています。
ロボでは決められたルールに沿って処理を行いますが、他システムでデータ入力を行う場合、システム毎に入力可能文字・入力可能文字数制限があります。
ロボで正しく入力したつもりですが、実は正しく入力できていないケースも起こり得るため、「ロボでデータ入力 → 入力したデータ取得」の工程を入れることにより正しく処理が行われたかの整合性チェックは重要となります。

| チェック対象 | チェック観点 |
|:--|:--|
| 文字数 | 入力した文字数が正しいかチェック(数字の場合、先頭に0がある場合システム側で省略されるケースもある) |
| データ入力 | 入力内容の整合性チェック(顧客情報の更新やステータスが正しいか確認する) |

:::note warn
ロボで入力値と取得値のチェックを入れていない場合、誤った情報のデータ更新を行われるケースがあります。その場合、インシデントに繋がるケースも多々あるため、入力値と取得値のチェックを入れることを強くオススメします。
:::

### メッセージチェック
ロボで特定ボタンを操作する場合、メッセージ表示されるケースがあります。
処理内容によっては特定の画面が表示された場合にそのまま処理を行うように作っている方もいらっしゃいますが、とても危険になります。
ロボで操作する場合、セレクターで操作するアイテムを設定するのですが、セレクター取得がid取得ではなくidxの場合、システム更新に伴い表示するボタン位置が異なるケースもあります。
その場合、本来データ更新のみを想定して作られているのですが、セレクター位置が削除処理を行うボタンの場合、データ削除として行われるケースがあります。
システム側で削除時に確認メッセージが表示または削除完了の旨もメッセージが表示された場合、ロボ側でメッセージチェック判定を入れていると想定外の削除処理を未然に防げるまたは想定外メッセージの場合にシステムエラーで落として原因分析を行えます。
メッセージチェックを入れていない場合、入れてみることをオススメします。

| 処理内容 | チェック観点 |
|:--|:--|
| 検索(SELECT) | 検索対象データが存在有無 , 検索件数が多い場合のメッセージ有無 |
| 登録(INSERT) | 登録時のポップアップメッセージ表示有無 , 想定通りのメッセージチェック |
| 更新(UPDATE) | 更新時のポップアップメッセージ表示有無 , 想定通りのメッセージチェック |
| 削除(DELETE) | 削除時のポップアップメッセージ表示有無 , 想定通りのメッセージチェック |

:::note warn
データ件数が10件程度の場合、処理内容によってはリカバリー可能ですが、
100件~1000件とデータが多くなるにつれてリカバリー対応は難しくなります。
データに対して処理が行われる場合はメッセージチェックを行うことを強くオススメします。
:::

### 利用システムの負荷確認
社内システムまたは社外システムで確認観点は変わってきますが、ロボでは条件を満たす限り繰り替えし処理を行うことは可能です。
人の手で操作する場合、画面確認や入力内容を確認してシステムの更新処理を行います。
処理するデータによっては時間にばらつきがあり、ロボの場合、人と比べてはるかに早い時間で入力およびデータチェック処理が行われます。
そのため人の操作に比べて処理するスピードが早いのでシステムに対して負荷がかかります。
負荷がかかりすぎる場合、システムが落ちてしまうケースも起こり得るため、ロボで利用したいシステムが決まっている場合、負荷対策に関してシステム側とお話しする必要があります。
システム負荷軽減策の例として、「一定回数のシステム再起動、一定時間の待機処理」などあげられます。

:::note warn
ロボで操作するシステムが基幹システムの場合、システム停止による影響範囲は甚大になります。ロボで操作前には事前に相談を行い対応策の検討が必要になります。
:::

### 処理するデータが一意になるか確認
処理するデータは検索方法によっては大量にデータが表示されるケースもあります。その場合、本当に処理を行いデータなのか判断がつきません。極力は表示されるデータが一意になる画面で操作するのが好ましいです。システム側で一意にならない場合、処理対象条件を細かく取り決めることにより限りなく想定した処理するデータに近づくことは可能です。

:::note warn
要件ヒアリングをしっかり行い業務内容に十分な理解を持ってから実装することを強くオススメします。
:::

# おわりに
今回は私自身がRPA開発時に気を付けているポイントを簡単にまとめました。
現時点で思いついたポイントをメモベースとしてまとめておりますが、今後気になった点がありましたら追加する予定です。今回の記事で誰かの参考になれば幸いです。
Cif2cellの環境構築

Cif2cell (https://sourceforge.net/projects/cif2cell/files/latest/download) から第一原理計算用入力ファイル.inを作成する方法の備忘録。とにかくcif2cellを動すことが目標としている。次の動画を主に参照している。(https://www.youtube.com/watch?v=yPUjTDWIMOU&list=LL&index=2&t=210s)

環境:Ubuntu

まずCif2cellはUbuntuに標準搭載のpython3では動かないらしい(筆者は試していないが)ためUbuntuにpython2を入れる。
```
$ sudo apt upgrade
$ sudo apt -y install python2 python-setuptools python2-dev
```
次にCif2cellのホームページから(https://sourceforge.net/projects/cif2cell/files/latest/download) からcif2cell-1.2.10.tar.gzをダウンロードし、任意のディレクトリ中で解凍する。
```
$ tar -zxvf cif2cell-1.2.10.tar.gz
```
次にpython2をデフォルトで使用できるようにする。筆者は次の方を参考にした。(https://qiita.com/piyo_parfait/items/5abbe4bee2495a62acdc) 現段階でどのpythonが入っているか、確認する。
```
~$ which python2
/usr/bin/python2
~$ ls /usr/bin/ | grep python
python2
python2-config
python2.7
python2.7-config
python3
python3-config
python3.10
python3.10-config
x86_64-linux-gnu-python2-config
x86_64-linux-gnu-python2.7-config
x86_64-linux-gnu-python3-config
x86_64-linux-gnu-python3.10-config
```
python2は2.7 python3は3.10が入っていることがわかります。下記の通り入力し python2.7を優先度1、python3.10を優先度2で登録しておきます。
```
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7  1   #python3.6を優先順位1で登録
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.10 2   #python2.7を優先順位2で登録
```
登録されたpythonの、優先順位を確認しpython2に設定する。
```
$ sudo update-alternatives --config python
There are 2 choices for the alternative python (providing /usr/bin/python).

  Selection    Path                 Priority   Status
------------------------------------------------------------
* 0            /usr/bin/python3.10   2         auto mode
  1            /usr/bin/python2.7    1         manual mode
  2            /usr/bin/python3.10   2         manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
```
再びcif2cell-1.2.10のディレクトリ内に入って確認

```
$ cd cif2cell-1.2.10
$ ls
ESPInterfaces.py  LICENSE   PyCifRW-3.3.tar.gz  cif2cell  docs            setup.py           uctools.py
HOWTOCITE         PKG-INFO  README              cifs      elementdata.py  spacegroupdata.py  utils.py
```
PyCifRW-3.3.tar.gzを解凍
```
$ tar -zxvf PyCifRW-3.3.tar.gz
```
PyCifRW-3.3中に入ってsetup.pyを実行
```
$ cd PyCifRW-3.3
$ sudo python2 setup.py install
```
cif2cell-1.2.10に戻ってsetup.pyを実行
```
$ cd ..
$ sudo python2 setup.py install
```

ここまででCif2cellの環境構築は終了。

(https://www.crystallography.net/cod/) から適当なcifを持ってきて保存。cifファイルを保存したディレクトリに移動し確認。今回は1010196.cifで保存している。
```
$ ls
1010196.cif
```
細かいコマンドは別の投稿で解説する予定。対称性を保った形で.inファイルを作成する。.cifを最後に書く。
```
cif2cell --force -p pwscf --setup-all --print-symmetry-operations --pwscf-atomic
-units --pwscf-pseudostring=.pbe-spn-kjpaw_psl.1.0.0.UPF -f 1010196.cif
```
同じディレクトリ中に.inファイルが作成されている。
```
$ ls
1010196.cif  name.in
```
GraphRAGを試しました。（Neo4jでナレッジグラフを作成）

昨日、最近話題となったGraphRAGを試しました。
GraphRAGとは、データをナレッジグラフの形式で保管し、RAGで検索する際にはナレッジグラフで回答を探すという技術です。通常のRAGと比べると、基本的には正しい情報だけが含まれているため、精度が高くなります。マイクロソフトも先日RAGとGraphRAGを比較する研究レポートを発表しました。⇩（GraphRAGの特徴と、どんな場合にRAGより精度高いのかを多角的に説明しています。）

https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/?ref=blog.langchain.dev

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/c0ef9231-4951-4bfa-5824-6d30aa640699.png)

## ナレッジグラフ（Knowledge Graph）とNeo4j

ナレッジグラフは主に、ノード（node）とリレーションシップ（relationship）で構成されて、単語ごとの関係を表しています。（GoogleやYahooなどの検索エンジンもナレッジグラフに基づいて検索を行っています）

ナレッジグラフを自動的に作成するために最もよく使われているライブラリはNeo4jです。Neo4jにテキストデータとパラメーターを設定して渡したら、自動的にナレッジグラフを作成してくれます。（イメージとしては⇩）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/4a73cd30-d63e-98d5-551f-791fd08fc243.png)

こちらは、WikipediaのAPIを使って”toyota”に関して検索した結果をNeo4jで生成したナレッジグラフです。真ん中には”Toyota”というノードがあり、それに関連する他のノードが周りに配置されています。それらの間にはリレーションシップが示されています。例えば、ToyotaとLexusの間のリレーションシップはproduces（生産する）となっています。Lexusに関するデータをさらに追加すれば、Lexusの周りにも他のリレーションシップが広がります。（日本語wikipediaで試しましたが、なぜかエラーが出てうまくいかなかったので、英語で作りました）


## Graph RAGの処理フロー

⇩の図は、LangChainが公開されたGraph RAGの処理フローです。（Graph RAGと通常のRAGを両方組み合わせしています）
流れとしては、ユーザーのprompt文をナレッジグラフと通常のベクトルストアの両方で答えを探し、LLMに結果を渡してoutputを生成する感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/21c7eea4-c306-b23d-2df3-2060d5ead676.png)


実際ナレッジグラフから検索されたデータ（LLMに渡した内容）は以下のようです。
"トヨタはどのような会社ですか"と検索すると、先の図に示されていた”toyota”に関連する内容がテキスト形式（node⇒relationship⇒node）で整理されて返ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/dd005d53-6294-bfef-330e-181f1b7d6c7b.png)

１個質問を試したら間違いなく回答できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/5e398b18-5612-c4a3-1b8d-8c038c797cef.png)


興味ある方:

https://blog.langchain.dev/enhancing-rag-based-applications-accuracy-by-constructing-and-leveraging-knowledge-graphs/

Deeplearning.aiのGraph RAGコース

https://www.deeplearning.ai/short-courses/knowledge-graphs-rag/
【Windows】Git 導入

## Git とは
ソースコード等の管理に使用される、バージョン管理システム。
バージョンの新旧に関わらず一元的に管理することができ、任意のタイミングで任意のバージョンに戻すことができる。

## Git インストール手順
### 1. 下記 URL にアクセスする
https://git-scm.com/

### 2. インストーラをダウンロードする
Downloads をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/6b941a54-b6fe-87d5-59d4-78989da07b87.png)

Windows をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/3f34b2ee-3109-de30-0136-1a45f880cc83.png)

Click here to download をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/17524b89-b813-57d9-49c0-e7ff1213fe53.png)

### 3. インストーラを実行する
Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/367d6f11-2566-cd21-c809-b9d6b13391ec.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/722e9761-29fd-6d5b-e734-7560929acfb8.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/363464f1-eaf4-83b9-a8ca-2257a322aa9f.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/98f76a92-8370-3094-bb8a-1508dd3553b8.png)

使用するエディターを選択して Next をクリック
(筆者は Visual Studio Code を選択している)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/c352d3e2-2e46-a45e-9f8a-77e7b206bdc8.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/6eb7da79-cccf-4cd4-2216-dc05c3c78769.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/2c88e93a-2861-9d8e-5f9b-f33dc4f9dd49.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/93e5fc7a-7047-4fc8-d2bb-2c68bc10bcc6.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/0ebc1fd0-076d-47aa-22e9-2fbc54c17090.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/0f946aad-8713-4086-635e-12211da94699.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/ec89900b-534d-e44c-0fae-012b6ee4a710.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/602f2f9c-5006-ed03-55dd-b56050192052.png)

Next をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/3a07b4fe-0946-3222-258f-2b2bac8ccb9d.png)

Install をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/951fd734-5173-c256-b1a0-37d12f5542e6.png)

Finish をクリックしてインストール完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/ca193809-f59d-6b06-2bfb-5f1023be90a9.png)

## Git 動作確認
### Git にパスが通っていることを確認する
コマンドプロンプトで、以下のコマンドラインを実行
```
where git
```
実行結果がキャプチャのようになれば OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/82795afa-beca-b92a-fa42-9c38a761472c.png)

### Git のバージョンを確認する
コマンドプロンプトで、以下のコマンドラインを実行
```
git --version
```
インストールしたバージョンが表示されれば OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749137/d67ca952-d606-26f2-753a-3a262b1bbf61.png)
「加比の理」を調べた。ChatGPTも。

・**ChatGPT-3.5先生の回答で、 はじめて２案がでました。２列表示です。**
・中学入試数学？いろいろ種類があるようです。

# オリジナル 
・加比の理 でgoogle検索

https://sanjutsu.com/sansuukouza/kahinori/

・sympyで
　FreeCADで作図作成中。
```python
from sympy import *
E = Point(0, 3)
C = Point(8, 0)
B = Point(0, 0)
F = Point(5, 5)
G=Line(E,C).intersection(Line(B,F))[0] 
print("#",E.distance(G)/G.distance(C))
print("#",Triangle(E,B,G).area/Triangle(G,B,C).area)
# 3/8
# 3/8
```

# "加比の理"の正式の翻訳を探しています。
#### (以下抜粋です。) ChatGPT-3.5先生へ はじめて２案がでました。２列表示です。　
You
数学の「加比の理」 を英語で教えて下さい

You
正しいですか

ChatGPT

Which response do you prefer?
Your choice will help make ChatGPT better.
...

**みなさんへ**
Associative Property
でいいですか？

# wikipedia 
勉強中

# 大学入試の過去問
#### "加比の理"で過去問の内部検索
(2024/03/20)

＞一致する結果はありません　大学入試数学問題集成 様内

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&oq=%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&gs_l=partner-web.12..0i512i4i37l2j0i512l6.3070.3070.0.5399.1.1.0.0.0.0.257.257.2-1.1.0.csems%2Cnrl%3D10...0....1.34.partner-web..0.1.256.iOUNOcx-Nuo

＞site://kamelink.com "加比の理"との一致はありません。

https://www.google.com/search?q=site%3A%2F%2Fkamelink.com+%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&rlz=1CAUHAM_enJP1089&oq=site%3A%2F%2Fkamelink.com+%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQRRg60gEJMTEwNzdqMGo0qAIAsAIA&sourceid=chrome&ie=UTF-8

＞site://mathmathmass.exblog.jp "加比の理"との一致はありません。

https://www.google.com/search?q=site%3A%2F%2Fmathmathmass.exblog.jp+%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&rlz=1CAUHAM_enJP1089&oq=site%3A%2F%2Fmathmathmass.exblog.jp+%22%E5%8A%A0%E6%AF%94%E3%81%AE%E7%90%86%22&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQRRg60gEIODQ0MWowajSoAgCwAgA&sourceid=chrome&ie=UTF-8

# 中学入試の過去問


# リンク
UE5 幽霊マテリアルを実装

# 概要
今回は幽霊感を出すマテリアルを作成していきます。

# 実装
### 輪郭を不透明
輪郭部分を不透明にすることで幽霊感をだしていきます。
実装はメッシュの法線と視線ベクトルとの内積で求めていきます。
「Blend Mode」は「Translucent」で設定します。
![dot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/83a6a606-8ee0-bfbe-6028-a7c5b0ecabe4.jpeg)

### 接触色変化
他オブジェクトが接触した場合に接触点を発行させるとより幽霊ぽくなります。
実装は深度テクスチャと自身の深度を比較することで求めます。
![Contact.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/f1eee162-69e0-50c3-6817-6cf6d1d7b203.jpeg)


### マテリアル全体
![whole.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/97c4e51a-3050-beff-c47c-99408c246627.jpeg)

# 結果
![Result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/04353b57-4a51-ad01-d63b-c2c5ca317787.jpeg)


# まとめ
どちらかというとゲームに出てくる幽霊なマテリアルになりましたね。

# 参考

https://www.4gamer.net/games/463/G046388/20220827012/
Web API The Good Partsのまとめ Part1

### 初めに
仕事でヘッドレスCMSを利用する機会があり、APIについてより深く知る必要ができたので以下のWeb API The Good Parts読みます。

![Web API The Good Parts](https://m.media-amazon.com/images/I/51GHwTNJgSL._SX342_SY445_.jpg)

### 読む前の期待

- Web APIの設計方法
- Web APIを設計する上で注意する点
- Web APIを利用する上でセキュリティ上注意する点

# メモ

### Web APIとは

<aside>
👌 HTTPプロトコルを利用してネットワーク越しに呼び出すAPI

</aside>

> **APIとは**…Application Programming Interfaceのことで、機能は分かっているけれど中身の実際の動作は詳しくわからない機能のカタマリを外部から呼び出すための仕様のこと
> 
- サービスを提供しているのなら、APIも公開すべき
- APIを公開することで、サービスの新しい活用方法などが考えられサービス自体の価値を高める。
- また既に公開されているAPIを利用することでユーザー側がサービスを利用するハードルを下げることができる

### Web APIは美しく設計しよう

- 良いAPIは
    - 使いやすい
    - 変更しやすい
    - 堅牢である
    - 恥ずかしくない


### 感想
そもそも最初の内はAPIが何なのかさっぱりでしたが、WebAPIがURIであることを理解してからは少しずつ親近感がわいてきたように思います。
またネットで簡単に利用できるAPIなどを実際に触ってみるのも理解を深めるのに良いなと思いました。

また、この本は読書中ですが、[Webを支える技術](URL "https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042/ref=asc_df_4774142042/")という本を読んでおくとかなり理解度が違うなと思いました。(RESTの概念や、HTTPメソッドの利用目的や背景などが特に）

![Webを支える記述](https://m.media-amazon.com/images/I/61wuUjGEoML._SY466_.jpg "Webの基礎")
ITで頻出の〇〇性をまとめてみた。

## はじめに
エンジニアをしていると〇〇性に当てはまる単語を目にする機会が多いと思います。
今回はよく見るものをまとめてみました。

## 〇〇性
### 保守性（Maintainability）
ソフトウェアの将来的な修正、更新をどのくらい低コストで効率的に行えるかを表す。

### 再利用性（Reusability）
プロジェクトのソースコードを、他のプロジェクトでもそのまま利用できるかを表す。

### テスト容易性（Testability）
ソフトウェアがどれだけ簡単に正確性の高いテストをできるかを表す。

### 機密性（Confidentiality）
情報にアクセスできるのは許可されたユーザー、システムのみであることを保証する。

### 完全性（Integrity）
情報が不正な改竄や削除がされていなく、正確なものであることを保証する。

### 可用性（Availability）
許可されたユーザーが必要な時に情報やリソースにアクセスできることを保証する。

### 信頼性（Reliability）
障害が発生せずどのくらい正常に動作し続けるかを表す。

### 互換性（Compatibility）
あるシステムやデバイスを置き換えても問題なくこれまで通り動作することを表す。

### 脆弱性（Vulnerability）
ソフトウェア、ハードウェアのセキュリティ面での欠陥を表す。

### 柔軟性（Flexibility）
ソフトウェアが将来の変更について容易に変更できることを表す。

### 可読性（Readability）
コードの読みやすさ、理解しやすさを表す。

### 拡張性（Extensibility）
システムに新しい機能の追加のしやすさを表す。

## 最後に
もっと色々な〇〇性があると思いますが、一部まとめてみました。
英語だと〇〇ビリティでちょっとかっこいいですよね。
ソフトウェア開発をする上で、上記のような色々な部分を考えて設計・実装ができるようになりたいです。
BedrockでQiitaの記事を書いてもらった

# はじめに
お疲れ様です。yuki_inkです。

気付けば3月末となってしまいました。
いろいろやることがあって、めちゃくちゃ忙しい！
そんな中でも記事の投稿はしたい！
よし、Bedrockに助けてもらおう！

という内容の省エネ系ネタ記事です。


# やったこと
Qiitaの「Markdown記法 チートシート」をプロンプトでLLMに渡して、それっぽい記事を作ってもらう。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

・環境：Bedrockのテキストプレイグラウンド
・利用したモデル：Claude 2.1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/b076a9c4-85ce-1d22-6187-9910ed9d5545.png)

プロンプトは以下の通り。
```
Human:
あなたは生成AIの専門家です。
生成AIに関する最新技術の内容やその課題について、起承転結のあるブログ記事にまとめてください。
冒頭にこのブログ記事のタイトルを示し、その後に記事を作成してください。
記事の作成にあたっては、<rules></rules> に示すMarkdown記法に従い、必要に応じて、以下の対応をしてください。
・見出しの作成と見出しタイトルの付与
・コードの挿入
・文字の強調　など

<rules>
###### 以下、「Markdown記法 チートシート」の内容をコピペ ######

Code - コードの挿入
Code blocks - コードブロック
たとえば、「Ruby」で記述したコードをファイル名「qiita.rb」として投稿したいときは、 バッククオート（`） か チルダ（~） を使用して以下のように投稿するとシンタックスハイライトが適用されます。
コードブロック内でコードブロックを書きたい場合は異なる記号を使うことで書けます。

・・・
</rules>

Assistant:
```
# 結果
`Assistant:`の後に、生成された文章が表示されます。
「生成AIの最新技術とその課題」というタイトルのブログ記事ができました！
良い感じにMarkdown記法が使えており、内容もそれっぽく仕上がっています。
コードとして`import generative_ai`などと書いていますが、そこはご愛嬌。。

**※生成された文章は、この記事の最後にそのままコピペしておきます。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731275/638352ad-e7fe-18b0-d53c-7cfd0134a8fb.png)



# 感想
Markdown記法に則った記事が、想像より遥かに良い感じの内容で出てきたので、正直驚きました。
RAGアーキテクチャなどと組み合わせて、様々なノウハウを簡単にブログに落とし込むことができそうです。

記事を書くことは、少なくとも私にとっては結構大変な作業でした。
記事の構成を考え章立てを決め、実際に文章を書くのって、かなり時間を使います。
生成AIの助けを借りることで、その負荷が下がり、アウトプットのハードルが下がるかなと思いました。

一方で、あくまで生成AIが作る文章。
その内容の正確性、信頼性にはまだまだ疑念が残ります。
[Qiitaのコミュニティガイドライン](https://help.qiita.com/ja/articles/qiita-community-guideline)でも案内されている通り、自分の目でしっかり内容を確認する必要があります。

> **☝ AIが生成した内容は正確性を確かめよう**
記事等の執筆に便利なAIツールを活用することそのものは禁止していませんが、AIが生成した内容は、そのまま投稿するのではなく、正しいかどうかを検証した上で投稿するようにしましょう。 Qiitaで提供しているAI機能を利用する場合も同様です。 正確ではない情報が投稿されることは、コミュニティにとって望ましいことではありません。内容に責任をもって投稿しましょう。


# 今回作ってもらった記事
最後に、今回Bedrockで作ってもらった記事をそのまま貼っておきます。

:::note warn
以下の内容はClaude 2.1が生成したものをそのまま添付しているものになります。
内容の確からしさは確認しておりませんので、それを踏まえてお目通し下さい。
:::

# 生成AIの最新技術とその課題

## 1. 生成AIとは

生成AIとは、テキスト、画像、動画などのコンテンツを自動生成するAIのことです。近年、大規模な学習データと計算資源の向上により、非常にリアルなコンテンツを生成できるようになってきています。

```python
import generative_ai
text = generative_ai.generate_text("Hello!") 
```

代表的な生成AIとしては、**OpenAI**のDALL・EやGitHub Copilot、**Stable Diffusion**などがあります。

## 2. 生成AIの最新技術

生成AIの最新技術としては、以下のようなものがあります。

### 2-1. 大規模言語モデル(LLM)

LLMとは、膨大なテキストデータから言語の法則性を学習したAIモデルです。**GPT**シリーズや**BLOOM**などが知られています。これらは自然な会話ができたり、コードを生成したりすることが可能です。

### 2-2. ディフュージョンモデル

ディフュージョンモデルは、ランダムノイズから徐々に画像などを生成していく手法です。**Stable Diffusion**や**DALL・E**が採用しています。リアルな画像を生成できる反面、トレーニングデータのバイアスが結果に現れやすいという課題があります。

_この手法は画像生成以外にも応用が期待されています。_

## 3. 生成AIの課題

生成AIには以下のような課題があります。

### 3-1. 結果の信頼性

生成AIの結果が事実かフィクションか判断しづらいため、デマの拡散などの社会的影響が懸念されています。

### 3-2. トレーニングデータのバイアス

生成AIは膨大なデータから学習するため、データに含まれる偏見などが結果に現れる可能性があります。公平性や多様性への配慮が必要です。

:::note warn
生成AIの利用には倫理的な配慮が重要です!
:::

## 4. 今後の展望

生成AIは高性能化と共に身近な技術となってきていますが、適切な利用のための議論とガイドライン作りが急務です。多角的な観点から技術革新と社会的影響を踏まえた対話が望まれます。
ランダム生成中に　特別なオブジェクトを混ぜる場合のメモ

Blenderのジオメトリノードで
ポイント上にランダム生成する場合に　特定地点には決まったものを生成したいとい場合の手法メモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/c7617efa-a99d-4c40-bd47-65d229025720.png)
- 基本はジオメトリ近接で距離を取得してポイントをフィルタするだけ
- ただしコレクション内のオブジェクトでまとめてフィルタしたい場合
コレクション情報から出るのはインスタンスとしての情報なので実体化する必要がある（忘れがち）
- 距離でのフィルタは　あくまでもポイントの座標からなので重ならない座標にするには注意が必要
![24032001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/f2994dcc-3827-2a92-686a-468e06fd926a.gif)
（面からポイントの距離を意図的に遠くなるようにして　内部でも発生してしまうようにした例）
【AWS】ACM SSL/TLS認証ステータス保留中の検証のまま変わらない


# はじめに:
SSL/TLS認証をリクエストして、ステータスが保留中の検証のまま変わらずタイムアウトした時のことを書きたいと思います。

# 問題の説明:
Route53でドメインを購入して、ホストを作成しました。
その後CloudFrontとALBにSSL/TLS証明書を付けたかったのでACMで証明書をリクエストしました。

しかし、以下図のようにステータスが保留中の検証のまま変わらずタイムアウトしました。
![スクリーンショット 2024-03-20 17.31.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672823/7fe9113a-53d1-b690-6012-be09a621a66e.png)

# 原因と解決方法：
結論から言うと、以下３つの値が一致していなかったことが原因でした。
(既存ドメインとは別に新しくドメインを購入した際にネームサーバーを変更していなかったようです。)


- 登録済みドメインのネームサーバー
- ホストゾーンのネームサーバー
- ホストゾーンのNSレコードの値

![スクリーンショット 2024-03-20 16.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672823/4eba6f17-c497-7c46-fc24-993a7fd9263d.png)

![スクリーンショット 2024-03-20 17.04.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2672823/b2f1dcaa-29bb-e553-0c9e-3d9527f1d6fa.png)

ホストゾーンのネームサーバーの値は変更不可でしたので
他２つをホストゾーンのネームサーバーの値に合わせると、数分後にステータスが発行済みのとなりました。

またその際、NSレコードのTLLを300秒に設定してレコードの伝播速度を一時的に短く設定して変更が早く反映されるようにしました。


# 参考資料:
https://repost.aws/ja/knowledge-center/acm-certificate-pending-validation

https://techblog.nhn-techorus.com/archives/22849

https://speeddata.jp/dns_monitoring/dns_ttl.html
poetryに直接wheelを読み込ませる方法

pystanが動く環境をpoetryとdockerを使って作ろうとしましたが、僕の使っているM1 macではpystanが依存しているhttpstanのwheelファイルが用意されていないらしく、httpstanを直接buildしてpoetryに読み込ませる羽目になりました。

https://twitter.com/otakumesi/status/1459906977589436418

同じ悩みを持っていた方

dockerコンテナの作成や、poetryプロジェクトの作成は終わっているものとします。

# ライブラリのダウンロード
wheelファイルがないライブラリのgithubに行ってライブラリをダウンロードします。
```
wget https://github.com/stan-dev/httpstan/archive/refs/tags/4.12.0.tar.gz
tar -zxvf 4.12.0.tar.gz
```

# ライブラリのbuild
githubのinstallationに従ってbuildしてwheelを作ります。
```
cd httpstan-4.12.0
make
```
httpstanではpoetry buildでwheelを作成します。
```
python3 -m poetry build
```


# wheelをpoetryに読み込ませる
作成されたwheelをプロジェクト内のpyproject.tomlに読み込ませます。[tools.poetry.dependencies]にはライブラリ名=バージョンが書かれていますが、バージョンの部分を{path}に変えることローカルのwheelを読み込ませることができます。
```
# 普通にインストールするとpymcのようになる。
pymc = "^5.11.0"

# ローカルのwheelのpathを指定することでローカルから読み込んでくれる
httpstan = {path = "/home/httpstan-4.12.0/dist/httpstan-4.12.0-cp311-cp311-manylinux_2_36_aarch64.whl"}
```
参考にしたサイト
https://python-poetry.org/docs/dependency-specification/#path-dependencies

# 目的のライブラリをインストール
依存関係にあるライブラリを読み込ませたので、目的のライブラリをインストールできます。
```
poetry add pystan
```

# あとがき
前に[m1 Macでのtensorflowのインストール方法](https://qiita.com/Hakky_ball/items/f70fd7247831d77549d3)の記事を書きましたが、CPUのアーキテクチャが違うだけでこれほどまでにめんどくさいと、だんだんイライラしてきます。

お金があればlinux用の端末も買えるのに...
Streamlitでpage_linkを使おうとしたらStreamlitAPIExceptionで怒られた話

# Streamlitでpage_linkを使おうとしたらStreamlitAPIExceptionで怒られた話

Streamlitは、データサイエンスと機械学習向けのアプリケーションを簡単に作成できるフレームワークです。今回は、異なるページ間でのナビゲーションを実装しようとしたらエラーが発生して仕様の理解に詰まったため、備忘録もかねてまとめてみます。この記事では、`page_link`を使ってページ間リンクを設定しようとした際に遭遇した`StreamlitAPIException`エラーのトラブルシューティングプロセスについて紹介します。

## 発生した問題

page_linkを使用したら、以下のようなエラーメッセージに直面しました。

```
StreamlitAPIException: Could not find page: ./movie_app/app.py. Must be the file path relative to the main script, from the directory: ocam_app. Only the main app file and files in the pages/ directory are supported.

Traceback:
File "/home/kinoshita/ocam_app/app.py", line 5, in <module>
    st.page_link("./movie_app/app.py", label="映画レビュー分析アプリ", icon="🎬")
```

## トラブルシューティング

### ファイルパスの確認

まず、指定したファイルパスが正しいかを確認しました。ファイルパスに問題はなく、`movie_app/app.py`は存在しています。しかし、Streamlitはこのファイルをページとして認識していませんでした。

### `pages`ディレクトリの利用

Streamlitの仕様上、ページ間ナビゲーションは`pages`ディレクトリを通じて管理されます。そこで、`pages`ディレクトリを作成し、`movie_app`フォルダを`pages`ディレクトリに移動してみましたが、認識せず。結果として、`pages`ディレクトリの直下に、`pythonファイル`を設置しないとしないことがわかりました。

### シンボリックリンクの試み

直下に配置する前に、`movie_app`フォルダを`pages`ディレクトリにシンボリックリンクとして追加する方法を試みましたが、先ほどの結論通りうまくいきませんでした。

## 結論

最終的にわかったこととしては、基点となる`app.py`と同じ階層に`pages`ディレクトリを作成し、その中に`pythonファイル`を直接入れる形が必須なようですね。

```scala
project_root/
│
├── app.py
│
└── pages/
    ├── movie_app.py
    └── (他のページ用Pythonファイル)
```

基本的に`pages`ディレクトリを作成するとサイドバーにリンクが自動表示されます。その機能を使う形としてのみ利用できるイメージですね...

今回の私が作っているアプリは独立したものを一つのページにまとめたりしたいだけなので、この機能よりlink_buttonを使って外部リンク扱いした方がいいかもしれません。
今さらですがＸ（旧Twitter）のアイコンを変更しました

コーポレートサイトにあるツイッターのアイコン（青い鳥）をＸのアイコンに変更した話です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/31e618e2-af68-ad4f-51fe-df5d93664ddc.png)

アイコンはWebフォントの **Font Awesome 5 Free** を使っています。

https://fontawesome.com/v5/search?q=twitter

```html:定義箇所
<a href="https://twitter.com/foobar" target="_blank">
    <i class="fab fa-twitter" alt="Twitter"></i>
</a>
<a href="https://www.facebook.com/foobar" target="_blank">
    <i class="fab fa-facebook" alt="Facebook"></i>
</a>
<a href="https://www.youtube.com/user/foobar" target="_blank">
    <i class="fab fa-youtube" alt="YouTube"></i>
</a>
```

Ｘのアイコンフォントは **Font Awesome 5** では提供されておらず、バージョンを **Font Awesome 6** に上げる必要がありました。
下位互換に対応しているようですが、今回はＸの公式サイトで配布しているSVGコードをコピペすることで対処します。

https://about.x.com/ja/who-we-are/brand-toolkit

上記サイトでＸのロゴをダウンロードすると `x-logo.svg` というファイルが含まれているので、エディタで開き、SVGコードをコピペします。
`width`, `height`, `fill` はCSS側で指定するので省きます。

```html
<a href="https://twitter.com/foobar" target="_blank">
    <!-- <i class="fab fa-twitter" alt="Twitter"></i> -->
    <svg viewBox="0 0 1200 1227">
        <path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z"/>
    </svg>
</a>
```

各アイコンはマウスホバー時、各Webサービスのブランドカラーに色が変わるようになっています。

```scss:SCSS
i {
	color: #fff;
	font-size: 36px;
	margin: 30px 20px 0 0;
	&:hover {
		color: #aaa;
	}
}
a[href*="twitter"]:hover i {
	color: #55acee;
}
a[href*="facebook"]:hover i {
	color: #1877f2;
}
a[href*="youtube"]:hover i {
	color: #da1725;
}
```

なので、SVGでもそれを実現するようホバー時に`fill`をセットしてあげれば完成です。
Ｘのブランドカラーは黒でした。

```scss:SCSS
svg {
	width: 36px;
	height: 36px;
	fill: #fff;
	margin: -14px 20px 0 0;
	&:hover {
		fill: #111;
	}
}
```
marqueeが非推奨なので代替物の雛形をanimateメソッドで再現

marqueeタグが非推奨になったので、代わりになるものを再現してみた。

CSSのキーフレームでも再現はできるんだろうけど、「アニメーションにかける時間」は文字数に応じてやりたいので、JavaScriptのanimateメソッドを使ってみた。

以下サンプル。

```html
<html>
<style>
  html,
  body {
    margin: 0;
    padding: 0;
    background-color: black;
    overflow: hidden;
  }

  #main_pane {
    margin: 0;
    padding: 0;
    line-height: 100vh;
    height: 100vh;
    color: white;
    font-size: 80vh;
    width: max-content;
    font-weight: bold;
  }
</style>
<div id="main_pane">こっちみて！😍😍😍</div>
<script>
  const textLength = document.getElementById('main_pane').innerText.length;
  document.getElementById('main_pane').animate(
    [
      {
        // ギリ画面の外に出しておく（長3変形）
        transform: "translateX(100vw) scale(0.7,1)", 
      },
      {
        // divの幅すべてを左に出す（長3変形）
        transform: "translateX(-100%) scale(0.7,1)", 
      },
    ],
    {
      // 文字数 x 0.8秒かけて移動させる
      duration: textLength * 800, 
      iterations: Infinity,
    }
  )
</script>
</html>
```

### 用途

スマホをデジタルサイネージ的に使って、案内文を出したい時を想定。

デジタルサイネージにするには、スマホのスリープを防ぐ仕組みが必要。WakeLock APIを使えばできるみたいだけど、まだ試してない。
EP2 プラントシュミレーションを使って異性からモテモテになろう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597163/5c77bad5-d476-1789-c38c-ef1d73b855aa.png)


---

え？プラントシュミレーションでモテるだって？そんなの可能なのかって？もちろんだぜ！プラントシュミレーションの魅力を上手く伝えれば、知的で魅力的なあなたをアピールできるんだ。さあ、どうやってそれを実現するか、オレが教えてやるよ！

### プラントシュミレーションって何？

まずは基本中の基本、プラントシュミレーションについて簡単に説明するぞ。これは、製造ラインやプラントの動きをコンピュータ上で再現し、効率化や問題解決を目指す技術だ。こう聞くと、ちょっと難しそうに感じるかもしれないが、要は「バーチャルでプラントを動かして、リアルの世界で役立つアイデアを見つけ出す」ってわけだ。

### 知的魅力をアピールしよう

異性を惹きつけるには、知的な話題で興味を持ってもらうのが一番。プラントシュミレーションを例に出して、「最新の技術を使って、より良い製品を作るためのシミュレーションをしているんだ」という話をすれば、あなたの知性や先見の明をアピールできる。

### チームワークの重要性を強調

プラントシュミレーションはチームで取り組むことが多い。この点を強調して、「チームで一緒に問題を解決することの大切さ」や「異なる専門知識を持つ人たちとの協力」など、協調性やコミュニケーション能力もアピールできる。これは、人間関係を大切にするあなたの姿勢を示す良いチャンスだ。

### 未来を見据えた話をしよう

プラントシュミレーションは、未来の製造業を形作る重要な技術。この話をすることで、「未来に向けて学び、成長しようとする姿勢」を示せる。例えば、「この技術がどう社会に貢献するか」や「将来の夢」など、ビジョンを共有することは、深いレベルでのコミュニケーションにつながるぞ。

### まとめ

プラントシュミレーションをただの技術だと思うなかれ。これをきっかけに、あなたの魅力をしっかりと伝えることができれば、異性からの関心もグンと上がるはずだ。何より、「こんなにクールな技術に取り組んでいる人」というイメージを持ってもらえるだけで、もうモテモテになること間違いなしだ！

さあ、プラントシュミレーションの世界で、あなたの新しい魅力を発見してみないか？興味を持ってもらえるような話題を見つけて、自信を持って伝えていこう。じ
テストケースの過不足確認の考え方について

# テストケースとは
> JSTQB用語集(※1：ソフトウェアテスト標準用語集Version2.3.J01)では、「実行事前条件、入力値、アクション(適用可能な場合)、期待結果、および実行事後条件のセットであり、テスト条件に基づいて開発されたもの」と定義されています。ソフトウェアテストを実施するためには、具体的な確認内容や期待値などをまとめた「テストケース」が必要になります。

> テストケースには読み手がいます。テスト実行者、他のテスト設計者、レビュアー、開発者などです。これらの読み手にテスト内容が伝わるように書かなくてはなりません。さまざまな読み手が理解できるように記述しておかなければ、テストケースとして意味のないものになってしまいます。

## 良いテストケースを書くには、十分にテスト計画する
### 1. ﾃｽﾄ方針（PJの背景、ﾃｽﾄの目的、ﾃｽﾄ対象、対象外のもの、前提と制約）
### 2. ﾃｽﾄ基準（ﾃｽﾄレベル、ﾃｽﾄタイプ、そのﾏｯﾋﾟﾝｸﾞ、ﾃｽﾄ手法、ﾀｽｸ）
### 3. 関係者（ｽﾃｰｸﾎﾙﾀﾞｰ、承認、役割と責任範囲、要員ﾄﾚｰﾆﾝｸﾞ）
### 4. スケジュール（工程、期間）
### 5. ﾃｽﾄ環境（ﾃｽﾄｼｽﾃﾑ構成、ﾃｽﾄﾃﾞｰﾀ、作業場所、適用ﾂｰﾙ）
### 6. 管理基準（管理項目、開始終了基準、一時停止基準、成果物）
### 7. リスクと対策（プロダクト品質観点、プロジェクト遂行観点）

#### 一言で表すと、テスト計画は、テストにおける5W1Hを詳細に洗い出していくプロセスといえるでしょう。

## テスト計画作成の流れ
1．テストに求められる要求を整理
2．実際に行うテストの実行計画を作成
3．テスト段階で必要となる管理項目の整理と管理計画の作成


## 実行計画を作成する際に意識したいポイント
1. 実際のテストはどのような段取りで行うか
2. テストをする際に必要なツールなどはあるか
3. テスト段階の各項目における基準は明確に
4. テストにおける役割や実施場所を設定
5. どのくらいのテスト期間が必要なのかスケジュールの明確化

## テスト段階で必要となる管理項目
1. リスクの管理
2. 作成・記録するデータや文書の管理
3. 進捗管理
4. 機材・ツール・人材の管理
5. 仕様変更等の管理

> テスト計画の骨組は、以下5W1Hに置きかえることができる

– テスト方針の立案→Why
– テスト基準の決定→What
– 要員・体制の決定→Who
– スケジュールの決定→When
– テスト環境・ツールの決定→Where
– 各種管理基準の設定→How

これらをアウトプットしたドキュメントがテスト計画書となる

## 漏れなく、効率よくテストケースを洗い出す方法
1. 同値分割
2. 境界値分析
3. ディシジョンテーブル(決定表)
4. 状態遷移テスト
5. ランダムテスト

# テスト計画を効率よく進める
1. チームメンバー同士での情報共有
2. 観点の目線を変えてみる

# まとめ
管理システムといえば、BacklogやRedmine、Jiraなど、BTSとしても活用できるツールをお使いの方は多いと思う。 
最近では、テスト管理に特化したツールが登場し、BacklogやRedmine、JiraなどのBTSとの連携も可能なクラウド型のサービスもある。 
テスト管理ツールは、テストケース全体を把握できるだけでなく、進捗管理や結果の入力、エビデンスの添付など、システムやソフトウエアのテストに役立つ機能がある。

https://backlog.com/ja/
https://www.redmine.org/
https://www.atlassian.com/ja/software/jira/agile
EP1 プラントシュミレーションって知ってる？



おっと、プラントシュミレーションの世界に飛び込もうとしてるのか？それなら、オレがガイドになってやるよ！今回は、シーメンス製のプラントシュミレーションについて、分かりやすく説明していくぞ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597163/a63c99b6-94e3-1396-da54-054e497c9dbe.png)


### プラントシュミレーションとは？

まずは基本からだ！プラントシュミレーションっていうのは、製造ラインやプラントの動きをコンピュータ上で再現する技術のこと。これを使えば、現実に建てる前に、あらゆる試みができるんだ。

### なんでプラントシュミレーションが大事なのか？

それでは、表を使って、プラントシュミレーションの重要性を見てみよう。

| メリット              | 説明                                                           |
|---------------------|--------------------------------------------------------------|
| 効率的な設計とテスト     | 事前にシミュレーションでテストできるから、時間とお金を節約できるんだ。                |
| リスクの低減          | 事故やトラブルを事前に予測できるから、安全対策がバッチリだ。                       |
| 最適化された運用       | プロセスを改善して、生産性をグンと上げることができるぞ。                           |

### プラントシュミレーションの使い方

- **設計段階での活用**: これから建てるプラントの設計を、シミュレーションで試すことができるんだ。
- **プロセスの最適化**: 現在のプラントをシミュレーションでチェックして、どこを改善すればいいかを見つけ出せる。
- **緊急時のシナリオテスト**: もしもの時のために、シミュレーションで緊急事態を想定して、計画を立てておくことができるぞ。

### プラントシュミレーション、始めようぜ！

1. **目標をハッキリさせる**: 何を改善したいか、目標をしっかり設定しよう。
2. **いいソフトウェアを選ぶ**: シーメンス製のEP1みたいな、目的に合ったソフトを選ぼう。
3. **データを集めてモデルを作る**: 必要なデータを集めて、シミュレーション用のモデルを作成するんだ。
4. **シミュレーションして分析する**: さあ、モデルを使ってシミュレーションを実行！そして、改善点を見つけ出そう。

これで君もプラントシュミレーションの基本をマスターしたぞ！わからないことがあれば、どんどん挑戦して、経験を積んでいくんだ。おっと、何か質問あるかい？



https://www.youtube.com/watch?v=g6Pk8Mm6n3o
AtCoder Beginner Contest 344 振り返り

# ABC344

## 概要

https://atcoder.jp/contests/abc344

## A - Spoiler

**考えてたこと**
結構どうやって解くか悩んだ問題。最初の縦棒を見つけたタイミングでフラグを立てて次の縦棒を見つけタイミングでフラグを降ろす。フラグが立っていて値が縦棒じゃない時にansの変数に追加していくという形で。

**提出したもの**

```c++:a.cpp
int main() {
    string s;
    cin >> s;

    string ans;
    bool judge = true;

    fore(a, s) {
        if (a == '|') {
            judge = !(judge);
        }
        if (judge && a != '|') {
            ans += a;
        }
    }
    cout << ans << endl;
    return 0;
}
```

**振り返り**
解答見てもあまりしっくり来るものがないからこれでも良いかな...。

## B - Delimiter

**考えてたこと**
こういう入力の個数が与えられない問題珍しい気がする...。whileを使って入力を全部受け取って配列に入れる、0の時break。breakされた後に配列をreverseして全部出力。

**提出したもの**

```c++:b.cpp
int main() {
    vector<int> vec;
    while (true) {
        int a;
        cin >> a;

        vec.push_back(a);
        if (a == 0)
            break;
    }
    reverse(vec.begin(), vec.end());
    fore(a, vec) {
        cout << a << endl;
    }
    return 0;
}

```

**振り返り**
特になし。

## C - A+B+C

**考えてたこと**
全探索でいけそう...?ぐらいに考えてたけど他にもやり方を思いつかなかったので全探索で。

**提出したもの**
```c++:c.cpp
int main() {
    vector<int> vec_a, vec_b, vec_c;

    int n;
    cin >> n;
    rep(i, 0, n) {
        int a;
        cin >> a;
        vec_a.push_back(a);
    }

    int m;
    cin >> m;
    rep(i, 0, m) {
        int b;
        cin >> b;
        vec_b.push_back(b);
    }

    int l;
    cin >> l;
    rep(i, 0, l) {
        int c;
        cin >> c;
        vec_c.push_back(c);
    }

    set<ll> set;
    fore(a, vec_a) {
        fore(b, vec_b) {
            fore(c, vec_c) {
                set.insert(a + b + c);
            }
        }
    }

    int q;
    cin >> q;
    rep(i, 0, q) {
        int x;
        cin >> x;
        if (set.count(x)) {
            cout << "Yes" << endl;
        } else {
            cout << "No" << endl;
        }
    }
    return 0;
}
```

**振り返り**
個数がABCそれぞれ100個しかないから全部を足しあわせても10^6, これをq回探索するから計算量がO(q * log(10^6))で足りる。

## D - String Bags

**考えてたこと**
こういう問題dpで解くんだろうなぁとは思いながらもどういうdpを書けばいいか分からず全然解けなかった。

**振り返り**
解説見ながらコードを真似してなんとか解答理解できたレベル...。dpまだ手に馴染んでないからもっと数をこなしたいです。

## 感想
dp勉強してる最中なのに解けなくて残念。もっと鍛錬が必要。
ネットワークを可視化するツールを作ってみた

# はじめに

「グラフ　可視化」で検索すると、折れ線グラフや棒グラフを作る方法ばかりが引っかかって、グラフ理論でいうところのグラフを簡単に可視化するツールを見つけられなかった。多分、探せばあるのだろうがjavascriptの勉強がてら、D3.jsを使って四苦八苦して作ってみた。最低限の機能だが、これだけのコード量で書けることには驚いた。

# できたもの

https://github.com/haru-44/network_visualizer

適切なjsonファイル(あるいはcsvファイル)を与えると次のようにネットワークを描画する。

![img](https://raw.githubusercontent.com/haru-44/network_visualizer/main/README_img/network.png "表示例")

# 機能

- ノードの色を設定する(チェックボックスにより切ることも可能)
- ノードの名前を表示する(チェックボックスで非表示にすることも可能)
- 有向、無向辺の切り替え
- ツールチップによる表示
- 拡大・縮小
- ノードを掴んで移動する

## 今後、改善したい点

- エラー処理とかしてないので、少しでも想定外のファイルを読み込んでもメッセージとかなくて分かりづらい
- エッジの属性によってエッジの太さを変えられると嬉しいか？
画像の動的リサイズ方法を検討した

# 結論

https://www.libvips.org/

速度・省リソースの観点ではこれが良い。

# 背景

10年もののシステムを運用しています。
画像を扱うサービスなのですが、画像ファイルが相当数になって、ファイルサイズの合計が peta byte にとどこうとしています。
ここまでくると、Storageの費用がかなり目立ちます。

画像の表示速度が遅くなることはビジネス要件として許容しにくく、ストレージを低速なものに変えにくいです。

一番量が多い画像の種別は大きさ違いで同じものを扱っている画像でした。
（メインのドメインの画像を大きさごとに物理的に３種類）

なので、
その種別の画像は１枚のみ管理して他の大きさの画像を削除して１種類のみ管理することで、ストレージのディスクサイズを減らすことで費用削減効果が期待できました。
(細かい話は割愛)

１種類のみ管理するために他の大きさの画像は動的に生成することでそれが実現できます。
(他にも色々対策ありそうですが、細かい話は割愛)

つまり、
画像の大きさを動的に生成する必要がありました。

動的リサイズ: https://engineering.mercari.com/blog/entry/2018-01-30-161001/

上記の内容に近いです。
ヘイシャにもwebp変換のニーズがありましたが、一旦スコープアウトとなりました（それを見据えた設計にする）

これや、他のサービスも検討候補に上がりましたが、
弊社の事情があって、自前で用意した方が安くなりそうだったので、自前で用意してみることになりました。

# 画像リサイズのライブラリ比較検証

有名なのは ImageMagick, OpenCVです。
処理速度・省リソースを考慮して検証した結果、libvipsが良さそうです。
https://www.libvips.org/

検討した技術

- Go
  - Go標準ライブラリ
  - GoCV（OpenCVのラッパー）
  - gopkg.in/gographics/imagick.v3/imagick（ImageMagicのラッパー）
  - bimg(vipsのラッパー)
  - govips(vipsのラッパー)
- JavaScript
  - Sharp(vipsのラッパー)
- Python
  - Pillow
  - OpenCV
  - pyvips(vipsのラッパー)
- Java
  - thumbnailator

当初、AWS Lambdaにのせることを検討していたので、
Lambdaで実装して、処理速度と画質を比較検証しました。

どのライブラリもコード（＋Doc）が読みやすいので、実装しやすいです。
色々細かい調整をしてみたのですが、
省メモリ環境を考慮していたので、bimgが最も性能良い（最も早く、画質も圧縮もいい感じ）という結論になりました。

一応、サービスインできそうな形にはできたものの、
AWSLambdaの最低メモリ割り当て数 128MB では、サービス運用に支障が出そうでした。
メモリ割り当てを調整した結果、1500MB くらい割り当てすることが好ましいという結果になりました。

# アーキテクチャ検討

当初、AWSのCloudFront＋S3ObjectLambdaの利用が候補に上がっていました。
しかし、ヘイシャではKubernetesでサービスを運用していて、コンピュートリソースが余っていたので、
コンテナ上で動的リサイズするとどうなるのか、という検証を行うことになりました。

サーバ立てて動的リサイズを行う方法で以下を検証しました

- Nginxでリサイズ（image filter module）
- imgproxy (vipsを利用してhttpで画像をリサイズするアプリケーション)
  - https://imgproxy.net/

どちらもドキュメントが充実していてシンプルなので実装しやすいです。

コンピュートリソースを潤沢に使えるのであれば、
imgproxy　を利用するのが、楽で、処理速度も早く、色々な処理ができます。


結果的には以下のアーキテクチャが良さそうという結論になりました

CDN -> AppServer(Kubernetes上でimgproxyのコンテナ)

画像周りのリクエストはかなり多くなると思われるので、
LB分けておいた方が被害少なくなる＋監視しやすくなるでしょう。

切り替えはDNSの重みづけで徐々に流していくことができますし、
やっぱり自前で立てておくほうが良いなーと思ってます。

サービスインはこれから。
一旦覚えているうちにアウトプット。

技術検証させてくれるチームと会社に感謝
viewportに入った時にイケてる演出できるコンポーネント

## 概要

viewportに入った時だけアニメーションを適用してほしくて
vueの[transition](https://ja.vuejs.org/guide/built-ins/transition)のwrapperコンポーネントを作成した。

viewportに入った時とでた時に演出を持たせられるコンポーネント

## 出来上がったもの
https://twitter.com/SphereVR/status/1770356585497591891


## ちょっとつまったところ
slotで受けとったものがisVisibleの値を参照しfalseのときは`v-if`によってdomからいなくなるため高さが亡くなってしまうので
isVisibleを監視してtrueになった時だけ親要素の高さをへんこうするようにした。

https://twitter.com/SphereVR/status/1770361367842959804

## 改善点
- IntersectionObserverのoptionは親からpropsで受け取るようにするともっといろんなパターンで使えるかも


## コンポーネントソース
``` vue
<script setup>
import { ref, onMounted, watch } from 'vue'

const isVisible = ref(false)
const containerRef = ref(null)

onMounted(() => {
  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      isVisible.value = entry.isIntersecting
    })
  }, {
    threshold: 0.5
  })

  watch([containerRef], ([newContainerRef]) => {
    if (newContainerRef) observer.observe(newContainerRef)
  }, { immediate: true })
})
watch(isVisible, async (newVal) => {
  if (newVal) {
    await nextTick()
    let contentHeight = 0
    for (const child of containerRef.value.children) {
      contentHeight += child.offsetHeight
    }
    containerRef.value.style.height = `${contentHeight}px`
  }
})
</script>

<template>
  <div ref="containerRef">
    <span></span>
    <transition v-bind="$attrs">
      <slot v-if="isVisible"></slot>
    </transition>
  </div>
</template>

```



### 使い方
例1 四角のが横から回りながら出現
```
<TransitionInViewportObserver
class="absolute bottom-2 right-5 h-32 w-32"
enter-active-class="transition-all duration-1000 rotate-90"
leave-active-class="transition-all duration-1000"
enter-from-class="-translate-x-20 opacity-0 rotate-90"
leave-to-class="opacity-0">
<div class=" rotate-12 bg-sky-200/10"></div>
</TransitionInViewportObserver>
```

例2 左右からslideしながら出現
```
<TransitionInViewportObserver
  v-for="(feature, index) in featureBanners"
  :key="feature.title"
  class="h-52"
  enter-active-class="transition-all duration-1000"
  leave-active-class="transition-all duration-1000"
  :enter-from-class="index % 2 === 0 ? 'translate-x-20 opacity-0' : '-translate-x-20 opacity-0'"
  leave-to-class="opacity-0">
  <div class="bg-base-300 p-4 ">
    {{ feature.title }}
    {{ feature.description }}
  </div>
</TransitionInViewportObserver>
```

例3 下からslideしながら出現
```
<TransitionInViewportObserver
  enter-active-class="transition-all duration-1000"
  leave-active-class="transition-all duration-1000"
  enter-from-class="translate-y-20 opacity-0"
  leave-to-class="opacity-0">
  <div class="chat chat-start">
    <div class="avatar chat-image">
      <div class="w-10 rounded-full">
        <img alt="profile" :src="feedback.profile_photo">
      </div>
    </div>
    <div class="chat-bubble">
      {{ feedback.description }}
    </div>
  </div>
</TransitionInViewportObserver>
```