OmniAICreator/Qiita-1.07M huggingface dataset:
クラスメソッドは特異メソッドの一種

>RubyのAPIドキュメントでもクラスメソッドという用語は用いず、「特異メソッド」として説明されています

# 特定のオブジェクトに絞るか絞らないかの違い
```rb
irb(main):001* class User
irb(main):002*   def self.hello
irb(main):003*     "hello"
irb(main):004*   end
irb(main):005*
irb(main):006*   class << self
irb(main):007*     def hi
irb(main):008*       "Hi."
irb(main):009*     end
irb(main):010*   end
irb(main):011> end
=> :hi
irb(main):012> alice = 'I am alice.'
=> "I am alice."
irb(main):013* def alice.hello
irb(main):014*   "hello"
irb(main):015> end
=> :hello
irb(main):016* class << alice
irb(main):017*   def hi
irb(main):018*     "Hi"
irb(main):019*   end
irb(main):020> end
=> :hi
irb(main):021> User.hello
=> "hello"
irb(main):022> User.hi
=> "Hi."
irb(main):023> alice.hello
=> "hello"
irb(main):024> alice.hi
=> "Hi"
```

# クラスメソッドが特異メソッドあること
```rb
irb(main):001* class User
irb(main):002> end
=> nil
irb(main):003* def User.hello
irb(main):004*   "Hello"
irb(main):005> end
=> :hello
irb(main):006* class << User
irb(main):007*   def hi
irb(main):008*     "Hi."
irb(main):009*   end
irb(main):010> end
=> :hi
irb(main):011> User.hello
=> "Hello"
irb(main):012> User.hi
=> "Hi."
```

https://gihyo.jp/book/2017/978-4-7741-9397-7
使おうとしてみた

microCMSでこんなことができた！あなたのユースケースを大募集 by microCMS
Calendar 2024
https://qiita.com/advent-calendar/2024/microcms
day 12 使ってみた

# 登録
Mail Addressp, Password登録。

# 選択
Templateから作るか、１から作成するか。

最初に１からは無理っしょ。

Templateを選ぶ。

一覧が出る。

技術では、RUST, Python, C++, Fortranがない。泣

Angular
Astro
Django
Flutter
Gatsby
jQuery
Kotlin
Laravel
Next.js
App Router
Pages Router
Nuxt.js
PHP
Qwik
Qwik City
React
React Native
RedwoodJS
Remix
Ruby on Rails
Slim
SolidJS
SolidStart
Svelte
SvelteKit
Swift
Vanilla JS
Vue.js

シンプルなコーポレートサイトを選ぶ。

プレビューを見る。

詳細へ

このテンプレートを利用。

Github リポジトリの指定
ここで挫折中。連携失敗。
やりたいことも得意なこともない、という方にむけてのキャリアの考え方のヒント

こんにちは、GxPの石村です。
この記事は[グロースエクスパートナーズ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/gxp)の4日目です。

私は株式会社GxPでヘルスケア事業本部の本部長を務めており、「自分たちで自分たちの仕事を面白くする」というコンセプトを掲げています。
そのサブテーマとして「価値創造（顧客／世の中の役に立つものが作れているという実感）」「技術力（技術的にチャレンジできているという実感）」「チームワーク（仲間と協力し関係性の質を結果の質につなげていける環境）」の3つのどれかに各々取り組んでもらっています。

このテーマを掲げる上であがる声のひとつが「自分はどれに対してもやりたいとか得意とかない」といった声です。
これは目標設定をする時にもよく聞く話ですね。
そんな人に向けて少しでもヒントになればと今回の記事を書いてみます。

# 向いていることをさがす

これが好き！これをやったときに達成感を感じる！といったことが見つかるとよいのですが、なかなか難しいという方は以下のようなことを探してみてはいかがでしょうか。

* 自分にとっては普通のことだが周りから感謝されること
* 他の人は嫌がるが自分にとってはそんなに苦痛ではないこと
* ないがしろにされると気になってしょうがないこと

## 自分にとっては普通のことだが周りから感謝されること

チームのメンバーから直接感謝されたり、上長から褒められたことはないですか？
それに対して「こんなの普通のことだ」とか「あの人の方がもっと上手で私なんてまだまだ」と言って「それは私に向いていることではない」と否定していませんか？

「向いていること」を探すのに、そこにキラキラした情熱を注げないとダメだ、とか、誰よりも秀でていないとダメだ、なんてことはありません。
数名集まったときに、このメンバーだったら他の人より少し経験が多いかな？少しうまくやれるかな？ぐらいでいいのです。

これは周り人にとっては「その人の得意なこと」が明確なのに、本人だけが認めていないパターンです。

## 他の人は嫌がるが自分にとってはそんなに苦痛ではないこと

1つ目に似ているのですが、他の人が進んでやってくれない仕事で「私やりますよ」となる仕事です。
別にうまくやれるってことはないけど、他の仕事と比べて嫌だとか苦痛だとは思わない、ということはないですか？

「落ちているボールを拾うのが得意」という方もいますね。
スペシャリストではないことに劣等感を感じてしまう人もいますが、そういう方はゼネラリストで視野が広いのでチームにとって非常に助かる存在です。

テストや管理を専門としている方にはこのパターンに当てはまる人が結構いるように思います。

## ないがしろにされると気になってしょうがないこと

これは今やっているかどうかに関わらず、どんなことに関心が向くかです。
「もっとこれを大事にするべき」「この作業をおざなりにするなんてけしからん」とぷりぷり怒っている人をたまに見かけるのですが、それを自分がやればいいのです。
例えば、設計書がメンテナンスされていない、ソースコードが汚い、テストコードがない、新しく入った人に不親切な資料しかない、雑談が少ない、タスク管理がわかりにくい、などです。

日々の仕事の中で「やった方がいいこと」はたくさんありますが、「やれること」には限りがあります。
そうなるとチームの中でリーダーシップを発揮している人が何を選択するかによって「やってくれること」「やってくれないこと」が出てきますよね。

リーダーに「これをやるべきだ」と主張してもなかなか優先順位を上げてもらえなかったり、やってくれても「違うそうじゃない」と納得がいかなかったりしていませんか？
「これは私の仕事じゃない」という立場で文句を言い続けるのは本人と周囲の双方にストレスが溜まります。
一番関心を持っていて、こだわりのある人が自分でやればいいんです。
自分でやればリーダーシップも育まれ、実践する難しさを乗り越える経験ができるため、今後のキャリアにも役立つはずです。

# あとがき

少しはヒントになったでしょうか？
かくいう私も実は「ないがしろにされると気になってしょうがないこと」が今のキャリアに繋がっています。
新卒のころはデータを眺めたりいじったりするのが好きで、RDB関連の仕事を中心に担っていたのですが、今ではすっかりマネジメント方面に染まっています。
そのきっかけは「なんでもっと後輩の育成に関心を持ってくれないんだろう」といった育成や組織の体制についての不満がたくさんあって、イライラしていたことでした。
それを自分でやろうと決めたとき、それに責任を持つ人の職種は何だろうか？と考えた結果がマネジメントでした。
私をよく知る人たちには最初は「おまえはマネジメントじゃないと思っていた」と言われたものですが、今では違和感がないようです。
私自身も当時はやってみて「やっぱ違う」と思ったらマネジメントはやめようと思っていました。
しかしやってみれば「もっと知りたい」「もっとうまくやれるようになりたい」が尽きない分野で、難しいけれどやりがいを感じています。

今キャリアに悩んでいる方にも、何かこれを伸ばしてみようかなと思うものが見つかりましたら幸いです。
Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.23.dylib (LoadError) を解決

railsクレデンシャルの修正を行おうと下記コマンドを実行したところ、エラーが表示されました。

```
$ EDITOR="vim" bundle exec bin/rails credentials:edit
```

```
<internal:/Users/aisplay/.rbenv/versions/3.2.3/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require':
dlopen(/Users/aisplay/project/EXMAPLE-REPOSITORY/vendor/bundle/ruby/3.2.0/gems/mysql2-0.5.6/lib/mysql2/mysql2.bundle, 0x0009):
Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.23.dylib (LoadError)
Referenced from: <XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX> /Users/aisplay/project/EXMAPLE-REPOSITORY/vendor/bundle/ruby/3.2.0/gems/mysql2-0.5.6/lib/mysql2/mysql2.bundle
Reason: tried: '/usr/local/opt/mysql/lib/libmysqlclient.23.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/mysql/lib/libmysqlclient.23.dylib' (no such file), '/usr/local/opt/mysql/lib/libmysqlclient.23.dylib' (no such file), '/usr/local/lib/libmysqlclient.23.dylib' (no such file), '/usr/lib/libmysqlclient.23.dylib' (no such file, not in dyld cache) - /Users/aisplay/project/EXMAPLE-REPOSITORY/vendor/bundle/ruby/3.2.0/gems/mysql2-0.5.6/lib/mysql2/mysql2.bundle
```

エラーメッセージを見ている感じだと、`Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.23.dylib (LoadError)`とあるので、mysqlのlibで`libmysqlclient.23.dylib`の読み込みに失敗しているよう。

試しに確認。

