OmniAICreator/Qiita-1.07M huggingface dataset:
【VBA】疑問共有会をやってみました


# 概要
若手を中心にVBAを触ってきて抱く疑問や気になる点を共有して、ベテランエンジニアに意見をもらったり、ともに考えてみる勉強会を社内で開催したので、その内容を共有する記事です。


## 変更容易なコード
### マジックナンバーをいかになくすか？
ベテランG ：大規模な開発であればルールを作るが、小規模ならば意識する程度
　　　　　規模は体制がどうであるかということ
若手U：　 evmanだとマジックナンバーに関してルールは設けていないが、
　　　　　意味が分かるようにコメントを書いている
若手T：　 Constで値を設定することで意味を持たせるようにしている

### タイトルが変わる表にいかに対応するか？ 
ベテランG：Excel上の範囲の扱いは最近だとテーブルを使う
　　　　　 テーブル書式とするとカラム名で列にアクセスできる
　　　　　 テーブルとしてSQL発行もできるが少し複雑で難しい
　　　
ベテランG：最近開発者として入ったところではピポットでの集計を使った
　　　　 　ルールを作ればやりやすいが、Join等ができない

　　　　　 列名を定義しないで済むやり方を実現したい★課題★
　　　　
若手S：　　範囲に名前を付けるやり方はしないのか
ベテランG：場合は列全体で名前を付けることが多い
　　　　
　　　　　 範囲にはBookスコープやSheetスコープがある
　　　　　 しかし、一度Bookスコープに設定すると変えられない
　　　　
ベテランK：テーブル書式は事前に設定する？、プログラムで組み込む？
ベテランG：ひな形として設定しておく

若手S：　　最終行を取得するやり方はどうか
　　　　　 私は行のエンドから上に戻るやり方をしている
ベテランG：あまりそれはやらない
　　　　　 UsedRangeからとる場合もある

## 堅牢なコード
### エラー処理をどうやって実装するべき？
若手S：　　深い場所でのエラーへのハンドリングをどうするのか
若手U：　　エラーレイズする
ベテランG：システムエラーとユーザーエラーの場合で分けて考える必要がある
　　　　　 ユーザーエラーであればエラーレイズして親でキャッチする

若手S：　　定跡的なエラー処理のやり方はあるのか
ベテランG：簡易的なものであれば戻り値でエラーかどうかを返してメインで処理するように作る
　　　　　 時間の余裕にもよる
ベテランK：C言語以降の人ならとにかく正常終了させる
　　　　　 戻り値はあまりチェックしたくない
　　　　　 戻り値以外の例外を知る方法が言語的にあるのならそれを使うべきな気もする。
　　　　
ベテランG：サブモジュールでエラーを上にあげたときにオブジェクトの解放がどうなるか気になる。
　　　　　わざわざ解放しなくても問題ないようだが
ベテランK：JavaでいうFinallyのような最後に絶対実行されるものはないのか
若手T：　 ない
　　　　　Resumeはエラーが出てもそのまま何かを動かすもの

ベテランG：研究してベストソリューションをつくりたいね★課題★

### テストはどうやって行う？
若手S：　　テスト駆動開発のように最初にテストコードを書くのか
ベテランG：そこまでやっていない
若手T：　　そこまでちゃんとやっていなかった
ベテランG：ファンクションのテストドライバをその横で作って何パターンかテストするくらいはする。
　　　　　アサーションまではやっていない
ベテランK：テストドライバを作るならアサーションまで作ってもいいのでは？
ベテランG：ツールがあってそれが自動的に参照してレポートしてくれるならメリットがあるが、
　　　　　人力ならそこまではいらないかな
若手N：　アサーションとは？
ベテランK：　期待値と実際の戻り値をチェックするプログラム

若手S：　VBAだと大規模開発にならないのであまりテストは簡易なものになってしまうもの？
ベテランK：　大規模じゃなくても自分が毎回やるという観点であればテストツールを作るもの意義がある
ベテランG：Excelだとテストでシートのデータを作る場合があるが、これをアサーションするのは難しい
　　　　　標準的なテストケースフォーマットのテストケース一覧とそれに紐づくテストデータを用意し、
　　　　　そこからテストコードを自動生成するというのをやったことがある。
　　　　　しかしExcelだとデータの作り方が多岐にわたり、網羅が難しい
ベテランT：スタートの状態を自動で生成できるようなプログラムを作っていた
　　　　　VBAでなくても、バッチでそれを行うといった工夫もよくする。
　　　　　これは初期化に関してだが、結果の比較をするプログラムを作る場合もある。
　　　　
ベテランTイミディエイトウィンドウでメソッドを動かせるのでそこで試す
　　　　　"?<式（返値があるもの）>で値を見ることができる。

## よりよいコード
### クラスモジュールをどう使う？
若手S：　　クラスモジュールはそもそも使う？
ベテランT：データを入れておく箱として使う
ベテランG：あまり使わない。シートを使えばいいと思う。
　　　　　 大量データの場合はクラスか配列を使う
ベテランT：個人的には可読性があがると思うが、一般的でないのでよくないかも
ベテランG：evmanでログイン処理を書いたときは積極的にクラスを使った
若手T：　　標準モジュールだと同名の関数をつけられないため、
　　　　　　クラスを使う
若手S：　　インターフェースは使えるよう

若手T：　　ライブラリをラッピングする形でクラスを使ったことがある。
若手S）　　VBAだとコンストラクタで引数を渡せない
ベテランG：コンストラクタに引数が渡せなくても別に1つコンストラクタの役割をもつ
　　　　　 メソッドを定義すればよいのではないか
若手S）　　おっしゃるとおりです。

### 構造体”Type”を使う実装は考えられる？
ベテランG：配列として使えるのか
若手S：　<TypeName>(2)といった具合で使える
ベテランK：データを入れておく箱を使うとき、構造体ではなく
　　　　　クラスを使うのはなぜなのか
若手S：　構造体だとセッターゲッターを入れられず、勝手に値を入れられてしまう。

### まとめ
若手S：　まだまだ深掘りできたり広げられるトピックがあるので
　　　　次回開催ができならうれしい
ベテランK：今回の内容を細切れにしてFAQ集を作ったり、誰かが気になったことをポストして
　　　　　誰かが答える場所があったらより議論が活性化してよい
ベテランG：SharePointならFAQを作るのは簡単　
　　　　　スレッドに対してコメントする、ということもできそうな気がする
python – inputがある限りループする


# 例

無限ループさせておいて入力が空であればループを抜ける。

```py
while True:
    x = input()
    if x == "":
        break
    else:
        print(x)
```

`while line = input():` みたいな簡潔な書き方は出来ない気がした。


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
GitHub のリポジトリを eclipse に落としてくる（クローンする）

GitHub に作ったリポジトリを eclipse で他のPCに落とす（クローンする）方法を備忘録でメモ
チーム間共有だったり個人的にいろんなところから同じ開発環境を作るときなどに使える

### eclipse で Git リポジトリのビューを開く
1. ヘッダメニュー[ウィンドウ] - [ビューの表示] - [その他] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/fe69b013-0fc8-b182-498e-6e6bb95f55fb.png)

1. [Git] - [Git リポジトリ] - [開く]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/cfaa0e56-899b-46a5-9d99-75560fd93fa5.png)

### Git リポジトリのビューから Github レポジトリをクローン
1. ビューヘッダメニュー[Gitリポジトリをクローンし、このビューへ追加] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/d9074d2e-e598-7763-1d32-41190532b4c3.png)

1. [クローンURI] - [次へ]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/99181ca0-b69d-c8ca-ef5d-47f69e9b9234.png)

1. 以下を入力して [次へ]をクリック

    - URI : Github のリポジトリより取得した URL ※これを入力でホスト、リポジトリ―パスは自動保管
    - ユーザー : Github のアカウント
    - パスワード : アクセストークン(コミットなどするときのために Repo の権限必要)
※アクセストークンの取得はこちらを参照 [GitHubアカウント作成＆アクセストークン取得 (2022/09/22)](https://qiita.com/sueasen/items/d00156f2617305b01511)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/ed480b7a-2a4b-9afa-7a12-d86d18df3440.png)

1. リポジトリのブランチがチェックされてることを確認し [次へ] をクリック ※デフォルトでOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/5b94a494-0911-a19a-5275-3a1650e5be87.png)

1. 以下の入力をして[完了] をクリック

    - クローン終了後、すべての既存 Eclipse プロジェクトのインポート : チェック
↓↓ 以降は念のため、用途によって変わるかも
    - ディレクトリー：なんでもOK（ここにローカルリポジトリが作られる）
    - 初期ブランチ : デフォルトでOK
    - リモート名 : デフォルトでOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/7aaf955c-7049-390a-a3cf-1380ff6caaac.png)

1. ビュー[パッケージエクスプローラ], ビュー[Gitリポジトリ] に該当のプロジェクトが表示されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/369912c4-5d9a-eb50-f19f-25669901712d.png)

これでOK！
FastAPI: シリアルポートの制御

