OmniAICreator/Qiita-1.07M huggingface dataset:
BLE Central@Spresense SDK3.1.0 の不具合パッチ

# 初めに

Spresense の SDK3.1.0 で BLE Add-onを動かす際にバグがあることを発見し、これを修正するパッチを作ったので載せます！

SDK3.1.0では、複数のCharactaristicを持つPeripheralデバイスのCharactaristicをdiscoverしようとすると無限ループに入ってしまいます。また、Indicatorイベントを受けた時に、ACKを返さないため応答が完了しないという問題もありました。

# 必要なもの

[**SPRESENSEメインボード[CXD5602PWBMAIN1]**
https://www.switch-science.com/catalog/3900/](https://www.switch-science.com/catalog/3900/)
<img src="https://d2air1d4eqhwg2.cloudfront.net/images/3900/500x500/42ccd153-3e89-4f7c-921c-775bc7de996d.jpg" width="200">

[**BLE1507 (BLE for Spresense)**
https://crane-elec.co.jp/products/vol-24/](https://crane-elec.co.jp/products/vol-24/)
<img src="https://crane-elec.co.jp/wp/wp-content/uploads/2022/07/attached_BLE1507-1024x768.jpg" width="200">



# ブログ（元ネタ）
この記事は、以下のブログに過去に投稿したもののまとめです。

http://spresense.livedoor.blog/archives/34489551.html

# 修正コード

修正コードを以下の、Spresense developブランチのforkにcommitしました。

https://github.com/Interested-In-Spresense/spresense/commit/1e218f25d78573acf40e9a5e8f6522eadb47b457

こちらを確認していただき、適宜、パッチを当てれば正しく動作できるようになります！

とりいそぎ。
TypeScriptで学ぶ型安全な開発プラクティス【その２】TypeScriptの基本

https://qiita.com/YushiYamamoto/items/1721e9030e1612125ceb#%E6%A6%82%E8%A6%81

# TypeScriptの基本（2025年版）

## **概要**
TypeScriptは、JavaScriptに型付けの概念を追加した静的型付け言語で、モダンなウェブ開発では欠かせないツールとなっています。本記事では、TypeScriptのセットアップ方法から基本的な型定義、型推論までを最新情報を交えてわかりやすく解説します。初心者から中級者まで、TypeScriptの基礎をしっかりと学びましょう。

---

## **1. TypeScriptのセットアップ方法** ⚙️

### **ステップ1: Node.jsのインストール**
TypeScriptを使用するにはNode.jsが必要です。公式サイト（[https://nodejs.org/ja/](https://nodejs.org/ja/)）からインストールしてください。

### **ステップ2: TypeScriptのインストール**
以下のコマンドでTypeScriptコンパイラをグローバルにインストールします：
```bash
npm install -g typescript
```

インストール後、以下のコマンドでバージョンを確認できます：
```bash
tsc -v
```

### **ステップ3: プロジェクトの初期化**
プロジェクトごとにTypeScriptを設定する場合は、以下の手順を実行します：
1. プロジェクトディレクトリを作成：
   ```bash
   mkdir my-typescript-project
   cd my-typescript-project
   ```
2. npmプロジェクトを初期化：
   ```bash
   npm init -y
   ```
3. TypeScriptを開発依存としてインストール：
   ```bash
   npm install -D typescript
   ```
4. `tsconfig.json`ファイルを生成：
   ```bash
   npx tsc --init
   ```

これでプロジェクト内でTypeScriptを使用する準備が整います。

---

## **2. 基本的な型の定義と使用方法** 🛠️

TypeScriptでは、基本的な型から複雑な型まで幅広くサポートされています。以下に主要な型定義の例を示します：

### **プリミティブ型**
```typescript
let x: string = "hello";
let y: number = 42;
let z: boolean = true;
```

### **配列型**
```typescript
let arr: string[] = ["hello", "world"];
```

### **オブジェクト型**
```typescript
let obj: { name: string; age: number } = { name: "Alice", age: 25 };
```

### **タプル型**
```typescript
let tuple: [string, number] = ["hello", 42];
```

### **列挙型 (enum)**
```typescript
enum Color {
  Red,
  Green,
  Blue,
}
let favoriteColor: Color = Color.Green;
console.log(favoriteColor); // 出力: 1
```

💡 *ポイント*: 型定義により、コードの可読性と安全性が向上します。

---

## **3. 型推論とは何か？** 🔍

### **型推論の概要**
TypeScriptは、明示的に型注釈を書かなくても、変数や関数の型を自動的に推論します。これにより、コードが簡潔になります。

#### **例: 型推論**
```typescript
let message = "Hello, TypeScript!"; // TypeScriptは自動的にstring型と推論

function add(x: number, y: number): number {
  return x + y;
}

add(1, "2"); // コンパイル時エラー
```

### **明示的な型注釈が必要な場合**
複雑な構造や曖昧なケースでは、明示的に型注釈を書くことでコードの理解が容易になります。

#### **例: 型注釈**
```typescript
let coordinates: { x: number; y: number } = { x: 10, y: 20 };

function multiply(a: number, b: number): number {
  return a * b;
}
```

💡 *ポイント*: 型推論と型注釈を適切に使い分けることで、効率的かつ安全なコーディングが可能です。

---

## **4. 最新機能とベストプラクティス（2025年版）** 🚀

### **4.1 テンプレートリテラル型**
特定の文字列パターンを強制する新しい方法です。
```typescript
type Route = `/${"home" | "about" | "contact"}`;
const homeRoute: Route = "/home"; // OK
const invalidRoute: Route = "/invalid"; // エラー
```

### **4.2 ユーティリティタイプの活用**
TypeScriptには便利なユーティリティタイプが多数あります。
- `Partial<T>`: オプショナルプロパティとして定義。
- `Readonly<T>`: 読み取り専用プロパティとして定義。

#### **例: Partial の使用**
```typescript
interface User {
  id: number;
  name: string;
}

const updateUser = (user: Partial<User>): void => {
  console.log(user);
};
```

---

## **まとめ**

TypeScriptは、その強力な型システムによって安全で効率的な開発を可能にします。本記事で紹介した以下のポイントを実践することで、TypeScriptの基礎をしっかりと身につけることができます：

1. TypeScript環境のセットアップ  
2. 基本的な型定義とその活用方法  
3. 型推論と明示的な型注釈の使い分け  
4. 最新機能やベストプラクティス  

これらを活用して、高品質で保守性の高いコードを書いていきましょう！ 🎉
bash, zshにGitのブランチ名をいい感じに表示する（サンプルあり）

未来の自分のために、設定方法といくつかサンプルを載せておこうと思います

## 設定方法
### git-prompt.sh のダウンロード

```bash
curl -o ~/.git-prompt.sh \
    https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
```

`git-prompt.sh` は、Gitのステータスをプロンプト表示できるツール（Git公式のツール）
ユーザのホームディレクトリにダウンロードします

### .bashrc の設定

```bash
sudo vi ~/.bashrc
```

```bash:.bashrc
# 以下を追加
if [ -f ~/.git-prompt.sh ]; then
    source ~/.git-prompt.sh
fi
GIT_PS1_SHOWDIRTYSTATE=true 
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto

PS1='\e[32m\u@\h \e[1;34m\w\e[1;31m$(__git_ps1 " (%s)") \e[0m\$ '
```

```bash
source ~/.bashrc
```

カスタマイズしたプロンプト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/a98c90bf-c7f9-0230-e059-99517b4bf509.png)

## `PS1=...` のサンプル

### ブランチ名の後で改行
```bash
PS1='\e[32m\u@\h \e[1;34m\w\e[1;31m$(__git_ps1 " (%s)")\e[0m\n\$ '
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/13401b0f-28b2-58fb-7137-913dba00e633.png)

### シェルの名前を表示
```bash
PS1='\e[32m\s \e[1;34m\w\e[1;31m$(__git_ps1 " (%s)")\e[0m\n\$ '
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/aff0d1e1-ca2f-029f-0b47-4547aa16504b.png)

### 日時を表示
```bash
PS1='\e[32m\u@h \e[33m\d \@ \e[1;34m\w\e[1;31m$(__git_ps1 " (%s)")\e[0m \$ '
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/57efdd65-0354-4d62-85ee-e31ea9cf1869.png)


# 解説

`.bashrc` の内容は一見わかりにくいですが、分割すると以下のようになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368005/7047c3a9-b9fd-6722-642b-f90c95acf51f.png)

「特殊文字」と「文字装飾」を組み合わせてカスタマイズしています

## 特殊文字

PS1変数には `\u` や `\h` など、特殊文字が用意されており、OS情報などを表示できます

| 特殊文字 | 詳細 |
| ---- | ---- |
| `\u` | ユーザー名 |
| `\h` | ホスト名 |
| `\w` | ホームディレクトリ基準のカレントディレクトリ |
| `\$` | `$` (rootユーザーでは`#`) |

詳しい内容は、以下が参考になります

https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/002cngprmpt.html

## 文字装飾

`\e[...m` は、以降の文字装飾を変更しています
`...` の値によって装飾されます

また、`\e[1;31m` のように;で区切られたものは
`\e[1m`(ボールド) と `\e[31m`(赤文字) を組み合わせたものになります

| 文字装飾 | 詳細 |
| ---- | ---- |
| `\e[32m` | 緑文字 |
| `\e[1;34m` | 青文字とボールド |
| `\e[1;31m` | 赤文字とボールド |
| `\e[0m` | デフォルトにリセット |

詳しい設定内容は、以下の「ECMA-48 グラフィクスレンディション(Graphics Rendition)の設定」が参考になります

https://manpages.ubuntu.com/manpages/xenial/ja/man4/console_codes.4.html

## `GIT_PS1_...` について

`.git-prompt.sh` のオプションです
`__git_ps1` で表示される内容をカスタマイズできます

| 環境変数 | 詳細 | 表示 |
| ---- | ---- | ---- |
| `GIT_PS1_SHOWDIRTYSTATE` | unstagedな変更がある時に `*` を表示<br>stagedな変更がある時に `+` を表示 | unstaged: ```(main *)```<br>staged: ```(main +)``` |
| `GIT_PS1_SHOWUNTRACKEDFILES` | untracked filesがある時に `%` を表示 |  ```(main %)``` |
| `GIT_PS1_SHOWSTASHSTATE` | stashedがある時に `$` を表示 | ```(main $)``` |
| `GIT_PS1_SHOWUPSTREAM` | upstream より遅れている時 `<` を表示<br>upstream より進んでいる時 `>` を表示<br>upstream から分岐している時 `<>` を表示<br>upstream と一致している時 `=` を表示 | 遅れている: ```(main <)```<br>進んでいる: ```(main >)```<br>分岐している: ```(main <>)```<br>一致している: ```(main =)``` |
TypeScriptで学ぶ型安全な開発プラクティス【その１】型安全性の必要性

# TypeScriptで学ぶ型安全な開発プラクティス（2025年版）

## **概要**
この記事では、TypeScriptを用いた開発における「型安全性」の重要性を解説します。近年、TypeScriptはモダンなウェブ開発において欠かせないツールとなり、その型安全性はバグの削減や開発効率の向上に大きく寄与しています。本記事では、初心者から中級者までが理解できるよう、具体例を交えて型安全性のメリットと実践方法を紹介します。

https://qiita.com/YushiYamamoto/items/1721e9030e1612125ceb



---

## **1. 型安全性の必要性** 🛡️

### **動的型付けと静的型付けの違い**
- **動的型付け言語（例: JavaScript）**  
  実行時まで変数のデータ型が確定しないため柔軟性が高い一方、予期せぬバグが発生しやすい。
- **静的型付け言語（例: TypeScript）**  
  コード記述時に型を定義し、コンパイル時に型の一貫性をチェック可能。これにより、安全で信頼性の高いコードを生成できます。

#### **例: JavaScript vs TypeScript**
```javascript
// JavaScript (動的型付け)
let value = "hello";
value = 123; // 実行時エラーの可能性あり

// TypeScript (静的型付け)
let value: string = "hello";
value = 123; // コンパイルエラーで検出
```

### **型安全性とは何か？**
「型安全性」とは、プログラム内で意図したデータ型のみを扱い、型エラーをコンパイル時に検出する能力を指します。これにより以下が実現します：
- バグの早期発見
- コードの予測可能性向上
- 開発者間のコミュニケーション効率化

---

## **2. 型安全性を追求するメリット** 🌟

1. **実行時エラーの削減**  
   型チェックにより、実行時エラーを未然に防ぎます。
2. **コードの読みやすさと保守性向上**  
   明確な型定義により、コードが自己文書化されます。
3. **早期バグ検出と修正**  
   コンパイル時にエラーが検出されるため、修正コストが低減します。
4. **チーム開発の効率化**  
   型情報がドキュメントとして機能し、新しいメンバーも迅速にプロジェクトへ参加可能。

---

## **3. 型安全なコーディングプラクティス** 🛠️

### **3.1 明示的な型定義**
TypeScriptでは、変数や関数の引数・戻り値に明示的な型定義を行うことで、コードの可読性と安全性を向上させます。

#### **例: 明示的な型定義**
```typescript
function greet(name: string): string {
  return `Hello, ${name}!`;
}

const message: string = greet("Alice");
```

### **3.2 `unknown` の活用**
`any` は極力使用せず、安全な `unknown` を活用しましょう。

#### **例: unknown の使用**
```typescript
let data: unknown;

if (typeof data === "string") {
  console.log(data.toUpperCase()); // 型チェック後に操作可能
}
```

### **3.3 型ガードとユニオン型**
複数の可能性がある場合はユニオン型を使用し、型ガードで絞り込みます。

#### **例: ユニオン型と型ガード**
```typescript
type UserInput = string | number;

function processInput(input: UserInput): void {
  if (typeof input === "string") {
    console.log(`文字列入力: ${input}`);
  } else {
    console.log(`数値入力: ${input}`);
  }
}
```

---

## **4. tsconfig.json の活用** ⚙️

TypeScriptプロジェクトでは、`tsconfig.json` を適切に設定することで、厳密な型チェックと効率的な開発環境を構築できます。

### **推奨設定例**
```json
{
  "compilerOptions": {
    "strict": true,
    "target": "ES2020",
    "module": "CommonJS",
    "baseUrl": "./src",
    "paths": {
      "@components/*": ["components/*"]
    }
  }
}
```

### **設定オプション**
- `strict`: 厳密な型チェックを有効化。
- `noImplicitAny`: 暗黙の `any` を禁止。
- `strictNullChecks`: `null` と `undefined` を厳密に区別。

---

## **5. 最新機能とベストプラクティス（2025年版）** 🚀

### **5.1 新機能：Template Literal Types**
テンプレートリテラルタイプで特定の文字列パターンを強制できます。
```typescript
type Route = `/${"home" | "about" | "contact"}`;
const homeRoute: Route = "/home"; // OK
const invalidRoute: Route = "/invalid"; // エラー
```

### **5.2 ユーティリティタイプの活用**
TypeScriptには便利なユーティリティタイプが多数用意されています。
- `Partial<T>`: オプショナルなプロパティとして定義。
- `Readonly<T>`: プロパティを読み取り専用に。

#### **例: Partial の使用**
```typescript
interface User {
  id: number;
  name: string;
}

const updateUser = (user: Partial<User>): void => {
  console.log(user);
};
```

---

## **まとめ**

TypeScriptで「型安全性」を追求することは、高品質なコードを書くための第一歩です。本記事で紹介したポイントを実践することで以下が期待できます：
1. 実行時エラーの削減。
2. コード可読性と保守性向上。
3. チーム開発効率化。

2025年現在も進化し続けるTypeScript。最新機能やベストプラクティスを取り入れながら、安全で効率的な開発環境を構築していきましょう！ 🎉
40代事務職Java面白い！6週間勉強してオブジェクト指向とGithub便利だなって思った

公式ドキュメントを読め！おじさんに疲れたので、じゃあ英語で読めるようにアメリカのオンライン大学のコンピューターサイエンス学部に2023年9月に入学しました。現在社会人学生です。
11月からプログラミングのJavaコース入門で勉強してます。

1週間のカリキュラム
使用しているテキスト※公式サイトで公開されているシラバスより引用してます
Introduction to Programming Using Java Version 9.0, JavaFX Edition
https://math.hws.edu/javanotes/index.html

公式サイト掲載シラバスよりhttps://www.uopeople.edu/become-student/prepare-for-uopeople/prepare-college-courses/programming-1-cs-1102-learning-materials/

- その週のテーマのテキストを読む
- その週テキストで学んだことを英語のエッセイ形式で書く
- 毎週プログラミングのコードを書く課題

こんな感じです。

プログラミングの課題は、世の中によくあるシステムで、こういうのを作ってみてください。という感じです。

1～4週でJavaの基礎を終わらせる エラー処理もしっかりやりましょう
5週目：オブジェクト指向で作りましょう カプセル化 class method バシバシ使いましょう
6週目：ポリモーフィズム、継承 オーバーライド インターフェースしっかりやりましょう

わかり易く説明すると
スッキリわかるJava入門の本を 6週間で理解できて自分で簡単なシステムを作れるようになるって感じです。

5週目のオブジェクト指向が最初なれなくて、作っては壊し作っては壊ししてました。この週は毎日深夜まで数時間コード書いてました。コードが多くなっていけばなるほど、エラー処理を追加したり、そしたらなんかどっかで{}のつけわすれしたり、変なループしたりしてどこを直していいか分からなくなりました。

でもオブジェクト指向で作ると、機能をガンガン切り出して使いまわしできるので、これ便利じゃん！って思いました。いかに使い回せるように作るのかと言うのって大事ですね。

5週目にそういえばGithubで履歴管理すれば、ソースコードの履歴管理できたはず！っというちょっとかじったgitを思い出しGit管理を導入しました

そしたら間違えても戻れるし、試しにブランチ作って遊んでみたりしました。でもいまいちマージするときのやり方が理解してないからそれはまた勉強する

話は戻ると、インターフェースや継承まで使えるようになると、どんどんコードがきれいになっていくので、面白くなってきました。

最初はこんなのやだよ。。。Javaなんてやりたくないよ、Pythonで遊びたいよ。。。って思ってました。
でもこうして強制的にJavaを勉強する環境になって

- データ型って最初はめんどくさいけど、どんなデータが入っているかわかるから便利
- データ型でエラー多いけど、エラーで変な処理をしてることに気がつけるから助かる
- オブジェクト指向だと、どのメソッドorクラスがエラー起こしてるかわかるから修正しやすい
- インターフェース便利すぎる継承楽しい最高じゃん
- 英語と自分で買ったスッキリわかるJava入門のテキストで勉強してるから、公式ドキュメントに抵抗なくなった
- コメントを書くとき英語で書けばいいから日本語と英語にわざわざ変更しなくていい
- エラーは英語でも普通によめるようになって助かる
- Git管理は一人でも大事。こまめなコミットも大事

特にインターフェースと継承は沢山の人と開発するときにはとても便利な機能だなと感じました。同じコードをわざわざ全員書かなくてもいいっというのが私が気に入ったポイントです

ここまでやできるようになるとJavaは大変だけど、面白いなって思います。あとの設計を考えたインターフェースとかなんか、後々を考えて要件を定義するスーパーエンジニアになった気分になれます。

このJavaの授業全部で8週間あるから、あとはGUI操作して今まで作ったやつをさらにパワーアップしたツールを作らなきゃいけない

マジ大変さがドラゴンボール並みにインフレしていく
でも楽しいからなんとか頑張れるよ
【目次】TypeScriptで学ぶ型安全な開発プラクティス

# TypeScriptで学ぶ型安全な開発プラクティス（2025年版）

## **概要の更新**
この記事では、2025年現在のTypeScriptを用いた型安全な開発の最新プラクティスを解説します。TypeScriptは静的型付けによるエラー検出やコードの保守性向上が可能であり、大規模開発において欠かせないツールとなっています。本記事は、初心者から中級者までを対象に、最新の機能やトレンドを取り入れた実践的なガイドを提供します。

---

## **目次**


### **型安全性の必要性**
- 動的型付けと静的型付けの違い
- 型安全性とは何か？
- 型安全性を追求することのメリット

https://qiita.com/YushiYamamoto/items/f17633da037506aacc81

### **TypeScriptの基本**
- TypeScriptのセットアップ方法（Node.js, Bun, Deno対応）
- 基本的な型定義と使用方法
- 型推論と明示的な型注釈の使い分け

https://qiita.com/YushiYamamoto/items/e28de67c6acbf560f6ca

### **高度な型の使い方**
- ジェネリックスとその制約 (`extends` の活用)
- ユニオン型とインターセクション型
- 条件付き型やマップド型など、複雑な型パターン

https://qiita.com/YushiYamamoto/items/9db4f094f826327c9c7f

### **実践！型安全な開発プラクティス**
- ReactやVue.jsでのコンポーネント設計とProps管理
- APIレスポンスの型定義とエラーハンドリング
- 状態管理ライブラリ（Redux, Zustand）での型適用

https://qiita.com/YushiYamamoto/items/6e60f9658466303f1271

### **型安全性を高めるためのツールとテクニック**
- 最新Lintツール（ESLint v9.18.0）の設定
- JestやVitestによるユニットテスト
- エディタ（VSCode）の高度な型チェック機能

https://qiita.com/YushiYamamoto/items/fe4a6c05a8717b690d5d

### **TypeScript 5.xシリーズの新機能活用**
- 型述語推論（Type Predicates）によるコード簡略化
- ECMAScript Setメソッド（`union`, `intersection`等）のサポート
- Nullishチェック強化オプション (`--strictBuiltinIteratorReturn`)

https://qiita.com/YushiYamamoto/items/2c2078082c1feb751269

https://qiita.com/YushiYamamoto/items/bce642183528c84516cb

### **まとめ**
- 型安全性に対する考え方と今後の展望
- TypeScriptによる開発ベストプラクティス

---

## **記事内容更新ポイント**

### **1. 最新トレンドに基づく背景説明**
2025年現在、TypeScriptはReactやAngularなど主要フレームワークで標準的に使用され、90%以上のフロントエンド開発者が採用しています。その背景には以下があります：
- 静的型付けによるバグ削減
- 大規模プロジェクトでの保守性向上
- IDEサポート強化（自動補完、コードナビゲーション）

### **2. 新しいTypeScript機能**
#### 型述語推論 (Inferred Type Predicates)
TypeScript 5.5以降では、関数本体から自動的に型述語を推論できるようになり、冗長なコードが不要になります。
```typescript
function isNumber(value: number | string) {
  return typeof value === 'number';
}

const result = [1, "a", 2].filter(isNumber); // resultはnumber[]として推論される
```

#### ECMAScript Setメソッドサポート
新しいSet操作メソッド（`union`, `intersection`など）を活用することで、データ処理がより簡潔になります。
```typescript
const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);
const union = setA.union(setB); // {1, 2, 3, 4, 5}
```

#### Nullishチェック強化オプション
`--strictBuiltinIteratorReturn`オプションにより、未初期化変数に対する厳密なチェックが可能になりました]。

