OmniAICreator/Qiita-1.07M huggingface dataset:
【ChatGPT＋DALL-E3】募集企画、無事に終了しました。


　どうも、カーブミラーです。

　今回は、募集企画が無事に終了したご報告です。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　今日は、
　　エイプリルフールですね。
　　　もう誰がを騙しましたか？

　ここでは、
　　ウソは書きませんよ。

　私は、昔から
　　騙される側ですからw
***
　先週の金曜日に
　　お知らせしました
　　　募集企画、無事に終了しました。
[【ChatGPT＋DALL-E3】だけじゃない。X-Twitterで画像の企画しました的な内容です。](https://qiita.com/kabumira/items/7c64f5f6bd253169f5e6)

　テーマ
　『#AIファッション雑誌を飾ろう』で
　　募集して、24名様に
　　　応募していただきました。
　　　　感謝します🙇

　今回は、
　　縛りが多いにもかかわらず、
　　　参加者が多くいらして、
　　　　私としては、
　　　　　うれしい限りでした😄

　縛りというのは、
　　以下のとおりでした。
　　　ダメだよ、という縛りですね。

　・人型以外
　　(イカ・タコ・キノコなんかはダメw)
　　(でも、人型の頭に使う分にはOK)

　・水着、下着、中高の制服
　・プラグスーツ的な
　　身体のラインだけのものはダメ
　・ウェディングドレスもダメ
　・和服(自分縛り。Mではないw)

　ファッション雑誌に
　　載せる前提の服装を
　　　お願いしました。
***
　ここでは
　　紹介しませんが、
　　　普段着、
　　　街歩き服、
　　　ショッピング服、
　　　オフィス服、
　　　デート服、
　　　ファッションショーで
　　　　披露されるような
　　　　　デザイナーのドレスまで。

　本当に、
　　さまざまな服装でした。

　そのひとつひとつに
　　服装の詳細と感想を
　　　コメントしていく作業は
　　　　なかなかに大変でした😅
***
　その作業を
　　手助けしてくれたのが
　　　ChatGPTさんです。

　画像の服装を
　　解析してもらって、
　　　詳細を教えてもらいました。

　そこから服装の
　　おおまかな要素を
　　　抽出して。

　自分なりの
　　コメントを書いて、
　　　送りました。

　X-Twitterの文字数制限があって
　（プレミアムならば気にならない）
　　文字数を気にしながらの
　　　コメント作成でした。

　ChatGPTさんの手助けがなかったら
　　きっとこの服装の企画は
　　　やらなかったでしょうね。

　今回使った解析Promptは、
　　服装・装飾品に限ったもので
　　　背景や人物などは
　　　　解析から、外しました。

　別に、
　　すべてコピってやるのも
　　　普段ならば、いいのですが、
　　　　今回の目的には
　　　　　邪魔になります。

　それで
　　服装や装飾品に絞っての
　　　解析にしたのです。

　ただ、
　　もちろん完璧ではなく、
　　　何度やっても
　　　　うまくいかない場面も
　　　　　ありました。

　そこは
　　人間である私が
　　　修正するしかありませんでした。
***
　もしも
　　みなさんが
　　　こうした企画を立てて、
　　　　集まってくる画像を
　　　　　ChatGPTさんに
　　　　　　解析させる場合、
　　　　　　　全幅の信頼をおいては
　　　　　　　　いけません🤔

　別に、ハルシネーションだ
　　というわけではありません。

　人間でもそうですが、
　　見誤りというのは
　　　あるからです。

　また、
　　ChatGPTさんの解析能力は
　　　それほどのレベルでは
　　　　ないのもあります。

　言葉として知ってはいても
　　言葉と画像が、結びつくかは
　　　また別物ですしね。

　これらのことが
　　みなさんの
　　　作品制作の糧に
　　　　なれば、幸いです。

　今回は、ここまで。
![_c4cbcf91-46e7-43d0-ae63-a0ab1d26c776.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/3ead425e-3873-fdff-15ec-d6c300dd33de.jpeg)
CompileCエラー対応

こんなエラーメッセージが出て困ったら・・・

```
The following build commands failed:
CompileC
/Users/xxx/xxx/DerivedData/xxx/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/PromisesObjC.build/Objects-normal/arm64/FBLPromiseError.o
/Users/xxx/xxx/App/Pods/PromisesObjC/Sources/FBLPromises/FBLPromiseError.m normal
arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'PromisesObjC' from project 'Pods')
CompileC
/Users/xxx/xxx/DerivedData/xxx/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/PromisesObjC.build/Objects-normal/arm64/FBLPromise+Validate.o
/Users/xxx/xxx/App/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Validate.m
normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'PromisesObjC' from project
'Pods')

(2 failures)
```

これで解決するらしい
```
rm -rf ~/Library/Caches/CocoaPods        
rm -rf Pods
rm -rf ~/Library/Developer/Xcode/DerivedData/*
pod deintegrate
pod setup
```

今回はcapacitorプロジェクトのせいか、これでは解決しなかったが、
以下に`DerivedData`があったので、これを削除すると解決した。

```
rm -rf ios/DerivedData
```
2024年4月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。

# 2024年4月1日の検索結果 (リスティング広告)

![スクリーンショット 2024-04-01 113431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/d9c27984-c560-2a40-c8e9-c8ed08774b47.png)

* Splunk
* PureStorage
* Hitachi
* Dynatrace

Splunk がトップで PureStorage と Hitachi が続いています。

先月の結果はこちら --> [2024年3月 AIOps 定点観測](https://qiita.com/mkodera/items/8ff7e0c74c270227d92c)

# 2024年4月1日の検索結果 (広告以外)

![スクリーンショット 2024-04-01 113612.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/0310596c-1ee9-4f6f-c47b-4cdb44e8abe9.png)

* HPE
* Splunk
* AWS
* IBM

先月と全く同じでした。

先月の結果はこちら --> [2024年3月 AIOps 定点観測](https://qiita.com/mkodera/items/8ff7e0c74c270227d92c)
httpsのサイトにアクセスしているのにATSに引っかかる

# 現象
表題の通り
https ならなんでもいいと思っていたのですが、そうではないようです。

# 原因
Appleの定めるATS（接続先URLがHTTPSでかつセキュアでないサーバー証明書を使用しているなら接続不可とする機能）に引っかかっていたため、表示できなくなった。

ATSに許可されている要件は以下

■鍵
ECDHE_ECDSA
ECDHE_RSA
DHE_RSA
RSA

■暗号
AES_256_GCM
AES_128_GCM
AES_256_CBC
AES_128_CBC

■ハッシュ
SHA384
SHA256
SHA

# 対策
以下のように該当のドメインでは鍵交換アルゴリズムを厳密にチェックしない設定をinfo.plistに追加することでアクセス可能となった。
```xml:info.plist
<key>NSExceptionDomains</key>
        <dict>
            <key>www.◯◯◯.co.jp</key>
            <dict>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
        </dict>
</key>
```

### その他
以下のコマンドでどんな設定値にすればアクセスできるようになるか、調査してくれる
```
nscurl --ats-diagnostics --verbose https://www.◯◯◯.co.jp
```
【iOS】Crashlyticsに自作Frameworkのログも出したい

# やりたいこと
Firebase Crashlyticsを使えば、アプリのどこでクラッシュしたかは一目瞭然。
しかし、アプリの中のFrameworkの中でクラッシュした場合は、その限りではなくなる。

### 通常のCrashlytics
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/104bb6f2-0569-d3e4-713d-732a16408b1e.png)
ViewControllerの23行目で落ちてる事がわかる

### FrameworkでクラッシュしたCrashlytics
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/8eae0e1d-ca66-ec49-d57b-a55faccdbf07.png)
TestFrameworkのsample()でクラッシュしてることはなんとなく読み取れるが、よくわからない

# どうしたらいいか
Frameworkのスタックトレースを見る場合は、FrameworkのdSYMファイルもアップロードする必要がある。
【参考】
https://firebase.google.com/docs/ios/installation-methods?hl=ja

## 手順
### 1. FrameworkのBuildSettingsからDebug Information Formatを探し、任意のビルドタイプで「DWARF with dSYM File」に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/517e9550-4da2-728d-857f-66e1c8143162.png)

### 2. 設定変更後、FrameworkをビルドするとdSYMファイルも同時にできるので、できたFrameworkとdSYMをアプリ側プロジェクトの任意の場所に設置する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/cd2a0c09-24c7-3871-0ff2-6592232f88e3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/cdbe3faf-22c6-bc70-0f40-720101bd3c79.png)

### 3. Build Phasesに新しいRun Scriptを登録する
※ SPMの手順だが、CocoapodsやCarthageでもupload-symbolsのパスさえ分かれば同様にできる
```run.sh
"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols" 
-gsp "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleService-Info.plist" 
-p ios "${SRCROOT}/${PROJECT}/Test1Framework.framework.dSYM（フレームワークのdSYMファイルパス）"
```
### 4. Input Filesに以下の4件を追加
```
$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist
$(SRCROOT)/$(PROJECT)/Test1Framework.framework.dSYM（フレームワークのdSYMファイルパス）
$(SRCROOT)/$(PROJECT)/Test1Framework.framework.dSYM（フレームワークのdSYMファイルパス）/Contents/Info.plist
$(SRCROOT)/$(PROJECT)/Test1Framework.framework.dSYM（フレームワークのdSYMファイルパス）/Contents/Resources/DWARF/Test1Framework（フレームワーク名）
```

### 5. クラッシュさせてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/a743a480-8d1e-3df7-24ad-4812028dc0cd.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961919/7a9b1008-a8ac-23c5-ce0e-114c1168ee75.png)
クラッシュさせて確認するとFramework内のどこで発生したか追うことができる
【Swift】シンプルにログをファイルに書き出す

コピペでいけます

# ソース
```logger.swift
import Foundation
import UIKit


///
///
/// 日時用書式インスタンス
///
///
private class __formatInstance {

    private static var _formatter : DateFormatter?
    
    static var formatter : DateFormatter {
        get {
            if ( _formatter == nil  ){
                _formatter = DateFormatter()
                _formatter!.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS "
            }
            return _formatter!
        }
    }
}

func dateString() -> String {
    return __formatInstance.formatter.string(from:Date())
}

func printLog(_ log: Any) {

    let timestamp = __formatInstance.formatter.string(from:Date())
    print(timestamp, terminator: "")
    let tid = Thread.current

    let logStr = log as? String
    if let str = logStr {
        print("\(tid) : \(str)")
        Logger.getInstance().write(timeStamp: timestamp, text: "\(tid) : \(str)")
    }else{
        print("CAN'T LOG WRITE")
    }
}

class Logger {
    
    private let filename_ : String
    
    private static let instance_ = Logger()
    
    init(){
        
        let date = Date()

        let df = DateFormatter()
        
        df.dateFormat = "yyyyMMddHHmmss"
        self.filename_ = "Log_\(df.string(from: date)).log"
        
        print("log filename:\(self.filename_)")
    }
    
    
    static func getInstance() -> Logger{
        return Logger.instance_
    }

    func write(timeStamp tm: String,  text:String)
    {
        /// DocumentsフォルダURL取得
        guard let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
            fatalError("フォルダURL取得エラー")
        }
        /// 対象のファイルURL取得
        let fileURL = dirURL.appendingPathComponent( self.filename_ )
        if self.write(url: fileURL, text: "\(tm) \(text)") == false{
            printLog("LOG ERROR")
        }
    }
    
    func write(_ text:String)
    {
        let logTimeStamp = __formatInstance.formatter.string(from:Date())

        self.write(timeStamp:logTimeStamp,  text:text)
    }
    
    func write(url: URL, text: String) -> Bool {
        guard let stream = OutputStream(url: url, append: true) else {
            return false
        }
        stream.open()
        
        defer {
            stream.close()
        }
        
        let logText = "\(text)\n"
        
        guard let data = logText.data(using: .utf8) else { return false }
        let byteArray = [UInt8](data)
        let result = stream.write(byteArray , maxLength: byteArray.count)
        return (result > 0)
    }

}

```

# つかいかた
```swift
Logger.getInstance().write("test")
```

# ファイルを確認
1. Window > Devices and Simulators
2. デバッグ中のiPhone > デバッグ中のApp > [...] > Download Container...
3. できたContainerを右クリック > パッケージの内容を表示 > AppData > Documents
【iOS】UIフレームワーク比較

# はじめに
iOSでUIを実装する手段は主にXib、Storyboard、SwiftUI、UIKitがありますが、どれか一つだけを利用することは少ないです。
大抵の場合、上記の組み合わせでUIを実現します。UI実装にあたってその比較表を作成しました。

# それぞれの違い
|種類|説明|ファイル|
| ---- | ---- |---- |
|SwiftUI|・GUIを使用して、パーツおよび画面間の関係を作成できる<br>・2011年のXcode4.2より登場|storyboard(xml)|
|Xib|・GUIを使用して、パーツおよび画面間の関係を作成できる<br>・2011年のXcode4.2より登場|.storyboard(xml)|
|UIKit|・コードでView周辺を扱うフレームワーク<br>・StoryboardおよびSwiftUIと共存可能<br>・UIKitのみで構築するのは大変なため、StoryboardおよびXibで代替することが多い|コード|
|SwiftUI|・コード/GUIを使用して画面を作成できる<br>・2019年6月に発表された新しいフレームワーク。将来的にSwiftUIに一元化される可能性もある<br>・対応OSバージョンはiOS13以降|コード|

# 組み合わせ比較
|種類|メリット|デメリット|
| ---- | ---- |---- |
|Storyboard + UIKit|・ノウハウが蓄積されている<br>・GUIでUIおよび画面間の関係を作成できる|・UIの再利用性が低い<br>・コンフリクトが発生し易い<br>・将来的にSwiftUIへの移行作業が発生するかもしれない|
|Xib + UIKit|・ノウハウが蓄積されている<br>・GUIでUIを作成できる<br>・Xibを使用して、UIの再利用性を高くすることができる<br>・コンフリクトの発生を抑制できる|・将来的にSwiftUIへの移行作業が発生するかもしれない<br>・Storyboardと比べると画面間の関係がわかりにくい|
|Storyboard + Xib + UIKit|・ノウハウが蓄積されている<br>・GUIでUIおよび画面間の関係を作成できる<br>・Xibを使用して、UIの再利用性を高くすることができる<br>・Xibを使用して、コンフリクトの発生を抑制できる|・将来的にSwiftUIへの移行作業が発生するかもしれない|
|SwiftUIのみ|・SwiftUIへの移行作業が発生する可能性がない<br>・再利用性が高い<br>・コンフリクトの発生を抑制できる|・標準UIの中にSwiftUIのみでは対応できないものがある<br>・iOS13以上である必要がある<br>・新しい技術のためノウハウが蓄積されていない|
|SwiftUI + UIKit|・SwiftUIへの移行作業が発生する可能性がない<br>・UIの再利用性が高い<br>・コンフリクトの発生を抑制できる<br>・作成中の画面のPreviewをみることができるためデバッグが早い|・iOS13以上である必要がある<br>・新しい技術のためノウハウが蓄積されていない|

# 結論
これから新規で開発するならSwiftUI + UIKitを採用するのが良い
光モジュールの概要

まとめ：
光モジュールは、光信号を電気信号に変換するデバイスであり、現代の通信ネットワークやデータセンターで重要な役割を果たしています。 光モジュールには、伝送速度、実装形態、伝送距離などの分類方法に基づいて多くの種類があります。 データセンターにおいて、光モジュールは高密度・低消費電力の要求を満たしながら、高速なデータ伝送とバックアップを実現します。
文章：
光モジュールは現代の通信技術において重要な役割を果たしており、高速、効率的、長距離のデータ伝送を実現するための中核コンポーネントです。 データセンター、クラウドコンピューティング、5Gネットワ​​ークのいずれにおいても、光モジュールは不可欠な役割を果たします。
光モジュールは、光信号を電気信号に、または電気信号を光信号に変換する装置であり、送信側では電気信号を光信号に変換して送信し、受信側では光信号を受信して​​電気信号に変換します。 光モジュールは、光電子デバイス (レーザー ダイオード、フォトダイオードなど) と関連回路で構成されます。 光モジュールの利点には、高い伝送速度、長い伝送距離、優れた耐干渉性能、小型サイズが含まれます。 光モジュールには、送信側と受信側の 2 つの部分があります。
光モジュールを分類するにはさまざまな方法があり、速度に応じて、100G 光モジュール、ギガビット光モジュール、10G 光モジュール、40G 光モジュール、100G 光モジュール、400G 光モジュール、800G 光モジュールなどに分類できます。 パッケージ形態に応じて、光モジュールは SFP、SFP+、QSFP、QSFP28、QSFP-DD などのさまざまなパッケージ形態に分類できます。 光モジュールは、モードによってシングルモード光モジュールとマルチモード光モジュールに分類できます。 光モジュールは、伝送距離に応じて、短距離光モジュール、中距離光モジュール、長距離光モジュールに分類できます。 波長に応じて、光モジュールは850nm、1310nm、1550nmなどの異なる波長の光モジュールに分割できます。
一般に光モジュールの使用方法は、光ファイバのジャンパを接続するだけで比較的簡単ですが、特殊な場合には、機器やシナリオに応じた設定が必要となる場合があります。 一般的なトラブルシューティング方法には、光モジュールが正しく差し込まれているかどうか、接続が緩んでいないか、伝送媒体が正常かどうかなどを確認することが含まれます。障害が発生した場合は、光モジュールの再挿入または交換を試みることができます。
光モジュールは光通信の重要な機器であり、電気信号と光信号の間の変換を実現し、データセンター、運賃計算ステーション、5Gネットワ​​ークなどのシナリオで広く使用されています。 光モジュールには、高い伝送速度、長い伝送距離、優れた耐干渉性能、小型などの利点があり、さまざまなシナリオでの伝送ニーズを満たすことができます。 光モジュールを使用する場合は、光モジュールの正常な動作と通信品質を確保するために、特定の機器やシナリオに合わせて設置および設定し、一般的な障害への対処方法に注意する必要があります。
光モジュールの超詳しい入門書（必携）

光モジュールは現代の通信ネットワークの重要な部分であり、光信号と電気信号の間の変換を実現し、光ファイバーを介してデータをより高速かつ長距離に送信できるようにします。 この記事では、この分野を包括的に理解できるように、光モジュールについて詳しく説明します。
1. 光モジュールの概要
光モジュールは光トランシーバモジュールとも呼ばれ、光信号と電気信号の間の変換を完了できるデバイスです。 光モジュールは一般に、電気信号を光信号に変換して送信する送信機と、光信号を受信して​​電気信号に変換する受信機から構成されます。 光モジュールの主な機能は、光通信システムにおける光電変換を実現することです。
2. 光モジュールの分類
光モジュールには多くの分類方法がありますが、一般的な分類方法のいくつかを次に示します。
伝送速度に応じて、155M光モジュール、1.25G光モジュール、10G光モジュール、25G光モジュール、40G光モジュール、100G光モジュール、200G光モジュール、400G光モジュール、800G光モジュールに分けることができます。
パッケージ形態に応じて、SFP 光モジュール、SFP+ 光モジュール、SFF 光モジュール、QSFP+ 光モジュール、QSFP-DD、OSFP 光モジュールなどに分けることができます。
伝送距離に応じて、短距離光モジュール、中距離光モジュール、長距離光モジュールに分けることができます。
3. 光モジュールの応用シナリオ
データセンター: データセンターは、光モジュールの重要なアプリケーション シナリオの 1 つです。 クラウド コンピューティングとビッグ データ テクノロジの急速な発展に伴い、データセンターにおける高速かつ効率的な光モジュールの需要は増加し続けています。 高速光モジュールを使用することで、データセンターは効率的なデータ伝送とバックアップを実現できます。 同時に、データセンターは、高密度導入、省エネ、環境保護のニーズを満たすために、高密度、低電力の光モジュールも必要としています。
通信ネットワーク: 通信ネットワークは、光モジュールの主要なアプリケーション シナリオの 1 つです。 光ファイバーアクセス、モバイル通信からブロードバンドネットワークまで、光モジュールが必要です。 通信ネットワークでは、光モジュールは高速、長距離の光信号伝送と変換を実現し、通信ネットワークのパフォーマンスと信頼性を向上させます。 同時に、5G通信技術の発展に伴い、光モジュールの高速化、小型化、低消費電力化の需要も高まっています。
産業オートメーション: 産業オートメーションの分野では、センサーやアクチュエーターの高速通信と制御に光学モジュールが必要です。 光モジュールを使用すると、高速で信頼性の高いデータ伝送と信号処理が実現され、産業オートメーション システムの効率と精度が向上します。 同時に、産業オートメーション分野では、過酷な作業環境の要件を満たすために、高い信頼性と耐環境性を備えた光モジュールも必要です。
計測機器: 物理学、化学、生物学などの科学分野では、高速かつ正確な測定やテストが必要です。 光モジュールを使用することにより、高速かつ確実なデータ収集・送信が可能となり、様々な計測器や試験装置に広く使用されています。 同時に、計測分野では、携帯性や長期使用のニーズを満たすために、小型化された低電力の光モジュールも必要としています。
セキュリティ監視: ビデオ監視や空港セキュリティなどのセキュリティ監視の分野では、高速かつ高解像度のビデオ伝送と処理が必要です。 光モジュールを使用することで、高速かつ信頼性の高いビデオ収集と送信が実現でき、監視システムのリアルタイム性と精度が向上します。 同時に、セキュリティ監視分野では、夜間または低照度条件下での監視ニーズを満たす、低照度で広ダイナミックレンジの光モジュールも必要としています。
5. まとめ
要約すると、光モジュールは現代の通信システムの重要な部分であり、高速、効率的、長距離のデータ伝送と変換を可能にします。 データセンター、クラウドコンピューティング、通信ネットワークなどの分野でも、産業オートメーション、計測機器、セキュリティ監視などの分野でも、光モジュールはますます重要な役割を果たしています。 技術の継続的な進歩とアプリケーション需要の継続的な成長により、光モジュール業界はより広範な発展の可能性をもたらします。
光モジュール: コンポーネント、分類、および用途

まとめ：
光モジュールは現代の通信システムの中核コンポーネントであり、光信号の送信と変換を担当します。 通信技術の発展に伴い、光モジュールはデータ伝送の分野でますます使用されており、その性能と安定性は通信システム全体の伝送品質と信頼性に重​​要な役割を果たしています。 この記事では、光モジュールの構成要素、分類、用途について詳しく紹介します。
文章：
光モジュールは現代の通信システムの中核コンポーネントであり、光信号の送信と変換を担当します。 通信技術の発展に伴い、光モジュールはデータ伝送の分野でますます使用されており、その性能と安定性は通信システム全体の伝送品質と信頼性に重​​要な役割を果たしています。 この記事では、光モジュールの構成要素、分類、用途について詳しく紹介します。
1. 光モジュールの構成部品
光モジュールは主に次のコンポーネントで構成されます。
送信部: 電気信号を光信号に変換する役割を果たし、通常は発光ダイオードまたは半導体レーザーを光源として使用します。
受信部: 通常はフォトダイオード (PD) を使用して、光信号を電気信号に変換する役割を果たします。
機能回路：送信回路、受信回路、電源管理回路、温度補償回路などを含む。
光インターフェイス: 一般的な光インターフェイスには、LC、MPO、SC、FC などが含まれます。
2. 光モジュールの分類
さまざまな分類基準に従って、光モジュールは多くのタイプに分類できます。 一般的な分類方法をいくつか示します。
伝送速度に応じて、ギガビット光モジュール、10G 光モジュール、40G 光モジュール、100G 光モジュール、400G 光モジュール、800G 光モジュールなどに分けることができます。
伝送距離に応じて、短距離光モジュール、中距離光モジュール、長距離光モジュールなどに分けることができます。
パッケージ形態に応じて、SFP 光モジュール、SFP+ 光モジュール、QSFP 光モジュール、QSFP28、QSFP-DD 光モジュールなどに分けることができます。
モードに応じて、シングルモード光モジュールとマルチモード光モジュールに分けることができます。
3. 光モジュールの応用
データセンター: データセンターは光モジュールの重要な応用シナリオの 1 つであり、クラウド コンピューティングとビッグデータ技術の急速な発展に伴い、データセンターでは高速かつ効率的な光モジュールに対する需要が高まっています。 高速光モジュールを使用することで、データセンター内およびデータセンター間の高速データ伝送とバックアップを実現できます。
通信ネットワーク: 通信ネットワークは、光ファイバ アクセス、モバイル通信、ブロードバンド ネットワーク、その他の分野を含む、光モジュールの主要なアプリケーション シナリオの 1 つです。 これらの分野において、光モジュールは高速・長距離の光信号伝送と変換を実現し、通信ネットワークの性能と信頼性を向上させます。
産業オートメーション: 産業オートメーションは、光モジュールの重要なアプリケーション シナリオの 1 つです。産業用制御システムでは、さまざまなセンサーとアクチュエータ間の高速通信と制御が必要です。光モジュールは、高速で信頼性の高いデータ伝送と信号処理を実現できます。
計測: 計測は光モジュールの重要な応用シナリオの 1 つです. 物理学、化学、生物学などの分野では、高速かつ正確な測定とテストが必要です. 光モジュールを使用することで、高速かつ信頼性の高いデータを実現できますデータの収集と送信。
セキュリティ監視: セキュリティ監視は光モジュールの重要な応用シナリオの 1 つです. ビデオ監視や空港セキュリティなどの分野では, 高速かつ高解像度のビデオ伝送と処理が必要です. 光モジュールを使用することで高速化を実現できます.信頼性の高いビデオ収集と送信。
つまり、現代の通信システムの中核コンポーネントとして、光モジュールの性能と安定性は、通信システム全体の伝送品質と信頼性において重要な役割を果たしています。 通信技術の発展とアプリケーション要件の継続的な改善により、光モジュールはより多くの分野で応用および開発されるでしょう。
![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736721/11bd927e-0acd-ce21-384b-30e13dce6958.jpeg)
光モジュール使用時のトラブルと注意事項

まとめ：
光モジュールの使用における一般的な問題と注意事項: 互換性の問題、温度の問題、プラグインの動作の問題、および故障診断の問題。
文章：
光モジュールは現代の通信システムの重要な部分であり、その性能は通信システム全体の伝送品質と安定性に直接影響します。 光モジュールを使用する過程でいくつかの問題が発生する場合があり、これらの問題が時間内に解決されない場合、通信システム全体に重大な影響を与える可能性があります。 この記事では、光モジュールを使用する際に起こり得るトラブルとその注意点を紹介します。
1. 光モジュールの互換性の問題
光モジュールの互換性の問題は、使用中に最もよくある問題の 1 つです。 異なるブランドやモデルの光モジュール間で互換性の問題が発生し、正常に通信できなくなる可能性があります。 したがって、光モジュールを選択する際には、光モジュールとスイッチ、ルータなどの機器との互換性など、光モジュールと主装置との互換性にも注意する必要があります。 光モジュールが互換性があるかどうかわからない場合は、まずテストするか、サプライヤーを見つけて確認し、大規模な導入前に主要な機器との互換性を確認できます。
2. 光モジュールの温度問題
光モジュールの動作温度は、その性能と安定性に大きな影響を与えます。 光モジュールの動作温度が高すぎると、性能の低下や寿命の低下などの問題が発生する可能性があります。 したがって、光モジュールを使用する場合には、動作温度の管理に注意する必要があります。 光モジュールの動作温度は、ヒートシンク、ファン、その他の冷却装置を取り付けることで下げることができます。 同時に、光モジュールの使用環境温度にも注意し、高すぎたり低すぎたりしないようにする必要があり、環境が特に厳しい場合は、産業グレードの光モジュールを選択することもできます。
3. 光モジュールの抜き差し動作の問題
光モジュールの挿入および取り外しを不適切に行うと、破損したり、正常に動作しなくなる可能性があります。 したがって、光モジュールの取り付けおよび取り外しの際には、次の点に注意する必要があります。
不適切なポートの使用を避けるために、光モジュールがネットワーク デバイスのポートと一致していることを確認してください。
光モジュールやデバイス スロットの損傷を防ぐため、プラグを抜き差しするときに過度の力を加えないでください。
プラグの抜き差しのプロセス中は、性能に影響を与えないよう、光モジュールやソケットに塵、埃、その他の不純物が入らないように注意する必要があります。
光モジュールの正しい挿入および取り外し方法がわからない場合は、関連する操作マニュアルを参照するか、専門家の助けを求めることができます。
4. 光モジュールの故障診断の問題
光モジュールに障害が発生した場合、問題を迅速かつ正確に診断して解決することが重要です。 一般に、光モジュールに障害が発生した場合は、次の方法で診断できます。
光モジュールの外観とインターフェースに損傷がないか、明らかな物理的損傷がないかを確認します。
光パワーメータやスペクトラムアナライザなどを使用して、光モジュールの送受信光パワーが正常かどうかを確認してください。
ファイバージャンパーの接続がしっかりしているか、明らかな緩みや破損がないか確認してください。
通信機器が正しく設定されているか確認してください。
上記のどの方法でも問題が解決しない場合は、光モジュールの交換を試すか、テクニカル サポート担当者に連絡してさらなる診断と修理を依頼してください。
光モジュールを使用する場合は、上記に加えて以下の点にも注意してください。
表面の清掃やファイバ ジャンパの接続の確認など、光モジュールを定期的に検査および保守してください。
光モジュールの性能への影響を避けるため、強い電磁干渉のある環境での光モジュールの使用は避けてください。
光モジュールの壊れやすい部分（光ファイバインターフェースなど）が汚れたり、外力による衝撃を受けたりしないように注意して保護してください。
保管または輸送の際は、損傷や振動を避けるため、光モジュールのパッケージの保護と耐衝撃対策に注意する必要があります。
光モジュールの取り付けまたは設定を行う場合は、関連する技術文書またはマニュアルを参照して、光モジュールが正しく設定され、使用されていることを確認する必要があります。
光モジュールの問題や障害の対処方法がわからない場合は、専門家の助けや技術サポートを求めることができます。
![20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736721/e2522675-8a1a-d81e-031d-d1d55a51c5d3.jpeg)
光モジュールの高速伝送を実現する3つの技術

まとめ：
本稿では、光モジュールの伝送速度を向上させる3つの技術、「波長分割多重技術」「多チャンネル並列伝送技術」「高次変調技術」を紹介します。 波長分割多重技術は、光の波長特性を利用して、同一の光ファイバ上で異なる波長の信号を同時に伝送し、光ファイバの並列伝送を実現します。 マルチチャネル並列伝送技術は、複数のチャネルを使用してデータを同時に送信することで、伝送帯域幅と速度を向上させます。
文章：
データトラフィックが増加し続けるにつれて、光モジュールの伝送速度も増加し続けています。 現在、市場に流通している光モジュールの伝送速度は800Gbpsに達していますが、将来のデータセンターやクラウドコンピューティングなどのさらなるニーズに応えるためには、より高い伝送速度を実現する光モジュール技術の探索が必要です。 本稿では、伝送速度を向上させる3つの技術、「波長分割技術」「多チャンネル並列伝送技術」「高次変調技術」を紹介します。
1. 波長分割多重技術
波長分割多重技術 WDM は、光の波長特性を利用して、異なる波長の信号を同一の光ファイバ上で同時に伝送する技術です。 光モジュールでは、レーザーによって電気信号が光信号に変換され、各波長の光信号がカプラを介して結合され、光ファイバに入力されて伝送されます。 波長分割多重技術は光ファイバーの並列伝送を実現し、光ファイバー伝送容量を大幅に増大させます。 波長分割多重技術の効率性と信頼性により、波長分割多重技術は現代の通信システムにおける高速伝送にとって重要な技術となっています。 WDM 波長分割多重化に一般的に使用される波長範囲には、CWDM、DWDM、LAN-WDM などがあります。
2. 多チャンネル並列伝送技術
マルチチャネル並列伝送技術は、複数のチャネルを使用してデータを同時に送信することで、伝送帯域幅と速度を向上させます。 複数の送信チャネルを利用することにより、最初はシリアルに送信されたデータを、並列に送信される複数のサブストリームに分割できるため、送信帯域幅が増加します。 多チャンネル並列伝送技術は、伝送路の数を増やすことで伝送速度を向上させ、データ処理能力を高めることでデータスループットを向上させることができます。
3. 高次変調技術
高次変調は、より多くの情報を単一の光パルスにエンコードする技術です。 高次の変調技術を使用すると、単位時間あたりにより多くのデータを送信できます。 PAM4 と NRZ は、現在の光通信分野における非常に重要な技術基盤です。 高次変調技術により、光モジュールの伝送速度が向上し、光モジュールの消費電力が削減されます。 変調技術の効率を改善することにより、より高い伝送速度とより低いエネルギー消費を達成できます。
以上をまとめると、光モジュールの伝送速度を向上させるためには、波長分割多重技術、多チャンネル並列伝送技術、高次変調技術の3つが重要な技術となります。 技術の継続的な進歩により、光モジュールの伝送速度は、増大するデータ伝送の需要に応えるためにさらに向上すると考えられています。![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736721/343fe8c0-cfbd-eed4-15a8-ceee925b6518.jpeg)
wslで、最小のカーネルをコンパイル その43

# 概要
wslで、kernel.elfのコンパイル、やってみた。
さらに、上のkernel見つけたので、コンパイルしてみた。

# 参考にしたページ

https://github.com/TaiseiIto/hariboslinux

# 手順

```
cd git

git clone https://github.com/TaiseiIto/hariboslinux.git

cd hariboslinux

make


```

# qemu実行結果

うまく動かない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/24b098c9-95e0-0284-2090-193c1e1eb837.png)


