OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel + Inertia で React上で値をどこからでも扱えるようにしたい。

Laravel + Inertia + Reactで構築した環境では、
バックエンド(Laravel)からフロントエンド(React)に値を渡す時は、
通常は下記のようにコントローラでレンダリングするPageコンポーネントを値を渡します。
```php:
    public functionindex()
    {
        $posts = Post::orderBy('id','desc')->take(5)->get();

        return Inertia::render('Post/Index', [
            'posts' => $posts,
        ]);
    }
```

しかし、Pageコンポーネントではなくて例えばヘッダーやフッター、ボタンなど
ページとして表示するcomponentではなくてパーツ的なcomponentにバックエンドから
値を渡す時にコントローラから値を渡すことに違和感を感じた(そもそも可能なんでしょうか？)ので
他の方法をご紹介します。

## shared-dataを利用する

コントローラを使わずに値を渡す方法が公式にありました。

公式document
https://inertiajs.com/shared-data

Middlewareの中にHandleInertiaRequests.php
というファイルがあり、ここで値を渡す処理を書けばいいみたいです。
デフォでは下記のようになっています。
```php:HandleInertiaRequests.php
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Inertia\Middleware;
use Tighten\Ziggy\Ziggy;

class HandleInertiaRequests extends Middleware
{
    /**
     * The root template that is loaded on the first page visit.
     *
     * @var string
     */
    protected $rootView = 'app';

    /**
     * Determine the current asset version.
     */
    public function version(Request $request): string|null
    {
        return parent::version($request);
    }

    /**
     * Define the props that are shared by default.
     *
     * @return array<string, mixed>
     */
    public function share(Request $request): array
    {
        return [
            ...parent::share($request),
            'auth' => [
                'user' => $request->user(),
            ],
            'ziggy' => fn () => [
                ...(new Ziggy)->toArray(),
                'location' => $request->url(),
            ],
        ];
    }
}

```
ここの部分に追記していけば良さそうですね。
```php:
public function share(Request $request): array
    {
        return [
            ...parent::share($request),
            'auth' => [
                'user' => $request->user(),
            ],
            'ziggy' => fn () => [
                ...(new Ziggy)->toArray(),
                'location' => $request->url(),
            ],
        ];
    }
```
では、適当に文字列を渡してみます。
```php:
public function share(Request $request): array
    {
        return [
            ...parent::share($request),
            'auth' => [
                'user' => $request->user(),
            ],
            'value' => 'あいうえお',
            'ziggy' => fn () => [
                ...(new Ziggy)->toArray(),
                'location' => $request->url(),
            ],
        ];
    }
```

この値をReactでは下記のようにすれば使用できます。
"usePage"を使って値を使えるようにします。

```typescript

//HandleInertiaRequests.phpのデータを受け取りに"usePage"使う
import { usePage } from '@inertiajs/react';//

export default function Footer() {
    const { value } :any= usePage().props;  
    return (
        <footer className="">
            <div>{value}</div>
        </footer>
    );
}

```

以上です。
Qiita-cliを使って記事を書いてみた

# はじめに
Qiita-cliを使って記事を書いてみた。これまでの投稿は、Markdown形式の記事をvimで別途作成し、これをqiitaの記事編集エリアにコピペして投稿していた。この手順だと、ブラウザ上での作業がどうしても必要で正直手間だった。コマンドライン上で記事の編集・投稿作業を完結できれば、もっと気軽に(自分のメモとして)投稿できるのに、と思っていた自分としては、Qiita-cliは理想の環境ではないか、と感じたので早速試してみた。

(この記事はQiita-cliがリリースされた直後あたりにメモ書きしたものが投稿されずに放置されていたもの。久々に記事を書く際に参考になったので、備忘録として投稿)

