OmniAICreator/Qiita-1.07M huggingface dataset:
Python lambda関数、使いどころはここ！1行で書けるアロー関数風の魔法

## はじめに
こんにちは、Pythonエンジニアの皆さん！今回は、Pythonの中でも特に便利で魔法のような機能を持つlambda関数について、その使いどころと魅力をご紹介します。lambda関数は、1行で書けるアロー関数風の短い関数で、コードをよりシンプルかつ読みやすくする強力なツールです。

## lambda関数とは？

lambda関数は、Pythonの匿名関数です。通常の関数定義（`def`キーワードを使用）とは異なり、名前を持たず、1行で記述できます。構文は以下の通りです：

```python
lambda 引数: 式
```

## lambda関数の魅力

1. **簡潔性**: 1行で関数を定義できるため、コードがスッキリします。
2. **一時的な使用**: 一度しか使わない小さな関数に最適です。
3. **可読性**: 適切に使用すれば、コードの意図が明確になります。
4. **関数型プログラミング**: `map()`、`filter()`、`reduce()`などの関数と相性が良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/ef58c0a7-c902-0aa1-9f73-1a112faa5957.png)

## 使いどころベスト5

それでは、lambda関数の具体的な使用例を見ていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/6b73f73f-1cf7-9a75-053c-20c8d28ca0e8.png)

### 1. リストのソート

```python
fruits = ['apple', 'banana', 'cherry', 'date']
sorted_fruits = sorted(fruits, key=lambda x: len(x))
print(sorted_fruits)  # ['date', 'apple', 'banana', 'cherry']
```

この例では、フルーツのリストを文字列の長さでソートしています。`lambda x: len(x)`は各要素の長さを返す関数です。

### 2. リスト内の要素の変換

```python
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # [1, 4, 9, 16, 25]
```

`map()`関数とlambda関数を組み合わせて、リスト内の各数値を二乗しています。

### 3. フィルタリング

```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # [2, 4, 6, 8, 10]
```

`filter()`関数とlambda関数を使用して、偶数のみを抽出しています。

### 4. 辞書のソート

```python
people = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
sorted_people = sorted(people, key=lambda x: x['age'])
print(sorted_people)  # [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
```

辞書のリストを、'age'キーの値でソートしています。

### 5. 条件付き式

```python
get_status = lambda age: "未成年" if age < 20 else "成人"
print(get_status(18))  # 未成年
print(get_status(25))  # 成人
```

年齢に基づいて状態を返す簡単な関数をlambdaで作成しています。

## 注意点

lambda関数は便利ですが、複雑な処理には向いていません。可読性が下がる場合は、通常の関数定義を使用することをおすすめします。

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/f40aa255-8cd3-67bd-9dec-c8bc10cddd7e.png)

lambda関数は、Pythonプログラミングにおける小さな魔法です。適切に使用すれば、コードをより簡潔で読みやすくすることができます。ただし、複雑な処理や再利用性が必要な場合は、通常の関数定義を選択しましょう。

皆さんも、コードの中にこの小さな魔法を取り入れて、より洗練されたPythonistaになりましょう！

Happy Coding!

## 参考情報

lambda関数についてさらに深く学びたい方は、以下の公式ドキュメントを参照してください：

1. [Python公式ドキュメント - ラムダ式](https://docs.python.org/ja/3/tutorial/controlflow.html#lambda-expressions)
   - lambda関数の基本的な説明と構文について詳しく解説されています。

2. [Python公式ドキュメント - 関数定義](https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions)
   - lambda関数を含む、Pythonの関数定義全般について説明されています。

3. [PEP 8 - Pythonコードのスタイルガイド](https://pep8-ja.readthedocs.io/ja/latest/)
   - lambda関数を含むPythonコードの書き方に関する公式のスタイルガイドです。可読性の高いコードを書くための指針が示されています。

これらの公式ドキュメントを参照することで、lambda関数の使用方法や適切な使用場面についてより深い理解が得られるでしょう。また、Pythonコミュニティで広く受け入れられているベストプラクティスを学ぶこともできます。
[2024年6月~] Evilのインストールでエラー (easkを入れる)

# Evilのインストールでエラー
https://github.com/emacs-evil/evil

Evilを`make`すると, 2024年6月ごろから以下のようなエラーが出るようになった.

```console
~/.emacs.d/el-get/evil $ make
eask compile
make: eask: No such file or directory
make: *** [compile] Error 1
```

`eask`なるものがなく, エラーとなったようである.
`Makefile`としては下記の部分が該当している.

https://github.com/emacs-evil/evil/blob/5db0bdc7dcd9300b983526d37cbe480f35e36211/Makefile#L9

# 対処方法

`eask`とは

https://emacs-eask.github.io/

のことのようである.

https://emacs-eask.github.io/Getting-Started/Install-Eask/

にインストール方法が載っているが, `npm`だと下記のとおり.

```shell
npm install -g @emacs-eask/cli
```

# ついでにdocやinfoについても...

https://github.com/emacs-evil/evil/blob/5db0bdc7dcd9300b983526d37cbe480f35e36211/doc/Makefile#L7

また, 上記のように`doc`や`info`の`make`ではsphinxを使っているようである.

https://www.sphinx-doc.org/ja/master

必要に応じてsphinxもインストールする.

https://www.sphinx-doc.org/ja/master/usage/installation.html

にインストール方法が載っているが, `pipx`だと下記のとおり.

```shell
pipx install sphinx
```
高齢者を熱中症から守りたい！熱中症警戒アラートbot

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819170/a7c9c222-980a-8de3-06a2-8785977c7087.png)


# 高齢者を熱中症から守りたい！熱中症アラートつぶやきを自動化するツールを作りたい！！

介護関係の仕事に従事しています。
こういった作業に関しては全くの素人ですが、今回、チャレンジしようと思いました。

開始しようとした経緯として、高齢者は体調の変化に気づきにくく、夏の時期に熱中症で救急搬送されるご利用者さまも多数いらっしゃいます。そんな方を熱中症から守るためにツールを作成したいと思いました。

このツールのターゲットはご利用者さま本人というよりは、勤務しているスタッフがメインターゲットになるかと思います。スタッフに伝えることで、ご利用者さまに対してサービス利用中に水分補給を促すことや、帰りの送迎でご自宅前まで送った後に、暑いのでエアコンをつけて下さいと声掛けすることがメインの目的となっております。

しかし、最近の高齢者をなめてはいけません！！
スマホを使いこなしている方は少ないですが、使いこなしている方はLINEで家族に写真で送るだけでなく、Googleの有料コンテンツで写真を撮影するだけで、花など身の回りのものでわからないことを調べてくれるコンテンツを使いこなす80オーバーの高齢者もいるんです。
恐るべし.....

さて、目的もはっきりした所で作成に取り掛かりましたが...




https://x.com/isocchi1123/status/1823303611788795982

# うまくできません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819170/6017122a-d8e4-2667-4494-a1526ba4a1ac.png)

## 修正すればするほど深みにはまりわからなくなってしまいました。

これに関してはLINEの設定がおかしいということはわかりました。とりあえずそこは修正しましたが、完成には至っておりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819170/901394d6-543a-29ed-32e3-46610f67f11e.png)

APIバンクを探したり色々と試行錯誤しましたがうまくいきませんでした。

AIの力も借りましたが知識不足でわからない＆上限になってしまう
(；ﾟДﾟ)

![スクリーンショット 2024-08-13 201241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819170/d9def617-2c71-ee33-2d3c-b15740c17fdf.png)

多分、人生でこんなに業務以外でパソコンに向き合ったのは初めてです。

高齢者は気温の変化で体調不良になるので、情報発信することでエアコンを使用して貰ったり、水分・塩分補給に役立ててもらえればと思いましたが残念です。

次回に向けて出直します...


がしかし....



でもこのまま終わるのも悔しかったので

https://x.com/isocchi1123/status/1823336117556625515

メッセージに対して猫の画像リンクを送信するものを作りました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819170/a0774486-b30e-f279-448c-c103df3b6f99.png)


