OmniAICreator/Qiita-1.07M huggingface dataset:
【Error】コードは正しいはずなのにログアウトボタンを押すとエラーになる。Turbo

前置きなく本題早速入ります

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## こうすることで解決した
👇エラーが起こっていたコード
```
<%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: "btn btn-primary" %> 
```
👇エラー解消コード
```
<%= link_to "ログアウト", destroy_user_session_path, class: "text-sm font-semibold leading-6 text-gray-900", data: { turbo_method: :delete } %> 
```

## 一体何がいけなかったのか？
- **Turboの影響**:
    - Rails 7以降では、Turboがデフォルトで使われる。（Turboはページの部分的な更新を可能にし、ページ遷移を軽くするライブラリ）
    - `method: :delete`を使ったときに、UJS（Unobtrusive JavaScript）が正しく動作しない場合、Turboはこの情報を正しく処理できないことがある。
- **`data: { turbo_method: :delete }`の使用**:
    - `data: { turbo_method: :delete }`を使うことで、TurboがこのリンクがDELETEリクエストであることを理解し、正しく処理。
    - これにより、JavaScriptが直接関与することなく、Railsのログアウト機能を正しく呼び出すことができる。
- **UJSとTurboの連携**:
    - 元のコードでは、`method: :delete`を指定してUJSに依存していたが、なぜかUJSが動作せず、DELETEリクエストが適切に送信されていなかった？！
    - Turboを使用することで、リクエストのメソッドを指定するための新しい方法が提供。正しく機能しログアウトができた。


### ★UJSについて★
UJS（Unobtrusive JavaScript）は、Railsが提供するJavaScriptライブラリで、特にリンクやフォームの動作を強化するために使用。
UJSを使うことで、例えばリンクにmethod: :deleteやmethod: :patchなどを指定し、サーバーに対して正しいHTTPメソッドを送信することができます。

Rails 6以前では、`application.js`ファイルでUJSを読み込むように設定されていたそうです。
`app/assets/javascripts/application.js`に下記のような記述がある
```java
//= require rails-ujs
```

ついでにRails7以降では次のように確認できるそうです
- **Rails 7以降**（`importmap`を使う場合）では、`config/importmap.rb`に`pin "@rails/ujs"`があるか確認し、`app/javascript/application.js`でインポートされているか確認。
- **Webpackerを使っている場合**では、`package.json`に`@rails/ujs`が含まれているか、そして`app/javascript/packs/application.js`でインポートされているか確認。



# さいごにまとめ
- Rails 7以降はTurboが加わったことをしる
- Turboを考慮してコードを書くことが大切！
- 今回の記事が何か参考になれば幸いです。
vbaからsql文を作成する

```
Sub GenerateCreateTableSQL()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim tableName As String
    Dim sql As String
    Dim i As Long
    Dim colName As String, colType As String
    Dim isPrimaryKey As Boolean, isAutoIncrement As Boolean
    
    ' 対象のシートを設定
    Set ws = ThisWorkbook.Sheets("USER")
    
    ' 物理テーブル名を取得
    tableName = ws.Cells(4, 11).Value
    
    ' SQL文の初期化
    sql = "CREATE TABLE スキーマ名." & tableName & " (" & vbCrLf
    
    ' 最後の行を取得（空白行を考慮）
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row
    
    ' 8行目以降のカラム定義を読み込む
    For i = 8 To lastRow
        colName = ws.Cells(i, 10).Value  ' 物理カラム名
        colType = ws.Cells(i, 17).Value ' データ型
        If Not ws.Cells(i, 22).Value = "-" Then
            byteNum = "(" & ws.Cells(i, 22).Value & ")" 'バイト数
        Else
            byteNum = ""
        End If
        isPrimaryKey = (ws.Cells(i, 32).Value = "Yes")  ' PKフラグ
        isAutoIncrement = (ws.Cells(i, 37).Value = "AUTOINCREMENT")  ' AUTO_INCREMENTフラグ
        
        ' カラム定義をSQL文に追加
        sql = sql & "  " & colName & " " & colType & byteNum
        
        ' 主キーなら追加
        If isPrimaryKey Then
            sql = sql & " PRIMARY KEY"
        End If
        
        ' AUTO_INCREMENTがある場合は追加
        If isAutoIncrement Then
            sql = sql & " AUTO_INCREMENT"
        End If
        
        sql = sql & "," & vbCrLf
    Next i
    
    ' 最後のカンマを削除してSQLを閉じる
    sql = Left(sql, Len(sql) - 3) & vbCrLf & ");"
    
    ' SQL文をメッセージボックスで表示
    MsgBox sql
End Sub

```
JavaScriptでHTMLパース【DOMParser html】

```js
await fetch('').then(r=>r.text()).then(html=>new DOMParser().parseFromString(html,'text/html'))
```

例

```js
await fetch('https://example.com').then(r=>r.text()).then(html=>new DOMParser().parseFromString(html,'text/html'))
```

```js
const doc = await fetch('https://example.com').then(r=>r.text()).then(html=>new DOMParser().parseFromString(html,'text/html'))
console.log(doc.querySelector('a').href)
```

https://developer.mozilla.org/ja/docs/Web/API/DOMParser
【AWS】Amazon Bedrock Knowledge BasesでRAG実装


## RAGとは
　2020年に発表された「Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks」では、事前学習済みパラメトリックメモリ(事前学習済みLLM)に非パラメトリックメモリ(ナレッジ)を用いてfine-tuningを行い、特定知識への適用を行っていました。現代では、LLMが進化し、プロンプトへ知識を追加するだけである程度特定知識へのアクセスを実現するため、多くのRAGシステムでは高度な検索後の知識をプロンプトへ追加することで、ドメイン知識の回答を生成している。

https://arxiv.org/pdf/2005.11401

論文要旨の日本語訳
>私たちは、言語生成のための retrieval-augmented generation (RAG) - 事前学習済みパラメトリックメモリと非パラメトリックメモリを組み合わせたモデル - 向けの汎用的な fine-tuning の手法を探求しました。私たちは、パラメトリックメモリが事前学習済みseq2seqモデル、非パラメトリックメモリが事前学習済みニューラル retrieverでアクセスされるWikipediaの密ベクトルインデックスであるRAGモデルを導入しました。

## 現代RAGの一般的な流れ

1. ベクトルデータベースの構築
   チャンク分割とEmbeddingモデルによるエンコード
2. ユーザープロンプトの入力
   Embeddingモデルによるエンコード
3. ベクトルデータベースとの類似度計算
4. 高度な検索エンジンによるフィルタリング
5. 検索結果をプロンプトへ追加
   プロンプトエンジニアリングで参照知識を指定
6. 回答生成

![RAG流れ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/53698446-7feb-f1e7-51c8-41638042aee6.png)
https://arxiv.org/pdf/2312.10997v5

## Amazon Bedrock Knowledge BasesのRAG作成手順

![rag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/52676312-c262-fdfa-c3ee-3c0b131a1597.png)
https://aws.amazon.com/jp/blogs/news/knowledge-bases-for-amazon-bedrock-rag-patent/


1. Bedrockコンソール画面を開く
1. 左メニューのナレッジベースをクリックする
   ![RAG_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e68414ac-53ae-02bb-3561-5f5f2c7d7e7c.png)
1. ナレッジベースの詳細を入力する
   ![RAG_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/b513fb3b-db11-ec3c-98a0-2fd432b1c403.png)
1. データソースを選択する
   ![RAG_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/2e4e12ab-f831-891d-0bc5-138e387f652a.png)
   ![RAG_4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/61b3588d-2af5-d53f-64e3-08562150617a.png)
1. チャンク分け方法を選択する
   ![RAG_5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e66e0ce6-b0fd-d237-12af-be0f7488d4e7.png)
   ![RAG_7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/70c68cad-8da9-abab-4a85-87075c8b011e.png)
1. 画像やテーブル情報を読み取るため、LLMを使用するか選択する
   ![RAG_6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/63fafb05-8f7a-3146-ee51-4bceaa750c80.png)
1. 埋め込みモデルを選択する
   ![RAG_8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/0e4bca61-830e-82e4-02b2-ade5f98f2454.png)
1. ベクトルデータベースの設定を行う
   ![RAG_9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e258ba3c-3e28-6ca1-99a5-ea0fe2775334.png)

## 利用料金
個々のサービスでお金がかかる

 - Amazon Bedrock
   最上位Claude 3.5 Sonnetで、1000トークンあたり入力0.003ドル、出力0.015ドル
   月1000回プロンプトを入力するとだいたい数ドル程度
 - Amazon OpenSearch Serverless
   OpenSearch Compute Units (OCU)
   1 OCUで6GBのRAM、対応するvCPU、GP3ストレージ。
   1OCUで1時間あたり0.334ドル
   一か月あたり240ドル