以上。
[過去記事]Vue.js 番外編 Chromeの検証機能で楽に検証を行う方法

## 概要

今回は番外編ということでChromeの検証機能を使って作成したVueのコードを楽に検証する方法をまとめます！

## やること

Chromeの検証機能でVueで定義されている値を書き換える。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <div v-if="signal === 'str1'">一番目の文字列です</div>
            <div v-else-if="signal === 'str2'">二番目の文字列です</div>
            <div v-else-if="signal === 'str3'">三番目の文字列です</div>
            <div v-else>その他の文字列です</div>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                    // キー(key): 値(value)
                    signal: 'str1'
                }
            },
        })
    </script>
</body>
</html>
```

コレで準備は完了です！早速当該のhtmlファイルをChromeで開いて見ましょう！
下記のように「一番目の文字列です」と表示されていると思います。

[Document-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/929802d1-3102-8d9e-2ccb-e66000110d14.png)

## 検証機能を用いてVueで定義した値を書き換える

今回はVue側（script要素内）で定義しているキーに紐づく値（signalキーに紐づくstr1文字列）を検証画面側から変更してみたいと思います

まずはChromeのウインドウ上で右クリックをして「検証」をクリックします。

![スクリーンショット_2021-12-08_7_22_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d6bf8a03-b850-84d6-b84a-21783b76cf11.png)

下記のようなちょっとごちゃごちゃした画面が開きます。コレが検証用のメニュー画面です！

![Document-8-1024x344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/62c6f9e0-ac91-d615-b81a-a035240b3741.png)

「Console」をクリックします。

![Document-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/521815ce-ef51-0a99-22d8-c730add17d6e.png)

下記の赤矢印が指している部分に「app.$data.signal = 'str2'」と入力してEnterキーを押下してみましょう！

![Document-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e65e86fb-2229-8183-5ce0-7a3269212b6a.png)

Vueですでに定義されているsignalキーに紐づく値がstr1からstr2に書き換えられ「二番目の文字列です」が表示されている事がわかります！

![Document-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0325cdd4-1f2e-d540-4ca0-ae0c5ac20e8b.png)

## 簡単な解説

Chromeの検証画面のConsoleでは「elの値.データオブジェクト名.キー名」と指定することでVueで定義されてた値にアクセスや書き換えを行う事ができます。

コレなら記載したVueのコードの振る舞いを確認する時に毎回コードを修正しなくともChrome側のみで検証が可能になります！!
【eclipse】Spring bootでバージョンが違うというエラーが出た（java.lang.UnsupportedClassVersionError）

JavaのSpring bootでWebアプリを開発していたら下のようなエラーが発生。

:::note alert
エラー: メイン・クラスcom.example.demo.~のロード中にLinkageErrorが発生しました
	java.lang.UnsupportedClassVersionError: com/example/demo/~ has been compiled by a more recent version of the Java Runtime (class file version 66.0), this version of the Java Runtime only recognizes class file versions up to 65.0
:::

## 【原因】build.gradleで指定しているバージョンがJavaのバージョンと異なる
1. Javaのバージョンを確認
Eclipseのメニューから［設定］を選択→［Java］-［インストール済みのJRE］を選択
チェックの付いているJavaのバージョンを確認。

2. build.gradleで正しいJavaのバージョンを指定
java {
	sourceCompatibility = '<font color="red">**ここを変更**</font>'
}

# 参考
https://teratail.com/questions/kg8cqd3c6dvujk

https://ti-tomo-knowledge.hatenablog.com/entry/2018/06/19/132656

https://qiita.com/tutuz/items/af4ab620f47b8a56ed55
円グラフの弱点と代替チャートの提案

円グラフは、割合を表現するチャートとして使われます。
スタンダートなチャートとして棒グラフや線グラフなどと同様によく使われますが、
実は円グラフはよく使われるチャートの中では表現できることが少なく **とても不便** です。

![円グラフイメージ01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/cd200393-54c1-91a1-2032-edd22c683906.png)

本記事では円グラフの弱点と、
円グラフとほぼ同等のことが表現できる代替チャートの提案をします。


# 円グラフのデメリット

円グラフのデメリットとしては以下の点が挙げられます。

* 角度の微妙な違いを比較するのが困難
* 色を使わないと表現できない
* 要素の中の隣り合っているものしか比較できない
* 数が多いと比較が困難になる

### 角度の微妙な違いを比較するのが困難

![円グラフイメージ02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/8e1715ed-4c01-fdc0-275a-409bc429ca77.png)

上記の図ではあえて割合の表記を隠しています。
家具と家電のカテゴリではどちらの割合が大きく見えるでしょうか？
角度の違いだけを見て判断するのは難しいと思います。

![円グラフイメージ03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/abd531ee-68d6-09df-2094-212433e44820.png)

実際はこの図では家電の方が大きいとわかります。
このように、角度の厳密な比較は人間の目では難しいため、
微妙な値の差を示すような場面では適切でないと思われます。

### 色を使わないと表現できない

![円グラフイメージ04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/8e660539-f64a-d7c9-a218-d07fff364417.png)

色を使わずに表現した場合はどうでしょうか。
不可能ではないですが、色を使わない場合は各要素の詳細部分に書き込むなどする必要があり非常に見づらいです。
色を使わずに円グラフを使用するのは避けた方がよいでしょう。

### 要素の中の隣り合っているものしか比較できない

![円グラフイメージ05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/f2bff7ea-4ab4-e335-717e-350abf465c51.png)


上記の図において、隣り合っていないもの同士の比較は出来るでしょうか。（※例のため、あえて割合の大きい順ではないグラフにしています。）
例えば関東と関西の割合はどちらが大きいか、数値の表記なしでは一目で比較するのは難しいと思います。

### 数が多いと比較が困難になる

![円グラフイメージ06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/20b2fbb8-de85-07fe-1031-2b4ecacbb974.png)

比較対象の数が多いとその分色の凡例も増え非常に見づらくなります。
一般的に人間が一度に区別できる色の種類は7色程度とされています。7色を超える場合は色ではなく別の表現で区別する工夫が必要でしょう。

# 円グラフのメリット

円グラフのメリットとしては以下の点が挙げられます。

* 全体に対する割合が一目でわかる

上記の図「サブカテゴリ別売上」では、50%の部分までで「椅子」、「コピー機」、「本棚」、「アプライアンス」のサブカテゴリで構成されており、 **上位4つのサブカテゴリで全体の売上の約半数を占める** というのが一目で確認できるかと思います。
このように、円グラフは全体に対する割合を一目で確認するのに役立ちます。

# 代替チャートの提案

ここまでで円グラフの弱点は比較的多く、メリットがあまり多くないことがわかりました。
では、代わりにどのチャートを使うかについて考えたいと思います。

## ツリーマップ

比較対象が7つを超え数が多い場合は、ツリーマップを使うことが考えられます。

![ツリーマップイメージ01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/ba5c1b5b-dae1-2487-7bd0-a2fa69859791.png)

それぞれの要素が扇状ではなく矩形であるため、内部に詳細を書き込むスペースがあり、また面積比で割合を示すため全体に対する割合も表現することができます。

## 棒グラフ

そもそも割合を角度で表すのではなく、棒グラフで表現することも考えられます。

![棒グラフイメージ01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/aeb7c052-0fde-5060-5380-8cc96a9267f4.png)

上記の棒グラフであれば、家具より家電の売上が大きいことが数値の表記が無くてもわかるかと思います。
このように角度ではなく長さで差を示す棒グラフであれば、微妙な値の違いも確認することができます。

## 100%積み上げ棒グラフ

棒グラフ1本の全体を100%として、その内訳を色を使って区別することで割合を表現することも考えられます。

![棒グラフイメージ02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/77e66b04-b4b6-4a4f-a4ae-61c24b43a9f2.png)

1本あたりが円より小スペースで表現できるため、時間の要素も入れて売上の推移を表現することもできました。

## 100%積み上げ面グラフ

横軸が時系列や地域など順序的な意味を持つ値である場合、面グラフを使うことも効果的です。

![面グラフイメージ01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748585/7ba16db6-9e65-d3be-5064-4d9d7d27ad91.png)

割合の推移が一目で確認できるようになりました。
ただし、100%積み上げグラフは比較対象の色が多いと非常に見づらくなってしまうため注意が必要です。

# まとめ

円グラフは、割合を示すのに使われますが欠点が多く、適切な場面でないとかえって見づらくなってしまうことがわかりました。 **割合=円グラフ** と安易に決めてしまうのではなく、本当にその場面で円グラフを使うのが効果的なのか一度考えてから使うようにしたいです。

割合を示すチャートはいくつもあり、それぞれに長所・短所があるので適切な場面で使い分けをしましょう。
[過去記事]Vue.js v-on イベントを取得する

## 概要

今回はv-onディレクティブを使ったイベント情報の取得をやってみたいと思います。
前回↓

https://qiita.com/miriwo/items/697f4f0948fb99711ad5

## やること

v-onディレクティブが設定されたボタンをクリックした時のイベント情報をコンソールに表示する。

## 準備

下記の内容を任意のhtmlファイルに記載して保存します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">

        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {

                }
            },
        })
    </script>
</body>
</html>
```

