OmniAICreator/Qiita-1.07M huggingface dataset:
【Salesforce】速習 - コードビルダー

Winter'24 から「コードビルダー」が正式リリースとなりました。
ただ日本語での情報が少なく感じます。
将来有望な本製品を多くの人に知ってもらいたいたく、簡単に魅力を紹介します。

## 1.コードビルダーとは
コードビルダーとは、ブラウザで使える VS Code と同機能のコードエディターです。
VS Code と同じ操作感で作業ができます。
Enterprise Edition 以上を契約しているお客様なら問題なく使えます。
※PEはAPIアドオンが必要
Developer Edition では、残念ながら使用できません。

![レコーディング-2024-08-21-213157.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/8dbe8b45-e876-0e76-47ce-5abc0a7bd802.gif)


## 2.メリット
### 1.環境設定が楽々
コードエディターはもちろんのこと、Salesforce拡張機能、CLI、Gitなど、Salesforce開発に必要なものがすべて揃っていて、初学者に優しいです。
JDK を意識しなくていいのは、助かります。
「Einstein for Developers」というコーディング支援機能もすぐに使えます。
※追って説明します
### 2.ローカル環境を汚さない
ローカルマシンにインストール不要で、全てクラウド上でコーディング作業が完結します。
### 3.最新の環境
Salesforce拡張機能が常に最新の状態に保たれています。
バージョンの更新作業が不要となります。

## 3.初期設定
### 1.有効化 と インストール
1.[設定] から、[コード ビルダー]を選択する。
2.[有効化]にチェックする。
3.パッケージを[すべてのユーザー向けにインストール]で[インストール]する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/3ad14ed7-ee51-6891-c3e7-038129b161f3.png)
### 2.起動
1.[アプリケーションランチャー] から、[Code Builder]を選択する。
2.[Launch]をクリックする。
これで開発環境が用意されて、コーディング作業を始めることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/2388606f-646e-eef2-ac3b-dc28d5311830.png)