こちらのシステムを、FastAPI で制御する方法です。
[M5Stack Core2: シリアルで LED を制御](https://qiita.com/ekzemplaro/items/e4ddb0ba0b03a9004204)

```py:post_serial.py
# ------------------------------------------------------------------
#	post_serial.py
#
#					Sep/25/2022
# ------------------------------------------------------------------
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import serial
import sys

# ------------------------------------------------------------------
class Item(BaseModel):
	color: str

app = FastAPI()

app.add_middleware(
	CORSMiddleware,
	allow_origins=["*"],
	allow_credentials=True,
	allow_methods=["*"],
	allow_headers=["*"],
)

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.1)

@app.get("/")
def say_hello():
	sys.stderr.write("*** start *** say_hello ***\n")
	return {"Hello": "World"}

@app.pos
t("/led")
async def process_item(item: Item):
	sys.stderr.write("*** start *** process_item ***\n")
	rvalue = {}
	rvalue["color"] = item.color
	byte_color = bytes(item.color, 'utf-8')
	ser.write(byte_color)
	return rvalue
#
# ------------------------------------------------------------------
```

サーバーの起動

```bash
uvicorn post_serial:app --reload
```

テストスクリプト

```bash
http POST http://127.0.0.1:8000/led color="red"
```

```bash
http POST http://127.0.0.1:8000/led color="yellow"
```

```bash
http POST http://127.0.0.1:8000/led color="green"
```

```bash
http POST http://127.0.0.1:8000/led color="blue"
```
python で指定回数ループする例:  for i in range(10) 

# 例

```py
for i in range(10):
    print(i+1) # 1から10までを出力
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
シェルのショートカットキー

# シェルについて
シェルはLinuxのCLIを提供するソフトウェア。
コマンド入力された内容をコンピュータに伝えている。
ちなみにコマンド入力や結果の出力をする画面はターミナルというソフトウェア。


# シェルのショートカットキーについて
## カーソルの操作

| コマンド      |     内容                                         |           
|:-----------  |:------------:                                    |
| Ctrl + f     | 一文字次へ移動                                    | 
| Ctrl + b     | 一文字前へ移動                                    | 
| Ctrl + a     | 行の先頭に移動                                    | 
| Ctrl + e     | 行の最後に移動                                    | 
| esc + f      | 一単語次へ移動　（escを押した後，escを離してfを押す）| 
| esc + b      | 一単語前へ移動　（escを押した後，escを離してbを押す）| 





## 文字列の操作

| コマンド     |    内容                                 | 
|:----------- |:------------:                           |
| Ctrl + h    | カーソルの左を１文字削除                  | 
| Ctrl + d    | カーソル部分を１文字削除                  | 
| Ctrl + w    | カーソル位置の単語を削除（カーソルの前部分）| 
| Ctrl + u    | カーソルの位置から行頭まで削除             | 
| Ctrl + k    | カーソルの位置から行末まで削除             | 
| Ctrl + y    | 最後に削除した内容を挿入                  | 


## トラブル時の操作
| コマンド       | 内容                                                | 
|:-----------   |:------------:                                       |
| Ctrl + c      | 実行中のコマンドを強制終了                            | 
| Ctrl + l      | 画面の消去                                          | 
| Ctrl + s      | 画面表示のロック(キーボードからの入力を受け付けない)    | 
| Ctrl + q      | 画面表示のロック解除                                 |
（特にIT駆け出しの方向け）覚えたらこの先ずっと役に立つ技術

よく質問されるのですよね。何勉強したらよいの？って。ということで主観でのリスト化。
## ずっと活用できる（と思われる技術）トップ10！
1. マークダウンで出力される程度のHTMLと、シンプルなCSS
2. http(s)等アプリケーション層のプロトコル、DNS、DHCP、SMTP、IMAP、FTPあたりの存在と用途、概要も知っていても良い。OSI7層とTCP/IPを一緒に学習すると効果的
3. OSI7層
4. TCP/IP
5. ドメイン管理（DNS）
6. （ネットワーク系を中心に）UNIXコマンド
7. （動的言語として)JavaScript(ECMAScript)
8. （静的言語として＆メモリ操作を理解するために）C言語
9. SQL構文
10. 正規表現

## 番外編
- JIS X 8341 (特に8341-3)
- オブジェクト指向
- NISTのクラウド定義
- The twelve-factor app


## 実はこれが1番役立つ技術（いまのところ）
- ブラインドタッチ（アルファベット、数字、記号)。できれば、日本語キーボード・英語キーボード、PC/Macそれぞれ各種で
GitLabで意図せずブランチを削除してしまった時の対処法

# TL;DR
先日、GitLabでマージする際に削除したくない共有ブランチを削除してしまった時に、GitHubやローカルでブランチを削除した際の対処法の記事は多く見受けられたのですが、GitLabに関する記事が少なかった(日本語はない？)ので備忘録として投稿します。
**急いでいる方は、解決策のところだけお読みください。**

# 背景
現在、長期インターンシップでエンジニアとしてシステム開発をしていますが、その開発形態として
1. タスクを振ってもらう。(この機能追加して〜。このバグ修正して〜。など)
1. 開発環境ブランチからそのタスク用のブランチを作成し、実装する。
1. 実装できたらマージリクエストをしてレビューしてもらう。

という流れを繰り返して進めています。
そこであるタスクについて実装中に、「開発環境ブランチにいくつかマージしました〜。」という連絡を受けたので、「マージリクエストの際にコンフリクト起きるの嫌だな〜」と思ったので、実装を一時退避して現在のタスク用のブランチにマージしようとお気持ちで、GitLabで開発環境ブランチからタスク用ブランチのマージリクエストを作成し、マージしました。そしてマージ完了の文字と共に戦慄する文字(`Deleted the source branch.`)が並んでいました...。
![メモ1-146.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2872200/4e293c50-828d-0ad1-d6ec-c18beb5fbb63.jpeg)

# 原因
マージリクエストを作成した後、マージするときに`Delete source branch`というチェック項目があり、こちらをチェックにすることでマージ後にソースブランチが削除されるようになります。こちらデフォルトでチェックが入っていることに気づかず、マージしてしまったのが原因です。
![メモ1-147.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2872200/340d25fa-689b-960d-e519-1709a82218c7.jpeg)

# 解決策
削除前のブランチの`commitSHA`を元に新たにブランチを作成することで元のブランチが復活します。
## 具体的な手順
1. 落ち着く。
焦ってはさらに大きなミスにつながるかもしれないので大きく深呼吸しましょう。
1. マージしたターゲットブランチのHistoryを開く。
![メモ1-149.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2872200/a9b77fca-1fbe-6d57-763c-4118d032b956.jpeg)
1. ソースブランチだったコミット(マージしたコミットの一つ前のコミット)の`commitSHA`をコピーする。(右のボタンでもコピー可能)![メモ1-150.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2872200/dfd3ee40-4f6d-ffe0-ae0f-bbd340958b0a.jpeg)
1. ブランチを新規作成画面でブランチ名にソースブランチの名前を入力し、`Create from`の部分をクリックして検索ボックスの部分に先ほどの`commitSHA`を入力しEnterを押し、`Create branch`する。![メモ1-151.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2872200/b01c13f3-cf6f-a8d4-74f7-e8a49120dda7.jpeg)

この手順で元のソースブランチは復活します。

# お気持ち
GitHubではマージ処理を元に戻すボタンがあるようですが、なぜGitLabにはないのでしょうか...。([open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/18633)になっているようなので是非はやく実装してもらいたい。)
また、デフォルトで`Delete source branch`にチェックが入っているのがどうなんだろうという気持ちです。(共同のリポジトリでも個人のリポジトリでもソースブランチを消したいと思うタイミングに遭遇したことがない。)

# 参考
https://stackoverflow.com/questions/69761824/can-a-deleted-gitlab-branch-be-restored
Alibaba CloudとAWSにおけるEIPとpublic IPの違いについて


# public IP(固定パブリックIP)
インスタンス起動時に以下のように「パブリックIPの割当」を選択すれば、自動的に割り当てられる動的なグローバルIPアドレスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/08d385cd-cfcb-beb1-7479-aad6698d7132.png)

- ランダムに割り当てられるため、userはIPアドレスを指定できない
- IPアドレスを自動で割り当てないことも可能
- インスタンスを再起動、あるいは停止してから再度起動しても、IPアドレスが変わらない。
- インスタンスをリリース(削除)したら、IP自体も回収され、再度同じIPが利用できなくなります。
- public IPは特定のECSインスタンスにバインドされて、アンバンドルし、他のインスタンスにバインドすることはできない。
- EIPに変換することができます。

:::note info
AWS：
- インスタンスを再起動してもIPアドレス変わらない。
- インスタンスを停止してから再度起動した場合は、IPアドレスが変わってしまうので、IPを固定にしたい場合は、AWSのEIPを利用するしかない。
つまり、AWSではIPを固定化したい場合は、EIPを利用するしかないのですが、
Alibaba Cloudではインスタンスに割り当てられているpublic IP自体も固定であり、インスタンスをリリース(削除)しなければ、ずっと同じIPが利用しつづける。
:::

# EIP
- `Elastic IP Address`の略称、独立したパブリックIPリソースであり、ECS、NATゲートウェイ、ENI NIC、SLBにバインドまたはアンバインドすることができ、簡単かつ柔軟に使用することができます。
- Alibaba Cloudのアカウントに紐づけられた静的なグローバルIPアドレスです。
- 再起動してもIPアドレスが維持(IP固定)される
- ユーザーはニーズに応じていつでもEIPの帯域幅値を調整でき、帯域幅の変更は即座に反映されます。
- EIP自体は課金されない、データ転送量に応じて完全に従量課金です。

https://www.alibabacloud.com/help/en/elastic-ip-address/latest/122035

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/500e5c52-835e-32a7-b2b0-b4536dbb345f.png)


:::note info
AWS EIPの課金方式
- 利用していない場合に課金される
    - 課金されるパターン
        - EIPがEC2に関連付けられているが、EC2が停止している場合
        - EIPが付与されているが、どこにも関連付けられていない場合
        - 稼働しているEC2に2つ目のEIPを関連付ける場合
- EIP自体の料金： 
東京region 0.005USD/h → 0.005 * 24 * 30 = 3.6$/月

https://aws.amazon.com/jp/ec2/pricing/on-demand/

- 一定の条件を満たせば、EIP自体は無料になりますが、通信量に応じてデータ転送量が別途発生します。
:::

# public IPとEIPの比較
public IPはバックエンドのECSインスタンスと密結合、EIPはバックエンドのECSインスタンスと疎結合である。
疎結合は、ソフトウェアとネットワークの両方のアーキテクチャに適した設計であり、密結合にはない多くの利点があります。
public IPは、実はclassic network(VPC利用できる前の古いnetwork type)ネットワークの歴史的遺産で、AWSやAlibaba Cloudなど歴史のあるクラウドベンダーからしか利用できませんが、長期的には徐々にEIPに置き換わっていくでしょう。 そのため、ECSインスタンスを作る時に、なるべくpublic IPを選ばず、EIPを使いましょう。

これまですでにpublic IPを使っていた場合は、「public IPからEIPへ変換」機能を利用してください。

https://developer.aliyun.com/article/272240

|public IP|AWS|Alibaba Cloud|
|:-----:|:----:|:----:|
|固定/変動|変動：インスタンスを停止してから再度起動した場合は、IPアドレスが変わる|固定：インスタンスを停止してから再度起動した場合は、IPアドレスが変わらない|
|EIPに変換|直接変換できないため、別途EIP(別のIP)を作成してから、EC2にattachする|IPアドレスを保持するまま、EIPに変換できる|


|EIP|AWS|Alibaba Cloud|
|:-----:|:----:|:----:|
|固定/変動|固定|固定|
|料金タイプ|基本料金(EIP自体、稼働しているEC2にattachされている場合は、無料) + 従量料金|基本料金なし(EIP自体は無料)、データ転送量に応じて完全に従量課金|
|料金詳細|以下の課金方法しかなくて、柔軟性が低い。|subscriptionやPay-as-you-goなどの課金方法があり、柔軟性が高い。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/df173829-9404-c26c-dac9-87ac81b45c36.png)
【WiX Toolset】カスタムアクションからログを出力する

WiX Toolset で生成した MSI ファイルを Windows Installer で実行する時、ログを出力するには、下記のようなオプションをつければよい。

```
msiexec.exe /i AppInstaller.msi /l*v installer.log
```

これで、  installer.log に MSIファイル実行時のログが出力される。ちなみに、```/l*v```は、全ての情報の詳細をログに出力することを示している。

# カスタムアクションからのログ出力

WiX Toolset に含まれる SDK を使用すれば、C/C++で実装されたカスタムアクションからも上記のログファイルにログを出力し、デバッグや障害時の原因調査に役立てることができる。

## SDKの使用方法

WiX Toolset のインストールフォルダの直下には、```SDK```フォルダがあり、SDKを構成するファイル一式が格納されている。```SDK```フォルダの下には、Visual Studio のバージョンごとにフォルダが配置され、その中にC/C++のヘッダファイル（```*.h```）およびライブラリファイル（```*.lib```）が格納されている。

```:SDKのディレクトリ構成
[WiX Toolset のインストールフォルダ]
 └ SDK
     ├ VS2010
     ├ VS2012
     ├ VS2013
     ├ VS2015
     └ VS2017
        ├ inc
        │　└ [各種 *.h ファイル]
        └ lib
           ├ x64
           │　 └ [各種 *.lib ファイル]
           └ x86
```

```inc```フォルダ内にヘッダファイルは数十個存在するが、今回の目的はログの出力なので、カスタムアクションを定義したDLLのプロジェクトからは、```wcautil.h```を include すればよい。また、ライブラリファイルについては、```wcautil.lib```の他```dutil.lib```のリンクが必要となる。

なお、この記事を書いている時点における最新安定バージョンの WiX Toolset ver. 3.11.2 では、 Visual Studio 2019 以降用のディレクトリが存在しないが、```VS2017``` ディレクトリ内の```*.h```ファイルおよび```*.lib```ファイルを使用して、Visual Studio 2019によりビルドしても、この記事の内容の範囲内であれば正常に動作させることができた。

## ログ出力関数の呼び出し

```cpp
UINT WINAPI CustomActionFunc(MSIHANDLE hInstall)
{
    INT val = 0;
    BOOL err = FALSE;

	HRESULT hResult = WcaInitialize(hInstall, "CustomActionFunc");
	if (FAILED(hResult))
	{
		return ERROR_INSTALL_FAILURE;
	}
    
    // Do something. (omit)

    if (err) {
        //Error occurred
        return WcaFinalize(ERROR_INSTALL_FAILURE);
    }

	WcaLog(LOGMSG_STANDARD, "Value: %d", val);

	return WcaFinalize(ERROR_SUCCESS);
}
```

上記コードの```CustomActionFunc```は、カスタムアクションを実装したDLLの関数で、内部で WiX Toolset の SDK を使用して、ログ出力を行なっている。

まず、```WcaInitialize```を呼び出し、フレームワーク（SDKのソースコード中では「Wcaフレームワーク」と呼ばれている）の初期化を行なっている。この時第2引数で指定された文字列が、ログに出力されるカスタムアクション名となる。

ログ出力を行うのは```WcaLog```関数で、第1引数でログレベルを指定する。ログレベルは下記の3種類から指定可能となっている。

* LOGMSG_STANDARD
常にログ出力される。通常はこれを指定すればよい。 
* LOGMSG_VERBOSE
次のように、```LOGVERBOSE```プロパティが有効にされた場合にログ出力される。
```
msiexec.exe /i AppInstaller.msi /l*v installer.log LOGVERBOSE=1
```
* LOGMSG_TRACEONLY
ログ出力されない。（ SDK 自体がデバッグビルドされている場合のみログ出力される）

第2引数以降でログ出力内容を指定する。```printf```同様の書式設定が可能となっており、第2引数で書式文字列を、可変長の第3引数以降で書式に渡すパラメータを指定する。

最後に、```WcaFinalize```はフレームワークをクリーンアップする関数で、```WcaInitialize```と対で呼び出す必要がある。

```WcaFinalize```は通常、引数の値を返すが、```WcaSetReturnValue```関数で```ERROR_SUCCESS```以外の値がセットされている場合は、その値を返すようになっている。（一度も```WcaSetReturnValue```が呼ばれていない場合の初期値は、```ERROR_SUCCESS```である。）

## ドキュメントについて

探した限りでは、WiX Toolset の配布物にSDKのドキュメントは付属していない。ヘッダファイルを見ても、関数の説明は書かれていないので、ソースコードを参照するのがよいだろう。WiX Toolset のソースコードは、[GitHubで公開](https://github.com/wixtoolset/wix3)されており、 ```src\libs```以下がSDKのソースコードとなっている。
機械学習：主成分分析で多重共線性の問題を回避

次々と新しい技術が登場するITの世界。それを追いかけるだけでも時間が足りないのに機械学習もとなると大変です。詳しく調べる前に概略を知りたい。そんな機械学習の暗闇にスポットライトをあてたい。

今回のテーマは「主成分分析で多重共線性の問題を回避する」です。
多重共線性の問題については以前の記事↓を参照ください。

多重共線性
https://qiita.com/ydclab_P002/items/95d34564faf6e28d3c3f

## 主成分分析
身長と体重から腹囲を予測したいが、身長と体重には強い相関があるとします（下左図）。
新たな軸を作成し分散が最大となるように回転させます（下右図）。

![qiita5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/ebf618a4-ebf7-8787-72c9-52174bdd185b.png)


新しい軸の成分（下図）は、身長と体重に共通する成分（横軸）とそれ以外の成分（縦軸）です。

![qiita5_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/299f599d-04b8-8d48-8081-1a9a496dec60.png)

このとき縦軸の成分を誤差とみなして切り捨てると、主要な成分（横軸）を残しつつ２つの変数を１つに削減できます（次図）。

![qiita5_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/0387f501-ffa8-e7e3-f1f5-7e4b3284e5ed.png)


この横軸の成分にあえて命名するとすれば「体の大きさ」を表す潜在的な変数です。

![qiita5_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629684/04dd7075-4869-a960-83a9-d25925833d40.png)


これがデータから主成分を抽出する主成分分析（PCA, Principal Component Analysis）の概略です。なお、軸を減らすことを次元削減や次元圧縮などといいます。

## 主成分回帰 PCR で多重共線性の問題を回避
入力変数間に強い相関関係が存在する場合、誤差の拡大効果によって回帰係数の推定結果を信頼できなくなるのが多重共線性の問題です。

次元削減で誤差成分を取り除き、抽出した主成分を用いて線形回帰モデルを構築すれば、多重共線性の問題を回避できます。これを主成分回帰（PCR, Principal Component Regression）といいます。このとき次元削減せずに全ての成分を用いると多重共線性の問題を回避できないので注意してください。

scikit-learn（Python）を用いて PCR を試します。

訓練データ
|腹囲<br>$y$|身長<br>$x_1$ |体重<br>$x_2$ |
|:-:|:-:|:-:|
|0.99|1|1.01|
|2|2|2|
|3|3|3|

このまま線形回帰モデルを適用すると体重 $x_2$ が増えると腹囲 $y$ が減るという期待を裏切る回帰係数が得られます。

```py
import numpy as np
from sklearn.linear_model import LinearRegression

y = np.array([[0.99], [2], [3]])
X = np.array([[1, 1.01], [2, 2], [3, 3]])

lr = LinearRegression()
lr.fit(X, y)

# 回帰係数
lr.coef_
```
実行結果（回帰係数）
```
array([[ 2., -1.]])
```
テストデータ（身長、体重）=（1, 2）を予測させると腹囲はほぼゼロとなり、期待を裏切る結果が得られます。
```py
# テストデータ
X_test = np.array([[1, 2]])

lr.predict(X_test)
```
実行結果（テストデータの予測結果）
```
array([[-1.99840144e-15]])
```


次は PCR を試します。

説明変数を１次元に削減します（n_components=1 を指定）。
```py
from sklearn.decomposition import PCA

# １次元に削減
pca = PCA(n_components=1)
pca.fit(X)

# 主成分
Z = pca.transform(X)
Z
```
実行結果（主成分）
```
array([[-1.4095069 ],
       [-0.00235111],
       [ 1.41185802]])
```
次元削減した主成分を用いて線形回帰モデルを構築し、テストデータを予測します。
```py
pcr = LinearRegression()
pcr.fit(Z, y)

pcr.predict(pca.transform(X_test))
```
実行結果（テストデータの予測結果）
```
array([[1.48997711]])
```

腹囲はおよそ 1.5 と予測されました。
多重共線性の問題を回避できたようです。


## PLS
PCR は目的変数と無関係に主成分を決定します。このため主成分が予測に寄与するとは限りません。その欠点を補うのが PLS（Partial Least Squares Regression）です。PLS は、目的変数との相関が最大となるように主成分を決定します。詳しくは、参考文献をご覧ください。


## 参考文献
- [加納学, PLS（Partial Least Squares）入門](
http://tech.chase-dream.com/control/SICE_PC_School/SICE2007_3_PartialLeastSquares.pdf)

- [Principal Component Regression vs Partial Least Squares Regression](https://scikit-learn.org/stable/auto_examples/cross_decomposition/plot_pcr_vs_pls.html)
Base.reduce, Base.foldl, Base.foldr

# イントロ
複数の値をひとまとめにしたコレクションがあったとき、その要素に対して一連の操作を施してひとまとめにしたいことがある。たとえば、全ての要素を順に足すとか:
```Julia
x = [1,2,3]
val = 0
for in 1:length(x)
  val += x[i]
end
```
これなら`sum(x)`でよいが、順番を気にしながら処理したいこともあるだろう。たとえば、各要素を順に割りたいとか:
```Julia
x = [1,2,3]
# 1 / 2 / 3相当が計算したい
val = x[1]
for i in 2:length(x)
  val /= x[i]
end  # ちょっと長い
println(val)  # 0.166666666666666
```
初期値を決めたいことがあるかもしれない。
```Julia
x = [1,2,3]
#  1 / 2 / 3相当が計算したい
val = x[1]
for i in 2:length(x)
  val /= x[i]
end  # ちょっと長い
```
二つの値をとる任意の関数でやりたいことだってあるかもしれない...
```Julia
x = [1,2,3]
# f(f(1,2),3)を計算したい。
```
要素が長くなると面倒くさい。

JuliaのBaseでは、このようにコレクションの要素に対して一連の演算を施して1まとめにするような操作が提供されている。そのなかに`Base.reduce`, `Base.foldl`, `Base.foldr`というのがある。

(裏話: [Flux.jl](https://fluxml.ai/)のドキュメントを呼んでたらfoldlが出てきたが、知らんかったのでまとめた)

# Base.reduce
```Julia
reduce(op, itr; [init])
```
[Base.reduce](https://docs.julialang.org/en/v1/base/collections/#Base.reduce-Tuple{Any,%20Any})は任意の二項演算を各要素に順に当てていく操作を実現できる。たとえば、上の例は以下のように書ける:
```Julia: 例1
x = [1,2,3]
reduce(+, x) # 6
```

```Julia: 例2
x = [1,2,3]
reduce(/, x) # 0.1666666666
```

```Julia: 例3
f(x, y) = (x+y)/2
x = [1,2,3]
reduce(f, x) # ((1+2)/2 + 3)/2 = 2.25
```

`init`で初期値を決めることもできる。空のコレクションに対して何かする場合にはinit必須
```
x = [1,2,3]
reduce(*, x, init=5)  # 30
reduce(*, [], init=5)  # 5
reduce(*, [])  # error
```


## 注意事項1: 特別な場合にはすでに別の関数があるのでそちらをつかう
たとえば、全部足すとかという場合には上でも述べたように`sum(itr)`がある。こういうよく使う例については別途実装されたものがあるのでそちらを使うべきである。このようなものの例には和`sum(itr)`、積`prod(itr)`、最大最小チェック`maximum(itr)`, `minimum(itr)`, and, or`all(itr)`, `any(itr)`がある。
```
sum([1,2,3,4])  # 10
prod([1,2,3,4])  # 24
maximum([1,2,3])  # 3
minimum([1,2,3])  # 1
all([true, true, false])  # false
any([true, true, false])  # true
```

## 注意事項2: 演算順序が大事な場合はreduceではなくてfoldl, foldrを使う
公式ドキュメントに以下のようにある。
> The associativity of the reduction is implementation dependent. This means that you can't use non-associative operations like - because it is undefined whether reduce(-,[1,2,3]) should be evaluated as (1-2)-3 or 1-(2-3). Use foldl or foldr instead for guaranteed left or right associativity.


つまり、演算順序がどうなるかはJuliaの実装依存で、保証がないということである。したがって、たとえば、`op`が`-`(マイナス)の場合を考えると、これは実装しだいで`(1-2)-3`になるかもしれないし、`1-(2-3)`になるかもしれない。順序を保証したいときはそれのための関数があるのでそっちを使えというこでとである。


# Base.foldl
`Base.reduce`のようなものであるが、左の要素から次々と処理されることが保証されている。
(opがf(x,y)だったとすると、yのほうにコレクションの要素が左から順次詰め込まれていく。ただし、最初のxは初期値でコレクションの最後の値か、initの値である)
```Julia
foldl(=>, 1:3)  # (1=>2)=>3
```
初期値ももちろん与えられる
```Julia
foldl(=>, 1:3, init=0)  # ((0=>1)=>2)=>3
```

# Base.foldr
`Base.reduce`のようなものであるが、右の要素から次々と処理されることが保証されている。
(opがf(x,y)だったとすると、xのほうにコレクションの要素が右から順次詰め込まれていく。ただし、最初のyは初期値でコレクションの最後の値か、initの値である)
```Julia
foldr(=>, 1:3)  # (1=>(2=>3))
```
初期値ももちろん与えられる
```Julia
foldl(=>, 1:3, init=0)  # 1=>(2=>(3=>0))
```

# 注意
Setとか順番がよくわからない気がするが、要するにfor ... in iterするときに出てくる順番である。

# 参考
* [Base.reduce](https://docs.julialang.org/en/v1/base/collections/#Base.reduce-Tuple{Any,%20Any})
* [Base.foldl](https://docs.julialang.org/en/v1/base/collections/#Base.foldl-Tuple{Any,%20Any})
* [Base.foldr](https://docs.julialang.org/en/v1/base/collections/#Base.foldr-Tuple{Any,%20Any})
react-native-draggable-flatlistでdrag後に表示がバグる

`react-native`で並び替え可能なlistを簡単に作れる`react-native-draggable-flatlist`使っていますか？？
(https://github.com/computerjazz/react-native-draggable-flatlist)

便利なんですが、表示がバグる問題に遭遇したのでメモがてら共有しようと思います。

## drag後に一瞬だけdrag前の順序で表示されてしまう
発生していた問題は上の通りです。
`DraggableFlatlist`自体はこんな使い方をすると思います
```typescript: index.tsx
<DraggableFlatlist
  data={flatlistData}
  onDragEnd={onDragEnd}
  keyExtractor={(item): string => item.id}
  renderItem={renderItem}
/>
```
onDragEndではAPIで順序を更新して、更新ができればStateにも反映するというような処理をしていました。
詳しくは書きませんがだいたいイメージとしてこんな感じです。
```typescript: index.tsx
const onDragEnd = async ({ data }: DragEndParams<MockInterview>): Promise<void> => {
  // DB上で順序を保持するcolumnを更新、更新後のdataを返すapi
  const result = await api(data)
  // DraggableFlatlistの表示を更新するためにdataとして渡しているflatlistDataのStateを更新
  setFlatlistData(result)
}
```
これでdragすればDB更新しつつ表示も順序通りにできると思っていたのですが、
いざ動かすと、一瞬動かす前の順番に戻ってしまう状態に陥りました。

## 原因: 最初にdataをsetする必要があった
結論から言うと、onDragEnd内でdataとして渡しているStateを更新するときは、一番最初にとりあえずとして更新しておかないといけないようです。
最初に更新しないと、通信の結果を待っている間は更新前、つまりdrag前のStateの順序で表示がされるみたいです。

なので解決としては、onDragEndのparamsのdataは並び替えた順序通りになっているので、
```typescript: index.tsx
const onDragEnd = async ({ data }: DragEndParams<MockInterview>): Promise<void> => {
  // 暫定的にDBの更新が成功するかに関わらずdataの内容で順序を保証
  setFlatlist(data)
  // DB上で順序を保持するcolumnを更新、更新後のdataを返すapi
  const result = await api(data)
  // DBの更新結果を反映
  setFlatlistData(result)
}
```
といった感じで、最初に暫定的に更新してしまうという対応ができる。

今回の場合は通信やDBの更新が失敗する可能性が考えられるので、実際の更新結果を待ってState更新する必要がありました。その場合でもとりあえずはうまくいった場合の内容でStateを更新しておく必要があるというわけです。

もちろんdataとresultと2回のset内容が違う場合は当然表示が切り替わることになります。
しかしdataとresultが異なる状況は、DBなどで更新に失敗したということになるので、DBと表示を合わせるために切り替わって問題ないでしょう。
Toastなどで更新失敗してしまったことを伝えるとUX的にもいいでしょう。

## 余談: 根本原因はたぶんこれ？？
非同期の関数だからかもしれない

Readme見ると、onDragEndの返り値は`Promise<void>`ではなく`void`なのでそもそも今回のような非同期関数での利用を想定していないっぽい
(https://github.com/computerjazz/react-native-draggable-flatlist#:~:text=(params%3A%20%7B%20data%3A%20T%5B%5D%2C%20from%3A%20number%2C%20to%3A%20number%20%7D)%20%3D%3E%20void)
当然ソースコードを見てもonDragEnd周辺でawaitしたりしていないので、
1. 一旦非同期のonDragEndの処理を無視して元のStateのまま表示
2. そのあとonDragEnd内でsetStateされると新しいStateの順序で表示

ということになっていそう
それでも処理の最初くらいすぐにsetStateすれば1が起きずに済むということなのかと
api通信くらい待ち時間が生じると1が起きてしまう感じと予想

確証がないので余談としました。
【Laravel】外部キー制約を外して削除したいのにCan't DROPエラーが出る

## 環境

Laravel v9.5.1 (PHP v8.1.3)

## 状況

- PointWalletテーブル
  外部キー：```user_id```
- Userテーブル

PointWalletテーブルの外部キー```user_id```を一旦削除して```cascadeOnDelete()```をつけたい。

```php
public function up()
{
    Schema::table('point_wallets', function (Blueprint $table) {
        //外部キーを外す
        $table->dropForeign('point_wallets_user_id_foreign');
        //カラムを落とす
        $table->dropColumn('user_id');
    });
    Schema::table('point_wallets', function (Blueprint $table) {
        $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    });
}
```
下記のエラーでmigration失敗する。

```
 Syntax error or access violation: 1091 Can't DROP 'point_wallets_user_id_foreign'; check that column/key exists (SQL: alter table `point_wallets` drop foreign key `point_wallets_user_id_foreign`)
```

## 原因と解決法

テーブル作成当初から外部キーを張っていて途中でテーブル名を変えた場合、作成当初のテーブル名を使ったカラム名で指定しないとmigrationに失敗する。
（PointWalletテーブルは以前```UserPoint```テーブルだった）

```php
Schema::table('point_wallets', function (Blueprint $table) {
    //外部キーを外す
    Schema::disableForeignKeyConstraints();
    $table->dropColumn('user_id');
});
```

```disableForeignKeyConstraints```を使うと当初のカラム名がエラー文に出てくれる。
```
 Cannot drop column 'user_id': needed in a foreign key constraint 'user_points_user_id_foreign' (SQL: alter table `point_wallets` drop `user_id`)
```
↑を指定してdropForeignするとmigration成功。
```php
public function up()
{
    Schema::table('point_wallets', function (Blueprint $table) {
        $table->dropForeign('user_points_user_id_foreign');
        $table->dropColumn('user_id');
    });
    Schema::table('point_wallets', function (Blueprint $table) {
        $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    });
}
```
[JavaScript] マウスでcanvasにお絵描きする現代的な方法

JavaScriptでマウスを使ってcanvasにお絵描きするコードの作り方。2022年版。

### 動作サンプルとソースコード

以下の動作サンプルでは、赤枠の中でマウスをドラッグすると線を描くことができます。

https://gistpreview.github.io/?5d0213b49523f669d322ae86db8d5c3c



```html:マウスでお絵描きのコード
<canvas id="$canvas" width="600" height="200" style="border:solid 1px red"></canvas>

<script>
const context = $canvas.getContext('2d')

$canvas.onpointermove = function(e){
    if(e.buttons){ // ドラッグ中なら
        context.beginPath()
        context.moveTo(e.offsetX-e.movementX, e.offsetY-e.movementY) // 始点
        context.lineTo(e.offsetX, e.offsetY) // 終点
        context.stroke() // 線を引く
        this.setPointerCapture(e.pointerId) // マウスがcanvasからはみ出た時も捕捉する
    }
}
</script>
```
ドラッグ中かどうかの判定方法、始点の算出方法、マウスがはみ出た時の対処方法あたりがポイント。
機能的には、canvasの外からでも描き始めることができるのが利点。

ドラッグ処理は時々出てくるので、覚えておいて損はないコードです。


## 元ネタ
https://qiita.com/arita_mii/items/27b10d67be64d0111945
【PHPUnit】factory作成はマジックメソッドが便利

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## マジックメソッドの使用
https://qiita.com/kat0/items/e037bc97a67943585082

上記の記事で```afterCreating```を使うとUser作成時にPointWalletの```points```が初期値で作成されてしまう。
テストによって値を変えたいときは下記のように書ける。

```php
User::factory()->hasPointWallet([
  'points' => 100,
])->create();

User::factory()->hasPosts(3, [
    'title' => 'Laravelについて',
])->create();
```

## 参考

https://readouble.com/laravel/9.x/ja/eloquent-factories.html?header=%25E3%2583%259E%25E3%2582%25B8%25E3%2583%2583%25E3%2582%25AF%25E3%2583%25A1%25E3%2582%25BD%25E3%2583%2583%25E3%2583%2589%25E3%2581%25AE%25E4%25BD%25BF%25E7%2594%25A8
Rust - Vectorで連続して重複する要素を削除する ( dedup )

# 例
```rs
let mut numbers = vec![1, 2, 2, 2, 2, 1, 1, 2, 2, 1];

numbers.dedup(); // [1, 2, 1, 2, 1]
```

sortを組み合わせるとユニークに出来る

```rs
let mut numbers = vec![1, 2, 2, 2, 2, 1, 1, 2, 2, 1];

numbers.sort();
numbers.dedup(); // [1, 2]
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Pair

# イントロ
Juliaには[Pair](https://docs.julialang.org/en/v1/base/collections/#Core.Pair)というデータ構造がある。よく知らなかったのでメモ。

# Pair
PairというのはJuliaのコレクションのひとつで、二つのものをまとめるために使われる。
```Julia
Pair(x, y)
```
あるいは
```Julia
x=>y
```
で`Pair{typeof(x), typeof(y)}`型のPairオブジェクトが生成される。二つの記法は完全に等価である。
```Julia
Pair(x, y) == (x=>y)  # true
```

それぞれの変数には`first`, `second`という名前のfieldに格納されている。
```Julia
x,y = 1,2
mypair = x=>y
typeof(mypair)  # Pair{Int64, Int64}
mypair.first  # 1
mypair.second  # 2
```

また、iterationを通じて各変数にアクセスすることもできる。
```Julia
x,y = 1,2
mypair = x=>y
for v in mypair 
  println(v)
end
```
とすれば、1,2が順に表示される。

(しかし、ブロードキャストする際には、1つのペアは1つのscalarとして扱われる）

# Pairが関連するあれこれ
Pairを使う場面はたくさんある。関連するデータ構造などをメモっておく。

## Dict
Dictを作る際には、
```Julia
mydict = Dict{String,Int}()
mydict["A"] = 123
```
などとしてまず空のDictを作ってから要素を追加することもできるが、キーと値のペアを渡すことで作ることもできる
```Julia
mydict = Dict("A"=>123)
mydict["A"]  # 123
```

## Fluxのレイヤーを作るときの入出力サイズ
深層学習フレームワークである[Flux.jl](https://fluxml.ai/)でレイヤーを作るときに
```Julia
Dense(10=>5)
```
とかすると思うが、これの`10=>5`はPairである。

# 参考
* [Core.Pair公式](https://docs.julialang.org/en/v1/base/collections/#Core.Pair)
* [Base.Dict公式](https://docs.julialang.org/en/v1/base/collections/#Base.Dict)
* [Flux.mlのモデル作り](https://fluxml.ai/Flux.jl/stable/models/overview/#Build-a-Model-to-Make-Predictions)
【PHPUnit】factoryのリレーション先のデータ作成はafterCreatingを使おう

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 状況

下記のようにテストでデータ作成していると、Userを削除したときのリレーション先のエラーが出ずテストでは動いているように見えていた。
だがこれに気づかないままデプロイしてdevelopでUserを削除した際、500エラーが起きてしまった。

```php
class UserFactory extends Factory
{
  public function definition()
  {
    return [
      'name' => $this->faker->name(),
      'email' => $this->faker->unique()->safeEmail(),
      'avatar' => $this->faker->imageUrl(),
    ];
  }
}

class PointWalletFactory extends Factory
{
  public function definition(): array
  {
    return [
      'user_id' => User::factory(),
      'points' => 30,
    ];
  }
}

# test
User::factory()->create();
PointWallet::factory()->for($user)->create();
```

```
Illuminate\Database\QueryException
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails 
```

## 解決法
```afterCreating```を使ってFactoryでUserを作成したときPointWalletも作成されるように追記。
するとUserを削除したときに先程のエラーが出るので、Userを削除したらリレーション先のPointWalletも削除されるようにmigrationファイルを書き換える。
さらに、PointWalletFactoryデータをテストのたびに作成しなくても良くなる。

```php
class UserFactory extends Factory
{
  public function definition()
  {
    return [
      'name' => $this->faker->name(),
      'email' => $this->faker->unique()->safeEmail(),
      'avatar' => $this->faker->imageUrl(),
    ];
  }
 
  public function configure(): self
  {
    return $this->afterCreating(function (User $user) {
      PointWallet::factory()->for($user)->create();
    });
  }
}

class PointWalletFactory extends Factory
{
  public function definition(): array
  {
    return [
      'user_id' => User::factory(),
      'points' => 30,
    ];
  }
}

# test
User::factory()->create();
```
【MySQL】検索したい数値により近いデータを取得したい

# やりたいこと
名前が A でサイズが 160 に近いデータの金額を取得したい

| id | name | size | price |
|:-:|:-:|:-:|:-:|
| 1 | A | 100 | 3000 |
| 2 | A | 200 | 4000 |
| 3 | A | 300 | 5000 |
| 4 | B | 100 | 9000 |
| 5 | B | 200 | 10000 |

結果としてこうなるようにしたい
| id | name | size | price |
|:-:|:-:|:-:|:-:|
| 2 | A | 200 | 4000 |

## ABS関数で絶対値を活用する
```sql
SELECT
    *
FROM
    `test`
WHERE
    `name` = 'A' 
    AND ABS(`size` - 160) = (
            SELECT
                MIN(ABS(`size` - 160))
            FROM
                `test`
            WHERE
                `name` = 'A'
        );
```

## 解説
1. サブクエリで名前が A 、サイズが 160 との絶対値のうち最も小さい値 40 を抽出
1. メインクエリで名前が A 、サイズが 160 との絶対値が 40 に一致するデータを取得

# 検索値が中間にあるときには注意が必要
例えば、名前が A でサイズが 250 に近いデータを取得したい時には、サブクエリで絶対値 50 が抽出され、サイズが200と300のデータがヒットしてしまいます。
| id | name | size | price |
|:-:|:-:|:-:|:-:|
| 2 | A | 200 | 4000 |
| 3 | A | 300 | 5000 |

一意のデータが欲しい際には要件を確認しましょう。

# 対応例
検索値により近いサイズの金額を取得したい。間の値の際は低い金額を優先すること。

```sql
SELECT
    MIN(`price`) AS 'result'
FROM
    `test`
WHERE
    `name` = 'A' 
    AND ABS(`size` - 250) = (
            SELECT
                MIN(ABS(`size` - 250))
            FROM
                `test`
            WHERE
                `name` = 'A'
        );
```

取得の結果

| result |
|:-:|
| 4000 |
Qiitaで気になる言葉「忘備録」ほか

### 忘備録
　辞書には「備忘録」でしか載っていませんが、Qiitaの投稿では「忘備録」という言葉を頻繁に見掛けて気になります。ＩＴエンジニアの間では常用されているのでしょうか？　言語は時代とともに変わっていくものと聞くので、老害がとやかく言うことではないかもしれません。関心などないでしょうが、私は太字の方を使っています。

**備忘録**　⇔　忘備録
山茶花：　さんざか　⇔　**さざんか**
雰囲気：　**ふんいき**　⇔　ふいんき
**インキ**　⇔　インク
**ハンケチ**　⇔　ハンカチ
**パーテーション**　⇔　パーティション
シュミレーション　⇔　**シミュレーション**
**ディレクトリ**　⇔　フォルダー
**プログラム**　⇔　スクリプト　⇔　スケッチ　⇔　・・・
**プログラマ**　⇔　エンジニア
**ブスバー**　⇔　バスバー
**ズボン**　⇔　パンツ
さるまた　⇔　**パンツ**
ビンタン　⇔　**洗面器**

### その他、意味が分かりにくいQiita用語
（**「** ググれカス ! **」** とか言われそうですが ）

箱庭、小川メソッド、水色、溶かす、メタバース、
ハッカソン、フロントエンド、バックエンド、
その他、カタカナ動詞いろいろ
　デプロイする、
　コントリビュートする

　フロントエンドとは、最前線で薄給にもめげず命を懸けて果敢に戦うＩＴ戦士、バックエンドとは、世間の批判から遮断された大本営の中で檄を飛ばすだけの管理者階級か？　と思っていましたが、どうも違うようです。勉強して出直してきます。
システムの性能指標

# オーバヘッド
コンピューターで、```ある処理を実行する際に発生する付加的な作業とそれにかかる時間```のこと。ふつう、システム全体の負荷になるものを指す。
出典 https://kotobank.jp/word/%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%98%E3%83%83%E3%83%89-1982#:~:text=%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%98%E3%83%83%E3%83%89%EF%BC%88overhead%EF%BC%89&text=%EF%BC%92%20%E3%80%8A%E9%96%93%E6%8E%A5%E8%B2%BB%E3%81%AE%E6%84%8F,%E3%81%AB%E3%81%AA%E3%82%8B%E3%82%82%E3%81%AE%E3%82%92%E6%8C%87%E3%81%99%E3%80%82

# 多重プログラミング
複数のプログラムが```同時に実行されているかのように処理```されること。CPUは1度に1つの命令しか実行できないが、処理速度が速いため、入出力命令の実行中などに割り込みが発生し、別のプログラムを処理しても、同時に実行されているように見える。
出典
https://kotobank.jp/word/%E5%A4%9A%E9%87%8D%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-5585#:~:text=%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%8C%E5%90%8C%E6%99%82%E3%81%AB,%E3%81%A6%E3%81%84%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E8%A6%8B%E3%81%88%E3%82%8B%E3%80%82

# ベンチマークテスト
実際にプログラムを実行してその時間の測定を行い、相対的な性能比較をする。
## SPEC
### SPECint
```整数演算```を１秒間に実行できる回数
### SPECfp
```浮動小数点演算```を１秒間に実行できる回数

## TPCベンチマーク
オンライントランザクション処理の性能を評価を行う。
業務別に次のような種類がある。
* TPC-A(基本性能評価用）
* TPC-B(データベース評価用）
* TPC-C(業務処理評価用）
* TPC-D(意思決定支援システム評価用）

# モニタリング
* ```測定用のハードウェアを組み込む方法をハードウェアモニタリング```
* ```測定用のソフトウェアを組み込む方法をソフトウェアモニタリング```。
  測定用のソフトウェア自身がシステム資源を使用している点に注意。

# 問題３の気づき
全体の台数で稼働率をかける。
総資源量を全体の台数からXを引いたものを分母にするそれが90%超えなければいい。
そういう関係式を作って解いていくのか。

難しい。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
駆け出しエンジニアがAWSアーキテクチャを検討した件

# もちろん製品のアーキテクチャ検討ではありません
いくら弊社([Works Human Intelligence](https://qiita.com/organizations/works-hi))が若手にチャレンジングな仕事を任せる社風だからといって、ペーペーの自分(@185shingeki)にそんな無茶をいいません。
今回はAWSさんが主催する外部研修に参加してきたのでそのお話です。

# AWS JumpStart for NewGrads
外部研修、その名はAWS JumpStart for NewGradsです。
様々な企業から新卒を集めて、地下闘技場で戦わせる夢のようなイベントです(大嘘)
期間は三日間（2022/09/07 ~ 2022/09/09）で、その主たるコンテンツは以下の二つです。
- アーキテクチャ検討
    - 新卒を4人前後のチームに分けて、お題に沿ったWebサービスのアーキテクチャをディスカッションしながら検討する。
- ハンズオン
    - AWSのアカウントを運営さんより付与してもらって、実際にそのサービスを触る。
 
# ハンズオンについて
実際にEC2やlambdaを設定し起動させるなどしました。
今回は検討について語りたいので割愛します。
大変勉強になったことは間違いないので、悪しからず。

# そもそもアーキテクチャって？
自分はこのイベント(外部研修)に参加する前はこのレベルだったので、ここから説明します。
みんな大好き[IT用語辞典](https://e-words.jp/w/%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3.html)さんによると、
「アーキテクチャとは、(中略)ITの分野では、コンピュータやソフトウェア、システム、あるいはそれらの構成要素などにおける、基本設計や共通仕様、設計思想などを指すことが多い。」
…だそうです。

# で結局どんなやつなん？
こんなやつです↓
![img_way-to-draw-architecture_03.08e1366ebaecaf76a333002acbe1e2bd363acd4b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713154/1c71b633-5cce-5077-83e9-ee90e56afaff.png)
出典元：[AWS のアーキテクチャ図を描きたい ! でもどうすれば良いの ?](https://aws.amazon.com/jp/builders-flash/202204/way-to-draw-architecture/?awsf.filter-name=*all)

今回の文脈でいうと、要するにAWSを活用したwebサービスの設計図ですね。
最終的にそれぞれのグループで、お題のサービスに適した↑のような図を完成させることが目標です。

# 実際どんなん作ったん？
こんなん作りました。
![スクリーンショット 2022-09-09 145823.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713154/a066e9ce-ea79-b461-787c-c25ce36d1c54.png)
お題は、「チャットツールのアーキテクチャを検討してね」的な感じです。
実際にはもっと詳細な要件が課されていますが、お題に関してこれ以上説明してしまうと、これ以降のイベント運営に悪影響が出るかもしれないのでぼやかします。

# イベントの流れ
![schedule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713154/908cb26f-3b63-25e6-e4b6-992a3d849046.png)
順番が前後してあれですが、こんな感じでイベントは進んでいきました。
このアーキテクチャ検討と書かれた時間にディスカッションを進める形式です。
また、その間に何度かAWS側の方に質問、相談する時間が設けられています。

# 感想
めちゃくちゃ面白かったです。
### めちゃくちゃ面白かった理由
- ほかの会社の新卒の方々と接する機会は普段ないので、新鮮だった。
- アーキテクチャとはなんぞやの状態から成果物を出せるまでに成長できたのでうれしかった。（こんな初心者も楽しませるAWSのイベント企画力、運営力恐るべしとなった。）
- 主体的に参加することで、頭を悩ませて作り出したアーキテクチャ図に愛着を持つことが出来た。
- 一から自分達で検討を行うことで、AWSのサービスについて調べざるを得ない状況に追い込まれ、単にサービス紹介を見聞きするよりも学びがあった。
- AWSの資格([SAA](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)とか？)に興味がわいた。

# まとめ
運営してくださったAWSの方々や同じグループのメンバーにはもちろん、このイベントを紹介し、快く送り出してくださった弊社の先輩方に感謝の意を表明して終わりにします。ありがとうございました！
【ActiveModelSerializer】undefined method `read_attribute_for_serialization'

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## 状況

serializerを指定するところで下記のエラーが発生。

```
NoMethodError:
       undefined method `read_attribute_for_serialization' for #<ActiveRecord::Associations::CollectionProxy []>
```

```ruby
def show
    posts = ...
    render json: posts,
           serializer: HogePostSerializer
end
```

## 解決法
```serializer```ではなく```each_serializer```に変更する。
大体の場合```each_serializer```は```index```アクションで使うイメージがあったし、ドキュメントにもそう書いてあった
>To specify which serializer to use on individual items in a collection (i.e., an index action), use each_serializer:

が、それにとらわれず何をシリアライズしたいかをよく考える。

```ruby
def show
    posts = ...
    render json: posts,
           each_serializer: HogePostSerializer
end
```

## 参考

https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/rendering.md#explicit-serializer
【AtCoder】ビット演算で状況を管理することを覚えたい【Python】

# 自分が得た学び
* 一律にフラグのオンオフを管理するときは, リスト管理よりもビット管理の方がいいことがある
* 例えば, 二つのオブジェクトのフラグ状況を見て出力が変化する場合など

# 記事の執筆経緯
この問題を解いていました。
（問題ページはこちら >>> [ABC270 A問題 1-2-4 Test](https://atcoder.jp/contests/abc270/tasks/abc270_a "A - 1-2-4 Test"))
>3 問の問題からなる試験があり、それぞれの問題の配点は 1 点、2 点、4 点でした。高橋君、青木君、すぬけ君の 3 人がこの試験を受け、 高橋君は A 点、青木君は B 点を取りました。すぬけ君は、高橋君と青木君のうち少なくとも一方が解けた問題は解け、 2 人とも解けなかった問題は解けませんでした。すぬけ君の点数を求めてください。ただし、この問題の制約下で、すぬけ君の点数は一意に定まる事が証明できます。

お恥ずかしいことにずっと前の自分なら場合分けをして、A君とB君の正解状況をリストで管理していました。恥ずかしい…(けど解けていたからヨシ！)
最近になって、状況をビット列で管理するという手法を知り、今回実践してみた次第です。

# 環境
Python(3.8.2)

# どう考える？
* 二人の状況で出力点数が変化する ⇒ ってことはビット管理の方がいい？
* なおかつ、問題の状況ってor演算になっているのでは？

# 方針
* Aの点数、Bの点数を2進数化しビット列にする
* あとはor演算を取るだけなんじゃない?

# ACコード
```python:main.py
A, B = map(int, input().split())
C = A | B
print(C)
# print(bin(A)) >>> A=5のとき, 0b101
# print(bin(B)) >>> B=3のとき, 0b11
# print(bin(C)) >>> 以上のとき, 0b111
```
# ビット演算種類
``` Python:bit_operation.py
# bit列に対して, シフト演算, or/and/xor/not演算をかけることができる
# int型の変数にそのままbit演算をかけることができる
2つ右シフト : A >> 2
3つ左シフト : B << 3
or : A | B
and : A & B
xor : A ^ B
not : ~A
```
# メモ : ビット演算はint型変数にそのまま使う
ビット演算をかじった上でここにちょっとひっかかりました。
当初のイメージでは、ビット列に変換してから使う（bin()に入れてから使う）と思ってたけど、実際は違う。
int型の変数にそのまま適用することで使えてしまうらしい。
```Python:ex1.py
A = 10
B = 12
# A, Bのint型変数に対してそのままビット演算を適用
print(bin(A)) >>> 0b1010
print(bin(B)) >>> 0b1100
print(bin(A | B)) >>> 0b1110
print(bin(A & B)) >>> 0b1000
print(bin(A ^ B)) >>> 0b110
print(bin(~A)) >>> -0b1011 # 2の補数表現になっていることに注意
print(bin(A>>2)) >>> 0b10
print(bin(B<<3)) >>> 0b1100000
```

ただし、bin()で変換した値はstr型になるため、ビット演算を適用することはできない
```Python:ex2.py
A = 10
B = 12
# ここで一度bit列(str型)への変換を挟みます
A_bit = bin(A)
B_bit = bin(B)
print(A_bit & B_bit)

>>> Traceback (most recent call last):
  File "./Main.py", line 5, in <module>
    print(A_bit & B_bit)
TypeError: unsupported operand type(s) for &: 'str' and 'str'
# やっぱりbin()使うと, str型になるからダメだって
```

でも、ビット列にしないとなんだか状況が分かりづらい…
そんなときは、`0bXXX`の表記で値を入れればOK
（これだとstr型にならない、というか結局は2進数表記で整数値を入れただけにすぎないので何の問題も起こらない）
```Python:ex3.py
A_bit = 0b1010
B_bit = 0b1100
print(bin(A_bit & B_bit)) >>> 0b1000
```
これでもうビット列で状況を管理できそうです。

# 終わりに
自分用のメモとして記事を作成しましたので、非常に読みづらく、かつミスが多いかと思われます。ミスを発見した際にはスルーしていただくか、お手柔らかにご指摘していただけると嬉しいです。
【Ruby】ひらがな/カタカナ変換や全角/半角変換や漢字にマッチする正規表現などなど

# 目次
1. [概要](#概要)
2. [参考文献](#参考文献)
3. [使用した正規表現](#使用した正規表現)
4. [作ったメソッド達](#作ったメソッド達)
    - [全角半角変換](#全角半角変換)
    - [ひらがなカタカナ変換](#ひらがなカタカナ変換)
    - [記号の削除](#記号の削除)
5. [破壊的メソッドにしたい時！](#破壊的メソッドにしたい時)
6. [Railsにおける便利な文字列操作のおすすめ記事](#Railsにおける便利な文字列操作のおすすめ記事)

# 概要
日本語の表記揺れなどに対応する必要があり、Stringクラスに定義する形で色々作ったのでメモしておきます。

# 参考文献
- https://easyramble.com/japanese-regex-with-ruby-oniguruma.html
- https://docs.ruby-lang.org/ja/latest/class/String.html#I_TR
- https://docs.ruby-lang.org/ja/latest/class/NKF.html
- https://spirits.appirits.com/doruby/11666/
- https://qiita.com/scivola/items/905225bf4175392bc359
感謝です😆

# 使用した正規表現
```ruby
/\p{Han}/ # 漢字にマッチ
/\p{Hiragana}/ # ひらがなにマッチ
/\p{Katakana}/ # カタカナにマッチ
/ー/ # 長音符にマッチ（当たり前ですがこれ忘れると「サッカー」とかにマッチしなくなるので注意）
/々/ # 「々」にマッチ（漢字に含まれないので注意）
```
※記事初稿時点では漢字の正規表現は /一-龥/ としていました。（ググって出てくるものもこれが多いです）
しかし、上記の表現ではカバー出来ない漢字があるとのことで、注意が必要です。
こちらはコメントで頂いた情報を元に修正しました。

以下記事が詳しいです。
https://qiita.com/scivola/items/905225bf4175392bc359

# 作ったメソッド達
## 全角半角変換
```ruby
class String
    def to_half_size
        # 全角を半角に
        # 長音符はハイフンに
        self.tr('０-９ａ-ｚＡ-Ｚ＋ー', '0-9a-zA-Z+-')
    end

    def to_full_size
        # to_hals_sizeと逆
        self.tr('0-9a-zA-Z+-', '０-９ａ-ｚＡ-Ｚ＋ー')
    end
end
```

## ひらがなカタカナ変換
```ruby
class String
	def hiragana_to_katakana
		NKF.nkf('-W -w --katakana', self)
	end

	def katakana_to_hiragana
		NKF.nkf('-W -w --hiragana', self)
	end
end
```
※nkfのオプション（第一引数）は公式を参考にしてください。

## 記号の削除
```ruby
class String
    def remove_symbolic_character
		# 全&半角数字/全&半角英小&大文字/ひらがな/カタカナ/漢字/ー（長音符）/スペース以外　と　スペース　を消す
		self.gsub(/[^０-９ａ-ｚＡ-Ｚ0-9a-zA-Z々\p{Han}\p{Hiragana}\p{Katakana}ー']| |　|\'/, '')
	end
end
```

# 破壊的メソッドにしたい時！
replaceメソッドでselfを置き換える事が出来るらしい。
（js使う人には文字列の置換っぽく見えるけど、self自体を置き換える）
```ruby
class String
    def to_half_size
        self.tr('０-９ａ-ｚＡ-Ｚ＋ー', '0-9a-zA-Z+-')
    end

    def to_half_size!
        self.replace(self.to_half_size)
    end
end
```

# Railsにおける便利な文字列操作のおすすめ記事
- https://qiita.com/hana-da/items/ec9ac3e1c8803f5fa1fc
Excel の ATAN2 関数の説明の誤り

　多くの言語に組み込まれている**逆三角関数 atan2** の使用上の注意について、既に下記の記事で言及しました。しかし、これには「あまり同意は致し兼ねる」風のコメントは沢山いただいたものの、「いいね」は１つだけです。誤使用による危機を皆さんに十分に伝えられなかったようで残念です。かなり切実な内容だったのですが・・・。

　　[atan2について感謝と疑問と注意点 - Qiita](https://qiita.com/tsubolabo/items/fbc1f156b7c6aa352f58)

しかし、その後、それ以前のもっともっと重大な問題が見つかりました。**Microsoft Excel の公式？ページの ATAN2 の説明の一部に誤りがあります**。

　　[ATAN2 関数 - support.microsoft](https://support.microsoft.com/ja-jp/office/atan2-%E9%96%A2%E6%95%B0-c04592ab-b9e3-4908-b428-c96b3a565033)

この「解説」の中に、

> **ATAN2(a,b) と ATAN(b/a) は等しくなりますが、ATAN2 では a に値 0 を使用できる点が異なります。**

とありますが、これが**大間違い**です。下記のように、実際に試してみれば直ぐに分かることです。他の言語の atan2 と同様に、第２，３象限では atan とは異なる正しい動作をしています。説明だけが誤っています。

![Excel_atan2_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/932484/db4351ed-92e9-09fc-1960-166427a360fc.png)

　しかし、上記の説明が多くのサイトに引用され、独り歩きして誤情報をまき散らしています。Qiita の会員の中にも、この誤情報に惑わされて atan2≒atan と思い込んでいるような方をお見受けします。この先、**地獄を見ることがないよう十分にご注意ください。**
両軸グラフ

# 両軸グラフの作り方
以下のコードで作れます。twinx()を使って両軸グラフにしています。
```
import matplotlib.pyplot as plt
import numpy as np


#配列の準備
x = np.linspace(0,2*np.pi,1000)
y = x**2
z = np.sin(x)


#図の準備
fig = plt.figure(figsize=(12,8))

#左軸の作図
ax1 = fig.add_subplot(111)
ln1=ax1.plot(x,y ,label = 'y',c='b')

#右軸の作図
ax2 = ax1.twinx()
ln2=ax2.plot(x,z, label = 'z',c='r')

#凡例の設定
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1+h2, l1+l2, loc='lower center', bbox_to_anchor=(0.5,1), ncol=2)

#軸ラベルの指定
ax1.set_xlabel('time (s)')
ax1.set_ylabel('$Y = X^2$')
ax2.set_ylabel('$Z = sin(x)$')
ax1.grid(True)
plt.show()
```
NFTドメインを取得してみた

# はじめに

NFTドメインを取得してみましたので、その際の記録です。

NFTとは

> NFTとは、Non-Fungible Token (非代替性トークン)のことで、**「偽造不可な鑑定書・所有証明書付きのデジタルデータ」** のこと。暗号資産と同じく、ブロックチェーン上で発行および取引される。

NFTアートやゲームが盛り上がっていますが、まだまだ薄い知識しかありません。
この度、NFTドメインなるものを知り、取得してみようとなりました。


# NFTドメイン取得のきっかけ

これまでの.comのような通常のドメインですと更新費用がかかっていましたが、**NFTドメインの場合は、最初の取得費を払うだけ**、ということを耳にしたからです。

買い切り、というのがよい、というとプラスして、

> 暗号アドレスとしてだけでなく、WebサイトのURLとして使用したり、PFPを設定したり、Webサービスのユーザー名や IDとして使用も可能です。最近はNFTドメインをTwitterのユーザ名に設定する人も増えています。

ということでした。暗号資産アドレスとして、しばらく使う予定はなくても、他にも用途がいろいろあるのであれば、好きな名前で取っておいても損はないかと思いました。


# NFTドメインの取得

最安値20ドルから買えます。

NFTドメイン by GMO

https://cryptoname.jp/

NFTドメイン取得

https://unstoppabledomains.com/ja-jp


取得については、全く難しくありませんでした。
参考URLを最後に載せていますが、見なくて問題ないです。まさに、指示に従うだけという感じです。

# ミント処理

NFTドメイン取得後にミント処理が必要です。

> Mintとは、取得したNFTドメインが “自身の所有であること” を、ブロックチェーン上に書き込む処理になります。

その前に、以下の2点を実施しました。とてもわかりやすかったです。参考URLに感謝。

- MetaMask(暗号ウォレット)のセットアップ

https://techffee.com/metamask-setup-21679/

- MetaMaskにポリゴンネットワークを追加する

https://techffee.com/metamask-polygon-24852/


# Openseaでの確認

取得したNFTドメインを確認することができます。

https://opensea.io/ja

![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/429ec6d1-8d9a-a53e-9c5e-f006bfb63a8f.png)


# ドメインの管理画面

unstoppabledomainsのドメイン管理画面から、ウェブページを作成することができます。

![Screenshot_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/7333b6e0-db6b-0d70-a379-102836743306.png)

![Screenshot_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/b88d8d77-c65e-40e7-c7f7-b7a26d2b7d7b.png)


#### IPFSとは何か？

https://ipfs-book.decentralized-web.jp/what_is_ipfs/

#### 対応ブラウザ

>IPFS(InterPlanetary File System)といった、ブロックチェーン技術をベースとした分散型ファイル保存技術により、Webサイトファイルが分散された状態で保存される。このためネットワーク障害にも強く、機密性も高く、また改ざんにも強いなどの性質がある。これら分散保存されたファイルへアクセスするには、従来(Web 2.0など)で言うところのDNSに替わるネームサービスとなりうる、ENS(Ethereum Name Service)を利用する。Web 3.0上のWebサイトおよびコンテンツへアクセスするには上述のIPFS(ファイル保存技術)とENS(ネームサービス)に対応したブラウザが必要になる。


# ブラウザから確認

Braveというブラウザで、取得したドメインでWEBページが確認してみます。

Braveは、何の設定もしなくても標準で、広告やトラッカーがブロックされ、それにより節約できたデータ量も確認できます。また、Chromeと同じChromiumベースのブラウザであるため、Chromeウェブストアにある拡張機能も使用できるそうです。

https://brave.com/ja/


# まとめ
- ブロックチェーン上の資産ともいえる、NFTドメイン。買い切り、ということなので、自分好みの名前があれば、ひとつ取得しておくのがよいかと思いました。


# 参考URL

https://qiita.com/euonymus/items/b41fefbe4fcb5f8d479c

https://techffee.com/blockchain-domains-18260/
【Ruby】ダックタイピングとは

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## ダックタイピングとは
特定のクラスと結びつかない、クラスを跨ぐパブリックインターフェースを取り決め実装する作法。
下記の例は```bark```メソッドがダックタイプされていると言える。
もっと複雑な実装になってくると```bark```メソッドをmoduleにまとめて共通化する方が良さそう。

```ruby
class Cat
  def bark
    puts 'ニャーニャー'
  end
end

class Dog
  def bark
    puts 'ワンワン'
  end
end

mike = Cat.new
poti = Dog.new

mike.bark
#=> 'ニャーニャー'
poti.bark
#=> 'ワンワン'
```

### 継承よりもダックタイピングを積極的に使うこと
継承が設計上必要でなければ、ダックタイピングで楽しようとのこと。

```ruby
class Animal
  def bark
  end
end

class Cat < Animal
  def bark
    puts 'ニャーニャー'
  end
end

class Dog < Animal
  def bark
    puts 'ワンワン'
  end
end
```


## 参考

https://creators.members.co.jp/2021/10/knowledge_060/

https://techracho.bpsinc.jp/hachi8833/2017_03_07/36256
JavaScript使い目線のCargo入門: CargoでHello Worldする

本稿では、Rustのツール「Cargo」について軽く触れてみることを目的とした記事です。

## Cargoとは何なのか？

Cargo(カーゴ)はRustのパッケージマネージャーです。(NodeでいうところのNPMやYarnのようなもの)

## Cargoのインストール

CargoはRustを[インストール](https://qiita.com/suin/items/4b4074acc07ce4d9720f)すると、付属してついてくるので別途インストールする必要はありません。

Cargoがインストールされているかは、バージョンを表示してみることで確認できます。

```shell
$ cargo --version
cargo 1.64.0 (387270bc7 2022-09-16)
```

## Cargoでプロジェクトを作る

Nodeの`npm init`と同じように、Cargoでもプロジェクトを作ることができます。

新たにプロジェクトを作るには`cargo new`を実行します。

```shell
cargo new hello
```

これを実行すると

- `hello`ディレクトリ
- .git
- .gitignore
- Cargo.tomlというパッケージマニフェストファイル(NPMのpackage.jsonのようなもの)
- src/main.rs

が生成されます。

main.rsの中身は次のようになっています。

```rs:src/main.rs
fn main() {
    println!("Hello, world!");
}
```

Cargo.tomlの内容は次のようになっています。

```toml:Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
```

Cargo.tomlの中身は、パッケージ名やバージョンなどが最初から設定されています。`[dependecies]`には、パッケージが依存するパッケージが列挙される場所ですが、生成時点ではどのパッケージにも依存しないので、空欄になっています。

## main.rsを実行する

Rustは基本的にコンパイル(rustc)して、実行ファイルを作らないとRustコードは実行できません。コンパイルから実行までの一通りの流れをコマンドひとつでできる機能がCargoにはあります。

次のように`cargo run`にRustファイルを指定して実行すると、コンパイルから実行までを行うことができます。

```shell
cargo run src/main.rs
```

この出力結果は次のようになります。

```
   Compiling hello v0.1.0 (/Users/suin/Desktop/hello)
    Finished dev [unoptimized + debuginfo] target(s) in 0.68s
     Running `target/debug/hello src/main.rs`
Hello, world!
```

Cargoには本稿で触れた`new`と`run`以外にも

- `build`: プロジェクトをビルドする
- `check`: コンパイルチェック
- `install`: パッケージのインストール

などのコマンドがあるので、これらにはまた今度触れてみたいと思います。