## 方法

まずはscript要素内でcuttonClickメソッドを定義します。

```html
<script>
    let app = new Vue({
        el: '#app',
        data(){
            return {
            }
        },
        methods: {
            buttonClicked(e){
                console.log(e);
            }
        }
    })
</script>
```

div要素内を下記の様に記載してv-onディレクティブを省略記法で記載します。

```html
<div id="app">
    <button @click="buttonClicked">クリック</button>
</div>
```

ファイル全体は下記の様になっています。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <header></header>
    <main>
        <div id="app">
            <button @click="buttonClicked">クリック</button>
        </div>
    </main>
    <footer></footer>
    <script>
        let app = new Vue({
            el: '#app',
            data(){
                return {
                }
            },
            methods: {
                buttonClicked(e){
                    console.log(e);
                }
            }
        })
    </script>
</body>
</html>
```

コレで準備は完了です！当該のhtmlファイルをブラウザで開き、ブラウザの検証モードのconsoleを開き「クリック」ボタンをクリックしましょう。

コンソールにイベント情報が記載され確認することができます！

![Document-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/93334a0c-3ae2-b7e1-66f2-81931fc40d91.png)
なぜ、Strong Parameters がいいのか

# はじめに
Railsを学習していて、
なぜ、Strong Parametersが重要なのか、マスアサインメントではなぜダメなのかを
整理したくて記事にしてます。
## この記事を読むと分かること
* Strong Parametersがどういうものか分かる
* なぜ、マスアサインメントがダメなのかが分かる
## Strong Parametersとは？
Strong Parametersは、Action ControllerのパラメータをActive Modelに
「マスアサインメント」で渡すことを良しとしない。:x:

開発者側はアップデートしたいパラメータを、
Active Controllerで明示的に指定する必要がある。

要は、Active Controllerのアクションで本当に使用したいパラメータだけを
厳密に指定してモデルに渡してあげる事でより安全だよねというお話。

## マスアサインメントではなぜ、ダメか？
まず、**「マスアサインメント」** とは、
チェックされていないパラメータをまるごとモデルに保存する行為の事を言います。

以下のコードでは「マスアサインメント」でActive Modelにパラメータを渡しています。
```ruby
# UserModelが 'name'と'email'を定義していた場合
# 以下でActiveModelに渡しているコードは...
@user = User.new(params[:user])