## 4.クイックスタート
[Quick Start with Code Builder](https://developer.salesforce.com/docs/platform/code-builder/guide/codebuilder-quickstart-intro.html)
[Quick Start with Apex Development](https://developer.salesforce.com/docs/platform/code-builder/guide/codebuilder-apex-get-started.html)
[LWC Development Quick Start](https://developer.salesforce.com/docs/platform/code-builder/guide/codebuilder-lwc-get-started.html)

## 5.Einstein for Developers
「Einstein for Developers」は、Salesforce の AIモデルを使用したコーディング支援ツールです。
2024年8月現在、次の3つの機能が使用できます。
・自然言語プロンプトから Apex コードを生成
・Apex および LWC のオートコンプリート
・Apex のテストケース生成
右クリックでテストケースが作成できて感動しました。
ApexだけでなくLWCコードも生成できたら嬉しいですね。
コード生成のプロンプトは、日本語でも記述できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/130f4570-3a8c-f49d-ee0b-9ed8a178fe7a.png)



なお「Einstein for Developers」は、安心して使うことができます。※超大事
>[訳文引用]
>私のコードは Salesforce の外部で共有されることがありますか?
>
> いいえ。Salesforce は、お客様のコードをメインサービス契約 (MSA) に基づく機密情報として扱い、他の Salesforce 顧客や Salesforce 外部の誰にも開示しません。
> また、Salesforce は、製品の改善やグローバル LLM のトレーニングにお客様のコードを使用することはありません。
[Frequently Asked Questions](https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/einstein-faq.html)

デフォルトでは、Einstein for Developers機能がオフとなっています。
[Manage]  → [Setting] から、「Einstein」と入力して
「Activate the Einstein for Developers(Beta) extension」を有効にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/576a574a-a6c2-3a77-8057-5a9b15ea3b21.png)

## 6.まとめ
高機能で初学者にも優しい「コードビルダー」。
これからの進化に期待します。
本記事から、少しでも「コードビルダー」に興味を持っていただけると幸いです。


## 7.参照記事
[Code Builder](https://developer.salesforce.com/docs/platform/code-builder/guide/codebuilder-overview.html)
[Einstein for Developers (Beta)](https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/einstein-overview.html)
[コードビルダーを使用してどこからでも開発 (正式リリース)](https://help.salesforce.com/s/articleView?id=release-notes.rn_code_builder_ga.htm&release=246&type=5)
Rails7のTurboが原因でリダイレクト後にjsが動かなくなる

## 概要
Turboが有効なRails7にて、削除処理を行った後リダイレクトするとjsが聞かなくなってしまった。


## 元のコード

```erb:erb
<%= link_to '削除する', users_memo_path(@memo.id), data: { turbo_method: :delete }, class: 'delete-button button' %>
```

```ruby:controller
def destroy
    memo = Memo.find(params[:id])
    memo.destroy if memo.user_id == current_user.id
    redirect_to users_memos_path, status: :see_other
end
```

```js:js
document.addEventListener('DOMContentLoaded', function() {
    // 既存の処理
});
```

## 成功した方法
Turboが読み込まれた際にjsを実行するように変更

```js
document.addEventListener('turbo:load', function() {
    // 既存の処理
});
```

## （おまけ）やってみたこと
### 1. Turboを無効にしてみる

```erb
<%= link_to '削除する', users_memo_path(@memo.id), data: { turbo: false, turbo_method: :delete }, class: 'delete-button button' %>
```

結果: Turboは無効になったが`turbo_method: :delete`も無効になってしまった。

### 2. button_toを使ってみる

```erb:erb
<%= button_to '削除する', users_memo_path(@memo.id), method: :delete, data: { turbo: false }, class: 'delete-button button', form: { class: 'delete-form' } %>
```

```js:js
document.querySelector('.delete-form').setAttribute('action', '/users/memos/' + data.id);
```
結果: 行クリックで詳細なメモデータを取得し、削除のURLを変更していたことが原因で`Can't verify CSRF token authenticity.`のエラー。

参考: https://halkyo.com/post/web/rails7-turbo-redirect-to-javascript-not-working
Spring Bootのフォルダ構成を整理整頓で開発効率アップ！

## はじめに

Spring Bootでの開発は楽しいものですが、プロジェクトが大きくなると、まるで引き出しを開けると物が飛び出してくるような状態になりがちです。
「この場合どこのフォルダに配置したほうがいいのかな？」「どこに何があるのか分からない！」なんてことにならないためにも、フォルダ構成はしっかりしておきたいところ。

今回は、Spring Bootプロジェクトのフォルダ構成について、整理整頓の大切さと共に、Spring Bootプロジェクトでよく使用されるフォルダ構成について、その目的や役割を解説します。

## 問題

プロジェクトが大きくなればなるほど、コードがゴチャゴチャに。
まるで片付けられない部屋のように、どこに何があるのか分からなくなります。
さらに、「あれ？このクラス、こんなところにいたの？」と予期せぬ出会いを果たすこともしばしば。
こんな状態では、開発効率がガタ落ちしてしまいます。

**主な問題点**:

- コードの可読性が低下し、新人開発者がプロジェクトに参加するときに「ここがカオスですか？」と戸惑う。
- バグ修正や機能追加時に、関係ないクラスまで巻き込む事態に発展する。
- 「あれ？これどこで使われてたっけ？」と、デバッグがまるで宝探しのように。

## 解決方法

整理整頓の基本は、物の居場所を決めること。

Spring Bootでも同じです。クラスごとに適切なフォルダに「お家」を作ってあげることで、開発はもっとスムーズに進むようになります。
さあ、みんなでお片付けしましょう！！

### Spring Bootでのおすすめフォルダ構成

| フォルダ名 | 役割 |
| --- | --- |
| **config** | アプリケーションの設定を行うクラスが「ここが私の居場所だ！」と落ち着く場所。Springの設定や外部設定のロードを担当。 |
| **controller** | ユーザーからのリクエストをキャッチし、サービスへ華麗にパスを出すマルチプレイヤー。REST APIのエンドポイントだけでなく、Webページへのリクエストマッピングも巧みに処理するディフェンダー。 |
| **service** | ビジネスロジックの司令塔。コントローラーからのパスを受け取り、データを処理して次のレイヤーへバトンタッチ。 |
| **repository** | データアクセス層のスペシャリスト。データベースとコネクションを持ち、必要な情報を提供する頼れる存在。 |
| **entity** | データベースのテーブルと双子のような存在。データベースに保存されたデータの姿を映し出す。 |
| **dto** | サービス層とコントローラー層をつなぐ伝令役。データを効率的に運び、シンプルに管理。 |
| **model** | ビジネスロジックにとっての心臓部。ドメインモデルやビジネスロジックに関連するクラスをここに集結。 |
| **util** | 必要とあらば、どこへでも駆けつける便利屋。ユーティリティクラスやヘルパーメソッドを提供。 |
| **exception** | アプリケーション特有のエラーを捉えて、スマートに処理。バグが発生しても、ここでキャッチして安心。 |
| **security** | 認証・認可の門番。セキュリティ設定クラスやフィルタで、外部からの侵入をブロック。 |
| **scheduler** | 定期的に「お仕事の時間ですよ」と教えてくれるアラーム。スケジューリング関連のクラスを配置。 |
| **runner** | アプリケーション起動時に「さあ、始めよう」と先陣を切るクラス。実行するタスクをここに配置。 |
| **mapper** | エンティティとDTOの橋渡し役。データのマッピングをスムーズに行い、互いの連携をサポート。 |
| listener | イベントが起きるたびに「今だ！」と反応する耳の良いリスナーたち。アプリケーションのイベントをキャッチして、素早く対応します。ApplicationListenerを実装したクラスが集う場所です。 |
| validator | 厳しいチェックマンが集まる場所。入力データのバリデーションを担当し、問題があれば「ダメ出し！」。カスタムバリデータや検証ロジックを実行するクラスが含まれます。 |
| view | 見た目にこだわるデザイナーたちが住むフォルダ。`Thymeleaf`や`JSP`で、エレガントなHTMLを生成し、ユーザーに美しいビューを提供します。 |
| converter | 「なんでも変えます！」がモットーの変身マスターが集まる場所。エンティティをDTOに、または別の形式へと自在に変換します。変わり身の得意なクラスたちがここに集合。 |

## まとめ

整理整頓されたプロジェクトは、開発者にとって最高の作業環境です。
フォルダ構成をしっかり整えることで、コードの可読性と保守性が劇的に向上し、プロジェクトの成長を支える強力な土台となります。
Spring Bootでの開発をもっと楽しく、スムーズに進めるために、ぜひフォルダ構成を見直してみましょう。お片付けが終わったら、あとは開発を楽しむだけです！

読者の皆さんも、この記事を参考にして、ぜひご自身のプロジェクトでフォルダ構成を整理整頓してみてください。
また、「こんな役割のフォルダがあるぞ！」などのご質問やフィードバックがありましたら、ぜひコメントでお知らせください。
YAGNI

### YAGNIとは
https://ja.wikipedia.org/wiki/YAGNI

あるWebアプリのプロトタイプを採用した開発で、一覧画面に複数選択による一括削除やインライン編集機能を実装する場面がありました。これらの機能はどうせ後から要望されるだろうと考え、現段階の要件には含まれていなかったものの、時間があったこともあり、先に隠し機能として実装しておくことにしました。

後日、社内で「まだそんな要望も出ていないのに、なぜ先に実装しているのか、必要はないと思う」という指摘を受けました。私はあんまり納得がいかずそこで、自分の行動が適切だったのか、こんなことよくあるだろうなと調べてみると、ソフトウェア開発には「YAGNI」という原則があることをそこで知りました。


YAGNIとは、「You Aren't Gonna Need It（それは必要にならないだろう）」の略語で、将来的に必要になるかもしれないという理由だけで機能を実装するのを避けるべきという、アジャイル開発で重要な設計原則のひとつです。この原則は「無駄な作業や複雑さを排除し、変化に強いコードを維持する」ために有効とされています。

### 実際に機能は必要になった

ただ、実際には、私が先に実装していたこれらの機能は、後に本当に要望が出されました。結果として、「無駄だった」とは一概には言えず、むしろ対応が早く済んだことで、プロジェクトの進行がスムーズになった部分もありました。そのため、YAGNIの原則を学びつつも、今回のケースでは必ずしも無駄なリソースだったとは感じていません。（反省していない）


ただ、この経験から定義するなら、現実化する可能性が非常に高い近未来のことは考慮し先に進めるべきだと感じました。ファイル管理機能にせっかくなんでOCR付けときました！はYAGNIなことくらいはわかりますが
YAGNIという考え方があることを頭に入れておきたいと思います。

### 自分なりのYAGNIへの付き合い方

YAGNIを絶対的なルールとしてではなく、コストに見合うかどうかを判断するための線引きとして活用するのが現実的だと考えるようになりました。

・仕様が不確実な機能 → 実装しない（YAGNI）
・90%の確率で実装必須になると分かっているもの → チームの合意（これが大事）の上で先に組み込む余地あり
もはや役に立たないだろうが、貫通させない衝突判定


## 前書き

ゲームエンジンによってはうまい具合に衝突判定する仕組みがあると思われるので、この記事はほとんどの方にとってはクソほども役立たないと思われます。

あと、未検証なんでご了承ください

## 問題

1フレームでこんだけ進むオブジェクトAがあるとする。

<img width=600 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/e647aa03-a99d-7c9a-c1ea-f0c367784b07.png>

こいつの途中でオブジェクトBがあったときにどうすれば途中で衝突したことに気づけれるだろうか？

<img width=600 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/f4bed6a1-114c-585d-bcfd-ddd1a201143c.png>

## 方法

そうだね二分探索だね。

<img width=600 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/da079771-65e2-3627-55b1-fcc22a5095ee.png>

まず二分探索を行う前に、次の場合はそもそも衝突しえない。

（**ざっくりした衝突処理**）
1フレーム前のオブジェクトAのことをA-として
* オブジェクトA,A-の右端がオブジェクトBの左端より左にあれば衝突していない
* オブジェクトA,A-の左端がオブジェクトBの右端より右にあれば衝突していない
* オブジェクトA,A-の上端がオブジェクトBの下端より下にあれば衝突していない
* オブジェクトA,A-の下端がオブジェクトBの上端より上にあれば衝突していない

それ以外の場合は、衝突している可能性があるため二分探索を行う。

二分探索の中央のオブジェクトをオブジェクトA´として、
オブジェクトA´とオブジェクトBが衝突すれば衝突している（探索終了）
それ以外はオブジェクトBとの距離が近い方に二分探索を繰り返す。（※）
このとき再度、上に書いた**ざっくりした衝突処理**を行う。（細かい文言は適当に読み替えて。いちいち言葉を定義して書き直すのだるい。）

終わり。

※：距離が同じだったときには衝突しえない。というのは成立するのだろうか？
しないなら、衝突しそうな方を選択して。

## おまけ：実装例

https://github.com/mogamoga1024/WireActionGame/blob/3f8fc9aa8552bd683b93daae65d4e2bef5f108df/player/hook.js#L167-L210
SwiftUIでリストの並び替えをする方法

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601978/d3a3ca07-b80a-6983-68ac-2ab57592b138.png" width="45%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601978/3d026020-bcd7-f9fd-41da-56e4c369933d.png" width="45%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601978/ec75d225-5b03-ccb4-9bed-df36cf0a7a21.png" width="45%">

## つまづいたこと
- リストの並び替えができなかった
- プレビューではonMove自体が動作しなかった
- シミュレーターではonMove自体は動作したが、並び替えができなかった

## 環境
- Xcode 15.4
- iOS17.5
- SwiftUI
- CoreData

## 条件
- @Queryを使用

## 解決方法
- プレビューではonMoveが動作しないので、シミュレーターで確認した
- @Queryの後に(sort: [SortDescriptor(\Memo.order)])をつけると並び替えができるようになった

## 知見
- プレビューは完全ではないのでちゃんと検証したいときはシミュレーターで確認する
- moveMemo()でorderプロパティを更新していたが、DBから@Queryで取得されたデータはそのままの順番で使用されるのでorderの順番がUIに反映されていなかった
- (sort: [SortDescriptor(\Memo.order)])を追加することで、orderプロパティの順番でソートされた状態で取得される

## ソース

```swift

import SwiftUI
import SwiftData
import Algorithms
import Foundation

@Model
final class Memo {
    var id: String
    var order: Int
    var content: String

    init(content: String, order: Int = 0) {
        self.id = ""
        self.content = content
        self.order = order // 初期値として0を設定

    }
}

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query(sort: [SortDescriptor(\Memo.order)]) private var memos: [Memo]
    
    var body: some View {
        NavigationStack {
            List{
                ForEach(memos, id: \.self){ memo in
                    NavigationLink(memo.content, destination: MemoDetailView(memo: .constant(memo))
                    )
                }
                .onMove(perform: moveMemo)
            }
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing){
                    NavigationLink(destination:
                        MemoDetailView(memo:.constant(Memo(content: "")
                        )
                    )
                
                    ){
                        Image(systemName: "plus")
                    }

                }
                ToolbarItem(placement: .navigationBarTrailing) { // EditButtonをナビゲーションバーの左側に配置
                    EditButton()
                }
            }
        }
    }    

    private func moveMemo(from source: IndexSet, to destination: Int) {
        var orderedMemos = memos.sorted(by: { $0.order < $1.order }) // orderで並び替え
        // 並び替えを実行
        orderedMemos.move(fromOffsets: source, toOffset: destination)
        // 更新された順序をmodelContextに反映
        for (index, memo) in orderedMemos.enumerated() {
            if let existingMemo = memos.first(where: { $0.id == memo.id }) {
                existingMemo.order = index
            }
        }
        saveContext()
    }
    // コンテキストの保存を行う関数
    private func saveContext() {
        do {
            try modelContext.save()
        } catch {
            print("コンテキストの保存に失敗しました: \(error.localizedDescription)")
        }
    }
}


```
[Excel VBA] 列番号を列文字に変換する／列文字を列番号に変換する

下記の記事の機能分離版です

https://qiita.com/ivkaresta/items/5a8e4faa284efd390517

### ざっくり説明
列番号を渡すと列文字にしてくれる関数 (以下、***列番号→列文字 変換***)と、
列文字を渡すと列番号にしてくれる関数 (以下、***列文字→列番号 変換***)です。

ex.
ConvertColNumberToColLetter (3776)　→　"EOF"
ConvertColLetterToColNumber ("AB")　→　28

### コード
```vb:列番号→列文字 変換
Function ConvertColNumberToColLetter(ByVal colNumber As Long) As String
'================================
'用途　　：列番号を列文字に変換
'--------------------------------
'第一引数：列番号 (Long型)
'戻り値　：列文字 (String型)
'================================
    Const MAXIMUM_COL_NUMBER As Long = 16384

    If colNumber <= 0 Or colNumber > MAXIMUM_COL_NUMBER Then GoTo ErrorLabel

    Dim colLetter As String
    Do While colNumber > 0
        colNumber = colNumber - 1
        colLetter = Chr((colNumber Mod 26) + 65) & colLetter
        colNumber = Int(colNumber / 26)
    Loop

    ConvertColNumberToColLetter = colLetter
    Exit Function
ErrorLabel:

    ConvertColNumberToColLetter = "ERROR"
End Function
```

```vb:列文字→列番号 変換
Function ConvertColLetterToColNumber(ByVal colLetter As String) As Long
'================================
'用途　　：列文字を列番号に変換
'--------------------------------
'第一引数：列文字 (String型)
'戻り値　：列番号 (Long型)
'================================
    Const MAXIMUM_COL_LETTER As String = "XFD"

    colLetter = UCase(colLetter)
    If colLetter = vbNullString Then GoTo ErrorLabel
    If Len(colLetter) > Len(MAXIMUM_COL_LETTER) Then GoTo ErrorLabel
    If Len(colLetter) = Len(MAXIMUM_COL_LETTER) And _
        colLetter > MAXIMUM_COL_LETTER Then GoTo ErrorLabel

    Dim colNumber As Long
    Dim i As Long
    For i = 1 To Len(colLetter)
        Dim targetCharacter As String
        Dim asciiCode As Long
        targetCharacter = Left(Right(colLetter, i), 1)
        asciiCode = Asc(targetCharacter)
        If asciiCode < 65 Or asciiCode > 90 Then GoTo ErrorLabel
        colNumber = colNumber + (asciiCode - 64) * 26 ^ (i - 1)
    Next

    ConvertColLetterToColNumber = colNumber
    Exit Function
ErrorLabel:
    
    ConvertColLetterToColNumber = "ERROR"
End Function
```
### 使用方法
***列番号→列文字 変換***
第一引数に列番号を渡す

***列文字→列番号 変換***
第一引数に列文字を渡す

### 仕様等
***共通***
エラーで弾かれたものはErrorLabelに飛ばされるので適宜処理を記入して下さい
(とりあえず文字列"ERROR"を返します)

***列文字→列番号 変換***
引数で文字を入力するときは小文字でも大丈夫です

### 注意点
以下はエラーになります。(以下、第一引数を引数と言う)

***列番号→列文字 変換***
- 引数で空白("")を渡す
- 引数(数字)が小数
- 引数(数字)が0以下
- 引数(数字)が最大列の数字(現状16384)より大きい

***列文字→列番号 変換***
- 引数で空白("")を渡す
- 引数(文字)がアルファベットではない
- 引数(文字)が最大列の文字列(現状"XFD")より大きい

あと、引数で#REF!とか#DIV/0!とか渡すのはダメ

### その他
将来的にExcelの仕様変更で最大列数が増えた場合も
`Const MAXIMUM_COL_LETTER`と`Const MAXIMUM_COL_NUMBER`の変更で対応可能なはずです。
#Desynced #プログラミング のブループリント

**本内容を利用した場合の一切の責任を私は負いません。**

Desynced( https://store.steampowered.com/app/1450900/Desynced_Autonomous_Colony_Simulator/ )はSteamの高度自動化コロニー作成ゲームです。
ただ、早期アクセスゲーム扱いのため不完全です。
高度自動化とは、作成したアイテムによってエンティティ(ボット、ドローン、ビルディング等)に処理を仕込むことができます。
例えば、資源輸送を複数に配達するとか、複数個所の資源を取得するとか、しばらく使わないビルディングの電源をOFFにするとか。
処理を含めたエンティティはタイトルにあるブループリントと言われます。
そしてこのブループリントはゲーム外と出し入れすることができます。
つまり、他のプレイヤーのブループリントを入れたり、自分のものを提供したりすることができます。
本記事はその方法等についてです。

# ブループリント
テキストデータで、処理を含めたエンティティのデータがJSONで表現され、それをBase64エンコードしたものです。
下記のサイトでJSON・Base64間のコンバートができます。
https://stagegames.github.io/DesyncedJavaScriptUtils/
下記のリンクにあるフォーラムのブループリントで試すとこうなります。

```text:ブループリント
DSC9y2bZV4C0tMgij1EUplM3g7SbQ3dyZPt0vv1q44EgnkF40lx2r3KR2AL18AIVx2xSU1y2agTwI3Sh2f33WGW1l3VHw0842dajP3KgLvy3GASsz0ju1010T8klD3KAl9R40ajsw1ftS970p3inI1jvMov2Od1wn4Vw9da3XjeFf15leDd2fO7Ur2hyPZM0hBBFb0mbWjk0jgZQC11S0W302kBYb3od74V0A5mW61TwiB21g1EKo2OvGAf37gywv2Foa5G1JJg8807klU53naUrO3yw9Bl2PcqtO421vS12F1ZCw1SQSYh48va9a1ty1t22lxU3a3JoXxp2L9Qnx38pJxt1QHSRe419n4a06mIYf1lUwz23
```

```Javascript:中身
{
    "0": {
        "0": {
            "num": 1
        },
        "op": "wait"
    },
    "1": {
        "op": "unlock"
    },
    "2": {
        "0": 1,
        "1": "A",
        "2": "B",
        "3": false,
        "op": "for_signal_match"
    },
    "3": {
        "0": false,
        "1": false,
        "2": "B",
        "3": 1,
        "cmt": "Compare signal number",
        "op": "check_number"
    },
    "4": {
        "0": 1,
        "1": {
            "num": 20
        },
        "2": "E",
        "op": "set_number"
    },
    "5": {
        "0": "A",
        "1": "E",
        "op": "order_transfer"
    },
    "parameters": [
        false
    ],
    "pnames": [
        "Distributed Item with Signal"
    ],
    "vars": {
        "A": 2,
        "B": 3,
        "E": 5
    },
    "name": "Distribute Single Item (Signaled)"
}
```

# 自分のブループリントの作り方
フィールド上でエンティティを選択した状態で、ゲームの操作のコピー(Cキー押下)をするとブループリントがOSのクリップボードに作成されます。
処理も入れたい場合はエンティティが動作コントローラのアイテムを持ってる必要があります。
当然、動かしたい処理があれば、そのアイテムに仕込まれてる必要があります。

# ブループリントの授受
授ける場合、上記のテキストデータを渡すことになります。
受ける場合、まず受けたブループリントのテキストデータをコピー(Ctrl+cキー等)してOSのクリップボードに入れます。
次に、フィールド画面右下のライブラリを開き、そこでペースト(Vキー押下)するとそのブループリントが追加されます。
使いたい場合、ライブラリにあるものはエンティティ作成画面に表示されるので、そこで選択すれば作成して使えます。

# ライブラリ
マウスオーバー等でだいたい使い方はわかると思います。
処理の確認をしたい場合、まず一覧でエンティティを選択します。
(ライブラリ左に詳細が開きます。)
処理がある場合は動作コントローラを持っているので、それをShiftを押しながらクリックするとロジックエディタが開きます。

# リンク
- 公式wiki
https://wiki.desyncedgame.com/Main_Page
- Stermフォーラムのプレイヤーが投稿したブループリント
https://steamcommunity.com/app/1450900/discussions/0/3880470762775678500/
- 公式wikiから抽出したエンティティ等のデータ
https://docs.google.com/spreadsheets/d/1arwLVq9ckkL6NpvNljAVNEQs_Ezo_WsDQ2QgA0fnayY
[エンジニアのmacOS] ストレージの空き容量を確保したいときに削除できるものメモ

# 概要

エンジニアとして使っているMacBookの空き容量を確保したいときに削除できるものをリストしておく。
あくまでも個人的なメモなので、使っている言語やツールによって全く異なると思う。

# 一般的なデータ

## 「書類」

システム設定 > 一般 > ストレージ > 書類 > i マーク > ファイルブラウザ

をクリックすると、容量の大きいファイルをサクサク消していける。
一般的なパソコンとしての使い方をしている場合はこれだけでも十分かもしれない。
ここで閲覧 & 削除できるものに関しては以降では言及対象外とする。

## ~/Library/Caches

各種アプリケーションのキャッシュが入る。
ボトルネックになるサイズのものがあるかどうか確認すると良い。
その中でもう使っていないアプリケーションのキャッシュや、消しても大丈夫と判断できるものは消していく。

# エンジニア関連

エンジニアとして色々やっていると、上記「書類」に含まれないデカデータ（恐らくだいたいは「システムデータ」に含まれる？）が出てくるのでさらにそれらを消す必要がある。

## デベロッパ

システム設定 > 一般 > ストレージ > デベロッパ > i マーク

Xcodeの「キャッシュ」と「ビルドデータとインデックス」は状況に応じて消しても良いだろう。

## node_modules

何はともあれ、まずは最近触っていないレポジトリの node_modules を消していく。
再度使う時はまた npm install すれば良い。

## Yarn Cache

yarn はデフォルトでインストールしたパッケージを（恐らく全て）キャッシュしていく。
つまり各ローカルレポジトリ内の node_modules を消したとしても、`~/Library/Caches/Yarn/` 配下にパッケージが残っている。

```
yarn cache clean
```

このコマンドで全て削除できる。

## Docker Image

Docker には気づくと全然使っていないのにクソデカ容量のイメージがあったりする。

ガシガシ消していく。

```
docker images
docker rmi IMAGE_ID
```

OrbStack と Docker Desktop の両方を使っていた場合は、以下のコマンドでコンテキストを切り替えることができる。OrbStackからは見えないが、Docker Desktop に使っていないイメージがたくさん、なんてことも。

```
# 一覧
docker context list

# Docker Desktop へ
docker context use desktop-linux

# OrbStack へ
docker context use orbstack
```

## Docker Volume

ボリュームも気づくと溜まってたりするのでリストから不要そうなものがあれば消す。

```shell
docker volume ls

docker volume rm <ボリューム名>
```

## Docker のビルドキャッシュ

```
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     64        0         63.47GB   63.47GB
```

このコマンドで容量の内訳を見ることができる。自分のこのコンテキストの場合、イメージを全部消した後だったので Build Cache のみが63.47GBとなっている。
（コンテキストごとに存在するので注意。OrbStack と Docker Desktop ではそれぞれ別の場所にビルドキャッシュを持っている。）

https://docs.orbstack.dev/docker/images#build-cache

> Image build stages are cached to speed up future builds. Unused cache is automatically deleted to save disk space.

ビルドキャッシュは自動で削除されるらしいが、今すぐ消したい場合は以下のコマンドを実行する。

```
$ docker builder prune -a

...

Total reclaimed space: 63.47GB
```

```
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          0         0         0B        0B
Containers      0         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B
```

消せました 🚮

コンテキストごとにこれをやるとかなりの容量が空く。

### 参考

https://docs.orbstack.dev/docker/images#build-cache

https://docs.docker.com/reference/cli/docker/builder/prune/

https://github.com/orbstack/orbstack/issues/242


# おしまい

他にもありがちなものがあれば教えていただけたら嬉しいです。
GNOME Remote Desktopとxrdpの違い【Ubuntu 22.04】


実装が異なる。GNOME使わないならxrdpの方が良さそう

https://gitlab.gnome.org/GNOME/gnome-remote-desktop

https://github.com/neutrinolabs/xrdp

https://can.ne.jp/2022/05/06/ubuntu-22-04-lts%E3%81%AEgnome-remote-desktop%E3%81%8C%E8%87%AA%E5%AE%85pc%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%81%AE%E6%95%91%E4%B8%96%E4%B8%BB%E3%81%A7%E3%81%AA%E3%81%84%E7%90%86%E7%94%B1%E3%80%90/
「IBM i で利用できるプログラミング言語は？」をシュッと回答【備忘録】

# 前置き:raised_hand:
- ずばり、備忘録です

# ずばり、プログラミング言語一覧です
| 言語 | OSサポート有無 |
|:-:|:-:|
| ILE C++ |  OSサポート |
| ILE C  | OSサポート  |
| OPM CL、ILE CL  | OSサポート  |
| OPM COBOL、ILE COBOL  | OSサポート  |
| OPM RPG(=RPGⅢ)、ILE RPG  | OSサポート  |
| SQL（Db2 for i）  | OSサポート  |
| Qshell | OSサポート  |
| REXX | OSサポート  |
| PL/I | OSサポート(PRPQ) IBM i V7.3まで  |
| Java  | OSS |
| PHP  | OSS  |
| Ruby  | OSS  |
| Perl  | OSS  |
| R  | OSS  |
| Python（２系、３系）  | OSS  |
| JavaScript（Node.js環境実行可能/Node-RED利用可能）  | OSS  |


# 終わりに
- 今後Updateがあれば、記事を更新します
- 夏にピッタリ（？）さっぱりめの記事でした:relaxed:
昨日のレコードを削除する際にError: supabaseUrl is requiredというエラーが出る

# はじめに
supabaseで昨日のレコードを削除するコマンドを実行した際にエラーが出たのでその解決策を書いていきます。
# 問題
npx tsx batch/index.tsのコマンドを打つと以下のエラーが出る。index.tsには昨日追加されたレコードを削除する処理が書かれています。
```
Error: supabaseUrl is required
```
# 解決策
supabase.tsに以下の一行を追加する。
```ts
import 'dotenv/config';
```
dotenvは環境変数を.envファイルから読み込むことができるNode.jsのライブラリみたいです。今回の場合適切に.envに定義されてるsupabaseの情報が適切に読み込まれていなかったためエラーになっていたみたいです。

# 追記: 注意点と補足
上記の解決法で一応問題となっていたエラーは消えますが、firebaseでデプロイされているURLを確認すると画面が真っ白になってしまいました。コンソールで確認すると以下のエラーが出ます。
```
Uncaught ReferenceError: process is not defined
```
なのでimport 'dotenv/config'をsupabase.tsに追加するのではなく、コマンド実行時に直接.envの環境変数を渡してあげると良いです↓
```
npx tsx --env-file=.env  batch/index.ts
```
 またgithub actionsのパイプラインでは.envを読み取れないので以下のように渡してあげる必要があります。
 ```yml
      env:
        VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
        VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
      run: npx tsx batch/index.ts
 ```

# おわりに
dotenv自体はjestの環境構築でも使っていたのですが、いまいち何のためのライブラリかはわかっていませんでした。今後はなぜそのライブラリが必要なのかも少しずつ考えるようにしていきます。
【AWS】Lambda関数削除手順【Lambda】

1). Lambdaを開き、削除対象の関数のラジオボタンを押し、「アクション」から「削除」を選択します。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/bbcde979-f26b-8bc1-9ea2-b6d17051ee2f.jpeg)

2). 赤枠に「削除」と入力し、「削除」を押します。
![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/a399c879-2cb7-4fb7-2863-b1e384e5f296.jpeg)

3). 正常に削除されたことを確認して「閉じる」を押して完了です。
![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/77b2d509-ea72-ee8a-e93f-7f02bca959c0.jpeg)
Pythonの dataclass とリスコフの置換原則