```
$ cd /usr/local/opt/mysql/lib/
$ ls -a
```

見た感じ`libmysqlclient.23.dylib`はなくて、`libmysqlclient.24.dylib`がある。

どうやら`libmysqlclient.23.dylib`が提供されているのはmysql@8.3で、
`libmysqlclient.24.dylib`はmysql@9.0だった。

mysqlのバージョンを確認してみる

```
$ mysql --version
```
やはり9.0が使われている！
最近PCを新しくして`brew install mysql`を行ったのですが、最近 安定版が9.0になったようで、その時にうっかりmysql9をインストールしてしまったようです。

そして使用しているgem　`mysql2`の最新版が0.5.6（更新時点）で、
libmysqlclient 8.3までしかサポートしていないと書いてある。。
https://github.com/brianmario/mysql2/releases/tag/0.5.6


 ## mysqlをダウングレードする

そもそも今のプロジェクトではmysqlのバージョンは8なので、インストールしました。

```
$ brew install mysql@8.0
```
brewで提供されている8系は8.4もありましたが、8.4では9.0と同じく`libmysqlclient.24.dylib`が使われていたので、8.0をインストール。
ちなみに`brew search mysql`してインストールできるバージョンを確認してみましたが、8.3がなかったので8.0をインストールしました。

一緒にmysql-client@8.0もインストール。

```
brew install mysql-client@8.0
```

開発ディレクトリ内で、参考Issue（後述）通りにコマンドを実施。
```
$ bundle config --local build.mysql2 -- --with-mysql-dir=$(brew --prefix mysql-client@8.0)

上記設定が反映されたかを確認
$ bundle config

$ bundle install
```
これでもエラーが解消されなかったので、
一旦vendor配下のbundleディレクトリを削除してから再度`bundle install`実行したら、エラーが解消されました！


## 参考
このIssueの回答がめちゃめちゃ参考になりました🥲🥲

https://github.com/brianmario/mysql2/issues/1346#issuecomment-1925565106
ショートカットappを使ってTerminal,Vscodeをフォルダー指定で開く

# ショートカットappを使って
### Open in Terminal
https://www.icloud.com/shortcuts/d46cca16d39541f7b6e2097c6af5fa08

### Open in Vscode
https://www.icloud.com/shortcuts/c5e50974a8394ed6a7cd670a4a6724e9

### 使い方
https://qiita.com/soun1218/items/8b9cd20af670cb24921c

このページを参考にしてfinderにアイコンを追加して、フォルダーを開いたらアイコンをクリック。

以下を参考に作成

https://note.com/at_ignister/n/na9a2365b5130

https://rennnosukesann.hatenablog.com/entry/2018/12/21/202658
AWSスイッチロールURLのパラメーター

# AWSスイッチロールURL

```
https://signin.aws.amazon.com/switchrole?roleName={Role名}&account={AWS_ID}
```
AWS標準のURLにはRole名とAWSアカウントIDが含まれています。

```
https://signin.aws.amazon.com/switchrole?roleName=TestRole&account=123456789012
```
上記のURLの場合は下記のようになりますが、URLパラメーターを追加する事で表示名と表示色を指定する事もできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/3e4e47f9-7f76-6a51-30ce-50bb5902fbec.png)

URLパラメーターで指定できるのは4個あります。

## account
スイッチロール対象のAWSアカウントIDを指定します。

## roleName
スイッチロール対象のRole名を指定します。

## displayName
空欄だとroleNameが表示されるので、アカウントを区別できる表示名を指定した方が良いです。
URLエンコードすれば日本語も設定可能です。

```日本語
displayName=%E6%97%A5%E6%9C%AC%E8%AA%9E
```
「日本語」を指定する場合は下記のようになります。

## color
16進数のカラーコードを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/ddd5653d-bfcc-bb32-3cfd-9cbeb40075c8.png)
画面では選択（None、Red、Orange、Yellow、Green、Blue）になっていますが、URLパラメータで任意のカラーコードを設定できます。

```Gray
color=AAAAAA
```
灰色を指定する場合は上記のようになります。

## サンプルURL
```
https://signin.aws.amazon.com/switchrole?roleName=TestRole&account=123456789012&displayName=%E6%97%A5%E6%9C%AC%E8%AA%9E&color=AAAAAA
```
上記のURLは下記のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/875f1ee5-5be5-9826-f7b2-f2193d676adf.png)

表示色が空欄になっていますが、スイッチロールすると指定した色で表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/3be1eb8d-e743-fc9d-8111-bfeb00feb134.png)
MIPI CSIの種類（15・22・24ピン）

Mipi CSIは規格であり、ピン数に制約がないことがわかったので記事にします。
発端はRDK-X3のイベントにて __Raspberry Piで採用されている15ピン__ でも __22ピン__ でもない __24ピン__ が使われている理由について質問したことがきっかけです。
# MIPI CSI
__RDK-X3__ ではカメラ入力の __MIPI CSI__ に __24Pin__ が使用されています。
__Raspberry Pi__ は __15ピン、22ピン__ が採用されています。
先日のイベントで確認したところ __24ピンの製品が多い為に、24ピンにした__ とのことでした。
しかし、調べたところ22ピンと24ピンが混在しており、特に24ピンが多いというわけではなさそうでした。
さらに、24ピンと22ピンの規格に違いがあり、24ピンの方が性能が上という事も無いようです。
# MIPI CSIの規格
MIPI CSIのピン構成は以下のようです。
22ピンと24ピンはピンアサイン以外に大きな違いが無いことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/aecb12df-dd15-b21c-662d-9df677d5c428.png)
# Aliexpress
Aliexpressで探すと24ピンのものを見つけることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/9dd20f0b-9909-f778-3f8d-17d6caa94c83.png)

しかし、RDK-X3に対応しているカメラモジュールはRaspberry Pi用の22ピンや15ピンが多く２４ピンは見つかりませんでした。
このため、変換コネクタを使用する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/50bc11f0-7a8d-df9f-b4b6-fc24c1ecdf18.png)
### 22Pinの例
- JETSON ORIN NANO 
- Raspberry Pi5
- RDK-X5
- Kakip
### 24ピンの例
- AIO-3288J
- RDK-X3
- Coral Dev Board
### 15ピンの例
- Raspberry Pi4まで
- RDK ULTRA
- Jetson Nano
など多数・・・
# 15ピン用変換アダプタ
24ピンのコネクタに15ピンのカメラを使用できるようにする変換するアダプタが大量に販売されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5eb9c652-3610-e171-580c-6072cc934a30.png)
スイッチサイエンスでも販売しています。
変換アダプターはフレキ基板で曲げを推奨することは無いと思いますが、一定レベルまでは曲げることができます。
![RDK-X3-camera.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ee76ee02-40c0-106c-b413-19a72e23c40c.jpeg)
ただし、22ピン用カメラを24ピンにする変換アダプターは販売されていません。
この辺は規格統一されていれば良いのにと思わずにいられません。
# RDK-X5は22ピン
MIPI CSIの調査をしていたところRDK-X5のCSIは22ピンであるようです。
このため、高須正和が言っていることは嘘であったことがわかりました。
せっかくメーカーの人間が来ているのに通訳をせず、勝手に独断で嘘の返答をしてメーカーの人間から解答をもらう事が出来ませんでした。
なぜ、高須氏は嘘を吹聴するのでしょうか？
通訳だけやればいいのに、非常に残念です。
なお、RDK-ULTRAは15ピンです。
https://d-robotics.github.io/rdk_doc/en/Quick_start/hardware_introduction/rdk_x5/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5731e312-b7f5-aa65-de1e-5c835eee8de2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f3bd7b96-09f0-fa4c-0190-53e696fd166f.png)
このため、なぜ、RDK-X3が24ピンなのか最後までわからず、本当に困ってしまいました・・・
高須氏が余計な事を言わないで通訳をしてくれればよかっただけに非常に残念です。
特異メソッド

# 特定のオブジェクトしか使えないメソッド
```rb
irb(main):001> alice = "I am　Alice."
=> "I am　Alice."
irb(main):002> bob = "I am Bob"
irb(main):003>
=> "I am Bob"
irb(main):004* def alice.shuffle
irb(main):005*   chars.shuffle.join
irb(main):006> end
=> :shuffle
irb(main):007> alice.shuffle
=> "cl .am　IieA"
irb(main):008> bob.shuffle
(irb):8:in `<main>': undefined method `shuffle' for "I am Bob":String (NoMethodError)
```
# オブジェクトが数値やシンボルだけは特異メソッドは使えない
```rb
irb(main):009> n = 1
=> 1
irb(main):010* def n.foo
irb(main):011*   'foo'
irb(main):012> end
(irb):10:in <main>': can't define singleton (TypeError)
...
irb(main):013> sym = :alice
=> :alice
irb(main):014* def sym.bar
irb(main):015*   'bar'
irb(main):016> end
(irb):14:in `<main>': can't define singleton (TypeError)
```
# 上の書き方以外にも特異メソッドは指定できる
`class << alice`
```rb
irb(main):017> alice = "I am Alice"
=> "I am Alice"
irb(main):018* class << alice
irb(main):019*   def shuffle
irb(main):020*     chars.shuffle.join
irb(main):021*   end
irb(main):022> end
=> :shuffle
irb(main):023> alice.shuffle
=> "I Aale mci"

irb(main):025> bob = "BoB hi!"
=> "BoB hi!"
irb(main):026> bob.shuffle
(irb):26:in `<main>': undefined method `shuffle' for "BoB hi!":String (NoMethodError)

