OmniAICreator/Qiita-1.07M huggingface dataset:
[systemd] システム起動時にNFSをマウント

`/etc/fstab`に自動マウント設定を書いたら、スペルミスで立ち上がらなくなった経験が何度かあるので、`systemd`を使った時の記録



## 環境
- サーバ側
Synology製NAS

- クライアント側
Ubuntu 24.04.01 LTS
```bash
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
```
```mermaid
graph LR
    NFS[NFSサーバ<br>192.168.0.10] ---- CLI[Ubuntu<br>192.168.0.2]
```

## 準備

### 前提パッケージのインストール
必要なパッケージをインストールする
```bash
$ sudo apt install nfs-common
```

### マウント先ディレクトリの作成
`/mnt`の下に好きな名前のディレクトリを作る
```bash
$ sudo mkdir -p /mnt/nfs
```

### マウントの確認
```bash
$ sudo mount -t nfs -o vers=4 192.168.0.1:/nfs-volume /mnt/nfs
# sudo mount -t nfs -o vers=[NFSバージョン] [IPアドレス]:[NFSディレクトリのパス] [マウント先ディレクトリパス]
```
マウントできたことを確認したらアンマウントしておく
```bash
$ 例: sudo umount /mnt/nfs
# sudo umount [マウント先ディレクトリパス]
```

:::note warn
外部のファイルシステムをマウントするときは`root`権限が必須 [^1] 
:::


## systemdへ登録
`/etc/systemd/system`に`.mount`と`.automount`ファイルを作成する

:::note warn
- ファイル名はマウント先のパスの基づいて名付ける [^2]
マウント先: `/mnt/nfs` -> ファイル名: `mnt-nfs.mount`
- `.automount`は`.mount`ファイルと同じ名前にする
`mnt-nfs.mount` <-> `mnt-nfs.automount`
:::

## `.mount`ファイルの作成
```bash
$ sudo vi /etc/systemd/system/mnt-nfs.mount
```
```systemd:net-mount.mount
[Unit]
Description=Mount network volume at boot

[Mount]
What=192,168.0.1:/nfs-volume
Where=/mnt/nfs
Options=vers=4
Type=nfs
TimeoutSec=10

[Install]
WantedBy=multi-user.target
```
- Description: 説明
- What: ネットワークボリュームの場所 ([IPアドレス]:[NFSディレクトリのパス])
- Where: マウント先
- Options: マウント時のオプション ここではNFSv4を指定
- Type: ファイルシステムの種類を指定
- Timeout: タイムアウト時間を設定 (秒)
- WantedBy: 依存関係を設定 (システム起動時に実行させる)

### `.automount`ファイルの作成
```bash
$ sudo vi /etc/systemd/system/mnt-nfs.automount
```
```systemd:net-mount.automount
[Unit]
Desctiption=Automount network volume

[Automount]
Where=/mnt/nfs

[Install]
WantedBy=multi-user.target
```

- Description: 説明
- Where: マウント先パス
- WantedBy: 依存関係を設定 (システム起動時に実行させる)

### オートマウントの登録 & 開始
`.automount` のみ `multi-user.target` に登録し起動する
※マウント先ディレクトリが存在しなければ作成される (らしい)
```bash
# 一応systemdをリロード
$ sudo systemctl daemon-reload

# `.automount`のみ`multi-user.target`に登録 & 起動
$ sudo systemctl enable mnt-nfs.automount
$ sudo systemctl start mnt-nfs.automount
```

これでNFSサーバから`/mnt/nfs`にマウントができる

---

AutoFSの存在を知ったのはこの記事を書いてる途中でした

