OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby基礎①

# 久しぶりに勉強してみる
昔スクールで勉強したことあるが使う機会がなかったので全然使っていなかった。しかし意味働いているベンダーはRubyを使っているみたいだ。

親会社もグループ会社もRuby、最近だとサーバレスなフレームワークを使うみたいだが。TypeScriptをやった方がいいと言いつつRuby on Railsの需要もまだある。

公式は日本語もあるので学習しやすいだろう。
[official](https://docs.ruby-lang.org/ja/3.3/doc/index.html)

https://docs.ruby-lang.org/ja/3.3/doc/spec=2fliteral.html

```ruby
# 数値の１２３、文字列などをリテラルという。
# Rubyで使える例

# 数字
puts 123

# 文字列
puts "Hi"

# 配列
puts [1, 2, 3]

# ハッシュ
puts {'ja' => '81'}

# 変数名 = 式や値
num = 123
puts num

greet = "Hi"
puts greet

is_done = true
puts is_done

n = 10 * 2
puts n
```

変数名は監修として小文字のスネークケースで書く文化がある。(_)で英単語を区切る。
```ruby
is_done = true
puts is_done

home_page = "/home"
puts home_page
```

変数名は英語の小文字、アンダースコア、で始めることができる。
```ruby
_private = "private"
puts _private

tax_10 = "10%"
puts tax_10
```

数字から始めるとSyntaxErrorが発生する
```ruby
1number = 1
puts 1number
```

error code
```shell
basic2/literal.rb:35: syntax error, unexpected local variable or method, expecting end-of-input (SyntaxError)
1number = 1
 ^~~~~~
```

演算子による値の比較

https://docs.ruby-lang.org/ja/3.3/doc/spec=2foperator.html

```rb
puts 1 < 2
puts 1 <= 2
puts 1 > 2
puts 1 >= 2
puts 1 == 2
puts 1 == 1
puts 1 != 2
```

### log
```shell
true
true
false
false
false
true
true
```

## 嘘か本当か？
Rubyには`false`か`nil`がある。`nil`だとログが表示されなかった。
```ruby
puts '--------'
puts true
puts false
puts nil
```

### log
```shell
--------
true
false
```

`nil`を使った例。nilは、Swift以外であるの忘れていた。Goにもあったような。
```ruby
# 1. 基本的な nil チェック
def basic_nil_check(data)
    if data.nil?
      puts "データなし"
    else
      puts "データあり: #{data}"
    end
  end
  
  # 2. nil?メソッドを使用した条件分岐
  def nil_method_check(data)
    if !data.nil?
      puts "データあり: #{data}"
    else
      puts "データなし"
    end
  end
  
  # 3. 三項演算子を使用したnil判定
  def ternary_operator_check(data)
    result = data.nil? ? "データなし" : "データあり: #{data}"
    puts result
  end
  
  # 4. ||演算子を使用したデフォルト値の設定
  def or_operator_default(data)
    result = data || "デフォルト値"
    puts "結果: #{result}"
  end
  
  # 5. &.演算子（安全なナビゲーション演算子）を使用
  def safe_navigation_operator(data)
    length = data&.length || 0
    puts "データの長さ: #{length}"
  end
  
  # 6. ||=演算子を使用した初期化
  def conditional_assignment(data)
    data ||= "デフォルト値"
    puts "結果: #{data}"
  end
  
  # サンプルの使用
  some_data = "Hello"
  no_data = nil
  
  basic_nil_check(some_data)  # 出力: データあり: Hello
  basic_nil_check(no_data)    # 出力: データなし
  
  nil_method_check(some_data) # 出力: データあり: Hello
  nil_method_check(no_data)   # 出力: データなし
  
  ternary_operator_check(some_data) # 出力: データあり: Hello
  ternary_operator_check(no_data)   # 出力: データなし
  
  or_operator_default(some_data) # 出力: 結果: Hello
  or_operator_default(no_data)   # 出力: 結果: デフォルト値
  
  safe_navigation_operator(some_data) # 出力: データの長さ: 5
  safe_navigation_operator(no_data)   # 出力: データの長さ: 0
  
  conditional_assignment(some_data) # 出力: 結果: Hello
  conditional_assignment(no_data)   # 出力: 結果: デフォルト値
```

## まとめ
def endのコードはよくみる機会があるので書いて練習した方がいいなと思った。Pythonに似てるから理解はしやすい。
折り畳んでもコメントが隠れないif文の書き方

## はじめに
普段はほぼ拡張機能を導入していないVSCodeやSublime Textでコーディングをしているのですが、その中で最近いいなと思っているif文の書き方を紹介したいと思います。

## 一般的な書き方

```js
const [ isFoo, isBar ] = [ false, true ] ;
const doAnything = () => {};

if (isFoo) {
    // fooの場合
    doAnything();
} else if (isBar){
    // barの場合
    doAnything();
} else {
    // どちらでもない場合 
    doAnything();
}
```
:::note 
2024/09/19 行末に記述する例から、ブロックの内側に記述する例へ変更しまいた。
:::

多くの場合は上記のように同じ行で`} else {`と記述し、コメントは行末かブロックの内側に書くことが多いと思います。ですが拡張機能とかを入れていない状態でコードを折りたたむとコメントが巻き込まれてしまい少し読みづらいなと感じていました。


```js:折りたたんだ状態
const [ isFoo, isBar ] = [ false, true ] ;
const doAnything = () => {};

if (isFoo) { ...
} else if (isBar){ ...
} else { ...
}
```

## 該当のコード

```js
const [ isFoo, isBar ] = [ false, true ] ;
const doAnything = () => {};

// fooの場合
if (isFoo) {   
    doAnything();
}

// barの場合
else if (isBar) {    
    doAnything();
}

// どちらでもない場合 
else {               
    doAnything();
}
```

上記のように`}`の後に改行してからelse句を始めてその上にコメントを記述することで、エディタでコードを折り畳んでもコメントが隠れないようになります。


```js:折りたたんだ状態
const [ isFoo, isBar ] = [ false, true ] ;
const doAnything = () => {};

// fooの場合
if (isFoo) { ...
}

// barの場合
else if (isBar) { ...
}

// どちらでもない場合 
else { ...
}
```

### 注意点

補助が少ないエディタで今回のようなスタイルで記述をしている場合、コメントを書くスペースに動作する記述をしてしまってもエラー表示がなされない場合もあります。
鋼の意志を持って注意するか、`/* */`で間のスペースを丸ごとコメントアウトして動作する記述をできないように回避するかっていう対応になるかなと思います。


## まとめ

あまり一般的ではなく実装ミスが混入する恐れがある場合もあるため、チームでコーディング規約を決めているなどの固い環境向けというよりは、個人開発や趣味など自分で気をつけて読みやすい書き方ができればいいゆるい環境向けというような感じです。

読みやすい条件式を書く、理解しやすい変数or関数を条件式に使用するなどで、コメントを使用しなくて読みやすくする方法などと適宜使い分けをすると効果的かなと思います。
【SSv5】マイコンボードにファームウェアを書き込む手順

## 環境
OS：Windows 10  
IDE：Simplicity Studio Version: SV5.9.2.1  
マイコンボード：PCB4001 Rev A03  


## 背景
IDEを立ち上げたら「マイコンボードのファームウェアを更新できるよ」と言われた。  
![AdapterUpdateAvailbre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/375834a5-22b8-27b9-ea08-f74bdaf7e803.png)  

更新しようとしたら失敗した。  
![Error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/2a1a3559-7036-ad55-d439-afd127bd916f.png)  

マイコンボードを認識しなくなった(Custom Boardと表示される)。  
![DebugAdapters.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/9bee8542-d2ae-e490-4b16-49223b845f62.png)
  

## ファームウェアの書き込み手順
DebugAdaptersタブでマイコンボードを選択し右クリックより「Device Configration」を押下する。  
「Boards」にマイコンボード名を入力し、リストから選択する。  
(Rev A03が出てこないのでA01を選択した)  
![BoardsSelect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/3d09d3e8-20e3-b102-292c-eea105c6635e.png)  

再度、DebugAdaptersタブでマイコンボードを選択し右クリックより「Upload Adapter Firmware」を押下する。  
書き込みたいファームウェアを選択する。  
(今回は「WSTK Firmware」を選択した)
![BinaryImageUpload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/4bea3900-52c3-59f7-6d31-1adbf13d2e46.png)  

完了するまで少し待つと、ファームウェアが書き込めている。  
![DebugAdapters_After.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295695/c44e52eb-0035-8892-de39-6a28f03ab87e.png)  


## おわりに
この手順でファームウェアを書き込んだ後も、ファームウェアの更新を促すウィンドウが毎回出てきます。  
ただ、更新に失敗し続けます。  
もしかしたらインストールしたデータや設定を間違えているなどあるかもしれません:sob:
KT0937-D8でラジオモジュール＆ライブラリを自作する

# KT0937-D8について
KT0937-D8は、AM/FM/SWの3つが受信可能なラジオ受信チップです。SDRラジオが構築可能です。

秋月電子で、私は150円で購入しました。DIP/SOP変換基盤が約30円でした。

https://akizukidenshi.com/catalog/g/g117875/

https://akizukidenshi.com/catalog/g/g113602

KT0937-D8の足が0.635mmなのでかなりはんだ付けは難しいです。

SDRの詳細については以下の記事が有用でした。

https://www.keisoku.co.jp/pw/u-po/20230907-01/


# 回路作成
回路はKicadを使って設計しました。プロトタイプ(ユニバーサル基盤)が完成し、うまく動作したらJLCPCBなどに発注予定です。ちなみに、回路設計に関しては完全素人なのでお察しください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337685/4a9c09ed-4a85-b049-96d6-1e7d9f0f5273.png)


