OmniAICreator/Qiita-1.07M huggingface dataset:
「良いコード、悪いコード 」& 「リーダブルコード」の個人的まとめ

# 概要
以下の書籍に記載されているもののうち、個人的に特に気をつけているコーディングルール（実装時、レビュー時）をまとめました。
- [リーダブルコード](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)　
- [良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方](https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89-%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2/dp/4297127830) 
# 目次
- 目的
- 前提
- コーディングルール
## 目的
- 書籍で学んだルールの中で自分が開発しているプロダクトに合わせて解釈、取捨選択したものを言語化することによって理解を深める
- まとめたルールを公開することで同じような技術スタック、コーディングスタイルの方の一助になればと

## 前提
私は業務ではTypescriptでフロントエンドはReact、バックエンドはNode.jsを使用しています。
クラスを用いたオブジェクト指向な書き方ではなく、関数型プログラミングライクな書き方をしています。
そのため、上記書籍のうち、クラス特有のルールについては割愛しています。

## コーディングルール
- #### 変数
    - **デフォルトはイミュータブルにする**
        - 理由
            - ミュータブルだとコードの処理中に変数の中身が変化してしまう可能性があり、可読性が低下、バグを起こしやすくなるため
        - ミュータブルを許容するケース
            - パフォーマンスに影響するケース
            	- 大量のデータの高速処理、画像処理、リソース制約がある組み込みソフトウェアなど
            	- 不変にすると値の変更のたびにインスタンスを新しく生成する必要があるため
            - スコープが局所的なケース
                - ループカウンタなど、あるスコープでしか使われないことが確実な変数の場合
    - **変数名に単位情報を記載する**
        - 理由
            - ms, Wなど単位がないと変換ミスが起きやすい
- #### メソッド
    - **フラグ引数は使わない**
        - 理由
            - フラグによってどのような処理分岐になっているか、関数内を読み解かなければいけないため
        - フラグ引数を使いたくなった場合には、メソッドを分ける、もしくは呼び出し側でフラグの処理分岐を行う
- #### コメント
    - **ロジックの内容をなぞるだけのコメントをしない**
    - **可読性の悪いコードをコメントで補足しない。代わりにコードの可読性をあげる**

- #### その他
    - **マジックナンバーはロジックにベタ書きせず変数に格納して定義する**
        - 理由
            - 仕様変更の際に一度に該当箇所を漏れなく変更できる
            - 変数名でマジックナンバーが何を表す数字なのか読み手が理解できる
    - **一見同じコードでも概念が異なれば別々に実装する**
        - 理由
            - 違う概念だが、一見同じようなコードなため、共通化すると、共通化コードに一方の都合で修正を行った場合に他方で予期せぬ影響が出てしまう
            - ex) typecriptでPrice(価格)とDistance(距離)の型定義をする場面で、どちらもnumber | nullだったとしても共通化せずに別々の型として実装する
    - **テスト関数には説明的な名前を付けてどんな条件をテストしているのかわかるようにする**
        - 理由
            - 説明的でないと第三者が見たときにコードを読み解かないとテスト内容が理解できないため
            - 主なテストツールはテストが失敗した際に関数名が表示されるため、デバックに役立つ
    
    - **if文内では早期return、ループ内では早期continueできないか検討する**
        - 理由
            - ネストを浅くできるため
OpenAPI(Swagger)とPrismでモックサーバーを建てたらテストが捗った

#### 背景

先日、とある開発にてWebAPIを複数作成することとなり、APIの単体テストやサブシステム間のテストをどのように進めるか考えていた際に、モックサーバーというものをご教示いただいたことで、その後のテストが大変捗ったため、個人の記録として書き記すものです。

先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが**自分のメモ**として、こちらへまとめておきます。

#### OpenAPI(Swagger)とは

API構造を記述するインターフェース記述言語です。yamlもしくはjsonで記述することで、綺麗なAPIドキュメントを作成することができたり、この記事で紹介するようにモックサーバを建てることができます。

https://swagger.io/
https://swagger.io/tools/swagger-ui/
https://swagger.io/tools/swagger-editor/

#### Prismとは

API設計関係のツールを提供するStoplight社によって開発されている、OSSのHTTPモックツールです。OAS2.0およびOAS3.0に準拠したドキュメントから、自動的にモックサーバを構築することができます。
https://stoplight.io/open-source/prism
https://github.com/stoplightio/prism

#### 環境

