OmniAICreator/Qiita-1.07M huggingface dataset:
PHPについて

# PHPについて

## 概要

PHPは「Hypertext Preprocessor」の略で、動的なWebページを生成するために開発されたサーバーサイドのプログラミング言語です。HTMLと密接に連携するため、動的なWebアプリケーションやAPIの開発に多く利用されています。

## PHPの特徴

- **サーバーサイドスクリプト**: PHPコードはサーバー側で実行され、その結果だけがHTMLとしてクライアントに返されます。
- **動的なWebページ生成**: データベースと連携することで、ユーザーのリクエストに応じてページ内容を変更できます。
- **クロスプラットフォーム**: Windows、macOS、LinuxなどさまざまなOSで動作します。
- **オープンソース**: 無料で使用できるオープンソースの言語で、コミュニティによって開発が続けられています。

## PHPの基本構文

PHPは`<?php`と`?>`で囲まれた部分に記述し、その中にコードを書きます。以下は、基本的な構文です。

### 1. 変数

変数は`$`記号で始まり、データを格納します。

```php
<?php
$name = "Alice";
echo "こんにちは、" . $name . "さん！";
?>
```

### 2. 配列

配列は、複数のデータを格納できるデータ構造です。

```php
<?php
$fruits = array("Apple", "Banana", "Cherry");
echo $fruits[0]; // Apple
?>
```

### 3. 条件分岐

条件分岐を使って、処理を分けることができます。

```php
<?php
$age = 20;
if ($age >= 18) {
    echo "成人です。";
} else {
    echo "未成年です。";
}
?>
```

### 4. ループ

同じ処理を繰り返し行う場合、ループを使用します。

```php
<?php
for ($i = 0; $i < 5; $i++) {
    echo $i . " ";
}
?>
```

### 5. 関数

関数は特定の処理をまとめたもので、再利用可能なコードのブロックです。

```php
<?php
function greet($name) {
    return "こんにちは、" . $name . "さん！";
}
echo greet("Alice");
?>
```

## PHPとデータベース

PHPはMySQLやPostgreSQLなどのデータベースと連携することが多く、データの取得や保存が容易に行えます。PDO（PHP Data Objects）を使用することで、安全かつ柔軟なデータベース操作が可能です。

### データベース接続の例

以下は、PDOを使用してMySQLデータベースに接続する例です。

```php
<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
    echo "データベース接続成功";
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage();
}
?>
```

### データの取得

データを取得する際には、SQLクエリを実行して結果を配列に格納します。

```php
<?php
$stmt = $pdo->query("SELECT * FROM users");
foreach ($stmt as $row) {
    echo $row['name'] . "<br>";
}
?>
```

## セキュリティの考慮

PHPでは、ユーザーからの入力を受け取り処理する場面が多いため、セキュリティを意識したコーディングが必須です。

### XSS（クロスサイトスクリプティング）

ユーザーの入力をエスケープすることで、HTMLに悪意のあるスクリプトが埋め込まれるのを防ぎます。

```php
<?php
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>
```

### SQLインジェクション

プリペアドステートメントを使用して、SQLインジェクションを防止します。

```php
<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
?>
```

## まとめ

PHPは、動的なWebページやアプリケーションを構築するために非常に有用な言語です。サーバーサイドスクリプトとして多くのプロジェクトで採用されており、データベースと組み合わせることで、柔軟かつ強力なWebサービスが構築できます。基本的な構文やセキュリティの考慮事項を理解し、実践することで、安全かつ効率的なアプリケーション開発が可能になります。
【置換】順次に置換するスクリプト

# はじめに
XMLファイルに大量の要素を追加する作業があった。エクセルファイルにデータ内容が記載されているためそれをもとに、XML形式のテキストを作ってほしいという作業である。手作業でチマチマ作ると1000件、10000件と件数が膨大だと日が暮れても終わらない...。このような作業はスクリプトを組んでサクっと終わらせたい。

# 完成イメージ
例えばエクセルで下記のような指示があり、これをXML形式に変換したい。
これが10000件とかあって、手作業でXMLを作ると地獄...。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3911030/c56f1ee6-6e31-a53b-3130-6e80f8992bc3.png)
```xml
<Item>
 <No>1</No>
 <Date>2024/10/29</Date>
 <Name>Yamada</Name>
 <Age>23</Age>
</Item>
...以下省略
```

# スクリプト
下記のスクリプトで置換処理を順次に行う。
```python
import pandas

with open("template.txt", "r", encoding="utf-8") as file_obj:
	template_text = file_obj.read()

df = pandas.read_excel("ReplaceList.xlsx", "List")

output_text = ""
for rowdata in df.iloc:
	replaceinfo = rowdata.to_dict()
	worktext = template_text
	for key, value in replaceinfo.items():
		worktext = worktext.replace(str(key), str(value))

	output_text += worktext + "\n\n"
	
with open("output.txt", "w", encoding="utf-8") as file_obj:
	file_obj.write(output_text)

```

`pandas`を使って置換対象のリストを読み込む。`df.iloc`から１行ごとのデータを取得する。`to_dict()`メソッドを使って見出しと値のペアバリューを作る。キー値を置換元、バリュー値を置換先として置換処理を行う。
```python
	for key, value in replaceinfo.items():
		worktext = worktext.replace(str(key), str(value))
```

テンプレートテキストは事前に用意しておく。
今回の例だと下記のようなテンプレートを用意する。
```xml
<Item>
 <No>【No】</No>
 <Date>【Date】</Date>
 <Name>【Name】</Name>
 <Age>【Age】</Age>
</Item>
```

見出しとなっている"【No】"などが表中の`1`に置換される。これが順次処理されることで、下記のようにXMLデータが瞬時に量産される。

```xml:template.txt
<Item>
 <No>1</No>
 <Date>2024-10-29 00:00:00</Date>
 <Name>Yamada</Name>
 <Age>23</Age>
</Item>

<Item>
 <No>2</No>
 <Date>2024-10-30 00:00:00</Date>
 <Name>Sato</Name>
 <Age>35</Age>
</Item>

<Item>
 <No>3</No>
 <Date>2024-10-31 00:00:00</Date>
 <Name>Kimura</Name>
 <Age>19</Age>
</Item>
```

# 応用
`template.txt`の内容を変えれば、XML以外の形式でも使える。エンジニア以外でも事務作業とかで活用できたりするのかな？
ABC350Dを解いた【UnionFind】


筆者はレート700前後の茶色コーダ