### **3. 実践例：Reactコンポーネント**
以下はReactでPropsを型安全に管理する例です：
```typescript
type ButtonProps = {
  label: string;
  onClick: () => void;
};

const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
  <button onClick={onClick}>{label}</button>
);
```

---

## **結論**
この記事では、2025年現在のTypeScriptを活用した最新ベストプラクティスを紹介しました。特に、新機能やツールを取り入れることで、開発効率やコード品質を大幅に向上させることが可能です。これらを参考にしながら、より高度で保守性の高いプロジェクト構築を目指してください。
git pushでブランチ名をいちいち書くのめんどくさい！！

# これでコマンド打つのめんどくさい。
```
git push origin feature-1111/create_xxxx
```

# 以下の記述で解決

```
git push origin HEAD
```

git push origin HEAD は、現在チェックアウトしているブランチ（現在作業中のブランチ）をリモートリポジトリにプッシュするための簡便なコマンドです。これを使うことで、特定のブランチ名を毎回指定する必要がなく、現在作業しているブランチを手軽にリモートに反映できます。

:::note warn
注意点
git push origin HEAD では現在のブランチをリモートにプッシュするため、ブランチが追跡設定されていない場合や、リモートリポジトリに同名のブランチが存在しない場合は、エラーが発生することもあります。この場合は、git push --set-upstream origin HEAD のように追跡設定を行う必要があります。
:::