# qiita-cli環境の導入方法
基本は以下のリンクのREADMEに書いてある通り行えばよい
[https://github.com/increments/qiita-cli](https://github.com/increments/qiita-cli)

# 記事の作成方法
## まず記事の雛形を生成し、それを起点に記事を書く方法
以下のコマンドにより、カレントディレクトリにpublicというフォルダが生成され、その下にnewArticle.mdというファイルが生成される。newArticleというファイル名は任意。ファイル拡張子(md)は自動的に付加されるので自分ではつける必要がないことに注意
```
macos$ npx qiita new newArticle
created: newArticle.md
```
catで生成されたファイルを表示すると、中身は以下のようにyaml形式のヘッダのみで、ヘッダの下に記事をMarkdownk形式で書いていけばよい。titleとtagsは適宜追加・編集する。titleにはファイル名が書かれていることに注意のこと。titleとtagsの記入時、キーワードに半角スペースが含まれている場合はシングルコーテーションでくくること
```
macos$ cat public/newArticle.md
---
title: newArticle
tags:
  - ''
private: false
updated_at: ''
id: null
organization_url_name: null
slide: false
---
# new article body
```
id、update_at、等は投稿処理(publish)を行うと自動的に追記される。『# new article body』の行を削除し、Markdown形式で記事を追記する

## 過去の記事(Markdown形式)を流用して記事を書く方法
こちらのやり方では、yaml形式のヘッダ部分が文書に含まれていないため、ヘッダ部分を手動で追加する必要がある。まずは、newコマンドで雛形ファイルを生成し、その中に過去のファイルを読み込んで編集すれば楽。なおtitleとtagsは投稿する記事に合わせて適宜編集が必要になる

## preview機能で投稿前に記事の確認ができるのが便利
編集するターミナルとは別のターミナルから以下のコマンドでpreviewを起動しておく
```
macos$ npx qiita preview
```
ブラウザから以下にアクセスすると、qiitaと同じ見た目で投稿前の記事を確認することができる
[http://localhost:8888](http://localhost:8888)

# 投稿方法
## コマンドラインで行う場合
以下のコマンドで記事を投稿する。xのところはハッシュコード(?)が表示され、このコードがヘッダのidのところに追記される
```
macos$ npx qiita publish newArticle
Posted: newArticle -> xxxxxxxxxxxxxxxxxx 
Successful!
```

## preview画面から行う場合
画面右上にある"記事を投稿する"ボタンをクリックする。投稿が成功すれば、 preview画面の上部に"投稿が成功しました"と表示が出る。

# 最後に
これで備忘録として記事を投稿する頻度が上がること間違いなし(結局はネタ次第なのですが)
Azure Portal の左に並んでいるサービスメニューを折りたたんだり展開したりしてみた

クラウドで提供されるサービスの機能や仕様が日々進化していたり、逆にリタイアされていくバージョンやサービスがあったりと、数ヶ月前の情報があっという間に古くなってしまいます。Azure Portal もサービスの一つで、左に並んでいるサービスメニューが折りたたんだ状態で表示されるよう、仕様が変更（進化？）されました。これまでは「スクロールして目的のメニューを見つけてクリック」という動作が、「メニューカテゴリーをクリックして、あっ違った、別のメニューカテゴリーをクリックして、あった、このメニューをクリック」という感じで、個人的には目的のメニューがとても探しづらい仕様になりました。

ところがいつの間にか、メニューを検索するバーの右横にこっそりと、何やらクリックできそうなアイコンが増えていました。このアイコンをクリックするとメニューカテゴリが全て展開される事を見つけました。それでも「アイコンクリック、スクロールして目的のメニューを見つけてクリック」する必要があるわけで、以前よりワンクリック多いのです。

* メニューカテゴリ展開前の状態

![azure-portal-menu-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/1cb02bfb-5386-1fb2-3049-6d20b7a76216.png)

* メニューカテゴリ展開アイコンクリック後の状態

![azure-portal-menu-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/ec7d6754-f343-a899-0da7-6e44d1ad2f73.png)

では、最初からメニューカテゴリが展開されている状態にならないか調べてみたら、「外観とスタートアップビュー」に「サービスメニューの動作」という設定項目がありました。試しに InPrivate で動作確認したところ、メニューカテゴリが展開済みの状態である事を確認できました。

* サービスメニューの動作を設定する画面

![azure-portal-menu-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/2caa2c42-bb88-379c-3a34-255c6b0b2731.png)

## 参考

https://learn.microsoft.com/ja-jp/azure/azure-portal/set-preferences?utm_source=pocket_shared#service-menu-behavior
Python httpsサーバーとWiresharkでのTLS復号

# PythonでのhttpsサーバーとWiresharkによるTLS復号化
もともとはWiresharkで暗号化データを見たいというところからスタートし、そのためには、簡単にhttpsサーバーを構築したい、ついでにPythonにて作成で、、、ということなった。調べると下記内容の単なる組み合わせで済んだが、備忘録として記録に残す。
 - [Python Tips: Python で https サーバーを動かしたい](https://www.lifewithpython.com/2021/03/python-https-server.html)
 - [MacOsのWiresharkでHTTPトラフィックを見る方法　 How to decode TLS traffic on Wireshark](https://qiita.com/takamon9/items/4325a3f129c28b4221d1)

## Pythonでのhttpsサーバー
上述リンク先のコードとほぼ同じ。
```python:server.py
import ssl
from http.server import HTTPServer, SimpleHTTPRequestHandler

PORT = 443
CERTFILE = "./oreore.pem"
Handler = SimpleHTTPRequestHandler

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(CERTFILE)

with HTTPServer(("", PORT), Handler) as httpd:
    print("serving at address", httpd.server_address, "using cert file", CERTFILE)
    httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
    httpd.serve_forever()
```
証明書を本ファイルがあるディレクトリの”oreore.pem”としている（オレオレ証明書）。同ディレクトリにあるindex.htmlは下記となっている。
```html:index.html
<html>
  <h1>Test12345</h1>
</html>
```
実行する。
```shell
% python3 server.py
```
```shell
$ SSLKEYLOGFILE=./key.log /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=./tmp
```
”key.log”はWiresharkで利用されるログファイルである（後述）。

## WiresharkでTLS復号化
こちらも上述リンクのとおりに実施。
![Wiresharkのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/aa025f9e-f7d5-9922-edb4-ecfebe5ab1a8.png)
PreferenceのProtocol TLSにて、シークレットログファイル（ここではkey.log）を定める。

## 検証
### アクセス
ループバックアドレス”https://127.0.0.1/”へアクセスする。オレオレ証明書なので下記メッセージが表示されるが、無視して進む。
![プライバシーエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/280b3cf5-751d-7650-2b5a-7cfeb8630f61.png)
![Test12345.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/94370583-f431-6e3b-76d1-73c27acb448b.png)
index.htmlの内容が表示されている。

### Wiresharkで取得したデータ
同じキャプチャファイルを、シークレットログファイル指定がある場合とない場合とで比較してみる。ログファイル指定がある場合が下記。
![key指定ありのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/8fee4b71-94f0-423e-bd23-d16b909487da.png)
HTTPのコマンドやレスポンスが見えるが、ログファイル指定がない場合が下記となり、それらが見えない。
![key指定なしのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/39b915af-e1d7-e30e-a6bd-4b7f670c2a8c.png)
ポート番号が443であることも確認（下記）。
![Port443のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/d0d360ff-3dda-1250-2d70-eda0eb5f7466.png)
シークレットログファイル指定がある場合で、シーケンスを表示してみる。ここでは、TLSストリームを選択。
![追跡.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/600bc465-794c-e0bb-382a-5e94f992b7fd.png)
その結果が下記となる。
![TLSストリーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/4973a796-2466-f107-4062-b07ddfce15b8.png)
HTTPの詳細が見える。まずは意図したことは実施できた。

### server.pyログ
参考までに、server.pyログを表示。
```
serving at address ('0.0.0.0', 443) using cert file ./oreore.pem
127.0.0.1 - - [18/May/2024 16:32:23] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [18/May/2024 16:38:33] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [18/May/2024 16:44:36] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [18/May/2024 16:44:36] code 404, message File not found
```

EOF
WSL2上のubuntuでmeldを起動したときに、Window操作ができなくなって困った件

# はじめに
WSL2環境(Windows10/11)のubuntuでmeldを立ち上げた時、割と頻繁にWindow操作ができなくなって困っていたが、復旧方法がわかったのでメモ
(meld以外にqterminalもハマった記憶がある)

# トラブルの状況
* meldは起動するものの、Window最大化やWindowの移動ができなくなる(マウス操作に反応しない感じ)
* meldの終了もGUIから操作できず、ターミナルでCtrl+Cでkillするか、WindowsのタスクバーでWindowを閉じる、で止めるしかない状況
* WSL2再起動、Windows再起動でも解決せず困り果てる(WindowsにインストールしたMeld.exeをubuntuから起動してしのいでいた)

# トラブルの発生原因
Windowsをマルチ画面で操作していて、meldを隣のモニタに移動させたり、最大化したりするとハマった印象がある(再現実験はしていないです)

# 解決方法(不十分)
問題が発生したら、meldを止めてから以下のファイルを消去する

```
$HOME/.config/dconf/user
```

# 解決方法(本命？)
* dconf-editorで設定を変更する(詳細は後ほど)


# 注意点
この操作を行うと以前のwindowサイズ・位置は忘れてしまう。それでも操作できないよりはマシ

# 最後に
この方法はあくまでもその場しのぎでしかない。こんなトラブルがそもそも発生しない対策があれば知りたいです(WSL2環境に限った問題？)

# 追記(2024/09/03)
上記対策でも制御が効かなくなる場合があることを改めて確認。最大化(タイトルバーのダブルクリック)をすると、それ以降おかしくなる模様。Windows側の制御と齟齬が発生しているのかも？更に確認をすすめる→dconf-editorを使って設定変更すれば確実に復旧できそうな感触あり
プロジェクトマネジメントをより良くするための当面の目標を立ててみた。

アンチパターンで学ぶ仕事の進め方、というQiitaの記事にインスパイアされた。

https://qiita.com/TabataRin/items/4cd7bacb64f3138f99b7?utm_source=Qiita+ニュース&utm_campaign=070e12de56-Qiita_newsletter_634_09_04_2024&utm_medium=email&utm_term=0_e44feaa081-070e12de56-32768633

この記事を読み、自分でもこの数か月で学んだ仕事の仕方、というか、失敗談を元にした、今後の仕事の改善したい点を書いてみようと思った。

と始めたものの、一言で言うと、「MECEにやりましょう」ということに尽きるんですよね。

MECE、もれなく、ダブりなく。大きなテーマです。

言うのは簡単だけど、やるのはめっちゃ難しい。

私の場合、まずは、WBS。

スケジュール、タスク、リソース、の3つの観点で、俯瞰的なマクロの視点と、ズームインしたミクロの視点を何度も行き来し、抜け漏れなく、タスク化し、管理する。

管理の仕方も、やはり、ズームイン・アウトを繰り返す。

プロジェクト開始から終了までの俯瞰的視点でヌケモレが無いか。一週間予定にヌケモレはないか。一日の予定にヌケモレは無いか。

MECEにやる上で有用と思われるドキュメントに、トレーサビリティマトリクスがある。

二つの事柄（例えば要件定義と基本設計）を縦軸、横軸にそれぞれ網羅すべき項目を記載し細密にヌケモレチェックを行うというもの。

プロジェクトがスケジュール通りに、一定の品質で進行していることを確認することも大事。

プロジェクトの進行中は、各タスクやプロジェクト全体における潜在的なリスクを洗い出し、リスクが顕在化する前に対応策を検討する。

そのために、リスクマトリックスやリスクレジスターを作成し、定期的に見直す。

プロジェクトの各フェーズで設定された品質基準を満たすためのチェックリストやガイドラインを作成する。

プロジェクトの途中で発生する変更要求を適切に管理し、プロジェクト全体に与える影響を評価する。

上記は具体的なアクションだが、心構えも変えていきたい。

まっとうなプロセスを踏む。やってできたらそれでいいという考え方をやめる。

そのために、まず全て自分調べてから、わからないものだけを確認する。

参照すべきドキュメントが正しいかを、作業着手前に常に問う。

古いドキュメントを更新すると、デグレが起こる。

何か指摘を受け修正した場合は、他に直すべき箇所が無いかを俯瞰的に調べる。

方法は、一番簡単なのは、文言チェック→検索（Ctrl+F）で同じワードが無いかチェックする。

必要に応じ、Pythonでツールを作る。

このあたりをここから半年くらいかけて、しっかりとやっていきたい。
M1 Mac + Docker で 「ゼロからのOS自作入門」をやってみる ~Hello, World!編~

# 環境情報
 - MacBook Air M1, 2020
 - Chip: Apple M1
 - macOS: Ventura 13.3.1 (a)
 - docker version: 27.1.1

# 事前準備
## Docker Desktop のインストール
Docker Desktop は 250 人以上の企業では有料ですが、個人では無料で利用できます。
1. https://www.docker.com/products/docker-desktop/ から Apple Silicon 版 Docker Desktop を選択し、Docker.dmg をダウンロード
1. 指示に従いインストールする
   - "Use recommended settings (require password) を選択
       - 必要であれば後で設定は変更可能
   ![Config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407073/e2480f22-b690-0874-6418-9d30544185b4.jpeg)
   - 色々質問されるが"Skip"でOK　
       - 必要であれば後でアカウントを作る
   ![Welcome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407073/85420d2b-e2b7-fd5a-4d2d-1d84c12cf8af.jpeg)
1. Docker コマンドが使えることを確認する
`docker version`を実行して、バージョン情報等が出力されればOK.

   ```
   $ docker version
   Client:
    Version:           27.1.1
    API version:       1.46
    Go version:        go1.21.12
    Git commit:        6312585
    Built:             Tue Jul 23 19:54:12 2024
    OS/Arch:           darwin/arm64
    Context:           desktop-linux

   Server: Docker Desktop 4.33.0 (160616)
    Engine:
     Version:          27.1.1
     API version:      1.46 (minimum version 1.24)
     Go version:       go1.21.12
     Git commit:       cc13f95
     Built:            Tue Jul 23 19:57:14 2024
     OS/Arch:          linux/arm64
     Experimental:     false
    containerd:
     Version:          1.7.19
     GitCommit:        2bf793ef6dc9a18e00cb12efb64355c2c9d5eb41
    runc:
     Version:          1.7.19
     GitCommit:        v1.1.13-0-g58aa920
    docker-init:
     Version:          0.19.0
     GitCommit:        de40ad0
   ```

## XQuartz のインストール
https://www.xquartz.org/index.html から XQuartz をインストールする。
.pkgファイルをダウンロードして、指示通りに進めればOK.

XQuartz の Settings > Security の "Allow connections from network clients" にチェックを入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407073/568ce13b-afda-0183-d08c-52d981f7d56f.png)

# okteta を起動する
いよいよ、oktetaを起動します。

## Dockerfile の準備
Ubuntu の docker image は下記を参照しました。
https://hub.docker.com/_/ubuntu

1. 任意の場所にディレクトリを用意し、そこに移動する
   ```
   mkdir mikanos
   cd mikanos
   ```
   
1. 下記の内容で`Dockerfile` を作成する
   ```
   FROM ubuntu:18.04

   # 環境変数の設定
   ENV DEBIAN_FRONTEND=noninteractive

   # 基本的なパッケージのインストール
   RUN apt-get update && apt-get install -y \
       software-properties-common \
       locales \
       && locale-gen en_US.UTF-8

   # KDEとoktetaのインストール
   RUN apt-get update && apt-get install -y \
       okteta \
       kde-plasma-desktop \
       dbus-x11 \
       --no-install-recommends

   # 不要なパッケージとキャッシュのクリーンアップ
   RUN apt-get clean && rm -rf /var/lib/apt/lists/*

   # エントリーポイントの設定
   CMD ["/usr/bin/okteta"]
   ```

1. Docker container の起動
   ```
   $ docker build -t okteta .
   ```
   (5分くらいかかる)
   ```
   docker run -e DISPLAY=host.docker.internal:0 \
           -v /tmp/.X11-unix:/tmp/.X11-unix \
           --name okteta \
           okteta
   ```

起動できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407073/4e34251b-09ab-1f27-092b-f9e6193b9d58.png)
Security Testing on Salesforce

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)

-------


+ [Security Testing on Salesforce apps?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifbot)

:::note
外部システムと統合する場合は、API が OAuth または同様の方法で保護されていることを確認する必要があります。また、接続が安全であること、ログイン範囲と信頼できる IP が準拠していることも確認する必要があります。 

セキュリティ テストに役立つ可能性がある次のリンクを確認してください。

When you're integrating with external systems, you need to make sure your APIs are secured with OAuth or something similar. You also need to make sure your connections are secure, and that your login ranges and trusted IPs are compliant. 

Check out the following link, which might help you in security testing:

https://security.salesforce.com/security-best-practices
https://trailhead.salesforce.com/content/learn/modules/mobile-application-security-implementation/test-mobile-applications
:::
Pinguinoは死してgccを残す

pinguino.ccのサイトがいつの間にかなくなっています。

PinguinoIDEはPIC18,PIC32MXをターゲットにしたArduinoライクな開発環境でした。

Microchipのコンパイラーが有料だったりしたので、Pinguinoに入っている、gccを利用していました。

サイトがなくなってバイナリの新規入手ができなくなったのでplatformioに移そうかと思ったので、platformioのgccはchipKITのライブラリに強く依存していてビルドが通せません。

インターネットアーカイブでサイトを見直したところ、githubにアカウントがありました。その中にgccのバイナリを含むリポジトリがありました。

https://github.com/PinguinoIDE/pinguino-compilers

ちょっといじって、下記のリポジトリをEl Capitanでビルドできました。

https://github.com/yamori813/pic32mx_i2s_sin

linux64のバイナリはFreeBSDのエミュレーションで使えました。

実は死んでなくて、こちらに引越ししたようです。

https://pinguinoide.github.io/

ただMacのサポートはやめているので、上記のレポジトリのgccも4.6.2とちょっと古いもののままです。

ページが崩れていて、ちょっと厳しそうです。
JMeterの環境をDockerで構築してみた（とても楽できた）

### 備忘録
JMeterはJAVAで実装されているが、Dockerで環境構築すれば超簡単。


Dockefile
```Dockerfile
# JMeterの公式イメージを使用
FROM justb4/jmeter:5.5

# JMeterのテストプランと結果のディレクトリを指定
COPY test_plan_1.jmx /test_plan_1.jmx
VOLUME /results

# JMeterのコマンドを実行してテストを開始
ENTRYPOINT ["jmeter", "-n", "-t", "/test_plan_1.jmx", "-l", "/results/result.jtl"]
```

Docker compose
（他のservicesについては当時の開発時のものママ）
```Dockerfile
version: "3.8"
services:
  frontend:
    # image: node:18
    build:
      context: ./frontend
    container_name: frontend
    working_dir: /app
    volumes:
      - ./frontend:/app
    ports:
      - "3000:3000"
    env_file:
      - .env
    command: ["npm", "run", "dev"]
    depends_on:
      - backend
    networks:
      - app-network

  backend:
    build:
      context: ./backend
    volumes:
      - ./backend:/app
    ports:
      - "8000:8000"
    env_file:
      - .env
    depends_on:
      - db
      - redis
    networks:
      - app-network

  db:
    image: postgres:13
    container_name: postgres_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    ports:
      - "5432:5432"
    networks:
      - app-network

  redis:
    image: redis:7.0
    container_name: redis
    ports:
      - "6379:6379"
    networks:
      - app-network
  
  playwright: 
    image: mcr.microsoft.com/playwright:focal
    container_name: playwright
    working_dir: /e2e
    volumes:
      - ./e2e:/e2e
    env_file:
      - .env
    networks:
      - app-network
    depends_on:
      - frontend
      - backend
    command: ["npx", "playwright", "test"]

  jmeter:
    build:
      context: ./jmeter
    container_name: jmeter
    volumes:
      - ./jmeter/results:/results
    networks:
      - app-network



networks:
  app-network:
    driver: bridge

volumes:
  postgres_data:
```
Smart Listsのまとめ

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)