# はじめに
Python の [dataclass](https://docs.python.org/ja/3/library/dataclasses.html) を使ってコーディングしている際、
ああ、[リスコフの置換原則](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%B9%E3%82%B3%E3%83%95%E3%81%AE%E7%BD%AE%E6%8F%9B%E5%8E%9F%E5%89%87)ってこういうことか、って気付いたので雑記です。

# 気づき
たとえば、実際の処理`f`と、`f`が受け取るデータ構造`C`に関する下記のようなコードがあったとする。

~~~ python
from dataclasses import dataclass
@dataclass
class C:
    x: str
    y: int

def f(c:C):
    ...

c = C(x='hoge', y=10)
f(c)
~~~

もちろんこれくらいだったら`C`のオブジェクトを直接生成すればよいが、フィールドが多くなると一発で生成できず、`None`等で仮置きしたい場合が出てくる。

~~~ python
c = C(x='hoge', y=None) # type error
...
c.y = 10
f(c)
~~~

ただ、上記のコードでは `c = C(x='hoge', y=None)` の部分で型エラーが出てしまう。
そのため、下記のふたつのクラスを分けたい。
- すべてのフィールドに有効な値が埋まった(最終形の) `C`
- 一部のフィールドに未定義値があることを示す(生成途中の) `C` (以後、`IC` (IncompleteC)で表す)

このとき、直感的には、下記のように記述したくなってしまう(しまった)。
- まず`C`を定義
- 次に`C`を継承して`IC`を定義する
~~~ python
### ダメな例
@dataclass
class C:
    x: str
    y: int

@dataclass
class IC(C):
    x: str # 記述しなくてもOK
    y: int|None
~~~

しかしこう定義してしまうと、`f`が`IC`も問題なく受け入れてしまう。
(`IC`は`C`のサブクラスということは、`IC`は`C`の一種であるから。)
つまり、下記のように記述すべきである。
~~~ python
### 良さそうな例
@dataclass
class IC:
    x: str
    y: int|None

@dataclass
class C(IC):
    x: str # 記述しなくてもOK
    y: int
~~~

集合として考えると、「最終形の」`C`は「生成途中の」`IC`の部分集合なので、まぁ確かにそうかも、って感じがする。

# リスコフの置換原則に当てはめる
[リスコフの置換原則](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%B9%E3%82%B3%E3%83%95%E3%81%AE%E7%BD%AE%E6%8F%9B%E5%8E%9F%E5%89%87)についてWikipediaから引用:
> 型 S の各オブジェクト o1 に対し、型 T のオブジェクト o2 が存在し、T に関して定義されたすべてのプログラム P が o1 を o2 で置き換えても動作を変えない場合、S は T のサブタイプである。

前述の`C`, `IC`, `f`に当てはめると、
`C`は`IC`としてそのまま振る舞うこともできる(定義済みの値を未定義として扱っても支障がない)ため、
**`IC`(T)に関して定義されたすべてプログラムは、`C`(S)に対しても動作を変えない**、
だから良さそうな例の定義による`C`, `IC`の関係はリスコフの置換原則を満たす。

逆に、ダメな例の定義による`C`, `IC`の関係はリスコフの置換原則を満たさない。


# メソッドについても同様だと気付いた
今回はデータクラスとその値を起点にして考えたが、メソッド(意味論)についてもまったく同様で、
生成途中の状態に対しても有効であるメソッドは、最終形の状態に対しても当然使えるはず。
しかし、逆は成り立たない。
~~~ python
### ダメな例
@dataclass
class C:
    x: str
    y: int
    def __str__(self):
        return f'{self.y:05d}/{self.x}'

@dataclass
class IC(C):
    x: str # 記述しなくてもOK
    y: int|None

ic = IC(x='hoge', y=None)
print(str(ic)) # error!
~~~

# 最後に
なお、今回はデータ型への着目から出発して、リスコフの置換原則を理解したが、
メソッドについても触れたとおり、リスコフの置換原則はデータ型についてのみ言うものではない。
実際、Wikipediaにも下記のような記述がある。

> 1. 事前条件(preconditions)を、派生型で強めることはできない。派生型では同じか弱められる。
> 2. 事後条件(postconditions)を、派生型で弱めることはできない。派生型では同じか強められる。
> 3. 不変条件(invaritants)は、派生型でも保護されねばならない。派生型でそのまま維持される。
> 4. 基底型の例外(exception)から派生した例外を除いては、派生型で独自の例外を投げてはならない。

奥が深いなぁ。


# 追記: dataclass のフィールドをオーバーライドするにあたって
型チェッカに警告されたので気付いたのだが、何も考えず dataclass のクラスをオーバーライドして型を変えるのはよくない。
なぜならば、スーパークラスではスーパークラスで定義したフィールドの型を期待しているから。
具体例:

~~~ python
@dataclass
class A:
    x: int|None

    def set_none(self): # こういう手続きがありえる
        self.x = None

@dataclass
class B(A):
    x: int # ダメ!

b = B(x=0)
b.set_none() # これができてしまい、Bの型制約に違反する！
~~~

これを回避するには、`frozen=True`でイミュータブルにしてしまうとよい。

~~~ python
@dataclass(frozen=True) # frozen=True をつける
class A:
    x: int|None

    # そもそもこういうメソッドは許されなくなる。
    #def set_none(self):
    #    self.x = None

@dataclass(frozen=True) # こっちにも
class B(A):
    x: int # OK!
~~~
【UE5】背景透過したキャラクター画像をゲーム内に配置する方法

3Dゲーム内に2Dのイラストを配置してみました！
モデリングがまだできない&表現方法としてちょっとオシャレかな〜と思って作ってみました。いい感じになった気がする。モデリングのコストを抑えられる意味でもおすすめかも

完成画像
![スクリーンショット 2024-08-20 20.30.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3823140/8a2cf9e2-99f7-3d81-b062-18080c8aafbe.png)

1.背景透過した画像を用意し、ドラッグ&ドロップでUE内にインポートします。
2.取り込んだ画像を右クリックしマテリアルを作成
3.マテリアルを開き Blend Mode を Masked に変更
4.透明度（A：Alpha）を オパシティマスク に繋ぎます。

![スクリーンショット 2024-08-21 18.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3823140/30c31b6d-0f70-0d93-a105-59402b9ac9a1.png)


5.作成したマテリアルを反映させるためのアクタのブループリントを作成
6.薄い板を作り、作成したマテリアルを反映したら完成！

![スクリーンショット 2024-08-21 18.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3823140/960777c9-efc3-fafa-3636-4763be86ac3a.png)
【CSS】子要素の状態によって親要素のデザインを変える

# はじめに

かなり初心者向けです。

Material UI の一つである Mantine UI で「Checkbox」というコンポーネントを使用し、checked属性によってCheckboxコンポーネントのデザインを変更したいのに、実際にchecked属性が付いているのはその子要素の`div`のさらに子要素の`input`と入れ子になっていてどうしたらええんや～（CSS初心者並感）

ということがありました。

```html
/** 使用しているコンポーネントの見た目 */

<Checkbox
    label="チェックボックス"
    oChange={() => {}}
    size="md"
    mr="xl"
    checked
/>
```

```html
/** 実際の中身 */

<div class="mantine-Checkbox-root">     /** Checkboxコンポーネントを構成する大外の要素*/
    <div class="mantine-Checkbox-inner">
        <input type="checkbox" checked />   /** チェックボックスの本体 */
    </div>
</div>
```

そこで調べてみたところ、擬似セレクタの一つに`has`というものがあったので紹介します。

# 概要

- 擬似セレクタ
- has

# 擬似セレクタ

セレクタは `.parent`や`#children` のようなHTMLの要素を特定するためのものですが、擬似セレクタは**要素の状態によってスタイルを設定することができるもの**です。

ほんの一例ですが、

- checkboxがチェックされていることを示す `:checked`
- クリックされアクティブ化された要素（a や button等）を示す `:active`
- カーソルが要素にかざされていることを示す `:hover`

などが有名です。

# has

今回使用するセレクタは `:has` セレクタです。

これは特定の子要素を持つ親要素を指定するためのセレクタとなります。

```html
<div class="parent">
  <input type="checkbox" class="checkbox"/>
</div>

<style>
  .parent:has(input:checked) {
    background-color: red;
  }
</style>
```

例えば上記のようにすると、

##### 「checked属性がtrueである（checkedがついている）input要素」を子要素に持つ親要素

を指定することができます。

# 最後に

長らくWeb開発に携わっていますが未だにCSSの苦手意識が強いため、もう少し積極的に触れていきたいと思ってます。

同じ問題を抱えている人の手助けになれたら幸いです！
git cloneでは取得できなかったブランチをgit checkoutでまとめて取得。

このGitHubのリポジトリは、ある技術本のサンプルです。

https://github.com/PacktPublishing/Building-Production-Grade-Web-Applications-with-Supabase

ただし、これを開くと
LICENSE
README.md
だけで、ソースコードがmainブランチにありません。

このリポジトリは、mainブランチ以外のブランチに章ごと分けてサンプルが入っています。

素直に`git clone`をしても、これではmainだけをcloneして、その他のブランチは取得できません。

それぞれの章を取得するには、一つ一つ git checkoutをする必要があります。

サンプルは章ごとにあるので、何回もやるのは面倒なのでAIに聞きつつ、まとめて取得するスクリプトを書いて貰いました。

## Windows版

リモートも含めたすべてのブランチ名の取得、確認
```terminal
git branch -a
```

すべてのリポジトリをまとめて取得。
```terminal
$branches = git branch -r | Where-Object { $_ -notmatch '->' -and $_ -notmatch 'HEAD' }
foreach ($branch in $branches) {
    $branchName = $branch.Trim() -replace 'origin/', ''
    git checkout --track "origin/$branchName"
}

```

本のサンプルなので、必要なときに`git checkout`すればいいという考え方なのでしょうが、サンプルをまとめてダウンロードしたかったので調べてみました。

`git clone`はデフォルトブランチしかダウンロードしてくれません。

### ログ

```log
08-21 18:19:29> $branches = git branch -r | Where-Object { $_ -notmatch '->' -and $_ -n
\ebook\Building-Production-Grade-Web-Applications-with-Supabase [Ch02_AppRouter ≡
08-21 18:19:51> foreach ($branch in $branches) {
>>     $branchName = $branch.Trim() -replace 'origin/', ''
>>     git checkout --track "origin/$branchName"
>> }
fatal: a branch named 'Ch02_AppRouter' already exists
Switched to a new branch 'Ch02_PagesRouter'
branch 'Ch02_PagesRouter' set up to track 'origin/Ch02_PagesRouter'.
Switched to a new branch 'Ch03_TicketSystem_UI'
branch 'Ch03_TicketSystem_UI' set up to track 'origin/Ch03_TicketSystem_UI'.
Switched to a new branch 'Ch04_TicketSystem_Auth'
branch 'Ch04_TicketSystem_Auth' set up to track 'origin/Ch04_TicketSystem_Auth'.
Switched to a new branch 'Ch05_TicketSystem_MultiTenancy'
branch 'Ch05_TicketSystem_MultiTenancy' set up to track 'origin/Ch05_TicketSystem_MultiTenanc
Switched to a new branch 'Ch06_RLS_Permissions_Domains'
branch 'Ch06_RLS_Permissions_Domains' set up to track 'origin/Ch06_RLS_Permissions_Domains'.
Switched to a new branch 'Ch07_Registration'
branch 'Ch07_Registration' set up to track 'origin/Ch07_Registration'.
Switched to a new branch 'Ch08_Tickets'
branch 'Ch08_Tickets' set up to track 'origin/Ch08_Tickets'.
Switched to a new branch 'Ch09_UserList_and_Assignees'
branch 'Ch09_UserList_and_Assignees' set up to track 'origin/Ch09_UserList_and_Assignees'.
Switched to a new branch 'Ch10_Realtime'
branch 'Ch10_Realtime' set up to track 'origin/Ch10_Realtime'.
Switched to a new branch 'Ch11_Storage'
branch 'Ch11_Storage' set up to track 'origin/Ch11_Storage'.
Switched to a new branch 'Ch12_Security'
branch 'Ch12_Security' set up to track 'origin/Ch12_Security'.
Switched to a new branch 'Ch13_Superpowers'
branch 'Ch13_Superpowers' set up to track 'origin/Ch13_Superpowers'.
fatal: a branch named 'main' already exists

```

最後は`mainブランチ`はすでにあるので失敗しています。

Ch02_AppRouter はすでに`checkout`していたので失敗しています。
SquarespaceにAmazon SES DKIM認証のDNSレコードを登録する時の注意点

SES側の[ 名前 ]列の値はドメイン部分を除外してからSquarespaceの[ ホスト ]に登録する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/50be1501-86be-59b6-50a4-00c09c930981.png)
OpsRamp - Knowledge Baseの割り当て先について

