OmniAICreator/Qiita-1.07M huggingface dataset:
ApacheでWebSocketのタイムアウトを30分以上に設定する方法

# 1. はじめに
WebSocketを使用したApacheでのタイムアウト時間を30分以上に設定する方法について説明します。以下の手順に従って、Apacheの設定を変更してください。

# 2. WebSocketモジュールを有効にする
最初に、ApacheがWebSocketに対応しているか確認してください。WebSocketに対応させるには、`mod_proxy_wstunnel`モジュールを有効にする必要があります。Apacheをコンパイル済みでインストールしている場合、以下のコマンドでモジュールを有効にできます。

```
sudo a2enmod proxy_wstunnel
```

# 3. Apacheの設定ファイルを開く
次に、Apacheの設定ファイル（通常は `httpd.conf` または `apache2.conf`）を開きます。設定ファイルの場所はインストール方法やディストリビューションによって異なりますが、一般的な場所は以下の通りです。

- Debian/Ubuntu: `/etc/apache2/apache2.conf`
- CentOS/RHEL: `/etc/httpd/conf/httpd.conf`

# 4. タイムアウト設定を追加する
設定ファイル内で、`<VirtualHost>` セクションまたは `<Location>` セクションを見つけます（WebSocketを使用するサイトに関連する部分）。そのセクションに以下の設定を追加します。

```
# タイムアウトを30分（1800秒）に設定
ProxyTimeout 1800
```

# 5. Apacheを再起動して変更を適用する
設定ファイルを保存し、Apacheを再起動して変更を適用します。再起動コマンドはディストリビューションによって異なりますが、一般的なコマンドは以下の通りです。

- Debian/Ubuntu: `sudo systemctl restart apache2`
- CentOS/RHEL: `sudo systemctl restart httpd`

これで、WebSocketの接続が30分間維持されるようになります。必要に応じて、`ProxyTimeout` の値をさらに増やして、より長い接続を維持できます。ただし、サーバーのリソース使用やセキュリティを考慮して適切な値を設定してください。

# 6. セキュリティとパフォーマンスに関する注意点
WebSocketのタイムアウト時間を長く設定する際には、セキュリティとパフォーマンスの観点から注意が必要です。

## セキュリティ
長いタイムアウト時間は、悪意のある攻撃者が長時間接続を維持し、サービスへのアクセスを妨げるDoS攻撃（Denial of Service）のリスクが高まることがあります。そのため、適切なセキュリティ対策を講じることが重要です。例えば、次のような対策があります。

- IPアドレスによるアクセス制限
- ユーザー認証の実装
- リクエストのレート制限

## パフォーマンス
タイムアウト時間を長く設定すると、同時に多数の接続が維持されることになり、サーバーのリソース使用量が増加します。これにより、パフォーマンスが低下する可能性があります。リソース使用量を適切に管理するために、以下の対策を検討してください。

- 接続数の制限
- メモリやCPUリソースの監視
- 必要に応じてサーバーのリソースをスケーリング

適切なセキュリティ対策とパフォーマンス管理を行うことで、WebSocketのタイムアウトを長く設定しても安全かつ効率的なサービスを提供することが可能です。各状況に応じて、上記の対策を実施し、リスクを最小限に抑えながらサービスの運用を行ってください。
[AWS Q&A 365][SES]AWSのよくある問題の毎日5選 #46

# 1. Amazon SESの送信制限とは何ですか？
送信制限とは、Amazon SESアカウントが24時間以内に送信できるメールの最大数です。

# 2. Amazon SESの送信制限はどのように決定されますか？
Amazon SESの送信制限は、アカウントの送信履歴、送信されたメールのボリュームと品質、受信者のエンゲージメントなどに基づいて決定されます。

# 3. Amazon SESの送信制限は増やすことができますか？
はい、Amazon SESの送信制限は、自動的に増やされる送信クオータやユーザーがリクエストする送信クオータの2つの方法で増やすことができます。

# 4. Amazon SESの自動的な送信クオータの増加はどのように機能しますか？
自動的な送信クオータの増加は、Amazon SESの機能の1つで、アカウントの送信履歴やエンゲージメントメトリクスに基づいて、アカウントの送信クオータを自動的に増やします。

# 5. Amazon SESの送信クオータを増やすにはどのようにすればよいですか？
ユーザーはAWSサポートセンターを通じてリクエストを送信することで、Amazon SESの送信クオータを増やすことができます。リクエストには、意図されたユースケースや送信予定のボリュームなどの情報が含まれる必要があります。
[AWS Q&A 365][SES]Daily Five Common Questions #46

# 1. What are sending limits in Amazon SES? 
Sending limits are the maximum number of emails that can be sent by an Amazon SES account per 24-hour period. 

# 2. How are sending limits determined in Amazon SES? 
Sending limits in Amazon SES are determined based on the account's sending history, which includes the volume and quality of emails sent, as well as the recipient engagement. 

# 3. Can sending limits be increased in Amazon SES? 
Yes, sending limits can be increased in Amazon SES through two methods: automatically increased sending quotas and user requested increased sending quotas. 

# 4. How does automatic sending quota increase work in Amazon SES? 
Automatic sending quota increase is a feature in Amazon SES that automatically increases the sending quota for an account based on its sending history and engagement metrics. 

# 5. How can users request an increase in sending quotas in Amazon SES? 
Users can request an increase in sending quotas in Amazon SES by submitting a request through the AWS Support Center. The request should include information about the intended use case and expected sending volume.
ChatGPTとリリックを書いて、AIにラップさせてみよう！ラップ編

# 概要
「ChatGPTとリリックを書いて、AIにラップさせてみよう！」は
**1.** ChatGPTとやり取りをしてリリックを書き上げる **「リリック編」**
**2.** 文字を音声に変換するサービスを使ってリリックをラップにする **「ラップ編」**
の2つからなる、リリックを書いてラップにするまでの記録です。

この記事では、リリック編で書き上げたリリックを、音声データに変換します。
日本語はCoeFont、英語はVoxBoxとUberduck.aiを使用しました。

詳しい説明はリリック編1を読んでください。

https://qiita.com/komakinex/items/d3abaa76d66b705b2444

今回紹介する方法で初めてラップを制作し、ライブをしたのがこちらです！

######  
<iframe width="1147" height="645" src="https://www.youtube.com/embed/zrEjnQ5onWY?list=PLBBXvPY2hFT3PVf1DhWtxm9eDxt-VSsUg" title="さざれ場 #002 - komakinex (My First SOLO A/V Live Performance)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen ></iframe>

######
ライブのVJに関しては、画像生成について書いているこちらの記事で紹介しています。

https://qiita.com/komakinex/items/e9ff671bc50976fd4079


# 1. 文字を音声に変換するサービス
2023年5月2日時点の情報です。

## 日本語
アナウンサー風だったりSiriのように読み上げるサービスは多くありましたが、ラップで使えそうな抑揚のついた音声を生成するサービスは調べた限りCoeFontのみでした。

### CoeFont
https://coefont.cloud/

- ウェブサービス
- 月500円で1万字

日本語のサービスで、おしゃべりひろゆきが有名。
数多くの登録されている声を使えるほか、自分のAI音声を作成して収益を得ることもできる。

ラッパーのマチーデフさんの声を使用しました。

https://coefont.cloud/coefonts/f15131e4-fc22-464d-a4d7-2d05131516e5

https://www.macheedef.com/



### Ondoku
https://ondoku3.com/ja/

- ウェブサービス
- 月11ドルで20万字

抑揚はなく読み上げる感じで、まさに音読。
多言語に対応していて、例えばマレーシアの人の英語の訛りとかを生成できて楽しい。


## 英語のサービス
英語のほうが学習リソースが多いからなのか、読み上げる系はかなり綺麗に生成されるものが多かったです。ラッパーの声も需要があるみたいで日本語よりたくさんサービスがありました。

最終的なワークフローは、Uberduck.aiでテストして、VoxBoxで生成してwavファイルをダウンロード、という感じでした。

### VoxBox
https://filme.imyfone.com/voice-recorder/

- デスクトップアプリ
- 月15ドル250,000字

トランプ大統領とか有名人に加えて、Kanye Westとか2Pacとかラッパーの声も生成してくれる。他にもゲームやアニメのキャラとか（マリオもいた）。
登録してインストールしたら6000文字くらい無料で使えた。

### Uberduck.ai
https://app.uberduck.ai/

- ウェブサービス
- 月10ドルで保存し放題

字数制限が特になく、アカウントに保存しなくてよければ（その場でダウンロードはできる）無料で生成できる。ただ、課金しないと使えない声もある。
VoxBoxと同じモデルを使ってるぽくて出力が同じだったので、いろんなラッパーを試せた。

### Typecast.ai
https://typecast.ai/learn/rapper-voice-synthesizer/

- ウェブサービス
- 料金不明

設定項目がいっぱいあってむずかった、試してない。
英語の教科書みたいなやり取りも生成でき、会話の間とかかなり細かく設定できるぽい。

