OmniAICreator/Qiita-1.07M huggingface dataset:
ChatGPTで始めるJavaScript入門⑥～ループ～

# 概要
　今回は3.JavaScriptの文法と構文について、の
　ループ処理について確認していきます。

　様々な条件で繰り返したり、オブジェクトや配列を簡単にループできる機能はしっておきたいですね。


　**※無料版なので、誤っている情報もあると思いますが、アウトプットできれば良しとします。**


# ループ
　ループはいくつか種類があるのでその辺を聞いてみます。

　【質問】
　JavaScriptの文法と構文について、ループ処理の種類、記述方法や注意点を教えてください。


【回答】
　JavaScriptには、いくつかの種類のループがあります。
　以下にそれぞれの種類と記述方法、注意点を説明します。

**forループ**
forループは、特定の回数だけ処理を繰り返したい場合に使用します。
以下のように書きます。

```javascript:for.js
for (初期化式; 条件式; 更新式) {
  // 処理
}
```

例えば、1から10までの数字を順に表示する場合は、以下のようになります。

```javascript:for.js
for (let i = 1; i <= 10; i++) {
  console.log(i);
}
```

**whileループ**
whileループは、条件がtrueである限り処理を繰り返したい場合に使用します。
以下のように書きます。

```javascript:while.js
while (条件式) {
  // 処理
}
```

例えば、10から1までの数字を逆順に表示する場合は、以下のようになります。

```javascript:while.js
let i = 10;
while (i >= 1) {
  console.log(i);
  i--;
}
```

**do...whileループ**
do...whileループは、最低でも1回は処理を実行し、その後条件がtrueである限り処理を繰り返したい場合に使用します。
以下のように書きます。

```javascript:dowhile.js
do {
  // 処理
} while (条件式);
```

例えば、1から10までの数字を順に表示する場合は、以下のようになります。

```javascript:dowhile.js
let i = 1;
do {
  console.log(i);
  i++;
} while (i <= 10);
```

注意点としては、無限ループに陥らないように条件式を確認することです。
また、forループでは初期化式で変数を宣言することができますが、letやconstを使用する場合はブロックスコープに注意する必要があります。
さらに、ループ処理によるパフォーマンスの問題にも注意する必要があります

**for...inループ**
for...inループは、オブジェクトのプロパティを列挙する場合に使用します。
以下のように書きます。

```javascript:forin.js
for (変数 in オブジェクト) {
  // 処理
}
```

例えば、以下のようなオブジェクトをfor...inループで列挙する場合は、以下のようになります。

```javascript:forin.js
const obj = { a: 1, b: 2, c: 3 };
for (let prop in obj) {
  console.log(`${prop}: ${obj[prop]}`);
}
```

この場合、a: 1、b: 2、c: 3が順に表示されます。

注意点としては、オブジェクトのプロトタイプチェーンに含まれるプロパティも列挙されることがあるため、
hasOwnProperty()メソッドを使用して、オブジェクト自身のプロパティであることを確認する必要があります。

**for...ofループ**
for...ofループは、配列や文字列などの反復可能なオブジェクトを列挙する場合に使用します。
以下のように書きます。

```javascript:forof.js
for (変数 of 反復可能オブジェクト) {
  // 処理
}
```

例えば、以下のような配列をfor...ofループで列挙する場合は、以下のようになります。

```javascript:forof.js
const arr = [1, 2, 3];
for (let num of arr) {
  console.log(num);
}
```

この場合、1、2、3が順に表示されます。

注意点としては、オブジェクトが反復可能であるためにfor...ofループを使用できるかどうかを確認することが重要です。

**forEach()メソッド**
forEach()メソッドは、配列の各要素に対して指定された関数を実行する場合に使用します。
以下のように書きます。

```javascript:foreach.js
配列.forEach(function(要素, インデックス, 配列) {
  // 処理
});
```

例えば、以下のような配列をforEach()メソッドで処理する場合は、以下のようになります。

```javascript:foreach.js
const arr = [1, 2, 3];
arr.forEach(function(num) {
  console.log(num);
});
```

この場合、1、2、3が順に表示されます。

注意点としては、forEach()メソッドは、配列の各要素に対して順番に処理を実行するため、同期的な処理しか行えないことです。


色んな種類があり、場面によってどれを使うか選択する必要があります。
特に、for、while、foreachは非常に良く使うと思います。
【SwiftUI】Hashableとidentifiableの違いをChatGPTに聞いてみる。

**私-** hashableとidentifiableの違いがマジで分からん

**ChatGPT-** 大丈夫です！もう少し簡単に説明してみますね。
Hashable と Identifiable は、どちらも Swift のプロトコルですが、役割が異なります。

**Hashable（ハッシュ可能）**
オブジェクトの中身に基づいて、ハッシュ値（一意の数値）を作成できることを保証します。
辞書のキーやセットの要素として使われることが多いです。

**Identifiable（識別可能）**
オブジェクトが一意の識別子（id）を持つことを保証します。オブジェクト同士を区別するために使われます。
SwiftUI のリストやコレクションビューなどで、アイテムの区別や更新が効率的に行われます。

**2つの違い** 
Hashable は、オブジェクトの内容に基づいてハッシュ値を生成し、データ構造（辞書やセット）で効率的に操作できるようにします。
Identifiable は、オブジェクトに一意の識別子（id）を与えて、オブジェクト同士を区別しやすくします。内容とは関係ありません。
つまり、Hashable は「中身」に焦点を当てているのに対して、Identifiable は「識別」に焦点を当てているという違いがあります。



**私-** オブジェクトの内容に基づいて　とは具体的にどういうことか？

**ChatGPT-** 「オブジェクトの内容に基づいて」というのは、オブジェクトのプロパティ（変数）や値が同じであれば、ハッシュ値（一意の数値）も同じになるということを意味しています。

例えば、以下の2つの構造体があるとします。
```swift:ContentView.swift
struct Person: Hashable {
    let name: String
    let age: Int
}

let person1 = Person(name: "Alice", age: 30)
let person2 = Person(name: "Alice", age: 30)
```

person1 と person2 は、name と age のプロパティが同じです。この場合、Person 構造体が Hashable に準拠しているため、person1 と person2 のハッシュ値も同じになります。

この性質は、辞書やセットなどのデータ構造で効率的に操作できるようになります。例えば、辞書では、ハッシュ値を使ってキーと値のペアを高速に検索できます。セットでは、ハッシュ値を使って重複する要素を効率的に除外できます。

Hashable を実装する場合、オブジェクトの内容（プロパティや値）に基づいてハッシュ値が計算されるため、同じ内容のオブジェクトは同じハッシュ値を持ちます。これにより、データ構造で効率的に操作ができるようになります。

Identifiable は、オブジェクトに一意の識別子（id）を与えることを保証するプロトコルです。この識別子は、オブジェクト同士を区別するために使われます。

Identifiable は、オブジェクトの内容（プロパティや値）とは関係なく、オブジェクトごとに固有の識別子を持つことが重要です。これにより、たとえオブジェクトの内容が同じでも、識別子が異なれば、それらのオブジェクトは異なるものとして扱われます。

Identifiable の一般的な使い方は、SwiftUI のリストやコレクションビューなどで、アイテムの区別や更新が効率的に行われることです。一意の識別子により、リスト内の各アイテムが正確に識別され、変更があったアイテムのみを更新することができます。

例えば、次のような構造体があるとします。
```swift:ContentView.swift
struct Person: Hashable {
    let name: String
    let age: Int
}

let person1 = Person(name: "Alice", age: 30)
let person2 = Person(name: "Alice", age: 30)
```
person1 と person2 は、name と age のプロパティが同じですが、id が異なります。この場合、Person 構造体が Identifiable に準拠しているため、person1 と person2 は異なるオブジェクトとして扱われます。これにより、SwiftUI のリストやコレクションビューなどで、アイテムを正確に識別して効率的に表示や更新が行われます。
フラット族着せ替えツール

# 目的
[フラット族着せ替えツール](https://pandrabox.booth.pm/items/4663263)はフラット族の服着せ替えをUnityのみの単純操作で実現するツールである。
その使用方法についてフェルの服をフラットに着せる場合をサンプルにして説明する。

# 手順
1. Unity Projectを作成
1. 着せ替えするアバター2つと必要なシェーダーをインポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/eb2ca5be-3e3c-49d4-a0c8-0d40a212a1fb.png)
1. FlatsClothChangerをインポート　※実行すると、上のメニューにFCCというものが追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/216b0cc0-c93a-7b2b-ad66-b1ef246a1872.png)　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/d58fdc4e-4d8d-ebbe-ea78-6cf60f3e0d44.png)
1. 着せ替えするアバター2つのPrefubをHierarchyにドラッグ&ドロップする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/eafe6201-e7b5-0365-f042-d5a7212207e4.png)
1. 上部メニューからFCCをクリックして、「Fel→Flat」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/69b39d2d-29ee-c1e4-ad8f-2782b1c6938b.png)
1. 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/ad21899e-0338-98d1-f473-da049cda2448.png)

# トラブルが発生した場合
1. 服を着せたアバターの名前_FCCというオブジェクトを削除して、Activeが自動的にOFFになった2つのアバターのActiveをONにすれば元に戻る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/1cbb4b0a-7639-7340-33e4-6ec13634475c.png)

