OmniAICreator/Qiita-1.07M huggingface dataset:
COBOLのPERFORM 


# PERFORM 
:::note
ループ処理を行うためのもの
:::

# PERFORM VARYINGとは

**特定の変数を指定した範囲内で変化させながら繰り返し処理を行う**


## PERFORM VARYINGステートメントの構文

```cobol
PERFORM VARYING variable-name FROM start-value BY increment-value UNTIL condition
    ...
END-PERFORM
```
### 各要素の意味

#### variable-name 
ループ処理中に変化させる変数の名前
#### start-value 
variable-nameの初期値
#### increment-value 
variable-nameの増分を指定

<details><summary>increment-valueについて
</summary>

## increment-value
:::note
ループ処理中に変化させる変数の増分を指定する
ループが一回繰り返されるごとに、指定した変数がこの増分だけ増加 / 減少する
:::
### 例
```cobol
PERFORM VARYING Counter FROM 1 BY 2 UNTIL Counter > 10
    ...
END-PERFORM.
```
increment-valueはBY 2が該当する

Counter変数は１からスタートして、１回のループごとに２ずつ増加していく
→１，３，５，７，９，となる

*****

</details>

#### condition　
ループを続けるかどうかを判定する条件式
この条件が false になるまでループが続く




## PERFORM VARYINGステートメントの使用例

```cobol
IDENTIFICATION DIVISION.
PROGRAM-ID. LoopExample.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Counter      PIC 9(3) VALUE 1.

PROCEDURE DIVISION.
    PERFORM VARYING Counter FROM 1 BY 1 UNTIL Counter > 10
        DISPLAY "Counter: " Counter
    END-PERFORM.
    STOP RUN.
```

Counter変数の値を1から10まで変化させながら、その値を表示している
PERFORM VARYINGステートメントによって、ループが10回繰り返される



# PERFORM UNTILとは

**指定した条件が満たされるまで、特定の処理を繰り返し行う**

## PERFORM UNTILステートメントの構文

```cobol
PERFORM UNTIL condition
    statements
END-PERFORM.
```

### 各要素の意味

#### condition
ループの終了条件を示す条件式
TRUEになったらループは終了する

#### statements
実際に実行される処理



## PERFORM UNTILステートメントの使用例

```cobol
PERFORM UNTIL COUNTER >= 5
    DISPLAY "Counter value: " COUNTER
    ADD 1 TO COUNTER
END-PERFORM.
```

COUNTER の値が５未満である限り、DISPLAY ステートメントが実行される
COUNTER の値は１ずつ増加
COUNTER の値が５以上になると、PERFORM UNTIL ループは終了する
【学習用】基本情報技術者試験「スタック・キュー」

## 目次
* データ構造
    * データ構造の種類
* スタック
    * スタックの具体例
* キュー
    * キューの具体例
* まとめ

## データ構造
データ構造とは、主記憶装置上のデータの並べ方のことを「データ構造」という。

#### データ ：コンピュータが扱う情報のこと
※データは「****主記憶装置****」に保存される

#### データ構造の種類
1. スタック
2. キュー
3. 配列
4. 連結リスト
5. 木構造

## スタック

データを一列に並べて、****最後****に格納したデータを****最初****に取り出すデータ構造

スタックにデータを格納することを****push****、データを取り出すことを****pop****という

 ![qiita-square.png](https://upload.wikimedia.org/wikipedia/commons/e/e4/Lifo_stack.svg)

#### スタックの具体例

本を積み上げるときは、上へ上へと重ねる。
反対に、本の山の中から1冊取りたいときは、最上部の本から順番にとる。
途中にある本をとることはできない！

常に、取り出せるのは最後に置いたもの。スタックは****新しいもの****から処理していく。

## キュー
データを一列に並べて、****最初****に格納したデータを****最初****に取り出すデータ構造
キューにデータを格納することを****enqueue****（エンキュー）、データを取り出すことを****dequeue****（デキュー）という
![qiita-square.png](https://upload.wikimedia.org/wikipedia/commons/d/d3/Fifo_queue.png)

先に入れたデータを先に出すアルゴリズムのことを****先入れ先出し****(FIFO：First in First Out)という

#### キューの具体例
・レジなどの待ち行列
・スーパーなどの飲み物の陳列
（裏から新しいものを補充して、お客さんは手前から取っていく）
・ロケット鉛筆
・プリンターの印刷順
・画像のアップロード順

常に、取り出せるのは最初に置いたもの。キューは****古いものから処理****していく。

## まとめ

#### スタック
データを一列に並べて、****最後****に格納したデータを****最初****に取り出す
データ構造。
データを格納することを****push****、データを取り出すことを****pop****という。

#### キュー
データを一列に並べて、****最初****に格納したデータを****最初****に取り出す
データ構造。
キューにデータを格納することを****enqueue****、データを取り出すことを****dequeue****という。
Arduino Uno R4 MINIMAにアップロードできない


:::note info
Problem:
```Cannot open DFU device 2341:0069 found on devnum 7 (LIBUSB_ERROR_NOT_FOUND)```
Solution:
```Use Arduino IDE1.8.x and install Driver.```
:::


arduino UNO R4 MINIMA を購入したので、
ワクワクで PlatformIOにてビルドしてみました。環境はWindows11です。
platform.iniの設定は以下の通り。

```
[env:uno_r4_minima]
platform = renesas-ra
board = uno_r4_minima
framework = arduino
```
ビルド自体は通るのですが、書き込みでエラー。

```
Cannot open DFU device 2341:0069 found on devnum 7 (LIBUSB_ERROR_NOT_FOUND)
No DFU capable USB device available
Failed uploading: uploading error: exit status 74
```

コントロール パネル>ハードウェアとサウンド>デバイスとプリンター
で確認してみると、デバイスデバイスがちゃんと認識されていないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c07422ae-d2aa-1269-db20-c5f1d11f0f91.png)

色々調べてみたのですが、ArduinoIDE 1.8.xから立ち上げると
ドライバーのインストールを促されるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/aaac4dbb-ee96-1d07-5bb8-889d795fcbed.png)

インストールしたところ、デバイスが正常に動作していると出るようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/b12b2b8a-1366-a6b1-82bb-893728244c2e.png)

この状態で再度build＆uploadしてみると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/eb9316d6-1e9f-451e-4b0c-1718426050e3.png)

正しくアップロードされました！

アップロード中は自動的にDFUモード（ビルトインLEDがゆっくり明滅する）になり、書き込みが終わると通常モードになるようです。
なお、リセットボタンをダブルクリックすることでもDFUモードにすることができます。