## 参考文献
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2024_Amazon-Bedrock-Knowledge-Bases_0920_v1.pdf

https://aws.amazon.com/jp/blogs/news/knowledge-bases-for-amazon-bedrock-rag-patent/

https://arxiv.org/pdf/2005.11401

https://arxiv.org/pdf/2312.10997v5
AI Everywhere を実現するインテルのポートフォリオをご紹介！

【開発と活用を推進するインテルの AI】
インテルはクラウドからデータセンター、エッジにおいて、あらゆる場所での AI 活用を目指す、ソフトウェアやハードウェアでの AI 開発、さらには AI ソリューションへの活用を動画で解説するWebサイトを公開しています。

https://www.intel.co.jp/content/www/jp/ja/artificial-intelligence/ai-development-and-utilization.html

＜あらゆる場所で AI を活用する！＞
インテルは、クラウドからデータセンター、そしてエッジにいたるまで、あらゆる場所で AI を活用することを支援するために、ハードウェアとソフトウェア双方に渡り幅広いポートフォリオを提供しています。インテルがこの AI 時代をさらに加速させるための、さまざまなツール、開発環境やソリューションをどのように利用するのかをご紹介します。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/d916af7b-57a3-cffb-403b-93004e9c137d.png)


１：あらゆる場所で AI の活用を可能にする インテル® AI ポートフォリオ
本セッションではインテルの AI 製品群を紹介します。PC、エッジ・コンピューター、データセンター、クラウドにいたるまで、ユーザーの理想的なソリューション構築を支援するための幅広いハードウェアとソフトウェアの製品群を紹介します。

２：インテルの AI ソフトウェア製品ポートフォリオ
本セッションでは AI の開発を支えるソフトウェア群を紹介します。ユーザーが AI を活用したサービスやソリューションを構築するために役立つ幅広い開発環境とソフトウェアの製品群を紹介します。

https://www.intel.co.jp/content/www/jp/ja/artificial-intelligence/ai-development-and-utilization.html

是非この機会にAI Everywhere を実現するインテルのポートフォリオをご覧ください！
(ハンズオンで学ぶ)Git入門


## What is git ?
Gitとはソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システム（Wikipediaより）
https://ja.wikipedia.org/wiki/Git

## Terms
- Git : 上記バージョン管理システムのこと
- GitHub : Gitを共有しgit flowによる開発を可能にするウェブ
- repository : 管理するシステムの区分。ルートフォルダ。
- branch : リポジトリに対する変更を元のリポジトリから分岐させること。その操作を"branchを切る"という。
- ローカルリポジトリ : コンピュータ上でのみ存在するリポジトリ
- リモートリポジトリ : ネットワーク上に存在するリポジトリ

## Install
https://gitforwindows.org/ からGitForWindowsをダウンロードし, ウィザードに従ってインストールする
(インストール手順参考：https://qiita.com/T-H9703EnAc/items/4fbe6593d42f9a844b1c)



## Handson01 Way To Commit
    Let's try !
    ターミナルを開いて実践してみましょう

1. `git config --global user.name "任意のユーザー名"`, `git config --global user.email "メールアドレス"`を順次実行してgitの設定をする

2. 作業ディレクトリを作成する
（Windows:`mkdir`, Linux:`mkdir`）

3. カレントディレクトリを上で作成した作業ディレクトリまで移動し, `git init`を行う
(Windows:`dir`, Linux:`ls -a`で`.git`ファイルの存在を確認)


4. 必要に応じて, プロジェクト管理から外したいファイルを`.gitignore`ファイルを作成して追記する

5. GitHubにリポジトリを作成（ https://github.co.jp/ ）

6. `README.md`を作成し, コマンドラインで`git add README.md`を実行`git add`以降に指定したファイルをステージングへ追加

7. `git commit -m "first commit"`を実行してインデックスに追加したファイルをコミットする（変更を適用する）

8. `git remote add origin git@github.com:リポジトリ名.git`を実行してGitHub上のリモートリポジトリにadd

9. `git push -u origin main`を実行してリモートリポジトリにプッシュする（変更を上書きする）

10. GitHubのリポジトリを更新してREADME.mdが追加されていることを確認する

ここまででGitHubへのプッシュまでができるようになった！

### Supplement01
- `git add .`とすることで`.gitignore`にないファイルをすべてステージングできる
- `git status`でファイルのステータスを確認できる（ステージング等）
- **コミットの際には必ずコメントが必要**（内容は変更内容がわかるようなもの）
- `git commit --amend`でコミットメッセージを修正できる

## Handson02 Way to Merge
### Part1 Fetch And Merge(Update Local)

0. `README.md`に`README.mdに追記(fetch merge)`と追記し, Commit messageに`README.mdをリモートリポジトリから直接更新`と追記する
1. `git log --oneline`で現在のコミット履歴を確認する
2. `git fetch origin`でローカルブランチを更新する
3. `git log main..origin/main --oneline`でローカルブランチとリモートブランチの差分を確認する
4. `git merge origin/main`で作業ディレクトリを更新する
5. `git log --oneline`で現在のコミット履歴を確認
6. `README.md`の内容を確認

### Part2 Pull(Update Local)

0. `README.md`に`README.mdに追記(pull)`と追記し, Commit messageに`README.mdをリモートリポジトリから直接更新2`と追記する
1. `git log --oneline`で現在のコミット履歴を確認
2. `git pull origin main`でローカルリポジトリと作業ディレクトリを更新する（fetchとmergeをまとめて行える）
3. `git log --oneline`で現在の履歴を確認する
4. `README.md`の内容を確認

## Handson03 Way To Check Out Branch

1. `git branch`で現在のブランチを確認
2. `git checkout -b 新しいブランチ名`で新規ブランチを作成し, そのブランチに切り替える
3. `git branch`で再度現在のブランチを確認
4. `git push origin 作成したブランチ名`でリモートリポジトリにプッシュする
5. GitHubでブランチが新しく追加されているのを確認

## Handson04 Way To Pull Request Then Merge

0. 新しく作ったブランチの`README.md`を変更して`add`, `commit`, `push`まで行う（ここでは`main`ブランチは更新されていない）
1. GitHubの`Pull requests`から`New pull request`を選択. プルダウンから`base:main`, `compare:作成したブランチ名`を選択する
2. 変更内容を確認して`Create pull request`
3. `Add a title`と`Add a description`を入力し, `Create pull request`を選択
4. レビュアーがコードレビューを行い, 問題なければ`Merge pull request`を実施する（`Confirm Merge`で確認）
5. 変更内容が反映され, 対象のブランチは削除される

### Suppliment04
- base: マージ先(変更させたいブランチ)
- compare: マージ元(自分が変更したブランチ)
Flaskの環境構築から、Hello World出力まで【備忘録】

# 環境
+ Windows
+ Python 3.12.4
+ Flask 3.0.3

# ディレクトリ構成

```
flask_test/
  ├─ venv/
  └─ app.py
```

# 手順1 flaskインストールまで
※Pythonはインストール済みとする

仮想環境用ディレクトリ `test_project` を作成
作成したディレクトリに移動

```
mkdir test_project
cd test_project
```

仮想環境を作成（ `py -3 -m venv [フォルダ名]` ）

```
py -3 -m venv venv
```

仮想環境を有効化（ `[フォルダ名]\Scripts\activate` ）

```
venv\Scripts\activate
```
→ 先頭に `(env)` が付く

:::note
無効化するときは　`deactivate` と入力
:::

仮想環境の中にFlaskをインストール

```
pip install Flask
```

# 手順2 "Hello World"出力まで
## （任意）ワークスペース作成
vscode上で `名前を付けてワークスペースを保存` を選択
複数のフォルダを同時に開くことが可能
→フロントとバックを同時に見れる


## スクリプト作成
`test_project` フォルダの中に `app.py` を作成

```python:app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True)

```
実行する(cmd)

```
flask run --debugger --reload
```


:::note
`--debugger --reload` を付けないと、修正が直後に反映されない
:::
vbsの作法 その92

# 概要
vbsの作法、調べてみた。
練習問題やってみた。

# 練習問題
zundokoをIE11で表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b264b266-4c43-25b1-a78b-ac378283df6f.png)


# サンプルコード