------------

+ [Smart Lists](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N4V00000HEZW9UAP)

レコード、ファイル、外部データを処理するための高度にカスタマイズ可能なリスト

Smart List を使用すると、カスタム開発に何日もかかる時間を節約し、わずか数分でカスタム リストを構築できます。

# Issue 

+ [Issue with picklist edit 一意の行を選択してピックリスト フィールドを編集するときに発生します。新しい値を選択した後、保存ボタンは表示されず、ピックリスト値メニューを非表示にすることはできません (Esc キーまたはクリックしてフォーカスを変更する)。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifiAJSAY)

:::note
保存ボタンを表示するには、選択リストのタブをクリックする必要があります。これは、スマート リストに使用される LWC lightning-datatable コンポーネントの制限によるものです。簡単な回避策はありません。この動作は、選択リスト フィールドで一括インライン編集が適切に機能しなかったため、3.6 で変更されました。 
:::
モジュールの結合度について

モジュールの結合度（Coupling）は、ソフトウェア開発における設計の概念であり、異なるモジュールやコンポーネント間の依存関係の強さを示します。結合度が高いということは、モジュール間の依存関係が強く、変更が困難であることを意味します。一方、結合度が低い（疎結合）は、モジュール間の依存関係が弱く、変更が容易で再利用しやすいという利点があります。結合度はソフトウェアの保守性、再利用性、テストのしやすさに大きな影響を与えます。

### 1. **結合度の種類**
結合度は、その強さに応じていくつかのタイプに分類されます。以下に、一般的な結合度の種類を、強いものから弱いものの順に説明します：

1. **内容結合 (Content Coupling)**:
   - 最も強い結合度のタイプで、一つのモジュールが他のモジュールの内部に直接アクセスする場合を指します。例えば、あるモジュールが別のモジュールの内部データやアルゴリズムに直接依存している場合です。内容結合は非常に望ましくないとされており、変更の影響範囲が広がりやすく、保守性が低下します。

2. **共通結合 (Common Coupling)**:
   - 複数のモジュールが共通のデータ（例えば、グローバル変数）を共有する場合の結合度です。共通結合も望ましくないとされており、どのモジュールが共通データを変更するかがわかりにくく、デバッグや保守が困難になります。

3. **外部結合 (External Coupling)**:
   - 複数のモジュールが同じ外部インターフェースやデータフォーマットを共有する場合の結合度です。例えば、同じファイルフォーマットを使用する場合や、共通の外部プロトコルに依存する場合です。外部結合は、共有する外部要素が変更されると、依存するすべてのモジュールに影響を与える可能性があるため、やや結合度が強いとされます。