# 以下のコードとほぼ同じ
@user = User.new(name: "フォームから入力されたName", email: "フォームから入力されたEmail")
```

ではなぜ、「マスアサインメント」ではダメなのか？
渡ってきたパラメータを自動的にモデルに渡せるのは開発者側としては楽です。:relaxed:

ですが、パラメータチェックされていない部分を攻撃者に悪用される場合があり、
意図していないフォームのパラメータを密かに追加されてアプリケーションの整合性が
損なわれる可能性があります。:imp:

## Strong Parameters の実装方法
requireメソッドとpermitメソッドで、
paramsから **取得してくるオブジェクト名** と **どのキーを取得するか** を指定してあげます。
事前にパラメータをチェックし、不正なパラメータを防いでくれます。
```ruby
def create
  @article = Article.new(article_params)

  @article.save
  redirect_to @article
end

# 外部から不正に呼び出されることが内容にprivate修飾子でカプセル化
# updateアクションでも再度利用できる
private
  def article_params
    params.require(:article).permit(:title, :text)
  end
```
# おわりに
Strong Parametersの概要やどういったものなのか
理解することが出来ました。
また、マスアサインメントではなぜダメなのかも理解することが重要だと思ったので
整理できてよかったです。

# 参考資料

https://railsguides.jp/action_controller_overview.html#strong-parameters
【Spring boot】メイン・クラスcom.example.demo.~を検出およびロードできませんでしたを解決する【eclipse】

eclipseを使ってSpring bootでWebアプリを開発していたらコードは間違えていないのに下のようなエラーが出てしまった。

:::note alert
エラー: メイン・クラスcom.example.demo.~を検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: com.example.demo.~
:::
:::note alert
型 java.lang.Class を解決できません。It is indirectly referenced from required type org.springframework.boot.autoconfigure.SpringBootApplication
:::


# 【原因】JREシステムライブラリがアンバインド済みもしくは追加されてない
1. プロジェクトを右クリック
1. プロパティを選択
1. Javaのビルド・パスを選択
1. ライブラリー選択
1. 変数の追加からJRE システムライブラリー追加、もしくはアンバインド済みのJREシステムライブラリの編集で使ってるJavaバージョンに合わせる

[こちらの記事](https://qiita.com/sekibouya/items/793982495501ae629d8c)も併せて参考にしてください。

# 参考
https://atmarkit.itmedia.co.jp/bbs/phpBB/viewtopic.php?topic=38517&forum=12
Google Spreadsheetを活用したGoogleカレンダー自動登録

GASとGSSを利用して、１か月分のスケジュールをGSSに用意しておいて、ボタン１つでGoogleカレンダーに自動登録するシートを作成しました。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/97ccfc28-4759-4e31-e71d-86b22807571b.png)


まず、下のリンクから配布用シートを開き、File→Make a copyでご自身のGoogle Driveにコピーしてください。
https://docs.google.com/spreadsheets/d/1p2LLT28D818IoDbqjnw7tkqY-crozys9vSnajOI4Bos/edit?usp=sharing

それでは、使用方法について解説していきます。

まず下図のように、D列に上から、「カレンダーID」、カレンダーを作成したい「年」「月」を入力してください。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/a5004d0f-94fc-0b15-a809-3021ac33d00b.png)

カレンダーIDは、Googleカレンダーの左側のメニューから設定を開くと、下図のように確認することが出来ます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/3cd1b519-463d-93d4-5a03-03a112592b94.png)

「カレンダー設定」をクリックすると、下図のように１か月分のカレンダーが縦に作成されます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/64fec1de-0178-15ec-fb59-61766d4ddc18.png)

内閣府のAPIを利用して、祝日も自動で取得します。

GSSへの読み込みに関しては、下図のように祝日シートで実行しています。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/357794d3-fa29-fa26-a5d7-a0a9d4750802.png)

次に下図のように、予定を入力していきます。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/6fd37b6c-02ce-c735-c16c-041ac0084393.png)

J列では、アイコンの色を指定できます。

Googleカレンダーに用意されているアイコンの色は11種類ありますので、I列ではプルダウンメニューが展開して、色を選択することが出来ます。

この時、開始時間と終了時間を空白にすると、終日の予定として設定されます。

また、何も入力しない日付があると、「何も入力されていない予定」が終日の予定として設定されてしまうので、カレンダー上で未入力としておきたい日付がある時は、その日付の行そのものを削除してください。

また、１日の中に複数のスケジュールを設定したい時は、下図のように行を挿入して同じ日付を入力し、予定を入力してください。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/1c3dc043-2b0c-a7ba-e9bb-622fab07f1a3.png)

入力が完了したら、カレンダー入力ボタンをクリックしてください。スクリプトが実行され、Googleカレンダーへの書き込みが行われます。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/1ae08f9a-a481-156b-727e-50e4a5f7e652.png)

無事、下図のようにGoogleカレンダーへの書き込みが行われました。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/12a1a331-7da3-2371-f53d-551c99bf1c28.png)


では次に、一度入力した内容を修正したい場合の方法について解説します。

一度実行した後のシートは、下図のようにA列に「済」と入力されています。このフラグがついている行に対しては、「カレンダー入力」をクリックしてもGoogleカレンダーへの書き込みは行われません。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/a238707c-a644-d5b4-2d74-8c719c90f186.png)

まず、フラグクリアをクリックしてください。すると下図のようにA列全てに対して、実行済フラグが消去されます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/f0b51e02-78fb-9020-da5c-62611a3ec484.png)

次に、修正したい行の内容を修正してください。

ここで、「カレンダー入力」を実行してしまうと、一度入力した内容に対して上書き修正されるのではなく、重複する形で二度書きされてしまいます。

そこで、「カレンダー入力」をクリックする前に、「全削除」をクリックしてください。

すると下図のように、一度入力した内容の全てが削除されます。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/29bb98fd-62c7-1b24-1db9-63e5afae9780.png)


その上で、「カレンダー入力」をクリックしてください。すると修正した内容を含む１か月分のスケジュールが再度書き込まれます。

入力が完了したら、「フォーム削除」をクリックしてください。すると、下図の様にカレンダーを含めたすべての入力データが削除されます。
(※Googleカレンダーに入力されたデータは消えません)
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/db7eba66-2f0a-b8af-d2d1-da4f05829983.png)
Promise.allの魔法：複数の非同期操作を一度に処理

# はじめに
Promise.allは、複数のPromiseオブジェクトを並行して処理するための非常に便利なJavaScriptの機能です。複数の非同期操作を完了する必要があり、これらの操作が相互に依存していない場合に、Promise.allは特に便利です。
# Promise.allを利用前
以下の関数を参考にしてください。この関数では、すべてのステップが前のステップが終了するのを待ってから実行されますが、実際にはご飯を炊くことと野菜を切ることは同時に行うことができます。そのため、かなりの時間が無駄になっています。
```typescript:example.ts
// チャーハンを作る関数
const makeDish = async (): Promise<void> => {
  await prepareIngredients(); //食材を用意する
  await cookRice(); //ご飯を炊く
  await chopVegetables(); //野菜を切る
  await addIngredients(); //食材を入れる
  await stirFry(); //炒める
};
```
# Promise.allを利用後
Promise.all を使用して、ご飯を炊く作業と野菜を切る作業を同時に行うことで、上述の問題を解決することができます。これにより、これらのタスクが互いに依存していないため、同時に実行することで全体の処理時間を短縮できます。以下のコードは、このアプローチを実装したものです。
```typescript:example.ts
// チャーハンを作る関数
const makeDish = async (): Promise<void> => {
  await prepareIngredients(); // 食材を用意する
  // ご飯を炊くと野菜を切る作業をPromise.allで同時に実行
  await Promise.all([cookRice(), chopVegetables()]);
  await addIngredients(); // 食材を加える
  await stirFry(); // 炒める
};
```
# まとめ
Promise.all を使用することで、複数の非同期操作を並行して実行し、全体の処理時間を効率的に短縮することができます。この方法は、特に互いに依存しないタスクを同時に実行する必要がある場合に有効です。
Step Functionsの遅延監視をLambdaを使わずにやってみた

AWS Step Functionsが時間以内に終わっているかを監視する方法としては、クラメソさんの以下の記事で紹介されていますが、

https://dev.classmethod.jp/articles/monitor-step-functions-activity/

Step FunctionsでAPIが呼び出せるようになったのでLambdaを使用せずにStep Functionsで実装してみました  

## Step Functionsから実行できるAPI一覧
実行可能なAWS SDK APIは以下で確認できます  

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/supported-services-awssdk.html

個人的には、WebUIのWorkflow Studio for AWS Step Functionsで探すほうが楽かなと思います  

![workflow-studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590294/5968ba03-2ecf-4225-bbc6-6273a1a67927.png)

## IAMロールの準備
まず、Step FunctionsのIAMロールに ListExections を実行できるように以下のポリシーを追加します
```
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"states:ListExecutions"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:*"
		}
  	]
}
```
## ステートマシンの作成
対象のステートマシン名はEventBridgeからInputで渡されることを想定してます  

### 最新のExecutionを取得
`sfn:listExecutions` で最新の1件だけ取得します
```
{
  "Comment": "ジョブの遅延監視",
  "StartAt": "GetLastExection",
  "States": {
    "GetLastExection": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:sfn:listExecutions",
      "Parameters": {
        "StateMachineArn.$": "States.Format('arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:{}', $.stateMachine)",
        "MaxResults": 1
      },
      "ResultPath": "$.result",
      "Next": "CheckStatus",
      "Retry": [
        {
          "ErrorEquals": ["States.ALL"],
          "IntervalSeconds": 10,
          "MaxAttempts": 5,
          "BackoffRate": 2
        }
      ]
    },
```
### Statusをチェック
Responseの構造は以下で確認します

https://docs.aws.amazon.com/ja_jp/step-functions/latest/apireference/API_ListExecutions.html

Executionsはlistで返されるのでStatusは `Executions[0].Status` となります  
これが `SUCCEEDED` ではない場合は完了していないってことなのでエラー通知に移ります

```
    "CheckStatus": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.result.Executions[0].Status",
          "StringEquals": "SUCCEEDED",
          "Next": "Succeed"
        }
      ],
      "Default": "NotSucceeded"
    },