[昨日勉強した](https://qiita.com/comet725/items/e55a47fa7023df74e02b)UnionFindを早速使いこなすために

解説でUnionFindでも解けると見た記憶のある
この問題を解いていく

https://atcoder.jp/contests/abc350/tasks/abc350_d



# 実装コード

UnionFind使って各グループごとの頂点数を求める。

あとは[解説](https://atcoder.jp/contests/abc350/editorial/9811)の通りに答えを出すだけ(以下引用)

> 頂点数 $n$ の連結成分には最大で $\frac{n(n-1)}{2}$ の辺が存在できるため、求める答えは、この値の連結成分ごとの和からもともと存在する辺の個数を引いたものです。

```python:main.py
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

class UnionFind:
    def __init__(self, n):
        self.parent = [-1] * -~n
        self.rank = [1] * -~n
    def root(self, x):
        while (p:=self.parent[x]) != -1:
            x = p
        return x
    def union(self, x, y):
        xr = self.root(x)
        yr = self.root(y)
        if xr == yr: return
        elif (rx:=self.rank[xr]) < (ry:=self.rank[yr]):
            self.parent[xr] = yr
            self.rank[yr] += rx
        else:
            self.parent[yr] = xr
            self.rank[xr] += ry
    def same(self,x,y):
        # err(self.root(x), self.root(y))
        return self.root(x) == self.root(y)



def main():
    N, M = rLI()
    
    UF = UnionFind(N)
    
    for _ in range(M):
        a,b = rLI1()
        UF.union(a,b)
    
    ans = 0
    for i in range(N):
        if UF.parent[i] == -1:
            z = UF.rank[i]
            # err(i,z,~-z*z//2)
            ans += (~-z*z)//2
    ans -= M
    print(ans)
if __name__ == '__main__':
    main()

```

# まとめ

UnionFindを使ってABC350のD問題を解いた

解説みてベタ移植で丸写しの解答だが
なにかの力になっている…ハズ

# 余談

昨日作ったUnionFindにバグが有って30分ハマったorz

位数がイコールの場合に何故か+1しかしていなかったので合計が合わなくなっていた
(昨日の記事も修正済)

<details><summary>修正内容</summary>

```diff_python:main.py
class UnionFind:
    def __init__(self, n):
        self.parent = [-1] * -~n
        self.rank = [1] * -~n
    def root(self, x):
        while (p:=self.parent[x]) != -1:
            x = p
        return x
    def union(self, x, y):
        xr = self.root(x)
        yr = self.root(y)
        if xr == yr: return
        elif (rx:=self.rank[xr]) < (ry:=self.rank[yr]):
            self.parent[xr] = yr
            self.rank[yr] += rx
-       elif rx > ry:
-           self.parent[yr] = xr
-           self.rank[xr] += ry
        else:
            self.parent[yr] = xr
-           self.rank[xr] += 1
+           self.rank[xr] += ry
    def same(self,x,y):
        # err(self.root(x), self.root(y))
        return self.root(x) == self.root(y)
```

</details>
シェルでコマンドプロンプト経由でコマンドを実行する方法

一部のコマンドだけコマンドプロンプトからじゃないと実行できないコマンドがあった。
しかし、すべての処理はgit bashからシェルで実行したかった。

以下のようにシェルの中で実行したらいけた

```
cmd //c 【任意のコマンド】
```
Power AutomateでTeamsにリンク付きのメッセージ投稿をする

# やりたいこと
SharePoint Onlineに保存されているExcelへのリンクを、Teamsのチャットに挿入してメッセージ投稿する。

# 手順1. ［ファイルの作成］アクション

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/0139a6a6-fcbe-5ab7-7878-28d92ca5885a.png)


# 手順2. ［ファイルまたはフォルダーの共有リンク］アクション
［ファイルまたはフォルダーの共有リンクを作成］アクションで作成されたファイルのリンクを取得します。「項目ID」と「リンクの種類」と「リンクスコープ」はご希望に合わせて設定します。

![スクリーンショット 2024-10-29 232804.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/8612e65e-07c3-762b-a78c-307d5471c968.png)

詳細な設定方式については、以下記事をご確認ください。

https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#create-sharing-link-for-a-file-or-folder

# 手順3. ［チャットまたはチャネルでメッセージ投稿をする］アクション
［チャットまたはチャネルでメッセージ投稿をする］アクションで、メッセージ欄でコードビューに切り替えてから、下記内容を入力します。

```html
<a href="@{triggerOutputs()?['body/{Link}']}" target="_blank">ファイルを開く</a>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/999d93da-6194-f92b-80a5-17c48594fd3d.png)

# 手順4. メッセージ欄にリンクを挿入する
［ファイルまたはフォルダーの共有リンクを作成］アクションから「共有リンク」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/61e4444c-30e7-955f-51b5-0217b6db3552.png)


# 手順5. メッセージ欄にリンク名を設定する
［ファイルの作成］アクションから「Name」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/45da3b25-5192-3a0f-3b4b-a7e25c314cea.png)


Teamsへのメッセージ投稿は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/f3788ce1-cba9-7e4d-c928-c4d8303c42b7.png)
Next.js(Typescript)でPrismaのseedデータを保存する


# はじめに
個人開発中にseedファイルを作成して、データベースに初期データを投入したいと考えました。

過去にRailsでseedファイルを作成してデータベースに反映させた経験はあるものの、Next.js × Prismaの組み合わせで実装するのは初めてだったため、備忘録として実施方法を残します。


## 環境
- React 18.3.1
- Next.js 14.2.16
- Prisma 5.21.1
- TypeScript 5.6.3


## 実装手順

### 1.seedファイルを作成する
私は個人開発で犬の情報を登録する実装を行なっていたため、犬種リストをseedファイルで管理するようにしました。
以下はbreedsテーブルに対して、配列dogBreedsの要素を挿入するseedです。

`prismaディレクトリ`内に`seed.ts`ファイルを作成して以下のように記述をします。

```ts: prisma/seed.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  // 初期データとして投入したいリストを配列で作成
  const dogBreeds = [
      "秋田犬",
      "アメリカンコッカー・スパニエル",
      "イタリアングレーハウンド",
      "ウェルシュ・コーギー",
      ~ 省略 ~
      "ヨークシャーテリア", 
      "ラブラドールレトリバー",
  ]

  try {
    // 配列から1つずつ要素を取得し、breedテーブルに保存する
    for (const breed of dogBreeds) {
      await prisma.breed.upsert({
        where: { name: breed },   // nameの値がbreedに一致するレコードがあれば
        update: { name: breed },  // nameの値を更新
        create: { name: breed },　// 一致するレコードがなければ新規作成する
      });
    }
  } catch (error) {
    console.log(error)
    process.exit(1)  // スクリプト実行時にエラー発生したら、異常終了としてプロセス終了をする
  } finally {
    await prisma.$disconnect(); //prismaとの接続を遮断
  }
}
```

### 2. ライブラリの導入
TypeScriptのseedファイルを実行できるように、ライブラリを導入します。
ターミナルで以下のコマンドを追加してください。
```
npm install -D typescript ts-node @types/node
```


### 3. package.jsonへコマンドを追加
package.json内にseedコマンドを追加します。以下のように追加してください。

```json:package.json
  "scripts": {
    "dev": "next dev",
    "build": "prisma generate && next build",
    "start": "next start",
    "lint": "next lint"
  },
  
  // 以下を追加
  "prisma": {
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
  },
```
このコマンドを追加することで、`npx prisma db seed`コマンドでseedファイルの実行をすることができます。

Next.jsの場合はコンパイルをする際にオプション設定が必要です。`"ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts`のように記載しましょう。

オプションを設定せずに、`"seed": "ts-node prisma/seed.ts"`と記載すると、以下のようなエラーが発生するので注意です。

```[]:エラーメッセージ
An error occurred while running the seed command:
Error: Command failed with exit code 1: ts-node prisma/seed.ts
```

### 4. seedコマンドを実行
```terminal:
npx prisma db seed
```

これでデータベースに対してseedファイル内の情報が保存されたはずです！


