OmniAICreator/Qiita-1.07M huggingface dataset:
【情報セキュリティマネジメント試験】試験内容のまとめ

4月末の受験を目指して情報セキュリティマネジメント試験の勉強をしています。
まずはどんな内容を勉強しないといけないか
まとめの記事を書きます。

目次的な記事です。

:::note info
情報セキュリティとは
:::
:::note info
情報セキュリティマネジメント
:::

https://qiita.com/miku_swift555/items/892e3aba83be3878123e

:::note info
ネットワーク
:::

https://qiita.com/miku_swift555/items/43c51783e07c2d03271f

https://qiita.com/miku_swift555/items/edeb8bca7d7b35fb3cb4

:::note info
コンピュータウイルスとマルウェア
:::

https://qiita.com/miku_swift555/items/7970bb8e35f156955906

:::note info
サイバー攻撃手法とセキュリティ対策について
:::
https://qiita.com/miku_swift555/items/92371d7add170e9eaff6

https://qiita.com/miku_swift555/items/22c852ff2ec9ea128896 

:::note info
暗号と認証
:::

 https://qiita.com/miku_swift555/items/6fff74e89ced20459581

https://qiita.com/miku_swift555/items/b82c95da37efbb3c8b90  

https://qiita.com/miku_swift555/items/8becbc64561a026254ac
 
:::note info
データベース
:::
:::note info
システム開発
:::
:::note info
システム構成と故障対策について
:::
:::note info
システム周りの各種マネジメントについて
:::

:::note info
システム監査
:::


https://qiita.com/miku_swift555/items/579f6dddf500448a328e

:::note info
企業と法務について
:::

https://qiita.com/miku_swift555/items/98ff183f0470235dfc83

https://qiita.com/miku_swift555/items/c10df442cd7d04a1f9a5


:::note info
企業活動と組織について
:::

まだ枠組み的な記事ですが、過去問を解いてわからなかった項目について調べた記事を
ここにまとめて行こうと思います。
GoでUnion型を表現する

## はじめに
GoもUnion型が使えるといいなと思って、調べたのですが残念ながらないみたいですね！
ただ、代用方法がいくつか提示されていたので、勉強がてら紹介したいと思います。

## タグ付き構造体を使う
```go:main.go
package main

import "fmt"

// ユニオン型を表現するタグ付き構造体
type ItemResult struct {
	Type  string
	Value interface{}
}

// 処理を行う関数
func ProcessItem(item ItemResult) {
	switch item.Type {
	case "int":
		fmt.Println("Integer:", item.Value.(int))
	case "string":
		fmt.Println("String:", item.Value.(string))
	case "float64":
		fmt.Println("Float64:", item.Value.(float64))
	default:
		fmt.Println("Unknown type")
	}
}

func main() {
	ProcessItem(ItemResult{Type: "int", Value: 100})        // 出力: Integer: 100
	ProcessItem(ItemResult{Type: "string", Value: "Hello"}) // 出力: String: Hello
	ProcessItem(ItemResult{Type: "float64", Value: 99.9})   // 出力: Float64: 99.9
}
```
:::note info
`Type  string`でどの型かを持たせ、Validationチェックを実施制御
:::

## インターフェースを使う方法

```go:main.go
package main

import "fmt"

// インターフェースでユニオン型を表現
type ItemResult interface{}

// 型スイッチで処理を分岐
func ProcessItem(item ItemResult) {
	switch v := item.(type) {
	case int:
		fmt.Println("Integer:", v)
	case string:
		fmt.Println("String:", v)
	case float64:
		fmt.Println("Float64:", v)
	default:
		fmt.Println("Unknown type")
	}
}

func main() {
	ProcessItem(100)         // 出力: Integer: 100
	ProcessItem("Hello")     // 出力: String: Hello
	ProcessItem(99.9)        // 出力: Float64: 99.9
	ProcessItem(true)        // 出力: Unknown type
}
```

##  型制約（Generics）を使う

```go:
package main

import "fmt"

// ユニオン型を表現する型制約
type ItemType interface {
	int | string | float64
}

// ジェネリック構造体
type Container[T ItemType] struct {
	Value T
}

// 値を表示する関数
func Display[T ItemType](c Container[T]) {
	fmt.Printf("Type: %T, Value: %v\n", c.Value, c.Value)
}

func main() {
	// 許可された型を使用
	intContainer := Container[int]{Value: 100}
	stringContainer := Container[string]{Value: "Hello"}
	floatContainer := Container[float64]{Value: 99.9}

	// 値を表示
	Display(intContainer)    // 出力: Type: int, Value: 100
	Display(stringContainer) // 出力: Type: string, Value: Hello
	Display(floatContainer)  // 出力: Type: float64, Value: 99.9

	// 許可されない型はエラー
	// boolContainer := Container[bool]{Value: true} // コンパイルエラー
}
```
:::note info
Genericsはv1.18以降で導入されています。
:::
フロントエンドエンジニアが覚えておきたい英語

**日々の業務で英語を使い話すことはないのですが、エンジニアが業務でよく使う英会話とかあったらいいのになと感じたのでこの記事を作成しました**。

# 基本用語

**Frontend**

意味：ユーザーが直接触れる部分の開発領域（HTML、CSS、JavaScriptなど）。

例文：

“We need to implement the frontend with responsive design.”（レスポンシブデザインでフロントエンドを実装する必要があります）

**Rendering（レンダリング）**

意味：ウェブページやアプリケーション画面を表示する処理全般。ブラウザがHTMLやCSS、JavaScriptを読み込んで画面を描画するプロセス。

例文：

“The rendering performance affects the user experience.”（レンダリング性能はユーザー体験に影響を与えます）

**Responsive Design（レスポンシブデザイン）**

意味：画面サイズに応じてレイアウトが自動的に最適化されるデザイン手法。

例文：

“Responsive design ensures the layout adjusts to different screen sizes.”（レスポンシブデザインにより、異なる画面サイズでもレイアウトを調整できます）

**DOM（Document Object Model）**

意味：HTMLやXML文書を階層構造で表現したもの。フロントエンド開発では要素を操作する際に重要。

例文：

“We can manipulate the DOM with JavaScript to update content dynamically.”（JavaScriptを使ってDOMを操作し、動的にコンテンツを更新できます）

# 実装・開発時によく使うフレーズ

“Let’s initialize the project with a frontend framework.”

フロントエンドフレームワークでプロジェクトを初期化しましょう。

“We’ll need to set up the build pipeline.”

ビルドパイプラインを設定する必要があります。

“I will adjust the layout to match different screen resolutions.”

さまざまな画面解像度に合わせてレイアウトを調整します。

“We need to clear the cache before we test the new version.”

新しいバージョンをテストする前にキャッシュをクリアする必要があります。

# デザインやUI関連

“Please align the elements according to the design guidelines.”

デザインガイドラインに沿って要素を配置してください。

“This layout helps ensure consistent spacing across all components.”

このレイアウトにより、すべてのコンポーネントで一定のスペーシングを確保できます。

“We should consider accessibility and keyboard navigation.”

アクセシビリティとキーボード操作への対応を考慮するべきです。

# バグ対応やデバッグ

“I found a glitch when resizing the browser window.”

ブラウザのウィンドウサイズを変更すると不具合を見つけました。

“Let’s add a console log to check the component state.”

コンポーネントの状態を確認するためにコンソールログを追加しましょう。

“There’s an offset issue when we scroll the page.”

ページをスクロールするときにオフセットの問題が起きています。

# プレゼン・ミーティングで使える表現

“Could you provide an overview of the frontend architecture?”

フロントエンドのアーキテクチャ概要を説明してもらえますか？

“We need to discuss performance optimizations.”

パフォーマンス最適化について議論する必要があります。

“Let’s finalize the design specs for the user interactions.”

ユーザー操作に関するデザイン仕様を最終決定しましょう。



**専門書や海外のドキュメントを読む際にも役立ちます。ぜひ実践で使ってみてください！**
M5Stack用GPSユニット v1.1(AT6668)を使ってみた