```
### エラー通知
通知用にError、Causeのメッセージを生成します
```
    "NotSucceeded": {
      "Type": "Pass",
      "Parameters": {
        "errorString": "Not Succeeded",
        "causeString.$": "States.Format('{} is {}.', $.stateMachine, $.result.Executions[0].Status)"
      },
      "Next": "Failed"
    },
    "Failed": {
      "Type": "Fail",
      "ErrorPath": "$.errorString",
      "CausePath": "$.causeString"
    },
    "Succeed": {
      "Type": "Succeed"
    }
  }
}
```

## EventBridgeに登録
EventBridgeに監視対象となるStep Functionsが終了していてほしい時刻に実行されるように登録します  
また、このStep FunctionsのFAILEDをEventBridgeのRuleとして登録し、TargetにSNSを設定して通知されるようにします
```
{
  "detail": {
    "stateMachineArn": ["arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:sfn_delay_monitor"],
    "status": ["FAILED"]
  },
  "detail-type": ["Step Functions Execution Status Change"],
  "source": ["aws.states"]
}
```

Step FunctionsからSDK APIが実行されるようになって、今までLambdaを介していたものがStep Functionsだけ済むようになりました  
プログラムを書く必要もなくなってこれは楽ですね
MFA Login Flow



+ [【未解決】MFA Login Flow Help](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ahVhb)

:::note alert
Error Occurred: This error occurred when the flow tried to execute Apex class TOTPPlugin: Invalid shared key You can look up exceptions in the Apex Developer Guide.
:::


TOTPPlugin accesses the Salesforce TOTP methods, generates a time-based secret key with a QR code, and validates the TOTP. The Apex class for TOTPPlugin is available in the login flow sample package.

The legacy Apex action has these input parameters.

OTP_INPUT–The TOTP token that the user provides.
OTP_REGISTRATION_INPUT–The TOTP token that the user provides when first registering.
SECRET_INPUT–The secret key used to generate the TOTP.

https://help.salesforce.com/s/articleView?id=sf.security_login_flow_examples.htm&type=5
Winter 25 の「フロー実行へのユーザー アクセスを制限する」リリース アップデート

[Salesforceのアンケートに戻る](https://qiita.com/Keiji_otsubo/items/ce153ec9d338d7af0d81)

# フロー実行へのユーザー アクセスを制限するリリース アップデートによって調査は影響を受けますか?

+ [Survey impacted by the Restrict User Access to Run Flow release update?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Yvoqs)

Winter 25 の「フロー実行へのユーザー アクセスを制限する」リリース アップデートの自動有効化に関するアクションが必要な電子メールを受け取りました。具体的には、影響を受ける可能性がある調査の 1 つのフロー定義 ID が示されています。しかし、ゲスト プロフィールにアンケートのフローへのアクセスを提供する方法がわかりません。


アンケートがこのリリース更新の影響を受けるかどうかを確認または拒否できますか: https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow_release_update_restrict_user_access.htm 


:::note
after more than a month and more than one Support ticket, Support did verify (as much as they definitively verify anything) that Survey-related Flows aren't affected by this update. The person or persons who set up that "Action Required" email didn't filter out Survey-related Flow IDs, and so it went to many organizations who should not have received it. And, of course, Salesforce can't be bothered to send out retractions, corrections, or apologies when they goof like this.

1 か月以上経過し、複数のサポート チケットが発行された後、サポートは (決定的に何かを検証しているのと同じくらい) 調査関連のフローがこの更新の影響を受けないことを確認しました。 「要アクション」メールを設定した人は調査関連のフロー ID をフィルタリングしなかったため、メールは受信すべきではない多くの組織に送信されました。そしてもちろん、Salesforce は、このようなふざけた行為をした場合、わざわざ撤回、訂正、謝罪を送ることはできません。
:::
Salesforceのアンケート 未解決

[Salesforceのアンケートに戻る](https://qiita.com/Keiji_otsubo/items/ce153ec9d338d7af0d81)



# 参加者は質問「イベント日」に対する回答を送信しています。これは将来の日付 (TODAY() よりも後の日付) にすることができます。アンケートの完了日からわかるのは、その人がアンケートを送信した日だけであり、イベントがいつ開催されるかはわかりません。たとえば、誰かが来月のイベント日を含むアンケートを今日送信することができます (事前登録している人)。 

+ [アンケートの回答フィールドと計算式](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007agwKE)

# Experience Cloud で添付オプションのあるアンケートを表示できない

+ [Cannot view Survey that has attachment option in Experience Cloud](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007aiOzd)

:::note alert
**Either you don't have access to respond to this survey or the default survey invitation hasn't been generated.**

I cannot create a survey invitation, as when I try to do this I get this message:

**You can't create a public invitation for this survey because one of the versions contains a question that allows attachment. Remove the question that allows attachment and try again.**
:::


+ [The email template must contain this merge field when a question isn't specified: [[SURVEY_INVITATION_URL]]. Update the email template and try again.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eovhx)

:::note alert
Error element Send_Survey_Invite (FlowActionCall)

The email template must contain this merge field when a question isn't specified: [[SURVEY_INVITATION_URL]]. Update the email template and try again.
:::

+ [ユーザーがアンケートの招待を一時停止した場合、回答はどこに保存されますか? 一時的な回答を保持するオブジェクトまたはフィールドはありますか? または、不完全なアンケートの回答を照会する特定の方法はありますか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000NfG6)

:::note
興味深い問題です。データはどこかに保存して、アンケートを再開したときに取得できるようにする必要があります。その場所は明らかに文書化されていません。Salesforce Surveys では、文書化されていないアクションが多数実行されています。

私の最初の考えは、アンケート回答レコードのステータス フィールドが一時停止から完了に変わるまで、InvitationId フィールドは実際に割り当てられないということです。
:::

+ [メールアラートが送信されるケースに調査リンクを関連付ける](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Kgd7t)

:::note
以下のリソースがシナリオに役立つかもしれません: 

https://trailhead.salesforce.com/content/learn/projects/design-and-distribute-surveys-with-salesforce-フィードバック-management/add-merge-fields-within-your-surveys
 
https://help.salesforce.com/s/articleView?id=xcloud.concept_merge_fields.htm&type=5
 
https://help.salesforce.com/s/articleView?id=service.merge_fields_cases.htm&type=5
:::
ubuntuのローカルネットワークがすぐに切れる。。。

ローカルネットワークが切れる

なぜかわかりませんが、ゲートウェイの設定を無くしたら、ローカルネットワークが切れるトラブルは無くなった
(GUIのネットワーク設定アプリからGWは空欄でIPアドレスを設定した)

そもそも、外部との接続は不要だったので、ゲートウェイの設定は不要だったが、設定するとネットワークが切れるようになるのか。。。
Pheatmapクラスタリング

Rのpheatmapを用いた階層型クラスタリングのスクリプト
いつも忘れてしまうので備忘録として。

```R:
library(pheatmap)