bob.shuffle
   ^^^^^^^^
irb(main):027> alice.shuffle
=> "em li caAI"
```
https://gihyo.jp/book/2017/978-4-7741-9397-7

# 感想
特異メソッドも知らなかった
MacのNode.jsバージョン管理をVoltaからmiseに変更する

これまでNode.jsのバージョン管理は長いことnodebrewを使ってきて最近Voltaに変えたのですが、一緒に仕事をしているエンジニアがmiseを使っていると聞いて、Node.js以外にもバージョン管理ができて便利と強く進められたので、miseを使ってみようと思い備忘録として残します。

miseリンク
https://mise.jdx.dev/

# miseのインストール

インストール方法は下記参照
https://mise.jdx.dev/getting-started.html

`curl https://mise.run | sh`

```
% curl https://mise.run | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6333  100  6333    0     0  44084      0 --:--:-- --:--:-- --:--:-- 43979
mise: installing mise...
######################################################################## 100.0%
mise: installed successfully to /Users/cc/.local/bin/mise
mise: run the following to activate mise in your shell:
echo "eval \"\$(/Users/cc/.local/bin/mise activate zsh)\"" >> "/Users/cc/.zshrc"

mise: this must be run in order to use mise in the terminal
mise: run `mise doctor` to verify this is setup correctly

% ~/.local/bin/mise --version
2024.11.29 macos-arm64 (644cb6d 2024-11-25)
```

## shimsの設定
shimsを設定しておくと便利なのでやっておく。

`% echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc`

```
% source ~/.zshrc
% mise -v
2024.11.29 macos-arm64 (644cb6d 2024-11-25)
```

# Nodeのインストール

https://mise.jdx.dev/dev-tools/#mise-install

Node.js 20.12.2をインストールする場合。

`mise install node@20.12.2`

```
% ~/.local/bin/mise install node@20.12.2
mise node@20.12.2 ✓ installed  
```

インストールしたNodeのバージョンに切り替えする。

https://mise.jdx.dev/dev-tools/#mise-use

`mise use node@20`

プロジェクトフォルダにmise.tomlがあった場合、下記のようなエラーが表示されるので、`mise trust`とする。

```
mise ERROR error parsing config file: ~/local/project1/mise.toml                                            
mise ERROR Config file ~/local/project1/mise.toml is not trusted.
Trust it with `mise trust`.
mise ERROR Run with --verbose or MISE_VERBOSE=1 for more information
```

## mise ls

mise.tomlファイルに記述されているツールのバージョンと、現在インストールされているバージョンが異なる場合は、mise ls で下記の通り表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/d4ff820f-ff5e-97ee-4ebc-8612ac5215dc.png)

## mise install

プロジェクトフォルダに mise.tomlファイルがある場合は、`mise install`すると必要なツールがインストールされる。

下記のエラーが表示された時は、`brew install gpg`する。

```
Missing following dependency: gpg
mise ERROR ~/.local/share/mise/plugins/yarn/bin/install failed
```

再度`mise install`

```
% mise install             
mise yarn@1.22.22 ✓ installed                      
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/45763f04-f88a-82ef-dafe-c4eda368eeb6.png)
おかあさんといっしょの特集みてスクラムに関して思ったこと

おかあさんといっしょの特集みてたらスクラムマスターは保育園の先生と似ている話を思い出したのと、それについて色々おもうことがあったのでメモ

思い出したもの：https://kawaguti.hateblo.jp/entry/2019/01/29/225720
見てたもの：https://www.nhk.jp/p/okaasan/ts/ZPW9W9XN42/blog/bl/plLar1eke9/bp/pzkqmOwY7M/

## ストレスフルな現場
* 番組に出たい親御さんは多く、年間200回で1回の収録で選ばれる子どもたちは４０人ほど。倍率は20倍。
* 出てる子どもたちは厳格に数え年で3歳から4歳まで
* 中にはもんぺもいるでしょう…
* そんな中で一番気を遣っているのが安全
  * ドアノブや扉の間など子どもたちに対して危ないところはスタッフを配置して怪我をしないようにしている
  * ただスタッフを配置するだけではなく子どもたち側から見れば遊び？と思えることをしている
  * 例えばトンネル遊び。腕の下を通らせることで子どもたちを飽きさせないのと同時に子どもたちの経路を制限して安全を確保している
  * **これはここだけの話ではなくて、どこでもそう。人を犠牲にして成果だしたところで意味がない**
  * 人に対しての安全だけではなくモノに対してもそうでフールプルーフの考え方はスクラム以外でも通じる考え
  * スクラムメンバーから見ても大変だけどモチベーションも与えて、それでリスクヘッジもできるならいいよね

## 子どもたちに言うことを聞かせるには

* セサミストリートのように海外では犯罪につながる恐れから子供は出さないし出してもパペットだけだす
* なんでおかあさんといっしょは逆を行くか
  * おかあさんといっしょは最初は3~4歳を対象にしていて、次に2~3歳、現在は2~4歳が対象
  * この頃の子供は大人の動きを見るのではなく子供の動きを見る  
    * どこかで拾った記事で、小学生に新しいこと伝えるとそれをその言葉のまま実行する子は少なく、まずは他の子どもたちの様子を見ていた(原文どこかいった)
  * 1対1で教えるならまだしも多人数に対して言うことを聞かせようとするには、**最初に動く敏感な子どもたちにどうアプローチするかが重要**
  * 一番興味のある子どもたちは一番前に来て自分のやることの一挙一投足を観察して反応する
  * そしてその子どもを見て他の子どもたちが真似する
  * 番組では元気よく「キャー！」という声をあげた子どもにお姉さんが驚くのをみて他の子どもたちも「キャー！」と伝染していった
  * イノベーター理論にも通じそうで、アーリーアダプターにインフルエンサーが多いのもそうかも

## 飽きずに集中するために
* 幼児の集中力の限界は2分30秒
* 大人でも15分周期
* おかあさんといっしょ本編も短い時間で小さな番組を切り替えている
* **大人の場合でも一緒で20分〜30分ぐらい＋休憩がよさそう**
* おかあさんといっしょは24分  
* 野球で1回裏表が終わるのは20分ぐらい
* ポモドーロテクニックは25分と5分の休憩
* 番組内で触れられているアニメ（でこぼこフレンズ）は背景を真っ白にしてどこに集中させるかわかりやすく
* **伝えたいこと多くてたくさん載せがち**
  * このメモは余計なことだらけ

## 自主性の尊重
* おかあさんといっしょに親御さんは映らないので子どもたちだけで出ないと行けない
* 最初に親御さんと離れられるかのテストをする
* 知らないところ、知らない人たちに囲まれて緊張している子どもたちは多い
* ここで親御さんと離れられなくても**無理に離さない**
* お兄さんお姉さんが子どもたちを呼ぶのではなく、子どもたちがお兄さんお姉さんを呼ぶ
* スタジオに移動してもまだ離れられなかったり、不安な子どもたちはいる
* **ひとりひとりにお兄さんお姉さんが話しかける**
  * 1on1の実施
* それでも10人に1人は最後までお兄さんお姉さんの元に行くことができない
* もしできなくても記念写真を撮る
  * 円滑なオフボーディング
* 人間ひとそれぞれ。大抵は他の人と仲良くできるとしても1割ほどはどうしようもない
* **無理矢理やらせようとしないことが大事**
* **できない人に対してもケアを**

## 適切な人数比
* 数えただけで子どもたちと直接触れ合ったスタッフ20人近く
* それで言うとスタッフと子どもたちは1:2ぐらい
* スクラムマスターとメンバーのバランスは教育を重視するに連れて少なくなるのかも
* https://www.infoq.com/jp/news/2009/04/agile-optimal-team-size/
* 実務では1:5までくらいかな

## 組織として健全と幼児として健全

リソースが足りている＝お腹が空いていない
カルチャーマッチ＝場所が明るい、うるさくない
心理的安全性がある＝安心できるものがある
程よい粒度のタスクがある＝眼の前に遊べるものがある
DockerでMySQLコンテナが一瞬だけ起動して停止する原因と解決方法（M1 Mac）

## 発生したこと
dockerでmysqlコンテナを起動しようとした。
一瞬、コンテナが立ち上がるものの、数秒すると停止してまう。

## 環境
PC：Apple M1 Mac
MacOS: 14.6.1（sonoma）

## 発生経緯
以下、コマンドを叩いた
```bash
docker run --name mysql001 -dit --net network001 \
  -e MYSQL_ROOT_PASSWORD=myrootpass \
  -e MYSQL_DATABASE=db001 \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=password \
  mysql \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
  --default-authentication-plugin=mysql_native_password