# バグ報告をする場合
1. 万一バグ等で途中で動作が止まった場合次の方法でログを添付して報告頂くと問題解決に繋げることができます。
1. Consoleを押す
1. 右上の3つ点が縦に並んだボタンを押す
1. Log Entryを押す
1. 1 Lineを押す
1. 左にある[Flat/ClothChange]と書いてあるログをすべてスクリーンショットで撮影し、報告する
※必要に応じさらに詳細な情報の取得にご協力頂く場合がございます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/cc0166bc-1f57-50eb-ac09-09d7508e9709.png)

# AdvancedMenuの説明
いろいろできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/91a9fedb-2dc4-ff59-8692-33e021bc3aee.png)

## プリセットモード
上のメニューから普通にやるのと同じです。
一応ここからだけできる隠しキャラもいます。（あまり品質は良くない）
ここから実行すると後述のマニュアルモードの所に実行内容が入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/7228f820-4b62-d852-2758-3f90f6658b64.png)

## マニュアルモード
アバターのオブジェクトとか服のオブジェクト、サイズ、高さ等を微調整しつつ着せることができます。
もはやフラット族関係ない。
プリセットの服の位置やサイズに不満がある場合にここでちょっと調整する、本ツールプリセット非対応のアバターに着せる場合にどうぞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/49358b40-50f4-66db-afe1-346ced629376.png)
どういう設定にすればいいかわかっている場合は設定して「一発実行」を教えてください。
解っていない場合は「サイズ調整」を押してから服のサイズと高さを上のバーで調整して、サイズ調整ボタンがあった場所にできているボタン（適応して統合）を押してください。

## 服リセット
このツールによって作成された服を着たアバターを**削除**して、非表示になっているフラット族全てのアバターを表示します。
デフォルトアバターを読み込んで、何も改変しないでFCCで服を着せた後、このボタンを押すと元に戻るというのが想定している用途です。
マニュアルモードを何回も試すときに便利ですが、一切何の確認もせずにアバターを削除します。取り返しのつかない結果になることもあります。充分に気を付けてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/910ebf27-3269-a60f-4636-acaa9a71ca10.png)

## マニュアルモードの保存コード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935918/4ad40b42-6906-3624-4c77-c4f910b0f01a.png)

マニュアルモードの設定値を文字列で保存・読み込みできます。
例えばComodo>Felの保存コードは「FCSC,comodo,Fel,clothing,Comodo,0.8928571,0」です。
これを何処かにメモっておいて、SaveCode欄に貼り付けて、読込を押すと、その値がマニュアルモード欄に復元されます。たぶん。（同じ名称のアバターが複数あると予期せぬ動作をします。）
プリセットモード非対応アバター等でいい感じのマニュアルモード設定ができたと思った時に将来のご自身のためもしくは周囲の方々の為に設定を保管しておく用途にどうぞ。
csv出力先指定する【備忘録】

下記画像の「CSV Export」ボタン押下時、csv出力する処理を走らせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146592/f53a654e-ccb2-f1b5-f1f8-8ade0a384da8.png)


```vb:Form1.vb

Imports System.Net.Mail

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'CSVファイルを作成する準備　リストに値を追加
        Dim IstWriteText As List(Of String)
        IstWriteText = New List(Of String)
        IstWriteText.Add("りんご")
        IstWriteText.Add("ぶどう")
        IstWriteText.Add("ばなな")

        'System.IO.StreamWritterを変数として宣言
        Dim sw As System.IO.StreamWriter = Nothing

        '作成するファイル名を設定
        Dim writeFilePath As String = "./Test.csv"
        '出力先を指定する
        '----------------------------------------------------
        Dim sfd As New SaveFileDialog()
        sfd.FileName = "新しいファイル.csv"
        sfd.InitialDirectory = "C:\"
        sfd.Filter = "CSVファイル(*.csv)|*.csv;"
        sfd.FilterIndex = 0
        sfd.Title = "保存先のファイルを選択してください"
        sfd.RestoreDirectory = True
        sfd.OverwritePrompt = True
        sfd.CheckPathExists = True

        If sfd.ShowDialog() = DialogResult.OK Then
            Console.WriteLine(sfd.FileName)
        End If


        '文字コードを設定
        Dim utf_8 As System.Text.Encoding = System.Text.Encoding.UTF8

        'インスタンスを作成
        '第一引数に作成するファイル名（パス含む）
        '第二引数に上書きするしかないか（True or False）
        '第三引数に文字コード
        sw = New System.IO.StreamWriter(sfd.FileName, False, utf_8)

        'CSVファイルに書き込む準備
        'カンマ区切りの文字列を作成
        Dim writeText As New System.Text.StringBuilder
        For Each text As String In IstWriteText
            writeText.Append(text & ",")
        Next text

        'ファイルに書き込む
        sw.Write(writeText.ToString)

        'オブジェクト開放を行う
        If sw IsNot Nothing Then
            sw.Close()
            sw.Dispose()
            sw = Nothing
        End If
    End Sub
End Class


```
【日本文化の破壊】キートップに［かな文字］が無い［唯我独尊の新型パソコン］

　もうSSDの容量も不足ぎみだし、windows10パソコンからWindows11パソコンに買い替えよう・・・と調べ始めてビックリしました。**なんと、国産某社の愛用中のシリーズの最新パソコンは、キーボードから「かな文字」が無くなってしまっているのです**。かな入力を常用している私にとって、これは天下の一大事です。買い替える気力も萎えてきました。

### 「英数字キーのみ」が当然だった時代

