OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】特定の要素をリストの末尾に移動する関数

# 作るもの
与えられたリスト（array）内の特定の要素（toMove）をリストの末尾に移動する関数。

# 実装
```python:main.py
def moveElementToEnd(array, toMove):
    # 一時的なインデックスを初期化
    tmp = 0

    # リスト内の各要素に対してループ処理を開始
    for i in range(len(array)):
        # 現在の要素が移動させたい要素でない場合
        if array[i] != toMove:
            # 現在の要素と一時的な位置にある要素を入れ替え
            array[i], array[tmp] = array[tmp], array[i]
            # 一時的な位置を次の要素に更新
            tmp += 1

    # 要素の移動が終了したリストを返す
    return array


# テスト
if __name__ == "__main__":
    array = [2, 1, 2, 2, 2, 3, 4, 2]
    toMove = 2
    print(moveElementToEnd(array, toMove))
```

# 参考
https://www.algoexpert.io
Junit5 + Mockitoでstaticメソッドのモック化

junit5とMockitoを使用してstaticメソッドのモック化をしようとした際に、junit4やPowerMockitoを使用した情報やMockitoのバージョンによるエラーで詰まったので記録します。

### pom.xml
```pom.xml
    ...
    <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
		<mockito.version>4.4.0</mockito.version>
	</properties>
    ...
	<dependencies>
		<!-- mockito -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>${mockito.version}</version>
			<scope>test</scope>
		</dependency>
        <!-- mockStaticで使用 -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-inline</artifactId>
			<version>${mockito.version}</version>
		</dependency>

		<!-- junit5を含む -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
```
今回は`mockito-core`と`mockito-inline`のバージョンを`4.4.0`に揃えていますが、`4.5.*`や`4.6.*`にあげるとこちらにあるようなエラーが出てしまってうまくいきませんでした。
https://github.com/mockito/mockito/issues/2629

### モック対象メソッド
```java
public class Sample {
    public static boolean doSomething() {
        return false;
    }
}
```

### Test
```java
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import ...Sample;

public class SampleTest {
    @Test
    public void test() {
        try (MockedStatic<Sample> mock = Mockito.mockStatic(Sample.class)) {
            Mockito.when(mock.doSomething()).thenReturn(true);
            Assertions.assertEquals(true, mock.doSomething());
        }
    }
}
```

`MockedStatic`クラスはcloseする必要があるためtry-with-resource文にしています。
junit4のアノテーションやPowerMockitoが混在しているとエラーが起きたため、統一した書き方をする必要がありそうです。
AWSでデータ分析基盤構築をサクッと始めてみる（4.Athenaでアドホック分析編）