```

数秒、コンテナが起動するものの、すぐに停止する

そこで以下コマンドでdockerのログを確認する

```bash
docker logs mysql000ex11
```
**ログ例**
「[ERROR]」や「[Warning]」で始まる行を確認。
Cannot create user や Authentication plugin に関連するエラーがないか確認。

## ログ
以下エラーログが出ていた

```bash
2024-11-26T07:16:43.877071Z 0 [ERROR] [MY-000067] [Server] unknown variable 'default-authentication-plugin=mysql_native_password'.
2024-11-26T07:16:43.878072Z 0 [ERROR] [MY-010119] [Server] Aborting
```

## 原因
MySQL8.0から'default-authentication-plugin=mysql_native_password'が非推奨になった
デフォルト認証プラグインは caching_sha2_password であり、特に設定しなくても安全性が高い SHA-256 が利用されるらしい

https://dev.mysql.com/doc/refman/8.0/ja/caching-sha2-pluggable-authentication.html

## 暫定対応
使用している MySQL のイメージタグ（例: mysql:latest や mysql:8.0）を確認
バージョンを明確に指定してみる

```bash
docker run --name mysql001 -dit --net network001 \
  -e MYSQL_ROOT_PASSWORD=myrootpass \
  -e MYSQL_DATABASE=db001 \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=password \
  mysql:8.0 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
```

## 解決
起動したが、latest を指定すると、想定外のバージョンに引き込まれるケースがある。
バージョンを明確に指定することで問題を防げるので指定できるならした方がよさげ。
あと、ログ確認は大事。
MacBookのスクショがiPhoneにも表示される、解除方法

以下のiPhoneマークをOffにすれば解除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/334d77dd-2bf4-873d-dc36-5bfbccd8e240.png)
オープンクラス、モンキーパッチ

# 定義済のクラスを継承して独自クラスを定義できる
```rb
irb(main):001* class MyString < String
irb(main):002> end
=> nil
irb(main):003> s = MyString.new("Hello")
=> "Hello"
irb(main):004> s
=> "Hello"
irb(main):005> s.class
=> MyString
irb(main):006* class MyArray < Array
irb(main):007> end
=> nil
irb(main):008> a = MyArray.new()
=> []
irb(main):009> a << 1
=> [1]
irb(main):010> a << 2
=> [1, 2]
irb(main):011> a
=> [1, 2]
irb(main):012> a.class
=> MyArray
```
## オープンクラスは定義済のクラスにも再定義できる
>Rubyのクラスは変更に対してオープンなので、「オープンクラス」と呼びれています。

```rb
irb(main):013* class String
irb(main):014*   def shuffle
irb(main):015*     chars.shuffle.join
irb(main):016*   end
irb(main):017> end
=> :shuffle
irb(main):018> s = 'Hello, I am Alice'
=> "Hello, I am Alice"
irb(main):019> s.shuffle
=> "llclo mieeIHA, a "
irb(main):020>
irb(main):021> s.shuffle
=> "eaI ,Aoe mlliHlc "
```
### Rails独自のメソッドがある
```rb
garden(dev)> 'MyString'.underscore
=> "my_string"
garden(dev)> numbers = [1, 2, 3]
=> [1, 2, 3]
garden(dev)> 2.in?(numbers)
=> true
garden(dev)> 5.in?(numbers)
=> false
```
# モンキーパッチとは既存の実装に上書きして、自分が期待する挙動に変更すること
```rb
irb(main):023* class User
irb(main):024*   def initialize(name)
irb(main):025*     @name = name
irb(main):026*   end
irb(main):027*
irb(main):028*   def hello
irb(main):029*     "Hello, #{@name}"
irb(main):030*   end
irb(main):031> end
=> :hello
irb(main):032> user = User.new("Alice")
=> #<User:0x00000001071985e0 @name="Alice">
irb(main):033> user.hello
=> "Hello, Alice"
irb(main):034* class User
irb(main):035*   def hello # ←既存の実装の上書きを行ってる
irb(main):036*     "#{@name}さん,こんにちは!"
irb(main):037*   end
irb(main):038> end
=> :hello
irb(main):039> user.hello
=> "Aliceさん,こんにちは!
```
# エイリアスメソッドにして再利用する
```rb
irb(main):001* class User
irb(main):002*   def initialize(name)
irb(main):003*     @name = name
irb(main):004*   end
irb(main):005*
irb(main):006*   def hello
irb(main):007*     "Hello, #{@name}!"
irb(main):008*   end
irb(main):009> end
=> :hello
irb(main):010* class User
irb(main):011*   alias hello_original hello
irb(main):012*
irb(main):013*   def hello
irb(main):014*     "#{hello_original}じゃなくて、#{@name}さん、こんにちは！"
irb(main):015*   end
irb(main):016> end
=> :hello
irb(main):017> user = User.new("Alice")
=> #<User:0x000000010c02ccb0 @name="Alice">
irb(main):018> user.hello
=> "Hello, Alice!じゃなくて、Aliceさん、こんにちは！"
```
# 以下に注意
>オープンクラスやモンキーパッチは非常に強力で上手く使えば開発の効率を高めることができます。

>オープンクラスやモンキーパッチを乱用してはいけません。`最初に検討すべきことは、オープンクラスやモンキーパッチに頼らずに要件を満たすコードを書けないか`、ということです。

https://gihyo.jp/book/2017/978-4-7741-9397-7

# 感想
確かにこの機能はすごいが失敗をするとめんどくさい展開になりそうだ
ショートカットApp をFinderに追加

# ショートカットApp をFinderに追加
### ショートカットappで作ったスクリプト?はappではない
Automatorではアプリを作成できるため、それによる色々ができるのですが、
普通にやるとショートカットappで作ったスクリプト?はappになりません
この記事はなぜか一手間かかるショートカットappで作ったスクリプトをappにする方法です。
ついでとして、appはfinderに拡張機能っぽく配置できるため、それも書いておきます。

### ショートカットappで作ったスクリプトをappにする
- 使用したいショートカットを開いて、画像の「Dockに追加」
<div align="center"><img width="500" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1278266/ad466ded-f711-6c1b-dc53-962a91ee94e9.png"></div>

これによって、ショートカットがappとして保存されました。ので、それを探します。

- 追加されたDockのショートカットで以下の「Finderに表示」を選択
<div align="center"><img width="300" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1278266/fad30e58-74e9-1c88-97d2-346ecdb56283.png"></div>

そうすると、アプリが出てくるので、あとは好きにすれば良いわけですが、今回はアイコンを変更します。
その前に、ラウンチパッドにもappが追加されるので、消しておきましょう
<div align="center"><img width="300" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1278266/ce7f9a50-9d04-7c13-65fc-874897336432.png"></div>

### アイコンを変更
今回はターミナルアプリから引っ張ってきたいので、
- 類似のappとショートカットで詳細を表示して、画像のようにドラッグアンドドロップ
<div align="center"><img width="300" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1278266/a4c604fd-0c45-1e09-1cf9-c78430a3abb0.png"></div>

これで画像を変更できます。

### アプリをFinderに追加
以下のようにするとappを追加できます。
<div align="center"><img width="500" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1278266/3df61eda-0b9f-f68a-9ee0-ee6ca95fe759.png"></div>
既にS3で公開しているバケットをhttps通信させたい

## **▽概要**
・既にS3でインターネット公開しているバケットがhttp通信になっている
・サーバ証明書を用意してhttps通信にしたい
・サーバ証明書はAWS Certificate Managerで用意したい

## **▽内容**
**①ACMで証明書リクエストを発行する**
マネジメントコンソール＞Certificate Manager＞証明書をリクエスト
「パブリック証明書をリクエスト」を選択し、「次へ」を押下

・完全修飾ドメイン名：○○.co.jp
・検証方法：(今回は)DNS検証　
　※メールアドレス認証でもOKだけどDNS認証にすれば自動更新になる(便利)
・キーアルゴリズム：RSA 2048
・タグ：何かつけたければ、つける

:::note info
メールアドレス認証は、
検証ドメインとして example.com を指定すると、admin@example.com に E メールが届きます www.example.com のACM証明書をリクエストすると、E メールは admin@example.com ではなく admin@www.example.com に送信されます。
同様に、*.test.example.com のACM証明書をリクエストすると、admin@test.example.com に E メールが送信されます。
:::

設定した値に問題なければ「リクエスト」を押下する

**②DNSサーバにCNAME登録する**
マネジメントコンソール＞Certificate Manager＞証明書をリクエスト
の一覧でCNAMEレコードが表示されているので、
Route53でも他のDNSサーバでもご自身が使用しているもので登録を行う


**③CloudFrontでディストリビューションを作成する**
・OriginDomain：S3を指定する
・名前：S3を指定する
あたりを指定して「作成」します

**④CloudFrontにHTTPS通信用の設定とHTTPSへのリダイレクト設定を追加する**
該当のディストリビューションを選択し、「一般」タブから下記の設定を追加する
・Custom SSL certificate - optional：ACMの証明書を指定する
　・Security policy：TLSv1.2_2021

 「ビヘイビア」のタブから下記の設定を追加する
 ・ビューアープロトコルポリシー：Redirect HTTP to HTTPS

 ↑
 必要最低限の設定のみを記載しておりますので、
 その他(ログ設定や細かい設定)が必要でしたら、必要に応じて設定してください。


**⑤ブラウザとかでHTTPSの通信になっているか確認する**
ブラウザで対象のFQDNに( https://○○.co.jp みたいな感じで)アクセスしてHTTPSアクセスできるか確認する。


## **▽やってみた感想**
S3バケットをHTTPS化させるのには、今のところCloudFrontを利用する方法が主流のようでしたので、
今回CloudFrontを用意してみました。
いろいろ調べて、必要な設定を調べてみて構築してみましたが、
AWSの設定って、一つずつ役割を調べるとなかなか時間かかるんですね。。
勉強になりました。。

今後違うリソースとか触ってみたいです。
【競技プログラミング】AtCoder Beginner Contest 184_D問題

# 問題
https://atcoder.jp/contests/abc184/tasks/abc184_d


# アプローチ
動的計画法と再帰を組み合わせた方法を用いて、期待値を計算する。
各状態（金貨、銀貨、銅貨の枚数の組み合わせ）から終了条件までの期待値を再帰的に計算し、メモ化を行う。


# 解法手順
1. 入力として金貨A枚、銀貨B枚、銅貨C枚を受け取る。

2. 再帰関数 dfs(x, y, z) を定義する。この関数は現在の状態（金貨x枚、銀貨y枚、銅貨z枚）から終了条件までの操作回数の期待値を返す。

3. dfs 関数内で以下の処理を行う：
   - 終了条件（x=100 または y=100 または z=100）をチェックし、満たされていれば0を返す。
   - 現在の硬貨の総数 s を計算する（s = x + y + z）。
   - 各硬貨を選ぶ確率を計算し、次の状態の期待値を再帰的に呼び出す。
   - 期待値の計算式：p = dfs(x+1,y,z)*(x/s) + dfs(x,y+1,z)*(y/s) + dfs(x,y,z+1)*(z/s)
   - 現在の操作（+1）と次の状態からの期待値（p）の和を返す。

4. functools.cache デコレータを使用して、dfs 関数の結果をメモ化する。

5. 初期状態 dfs(A, B, C) を呼び出し、結果を出力する。



# ACコード
```python:ac.py
import functools

