OmniAICreator/Qiita-1.07M huggingface dataset:
VAST形式で静止画を配信したい。

:::note warn
この記事は、[Supershipグループ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/supership)の 22日目の記事になります。
:::

Supership株式会社の @hosomin0211 です。
普段はデータソリューション領域で、ECサイト向けの広告配信プロダクトや[Supership Touch Gift](https://supership.jp/business/touchgift/)の開発を行っています。

## はじめに
VAST形式を使用して動画広告を配信する中、通信環境が悪く、動画広告が再生できない場合に容量の少ない静止画を配信すれば良いのではと考えました。
そこで、静止画広告表示用の実装を入れずにVAST形式でまとめて一括で再生できるようにする方が効率的ではないかと考え調査したので、本記事にまとめます。

## 検討した方法
VAST形式で静止画を配信するに当たり、以下3つの方法を検討しました。
- CompanionAdsタグに静止画を入れる
- NonLinearタグで静止画を表示する
- 静止画を動画に変換して、動画として表示する

### CompanionAdsタグで静止画を入れる
初めに、CompanionAdsタグに静止画を入れれば良いのでないかと考えました。
コンパニオン広告とは、動画広告といっしょに配信される広告であり、動画サイト等で動画の横等に表示されている広告になります。
https://support.google.com/admanager/answer/1191131?hl=ja

エンドカードの用に使われることもあるため、動画広告を抜いてエンドカードのみを表示するようにすればそのまま表示できるのでは？と考えました。

しかし、この方式の場合には、配信APIを導入頂く側のアプリに別途実装が必要になることが分かり断念しました。
コンパニオン広告は通常、動画外に表示される広告なため、google imaのようなvast playerとは別に別途xmlを解析して画面上に表示して頂く必要がありました。

### NonLinearAdsタグで静止画を表示する
次に、NonLinearタグを用いて静止画を表示すれば良いのではと考えました。
NonLinearタグは、オーバーレイ広告と呼ばれる再生中の動画の上に表示される静止画の広告を設定するためのタグです。
動画広告枠ピッタリのサイズでオーバーレイ広告を出せばvast playerで読み込むだけで静止画広告を表示できるのでは？と考え、google imaのテスト環境で再生した際には綺麗に表示されました。

しかし、結果的にこの方式は断念しました。
理由としては、google imaのSDKがiOSとAndroid用共にNonLinearタグに対応していないことが発覚したためです。
https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/compatibility?hl=ja

Web上で綺麗に表示されていたにもかかわらず、iOSでテストした際に表示されず、がっかりした記憶があります。
先に導入先のiOS, Androidへの互換性を調べておくべきでした。


### 静止画を動画に変換して、動画として表示する
最後に、一番シンプルな形ですが、静止画を動画に変換して入稿すれば良いのではと考えました。
vast playerで再生する際は動画として再生するので、当たり前ですが問題なく表示できました。

しかし、動画に変換すると容量が大きくなってしまい、通信環境が悪い状態では表示できなくなってしまいます。
また、mp3やpngから動画に変換するとどうしても色味が変わってしまい、元のデザインを維持することができませんでした。
（Finalcutが一番綺麗に変換できていました。）

容量の問題に関しては1fpsの動画を作成することで、画像と同等サイズに抑えることができましたが、色味の問題は要検討です。



## おわりに
VAST形式で静止画を配信する方法を検討しましたが、最終的に静止画を動画に変換する方式を選択しました。
動画広告用のフォーマットで静止画のまま再生させることは難しいと感じ、断念しました。
動画でも静止画でもまとめて配信できるようなフォーマットがあれば良いなと思い日々調べてます。

:::note
**最後に宣伝です。**

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
[Supership 採用サイト](https://supership.jp/recruit/)
是非ともよろしくお願いします。
:::
CLI 操作前にzshプロンプトをいじろう

この記事は [Wano Group Advent Calendar 2024](https://qiita.com/advent-calendar/2024/wano-group) の20日目の記事となります。
昨日の[goose で DB マイグレーションを行う](https://qiita.com/_kobacky/items/1d0ff11e4876264524e5) には自分も助けられました。
今日もこの記事で誰かが助けられるといいなと思います。

# ネタバレ
- CLI操作時にカレントディレクトリや時間・ブランチ・編集ファイルがわからないと不便じゃないですか？それを解決します。
- コピーしてそのまま使っちゃってください

# エピソードトーク
入社直後の自分のターミナルは以下のようなものでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/19dfaa48-a732-f1c9-68d6-b0ed6e7a03b9.png)
※プライバシーにかかわる部分は削除しています

黒くて格好がいいですよね。
しかし、私の逆タブラ・ラサ画面を目にした上司はこのように口走っていました。
:robot: 「見づらいんじゃない？？zshプロンプトをカスタマイズしてきれいにしたらいいよ」
:dog2: 「？？？？？」

ということでCLIのデフォルト表示をきれいにすることにしました。これが創世記です。

## 結果

### Gitを使っていないディレクトリにいる場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/cdaf7067-afad-a89a-70fe-cc13436fd1a4.png)
カレントディレクトリが表示されていますね。
色分けするだけでだいぶ視認性が上がります。

### Gitを使っているディレクトリにいる場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/6c4faa73-7365-753e-59bf-3720512cba2b.png)
ローカルの編集なし。ブランチ名が表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/870da297-1201-56a9-8640-ae7ded321d8b.png)
ローカルの編集がある場合は、黄色の `+` を表示しつつブランチ名を黄色で表示するようにしています。
**この文字色の変更でcommit忘れを幾度となく防ぐことに成功しました。本当に感謝**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/26a3d729-85e3-c0cb-97d1-9023aa87c7cf.png)
変更があり、その一部が `git add` されている場合、赤色の :exclamation:と黄色の `+` を表示しつつブランチ名が黄色になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475741/4f4bc979-1767-6567-dc0d-3e9d33f6cd72.png)
変更があり、そのすべてが `git add` されている場合、赤色の :exclamation: を表示しつつブランチ名が赤色になります。



## なにを実施したんですか？

`~/.zshrc` に以下の設定を加え、 `source ~/.zshrc` を実行しました。

```bash
# git

# vcs_infoモジュールをロードし、プロンプト内ので変数やコマンドの置換を有効化
autoload -Uz vcs_info
setopt prompt_subst

# Gitリポジトリの変更をチェック
zstyle ':vcs_info:git:*' check-for-changes true

# gitリポジトリ内の変更を検知
zstyle ':vcs_info:git:*' stagedstr "%F{magenta}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{yellow}+"

# ブランチ名表示
zstyle ':vcs_info:*' formats "%F{cyan}%c%u[%b]%f"
# アクションがある場合はそれも表示
zstyle ':vcs_info:*' actionformats '[%b|%a]'
precmd () { vcs_info }

# 表示設定
# hh:mm:ss
# ユーザー名@ホスト名[カレントディレクトリ絶対パス]gitブランチ名
# $
PROMPT='
%*
%F{magenta}%B%n%b%f@%F{blue}%U%m%u%f[%F{green}%~%f]%F{cyan}$vcs_info_msg_0_%f 
%F{yellow}$%f '
```

以上となります。
「この設定をいじってもっと見やすいようにしたったｗｗｗ」などコメントをいただけると嬉しいです。

この記事で、より多くの魂が救われることをここで祈り続けています。

***  
TuneCore Japan では 一緒に働くメンバーを募集しています。
エンジニアだけでなく、Director等の各種ポジションをオープンしているので興味がわいた方はぜひご覧ください！


https://www.tunecore.co.jp/jobs

***

# 参考記事
https://ktksq.hatenablog.com/entry/mac-customize
https://webrandum.net/zsh-prompt-name/
https://tkengo.github.io/blog/2013/05/12/zsh-vcs-info/
ZOZOTOWNのパーソナライズ枠改善：検索結果面への遷移導線追加による効果検証



## はじめに

こんにちは。推薦基盤の関口です。

本記事では、ZOZOTOWN HOME面のパーソナライズ枠から検索結果面に遷移を可能にした取り組みについてまとめたいと思います。

一般的に、ECサイトにおいて回遊率の向上は、ユーザーの購買意欲を高め、最終的な購入率の向上につながると言われています。今回の改善を通じてどのような結果になったのかをご紹介します。

## パーソナライズ枠とは

ZOZOTOWNのHOME画面は、「モジュール」と呼ばれる単位で商品が表示されるようになっています。

モジュールは以下の4つに大別されます。

|モジュール名|	説明|
|---|---|
|導線モジュール|閲覧した商品を軸としたリターゲティング系モジュール|
|企画モジュール|トレンド商品や企画商品など企画チームが考案したモジュール|
|広告モジュール|広告商品用モジュール　|
|レコメンドモジュール|ユーザーごとにパーソナライズされたモジュール|

今回は、これらのモジュールの中でも特にユーザーの購買行動に大きな影響を与えるレコメンドモジュールの改善についてお話しします。レコメンドモジュールは、ユーザーの閲覧履歴や購買履歴に基づいて、一人ひとりに最適化された商品を提案するもので、HOME面の中でも特に重要な役割を担っています。

この記事では、複数種類あるレコメンドモジュールをまとめてパーソナライズ枠と呼称します。パーソナライズ枠はHOME面でも売上影響の大きい部分になるため、以下の施策を実施する運びとなりました。

## 施策

レコメンドモジュール以外の商品訴求するモジュールでは基本的に「すべて見る」リンクが設置されており検索結果面に遷移することができます。これにより、より多くの商品を閲覧することができ、サイト内回遊を促すことができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997599/3008030f-9949-ac41-0627-1a9bd7d6c1ca.png)

しかし、システム上の都合により、これまでレコメンドモジュールには「すべて見る」リンクを設置することができない状態でした。そこで今回、この課題を解決し、レコメンドモジュールにも検索結果面への遷移リンクを実装する運びとなりました。

## 導入後の結果

様々な開発チームに助けられ、まずはWEB版に先行して遷移リンクの設置をリリースしました。この変更による効果検証のため、ABテストを実施しました。今回の指標は、日頃から定常的にモニタリングしている指標を活用しています。


