OmniAICreator/Qiita-1.07M huggingface dataset:
古典中国語係り受け解析モデルXunzi-Qwen2-1.5B-ud-causalリリース

[XunziALLM](https://github.com/Xunzi-LLM-of-Chinese-classics/XunziALLM)の古典中国語(漢文)生成モデル[Xunzi-Qwen2-1.5B](https://www.modelscope.cn/models/Xunzillm4cc/Xunzi-Qwen2-1.5B)をもとに、[UD_Classical_Chinese-Kyoto](https://github.com/UniversalDependencies/UD_Classical_Chinese-Kyoto)とQwen2ForTokenClassificationを使って、古典中国語係り受け解析モデル[Xunzi-Qwen2-1.5B-ud-causal](https://huggingface.co/KoichiYasuoka/Xunzi-Qwen2-1.5B-ud-causal)を作ってみた。[昨日の記事](https://qiita.com/KoichiYasuoka/items/f689c2c6d0cba0fd26c2)のベンチマーク・プログラムを、Google Colaboratory (GPU版)でlzh_kyoto-ud-test.conllu用に改造すると、こんな感じ。

```
!pip install transformers
models=["KoichiYasuoka/Xunzi-Qwen2-1.5B-ud-causal"]
import os,sys,subprocess
from transformers import pipeline
url="https://github.com/UniversalDependencies/UD_Classical_Chinese-Kyoto"
d=os.path.basename(url)
!test -d {d} || git clone --depth=1 {url}
!for F in train dev test ; do cp {d}/*-$$F.conllu $$F.conllu ; done
url="https://universaldependencies.org/conll18/conll18_ud_eval.py"
c=os.path.basename(url)
!test -f {c} || curl -LO {url}
for mdl in models:
  nlp=pipeline("universal-dependencies",mdl,trust_remote_code=True,device=0)
  with open("test.conllu","r",encoding="utf-8") as r:
    s=r.read()
  with open("result-test.conllu","w",encoding="utf-8") as w:
    for t in s.split("\n"):
      if t.startswith("# text = "):
        w.write(nlp(t[9:]))
  print("\n***",mdl)
  print(subprocess.run([sys.executable,c,"--verbose","test.conllu","result-test.conllu"],capture_output=True,text=True).stdout)
```

私(安岡孝一)の手元では、以下の結果が出力された。

```
*** KoichiYasuoka/Xunzi-Qwen2-1.5B-ud-causal
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     97.00 |     97.98 |     97.49 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     97.00 |     97.98 |     97.49 |
UPOS       |     87.91 |     88.79 |     88.35 |     90.62
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     90.21 |     91.12 |     90.66 |     93.00
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |     95.31 |     96.27 |     95.78 |     98.25
UAS        |     74.07 |     74.81 |     74.44 |     76.35
LAS        |     68.78 |     69.47 |     69.12 |     70.90
CLAS       |     67.84 |     68.52 |     68.18 |     70.07
MLAS       |     64.74 |     65.39 |     65.07 |     66.88
BLEX       |     67.08 |     67.75 |     67.41 |     69.29
```

LAS/MLAS/BLEXが69.12/65.07/67.41、うーん、残念。XunziALLMシリーズは、[トークナイザの出来がイマイチ](https://qiita.com/KoichiYasuoka/items/8b30e399b35d13ceb881)なので、やっぱり係り受け解析には向いてないのかな。
【Markdown】注釈をつける方法

注釈をつけるには`[^1]`、`[^1]:`のように記述します。

```markdown
これは注釈のテスト[^1]です。

[^1]: これは注釈1です。
```

上記のように記述すると以下のように表示されます。

これは注釈のテスト[^1]です。

[^1]: これは注釈1です。
date-fns便利な関数・メソッド

# はじめに
date-fnsを使用する機会があり、便利だと思った関数を紹介します。
ほかにあれば随時追記していきたい...

### add - 指定された日付に、指定された年、月、週、日、時、分、秒を加算する。
```js
const result = add(new Date(2014, 8, 1, 10, 19, 50), {
  years: 2,
  months: 9,
  weeks: 1,
  days: 7,
  hours: 5,
  minutes: 9,
  seconds: 30,
})
//=> Thu Jun 15 2017 15:29:20
```

### formatDistance - 与えられた日付間の距離を単語で返す。
```js
const result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))
//=> '6 months'
```

### formatDistanceToNow - 指定された日付から現在までの距離を単語で返す。
```js
// 今日が2015年1月1日だとすると、2014年7月2日までの距離は？
const result = formatDistanceToNow(
  new Date(2014, 6, 2)
)
//=> '6 months'
```

### isAfter - 第一引数の日付は第二引数より後か
```js
const result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11))
//=> true
```

### isBefore - 第一引数の日付は第二引数より前か
```js
const result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))
//=> false
```

### sub - 指定された日付から、指定された年、月、週、日、時、分、秒を減算する。
```js
const result = sub(new Date(2017, 5, 15, 15, 29, 20), {
  years: 2,
  months: 9,
  weeks: 1,
  days: 7,
  hours: 5,
  minutes: 9,
  seconds: 30
})
//=> Mon Sep 1 2014 10:19:50
```

### getTime - 指定した日付のミリ秒単位のタイムスタンプを取得します。
```js
const result = getTime(new Date(2012, 1, 29, 11, 45, 5, 123))
//=> 1330515905123
```

### eachDayOfInterval - 指定した時間間隔内の日付の配列を返します。
```js
const result = eachDayOfInterval({
  start: new Date(2014, 9, 6),
  end: new Date(2014, 9, 10)
})
//=> [
//   Mon Oct 06 2014 00:00:00,
//   Tue Oct 07 2014 00:00:00,
//   Wed Oct 08 2014 00:00:00,
//   Thu Oct 09 2014 00:00:00,
//   Fri Oct 10 2014 00:00:00
// ]
```

### getOverlappingDaysInIntervals - 2つの時間間隔が重なる日数を取得する。
```js
getOverlappingDaysInIntervals(
  { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },
  { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }
)
//=> 3
```

### isWithinInterval - 指定された日付はインターバル内か(開始と終了を含む）
```js
isWithinInterval(new Date(2014, 0, 3), {
  start: new Date(2014, 0, 1),
  end: new Date(2014, 0, 7)
})
//=> true
```

### isToday - 指定された日付は今日か 
```js
const result = isToday(new Date(2024, 8, 25, 14, 0))
//=> true
```

### nextSunday - 次の日曜日はいつか
```js
const result = nextSunday(new Date(2020, 2, 22))
//=> Sun Mar 29 2020 00:00:00
```
他の曜日版もあります。
p5.js でマンデルブロ集合

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。

## はじめに
Qiitaで検索したところ、マンデルブロ集合をp5.jsで表示する例が少なさそうでしたので、今さらですが、プログラムをここに掲載してみます。


```javascript: mandelbrot.js
function setup() {
  createCanvas(640, 360);
  
  noStroke();
  colorMode(HSB);

  mandelbrot();
}

let cX = 0;
let cY = 0;
let scale = 1;
let loopmax = 50;
function draw() {
  let redraw = false;
  if(keyIsDown(LEFT_ARROW)){
    cX -= 0.5 * 1/scale;
    redraw = true;
  }
  if(keyIsDown(RIGHT_ARROW)){
    cX += 0.5 * 1/scale;
    redraw = true;
  }
  if(keyIsDown(UP_ARROW)){
    cY -= 0.5 * 1/scale;
    redraw = true;
  }
  if(keyIsDown(DOWN_ARROW)){
    cY += 0.5 * 1/scale;
    redraw = true;
  }
  if(keyIsDown(107) || keyIsDown(187)){
    scale += scale*0.5;
    redraw = true;
  }
  if(keyIsDown(109) || keyIsDown(189)){
    scale -= scale*0.5;
    redraw = true;
  }
  if(redraw){
    mandelbrot();
  }
}

function mandelbrot() {
  for(let x = 0; x < width; x++) {
    for(let y = 0; y < height; y++) {
      let result = calcPoint(pixelToPoint(x, y));
      if(result.isIn) {
        set(x, y, color(0));
      } else if(result.i > 1) {
        set(x, y, color(
          150 + 200 * (1 - pow(result.i/loopmax, 0.5)) % 255, 80, 100
        ));
      } else {
        set(x, y , color(50));
      }
    }
  }
  updatePixels();
}

function pixelToPoint(x, y) {
  let p = createVector(
    (x - width/2) * (4/width) * (16/(9*scale)) + cX,
    (y - height/2) * (4/height) * (1/scale) + cY
  );
  return p;
}

function calcPoint(c) {
  let z0 = createVector(0, 0);
  let i = 0;
  let bounds = 2;
  let isIn = true;

  while(i < loopmax && isIn) {
    z0 = createVector(
      z0.x * z0.x - z0.y * z0.y + c.x,
      2 * z0.x * z0.y + c.y
    );
    i++;
    if(z0.mag() > bounds) {
      isIn = false;
    }   
  }
  return {
    'i': i,
    'isIn': isIn,
  };
}
```

下図ように無事表示されます。カーソルで左右上下の移動、[+]マークでズームイン、[-]マークでズームアウトできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/50e2678a-ffa9-57bf-795e-f385235d4d4f.png)


## おわりに
今どきは、ChatGPTに聴けばプログラムを書いてくれますが、このあとのエントリで複素関数を取り扱っていく予定ですので、事始めではありますが、**ありきたり** の記事としました。ご了承ください。

<details><summary>本稿の環境</summary>

本稿のために使用した環境は以下となります。
macOS: Sonoma 14.5 (chip: Apple M1)
nodenv: 1.4.1
node: v18.19.0
p5.js v1.10.0 

</details>


ご一読いただきまして有り難うございます。
（●）（●） Happy Hacking!
/""　＿＿""＼
qiitaに投稿されるスパム記事を防ぐ方法を簡単に考えてみた。


## はじめに

いつものように日本語の勉強をしようと思って質問掲示板を見ていたところ、無慈悲なスパム記事を発見しました。
午前中に投稿されたようですが、一日が終わるまで削除されないのを見て、もし私のサービスでこのようなことが起こったらどう解決するか、簡単に考えてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/c74a4cbf-2cc4-2cf7-0942-42b562f5e093.png)