# 2. & 4. 再帰関数 dfs を定義し、メモ化を行う
@functools.cache
def dfs(x, y, z):
    # 3. dfs 関数内の処理
    # 終了条件をチェック
    if x == 100 or y == 100 or z == 100:
        return 0
    
    # 現在の硬貨の総数を計算
    s = x + y + z
    
    # 期待値を計算
    p = (
        dfs(x+1, y, z) * (x/s) +  # 金貨を選んだ場合
        dfs(x, y+1, z) * (y/s) +  # 銀貨を選んだ場合
        dfs(x, y, z+1) * (z/s)    # 銅貨を選んだ場合
    )
    
    # 現在の操作（+1）と次の状態からの期待値（p）の和を返す
    return 1 + p

if __name__=="__main__":
    # 1. 入力を受け取る
    A, B, C = map(int, input().split())
    # 5. 初期状態で dfs を呼び出し、結果を出力
    result = dfs(A, B, C)
    print(result)
```

# 一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)
テスト自動化エンジニアシラバス：テスト自動化の実装とデプロイ戦略

# はじめに

テスト自動化エンジニアのシラバスを再度読み直し、各章をDailyで読めるようにしてみた

https://www.istqb.org/certifications/test-automation-engineer

5 Implementation and Deployment Strategies for Test Automation を今回は翻訳・解説する

# テスト自動化のパイプライン統合

パイプラインとは、ソフトウェア開発における一連の自動化されたプロセスを視覚的に表現したものです。
各プロセスは、前のプロセスから受け取った成果物を基に次のプロセスを実行し、最終的に製品を完成させる。

テスト自動化のパイプラインでは、コードの変更からデプロイまでの一連の工程を自動化し、テストを組み込むことで、ソフトウェアの品質を継続的に向上することができます。


## テストレベルごとのパイプライン統合のポイント

1. TAF、TASの構成テスト
 テストスクリプトで使用されるファイルのパスが正しく設定されているか、ファイルが存在するかを確認するためのテストです。

2. コンポーネントテスト
 コードが小さな単位(ライブラリクラス、Webコンポーネントなど) でテストされるため、バグを早期に発見できます。
 パイプラインの初期段階で品質を確保し、後工程への影響を最小限に抑えます。

3. コンポーネント統合テスト
 複数のコンポーネントが連携して動作することを確認します。
 コンポーネント間のインタフェースが正しく機能することを検証します。

4. システムテスト
 システム全体の機能が要件を満たしていることを確認します。
 パフォーマンス、セキュリティなど、非機能要件を検証します。

5. システム統合テスト
 複数のシステムが連携して動作することを確認します。
 システム間のデータ連携が正しく行われることを検証します。


## 継続的デリバリーパイプラインにおけるテストの統合
継続的インテグレーションシステムでは、継続的デリバリーパイプラインのビルドフェーズとデプロイフェーズが区別される。

- ビルドフェーズ
 コンポーネントテストとコンポーネント統合テストが実行されます。このフェーズが成功すると、コンポーネントやSUTがデプロイされます。

- デプロイフェーズ
 システムテストや受け入れテストが実行されます。テスト結果に基づいて、デプロイの成功または失敗が決定されます。

## その他のテスト自動化のパイプライン活用

パイプラインは、以下のようなテスト自動化の目的にも利用できます。

- 定期的な回帰テスト
 長時間のテストスイートを夜間実行し、翌朝にシステムの品質を確認します。
- 非機能テスト
 パフォーマンステストやセキュリティテストなど、定期的に実行する必要がある非機能テストを自動化します。


# テストウェアの構成管理

テストウェアとは、テストを行うために必要なすべての要素の総称です。
テストスクリプト、テストデータ、テスト環境設定などが含まれます。
構成管理は、これらの要素を効率的に管理し、一貫性を保つためのツールです。

構成管理の対象となるものとして、次のようなものがあります

## テスト環境の構成

さまざまなURLや認証情報など、開発パイプラインで使用される各テスト環境の構成を管理します。
テスト環境の構成は通常、テストウェアと一緒に保存されます。
複数のプロジェクトや同じプロジェクトの複数のTAFで使用される場合は、共通のコアライブラリや共有リポジトリに保存できます。


## テストデータ

テストデータは、テスト環境やSUTのリリース・機能セットに固有のものがあります。
テストデータは、通常、小さなTAFと一緒に保存されますが、テストデータ管理システムも使用できます。


## テストスイート/テストケース

テストケースは、目的別に異なるテストスイートにグループ化されます（例えば、スモークテストや回帰テスト）。
異なるテストレベルで実行されるため、さまざまなパイプラインとテスト環境を活用します。
各SUTのリリースには、そのリリースの品質を評価するテストケースとテストスイートが含まれます。
機能トグルを使用して、リリースやテスト環境ごとに機能を有効化/無効化し、実行するテストスイートを制御できます。
SUTのバージョンとテストウェアのバージョンを一致させることで、テストの信頼性を確保できます。


## テストウェアの構成管理のベストプラクティス

以下のことを考慮すると、テストウェアの構成管理がうまくいきます。

- バージョン管理
 テストウェアをバージョン管理システム（Gitなど）で管理し、変更履歴を追跡します。
- モジュール化
 テストコードをモジュール化し、再利用性を高めます。
- テストデータ管理
 テストデータを適切に管理し、再利用できるようにします。
- 環境変数
 テスト環境やデータの差異を環境変数で管理します。
- CI/CDパイプライン
 テスト自動化をCI/CDパイプラインに組み込み、自動化されたテスト実行を実現します。


#  APIインフラのテスト自動化依存

APIのテスト自動化を行う際には、適切な戦略を構築するために、以下の依存関係に関する情報を理解することが重要です。

- API 接続
 自動テスト対象となるビジネスロジックとAPI間の関係を理解します。
- APIドキュメンテーション
 パラメータ、ヘッダー、リクエスト・レスポンスのオブジェクトの種類など、関連するすべての情報を含むAPIドキュメンテーションを参照します。

APIの自動化テストは、開発者またはテストエンジニア（TAE）によって実行できます。しかし、シフトレフトの原則に基づいて、異なるレベルでのテストをサポートし、分担することが推奨されます。
ISTQB CTFLシラバスでは、コンポーネント統合テストとシステム統合テストが挙げられていますが、それに加えて、次に説明する、契約テスト(Contract testing) というベストプラクティスを導入することができます。

契約テストは、サービス間の通信が正しく行われ、共有されるデータが特定のルールに準拠していることを検証する統合テストの一種です。
契約テストを使用すると、2つの異なるシステム（例えば、2つのマイクロサービス）が互いに通信するための互換性を確保できます。
スキーマの検証を超えて、両者が時間をかけて合意した一連のインタラクションを遵守することを要求します。
各サービス間で交換されるインタラクションをキャプチャし、契約として保存することで、両者が契約を遵守していることを検証できます。

契約テストの主な利点の一つは、基礎となるサービスの欠陥をSDLCの早期段階で発見し、その欠陥の原因をより容易に特定できることです。

コントラクトテストの消費者駆動アプローチでは、消費者（API呼び出し側）がその期待を設定し、提供者がこの消費者からの要求に応答する方法を決定します。
コントラクトテストのプロバイダー駆動アプローチでは、プロバイダー（API側）が契約を作成し、そのサービスの動作を示します。
Laravelでバインドパラメータ込みのSQL文を確認する方法

開発中にデバッグなどで実際に実行されるSQL文を確認したい時があるので、メモ。

## Laravel10以下の場合は`getBindings()`と`toSql()`

```php
// クエリを作成
$queryBuilder = XXXTable::where('client_id', $clientId)
            ->where('del_flag', 0)
            ->where('update_at', '>=', $dateFrom)
            ->orderBy('name');
