OmniAICreator/Qiita-1.07M huggingface dataset:
[Node.js] packeage.json、paceage-lock.jsonとは

# 目的
node.jsに必須なpackeage.json、packeage-lock.json、node_mudulesとは何かまとめる

## packeage.json
パッケージ(=プロジェクト)の詳細が書かれたファイル
例) sampleというRailsプロジェクトのpackeage.json
``` packeage.json
{
  "name": "sample",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "5.4.4",
    "turbolinks": "^5.2.0",
    "webpack": "^4.46.0",
    "webpack-cli": "^3.3.12"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3"
  }
}

```

#### name
パッケージの名前

#### version
パッケージのバージョン指定

#### description
パッケージの説明

#### main
そのパッケージをインストールする際に開始となるファイルを指定

#### scripts
コマンドのエイリアス（別名）を設定。npmだとrunで実行できる。
以下のように書いたとすると、
```
"scripts": {
"start": "next start"
}
```
この場合はnpm,yarnで以下のようにコマンドを実行できる。
```
npm run start 
yarn start
```

####  author 
パッケージの管理者

#### Dependencies

 - 本番環境でそのパッケージを実行するのに必要なパッケージを記述する
 - 何のパッケージを入れたいのか
 - 個別にパッケージのインストール(npm install パッケージ名)をすると、自動でパッケージの情報が追記される。

#### devDependecies
- 開発やテストで使用する、そのパッケージ(プロジェクト)を実行するのに必要なパッケージを記述する。typescriptなど

#### private
公開設定。公開しない場合はtruenに設定。


#### repository
パッケージのソースコードを管理している場所ど設定


# package.lock.json/yarn.lock
- パッケージのバージョンをロックするファイル
- 何のパッケージを入れたのかを自動的に記述される
- パッケージをインストールすると作成され、その後パッケージをインストールするたびに更新される(npm install)
- 依存関係にあるものを含め、ダウンロードしたすべてのパッケージのバージョンとその情報が管理されている

## node_modulesフォルダ
- カレントディレクトリ配下にあり、カレントディレクトリにインストールされるモジュールの中身が配置されるフォルダ

# 参考にさせていただいた記事
- [【初心者向け】NPMとpackage.jsonを概念的に理解する](https://qiita.com/righteous/items/e5448cb2e7e11ab7d477)
- [【まとめ】package.jsonとnpmコマンドについてわかりやすく解説](https://kosuke-space.com/package-json-npm)
自分用メモ:AtCoderのエディタの変更点

ボタンが増え、左側に来た。
コードのブロックを折り畳めるのが好き。
- 高さ自動調節
 前からあるやつ。オンにすると下に長いプログラムはそのまま表示されるが、オフにすると縦が短くなり、スクロールして見れるようになる。
- 自動補完
 候補を表示してくれるやつ。
- タブ幅拡張
 オンにするとタブが4文字になる。オフは前からの2文字。
- 空白を表示
 表示すると空白と改行が表示される。
並列Lisp　ARMでOKなのにインテル、AMDでだめはのはなぜ？

# ご注意
以下の話はあくまで仮説です。実証できたわけではありません。推測が含まれていますのでご注意ください。

# 発端
自作のEasy-ISLispに並列機能をもたせるということをこの数ヶ月やってきました。スレッドセーフやコンカレントGCの問題を解決し、インタプリタ及びコンパイラにおいて並列動作をするようになりました。しかし、ラズパイ400のARMだと並列で性能を発揮するのに対し、インテルのicoreやAMDのRyzenでは並列処理の方が遅くなる場合があります。この理由をずっと考えていました。ようやく理解に達したような気がしましたので記録に留めることとしました。


# 並列で遅くなる場合
Easy-ISLispはインタプリタとコンパイラを持っています。さらにコンパイラには型推論を応用した最適化により高速コンパクトなコードを生成する機能があります。インテルとAMDにおいてはそれぞれにおいて並列の性能が異なるのです。

○インタプリタ　　　☓　並列の方が遅くなる

○コンパイラ　　　　☓　並列の方が遅くなる

○最適化コンパイル　○　並列の方が速くなる


テストに使用したコードはベンチマークでよく使われる再帰計算によるフィボナッチ数です。


# L３キャッシュ
調べていますとラズパイに搭載されているARMのCPUにはL1,L2キャッシュのみがありL３キャッシュはないことがわかりました。一方でインテル、AMDのCPUにはL3キャッシュがあり、それは近年大容量化する傾向にあります。

![single.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/ea2ffc37-f317-2b79-e3e1-15ed1c47c841.png)



L1キャッシュはCPUからもっとも近く、速度も高速です。L１キャッシュで見つからない場合には２番めに高速なL2キャッシュを探しに行きます。さらになければL3キャッシュを探し、最終的に見つからなければメモリを探しにいきます。近年のCPUはこのキャッシュを高速化、大容量化することにより高速化を図っているものと思います。


# 共有キャッシュのマルチコアでの問題点
L1、L2キャッシュは各コアが独立に保有します。しかしL3キャッシュは各コアで共有で保有します。L3キャッシュは禁煙、大容量化してお普及型のRyzenでも１６MBあります。シングルコアの場合にはこれによりヒット率が高くなり高速化が期待されます。しかし、メモリ共有で各コアが並列で動作すると状況は変わってきます。各コアがみているメモリの範囲が異なるからです。L3キャッシュで見つからなければメモリから再ロードすることになります。また、共通のメモリからロードしますので競合の問題が起きやすくなります。Pthreadライブラリを利用したメモリ共有型の並列ではこれが問題となるはずです。

![multi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/44d20cf5-9d40-422b-5368-c9a869869c1e.png)



一方、マルチプロセスでは影響はありませんでした。下の図は２つのプロセスで独立してフィボナッチ数を計算している様子です。他のコアが計算中であっても速度には影響を受けていません。マルチプロセスの場合にはメモリ空間が独立しておりキャッシュの更新の際の競合の問題が起きにくいです。

![bandicam 2023-08-24 06-29-56-342.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/2dde486b-b267-bf6b-6d7c-e1728949d90c.jpeg)


# 今のところの結論
Easy-ISLispの並列機能はPthreadライブラリ（POSIX)を利用したマルチスレッドによるマルチコア並列です。これをマルチプロセス方式にすれば並列の性能向上が見込まれる一方でLispのもつ大域変数のアクセスを実装するには複雑なことをしないといけません。プログラムも全プロセスで共有する仕組みが必要になります。

いずれインテルもAMDもこの並列の問題を解決するに違いない、とのんびり構えてその時を待つことにしました。


私はCPUの詳細にういて専門知識を有しません。上述の仮設についてのご意見をいただければ幸いです。コメント欄にてご教示ください。よろしくお願いします。
どうやってプログラミング、技術情報を集めるか？のすすめ

## いままで学んだこと（プログラミング学習）

## 中級者になったらWEB検索から離れよう！

Web検索ではじめに出てきやすい情報は初心者向け
＝＞初心者向けの情報のほうが欲しい人が多いから

## 欲しい情報がある！
ブラウジング＝＞そのままキーワードを検索エンジンに打つ

初心者からレベルが上がるほどマッチした情報が出てこなくなる。

＝＞知らない人が多いから

つまり知ってる人が少ない情報でも載ってる

コアなサイトに飛んでから検索するべき

そのサイトを知らなければまずそのサイトを調べて集めてお気に入りに並べとけ

## Programming情報収集に使えるサイト（一般的な奴）
Qiita：https://qiita.com/
GitHub：https://github.com/
Reddit：https://www.reddit.com/
Hacker News：https://news.ycombinator.com/

いずれも英語ができるとさらに良き

英語ができる人は世界のコミュニティとつながりやすいので有利である

公式DocumentやForum  を読む

個人ブロガーで自分の専門分野に合ったいい人を探す

これもある!

みんなが知らないためになる情報はなかなか手に入らない！

宝探しである！！！

おすすめはGitHubで他人のリポジトリをあさること。

Twitterも侮れない。

=>理由 　情報を共有してくれるエンジニアが多い。特に、特定の技術や言語のコミュニティをフォローすると、新しいツール、ライブラリなどの情報を速やかにキャッチできる。

## 質の高いクリエイターの追っかけをする。
この人すげえ。こんな技術欲しい！

大体その人のSNSとか探せば情報は公開している。

運が良ければGitHubのリポジトリもみれるかもしれない。

これはおすすめ。人の技術を盗めるかもしれないから。

ちなみに自分のおすすめクリエイターは

Keijiro Takahashiさんです（どうでもいい） 

## 勇気を出して英語で検索する

え？英語わからん？

予測変換という相棒がいるじゃない

例えばJS おすすめライブラリ

と検索する人がいるかもしれない

Js Recommend Library

と検索してみよう。

いつも見る日本語とは

違った新鮮な情報が入ってくる。

海外の情報の方が出回りは早いし進んでいる。

日本語検索を悪くいうつもりではないが

プログラミングや、技術の分野においては覆らない事実である

いくら調べても日本語では書かれてないエラーの対策方法が

外国圏のコミュニティでは既知のバグとして知られていて

対策方法がきっちり書かれてあったり

外国人がリークしたライブラリがかなり実用的だったり。

HowTo動画だったら場合によっては日本語字幕を付けることも可能だったり

良い情報の宝庫である。

海外がITの最先端であるし、先駆者がいるのはもちろん

プログラミング人口も圧倒的に多いため当たり前だ。


英語の勉強にもなるし,世界の情報もリサーチできる。一石二鳥だ。

## ChatGPTは？

# おすすめできない

導入部分で導入方法を体系的に理解するには

説明がわかりやすくて向いている。

だが.....

初歩的なコードでさえもGPTは中身のロジック正しく理解していない時もある。

コードは正しいが、解説してと頼んだらしっかり理解していない時もある。

最新のライブラリの仕様変更も理解していない

マニアックな情報などもってのほかだ。

しかも2021年のデータまでしか学習していない。

絶対頼るな。初心者のうちは良いが

あいつが喋る内容は調べたら

すぐ出てくるものが多いし時間の無駄。

あくまで調べるのが面倒くさい人向けの効率化ツール。

本格的に調べたいなら自分で調べる。

調べ方が分からんならその調べ方を調べるんや

そっちの方が長い目で見れば効率的である。
VSCodeでMakefileを編集するときにTab文字が入力されるようにする

# はじめに
MakefileをVSCodeで編集した後に、makeコマンドを実行すると以下のエラーが出ました。
```
Makefile:6: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.
```
VSCode上でTab文字がスペースに置き換わっていることが原因です。
# 解決方法
- Windows:`Ctrl + Shif + P` ,(Mac `command + shit + P`)でコマンドパレットを開きます
- `Preferences: Open Settings(JSON)`を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3289319/2727e2fa-fae3-687c-61c8-8040fa8b4416.png)
- settings.jsonを以下のように編集します
```json
 {
    "[makefile]": {
        "editor.insertSpaces": false,
        "editor.detectIndentation": false
    },
}
 ```