(名前がお料理botになっているのはお許し下さい）
やりたいことはできていないので修行します...

記事を見ている方でアドバイスがございましらたら頂けましたら幸いです。
AWS Backupの最新機能「論理的にエアギャップされたボールト」について

（論理的にエアギャップされたボールト…？）

以下の最新情報を見かけたのでBackupの基本と最新機能について書いてみます。

AWS Backup 論理的にエアギャップされたボールトの一般提供開始を発表（直訳）
https://aws.amazon.com/about-aws/whats-new/2024/08/general-availability-aws-backup-logically-air-gapped-vault/

# ■AWS Backupとは
まずAWS Backupについてですが、
AWS環境における一元的なデータバックアップソリューションという位置付けです。

基本的な機能と利点を紹介します。

```
・一元管理
EC2、EBS、RDS、S3など、複数サービスにまたがるバックアップを一元管理できます。

・自動化
バックアップスケジュールの設定を自動化することで、定期的かつ計画的なバックアップが可能です。

・復元の迅速化
万が一の障害発生時に、迅速にデータを復元できる点も大きな魅力です。
これにより、ダウンタイムを最小限に抑えることが可能です。
```

# ■補足
ここで出てくるワードについて先に少し補足します

:::note info

- **バックアッププランとは？**: 
バックアッププランは、どのリソースをどのタイミングで、どのようにバックアップするかを定義する、いわば「バックアップの設計図」です。AWS Backupでは、このバックアッププランを作成することで、自動的かつ計画的にデータを保護することができます。

:::

:::note info

- **ボールトとは？**: 
ボールトは、バックアッププランに基づいて作成されたバックアップデータを実際に保管するための「セキュアなストレージコンテナ」です。バックアップデータは、このボールトに保存され、必要に応じて復元や共有が可能です。

:::

# ■基本的な使い方
一番シンプルな使い方は以下の4項目になってくると思います。
知ってる人は読み飛ばしてください！

```
1. バックアッププランの作成: 
AWS Backupコンソールにログインし、新しいバックアッププランを作成します。
プランには、バックアップするリソースの種類、頻度、保存期間を指定できます。

2. リソースの選択: 
バックアップ対象のリソースを選択します。
EC2インスタンス、EBSボリューム、RDSデータベースなど、対応するリソースが多数あります。

3. スケジュールの設定: 
バックアップの実行スケジュールを設定します。
毎日、毎週、毎月など、ビジネスニーズに応じた柔軟なスケジュールが組めます。

4. 通知の設定: 
バックアップ成功時や失敗時に通知を受け取るように設定できます。
これにより、バックアッププロセスの状況をリアルタイムで把握できます。
```

簡単ですね！

# ■今回のアップデートについて
今回のAWS Backupのアップデートは「論理的にエアギャップされたボールト」の導入です。

？という感じですが… ↓

:::note info
- **まず論理的エアギャップの意味**
::: 

エアギャップという言葉が聞き慣れなかったのですが、以下の通りです。

```
「エアギャップ（Air Gap）」は、セキュリティの観点からデータやシステムを物理的に、
または論理的に他のネットワークやシステムから隔離する手法を指します。
もともとは、非常に高いセキュリティを要求される環境で使用されており、
たとえば、機密情報を含むシステムをインターネットから完全に切り離すことで、
外部からのアクセスや攻撃を物理的に不可能にする方法が含まれます。
```

なるほど。

そしてAWSで行われる事としては、バックアップデータがデフォルトでロックされ、AWS所有のキーによって暗号化されるとの事。
これにより、データが外部からの攻撃や改ざんを受けるリスクが大幅に低減されます。
（物理的なネットワーク接続みたいなものが不要となる）

なおかつ特にリージョンの縛りはありませんし、通常のAWS Backup同様に主要なサービスで利用できます。

# ■コンソールで見てみましょう

:::note info
**論理的にエアギャップされたボールトの作成**
:::

1. AWS Backupコンソールにログインし、ボールトの作成画面に進みます。
2. 「論理的にエアギャップされたボールト」を選択し、名前と設定を入力します。暗号化キーやアクセス制御もこの段階で設定可能です。

![作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/a48f5e25-4248-afcc-989d-10a1b65575db.png)

この右のやつですね。
作成後、即ロックされました

![ロック済み20240812144611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/167fe8f3-26df-e762-e04e-99a15934a719.png)

それぞれの項目についても少し補足です！

:::note info
ロック済み - コンプライアンスモード:
→ このモードでは、ボールトに対するロックが適用されており、設定された保護ポリシーを変更することができない状態です。
:::

このため、特定の保護期間中にバックアップデータが削除されたり、変更されたりすることを防ぎます。

:::note info
ロックはイミュータブル（変更不可）:
→ 「イミュータブル」という表現は、ボールトが変更不可であることを示しています。
:::
この状態では、保護ポリシーを緩和することができないため、データの改ざんや不正な削除からの保護が強化されています。

# ■最後に
とても頑丈なバックアップという所でしたが、昨今の事故や事件などを考えると必要とされるものでしょう。
またAWS Resource Access Manager (RAM)を使用して、他のAWSアカウントとボールトを共有する事も可能です。
開発に役立つ！作業効率を劇的に向上させるGoogle Chromeの便利な拡張機能4選

# はじめに
Web開発やデザイン作業を効率化するために、Google Chromeには多くの拡張機能が提供されています。
今回は、特におすすめの4つの拡張機能を紹介します。
これらを活用することで、日々の作業がよりスムーズに進むこと間違いなしです。

# GoFullPage - Full Page Screen Capture

https://chromewebstore.google.com/detail/gofullpage-full-page-scre/fdpohaocaechififmbbbbbknoalclacl

用途: Webページ全体のスクリーンショットを簡単にキャプチャできる。

**主な特徴**
- ワンクリックでページ全体のスクリーンショットを取得
- 取得したスクリーンショットはPDFやPNG形式で保存可能
- 簡単な操作で、長いページでも全体を見渡せる画像が手に入る

**使用例**
クライアントへのデザイン確認用として、全体の見た目を共有。
Webサイトのフルページスクリーンショットを資料として保存しておく。


:::note info
デベロッパーモードからrun commandでフルスクリーンショットを撮ることもできます。
ただ、この拡張機能をピン留めしておくだけでスクロールしないと全体が見えないような画面でも、ボタン一つで上から下までキャプチャが取得でき大変便利です。

:::

# page-ruler

https://chromewebstore.google.com/detail/page-ruler/jcbmcnpepaddcedmjdcmhbekjhbfnlff

用途: Webページ上で特定の要素のサイズを測定する。

**主な特徴**
- 任意の部分をドラッグするだけで、その要素の高さ・幅を即座に計測
- ガイドラインを表示して、レイアウトの微調整に役立てることが可能
- ピクセル単位での正確な計測が可能で、デザインの整合性チェックに最適

**使用例**
デザインやコーディング時の要素のサイズ確認に活用。
レスポンシブデザインの検証時に要素のサイズをチェック。

:::note info
これはcssでおおよその空白を考えたりする際に使うことが多いです。
:::

# Responsive Viewer

https://chromewebstore.google.com/detail/responsive-viewer/inmopeiepgfljkpkidclfgbgbmfcennb

用途: Webページのレスポンシブデザインを確認する。

**主な特徴**
- 様々なデバイスの表示画面を一度に確認できる
- カスタムデバイスの追加や、任意の画面サイズでの表示チェックが可能
- デバイス間でのデザインの一貫性を確認するのに役立つ

**使用例**
開発中のWebサイトが各デバイスで正しく表示されるかを一括確認。
クライアントへのデザイン確認時に、マルチデバイス対応状況を示す。

# ColorZilla

https://chromewebstore.google.com/detail/colorzilla/bhlhnicpbhignbdhedgjhgdocnmhomnp

用途: Webページ上の任意の色を取得し、カラーピッカーとして使用。

**主な特徴**
- ピクセル単位で正確なカラーコードを取得可能
- カラー履歴機能があり、過去に選んだ色を再利用できる
- ページ上のグラデーション情報を取得することも可能

**使用例**
クライアントのブランドカラーをWebデザインに反映させる際に便利。
デザイン制作時に、他のサイトからインスピレーションを得るためのカラー確認に使用。

:::note info
色にこだわりのあるデザインを作成する際にとても便利です。
操作も直感的にできるようになっているので非常に使いやすいです。
:::


# まとめ
これらの拡張機能を活用することで、Web開発やデザイン作業の効率が大幅に向上します。
それぞれのツールをぜひ試してみて、作業の質とスピードを向上させてください。
皆さんの作業が少しでも快適になることを願っています！
読んでいただきありがとうございます。
ICML2024の量子化・枝刈り論文

# 概要

この記事では、[ICML2024](https://icml.cc/Conferences/2024)の量子化・枝刈り論文を紹介します。[^1]

[^1]: 画像や数式は論文から引用しています。

# Outlier-aware Slicing for Post-Training Quantization in Vision Transformer

- https://openreview.net/forum?id=Uh5XN9d2J4

- 概要：PTQの改善
- 新規性："Reconstraction granularity"の導入
- キモ：量子化誤差最適化の粒度は、Transformer-likeは粗く、それ以外は細かくする。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/6b38a4ac-97a6-e362-2ec6-15af5ec9924d.png)


# ERQ: Error Reduction for Post-Training Quantization of Vision Transformers

- https://openreview.net/forum?id=jKUWlgra9b

- 概要：PTQの改良
- キモ：Aqerは(8)で重みを補正する。Wqerではチャネル毎に丸めの向きを最適化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/5f5914f0-7b78-bd04-d4b0-de688e91fe44.png)


# LayerMerge: Neural Network Depth Compression through Layer Pruning and Merging

- https://openreview.net/forum?id=uDoy7AGvEC

- 概要：DNNのレイヤをマージして軽量化する
- 新規性：Fig.2 のようなマージを最適に求める
- キモ：(4)式と動的計画法で効率的に最適化問題を解く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/9989db4d-0944-3d56-0af2-1f1fa125840e.png)


# Pruner-Zero: Evolving Symbolic Pruning Metric From Scratch for Large Language Models

- https://openreview.net/forum?id=1tRLxQzdep

- 概要：枝刈りの指標
- 新規性：演算の組み合わせの最適化で指標を探索する点
- キモ：Table 10を組み合わせた指標から、進化的アルゴで最適な組み合わせを探索する。スコアはLlama-2から実際に刈って確かめた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/55c1761a-d8a0-a45b-e5c0-ddd57c958929.png)
社内でGrowiを立ち上げてみた（補足その2）

# はじめに
https://qiita.com/cohpen/items/d307dfb8b540e3976d37