本記事では、OpsRampのKnowledge Baseの割り当て先について説明します。

# 概要
OpsRampでは、Knowledge Baseをリソース、モニターおよびインシデントに割り当てることが可能です。

# 説明
リソースまたはモニターにKnowledge Baseを割り当てることができ、アラートおよびインシデントで参照することができます。
- リソースに割り当て方
リソースの詳細画面から割り当て可能です。
![kb-resource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/1980b436-617a-3e01-1d9e-14610b31f881.png)
- モニターに割り当て方
モニターテンプレート設定画面の各モニターに対するKnowledge Articlesから割り当て可能です。
![kb-monitor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/ea5ffa48-319f-9afc-aa5f-26e554f4497f.png)

- アラートでの参照
![kb-refer-alert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/8a2311a8-a887-e80a-d6b1-6985932ca472.png)


Alert Escalationポリシーを使用して、自動でインシデントに割り当てることも可能です。
- インシデントに割り当て方
インシデント詳細画面のナレッジアーティクルから割り当て可能です。
![kb-incident.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/62bd4c5a-9b4a-65c6-dd30-51689e6d276b.png)

- Alert Escalationポリシーでの割り当て方
インシデント設定画面のKnowledge Articlesから割り当て可能です。
![kb-aep.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/7c6a9627-e9c6-a57d-34e7-e1bd5836a38b.png)