# はじめに
間違ったことが書いている可能性があるので、鵜吞みにしないでください。責任取りません。
調べた情報が少ないのでよくわかりません。
# 詳細
**通信の確保**
ボーレート 115200
**受信する衛星**
```
GPS L1
みちびき(QZSS) L1 (194,195,196,199)
北斗(Beidou) B1C/B1I
GALILEO E1b
GLONASS R1F
```
(北斗 マルチ周波数対応!!)
主要な衛星は受信します（Air530Zではガリレオは受信しませんでした）
SBAS(補強信号)は受信しません!!
**内部構造**
Soc AT6668
Hardware ATGM336H
```txt:起動時出力
$GPTXT,01,01,02,MA=CASGN*24
$GPTXT,01,01,02,HW=ATGM336H,0004051102789*17
$GPTXT,01,01,02,IC=AT6668-6N-74-00000A30,DM31A2J-22-41D002043*1F
$GPTXT,01,01,02,SW=URANUS6,V6.2.3.0*1F
$GPTXT,01,01,02,TB=2024-04-26,09:49:42*4C
$GPTXT,01,01,02,BS=BOOT8A,V8.0.1.0*53
$GPTXT,01,01,02,MO=GBREQ*31
$GPTXT,01,01,02,SM=00084CA1,GPS,BD2,BD3,GLN,GAL,QZS*73
$GPTXT,01,01,02,SR=1,0000,F3,0F,4,00,AD*7
```
何かの参考にしてください

**設定の保存**
いろいろ設定したら以下のコマンドを送って次の起動時からも有効にしてください。
```
$PCAS00*01
できなかったらこっちも
$PCAS00*01\r\n
```

**マルチ周波数対応**
 確かに北斗は2周波対応していますが、使用するにはシリアル変換機で設定する必要があります。
 使ったソフト GNSStoolKit3
 接続→設定(Configuration View)→NMEA→CCSIR
 ここにきたらSignalをallにして下にあるSendを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3994157/cdecae22-03fd-4828-badb-a2cea74a98d5.png)
ここを変更してください

:::note warn
 中国のソフトです。自己責任でお願いします
 言語は最初中国語なので、英語にしたほうがいいです。
 メニューの一番右からそれっぽいのを探してください
 (わからなくもないけど)
:::

**NMEAの出力**
以下を送信するとすべてのセンテンスを出力します。

```
$PCAS03,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1*1F
```
詳細
PCAS03,GGA,GLL,GSA,GSV,RMC,VTG,ZDA,ANT,DHV,LPS,予約,予約,nUTC
全部有効にしたければALL1でもいいと思います。

**コマンド**
PCASコマンドは動くようですが、プロトコルの仕様書がありません...
PCAS04なども従来みたいな挙動はするようですが、わかりません
何かわかる人は教えてください!!
# おまけ
 Air530Z(AT6558R)に比べ進化してる(V1.0)←う　れ　し　い
 どんな感じでFixするの?
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3994157/dbad3c2f-5d96-4d89-ac47-300c8c9c939b.png)

## ここまで見てくれてありがとうございます。
Google SheetsでChatGPT OpenAI APIを使って自動要約する方法


## はじめに

Google Sheetsで特定のセルの内容をGPT-4を使って自動要約する方法を紹介します。Google Apps ScriptとOpenAI APIを組み合わせることで、スプレッドシート上のテキストを効率的に要約することができます。

## 準備するもの