でどうにかこうにか社内でGrowiの運用を始めたのはよかったのですが、Growiのバージョンアップを行う必要がでました。また、蓄積したWikiのデータをバックアップ・リストアする手段も用意しなければなりません。本番環境で作業ミスってみんなが折角入れてくれたノウハウ集を失ってしまうと<del>恐ろしいお仕置きが</del>たまりませんから、練習用Growiを用意してそちらで手順を予行演習することにしました。（え？先に練習してから本番運用しろ？デスヨネー）
# 本番環境に間借り（？）
最初に試したのは、本番環境のホストにもう一つGrowiサーバーを立てるという方法です。こちらも設定できたのですが、dockerのコンテナやイメージが乱立することになり間違って事故を起こす可能性が高いので、この方法は【全く】お勧めしません。こういうこともしてみました、という紹介です。
## Growi2の作成
/opt/growi で本番環境が立ち上がっているとします。
/opt/growi2 というディレクトリに/opt/growi以下のファイルを丸ごとコピーします。そして
/opt/growi2/docker-compose.yml ファイルの
```
services:
  app:
    ports:
      - 3000:3000
```
の　3000:3000　を　3010:3000
と修正し、
```
$ cd /opt/growi2
$ sudo docker-compose up -d
```
でgrowi2を起動します。ブラウザから
http://192.168.0.10:3010/
でアクセスするとgrowi2の方にアクセスできます。（192.168.0.10はGrowiを起動しているホストのIPアドレス）
/opt/growi2の方をあれこれいじって練習することができました。（うっかり本番環境のGrowiをdocker-compose, dockerコマンドでいじらないように）

本番の方にアクセスする場合は3000番ポートへ
http://192.168.0.10:3000/
# 別のUbuntu Server上に作成
独立したUbuntu Serverが利用できるであればそちらに本番と同じ構成で練習用Growiを立ち上げるのが楽だと思います。IT部門からもう一つサーバーを借りようかと思ったのですが、費用負担が発生するので選択肢から外しました。
# 自分のWindowsPC上で作成
結局、自分のWindowsPCに仮想環境のGrowiを構築し、自分専用の練習環境を作りました。
仮想環境ならば他に影響は与えませんし、スナップショットを取っておけば元に戻すのも簡単なので大胆な実験ができます。Ubuntuのセットアップ経験も積むことができます。
## VirtualBoxのインストール
仮想環境として使い慣れているVirtualBoxを利用しましたが、WSL2の方が簡単かも？VirtualBoxは下記からダウンロードしてインストールします。

https://www.virtualbox.org/
## Ubuntuのインストール
こちらを参考にどうぞ。

https://qiita.com/HirMtsd/items/225c20b77a7cd5194834

Ubuntu DesktopではなくUbuntu Serverの方をインストールしました。（Ubuntu Desktopはファイルサイズも大きいしメモリ消費も多いため）

[補足] 最新のUbuntu Server 24.04 LTS上でGrowiをdocker-composeで設定しようとしたらエラーが出て立ち上げられませんでした。Ubuntu Server 22.04.4 LTSで同じことをやったらすんなり立ち上がりました。（2024/8/12現在）
こういう時、仮想環境は楽でいいですね。

## VirtualBoxのネットワーク設定
ホストWindowsからVirtualBox内のUbuntuにアクセスするためポートフォワーディング設定を行います。
![Network.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692824/3a9891b2-3bc7-2e19-d9b7-86c2ae18641c.png)
設定＞ネットワーク＞アダプター1＞高度　を開いてポートフォワーディングをクリック

![port-forwarding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692824/7ef357ea-cee7-a296-daec-3ab74ebece08.png)
+アイコンを押して、
SSHはホストポート3022, ゲストポート22
httpはホストポート3030, ゲストポート3000
を設定します。
SSHはホストWindowsのターミナルソフトからUbuntuにログインするのに使用
　IPアドレス：127.0.0.1、ポート：3022 でSSHログイン
httpはホストWindowsのブラウザからUbuntu上のGrowiにアクセスするのに使用
　http://127.0.0.1:3030 でGrowiにログイン→あれ？アクセスできなくなった？ブラウザの脆弱性対策のせい？(2024/8/16確認中)
## ツールのインストール
SSHでターミナルからUbuntuにログインし、作業します。
git, curl, docker, docker-composeその他必要なツールをUbuntu Serverにインストール
## Ubuntu上でproxyの設定
これは本番環境と同じ作業です。
## Growiの設定
これも本番環境と同じ作業です。
## 本番環境からのデータのコピー
本番環境からデータを自分のWindowsPCに持ってきて、ホストWindowsから仮想環境にコピーします。VirtualBoxの共有フォルダを設定するか、drag&dropでコピーするとか。
## WindowsからのGrowiへのアクセス
ホストPCのWindowsのブラウザから
http://172.0.0.1:3030/
で仮想環境のGrowiにアクセスできます。

これで練習用Growiができましたので、docker-compose、dockerコマンドをあれこれ使ってGrowi, Elasticsearch, mongoDBのコンテナを作ったり消したり、バージョン変更手順を試したり、バックアップデータからのリストア実験をしたりしました。

やらかして本番環境を壊しても現バージョンのGrowiをスクラッチから再構成し、バックアップデータからコンテンツを復元できるという自信が持てましたし、万一のバックアップ環境にもなります。（手順はメモして残しておきましょう）
useStateとChakraUlを使って削除するときにAlertDialogを出しながらリッチに削除する

reactで値を削除するときにChakra-uiのalert dialogで削除の確認を出してから削除するというのがuiもリッチに削除しつつあまり処理も複雑ではなかったので紹介します。
# 処理の流れ
ユーザーが削除したい値の削除ボタンを押す
↓
`handleClickDelete`が発火してその値のidをステートに保持、同時にalert dialogを表示する
↓
alert dialogが表示され、削除の確認
↓
削除ボタンが押されると`onClickDelete`が発火
↓
削除

# 具体的な処理
以下をインポートしてください。
内容はchakraUI公式から持ってきています。
```
import { 
    AlertDialog,
    AlertDialogBody,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogContent,
    AlertDialogOverlay,
    AlertDialogCloseButton,
    useDisclosure,
    Button,} from "@chakra-ui/react"
```

またstateなどは以下にしてください。
ちなみにこれはOpenの判定とキャンセルするときにキャンセルボタンにフォーカスが当たるようにするためのものです。
```
//削除ボタンの管理
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef<HTMLButtonElement>(null);

//削除ボタンを押したときにクエリパラメータを保持するためのステート
const [selectId,setSelectId] = useState<number | null>();
```

またAlert Dialogの内容は以下にしてください。
削除ボタンを押した際に`onClickDelete`を発火させるようにしています。
こちらも公式の内容を若干変更しているのみです。
```
<AlertDialog
        isOpen={isOpen}
        leastDestructiveRef={cancelRef}
        onClose={onClose}
      >
        <AlertDialogOverlay>
          <AlertDialogContent>
            <AlertDialogHeader fontSize='lg' fontWeight='bold'>
              削除の確認
            </AlertDialogHeader>

            <AlertDialogBody>
              本当に削除しますか？
            </AlertDialogBody>

            <AlertDialogFooter>
              <Button ref={cancelRef} onClick={onClose}>
                キャンセル
              </Button>
              <Button colorScheme='red' onClick={onClickDelete} ml={3}>
                削除
              </Button>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialogOverlay>
      </AlertDialog>
```

以下からその流れを書いていきます。
ページ内に削除ボタンを作成するとして、そのときにすぐ`onClickDelete`を発火させるのではなく、`handleClickDelete`を発火させるようにしてください。
またそのときにidを渡すようにします。(例としてuser)
```
~中略~
<Button onClick={()=>handleClickDelete(user.id)}>削除</Button>
```
`handleClickDelete`の処理としては以下としてください。
このときにstateに押された時のidを割り振って保持するようにして、`onOpen()`を呼びます。
```
const handleClickDelete = (id:number)=>{
     setSelectId(id)
    onOpen()
}
```
そうすると、ChakraUIが提供している`useDisclosure()`で開いているかを判定してモーダルを開くようになるので、先ほどのAlert Dialogが表示されます。
```
<AlertDialog
        isOpen={isOpen}
        leastDestructiveRef={cancelRef}
        onClose={onClose}
      >
```
開いたときに削除するボタンを押すことでonClickDeleteが発火します。
```
const onClickDelete = async()=>{
    if (selectId !== null) {
        try {
          const response = await fetch(`/user/${selectId}`, {
            method: "DELETE",
          });
          
          if (response.ok) {
            setUsers(users.filter((user) => user.id !== selectId));
            onClose(); // ダイアログを閉じる
          } else {
            console.error("削除に失敗しました");
          }
        } catch (error) {
          console.error( error);
        }
      }
    }
```
処理としてはselectIdがあるときにクエリパラメータで所得したidのuserを削除して、responseが返ってきたときにそのuserのid以外を残して`filter`します。
ちなみにこの`filter`という関数はtrueが返ってきた値のみを残して新しく配列を作るメソッドです。
そしてその後に`onClose()`でモーダルを閉じます。

この流れで削除するときにAlert　Dialogを出しながら確認し削除するという流れを実装することができます。

読んでいただきありがとうございます。
何か間違いがありましたら指摘していただけると嬉しいです。
Dog APIでAPIの呼び出し練習をする