### 最後に
私は`package.json`内の`seedコマンド`にオプションをつけておらず、暫くエラーにハマりました。
[Prismaの公式ドキュメント](https://www.prisma.io/docs/orm/prisma-migrate/workflows/seeding)にも記載しているのですが、下部に書かれていて見逃してしまっていました...!

ぜひ今後Next.jsでseedファイルを作成されたい方は、参考にしてみてください。
【AWS初心者必見！】S3バケットのデータを守るための完全ガイド

## はじめに
こんにちは、uiroleです！  

AWSの**Amazon S3**は、高い可用性とスケーラビリティを持つオブジェクトストレージサービスとして広く利用されていますが、セキュリティ設定が不十分だと、大量のデータが外部に漏洩するリスクがあります。

今回は、AWS S3のセキュリティを高めるためのベストプラクティスと設定方法について解説します。

### 対象者
- S3バケットを使用しているAWSユーザー
- AWS環境のセキュリティ強化を目指すシステム管理者やエンジニア
- S3データのセキュリティリスクを回避したい人

### 前提
- AWSの基本操作ができる
- IAM（Identity and Access Management）の基本的な概念を理解している

### 記事を読んで解決すること
- S3のセキュリティリスクとその対策を理解できる
- IAMポリシーやバケットポリシー、暗号化などの設定方法を実践できる
- S3を安全に利用するためのベストプラクティスを学べる


## S3のセキュリティリスクと課題
Amazon S3は利便性が高い反面、以下のようなセキュリティリスクを伴います。

- **パブリックアクセスのリスク**
誤ってS3バケットがパブリックに公開されると、すべてのデータが外部からアクセス可能になります。
- **不適切なアクセス権限の付与**
許可の範囲が広すぎると、外部からのアクセスだけでなく内部の不正アクセスも招く恐れがあります。
- **データ漏洩や改ざんのリスク**
暗号化が不十分だと、データが漏洩した際に悪意ある者にデータが閲覧される可能性が高まります。


## S3のセキュリティベストプラクティス

### 1. バケットのパブリックアクセス制御
AWSでは、バケットのパブリックアクセスを簡単に制御できる機能があります。
重要なデータを含むバケットは、**パブリックアクセスの設定を無効化**することが推奨されます。

#### 手順:
1. **S3コンソール**にアクセスし、対象のバケットを選択。
2. 左サイドバーから**「パブリックアクセス設定」**をクリック。
3. **「すべてのパブリックアクセスをブロック」**にチェックを入れ、変更を保存。

:::note info
これにより、すべてのパブリックアクセスを禁止し、誤った設定でデータが外部に公開されるリスクを防げます。
:::

### 2. IAMポリシーとバケットポリシーの設定
AWS IAMを使ってユーザーやロールに対してS3バケットへのアクセス権限を細かく設定します。
S3バケットポリシーを利用すると、特定の条件でアクセス制御ができ、リソースの管理が容易になります。

::: note info
IAMポリシーを適切に設定し、必要な権限だけを付与することで、不正アクセスのリスクを軽減します。
:::

### 3. データの暗号化
AWS S3では、**サーバーサイド暗号化**と**クライアントサイド暗号化**の両方がサポートされています。
サーバーサイド暗号化では、S3が自動的にデータを暗号化して保存します。

#### 暗号化の設定手順
1. **S3コンソール**にアクセスし、対象のバケットを選択。
2. 左サイドバーから「プロパティ」を開き、「デフォルト暗号化」を設定。
3. 必要に応じて**SSE-S3**、**SSE-KMS**、または**SSE-C**を選択して暗号化を有効にする。

### 4. アクセスログの有効化
S3のアクセスログを有効にしておくと、バケットへのアクセス状況を確認でき、異常なアクセスがあった場合の調査に役立ちます。

#### アクセスログの設定方法
1. S3コンソールで対象のバケットを選択。
2. 「プロパティ」の「アクセスログ」で、「ログ配信バケット」を指定。
3. 設定を保存すると、指定したバケットにアクセスログが出力されます。

## まとめ
Amazon S3のセキュリティを強化するためには、**パブリックアクセス制限**、**IAMポリシーの適切な設定**、**データの暗号化**、**アクセスログの有効化**が重要です。  
S3のセキュリティ設定をしっかりと行い、安全なクラウド環境を構築して、データを安心して管理しましょう。


記事を気に入っていただけたら、「いいね」やフォローをお願いいたします！
エンジニアは骨伝導イヤホンを買うべし

お疲れ様です。秋並です。

近年、リモート会議やリモートワークの増加によってイヤホンを使用する機会が増えている人も多いと思います。

今回はそんな人におすすめなイヤホンである「骨伝導イヤホン」について紹介したいと思います。

# 骨伝導イヤホンとは

骨伝導イヤホンとは「耳や鼓膜を介さずに、頭蓋骨の振動で音を伝えるイヤホン」です。

骨伝導イヤホンは

- 耳を塞がない

というところが、一番の特徴になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/37ff32d8-683b-785e-234b-947e98674867.png)
引用：[https://jp.shokz.com/products/openrun](https://jp.shokz.com/products/openrun)


# なぜエンジニアに骨伝導イヤホンがいいのか

私が骨伝導イヤホンをエンジニアにおすすめする理由は以下になります。
（正確には、**リモート会議が多い職業全般**におすすめの理由になるかなと思います）

- 耳をふさがないから耳に優しい
- 長時間つけていても疲れにくい（ここは、人によるかも）
- （マイク内臓タイプは）話し相手に音がしっかり聞こえる

一つずつ解説していきます。

## 耳をふさがないから耳に優しい

骨伝導イヤホンは耳を塞がないため、<font color="red">鼓膜に対するダメージが少ない</font>です。

近年は「イヤホン難聴」なる言葉も誕生しており、長期的に考えると鼓膜へのダメージが少ないことは大きなメリットです。


## 長時間つけていても疲れにくい

骨伝導イヤホンは、カナル型イヤホンやヘッドフォンと比較すると耳への負担が少ないため、<font color="red">長時間つけていても耳が疲れにくい</font>です。

こちらに関しても、リモートワークなどで長時間リモート会議をする人には大きいメリットだと思います。

(ただし、後述するように合わない人もいることに注意してください)

## (マイク内蔵型の場合)話し相手に声が聞こえやすい

パソコンの内蔵マイクなどの場合、マイクと口の距離が遠くなってしまうと、相手に自分の声が聞こえにくくなってしまう場合があります。

一方で骨伝導イヤホンの場合、耳元にマイクがついており、マイクと口の位置関係が変わらないため、<font color="red">常に一定の音量で相手に声が伝わります</font>。

(これに関しては、骨伝導イヤホン特有のメリットという訳ではないですが)

# デメリット

ここまで、骨伝導イヤホンのメリットを紹介してきましたが、もちろんデメリットも存在します。

具体的には以下の通りです。

- 騒音が大きいところでは使いにくい
- 音質が悪い
- 人によってはつけ心地に違和感を感じる

## 騒音が大きいところでは使いにくい

骨伝導イヤホンは、耳の穴を塞がずに使用するため、<font color="red">周りの騒音が大きいと音が聞こえにくい</font>です。

また、音を大きくすると音漏れしやすいので電車の中のような大きな騒音がある場所での使用はおすすめできません。

ただ、リモート会議をするような場所で、騒音が大きいことはあまりないと思うので、あまり気にする事はないかなと思います。

## 音質が悪い

骨伝導イヤホンはカナル型のイヤホンと比べると、どうしても<font color="red">音質は劣ります</font>。

こちらに関しても、リモート会議で音質を気にする事は少ないと思うので、今回述べている用途ではあまり問題ないと思われます。

## 人によってはつけ心地に違和感を感じる

骨伝導イヤホンは、その名の通り骨を振動させて音を伝えているわけですが、<font color="red">体質によっては振動に違和感を感じたり、痛く感じる人もいる</font>ようです。

これに関しては人によって違うため、家電量販店などで一度使用してみて、自分に合っているか確認してみると良いと思います。

# おすすめの骨伝導イヤホン

ここまで、骨伝導イヤホンの特徴についてお話ししました。

最後に一つだけ補足すると、骨伝導イヤホンは、専用の充電器を必要とするものも多いのですが、そのためにケーブルを追加で持ち歩くのは面倒だと思うので

- <font color="red">usb-cケーブルによる充電に対応</font>しているものをおすすめします！


ちなみに私は、SHOKZのOPEN MOVE（usb-c充電対応）を使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/8df954a0-df35-f589-a6b8-ca88908db53d.png)
引用：[https://jp.shokz.com/products/bone-conduction-headphone-openmove](https://jp.shokz.com/products/bone-conduction-headphone-openmove)

# さいごに

この記事を見て骨伝導イヤホンに興味が出た方は一度購入してみて下さい！
CloudWatch Logs Insightsまとめ

## はじめに

CloudWatch Logs Insightsを使用するときに意識しておかないと、思ったよりコスト高くなるので、クエリの書き方と実行時に注意することをまとめる。

## クエリ実行時に注意すること

公式にも掲載されているが、クエリ実行時はロググループを選択すること、時間指定は必ず行うこと。
個人的にはFiledsも指定した方がパフォーマンス上がるので、Mustレベルで指定した方がいいと思う。

ウィジェットは慣れるまで使用しない方が安心。更新のたびにクエリ実行されるので、頻繁に更新されるとコスト嵩む。

## 生成されるフィールド

| filed | 内容 |
| --- | --- |
| @message | ログイベント |
| @timestamp | ログイベントに含まれる時刻 |
| @ingestionTime | CloudWatchがイベントを受信した時刻 |
| @logStream | イベントを追加したログストリーム名 |
| @log | ロググループの識別子(account_id:log-group-name) |

## クエリ構文

バグ調査などでよく使う構文のみピックアップします。

| コマンド | 内容 | SQLなら |
| --- | --- | --- |
| display | 表示するフィールドを選択<br> fieldsとごっちゃになりやすいので注意 | select(イメージ的には表示する内容の順序などレイアウト調整) |
| fields | 表示するフィールドを絞る | select(カラム選択のイメージ) |
| filter | ログイベントのフィルタリング | where |
| sort | ログイベントを昇順または、降順で表示 | order by |
| stats | ログの集計 | group by |
| limit | 検索結果の上位x件を表示 | limit, top |
| dedup | 指定したフィールドの特定の値の重複を除く | distinct |

## バグ調査でも汎用クエリ

バグ調査時にログ検索をなるべく効率化しつつ、様々な場面で活躍するクエリを紹介。
ロググループは指定されていること


~~~sql
fields @timestamp, @message, @logStream
| filter @message like {検索したい文字列}
| filter @timestamp >= 1672567200000 and @timestamp <= 1672574400000
| sort @timestamp desc
| limit 10
~~~

timestampで絞るときはミリ秒で指定する必要がある。

Fargate使用しているとログストリームよく分かれるので、上記のようなクエリでログストリームを探して、その後、ログストリームで前後のログまで確認すると、調査しやすくなると思います。
クエリだけだと、いつそのログが出力されたかは分かりますが、メッセージでFilterかけている分断片的な部分しか表示されなかったりします。


## 参考文献

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
投稿 121 Slack 2024/10/29

本日の勉強時間　4H

Slack（スラック）は、スチュワート・バターフィールドによって開発され、2013年に市場導入されたチームコミュニケーションツール[1]。 Slackという名称は"Searchable Log of All Conversation and Knowledge"のアクロニムである。
サーバー荒らし対策！！Discord Bot「Fortify」の認証パネル機能解説

# はじめに
Fortifyは、サーバーを安全に保つための「認証パネル」機能を搭載した多機能セキュリティBotです。本記事では、この認証パネルの作成方法、ユーザー認証の流れ、および活用事例を詳しく解説します。

# 認証パネルとは？
認証パネルとは、サーバーに参加したユーザーが適切に認証されているかを確認するための専用インターフェースです。
**Fortify**は独自の危険ユーザーリストを利用して、約6万人の危険なユーザーの存在をチェックします。
安全が確認されたユーザーのみにロールを付与するため、不正や荒らし行為を未然に防ぐことができます。

# 機能の概要
1.管理者がコマンド`/verifier` を使って認証パネルを作成
2.認証後に付与するロールを指定。
3.パネルに表示する説明テキストを自由に設定。
4.ユーザーが✅リアクションを押して認証を開始

**危険ユーザーリストに含まれていない場合**
・指定されたロールを付与し、認証完了メッセージを送信

**危険ユーザーリストに含まれていた場合**
・認証を行わず、警告メッセージを送信

# 実際の使用例
**1.管理者が認証パネルを作成**
`/verifier role: @Member message: "認証を行うには下の✅をクリックしてください"`

**2.パネルの表示例**
`✅ を押して認証を完了しましょう。安全確認が取れた後、自動でロールを付与します。`


**3.ユーザーの操作とフロー**
ユーザーが ✅ をクリックすると、Botが内部で危険ユーザーリストと照合します。

**4.判定結果のメッセージ例**
**・安全な場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3918325/267431cd-7a98-aa70-eb64-d17236c258c1.png)

**・危険ユーザーの場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3918325/6ccf47b7-9337-426f-7429-59d8aeec6cd1.png)

**5.エラーが発生した場合**
認証パネル使用時、以下のエラーパターンに注意してください。

**・指定したロールが存在しない場合**
→ 「指定されたロールが見つかりません」と表示されます。

**・Botに権限がない場合**
→ 「ロールを付与する権限がありません」と警告されます。

# 活用のポイント
**1. 荒らしからの防御強化**
新規参加者が荒らしでないか、事前にチェックが入るため、不正なユーザーの侵入を未然に防止できます。

**2. 自動化された運用**
認証の流れが自動化されており、管理者の負担が軽減されます。

# 実装時のヒント
パネルにルール説明やお知らせを含めることで、ユーザーに安心感を与えられます。
認証後のカスタムメッセージを工夫し、ユーザーの歓迎ムードを作りましょう。

# 最後に
Fortifyの認証パネル機能は、簡単な操作で強力なセキュリティを実現します。これを活用することで、サーバー運営者は日々のトラブル対応から解放され、より楽しいコミュニティ運営に集中できるでしょう。

これで認証パネルの解説は完了です。

サーバーの安全はFortifyにお任せ！ 
皆さんのサーバー運営がより安心で快適なものになることを願っています。