簡易的ですが以上です。
Do you already  have another mysqld server running on port: 3306 ? で3306ポートを使っていない

# 環境
```
Ubuntu 22.04.3 LTS \n \l
```

# 現象
ubuntuでmysqlにログインできない。
状態は起動中になっている。
```
$ sudo systemctl status mysql.service 
● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: activating (start) since ~
　　　　　　　　　　　　　　　　　　　　　　　　：
```
エラーログを見ると、以下のエラーが存在している。
```
$ vi /var/log/mysql/error.log
Do you already have another mysqld server running on port: 3306 ? # 抜粋
```

# 原因
「マシンのIPアドレス」と「cnfファイルのbind-addressのIPアドレス」が異なっている。

# 経過
```
netstat -aon | grep 3306
```
や
```
sudo lsof -i :3306
```
を実行しても、何も表示されない。

ネットの情報を参考に、cnfファイルを確認してみる。
/etc/mysql/mysql.conf.d/mysqld.cnfで設定していたので、
```
$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
<略>
bind-address            = xxx.xxx.xx.xx
mysqlx-bind-address     = xxx.xxx.xx.xx
# xxx.xxx.xx.xxをマシンのipアドレスに変更する
```
上書き保存して閉じる。
特に何もしなくとも、mysqlは起動して
```
$ sudo systemctl status mysql.service 
● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since ~
```
/var/log/mysql/error.logもプロセスに表示されなくなった。

# 感想
エラーログを見てもネットで調べても、3306ポートが既に使われているのが原因としか思えず、
netstatやlsofで引っかからないので、困りました。
cnfファイルの解決法を共有してくださった方が居て感謝です。

私の場合、停電があったのが原因でipアドレスが変更されたようです。
mysqlに関係するであろうcnfファイルはいくつかありますが、どれかを編集しているかと思います。
/etc/my.cnfとか/etc/mysql/my.cnfとか。

# 参考
https://www.anagix.com/gijutsu-memo/alb/mysqlgaqidongshinaitoraburu
https://nanaco-programming.hatenablog.com/entry/2019/06/11/121751
https://qiita.com/iwantit/items/837ba0ad5307e14b2b00
https://qiita.com/yosyosyoyoyo/items/b40f9fdf1da2b2abfab0
Aurora Serverless v1のリスト化方法

Aurora Serverless v1がサポート切れです。

v2と設定パラメータが異なるので地味に探しづらい代物

AWS Config Advanced Queryを使うなら


```sql
SELECT 略
WHERE
 resourceType = 'AWS::RDS::DBCluster'
 AND configuration.engineMode = 'serverless'

```

インスタンスではなくDBClusterを検索するのがポイントです。
v2のほうはインスタンスで検索できます。
Google Apps Script の MailApp.sendEmail 関数で、Web上の複数の写真を添付送信する

#### Google Apps Script の MailApp.sendEmail 関数で、Web上の複数の写真を添付送信します。
▼各々の引数を設定し、**sendEmail関数**を呼び出します。
```javascript
function callSendFunction() {
  var recipient = 'test@example.com', cc = '', bcc = '';
  var subject = '写真付きメール', msgBody = '写真付きメールです。';

  // 送信時のファイル名と画像URLを、2次元配列に設定する（ファイル名はnullか''で元のファイル名になる）
  var imageFiles = [
    [null, 'https://example/001.jpg'],
    ['002a', 'https://example/002.jpg'],
    ['', 'https://example/003.jpg'],
    ['004b', 'https://example/004.jpg'],
  ];
  //var imageFiles = null; // 添付写真がないとき
    
  sendEmail(recipient, cc, bcc, subject, msgBody, imageFiles);
}
```
▼**sendEmail関数**です。
```javascript
function sendEmail(recipient, cc, bcc, subject, msgBody, imageFiles = []) {

  // 改行コードを変換する（テキスト形式修復）
  var subject = subject.replace(/<br>/g, ' ').replace(/\n/g, ' ');
  var body = msgBody.replace(/<br>/g, '\n');

  // 画像レスポンスを取得する
  var imageRes = [];
  for (var i=0; i < imageFiles.length; i++) {
    imageRes[i] = UrlFetchApp.fetch(imageFiles[i][1]);   
  }

  // imageFilesがあればファイルのデータ型を取得してファイル名を復元する
  var blobs = [], fileName = [], extension = [];
  for (var i=0; i < imageFiles.length; i++) {
    // ファイルのデータ型を取得する
    blobs[i] = imageRes[i].getBlob();
    
    // ファイル名を設定する
    fileName[i] = decodeURIComponent(blobs[i].getName()); // 元のファイル名(拡張子含む)
    if (imageFiles[i][0]!=null && imageFiles[i][0]!='') {
      extension[i] = fileName[i].match(/\.[^.]+$/)[0]; // 元の拡張子
      fileName[i] = imageFiles[i][0] + extension[i]; // 新しいファイル名(拡張子含む)
    }
    blobs[i] = blobs[i].setName(fileName[i]); // (拡張子含む)
  }

  // Email 送信する
  MailApp.sendEmail (
    recipient,
    subject,
    body, {
      cc: cc,
      bcc: bcc,
      attachments: blobs // データ型の配列を渡す
    }
  );
}
```
Goのinterfaceをわかりやすく説明したい