APIっていうのがあるやん。なんなんあれ。どうやって使えばいいんや。  

①フェッチというやり方でリクエスト？をAPIに送る
②リクエストに応じてレスポンスが返ってくる
③レスポンスの内容をなんか解析する
④解析できたものから情報を取り出す
⑤取り出した情報をHTMLに埋め込む  

っていう動作をすれば
どこに画像のurlがあるのか、とか気にせずに情報を取ってくることができるらしいわ！

試しにDog APIを用いて練習してみようやないか。
次のコードでは毎回違う犬の画像がランダムで表示されるんや。
```html
<!DOCTYPE html>
<html lang='ja'>
<head>
    <meta charset="utf-8">
    <title>dog</title>
</head>
<body>
    <h1>ランダムに犬の画像が表示されます</h1>
    <div id="randomDog"></div>
    <script src="script.js"></script>
</body>
</html>
```


```javascript
async function displayRandomDog(){       
        const url = "https://dog.ceo/api/breeds/image/random";
        const response = await fetch(url)
        data = await response.json();       
        const object = document.getElementById("randomDog");
        object.innerHTML = `<img src="${data.message}">`;
}
displayRandomDog();
```

### JavaScriptについて

```javascript
async function displayRandomDog(){}
```  
   ここで `displayRandomDog` いう関数を自分で定義しとるんや。自分で定義するんやから名前は何でもええで。  
   この関数は `async` っていう非同期処理を使うためのキーワードが付いとるから、関数の中で `await` が使えるんや。  
   非同期処理っちゅうのは、何か時間がかかる処理が終わるのを待つんやけど、待ってる間も他の作業ができるっちゅう便利な機能やな。

```javascript
const url = "https://dog.ceo/api/breeds/image/random";
```  
   `url` っちゅう変数に、犬のランダムな画像を返してくれるAPIのURLを入れとるんや。このURLにアクセスすると、ランダムな犬の画像がもらえるんや。

```javascript
const response = await fetch(url)
```  
   `fetch` っていう関数を使うて、さっきの `url` にリクエストを送っとるんや。このとき `await` を使うて、リクエストの結果が返ってくるまで待つっちゅうことや。これで `response` には、リクエストの結果が入るんやで。

```javascript
data = await response.json();
```  
   `response` に入ってる結果をJSON形式で解析して、`data` っちゅう変数に入れとるんや。この `data` の中には、APIから返ってきたデータが入っとるんや。

```javascript
const object = document.getElementById("randomDog");
```  
   `object` っていう変数に、HTMLの中にある `id` が `"randomDog"` の要素を取ってきとるんや。この要素に犬の画像を表示させるんやで。

```javascript
object.innerHTML = `<img src="${data.message}">`;
```  
   ここで、さっき取得した `data.message` に入っとる犬の画像のURLを使うて、`<img>` タグを作成し、その中に画像を表示させとるんや。`innerHTML` を使うて、要素の中身を直接書き換えとるんやで。  
   `で囲った中には変数を${}で囲むようにして入れ込むことができるんや。  
dataっていう変数の中のデータはJSONやから次のようになっとる。一例やで。messageのurlはランダムに与えられるんや。
```json
{
    "message": "https://images.dog.ceo/breeds/hound-walker/n02089867_3044.jpg",
    "status": "success"
}
```
jsonの変数の中のデータにアクセスるにはドットを使えばできる。  
例えば上のデータやったら  
`data.message`には`"https://images.dog.ceo/breeds/hound-walker/n02089867_3044.jpg"`  
`data.status`には`"success"`が入ってるんや。
```javascript
displayRandomDog();
```  
   最後に、関数 `displayRandomDog` を呼び出して実行しとるんや。この一行で、犬の画像がランダムに表示されるっちゅうわけやな。

こんな感じやで！このコードを使うたら、可愛いやろ？
LLMはアニマシーを理解できるのか？新たな心理言語学的アプローチで探る

# Animate, or Inanimate, That is the Question for Large Language Models

今回は、最新の研究成果である「Animate, or Inanimate, That is the Question for Large Language Models」という論文をご紹介します。この研究は、言語モデル（LLM）が人間のようにアニマシー（生物性）を理解し処理する能力を持っているかどうかを探求するものであり、言語処理における重要な問いに答えようとしています。

### 論文情報
- **タイトル**: Animate, or Inanimate, That is the Question for Large Language Models
- **リンク**: [リンク](https://arxiv.org/abs/2408.06332v1)
- **発表日**: 2024年8月12日
- **著者**: Leonardo Ranaldi, Giulia Pucci, Fabio Massimo Zanzotto
- **DOI**: [10.48550/arXiv.2408.06332](https://doi.org/10.48550/arXiv.2408.06332)

## 背景と目的

この研究は、アニマシー（物が生物であるか否かの概念）が人間の記憶、視覚、および多層的な言語理解に深く関わっていることを背景にしています。人間が言語を使用する際にアニマシーを理解する能力は、社会的な相互作用を理解する上で非常に重要です。一方で、現在の大規模言語モデル（LLM）は、テキストデータのみで訓練されており、非言語的な情報にアクセスできないため、アニマシーをどの程度理解しているのかが問われています。

本研究の目的は、LLMがアニマシーに関連する言語的なフックに対してどの程度人間と同様に反応するかを検証することです。特に、LLMが通常のアニマシーの制約をどの程度理解し、さらに非典型的なアニマシーの状況にどのように対応するかを調査します。

## 研究の焦点

この研究は、LLMが人間と同様にアニマシーを処理するかどうかを検証するために、心理言語学的な実験をLLMに適用することで、その行動を分析しています。実験は以下の2つの側面に焦点を当てています。

1. **典型的なアニマシーの実験**: 
    - ここでは、動詞や形容詞の使用が、アニマシーの制約に従っているかどうかを調べることで、LLMの言語処理能力を評価します。
    - 具体的には、「BLiMPベンチマーク」と「文の妥当性ベンチマーク（BSP）」を使用して、LLMが文法的に正しい文と正しくない文を区別できるかどうかを検証します。

2. **非典型的なアニマシーの実験**: 
    - こちらでは、通常アニマシーがないと考えられる対象に対して、LLMがどのように反応するかを調べます。
    - 特に、繰り返しや文脈に基づくストーリーを使用して、無生物の対象が生物のように振る舞う場合にLLMがどの程度驚きを示すかを評価します。

## 実験の概要と結果

### 典型的なアニマシーの実験

実験では、BLiMPとBSPベンチマークを使用して、LLMがアニマシーの制約に基づいて文を正しく評価できるかどうかを調査しました。結果は以下の通りです。

- **BLiMPベンチマーク**: 
    - GPT-4は、人間とほぼ同等の精度でアニマシー制約に基づいた文を評価できることが示されました。
    - Meta社のLlamaモデルやMistralモデルも、徐々に人間のレベルに近づいていますが、まだいくつかのケースでパフォーマンスが劣ることが確認されました。

- **BSPベンチマーク**: 
    - LLMは、人間と同様に、アニマシーに関連する妥当な文と不妥当な文を区別できることが確認されました。
    - 特にGPT-4は、人間以上の精度で文の妥当性を評価できることが示されています。

### 非典型的なアニマシーの実験

この実験では、無生物の対象が生物のように振る舞う場合に、LLMがどのように驚きを示すかを調査しました。

- **結果**: 
    - LLMは、人間と同様に最初は無生物の対象に対して驚きを示しましたが、文脈が進むにつれて驚きの度合いが低下することが確認されました。
    - 特にGPT-4は、人間と非常に似た反応を示し、文脈に基づいて驚きが減少することが明らかになりました。

### 賛否両論

**賛成意見**

本研究は、LLMがアニマシーを人間と同様に理解し処理できることを示した点で、大きな意義があります。特に、GPT-4のような最新のモデルが人間に匹敵する言語処理能力を持っていることが実証されました。これにより、LLMがより複雑な社会的相互作用や自然言語処理のタスクに応用できる可能性が広がります。

**反対意見**

一方で、本研究にはいくつかの制約が指摘されています。例えば、LLMがアニマシーを理解する際に、依然として人間のような認知的プロセスに完全には到達していない可能性があります。また、LLMがテキストデータのみで訓練されているため、視覚や物理的な刺激に基づく理解が欠如している点も課題として挙げられます。

## 
この記事が皆さんの研究や実務に役立つことを願っています。ご質問やフィードバックがありましたら、コメント欄にお寄せください。
command not found: docker-compose

# Issue - docker composeコマンドが使えなくなった
docker周りでバージョンを更新しようとしたところ，以下のようなエラーが出てdocker composeコマンドを使えなくなってしまったので，解決方法を記録します．
```
zsh: command not found: docker-compose
```
原因の詳細は忘れたので後で書きますが，docker compose v2へのアップデートがうまくいっていなかったようなので，docker, docker composeをアンイストール後，再インストールしたところきちんと動くようになりました．
# Solution
 まずは以下のコマンドでDocker Desktopをアンインストールします．(Mac OSを使ってる人)
```
/Applications/Docker.app/Contents/MacOS/uninstall
```
続いて，関連するファイルがいくつか残っている場合があるので，以下のコマンドで削除します．
```
rm -rf ~/Library/Group\ Containers/group.com.docker
rm -rf ~/Library/Containers/com.docker.docker
rm -rf ~/.docker
```
:::note alert
Docker Desktopをアンインストールすると，ローカルにあるコンテナ，イメージなどが破棄されるので，重要なデータは以下のリンクを参考にバックアップしてください．
:::

https://docs.docker.com/desktop/backup-and-restore/

以下のサイトからDocker Desktopを再度インストールします．

https://docs.docker.com/desktop/install/mac-install/

これで無事にdocker composeコマンドが使えるようになりました．
# まとめ
docker周りでよく詰まるので，最新の情報をキャッチアップしておきたいです．
「群論入門」を読んでみた

![Eq0NDLEVoAA_gl0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174906/eda39ccf-09cc-b05f-be85-714faf6fbdd7.jpeg)
　ヨビノリで群論入門という講座を見て群論に興味を持った。講座は分かりやすくて良いものだったが、初歩的なところで終わっているのでもう少し踏み込んだところまで勉強してみることにした。そこでヨビノリおすすめの一冊目の教科書という群論入門(雪江明彦著)を購入して読み始めることになった。2020年11月のこと。
<iframe width="560" height="315" src="https://www.youtube.com/embed/dO1T5-N3k1U?si=NXDjCG4q7TLiSW7Z" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
　自分には難解に感じたが、最初は半年ぐらいで読み終えられると思っていた。しかし読み進められたのは半年でようやく半分ほど。しかも後半はより難しくなり、理解出来ない。2021年6月で中断。2023年9月から勉強を再開したがもう内容を忘れているので最初からやり直し、2024年1月末までで3/4ほど読み進めて中断。2024年4月から再開して2024年8月までかけて読み終えた。中断時期を除いても15か月を費やした。

　元々知っていることが多いという意味で単純に比較は出来ないが、有限要素法や、電気工学、機械工学を扱う工学書は2～4週間もあれば読み終えられていた。しかし数学書は理解に時間がかかる。難易度が段違い。自分のレベルでは読むだけではダメで、手を動かして定理や証明を内容を補足しながら書き写し、演習問題を解かないと理解出来ない。書いたノートは5冊以上に及んだ。

 内容は洗練されており高密度。入門書なので導入はそれなりに詳細に解説しているが、その後は割と突き放した感じ。演習問題の多くを占める証明問題は答えが載っていないので、どうしてもわからない場合は他の書籍やWebを調査することになり、相当な時間を費やしてしまう。僅か140ページだが数学科出身でない社会人が読むには覚悟が必要。多少の誤字や誤記はあるが、比較的間違いは少ない。教科書としては素晴らしい良書。

 # 概要
 本書が前提とする知識はかなり少ない。中学数学程度が分かれば十分。線形代数の知識があると読み進めやすい個所もあるが、別になくても構わないと思う。行列演算の基礎をWebを使って調べる程度で十分。ただし本書には応用の具体例がほとんどないのでイメージしづらい。ゲーム、パズルやあみだくじや時計の針など、自分で想像力を働かせて応用をイメージする必要がある。
　本書は4章に分かれている。第1章は集合論、第2章は群の初歩、第3章は休憩タイムで、第4章は群の少し発展的な内容。第1章と第3章はオマケのようなものでメインは第2章と第4章である。
 　第1章では集合や写像と言った考え方と、論理を学ぶ。一見余りにも当たり前すぎて何でこんなことを学ぶのだろうと思ってしまうが、この当たり前なことから当たり前でないことを導くのが数学のやり方。当たり前をちゃんと理解することが非常に重要。自分は途中で何度も当たり前が分からなくなってきて、何度も読み返した。実はこの章こそ多くの人が群論を学ぶことで得られる最も大事な知見ではないかと思う。群論そのものが役立つのではなく、群論を学ぶ過程で集合、写像、論理への理解を深められることが、他のあらゆる科学や技術を学ぶ上で大いに役立つ。この考え方は全ての科学の前提になっているからである。数学の仕事を目指すひとだけでなく、物理や工学やプログラミングの仕事を目指すひとも、群論を学ぶ価値があると自分が思うのはこの点にある。
　第2章では群の定義からいくつかの群の例とその周辺の概念、そして準同型定理という重要な定理を学ぶ。こんなに少ない前提から色々なことが導けることに驚きを得ることが出来ればこの章はマスターしたと言えるのではないだろうか。ちなみにヨビノリの講座はこの第2章の一部を分かりやすく解説したしたものであり、初学者は本書を読む前に講座を見ることをオススメする。
 　第3章では群論というものが生まれるきっかけになった方程式の解の公式の話が触れられている。5次以上の方程式の解の公式は存在しないという有名な理論である。しかしこれを説明するためのガロア理論を知るにはもっと深くまで代数学を学ぶ必要がある。ここではあくまで触りを紹介しているだけである。
　第4章では群の作用、シローの定理、生成元と関係式で定義された群、有限アーベル群の基本定理、交代群の性質という内容を学ぶ。前半よりも当たり前でない不思議な結論が得られて面白い内容ではあるが、内容を理解することはなかなか難しい。一部の難問や、筆者が読み飛ばしても良いとされている項目は自分には理解できず諦めた。

# プログラミングによる解法
　有限群の問題は、手で論理的に解くことが出来なくても、コンピュータで全パターン調べれば分かることがある。またそういう愚直なやり方も理解の助けになる。それ自体がプログラミングの練習にもなる。解答例のない問題に対して分からないままで放置するよりも、力技であっても解いておけばスッキリするものである。ということで一部の問題をプログラミングで解いた。
 https://github.com/MhageGH/GroupTheory
正規化して元に戻す関数

ニューラルネットワークなんかだと正規化(最大値が1、最小値が0)の機能を使うことがあると思いますが、そんなデータを元に戻す方法を考えてみた
```math
t=\frac{x-min(x)}{max(x)-min(x)}
```
なので
```math
x=t(max(x)-min(x))+min(x)
```
となります。
実際にやってみます。
# 正規化関数
```Python3
def scale(x):
    val = {}
    for col in x.columns:
        val[col] = [{"max" : x[col].max()}, {"min" : x[col].min()}]
        x[col] = (x[col] - x[col].min()) / (x[col].max() - x[col].min())
    return x, val