### Melobytes
https://melobytes.com/en/app/rap

- ウェブサービス
- 月1964円、7日間レンタル？1389円

設定項目にBGMがあり、謎の音楽と一緒にラップが生成されるので今回の用途には合わない（無音にはできない）。
どの声を選択しても、読み上げの声がぐちゃってなりがち。
無料アカウントで生成は、1日5回くらいまで。


# 2. CoeFontによる微調整
完成したリリックを、ラップにしたときに自然になるように読ませ方を少し変えて音声に変換していました。CoeFont上で読み方を修正でき、スピードも調整できます。語尾を強くする声質のせいか、アクセントは変更しても違いがわからなかったです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144702/69133e2e-a72a-80a8-5072-e1606240fcfd.png)


こういった作業はマチーデフさんいわく、実際のラップ制作でも行われるみたいです。

> これは人間がラップする時にもよくやる工夫ですね！
僕もフロウを作る時、リズムにハマるように発音の仕方や音の伸ばし具合を調整してます。


## サンプル
ということで修正したサンプルがこちらです。リズムよくする目的で行いました。


**リリック1**
俺の名前はコマキネクス　今日が初めての音楽ライブ　準備期間は1ヶ月　思い立ったがすぐ吉日

おれのなまえわこまきねくす。きょーがはじめてのおんがくらいぶ。じゅんびきかんわ**いっかげっ**。おもいたったがすぐきちじつ。

**リリック2**
さざれ場についてリリック執筆　ChatGPTと共同作業　やり方は後で公開するから　とりあえずまずは聞いてくれショータイム

さざればについてりりっくしっぴつ。**ちゃっとじぴてぃ**ときょーどーさぎょー。やりかたわあとでこーかいするから。とりあえずまずわきーてくれ**しょーたいん**。


**リリック3**
音と光の融合、未来への道　繋がる創造の炎、共鳴する場　新しい才能、輝かせる時

**ひかりとおとのゆーご**、みらいえのみち。つながるそーぞーのほのー、きょーめーするば。あたらしいさいの、かがやかせるとき。

# 3. いーじょう！！
以上です。
ラッパーが増えますように。

報告待ってます！

https://linktr.ee/komakinex
AWS Amplifyを使ってWebアプリを構築してみた#1

# はじめに
本シリーズは、かっこよさそうなReactと、楽そうなAWS Amplifyを使って、Webアプリを構築するまでの記録です。
フロントエンド、バックエンド、インフラどれも雀の涙の知識もないペーペーエンジニアが
苦戦する様子を楽しんでください。

# 第1回: AWS Amplify CLIの設定編

本記事では、AWS Amplify CLIの設定を行います。
Amplify CLIは、Amplifyを使用した開発を支援するコマンドラインツールです。Amplify CLIを設定することで、Amplifyを使用してフロントエンドプロジェクトを効率的に構築することができます。

## 1. AWSアカウントの設定