// ddで確認
dd(preg_replace_array('/\?/', $queryBuilder->getBindings(), $queryBuilder->toSql()));
```

結果
```
"select * from `xxx_table` where `client_id` = 12345 and `del_flag` = 0 and `update_at` >= 2024-11-26 12:34:56 order by `name` asc"
```

#### やっていること
1. Eloquentモデルでクエリを作成し、`get()`などで値を取得する前に変数へ代入
2. クエリビルダの`getBindings()`でバインドされたパラメータの配列を取得
3. クエリビルダの`toSql()`でクエリの文字列を取得
4. 3で取得したクエリはパラメータが`?`になっているので、2で取得したパラメータに置換する

`$queryBuilder->toSql()`の返却値
```
"select * from `xxx_table` where `client_id` = ? and `del_flag` = ? and `update_at` >= ? order by `name` asc"
```

`$queryBuilder->getBindings()`の返却値
```
array:3 [▼
  0 => 12345
  1 => 0
  2 => Carbon\Carbon ...(Carbonオブジェクトを渡している)
    date: 2024-11-26 12:34:56.0 Asia/Tokyo (+09:00)
  }
]
```

`preg_replace_array()`はLaravelのヘルパー関数
> preg_replace_array関数は、指定パターンを順番に配列中の値に置き換えます。

https://readouble.com/laravel/8.x/ja/helpers.html#method-preg-replace-array

PHP標準関数の`preg_replace()`でも置換できなくはないですが、`preg_replace_array()`の方が簡潔に書けて便利。


## Laravel10以上の場合は`toRawSql()`
なお、Laravel10以上の場合は`toRawSql()`一発で書けるそうです。
```php
XXXTable::where('client_id', $clientId)
        ->where('del_flag', 0)
        ->where('update_at', '>=', $dateFrom)
        ->orderBy('name')
        ->toRawSql();
```

https://laravel-news.com/raw-query-output-with-bindings-is-coming-to-laravel-10

LaravelのAPIリファレンスにも記載あり。

https://laravel.com/api/master/Illuminate/Database/Query/Builder.html#method_toRawSql

サクッと確認したい時に便利なので嬉しいですね。


#### 参考記事
https://qiita.com/fuwasegu/items/c6e668dae1546184ff15
iPadの3Dスキャンデータ（.ply）をPythonで表示する

# iPad ProのLiDAR（3Dスキャナー）で取得した点群データをPythonで表示する
**１．取得した点群ファイルを準備**
ここでは，Artec 3Dサイトから無料ダウンロードさせて頂いたCar body.plyファイルを例に挙げる．
![Car body.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/a9f25e25-2b3c-4b00-5e21-8c968f870ea4.jpeg)
**２．任意のフォルダに，点群ファイルをコピーして，下記のPythonを実行する．**

**＜ポイント＞**
・ダイアログボックスで，.plyファイルが選択できる
・読み込んだ点群データの頂点数と面の数を表示
・mesh.show()では表示できなかったので，matplotlibライブラリで表示するようにした

```plot_ply.py
import trimesh
import os
import tkinter as tk
from tkinter import filedialog
import matplotlib.pyplot as plt

# ダイアログボックスでPLYファイルを選択
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(filetypes=[("PLY files", "*.ply")])

# PLYファイルの読み込み
mesh = trimesh.load(file_path)

# メッシュ情報の表示
print(mesh)
print("頂点数:", len(mesh.vertices))
print("面の数:", len(mesh.faces))

# PLYメッシュの表示
# mesh.show()

# 3Dプロットの準備
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 点群のプロット
ax.scatter(mesh.vertices[:, 0], mesh.vertices[:, 1], mesh.vertices[:, 2], s=0.1)