```
Class ohicompo0
	Private objIE
	Private Sub Class_Initialize
		Set objIE = CreateObject("InternetExplorer.Application")
		objIE.Visible = true
		objIE.Top = 50
		objIE.Left = 100
		objIE.Width = 500
		objIE.Height = 400
		objIE.Navigate("about:blank")
		objIE.StatusBar = False
		objIE.ToolBar = 0
		objIE.Document.Write("<html><head><title>ohicompo0</title></head>")
		objIE.Document.Write("<body bgcolor='pink'>")
		objIE.Document.Write("<div id='div-id-1'></div><br>")
		objIE.Document.Write("<textarea id='out' rows='13' cols='40'></textarea>")
		objIE.Document.Write("</body></html>")
	End Sub
	Private Sub Class_Terminate
		'MsgBox "ウインドウオブジェクト 解放", vbOKOnly + vbInformation, "ウインドウオブジェクト インスタンス "
	End Sub
	Public Sub text(str)
		objIE.Document.getElementById("out").InnerText = str
	End Sub
	Public Sub owari()
		objIE.Quit
	End Sub
End Class

Dim str
str = ""
Dim zudo(1)
zudo(0) = "ズン" & vbcrlf
zudo(1) = "ドコ" & vbcrlf
Dim count
count = 0
Randomize
Do
	Dim i
	i = Int(Rnd * 2)
	str = str & zudo(i)
	If i = 0 Then
		If count <= 4 then
			count = count + 1
		End if
	Else
		If count >= 4 Then
			Exit Do
		Else
			count = 0
		End If
	End If
Loop
str = str & " キ・ヨ・シ！"

Dim w1
Set w1 = new ohicompo0
w1.text str







```

以上
Goでtime.Now()を使用している箇所のテストについて


## 概要


time.Now()を使用している箇所のテストがしづらいと感じたのでその際のメモ


結論：**contextにtime.Now()で生成する方法を採用**


## 既存のコード


```go
func Hoge() {
	todo := GetTodo()
	if IsTimeAfter(todo.StartTime) {
		...
	}
}

func IsTimeAfter(startTime time.Time) {
	currentDate := time.Now() // テストを実行する時刻に依存する。現在日時を固定にしたい。
	return startTime.After(currentDate)
}

```


## 対応方法


### time.Now()で生成した現在時刻を引数にする

- パッと修正可能
- IsTimeAfter()のテストはしやすくなったが、Hoge()がtime.Nowに依存している状態

```go
func Hoge() {
	todo := GetTodo()
	currentDate := time.Now()
	if IsTimeAfter(todo.StartTime, currentDate) {
		...
	}
}

func IsTimeAfter(startTime, currentDate time.Time) {
	return startTime.After(currentDate)
}

```


### time.Now()で現在時刻を生成する処理をmock化

- インターフェースを作成してテストの際はmockを使用する
- 現在時刻を生成するためだけにインターフェースを定義したり、依存性を注入するのは少し過剰か？

```go
type TimeProvider interface { // インターフェースを作成
    Now() time.Time
}

type RealTimeProvider struct{}

func (rtp RealTimeProvider) Now() time.Time { // 実装
    return time.Now()
}
```


```go
type SomeService struct {
    TimeProvider timeprovider.TimeProvider
}

func NewSomeService(tp timeprovider.TimeProvider) *SomeService {
    return &SomeService{TimeProvider: tp}
}

func (s *SomeService) Hoge() {
    currentDate := s.TimeProvider.Now() // テストの際はモックを使用する
		if IsTimeAfter(todo.StartTime, currentDate) {
				...
		}
}

func IsTimeAfter(startTime, currentDate time.Time) {
	return startTime.After(currentDate)
}
```


### middlewareでtime.Now()で現在時刻を生成してcontextに入れておく

- mock化より実装はシンプルになる

```go
// middleware(echoを使用)
func NewCurrentTime() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			n := time.Now()
			ctx := context.WithValue(c.Request().Context(), "current_time", n)
			c.SetRequest(c.Request().WithContext(ctx))
			return next(c)
		}
	}
}
```


```go
// route.go(echoを使用)
func SetupRouter() *echo.Echo {
	e := echo.New()
	e.Use(middleware.NewCurrentTime()) // ここで使用
	e.GET("/hoge", hogeHandler.Hoge)
	.
	.
```


```go
func (s *SomeService) Hoge(ctx context.Context) {
    currentDate := ctx.Value("current_time").(time.Time) // ここでcontextから取得
		if IsTimeAfter(todo.StartTime, currentDate) {
				...
		}
}

// 現在時刻を引数にしているが、関数内でcontextから時刻を取得してもよい。迷う。
func IsTimeAfter(startTime, currentDate time.Time) {
	return startTime.After(currentDate)
}
```


## 参考にした記事