# はまったところ
~~現在(2024/09/18)にI2Cで認識ができないという問題に陥っています。~~
解決しました。I2Cスキャナーを使ってI2Cアドレスを調べたところデータシートに記載されている**0x60**ではなく、**0x35**でした。おそらく、読み書き用のビットをデータシートは含めているようでした。

また、問題発生。現在(2024/09/21)にすべての周波数において-87dBmというRSSIを受信するという謎の状況に至っています。おそらくアンテナ回路が適当なので、実装をもう一度考え直すことにしました。

# ライブラリ

このたび人生初のライブラリを自作しました。以下のgithubのページにあります。

https://github.com/BB-KING777/KT0937-D8lib

かなり労力を使うので、最低限だけ自分でやって他はAIにやらせました。一応正常に動いています。

# 今後の展望
現在の回路ではAM FM用のアンテナが共用になっているので別々にしたいと思います。

ただ、AM用のアンテナが一つ当たりの値段が高い....(最低でも600円以上)
Rasberry Pi 5のセットアップ

# はじめに

:::note info
こんな人向け
- 初めてRasberry Pi5のセットアップをする人
- OS書き込み済みのSDカードが手元にある人
- Rasberry Pi5のセットアップの振り返りをしたい人
:::

# 手順

今回は秋月でスターターキットを購入

https://akizukidenshi.com/catalog/g/g129363/

:::note info
***いいところ***
- ボード，HTMLコード，ACアダプター，ケース(ファン付き)がついてくる
- SDカードにすでにOSを書き込み済み
:::

## 初期設定

Rasberry Pi5にOSのimageを書き込み済みのSDカードを刺した状態でACアダプターを接続

![20240918_230402.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/52002be6-0acb-d7dd-864a-459957d34f9c.jpeg)

:::note info
Rasberry Pi5は電源供給があったら勝手に立ち上がる模様
:::

電源がつくと以下の画面に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/a58a8daa-9ee2-f363-a9b5-95ad8ee94782.png)