plt.show()
```
ちなみに，マウスドラッグで回転できます．

![Car body plot.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/161538d6-8542-7b18-754c-67d350c2b4d3.jpeg)

# Trimeshライブラリのバージョンでエラーが出る時の対処
インストールされているtrimeshをアンインストール
```:bash
pip uninstall trimesh
```

バージョンを指定してtrimeshを再インストール
```:bash
pip install trimesh==1.8.5
```

インストールされたバージョンを確認する
```:bash
import trimesh
print(trimesh.__version__)
```
Japan AWS Jr. Champion活動記録 番外編


## はじめに
私のJapan AWS Jr.Champion（以下、Jr.Champion）としての活動期間は、既に終わったのですが、現Jr.Championsと旧Jr.Championsの交流イベントに参加してきたので、それを記事にしたいと思います。

↓ 前回の記事はこちら ↓

https://qiita.com/am_i-12/items/26a7c8f86135f351e906

## Japan AWS Jr. Champion Partner Programとは
> 「[Japan AWS Jr. Champion Program](https://aws.amazon.com/jp/blogs/psa/2024-japan-aws-jr-champions-criteria/)」とは、AWS Partner Network (APN) 参加企業に所属し、現在社会人歴 1 ～ 3 年目で AWS を積極的に学び、アクションを起こし、周囲に影響を与えている APN 若手エンジニアを選出しコミュニティを形成する、日本独自の認定プログラムです

2024年は[95名が選出](https://aws.amazon.com/jp/blogs/psa/2024-japan-aws-jr-champions/)されています。

## イベントの流れ

現Jr.Championsと旧Jr.Championsの交流イベントは以下の流れで行われました。

- Jr.Champions活動共有
- DeepRacerCup決勝
- 懇親会

それぞれについて、以下で詳しく書いていきます。

### Jr.Champions活動共有
今年のJr.Championsの活動内容について発表がありました。要約は以下です。

- コミュニティ活動が活発に行われている。
  - 例）休日朝活会 → 土曜日朝9時からAWSに関する勉強会 
- YouTube配信等の自主イベントも盛んにおこなわれている
- Jr.Championsで本出版も行われた。

https://techbookfest.org/product/aC3JnqNigevzd0rNCaRNve?productVariantID=g8eMkfYVEKkbYF4t59FqXp

https://techbookfest.org/product/dhwqXi3GyBQvHNK7jpaAqF?productVariantID=mCSF8gJBULaKpQHi6NmJJx

- Qiitaで、Jr.Championsのインタビューやブログリレーが行われている。

https://qiita.com/tekuta7/items/7c1f0d44398b20f1c5e4

https://qiita.com/y-mae/items/7f4b39038f79f6a6f4d4

- Jr.ChampionsのQiitaアドベントカレンダーも作成されていて、多くの記事が投稿される予定とのこと

https://qiita.com/advent-calendar/2024/japan-aws-jr-champions


 **感想** 
 全部把握するのが難しいほどの自主イベントやコミュニティ活動が行われているということで、現Jr.Championsの皆さんの積極性と実行力に感嘆しました！

### DeepRacerCup決勝

去年も行われたDeepRacerのJr.Champions Cupが今年も開催されました。イベントでは予選1位・2位のJr.Championsによるリアルタイムレースが行われ、大いに盛り上がりました :red_car: 

 **感想** 
去年のJr.Champions DeepRacer Cupは、オンライン開催でしたが、今年は対面開催だったので、大画面でレースを見ることができて、新鮮で楽しかったです！
Jr.Championsの方が作ったモデルは、急なカーブにも難なく対応していて見事な走りでした :clap:

### 懇親会
 **感想** 
旧Jr.Championsと久々に再会したり、現Jr.Championsの方とお話しして、とても楽しい時間でした！中には私がJr.Champions時代に登壇した内容を覚えていてくださる方もいて、嬉しかったです。

予約投稿のため、この記事が投稿されているころには私はラスベガスでre:inventに参加しているのですが、re:invent経験者からのお話もたくさん聞けて、ありがたかったです。


<br>


以上です。ありがとうございました。
Wordpressのプラグインbbpress

bbPressカスタマイズ用の設定ファイル群が煩雑なので，メモ

# 設定ファイルの出し方
Wordpress設定画面で「プラグイン」－「プラグインファイルエディター」をクリック．
右上の「編集するプラグインを選択」ドロップボックスで bbPress を選択．

![bbp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/d215077e-bacd-b9c2-a59a-8083a292d7e3.png)


# 設定ファイルの在りか

| 設定対象 | ファイル |
| --- | --- |
| forum一覧ページ | templates - default - bbpress - content-archive-forum.php |
| 各Forumのトピック一覧 | templates - default - bbpress - content-single-forum.php |
| トピック | templates - default - bbpress - content-single-topic.php |
| 検索結果の画面 | templates - default - bbpress - content-search.php |
| 検索 | templates - default - bbpress - form-search.php |
| デフォルトのユーザ名，フォーラム名など | bbpress.php |
Oracle Analytics Cloud：「上位下位N件」のフィルターで、フィルター条件をパラメータ化して利用する

はじめに
---
2024/3 アップデートで「上位下位N件」のフィルターで、フィルター値をパラメータにバインドすることができるようになっています。フィルター値をパラメータにバインドすると、ダッシュボード・フィルタにパラメータを配置して利用することができます。「上位下位N件」のフィルターで、フィルター条件をパラメータ化し利用する方法を試してみます。

![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/0e7b2e7a-1a62-53a8-221a-a82d6c1381bb.jpeg)



記載時のOACバージョン：OAC 2024 Nov版


前提
---
・ Data Visualizationでワークブックを作ったことがある
・ ワークブックで利用するデータセットが作成済みである


ワークブックの作成
---
ワークブックを作成します
例では商品名、受注金額を複数選択し右クリック、右クリックメニューからビジュアライゼーションの選択で横積み上げ棒を選択しています
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/7b7596d7-d082-7f8b-10d1-0918f67a601b.jpeg)

ビジュアライゼーションの右上部にマウスカーソルを移動し、表示された右端のメニューアイコンをクリックし、メニューからソート基準を選択、
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/3d809042-2829-f4f7-5306-e42bcc1e5ec0.jpeg)

受注金額 - 高から低をクリックします。
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/9afe3718-eb22-ac1a-7533-e3d179023ab7.jpeg)

受注金額の上位から並び替えられました。

フィルタの追加
---
ビジュアライゼーションのフィルタを追加します。イメージでは、受注金額を、フィルタに追加しています。
![g6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/cc284328-209f-bfdf-8ffa-713f886c28eb.jpeg)

ビジュアライゼーションのフィルタに配置した受注金額をクリックします。
上位下位N件のタブをクリックします
![g7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/10efbe2f-1198-98dd-09c6-7b54284c2793.jpeg)

方法のところのパラメータアイコン(x)をクリックし、パラメータの作成を選択します
![g8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/ea22b938-2723-9de2-d4b5-78ef7cbb0b60.jpeg)

同様に、件数のところのパラメータアイコン(x)をクリックし、パラメータの作成を選択します
![g9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5131088e-7a1a-35cd-a1b5-e6cb89f62904.jpeg)

※パラメータを作成すると、フィルタで選択した値が作成したパラメータにバインド（格納）されます。

![g10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/3385d40a-0f30-55e4-f6da-bc87a7d448f0.jpeg)

ダッシュボード・フィルタの追加
---
ダッシュボード・フィルタを追加します
左上部の左から２番目の"ビジュアライゼーション"タブを開き、ダッシュボード・フィルタをドラッグし、右のキャンバスの上部に配置します
![g10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/817d8fd4-1e9d-f478-e155-5a43c9e75536.jpeg)

左上部の右端"パラメータ"タブを開きます。作成したパラメータ "受注金額上位/下位メソッド"をドラッグして、ダッシュボード・フィルタに配置します。
![g11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/7d873f11-22ee-2389-365b-bb997c693943.jpeg)

同様に、作成したパラメータ "受注金額上位/下位件数"をドラッグして、ダッシュボード・フィルタに配置します。
![g12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/57628a5c-bc7f-d387-357e-e75ba1280225.jpeg)

色に商品名を配置します
![g13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/9c7c1fb8-c562-9b7e-eecb-5dd028430922.jpeg)

パラメータを利用したダッシュボード・フィルタで条件で検索が実行されます
![g14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/b0efcd25-3080-0777-7cc9-253c13658689.jpeg)

まとめ
---
「上位下位N件」のフィルターで、フィルター値をパラメータにバインドし、ダッシュボード・フィルタで利用する方法をためしてみました。

[参考記事](https://www.youtube.com/watch?v=u4QEFqP1R-Y&list=PL6gBNP-Fr8KWlnpaELiCxQJii-F4c7Ehz&index=1)です

以上
Docker で API サーバーと DB を立てて接続するまで

# 概要
個人開発で Docker 非常に便利ですね。
今回は Docker で APIサーバー と DB を立てて、APIサーバー から DB に接続するまでをまとめます。
DB には Postgres を採用しています。
一つ一つ解説することはしませんが、コピペすれば動くはずなので、動かして気になったところを調べていくと良いと思います。

# 前提
- Docker がインストールされていること

# 使用技術
- Docker
- PostgreSQL

# 手順
1. Dockerfle 作成
2. docker-compose.yml 作成
3. コンテナ作成
4. DB 接続

# フォルダ構成
docker/
　　├ docker-compose.yml
　　└ Dockerfile

# 1. Dockerfile 作成
Dockrfile では既存のイメージを pull して、その上に自分で必要なものを付け足すことができますが、今回は説明を簡単にするため、付け足した部分は省略します。

次のような `Dockerfile` を作成します。
```Dockerfile
# api-server
FROM eclipse-temurin:23-jdk AS api-server

#db
FROM postgres:15.4-alpine AS db
```
`eclipse-temurin:23-jdk` と `postgres:15.4-alpine` の部分は自身で使用したい言語とDBのイメージに置き換えてください。

# 2. docker-compose.yml 作成
次はイメージからコンテナを立てる際の手順書に相当する `docker-compose.yml` を作成します。

```yml
services:
  app:
    container_name: api-server
    build:
      context: .
      target: api-server
      dockerfile: ./Dockerfile
    tty: true
    ports: ['8080:8080']
    networks:
      - app-network
    depends_on:
      - db
    volumes:
      - ../api:/java_project/
  db:
    container_name: db
    build:
      context: .
      target: db
      dockerfile: ./Dockerfile
    environment:
      POSTGRES_DB: 'test-db'
      POSTGRES_USER: 'user'
      POSTGRES_PASSWORD: 'password'
      POSTGRES_HOST: 'localhost'
    ports: ['5432:5432']
    networks:
      - app-network
    volumes:
      - postgres:/var/lib/postgresql/data

volumes:
  postgres:

networks:
  app-network:
    driver: bridge
```

`build` > `dockerfile` で参照する `dockerfile` を指定し、
`build` > `target` で元となるイメージを指定します。
この `target` に指定するのは `Dockerfile` の `AS` 以降の部分です。

`db` > `environment` の各値は適宜書き換えてください。

`app` > `volumnes` の `../api:/java_project/` では APIサーバー に乗せたいソースをコンテナにマウントしています。私の場合、`docker` フォルダと同じ階層に `api` というjavaのプロジェクトフォルダがあるので、それを指定しています。

# 3. コンテナ作成
カレントディレクトリ下に `docker` フォルダがあることを確認してください。

下記コマンドで `Dockerfile` のイメージを pull します
```
docker-compose -f ./docker/docker-compose.yml build
```

その後、下記コマンドでコンテナを作成します
```
docker-compose -f ./docker/docker-compose.yml up -d
```


コンテナが問題なく立っているかを確認します。
下記コマンドで、ターミナルを操作するようにコンテナにコマンドを投げられます。ここでは、DBにSQLを投げています。
```
docker exec -it db psql -U user test-db -c "SELECT 'KIPFEL'"
```
次のような結果が返っていれば問題ありません
```
 ?column? 
----------
 KIPFEL
(1 row)
```

# 4. DB 接続
APIサーバーとDBは `docker-compose.yml` の `network` で作成した `app-network` で繋がっているので、APIサーバーから
```
url: "jdbc:postgresql://db:5432/vrcs-db"
userName: "user"
password: "password"
```
を指定すれば接続できます。
`jdbc:postgresql` の部分はデータベースドライバなので postgres 以外を使用する場合は適切なドライバ名に書き換える必要があります。また、psotgres を使用する場合でもドライバを依存関係に追加するか直接ダウンロードする必要があります。

java で postgres のドライバを追加する場合の参考
    ＝＞https://mvnrepository.com/artifact/org.postgresql/postgresql/42.7.4


# おわりに
初めての投稿で説明の至らぬところもあったとは思いますが、参考になれば幸いです。
何か誤りや不正確な点があればご指摘ください。
【競技プログラミング】AtCoder Beginner Contest 254_D問題

# 問題
https://atcoder.jp/contests/abc254/tasks/abc254_d


# アプローチ
素因数分解と平方数の性質を利用して、条件を満たす組み合わせを数え上げる。

# 解法手順
1. 入力として整数Nを受け取る。

2. カウンター変数cntを0で初期化する。

3. 1からNまでの各整数iに対して以下の処理を行う：
   a. iを素因数分解し、平方数部分を取り除く。
   b. 残った数をjとする。
   c. j×k^2がN以下となる最大のkを求める。
   d. kの値だけcntに加算する。

4. すべての処理が終わったら、cntを出力する。


# ACコード
```python:ac.py
import math