- OpenAI APIキー（[OpenAIのウェブサイト](https://platform.openai.com/)から取得）
- Google アカウント
- Google Sheets

## 実装手順

### 1. スプレッドシートの準備

1. 新しいGoogle Sheetsを作成します
2. シート名を"GPT"に変更します
3. A1セルにベースとなるプロンプトを入力します（例：「以下の内容を3行で要約してください：{content}」）

### 2. Google Apps Scriptの実装

スプレッドシートのメニューから「拡張機能」→「Apps Script」を選択し、以下のコードを貼り付けます：

```javascript
function GPTCell(cellAddress) {
    const API_KEY = "your-api-key-here"; // ⚠️ APIキーを設定してください
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("GPT");
    const basePrompt = sheet.getRange("A1").getValue();
    
    try {
        const cellValue = sheet.getRange(cellAddress).getValue();
        const prompt = basePrompt.replace("{content}", cellValue);
        const messages = [{ role: "user", content: prompt }];
        const payload = {
            model: "gpt-4o-mini-2024-07-18",  // または "gpt-3.5-turbo" など、利用したいモデルを指定
            messages: messages
        };
        const options = {
            contentType: "application/json",
            headers: { Authorization: "Bearer " + API_KEY },
            payload: JSON.stringify(payload),
            muteHttpExceptions: true
        };
        const url = "https://api.openai.com/v1/chat/completions";
        const response = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
        const summary = response.choices[0].message.content.trim();
        return summary;
    } catch (e) {
        return `エラー: ${e.message}`;
    }
}
```

### 3. APIキーの設定と安全な管理 ⚠️

1. OpenAIのウェブサイトからAPIキーを取得します
2. コード内の`your-api-key-here`を取得したAPIキーに置き換えます
3. **重要な注意事項：**
   - APIキーは秘密情報です。絶対に公開しないでください
   - スクリプトを共有する際は、必ずAPIキーを削除してください
   - 理想的には、APIキーはスクリプトプロパティなどで管理することをお勧めします

#### APIキーをスクリプトプロパティとして設定する方法

より安全な実装のために、以下の手順でAPIキーを設定できます：

1. Apps Scriptエディタで「プロジェクトの設定」を開く
2. 「スクリプトプロパティ」タブを選択
3. 新しいプロパティを追加：
   - プロパティ名：`OPENAI_API_KEY`
   - 値：あなたのAPIキー

そして、コードを以下のように修正：

```javascript
const API_KEY = PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY');
```

## 使い方

1. 要約したいテキストをスプレッドシートのセルに入力します
2. 別のセルに以下のような数式を入力します：
   ```
   =GPTCell("B1")
   ```
   ※ B1は要約したいテキストが入っているセルのアドレスに置き換えてください

## コードの解説

### 主な機能

- `GPTCell`関数は指定されたセルの内容を取得し、GPT-4に要約を依頼します
- A1セルのベースプロンプトを使用して、柔軟に指示を変更できます
- エラーハンドリングにより、APIリクエスト失敗時にも適切なメッセージを返します

### モデルの選択

OpenAIは複数のモデルを提供しています：
- `gpt-4`: 最も高性能なモデル
- `gpt-3.5-turbo`: コストパフォーマンスの良いモデル

用途と予算に応じて適切なモデルを選択してください。

## 注意点

- OpenAI APIの利用には課金が発生します
- API利用制限に注意してください
- **APIキーは絶対に公開しないでください**
- 共有や公開時は必ずAPIキーを削除してください

## まとめ

このスクリプトを使用することで、Google Sheets上で簡単にGPT-4による要約機能を実装できます。ビジネスシーンでの文書要約や、大量のテキストデータの処理に活用できるでしょう。

プロンプトをカスタマイズすることで、要約以外にも様々な用途に応用可能です。例えば：
- テキストの感情分析
- キーポイントの抽出
- 文章のリライト
- 多言語翻訳

## 参考資料

- [OpenAI Models Documentation](https://platform.openai.com/docs/models)
- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference)
- [Google Apps Script Documentation](https://developers.google.com/apps-script)
【AWS】スポットインインスタンスがいまいちパッとこないのでまとめる。

### ずばり・・・
未使用のEC2インスタンスを通常よりも低価格で利用できるオプション。AWSのデータセンター内のリソースを空いてるやつ勝手につかうねーってオプション。
もちろんAWSの都合上で自分が間借りしてたインスタンスを勝手に使われることがあるので意図せず中断することがある。長期的には向いていない、バッチテストとかで使うといいかも。
**普通にマネジメントコンソールなどからリクエストできるらしい。(AWSの承認まで少し時間がかかるかもしれない。)**

### 参考文献

https://www.future.ad.jp/futuremedia/keyword_ec2spot/
【電脳少女プログラミング2088 ─壊レタ君を再構築─】Python初心者がやってみた（ネオン街の裏路地編）

## はじめに

前回の記事で「カジノ」をクリアして、今回は「ネオン街の裏路地」をクリアしたので書こうと思います。

難しくてまだクリアできてない方などに参考にしてもらえると嬉しいです。

https://paiza.jp/entry/denno2088_qiita

## 【問題】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/8f1f9c10-4b23-4aa4-ba32-530680e2fa08.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/9ed99ad6-b29e-4ff0-b87d-79f463b4d29d.png)

## 解答

今回もPython3を選択して書いてみました。前回、問題の解答の方法を学んだので結構簡単にクリアすることができました。

```python:解答
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！

n = int(input())  # 1行目の扉の個数を整数として受け取る
m = []  # 扉に書かれた数字を格納するリスト

for i in range(n):
    m_i = int(input())  # 各行で扉に書かれた数字を受け取る
    m.append(m_i)  # リストに追加
    
print(max(m))  # リストmの最大値を表示
```

## コード解説

上のコードの解説をすると

扉の個数整数として`n`に代入

```python:５行目
n = int(input())
```

***

扉に描かれた数字を格納するリストを作成

```python:６行目
m = []
```

***

for文で`n`の回数分、下の処理を繰り返す
1. `m_i`に`n`個目の値を整数として代入
2. リスト`m`に`m_i`を追加

```python:８行目～１０行目
for i in range(n):
    m_i = int(input())
    m.append(m_i)
```

***

リスト`m`の中で一番大きい値を表示

```python:１２行目
print(max(m))
```

***

こんな感じで上のコードで問題を解くことができました。

## 最後に

記事を最後までお読みいただきありがとうございます！
前回のカジノの問題より難しかったですが解決することができました。次回は「郊外のスラム街」をやろうと思っています。次回も見てくださると嬉しいです。

ではまた他の記事で会いましょう！またねーヾ(*´∀｀*)ﾉ
Rails 8以降のJavaScript環境は何を選択するべきか？

RailsのJavaScript環境は、Rails7になってから大きく変わりました。Rails wayに乗る場合とそれ以外を選択する場合ではどのような選択肢があり、どういう基準で選択すればよいか軽く調べました。

### はじめに結論
Railsのデフォルト推奨の環境は小中規模な開発に特化していると言えます。Rails way = さくっと小中規模環境を作るのに最適だという認識で以下の記事を読んで下さい。


JavaScriptの環境としていくつか選択肢がありますが

# 1. Importmaps (デフォルト)
Importmapsは、Rails 8のデフォルトのJavaScript管理方法です。

### 特徴:


1. バンドラーを必要としない
1. ブラウザのネイティブES moduleシステムを活用
1. CDNからJavaScriptライブラリを直接ロード
1. 小規模なアプリケーションに適している
1. rails7からデフォルトのJavaScript管理方法になっている

### 設定方法:
バンドラーを利用しない分シンプルです。
railsガイドを確認してみて下さい。サクッと環境構築ができるかと思います。

https://railsguides.jp/v7.0/asset_pipeline.html#import-map%E3%82%92javascript%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E4%BD%BF%E3%81%86

# 2. JavaScript Bundlers
従来のJavaScriptバンドリングを好む場合は、以下のオプションがあります。また既に構築済みのRailsの場合は以下の設定を選ぶことが多いかと思います。


1. Bun
2. esbuild
3. Webpack
4. Rollup.js

### 特徴:

1. 複雑なJavaScriptの依存関係を管理
2. プリプロセッシングやトランスパイリングが可能
3. 大規模で複雑なアプリケーションに適している

### 設定方法:
jsbundling-railsのgemを使えば簡単に設定できます。

https://github.com/rails/jsbundling-rails



### おすすめ
小〜中規模のアプリケーション: Importmapsを使用することをおすすめします。設定が簡単で、多くのアプリケーションにとって十分な機能を提供します。

大規模または複雑なアプリケーション: 従来のバンドラー（例：Webpack）の使用をおすすめします。特に以下の要件がある場合:

1. 複雑なJavaScript依存関係の管理
2. カスタムビルドプロセスの必要性
3. レガシーブラウザのサポート4

最終的な選択は、プロジェクトの具体的な要件、チームの経験、パフォーマンスの考慮事項に基づいて行うべきで、小中規模でも現在のバンドラーで困っていることがなければ移行するメリットはないかと思います。ただRails wayに載っておくと開発効率を上げることができるので、必須要件ではなくとも、importmapsに移行も選択肢にあがるのではないでしょうか。

新規ぷろじぇくｔはImportmapsやstimulus.jsを使ってなるべく少ない工数でRailsのサポートを受けながら開発することをおすすめします。
個人的備忘録：制約・インデックス・ビューとは？データの整合性を守るために、改めて知識を体系的に整理してみた

## はじめに

データベースを設計する際には、スキーマの理解が不可欠です。スキーマはデータの構造や制約を定義し、データの整合性やパフォーマンスを確保する役割を果たします。

:::note info
***本記事では、データベーススキーマの基本概念やその構成要素について詳しく解説します。***
:::

## 書こうと思ったきっかけ

データベースを設計する際にスキーマの知識が不足していると、後々の運用で問題が発生することがよくあります。

:::note warn
**例えば、適切な制約を設けなかったことでデータの重複や不整合が発生したり、適切なインデックスを設定しなかったために検索速度が低下したりすることがあります。**
:::

こうした課題を防ぐため、スキーマ設計の基本を整理し、実践的な知識を身につけるためにこの記事を書くことにしました。

## データベースのスキーマとは？

データベースの**スキーマ（Schema**）とは、データベース内の構造や定義を記述する設計図のようなものです。

スキーマには、テーブル、ビュー、インデックス、制約（制約条件）、リレーション（テーブル間の関係）などの情報が含まれます。

## データベーススキーマの主な要素

### 1. テーブル（Table）
データを保存する基本的な単位であり、列（カラム）と行（レコード）で構成されます。

#### 例：
```sql
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

### 2. カラム（Column）
各テーブル内のデータの種類を定義し、データ型や制約を設定できます。

### 3. データ型（Data Type）
各カラムに格納できるデータの種類を指定します。

**例:** `VARCHAR(255)`, `INT`, `BOOLEAN`, `DATETIME`

### 4. インデックス（Index）
データ検索の高速化のために使用される仕組み。

#### 例：
```sql
CREATE INDEX idx_users_email ON users(email);
```

### 5. 制約（Constraint）
データの整合性を維持するためのルール。

**主な制約:**
- `PRIMARY KEY`（主キー）
- `FOREIGN KEY`（外部キー）
- `UNIQUE`（一意性制約）
- `CHECK`（条件チェック）

### 6. ビュー（View）
実データを持たず、クエリの結果を仮想的なテーブルとして扱う。

#### 例：
```sql
CREATE VIEW active_users AS
SELECT id, name, email FROM users WHERE active = 1;
```

### 7. リレーション（Relation）
テーブル間の関係を定義する仕組み。

#### 例：
```sql
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    FOREIGN KEY (user_id) REFERENCES users(id)
);
```

## スキーマの種類

### ロジカルスキーマ（論理スキーマ）
データの構造を論理的に定義。ER図（エンティティ・リレーションシップ図）を用いることが多い。

### フィジカルスキーマ（物理スキーマ）
データの保存方法やインデックスの配置など、実際のデータベース管理システム（DBMS）での設定を定義。

### ユーザースキーマ
データベースの利用者ごとにアクセスできるデータや操作権限を管理。

## スキーマの具体例
例えば、ECサイトのデータベーススキーマを考えると、次のような関係があるかもしれません...。

```
Users (id, name, email, password, created_at)
Orders (id, user_id, total_price, status, created_at)
Products (id, name, price, stock, created_at)
OrderItems (id, order_id, product_id, quantity, price)
```

このスキーマをもとに、データベース内の関係を整理し、データの整合性やパフォーマンスを考慮しながら設計を進めていきます。

## まとめ
- スキーマはデータベースの構造を定義するもの。
- テーブル、カラム、データ型、インデックス、制約、ビュー、リレーションなどを含む。
- スキーマを適切に設計することで、データの整合性を保ち、検索の高速化が可能になる。

データベースを設計する際は、スキーマ設計をしっかり行うことが重要です！
個人的備忘録：DockerとAWS ECSの実際のポートマッピングを自分なりに体系的にまとめてみた

## はじめに

ポートマッピングは、ホストマシンとコンテナ間、またはクラウド環境のインスタンスと外部ネットワーク間で、通信を適切にルーティングするための設定です。

これにより、外部からのリクエストを特定のコンテナやアプリケーションに転送できます。

## 書こうと思ったきっかけ
この記事を書こうと思ったきっかけは、Docker や AWS ECS を利用する際にポートマッピングの設定でつまずくケースが多かったためです。

:::note warn
***特に ECS の Fargate では動的ポート割り当ての仕組みが理解しにくいため、整理して説明しようと思いました。***
:::

また、Docker の基本的なポートマッピングとの違いを明確にすることで、読者の理解を助けたいと考えました。

## 実際のポートマッピングについて

本記事では、**Docker** と **AWS ECS (Amazon Elastic Container Service)** でのポートマッピングの方法について解説します。

### 1. Docker でのポートマッピング

Docker では、`-p` オプションを使用してホストとコンテナのポートをマッピングします。

#### 基本的なポートマッピング

```sh
$ docker run -d -p 8080:80 nginx
```

上記のコマンドでは、
- ホストの **8080番ポート** にアクセスすると、
- コンテナ内の **80番ポート** にリクエストが転送されます。

#### 特定のIPアドレスを指定する場合

```sh
$ docker run -d -p 192.168.1.100:8080:80 nginx
```

この場合、`192.168.1.100` の **8080番ポート** にアクセスしたときのみ、コンテナの **80番ポート** にリクエストが転送されます。

#### Docker Compose でのポートマッピング

```yaml
version: '3'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
```

この設定では、ホストの `8080` ポートがコンテナの `80` ポートにマッピングされます。

### 2. AWS ECS でのポートマッピング

AWS ECS では、ポートマッピングは **タスク定義 (Task Definition)** のカスタム JSON で設定できます。

#### 基本的なポートマッピング設定

ECS では、ポートマッピングは **containerDefinitions** 内の `portMappings` に定義します。

```json
{
  "containerDefinitions": [
    {
      "name": "web-app",
      "image": "nginx",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 8080,
          "protocol": "tcp"
        }
      ]
    }
  ]
}
```

この設定では、
- ホストの **8080番ポート** が、
- コンテナの **80番ポート** にマッピングされます。

#### AWS Application Load Balancer (ALB) との連携

ECS の **Fargate** では、ホストポートの指定を `0` にすることで、動的ポート割り当てが可能になります。

```json
{
  "containerDefinitions": [
    {
      "name": "web-app",
      "image": "nginx",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ]
    }
  ]
}
```

この設定では、コンテナの `80` 番ポートが、ECS によって自動的にホストの空きポートに割り当てられます。ALB などを使用することで、適切にルーティングされます。

## まとめ

Docker と ECS のポートマッピングは、環境や要件によって適切に設定することが重要です。

| 環境  | 設定方法 |
|------|---------|
| **Docker** | `-p` オプションでホストとコンテナのポートをマッピング |
| **Docker Compose** | `ports` でホストとコンテナのポートを定義 |
| **AWS ECS (EC2 起動タイプ)** | `hostPort` と `containerPort` を設定 |
| **AWS ECS (Fargate)** | `hostPort` を `0` に設定し、動的ポート割り当てを使用 |

特に ECS の場合、ALB やサービスディスカバリと組み合わせることで、より柔軟なポート管理が可能になります。
【Git】変更を一時退避する便利技 git stash の基本コマンド

# はじめに
開発中に「今の変更を一時的に保存して、後で戻したい…」と思うことはありませんか？  
そんなときに便利なのが `git stash` です！  
`git stash` を使えば、コミットせずに作業途中の変更を退避し、好きなタイミングで元に戻せます。  
本記事では、知っておきたい `git stash` の基本コマンド5つを紹介します！

# **1. 変更を退避する**  
```sh
git stash push -u -m "作業中の変更を退避"
```
- `push`は省略可能なので、`git stash -u -m "作業中の変更を退避"` でも同じ動作になります
- `-u`は未追跡ファイルを含めるオプション。指定しない場合、新規作成したファイルはスタッシュされません
- `-m`はスタッシュにメッセージを付けられるオプション。メッセージを付けることで `git stash list` を実行したときに内容を確認しやすくなります

# **2. 退避した変更を一覧表示する**  
```sh
git stash list