```
# 元に戻す関数
```Python3
def inverce(x, val):
    for col in x.columns:
        tx[col] = x[col] * (val[col][0]["max"] - val[col][1]["min"]) + val[col][1]["min"]
    return tx
```

## 使用例
```Python3
df = pd.read_csv("iris.csv")
x = df.drop("category", axis=1)
x.describe()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/7d7a7be4-5aba-ed3d-1519-98411e92831b.png)

```Python3
tx, val = scale(x)
tx.describe()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/52baa8f3-8269-6461-6ba3-07215572030d.png)
正規化されました。
これを元に戻します。
```Python3
x_inv = inverce(tx, val)
x_inv.describe()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/6863ab26-ae71-4764-05f6-d5c51ea27795.png)


元に戻りました。
AGVへの道は遠からじ ② 車輪の組み立て

　設計図をかけるわけもなく、車体は、利用する部品をフレームにおいて印をつけ、穴あけをしながら組み立てをしていきます。

### （メモ）ソフトウェアの環境
Raspberry Pi 5 8GB
- 追加ボード；NVMe Base for Raspberry Pi 5 (NVMe Base by Pimoroni)
- Crucial クルーシャル P2シリーズ 500GB 3D NAND NVMe PCIe M.2 SSD CT500P2SSD8
- OS ubuntu24.04にROS2 Jazzy

### 車輪
　探し方が悪いのか、桃太郎とかミスミなどでみつかりませんでした。12φのハブはミスミにありましたが、なぜか、それにつなげられる車輪がないのです。
 　ロボショップ楽天市場店で購入しましたが、耐荷重の優れたごっつい車輪もあるようです。一番安価な車輪を購入しました。本体は、ABS樹脂より少し柔らかめで、外周には、ゴムではないけど灰色のすべり止めが使われています。柔らかさ？の異なるブルーのモデルもありますが、入手できませんでした。

- 12mmシャフト用 ユニバーサル アルミニウム マウンティング ハブ
- 8 inch SmoothGripホイール 50A

![IMGP2161.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/81e54823-4054-af19-780c-f2cb33931c9f.png)

![IMGP2166.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/2d81fcaa-066c-1896-4e9d-ae5555e58bba.png)


　木ねじで、ハブを固定します。

 ![IMGP2168.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/cfa412f3-4798-2641-57ae-0a0eaffe1163.png)


　モータの軸に差し込んで、六角ねじを回して固定します。
 
 ![IMGP2169.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/bb873968-a8c8-c454-80d1-71174464519f.png)

![IMGP2178.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/cb4d2e49-8db8-1333-5fcd-e3ae78d0126f.png)


### 車輪をフレームに固定する
　30mm角のアルミフレームに、アルミ板を載せ、M6ねじで固定する位置を決めます。M6ねじのヘッドの形状によって、対辺が4mmと5mmの2種類のねじ穴が存在します。なぜ？
 
　アルミ板に取付穴をあけます。
 
![IMGP2189.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/56e28daa-45f1-74b4-2992-7df0851f2a85.png)

　車輪のモータ・マウント（SOL5M8F）を、アルミ板、アルミフレームと共締めします。
 　アルミ板には、モータ配線用ケーブルを表側に出すための大き目の穴をあけておきました。
  
![IMGP2193.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/facd11e8-ca01-541d-fbfb-115b645d58f3.png)