　思えば、最初に買ったパソコン（ Apple ][ ）ではキーボードは英数字だけでした。漢字はもちろん、ひらがな・カタカナのキャラジェネさえ装備されていないパソコンですから、キーボードに「かな文字」が欲しいなどと思ったことは一度もありません。

　この時代には、BASICプログラムにコメントを書くとき、無教養を晒すようなローマ字の使用は憚られ、背伸びして英文で書かざるを得ませんでした。大袈裟ではなく、本体のプログラムを書くよりも、コメントの英作文に余計な時間がかかりました。自由に日本語のコメントが書ける現在は、天国にいるような気分です。

### 「かな入力」へのめざめ

　その後、幾星霜、Windows3.1の時代になりました。会社ではcompaqのノートパソコンを占有できるようになりました。しかし、Wordで文書を打ち込む際、それまで使っていたローマ字入力の方式では「ハイフン」と「長音記号」の使い分けが非常に煩わしく、嫌気が差してきていました。

　さて、この時代になると、海外メーカ製のパソコンでもキーボードには「かな文字」も刻印されるようになっていました。そこで、試しに「かな入力方式」に切り替えて使ってみました。当初、多少はもたついたものの、慣れてくると「ハイフン」と「長音記号」の混同もなくなり、非常に快適に作業できるようになりました。これが、かな入力を常用するようになった経緯です。

　ローマ字入力にしても、かな入力にしても、いまだに人差し指一本での入力作業ですが、**打鍵数から見て「かな入力」のほうが倍以上に効率的です。もう、ローマ字入力には戻れません**。

### 結論

　海外資本の手に落ちたとはいえ、**日本で販売するパソコンである以上、「かな文字」の無いキーボードなどあり得ません**。メーカーは即刻、悔い改めるべきです。

　今時の流行語である「多様性の尊重」とは、「かな文字なしのキーボードも、かな文字つきのキーボードも、広く存在価値を認め合って共存していきましょう」という意味ではありません。「**汎用性が高く慣れ親しんできた［かな文字つきのキーボード］から［ひらがな］だけを差別・排除するのは止めましょう**」という意味です。そのほうが、これまた流行語の「SDGs」にも適った製品になるはずです。

**みなさん、これからも、日本の伝統ある大切な文化を守り続けて行きましょう。**
OSSのCOBOLコンパイラー

***業務系システムエンジニア（SIer）となってCOBOLを使用することになったが、学習用環境をどのように作成すれば良いの？となっている方も多いと思う。***
***この私も新卒で入って、研修はJavaで行い、いざ現場配属されたらCOBOLで開発となり右往左往した記憶があります。***
#### ４月という季節柄、新卒で業務系SIerとしてスタートを切る方も多いと思う。COBOLを勉強するための最初の一歩である開発環境、中でも無償で使用可能なコンパイラーを３つご紹介します。

どれも公式サイトを見ながら導入すれば、簡単に開発環境をと整えられます。


※2023 年 4 月 2 日時点の調査結果に基づく

| No. | 提供元             | コンパイラー    | サービス内容                                                                                                                               | URL                                      |
| --- | ------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| 1   | GNU                | GnuCOBOL            | COBOL ソースのコンパイル過程で C 言語ソースを出力する                                                                                      | https://gnucobol.sourceforge.io/         |
| 2   | OSS コンソーシアム | Opensource COBOL    | ・COBOL ソースのコンパイル過程で C 言語ソースを出力する<br>・OpenCOBOL(GnuCOBOL)に日本特有のビジネス環境に即したカスタマイズが施されている | http://www.osscons.jp/osscobol/download/ |
| 3   | OSS コンソーシアム | Opensource COBOL 4J | COBOL ソースのコンパイル過程で Java ソースを出力する                                                                                       | http://www.osscons.jp/osscobol/download/ |


## GnuCOBOL

[GNU プロジェクト](https://gnucobol.sourceforge.io/)で開発している。  
前身は、西田圭介氏が設計していた OpenCOBOL。
COBOL コンパイラー。  
C 言語ソースが生成される。  
COBOL コンパイルの過程で COBOL を中間 C ソースに変換し、モジュールを作成する。
9740 以上の NIST COBOL 85 test suite のテスト項目をクリアし、1000 以上の内部チェックを実施している。  
IDE でデバッカーを使用したり、GNU gdb もサポートしている。

## Opensource COBOL

[OSS コンソーシアム](http://www.osscons.jp/osscobol/download/)が開発している 。  
COBOL コンパイラー。  
C 言語ソースが生成される。
COBOL コンパイルの過程で COBOL を中間 C ソースに変換し、モジュールを作成する。
OpenCOBOL(GnuCOBOL)に日本特有のビジネス環境に即したカスタマイズが施されている。

## Opensource COBOL 4J

[OSS コンソーシアム](http://www.osscons.jp/osscobol/download/)が開発している 。  
COBOL コンパイラー。  
Java ソースが生成される。
COBOL コンパイルの過程で COBOL を中間 Java ソースに変換し、Java コンパイラでバイトコードを生成する仕組み。

### 実装状況

下記の実装済みリストにある機能は NIST COBOL85 test suite でテストされており,99% のテストケースをパスしています.

＜実装済み＞  
基本的なデータ操作 (MOVE, COMPUTE, ... )
制御文 (IF, PERFORM, GO TO, ...)
DISPLAY 文, ACCEPT 文
CALL による呼び出し
SEQUENTIAL ファイルの入出力機能
RELATIVE ファイルの入出力機能
INDEXED ファイルの入出力機能
SORT 文
組み込み関数 (ACOS, LENGTH, MAX, ...)

＜既知の不具合＞  
同一ソースコード内の別プログラムの CALL ができない.
CSVから特定の列のデータだけを抜き取るスクリプトを書く

# 何をしたか
CSVから特定の列のデータだけを抜き取るスクリプトを作成しました。

# 具体的な内容
下記のようなCSVで、会員の情報があります。
このデータのID情報のみ配列で取得することが目的です。

```plaintext:list.csv
id,last_name,first_name,gender
16452,John,Moore,0
64366,Barbara,Stanwyck,1
35434,Paris,Williams,1
66466,Hailey,Brown,1
56436,Mike,Miller,0
66468,Sara,Anderson,1
72854,Carl,Taylor,0
87537,Chad,Smith,0
97273,Paul,Harris,0
10346,Bella,Freud,1
.
.
.
```

ちょうどRuby Silverの資格取得のため学習していた「IO」クラスが使えると思い、スクリプトを書いてみました。

# どのようにしたか
- 組み込みライブラリである**IOクラス**を利用する方法
- 添付ライブラリである**CSVクラス**を利用する方法

## IOクラスを利用する方法
`IO.foreach`を利用することで直接ファイル名を指定しつつ、
ファイルの各行に対して処理を実行できます。

ファイルの各行に対しては、
`"id,last_name,first_name,gender\n"`というような文字列が渡ってくるため、
`String#split`を利用してカンマを対象に配列に変換します。

この結果として
`["id", "last_name", "first_name", "gender\n"]`という文字列の配列が返ってくるため、
IDが格納されている配列の0番目を`Array#first`によって取得しています。

取得した要素をresultという空の配列に`Array#<<`を利用して破壊的に追加していきます。

```ruby
result = []

IO.foreach('list.csv') {|row| result << row.split(',').first }

# headerを取り除く
result.shift #=> "id"

IO.write('ids.rb', result)
```

resultでは最初の要素にCSVファイルのheaderの「"id"」が入っているため
`Array#shift`で破壊的に取り出しています。

ファイルへの書き込みは、`IO.write`を利用しました。

```ruby:ids.rb
["16452", "64366", "35434", "66466", "56436", "66468", "72854", "87537", "97273", "10346"]
```


## CSV添付ライブラリを利用する方法
`require`で添付ライブラリを読み込み、
`CSV.foreach`にキーワード引数`headers`を`true`にすることで、
CSVファイルの一行目をヘッダとして扱うため、
headerを取り除いて処理を実行できます。
[foreachの引数に指定できるオプションの参考文献](https://docs.ruby-lang.org/ja/latest/method/CSV/s/new.html)

CSVクラスを利用する場合、ブロック引数には各行のカンマ区切りの配列が渡されます。
そのため、idが格納されている0番目を`Array#[]`で取得しています。

```ruby
require 'csv'

result = []

CSV.foreach('list.csv', headers: true) { |row| result << row[0] }

IO.write('ids.rb', result)
```

# まとめ
こんなスクリプトをわざわざ作らなくても、
VSCodeの正規表現を利用したり、
そもそもCSVファイルにデータを出力する際にidだけにすればいいのでは？とも思いましたが、
Ruby Silverの学習のために利用してみました。

Ruby Silverの学習の際に`File`、`IO`、`Dir`あたりのクラスは普段あまり利用しないため覚えるのが大変でしたが、
実際に何か処理を作ってみると記憶に残りやすいなと思いました。


# 参考文献
- [Ruby技術者認定試験合格教本 Silver/Gold対応　Ruby公式資格教科書](https://www.amazon.co.jp/gp/product/B016B877OG/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)
- [Rubyリファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/index.html)
RubyでAtCoder ABC291(A, B, C, D)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC291のA, B, C, Dを解きました。備忘録として解き方をまとめていきたいと思います。

# A - camel Case
https://atcoder.jp/contests/abc291/tasks/abc291_a
```ruby:a-291.rb
s = gets.chomp.chars
arr = *"a".."z"
s.each_with_index do|i, j|
    unless arr.include?(i)
        puts j + 1
        exit
    end
end
```
<追記>
コメントでいただいた別解になります。正規表現を使った書き方で[A-Z]がAからZまでを列挙したもので、これを使って大文字があるかどうかを判定できるようです。
```ruby:別解
s = gets.chomp
puts s.index(/[A-Z]/) + 1
```
## 解説
与えられた文字列に対して、先頭から調べていき大文字ならその時のindexを出力して終了します。

# B - Trimmed Mean 
https://atcoder.jp/contests/abc291/tasks/abc291_b
```ruby:b-291.rb
n = gets.to_i
x = gets.split.map(&:to_i).sort
n.times do
    x.shift
    x.pop
end
puts x.sum.to_f / (3 * n)
```
<追記>
コメントでいただいた別解になります。fdivメソッドは便利そう！
```ruby:別解
n = gets.to_i
xs = gets.split.map(&:to_i).sort

puts xs[n...4 * n].sum.fdiv(3 * n)
```
## 解説
まず、与えられた集合xをsortしておきます。そして、xの先頭と末尾の要素を取り除くことをN回繰り返します。最後に、残ったxの集合の要素の平均値を出力すればOKです。なお、答えは浮動小数点型で計算する必要があります。

# C - LRUD Instructions 2
https://atcoder.jp/contests/abc291/tasks/abc291_c
```ruby:c-291.rb
n = gets
s = gets.chomp.chars
x, y = 0, 0
hash = {[0, 0]=>true}

s.each do|i|
    if i == "R"
        x += 1
    elsif i == "L"
        x -= 1
    elsif i == "U"
        y += 1
    else
        y -= 1
    end

    if hash[[x, y]]
        puts "Yes"
        exit
    else
        hash[[x, y]] = true
    end
end
puts "No"
```
## 解説
まず、x, yをそれぞれ0で初期化し、高橋君が通った座標を記録する連想配列hashを用意します。そして、与えられた文字列に対してx, yを変更していき、すでに通っていればYesを出力して終了、そうでなければその座標をのvalueをtrueにします。逆に、最後までYesとなるような場合がなければNoを出力します。
# D - Flip Cards
https://atcoder.jp/contests/abc291/tasks/abc291_d
```ruby:d-291.rb
n = gets.to_i
arr = Array.new(n){gets.split.map(&:to_i)}

dp = Array.new(n){[0, 0]}
dp[0] = [1, 1]
mod = 998244353
for i in 1..n - 1
    2.times do|pre|
        2.times do|nxt|
            dp[i][nxt] += dp[i - 1][pre] if arr[i - 1][pre] != arr[i][nxt]
        end
    end
    dp[i][0] %= mod
    dp[i][1] %= mod
end
puts (dp[n - 1][0] + dp[n - 1][1]) % mod
```
## 解説
（公式の解説を参考にしました）

<方針>
DP（動的計画法）を使い、dp[i][j]：i枚目の面がj（j=0なら表、j=1なら裏）でそれまでに条件を満たす枚数とします。

<実装方法>
まず、1枚目は表裏ともに1通りなので`dp[0]=[1,1]`で初期化します。そこから順に条件を満たすなら１つ前の要素までの枚数を足していきます。そして、最後のカードの面のそれぞれの状態における条件を満たす枚数を足すことで答えを求めることができます。

# 終わりに
どういった時にDPを使うのかの見分けがまだつかないので、数をこなして慣れていきたいと思います！

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166

# 参考
https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html
Laravel10 x tableplus

# Laravel10の環境構築（DB接続時のつまずきポイントと解消方法）

### 前提条件
    * Laravel sailを使用

### mysqlへのログイン方法
    * ```sail mysql```

### tableplusへの接続方法
.envの初期値
```
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=myblog
DB_USERNAME=sail
DB_PASSWORD=password
```

しかし、tableplus接続の際、ユーザーネームがsailだとエラーとなった。
```root```にしたところ接続できた
[参考ドキュメント](https://readouble.com/laravel/10.x/ja/sail.html#:~:text=%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%93%8D%E4%BD%9C-,mysql,-%E3%81%8A%E6%B0%97%E3%81%A5%E3%81%8D%E3%81%8B%E3%82%82%E3%81%97)

[参考記事](https://reffect.co.jp/laravel/laravel-sail)
ChatGPT APIの取得方法

# はじめに
今回は、ChatGPTのAPIをどのように取得するのか書いていこうと思います。

# 取得方法
### ログイン
まずは、[https://openai.com/product](https://openai.com/product)にアクセスし、`Transforming work and creativity with AI`の`Get started`からログインします。

### APIキーの取得
ログイン後、画面右上の`Personal`から`View API Keys`を選択します。
遷移後の画面に`+ Create new secret Key`というボタンがあるので、それをクリックします。
クリック後、画面にAPIキーが表示されるので保管しておきます。
- このAPIキーは一度しか表示されないので確実にメモしておいてください。

以上で、APIキーの取得は終わりです。
【Linux】Windows11用、WSL2へのUbuntuの環境構築方法【Windows11】

## インストール手順
1. WSL2のインストール
1. Linuxディストリビューションのインストール
1. Ubuntuの初期設定

## WSL2のインストール
1\. Windowsの「コントロールパネル」→「プログラム」→「Windows の機能の有効化または無効化」で以下の3つの項目にチェックを付ける。
* 「Hyper-V」
* 「Linux 用 Windows サブシステム」
* 「仮想マシンプラットフォーム」

***
2\. ターミナルを管理者として実行し、以下の3つのコマンドを打つ。
まずLinux 用 Windows サブシステムを有効にする。
```terminal
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```
仮想マシンの機能を有効にする。
```terminal
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
WSL2を既定のバージョンとして設定する。
```terminal
wsl --set-default-version 2
```
***

3\. Linux カーネル更新プログラム パッケージをダウンロードし、インストールする。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

## Linuxディストリビューションのインストール
コマンドプロンプトを管理者権限で実行する。

以下のコマンドでLinuxディストリビューションの一覧を確認できる。
```
wsl --list --online
```

`wsl --install -d <パッケージ名>`でインストールができる。今回はUbuntu-22.04をインストールする。
```
wsl --install -d Ubuntu-22.04
```

## Ubuntuの初期設定
Ubuntuを起動する。（Windowsの「すべてのアプリ」から選択して実行できる。）

そこでユーザーネームとパスワードを設定すればok。

:::note warn
ちなみにユーザー名には大文字は指定できない。以下が設定ファイルのユーザ名の正規表現の設定である。
```text:/etc/adduser.conf
NAME_REGEX="^[a-z][-a-z0-9_]*\$"
```
:::

## VS CodeでUbuntuを使う
この拡張機能をVS Codeでインストールする。

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl

VS Codeのウィンドウ上で「F1」を押したら出てくる検索窓でWSLと検索。結果のうち「Remote-WSL: New Window using Distro」を選択すれば、Ubuntuのコンソールが出てくる。

## Windowsとのファイルの連携
この記事が役に立つので参照したり。

https://qiita.com/quzq/items/1096c638c0d86795be13

## 参考

https://www.kkaneko.jp/tools/wsl/wsl2.html

https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package

https://qiita.com/_masa_u/items/d3c1fa7898b0783bc3ed

https://qiita.com/Kal24w/items/467dd26c2e5306b3ba59
MATLABとSimulink APIによるモデル開発、シミュレーションの自動化、効率化方法

とある現役ソフトウェアエンジニアです。
当方の技術ブログにて、MATLAB、Simulinkに関する技術記事をブログで紹介しています。

Simulinkは、モデルベースの設計（MBD）で広く使用されるツールであり、システムのモデル化、シミュレーション、コード生成が可能です。Simulinkは、GUIを介して直感的なモデリング環境を提供していますが、APIを使うことで、コマンドラインからSimulinkを制御することができます。この記事では、SimulinkのAPIを使用する場面をいくつか紹介します。


https://toarusw.com/matlab-simulink-apiutil/

本記事の目次は以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118344/9c5f94b9-7ad6-4fa2-31f7-9d3911185344.png)


さくっと読めますので是非ご覧ください^^
Google Apps Scriptで2つの画像を重ね合わせてPDFとして保存する

Google Apps Scriptを使って2つの画像を重ね合わせてPDFとしてGoogleドライブに保存させる方法です。以前はHTML canvasが使えないと思っていたのですが、実は使えました。ただし、作成されるPDFには余白があります（この余白は削除できませんでした）。

ちなみに、canvasが使えないと思った頃は、Googleスライドを使って合成していました：

https://qiita.com/takatama/items/b21cb8e194836be15ac8

# 2つの画像を合成してPDFファイルを作成する

以下がコードです。

```javascript:Code.gs
function toDataUrl(fileId) {
  const blob = DriveApp.getFileById(fileId).getBlob();
  return `data:${blob.getContentType()};base64,${Utilities.base64Encode(blob.getBytes())}`;
}

function combineTwoImages() {
  const baseFileId = '...';
  const stampFileId = '...';
  const baseImage = toDataUrl(baseFileId);
  const stampImage = toDataUrl(stampFileId); 

  // stampの位置とサイズ
  const x = 481;
  const y = 215;
  const width = 100;
  const height = 100;

  const html = `
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Canvas Example</title>
	<style>
		canvas {
			border: 1px solid black;
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width="794" height="1123"></canvas>
	
	<script>
		const canvas = document.getElementById('myCanvas');
		const ctx = canvas.getContext('2d');
    const baseImage = new Image();
    const stampImage = new Image();
    baseImage.onload = function() {
      const ratio = Math.min(canvas.width / baseImage.width, canvas.height / baseImage.height);
  		ctx.drawImage(baseImage, 0, 0, baseImage.width, baseImage.height, 0, 0, baseImage.width * ratio, baseImage.height * ratio);

      stampImage.onload = function() {
    		ctx.drawImage(stampImage, ${x} * ratio, ${y} * ratio, ${width} * ratio, ${height} * ratio);
      }
      stampImage.src = '${stampImage}';
    }
    baseImage.src = '${baseImage}';
	</script>
</body>
</html>
  `
  const blob = Utilities.newBlob(html, MimeType.HTML).setName('images.pdf');
  DriveApp.createFile(blob.getAs(MimeType.PDF));
}
```

このGoogle Apps Scriptのコードは、2つの画像を合成してPDFファイルを作成するためのコードです。コードの概要は以下の通りです。

1. toDataUrl関数は、GoogleドライブのファイルIDを受け取り、そのファイルのデータURLを返します。
2. combineTwoImages関数は、2つの画像を合成してPDFファイルを作成するためのコードです。
3. baseFileIdとstampFileIdは、それぞれの画像のGoogleドライブのファイルIDを表しています。
4. toDataUrl関数を使用して、2つの画像のデータURLを取得し、baseImageとstampImageに格納します。
5. x、y、width、heightは、スタンプ画像の位置とサイズを表します。
6. HTML文字列を生成し、それをPDFファイルに変換してGoogleドライブに保存します。
7. HTMLには、2つの画像をキャンバスに描画するJavaScriptが含まれています。それぞれの画像のロードが完了したら、ctx.drawImage関数を使用して画像を描画します。baseImageは、画像を最大限に大きくするための比率を計算し、キャンバスに描画されます。stampImageは、指定された位置とサイズで描画されます。
【論文読み】階層的クラスタリングを用いたドライバの運転特性抽出

## はじめに
こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「階層的クラスタリングを用いたドライバの運転特性抽出」という論文です。  

- タイトル： 【論文読み】階層的クラスタリングを用いたドライバの運転特性抽出  
- 出典： 横山 達也, et al.; 情報処理学会、 2021   
- URL： https://www.ipsj.or.jp/award/9faeag0000004emc-att/1D-04_1.pdf  


## 概要
類似度の分析に有用な階層的クラスタリングを新たに適用し、運転特性に対応付けられる特徴量を検討する。
「直進走行時」の車載データを対象に「加減速による前後方向の挙動」の特徴量に着目する。    
個人差を考慮した運転支援、運転特性に応じた事故防止対策、の関連研究がある。  

## 特徴
- 階層的クラスタリングを適用  
- 「加減速による前後方向の挙動」、「車間距離」に関わる特徴量。合計 26 項目に対し、統計値(最大値、最小値、平均値、標準偏差値、四分位数)を算出し、階層的クラスタリングに用いる。  
- 距離測定方法はウォード法、距離尺度はユークリッド距離を採用。  
- クラスタリング結果と各ドライバのアンケート調査結果・入力した特徴量候補の関係を比較することで、運転特性に対応付けられる特徴量を抽出。  
- 被験者6名のデータを用いた。1周約30分かかるコースを各被験者が8回走行した際のデータ(合計48試行分)を用いる。  
- 今回は被験者数とほぼ同数の5つのクラスタ(Cluster1～Cluster5)に分類。  


## 想定される適用例
- 各計測データを全て使ってクラスタリングし、各自がどのクラスタに所属するかを分析する  
- クラスタの結果と個人特性の関係性を分析する  


## 参考
- [階層的クラスタリングを用いたドライバの運転特性抽出](https://www.ipsj.or.jp/award/9faeag0000004emc-att/1D-04_1.pdf)
【Rails】migrateファイル内修正

# migrateファイルを修正

migrate内は修正方法があります！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111780/64582e5f-3925-f21b-f0c5-c3361cd45eb4.png)

# ①現在のファイル状況確認

下記のコマンドを入力
```php
$ rails db:migrate:status
```
するとファイルがUPと出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111780/76f64375-1970-a2cc-c1e5-ec28c224d797.png)

この状態のまま内容を修正しても反映されません！！
今回は、favoriteファイル修正したいとしましょう。

次の方法で修正できる環境に変えましょう

# ②migrateファイル修正できるようにする
下記のコマンドを打ってください。

```php
& rails db:rollback STEP=3
```
すると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111780/21575bdf-96c4-17ac-de34-d8586521bd08.png)

このように下から3行目まで「down」という表示に変わりました。
downになってからようやく修正がOKになります。


# ③修正後

中身を修正したら、次の作業に移ります。

念のため、ファイルがdownになっているか確認しましょう
```php 
$ rails db:migrate:status
```

3行目まで間違いなくdownになっていたら、次に
```php
$ rails db:migrate
```
を打って更新かけましょう！

全てがUPになっているか「rails db:migrate:status」で確認しましょう！！


これで変更した内容が反映されます！


※初めての時は、downにすることを知らず他のファイル同様に
修正して「変わってないけどなんで！！」となってました～
「rails db:rollback」をすることでdownにして修正することを
メンターさんに教えてもらい解決できました！
【Go言語入門】Goのレシーバーとは？2種類のレシーバーを使い分ける方法

## はじめに

Goのレシーバーって何？って思った人に向けて、Goで使われるレシーバーという概念と、その中で重要な値レシーバーとポインタレシーバーの2種類の違いと使い分けについて解説します。

## Goの構造体について

まず前提として、Goでは構造体を使って複数のデータをひとまとめにできます。
構造体は次のように定義します。

```go
type Person struct {
    Name string
    Age  int
}
```
構造体のインスタンスは以下のように、初期化することができます。

```go
person := Person{Name: "taro", Age: 42}
```

## レシーバーとは何か？

レシーバーとは、構造体に関連付けられた関数（メソッド）を定義するための機能です。
これにより、構造体のインスタンスに対して操作を行うことができます。
以下にコード例を示します。

```go
// 構造体の定義
type Person struct {
    Name string
    Age  int
}

// Person構造体にGreetというメソッドを定義する
func (p Person) Greet() {
    fmt.Printf("Hello, I'm %s, %d years old.\n", p.Name, p.Age)
}

func main() {
    person := Person{Name: "Taro", Age: 42} 
    person.Greet() // Hello I'm Taro, 42 years old.
}
```

この例では、`Person`構造体に`Greet`メソッドを追加しています。
`func (p Person) Greet()` の部分で、`p Person`がレシーバーとなっています。
これにより、`Person`型の変数（オブジェクト）から`Greet`を呼び出すことができます。

要するに、レシーバーを使うことで、**構造体に関連する関数を定義する**ことができるのです。

## 値レシーバーとポインタレシーバー

レシーバーには、「値レシーバー」と「ポインタレシーバー」の2種類があります。

- 値レシーバー：構造体のコピーを受け取る
- ポインタレシーバー：構造体のポインタ（参照）を受け取る

構造体の値をメソッド内で変更したい場合、ポインタレシーバーを使う必要があります。

それでは、具体的な例を見ていきましょう。

### ポインタレシーバーの使用例

次の例では、`Person`構造体に`Birthday`メソッドを追加しています。
このメソッドはポインタレシーバーを使用しているため、構造体の値を変更することができます。

```go
func (p *Person) Birthday() {
    p.Age++ // ポインタレシーバーを使っているので、構造体の値を変更できる
}

func main() {
  person := Person{Name: "Taro", Age: 42}
  person.Birthday()
  person.Greet() // Hello, I'm Taro, 43 years old.
}
```

### 値レシーバーの使用例

```go
func (p Person) Birthday() {
    p.Age++ // 値レシーバーを使っているので、呼び出し元の構造体は変更されない
}

func main() {
  person := Person{Name: "Taro", Age: 42}
  person.Birthday() // 値が変わらない
  person.Greet() // Hello, I'm Taro, 42 years old.
}
```

値レシーバーを使用した場合は、構造体の中身が変更できないことに注意しましょう。

## 値レシーバーとポイントレシーバーの使い分け

使い分けについては、使用例で確認したとおり、構造体の値を変更するかどうかによって判断することができます。

それ以外にも、構造体が大きい場合は、効率性の観点から、ポインタレシーバーを使用するといった選択方法があります。

GoのWikiに記載されていた値レシーバーとポインタレシーバーの使い分けを表にまとめました。

| 状況                                       | ポインタレシーバー | 値レシーバー |
|--------------------------------------------|----------------|------------|
| レシーバーがmap, func, chan                | ×              | 〇          |
| レシーバーがスライスでリスライス・再割当てがない  | ×              | 〇          |
| レシーバーが小さい配列や構造体でポインタを持たない（プロファイリングを行った上で判断する）   | ×              | 〇          |
| メソッドがレシーバーを変更する必要がある       | 〇              | ×          |
| レシーバーが変更される可能性がある            | 〇              | ×          |
| レシーバーが大きな構造体や配列、同期フィールドを含む | 〇              | ×          |

基本的には、同じ型で値レシーバーとポインタレシーバーを混在しないことにも気をつけましょう。もし迷った場合は、ポインタレシーバーを使うことが推奨されています。

詳細については、以下のリンクをご覧ください。
https://github.com/golang/go/wiki/CodeReviewComments#receiver-type

## まとめ

Goのレシーバーとは、構造体に関連付けられた関数（メソッド）を定義するための機能でした。値レシーバーとポインタレシーバーを状況に応じて上手に使いこなしましょう！

## 参考

https://medium.com/globant/go-method-receiver-pointer-vs-value-ffc5ab7acdb

https://go-tour-jp.appspot.com/methods/4

https://go.dev/doc/faq#methods_on_values_or_pointers

https://stackoverflow.com/questions/27775376/value-receiver-vs-pointer-receiver

https://github.com/golang/go/wiki/CodeReviewComments#receiver-type
明日から入場だ。未経験SESのドキドキ

# 明日から配属　ちょー緊張　≪≫≪≫≪≫
明日から正式に配属されることとなりました。
１月からここに就職して三か月間研修を行っていました。

研修中はというと、、、「在宅幸せ～～～！、でも学習効率低すぎて不安だなぁ、、」。
ま、自分で決めた道だからやるしかないぞ俺！って感じでした。

あーっという間に３か月が過ぎ、現場配属を明日に控えて、「やばっっ！超不安、うまくやっていけるかな、まずは人間関係、いじめられないかな！」＜ー技術面よりまず人が怖い>_<;技術面は言わずもがな、えぐ怖い、、、

でもやるしかない、ちょーー不安だけどやるしかない、この世界に全力で尽くすんだ！

明日から頑張ります！！
【AI】入門記事リンク集【ChatGPT / GitHub Copilot / Notion AI】

# 0. はじめに
大阪の受託開発エンジニアの、kazumakishimoto([@kazuma_dev](https://twitter.com/kazuma_dev))です！

## 0-1. 全体の流れ
> [1.ChatGPT](#1-chatgpt)
> [2.Copilot](#2-copilot)
> [3.NotionAI](#3-notionai)

## 0-1. TL;DR
- ChatGPT / GitHub Copilot / Notion AIの教材や参考リンク集まとめ

# 1. ChatGPT

https://zenn.dev/stafes_blog/articles/76e84b39f3de94

https://zenn.dev/umi_mori/articles/what-is-gpt-4

https://zenn.dev/waarrk/articles/a6868cea7549de

https://zenn.dev/nameless_sn/articles/chatgpt_cheat_sheet

https://zenn.dev/nameless_sn/articles/the_pros_and_cons_about_chatgpt

https://zenn.dev/kazuwombat/articles/5617468b97fa3f

https://zenn.dev/fumi_sagawa/articles/932bcaafd28c53

https://zenn.dev/vim_jp/articles/26eb77fea1e9a4

https://zenn.dev/bolmatu/articles/4cacb9072750fe

https://qiita.com/tak001/items/7605f0be7b424118e5a5

https://qiita.com/tak001/items/748f648900dc88419434

https://qiita.com/tak001/items/720e279f70222f065ab3

https://qiita.com/ryome/items/0408153a685848cc33dc

https://qiita.com/tak001/items/6a39da97e2f3e5d4eb08

https://qiita.com/sakasegawa/items/82069c97a1ee011c2d1e

https://qiita.com/devneko/items/0dc9fd8b37419d9e369c

https://qiita.com/sakasegawa/items/5a5bb4beca0a435d8535

https://qiita.com/ot12/items/6b6b15c71c7676a683d5

https://chrome.google.com/webstore/detail/superpower-chatgpt/amhmeenmapldpjdedekalnfifgnpfnkc

https://chrome.google.com/webstore/detail/webchatgpt-chatgpt-with-i/lpfemeioodjbpieminkklglpmhlngfcn

https://chrome.google.com/webstore/detail/sharegpt-share-your-chatg/daiacboceoaocpibfodeljbdfacokfjb

# 2. Copilot

https://zenn.dev/gon/articles/06fe05730f8294

https://zenn.dev/riya_amemiya/articles/7a7cec9244e4b9

https://zenn.dev/ichii731/articles/8ec3114381c6f6

https://qiita.com/tak001/items/c6bca65d67843c24478f

https://qiita.com/flutter_daisuki/items/6d6e663a089c1a26fa56

https://qiita.com/tak001/items/9ef12a924469b0370c01

# 3. NotionAI

https://zenn.dev/umi_mori/articles/notion-ai-writing-blog-for-engineer-tips

https://zenn.dev/takiko/articles/fb73f70581e08f

https://zenn.dev/nokonpt/articles/notionai-rewrite

https://qiita.com/namizatork/items/b23edefc4165ecc8fda1

https://qiita.com/good_engineer00/items/736c7ef8d2d64bdecf86
【MySQL】MySQLにおけるデータ型

## データ型
MySQLには数値、文字列、日付などのデータの種類に応じた型がある。
### 数値
MySQLで扱える数値には、整数を扱うための`INT型`や、実数（小数点がついた値）を扱うための`FLOAT型`がある。
固定小数点は金銭データを扱う場合や正確な精度を保持することが重要な場合に使用し、範囲の広い実数を扱いたい場合は浮動小数点を使う。

・数値型
|数値の種類|代表的データ型の種類|
|-|-|
|整数|INT、BIGINT、TINYNTほか|
|固定小数点|DECIMAL、NUMERICほか|
|浮動小数点|FLOAT、DOUBLEほか|

・文字列型
|型|特徴|
|-|-|
|CHER|固定長文字列|
|VARCHAR|可変長文字列|
|TEXT|文字列データを扱うデータ型で格納できるデータのサイズを指定しない|

`CHAR型`は長さ５とする場合、CHAR(5)と表す。仮に、「DOG」という3文字をCHAR(5)に格納すると2文字分余るが、余った部分にはスペースが入ることで長さが５になる。これを`固定長`という。データを取り出すときはこのスペースは削除される。
`VARCHAR型`も長さを５とする場合、VARCHAR(5)と表すが、「DOG」という3文字を格納すると長さは3と表現される。
なお両方とも、指定した文字列を超えた値が入力されると、<INS>**オーバーした分がカットされる**。

#### NULL値
`NULL値`はデータが存在しないことを表す値で、どの型にも入れることができる。
<INS>**レコードが作成されたものの、データを追加する際に値が渡されなかったカラムの値はNULLになる**。
Powershell で配列の作り方

# はじめに

ネットで検索すればすぐに出てきますが、自分の中では配列の作成方法が曖昧だったので簡単にまとめることにしました。


# 作り方

```
変数 = @('配列のデータ１','配列のデータ2',以下略)
```
最初に変数を宣言して@をつけ（）以下に格納したいデータを記入していきます。
変数には初めに「$」をつけます。


以下の通りに作ってみました。
```
$todouhuken = @(
'yamanashi'
'shizuoka'
'kanagawa'
)
```

ではいくつか出力させてみます。
```
$todouhuken
$todouhuken.count
$todouhuken[0]
```


出力結果は以下の通りです。
```
yamanashi
shizuoka
kanagawa
3
yamanashi
```

最初は変数「todouhuken」自体になるので格納した３つのデータが全て出力されます。
２番目は.countとすることで配列の数が出力されます。
３番目は[0]なので一番最初のデータ「yamanashi」が出力されます。１番目は「０」となるのが注意点です。

# おわりに

非常に初歩的な内容ですが、自分の記憶を整理するために書きました。
読んでいただきありがとうございます。
Raspberry Pi Pico WでLINE通知をお試し

Raspberry Pi Pico Wで、[WiFiスキャン](https://qiita.com/jksoft/items/86d61e85320733da70cc)や[Bluetooth通信](https://qiita.com/jksoft/items/dcd0091f6b39a2beb4c0)は試してましたが、Http Clientは確認してなかったので、試しにLINE NotifyのAPIを使って、Raspberry Pi Pico WからLINEへの通知を試してみます。
開発環境はArduino IDE 2.0を使いました。Raspberry Pi Pico WのArduino環境の準備方法はRaspberry Pi Picoと同様です。ボードの選択でRaspberry Pi Pico Wを選べばOKです。

[参考]

https://qiita.com/jksoft/items/4791973a5922efb77169


## LINE Noifyの登録
LINE通知を行うには、LINE Noifyにログインしてトークンを取得する必要があります。(LINEのアカウントを持っていることが前提)

以下のサイトが参考になります。

https://zenn.dev/protoout/articles/18-line-notify-setup

## スケッチ
単純にRaspberry Pi Pico W上のBOOTSELボタンを押すと定型文をLINE通知するというスケッチです。
WiFiのSSID（`ssid`）とパスワード（`password`）、LINE通知のトークン（`token`）は自分の環境のものに変更して下さい

```c++
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>

#define STASSID "ssid"
#define STAPSK "password"
#define LINE_ACCESS_TOKEN "token"
#define LINE_NOTIFY_MESSAGE "BOOTSELボタンが押されました"

const char *ssid = STASSID;
const char *pass = STAPSK;

HTTPClient httpClient;
String TOKEN = LINE_ACCESS_TOKEN;
String MESSAGE = LINE_NOTIFY_MESSAGE;

WiFiMulti multi;

void lineNotify(String body)
{ 
  String Url = "https://notify-api.line.me/api/notify";

  httpClient.setInsecure();
  httpClient.begin(Url);  
  httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");
  httpClient.addHeader("Authorization", "Bearer " + TOKEN);

  int status_code = httpClient.POST("message=" + body);
  Serial.println(httpClient.getString());
  if (status_code == 200){
    Serial.printf("[SUCCESS]");
  } else {
    Serial.printf("[ERROR]Code:%d", status_code);
  }
  httpClient.end();
}

void setup() {

  Serial.begin(115200);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  multi.addAP(ssid, pass);

  if (multi.run() != WL_CONNECTED) {
    Serial.println("Unable to connect to network, rebooting in 10 seconds...");
    delay(10000);
    rp2040.reboot();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  bool bootSel = BOOTSEL;
  static bool beforeBootSel = BOOTSEL;

  if ((multi.run() == WL_CONNECTED)) {

    if(bootSel && !beforeBootSel) {
      lineNotify(MESSAGE);
    }
    beforeBootSel = bootSel;
  }
}
```

## 動作確認
SSIDとパスワードが間違っていなければシリアルモニタに以下のように表示されます。

```
12:01:29.906 -> WiFi connected
12:01:29.906 -> IP address: 
12:01:29.906 -> 192.168.2.182
```

BOOTSELボタンを押し、トークンが間違ってなければシリアルモニタに以下のように表示されます
```
12:01:34.259 -> {"status":200,"message":"ok"}
12:01:34.259 -> [SUCCESS]
```

LINEに通知も飛びました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/ad7e9faa-03f4-870c-4b1b-01aac9e1099e.png)

## 最後に
サンプルやライブラリが準備されているので、Http Clientも5分ぐらいで試せました。
Arduino IDE向けのライブラリは豊富なので、センサー連動とかもあっという間にできそうですね。
Timeoutのテストに利用できる簡単な遅延APIをdockerを使って作成しよう

# 遅延APIが欲しい

最近 504 timeout エラーで悩まされ、開発やデバックに利用できるAPIが欲しくなった。
（例えば、サーバレスAPI（APIゲートウェイ と AWS Lambdaで構成） から処理時間の長い別のAPIを呼ぶ場合など。ちなみにAPI GatewayのTimeoutは29秒がデフォルトでMax値なので、これ以上時間のかかるAPIはこの構成では作っちゃダメです。）

そこで、遅延する時間とレスポンス（http status codeとbody）を簡単に変更できるAPIが欲しくなった。

結果、ローカルで遅延を起こせるAPIサーバーを立てて、[ngrok](https://ngrok.com/)を使ってインターネット経由で呼べるような仕組みを作った。
簡単に作成できますし、他に困っている人もいると思うので紹介します。

## 利用方法
当時作成したAPIサーバーは python flaskで作成したが、ここでは、rubyのsinatraを紹介します。（個人的にはこっちの方が直感的に色々設定しやすい）
利用方法は、[Source code (git)](https://github.com/yusungkim/delay_api)をダウンロードし、docker-composeで起動するだけ。
### ローカル起動
```bash
# api start
$ docker-compose up
```

### インターネットからアクセス
ローカルではなく、クラウド環境など運用中のサーバーで確認したい場合は、ngrokを使うと便利です。
ローカルで起動したサーバーをインターネットからアクセスできます。

```bash
# ローカルの3000ポートをインターネットに公開
$ ngrok http 3000
```

```bash:画面出力
# ...(中略)
Forwarding                    https://fc70-119-173-192-139.jp.ngrok.io -> http://localhost:3000
```

```bash
# 上の「Forwarding」に記載されているurlを使ってローカルのAPIサーバーにrequest
$ curl https://fc70-119-173-192-139.jp.ngrok.io/api/delay
# {"status":200,"delayed_sec":1,"inputs":{},"usage":"/api/timeout?sec=1&status=200"}
```

## その他

### APIの設定
GET リクエストとqueryから遅延する時間、返すhttp status codeを決めていますが、お好みに合わせて簡単に修正可能です。
POSTリクエストへの変更や headerの追加も直感的にできます。
文法は[sinatraのdoc](https://github.com/sinatra/sinatra#routes)を参照してください。

```bash:app.rb
# 遅延API
get '/api/delay' do
  # inputs
  delay_sec = params["sec"]&.to_i || 1
  res_status = params["status"]&.to_i || 200

  # headers
  content_type 'application/json'
  headers "Access-Control-Allow-Origin" => "https://yusungkim.com"

  # delay
  sleep delay_sec

  # response http status
  status res_status

  # response body
  {
    "status" => res_status,
    "delayed_sec" => delay_sec,
    "inputs" => params,
    "usage" => "/api/timeout?sec=1&status=200"
  }.to_json
end
```

```bash:APIの応答例
# /api/delay?sec=2&status=504
{
  "status": 504,
  "delayed_sec": 2,
  "inputs": {
    "sec": "2",
    "status": "504"
  },
  "usage": "/api/delay?sec=1&status=200"
}
```

### ポート番号の変更

ローカルで利用するときにポート番号を他のにしたい場合は、docker-compose.ymlを変更してくだい。
例えばポート3001を使いたい場合は、下記のように変更してください。

```bash:docker-compose.yml
# ...中略
services:
  app:
    build:
      context: .
    ports:
#      - 3000:3000  # original
      - 3001:3000   # 3001を利用したい場合
```
未経験からのプログラミング学習・エンジニア転職の振り返り

## この記事の概要
私はテックキャンプを利用して、半年間の学習と転職活動を先日完了しました。これまでを振り返るため、この記事を書きました。あくまで一個人の体験記録としてさらりと呼んでいただけると幸いです。

### 筆者のプロフィール
・職業：地方公務員
・年齢：29歳
・学生時代の専攻：文系

## プログラミング学習について
### 学習の概要
・学習期間：2022年7月中旬〜2023年1月中旬
・夜間・休日コースを選択（仕事と両立したい場合は必然的にこのコースになる）
・学習方法：オンラインでのカリキュラム学習
・スクールのサポート体制：技術的な質問ができるメンター制度、学習方法や困りごと相談のできるライフコーチ制度、転職サポート制度

### カリキュラムの詳細
※カリキュラムは随時アップデートされるため、下記の通りでない場合もあります
・カリキュラムは基礎、応用、発展、最終課題の４フェーズに大別される
・週23時間の学習時間確保を推奨される
・１週間に１日は「時間割学習日」という日を設定し、推奨される時間配分の通りに学習を進める
・学習期間の途中にスキルチェックテストがあり、次のフェーズに進めるかの試験となるものもある
・期間の最後には、カリキュラムで指定されたアプリまたはオリジナルアプリを作り、発表する機会あり
・スタッフとはSlackで連絡を取り合う

### 入学前に行ったこと
・現職からの転職を視野に入れ、入学するスクールを選定（判断基準：仕事と両立して学習できるか、サポート体制の違い、学習方法・内容、費用　等）
・ITパスポートの取得

### 学習を通して学び得たこと
・学習時間を確保するために、計画を立てて実行する力がついた
・学習の習慣がつき、転職後も資格の勉強などに役立てられそう
・コロナにかかったり、プライベートで忙しかったりして、学習進捗が思わしくないこともあったが、臨機応変に対応できた

### テックキャンプを選択して良かったと思うこと
・カリキュラムを読んで理解するのではなく、実際に手を動かしてアプリケーションを作ってみることで、サーバーサイドの動きや開発の流れを体得することができた
・メンターさんに質問するとき、自分の中で要点をまとめてから質問することで、思考の整理をする癖がついた。

### 学習を終えて思うこと
・実践型のカリキュラムで学ぶということが自分に合っていた
・学習を通して、技術面だけでなく、習慣作りやスケジュール管理、セルフマネジメント力などを磨くことができた
・転職後も役立ちそうなことが学習終了時点で身についていて、転職活動中も自信を持っていられた

## 転職活動について
### 転職活動の概要
・転職活動期間：2023年1月下旬〜3月上旬（約40日間）
・応募社数：21社
・内定獲得：6社
配偶者がいるため、居住地である愛知県内に絞って就職先を探した。
未経験スタートということと、将来的に顧客折衝の業務に携わりたいと思っていることから、フルリモートの働き方は対象外とした。

#### 筆者が思う転職活動でのポイント
##### 志望動機の磨き方
※本記事末尾の参考図書の内容を実践しました
・本音を洗い出す（前職で感じたもやもやを書き出して、なぜ？を繰り返し問い、自分の奥底にある本音に辿り着く）
　→面接にて転職理由などを聞かれた時、前職の愚痴、ネガティブなことを言わなくなり、ポジティブな内容のみを話せるようになる

##### 面接で大事にしていたこと
・相手に自分のことを知ってもらう対話の機会と捉え、落ち着いて自分のことを話す。真反対のことや、誇張しすぎるのはNG
・業界や企業の話など、事前に調べはするものの理解しきれないのは当たり前なので、多少の間違いはあったとしても「自分はこう思う！こうなりたい！」と自信を持って話すことが大切
・笑顔が大切。緊張していても、意識的に笑顔にすると和らぐ
・本音を磨いていれば、想定外の質問が来た時も落ち着いて回答ができる

##### 選考のポイント
・選考フェーズはなるべく揃える（内定をもらった時、回答を待ってもらう期間が１週間程度しか取れないため）
・企業の選考を多く入れすぎない。５社程度が限界かも（想定問答を考えたり、面接練習が大変なため）
　※筆者は１週間に７社くらい選考を入れた時もあり大変でした。１社あたりにかける時間が少なくなってしまうのと、受けた企業の印象が後々薄くなってしまうこともあり、あまり同時期に多く入れすぎるのはお勧めしません。
・選考準備の段階で、なんとなく知っているけどわからない単語などがあれば調べておく（専門用語だけでなく、条件面でよく出てくる年収、社会保険、みなし残業などの単語も、自分で説明できない場合は調べると良い。面接で条件面の確認が必ずされるため）
・スケジュール管理ツールとしてGoogleカレンダーを使っていた。面接の予定だけでなく、訪問面接の場合の移動時間や、面接の準備時間なども入れておくと、自分のタスクも明確になってお勧め

### 転職活動を終えて思ったこと
・学習中に自信がついたので、転職活動でも自信を持って選考に臨めたのが非常に良かった
・企業様の選考を受けていく中で、自分の思っていることがより整理され、志望動機などが磨かれていく感覚があった
・選考に慣れていくといった意味でも、本命の企業様の選考は後の方に回す方がいいのではと思う

### 学習・転職活動を終えて思うこと
テックキャンプでは時間割学習で学習習慣の定着を促してくれたり、メンターに質問する際の思考整理用フォーマットを使う必要があったり、受講生に対するルールが一定数あります。それらは受講生を縛るものではなく、全て「エンジニアになった後を想定して自律した人材を育てる」という意図のもと設けられているものです。テックキャンプは、無駄のない学習方法が確立されており、技術力はもちろんのこと、エンジニア転職後も役立つヒューマンスキルが身に付くスクールだと思います。私はテックキャンプでの学習が本当に自分に合っていたため、テックキャンプに入学して良かったと心から思います。転職活動を無事終えた今、温かくて頼もしいスタッフさん達に心から感謝の意を表したいと思います。

この記事が、どなたかの役に立てば幸いです。

### 参考図書
[「会社辞めたい」ループから抜け出そう! 転職後も武器になる思考法](https://www.amazon.co.jp/%E3%80%8C%E4%BC%9A%E7%A4%BE%E8%BE%9E%E3%82%81%E3%81%9F%E3%81%84%E3%80%8D%E3%83%AB%E3%83%BC%E3%83%97%E3%81%8B%E3%82%89%E6%8A%9C%E3%81%91%E5%87%BA%E3%81%9D%E3%81%86-%E8%BB%A2%E8%81%B7%E5%BE%8C%E3%82%82%E6%AD%A6%E5%99%A8%E3%81%AB%E3%81%AA%E3%82%8B%E6%80%9D%E8%80%83%E6%B3%95-%E4%BD%90%E9%87%8E%E5%89%B5%E5%A4%AA/dp/4763139495)
日本の鉄道時刻表をプログラムで扱うときに気を付けたいこと

鉄道時刻表を扱うプログラムを作成する場合、特殊な運行形態を取る路線を処理する必要があるかもしれない。
この記事では、時刻表をプログラムで扱う上で覚えておきたい列車の特殊な運行形態を挙げていく。

## 列車番号の重複

列車番号とは、時刻表上で列車に対して与えられている一意な番号のこと（例：`9375M`）。

基本的に１つの路線内では一意だが、稀に重複した番号が振られることがある。

例
- 京成線`1846b` http://ksweb.org/etc/202201/e002352.php （過去）
- 名鉄線`1250`など
- 京急線`830`など https://okwave.jp/qa/q5422479.html

プログラム上、列車番号を一意なキーとして扱ってしまうとバグのもとになってしまうので注意。

## 同じ駅を2回通る列車

列車の時刻表から駅の時刻表を生成するときに困る。
例えば運転経路が「A駅→B駅→A駅→C駅」という経路になっている場合（A駅を2回通る）を考える。
A駅からC駅へ行きたい人は、何時にA駅へ行けばいいだろうか。
当然、列車が1回目にA駅を発車する時刻ではなく、2回目にA駅を発車する時刻である。
（ここで1回目の時刻を案内してしまうと、乗客は遠回りすることになり時間の無駄になる。）

列車時刻表を扱うときは、このように同じ駅に複数回停車する場合を考える必要がある。
このようなケースはいくつかのパターンに分けることができる。

#### 環状運転

- 山手線（大崎→大崎）
- 大阪環状線（天王寺→天王寺）
- ディズニーリゾートライン（リゾートゲートウェイ・ステーション→リゾートゲートウェイ・ステーション）
- 札幌市電（西４丁目→西４丁目）
- 名城線（ナゴヤドーム前矢田→ナゴヤドーム前矢田）
- 富山地鉄 環状線（富山駅→富山駅）

#### 6の字運転／9の字運転

- 大江戸線（光が丘→都庁前→大門→都庁前）
- 大和路快速（奈良→天王寺→大阪→天王寺）
- 関空/紀州時快速（日根野→天王寺→大阪→天王寺）
- 名城線の名港線直通列車（奈良→天王寺→大阪→天王寺）

6の字運転後、そのまま環状運転に移行する列車もあり。
例：

- 大和路線`323Y`は加茂→天王寺→大阪→天王寺と6の字運転後、そのまま大阪環状線`2394`列車として更にもう1周する。
- 名港線の列車の一部は、名古屋港→金山と運転後、そのまま名城線を環状運転する。

#### ラケット型運転

- ユーカリが丘線（ユーカリが丘→公園→中学校→公園→ユーカリが丘）
- ポートアイランド線（三宮→中公園→中埠頭→中公園→三宮）
- 富山地鉄 富山港線（岩瀬浜→富山駅→丸の内→富山駅→岩瀬浜）

#### Y字運転

以下のような運行形態。B駅を2回通る。

```
A駅→B駅→D駅
　　 ⇅
    C駅
```

- リゾートしらかみ（青森→川部→弘前→川部→秋田）
- はくたか（過去）（越後湯沢→津幡→金沢→津幡→和倉温泉）
- 名鉄（過去）（豊橋→神宮前→金山→神宮前→中部国際空港）
- 福井鉄道（田原町→福井城址大名町→福井駅→福井城址大名町→たけふ新）


## 行先!==終着駅

車両や駅の電光掲示板には行先が表示されるが、ここには必ずしも終着駅の駅名が表示されているわけではない。
アプリ等で行先を案内したい場合、時刻表上の終着駅とは別に行先のデータを保持しておく必要がある。

- 列車番号が途中で変わる列車
  - 通常は1つの列車に1つの列車番号が割り振られているが、列車番号を途中で変えて運転を継続する列車がある。この場合、最終的な終着駅が行先として使われることがある。
- 環状運転の場合
  - 山手線「渋谷・品川方面」など
- 大阪環状線に直通する列車
  - 終着駅は天王寺だが、行先は「大阪環状線」を表示する
- 案内上表示を簡略化している場合
  - 京急線の羽田空港国内線ターミナル行の場合、行先は「羽田空港」で案内される（国内線ターミナルと国際線ターミナルの両方に停車するため）
- 駅側のシステムが対応していない場合、終着駅より手前の駅を行先として案内することがある。
- 特殊な列車
  - [行き先はニューヨーク！？　JRがついに大陸間列車を運行開始か](https://togetter.com/li/741955)

## 特殊文字

ごく稀に、列車名や列車番号に特殊文字が使われることがある。
（異常時において列車番号に`'`を使っている会社を見たことがある程度）

現在は列車名や列車番号も（鉄道会社社内の）システムで管理されている。
逆に言えば、それらのシステムが許せばどんな値でも列車名や列車番号として使用できることになる。
HTMLタグ等のエスケープ処理を忘れずに。

以上、簡単ではあるが、鉄道時刻表を扱う際に気を付けたいポイントの紹介でした。
Node.js + TypeScriptでexpressの入力支援、型推論を表示させるまで

## `typescript`、`express`をインストール

``` bash
npm init -y
npm install typescript
npx tsc --init
npm install express
```

## `app.ts`を作成
``` js
touch app.ts
```

## `app.ts`で`express`を`require`したところエラーが出た

``` js
const express = require('express')
```

![2023-04-02-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/a55fe70d-dd22-f2e0-048d-93c97b57952c.png)

```
TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
```

- TypeScriptは`node.js`の関数である`require`を理解していない
- `require`を理解させるために`Node.js`の型定義ファイルが必要
- エラー内容に従って`@types/node`をインストール
- `@types/node`はNode.jsの型定義ファイル
- インストールすると、エラーが解消される

``` bash
npm install -D @types/node
```

## インポートした`express`で入力支援が行われない

![2023-04-02-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/7834af38-ac0f-02ef-9f5b-4bc121c48ace.png)

- `app.`と入力しても、`listen`などが入力支援で出てこない
- `app`の型推論が`any`になっておりexpress用の型定義ファイルが無いため
- `express`用の型定義ファイルである`@types/express`をインストールする

``` bash
npm install -D @types/express
```

しかし、まだでない

![2023-04-02-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/b7096d05-eb69-f12e-ec24-d7505893e8d4.png)

- そもそも`require`にカーソルを合わせて見てみると、`any`を返す関数として定義されている

![2023-04-02-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/dece4ec6-494d-f3c4-5941-1246d0116ae6.png)

```
TS80005: 'require' call may be converted to an import.
```

- TypeScriptはこの`require`関数が何をしているのか知らない状態
- TypeScriptで正しく機能させるためには、TypeScriptにあるモジュールシステムである`import`を使わないといけない
- `require`を`import`に変更する

```js
// const express = require('express')
import express from 'express' // これに変更

const app = express()
```

- 正しく入力支援が出るようになりました。

![2023-04-02-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/03e998ea-301a-e00b-8092-19707f5caaeb.png)
CH32V003F4P6のメモ

最後に環境準備なども書きますが、まずは引っかかったところ。
■terminalへの出力は？
書き込みもデバッグもSWDIO一本でOKなんて書いてあるから、arduinoのシリアルモニタ的なものもSWDIOだけでOKかと思ったらそうではありませんでした。Txである PD5(Chipの#2)を WCH-LINKのRxにつなぐ必要あり。

■ターミナルの起動
メインメニューからは辿れなくて(私には)
ツールバーにしかない感じ
![terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107685/9de4c195-0f04-d294-9d32-f958c1df7471.png)

■評価ボードじゃなくてChip単品で使う
SSOP20のBreakOutボードがあればOK
WCH-LINK   Chip
3.3        #9
GND        #7   
SWDIO      #18
Rx         #2  (terminalへ printf したいなら)
の接続でOK　外部オシレータ無しでも可


■内部外部オシレータによる速度の差
評価ボードがそうであるように外部オシレータがある場合
Delay_Ms();
は期待通りの挙動ですが
外付け水晶なしの場合(内部オシレータ使用の場合)、どうも 
Delay_Ms();
は期待の2倍delayするようです。
正しくする設定を知らないだけだと思いますが、、

ただ、USARTの速度は設定した値でTerminalと通信できました
delayなしでpinのHIGH/LOW上げ下げさせてみると
内部オシレータの場合は 772KHz
外部の場合は 1.14MHzでした。
どちらの場合もシステムクロックは 48000000
と報告してくるのがちょっと不思議

■書き込めないことがある
確実なのは　
MounRiver Studioから

もし実行中なら　■ボタンでデバッガを止める
メインメニュー/Project/Clearn
メインメニュー/Run/Run

<hr>
<h2>■□■一般的な情報</h2>
■そもそもこれは何？
今一部で注目の激安RISC-V Chipに関する情報です。
あまりに情報が少なく、しょぼいところで躓いて起き上がれないこともあるかと、、

■SDKなどは？
https://www.wch.cn/
https://www.wch.cn/search?t=all&q=CH32V003
で
CH32V003EVT.ZIP
を落としてきましょう。
その中に
 EXAM というフォルダと、PUBというフォルダがあります。
PUBにある
CH32V00x Evaluation Board Reference-EN.pdf
にいろいろ書いてあるので参考になりますが、
間違っている内容もありますね、、
EXAM フォルダにはサンプルコードがたくさん載っているので役に立ちます。

■開発環境
EVT.ZIPのPUBフォルダの
CH32V00x Evaluation Board Reference-EN.pdf
の p2 に IDEは MounRiverを使えと書いてありますがリンクがありません。
http://www.mounriver.com/download
から
MounRiver_Studio_Setup_V184.zip
をget してインストールしましょう。
MounRiver_Update_V184.zip　と間違えないように注意。

で、MounRiverがインストールされたら、
WCH-LINKに評価ボードをつないで、それをPCにつないで
メインメニュー/File/Loadで先程の EVT.ZIPを解凍してできた EXAM フォルダ内の
GPIO/GPIO_Toggle
を開いてみましょう。
これがだいたいLチカです。
開くには
GPIO_Toggle.wvproj
を開きます。

■Loadしたけど、どこに書き込むのか?
user フォルダ下の main.c を開きます。
![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107685/cda12ab5-8c81-8875-2513-13496da382aa.png)

■書き込み方
CH32V00x Evaluation Board Reference-EN.pdf
にはやたらと難しく書いてありますが、実は以下でOK
例:EXAM下のサンプルプロジェクト を書き込むとする
WCH-LINKとチップまたは評価ボードを正しくPCに繋いで、
MounRiver stduioの メインメニュー
Project/Build ALL
 の後、
Run/Run
その後ソースを変更して再び書き込むときはまずSaveします。
下記<font color = red>■</font> をクリックして開発環境とチップの連携を切ります。
![reload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107685/ebc2b77b-07e0-7022-2007-411c140dfd24.png)
その上で 
Project/Clean やって Run/Runすると新しいソースで書き込んでくれます。
もっと効率が良い方法もあると思いますが今のところこれが確実でした。