4. **制御結合 (Control Coupling)**:
   - 一つのモジュールが別のモジュールの動作を制御するために、フラグや制御パラメータを渡す場合の結合度です。制御結合は、モジュール間の依存性が高まるため、望ましくありませんが、必要な場合もあります。

5. **スタンプ結合 (Stamp Coupling) / データ構造結合 (Data-structured Coupling)**:
   - モジュール間でデータ構造を共有する場合の結合度です。具体的には、データ構造の一部だけを使用するのに、全体を渡す場合などです。この結合度は、スタンプ結合が強いほど、モジュールが変更されると依存するモジュールに影響を与える可能性が高くなります。

6. **データ結合 (Data Coupling)**:
   - 最も望ましい結合度のタイプで、一つのモジュールが別のモジュールに単一のデータを引数として渡す場合を指します。モジュール間で共有されるデータは必要最小限であり、依存関係が最小限に抑えられます。データ結合が低い（疎結合）と、モジュールの再利用性や保守性が向上します。

### 2. **結合度の影響と設計のポイント**
結合度が強いと、以下のようなデメリットがあります：

- **保守性の低下**: モジュール間の依存が強いため、一つのモジュールを変更すると、他のモジュールにも変更が必要になる場合があります。これにより、ソフトウェアの保守や更新が困難になります。

- **テストの難しさ**: 結合度が高いと、個別のモジュールをテストすることが難しくなります。モジュール間の依存が強いと、単体テストが困難になり、テストのカバレッジが低下する可能性があります。

- **再利用性の低下**: 結合度が強いと、モジュールが他のプロジェクトやシステムで再利用される可能性が低くなります。再利用するには依存関係をすべて考慮する必要があり、時間と労力がかかります。

一方、結合度が低い（疎結合）と、以下のようなメリットがあります：

- **保守性の向上**: モジュール間の依存が少ないため、あるモジュールを変更しても他のモジュールに影響を与える可能性が低くなり、保守が容易になります。

- **テストの容易さ**: 各モジュールが独立して動作するため、単体テストが容易であり、テストのカバレッジを高めることができます。

- **再利用性の向上**: モジュールが他のシステムやプロジェクトで再利用されやすくなります。疎結合なモジュールは、他のコンテキストでも簡単に統合できるためです。

### 3. **結合度を低く保つための設計手法**
結合度を低く保つための一般的な設計手法には以下のようなものがあります：

- **インターフェースの使用**: モジュール間の相互作用をインターフェースを通じて行うことで、依存関係を減らし、モジュールの独立性を保ちます。

- **情報の隠蔽**: モジュール内の内部実装を隠蔽し、必要最低限の情報だけを公開することで、他のモジュールからの依存を減らします。

- **疎結合なアーキテクチャの採用**: マイクロサービスアーキテクチャやサービス指向アーキテクチャ（SOA）のような、疎結合を重視した設計を採用することで、モジュール間の依存性を最小化します。

結合度を適切に管理することで、ソフトウェアの品質を向上させ、保守性や再利用性を高めることができます。モジュール間の適切な結合度を保つことは、良好なソフトウェア設計の重要な要素です。
PIC32MXのUSBスタック

以下のようなものがあります。

* Microchip Libraries for Applications

昔のUSBスタックです。2018-11-26が最終です。MLAとも呼ばれています。初期のころは再配布不可だったのですが、最終的にはApatchライセンスのオープンソースになっていました。

https://github.com/MicrochipTech/mla_usb

結構むちゃくちゃです。

よくよく見ると最終のコードにはMXのサポートが抜かれています。2013-06-15には入っています。なんでそんなことするかな。

pic32mx_usb_i2sはmicrochip_solutions_v2013-06-15を使っています。

* MPLAB Harmony

MPLAB® Code ConfiguratorのMPLAB Harmonyにも入っています。これはPIC32にARMが追加されたりAtemlを買収してSAMが加わったりしたものをサポートしています。コードが大きいので小さいリソースのPIC32MXでは使えないと思います。

* m-stack

完全なオープンソースのようです。MLAがオープンではなかったので作られたのではないかと思います。

https://github.com/signal11/m-stack

* chipKIT-arduino

デフォルトでコンソールとしてCDCが入りますが、他にもコードがあります。使い方がわかりません。
誤ってプッシュしたコミットを git revert で取り消す方法

# はじめに
今回は、私が実際の開発現場で経験した、誤ってリモートリポジトリにプッシュしてしまったコミットを `git revert` で取り消す方法について、まとめました。初心者の方でも安心して使える手順を紹介しますので、参考にしてみてください。

# git revertとは
`git revert` は、Git（ソースコード管理ツール）のコマンドのひとつで、過去に行った特定の変更を取り消すためのものです。具体的には、「前にした変更をなかったことにしたい！」というときに使います。

# 実際の使用例
スクショのコミットメッセージ「console.logの削除」を誤ってリモートリポジトリにプッシュしたケースを想定して、取り消したい思います。

![スクリーンショット 2024-08-30 20.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/e9defce2-a77b-d60a-d08c-32c1e8a368be.png)

### リバート対象のコミットを確認

ローカルのリポジトリで取り消したいコミットのIDを `git log` で確認します。
```
% git log
commit コミットID (HEAD -> feature/revert-example, origin/feature/revert-example)
Author: author <author@example.com>
Date:   Fri Aug 30 20:10:14 2024 +0900

    console.logの削除
```

### リバート

次に、リモートリポジトリにプッシュされたコミットを `git revert` で取り消します。先ほどのコミットIDを使用してリバートを実行します。

```
% git revert コミットID
```

### リバートコミットの編集
`git revert` コマンドを実行すると、以下のようなコミットメッセージ編集画面が表示されます。

![スクリーンショット 2024-08-30 20.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/98efd4b7-aa30-90a0-50d8-4cd14dec7add.png)

この画面では、リバートのメッセージが自動的に入力されます。たとえば、「Revert "console.logの削除"」 のように、元のコミットの内容を示すメッセージが含まれます。このメッセージをそのまま使用する場合は、特に変更せずに<font color="red">**コミット**</font>ボタンを押して終了します。必要に応じてメッセージを編集することも可能です。

コミットボタンを押すと、リバートコミットが作成され、ローカルリポジトリに反映されます。この操作によって、指定したコミットを取り消す新しいコミットが履歴に追加されます。

### リモートリポジトリの反映

リバートコミットがローカルリポジトリに作成された後は、それをリモートリポジトリに反映させる必要があります。この手順を行うことで、他のチームメンバーもリバートされた状態を共有することができます。

コミットボタンを押した後に表示される<font color="red">**変更の同期**</font>ボタンを押すことで、リモートリポジトリに変更が同期されます。これにより、リバートコミットがリモートリポジトリにも反映され、リモートリポジトリの状態がローカルリポジトリと一致します。


![スクリーンショット 2024-08-30 20.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/0cba1cf2-5f70-bd84-0a48-1644c7856d42.png)

### Githubで確認
GitHubで変更が正しく反映されているか確認できます。

![スクリーンショット 2024-08-31 5.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/89b99bca-0d25-f214-7bb7-d3c3d4957ba1.png)


上の画像のように、GitHubのコミット履歴を確認すると、リバートコミットが追加されていることが分かります。コミットメッセージとして「Revert "console.logの削除"」と表示されているため、指定したコミットがリバートされたことが確認できます。

ここで重要なのは、<font color="red">**`git revert` で取り消したいコミットの変更は元にできるが、履歴の「console.logの削除」を行なった履歴は残る**</font>ということです。

さらに、リバートされたコミットに関連する変更が正しく反映されているか、ファイルの変更履歴を確認することも可能です。

![スクリーンショット 2024-08-31 5.32.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/c7c39f9c-9d31-d101-5b50-3a300fd68ef4.png)

この画面では、リバートコミットによって元に戻された変更が表示されています。リバートしたい変更が正しく取り消されているかどうかを、ここで確認してください。

# おわりに

これまでは、誤ってプッシュしたら、リモートリポジトリのmainブランチを参照しながら、手動で該当箇所を直してましたが、コミット履歴を綺麗に保つうえで、便利なコマンドを知ることができました。
SVAで過去のイベントのチェック

SVAでは信号の過去の状態を表すのに`$past()`が用いられる。例えばとある地点の「１～３クロック前に信号が立ち上がる」を表現するには`$past()`を用いて以下のように書ける。

```verilog:１～３クロック前に立ち上がる
//    4 3 2 1|0
//      _____.__
// ____|  ___.__
// ______|  _.__
// ________|
(!$past(a,4) && $past(a,3)) || (!$past(a,3) && $past(2)) (!$past(a,2) && $past(a,1))
```

しかし、`$past()`だけではあまり複雑なシーケンスは表現できない。例えば「10クロック前まで」とかになっただけでも`$(past)`を大量に繋げなくてはならない。又、あまり前の過去の状態を参照するのもシミュレーターの性能上良くなかったりする。
この様な過去のシーケンスを表現するのには`<Sequence>.triggered`を利用する事ができる。`.triggered`自体はシーケンスの終了を示すbooleanで、`seq_a ##0 seq_b.triggered`の様にすれば２つのシーケンスが同時に終了する事を意味する。プロパティの右辺で使用されればその事をチェックするプロパティとなる。