- インシデントでの参照
![kb-incident.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/62bd4c5a-9b4a-65c6-dd30-51689e6d276b.png)
![kb-incident-resource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/15cada19-bdd8-0cc3-2ce7-46d1b0a296cd.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
第三回: WEBサイトが手元に届くまで

こんにちは、[株式会社カスタマトリックス](https://www.customatrix.co.jp/)の寺尾です。

こちらは **新卒社員と学ぶWEBプログラミング** 企画になります。
可能な限り毎日更新していくのでご期待ください。

本日は第三回、「**WEBサイトが手元に届くまで**」を説明していきます。
どうしてURLをWEBブラウザで開くだけで勝手にWEBサイトの表示まで辿り着けるのか、そしてその裏でどのようなサービスが動いているのか、その辺りを簡単に説明します。

前回はこちら
https://qiita.com/r-terao/items/26fca77cf5fc1e1db218

第一回はこちら
https://qiita.com/r-terao/items/e6237c4dc59db9e96ec6

# 前回のあらすじ
前回学んだ事は覚えていますでしょうか？

- WEBサイトはサーバが持っていて、それをクライアントがお願いして表示する
- フロントとかバックというのはあくまで仕事内容が違うだけで、仕事場所に左右されるとは限らない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/f7341021-e98f-1250-e692-495645f7b78d.png)

# 間に横たわる距離
前回、クライアントがサーバに対して「サイトください」とお願いする事でWEBサイトが表示できると説明しました。
これ自体は何もおかしな事のない説明なのですが、その裏で動いている機能があります。

それは「 **遠く離れたどこにあるか分からないサーバをどうやってクライアントは発見しているのか** 」です。

このクライアントとサーバの間にある距離を繋いでくれる仕組みが今回の主役になります。

# インターネット上の住所
ここで問題です。
```
WEBサイトの住所といえば何を指すでしょうか？
```

URLと答えた方も多いのではないでしょうか？
それは残念ながらちょっと違います。

正解は「 **IPアドレス** 」です。

IPアドレスはネットワークに接続する端末一つ一つに割り当てられる識別番号で、必ず被らない値になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/ae1a8d36-7ac1-a5d6-dd79-2af97fc0c002.png)