# 実行結果（保存されているスタッシュの一覧）
stash@{0}: On feature-branch: 作業中の変更を退避
stash@{1}: On main: バグ修正用の一時退避
```
- `stash@{0}` が最新のスタッシュ、`stash@{1}` は1つ前のスタッシュを指します

# **3. 退避した変更を適用する**  
```sh
git stash apply stash@{0}
```
- `stash@{0}`（最新のスタッシュ）の変更を適用する
- 実行後も `git stash list` にスタッシュは残る
- 過去のスタッシュを適用したい場合は、`git stash apply stash@{1}`（1つ前）のように指定できる

# **4. 退避した変更を削除する**  
```sh
git stash drop stash@{0}
```
- `stash@{0}` （最新のスタッシュ）だけを削除し、他のスタッシュは残る

# **5. 退避した変更を適用しつつ削除する**  
```sh
git stash pop stash@{0}
```
- `apply` + `drop` を1回のコマンドで実行
- `apply` との違いは、適用後にスタッシュが削除されるかどうか

# 最後に
覚えておくと便利な `git stash` コマンドを紹介しました。
この5つを押さえておけば、基本はバッチリです！
「git stash の使い方を忘れた」と思ったときにすぐ見返せるよう、ブックマークしておくのがオススメです！

その他のコマンドについて詳しく知りたい方は、[公式ドキュメント](https://git-scm.com/docs/git-stash)を参考にしてください。
個人的備忘録：nginx.conf のリバースプロキシをいい感じに設定して、ECS × Nginx × Django でデプロイ準備

## はじめに

Nginx を利用して Django アプリケーションをリバースプロキシとして運用する方法について説明します。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、基本的な設定とポイントを解説し、よりスムーズな運用を目指します。

## 書こうと思ったきっかけ

Django アプリケーションを本番環境にデプロイする際に、Nginx をリバースプロキシとして利用する機会がありました。

その際、設定のポイントを整理することで、今後の運用に役立てられると考え、この記事を書くことにしました。

## Nginx を利用した Django アプリケーションのリバースプロキシ設定

今回は、Nginx を使用して Django アプリケーションのリバースプロキシを設定する方法について解説します。

## 設定の概要

この設定では、以下の動作を実現します。

- test.com というドメインでアクセスを受け付ける。
- ルート URL (`/`) にアクセスがあった場合、`/test.com/` にリダイレクトする。
- `/static/` へのアクセスは `/app/staticfiles` ディレクトリを参照する。
- `/test.com/` 以下のパスは `http://127.0.0.1:8000` へリバースプロキシする。
- `server_tokens` を `off` に設定し、Nginx のバージョン情報を非表示にする。

## Nginx 設定の詳細

以下のような Nginx の設定を行います。

```nginx
server {
    listen 80;
    server_name test.com;
    charset utf-8;

    location = / {
        return 301 /test.com/;
    }

    location /static/ {
        alias /app/staticfiles;
    }

    location /test.com/ {
        proxy_pass http://django:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

http {
    server_tokens off;
}
```

## 設定のポイント

### 1. `/` へのアクセスを `/test.com/` にリダイレクト

```nginx
location = / {
    return 301 /test.com/;
}
```

- ルート (`/`) へアクセスされた場合、自動的に `/test.com/` へリダイレクトします。
- `301` は恒久的リダイレクトを意味します。

### 2. `/static/` を `alias` で指定

```nginx
location /static/ {
    alias /app/staticfiles;
}
```

- `/static/` へのリクエストは `/app/staticfiles` のファイルを直接提供します。
- Django の `collectstatic` コマンドで静的ファイルを `/app/staticfiles` に集約する前提です。

### 3. Django アプリケーションへのリバースプロキシ

```nginx
location /test.com/ {
    proxy_pass http://django:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
```

- `/test.com/` へのアクセスを `http://django:8000` に転送します。
- `proxy_set_header` を使用して、クライアントのリクエスト情報を Django 側に正しく伝えます。

### 4. `server_tokens off;` でセキュリティ強化

```nginx
http {
    server_tokens off;
}
```

- `server_tokens` を `off` にすることで、Nginx のバージョン情報を非表示にします。
- セキュリティ上、Nginx のバージョン情報を隠すことは推奨されます。

## まとめ

今回、Nginx を利用した Django アプリケーションのリバースプロキシ設定について解説しました。

:::note info
***この設定により、適切なリダイレクトや静的ファイルの提供、リバースプロキシの動作を実現できることが分かりました。***
:::

実際の運用では、Nginx の設定を適切に行うことで、Django アプリケーションを安定して動作させることができます。

今後もより最適な設定を模索しながら、運用を改善していきたいと思います。
【電脳少女プログラミング2088 ─壊レタ君を再構築─】Python初心者がやってみた（カジノ編）

Pythonでなにかしたいなーと思っていた矢先にQiitaで何やらイベントをしている模様、、、
これはやるしかないと思い参加したものの仕様の部分で結構つまずき、調べながらやってクリアしました。
難しくてまだクリアできてない方などに参考にしてもらえると嬉しいです。

https://paiza.jp/entry/denno2088_qiita

【問題】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/67c7a10a-4a57-47f1-8bc0-401d82b48665.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/028cbf5f-06fd-4ac6-a911-ecc4ae2c5781.png)