# シリーズ目次
<!-- タイトルとアンカー名を編集 -->
[AWSでデータ分析基盤構築をサクッと始めてみる（1.データカタログ作成編（行指向））](https://qiita.com/maechan55/items/d69ebcae324771f14a4e)
[AWSでデータ分析基盤構築をサクッと始めてみる（2.行指向から列指向に変換編）](https://qiita.com/maechan55/items/608c11382cecf6bdb0a4)
[AWSでデータ分析基盤構築をサクッと始めてみる（3.データカタログ作成編（列指向））](https://qiita.com/maechan55/items/33fa79330c76f1e59166)
[AWSでデータ分析基盤構築をサクッと始めてみる（4.Athenaでアドホック分析編）](https://qiita.com/maechan55/items/84cfb8d5347d71dc3f71)
[AWSでデータ分析基盤構築をサクッと始めてみる（5.Lambdaで分析自動化編）](https://qiita.com/maechan55/items/ed3f40128d684100e3ea)

<!-- 各チャプター -->
# 4. Athenaでアドホック分析編
本章では、S3に保管したデータカタログに対して、Athenaでクエリー実行できるか検証していきます。
（S3のデータをAthenaで直接見にいくってやつです！）
それでは、Athenaを使って、S3データに対してクエリーチャレンジしましょう！

（１）クエリー保管場所の作成
　　まずは、S3画面からクエリー実行結果を保管するフォルダを作成しておきます
　　ex.)　s3://test_bucket/query/

（２）クエリー結果保管場所の設定
　　Athena画面のクエリエディタから”設定”タグを開き、"クエリ結果の場所"に上記（１）のS3 URLを設定し、”保存"ボタン押下
![Athena3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/2c5d2424-f534-20ce-78b3-2200b8572a0d.png)

（３）クエリー実行
　　Athena画面のクエリエディタから”エディタ”タグを開き、対象とするデータベースを選択し、SQL文を記載しクエリーを実行
すると、クエリーの実行結果が右下に表示されます（ぅぅ、なんて便利なんだ！涙）
![Athena1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/fd4e924a-7283-6244-f6aa-5cb168a5c534.png)

Athenaでクエリー実行できましたか？

本章はこれで終わりです。どうもお疲れ様でした。
引き続き、最終章にチャレンジしてください！

[AWSでデータ分析基盤構築をサクッと始めてみる（5.Lambdaで分析自動化編）](https://qiita.com/maechan55/items/ed3f40128d684100e3ea)
# 参考文献
- AWS公式サイト
[Amazon Athena](https://aws.amazon.com/jp/athena/)
AWSでデータ分析基盤構築をサクッと始めてみる（3.データカタログ作成編（列指向））

# シリーズ目次
<!-- タイトルとアンカー名を編集 -->
[AWSでデータ分析基盤構築をサクッと始めてみる（1.データカタログ作成編（行指向））](https://qiita.com/maechan55/items/d69ebcae324771f14a4e)
[AWSでデータ分析基盤構築をサクッと始めてみる（2.行指向から列指向に変換編）](https://qiita.com/maechan55/items/608c11382cecf6bdb0a4)
[AWSでデータ分析基盤構築をサクッと始めてみる（3.データカタログ作成編（列指向））](https://qiita.com/maechan55/items/33fa79330c76f1e59166)
[AWSでデータ分析基盤構築をサクッと始めてみる（4.Athenaでアドホック分析編）](https://qiita.com/maechan55/items/84cfb8d5347d71dc3f71)
[AWSでデータ分析基盤構築をサクッと始めてみる（5.Lambdaで分析自動化編）](https://qiita.com/maechan55/items/ed3f40128d684100e3ea)


<!-- 各チャプター -->
# 3. データカタログ作成編（列指向）
本章では、列指向データ（parquet形式）ファイルからデータカタログを作成しようと思ってます。
それでは、Glueのcrawlerを使って、データカタログ作成にチャレンジしましょう！

（１）データカタログの作成（列指向）
　　ここでは、Glue crawlerを使ってparquet形式ファイルを取り込んだデータカタログを作成していきますので、Glue画面を開いてください。

　　①Crawlerを作成します
　　　左のメニューから"Crawlers"をクリックしてください。
![Glue_Crawler3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/da8cc915-8a7c-add0-ea15-701a6886d817.png)
　　②[Step1] データソース元を指定してください
　　　”Add a data source”ボタンを押してデータソースを追加
　　　”S3 path”に[2章](https://qiita.com/maechan55/items/608c11382cecf6bdb0a4)で変換作成して保管したparquetファイルのフォルダ（S3 URL）を指定
　　　　ex.)　s3://test_bucket/output/
![Glue_Crawler2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/4a01eedd-6b70-d978-e459-b2e997a8bb2c.png)
　　③[Step2] 次に進んで、IAMロールを作成してください
　　　”Create new IAM role”ボタンを押してIAMロールを追加。
　　④[Step3] 次に進んで、[1章](https://qiita.com/maechan55/items/d69ebcae324771f14a4e)で作成したデータベースを指定し、テーブル名をつけてください
　　　ex.)　テーブル名：output_table
　　　・Crawler scheduleは”On demand”を選択
　　⑤[Step4] 次に進んで、最後に入力内容を確認し、Crawlerを完成させます
　　　”Create crawler”ボタンを押す
　　　これで、クローラーの完成です！
　　⑥クローラーを実行します（[1章](https://qiita.com/maechan55/items/d69ebcae324771f14a4e)で経験済のためドキドキしない）
　　　作成したクローラーを画面の”Run crawler”ボタンを押す
　　　※ここで、クローラーによるデータカタログの作成が始まります
　　⑦データカタログの確認をします
　　　実行完了後、上記で作成したデータベースを開きデータカタログが作成されていることを確認

これで、列指向のデータカタログの完成です！

本章はこれで終わりです。どうもお疲れ様でした。
引き続き、次の章にチャレンジしてください！

[AWSでデータ分析基盤構築をサクッと始めてみる（4.Athenaでアドホック分析編）](https://qiita.com/maechan55/items/84cfb8d5347d71dc3f71)
# 参考文献
- AWS公式サイト
[AWS Glue](https://aws.amazon.com/jp/glue/)
AWSでデータ分析基盤構築をサクッと始めてみる（2.行指向から列指向に変換編）

# シリーズ目次
<!-- タイトルとアンカー名を編集 -->
[AWSでデータ分析基盤構築をサクッと始めてみる（1.データカタログ作成編（行指向））](https://qiita.com/maechan55/items/d69ebcae324771f14a4e)
[AWSでデータ分析基盤構築をサクッと始めてみる（2.行指向から列指向に変換編）](https://qiita.com/maechan55/items/608c11382cecf6bdb0a4)
[AWSでデータ分析基盤構築をサクッと始めてみる（3.データカタログ作成編（列指向））](https://qiita.com/maechan55/items/33fa79330c76f1e59166)
[AWSでデータ分析基盤構築をサクッと始めてみる（4.Athenaでアドホック分析編）](https://qiita.com/maechan55/items/84cfb8d5347d71dc3f71)
[AWSでデータ分析基盤構築をサクッと始めてみる（5.Lambdaで分析自動化編）](https://qiita.com/maechan55/items/ed3f40128d684100e3ea)


<!-- 各チャプター -->
# 2. 行指向から列指向に変換編
本章では、行指向（CSV形式）→列指向（parquet形式）にデータ変換しようと思ってます。
それでは、GlueのETLジョブ（Spark）を使って、parquet形式変換にチャレンジしましょう！

（１）ジョブの作成
　　GlueよりETL jobを選択し”Visual with a source and target”を選択していることを確認し作成（"Create"ボタン押下）
図）”ETL jobs”画面
![Glue_ETL_JOB5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/1cd45fcb-3ad2-21c8-b433-e0c7266dc308.png)
図）”Visual”タグの初期画面
![Glue_ETL_JOB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/95dfad5a-2c86-4328-e841-ad57d9242de6.png)
　　①Data Source（S3 bucket）の設定
　　　・Name：S3 bucket input　←名前はなんでもいいです
　　　・S3 Source type：
　　　　・S3locationの場合、S3に保管したファイルを入力
　　　　　　ex.)　s3://test_bucket/input/
　　　　・Data Catalog tableの場合、前章で作成したテーブルを選択
　　　・Data format：CSV
　　　・Delimiter：Comma(,)
　　　・Quote character：Disable　←適切なものを選択
図）”Data source properties - S3”画面
![Glue_ETL_JOB3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/52561952-67db-0595-8041-a835507e7d53.png)
　　②Transform ApplyMappingの設定
　　　※必要があれば、ここでスキーマのカラムのデータ型を変更
　　③Data Target（S3 bucket）の設定
　　　・Name：S3 bucket output　←名前はなんでもいいです
　　　・Format：Parquet
　　　・Compression Type：Uncompressed　←とりあえず圧縮しない
　　　・“S3 Target Location”にparquet形式後のファイルを保管する用のフォルダのS3 URLを指定
　　　　ex.)　s3://test_bucket/output/
図）”Data target properties - S3”画面
![Glue_ETL_JOB4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/e5d17b25-1978-0ce0-a224-2f822671b44d.png)
図4）設定完了後・・・すべてに完了チェックが入っている
![Glue_ETL_JOB2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102468/133e1357-8aac-75ee-eaf0-a8d7a5232630.png)
　　④あとは、”Job details”タグにて必要項目を埋めて”Save”ボタン押下
　　　・JobName：適当なジョブ名を指定
　　　・IAM Role：適切なロールを指定
　　　・Type：デフォルト（Spark）
　　　・Glue version：デフォルト（spark 3.3, Python 3）
　　　・Language：デフォルト（Python 3）
　　　※2023/08時点で最新のもの（デフォルト）

（２）ジョブの実行
　”Run”ボタン押下
　“Run”タブよりジョブが成功していることを確認したらS3に移動しparquet形式後のファイルを保管する用のフォルダにparquet形式のファイルが格納されていることを確認


本章はこれで終わりです。どうもお疲れ様でした。
引き続き、次の章にチャレンジしてください！

[AWSでデータ分析基盤構築をサクッと始めてみる（3.データカタログ作成編（列指向））](https://qiita.com/maechan55/items/33fa79330c76f1e59166)
# 参考文献
- AWS公式サイト
[AWS Glue](https://aws.amazon.com/jp/glue/)
SVGで矢印を作る

[海しる](https://www.msil.go.jp/)で色んな図形を描けるけれど、ユーザーデータの流れの矢印を描くことはできない。作図ができるJavaScriptライブラリの[d3.js](https://d3js.org)では地図を描けるみたいだけど、矢印は標準では図形として持っていないらしい。

d3.jsはグラフを描画するライブラリではなく、データを処理してどこに何を描画すべきか座標や幅で返す機能を持っている。HTMLのSVG要素にその座標を渡して、SVGで作図している。

https://qiita.com/daxanya1/items/734e65a7ca58bbe2a98c

上の記事は全然超初心者向けじゃないよ！というのはさておき、矢印を描くためには、d3.jsを直接学ぶより、SVGで遊んでからd3.jsをやるのがよさそう。

それに、d3.jsはv3からv4への更新で、名前空間が大きく変わって、それまでのコードがそのまま使えないらしい…。上のQiitaの記事も、下で参照している古旗本も、v3。しかも、今はv7。

https://qiita.com/cawpea/items/8d66e1a1df9e2d64fef6

ということで、d3.jsはちょっとおいといて、表題のとおりSVGで矢印を作ってみる。

SVGはhtmlのbodyにそのまま書く。

古旗一浩著「データビジュアライゼーションのためのD3.js徹底入門」によれば、SVGの図形要素のなかにはpathがある。path要素で指定できる属性はdで、ここにパスデータを入れる。d属性で指定できる命令と座標値のうち移動と直線描画に関する命令は以下のとおり。
| 命令の種類 |  命令  |  座標値 |
| ----      | ----   | ---- |
| 移動       |  M     |  絶対X座標, 絶対Y座標 |
| 移動       |  m     |  相対X座標, 相対Y座標 |
| 直線描画   |  L     |  絶対X座標, 絶対Y座標 |
| 直線描画   |  l     |  相対X座標, 相対Y座標 |

矢の元に絶対座標で最初に移動して、そこから、矢の先、三角形の順に相対座標で直線描画して一筆書きをするかなあ、と思っていたけれど、線を太くするとパスの最後が鋭くならないので、不採用。

不採用のコード
```
<svg>
  <path d="M180,70 l0,-50 l-20,20 l40,0 l-20,-20" style="fill:rgb(0, 0, 0);stroke:rgb(0, 0, 0);stroke-width:3px" />
</svg>
```
![Web キャプチャ_10-8-2023_214055_localhost.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2167014/451371e4-8f91-50d2-30a1-1fbdfa5909ec.jpeg)

矢印の三角形の三つの角全てが、直線描画の途中にあれば、たぶん全部鋭くなって、この問題は解決する。だから、パスを三角形の真ん中にも増やして、三つの角全てを回った後、ここをパスの終点にすることにした。
それと、流れの図っぽい形に少し調整。色もちょっと変えた。

```
<path d="M280,80 l0,-30 l15,0 l-15,-30 l-15,30 l15,0" style="fill:rgb(255, 85, 0);stroke:rgb(255, 85, 0);stroke-width:10px" />
```

![Web キャプチャ_10-8-2023_214911_localhost.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2167014/41d67eae-8f62-9155-c674-39e9cc1dffce.jpeg)

ちなみに、pathの頂点はこんな感じ。

![Web キャプチャ_10-8-2023_215019_localhost.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2167014/00e7e2f2-8861-beab-9255-2715c9b2a045.jpeg)

SVGでは図形の移動もできるらしい。path属性にtransform属性を指定する。transform属性には回転がある。ちなみに本では複数の図形要素をまとめたg要素に対してtransform属性を指定していたので、何に対しても使える。

|  機能  |  説明 |
| ----   | ---- |
|  rotate(d)またはrotate(d,cx,cy)  |  回転。dは角度、cxは中心X座標、cyは中心Y座標。  |

```
<path d="M90,320 l0,-30 l15,0 l-15,-30 l-15,30 l15,0" transform="rotate(45,90,290)" style="fill:rgb(255, 85, 0);stroke:rgb(255, 85, 0);stroke-width:10px" />
```

45度回転させてみる。

![Web キャプチャ_10-8-2023_215920_localhost.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2167014/42165166-a47e-d20c-a525-9f5b2de0b00e.jpeg)

いいものができそう！
iOS App Dev Tutorialsを読んで実際にやってみた。その９

## 前回の記事
[iOS App Dev Tutorialsを読んでみた。その8](https://qiita.com/shomiya181210/items/c27e2d5a77047ae2732f)
前回の記事を読んだ後に、この記事をご覧ください。
## 今回の範囲
#### [Making classes observable(クラスを観察可能にする)](https://developer.apple.com/tutorials/app-dev-training/making-classes-observable)
9回目は、アプリのユーザー インターフェイスの信頼できる情報源として参照型を定義する方法を学びます。
## 内容の要約
### 1.参照型の操作
　以前のチュートリアルでは、@State属性をプロパティに追加して、そのプロパティを真実の情報源として扱う方法を学びました。ただし、@Stateプロパティラッパーは、値型（構造体や列挙型など）にのみ適用できます。SwiftUIは、クラス型を真実の情報源として使うためのプロパティラッパーとして、ObservedObject、@StateObject、@EnvironmentObjectを提供しています。これらのラッパーをクラスで使うには、そのクラスを監視可能にする必要があります。
### 2.クラスを観測可能にする
　プロトコルを採用することでクラスを監視することができます。また変更時にUIを更新する必要があるプロパティを特定することができます。次に、各プロパティ宣言にObservableObject@Published属性を追加します。
次のスタータープロジェクト（ScrumTimer）には、毎日のスクラムミーティングの時間を管理するクラスが含まれています。

```ScrumTimer.swift
class ScrumTimer: ObservableObject {
   @Published var activeSpeaker = ""
   @Published var secondsElapsed = 0
   @Published var secondsRemaining = 0
   // ...
}
```
 次のチュートリアルのスタータープロジェクトには、毎日のスクラムミーティングの時間を管理するScrumTimerクラスが含まれています。このクラスは、スクラムセッション中に更新されるいくつかの公開プロパティを宣言します。

### 3.オブジェクトの変更を監視する
　SwiftUIでは、Observableオブジェクトを監視するために、プロパティ宣言に次の中の、ObservedObject、StateObject、Environment、のいずれかの属性を追加することができます。これらの属性を使用すると、ビュープロパティが新しいデータソースを作成します。App、Scene、またはView内で、@StateObject属性を使用して、Observableオブジェクトを作成します。システムはオブジェクトを初期化し、他のビューに渡すために保持します。
```swift
struct MeetingView: View {
   @StateObject var scrumTimer = ScrumTimer()
   // ...
}
```
　ObservedObjectプロパティラッパーを使用して、ビューがアプリ、シーン、ビューなどの親ソースからオブジェクトを受け取ったことを示します。この親構造はオブジェクトを作成し所有するので、子ビューはObservedObjectの初期値をしません。
```swift
struct ChildView: View {
   @ObservedObject var timer: ScrumTimer
   // ...
}
```
 observableオブジェクトのインスタンスをビューのイニシャライザーに渡します。
```swift
struct MeetingView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView(timer: scrumTimer)
      }
   }
   // ...
}
```
　複雑なビュー階層でObservableオブジェクトを共有するには、@EnvironmentObjectを使用します。そのため、オブジェクトを環境に配置して、イニシャライザ経由で渡す必要はありません。environmentObjectビュー修飾子は、ビューの環境にオブジェクトを配置します。
```swift
struct ParentView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView()
            .environmentObject(scrumTimer)
      }
   }
   // ...
}


struct ChildView: View {
    var body: some View {
        GrandchildView()
    }
}
```
　@EnvironmentObjectプロパティラッパーを使用して、ChildViewの子のオブジェクトにアクセスすることができます。
```swift
struct GrandchildView: View {
   @EnvironmentObject var timer: ScrumTimer
   // ...
}
```

　EnvironmentObjectを使用すると、中間ビューに不要な依存関係を持たずに済みます。ParentViewとGrandchildViewはScrumTimerに依存しますが、ChildViewは依存しません。そのため、このモジュールでは@EnvironmentObjectは使用されず、他のプロパティラッパーと同様に、"Managing model data in your app"を参照します。
### 4.まとめ
SwiftUIでスクラムディンガーのUIにデータを接続するために様々なツールを使用し、参照型の操作方法を学びました。次の記事では、SwiftUIアプリとビューのライフサイクルについて学び、MeetingTimerを使用して公開された会議のプロパティを監視するために@StateObjectをインスタンス化します。

#### [次回　iOS App Dev Tutorialsを読んで実際にやってみた。その10](https://qiita.com/shomiya181210/items/824de1975d627ecf478f)
vSphere検証環境を最短・無償で調達

vSphere検証環境を「最短・無償」で調達する方法を教えます。

#前置き

インフラエンジニアに共通する悩みとして、
技術習得のためには、実機に触る必要がありますが、
検証環境を揃えると高額になりがち。。。のようなことに陥りがちです。

個人利用無料なVirtual BOXやVMware Workstation（評価版）など
の仮想化ソフトを利用すればこのあたり解決できなくもないですが、
vSphereを物理マシン1台のうえできちんと構築するには、
nested環境を作る必要があり、ハードル・時間がかかります。

▼Virtual BOX
https://www.virtualbox.org/

▼VMware Workstation(評価版の利用想定。スナップショット利用不可な点に注意)
https://www.vmware.com/jp/products/workstation-pro.html

#本題

こういった手間を惜しむかたはVMware HoL(ハンズオンラボ)をおすすめします。
勿論ラボ内のテキストに沿って、ハンズオンを進めることもできます。

しかし、注目してもらいたいのが
「学習者に操作できる仮想環境」が提供される点です。

そのためテキストを無視して、分散スイッチに新しいポートグループを作成したりと
利用方法は無限大です。

下記のURLを貼っておくので、初学者の方や、プロジェクトで検証したいパラメータが
あるetc...といった方は是非参考にしてみてください。

▼VMware HoL
https://web.hol.vmware.com/landingPages/index.html?id=HOL-Japan
自己紹介

はじめまして。インフラエンジニア５年目のamaameです。
得意領域は、WindowsOS,VMwareです。

前々から技術のアウトプットについて興味はあったのですが
いまいち腰が上がらず、20代後半を過ぎてしまいました。
今週から夏季休暇に入る前に、まずは機会を作ることが大切と考えて
Qiitaに登録してみました。

あまりＰＶ数は意識せず、自身のアウトプットメモとして
活用していきたいと考えています。
もし何かしらの理由で読者の皆さんに参考になれば幸いです。

まだマークダウン方式に慣れてないので、記事が
見ずらいかもしれませんが、これから改善していきたいと思ってます。
【Python】re.sub関数を使ってX.0の0を消す方法 & str()使って文字列にした方が良い

# 概要
以前、`pandas`で発生する現象として「`X.0`になる」問題の解決方法を記事にしました。
[【Python】Pandasでデータを抽出する時、整数値が小数点になってしまう問題の解決方法3選](https://qiita.com/Ryo-0131/items/d9057aa63bb94dea76f1)

ただし、今回これとは別でPythonコード内でこういったことをゼロにしようということになりましたので、その実装方法も記載します。

# サンプルコード

```py
import re

def resubFloat(value):
    if value is not None:
        return re.sub(r'\.0$', '', str(value))
    else:
        return value

sample_value = 1.0
sample_number=resubFloat(sample_value)
print(sample_number) # 1
```

## コードの補足：
・`re`モジュール（正規表現操作）をインポート
・`re.sub(r'\.0$', '', str(value))`: 正規表現を使って文字列を操作。文字列内の`.0`で終わる部分を空文字列に置換します。`re.sub`関数は、基本的に以下のように使われます。

```py
re.sub(pattern, replacement, string)
```

・`pattern`(第一引数): 正規表現のパターン文字列
・`replacement`(第二引数): 置換後の文字列
・`string`(第三引数): 置換を行いたい対象の文字列

上記のように使って、与えられた正規表現のパターンにマッチする部分を、指定した置換文字列で置き換えます。
`replace()`は完全一致に使われますが、正規表現にマッチした文字列を置換したい場合には`re.sub()`が有効ですね。

## 処理対象は文字列を渡すこと
一点、注意点があります。
`re.sub`関数を以下のように使うとエラーになることがあります。

```py
        return re.sub(r'\.0$', '', value)
```
↓
```
Traceback (most recent call last):
  File "/Users/xxx/Projects/TEST/test-resubfloat.py", line 10, in <module>
    sample_number=resubFloat(sample_value)
  File "/Users/xxx/Projects/TEST/test-resubfloat.py", line 5, in resubFloat
    return re.sub(r'\.0$', '', value)
  File "/opt/homebrew/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/re.py", line 209, in sub
    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object
```

これは、`re.sub()`関数は、文字列を引数として受け取るため。
`value`が文字列でない可能性がある場合は、`str()`関数を使用して`value`を文字列に変換するのが良いでしょう。

## 公式ドキュメント
[6.2. re.sub() — 正規表現操作 — Python 3.8.0 ドキュメント](https://docs.python.org/ja/3/library/re.html#re.sub)
コード内の文字列を強調したい

# コード内の文字列を強調したい

Markdown で文章を作成中に 2 つの非常に類似した文字列をより区別しやすくするために、強調を利用することがあります。

例えば、次のようなものが挙げられます。

```markdown
te**s**t と te**x**t
```

te**s**t と te**x**t

通常の文章であれば上のように出来ますが、コード内にあった場合、このような強調は出来ません。

```markdown
`te**s**t` と `te**x**t`
```

`te**s**t` と `te**x**t`

本記事ではコード内で強調する方法を考えます。

## HTML を使おう

HTML では、`` `te**s**t` と `te**x**t` `` を次のように表記します。

```html
<code>te<strong>s</strong>t</code> と <code>te<strong>x</strong>t</code>
```

<code>te<strong>s</strong>t</code> と <code>te<strong>x</strong>t</code>

これであれば、コード内で強調することが出来ています。

この方法は少し面倒なので、`<strong>` は Markdown にしてしまいましょう。

```markdown
<code>te**s**t</code> と <code>te**x**t</code>
```

<code>te**s**t</code> と <code>te**x**t</code>

# まとめ

コード内で強調するには、コードを HTML の `<code>` タグを利用します。
この方法はもちろん、HTML を制限されている状況では実現できないことに注意してください。

ちなみに、コード全体であれば強調できます。

```markdown
**`test`** と **`text`**
```

**`test`** と **`text`**
【Ruby】三項演算子による条件分岐とは？

## 三項演算子とは。

条件式を評価してその結果に応じて2つの異なる値を返すことができる短縮された記法。

Railsにおいても、コントローラーやビューで三項演算子を使って動的な処理を行うことができる。

一般的な三項演算子の形式はこんな感じ。

？〜：の間に条件式がtrueだった場合の値を入れる。

```ruby
条件式 ? 条件が真の場合の値 : 条件が偽の場合の値
```

例えば

```ruby
age = 20
is_adult = age >= 18 ? true : false
```

上記の例では、
**`age`**の値が18以上の場合、**`is_adult`**には**`true`**が代入される。
そうでない場合は**`false`**が代入される。
#0013 プリンシプルオブプログラミングから　その①

## はじめに
- プリンシプルオブプログラミングを読み始めて、気になったポイントを記事にしてきます。
- 今回は導入部分から気になった部分をまとめます。

## "プログラミング"の変わらない前提
- コーディングは積み重ねであり、特効薬（silver bullet）は存在しない。進化の歴史と最新の技術を地道に学ぶことで、最善手が打てるようになる。
- 良いプログラマーは良い設計者であり、すなわち創造的な役割を果たす。
- プログラムは"変更されるもの"である。変更に強いものがいいプログラムである。
- 最高のコードとは、
    - 拡張性が高く
    - 余分がなく
    - 読みやすく
    - 理解しやすい
- コードは書く時間よりも、読まれる時間の方が長い。（レビュー、コンパイル）


#### 書籍
「[プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則](https://www.amazon.co.jp/%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B7%E3%83%97%E3%83%AB-%E3%82%AA%E3%83%96-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B03%E5%B9%B4%E7%9B%AE%E3%81%BE%E3%81%A7%E3%81%AB%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%81%9F%E3%81%84%E4%B8%80%E7%94%9F%E5%BD%B9%E7%AB%8B%E3%81%A4101%E3%81%AE%E5%8E%9F%E7%90%86%E5%8E%9F%E5%89%87-%E4%B8%8A%E7%94%B0-%E5%8B%B2/dp/4798046140)」
asdf で Ruby の最新バージョンをインストール（したいけど最新バージョンが見つからないときは）

ふつうは `asdf install ruby latest` でいけるはずですが、plugin の更新をしばらくしていないと最新バージョンを見つけられなかったりするみたいです。
```
naokid@myhost:~$ asdf list all ruby
～略～
3.1.4
3.2.0-dev
3.2.0-preview1  # あれれ、2023年08月現在は 3.2.2 までリリース済みのはずなのに・・・
artichoke-dev
jruby-dev
jruby-1.7.2
～略～
```

こんな時は `asdf plugin-update ruby` してやるとよいようです。
[公式の README](https://github.com/asdf-vm/asdf-ruby#use) にこんな記述がありました。

> Running `asdf plugin-update ruby` will update asdf-ruby and ensure the latest versions of ruby are available to install.

実際にやってみると「Already on 'master'」とか言われましたが、あらためて `asdf list all ruby` してみると確かに変化がありました。

```
naokid@myhost:~$ asdf plugin-update ruby
Updating ruby to master
From https://github.com/asdf-vm/asdf-ruby
   368792a..8cb9721  master     -> master
   368792a..8cb9721  master     -> origin/master
Already on 'master'
Your branch is up to date with 'origin/master'.
naokid@myhost:~$
naokid@myhost:~$ asdf list all ruby
～略～
3.1.4
3.2.0-dev
3.2.0-preview1
3.2.0-preview2
3.2.0-preview3
3.2.0-rc1
3.2.0
3.2.1
3.2.2
3.3.0-dev
3.3.0-preview1
artichoke-dev
jruby-dev
jruby-1.7.2
～略～
```

めでたしめでたし。
```
naokid@myhost:~$ asdf install ruby latest
To follow progress, use 'tail -f /tmp/ruby-build.20230810162020.15127.log' or pass --verbose
Downloading ruby-3.2.2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz
Installing ruby-3.2.2...
Installed ruby-3.2.2 to /home/naokid/.asdf/installs/ruby/3.2.2
```
仮想化技術

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/ebd1f125-c6e1-00b7-8de9-476595e725fb.png)
　コンピュータの仮想化は、一台の物理的なコンピュータ上で、複数台の仮想的なコンピュータを稼働させる技術です。ベースとなる物理的なコンピュータを実マシン（物理マシン、物理サーバ）と言います。PCの一挙一動の動作をソフトウェアで正確に模倣して、仮想的にコンピュータを作り上げます。実態は、ソフトウェアですから、何台でも仮想的なコンピュータを生成することができます。

　仮想マシンは、独立した一台のコンピュータとして振る舞います。従って、仮想マシンごとにOSをインストールして利用します。仮想マシンにインストロールするOSをゲストOSと呼びます。ある仮想マシンにはWindows、別の仮想マシンにはLinuxをインストールするといったことができます。WindowsコンピュータとLinuxコンピュータを同じ一台の物理コンピュータ上で、同時に動作させることができるのです。

　仮想化ソフトの代表的な方式には、ホストOS型とハイパバイザ型があります。ホストOS型は、仮想化ソフトを通常のアプリケーション（ワープロや表計算）と同じ扱いでPCなどにインストールして、仮想マシンを作る方法です。一方、ハイパバイザ型は、仮想化ソフト専用のOS（ハイパバイザOS）をインストールして、仮想マシンを作る方法です。仮想マシンサーバはハイパバイザ型で構築することが多いです。
Javaで「ディレクトリを作成する(Files.createDirectory)」の動作を確認してみた

# 概要
Javaで「ディレクトリを作成する(Files.createDirectory)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/file/index5.html

# 実装
以下のファイルを作成しました。
```JSample5_1.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;

class JSample5_1{
  public static void main(String[] args){
    Path p = Paths.get("/code/java/file/doc");

    try{
      Files.createDirectory(p);
    }catch(IOException e){
      System.out.println(e);
    }
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample5_1.java 
$ java JSample5_1 
$ java JSample5_1 
java.nio.file.FileAlreadyExistsException: /code/java/file/doc
```
以下のファイルを作成しました。
```JSample5_2.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;

class JSample5_2{
  public static void main(String[] args){
    Path p = Paths.get("/code/java/file/doc/manual/back");

    try{
      Files.createDirectories(p);
    }catch(IOException e){
      System.out.println(e);
    }
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample5_2.java 
$ java JSample5_2
$ java JSample5_2
```

# まとめ
何かの役に立てばと。
Broadcast Upload Extentions と アプリケーションのデータ共有について

# やりたかったこと
1. アプリとBroadcast Upload Extentions(BUE)間での変数の共有
1. BUEからアプリへブロードキャストの開始と終了を通知（フラグの監視）



## Broadcast Upload Extentions
開発しているアプリケーションに画面共有を提供する機能。開発しているアプリケーションとは別アプリで別プロセスで動作する。
Sandbox構造は開発しているアプリと別となる。

## 変数の共有
App Groups × UserDefaultsを用いて実装可能
アプリ間のデータ共有のため`UserDefaults(suiteName:<groupName>)`を指定する必要あり

⚠️`UserDefaults.standard`を用いればobserverを用いて、変数の監視が出来るが、App Groupsから`suiteName`を指定した場合以下の理由により変数の監視ができない。

>App Groupsを使用してUserDefaultsを共有している場合でも、KVO (Key-Value Observing) は同一プロセス内での変更を監視するための仕組みであり、別プロセスのアプリがUserDefaultsの値を変更した場合はKVOでイベントを検知することはできません。
App Groupsを使ってUserDefaultsを共有すると、複数のアプリが同じApp Group内のUserDefaultsにアクセスできるようになります。同じApp Group内の複数のアプリは同じUserDefaultsを見ることができるため、一方のアプリでUserDefaultsの値が変更された場合、他のアプリもその変更を見ることができますが、KVOを使って別プロセスのアプリに変更を通知することはできません。


KVO（key value observing） : swiftのキーバリューオブジェクトの監視機構
(参考記事）
https://developer.apple.com/documentation/swift/using-key-value-observing-in-swift

(参考記事)
https://tech.amefure.com/swift-widget-app-groups

## アプリ間通信
以下の記事を参考にしました
https://qiita.com/naru-jpn/items/4ba9b5189414f65b8fc8

### 結論
以下の方法で実装
- アプリとBUEの共有ディレクトリにjson形式でフラグを(isBroadcasting)を書き込み
- DispatchSourceFileSystemObjectを用いて共有ディレクトリの書き込みを監視
    - https://developer.apple.com/documentation/dispatch/dispatchsourcefilesystemobject
- ⬆️のオブジェクトにイベントハンドラーを登録
- combine, publisherを用いてアプリ側でファイルの変更を監視、検知

`cancellable`フィールドを定義しないと検知できない（変更を監視、検知するための変数をinit()でメモリ上に登録しておくイメージ）

```swift
  private var cancellable: AnyCancellable
  
   override init() {
    cancellable = BroadcastPreferences.shared.isBroadcasting
       .$value // @Published等状態変数の参照に'$'をつける
       .receive(on: DispatchQueue.main)// メインキューのイベントを発火させる
       .sink(){_ in // Subscribeの動作を記述する
            // 処理を記述
        }
     super.init()
  }
```

DispathcQueueについては以下を参照
https://tech.amefure.com/swift-dispatchqueue

Combineについては以下
https://dev.classmethod.jp/articles/swift-combine-framework-for-beginners/
SPAとAjaxについて

# はじめに
近年、Webアプリケーションの開発において``SPA（Single Page Application）``と``Ajax``の概念が広く使われています。

これらの技術は、**ユーザーエクスペリエンスの向上や効率的なデータ通信**を実現するためにとても重要です。

この記事では、SPAとAjaxの基本的な考え方と使い方について解説します。
# 従来の通信手段（同期通信）
まず同期通信の仕組みについて解説します。同期通信では、ユーザーがブラウザ（クライアント）からサーバーに対してリクエストを送ります。それを受け取ったサーバーが、HTMLをレスポンスしてブラウザ側でそのHTMLが表示されるという仕組みです。

もう少し噛み砕いて言うと、ボタンを押したときに、新しいページが読み込まれます。これはサーバーが新しいページをレスポンスとして返してきたということです。

そして、同期通信ではリクエストを送信してから**レスポンスが返ってくるまでの間は、他の処理を行うことはできず、レスポンスを待ち続ける必要があります。**

GoogleMapを例にします。例えば探したい場所を検索すると一瞬ページが真っ白になってから表示されます。ページが真っ白になってから表示されるまでの間は、ユーザーは何もすることはできません。
同期通信は、ページを1から作成して表示しているので、どうしても表示までの時間が取られてしまいます。

# 非同期通信
非同期通信とは、通信の送信と受信のタイミングをずらして他の処理を並行して行う事ができる通信手段です。

簡単に言うと、**リクエストを出してからレスポンスが返ってくるまでの間、ブラウザで他の処理を行うことができます。**

これもGoogleMapを例にすると、地図上でカーソルで移動したとしても、そのページを再読み込みすることなく移動先の地図が表示されると思います。カーソルで移動している間に地図の一部分が表示されなくても、それを待つ必要はなく操作を続けることができます。

ページの読み込みがなく、一部分だけ更新するというのは、Ajaxの仕組みで、非同期通信の本質とは少し違います。

## SPA（Single Page Application）とは?
``SPA（Single Page Application）``は、最初のリクエストでサーバーからHTMLをレスポンスしたあとはページ遷移を伴わずに、ページの一部分だけを更新していくというものです。つまり、SPAは単一ページで構成されています。このようなデータのやり取りを行うための通信が``Ajax``と呼ばれるものです。Ajaxでは、サーバーからのレスポンスはJSON形式で送られてきます。ブラウザは受け取ったJSONを使い、JavaScriptによってページの一部分を更新しています。

### SPAの特徴：
* SPAはページ遷移がないため、ユーザーが操作した際の反応がスムーズです。コンテンツの切り替えやデータのロードが非同期で行われるため、画面のフリッカリングが少なく、**快適なユーザーエクスペリエンス**を提供します。
* 最初に1つのHTMLページをロードした後は、必要なデータだけを非同期で取得するため、ページ全体を再読み込みする必要がありません。これにより、**ページのロード速度が向上**します。
* SPAは1つのHTMLページを使用するため、ブラウザのキャッシュ効率が高まります。変更がある場合でも、必要なデータのみを更新するため、**効率的なキャッシュ制御**が可能です。

## Ajax（Asynchronous JavaScript and XML）とは？
Ajaxは、``非同期でデータを送受信するための技術``です。JavaScriptを使用して、ユーザーが操作した際にサーバーと通信し、必要なデータを取得したり送信したりすることができます。これにより、ユーザーの操作に対してすぐに応答することが可能となります。

### Ajaxの特徴：
* ページの再読み込みをせずにデータ通信を行う
* ユーザーインタラクションをリアルタイムに処理
* APIとの連携によるデータの取得・更新

## SPAとAjaxの組み合わせ
上記でも解説しましたがSPAでは、ページ遷移を行わずにユーザーインタラクションを提供するため、Ajaxを使用して非同期通信を行います。これにより、ユーザーエクスペリエンスの向上と効率的なデータ通信を実現します。

## SPAとAjaxの開発フロー
* ユーザーの操作に応じてAjaxリクエストを発行
* サーバーからJSONやXMLなどのデータを取得
* 取得したデータを使ってページの特定部分を更新
* ユーザーにリアルタイムな情報を提供

## まとめ
SPAとAjaxは、現代のWebアプリケーション開発において欠かせない技術です。SPAはユーザーエクスペリエンスの向上を、Ajaxはリアルタイムなデータ通信を可能にします。これらの技術を使いこなすことで、魅力的で効率的なWebアプリケーションを開発することができます。
【NVIDIA DLI Teaching Kits】Lecture 2 まとめ

# はじめに
本記事は、NVIDIA DLI Teaching Kits Lecture 2についてのまとめになります。
気力が続く限り、今後も3-24章までのLabs、Lecture、Quizを取り上げていきます。
どうぞよろしくお願いします。

前章: [Lecture1](https://qiita.com/candy_wataame/items/c004439f251d4e958797)

# 目次
- Lecture
- Labs
- Quiz 

# Lecture 
### 2.1 データの収集
`データの集め方とコスト`
ダウンロード -> <font color="green">低</font>
API (Application Programming Interface) -> <font color="blue">中</font>
スクレーピング、クローリング -> <font color="red">高い</font>

`ダウンロードできるデータ`
・data dump (wikipedia)、csv、xml (stack overflowなど)

`APIを経由してデータを集める`
・Google Data API、Twitter(X)、data.gov

`APIを経由して利用できないデータ`
・Amazon、ESPN、eBay

### 2.2 データスクレイピング
`いかにしてデータをスクレイピングするか(Google Play)`
・Shazam
・同様アプリの相関図を作る、そのためにスクレイピング
・データを抽出するためにブラウザの開発ツールを使う 
```
開発ツールは　option + command + I で開ける
```
### 2.3 代表的なスクレイピングライブラリ
[Selenium](https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a) 多言語に対応しているらしい
> 参考記事: 10分で理解するSelenium 

[Beautiful Soup](https://qiita.com/Chanmoro/items/db51658b073acddea4ac) Pythonのライブラリー
> 参考記事: 10分で理解するBeautifulSoup

[Scrapy](https://qiita.com/Chanmoro/items/f4df85eb73b18d902739) Pythonのライブラリー
> 参考記事: 10分で理解するScrapy

[JSoup](https://qiita.com/opengl-8080/items/d4864bbc335d1e99a2d7) Javaのライブラリー、HTML解析
> 参考記事: Jsoup使い方メモ

### 2.4 データアノテーションとデータの質

`データアノテーション (ラベルの作成)`
データアノテーションとは、収集したデータに様々な用途に応じたラベルを付けること

 
`データアノテーションの例`
・画像処理 (画像分類、物体検出、セマンティックセグメンテーション)
・LabelMe 画像へのアノテーション付与のためのグラフィカルなツール、Pythonで書かれている
・Computer Vision Annotation Tool (CVAT) 
・Einstein Vision Object Detection 
・自然言語処理 (NLP) > 感情分析(センチメント分析)、固有表現抽出 (NER)


`データアノテーションの品質管理`

**データの質 Data Quality（DQ)**

データの質とは、情報の定性的あるいは定量的な状態のこと 
 > 品質特性: 関連性、正確性、適時性、比較可能性、完全性 

**なぜデータの質について注意しなければならないのか** 
>データの質(高） 競争上の優位性を担保する
データの質(低)　顧客満足度の低下、組織への信頼の低下

**質の高いデータの得方**
> 予防、検出、修復、リソースの割り当て

### 2.5 SQLite: 簡単で効率的なストレージ
`データの格納方法` 
・もっとも簡単なのはどれか
・csv（comma seperated files or values) ではないらしい

`SQLite` 
・世界で**一番有名**でユーザの多い組み込みデータベース
・自己完結型、スキーマとデータが一つのファイルに含まれる
・サーバーレス、ローカルにある
・ゼロ・コンフィギュレーション、セットアップ必要なし

https://qiita.com/ko1nksm/items/87d27a287e1b6005d11c

### 2.6 SQLリフレッシャー

基本的なSQLの文法の説明なので、各自ググろう。

https://zenn.dev/umi_mori/books/331c0c9ef9e5f0/viewer/e24f5b

```
とりあえず覚えておけばいい構文

SELECT > FROM > WHERE > HAVING / BETWEEN / ORDER BY ...
INSERT > INTO ...
UPDATE ...
DELETE ...
```

### 2.7 欠けているインデックスに注意 
SQLiteは簡単に数GB程度のデータ量になってしまう。
動作が遅いときは、適切なインデックスを作成したかを確認する必要がある。

**B木インデックス(データ構造)** 

https://qiita.com/kiyodori/items/f66a545a47dc59dd8839 

# Labs 

Labsで登場する<INS>RAPIDS_AI</INS>エコシステムの**BlazingSQL**というモジュールですが、
バージョン21.12にてDask-SQLに替わりDeprecated(廃止)されたようです。

StackOverflowにおいて、以下のQAを見つけましたので共有いたします。
なお、バージョン21.11以前のものについてはまだ動作の確認ができていないため、
分かり次第追記いたします。

https://stackoverflow.com/questions/70759825/modulenotfounderror-no-module-named-blazingsql-error-after-installing-rapids

# Quiz 

Q1) Ans: ABC
・2.4 データのアノテーションとデータの質 p.9 を参照

Q2) Ans: 全て
・2.4 p.12 を参照

Q3) Ans: 全て
・2.4 p.14 を参照

Q4) Ans: A
・2.1 データの収集を参照

Q5) Ans: C
・2.7 欠けているインデックスに注意、B木(B-tree)データ構造

Q6) Ans: D
・2.7 p.4を参照、オーダ記法を用いている。

Q7) Ans: A 

Q8) Ans: B
・SQLiteの上限は140TB(テラバイト）らしい。


**参考文献**

https://www.momoyama-usagi.com/entry/calc-order

https://www.sqlite.org/limits.html
RailsでのGemを使用したログイン機能の実装方法

この記事では、Ruby on Railsで人気のあるGem、`devise`を用いてログイン機能を実装する方法を備忘録としてまとめていきます。

## 1. 前提条件
- Ruby on Railsがインストールされていること
- 新規のRailsアプリケーションが作成されていること

## 2. Devise Gemのインストール
まずは、Gemfileに以下の行を追加します。

```ruby
gem 'devise'
```

その後、ターミナルで以下のコマンドを実行して、gemをインストールします。

```
$ bundle install
```

## 3. Deviseのセットアップ

インストールしたら、Deviseの初期設定を行います。

```
$ rails generate devise:install
```

これにより、いくつかの初期設定ファイルや、インストール時の指示が表示されます。これに従って設定を進めていきましょう。

## 4. Userモデルの作成

次に、ユーザーモデルを作成します。

```
$ rails generate devise User
```

このコマンドにより、Userモデルや関連ファイル、マイグレーションファイルなどが生成されます。

## 5. マイグレーションの実行

```
$ rails db:migrate
```

このコマンドで、usersテーブルがデータベースに作成されます。

## 6. ログイン、ログアウト、サインアップのViewを作成

Deviseはデフォルトでviewを提供していますが、カスタマイズしたい場合は以下のコマンドでアプリケーションにコピーしてカスタマイズすることができます。

```
$ rails generate devise:views
```

## 7. ルーティングの設定

Deviseのインストールにより、`config/routes.rb`には以下のルートが追加されます。

```ruby
devise_for :users
```

これにより、ログイン、ログアウト、サインアップ、パスワードの再設定などのルートが自動で設定されます。

## 8. 認証の追加

任意のコントローラに認証を追加するには、そのコントローラ内で以下のように記述します。

```ruby
before_action :authenticate_user!
```

これにより、そのコントローラのアクションを実行する前にユーザーのログインを要求するようになります。

## 9. カラムの追加

デフォルトで生成されるUserモデルには、emailとpasswordのカラムしかありませんが、例えば名前やユーザ名を追加したい場合は以下のようにします。

1. マイグレーションを生成:

```
$ rails generate migration AddNameToUsers name:string
```

2. マイグレーションを実行:

```
$ rails db:migrate
```

## 10. 認証以外の機能: パスワードのリセット、確認メールの送信

`devise`は、認証以外にも多くのユーザー関連の機能を提供しています。これには、パスワードのリセット、アカウントの確認メールの送信、アカウントのロックなどがあります。

これらの機能を有効にするには、`config/initializers/devise.rb`の設定を変更するだけで十分です。ただし、メールの送信機能を使用する場合は、メールの設定が必要になります。

## 11. 認証のカスタマイズ: バリデーション、コールバック

`devise`で生成されるモデルは、通常のActiveRecordモデルと同様にカスタマイズすることができます。バリデーションを追加したり、コールバックを使用して特定のアクションをトリガーすることができます。

```ruby: 例
class User < ApplicationRecord
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable

  validates :name, presence: true, length: { maximum: 50 }
end
```

## 12. Viewのカスタマイズ: スタイリング

`devise`が提供するViewは、BootstrapやTailwind CSSなどのフレームワークを使用してスタイリングすることができます。これにより、アプリケーションの全体的なデザインに合わせて、ログインやサインアップのページをカスタマイズすることができます。

## まとめ

`devise`は、Railsアプリケーションにログイン機能を追加するための非常に強力なツールですが、その機能は上記に示した基本的なものだけではありません。公式のドキュメントを読みながら、アプリケーションのニーズに合わせてカスタマイズを進めてみてください。

## 参考文献
https://github.com/heartcombo/devise
[小ネタ] CodeBuild (AmazonLinux2023 ベース image) で日本語ファイルを扱えるようにする

# 経緯
今まで使っていた CodeBuild の AmazonLinux2 ベースイメージ `aws/codebuild/amazonlinux2-x86_64-standard:3.0` が、いつのまにか廃止になっていました。

そこで、思い切って AmazonLinux2023 ベースの `aws/codebuild/amazonlinux2-x86_64-standard:5.0` へ更新したところ、日本語ファイル名を扱うタイミングで文字化けしてビルドが通らなくなってしまったので、その対応記録です。

:::note info
CodeBuild 廃止イメージ
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-available.html#deprecated-images
:::


# 対応方法
公式ドキュメントのトラブルシューティングを見ると、そのまんまの内容があります。
`pre_build` フェーズでロケールを設定するだけらしい。

https://docs.aws.amazon.com/codebuild/latest/userguide/troubleshooting.html#troubleshooting-utf-8

```yml:buildspec.yml
pre_build:
  commands:
    - export LC_ALL="en_US.utf8"
```

・・・が、そもそもこんなロケールは最初からインストールされていないので、エラーになります。

```
/codebuild/output/tmp/script.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.utf8): No such file or directory
```

AmazonLinux2023 は Fedora ベースらしいので、Fedora のロケール設定方法を探して `pre_build` フェーズに設定したところ、解決しました。

```yml:buildspec.yml
  pre_build:
    commands:
      - dnf -y install glibc-langpack-ja
      - export LANG=ja_JP.utf8 LC_ALL=ja_JP.utf8 LANGUAGE=ja_JP:ja
```
ABC306 - D - Poisonous Full-Course 自己解法

# 問題

https://atcoder.jp/contests/abc306/tasks/abc306_d

# 考察
料理店から生きて退店する条件の下、食べた料理の美味しさの総和として考えられる最大値を求めてください問題です。
- 高橋くんは最初、お腹を壊していない
- 高橋くんは最初、食べた料理の美味しさの総和は$0$(何も食べてないため)

以上の2点を出発点として動的計画法で解くことができないか考えていきます。
そのために下記の動的計画法用の変数$dp_{i,j}$を用意してみます。
- $dp_{i, j}$: 高橋くんに、$i$番目の料理まで提供が終わった。そして高橋くんの現在のお腹の状態が$j$である。この状況下で考えられる美味しさの総和の最大値。($j=0$:お腹を壊していない。$j=1$:お腹を壊している。)

もし、上記の変数$dp_{i,j}$を正しく求めることができたなら、最終的な答えは「$dp_{N, 0}$」と「$dp_{N, 1}$」のうちのより大きい方になります。
では出発点から変数$dp_{i,j}$の中身を順番に求める方法を考えます。

-----
まずの出発点についてですが、上記の通り「最初、お腹を壊していない」「最初、食べた料理の美味しさの総和は$0$」です。つまり出発点は、
$$dp_{0, 0} = 0$$
であるといえます。

-----
次に、1番目料理から$dp_{i, j}$を順に求める方法を考えていきます。そのために、$dp_{i-1, 0}$と$dp_{i-1, 1}$の値が既知でならば$dp_{i, 0}$と$dp_{i, 1}$を求めることができるか考えてみます。
高橋くんは提供された料理を「食べる」「下げてもらう」という選択肢があります。それぞれの場合を考えていきましょう。
### 食べる場合
$i$番目の料理が「解毒剤入り」か「毒入り」かで分けて考えていきます。

料理が「解毒剤入り」だった場合、お腹を壊していなければお腹を壊していないまま。お腹を壊していればお腹を壊していない状態になります。つまり、下記のことがいえます。

- 「$dp_{i, 0}$」が以下の値になる可能性がある。
    - $dp_{i-1, 0} + Y_i$(お腹を壊していない状態で料理を食べたケース)
    - $dp_{i-1, 1} + Y_i$(お腹を壊している状態で料理を食べたケース)

次に、料理が「毒入り」だった場合、お腹を壊していなければお腹を壊す。お腹を壊していると死んでしまいます。生きて退店することが条件のため、お腹を壊している状態では「食べる」という選択はそもそもできません。そのため、お腹を壊していない状態で食べたときのみを考えればいいです。つまり下記のことがいえます。
- 「$dp_{i, 1}$」が以下の値になる可能性がある。
    - $dp_{i-1, 0} + Y_i$(お腹を壊していない状態で料理を食べたケース)

### 下げてもらう場合
料理を下げてもらう場合は、お腹の状態も美味しさの総和にも変化はありません。つまり、下記のことがいえます。
- 「$dp_{i, 0}$」が以下の値になる可能性がある。
    - $dp_{i-1, 0}$(お腹を壊していない状態を維持)
- 「$dp_{i, 1}$」が以下の値になる可能性がある。
    - $dp_{i-1, 1}$(お腹を壊している状態を維持)

以上のことから、$dp_{i, 0}$と$dp_{i, 1}$について、可能性がある値の中から最大のものに更新をすることで、$dp_{i, 0}$と$dp_{i, 1}$を求めることができます。

このことから、出発点である$dp_{0, 0} = 0$から順番に計算することで、「$dp_{N, 0}$」と「$dp_{N, 1}$」まで求めることができます。

これで、計算量$O(N)$と十分に間に合う時間で求めることができます。

# 提出コード(コンテスト後)

https://atcoder.jp/contests/abc306/submissions/44432071

ご不明点などがあれば教えていただけると幸いです。
List型をphotonView.RPCでやりとり出来ない時の迂回案

# そもそもなぜList型をRPCで使えないのか
PhotonのRPC機能を用いてList型を渡せないのは **Photonがサポートしていない型** だからです。
詳しいことは[公式のリファレンス](https://doc.photonengine.com/ja-jp/pun/current/reference/serialization-in-photon# "Photonでの直列化 | Photon Engine")を見れば書いてありますが、基本的な型と、その配列にしか対応していません。そのため、そのままList型を引数とするメソッドをRPC化して実行すると以下のエラーが出ます。
```c#:int型のListの場合
[PunRPC]
void ListRPC(List<int> intlist) 
{
    return;
}

private void Start()
{
    List<int> Intlist = new List<int>();
    photonView.PRC(nameof(ListRPC), RpcTarget.All, Intlist);
///Exception: Write failed. Custom type not found: System.Collections.Generic.List`1[System.Int32]
}
```
エラーの内容としてはSystem.Int32のカスタムタイプは見つからない、といっています。

このエラーの解決方法はざっくりと以下の2つです。
1. List型を使わなくていいようにメソッドを改変する。
1. カスタムタイプにList型を登録する。

# 1. List型を使わなくていいようにメソッドを改変する。
そもそもList型は他の型に比べると使用するバイト数が大きいため、なるべくListのままで通信するのは避けるのが無難と思います。(わざわざカスタムタイプを分けてるのはPhotonが推奨していない？)
そのため、コード上別の方法が使える場合、少し工夫してList型以外で受け渡しできると軽量化にもつながると思います。

一つ目の方法としては無理矢理にでも配列にしてしまう、という方法です。かなり乱暴ではありますが、割とどんなときでも使える万能策です。
```c#:配列で解決
[PunRPC]
void ListRPC(int[] intarray) 
{
    return;
}

private void Start()
{
    List<int> intList = new List<int>();
    int[] intArray = new int[intList.Count];
    for(int i = 0; i < intArray.Length; i++)
    {
        intArray[i] = intList[i];
    }
    photonView.PRC(nameof(ListRPC), RpcTarget.All, IntArray);
}
```

二つ目は、一つずつデータを渡す方法です。こちらはListの長さが短い時に使える方法です。
こちらはあまりおすすめできませんが、特定の条件次第では使えるかもしれないので一応記載しておきます。
```c#:一つずつ渡す
List<int> IntList = new List<int>();

[PunRPC]
void ListRPC(int num) 
{
    intList.Add(num)
    return;
}

private void Start()
{
    List<int> intList = new List<int>();
    for(int i = 0; i < intList.Count; i++)
    {
        photonView.PRC(nameof(ListRPC), RpcTarget.All, intList[i]);
    }
}
```

# 2. カスタムタイプにList型を登録する。
こちらはリファレンスを参照していただいた方がいいと思うのでこの記事では省略させていただきます。

>[Photonでの直列化 | Photon Engine](https://doc.photonengine.com/ja-jp/pun/current/reference/serialization-in-photon# "Photonでの直列化 | Photon Engine")

こちらのサイトもわかりやすいので紹介しておきます。

>[PUN2（Photon Unity Networking 2）で始めるオンラインゲーム開発入門](https://zenn.dev/o8que/books/bdcb9af27bdd7d/viewer/1a456e#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%BF%E3%82%A4%E3%83%97 "PUN2（Photon Unity Networking 2）で始めるオンラインゲーム開発入門")
ソフトウェアのTestability（試験性）とは

:::note warn
参考文献が少ないので、内容の正確性に疑問がある部分もあります。
あくまで現時点で得た情報や理解を整理した記事です。
:::

# この記事について

ソフトウェア品質に含まれるTestability（試験性）について、自分なりに整理したことのまとめです。

- Testability（試験性）とは
- Testabilityの特性
- Testabilityが低い状態とは
- Testabilityを向上させるには

# Testability（試験性）とは

まずソフトウェアの品質について、ISO/IEC25010 SQuaREの”ソフトウェアの製品品質モデル”にて次のように定義されています。

- 機能適合性：機能完全性、機能正確性、機能適切性
- 性能効率性：時間効率性、資源効率性、容量満足性
- 互換性：共存性、相互運用性
- ユーザビリティ：適切度認識性、習得性、運用操作性、ユーザーエラー防止性、ユーザインタフェース快美性、アクセシビリティ
- 信頼性：成熟性、可用性、障害許容性、回復性
- セキュリティ：機密性、インテグリティ、否認防止性、責任追跡性、真正性
- 移植性：適応性、設置性、置換性
- **保守性**：モジュール性、再利用性、解析性、修正性、**試験性**

この８つの品質特性のうちの**保守性**を構成する品質副特性の中に**試験性**（Testability）があります。
（試験性の他にはテスト容易性という訳も見かけます）

# Testabilityの７つの特性

Testabilityの定義として、７つの特性があるようです。

- 実行円滑性（Operability）
- 観測容易性（Observability）
- 制御容易性（Controllability）
- 分解容易性（Decomposability）
- 単純性（Simplicity）
- 安定性（Stability）
- 理解容易性（Understandability）

これらの特性はJames Bach著『ソフトウェアテスト293の法則』やRoger S. Pressman著『実践ソフトウェアエンジニアリング』 で挙げられているようです。書籍が手元に無いので末尾に記載した記事を参考にさせていただきました。

## 1. 実行円滑性（Operability）

ソフトウェアが効率的に実行され、必要な操作や監視がスムーズに行えるかどうかを表す特性です。

例えば次のような状況は、実行円滑性が低くそうです。

- テストの準備や実行にコスト（時間、費用）がかかる
- 安全に実行できる環境が無い

## 2. 観測容易性（Observability）

システムの内部状態がテスト中にどれだけ容易に観察できるかを表す特性です。

例えば次のような状況は、観測容易性が低くそうです。

- 外部から状態の観測ができない（結果を返さない、privateになっている）
- 影響が観測範囲外に発生する（外部サービス、メール送信など）
- デバック情報が不足していて、エラーやテスト失敗の原因を追跡できない

## 3. 制御容易性（Controllability）

テスターがシステムの異なる部分をどれだけ容易に制御できるか、特定の条件や状態を作成できるかどうかを表す特性です。

例えば次のような状況は、制御容易性が低くそうです。

- パラメータや依存関係がハードコーディングされていて、制御が出来ない

## 4. 分解容易性（Decomposability）

システムを分割して個々の部分を独立してテストすることがどれだけ容易かを表す特性です。

例えば次のような状況は、分解容易性が低くそうです。

- テスト対象と直接関係がないパラメータや依存関係が必要になる
- 依存をテストスタブに置き換えられない

## 5. 単純性（Simplicity）

テスト対象となるシステムやコンポーネントがどれだけ簡単に理解し、分析し、そしてテストできるかを表す特性です。

例えば次のような状況は、単純性が低くそうです。

- 過度に複雑な機能や仕様
- 複数の責務を持つ

## 6. 安定性（Stability）

同じ条件や環境で何度テストしても、一貫した振る舞いができるかという特性です。
恐らくですが、コンポーネントの安定度についてち、実行結果が不安定ではないことを含むものと思われます。

例えば次のような状況は、安定性が低くそうです。

- 変更が頻繁で、テストへの影響が大きい
- 外部環境へアクセスしたり、乱数や時刻を使用したりして、同じ条件下でも結果が安定しない

## 7. 理解容易性（Understandability）

ソフトウェアの構造と動作をどれだけ容易に理解できるかという特性です。

例えば次のような状況は、安定性が低くそうです。

- 適切ではない命名
- 過剰な複雑性
- ドキュメントやコメントの不足

# Testabilityが低い状態とは

ここまでの特性などを踏まえて３行でTestabilityが低い状態を考えると

- テスト対象の理解が困難
- テストの実施が困難
- テストの結果が不安定

のような状態が考えられました。

# Testabilityを向上させるには

Testabilityが低い状態を解消し、テストを容易にするにはどうするか考えてみます。

## ”テスト対象の理解が困難”を解決するには

- コードをリーダブルにする
- 高凝集にすることで、テスト対象の責務を明確にする
- コードを補うドキュメントを用意する
- 追跡するためのログを出力する

## ”テストの実施が困難”を解決するには

- 安全にテストを実施できる環境を用意する
- 高コストな依存をテストダブルに置き換える
- 必要最小限のテストケースにする

## ”テストの結果が不安定”を解決するには

- 乱数や現在日時など非決定的な処理をテストダブルに置き換える
- 外部環境への依存をDockerコンテナやテストダブルに置き換える

# まとめ

Testabilityが高い/低いとはどういう状態なのか？という点の理解がぼんやりしていたので、理解を深めるために調査し、自分の経験も踏まえて整理してみました。

大きくわけると、テスト対象の理解のしやすさ、テスト実施のハードルの高さ、テスト結果の信頼性あたりがTestabilityにつながるイメージを持ちました。

Testabilityの７つの特性については、一次情報である書籍を読んで改めて整理したいと思います。

# 参考記事

こちらの記事を参考にさせていただきました。

https://goyoki.hatenablog.com/entry/2021/05/30/074612

https://thinkit.co.jp/article/14136
福岡へ来るエンジニア/メイカーの皆様に伝えたいパーツショップ/コワーキング/グルメなどまとめ

様々なイベントで我がふるさと福岡に来る/メイカーの皆様へお伝えしたい情報をこちらにまとめます。

なお、現在東京住まいのため、情報が古い場合もありますのでご了承ください。

# 電子部品・パーツショップ

#### カホパーツセンター
九州随一の品揃えを誇る電子部品・パーツショップです。
私が小学生の頃からお世話になっており、現在IT関連の仕事につけているのはにこちらでお世話になったおかげです。感謝しています。
※お店がある場所がラブホゾーンのど真ん中という斬新なロケーションです

https://www.kahoparts.co.jp/

福岡市中央区今泉1丁目9番2号天神ダイヨシビル2F　FAX 092-712-4946

#### (閉店)マルツ呉服町店(閉店)
マルツもあったのですが2023年6月で閉店となっています。
https://www.marutsu.co.jp/select/list/detail.php?id=1778

# コワーキング＆ファブスペース
##### エンジニアカフェ
素晴らしいコワーキングスペースができていました。

コワーキングスペース利用無料、ファブ系の工具、3Dプリンターなども無料！！！(フィラメント代は有料)で利用可能なスペースができていました。当然登録も無料。
こんなスペースが朝9:00から開いています。

福岡すごい。

https://engineercafe.jp/ja/


##### ヨカラボ天神
いつも使っているコワーキングスペースです。
2023年8月に実際ありましたが、エンジニアカフェは台風でクローズしていましたが、ヨカラボ天神はバッチリ開いてました。安心です。重要な会議などがある際など、使い分けが重要かと。
ロケーションも天神のど真ん中、電話会議ができるスペース、モニターの貸出、安定したネットワークなどなどストレス無く仕事ができます！

https://yokalab.jp/


# ジャンクショップ

いつのまにか秋葉原の有名店が福岡に！

#### イオシス福岡天神店
https://iosys.co.jp/shop/fukuoka_tenjin.html

#### じゃんぱら福岡天神店
https://www.janpara.co.jp/shopinfo/shop/?shopcd=225


# グルメ情報

主観に基づいたソウルフードたちを紹介します。

#### ふきや(お好み焼き)@博多駅
中学生の頃から食べ続けているホッとする味。
無料で大きめにアップグレードしてくれます。
※焼めしもおすすめなのですが、2023年8月時点、玉子高騰のため停止中とのこと

https://www.h-bt.jp/floor/shop24.html

#### むっちゃん万十(お好み焼き)@博多駅
中学生の頃から食べ続けているホッとする味(同じコメント！)
おすすめはハムエッグ。

https://www.h-bt.jp/floor/shop45.html

#### 元祖長浜屋@長浜
小学生の頃から食べ続けているホッとする味(こればっかり！)
色々あって元祖長浜屋だけではなく元祖長浜家、元祖ラーメン 博多元長、などありますが、私が行くのはこのお店です。

http://www.ganso-nagahamaya.co.jp/

#### 博多ラーメン はかたや
小学生の頃から食べ続けているホッとする味(これしかコメントないんか！)
色々あって元祖長浜屋だけではなく元祖長浜家、元祖ラーメン 博多元長、などありますが、私が行くのはこのお店です。

https://www.showafoods.jp/hakataya.html#tenpo



#### ウエスト(やわいうどん)
福岡といえばやわいうどん、プラスかしわ飯のおにぎり。

いろんなチェーンがありますが、私が行くのはこのお店です。

https://www.shop-west.jp/store/
ほぼ未経験でもChatGPTを使えばプログラムを作れるのか⑦プログラミングほぼ未経験者の挑戦～：アルゴリズム6

前回でデータの分析を解決（？）させたので、ようやく次に進めるわ！

![1 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/bfb105e7-41f5-1a25-f12b-7c00db062968.png)
図1：アルゴリズムの設計①の図7再掲

データの分析の次は5.の制約のリソースの把握ね。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/7ad4d368-f396-54b5-d6c3-3e012630b6bf.png)
図2

結構考えないといけないことが多いなぁ・・・

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/31203769-a615-8bd3-9c8d-bb4f6fc4d9be.png)
図3

機能要件は分かったけど、制約の中の整合性ってなんだ？

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/7ae7d5f3-0efe-afb1-f5df-f7443a5d0e87.png)
図4

スプレッドシートに入力する段階でミスったらダメってことか。

3.のデータの可用性と精度だけど、データの入力をするのは私だし、土日の入力が無理だな。
休みたいし。
あと私の事だから、入力ミスもめっちゃ考えられる。やりかねない。

データの更新頻度は1日1回でいいかな？

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/3b146b5a-0627-2751-d026-f57cce9dc547.png)
図5

これってパソコンのこ・・・と・・・・？ですよね？？

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/86a4cc30-dfdb-089d-6efe-a86345bc0a26.png)
図6

だいたいでいいから教えてほしいのに・・・

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/8d3cb948-c44e-8658-eed8-6bf3301b0594.png)
図7

Windows10でいけるなら11もいけるでしょ。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/06a35a1a-3c67-9605-d88c-861e3630aeea.png)
図8

え、分からない。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/71f884b4-8110-a5f4-edee-56fe158d404b.png)
図9

例じゃなくて、もう答えをください。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/78753bc4-cebb-5d85-bf79-a75d8c980e2c.png)
図10

めっちゃいい感じに教えてくれた！

でもお金がかかるものもあるのかな？

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/531eae69-fb40-74d5-8d31-df41bf4d9368.png)
図11

全部無料だって！！

よかったよかった。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500101/b350a2bb-ab49-7440-d97a-cbbb1aacd1ae.png)
図12

最後の5.の時間の制約は8月31日までだから全然時間ない。

だって７月に池田のやる気がちょっと早めの夏休みを2週間以上もとっちゃったからな・・・

まぁあんまり気にせず、出来るところまでやるということで。

制約やリソースの把握：解決

所用時間：1時間（素晴らしい仕事ぶり。ChatGPTが）
Wordにドキュメントのプロパティを追加する方法

## 導入
ドキュメントプロパティは、タイトル、著者、主題、キーワードなど、ドキュメントに関する追加情報を提供します。これにより、ユーザーはドキュメントを効果的に管理し、分類することができます。これらのプロパティは、ドキュメント編集ソフトウェアで設定や表示するだけでなく、C#とVB.NETのコードを通じても設定することができます。以下では、この操作について詳しく説明します。

## Free Spire.Doc for .NETをインストールする
**方法1**：[NuGet](https://www.nuget.org/packages/FreeSpire.Doc)でFree Spire.Doc for .NETをインストールする
Visual Studioを開いて新しいプロジェクトを作成します。次に、「Solution Explorer」で「References」を右クリックし、「Nuget Manage Packages」を選択します。Free Spire.Doc for .NETを検索してインストールします。
**方法2**：手動でSpire.doc.dllを追加する
[Free Spire.Doc for .NET](https://jp.e-iceblue.com/download/free-spire-doc-for-net.html)をローカルにダウンロードしインストールします。次に、Visual Studioて新しいプロジェクトを作成し、右側の「Solution Explorer」で「References」を右クリックし、「Add Reference」>「Browse」を選択して、インストールパスの下のBINフォルダのdllファイルを見つけ、「OK」をクリックして、プログラムに参照を追加します。

## コード：
**C#**:
```C#
using Spire.Doc;

namespace AddBuiltinDocumentProperties
{
    class Program
    {
        static void Main(string[] args)
        {
            //Documentクラスのインスタンスを作成する
            Document document = new Document();

            //Word文書の読み込み
            document.LoadFromFile("sample.docx");

            //組み込みの文書プロパティを文書に追加する
            BuiltinDocumentProperties standardProperties = document.BuiltinDocumentProperties;
            standardProperties.Title = "文書プロパティ";
            standardProperties.Subject = " 文書操作 ";
            standardProperties.Author = "山本";
            standardProperties.Company = "株式会社";
            standardProperties.Manager = "田中";
            standardProperties.Category = "文書";
            standardProperties.Keywords = "文書, Word, プロパティ";
            standardProperties.Comments = "この記事では、ドキュメントのプロパティの設定方法について説明しています。";

            //結果文書を保存する
            document.SaveToFile("result.docx", FileFormat.Docx2013);
        }
    }
}
```
**VB.NET**:
```VB
Imports Spire.Doc

Namespace AddBuiltinDocumentProperties
    Class Program
        Shared Sub Main(ByVal args() As String)
            'Documentクラスのインスタンスを作成する
            Dim document As Document = New Document()

            'Word文書の読み込み
            document.LoadFromFile("sample.docx")

            '組み込みの文書プロパティを文書に追加する
            Dim standardProperties As BuiltinDocumentProperties = document.BuiltinDocumentProperties
            standardProperties.Title = "文書プロパティ"
            standardProperties.Subject = "文書操作"
            standardProperties.Author = "山本"
            standardProperties.Company = "株式会社"
            standardProperties.Manager = "田中"
            standardProperties.Category = "文書"
            standardProperties.Keywords = "文書, Word, プロパティ"
            standardProperties.Comments = "この記事では、ドキュメントのプロパティの設定方法について説明しています。"

            '結果文書を保存する
            document.SaveToFile("result.docx", FileFormat.Docx2013)
        End Sub
    End Class
End Namespace
```
## 効果図：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/a0e3bb34-d340-9acd-3292-541f55185948.png)
WindowsでのNode.jsのバージョン管理

# はじめに

Node.js のバージョン管理は Linux なら asdf 一択なのですが、Windows で何を使うかずっと悩んできました。どれも微妙にしっくりこないんですよね。

nodist、Volta、nvs その他いろいろ渡り歩いて最終的に fnm にたどり着きました。

.node-version を認識して自動でバージョンが切り替わってくれるし、コマンドが分かりやすいので、今は fnm に満足しています。

ここには自分の開発環境作りのためのメモとして設定方法を残しておきます。

# インストール

方法はいろいろあるのですが私は winget を使いました。

```powershell
winget install Schniz.fnm
```

# 補完の設定
役に立っているのかはよく分からないｗ
```powershell
fnm completions --shell powershell
```

# シェルの設定
.node-version を検出して自動でバージョンが切り替わるようにするためには設定が必要。

PowerShell 上で `$profile` と入力して出るファイルに設定を追加する。

```powershell
$profile
```

私の場合には
~/ドキュメント/PowerShell/Microsoft.PowerShell_profile.ps1 ファイルだったが、そもそもファイルがなかったので作成して
`fnm env --use-on-cd | Out-String | Invoke-Expression`
を追加した。

PowerShell のバージョンによってファイルが異なるので注意。詳しくは公式のページを確認。
https://github.com/Schniz/fnm#shell-setup

# Node.js のインストール

```powershell
fnm install 18.17.1
```

# インストールされたバージョンの一覧

```powershell
fnm list
```

# ヘルプ

分からなくなったらとにかく fnm を打てば良い。ヘルプが出る。

```powershell
fnm
```