# 参考リンク
Fortify公式サポートサーバー: [参加](https://discord.gg/YT7BctbGmy)
Bot導入リンク: [Botを招待](https://discord.com/oauth2/authorize?client_id=1240964440581603370&permissions=8&scope=bot+applications.commands)
Reactでクリップボードにテキストをコピーさせる

## これはなに

Reactでクリップボードにテキストをコピーさせる簡単なコンポーネントのサンプルを紹介します。これにより、ユーザーにテキストを簡単にコピーしてもらうインターフェースを実装できます。

## 対象読者

- Reactを使ってフロントエンド開発を行っているエンジニア
- Reactを使ったコンポーネント開発に興味がある人
- ユーザーに簡単にテキストをコピーさせたい人

## ゴール

Reactでクリップボードにテキストをコピーさせる機能を実装するシンプルなコンポーネントを作成し、動作する状態まで持っていくこと。

## TL;DR

以下のコードを使うことで、Reactで簡単にクリップボードにテキストをコピーさせるコンポーネントを作成できます。

```jsx
import { useState } from 'react';

export default function CopyToClipboard() {
  const [copySuccess, setCopySuccess] = useState('');

  const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText('コピーさせるテキスト');
      setCopySuccess('コピーしました！');
    } catch (err) {
      setCopySuccess('コピーに失敗しました...');
    }
  };

  return (
    <div>
      <button onClick={copyToClipboard}>テキストをコピー</button>
      {copySuccess && <p>{copySuccess}</p>}
    </div>
  );
}
```

## 解説

### コードの説明

上記のコンポーネントは、ユーザーがボタンをクリックすると特定のテキスト（ここでは“コピーさせるテキスト”）がクリップボードに保存される仕組みです。`navigator.clipboard.writeText()`を使うことで、非同期的にテキストをクリップボードにコピーできます。

- `useState`はコピーの成功メッセージを管理するために使用しています
- `copyToClipboard`関数は非同期関数で、成功した場合には“コピーしました！”というメッセージを表示します

### 注意点

- `navigator.clipboard`はHTTPS環境でのみ動作するため、ローカルでテストする場合は`localhost`かHTTPSプロトコルが必要です
- 一部のブラウザでは、クリップボードのアクセスに制限があるため、ユーザーの操作によってのみコピー処理が実行可能です

## 参考文献

- [MDN Web Docs - Clipboard API](https://developer.mozilla.org/ja/docs/Web/API/Clipboard_API)
OIDCにおける認可コードとアクセストークンの違い

### 認可コード (Authorization Code)

- 認可コードは、クライアントアプリケーションがリソースオーナー（ユーザー）の同意を得て、認可サーバーから一時的に発行されるコードです。
- 認可コードはセキュリティ上の理由から、ブラウザやURL経由でクライアントに送信されます。
- 認可コード自体はリソースに直接アクセスするための権限を持たず、アクセストークンを取得するための中間的なステップです。
- 認可コードは、通常のシーケンスではクライアントがサーバーと通信してアクセストークンと交換されます。
- 認可コードは一度だけ使用される短命のコードで、セキュリティを高める役割もあります。

### アクセストークン (Access Token)

- アクセストークンは、クライアントアプリケーションがリソースサーバー（API）に対してユーザーの代わりにリソースアクセスを行うためのトークンです。
- アクセストークンは認可サーバーから発行され、リソースサーバーがそれを検証することでクライアントにアクセスを許可します。
- アクセストークンは一定の有効期間を持ち、トークンの有効期限が切れた場合、再度認証が必要になります（またはリフレッシュトークンを使用して更新することが可能）。
- アクセストークンは認証情報やユーザーの属性に基づいて発行され、APIリクエストのヘッダーに添付してアクセス権限を示します。

### 簡単な流れ

1. ユーザーがクライアントアプリケーションにログインを試みると、クライアントは認可サーバーから認可コードを取得します。
2. クライアントは認可コードを使用して認可サーバーからアクセストークンを取得します。
3. アクセストークンを用いて、クライアントはリソースサーバーへリクエストを送り、ユーザーのデータやリソースにアクセスします。

### まとめ

- **認可コード**はアクセストークンを取得するための一時的なコードで、セキュリティの強化に寄与します。
- **アクセストークン**は、リソースアクセス権限を表すトークンで、ユーザーのデータやリソースへのアクセスに使用されます。

この仕組みにより、OIDCはセキュアで効率的な認証とリソースアクセスを実現しています。
【トラブルシューティング】Docker composeでNVIDIA GPUが利用できなくなった時の対処方法

# はじめに
　DockerとDocker Composeをアップデート後に、NVIDIA GPUが利用できなくなった時の対処方法を紹介する。

# 動作環境
* Ubuntu 22.04 x64

# 原因と対策
　```docker-compose.yml```の設定ミス。利用するGPU数（```count```）を設定しなかったのが原因。以前はcountを設定していなくてもNVIDIA GPUが使えていたが、アップデート後は使えなくなった（2024/9/25時点）。
　```count```を以下のように設定することでNVIDIA GPUが認識するようになる。

 ```yaml:docker-compose.yml
services:
  test:
    image: nvidia/cuda:10.2-base
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1  # この設定を忘れないようにする。全てのGPUを利用する場合は、all にする。
              capabilities: [gpu]
 ```

# まとめ
　Docker composeでNVIDIA GPUが利用できなくなった時の対処方法を紹介した。設定方法が変わる可能性があるので、公式ドキュメントを参照することをお勧めする。

# 参考

 https://matsuand.github.io/docs.docker.jp.onthefly/compose/gpu-support/#enabling-gpu-access-to-service-containers
CM4-IO-BASE-CでM.2 NVMe SSDを使う

# 1. はじめに
Waveshareが出しているCM4用のIOボード「CM4-IO-BASE-C」にはM.2のコネクタがある。そこにNVMe SSDを接続して使用できるか確認する。
※このボードはSATAには対応していない。最初に間違えて購入してしていまい無駄ができた。

# 2. 機材
* CM4
* CM4-IO-BASE-C
* M.2 NVMe SSD（サイズは2230）
* OSはbullseye 64bit

# 3. SSDの接続
コネクタには切り欠きがあるので、おそらく間違えて接続することはない。CM4-IO-BASE-Cは2230と2242に対応している。それ以外だと長さオーバーとなって安定して固定できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/b1a6f0e7-bbf3-c455-6a6c-ccfaaf0774d6.png)

# 4. 使用できるようにする
まずは、電源をいれて状態を確認する。dmesgで追加されたのか判断つかなかった。lsblkだとeMMCとは異なる容量のデバイスが見えた

```
$ lsblk 
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mmcblk0      179:0    0  29.1G  0 disk 
～略～
nvme0n1      259:0    0 119.2G  0 disk 
```

フォーマットしてみる
```
$ sudo mkfs.ext4 /dev/nvme0n1
mke2fs 1.46.2 (28-Feb-2021)
～略～
Writing superblocks and filesystem accounting information: done 
```

マウントして確かめる
```
sudo mkdir -p /mnt/testdisk
sudo mount /dev/nvme0n1 /mnt/testdisk
```

マウント状態の確認
```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
～略～
/dev/nvme0n1    117G   24K  111G   1% /mnt/testdisk
```

マウントポイントの書き込み権限は初期状態でrootのみだったので、必要に応じて変更が必要。

## 4.1. 永続的にマウントする
UUIDを取得する
```
$ sudo blkid /dev/nvme0n1
/dev/nvme0n1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" BLOCK_SIZE="4096" TYPE="ext4"
```

/etc/fstabを編集してマウント情報を追加する
```
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/recdisk ext4 defaults 0 0
```

以上
git@github.com: Permission denied (publickey). githubにpushエラー対処

## はじめに
初心者向け＋備忘録です。
通常の手順は、自分のプロジェクトフォルダまで移動して
```
1.初期化
git init .

2.全ファイルステージング
git add . 

3.ブランチの作成
git checkout -b <branch name>

4.コミット
git commit -m "<コメント>"

5.接続
git remote add origin <SSH>

6.push(GitHubにデータを転送)
git push origin <branch name>
```
上記のコマンドをたたけば問題なくpushができるが
パソコンを変えたり、何らかの理由でSSHの接続ができていないとタイトルのようなエラーが発生する。


SSHを作り直すだけだし、簡単だろうと思っていたがハマってしまったのでｗ
共有します。

## 最初が一番つまずいた、、、

最初だがここが一番大切なところで、git bashで操作する！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/99a677f1-fe6b-97cf-c7c9-298bd8d99d3c.png)
windowsのスタートボタンの検索窓で検索すれば出てくるはず。
もし出てこなかったらインストールの必要があります。
　
自分はUbuntuだったり、コマンドプロンプトだったり、PowerShellだったりでいろいろやりましたが、ハマった原因はここです、、、。笑
　


gitBashを初めて使う方は
```
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"
```
上記のコマンドで登録を行います。
登録ができているかの確認は以下のコマンドで。
```
git config user.name
git config user.email
```

## 本題のSSHの発行！！
　
gitBashで下記のコマンドを実行する。
```
ssh-keygen -t ed25519 -C "GitHubに登録したメールアドレス"
```

パスワードは自分は打ちましたが
打たなくてもエンター連打で行けるみたいです。ｗ

 　
SSHの発行ができたら
SSHキーをクリップボードにコピーのコマンドを実行
```
clip < ~/.ssh/id_ed25519.pu
```

## GitHubに発行したSSHの登録
　
あとはこれをgitHubの方に登録するだけ！

gitHubの右上のアイコンをクリックするとメニューバーがでてくるので「Settings」を押下

![スクリーンショット 2024-10-29 224227.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/2cc2a7d8-7c18-6f7e-5108-2fbdf26fdc32.png)

右のサイドバーの「SSH and GPG keys」を押下
![スクリーンショット 2024-10-29 224430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/76e68cc4-ffa5-3419-e324-5ffbd8096edd.png)

「New SSH key」を押下で画面遷移。

赤枠にSSHキーをペースト！
※TitleはなんでもOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/771e7154-1fcc-6de5-f423-56f71165023b.png)


クリップボードにコピーされていない人はgitBashで
```
clip < ~/.ssh/id_ed25519.pu
```

SSHの保存ができたら接続がうまくできているか確認。
```
ssh -T git@github.com
```
下記の文言がでたら完了！
```
 You've successfully authenticated, but GitHub does not provide shell access.
```