Dでeasyとも書いてあったので簡単だろうと思いながらやってみると問題文がよくわからない(´･ω･`)
特に下の写真の部分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/5eec372c-eafb-4ccf-a997-eb01a44a849b.png)

「さあ、書き始めるぞ！」、、、かけない？
なぜかと悩んでいると右上から言語を選べることを発見！
そこでPython3を選択してとりあえず書いてみました。

```python:はじめの一歩
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！
input_line = input()
print("46")
```

提出前動作確認で「提出コードのアウトプット」と「期待する出力」が同じになったので、てっきりこれで大丈夫なのかと提出したら「不正解」とました。なぜだろう？と何度も考えてやっと一行ずつa、b、c、の順に改行されて入力されることを解明しました。

理解したので、もう一度書いてみると今度はちゃんと正解になりました。

```python:正解
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！

dollar_1 = int(input()) # １ドルのチップの数
dollar_5 = int(input()) # ５ドルのチップの数
dollar_10 = int(input()) # １０ドルのチップの数

# 合計金額を計算
result = (dollar_1 * 1) + (dollar_5 * 5) +( dollar_10 * 10)

print(result)
```

上のコードの解説をすると

各チップの数を`int(input())`で変数に代入
```python:５行目～７行目
dollar_1 = int(input()) # １ドルのチップの数
dollar_5 = int(input()) # ５ドルのチップの数
dollar_10 = int(input()) # １０ドルのチップの数
```

***

（１ドルのチップの数　×　１）＋（５ドルのチップの数　×　５）＋（１０ドルのチップの数　×　１０）の結果を`result`に代入

```python:１０行目
result = (dollar_1 * 1) + (dollar_5 * 5) +( dollar_10 * 10)
```

***

さっきの計算を代入した`result`を`print`で表示

```python:１２行目
print(result)
```

***

こんな感じで上のコードで問題を解くことができました。

記事を最後までお読みいただきありがとうございます！
プレゼント欲しくてやってみましたが、結構楽しくて他の問題も解こうと思ったので、他の問題も解けたら投稿したいと思います。

ではまた他の記事で会いましょう！またねーヾ(*´∀｀*)ﾉ
ピタゴラスの定理で遊ぶ。(斜辺を求めよ)(手計算で確認できる程度の整数)



参照
----

![o_coq826.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8a00a633-ea50-4199-a69a-cd9216548522.jpeg)


https://ja.wikipedia.org/wiki/%E3%83%94%E3%82%BF%E3%82%B4%E3%83%A9%E3%82%B9%E3%81%AE%E5%AE%9A%E7%90%86


注意、いろいろ
----

- 過去ログを見よ!!!
- M5NanoC6での予定は、未定
- 平方根のプログラムをせつかく作ったので

目的
----

直角三角形の斜辺を求める

ピタゴラス数の一番小さい
a = 3
b = 4
c = □

プログラム
----

オンラインコンパイラ


```c++



#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    
    //9x9=81
    //10x10=100
    //11x11=121
    
    int s;
    int y; //二乗
    int i; //カウンター
    
    int a;
    int b;
    
    printf("START\n\n");
    
    a = 3;
    b = 4;
    
    printf("a = %d\n\n",a);
    printf("b = %d\n\n",b);
    
    s = (a * a)+(b * b);
    
    printf("INPUT %d\n",s);
    printf("...\n");
    
    i = -1;
    y = 0;
    while(y <= s){ //超えた場合に抜ける
        i = i + 1;
        y = i * i;
        printf("%d=SQ(%d)\n",i,y);
    }
    i = i - 1;
    
    printf("...\n");
    printf("Answer　%d=SQ(%d)\n",i,s);
}



```


```

START

a = 3

b = 4

INPUT 25
...
0=SQ(0)
1=SQ(1)
2=SQ(4)
3=SQ(9)
4=SQ(16)
5=SQ(25)
6=SQ(36)
...
Answer　5=SQ(25)


```
RSpecでGET・POSTはどれ？

# 概要
Rspecのrequestsの部分を書く必要がありました。ここで初心者たる私は`descride`の後に続く`GET`・`POST`をどう書けばいいのかわからないのでこの記事に忘備録として残しておきます。

# 使用環境
docker・Ruby on Rails

## 方法
**コンテナ内に入る**

docker環境でプロダクトを作成しているので`exec`コマンドで中に入ってください(私たちのプロダクトはwebを使用しています。)
webの部分は`compose.yml`などを見て自身で置き換えてください

```shell
docker compose up
```
```shell
docker compose exec web bash
```

## GET・POSTを判断する
下記のコマンドを打ってGET・POSTを判断してください

```shell
rails routes | grep ◯◯◯◯◯◯◯◯
```
    
ここの◯◯◯◯◯◯の部分は自身のプロダクトの`spec/requests/admin/◯◯◯◯◯◯_spec.rb`を参考にしてください。
    今回は`release_note`の作成しているので`release_note`となっています。
    
```shell
rails routes | grep release_notes
```

## 結果

```shell
    root@2c89aaab34d5:~/deeadada# rails routes | grep release_notes
                            release_notes GET      /release_notes(.:format)                                          release_notes#index
                             release_note GET      /release_notes/:id(.:format)                                      release_notes#show
                      admin_release_notes GET      /admin/release_notes(.:format)                                    admin/release_notes#index
                                          POST     /admin/release_notes(.:format)                                    admin/release_notes#create
                   new_admin_release_note GET      /admin/release_notes/new(.:format)                                admin/release_notes#new
                  edit_admin_release_note GET      /admin/release_notes/:id/edit(.:format)                           admin/release_notes#edit
                       admin_release_note GET      /admin/release_notes/:id(.:format)                                admin/release_notes#show
                                          PATCH    /admin/release_notes/:id(.:format)                                admin/release_notes#update
                                          PUT      /admin/release_notes/:id(.:format)                                admin/release_notes#update
                                          DELETE   /admin/release_notes/:id(.:format)                                admin/release_notes#destroy
```

## あとはテストを書くだけ

あとは自身の`controller`を見てテストを書いてください

### 例
ここの中身は濁すのですが、こんな感じで自身で判断して書いてください。上記のコマンドでGET・POST等が判断で切るのでそれで書いてください。

```Ruby
describe "GET /admin/release_notes" do
    it "hogehoge" do
        ~~~~
        ~~~~
    end
end

describe "GET /admin/release_notes/:id" do
    it "hogehoge" do
        ~~~~
        ~~~~
    end
end

describe "POST /admin/release_notes" do
    it "hogehoge" do
        ~~~~
        ~~~~
    end
end
```
【NestJS × Docker】BigIntのシリアライズエラー、大目に見てくれよ - Do not know how to serialize a BigInt  - 

僕は2025年の4月からエンジニアになる学生です。
最近は趣味でNestJSを書いています。

以下が簡単なプロフィールです。
- サッカー好き
    - 国内サッカー：柏レイソルサポーター
    - 海外サッカー：プレミアリーグ、セリエA (Roma推し)
- マンガ、アニメも好き
    - ジャンプ定期購読者
    - 来世はロシア語を話したい
    - 最近はガンダムにどハマり中
- 大学は東洋大学文系
    -  恥ずかしい
- エナドリ中毒
    - 最近は4日に1本で我慢
- NestJSのロゴと色が好き
- 雀魂で雀士2に上がった

## 開発環境
今現在はDockerで以下のコンテナを作成
- バックエンド（NestJS）のコンテナ
- フロントエンド（NextJS）のコンテナ
- データベース（postgreSQL）のコンテナ
- データベースをGUIで閲覧・管理できるpgadminコンテナ

docker-compose.ymlの記述は面倒なので省きます。以下の記事に少し載せているのでぜひ確認してみてください。
[[Nestjs × Docker] prisma ORM で migration するときに躓いた話](https://qiita.com/JonyTask/items/2908373f11fe69333a08)

ORMはPrisma ORMを使用しています。

## API作成
**まずは特に何も考えずに関数を作成してみます**
```
async listUpAllTodos(){
    try {
        const todos = await this.prisma.todo.findMany();
        return todos;
    }
    catch(error) {
        console.error('Error fetching todos:', error);
        throw error;
    }
}
```
とりあえず、todosテーブルにあるデータをすべて取得する関数です。
エラーハンドリングの無意味さ、命名などは見逃してください。

さてこのままリクエストを送信すると、エラー500、Internal server error が出力されます。
最初は本当に意味が分かりませんでした。

ログを吐き出してみると、このように書いてありました。
```
Do not know how to serialize a BigInt
```
自分はidなどのカラムをbigInt型で指定していました。
どうやら標準のJSONパーサーがBigIntに対応していないためらしいです。

:::note info
※JSONパーサーとは
ただの文字列をオブジェクトとして扱う際に変換してくれるプログラムのこと
:::

なんて面倒なんだ。そのままJSONで吐き出してくれよ。
文句言っても仕方がないので、自分は以下のクラスを作成してみました。

```
export class SerializeBigInt {
    public static serialize(input: Object): Object {
        return JSON.parse(JSON.stringify(input, this.replacer));
    }