|指標|t/c比率|
|---|---|
|HOME面訪問者1人あたり受注金額（KGI）|101.2%|
|モジュール閲覧者1人あたりモジュール閲覧コンテンツ数（KPI）|97.9%|
|モジュール閲覧者1人あたりモジュールクリック数（ヘッダー+コンテンツ）（KPI）|100.3%|

#### 結果の考察
上記のABテストの結果から、以下のことが読み取れます。

1. **HOME面訪問者1人あたり受注金額**
101.2%と有意差ありで向上しており、施策が売上にポジティブな影響を与えたことが示唆されます。（ただし、集計の都合上、施策とは無関係に偶然生じたアップリフトが含まれている可能性もある点に注意しなければなりません。）

2. **モジュール閲覧者1人あたりモジュール閲覧コンテンツ数**
97.9%と低下しました。これは、ユーザーがパーソナライズ枠から直接検索結果面へ遷移するようになった結果、モジュール内の商品を閲覧する回数が減少したことによるものです。この現象は施策の意図に沿ったものであり、問題ないと判断しています。

3. **モジュール閲覧者1人あたりモジュールクリック数**
100.3%とほぼ変化がなく、モジュール内のクリック数には施策前後で大きな変化が見られませんでした。これは、施策による影響が限定的であったと考えています。

総じて、今回の施策は売上に対するポジティブな影響が確認された一方で、ユーザー行動の変化が施策の意図に沿ったものであることが裏付けられました。

### まとめと今後
この結果から、今回の施策ではサイト全体の回遊性の向上にはさらなる課題が残るものの、ユーザーが効率的に商品を見つけられるようになり、売上の向上に寄与した可能性が高いと考えられます。今後は、影響が大きいAPPへのリリースも完了したため、引き続き効果検証を進めていきます。ZOZOTOWN HOME面の改善を通して愛されるZOZOTOWNを目指します。


# 最後に
みなさま良いお年を。ZOZOTOWNの初売りセールが楽しみ!!
何となくでコーディングすることの危険性

# はじめに
初めまして！株式会社LITALICOの @matchyarn と申します！
2年半ほどQAの業務を行っていて、今年の7月からほぼ未経験ですが開発の業務に携わっております。
現在、私が所属しているチームは主にモブプロで実装を進めているのですが、自分が何となくでコーディングしてしまう時があり、「何故そのコードを書きましたか？」とご指摘を受けることが多々あります。これは何が原因でどう改善すればいいかを自分なりにまとめてみました！

# なぜ何となくでコーディングしてしまうのか
一言で言うと、書いたコードに根拠が伴っていないからです！何をすれば良いかしっかり理解していないから、根拠なくとりあえずそれっぽいコードを書いてしまう…。下手な鉄砲も数打ちゃ当たるみたいなもので、たまに正解を引けますが、理解していなければまた同じミスをしてしまうので本質的な解決にはなっていません。

# 何となくでコーディングすることの危険性
仕事をする上で非常に危険です！特にチームで仕事をする傾向が強ければ強いほど危険度は高くなると思います。なぜなら、仕事は少なからず他の方と協力して進めていくものなので、全体である程度の認識を揃えないといけないからです。考えなしで進めるとチームの方たちと認識が合わなくなり、自分が今何をやっているのか分からなくなっちゃいます。
これでは自分が苦しくなるし、チームの方たちに不安を与え、認識合わせの労力が発生したりします。結果として作業がスムーズにいかなくなってしまいます。

# 改善するには
行動と根拠はセットにする！これを意識して、チーム・自分が今何をしたいのか、何故それをしているのか認識を合わせるようにしていきましょう！
実装の前にissueやPRを読み、やることを書き出して情報を整理し、何をするのか理解しておけば、チームとの認識は合いやすくなります！

# おわりに
今回はコーディングの観点で行動には根拠を持った方が良いと書きました！しかし、これはコーディング以外のことでも大切なことだと思います。
行動に根拠が無いと、自分のやったことが後で問題になって誰かに聞かれた場合、「分かりません」「知りません」と答えることになります。これは非常に無責任ですよね？
根拠を持つということは責任を持つことと同じようなものかもしれません。自分のやっていることにしっかり根拠を持ち、積極的にチームと認識を合わせ、スムーズにコーディングしていきましょう！
【完全保存版】もし私が今からエンジニアを目指すなら取る資格3選

## はじめに