# 参考記事
https://qiita.com/y-w/items/614843b259c04bb91495

https://qiita.com/tatsuyayamakawa/items/df7e5b1b0d7c336af124

https://stackoverflow.com/questions/34937092/why-does-visual-studio-code-insert-spaces-when-editing-a-makefile-and-editor-in
Requestクラスについて（Laravel）

## 初めに
Requestクラスをよく使用するので、メモとして残します。

## 環境
| 開発環境   |バージョン    |
|-----------|------------|
| __Laravel__ | 10 |

## Requestファイルを作成する
```terminal:
php artisan make:request Hogehoge 
```

## Requestクラス説明
```php:HogehogeRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class Hogehoge extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool // ユーザーがこのリクエストを行う権限があるかどうかをチェックする。
    {
        return false; // trueでよく使う
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
     */
    public function rules(): array // バリデーションのルールを定義することができる。
    {
        return [
            // 例
            user_id = required|integer,
        ];
    }

    // バリデーションが成功した時に実行されるメソッド
    public function passedValidation(): void
    {
        // バリデーションが成功した時に実行したい処理
    }
}
```

## Controllerでの使い方
```php:HogehogeController.php

use App\Http\Requests\HogehogeRequest;

    /* 省略 */

    public function RequestTestMethod(HogehogeRequest $request)
    {
        Log::debug($request->all());
    }
```


## 最後に
最後まで閲覧いただきありがとうございました。
ご意見、ご指摘ありましたら、コメントお願いいたします。
Yoast Duplicate Postのエラー解決方法

# Yoast Duplicate Postのエラー解決方法
ブログで記事を複製するプラグイン（Yoast Duplicate Post）でエラーが出ていたので解決方法をまとめます。

&emsp;
## エラー内容

出力されるエラー内容はこんな感じ。記事が1つしかないのにずっと複製されたやつもあるでと言われる。
![スクリーンショット 2023-08-24 0.09.49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/f404aa9a-8146-b029-0ec4-b3e14b7e0170.jpeg)





```
この投稿の複製が作成されました。この投稿に加えた変更は、複製版が再公開された際に置き換えられることに注意してください。
```


&emsp;

## エラー原因
海外ニキいわく、記事を複製する際に元の投稿のメタフィールドもチェックしているようでその残骸がデータベース上にゴミとして残ってるのが原因っぽい。

https://wordpress.org/support/topic/cant-get-rid-of-duplicate-post-was-created-cant-edit-url-slug/

https://wordpress.org/support/topic/rewrite-republish-option-missing-on-one-post/

https://wordpress.org/support/topic/the-rewrite-and-republish-is-missing-for-a-specific-page-only/

&emsp;

## エラー解決方法

データベースからゴミを削除すればよい。編集前には必ずバックアップをとる。特に詳しくない方は慎重に。

自分はXserverなので、サーバパネル→データベース→phpmyadminに移動して、MySQLユーザでログイン。

ご自身のサイトのデータベースのテーブル名の「wp_postmeta」まで移動して、対象の「meta_key」をぽちぽち検索するか、SQLのSELECTコマンドで「meta_key」w検索する。エンジニアながらSQLを初めて使っていい勉強になった。オラクルも勉強したいなー
&emsp;

### SQLの場合
検索はSQLでいいけど、削除は対応する数が少ないと思うのでGUI画面をぽちぽちのがよさそう
```
SELECT * FROM `wp_postmeta` WHERE `meta_key` = '_dp_has_rewrite_republish_copy'
```

&emsp;
### GUI画面をぽちぽちやる場合
ご自身のサイトのデータベースのテーブル名の「wp_postmeta」まで移動し、検索タブから「meta_key」のカラムの値を「_dp_has_rewrite_republish_copy」で検索。演算子は「＝」にする

![スクリーンショット 2023-08-24 0.18.24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/2aa801d0-6bb3-8b55-41e4-de6276ad64a6.jpeg)

&emsp;
原因のmeta_keyが表示されるので、「post_id」の記事IDとエラーを消したい記事IDが一致していることを確認したら、「削除」をクリックして、完了

![スクリーンショット 2023-08-24 0.14.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/0c888c76-b9e6-8081-94da-1f9ebfcb0764.jpeg)

以上！
CKAD) Init Container

https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

- アプリ（本番）コンテナの実行前にすでに動作するコンテナ
- アプリ（本番）コンテナが実行する前に事前作業が必要の場合、利用する
- Init Containerがすべて実行された後、アプリ（本番）コンテナを実行
  - Init Containerはいつも完了を目標として実行される
  - 各Init Containerは次のInit Containerが実行する前に完了されるべき
  - PodのInit Containerが失敗したら、Init Containerga成功するまでリランする

```k8sホームページのInit-Container例.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  containers: # Init container が実行完了になったら実行される
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers: # 記載された順番に実行する 
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
```
Postbotでお手軽AIテスト生成

## はじめに
Postmanではコードを生成してくれるAIコンパニオンの **Postbot** が2023年7月にベータ版としてリリースされました。
ベータ版のため、まだまだ不安定な部分もありますが、テスト生成やレスポンスの視覚化など工数の多い作業を代行してくれるため、生産性UPに役立ちそうです。

## Postbotの使い方
個人プランを使用している場合は、何もせずとも使用できます。
APIを開いて**Tests**タブを開くと右にあるボタンからPostbotのウィンドウが開けます。
![Postbot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/4b7f5108-141e-ae4c-4a8f-5516c7c61007.png)

開いたウィンドウにChatGPTのようにプロンプトを入力することで、Postbotを使うことができます。デフォルトでいくつかのプロンプトが用意されており、それを使うことで機能を試すこともできます。
![スクリーンショット 2023-08-23 23.15.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/561892a3-c856-0e56-fff5-78dd4427021f.png)

:::note info
Postmanは英語しかサポートしておらず、用意されているサンプルのプロンプトも英語です。しかし、Postbotに使用されているAIは日本語にも対応しているようで、プロンプトを日本語で書いても一応は理解します。（英語に比べると結果が不安定です）
:::

## テストの生成を支援
Postbotはテストの生成に便利です。テスト生成のプロンプトを入力すると、AIが実際にAPIを叩いて、リクエストやレスポンスなどの情報を得ることで必要なテストを作成します。完璧なテストではないですが、生成されたテストを修正するだけである程度の品質は担保できるので工数の削減には十分です。

Postbotでテストを生成するには「Add tests to this request」をクリックし右上の実行ボタンを押すだけです。
![Add tests to this request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/fa4ba3cb-6f75-39b1-dc8e-f1abddf9cf9e.png)

テストが生成されると自動でAPIを実行します。
生成されたコードはTestsタブに記述されます。テストの実行結果はレスポンスの**Test Results**で見ることができます。
![テスト結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/d9ec8dd1-b777-b397-2aa3-df6f85edfcfc.png)

もし追加のテストが必要なら「Add more tests」をクリックすればプロンプトが追加され、更にコードが生成されます。


## コレクションのテストをまとめて生成
コレクション内のAPIのテストをまとめて生成することもできます。
コレクションの右の3点リーダーをクリックし、BETA版のGenerate testsを押下します。
![コレクション　テスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/3694b485-3fea-e05d-5c02-a1343ff65bbb.png)

テストが生成されると一覧が表示されます。右上の「Generate Tests」をクリックすることですべてのテストが実行され、結果が表示されます。
![コレクション　テスト　結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/8419c355-4cbf-f3a8-8ef5-32b8755d051b.png)