(自分の画面を写真撮ればよかったのだが忘れていたため，[karaage0703さんの記事](https://zenn.dev/karaage0703/articles/8fe578dba4857a)から画像をいただきました．)

起動画面に入るとまずはcountryを選択する画面に移動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/c8dabcfd-17f0-5574-393d-3eac895250fc.png)

(これも写真撮るの忘れていたので，http://independence-sys.net/main/?p=6118 からいただきました)

今回の設定
- Country: Japan
    - Countryを設定すればLanguageとかTimezoneは勝手に設定される
- use English languageにチェック
    - これにチェックをいれることでhome画面のdefaultのアプリの名前が英語表記に

次にUsernameとPasswordを入力

:::note info
自分がわかるUsernameとPasswordを入力して次へ
:::

ここからはアプリ系の選択

![20240918_225345.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/4f2dee75-58e7-0fcb-1bc4-efbd2c06686a.jpeg)

![20240918_225420.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/9e33b469-ce7b-3b49-a720-5a1fb229e7d4.jpeg)

:::note info
途中でWi-Fiの接続先を指定するため，updateできるようになる
中でupdateが始まるのでそこそこ時間がかかる
:::

***初期設定完了！***

![20240918_232138.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/98be13e9-6e66-ff10-3449-ed149b95bf63.jpeg)

## 開発環境設定

:::note info
基本的に外部からremote desktopで接続できるようにして，外部PCで作業できるようにしたい
:::

https://qiita.com/sirius1000/items/a68343ceac27204d43ce#ssh%E6%9C%89%E5%8A%B9%E5%8C%96

以下のコマンドでラズパイのセッティング画面に行くので，ssh接続の有効化まで進める

```bash
sudo raspi-config
```
![20240918_234407.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/5703c1bd-f5c1-d2f5-871d-fbba377aae44.jpeg)

![20240918_234436.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/8cf86f6f-0bb6-b7a4-b935-0de956aca008.jpeg)

![20240918_234452.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/3daf5c80-1382-6650-3a95-62d1d163f59c.jpeg)
![20240918_234510.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/9482b8e2-70f2-1717-c4e6-5724a3e6dacb.jpeg)

***ssh接続設定完了！***

:::note info
ssh接続作業ができるようになったため環境構築はひと段落
:::

# 残課題

- remote desktop接続の設定 -> [こちらの記事](https://qiita.com/hoto17296/items/0e3e5bd407351fd2e6ca)を参考に完了
- Raspberry Pi5に開発で使うライブラリ等をインストール
UnityでビルドしたiOSアプリの表示名 (Bundle display name)

## iOSアプリの表示名を任意に設定
- Bundle display nameは iOSのアプリ名として表示される名前
- 毎回 "My Project (1)" として名前が付けられてしまう
- Bundle display nameの変更は
    1. Unity の Project Setting > Player > Product Name によって設定される
    1. BuildScriptで自動化できる

```csharp

using UnityEditor;
using UnityEngine;

public class BuildScript
{
    [MenuItem("Build/Build Prototype 1")]
    public static void BuildPrototype1()
    {
        Build("com.companyname.prototype1", "Builds/Prototype1", "Prototype 1");
    }

    [MenuItem("Build/Build Prototype 2")]
    public static void BuildPrototype2()
    {
        Build("com.companyname.prototype2", "Builds/Prototype2", "Prototype 2");
    }

    private static void Build(string bundleIdentifier, string outputPath, string productName)
    {
        // Set the Bundle Identifier
        PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.iOS, bundleIdentifier);
        // Set the Product Name (Display Name)
        PlayerSettings.productName = productName;

        BuildPipeline.BuildPlayer(
            new string[] { "Assets/Scenes/MainScene.unity" }, // Replace with your scene paths
            outputPath,
            BuildTarget.iOS,
            BuildOptions.None
        );

        Debug.Log($"Build completed for {bundleIdentifier} with display name '{productName}'");
    }
}
```
【PHP】nullの扱い方

nullに対する四則演算や型変換を実行すると0に変換されてしまうケースがあり、条件分岐などが想定通りにならない場合がある。
その場合にどうすればよいか、もしくはnullをどのように扱えばうまくいったかを書いていく。
# nullどうしの加算、減算、乗算
```php
$plus     = null + null;
$minus    = null - null;
$multiply = null * null;
```
```php
// nullにはならず、全て数値型の0に変換される
int(0)
int(0)
int(0)
```

# nullどうしの除算
```php
$division = null / null;
```
```php
// エラーが発生
PHP Fatal error:  Uncaught DivisionByZeroError: Division by zero in XXX
Stack trace:
#0 {main}
  thrown in XXX
```
# nullと数値の四則演算
```php
$plusOne     = null + 1;
$minusOne    = null - 1;
$multiplyOne = null * 1;
$divisionOne = null / 1;
```
```php
// nullが0のように扱われている
int(1)
int(-1)
int(0)
int(0)
```
# nullの型変換
```php
$castToInt    = (int) null;
$castToString = (string) null;
```
```php
// エラーやnullにはならず、0に変換される
int(0)
string(0)
```

# nullを考慮しておらず、変数や条件分岐が期待しない結果になった、もしくはエラーが発生してしまった場合にどうすればよいか

## 対策1
nullが存在するパターンを考慮し、条件分岐する
```php
if (is_null($var)) {
    // $varがnullの場合の処理。早期リターンやエラー出力処理など
}
```
## 対策2
例外を投げる
```php
If (is_null($var)) {
    throw new Exception(‘nullだよ’)
}
```

## 対策3
nullを避けられないなら、関係者間でnullの扱い方を決めておく
例：nullの場合には特定の数値に変換して処理を続行する、エラーを出力する、など

# 参考
* [PHPのnull + nullはなぜ0になるのか。PHPにおけるnullの扱いを理解して仲良くなろう](https://www.docswell.com/s/tyamahori/KGXWQN-php-null "PHPのnull + nullはなぜ0になるのか。PHPにおけるnullの扱いを理解して仲良くなろう")
【初心者向け】AWS EC2の料金モデルを 特徴・コスト・使用例・注意事項 に着目してまとめてみた

## はじめに
普段、なんとなく理解している使っているEC2の料金モデルについて言語化して備忘録としてまとめてみました。
AWS認定試験でも役立つと思うので、よろしければお読みください！
※当記事ではふわっと説明しています
※もし間違っていたら教えてください🙇‍♂️🙇‍♂️🙇‍♂️


## この記事のターゲット
* AWSの有名なサービス（EC2やS3）がふわっとわかってるレベルの人
* AWS認定試験のプラクティショナーを勉強している人


## そもそもEC2における料金モデルとは？
EC2を利用する場合、基本的にはインスタンスを起動している時間に応じて料金がかかる仕組みになっていると思いますが、その仕組みを料金モデルと呼びます。
※今回はEC2インスタンスの利用料金自体に着目しますので、EBS等は対象外です


## 一般的な料金モデル一覧

### 1.オンデマンドインスタンス
* **特徴**
    * 先ほど記載した、「インスタンスを起動している時間に応じて料金がかかる」料金モデルのことを、「オンデマンドインスタンス」と呼び、最も基本的な料金モデルです
    * 特に設定をしない限りは、この料金モデルが適用されます
* **使用例**
    * 短期間の使用しかしなかったり、負荷の予測が立てられない場合
        * 開発環境用
        * 踏み台
        * アクセス数がわからないWebサイト（リリース直後だけ）
* **コスト**
    * 他の料金モデルと比べるとやや高め（割引とかがない）
    * ただし、ほとんど使わない等の理由であれば結果的に一番安くなる


### 2.リザーブドインスタンス
![スクリーンショット 2024-09-15 220006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1909565/74fd1278-3047-9964-ae23-76dad4837d68.png)
* **特徴**
    * 1年または3年の期間分の使用料を前払いすることでEC2インスタンスを利用できる料金モデル
* **コスト**
    * オンデマンドインスタンスと比べ、コスト面は安くなっている
    * 一応前払いでないのも含め、他にも支払い方法はあるが、前払いが一番安い
* **使用例**
    * 事前にEC2の一定期間の使用が見込めている場合
* **注意事項**
    * オンデマンドインスタンスと違い、インスタンスを停止していても料金に影響がない
    * インスタンスのスペックを変更する場合、再予約が必要になる


### 3.スポットインスタンス
![スポットインスタンス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1909565/a57c0ac1-e634-2174-710b-ed5a545ec5e9.png)
* **特徴**
    * EC2インスタンスは、超簡単に言うと基本的にはAWSの物理的なサーバ上を内部でいくつかに区切り、その1つをインスタンスとして提供しているが、その中で現在使用されていない部分を使用できる料金形態
    * ただし、見知らぬ誰かがその部分を使用することになった場合、使用が中断される（一応2分前に警告が来る）
    * 設定すれば、使用が中断された際にインスタンスは終了ではなく停止になる
* **コスト**
    * オンデマンドインスタンスより、超安く利用できる
* **使用例**
    * 負荷が高いような処理の中でも、中断されても良いような処理を任せたい場合
        * 機械学習のトレーニング、バッチ処理等
* **注意事項**
    * 上記の通り、EC2インスタンス使用中に中断させられる可能性がある


## ちょっと特別なインスタンス

### 1. 専有ホスト
* **特徴**
    * AWSの物理的なサーバ（以下、ホスト）を丸っと借りてしまう料金モデル
    * 丸っとかりてしまうため、他の人とホストを共有しない
    * ホスト事態が固定 = ホストのスペックが固定されるので、ユーザが用意したソフトウェアライセンスを使用できる
        * 代表例だとWindowsServerとか
* **コスト**
    * ホストを占有するだけあって、めっちゃ高い
* **使用例**
    * 金融機関や医療機関等、情報の取り扱いが難しい案件
* **注意事項**
    * ホストに対しての管理はユーザがやらなければならない
    * 例えば、複数のインスタンスをたてる場合、ホストのリソースに対してどのインスタンスタイプをどのくらい割り当てるか…等


### 2.専有インスタンス
* **特徴**
    * ホストを丸っと借りてしまう料金モデル。ただし、こちらは専有ホストと違ってホストのリソース管理はAWSが行う
    * ほかの人とホストを占有しない点は、専有ホストと同じだが、ホストのリソース管理をしなくてよい
        * インスタンスに適したホストのリソース管理をしてくれる
    * ホストのスペックは固定されないので、ユーザが用意したソフトウェアライセンスを使用できないor使用にむかない
* **コスト**
    * 専有サーバより安く利用できる
* **使用例**
    * 案件のコンプライアンス的に専有サーバを利用したいが、そこまで規模が大きくない場合やホスト管理が必要ない場合
    * スケールアウトが必要な場合
Chakra-UI モーダルのスタイルが崩れる原因と解決策

## Chakra-uiでモーダルを使おうとしたところ、画像のようにスタイルが崩れて表示されてしまいます。
![スクリーンショット 2024-09-18 23.23.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/36609fdb-c57b-9c6e-fdb2-8b4b9e1d906a.png)

公式のモーダルのサンプルをそのまま持ってきましたが、うまくスタイルが当たっていません。

## 原因
アプリケーションのルートにChakraProviderをセットできていないことが原因でした。
### 修正前
main.tsx
```
import React from 'react'
import ReactDOM from 'react-dom/client'
import { App } from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)
```
### 修正後
```
import React from 'react'
import ReactDOM from 'react-dom/client'
import { App } from './App'
import './index.css'
import { ChakraProvider } from '@chakra-ui/react'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ChakraProvider>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
)
```
ChakraProviderでラップしないといけませんでした。
修正後は以下の画像のように公式と同じスタイルが当たっています。
![スクリーンショット 2024-09-18 23.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/377ad7fc-fabf-2c4f-d069-cb13bd96c052.png)

## 最後に
公式ドキュメントの「Getting Started」のページに、ChakraProviderの設定方法が記載されています。
https://v2.chakra-ui.com/getting-started#:~:text=After%20installing%20Chakra%20UI%2C%20you%20need%20to%20set%20up%20the%20ChakraProvider%20at%20the%20root%20of%20your%20application.%20This%20can%20be%20either%20in%20your%20index.jsx%2C%20index.tsx%20or%20App.jsx%20depending%20on%20the%20framework%20you%20use.
>After installing Chakra UI, you need to set up the ChakraProvider at the root of your application. This can be either in your index.jsx, index.tsx>or App.jsx depending on the framework you use.

訳
>Chakra UIをインストールした後、アプリケーションのルートにChakraProviderをセットアップする必要があります。 これは、使用するフレームワークによって、index.jsx、index.tsx、またはApp.jsxのいずれかになります。


以上になります。本記事が誰かの助けになれば幸いです。
Arduino UNO 3、リレー Grove- Relay であそぶ




参考

![o_coq430.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/db614bca-4fd2-6995-498d-d31d927c7f4b.jpeg)


https://wiki.seeedstudio.com/Grove_Starter_Kit_for_BeagleBone_Green/


結果

![o_coq431.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8a58ad8b-4879-2881-4542-7e5a27877ca2.jpeg)



プログラム


```c++


//Grove_Relay_1S_UNO_1

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin as an output.
  pinMode(14, OUTPUT); //14 = A0
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(14, HIGH);   // turn the on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(14, LOW);    // turn the off by making the voltage LOW
  delay(1000);                       // wait for a second
}


```
フロントエンド忘備録① 環境構築 Reactとかいろいろ

# やりたいこと
VS Codeで Viteを使用して、**React, Tailwind CSS, Swiper**を使える環境を作りたいです。

# 環境構築

*node.js* は既にインストールしてあることを前提で進めていきます。

## Vite + React をインストール
```
npm create vite@latest "プロジェクト名" --template
```
Reactを選択する

![スクリーンショット 2024-09-18 230238.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/5b794628-41df-12a5-5522-242a3c3cb790.png)

今回は JavaScript を選択 

![スクリーンショット 2024-09-18 230311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/e74e54fb-cf03-3a72-86c2-4d65a2aa454e.png)

![スクリーンショット 2024-09-18 230323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/64171e07-ae81-c589-ac84-8767814e4fb5.png)

インストールが完了したら生成されたフォルダに移動して
```
npm install -D vite
```

![スクリーンショット 2024-09-18 230755.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463558/3f172880-7a32-9bd1-1780-7fd9e6062383.png)

これで純粋なVite + Reactの環境が完成しました。

## ライブラリをインストールしていく
今回は **Tailwind CSS** と **Swiper** を使いたいのでその２つをインストールしていきます。

### Swiperのインストール
```
npm i swiper
```
これだけでSwiperが使えるようになります。

### Tailwind CSSのインストール

```
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

npm~の方で必要なライブラリをダウンロードしてnpx~の方でconfigなどなどを初期化してくれます。

その後、 *tailwind.config.js* の中を以下のように書き換えます。

```javascript
export default {
  //この部分を書き加えた
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};
```

さらに、 *index.css*に以下の文を書き加えます。

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
:::note 
以上で Vite + Reactの環境で Tailwind CSS, Swiperが使えるようになります。
:::

# 最後に

純粋なHTML CSS JavaScriptで簡単なサイトは書いてみたものの、モダンJSを優先的に勉強した方がいいと思ったのでReactから手をつけてます。元々Reactだけ学ぼうと思ってましたが、いろんなサイトを見てると、**Swiper, GSAP**あたりが最近多く使われているような気がしたのでこの辺も使いこなせるようになりたいですね。
IT未経験がスクラムマスターを半年やって気づいたこと


### はじめに
経歴を簡単に紹介させていただく
大手事業会社で営業を約3年経験
その後、IT部門に移動し最初の半年間はウォーターフォール型の開発で主にテスト領域を担当
半年間経過し、なぜか年間予算1億円規模のスクラムマスターを任される
半年間経過し、アウトプットをし始める　←now

### スクラムとは
短期間で小さな成果を出し続けるフレームワークの1つ
アジャイルという概念を開発に落とし込む手法である

### 弊社でのスクラム
PJT化しておらず特定領域に対し、年間予算内で継続開発を行う
当初は3名程度で開発を行う小規模部隊であったが、現在は開発6~7名まで増えている


## 会社単位
### 弊社での問題点
スクラムはチームワークを重要視しているため、MTG(イベント)が多い
人数が多いとMTG時間が伸び、全体的な生産性が下がっている。生産性低下が問題である
また、本来固定メンバでスクラムを実現すべきだが、メンバの入れ替えが多く発生している

### 問題を引き起こす要因
事業要望が、スクラムで対応できる規模感ではなくなっている
スクラムをある領域特化で設けた結果、スクラムという集団に属人化してしまった
その改修を行うためにはスクラムで対応する必要があり、結果として規模が大きくなっている
また、内製エンジニアが少ない環境のため、外部委託で賄っているのも問題である
個人の意見だが、見ていると外部委託のメンバには下記傾向がある印象である
下記傾向がある上で、開発を外部に依存している＋顧客インパクトが大きいシステムのため、切り替えて内製開発を進めるのが難しい

一次請け：元々能力値が高い人が、様々な場所で経験するためにSierを選ぶ
　　　　　→長期的に同じ環境に留まりたいという思考が薄い
     　　　　　→弊社はその上で大手✖若手が多いため、数年で抜けてしまう
二次請け：給料や環境問題、一次請への憧れから早期で抜けることがある
　　　　　→前提として長期就業ではなく、安くても経験！の可能性が高い

### 解決手段はあるのか
①外部委託=悪ではないので、上手く付き合っていく
　悪ではないが、コストのデメリットが大きく、離脱リスクもある
 　開発規模を小さくし、内製化を進める
  　or 内製チームを並行作成し、規模を小さくしたら内製化を進める
　 →小規模な案件は内製チームに切り出し、知見を溜めていく
②徐々に内製化を進める
　コスト面でのメリットが大きい。内製化=離脱しないではない
③一気に内製化に切り替える
　コスト面でのメリットが超大きい。内製化=離脱しないではない

## スクラム単位
### デイリースクラム
15分程度で実施できており問題なし
昨日何をし、本日はどのタスクに対して、どこまで対応するのか明確にできている
### スプリントレビュー
親睦を深める時間として1時間所用している
スクラムでは必要な時間だが、業務に還元できていない
話しやすい関係を作り、業務で発言しやすくすることが目標でもある、、、
意見を言い合う場で、間違える前提で自身が先陣切って会話することが重要
他人ではなく、まずは自身の心理的安全確保→自身がもっと発言する→周囲がもっと発言する
上記スパイラルを作れるよう、自身がもっと話して、もっと発言することを意識する
### スプリントリファインメント
タスク整理の場となっている
司会をローテーションしても良いのでは❓
スプリントレビューほどは大事な話しないし、開発内に閉じた会話が多い
意思決定の場でもないし、司会をローテさせても良いと思う

## まとめ
雰囲気は良いため、自身で苦労はしていない
ただ、どうしても事業会社-一次請け-二次請けの関係性が邪魔になる
自身がもっと会話し、間違ってでも発言し、発言しやすい雰囲気を作るしかない！
まずはそこ。理想的なスクラムマスターの姿ではないが、
チームワークを重要視する！という意味では、スクラムのあるべき姿を推進できるのでは❓
HTTPメソッドを覚える

サーバー周りの勉強でHTTPメソッドを勉強したのでアウトプットします。
完全にメモです、悪しからず…

# HTTPメソッド
HTTPメソッドとは、HTTP通信における処理の種類のこと
HTTP通信とは、Webアプリケーションを表示する際の、情報やデータなどを送受信するための通信方法
http//~で始まる


# GETメソッド
主にデータの取得を目的としており、パラメータをURLに含めて送信する
ブックマークに記録したり、キャッシュを行うことができる
リソースの取得を要求するために使用される
送信したデータはURLのクエリ文字列に追加される形式で送信される
ブックマークに記録することができる
キャッシュを行うことができる
平文でデータが送信されるため、送信データ量に制限がある

# POSTメソッド
データの登録や更新などの書き込みを目的としており、データ本体をリクエストボディに含めて送信する
リクエストの内容を処理するために使用される
サーバー上のリソースを更新や新規作成に使用できる
リクエストボディを使ってデータを送信する
送信データがURIに表示されない
幅広くフォームの送信やAPI利用に使われる
冪等性がない﻿

# PUTメソッド
主にリソースのデータ全置換のために利用される
データ送信方法は、POSTメソッドと同じようにHTTPリクエストボディにデータを追加して送信する
リクエストURIはリソースの識別子として利用される
リクエストBodyに更新後のリソースの全体が含まれる
冪等性（アイデンポテンシー）を持つため、同じリクエストを繰り返しても結果は同じになる
既存のリソースが存在しなければ、新規に作成される
既存のリソースが存在すれば、本文の内容で完全に置き換えられる﻿


:::note warn
PUTメソッドとPOSTメソッドの違いは、PUTメソッドはべき等であるのに対し、POSTメソッドは連続して同じものを実行すると追加の影響が発生する可能性があること
:::

# DELETEメソッド
リソースの削除を安全に行うために推奨されているHTTPメソッド
サーバー上の特定のリソースを削除することができる
レスポンスの内容を返す必要はない
成功した場合は200(OK)や204(No Content)を返す
失敗した場合は404(Not Found)や403(Forbidden)などのエラーコードを返す
CCNA受験(合格)レポート(2024/09/18)

皆様、お久しぶりです。長谷川です。
今回はCCNAの受験レポートを記載します！
今回は6月に受験して以来、三か月ぶり二度目の受験となりました。
また、先に記載しますがタイトルにある通り今回は合格しましたので、もしお時間があれば前回の投稿内容を読んでいただけると幸いです。

https://qiita.com/itsushia/items/d8ade0936127c2736f94

# 受験スコア
今回受験した際のスコアと前回のスコアを記載したいと思います。
CCNA(200-301)は以下の構成となっています。
※各項目の下に前回(6月)と今回(9月)の正答率を記載しています。
* Network Fundamentals(ネットワーク基礎)
6月：55% 今回：50%(5%ダウン)

* Network Access(ネットワークアクセス)
6月：30% 今回：45%(15%アップ)

* IP Connectivity(IP接続)
6月：56% 今回：72%(16%アップ)

* IP Service(IPサービス)
6月：70% 今回：80%(10%アップ)

* Security Fundamentals(セキュリティ基礎)
6月：73% 今回：60%(13%ダウン)

* Automation and Programmability(自動化とプログラミング)
6月：70% 今回：80%(10%アップ)

全体的に振り返ると33%正答率が上がっていました！
Ciscoは合格ラインを正式に公表していないので正式な点数はわかりませんが、恐らくギリギリでの合格だったろうなぁと思っています笑
※まあ、何点でも合格は合格です！

# 三か月間の勉強方法
さて、ここから本題に入ります。
現在CCNAを勉強されている方、既に不合格となり落ち込んでいる方や悩んでいる方、勉強方法に悩んでいる方のヒントになればいいなと思い記載させて頂きます。

* 基本の勉強
基本的には模擬試験を解く→間違えた問題の答えと説明を読んで理解度を上げる。これを毎日のように行いました。
間違えた問題に関しては、設問と答え、回答をルーズリーフにまとめました。(重要な部分や記憶すべき部分は青いボールペンを使用してひたすら暗記しました)
※Ping-tやUdemyの解説では足りない部分は、自分で調べてエクセルにまとめて、Googleドライブに格納して電車内や職場でいつでも見れるようにしました！

* シミュレーション問題
前回の受験時は全く対策をしていなかった問題です。シミュレーション問題とはトポロジー図と設定条件などが提示され、各ホストやスイッチ、ルーターなどを設定していく問題です。
※CLI画面が表示されるのでどんどんコマンドを投入していきます。

CCNA(200-301)試験では88問中3問必ず出ます。
個人的な感想ですが、3問の中でレベルが三段階に分かれているなと感じました。
簡単な問題、中難度の問題、高難度の問題
※簡単な問題は、IPアドレスを設定したりPing試験が完了すればOKレベルの問題と考えて頂ければ問題ないかなと思います。

シミュレーション問題の対策は、基本的にPing-tにあるスイッチとルーターのシナリオ問題をひたすら解きました。
ただ、Ping-tで用意されている問題はIPアドレスやデフォルトゲートウェイの設定、VLANの設定など基本的な問題しか用意されていない為、CCNA本試験で出てくる中難度の問題、高難度の問題の対策には不向きです。
中難度の問題、高難度の問題をしっかり対策したい場合は、Ciscoが無料で提供しているPacket Tracerを利用することをお勧めします。
ただ、私もそうですが初心者がPacket Tracerをインストールした状態では一から構成などを考えないといけない為、意外と時間がかかってしまいます。
その為、ぐぐったりしてPacket Tracerで使えそうな問題などを探して活用するのがおすすめです！

* ドラッグアンドドロップ問題
こちらの問題は本試験では8問くらい出てきたような気がします。
また、この解答形式の問題はいくら探しても模擬試験はありません。
そのため、上述した基本の勉強でひたすら理解度を上げるしかありません。
例えば、AAA(認証、認可、アカウンティング)のそれぞれに分類わけする問題が出てきたとします。
認証はこれとこれ。認可はあれとあれ。アカウンティングはそれとそれ。とぱぱっと仕分けできるように理解しておく必要があります。

# 最後に
正直にこの三か月間は現場業務もばたばたしていたので、「面倒くさいな。」「今日は眠いから明日やろう。。。」と思ったことは何百回とありました。
ただ、毎日アウトプットをすることを意識して自分を奮い立たせて勉強を行いました。
一日5問でもいいので、始めるといいかなと思っております。

最後まで読んでいただきありがとうございました。
React : メモリーリーク対策が不要なケース

古い情報なので何番煎じか分からないが失礼して記述する

## 前提
- react においてブラウザコンソール上にメモリーリーク警告が表示されるケースがある
- これらは component が消える際の開放漏れが原因らしい
    - 参考: https://zenn.dev/reds/articles/25f68e50b42f43


## メモリーリークしないパターン
以下の様な, useState を開放するパターンは本来メモリーリークしない.
あくまで, エラーメッセージ抑制のために用いられている手法とのこと.

```react
useEffect(() => {
    setFlag(true)
    await saveData();  // 非同期処理中にコンポーネントが unmount されるかもしれない
    setFlag(false)
  }, []);
```


## 根拠: 開発者の明確な記述
https://github.com/reactwg/react-18/discussions/82

こちらの中で, 当パターンでは実際にはメモリリークしないと明記されている.
また, react 18 へ上げる事で警告メッセージは表示されなくなるとのこと.


## 謝辞
開発中に教えていただいた皆様, ありがとうございます :pray:
読書記録　「VTuberサプーが教える！　Python　初心者のコード／プロのコード」

## 本の概要

「動けばいいや」の「初心者のコード」と、保守性などの将来まで考えられた「プロのコード」について、簡単な例を示しながら解説を行っている本である。

## 感想

第三章では一般的な良いコード、例えばネストを減らすにはファストリターンを利用しようとか、長い関数は分割しようとか、そういった基礎の部分を教えていて、
第四章では頻出のPythonの標準ライブラリなどの解説をしていた。
そういった章で言っていることがまともで、初心者にも無理なく進められる本だと感じた。

個人的にはPycharmを前提にしているのも良い。初心者がVSCodeで環境構築をするのは厳しいと思っている。

## 同じような本の比較

この手の本と同じような主題の本だと、まず思い浮かぶのはこの本だと思う。
[Good Code, Bad Code ～持続可能な開発のためのソフトウェアエンジニア的思考](https://www.amazon.co.jp/Good-Code-Bad-%EF%BD%9E%E6%8C%81%E7%B6%9A%E5%8F%AF%E8%83%BD%E3%81%AA%E9%96%8B%E7%99%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E7%9A%84%E6%80%9D%E8%80%83/dp/4798068160)

簡単に比較すると、こちらの本のほうが抽象的で一般的な論にしている。
Vtuberの絵で集客することも合わせて、「初心者のコード／プロのコード」は初心者に寄せている感じが強かった。

## 推奨読者層

ぱっと思いつく読者層は次の3つだった。

1. 「SESとかに入って、とりあえずJavaの本を渡されて読んだ」というような人の二冊目の本に良さそうだ
そのレベルの人であれば上の「Good Code, Bad Code」は少しむずかしいかなと思う。

2. SI系の一次請けの人たちも読んだほうが良さそうだ
自分がSESで派遣されていた現場では、ジュニア層からシニア層までこの本の内容を理解できている人はいなさそうなレベルだった。
CMをテレビやラジオで流すような巨大なSI系にも派遣されたこともあるけど、ろくなコードを書いている人は結局見なかった。

3. プログラミングを職業としていなくても手元にPythonのコードがあり、それを改良しながら仕事をしなければいけない人にも良い
dataclassをはじめとした実務でもよく使う標準ライブラリを紹介しているのは大きい。


## 個人的に感じた改善ポイント

きちんと人に進められる本だと感じたからこそ、いくつか気になった場所がある。

+ 個人的な「動けばいいや」なコードの典型例は「例外を握りつぶすコード」で、それに関する言及は欲しかった
+ インプレースの使い所に「シビアな処理能力が求められる箇所」と言っていたが、そこまでシビアな場合は「Pythonを使わない」という選択肢も入れてほしい
+ assert文は本番環境では無視される事を言わないとトラブりそう

あと、どうしようもないのはわかってるんだが、40代半ば以上の人に勧めるのは若干抵抗があった。
「Pythonで日曜大工的にプログラムを書いているんだが、どうにも詰まっている」って人だったのでちょうどいい本ではあるんだが。
【TypeScript】オブジェクトの値を読み取り専用にする方法

## Readonly`<T>`を使用する
`Readonly<T>`を使用すると`T`のプロパティを全てを読み取り専用にできます。

```ts
type Profile = {
  name: string
  age: number
}

type PersonalDataType = Readonly<Profile>

const friend: PersonalDataType = {
  name: "田中",
  age: 19
}

// friend.age++
// error TS2540: Cannot assign to 'age' because it is a read-only property.

type Yomitorisenyo<T> = {
  readonly [P in keyof T]: T[P];
};
type YomitorisenyoProfile = Yomitorisenyo<Profile>
// type YomitorisenyoProfile = {
//   readonly name: string;
//   readonly age: number;
// }


type User = {
  id: number,
  name: string,
}
 
const user: Readonly<User> = {
  id: 1,
  name: '田中',
};
 
user.name = '佐藤'
// Cannot assign to 'title' because it is a read-only property.

```

:::note warn
`Readonly<T>`は再帰的に読み取り専用にしません。
:::

```ts
const user: Readonly<User> = {
  id: 1,
  name: {
    first: "太郎",
    last: "田中",
  }
};
// name.firstとname.lastは読み取り専用にならない
```
git rebaseによるローカルとリモートのずれの発生と解消

## 背景
git rebaseを行ったところ、ローカルとリモートでずれた状態になった。
あまり実務では実施しないため、どのような動きで実現・解消できるか記載。

## 目的
rebase が起こす問題を知る

## 実施内容
![スクリーンショット 2024-09-18 21.52.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644072/bdb104af-e046-5c90-fae1-46f0bce6d7a9.png)
もともと上記画像のorigin/feature-1にいたfeature-1を下記でrebaseしたのが上記画像の状態
```git
git rebase develop
```
しかし、上記操作によりリモートとずれてしまっている。（feature-1とorigin/feature-1がずれている）
そのため、下記を実施してリモートの状態を強制的にローカルと合わせた。

```git
git push --force origin feature-1
```
実施後が下記の図。
ローカルとリモートのズレがなくなった。
![スクリーンショット 2024-09-18 21.56.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644072/6d8f3379-f3c0-4996-bbb5-63e77fdb7b60.png)


## 学び
- rebaseはgitの履歴の改変であるため、ローカル内のブランチに留めること。
- 具体的な使用場所は、developからfeatureを切ったが、developが先に進んでいた時など。
- featureはこまめにpushしているとrebaseするのは難しくなりそう。

## 次のアクション
- ローカル内のブランチはrebaseで綺麗にしてみる
- rebaseでコンフリクトが起きた場合も試してみる
そして、push時はgitの内部的にはどのような仕組みで行われているのか気になった。
React初心者 はじめてのアプリを作る

## 作ったもの
「学習記録アプリ」
「JISOU」の最初の課題として出された以下のお題。
> エンジニアとしての学習時間は1000時間が必要と言われています
> そこで日々の学習の内容と学習時間を記録するアプリを作ることにしました。

できたのがこちら。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275708/994a5edf-d757-5153-2231-ead3fe3182cf.png">
機能も全然足りていない。スタイルもあてていない。
だがしかし、これは確かにアプリケーション。


## 所要時間
ちょっと詰まって2時間くらいでした。

## 詰まったところ
- reduce
初めて使いました。今までだったら、何も考えずにforでぶん回していました。
- useState
setした後に、すぐconsoleで値を確認しようとして「更新されていない…なぜ…」ってなりました。
関数を出ないと更新されないようです。このあたりもう少し詳しく学んでいきたいところ。


## 感想
### React楽すぎん…？
いや、これは本当に思いました。VanillaJSでやるより圧倒的に楽。
ちょっと罪悪感が出るくらい便利で楽。エラーメッセージも親切。

こりゃぁ、流行るわけだ…、と、痛感しました。

まだReactの触りをやっただけで、何もわかっていない段階だと思いますが、
これだったら過去に諦めたアレやコレも作れるのでは？と、久しぶりにワクワクさせられました。

## これから
ますますReactを学ぶのが楽しくなりそうな予感です。
この先、勉強する意欲がなくなったら、この記事を見返してワクワクを呼び覚ましたいと思います。

## JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからお願いします:point_down:
https://projisou.jp
🔰TypeScriptの環境構築をまとめてみた

## TypeScriptでコーティングするために必要な環境構築についてまとめていきます。
※Udemyの内容を噛み砕いて私なりにまとめました。

### TypeScript（TS）とは
JavaScript（JS）のスーパーセット（上位互換）
* 型を指定することができ堅牢なコードを書ける
* 古いWebページにも対応できる
などなど、さまざまな便利な機能が搭載されています。

TSで書いたコードはJSにコンパイル（変換）され、JSで動的なWebページを実現します。

### 環境構築
1. VS-Codeで開発用フォルダを開く
1. ターミナルを開く `⌘ + J`
1. packege.jsonファイルの作成　`npm init`
1. 3実行時に設定についていくつか問われるが、全てEnterでOK
1. lite-serverをpackege.jsonに追加 `npm install dev-server lite-server`
1. packege.jsonの`scripts`オブジェクトに手動で`”start”: “lite-server”`を追加
    * オブジェクトのプロパティは`,`で区切らないとエラーになるので注意
1. サーバープロセスを起動する `npm start`

### よく使うコマンド操作
|名称|説明|コマンド|
|---|---|---|
|コンパイル|TSからJSにコンパイル（変換）する機能|`tsc ファイル名`|
|ウォッチモード|TSをコンパイルすると、Webアプリが自動更新される機能|`tsc ファイル名 —watch` <br> `tct ファイル名 -w`|
|ファイルを開く|１階層下のファイルを指定して開く|`cd ファイル名`|
|ファイル戻る|ファイルを１階層戻る|`cd ..`|
「git pull」はgitの内部では何をしているか

## 背景
昨日gitの内部の仕組みを学習した。
git pullの時の解説がなく、何が行われているか疑問に思った。

## 復習
・git fetch の際に行われているのは、リモートのgitオブジェクト＆リファレンスを「origin/〇〇」としてローカルに持ってくること。つまり、ローカルのリファレンスやブランチは変化しない。
・git merge の際に行われているのは、リファレンスの付け替え（commitオブジェクトの生成はない）。

## git pullは何をしている？

答えは書いてあった。
pull = fetch + merge

つまり、下記を行っている。
1. fetchでリモートのgitオブジェクト、リファレンスをローカルに持ってきた後、
2. mergeでリファレンスを動かす（コミットオブジェクトは作成されない）

![スクリーンショット 2024-09-18 22.22.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644072/f8b51313-cfc2-f4cc-db89-ddf0eabcf1ff.png)

## 学び
- git pull時の動きが少しイメージできるようになった。

## 次のアクション
gitを動かしながらrebaseやmergeの様々なパターンを確認する。
個人的に感じたMVCアーキテクチャとレイヤードアーキテクチャの違いについて

## はじめに
初めまして。私は新卒2年目のエンジニアで、これまでに2つのプロジェクトに携わりました。1つ目のプロジェクトはMVCアーキテクチャを採用し、2つ目はドメイン駆動設計（DDD）とレイヤードアーキテクチャに基づいて開発を行いました。

この記事では、これら2つのアーキテクチャの比較を、私自身の経験を基に説明します。まだ経験が浅い部分もありますが、意見やフィードバックをいただけると嬉しいです。

## それぞれのメリット、デメリットについて
|                          | 学習コスト | 開発スピード         | 責務の分離                           | 
| ------------------------ | ---------- | -------------------- | ------------------------------------ | 
| MVC                      | 比較的低い | 小〜中規模だと早い   | チームで決めておかないと不明瞭になる | 
| レイヤードアーキテクチャ | 高い       | コードが増え遅くなる | 明確                                 | 

私が最近感じているのは責務の分離についてです

## 責務の分離について
責務の分離とは、システムの各部分が「何を担当するか」を明確にし、それぞれが持つ責務（役割）を厳密に分けることです。レイヤードアーキテクチャでは、各層が特定の役割を持つため、コードの可読性や保守性が向上します。

例えば、私が担当したプロジェクトでは、次のように責務を分離していました。

- **interface層**: 外部との連携を担当し、リクエストやレスポンスの変換を行う
- **application層**: ビジネスロジックの流れ（ユースケース）を制御する
- **domain層**: ドメイン固有のロジックやエンティティを扱う
- **infra層**: データベースへのアクセスや永続化を行う

このように、責務が明確になることで、各層が独立して機能し、コードの変更が他の部分に与える影響を最小限に抑えられます。一方、MVCアーキテクチャでは、モデル、ビュー、コントローラーにドメインロジックが散らばりやすく、特に大規模プロジェクトになると保守が困難になります。


以下に例を挙げます
これは注文(order)モデルにデータ取得とドメインロジックが混在している例です

```ruby:order.rb
class Order < ApplicationRecord
  belongs_to :customer
  has_many :order_items

  # 注文IDで注文を取得するリポジトリ的なロジック
  def self.find_by_order_id(order_id)
    find_by(id: order_id)
  end

  # 顧客IDで注文を取得するリポジトリ的なロジック
  def self.find_all_by_customer(customer_id)
    where(customer_id: customer_id)
  end

  # 注文の合計金額を計算するビジネスロジック
  def total_price
    order_items.sum { |item| item.quantity * item.product.price }
  end

  # 支払い処理（ビジネスロジック）
  def process_payment
    total = total_price
    payment_gateway = PaymentGateway.new(customer.payment_info)
    unless payment_gateway.charge(total)
      errors.add(:base, "Payment failed")
      return false
    end
    true
  end

  # 注文処理のための複合ビジネスロジック
  def place_order
    if process_payment
      order_items.each do |item|
        item.product.update(stock: item.product.stock - item.quantity)
      end
      update(status: 'completed')
    else
      errors.add(:base, "Order could not be placed")
    end
  end

```

こんな感じでデータの永続化やドメインロジックが混在してしまいわかりにくくなっています
前いたプロジェクトはMVCを使っていて、ドメインロジックがmodel,view,controller全てに対して散らばっていました
そうなってくると保守性を下がり、大規模になるにつれ生産性も落ちていきます

### シグネチャについて
責務の分離をする際に重要だと感じたものの一つにシグネチャがあります
シグネチャとは、関数やメソッドがどのような引数を受け取り、どのような値を返すかを定義したものです。これが明確であれば、他の開発者がコードを読む際に、関数の動作や目的をすぐに理解でき、変更による影響範囲も最小限に抑えられます。

特にGoのインターフェースでは、関数のシグネチャを定義することで、そのインターフェースを実装する全ての構造体が、同じシグネチャのメソッドを持つことを保証できます。これにより、どの実装が使われているかを意識せずに同じインターフェースを利用できる点が強力です。例えば、次のようなシグネチャを持つ `OrderRepository` インターフェースがあります。

```go:order.go
type OrderRepository interface {
	// 注文を保存する
	Create(ctx context.Context, order *Order) error
	// IDで注文を取得する
	GetByID(ctx context.Context, id int) (*Order, error)
	// 顧客IDで注文リストを取得する
	GetByCustomerID(ctx context.Context, customerID int) ([]*Order, error)
	// 注文を更新する
	Update(ctx context.Context, order *Order) error
	// 注文を削除する
	Delete(ctx context.Context, id int) error
}
```

### 終わりに
エンジニアとしての経験はまだ浅いですが、これまでに感じたことをアウトプットすることで、より深く理解し、改善点を見つけたいと思っています。もしお気づきの点があれば、ぜひご指摘いただければ幸いです。
MVCで大規模になってしまった場合はどうやって対処すればいいのか知りたいなとも感じます
VMWare ESXIにてVyosを構築する

# 概要
vyosをesxiにて構築する際の手順を備忘録としてここで記載する。
##  環境のバージョン

- ESXi:8.0.0
- Vyos:1.5.0

# 手順
事前に以下のサイトから、vyosのisoをダウンロードしておく。

https://vyos.net/get/nightly-builds/

ここでは1.5.0の一番上をDLする。なお。LTS版は有料である。Rolling Releaseであれば無料でDL可能。

## esxiで作成していく。

まず、必要なネットワークをESXiの`ネットワーク`から作成する。
任意の名前とVlanID、必要な仮想スイッチを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/b0f3d017-fd96-77de-a382-ac29f936652a.png)

その後、新規仮想マシンを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/7b740dbe-47fe-a272-87a2-0bf4b6d405e7.png)

その後、任意の名前を付ける。
- 互換性
    - ESXI 8.0 仮想マシン
- ゲストOSファミリ
    - Linux
- ゲストOSのバージョン
    - Debian（ここでは12 64ビット）
を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/8e61837b-3571-8fe5-3d1e-0f12e42b7bde.png)

ストレージはそのままにして`次へ`を押す。

スペックを選択する。今回は
- CPU：2core
- メモリ：4GB
- ハードディスク：16G
にする。
そして下へスクロールし、ネットワークアダプタに必要なvlanの数だけいれる。
また。`CD/DVD`に、ダウンロードしたisoファイルを選択して`次へ`を押す。

その後、完了を押して起動させる。コンソールを見ると起動が走る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/8ec86735-a041-94eb-6a61-202ec4896fb9.png)

立ち上がったらログインする。初期の認証情報は

- ユーザー名
    - vyos
- パスワード
    - vyos
である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/814eda81-2bf8-4112-cf39-8abf7c095047.png)

この状態はCDから起動しているだけでインストール自体はできていない。そのため以下のコマンドを実行してisoをインストールする。
```
install image
```

指示に従い、インストールを行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/4c9aca21-7ffb-d6c8-d853-0f7ab787fd39.png)

その後、ESXIから、`Edit`を押し、isoファイルをCD/DVDの所から外す。

## VYOS側での作業
ここではユーザーの作成、ログイン用IPの設定,SSHの有効化までを行う。
ログイン用パスワードの作成は以下のコマンド
```
set system login user ユーザー名 authentication plaintest-password パスワード
```

なお、管理用のIPを付けるには以下のコマンド群を実行する。
まずは
```
run show running-command
```
で、ログイン用IPに付ける予定のMACアドレスをESXIと照らし合わせて確認する。

その後、以下のコマンドを実行
```
set interfaces ethernet インターフェース名 vrf VRF名
```
以下のコマンドを実行
```
set interfaces ethernet インターフェース名 address IPアドレス/サブネットマスク
```
その後、vrfテーブルの作成
```
set vrf name mgmt table 100~65535までの番号
```
その後、vrf用のスタティックルート（デフォルトルート）を作成する。
```
set vrf name mgmt protocols static route 0.0.0.0/0 next-hop ゲートウェイのIP
```
その後、以下のコマンドでsshを有効化する。
```
set service ssh vrf mgmt
```

*ip aなどのLinuxコマンドで、自分についているIPを確認できる。

## 参考サイト

https://qiita.com/h_tyokinuhata/items/f1f6da1ba9e1265b4192
[Cryptosystem] デジタル証明書の失効情報

# 用語一覧
|||
|:--|:--|
|CA|認証局|
|CRL|有効期限内に何らかの理由で失効させられたデジタル証明書のリスト<br>失効日時の記載がある|

# 失効情報の確認方式
|||
|:--|:--|
|CRLモデル|CAが定期的にCRLを公開|
|OSCPモデル|Online Certificate Status Protocol<br>証明書の失効情報を保持したサーバ（``OSCPレスポンダ`）に、確認したい証明書のシリアル番号と証明書発行者の識別子を送り、その応答で証明書の有効性を確認する|


# 参考リンク
- [令和2秋38](https://www.ap-siken.com/kakomon/02_aki/q38.html#:~:text=を表示する-,解説,の結果を受け取ります%E3%80%82)
- [令和2秋36](https://www.ap-siken.com/kakomon/29_aki/q36.html)
[FontViewMax v0.1.0リリース]真に利用可能なフォント一覧を表示するフォントビューアの更新版をリリース

# FontViewMax を更新しました
ユーザプロファイル配下にインストールしたフォントも表示するフォントビューアの最初の更新をアップロードしました。
以下の Github にて公開していますので、ダウンロードして使ってみてください。

https://github.com/tkmry/FontViewMax

なぜ本ツールをリリースするに至ったのか、技術的な背景については以下の初期リリース記事をご参照ください。

https://qiita.com/tkmry/items/c6a7a008f1d839481686

# 動作環境(確認済み)
Windows 11 Pro 23H2

# 動作画面
![スクリーンショット 2024-09-18 214506.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124578/aa10d0b7-271e-bccd-27f2-2e93c5b1f025.png)

# 主な更新内容
フォントの英語名(別名)がある場合にはそれを併記するようにしました。
GIMPでは英語でフォント名を指定しなければならない場合があるための更新となります。
await userEventはどこまで待ってくれるのか

## はじめに
TDDで開発をしていく中で実装は上手く行っているのにテストが上手く行かないパターンってありませんか？
僕はそのとき結構むやみやたらにawaitやact、waitforをむやみやたらに入れてしまっているのとここで一度機能を確認しておきたいと思いました。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- TDDを取り入れている開発をしている方

## await userEvent.clickでテストが失敗するパターン
使用バージョン
- "@testing-library/user-event": "^14.5.2"
### dialogを表示させるflagがsetTimeoutによってラップされている場合
```typescript
// 実装
function UserEventTryPage() {
  const [isShowDialog, setIsShowDialog] = useState(false);

  return (
    <div>
      <button
        onClick={() => {
          setTimeout(() => {
            setIsShowDialog(true);
          }, 1000);
        }}
      >
        dialog open
      </button>
      {isShowDialog && <p>dialog title</p>}
    </div>
  );
}
```

```typescript
// テスト
it("dialog openボタンが押されてから1秒後にdialog titleが見えている事", async () => {
  render(<UserEventTryPage />);

  expect(screen.queryByText("dialog title")).not.toBeInTheDocument();

  await userEvent.click(
    screen.getByRole("button", { name: "dialog open" }),
  );

  expect(screen.getByText("dialog title")).toBeInTheDocument();
});
```
await userEventではその時に発生する非同期やUIのレンダリングは待ってくれるが
非同期タイマー処理は待ってくれないためテストが失敗する
ではこのような場合どうすればいいか？
1. useFakeTimersを使用してタイマーを偽物に置き換えて手動で時間を経過させる方法
   https://qiita.com/engineer_ponpon/items/dfe8473ea4769a65174c
1. 下記のようにexpectに await waitforを入れて要素が見えるまで待ってもらう

```typescript
it("dialog openボタンが押されてから1秒後にdialog titleが見えている事", async () => {
  render(<UserEventTryPage />);

  expect(screen.queryByText("dialog title")).not.toBeInTheDocument();
  
  await userEvent.click(screen.getByRole("button", { name: "dialog open" }));
  
  await waitFor(()=>{
    expect(screen.getByText("dialog title")).toBeInTheDocument();
  })
});
```
:::note warn
注意
onClick内がsetTimeoutとstateの更新だけだとテストが失敗しました。
なんでもいいのですがconsole.log()など何かしら入れないとテストが成功しませんでした。
もしかすると現時点でのバグかもしれません。
```typescript
<button
  onClick={() => {
    console.log()
    setTimeout(() => {
      setIsShowDialog(true);
    }, 1000);
  }}
>
  dialog open
</button>
```
:::


## await userEvent.clickでテストが成功するパターン

### 非同期の処理がある場合
Promiseの非同期な処理が入っている場合はその処理を待ってくれる
```typescript
function UserEventTryPage() {
  const [isShowDialog, setIsShowDialog] = useState(false);

  return (
    <div>
      <button
        onClick={async () => {
          await returnPromise();
          setIsShowDialog(true);
        }}
      >
        dialog open
      </button>
      {isShowDialog && <p>dialog title</p>}
    </div>
  );
}
```
```typescript
it("dialog openボタンが押されてから1秒後にdialog titleが見えている事", async () => {
  render(<UserEventTryPage />);

  expect(screen.queryByText("dialog title")).not.toBeInTheDocument();

  await userEvent.click(
    screen.getByRole("button", { name: "dialog open" }),
  );

  expect(screen.getByText("dialog title")).toBeInTheDocument();
});
```


## おわりに
await userEventは非同期を待ってくれるものという認識でしたが、
Promiseのような非同期関数の処理は待ってくれるものの、
タイマーが絡んでいる非同期な処理は待ってくれない事がわかった

最後まで読んで頂きありがとうございました。
少しでも参考になったと思ったらいいね！お願いします
Cloud RunでDockerコンテナの立ち上げに失敗するときの原因調査と対策

# これは何？

Apple Silicon、M1 MacBook ProでビルドしたDockerイメージをCloud Runで動かそうとすると、コンテナが立ち上がる前にエラーで落ちる。
コンテナが立ち上がっていないため、詳しいエラー内容もわからない。

このような事象に遭遇して解決に時間を要したため、原因調査や対策について備忘録を残しておく。

# Dockerイメージのアーキテクチャによる問題

1つ目に遭遇したエラーは以下の内容。

```
terminated: Application failed to start: failed to load /valhalla/scripts/run.sh: exec format error
Default STARTUP TCP probe failed 1 time consecutively for container "custom-valhalla-1" on port 8002. The instance was not started.
```

これはApple Siliconだとありがちなもので、Dockerイメージのアーキテクチャが問題である。
Cloud Runは `x86_64` であることに対し、Apple Silicon上でビルドしたDockerイメージは `arm64` となる。
そのため、ビルド時に明示的にプラットフォームを指定すれば良い。

```sh
$ docker build --platform linux/amd64 -t custom-valhalla:0.1.0 .
```

ちなみに、 `valhalla` というのは、OSSの経路検索エンジン。

https://github.com/valhalla/valhalla

# Cloud Runの実行環境による問題

2つ目に遭遇したエラーは以下の内容。

```
The user-provided container failed to start and listen on the port defined provided by the PORT=8002 environment variable. 
```

これはエラーメッセージのみから追うのは難しいが、Cloud Runの実行環境による問題だった。

https://cloud.google.com/run/docs/about-execution-environments?hl=ja&_gl=1*10obwjq*_ga*MTIzODQxNTgwMC4xNzE0NDYwNjg3*_ga_WH2QY8WWF5*MTcyNjY2MDQxOC4xOC4xLjE3MjY2NjI4MTkuNjAuMC4w

Cloud Runには2024年9月時点で2種類の実行環境が用意されており、デフォルトでは第1世代が選択される。
第1世代はコールドスタートが高速だというメリットがあるものの、第2世代のようなLinuxの完全互換性は実現されていない。

そのため、第1世代ではコンテナを動かすために必要な素材が入っておらず、コンテナの起動に失敗してしまっていたのがこのエラーの原因だった。
第2世代を選択することで無事コンテナが起動された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363036/e0a690c7-30e6-f2fe-234b-cb7f3a57d7a1.png)

（デフォルトを選ぶとCloud Runが適切な実行環境を選択してくれるとのことだが、自分の場合はそうではなかった……）

# どのように原因調査を進めるのが良いか？

最後に、Cloud Runのエラーに遭遇した際の対処Tipsを記載して終わる。

1. ググる
1. Google Cloud上のログを確認する
1. ChatGPTなどの生成AIに質問する
1. **AWS Lamdaでデプロイしてみる**

1と2は当然のこととして、最近だと3つ目のChatGPTにも大いに助けられている。
ただし、これらは有用なエラーメッセージがあってこそ輝くものである。

「Cloud Runの実行環境による問題」の問題で遭遇したエラーのように、 **そもそもコンテナが立ち上がらないため詳細なエラーログを取得できない** 場面もある。
そういった際、一度Google Cloudから離れ、AWSにてデプロイすることで異なるエラーログを得ることができるケースも存在する。

実際、今回私がGoogle Cloud (Cloud Run)で得たエラーログと、AWS (Lambda)で得たエラーログを比較すると下記の通りである。

```sh
# Cloud Runのエラーログ
The user-provided container failed to start and listen on the port defined provided by the PORT=8002 environment variable. 

# Lambdaのエラーログ
If you run with custom UID or GID you have to create the mapped directory to the container's /custom files manually before starting the image
```

前者はPORTまわりに問題があるかも、といったエラーを出してくれているが、どこを確認してもPORT設定には問題が見つからなかった。
一方、後者はどうやらcustomディレクトリのファイルをどうにかする必要があることを教えてくれている。
後者の内容でググると、なんと下記記事にたどり着き、今回の原因はCloud Runの実行環境が問題であることを知れたのである。

https://github.com/gis-ops/docker-valhalla/discussions/87

（AWSで発生したエラーをググって、Google Cloudの解決策に辿り着くのは何とも皮肉であるが……）
どうしようもなくなったら利用するクラウドを変えてみるというのは、エラー原因調査においてひとつの選択肢なのだろう。
【TypeScript】typeとinterfaceの違いを表解で解説する

# はじめに

TypeScriptの勉強をしている中で、typeとinterfaceの違いについてだいぶややこしいなと思ったので、備忘録としてまとめておきます。

# 登場背景

オブジェクトを作成する際に、下記のように型注釈としてそれぞれのプロパティを宣言するとなった場合、プロパティの数が増えていくにつれて、可読性が落ちてしまうといった問題がありました。そこで、その問題を解決するために、typeとinterfaceといったものが登場しました。

```ts
const student: {name: string, age: number, hobby: string} = {
    name: "Taro",
    age: 18,
    hobby: "soccer"
};
console.log(student.name); // "Taro"
console.log(student.age); // 18
console.log(student.hobby); // "soccer"
```

# typeとinterfaceの定義

### type

typeとは、型に名前をつけることができるエイリアスになっています。下記の例では、`User`といった名前にて型の宣言を行ってくれます。

```ts
type User = {
  name: string,
  age: number,
  hobby: string
}
const student: User = {
    name: "Taro",
    age: 18,
    hobby: "soccer"
};
console.log(student.name); // "Taro"
console.log(student.age); // 18
console.log(student.hobby); // "soccer"
```

### interface

typeと同様に、型に名前をつけることができ、かつ**オブジェクト構造に特化して定義した型**となっています。
```ts
interface User {
  name: string,
  age: number,
  hobby: string
}
const student: User = {
    name: "Taro",
    age: 18,
    hobby: "soccer"
};
console.log(student.name); // "Taro"
console.log(student.age); // 18
console.log(student.hobby); // "soccer"
```

# typeとinterfaceの違い

上記の説明では、typeとinterfaceに違いがないと感じるかもしれませんが、
大きく分けて3つの違いがあります。

|内容|type|interface|
|:-:|:-:|:-:|
|型の種類|オブジェクト型以外の型でも定義可能|オブジェクト型のみ|
|型のマージ|×|◯|
|継承|×|◯|

### 型の種類
* type：オブジェクト型以外(union型,tuple型など)の宣言が可能
* interface：オブジェクト型のみの宣言が可能

```type.ts
// type:定義できる(union型)
type SupportLanguage = "jp" | "en" | "fr" | "it"
```
```interface.ts
// interface:定義できない(union型)
interface SupportLanguage { "jp" | "en" | "fr" | "it" }
```

### 型のマージ
* type：同名の型を宣言した場合、マージされない
* interface：同名の型を宣言した場合、マージされる
```type.ts
// type:マージできない(エラー発生)
type User = {
  name: string
}
type User = {
  age: number
}
```
```interface.ts
// interface:マージできる
interface User {
  name: string
}
interface User {
  age: number
}

const student: User {
  name: "Taro",
  age: 18
}
```

### 継承
* type：継承できないが、交差型では表現可能
* interface：継承ができる

```type.ts
type Name = {
  name: string;
};
type Age = {
  age: number;
};

// 交差型(intersection型)で表現可能
type Member = Name & Age;

const student: Member = {
  name: "Taro",
  age: 18
};
```
```interface.ts
interface Name {
  name: string;
}

interface User extends Name {
  age: number;
}

const student: User = {
  name: "Taro",
  age: 18
};
```

# 最後に

本記事では、typeとinterfaceの違いについて解説しました。
かつてはinterfaceを使うことが多かったようですが、最近はtypeで十分に機能を賄えるようになったので、type派が多くなったようです。
自分も、実際にアプリ開発するときに使い分けることができればと思いました！
【Go言語】　クロージャー

# 前回までのあらすじ
第1回目は「型ごとの特徴」について学びました。もしよかったらご覧ください。

https://qiita.com/koutorino/items/84b4895ff35f86d1d2f4


今回も引き続きUdemyの『【Go入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』の内容をもとに学習を進めていきます。

https://www.udemy.com/course/golang-webgosql/?couponCode=ST11MT91624B


# クロージャーとは
wikiでクロージャーを調べると以下のような説明がありました。

>関数閉包はプログラミング言語における関数オブジェクトの一種。いくつかの言語ではラムダ式や無名関数にて利用>可能な機能・概念である。引数以外の変数を実行時の環境ではなく、自身が定義された環境（静的スコープ）において>解決することを特徴とする。関数とそれを評価する環境のペアであるともいえる。

ちょっと何を言っているのかわからないですが、簡単にいうと関数の外で定義された変数の状態を保持し、後で使用することができる関数のことだと思っています。実際にコードベースで見た方がわかるかなと思うので早速実践していきます。

## Go言語でクロージャーを書いてみた。
```golang
func AddCounter() func() int {
	var store int = 1
	return func() int {
		s := store
		store++
		return s
	}
}

func main() {
	f := AddCounter()
	fmt.Println(f()) // 1
	fmt.Println(f()) // 2
	fmt.Println(f()) // 3
	fmt.Println(f()) // 4
}
```

これがクロージャーというものです。
`main()`で`f := AddCounter`と`f`に代入してから、4回呼び出すとそれぞれ違う値が返ってきます。
これは`AddCounter()`が変数の状態を維持しており、関数が呼ばれるたびに前回の状態を保持した状態から処理を始めるからです。仕組みを1つずつみていきましょう。

`f := AddCounter()`との記載があるため、`f`には以下の無名関数が入ってきます。

```golang
func() int {
		s := store
		store++
		return s
	}
```

1回目に呼び出した時の処理からみていきましょう。呼び出された時に`AddCounter()`の`store`は`1`です。結果的に最初の処理では`1`を出力します。
```golang
//AddCounter()で定義されている変数
var store int = 1

func() int {
		s := store // sにstore(1)を入れる。
		store++    // store = 2　になる。
		return s   // 現在sには1が入っている。
	}
```

2回目です。呼び出された時に`AddCounter()`の`store`は`2`になります。なぜかというと、先ほどの`store++`の処理で`store = 2`になっているからです。
```golang
//AddCounter()で定義されている変数
var store int = 2

func() int {
		s := store // sにstore(2)を入れる。
		store++    // store = 3　になる。
		return s   // 現在sには2が入っている。
	}
```

あとはこれの繰り返しです。
```golang
//3回目
//AddCounter()で定義されている変数
var store int = 3

func() int {
		s := store // sにstore(3)を入れる。
		store++    // store = 4　になる。
		return s   // 現在sには3が入っている。
	}

//4回目
//AddCounter()で定義されている変数
var store int = 4

func() int {
		s := store // sにstore(4)を入れる。
		store++    // store = 5　になる。
		return s   // 現在sには4が入っている。
	}
```
結果的に関数を呼ぶたびに数値が増えるということになります。

## 使い道
**状態を持つ関数**
関数が内部状態を持つようにすることができます。例えば、カウンターを保持する関数を作成できます。

**ファクトリ関数**
特定の設定に基づいて異なる動作をする関数を作成できます。動的に異なる振る舞いを持つ関数を生成することができます。

**データのカプセル化**
外部変数の状態を閉じ込め、外部から直接アクセスできないようにしながら、制御された方法でアクセス・変更できる関数を作るのに役立ちます。

という感じの使い方があるそうです。ただ、私はまだ使っているところに出会っていないです。使い方によっては面白そうなことはできそうな感じがしますね。

# ジェネレーターとは
必要な時に一つずつ値を順次生成するものジェネレーターと呼び、上記のクロージャーの例もその1つになります。今回は1ずつ増やすという簡単な実装でしたが、フィボナッチ数列を生成するジェネレーターなども応用すれば作ることができます。ぜひ興味がある人は作ってみてください。

## ジェネレーターの注意点
当たり前と言えば当たり前ですが、変数名を変えてジェネレーターを実行するとそれぞれで値を保持するようになります。
```golang
func AddCounter() func() int {
	var store int = 1
	return func() int {
		s := store
		store++
		return s
	}
}

func main() {
f := AddCounter()
fmt.Println(f()) // 1
fmt.Println(f()) // 2
fmt.Println(f()) // 3
fmt.Println(f()) // 4

f2 := AddCounter()
fmt.Println(f2()) // 1
fmt.Println(f2()) // 2
fmt.Println(f2()) // 3
fmt.Println(f2()) // 4    
}
```


# まとめ
### 是非お目にかかりたいです。