OmniAICreator/Qiita-1.07M huggingface dataset:
MagicPodの「履歴機能」によるテストケースレビューの効率化

# はじめに
MagicPod社の企画きっかけで前回[記事](https://qiita.com/hiroyukiOkuda/items/809115e8ace05b1df821 "MagicPodのテストケースをチームで管理するための工夫")を書いてから早2ヶ月。第2回の企画のテーマである「実装したテストケースのレビューのやり方」に対して記事を書こうと思いながらも、なかなか書くのが遅くなりました。

ちなみに第2回のテーマを投稿したのは私で、私自身MagicPodを使っていてテストケースレビューのやり方は本当に悩んでいました。今回の記事では、悩んでいた内容とその悩みを解決してくれた[履歴機能](https://support.magic-pod.com/hc/ja/articles/15981973023385-%E5%B1%A5%E6%AD%B4%E6%A9%9F%E8%83%BD)(2023年3月リリース)についてまとめてみました。

# 以前の悩み：レビュー時のやりとりや修正履歴を管理するのが大変
* 困っていたこと
    * Githubのプルリクエストのように、レビュー時のやりとりや修正履歴などを管理したい。しかし、MagicPodにはそういった仕組みがなかったため、その辺の記録をどのように残すべきか迷っていた。
* [履歴機能](https://support.magic-pod.com/hc/ja/articles/15981973023385-%E5%B1%A5%E6%AD%B4%E6%A9%9F%E8%83%BD)がリリースされるまでの自チームの記録の残し方
    * 基本的にslack上でテストケースのレビューを行っており、slack上にしか情報が残らない状況でした。そして、MagicPodのテストケースからslack上の会話のログにたどり着く仕組みもあまり考えていなかったため、なぜテストケースの修正が行われたかは時間が経つと誰もわからない状況でした。

# [履歴機能](https://support.magic-pod.com/hc/ja/articles/15981973023385-%E5%B1%A5%E6%AD%B4%E6%A9%9F%E8%83%BD)のリリースにより私の悩みが解決


## MagicPodの履歴機能とは
2023年3月にMagicPodに[履歴機能](https://support.magic-pod.com/hc/ja/articles/15981973023385-%E5%B1%A5%E6%AD%B4%E6%A9%9F%E8%83%BD)が実装されました。

:::note info
履歴の機能を使うと、テストケースや共有ステップに対する変更履歴を確認することができます。
これにより、いつ、誰が、どのような意図で変更したのかが明確になります。
:::

## 履歴機能を使ったテストケースレビューの例
1. テストケース修正前
1. テストケースを修正し、レビュー依頼
1. レビュー実施（履歴にレビューコメント記入）
1. レビューコメントを踏まえたテストケース修正
1. 再レビュー実施

履歴機能により、1-2の差分(修正前と修正後)や1-4の差分（修正前と最終的な状態）などが簡単に見れるようになりました。
例えばですが、3-4の差分（レビューコメントを踏まえた修正前後）が見れることで、再レビューがものすごくラクになります。
![スクリーンショット 2023-04-28 2.37.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115639/e2620fa5-b8ff-dcac-8601-4764b9fcf67c.png)
今までslackで行っていたやりとりを履歴管理でできるようになったり、いつでも簡単に修正履歴の差分が見れるようになり、この機能のリリースにより私の悩みが解決しました。

# 履歴機能の使い方のアイデア
テストケースレビューだけでなく、「悪いテストケースの例」とそれに対して「改善したテストケースの例」などを示すのに活用できるかなと思います。
* 履歴機能がない場合
    * 「悪いテストケースの例」とそれに対して「改善したテストケースの例」の２ケースを作成する。
→この場合、差分などが把握しづらい

* 履歴機能を使った場合
    * 履歴機能があることで、簡単にテストケースの改善前、改善後の差分を見れるようになりました。
例
        1. 改善前のテストケースの例を作成
        1. ベースURLを利用するように改善![スクリーンショット 2023-04-28 3.01.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115639/bf057e3c-93c6-9333-6fbb-ae5ac3f782d8.png)
        1. 共有変数を使うように改善![スクリーンショット 2023-04-28 3.02.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115639/43bffdb7-e55d-0201-4d43-ba053aed6a54.png)
        1. 共有ステップ化し、改善![スクリーンショット 2023-04-28 3.04.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115639/bacd21ae-53f7-fb06-d406-f7a8b894bce9.png)

MagicPodに慣れていない人がいきなり1と4の差分を見ても、差分が多くてどこからどう改善したのか理解しづらいかなと思います。上記の例のように履歴機能を使うことで、どういった順序で良いテストケースに変わっていくかが理解しやすくなると思います。
そのため、履歴機能はテストケースレビューへの活用だけでなく、このようにお手本を示すのにも利用できるかなと思います。

# まとめ
MagicPodに追加された履歴機能を使いこなすことで、チームとしての生産性を高めることができると思います。また、今回の履歴機能に限らず、MagicPodには日々便利な機能が追加されています。リリース内容を把握し、追加された便利な機能を活用していくことが大事だと改めて思いました。
Databricksマーケットプレイスとは？

[What is Databricks Marketplace? \| Databricks on AWS](https://docs.databricks.com/marketplace/index.html) [2023/4/26時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

:::note info
**プレビュー**
本機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。
:::

本書では、データ製品交換のためのオープンフォーラムであるDatabricksマーケットプレイスをご紹介します。Databricksマーケットプレイスは、データ提供者がセキュアにデータ製品を共有し、データ利用者に自分達の必要とするデータやデータサービスへのアクセスを探索、拡大するパワーを提供するために、[Delta Sharing](https://qiita.com/taka_yayoi/items/3a53516c4434c0ee76f0)を活用しています。
![](https://docs.databricks.com/_images/marketplace-home.png)

# データ利用者はどのようにDatabricksマーケットプレイスのデータにアクセスできるのか？

Databricksマーケットプレイスで欲しいデータ製品を探すには、シンプルに提供者のリスティングをブラウズ、検索し、欲しいデータ製品へのアクセスをリクエストします。いくつかのデータ製品はリクエストを行い、利用条件に同意すればすぐに利用できます。他のものにおいては、提供者の承認と提供者のインタフェースを用いたトランザクションの完了が必要となることがあります。いずれの場合でも、マーケットプレイスを支援するDelta Sharingプロトコルはセキュアに共有データにアクセスできることを保証します。

## データ製品へのアクセスをスタートする

プレビュー期間中にDatabricksマーケットプレースのデータ製品にアクセスするには、Databricksアカウントとワークスペースが必要です。使い始めるには、[Request and access data products in Databricks Marketplace](https://docs.databricks.com/marketplace/get-started-consumer.html)をご覧ください。

# データ提供者はDatabricksマーケットプレイスにどのようにデータ製品を提供できるのか？

Databricksマーケットプレイスは、データ提供者に対してデータサイエンティストやアナリストが自分達の組織の成功のために活用できるデータ製品を共有するためのセキュアなプラットフォームを提供します。Databricksマーケットプレイスでは、共有データに対するセキュリティとコントロールを提供するためにDelta Sharingを活用しています。公開データ、無料のサンプルデータ、有償のデータオファリングを共有することができます。データセットに加えて、ユースケースやお客様がデータ製品の利点を完全に活用できるようにする方法を示すために、Databricksノートブックやその他のコンテンツを共有することもできます。

## データ製品の提供を開始する

Databricksマーケットプレイスでデータ製品を提供するには、以下が必要です:

- Databricksアカウントとプレミアムワークスペース
- [Databricks Data Partner Program](https://www.databricks.com/company/partners/data-partner-program)を通じた提供者の申込み

どのように始めるのかに関しては、[List your data product in Databricks Marketplace](https://docs.databricks.com/marketplace/get-started-provider.html)をご覧ください。

# デモを見る

この動画では、Databricksマーケットプレイスを紹介し、製品一覧に利用者がどのようにアクセスするのか、提供者がどのようにそれらを作成するのかをデモします。
<iframe width="560" height="315" src="https://www.youtube.com/embed/8NJ-JQjcFsQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
We could not find the section 'Approvers' on the Position page layout.

# 解決

+ [DOING MODULE "Lay the Groundwork for an Approval Process" GETTING ERROR" We could not find the section 'Approvers' on the Position page layout."
](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000NGynLSAT)

:::note
Create a section named "Approver" in the "Technical Position Layout" (under the "experience & education") and move the approver fields into that section as you did in the "Position Layout". So both layout will have the section named "Approver" with similar fields.  

「技術職レイアウト」(「経験と教育」の下) に「承認者」という名前のセクションを作成し、「職位レイアウト」で行ったように、承認者フィールドをそのセクションに移動します。したがって、両方のレイアウトには、同様のフィールドを持つ「承認者」という名前のセクションがあります。
:::

+ [getting error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PeTZl)
+ [Step not yet complete in My Trailhead Playground 1 We could not find the section 'Approvers' on the Position page layout.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QOBZ8)
+ [Step not yet complete in My Trailhead Playground 1 We could not find the section 'Approvers' on the Position page layout.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QOBZ8)

:::note
Create a section named "Approver" in the "Technical Position Layout" (under the "experience & education") and move the approver fields into that section as you did in the "Position Layout". So both layout will have the section named "Approver" with similar fields. 

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000NGynLSAT


「技術職レイアウト」(「経験と教育」の下) に「承認者」という名前のセクションを作成し、「職位レイアウト」で行ったように、承認者フィールドをそのセクションに移動します。したがって、両方のレイアウトには、同様のフィールドを持つ「承認者」という名前のセクションがあります。
:::






# 未解決

+ [It shows error that Approvers section not created, but i have created it and completed all challenges after this challenge as well.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000DdoqV)
[Flutter] Makefileを活用していいFlutterライフを送ろう

コードを書いていく中で、`fvm flutter clean`や`flutter pub run build_runner build`などのコマンドを入れる時があると思います。

これらのコマンドを一つ一つやっていくのがめんどくさいと思いませんでしょうか？？

そんなあなたにとっておきの方法をご紹介いたします。

# Makefileとは
- c/c++のコンパイルに必要なコマンド、ソースコード、オプション、依存関係などを書き込んだファイル
- コマンド一つで自動化できるとても便利なもの
- チーム開発する際、Makefileを共有すれば全員でコンパイルルールを統一できる
- 基本構造はシンプルなので、自分のテンプレートを一度作れば様々なプログラムに流用できる




# makefileを活用してみよう

以下のフォルダー構造に追加してください。

```
 - android
 - ios
 - lib
   - main.dart
 - Makefile <--ここ！
```


一つの記載例をご紹介いたします。

```makefile:Makefile
.PHONY: setup
setup:
	flutter clean
	flutter pub get
```

こちらのファイルを追加した後に以下のコマンドを打ってください。

```terminal
make setup
```

こちらを入力すると以下の結果になります

```terminal
flutter clean
Cleaning Xcode workspace...                                      1,583ms
Cleaning Xcode workspace...                                      2,358ms
flutter pub get
Running "flutter pub get" in sample_app...                        3.3s
```

# おすすめのセットアップ

せっかく使うなら有効活用できるようにおすすめなセットアップをいくつかご紹介致します。自分に合うものを自分で探してみてもいいと思います！



```makefile:Makefile
.PHONY: setup
setup:
	flutter clean
	flutter pub get

flutter_generate:
	flutter clean
	flutter pub get
	# l10nの生成コマンド
	flutter gen-l10n
	# import_sorterの実行コマンド
	flutter pub run import_sorter:main
    # flutter_launcher_iconsの生成コマンド
	flutter pub run flutter_launcher_icons
	# コード生成(build_runner)
	flutter pub run build_runner build --delete-conflicting-outputs

submit_ios:
	flutter clean
	flutter pub get
	#Xcodeを開く
	open ios/Runner.xcworkspace

submit_android:
	flutter clean
	flutter pub get
	#AndroidのBundleを生成する
	flutter build appbundle
```


# 最後に
仕事を始めて、Makefileの存在を知りました。使ってみるうちにとても便利だな！と思いました。チームで開発をしていると、全員でバージョンやルールなどの統一ができたりとてもいいなと思いました！
個人開発でも使ってみようかなと思っています！！

いいFlutterライフをみんなで送りましょう〜〜〜！！！！
Express Generator でWebアプリ作成

# はじめに
この記事では、[**_Express Generator_**](https://expressjs.com/en/starter/generator.html) を使ったWebアプリの作成方法について記載していきます。

# 前提
開発環境は以下の通りです。

- Windows11
- VSCode
- JavaScript
- Node.js 18.14.0

# Express Generator のインストール
以下のコマンドで Express Generator をインストールします。
```
npx express-generator
```
プロジェクトファイルが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/becf4ada-468d-a620-588d-ff755a1884db.png)

# パッケージインストール
以下のコマンドで、`package.json` を元に必要なパッケージをインストールします。

```
npm install
```

# アプリの起動
以下のコマンドでアプリを起動します。

```
set DEBUG=express-generator-sample:*
npm start
```

起動することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/b1b19ae6-8fc2-98d2-68af-d6bb17653d8d.png)
`routes/index.js` のコードが表示されます。
```routes/index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;
```

# 参照
- [Express application generator](https://expressjs.com/en/starter/generator.html)
linux スワップ領域について学んだこと

# はじめに
スワップ領域についてよく分からないため、有識者にご教示いただいた内容を本記事
記載しました。


## スワップ領域とは
物理メモリがいっぱいになった時にハードディスク上にメモリを保存する領域です
基本的にはスワップ領域は緊急時に使うものです。

※「スワップ領域とは」以下の記事が参考になりました。
https://e-words.jp/w/%E3%82%B9%E3%83%AF%E3%83%83%E3%83%97%E9%A0%98%E5%9F%9F.html


スワップ領域を作成するには指定したパーティションをすべてスワップ領域する又は
ファイルをスワップ領域として設定することがあるそうです。

※「スワップ領域の作成方法」以下の記事が参考になりました。
https://kazmax.zpp.jp/linux_beginner/mkswap.html


EC2にスワップ領域を作成手順は以下のサイトが大変参考になりました。
https://engineer-blog.ajike.co.jp/ec2-swap/



## スワップ領域の中身を空にして良いか
スワップ領域を空に出来ないかを考えたところ、以下の2つのパターンがあることを知りました。

スワップ領域を解放するのは本番環境の場合は動いているプログラムに影響が出る可能性があるため、あまりお勧めではありません。プログラムが落ちる原因に繋がります。

プログラムが落ちて良い環境の場合はスワップ領域を解放しても良いと思います。


### 一時的にスワップ領域を使用している場合
一時的に負荷が上がってメモリが上限に達してスワップ領域が増える場合があります。
その場合は負荷が下がった際はスワップ領域のサイズが減る可能性があります。



### 常時スワップ領域を使用している場合
常時スワップ領域を使っているなことがあれば、それはリソースがカツカツなのでスペックアップを上げる必要があります。


プログラムやプロセスは仕事を始めるときにメモリを確保し、仕事が終わったら解放するため、
常時ずっと動き続けるようなプログラムがスワップ領域を使用している場合は解放されないケースがあるそうです。そのため、そのプログラムを終了したらスワップ領域が解放されると思います。

※プログラムが落ち切らないゾンビプロセスということもあります。


ゾンビプロセスとは
終了したはずのプロセスが資源を占有した状態でシステムに残るプロセスのことです。

以下の記事が参考になりました。
https://e-words.jp/w/%E3%82%BE%E3%83%B3%E3%83%93%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9.html
Mastering Emacs in Japaneseを入手する方法

Mastering Emacsという本には、有志による日本語版が存在していますが、[公式のページ](https://www.masteringemacs.org/article/mastering-emacs-now-available-in-japanese)には具体的な入手方法の記述がありません。

> If you own my book, you can download the translated version for free.

という記述があるのみで、ネットを少し探したのですが他の方の解説も見付からず。
今回、実際に入手したので、入手方法を書いておきます。

英語版を購入すると、本のデータをダウンロードするページに飛べるようになります。
そのページに英語版のPDF版、ePub版のダウンロードリンクと並んで、日本語版ePub版のダウンロードリンクがあります。そこからダウンロードするだけなので、実質英語版の入手方法と同じです。

別途、日本語版のダウンロードページがあるのかと思ったのですが、特にそんなものはないようです。
安い買い物でもないので、せっかく英語版購入したのに日本語版の入手方法が分からなかったらどうしよう、と思って購入を躊躇してる人の助けになれば幸いです。
Datadog 監視概要

そもそも、監視とは
継続的かつ定期的にシステムが正常稼働するためにメトリクス(リソース、プロセス)などを監視し維持や向上をさせること。また、異常を検知した際には管理者へ通知し、復旧させること。


Datadogの要素ざっくり
・Agent側
・Dashboard側
・monitor側


Agent側
・どうやって監視対象からイベントとメトリクスを取得するの？(HOW)
ＯＳから出力されているファイルなどから取得をする。/proc/statや/proc/diskstatsなどから

・どこからメトリクスを取得からするの？(WHERE)
Datadog AgentがインストールされているホストもしくはDatadog Agentがインストールされているホストから対象から
メトリクスを取得する
https://docs.datadoghq.com/ja/getting_started/agent/
※URL監視する場合は、遠隔からになるため

・いつメトリクスを送信するの？(WHEN)
各監視項目によって、様々になる以下参照
https://docs.datadoghq.com/ja/developers/guide/data-collection-resolution-retention/

基本的には、15～20秒間隔で収集
https://docs.datadoghq.com/ja/getting_started/agent/

・何のメトリクスを取得するの？(WHAT)
デフォルトでは以下のインテグレーションが対象となる
https://docs.datadoghq.com/ja/getting_started/agent/

・だれがメトリクスを取得するの
Agentです


Dashboard側
ダッシュボードには、2種類ある
・タイムボード　調査等で使用
・スクリーンボード　ステータス確認等で使用

カウンタとゲージ
・カウンタ　蓄積のイメージ
・ゲージ　　計測器のイメージ
カウンタは、増加量がわかりやすく、ゲージは変化量がわかりやすい


monitor側
・メトリクスをAgentが取得して、DatadogにHTTPSなどで送信される。
※このDatadogはマルチテナントで構成されており、APIキーによって識別される
monitorで閾値を設定をして、管理者へどのようにアラートを通知するか、など設定が可能
Unity 　記録【随時更新】




# クローンゲーム

## タワーデフェンス
参考元

https://www.udemy.com/course/learn-how-to-create-a-2d-tower-defense-game-in-unity-2020/



投稿した記事
敵機能

https://qiita.com/RYA234/items/6d878a7958a3c760c8af

タレット機能

https://qiita.com/RYA234/items/c9925ce07d6afe64be7e

タレット設置機能

https://qiita.com/RYA234/items/c3d52a0f4ab3258a494a


## FarmRPG

https://qiita.com/RYA234/items/3f105070a9c51d38f98e

https://qiita.com/RYA234/items/ac8421d68187062c7b02

https://qiita.com/RYA234/items/83d7a0c8b65502755b16

https://qiita.com/RYA234/items/895cb735235a5262198f


# アセットの使い方記録

## NewUI Widget

https://qiita.com/RYA234/items/160ac5ef4a129d2c471b

https://qiita.com/RYA234/items/89896c35093158a8925b

https://qiita.com/RYA234/items/f0d939ad90c6b98636d7
## TopDown Engine
WSL導入時のエラー(0x80004002)対処

# はじめに
　WSLを導入したときに遭遇したエラーとそのときの回避方法を書きます。メモ程度の内容ですが同じエラーで困っている人の助けになれば幸いです。

# 環境
```
Windows10
OSビルド: 19045.2728
```

# エラー内容
インストール後、何をやっても0x80004002と表示されました。
```bash
> wsl -l
インターフェイスがサポートされていません
Error code: Wsl/0x80004002
```

# 導入方法(失敗)
　下記を参考にしたところ冒頭のエラーが発生しました。その後設定いじり、DLL再登録、ストアからのダウンロードなど試しましたが、どれも効果無しでした。

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



# 導入方法(成功)
　下記を参考にしたところ正常にインストールできました。

https://learn.microsoft.com/ja-jp/windows/wsl/install-manual
タワーデフェンスゲーム　Unity 敵機能　まとめ

# 説明
Unity でタワーデフェンスゲームのクローンを作ってます。
敵機能の実装について後で確認しやすくするため、記事のリンクと実装後のUnityの画面(gifアニメ)をまとめます。


# 目次
## 1/10　初期時点に移動し待機するようにする
![Enemy1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0b0f0219-4529-1219-ca2a-19843d96394e.gif)


https://qiita.com/RYA234/items/baa5c93c4904c1c23bea


## 2/10　敵が経路に沿って移動する

![Enemy1222.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d91fb3c0-77a3-3258-9d4f-7c67cffac975.gif)


https://qiita.com/RYA234/items/2632c67fffcc4ce4e07a

## 3/10  終点に達した時に敵オブジェクトが非表示にする

![Enemy1222222.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/1b7bdcd3-395c-601c-a001-8920a6e56827.gif)

https://qiita.com/RYA234/items/fa9f1e49b7b97233c4d1

## 4/10 敵が終点に到着した時　残機が減るよう実装

![Enemy1222222333.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/68d3dbc0-7258-4e03-2c56-0d3dd352b84f.gif)

https://qiita.com/RYA234/items/5d51902ac84f718aaa7f

## 5/10 Object Poolを作って複数の敵オブジェクトを出現する様に実装

![111111.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/67c557f7-df12-5e49-cab9-997c7e2d4c72.gif)

https://qiita.com/RYA234/items/9ba3908eec0a15709e91

## 6/10 ２回目以降の敵オブジェクト生成時に最初の移動地点を初期地点にする
改善前
![before.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/70a1f6af-8025-0254-c12a-437fa0dcc5c8.gif)


改善後

![after.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/56476396-36c0-3972-a166-069589e41757.gif)

https://qiita.com/RYA234/items/f4af52f2bfa8538bf6b1

## 7/10 HPバーの作成　オブジェクトの上に生成するように実装


![neoatlas.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/8b0e8cc9-81a8-c59b-587d-752392184bcf.gif)

https://qiita.com/RYA234/items/7a606fc8b879a4032a1b

## 8/10 aボタンを押すとHPバーが減少するように実装

![HeatlhReduce.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/90db3fd8-9c80-4435-fd55-61fbf323fc00.gif)

https://qiita.com/RYA234/items/b1f54272c1d63d95d859

## 9/10 HPバーが０になった時消える処理を実装


![Die.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/55ece9b4-b810-e9bd-ac61-6946a48bed34.gif)

https://qiita.com/RYA234/items/34c1a2eaa069691f58c6

## 10/10　敵オブジェクトがKillされた場合でも、次ウェイブで湧くようにする

![NextWave.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d3515a51-79e6-0d37-32e2-465608d78e32.gif)

https://qiita.com/RYA234/items/2793200acb300ef6bf67

# 参考

参考にしたUdemyの講座

https://www.udemy.com/course/learn-how-to-create-a-2d-tower-defense-game-in-unity-2020/
ChatGPT等のジェネレーティブAIを使ったサービスの利点と課題について

ChatGPTが発表されて、GPT4、GPT5の話も出てきて、話題の中、ChatGPT等のジェネレーティブAIを使ったAIサービスが急速に増加し、市場は既にレッドオーシャン化しています。

ChatGPTは、自然言語処理技術を活用して、人とのコミュニケーションを可能にすることで、面白さや興味深さを持つサービスとして注目を集めています。しかし、実際のアウトプットやシステム構築の観点から考えると、AIを使う利点とルールベースのシステムの利点を比較すると、どのような考察が得られるのでしょうか。

# 現在のレッドオーシャン化とシステム構築の観点からの考察
話題に合わせるプロダクトをリリースするのはとても重要です。何しろ検索数も増えると、いろんなメディアや記事にも取り上げられます。
戦略としてとても重要な動きです。
したがって、現在、ChatGPT等のジェネレーティブAIを使ったサービスを一気にリリースする事はとても重要な事だと思います。

ジェネレーティブAIを使ったサービスは新鮮さやキャッチーさがあり、注目を集めやすいという利点があります。AI技術を活用すること自体が話題性があり、マーケティングの観点からは魅力的に映ります。そのため、無理やりにでもジェネレーティブAIを利用したサービスを作り上げる動きがあるのかもしれません。

# 問題点
一方で、ジェネレーティブAIを使ったサービスが本当に効果的であるかどうかは別の問題です。
例えば、冷蔵庫を写真で撮って献立やレシピを提案するサービスは面白いアイデアですが、実際には写真から食材を判断した後にルールベースのロジックを使って献立を提案する方が良い場合があります。
現在、リリースされているほとんどサービスがChatGPT等のジェネレーティブAI使いたいために無理やりに作り上げられたサービスに惑わされてしまわない様に慎重にチェックする必要があります。

企業側もジェネレーティブAIを利用することに盲目的に追随するのではなく、自社のサービスやビジネスモデルに合った最適な技術選択を行う必要があります。ジェネレーティブAIを使ったサービスが適切かどうかを十分に検討し、技術を選択する際には新鮮さや話題性だけでなく、実際の効果やユーザーのニーズに合った選択を行うべきです。

# アウトプットベースのプロフィットをチェックする
ChatGPT等のジェネレーティブAIを使っていようが、ルールベースの従来型のサービスであろうが、得られるプロフィットが何なのかが重要です。
流行りのワードだからといっても得られるプロフィットはルールベースの方が大きいパターンも多いです。

ジェネレーティブAIを使ったサービスであっても、アウトプットベースのプロフィットをチェックすることが重要です。流行りのワードや新しい技術を採用するだけでなく、実際に得られるプロフィットを考慮することが必要です。ルールベースの従来型のサービスであっても、効果的なビジネスモデルを持つことで、十分な収益を上げることができます。

以下は、アウトプットベースのプロフィットをチェックする際に考慮すべきポイントです。

## １．収益モデルの評価:
 ジェネレーティブAIを使ったサービスにおいても、具体的な収益モデルを評価することが重要です。例えば、サブスクリプションモデル、広告収益、プロダクトの売上など、収益を生み出す仕組みを明確にし、収益の見込みを評価します。また、顧客層や市場規模に合った収益モデルを選択することも重要です。

## ２．コストの評価:
 ジェネレーティブAIを使ったサービスを提供するために必要なコストを評価します。AIモデルの開発や運用に必要な人件費、インフラストラクチャのコスト、データ収集やデータ処理にかかるコストなどを考慮し、適切な価格設定や収益見込みを評価します。

## ３．マーケットの分析:
 ジェネレーティブAIを使ったサービスの市場の需要や競合状況を分析し、潜在的な顧客層や市場規模、競合他社の存在や差別化ポイントを把握します。市場のニーズやトレンドに合致し、収益を見込める市場を選択することが重要です。

## ４．ユーザーのフィードバックを考慮する:
 ユーザーのフィードバックを重視し、サービスの改善やアップデートを行いながら、ユーザーからの収益を最大化するための改善点を見つけ出します。ユーザーのニーズを満たし、顧客満足度を高めることが、収益の向上につながります。

## 5.リスク評価:
 ジェネレーティブAIを使ったサービスには、技術的なリスクや法的なリスクが存在する可能性があります。例えば、AIモデルの正確性や信頼性の問題、データのプライバシーとセキュリティの問題などがあります。これらのリスクを評価し、適切な対策を講じることが重要です。

## 6.長期的な見通しを持つ:
 アウトプットベースのプロフィットをチェックする際には、長期的な見通しを持つことも重要です。一時的な利益だけでなく、持続的な収益を見込めるかどうかを評価します。将来の市場の変化や技術の進化を考慮し、持続的なビジネスモデルを構築することが大切です。

## 7.実証実験を行う:
 アウトプットベースのプロフィットをチェックするためには、実証実験を行うことも有効です。実際にサービスを市場でテストし、収益の実績データを収集し分析することで、実際の収益を評価することができます。

以上のように、アウトプットベースのプロフィットをチェックする際には、収益モデルの評価、コストの評価、マーケットの分析、ユーザーのフィードバックの考慮、リスク評価、長期的な見通しの持ち方、実証実験の実施などを総合的に考慮することが重要です。単に流行りのワードや新しい技術を採用するだけでなく、実際に収益を見込めるかどうかをしっかりと評価し、適切なサービスを選択するようにしましょう。

# まとめ
話題のChatGPT等のジェネレーティブAIを使ったサービスが沢山出てきていて自社でもすぐに採用しないと乗り遅れと思ってしまうと思いますが、実際に得られるプロフィットをしっかりと吟味した上で、ChatGPT等のジェネレーティブAIを使ったサービスを採用するのか、従来型のサービスを採用するのか検討する必要があります。

きっと、今レッドオーシャン化しているChatGPT等のジェネレーティブAIを使ったサービスも淘汰されて無くなってくるでしょう。
そこから導入を考えても遅くはありませんが、自分で目利きしてジャッジする事も重要だと思います。

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Minecraft 1.19以降のMod(Forge)でMixinの設定をする

この記事はMinecraft 1.18以前でModを開発したことがあるが、1.19以降のMixinの設定で`build.gradle`をみて、戸惑った人向けです
Modを作ったことがない人向けではありません

# 前提知識
- **Mixin**を設定してあげることで、新しい要素を追加するだけでなく、元々のMinecraftのコードを改造したような機能も実装できる
- Minecraft ForgeではJava向けビルドツールである**Gradle**を使って、依存関係やタスクを管理している

# 問題
[Mixinの公式ドキュメント](https://github.com/SpongePowered/Mixin/wiki/Mixins-on-Minecraft-Forge)をみると、設定の方法が3ステップで書かれており、**1.18以前**では、手元の`build.gradle`をコピペしながら変更するだけで設定できる
しかし**1.19以降**で同じように進めていこうとすると、第1ステップで手が止まる(第2, 3ステップは今まで通りでいける)
公式ドキュメントには、
```groovy:build.gradle
buildscript {
    repositories {
       ...
    }
    dependencies {
        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
        // MixinGradle:
        classpath 'org.spongepowered:mixingradle:0.7.+'
    }
}
...
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
// MixinGradle:
apply plugin: 'org.spongepowered.mixin'
...
```
のように`build.gradle`の`buildscript`と`apply plugin`に追加しろと書かれているが、
Forgeからダウンロードしてきた、MDKの`build.gradle`をみると、それらしいところはなく、
```groovy:build.gradle
plugins {
    id 'eclipse'
    id 'maven-publish'
    id 'net.minecraftforge.gradle' version '5.1.+'
}
...
```
という`buildscript`と`apply plugin`の間をとったような数行が書かれているだけである
似ているからといって、`plugins`にそれっぽく`id 'org.spongepowered.mixin'`や`id 'org.spongepowered:mixingradle:0.7.+'`、`id 'org.spongepowered:mixingradle' version '0.7.+'`と書いたところでエラーが出るだけで何も動かない

# 原因
調べたところ、プラグインの書き方は2通りあるらしく、1.18以前は`buildscript`+`apply plugin`という古い書き方だが、1.19以降は`plugins`という新しい書き方らしい
[参考：エキサイトTechBlog -build.gradleのbuildscript、plugins、dependenciesの違いについて-](https://tech.excite.co.jp/entry/2022/08/15/153626#buildscript-plugins-%E3%81%AE%E4%BD%BF%E3%81%84%E6%89%80)

# 解決方法
もちろん`plugins`のところを丸々`buildscript`+`apply plugin`に置き換えれば動くが、せっかく新しい書き方が使われているので、そのやり方で書くために調べたところ以下のサイトが参考になった
[参考：Stack Overflow -How can the gradle plugin repository be changed?-](https://stackoverflow.com/questions/37285413/how-can-the-gradle-plugin-repository-be-changed)
参考サイトによると、`build.gradle`だけではなく`settings.gradle`も変更する必要があるらしい
```groovy:build.gradle
plugins {
    id 'eclipse'
    id 'maven-publish'
    id 'net.minecraftforge.gradle' version '5.1.+'
    id 'org.spongepowered.mixin' version '0.7.+'
}
...
```
```groovy:settings.gradle
pluginManagement {
    repositories {
        gradlePluginPortal()
        maven { url = 'https://maven.minecraftforge.net/' }
        maven { url = 'https://spongepowered.org/maven/'}
    }
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == 'org.spongepowered.mixin') {
                useModule('org.spongepowered:mixingradle:0.7.+')
            }
        }
    }
}
```
なぜ`settings.gradle`の変更が必要かというと、`org.spongepowered.mixin`は外部プラグインなので、プラグインを取得してくる場所を指定してあげる必要があるからである
とにかくこれで正しくなったので、[Mixinの公式ドキュメント](https://github.com/SpongePowered/Mixin/wiki/Mixins-on-Minecraft-Forge)の残りのステップの設定をしたらMixinは使えるようになるはずである
Fedora Silverblue でアップグレード後リブート前に user id 不足をチェックする

# 動機
rpm-ostree を使って update や install/remove を行った後、
リブートしてみるとものがまともに動かなくてロールバックすることがそこそこある。
理由の殆どは、必要なサービス用のIDがちゃんと作成されていないこと。
なーぜーか、そういうことが結構ある。

リブート前にこれをチェックしたいと思って簡単なスクリプトを作成した。

# スクリプト
```shell:ostree-check-ids
#!/bin/bash
#
OSTREE=/usr/bin/ostree
HEAD=/usr/bin/head
CUT=/usr/bin/cut
SORT=/usr/bin/sort
UNIQ=/usr/bin/uniq
DIFF=/usr/bin/diff
#
NUM=$(${OSTREE} admin status|${HEAD} -1|${CUT} -c 10-75)
#
function extf ()
    {
    ${CUT} -d : -f 1 $1 | ${SORT} | ${UNIQ} > $2
    }
#
extf /usr/lib/passwd /tmp/usr_lib_passwd.$$
extf /ostree/deploy/fedora/deploy/${NUM}/usr/lib/passwd /tmp/ost_passwd.$$
${DIFF} -bwtBu /tmp/usr_lib_passwd.$$ /tmp/ost_passwd.$$
(( RET=$? ))
if (( ${RET} != 0 )); then
    exit ${RET};
fi
#
extf /usr/lib/group /tmp/usr_lib_group.$$
extf /ostree/deploy/fedora/deploy/${NUM}/usr/lib/group /tmp/ost_group.$$
${DIFF} -bwtBu /tmp/usr_lib_group.$$ /tmp/ost_group.$$
(( RET=$? ))
if (( ${RET} != 0 )); then
    exit ${RET};
fi
```

# 実行例
```
# /root/bin/ostree-check-ids 
--- /tmp/usr_lib_passwd.38204	2023-04-28 03:20:37.483279326 +0900
+++ /tmp/ost_passwd.38204	2023-04-28 03:20:37.486279392 +0900
@@ -11,7 +11,6 @@
 dhcpd
 dnsmasq
 dockerroot
-dovecot
 dovenull
 etcd
 flatpak
# 
```

うーん、これはダメだね。
次の update 待ち。
AWS Amplifyをterraformで管理する際の引数解説

# 誰向けの記事か
・AWS Amplifyをterraformで管理しようとしている人
かつ
・公式ドキュメントをみてもイマイチ各引数の動作イメージが湧かなかった人
# 概要
・この記事はAWS Amplifyをterraformで管理する際、各引数が動作をするのかを解説した記事です。
・自分で構築する際、公式ドキュメントだけだと（英語なので）実際にどういった動作をするのか分からなかったので記事としてまとめました。
・全ての引数は網羅できていません、主要と思われるものだけ載せています。

詳細は[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/amplify_app#custom_rule)を参照してください


```tf:amplify.tf

resource "aws_amplify_app" "amplify-app" {
  # Amplifyのアプリ名、AWSコンソール上などに表示される
  name = "app-name"
  # リポジトリのURL
  repository = "https://github.com/test/test_repo"
  # リポジトリのアクセスに必要なトークン、コードの読み取り権限とWebhookの作成権限が必要
  access_token = "xxxxxxxxxxxxxxxxx"

  # trueだとauto_branch_creation_patternsに一致するブランチgit側に作成された時、Amplifyに当該ブランチが連携される
  enable_auto_branch_creation = true
  # trueだとブランチがgit側から削除された時、Amplify側でも削除される
  enable_branch_auto_deletion = true
  # ブランチの正規表現パターン
  auto_branch_creation_patterns = [
    "*",
    "*/**",
  ]

  # デプロイの際に実行されるビルド設定、AWSコンソールから手動でブランチを作成した場合に使用
  build_spec = <<-EOT
    version: 0.1
    frontend:
      phases:
        preBuild:
          commands:
            - yarn install
        build:
          commands:
            - yarn run build
      artifacts:
        baseDirectory: build
        files:
          - '**/*'
      cache:
        paths:
          - node_modules/**/*
  EOT


  # 自動連携されたブランチに適応される設定
  # auto_branch_creation_patternsに一致するブランチgit側に作成され、Amplifyに連携された時に適応される
  # AWSコンソール上でブランチを連携した場合は適応されない
  auto_branch_creation_config {
    content {
      # ビルド設定、この設定が無い場合は前述のbuild_specが適応される
      build_spec = <<-EOT
    version: 0.1
    frontend:
      phases:
        preBuild:
          commands:
            - yarn install
        build:
          commands:
            - yarn run build
      artifacts:
        baseDirectory: build
        files:
          - '**/*'
      cache:
        paths:
          - node_modules/**/*
  EOT
      # trueだとブランチに更新があった時にAmplify側に自動的にビルド＆デプロイされる
      enable_auto_build = true
      # tureだと自動デプロイされたブランチにBasic認証がかかる
      enable_basic_auth = true
      # Basic認証のユーザー名とパスワード
      basic_auth_credentials = base64encode("develop:develop123")
    }
  }

  # trueにすると全てのブランチにBasic認証がかかる
  enable_basic_auth = true
  # 全てのブランチにBasic認証をかける場合のユーザー名とパスワード
  basic_auth_credentials = base64encode("admin:admin1234")


  # 環境変数の設定、設定できる変数は https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html を参照
  environment_variables = {
    // ビルドに使うNode.jsのバージョン
    _LIVE_UPDATES = "[{\"name\":\"Node.js version\",\"pkg\":\"node\",\"type\":\"nvm\",\"version\":\"16.15.0\"}]"
  }

  # 通信のカスタムルール、アクセス元を判別してアクセス先の書き換えが可能、リダイレクト等に用いる
  custom_rule {
    source = "/<*>"
    status = "404"
    target = "/index.html"
  }

}


```
【Lando】MySQL - 日本語の文字化けを解消する方法

## 現象
Lando環境でMySQLに接続し、SQL文で取得した日本語文字が「???」になる。
## 対応方法
drushを使用すると簡単にSQLに接続が可能。
次の2つのパターンで接続できる。
パターン①だとコマンドを叩いた直後で、Landoで使用しているアプリのDBに接続可能だが、日本語が文字化けする。
パターン②では文字化けが解消されるがDBを選択する必要がある。```use {DB名}``` で接続が必要。
```
## パターン① 日本語が文字化けしてしまう。
drush sqlc
## パターン② 文字化けしない方法。
drush mysql
```
## 参考
LandoアプリにDrushをインストールできるコマンド
```composer require drush/drush```
【作業効率化＆自己満】データサイエンティストを目指す大学生のデスク周り製品まとめ【深夜テンション】

去年の夏に、モニターを買ったらマジで効率が爆発的によくなったので、それ以来モニターをオススメしまくっている。

なので（？）、この機に自分のデスク周りの製品を全て紹介する。（？）

ただの自己満である。あと、何使ってるの？とかよく聞かれるので、その時のためにまとめておこう、という感じ。

# 自己紹介
データサイエンティスト目指してる慶應大学4年生。詳しいプロフィールはTwitter(<a href='twitter.com/A7_data'> @A7_data</a>）か、このページを見てね

https://mohki7.notion.site/Mototsugu-Oki-c478f842c4de48f394e2e24b58e206bb?pvs=4

# こちらの記事はNoteに移行しました
こちらをご覧ください。

https://note.com/a7_data/n/n2b045b0313a4
単語を数値にして計算するやつ作ってみた

皆さんこう思いますよね。
「単語間で計算を行いたい」と。
実際Word2Vecというものがあるのですが、初心者の私にはハードルが高くて...
なので今回はPythonのdict型を使って作ってみようと思いました。
(初投稿です)
# 経緯
作った理由を詳しく話すと、Word2vec自体は他の記事を見ながら書いてみたりしたのですが、
単語の計算(王-男+女=女王)みたいなのもチャレンジしてみようと思いましたが、
モデルのサイズが大きいので断念。
なので自作してみよう！って思いました。
# 実際に書いてみる
以下コードです。きたないです。申し訳ございません。(コメントでif文について指摘が来ていたので修正しました)
```python
import random
import json
import sys
num_range=100
textlist=["Search","Microsoft","Phone","GameConsole","Facebook","Community","Sony","Valve","Apple","Pie","Tech","PC","SmartPhone","China","UnitedStates","GAFAM","VR","FaceBook"]
if len(sys.argv) == 1:
    WordVec={_:random.uniform(-num_range,num_range) for _ in textlist}
    WordVec["ApplePie"]=WordVec["Apple"]+WordVec["Pie"]
    WordVec["AppleInc."]=WordVec["Apple"]+WordVec["Tech"]
    WordVec["IPhone"]=WordVec["AppleInc."]+WordVec["SmartPhone"]
    WordVec["MacOS"]=WordVec["AppleInc."]+WordVec["PC"]
    WordVec["BATH"]=WordVec["GAFAM"]+WordVec["China"]
    WordVec["GAFAM"]=WordVec["BATH"]+WordVec["UnitedStates"]
    WordVec["MetaQuest2"]=WordVec["Facebook"]+WordVec["VR"]
    WordVec["Pico4"]=WordVec["China"]+WordVec["VR"]
    WordVec["Steam"]=WordVec["Valve"]+WordVec["Community"]
    WordVec["SteamVR"]=WordVec["VR"]+WordVec["Steam"]
    WordVec["ValveIndex"]=WordVec["VR"]+WordVec["Valve"]
    WordVec["PlayStation"]=WordVec["GameConsole"]+WordVec["Sony"]
    WordVec["PSVR"]=WordVec["VR"]+WordVec["PlayStation"]
    WordVec["TrinusPSVR"]=WordVec["PSVR"]+WordVec["PC"]
    WordVec["iVRyPSVR"]=WordVec["PSVR"]+WordVec["SteamVR"]
    WordVec["Windows"]=WordVec["Microsoft"]+WordVec["PC"]
    WordVec["Bing"]=WordVec["Microsoft"]+WordVec["Search"]
    WordVec["Skype"]=WordVec["Microsoft"]+WordVec["Phone"]
    json.dump(WordVec, open("WordVec.json","w",encoding="utf-8"), indent=4) #数値の保存
else:
    #数値の読み込み
    fp_read=open(sys.argv[1],"r",encoding="utf-8")
    WordVec=json.load(fp_read)
reverse_WordVec={v:k for k,v in WordVec.items()}

while True:
    try:
        originalText=input(">").replace(" ","")
        if "+" in originalText: #足し算の場合
            originalText_Splits=originalText.split("+")
            a=originalText_Splits[0]
            b=originalText_Splits[1]
            try:
                print(reverse_WordVec[WordVec[a]+WordVec[b]])
            except:
                print(f"エラーが発生しました。:{WordVec[a]+WordVec[b]}")
        elif "-" in originalText: #引き算の場合
            originalText_Splits=originalText.split("-")
            a=originalText_Splits[0]
            b=originalText_Splits[1]
            try:
                print(reverse_WordVec[WordVec[a]-WordVec[b]])
            except:
                print(f"エラーが発生しました。:{WordVec[a]-WordVec[b]}")
        else:
            print("+ もしくは - を書いてください。")
    except IndexError:
        print("エラーが発生しました。マイナス記号もしくはプラス記号の前と後ろに単語を書いてください。")
    except KeyError:
        print("エラーが発生しました。辞書を参照してみましたが、そのような単語が見つからないためです。")
```
実際に実行するとこうなったりします。
```
>Phone+Microsoft
Skype
>Skype-Phone
Microsoft
>Windows-Microsoft
PC
```
# おわりに
ここまで読んでいただきありがとうございます。
誤字脱字があったらコメントで指摘していただければ助かります。
(お手柔らかにお願いいたします)
Stream APIについて

## Stream API

Java 8から追加されたJavaのライブラリ
コレクション（リストやセットなど）や配列などのデータソースから要素をストリーム処理するためのAPI

→コードの可読性や効率性を向上できる

## forループを使用する場合と比較した時のメリット

- 簡潔なコード：短いコードで複雑な処理を実行することができます。

- 内部反復：並列処理が容易になる
→複数のスレッドを使用してストリームの要素を同時に処理できる

- 遅延評価：必要なときにのみ要素を処理する
→ストリームの要素が必要なときにのみ処理が実行されるため余分な処理を避けられる

## Stream APIを使用するには、以下の手順が必要です。

1,データソース（コレクションや配列など）を作成

2,データソースからストリームを作成

3,ストリームに対して、中間操作（フィルタリング、マッピング、ソートなど）を実行

4,最終操作（リダクション、コレクション、forEachなど）を実行しストリームの要素を処理
Windows11 ネットワークアダプタードライバ 突然死ぬ

## Windows11 ネットワークアダプタードライバ 突然死ぬ
発生当時はインターネットアダプタドライバーに警告マークがついていて
デバイスの再インストールで解決
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/709188/1f93aa60-b739-1876-3b23-6b0ab536d822.png)

## まとめ
とりあえず、びっくりした。
いままでどんなボロPCでもこんなこと起こったことなかったので...
win11 は スタートの検索窓でなにかしら、文字が入力できなかったり不具合っぽいところもあったりする。
os としては若干まだ未熟なのだろうか？
PyAVでの動画の1フレームごとへの処理と動画の保存

# 今回したこと

PyAVを使用して動画を1フレームずつ読み込み処理し，動画として保存します．以下のPyAVの公式サイトを参考に作成しました．

- https://pyav.org/docs/develop/cookbook/numpy.html#generating-video 

今回は動画データセットを1フレームごとに物体検出し，その結果を動画として可視化しました．

# 流れ

- 動画フォーマットの指定
- streamの指定
- １フレームごとの処理
- 動画へ出力

## 必要なライブラリのインポート

```python
import av
import numpy as np
```

## streamの指定と作成動画のフォーマットの指定

読み込む動画と作成する動画のコンテナを作成します．

```python
filename_out = './out.mp4'  # 作成するファイルのパス
filename_read = './read.mp4'  # 読み込むファイルのパス
container_out = av.open(filename_out, mode="w")
container_read = av.open(filename_read)
```

アクセスするstreamを指定します．streamにはvideoとaudioなどがあります．
videoでは大抵一つしかないため，0番目のstreamである`video[0]`を使用します．

```python
stream_read = container_read.streams.video[0]
```

次に作成する動画のフォーマットを指定します．

- `stream_read.codec_context.`で読み込む動画のfpsとwidthとheightを取得し，`stream_out`の変数に代入します．
- `stream_out.pix_fmt`でピクセルのフォーマットを指定します．

```python
fps = stream_read.codec_context.rate
stream_out = container_out.add_stream("mpeg4", rate=fps)
stream_out.width = stream_read.codec_context.width
stream_out.height = stream_read.codec_context.height
stream_out.pix_fmt = "yuv420p"
```

## 1フレームごとの処理と動画化

```python
    for frame in container_read.decode(video=0):

        # PILへ変換
        img = frame.to_image()
        # detection
        detected_image = detection(img, processor, model)
        # 検出の進捗ログ出力
        print("%d/%d" % (frame.index + 1, stream.frames))  

        # 動画化
        detected_image = np.array(detected_image)
        detected_image = av.VideoFrame.from_ndarray(detected_image, format="rgb24")
        for packet in stream_out.encode(detected_image):
            container_out.mux(packet)

    # Flush stream
    for packet in stream_out.encode():
        container_out.mux(packet)

    # Close the file
    container_read.close()
    container_out.close()
```


まず`container_read.decode(video=0)`で1フレームごとに読み込みます．

以下のコードで1フレームごとの処理を行います．今回はPIL形式の画像と，読み込んだhuggingfaceのmodelとprocessorを引数にとり，物体検出してbounding boxを描写した画像`detected_image`を返す自作の関数`detection`を使用しました．

```python
# PILへ変換
img = frame.to_image()
# detection
detected_image = detection(img, processor, model)
#検出の進度のログの出力
print("%d/%d" % (frame.index + 1, stream.frames))
```

`av.VideoFrame.from_ndarray()`で画像をビデオ用フレームに変換します．この関数に画像を渡す前に，画像をndarray形式に変換してください．

```python:動画化
# ndarray形式の画像に変換
detected_image = np.array(detected_image)
# 画像をビデオ用のフレームに変換
detected_image = av.VideoFrame.from_ndarray(detected_image, format="rgb24")
 # 出力ストリームにまとめて出力
for packet in stream_out.encode(detected_image):
    container_out.mux(packet)
```

残ったフレームを出力します．

```python
    # Flush stream
    for packet in stream_out.encode():
        container_out.mux(packet)
```

コンテナをクローズします．

```python
container_read.close()
container_out.close()
```

## 結果

このような検出したbounding boxが描画された動画を作成できました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346739/3e989d7e-d283-e28b-a6c7-c196f8fe7100.png)
【Git】メールアドレスをnoreplyに設定する

## はじめに

以下のようなコマンドを実行することで`~/.gitconfig`や`~/.config/git/config`の`user.email`で設定しているメールアドレスが表示されます。  

```zsh:ターミナル
$ git log --pretty=fuller    
commit 2wf60faofewao1c00af12b3dd69d93900cd1156d (HEAD -> main)
Author:     UserName <e-mail@example.com>
AuthorDate: Thu Aug 18 09:26:25 2022 +0900
Commit:     UserName <e-mail@example.com>
CommitDate: Thu Aug 18 09:26:25 2022 +0900

    chore: delete docker-compose.yml

commit 75dweioj7ce834dd2ffjaofjewb92839dbec4254 (origin/main)
Author:     UserName <e-mail@example.com>
AuthorDate: Sun Aug 14 15:30:22 2022 +0900
:
```

上記で表示されるメールアドレスをダミーに変更する方法について記載します。

## メールアドレスを非公開に設定

GitHub上でメールアドレスを非公開に設定します。

GitHubを開き「右上のユーザーアイコン」→「Settings」→「サイドバーのEmails」の順にクリックします。  

開いたページで以下の赤枠の2つにチェックを入れます。

![設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/f45072d2-cc31-32df-62ee-279eb6a4c05a.png)


2つの項目を翻訳すると下のようになります。
* 上の項目

>メールアドレスを非公開にする  
>ウェブベースの Git 操作 (例: 編集やマージ) やメール送信を代行する際には、あなたの公開プロファイルのメールを削除して 00000000+UserName@users.noreply.github.com を使うことになります。コマンドラインのGit操作で非公開の電子メールを使いたい場合は、Gitで電子メールを設定する必要があります。

* 下の項目

>メールアドレスを公開するコマンドラインプッシュをブロックする  
>GitHub にプッシュすると、直近のコミットがチェックされます。もしそのコミットの作者のメールアドレスがあなたの GitHub アカウントの非公開メールアドレスだった場合は、そのプッシュをブロックして非公開メールアドレスの公開について警告を出します。

## Gitの設定を変更

上記の設定だけではターミナルで`git commit`を実行した際、非公開にしたメールアドレスが使用されてしまいます。
そのためGitの設定を変更する必要があります。

変更するためには以下のコマンドを実行します。
`数字+アカウント名@users.noreply.github.com`の部分には下画像の赤線部分に置き換えます。

```zsh:ターミナル
git config --global user.email "数字+アカウント名@users.noreply.github.com"
```

![メールアドレスの場所](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6ef00ac8-1f7b-784f-ba35-0f948e948ba3.png)
【2週目】Javascript・JQuery・Fetch【スパルタコーディングクラブ】

・Javascriptについて
→プログラミング言語の1つ。データの送受信や入力形式の確認などの処理ができる

・JQueryについて
→ウェブを操作することができる。JavaScriptのみだと複雑しがちなことを簡素化できる

▼JavaScript
document.getElementById("element").style.display = "none";

▼JQuery
$('#element').hide();

・forEachを使うことで膨大な変数に対していちいちコーディングする必要がなくなる

・Fetchについて
→欲しいデータのリクエストを発行し、そのレスポンスを取得できる

PM2.5の地域ごとの数値と日本、各駅のレンタサイクル情報の情報をOpenAIから引っ張ってきました。
【RSpec】  Failure/Error: @pid = Process.spawn(*@command, options) エラーの対処法

## はじめに
RSpecのシステムスペックで非同期通信のテストをしていました。
`visit root_path`によって画面を表示しようとした際に以下のエラーに遭遇しました。
```
     1.1) Failure/Error: visit root_path
          
          TypeError:
            no implicit conversion of nil into String
          # ./spec/system/tasks_spec.rb:20:in `block (2 levels) in <main>'

     1.2) Failure/Error: @pid = Process.spawn(*@command, options)
          
          TypeError:
            no implicit conversion of nil into String
```
## 環境
rails 6.1.3.7
selenium-webdriver 4.8.2
webdrivers 5.2.0

## 該当のコード
```ruby:app/rspec/system/sample_spec.rb
require 'rails_helper'

RSpec.describe "Tasks", type: :system, js: true do

  before do
    driven_by :selenium_chrome_headless
  end
 
  scenario 'home画面に遷移する' do
    visit root_path
    .
    .
    .省略
  end

end
```
テストを実行すると、冒頭で記載したエラーが`visit root_path`の部分で発生しました。
```
     1.1) Failure/Error: visit root_path
          
          TypeError:
            no implicit conversion of nil into String
          # ./spec/system/tasks_spec.rb:20:in `block (2 levels) in <main>'

     1.2) Failure/Error: @pid = Process.spawn(*@command, options)
          
          TypeError:
            no implicit conversion of nil into String
```
他のテストでも`visit root_path`は使っていて問題はなかったので、なぜエラーが発生しているのか戸惑いました。
## 原因と対処法
__原因__
`gem selenium-webdriver '4.8.2'`で起こるバグのようです。
ブラウザを立ち上げた時にエラーが発生します。

参考：

https://stackoverflow.com/questions/75844511/rspec-rails-testing-warn-selenium-deprecation-and-typeerror-no-implicit-con

__対処法__
`gem selenium-webdriver '4.8.3'`以上をインストールする。
(もしくは`4.8.1`にダウングレードする)
```ruby:Gemfile
gem 'selenium-webdriver', '~> 4.8.3'
```
バージョンを変更した後、テストを実行すると非推奨通知が表示されます。
```
2023-04-27 20:09:03 WARN Selenium [:logger_info] Details on how to use and modify Selenium logger:
  https://selenium.dev/documentation/webdriver/troubleshooting/logging#ruby

2023-04-27 20:09:03 WARN Selenium [DEPRECATION] [:capabilities] The :capabilities parameter for Selenium::WebDriver::Chrome::Driver is deprecated. Use :options argument with an instance of Selenium::WebDriver::Chrome::Driver instead.
```
これを非表示にするには以下のような設定を追記します。
```ruby:rspec
before do
  driven_by :selenium_chrome_headless
  Selenium::WebDriver.logger.ignore :capabilities
end
#02 壊れたPCをモニター化して再利用する【準備】

<h2>壊れたPCの活用方法</h2>

![IMG_4895（大）.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/0f6c46ca-a3eb-3e17-8547-3b7d49f4bc72.jpeg)

皆さんは壊れたPCをどうしていますか？大体の方であれば修理に出したり、PCの使用年数が結構経っていれば新しく買う方もいるかと思います。 壊れて使わなくなったPCをモバイルモニターやディスプレイにして再利用する方法を紹介していきたいと思います。
この記事は準備編です。計画編をみたい方は[こちらのリンク](https://qiita.com/umashikate/items/e13a61b659bc3ea4085a)からアクセスできます。
初めて挑戦する方でも確実にできるように一つひとつ確認していきましょう。

<h2>〜前回の振り返り〜</h2>

<h4>必要なものを確認</h4>

1.壊れている又は使わないノートパソコン
2.LCDコントロール基盤
3.電源アダプタ
4.精密ドライバー

<h4>ノートパソコンの紹介</h4>
今回モニター化を行うノートパソコンは「ThinkPad X240」です。
<h4>作業時の注意点</h4>
作業に取り掛かる前のBIOSの設定変更。作業中の短絡（ショート）する可能性を下げてくれます。今回の作業は比較的問題はありませんが念のためです。
<h4>液晶を取り出す作業</h4>
ThinkPad X240の場合は液晶カバーがプラスチックの爪でとまっているだけだったので、簡単にパネルを取り外すことができました。 機種によってはここでプラスドライバーが必要になるかもしれません。部品が細かいので無くさないようにと怪我に気をつけましょう。
<h4>液晶の型番確認</h4>
LCDコントロール基盤を注文するときに必要な作業です。 液晶の型番は、液晶パネルの裏側に貼ってあるのでそこを確認しましょう。型番が確認できたら「Panelook.com」で液晶パネルの詳細を確認します。

[Panelook.com](http://www.panelook.com/index.php)
サイトの検索欄で型番を入力します。 このThinkPadの液晶の型番は「HB125WX1-200」なのでこちらを検索します。

確認する事項は以下の４つです。 1.Panel Size (モニターサイズ) 2.Resolution (画面解像度) 3.Lamp Type (照明のタイプ) 4.Signal Interface (接続のピン数)

ここからは準備（購入）編です

<h2>LCDコントロール基盤の注文</h2>

![Panelook2（大）.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/2c32dd46-0dcc-a61e-8163-40eecc5b7b30.jpeg)

[Panelook.com](http://www.panelook.com/index.php)のページより「ThinkPad X240」を検索しました。
このパソコンの各ステータスは
1.Panel Size (モニターサイズ)"12.5"
2.Resolution (画面解像度)"1366(RGB)×768, WXGA  125PPI" 
3.Lamp Type (照明のタイプ)"9S3P WLED , 15K hours , With LED Driver"
4.Signal Interface (接続のピン数)"eDP (1 Lane) , RBR (1.62G/lane) , 30 pins Connector"

![amazon注文画面.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/de77bbad-fcc7-1fbe-1ad8-08eca24bb338.jpeg)

LCDコントローラ基盤ですが専用の基盤を入れるケースもあったので、きれいに収納したい方は合わせて注文しても良いかもしれません。私はケースを自作してみたいので買わないことにしました。

<h2>電源供給ケーブルの注文</h2>

持ち運びできるようにUSBの昇圧ケーブルにしました。
これならモバイルバッテリーがあればどこでも使えるからです。
LCDコントロール基盤の規格に合った電源アダプタを選択しましょう。

![amazon注文画面2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/a8a20d16-0045-ad3a-43b1-4c09a64bc548.jpeg)

<h4>昇圧ケーブルとは</h4>

昇圧ケーブルには、昇圧型DC-DCコンバータが内蔵されています。この昇圧型DC-DCコンバータに電流が流れている状態からスイッチをOFFにすることで発生する高電圧を利用して昇圧させています。スイッチのONとOFFを高速に切り替えることで、元々流している電圧よりも高い電圧を作り出すことができます。

ここまで読んでいただきありがとうございました。
次投稿では実際に組み立てをしていきたいと思います。ぜひチェックしてみてください。

***

<h3>補足</h3>

<h4>昇圧ケーブルの仕組み</h4>

電圧を昇圧させるにはコイルの性質を利用します。コイルには急激な電流の変化が生じると、変化前の状態を維持しようとする力が働きます。
電気が流れていない状態からコイルに電流を流すと、電流を流させまいとしてエネルギーを蓄積して一定以上の電気は流れない性質があります。逆に電気が流れないようになると、それまで蓄積していたエネルギーを放出して元々入力されていた電気以上の電圧で電気を流す動きをします。これが昇圧ケーブルの仕組みです。

<h4>LCDコントローラ基盤とは</h4>

LCDコントローラ基盤は、液晶ディスプレイの制御に必要な回路が搭載された基盤です。液晶ディスプレイは、液晶素子に電気信号を与えることで画像を表示するため、LCDコントローラ基盤は液晶素子の電気信号を生成し、表示するための制御回路を含んでいます。 LCDコントローラ基盤には、ディスプレイの解像度、表示色数、表示方法（表示方式）、ディスプレイの種類（TFT、STN、TNなど）に応じたコントローラが使われます。また、LCDコントローラ基盤には、ディスプレイの信号入力（VGA、HDMI、DVIなど）に対応した入力端子が備わっていることが一般的で、液晶ディスプレイの制御に必要な要素が集約された重要な部品であり、様々な電子機器の中で広く利用されています。
docker compose upした際に「failed to solve with frontend dockerfile.v0」的なエラーが出る件

# 初めに
表題のとおり、docker compose upやbuildを行った際に発生するエラーの解消方法について記載します。
環境は以下
```
OS：Windows11
```
エラーは以下
```
failed to solve: rpc error: 
code = Unknown desc = failed to solve with frontend dockerfile.v0: 
failed to create LLB definition:
rpc error: code = Unknown desc = error getting credentials - err: docker-credential-desktop
resolves to executable in current directory (.\docker-credential-desktop), out: ``
```

# 解決方法
以下に格納されているconfig.jsonを編集する。
```
C:\Users\[ユーザー名]\.docker\config.json
```
"credsStore": "desktop"の記述を以下に変更する。
```
{
　// sを削除、以下に変更
   "credStore": "desktop"

}
```

# 終わり
原因は調べてないです！！！！！
なにかとDockerで環境つくるとトラブってる気がしています。



# 参考
https://forums.docker.com/t/docker-credential-desktop-exe-executable-file-not-found-in-path-using-wsl2/100225
zshに設定している個人的な便利な関数、alias

随時更新していきます。

## 前提条件

Ubuntu(WSL)とMacで使っていますが、一部はMacのみでしか動かない場合があります

## ディレクトリを ディレクトリ名.zip でzipファイルにする

※ファイルでも動きます

`zipp ディレクトリ名`

```shell
function zipp() {
    DIR="$1"
    command rm -f "${DIR}.zip"
    command zip -r "${DIR}.zip" "$DIR" -x "*.DS_Store"
}
```

## ディレクトリまたはファイルをzipファイルにしつつ、自動生成したパスワードもかける

※ファイルに対しても使いやすいようにファイルを想定して拡張子をzipに変更します

`ppap ディレクトリ名またはファイル名`

```shell
function ppap() {
    PASSWORD=`openssl rand -base64 9`
    FILENAME=${1%.*}
    command rm -f "${FILENAME}.zip"
    command zip -P "${PASSWORD}" -r "${FILENAME}.zip" "$1" -x "*.DS_Store"
    echo "[パスワード]"
    echo "$PASSWORD"
}

```

## シェルスクリプトの設定を変更した時に再読込

`reload`

```shell
alias reload='exec $SHELL'
```
ELB概要２

* LBはリスナーを複数持てる。（HTTP、HTTPSなど）
* リスナーはルールを複数持てる（HTTPヘッダー、ソースIPアドレスなど優先度も設定可能）
* リスナーのルールは通常デフォルトアクションとして通信をターゲットグループに転送する。
* ターゲットグループは複数のターゲットを持つ。
* ターゲットグループはターゲットに指定したポート番号で転送を行う。
* ターゲットはEC2インスタンス、Lambda、IPアドレスなどを設定できる。

# ELB　スティッキーセッション機能
通常、ELBは複数のECインスタンスにユーザからアクセスをランダムに振り分ける。
→アプリケーションがセッション情報をEC2インスタンスに保持する場合、保持しているEC2インスタンスにリクエストが振り分けられる必要がある。
↓
スティッキーセッション
特定のユーザからのアクセスはすべて同じEC2インスタンスに振り分ける。
（クッキーの有効期限内は特定のターゲットのみに通信を振り分けられる。）
期間ベース：ALBがクッキー生成
アプリケーションベース：アプリケーションがクッキーを生成

# ステートレス設計、セッションストアの概念
セッション情報がEC2内部にあるとデータ損失の可能性がある。（ステートレス（EC2内部には情報を持たないことが推奨される））
↓
セッションストア：セッション情報を外部に保存する。
BIOSの画面が表示されなかった問題についてのメモ

# 背景
BIOSを確認しなければならない問題に直面したため、BIOSを設定しようとした。しかしBIOSの画面が表示されず、ずっと困り果てていた。

# 原因
- PCとディスプレイを正しく接続できていなかったことが原因。
- 接続はHDMLケーブルを使用していたが、マザーボードに接続しなければいけなかった。

# 結果
HDMLケーブルを、マザーボードのHDML端子に接続し直したところ、BIOSへの画面が表示された。

# 状況（解決前）
1. PCの電源をシャットダウンする。
1. 再度、PCの電源を入れる。
1. 電源を入れた直後、F2キーを押し、BIOSへ入ろうとする。この時、ディスプレイの画面は真っ黒で、メーカーのロゴすら、ディスプレイに表示されていなかった。
1. 長時間待っても、ディスプレイの画面は真っ暗なので、電源をシャットダウンする。

# 状況（解決後）
1. PCの電源をシャットダウンする。
1. 再度、PCの電源を入れる。
1. 電源を入れた直後、F2キーを押し、BIOSへ入ることができた。

# PCの情報
メーカー：DELL
OS：Windosw10
システムの種類：64ビットオペレーティングシステム

# この記事は誰向けの記事か？
- BIOS設定したいが、BIOSの画面が表示されず、困っている人

# 環境
- OS：Windows10

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。
CSSだけで簡易的なくるくる回転するローディングアニメーション

HTMLとCSSだけでくるくる回転するアニメーションを超簡易的に実装する方法です。なにかをローディング中にごまかすためのよくある表示です。テキスト数行だけでの実装です。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRYEjxg" data-user="suzuki-navi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/suzuki-navi/pen/GRYEjxg">
  Untitled</a> by suzuki-navi (<a href="https://codepen.io/suzuki-navi">@suzuki-navi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```html
<span class="progress-circular">|</span>
```

```css
.progress-circular {
  display: inline-block; /* これがないと回転してくれない */
  animation: rotate-z 2s linear infinite; /* 2秒で1回転 */
}
@keyframes rotate-z {
  from { transform: rotateZ(0deg); }
  to { transform: rotateZ(360deg); }
}
```

Vuetifyの `v-progress-circular` みたいなのが使えればいいのですが、そうは行かない場合にどうぞ。
AIにイラストを作ってもらってゲーム画面みたいなポートフォリオを作成してみた

最近、画像生成AIで遊んでいて「これを使って、何か作れないか？」と思い立ち、
簡単なポートフォリオサイトを作ってみました。

で、作ってみたのがこちら。↓

![kookeLab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387747/2c8c0c66-f96e-10e8-c72e-4f7d3636011b.gif)

画像はAIで、viewはコードで書いています。
文字だけのポートフォリオよりもオシャレになった！

ということで、簡単に作成の流れを説明します。

## 作成の流れ
1.にじジャーニーを使って好きな画像を作ってもらう
2.作ってもらった画像を使って、viewを作る
3.公開する

以上！

## 1.にじジャーニーを使って好きな画像を作ってもらう
まず初めにAIに画像を作成してもらいます。
今回は、Midjourneyという画像生成AIの派生版　**「にじジャーニー」**　というAIを使用しました。


https://nijijourney.com/ja/

**■ にじジャーニーとは？**
Midjourney（ミッドジャーニー）という画像生成AIを「アニメ風二次元イラストに特化させたモデル」です。
キーワードを入力するだけで、それっぽいイラストを作成してくれて、有料版では作成したイラストは、基本的に自分のものになるそうです。（無料版では、同モデルを使用した旨を記載する利用規約があるっぽいです）（追記で現在無料版でのイラストの作成は停止中だそうです）

**■ 使用方法**
以下を参考にしました。

https://wowokurage.com/midjourney/nijijourney

**■ 作ってもらったもの**
色々試行錯誤した上で、以下の2枚を作成してもらいました。
とりあえず「キャラクター」と「背景」を、好みに合わせて作ってもらいました。
![スクリーンショット 2023-04-27 22.01.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387747/b06544af-0327-b9d0-0cd4-c5e1445cede3.png)
す、すごい、、、
なんかおしゃれでサイバーパンク的なエモいいい感じの画像を作ってくれました。（語彙力）

ドット絵調の背景がカッコよかったので、これを元にゲーム調のサイトを作っていきます。
この画像を元に想像を働かせて、ポートフォリオを作っていきます。

## 2.作ってもらった画像を使って、viewを作る
nuxt3で作りました。

https://github.com/koo-ke/kookeLab

画像がビット調なので、フォントもビット調に。
DotGothic16を使用しています。

https://fonts.google.com/specimen/DotGothic16

PC幅では、メニューをcssで点滅させたりなんかしてゲームっぽさを演出。
![スクリーンショット 2023-04-27 21.51.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387747/cf466a4f-3fb0-8e4d-88b7-a4b7d580c6c9.png)

完成！

## つくってみて
**画像生成AI**が本当にすごいなぁと思いました。
サイト制作に関して、僕みたいなセンスのない人間が何も考えず作成すると、**なんとなくモサっとした言いようのないダサダササイトが出来上がってしまう**のですが、画像生成AIを駆使して、気に入った画像に合わせたサイトを作ってみると、一気にオリジナル感が出て良いなと思いました。

以上です！
Spring bootのonclickイベントで文字列の値が取れない。

# はじめに
普段はフロントエンドを主で触っていますが、今回は初めてJavaのタスクに取り組むことになりました。

Spring bootで開発を進めています。
その際、若干はまったところがあったので、備忘録。

# 起こったこと

以下の方法では、intは値として取れるが、stringは取れない。

```html
<td class="id-content" th:text="*{hogeId}"></td>
  <td th:text="*{hoge}"></td>
	<a 
		class="view_icon" 
		href="#" 
		th:onclick="|javascript:openEditModal(*{hogeId}, *{hoge}|"
	>
省略 *hogeIdはint*
```                  

# 原因
Thymeleafのテンプレートで文字列の値をJavaScriptのonclick属性内で使用しようとしたことが原因である。 onclick属性はJavaScriptのコードを含むため、セキュリティ上の理由から、onclick属性内で文字列を直接参照することは許可されていない。

# 対処法
Thymeleafの```th:data-*```属性を使用して、JavaScript関数に渡す引数を設定する。

その値をthis.getAttributeで取得する。

```html
<a 
    class="view_icon" 
    href="#"  
    th:hoge="*{hoge}"
    th:onclick="|javascript:openEditModal( *{hogeId}, this.getAttribute('hoge')|"
  >
```



# 備考
```th:onclick```を使う際は、```"|javascript: ~~~ |"```が必要となる。

また、```th:onclick```をなぜ使ったのかに対しては、Javaのコントローラークラスで処理したデータをHTMLに反映させているからである。