    private static replacer(key: string, value: any): any {
        if (typeof value === 'bigint') {
            return value.toString();
        }
        return value;
    }
}
```

パースする処理はさまざまな箇所で重複しそうなのでクラスにしています。
これをリターン時に呼び出します

```
async listUpAllTodos(){
    try {
        const todos = await this.prisma.todo.findMany();

        //以下が追加箇所
        return SerializeBigInt.serialize(todos);
    }
    catch(error) {
        console.error('Error fetching todos:', error);
        throw error;
    }
}
```

## 終わり
実はこれ、chatGPTのo3-mini-highモデルに助けてもらいました。
これ、めちゃめちゃ良い。
技術書買ったり、動画見たりよりも遥かに効率よく学習を進められていると感じます。
インフラなどのすぐには必要にならない領域の知識を学ぶ面白さも十分にわかるので、技術書は欲しいし、好きです。

でも、今自分が進めている個人開発しながら勉強する方法には、o3-mini-highモデルはうってつけです。

んー、openAI最高！頼むから買収されないで！
dune query by solana pumpfun instruction code

```sql
select
    account_arguments[8] as dev_addr,
    count(account_arguments[1]) as token_addr_count
from
    solana.instruction_calls
where
    executing_account = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'
    and bytearray_substring (data, 1, 8) = 0x181ec828051c0777
    -- FROM_HEX('b712469c946da122')
    and tx_success = true
    AND block_time > NOW() - INTERVAL '30' day
    -- AND block_time BETWEEN date '2025-01-01' AND date '2025-01-31'
group by
    1
order by
    2 desc
```


![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/4f0f0ed6-7717-4db0-988f-01a5f94fc044.png)

### create

https://solscan.io/tx/WxE2LLuM4x5RrSyxGbohxawQitmeAki6ENPC2uJpmNnGhBGhLB7ukL7ZhMkJh63fa9VEfDV1tbYd6CoawMDBfNa

`181ec828051c0777`

## Buy
https://solscan.io/tx/WsXdNF64Zu9JHss7jL6LGF5Ujtutg9k6qhumSxCMST8BNJzLhcazUrG3xr9qZnqx2HAa2uA78y934HW4tvUGxgJ

`66063d1201daebea`

## Sell

https://solscan.io/tx/Zz5uHncY2GZJWWLXhZG6gvahdgeRQaYL2x4SM5h86EyXaiv5gDouw5K2i9XzUxsedyfHhqZVJsxusZ3xpRFcT4L

`33e685a4017f83ad`

## withdraw

https://solscan.io/tx/2hAcVw6kr3Z3WffCpghRfMSpxYfhTKD3SEGcqPJiTgQrRxXgR1LQtarDWnyJZkJfchFyANM8yg8qYQxX21GaFuoj

`b712469c946da122`

## python code

```py
import re
from hashlib import sha256

def camel_to_snake(text):
    str1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', text)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', str1).lower()

ix_name = "Buy"
ix_name = "Sell"
ix_name = "Create"
ix_name = "withdraw"

stuff = f"global:{camel_to_snake(ix_name)}"
encode = sha256(stuff.encode()).digest()[:8]

print("action: ", stuff)
print(encode.hex())
```

## rust code

https://github.com/666pulse/solana-discriminator
KotlinプロジェクトにSpotlessリンターを導入

リンターが入っているとチームの中でスタンダートな書きっぷりができて　統一感が出て、レビューの中で表面的なことを見なくて　時間短縮になる。

本章では SpotlessとKtlinを導入する. [前回のQuarkusプロジェクト](https://qiita.com/nacho4d/items/e926b769649fe6b386d9)用に考えているが、多分どのKotlinプロジェクトでもできるでしょう。

## 1. Spotlessを導入

gradleファイルに spotlessプラグインを導入. 基本的に[公式ガイドの通り](https://plugins.gradle.org/plugin/com.diffplug.spotless)

```diff_kotlin
  plugins {
      kotlin("jvm") version "2.0.21"
      kotlin("plugin.allopen") version "2.0.21"
      id("io.quarkus")
+     id("com.diffplug.spotless") version "7.0.2"
  }
```

## 2. Spotless用の設定を追加

gradleファイルの最後ら辺に Spotlessの設定を追加。そして、buildタスクと同時に実行されるように設定を追加。 詳細は[公式ガイド](https://github.com/diffplug/spotless/tree/main/plugin-gradle#applying-ktlint-to-kotlin-files)を参照

```diff_kotlin:build.gradle.kts
  kotlin {
      compilerOptions {
          jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
          javaParameters = true
      }
  }
  
+ spotless {
+     kotlin {
+         target("src/**/*.kt")
+         ktlint("1.5.0")
+         toggleOffOn() // spotless:off / spotless:onで一時的にオン・オフ可能とする
+     }
+ }
+ // Spotless: buildタスクと同時に spotlessもapplyする
+ tasks.named("build") {
+     dependsOn("spotlessApply")
+ }
```

## 3. rulesを導入
gradleファイルにルールを書くこともできるが、できればlinter関連のことを最低限にして、アプリのビルド関連のことにしたい。spotless/ktlintもeditorconfigファイルに対応しているため 以下にファイルで別管理が可能。

プロジェクトのルートに導入。

```ini:.editorconfig
root = true

[*]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[*.kt]
max_line_length = 160
```

また、必要に応じて、プロジェクトの別のフォルダーに.editorconfigを追加することもできる。root=falseにすれば良い

```ini:src/native-test/kotlin/com/ibm/jp/.editorconfig
root = false