def solve(N):
    # 1. 入力として整数Nを受け取る（この関数の引数として渡されています）

    # 2. カウンター変数cntを0で初期化する
    cnt = 0

    # 素因数分解を効率的に行うための前処理
    # エラトステネスの篩を用いて素数リストを作成
    primes = []
    is_prime = [True] * (N + 1)
    for i in range(2, N + 1):
        if is_prime[i]:
            primes.append(i)
            for j in range(i * i, N + 1, i):
                is_prime[j] = False

    # 3. 1からNまでの各整数iに対して処理を行う
    for i in range(1, N + 1):
        # a. iを素因数分解し、平方数部分を取り除く
        j = i
        for p in primes:
            if p * p > j:
                break
            while j % (p * p) == 0:
                j //= p * p

        # b. 残った数をjとする（上記のループで既に計算済み）

        # c. j×k^2がN以下となる最大のkを求める
        k = int(math.sqrt(N // j))

        # d. kの値だけcntに加算する
        cnt += k

    # 4. すべての処理が終わったら、cntを出力する
    return cnt

if __name__=="__main__":
    N = int(input())  # 標準入力からNを読み込む
    result = solve(N)  # solve関数を呼び出して結果を得る
    print(result)  # 結果を出力する
```

# 一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)
接続しているデータベースの host と名前を取得する

[ActiveRecord::ConnectionHandling#connection_db_config](https://api.rubyonrails.org/classes/ActiveRecord/ConnectionHandling.html#method-i-connection_db_config) を使う。なお、他に取得できる情報については [ActiveRecord::DatabaseConfigurations::HashConfig](https://api.rubyonrails.org/classes/ActiveRecord/DatabaseConfigurations/HashConfig.html) を参照。

```rb
config = ApplicationRecord.connection_db_config

# host
config.host
#=> "127.0.0.1"

# データベース名
config.database
#=> "my_database_development"

# バージョン情報
Rails.version
#=> "8.0.0"
RUBY_VERSION
#=> "3.3.6"
```
Amazon Bedrockを使って、RAGを構築　 - ドメイン知識のインプット補助ツールを作りたい -

:::note info
この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) カレンダー1 の 18日目の記事です
:::

# はじめに

生成AI活用してますか？
生成AIの進化は凄まじいなと思うものの、広く一般的な内容には活用できるなと思う反面、特定領域に関するタスクはよろしくないなと感じることもありますよね

私は、今年、社内で担当プロダクトが変更になり
中古マンションの住宅価格予測をやってみた

１　はじめに
今までプログラミングスクールで学んできた内容を生かしてnishikaの中古マンションの住宅価格予測のコンペをやっていこうと思います

2　解決するためには
住宅マンションの価格は距離や都道府県などで変動しているので分析など注意深く行っていくようにします

3　実行環境
パソコン：ASUS
開発環境：Anaconnda spyder
言語：Python
ライブラリ：Pandas、Numpy、Matplotlib、sklearn　等

4 分析するデータ
今回は以下のデータを使用して分析を行っていきます
![スクリーンショット (35).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/205c5258-a2dd-4fdd-6640-525d3dd97694.png)

5　分析の流れ
  ①４７都道府県のデータを一括にする
  ②データの確認
  ③データの分析
  ④重視する変数の選定
  ⑤モデルを作って予測を行う　今回予測精度の評価はmae(mean_absolute_error)で行っていこうと思います

６　分析
 ①、②４７都道府県のデータを一括にするのとデータの確認をする
 まず必要なライブラリをインポートをしてCSVファイルを読み込みます
 この時４７都道府県のでーたを一括して読み込んでいきます
 
 実行したコード
![スクリーンショット (38).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/4a8d7300-c337-a7cd-70bc-dae45c0e24ff.png)

③　データの分析
この時取引価格(総額)_logになっていてlogで計算は行わないので
![スクリーンショット (39).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/52af39df-0d1a-9e5f-9d18-0c32e0c5e78f.png)
のコードを実行した

次に一つ一つの変数と取引価格の分析を行う
※データの変数と欠損値の量
![スクリーンショット (41).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/d143a592-f6e6-6165-223c-56739911b502.png)
この時欠損値が多い変数やグラフ化してもわからないような変数は分析ができないので分析は行わない

例として価格情報区分の変数の分析を行う

実行したコード
![スクリーンショット (43).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/f03ca125-e8cc-35e3-f71a-f157bf63891e.png)

実行結果とデータの可視化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/4bcd32fb-9021-c000-fdcc-8f4eb1b40734.png)
分析結果から不動産取引価格情報の量は成約価格情報に比べて多いが成約価格情報の平均値は不動産取引価格情報に比べて多いというのが分かった

このように分析できる変数一つ一つ分析した結果が以下の内容である
![スクリーンショット (44).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/b0b2dae6-cd4d-c64e-74fb-9c29a716f096.png)
なお 建ぺい率と容積率と取引時点は欠損値が多い等の理由でデータ分析は行わなかった

④重視するデータの選定
今回重視するデータは面積と建築年を使って予測を行っていこうと思います

⑤モデルを使って予測を行う
今回はMAE(mean_absolute_error)という精度指標を使います
実行したコード
![スクリーンショット (45).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/7e07974b-f96e-57bc-4a35-0c995ffb6283.png)

モデルを予測する前に欠損値の処理やdf.unique()を使って変数の中に戦前や2000m以上という文字が紛れているので欠損値の処理と並行して行っていく
最後のコードでnishikaに提出する用のファイルも完成できたのでnishikaに提出していきます

nishikaにデータの提出を行った結果
![スクリーンショット (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939691/5d3848bf-8381-cdb4-e37a-dc72f98bb135.png)

7　今後の課題
今回はモデル予測に2つの変数しか使いませんでしたが距離や建物の構造などの変数を使用して今後も予測をしていこうと思います

8　まとめ
今回の中古マンションの価格予測でpythohの基礎やデータ分析でやらなきゃいけないこと等を学べました。一つエラーが出た時の対処法や分析結果が思ったような結果じゃなかったときはコードにおかしなところはないか？や分析結果のデータフレームに欠損値があるかも？といったところに気を配り、落ち着いて対処していこうと思いました。

次の目標はまた新しいコンペに参加することと加えて今回の予測で２つの変数しか使っていないので使える変数はすべて使ってデータ分析を行っていこうと思います
演算子の再定義

# 演算子の独自の再定義
```rb
irb(main):001* class User
irb(main):002*   def name=(value)
irb(main):003*     @name = value
irb(main):004*   end
irb(main):005> end
=> :name=
irb(main):006> user = User.new
=> #<User:0x00000001086e5128>
irb(main):007> user.name
(irb):7:in `<main>': undefined method `name' for #<User:0x00000001086e5128> (NoMethodError)

user.name
    ^^^^^
...
irb(main):008> user.name = "Alice"
=> "Alice"
```

```rb
irb(main):001* class Product
irb(main):002*   attr_reader :code, :name
irb(main):003*
irb(main):004*   def initialize(code, name)
irb(main):005*     @code = code
irb(main):006*     @name = name
irb(main):007*   end
irb(main):008> end
=> :initialize
irb(main):009> a = Product.new("A-0001", "A great movie")
=> #<Product:0x00000001078c2a50 @code="A-0001", @name="A great movie">
irb(main):010> b = Product.new("B-0001", "An awesome film")
=> #<Product:0x000000010b521280 @code="B-0001", @name="An awesome film">
irb(main):011> c = Product.new("A-0001", "A great movie")
=> #<Product:0x000000010b409ff0 @code="A-0001", @name="A great movie">
irb(main):012> a == b
=> false
irb(main):013> a == c
=> false
```
### `==`をインスタンスソッドにする
```rb
irb(main):014* class Product
irb(main):015*   attr_reader :code, :name
irb(main):016*
irb(main):017*   def initialize(code, name)
irb(main):018*     @code = code
irb(main):019*     @name = name
irb(main):020*   end
irb(main):021*
irb(main):022*   def ==(other)
irb(main):023*     if other.is_a?(Product)
irb(main):024*       code == other.code
irb(main):025*     else
irb(main):026*       false
irb(main):027*     end
irb(main):028*   end
irb(main):029> end
=> :==
irb(main):030> a = Product.new("A-0001", "A great movie")
=> #<Product:0x000000010b43acb8 @code="A-0001", @name="A great movie">
irb(main):031> b = Product.new("B-0001", "An awesome film")
=> #<Product:0x000000010b4c9e68 @code="B-0001", @name="An awesome film">
irb(main):032> c = Product.new("A-0001", "A great movie")
=> #<Product:0x000000010b503820 @code="A-0001", @name="A great movie">
irb(main):033> a == b
=> false
irb(main):034> a == c
=> true
irb(main):035> a == 1
=> false
irb(main):036> a == "a"
=> false
```
### インスタンス変数だから`.==`のようにも呼び出せる
```rb
irb(main):037> a.==(b)
=> false
irb(main):038> a.==(c)
=> true
```
### 左辺のオブジェクトが変わると処理も変わる
```rb
irb(main):039> 1 == a
=> false
```
# 感想
railsのAPIを読めるように覚えておこう