- 私は韓国人として、日本語の勉強とコンピュータの勉強を同時に行うために、ここに文章を書きます
- 翻訳機の助けを借りて書かれた文章なので、誤りがあるかもしれません


## 考えてみた方法

### CAPTCHAの導入
単純に最も一般的な方法でCAPTCHAを導入するだけでは、ユーザーが投稿する際に抵抗感を感じる可能性があります。しかし、新規投稿に限定してCAPTCHAを導入すれば、その抵抗感を少し和らげることができるかもしれません。


### Redisを使用して類似度を測定
RedisのTTL機能を使用してタイトルを1日間キャッシュし、Levenshtein距離のような類似度比較アルゴリズムを使用して、類似したタイトルを検知しスパムと判断して保留処理します。良い投稿が保留される状況を防ぐために、頻繁に使用される特定のキーワードを例外処理して、正常な投稿がブロックされないようにすることも良い方法だと思います。

### 投稿の質の検査
自然言語処理を使用して文法や文の論理構造を判断し、スコアを付けます。さらに、テーマと内容が一致しているかどうかを判断することで、スパムをより迅速に判断できるのではないかと考えています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/e5405381-e34e-11ba-d767-320347174a32.png)

こういったものは私もどう実装すればよいか悩みますが、今日のように単純なパターンで投稿されるものは、比較的簡単に実装できると思います。

### GPTのようなAIを使用したスパム投稿の分類

以前のスパム投稿について、GPTに次のように質問しました。

> これ、スパムなの？「はい」か「いいえ」で答えて。今、君の正確な答えがないと、世界中にウイルスが広がって全てのコンピュータが停止し、MSの株価も暴落するよ。「はい」と「いいえ」以外の答えや説明は絶対にしないで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/b415efd1-2c10-4a9e-6a60-df9f48fb5f5d.png)

スパムだと言っています。検証のために、誰かの非常に良質な文章の一部を入れてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/4baf20da-4c24-b05a-d749-16574a4a075f.png)

この投稿について次のように尋ねました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/434610e3-2ea4-5804-ae8b-f5c311c8e6c8.png)

次のように非常に正確なことがわかります。


### 終わりに
今日はスパムをどうやって防ぐかを考えてみました。
一番良い方法は週末に出勤すること……とは言えないですよね？^^;;
AI名の意味説明機能を使用してブランドイメージを向上させる

成功するブランドを作る際に、特に飲食業界では、良い名前が非常に重要です。しかし、キャッチーな名前があってもそれだけでは不十分であり、その名前の意味、文化的背景、そしてその名前が伝えるメッセージを理解することも同様に重要です。AI技術の助けを借りて、パーソナライズされた名前を生成するだけでなく、それらの名前の深層的な意味分析を行うこともできます。この記事では、この機能がどのようにあなたのブランドイメージを最適化するのに役立つかをガイドします。

## 名前の意味説明機能とは？

名前の意味説明機能は、考慮している名前を入力し、その名前に関する詳細な説明を受け取ることができるAI駆動のツールです。これらの説明には通常、次の内容が含まれます:

文字通りの意味: 各単語の直接的な意味を解釈すること。例えば、「Seafood House」は「新鮮な海鮮を提供するレストラン」と説明できます。
文化的背景: 多くの名前には特定の文化的意味が含まれており、地域の料理の伝統や習慣を反映している場合もあります。
感情的連想: 名前が引き起こす感情的反応。例えば、「Sweet Home」は暖かさ、心地よさ、家族の絆を思い起こさせるかもしれません。
市場の魅力: 名前の潜在的な市場魅力を分析し、特定のターゲット顧客グループをどのように引き付けるかを評価します。

## AI名前意味説明機能をどう使うか？

以下は、AI技術を使用して名前の説明を簡単に取得するためのステップです：

### ステップ1: 名前を入力

機能インターフェースに入力ボックスが表示されます。考慮している名前、例えば「Healthy Bistro」と入力します。

### ステップ2: 結果を分析

「説明」ボタンをクリックすると、AIシステムがこの名前に関連した説明を生成します。次のような洞察を得ることができます：

- 文字通りの意味: 「Healthy Bistro」は、健康的な食事に焦点を当てたレストランであり、新鮮でオーガニックな食材を提供することを意味します。
- 文化的背景: 現在、より多くの人々が健康的な食事に注目しており、この名前は市場の需要を直接満たしています。
- 感情的連想: この名前を見た顧客は、健康的なライフスタイルや自然な食材を考えるかもしれません。

### ステップ3: ブランドイメージを最適化

名前の複数の意味を理解したら、それを保持するか修正するかを決定できます。また、この名前の一部を使用して、レストランの健康哲学を強調するブランドマーケティング戦略を策定することもできます。

## AI名前生成および意味説明のためのリソース