# このフォルダー配下のルールを記入
rule = value
```

以上！

See you later!🐊
cursor使ってみた

# はじめに
今更ですが、今流行ってるコードエディタのCursorを使ってみました。
開発言語はこれも流行っているRemixで、チュートリアルの内容を行おうと思います。

# UI
VScodeのフォークなので、ほとんど同じです。
普段からVScodeを使用している方は特に違和感ないかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110243/6d15d13b-b6ee-455e-bb48-df249b06049b.png)

# 機能
機能は主に、以下四つになります（公式より）
* Tab キー
* チャット
* エージェント
* Ctrl K　

詳しくは公式をご確認ください↓

https://www.cursor.com/ja/features

# 使ってみた感じ
正直めちゃくちゃいいです。
中でもtab補完がすごいと感じました。

書こうと思ったソースを、AIが予測してくれて、すべて補完してくれます。
大枠だけで言うと１ファイル10秒くらいで作ってくれる。。。。

あとCSSとかも保管してくれるので、苦手な人はめちゃくちゃ楽だと思います。

こんな感じ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110243/a955117e-f929-4ab5-828d-b57484dea4b4.png)

また、エラーの原因特定なども、AIチャットで具体的に教えてくれます。
（これはほかのチャットツールに投げるのとそんなに大差ないかな。。。）

# 最後に
cursor 思ったより使い勝手すごいよかったです。
ただ、自分のコーディングのへの理解が下がってしまうと思ったりもしました。
AIを使いこなす力のほうが今後は大事だとは思いますが。。

開発速度が爆速になるので、皆さんもぜひ使ってみてください。
【GAS】ランダムでお掃除当番を選任してSlackに投稿するBotの作り方

# はじめに
弊社では可能なことはできる限り自動化する方針で雑務を調整しています。
その中の一つとして、毎週のお掃除当番をそれぞれ選任するBotを運用しているのですが、なかなか便利なので備忘録も兼ねて残しておこうと思います。

# Botの実装方法
今回のゴールとして、毎週決まった曜日の決まった時間にBotが実行されるようにします。

また、Botの実装はGAS(Google Apps Script)を使用して実装します。

https://script.google.com/home?hl=ja

実装の詳細は以下になります。

```
function handler() {
  // Slack の "メンバーID" を指定する
  const members = [
    "AAAAAA", 
    "BBBBBB", 
    "CCCCCC", 
    "DDDDDD", 
    "EEEEEE"
  ];

  for(var i = members.length - 1; i > 0; i--){
    var r = Math.floor(Math.random() * (i + 1))
    var tmp = members[i]
    members[i] = members[r]
    members[r] = tmp
  }

  const pair = 
`
来週のお掃除担当は<@${members[0]}>さんと,<@${members[1]}>さん
`;

  const incomingWebhookUrl = "Slackで投稿したいチャンネルのWebHookUrlを指定してください";
  // Slack に投稿
  UrlFetchApp.fetch(incomingWebhookUrl, {
    "method": "post",
    "contentType": "application/json",
    "payload": JSON.stringify(
      {
        "text": pair,
      }
    )
  });
}
```
実装は以上になります。
選任ロジックや投稿する際のメッセージはあくまでサンプルとしての内容になっているので、ご利用の際にそれぞれに合った実装で調整してあげてください。

また注意点として、コメントにもありますがメンションをつける場合には**必ずメンバーID**を指定するようにしてください。
メンバーIDを指定しないと、日本語のユーザーなど一部のメンバーだけメンション化されないみたいな問題が起きます。

上記を実装したらあとは、画面左のトリガーから定期実行の間隔などを指定してあげる形になります。
設定の内容は以下を参考にしてみてください。

![スクリーンショット 2025-02-23 18.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/4e20a89e-515d-4546-866b-0625c5b45939.png)

Botの設定は以上です、GASめちゃくちゃ便利です。

# さいごに
最近体重が落ちなくなってきました、悲しい
【初心者向け】画面エビデンスの取り方・基本編（画像／動画編／Windows11）

:hatched_chick: **はじめに**
今回は、IT現場でよく使用されるエビデンスの取り方（画像／動画編）をご紹介します。
※OSがWindows11の場合を想定しています。

この記事は、未経験からSESに転職後7年目の梅干しとにらめっこが、これから現場で活躍される、もしくは現場参画を目指されている方向けにお届けします。
もちろん純粋に画面を残す方法が知りたいだけだよって方も大歓迎です。
## 目次
- **0.そもそもエビデンスってなに？**
- **1.画像編**
    - 1-1画面全体をキャプチャする
    - 1-2画面の一部を切り取ってキャプチャする
- **2.動画編**
    - 2-1指定した位置の動画を切り取る

## 0.そもそもエビデンスってなに？
**エビデンス**は、主にテスト工程時・バグ発見時等に、システムが正常に動作していることやバグが発生していることを証明する **「証拠」** の意味合いで使用されることが多いです。
※設計段階で、システム設計が正しいことの意味合いで使用されることもあります。

エビデンスの形式は現場のルールや使用しているシステムによって様々です（画像、テキスト、Excel形式、json形式等）。

:::note info
現場が **「何をエビデンスとしているのか」** は、きちんと確認しておきましょう。
:::

今回は画像／動画で残す場合の基本的な操作をご説明します。

## 1.画像編
#### 1-1画面全体をキャプチャする
- まずは以下どちらかのキーを押します。
    - キーボードの[prt scキー]（Print Screen キー）
    - ショートカット:[Shiftキー] + [Windowsロゴキー] + [S]
※[Shiftキー]が見つからない場合は、[⇧]ボタンのことを指しています。



すると、以下のような設定画面が画面上部に表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/3b8a020f-6607-4c90-a796-3bcf49832270.png)

②この状態で、画面全体が暗くなりますので設定画面右側の[ v ]ボタンを押下→出てきたオプションのうち **[全画面表示]** を選択してください。

これで***拡張ディスプレイを含む全画面***のコピーがとれました。
※1画面だけをコピーしたい場合は、 **[ウィンドウ]** を選択してください。
どこかに貼りつけてもいいですし、コピー後に画面右下へ **「Snipping Tool」** のダイアログが出てきますので、それをクリックするとコピーした画像の編集も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/1d775942-fa78-4142-8868-47d1f56aedf4.png)

#### 1-2画面の一部を切り取ってキャプチャする
- まずは以下どちらかのキーを押します。
    - キーボードの[prt scキー]（Print Screen キー）
    - ショートカット:[Shiftキー] + [Windowsロゴキー] + [S]
※[Shiftキー]が見つからない場合は、[⇧]ボタンのことを指しています。

すると、以下のような設定画面が画面上部に表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/3b8a020f-6607-4c90-a796-3bcf49832270.png)

②この状態で、画面全体が暗くなりますので切り取りたい箇所の左上から右下まで、マウスをドラッグしたまま移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/891a58da-1593-4685-994b-19433cc4c778.png)

これで***一部選択した箇所のみ***のコピーがとれました。
どこかに貼りつけてもいいですし、コピー後に画面右下へ **「Snipping Tool」** のダイアログが出てきますので、それをクリックするとコピーした画像の編集も可能です。

## 2.動画編
#### 2-1指定した位置の動画を切り取る
- まずは以下どちらかのキーを押します。
    - キーボードの[prt scキー]（Print Screen キー）
    - ショートカット:[Shiftキー] + [Windowsロゴキー] + [S]
※[Shiftキー]が見つからない場合は、[⇧]ボタンのことを指しています。

すると、以下のような設定画面が画面上部に表示されます。〇の箇所を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/622f619b-b643-4d78-ad68-6099ad6fba67.png)

②この状態で、画面全体が暗くなりますので切り取りたい箇所の左上から右下まで、マウスをドラッグしたまま移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089043/891a58da-1593-4685-994b-19433cc4c778.png)

③画面上部にスタートボタンとマイクマークが出てきます。
 スタートボタンを押下します。

④3秒のカウント後に録画が開始されます。録画が完了したら。[❑]ボタンで終了できます。その他、一時停止も可能です。

## **最後に**:hatched_chick:
本日も最後までご覧頂きありがとうございました！
今回の方法は、チャットで仕様の質問をしたい場合などにもよく使う方法です。

参考：[Microsoft-Snipping Tool を使ってスクリーン ショットをキャプチャする](https://support.microsoft.com/ja-jp/windows/snipping-tool-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3-%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%82%92%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%81%99%E3%82%8B-00246869-1843-655f-f220-97299b865f6b#section-1_tabControl-1=Windows_10)

**素敵なITライフをお過ごしください！**
OpenWhiskを使い簡単な利用の仕方を確認してみる

# 目的
構築した検証用環境を用い、WebUI上でのリソース登録、登録リソースのリモート呼び出し、リモートからのリソース登録などについて、簡単なサンプルコードを用い動作確認していきたいと思います。

# Playground(WebUI)からの公開(Publish)
WebUIからGo言語で作成されたサンプルコードを公開していきます。ブラウザでPlygroundを開き、Publishボタンを押下します。押下する左上の「URL」が、「editable, private]から「Readonly, public at http://xxxx」に更新されました。

![Go Sample Code](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50452/f392c96a-63a5-427f-814e-e5707674e90d.png)
![Go Sample Code Publish](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50452/3a3d2ca2-5442-4226-aa91-d67f6e7e4b4e.png)


URL: Readonly, public at http://192.168.11.55:13233/api/v1/web/whisk.system/user283538/sampleGo

# 公開されたサービスを呼び出してみる

引数なしでCLIにて対象サービスを呼び出してみます。引数nameを指定していないためコード固定のstrangerの文字列がレスポンスに現れていることを確認できました。

```bash
$ curl http://192.168.11.55:13233/api/v1/web/whisk.system/user283538/sampleGo
Hello, stranger!$ 
```

# 変数付与したGETメソッドによる呼び出し
では、次に引数nameにGolangを設定しGETメソッドを用いリクエストしてみます。想定通りリクエストパラメータを理解しレスポンスを作成してくれている様です。

```bash
$ curl http://192.168.11.55:13233/api/v1/web/whisk.system/user283538/sampleGo?name=Golang
Hello, Golang!$ 
```

# 変数付与したPOSTメソッドによる呼び出し

次に、リクエストをjson形式で与えてみます。明示的にヘッダーにjsonを指定しないとエラーになりますね。指定して再実行すると問題なく処理されている様です。

```bash
$ curl -X POST http://192.168.11.55:13233/api/v1/web/whisk.system/user283538/sampleGo -d '{"name": "Golang2"}'
{"code":"mCfNUwgfLOEVL0WIZqYXBqXXXLOVEiftiOyE","error":"Illegal query: Invalid input ' ', expected '+', '=', query-char, 'EOI', '&' or pct-encoded (line 1, column 9): {\"name\": \"Golang2\"}\n        ^"}$
$ curl -X POST http://192.168.11.55:13233/api/v1/web/whisk.system/user283538/sampleGo -d '{"name": "Golang2"}' -H "Content-Type: application/json"
Hello, Golang2!$ 
```
ここまでは割と順調に進めらている感じがします。次は、CLIでサービスを作成してみましょう。

# CLIによるサービスの作成
hello.jsというJavaScriptで作成したファイルを準備し公式ドキュメントに従い実行した所、以下エラーとなりうまくいかなかったので今回はここで終了としたいと思います。

```bash
$ wsk action create myAction hello.js 
error: Unable to create action 'myAction': Unable to create HTTP request for PUT 'actions/myAction?overwrite=false': Unable to add the HTTP authentication header: Authorization key is not configured (--auth is required)
Run 'wsk --help' for usage.
```
Java: record class とは？

# record class とは

## 特徴
- フィールドがイミュータブル(```private final```)
    - 一度インスタンス化した後に、値を変更できない
- 下記が自動的に作成される
    - コンストラクタ
    - getter
    - equals
    - hashCode
    - toString

## 使い方

```java
// クラス名の前にrecordをつける
record Rectangle(double length, double width) { }
```
下記の記述と同等
```java
// record使わない場合
public final class Rectangle {
    private final double length;
    private final double width;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    double length() { return this.length; }
    double width()  { return this.width; }