(モックサーバー)
-AWS EC2 (Amazon Linux 2)
-[Docker](https://www.docker.com/)

(OpenAPI(実体)の技術スタック)
API
-[Python](https://www.python.org/) 3.10.1
-[toranado](https://www.tornadoweb.org/en/stable/) 6.2
DB
-Amazon Aurora/MySQL 5.7
テストツール
-[Postman](https://www.postman.com/)

サーバーの構築方法については、以下の参考記事がとてもよくまとまっていますので、そちらをご参照くださいませ。
手順に沿って進めれば簡単にモックサーバーを構築できテストも進められます。

- [【OpenAPI】Prismでモックサーバ作成](https://qiita.com/andynuma/items/bf043b5184d3826d0f92)
- [prsim使って爆速でモックAPIサーバをセットアップする](https://qiita.com/hiyasichuka/items/d7f197570b6a633a1444)
- [PrismでOpenAPIを利用したモックサーバーを作る](https://zenn.dev/lightkun/articles/dfd7eeb8ad4691)
- [OpenAPI(Swagger)からモックサーバーを作成できるPrismまとめ](https://zenn.dev/wim/articles/prism_mock_server_from_swagger)

特にサブシステムや、フロントエンド／バックエンドの担当がベンダーやプロジェクトチームで分かれる際は、組織も縦割りであることからコミュニケーションにも壁ができてしまったり、開発環境やテスト環境も縦割りで個別に作られてしまったりと、なかなか思うように協力し合い共同で使える環境が構築されないケースもあるかと思います。
そういった際に、APIのパラメータとレスポンス項目とそれらのサンプル情報だけでもあれば、システム間や担当間の隔たりも、こういったモックサーバーを建てることで、スムーズに開発やテストが行なえることを、今回特に実感として得ました。

今後は、さらなるテストの効率化のため、このモックサーバーをCI/CDに絡めることで、コーディング→デプロイ→自動テスト(postman+mockサーバー)→検証と自動で進められるようにしたいと考えております。
独習プログラミングの備忘録　4 後編　【制御構文のバリエーション】

～学んだこと～
・for文の基本
　　for (初期値; 繰り返す回数; 増やすまたは減らす数)
　　ex: for(int a = 0; i < 10; i++ ≪i--≫) {...

・break文は、繰り返し自体を中断する

・continue文は、現在の回のみを中断し次の回へ

・goto文は望むところへ制御を飛ばすことができるが、多用するとプログラムの構成が複雑化し原因の特定が困難になる可能性がある

～感じたこと～
![プログラム.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882606/a328ae88-aa1d-6bcd-c7bb-d8d0431c9086.png)

九九の表を出力するプログラムを模写コーディングしてみたが、8行目の"%2d"の2がどのような役割をしているのか、あまり理解できていない。

"%2d"のとき
![テスト2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882606/02869d2a-626c-b500-0ddd-62c44bbc1f2c.png)

"%d"のとき
![テスト3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882606/39c1d362-b9c5-a0a8-8fab-0c1988fe66ef.png)

2つの画像から"%2d"はスペースを入れる役割と推測するが、参考書にはこのことについて記されていないため確証が持てない。
Gitで使用するエディターを変更する

## git commit 時のエディターを変更する

```shell-session
$ git config --global core.editor <エディタ名>
```

## git rebase -i 時のエディターを変更する

```shell-session
$ git config --global sequence.editor <エディタ名>
```

※指定しない場合は `core.editor` が使われます。
ので、使い分けしたいとかなければ設定不要です。

## お好みのエディタを設定する

- Emacs https://www.gnu.org/software/emacs/
- Nano https://www.nano-editor.org/
- Helix https://helix-editor.com/
- micro https://micro-editor.github.io/
- Visual Studio Code https://azure.microsoft.com/ja-jp/products/visual-studio-code/

お好みなのでなんでも良いです。よく目にするエディタを抜粋しました。

```shell-session
# Emacs
$ git config --global core.editor emacs
$ git config --global sequence.editor emacs

# Nano
$ git config --global core.editor nano
$ git config --global sequence.editor nano

# Helix
$ git config --global core.editor hx
$ git config --global sequence.editor hx

# micro
$ git config --global core.editor micro
$ git config --global sequence.editor micro

# Visual Studio Code
$ git config --global core.editor 'code --wait'
$ git config --global sequence.editor 'code --wait'
```

VSCode(GUIエディタ)で編集する時は `--wait` オプションを付けて保存してファイルが閉じるまで待ってくれるオプションを指定します。
Vimに戻したい時はこちら

```shell-session
$ git config --global core.editor vim
$ git config --global sequence.editor vim
```

## Git Interactive Rebase Tool

https://github.com/MitMaro/git-interactive-rebase-tool

```shell-session
$ git config --global sequence.editor interactive-rebase-tool
```

最近見つけたツールで試しに使ってみてます。
rebase用とエディタを分けれるのでこういう時に `sequence.editor` があると便利かもです。

## 参考

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%81%AE%E8%A8%AD%E5%AE%9A
https://qiita.com/takeo-asai/items/9bc7e25cd94cd8c9adee
AI Programmerの作法 その16

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- ある日、学校へ行くのに疲れてしまった高橋くんは、土曜日まであと何日あるかを知りたくなりました。
その日は平日で、曜日を英語で表すと SS だったことが分かっています。その日より後の直近の土曜日は何日後かを求めてください。なお、月曜日、火曜日、水曜日、木曜日、金曜日はそれぞれ英語で Monday, Tuesday, Wednesday, Thursday, Friday です。

# 実行結果

```
ある日、学校へ行くのに疲れてしまった高橋くんは、土曜日まであと何日あるかを知りたくなりました。
その日は平日で、曜日を英語で表すと SS だったことが分かっています。その日より後の直近の土曜日は何日後かを求めてください。なお、月曜日、火曜日、水曜日、木曜日、金曜日はそれぞれ英語で Monday, Tuesday, Wednesday, Thursday, Friday です。

#include <iostream>
#include <string>

using namespace std;

int main() {
	string s;
	cin >> s;

	int cnt = 0;
	if (s == "Monday") 
	{
		cnt = 5;
	} 
	else if (s == "Tuesday") 
	{
		cnt = 4;
	} 
	else if (s == "Wednesday") 
	{
		cnt = 3;
	} 
	else if (s == "Thursday") 
	{	
		cnt = 2;
	} 
	else if (s == "Friday") 
	{
		cnt = 1;
	}

	cout << cnt << endl;
}
```

# paiza.io

# 入力

```
Wednesday
```

# 実行結果

```
3
```

# 成果物

https://paiza.io/projects/1nqRuNlYy-7QALGXMxQf0A

以上。
supervisor docker構築 使用方法

# Supervisor構築

## 今回のインフラ構成
### Dockerのコンテナ
    - Laravel（phpコンテナ）
    - Nginx
    - dbサーバ（mysql）

## suervisor導入理由
laravelにはデフォルトで以下のコマンドが存在するが落ちる可能性が高く落ちたときにjobバッチが実行されない危険性があったのでsupervisorを導入してlinux上で監視させ落ちたときに自動で再起動させるように設定
```
php artisan queue:work
```

### 実装方法
まずsupervisorを導入したいコンテナのdockerFileにsupervisorインストールさせるコマンドを追記する
今回はphpコンテナを監視させたいのでphpのdockerFileに以下を追記する
```
RUN apt-get update supervisor
```

次にsupervisord.conf（設定ファイル）を作成する

```
[supervisord]
// trueに設定しないと起動時にデーモンモードになってしまい落ちるので必ずtureにする
nodaemon=true

[program:php-fpm]
command=php-fpm --nodaemonize
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0


// xxxはjob実行時にdispatchするQueueの名前
[program:xxx]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work --queue=xxx --timeout=0 --backoff=10
autostart=true
autorestart=true
user=root
numprocs=3
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
```

そしてこのsupervisord.confをdockerコンテナ上にコピーするコマンドをphpのdockerfileに記入
```
RUN mkdir -p /var/log/supervisor
COPY ./supervisord.conf /etc/supervisor/conf.d
```

これでdockerを立ち上げ直すとsupervisorが使用できるようになります

### 使用するコマンド

- Jobを修正した場合は以下のコマンドを実行し直しsupervisorを立ち上げ直す必要がある
```
supervisorctl reload
```

- supervisorが起動しているかどうかの確認
```
supervisorctl status
```

### 以上
Google UXデザイン：ペルソナを作る

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3729adea-8dba-b2a3-6127-9b0bf6886e54.png" width="800">

# ペルソナとは

***<font color="MediumVioletRed">『ペルソナとは、目標や特徴を持つ架空のユーザーで、より多くのユーザーのニーズを代弁するもの』</font>***

ペルソナは、調査によって得られた、類似した特徴を持つユーザーのグループを表します。ペルソナは、ユーザーのライフスタイルを反映し、ユーザーのニーズや課題を満たすためのアイデアをチームに与えてくれるため、デザインプロセスにおいて重要な役割を果たします。

UXデザインの世界では、常にユーザーが最優先されます。しかし、ユーザーのニーズを最優先するには、誰のことを指しているのかを知らなければなりません。

# ペルソナをビルドする

わたしたちは、[ユーザーリサーチ][research]から[共感マップ][map]を使い、[ペインポイント][painpoint]を特定することができました。ようやく、ペルソナを作ることができます。つまり、総まとめなのです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/af294dbb-0f2a-bdb1-699a-4a52a295d947.jpeg" width="５00">

[research]: https://qiita.com/masami-atwvn/items/d92fcf41ececbbd2492b
[map]: https://qiita.com/masami-atwvn/items/44d441768bb9e7b35ed4
[painpoint]: https://qiita.com/masami-atwvn/items/82dd96ffc40405c5d229

ペルソナを作成する際には、***<font color="Teal">データの中から最も共通するテーマを探し出し</font>***、そのテーマを擬人化したユーザーをグループ化します。

# サンプル（犬の散歩アプリ）

:::note info
45歳から60歳の潜在的なユーザーの多くが、犬の散歩をしている人が自分の家に出入りすることを懸念している
:::

この年齢層のユーザーを代表するペルソナを作成すれば、間違いなくペインポイントになるでしょう。

一般的には、3～8人のペルソナを作成すれば、製品のユーザーベースの大部分を表現するのに十分です。

ペルソナは、ユーザーを正確に表現することが重要ですが、ユーザーの具体的なニーズをすべて満たすことは不可能です。大切なことは、製品を効果的に利用するユーザーの行動と目標に焦点を当てる必要があります。

さて、犬の飼い主の視点からシナリオを考えてみましょう。

- ダニエラは48歳のフリーランスの映画プロデューサーで、パートナーのプリヤと2人の子供と一緒にジョージア州アトランタに住んでいます。一家は最近、シスコという名のゴールデンレトリバーの子犬を迎えました。
- 一家は体操競技のために子供たちと定期的に旅行に出かけ、ダニエラは撮影の際に長時間移動することが多い。ダニエラは、家族が留守の間や忙しいときに、子犬のシスコの世話をしてくれる人を探したいと思っています。
- ダニエラさんが一番心配なのは、見ず知らずの人を家に入れ、子犬の世話をしてもらうことです。ダニエラさんは、子犬の適切な世話の仕方を知っていて、シスコを散歩やドッグパークに連れ出すことができる人を雇うのが一番安心でしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/6b7f60f4-03cd-a764-dafe-f00c6d684ea4.png" width="５00">

ペルソナの情報を使って、ダニエラのようなユーザーに直接語りかけるようなデザインを作ることができるのです。そうすることで、ユーザーが製品を使用する際に最高の体験をすることができます。

例えば、ドッグウォーカーがアプリによって審査され、バックグラウンドチェックに合格しなければならないことをデザインに示すと、ダニエラのようなユーザーは自分の愛犬が安全であることを安心することでしょう。


:::note info
ペルソナを作成する前に、製品のユーザーについてチームの意見を聞いてください。そして、ペルソナを作成した後、作成したペルソナと比較します。その際、データがどのように彼らの提案を検証し、あるいは矛盾しているのかを指摘してください。ユーザーと真につながるためには、チームの全員がペルソナを理解する必要があるのです。
:::

# 提出したペルソナ（題材：環境問題支援アプリ）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4e59a284-9081-3c34-e947-2f679612638b.png" width="５00">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/350432ee-175b-9d8f-1802-06b0e09bda22.png" width="５00">
ChArUco マーカーボードで位置推定

# ChArUcoとは

公式Doc: https://docs.opencv.org/3.4/df/d4a/tutorial_charuco_detection.html

![charucodefinition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/c7c0c06f-b45b-f6c6-48ca-bcc00b7d09ac.png)

> The ArUco part is used to interpolate the position of the chessboard corners, so that it has the versatility of marker boards, since it allows occlusions or partial views. Moreover, since the interpolated corners belong to a chessboard, they are very accurate in terms of subpixel accuracy. When high precision is necessary, such as in camera calibration, Charuco boards are a better option than standard Aruco boards. (公式Docより引用)

- とどのつまり
  - arucoマーカーたくさん並べて精度上げたり安定性を高めるための便利ツール。
  - 一部が隠れててもChArUcoボード自体の姿勢推定ができる。
  - ChArUcoボード自体でカメラのキャリブレーションもできる。

- ボードの作り方
  - 売ってる (たぶんぼったくり) https://calib.io/products/charuco-targets
  - 自分はpdfにしてキンコーズでセルフで印刷(厚紙A3)+ラミネート(マッド加工)しました (全部で600円くらいでできた)
    - pdfへの出力は無劣化な方法を使いましょう (⇩のコード参照されたし！)

# 詳しくは

- こちらのjupyter notebookを参照してください・・・ (雑)
    - https://github.com/naruya/aruco/blob/master/3_charuco.ipynb
    - (多少自己流が含まれます)

# ギャラリー


<iframe width="640" height="540" src="https://www.youtube.com/embed/05WQJ5xQrgc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

- ⇧ マーカーで推定したカメラの姿勢データを使ってNeRF (Colmapを使わないNeRF)


![sample3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/4cc578fd-0bd7-d6c2-e2c8-0fbb59bab62c.gif)


- ⇧ マーカーでカメラの姿勢推定


![charucotable.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/bdcc3787-ec79-cddd-120f-ff78f1d49bd0.jpeg)

- ⇧ 入力画像

![charuco2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/6e674387-dbcd-4e12-7cfe-023fcaef1a46.png)

- ⇧ 邪魔なオブジェクトを描画

![charuco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/63679555-d6af-61b3-fcfe-969e5bed7a44.png)
![charuco2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188173/0debdf96-549d-9a83-5317-10966f094938.jpeg)

- ⇧ 邪魔なオブジェクトありで、ボードの姿勢推定をした結果
４行のコードでAI物体検出を使う方法【Python,Yolov5】

# 物体検出を使ってみたい
プログラムが自動で画像から物体を見つけてくれる物体検出、色々な分野で使えます。
![6ffb75b6-a203-4b7f-b512-504062e15991.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f423d4dd-f299-a6cb-48ee-82686f5bc477.jpeg)

# AIを使うのは難しそう
何行もコードが必要と思うじゃないですか。

# 実はめちゃくちゃかんたん
すごくかんたんに使えるようになっています。
今回は**Yolov5**を使います。

https://github.com/ultralytics/yolov5

# 方法

torch hubからモデルをロードして、画像を入力として与えます。

```python
import torch
model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # initialize model
result = model('teddybear.jpg') # inference
result.save()
```

これだけで推論画像が保存されます。
かんたんでしょ？

![6ffb75b6-a203-4b7f-b512-504062e15991.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f423d4dd-f299-a6cb-48ee-82686f5bc477.jpeg)


# 結果を見る

結果の座標にアクセスすることもできます。

```python
result.pandas().xywhn
```

>[    xcenter   ycenter     width    height  confidence  class        name
 0  0.701028  0.522462  0.262828  0.421278    0.930700     77  teddy bear
 1  0.703856  0.719701  0.487835  0.442845    0.913001     13       bench]

検出可能なクラスは以下で取得できます。

```python
model.names
```

>{0: 'person',
 1: 'bicycle',
 2: 'car',
 3: 'motorcycle',
 4: 'airplane',
 5: 'bus',
 6: 'train',
 7: 'truck',
 8: 'boat',
 9: 'traffic light',
 10: 'fire hydrant',
 11: 'stop sign',
 12: 'parking meter',
 13: 'bench',
 14: 'bird',
 15: 'cat',
 16: 'dog',
 17: 'horse',
 18: 'sheep',
 19: 'cow',
 20: 'elephant',
 21: 'bear',
 22: 'zebra',
 23: 'giraffe',
 24: 'backpack',
 25: 'umbrella',
 26: 'handbag',
 27: 'tie',
 28: 'suitcase',
 29: 'frisbee',
 30: 'skis',
 31: 'snowboard',
 32: 'sports ball',
 33: 'kite',
 34: 'baseball bat',
 35: 'baseball glove',
 36: 'skateboard',
 37: 'surfboard',
 38: 'tennis racket',
 39: 'bottle',
 40: 'wine glass',
 41: 'cup',
 42: 'fork',
 43: 'knife',
 44: 'spoon',
 45: 'bowl',
 46: 'banana',
 47: 'apple',
 48: 'sandwich',
 49: 'orange',
 50: 'broccoli',
 51: 'carrot',
 52: 'hot dog',
 53: 'pizza',
 54: 'donut',
 55: 'cake',
 56: 'chair',
 57: 'couch',
 58: 'potted plant',
 59: 'bed',
 60: 'dining table',
 61: 'toilet',
 62: 'tv',
 63: 'laptop',
 64: 'mouse',
 65: 'remote',
 66: 'keyboard',
 67: 'cell phone',
 68: 'microwave',
 69: 'oven',
 70: 'toaster',
 71: 'sink',
 72: 'refrigerator',
 73: 'book',
 74: 'clock',
 75: 'vase',
 76: 'scissors',
 77: 'teddy bear',
 78: 'hair drier',
 79: 'toothbrush'}

# 自分でトレーニングしたモデルの使用
自分でトレーニングしたモデルを使うこともできます。
これにより、デフォルトのクラス以外の物体も検出することができます。

```python
model = torch.hub.load('ultralytics/yolov5', 'custom', path='path/to/best.pt') # Specify your own path
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
Nginx リダイレクト

# Nginx リダイレクト処理

## 背景
お金をかけずにリダイレクト処理をさせたいという要望で普段WAFで実装していることをnginx側で実装
AWSなどでも同じことはできるがリクエストの度にWAFを通すことで一回のリクエストの料金は安くても意外とコスト削減につながる
WAFとの違いは、nginxを通すか、通す前弾くかの違いでそこまでセキュリティに差はないのかなと感じている（個人の感想）
なので今後基本的にnginxでいいのでは？と思っている次第
ということで以下実装方法

### 実装方法
nginxのリダイレクト色々あるみたいなんですけど、今回はrewrite構文で実装しました

```
rewrite ^/リダイレクトさせたいパス$ 遷移後のパス [option];
```

使用例を上げるとすると、
/hoge を /hogehoge にリダイレクト（恒久的に）させることを設定するとなると、

```
rewrite ^/hoge$ hogehoge permanent;
```
になります。

また、階層を一つ戻す場合も同様で
/hoge/hoge を /hogehogeにリダイレクトさせる場合は

```
rewrite ^/hoge/hoge$ ../hogehoge permanent;
```

ちなみに
/hoge/hoge.html の.htmlを消したい場合は以下で実装可能です
```
rewrite ^/hoge/(.*).html$ $1 permanent;
```

### 以上
nginxの資料少なかったので、自分へのメモとして記させていただきました。
AI Programmerの作法 その15

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- 与えられる 5 つの整数 A, B, C, D, E の中に何種類の整数があるかを出力してください。

# 実行結果

```
与えられる 5 つの整数 A, B, C, D, E の中に何種類の整数があるかを出力してください。

#include <iostream>
using namespace std;

int main() {
	int A, B, C, D, E;
	cin >> A >> B >> C >> D >> E;

	int count = 0;
	int nums[5] = {A, B, C, D, E};
	for (int i = 0; i < 5; i++) 
	{
		bool duplicate = false;
		for (int j = 0; j < i; j++) 
		{
			if (nums[i] == nums[j]) 
			{
				duplicate = true;
				break;
			}
		}
		if (!duplicate) 
		{
			count++;
		}
	}

	cout << count << endl;
	return 0;
}
```

# paiza.io

# 入力

```
31 9 24 31 24
```


# 実行結果

```
3
```

# 成果物

https://paiza.io/projects/daUuB1-JkcbFoURKgYdXSQ?language=cpp

以上。
AI Programmerの作法 その14

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- 整数 a, b, c, d が与えられるので、以下の指示に従って 2 行出力してください。
1 行目は (a+b)×(c?d) の計算結果を整数として出力してください。
2 行目は入力にかかわらず Takahashi と出力してください。

# 実行結果

```
整数 a, b, c, d が与えられるので、以下の指示に従って 2 行出力してください。
1 行目は (a+b)×(c?d) の計算結果を整数として出力してください。
2 行目は入力にかかわらず Takahashi と出力してください。

	int a, b, c, d;
	std::cin >> a >> b >> c >> d;

	std::cout << (a + b) * (c - d) << std::endl;
	std::cout << "Takahashi" << std::endl;

```
# paiza.io
# 入力

```
1
2
5
3
```

# 実行結果

```
6
Takahashi
```

# 成果物

https://paiza.io/projects/wFY7OUjne9LXAKyUGwmEYQ?language=cpp

以上。
AI Programmerの作法 その13

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- 0 以上 255 以下の整数 N を、必要に応じて先頭に 0 を加えることでちょうど 2 桁の 16 進表記に変換してください。

# 実行結果

```
0 以上 255 以下の整数 N を、必要に応じて先頭に 0 を加えることでちょうど 2 桁の 16 進表記に変換してください。

	int N;
	if (N < 0) 
		N = 0;
	if (N > 255) 
		N = 255;
	printf("%02X", N);

```

# paiza.io

# 入力

```
99
```

# 実行結果

```
63
```

# 成果物

https://paiza.io/projects/-So7CzFKpFeuDz-6_rF8QA

以上。
【Terraform】environmentsディレクトリとmodulesディレクトリの構造が微妙な理由

# 背景

複数環境あるインフラでのterraformのディレクトリ構造として以下の構成を取っているケースを比較的見かけます。

```
├── environments
│   ├── dev
│   │   ├── backend.tf
│   │   └── main.tf
│   ├── prod
│   │   ├── backend.tf
│   │   └── main.tf
│   └── stg
│       ├── backend.tf
│       └── main.tf
└── modules
    ├── database
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── eks
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    └── vpc
        ├── main.tf
        ├── outputs.tf
        └── variables.tf
```

[Terraform を使用するためのベスト プラクティス  \|  Google Cloud](https://cloud.google.com/docs/terraform/best-practices-for-terraform?hl=ja#subdirectories)にもこれと同じ構成の例が載っています。

ただ、この構造はあんまり良くない点があります。

# なぜ微妙か

多くの人が意識していませんが、普段 `terraform plan` や `terraform apply` を実行するディレクトリもまたrootモジュールと呼ばれるモジュールです[^1]。

[^1]: [Modules Overview \- Configuration Language \| Terraform by HashiCorp](https://www.terraform.io/language/modules#the-root-module)

冒頭のディレクトリ構造を見ると、フォルダ(ファイル)をenvironmentsとmodulesという2種類に分類しているように見えます。しかし、実際にはenvironmentsフォルダ中にあるdevやprodもまたモジュールです。なので、rootモジュールの知識を持っている人が見ると奇妙に見えます。



```
├── environments
│   ├── dev      ← これもモジュール
│   ├── prod     ← これもモジュール
│   └── stg      ← これもモジュール
└── modules
    ├── database
    ├── eks
    └── vpc
```

例えるなら以下のような構造に見えます。

```
├── 人物
│   ├── 太郎                 ← これも哺乳類
│   ├── 花子                 ← これも哺乳類
│   └── フェルスタッペン       ← これも哺乳類
└── 哺乳類
    ├── 犬
    ├── 猫
    └── 熊
```

# どうすればいいか

以下のどちらかをおすすめします。

## 案1. modulesをchild-modulesへリネームする

environments下のディレクトリはモジュールではありますが、rootモジュールでありchildモジュールではありません。
なので、modulesディレクトリをchild-modulesなどへリネームすれば矛盾は解消できます。

```
├── environments
│   ├── dev
│   ├── prod
│   └── stg
└── child-modules    (修正)
    ├── database
    ├── eks
    └── vpc
```

## 案2. modulesをchild-modulesへ、environmentsをroot-modulesへリネームする

案1に加えてenvironmentsディレクトリもリネームする案です。
個人的にはこちらのほうがおすすめです。というのは、そもそもenvironmentsとmodulesというディレクトリの切り方が概念として直行していないことが根本的なわかりにくさの原因だからです。root-modules or child-modulesという切り方は同じ切り口でフォルダを分類しており、その問題を解消しています。

```
├── root-modules     (修正)
│   ├── dev
│   ├── prod
│   └── stg
└── child-modules    (修正)
    ├── database
    ├── eks
    └── vpc
```

# 蛇足

childモジュールの名前の変更は moved ブロックを使用すれば結構手軽にできます。
`terraform state mv` の利用なしに通常の `terraform plan / apply` と同じフローで移動できるからです。
なので、微妙だと思っているモジュール名やモジュール配置は気軽に改善していきましょう。
Google UXデザイン：ペインポイントを特定する

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3729adea-8dba-b2a3-6127-9b0bf6886e54.png" width="800">

# ペインポイントとは

UXデザイナーが行うすべてのことを1つの役割に絞り込むと、その役割は問題解決者であり、ユーザーの苦悩や痛点を解決することがリストの第1位となります。

***<font color="MediumVioletRed">『ペインポイントとは、ユーザーを苛立たせ、必要なものを得るのを妨げるUXの問題のこと』</font>***

UXデザインとは、ユーザーに関するものであることは、もうお分かりでしょう。常に、常に、ユーザーのためにデザインするのです。

しかし、ユーザーとは誰で、どんなことに困っているのでしょうか？それを知るには、「共感する力」が必要です。ユーザーの頭の中に入り込み、彼らがどこから来るのかを理解するためのリサーチが必要なのです。

また、ユーザーが知っているニーズと、知らないニーズの両方を予測する必要があります。

# ペインポイントの種類

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/6ac2a14c-e601-ce17-bf76-e9b59c2910c7.png" width="650">

### お金にまつわる
有料の壁に阻まれたことがある人なら、よくご存じでしょう。

### 製品の品質
ドアが開くと思えば、開くはずです。開かない場合は、それがユーザーのペインポイントになります。

### プロセス
オンラインで買い物をしたときに、欲しい商品を手に入れるのに苦労したことはありませんか？

### サポート
企業のウェブサイトからカスタマーサービスを探しても、見つからない。。

# デザイナーが考えること

私たちは皆、これらの痛みを経験したことがあると言ってもいいでしょう。私たちはその気持ちを知っています。デザイナーとして、あなたはそれがユーザーにとってどのように感じられるかを知る必要があります。

ドアの実験を思い出してください。ドアを開けるのは、必ずしも簡単ではないかもしれません。

- もし、ユーザーが車いすに乗っていたらどうでしょう？
- ノブに手が届かなかったら？
- 力が足りなかったら？

あなたは、すべてのユーザーを考慮したいと思うでしょう。

# 共感マップからペルソナへ

[前回ご紹介した共感マップ][map]は、ユーザーが何を考え、何を言い、何を行動し、何を感じているかを示してくれます。

***<font color="MediumVioletRed">『共感マップは、ユーザーの考え方に入り込むのを助け、彼らのペインポイントを特定することを可能にする』</font>***

これはほんの始まりに過ぎません。ユーザーのことを本当に知りたいからこそ、デザイナーはユーザーペルソナを作るのです。それでは、次回[ペルソナ][persona]を作ってみましょう。

[map]: https://qiita.com/mapami/items/44d441768bb9e7b35ed4
[persona]: https://qiita.com/mapami/items/8a6894d0ca86ff8bc17f
Intel RST RAID を Boot Drive に使う時はよく考えて使おう

# なにがあったか
1. Windows11 の Boot SSD を、RST RAID (Mirror) にしていた
2. 電源ボタンで強制電源OFFにした
3. ブルースクリーンさんこんにちは＾＾

# why？
- Mirror は、正常にシャットダウンされないと `verify` state になる
    - 二つのドライブで整合性が取れない状態
    - `verify` state は、整合性チェックが終わらないとデータを読み出せない
- **Boot SSD が読み出せない**
    - こうなると面倒
    - Windows11 のバニラ iso だと VMD をそもそも認識できないのでドライバが別に必要になって死ぬほど面倒くさい


# 対処
- 何回か再起動したら起動できました
    - 裏で整合性チェック終わったらしいです
- Mirror やめました
    - 書き込みも遅いし
- そもそも個人レベルならシステムイメージ作っとけば大丈夫やろ（多分）


# URL
- https://www.intel.com/content/www/us/en/support/articles/000006188/technologies/intel-rapid-storage-technology-intel-rst.html
- https://support.lenovo.com/us/ja/solutions/ht079429
- https://community.spiceworks.com/topic/445731-does-intel-rapid-storage-technology-verify-in-bios-or-way-to-verify-from-boot-cd
ubuntuのホームディレクトリを拡張する方法

環境 ubuntu18.04
1TBが乗ってる化石
2TBの共有ディスクがあるけど運用的に使いづらい
/homeの容量は512GBで53％
このディスクより大きいディスクを挿すことで拡張をする。

以下、コマンドは一例で出力内容は一部省略しています
当該作業による不利益を一切保証しません

今回はWD赤6TBを挿す
とりあえずカバー開けてHDDを挿して起動

~~~
$ sudo fdisk -l
/dev/sda 894GB
/dev/sda1 ######## BIOS boot
/dev/sda2 ######## Linux filesystem
/dev/sda3 ######## Linux swap
/dev/sda4 ######## Linux filesystem
/dev/sda5 ######## Linux filesystem

/dev/sdb 1.8TiB

/dev/sdc 5.5TiB
~~~

~~~
/dev/sdc 5.5TB
~~~
どうやら認識されていそう

ファイルシステムをext4でフォーマットする
~~~
$ sudo mkfs.ext4 /dev/sdc
~~~
あとでわかるけどここで/homeと同じファイルシステムにしておくとスムーズ

UUIDを見る
~~~
$ blkid
/dev/sda2: UUID="2*****" TYPE="ext2" PARTUUID="******"
/dev/sda3: UUID="3*****" TYPE="swap" PARTUUID="******"
/dev/sda4: UUID="4*****" TYPE="xfs" PARTUUID="******"
/dev/sda5: UUID="5*****" TYPE="xfs" PARTUUID="******"
~~~

どのUUIDのディスクが/homeとしてマウントされているのかを確認する
~~~
$ sudo cat /etc/fstab
#####
UUID=5***** /home xfs defaults 0 1
#####
~~~
どうやら /dev/sda5らしい

/dev/sda5(/home)から/dev/sdc（追加したディスク）へコピー
~~~
$ dd if=/dev/sda5 of=/dev/sdc
~~~

なお、UUIDとパーティション、ファイルシステムもコピーされる
なんにも出力されなかったりするけど正常、結構時間かかるのでコーヒーでも入れてのんびり待ちましょう。

このままでは/dev/sda5とUUIDが同じでマウントできない
試しにUUIDを表示してみると同じなのが確認できると思う
~~~
$ sudo xfs_admin -u /dev/sda5
$ sudo xfs_admin -u /dev/sdc
~~~

uuidgenコマンドを使ってUUIDを生成して/dev/sdcに設定する

ただ、今回mkfsでext4を指定しているのでエラーが出てしまった。

順序立てて行う
これでファイルシステムの修復を行える
~~~
$ sudo xfs_repair -L /dev/sdc
~~~
便利

次にUUIDの変更を行う
~~~
$ sudo xfs_admin -U `uuidgen` /dev/sdc
~~~

UUIDを表示してみる
~~~
$ sudo xfs_admin -u /dev/sdc
~~~
無事変更できた

これを/etc/fstabに追記しないと行けない。
僕は普段ファイルにパイプしてヤンクしているがそれぞれの宗教でいいと思う。
ついでに/home_backupみたいな名前でマウントポイントをもう一つ作成しておく

~~~
$ sudo mkdir /home_backup
$ sudo vim /etc/fstab
~~~

``` diff:/etc/fstab
- UUID=5***** /home xfs defaults 0 1
+ UUID=5***** /home_backup xfs defaults 0 1
+ UUID=c***** /home xfs defaults 0 1
```

もともとあった/homeディレクトリを一応バックアップとして残しておいて新しくコピーしたほうを/homeとしてマウントする

/homeディレクトリ以外にcd
~~~
$ cd /
~~~
/homeディレクトリをアンマウント
~~~
$ sudo umount /dev/sda5
~~~
設定変えたところをマウント
~~~
$ sudo mount /dev/sda5
$ sudo mount /dev/sdc
~~~

/homeディレクトリに移動
~~~
$ cd
~~~
設定が変わったかの確認方法として新しい/homeディレクトリのほうのアンマウントを試みる
~~~
$ sudo umount /dev/sdc
umount: /home: target is busy
~~~
エラーが出てアンマウントできなかったので設定が反映されている

~~~
$ sudo df -h
/dev/sdc 477G 252G 252G 53% /home
/dev/sda5 477G 252G 252G 53% /home_backup
~~~

ただこのままでは古いパーティションで切られており容量が小さいままなので容量を広げる

~~~
$ sudo xfs_growfs /dev/sdc

$ sudo df -h
/dev/sdc 5.5T 252G 5.3 5% /home
/dev/sda5 477G 252G 252G 53% /home_backup
~~~
/dev/sdcが無事大きくなった

一旦再起動して異常がないか確認
sudo reboot

emergency modeが起動した
fdiskでディスクが認識しているか確認
/dev/sdcが認識されていない
どうやらラックに戻すときに追加したHDDが半挿しになってしまっていたっぽい
挿し直してもっかいreboot

正常に起動

おわり
Swiftメモ詳細画面・タイトル日付フォーマット（西暦）作成の復習：初学者アウトプット３

<h2>メモの内容を表示させる</h2>
・Storyboard上において、メモなどの比較的長い文章などを表示させる際には「UITextView」を使用する。<br>
<br>
・画面いっぱいに表示させるには「autolayout」を使用する。エディターエリア右下のアイコン「Add new constraints（新しい制約を追加）」を開くと余白を設定できる。<br>
<br>
・ヘッダー部分に表示させたい文字列がある場合、UIViewControllerに標準で用意されている「navigationItem」というプロパティを使用する。このプロパティの「title」に対して任意の文字列を代入することで表示させることができる。

```
例：
navigationItem.title = "任意のタイトル"
```
・「DateFormatter」：日付のフォーマットを変更する場合に使用するクラス。<br>
使用するには、<br>
１：変数に「DateFormatter」クラスを代入してインスタンス化<br>
２：「dateFormatter.dateFormat」プロパティに文字列を代入する。<br>
３：今回は年月日を西暦で表示したいので、「yyyy年MM月dd日」を代入
```
例：
var dateFormat: DateFormatter {
    let dateFormatter = DateFormatter ()
    dateFormatter.dateFormat = "yyyy年MM月dd日"
    return dateFormatter
}

// 「y」は年、「M」は月、「d」は日　　の数値が入る。
// dateFormatはコンピューティッドプロパティ（値の参照型：getterのみ）
```
【Laravel】ビューコンポーザとは

# はじめに

半年前くらいにビューコンポーザについて調べたつもりでしたが、見事に忘れました…。
私と共にビューコンポーザについて学んでいきましょう。

# 準備

ビューコンポーザを使用するには、アプリケーションのサービスプロバイダに登録する必要があります。
```config/app.php

'providers' => [
    // 他のサービスプロバイダ
    App\Providers\FoodServiceProvider::class,
],
```
# ビューコンポーザとは

**ビューをレンダするときに呼び出す**コールバックまたはクラスメソッド
（今回はクラスメソッドを呼び出すパターンのみ確認していきます。）

## ビューコンポーザを使うと何が嬉しいの？

**ビューを表示させる責務**と、**ビューに表示させるデータを扱う責務**を完全に分けることができます。

# 実際に書いてみる

## ビューコンポーザがない時
```FoodController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class FoodController extends Controller
{
	/**
     * ビュー表示
     * 表示させるビューにデータを渡す
     *
     * @return void
     */
	public function index() {
		return view('food.index')->with('food', 'oniku');
	}
}
```
Controllerのindexメソッド内でビュー表示・データ定義が同時に行われています。

## ビューコンポーザがある時
```FoodServiceProvider.php
<?php

namespace App\Providers;

use App\View\Composers\FoodComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class FoodServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * 全アプリケーションサービスの初期起動
     *
     * @return void
     */
    public function boot()
    {
        // クラスベースのコンポーザを使用する
        View::composer('food.index', FoodComposer::class);
    }
}
```
定義
↓
```FoodController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class FoodController extends Controller
{
	/**
     * ビュー表示"のみ"
     *
     * @param View $view
     * @return void
     */
	public function index() {
		return view('food.index');
	}
}
```
ビューを呼び出し
↓
```FoodComposer.php
<?php

namespace App\View\Composers;

use Illuminate\View\View;

class FoodComposer
{
    /**
     * データをビューと結合
     *
     * @param  View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('food', 'oniku');
    }
}
```
ビューをレンダーする前に、データをビューと結合
***
ビューコンポーザがない時と比べると必要なコード量が増えていますが、**責務がそれぞれ分かれています。**

# さいごに
今回扱ったコード量であれば、ビューコンポーザを使用すると、ファイル数も多くなってしまいますし、少し冗長かもしれません。

ですが、システムが大きくなればなるほど、Controllerに全てを詰め込んだりしてしまいがちです。
そういった状況を避ける為にも、それぞれのClassはもちろん、メソッドの責務を分ける必要があります。

そこで大活躍するのが、今回紹介したビューコンポーザです。
最初Controllerに全て詰め込んでたコードを、それぞれの責務に従って分けることができました🎉

# 参考URL🙏
https://readouble.com/laravel/9.x/ja/views.html

https://hara-chan.com/it/programming/laravel-view-viewcompoer/

https://qiita.com/hitochan/items/ec3ccfe0c051e8565f4a
Rustを動的ライブラリにリンクする方法

rustcはデフォルトで静的ライブラリにリンクしますがサイズが大きくなってしまいます。

動的ライブラリにリンクしてサイズを減らすには下記でコンパイルします。
```bash
rustc -C prefer-dynamic source.rs
```
iOSアプリ設計パターン入門(第2章:設定パターンを適用する前に)

# 概要
「責務」「パターン」「設計の原則」の3つを中心に設計プロセスについて説明しており、設計パターンをする前にSwiftにおけるプログラミングの作法を中心に説明している。

# まとめ
「責務」「パターン」「設計の原則」の3つを中心に設計プロセスについて説明してくれている。

# 学び
・責務とは、解決すべき問題の領域のことで、モジュールに責務をまとめて置いている。
・責務分離が適切に行われた状態は、モジュール内で責務がまとまっており高凝集といい、モジュール同士では責務が分かれている疎結合状態という。
・あるモジュールの責務は、他のモジュールとは分離されているはずでありその境界線を崩してしまうと、重大なエラーを発生させてしまう可能性もある。
・Apple公式によるUIViewControllerの役割は、以下の4点である。
①データの変化に応じてViewsの内容を更新②ユーザーインタラクションへの反応③レイアウトの管理④他のオブジェクトとの連携
・関数や変数を命名する際には、「ユーザーがそこ関数の挙動を行うと、どのような処理を動くのか」を考えて命名すると他のメンバーも関数や変数に関して理解しやすい。
・APIデザインガイドラインによれば、API(Application Programming Interface)が守るべき以下の3つの原則が挙げられている。
①使い道を明確に②短い名前よりも明確であることが重要③ドキュメントコメントを書く
・正しい名前に向き合うことで、論理の破綻、隠れている役割、所属のおかしさを浮き彫りにし設計の改善につながる。その命名の際は、データと振る舞いのセットで書くことが望ましい。
・アジャイル開発は、「俊敏な開発」という意味でiOSアプリ開発にの現場ニーズにマッチしている。
・『設計の原則』とは、責務の分割単位が適切かどうかを検証するための物差しで、有名な設計の原則にSOLID原則がある。SOLID原則の考えから、「硬さ」「もろさ」「移植性のなさ」「扱いにくさ」「不必要な繰り返し」「不必要な複雑さ」「不透明さ」を取り除くべきである。
・しかし原則は、使い過ぎると不必要な複雑さが出てくる。そのため、オーバーエンジニアリングを防ぐための『KISS(Keeo it simple small:簡潔に単純にしておけ)』や『YAGNI(You Are not Going to Need it:どうせ必要にならないよ)』という原則がある。
・設計とリファクタリングは表裏一体のものであり、リファクタリングをすることで、『設計の原則』や『KISS』、『YAGNI』に対応する。リファクタリングとは、作り直しという意味ではない。常に少しずつ改良を重ねていくことが必要である。
・テスト駆動開発のプラクティスでは、「開発者の実装を助けるためのテスト」のことをチェッキングと言い、品質補償のためのテスティングと区別されている。
・テストにしやすさは、以下の3つが挙げられている。
①入力と出力が明確で、副作用が少ない②複雑な内部状態に依存しない③疎結合。処理に影響のあるオブジェクトは抽象的なインターフェースとして表現されており、モックやスタブに差し替え可能
・最速のテストは、型付けである。
・パターンを使うのは、開発をしながらリファクタリングを少しずつしてモジュール同士の結びつきを弱めたりしていくことで、「コードがデザインパターンに回帰していく」と言われる。

# 感想
現在携わっているプロジェクトは、MVPへ移行していたりしていなかったりとカオスな場面もあるので、少しずつリファクタリングして『パターンに回帰している』時期なのかなと感じました。アーキテクチャを学ぶ前にリーダブルコードで命名規則やその周辺の原則の知識を学んでおいて本章の内容もすんなり頭に入ってきました！
SNSシェアボタン実装するのに時間を溶かした件

# 何が起きたか
SNSシェアボタンのOGP表示を実装するときに、ローカル環境だと上手くいかず時間を溶かしてしまった...

OGPとは、URLを入力したら↓のようにアイキャッチやサイト説明が自動的に表示される仕組みのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545959/7aafcb60-f5f7-b168-9e28-903218ff0564.png)

開発中のサイトのローカルのURLを入力しても表示されませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545959/bd7d5f49-8cfd-6ec8-ba07-5411903b82da.png)


# OGPの仕組み
OGPとはOpen（＝公開）Graph（＝図式）Protocol（＝約束事）の略らしいです。
HTMLのメタタグのに以下のように記載することで、SNSでシェアされた時の表示を設定できるようです。

```
head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<meta property="og:site_name" content="サイト名">
<meta property="og:title" content="ページタイトル">
<meta property="og:url" content="ページURL">
<meta property="og:type" content="ページタイプ">
<meta property="og:description" content="ページの説明">
<meta property="og:image" content="サムネイル用画像">
</head>
```

具体的な設定方法は以下の記事を参考にしてください。
https://hibi-update.org/other/ogp-setting/

# なぜローカルだと上手くいかなかったのか
OGPですが、各SNS側でいろんなサイトをスクレイピングすることで機能しているようです！
いくらメタタグ設定してもlocalhost:8000みたいなローカル環境上のサイトをスクレイピングできるわけないですね...
よく考えればすごく当たり前な話なのに、1時間以上時間を溶かしました（笑）

他にもシェアボタンを実装するのにハマり所があったので、別記事で書きたいと思います！
Databricksワークフローによるプロダクションのdbtプロジェクトのオーケストレーション

[Orchestrate Production dbt Projects on the Lakehouse With Databricks Workflows \- The Databricks Blog](https://www.databricks.com/blog/2022/10/03/orchestrate-production-dbt-projects-lakehouse-databricks-workflows.html)の翻訳です。

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

高信頼のレイクハウスオーケストレーターである[Databricksワークフロー](https://www.databricks.com/jp/product/workflows)がパブリックプレビューとしてdbtプロジェクトのサポートを発表できることを嬉しく思います。このプレビューによって、データチームはdbtプロジェクトと、ノートブックからMLモデルに至るレイクハウスのすべての機能をコーディネートすることができるようになります。この機能によって、オープンソースdbtユーザーによるSQLを用いたデータの変換、レイクハウスを通じたデータとMLのパイプラインのモニタリング、メンテナンスがシンプルなものとなります。

ジョブを実行する際、あなたのdbtプロジェクトはGit[リポジトリ](https://qiita.com/taka_yayoi/items/b89f199ff0d3a4c16140)から収集され、シングルノードのクラスターが構築され、dbt-coreとプロジェクトの依存関係がそこにインストールされます。dbtによって生成されたSQLはサーバレスSQLウェアハウスで実行され、容易なデバッグと優れたパフォーマンスを提供します。また、失敗したランの[リペア](https://qiita.com/taka_yayoi/items/1456e0d9a4ebe0291e41)や、dbtタスクが失敗した際にSlackやwebhookの宛先へのアラート送信、言うまでもないことですが、[Jobs API](https://docs.databricks.com/dev-tools/api/latest/jobs.html#section/Authentication)を通じたこの様なジョブの管理機能など堅牢かつオペレーションに関する機能も提供しています。
![](https://cms.databricks.com/sites/default/files/inline-images/db-365-dbt-workflows-img-1.jpg)

Databricksでdbtを使い始めるには、シンプルにDatabricksで`pip install dbt-databricks`を実行します。これによって、dbt Labsとその他のコントリビューターと開発したオープンソースの[dbt\-databricks package](https://www.databricks.com/blog/2021/12/06/deploying-dbt-on-databricks-just-got-even-simpler.html)がインストールされます。SQLウェアハウスで実行できるサンプルプロジェクトを使い始めるために[詳細ガイド](https://docs.databricks.com/integrations/prep/dbt.html)を参考にすることもできます。ソースコードをGitリポジトリにコミットすると、プロダクションでdbtモデルを実行するための新たなdbtタスクタイプを使用できる様になります([Azure](https://learn.microsoft.com/en-us/azure/databricks/workflows/jobs/how-to-use-dbt-in-workflows)、[AWS](https://docs.databricks.com/workflows/jobs/how-to-use-dbt-in-workflows.html)のドキュメントをご覧ください。GCPも間も無く提供されます)。この機能はサーバレスSQLウェアハウス([Azure](https://learn.microsoft.com/en-us/azure/databricks/sql/admin/serverless#requirements)、[AWS](https://docs.databricks.com/administration-guide/cloud-configurations/aws/regions.html))をサポートしているすべてのリージョンで利用できます。

Databricksワークフローにおけるdbtの機能について我々は興奮しています。更なるリージョンにこのプレビューを拡大し、更なる計算オプションを提供できることを楽しみにしています。[dbt Coalesce](https://coalesce.getdbt.com/)におけるDatabricksブースで皆さまとお話しできることを楽しみにしています。同時に、この新機能に対する皆様の[フィードバック](https://forms.gle/C5n1m5HgCpfoFDCy8)をお聞かせいただければと思います。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
c言語猛特訓5日目

頭が痛い。
短時間で詰め込みすぎたのとコーヒー飲みすぎたからと思う。
今日は特殊なフォーマットにしてくれる自動拡張機能を入れた。結局はフォーラムのギットハブの文章に大体乗ってるからググらないことも必要だなと思った。
問題も3問解いた。そして、時間を区切る大切さを知った。
一時間粘ってわからないならもう次の問題いくか解答を見るべき。進んでてわかる確証があるならいいけどね。締め切り効果大事。

関係ないけどおれはポテンシャルて言葉が嫌い。一年で人はプロになれる。人の3倍成長してやるという気概が必要。
iOSアプリ設計パターン入門(第1章:設計するということ)

# 概要
本書の本質的な部分を説明する前に、「iOSエンジニアとして設計するということ」の意義を簡単にまとめてくれている。昨今、iOSの開発環境が進化し、アプリ自身も成長している中で、膨大なコードをどのように書くのかを考えた上で開発しなければ、複雑にコードが絡み合い非効率になる。
そのため、そもそもなぜ設計を学ぶ必要があるかを説明してくれていた。

# まとめ
アプリの持つ複雑な問題を「関心の分離」によって小さな問題へと切り分けるといる、そのことを設計するという行為で、そのための武器がパターンである。

# 学び
・iOSアプリの開発事情「アプリでできることが増えた」「頻繁・継続的なリリース」「アプリの大規模化」「プロジェクトの長期化」「チーム開発での分業化」が挙げられる。
・関心の分離とは、アプリ開発における解決するべき問題（実装したいこと）をできる限り小さな単位で分けてコードを管理すること
・設計パターンは、複雑な問題をより簡単な問題群として切り分けるために活用できるもので、再現性のある問題に対する共通の解決策のこと
・パターンを知るメリットは、「問題を定型化して捉えられる」「解決策を客観的に比較できる」「メンバーの共通言語となる」
・アーキテクチャは、「アプリを動かす」という複雑な問題領域を大まかに複数の層へ切り分けるときに活用するもの

# 感想
リーダブルコード→Swift実践入門文法書→iOSアプリ設計パターン入門の順で読破してまして、アーキテクチャについて本格的に学ぼうと考えてます！
Rubyの勉強時には、MVCを学習していて今の会社に入るまではMVC以外のアーキテクチャは恥ずかしながら全く知らなかったです。
なので、Swiftで書くようになってからは会社でMVPを使った開発をしているので、より深くアーキテクチャを学べば実装も効率良くなるかな〜なんて考えてます(笑)
rsyncでのディレクトリ同期

EC2上のディレクトリ同期を行う必要があり、試行錯誤の結果、Rsyncでの方法が良さそうだったので、やり方をメモしておこうと思います。

Amazon Linux 2 on EC2の環境です。

# 必要パッケージのインストール
## Master側での作業

```common_lisp
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y rsyncd inotify-tools
```

## Slave側での作業

```common_lisp
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y xinetd rsyncd
```

# 通信するためのSSHキーの作成
## Master側でSSHキーを作成する
```common_lisp
sudo su
ssh-keygen -t rsa -N ""
```
## Master側で作成された`id_rsa.pub`の中身をコピーする
```common_lisp
vi /root/.ssh/id_rsa.pub
```

## Slave側にSSHキーをコピー（設置）する
vimでファイルをオープンし、さっきコピーした中身を貼り付ける
```common_lisp
vim ~/.ssh/id_rsa.pub
```
Permissionを変更する
```common_lisp
chmod 644 ~/.ssh/id_rsa.pub
```

# Master側に変更検知のスクリプトを設置する
スクリプトは、任意の場所に配置でOKです。私は、`/usr/local/bin`に配置してみました。
`.sh`は実行権限を付与する必要があります。

```watch.sh
#!/bin/bash
# required package: inotify-tools

WATCH_DIR=/var/www/html/xxx
SLAVE_IP=xxx.xxx.xxx.xxx(<= EC2のLocal IPでOK: 172.16.X.X)

events=(-e CREATE -e DELETE -e MODIFY -e MOVED_TO)
while inotifywait ${events[@]} $WATCH_DIR; do
    echo "Detect Changes"
    rsync -avogh --chown=nginx:nginx --delete --exclude=".*" $WATCH_DIR $SLAVE_IP::wp
done
```

# systemdにサービス登録する
```common_lisp
sudo vim /etc/systemd/system/watch.service
```
```watch.service
[Unit]
Description=Rsync service 
[Service]
ExecStart=/usr/local/bin/watch.sh
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target
```

`.service`ファイルができたら、サービス登録を行います。
```common_lisp
sudo systemctl enable watch
```

# Slave側でxinetdとrsyncを設定する
## xinetdの設定
```common_lisp
sudo vim /etc/xinetd.d/rsync
```

設定は以下の通り。
```common_lisp
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#   allows crc checksumming etc.
service rsync
{
    disable         = no
    flags           = IPv6
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/bin/rsync
    server_args     = --daemon
    log_on_failure  += USERID
}
```

## rsyncの設定
```common_lisp
sudo vim /etc/rsyncd.conf
```

設定は以下の通り。
```common_lisp
#--------------
# Global options
#--------------
uid           = root
gid           = root
log file      = /var/log/rsyncd.log
pid file      = /var/run/rsyncd.pid
hosts allow   = xxx.xxx.xxx.xx/32 (<= MasterのEC2インスタンスのLocal IP)
hosts deny    = *
dont compress = *.gz *.tgz *.zip *.pdf *.sit *.sitx *.lzh *.bz2 *.jpg *.gif *.png

[wp]
  comment      = rsync server
  path         = /var/www/html/xxx
  read only    = false
  exclude      = *.mp
  include      = *.mp30
```

## xinetdを再起動する
```common_lisp
sudo systemctl restart xineted
```

以上でMasterからSlaveへのディレクトリ同期ができるようになっているはずです。
【React】「Warning: Each child in a list should have a unique "key" prop.」のエラー

# 実現したいこと
配列のデータをテーブルで表示させる。

# バージョン等
React 17.0.0
Node.js 17.0.0


# 問題のコード

```typescript
import * as React from "react";

export default function Notification() {
  const noticeList = [
    { content: "お知らせ1", date: "2022/10/01" },
    { content: "お知らせ2", date: "2022/10/02" },
    { content: "お知らせ3", date: "2022/10/03" },
  ];
  return (
    <table>
      <thead>
        <tr>
          <th>日付</th>
          <th>おしらせ</th>
        </tr>
      </thead>
      <tbody>
        {noticeList.map((ele, index) => (
          <tr>
            <td>{ele.date}</td>
            <td>{ele.content}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}
```

のように記述していました。

# 発生したエラー(警告)

```
Warning: Each child in a list should have a unique "key" prop.
```

# 原因
繰り返し要素(テーブルタグやリストタグ)において、兄弟要素の中でそのアイテムが区別できるようにしてあげる必要があり、keyが指定されていないと、Reactがこのような警告を出します。
Reactチュートリアルにも解説がありますので、詳しくはこちらを参照してください。


https://ja.reactjs.org/tutorial/tutorial.html

# 対策
このように、繰り返し要素に、keyプロパティとして、配列のインデックスを与えれば警告は消えます。
```typescript
<tr key={index}>
```
NATゲートウェイを削除する

NATゲートウェイは有償のサービスです。
使用しない時は速やかに削除します。

AWSマネジメントコンソールにログインしてください。
VPCダッシュボードから[NATゲートウェイ]をクリックしてください。
![スクリーンショット 2022-10-08 6.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/9520fa27-0920-e961-ef70-1db08c26785d.png)

削除するNATゲートウェイをチェックし、[アクション]-[NATゲートウェイを削除]をクリックしてください。
![スクリーンショット 2022-10-08 6.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/976bbbe8-8a8f-5aba-e748-799e1c69a81c.png)

NATゲートウェイを削除ページが表示されます。[削除]を入力し、[削除]をクリックしてください。
![スクリーンショット 2022-10-08 6.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/a3275bc9-7883-383e-56ab-815e3a5ba262.png)

次に、NATゲートウェイに割り当てたElastic IPアドレスを削除します。
VPCダッシュボードの[Elastic IP]をクリックしてください。
![スクリーンショット 2022-10-08 6.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/bff1bf54-2801-cc42-b3ba-25bae4f4b2e6.png)

Elastic IPアドレスのページが表示されます。
削除したいElastic IPをチェックし、[アクション]-[Elastic IPアドレスの解放]をクリックしてください。
![スクリーンショット 2022-10-08 6.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/46afc490-b894-b25c-1e41-b939f7c000b2.png)

Elastic IPアドレスの解放ページが表示されます。
[解放]をクリックしてください。
![スクリーンショット 2022-10-08 6.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/322aa746-f0fd-47b2-5bb4-30fbe76bc4f2.png)

以上で、NATゲートウェイを削除できました。
Python,Ruby,PHP,Java,JavaScript,Perlのビット演算の比較 | プログラミング言語比較


<a href="https://qiita.com/yuki_kimoto/items/f9c2454e7f9130ddb003">Qiita > プログラミング言語の比較</a>

プログラミング言語Python,Ruby,PHP,Java,JavaScript,Perlのビット演算の比較

# Python

https://qiita.com/7shi/items/41d262ca11ea16d85abc

# Ruby

https://qiita.com/jkr_2255/items/8e29dce1999f3f6b69ad

# PHP

https://qiita.com/mpyw/items/ce626976ec4dc07dfec2

# Java

https://qiita.com/Ingward/items/43acda931c8a62c70d2f

# JavaScript

https://qiita.com/41semicolon/items/c1a16f220d4545410ddc

# Perl

https://perlzemi.com/blog/20080806121804.html
2022/10/8主にITとかセキュリティの記事

楽モバの通信障害、ソフトに不具合 - 緊急対応判断に時間要し長期化
https://www.security-next.com/140371

米政府、中国関与のサイバー攻撃者が悪用する脆弱性のリストを公開 - 国内製品も
https://www.security-next.com/140355

サイバー攻撃で公式アプリ会員のメアドなど流出 - 食肉小売チェーン
https://www.security-next.com/140288

本日付 日本経済新聞における当社システムに関する記載について 出光(10/5)
https://www.idemitsu.com/jp/whatsnew/2022/221005.html

2022年6月～8月「フィッシングトレンド」を発表 フィッシングキャンペーン前のリソース準備段階のフィッシングサイトURLも検出(10/5)
http://news1st.jp/archives/8775

フェラーリにサイバー攻撃？現時点では「証拠はない」ものの状況を精査。F1マシンには新サイバーセキュリティ企業のロゴ･･･(10/5)
https://www.topnews.jp/2022/10/05/news/f1/210302.html

Microsoft SQLサーバを標的とするマルウェア、285台に感染(10/6)
https://news.mynavi.jp/techplus/article/20221006-2473067/

第15回 日・ASEANサイバーセキュリティ政策会議の結果(10/6)
https://www.meti.go.jp/press/2022/10/20221006001/20221006001.html

YouTubeに“フィッシング画像”出現　「動画見たいならクリック」→カード情報詐取(10/6)
https://www.itmedia.co.jp/news/articles/2210/06/news140.html

Androidを標的としたスパイウェア「RatMilad」登場(10/6)
https://news.mynavi.jp/techplus/article/20221006-2473068/

『オーバーウォッチ2』サービス開始するもサーバーエラー多発―開始早々に「大規模なDDoS攻撃」を受ける(10/5)
https://www.gamespark.jp/article/2022/10/05/123123.html

JVNTA#96784241 VLAN対応ネットワーク機器において、L2保護機構がバイパスされる問題(10/6)
https://jvn.jp/ta/JVNTA96784241/index.html

iPhone14分解、部品コスト2割上昇　4ナノ半導体搭載(10/6)
https://www.nikkei.com/article/DGXZQOUC204XK0Q2A920C2000000/

Windows 11のファイルエクスプローラにタブ、プレビュー版で限定的に提供(10/6)
https://news.mynavi.jp/techplus/article/20221006-2472834/

データ活用で十分な成果を得ている企業は2.2%‐ガートナーが調査(10/6)
https://news.mynavi.jp/techplus/article/20221006-2473155/

詐欺の支払いに人気のある方法として仮想通貨ATMが浮上＝FBI(10/6)
https://jp.cointelegraph.com/news/crypto-atms-emerging-as-popular-method-for-crypto-scam-payments-fbi

SWIFT、CBDCとトークン化資産での実験に成功(10/6)
https://jp.cointelegraph.com/news/swift-says-it-has-reached-a-breakthrough-in-recent-cbdc-experiments

イラン中銀、デジタル通貨の実証実験開始(10/4)
https://forbesjapan.com/articles/detail/50831

仮想通貨取引所OKXがロシアでブラックリストに登録される(10/6)
https://nextmoney.jp/?p=53600

Amazon SESのドメイン認証トラブルシューティング（やや特殊な）(10/5)
https://ascii.jp/elem/000/004/107/4107690/?rss

中国サーバーにデータ保管、選挙関連システム企業トップが個人情報盗難で逮捕(10/6)
https://www.mashupreporter.com/lada-charged-election-software-ceo/

自治体システム標準化の大問題　企業の失敗と成功を教訓にせよ(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600007/092800123/

筆者を後悔させたMAXIMの実力　手ぶれやノイズをAIが驚異の補正(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100111/092800084/

画像ファイルに潜むマルウエア　セキュリティーソフトは検知できず(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100113/092800092/

カルト信者がつくったITサービス　安心して利用できるか(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100112/092800050/

「オンライン薬局」にアマゾン襲来　ドコモはどう立ち向かうか(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100110/093000090/

「民間宇宙システムにおけるサイバーセキュリティ対策ガイドライン Ver1.0」の内容とは(10/7)
https://xtech.nikkei.com/atcl/nxt/mag/rob/18/00008/00054/

業種や規模は関係ない、猛威振るうランサムウエア対策の勘どころ(10/7)
https://xtech.nikkei.com/atcl/nxt/info/18/00037/100700062/

セキュリティーが強化された最新版のRed Hat Enterprise Linux 9(10/7)
https://xtech.nikkei.com/atcl/nxt/column/18/02195/091300005/

自宅にVPN接続できる環境を構築、無料の「SoftEther VPN」を使う(10/7)
https://xtech.nikkei.com/atcl/nxt/column/18/02193/091200004/
WindowsでのパスとWSLでのパスが衝突するのを回避する方法

pyenvをWindows (pyenv-win) とWSLでそれぞれインストールした際に、WSL側で以下のようなエラーが発生し、パスが衝突したため、回避する方法を共有します
```sh
/mnt/c/Users/[ユーザー名]/.pyenv/pyenv-win/bin/pyenv: 3: cygpath: not found
```

## 原因
本来WSL側のパスを参照すべきところを、Windows側のパスを参照しようとしていることが原因です

`echo $PATH`に`/mnt/c/Users/[ユーザー名]/.pyenv/pyenv-win/bin`が含まれているのが確認できると思います
WSLはデフォルトでWindowsのパスを引き継ぐ設定となっており、Windowsでパスを設定すると自動でWSLにもパスが通ってしまいます

これはWSLからの実行を想定していないプログラムへのパスも通る可能性があり、その上、WSLからWindowsへのアクセスは非常に遅いためデフォルトで設定しているのは、とても気分が悪い設定です
そこで、その設定を解除する方法を紹介したいと思います

## WSLへWindowsのPATH設定が引き継がれるのを解除する
方法は以下のページにて紹介されています

[WSL2でWindowsのPATH設定が引き継がれるのを解除する](https://zenn.dev/o2z/articles/zenn-20210524-01) 
WSL側で以下のように`wsl.conf`を作成します
```sh
# WSL側
sudo vi /etc/wsl.conf
--
# WindowsのPATHを引き継がない設定を追記する
[interop]
appendWindowsPath = false
```

次にWindows側でWSLの再起動を行います
```sh
# Windows側
--
wsl.exe --shutdown
```

これにより、Windows側のパスがWSL側に引き継がれなくなったのが確認できると思います

## 個別にWindows側のパスを通したい場合
例えばVS CodeをWSLで使用する場合はWindows側のパスをWSLに通す必要がでてきます
その場合は.profileやシェルのrcファイルに
```sh
export PATH=$PATH:'/mnt/c/Users/[ユーザー名]/AppData/Local/Programs/Microsoft VS Code/bin'
```
を追記することでパスを通すことができます
DynamoでRevit Python Wrapperをつかう

# RPW(Revit Python Wrapper)とは
RevitAPIを簡単に扱えるようにしたパッケージです。DynamoのPythonスクリプトやRevit Python Shell (RPS)、pyRevitなどで使用できます。

https://revitpythonwrapper.readthedocs.io/en/latest/index.html

# インストール

### Dynamoパッケージのインストール

「__パッケージ__」→「__パッケージの検索__」から RevitPythonWrapperパッケージをインストールします。
最新版はバージョン1.7.2で、2017年から更新されていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/7396f2a1-5a46-ba83-21b4-21cd12b32745.png)
パッケージは下記のディレクトリにインストールされています。
```
C:\Users\<ユーザー名>\AppData\Roaming\Dynamo\Dynamo Revit\2.12\packages\RevitPythonWrapper
```


### パスを編集
下記ディレクトリの __rpw.zip__ を解凍し、
```
C:\Users\<ユーザー名>\AppData\Roaming\Dynamo\Dynamo Revit\2.12\packages\RevitPythonWrapper\extra\rpw.zip
```
VSCodeなどで __resources.py__ を開きます。
```
rpw/ui/forms/resources.py
```
40行目のパスを下記のように編集し、__rpw__ フォルダをZIP圧縮します。
```
C:\Program Files\Autodesk\Revit 2022\AddIns\DynamoForRevit\IronPython.Wpf.dll
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/a3ff057e-08d7-9e1b-e17b-93db5c257f4b.png)


### インポート

Pythonスクリプトのエンジンを __ironPython2__ に切り替えて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/09c701c2-0c05-f342-ea39-1f000f3745cd.png)

コードの先頭に下記を追記します。
```python
import sys
sys.path.append(r'C:\Users\<ユーザー名>\AppData\Roaming\Dynamo\Dynamo Revit\2.12\packages\RevitPythonWrapper\extra\rpw.zip')
```

__RPW__ をつかえるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/38df6b5f-53af-903b-cc8f-b37ae815ce65.png)