![IMGP2196.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/8297d4d4-bd70-92e9-a6e2-5a44ee8e7eaa.png)

　両輪の仮取付けが終わりました。


![IMGP2198.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b291e78e-f19a-b494-da5e-a1b9aa974c5e.png)


![IMGP2202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/4256f84a-dcaa-fe5d-14fb-4c6d9e7216ca.png)

 
-----------

https://qiita.com/jamjam/items/692568361dde688fad16
いろいろな言語のコメントアウト文

自然文の中で書かれるコメントアウト文は、その人の好みがあらわれてちょっと面白いですよね。私は lisp にならって ``` ;; ''' を使うことが多いです。

|言語名  |１ライン  |複数行  |
|---|---|---|
|C  |   |/* ... */  |
|C++  | // ...  | /* ... */  |
|Rust| 同上  | 同上  |
|Jave| 同上  | 同上  |
|Scala|同上  | 同上  |
|Go| 同上  | 同上  |
|Perl| # ...  | =pod ...  =cut  |
|Pascal| | { ... }  |
|lisp|; ... | #&#124; ... &#124;#  |
|Haskell| -- .. | {- ... -}  |
|bash|  # ... | : << COMMENT ... COMMENT |
|zsh | 同上|同上   |
|csh|同上   | 同上(若干仕様異なる)  |
|ruby| # ... |  =begin ... =end   |
|python|# ... | """ ... """ |
| R | # ... | |
turbo_methodについて学ぶ

# はじめに
Turboについて簡単に概要だけ学びましたが、実際にコードの中で使用するとなると話はまた別で、非常に難しいと感じてしまいました。
今回は`turbo_method`について学ぶ機会があったのでアウトプットもかねて記事にまとめてみたいと思います

# そもそもTurboとは
- Turboとは、RailsのHotwire[^1]というセットアップの一部で、ページの遷移を高速化するための技術
- 主に、ページ全体をリロードすることなく、部分的にコンテンツを更新できるようにするためのもの
- これにより、ユーザー体験が向上し、アプリケーションがよりスムーズに動作する
- ユーザーがフォームを送信したときや、ボタンをクリックしてデータを更新したいときに使用される



# turbo_methodについて
Turboを使用してHTTPリクエスト[^2]を送信する際に、使いたいHTTPメソッドを指定するための機能で、Railsのビューで使うと、特定のアクションを実行するために便利


### **詳細**
`turbo_method`は、Railsのフォームやリンクに使われることが多く、通常のリンクやフォームでは、`GET`や`POST`メソッドが使われるけど、`turbo_method`を使うことで、`DELETE`や`PATCH`などの他のHTTPメソッドも簡単に使えるようになる


### **簡単な例**
例えば、Railsでリソースを削除するためのリンクを作る場合、次のように書くことができる
```
<%= link_to 'Delete', resource_path(@resource), method: :delete, data: { turbo_method: :delete } %>
```

この例では、リソースを削除するためのリンクを作成していて、`method: :delete`が`turbo_method`に該当する部分。これにより、リンクをクリックすると、Turboが自動的に`DELETE`リクエストを送信してくれる


### **Turboを使用しない場合のコード**

Turboを使用しない場合、次のように書くことができるぞ。
```
<%= link_to 'Delete', resource_path(@resource), method: :post %>
```
このコードでは、`method: :delete`を使わずに`POST`メソッドを指定している。この場合、リソースを削除するための正しいHTTPメソッドを使っていないため、サーバー側で適切な処理が行われない可能性がある！！

### **使用しない場合のデメリット**
- **意図しない動作**: `POST`リクエストが送信されても、サーバー側でDELETEリクエストとして処理されない場合、リソースが削除されないか、エラーになることがある。
- **セキュリティのリスク**: `POST`リクエストは、通常、データを作成するために使われるため、削除操作が意図しない方法で行われる可能性がある。
- **可読性の低下**: コードを見たときに、どの操作を意図しているのかが不明瞭になるため、他の開発者が理解しにくくなる。



### **まとめ**
- **turbo_method**は、HTTPリクエストのメソッドを指定するための機能。
- **詰め合わせ**というよりは、特定のメソッド（GET、POST、DELETEなど）を指定するためのオプション



[^1]: **Hotwire**：Railsの開発者が提唱した新しいアプローチで、Webアプリケーションをよりインタラクティブにするための技術群だ。Hotwireには主に以下の3つのコンポーネントが含まれている①**Turbo**: ページ遷移を高速化するための技術。②**Stimulus**: JavaScriptを使って、HTMLの動的な振る舞いを簡単に追加するためのフレームワーク。③**Strada**: モバイルアプリケーションとWebアプリケーションをつなぐための技術。

[^2]: **HTTPリクエスト**：クライアント（通常はブラウザ）がサーバーに対して送信する要求のこと。これにより、サーバーはデータを取得したり、更新したり、削除したりする操作を行うことができる。リクエストには、さまざまなメソッド（GET、POST、PUT、DELETEなど）がある
グラフ信号処理 グラフ周波数領域におけるサンプリング

## はじめに
グラフ信号処理の日本語文献はグラフフーリエ変換やグラフニューラルネットワークなどの文献が多いですが，サンプリングも重要な議論のひとつです．そこで，本記事ではグラフ周波数領域におけるサンプリングについて解説します．

手続き的な面について詳細に記述するので，理論については後述の参考文献を確認してください．
筆者も勉強中なので間違いなどありましたらご指摘いただけると幸いです．

## 環境
* MATLAB R2023b
* GSP toolbox : https://epfl-lts2.github.io/gspbox-html/index.html

GSP toolbox はグラフ信号処理で使えるMATLABのtoolboxです．

## 理論
元のグラフを$G$とし，サンプリング先のグラフを$G_1$とします．また，元信号を$\boldsymbol{f}\in\mathbb{R}^N$とします．$N$はグラフ$G$の頂点数です．今回はグラフ周波数領域におけるサンプリングをするので，元信号をグラフ周波数領域に飛ばします．
$$
\boldsymbol{\hat{f}} = \mathrm{GFT}_G(\boldsymbol{f}) = \boldsymbol{U}^\top \boldsymbol{f}.
$$
$\boldsymbol{U}$はグラフ$G$のグラフフーリエ基底です．グラフ周波数領域でサンプリングフィルタ$g(\boldsymbol{\Lambda})$を通した後，スペクトル折り畳み行列$\boldsymbol{D} _\mathrm{samp}=[\boldsymbol{I} _{M} \ \boldsymbol{I} _{M} \cdots]$をかけることでサンプリングを行います．なお，$M$はグラフ$G_1$の頂点数です．
$$
\boldsymbol{c} = \boldsymbol{D} _\mathrm{samp} \ g(\boldsymbol{\Lambda}) 
\ \boldsymbol{\hat{f}}.
$$

サンプリングにより$\boldsymbol{c}$の次元は$M$になりました．最後に，逆グラフフーリエ変換で信号を$G_1$上に飛ばせば完了です．
$$
\boldsymbol{f}_1 = \mathrm{IGFT} _{G_1}(\boldsymbol{c}) = \boldsymbol{U}_1 \boldsymbol{c}.
$$
$\boldsymbol{U}_1$はグラフ$G_1$のグラフフーリエ基底です．今回用いたグラフフーリエ変換，逆グラフフーリエ変換は使用している基底が別のグラフに由来することに注意してください．
## 具体例
頂点数32のパスグラフで具体例を示します．
```MATLAB
N = 32;
G = gsp_path(N);
f = sin((1:N)/N*2*pi)';
figure
gsp_plot_signal(G,f)
```
グラフの形状とグラフ信号は下図の通り．
パスグラフ上に正弦波信号があるものとします．
![graph_with_signal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/724144ff-df7d-d073-30ef-f4fc6c8e6566.jpeg)
この信号をグラフフーリエ変換し，グラフ周波数領域に飛ばします．
```MATLAB
G = gsp_compute_fourier_basis(G);
f_hat = gsp_gft(G,f);
figure
gsp_plot_signal_spectral(G,f_hat)
```
低周波数の信号が大きく，高周波数の信号は小さいことがわかります．
![signal_in_spectral_domain.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/6a3228d0-c147-cacb-aa65-1985092d8603.jpeg)
この信号を新たなグラフ$G_1$上の信号としてサンプリングします．今回$G_1$として頂点数16のパスグラフを採用します．
```MATLAB
G1 = gsp_path(N/2);
```
簡単のため，サンプリングフィルタとして単位行列を採用します．すなわち，
$$
\hat{g}(\boldsymbol{\Lambda}) = \boldsymbol{I}_{32}.
$$

また，頂点数32のグラフから頂点数16のグラフにサンプリングするため，スペクトル折り畳み行列は，

$$
\boldsymbol{D}_ \mathrm{samp} = \left[ \boldsymbol{I}_ {16} \ \boldsymbol{I}_{16} \right].
$$

以上より，サンプリングされたグラフ周波数領域の信号は，
```MATLAB
g_hat = eye(N);
D_samp = [eye(N/2) eye(N/2)];
c = D_samp*g_hat*f_hat;
f1 = gsp_igft(G1,c);
figure
gsp_plot_signal_spectral(G1,c)
```
となり，グラフ周波数領域ではおおよそ類似した信号になります．
![sampled_signal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/83a31654-6bfa-1295-2c88-c07cdf07ba71.jpeg)
加えて，グラフの頂点領域では，
```MATLAB
figure
gsp_plot_signal(G1,f1)
```
正弦波状の信号が得られます．
![sampled_signal_in_graph_domain.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/5afacf8b-bc9e-ab18-6892-ef64e1b57438.jpeg)

## 参考文献
* グラフ信号処理の基礎と応用 https://www.coronasha.co.jp/np/isbn/9784339014051/
数字の部分列の合計を行列の漸化式を使って求める

連立の漸化式を行列の掛け算に変形する方法はよく知られていますが、今回はその応用を考えます。

### 数字のすべての部分列の合計を求める

例えば$n=123$のすべての部分列は$\lbrace 1,2,3,12,23,123\rbrace$となりその合計を$A(n)$と表すと$A(123)=1+2+3+12+23+123=164$となります。

***【例題 １】$A(123456789)$を求めよ***

桁を左から１つずつ増やしながらに部分列の増分に注目します。ここで、
```math
\begin{align}
&d_i : i番目の数字\\
&B_i : i番目の数字を加えたときに増える部分列の合計\\
&C_i : B_iの部分列の個数\\
\end{align}
```


| i|$d_i$ |$B_i$ | $C_i$ | $B_i$の漸化式 |
|:---:|:---:|:---:|:---:|:---:|
| 0| 0| 0 | 0 | - |
| 1| 1| $1$ | 1 | $1 + (0) \cdot 10 +1 \cdot 0$|
| 2|2| $2+12$| 2| $2 + (1) \cdot 10 +2 \cdot 1$|
| 3| 3| $3+23+123$|3 | $3 + (2+12) \cdot 10 +3 \cdot 2$|
| 4|4| $4+34+234+1234$ | 4 |$4 + (3+23+123) \cdot 10 +4 \cdot 3$ |
| | | $\cdots$ | | |
| i|$d_i$| $\cdots \cdots$ | $C_i$ |$d_i + B_{i-1} \cdot 10 +d_i \cdot C_{i-1}$ |

ここで得られた漸化式をリストします。
```math
\begin{align}
&A_i = A_{i-1} + B_{i} \ \ \  &\dots (1) \\ 
&B_i = d_i + B_{i-1} \cdot 10 +d_i \cdot c_{i-1} &\dots (2) \\
&C_i = C_{i-1} + 1 &\dots (3) 
\end{align}
```
ここで$d_i$は$i-1$に依存しないので除くと、$(1)$だけが右辺に$B_i$があるのでこれに$(2)$を代入します。
行列にしやすいように多少順序を変えて、定数項のために$(4)$を加えます
```math
\begin{align}
&A_i = A_{i-1} +  \color{red}{10 \cdot B_{i-1}  +d_i \cdot C_{i-1} + d_i}  &\dots   (1)’ \\ 
&B_i =0 + 10 \cdot B_{i-1}  +d_i \cdot C_{i-1}+ d_i &\dots  (2)' \\
&C_i =0 + 0 + C_{i-1} + 1 &\dots (3)' \\
&1 = 0 + 0 + 0 + 1  &\dots (4) \
\end{align}
```
ここから以下の行列の漸化式が得られました。
```math
\begin{align}
\begin{bmatrix}
A_i \\
B_i \\
C_i \\
1 \\
\end{bmatrix}
&=
\begin{bmatrix}
1 & 10 & d_i & d_i \\
0 & 10 & d_i & d_i \\
0 & 0 & 1 & 1\\
0 & 0 & 0 & 1\\
\end{bmatrix}
\cdot
\begin{bmatrix}
A_{i-1} \\
B_{i-1} \\
C_{i-1} \\
1 \\
\end{bmatrix} \\
&= M_i \cdot
\begin{bmatrix}
A_{i-1} \\
B_{i-1} \\
C_{i-1} \\
1 \\
\end{bmatrix} 
& \cdots (5)
\end{align}
```
したがって

```math
\begin{align}