自分の使いやすいCLI（gitをpushできる環境)でpushしてみよう！
pushのコマンドや流れなどは最初のコマンドを参考に！
time.sleep()ではなくdriver.implicitly_wait()を使ったら劇的に改善した話

:::note info
本記事は、Webクローリング・スクレイピングに関する記事です。
:::

先日、初めてWebクローリング・スクレイピングを実装しました。

大抵は、クローリングするサイトの負担を軽減するために、ページ遷移間隔を最大1秒ほどあけるべき、というのが一般的だと思いますが、**1秒の待機時間をとってもでもそのページをしっかり読み込めていない状態で次のページに遷移していまい、そのページのHTMLをしっかり取得できない**といった現象が起きていました。

よって筆者が実際に解決した、エラー解決プロセスについて記録しておきます。

もし、本記事で紹介している方法よりももっと簡単な解決方法があるといった場合や、誤って解説している箇所があればどしどしコメントください！！

## 問題点 ##
以下ようなの↓`time.sleep()`を利用したコードだと、うまくいかなかった
```diff_python
import time

# （例） ↑ここまで、目的のページのurlを取得しアクセスしようとしている。    
driver.get(item_url)

time.sleep(1)  # 商品ページが読み込まれるまで強制的に1秒間待機

# （例）↓ここからページに遷移したらそのページののHTMLを取得
item_html_content = driver.page_source 
```

## 解決策 ##
**chrome.driverというライブラリを使い、implicitly_wait()を用いる。**

さっきのコードの`time.sleep()`を変更して以下のようにするだけで、クローリングがうまくいきました。

```diff_python
from selenium import webdriver

# （例） ↑ここまで、目的のページのurlを取得しアクセスしようとしている。    
driver.get(item_url)

driver.implicitly_wait(10)  # 商品ページが読み込まれるまで強制的に10秒間待機

# （例）↓ここからページに遷移したらそのページののHTMLを取得
item_html_content = driver.page_source 
```

### 両者の違いとは？ ###
では、両者の違いとはいったい何だったのでしょうか？
まとめると以下↓のようになりそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871898/74be73c3-18ad-334b-e1a3-0c9eb42ff781.png)

chatgptを参考にコードを書いている方は、第一に`time.sleep()`を使う例を提案してきますが、正直ほとんど`time.sleep()`を使うメリットもないような気がしましたがどうなのでしょうか。。（`implicity_wait()`を利用するために必要なchrome.driverを使えないなど理由がある場合は別）
【Django・DRF】model取得時の外部結合方法

# 前置き
今回は外部結合方法がメインのため、モデルの定義などは省略する。

# 内部結合（INNER JOIN）
以下のようなコードがある

```python
@extend_schema(responses=SongListSerializer, tags=["song"])
class SongListView(views.APIView):
    def get(self: Self, request: Request, *args: Any, **kwargs: Any) -> Response:
        """曲一覧情報の取得"""
        songs = Song.objects.alive().select_related("artist", "album").all()

        print(songs.query)
        serializer = SongListSerializer(data=songs, many=True)
        serializer.is_valid()
        return Response(serializer.data, status=status.HTTP_200_OK)
```

この場合に発行されるクエリは以下の通りになる
```sql
SELECT 
  --カラム省略
FROM
 "songs"
INNER JOIN "artists"
 ON ("songs"."artist_id" = "artists"."id") 
INNER JOIN "albums" 
 ON ("songs"."album_id" = "albums"."id")
WHERE
  "songs"."deleted_at" IS NULL
```

そう`INNER JOIN`となるのである。

# 外部結合（LEFT JOIN）
以下のコードにすることで外部結合が行える。
```diff_python
# 変更前
- songs = Song.objects.alive().select_related("artist", "album").all()
# 変更後
+ songs = Song.objects.alive().select_related("album").prefetch_related("artist").all()
```
`prefetch_related`を利用すると中で定義したテーブルは外部結合される。

# 参考

https://qiita.com/shimayu22/items/1c0d9f0365ce6cc6488f

https://docs.djangoproject.com/en/4.0/ref/models/querysets/#prefetch-related
技術ブログのシステム化

##  技術ブログの目的


:::note info
昨今、ChatGPTが登場して技術ブログの必要性は相対的に減りつつあります。もともと技術ブログを他人のために体系立てて書いてやろう、という他者奉仕の精神で書いていたわけではありませんが、技術ブログを書く目的をあらためて整理したいと思いました。
:::


こんな画像もものの数秒で書いてくれるChatGPT。すごいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253735/1b95229a-8bef-bb1e-9e88-2e7d362ff7db.png)

:::note info
個人の技術ブログについて、何のために書くのかという目的を言語化していく記事になります
:::


- 技術ブログを何のために書くのかという目的によって、書き方は変わってきます
- 技術ブログは、「自分のため」に書くのが1番で、「他人のため」に書くのは余裕がある時でOKというスタンスでやっていきたいと思います（周りにも伝わる書き方にこだわりすぎると、アウトプットサイクルが鈍化するからです）
- 自分で一度学んだことを忘れないように要点を絞って書き出します
- 技術ブログにかける時間は少ければ少ないほどよく、時間をかけたからといってクオリティが上がるわけではありません
- したがって、なるべく多くの形のテンプレートを持っておいた方が、書き出すスピードもアウトプットの質が高まります



### みんなどうやって技術ブログを書いているの？

まず、技術ブログのテンプレをリサーチしよう！というのが以下の流れとなります。



## スクラップ部門

https://zenn.dev/ficilcom/articles/tech-blog-short

:::note info
1テーマ1記事という「ショート」なブログスタイルを提案。書き手も読み手も読みやすい工夫という意味で大変納得しました。体系的に書いていこうと思うと、記事も長くなって結局何が言いたいのかわからなくなりがちですが、「短くて良い」という価値観を知りました。
:::



## テンプレート管理部門

https://zenn.dev/renn/articles/454ea916a29236

:::note info
以下の3つのジャンルについて、それぞれブログのテンプレートを用意してくれています。「自分の知識の定着」という目的のために技術ブログを書くにあたって、「トライ系」と「紹介系」は良いテンプレートであり、参考になりました。
:::


> トライ系
>「〜やってみた。」「〜をする方法。」などです。おそらく、技術ブログと聞いて一番に思い浮かべるタイプではないでしょうか？

> 紹介系
> 「〜とは。」「〜は何のためにあるのか。」などです。自分が勉強したことのアウトプットとして書いている人が多いです。

> レポート系
> 「〜へ参加した。」「〜で思ったこと。」などです。こちらも、カンファレンスなどで知ったことや体験したことの備忘録として記事を書いている人が多いです。


## OpenAI活用編

https://logmi.jp/tech/articles/328718

この記事では、音声認識のAIなどを用いてアウトプットの効率化を図る取り組みなどが紹介されていました。
最近では、Napkin.aiなどを用いた図表作成AIも登場しており、これらも技術ブログの補助としてはとても良いと思います。図は、文章よりも情報伝達量が多いのと、知識をよく整理していないと上手な図表がそもそも書けないという点で、良い図を書けるというのは高い理解度を表していると思います。

ここでOpenAIの話題になったので、記事をAIに書いてもらうのも良いのではないかと思うかもしれませんが・・・

:::note alert
テックブログをChatGPTに書かせたのでは、何の学びにもなりません。補助として活用するにしても、やはり自分でタイピングすることに意味があります。
:::

- ChatGPTを用いたテックブログ作成は、注意が必要だと思っています
- 第三者からすれば、「よくまとまっている記事だなぁ」と見えますが、果たして自分の血肉となっているかと言われれば悩ましいと思われます。Googleが登場した時も、「ググった内容を忘れる」現象が生じたのと同じです
- 自分の学びではなく「PVを伸ばすため」など作業としての技術ブログであれば、どんどんChatGPTを活用すべきだと思います
- また、分からないことを聞くために活用するのはもちろんOKですが、回答が合っているのかのダブルチェックは必要です




## 企業ブログ編

https://note.com/megaya/n/n4b9e16362d61


:::note info
企業のテックブログは、エンジニア採用時にとても見られるコンテンツだと思います。書く側からすれば面倒極まりない作業ですが、書く側にもメリットを持たせる制度設計ができていれば、意外とすんなりアウトプットが定着するのでは・・・と思った記事でした。企業ブログをやるのであれば、目的の周知とテーマの選定、レビュー体制など1人でアクションを起こさずなるべく周りを巻き込んで進めていくのが継続の秘訣だと感じました。
:::


## 自分流のテックブログの書き方

- 1テーマ1記事
- 1記事に書ける時間は30分(or60分)
- ⭕️「自分の知識定着のために書く」❌「他人に説明するために書く」
- 文章の校正、加筆修正はやるとしても1回まで
- 記事のテンプレートを積極的に活用する（文章構成に時間をかけない）
- 図表の作成などAIの力はなるべく借りる（シーケンス図やフローチャートに時間をかけない）


以上、おしまい！
FLOPS,FLOPs,MACsの違い



## FLOPs（Floating Point Operations）
FLOPsは，アルゴリズムやAIモデルが実行する浮動小数点演算の総量を示す指標です。
FLOPsの値が大きいほど，プログラムが多くの計算を必要とします．

## FLOPS（Floating Point Operations Per Second）
1秒間に浮動小数点演算が何回できるかの指標値で、主にCPUやGPUといったコンピュータのハードウェア性能を評価します．
例えば，MRIデータをリアルタイムで解析する場合、FLOPSが高いプロセッサを使用すれば，迅速にデータを処理できます．
2024年3月現在，世界最高速のスパコンはFrontierで1.102EFLOPS．分散コンピューティングでは，Folding@homeが一時的に2.4EFLOPSを突破しました．

2.4EFLOPSのすごさ．