ph <- pheatmap(mat, 
               cluster_cols = TRUE,
               cluster_rows = FALSE,
               show_colnames = FALSE,
               clustering_method = "ward.D")

#クラスタリング数を変える
clusters <- data.frame(x =matrix(nrow = ncol(data.frame(mat)), ncol = 1))
for(i in 2:7){
  tmp <- cutree(ph$tree_col, k = i)
  clusters <- cbind(clusters, tmp)
}
clusters$x <- NULL
colnames(clusters) <- paste0("ph_", 2:7)

#各グループ内をfactor型に変換する
for(i in 1:ncol(clusters)){
  clusters[,i] <- as.factor(clusters[,i])
}

#得られたクラスターをアノテーションとして可視化
ph <- pheatmap(mat, 
               cluster_cols = TRUE,
               cluster_rows = FALSE,
               show_colnames = FALSE,
               clustering_method = "ward.D",
               annotation_col = clusters
               )
```

覚えてしまいたいところ、、
【ROS2 colcon test】pythonパッケージのcolcon testで、consider_namespace_packagesエラーとなる場合の対処方法

# はじめに

　ROS2のPythonパッケージで、colcon testコマンドによるpytestを用いたPythonの単体テスト実行時に下記のエラーとなった。今までは成功していたが、pytest8.1.0での仕様変更の影響でエラーとなる。

```bash
ERROR test - TypeError: import_path() missing 1 required keyword-only argument: 'consider_namespace_packages'
```

　Humbleでは下記のように対策が取られるようだが(2024.4.1現在)、EOFであるFoxyは公式には対処されないので、エラーの回避方法を紹介する。

https://github.com/ros2/launch/pull/766

# 動作確認環境

* ROS2 Foxy

# エラー対処方法

pytestのバージョンを、8.1.0より前のバージョンに変更する。

```bash
pip install 'pytest<8.1.0'
```

参考までに、pytestのバージョンの違いによるcolcon test時のエラーの有無を示す。


|pytestバージョン|結果|
|:-:|:-:|
|8.1.1|NG|
|8.1.0|NG|
|8.0.2|OK|
|8.0.1|OK|
|8.0.0|OK|
|7.4.4|OK|

# 参考

https://github.com/ros2/launch/pull/766

https://zenn.dev/wtkn25/articles/python-pip-install-version
Go言語でブロックチェーンのシステムを作成する（その３）

## はじめに
前回は、Block、Blockchainの作成、hashの実装までやりましたが、今回はtransactionsの実装をしていきます。

- 前回までの記事

https://qiita.com/jun_11/items/a1adf93ba02292321b25

https://qiita.com/jun_11/items/259f0a777e12b3fa1b32

- バージョン
  - Go 1.22.0

## 実装
### イメージ図
下の図のPool、transactionsの実装をしていきます。

<img width="600" alt="ブロックチェーン2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676504/bb0ad399-3d61-1134-2910-054fc889f08d.png">

### transactionsの実装
まず、transactionsの実装をしていきます。

```golang
type Transaction struct {
	senderBlockchainAddress    string
	recipientBlockchainAddress string
	value                      float32
}