[Udemyおすすめ講座をシェアしよう！ by Udemy Advent Calendar 2024](https://qiita.com/advent-calendar/2024/udemy)の20日目の記事になります。

今回は「もし、私が今からエンジニアになるなら」を想定して、どの資格を取ってエンジニアとしてのキャリアをスタートするかお話したいと思います。

## 目指したいエンジニア
まず初めに、ざっくりとしたキャリアパスを考えた時

**インフラエンジニアとしてスタート→クラウドエンジニアにキャリアチェンジ**

この道筋をたどっていきたいと思います。いきなりクラウドエンジニアになるのは、新卒以外ではかなり難しいので、インフラエンジニアからスタートします。

「Web系に行って自分でコンテンツを作りたい！！」と考える人は多いですけど、**実は基盤系やインフラなどの裏方の方が堅実に稼げる**、というのが周囲のエンジニアを見渡して出した私の持論です。

デザイン系、Web系やって稼いでいる人は目立つんですけど、**稼いでいるエンジニアの割合でいうと、全体の1%くらい**ではないでしょうか。

基盤系は**自ら進んでなった人はほぼおらず、みんな偶然なってしまった人ですが、結果的に稼げるようになった人達**です。

この基盤系のポジションを積極的に取りに行きたいと思います。

## 取るべき資格
インフラエンジニアとして現場に入るため、以下の3つに絞って取得を目指します。

- LPIC/Linuc
- CCNA
- アソシエイトレベルのクラウド資格

順番に見ていきます。

### LPIC・LinuC
インフラエンジニアになりたいなら、Linuxの操作ができることは必須条件です。頻出の基本的なコマンドは丸暗記するレベルまで頭に叩き込みましょう。受験するのはレベル1で十分です。

LPIC・LinuC対策の講座はUdemyに山のようにありますが、以下のような実際に手を動かして覚えることができる講座を選びましょう。

特に、[【5日でできる】はじめての Linux 入門（LPIC Level1対応）](https://www.udemy.com/course/5dayslinux/)は仮想環境（VirtualBox）へのLinuxのインストールから説明してくれているので、初心者におすすめです。

**オススメ講座**

https://www.udemy.com/course/5dayslinux/

https://www.udemy.com/course/linuc-lv1/

### CCNA
疎かにされがちですが、ネットワークの知識は現場で非常に役立ちます。私も何度となく、CCNA・CCNPで得た知識に救われてきました。

CCNPはネットワークエンジニアを目指さない限りはオーバースペックなので、エンジニアになりたてであれば、初心者向けのCCNAで抑えておきましょう。

**CCNAの対策にはCiscoが公式で公開しているPacket Tracerを利用してください**。これはPC上でスイッチやルーターなどのコンフィグ設定ができるシミュレーターになります。

ぶっちゃけ講座を受けるだけでも合格できるくらいCCNAは易しい試験ですが、**得られた知識を血肉とするためにはPacket Tracer利用を推奨します**。入手方法は[コチラ](https://www.infraexpert.com/info/packettracer02.html)にあります。

**オススメ講座**

https://www.udemy.com/course/ccna-full/

https://www.udemy.com/course/ccna2024/

### アソシエイトレベルのクラウド資格
インフラエンジニアからクラウドエンジニアへジョブチェンジするための準備をしておきます。

やはり、クラウドはアツいです。今のところ、クラウドエンジニアの需要が下がることはないでしょう。アソシエイトレベルは、前段2つの資格に合格して、基礎的な知識が身についていれば難なく合格できる試験になっています。

クラウド資格だけは、入門レベルではなく、中級者向けのアソシエイトレベルまで受けましょう。例えば、AWSであればクラウドプラクティショナーではなく、ソリューションアーキテクトアソシエイツまで受けます。AzureであればAZ-900ではなく、AZ-104まで取得することが望ましいです。

なぜかというと、**入門レベルの資格ではそこまで実務の役に立たない**からです。あれはリソースの名前を知っているか、程度の知識が問われる、いわばクイズのような試験です。実務レベルで活用できるスキルを手に入れるためには、今一つ物足りなません。

クラウドも実際に手を動かしてナンボなので、サブスクリプションの契約をして実際にリソースをデプロイして知見を深めましょう。

**オススメ講座**

https://www.udemy.com/course/aws-associate/

https://www.udemy.com/course/azure-az104-learn/

いきなりインフラや基盤系を目指す人は限りなくゼロで、アプリやWebと比べて競合も少ないので超オススメです。

ここまで読んでいただきありがとうございました。

Xではエンジニアに有益な発信をしていますので、ぜひフォローよろしくお願いします！！

https://twitter.com/satan_engineer
letta（旧memGPT）をローカルLLM（Ollama）で動かしたけどまだまだ使い物にならなかった話

## 趣旨
Ubuntu 22.04環境でコンテナ版Lettaを動かすことに成功したので、備忘録として手順や注意点を記載します。

## 前提条件
本記事は以下の環境および前提を想定しています。

- **OS**: Ubuntu 22.04  
- **Ollama**: 既にインストール済み  
- **LLM**: Ollamaに任意のLLMをpull済み  
- **Docker**: 使用可能な状態  

必要に応じてこれらの環境を事前に構築してください。

## 導入と起動
Lettaの公式ドキュメントは以下の2つが参考になりますが、非常に分かりづらいため、結論だけをまとめました。

https://docs.letta.com/server/docker

https://docs.letta.com/models/ollama

以下のコマンドを実行してください。

```bash
docker run \
  -v /[ローカルホスト側の任意のパス]/letta:/var/lib/postgresql/data \
  -p 8283:8283 \
  -e OLLAMA_BASE_URL=http://[自ホストのIPアドレス]:11434 \
  letta/letta:latest
```

### ポイント
1. **OLLAMA_BASE_URLの設定**  
   - ベースURLは`localhost`や`127.0.0.1`ではなく、**自ホストのIPアドレス**（例: `192.168.1.10`）を指定してください。  
   - Lettaはコンテナ内で動作しているため、`localhost`や`127.0.0.1`を指定すると、コンテナ内部の自分自身を参照してしまいます。

2. **UFWの設定**  
   - Ubuntuのファイアウォール(UFW)でポート`11434`への接続を許可する必要があります。Dockerコンテナはデフォルトで`docker0`インターフェースを使用して通信します。この通信はUbuntuホストから見ると「外部からの通信」として扱われるため、UFWでブロックされ、見かけ上は原因不明のトラブルになります（letta側がエラーとか出さずに無言で疎通に失敗するため、そもそもOllamaと通信できてない、ということすら中々気づけない）

上記の設定により、`http://localhost:8283`でLettaの画面を開き、またエージェント作成画面でOllama上にpull済みの各種LLMを参照することができます。

## 現状の制約と問題点

### 日本語テキストのEmbeddingが機能しない
2024年12月20日時点のコンテナ版Lettaでは（もしかするとpip版も）日本語テキストのEmbeddingに問題があり、かつデータソースの作成にも不具合が生じています。

### データソースの作成
以下のように`curl`を使用してAPIを直接叩くことでデータソースを作成可能です。
GUI上にあるデータソース作成ボタンは実行してもエラーになって何も作成できません。

```bash
curl --request POST \
  --url http://localhost:8283/v1/sources/ \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "test-datasource",
  "embedding_config": {
    "embedding_endpoint_type": "ollama",
    "embedding_endpoint": "http://[自ホストのIPアドレス]:11434",
    "embedding_model": "nomic-embed-text:latest",
    "embedding_dim": 768,
    "embedding_chunk_size": 300
  },
  "description": "test",
  "metadata_": {}
}'
```

参考: https://docs.letta.com/api-reference/sources/create-source

### データソースへのファイルアップロード
作成したデータソースに対してはGUI上でファイルをアップロードすることができます。
しかし、50MB規模の英語PDFの処理に失敗するケースがありました。これは以下に起因しているのかもしれないし、していないのかもしれません。

- 使用しているEmbeddingモデルの限界
- GPUやPCの性能不足  
（ただし、VRAMにEmbeddingモデルをロードしようとする挙動すら見られないため、個人的には別のところに原因があるような気がします）

## データソースを活用した質疑応答
現状、データソース内の文章を参照した質疑応答は機能していません。

### 問題の原因の推測
以下の要因が関連していると考えられます。

1. プロンプトが日本語である  
2. データソース内のテキストも日本語である  
3. 内部のRAG検索用プロンプトが英語で記述されている  

まあこの辺が原因なのかは定かではないものの、うまく知識を検索できていない以上、letta本来の売りである「過去の会話履歴を記憶として保持＆想起する機能」が日本語環境では正常に動作しない可能性があります。

## 終わりに
lettaの売りである「擬似的に無制限のコンテキスト長を実現」「ファイルアップロードも可能なのでこれまた擬似的に無制限のデータサイズでのRAGを実現」といったコンセプトに夢を見たものの、見事に夢破れました。

ただまあ、結局lettaがデータソースとして登録したファイルの扱いは、単純なRAGに過ぎなかったので仮に動作したとしても「長大なテキストを苦もなく把握！」みたいな挙動にはならなそうな気がします。将来に期待、といったところでしょうか。

※データソースにPDF文書を登録し、エージェント側に接続してからArchived Memoryの項目で中身を表示してみた様子。
　いかにも単純にベクトルDBにチャンク化した細切れのテキストを格納した様子が見て取れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179750/bb578b10-1de3-8348-d08e-0a64749d46b9.png)
GCSとGemini APIをつかってみる

# はじめに
先日の記事では、`Gemini API`を利用した画像処理について取り扱いました。しかし、その中の、「`File API`を用いた画像のアップロード」の部分を私の勉強不足のせいで触れることができなかったので、今回はまず始めに`GCS（Google Cloud Storage）`の概要などについて軽く触れた後に実際に使ってみようと思います。

では、始めていきます。

# GCS（Google Cloud Storage）とは？
### 概要
`GCS`は、構造化されていないデータを保存するためのマネージドサービスで、名前の通り`Google`が提供しています。
保存できるデータの量に制限はなく、保存したデータを必要に応じて何度でも取得できます。

:::note info
「構造化されていないデータ」とはその名の通り構造定義されていないデータのことを表します。一定の組織化された原則を持たないため、データベース化できず、検索や集計、解析に不向きです。
具体的には、画像・音声ファイルや文書ファイルなどが該当します。
:::

### 使い方（初回）
まずは、以下のページに行き、Googleアカウントでログインした後、ページ右上の「無料で利用開始」に進みます。

https://cloud.google.com/storage/docs/apis?hl=ja

次にユーザー情報と支払い用のクレジットカードの情報を入力します。

:::note warn
File APiの利用にあたって、以下のように公式から説明があります。
> File API では、プロジェクトごとに最大 20 GB のファイルを保存できます。ファイルあたりの最大サイズは 2 GB です。ファイルは 48 時間保存されます。この期間中は API キーを使用してアクセスできますが、API からダウンロードすることはできません。Gemini API を利用できるすべてのリージョンで、追加料金なしでご利用いただけます。
:::

登録が終わったら、`Google Cloud Console`にアクセスし、左側メニューから「ストレージ」、「バケット」と進んでいき、バケットを作成します。

バケットにはオリジナルの名前をつけることが可能ですが、グローバルに一意（他人とかぶってはいけない）などの規則があります。詳しくは以下のページを参照してください。

https://cloud.google.com/storage/docs/buckets?hl=ja#naming

また、バケット作成時にリージョン（データを保存する物理的な場所）やストレージクラス（保存タイプ）などを選択します。これは各自の必要に応じて選択してください。
今回、私はデフォルトの設定のまま進みました。

最後に、作成したバケットのページから任意のファイルなどをアップロードします。

これでアップロードは完了しました。

# つかってみる
今回は冒頭で述べたように`Gemini API`に、`GCS`でアップロードしたファイルを読み込ませていきます。なお、用いたファイルは前回に引き続いて以下のスクリーンショットです。

![スクリーンショット 2024-11-13 155312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817741/f30b9b33-b298-b437-c7c1-f2175ed8611b.png)

:::note info
本来、この方法は`Gemini API`にアップロードするファイルのサイズが大きい（20Mb以上）の場合に用いる手段であるので、今回のように小さなデータの場合はこの方法を採用する必要はありません。
:::

実行の前に、`Gemini API`が画像を参照できるようにするため、バケットから「権限」のページに移り、公開アクセスを許可しておきます。そして、「プリンシパルの追加」から`allUsers`を入力します。

これで、準備は一通り完了したと思います。では、コードを書いていきましょう。

```python:example.py
import google.generativeai as genai

genai.configure(api_key="(ここにAPIキーを入力)")

image_url = f"https://storage.googleapis.com/(作成したバケット名)/(アップロードしたファイル名)"

model = genai.GenerativeModel("gemini-1.5-flash")

prompt = "この画像の内容を詳しく説明してください。"
response = model.generate_content([image_url, "\n\n", prompt])

print(f"Result: {response.text}")
```

すると、以下のように返ってきました。

> Result: 画像には、スマートフォン画面と思われるものが写っており、日本語で書かれた複数のメッセージが表示されています。メッセ ージの内容は特定できませんが、会話の一部であると推測されます。画面上部には時刻表示のようなものも確認できます。

ここで、レスポンスは来るのにその内容があまり適切でない場合は先ほど紹介した画像の公開設定などに問題があると考えられます。

# おわりに
今回は`GCS`と`Gemini API`を用いて画像処理を行ってみました。
何回もつまづきながらの実行だったので、もしかすると誤った情報も含まれているかもしれません。その点は申し訳ないです。

あと、感じたのはレスポンスの内容が間違ってはないが直接画像をアップロードしたときの方が精度が高かったということです。途中で述べたようにこれは大容量ファイルを用いる際の方法なのでなんとなくデータ不足？によるものかなと思いましたが、これまた確証です。余裕があるときに調べてみようと思います。

では、今回の記事はこれで終わりです。最後までお読みいただきありがとうございました。

# 参考
https://cloud.google.com/storage?hl=ja

https://solution.toppan.co.jp/bx/contents/cdp_contents07_0831.html

https://ai.google.dev/gemini-api/docs/vision?hl=ja&lang=python
マイコンでLEDライトを制御

100VのライトはリレーやSSRで制御ができます。

12Vや5Vのライトは[リレーで制御](https://qiita.com/yamori813/items/362327ad1281de99a7a0)できます。回路は複雑になりますがトランジスターやFETで制御する事もできます。

部品販売で取り扱いしてるところはあまり見かけませんが、USBのPower制御素子を使う方法がお手軽だと思います。5V限定にはなりますが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/260d7e22-25b2-83e4-e829-5857b97e9e0c.png)

このチップは1.5Aまで流せます。

製品はたくさんあり、USBハブやUSBホストのモジュールに入っていることがあります。

![20241220165954539 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a336e75f-8d16-7917-11cd-e6d8a33635ad.jpeg)
Pythonでスクレイピングを始めるならこれ！ライブラリの選び方と使い分け


## はじめに

皆さん、Webページの情報を自動で取得したり、ブラウザ操作を自動化したい、と思ったことはないでしょうか。  

Webページから必要な情報を自動的に取得する手法を『スクレイピング』と呼びます。  
スクレイピングは、データ収集や業務の効率化に役立つ便利な技術です。  

私自身Pythonをよく使用しており、Pythonでのスクレイピングをすることがあるのですが、Pythonライブラリ「Playwright」を使う機会があり、これまでは他のライブラリである「BeautifulSoup」や「Selenium」を使用していたので、何が違うのか、それぞれ何ができるのか、というのが気になりまとめてみました。  


## スクレイピングの例

### ① Webページ上のHTML情報の取得
HTMLに埋め込まれているテキストの情報や、表のデータを取得できます。

以下の画像は、体重と体脂肪率を記録したWebページの例です。このような表形式のデータをスクレイピングで取得し、分析や保存に活用できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867584/9e03906e-879c-0417-a013-9bf8d1c556f3.png" alt="テキスト、表データ" width="95%">


### ② ブラウザ操作
一部のWebページでは、目的のデータを表示するためにユーザー操作が必要な場合があります。 
ログインが必要なページがその一例です。

以下の画像は、ログイン画面の例です。このようなページでは、スクレイピングを行う前に自動的にログイン操作を行い、ログイン後のページからデータを取得することができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867584/b4ce7407-999c-a7b8-7462-248e08f92195.png" alt="ログイン画面" width="65%">


## スクレイピング用ライブラリ比較

スクレイピングでは主に先述の2つのことができるのですが、やりたいことによって使うべきライブラリが異なります。  
Pythonでのスクレイピングのライブラリを3つ取り上げますが、それぞれの特徴は下表の通りです。


![pic04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867584/99a3564d-a425-20af-ded0-2f303e130f02.png)

## スクレイピング用ライブラリの使い分け

### ① Webページ上のHTML情報の取得
基本的には、静的WebページのHTMLを取得するだけであれば「BeautifulSoup」が最適です。
「BeautifulSoup」はURLからHTML情報を直接取得するため、動作が軽量で高速です。 

例えば、ニュースサイトやブログのように、ページロード時にすべてのデータがHTMLに含まれている場合に適しています。

「Selenium」や「Playwright」は実際にブラウザを起動して画面を表示させてからHTMLを取得するため、HTMLのみを取得する場合には余分なリソースを消費し、動作が遅くなることがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867584/6effd07f-e05d-f0e4-f636-f5ee82659aea.png" alt="ライブラリによるhtml取得方法の違い" width="90%">

しかし、「BeautifulSoup」では外部ファイルの（HTMLに埋め込まれていないJavaScriptファイルや、ページ読込後に動的に生成される要素）を取得することができません。  
そのため、ページによっては取得したい情報が欠落してしまう可能性があります。

このような場合は、「Selenium」や「Playwright」を使用することで、動的に生成されたデータも取得することができます。

  
  
また、ログインが必要なページでは、「BeautifulSoup」だけではデータを取得できません。  
なぜなら、URLにアクセスしてもログインページにリダイレクトされてしまうためです。ログインページのデータが取得されてしまいます。
このような場合も、「Selenium」や「Playwright」を使用することで、ログイン操作を自動化し、必要なデータを取得することが可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867584/3562d2e1-4ab8-8df6-c506-7ca4f013ae35.png" alt="ログインページがあるブラウザへのアクセス" width="90%">



### ② ブラウザ操作
ブラウザ操作が必要な場合、基本的にJavaScriptが関与していることが多いため、「BeautifulSoup」では操作を行うことができません。
例えば、ボタンのクリックやフォームへの入力、ページのスクロールなど、Webページ上でのユーザー操作をシミュレートする必要がある場合は、「Selenium」や「Playwright」を使用する必要があります。

「Selenium」や「Playwright」は、JavaScriptで生成される動的コンテンツを取得できるだけでなく、ユーザー操作を完全にシミュレートできるため、ログインや複雑な操作が必要なシナリオでも活躍します。  
例えば、定期的に生成するデータをもとにメールを作成し、送信するといったようなことも実現できます。



## まとめ

複数のライブラリを使い分けるのは難しそうだと思っていましたが、それぞれに得意分野や向き不向きがあることを知り、使い分ける理由が分かりました。  

また、今回調べたことで、「ログインページがあるからスクレイピング諦めよう」とか、「スクレイピングにかなりの時間がかかるけどブラウザにアクセスしているから仕方ないよね」といったことがなくなり、私自身の実装できる幅が広がったと思います。

本記事では、Pythonでのスクレイピングに使用する主要なライブラリの特徴と使い分けについて解説しました。
それぞれのライブラリの得意分野を理解することで、効率的にスクレイピングを行うことができます。 

ぜひ、この記事を参考にして、自分のプロジェクトに最適なライブラリを選び、スクレイピングを活用してみてください！
EC2のGPU 使用率をモニタリングする

## はじめに

GPU使用率を取得するにあたり、IMDSv2対応などで少し手間取ったため忘れないように記載します。
CPU使用率はcloud watch agentで簡単に取得できるが、GPU使用率の場合は取得するプロフラムを用意する必要があり、少し手間がかかる。


## 対応手順

事前にcloud watch agentはインストールしておきます。

* 権限の設定
対象のEC2に下記権限が必要なため、ポリシーを追加します。

`CloudWatchAgentServerPolicy`

* 必要なライブラリを確認

```
$ pip3 list |grep -e boto3 -e nvidia
boto3                        1.26.142
nvidia-ml-py                 11.525.112
```

不足している場合はインストールします。

```
$ python3 -m pip install nvidia-ml-py
$ python3 -m pip install boto3
```

* GPUをモニタリングするソースコードを用意

下記サイトからgpumon.pyをダウンロードします。
記事中ほどの 「Python コードをダウンロードします」からダウンロードできます。

https://aws.amazon.com/jp/blogs/news/monitoring-gpu-utilization-with-amazon-cloudwatch/

gpumon.pyを実行する環境に沿って書き換えます。

**EC2_REGION**
`us-east-1`から`ap-northeast-1`に変更

**my_NameSpace**
`DeepLearningTrain`から`GPUMonitor`に変更

この辺りは下記サイトを参考にしてください。
こちらのサイトにもサンプルコードが記載されています。

https://dev.classmethod.jp/articles/monitoring-gpu-utilization-with-cloudwatch/


### IMDSv2対応のGPU使用率の出力について

IMDSv2でなければ上記対応のみで良かったが、IMDSv2の場合追加の対応が必要となります。
単にGETリクエストのレスポンス見るだけだった部分を、以下のように修正する必要があります。

1.PUT `http://169.254.169.254/latest/api/token` でトークンを生成する
2.リクエストヘッダにトークンを含めてGET `http://169.254.169.254/latest/meta-data/*` でメタデータを取得する。


上記の通り、メタ情報を取得している部分を書き換えると下記のようになります。

```
#Issue Token
TOKEN_BASE_URL = 'http://169.254.169.254/latest/api/token/'
tokenrequest = urllib2.Request(TOKEN_BASE_URL, headers={"X-aws-ec2-metadata-token-ttl-seconds" : "21600"}, method='PUT')
TOKEN = urllib2.urlopen(tokenrequest).read()
#Instance information
BASE_URL = 'http://169.254.169.254/latest/meta-data/'
content_header = {"X-aws-ec2-metadata-token" : TOKEN}
request = urllib2.Request(BASE_URL + 'instance-id', headers=content_header)
INSTANCE_ID = urllib2.urlopen(request).read().decode(encoding)
request = urllib2.Request(BASE_URL + 'ami-id', headers=content_header)
IMAGE_ID = urllib2.urlopen(request).read().decode(encoding)
request = urllib2.Request(BASE_URL + 'instance-type', headers=content_header)
INSTANCE_TYPE = urllib2.urlopen(request).read().decode(encoding)
request = urllib2.Request(BASE_URL + 'placement/availability-zone', headers=content_header)
INSTANCE_AZ = urllib2.urlopen(request).read().decode(encoding)
EC2_REGION = INSTANCE_AZ[:-1]
```



## GPU使用率取得の実行

下記コマンドで実行し、正常に処理が出来ていればCloudWatchに出力されます。

```
$ python3 gpumon.py
```


上記コマンドでは実行中のみしか取得できないため、サービス化します。

* サービスファイルの作成

```
$ vi /etc/systemd/system/gpumon.service
```

* サービスファイルの中身

```
[Unit]
Description = gpumon daemon

[Service]
ExecStart =/opt/tensorflow/bin/python3 「gpumon.pyのパス」
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

* サービスの起動

```
$ sudo systemctl daemon-reload
$ sudo systemctl start gpumon
$ sudo systemctl enable gpumon
```

以上で終了です。
【Docker】docker compose execとdocker compose runの違い

# はじめに
学習中にDockerを使用している際、
「`docker compose`は分かるが、次に続く`exec`と`run`ってどういう意味？」と疑問に感じたので調べてまとめたことを備忘録として記事にします。

# 目次
1. docker compose execについて
1. docker compose runについて
1. この2つはどう使い分ければよい？
1. まとめ

# docker compose execについて
Docker Compose環境で<INS>**起動中のコンテナに対してコマンドを実行**</INS>します。
```docker
docker compose exec [オプション] <サービス名> <コマンド>
```
例としてRailsを用います（オプションは必須じゃないです）

```docker
docker compose exec web rails 〇〇
```
### そもそも... Docker Composeってなんだ？
簡単に説明すると...
- 複数のDockerコンテナを一つのコマンドで立ち上げることができる
- Docker CLI（コマンドラインインターフェース）の拡張機能として動作する<br>プログラムのこと
- docker-compose.ymlで設定されたサービスを操作する
# docker compose runについて
Docker Compose環境で<INS>**コンテナが起動していなくてもコマンド入力が可能**</INS>で、
新規のコンテナを作成してコマンドを実行します。
記述方法も`exec`と似ています。
```docker
docker compose run [オプション] <サービス名> <コマンド>
```
# この2つはどう使い分ければよい？
この`exec`と`run`の2つのはどのように使い分ければよいのでしょうか？
前項の各説明での下線部分に注目します。
- docker compose exec
起動しているコンテナに対してコマンドを入力するため、
既存の環境に直接コマンドを入力する場合。
- docker compose run
既存のコンテナには触れずに新規でコンテナを追加するため、
一時的な作業（マイグレーション・初期設定・テスト等）をする場合。

`exec`は、確実に実行できる場合でrunのように回り道をせずに
すぐにコンテナに適用したい場合で有効。
`run`はコンテナが起動していないので、
コンテナ起動前にbundle installをし、問題がなければ<br>コンテナを起動して同期させるというコマンド入力直後のトラブル防止になる。
# まとめ
||docker compose exec|docker compose run|
|---|---|---|
|コンテナの状態|既に起動中|起動していなくてもよい|
|処理の影響|対象コンテナに直接処理を実行|新規でコンテナを作成して実行<br>現在のコンテナは影響しない|
|使い分け|すぐに適用させたい<br>エラーが無く確実に実行可能な処理|一時的または試験的な処理|
# おわりに
`exec`と`run`は使用用途に応じて使い分けることが重要ですね。
不安な処理であれば一度`run`で確認し、問題がなければ`exec`で本番環境に適用させるといった流れも可能です。
まだまだDockerは奥が深い...!!
awk 使い方

# Linuxコマンド: `awk`

`awk` は、テキスト処理やデータ解析に特化した強力なコマンドラインツールです。主に、パターンマッチングやフィールド単位でのデータ操作に使用されます。

---

## 基本構文

```bash
awk 'パターン { アクション }' ファイル名
```

- **パターン**: 処理対象となる行を指定する条件。
- **アクション**: 条件に一致する行に対して実行する操作。
- **ファイル名**: 処理対象のテキストファイル。

### 標準入力との組み合わせ

`awk`は標準入力からデータを受け取ることもできます。

```bash
cat ファイル名 | awk 'パターン { アクション }'
```

---

## 基本の使用例

### 1. ファイルのすべての行を表示

```bash
awk '{ print }' ファイル名
```
**出力:** ファイルのすべての内容をそのまま出力します。

### 2. 特定の列（フィールド）を抽出

`awk`は、スペースやタブで区切られた列を「フィールド」として認識します。

```bash
awk '{ print $1 }' ファイル名
```
**出力:** 各行の最初のフィールドを出力します。

- `$1`: 最初のフィールド
- `$2`: 2番目のフィールド
- `$0`: 行全体

### 3. 特定の条件に一致する行を表示

```bash
awk '$3 > 100 { print }' ファイル名
```
**出力:** 3番目のフィールドが100より大きい行を出力します。

---

## オプション

### `-F` (フィールド区切り文字の指定)

フィールド区切り文字を指定します。デフォルトはスペースやタブです。

#### 使用例: カンマ区切りファイルの処理
```bash
awk -F"," '{ print $2 }' ファイル名
```
**例:**
以下のようなデータが格納されたファイルがあるとします。

```
tarou,tanaka,satou
suzuki,tamagawa,oya
```

コマンドを実行すると、2番目のフィールドが出力されます。

**入力:**
```bash
awk -F"," '{ print $2 }' データファイル名
```

**出力:**
```
tanaka
tamagawa
```

### `-v` (変数の指定)

`awk`スクリプト内で使用する変数をコマンドラインで指定できます。

#### 使用例: 変数の使用
```bash
awk -v threshold=100 '$3 > threshold { print $0 }' ファイル名
```
**出力:** 3番目のフィールドが100より大きい行を出力します。

#### 応用例: 動的な閾値の計算
以下のようなファイルがあるとします。

```
A,50
B,150
C,120
```
コマンド:
```bash
awk -F"," -v threshold=100 '$2 > threshold { print $1 }' データファイル名
```
**出力:**
```
B
C
```

### `-f` (スクリプトファイルの使用)

`awk`スクリプトを外部ファイルとして保存し、そのファイルを指定して実行できます。

#### 使用例: スクリプトファイルの実行
```bash
awk -f script.awk ファイル名
```

### `-W` (警告や動作モードの指定)

`awk`の動作モードや警告レベルを指定します。

#### 使用例: 非標準拡張の警告を有効化
```bash
awk -W lint '{ print $1 }' ファイル名
```

---

## よく使われるパターンとアクション

### 1. 行番号を付与

```bash
awk '{ print NR, $0 }' ファイル名
```
**出力:** 各行の先頭に行番号を追加します。

- `NR`: 現在の行番号

### 2. 合計値を計算

```bash
awk '{ sum += $3 } END { print sum }' ファイル名
```
**出力:** 3番目のフィールドの合計を出力します。

- `END`: 入力処理が終了した後に実行されるアクション。

### 3. 平均値を計算

```bash
awk '{ sum += $3; count++ } END { print sum / count }' ファイル名
```
**出力:** 3番目のフィールドの平均値を出力します。

### 4. 特定の文字列を含む行を抽出

```bash
awk '/エラー/ { print }' ファイル名
```
**出力:** "エラー"という文字列を含む行を出力します。

### 5. 列の並び替え

```bash
awk '{ print $2, $1 }' ファイル名
```
**出力:** 1列目と2列目の順序を入れ替えます。

---

## 条件演算子

`awk`ではさまざまな条件演算子を使用できます。

- `==`: 等しい
- `!=`: 等しくない
- `>`: 大きい
- `<`: 小さい
- `>=`: 以上
- `<=`: 以下

#### 使用例
```bash
awk '$2 == "成功" { print }' ファイル名
```
**出力:** 2番目のフィールドが"成功"と等しい行を出力します。

---

## 応用例

### 1. ユーザーリストの表示（`/etc/passwd`ファイル）

```bash
awk -F":" '{ print $1 }' /etc/passwd
```
**出力:** ユーザー名をリスト表示します。

### 2. スペース区切りのデータをCSV形式に変換

```bash
awk '{ print $1 "," $2 "," $3 }' ファイル名
```
**出力:** 各行をカンマ区切り形式で出力します。

### 3. 最大値の計算

```bash
awk 'max < $3 { max = $3 } END { print max }' ファイル名
```
**出力:** 3番目のフィールドの最大値を出力します。

### 4. ファイルのヘッダー行を無視

```bash
awk 'NR > 1 { print $0 }' ファイル名
```
**出力:** 2行目以降を出力します。

### 5. フィールドを条件に応じて加工

```bash
awk '$2 == "OK" { $3 = "Success"; print $0 }' ファイル名
```
**出力:** 2番目のフィールドが"OK"の場合、3番目のフィールドを"Success"に変更して行全体を出力します。

---
Google Colab上で動物骨格推定モデルを実行した

## 1. はじめに

以前から動物の骨格推定の例が無いか気になっていました。調べたところ、既存のモデルで意外と簡単に試せました。  
Google Colab上で、動物骨格推定モデルに自前の画像を入力して推定させるまでの流れとその結果を紹介します。

## 2. 環境構築

ailia SDKの「AnimalPose」を使います。

下記のコマンドをcolabのセルに入力・実行し、`ailia-models`をクローンします。

```python
!git clone https://github.com/axinc-ai/ailia-models.git
```

colabを開いてからカレントディレクトリを変更していなければ、`/content`下にローカルリポジトリが作られます。

クローンしたリポジトリをカレントディレクトリにし、必要なパッケージをインストールします。

```python
%cd /content/ailia-models

!pip install -r requirements.txt
```

## 3. 動物骨格推定を実行

### サンプル画像を入力とした場合

まずはリポジトリに含まれるサンプル画像で動物の骨格推定を試してみます。  
`pose_estimation/animalpose`に移動し`animalpose.py`を実行します。

```python
# pose_estimation/animalposeに移動し、試しに実行してみる
%cd /content/ailia-models/pose_estimation/animalpose

!python3 animalpose.py --input input.jpg --savepath output.jpg
```

実行に成功すると、`animalpose`ディレクトリに[README](https://github.com/axinc-ai/ailia-models/tree/master/pose_estimation/animalpose#output)の通りに推定された骨格が描画された画像`output.jpg`が出力されます。

![output.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/51d5aaea-45fd-5d5f-2438-4f93c5e5d0e9.jpeg)

### 自前の画像を入力とした場合

今回は下のウサギの画像を入力とします。

![img.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/066239ef-8d20-97d6-7261-b90e114f1d50.jpeg)

この画像を、Google Colabの`ファイル`上にアップロードします。
(`/content`下にアップロードした前提とします。)

![upload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/53e858d4-8bba-3f5e-8f2a-2cae50b0add5.png)

骨格推定の実行方法はサンプル画像の時と同様です。

```python
# サンプル画像以外の画像をモデルに入力する
!python3 animalpose.py --input /content/img.jpg --savepath /content/test_result.jpg
```

実行に成功すると、下図のように骨格推定の結果が確認できます。  
後ろ足を見つけられていないようですが、概ね骨格推定ができているかと思います。

![test_result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/39a6b50e-a8d2-128c-0047-ae421137fd16.jpeg)

### 動画を入力とした場合

`--video`オプションに動画ファイルのパスを指定することで、動画に対しても骨格推定を行えるようです。

```python
# 動画を入力として骨格推定を実行
!python3 animalpose.py --video /content/video.mp4 --savepath /content/output.mp4
```

注意点として、元のソースコードをcolabで実行すると`cv2.imshow`の使用箇所でエラーが発生します。  

[animalpose.py 363-364行目](https://github.com/axinc-ai/ailia-models/blob/master/pose_estimation/animalpose/animalpose.py#L363-L364)と[372行目](https://github.com/axinc-ai/ailia-models/blob/master/pose_estimation/animalpose/animalpose.py#L372)をコメントアウトすれば、推論を実行できます。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/67f9a7cc-01e6-e476-078b-d0e8a6a27f0f.gif)

精度は微妙ですが、骨格推定の結果が描画された動画を出力できました。

## 4. おわりに

環境構築の観点から、MMPoseのモデルを使うよりも簡単に動物骨格推定を試せました。  
手間のかかる導入無しに動物骨格推定を試したい時にお勧めできます。

## 5. 参考

- <https://github.com/axinc-ai/ailia-models>
- <https://medium.com/axinc/animalpose-%E5%8B%95%E7%89%A9%E3%81%AE%E9%AA%A8%E6%A0%BC%E6%A4%9C%E5%87%BA%E3%83%A2%E3%83%87%E3%83%AB-f7f667c0e69d>
Difyのトラブルシュート、いろいろ

## はじめに

今流行りの？ Difyという生成AIアプリが作成できるという、ノーコードツールを、お試し程度で使ってみました。

非エンジニアでも数分で使えるようになるなど、色々と謳い文句があるようですが、エンジニアの自分でも、サクッとは使えるようにはならず、色々とエラー対応を強いられることになりました。

そのトラブルシュート記事となります。

## エラーいろいろ

### 429 - Rate limit reached for requests You exceeded your current quota, please check your plan and billing details.

モデルで「Gemini 1.5 Pro」、「Gemini 2.0 Flash Exp」を利用してエラーになりました。
無料枠で使っているため、利用制限に引っかかったのだと思います。エージェント利用で、20～30文字程度のリクエストにはちゃんと答えてくれました。しかし、ナレッジに登録した300ページ位あるPDFファイルをコンテキストに追加して、RAGのような使い方をしたところ、まったくもって使いもになりませんでした。

### 400 - Your credit balance is too low to access The Anthropic API. Please go to Plan& Billing to upgrade or purhase credits

AnthropicのClaudeが無料枠で使えるとの情報をGetしたので、AnthropicのAPI Keyを取得し、DifyのAnthropicモデルにAPI Keyを登録しようとしたところ、このようなエラーが出ました。

AnthropicのClaudeが無料枠で使えるという情報は既に過去のものとなっており、現時点（2024/12/20）では有料になっています。

>OpenAIとは別路線のハズで多くの資金調達があるにも関わらずだぜ、おい。

### 403 - dose not have access to model 'gpt-4o-mini'

DifyのOpenAIモデルでOpenAIのAPI Keyを登録しようとしたところ、このようなエラーが出ました。

OpenAIのPlatformから使えるモデルに制限をかけたことが原因でした。「gpt-3.5-turboしか使わねーよ。gpt-4使って高い請求がきたらたまらんからな。」と思って、ケチって、OpenAI Platformで利用できるモデルをgpt-3.5-turboだけに制限をかけたしたところ、DifyでAPI Keyの登録ができなくなりました。どうやら、使わなくてもデフォルトでgpt-4o-miniを使えるようにしておかないといけないみたいです。なぜ、このようになっているのかは不明です。
3Dセキュアの組込におけるCookie属性の確認

2025年3月末からECサイトへの本人認証（EMV 3-Dセキュア）の導入が義務化されることになりました。
クレジットカードで決済可能なシステムの場合、決済代行会社のSDKなど用いて修正が必要になりますね。

3Dセキュアに関してはご存じだと思いますが、決済時にカード会社のサイトに飛んで、本人確認ができたら再度ECサイト側に戻ってきて決済する、という仕組みです。

![003-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924179/5e71f8ca-d31f-0fe2-5d97-c50699a55ec6.png)

参考：https://www.sbpayment.jp/service/method/3d/

## リダイレクト先からセッションが維持されない！

かなり古いフレームワークを使用しているサイトで、カード会社からの認証リダイレクトで戻ってくる際に、セッション情報（購入した商品の情報等）が維持されない現象がおきました。
しかし、原因は至極単純なものでした。

## CookieのSameSite属性を確認する

ChromeはVer80からCSRF対策で、Cookieセット時にSameSite属性が適切に指定されていない場合、外部からそのサイトにPOSTなどでアクセスされた際に発行されたサイトのCookieが強制的に無効になります。
そのため、セッションに`SameSite=None Secure;`の属性がついていないとカード会社のサイトから戻ってきたときにセッションが切れてしまいます。

サイト側のセッションに常に`SameSite=None Secure;` を付与することで解決できます。

外部リンク型の決済の場合既に対応されているケースが多いと思いますが、組み込み型でやっていると上記ケースで実装されている場合もありそうなので、お気を付けください。


Dev ToolsでこうなってればOKかと。
![Cap_3ds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924179/0fe9b738-c1cc-0d24-5901-c3fcef42f31d.png)

古えのフレームワークバージョンだと、そもそもセッションの属性を指定できなかったりで結構大変だったのですが、それはまた別のお話…。
WSL2体験記（歴3年版）

# はじめに

WSL環境で開発を始めて3年ほど経ったので、ふりかえりの意味も込めて思ったことなどを書き残します。
この記事を書いた人のバックグラウンドは以下の通りです。

- 7年ぐらいWindowsやLinuxでサーバサイドアプリケーションを中心に開発
- 3年ぐらいWSL2(Ubuntu)環境でRuby on Railsの開発、最近はFirebaseも触っている
- Windowsで開発しているメンバーは社内で自分だけ。Macはサブ機で触っている

また、WSLの機能に関する話はWSLバージョン 2.3.26.0 を基準に書いています。

# WSLの良いところ

WSLの良いところは「まともに動くLinuxとWindowsをシームレスに行き来できる」ということです。良いところはこれだけです！（個人の感想です）

WSLで出来る開発は、基本的にはMacや純粋なLinuxでも可能です。Windowsを使うことにメリットを感じない人は、macかLinuxへ移行するべきです。

自分の場合はWindowsとLinuxで開発経験を積んだ後にWSLを知り、macに移行するよりもメリットを感じでWSL2を使い始めました。
「切り替え無しで2つのOSを行き来できるなんて最高！Linuxまともに動く！」と結構感動した記憶があります。

# GUIアプリが意外に動くけどまだ難あり

Ruby on RailsやFirebaseなど、CUIで完結できる開発は問題なく出来ています。
最新版ではGUIアプリケーションの実行もある程度サポートされていて、WSL側に必要なパッケージをインストールすればブラウザぐらいは問題ないレベルで動きます。

https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps

以前にAndroid StudioなどのIDEもWSL側で動かせるのでは？と思った試したところ、立ち上げ自体はできました。

ただ、同じPCのWindows側で立ち上げた時より動作が重く、開発利用は厳しい印象でした。WSLのGUI対応はWSLgというプロジェクトで進められていて、さらなる発展を期待しております。

https://github.com/microsoft/wslg

# エディタはVisual Studio Codeが最強（2024年12月現在）

Visual Studio CodeのWSL向け拡張機能が非常に優秀で、現状は出来る限りこれを使って環境を構築した方が色々と捗ると思います。

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl

この拡張機能を使うとUI（ウィンドウ）だけWindows上で実行され、あらゆる操作や拡張機能がWSL側で実行される形になります。
日々開発する中でWSL側との行き来をするのがすごーく楽になり、個人的にはこれが無いと生きていけないです。

もしJetBrainsのIDEなど他の環境を使いたい人は、そのツールが提供しているWSL連携機能を使うなどして構築する必要があります。2023年ごろは拡張機能が上手く動かない～という話をちらほら聞きました。
いずれ解消されていくところだと思うので、脱Visual Studio Codeをしたい方は使いたいIDEの最新情報を追ってみると良いと思います。

# 管理はMacの方が楽

WSLはMicrosoft Storeからインストールするか、公式ドキュメントにあるコマンドを打てばサクッと使えるようになるので、導入は簡単です。

https://aka.ms/wslstorepage

https://learn.microsoft.com/ja-jp/windows/wsl/install

管理面はちょっと複雑で、何か起きた時にWSL側とWindows側の両方を気にする必要があります。
自分が過去にWSL側で問題が起きた際、WSL側で環境変数の設定ミスが原因だったこともあれば、Windows側のネットワーク設定が影響していたこともあります。

環境としてはMacの方が全体の見通しが良くて管理しやすいと思います。

# PCのメモリは32GB以上欲しい

WSLはデフォルトで「Windowsの合計メモリの50%」を確保します。設定ファイルで確保量の変更は可能です。

https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config#main-wsl-settings

WindowsとWSLで1台のPCのリソースを分け合う形になるので、ちゃんとメモリを積まないとスワップが発生して開発体験が非常に悪くなります。
現在はPCのメモリは32GB積んで、WSLには16GBを割り当てて運用しています。

# 変化が激しいので公式の情報を追いかけよう

（当たり前すぎる話ですが、一応書き残します。）

WSLはこの3年の間に大きなアップデートが何度かありました。
機能面では先に述べたGUI対応（WSLg）の他にも、systemdやネットワークのミラーモードも個人的に嬉しいアップデートでした。

https://learn.microsoft.com/ja-jp/windows/wsl/systemd

https://learn.microsoft.com/ja-jp/windows/wsl/networking#mirrored-mode-networking

WSLは仕組みとしては割と新しいので、大きな変更がまだまだ入りそうな印象です。開発効率UPにつながるアップデートが来るかもしれないので、使っているうちはしっかり情報収集していきたいところです。

wslのGithubリポジトリのREADMEに、本家Microsoftやコミュニティへのリンク集があるので、情報源としてはそこがおすすめです。

https://github.com/microsoft/WSL

# おわりに

雑多な内容になってしまいましたが、WSLについては「開発内容によっては問題なく使えるし、手放しでオススメはできないけど、合う人には合う環境」というのが現状の評価です。自分は引き続きメインの開発環境として使い続ける予定です。

また何年かたったらふりかえる予定です（もし別環境に移行していたらお別れの経緯を書きます）
Taobaoのデータアナリストが教える経営分析の基礎と応用

# 経営分析の起点：損益計算書（PL）

## 1. 損益計算書の基本構成
経営分析のスタート地点は損益計算書（PL）です。損益計算書には、以下の重要な項目が含まれます。

### 損益計算書の基本構成
- **売上高**
  - 商品やサービスの販売による収益。

- **売上原価**
  - 商品やサービスを提供するための直接コスト（例：材料費、人件費）。

- **売上総利益**
  ```
  売上総利益 = 売上高 - 売上原価
  ```

- **販売費および一般管理費**
  - 営業活動や管理業務で発生する間接費用（例：広告費、管理者給与、オフィスの賃料）。

- **営業利益**
  ```
  営業利益 = 売上総利益 - 販売費及び一般管理費
  ```

- **経常利益**
  - 営業利益に財務収支（利息収入や利息支出など）を加えた利益。

- **税引前当期純利益**
  - 税金を差し引く前の最終的な利益。

- **当期純利益**
  - 税金を差し引いた後の最終的な利益。

### 補足：トレンド分析
損益計算書を活用する際、以下の分析を加えることでさらに深い洞察が得られます：
- **前年比較：** 前年同月や同四半期との比較。
- **月次比較：** 前月や前四半期との比較。

---

## 2. 経営分析と財務分析の違い
経営分析と財務分析は似ていますが、経営分析はビジネス価値を生む要因を掘り下げ、改善ポイントを特定することに焦点を当てています。

### (1) 売上分析
- 売上を以下の観点で分解：
  - **顧客別：** どの顧客層が収益に貢献しているか。
  - **チャネル別：** どの販売チャネルが効率的か。
  - **商品別：** どの商品が高収益を生むか。

- 補足：増減率や効率性も分析。
  - **顧客増加率：** 新規顧客がどれだけ増加しているか。
  - **チャネル効率：** 各チャネルの単位投入で得られる収益。

### (2) 原価分析
- 重要コストの特定：
  - コストを「占比」と「重要性」で評価。
  - 例：原材料費、工程コスト。

- 補足：コストの背景要因も分析。
  - 原材料価格の変動。
  - 工程効率の向上可能性。

### (3) 費用分析
- 業務モデルごとに分解：
  - **重マーケティング業種：** 広告費、販売促進費が主。
  - **労働集約型業種：** 人件費、管理費が主。

- 補足：収益に対する費用の割合（費用率）を計算し、業界水準と比較。

---

## 3. 最小経営単位の特定

### 最小経営単位の例
- **店舗型ビジネス**
  - **単位：** 店舗。
  - **指標：**
    - 店舗あたりの売上、客単価、来店客数。
    - 店舗あたりの運営費用（家賃、光熱費、人件費）。

- **オンラインビジネス**
  - **単位：** ユーザー。
  - **指標：**
    - GMV = UV × コンバージョン率 × 客単価。
    - CAC（顧客獲得コスト）とLTV（顧客生涯価値）。

- **製造業**
  - **単位：** 製品。
  - **指標：**
    - 製品別の売上・粗利。
    - コスト構成（材料費、工賃、製造オーバーヘッド）。

---

## 4. 業界特性を考慮した分析ポイント

### (1) 商業・流通業
- **重点：** 販売効率、チャネルごとの売上構成。
- **改善案：**
  - 非効率なチャネルの見直し。
  - 在庫回転率を改善し、資金効率を向上。

### (2) 製造業
- **重点：** 原価管理、製造プロセス効率。
- **改善案：**
  - 材料費削減（調達方法の見直し）。
  - 生産プロセスの効率化（歩留まり率向上）。

### (3) サービス業
- **重点：**
  - 軽資産型（例：教育）：顧客単価やリピート率。
  - 重資産型（例：輸送業）：設備利用率、満載率。
- **改善案：**
  - 軽資産型：顧客満足度向上策を導入。
  - 重資産型：稼働率を上げるスケジュール管理。

---

## 5. データ基盤の課題と対策

### (1) データ不足
- CRMやMRP（生産資材計画）が整備されていない。
- **対策：** 手作業でデータを整理し、基礎的な報告書を作成。

### (2) データ分類の不備
- 顧客や商品コードが不明確。
- **対策：** 一貫したコード体系を導入し、基準を整備。

### (3) データシステムの欠如
- 紙ベースや分散管理。
- **対策：** スプレッドシートや簡易ツールを活用。

---

## 6. まとめ

### 経営分析を成功させるポイント
1. **基礎データの整備：** 損益計算書を基点に、売上、費用、原価データを整理。
2. **最小経営単位の明確化：** 業界ごとの特性に合わせた単位設定。
3. **業界特性を考慮：** 業界標準と自社データを比較し、課題を特定。
4. **データ基盤の構築：** 既存データの活用から始め、段階的にシステム化。
「戸籍事務を電子情報処理組織によって取り扱う場合における氏又は名の記録に用いる漢字の字体」の適法性

『家庭の法と裁判』の[今月号](https://www.kajo.co.jp/c/magazine/006/31009000053)を読んでいたところ、「令和6年11月11日付け法務省民一第2451号法務省民事局民事第一課長通知」が掲載されているのを見つけた(pp.165-167)。

![2024-11-11minji.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/179d05b2-f25c-f205-ffdb-62b5938119d6.png)

以前「[戸籍統一文字に関するワーキンググループ](https://www.moj.go.jp/MINJI/minji04_00001.html)」でも指摘した覚えがあるのだが、この通知の

> なお，仮に，家庭裁判所が氏若しくは名の変更についての許可の審判又は戸籍の訂正についての許可の審判において，規則に反する文字を戸籍に記載する旨の審判をした場合には，当該文字を電算化戸籍に記録することはできないので，規則第69条の電子情報処理組織による取扱いに適合しない戸籍として，紙の戸籍を編製することとなります。

という一文は、戸籍法の解釈を完全に誤っており、電子情報処理組織による戸籍事務(いわゆるデジタル戸籍)を全く理解していない。そもそもデジタル戸籍における漢字制限は、戸籍法に根拠規定が存在しない。もちろん、戸籍法50条の「子の名には、常用平易な文字を用いなければならない。」は効いてくるが、これはあくまで出生届の瞬間だけであって、名の変更(107条の2)には適用されないし、ましてや氏には何の制限もない。つまり、戸籍法施行規則68条の3

> 戸籍事務を電子情報処理組織によつて取り扱う場合において、氏又は名に漢字を用いるときは、次の各号に掲げる字体で記録するものとする。
>**一**　常用漢字表に掲げる字体（括弧書きが添えられているものについては、括弧の外のものに限る。）
>**二**　別表第二に掲げる字体
>**三**　その他法務大臣の定める字体

の漢字制限は、戸籍法施行規則の独自規定であって、上位規定である戸籍法に繋がっていないのだ。

一方、氏の変更と名の変更については、戸籍法107条と107条の2に規定されており、家庭裁判所の許可を受けることになっている。つまり、ある文字を家庭裁判所が許可したならば、それは家庭裁判所が当該文字を「本人の氏名として正しい」と認めているわけであり、その手続きが戸籍法として可能となっているわけである。ならば、上位規定である戸籍法に従って、戸籍法施行規則としても当該文字をデジタル戸籍で扱えるようにするのがスジであり、端的には「その他法務大臣の定める字体」に当該文字を加えるしかない、というのが私(安岡孝一)の見解である。

ただ、法務省民事局は、私の見解をよっぽど嫌ったのか、結局、全国の家庭裁判所と最高裁判所事務総局家庭局を敵にまわしてしまった。それならそれで、家庭裁判所もやりようがあって、今後、氏名の変更許可には「…の変更を許可する。なお、戸籍・住民票の電子情報処理は、これを認める。」という一文が追加されることになるのだろう。さて、大変だなあ。
Spring BatchのChunkのトランザクション

Spring Batchにおける「1つのチャンク単位でトランザクションが管理される」という仕組みについて、詳細に説明します。

## チャンク（Chunk）とは？
Spring Batchの「チャンク」は、大量のデータを小さな単位に分割して処理するための仕組みです。チャンクサイズ（chunk-size）を指定することで、1回のトランザクション内で処理するデータの数を制御します。

例えば、データが1000件あり、チャンクサイズを10に設定した場合、以下のように処理されます：

- 1回のトランザクションで10件のデータを処理。
- 10件の処理が完了するとトランザクションがコミットされる。
- 次の10件を新しいトランザクションで処理。
- このプロセスを繰り返して、最終的に1000件を処理。
## トランザクション管理の流れ
Spring Batchでは、チャンク単位でトランザクションが管理されます。以下の流れでトランザクションが動作します：

### トランザクションの開始:

チャンク処理が開始されると、Spring Batchはトランザクションを開始します。
### データの読み取り（ItemReader）:

チャンクサイズ分のデータをItemReaderで読み取ります。
例えば、チャンクサイズが10の場合、10件のデータを読み取ります。
### データの加工（ItemProcessor）:

読み取ったデータを1件ずつItemProcessorで加工します（必要に応じて）。
### データの書き込み（ItemWriter）:

加工されたデータをItemWriterで一括して書き込みます。
### トランザクションのコミット:

- チャンクサイズ分の処理が完了すると、トランザクションがコミットされます。
- コミットが成功すると、次のチャンクの処理が開始されます。
### エラー発生時のロールバック:

チャンク処理中にエラーが発生した場合、そのチャンク内のすべての処理がロールバックされます。
これにより、データの整合性が保たれます。
## トランザクション管理の具体例
以下に、チャンク単位でトランザクションが管理される例を示します。

例: データベースからデータを読み取り、加工して別のテーブルに書き込む
- データ件数: 100件
- チャンクサイズ: 10
### 処理の流れ
### 最初のチャンク（1～10件）:

- トランザクションが開始される。
- 1～10件のデータをItemReaderで読み取る。
- 各データをItemProcessorで加工。
- 加工されたデータをItemWriterで書き込む。
- トランザクションがコミットされる。
### 次のチャンク（11～20件）:

- 新しいトランザクションが開始される。
- 11～20件のデータを同様に処理。
- トランザクションがコミットされる。
### エラー発生時:

- 例えば、15件目のデータ処理中にエラーが発生した場合、11～20件の処理がすべてロールバックされる。
- 1～10件の処理結果はすでにコミットされているため影響を受けない。
## トランザクション管理のメリット
チャンク単位でトランザクションを管理することには、以下のようなメリットがあります：

- データの整合性を保つ
1つのチャンク内でエラーが発生した場合、そのチャンク全体がロールバックされるため、データの不整合を防ぐことができます。
- 大量データの効率的な処理
データを小さな単位に分割して処理するため、メモリ使用量を抑えつつ、大量のデータを効率的に処理できます。
- 再実行が容易
処理が途中で失敗しても、失敗したチャンク以降の処理を再実行するだけで済むため、リカバリが簡単です。
- トランザクションのオーバーヘッドを軽減
すべてのデータを1つのトランザクションで処理する場合、トランザクションのオーバーヘッドが大きくなりますが、チャンク単位で分割することで負荷を軽減できます。
## チャンクサイズの設定
チャンクサイズは、<chunk>タグやJava Configで設定します。
### XML設定例
```xml
<step id="step1">
    <tasklet>
        <chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" commit-interval="10"/>
    </tasklet>
</step>
```
### Java Config設定例
```java
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory, 
                  ItemReader<String> reader, 
                  ItemProcessor<String, String> processor, 
                  ItemWriter<String> writer) {
    return stepBuilderFactory.get("step1")
            .<String, String>chunk(10) // チャンクサイズを10に設定
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
}
```
## 注意点
### チャンクサイズの選定:

- チャンクサイズが小さすぎると、トランザクションのオーバーヘッドが増加します。
- チャンクサイズが大きすぎると、メモリ使用量が増加し、エラー発生時のロールバック範囲が広がります。
- 処理内容やデータ量に応じて適切なサイズを選定する必要があります。
### トランザクションの境界:

- チャンク単位でトランザクションが管理されるため、1つのチャンク内で発生したエラーはそのチャンク全体に影響します。
## まとめ
「1つのチャンク単位でトランザクションが管理される」とは、Spring Batchがチャンクサイズ分のデータを1つのトランザクション内で処理し、処理が完了したらコミットする仕組みを指します。この仕組みにより、大量データの効率的な処理、データの整合性の確保、エラー発生時のリカバリが容易になります。
"The adapter astro-sst does not currently support the feature "sharp". Your project may not build correctly." を解決する

## 結論

SST + Astroでは、AstroのSharpモジュールを利用した機能が使えないので、Sharpを無効化すればOK。

どうしてもSharpを使った画像最適化をしたいなら、少なくともSST + Astroの中でやるのはやめて、別レイヤで実現するのが妥当だと思っているよ。

```js:astro.config.mjs
import { defineConfig, passthroughImageService } from "astro/config";
import aws from "astro-sst";

export default defineConfig({
  image: {
    // ▼ これを追加！
    service: passthroughImageService(),
  },
  output: "server",
  adapter: aws(),
});
```

ここで追加しているオプションについてはAstro公式ドキュメントの下記に記載されている。SSTに限らず、他の条件下でAstroのSharp関連エラーが出ていて、かつSharpによる画像最適化を無効化しても良いっていう場合なら、上記の対応で解決しちゃうのがいいんじゃないかな。

https://docs.astro.build/en/guides/images/#configure-no-op-passthrough-service
Combined loading L-shaped beam(2/2) はりのたわみと不静定はり 発展例題6.21 P172「材料力学演習(20221021)」をAI先生に聞きました。


・私の聞き方がまずかったです。あきらめました。ねじり剛性がでてきてませんでした。

:::note info
前　 [(1/2)sympyでやってみたい。](https://qiita.com/mrrclb48z/items/5ff29e8ac0f30b5cba23)
:::

**平面上の、L字型に曲がったはりの先端に、力Pが平面に垂直方向に作用している時、はりの先端の変位を求めよ。**

# ChatGPT先生へ
>(回答抜粋)
注意点
梁が細長い場合、せん断変形の影響は小さいと仮定できることが多いです。

sympyのソースコードを教えて下さい。

>(回答抜粋)

計算結果を教えて下さい。

>(回答抜粋)

ねじり剛性も考慮したsympyのコードをお願いします。

```python
from sympy import symbols, integrate, solve

# 材料と断面特性
E, I, G, J = symbols('E I G J')  # ヤング率, 曲げ剛性, 剛性率, ねじり剛性
P = symbols('P')                # 荷重
L1, L2 = symbols('L1 L2')       # 垂直部分、水平部分の長さ

# 垂直部分 (x軸方向に変位が生じ、ねじりが発生)
x1 = symbols('x1')
M1 = P * (L1 - x1)  # モーメント
T1 = P              # ねじりモーメント（垂直部分）

# 曲げによる変形
theta1_bending = integrate(M1 / (E * I), x1)  # 曲げによる回転角
v1_bending = integrate(theta1_bending, x1)    # 曲げによる変位

# ねじりによる変形
theta1_torsion = integrate(T1 / (G * J), x1)  # ねじり角
v1_torsion = theta1_torsion * (L1 - x1)       # ねじりによる変位（軸方向）

# 垂直部分の合計変位
C1, C2 = symbols('C1 C2')  # 積分定数
v1 = v1_bending + C1 * x1 + C2 + v1_torsion
theta1 = theta1_bending + C1  # 回転角の合計

# 境界条件を設定 (固定端では変位と回転がゼロ)
conds1 = solve([v1.subs(x1, 0), theta1.subs(x1, 0)], [C1, C2])
v1 = v1.subs(conds1)

# 水平部分 (y軸方向に変位が生じる)
x2 = symbols('x2')
M2 = P * x2  # 曲げモーメント
T2 = P       # ねじりモーメント（水平部分）

# 曲げによる変形
theta2_bending = integrate(M2 / (E * I), x2)  # 曲げによる回転角
v2_bending = integrate(theta2_bending, x2)    # 曲げによる変位

# ねじりによる変形
theta2_torsion = integrate(T2 / (G * J), x2)  # ねじり角
v2_torsion = theta2_torsion * x2              # ねじりによる変位（軸方向）

# 水平部分の合計変位
C3, C4 = symbols('C3 C4')  # 積分定数
v2 = v2_bending + C3 * x2 + C4 + v2_torsion
theta2 = theta2_bending + C3

# 境界条件 (曲がり点での連続性)
conds2 = solve([
    v2.subs(x2, 0) - v1.subs(x1, L1),  # 垂直部分と水平部分の変位が一致
    theta2.subs(x2, 0) - theta1.subs(x1, L1)  # 回転が一致
], [C3, C4])
v2 = v2.subs(conds2)

# 先端変位 (x2 = L2 の時)
displacement = v2.subs(x2, L2)
displacement
```

計算結果を教えて下さい。
(私の聞き方がまずかったです。一緒にすべきでした。)

あきらめました。ねじり剛性がでてきてませんでした。


# Gemini先生へ
・勉強中


# copilot先生へ
・勉強中

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。


#### 参考文献
Elixirのチートシートを作ろう #16 モジュールその2


# 1. OverView

OverViewの時間ですが、ElixirSchoolの引用から始めます。
https://elixirschool.com/ja/lessons/basics/modules#alias-3

```
さて、モジュールと構造体の作り方がわかったので、コンポジションを用いてモジュールや構造体に既存の機能を追加する方法を学びましょう。 Elixirは他のモジュールと連携する様々な方法を用意しています。
```

今回は、モジュールを取り込んだり、利用したりする話です。
今後もどっかでちらほら見るので、役立つとは思いますが、今日の時点では無理に覚えなくていいんじゃないでしょうか？

今回は、チートシート向きだなぁｗ

# 2. まずは解説

## 2.1 alias

モジュール名をエイリアスすることができます。

```
defmodule Sayings.Greetings do
  def basic(name), do: "Hi, #{name}"
end
```
このモジュールを外部から使用可能にしますね。
```
defmodule Example do
  alias Sayings.Greetings

  def greeting(name), do: Greetings.basic(name)
end
```

実行してみましょう。
```
iex(8)> Example.greeting("test")
"Hi, test"
```

```
# aliasを使わない場合
defmodule Example do
  def greeting(name), do: Sayings.Greetings.basic(name)
end
```

:as オプションで、別名にaliasも出来ます。
2つのエイリアス間で名前の衝突があったりにも便利ですね。

```
defmodule Example do
  alias Sayings.Greetings, as: Hi

  def print_message(name), do: Hi.basic(name)　# Greetings.basic/1をHi.basic/1として呼び出している。
end
```

## 2.2 import

モジュールをインポートするよりも、関数そのものを自分のモジュールに取り込みたい。
そんな時に使います。

ちょっと、Elixir Schoolの作例を変えてみますね。
```
iex(11)> List.last([1, 2, 3])
3
iex(12)>   import List
List
iex(13)> last([1,2,3])
3
```
importする前は、List.last/1と呼び出してますが、import語はlastと書くだけで呼び出せてますね。

## 2.3 フィルタリング

さぁ、みなさんご一緒に、フィルタリング。フィルタリング、ヤッホー！ヤッホー！
…うん、なんかコピペっぽい雰囲気に堪え切れなくなったんです、ごめんなさい。

importはデフォルトでは全ての関数とマクロが取り込まれますが、 :only や :except オプションにより、必要なものだけ取り込めます。
```
iex(14)> import List, only: [last: 1]
List
iex(15)> first([1, 2, 3]) # 上で、only: lastしかしていないので、失敗する。
error: undefined function first/1 (there is no such import)
  iex:15

** (CompileError) cannot compile code (errors have been logged)

iex(15)> last([1, 2, 3])
3
```

さらに、こんなことも出来るそうです。
「名前/アリティのペアに加えて、 :functions と :macros という2つの特別なアトムもあります。これらはそれぞれ関数とマクロのみを取り込みます」

```
import List, only: :functions
import List, only: :macros
```

## 2.4 require

他のモジュールのマクロを使用することをElixirに伝えるために requireを使えるそうです。
requireはinmportと異なり、マクロを使用可能にします。

```
defmodule Example do
  require SuperMacros

  SuperMacros.do_stuff
end
```

## 2.5 use

マクロの解説時に説明します。

# 3. 本日のチートシート

|機能の名前|説明|例|
|:--------|:----------------------------------------|:------------------------------------------------------------------|
|alias|モジュール名をエイリアスすることができます。|defmodule Sayings.Greetings do<br>  def basic(name), do: "Hi, #{name}"<br>end|
||:as オプションで、別名にaliasも出来ます。|defmodule Example do<br>  alias Sayings.Greetings, as: Hi<br>  def print_message(name), do: Hi.basic(name)　# Greetings.basic/1をHi.basic/1として呼び出している。<br>end|
|import|関数そのものを自分のモジュールに取り込む|iex(11)> List.last([1, 2, 3])<br>3<br>iex(12)>   import List<br>List<br>iex(13)> last([1,2,3])<br>3<br>|
||importはデフォルトでは全ての関数とマクロが取り込まれますが、 :only や :except オプションにより、必要なものだけ取り込めます|iex(14)> import List, only: [last: 1]<br>List<br>iex(15)> first([1, 2, 3]) # 上で、only: lastしかしていないので、失敗する。<br>error: undefined function first/1 (there is no such import)<br>  iex:15<br><br>** (CompileError) cannot compile code (errors have been logged)<br><br>iex(15)> last([1, 2, 3])<br>3<br>|

# 4. 本日の課題
# 4.1 require, useの説明　マクロ説明後にやること