## はじめに
何番煎じだという話ですが、Goのinterfaceついてどこよりもわかりやすく説明することを目標に記事を書きました。(型としてのinterfaceとは内容が異なります)

## 要点
### 1. インターフェースは特定のメソッドを持っている構造体をグループ化する仕組み
### 2. インターフェース内にメソッドを定義すると、同じインターフェースに属する構造体全てがインターフェース内のメソッドを使用可能

## 実際にコードを見てみよう
下のコードを見てください。構造体GokuとKrikkinは両方ともメソッドのKamehamehaを使用できます。

```
package main

import "fmt"

type Goku struct {
    Power int
}

func (g Goku) Kamehameha() {
    str := fmt.Sprintf("%d Kamehameha", g.Power)
    fmt.Println(str)
}

type Krillin struct {
    Power int
}

func (k Krillin) Kamehameha() {
    str := fmt.Sprintf("%d Kamehameha", k.Power)
    fmt.Println(str)
}
```

例えば、この2つに共通のメソッドであるTaiyokenを追加する場合、また1つ1つ追記しなければなりません。これは面倒ですね。

```
func (g Goku) Taiyoken() {
    fmt.Print("Flash!!\n")
}

func (k Krillin) Taiyoken() {
    fmt.Print("Flash!!\n")
}
```

2つだけなら楽ですが、他にも多くの構造体が同じメソッドを使用するとなると、いちいち書いていられません。そこでインターフェースの出番です。

```
type Kamesenryu interface {
    Kamehameha()
}
```

Kamesenryuというインターフェースを作成しました。
ここで注目するのは、Kamehameha()の部分です。これはKamehamehaメソッドを持っている構造体は全て、Kamesenryuインターフェースに属するという意味です。インターフェース内に記載されたメソッドはマーキングやラベルのようなものです。

```
func Taiyoken(k Kamesenryu) {
    fmt.Print("Flash!!\n")
}
```

新たにメソッドであるTaiyokenを定義しました。これでレシーバに指定されたKamesenryuに属する構造体は、全てTaiyokenを使用できるようになりました。

```
func main() {
    g := Goku{Power: 10000}
    g.Kamehameha()
    Taiyoken(g)
    
    k := Krillin{Power: 1000}
    k.Kamehameha()
    Taiyoken(k)
}
```

最後にコードの全てを掲載しておきます。

```
package main

import "fmt"

type Goku struct {
    Power int
}

func (g Goku) Kamehameha() {
	str := fmt.Sprintf("%d Kamehameha", g.Power)
	fmt.Println(str)
}

type Krillin struct {
    Power int
}

func (k Krillin) Kamehameha() {
	str := fmt.Sprintf("%d Kamehameha", k.Power)
	fmt.Println(str)
}

type Kamesenryu interface {
    Kamehameha()
}

func Taiyoken(k Kamesenryu) {
    fmt.Print("Flash!!\n")
}

func main() {
    g := Goku{Power: 10000}
    g.Kamehameha()
    Taiyoken(g)
    
    k := Krillin{Power: 1000}
    k.Kamehameha()
    Taiyoken(k)
}
```

ご指摘あればワクワクしながら待ってます。
2022～2023年の感じたこと


# 目的
前回の総括をまとめてから2年が経ったので、備忘としてメモしました。

# アジェンダ 
1. 筆者の2年間 
2. エンジニアに必要なもの
3. コミュニケーションツールの活用
4. テレワークについて
5. まとめ
6. 最後に

# 筆者の2年間
1. マイグレーションでテスト設計書作成～実施を経験
2. 結合されたテーブルからデータ抽出して報告する
3. SharePoint管理のチームで基本設計担当
4. PythonとExcelでBase64変換ツール作成
5. VBAでファイル分割やExcelファイル検索系のマクロを作成

# エンジニアに必要なもの
1. 報連相
> 進捗状況が苦しいときは特に重要です。

> 見積りや提案は推量を有識者やPL、PMとも認識合わせする

> 中間報告は分かりやすく、シンプルにしつつも、推量はしっかり正確に

2.(1)にあげたが、上長(報告先) も忙しいので、適度にコミュニケーションする(例 AM1回PM1回) 
> チャットやメールは流れやすいので、気になったスレッド等はテキストに保存しておくなりする。
> あとで検索しやすいように、送る内容は自身の中でルール化しておく。１度聞いたことは聞かないようになるために役に立つ。

3.参画当初にQA表を作成する。
> QA表には、不明点ごとにカテゴライズしておくと便利。また、同じファイル内に、「わかったこと」や「用語一覧」を設けること。現場内でしか使わない用語があったりする。例えば、３文字の英語略があったら、システムのことか協力会社のことを指しているのか、機能IDのことをいっているのかわからないので要確認しておく。
> QA表を運用していくと、有識者も忙しいので途中からチャットベースでのやり取りになってしまうときもあるが、そうなった場合は、QA表は更新されなくなることが多いので、自身で回答を貰ったらQA表を更新することが大切。

4.キャリアについて
> 毎月の終わりか１年の振り返りの際に、今の案件もしくは今の会社で今後成長していけるか活躍していけるかは考えた方がいいということ。昔の上長が、飲み会のときにいっていたのを思い出しました。