    // Implementation of equals() and hashCode(), which specify
    // that two record objects are equal if they
    // are of the same type and contain equal field values.
    public boolean equals...
    public int hashCode...

    // An implementation of toString() that returns a string
    // representation of all the record class's fields,
    // including their names.
    public String toString() {...}
}
```

## 使用場面
- 不変でシンプルなデータを持ちたい時
- 計算処理や状態遷移などを行わない時

# 参考
https://docs.oracle.com/javase/jp/15/language/records.html
# SafariでTailwindの`break-words`を使うとレイアウトがぶっ壊れる問題について 🧭

## 環境
- **Tailwind CSS**: v3.4.16
- **ブラウザ**: Safari Version 17.5

## 現象
Safariでは、`break-words`クラスを適用しても`break-normal`と変化がなく、単語が正しく折り返されません。また単語が折り返されず改行が行われないため下記のようにレイアウトがぶっ壊れてしまいます。

![messageImage_1740299169016.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3905122/d61fa712-c53d-49a8-8824-afac313f4f8d.jpeg)


## 調査と考察
Safari特有のレンダリングバグのようで、ウィンドウリサイズ時やクラスのオンオフで一時的に正常な動作が確認されるものの、根本的な問題はWebKit側の不具合らしいです。

下記GithubのIssue
*[https://github.com/tailwindlabs/tailwindcss/issues/8743](https://github.com/tailwindlabs/tailwindcss/issues/8743)*

## 回避策
以下のCSSを適用することで、Safariでも期待通りの挙動を実現できます。
単語ごとに改行せず、normalで改行させるようにしました。

```css
@supports (-webkit-touch-callout: none) {
  .break-words {
    word-break: normal !important;
    overflow-wrap: normal !important;
  }
}
```

## 余談
これのせいで位置時間悩みましｔ
[Linux][command] ファイルシステム管理_XFSファイルシステム管理_mkfs, xfs_

# XFSファイルシステム操作コマンド
| コマンド     | 英語の由来           | 説明 |
|:-------------|:---------------------|:-------|
| `mkfs.xfs`   | make filesystem      | XFSファイルシステムを作成する|
| `xfs_info`   | information          | XFSファイルシステムの詳細情報を表示する |
| `xfs_db`     | debug                | XFSファイルシステムのデバッグを行う |
| `xfs_check`  | check                | XFSファイルシステムの整合性をチェックする |
| `xfs_fsr`    | filesystem reorganizer | XFSファイルシステムのデフラグを行う<br>(断片化を解消しファイルの連続性を向上させる) |
| `xfs_repair` | repair               | XFSファイルシステムの修復する |

## 使用例

### XFSファイルシステムを作成
~~~terminal
# mkfs.xfs /dev/sdb1
~~~
- `/dev/sdb1` にXFSファイルシステムを作成

### マウントされたXFSファイルシステムの詳細情報を表示
~~~terminal
# xfs_info /mnt/data
~~~
- `/mnt/data` にマウントされたXFSファイルシステムの詳細情報を表示

### XFSファイルシステムの整合性をチェック
~~~terminal
# xfs_check /dev/sdb1
~~~
- `/dev/sdb1` のXFSファイルシステムをチェック

### XFSファイルシステムのラベルを変更
~~~terminal
# xfs_admin -l "NewLabel" /dev/sdb1
~~~
- `/dev/sdb1` のラベルを `"NewLabel"` に変更

### XFSファイルシステムのデバッグ
~~~terminal
# xfs_db /dev/sdb1
~~~
- `/dev/sdb1` のXFSファイルシステムをデバッグモードで開く

# Ping-t
- [3230_xfs_check](https://mondai.ping-t.com/question_subjects/31/question_sessions/30870646/progressing_questions/472924563)
- [3227_xfs_info](https://mondai.ping-t.com/question_subjects/31/question_sessions/31140772/progressing_questions/477192464)
- [3369_xfs_fsr](https://mondai.ping-t.com/question_subjects/31/question_sessions/32448701/progressing_questions/497231315)
- [3370_xfs_repair](https://mondai.ping-t.com/question_subjects/31/question_sessions/32581786/progressing_questions/499228232?result=true)
pubmedのreferenceをいい感じに整形するjavascript書いた【tampermonkey】

joslerや退院時サマリーの考察にご使用ください
↓使用例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2847174/b8805255-86ba-42a7-ab1f-a33d35e584bd.png)


```javascript:pubmed reference 整形
// ==UserScript==
// @name         pubmed reference 整形
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://pubmed.ncbi.nlm.nih.gov/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=nih.gov
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
　　//必要な箇所の文字を抜き出す
    const publish = document.querySelector('#full-view-journal-trigger').innerText;
    const cit = document.querySelector('#full-view-heading > div.article-citation > div > span.cit').innerText;
    const doi = document.querySelector('#full-view-heading > div.article-citation > span.citation-doi').innerText;
    const title = document.querySelector('#full-view-heading > h1').innerText;
    const author_1 = document.querySelector('#full-view-heading > div.inline-authors > div > div > span:nth-child(1) > a').innerText;
    const author_2 = document.querySelector('#full-view-heading > div.inline-authors > div > div > span:nth-child(2) > a').innerText;
    //htmlを出力
    const markup = `
  <div id="bookinfo" style="background:#333;color:#36d184;padding:.5em;text-align:start;font-family:sans-serif;">
  ${author_1},${author_2},et al.${title}:${publish} ${cit} ${doi}
  </div>
  `
    //htmlを差し込み
    document.querySelector("#article-page").insertAdjacentHTML("beforebegin", markup);

})();

```
Atcoder 備忘録_N個の整数からX個を選択

# 概要

- 競技プログラミングを始めてみた。
  せっかくなので１テーマごとに解法と学びをアウトプットしてみる。

# 取り組む内容
- [鉄則本](https://atcoder.jp/contests/tessoku-book) に沿って実施する。
- ![鉄則本.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636949/7525f26c-5077-422b-b6b6-cbfab34ef327.jpeg)
- 言語は Python
- 今回テーマは「B03 - Supermarket 1」
- 
# 問題文
- N 個の商品があり、商品i(i=1,2,⋯,N) の価格はAi円です。  
- 異なる3つの商品を選び、合計価格をピッタリ1000 円にする方法は存在しますか

# 制約
- 3≤N≤100
- 1≤Ai≤1000
- 入力はすべて整数

# 出力
合計を1000円にする方法が存在する場合Yes、そうでない場合Noと出力してください。

# 解法
#### 1回目
```
N = int(input())
A = list(map(int, input().split()))
Answer = False

binary_list = [[int(digit) for digit in format(i, f"0{N}b")] for i in range(2**N)]
candidate_list = []
for list_i in binary_list:
    if sum(list_i) == 3:
        candidate_list.append(list_i)

for list_i in candidate_list:
    sum_kakaku = sum([x for x, y in zip(A, list_i) if y == 1])
    if sum_kakaku == 1000:
        Answer = True
        break

if Answer:
    print("Yes")
else:
    print("No")
```

# 結果
#### 1回目
- TLEでタイムアウト
- Runtime： 1112 ms
- メモリ：120016 KB

正解はできるが処理効率が悪く、タイムアウトエラー  
リスト内包表記も含めるとfor文を回しすぎか...

# 解法
#### 2回目
```
N = int(input())
A = list(map(int, input().split()))

Answer = False
for i in range(N):
    for j in range(i+1, N):
        for k in range(j+1, N):
            if A[i] + A[j] + A[k] == 1000:
                Answer = True
                break

if Answer == True:
    print("Yes")
else:
    print("No")
```

# 結果
#### 2回目
- AC
- Runtime： 27 ms
- メモリ：8704 KB

一気に数値がよくなった。
1回目と比較して無駄な処理（sum(list_i) == 3のところとか）を除外した。

# 思想
- リストAiからいくつかの要素をピックアップするのに二進法を使ってやってみた

# 学び
- 二進法を使うアイデア自体は悪く無いとおもいつつ、今回は無理にfor文を使用して整形する必要があったのでかえって逆効果だった
- やっぱりfor文は無闇やたらに使いすぎるのは良くない

# 感想
- At coder始めてみた。Leet codeでは投稿者全体分布のうち自分のランタイムがどの位置にいたかがわかったがAt coderではその機能が無さげなのが残念
- とはいえ、ならでは機能もあるのでしばらくはこっちでしてみる。