func NewTransaction(sender string, recipient string, value float32) *Transaction {
	return &Transaction{sender, recipient, value}
}

func (t *Transaction) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		SenderBlockchainAddress    string  `json:"sender_blockchain_address"`
		RecipientBlockchainAddress string  `json:"recipient_blockchain_address"`
		Value                      float32 `json:"value"`
	}{
		SenderBlockchainAddress:    t.senderBlockchainAddress,
		RecipientBlockchainAddress: t.recipientBlockchainAddress,
		Value:                      t.value,
	})
}
```

Transactionは、senderBlockchainAddress、recipientBlockchainAddress、valueでstructを定義します。
NewTransactionでは、sender、recipient、valueの値を受け取り、Transactionを作成しています。
MarshalJSONは、前回もありましたが、json.Marshalをするために実装しています。

また、Transactionを定義したので、前回作成したコードでTransactionを使用している部分の修正をしていきます。

```golang
type Block struct {
    // stringから*Transactionに変更
	// transactions []string
	transactions []*Transaction
}

// 引数にtransactionsを追加
// func NewBlock(nonce int, previousHash [32]byte) *Block {
func NewBlock(nonce int, previousHash [32]byte, transactions []*Transaction) *Block {
	b := new(Block)
	b.timestamp = time.Now().UnixNano()
	b.nonce = nonce
	b.previousHash = previousHash
	b.transactions = transactions // 追加
	return b
}