<div style="text-align: center;">
<img width="150"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457930/ff377d56-35af-d825-defb-5af397793cd5.png">
   
</div>

## MACs
MACs（Multiply-Accumulate Operations）は、「乗算と加算の演算回数」を指し、特にニューラルネットワークなどの計算複雑性を測定するための指標としてよく使用されます。MACは1つの「乗算と加算」操作を1回の演算としてカウントします。


## FLOPsとMACsの関係
一般に，1つのMACは2つのFLOPに相当します.これは，1回のMAC操作が1回の乗算と1回の加算を含むためです．

                       1 MAC ≒ 2 FLOPs

たとえば，行列積の計算では、各要素の計算に1回の乗算と1回の加算が含まれるため，1要素あたり1 MAC（つまり2 FLOPs）が必要です．

詳しくはこの記事を見てください．


https://www.kdnuggets.com/2023/06/calculate-computational-efficiency-deep-learning-models-flops-macs.html#:~:text=What%20are%20FLOPs%20and%20MACs%3F%20FLOPs%20%28Floating%20Point,arithmetic%20operations%20required%20to%20perform%20a%20given%20com
【PostgreSQL】同じ時刻関数を同一SQL文に複数記述すると？

# はじめに
最近開発でPostgreSQLを使用していて、同一sql文に現在時刻を取得するnow()を複数記述しているのを見かけました。これって同じ値をとるの？呼び出すたびに少しずつ時間がずれるんじゃないの？という疑問が生じたので調べてみました。
例えば以下のような場合です。
```sql
UPDATE hoge
SET
    status = 'completed',
    updated_at = NOW(),
    registered_at = NOW()
WHERE
    id = 1
;
```
```sql
SELECT
    *
FROM
    hoge
WHERE
    startTime <= CURRENT_DAT
    and CURRENT_DAT <= endTime
;
```
2つ目だと、仮に(あまりあり得ないが)1つ目のCURRENT_DATと2つ目のCURRENT_DATの間で日付が変わったら、適切に比較処理できないのでは？と思ったりしました。
# 結論
postgresqlにおいて、時刻系関数はトランザクション開始時の時刻を参照するため、複数呼び出しても同じ値をとるようです。

https://kaede.jp/2015/09/25012107/

# まとめ
ふと気になったことをメモ書き程度に書いてみました。
文字列に含まれる全角・半角スペースを消去する方法

このくらいであれば、皆さんChatgptに聞いていると思うのでこの記事の需要があるかどうかは微妙なとこですが、自分のアウトプットのために記しておきます。

また、もし、本記事で紹介している方法よりももっと簡単な解決方法があるといった場合や、誤って解説している箇所があればどしどしコメントください！！

## 全角スペースを消去 ##
```bash
cleaned_title = cleaned_title.replace('\u3000', '')
```

## 半角スペースを消去 ##
```bash
cleaned_title = cleaned_title.replace(' ', '')
```
## 全角スペースを半角スペースに変換 ##
```bash
cleaned_title = cleaned_title.replace('\u3000', ' ')
```

今回は短めになりますが、以上にします！！
また、同じ系統のテーマで新たに学んだことがあればこの記事に追加します！
chrome のページ全体のスクショの操作方法

## 概要
- ページのスクショの撮り方 on chrome

##### why?
私のショートカットキーと被って、サイト見てもショートカットキーばかり言っていて、結果できなかった。
たまたま見つけたので、メモしておくよ。

## やり方
1. 開発コンソールを出す
1. レスポンシブの表示に変更
1. レスポンシブの右端にある縦の `・・・` をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387311/6ed64541-b200-d5b4-722f-c004607cd568.png)

4. `capture full size screenshot` をクリック

これで、ファイルがDL される。

## 終わり。
どうしてエンジニア向けじゃないサイトでも、ショートカットとか出てくるんだろう。
GUI での方法書いてほしい....

これ割と最近できた？？前からあった？？と疑問はありつつ、これあるのは素敵。
ActiveRecord::PendingMigrationError【Ruby on Rails】

ruby on railsでアプリケーション作成中に出遭ったエラーについての解決方法です。

今回、ターミナルからrails g migration Addカラム名Toテーブル名でカラムを追加したところ、テーブル名を間違えてしまったようでエラーになりました。

## エラーメッセージ
```
Migrations are pending. To resolve this issue, run:
bin/rails db:migrate RAILS_ENV=development
You have 1 pending migration:
20241025004905_add_user_id_to_tweers.rb
```
マイグレーションは保留中、bin/rails db:migrate RAILS_ENV=developmentを実行してとのことなのでターミナルに入力。

続いて下記エラーが発生。
```
StandardError: An error has occurred, all later migrations canceled: (StandardError)

~中略〜

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'pictweet2_development.tweers' doesn't exist (ActiveRecord::StatementInvalid)
/Users/--USERNAME--/projects/pictweet2/db/migrate/20241025004905_add_user_id_to_tweers.rb:3:in `change'

```

ここでテーブル名がtweetsではなく、tweersになっていると気づく。

## 解決方法
```
% rails db:migrate:status
```
上記ターミナルで実行し、マイグレーションファイルの状況を確認

```
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20241024001642  Create tweets
   up     20241024073306  Devise create users
   up     20241024075347  Add nickname to users
  down    20241025004905  Add user id to tweers 
```

問題のファイルが一番したのファイルですが、statusがdownになっていることを確認。

:::note
migrationファイルの修正は必ずstatusをdownにしてから行う必要がある
:::

該当のマイグレーションファイルのクラス名とファイル名を手入力で変更。
```
% rails db:migrate
```
上記を実行したところ正しいテーブル名となり、エラーが解消した。

## まとめ
エラーになる原因はスペルミスが多いので重要な変更をする際には注意が必要。
エラー時にはメッセージを読むのが解決の糸口になる。
どちらも当たり前だけど大事な基本だあと認識した。
Spring Bootプロジェクトのリファクタリング

## はじめに
進行中のプロジェクトでリファクタリングを担当しています。使用しているフレームワークはVue.jsとSpring Bootで、クライアントとサーバーはREST API（JSONフォーマット）で通信しています。
リファクタリングの経験がないため、どのような手順で進めればよいかを調査しながら、成果と学びを記録に残していきたいと考えています。

## リファクタリングの目的
リファクタリングの必要性を明確にし、以下の目的を目指します。

**1. コードの可読性向上：** コードを整理し、後から変更や追加がしやすい構造にする。
**2. 保守性向上：** メンテナンスが容易で、エラーやバグが発生しにくい構造を目指す。
**3. パフォーマンスの最適化：** 不必要な計算や処理を取り除き、効率的に動作させる。

## リファクタリングの進行手順
### 1. 現状と課題の分析 ###
**・コードレビュー：** 画面のバックエンド側のソースコードに対してコードレビューを実施し、改善が必要な箇所を洗い出す。
**・課題リストの作成と優先度の決定：** リファクタリング対象箇所をリスト化し、各箇所に対する解決策を検討した上で優先度を決定します。

### 2. コード修正とテスト ###
**・リファクタリングの実施：** 優先度の高い箇所から順次リファクタリングを進めていきます。
**・テストの実施：** 単体テストを行い、リファクタリング後も機能が正しく動作していることを確認します。また、自動化テストの適用範囲を広げ、効率的なテスト体制を整備します。

### 3. 品質確認 ###
**・最終品質確認：** リファクタリング後のコードを試験環境にデプロイし、結合テストを実施して全体の品質を確認します。

## リファクタリング対象のチェックリスト
| No| 大項目 | 中項目 | チェック内容 | 重要度 |
|:----|:------|:------|:-----------|:-----:|
|1|設計|クラスの責務分離|クラスが大きすぎず、1つのクラスが複数の責務を持たないようになっているか。|高|
|2|設計|メソッドの粒度|メソッドが短く、1つの責務に集中しているか。|高|
|3|設計|インターフェース設計|インターフェースで提供するデータが必要最小限に抑えられているか、不要なデータが含まれていないか。<br>シンプルでわかりやすい構造になっているか。<br>今後の機能追加や変更に備え、インターフェースが柔軟に拡張可能な設計になっているか。|高|
|4|可読性|命名規則の一貫性|変数名、メソッド名、クラス名が一貫性を持ち、コードの意図を明確に伝えているか。|低|
|5|可読性|コメントの適切性|必要な場所にコメントがあり、コードの動作や意図が理解しやすくなっているか。|低|
|6|可読性|コード構造の整理|ループや条件分岐が見やすく整理され、コードの構造がわかりやすくなっているか。|中|
|7|保守性|定数の利用|マジックナンバーやハードコードを避け、適切に定数を使用しているか。|中|
|8|保守性|条件分岐の簡潔さ|条件分岐が複雑すぎず、理解しやすい構造になっているか。|中|
|9|保守性|コードの再利用|共通の処理やユーティリティが独立したクラスやメソッドに整理されているか。|中|
|10|パフォーマンス|非同期処理|重たい処理を非同期で処理し、スループットとUIの応答性が保証されているか。|高|
|11|パフォーマンス|ループの最適化|不要なループを削減し、処理効率を向上させているか。|中|
|12|パフォーマンス|ライブラリの活用|適切なライブラリを効果的に活用し、パフォーマンスを改善しているか。|中|
|13|信頼性|エラーハンドリング|適切なエラーメッセージを提供し、ユーザーが問題を理解しやすくなっているか。|高|
|14|信頼性|リトライロジック|必要に応じて処理がリトライされる仕組みがあるか。|高|
|15|信頼性|ログレベルの一貫性|ログレベル（INFO、WARN、ERROR）が適切に設定されているか。|中|
|16|信頼性|ログの記録|重要なアクションやエラーについて、必要なログが記録されているか。|中|
|17|セキュリティ|データマスキング|ログに機密情報が含まれている場合、適切にマスク処理がされているか。|高|
ゲームプログラマのための設計：指示付き初期化

[ゲームプログラマのための設計シリーズ](https://qiita.com/kobitnex/items/93397d985682c806884c)：実装詳細編の記事です。

# 概要
* 指示付き初期化でconstにしつつ、初期化時の変数の取り違えを防ぎやすくなった
* 引数を多くとる関数にも活用

# 本文
## C++17以前の構造体・クラスの初期化

複数のメンバの値を外から初期化したい場合、素朴には以下のような実装が考えられます。
```cpp
struct Color
{
	float r,g,b,a; // (ほんとはこちらにも初期値を入れておいた方がいいです)
};