まずはじめに、AWSアカウントを設定します。AWSアカウントがまだない場合は、[AWS公式サイト](https://aws.amazon.com/)から登録してください。

## 2. AWS Amplify CLIのインストール

次に、AWS Amplify CLIをインストールします。以下のコマンドを実行して、最新版のAmplify CLIをインストールしてください。
`npm install -g @aws-amplify/cli`


インストールが完了したら、以下のコマンドでAmplify CLIのバージョンを確認しましょう。
`amplify --version`




## 3. Amplify CLIの設定

Amplify CLIの設定を行います。以下のコマンドを実行して、Amplify CLIを設定してください。
`amplify configure`

このコマンドを実行すると、Amplify CLIの設定ウィザードが開始されます。画面に従って、AWSアカウントの認証情報を入力し、Amplify CLIを設定します。

### 4. AWSマネジメントコンソールへのアクセス

シェルの指示に従って、ルートユーザーとしてAWSマネジメントコンソールにアクセスします。


```.シェル
Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
```


### 5. リージョンの設定

今回は、ap-northeast-1（東京）を選択します。


```.シェル
Specify the AWS Region
? region:  ap-northeast-1
```


### 6. IAMユーザーの設定


```.シェル
to complete the user creation in the AWS console
https://console.aws.amazon.com/iamv2/home#/users/create
```


指示に従って、IAMユーザー作成ページに移動します。

以降、基本的に[公式サイト](https://docs.amplify.aws/cli/start/install/#configure-the-amplify-cli)に沿って進めます（詳細は割愛）。

### 7. Amplify CLIの設定

- IAMユーザーとアクセスキーを作成したら、ターミナルに戻ります。
- 作成したアクセスキー（accessKeyId）およびシークレットアクセスキー（secretAccessKey）をコピー＆ペーストします。
- Profile Nameには、任意の名前を入力します。
    Profile Name：AWS CLIコマンドに適用できる設定と認証情報の集合です。

# まとめ

この記事では、簡潔な説明でAmplify CLIの設定を行いました。
次回は、フロントエンドプロジェクトの作成を行い、Amplifyを使用して開発を進めていきます。

# 参考サイト

- Amplify Dev Center
  https://docs.amplify.aws/cli/start/install/#install-the-amplify-cli
コードから生成できる、フローチャート描画ツール「D2」

こんにちは、Mottyです。
今回はコードから生成できるフローチャート"D2"についての説明です。

![qiita_20230502_00.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/2a396e2f-ed6f-79d3-3e8e-7e220e16b7fe.png)


 ### 概要

D2は、MarkDown記法を使用して簡単フローチャートを描画することができるツールです。D2は、MarkDown記法に準拠しており、MarkDownで書かれたテキストから、グラフィカルなダイアグラムを生成することができます。

D2は、様々な種類のダイアグラムをサポートしています。例えば、フローチャートやツリー図から、クラス図、状態遷移図、ER図などまで幅広くカバーしています。D2を使用すると、これらの図を素早く簡単に描画することができます。

D2の利点としては、Web上で使用できるということです。つまり、インストールする必要がありません。D2はオープンソースなので、誰でも自由に使用することができます。D2の使用方法は非常に簡単で、MarkDown記法を採用しているので少しルールを勉強するだけで、だれでも書けるようになります。
 

### 説明
下記にアクセスすると、以下のようなコマンド群が現れます。
説明に関しては以下の通り。


##### まずは試しにHello,World

矢印は基本的に->で繋ぐ

```
Hello -> World
```

![20230502_qiita_01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/d17649f2-9131-c9a5-480e-4cf6ca4445ca.png)

・方向の指定も可能
```
x1 -> y1
x2 -- y2
x3 <- y3
x4 <-> y4

```
![qiita_20230502_img04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/7b05df5c-4874-c9a6-e620-8d1b31f24b75.png)


##### ラベリング
いわゆるラベリングが可能。テキストが長い文章であるときなど。
また、繋ぐ順序が決まっているとき、ナンバリング等に便利
```
label1: Hello
label2: World
label3: and
label4: Good
label5: Afternoon

label1 -> label2 -> label3 -> label4 -> label5
```

![qiita_20230502_img05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/ea884e35-b2fb-f307-a7ec-34edb6ff8e77.png)

##### パラメーター指定
パラメーターも指定できる。例えば、形状はshape:"~"で変更することができる。
パラメータを指定する際は、ラベル:{~~}で囲う必要がある。

```
direction: down

Normal

Cloud: {
  shape: cloud
}

Paper: {
  shape: page
}

Oval: {
  shape: oval
}

```

![qiita_20230502_img06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/31142891-14ee-7d22-06d3-3c3dec61baab.png)


##### 分岐

条件分岐も可能です。

```
Q: Question

C: Did you eat breakfast? {
  shape: diamond
}

Y: full of energy {
  style.fill: red
}
N: lack energy {
  style.fill: blue
}

Q -> C
C -> Y: yes
C -> N: no

```

![qiita_20230503_img07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/6f9fd9f7-de77-a20a-8af1-3c1e1d2b507a.png)


##### 入れ子にも対応
いわゆるコンテナ的な考え方で大丈夫。

```
direction: down

container1: container1 {
  container2: container2 {
    target: target {
      shape: circle
    }
    dummy1: dummy
    dummy2: dummy
  }
}

container3: container3 {
  container4: container4 {
    container5: container5 {
      dummy3: dummy
      dummy4: dummy
      goal: goal {
        shape: circle
      }
    }
  }
}

container1.container2.target -> container3.container4.container5.goal
```

![23030503_qiita_img08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/2e7f66a8-ae0e-d7c3-2a43-76272f6f8bc9.png)


### 終わりに
Text To Diagramming ToolはD2の他にもMermaid やPlantUMLなど様々ありますが、微妙に構文が違うので
どれか１つを覚えて使えるようになれば良いのではと思います。
弾性棒に係る不静定系の力学 基本例題2.01 P31 「材料力学演習(20221021)」をsympyでやってみた。

# オリジナル
基本例題2.01 P31
http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=36

「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。＞sympy
https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy

# sympyで
```python
from sympy import *
NAB,NBC=symbols('NAB NBC',real=True)
PB     =symbols('PB'     ,real=True)
A  ,EE =symbols('A   EE' ,real=True)
l1 ,l2 =symbols('l1  l2' ,real=True)
myBsyuhen=Eq(-NAB-PB+NBC,0)
dAB=NAB*l1/(A*EE)
dBC=NBC*l2/(A*EE)
myHenkei=Eq(dAB+dBC,0)
ans=solve([myBsyuhen,myHenkei],[NAB,NBC])
print("#",ans)
mySubs={PB:7,l1:0.7,l2:0.3}
print("#",round(ans[NAB].subs(mySubs),1) )
print("#",round(ans[NBC].subs(mySubs),1) )
# {NAB: -PB*l2/(l1 + l2), NBC: PB*l1/(l1 + l2)}
# -2.1
# 4.9
```

# Mathematicaで
勉強中

# 作図
勉強中


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


# いつもと違うおすすめです。
Web Archive 魚拓サービスを表示するJavaScriptのブックマーク登録

# 目的
現在閲覧しているページのアーカイブがWeb Archiveやウェブ魚拓に保存されているか確認するのにいちいち各サイトを確認するのは面倒くさいので、ワンクリックで確認できるようにしたい。

# 方法
ブックマークにjavascriptコードを登録する

## javascriptコード

### Web Archive
```javascript
javascript:(function(){open("https://web.archive.org/web/*/" + location.href)})()
```
アーカイブの有無を気にせず、直ちに保存したい場合は次のとおり。
```javascript
javascript:(function(){open("https://web.archive.org/save/" + location.href)})()
```

### archive.today
encodeURIComponent で :（コロン）、/（スラッシュ）、?（クエスチョン）等もエンコードしておく。
※encodeURIはそれらはエンコードされない。
```javascript
javascript:(function(){open("https://archive.today/submit/?url=" + encodeURIComponent(location.href))})()
```

### ウェブ魚拓
上記2つと比べると保存できる対象が少ないので使う人はいないかもしれないが、一応紹介。
```javascript
javascript:(function(){open("https://gyo.tc/" + location.href)})()
```

## 登録イメージ
URL欄に上記のjavascriptコードを入力してブックマーク登録する。
![20230503.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2744936/8c834094-a339-6c54-d2da-1f99ca708055.png)
#PowerApps Copy 関数が実装されたので例のアプリへさっそく機能追加した件

待望の Copy 関数が Power Apps に実装されました！素晴らしい！
ってことで「例のアプリ」に機能を追加したぞ、というネタです。

# Copy 関数 公式情報
下記のリンクを確認ください。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-copy?WT.mc_id=BA-MVP-5004053

非常に簡単な構文です。

```構文
Copy( text )
```

text の箇所にテキスト（文字）を指定すればクリップボードへコピーしてくれます。

# 参考情報
[ヨウセイ](https://twitter.com/youseibubu) さんの記事がわかりやすいので、詳細はそちらをご確認ください。

 https://qiita.com/youseibubu/items/41f713d626181b141b2c

From コントロールや、ギャラリーからのコピー処理も解説されています。公式に記載されている例が少なすぎるので、記事を読んで実際に検証アプリを作って動きを確認するのが良いかなーと個人的には思います。

 # 参考情報 その2
念のため、記事投稿（2023年5月3日）時点の環境情報です。
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/a8b56495-6d15-49c4-a8c0-6e95331304e9.jpeg)
作成バージョン 「3.23044.12」です。

# 例のアプリに機能追加する！
さて、例のアプリにコピー機能を追加していきましょう！

## 例のアプリ、とは？
「予定の候補日メーカー」です。

https://qiita.com/yamad365/items/4895e040e2b1af38e64a

Power Apps のカレンダースクリーンをチョッと改造して、予定の候補日時を作成する補助ツールです。以前から、このアプリにコピー機能を実装したかったのですが、昔は Copy 関数なんて無かったんですよ。

それが！
ついに！！
ｷﾀ――(ﾟ∀ﾟ)――!!!

## 機能追加後の画面
作成した予定の候補をコピーするだけ、ですからね。ボタン1個置いて、チョッと動作と制御の関数追加するだけッ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/3875eedf-d939-9e98-43a4-659e4dbc9a00.png)
動作イメージは、Copy ボタンの上にある予定の候補日時をコピーする、ただソレだけです。

## Copy ボタンの関数
OnSelect に下記を設定しています。

```Copyボタン.OnSelect
Copy( Concat( 予定の候補日時ギャラリー.AllItems, $"{ギャラリーで表示しているラベル.Text}{Char(10)}" ));
```

Copy 関数は冒頭で紹介しておりますので公式情報は割愛。

Concat 関数を利用すると配列やテーブルを1つの文字列へ変換可能です。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-concatenate?WT.mc_id=BA-MVP-5004053

過去、こんな記事を書いてますので、こちらも是非ご参照ください。

https://qiita.com/yamad365/items/e4730238f56a24806358

「Char(10) って何やねん？」と思った方は、下記の記事が参考になると思います。

https://qiita.com/yamad365/items/4f0bec10ae57368173d3

改行コードですね。Windows は CRLF が多いのですが、LF のみでも当方の利用範囲では問題ないため上記のような関数になっています。アプリを利用する環境によって改行コードが異なる可能性があります。なので、実際に利用する端末・環境などで動作確認は必須かな、と個人的には考える次第です。

## 動作イメージ
ボタン1発でコピーされてメッチャ便利。ちゃんと Win＋v のクリップボード履歴にも保持されています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> Copy 関数 <a href="https://t.co/PnfFMNkI55">pic.twitter.com/PnfFMNkI55</a></p>&mdash; やま (Yama) (@yamad365) <a href="https://twitter.com/yamad365/status/1653685741975904256?ref_src=twsrc%5Etfw">May 3, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これで、イチイチ範囲指定してコピペしていた操作が、ボタン押すだけでコピーされるようになって非常に満足です👍

# 結び
Copy 関数、マジ待ってました。

- Copy 関数が受け取れるのは現状テキスト（文字列）のみ
    - ギャラリーやテーブル、配列のデータはテキスト化必須
- （試した限りでは）改行コードは LF（Char(10)）のみで張り付け時に改行されるので個人的にはコレで OK
    - 改行コードは環境やアプリ依存な場面が多いのでシーンにあわせてテスト必須な認識
- Copy 関数の結果は、ちゃんと Win＋v のクリップボード履歴にも保持される
- iPhone の Power Apps アプリでもちゃんと Copy 関数は動いた

また1つ、Power Apps の世界が広がりましたわ！
それでは、皆さま。素晴らしい Power Platform Life を！
Next.jsのプロジェクトににMUIを導入する

# はじめに
Next.jsにMUIを導入する方法が書かれた記事はたくさんありますが、MUIやyarnのバージョンによっては動かないことがあるため記事にしました。
今回は[MUI v5.12.3のExample](https://github.com/mui/material-ui/tree/v5.12.3/examples/material-next-ts)を参考にしましたが、yarn v3では動かない箇所があるため改良を加えています。

## 使用したライブラリとバージョン

| ライブラリ | バージョン |
|:---|:---|
| next | 13.3.4 |
| @emotion/cache | 11.10.8 |
| @emotion/react | 11.10.8 |
| @emotion/server | 11.10.0 |
| @emotion/styled | 11.10.8 |
| @mui/icons-material | 5.11.16 |
| @mui/material | 5.12.3 |


# 手順
## 1. Next.jsのプロジェクトを作成する

MUIとtailwind cssをそのまま併用すると背景や文字色が干渉するため無効にします。
今回は分かりやすいように [`--src-dir`](https://nextjs.org/docs/advanced-features/src-directory)を使いましたが、無くても大丈夫です。
また、2023年5月現在、[MUI側がapp directoryに対応していない](https://github.com/mui/material-ui/issues/34898)ようなので、`--no-experimental-app`を付けています。

```bash
corepack yarn create next-app "[プロジェクト名]" --src-dir --ts --eslint --import-alias "@/*" --no-tailwind --no-experimental-app
```

今回はyarn v3を使用しました。

```bash
corepack yarn set version berry
# 初回のインストールで"Migrating from Yarn 1"を済ませておく
corepack yarn install
# nodeLinkerの設定を削除
sed -i 's/^nodeLinker/# nodeLinker/' .yarnrc.yml
# 再度パッケージをインストールすることで、node_modulesフォルダを削除
corepack yarn install
```

## 2. MUIをインストールする

[MUI公式のGetting Started](https://mui.com/material-ui/getting-started/installation/)に従い、以下をインストールします。

```bash
yarn add @mui/material @emotion/react @emotion/styled
# アイコンを使用する場合は以下もインストールする
yarn add @mui/icons-material
```

Next.jsでSSRを行うために、下記をインストールします。

```bash
yarn add @emotion/server @emotion/cache
```

ただし、yarn berryでない環境では`@emotion/cache`は自動でインストールされるようです。

## 3. MUIをNext.jsプロジェクトに組み込む

1. 公式のExampleから[`theme.ts`](https://github.com/mui/material-ui/blob/v5.12.3/examples/material-next-ts/src/createEmotionCache.ts)、[`theme.ts`](https://github.com/mui/material-ui/blob/v5.12.3/examples/material-next-ts/src/theme.ts)、[`_app.tsx`](https://github.com/mui/material-ui/blob/v5.12.3/examples/material-next-ts/pages/_app.tsx)、[`_document.tsx`](https://github.com/mui/material-ui/blob/v5.12.3/examples/material-next-ts/pages/_document.tsx)をプロジェクトにコピーし、以下のように配置します。
    ```
    .
    |- src/
    |  |- lib/
    |  |  |- createEmotionCache.ts
    |  |  \- theme.ts
    |  |- pages/
    |  |  |- _app.tsx
    |  |  |- _document.tsx
    :  :  :
    ```
1. `pages/_app.tsx`と`pages/_document.tsx`にあるimport元を書き換えます。
    - プロジェクトを作成したときにパスのaliasを指定してある場合は、`../src/…`を`@/…`に置き換えるだけで大丈夫です。

# おわり
公式のExampleをコピーするだけなのでわざわざ記事にするほどでもないと思いましたが、公式Exampleにある[`theme.ts`](https://github.com/mui/material-ui/blob/v5.12.3/examples/material-next-ts/src/theme.ts)は`next/font`を活用していたりとお手本のような感じだったので、周知も兼ねて記事にしました。
おそらく`create-next-app`のオプションに公式ExampleのURLを付ける方がメジャーなやり方だと思いますが、デフォルトでパッケージのバージョンが明記されていないなど再現性に欠けるため今回は採用しませんでした。
ディープラーニングでよく使うコード

# 目的
個人的にディープラーニングの学習時によく使うコードを備忘録として記載

# Pytorch
## モデルの保存
```python
import torch
# "model"はモデルのインスタンス名、その後の引数で保存用パスを記載する
torch.save(model.state_dict(), 'xxx/model.pt')
```
## 保存したモデルの読み込み
```python
import torch
from torch.utils.data import DataLoader
import torchvision.transforms as T

# モデルのインスタンス化（保存時と同じモデル、引数の指定が必要）
model = Model()
# モデルの読み込み
model.load_state_dict(torch.load('xxx/model.pt'))
# 評価モードにする
model.eval()

# 読み込んだモデルで予測する為のデータを用意
## 以下はCIFAR10での例だが、実際は学習時と同形式のデータで用意する
transforms = T.Compose((
    T.ToTensor(),
    T.Normalize(mean=channel_mean, std=channel_std),
    ))

dataset = torchvision.datasets.CIFAR10(
        root='data', train=False, download=True,
        transform=transforms)

loader = DataLoader(dataset, batch_size=32)

'''
1バッチサイズ分のみ予測
'''
# バッチサイズ分のデータを取り出し
tmp = iter(loader)
x, y = next(tmp) # x：予測用データ、y：正解ラベル

# 予測値の計算
## (1) PytorchのLinear関数使った場合（基本（2）を使えば良い）
def get_device(self):
    return self.linear.weight.device # self.linearはクラスで指定したLinear関数

x = x.to(model.get_device()) # モデルのデバイスを指定
pred = model(x)

## (2) 単純にデバイス指定する場合
x = x.to("cuda") # GPUの場合
pred = model(x)
```

# Google Colab
## Googleドライブをマウント
```python
from google.colab import drive
drive.mount('/content/drive')
```

## デバイス設定の確認
Google Colabで割り当てられているGPUの種類を見るときに使う
```python
# TensorFlow経由でデバイス設定の確認
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
````

## モジュールのリロード
モジュール内のファイルを修正して、再起動せずに反映させる方法
（これやっても反映されないことはちょくちょくある。そういうときは諦めてランタイムの再起動をする）

```python
# devディレクトリ直下にあるutilsというモジュールを対象とした場合
base_dir = './drive/MyDrive/dev/'

import sys
sys.path.append(base_dir)

# インポート
import utils

# リロード
import importlib
importlib.reload(utils)
```
マテリアルデザインのsnackbarとtoastの違い

同じ文脈で使われがちなSnackbarとToastの違いを調べてみました。


## snackbarとtoastの違い
両方とも簡易的なメッセージを表示するためのUIコンポーネントで、その2つには表示方法や目的に違いがあります。

一般的にSnackbarは、ユーザーアクションに関連するメッセージを表示するために使用されます。例えば、フォームが正常に送信された場合や、ログインが成功した場合に、画面下部に短時間表示されるメッセージがSnackbarによって表示されます。Snackbarは、同時に1つのメッセージしか表示できず、表示時間が短いため、ユーザーに過剰な情報を与えないように配慮されています。またメール送信後に送信が完了しました。のメッセージとともに「送信取り消し」などのアクションを持つことができます。

一方、Toastは、アプリケーション内での操作や出来事に関する独立した情報を表示するために使用されます。例えば、新着メッセージの通知や、アプリケーションが正常に動作していることを示すためのメッセージを表示する際に、画面の任意の位置に表示されることがあります。Toastには表示時間が設定されていることが一般的で、メッセージが非常に簡潔であることが求められます。アクションは持ちません。


## 簡潔なまとめ

#### Snackbar
- ユーザーが行ったアクションへのフィードバックとして使われる
- 「送信取り消し」など、ユーザーが実行できるアクションを持たせることがある


#### toast
- ユーザーのアクションとは関係なしの通知（アプリからのお知らせや通知）
- アクションを持たない



#### ちょっとした疑問

例えばアプリのPush通知なんかは何らかのアクション（ページ遷移など）ができることがほとんどなのですがつまりスナックバーと言えるのかな？ iOSエンジニアはトーストって言っているけど(?)
少なくとも大体の意味だけ知っていればなにか調べ物のときには役立ちそう。
Figを使ってmakeコマンドの説明を出すのが便利だった

## はじめに
makeコマンドは便利なのですが、たくさん作ると何がどのコマンドなのか忘れがちでいちいちmakefile見に行くの億劫に感じたことないですか？
僕は開発中に感じていて、偶然Figを使用していてその解決法を発見してかなり快適になったので公開します。

## 実現したいこと
- makeコマンドを使って、簡単にコマンドを叩けるようにしておく際に、あれこのmakeコマンドなんだっけ？みたいなことになったので、makefileのそれぞれ用意したコマンドを使用する際に説明が見れるようにしたい。

## 前提(準備)
- Figのインストール
    - Figの使い方は今回説明しません
- makefileにコマンドを用意していること

https://fig.io/

## 使い方
- makeファイルにコマンドを用意してコメントを入れて、Figを使えば補完が出てくるので一緒にコメントアウトで説明が表示されます。

```:Makefile
# frontコンテナのnpmパッケージをアップデート
.PHONY: npm_update_for_front
npm_update_for_front:
	docker-compose exec -T front npm update

# コンテナ起動
.PHONY: up
up:
	docker-compose up -d

# コンテナ停止
.PHONY: down
down:
	docker-compose down

# コンテナビルド
.PHONY: build
build:
	docker-compose build

//...(略)
```

## デモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040483/33fd6363-5105-467a-023d-e653e09fe615.png)


## 終わりに
Fig最高ですね！
📖「良いコード／悪いコードで学ぶ設計入門」（第６章 条件分岐）を読んだ感想

## 前回の話

https://qiita.com/tomonac/items/22be5f4c2cdedbfe7d3f


## 感想　（第6章 条件分岐）
![良いコード悪いコード.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3144766/45ff35a4-7874-5398-f498-afa7527c7a9a.png)




**[ 学んだこと ]**

- 可読性が下がる為、条件分岐のネスト状態はやめよう
  - 早期 return するような構成の方が見通しが良い
    - 条件追加の場合も対応しやすい
- 分岐内の処理で重複コードやめよう
  - 処理をメソッド化しメソッド呼ぶだけにするか、専用のクラスを作成するか
- フラグ引数による、実装はやめよう
  - 内部の処理が不明瞭になり、ロジックを読む必要が出てくる。つまり、可読性が下がる
  - ストラテジパターンで実現できるか検討するのも良い
CI/CDツールについて

## CI/CDとは？
<p>開発や保守の途中でもソフトウエアが稼働するように、ビルドやテスト、デプロイを継続的に実行するものです。開発したソフトウエアが稼働するかどうかの確認作業を高い頻度で行うことにより、不具合を発見した際にその原因を見つけることは容易になります。一方で開発が済んだ後に確認し、不具合を見つけた場合、調査対象が全ソースコードになります。そのため、原因発見に多くの時間と膨大な作業が必要となります。</p>
<p>例えば、家計簿を4月1日からつけ始め、翌年の3月30日まで毎月の収支が銀行手帳上のお金の動きと合っているかどうか確認していない、加えて3月31日に家計簿の収支と手帳の収支を照合した際、合っていないことが確認された場合、4月1日から3月30日までのお金の動きを一つ一つ確認する必要が出てきます。しかし、4月30日時点で家計簿と手帳の収支を照合し、合っていなかった場合、1ヶ月間のお金の動きを追うだけで済みます。</p>
<p>同じように、CI/CDを使用し、ソフトウエアが期待通りに動くかを短い間隔で確認することで、負担が重い作業の発生を避けることができます。</p>

## バージョン管理システムとの連携
<p>バージョン管理システムは、ソースコードの変更差分を管理する為に使用されています。Git(#1)やSVN(#2)が代表例に挙げられます。ソースコードの変更があった際、即座に確認することが可能になります。</p>

#1 分散型バージョン管理システム。成果物を管理する場所がローカルとリモート2つある。
#2 集中型バージョン管理システム。成果物を管理する場所がローカルのみ。

##  成果物の管理
<p>CI/CDでは様々なパッケージを組み合わせて、ソフトウエアや環境を構築します。ビルド時に関連パッケージをダウンロードし、インストールします。適切な組み合わせのパッケージを矛盾なくインストールする為にパッケージ管理ツール(#3)が使用されています。代表例として、Apache Maven(#4)やyum(#5)が挙がります。例えば、Mavenを使用することで、ローカルとリモートリポジトリ(#6)の差を感じることなく、ビルドに必要なjavaファイルを自動的に収集できます。しかし、あるきっかけでMaven等のリポジトリにアクセスできなくなってしまうことがあります。そこでCI/CD環境に自前の成果物管理リポジトリを準備することがあります。代表例として、NexusやMaven Archiva
、Artifactoryが挙ります。</p>

<p>例えば、JA等と契約を結んでおくことで、自動的に欲しい食材が手元に届きます。しかし、自然災害により、届かなくなるということが考えられます。そういったケースを防ぐために自前で野菜を育てるという感じです。</p>

#3 OSへのソフトウェアの導入と削除、依存関係の整理などを行うツール
#4 Javaのライブラリ管理
#5 Linuxディストリビューションのパッケージ管理
#6 ファイルを管理する場所

## ログの管理
<p>CI/CD環境では、様々なマシンが動き、その上でosやアプリケーションがログを出します。CI/CD環境で実施したテストに異常があった場合やツール事態に異常があった場合にはログを参照し、異常の解明を行います。ログを管理するツールとして、syslogがあります。マシンからログをsyslogサーバに集積し、ログ調査の際にはsyslogのファイルを確認します。</p>

## 代表的なCI/CDサービス
<ul>
<li>Jenkins</li>
<li>Travis CI</li>
<li>Circle CI</li>
<li>Github Actions</li>
<li>GitLab CI/CD</li>
</ul>

## 参考資料
https://qiita.com/HITOSUKE/items/ae2fed680ca2b2ae6eae
https://wa3.i-3-i.info/word15664.html
https://qiita.com/sh-ogawa/items/26bd4edb2eff5787ca75
土台からしっかり学ぶーーソフトウェアテストのセオリー
ChromeでBabylon.jsのWebGPUのサンプルを試す (2023年5月3日)

# ChromeでWebGPUが使えるようになったらしい

https://caniuse.com/?search=webgpu

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/b9a1aeea-a3a7-c89a-1b6d-a905795709d1.png)

ということで,
Babylon.jsのWebGPUのサンプルを試していきます。

https://popov72.github.io/OceanDemo/dist/index.html

しかし、Chromeのバージョン更新前だと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/a139d85a-d2fb-8931-251d-fd58a5324e05.png)

こんなエラー文がでるので、まずはChromeを更新しましょう

# Chromeを更新する

https://support.google.com/chrome/answer/95414?hl=ja&co=GENIE.Platform%3DDesktop

こちらの記事を参考に更新してください。

再起動が求められるので、再起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/6ce56942-45a7-c822-a558-db3040161802.png)

# 再度WebGPUのサンプルページを見ると...?

改めてこちらを見ると...?
https://popov72.github.io/OceanDemo/dist/index.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/7137eeb6-c88a-61d7-08f8-2367842ef933.png)


うおおおお、すごい描画力だ！！！！

# 最後に

ということで、ChromeでBabylon.jsのWebGPUのサンプルを試す、でした！

ブラウザ3D表現に興味がある人があつまるコミュニティ
Babylon.js勉強会のDiscordではWebGPUの話題で盛り上がってますので、ぜひ興味ある人はDiscord気軽に入ってください！


こちらにもろもろ情報があります！

https://babylonjs.connpass.com/
Rails「Mysql2::Error: Table 'users' already exists」の解決方法

以下を実行する

```
$ rails db:migrate:reset
Dropped database 'XXX_development'
Dropped database 'XXX_test'
Created database 'XXX_development'
Created database 'XXX_test'
== 20230325042627 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0067s
== 20230325042627 CreateUsers: migrated (0.0067s) =============================
```

### 参考
* [【Rails】チーム開発している時の頻出DB系コマンド - Qiita](https://qiita.com/kinopyyy/items/2965c3215f93a58c3d19)


## 追記 (2023.5.6)
ご指摘を受け修正。
[こちらの記事](https://qiita.com/Asaiii12/items/99f402813997bc6bd50f)と[こちらの記事](https://bokunonikki.net/post/2018/0214_rails_mysql_error/)を参考にしました。
基本的にMySQL側でテーブルを操作するのは良くないと思っていたのですが、この場合は操作してもOKのような印象です(実際はどうかわからないです)。

以下のようにエラーが出ているとします。
```
$ rails db:migrate
== 20230325044645 CreateUsers: migrating ======================================
-- create_table(:users)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'users' already exists
/Users/me/environment/XXX/db/migrate/20230325044645_create_users.rb:3:in `change'

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'users' already exists
/Users/me/environment/XXX/db/migrate/20230325044645_create_users.rb:3:in `change'

Caused by:
Mysql2::Error: Table 'users' already exists
/Users/me/environment/XXX/db/migrate/20230325044645_create_users.rb:3:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
```

MySQL側でusersテーブルを削除します。
```
mysql> drop table users;
Query OK, 0 rows affected (0.17 sec)
```

usersテーブルが消えたことを確認します。
```
mysql> show tables;
+--------------------------------+
| Tables_in_agribeit_development |
+--------------------------------+
| ar_internal_metadata           |
| jobs                           |
| schema_migrations              |
+--------------------------------+
3 rows in set (0.00 sec)
```

再度`rails db:migrate`を実行します。
```
 $ rails db:migrate
== 20230325044645 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0637s
== 20230325044645 CreateUsers: migrated (0.0640s) =============================
```

usersテーブルが再度作られたことを確認します。
```
mysql> show tables;
+--------------------------------+
| Tables_in_agribeit_development |
+--------------------------------+
| ar_internal_metadata           |
| jobs                           |
| schema_migrations              |
| users                          |
+--------------------------------+
4 rows in set (0.01 sec)
```
RubyでAtCoder ABC269(A, B, C, D)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC269のA, B, C, Dを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Anyway Takahashi
https://atcoder.jp/contests/abc269/tasks/abc269_a
```ruby:a-269.rb
a, b, c, d = gets.split.map(&:to_i)
puts (a + b) * (c - d)
puts "Takahashi"
```

# B - Rectangle Detection
https://atcoder.jp/contests/abc269/tasks/abc269_b
```ruby:b-269.rb
array = Array.new(10){ gets.chomp }
str = "." * 10
a = b = c = d = 0
array.each_with_index do |factor, index|
  if factor != str
    a = index + 1
    c = factor.index("#") + 1
    d = factor.rindex("#") + 1
    break
  end
end

array.reverse.each_with_index do |factor, index|
  if factor != str
    b = 10 - index
    break
  end
end

puts "#{a} #{b}"
puts "#{c} #{d}"
```
## 解説
最初にa, c, dを求めます。次に、配列の順序を逆転させてbを求めます。なお、bは配列の順序を逆転させているので`10-index`としています。

# C - Submask
https://atcoder.jp/contests/abc269/tasks/abc269_c
```ruby:c-269.rb
n = gets.to_i
m = n
ans = [n]
while m > 0
  m = (m - 1) & n
  ans << m
end
puts ans.sort
```
## 解説
どちらも1であるような整数を求めればいいので、`&`を使うことで実装することができます。

# D - Do use hexagon grid
https://atcoder.jp/contests/abc269/tasks/abc269_d
```ruby:d-269.rb
n = gets.to_i
array = Array.new(n){ gets.split.map(&:to_i) }

hash = {}
array.each_with_index do |factor, index|
    hash[factor] = index
end

searched = Array.new(n, false)
dx = [-1, -1, 0, 0, 1, 1]
dy = [-1, 0, -1, 1, 0, 1]
ans = 0
n.times do |i|
    next if searched[i]
    ans += 1
    stack = [i]
    while node = stack.pop
        x, y = array[node]
        searched[node] = true
        6.times do |j|
            nx = x + dx[j]
            ny  = y + dy[j]
            key = [nx, ny]
            if val = hash[key]
                stack << val unless searched[val]
            end
        end
    end
end
puts ans
```
## 解説
DFSで解いています。基本的には、連結成分の個数を求めるDFSと同様ですが、隣接している部分についてはあらかじめdx, dyを用意しておき順に探索しています。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
ERR_BLOCKED_BY_CLIENT, Only one LaunchDarklyClient...エラーの対処法

## Vue.js学習中に2つのエラーが発生し、シークレットモードで解決

Vue.jsの学習を進めていると、以下の2つのエラーに直面しました。

1. `ERR_BLOCKED_BY_CLIENT`
2. `Only one LaunchDarklyClient can exist at a time, but another client already exists. This probably means something has gone wrong with our DI system, or we're using it incorrectly.`

これらのエラーは、私の場合、シークレットモードを利用することで同時に解決することが出来ました。

1の参考-原因は拡張機能のadブロック

https://itips.krsw.biz/failed-to-load-resource-neterr_blocked_by_client-error-reason/

2は、gpt3.5にべた張り
## まとめ
シークレットモードを使うことで、これらのエラーは解消され、Vue.jsの学習をスムーズに進めることができました。同様の問題に遭遇した方は、シークレットモードを試してみてください。
NeurIPS2022の枝刈り論文 (3)

# 概要

この記事では、[NeurIPS2022](https://nips.cc/)の枝刈り論文を紹介します。[^1]
[その1](https://qiita.com/kyad/items/35e72f05c9423e8f1b08) [その2](https://qiita.com/kyad/items/c5d4f53cdac674a909c0)

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

# Pruning Neural Networks via Coresets and Convex Geometry: Towards No Assumptions

https://openreview.net/pdf?id=btpIaJiRx6z

- 概要：Coresetsを使った枝刈りの改良
- 新規性：Coresets(任意の実行入力に対して理論的に誤差の上界が抑えられる)を使った枝刈りで、制約を緩めて実用的にした。
- キモ：元の点からなる空間からLouwer-John elipsoid (全ての点を含む最大の楕円体)を小さくして、カラテオドリの定理で得られる凸包を使って小さくする。
  Algorithm 1, 2で、元よりもロスが小さくなる点を選び、刈る。
- 評価：Filter pruningでResNet50, Pascal VOCなどで評価した


# Lottery Tickets on a Data Diet: Finding Initializations with Sparse Trainable Networks

https://openreview.net/forum?id=QLPzCpu756J

- 概要：IMPの良い初期値設定
- 研究機関：Meta, Google
- 新規性：
  (1) IMPのpre-trainingには少数データで良いことを実験的に示した。
  (2) (1)は学習回数がそんなに多くなくて良いことを示した。
  (3) 少数データはEL2N Score (サンプルの難しさを測る指標) の小さい、easyなデータが良いことを示した。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/7f9e0b40-10eb-3892-f302-8e1ce16df154.png)
- キモ：実験した。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/0b23836e-c0f6-fd4b-8c24-11d072aec880.png)
- 評価：実験した。


# Prune and distill: similar reformatting of image information along rat visual cortex and deep neural networks

https://openreview.net/forum?id=2OpRgzLhoPQ

- 概要：ラットの視覚野とDNNとの比較
- 新規性：視覚野とDNNを、DNNの序盤の枝刈りと蒸留で理解する。
- キモ：
  1. 視覚野のIntrinsic dimension(特徴の複雑さのようなもの)はhunchback(山)型となり、DNNの特徴と似る。
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/e2170619-dac2-9252-9e54-5ed5d16cb16b.png)
  2. Lower-level特徴は学習で序盤で減少する(枝刈り)。
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/32b43c6d-b887-a6f7-eb21-317aca23d019.png)
  3. 高レベル特徴は序盤でよく蒸留する。
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/3ced03c8-4841-9adf-3268-35998e50536e.png)


# A Fast Post-Training Pruning Framework for Transformers

https://openreview.net/forum?id=0GRBKLBjJE

- 概要：Transformer向け再学習不要structured pruning
- 研究機関：Samsung
- 新規性：Fisher行列を使って最適なPTQをする方法
- キモ：
  1. フィッシャー情報量(ロスのHessian)を最小化する。
  2. マスク間の相関をとるために、Fisher行列をMHAやFFN等にブロック対角化する。
- 評価：BERT, GLUE, SQuADで精度1%劣化で1.56倍高速


# Pruning has a disparate impact on model accuracy

https://openreview.net/forum?id=11nMVZK0WYM

- 概要：枝刈りが公平性に与える影響
- 新規性：枝刈りと公平性の関係性を議論した。
- キモ：枝刈りで、精度が高いクラスはより高く、精度が低いクラスはより低くなり、またその主要因は勾配の大きさやHessianの大きさのばらつきであると主張した。
  勾配が大きかったり、Hessianが大きかったりすると、ロスが大きく変わり(stepが大きくなって)精度が下がりがちになるから。
- 評価：ResNetやVGGで評価した。
JavaScriptでの多次元配列の表現法

サイ本のお勉強メモ。
JavaScriptは本当の意味での多次元配列はサポートしていない。しかし配列の配列をいう方法で、それに近いことができる。配列の配列では、`[]`演算子を2回しようすれば、データ要素にアクセスできる。例えば行列を表す変数matrixが、数値の配列の配列だとする。各要素matrix[x]は、1つの数値配列になる、したがって、matrix[x][y]と書けば、この配列の特定の要素にアクセスできる。
次のコードは乗算テーブルとして２次元配列を使用している例である。
```js 
let table = new Array(10);
for (let i = 0; i < table.length; i++) table[i] = new Array(10);

for (let row = 0; row < table.length; row++) {
  for (let col = 0; col < table[row].length; col++) {
    table[row][col] = row * col;
  }
}

table[8][7] // 56
```
#### 勉強した本
https://www.amazon.co.jp/JavaScript-%E7%AC%AC7%E7%89%88-David-Flanagan/dp/4873119707/ref=pd_vtp_h_pd_vtp_h_sccl_1/355-2445868-3340539?pd_rd_w=LgR9i&content-id=amzn1.sym.cbe5b1af-8663-4a63-8153-1f9ef8eb65e4&pf_rd_p=cbe5b1af-8663-4a63-8153-1f9ef8eb65e4&pf_rd_r=HR26D47EAVPQZAE5CEDH&pd_rd_wg=EzTaw&pd_rd_r=89dc44bf-2d1a-4bc7-bc11-03b6377aecfe&pd_rd_i=4873119707&psc=1
【Pandas基礎】dataframeの並べ替えの基本

## はじめに

#### 自己紹介
Python勉強中の大学院生です。自分が詰まったところを記録していきます。
#### 記事を書くに至った経緯
pandasのdataframeの並べ替えをしたいときに、どうやるんだっけと迷うことが多かったので、ここで記事にして整理しようと思いました。


## 本記事の概要
##### どんな人に読んでほしいか
- Pythonのpandasを学び始めた人
- pandasのdataframeの並べ替えのやり方をうまく整理できていない人


##### この記事に書くこと、わかること
dataframeの並べ替えのやり方がわかります。具体的なメソッドは以下の2つです。

- df.sort_values() （列の要素で並べ替え）
- df.sort_index()（インデックスで並べ替え）


## 具体的な方法
まずは適当にdataframeを作成します。

```py:data.py

import pandas as pd

data = [[4, 2, 3, 1],
        [5, 8, 6, 7],
        [11, 10, 12, 9]]

df = pd.DataFrame(data=data,
                  index=['a', 'b', 'c', 'd'],
                  columns=['col1', 'col2', 'col3'])
df

```

|   | col1|  col2|  col3|
|---|---:|---:|---:|
|d |   4|    5|  11|
|b |   2|    8|  10|
|a |   3|    6|  12|
|c |   1|    7|  9|


### 列の要素で並べ替え | df.sort_values()

例えば、今回のデータフレームを'col1'の大きさを基準に並べ替えたいときは
`df.sort_values('col1')`
とすることで、

|   | col1|  col2|  col3|
|---|---:|---:|---:|
|c |   1|    7|  9|
|b |   2|    8|  10|
|a |   3|    6|  12|
|d |   4|    5|  11|

このように、col1の列で上から小さい順に並べ替えることができました。列基準で並べ替えたいときは`.sort_values()`を用いてカラム名を指定することで実行できます。

並べ替えを小さい順（昇順）ではなく大きい順（降順）にしたい場合は、引数に`ascending=False`を加えます。

`df.sort_values('col1', ascending=Fasle)`

|   | col1|  col2|  col3|
|---|---:|---:|---:|
|d |   4|    5|  11|
|a |   3|    6|  12|
|b |   2|    8|  10|
|c |   1|    7|  9|

※昇順の時は何も指定しなければ元々昇順になる設定になっているので、`ascending=True`と表記しなくても大丈夫です。降順にしたいときは指定する必要があります。


### インデックスで並べ替え | df.sort_index()

列の要素だけでなく、インデックス（行名）で並べ替えたい時もあると思います。そのときはシンプルに
`df.sort_index()`
を実行することで、

|   | col1|  col2|  col3|
|---|---:|---:|---:|
|a |   3|    6|  12|
|b |   2|    8|  10|
|c |   1|    7|  9|
|d |   4|    5|  11|

インデックスをアルファベット順に並べることができました。逆にしたいときは、さっきと同じように
`df.sort_index(ascending=False)`
とすればOKです。

## まとめ
- 列の要素で並べ替えたい→`.sort_values('column')`
- インデックスで並べ替えたい→`.sort_index()`



データフレームを並べ替えたい時にどっちだっけ？とよくごっちゃになっていたので、これを機に整理して使いこなしていきたいと思います。
ChatGPTと画像生成AIを用いてTRPGのプロフィール作ってみた


TRPGで使うプロフィールと立ち絵をChatGPTとStableDiffusionで生成してみました。
# TRPGとは
テーブルトークRPG（Tabletop Role-Playing Game）の略称で、参加者が架空のキャラクターを演じ、物語を進めるアナログゲームです。ゲームマスター（GM）がシナリオを進行し、プレイヤーはキャラクターの行動を決定します。サイコロを使って行動の成功や失敗を決めることが一般的です。

# Stable Diffusionとは
簡単に言うとテキストから画像を生成するAIのこと。
コードも一般公開されていて、無料で使える。

# とりあえず使ってみるには
以下のサイトに英語で文字を入れると生成されます。
[Stable Diffusion Online](https://stablediffusionweb.com/#demo)

colorful treeと入れてみた場合
![colorfultree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355282/119bf301-08c0-3e93-a69f-d12211eb809f.png)

# 実際に生成した画像について
事前にプロフィールはChatGPTで作成したので、できるだけそれに沿ったものを作成しました。

## ChatGPTで作成したプロフィール
![スクリーンショット 2023-05-03 165434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355282/be6f671d-3690-268c-7757-cbec8453aed0.png)

[ChatGPT](https://chat.openai.com/auth/login)
使うにはSign upが必要です。

## プロンプトについて
- 作成したプロンプト(絵の内容についてのワード)
```
[(white background:1.4)::5],original,(illustration:1.1),(best quality),(masterpiece:1.1),(extremely detailed CG unity 8k wallpaper:1.1),(detailed beautiful eyes:1.15),(glowing black eyes:1.25////), (beautiful face:1.15),(mid shot:0.95),(full body:1.5),Dynamic angle,(solo:1.2),((rugged) Japanese beautiful man:1.35),/old beautiful man/,/mountain climber/,(black hair), (+perfect hand+:1.21),(Jacket),
```
- ネガティブプロンプト
```
nsfw, owres, bad anatomy, bad hands, text, kimono, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry,missing fingers,bad hands,missing arms, long neck, Humpbacked
```

使用したモデル：diffusion_pytorch_model.safetensors
オプション：Restore faces,hires.fix←これがないと顔が崩れやすかった。

sampling steps:20
hires steps:30

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355282/63427c42-2344-b19a-15d6-37985e6f2481.png)

# できた画像
![00130-771704489 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355282/257a56e6-f6ee-cc1e-c779-4c1b96b30022.png)

# 参考サイト
[Hugging face](https://huggingface.co/)(モデルのダウンロード)

# 感想
- 顔や手がうまく生成されないことが多い。
- 使用するモデルによってプロンプトを調整する必要がある。
- それらしい画像を手っ取り早く作成するには便利だと感じた。
- すでに自分の中にあるイメージを再現するには試行錯誤する必要がある。
- AWSのSagemakerなど使ってモデル作ってみたい
テスト93

```vb

Sub Tablelink()
'テーブルの存在チェック後、テーブルリンクの解除と設定を
'する...〆(-ω- )ﾒﾓﾒﾓ
Dim db As dao.Database
Dim tmp_db As dao.Database
Dim tbl As TableDef
Dim td As dao.TableDef
Dim i As Integer
Dim str As String
Dim link_flg As Boolean
Dim Link_TName As String
Dim FSO As Variant

Set FSO = CreateObject("Scripting.FileSystemObject")

link_flg = False

Link_TName = "テストテーブル"

'外部の別のDB
'str = "C:\Users\User\Desktop\VBA関連\VBA練習\Access練習\リンク.accdb"
str = "C:\Users\User\Desktop\VBA関連\VBA練習\Access練習\リンク2.accdb"

'対象データベースを開く
Set tmp_db = OpenDatabase(str)

'テーブルの存在チェック
If IsTable(tmp_db, Link_TName) = False Then

    MsgBox FSO.GetFileName(str) & "に「" & Link_TName & "テーブル」が存在しません。", vbCritical, "中止"
    tmp_db.Close
    Set tmp_db = Nothing
    End

End If

tmp_db.Close
Set tmp_db = Nothing
    
Set db = CurrentDb

For i = db.TableDefs.Count - 1 To 0 Step -1

    Set td = db.TableDefs(i)
    
    If td.Name = Link_TName Then
        '指定のリンクしたいテーブルを取得
        
        If (td.Attributes And dbAttachedTable) Then
            '既にリンクされていたらリンクを解除
            db.TableDefs.Delete (Link_TName)
            
        End If
        
        '新しくリンクする
        Set tbl = db.CreateTableDef(Link_TName)
        tbl.Connect = ";DATABASE=" & str
        tbl.SourceTableName = Link_TName
        db.TableDefs.Append tbl

        link_flg = True
        
        Exit For
        
    End If
    
Next

If link_flg = False Then

    '新しくリンクする
    Set tbl = db.CreateTableDef(Link_TName)
    tbl.Connect = ";DATABASE=" & str
    tbl.SourceTableName = Link_TName
    db.TableDefs.Append tbl

End If


db.TableDefs.Refresh

'-----------------------------------

db.Close

Set db = Nothing
Set tbl = Nothing

Set db = Nothing

End Sub


Public Function IsTable(ByVal db As dao.Database, _
                        ByVal strTableName As String) As Boolean
Dim myTDef  As dao.TableDef

IsTable = False

For Each myTDef In db.TableDefs

    Debug.Print myTDef.Name
    
    If myTDef.Name = strTableName Then
    
        IsTable = True
        Exit Function
        
    End If
    
Next

End Function
'メモ
'チェック箇所
'・ファイルパス
'・対象となる全てのテーブル
TravisCIでPython3.10を指定するには、Ubuntuバージョンを16.04(Bionic)以上にする必要がある

:::note
2023/05/03時点のTravisCIの状態です。
:::




# やりたいこと
TravisCI上で、Python in Ubuntu OSのテストを実施したいです。


# 概要
UbuntuのデフォルトバージョンはXenial(16.04)です。

>We use Ubuntu Xenial 16.04 as default. You find more about packages, tools and settings in Ubuntu Xenial 16.04.[^1]

[^1]: https://docs.travis-ci.com/user/reference/linux/#default

Ubuntu 16.04ではPython3.9までしか選択できません。[^2]

https://docs.travis-ci.com/user/languages/python/#python-versions

[^2]: Archは"x86_64"で確認


Python 3.10を利用するには、Ubuntu 18.04(Bionic)以上にする必要があります。
Python 3.11もUbuntu 18.04以上で利用できます。

最新のPythonでテストする場合は、`dist`キーにはデフォルトより上のUbuntuバージョンを指定した方がよいです。

# 所感
Ubuntu 16.04は2023/05時点でサポートが切れているので、TravisCIはデフォルトのOSバージョンをUbuntu 20.04(Focal)以上にした方がよい気がします。
📖「良いコード／悪いコードで学ぶ設計入門」（第５章 低凝集）を読んだ感想

## 前回の話
https://qiita.com/tomonac/items/a553f256b071fff98906

## 感想　（第5章 低凝集）
![良いコード悪いコード.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3144766/9643e4f7-9dc3-178b-cde6-f7a9a180974b.png)



**[ 学んだこと ]**

- 凝集度とは？
  - モジュール内における、データとロジックの関係性の強さを表す指標
    - 高凝集：変更に強い望ましい構造
    - 低凝集：壊れやすく変更が困難な構造
- 初期化処理の分散はやめよう
  - `new Hoge(10)`、`new Hoge(20)`のように関連ロジックが分散すると修正時の影響範囲が広がるのと考慮漏れが発生する
    - → `new Hoge.forMenber()`のように Hoge クラス内に定義し、メソッドを呼ぶだけになるように実装すべき
    - 生成ロジックが増えたら、ファクトリクラスを見直すのば良い
- 引数の扱いを間違えると低凝集になる可能性あり
  - 無関係のクラスに対して、引数のみだけで、値を操作し出力（返却）するような処理を出力引数と言う。この構成は低凝集に繋がる。あるべきクラスに定義するのが良い
  - 多すぎる引数はやめよう
    - 引数の数が多いと、間違って渡してしまう可能性あり

## 次回

https://qiita.com/tomonac/items/0946c7e5faab791ed736
Macのオーディオ出力装置の切替をChatGTPに質問して自動化する

# 目的
Macで無線でのデュアルディスプレイ時に毎回オーディオ出力設定の変更が必要になり、その手間を省きたい。

# デュアルディスプレイ環境
Macのデュアルディスプレイ環境をFire TV StickとAirReceiverで実現している。
Macからディスプレイに接続した際にオーディオ出力もディスプレイに変わってしまうのが難点。

# 実装方法をChatGTPに聞いてみる
MacのAutomatorの存在は知っていたので、Automatorで実装する方法を聞いてみた。

## 質問内容と回答

### 質問内容
- macでAutomatorを使用してAudio MIDI設定でサウンド出力装置を変更する方法を教えてください

### ChatGPTからの回答

MacでAutomatorを使用してAudio MIDI設定でサウンド出力装置を変更するには、次の手順に従ってください。

1. Automatorを開く:
   - 「アプリケーション」フォルダからAutomatorを探し、クリックして開きます。

2. 新しいワークフローを作成する:
   - 「ファイル」メニューから「新規」を選択します。
   - ワークフロータイプとして、「クイックアクション」を選択し、「選択」ボタンをクリックします。

3. ワークフローを設定する:
   - 上部の「ワークフローが受け取る現在の入力」メニューで、「なし」を選択します。

4. 「シェルスクリプトの実行」アクションを追加する:
   - 左側のライブラリパネルで、「ユーティリティ」カテゴリをクリックします。
   - 「シェルスクリプトの実行」アクションを見つけて、ワークフローエリアにドラッグアンドドロップします。

5. シェルスクリプトを記述する:
   - 「シェル」ドロップダウンメニューで、「/bin/bash」を選択します。
   - 「スクリプト」テキストエリアに次のスクリプトを貼り付けます（デバイス名を適切なものに置き換えてください）:

```
DEVICE_NAME="Your Device Name"
AUDIO_DEVICE_ID=$(system_profiler SPAudioDataType | grep -B 5 -A 1 "$DEVICE_NAME" | awk '/^ *Output Device ID:/{print $NF}')
switchaudiodevice -s $AUDIO_DEVICE_ID
```

**注意**: 上記のスクリプトでは、`switchaudiodevice` コマンドを使用しています。これは、[SwitchAudioSource](https://github.com/deweller/switchaudio-osx) ツールの一部であり、事前にインストールする必要があります。ターミナルで次のコマンドを実行してインストールしてください:

```
brew install switchaudio-osx
```

もしHomebrewがインストールされていない場合は、まず [Homebrew](https://brew.sh/) をインストールしてください。

6. ワークフローを保存:
   - 「ファイル」メニューから「保存」を選択し、名前を付けて保存します。

7. クイックアクションを利用:
   - 作成したクイックアクションは、Finderやタッチバーなどで利用できます。

これで、Automatorを使ってAudio MIDI設定でサウンド出力装置を変更する方法が完成しました

---

す、すごい！これ通りにやればできそう。
ということで、実際に回答通りに試したところ...できませんでした（笑


# 回答内容の間違っていたところ

回答内容はほとんど問題なく、`SwitchAudioSource`コマンドの使用方法が間違っていました。
以下のコマンドで切替ができました。

```shell
/opt/homebrew/bin/SwitchAudioSource -s 出力装置名
```
出力装置名は
```shell
/opt/homebrew/bin/SwitchAudioSource -a
```
で確認できます。

[ドキュメント](https://github.com/deweller/switchaudio-osx#usage)を見ると、`-s`オプションで出力装置名を指定するだけでよかったみたいです。
回答では、名前でなくIDを指定していたためエラーになりました。
また、Automatorで使用されるシェル環境では、`SwitchAudioSource`コマンドはフルパス指定でしか実行できませんでした。
これについては、エラー時にChatGPTに質問して解決できました。

# 実装方法
以上より、自動化する手順は以下の通りとなります。


1. Automatorを開く:
   - 「アプリケーション」フォルダからAutomatorを探し、クリックして開きます。

2. 新しいワークフローを作成する:
   - 「ファイル」メニューから「新規」を選択します。
   - ワークフロータイプとして、「クイックアクション」を選択し、「選択」ボタンをクリックします。

3. ワークフローを設定する:
   - 上部の「ワークフローが受け取る現在の入力」メニューで、「なし」を選択します。

4. 「シェルスクリプトの実行」アクションを追加する:
   - 左側のライブラリパネルで、「ユーティリティ」カテゴリをクリックします。
   - 「シェルスクリプトの実行」アクションを見つけて、ワークフローエリアにドラッグアンドドロップします。

5. シェルスクリプトを記述する:
   - 「シェル」ドロップダウンメニューで、「/bin/bash」を選択します。
   - 「スクリプト」テキストエリアに次のスクリプトを貼り付けます（デバイス名、コマンドのpathを適切なものに置き換えてください）:

```
コマンドのpath/SwitchAudioSource -s 出力装置名
```

**注意**: 上記のスクリプトでは、`SwitchAudioSource` コマンドを使用しています。これは、[SwitchAudioSource](https://github.com/deweller/switchaudio-osx) ツールの一部であり、事前にインストールする必要があります。ターミナルで次のコマンドを実行してインストールしてください:

```
brew install switchaudio-osx
```

もしHomebrewがインストールされていない場合は、まず [Homebrew](https://brew.sh/) をインストールしてください。

6. ワークフローを保存:
   - 「ファイル」メニューから「保存」を選択し、名前を付けて保存します。

7. クイックアクションを利用:
   - 作成したクイックアクションは、Finderやタッチバーなどで利用できます。

# 終わりに

作成したクイックアクションに適当な名前をつけてDockに表示させることで、ワンクリックでオーディオ出力装置を切り替えれるようになりました。
Automatorの使用経験がなくてもChatGTPに質問してここまで短時間でできるとは思っていなかったので驚きました。
＠Bindingについて勉強

## @Bindingについて調べたのでまとめていきます。

SwiftUIの講義において、@Bindingは非常に重要な概念です。@Bindingは、親ビューから子ビューに値を双方向で渡すために使用されます。つまり、値の変更が子ビューから親ビューにも反映されるようになります。

#### まず、@Bindingを使用するためには、次の手順を実行する必要があります。

１、親ビューの中で、値を保持するためのState変数を作成します。
２、子ビューを作成し、@Binding属性を使用して、値を受け取るバインディング変数を定義します。
３、子ビュー内で、バインディング変数を使用して値を読み取り、変更します。

```swift
// 親ビュー
struct ParentView: View {
    @State private var myValue = false
    
    var body: some View {
        VStack {
            Text("Parent View")
            
            ChildView(myValue: $myValue) // 子ビューにバインディング変数を渡す
        }
    }
}

// 子ビュー
struct ChildView: View {
    @Binding var myValue: Bool // バインディング変数
    
    var body: some View {
        VStack {
            Text("Child View")
            
            Toggle(isOn: $myValue) {
                Text("Toggle Value")
            }
        }
    }
}

```

この例では、ParentViewが親ビューであり、myValueというBool型の状態変数を持っています。ChildViewが子ビューであり、myValueを@Binding属性を使って受け取るバインディング変数として定義しています。

ChildView内では、Toggleを使用してmyValueを切り替えることができます。親ビューのmyValueの変更は、子ビューで反映され、その逆も同様です。

このように、@Binding属性を使用することで、親ビューと子ビュー間での値の双方向の通信が実現されます。


もう一つ例をみてみます。

```swift
import SwiftUI

// ユーザ情報を表す構造体
struct User {
    var name: String
    var age: Int
}

// 親ビュー
struct ParentView: View {
    @State private var user = User(name: "John", age: 30)
    
    var body: some View {
        VStack {
            Text("Name: \(user.name)")
            Text("Age: \(user.age)")
            
            ChildView(user: $user) // 子ビューにバインディング変数を渡す
        }
    }
}

// 子ビュー
struct ChildView: View {
    @Binding var user: User // バインディング変数
    
    var body: some View {
        VStack {
            TextField("Name", text: $user.name)
            Stepper(value: $user.age, in: 0...100) {
                Text("Age: \(user.age)")
            }
        }
        .padding()
    }
}


```

この例では、親ビューにはUser型の状態変数 user があります。子ビューである ChildView は、この状態変数を受け取るバインディング変数として @Binding var user を定義しています。

ChildView内のUI要素は、ユーザ情報を編集するためのものです。TextFieldは名前を編集し、Stepperは年齢を編集します。これらの要素は、親ビューの状態変数 user とバインディングされているため、値の変更が親ビューにも反映されます。

この例では、親ビューでUserの名前と年齢が表示され、子ビューでこれらの値を編集できます。子ビューで値を変更すると、親ビューの表示も更新されます。

このように、@Bindingを使用することで、親子間での値の双方向の通信を行うことができます。
開発をしているとView間で値を利用し合いたい時が多くあります。そんな時にこの@Bindingは欠かせない概念となります。