&\begin{bmatrix}
A(123456789) \\
- \\
- \\
- \\
\end{bmatrix} 
= (M_9 M_8 \cdots M_2 M_1) \cdot 
\begin{bmatrix}
0 \\
0 \\
0 \\
1 \\
\end{bmatrix} \\
&よって \\
&A(123456789) =  (M_9 M_8 \cdots M_2 M_1)_{1,4}
\end{align}
```
これをコードにします。基本的には行列の掛け算なのでnumpyを使えば簡潔に書くことができました。

```python 
import numpy as np
def A(dl):
  rdl = reversed(dl)
  ret = np.identity(4, dtype=int)  # identity matrix
  for d in rdl:
    ret @= np.array([[1,10, d, d],[0, 10, d, d],[0, 0, 1, 1], [0, 0, 0, 1]])
  return ret


print(A([1,2,3,4,5,6,7,8,9])[0,3])
# 167657325
```

### 元の数字がパターンの繰り返しの時

漸化式を行列で表すと、繰り返しの演算が出て来た場合に「繰り返し２乗法」が使えるので高速化することができます。

***【例題 ２】$n=123456789123456789...$と$123456789$が$10^3$回繰り返す数だったとき$A(n)$を$10^9+7$で割った余りを求めよ***

$n$は$9 \times 10^3$桁のとてつもなく大きな数になりますが「[フィボナッチ数列を行列を使ってO(log(n))で計算する](https://qiita.com/masa0599/items/5d412daa96695dea74bf)」で作った**mtxPowMod** を使って以下の式を計算します。
```math 
\begin{align}
&A(n) =  ((M_9 M_8 \cdots M_2 M_1))^k_{1,4}
\end{align}
```
```python
M = 10**9 + 7
print(mtxPowMod(A([1,2,3,4,5,6,7,8,9]),10**3, M)[0,3])
# 864817697
```

(開発環境：Google Colab)

この考え方はProject Euler, Problem 603: Substring Sums of Prime Concatenationsを解くのに役に立ちます。
ワイヤレス給電LEDを使って燈狐を光らせてみた

# 背景
告知されてから、ずっと欲しかった電脳大工さんの燈狐を手に入れました。素晴らしい造形に感動しつつも、燈が実際に光らないことが口惜しいです。
コストとサイズの面から厳しいと呟かれていたのを拝見しましたので、少なくともサイズ制約は我々工学屋さんの出番と、改造に着手しました。

# 目標
燈狐の持つ燈を光らせること
※造形の容易さから対象は提灯としました。灯籠も同様の手法で実現できると思います。他2つは別途構成を変える必要がありそうです。

# 方法
提灯は本体に引っ掛けることで装着されています。それによって、風等による揺れを再現することができます。一方で、光源を仕込むための配線を内部に通すことが出来ません。そこで、ワイヤレス給電方式のLEDを使うことで実現しました。

# ハードウェア構成
実際の構成図を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203155/0ca436f6-a467-2caf-d3a7-c33cb13af9f7.png)

実際に仕様した部品構成は下表のとおりです。

|品目|型式|備考|
|:-:|:-:|:-:|
|ワイヤレスLED |OSWM43-W5W|[秋月電子](https://akizukidenshi.com/catalog/g/g114404/)|
|ポリウレタン同線 0.8mm 10m| 2UEW 0.8mm 10m |[秋月電子](https://akizukidenshi.com/catalog/g/g109584/) |
| モータドライバ　| Pololu G2 High-Power Motor Driver 24v21 | [Pololu](https://www.pololu.com/product/2995/specs)|
|電源装置　|- | +24V程度（できれば電流制限機能があること）|

## コイル製造方法（両面テープ、巻き出し直径）
基本的には、なるべく大きな直径で、多数巻くと遠距離まで給電できます。コイルを巻く際にはベースとなるプレートに両面テープを張り付けることでポリウレタン線が動かないように固定できます。

内径を90mmとして10mを巻ききりました。結果的に外形は150mmくらいにまでなりました。
![IMG_5773.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203155/aad0ded4-5c70-f097-b05d-5d4591d85f58.jpeg)

※磁気共鳴式に送電回路とすることでより遠距離まで飛ばせるようですが、今回はそこまでしなくても実現できました。

## 提灯
正規の提灯に穴をあけて仕込むこともできそうでしたが、筆者が造形に関する技術を全く持っていなかったため、新規に提灯だけ作りました。図のようにCADでモデルを作成し、引っ掛ける部分（黒）と中央部（透明）と、ワイヤレスLED(黒)の3パーツ構成としました。
非常に小さなパーツのため、DMM.makeの3Dプリントサービスを利用しました(合計1853円)。上部は、高精細ABSライク｜HPS｜LumiaX1-除去有、中央部はクリアレジン｜SLAで作成しました。全てを組み立てた様子が下図です。

# ソフトウェア構成
マイコンからモータドライバに60kHzのアンチロックフェーズ方式の駆動指令(pwm端子をHi固定,Dir端子をduty0.5のpwm駆動)を与えました。なお、dutyは0.5固定です。
炎の揺らぎを表現するために、周波数を±数十Hzの範囲でゆっくりと動かすことで伝送効率を変動させて揺らぎを表現しました。

(注意)PWM端子をハードウェア的にHi固定にすると、dir端子が不定の場合に思いもよらぬ電流が流れます。そのため、マイコン側の電源を入れて安定化するのを待ってからモータドライバ側の電源を入れるか、マイコン側でdir信号を出力するまではPWM入力信号をlowにしておく必要があります。ここをしっかりとやらないと、過電流が流れてバッテリーを使用していた場合などは最悪燃えます。

# 結果
最終的に本体に設置した結果は図および動画のとおりです。
![IMG_5765.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203155/28f262e2-a9d5-2224-1baa-4a512853a0ac.jpeg)

![GUlp9LSWgAAWx9v.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203155/a5775ce0-c1b3-e215-b287-15e1c4931c73.jpeg)

https://x.com/i/status/1822104061052850248


# 所感
はじめは秋月電子のワイヤレスLEDのセットで試していましたが、距離が不足したため、送信側を自作しました。結局巻き数を増やして電源電圧上げてあげればどうにかなりました。

# 参考文献
https://www.youtube.com/watch?v=T-KUYHnxH1M&t=244s
Vim忘備録-特定の文字列が含まれる行を削除する-

特定の文字列が含まれる行を削除する機会があったため忘備録として記録に残そうと思います。

# 想定するデータ
下記のデータを想定します。
ファイル名：test.csv
```
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
ggg,2024-07-01,hhh,iii
jjj,2024-07-02,kkk,lll
mmm,2024-08-01,nnn,ooo
ppp,2024-08-02,qqq,rrr
```

# 実行するコマンド

Vimでtest.csvファイルを開き、以下のコマンドを実行します。
→ "2024-06"を含む行が削除されます。

```
:g/2024-06/d
```

実行後のデータ
```
ggg,2024-07-01,hhh,iii
jjj,2024-07-02,kkk,lll
mmm,2024-08-01,nnn,ooo
ppp,2024-08-02,qqq,rrr
```

## 特定の文字列が含まれない行を削除する（逆パターン）

特定の文字列が含まれない行を削除する場合は以下のコマンドを実行する。
→ "2024-06"を含まない行が削除されます。

```
:v/2024-06/d
```

実行後のデータ
```
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
```

# 参考資料

https://qiita.com/saba1024/items/c2489bcfa77122fa73c0

# 告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。
Linuxコマンド忘備録-特定の文字列が含まれる行を表示させる-

特定の文字列が含まれる行を抽出する機会があったため忘備録として記録に残そうと思います。

# 想定データ
下記のデータを想定します。
ファイル名：test.csv
```
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
ggg,2024-07-01,hhh,iii
jjj,2024-07-02,kkk,lll
mmm,2024-08-01,nnn,ooo
ppp,2024-08-02,qqq,rrr
```

# 実行するコマンド

```
grep -i "特定の文字列" ファイル名
```

上記に具体的な文字列、ファイル名を書くと以下になります。

```
grep -i "2024-06" test.csv
```
実行結果は以下のように、test.csvファイルの中で「2024-06」が含まれる行を表示します。
```
$ grep -i "2024-06" test.csv
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
```

## オプション -e を追加

オプションに`-e`を加えることで、複数の文字列を指定できます。
```
$ grep -i -e "2024-06" -e "2024-07" test.csv
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
ggg,2024-07-01,hhh,iii
jjj,2024-07-02,kkk,lll
```

## オプション -c を追加

オプションに`-c`を加えることで行数を表示することができます。
```
$ grep -ic "2024-06" test.csv
2
```

## 出力先にファイルを指定

出力先をファイルに指定すると、特定の文字列が含まれる行のみのファイルが作成できます。
```
$ grep -i "2024-06" test.csv > test_202406.csv
$ cat test_202406.csv 
aaa,2024-06-01,bbb,ccc
ddd,2024-06-02,eee,fff
```

# 参考資料

https://qiita.com/YASU_ojisan/items/8225c87acb4e1468dc90

# 告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。
CSSアニメーション：くるっとひっくり返るカード


クリックで回転させるカード作った、メモ✍

---------------------------------------

![画面収録 2024-08-13 10.19.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778695/0d6f3b6e-7838-b737-9155-88bbbe544366.gif)


<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="yLdzRrO" data-pen-title="Interactive 3D Card Flip Animation" data-user="hina1110" 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/hina1110/pen/yLdzRrO">
  Interactive 3D Card Flip Animation</a> by hina1110 (<a href="https://codepen.io/hina1110">@hina1110</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

https://codepen.io/hina1110/pen/yLdzRrO

#### ▼ HTML
```HTML
<div class="card">
  <div class="cardface cardface__front">front</div>
  <div class="cardface cardface__back">back</div>