# コミュニケーションツールの活用
> GoogleチャットやTeams、Outlook
> GoogleチャットやTeamsはスレッド迷子にならないように、自身のみのスレッドに何かしらのスレッドのメモとしてルールを書いておくとわかりやすい。
[Google Chat を使用する方法](https://support.google.com/chat/answer/14170781?sjid=14617197743919931284-AP)
[teams使い方マニュアル(Microsoftページ)](https://download.microsoft.com/download/5/9/c/59cecaeb-4e47-40cd-9d95-6ef2916ea20c/Teams%E4%BD%BF%E3%81%84%E6%96%B9%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB_pc_2019.pdf)

> Outlookは、ルール設定をし、受信したらこのフォルダに飛ばすようにしておくと迷子にならない。
[仕分けルールを使ってメール メッセージを管理する](https://support.microsoft.com/ja-jp/office/%E4%BB%95%E5%88%86%E3%81%91%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%A1%E3%83%BC%E3%83%AB-%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B-c24f5dea-9465-4df4-ad17-a50704d66c59)


# テレワークについて
> 上長からは見えない状態が続くので、ZOOMやteamsであれば、回線に問題があるのかアクティブ状態だったはずが、勝手に不在や取り込み中になっていることがあるので確認する時間をルール化しておくと良さそう。

# まとめ
> コミュニケーション系やコミュニケーションツールについて触れてきたが、まとめるとチームにとっても自身にとってもなんでも「ルール化」しておくことは大切である。ということです。

# 最後に 
今年１年お疲れ様でした。また、来年もよろしくお願いいたします。

# 参考 
https://samanthaheart.com/blog190730/
駄目グラフ003

ダイナマイトプロットは描かない

## ![20111210220621.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/ed27d75a-0f9d-74d5-bdbe-211dc2d9f653.jpeg)

そもそも，エラーバーも何を基準にするか。何を基準にしても，わかりにくいことに違いはないが。
AWS Certified Solutions Architect - Professional (SAP-C02) に合格しました

SAP-C02に合格しました。
こちらに記録と感想を記載します。

# 受けた試験
* SAP-C02( AWS Certified Solutions Architect - Professional )
* 受験日: 2023-12-27
* 受験者スコア: 756/1000

# 感想
想定以上に難易度が高く大変苦労しました。試験終了時には落ちたなと思って落胆していました。合格できたのは運が良かったのかもしれません。

自分的には、
* 長めの問いの文章から重要なポイントを抜き出し、要件を素早く理解する。
* 回答の選択肢から間違いが含まれるものを除外して、ベストプラクティスに沿ったもの、場合によってはベストプラクティスではないが妥当なものを探して早く回答する。
* これらを75回、3時間繰り返す。

このパターンの試験は苦手だなと感じました。

180分は相当長く感じました。集中力が切れるし、2時間経過したくらいでトイレに行きたくなって汗が出ました。
特に "複雑な組織に対応するソリューションの設計" は何度繰り返し勉強しても苦手意識が強くて、公式ドキュメントや本を読んで理解したと思っても応用できないだろうなあという感覚がずっとありました。
試験の結果もそのカテゴリは "改善が必要" の判定でした。

合格まで苦労がありましたが、取得の勉強をして損がない資格ではないかなという印象です。
AWSを使って課題を解決する能力は向上したと思います。


# 勉強期間
2017年に AWS Certified Solutions Architect - Associate に合格してからしばらく受験していなかったのですが、その後も Professional に向けた勉強は少しずつ進めていました。
一日15分〜30分ほど確保して勉強していて、今年の11月初めから本格的に試験対策の勉強を開始して一日2h〜4h、12月に入ってからは一日3h〜6hぐらい、直前の数日は12hぐらい勉強しました。
トータルすると多分300h以上は勉強していると思います。あまり効率の良い勉強はできていなかったかもしれません。

# 学習の進め方
* 本
  * 『AWS認定ソリューションアーキテクト-プロフェッショナル』(SAP-C01)
  * 『AWS認定資格試験テキスト＆問題集　AWS認定ソリューションアーキテクト - プロフェッショナル　改訂第2版 Kindle版』
* Umedy
  * AWS認定ソリューションアーキテクト プロフェッショナル模擬試験問題集
* 公式
  * 各サービスの公式ドキュメント、ブログ
  * 模擬試験
  * Skill Builder

試験勉強としては、
* まず自分の苦手な分野や知らない知識を把握する
* それを公式ドキュメント、ブログ、本、クラスメソッドさんの記事などを読んで集中的に調べて勉強する
* 問題に慣れるためにとにかく繰り返し問題を解く

という感じで進めました。

手書きで図やメモを書いたりまとめたりして覚えました。なんだかんだで手で書いたものは覚えている率が高かったです。
SkillBuilder の動画も少し見ましたが良かったと思います。

AWSの新サービスの追跡は欠かせません。
当たり前かもしれませんが、公式ドキュメントを読むのが大事だと改めて思いました。
アップロード画像を全消しした話

# S3のコンテンツを管理したい

そのWebサービスでは画像やJS、CSSなどの静的リソースをAWSのS3に上げて利用していたのですが、マネコンから手動でアップロードしている状態でした。
そのため、量が多いと作業も大変ですし、抜け漏れなどの人的ミスも発生していました。

元々その静的リソースはgitにも保存していたので、gitで管理しているリソースをawsのcliで `aws s3 sync` で同期した方が確実だし楽じゃん！、と思いデプロイ手順を変更しました。

# gitとs3の手動同期

そもそも今gitとs3の中身って本当に同じなの？、という疑惑があったので、 `aws s3 sync` で全差分を出して一つずつチェック。
S3にしかないもの、gitにしかないもの、これどこで使ってるの？、みたいなファイルが山ほどあり、調整は時間を要しましたが、基本はS3に上がっているものが正なので、差分はS3のものを残す方針で、どうにかgitとS3のリソースを完全一致させることができました。

# デプロイ手順の変更

- dryrunで差分を確認。ルートパスでやると余計な差分出てしまうかもしれない＆時間かかるので、最小の範囲のパスで。
  - `aws s3 sync path_to_target_localdir/ s3://BACKET/path_to_target_s3dir/ --delete --dryrun`
- 意図通りの差分であることを確認して、OKだったら実行
  - `aws s3 sync path_to_target_localdir/ s3://BACKET/path_to_target_s3dir/ --delete`

この方式でデプロイするようにし、作業はだいぶ楽になりました。

# それから3ヶ月後

新しいデプロイ手順にも慣れ、いつも通り本番デプロイした後に、**「このページの画像が全部でなくなったんだけど」** との問い合わせが・・・。

そのページは独自のCMSで作られているページで、記事や画像を管理画面から入力して生成する機能でした。
削除された画像のパスを見て、3ヶ月前のある記憶が蘇りました・・・。

----

（3ヶ月前の記憶）
「このS3のフォルダ、大量に画像上がってるけど、gitには一つもないなあ。なんだこれ」
「うわ、CMSの画像アップロード先、静的リソース置き場になっちゃってるじゃん・・・」
「どこかのタイミングで、アップロード先変更しないとなあ」
**「とりあえずは、同期する時にこのフォルダ除外するようにしておこう」**

----

**そう、調査のときに一つ除外しないといけないフォルダを確認していたのにも関わらず、すっかり忘れていました。**

デプロイ時にdryrunで差分をチェックする手順でしたが、作業慣れからチェックが形骸化しdryrunは実行するものの「まああってるでしょ」みたいなノリで異変を見逃され、**gitにはないアップロード画像数百枚全削除** の同期が実行されてしまいました・・・。

幸い、元になる画像は運用担当者の手元に残っていたので、全て上げ直してもらうことで復旧はできました。

# 運用方法の変更

`aws s3 sync` には `exclude` の除外オプションもありますが、また別のフォルダで起きるかもしれないので、根本的に変えました。

- `aws s3 sync` は禁止
- ファイルの追加は `aws s3 cp` 、削除は `aws s3 rm` で一つずつ実行
  - 事前にスクリプトを用意しておく
- コマンドの実行ログを記録に残す
- そもそも静的リソース置き場をgitで管理しないCMS等のアップロード先にしない

# ヨシ！

現場ネコの **[「前の2人が合格にしてるんだから絶対ヨシ！」](https://twitter.com/karaage_rutsubo/status/1157112554910437377)** を思い出しました。
CSSセレクター

## はじめに
新入社員教育でウェブ開発について学習しています。
今回は学習の中で複雑だと感じた、
CSSセレクターの種類や記述方法についてまとめました。

## CSSとは

CSS（Cacading Style Sheets）とは、
Webページ内の文字（テキスト）、画像や動画の幅、余白を指定したり、
それぞれの表示箇所を指定してレイアウトを決めたりするプログラミング言語です。

```css:app.css
h1 {
    color:green;
}
```



## CSSの構成要素
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/6e5fa764-e56a-7dc4-be5f-7a270b931eb0.png)

:::note info
cssの記述は
- [x] セレクタ（どの要素？）
- [x] プロパティ（なにを？）
- [x] 値（どんな風に？）
の３つの要素でできている。
:::

「h1」がCSSセレクターに相当し、
h1{・・・}と記載することでh1タグで囲った要素のみスタイルを指定させています。

〇〇{・・・}の〇〇部分をCSSセレクターと呼びます。

## セレクターの種類

| 区分| セレクタの種類 | 説明 | 記述例 |
|:-:|:-:|:-|:-:|
| 基本 | 全称セレクタ   | すべての要素を対象にします。 | * |
| 基本 | 要素型セレクタ | h1のようなタグで記述する要素を<br>対象にします。 | h1  |
| 基本 |  IDセレクタ | ID指定した要素を対象にします。 | #test |
| 基本 | クラスセレクタ | クラス指定した要素を対象にします。 | .test |
| 基本 | 属性セレクタ | 指定した属性を持つ要素を対象にします。 | h1[id] |
| 基本 | 疑似クラス | マウスが上にある時や最初の要素など<br>特定状態の要素を対象にします。 | a:hover|
| 基本 | 疑似要素 | 最初の行や文字など、<br>要素内の特定の場所を対象にします。 | p::first-line |
| 結合 | グループ化セレクタ | 複数の要素をまとめて(グループにして)<br>対象にします。 | h1, p |
| 結合 | 小孫結合子| 特定の親要素を持つ子要素や孫要素を<br>対象にします。| div p |
| 結合 | 子結合子| 特定の親要素を持つ子要素だけを<br>対象にします。| div > p|
| 結合 | 隣接兄弟結合子 |同じ階層にある次の要素を対象にします。|h1 + p|


			
	
			


## CSSで複数のclass名を指定(結合)
:::note info
1. class名を「 ``, ``( カンマ ) 」で区切る
2.  class名を「 ( 半角スペース ) 」で区切る
3.  class名を繋げて記述
4. class名を「 ``+`` ( プラス ) 」で区切る
5. class名を「 ``>`` ( 大なり記号 )」で区切る
:::

HTMLは以下のものを使用します。
```html:index.html
 <div class="parent1">
     <p class="p1 child1">子要素A</p>
     <p class="child2">子要素B</p>
     <p class="child3">子要素C</p>
 </div>
   <div class="parent2">
     <p class="child1">子要素D</p>
     <div class="child2">
         子要素E
         <p class="grandchild">子孫要素e</p>
     </div>
   </div>

```

### 1. class名を「 ``,`` ( カンマ ) 」で区切る
```CSS:css
.child1,.child2 {
 color: red;
}
```
【結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/aee7f547-08d8-d6a3-944f-7a7cce7b2458.png)



class名がchild1とchild2の要素の文字が赤くなる


### 2. class名を「 ( 半角スペース ) 」で区切る
```CSS:css
.parent2 .child1 {
 color: red;
}
```
【結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/190c5850-d6af-f4e3-9080-6a62889c43d4.png)


parent2を親要素に持つchild1が適用範囲となる


### 3. class名を繋げて記述
```CSS:css
.p1.child1 {
 color: red;
}
```
【結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/d121a963-56b3-c105-c6d5-438e1e804f54.png)


class名にp1とchild1の両方がある要素のみが適用範囲となる

### 4. class名を「 ``+`` ( プラス ) 」で区切る

```CSS:css
.child2 + p {
  color: red;
}
```
【結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/0dce2f12-2868-0484-05bb-8a8055c9c53b.png)
child2と同じ階層の、すぐ後のp要素にだけ適用される

### 5. class名を「 ``>`` ( 大なり記号 ) 」で区切る
```CSS:css
.parent2 > p {
  color: red;
}
```
【結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632608/b8e7f432-3a9c-19dc-eb0b-63122dd0d527.png)
parent2の、1つ下の階層にあるp要素を指定する

## 参考

https://beginners-hp.com/create_css_selector.html

https://webliker.info/css-selector-cheat-sheet/
ghaにおけるrspecで発生するActiveRecord::ConnectionNotEstablished:  MySQL client is not connected への対処案（動作未確認）

## エラー内容

```rb
 ActiveRecord::ConnectionNotEstablished:
       MySQL client is not connected
```

## 改善前の実装

```yml:.github/workflows/backend_test.yml
name: Backend Test

jobs:
  run-rspec:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        ports:
          - 3306:3306
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
```

## 改善策

ヘルスチェック周りのオプションを設定する
これにより、rspec実行前にmysqlコンテナの起動が完了していることを確認できるようになる（はず）。

## 改善後の実装

```yml:.github/workflows/backend_test.yml
name: Backend Test

jobs:
  run-rspec:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        ports:
          - 3306:3306
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
```