```verilog:シーケンスの同時終了
//                       ______|
// seq_a                |______|
//                  ___________|
// seq_b           |___________|
//                            _|
// seq_b.triggered __________| |

property prop_a_b;
  seq_a |-> seq_b.triggered;
endproperty
```

なのでそのシーケンスの最後を`[*n:m]`や`##[n:m]`ような繰り返しや遅延にする事により、とある地点（＝sdq_aの終了時点）で過去にイベントが起きたかどうかをチェックする事ができる。
冒頭の「１～３クロック前に信号が立ち上がる」の例として「信号aの立ち上がりの時点の１～３クロック前に信号bが立ち上がる」とすれば`.triggered`を使って以下の様に書く事ができる。

```verilog:１～３クロック前に立ち上がる
//        4 3 2 1|0
//               |_
// a : __________|*
// b :      _._._._.
//     ____|^ 1 2 3
//            _._._.
//     ______|^ 1 2
//              _._.
//     ________|^ 1 

sequence seq_b(clk);
  @(posedge clk) $rose(b) ##1 b[*1:3];
endsequence

property prop_a_b;
  $rose(a) |-> seq_b(clk).triggered;
endproperty
```

ここで注意しなければいけないのは、sequence内で@(posedge clk)と動作点を明示的に指定する必要がある事だ。シミュレータによっては無くても動くものもあるようだが、正式には必要のようだ。
あと、必ずsequneceを使う必要があり、`($rose(b) ##1 b[*1:3]).triggered`の様な記述はできない。