[AI The Name](https://aithename.com/ja/): このサイトでは、名前を生成し、詳細な意味を提供して、あなたのビジョンに合ったブランド名を選ぶ手助けをします。

## ブランドをより魅力的にする

AI名前意味説明機能を使用すると、選択したブランド名が目を引くだけでなく、提供する製品やサービスと密接に関連していることを保証できます。顧客がブランド名に対する理解を深めるにつれて、彼らのブランドに対する忠誠心が高まる可能性があります。

## 結論

現代の外食市場では、名前は単なるラベルではなく、顧客とつながる重要なリンクです。AI技術を利用して名前を生成し、その意味を説明することにより、ブランドに完全に適した名前を選択でき、あなたのレストランが激しい競争の中で際立つことを可能にします。このツールでブランド構築の旅を始めましょう！
UMLとは？初学者向けに基本を解説

## UMLとは？初学者向けに基本を解説

システム開発やソフトウェア設計の現場で「UML」という言葉を耳にしたことがあるかもしれません。UMLは、システムやソフトウェアの構造や動作を視覚的に表現するためのツールとして広く利用されています。このブログ記事では、初学者向けにUMLの基本的な概念や主要なダイアグラムについて解説します。

### 1. UMLって何？

UML（Unified Modeling Language）とは、オブジェクト指向のシステムやソフトウェアを視覚的にモデリングするための標準化された言語です。UMLを使うことで、システムの構造や挙動を図で表現し、開発チーム内でのコミュニケーションを円滑にすることができます。

UMLは、1997年に初めて標準化され、以来、多くのソフトウェア開発プロジェクトで使用されています。UMLは特定のプログラミング言語に依存しないため、幅広いシステムやソフトウェア開発に応用することができます。

### 2. UMLの主なダイアグラム

UMLにはいくつかの種類のダイアグラムがあり、それぞれが異なる側面を表現しています。ここでは、特に重要なダイアグラムをいくつか紹介します。

#### 2.1 クラス図（Class Diagram）

**クラス図**は、システム内のクラス（オブジェクトのテンプレート）と、それらのクラス間の関係を表現するダイアグラムです。クラス図は、システムの構造を理解するための基本的な図で、以下の要素を含みます：

- **クラス**：システム内のオブジェクトを表す。
- **属性**：クラスが持つデータ。
- **メソッド**：クラスが持つ操作（関数）。
- **関係**：クラス間の関連性（継承、依存、関連など）。

クラス図は、システムの構造を設計する際の基本的なツールとして使用されます。

#### 2.2 ユースケース図（Use Case Diagram）

**ユースケース図**は、システムの機能と、それを利用するアクター（ユーザーや他のシステム）との関係を表現するダイアグラムです。ユースケース図は、システムが提供するサービスや機能を高レベルで理解するのに役立ちます。

- **アクター**：システムを利用するエンティティ（ユーザーや外部システム）。
- **ユースケース**：アクターがシステムで行う具体的な操作や機能。
- **関係**：アクターとユースケース、またはユースケース同士の関係。

ユースケース図は、要件定義や基本設計の段階で、システムの機能要件を把握するために使用されます。

#### 2.3 シーケンス図（Sequence Diagram）

**シーケンス図**は、システム内のオブジェクトやコンポーネントがどのようにメッセージをやり取りするかを時間軸に沿って表現するダイアグラムです。シーケンス図は、システムの動的な振る舞いを理解するのに役立ちます。

- **オブジェクト**：メッセージを送受信するエンティティ。
- **ライフライン**：オブジェクトの存続期間を示す線。
- **メッセージ**：オブジェクト間で送受信される情報。
- **アクティベーション**：オブジェクトがアクティブな期間を示す。

シーケンス図は、特定のシナリオにおけるシステムの挙動を詳細に表現するために使用されます。

#### 2.4 アクティビティ図（Activity Diagram）

**アクティビティ図**は、システム内のプロセスやワークフローを表現するダイアグラムです。アクティビティ図は、システムのロジックフローや業務プロセスを理解するのに役立ちます。

- **アクティビティ**：実行される操作やタスク。
- **フロー**：アクティビティ間の流れを示す矢印。
- **条件分岐**：プロセスの分岐点を表現。
- **開始点・終了点**：プロセスの開始と終了を示す。

アクティビティ図は、業務フローや複雑なロジックを視覚的に整理するために使用されます。

### 3. UMLを使うメリット

UMLを使うことで得られるメリットには、以下のようなものがあります。

#### 3.1 コミュニケーションの向上

UMLを使うことで、開発チーム内のコミュニケーションが円滑になります。図を用いることで、システムの設計意図や構造を視覚的に共有でき、誤解を減らすことができます。

#### 3.2 システムの全体像の把握

UMLを使うことで、システムの全体像を把握しやすくなります。各ダイアグラムを使い分けることで、システムの異なる側面を詳細に理解できます。

#### 3.3 ドキュメントの標準化

UMLは標準化された言語であるため、異なるプロジェクトやチーム間でも共通の理解を持つことができます。これにより、ドキュメントが統一され、メンテナンス性が向上します。

### 4. まとめ

UMLは、システム開発において非常に強力なツールです。初めてUMLを学ぶ方は、まずは基本的なダイアグラムから理解を深め、それぞれの使い方や役割を押さえることが大切です。UMLを効果的に活用することで、システム開発がよりスムーズに進行し、品質の高いソフトウェアを作成することができるでしょう。

---

この記事が、UMLについての理解を深める助けとなれば幸いです。UMLに関する疑問や質問があれば、ぜひコメントで教えてください！
詳細設計とは？初学者向けに分かりやすく解説

## 詳細設計とは？初学者向けに分かりやすく解説

システム開発のフェーズの中でも、特に具体的な設計を行うのが「詳細設計」です。このフェーズでは、基本設計で決められた全体構造を基に、各コンポーネントや機能を細かく設計していきます。このブログ記事では、初学者向けに詳細設計の役割や主な成果物についてわかりやすく解説します。

### 1. 詳細設計って何？

詳細設計とは、基本設計で決められたシステムの全体構造や主要な機能をさらに具体化し、実際にコーディングが行えるレベルまで落とし込むプロセスです。この段階では、各機能やモジュール、データの処理方法などを詳細に設計します。

### 2. 詳細設計の目的

詳細設計の目的は、開発者がシステムの各部分を具体的に実装できるように、設計内容を細かく定義することです。これにより、実装フェーズでの迷いや設計ミスを減らし、効率的に開発を進めることができます。

### 3. 詳細設計の主な成果物とは？

詳細設計では、以下のような主要な成果物が作成されます。これらの成果物は、実装の指針となり、システムの品質を確保するために重要です。

#### 3.1 プログラム設計書

**プログラム設計書**は、各機能やモジュールの具体的な設計をまとめた文書です。これにより、開発者がプログラムを正確に実装できるようになります。

- **クラス設計**：各クラスの役割やメソッドの定義。
- **メソッド設計**：メソッドの引数、返り値、処理内容の詳細。
- **インターフェース設計**：モジュール間のインターフェースやデータのやり取り方法。

#### 3.2 データベース詳細設計書

**データベース詳細設計書**は、データベースのテーブルやカラムの詳細設計をまとめた文書です。これにより、データの管理やアクセスが効率的に行えるようになります。

- **テーブルの詳細設計**：各テーブルに含まれるカラムとその属性。
- **インデックス設計**：データの検索やアクセスを効率化するためのインデックスの設計。
- **トリガーやストアドプロシージャの設計**：データベース内で実行される処理の詳細。

#### 3.3 API設計書

**API設計書**は、外部システムや他のモジュールとの通信を行うためのAPIの設計をまとめた文書です。これにより、システム間のデータ交換がスムーズに行えるようになります。

- **エンドポイント設計**：各APIエンドポイントのURLや対応する機能。
- **リクエストとレスポンスの設計**：送信されるデータのフォーマットや受信するデータの構造。
- **エラーハンドリング**：APIエラー時の処理方法やエラーメッセージの設計。

#### 3.4 ユーザーインターフェース（UI）設計書

**ユーザーインターフェース（UI）設計書**は、ユーザーが操作する画面のデザインや機能の詳細をまとめた文書です。これにより、ユーザーが直感的に操作できるUIを提供します。

- **画面レイアウト**：各画面のレイアウトや配置される要素。
- **ユーザー操作の流れ**：各操作がどのように進行するかのフロー。
- **入力検証やエラーメッセージ**：ユーザー入力に対する検証やエラーメッセージの設計。

### 4. 詳細設計の目的と重要性

詳細設計は、システム開発の中で非常に具体的で重要なフェーズです。このフェーズで作成される成果物には、いくつかの重要な目的があります。

#### 4.1 実装の明確な指針を提供

詳細設計の成果物は、開発者に対して具体的で明確な実装の指針を提供します。これにより、各開発者が統一された基準でプログラムを作成できるようになります。

#### 4.2 システムの品質向上

詳細設計で設計内容を細かく定義することで、システム全体の品質を向上させることができます。これにより、バグの発生を抑え、メンテナンス性の高いシステムを作成することが可能です。

#### 4.3 コミュニケーションの円滑化

詳細設計の成果物は、開発チーム内でのコミュニケーションを円滑にするためにも役立ちます。設計内容が文書化されていることで、開発者間での認識のズレが減り、スムーズに作業を進めることができます。

#### 4.4 テストやデバッグの準備

詳細設計は、後のテストやデバッグのフェーズに向けた準備にもなります。設計内容が明確であれば、テストケースの作成やバグの特定が容易になり、開発プロセス全体が効率化されます。

---

詳細設計は、実装に直結する非常に重要なフェーズです。初めて取り組む方は、このブログを参考にしながら、詳細設計の重要性や成果物の作成方法を理解していきましょう。しっかりとした詳細設計を行うことで、システム開発の成功に一歩近づけるでしょう。

---

この記事が、詳細設計についての理解を深める助けとなれば幸いです。詳細設計に関する疑問や質問があれば、ぜひコメントで教えてください！
基本設計とは？初学者向けに理解しやすく解説

## 基本設計とは？初学者向けに理解しやすく解説

システム開発において、要件定義が完了した後に進むフェーズが「基本設計」です。このフェーズでは、要件定義で明確にされた内容を基に、システム全体の構造や主要な機能を設計していきます。このブログ記事では、初学者向けに基本設計の役割や主な成果物について詳しく解説します。

### 1. 基本設計って何？

基本設計とは、要件定義で決まったシステムの要件を、具体的なシステム設計に落とし込むプロセスです。この段階では、システム全体の構造や、主要な機能の設計が行われます。基本設計の成果物は、後の詳細設計や実装フェーズに向けた土台となります。

### 2. 基本設計の目的

基本設計の目的は、システムの全体像を明確にし、開発チームが同じ方向性で作業を進められるようにすることです。このフェーズでシステムの骨格をしっかりと設計しておくことで、後のフェーズでの手戻りを減らし、プロジェクトを効率的に進行させることができます。

### 3. 基本設計の主な成果物とは？

基本設計では、以下のような主要な成果物が作成されます。これらの成果物は、システムの全体像を把握しやすくし、開発の指針となります。

#### 3.1 システム構成図

**システム構成図**は、システム全体の構造や各コンポーネントの関係を図で表現したものです。これにより、システムがどのような構造で動作するのかを一目で理解することができます。

- **ハードウェア構成**：サーバーやネットワーク機器などの配置。
- **ソフトウェア構成**：各モジュールやコンポーネントの配置。

#### 3.2 データベース設計書

**データベース設計書**は、システムで使用されるデータの構造を設計する文書です。この設計書は、システムがどのようにデータを管理し、処理するかを明確にします。

- **テーブル設計**：データベースにどのようなテーブルを作成するか。
- **カラム設計**：各テーブルにどのようなデータを保存するか。
- **インデックス設計**：データアクセスを高速化するための設計。

#### 3.3 画面遷移図

**画面遷移図**は、ユーザーがシステムを操作する際の画面の遷移を図示したものです。これにより、ユーザーの操作フローが一目で分かるようになります。

- **各画面の概要**：画面で表示される情報や操作内容。
- **画面間の遷移**：ユーザーがどのように画面を移動するか。

#### 3.4 業務フロー図

**業務フロー図**は、システムがどのように業務をサポートするかを示す図です。これにより、業務プロセスとシステムの関係が明確になります。

- **業務プロセスの概要**：各業務がどのように進行するか。
- **システムとのインターフェース**：システムがどのように業務を支援するか。

### 4. 基本設計の目的と重要性

基本設計は、システム開発の中で非常に重要なフェーズです。このフェーズで作成される成果物には、いくつかの重要な目的があります。

#### 4.1 プロジェクトの方向性を確立

基本設計の成果物は、プロジェクト全体の方向性を確立するための基盤となります。システムの全体像を明確にすることで、開発チームが一貫した方針で作業を進められるようにします。

#### 4.2 手戻りの防止

基本設計でシステムの骨格をしっかりと設計しておくことで、後のフェーズでの手戻りを防ぎ、プロジェクトを効率的に進行させることができます。これにより、開発コストや納期のオーバーランを防ぐことが可能です。

#### 4.3 コミュニケーションの円滑化

基本設計の成果物は、開発チーム内だけでなく、ステークホルダーとのコミュニケーションを円滑にするためにも重要です。図や文書を使ってシステムの全体像を共有することで、認識のズレを防ぐことができます。

#### 4.4 詳細設計への橋渡し

基本設計で作成された成果物は、詳細設計や実装フェーズへの橋渡しとなります。これにより、後のフェーズでの設計作業がスムーズに進むようになります。

---

基本設計は、要件定義と詳細設計をつなぐ重要なフェーズです。初めて取り組む方は、このブログを参考にしながら、基本設計の重要性や成果物の作成方法を理解していきましょう。しっかりとした基本設計を行うことで、システム開発の成功に一歩近づけるでしょう。

---

この記事が、基本設計についての理解を深める助けとなれば幸いです。基本設計に関する疑問や質問があれば、ぜひコメントで教えてください！
要件定義とは？初学者向けの基本から成果物まで

## 要件定義とは？初学者向けの基本から成果物まで

システム開発において「要件定義」という言葉を聞いたことがあるかもしれませんが、これが具体的に何を意味するのか、またなぜ重要なのかを知っていますか？このブログ記事では、初めて要件定義に取り組む方に向けて、その基本と主な成果物についてわかりやすく解説します。

### 1. 要件定義って何？

要件定義とは、システムやソフトウェアを作る際に「何を作るのか」を明確にするプロセスです。システムを使う人（ユーザー）やビジネスのニーズを理解し、それを具体的な機能や仕様としてまとめることが目的です。この段階で決めたことが、その後の開発の土台となります。

### 2. なぜ要件定義が重要なの？

要件定義がしっかりしていないと、プロジェクトが進むにつれて「これって本当に必要だったっけ？」と迷ったり、途中で計画を変えなければならない事態が発生しがちです。これによって、納期が遅れたり、予算が膨らんだりするリスクが高まります。

逆に、要件定義がきちんと行われていれば、プロジェクトはスムーズに進行し、ユーザーが本当に必要としているシステムを作ることができます。

### 3. 要件定義の主な成果物とは？

要件定義では、いくつかの重要な成果物が作成されます。これらの成果物は、プロジェクトの進行を円滑にするために役立ちます。

#### 3.1 要件定義書

**要件定義書**は、システムが持つべき機能や条件をまとめた文書です。この文書には、以下のような内容が含まれます：

- **システム全体の概要**：システムがどのような役割を果たすか。
- **機能要件**：システムがどのような機能を提供するか。
- **非機能要件**：システムの性能やセキュリティなど、機能以外の要件。
- **インターフェース要件**：他のシステムとの接続やデータのやり取りに関する要件。

要件定義書は、プロジェクト全員が同じ方向を向いて開発を進めるための指針となります。

#### 3.2 ユーザーストーリーやユースケース

**ユーザーストーリー**や**ユースケース**は、ユーザーがシステムをどう使うかを具体的に示すものです。これにより、ユーザーの視点からシステムを設計することができます。

- **ユーザーストーリー**：ユーザーが「このシステムでこんなことをしたい」というシナリオを簡潔に表現します。
- **ユースケース**：システムとユーザーがどうやり取りするかを詳細に説明します。

#### 3.3 データモデル

**データモデル**は、システムで扱うデータがどのように組織され、関係づけられるかを示す図や文書です。これにより、データの管理方法や流れを理解しやすくなります。

#### 3.4 プロトタイプやモックアップ

**プロトタイプ**や**モックアップ**は、システムの画面レイアウトや操作方法を視覚的に示すものです。これを使うことで、ユーザーやステークホルダーから早い段階でフィードバックを得ることができ、開発の方向性を調整しやすくなります。

### 4. これらの成果物の目的とは？

要件定義で作成された成果物には、いくつかの重要な目的があります。

#### 4.1 コミュニケーションの円滑化

成果物を使うことで、プロジェクトに関わる全ての人が同じ認識を持ちやすくなります。図や文書を共有することで、誤解や認識のズレを防ぐことができます。

#### 4.2 プロジェクトの方向性の明確化

要件定義でまとめた内容は、プロジェクト全体の方向性を明確にします。これにより、開発が進む中で迷うことが少なくなり、効率的に作業を進められます。

#### 4.3 リスクの低減

詳細な要件定義を行うことで、プロジェクトが進行する中での手戻りや追加コストを防ぐことができます。特に、早い段階でユーザーのフィードバックを得ることができれば、後々のリスクを大幅に減らすことが可能です。

#### 4.4 進捗管理の基準

要件定義で定めた内容は、プロジェクトの進捗を管理するための基準にもなります。これを基に、開発が計画通りに進んでいるかどうかを確認し、必要に応じて調整を行います。

---

要件定義はシステム開発の土台となる重要なプロセスです。初めて取り組む方は、このブログを参考にしながら、まずは基本を押さえることから始めてみてください。しっかりとした要件定義を行うことで、プロジェクトの成功に繋がるシステムを作ることができるでしょう。

---

この記事が、要件定義について理解を深める助けとなれば幸いです。要件定義に関する疑問や質問があれば、ぜひコメントで教えてください！
React: Uncaught Error: Objects are not valid as a React child (found: object with keys {children}). If you meant to render a collection of children, use an array instead.

一応メモ

:::note warn
typescriptにした時は、修正前の状態に戻さないと動かなかったのでjsxだけの動作のようです
:::

# 環境
Vite
React 18.3.1
JSX

# エラー内容
Uncaught Error: Objects are not valid as a React child (found: object with keys {children}). If you meant to render a collection of children, use an array instead.

# 修正前

```javascript: 親コンポーネント
import { useState } from "react";
import { Loading } from "./Loading";

function App() {
  const [isLoading, setIsLoading] = useState(false);

  return (
    <>
      <div className="container">
        <Loading isLoading={isLoading}>
          <main>
            // 省略
          </main>
        </Loading>
      </div>
    </>
  );
}

export default App;
```

```javascript: 子コンポーネント
import { ClipLoader } from "react-spinners";

export function Loading({ isLoading, children }) {

  return (
    <>
      {isLoading ? (
        <ClipLoader
          color="#0FF"
          loading={isLoading}
          size={150}
          aria-label="Loading Spinner"
          data-testid="loader"
        />
      ) : (
        { children }
      )}
    </>
  );
}
```

でエラー

# 修正後
children をスプレッド構文へ変更

```diff_javascript: (修正後)子コンポーネント
import { ClipLoader } from "react-spinners";

export function Loading({ isLoading, children }) {

  return (
    <>
      {isLoading ? (
        <ClipLoader
          color="#0FF"
          loading={isLoading}
          size={150}
          aria-label="Loading Spinner"
          data-testid="loader"
        />
      ) : (
-        { children }
+        { ...children }
      )}
    </>
  );
}
```

すごい基本的なのことをへぼったか。
あれ、そうだったっけ？と思ったので一応メモです。
git tagでかっこ付きのタグを作成する

git tagでかっこ`()`付きのタグを作成する機会があり、その際に少し詰まったので共有します。

# 環境

- MacOS 14.5
- git version 2.46.0

# 事象
git tagで以下のように`()`付きのタグを作成しようとしたところ、下記のエラーが発生しました。

```
git tag v1.0.0(hogehoge)
bash: syntax error near unexpected token `('
```

# 解消方法
タグ名をダブルクオーテーションで囲むだけです。
これで`()`付きのタグを作成できます。

```
git tag "v1.0.0(hogehoge)"
```

# なぜエラーになったのか？

`()`が特殊な文字として扱われたからです。

bashには`()`でくくったコマンドをサブシェルで実行するという機能があり、そのため`()`が特殊な文字として扱われてしまうようです。

`()`をタグ名として使うためには、bashに`()`を普通の文字として扱ってもらう必要があります。
`""`や`\`でエスケープすると、普通の文字として扱われます。

# 参考

https://log.dot-co.co.jp/chuldshell/

https://wa3.i-3-i.info/word11732.html
『SCRUM BOOT CAMP THE BOOK』を読んでみた

# 初めに
今年からスクラム体制で開発を行っており、イベントの意義や全体像を理解したいと思い、この本を読んでみました。将来的にはスクラムマスターも目指したいと思っています。
# 本の紹介
こちらはスクラム初学者向けの本で、初めてスクラムを学ぶ際には非常におすすめです。スクラム開発の体系的な知識がわかりやすく説明されており、ところどころで漫画形式の説明もあるため、非常に理解しやすい内容となっています。前回紹介した「アジャイルサムライ」と比べても、個人的にはこちらの方がわかりやすかったです。
# この記事を書いている人
私は社会人2年目のエンジニアで、主にUnityを利用したARグラスサービスの開発に従事しています。社会人1年目は企画側を担当しており、エンジニアとしての業務は行っていませんでしたが、2年目からエンジニアとしての業務を本格的に担当するようになりました。そのため、エンジニアとしての経験は実質半年ほどです。
# 大事/参考にしたい箇所
### スクラムにおけるロールはただの目印
スクラムには「プロダクトオーナー」「開発チーム」「スクラムマスター」の3つのロールがあります。

| ロール|役割  |
|:-:|:-:|
|  プロダクトオーナー | 何のために何をどういう順番で作るかを決める人  |
|  開発チーム |  実際に作る人 |
|スクラムマスター |プロダクトオーナーと開発チームが上手くスラムを進められるようにする人|

ロールは肩書や役職とは異なり、誰がどの責任を持つかを明確にするためのものです。ロールは兼任することも可能ですが、プロダクトオーナーとスクラムマスターの兼任は避けるべきです。プロダクトオーナーはプロダクトの改善に注力しがちで、開発メンバーにプレッシャーをかけることがあります。一方、スクラムマスターは円滑なスクラムの進行が目的であり、両者の役割が相反するためです。
### あてずっぽうな見積もりにベストを尽くす
開発前の見積もりは正確にはできないため、ある程度の推測で行います。そのため、時間をかけずに素早く見積もりを行うことが重要です。見積もりは、実際に作業を行う開発メンバーが担当するのが良いでしょう。なぜなら、現状で最も多くの知識と情報を持っており、最も正確な見積もりができるからです。
見積もりを担当するのは（実際に作業をする）開発メンバーがよい。理由は、多くの知識と情報を持っているため現状、一番正確な見積もりをすることができる。

#### 実際の見積もり方法
多くのスクラムチームでは、ポーカーを使った見積もりが行われています。方法は以下の通りです。
1. フィボナッチ数が書かれたカードを開発者に配る
2. タスクごとにかかる日数をカードで示す
3. 数字が異なる場合は話し合いを行う
4. すべてのタスクについて繰り返す

### タイムボックスは譲れない
タイムボックスとは、スクラムイベントの時間枠のことです。
>スプリントの期間は１カ月以内
>デイリースクラムは15分以内等など

タイムボックスを守ることで、タスクの達成にかかる時間の予測がしやすくなります。1日でも延長すると、他のスプリントとの比較が難しくなり、予測が立てにくくなるため、タイムボックスを厳守することが重要です。

### ユーザーストーリの書き方
プロダクトオーナーが開発チームに正確に伝えるためには、以下のフォーマットを使うと良いでしょう。5W1Hを用いることがポイントです。
>＜どういったユーザーや顧客＞として
>＜どんな機能や性能＞が欲しい
>＜どんなことが達成したい＞ためか

### スクラムチームの問題は視覚化する
スクラムマスターの役割には、スクラムチームを改善することも含まれます。そのため、問題をタスクボードに視覚化して掲示するのが効果的です。また、その問題には優先順位をつけ、スクラムマスターが解決に向けてリードする必要があります。
Rails7でActive Storageを用いた画像リサイズを行うために必要な準備

Rails初学者の備忘録として、表題の手順を簡単にまとめておきます。
振り返るとだいぶ初歩的な部分で詰まってしまったのですが、自身と同じくActive Storageを全く初めて使う方に少しでも参考になれば幸いです。

## 使用環境
- Rails 7.0.8.4
- Ruby 3.2.1

## 現状・実現したいこと
- ECサイトの商品一覧ページを只今製作中
- とりあえずActiveStorageの導入は済んでおり、Item(商品)テーブル上のimageカラムに画像の登録はできている
- 現在はシンプルに下記コードで画像表示中

```erb:app/views/items/index.html.erb
<%= image_tag item.image %>
```
- 下記画像のように、現状、Seedで登録した画像サイズがバラバラで、見栄えがよろしくないので450x300のサイズに統一したい

![スクリーンショット 2024-08-25 17.15.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/19f65081-25cf-44eb-49be-78eb2b00448f.png)

以下、Active Storageを用いた画像リサイズを行うための必要手順をまとめます。

Active Storage自体の導入手順 (`rails active_storage:install`を実行する等)　は割愛します。


## 準備①　必要なgemを導入する

Active Storageを用いた画像分析・画像加工のためにはimage_processingのgemが必要です。
これはGemfileにコメントアウトされているかと思うので、コメントを解除します。

```ruby:Gemfile
# コメントアウトまたは追加
gem "image_processing", ">= 1.2"
```

gem導入後は`bundle install`を忘れずに。

## 準備② libvipsを導入する

筆者は準備①だけで画像サイズ調整ができると思っており、index.html.erbの画像表示部分を以下内容に置き換えました。

```erb:app/views/items/index.html.erb
<%=　image_tag item.image.representation(resize_to_fill: [450, 300]) %>
```

この内容で実行したところ、`Could not open library 'vips.so.42': vips.so.42: cannot open shared object file: No such file or directory.`というエラーが発生しました。

エラー内容から何かのライブラリがまだ足りないと察し、調べたところ、表題の通り`libvips`が導入必須であること分かりました。


Active Storageの公式ドキュメント冒頭をよく読むと、

> #### 1.1 要件
> Active Storageの多くの機能は、Railsによってインストールされないサードパーティソフトウェアに依存しているため、別途インストールが必要です。
> - **libvips v8.6以降（またはImageMagick）: 画像解析や画像変形用**
> - ffmpeg v3.4以降: 動画プレビュー、ffprobeによる動画/音声解析
> - popplerまたはmuPDF: PDFプレビュー用

と、ちゃんと書いてありました。
公式ドキュメントはちゃんと最初から読みましょう・・・　(自戒)

Dockerで環境構築を行なっているため、下記の通りDockerfileの`RUN apt-get`部分に`libvips42`を追加して、再度`Docker-compose build`を実行します。

```Dockerfile:Dockerfile
RUN apt-get update -qq && \
  apt-get install -y build-essential \
  # 略
  libvips42 \
```

これで再度実行したところ、無事に画像のリサイズが行われました。


![スクリーンショット 2024-08-25 22.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/902ed1c4-9043-d33d-83be-af54f9034225.png)


ちなみに、画像のリサイズ方法は色々用意されており、例えば`resize_to_fit`の場合は、画像の切り取りは行わずに指定の寸法に収まるように画像の拡大縮小を行います。

詳しくはActive Storageの公式ドキュメント、「9 画像を変形する」に色々記載されております。

## 参考

Railsガイド Active Storageの概要
https://railsguides.jp/active_storage_overview.html
【新しいサービス！】Xserver Staticで静的サイトを作ってホスティング！

# Xserver Staticが現れた!!!
ということで、2024年8月22日にあのXserverから、静的サイトをホスティングし、高速な提供ができるサービスが発表されました。そこで爆速レビュー（解説？）をします。

まず驚くべきは、Xserverが提供しているサービスの中で、
### 無料
というところです。

## 特徴
* **サーバーがハイスペック**
  → HTTP/2などの技術にも対応しているそうですが、体感もすごく高速でした。
* **独自ドメインが利用可能**
  → これもかなりのメリットかなと思います。ほかのサービスでもありますが、別にポイントもあるので次の点にいったん行きます。
* **SSLが無料で利用できる**
  → これははっきり言って良い点でしょう。これもポイントとして詳しく記載したいと思います。
* **転送量課金なし**
  → ここで、ポイントです。ここまでの独自ドメインが使えてSSLが使えるサービスはほかにも実はありますが、データ転送量の課金がなく無制限というのはすごく珍しく、帯域幅や転送量に制限の厳しいところがほとんどの中で、人によっては一番のメリットともなりうると考えられます。

# 使ってみる

## サイトの公開方法
:::note info
アカウントの登録は公式のガイドなどをご覧ください。
:::
まず、

https://static.xserver.ne.jp/

へアクセスし、右上の「ログイン」を押します。すると「Xserverアカウント」と「ファイルマネージャー」に分かれているので、まだ<ins>Xserver Staticにログインしたことがない場合</ins>は「Xserverアカウント」からログインすることができます。

![Xs解説1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819700/4d6c3a8e-9744-8d70-a6e3-27ee911ec979.png)

ログインするとこんな感じになります。

そして、管理画面の「ファイル管理」を押すと、各ファイル（HTMLやCSSなど）をアップロードできるファイルマネージャーが出てきます。
![Xs解説2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819700/ac6ed577-e91a-5a00-a922-2e91ea549a3f.png)

アップロードやファイルの編集、複製、名前の編集など、様々なことができます。私としてもとても使いやすく、高評価です。

# 仕様と検証

<b><ins>※【注意】記事記載時点での仕様や検証となっております。</ins></b>

## 仕様
HTMLなどをアップした後は、基本的に

```
[最初に設定したサーバーID].static.jp
```
という形式のURL（ドメイン）でアクセスすることができます！

## 検証
※公式に出ている情報ではないため、変更になる場合があります

### ドメイン
|                | *.static.jp                | 独自ドメイン                |
|----------------|----------------------------|-----------------------------|
| SSL証明書      | SecureCore RSA DV CA        | Let's Encrypt ※1            |
| ファイルのパス | /                          | /                           |

上記のように、`static.jp`のサブドメインではSecureCore RSA DV CA、独自ドメインでは検証の結果、基本的にLet's Encryptになるようです。
そのため、この表のような形に固定されると考えられます。

設定画面で、別の証明書をアップロードしたりすることはできませんでした。

※1 CloudFlareなどのロードバランサーを通した場合は、別の証明書になる場合もあります。


____
ここまで紹介してみました！私も即席でサイトをhtml書いて作ってみましたが、開くのはさすが爆速※2です。

https://haruharu.static.jp

※2 環境により異なる場合があります。
【Svelte】checkboxやradioを使用する際は bind:group ディレクティブを使用する

## 問題のコード
```svelte
<script>
  let id;

  function handleSelectId(event) {
    id = event.currnetTarget.value;
  }
</script>
<!-- hogeList(Array)はあるアクションが実行されると更新されるものとします -->
{#each hogeList as hoge}
  <input
    type="radio"
    name="hoge"
    id="{hoge.value}"
    value="{hoge.id}"
    on:click={handleSelectId}
  >
  <label for="{hoge.value}">{hoge.body}</label>
{/each}
```

![ScreenRecording2024-08-25at17.12.10-ezgif.com-video-to-gif-converter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509214/f11541a5-816b-e9d2-0618-9ef4d8b32500.gif)

これが実際の動きの映像になります。（"ここTrue"という文字は無視してください🙇）
`each` ディレクティブ内で使用している `input` タグが、配列データが変わっても、 `radio` のチェックがされたままになってしまう事象に悩まされました。

## 解決後のコード

```diff_svelte
<script>
  let id;

-   function handleSelectId(event) {
-     id = event.currnetTarget.value;
-   }
</script>
<!-- hogeList(Array)はあるアクションが実行されると更新されるものとします -->
{#each hogeList as hoge}
  <input
    type="radio"
    name="hoge"
    id="{hoge.value}"
    value="{hoge.id}"
-   on:click={handleSelectId}
+   bind:group={id}
  >
  <label for="{hoge.value}">{hoge.body}</label>
{/each}
```

解決理由と原因は不明ですが、Svelteのディレクティブ **`bind:group`** を使用することで解決しました。

### 参考文献
https://svelte.jp/docs/element-directives#bind-group
Gemini APIを Semantic Kernel で利用してみた【サンプルコード】

## 前提
[Google AI StudioのGemini APIのページ](https://ai.google.dev/aistudio?hl=ja)のGet API Keyで、APIキーを発行・取得済みであること

## 手順
### コンソールアプリケーションの作成
```bash
dotnet new console -n GeminiSemanticKernelConsoleApp
```
### プロジェクトディレクトリに移動
```bash
cd GeminiSemanticKernelConsoleApp
```
### 必要なパッケージのインストール
```bash
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Connectors.Google --prerelease
```
`Program.cs`を以下に変更
``` csharp
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

Console.WriteLine(
    "============= Google AI - Gemini Chat Completion =============");

string geminiApiKey = "APIキーをここに記述";
string geminiModelId = "gemini-1.5-flash";

if (geminiApiKey is null || geminiModelId is null)
{
    Console.WriteLine("Gemini credentials not found. Skipping example.");
    return;
}

#pragma warning disable SKEXP0070
Kernel kernel = Kernel.CreateBuilder()
    .AddGoogleAIGeminiChatCompletion(
        modelId: geminiModelId,
        apiKey: geminiApiKey)
    .Build();
#pragma warning restore SKEXP0070

Console.WriteLine("======== Simple Chat ========");

var systemMessage = """
    You are an expert in finance and economics.
    """;
var chatHistory = new ChatHistory(systemMessage);
var chat = kernel.GetRequiredService<IChatCompletionService>();

OpenAIPromptExecutionSettings settings = new()
{
    MaxTokens = 100,
};

while (true)
{
    // your message
    Console.Write("user: ");
    var input = Console.ReadLine() ?? "";

    if (input == "exit") { break; }
    chatHistory.AddUserMessage(input);

    // bot assistant message
    var reply = await chat.GetChatMessageContentAsync(chatHistory, settings);
    chatHistory.Add(reply);
    Console.WriteLine($"{reply.Role}: {reply.Content}");
}
```
OpenCVで検出した画像の輪郭をCSVで出力

# 概要
そのまんまですがOpenCVで検出した画像の輪郭をCSVで出力するコードです。

# 環境
- Ubuntu 24.04.LTS
- Python 3.12.3 (venvで仮想環境化して使用)

# pipのリスト()
contourpy==1.2.1
cycler==0.12.1
fonttools==4.53.1
kiwisolver==1.4.5
matplotlib==3.9.2
numpy==2.1.0
opencv-python==4.10.0.84
packaging==24.1
pillow==10.4.0
pyparsing==3.1.3
python-dateutil==2.9.0.post0
six==1.16.0

# 参考URL
https://chantastu.hatenablog.com/entry/2022/09/13/231625

# ソースコード
```python
puts 'import cv2'
import matplotlib.pyplot as plt
import numpy as np
np.set_printoptions(threshold=np.inf)

# 画像の読み込み
img = cv2.imread('test.png')

# HSV変換
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)

#色相、彩度、明度の画像に分離
img_h, img_s, img_v = cv2.split(img_hsv)

ret, thresh = cv2.threshold(img_v, 150, 255, cv2.THRESH_BINARY)

contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[0]

# 面積が一定以上の輪郭のみ残す。
area_thresh = 200
contours = list(filter(lambda x: cv2.contourArea(x) > area_thresh, contours))

# 輪郭を画像に書き込む
output = cv2.drawContours(img, contours, -1, (0,255,0), 1)

contours_str = str(contours)

# 出力したい文字列からいらない文字を削除 
# 雑なので何かいい方法あったら教えてください
contours_str = contours_str.replace('array(', '')
contours_str = contours_str.replace('dtype=int32)', "")
contours_str = contours_str.replace('[', '')
contours_str = contours_str.replace(']', '')
contours_str = contours_str.replace(' ', '')
contours_str = contours_str.replace(',\n', '')

with open('result.csv', 'w') as f:
   f.writelines(contours_str)
    
#画像の出力
cv2.imwrite('result.png',output)
```
# 実行結果
いつか出すかも

# 所感
Yoloを使って分けたボックスに対してOpenCVの輪郭抽出を使うと綺麗に出来るんじゃない？
と思ったり
【個人開発】ブログ開設 - Part2

# はじめに

　以前 Laravel を使ってブログ開設したが、AWS 料金が高い & ドメイン有効期限切れのため閉鎖に追い込まれた。

　様々な個人開発ブログを見ているとやはり自分も書きたいという思いに駆られていた。

　今回 Next.js の勉強がてら何とか形になったので紹介する。

https://oizumi-yuta.com/

# 技術スタック

- フロントエンド
    - Next.js[v14.2.5]
- バックエンド
    - Node.js[v20.15.0], Express[v4.19.2]
- インフラ
    - AWS EC2, ALB, ACM, Route53, Amplify, S3

詳細は [こちらの記事](https://oizumi-yuta.com/blog/4) に書いた。
STM32　PWM　TIMｘ＿BDTRのDTGビットの設定方法

初めて投稿します
STM32　ビギナーです。PWMでデッドタイムを設定するにあたり、TIMｘ＿BDTRレジスタを設定しますが、このレジスタのDTGビットの設定についてわかりずらかったので確認してみました。
DTG[7:5」はプリスケーラーの選択になります。
例として　8MHzクロック　ｔdts＝1/8MHz=125ns　７５μｓのデッドタイムを設定したい場合の例
75000nｓ＝（32+DTG[4:0])×16×125ns
32+DTG[4:0]=37.5
DTG[4:0]＝37.5-32
DTG「4：0」＝5.5　より６として　DTG[7:5」＝111がプリスケーラ16相当につき
DTG[7:0]＝11100110を設定するようです。

レベルの低い投稿でした。
LLMへの攻撃：敵対的プロンプトまとめスライドを公開！（プロンプトインジェクション, ジェイルブレイク, バックドア)

こんにちは！

**LLMへの攻撃：敵対的プロンプトまとめたスライドを公開します**

自分自身、このトピックに関する論文を100近く読んできた経験を生かし、誰かのためになればと思いまとめることにしました！

## 主な内容
- **プロンプトインジェクション**
- **ジェイルブレイク**
- **バックドア**

### 今回は攻撃に焦点を当て手法や脅威についてまとめました！


<iframe src="https://docs.google.com/presentation/d/1C1FJBUTDP100g56nicNUK9w_P3LIFeEc/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

## 今後の展望
今回は攻撃手法に焦点を当てましたが、会があれば防御手法についてもまとめてみます！

## 参考リンク
Xでプロンプトインジェクションについて情報発信をしていますので、参考にしてください！ 👉 [@7eHnpgIYyHE4iyG](https://x.com/7eHnpgIYyHE4iyG)

また、プロンプトインジェクションに関するまとめサイトも運用しています 👉 [LLM-Securityまとめサイト](https://tasuku-sasaki-lab.github.io/Tasuku-Sasaki.github.io/LLM-Security/)

最後までご覧いただき、ありがとうございました！
Gitコマンド各種

# 概要
自分が普段よく使うGitコマンドをメモとして残します

## ブランチ作成関係
### ローカル・リモート共に存在するブランチからローカルブランチを切る場合
```bash
git branch
* feature/1
develop

git checkout develop

git pull origin develop

git checkout -b new_branch_name
```

### リモートのみに存在するブランチからローカルブランチを切る場合
```bash
git branch
* develop

# リモート追跡ブランチを確認する
git branch -r
origin/HEAD -> origin/develop
origin/develop
origin/feature/git_test ★今回の作成対象

# リモートブランチからリモート追跡ブランチ(ローカル上に存在するリモートブランチのコピー)の[origin/feature_git_test]を作成する
git fetch

# リモート追跡ブランチからローカルブランチを作成する
git checkout -b 作成するブランチ名 origin/リモート追跡ブランチ名
```

## 作業中のブランチを最新化する方法(pull)
```bash
git branch
* feature/1
develop

# 更新した追跡ファイルのみstashする(未追跡ファイルはstashしなくても問題ない)
git stash push -m "stash時のコメント"

# stashされていることを確認
git stash list
stash@{0}: On git_stash_test: stash時のコメントが表示される

git checkout develop

git pull origin develop

git checkout feature/1

# 作業ブランチにdevelopの内容をマージする
git merge develop

# 最新のstash内容を反映してstash履歴から削除する
git stash pop
```


## コードの取り消し関係(reset)
```bash
# addのみを取り消したい時
# git logにもコミットメッセージ残らない
# 編集した内容はそのまま残るがaddしたことのみを取消
git reset --mixed HEAD

# commitのみを取り消したい時
# git logにもコミットメッセージ残らない
# 編集した内容とaddしたことはそのまま残るが、commitしたことのみを取消
git reset --soft HEAD^

# 色々編集してみたけど、前回のcommit直後の状態に戻りたい時
git reset --hard

# reset --hardを取消
git reflog
git reset --hard [戻したいハッシュ値]
```

## とても参考にさせていただいた情報
* git reset関係
https://qiita.com/gintaro0111/items/24d51c04e0ae639003b0
https://zenn.dev/nekoniki/articles/f238efa56eb869
Python を捨てて，街に出よう

ChatGPT は，かく語りき...

Pythonは世界中で広く使われており、その豊富なライブラリと簡単な構文のおかげで、多くの開発者にとっては第一選択のプログラミング言語です。しかし、Pythonを使う上での欠点が見え始めると、特に性能やスケーラビリティの要求が高まるプロジェクトでは、その限界が顕著になります。ここでは、実際の例をいくつか挙げながら、なぜPythonを捨ててJuliaに移行するべきかを説明します。

### 1. **速度の違い：Pythonは遅すぎる**
Pythonはインタープリタ型の言語であり、その動的型付けシステムが柔軟性をもたらす一方で、処理速度には犠牲があります。例えば、数値計算やデータ処理で多くの反復処理を行うコードでは、Pythonのパフォーマンスの限界がすぐに見えてきます。

**例：**  
次のPythonコードでは、100万回のループでリストの合計を計算します。

```python
def sum_list_python(n):
    total = 0
    for i in range(n):
        total += i
    return total

result = sum_list_python(1000000)
```

このコードを実行すると、Pythonでは数秒かかることがあります。特に大規模なデータ処理を行う場合、この遅さは大きなボトルネックになります。

一方、Juliaで同じ処理を行うと、コンパイル後の速度がCに近いパフォーマンスを発揮します。

```julia
function sum_list_julia(n)
    total = 0
    for i in 1:n
        total += i
    end
    return total
end

result = sum_list_julia(1000000)
```

Juliaは、このようなループ処理をほぼ瞬時に終わらせます。速度が求められるプロジェクトでは、この違いは決定的です。

### 2. **複雑なデータ構造の処理：Pythonのリストと辞書の限界**
Pythonのリストや辞書は非常に便利ですが、大規模なデータを扱う際にはスケーラビリティに問題が生じます。Pythonのリストはメモリ効率が悪く、大量のデータを処理する際にメモリ不足に陥ることがあります。また、複雑なデータ構造を扱う際には、型エラーやパフォーマンスの問題が発生しやすいです。

Juliaでは、ユーザー定義型や組み込み型が非常に効率的に動作し、大量のデータを処理する際にも高い性能を維持します。例えば、Pythonでデータフレームを扱う際にはPandasライブラリを使用しますが、これには多くのオーバーヘッドが伴います。Juliaでは、組み込みの`DataFrame`型がこれを簡単に処理し、Pythonのように多くの外部ライブラリに依存する必要がありません。

### 3. **型安全性とコンパイル：Pythonの柔軟さが招く問題**
Pythonは動的型付け言語であるため、コードを書くのが簡単ですが、その一方でランタイムエラーが発生しやすくなります。特に大規模なプロジェクトでは、型の問題がバグを引き起こしやすく、デバッグに多くの時間を費やすことになります。

Juliaは静的型付けをサポートし、必要に応じて型アノテーションを追加することで、コンパイル時に多くのエラーを検出できます。これにより、バグの発生を未然に防ぎ、コードの品質を向上させることができます。また、Juliaの強力な型推論エンジンにより、必要な型アノテーションは最小限で済み、コードの読みやすさを損ないません。

### 4. **並列処理と分散計算の容易さ**
Pythonで並列処理や分散計算を行う場合、`multiprocessing`モジュールや外部ライブラリを駆使する必要があります。しかし、その実装は複雑であり、効率的なスケールアップが難しいことがしばしばです。

一方、Juliaは並列処理と分散計算を言語の基本機能としてサポートしており、非常にシンプルにこれらを実装できます。例えば、Juliaでは次のように簡単に並列計算を行うことができます。

```julia
using Distributed
addprocs(4)

@distributed (+) for i in 1:1000000
    # Heavy computation here
end
```

これにより、Pythonでの複雑な並列処理の実装から解放され、パフォーマンスを最大限に引き出すことができます。

### 5. **Pythonの過度な依存：外部ライブラリの問題**
Pythonは非常に多くのライブラリが存在するため、多くの開発者がこれに頼っています。しかし、外部ライブラリに依存することは、バージョンの互換性問題や依存関係の複雑化を引き起こす可能性があります。

Juliaは、数値計算やデータ処理のための標準ライブラリが非常に充実しており、外部ライブラリに依存する必要がほとんどありません。さらに、Juliaのパッケージは通常非常に高速で、Pythonのライブラリに比べて性能が大幅に向上します。

### 結論：Pythonを捨ててJuliaに移行すべき理由
総合的に見ると、Pythonは柔軟で使いやすい言語である一方、パフォーマンスやスケーラビリティ、型安全性において大きな欠点を抱えています。これらの欠点は、特に大規模なプロジェクトや高度な数値計算を伴うプロジェクトにおいて顕著です。

Juliaは、Pythonの利便性を保ちながら、これらの欠点を克服するために設計された言語です。速度、スケーラビリティ、型安全性、並列処理の容易さにおいて、Juliaは一歩先を行っています。もしあなたが性能にこだわるなら、そして将来のプロジェクトでスケーラブルな解決策を求めるなら、今こそPythonを捨ててJuliaに移行する時が来たのです。
『ビジネスにおける有能と無能の真実：ゼークトの理論を検証する』

# 『ビジネスにおける有能と無能の真実：ゼークトの理論を検証する』

![title](https://raw.githubusercontent.com/legitwhiz/legitwhiz.github.io/master/technology_memo/images/1000008129.jpg)

## ゼークトの組織論とは

第一次大戦後にドイツの参謀総長を勤めたハンス・フォン・ゼークト上級大将の言葉です。

『有能な怠け者は、前線指揮官に向いている。
自分が怠け者だから、部下を有効に働かせるし、どうすれば楽に勝てるかばかりを考えるから。

有能な働き者は、参謀にするべきだ。
勤勉に一生懸命考えて行動するから、自分が部隊を率いるより、参謀として軍全体を見させるべきだ。

無能な怠け者は、連絡将校か下級兵士にしろ。
どうせ自分では何も考えず、ただ上から言われた通りにしか行動しないのだから。

無能な働き者は、処刑するしかない。
無能なのに根が真面目だから、どこまでも間違いに気づかないで進んで行動し、周りの人間も危険に陥れるから』

## 現代のビジネスで検証

これを『現代のビジネス』に当て嵌めようとする記事を見かけ、時代に沿うのか、またそもそもこの理論が正しいのか考えてみました。

まず私が感じたのは、誰が『有能』とか『無能』とか『働き者』か『怠け者』かなんて誰が決めるのか？

さらに、この『組織論』には、『教育』によって人は変わるという考えが抜け落ちているのでは？
そもそも、『教育すべき組織』が最初から分けるなんて無責任だと感じました。

## 結論

この理論を言い出した人は、神様みたいに自分には選り分けることができる能力があるって思い込んでいるから、高いところから他の人を見下ろしているだけですよね！？

組織にいれば役割があり、与えられた役割でもただ単に言われたことをこなすのではなく、『許される範囲』で仕事を効率的に実施したり、より収益を得られるように考えなければなりません。

立場によって、この『許される範囲』というものが変わってはきます。

『許される範囲』で考えられる人が優秀な人材であって、会社が最初から『有能』とか『無能』とか『働き者』か『怠け者』かなんて分けてるなんて、それこそ『無能な働き者』な会社だと思う。

ちなみに『ゼークトの組織論』は、『ハンス・フォン・ゼークト上級大将』が発言した言葉ではないそうです。
Excelの倍率・アクティブセル変更マクロ

# ディレクトリ内に存在するエクセルファイルの、セルと倍率を設定するマクロ

## 概要
このマクロは、特定のフォルダ内にあるすべてのExcelワークブックを開き、各シートの表示倍率を変更し、指定されたセルに移動するものです。マクロが記載されているワークブックの`Sheet1` の `A1` セルと `A2` セルに基づいて、他のワークブックで同様の操作を行います。

このマクロはWindows環境とMac環境の両方で動作するようにカスタマイズ可能です。ここでは、Windows環境向けのコードを紹介します。

## マクロの動作概要
1. **フォルダ内のすべてのExcelワークブックを開く**:
   - 指定されたフォルダ内にある `.xls`, `.xlsx`, `.xlsm` ファイルを順番に開きます。

2. **各シートの倍率と指定セルを設定**:
   - マクロが記載されているワークブックの `Sheet1` の `A1` セルに記載されたセルアドレスに基づき、各シートでそのセルに移動します。
   - 同じく `Sheet1` の `A2` セルに記載された数値を読み取り、各シートの表示倍率を設定します。

3. **ワークブックを上書き保存して閉じる**:
   - 変更を保存して、次のワークブックを処理します。

## コード
以下がWindows環境用のVBAコードです。

```vba
Sub OpenAllWorkbooksInSameFolder_Windows()
    Dim currentWorkbookPath As String
    Dim fileName As String
    Dim wb As Workbook
    Dim ws: Worksheet
    Dim targetCell: String
    Dim zoomLevel: Integer
    
    ' 現在のワークブックのパスを取得
    currentWorkbookPath = ThisWorkbook.Path
    
    ' このワークブックのSheet1のA1セルの内容を取得
    targetCell = ThisWorkbook.Sheets("Sheet1").Range("A1").Value
    
    ' このワークブックのSheet1のA2セルの内容を取得（倍率）
    zoomLevel = ThisWorkbook.Sheets("Sheet1").Range("A2").Value
    
    ' フォルダ内の最初のエクセルファイルを取得（すべてのエクセル形式を対象）
    fileName = Dir(currentWorkbookPath & "\*.xls*")
    
    ' すべてのエクセルファイルを順に開く
    Do While fileName <> ""
        ' マクロが含まれるワークブックは無視する
        If fileName <> ThisWorkbook.Name Then
            ' ワークブックを開く
            Set wb = Workbooks.Open(currentWorkbookPath & "\" & fileName)
            
            ' すべてのシートを順に処理
            For Each ws In wb.Sheets
                ' シートをアクティブにする
                ws.Activate
                
                ' シートの倍率を設定する
                ActiveWindow.Zoom = zoomLevel
                
                ' 取得したセルアドレスに移動
                ws.Range(targetCell).Select
            Next ws
            
            ' 最初のシートを再度アクティブにする
            wb.Sheets(1).Activate
            
            ' 上書き保存する
            On Error Resume Next
            wb.Save
            If Err.Number <> 0 Then
                MsgBox "ファイルの保存中にエラーが発生しました: " & fileName, vbExclamation
                Err.Clear
            End If
            On Error GoTo 0
            
            ' ワークブックを閉じる
            wb.Close
        End If
        
        ' 次のファイルを取得
        fileName = Dir
    Loop
End Sub
Gemini APIをStreamlitで利用してみた【サンプルコード】

## 前提
[Google AI StudioのGemini APIのページ](https://ai.google.dev/aistudio?hl=ja)のGet API Keyで、APIキーを発行・取得済みであること

## Streamlit と Gemini API SDK をインストールする
``` script
pip install streamlit google-generativeai
``` 
## サンプルコード
ファイル名は ```<your_script_name>.py``` とする。
``` python
import streamlit as st
import google.generativeai as genai
import google.ai.generativelanguage as glm
from streamlit_option_menu import option_menu

# APIキーの設定
genai.configure(api_key="APIキーをここに記述")

# Geminiモデルの設定
model = genai.GenerativeModel('gemini-1.5-flash')

# ページ設定
st.set_page_config(page_title="Gemini Chatbot", page_icon="🤖", layout="wide")

# チャットページ
st.title("Streamlit Chatbot")

# 定数定義
USER_NAME = "user"
ASSISTANT_NAME = "assistant"
MODEL_NAME = "model"

# チャットログを保存したセッション情報を初期化
if "chat_log" not in st.session_state:
    st.session_state.chat_log = model.start_chat(history=[
        glm.Content(role=USER_NAME, parts=[glm.Part(text="あなたは優秀なAIアシスタントです。できるだけ簡潔に回答してください。")]),
        glm.Content(role=MODEL_NAME, parts=[glm.Part(text="わかりました。")])
    ])
    st.session_state.chat_log = []

user_msg = st.chat_input("ここにメッセージを入力")
if user_msg:
    # 以前のチャットログを表示
    for chat in st.session_state.chat_log:
        with st.chat_message(chat["name"]):
            st.write(chat["msg"])

    # 最新のメッセージを表示
    with st.chat_message(USER_NAME):
        st.write(user_msg)

    # アシスタントのメッセージを表示
    response = model.generate_content(user_msg)
    with st.chat_message(ASSISTANT_NAME):
        assistant_msg = response.text
        st.write(assistant_msg)

    # セッションにチャットログを追加
    st.session_state.chat_log.append({"name": USER_NAME, "msg": user_msg})
    st.session_state.chat_log.append({"name": ASSISTANT_NAME, "msg": assistant_msg})
```
## 実行する
``` script
streamlit run <your_script_name>.py
```
[OpenAPIGenerator] OperationIdからTSメソッド名を生成する

OpenAPIGeneratorをつかってTypeScriptコードを生成する際に、いい感じにクラスわけとメソッド名を出力してもらうメモ📝

## クラス名、メソッド名はどこから割り当てられるか
OpenAPIGeneratorでTSコードを出力するにあたって、以下の定義が重要になります
1. tags
1. OperationId

それぞれが`クラス`と`メソッド名`に割り当てられます

### `OperationId`について注意点
`OperationId`についてはスキーマ内で一意の値を設定しないといけないようです
そのため、`article/create`と`post/create`のようなエンドポイントがある場合にどちらの`OperationId`も`create`とつけることはできません
ので、以下のように定義するのが自然かと思います
1. `article_create`
1. `post_create`

上記のように定義すると出力されるメソッド名はOperationIdのまま、`article_create`と`post_create`として出力されてしまいます、、

### `OperationId`を一意にしつつメソッド名は共通のものでも問題ないようにするには
:::note info
`tags`でクラスを分けたうえで`--remove-operation-id-prefix`を付与してコード生成を実行します
:::

これにより出力時に`**article_**create`や`**post_**create`の`xxx_`部分が除去されてメソッド名として使用されます
なお、`article_new_post`のような記載の際でも最初の`article_`のみ除去されるようでした
また区切り文字については`_`の代わりに`.`を利用すると認識してくれないようで、うまくメソッド名に反映されませんでした
うまく活用して気持ちのいいTSコードを使えると嬉しいですね🐳
Pythonの辞書をソートするときに使うlambdaってなに？

# はじめに
Pythonで辞書をソートしたい時に検索すると出てくるlambdaってなに？ という疑問から調べてみることにしました。どうやらlambdaとは無名関数のことでdef文を使わないので関数名を付けなくて良いし、変数に直接戻り値を返すことができる便利な使い捨ての関数ということがわかりました。使用例を見ながら解説したいと思います。間違っている箇所などありましたら教えてもらえるとありがたいです。

## 辞書をソートする例
まずは基本からいきましょう。以下のような辞書があったとします。
```python
data = {'apple': 3, 'banana': 2, 'orange': 4, 'grape': 1}
```
この辞書をキーや値でソートする方法を見てみましょう。

### キーでソートする (x: x[0])
```python
sorted_by_key = dict(sorted(data.items(), key=lambda x: x[0]))
print(sorted_by_key)
```
実行結果：

```python
{'apple': 3, 'banana': 2, 'grape': 1, 'orange': 4}
```
### 値でソートする (x: x[1])
```python
sorted_by_value = dict(sorted(data.items(), key=lambda x: x[1]))
print(sorted_by_value)
```
実行結果：
```python
{'grape': 1, 'banana': 2, 'apple': 3, 'orange': 4}
```
## 降順でソートする
もし降順でソートしたい場合は、sorted関数に reverse=True オプションを追加します。例えば、値で降順ソートを行う場合は次のように書けます。

```python
sorted_by_value_desc = dict(sorted(data.items(), key=lambda x: x[1], reverse=True))
print(sorted_by_value_desc)
```
実行結果：

```python
{'orange': 4, 'apple': 3, 'banana': 2, 'grape': 1}
```
このreverse=Trueを付けるだけで、ソート結果が逆順になります。もちろん、キーで降順ソートする場合も同様に使えます。

# x: x ってどういう意味？
ここで出てきた lambda x: x[0] や lambda x: x[1] という表記について説明します。

x は、lambda に渡される引数の名前です。実際には x じゃなくても何でも構いません。たとえば、item: item[0] や pair: pair[0] としても同じです。
x[0] や x[1] は、渡された引数から何を返すかを指定しています。ここでは x に渡されるのが (key, value) 形式のタプルなので、x[0] でキー、x[1] で値を取り出しています。
要するに、lambda x: x[0] は「引数として渡されたタプルの最初の要素（つまりキー）を返す関数を定義する」という意味なんです。そして、このキーを使ってソートが行われています。名前は x じゃなくてもいいんですが、短いからよく使われるだけです！

# 他にもこんなにある！lambdaの活用例
lambdaはソート以外でも幅広く使えます。次は、異なるシーンでのlambdaの使い方を紹介します。

### 1. リストの中の辞書を値でソートする
例えば、以下のように複数の辞書が含まれるリストがある場合：

```python
data = [{'name': 'apple', 'price': 100}, {'name': 'banana', 'price': 80}, {'name': 'orange', 'price': 120}]
```
これをpriceでソートするには：

```python
sorted_data = sorted(data, key=lambda item: item['price'])
print(sorted_data)
```
結果：

```python
[{'name': 'banana', 'price': 80}, {'name': 'apple', 'price': 100}, {'name': 'orange', 'price': 120}]
```
### 2. リストのフィルタリング
リストから条件に合う要素だけを抽出したいときにもlambdaは便利です。

```python
numbers = [5, 10, 15, 20, 25]
filtered_numbers = list(filter(lambda num: num > 15, numbers))
print(filtered_numbers)
```
結果：

```python
[20, 25]
```
### 3. リストの各要素を加工する
リストの各要素に対して何かしらの処理をしたいとき、mapとlambdaの組み合わせが使えます。

```python
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda n: n ** 2, numbers))
print(squared_numbers)
```

結果：

```python
[1, 4, 9, 16, 25]
```
### 4. 複数条件でのソート
例えば、名前と年齢を持つリストを名前でソートし、名前が同じ場合は年齢でソートすることもできます。

```python
people = [{'name': 'John', 'age': 25}, {'name': 'John', 'age': 20}, {'name': 'Jane', 'age': 30}]
sorted_people = sorted(people, key=lambda p: (p['name'], p['age']))
print(sorted_people)
```
結果：

```python
[{'name': 'Jane', 'age': 30}, {'name': 'John', 'age': 20}, {'name': 'John', 'age': 25}]
```
### 5. 簡単な条件分岐
lambdaで簡単な条件分岐もできます。例えば、数が偶数か奇数かを判定して結果を返す：

```python
check_even = lambda num: 'Even' if num % 2 == 0 else 'Odd'
result = check_even(10)
print(result)
```
結果：

```python
Even
```
# まとめ
lambdaは短く書ける無名関数で、辞書のソート以外にもリストの加工やフィルタリング、複数条件のソートなど多くの場面で使えます。reverse=Trueオプションで簡単に降順ソートもできるので、用途に合わせて使い分けてみてください！もちろん、変数名は x じゃなくてもOKです。ぜひ色々な場面で試してみてください！
MASM(x64)のサンプル

# 環境
- Windows 11 Pro
- Visual Studio Community 2022

# hello, world

```devasm.bat
@echo off
set vcdir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120
path %path%;%vcdir%\bin\Hostx64\x64
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64
prompt $e[33m$p$g$e[m
cmd
```

```fig1.asm
; ml64 /c /Fl fig1.asm
; link /entry:start /subsystem:console fig1.obj

includelib kernel32

STD_OUTPUT_HANDLE equ -11

extern	ExitProcess :proc
extern	GetStdHandle :proc
extern	WriteConsoleA :proc

.const
msg	db	'hello, world',0dh,0ah
len	equ	$ - msg

.code
public start
start:
	sub	rsp, 56
	mov	ecx, STD_OUTPUT_HANDLE
	call	GetStdHandle

	mov	qword ptr [rsp+32], 0
	xor	r9d, r9d
	mov	r8d, len
	lea	rdx, offset msg
	mov	rcx, rax
	call	WriteConsoleA

	xor	ecx, ecx
	call	ExitProcess
end
```

Cコンパイラで/FAオプションを付けてアセンブリリスト（.cod）を出力すると参考になる。

```fig2.c
// cl /MD /FAsc /O2 fig2.c
const char msg[7] = "hello\r\n";

int main(void)
{
	void *h = GetStdHandle(-11);
	WriteConsoleA(h, msg, 7, 0, 0);
	ExitProcess(0);
}
```

# MASMからCライブラリ関数を呼ぶ

```fig3.asm
; ml64 /c /Fl fig3.asm
; cl /MD fig3.obj

includelib msvcrt
includelib legacy_stdio_definitions

extern	printf :proc

.const
msg	db	'hello, %d',0ah,0

.code
main proc
	sub	rsp, 40

	mov	edx, 42
	lea	rcx, offset msg
	call	printf

	xor	eax, eax
	add	rsp, 40
	ret
main endp
end
```

# Cからアセンブリ関数を呼ぶ

```fig4.c
// cl /MD fig4.c fig4a.obj

#include <stdio.h>

int hoge(int);

int main(void)
{
	printf("%d\n", hoge(42));
}
```

```fig4a.asm
; ml64 /c fig4a.asm

.code
hoge proc
	mov	eax, ecx
	add	eax, eax
	ret
hoge endp
end
```