画像は適当な数値ですが、多くの場合上側のような四分割の数字が割り当てられます。
近年数字の枯渇に伴い、画像下側のIPv6という英数字対応の新しいものが出てきていたりもします。


WEBブラウザで`https:{IPアドレス}`などと入力する事でクライアントは世界のどこかにあるサーバを特定しアクセスする事ができるわけですね。

# URLとドメイン
ここまで聞いて「じゃあURLって何なんだろう？」「IPアドレスなんて普段見た覚えない気がする」といった疑問が湧いた方もいらっしゃるのではないでしょうか？

URLの説明のためにはまずはドメインの理解から始める必要があります。

ドメインとは、 **人間でも理解できる言葉にIPアドレスを置き換えたもの** です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/d808834f-ae0c-cfb0-8755-a05b9df56e82.png)

ドメインは「`自由な文字列 + 管理名`」で作られていて、IPアドレスと同じように他と被ることはありません。
同じに見えるドメインでも`.jp`や`.com`、`.net`などの管理元が違うことで全体を見ると違う名前になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/cb1f8bf3-3a61-ecf1-19e7-4b86fc3a9ca6.png)

基本的にトップレベルが「管理する団体」を示し、セカンドレベルかトップレベルが「目的、種別」などを指します。
また、ホスト名を足し合わせることで **FQDN（完全ドメイン）** と呼びます。

さて、ではURLとはなんなのかという話になります。
URLとは「 **サーバにアクセスして、どこにあるどのような何が欲しいのか** 」まで記載されたモノの事です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/1b909096-01e4-6608-6f62-0b4335bdab91.png)

- スキームは「どんな種類のモノを欲しいか」
- ポートは「サーバのどの出入口からデータを出入りさせるか」
- ディレクトリとファイル名は「どのデータが欲しいか」

を指し示しています。
難しい事を省くと、サーバの住所以外の細かい諸々の指定を足した文字列がURLというわけです。

# DNS
ドメインについて学んでいくと「 **DNS（ドメインネームシステム）** 」という存在が出てきます。

これは「 **IPアドレスとドメインの対照表** 」を管理するシステムです。
URLからサーバにアクセスする際、WEBサイトが置いてあるWEBサーバアへクセスする前に対照表を管理しているDNSサーバにアクセスし、自分が見たいサーバのIPアドレスをチェックするという処理が挟まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2273193/49c4f740-bd67-4252-1b8f-4a12be42ff06.png)

DNSサーバにも更に「権威DNSサーバ」「キャッシュDNSサーバ」とかあるので、気になる方はチェックしてみよう。

# まとめ
- サーバの住所はIPアドレスで管理している
- IPアドレスだと読みにくいのでドメインを代わりに使う
- DNSを使うことで、ユーザはIPアドレスを気にする事なくWEBサイトへアクセスできる
- URLはどんなファイルが欲しいかなどの情報が更に足されている

多少はイメージがついたでしょうか？
CDNとかプロトコルとかもっと色々説明するつもりでしたが長くなってしまったので残りは次回にします。

次を乗り切れば仕組みは大枠理解したといえるので、もうひと踏ん張り頑張っていきましょう。

その後はプログラミング言語に触れて実践的な内容をやっていこうと思います。

# おまけ
株式会社カスタマトリックスはエンジニアを募集しています！
完全未経験でも可！

- 新卒の方
https://www.customatrix.co.jp/newgrads/index.html

- 中途の方
https://customatrix.co.jp/career/index.html

https://www.instagram.com/cmx_pr/
クラウド変数の容量の限界を調べる

# はじめに
初投稿です。めちゃくちゃ分かりづらい記事になっている気がします。
Scratchというサイトとプログラミング言語があります。Scratchでは「クラウド変数」という機能が追加されています。クラウド変数はサーバーにデータが保存され、Scratcherであれば誰でも変更できます。この機能を応用すれば、オンラインゲームなども作成できます。
今回はクラウド変数について詳しく見ていきます。