以下、EDA Playground上で各社のシミュレータで実行できる例。
[SVA Past Event Check](https://www.edaplayground.com/x/TDrZ)
Common LispのRead処理（１）

@HaruoWakakusa さんのRead処理について、３点ほど気になった点があったのですが、Lisp屋さんとして一番ディープな話を書きます。

## Readマクロの本質

>バッククォート
> cons(make_symbol("QUASIQUOTE"), cons(expr, NIL) 

>コンマ
>cons(make_symbol("UNQUOTE"), cons(expr, NIL))

>コンマ@
>cons(make_symbol("UNQUOTE-SPLICING")


ここまでは、あってます。

この後、Read処理の中で、展開しないといけません。
展開する処理が、記事に書かれていなかったので、それをやっていますか？という点が一番気になりました。

## 実験

```lisp
* '`(a ,b ,@c)
`(A ,B ,@C)
```

うわ。SBCLは、まさかのダメだ、こりゃ。

## Clojureでやってみる

```Clojure
Clojure 1.11.3
user=> '`(a ,b ,@c)
(clojure.core/seq 
(clojure.core/concat
(clojure.core/list (quote user/a))
(clojure.core/list (quote user/b))
(clojure.core/list (clojure.core/seq 
(clojure.core/concat
(clojure.core/list (quote clojure.core/deref))
(clojure.core/list (quote user/c)))))))
```

バッククオート(`)の前にクオート(')をつけると、評価が抑制されるので、Readが読んだ結果が見えます。



clojure.core/ という名前空間が、ややこしいので、省略してみます。

```Clojure
(seq
   (concat (list (quote user/a))
               (list (quote user/b))
               (list (seq (concat (list (quote deref))
                          (list (quote user/c)))))))


```

こんな感じになりました。

注目すべき点は、この中に、QUASIQUOTE, UNQUOTE, UNQUOTE-SPLICINGが一切入っていないという点です。

Read処理の一番最後で、QUASIQUOTE, UNQUOTE, UNQUOTE-SPLICINGを全部変換して取り除いてしまい、appendやlistやlist*やconsなどに展開しないといけません。

決して、eval処理の中で、QUASIQUOTEというマクロを呼んで展開する訳ではないのです。

『Read処理中に全て展開してしまうから、Readマクロ』と呼ぶのです





## でも、動くよという反論について（理由はうまく説明できない）


もうLispを勉強したのが数十年ほど前で、その時ほど、覚えていないので、良い例が思いつきません。
検索したら以下のサイトに使用例がありました。引用しますね。

https://stackoverflow.com/questions/56438808/how-this-backquote-syntax-works-in-lisp

```lisp
(define-macro (bar)
  (let ((x 10) (y '(1 2 3)) (z 'foo))
    `(list ,x `(,',z ,,@y))))
```

こんな感じで、バッククオートを２重にかけます。
３重にも書けるし、４重にも書けます。

私も実は昔、「バッククオートを２重に書ける」事を知りませんでした。
当時私は、やはりevalの中で、QUASIQUOTEというマクロを呼んで展開していました。

例は忘れてしまいましたが、
(a)Read処理の中で展開してしまう方法
(b)eval処理の中でQUASIQUOTEを展開する場合
では、結果に差が出る事があるのです。

そうです、バッククオートを２重や３重に書いた場合に、そのバグが発生します。

## おわり

Read処理の最後で、QUASIQUOTE類は、展開して取り除いてくださいね。
それが私が考える、正しいReadの処理方法です。
（もし間違っていたらすみません）
CentOS7でパッケージがインストールできない場合の対処まとめ

## 1.はじめに
勉強用のサーバ環境の構築のためにCentOS7.9にてnginxをインストールしようとしたところ下記エラーが発生したため対処方法をまとめます。
```
# yum install nginx
http://ftp.iij.ad.jp/pub/linux/centos/7.9.2009/os/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
他のミラーを試します。
To address this issue please refer to the below wiki article
```
ほかリポジトリも同様

## 2.動作環境
```
CentOS Linux release 7.9.2009 (Core)
```

## 3.確認したこと、原因
実際にアクセスしてみるとたしかに`404`でした。

http://ftp.iij.ad.jp/pub/linux/centos/7.9.2009/os/x86_64/repodata/repomd.xml

階層たどると下記文言が

http://ftp.iij.ad.jp/pub/linux/centos/7.9.2009/readme

```
This directory (and version of CentOS) is deprecated. 
```

EoLになるとパッケージのインストールでも躓いちゃうんですね。。。
勉強になりました。orz

## 4.対処
勉強用にちょっと使いたいだけなのでOSのバージョン上げる等はせずに対処していきます。

1. リポジトリファイルのバックアップ
```
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
```

2. リポジトリファイルの編集
`/etc/yum.repos.d/CentOS-Base.repo` ファイルを編集し、ミラーURLをアーカイブURLに差し替えます。
```
sudo sed -i 's|mirrorlist=http://mirrorlist.centos.org|#mirrorlist=http://mirrorlist.centos.org|' /etc/yum.repos.d/CentOS-Base.repo
sudo sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|' /etc/yum.repos.d/CentOS-Base.repo
```

3. リポジトリのキャッシュクリアと更新
```
yum clean all
yum update
```

4. 目的のパッケージのインストール
```
yum install nginx
```

これで、アーカイブリポジトリを使用してパッケージをインストールできるようになりました。
Astroでページを横断したエラーハンドリングを行う方法

Astroのサーバーモードで、ページを横断してエラーハンドリングを行うにはMiddlewareを利用する方法がある。

`await next()` で後続の処理が実行されるので、try-catchでエラーハンドリングを行うことができる。

```ts
// src/middleware.ts
import { defineMiddleware } from "astro/middleware";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // ここでエラーハンドリングを行う
    throw e;
  }
});
```

## 利用例

### エラーログを通知したい場合

エラーが起きた時にエラーログを送信したい場合は、catchしたエラーを投げればよい。
[Sentry](https://sentry.io/)のようなエラーログ収集サービスへ通知する際など。
(以下は notifyError という関数があるとする)

```ts
// src/middleware.ts

import { defineMiddleware } from "astro/middleware";
import { notifyError } from "./notifyError";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // エラーログを送信する
    notifyError(e);
    throw e;
  }
});
```

### 特定のエラーで404ページを表示したい場合

特定のエラーが発生した場合に404ページを表示したい場合は、エラーの内容をチェックして404ページを返すことで実現できる。
例えばパスパラメータで指定されたデータがデータベースに存在しない場合に、500エラーを返す代わりに404ページを表示したい時など。
(以下ではそのような場合に NotFoundError というエラーがthrowされるとする)

```ts
// src/middleware.ts

import { defineMiddleware } from "astro/middleware";
import { NotFoundError } from "./errors";

export const onRequest = defineMiddleware(async (context, next) => {
  try {
    return await next();
  } catch (e) {
    // NotFoundErrorの場合は404ページを表示する
    if (e instanceof NotFoundError) {
      return context.rewrite("/404");
    }
    throw e;
  }
});
```

## 別の方法

他にも、カスタム500ページを用意してエラーハンドリングを行う方法もある。
https://docs.astro.build/ja/basics/astro-pages/#カスタム500エラーページ
ただしMiddlewareを使う方法の方が汎用的だとは思う。

```ts
// src/pages/500.astro
---
import { notifyError } from "../notifyError";

interface Props {
  error: unknown;
}

const { error } = Astro.props;
if (error instanceof NotFoundError) {
  return Astro.rewrite("/404", 404);
}
notifyError(error);
---

500 Internal Server Error
```

## 雑感

[Astro公式のミドルウェアのドキュメント](https://docs.astro.build/ja/guides/middleware/)をパッと見るだけではわからなかったのでメモ。
Middlewareのドキュメントをよく読むと[レスポンスの内容を書き換える](https://docs.astro.build/ja/guides/middleware/#センシティブな情報を消去する例)ことができたりもするので、柔軟性が高いと感じた。
git rebaseを使って誤ってコミットしたファイルとフォルダを削除する

# はじめに
開発中に誤って.envファイルやその他の機密情報を含むファイルをGitHubにアップロードしてしまうことは、誰にでも起こり得るミスです。これらのファイルにはAPIキーやデータベースの接続情報など、外部に漏れてはならない情報が含まれていることが多いため、早急かつ適切な対応が必要です。本記事では、誤って機密ファイルをアップロードしてしまった場合の具体的な対処法について解説します。

:::note alert
.gitignoreに追加してコミットしても、すでにコミットされたファイルはリポジトリから自動的に削除されません。手動で削除が必要です。
:::

:::note warn
ファイルを削除して新しいコミットを作成しても、過去の履歴には依然としてファイルが残っているため、履歴のクリーンアップが必要です。
:::

# 対処の基本ステップ
### 1. .gitignoreに追加する
まず、誤ってコミットしたファイルが再度コミットされないように、.gitignoreファイルに対象のファイルやディレクトリを追加します。
```bash:.gitignore
# Dependency directories
/node_modules

# Environment variables
.env
```
これにより、今後.envファイルがリポジトリに追加されることを防げます。

### 2. リベースを開始する
次に、誤ってコミットしたファイルを含む履歴を修正するため、インタラクティブリベースを使用します。例えば、直近の3つのコミットを対象にリベースを行う場合、次のコマンドを実行します。
```bash
git rebase -i HEAD~3
```
:::note warn
HEADを設定しないとうまく機能しないです。
:::

### 3. コミットの編集
このコマンドを実行すると、エディタが開き、以下のようなリストが表示されます。
```batchfile
pick abcdef1 First commit
pick abcdef2 Added login page
pick abcdef3 Another commit
```
削除したいファイルやフォルダが含まれるコミット行をpickからeditに変更します。例えば、最初のコミットを編集する場合は次のようにします。
```diff_batchfile
- pick abcdef1 First commit
+ edit abcdef1 First commit
pick abcdef2 Added login page
pick abcdef3 Another commit
```
保存して、エディタを閉じます。
### 3. コミットを修正
リベースが一時停止し、指定したコミットの修正を行います。まず、誤ってコミットしたファイルやフォルダを削除し、変更をステージングします。

ファイルを削除する場合：
```bash
git rm --cached .env
```
フォルダ（例えばnode_modules）を削除する場合：
```bash
git rm -r --cached node_modules
```
その後、修正した内容で新しいコミットを行います。
```bash
git commit --amend --no-edit
```
:::note info
--no-editオプションを使用すると、コミットメッセージを変更せずにコミット内容を更新できます。
:::

### 4. リベースを再開する
修正が完了したら、次のコマンドでリベースを再開します。
```bash
git rebase --continue
```

### 5. 修正内容をリモートに反映する
最後に、ローカルリポジトリの修正内容をリモートリポジトリに反映させます。ただし、リモートリポジトリの履歴が書き換わるため、強制プッシュが必要です
```bash
git push origin --force
```
:::note alert
強制プッシュにより、リモートリポジトリの履歴が書き換えられるため、他の開発者と連携している場合は事前に通知を行うことが重要です。
:::

# まとめ
この記事では、.envなどの機密ファイルをGitHubに誤ってアップロードしてしまった際の対処法を紹介しました。迅速かつ適切に対処することで、被害を最小限に抑えることができます。また、再発を防ぐための予防策も重要です。この記事を参考に、日常の開発に役立ててください。
Go言語(Golang) interfaceとstruct


### インターフェース (interface)

#### 機能
- インターフェースはメソッドの集合を定義する型です。
- インターフェースを実装する型は、そのインターフェースが定義するすべてのメソッドを持っている必要があります。
- インターフェースは、異なる型のオブジェクトが共通のメソッドを持つことを保証し、ポリモーフィズムを実現します。

#### 使い方
1. **定義**:
    ```go
    type Human interface {
        Say() string
    }
    ```
    - `Human`インターフェースは`Say`というメソッドを定義しています。このメソッドは引数を取らず、文字列を返します。

2. **実装**:
    - インターフェースを実装するには、そのインターフェースが定義するすべてのメソッドを持つ構造体または型を定義します。
    ```go
    type Person struct {
        Name string
    }

    func (p *Person) Say() string {
        p.Name = "Mr." + p.Name
        return p.Name
    }
    ```
    - `Person`構造体は`Say`メソッドを持っているため、`Human`インターフェースを実装しています。

3. **使用**:
    - インターフェース型の変数に実装型のインスタンスを代入できます。
    ```go
    var mike Human = &Person{"Mike"}
    fmt.Println(mike.Say()) // 出力: Mr.Mike
    ```

### 構造体 (struct)

#### 機能
- 構造体はフィールド（データ）をまとめて管理するためのカスタムデータ型です。
- 構造体はメソッドを持つことができます。これにより、データとその操作をまとめて表現できます。

#### 使い方
1. **定義**:
    ```go
    type Person struct {
        Name string
    }
    ```
    - `Person`構造体は`Name`という文字列フィールドを持ちます。

2. **インスタンス化**:
    ```go
    p := Person{"Mike"}
    fmt.Println(p.Name) // 出力: Mike
    ```

3. **メソッドの定義**:
    - メソッドは構造体に関連付けられた関数です。
    ```go
    func (p *Person) Say() string {
        p.Name = "Mr." + p.Name
        return p.Name
    }
    ```
    - `Say`メソッドは`Person`構造体のポインタレシーバを持ち、`Name`フィールドを変更して新しい名前を返します。

### インターフェースと構造体の連携

- 構造体はインターフェースを実装することで、異なる構造体が共通のインターフェースを持つことができます。
- これにより、異なる型のオブジェクトを同一の方法で扱うことができます。

```go
func DriveCar(human Human) {
    if human.Say() == "Mr.Mike" {
        fmt.Println("Run")
    } else {
        fmt.Println("Get out")
    }
}

func main() {
    var mike Human = &Person{"Mike"}
    var x Human = &Person{"x"}
    DriveCar(mike) // 出力: Run
    DriveCar(x)    // 出力: Get out
}
```

- このように、`DriveCar`関数は`Human`インターフェースを引数に取り、どの具体的な型のインスタンスであってもインターフェースを実装していれば使用できます。
分散と平均二乗誤差の類似点と違い

### 分散と平均二乗誤差の類似点と違い

データ分析や機械学習の分野で頻繁に使われる「分散」と「平均二乗誤差（MSE）」ですが、これらはどちらもデータのばらつきを測定するための指標です。ただし、それぞれが持つ意味や用途は異なります。この投稿では、分散とMSEの類似点と違いについて整理します。

#### 1. 分散とは
分散は、データが平均値からどれだけ散らばっているかを示す指標です。データポイントとその平均値との差を二乗し、その平均を取ることで計算されます。分散が大きいほど、データは平均値から大きく離れて分布していることを意味します。

$$
\text{Var}(X) = \frac{1}{n} \sum_{i=1}^{n} (x_i - \mu)^2
$$

ここで、$x_i$ は各データポイント、$\mu$ はデータの平均値、$n$ はデータポイントの数です。

#### 2. 平均二乗誤差（MSE）とは
MSEは、予測モデルの精度を評価するための指標です。予測値と実際の値との差を二乗し、その平均を取ることで計算されます。MSEが小さいほど、予測モデルが実測値に近い予測を行っていることを意味します。

$$
\text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
$$

ここで、$y_i$ は実測値、$\hat{y}_i$ は予測値、$n$ はデータポイントの数です。

#### 3. 分散とMSEの類似点
- **ばらつきを測る指標**  
  分散とMSEはどちらも「ばらつき」を測る指標です。分散はデータ全体のばらつきを、MSEは予測誤差のばらつきを表します。

- **計算方法の類似性**  
  どちらも、データポイントと基準点（分散では平均値、MSEでは実測値）との差の二乗を平均することで計算されます。

#### 4. 分散とMSEの違い
- **対象の違い**  
  分散はデータセット自体のばらつきを測るのに対し、MSEは予測モデルの精度を評価するために使われます。分散はデータの平均値を基準として計算されますが、MSEは実測値を基準として計算されます。

- **計算に用いるデータの違い**  
  分散は、実際の各データポイントとそのデータセットの平均値との差から求められます。一方、MSEは予測モデルが出力した予測値と実際の観測値（実測値）との差から計算されます。つまり、分散がデータ自体の特性を反映するのに対し、MSEは予測モデルの誤差を評価するための指標です。

- **目的の違い**  
  分散は、データの内在的なばらつきを理解するために使われます。一方、MSEはモデルの予測性能を評価し、モデルがどれだけ実測値に近い予測を行っているかを確認するために使われます。

---

このように、分散とMSEはどちらもデータのばらつきを評価する指標ですが、その対象と計算に用いるデータが異なります。分散はデータそのものの特性を評価するのに対し、MSEは予測モデルの精度を評価するために使用されます。
運用保守で気を付ける事をシンプルにまとめました

# はじめに
最近ミスが多発しているため、改めて運用保守作業について大切なことを振り返りました。
運用保守で気を付けることをシンプルにまとめました

私が書いた以下の記事から特に重要なことをこちらの記事にまとめました。

https://qiita.com/gama1234/items/5a6fb54194f687ab9f4a


## 運用作業が始まる30分ぐらい前は頭を作業に切り替える
運用作業が始まる30分前は手順書の内容を確認して流れを復習する。
ログインするサーバなど確認する。

**運用作業以外のことを作業直前にやるとミスのもとになります。**

## 翌営業日のカレンダーは必ず確認する
翌営業日のカレンダーは必ず確認した方が良いです。
明日の作業を把握することは必須です。作業漏れにつながります。

## 依頼が来た運用作業はすぐにカレンダー登録とタスクとして登録する
お客さんから依頼が来た運用作業は来たらすぐにカレンダー登録とタスク登録をした方が良いです。
後回しにすると複数の依頼が来た際に作業を忘れてしまいます。
**日程調整中の場合は仮でも良いため、目の前のタスクを一つづつ丁寧にカレンダー登録する**

## イレギュラーな対応はすぐにメモする
イレギュラーのことが起きた際に運用保守の作業ではパニックになります。
何とか調べて解決できても、メモを取らなかったら次回も同じところで躓きます。
過去のことは記憶が薄れています。早めにメモする。


## 作業内容を理解する
運用保守の作業は手順書通りにやってもうまくいかないことはあります。
例えばOSのEOLを迎えてパッケージがインストールできなくなる可能性もあります。
サーバごとに環境が違うので時が立つとサーバーの状態も変わってくる可能性があります。
**理解してから作業手順書を作成する**当たり前ですが意外と難しいことです。


## 割り込みが発生したら初めから手順書を確認する
作業中に別の割り込みや作業が思うように進まずに手順書から離れてしまった際は
**初めから手順書を一番上から一番下まで一つづつ確認する。**
初めから一つづつ確認しない場合は、作業漏れが発生しやすくなります。
終わった手順書に色を付けると視覚的にも分かりやすくなります。

## 本番環境からいきなり手順書を変更しない
テスト環境と開発環境で検証した後に、本番環境で作業することはよくあります。
そのため、どんな良いアイディアでもテスト環境で実施した実績がある手順書から
本番環境の作業の際にいきなり手順書は変更しないことです。

## 確認者は最終後の守りと意識する
確認者は最後の守りだと意識することです。
**自分が最後に見落としを防ぐという心がけが大切**

## 作業ログは必ず残す
サーバーで作業した作業ログは後で振り返るときにとても大切なため、
作業ログはすべて残してチームの共有のフォルダに管理することをお勧めします。
特に本番環境のサーバーの場合は必須です。
作業ログを運用作業後に削除しないように気を付けてください
ゼロから始めるプログラム学習（C#）_005

##    はじめに

 プログラミング言語 __<font color="red">　【C#『シーシャープ』】</font>__ を使用して
 プログラムを最初から学習するための記載。 


　　　前回：ゼロから始めるプログラム学習（C#）_004
　　　https://qiita.com/nekoozi/items/0e1f9bc78c98559dfffe



## <font color="green">繰り返し</font>

### 1･･･ <font color="red">for命令</font>
>for命令は、指定した回数だけ繰り返し処理を行うための構文

### for命令の基本構文
for (初期化子; 条件; 反復子)
{
    // 繰り返し実行する処理
}

```C#
namespace ArrayExample
{
    class Program
    {
        static void Main(string[] args)
        {
            /* 配列の宣言と初期化 */
            string[] characters = new string[] { "あ", "い", "う", "え", "お" };

            /* 各要素の表示 */
            // for文を使って配列の各要素を個別に表示

            // characters.Length は 配列の数をカウント

            for (int i = 0; i < characters.Length; i++)
            {
                Console.WriteLine($"characters[{i}] = {characters[i]}");

               /* 上記はつまり
                　 １回目のループでは　0 < 5 になり
                   i は 0（ZERO） を設定して出力

            　　　 ２回目のループでは　1 < 5 になり
                   i に 1 を設定して出力
                  
                   ３回目のループでは　2 < 5 になり
                   i は 2 を設定して出力

                   ４回目のループでは　3 < 5 になり
                   i は 3 を設定して出力

                   ５回目のループでは　4 < 5 になり
                   i は 4 を設定して出力
                   
                   ６回目のループでは　5 < 5 になり
                   そもそも処理を行わない
                  */
            }
        }
    }
}

````

````
実行の流れ:
　for ループでは、i の値が 0 から始まり、
　配列の長さ（characters.Length = 5）より小さい間、
　ループ処理が繰り返され、以下のようになります

1回目のループ (i = 0):
2回目のループ (i = 1):
3回目のループ (i = 2): 
4回目のループ (i = 3): 
5回目のループ (i = 4):
6回目 (i = 5) の時点で条件 i < characters.Length が成立しなくなるため、ループ終了。
````

出力結果:
````
characters[0] = あ
characters[1] = い
characters[2] = う
characters[3] = え
characters[4] = お
````

### 2･･･ <font color="red">foreach命令</font>
>foreach命令は、配列やコレクションの要素を順に処理するための構文で、要素数を気にせず安全に使えます。

### foreach命令の基本構文
foreach (型 変数 in コレクション)
{
    // 繰り返し実行する処理
}


```C#
namespace ArrayExample
{
    class Program
    {
        static void Main(string[] args)
        {
            /* 配列の宣言と初期化 */
            // String型の配列を宣言し、初期値を設定
            string[] characters = new string[] { "あ", "い", "う", "え", "お" };

            /* 各要素の表示 */
            // foreach文を使って配列の各要素を順に表示
            foreach (string character in characters)
            {
                Console.WriteLine($"Character: {character}");

                /* foreachではインデックスを意識せず
                   配列の各要素を1つずつ取得して処理します。
                */
            }
        }
    }
}

````
出力結果:
````
Character: あ
Character: い
Character: う
Character: え
Character: お
````

・簡潔な記述: 
　　for文のようにインデックスを管理する必要がありません。

・安全性: 
　　配列やリストの範囲外をアクセスする心配がないため、エラーを防ぎやすいです。

・制限: 
　　要素を直接変更することはできません（コピーに対して操作が行われるため）。


--------------------------------------------------------------

　　　次回：ゼロから始めるプログラム学習（C#）_006
　　　https://qiita.com/nekoozi/items/caddc226f36b99b1dad1


## 参考文献

C#関連情報サイト様

https://www.sejuku.net/blog/41892

https://yuyu-code.com/programming-languages/c-sharp/iterative-process/
G Pro Wirelessが充電されない/充電が増えない

## G Pro Wirelessが充電されないので困っていました

最近、私のG Pro Wirelessマウスが充電されなくなり、非常に困っていました。YouTubeを見ながら充電していたら、急にバッテリーがなくなり、コードを変えても、充電口を変えても関係なく充電されませんでした。

### Redditを調べてみたら…
インターネットを検索していたところ、Redditで同じ問題に直面した人たちの投稿を見つけました
そこにはテーブルにたたきつけたら直ったと報告している人が何人もいて、正直そういうジョークかと思ってたけど他に試す手がなかったので、思い切ってたたいてみることにしました。

すると、なんと、本当に充電が始まったのです！

## 感想
まさかこんな方法で直るとは思ってもみませんでしたが、今では問題なく充電できています。もちろん、根本的な解決策ではないかもしれませんが、同じ問題に悩んでいる方は、一度試してみる価値があるかもしれません。
Power Automate の承認で「連続した承認」を選択し、多段階承認した時に申請段階はどこに格納されるのか？

ごきげんよう、百合宮桜です！
うっかり Power Automate のアップデートに気づいたことを呟いたら、有識者をワラワラと釣り上げてしまったので、お詫びに検証してみました。
Dataverse を利用するので、有償ライセンスが必要です。

https://x.com/yurimiyasakura/status/1829320648851902498

今回のお題は、「開始して承認を待機」アクションで「連続した承認」を選択して、多段階承認をした時に「今どのステップにいるのか」を見つけることです。

連続した承認での多段階承認の方法についてはコルネさんが記事を書いてくださっているので、こちらも合わせてお読みください。

https://koruneko.hatenablog.com/entry/2024/06/18/085328

# 承認はどこに保存されるのか？

承認は、承認が走り始めた時に Dataverse の「承認」テーブルにレコードが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/d7c5bea9-3166-e002-0e9a-5b1f64f36bf6.png)

ここに保存されるのは承認アクションが起動したという記録です。
その為、ここには承認段階（第一承認・第二承認など）、承認の応答（Approve や Rejectなど）や承認時のコメントは含まれていません。
あくまでも承認が走っているということが記録されているだけです。

# 承認の応答はどこに保存されるのか？

Approve や Reject という応答は、Dataverse の「承認応答」というテーブルに保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/c0b54e7c-5938-ffb5-fdc7-dd715a8aa00f.png)

連続した承認を使用した場合は、承認者が承認 or 却下の判断をするタイミングで、1ステップに1レコードずつ作成されます。
先に出てきた「承認」テーブルの承認列に格納されている一意識別子が、「承認応答」テーブルでは「承認 ID インデックス」に格納されています。
その為、「承認 ID インデックス」列に格納されている、承認テーブルの一意識別子を検索して、当該承認のレコードを探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/aadc3fc7-f858-8b2d-ec1a-6eeb5b0bfd5b.png)

多段階承認だと当該承認のレコードが複数出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/df6b457b-ddf1-cb55-642f-0354f3b4220c.png)

どの段階なのかという区別は「ステップ番号」という列に格納されます。
連続した承認のステップ番号は、0 から始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/5fd43160-dcf9-71dc-a9cd-dc2cb2040c98.png)

その為、第一承認の「RyotaHR」がステップ番号「0」、第二承認の「SakuraIT」がステップ番号「1」という具合に登録されます。

# 結論
仕組みとしては上記のような感じなので、
申請段階を確認したい承認の一覧を作成し、承認応答テーブルにレコードが作成されたときにステップ番号を確認するような仕組みを作れば、申請段階を把握することはできます。
結構長くなりそうなので、私が考えたフローは別記事に分けたいと思います。
【ネタ】JavaScriptが顔に見える件


`JavaScript`を見ていたら
`JavaS`の部分が顔のように見えた。

分かりやすくするとこんな感じ。
`Jﾟ∀ﾟS`

そして無い知恵を絞ってJavaScriptでAAを作ってみた。

```
 Ja aS
   v
cr i  pt
```

`t`は十字架かなんかでしょう。

みんなもへのへのもへじみたいにJavaScriptで絵を作ってみてください。

## 関連

https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%9F%E3%83%A5%E3%83%A9%E3%82%AF%E3%83%A9%E7%8F%BE%E8%B1%A1
【Shell】特定のフォルダの容量を確認する方法


## `du`コマンド

`du`コマンドを使用することでディレクトリ内のファイル容量を表示させることができます。

```terminal
$ du .
8328	./sample/example
280240	./sample
7670680	.
```

## オプション（一部）

### `-h`
次のように実行すると、適切な単位で表示します。

```terminal
$ du -h .
4.1M	./sample/example
137M	./sample
3.7G	.
```

### `-s`

次のように実行すると、指定したディレクトリの合計を表示します。

```terminal
$ du -s .
7670776	.
```

### `-d 深さ`

次のように実行すると、表示する深さを指定できます。

```terminal
$ du -d 1 .
7670680	./sample
7670776	.
```

## 容量が大きい順に表示する

以下のように実行すると容量が大きい順に表示されます。

```terminal
du -h . | sort -n -r
```
【SAA-C03】AWS Certified Solutions Architect - Associate 【合格体験記】

## はじめに
こんにちは！
本記事では、私がCertified Solutions Architect - Associate（SAA-C03）に合格したときの学習方法を紹介します。
1回目の受験で合格することができ、スコアは**838点**でした。

※1,000点満点で、720点以上で合格です。

## 結論
[Ping-t](https://mondai.ping-t.com/g)を**全部コンボするまで勉強すれば合格ラインに届く**と思いました。


https://mondai.ping-t.com/g


## 詳しく解説
![AdobeStock_572846074.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/051b41cf-1d5c-3bdd-5909-0ab76b2e38bb.jpeg)

### 使用テキスト・問題集
まずは、私が学習に学習に使用したテキスト・問題集は以下です。
+ [AWS認定資格　ソリューションアーキテクトアソシエイトの教科書](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E5%90%88%E6%A0%BC%E3%81%B8%E5%B0%8E%E3%81%8F%E8%99%8E%E3%81%AE%E5%B7%BB-CloudTech%E6%9B%B8%E7%B1%8D%E4%BD%9C%E6%88%90%E5%A7%94%E5%93%A1%E4%BC%9A-ebook/dp/B0BCPNZ9GJ)
その名の通り、ソリューションアーキテクトアソシエイトの範囲を学習するための参考書なのですが、なんと**無料**です。これを使わない手はありませんね。
　
+ [AWS認定資格 WEB問題集&徹底解説 ソリューションアーキテクト - アソシエイト](https://aws-exam.net/saa/saa_question.php)
この問題集、なんと**無料**です。試しに何問か挑戦してみるといいかも。
　
+ [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/?couponCode=JUST4U02223)
SAAの模擬試験6回分です。問題の難易度は実際の試験よりも難しめに設定されています。有料です。
　
+ [ping-t](https://mondai.ping-t.com/g)
個人的に**最強の学習コンテンツ**です。最速でSAAを取得したい場合、ひたすらこれを解くのが良いのではないかと思います。そしてなんと**無料**です。

### 私がやった学習方法
初めは『AWS認定資格　ソリューションアーキテクトアソシエイトの教科書』を読み進めていました。
しかし、しばらく読み進めていると、「問題を解いてみたいな」と思うようになり、問題をひたすら解いて解説を読む勉強方法にシフトしました。

SAAの練習問題が解けるサイトを探したところ、見つけたのが『AWS認定資格 WEB問題集&徹底解説 ソリューションアーキテクト - アソシエイト』でした。
簡単な問題から解き進めていきましたが、**2択の問題があったり（実際の試験に2択の問題は無い）、答えが間違っている問題があったりした**ので、このサイトで学習するのはやめました。

他の学習サイトを探していると、『Ping-t』を知りました。
私は全ての問題を2回連続正解（ping-tではこれを"コンボ"と呼びます）するまで解き続けました。
このサイトの解説は図を用いており非常に分かりやすく、サービスの概要すら分からない状態でも学習できます。
そして**問題は700問以上**掲載されています。

ping-tは、試験に合格した人が合格体験記を投稿できます。
合格された方々の合格体験記を読んでいると、「Ping-tだけで合格できた」という書き込みがある一方、「Ping-tだけでは難しい」という書き込みもあり、不安を覚えた私は『【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）』を取り組みました。

模擬試験が6回分収録されていますが、実際に取り組んだのは1~4回目です。
試験本番前に取り組んだ模試の結果は、
模擬試験①：83%
模擬試験②：75%
模擬試験③：72%
模擬試験④：72%
でした。(それぞれ72%が合格ラインです。)

ただ、この問題集のレビューを見ると、「実際の試験より難しい」という書き込みがある一方、「**実際の試験と同難易度**」という書き込みもあり、後者のレビューの通りだった場合はちょっと**ヤバい**と思いました。。。
が、**このタイミングで試験を受けました。**

### 試験当日
テストセンターで受験しました。
最初はちょっと緊張してしまい、問題を解くのに時間をかけすぎてしまいましたが、**問題を解きながら合格を確信しました。**
実際の試験は、やはり『【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）』より簡単だったのです。
**ping-tだけでも大丈夫だったと思います。**

### 感想
試験の難易度はPing-tの問題とそんなに変わらないと思いました。
ただ、**試験は問題文や選択肢の文章が長い**ため、それに慣れておく必要はあると思いました。（ping-tは問題文が短めかも。）
『【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）』のおかげで、それは培われたと思います。

![AdobeStock_168512251.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/42e21740-0c1c-68ba-7422-7dc4b3704468.jpeg)

皆様のご参考になりましたら幸いです。
それではまた！

https://mondai.ping-t.com/g
プライベートリポジトリをpoetry addするときに詰まったこと

# 概要
pythonパッケージにしたプライベートリポジトリをpoetry addするときに細かいことで詰まったのでメモ（共有）
（普通にgit cloneできるような鍵登録などはした状態）

# 内容
誤って以下にしていた
```bash
poetry add git+git+ssh://git@github.com:DarekanoKaisha/RepoJitori.git@main
```

正しくは以下
```bash
poetry add git+git+ssh://git@github.com/DarekanoKaisha/RepoJitori.git@main
```

# 感想
なかなか気づかなかった。だってエラーが
```
DarekanoKaisha/RepoJitori.git@main is not a valid repository name
Visit https://support.github.com/ for help
```
なんだもん


(仮想のレポジトリです)