</div>
```
#### ▼ CSS（一部抜粋）
```CSS
.card {
  position: relative;
  width: 300px;
  height: 400px;
  perspective: 1000px;
  transform-style: preserve-3d;
}

.cardface {
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background-color: #262626;
  transition: transform 0.6s;
  backface-visibility: hidden;
}

// 前面
.cardface__front {
  transform: none;
}
// 前面 - ひっくり返ったとき
.is-flipped .cardface__front {
  transform: rotateY(180deg);
}

// 背面
.cardface__back {
  transform: rotateY(180deg);
  color: #262626;
  background-color: #aaaaaa;
}
// 背面 - ひっくり返ったとき
.is-flipped .cardface__back {
  transform: rotateY(360deg);
}

```
#### ▼ JavaScript
```javascript
const cards = document.querySelectorAll(".card");

cards.forEach((card) => {
  card.addEventListener("click", () => {
    card.classList.toggle("is-flipped");
  });
});
```

両面が画像のやつは作ったことあったんだけど、普通にコンテンツ入れたくて！
影もちゃんと回転についてきてくれてかわいいな〜

### 例

裏面はボタンのクリックで戻るようにした◎

![画面収録 2024-08-13 16.36.43.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778695/03d90eff-75af-5d1e-8fa0-5a55308cbea8.gif)

カードゲーム、ボードゲーム関連のなにかに使えるかな？
GithubActions jobの重複部分を共通化したい

# はじめに
GithubActionsを使用していて、firebaseにデプロイを行っていました。ymlファイルのjobのコードで共通部分がいくつかあったため、共通化して呼び出せるようにしたいと思いました。そこで、GithubActionsの`Composite action`を試してみました。

# コードを共通化する
## 共通化前
buildとdeployそれぞれでinstallやbuild等の共通部分がありました。
```yml:main.yml
name: firebase deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: "18"
      - name: Install dependencies
        run: npm install
      - name: Run build
        run: npm run build
        env:
            VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}}
            VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}}
      ...

  deploy:
    name: deploy
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Setup Node.js and cache
        uses: actions/setup-node@v2
        with:
          node-version: "18"
          cache: "npm"
      - name: Install firebase-tools
        run: npm install --save-dev firebase-tools
      - name: Run build
        run: npm run build
        env:
            VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}}
            VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}}
     ...
```
## 共通化後
`.github/actions/build/action.yml`というファイルを作成します。
```yml:.github/actions/build/action.yml
inputs:
  VITE_SUPABASE_URL:
    description: "Supabase URL"
    required: true
  VITE_SUPABASE_ANON_KEY:
    description: "Supabase Anon Key"
    required: true

runs:
  using: "Composite"
  steps:
    - name: Setup Node.js and cache
      uses: actions/setup-node@v2
      with:
        node-version: "18"
        cache: "npm"

    - name: Install dependencies
      run: npm install --save-dev firebase-tools
      shell: bash

    - name: Run build
      run: npm run build
      shell: bash
      env:
          VITE_SUPABASE_URL: ${{ inputs.VITE_SUPABASE_URL }}
          VITE_SUPABASE_ANON_KEY: ${{ inputs.VITE_SUPABASE_ANON_KEY }}
```
`main.yml`は以下に書き換え
`uses: ./.github/actions/build`で指定して、ファイルを呼び出す。
```yml:main.yml
name: firebase deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Initialize
        uses: ./.github/actions/build
        with:
          VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
          VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
      ...

  deploy:
    name: deploy
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Initialize
        uses: ./.github/actions/build
        with:
          VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
          VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
    　...
```

# 終わりに
jobのステップが増えてくると冗長化部分が増えてくるので、共通化したほうが分かりやすければ、適宜共通化していきたいです。

# 参考

https://zenn.dev/stafes_blog/articles/ikkitang-a694b8afeb66f5
React Router v6でのネストの書き方で詰まったところ

# はじめに
React Router v6の書き方で特に詰まったところを上げたいと思います

# コンポーネントの配下にコンポーネントをレンダリングする場合
## v5での書き方
v5の場合はswitchの中でRouteを設定し、親コンポーネントの配下に子コンポーネントをレンダリングし、それをSwitch文で囲っていました。
```react
import { BrowserRouter, Switch, Route } from "react-router-dom";

<BrowserRouter>
  <Switch>
    <Route exact path="/">
      <ParentComponent>
        <ChildComponent />
      </ParentComponent>
    </Route>
  </Switch>
</BrowserRouter>
```

## v6からの書き方
v6からはRoutesで囲み、elemntの中で親コンポーネントの配下の子コンポーネントをレンダリングするようになりました。
```react
import { BrowserRouter, Routes, Route } from "react-router-dom";

<BrowserRouter>
  <Routes>
    <Route
      path="/"
      element={
        <ParentComponent>
          <ChildComponent />
        </ParentComponent>
      }
    />
  </Routes>
</BrowserRouter>
```

# 終わりに
elemntの中でネストできることを知らず、詰まってしまいました。
React Router v6の書き方を覚えていきたいです。