# クラウド変数の制限
とても便利なクラウド変数ですが、いくつかの制限があります。
- 基本的にNew Scratcherだと使えない
- 一つのプロジェクトに10個しか作れない
- 基本的に0.1秒のレート制限がある
- クラウド変数に保存できる値には安全性確保やサーバーへの負荷を弱くするのための制限がある

今回は「クラウド変数に保存できる値」について考え、その容量の限界を調べてみます。クラウド変数の制限は詳しく明らかにされていませんが、有名なものとして、「数値しか保存できない」や「256文字しか保存できない」があります。

その他の制限としては、
- +がついているものは保存不可能
- -は最初の文字でしか置けない
- 小数点はどこにでも置けるが、1つのみ
- 空白（スペースではない）でも保存できる
- -や.単体では保存不可能
- NaNやInfinityは保存不可能
- 指数表記も内部的にNumber型にすれば保存可能
といった条件があります。

# 容量を計算する
では、容量を計算していきます。
まずは内部的にString型として保存される情報についてです。

### 正の数
正の小数点が含まれない文字列としての数については、
$$\sum_{k=0}^{256}10^k$$
で計算できます。k=0のときは""(何も保存しない)が保存できるので問題ありません。クラウド変数には"0005"のような値も保存できるのでこれで大丈夫です。

次に正の小数点が含まれる文字列としての数についてです。
$$\sum_{k=1}^{255}10^k(k+1)$$
で問題ないでしょう。k=0の場合は"."になるのですが、これは前述した通り保存できません。シグマの上を255に設定している理由は、先に"."を配置しているものだと考えればわかりやすいでしょう。

### 負の数
負の小数点が含まれない文字列としての数は、
$$\sum_{k=1}^{255}10^k$$
となります。

小数点が含まれている場合は、
$$\sum_{k=1}^{254}10^k(k+1)$$
です。これでk=2と設定しないのは、"-2."のような値も保存できるからです。ちなみに"-."は保存されません。

### Number型の場合
Number型の1000もString型の"1000"もクラウド変数のサーバー内部では同じようにStringとして保存されます。Number型はすぐにStringに変換されます。この変換はクライアント側で行われていますが、それをすっ飛ばしてNumber型のままデータを送っても上手くいかないため、Stringで保存されるように設計されています。

1e+20はScratchやJavaScriptの仕様では100000000000000000000となってしまいます。これだとStringで保存されるのと変わりませんよね？指数表記で保存されるものを調べたいということです。

ここで[仕様書](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-tostring)を使います。読めば分かりますが、$$x<10^{-6},x\leq10^{21}$$のどちらかが成り立つ x は指数表記になります。

ということで、
$$(0, 2^{-20}]$$
$$(2^{-20}, 10^{-6}]$$
$$[10^{21},2^{70})$$
$$[2^{70},\infty)$$
の4つの区間について倍精度浮動小数点でそれぞれ考えていきます。

$$(0, 2^{-20}]$$について、$$2^{-20}=2^{1003-1023}$$のため、
$$1003*2^{52}$$で個数を求められますね。