void func()
{
    // パッと見、どの変数を初期化しているのかわかりにくい
	const Color color{ 0.0f,0.5f,1.0f,1.0f };
}
```
しかしこれには、
* どの変数を初期化しているのかわかりづらく、取り違えの危険がある
* Color側の変数の順番を迂闊に入れ替えてしまってもその影響に気付きにくい

といった問題があります。
そこで、
```cpp
void func()
{
	Color color;
	color.r = 0.0f;
	color.g = 0.5f;
	color.b = 1.0f;
	color.a = 1.0f;
}
```
のように書くことで対策していました。
しかし、これはこれで初期化対象をconstにするのをあきらめる必要がありました。(この用途でconst_castを使うのはやりすぎだと思っています)

## 指示付き初期化
[指示付き初期化](https://cpprefjp.github.io/lang/cpp20/designated_initialization.html)とは、C++20で追加された変数の初期化方法です。詳しくはリンク先を参照いただくとして、簡単には以下のように書ける機能です。

```cpp
void func()
{
    // .rなどで、メンバ名を指定して初期化できる
	const Color color{
		.r = 0.0f,
		.g = 0.5f,
		.b = 1.0f,
		.a = 1.0f
	};
}
```
前述の二例のいいとこどりができるようになりました。
デメリットらしいデメリットもほとんど思い当たらないので、積極的に使っていくのをオススメします。

## 多引数関数にも活用
引数がたくさんある関数は、引数の取り違えが怖いですね。
```cpp
// 引数が5個を超えると、急に取り違えミスの発生確率が上がるらしい
void ManyArgFunc(int x, int y, int wx, int wy, Color color);
```
引数を構造体に切り出すと、指示付き初期化が使えて取り違えしにくくできます。
```cpp
struct ManyArgFuncArg
{
	int x;
	int y;
	int wx;
	int wy;
	Color color;
};
void ManyArgFunc(const ManyArgFuncArg&);

void func()
{
    // どの引数にどの値を与えているか、わかりやすくなった
	ManyArgFunc({
		.x = 0,
		.y = 50,
		.wx = 20,
		.wy = 10,
        // ネストも可能
		.color{
			.r = 0.0f,
			.g = 0.5f,
			.b = 1.0f,
			.a = 1.0f
		}
	});
}
```

## 余談
指示付き初期化自体の問題ではないのですが、惜しいと思うのが明示的な初期化を強制することはできないということです。

```cpp
struct Data
{
	const int a;  // constにしても・・・
	const float b;
};

Data d{.b = 0.1f}; // 集成体初期化で記述しなかった変数はゼロ初期化される
```

明示的な初期化を強制するなら、コンストラクタを使い指示付き初期化はあきらめるしかなさそうです。（せめて、明示的な初期化が必要な変数を別の構造体に分けるくらい）
何かいい方法をご存じであればぜひコメントください。
```cpp
struct Data
{
	Data(int a, float b) : a(a), b(b) {} // これがあるともう指示付き初期化は使えない
	const int a;
	const float b;
};
```
DNSキャッシュとnslookupの使い方：DNSサーバーの変更方法と名前解決の基本を解説

## はじめに
ネットワークのトラブルシューティングやドメイン情報の確認において、DNS（Domain Name System）は欠かせない存在です。

``nslookup``は、DNSサーバーにクエリを送信して、ホスト名からIPアドレスを取得したり、逆引き検索を行ったりできる便利なコマンドです。

:::note warn
オプションが多く最初は理解が難しい部分もありましたが、実際に手を動かすことで少しずつDNSについての理解を深めることができました。
:::

過去の記事でもDNSサーバーの構築方法と名前解決の技術検証について紹介していますので、興味のある方は参考にしてみてください。

https://qiita.com/free-honda/items/807b36c839f49d7bdb47

## 基本的な使い方
### ホスト名からIPアドレスを調べる
```
nslookup [ホスト名]
```

例: ``nslookup google.com``

このコマンドを実行すると、google.comのIPアドレスが表示されます。

### IPアドレスからホスト名を調べる（逆引き）
```
nslookup [IPアドレス]
```

例: ``nslookup 8.8.8.8``

このコマンドを実行すると、IPアドレス 8.8.8.8に関連付けられたドメイン名（逆引き）が表示されます。

## オプションと設定
### DNSサーバーを指定して検索

```bash
nslookup [ホスト名またはIPアドレス] [DNSサーバー]
```

例: ``nslookup google.com 8.8.8.8``
この例では、GoogleのDNSサーバー``8.8.8.8``を使用して``google.com``のIPアドレスを検索します。

### タイプ（レコードタイプ）を指定
```bash
nslookup -type=[レコードタイプ] [ホスト名]
```

例: ``nslookup -type=MX google.com``
これにより、``google.com``のメールサーバー（MXレコード）情報が表示されます。

### サーチタイムアウトの変更
```bash
nslookup -timeout=[秒数] [ホスト名]
```

タイムアウトの秒数を設定し、応答待ちの時間を調整できます。

### デバッグ情報を表示
```bash
nslookup -debug [ホスト名]
```

デバッグモードで詳細なDNSクエリ情報を確認でき、トラブルシューティングに役立ちます。

## 実務でよく使う``nslookup``のインタラクティブモード

``nslookup``を引数なしで実行すると、インタラクティブモードに入り、複数のドメインを一度に調べたり追加の設定を行えます。

:::note 
**一時的に異なるDNSサーバーに切り替えて名前解決を行うことが可能です。**
:::

``nslookup``とだけ入力してEnterを押すと、インタラクティブモードに入ります。

```bash
nslookup
```

``server``コマンドで新しいDNSサーバーのIPアドレスを指定します。例えば、GoogleのDNSサーバー``8.8.8.8``を使う場合は次のように入力します。。

```bash
> server 8.8.8.8
```

これにより、指定したDNSサーバーを使用して名前解決が行われるようになります。

続けて、名前解決したいホスト名を入力します。例えば、``google.com``のIPアドレスを確認するには以下のように入力します。

```bash
> google.com
```

これで、指定したDNSサーバーを使って名前解決が行われ、結果が表示されます。

インタラクティブモードから抜けるには、exitと入力してEnterを押します。

```bash
> exit
```

:::note warn
インタラクティブモードを使うと、一時的に異なるDNSサーバーに切り替えて複数のホストを連続して調べることができるため、ネットワークのトラブルシューティングや設定確認に役立ちます。
:::



## まとめ
``nslookup``は、ネットワークトラブルの調査やDNSに関する情報を素早く確認するための強力なコマンドです。

シンプルなコマンドながら、インタラクティブモードやオプション機能を活用することで、詳細なDNS情報を簡単に取得できます。また、DNSキャッシュをクリアすることで問題解決の手助けになる場合もあります。

ネットワークの基礎知識を深め、実務で役立てたい方にとって、覚えておくと便利なコマンドです！

## おまけ：DNSキャッシュをクリアするコマンド
DNSの問題が発生した場合、システム上のキャッシュをクリアすることで、DNSの最新情報を再取得できることがあります。以下は、DNSキャッシュをクリアするコマンドです。

**Windows**
```bash
ipconfig /flushdns
```

**MacOS**
```bash
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
```

**Linux（ディストリビューションにより異なります）**
```bash
sudo systemd-resolve --flush-caches
```

または

```bash
sudo service nscd restart
```

## 参考文献

https://www.winserver.ne.jp/column/about_nslookup/

https://atmarkit.itmedia.co.jp/ait/articles/0203/21/news003.html
【Git初心者向け】git statusの使い方｜リポジトリの状態を一目で確認！

## この記事でわかること
git statusの基本的な使い方

## 主な想定読者
- Git初心者
- git statusの使い方がわからない方
- git addやgit commitの実行状況を確認したい方

## git statusとは
現在のGitリポジトリの状態を確認できるGitコマンドであり、主に以下の3点の情報が確認可能
1. 未追跡ファイルが存在するか
2. git addされていない変更が存在するか
3. git commitされていない変更が存在するか
:::note info
未追跡ファイル：まだGitのバージョン管理対象となっていないファイルのこと。この「未追跡」のファイルは、まだGitの管理下に入っていないため、変更を加えてもGitの履歴には残らず、まだGitでバージョン管理ができていない状態。バージョン管理の対象に含めたい場合は、後述するように git add コマンドを使って「追跡」させる必要がある。
:::

## git statusの使い方
- Gitリポジトリ内の任意のディレクトリに移動し、以下のコマンドを実行
```:ターミナル
git status
```
- 上記コマンドの実行により、リポジトリに関する下記3点の情報を確認可能
　1. 未追跡ファイルが存在するか
　2. git addされていない変更が存在するか
　　（≒変更されたがステージグエリアには未追加のファイルが存在するか）
　3. git commitされていない変更が存在するか
　　（≒ステージングエリアには追加済みだがコミット待ち状態のファイルが存在するか）
- 以下は、実際にコマンドを実行した場合に表示される結果の例
```:ターミナル
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   file1.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   file2.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    newfile.txt