ちなみに基板の裏にあるハート型のランド、[調べてみたら](https://www.renesas.com/us/en/document/dst/renesas-ra4m1-group-datasheet)２２ピンにつながっているみたいだけど、何かに使えるのかなあ。。
Postmanの環境変数を使ってサーバーの向き先を簡単に変えてみる

## はじめに

使っていてサーバーの向き先を毎回変更するのが面倒でした...
調べてみると環境変数なるものがあったので使ってみました！

## 設定すると
下記の画像のようにクリックひとつで環境を変えることができます
![スクリーンショット 2023-08-29 17.11.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/4b827fb7-abcd-28d8-539d-3574f96e8fe4.png)

環境変数毎に設定したIP、ドメインが設定した値に代入されます
![スクリーンショット 2023-08-30 8.03.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/7295a233-3cca-0e35-564c-718d2f9304e1.png)


## 設定方法

左TabのEnviromentsを選択し、プラスボタンを押下します
![スクリーンショット 2023-08-29 17.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/c3ccdeaf-d839-c118-a010-760575f9c0f0.png)

するとNew Enviromentが追加されるのでVariableとInitial Valueを設定します
![スクリーンショット 2023-08-29 17.21.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/757927e3-2971-c9b6-3f4f-d9e4cf31d1f1.png)

同様にローカル環境も作成してみました
![スクリーンショット 2023-08-29 17.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/ecac1e06-1237-4e60-3495-950f235da722.png)

次にAPIのURLを設定する項目で今作成した変数を使用します
```{{}}``` で変数を囲うことで使用できます
今回は```{{IP}}```と入力しました
![スクリーンショット 2023-08-29 17.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1201315/1c452913-9fd5-a669-a502-2c6dcd4d2ae5.png)

右上の環境を変更することで環境ごとに設定した値が代入されます。

## 終わりに
毎回スニペットからサーバーのIPやドメインを打ち込んでいましたが、今回の作業からかんたんに向き先を変更できるので快適です！　変数はBodyやその他の場所でも使用できるので活用していきたいですね。
WSL1をインストールしたら動いていたけど、0x800700b7が出るようになったが rootfs 消したらもう一度インストールできた

# 概要

2023年8月の世だが Windows Server 2019 に WSL1 を入れて Ubuntu 使えるようにしたら、エラーで使えなくなった。  
しかし ubuntu.exe と同じ階層にある rootfs を消したら、再びインストールできて動かせるようになった。

# いきさつ

Hyper-VでVM一々立ち上げたくない。
Windows Server にも WSL 入れるととあるコマンド使えるから便利だから入れて使いたい。

Server 2019だからWSL1しか入らない。けど動くなら便利。

手動インストールして入れてみて動いたけど、ダウンロードフォルダに展開していたファイル動かしたら動かなくなった。

対策をWEBで探すと、WSL2の情報ばっかり。WSL1の頃のも見つかるが、大変そう。
共有マシンなので再起動が必要だとスケジューリングしないといけないのでめんどう。
どうしよう。

# 環境

* ```Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsHardwareAbstractionLevel```
```
Windows Server 2019 Standard 1809
```

# インストール

1. WSLのフィーファー有効化して再起動
2. Ubuntu2204-221101.AppxBundle を 7z で unzip
   a. unzip したフォルダの中の Ubuntu_2204.1.7.0_x64.appx を 7z で unzip
   b. unzip したフォルダの中の ubuntu.exe を実行
   c. ```Installing, this may take a few minutes...``` と表示され、しばらくすると、次のようにアカウント作成のプロンプトが表示され、使えるようになった。
      ```
      Please create a default UNIX user account. The username does not need to match your Windows username.
      For more information visit: https://aka.ms/wslusers
      Enter new UNIX username:
      ```
3. Downloadsフォルダに展開したもの要らないから消す。
4. 動かなくなる。
5. ```wslconfig /u Ubuntu``` してもう一度 ```ubuntu.exe``` すると、次のエラーが出る。
  ```   
  Installing, this may take a few minutes...
  WslRegisterDistribution failed with error: 0x800700b7
  The distribution installation has becom corrupted.
  Please select Reset from App Settings or uninstall and reinstall the app.
  Error: 0x800700b7 ????????????????????????
  
  Press any key to continue...
  ```

# 対策

```C:/path/to/Downloads/Ubuntu2204-221101/Ubuntu_2204.1.7.0_x64/ubuntu.exe``` と同じ階層にある
```C:/path/to/Downloads/Ubuntu2204-221101/Ubuntu_2204.1.7.0_x64/rootfs``` をリネームして別の名前にする。

再びその ```C:/path/to/Downloads/Ubuntu2204-221101/Ubuntu_2204.1.7.0_x64/ubuntu.exe``` をダブルクリックして実行する。

すると再びUbuntuがインストールできた。

# よかった

私の場合、WSLのフィーチャー無効にして再起動してもう一度WSLのフィーチャー有効にして再起動とかしなくても復旧できてよかった。

# 注意

別ユーザーが wsl やっても ubuntu 入ってない。
同じ ```C:/path/to/Downloads/Ubuntu2204-221101/Ubuntu_2204.1.7.0_x64/rootfs``` を別ユーザーが実行しても、
0x800700b7 のエラーが出るので、Ubuntu共有できない。
Javaで「HashMapの使い方」の動作を確認してみた

# 概要
Javaで「HashMapの使い方」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/collection/index3.html

# 実装
以下のファイルを作成しました。
```JSample3_1.java
import java.util.HashMap;
import java.util.Map;

class JSample3_1{
  public static void main(String[] args){
    HashMap<String,Integer> map = new HashMap<>();

    map.put("リンゴ",80);
    map.put("オレンジ",120);
    map.put("ブドウ",90);

    System.out.println(map.get("ブドウ"));
    System.out.println(map.get("リンゴ"));
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample3_1.java 
$ java JSample3_1 
90
80
```

# まとめ
何かの役に立てばと。
MSW導入詰まったところ

## はじめに
MSWを導入するにあたり遭遇したエラーやWarning、悩んだことをまとめます。

#### 開発環境
- webpack: ^4.44.2
- msw: ^0.48.3
    - rest api

## `Warning: captured a request without a matching request handler`

#### 問題点
リクエストハンドラに登録されていないリクエストがある場合に発生する。

#### 解決方法

- リクエストハンドラにWarningが出ているリクエストを追加する。
```ts
rest.get('/warning/request/path', (req, res, ctx) => {
    return res(ctx.json({ text: 'test' }))
})
```

- worker（あるいはserver）を開始する際にハンドルしていないリクエストのWarningを出さないように設定する。
```ts
worker.start({
  onUnhandledRequest: 'bypass',
})
```

参考: https://mswjs.io/docs/api/setup-worker/start#onunhandledrequest

## クエリパラメータの値によってレスポンスを変えたい

#### 問題点
使用しているAPIが`/api/?command=xxx`のようにクエリパラメータでエンドポイント名を指定するような設計になっている。
下記のように、リクエストハンドラにクエリパラメータ付きで登録してもエンドポイント名でリクエストを分岐させることはできない。（Warningが出る）

```ts
rest.get('/api/?command=aaa', (req, res, ctx) => {
    return res(ctx.json({ text: 'test' }))
}),
rest.get('/api/?command=bbb', (req, res, ctx) => {
    return res(ctx.json({ text: 'test' }))
})
```

#### 解決方法
`/api`のリクエストは一旦すべてインターセプトし、`command`パラメータの値でレスポンスを分岐させる。

```ts
rest.get('/api', (req, res, ctx) => {
    const commandName = req.url.searchParams.get('command')
    
    switch (commandName) {
        case 'aaa':
            return res(ctx.json({ text: 'aaa' }))
        case 'bbb':
            return res(ctx.json({ text: 'bbb' }))
        default:
            return
    }
  }
})
```

参考: https://mswjs.io/docs/recipes/query-parameters

## `Expected response resolver to return a mocked response Object but got undefined. The original response is going to be used instead`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482641/12c70b17-fe42-462b-1064-754eab2e3ff2.png)

#### 問題点
上記「クエリパラメータの値によってレスポンスを変えたい」で使用した解決方法で発生したWarning。
上記例で`default`の場合に`undefined`を返しているため発生していた。

:::note
mswのバージョン0.40.0以降のであれば発生しないが、バージョン指定が`^0.48.3`になっていたため発生した。
:::

#### 解決方法
上記例の`default`の返り値として`req.passthrough()`を返す。
これによりMSWでモックを返すことなく、そのまま本来のエンドポイントにリクエストが送信される。

```ts
default: 
    return req.passthrough()
```

参考: https://mswjs.io/docs/api/request/passthrough
IBOutletで接続しているBarButtonItemがいつの間にかnilになる

# この記事の内容

- IBOutletで接続しているBarButtonItemがnilになる原因と対策
- navigationItem.rightBarButtonItemやleftBarButtonItemには気をつけよう！
- IBOutletにweakをつけた時とつけなかった時の挙動の違い

# この記事のターゲット

- BarButtonItemがいつの間にかnilになるんだけど？！って人
- IBOutletってweakつける意味ある？！って人
- 俺（備忘録）

# 発生している問題

`@IBOutlet** weak **var** barButton: UIBarButtonItem!` のように定義しているオブジェクトがいつの間にかnilになっており、参照しようとするとクラッシュしてしまう。
`weak`を外して`@IBOutlet var barButton: UIBarButtonItem!`とするとクラッシュしない。

# 問題の原因

navigationItem.rightBarButtonItem = hogeButton と別のButtonを入れていたから！

## 詳細

元々storyboard上でnavigationItemのrightBarButtonItemにbarButtonを適用し、NavigationBarの右側にbarButtonが表示されるように設定していた。

しかし仕様上、ある動作をした時に表示されているボタンをbarButtonからhogeButtonへ変更させたいため`navigationItem.rightBarButtonItem = hogeButton`と実装していた。

この時、内部ではrightBarButtonItemからbarButtonが削除される → すなわちNavigationItemからbarButtonに対する強参照が解除されることになり、barButtonがメモリ解放されてしまう。

# 問題の対策

barButtonの宣言時にデフォルトでついているweakを削除し、barButtonへの参照を強参照とする
また、万が一で循環参照するかもしれないので、barButtonを宣言しているViewControllerのdeinit内で`barButton = nil` を行い参照カウントを減らしておく。

### なぜweakを削除するとクラッシュしないの？

先ほどの話では、`navigationItem.rightBarButtonItem = hogeButton`としたときに、NavigationItemからbarButtonに対する強参照が解除されるのでbarButtonのメモリ解放が発生すると説明しました。

しかし正確には、NavigationItemからbarButtonに対する強参照が解除されるからbarButtonのメモリ解放が発生するわけではなく、barButtonに対する強参照が解除されたことにより、barButtonの参照カウントが0になるからメモリが解放されます。
そこで、barButtonのweakを外すことで

- NavigationItemからの参照カウント
- UIViewControllerからの参照カウント

の2つが与えられるので、NavigationItemからの参照カウントが無くなってもbarButtonのメモリが解放されることはなくなります。

# IBOutletにweakをつけた時とつけなかった時の挙動の違い

おまけですが、IBOutletにweakをつけた時とつけなかった時の違いについて軽く解説します。
### weakをつけた時（デフォルト）のメリット

- 循環参照が発生しづらくなる
    - weakをつけた対象オブジェクトに対する参照は（一部を除き）すべてが弱参照となるため、循環参照が発生しづらくなる

### weakをつけた時（デフォルト）のデメリット

- weakをつけなかった時よりもnilにアクセスする可能性が上がる
    - 基本的にはないが、なんらかのきっかけで対象オブジェクトの参照カウントが0になってしまった場合にメモリが解放され、nilにアクセスしてしまう

weakをつけなかった時のメリデメは上記の逆です。
正確に管理しないと循環参照が発生しやすくなる代わりに、nilにアクセする可能性が下がります。
Aurora MySQL version2からversion3にしたときに詰まったこと

# はじめに
Aurora MySQL v2が[2024年10月31日でEOLを迎える](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.VersionPolicy.html#Aurora.VersionPolicy.MajorVersionLifetime
)ので、重い腰を上げてAurora MySQL v3にしました。
v3への移行の際に[Blue/Green deployment](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/blue-green-deployments-overview.html)で楽々移行♪と思っていたのですが、ハマるポイントなどもあったのでまとめました。


# Blue/Green deploymentでの問題

## Blue/Green作成時に「mysql.flush_rewrite_rules」のエラーが発生する

Blue/Greenの作成ボタンを押した段階で、エラーが発生しprecheckログには「mysql.flush_rewrite_rules」に関するエラー内容がありました。
```
        {
            "id": "routinesSyntaxCheck",
            "title": "MySQL 8.0 syntax check for routine-like objects",
            "status": "OK",
            "description": "The following objects did not pass a syntax check with the latest MySQL 8.0 grammar. A common reason is that they reference names that conflict with new reserved keywords. You must update these routine definitions and `quote` any such references before upgrading.",
            "documentationLink": "https://dev.mysql.com/doc/refman/en/keywords.html",
            "detectedProblems": [
                {
                    "level": "Error",
                    "dbObject": "mysql.flush_rewrite_rules",
                    "description": "at line 5,8: unexpected token 'QUERY'"
                }
            ]
        },
```

### 解決策
AWSに連絡してプロシージャをDROPしてもらうことで解決しました

> 本問題は RDS for MySQL DB インスタンスから移行した DB クラスターにおいて発生する場合があることを確認しております

ということで、[RDS for MySQLからAuroraに移行したデータベースでは発生することがある](https://repost.aws/questions/QUoE-he7giSgmAnx1qET17EQ/error-when-upgrading-aurora-mysql-from-v2-5-7-to-v3-8-0
)そうです


## Blue/Green切替ができない
Blue環境とGreen環境の切り替えが失敗してしまう

```markdown
Message : Switchover from DB cluster dev-aurora to dev-aurora-green was canceled due to external replication on dev-aurora. 
Stop replication from an external database to dev-aurora before you switch over.
```

### 解決策

元々オンプレミスからRDSに移行した際に、ライターインスタンスのSlave解除をせずに運用していたため発生していました
ライターインスタンスのリセットを行うことで解決しました

```sql
SELECT * FROM mysql.rds_history;
もしリセットされてなかったら 
CALL mysql.rds_reset_external_master;
でリセットする
```

# MySQL5.7 → MySQL8.0 になったことによる問題

## Rankが予約語になった
選択肢として、
1.  アプリケーション側でのエスケープ対応
2.  カラム名の変更

となると思いますが、エスケープ忘れなどミスが起きる可能性があるため `2. カラム名の変更` で対応しました。

## 移行後に特定クエリのパフォーマンスが劣化した

巨大なテーブルをJOINするクエリにおいてパフォーマンスが劣化してしまう

## 解決策
[MySQL8.0から一時テーブルの動作が変更されていた](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/ams3-temptable-behavior.html)
ストレージエンジンパラメータであるtemptable_max_ram、temptable_max_mmapをJOINするテーブルサイズを参考に、余裕をもたせた値に調整して対応しました。

# まとめ

## MySQL8.0になったこと
* MySQL 8系統にアップグレードしたことで、以前は使用できなかったWith句など、利用したかった機能が利用可能になった

## Blue/Green deploymentを利用したこと
* 大変なDBのアップグレード作業をコンソール上の簡単な操作でできる
* 開発環境での試験中にエラーが発生したが、適切に元の状態に戻ってくれるため、本番でも失安心して作業を進めることができた

# AWS公式の記事以外で参考にした記事

* [Amazon Aurora MySQL で Blue/Green Deployments を使ったマイナーバージョンアップグレードの手順](https://techblog.nhn-techorus.com/archives/22874)
* [AWS RDS 『Aurora Version 3.x（MySQL8.0互換）』導入時のノウハウ
](https://aimstogeek.hatenablog.com/entry/2023/04/17/000000)
buildした後に, buildエラーが発生していなかった場合 対象のソフトを自動的に起動するバッチファイルの作成

# 背景
- 以下の失敗を防止し, 作業の効率化を計る為に、
buildとソフトの起動を一度の操作で行うバッチファイルを作成した。<br><br>
  - 失敗の例
    - build中に他の作業を始め、その作業に集中してしまい、buildした方の作業を放置する。
      - 漫画を読んだり、SNSを確認したりして時間を浪費してしまう。
    - buildをしたか不安になり、何度もbuildしてしまう。
    - 変更後buildを忘れてアプリを起動する。

# コード
## ローカルリポジトリの切り替えが必要ない場合
```bat
@echo off
cd %PrivateRepository%
dotnet build

if %errorlevel%==0 (start "" "%AmongUs%\Among Us") else ( pause ) 
```

## ローカルリポジトリの切り替えが必要な場合
```bat
@chcp 65001
@echo off

:Select_Input
echo +-------------------------------------------------------------------+
echo  どのLocalRepositoryを使用していますか? 該当する数字を入力してください。
echo      1. Private_Repository
echo      2. Public_Repository
echo +-------------------------------------------------------------------+
Set /P INPUT_NO=
if "%INPUT_NO%"=="1" GOTO :Private_Repository
if "%INPUT_NO%"=="2" GOTO :Public_Repository
GOTO :Select_Input

:Private_Repository
echo +--------------------------------+
echo   Private_Repository に移動します。
echo +--------------------------------+
cd %PrivateRepository%
GOTO :Build_And_Start

:Public_Repository
echo +--------------------------------+
echo   Public_Repository に移動します。
echo +--------------------------------+
cd %PublicRepository%
GOTO :Build_And_Start

:Build_And_Start
if %errorlevel%==0 (start "" "%AmongUs%\Among Us") else ( pause ) 
```

# 説明
## ``%[環境変数名]%``
- コード
  - ``%PrivateRepository%``
  - ``%PublicRepository%``
  - ``%AmongUs%``<br><br>
- build対象のフォルダ 及び 起動ファイルを, 環境変数で指定しています。
  - build対象のフォルダを環境変数で指定している理由。
    - PCを複数台数使用していて, 更にこのバッチファイルを共用ファイルとして使用しているから。<br><br> 
  - 起動ファイルを環境変数で指定している理由。
    - 元々, build先が環境変数で指定している為, そのまま流用した。
    - フォルダ名等を変更した際に 一括で変更できる為, 環境変数を使用するのが便利である。

## ``cd %[環境変数名]%``
- build対象のフォルダに移動する。

## ``%errorlevel%``
- 直前のコマンドでエラーが発生しているか確認する。
  - 0が返った場合
    - 正常に処理ができた為, build後のファイルを起動する。
  - 0以外が返った場合
    - buildエラーが発生した為起動せず, 代わりに入力受付を行いターミナルを閉じない事により, エラーを確認できるようにする。

## ``start "" "%AmongUs%\Among Us"``
- ファイルを起動する。
  - このコードの場合, ``%AmongUs%``の中にある``Among Us.exe``を起動している。
  - ``%AmongUs%``はbuild先でもある。

## ``@chcp 65001``
- バッチファイルの文字コードを``UTF-8``として明示する。
  - これを使用しないと, 日本語の操作説明が文字化けしてしまう。
  - 参照 : [UTF-8のバッチファイルが文字化けする時の対処3選](https://nayutari.com/batch-utf8)

## ``:[ラベル名]``
- GOTO で飛ぶ際の指定先です。

## ``echo``
- プロンプトに文字を表示します。

## ``Set /P [変数名]=``
- 変数を宣言し, ユーザの入力を待ちます。
- 入力されると, 変数に代入されます。

## GOTO
- ``if "%INPUT_NO%"=="〇"`` でユーザが入力した文字を判定します。
  - 例
    - ``if "%INPUT_NO%"=="1" GOTO :Private_Repository``
      - ``1``が入力された場合, ラベル[``:Private_Repository``]に処理を飛ばす。
    - ``GOTO :Select_Input``
      - 此処の処理に達した場合(入力値が指定しての物ではなかった場合), 最初の処理に戻る。

# 参考資料
- 環境変数
  - https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81 <br><br>
- アプリの起動
  - https://takafumi-blog.net/cmd-start-call/ <br><br>
- GOTOとラベル
  - https://www.javadrive.jp/command/bat/index11.html <br><br> 
- ユーザ入力を受け付け, 入力値によって処理を変更するコード。
  - https://web-creators-hub.com/windows/bat-set-s/ <br><br>
  - https://sugublog.org/bat-set-p/
Rustでmpscチャンネルの受信スレッドを綺麗に止める方法

ハイサイ！オースティンやいびーん。

# 問題

Rustの`std::sync::mpsc::Channel`の`Receiver`を別のスレッドに移動させて、`iter`していると、そのスレッドのハンドルに足して`join`を呼んでも永遠に解決しない。

```rust
    let (tx, rx) = mpsc::channel();

    let handle = thread::spawn(move || -> Result<(), mysql::Error> {
        for data in rx.iter() {
            ///
        }

        Ok(())
    });
```

# 解決法その１

`Transmitter`（配信体）を無理やり`drop`して解放する:

```rust 
    let (tx, rx) = mpsc::channel();

    let handle = thread::spawn(move || -> Result<(), mysql::Error> {
        for data in rx.iter() {
            ///
        }

        Ok(())
    });

/// ...

drop(tx);

handle.join().unwrap(); // OK!
```

最も簡単です。~~ただ多分何かと間違っているのでしょう~~ これが一番明示的でいいでしょう！:joy: @namn1125 ありがとうございます。

# enumを使って、完了のメッセージを配信する

より優雅な解決法でしょう。

```rust
enum Message {
    Add(u64),
    Finished,
}

let (tx, rx) = mpsc::channel();

let handle = thread::spawn(move || -> Result<(), mysql::Error> {
    for data in rx.iter() {
        match data {
            Message::Add(n) => {},
            Message::Finished => {
                break;
            },
    }

    Ok(())
});

tx.send(Message::Finished);

handle.join().unwrap(); // OK!
```

しかしやや冗長です。

# まとめ

以上、Rustで別スレッドに移動したmpscの受信体の`iter`を止めて、綺麗にスレッドを終了させる方法を紹介しました。

特に感想はないのですが、読者さんには僕よりずっとRust経験が豊富な方がたくさんいると思いますので、ぜひコメントで技を共有していただけると嬉しいです。:relaxed:
plunkerでvue その63

# 概要
plunkerでvueやってみた。
練習問題、やってみた。

# 練習問題
vueファイルをcomponent化してtagで使う。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/aa3b5e93-3e99-1167-1506-fe3d96540232.png)

# サンプルコード

```

require({
  paths: {
    'Vue': 'https://unpkg.com/vue@2.5.11/dist/vue.min',
    'vue': 'https://unpkg.com/requirejs-vue@1.1.5/requirejs-vue'
  }
}, ['Vue', 'vue'], function(Vue, vue) {
  require(['vue!app', 'vue!tVar'], function(theApp) {
    theApp.$mount('#app');
  });
});


```

# 成果物

https://embed.plnkr.co/plunk/WYMHXLIJBnLmNDgg


以上。
Java で Word を HTML ファイル形式に変換する

## はじめに
HTML ファイルは、Web ページの作成に使用される、ハイパーテキスト マークアップ言語で記述されたテキスト ファイルです。 Web ページの構造、コンテンツ、スタイルなどの情報が含まれています。 Word 文書を HTML ファイルに変換すると、Word 文書内のテキスト、見出し、段落、リスト、表、画像、その他の要素を、対応する HTML タグと属性に変換できます。 この変換により、ドキュメントのコンテンツを Web 上に簡単に公開できるだけでなく、ドキュメントがさまざまなプラットフォームやデバイス間で一貫して表示されるようになります。 関連する方法を以下に説明します。
## ツール
* IntelliJ IDEA 2018 (jdk 1.8.0)
* [Free Spire.Doc for Java](https://www.e-iceblue.com/Introduce/free-doc-for-java.html)

## Jarファイルの導入
* [Free Spire.Doc for Java](https://www.e-iceblue.com/Download/doc-for-java-free.html)をダウンロードして解凍します。
* IDEAで新しいプロジェクトを作成します。
* 「File」>「Project Structure」>「Modules」>「Dependencies」をクリックします。
* 「+」の「JARs or Directories」を選択します。
* 「Spire.doc.jar」を見つけてプロジェクトにインポートします。
## コード：
```JAVA
import com.spire.doc.*;

public class WordToHtml {
    public static void main(String[] args) {

        //Documentインスタンスの作成
        Document document = new Document();

        //Word文書を読み込みます
        document.loadFromFile("sample.docx");

        //Wordを HTML として保存します
        document.saveToFile("output/toHtml.html", FileFormat.Html);
    }
}
```
上記のコードでは、まず、 Document インスタンスが作成されます。 loadFromFile() メソッドを呼び出して Word 文書を読み込みます。最後に saveToFile(String fileName, FileFormat fileFormat) メソッドを通じて文書を HTML ファイルとして保存します。

Free Spire.Doc for Java の saveToFile(String fileName, FileFormat fileFormat) メソッドは、Word から [PDF](https://www.e-iceblue.com/Tutorials/Java/Spire.Doc-for-Java/Program-Guide/Conversion/Convert-Word-to-PDF-in-Java.html)、[画像](https://www.e-iceblue.com/Tutorials/Java/Spire.Doc-for-Java/Program-Guide/Conversion/Convert-Word-to-Images-in-Java.html)、[XPS](https://www.e-iceblue.com/Tutorials/Java/Spire.Doc-for-Java/Program-Guide/Conversion/Java-Convert-Word-to-XPS-XML-RTF-TXT-and-SVG.html)などのさまざまな文書形式への変換をサポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/aedf9bbb-1db7-7089-4d9a-57b8196baee5.png)
Rust コンパイラーバグ？

まだ Rust は入門レベルだが、ネット上の資料を参考に Lisp インタプリタを作ってみた。

コードで "does not live long enough" コンパイルエラーが出たが、不思議なことに、全く別の関数を書いたらエラーが消えた。エラーはその関数を呼んでる分けでもない。（そもそも、その関数が存在する前から出ていた。）
細かく調べたら、その別の関数の引数に "&" を付けるか付けないかで、元のコードのエラー指摘が変る。

これはどう見ても Rust コンパイラーのエラーとしか思えない。

バグレポート出そうか。
create-react-app で作った Reactプロジェクト から Hello World (不要ファイル削除)

Reactの開発環境を作るときに公式とかで使われる [create-react-app](https://github.com/facebook/create-react-app) で何かやるときに不要ファイル削除すること多いのでざっくりそのやり方のメモ
作ったところから不要ファイルを削除して Hellow World の表示までやってみる
やることは大雑把にこんなかんじ．．．

- React プロジェクト作成 Win11
- React プロジェクトから不要ファイル削除（./src直下削除）
- Hellow World 表示のjSを作成
    - index.js のみで表示
    - index.js から App.js 読み込んで表示

# React プロジェクト作成 Win11

こちらのページ参考、Node.jsインストールからやってます

https://qiita.com/sueasen/items/5aaac3dd4052de82c2f9

# React プロジェクトから不要ファイル削除（./src直下削除）

1. 不要ファイル削除（./src直下削除）
    コマンドプロンプト or PowerShell で以下を入力して削除
    ＃ src フォルダは削除しない
    ```Powershell:PowerShell
    cd {Reactプロジェクトのフォルダ}
    Remove-Item src\* -Recurse
    ```
    ```Powershell:コマンドプロンプト
    cd {Reactプロジェクトのフォルダ}
    del /q src\*
    ```

# Hellow World 表示のjSを作成

## index.js のみで表示

1. ./src 直下に index.js を作成して以下のコードを入力
    ```JSX:index.js
    import ReactDOM from 'react-dom/client';
    import { StrictMode } from 'react';

    const App = () => {
      return (
        <>
          <h1>Hello World</h1>
          <p>index.js</p>
        </>
      );
    };

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <StrictMode>
        <App />
      </StrictMode>
    );
    ```

1. プロジェクトを実行してブラウザに `Hello World` 表示されればOK
     ```Powershell
    npm start
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/77acacc7-bcdc-fd5e-b01e-92eb5bf41563.png)

## index.js から App.js 読み込んで表示

1. ./src 直下に App.js を作成して以下のコードを入力
    ```JSX:App.js
    const App = () => {
      return (
        <>
          <h1>Hello World</h1>
          <p>App.jsx</p>
        </>
      );
    };
    
    export default App;
    ```

1. ./src 直下の index.js を以下のようにコードを修正
    ```JSX:index.js
    import ReactDOM from 'react-dom/client';
    import { StrictMode } from 'react';
    import App from './App';

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <StrictMode>
        <App />
      </StrictMode>
    );
    ```

1. プロジェクトを実行してブラウザに `Hello World` 表示されればOK
     ```Powershell
    npm start
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/994d1098-4f44-a66e-2401-99dc18f144ba.png)


# Appendix

## React とは

Wiki より引用 https://ja.wikipedia.org/wiki/React

> React (リアクト) は、Meta（旧Facebook）とコミュニティによって開発されているユーザインタフェース構築のためのJavaScriptライブラリである[3]。React.jsまたはReactJSの名称でも知られている。
> 
> Reactはシングルページアプリケーションやモバイルアプリケーションの開発におけるベースとして使用することができる。

## JavaScript フレームワークのはやり

Google Trends より引用、React が安定的にはやってる
https://trends.google.co.jp/trends/explore?geo=JP&q=React,Vue,Angular,jQuery&hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/15d0b3e5-14e7-29d9-c1de-240af3dba768.png)

## React のきほんとか雑多なめも

https://qiita.com/sueasen/items/05b45200f9e3e6a881a3
電子工作メモ - 74HC595

  - 74HC595: 8ビットシフトレジスタ
    シリアルデータ(1bit)をパラレルデータ(8bit)に変換する 
    3 本の制御線で 8bitデータを出力できるので、IOポートの拡張に使える。

    |ピン番号|ピン名|内容|
    |:--:|:--:|:--|
    | 1|Q1|パラレルデータ出力|
    | 2|Q2|パラレルデータ出力|
    | 3|Q3|パラレルデータ出力|
    | 4|Q4|パラレルデータ出力|
    | 5|Q5|パラレルデータ出力|
    | 6|Q6|パラレルデータ出力|
    | 7|Q7|パラレルデータ出力|
    | 8|GND|グランド|
    | 9|Q7'|シリアルデータ出力。<br>74HC595を複数接続するときに、上位の74HC595に接続する|
    |10|MR   |シフトレジスタを削除する。<br>Lowにするとシフトレジスタの値がクリアされる|
    |11|SH_CP|シリアルシフトクロック。<br>電圧の立ち上がり時にシリアルデータ入力レジスタがシフトする|
    |12|ST_CP|パラレル更新出力。<br>電圧の立ち上がり時にパラレルデータ出力が更新される|
    |13|OE   |イネーブル出力。HighにするとQ0-Q7が高抵抗状態になる。<br>LowにするとQ0-Q7が出力モードになる|
    |14|DS   |シリアルデータ入力|
    |15|Q0|パラレルデータ出力|
    |16|VCC|電源（2-6Vを供給する）|

- 使い方
  1. 初期化<br>MR をHighにする<br>OE をLowにする<br>SH_CP をHighにする<br>ST_CP をHighにする<br>
  1. 入力したいデータ(1bit)をDSに入力する
  1. SH_CP を立ち上げる（Low => High）シフトレジスタに格納される
  1. 上記を必要数のbit数回繰り返して、シフトレジスタにデータを一時格納する
  1. ST_CP を立ち上げる（Low => High）
  1. Q0-Q7 にシフトレジスタの状態が出力される

  - 複数台を使用することで、8bit以上のデータを出せる
    - Q7' を上位の DS に接続する
    - SH_CP と ST_CP は共通化する
    - SH_CP を立ち上げるのを必要bit数分行う
電子工作メモ - 流れる水のように光るLED


- [74HC595](/private/7a7a7261ed058514e743)


```python
import time
from my74HC595 import Chip74HC595

chip = Chip74HC595(18, 20, 21)
#Chip74HC595() == Chip74HC595(18, 20, 21) 

isDirectionMSB = False
while True:
#    x = 0x01
#    for count in range(8):
#        # 最上位ビットがQ8にくるので、Q1 -> Q8 の方向でON
#        chip.shiftOut(1, x)
#        x = x<<1;
#        time.sleep_ms(300)
#    x = 0x01
#    for count in range(8):
#        # 最下位ビットがQ8にくるので、Q8 -> Q1 の方向でON
#        chip.shiftOut(0, x)
#        x = x<<1
#        time.sleep_ms(300)

    isDirectionMSB = !isDirectionMSB
    x = 0x01
    for count in range(8):
        chip.shiftOut(isDirectionMSB, x)
        x = x<<1;
        time.sleep_ms(300)
```

```python
from machine import Pin

# 74HC595
# 16: VCC
# 15, 1~7: Q0~Q7
# 14: DS   --- Pico GPIO 18
# 13: OE   --- Pico GPIO 19
# 12: STCP --- Pico GPIO 20
# 11: SHCP --- Pico GPIO 21
# 9: Q7S
# 8: GND


class Chip74HC595(object):
    def __init__(self, ds: int=18, stcp: int=20, shcp: int=21, oe: int=19):
        self._ds = Pin(ds, Pin.OUT, value=0)
        self._shcp = Pin(shcp, Pin.OUT, value=0)
        self._stcp = Pin(stcp, Pin.OUT, value=0)
        self._oe = Pin(oe, Pin.OUT, value=0)
        self.enable()

    # 入力データをパラレル出力する
    # direction: データの方向(1: 上位ビット(MLB)がQ7に格納, 0: 下位ビット(LSB)がQ7に格納)
    # data: 出力データ(8bit)
    def shiftOut(self,direction,data): 
        self._shcp.on() 
        self._stcp.on()
        if direction: 
            for i in range(8):
                # データを左にシフトして最上位ビットのみ残す
                bit = data << i
                bit = bit & 0x80
                # シリアルデータをセット
                if bit == 0x80:
                    self._ds.on()
                else:
                    self._ds.off()
                # シフトレジスタをシフト
                self._shift_bit()
            # パラレルデータ出力
            self._send_data()
        if not direction: 
            for i in range(8):
                # データを右にシフトして最下位ビットのみ残す
                bit = data >> i
                bit = bit & 0x01
                # シリアルデータをセット
                if bit == 0x01:
                    self._ds.on()
                else:
                    self._ds.off()
                # シフトレジスタをシフト
                self._shift_bit()
            # パラレルデータ出力
            self._send_data()

    # データをクリアする
    def clear(self):
        for i in range(8):
            self._ds.off()
            self._shift_bit()
        self._send_data()
        self.enable()

    # シフトレジスタをシフトする(DS=>Q1, Q1=>Q2, ..., Q6=>Q7, Q7=>Q7')
    def _shift_bit(self):
        self._shcp.off()
        self._shcp.on()

    # シフトレジスタの状態を出力する。パラレル出力する。
    def _send_data(self):
        self._stcp.off()
        self._stcp.on()
        
    def disable(self):
        self._oe.on()
    
    def enable(self):
        self._oe.off()
```
電子工作メモ - PWMを使ったLED

- PWM(Pulse Width Modulation): パルス幅変調
  デジタル信号を使用してアナログ信号を生成する。 
  指定した周波数の矩形波をデジタルピンから出力する。

  - パルス幅: Highレベルの時間
  - デューティ比: 周期のうちパルス幅の割合（１周期のうちHighの時間がどのくらいか？）
  - デューティ比の割合が、アナログ信号としての電圧の割合になる

    |デューティ比|アナログ電圧|全電圧|
    |:--|:--|:--|
    |25% |0.8V|3.3V|
    |50% |1.6V|3.3V|
    |75% |2.4V|3.3V|
    |100%|3.3V|3.3V|

  - Pico は16個のPWMチャンネルがある。それぞれ個別に周波数とデューティ比を制御できる。
    - クロック周波数は、7Hz ～ 125MHz

  - [PWM Class](https://docs.micropython.org/en/latest/library/machine.PWM.html)
    - duty_u16()
      デューティ比を16bit(0～65535) で指定する

- PWM の使い方
  - 必要なもの
    - GPIOピン番号  : 初期化時に指定
    - 周波数        : 初期化時か freq() で指定
    - デューティー比 : duty_u16() で指定

```python
from machine import Pin, PWM
import time

#set PWM
pwm = PWM(Pin(15)) 
pwm.freq(10000)

try:
    while True:
        for i in range(0, 65535):
            pwm.duty_u16(i)
            time.sleep_us(100)
        for i in range(65535, 0, -1):
            pwm.duty_u16(i)
            time.sleep_us(100)
except:
    pwm.deinit()
```
電子工作メモ - LEDバー

```python
from machine import Pin
import time

pins = [16, 17, 18, 19, 20, 21, 22, 26, 27, 28]

flowlightPins = pins + reversed(pins)
def showFlowLight():
    global flowlightPins
    for pin in flowlightPins:
        showLed(pin)

def showLed(pin):
    print(pin)
    led = Pin(pin, Pin.OUT)
    led.value(1)
    time.sleep_ms(100)
    led.value(0)
    time.sleep_ms(100)

while True:
    showFlowLight()
```
電子工作メモ - テーブルランプ

  モーメンタリスイッチ異なり、押すごとにON/OFFを切り替える。

  - ボタンのチャタリング
    ボタンを押したり、離したりした際に、わずかの時間電圧が不安定になる。
    そのためボタンの状態を取得するときに少し時間をおいて取得する。

```python
from machine import Pin
import time

led = Pin(15, Pin.OUT)                   
button = Pin(13, Pin.IN, Pin.PULL_UP) # Pin13を入力として設定
def reverseGPIO():
    if led.value():
        led.value(0)                  # LED を ON
    else:
        led.value(1)                  # LED を OFF
        
try:
    while True:
        # ボタンが押されてなければ何もしない
        if not button.value():
            time.sleep_ms(20)

            # ボタンが押されたと判断してLEDの状態を変更
            if not button.value():
                reverseGPIO()
                # LED状態変更後にボタンが離されるまで待機
                while not button.value():
                    time.sleep_ms(20)
except:
    pass
```
電子工作メモ - ボタンとLED

  押している間だけLEDを光らせる（モーメンタリスイッチ）

  - タクトスイッチ
    - **接続方向は、足が出ている側同士がボタンを押すとつながる。逆に対面側は常に繋がっている。**

```python
from machine import Pin
import time

led = Pin(15, Pin.OUT)                   
button = Pin(13, Pin.IN, Pin.PULL_UP)   # Pin13を入力として設定

try:
    while True:
        if not button.value():
            led.value(1)                # LED を ON
        else:
            led.value(0)                # LED を OFF
except:
    pass
```
電子工作メモ - 一般的なLED

一般的なLEDを使う。

|LED|順方向電圧|最大定格電流|推奨電流|
|:--:|:--:|:--:|:--:|
| 赤色 |1.9-2.2V|20mA|10mA|
| 緑色 |2.9-3.4V|10mA|5mA|
| 青色 |2.9-3.4V|10mA|5mA|

  - 赤色を使う場合
    - GPIO からは3.3Vが出る
    - 10mAを流したい
      - 抵抗は、$ (3.3V - 2V) / 10mA = 0.13 * 10^3 = 130Ω $
      - 順方向電圧が約2V
      - 220オームの抵抗を使う場合、$ (3.3V - 2V) / 220Ω = 5 * 10^{-3} = 5mA $

  - 緑・青色を使う場合
    - 順方向電圧が約3V
    - 220オームの抵抗を使う場合、$ (3.3V - 3V) / 220Ω = 1 * 10^{-3} = 1mA $
    - 100オームの抵抗を使う場合、$ (3.3V - 3V) / 100Ω = 3 * 10^{-3} = 3mA $
    - 5Vを使う場合、$ (5V - 3V) / 330Ω = 9 * 10^{-3} = 6mA $

```python
from machine import Pin
import time

led = Pin(15, Pin.OUT)   # GPIO 15を出力として設定

try:
    while True:
        led.value(1)    # LED を ON
        time.sleep(0.5) # 0.5秒スリープ
        led.value(0)    # LED を OFF
        time.sleep(0.5) # 0.5秒スリープ
except:
    pass
```
せんせー、ダイヤモンドトランジスタってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、ダイヤモンドトランジスタってなに？

# ダイヤモンドトランジスタとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ダイヤモンドトランジスタって何？

みんな、ダイヤモンドを知ってますか。キラキラしてて、とても硬い宝石ですよね。
実は、このダイヤモンドを使って特別な電気のスイッチを作ることができるんです。
そのスイッチのことを「ダイヤモンドトランジスタ」と呼ぶんです。

## どういうこと？

トランジスタは、電気の流れをコントロールするための部品。
ダイヤモンドはとても良い性質を持っていて、電気のスイッチとして使うと、他の素材よりも優れていることがあるんです。例えば、とても高い温度でもしっかり動くとか、とても速く電気のスイッチができるとかです。

## どうしてそれがすごいの？

ダイヤモンドトランジスタがあると、今までよりもっと小さく、もっと速く、そしてもっと頑丈な電子機器を作ることができます。例えば、宇宙やとても高温の場所でも動く機械やコンピュータが作れるかもしれないです。

## だから、ダイヤモンドトランジスタってなに？

ダイヤモンドトランジスタは、キラキラのダイヤモンドを使った特別な電気のスイッチで、新しい電子機器を作るためのものなんです。

# まとめ

このように、ダイヤモンドトランジスタは、未来の電子技術をさらに進化させるための、とても興味深い部品なんです。
電子工作メモ - オンボードLED


```python
from machine import Pin
import time

led = Pin(25, Pin.OUT)   # Pico LED
#led = Pin("LED", Pin.OUT) # Pico W LED

try:
    while True:
        led.value(1)    # LED を ON
        time.sleep(0.5) # 0.5秒スリープ
        led.value(0)    # LED を OFF
        time.sleep(0.5) # 0.5秒スリープ
except:
    pass
```
Rでベクトルの各要素を別のデータシートを参照してナンバリングする

# はじめに
- Rにおいて、データフレーム中の名前で記されたデータ列に対して、名前と番号の対応表を参照して、対応する番号の列を追加するやり方をメモします。
- 言葉で説明するのは難しいので実際の実装例を見たほうが早いです。

# 動作環境
- Windows10 64bit
- R (バージョン 4.0.5)
  - dplyr (バージョン 1.0.10)　
- RStudio (バージョン 2022.12.0)

# R実装
## 前提となるデータフレームと対応表
- データフレームとして次のような表があります。
(実装用の例としてデータフレームを作っていますが、実際にはcsvなどの外部データから読み込んだりします。)

```r:R
df <- data.frame(
  SP_name = c("ブナ", "スギ", "ヒノキ", "", "スギ", "コナラ", "", "ヒノキ", "ブナ", "コナラ"),
  SP_no = NA
  )
df
   SP_name SP_no
1     ブナ    NA
2     スギ    NA
3   ヒノキ    NA
4             NA
5     スギ    NA
6   コナラ    NA
7             NA
8   ヒノキ    NA
9     ブナ    NA
10  コナラ    NA
```

- 一方で、予め決まっている種名と種ナンバーの対応表があります。
（こちらも本来は外部データとして読み込むことが多いです。）

```r:R
SP_table <- data.frame(
  name = c("スギ", "ヒノキ", "カラマツ", "ブナ", "コナラ", "ミズナラ"),
  no = 1:6
  )
SP_table
      name no
1     スギ  1
2   ヒノキ  2
3 カラマツ  3
4     ブナ  4
5   コナラ  5
6 ミズナラ  6
```

- 対応表を参照して、データフレームに種ナンバーの列を加えたいわけです。
- なお、対応表に存在しない行（この場合は種名が空欄の行）は`0`に置き換えるものとします。

## データ処理
- 結論としては下記のコードでそれが実現できます。
```r:R
df$SP_no <- if_else(df$SP_name %in% SP_table$name,
                    SP_table$no[match(df$SP_name, SP_table$name)],
                    as.integer(0))
df
   SP_name SP_no
1     ブナ     4
2     スギ     1
3   ヒノキ     2
4              0
5     スギ     1
6   コナラ     5
7              0
8   ヒノキ     2
9     ブナ     4
10  コナラ     5
```

### 中身の説明
- まず、データフレームの種名が対応表に存在するのかを論理値で評価します。
```r:R
df$SP_name %in% SP_table$name
 [1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
```
- 論理値を`if_else`関数に渡して、真ならこの後の処理に渡し、偽なら`0`とします。
```r:R
SP_table$no[match(df$SP_name, SP_table$name)]
```
- 真の場合、`match`関数でデータフレームの種名が対応表の種名のそれぞれ何番目に当たるかを抜き出し、それをインデックスとして対応表の種ナンバーを抜き出します。

# おわりに
いろいろ考えてこのやり方に落ち着きましたが、もしかしたら他にもっとスマートなやり方があるかもしれません。
参考になれば幸いです。

# 参考文献
https://stats.biopapyrus.jp/r/basic/string.html
ジュピターノートブックの内容をそのままqiitaに投稿する

## はじめに
ノートブックの内容やコードをqiitaの記事に引用する場面があり、いっそ最初から投稿を見据えた内容でノートブックを作っておいて、丸ごと貼り付ければいいのではと思いそうすることにしました。
VSCodeからですとmdファイルとしてエクスポートする項目が見当たらなかったので以下のライブラリを使用しました。
## 結論
#### nbconvertのMarkdownExporterを使う。
* 以下のコードをセルに貼り付けることで、mdファイルに変換されたノートブックを生成できます。
```Python
pip install nbconvert
```


```python
from pprint import pprint
from nbconvert import MarkdownExporter

IPYNB_FILE_PATH = "hoge.ipynb"
markdown_exporter = MarkdownExporter(exclude_output=True)
md = markdown_exporter.from_filename(IPYNB_FILE_PATH)

#テキスト生成
file1 = open('hoge.md', 'w')
file1.write('r'+"\t"+'Area'+"\n")
file1.write(md[0])
file1.close()
```




## おわりに
本当はqiitaに投稿するところまでノートブック上で行うつもりでした。次回挑戦します。
ハッカソンでGoを書いた感想

## TL;DR
+ `interface`の管理がちょっと辛かった
+ pub/prvが大文字小文字は罠
+ `enum`が分かりづらい
+ 後置型宣言好き
+ DB系つらい
+ ロガーいいのありませんか!!!!!

Kloudハッカソン#3 コードでつながる夏の友情物語に出場しました｡そこでGoをガッツリ書く機会をもらったので触った感想を書きたいと思います｡
Context: 普段はRustやTSを書く人間なので､その視点からの感想になります｡

## `interface`について
`interface` はGoにおける多態性を実現するための手段の一つで､｢外部から見た振る舞い｣の一致するものを内部の内容や実装に関わらず同じものとして扱う機能です｡
(あまり意味がない比喩を使うが)｢掃除｣を依頼するサービスがあった時､部屋がキレイになる結果がほしいのであって｡手段は何でもいいという場合､家政婦を雇って掃除をしてもらうのもいいですし､ルンバのような掃除ロボットを使用するのも手段の一つでしょう｡このような例においては､汚い部屋を掃除する機能を持つものであれば何を使っても良い場合が存在します｡つまり､`clean()`というメソッドを持つようなクラスや構造体を提供すればプログラム的にはOKなのです｡
```go:interfaceの例
package main

import (
	"fmt"
)

type Cleaner interface {
	Clean()
}

type Room struct{}

func (r *Room) RequestClean(cleaner Cleaner) {
	cleaner.Clean()
}

type Robot struct{}
type Maid struct{}

func (r *Robot) Clean() { fmt.Println("掃除したのはロボットです｡") }
func (m *Maid) Clean()  { fmt.Println("掃除したのは家政婦です｡") }

func main() {
	dirtyRoom1 := Room{}
	dirtyRoom2 := Room{}
	robot := &Robot{}
	maid := &Maid{}

	dirtyRoom1.RequestClean(robot)
	dirtyRoom2.RequestClean(maid)
}
```

掃除を依頼する`requestClean`の定義では､引数に`interface`である`Cleaner`型を要求しています｡これにより`interface`の持つ`clean()`メソッドを定義する構造体はこの`Cleaner`インターフェースを｢実装｣しているとみなすことができ､引数に取ることができます｡

Goの`interface`は､RustのTraitのように明確にコードで明示するのではなく､`interface`の持つ関数と同名のメソッドをすべて実装していれば`interface`の実装とみなすので､そこを気をつけないといけないのが少し大変違和感を覚えました｡

一応この様なエラーは出してくれるので確認はできますが､それでもこの`interface`を実装するぜ!みたいな書き方の方が安心できるという考えがあります
```
cannot use robot (variable of type *Robot) as Cleaner value in argument to dirtyRoom1.RequestClean: *Robot does not implement Cleaner (missing method Clean)
```

## ロガーが辛かった
動かしたときに､大量のログを吐いてしまい原因を探るのに苦労したのが辛かったです｡ちゃんとした仕様を理解せずにロガーを使うととんでもないことになるなぁという反省をしました｡これに関してはRustがすごい優秀なのも余計にあるかもしれません

## public/privateは大文字小文字で判定される
個々人で決めるような思想を言語側で縛られている感覚があるのと､視認性に頼るしか無いためやめてほしいなと思いました()
micro:bitで紫外線センサーを作ってみよう（その２）

[前回](https://qiita.com/UVweara/items/b64e36481b70081af18b)作った紫外線センサー。
「ウェアラブルデバイスを作る」という目的で紫外線センサーを作ったのですが、大きすぎて全然ウェアラブルじゃない・・・
とういことで、どうすれば「ウェアラブル」（着用可能）になるかを考えていきます。

# どうしたら小型化できるか
電池ボックスが大きいから、ボタン電池を使うという方法がまずひとつ。
ですが、そもそもの「micro:bitセンサーV2シールド」が大きいから、これをどうにかしたい。

ででーん！
![スクリーンショット 2023-08-28 143438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532281/37fa300e-d9f6-0d87-bfef-8cf4b26344ea.png)
これとmicro:bitメインボードを合わせただけでも、長さ10㎝を優に超えてしまう。

「ウェアラブル」（身につけられる）にするには、やはりmicro:bitメインボードのみの大きさが限界かな…と思うわけです。どうにか**micro:bitメインボードのみを持ち運べるようにできないか**を考えた結果、

**micro:bit同士で無線通信させよう**！ということになりました。

①　紫外線センサーとmicro:bitセンサーV2シールドは、カバンにつける
②　腕につけるmicro:bitメインボードで紫外線センサーの数値を受信する
の２台を無線通信させてやってみることにします。

micro:bitを腕に着けるために[バングルモジュールキット](https://www.switch-science.com/products/5272/)を使用します。

無線通信の方法については、また次回に。。
micro:bitで紫外線センサーを作ってみよう（その１）

# まずは組み立てから

[前回](https://qiita.com/UVweara/private/929e46a56c14d415ffde)購入した、[KEYESTUDIO 45 センサースターターキット](https://www.amazon.co.jp/KEYESTUDIO-%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%AD%E3%83%83%E3%83%88-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%83%93%E3%83%83%E3%83%88%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AA%E3%81%97-%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%96%E3%83%AC%E3%83%BC%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E4%BB%98%E3%81%8D/dp/B08H8C6TW5?th=1)に入っていた、『keyestudioGUVA-S12SD 3528紫外線センサー』を使って、紫外線センサーを組み立ててみました。

使用したものは下記のとおり。
・micro:bitメインボード× 1
・KeyStudiomicro:bitセンサーV2シールド× 1
・keyestudioGUVA-S12SD 3528紫外線センサー
・ジャンパーワイヤー× 3

[こちらのサイト](https://www.micro-bit.info/archives/935)を参考にさせていただきました。

micro:bitセンサーV2シールドとGUVA-S12SD 3528紫外線センサーを繋げて、micro:bitメインボードを差し込み、電池ボックスを繋げます。
（電池ボックスを繋げたことで、持ち運び可能となりました）

![スクリーンショット 2023-08-28 135133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532281/5b942534-4d92-568c-846c-f514e680ebf7.png)


# どんなコードを組むか

次に、micro:bitにどんなコードを組むかについてですが
とりあえず、センサーで読み取れる数値をメインボードに表示させることにします。

![スクリーンショット 2023-08-28 140217.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532281/5b8ae344-7246-4719-123c-03b84f42edbb.png)

これで、ボタンＡを押すと紫外線センサーの数値がメインボードに表示されるようになりました。

でも、「ウェアラブルデバイス」を目指すうえで、これだと大きすぎて、全然ウェアラブルじゃない！！身に着けられない！！

というわけで、どうしたら「ウェアラブル」になるか、というのを次回考えてみたいと思います。
ウェアラブルデバイスを作ってみよう！

# ウェアラブルデバイスって自作できるの？？

ウェアラブルデバイスって何？とか
ウェアラブルデバイスを使って何ができる？
っていうことを仲間内で話あっているうちに
実際に自分たちで作ってみよう！ということに。
(ちなみに私は非システム系のズブの素人・・・本当にできるのか？）

ちょっとだけ触ったのある **micro:bit** なら、色々センサーあるし
**Make Code**でブロックを使ってなら私にもコーディングできそう！
ということで、micro:bit でウェアラブルデバイスを作ってみることにしました。

# micro:bit でできること
まずは、micro:bitで何ができるのか、ウェアラブルデバイスとして使うならどんな機能を使うと良さそうか、ということを話し合いました。

このあたりのサイトを参考にさせていただきました。
[リビングの魔王](https://living-maou.com/microbit-matome/)
[きょうのかんぱぱ](https://kanpapa.com/today/2017/12/microbit-weatherbit.html)
[もんプロ](https://coinbaby8.com/micrbit-can-do.html)

**温度や湿度などの気象系**で攻めるのも面白そう。
どうせ作るなら（技術も知識もないけど）、主流のウェアラブルデバイス（バイタル測定や歩数計など）にない機能を使いたい。
ということで、検討の結果、UVセンサーを使うことにしました。
（ちょうど検討していた時期が５月中頃～末くらいだったので、紫外線も気になり出す時期でした）

こちらのセットに入っているUVセンサーを使用することにします。
**[KEYESTUDIO 45 センサースターターキット](https://www.amazon.co.jp/KEYESTUDIO-%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%AD%E3%83%83%E3%83%88-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%83%93%E3%83%83%E3%83%88%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AA%E3%81%97-%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%96%E3%83%AC%E3%83%BC%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E4%BB%98%E3%81%8D/dp/B08H8C6TW5?th=1)**

センサーも購入し、いざ作成へ！！
またそのお話は次回以降に。。。
Docker備忘録(初心者)

# はじめに
業務でコンテナを触り始めましたが、なかなか覚えられないので使ってる範囲の知識をまとめてみました。※随時更新予定

# 仮想化 vs コンテナのイメージ
- 仮想化
![仮想.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161388/40d6652f-4c0d-22fd-65fc-6d3016b591b0.png)

- コンテナ
![コンテナ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161388/7d208a48-49f4-62ca-8347-a578ec606128.png)

仮想化はゲストOSを都度立ち上げる必要がありますが、コンテナはその必要がありません。その分起動が早い、といった利点があります。

# Docker 用語
- Docker Engine
    - Dockerを利用するための常駐プログラム(PCにインストールする)
- image
    - コンテナの設定ファイル。imageからコンテナを起動する。読み取り専用。layler構造
- tag
    - imageのバージョン

# 基本的なコマンド
```
# ローカルのimage確認
$ docker image
```
```
# docker hubからのimage取得
$ docker pull イメージ名 
```
```
# Dockerfileからのイメージ作成

---Dockerfile
FROM イメージ名:タグ名　　　　　　　#どのimageを元にimageを作成するか
RUN パッケージ等インストールコマンド#ここに記述したコマンドを実行してミドルウェアをインストールし、imageのレイヤーを重ねる
CMD コマンド指定　　　　　　　    　#コンテナが作成された後で実行するコマンドを指定する
---

$ docker build -t ビルドしたイメージに付けるイメージ名 .

(キャッシュ無視)
$ docker build —no-cache -t docker-whale
```
```
# imageからコンテナ作成
$ docker create --name ${コンテナ名} ${imege名}
```
```
# コンテナ起動
$ docker start ${コンテナ名}
```
```
# docker pull&create&start
$ docker run ${イメージ名}
```
```
# 実行中のコンテナ表示
$ docker ps
```
```
# コンテナ削除
$ docker rm ${コンテナ名}
```
```
# コンテナからイメージを作成
$ $ docker commit コンテナ名 image名：タグ名
```

# DockerHub
※作成中
【zoho people】休日に日本の祝日をインポートする

最近zoho peopleという労務管理のノーコードSaaSを少し触ってるのですが、カレンダーに日本の祝日を設定するのに少しつまずいたので記事に書いておきます。

## 結論

googleカレンダーの日本の祝日をicsファイルでダウンロードして、zohoにインポートしました。


## 手順

<details><summary>1. googleカレンダーの日本の祝日をicsファイルでダウンロード</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/ab5936a6-a54b-64b3-c19d-a9a84bdf3826.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/c341ff9b-d1e5-ba9d-997a-5406059942e9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/ecf4a886-543d-b69d-fd62-162235af384c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/26e838e6-71af-4748-c027-3fa0612ca2f5.png)

このURLをコピーしてブラウザで開くとicsファイルがダウンロードされる。

</details>

<details><summary>2. zoho peopleにインポート</summary>

:::note warn
権限が必要です。
:::

休暇管理> 休日> 「・・・」メニュー> ICSファイルのインポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/35490c14-ff92-4571-2876-b2b7bf8eb7a2.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/bd4f1312-90fb-0242-9fe9-3bff83d3fdc0.png)
ファイルを選択して「送信」ボタンを押すと、こんな感じで登録されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487048/bcd2914b-c10c-3416-34f1-a8b0b91ce3ab.png)

</details>
GitHub、Sourcetreeの初期設定と使い方

ゲーム開発をされている皆様はご存じだと思いますが、これからゲーム制作やりたいなと考えている方に
外部サービスがGitHubとSourcetreeがあります。

それってなんなの？
と思われた方、GitHub、Sourcetreeとは今作成してるゲームの進捗状況をオンライン上に保存して
置ける外部サービスの事です。

具体的にどんなことができるの？
・誤ってPCからゲームデータが消えた時に復旧できる
・PCが壊れた時に別のPCでProjectの続きを始められる

この様にゲームを制作するにあたってとても便利なサービスになりますが、初期設定やその後の使用方法が
難しく一人で作業をしていたら詰みますｗ
今回は、以前自分用にGitHub、Sourcetreeについて走り書きしていた内容を一つにまとめたので下記条件に当てはまる方はぜひご活用ください。
・これからゲーム制作をやってみたいと思う方
・今ゲーム制作に取り組んでいるがこれらのツールを使用してこなかった方
・もう少し深く使用方法を知りたい方

また、この機能乗ってないよ、この機能について知りたいななど要望ありましたらご連絡ください。
ダウンロード↓
https://github.com/UmenoKoudai/github_manual/wiki
Solr 9 で Stream Body を有効にする

# 現象

Solr 9 にて stream body を使うAPIを利用しようとすると以下のエラーが発生する。

```json
{
  "error":{
    "metadata":["error-class","org.apache.solr.common.SolrException","root-error-class","org.apache.solr.common.SolrException"],
    "msg":"Stream Body is disabled. See https://solr.apache.org/guide/solr/latest/configuration-guide/requestdispatcher.html for help",
    "code":400
  }
}
```

また、Solr 8 までの対応方法（solrconfig.xmlを編集する）でもエラーになる。

```xml
<requestParsers multipartUploadLimitInKB="-1"
    enableRemoteStreaming="true"
    enableStreamBody="true"
    formdataUploadLimitInKB="-1"
    addHttpRequestToContext="false"/>
```

# 原因

Solr9 では仕様が変更になっている。

https://solr.apache.org/guide/solr/latest/upgrade-notes/major-changes-in-solr-9.html

> Use of stream.file, stream.url and stream.body params are no longer enabled via configuration in solrconfig.xml, nor dynamic equivalents with the config API. Older configuration now does nothing. Instead, set an env var: SOLR_ENABLE_REMOTE_STREAMING or SOLR_ENABLE_STREAM_BODY or system property equivalents.

> stream.file、stream.url、およびstream.bodyの各パラメータは、solrconfig.xmlのコンフィギュレーションや、コンフィギュレーションAPIを使用した動的な同等のコンフィギュレーションでは使用できなくなりました。古い設定は何もしません。代わりに、env varを設定します： SOLR_ENABLE_REMOTE_STREAMINGまたはSOLR_ENABLE_STREAM_BODY、または同等のシステムプロパティを設定してください。

# 対応

で、環境変数(SOLR_ENABLE_REMOTE_STREAMING, SOLR_ENABLE_STREAM_BODY)に何の値を設定するのかは書いてないように見えましたが、起動のシェルを見たらみつかりました。

環境変数(SOLR_ENABLE_REMOTE_STREAMING, SOLR_ENABLE_STREAM_BODY)に "true" をセットします。

```
SOLR_ENABLE_REMOTE_STREAMING=true
SOLR_ENABLE_STREAM_BODY=true
```

# まとめ

Solr 9 で Stream Body を有効にするには環境変数(SOLR_ENABLE_REMOTE_STREAMING, SOLR_ENABLE_STREAM_BODY)に "true" をセットします。

---

以上です。







# 参考

### OpenAI の embedding API の結果を Solr 9 に格納することも可能です。

https://qiita.com/akeyhero/items/ce371bfed64399027c23

### 関連するかもしれない記事 (Solr 9.x )

https://qiita.com/tukumo_rev1/items/00a15067daa4a6890b74

https://qiita.com/Sashimimochi/items/b52e9ea80f54d7e451ce
YYYYMMDDの形で厳密に形式を判別したい

年月日を厳密に判別したいときがあると思う。
普通にやると、値が繰り上がったりして厳密に値を取りたいのにとれなかったりする。。。

>dayjs('1970-00-00', 'YYYY-MM-DD').isValid() // true
dayjs('1970-00-00', 'YYYY-MM-DD', true).isValid() // false
dayjs('1970-00-00', 'YYYY-MM-DD', 'es', true).isValid() // false

YYYYMMDDの形の場合は以下のようにすればいいだけ。
if文とあわせてみると判定しやすい。

>dayjs(value, 'YYYYMMDD', true).isValid()

https://day.js.org/docs/en/parse/string-format