## レスポンスを可視化
Postmanにはレスポンスを視覚化する**Visualizer**という機能が存在します。
HTMLでテンプレートを用意し、レスポンスデータを入れることでグラフや表のような形にレンダリングすることができます。
[Postman | Visualizing responses](https://learning.postman.com/docs/sending-requests/visualizer/#accessing-data-inside-the-template)

Postbotを利用することでレスポンスを容易に視覚化することができます。
やり方はテストの生成と同じで、プロンプトのサンプルの「Visualize response...」を選択するだけです。次に表示される「...as table」「...as line chart」「...as bar graph」で表・折れ線グラフ・棒グラフを選択することも可能です。

画像は気温の取得するAPIを「Visualize response as line chart」で視覚化した結果です。
![気温 折れ線グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933439/157729a0-b018-3ea6-b59c-9d20c79a4a66.png)

---
[Postman | Introducing Postbot](https://blog.postman.com/introducing-postbot-postmans-new-ai-assistant/)
応用情報技術者試験　合格記

# はじめに
もともと2022年の夏の時点で秋に基本情報を受ける予定でしたが、勉強をはじめてすぐのころに諸事情により2023年春まで先送りすることとなったため、せっかくなら基本情報を飛ばして応用情報に挑戦してみようと思い勉強を始めました。

私は非IT系企業の社会人2年目で、修士は情報系ですが学部は非情報系で、ITパスポートや基本情報などの資格も持っていないため応用情報に出題されるような情報系の知識はほとんどありませんでした。ただし、趣味で競技プログラミングをやっており、AtCoder青なので、アルゴリズムやデータ構造に関する理解だけは多くの人よりもあるかと思います。

# 試験勉強
午前・午後ともに参考書等は購入せず、[過去問道場](https://www.ap-siken.com)だけをやりました。

## 午前
過去問道場をとにかく解きました。片道1時間以上ある通勤の間暇だったので、ずっと過去問道場をポチポチやってました。土日はあんまりやってません。

全部の問題を埋めるという気持ちでやっていたので、過去問道場にある現行試験の問題は、全部1回ずつは解いているはずです。ちなみに過去問道場の段位は六段です。

勉強を始めたばかりのときは、ほとんどの問題が解けなかったので、わからなかった問題については問題文や選択肢、解説などに登場する単語を検索していました。正解した問題についても、他の選択肢に知らない用語があった場合などはそれを調べるようにしていました。

その甲斐あって、勉強を始めたばかりの頃は4～5割程度の正答率だったのが、1か月後には合格点の6割、2か月後には7割、3か月後には8割をほぼ安定して取れるようになりました。回によっては事故りますが、2か月後以降は事故った回も含めて合格点を下回った記憶はないです。本番は事故りました。


## 午後
午前で8割取れたらやると決めてたので、午前で初めて8割を超えてから勉強を始めました。時間がない方はもう少し低くても良いかと思います。

午前で8割取れる実力がついていたので、問題文を読んでも何を言っているかわからないということはあまりありませんでした。「**頑張って読んで、それっぽい答えを書く**」を繰り返します。

午後問題は結構独特なので、勉強というよりもむしろ慣れが必要だと思います。特に、文で回答するタイプの問題は、字数制限が結構厳しいので注意が必要です。たとえば、「なぜエラーが起こったのか説明せよ」という問題の回答として「デッドロックが発生し、それ以降の処理が行われなかったから」というのが思いついたときは「デッドロックが発生したから」とだけ書けばよかったりします。**重要なキーワードだけ入れてあとは削る**というのを意識すると字数制限に引っかからずに回答できると思います。

あと、午後問題はすべての分野を解く必要はなくセキュリティ＋残り4分野選択なので、得意なやつを5，6分野ほどみつけておいてそれに絞って勉強すると良いと思います。

また、私はやらなかったのですが、時間を測って試験1回分を解く（鉛筆で紙に書く）というのを1度はやってた方がいいです。本番は鉛筆で大量に文を書かないといけないので、結構疲れます。それを考慮して解くスピードを上げる必要があります。

# 試験本番
## 準備
事前に持ち物をよく確認し、忘れ物がないようにしましょう。私は当日の朝に証明写真を撮りました。腕時計も当日購入しました。朝に準備することが多いと遅刻や忘れ物のリスクが上がるので、前日までに確実に準備しましょう。

## 午前
IPA試験のの午前問題は使いまわしが多いと言われていますが、私が受けた回は応用情報以外の区分の過去問からの使いまわしが多かったそうで、私は応用情報の問題しか解いていなかったので結構初見の問題が多かったです。かなり焦りましたが、選択肢の中に知ってる単語を見つけて消去することで対応しました。

## 昼休憩
眠かったので、エナジードリンクを購入して飲みました。
この時点で午前の解答速報を発表している企業や個人もいます。気になるかもしれませんが、ここで見るのはおすすめしません。午後試験に集中しましょう。

## 午後
私はシステムアーキテクチャ、プログラミング、情報システム開発、組み込みシステム開発を選択しました。プログラミングはもともと得意、組み込みは過去問が割と解けてたのでこの2つは受験前から解くことを決めていて、あとの2つは問題をさらっと見て解けそうなやつを選びました。

ちなみに、応用情報の午後では、特定分野しか解けない人を落とすためなのか知りませんが、毎回**ランダムに1～2分野で激ヤバ問題が出題される**ことが知られています。(私が受けた回(令和5年春期)はプログラミングが激ヤバ回でした。ですが、私は青コーダーなので全問正解しました。) 一般的には、**得意分野であっても激ヤバ回だと感じたら避けることをおすすめします。**

## 試験後
大体午前は終わった直後、午後は試験の3日後ぐらいに解答速報が出ました。ここで自己採点はしてもしなくてもよいですが、合格発表まで2か月以上あり気になって人生に集中できなくなってしまいそうなので、私は自己採点をした方が良いと思います。私は自己採点の様子をTwitterスペース(当時の名称)で配信しました。午前は60/80(75%), 午後は結構厳しめに付けて75%でした。どちらも合格点を超えており安心しました。

# 合格発表
自己採点で合格点を大きく超えていたので、やっぱり合格したという感じでした。先述の通り、試験から発表までが結構長かったので、やっとかという気持ちが大きかったです。私の実際の点数は午前が76.25、午後が86.00でした。午後は自己採点より大きく超えています。午前がずれているのはよくわかりませんが、私が見た解答速報が間違ってたのかもしれません。

ちなみに、公開直後は1時間ぐらいサイトが重くて全く見れなかったので、公開時刻になった瞬間に結果を見るようにしましょう。バトルに負けた方は、時間を無駄にしないためにおとなしく1時間待ちましょう。

# おわりに
応用情報は難しい試験ですが、過去問埋めによるゴリ押しでも割となんとかなる試験だと思いました。受験を考えている方、受験を控えている方の参考になれば幸いです。
laravel 独自のヘルパ関数を定義してみる

# 概要

- 独自ヘルパ関数の定義方法を簡単にまとめる。

# 前提

- 今回は「すべての階層の配列のキーをスネークケースからキャメルケースに変換する関数」をユーザー定義の独自ヘルパ関数として定義してみる。

# 方法

1. app/Helpers/helpers.phpファイルを作成し、下記のように記載する。

    ```app/Helpers/helpers.php
    <?php
    
    declare(strict_types=1);
    
    use Illuminate\Support\Str;
    
    /**
     * 配列のキーをすべてスネークケースからキャメルケースに変換
     *
     * @param array<mixed> $array
     * @return array<mixed>
     */
    function arrayKeysToCamelCase(array $array): array
    {
        $camelCaseArray = [];
        foreach ($array as $key => $value) {
            $camelCaseKey = Str::camel($key);
        
            // 再帰的に本関数を呼び出し
            if (is_array($value)) {
                $value = arrayKeysToCamelCase($value);
            }
        
            $camelCaseArray[$camelCaseKey] = $value;
        }
    
        return $camelCaseArray;
    }
    ```

1. composer.jsonの`autoload`に`files`を追記してhelpers.phpを指定する。

    ```composer.json
    "autoload": {
        "files": [
            "app/Helpers/helpers.php"
        ],
    ```

1. 下記コマンドを実行してオートロードを行う。

    ```shell
    composer dump-autoload
    ```

1. `$ php artisan tinker`でtinkerを起動し、`arrayKeysToCamelCase()`を実行しundefinedにならないことを確認する。
過酷なデスクワークからわいの身体を守るアイテムたち

締め切り直前に👇に投稿してみるやつ

https://qiita.com/official-events/8644e9719b0040cc1817

# はじめに

毎日毎日椅子に座り机に向かって仕事をしていれば身体にダメージが蓄積されていくでしょう。私も毎年のようにぎっくり腰になるようになってしまいました。リモートワークにより仕事の環境も変わってきました。自宅で仕事をするに当たり新たに気をかけなければならないことも生まれてきたでしょう。そんな中で私が実際に身体を守るために使用しているアイテムを紹介する、そんな記事です。

他の皆様たちの投稿を見るとかなりイケイケなガジェットが紹介されている中でアナログ（？）で趣の異なるガジェットばかりですが変化球として生暖かく見てください。

（想定されているガジェットでなくレギュレーション違反にならないことを祈るばかりです🙏）

# MAMO（マモ）

https://mamo-official.jp/

https://www.amepla.jp/c/mamo/393

数年前にハンズかどこかで見かけて衝動買いして以来使っています。抱いて使っても背中にあてて使っても良いようです。初代は背中にあてて使っていましたが酷使しすぎたのか圧が強すぎたのか腕がもげてしまったので2代目は抱いて使ってます。

クッションとしての使用感は普通（にあると楽）ですが、なんとも言えない(゜-゜)の表情による癒やし効果が高いです。

あと[購入サイト](https://www.amepla.jp/c/mamo/393)のオフィスでの集団での使用イメージが面白すぎるので推せます。

https://www.amepla.jp/c/mamo/523

手首用のミニマモもあります。手に巻きつけて使ったりスマホ立てになります（スマホ立てになるのは今回調べて初めて知った←）。**手に巻きつけると(゜-゜)が見えないので我が家のデスクではインテリアとして飾られています。**

# バンダナキャップ

リモートワークに伴いヘッドセットを装着する時間が増えたことによる影響なのかどんどん頭が凹んできている気がしています。私のヘアスタイルは坊主スタイルなのですがより凹みが目立つ気がします。毛根にも悪いような気がするので自宅で仕事をするときには頭を防御するためにバンダナキャップを被るようにしています（大真面目です）。

着用した姿についてはビッグダディや長渕をイメージしてもらえればだいたい合ってると思います。結局のところ上からヘッドセットを装着しているので Teams などでオンラインミーティングするときもあまり目立たずに変に思われないです。（と自分は信じています）

# ヘルシープログラマ

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

参考記事に書籍もあったので、折角ということで。

私がこの本をお気に入りなのは、目次のタイトルを見てもらえれば伝わるかと思いますが、プログラマが見たらフフッとなるような表現や言い回しがされているところです。読んでみると、そのような遊び心はありつつも、内容そのものは実用的なところもかえって面白さが増す要因です。

プログラマの健康に対して実用的な内容やHACKがプログラマ語で書かれているので単純に読み物としてやその存在が面白いと思ったのでオヌヌメしています。

# 最後に

これは人それぞれだと思いますが、私はコロナ禍のフルリモート生活により身体的にも精神的にもボロボロになってしまいました。現在はハイブリッドな勤務形態ですが、そんな経験もあるのでゆるふわなグッズを使ったり奇抜なバンダナスタイルで仕事をしたりなるべく楽しく仕事をするようにしています。

あとなんだかんだ外に出て身体を動かすのが最強
Leetcode 767. Reorganize String

https://leetcode.com/problems/reorganize-string/description/

#### アプローチ
- MaxHeap

```java
class Solution {
    public String reorganizeString(String s) {
        // 各Charの回数をもつHashMap
        HashMap<Character, Integer> hashMap = new HashMap<>();

        
        PriorityQueue<Character> maxHeap = new PriorityQueue<>((a, b) -> hashMap.get(b) - hashMap.get(a));

        for (char c : s.toCharArray()) {
            hashMap.put(c, hashMap.getOrDefault(c, 0) + 1);
        }

        for (char c : hashMap.keySet()) {
            maxHeap.offer(c);
        }

        // 結果の保存するために宣言
        char[] result = new char[s.length()];
        int resultIndex = 0;

        char maeNoChar = 0;

        while (!maxHeap.isEmpty()) {
            char nowCh = maxHeap.poll();
            int nowChCount = hashMap.get(nowCh) - 1;
            hashMap.put(nowCh, nowChCount);

            result[resultIndex++] = nowCh;

            // 前のCharに保存しなかった場合、MaxHeapに値が入ってこない
            // maxHeapの長さが0になればWhile文が終了になる
            if (maeNoChar > 0) {
                maxHeap.add(maeNoChar);
            }

            if (nowChCount > 0) {
                // 現在持ってきたCharの残っている数があれば、前のCharに保存する
                maeNoChar = nowCh;
            } else {
                // 現在持ってきたCharの残っている数がなければ、前のCharに保存しない
                maeNoChar = 0;
            }
        }

        // 前回の Charが残っている状態でWhile文が終了になるので、MaeNoCharが0でなはい
        if (maeNoChar != 0) {
            // 条件達成してないので空文字を返す
            return "";
        }

        // 条件達成しているのでで文字を返す
        return new String(result);
    }
}
```


#### 動画を参考しました
https://www.youtube.com/watch?v=2g_b1aYTHeg
プログラミング初心者の医学生が残り少ない夏休みでGithubcopilotとchatGPTの力を借りてアプリ開発してみた Day4

# これまでの経過
* [Day1(2023/08/20)](https://qiita.com/Shigemaxxx/items/606e7e58fe83f98bb780)
* [Day2(2023/08/21)](https://qiita.com/Shigemaxxx/items/ab1f0aecc291bb77534d)
* [Day3(2023/08/22)](https://qiita.com/Shigemaxxx/items/39ab4b0876cb6849fcf3)
   > - [x] 1. アイデアと計画
   > - [x] 2. DartとFlutterの学習
   > - [x] 3. 開発環境のセットアップ
   > - [ ] 4. デザインと開発
   > - [ ] 5. テスト
   > - [ ] 6. UIとUXの改善
   > - [ ] 7. アプリアイコンとアセット
   > - [ ] 8. ローカライゼーション
   > - [ ] 9. バックエンドとAPI
   > - [ ] 10. ベータテスト
   > - [ ] 11. App StoreとGoogle Playの開発者アカウント
   > - [ ] 12. アプリの提出
   > - [ ] 13. アプリレビュープロセス
   > - [ ] 14. アプリのリリース
   > - [ ] 15. マーケティングとプロモーション
   > - [ ] 16. モニタリングとアップデート 

# DAY4(2023/08/23)
SDKはダウンロードしているはずなのによくわからなくなったので，一度SDKをアンインストールし，再度インストールするとSDKの問題は解決しました．
![スクリーンショット 2023-08-22 23.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532964/043c167a-c364-abce-0ff0-889b768a5cb4.png)
PATHもよくわからなくなっていたので，最初っからやり直した．
昨日，今日で学んだことは，
### システムをいじったときには再起動する
です．どうやら，システムは再起動しないと反映されないみたいで，そこで時間を無駄に使ってしまった．
今日はもう体力の限界．
全然プログラミングの中身に入れなかったが，明日こそはプログラム的なことをやりたいと思う．
独学でプログラミングをすると，行き詰まったときにどうしていいかわからず時間だけが過ぎていってしまうことがもったいない．と思っていたら，Qiitaの中で質問できるようで，こんな超初心者の質問をやっていいのか分からないが，利用できるものは利用していこうと思う．













今日の進捗は...
   > - [x] 1. アイデアと計画
   > - [x] 2. DartとFlutterの学習
   > - [x] 3. 開発環境のセットアップ
   > - [ ] 4. デザインと開発
   > - [ ] 5. テスト
   > - [ ] 6. UIとUXの改善
   > - [ ] 7. アプリアイコンとアセット
   > - [ ] 8. ローカライゼーション
   > - [ ] 9. バックエンドとAPI
   > - [ ] 10. ベータテスト
   > - [ ] 11. App StoreとGoogle Playの開発者アカウント
   > - [ ] 12. アプリの提出
   > - [ ] 13. アプリレビュープロセス
   > - [ ] 14. アプリのリリース
   > - [ ] 15. マーケティングとプロモーション
   > - [ ] 16. モニタリングとアップデート 

今日は何も進みませんでした．申し訳ないです．プログラミングにかけられる時間をもう少し増やしたい...
今日はここまで．
他に必要なことやアドバイス等ありましたらぜひコメントにて教えてください．
Git 誤ってまだコミットしたくないファイルをコミットしてしまったときの対処法（Push前）

# 概要

- Gitにて、Push前にまだコミットしたくないファイルを誤ってコミットしてしまい、誤ってコミットしたファイルを取り除きたいときの方法をまとめる。

# 前提

- 誤ってコミットする前で下記の様な状態だったとする。

    ```
    modified:   file_A
    new file:   file_A_test
    modified:   file_B
    new file:   file_B_test
    modified:   file_1
    modified:   file_1_test
    ```

- 「file_1」と「file_1_test」以外を先にコミットしたかった。
- しかしながら上記のすべての内容を誤ってコミットしてしまった。
- 誤ってコミットしてしまったことにpush前に気がつけた。

# 方法

1. 下記コマンドを実行してローカルリポジトリの状態を最新の状態に戻す。

    ```shell
    git reset --soft HEAD~1
    ```

1. 下記コマンドを実行して「file_1」と「file_1_test」をステージから下ろす。

    ```
    git reset HEAD file_1
    git reset HEAD file_1_test
    ```

1. コミットを行う。
【Next.js】ページ遷移時に特定の処理を実行する方法


AppRouterでは`router.events`はサポートされていません。

以下の方法でページの変更ごとに処理を行うことができます。

```js:app/_components/navigation-events.js
'use client'
 
import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
 
export function NavigationEvents() {
  const pathname = usePathname()
  const searchParams = useSearchParams()
 
  useEffect(() => {
    const url = `${pathname}?${searchParams}`
    console.log(url)
    // URLが変更された際に実行される処理
  }, [pathname, searchParams])
 
  return null
}

```

上記を`layout.js`に記述します。

```js:app/layout.js
import { Suspense } from 'react'
import { NavigationEvents } from './components/navigation-events'
 
export default function Layout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
 
        <Suspense fallback={null}>
          <NavigationEvents />
        </Suspense>
      </body>
    </html>
  )
}
```
M5StickCPlusでマルチスレッド処理を実行してみた話。

# 目的
M5StickCPlusでジャイロの値を取り続けながら、LEDを制御してみる。

# ハード・ソフト
- M5StickCPlus
- MacStudio(2022)
- VSCode(PlatformIO)
- IC(IOエキスパンダ：MCP23017)

# 機能の説明
　今回作っていくのはM5StickCPlusにてジャイロ関連の測定を行い、結果をもとにLEDの点滅動作を制御する機能です。
以前にジャイロデータの取得、LEDの点灯に関しては記事にしておりますので興味があれば参考にどうぞ。

https://qiita.com/Moore_Ca/items/58b1cbbbb4af73fb36fa

https://qiita.com/Moore_Ca/items/1cf0226db8b1f0474f81

# 実際のコード
　マルチスレッドに関係のない箇所は記事の末端にまとめて記載しますので、いきなりマルチスレッドの部分から入ります。
今回はM5StickCPlusの別コアを用いたマルチスレッド処理になりますが、システムを通して以下の記事を参考に組み立てております。

https://qiita.com/kotai2003/items/6a4d620a51ca0f1535dc

上記の記事を読んでいただければわかりますが、以下のような関係でM5は起動しています。
~~~c++
void function0(){
    //関数　呼び出されない限りは読み込まれない。
}

void setup(){
    //最初に読み込まれる。
    //値などの設定を行うことが多い
}

void loop(){
    //setup()の次に読み込まれる。
    //この箇所に記載されたコードは終了までループする。
}

void function1(){
    //関数　呼び出されない限りは読み込まれない。
}
~~~

ここで重要なのはsetup()とloop()ですね。

要はsetup()の段階でスレッドを作成して並列処理をさせておけば、loop()の裏側で処理を行ってくれるわけです。
では、function0()を裏でループさせるコードを書いてみましょう。

~~~c++
#include <M5StickCPlus.h>

void function0(void* arg){
    while(1){
        //ここの処理をループします。
    }
}

void setup(){
    xTaskCreatePinnedToCore(function0, "Function_0", 4096, NULL, 1, NULL, 1)
}

void loop(){
    //ここの処理をループします。
}
~~~

さて、何やらsetup()に見慣れない一文が書かれていますね。
参考にさせていただいた記事から引用させていただきますが、このような内訳になっているそうです。
~~~c++
xTaskCreatePinnedToCore(タスクの関数名, "タスク名", スタックメモリサイズ, NULL, タスク優先順位, タスクハンドリングポインタ, Core ID)
~~~

https://qiita.com/kotai2003/items/6a4d620a51ca0f1535dc

というわけでfunction0()を並列処理させたければどのコアでどれほどの優先順位のどれほどの大きさのメモリにてどのタスクを実装したいのかを記載する必要があったわけですね。

以上のようなコードを書いた上で実行すれば、M5は二つのループを同時に行えるようになったというわけです。

### ジャイロ、LEDも実装した場合のコードのgithub

https://github.com/iput2021-moore/Seminar_Drone/tree/main/Control_team/0822_M5_gyroLED/src
Dockerの仕組み

# Abstract
Dockerの仕組みの理解、Docker特有の問題に対する解決の助けになるような箇条書き的な情報、ケーススタディなどを記す. 

この記事は技術初心者向けである.

この記事はDockerの成り立ちを体系的に記したものではない. 
# Dockerのコンテナではlocalectlは使えない
- localectlは、「systemd」というものによって起動されたシステムでのみ使えるコマンドである -> [参考文献](http://lfsbookja.osdn.jp/10.0-sysdja/chapter09/console.html)
- そして、Dockerではsystemdは使えない->[参考文献1](https://engineering.nifty.co.jp/blog/6523),[参考文献2](https://note.com/shift_tech/n/n2321a3628a81)
- よって、Dockerでlocalectlは使えない
- しかし、特別なbuild方法を指定することでdockerコンテナでもsystemdを使う方法がある(上の参考文献1,2を参照)
- systemdについての記事-> https://qiita.com/bluesDD/items/eaf14408d635ffd55a18


# DockerのvolumeはホストOS上にはない(Linux以外の場合)

[参考文献 1](https://gumfum.hatenablog.com/entry/2021/05/03/120000)
[参考文献 2](https://qiita.com/notakaos/items/b08ba7166bb5b56576a1)

- 使用するPC(ホストOS)がLinuxの場合、問題はない. しかし、PCがWindowsとMacの場合、上の問題が発生する.
- 一言で言うと、そもそもDockerというソフトはLinux上でしか動くことが出来ない不思議なソフトウェアである
- そのためWindowsやMacで使用するにはまずLinux仮想マシンを設置する必要がある。そのLinux仮想マシンの作成はWindowsやMacにDockerをインストールしたときに、インストーラーが裏で自動的にやってくれる。
- 従って、dockerの操作は、あたかもMacのターミナルやwindowsのコマンドプロンプトでやってるように見えるが、実はそれは見せかけで、Macのターミナルに打ち込まれたdockerコマンドは一度Linux仮想マシンに渡されて、それをdockerに渡している。
- 従って、dockerコマンドで作成したボリュームも例に漏れず、Linux仮想マシンのディレクトリに保存される。作成したボリュームの表示ディレクトリはホストOSのディレクトリとは全く関係ない
- ホストOSからvolumeにアクセスしたければ、Macの場合は以下のコマンドを実行すればよい:

```bash
nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock 
```
- Windowsの場合は、エクスプローラーの窓に `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes` と入力するとアクセスできる([参考文献](http://ogawa.s18.xrea.com/tdiary/20210312p02.html))

# Dockerのコンテナ内のcentosでlocalectlコマンドは実行不可能

https://qiita.com/ponsuke0531/items/c640fdafc744c5f55c6b
ddコマンドのステータス出力を消す方法

## はじめに

`dd` コマンドを実行すると以下のようなステータスが出力されます。一般的には正常終了したときにはこのような出力は行わないのが Unix の流儀ですが `dd` コマンドは変わったオプションの書式（JCL の流儀を踏まえているらしい）で、それもあってか正常終了でもステータス出力が標準エラー出力に出力されます。この記事ではこの出力を消す方法をまとめました。

```console
【英語の場合】
$ dd if=/dev/urandom of=./random.bin bs=1k count=1
1+0 レコード入力
1+0 レコード出力
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00074 s, 1.4 MB/s

【英語の場合】
$ dd if=/dev/urandom of=./random.bin obs=10 bs=1k count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00074 s, 1.4 MB/s
```

## status=none を使う

一般的な方法は `status=none` を使います。非表示になるのはステータス情報のみで、エラーメッセージは出力されます。

```console
$ dd if=/dev/urandom of=./random.bin bs=1k count=1 status=none
```

参考ですが `status=noxfer` を指定すると、一番最後の転送情報のみが非表示になります。

```console
$ dd if=/dev/urandom of=./random.bin bs=1k count=1 status=noxfer
1+0 records in
1+0 records out
```

ただし `status` オプションは 2012 年頃の GNU coreutils、2014 年の FreeBSD 9.3 以降、2015 年の OpenBSD 5.5 以降、OpenIndiana の少なくとも 2023-05 版で利用可能ですが、**NetBSD 9.3、Solaris 11 で非対応**で POSIX でも標準化されていないので注意してください。

## POSIX で標準化された範囲で実装する

`status=none` に対応した環境であれば、それを使うのが楽ですがそうでない環境でやるにはどのようにしたら良いでしょうか？ 一番簡単なのが標準エラー出力を `/dev/null` に捨てる方法です。

```console
$ dd if=/dev/urandom of=./random.bin bs=1k count=1 2>/dev/null
```

この方法はたしかにステータス出力を消すことができますが、エラーメッセージまでも消してしまうのでよくありません。

```console
$ dd if=/dev/no-such-file of=./random.bin bs=1k count=1 2>/dev/null
$ echo $?
1    ← エラーになっている

【本来ならこのようなエラーが出力される】
$ dd if=/dev/no-such-file of=./random.bin bs=1k count=1
dd: failed to open '/dev/no-such-file': No such file or directory
```

エラーになったときだけエラーメッセージを出力したいので、次のような回避策を実装しました。これをシェルスクリプトの冒頭に入れておくだけでステータス出力を消すことができます。

```sh
# dd シェル関数（ラッパー）で本来の dd コマンドを置き換える
dd() {
  # 標準出力はファイルディスクリプタ3 経由で迂回して出力し
  # エラーメッセージは標準出力経由で変数にキャプチャしている
  (
    # command でシェル関数をバイパスして元の dd コマンドを呼び出す
    err=$(command dd "$@" 2>&1 >&3) && : # 「&& :」は set -e でも機能させるため
    ex=$?
    # エラーのときだけ標準エラー出力にエラーを出力する
    [ "$ex" -eq 0 ] || echo "$err" >&2
    exit "$ex"
  ) 3>&1
}

# ステータスは出力はされない
dd if=/dev/urandom of=./random.bin bs=1k count=1
# => なし

# エラーメッセージは出力される
dd if=/dev/no-such-file of=./random.bin bs=1k count=1
# => dd: failed to open '/dev/no-such-file': No such file or directory
```
ChromeとSafariでの入力欄の自動補完を無効にする方法

## 事象

Webサービスにログインする際、Chromeのメールアドレスとパスワードの保存機能を使用すると、意図せぬ箇所に情報が自動補完されることがあります。特に、会員登録画面などでこの現象が発生しました。

## 対処法

Safariの場合、該当の入力欄にautoComplete="off"を追加することで問題を解消できます。しかし、Chromeではこの方法だけでは効果がありません。Chromeの場合は、autoComplete="new-xxx"を使用することで解消できます。

```tsx
<input
  type={"email"}
  autoComplete="new-email"
/>
```

```tsx
<input
  type={"password"}
  autoComplete="new-password"
/>
```

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
【備忘録】クラスタリングについての簡単な整理

# 概要
最近データサイエンスやデータ分析を学習しているので、そこで学んだことを備忘としてここに書き残していこうと思います。
学習した順番は前後しますが、今回はクラスタリングについて学んだことを整理したいと思います。
学んだことを思い出しながら書いているので、間違ったことを書いていたらご指摘ください！

※最近効率の良い学習方法に「アクティブリコール」という物があると知り、早速実践をしていますw

# クラスタリングとは
クラスタリングとはデータの類似性に基づいてデータを自動的にグルーピングすることです。
人間がデータをグルーピングすると主観が入ったりして、データの偏りが発生してしまう可能性があります。（このような偏りをバイアスと言います。）

クラスタリングでは「自動的に」データをクラスタリングするので、グループ分けされたデータの塊を人間側でどういった意味があるのかを解釈する必要があります。
しかしそれによってデータに隠れている類似性や関連性を見つけることができたり、別の視点からデータにアプローチすることができたりします。

# クラスタリングのアルゴリズム
クラスタリングにはいくつか種類があるようですが、私が今回学習したのは「K-平均法(K-Means)」なので、こちらのアルゴリズムの概要について整理します。

以下がアルゴリズムの流れです。
- Step1: データの散布図にセントロイドを配置する
- Step2: セントロイドとデータの距離に基づいてセントロイドとデータを紐付ける
- Step3: 紐付けたデータの塊(クラスタ)を基に重心を求めて、重心にセントロイドを移動する
- Step4: 移動後のセントロイドとデータを再度紐付けしなおす
- Step5: セントロイドが動かなくなるまでStep2~Step4を繰り返す 

セントロイドの数=クラスタの数になります。
そしてクラスタの数は予め決める必要があります。
クラスタの数は決め打ちで決めても良かったりしますが、数学的にデータに対して最適なクラスタ数を求めることができます。
エルボー法や残差平均和というものを用いることで求められるようですが、今回は詳細については割愛します。

# Pythonでクラスタリングを実装する流れ
Pythonでクラスタリングを実装する時の流れについて簡単におさらいします。
流れさえわかればあとはググるなりChatGPTに聞くなりで実装できるかなと思いますので、具体的なコードは書きません。

1. データを読み込む(DataFrame型)
1. データをndarray型に変換する
1. クラスタリングのモジュールをインポートする
1. インスタンス化する
    1. クラスタ数を決める
    1. 乱数を決める
1. 2のデータに対してモデルの学習をする
1. 1のデータに学習後に算出したクラスタの値をマージする
1. クラスタの値の代表値を確認する
1. データを可視化しクラスタの特徴を確認し、解釈する


# まとめ
以上が今回学習したクラスタリング(K-平均法)の知識整理です。
要するにクラスタリングを用いることで、データ全体を見て類似性を基にデータをグループ分けできるようになります。その時に人間によるバイアスがかからないため、潜在的な関連性や類似性を見つけることに繋がり、新しい角度からデータを見ることができます。

主成分分析についてちゃんと理解できていないので、次回はそれについて学び直して備忘として書き殴ろうかと思います。

ではまた。
Unity EditTestでasync/awaitが使いたい

# はじめに

UnityのEditTestで`async/await`が使いたい！ということで使い方を調べました。

# やり方

大きく分けて２つあります。

* `[UnityTest]` + `UniTask.ToCoroutine`を使う
* UnityTestFramework 1.3.8以降を使う

## `[UnityTest]` + `UniTask.ToCoroutine`を使う方法

`[UnityTest]`（コルーチンベースのテスト）に`UniTask.ToCoroutine`を組み合わせることで、`async/await`をEditTestで利用できるようになります。

```cs
using System;
using System.Collections;
using Cysharp.Threading.Tasks;
using NUnit.Framework;
using UnityEngine.TestTools;

namespace TORISOUP.Tests
{
    [TestFixture]
    public class SampleTest
    {
        [UnityTest]
        public IEnumerator 非同期テスト() => UniTask.ToCoroutine(async () =>
        {
            await Task.Delay(TimeSpan.FromSeconds(1));
            Assert.AreEqual(1, 1);
        });
    }
}
```

### メリット

* UnityTestFramework 1.1.33（標準で導入されている安定版）で利用できる

### デメリット

* `UniTask`の導入が必要
* [TimeoutAttribute](https://docs.nunit.org/articles/nunit/writing-tests/attributes/timeout.html)が使えない

## UnityTestFramework 1.3.8以降を使う方法

### 事前導入

```js:manifest.json
"com.unity.test-framework": "1.3.8",
```

**UnityTestFramework 1.3.8はまだstableではないため非推奨パッケージとなっています。**
導入の場合は`manifest.json`を書き換えて`1.3.8`を導入する必要があります。


### 非同期テスト

UnityTestFramework 1.3.8以降であれば`[Test]`を使って`async/await`が記述できます。
（`[UnityTest]`では使えない）

```cs
using System;
using System.Threading.Tasks;
using NUnit.Framework;

namespace TORISOUP.Tests
{
    [TestFixture]
    public class SampleTest
    {
        [Test]
        public async Task 非同期テスト()
        {
            await Task.Delay(TimeSpan.FromSeconds(1));
            Assert.AreEqual(1, 1);
        }
    }
}
```

### メリット

* UniTaskの導入が不要
* [TimeoutAttribute](https://docs.nunit.org/articles/nunit/writing-tests/attributes/timeout.html)によりタイムアウトを指定することができる

### デメリット

* UnityTestFramework 1.3.8（まだ非推奨パッケージ）が必要


# 最後に

どちらもBatchModeで動かすときは`runSynchronously = false`である必要があります。

## 補足

EditTest + BatchMode の環境で、`UniTask.Delay`などを用いると`await`が完了せずに無限待機にハマる可能性があります（原因不明。起きるプロジェクトと起きないプロジェクトがある。）

そのためテスト上では `Task.Delay` を使ったほうが安全かも。

また無限`await`してしまうとタイムアウトまで180秒待たされることになるので、[TimeoutAttribute](https://docs.nunit.org/articles/nunit/writing-tests/attributes/timeout.html)を指定できるなら指定しておきましょう。
The project is using an incompatible version (AGP 8.0.0) of the Android Gradle plugin. Latest supported version is AGP 7.3.1 の解決法

# はじめに
ある日、Anroid Studioでプロジェクトを開くとビルドエラーが発生した。。。

```
The project is using an incompatible version (AGP 8.0.0) of the Android Gradle plugin. Latest supported version is AGP 7.3.1
```

https://developer.android.com/studio/releases?hl=ja#android_gradle_plugin_and_android_studio_compatibility

何やらバージョンの互換性に問題があるようだ。。

# 指定されたバージョンにしてみる
`File > Project Structure > Project`を開く
Android Gradle Pluginを**7.3.1**に変更したところ、無事ビルド成功しました！
![Screenshot 2023-08-23 at 22.37.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/32e2ddcc-3fd7-20e4-eb09-a813ad74fc69.png)
[UIKit] Push遷移したページをどこからでもスワイプで戻れるようにする

真ん中スワイプで戻る方法を模索するのに一苦労したので、備忘録として残しておきます。

# 実装
```Swift
import UIKit

final class NavigationController: UINavigationController {
    private let fullWidthBackGestureRecognizer = UIPanGestureRecognizer()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupFullWidthBackGesture()
    }

    private func setupFullWidthBackGesture() {
        guard
            let interactivePopGestureRecognizer = interactivePopGestureRecognizer,
            let targets = interactivePopGestureRecognizer.value(forKey: "targets")
        else {
            return
        }

        fullWidthBackGestureRecognizer.setValue(targets, forKey: "targets")
        fullWidthBackGestureRecognizer.delegate = self

        view.addGestureRecognizer(fullWidthBackGestureRecognizer)
    }
}

extension NavigationController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let isSystemSwipeToBackEnabled = interactivePopGestureRecognizer?.isEnabled == true
        let isThereStackedViewControllers = viewControllers.count > 1
        return isSystemSwipeToBackEnabled && isThereStackedViewControllers
    }
}
```
interactivePopGestureRecognizerで端スワイプを検知しているので、Objective-Cの黒魔術を使用し、GestureをPanGestureに置き換えることで画面上のどこからでもスワイプを検知できるようになりました。

# 使用方法
```Swift
let controller = NavigationController(rootViewController: HogeViewController())
present(controller, animated: true)
```

# さいごに
これで端スワイプではなく、真ん中スワイプでpopすることができました！
SwiftUIで使用するにはintrospectを使うとできます。
WordPressからWixへのHPリニューアル作業にやきもきした話

## 概要

今回とある企業様のHPをWordPressからWixに移行するという仕事をしました。
作業をする上でいくつか注意点などありましたので備忘として残しておきます。
また、作業を通して改めて気づいたWixの強みや弱みについても触れていければと思います。

## どういう状況だったか

まずリニューアル前にHPがどういう状況だったかをおさらいします。

【ドメイン】
お名前.comで取得済

【レンタルサーバ】
ロリポップ！で契約済

【CMS】
WordPressで管理

【課題】
・ITに特化した人材がおらずWordPressの管理に手が回せていない。
・ページのレスポンシブ対応もできていない。

このような状態だったため、初心者でも今後継続してメンテができるようにWixでのリニューアルを提案しました。

なお、本記事は提案時（2023年7月）の情報にも続いて執筆しているため、技術的な制約は今後解消される可能性があります。実際にWixをご利用する場合最新の情報を参照ください。

## 作業のポイント

### ページ構築の際の注意点

今回は既存のドメインをそのまま生かしてリニューアルすることが要件でした。つまりURLは変更しないということです。これはブックマークしていたページがある日突然「404 Not Found」にならないという意味でも親切ですし、公式LINEから各サービスへのリンクもそのままでよいので楽ちんです。

一方で気を付ける必要があるのが、WixではURLの指定の仕方に制限があるということです。

ストアやブログ記事以外では原則以下のように第２階層までしか指定できません。そのため元のHPに深い階層のページがある場合は、リダイレクトなどを仕込む方がよいでしょう。
参考：[SEO 設定でページの URL 構造をカスタマイズする | サポートセンター | Wix.com](https://support.wix.com/ja/article/seo-設定でページの-url-構造をカスタマイズする)

![スクリーンショット 2023-08-19 223634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/d326ff59-f142-a608-8690-63d3385fec3c.png)


リダイレクトはダッシュボード＞SEO＞リダイレクトマネージャーから設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/78af533d-1e90-bee9-aea4-4d40a6d1fc10.png)

### 切替時の注意点

ページの切り替えは以下の手順で進めます。

1. プランを有料のもに変更する。（多くの場合独自ドメインにして広告を消すはずなので）
2. 独自ドメインをWixドメイン管理画面に入力
3. ドメインをどこで管理されているかを特定（自動）
4. ドメインを取得しているサービスにログインしてネームサーバの設定等を変更する。
5. 切替が完全に終わるまで12時間～48時間待つ。（長い…）

### ネームサーバの設定変更について

1~3は画面の指示に従って進めるだけで迷いどころはないはずです。4に関しては今回「お名前.com」を使っていたのですが、少しUI上わかりにくい部分があったので補足します。

切替の際は既存のネームサーバを削除して、Wixで取得したネームサーバを追加するように指示されるのですが、既存のネームサーバがUI上削除できないようになっています。
![qiita_ref2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/e691015f-473c-19a0-72d0-ae5b15a54cdf.png)



この状態をサポートセンターに問い合わせると、「新しいネームサーバを追加すると既存のネームサーバを非アクティブな状態になるので心配しなくていいですよ。」と返信が返ってきました。

したがって以下のように新規のネームサーバが追加されていることだけ確認できればOKです。

![qiita_ref1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/4b3c6b71-ccc1-d432-70f0-3a34cdea2fde.png)



### 切替が終わるまで待つ

切替は公式アナウンスによると24時間～48時間で完全に切り替わるとのことです。

（この時間は少し多めに見ているようで、実際自分の場合はhttpsも含めて12時間で完全に切り替わりました。）

切替中は既存のHPにアクセスできなくなるので注意が必要です。なるべくアクセスがこない夜間や休業日などに作業する方がよいでしょう。

切替の動きを見ている限り最初にhttpのアクセスを開通させて、その後SSL証明書が用意されてhttpsのアクセスが通るという順番のようです。以下のように「公開されました！」と出ていてもhttpsでは繋がらず、実質公開されていない、という状態が数時間あるので注意しましょう。
（この画面httpsでつながるまで出さない方がいいと思うんだけどなぁ…Wixさん。）
![スクリーンショット 2023-08-19 223118.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/0742abf9-6a00-6bfc-f8c0-a9767e96800f.png)


## 最後に

今回作業してみて思ったのは、切替の際に数時間も待つのが結構ストレスということでした。STUDIOなど他のサービスだとどのようになっているかまでは調査できていないですが、この点はWixを使う上で意識する必要がありそうですね。（特に既存のHPからの切り替えの場合）

一方でページの構築はやはりコードを全部書くより明らかに早いですし、メンテも考えると今後HP制作の主流はこういったサービスになるのかと改めて思いました。
実際引継ぎ先の方に話を聞いてもその点の満足度は非常に高かったです。

以上、どなたかの参考になれば幸いです。
辞書型をNumpyオブジェクトで保存する

```python
dic = {
  "key1": array([1,2,3]),
  "key2": array([4,5,6]),
  "key3": array([7,8,9]),
}
```
のような辞書型オブジェクトは、

```python
np.savez("numpy_key_value", **dic)
```
もしくは
```python
np.savez_compressed("numpy_key_value", **dic)
```
で保存すると
```python
loaded = np.load("numpy_key_value.npz")
print(loaded["key1"]) #=> array([1,2,3])
```
というように扱えます

(詳しく検証してはいませんが、pickle.dumpよりサイズが小さくなるというようなことは無さそうだったので、サイズを気にする場合は対象データで比較することをおすすめします)
関係演算と集合演算

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/a9c2a67f-828c-716b-1f47-e04e25400731.png)
１：関係演算
①選択：指定した条件に合致する行を抜き出す操作です。

②射影：指定した列を抜き出す操作です。

③結合：双方の表に存在する列を対応づけて、１つの表にまとめる操作です。対応づけに使う列を結合キーと言います。

２：集合演算
①直積は、集合演算の一種です。直積演算では、複煤の表の全ての行の組み合わせを求めます。
【Mac】brew install phpが実行できない

# brew install phpが実行できない
MacOSをBigsurからVentureにアップデートしました。VentureではPHPが標準でインストールされていないので、`brew insatall php`でインストールしようとしたがエラーが発生。
```
Error: Failure while executing; `/usr/bin/env cp -pR /private/tmp/d20230821-25559-arl6cn/autoconf/. /usr/local/Cellar/autoconf` exited with 1. Here's the output:
cp: /usr/local/Cellar/autoconf/./2.71: Permission denied
(省略)
cp: utimensat: /usr/local/Cellar/autoconf/.: Permission denied
```

# 解決策

以下のコマンドで`/usr/local/`ディレクトリ内のファイルとディレクトリの所有者を変更したことで解決しました。
```
sudo chown -R $(whoami) /usr/local/*
```
上記コマンドを実行後、`brew install php@8.1`でPHP8.1をインストールするとエラーは発生しませんでした。

インストールしただけでは使えないので、下記のコマンドでPATHを通します。
```
echo 'export PATH="/usr/local/opt/php@8.1/bin:$PATH"' >> ~/.zshrc
```
```
echo 'export PATH="/usr/local/opt/php@8.1/sbin:$PATH"' >> ~/.zshrc
```

PATHを通した後に下記コマンドでバージョンを確認できました。無事成功です。
```
php -v
```


# 問題の原因？
ユーザーアカウントを2つ持っていて、新しく作ったアカウントでこの問題が起こりました。そのことから以前使用していたアカウントとの競合が発生したのかも？（正確な原因は不明）

# 他に試したこと
## Homebrewのアンインストール・インストール
Homebrewのバージョンが古く、下記コマンドでアップデートしようとしましたが上手く行かなかったので一度アンインストールしました。
```
brew update
```
こちらの記事を参考にさせていただきました。

https://ralacode.com/blog/post/install-uninstall-homebrew/

しかしHomebrewを新しくしただけではエラーは解決しませんでした。

## brew doctor
`brew doctor`で原因を探せるとのことなので、実行しました。
```
% brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-trouble and cause formulae that depend onthose kegs to fail to run properly once built. Run `brew link` on these:
pkg-config
rbenv-communal-gems
ruby-build
yarn
nodebrew
autoconf
node
rbenv

Warning: You have an unnecessary local Core tap!
This can cause problems installing up-to-date formulae.
Please remove it by running:
brew untap homebrew/core

Warning: Your Xcode (10.3) is too outdated.
Please update to Xcode 14.3 (or delete it).
Xcode can be updated from the App Store.

Warning: Your Xcode (10.3) is outdated.
Please update to Xcode 14.3 (or delete it).
Xcode can be updated from the App Store.
```
4つほど問題が発見されたので、解決していきました。

### 1.brew linkコマンドの実行
Homebrewでインストールしたパッケージがリンクされておらず、依存関係に問題があるらしい？ので下記コマンドを実行。
```
brew link pkg-config rbenv-communal-gems ruby-build yarn nodebrew autoconf node rbenv
```
### 2.brew untapコマンドの実行
Homebrewが不必要な`core`を持っているため、最新パッケージをインストールする際に問題が起きているらしいです。
指示されているとおりコマンドを実行します。
```
brew untap homebrew/core
```

### 3.Xcodeをアップデート
Xcodeのバージョンが古いので、AppStoreで最新バージョンにアップデートしました。
特にコマンドなどは必要ありません。

上記3つの対策を行った後に再度`brew doctor`を実行すると、、、
```
% brew doctor
Your system is ready to brew.
```
問題は解決できたようです。
しかし、これでもエラーは治りませんでした。

# まとめ
とても苦労しましたがなんとかPHPをインストールすることができました。正確な原因がわからないのが心残りですが、、、

直接的な解決にはなりませんでしたが、`brew docotr`は今後も活用していきたいですね。
ネット記事やchatGPTを活用しながら一人で解決することができたので、いい経験になりました。
ExtrapolationException: Lookup would require extrapolation Xs into the future.  Requested time XX but the latest data is at time XX, when looking up transform from frame [hoge] to frame [hoge]

# 遭遇した事例
- 研究室がお盆休みで停電したとき、PCやロボット周りの主電源を落とすのを忘れた
    - （先生や諸先輩方にバレたら`自主規制`されてしまう大失態）
- 研究で使用しているサービスロボットが動かなくなった
    - JointTrajectoryを介した制御が全くできなくなる
    - ロボットの姿勢（？）を取ろうとしたときに、表題にも記した以下のエラーを吐く
        - `ExtrapolationException: Lookup would require extrapolation Xs into the future.  Requested time XX but the latest data is at time XX, when looking up transform from frame [hoge] to frame [hoge]`


# 原因
- 停電した関係でロボットの中の時計が狂ってた（こっそりSSHで忍び込んで確認）
    - JSTにしてあったLocal TimeがUTCに戻ってた（JSTのままだった制御PCと噛み合わない）
        - 確認方法：`timedatectl`
    - そもそものRTC TIMEも狂ってた（多分）
        - 確認方法：同上

# 対処法1
1. Local TimeをJSTに戻す
1. 時間も合わせちゃう
てことで以下を実行（stop, startでそれぞれpasswordを要求されるので1行ずつ実行する）

```bash
/etc/init.d/chrony stop
sudo ntpdate ntp.nict.jp
/etc/init.d/chrony start
```

# 対処法2
```python
import tf2_ros
tf_buffer = tf2_ros.Buffer()
tf_listener = tf2_ros.TransformListener(tf_buffer)
tf_buffer.clear()
```
TFのバッファをリセットするコード。こっちのほうが確実？

# 参考文献
- http://wiki.ros.org/ROS/NetworkSetup#Timing_issues.2C_TF_complaining_about_extrapolation_into_the_future.3F:~:text=on%20common%20problems.-,Timing%20issues%2C%20TF%20complaining%20about%20extrapolation%20into%20the%20future%3F,expected%20round%2Dtrip%20delay).%20For%20isolated%20networks%20look%20here.,-Wiki%3A%20ROS/NetworkSetup
    - 発見元： https://answers.ros.org/question/253944/extrapolation-error-looking-up-robot-pose-when-looking-up-transform-from-frame-base_footprint-to-frame-map/
- https://zenn.dev/karaage0703/articles/47838858dd3107
- https://s-port.shinwart.com/tech-column/kawatama05/
Nagios + NRPEでディスク監視の設定

## 目的
Nagiosを監視基盤とする練習としてディスク管理を行う。また、Nagiosは構築済みとする。

## 構成
- Nagios Server ( 192.168.1.1 ) →　監視基盤
- Nagios Client ( 192.168.1.2 ) →　監視対象

NagiosはPull型なので、Client側のポートを開ける必要がある
※Allow Hostsとportの５６６６の設定を忘れない


## イメージ
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/e76bc121-3027-d959-82f2-49023a45a7fc.png)



## Nagios側の設定(監視基盤)

### 監視対象のホストを追加する設定
/etc/nagios/nagios.cfg

```conf
### 51行目付近
cfg_dir=/etc/nagios/servers
```

### 監視対象を定義するディレクトリを作成する
```bash
# mkdir /etc/nagios/servers
```

### 権限の調整
```bash
# chgrp nagios /etc/nagios/servers
# chmod 750 /etc/nagios/servers
```

### 監視対象の監視設定
/etc/nagios/servers/server.cfg

```conf
define host {
    use                     linux-server
    host_name               ubuntu-nagios-client
    alias                   ubuntu-nagios-client
    address                 192.168.1.2(nagios-client)
}

define service {
    use                     generic-service
    host_name               ubuntu-nagios-client
    service_description     Disk root
    check_command           check_nrpe!check_disk_root
}
```

```check_nrpe```は以下の```コマンド定義```で定義しているコマンドの名前
!の後の```check_disk_root```は```コマンド定義```で定義しているコマンドに引数として指定される。下の$ARG1$に入る(```check_disk_root```には下の```NRPE側の設定```で指定したコマンドが入る)

つまり、```$ARG1$```=```command[check_disk_root]=/usr/lib64/nagios/plugins/check_disk -w 20% -c 10% -p /```

### コマンド定義
/etc/nagios/objects/commands.cfg
```conf
define command {
     command_name    check_nrpe
     command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
 }
```

## NRPE側の設定
以下は監視対象にて行う作業

/etc/nagios/nrpe.cfg

```conf
### 106行目付近
allowed_hosts=127.0.0.1,::1,192.168.1.1(Nagios Server)
### 305行目付近に追加
command[check_disk_root]=/usr/lib64/nagios/plugins/check_disk -w 20% -c 10% -p /
```

## サービスの動作

### NRPEの起動
```bash
systemctl start nrpe
systemctl enable nrpe
```

### 構文チェック
```bash
nagios -v /etc/nagios/nagios.cfg
```

### nagiosの起動
```bash
systemctl start nagios
```

### 解説
#### Nagios-Server側で実行されている
```bash
/usr/lib64/nagios/plugins/check_nrpe -H <nagios-client> -c check_disk_root
```
nagios-clientにcheck_disk_rootを実行するように要求

#### Nagios-Client側で実行
```/etc/nagios/nrpe.cfg```で定義されている```check_disk_root```を実行する。
実際には以下のコマンドが実行される
```bash
/usr/lib64/nagios/plugins/check_disk -w 20% -c 10% -p /
```
fishで環境変数を設定する方法


### 設定方法

```sh
set -Ux FOO bar
```

`-U` はユニバーサル変数のことで PC 再起動をしても値を維持できるオプション。永続化するためのオプション。
`-x` は export のことで、環境変数を宣言するという意味のオプション。

#### config で永続化する方法

`~/.config/fish/config.fish` ファイルに次の行を追加。以下の例では `$HOME/go/bin` というパスを `$PATH` に追加してます。

```sh
set -x PATH $PATH $HOME/go/bin
```

### 削除方法

```sh
set -e FOO
```

-e は erase のことで、つまり環境変数を削除するという意味のオプション。

#### 参考資料

https://fishshell.com/docs/current/tutorial.html
【プラクティス紹介】1分でさらっと分かる「用語集」

## プラクティス名（別名）
用語集　（ユビキタス言語、共通言語、メタファー）

## プラクティスの目的・狙い
* コミュニケーションの齟齬を防止する（チーム内の共通認識形成）
* 設計書やコード内の用語を統一する
* 新規メンバーの参入障壁を下げる

## どんな時に使うか
* チーム内やステークホルダーとの会話で認識齟齬が頻発する
* 同じ用語でも人によって意味するものが異なる
* 逆に意味するものが同じでも人によって呼び方が異なる

## 実施手順
1. 用語集の書式と掲載場所を定め、周知する（必ず全員がアクセスできる場所に置く）
1. 業務用語/技術用語/アジャイル用語など会話を円滑にするための基礎知識を持ち寄る
1. チーム内またはユーザとの会話の中で登場した新出語は、都度、用語集に追記する
1. 複数の呼称がある用語はどれかに統一し、チームの共通言語を形成する
1. 定期的に新出語を周知する（定例会議の中などで共有の場を設ける）

## アレンジ例
* 用語の和名/英名を併記し、コードの関数名/変数名/クラス名などのネーミングに利用する
（＝DDDにおけるユビキタス言語の考え方）
* 解説が欲しい用語をリクエストとして記入し、分かる人が意味を回答する（プル型運用）
* チーム内でしか通用しない方言/通称/略語/比喩なども追記する
（＝XPでは複雑な概念を別のものに例えて理解しやすくする「メタファー」というプラクティスがある）
* 有識者にドメイン知識を解説してもらい、それを用語集に追記する

## アンチパターン
* 特定の人しか用語集に追記していない（一方通行＆負荷集中）
* 用語を共有する場が無く、追記してもチームに浸透しない
* 専門用語をムリに使う（→「レトロスペクティブ」が馴染まなければ普通に「ふりかえり」でよい）

## 参考情報

用語集の作り方についてはこの記事がとても分かりやすかったのでオススメです。

https://zenn.dev/toshiokun/articles/7204d0e74da885

## こぼれ話（私的コメント）
アジャイル初心者にとって最初の壁となるのが耳慣れない専門用語。それを解消するための用語集を作っている時に、ふと、これを一通り説明したらそれだけで新人向けオリエンテーションになるな、と気づきました。用語集って昔からある定番の手法なので、あまりプラクティスという印象が無かったのですが、よくよく考えてみるとチームの成長とともに育っていく生きたナレッジで、アジャイル開発との相性も良さそうだと改めて認識した次第です。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)