```
- 上記実行結果の例の簡単な解説
  - `Changes to be committed:`（コミットすべき変更）
`file1.txt` は `git add` によってステージングエリアに追加されたファイルだが、`git commit` はまだされていない

  - `Changes not staged for commit:`（ステージングされていない変更）
`file2.txt` は、変更されているが、まだ `git add` されておらず、ステージングエリアには存在しない

  - `Untracked files:`（未追跡ファイル）
`newfile.txt` は、Gitでまだ一度も追跡されていないファイルで、Gitのバージョン管理対象に含まれていない

## 補足：未追跡ファイルを追跡対象にする方法
- 前提
Gitでは、プロジェクトのフォルダ内にあるファイルが、全て自動的に管理されるわけではなく、追跡する（＝バージョン管理する）かどうかを、ユーザーの方で指定する必要がある
- 追跡対象にする方法
未追跡のファイルをGitで追跡し、バージョン管理に含めたい場合は、`git add` コマンドを使う
- 追跡対象にする場合の `git add` コマンド実行例
以下のようにコマンドを実行することで、未追跡ファイルであった `newfile.txt` が、Gitの追跡対象（バージョン管理対象）へと変わる

```:ターミナル
git add newfile.txt
```

## 最後に
最後までお読み頂き、ありがとうございました！
この記事が少しでもお役に立てば幸いです。
react-router-dom v6で視覚的にネストした記述法

## 概要
`react-router-dom v6`でネストしたルーティングを記述する際、ソースコードを視覚的にネストさせて記述する方法

## 参考記事
https://zenn.dev/minntoko/articles/39d89c32cb0262

## ネストせずに記述する場合
```react
<Routes>
    <Route path="/" element={<Home />} />
    <Route path="page1" element={<Page1 />} />
    <Route path="page1/detailA" element={<Page1DetailA />} />
    <Route path="page1/detailB" element={<Page1DetailB />} />
    <Route path="page2" element={<Page2 />} />
</Routes>
```
* これでもpage1のページからdetailA,detailBへとネストしたページ遷移は可能
* ただ視覚的にネストしたページ遷移であることが分かりづらい（インデントが入っていないのと、絶対パスになっているため）

## ネストさせた記述法
```react
<Routes>
    <Route path="/" element={<Home />} />
    <Route path="page1">
      <Route index element={<Page1 />} />
      <Route path="detailA" element={<Page1DetailA />} />
      <Route path="detailB" element={<Page1DetailB />} />
    </Route>
    <Route path="page2" element={<Page2 />} />
</Routes>
```
* ネストの親ページに対しindexを指定
* 子ページには絶対パスではなく、親ページからの相対パスで記述する
* コード整形ツールを入れている場合、自動でインデントが入る

## まとめ
ネストしたルーティングはソースコードも視覚的にネストさせたほうが分かりやすいので、`react-router-dom v6`を使用する際は積極的に使用したほうが良さそうです。

私自身、まだReactの学習をして日が浅くバージョンの違いによる記述法を調べるのは大変ですが、これからキャッチアップ力を鍛えていきたいです。
「１億ドルコーチ」を読んで。～最高のコーチングから得る仕事術～

## 序文 
ビル・キャンベルという人物をご存じでしょうか？
私は殆ど記憶に残っていませんでしたが、2011年、スティーブ・ジョブズの追悼式で最初にスピーチをしたのが彼だそうです。
彼は、アメリカにあるいくつもの会社（アップル、グーグル、アマゾン、フェイスブック（現メタ）など）の経営陣や役員などから「コーチ」と親しまれ、敬われた人物です。
この本を読んでいるとビルは「素直で、口が悪く、優しく、ユーモアがあふれる」人間であったことがわかるのですが、もちろんそれだけでは巨大ともいえる会社の CEO 達から「コーチ」なんて呼ばれることはないでしょう。
そこには彼なりの考え方やメソッドがありました。
この本はそんな彼の考え方を、彼の教え子たちがまとめた本になります。
私はこの本から様々な考え方を得ましたが、その中から、３つほどご紹介したく思います。

## 会議が始まる前の時間は無駄にしない

仕事で会議に参加するもしくは会議の中心になるとき、あなたはどのような準備をしていますか？
この本でビルが求めていたことから私が実践している2つをピックアップします。
1つ、会議前に資料を読んでおく
2つ、会議前の時間を使いチーム内の友好関係を深める

１つ目の「会議前に資料を読んでおく」。これは結構目に見えて成果があった仕事のコツです。
本の中では

`最新の情報を会議で提示すると会議の話題はその「情報について」と、「情報の些細な問題について」で完結してしまう。情報を先に参加者へ提示し、参加者にはその資料を確認したうえで「質問」を持ってきてもらうことに期待する`

と書かれていました（ニュアンスは違いますが…）。
もちろんこの本はコーチングの本なので、視点はリーダーの物になってます。そして、私はその立ち位置にいないのでメンバーにそれを求めることはできないです。
ならばどうするか。
私は、自分だけでも資料を確認しておき、質問を持っていくようにしました。

たとえば会議の時間、折角口頭で質問ができる時間があるのにもかかわらず、情報のインプットだけで時間が無くなってしまい、後から「ここ、どうなんですか？」とチャットやメールで質問する。意外とありませんか？
それがなくなりました。一回のやり取りで完結するので、時間も短縮されましたし、現場でそのスタイルが評価されることも多々ありました。
１日の隙間時間で資料を確認し、質問を洗い出すのは若干大変ですが かなり ハッキリとした効果がみれます。
因みに私が会議の主体になるときは必ず先に資料を提示するようにしております。が、効果はこれからに期待ですかね…

2つ目の「会議前の時間を使いチーム内の友好関係を深める」。これは１つ目の物と違い、会議の場でできるコツです。
本の中では

`これはコミュニケーション法の一環であり、目的が2つある。1つは、メンバー同士が、「興味深い生活を持つ人間同士として、お互いを知りあえるようにすること」2つ目が「最初からミーティングを楽しめるようにすること」`

と言う趣旨が書かれていました。
もう少し本の内容に触れると、このやり方はgoogle内でも行われていたらしく、エリック・シュミットやビルはメンバーに「週末に何をしたのか」や、「どこに旅行へ行き、どんなことをしたのか」などを会議の議題に入る前に質問したそうです。
これを読んでいて思い出したのは、私が1年目の時のです。

当時の私には若干荷が重い案件に入ってしまい、毎日残業をしていました。ハッキリ言ってきつかったです。
しかし、当時も、今その時を振り返っても、嫌なイメージは殆ど、無いのです。

理由としてはメンバー内で一体感が強かったから。そしてその一体感を作り出していた要因の一つは「夕会前の雑談コーナー」だとおもいます。
話す内容は何でもいいです。競馬でも、スポーツでも、好きなアーティストでも。たった2，3分間の雑談。それだけでただのプロジェクトメンバーがより「仲間」に近づく。そんな感覚がありました。

しかし、どんなに効果があっても私は会議の時間に雑談の時間をこじ開けられる立場にいません。
私が狙ったのは会議の時間の前。その隙間時間で話すようにしました。会議があれば、５分前、遅くとも2，3分前にはその場にほとんどのメンバーが集まっているでしょう。その時にちょっとした話題を振っています。
例えば、「ふるさと納税、何かおすすめの商品ありますか？」など、仕事に関係のない話題などです。
これをするだけで場の雰囲気が軽くなりますし、何となく会話に参加したメンバーは会議中でも穏やかな表情になっているように感じられます。これが続くと、仲良くなれたり、助け合えたり、時に意見の交換や助言などをもらったりするようになれます。
また、この雑談というテクニックは、スティーブ・ジョブズもよく使っていました。
例えば、新型iPhoneの発売発表時、雑談の中で１世代前のiPhoneについて簡単に振り返ることで新型iPhoneへの意識の誘導を行っていたという話を聞いたことがあります。
これ以上は主題から大きく逸脱してしまうためここでは語りませんが、スティーブ・ジョブズの雑談テクニックは調べてみると様々な収穫があると思います。



## 安全な姿勢を貫く

安全な姿勢を貫くという言葉を読んで、あなたはどのようなイメージを受けたでしょうか？
この本でビルが求めていたことから私が実践している1つだけピックアップします。
1つ、相手がよい事をした場合、それを称える。

称える、と書きますと上から目線に感じますがそういうわけではなく、相手がちょっと良い事をしたときにそれに対して拍手や相槌を打つなどを行い、相手の行動に対して「応援」する意図をもちます。

本の中では

`誰かがミーティングで何か良い事を発表すると皆で５回拍手する。部下と彼らの成功を派手に応援せよ`

と書かれていました。
エニプラでは毎年忘年会で「エニプラアワード」の発表があり、私も去年ほかの社員の方の前で発表させて頂いたのですが…その際にがっちがちに緊張してしまいました。発表中も何回か噛んでしまい、「早く終わりたい！！」と思いつつ発表を続けていると、ふと、前のほうに座っていた先輩の一人が私を見て「うんうん」と頷いてくれているのが見えました。それが本当にうれしくて、一気に緊張が吹き飛んだ記憶があります。そんな経験があったので、この話は簡単に納得ができました。
是非、誰かの発言や発表に拍手をするところから、やってみてください。

## さいごに

「１億ドルコーチ」を読んで。～最高のコーチングから得る仕事術～ ということで、この本から学んで、私が実際に実践している中から３点をピックアップして書いてみましたが、いかがでしたでしょうか？
この本はコーチングについての本で、一見、私のような役職を持っていない人間からすると何の意味もないような本ですが、見方を変えれば「部下にこうなって欲しい」と言う像が読める本でもあります。
気になった方は是非読んでみてください。

エニプラの社員の方は後ほど（許可がとれれば）会社に置いておこうと思うので、本棚を探してみてください。

それでは、今回はこのあたりで失礼します。ほかのエニプラ社員も記事を投稿しておりますので、そちらも是非、ご覧ください。
ご覧いただき、ありがとうございました。