## 参考
[NFS - ArchWiki](https://wiki.archlinux.jp/index.php/NFS#systemd_.E3.83.A6.E3.83.8B.E3.83.83.E3.83.88.E3.81.A8.E3.81.97.E3.81.A6)

[^1]: [linux - mount.nfs: failed to apply fstab options when mount nfs file system in fedora 32 - Server Fault](https://serverfault.com/questions/1025805/mount-nfs-failed-to-apply-fstab-options-when-mount-nfs-file-system-in-fedora-32)

[^2]: [Systemd mount fails. Where= setting doesn't match unit name - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/283442/systemd-mount-fails-where-setting-doesnt-match-unit-name)
【Python入門】基礎構文のまとめ

# Python基本構文 まとめ
Python構文を理解しておくことで、世の中に出回っているソースコードが読み易く、また開発効率があがると思われるテーマをまとめてみました。
※記事を追加次第更新してきます。

|#|テーマ|概要|
|---:|---|---|
|1|[【Python】stringの扱いについて](https://qiita.com/atsuuun/items/e9df5dacd44284076e2c)|stringのフォーマット方法についての解説
|2|[【Python入門】真偽判定について](https://qiita.com/atsuuun/items/ecc5de9741e54c1c5eba)|if文やwhile文等での真偽判定帆方法についての解説
|3|[【Python】文字列操作について](https://qiita.com/atsuuun/items/5d7c5a64c622c2cd0cdf)|部分文字列等を取得するときに使用できるモジュールについての解説|
|4|[【Python入門】list,tuple,dict,rangeからのデータ抽出方法について](https://qiita.com/atsuuun/items/d9ff937c6005220785bd)|シーケンス型におけるデータ抽出方法
|5|[【python入門】関数定義と位置専用引数・キーワード引数について](https://qiita.com/atsuuun/items/f586e9ed1c6942d63f7f)|関数引数についての解説
|6|[【Python入門】変数のスコープについて](https://qiita.com/atsuuun/items/0bec272cf80e7a0f5d26)|変数のスコープについての解説
機械学習アルゴリズムに関する土台基礎

# 機械学習アルゴリズムの3つの主要構成
**1 意識決定プロセス**
一般に、機械学習アルゴリズムは、予測または分類を行うために使用される。

**2 誤差関数**
モデル評価を行うために、誤差関数を評価してモデル予測を評価する。

**3 モデルの最適化プロセス**
モデルの評価を行い、既知の例とモデルの評価の誤差を少なくしていく。「評価と最適化」のプロセスを繰り返して、制度の閾値が自律的に満たされるまで反復する。

# 機械学習アルゴリズムの大別について
機械学習アルゴリズムは、大きく3つに大別することが可能である。
　・教師有り学習
　・教師無し学習
　・強化学習
 の3つである。

## 教師有り学習
教師有り学習は、**回帰**、**分類**に分けることが可能である。
　**回帰**は、従属変数と独立変数の関係(XとYの関係)を理解するために使用されます。これは、特定のビジネスの売上収益などを予測するのによく使用されます。線形回帰、ロジスティック回帰、および多項式回帰は一般的な回帰アルゴリズムである。

　**分類**は、確認対象のデータを特定のカテゴリーに分類するのにつかわれるアルゴリズムである。

### 教師有り学習で使用されるアルゴリズム ###
教師有りで使用されるアルゴリズムについて、どのようなものがあるかを見ていこう。
 -  AdaBoostまたは勾配ブースティング
 -  決定木
 -  人工ニューラル・ネットワーク (別名 : ニューラルネットワーク)
 -  ロジスティック回帰
 -  ランダムフォレスト
 -  線形回帰
 -  サポートベクターマシン


## 教師無し学習
教師無し学習は、ラベルのないデータに対して関連付けを見つけ出してパターンを見つけ出すのに役に立つ。教師無し学習のアルゴリズムとしては、
 - 次元削除 (主成分分析)
 - クラスタリング
 - k平均法クラスタリング
 
 などがある。

 ## 強化学習
人間が学習するのと同じように、罰則と報酬により訓練する。この罰則と報酬は、エージェントにより制定されて、追跡が実施される。
この罰則と報酬によるスコアダウン、スコアアップの確率を最適化しながら楽手をしていく。
M5AtomS3で黒電話の受話器を上げたときの音を出してみた

# はじめに
[M5AtomS3で黒電話のダイヤルを検知させてみた](https://qiita.com/krohigewagma/items/fc8df2da3dd13550df31) でダイヤルを検出できたので、どうせなら受話器を上げたときに聞こえる音も出したいよねって思って、試行錯誤(?)してできた。


# やったこと

まずはPWMを追加して、G2で音が出るかを確認したところ、大音量で音が出ましたｗ
で、G1で入力と出力！と思ってやったり、G1とG2に黒電話から出てくる同じ線をつなげたりしたけどうまくいかず。
で、G1はそのままで、G2とグランドにもう一つの線をつなげたところ、いい感じに音が聞こえるようになりました。
これが正しいのかどうかわかりませんが・・・(詳しい方のご意見聞きたい)

![P_20240908_164334.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/630f3edc-f4d0-9a7b-7608-1585b6eafe85.jpeg)


# コード

こんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/1b75d4b3-cc82-9a00-d3dc-7ba5186ac9f5.png)

受話器を上げている(statee = STATE_ACTIVE)の時に。PWMで400Hzを書き込んでいます。
これ、PWMで書き込めば音声を受話器で聞けるってことか。
さらに言えばPWMで読み込めば音声入力もできるのだろうか・・・？
入力はどう試すか方法を考えないと・・・
あと、Bluetooth経由で飛ばせるんだろうか・・・？
ブロックエディタでできるんだろうか・・・？
GraphQLのメリット・デメリット

## GraphQLとは
graphQLの概要については[こちら](https://www.redhat.com/ja/topics/api/what-is-graphql)より引用
>GraphQL (グラフキューエル、グラフQL) とは、API (アプリケーション・プログラミング・インタフェース向けのクエリ言語とサーバーサイドのランタイムの両方を指します。GraphQL は、クライアントがリクエストしたデータのみを返すことを優先します。
>
>GraphQL は、API の速度、柔軟性、開発者にとっての使いやすさを向上させるために設計されました。GraphiQL と呼ばれる統合開発環境 (IDE) にデプロイすることもできます。GraphQL は REST の代わりに、データを複数のデータソースから取得するリクエストを 1 つの API 呼び出しで構成できます。
>
>さらに、GraphQL によって、既存のクエリに影響を与えずに、フィールドを追加したり、その使用を停止したりできるため、API の柔軟な保守が可能です。開発者は API を任意の方法で構築することができ、構築された API は GraphQL の仕様に基づいて、クライアントに対して予測可能な仕方で動作します。

## GraphQLのメリット
1. 少ないリクエストで複数のリソースにアクセスできる
REST APIは情報にアクセスするエンドポイントが多くなりがちだが、その問題を回避できる。
また、複数の情報にアクセスするために複数のリクエストを送る必要がなく、一度にまとめて取得することができる。

1. 必要なデータのみ取得できる
REST APIでは返却されたデータが必要なデータより少なかったり（アンダーフェッチ）多かったり（オーバーフェッチ）する。GraphQLではクライアントが要求した必要なデータのみを取得することができる。

1. 強い型付けのスキーマである
スキーマに型を指定することで、フロントエンドとバックエンドの型の食い違いを防ぐことができる

## GraphQLのデメリット
1. 学習コストの高さ
GraphQLは2015年に登場したものであるため、情報が少なく習得するまでに時間がかかる。

2. RESTよりもキャッシュが複雑になりやすい
RRST APIはURLベースでキャッシュを生成するため、比較的容易に扱うことができる。GraphQLのキャッシュはURLを生成せずレスポンス内容も異なるため、複雑になる。

# 参照
https://udemy.benesse.co.jp/development/system/graphql.html

https://kinsta.com/jp/blog/graphql-vs-rest/

https://www.redhat.com/ja/topics/api/what-is-graphql
期間リストの重複期間、空白期間を確認する方法【Python】

## 説明

1. 開始日で `date_list` をソートします。
2. 現在の終了日と次の開始日を取得し、以下の条件でチェックを行います。
   - 重複期間（次の開始日が終了日よりも早い）
   - 空白期間（終了日の翌日が次の開始日でない）

```python
from datetime import datetime

# 日付リスト
date_list = [
  {'start_date': '2024/04/01', 'end_date': '2024/04/30'},
  {'start_date': '2024/05/01', 'end_date': '2024/05/31'},
  {'start_date': '2024/06/01', 'end_date': '2024/06/30'},
  {'start_date': '2024/07/01', 'end_date': '2024/07/31'},
  {'start_date': '2024/07/01', 'end_date': '2024/07/31'},
]

# 文字列を日付に変換
def parse_date(date_str):
    return datetime.strptime(date_str, '%Y/%m/%d')

# 日付リストの期間チェック
def check_date_range(date_list):

    # 開始日でソート
    sort_list = sorted(date_list, key=lambda item: parse_date(item['start_date']))

    for i in range(len(sort_list) - 1):
        end_date = parse_date(sort_list[i]['end_date'])
        next_start_date = parse_date(sort_list[i + 1]['start_date'])
        
        # 重複期間（次の開始日が終了日よりも早い）
        if next_start_date <= end_date:
            return '重複期間あり'
        
        # 空白期間（終了日の翌日が次の開始日でない）
        if (next_start_date - end_date).days > 1:
            return '空白期間あり'

# 結果を確認
result = check_date_range(date_list)

print(result) # 重複期間あり
```
CDKを使ってLambdaFunctionとLayerを一気にデプロイする

# 前書き
個人開発や技術検証で、試行錯誤しながらとにかく手を動かしたいとき、デプロイをもっと簡単にしたいと考えています。
Lambdaのランタイムをイメージにする方法もありますが、スクリプトを作成せず、コマンド一発でイメージをビルドし直し、ECRにプッシュするなど、スムーズに処理できる方法がなかなか見つかりません。もし、良い方法があれば教えていただきたいです。

現状はFunctionとLayerを分ける形で対応していますが、これはあくまで妥協案です。とはいえ、一応使える状態にはなっています。

# 手順

 AWS CDK プロジェクトのセットアップ
```shell
mkdir my-lambda-project
cd my-lambda-project
cdk init app --language=typescript
```

`aws-lambda` と `aws-lambda-python-alpha` ライブラリをインストールします。

```
npm install aws-cdk-lib @aws-cdk/aws-lambda-python-alpha
```

ディレクトリとファイルの抜粋は下記の通り
```
my-lambda-project/
├── bin/
├── lib/
|   ├── my-lambda-project-stack.ts # CDN stackの Typescript コード
│   ├── lambda/
│   │   ├── index.py        # Lambda 関数の Python コード
│   ├── lambda-layer/
│   │   ├── requirements.txt  # Lambda レイヤの Python コード
├── node_modules/
├── cdk.json
├── package.json
└── tsconfig.json
```
CDKのstackの定義

```typescript: my-lambda-project-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambda_python from '@aws-cdk/aws-lambda-python-alpha';
import * as path from 'path';

export class MyLambdaProjectStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const layer = new lambda_python.PythonLayerVersion(this, "MyLayer", {
      entry: path.join(__dirname, 'lambda-layer'),
      compatibleRuntimes: [lambda.Runtime.PYTHON_3_9],
    });
    const myFunction = new lambda_python.PythonFunction(this, 'MyFunction', {
      entry: path.join(__dirname, 'lambda'),
      runtime: lambda.Runtime.PYTHON_3_9,
      layers: [layer],
    });
  }
}

```

`lambda-layer/requirements.txt`

```text:requirements.txt
requests==2.27.1
beautifulsoup4==4.12.3
```

```python:index.py
import json
import requests
from bs4 import BeautifulSoup

def handler(event, context):
    url = "https://aws.amazon.com/jp/blogs/aws/"

    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    articles = soup.select("article.blog-post")[:1]

    result = []
    for article in articles:
        title = article.select_one("h2.blog-post-title").text.strip()
        link = article.select_one("h2.blog-post-title a")["href"]
        date = article.select_one("footer.blog-post-meta").text.strip()

        result .append({"title": title, "link": link, "date": date})

    contents = json.dumps(result, ensure_ascii=False)

    response_body = {"application/json": {"body": contents}}
    action_response = {
        "actionGroup": event.get("actionGroup", "default_action_group"),
        "apiPath": event.get("apiPath", "/default_path"),
        "httpMethod": event.get("httpMethod", "GET"),
        "httpStatusCode": 200,
        "responseBody": response_body,
    }
    api_response = {"messageVersion": "1.0", "response": action_response}

    return api_response
```

デプロイ

```
npx cdk deploy
```
【エラー解決】No Next.js version could be detected in your project. Make sure `"next"` is installed in "dependencies" or "devDependencies"

# はじめに
vercelにNext.jsのアプリをデプロイしようとしたところ、以下のエラーがvercel画面上で表示された。

```
No Next.js version could be detected in your project. Make sure `"next"` is installed in "dependencies" or "devDependencies"
```
Next.jsのversionが見つかりませんと言われているようです。

# やったこと
まずNext.jsのバージョンを確認してみました。
package.jsonでは以下のようになっています。
```
  "dependencies": {
    "next": "latest",
  },

```

latestとなっていてバージョンを明記した方がいいかと思い、以下のように変更しました。
```
  "dependencies": {
    "next": "14.2.0",
  },

```

デプロイをもう一度試したところ同じエラーが表示されてしまいます。

# 解決法
インターネット上で調べてみるとどうやらデプロイ時にルートディレクトリをvercel側が確認しにいく時に、入れ子構造になっているとうまくソースを見つけることができないようです。

どういうことがというと、my-appというフォルダを作ったとします。
そのディレクトリ内でNext.jsをインストールするとmy-appの配下にさらにmy-appというプロジェクトができる構造になります。ここでは便宜上my-app2と呼びます。
そしてmy-app2の中にappフォルダなど実際のソースが格納されています。

このプロジェクトの構造は以下のようになっています。
```
my-app > my-app2 > app, package.json etc...
```
この構造になっているとvercelはmy-appの部分をルートディレクトリとしてソースを確認しますが、ソースが実際に格納されているのはmy-app2になるので、「Next.jsのバージョンが確認できません」という今回のエラーが発生していました。

解決法としては、my-app2に格納されているものを全てmy-app配下に配置しなおすことでエラー解消できました。

プロジェクトの構造は以下のようになります。
```
my-app > app, package.json etc...
```

# おわりに
はじめてvercelを使用してるのでエラーが出てしまいますが、同じように初めてvercelを使う人の参考になれば幸いです！

 # 参考

https://zenn.dev/kingdom0927/scraps/d7ed137c012ead


https://stackoverflow.com/questions/74297132/no-next-js-version-could-be-detected-in-your-project-make-sure-next-is-inst
企業のテックブログを好きになった件

# はじめに

エンジニアのみなさま、日々の学習本当にお疲れ様です！
また本記事まで足を運んでいただき本当に感謝です。
約3分程度で読めるので最後まで読んでもらえると幸いです。

- - - 

直近の案件でプロジェクトマネージャーやチームリーダーなど、プロジェクトを管理するお仕事をさせていただく機会が増えております。そんな中、顧客と会話する機会も増えてきており、どんな質問に対しても回答できる様に自分の知見を広げたいと思ったのがテックブログを読み始めたきっかけでした。


# なぜテックブログを好きになったのか

『脱：井の中の蛙』が一番大きな要因かなと考えます。
どうしても今の仕事の範疇で学習や考えを持つことが多く、調べる内容に対しても個人の記事を見る機会がほとんどでした。一方でテックブログにはそれぞれ会社の色があり、同じ事象に対しても考えや取り組みが全く違うことに気づきました。


さまざまな考え方に触れることで、顧客への回答のバリエーションも増えますし、回答する中でも「弊社としてはAの提案をします」と伝えるより「⚪︎⚪︎株式会社ではAのような考え方を持ってますが、弊社としてはBの理由で提案をします」とすることで、顧客にとってはより『信ぴょう性』のある判断材料となり、満足度の高い提案になるかなと考えます。


次に、自分の知見の無さを思い知ることができます笑
日々エンジニアとしての学習は続けていますが、テックブログを読んでいると知らない言葉や仕組みがたくさん出てきます。そのような状況になるたび

「なんやこの言葉！」「全然説明できへん！」「覚えること多すぎ...」

となります。辛いです笑
ただ学習を継続するきっかけにはなります。技術は日進月歩のため終わりが無い = ずっと学習になりそうですが、顧客から聞かれたときに「持ち帰ります」を極力少なくするための対策としてテックブログを読むのは良い手段になりそうです。

テックブログは社内のエンジニアに対して共有や意見交換をする機会を増やす事も出来ました。弊社ではSlackを使っており『記事チャンネル』なるものがあります。気になる記事や技術があればエンジニア間で連携する文化があります。今まで活用する機会が少なかったのですが、テックブログを読み始めてからは平日の始業前に毎日共有をする様にしてます。現時点では共有がほとんどになっていますが、共有に対するスタンプの反応や返信がくるようになって個人的には嬉しい限りです。将来的にはテックブログを通してエンジニア間で意見を出し合い、弊社としてのベストプラクティス集みたいなものが構築できれば良いかなと勝手に考えてます。テックブログはエンジニアレベルの底上げにも寄与する力も持ってると感じてます。

総じて、『個人』にも『他者』にもメリットが多いため、テックブログが好きになりました。もし違う理由でテックブログを読まれている方がいらっしゃればご意見聞いてみたいです！

# 個人的にオススメのテックブログ

ここからはテックブログの紹介になります。
テックブログを読む基準としては『更新頻度が多いもの』としてます。
以下の内容はその基準を満たしているため、常に最新情報に触れることが出来て個人的にはオススメです。

**▼web系開発関連はこちら**

https://techblog.zozo.com/

https://tech.smarthr.jp/

https://note.shiftinc.jp/

https://tech-blog.rakus.co.jp/

https://techracho.bpsinc.jp/category/ruby-rails-related

https://techblog.lycorp.co.jp/ja

**▼デザイン関連はこちら**

https://goodpatch.com/blog

**▼インフラ関連はこちら**

https://aws.amazon.com/jp/blogs/news/

# 上記テックブログ以外も見てみたい人向け

1年以内に更新のあった技術ブログがこちらでまとまっております。
興味のある方はこちらも確認してみてくださいね。

https://hatena.blog/dev/companies

# おまけ

弊社のご紹介もさせてください！

### 「日本で一番エンジニアが成長できる会社を創る」

https://prum.jp/

### エンジニアリングの募集

https://www.wantedly.com/projects/1808638

### PM・Webディレクションの募集

https://www.wantedly.com/projects/1355235

### セールス・事業開発の募集

https://www.wantedly.com/projects/1792065

### コーポレート系の募集

https://www.wantedly.com/projects/1752874

### コンサルティングの募集

https://www.wantedly.com/projects/1794481

弊社メンバーは日々学習した内容をアウトプットしております！
少しでもご興味を持たれた方は求人を見てみてください！
ご応募もお待ちしております！

### 最後までご覧いただき、ありがとうございました！
ネットワーク知識入門2

# 概要
ネットワークについて、知識不足を感じたため、学習をし始めました。
業務はWeb系のコーディングがほとんどですが、原点を理解しないと知識が深まらないため、さらに学んでいきます。

[ネットワーク知識入門1](https://qiita.com/saburo555/items/e14c2524a12d9b8d061f)
[ネットワーク知識入門3](https://qiita.com/saburo555/items/7a0972ed39a06c2d6175)

# データリンク層
## 復習
データリンク層とはノード間でのやりとりに関する約束事のまとまり。

### イーサネット
一言で言うとLANのルールを決めている規格。（WANにも広がりつつある）

**【規格の種類】**
DIXイーサネット、IEEE ８０２.3（アイトリプルイーと呼び、イーサネットはこっちが大半）というものがある。

IEEEでは、データリンク層を、LLC副層とMAC副層に分けている。
物理層に依存するようなルールを決めているのが、MAC副層。LLC副層は、物理層に依存しない。

**【命名規則】**
（例）「1000」「BASE」「　- LX」
通信速度、伝送方式、ケーブルの種類。

**【CSMA/CD】**
>ネットワーク制御方式の一種。
●各端末装置が送信を行うとき、送信のための通信路が空いているかどうかを確認してから送る方式。
●空いていないときそのまま送信すると、データとデータがぶつかってしまうので、定められた乱数によって求められた時間だけ待った後に再度送信を試みる。
●この方式はネットワークの制御のための特別な装置が必要ないため、システムが比較的安価にできる。 コンテンション方式ともいう。
●Ethernetで採用されている。

参照：[CSMA/CD方式](https://fa-dic.mitsubishielectric.co.jp/faq/show/15472)

全二重通信では、コリジョンが起こらないので、上記は必要なく、現状はほぼ全二重通信。
全二重通信はハブでは使えない。

**【フレーム】**
フレームは、DIX仕様とIEEE802．3仕様の2種類がある。
インターネットでは、DIX仕様が一般的となっている。

　イーサネットでは、DIX仕様では、ヘッダにMACアドレスや上位層のプロトコルを識別する番号のタイプが入っていおり、トレーラには、エラーチェック用の値（FCS　フレーム チェック シーケンス）が入っている。
 IEEE仕様では、タイプが長さに変わる。

 ### MACアドレス
 端末ごとに一意のアドレスを持っている。

 上位六桁で、製造会社を表す。OUI（オーガナショナリー　ユニーク　アイデンティファー）という。
【ESLint】React' must be in scope when using JSXの解決方法

# はじめに
React開発でESLintを設定している際に、「'React' must be in scope when using JSX」というエラーに遭遇したので、解決までの過程をまとめます。

```bash
'React' must be in scope when using JSX  react/react-in-jsx-scope
```

修正前のファイルがこちらです。
```react
export default [
  { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"] },
  { languageOptions: { globals: globals.browser },
    pluginJs.configs.recommended,
    ...tseslint.configs.recommended,
    pluginReactConfig,
  },
];
```

:::note warn
警告
現在PrettierとESLintの設定を勉強している途中ですので誤まった解決策である場合があると思います。その場合はぜひご指摘いただけると幸いです。（2024年9月現在）
:::



# 原因
このエラーは、ESLintがJSXを使用する際に、Reactがスコープ内に存在することを要求しているために発生します。一般的には、App.tsxなどのコンポーネントファイルの先頭にimport React from 'react';と記述することで解決しますが、今回のケースでは、ESLintの設定に問題がありました。

```App.tsx
import React from 'react';
```

# 解決策
## エラーを無視する設定の追加
今回はESLint側でこちらのエラーを無視する設定を追加します。

```react
rules: {
  "react/react-in-jsx-scope": "off",
  "react/jsx-uses-react": "off",
},
```
この設定を追加することで、ESLintは上記のエラーを無視するようになります。

## 設定の順序の変更:
ESLintの設定の順序によって、ルールが適用される順番が変わり、意図しない結果になることがあります。今回のケースでは、pluginReactConfigの設定を他の設定よりも前に移動することで、エラーが解消されました。

```react
export default [
  { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"] },
  //移動
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  pluginReactConfig,
  //
  { languageOptions: { globals: globals.browser },
    //追加
    rules: {
      "react/react-in-jsx-scope": "off",
      "react/jsx-uses-react": "off",
    },
    //
  },
];

```

# 終わりに
ESLintについてまだまだわからないことがたくさんあるので間違いがあれば、ぜひご指摘いただけると幸いです。

# 参考

https://zenn.dev/ryuu/scraps/583dad79532879
【ESLint】A config object is using the "extends" key, which is not supported in flat config system.  Instead of "extends", you can include config objects that you'd like to extend from directly in the flat config array.の解決方法

# はじめに
React開発でESLintを設定している際に、遭遇したESLint下記エラーの解決方法になります。

```bash
A config object is using the "extends" key, which is not supported in flat config system.

Instead of "extends", you can include config objects that you'd like to extend from directly in the flat config array.
```

:::note warn
警告
現在ESLintの設定を勉強している途中ですので誤まった解決策である場合があると思います。その場合はぜひご指摘いただけると幸いです。（2024年9月現在）
:::



# 原因
ESLintのバージョンが変わりflat configの書き方ではextendsは使用できなくなったようです。

```react
export default [
  {
    languageOptions: {
      globals: globals.browser,
    },
    settings: {
      react: {
        version: "detect",
      },
    },
    extends: ["eslint:recommended", "plugin:react/recommended", "prettier"],//古い書き方
  },
];
```

# 解決策
以下のように直接インポートするような記述に変更します。

```react
export default [
  {
    languageOptions: {
      globals: globals.browser,
    },
    settings: {
      react: {
        version: "detect",
      },
    },
  },

  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  pluginReactConfig,
  prettier,
];
```

# 終わりに
ESLintについてまだまだわからないことがたくさんあるので間違いがあればぜひご指摘お願いいたします。
【hono】Hello, worldした。

はじめまして。新卒1年目エンジニアのいちたです。

初投稿はhonoで「hello, world」を表示するところをまとめてみたいと思います。
ほぼ、公式ドキュメントでできる内容にはなってしまいますが、ご容赦ください。


# hono:fire:とは
honoは、JavaScriptのWebフレームワークです。**めっちゃ軽量で高速**に動くそうです。実際、Nuxtに比べて、プロジェクト作成や起動が高速でした。すごい...
（Webフレームワーク自体の開発にも興味が...）

さまざまなJavaScript Runtimeに対応しているのもすごい...

# 実際に動かす
「さまざまなJavaScript Runtimeに対応している」とは言いましたが、今回はNode.jsを使います。また、パッケージマネージャは"pnpm"です。
## プロジェクト作成
以下のpnpmコマンドでプロジェクトを作成します。
```sh
pnpm create hono@latest
```

こちらを実行するとアプリケーション名、JavaScript Runtimeを選択できます。
選択後、すぐに作成が完了します。

### 作成後
作成後のプロジェクトのディレクトリ構造はこんな感じです。
初期段階ではindex.tsがルータとコントローラの役割を持っている感じです。
```
.
└── my-app
    ├── src
    │   └── index.ts
    ├── package.json
    └── README.md
```

## 起動
以下のコマンドを用いると開発者モードで起動できます。
```sh
pnpm dev
```
起動結果はこんな感じ。（これくらいだと、2秒です。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880849/1d10ace7-aa34-c18c-b0aa-eab96d1f5edb.png)


# まとめ
今回はhonoフレームワークを使って、「Hello, World!」を無事に表示できました:clap:
## honoとは
- JavaScriptのWebフレームワークの一つ
- 超高速・超軽量
- Node.js以外のJavaScript Runtimeで動く
# 参考
- [Hono公式ドキュメント](https://hono.dev/)
- [Hono GitHubリポジトリ](https://github.com/honojs/hono)
- [Hono[炎]っていうイケてる名前のフレームワークを作っている](https://zenn.dev/yusukebe/articles/0c7fed0949e6f7#fastly-compute%40edge)
↑開発者さんの記事です。分かりやすくまとまっていてすごい...
あいさつ＋ブログでやりたいことの備忘録を書く


## 自己紹介と自身の現状
はじめまして。
社会人２年目で某派遣社員のITエンジニアとして働いている者です。

…ITエンジニアと名乗りましたが、今の業務内容としてはどちらかというと機構系や事務的な業務が多いです。
こんな境遇にいるためプログラミングや設計などの技術的な経験が少なく、ITエンジニアとしての市場価値は非常に低くなってしまっていると危機感を感じています。

自己学習として色々始めているのはいいもののアウトプットの機会がほとんどなく、
知識の定着まで進んでいないというのが現状であるため、これはまずい、何とかしないと、と何かのアクションを考えたところ、
自身が学んだことをブログとして残すことで知識のアウトプットの機会になると同時に言語化の力がつくのではないかと考えました。

## 今後のブログの投稿目的、内容

今後投稿しようと考えている内容は大きく分けて下記の2つの内容で考えています。
(内容については方針転換する可能性もあります)

### ～資格勉強で得た知識のアウトプット～
#### 〇G検定、データサイエンティスト検定
デジタルリテラシー競技会が推奨する3つの資格のうちITパスポートは取得しており、DXを推進する基本的な知識の保有を示せる『DX推進パスポート』を取得するために残り2つの資格も取得したいと考えています。

#### 〇基本情報技術者試験
ITパスポートは持っているため、次のステップとして基本情報技術者試験を目指したいです。
それなりにウェイトが重いと思うので直近で学習を進めているG検定が受かってから学習を進めたいと考えています。


### ～プログラミング言語学習内容のアウトプット～
#### 〇Python
##### ・外部ライブラリの使い方や紹介
Pythonを使う中で「こういうことできないかな」と考えて調べても具体的な使用方法などは簡単には書かれていないことが多いと思ったので、それを自分で見返せるようにという意味も込めて使用方法をまとめたいなと考えています。

#### 〇HTML/CSS
##### ・コピペで使えるCSSテンプレートの作成
これは単純に自分の興味で、CSSでこういうことができるよという内容がSNSで流れてきて、自分でも作ってみたいなというのが背景です。（おそらく投稿頻度は上記２つに比べて低いと思います。）

## 最後に
私はブログを書くことが初めてで、色々手探りで投稿を進めますので温かい目で見守っていただけるとうれしいです。
今後の投稿のモチベーションに直結するので、もし応援いただける方はいいねをいただけますと幸いです。

最後まで読んでいただきありがとうございました。
Logicoolのコントローラー F310のRB（R1）が反応しなくなったので直してみた

# 背景
嫁と「it takes two」をやっていたら、RBがカチカチ鳴らなくなり反応しなくなったので直した際の記録
これをすることでとどめを刺すことにもなりえるので、自己責任でやって臭い。
# 作業内容
## 分解と観察
ボタン面を下にしないといろいろ落ちてくるので注意。
※多少汚いので注意して下さ於。
![2024-09-03_15-47-44_940.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/086ddb67-3cf8-63d1-e316-a66edc68ba92.jpeg)
## LBとRBを見比べてみる
### LB
正常に動いているLBはこんな感じ
![2024-09-03_15-47-50_354.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/aad3ee6d-ec1a-fa29-9776-8f414f931784.jpeg)
### RB
異常のあるRBはボタンパーツが後退してしまっている
#### 上から見た図
![2024-09-03_15-47-53_293.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/37993cb8-1d52-0565-451c-aab7cbab5ab2.jpeg)
#### 正面から見た図
赤で囲ったところのパーツがボタンを固定しているのだが、見た通りなくなってしまっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/5f8f42b6-262e-17af-52b5-adab7158dba3.png)
## 原因
ボタンパーツが後退してしまい。物理的に押すことができなくなっていた。
## 修理というか使えるようにする。
熱してプラスチックをつけたり、接着剤はボタンが改悪思想だったので固定している金属プレートをまげて後ろから支える方針で作業してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193969/1d16ba37-4fcb-84ef-d7cf-e3741b90a6f9.png)
見た目は汚いが、このパーツは背面に端子は出ていないので手っ取り早く治すことができた。
動作も問題なく使えているのでLBが壊れた際もこの方法で対応する予定である。
Step FunctionsでJSONPathを使うと楽になった話

## はじめに
愚直にChoieステートでデータのフィルタリングを行なっていたもの、JSONPathに変えたらシンプルで使いやすくなった話

## 結論
MapステートとChoiceステートを使ったフィルタリングがJSONPathを使えば不要になった。

## どういうことか
下記のようなデータを受け取り、dataが100以上の値のtaskのみ後続処理させたい場合を例とする。
```JSON
{
  "tasks": [
    {
      "id": "task1",
      "data": 100
    },
    {
      "id": "task2",
      "data": 99
    },
    {
      "id": "task3",
      "data": 1000
    }
  ]
}
```

### MapとChoiceを使うパターン
今までの私。
下記のように`tasks`をMapで分散処理させ、それぞれに対してChoiceで判断の処理をしていた。
```JSON
{
  "Comment": "A state machine that processes tasks",
  "StartAt": "ParallelProcessing",
  "States": {
    "ParallelProcessing": {
      "Type": "Map",
      "ItemsPath": "$.tasks",
      "Iterator": {
        "StartAt": "CheckData",
        "States": {
          "CheckData": {
            "Type": "Choice",
            "Choices": [
              {
                "Variable": "$.data",
                "NumericGreaterThanEquals": 100,
                "Next": "Process"
              },
              {
                "Variable": "$.data",
                "NumericLessThanEquals": 99,
                "Next": "Pass"
              }
            ]
          },
          "Process": {
            "Type": "Pass",
            "End": true
          },
          "Pass": {
            "Type": "Pass",
            "End": true
          }
        }
      },
      "ResultPath": "$.results",
      "End": true
    }
  }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177290/57a3eea9-9637-a5c9-88b9-ced2e7a27a11.png)

この場合、`data`が99以下の場合の逃げ道を作ってあげることが必要だったり(次のステートが無いと怒られるため)、なによりMap実行それぞれの結果が見づらい。


### JSONPathを使うパターン
JSONPathを使ったフィルタリングを使用すると、下記のように１ステートで記載することができる。
```JSON
{
  "Comment": "using JSONPath",
  "StartAt": "SelectAndProcess",
  "States": {
    "SelectAndProcess": {
      "Type": "Pass",
      "Parameters": {
        "SuccessfulResult.$": "$.tasks[?(@.data >= 100)]"
      },
      "End": true
    }
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177290/cb783e89-5930-3000-833f-36630484c76f.png)


## 最後に
おまじない的に、`$`を付ければ引数の値をステートの入力に使える。くらいにしかおもっていなかったのが恥ずかしい。
実務経験1年ちょっとで転職ドラフト経由で転職しました

こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています
https://job-draft.jp/articles/251

# 初めに
転職ドラフト経由で受託開発企業から自社開発企業に転職して1か月が経過したので、
転職前と転職後の生活の変化や思いを書かせていただきます。
ドラフトには4月回に参加しました。

## 自己紹介
はじめに私のプロフィールをお伝えします。概要は以下のような感じです。

- 20代後半
- webエンジニア
- 実務経験は1年4か月（エンジニアになる前は職業訓練校でフロントエンドを学んでいました）
- 前職はLaravelやTypescriptを書くことが多かったです

## 転職ドラフトに登録したきっかけ
- もともと転職前の企業の入社時に、1年ほど経ったら転職活動を始めようと考えていました
（中途未経験の入社＆地方採用ということもあり、給与面でかなり足元見られていました、、、）
- 退職者が増えるなど社内的な環境が悪くなってきたことが後押しとなり、最初に考えていた通り入社後1年経過したタイミングで転職活動を本格的にスタートさせました

### 転職活動のはじめ
- 初めはGeeklyやリクルートダイレクトスカウティングを利用していました
Geeklyに関しては志望度が高くない企業を大量に半強制的に受けなければならず、時間効率が悪いため利用をやめました。
- リクルートダイレクトスカウティングはスカウトが来ない（転職活動時期が4月だったこともあり）ためこちらも利用をやめました

### 転職ドラフトを知る
- 次はどのサービスを利用しようと悩んでいたところ、Qiitaの転職ドラフトの体験談を見て転職ドラフトを知ることになりました
- 現職の年収を記載する必要がないという部分を画期的で、転職ドラフトで転職活動を進めていくことにしました
- Qiitaの記事でレジュメは転職ドラフトがOKを出すまで添削されて再提出が求められると見たため、身構えていましたが他の方の書き方等を参考に勧めていたこともあり、差し戻し無しで登録できました
    - 指名期間も通してレジュメの修正は行っていました

## どんな指名を受けてどのように受け止めたか
- 1回のみドラフトに参加して、最終的に指名は3社からいただきました
- どれも現職の年収の2倍以上の額を提示していただき、大変うれしく思ったのを覚えています
- 指名は基本的に最終日に集中しました

- 指名をもらったどの企業も初めて聞く企業でしたが、どの会社も魅力的なサービスを持っていて、知らない企業を知れる意味でも転職ドラフトは大変魅力的なサービスだと思います
- 企業側が指名した理由を詳細に記載してくれるので、自分の経歴のどういう部分に魅力があるのかを客観的に判断してもらえるのも非常に為になりました

## 面談や面接
- どの企業もカジュアル面談→一次面接というフローでした
- カジュアル面接は基本的に会社説明という感じでこちら側の準備する必要があるのは事前に共有してもらった資料に目を通すくらいのものでした
- 面接では技術質問メインで進行しました
- 自分の経験が浅いこともあり、質問された内容に的確に答えられない点が多くまだまだ技術不足であることを知れたのも良かったです

## 転職後に感じていること
- 前職のウォーターフォールからアジャイルのスクラムでの開発になったことで更に仕事は楽しくなりました
- コードを書くなど開発に関わっている時間が圧倒的に増えたなという印象です
- 前職では名ばかりだったフレックスタイム制やリモート勤務もしっかり整備されていて働きやすさの面でも満足感を感じています
- 自分の上司も非エンジニアからCTOに変わったため、悩み事の相談がしやすくなりました
- 前職は技術力に課題があったことに気付いた
- 転職ドラフトに参加している企業全体で見て、エンジニア全体の働きやすさを追求しているように思います

## 転職ドラフトへの改善要望
- 改善要望というほどのものではないですが、指名が指名期間の最終日に集中するため、特に在職中で多く指名を受けた方にとってはスケジューリングが非常に大変になるなと思いました

## これから参加する方へのメッセージ
- 転職ドラフトは特に若年層の方が大幅に年収を上げる機会を提供してくれるとても良いサービスだと思います
- 転職ドラフト内では転職のレジュメもかなり詳細に書くことが推奨されていますし、サービスに登録する段階で添削されてくれることも求職者にとっては非常にありがたかったです
- サービス登録してから内定に至るまでにはドラフト回のスケジュールの都合があるため、時間がかかりますがそれに見合う体験価値はあるのかなと思います
- また、転職ドラフトでの転職に成功した場合は運営からAmazonカード5万円などのプレゼントがもらえることもかなり嬉しいポイントです
    - 私の場合はAppleギフトカード10万円分を選びました

転職ドラフトで転職をお考えの方は是非私の友人紹介コード「**OLAT**」を利用してください！
以下のプレゼントからお好きなものが１つもらえます！
- お好きなO’REILLY JAPANの本1冊（税込5500円以内）
- ACTUSギフトカタログ Straw（ストロー）
- Amazonギフト券 3000円分（Eメールタイプ）
ネットワーク知識入門1

# 概要
ネットワークについて、知識不足を感じたため、学習をし始めました。
Web系のコーディングがほとんどですが、原点を理解しないと知識が深まらないため、学んでいきます。

[ネットワーク知識入門2](https://qiita.com/saburo555/items/b7fee560e091e7d8c009)
[ネットワーク知識入門3](https://qiita.com/saburo555/items/7a0972ed39a06c2d6175)

# ネットワーク
### 種類
ネットワークの種類は以下の2種類ある。
- LAN：狭い（LOCAL）範囲（建物内、敷地内など）。自分で用意。
- WAN：離れた(WIDE)LANをつなげる。広い範囲。電気事業者が提供している。

### インターネット
プロバイダを介して、構築されるネットワーク。
プロバイダの正式名は、インターネット　サービス　プロバイダー（ISP）である。

**【イントラネット】**
社内のネットワークをイントラネットという。
限定されたアプリなどを共有することができる。
イントラネット同士を繋いだものをエクストラネットという。

:::note info
VPNとの違いは、イントラネットは企業内部に限定された閉じたネットワークであるのに対し、VPNは公衆ネットワークを利用して離れた場所からでも安全に接続できる仮想的な専用ネットワーク。
:::

### ネットワークユーザーアプリケーションの種類
ネットワークユーザーアプリケーションの種類は以下の3種類がある。
- リアルタイムアプリケーション：クライアント同士の通信
- インタラクティブアプリケーション：サーバーとクライアント間の通信
- バッチアプリケーション：自動で実行し、終了するもの（実行やタイマー実行）

### 機器の総称
**【ノード】**
パソコンやプリンタなどの機器のこと。
→ ノード同士の繋ぎ方をトポロジという。
[ネットワークトポロジーとは？スター型、バス型、リング型を図解](https://emb.macnica.co.jp/articles/7294/)

→ 通信の種類は以下の3つある。
- ユニキャスト：1つのノードから1つのノードへ
- ブロードキャスト：1つのノードから他のすべてのノードへ
- マルチキャスト：1つのノードからマルチキャストグループ（複数のノードが入っているグループ）へ

:::note info
スター型は、家とかで使っているWi-Fiの接続イメージ。
Wi-Fiから、PCやスマホに繋いでいる。各々の接続が消えれても、その機器のみ使えなくなるだけなのが利点。
:::

**【リンク】**
ケーブルや電話などのデータが通るところのこと。

# 情報のやり取り
### 通信速度
1秒間に何bit送れるかは、「bps(bit oer second)」という単位。
8ビットで1バイト。

### 通信障害
輻輳とは、データが混雑して、通信ができなくなること。

# プロトコル
## 種類
プロトコルの種類は、プロトコルスタック、ネットワークアーキテクチャ、プロトコルスイートがある。

# OSI（オープン　システム　インターコネクション）参照モデル
異なる機種の間でも通信ができる世界の標準プロトコルスタック（約束をまとめたもの）。

### 7つのレイヤ
OSI参照モデルには、以下の7つの階層がある。
- 物理層：ハードウェアや電気信号のルール（通信している経路）
- データリンク層：直接など隣接的に接続した機器との通信ルール（通信する）
- ネットワーク層：異なるネットワーク間の通信ルール（経路を決める）
- トランスポート層：データの送受信のルール（データの送信経路を探す）
- セッション層：アプリケーション間のルール（相手側のアプリを見つける）
- プレゼンテーション層：文字コードなどの表現形式ノール（エンコード・デコード）
- アプリケーション層：メールやSNSなどのアプリケーション固有のルール（メールを書く）

各レイヤを通る際にヘッダやトレーラという情報がつく。
また、相手側に送信される場合は、それらが外される。
そのデータ（データ+ヘッダ+トレーラ）の単位をPDU（プロトコル　データ　ユニット）という。
またどのレイヤのものかによって、呼称が変わる。
レイヤ4はセグメント、レイヤ3はパケット、レイヤ2はフレーム。

# ネットワーク機器（ハブ）
### 光ファイバーケーブル
ノイズを受けないので、長距離、高速にデータ通信ができる。
シングルモードファイバ、マルチモードファイバがある。マルチモードは短距離向け。安価。

### ツイストペアケーブル
LAN（カテゴリ3以上）で最も使用されている。100m伝送できる。
ケーブルには、シールドなしのUTPケーブルと、シールドありのSTPケーブルがある。

### ポート
MDIとMDI-Xがある。
PCやルータはMDIを使用し、ハブやスイッチは、MDI-Xを使う。

ポートが同じの場合は、クロスケーブルを使う、ポートが違う場合は、ストレートケーブルを使う。
package.jsonのライブラリのライセンスを取得する

Node.jsで使っているライブラリの一覧を取得してNext.jsのアプリのページとして表示する方法を見つけた。

https://www.npmjs.com/package/license-report


ライセンスチェックというと、だいたいlicense-checkerの情報が出てくるけど、
この、license-report はマークダウン形式で出力できるのでなかなか便利。

ただ、URLの文字列がおかしいのはどこで情報とってきているんだろう。

https://flaming.codes/ja/posts/next-js-npm-license-generator/


Powershellが入っている環境で下記コマンドを実行すると、URLの表示が修正できる。
```shell 
license-report --output=markdown --config license-report-config.json| % { $_ -replace 'git\+', '' -replace 'ssh://', '' -replace 'git://', 'https://' -replace 'git@', 'https://' } | Set-Content license.md
```

```license-report-config.json
{
  "fields": [
    "department",
    "relatedTo",
    "name",
    "licensePeriod",
    "material",
    "licenseType",
    "link",
    "comment",
    "installedVersion",
    "author"
  ]
}
```

本番環境で使っているものだけ出力するオプションもあり、使い勝手は良さそう。
それはそれとして、使っているライブラリのライセンスをもとに、自分のアプリがどのライセンスで公開できるのか、とか、どういう利用制限があるのかをパッと教えてくれるアプリないのかな。
【解説】外部チートの基本

# 前提
この記事は違法なチート行為を推奨するものではなく、あくまで技術的な知識を提供するものです。
実際に行った場合、ゲーム会社から訴訟される場合がありますので絶対に行わないようにしてください。
# 外部チートとは？
簡単に言うと、AimbotやESPなどの基本的なチートです。
皆さんが想像するような空中浮遊やホーミングなどは基本外部では実装できません。
これは外部チートがメモリを読んで書く、ということしか出来ないからです。
1部の中国開発者や台湾開発者は外部にもかかわらずホーミングをしたりしていましたが、ごく一部です。普通できません。

# 簡単な作り方
まずは何をしたいかにもよりますが、メモリを改竄する対象の特性を考えましょう。
アンチチートがカーネルモード(ring0ドライバー)を使用している高度なアンチチートの場合、カーネルドライバーを作成する必要があります。
Apex等のゲームはカーネルモードのアンチチートであるため、カーネルドライバーが必須です。
CS2はbattleyeアンチチートですが、なぜかあまり機能しないのでドライバーは必須ではありません。

# その1 オーバーレイの作成
オーバーレイは、チーター界隈では通称「メニュー」と呼ばれるビジュアル的に必要なもので、必須ではありません。

この時に重要なことは、オーバーレイには表の世界、裏の世界があることを理解することです。
表の世界、というのはオーバーレイを見ている自分側の世界です。
裏の世界、というのはそれらを処理する描画側の世界です。つまりはソース側の話ですね。
オーバーレイは基本的にビジュアル的に作成できません。(そういうフレームワークがない限り)
オーバーレイ作成に役立つのはImGuiです。
Dear ImGui(オリジナル)や、それを拡張するOS-ImGui、SDL-ImGuiなどがあります。自分の環境に合わせて使いましょう。

私がおすすめなのはOS-ImGuiです。

OS-ImGuiでは簡単に画像描画ができたり、簡単にセットアップができます。

オーバーレイのサンプルソースも後々公開するので購読して待って頂けると幸いです。

# その2 ドライバーの導入(任意)
ちょっと前に言った通り、アンチチートの強度によってドライバーが必須かどうかが変わります。
ドライバーに関してはあまり深く書きたくないので書きませんが、
Ioctlという方法(デバイスを作成してなんかしらする方法)は無署名で行うと検知確率が高い、ということと、
KeStackAttachProcess
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/ddi/ntifs/nf-ntifs-kestackattachprocess
は少しばかり検知確率が高い

ということを書いておきます。

ドライバーに必要なのはメモリの読み書き、ベースアドレスの取得 が最低でも必要です。
作るのにおすすめの関数はMmCopyなんたらかんたらっていう関数です。
ドライバーはフックをすることが大切で、それをしなければ検知される可能性もあります。
ドライバーマッピング(crt署名ファイルを使用せずに署名をする)にはkdmapperを使うことをおすすめします。ランダムな署名をして検知を防ぐことが出来ます。

# その3 メモリの読み書きを実装
Config.hppまたは.hを作成してオンオフを管理すると楽です。
例えば、名前空間Config内にchamsというbool型のものを宣言しておきます。初期値はfalseにしておきましょう。

Feature.hppまたは.hを作成して、その中に
```cpp
void feature(){
    while(true){
        if(Config::chams){
            //ここにメモリ処理
            write<int>(entity + 0x26c, 7);//架空。entityのオフセット + 0x26cのアドレスに7を書き込む様になってます
        }else if(!Config::chams){
            //ここにメモリ処理
            write<int>(entity + 0x26c, 2);//架空。entityのオフセット + 0x26cのアドレスに2を書き込む様になってます
        }
    }
}
```
こんな感じでvoidを作り、whileループさせます。
writeって関数はドライバーでメモリを書く関数です
もしConfig::chamsがおんONであればメモリを書くようにしています。オフならメモリを戻す(やりたいことによるけど)ようになってます。
このfeature関数はmain.cppでもなんでもいいのでスレッド実行するようにしてください。

オーバーレイ側ではImGui::Toggleなどでオン・オフできるようにするとオーバーレイでコントロールできます。

# 締め
こんな具合で外部チートが作成できます。
これは絶対チートが禁止されているゲームでやってはいけません。
知識程度に覚えておいてください。
UE5 TextBlockのテキストセンタリング

TextBlockで指定範囲内の上下左右センタリングについて

まずはTextBlockを置いてみます
(背景が寂しいのでImageを置いていますが実際は置かなくても大丈夫です)

500x300の範囲でセンタリングした文字を表示するのが目的です
デフォルトでは左上になってしまっていますね
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/9423d702-65ee-eb2d-9ca3-2b7acca4c538.jpeg)

横方向をセンタリングするように変更してみましょう
右の詳細から「Justification」をテキスト左揃えからテキスト中央揃えに変更します
これで横方向は指定範囲でセンタリングされるようになりました
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/a9f5da1f-e6ec-2536-90d3-524d3c5d4ebd.jpeg)

縦方向をセンタリングするためにはTextBlockだけですと難しいので、TextBlockをVerticalBoxを下に置くことで縦方向をセンタリングできるようにします

VerticalBoxを置いたことでTextBlockの位置情報が吹き飛んでしまっていますので、位置情報や範囲情報をVerticalBoxから入れ直してあげる必要があります
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/c320381a-f9be-d4d4-ad7d-eda99cff6472.jpeg)

VerticalBoxの範囲とTextBlockの範囲ズレがあるので、TextBlockからSizeを「自動」から「フィル」にして合わせます
そして縦方向のセンタリングをするためにVertical Alignmentを「垂直方向に上揃え」から「垂直方向に中央揃え」に変更します
これで左右上下にセンタリングができました
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/73f4a959-941f-775f-b78f-3712f104a0fe.jpeg)

複数行にテキストを入れてテキストの文字数を行ごとに変えてもセンタリングして表示されています
位置や範囲を変更するときはVerticalBoxの大きさを調整してください
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/61f3d6c2-08f2-9cca-b313-c63fba54e442.jpeg)
便利な翻訳と辞書機能アプリ(DicTran)をElectron+Reactで開発した

## 開発の背景
AI開発で英語の論文を読む時や、英語のニュースサイトで情報収集するときに[DeepL](https://www.deepl.com/ja/translator)や[Google翻訳](https://translate.google.com/)などの翻訳ツールをよく使用すると思います。ですがWebブラウザを行ったり来たりするのが面倒だと感じたことはありませんか？私はよく感じていて何かツールを探している、以下を見つけました。
[Mouse Dictionary](https://qiita.com/wtetsu/items/c43232c6c44918e977c9)
この機能は非常に便利な一方で、単語の登録や、文章の翻訳には対応できていないので、今回それらに対応するアプリを開発しました。

## インストール
:::note alert
Macユーザーの皆様
コードサイニングをしていないため、Macユーザーの方は以下のコマンドを実行しないと使用できません。（お金なくて、Appleのコードサイニングを使用できてません。。。）
```xattr -c /Applications/DicTran.app```
※アプリのパスは個人で調整お願いします!
:::

Dropboxに以下のファイルを格納していますので、こちらのファイルをダウンロードして開くとアプリをインストールできます。
https://www.dropbox.com/scl/fo/42c5ptts6y2rctanrfo1e/ACOK8vdw9czSjmXEzoIeqeY?rlkey=3jqehiqv3i5fmj3m52b6erst2&st=n8in3yqp&dl=0
- .exeファイル（Windowsユーザー）
- .dmgファイル（Macユーザー）

## 機能
- 辞書（現状英語のみ 2024.9.8）
- 翻訳
- 単語登録
- 単語読み上げ
※オフラインでは辞書機能のみ利用可能です。

[![Watch the video](https://img.youtube.com/vi/Q4tJM5eEgcY/default.jpg)](https://youtu.be/Q4tJM5eEgcY)

## 技術
フロントエンド: React + Electron
バックエンド: Python
「箱庭ドローンシミュレータ pythonAPI利用編」がCore i5 8th/8G、PS5コントローラで動いた！

下図は、PS5コントローラ(DualSense)を操作して荷物を掴んだあと！
![GW7XUH_a8AECR74.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089345/fbe646fd-1c11-a66c-b28b-2c376ef21085.jpeg)
<br>
参照資料 : [ubuntu22.04_install&operation_pythonAPI編.md](https://github.com/toppers/hakoniwa-px4sim/blob/main/docs/manual/ubuntu22.04_install%26operation_pythonAPI%E7%B7%A8.md) 0.5版
格納場所 : [TOPPERS Project](https://github.com/toppers) / [hakoniwa-px4sim](https://github.com/toppers/hakoniwa-px4sim)

お試し環境は以下の通り。
Core i5 / Memory 8G / intel UHD / Lenovo ideapad
Ubuntu 22.04.4 LTS (Native/Clean install using USB memory/Not Dual boot)
Python 3.10 ( Ubuntu 22.04.4 LTS Pre install )
[DualSense Wireless Controller](https://www.playstation.com/ja-jp/accessories/dualsense-wireless-controller/) (for PlayStation 5 : PS5)

DualSenseをUSB接続でもBluetooth接続でもどちらでも動く。

さて。次はニューヨーク！

---
以下、覚書。
あとこれらをインストール。
```
$ sudo apt install python3-pip
$ sudo pip3 install pygame numpy
```

```
# 環境変数の設定.
$ echo 'export LD_LIBRARY_PATH=/usr/local/lib/hakoniwa:$LD_LIBRARY_PATH' >> ~/.bashrc
$ echo 'export PATH=/usr/local/bin/hakoniwa:$PATH' >> ~/.bashrc
$ echo 'export PYTHONPATH=/usr/local/lib/hakoniwa/py:${PYTHONPATH}' >> ~/.bashrc
$ source ~/.bashrc
```
```
# DroneAppLinux.zipの入手.
$ cd ~/Downloads
$ wget https://github.com/toppers/hakoniwa-unity-drone-model/releases/download/v2.1.0/DroneAppLinux.zip
```

<br>
箱庭ドローンシミュレータ PX4利用編のときと違うのが、Python APIでコントローラからのボタン操作等を扱う。
そして、ps5-control-lnx.json を新規に自作。ベースをコピーしてリネームしただけだけど。

```
# ps5-control-lnx.jsonをコマンドラインで指定
$ python3 rc-custom.py ../../../hakoniwa-unity-drone-model/DroneAppLinux/custom.json rc_config/ps5-control-lnx.json

# ps5-control-lnx.jsonを環境変数で設定
$ echo 'export RC_CONFIG_PATH=rc_config/ps5-control-lnx.json' >> ~/.bashrc
$ source ~/.bashrc
$ python3 rc-custom.py ../../../hakoniwa-unity-drone-model/DroneAppLinux/custom.json
```

下図は、環境変数でps5-control-lnx.jsonをしてしたときの実行手順。
![Screenshot from 2024-09-08 11-41-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089345/e5e0f776-5211-d74a-f00e-92f91f66619d.png)
【書評】初めてのGo言語

## 読んだ本

https://www.oreilly.co.jp/books/9784814400041/

## 感想

他の言語経験者に向けたGo言語の解説本で、コンセプトがすごく良かった。
自分自身新しい言語を習得する際、ただコーディングできるという状況には公式サイトのチュートリアルなどで簡単にたどり着けることが多いが、言語特有のイディオムや慣習などは、GithubのOSSを読みまくったり、言語の成り立ちや仕組みに切り込んでいかないと把握することができないという課題感を抱えていた。
そんな中で、この本は自分の知りたかった内容に限りなく近い形でまとまっていて、本当にぴったりだった。実際一ヶ月ほどGo言語で開発を行っているが困らないレベルになっている。
付録が良い要約になっていて、ここだけ切り取って携帯しておきたいくらいだった。

## おすすめの人

- 他の言語を習得済みで、これからGo言語を習得したい人

## 次に読むなら

- GithubのOSSを読んでみるなど、実践に進めるレベルになっているはず

## 読んだときのメモ

- カンマOKイディオム `v, ok = m[k]`
- 関数内の変数はv、k、i、n、jなど短い名前にする
- ゼロ値（nilは値がないことを示すなど）
- マップをforした時の順番は固定されていない
- deferはLIFOで実行される
- レシーバー名は頭文字で定義、thisやselfは使わない
- ゴルーチンは軽量スレッド。OSでは無く、goのランタイムが管理しているので早い
小数点の計算

```kotlin
val value1 = 1.2
val value2 = 0.4
val result = value1 - value2
println(result) // 0.7999999999999999
```

プログラミング言語で少数計算をすると2進数、10進数変換の関係で誤差が発生する。Kotlinで誤差を無くす方法はBigDecimal型を使用する。

```kotlin
val value1 = BigDecimal("1.2")
val value2 = BigDecimal("0.4")
val result = value1 - value2
println(result) // 0.8
```

#### 注意
Double型からBigDecimalに変換すると誤差が出ますので、文字列型から変換することを忘れないようにする。

```kotlin
val value1 = BigDecimal(1.2)
val value2 = BigDecimal(0.4)
val result = value1 - value2
println(result) // 0.79999999999999993338661852249060757458209991455078125
```

#### 参考

https://tamotech.blog/2023/02/12/big-decimal/
params[:id]とprivateで定義して取得するparamsの違い

## 初めに

疑問に思ったことや上手くいかなかったことのアウトプットをしています。
自分なりの理解でアウトプットしていきます。初学者なので誤りもあると思います。
その際はご指摘いただけると幸いです。

## 疑問に思った点
コントローラでparamsの記述するときはprivateで定義をして取得している時があります。
```
private

  def xxxxx_params
    params.require(:user).permit(:email)
  end
```

なのに
```
@token = params[:id]
```
と記述するだけで取得できるコードもあります。違いはなんでしょう。

## 調べた結果
params[:id]とxxxxx_paramsでの違いはAPIで送られるデータかそうでないかです。
idはAPIリクエストの一部として送信されるので、pramas[:id]で取得できます。
モデルから取得する必要があるデータと、直接送られてくるデータで区別をしています。

## 修正・追記
privateでparamsを定義しなくてもparamsは使えます。
それでも定義するのはセキュリティの強化、コードの可読性や明示性を高めるためです。
これによって、どのメソッドが外部からアクセスできるかが明確になります。
個人で路上ライブマッピングサイトを作りました

この記事を見てくださりありがとうございます。今回、路上ライブが開催される場所を地図上にマッピングして集客できるようなWebアプリケーションを作ってみました。以下のリンクから
URL:
https://livespot.onrender.com/
Gitub
https://github.com/Nowshun1124/myapp

![スクリーンショット 2024-09-06 18.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768119/56e31ffb-d42a-a082-5ad0-b2883a8f5ae8.png)


# 1. Webアプリの目的
大学で音楽活動をしていて、何かインディーズ界隈に貢献できるサービスを開発できないかと考えていたときに「路上ライブ」に目をつけました。私が考える路上ライブの課題及び改善点として、「集客のしにくさ」が第一に挙げられます。この課題を解決する手段として、POKEMON GOのようなマッピングサービスが有効だと考えました。作ったアプリ(Livespot)ではアーティストはユーザー登録を行えばアプリ内でアーティストアカウントをもち、ライブを行う場所と詳細を事前にマッピングして登録してホーム画面の地図に表示させることができます。これにより、駅前でたまたま路上ライブを見るというゲリラ的な集客に加えて、地図を見て時間があったから見にきたという能動的な集客も見込めます。

# 2. 技術選定
Livespotを作るにあたって使用した技術スタックは以下の通りです。
・Ruby on Rails
・Google map API(Geocoding API, Maps JavaScript API)
・Javascript
・MySQL(開発環境DB)

# 3. ER図
![スクリーンショット 2024-09-08 11.55.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768119/3ab26695-3d62-843e-628c-06dc4e312653.png)

# 4. webアプリの具体的な機能
ここで、機能について紹介します。Livespotの主な機能は以下の通りです。

・マッピング機能
・ログイン機能
・フォロー機能

上から順番に実装方法と詳細について説明していきます。

### 4.1 マッピング機能
この機能を実装するにあたり、Google map APIを利用しました。RailsでDBからアーティストの投稿したライブ情報を持ってきてviewに渡しています。

Geocoding APIは座標と住所の相互変換を担っています。例えば、検索フォームで地名を検索したら(handleLocationSearch関数で)その住所を座標に変換し、地図の中心位置を変更したり、(addMarker関数で、)ライブの場所の座標を元に住所を取得し、HTML内の該当する要素に住所を表示しています。

Maps Javascript APIは地図を操作、マーカーを配置、アーティスト名や地名で検索するときなどに多く使っています。

### 4.2 ログイン機能
Railsでusers_controllerとsessions_controllerを使い、パスワードやメールアドレスをcookieに保存して入力せずにログインできるようにしています。また、アーティストアカウントとリスナーアカウントの2種類でユーザー登録ができて前者はライブ情報の投稿やフォロワーへのメッセージ投稿ができて、後者ではアーティストをフォローすることができます。仮に、ユーザー登録をしなくても地図からライブ情報を見ることができるので主な機能自体はサイトを訪れるだけで使えるようにしています。

### 4.3 フォロー機能
バックエンド側で実装した機能の中では一番手こずった機能です。中間テーブルであるrelationshipテーブルを用意してそこにユーザーのidを格納するオーソドックスな方法で実装しましたが、今回アーティストをリスナーがフォローできてもアーティストはその他のアカウントをフォローできない仕様にしたかったため、バリデーションを書く必要がありました。こちらが予期せぬ操作をされてエラーがでないようにするために必要なバリデーションを書くのは、かなり労力がかかりました。

# 5 作成後の振り返り
今回制作するにあたって意識した点は以下の通りです。
・セキュリティ面での安全性
・修正がしやすいコード

まず、セキュリティに関してですが今回最も意識した面でもあります。実はこの前にも個人制作をしたことがあったのですがセキュリティ面での欠陥が多く見つかってしまいました。例えば、ログインをしていないのにほかのユーザーのプロフィール編集画面に飛んだり、urlでリクエストを送って意図しない操作ができたりと考慮にかけたものになってしまいました。そこで、セキュアなアプリ開発は何かや対策方法などを本や記事で勉強した後にこのアプリを制作しました。現状、セキュリティに関する欠陥はまだ見つかっていないので、今後テストを書いたり他人に触ってもらうなどしてさらにブラッシュアップしていければなと思います。

また、今回初めてRailsで制作したのですが非常に直感的にかけるなと感じました。使用するメソッドは細かく分けてネーミングをして、何をしているコードなのかを後からでも理解しやすいようにしました。さらに、作成後もリファクタリングを行い誰が見ても読みやすいリーダブルなコードにできたのではないかと思います。

最後に、Livespotの制作では前回の反省を踏まえた実装と自分の今後の勉強方針や足りないものを理解することができました。今後の展望としてスマートフォンで使用するためにPWA、また、ユーザー数を増やすためにSEO対策なども必要なのかと考えています。そのため、Next.jsやReactなどのフロントエンドフレームワークの勉強とそれを用いたプロダクト開発を行いたいと考えています。
PythonでFile名-関数名-引数をログに出したい

### Pythonで関数ごとにログを出したいが関数名とか毎回手入力は面倒くさいなあという方用

要らないログを省いた結果、コード自体が長くなってしまったので、モジュール化することにした。
自分を呼び出してしまうので、ファイル名を変更する方は`__file__`で自動化すればいいかもしれない

必要であれば`logging`で出力する

#### ログ出力用
```ruby:getLog.py

import inspect
from datetime import datetime
import os
import functools

def log_function_call(func):
    """関数が呼び出されるたびにログを出力するデコレータ"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # 呼び出し元のフレームを取得
        frame = inspect.currentframe()

        # フレームスタックを辿り、`getLog.py` 以外のフレームを探す
        for outer_frame in inspect.getouterframes(frame):
            file_name = os.path.basename(outer_frame.filename)
            # `getLog.py` 以外のファイルを探す 呼び出し元になってしまうため
            if "getLog.py" not in file_name and not file_name.startswith(("pydevd", "debugpy")):
                break

        current_function = func.__name__
        line_number = outer_frame.lineno
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        # 引数の情報を取得
        args_str = ', '.join(repr(arg) for arg in args)
        kwargs_str = ', '.join(f"{key}={value!r}" for key, value in kwargs.items())
        all_args_str = ', '.join(filter(None, [args_str, kwargs_str]))

        # 引数がない場合も () を表示
        if all_args_str:
            args_display = f"({all_args_str})"
        else:
            args_display = "()"

        # ログ出力
        print(f"{timestamp} - {file_name}:{line_number} - {current_function}{args_display}")

        # 元の関数を実行
        return func(*args, **kwargs)

    return wrapper

```

#### 実装用コード
```ruby:
from getLog import log_function_call

@log_function_call
def test(a):
    print(f"tggest: {a}")

@log_function_call
def example_function(x, y, z=1):
    print("example_function:x, y, z=0")
if __name__ == "__main__":
    test("Hello")
    example_function(5, 10, z=3)
    example_function(1, 2)  # 引数なし

```

#### 結果

```
2024-09-08 12:59:38 - main.py:11 - test('Hello')
tggest: Hello
2024-09-08 12:59:38 - main.py:12 - example_function(5, 10, z=3)
example_function:x, y, z=0
2024-09-08 12:59:38 - main.py:13 - example_function(1, 2)
example_function:x, y, z=0
```
PHPとMySQLの接続方法をわかりやすく解説【初心者向け】

# 1.はじめに
この記事では、PHPを使ってMySQLデータベースに接続する方法を解説します。
PHPの基本的な知識がある方、データベース接続に挑戦したい初心者の方は是非ご覧ください。

# 2.PHPとMySQLの接続とは？
まずデータベースとは何か、PHPがどのようにデータベースと通信するのかについて簡単に説明します。
データベースとは、データを効率的に保存・管理・検索・更新するためのシステムです。一般的にデータベースは、表形式でデータを保存する「リレーショナルデータベース」(MySQL,PostgreSQL)がよく使用されます。これに対して、ドキュメント指向などの非リレーショナルデータベース(MongoDB)も存在します。
そして、PHPはデータベースと通信するための多くの方法を提供しています。最も一般的なのがMySQLやMariaDBと連携することです。
接続方法として「PDO(PHP Datta Objects)」と「MySQLi」の2つの接続方法があります。
今回はより汎用的で推奨されているPDOを使用します。

# 3.PHPでのMySQL接続コードの解説
### 3.1 PDOを使用した接続方法
```PHP:php
try {
    $dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8';
    $username = 'root';
    $password = '';
    $option = [
        PDO::ATTR_ERRMODE => PDO::ERRRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ];

    $pdo = new PDO($dsn, $username, $password, $option);
    echo "データベースに接続できました！";
} catch (PDOException $e) {
    echo "接続に失敗しました。". $e->getMessage();
}
```
#### コードの説明：
 - `$dsn`：データベースの接続情報を定義する文字列。`host`、`dbname`、`charset`を指定。
 - `$username`と`$password`：データベースにアクセスするためのユーザー情報。
 - `PDO`オプション：PDO(PHP Data Object)によるデータベース接続時に設定する追加のオプションです。これにより、エラーハンドリングやデータの取得方法など、PDOの挙動をカスタマイズすることができます。
 - `try-catch`：プログラムで発生するエラー（例外）を適切に処理するための構文です。これを使うことで、プログラムが予期せぬエラーで停止することを防ぎ、エラーが発生した場合にどう対処するかを決められます。
### 3.2 エラーハンドリングとデバッグ
 - `$e->getMessage()`：この方法で取得できる具体的なエラーメッセージは、開発者にとってエラーの原因を特定し、効率的なデバッグと適切なハンドリングエラーを行うための強力なツールです。

# 4.データの取得と表示
接続が成功した後、簡単なクエリを実行してデータを取得・表示する方法を紹介します。
```PHP:php
$stmt = $pdo->query('SELECT * FROM users');
while ($row = $stmt->fetch()) {
    echo $row['name']. '<br>';
}
```
#### コードの説明：
##### `$stmt = $pdo->query('SELECT * FROM users');`
- `query()`メソッドは、SQL文を実行するために使われます。この場合、`SELECT * FROM users`というSQLクエリが実行されています。このクエリは、`users`テーブルのすべての列を取得します。
- `pdo`は、事前に作成されたデータベースへの接続帆保持している`PDO`オブジェクトです。この接続が成功していれば、クエリを実行できます。
##### `while ($row = $stmt->fetch())`
- `fetch()`メソッドは、クエリ結果から1行ずつデータを取得します。最初に呼び出すと、最初の行を返し、次に呼び出すと2行目以降を順に返します。
- `while`ループを使用して、結果が取得され続ける限り、データの処理を繰り返します。データがなくなると、`fetch()`は`false`を返し、ループが終了します。
`echo $row['name']. '<br>';`
- `$row`は`fetch()`で返された1行分のデータを保持する配列です。この配列の各要素は、テーブルの列に対応しています。例えば、`users`テーブルに`name`という列がある場合、`$row['name']`でその列のデータを取得できます。
- `echo`を使って`name`列の値をブラウザに表示し、`<br>`で改行を挿入しています。

# 5.まとめ
PHPとMySQLの接続ができるようになった後、次に挑戦すべきステップは、データベースへのデータの挿入、更新、削除などの操作です。これらの操作を総称してCRUD操作(Create,Read,Update,Delete)と呼びます。
CRUD操作を習得することで、動的なWebアプリケーションの開発が可能となり、ユーザーの入力に応じてデータを操作するシステムを構築できるようになります。

# 6.追加リソース
さらに深掘りしたい人向けに役立つ公式ドキュメントや参考リンクを紹介して終わりたいと思います。
- PHP PDO マニュアル
https://www.php.net/manual/ja/book.pdo.php
- MySQL マニュアル
https://dev.mysql.com/doc/

最後までご覧いただきありがとうございました。
firestoreのversionエラー

```sh
[!] CocoaPods could not find compatible versions for pod "FirebaseCore":
  In Podfile:
    FirebaseFirestore (from `https://github.com/invertase/firestore-ios-sdk-frameworks.git`, tag `10.29.0`) was resolved to 10.29.0, which depends on
      FirebaseFirestoreBinary (= 10.29.0) was resolved to 10.29.0, which depends on
        FirebaseCore (= 10.29.0)

    firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`) was resolved to 11.2.1, which depends on
      Firebase/Analytics (= 11.0.0) was resolved to 11.0.0, which depends on
        Firebase/Core (= 11.0.0) was resolved to 11.0.0, which depends on
          FirebaseAnalytics (~> 11.0.0) was resolved to 11.0.0, which depends on
            FirebaseCore (~> 11.0)

    firebase_core (from `.symlinks/plugins/firebase_core/ios`) was resolved to 3.4.0, which depends on
      Firebase/CoreOnly (= 11.0.0) was resolved to 11.0.0, which depends on
        FirebaseCore (= 11.0.0)

```
        // 以下の解決方法
    
    pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '10.7.0'
AWS　プログラミングノート

# awsをCLIから使用する時に行うべきこと
以下のコマンドでプロファイルを選択して作業を行う
```
aws configure --profile 名前
```
### 以下のコマンドで今自分が使用しているAWSアカウントがどれかわかる
```
aws sts get-caller-identity --profile 名前
```
以下のように表示される
```
{
    "UserId": "AAAAA",
    "Account": "111111",
    "Arn": "arn:aws:iam::1111:user/IAMのユーザー名"
}
```
これをAWSマネジメントコンソールの右上クリック→アカウント→アカウントIDと進み、この値が上記のAccountと一致すればOK

**またコンソールのリージョンがCLIのものと一致しているか確認する**

# profileの確認、変更

ホームディレクトリで以下を実行
```
ls -a
```
.awsというディレクトリを見つけ、移動する。そこでlsコマンドを打つと
```
ls
amplify		config		credentials
```
と表示される。config,credentialsをクリックしてファイルを開き編集する。
#### credentials
```
[default]
aws_access_key_id = a
aws_secret_access_key = a
```

#### config
```
[default]
region=ap-northeast-1
```
プロファイルを追加したければ任意の名前で追加すればOK

samのデプロイコマンドを例にプロファイルの切り替えの方法を説明
```
sam deploy guided --profile default
```

# Lambda

S3

CloudWatch

CloudFormation

## AWS Secret Manager
機密情報管理のためのAWSサービス。主にデータベースの認証情報やOauthトークンをjson形式で管理してくれる。
またparameter storeとの違いとして暗号化や自動ローテーションを行ってくれる。そしてこのサービス自体が認証情報を保管してくれるデータベースとなっている。
参考記事：(https://zenn.dev/fdnsy/articles/133db8440d052f)

キー、値のペアでsecret managerに保存、apiを叩いてその値を取得して自分のサービスに使えることを確認、ローテーションをオンにしても使うことができるかも確認する。