func (b *Block) MarshalJSON() ([]byte, error) {
    // stringから*Transactionに変更
    // Transactions []string `json:"transactions"`
    Transactions []*Transaction `json:"transactions"`

type Blockchain struct {
    // stringから*Transactionに変更
    // transactionPool []string
	transactionPool []*Transaction
	chain           []*Block
}

func (bc *Blockchain) CreateBlock(nonce int, previousHash [32]byte) *Block {
    // bc.transactionPoolを引数に追加
    // b := NewBlock(nonce, previousHash)
	b := NewBlock(nonce, previousHash, bc.transactionPool)
	bc.chain = append(bc.chain, b)
	bc.transactionPool = []*Transaction{} // 追加
	return b
}
```

次に、TransactionをBlockchainのstructに追加するコードを実装します。

```golang
func (bc *Blockchain) AddTransaction(sender string, recipient string, value float32) {
	t := NewTransaction(sender, recipient, value)
	bc.transactionPool = append(bc.transactionPool, t)
}
```

AddTransactionでは、sender、recipient、valueの値を受け取り、Transactionを作成して、BlockchainのtransactionPoolに追加しています。

## おわりに
今回は、transactionsの実装をしていきました。
次回は、nonceの実装をしていきます。

次の記事

https://qiita.com/jun_11/items/88f9a40648444b597529

# 参考

https://www.udemy.com/course/go-blockchain/?couponCode=ACCAGE0923