次に
$$(2^{-20}, 10^{-6}]$$ですが、[浮動小数点数内部表現シミュレーター](https://tools.m-bsys.com/calculators/ieee754.php)によると$$10^{-6}=3eb0c6f7a0b5ed8d_{(16)}*2^{-20}$$
が成り立つようです。よって、
$$3eb0c6f7a0b5ed8d_{(16)}$$
がその値になります。

では、$$[10^{21},2^{70})$$についてです。
$$10^{21}=b1ae4d6e2ef50_{(16)}*2^{69}$$

よって、答えは
$$2^{52}-b1ae4d6e2ef50_{(16)}$$
でいいです。では、さいごの$$[2^{70},\infty)$$やります。
[1093,2047)なので、答えは
$$954*2^{52}$$
ですね。負の数は同じものの和でできます。

では、JavaScriptのBigIntを用いて足し算していきます！
```js
let tmp = 0n;
for(let i = 0n;i<256n;i++){
    tmp += 10n**i
}
for(let i = 1n;i<255n;i++){
    tmp += 10n**i*(i+1n)
}
for(let i = 1n;i<255n;i++){
    tmp += 10n**i
}
for(let i = 1n;i<254n;i++){
    tmp += 10n**i*(i+1n)
}
tmp +=1003n*2n**52n
//3eb0c6f7a0b5ed8d(16)=4517329193108106637(10)
tmp += 4517329193108106637n

//b1ae4d6e2ef50=3125794903879504
tmp += 2n**52n-3125794903879504n
tmp += 954n*2n**52n
console.log(tmp.toString())
```
電卓としてつかったので適当ですが、こんな感じでやると「32364197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530864197530877529782332793189162」という値になります。これが何bitかというと、底が2の対数にいれるため、852.1079910239091bitとなります。
指数表記を含めると13332251468595658301通り増えました。めちゃくちゃ少ない……。

# さいごに
指数表記とか面倒なことに囚われてもほとんど意味がありませんよ！諦めて文字列連結を頑張りましょう！
Elixir Jason

この記事ではelixirのJasonについて解説を行います。
ドキュメントを引用しつつJasonとは何なのかどういう機能があるのかを解説します。

Jason
公式ドキュメントからの引用によると
> A blazing fast JSON parser and generator in pure Elixir.

https://hexdocs.pm/jason/readme.html

とのことでJsonパーサーとジェネレーターのようです。

Json形式の文字列を理解しやすいように加工してくれるようです。

mix.exsに対して
{:json, "~> 1.4"}を追加、mix deps.getで依存関係の取得を行います。

https://hexdocs.pm/json/readme.html

```elixir
iex(2)> %{"first" => 1, "last" => 10, "step" => 2}
%{"first" => 1, "last" => 10, "step" => 2}
iex(3)> |> Jason.encode!
"{\"first\":1,\"last\":10,\"step\":2}"
iex(4)> |> Jason.decode!(keys: :atoms)
%{first: 1, last: 10, step: 2}
iex(5)> %{first: 1, last: 10, step: 2}
%{first: 1, last: 10, step: 2}
iex(6)> |> Jason.encode!
"{\"first\":1,\"last\":10,\"step\":2}"
iex(7)> |> Jason.decode!
%{"first" => 1, "last" => 10, "step" => 2}
```

エンコードデコードが簡単にできます。
Macでpygraphvizをインストールするのに「graphviz/cgraph.hがない」と怒られる問題

# はじめに
LangGraphでグラフの画像を出力するときに`pygraphviz`が必要になったので、`homebrew`で`graphviz`をインストールしてから`pygraphviz`をインストールしようとするとエラーが出ました。

# エラー
`graphviz/cgraph.h`が見つからないというエラーがでました。

# 解決策

まず以下の記事を見つけました。

https://qiita.com/ryoppippi/items/f484eb995ff1e913dd44

`--install-option`で適切に`--include-path`と`--library-path`を設定すれば良いとのことでした。しかし、自分はパッケージマネージャーの`uv`を使用しており、`--install-option`がありませんでした。

さらに調べて見つけた[このサイト](https://iriusrisk.github.io/startleft/Troubleshooting/#cannot-open-include-file-graphvizcgraphh)の通りにやったら解決しました。

まとめると、以下のコマンドを実行することでインストールすることができます。
```sh
$ brew install graphviz
```
```sh
$ export CFLAGS="-I $(brew --prefix graphviz)/include"
$ export LDFLAGS="-L $(brew --prefix graphviz)/lib"
```
```sh
$ uv pip install pygraphviz
```

# おわりに

環境変数を設定することで、無事インストールできました。
[Python + Selenium ヘッドレスブラウザ] webdriverでjsを呼び出した場合のログ確認

ヘッドレスブラウザ上でjavascriptで処理を実行した場合どうデバッグする方法
console.log()の内容をpython側に持ってきて標準出力で確認できるようにしました。

```
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

# Chrome WebDriverの設定
chrome_options = Options()
chrome_options.add_argument("--headless")  # ヘッドレスモード
service = Service('/path/to/chromedriver')  # Chromedriver のパス

# WebDriverの初期化
driver = webdriver.Chrome(service=service, options=chrome_options)

# 任意のURLを開く
driver.get("https://example.com")  # ここに実際のURLを指定

result = driver.execute_script('example.js')  # ここに実際のjsファイルのパスを指定

# コンソールログを取得
logs = driver.get_log('browser')

# 結果の表示
print("JavaScript result:", result)
for log in logs:
    print("Log:", log['message'])

# ブラウザを閉じる
driver.quit()

```
Windows OS が起動しなくなった...セーフ モード！君に決めた！

Windows OS には、必要最低限の機能のみで起動できる Safe Mode という起動方法があります。追加でインストールした 3rd Party 製のドライバーを起因として OS 起動不可が発生している場合には、Safe Mode でなら起動できる可能性があります。

Safe Mode で起動できたら、怪しそうなソフトウェアをアンインストールすることで、OS 起動不可の状態を解消できるかもしれません。

Safe Mode を起動する方法は、複数ありますが、ブート メニューから選択する方法が個人的におすすめなので、こちらを紹介します。

## ブート メニューからセーフ モードを起動
### Step 1. コマンド プロンプトを起動
以下の Web サイトに OS が起動しなくなった状態からコマンド プロンプトを実行する方法を投稿したので、いずれかの方法でコマンド プロンプトを実行します。

https://qiita.com/ausamayuni/items/1a581eaec6e82e966419

### Step 2. ブート メニューを表示する設定を追加
bcdedit コマンドを使用し、displaybootmenu の設定を入れます。
```bat
bcdedit /set {bootmgr} displaybootmenu yes
```
設定が正しくされたか、displaybootmenu の設定値が Yes になっていることを確認します。
```bat
bcdedit /enum
```

![displaybootmenu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/1b2cdfad-fbbc-2bbb-d08b-511d2088b0d7.png)

https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/bcdedit-command-line-options

### Step 3. システムを再起動
回復環境、インストール メディア、Windows PE からコマンド プロンプトを起動している場合には、`wpeutil reboot` で、再起動するのが簡単です。
```bat
wpeutil reboot
```
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/wpeutil-command-line-options

### Step 4. ブート メニューが表示されるので F8 を入力
以下のような画面が表示されるので、F8 を入力して詳細オプションへ進みます。なお、Windows OS のバージョンによって、若干、画面の表示は異なります。

![bootmenu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/5e2626ea-a693-a274-0b0d-f9ea04d2c496.png)

### Step 5. F4 を入力し、セーフモードを有効にするを選択
様々なスタートアップ設定が選択できますが、F4 がセーフモードで起動する選択肢になります。
![startup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/ffa4586c-ef8c-cdfa-3f8c-636088f494ef.png)

F4を入力するとセーフモードで起動し、画面の端にセーフモードと表示がされます。
![safemode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/6c33a687-e7d2-46bc-eac6-c3de5cd9f44f.png)

### ブート メニューを表示する設定の解除方法
displaybootmenu の設定は、コマンド プロンプトより、以下のコマンドを実行することで、削除でき、元の状態へ戻せます。
```bat
bcdedit /deletevalue {bootmgr} displaybootmenu
```

## さいごに
セーフ モードで起動できたら、怪しそうなのを片っ端からアンインストールしましょう！
【paiza×Qiita】JavaScriptで最小文字数での解答を目指す【Cランク編】

# はじめに
こちらの[paiza×Qiita記事投稿キャンペーン](https://qiita.com/official-events/9ab96aa95d62fe3cbdd7)のCランク問題を、コードゴルフの要領で最小文字数で解答することを目指しました。
言語はJavaScriptです。

他のランクはこちら

- [Dランク](https://qiita.com/TD12734/items/8864fc925e4b35efea13)(標準入力の解説もこちら)
- [Bランク](https://qiita.com/TD12734/items/5e36081d58f0ee5cf97b)
- [Aランク](https://qiita.com/TD12734/items/bfded9d604d71554eb19)

# 多分これが一番短いと思います
## 宝くじ
```js
process.stdin.some(l=>{[a,b,...c]=(0+l).trim().split`
`;c.map(d=>{d-=a;console.log(d?~d&&d-1?d%1e4?d%1e3?"blank":"third":"second":"adjacent":"first")})})
```

153文字

`0+l`で入力された数字を数値の配列に変換。
jsでは0がfalse扱いされることを利用し、三項演算子で色々と処理しています。
まず、それぞれの宝くじ番号(d)から当選番号(a)を引き、以下を確認しています。

- 0のとき：1等
- ビット反転して0(d=-1)か1引いて0(d=1)のとき：前後賞
- 10000(1e4)で割った余りが0のとき：2等
- 1000(1e3)で割った余りが0のとき：3等
- その他：はずれ

## 野球の審判
```js
s="strike";t="ball";u=v=3;process.stdin.some(l=>{[a,...b]=(0+l).split`
`;b.map(c=>c&&console.log((c==s?--u?s:"out":v--?t:"four"+t)+"!"))})
```

138文字

uが0になったら`out!`、vが0になったら`fourball!`を出力します。
bの最後には空白文字列が来るので、それを`c&&`で弾いています。

## みかんの仕分け 
```js
process.stdin.some(l=>{[a,...b]=(l+"").split`
`;a=a.split` `[0];b.map(c=>c&&console.log(a*Math.round(c/a)||a))})
```

112文字

a*Math.round(c/a)が0の時はaを出力します。

## Fizz Buzz
```js
process.stdin.some(l=>{for(i=1;i<=l;i++)console.log(i%15?i%3?i%5?i:"Buzz":"Fizz":"Fizz Buzz")})
```

95文字

入力が数字と改行だけなら文字列にしたり改行を消さなくても数字扱いされるようです。

## 残り物の量
```js
process.stdin.some(l=>{[m,p,q]=(0+l).split` `;console.log(m*(100-p)*(100-q)*1e-4)})
```

83文字

今回はlを文字列にするのは不要なので0+lで数値に変換。

# おわりに
今回は文字の出力が多くなったのでDランクよりも全体的にコードが長くなりましたが、コードは全体的に綺麗なんじゃ無いかと思います。
特にFizz Buzzは良いコードになったと思います。
lambda share

```
export const handler = async (event) => {
    try {
        
        const jsonObject = event;

        
        const formattedMessage = `Security Hubが以下の重要度の異常を検知しました: ${jsonObject["Security Hubが以下の重要度の異常を検知しました"]}
Account ID: ${jsonObject["Account ID"]}
発生時間: ${jsonObject["発生時間"]}
ProductArn: ${jsonObject["ProductArn"]}
検出内容: ${jsonObject["検出内容"]}`;

        
        return formattedMessage;
    } catch (error) {
        return `Error: ${error.message}`;
    }
};
「初心者向け」Hugging Faceのモデルを使って画像生成を試してみた




そもそもHugging Face って何？
----
https://huggingface.co/

**HuggingFace** は、AIや機械学習の技術を簡単に使えるプラットフォームです。特に、自然言語処理（NLP）分野で有名で、テキストの翻訳、要約、質問応答などのタスクに役立つモデルを提供しています。初心者でも扱いやすく、プログラミングの知識がなくても利用できるインターフェースやツールが揃っています。多くの事前学習済みモデルが公開されており、自分のデータに合わせてモデルをカスタマイズしたり、再利用したりすることも可能なサイトです。




<br>
シンプルに言うとたくさんのAIモデルが公開されていて、それを個人でも簡単に使用できるサイトってことですね。



さぁ、使ってみよう
-----
今回はこちらの画像生成モデル[runwayml/stable-diffusion-v1-5](https://huggingface.co/runwayml/stable-diffusion-v1-5)を実装してみたいと思います。
  各モデルの実装方法は基本的に **ModelCard** タブに記載されています。今回のモデルのサンプルコードは以下になるようですね。

```python:runwayml/stable-diffusion-v1-5
from diffusers import StableDiffusionPipeline
import torch

model_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "a photo of an astronaut riding a horse on mars"
image = pipe(prompt).images[0]  
    
image.save("astronaut_rides_horse.png")

```

実装方法がわかったので、あとはコードを環境に入れて実行するだけですね。
今回の実行環境として**Google colaboratory**を使います。



操作方法などネットでたくさん公開しているので、初めてお使いになる方はぜひ参照してみてください。


 

 さて、GoogleColabでNoteBookを開けたら、まずランタイムのタイプが**T4 GPU**になっていることを確認します。
 <br>
ランタイムタブ → ランタイムタイプ → **T4 GPU**
 <br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784500/547b482f-31b0-5d37-35f2-44bf5f190820.png)


 続いて、さきほどのサンプルコードをコピペして少しアレンジしていきます。変更箇所に注釈を追記しています。

```python:runwayml/stable-diffusion-v1-5

#必要なライブラリをインストール
!pip install diffusers==0.24.0 accelerate==0.25.0

from diffusers import StableDiffusionPipeline
import torch

model_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe = pipe.to("cuda")

#生成したい画像のプロンプトに書き換える
prompt = "a bird flying in the sky"


image = pipe(prompt).images[0]  

#GoogleColabでは変数名を書くだけで中身（画像）を表示してくれる
image

```
<br>
こちらの↓リンクから実際実行したNoteBookにアクセスできます。

https://colab.research.google.com/drive/1C9M_z7PqvR6sovI0eFUygm9pNTfRqaIF?usp=sharing

 実行結果
----
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784500/bdf7b9c3-7e7f-1c9a-0a42-7a83641bfc1b.png)

確かに鳥が空に飛んでいる画像を生成してくれましたね。ほんとに鳥なのか、微妙なところではありますが、精度は今回のPointではないので、大目に見てあげましょう　(笑)


生成された画像たち
----
```python
prompt = "a bird flying in the sky"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784500/79210b52-bf27-9357-d86e-14b2d7f96b5d.png)

```python
prompt = "A black cat with blue eyes"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784500/98a934d8-3833-d37c-493f-643088e31417.png)

```python
prompt = "A white cat with blue eyes"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784500/97f4220c-d3fa-76a1-c1c5-3fae0691f349.png)