## 参考

https://zenn.dev/snowcait/articles/0cc4a464610e61

https://docs.github.com/ja/actions/using-containerized-services/about-service-containers

https://dev.mysql.com/doc/refman/8.0/ja/mysqladmin.html
開発者向け：VagrantとDockerの特徴と選び方を徹底解説🌟

# VagrantとDockerの違い（2025年版）🚀

## **概要**
VagrantとDockerは、開発環境を効率化するためのツールですが、その目的やアプローチに大きな違いがあります。2025年現在、両ツールは進化を続け、それぞれの強みを活かした活用が求められています。本記事では、最新情報を基にVagrantとDockerの違いをわかりやすく解説します。

---

## **Vagrantとは？🏠**
![スクリーンショット 2023-12-28 14.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/f9aa929c-adf8-a1b6-aa1f-dbc1a071e7b9.png)
https://www.vagrantup.com/

Vagrantは、仮想マシン（VM）を管理するためのツールで、開発環境を再現性高く構築できます。

### **特徴**
- **完全な仮想マシン**を作成し、ホストOSとは独立した環境を提供。
- **Vagrantfile**を使用して、環境設定をコード化。
- VirtualBoxやVMwareなどのプロバイダーと連携可能。
- **HCP Vagrant Registry**によるボックス共有が簡単に。

### ✅ **メリット**
- 高い**セキュリティ**と完全なリソース分離。
- 複雑なネットワーク設定や複数台構成が容易。
- 異なるOS（例: Windows上でLinux）を実行可能。

### 📌 **基本コード例**
```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
  config.vm.network "private_network", type: "dhcp"
  config.vm.synced_folder ".", "/vagrant", type: "rsync"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end
end
```

---

## **Dockerとは？⚓**
![スクリーンショット 2023-12-28 14.06.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/3e7f4ea9-a19d-1711-ef6c-b41e0b6ddf0b.png)
https://www.docker.com/products/docker-desktop/
Dockerは、軽量な仮想化技術「コンテナ」を利用してアプリケーション環境を構築します。

### **特徴**
- コンテナはホストOSのカーネルを共有し、起動が高速。
- **Dockerfile**で環境構築手順を定義。
- Docker Hubでイメージの共有が簡単。

### ✅ **メリット**
- 軽量でリソース効率が高い。
- 環境の移植性が高く、ローカルからクラウドまで一貫した動作。
- マイクロサービスやCI/CDパイプラインとの親和性が高い。