- [https://qiita.com/tomtwinkle/items/4dee6ed4e81784c66cd2](https://qiita.com/tomtwinkle/items/4dee6ed4e81784c66cd2)
- [https://daisuzu.hatenablog.com/entry/2018/05/05/010510](https://daisuzu.hatenablog.com/entry/2018/05/05/010510)
- [https://scrapbox.io/tsuchinaga/現在の日時が絡む処理の単体テストを書いてみる@Golang](https://scrapbox.io/tsuchinaga/現在の日時が絡む処理の単体テストを書いてみる@Golang)
vbsの作法 その91

# 概要
vbsの作法、調べてみた。
練習問題やってみた。

# 練習問題
fizzbuzzをIE11で表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/abae8823-f04f-4df5-05c1-ea02e195c55c.png)


# サンプルコード

```
Class ohicompo0
	Private objIE
	Private Sub Class_Initialize
		Set objIE = CreateObject("InternetExplorer.Application")
		objIE.Visible = true
		objIE.Top = 50
		objIE.Left = 100
		objIE.Width = 500
		objIE.Height = 400
		objIE.Navigate("about:blank")
		objIE.StatusBar = False
		objIE.ToolBar = 0
		objIE.Document.Write("<html><head><title>ohicompo0</title></head>")
		objIE.Document.Write("<body bgcolor='pink'>")
		objIE.Document.Write("<div id='div-id-1'></div><br>")
		objIE.Document.Write("<textarea id='out' rows='13' cols='40'></textarea>")
		objIE.Document.Write("</body></html>")
	End Sub
	Private Sub Class_Terminate
		'MsgBox "ウインドウオブジェクト 解放", vbOKOnly + vbInformation, "ウインドウオブジェクト インスタンス "
	End Sub
	Public Sub text(str)
		objIE.Document.getElementById("out").InnerText = str
	End Sub
	Public Sub owari()
		objIE.Quit
	End Sub
End Class


Dim i
Dim str
str = ""
For i = 1 To 100
	If i Mod 15 = 0 Then
		str = str & "FizzBuzz "
	ElseIf i Mod 3 = 0 Then
		str = str &  "Fizz "
	ElseIf i Mod 5 = 0 Then
		str = str &  "Buzz "
	Else
		str = str & CStr(i) & " "
	End If
Next
Dim w1
Set w1 = new ohicompo0
w1.text str







```

以上
Gauge×Playwrightのts.properties設定活用法

# はじめに
今回は、私が日々のE2Eテストで活用している ts.properties ファイルの使い方についてご紹介します。特に、GaugeとPlaywrightを使ったテストで環境ごとの設定をどのように管理しているか、実際のプロジェクト構成を基に解説します。

# なぜts.propertiesが必要なのか？
E2Eテストを行う際、異なる環境や設定を使い分けることがよくあります。たとえば、開発用のローカル環境やステージング、CI（継続的インテグレーション）、本番環境などです。それぞれで異なるURLやユーザー情報を使用したい場合、設定ファイルを一元管理することが重要です。

ts.properties は、こうした設定をまとめて管理できる便利なファイルです。テストコードを変更することなく、環境設定やユーザー情報を柔軟に切り替えられるようになります。

# ts.properties を使った環境ごとの設定構成
まず、ts.properties の中身をご紹介します。
弊社では、以下のように環境ごとに ts.properties を分けて管理しています。
```
env
├── ci
│   └── ts.properties
├── default
│   ├── default.properties
│   └── ts.properties
├── local
│   └── ts.properties
├── prd
│   └── ts.properties
└── stg
    └── ts.properties
```
このように環境ごとにディレクトリを作成し、それぞれの ts.properties ファイルに対応する設定を記述しています。これにより、テスト実行時に特定の環境の設定を簡単に切り替えられます。

# 各ts.propertiesの役割と内容
例えば、env/ci/ts.properties には、CI環境でのテスト実行に必要な設定を記述します。
```ts.properties
PLAYWRIGHT_HEADLESS=true
PLAYWRIGHT_SLOW_MO=0

HITOTSU_ASSET_URL=https://ci-xxxx
HITOTSU_LINK_URL=https://ci-yyyy

USER_NAME_ADMIN=ci_admin
USER_PASSWORD=ci_password
```
一方、ローカル開発用の env/local/ts.properties は、デバッグしやすいようにPlaywrightをヘッドフルモード（ブラウザを表示するモード）で実行する設定にしています。
```ts.properties
PLAYWRIGHT_HEADLESS=false
PLAYWRIGHT_SLOW_MO=500

HITOTSU_ASSET_URL=http://localhost:3000
HITOTSU_LINK_URL=http://localhost:3001

USER_NAME_HP_ADMIN=local_admin
USER_PASSWORD=local_password
```
このように設定ファイルを環境ごとに用意しておくことで、テスト実行時に簡単に設定を切り替えることができます。テストの対象環境に応じて env フォルダ内の適切な ts.properties を参照するように設定するだけです。

# 具体的な活用例
例えば、ローカル環境でテストを実行したい場合、以下のようにコマンドを実行します。
```
gauge run --env local specs/1_login.spec
```
このコマンドを実行することで、env/local/ts.properties が読み込まれ、ローカル環境用の設定でテストが実行されます。同様に、CI環境や他の環境でテストを実行したい場合は、--env オプションを使って環境を指定することで、対応する ts.properties が適用されます。

# まとめ
ts.properties を環境ごとに管理することで、GaugeとPlaywrightによるE2Eテストの柔軟性と保守性が大幅に向上します。設定を分けることで、テストの実行環境に合わせた最適な設定が可能になり、効率的なテスト運用が実現できます。ぜひ、皆さんのプロジェクトにも取り入れてみてください！！
Djangoでログアウト機能を実装できない場合のエラー解消法

## 発生していた問題・エラー
ログアウトをしようとした時に、HTTP 405エラー「Method Not Allowed」（許可されていないメソッド）が発生している

![ログアウト機能失敗.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677649/82168d28-b663-117c-047d-70f3fa43e8a8.gif)


## エラーの原因・解決方法
- 多くのWebアプリケーションでは、ログアウトの操作はセキュリティ上の理由から、GETではなくPOSTリクエストを使用して行われるらしいです
- ログアウトを行う際には、フォームを使ってPOSTメソッドでリクエストを送信するようにリンクを変更する必要があります


```html:layout.html
<nav class="navbar navbar-expand-sm navbar-dark fixed-top">
  <div class="container">
    <a class="navbar-brand" href="{% url 'gourmet_guide:index' %}">おすすめご飯やさん</a>
    <ul class="navbar-nav">
      {% if user.is_authenticated %}
      <li class="nav-time">
        <span class="navbar-text">{{ user }} - </span>
      </li>
      <li class="nav-item">
        {% comment %} 
        <a href='{% url "logout" %}' class="logout nav-link">Logout</a> 
        {% endcomment %}
        <!-- POSTリクエストに変更 -->
        <form method="POST" action="{% url 'logout' %}">
          {% csrf_token %}
          <button type="submit" class="logout nav-link btn btn-link" style="display:inline; padding: 0;">Logout</button>
        </form>
      </li>
      {% else %}
      <li class="nav-item">
        <a href="{% url 'login' %}" class="login nav-link">Login</a>
      </li>
      {% endif %}
    </ul>
  </div>
</nav>
```
無事、ログアウト機能が使えるようになりました。

![ログアウト機能成功.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677649/39e6173e-a1cd-15e5-b2d5-9aa2a6fd8f07.gif)


## 参考記事

https://qiita.com/guabanapple/items/c8062a138acbbb5896de

https://terakoya.sejuku.net/question/detail/33882
MediaPipeでAndroid端末上でLLMを動かすメモ


[A walkthrough for Android’s on-device GenAI solutions | Spotlight Week](https://www.youtube.com/watch?v=EpKghZYqVW4)


を見ていて途中で出てきたので、まとめておきます。
adb pushが必要なところ以外は簡単でした。

基本は以下のとおりです。

https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference/android

# 事前準備

## リポジトリチェックアウト

(これでモノレポで管理するときに便利な `sparse-checkout` というものを知りました。 ) 

```
git clone https://github.com/google-ai-edge/mediapipe-samples
cd mediapipe
git sparse-checkout init --cone
git sparse-checkout set examples/llm_inference/android
```

## モデルのダウンロード

この中で必要なものを一つ選んでダウンロードする。サービスへの登録が必要でした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/962d3164-77c6-5426-e0d3-4397320b91cb.png)

https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference/android より

ここではGoogleのオープンソースモデル、gemma2-2b-it-gpu-int8.binをダウンロードして利用しました。Gemma以外を利用する場合は、MediaPipeと互換性があるフォーマットに変換が必要になるようです。

## モデルを端末にpushする。

端末にモデルをpushする。apk内に保存できないか試みたがモデルが2GBを超えていて、apkのビルド中に失敗するので断念した。
(Android SDK内にあるadbとAndroidの開発者モードとUSBデバッグの許可が必要)

```shell
$ adb shell rm -r /data/local/tmp/llm/ # Remove any previously loaded models
$ adb shell mkdir -p /data/local/tmp/llm/
$ adb push output_path /data/local/tmp/llm/model_version.bin
```

## Android Studioから開いて起動する。

examples/llm_inference/android をAndroid Studioから開く。


コードをいじらず簡単にいけました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/bc94469c-3d1d-6737-ce54-a25fbcfb4b0d.png" width=300 />

他にもLoRAを使ってカスタマイズなどができるようですが、ここでは説明しません。
３つの立方数の和で42　巨大数の計算

３つの立方数の和で42になる答えの検算。

(-80538738812075974)^3
+80435758145817515^3
+12602123297335631^3
=42


# googleの検索窓の電卓ではダメ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/fe07704c-d659-5c31-e713-3c86a6066b04.png)


# wolframAlphaはOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/884f2a37-c6b7-c45b-df4d-1e2e1bc324b1.png)



# ProcessingでjavaのBigInteger使ってOK
```java:Processing
import java.math.BigInteger;

BigInteger x = new BigInteger("-80538738812075974");
BigInteger y = new BigInteger("80435758145817515");
BigInteger z = new BigInteger("12602123297335631");

BigInteger ans1 = x.multiply(x).multiply(x);
BigInteger ans2 = y.multiply(y).multiply(y);
BigInteger ans3 = z.multiply(z).multiply(z);
BigInteger ans = ans1.add(ans2).add(ans3);
print(ans);
```

```
42
```

# 参考

2019年
「Charity Engine」利用
50万台のPC
100万時間の計算時間
にて発見

https://fabcross.jp/news/2019/20191009_charity-engine.html
devcontainer内でホストのSSH鍵を使ってgitを使うときにハマったメモ

# 前置き
https://code.visualstudio.com/remote/advancedcontainers/sharing-git-credentials

上記の資料を参考に、devcontainerを使う時にホスト側のgitの認証情報を使って操作できる環境を構築していたのですが、自分の環境をいろいろ汚しすぎていて予想外のところでたくさんハマったので参考になればと思い残しておきます。


# 結論
- 複数のGithubアカウントでsshするのをやめる
- 公開鍵はパスフレーズのない公開鍵を作る
- user.nameとuser.emailはglobalで変えておく


# 環境
windows + wsl2(ubuntu 22.04LTS) + docker desktop

# 複数のGithubアカウントでsshするのをやめる
https://qiita.com/yampy/items/24638156abd383e08758

~/.ssh/configを使って複数のgithubアカウントを使い分ける設定をしていました。

git cloneする時は`git@github.com.private:...`のようにURLを書き換えることによって使い分けるのですが、どうやらdevcontainerは`~/.ssh/config`ファイルの中身まで見ていないらしく、cloneする時のURLを変えてもdevcontainer内でsshの情報がないとエラーが出ていました。
おとなしくconfigファイルのHost名を`github`にしたらdevcontainerで認識されました！

# 公開鍵はパスフレーズのない公開鍵を作る
https://code.visualstudio.com/docs/devcontainers/containers#_known-limitations

> If you clone a Git repository using SSH and your SSH key has a passphrase, VS Code's pull and sync features may hang when running remotely. Either use an SSH key without a passphrase, clone using HTTPS, or run git push from the command line to work around the issue.

公開鍵をパスフレーズ付きで作成して登録していたのですが、上記資料によるとSSHキーにパスフレーズが含まれている場合ハングする可能性があるとのこと。
パスフレーズなしのキーを再作成することでSSH接続確認ができるようになりました！

# user.nameとuser.emailはglobalで変えておく
devcontainerはホストのgit globalのuser情報を取得するらしく、違うユーザー名でコミットされているということがありました。思わぬところでユーザーが変わっている可能性があるので気を付けたいですねー
`git config --local user.name`でも良さそうですが、最初の資料でもglobalでと書いてありましたし、おとなしく手順書に従っておくのが良さそうです

# 感想
devcontainer便利ですよね！ただ、一度ハマるとかなり時間を食ってしまうところがネック...
今回の設定を踏まえて、複数のgithubアカウントを切り替えてdevcontainer使うときはSSH公開鍵認証よりもHTTPS認証の方が良いかもしれないと思いました
この記事がどなたかの問題解決の参考になればと思います！
ご一読いただきありがとうございました！
HPE MSA,DELL PowerVaultパラメータ取得一覧

MSAもPowerVaultも中身は同じ。
GUIをみるかぎり同じレイアウト、共通のコマンドが使用できる。
（当然一部出力結果は異なるものもある。）


!パラメータ確認試験したいとき
!一括表示のおまじない
set cli-parameters pager disabled
!-- ハードウェア ---------------------------------------------------------
! エンクロージャ情報
show system
! コントローラ情報
show controllers
! コントローラバージョン
show versions
!ディスク一覧
show disks
!-- プロビジョニング設定 -----------------------------------------------
! ボリューム
show volumes
show volumes detail
!ホストグループ
show host-groups
!イニシエータ
show initiators
!マッピング
show maps
!-- ネットワーク設定 --------------------------------------------------
! ネットワーク
show network-parameters
! DNS
show dns-parameters
! ホスト名
show dns-management-hostname
!管理サービス
show protocols
!証明書
show certificates
!プロキシサーバ
! プロキシの設定
! Proxy State
! プロキシホスト
! Host
! プロキシポート
! Port
! プロキシユーザ
! User
show proxy-server
!-- ユーザ設定 --------------------------------------------------------
! ユーザ名
show users
! ユーザグループ
show user-groups
! LDAP
show ldap-parameters
!-- システム設定 -------------------------------------------------------! システム識別情報
show system
! NTPサーバ
 show ntp
! タイムゾーン
show controller-date
! フルディスク暗号化
 show fde-state
! 同期キャッシュモード
! Sync Cache Mode,
! LUN応答の消失
! Missing LUN Response,
! ライトバックキャッシュのホスト制御
! Host Control of Caching,
! コントローラーの障害
! Controller Failure,
! キャッシュ電源
! Supercap Failure
! 電源障害
! Power Supply Failure,
! 冷却ファンの障害
! Fan Failure
! 過熱障害
! Temperature Exceeded
! トリガー条件クリア時の復元
! Auto Stall Recovery
! コントローラーへの通知
! Partner Notify
! SMART設定
! SMART
! EMPポーリングレート（秒）
! Enclosure Polling Rate
! 動的スペア機能
! Dynamic Spare Configuration
! ディスクスピンダウン
! Inactive Drive Spin Down
! ディスクスピンダウンディレイ（分）
! Inactive Drive Spin Down Delay
! ディスクグループのスクラブ
! Disk Group Background Scrub,
! ディスクグループスクラブスケジュール
! Scrub Schedule
! 管理ログ
! Managed Logs
! パートナーファームウェアの更新
! Partner Firmware Upgrade
show advanced-settings
! 管理ログの送信先電子メール
! Log Destination
! 管理ログを含める
! Include Logs
show email-parameters
!-- 通知設定 ---------------------------------------------------------
! メール
show email-parameters
! SNMP
show snmp-parameters
! syslog
show syslog-parameters
!-- iSCSI設定 --------------------------------------------------------
! iSCSI ポート
show ports
! chap認証
show chap-records
! iscsi 設定
show iscsi
!-- ストレージ設定 ----------------------------------------------------
! ディスクグループ
show disk-groups
show disk-groups detail
! プール
show pools
! スペアディスク
show disks usage spares
!-- その他設定---------------------------------------------------------
! 更新サーバ
show update-server
! ライセンス
show license
!-- extra ---------------------------------------------------------
show configuration
show metrics-list
App RunnerからCognitoへ接続時にタイムアウトエラーが発生

# App RunnerからCognitoへ接続する際にタイムアウトが発生し少し時間がかかってしまったので整理

# 前提
- App Runnerの構築とCognitoのユーザープールおよびIDトークンを用いた検証の実装などは済んでいる状態
- App RunnerはVPC Connectorを利用してVPC内のリソースに接続している
App RunnerのVPC Connectorなど参考になる記事
https://dev.classmethod.jp/articles/introduction-2024-aws-app-runner/

#  つまずいたところ
#### App RunnerからCognitoのリクエストでタイムアウト

#### 原因：ネットワーク

- App Runnerはデフォルトではインターネット経由で外部にアクセス
- ただし、VPC Connectorを利用すると、VPCネットワークに接続してプライベートにアクセスになる
- CognitoはVPCの外にあるので、VPC Connecotr利用する場合App Runnerから接続できない状態になっていた。

#### 対応：NatGatewayを設置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52335/60d6ec82-76ce-9af0-24d7-e2f5b9dedfa4.png)




terraformで管理している場合は以下のようなリソースを追加すればOK

```terraform:main.tf
/* ===================================
// NAT Gateway
// =================================== */

// public subnet
 resource "aws_subnet" "app_public_subnet1" {
   vpc_id            = aws_vpc.app_vpc.id
   cidr_block        = "172.16.10.0/24"
   availability_zone = "ap-northeast-1a"

     tags = {
     Name = "app_public_subnet1"
   }
 }

 resource "aws_internet_gateway" "app_igw" {
   vpc_id = aws_vpc.app_vpc.id
 }

// ルートテーブル for NAT Gateway
 resource "aws_route_table" "app_public_route_table" {
   vpc_id = aws_vpc.app_vpc.id
   route {
     cidr_block = "0.0.0.0/0"
     gateway_id = aws_internet_gateway.app_igw.id
   }
 }

// ルートテーブルに紐づくサブネット
 resource "aws_route_table_association" "public_route_table_association" {
   subnet_id      = aws_subnet.app_public_subnet1.id
   route_table_id = aws_route_table.app_public_route_table.id
 }

// EIP
 resource "aws_eip" "nat_eip" {
   domain = "vpc"
 }

 resource "aws_nat_gateway" "nat_gateway" {
   allocation_id = aws_eip.nat_eip.id
   subnet_id     = aws_subnet.app_public_subnet1.id
 }



 //ルートテーブルfor private subnet
 resource "aws_route_table" "app_private_route_table" {
  vpc_id = aws_vpc.app_vpc.id

  // すべての外部トラフィックをNAT Gatewayにルーティング
  route {
     cidr_block = "0.0.0.0/0"
     nat_gateway_id = aws_nat_gateway.nat_gateway.id
  }
}

// apprunner sgのセキュリティグループ 
resource "aws_security_group" "app_runner_sg" {
  name        = var.app_runner_sg_name
  vpc_id      = var.vpc_id
  description = "Security group for App Runner"

  # Outboundルール: HTTPS (443)
  egress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # NAT Gateway へのアクセスは0.0.0.0/0を使用します
  }
}

 ```

これでネットワークの問題は解決するはずです！

### 関連
上記を解決したもののCognitoへの接続時に509エラーになったのでそれについては以下に書いています。
https://qiita.com/yukiyoshimura/items/0b6e31b117853049c228
Debian12のflet環境でハマったこと

# Debian12の環境でFletをインストールしてハマったことのメモ
Debian12からpythonを使う際、venv環境が矯正される。
なのでvenv環境に移行した後Fletをインストールするために
```bash
pip install flet
```
でインストールする。
テストプログラムを書いて実行する
```flt01.py
import flet as flt

def main(page: flt.Page):
    tx1=flt.Text("Test")
    page.controls.append(tx1)
    page.update()

flt.app(target=main)
```
すると・・・
libmpv.so.1がないと怒られる。

# 対処方法
debian12ではsudoの設定がされていないので
su -
でルートユーザーに移行する
apt update
でとりあえずリポジトリを更新して
apt install libmpv-dev
をインストールする。
で実行しても同じエラーが出る・・・
なんでや

# 原因は・・・
debian12のlibmpv-devパッケージではlibmpv.so.2がインストールされるのが原因でした。
なので・・・
ルート権限で
```bash
cd /lib/x86_64-linux-gnu
ln -s libmpv.so.2.0.0 libmpv.so.1
```
というふうにシンボリックリンクを加えると動作します。
RSpecでのモックの使い方

# はじめに

こんにちは！
社会人一年目の石川です。
記事をご覧いただきありがとうございます。

本記事では、RSpecでのモックの使い方についてまとめます。

# 目次
1. [モックとスタブについて](#モックとスタブについて)
1. [モックを使う目的](#モックを使う目的)
1. [スタブを使う目的](#スタブを使う目的)
4. [モックとスタブの書き方](#モックとスタブの書き方)
4. [最後に](#最後に)


# モックとスタブについて
外部に依存する部分をテスト時に仮のオブジェクトで置き換える手法のことです。例えば外部のAPIを使うシステムのテストをするとき、モックやスタブを使わずにテストをすると、APIが正常に動いていない場合、テストが通らなくなってしまいます。つまり APIサービスが落ちていたり、エラーになっている時にはテストを実行しても失敗してしまいます。その他にも、ネットワークの遅延や、レスポンスが変動することで、テストが不安定になります。本来確認したい内容は、APIの状況ではなく、自分が作ったプログラムが正しく動いているかなので、このような状況で、APIをモックやスタブで置き換えることにより、外部の状況に左右されず、作ったシステムが正しく動いているか確かめることができます。



# モックを使う目的
モックの目的は、「メソッドが正しい引数で呼ばれたか」「呼び出しの回数」などの振る舞いを検証することです。

例えば、外部の API が正しく呼び出されたか、指定した引数で実行されたかを確認したい場合にモックを使用します。
外部 API やメール送信など、実際の処理を行わず、呼び出しだけをテストしたい場合に便利です。


# スタブを使う目的
スタブの目的は、「外部依存の応答を仮定し、プログラムのロジックをテストする」ことです。
API などの外部サービスに依存する処理があっても、スタブを使えばその部分を固定の返り値に置き換えてテストを進められます。

:::note info
 モックとスタブの違いと使い分け
- **モック(Mock)**
  → メソッドが正しく呼ばれたか（引数・回数も含めて）を検証する。


- **スタブ(Stub)：**
→ 特定の値を返すように置き換えて、プログラムのロジックをテストする。
:::



# モックとスタブの書き方
#### モックの書き方

```ruby
expect(オブジェクト).to receive(:メソッド).with(引数).and_return(返り値)
```

#### スタブの書き方
```ruby
allow(オブジェクト).to receive(:メソッド).and_return(返り値)
```
# 最後に
最後まで読んでいただきありがとうございました。
RSpecでモックやスタブを使用することで、外部依存を取り除いた効率的なテストが可能になります。
この記事を読んでモックの基本的な使い方や具体例について理解が深まれば幸いです。
【Flutter x Firebase Auth】電話番号認証時にFlutterアプリ(iOS)がクラッシュする

# 環境

- Flutter: `3.24.3`
- Dart: `3.5.3`
- firebase_core: `3.6.0`
- firebase_auth: `5.3.1`
- Xcode: `16.0`

# エラーの内容

電話番号認証を行おうとすると Flutter アプリがクラッシュした。
デバッグコンソールには以下のエラーメッセージが出力されていた。

```zsh
Launching lib/main.dart on iPhone 16 Pro in debug mode...
Xcode build done.                                           23.5s
...略...
FirebaseAuth/PhoneAuthProvider.swift:484: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Lost connection to device.

Exited.
```

# 解決策

[こちら](https://github.com/firebase/flutterfire/issues/13471)を参考に、以下を `ios/Runner/Info.plist` に追記することで解決しました


```
<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleTypeRole</key>
		<string>Editor</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>ここにREVERSED_CLIENT_IDを入力する</string>
		</array>
    </dict>
</array>
```
新人に指摘したことのログ

新人に指摘したことを記録する。順次更新。
コミュ力なくていいので、単語を正確に発話してほしい。

# 報告・連絡・相談

## 用語

- 知らない単語は必ず調べること
- 英単語の発音はすぐに確認できる。調べること
- 固有名詞は正しく発音する。勝手に省略しないこと
- 似たようなタスクを勝手にひとまとめにして別の名前をつけない。その名前で報告しない
- 独自用語で説明しても伝わらない

## 文章

- 報告する前に伝えることを整理しておくこと
    - 「何が」「どうなる」のかを考えましょう
- 事象を正確に説明すること
- 主語・述語をあいまいにしないこと

## 資料作成

- 一通り作ったら、内容に問題がないかほかの人に見てもらうこと
- 一度提出した資料は、思った以上に様々な人が目を通す。誤解を生みやすい表現は控えること

## パワポ

- 事前に読む練習をすること
- カンペつくること
- 発表は時間内に収めること

## 作業内容確認時

- メモをとること
- 会話の最後に自分がこの後する作業を言うこと。こうすると相手に自分の理解度を確認してもらえる

# プログラミング

## 心構え

- 指示以上の変更を勝手に入れてはいけない。指示以上の変更は、客先と合意していない変更である。プログラマ視点ではいい改修でも、他の作業者（プログラマの前に現れないプロジェクト関係者はたくさんいる）にとっては問題かもしれない
- 規模の大きいリファクタリングは、プログラミング言語に習熟し対象システムの仕様を正確に把握出来るようになってから試みること。想像以上にシステムは複雑です

## 作業中

- 設計書を読むこと
- 理解できなければ、図にして書き出してみるといい

## レビュー

- （開発が一通り完了し、開発内容全般のチェックを依頼する場合）不要なコメントやソースコードは削除しておくこと。レビュー時に、動く成果物を目視確認できるのが望ましい

# Git

- pushするときは、自分がpushしようとしているブランチをよく確認すること。一度pushすると、他開発者がその変更を利用できる。事情を知らない人が不適切な更新を元に、新しい改修を入れてしまうかもしれない。混乱の元なので、push時は特によく確認すること

# テスト

- 良い開発者は、必要十分なテストを作成出来る。適切なテスト項目を考えられるようになるといい

# 眠くなったら

- ほぼすべての職場でいい顔されない。起きろ
- 眠くなったら[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/)あたりを読んでおけばいいんじゃないか
- qiitaは玉石混交だし、煽ってくるのでおすすめしない。真に受けないこと
使用しているポートを確認してkillする

# 使用しているポートを確認してkillする
※備忘録

lsofを使います。lsofとは"list open files"の略。

ポート番号を指定して実行中のプロセスを確認する
```shell
lsof -i:8080
```

実行結果は下記の情報が返ってくる
```shell
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
```


プロセス番号のみ取得したい場合は下記のコマンドを実行
```shell
lsof -ti:8080
```

取得したプロセス番号をkillする
```shell
kill [プロセス番号]
```
複数の設定がある場合のエラー


+ [Trailheadの検証チェッカーの情報を整理します](https://qiita.com/Keiji_otsubo/items/d34d73ccac77fadc11f8)


:::note alert
Step not yet complete There was an unhandled exception. Please reference ID: QUHIDFJQ. Error: Faraday::ClientError. Message: MALFORMED_QUERY: When retrieving results with Metadata or FullName fields, the query qualificatio​ns must specify no more than one row for retrieval. Result size: 4
:::

上記に似ているけどメッセージは違う

:::note alert
There was an unexpected error in your org which is preventing this assessment check from completing: System.QueryException: List has no rows for assignment to SObject
:::

# Use Sharing Rules for External Users trailhead project (Share CRM Data with Your Partners)

+ [Issue with Use Sharing Rules for External Users trailhead project (Share CRM Data with Your Partners)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eq2MjSAI)

:::note
Thanks for provided the org access. I have reviewed the issue in your org and found that there are 2 user records created with the name Sean Forbes.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/62355a57-2d48-1152-7240-64907e74f197.png)

I have renamed the inactive user first and last name and now the challenge check is working as expected.

組織へのアクセスを提供していただきありがとうございます。組織の問題を確認したところ、Sean Forbes という名前のユーザー レコードが 2 つ作成されていることがわかりました。

非アクティブなユーザーの姓名を変更したところ、チャレンジ チェックが期待どおりに動作するようになりました。
:::
【Winter 25】Quick Start: Explore the Coral Cloud Sample App

+ [Winter 25 トレイルヘッドのエラーに戻る](https://qiita.com/Keiji_otsubo/items/bdb9b4070eb04d8d12c6)

----------------

https://trailhead.salesforce.com/content/learn/projects/quick-start-explore-the-coral-cloud-sample-app

+ [How to advance past Coral Cloud metadata deploy errors/ fail?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007igJMvSAM)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/78c8382e-271d-1154-1fe9-d383a499a0f9.png)

以下も同じみたい

+ [Quick Start: Explore the Coral Cloud Sample App](https://qiita.com/Keiji_otsubo/items/b7e9bb332033d6e7ccb5)
Git でリモートリポジトリに SSH 接続する際に任意の秘密鍵を指定する

## やりたいこと

Git でリモートリポジトリに SSH 接続する際、デフォルトの秘密鍵 (`~/.ssh/id_rsa` や `~/.ssh/id_ed25519` など) ではなく任意の秘密鍵を指定したい。

## 方法

`core.sshCommand` を設定する。以下の例の `~/.ssh/id_ed25519.quanon` を実際に指定したい秘密鍵のパスに置き換えること。

```shell-session
$ git ls-remote origin # リモートリポジトリにアクセスできない。
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

$ git config --add --local core.sshCommand 'ssh -i ~/.ssh/id_ed25519.quanon'

$ git ls-remote origin # リモートリポジトリにアクセスできた！
694cd4a3eda71d53c4e2defe202eea345b0bbf40	HEAD
694cd4a3eda71d53c4e2defe202eea345b0bbf40	refs/heads/main
```

なおこの `core.sshCommand` の設定を削除したい場合は以下を実行する。

```shell-session
$ git config --unset --local core.sshCommand
```

## 参考

- [Git - git-config Documentation](https://git-scm.com/docs/git-config)
[Rails] belongs_toの関連付け

# Rails の belongs_to 関連付け：詳細解説

## はじめに

Ruby on Rails の `belongs_to` 関連付けは、モデル間の関係を定義する上で非常に重要な役割を果たします。この記事では、`belongs_to` 関連付けの詳細について解説していきます。

## belongs_to 関連付けとは？

`belongs_to` 関連付けは、「このモデルは別のモデルに属している」という関係を表します。データベースの観点から見ると、この関連付けは「このモデルのテーブルに、別のテーブルを参照するためのカラムが含まれている」ことを意味します。

### 具体例：

```ruby
class Book < ApplicationRecord
  belongs_to :author
end

class Author < ApplicationRecord
  has_many :books
end
```

この例では、`Book` モデルが `Author` モデルに属しています。つまり、`books` テーブルには `author_id` というカラムが存在し、これが `authors` テーブルの `id` を参照しています。

## belongs_to 関連付けで追加されるメソッド

`belongs_to` 関連付けを宣言すると、以下の 9 つのメソッドが自動的に利用できるようになります。ここでは、`Book` モデルが `Author` モデルに属している例で説明します。

1. `association` (例: `book.author`)
   - 関連付けられたオブジェクトを返します。関連付けられたオブジェクトがない場合は `nil` を返します。

2. `association=(associate)` (例: `book.author = an_author`)
   - 関連付けられたオブジェクトを割り当てます。これは内部で外部キーを更新します。

3. `build_association(attributes = {})` (例: `book.build_author(name: "Leo Tolstoy")`)
   - 関連付けられた型の新しいオブジェクトを作成します。これは保存されません。

4. `create_association(attributes = {})` (例: `book.create_author(name: "Jane Austen")`)
   - 関連付けられた型の新しいオブジェクトを作成し、保存します。

5. `create_association!(attributes = {})` (例: `book.create_author!(name: "Charles Dickens")`)
   - `create_association` と同じですが、保存に失敗した場合に例外を発生させます。

6. `reload_association` (例: `book.reload_author`)
   - キャッシュされている関連付けられたオブジェクトを再読み込みします。

7. `reset_association` (例: `book.reset_author`)
   - キャッシュされている関連付けられたオブジェクトをクリアします。

8. `association_changed?` (例: `book.author_changed?`)
   - 関連付けられたオブジェクトが変更されたかどうかを確認します。

9. `association_previously_changed?` (例: `book.author_previously_changed?`)
   - 関連付けられたオブジェクトが前回の保存操作で変更されたかどうかを確認します。

## belongs_to の使い方と注意点

1. **外部キー**：
   `belongs_to` を使用する場合、デフォルトでは `{関連名}_id` という名前の外部キーを探します。例えば、`belongs_to :author` の場合、`author_id` という外部キーを探します。

   ```ruby
   class Book < ApplicationRecord
     belongs_to :author
     # books テーブルに author_id カラムが必要
   end
   ```

2. **オプション**：
   `belongs_to` にはさまざまなオプションを指定できます。よく使われるものをいくつか紹介します。

   - `optional: true`：関連付けを任意にします（Rails 5以降ではデフォルトで必須）。
   ```ruby
   belongs_to :author, optional: true
   ```

   - `class_name`：関連付けるモデルクラス名を指定します。
   ```ruby
   belongs_to :writer, class_name: "Author"
   ```

   - `foreign_key`：使用する外部キーの名前を指定します。
   ```ruby
   belongs_to :author, foreign_key: "writer_id"
   ```

3. **バリデーション**：
   Rails 5以降、`belongs_to` 関連付けはデフォルトで存在性のバリデーションを行います。これを無効にするには `optional: true` を使用します。

4. **ポリモーフィック関連付け**：
   1つの `belongs_to` 関連付けで複数のモデルと関連付けることができます。

   ```ruby
   class Comment < ApplicationRecord
     belongs_to :commentable, polymorphic: true
   end

   class Article < ApplicationRecord
     has_many :comments, as: :commentable
   end

   class Photo < ApplicationRecord
     has_many :comments, as: :commentable
   end
   ```

## まとめ

`belongs_to` 関連付けは、Rails アプリケーションでモデル間の関係を定義する上で非常に重要です。この関連付けを使いこなすことで、より柔軟で保守性の高いコードを書くことができます。

## 参考
https://railsguides.jp/association_basics.html#has-one%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0%E3%81%AA%E5%8F%82%E7%85%A7
【TypeScript】Interface と type どちらが良いの ? 違いは ?

## はじめに
以前、初めてTypeScriptを実務で使用した際に、Interface(インターフェース)とtype(型エイリアス)
どちらを使うべきか迷うことがあったので、知見を今更ながらまとめます。

>Because an interface more closely maps how JavaScript objects work by being open to extension, we recommend using an interface over a type alias when possible.
ref:https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases

公式ドキュメントに**インターフェース（interface）** が推奨されています。

理由は、インターフェースがJavaScriptオブジェクトの動作により近いからです。具体的には、インターフェースは拡張可能であり、同じ名前のインターフェースを複数回宣言しても、それらがマージされます。

ただ、これだけだいまいちピンと来ないと思うので次の章でサンプルコードを出していきます。

## Interface と type の違いについて
拡張性について、インターフェースは拡張可能であり、同じ名前のインターフェースを複数回宣言しても、それらがマージされます。
サンプルコードを書いていきましょう。

### 同名のものを宣言
**interface** 

```typescript
interface Cat  {
  name: string
}

interface Cat {
  age: number
}
```

上記のコードは問題なく動作します。実質的には以下と同じです。
```typescript
interface Cat {
  name: string
  age: number
}
```

さあ、typeはどうでしょうか。 このような拡張は使用できません。

**type**

```typescript
type Cat = { // 識別子 'Cat' が重複しています。
  name: string
}

type Cat = { // 識別子 'Cat' が重複しています。
  age: number
}
```

**継承**
原則、インターフェースは継承できますが、型エイリアスは継承できません。

**interface**

```typescript
interface Animal {
  name: string
}

interface Cat extends Animal {
  age: number
}
```

上記のように定義することによって、
```typescript
interface Cat {
  name: string
  age: number
}
```
と同じ意味になります。


型エイリアスでは継承は行えませんが、`&`演算子を使用することで、複数の型を結合することができます。

**type**

```typescript
type Animal = {
  name: string
}

type Cat = Animal & {
  age: number
}
```

継承もそうですし、マージできない問題についても、上記のように型エイリアスを使用することで解決自体はできそうです。

## おわりに
正直いって、`Interface` でやりたいことは`type`で出来ることが多いですし、どちらを使っても問題ないと思います。
プロジェクトの方針、チームの方針に合わせて使い分けるのが良いと思います。

オブジェクト指向 プログラミング になじみがある方は、`Interface`の方が使いやすいかもしれません。

また、歴史的に見ると`Interface`は初めからあるもので、`type`は後から追加されたもので
`type` は できないことが多かったので、以前は `Interface` を使う人が多かったようです。

Googleが公開している [Interface vs type alias](https://google.github.io/styleguide/tsguide.html#interfaces-vs-type-aliases) ではオブジェクト型に関してはInterfaceを使うことを推奨されています。

この記事が、Interface と type どちらを使うべきか迷っている方の参考になれば幸いです。

## 参照

https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases

https://typescriptbook.jp/reference/object-oriented/interface/interface-vs-type-alias

https://google.github.io/styleguide/tsguide.html#interfaces-vs-type-aliases
【機械学習アルゴリズム/フレームワーク/Kaggle】ローン承認予測 (Loan Approval Prediction) - Kaggle 運動場 シリーズ


## はじめに
2024年のKaggle Playgroundシリーズへようこそ！このシリーズは、機械学習のスキルを練習するための興味深いデータセットを提供し、参加者がさまざまな問題に取り組むことで、スキルを磨く場を提供することを目的としています。毎月新しいコンペティションが開催され、今回は「ローン承認予測」というテーマで、ローンの承認可否を予測するタスクです。

この記事では、このコンペティションの概要、評価基準、提出フォーマット、タイムラインについて説明し、さらにこの課題に対する戦略を簡単に説明したものになります。



**具体的に分類木のアルゴリズムを使用したkaggle参加者の方のノートブックの説明を下記でしていますので、ご参考に下さい。**

https://qiita.com/Life-tech/items/a785e3cad191d44e9b06



## 競技概要
### 目的
このコンペティションの目標は、ローン申請者がローンを承認されるかどうかを予測することです。与えられたデータを基に、モデルを構築し、ローンの承認状態を「loan_status」として予測します。

### データセット
今回のデータセットは、現実世界のデータを基にして生成された合成データ（synthetic data）を使用します。これにより、テストデータのラベルが公開されない形で、より興味深いデータセットが提供されています。合成データの利点として、実世界のデータに近い特徴を持ちながらも、データの機密性が守られていることが挙げられます。

### 提出フォーマット
提出するファイルは、テストセットの各行に対して予測された「loan_status」を含む必要があります。ファイルにはヘッダーが含まれ、以下のような形式でなければなりません。

id,loan_status
58645,0.5
58646,0.5
58647,0.5
...

### 戦略とアプローチ
この課題に取り組むにあたって、いくつかの重要なポイントを考慮する必要があります。まず、データの前処理が非常に重要です。合成データではありますが、現実のデータと同様に、不完全な値や異常値が含まれる可能性があります。データのクレンジングと欠損値処理、カテゴリカル変数のエンコーディングなどを行う必要があります。

### 主な戦略
**データの可視化**
まず、データを可視化してパターンや特徴を理解しましょう。例えば、申請者の年齢や収入がローンの承認にどのような影響を与えるかを調べることが重要です。
**特徴量エンジニアリング**
合成データには、多くの特徴が含まれている可能性があります。その中で、重要な特徴を選び出すために特徴選択手法を使ったり、新たな特徴を作り出す「特徴量エンジニアリング」が有効です。
**モデル選択**
ローン承認予測のタスクは、二値分類問題です。そのため、ランダムフォレストやXGBoost、LightGBMなどの分類アルゴリズムがよく使われます。また、ニューラルネットワークを使うアプローチも可能です。
**ハイパーパラメータチューニング**
モデルの性能を最大限に引き出すために、ハイパーパラメータのチューニングを行います。これには、グリッドサーチやランダムサーチ、ベイズ最適化などの手法が使えます。
**クロスバリデーション**
モデルが過学習しないよう、クロスバリデーションを行ってモデルの汎化性能を高めます。

### 必須手順
1. データの前処理
1. 特徴量選択とエンジニアリング
1. モデルのトレーニングと評価
1. ハイパーパラメータの最適化
1. 最終提出ファイルの作成


## まとめ
このコンペティションは、機械学習におけるデータ前処理、モデル構築、評価を行う実践的な流れを学習することが可能です。ROC AUCスコアを最大化するために、適切なデータ処理とモデルの選択が成功の鍵となります。KaggleのPlaygroundシリーズは、初心者から中級者までの幅広い参加者にとって学習と成長の機会が提供されています。
paizaラーニング問題集「【条件判定 3】過剰コンプライアンス」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__over_conpriance

▼考え方

この問題を解くために私が考えた内容1.～2.2.を以下に示します。

1.放送したい単語Vを1つずつインプットし、題意に基づいた検閲処理を行います。

2.1.放送したい単語Vの前半分の検閲処理を行います。変数v1を用いたV[:v1]は、放送したい単語Vの前半分を示します。V[v1:]は前半分以外の残りを示します。変数s1を用いたS[:s1]は、放送禁止単語Sの前半分を示します。

2.2.放送したい単語Vの後ろ半分の検閲処理を行います。変数v2を用いたV[v2:]は、放送したい単語Vの後ろ半分を示します。V[:v2]は後ろ半分以外の残りを示します。変数s2を用いたS[s2:]は、放送禁止単語Sの後ろ半分を示します。

▼コード
```py
########## 処理0(準備) モジュールインポート,インプット ###########

import math

N = int(input())

S = input()

########## 処理1 放送したい単語Vの検閲処理、出力 ###########

for i in range(N):

    # 考え方1.
    V = input()
    
    if V == S:
        print("banned")
    
    elif len(V) != len(S):
        print(V)

    else:
        # 考え方2.
        v1 = math.ceil(len(V)/2)
        s1 = math.ceil(len(S)/2)
        v2 = math.floor(len(V)/2)
        s2 = math.floor(len(S)/2)

        # 考え方2.1.
        if V[:v1] == S[:s1]:
            V = len(V[:v1])*"x" + V[v1:]

        # 考え方2.2.
        elif V[v2:] == S[s2:]:
            V = V[:v2] + len(V[v2:])*"x"
            
        print(V)
```
paizaラーニングスキルチェック「C062:回転寿司のメロン」を解いてみた

https://paiza.jp/challenges/share/XjwwS5Cs-r-aEILFvK41X8BAlqw2u607JOxvQDyAjSU?source=social

▼考え方

この問題を解くために私が考えた内容を以下に示します。

1.流れてくる皿の残りが10皿未満の場合は、新たにメロンを取ることはできないため、処理を終了します。10皿以上ある場合は、食べられない皿のネタは処理しないようにします。

▼コード
```py
########## 処理0(準備) インプット,変数定義 ###########

T = int(input())

# count: お店に滞在している間に食べられるメロンの数を格納する変数
count = 0

i = 1

########## 処理1 メロンの数を計算、出力する処理 ###########

while i <= T:

    # neta: 流れてくる皿のネタを1つずつ格納する変数
    neta = input()

    if neta == "melon":
        count += 1

        # 考え方1.
        if T - i < 10:
            break
        else:
            for j in range(10):
                neta = input()
            i += 11
    
    else:
        i += 1

print(count)
```
スケジュールをパンクさせてわかったマネジメントの大変さ

# はじめに
##### 私の状況
- 数人のチームのチームリーダ（新任リーダ）
- メンバのタスク（あと私のタスク）を完全にパンクさせて大変なことになった

##### メンバの状況
- 私の下で働いてくれている神

# とりあえず結論
1. 私のチームで対応すべきタスクがパンクした
1. タスクに遅延が許されなかったのでメンバ（と私）が超勤でカバーすることになった
1. 超勤は大変なことになるし上司からは大目玉を食らうしで大変なことになった

# 原因
1. タスクの期限に対して最初に定められた期限をアップデート出来ていなかった
    1. マスタスケジュールがしょっちゅう変わるプロジェクトなので、それに対応して各タスクの期限もアップデートする必要があった
    1. マスタスケジュール上のどの予定までになんのタスクが終わってないと問題になるのかを把握しきれなくなっていた
1. 振ったタスクの状況を把握できていなかった
    1. ベテランに任せたので「任せておけば良いだろう」と思ってしまった
    1. 自分が手を動かさないといけないタスクに集中してしまった
1. 上への報告が遅れた
    1. 正直「あれ？やばいか？」と思った瞬間はあったが、叱責を恐れた

# 対応
1. 対応内容で優先度を決めて対応をした
1. 上司メンバその他関係者への謝罪＆協力要請行脚
1. 超勤超勤＆超勤

# 対策・学んだこと
1. スケジュール感のアップデートを学ぶ
    1. どんなイベントがあるのか
    1. そのイベントのためになにが必要なのか
    1. 必要なものを満たすためになにをしないといけないのか
1. 報告
    1. 「あれ？やばいか？」と思った時にちゃんと報告すればまだ助かったかもしれない
    1. びびらない
1. PM試験で学んだことは役に立つ
    1. 「叱責を恐れて報告が遅れた」とか「新任が管理しきれなくてリカバリ」とか午後1でしょっちゅう見るやつ

# まとめ
1. 問題なら解けるのに自分がやらかすとわからない（というかそんなことできない）
1. 当然のことだがとっとと報告したほうが浅い傷で済む
1. 全体スケジュールを把握する意識を持たないと駄目