### 📌 **基本コード例**
```dockerfile
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

---

## **VagrantとDockerの違い📊**

| 機能/特徴             | Vagrant                              | Docker                               |
|-----------------------|-------------------------------------|-------------------------------------|
| **仮想化タイプ**       | 仮想マシン（フルOS仮想化）           | コンテナ（軽量仮想化）               |
| **リソース消費**       | 高い                                 | 低い                                 |
| **起動時間**           | 数分（フルOS起動）                   | 数秒（コンテナ起動）                 |
| **セキュリティ**       | 高い（完全分離）                     | 中程度（カーネル共有）               |
| **移植性**             | 制限あり                             | 高い                                 |
| **ネットワーク設定**   | 高度な構成が可能                     | シンプルだが柔軟性あり               |
| **主な用途**           | 複雑な開発環境や異なるOSの再現        | アプリケーション単位の軽量環境構築   |

---

## **使い分けガイド🎯**

1. 🛡️ **セキュリティ重視・完全なOS分離が必要な場合**
   - Vagrantが適しています。例: 異なるOS間の開発や複雑なネットワーク設定。

2. ⚡ **軽量で高速な環境・マイクロサービス構築が必要な場合**
   - Dockerが適しています。例: CI/CDパイプラインやクラウドネイティブアプリケーション。

3. 🔗 **両方の利点を活用したハイブリッド運用**
   - Vagrant内でDockerコンテナを使用することで、柔軟性と効率性を両立可能。

---

## 💡 **まとめ**
VagrantとDockerは、それぞれ異なるニーズに応える強力なツールです。  
- Vagrantは「完全な仮想マシン」で複雑な環境再現に最適。  
- Dockerは「軽量コンテナ」で迅速かつスケーラブルなアプリケーション開発に最適。  

プロジェクトの要件に応じて適切に選択し、それぞれの強みを活かしてください！✨



https://qiita.com/YushiYamamoto/items/9b6598257f34f1b3bdfe

https://qiita.com/YushiYamamoto/items/abf45fb29a86a4ea5950

https://qiita.com/YushiYamamoto/items/767d6f4e82ba0dc2baf3
Overleafで卒論を書く

初めて卒論を書いた時TeXわからなすぎて変なとこで時間食ったので，やったことを残しておく

# まずはフォーマットをダウンロードしてOverLeaf上にアップロード
多分学院Wikiとかで配られている

# コンパイル設定
デフォルトのpdfLaTeXからLaTeXに変更

# 新たに追加するファイル

以下のファイルを追加

```:latexmkrc
$latex = 'platex';
$bibtex = 'pbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex %O -o %D %S';
$pdf_mode = 3; 
$ENV{TZ} = 'Asia/Tokyo';
$ENV{OPENTYPEFONTS} = '/usr/share/fonts//:';
$ENV{TTFONTS} = '/usr/share/fonts//:';
```

# .tex上での変更
一番最後の
`\bibliographystyle{jplain}`（多分アルファベット順に参考文献がナンバリングされる）から
`\bibliographystyle{junsrt}`（論文中の引用の順番にナンバリングされる）に変更

# 参考文献の載せ方
1. 引用したい論文のCitationを.bib形式でダウンロード
1. .BibDeskアプリで開く（多分デフォルトアプリ）
1. 二本指クリックで"Copy Minimal BibTex Record"を選択
1. OverLeafのreferences.bibファイル内にペースト．一番最初のエントリ（名前）を好きに変えて.texファイル上で\cite{}できるようになる

# 無料枠でコンパイルできなくなった！
タイムアウトしたから課金しろ，と言われたら，一旦以下の方法を試すと良い

## 画像を軽くする
特に大きくて画質の良い画像である必要がないなら，画像サイズを落とすか，png->jpegにするだけでかなり変わる．
私は[このサイト](https://png2jpg.com/ja/)に大変お世話になりました．

## コンパイルモードを変える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1789756/6e3d0e46-adcf-746a-be23-e9e9329c1286.png)
ここのコンパイルモードを「ファスト」にすることで，画像の表示を省略するので早くなる．
しかも，一旦ファストモードでコンパイルが通りさえすれば，その後ノーマルモードに戻して再度コンパイルできることが多い（なんかキャッシュが残ってるのかな）．

## 一旦本体を削る
上の手法をさらに応用（？）した手法．
画像が重い部分を一旦一気にコメントアウトして軽くし，コンパイルを通す→コメントアウトを外してリコンパイルすると通ったりする（低確率．別の要因だった可能性もある）．あんまり胸を張ってお勧めできる手法ではない．．．．
AI-102についての情報共有と受験しての所感

# はじめに
AI-102はMicrosoftのAzureにおけるAI関係の中級者向け資格。
この試験について「あまりにも日本語の情報が少ない！」（もちろんほかに良質な記事がいくつかQiitaにあったりするけどね）と感じたので、こうして書いている次第です。

# 前置き
##  ざっくり結論
- Microsoft公式ドキュメントの検索に慣れよう
- 勉強するのは結局公式ドキュメントが正義？

##  いつの受験の話？
2023年12月21日

:::note warn
##     試験内容の変更について
AI-102の試験範囲変更が予告されています。
Microsoft公式
https://learn.microsoft.com/ja-jp/credentials/certifications/exams/ai-102/
そのためこの記事の内容は公開後すぐに古い情報となっている可能性が高いです！
:::

当時の受験に基づいた記事ですので、少し役立つことはあるかもですが基本的に変更後の試験に対応はできません🙅

##  この記事のターゲット
AI-102を受験したいけど、あまり対策情報が出てなくて藁にも縋りたい方

##  どういった立場の人が書いてる？
2023年12月にAI-102を850/1000で合格。
Python・AIについて独学で勉強し始めて1年ちょっと。
エンジニア歴1年目の駆け出し。AZ-900, AI-900は事前に取得済み。

# AI-102受験お役立ち？情報
##  私がおこなった試験対策
- Microsoft Training

https://learn.microsoft.com/ja-jp/training
- Microsoft公式のAI-102模試

https://learn.microsoft.com/ja-jp/credentials/certifications/exams/ai-102/practice/assessment

- 上記試験で引っかかった問題に関するMicrosoft Learnをリストに入れ読む

https://learn.microsoft.com/ja-jp/azure/ai-services/
- Udemyにある模試

##  知っておいた方が良い注意点
- **Microsoft Learnを別ウインドウで検索しながら試験に臨めます**。ただし検索にやや癖を感じました
- **2023年12月21日時点で**出題されるのはまだCognitive Search。AI Searchなどは出題されませんでした。たしLearnの検索時AI Searchの結果が混じってきます
- 試験完了ボタンを押すとすぐに合否と点数が出ます。~~心臓に悪い~~
- 問題文は日本語と英語を切り替えられました。英語資料でも勉強していた方は活用してもいいかも

##  問題構成・時間配分
私の場合は**1時間40分**の試験時間で
1. 最初に要件や仕様を設定されたうえで解く**長文（？）問題4問**
2. **通常の択一式問題40問弱**
3. **後戻りできない〇×的な問題（後述）3問**

という順に出題された。
**長文問題完了後に通常問題へ進むと長文問題へ戻ることはできませんでした**。ここが時間配分を難しく感じさせたポイント。長文で30分、通常問題で50分、〇×で5分かけてしまったのだが、見直しには15分しか残らなかったです
またLearnの検索に手間取ると一気に時間が溶けるので注意

##  ざっくりとした問題傾向
- とにかく**正しいクラス名・メソッド名**を答える問題が多かった印象です
- 逆にリソース名を答える問題は少ししかなかったです
- **URI**を答える問題も数問あった。これらは検索出来れば解けます
- **順序並び替え問題も多いです**（例えばコンテナのマウント時の正しい操作順序はどうなるか。以下の選択肢から正しいものを選び並び替えよ、みたいな）。そのため一問一答の模試だけやっていると苦しめられるかも
- 先にも述べた**要件定義や作ってほしいと依頼されたサービスの概要などを1ケース読んだうえでの長文問題**が複数題出されます。私の受験時はeコマースサイトのケースにおいてオートコンプリートなどについて出題。主題はあくまで個々の質問に書かれていることで、要件定義などを熟読までする必要はないような印象を受けました
- 通常問題の後の〇×問題はシチュエーションについての文章を読み、**起きている問題はこの方法で解決できる、〇か×か**のような問題でした（問題例:「この値段はいくらですか?」では検索ができるが「これは何円ですか?」だと検索できない。この問題は「同意語」を追加することで解決できる。〇か×か？）
- Bot ServiceのAnimationカードなどについて、Contents Moderatorの「露骨に性的」なのは分類的に何番?も出題。~~問題作りやすいんだろうな~~
- コンテナ関係・エッジデバイス関係の問題も多かった気がします



# 試験勉強・本番を通しての所感
とにかく勉強方法が分からない！！という感じでした。
公式模試だけでは問題形式や用意されている問題数的に勉強足りない気がします。しかしこれに合格できないと本番で通用しないのでやっておいて損はないと思います！そこから苦手な分野・得意な分野を理解してその分野のLearnやトレーニングをしっかり行うのが一つの手じゃないかな、と感じました。だいたいLearnやTraningのどこかには本番問題の根拠が書かれているんだろうな、という印象もあります。そのため**Microsoftのドキュメント検索に慣れておけば合格に近づけるような気がします！**。※個人の感想です。
この記事も数か月後には試験範囲更新で古くなっちゃうんですよね……。ネット上の記事や講座・模試は試験範囲の更新についていってないものも多いので勉強する側としては混乱しました。ですので、何を一番勉強したらいい？と聞かれたら**公式のLearnやTrainingを読み、演習を行うこと**だと私は答えるかなぁ。~~**やはり公式・・・・!!公式はすべてを解決する・・・・!!**~~

# さいごに
世界のどこかから応援してます！
ずんだもんナレーター（VOICEVOXクライアント）

# Linux環境のPythonでVOICEVOXのUI付きクライアントを書いてみた
VOICEVOXでナレーションするにはVOICEVOXを起動しておいてAPIを叩く必要があります。

## VOICEVOXをLinuxにインストールする場合
下記の記事を参考にしてください。
https://qiita.com/kawamo55/items/d333524c82a03dd28c07

# 必要なライブラリ
PySimpleGUI、request、pyaudio がいります。

中でも、pyaudioをLinuxにpipでインストールする際ヘッダーファイルがないというエラーで止まる場合があります。
その場合は
apt install portaudio19-dev
でパッケージを入れないとだめな場合があります（debian系)

## 使い方
1. VOICEVOXを起動します。
1. ナレーション内容はソースの中にあるので書き換えます。
1. ナレーションは('よみ'、'表示')の順に書きます。
　　これは読み間違いのある場合読みの方の読み間違う漢字をひらがなでいれます。
1. スクリプトを起動します。
1. TOP ボタンは最初の文章を読みます。
1. Nextは次の文章を読みます。
1. 終了　でプログラムを終わります。
ファイル名は vvnar としており実行権をつけるとコマンドとして起動できます。

## プログラム内容
ご自由に書き換えてお使いくださいませ。
~~~Python
#!/usr/bin/python3
# このプログラムはVOICEVOXを利用したLinux版ナレータープログラムです。
# 使用するためにはVOICEVOXを起動しておく必要があります。

import PySimpleGUI as psg
import requests as req
import json
import pyaudio as pa

#　ここにナレーションを入れます。('よみ','表示')の順で入れます。
mess = [
    ('読みには読み間違う漢字の部分を平仮名で入れます。','読みには読み間違う漢字の部分を平仮名で
入れます。'),
    ('読みと表示に分けることで正確に発音できます。','読みと表示に分けることで正確に発音できます
。')
]
dispnum=0
# init window
wlay = [[psg.Multiline(default_text=mess[0][1],size=(40,10),border_width=2,font=("",15),key='MText',disabled=True)],
        [psg.Button('Next',key='Next'),psg.Button('Top',key='Top'),psg.Button('終了',key='END')]]
win = psg.Window('VOICEBOX ナレータ',wlay)

# sperk function
def speak(mess,no):
    qu_requrl='http://localhost:50021/audio_query'
    ad_requrl='http://localhost:50021/synthesis'
    reqprm = (('text',mess), ('speaker',no), )
    rsvdat = req.post(qu_requrl, params=reqprm)
    wavdat = req.post(ad_requrl,
        headers={"Content-Type": "application/json"},
        params = reqprm,
        data = json.dumps(rsvdat.json())
    )
    wav = wavdat.content
    dev = pa.PyAudio()
    dev_stream = dev.open(format=pa.paInt16,
        channels=1,rate=24000,output=True)
    dev_stream.write(wav)
    dev_stream.close()
    dev.terminate()

while True:
    ev,val = win.read()
    if ev in ('END',None):
        break
    if ev == 'Next':
        dispnum+=1
        if dispnum >= len(mess):
            dispnum=len(mess)-1
    if ev == 'Top':
        dispnum=0
    win['MText'].Update(mess[dispnum][1])
    try:
        # キャラを変えるためには第２引数の数値を変更します。
        # 3 はずんだもん
        speak(mess[dispnum][0],3)
    except Exception as e:
        print(e)

win.close()

~~~

以上
[Ubuntu] 壊れた SSD の中身を新しいディスクにクローン

# はじめに
 Ubuntu で Minecraft サーバーを建てたりしていたら SSD が死んでしまったので、データをクローンしつつディスクを交換します。

# 環境
OS : Ubuntu 22.04
Disk (dead) : 128 GB SSD (PLEXTOR 2012 年製)
Disk (new)  : 512 GB SSD (Crucial)

# 準備
　今回交換する予定のディスクには OS 本体は入っていないので、Live USB は必要ないのですが、いつかやることになると思うので今回はこの方法を採りました。

必要なものを下にまとめました。

 - Ubuntu の iso ファイル ([ダウンロードページ](https://jp.ubuntu.com/download))
 - Rufus や Etcher などの書き込みソフト
 - USB メモリ (2 GB 以上)

## 1 - Live USB の作成
 Rufus や Ether といったソフトで USB メモリに用意した iso ファイルを書き込みます。
 特に注意点はありません。


# 実機での操作
## 2 - SSD を接続
置き換えたい SSD と新品の SSD を PC に接続します。

## 3 - ブートデバイスの変更
交換したいディスクが搭載されている PC に手順 1 で用意した USB メモリを挿し、電源を入れます。
このとき BIOS か UEFI に入ってブート順を変更し、 Live USB の OS が起動するようにしましょう。
## 4 - パッケージのインストール
`ddrescue` というパッケージを利用します。
普通の `apt install` ではインストールできないので、
```
sudo add-apt-repository universe
sudo apt update
sudo apt install ddrescue
```
の 3 コマンドを実行します。
(有志によるメンテナンスが行われているリポジトリからのインストールを許可するコマンドを発行しています。)

## 5 - パーティション作成、フォーマット
`fdisk -l` や `lsblk` を使用して置き換え対象と新しいディスクのデバイスファイル名を確認します。
今回は `/dev/sdb` のデータを `/dev/sdc` に移行するという想定でコマンドを書いたので、各自で引数を自分の環境のものに置き換えて実行してください。

早速データ移行を、とその前に新しく接続したディスクのフォーマットを行いましょう。

今回は新しく用意したディスクのすべての領域を使用する 1 つのパーティションを作成します。

```shell
sudo parted /dev/sdc # parted の対話モードを開始
(parted) mklabel gpt # パーティション形式を GPT に設定
(parted) mkpart # パーティションを作成(するモードに入る)

Partition name? []? new_disk # パーティション名を設定
File system type [ext2]? ext4 # ファイルシステムを設定(ext4 が無難)
Start? 0% # パーティションの開始位置
End? 100% # パーティションの終了位置

(parted) p # 設定が正しく行われたかの確認
(parted) q # parted を終了する
```

次に、作成したパーティションのフォーマットを行います。
作成したパーティションは `/dev/sdc1` であるとして進めます。
```shell
mkfs -t ext4 /dev/sdc1
```


## 6 - データ移行
いよいよ古いディスクから新しいディスクにデータをコピーします。。

/dev/sda から /dev/sdc にデータを移す際は下記のコマンドを実行します。
```
ddrescue -f -v /dev/sda /dev/sdc
# 書き込み先のデータに書き込み元のデータを強制的に上書きする
# かつ、詳細情報を表示する。
```

128 GB SSD に 40 GB ほどデータが入っている状態でクローンを行い、 10 分ほどで処理が完了しました。
HDD から移行するのであればもっと時間がかかるかもしれません

# おわりに
ddrescue の公式サイトを見ていたら、
*"Never try to repair a file system on a drive with I/O errors; you will probably lose even more data."*
「I/O エラーが出ているドライブには使用しないほうが良い」と書かれていたので、今回の私のように「SSD が死んだので ddrescue を使って復旧します！」はやるべきではないということのようです。

# 参考文献
https://qiita.com/propella/items/a085ec43fd59841da9d0

https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html

https://www2.yukawa.kyoto-u.ac.jp/~koudai.sugimoto/dokuwiki/doku.php?id=ubuntu:%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88

https://atmarkit.itmedia.co.jp/ait/articles/1803/08/news017.html

https://atmarkit.itmedia.co.jp/ait/articles/1803/09/news034.html

https://itsfoss.com/ubuntu-repositories/
技術イベントの時は名刺はあったほうがいいですか？

名刺に関しての記事が思ったより無かったので書いてみました。

今年はもくもく会(勉強会)や交流会の開催が活発になったと思われます。
特に食事や飲み物がある交流会は去年に比べて開催数がかなり増えたと思います。
その時に自分も参加した時に何度か名刺を頂きました。
改めてエンジニアは名刺が必要になるのかどうか？を書いていきたいと思います。

## 自己紹介
2023年からフリーランスエンジニアになった者。
今年はもくもく会、交流会、LT会登壇など合わせて100回ぐらい参加しました。
もくもく会も20回ぐらい主催しました。

https://connpass.com/user/mikaijun/

## この記事の対象者
- これからエンジニアを目指す方
- Web系エンジニアの会社員
- 準委任契約をメインとしたWeb系フリーランスエンジニア

## この記事で書かないこと
名刺の作り方

## 結論
名刺はあったほうがいい。しかし、無くて困ることはない。
名刺を持っているエンジニアの割合は50人中1人ぐらいかなと思います。

## Q.案件獲得に必要かどうか？
A. エンジニアの案件において名刺の有無によって案件が取れるかどうかは関係ないかなと思います。
自分も正社員時代に交流会等経由で何件か案件を獲得したことはありますが、名刺は一度も渡したことはありません(というより作って無かったです)。
案件できるかどうかは名刺の内容より関係者と何回か会って信頼を得る方がいいと思います。名刺交換だけ行う行為に関しては下記がわかりやすいかなと思います

https://www.fra-sco.co.jp/blog_old/%E4%BB%95%E4%BA%8B/post-1356/

## 名刺を作った方がいいメリット
### プロフィールとしての名刺
理由は初対面の方と話すときに話題が広がりやすいからです。
例えば以下のことを一覧に書いてあるものを渡せば「私はこのようなことに興味があります」と一瞬でわかるので共通点や相手が興味あることを聞いてくれることが高いです

**話題に広がりそうな要素一例**
- キャリア
- 住まい
- 普段使っている技術
- 好きなこと
- 今後したいこと
など

### SNS等での連絡交換として
名刺にX(Twitter)などのアカウントを書いておけば繋がりができるかもしれません。
その場で教え合えばいいじゃん！と思いますが名刺に書くと以下のようなメリットがあります

- その場で交換しなくてもSNSで繋がれる可能性がある
- 交換しよ！と言った後にSNSアカウントがない(教えたくない)と言われた時の気まずさを回避できる

### 早く名前(苗字)で呼び合う仲になれる
名前で呼び合うと人間関係が良くなると言われます。
エンジニアのもくもく会や交流会ではネームプレートを配っていないことの方が多いので名前わからない人と話してたというのは良くあるケースです。
苗字が珍しい場合もあるのでカタカナやローマ字で紹介できるのはいいと思います。

https://www.mypsychology.biz/byname/

### ネームプレートに名刺を入れる
イベントによっては以下のようなネームプレートに名前等を記載することがあります
(首から下げるタイプもあります)
<img width="300px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/a8c2d591-13b2-1d47-91e4-609a37426fc8.png">

この時に名刺を代わりにセットすれば自分のことを知ってもらえるでしょう
(名刺をセットしていいかは運営に確認取ったほうがベターかなと思います)

## 名刺を作る時に考えること
誰に向けた名刺を作るか？を考えた時に以下の2パターンがあると思います

- エンジニア向け(比較的カジュアル)
- 経営者向け(比較的固い感じになりそう?)

主に渡す方は前者になると思うのでエンジニア向けに渡す場合は名刺によって後々の繋がりどうこうを考えるよりその場で会話が盛り上がるかどうか？を考えた方がいいかなと思います。
となると記述内容は以下のような感じになると思います

- キャリア
- 住まい
- 普段使っている技術
- 好きなこと
- 今後したいこと


## 名刺に書く内容について

見た目に関しては以下の記事が参考になるかなと思います

https://goworkship.com/magazine/business-card-utilization/




以上です。参考になれば幸いです！
CypressはPlaywrightに負けてない

## 背景
　業務で自動テストにCypressを使っているのですが、最近ではCypressとPlaywrightを比較し、Playwrightのほうが優秀っぽく記載される記事や、CypressからPlaywrightに移行しました！、という記事を見かけることが多くなったような気がします。ちなみに以下はGoogleトレンドでCypress（青）とPlaywright（赤）を比較したものです。2023年6月くらいからcypressをPlaywrightが上回っており、少しずつ差が開いてきています。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/82af77d4-02ec-8f53-e274-c2e25926f358.png)
　そのためPlaywrightへの移行を検討する趣旨でいろいろ触ってみたのですが、たぶん単純なスペック（機能・性能）を比較するとPlaywrightが上回っていると感じました。しかしCypressの弱みよりも強みのほうが私にとっては重要であり、Cypressを使い続けたいと感じました。

## Cypressの弱み（としてネットで見かけること）
* テスト実行が遅い
　テストの実行速度では圧倒的にPlaywrightのほうが上で、特に画面への入力では2倍程度の差が出ました。画面遷移するだけであれば有意な差はないように感じました。
　なお比較記事によっては4倍からそれ以上の差異が出ている記事もありますが、設定とケースによると思います。Cypressは人間が入力したときのテストと近くなるようにあえて入力時に遅延を挟んでいます。私が試したケースでは画面入力の速度はデフォルトの遅延だとPlaywrightが3倍程度早く、遅延なしだとPlaywrightが2倍程度早かったです。遅延有で入力量が多くなると差はもっと大きくなると思います。
　ただし後述の起動速度を考慮すると必ずしもPlaywrightのほうが早いとは言えないと思います。
　
* 複数ウィンドウによるテストができない
　これはCypressの公式サイトでもCypressを使用する上での永続的なトレードオフとしてあがっていることです。
https://docs.cypress.io/guides/references/trade-offs#Multiple-browsers-open-at-the-same-time
　ただ私もこれは弱点ではなく、トレードオフだと認識しています。自動テストではカバレッジが上がれば上がるほど、それ以上を求めるのが厳しくなっていきます（①70%を90%にするよりも②90%を95%にする方が難しい）。これは実装が難しくなるというのもありますが、保守性やフレーキーなテストになりやすいというのが一番の理由と考えます。そうしたとき、複数ウィンドウで同時打鍵するケースは①なのか②なのか、自分が開発しているシステムが求める品質レベルはどの程度なのかを考えると、複数ウィンドウのテストは自動化の対象とすべきではないという結論になりました。
　
* レコーディング機能がない
　これは誤解もしくは情報が古いです。Cypressにはβ版ではありますが公式のレコーディング機能があります。またChormeのレコーディング結果をCypressのコードとして出力するChrome拡張もCypressの公式として公開しています。ただ、個人的には前者のβ版はPlaywrightよりもUXの面で優っていると感じますが、後者は劣っていると感じます。
　UXで優っていると感じる理由は以下のように単一のGUI上で操作ができるからです。以下の画面のように要素を右クリックしてアサーションを追加したりできるのでこのGUIで完結します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/d7cd4b49-b33d-bb24-f12e-c0f340148246.png)
　Playwrightは以下のような操作パネルとブラウザを行き来しなければいけないのが面倒だと感じました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/cafc326c-ecc9-f366-7166-5140e88437a5.png)

## Cypressの強み
* テスト実行におけるオーバーヘッドがほぼない
　Cypressで開発するときは常にGUIランナー（ブラウザ）を起動しているので、ブラウザを起動する・閉じるといったオーバーヘッドが発生しません。そのためすでに開いているテストファイルにケースを追加し、再実行するのであればテスト実行まで0.1秒程度で実行が開始するレベルでオーバーヘッドがありません。Playwrightはテスト実行自体は2秒程度のケースも起動・クローズ含めて計測すると10秒かかりました。単一のケースを実行する上で10秒を超えることはかなりまれなので、単一のケースを実行するにはCypressのほうが早いと思います。そして開発中は大量ケースを流すよりも、追加したケースを流すことの方が多いです。
* GUIテストランナーが秀逸
　テスト実行画面をiframeで含んだブラウザ上で実行されるためテストの実行内容が目で見てわかります。これは特にエラーが出たときに効果が大きいです。例えばある要素が見つからないといわれたときヘッドレスだと「要素が見つからない」ことしかわからないので、スクリーンショットや動画を開くことになります。しかしCypressだとGUIランナーにテスト時の画面が表示されるので、「バグで要素が表示されていない」のか、「テストコードが悪くて要素を拾えていない」のか、「それよりも前の手順でミスっているから目的の画面にたどり着いていないのか」がすぐにわかります。
　エラーが発生した状態からその後の操作もすることが可能なのでデバッグ効率が圧倒的に高いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/35b0fb1a-cb01-b53b-848b-8870a3231e5d.png)

ただヘッドレスで実行した場合の実行結果はブラウザでGUIとして出してくれるPlaywrihgtのほうがみやすいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/8591771e-2d43-1833-4ac5-901744f5305c.png)
特にビジュアルリグレッションの結果は見やすいです。タブでDiff、Actual、Exceptedを比較して見れるのがいいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/89d5a92a-e523-39ee-5ea2-42dbec6bd729.png)

## 結論
Cypress、Playwrightでどちらが優れているとは一概にはいえず、あくまで求める要件と好みによるかと思います。