OmniAICreator/Qiita-1.07M huggingface dataset:
Apple M1 mac mini (2020) StableSwarmUI SDXL1.0

https://youtu.be/qgj01CwrWxk
![20230824_サムネイル16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486298/9ccb5a8f-cca1-a29a-7d72-a5ff2f2806b2.png)

- __※いかなる艱難辛苦も心が折れない人が対象__
- __のっぴきならない事情
よほどの事情がない限り、M1 mac mini でStable Diffusionを動かさない方がいいという自らへの戒めの記録__


## 2023/08/下旬 アルファ版
- 導入の段取り
  - Stable Diffusion Web UI AUTOMATIC1111
  - <font color=yellow>StableSwarmUI</font>
- Web コンテンツが軽め
  ブラウザに表示されるコンテンツが旧世代のコンテンツのため表示のフットワークがいい
- M1 Mac mini でブラウザで操作せず、スマートフォンか iPad から接続するとメモリ消費を抑えられる

## 制限事項、問題点
- M1 mac mini のメモリ
- 512 x 512 までが実用限界
  →モデルデータは SDXL1.0 用を使う
- 768 x 768 は Generate ができていない
  →今後もできない可能性がある

## 準備するもの
- [Stable Diffusion Web UI AUTOMATIC1111 GitHub](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
- [StableSwarmUI 公式 GitHub](https://github.com/Stability-AI/StableSwarmUI)
- iPad mini 4 (※推奨 ブラウザ操作のため)
- iPhone SE2 以上(※推奨 ブラウザ操作のため)

## 導入
- GUI の画面でぽちぽちすすめる
- 設定は気合と根性
- A1111 のエラーログが無いことを確認

## 実際の生成
- 512 x 512 type A 人の画像生成
![00003-3666103840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486298/1113ff2e-824f-d7ba-7d2e-3bf8e565b8dc.png)

SDXL 1.0 __53 min. 43.4sec__
Prompt
```
1girl, Caucasian.upright immovable,full body,like the royal highness,(((slim))),thin shoulder white strap and white camisole.(realistic, real life:1.1),(masterpiece:1.1),25-years-old,standing,(shaped face:1.1),brun eyes,simple silver piassings,(simple necklace:0.9),RAW, stunning portrait of an intelligent young beautiful woman. The final product should be a masterpiece that captures the essence and beauty of a woman. sharp focus, sharp focus, 8k UHD, DSLR, high quality
```
Negative prompt: 
```
nsfw, naked, wet skin,black woman,hispanic woman,crown,open mouth
```


- 512 x 512 type B ぬこの画像生成
![00000-1978204809.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486298/d919f9ef-0e7b-20c1-0c51-939411062996.png)

SDA1111 __N/A__
Prompt
```
A brown cat with green eyes is sitting on a blue sofa.
```
Negative prompt: 
```
なし
```

- 768 x 768
  →Out of Memory で停止したことを確認

###### tags: `S02EP31` `底辺インフラエンジニアシリーズ` `デバイス棚卸編`
AddROM Bypass APK は、ユーザーが Android 7 Nougat

AddROM Bypass APK は、ユーザーが Android 7 Nougat 以降のバージョンを実行しているスマートフォンやタブレットで Google FRP (工場出荷時設定へのリセット保護) ロックをバイパスできるように設計された Android アプリケーションです。 AddROM FRP ファイルは責任を持って使用することが重要です。

AddROM Bypass はすべての Android 携帯電話と互換性があり、Android Lollipop 5.0 から Android 13 までのバージョンをサポートします。

Android デバイスの Google アカウント アクティベーション ロックをバイパスするソリューションを探している個人にとって、AddROM APK の最新バージョンは実行可能なオプションを提供します。 工場出荷時設定にリセットした後に携帯電話にアクセスする際に問題が発生した場合は、このバイパス APK をダウンロードして問題を解決できます。 アプリケーションの更新バージョンには、優れた機能と、幅広い Android デバイスにわたるシームレスな機能が搭載されています。

FRP ロック メッセージが表示されるデバイスに直面した場合、Gmail ID のパスワードが認証されるまでアクセスすることはできません。 この問題に対処するには、AddROM Bypass FRP Apk をデバイスにインストールします。 このアプリケーションを使用すると、FRP ロックをバイパスして、デバイスへのアクセスを取り戻すことができます。

すべての Android バージョンで AddROM Bypass を使用する方法は次のとおりです。

携帯電話の電源をオンにして、Wi-Fi ネットワークに接続します。
Android デバイスで Chrome またはその他の Web ブラウザを開きます。
AddROM apk を Android スマートフォンに直接ダウンロードします。
ダウンロード フォルダーに移動し、[次へ] => [インストール] => [完了] をタップして FRP_ADDROM.apk をインストールします。
FRP_ADDROM.apk をインストールした後、Web ブラウザーに戻り、次の Web サイトにアクセスします: bit.ly/3rMdpCr
Apex Launcher.apk をダウンロードしてデバイスにインストールします。
Apexランチャーを開きます。
デバイス設定にアクセスします。
「セキュリティ」に移動し、「その他のセキュリティ オプション」=>「デバイスの検索を無効にする」を選択します。
メインの設定メニューに戻ります。
「アプリ」に移動し、「Google Play サービス」を見つけます。 無効にしてください。
「設定」=>「アカウント」=>「アカウントを追加」=>「Google」に移動して、Google アカウントを追加します。
「アプリ」と「セキュリティ」の両方から、以前に無効にしたサービスを再度有効にします。
最後に、携帯電話を再起動して変更を適用します。
AddROM Bypass APK の使用は、法的および倫理的なガイドラインに従って責任を持って行う必要があることに留意してください。
https://frpaddrom.com/addrom-bypass-apk/
DOMの仕組みと使い方について調べる

## はじめに
未経験の僕が先輩エンジニアのアプリ開発に参加せてもらったのはいいが、 利用している技術について全く理解ができていないので、少しでも理解するために調べてメモしていくことにしました。


## 今回の記事に関連する言語
・HTML
・JavaScript

## DOMとは何か
HTMLやXMLの構造をプログラミング的に表現することで、提供されるAPIを通じてプログラムから自由に操作できるようにしたもの。
~~CSS オブジェクト モデル (CSSOM)というのもある事を知りましたが、こちらは使う場面でまた調べたいと思います。~~
>  [JavaScript初心者でもすぐわかる！DOMとは何か？](https://eng-entrance.com/what-is-dom)
>> DOMとは「Document Object Model」の略だ。直訳すると、「ドキュメントを物として扱うモデル」になる。プログラムからHTMLやXMLを自由に操作するための仕組みだ。
ファイルの特定の部分に目印を付けて「この部分」に「こういう事をしたい」という処理を可能にするための取り決めがDOMである。
>
>  [何度調べてもわからないDOMに決着をつける](https://zenn.dev/antez/articles/b6eb22cb228a49)
>> DOM(Document Object Model) とはHTML(またはXML)ドキュメントに関するAPIで、ドキュメントをどのような構造にして、どのように操作するかを定義したものです。
このDOMが何を定義しているかというと、主にインタフェースです。

## DOMを使う理由をGPTに聞いてみた
<details><summary>インタラクティブなウェブページの構築:</summary>
　DOMを使用することで、JavaScriptなどのプログラミング言語を介してウェブページの要素や属性を動的に変更できます。これにより、ユーザーがページ上での操作に対して迅速にフィードバックを得ることができる、よりインタラクティブなウェブページを作成できます。
</details>
<details><summary>動的なコンテンツ更新:</summary>
　ウェブページの一部だけを再読み込みすることなくコンテンツを更新する際に、DOMは不可欠です。Ajax（Asynchronous JavaScript and XML）を使用して、サーバーとの通信を行いながらページの特定の部分を動的に更新することが可能です。
</details>
<details><summary>ユーザーインターフェースの操作:</summary>
　DOMを使用することで、ユーザーがフォームやボタンなどのインターフェース要素を操作した際のイベント処理を実装できます。これにより、ユーザーの入力に対して適切な反応を示すことができます。
</details>
<details><summary>データの取得と表示:</summary>
　サーバーから取得したデータをDOMを介してウェブページに表示することができます。APIからのデータ取得や外部サービスとの連携を通じて、リアルタイムの情報をユーザーに提供できます。
</details>
<details><summary>動的なアニメーション:</summary>
　DOM要素のスタイルや位置を変更することで、アニメーションやトランジションを作成できます。これにより、ユーザーエクスペリエンスを向上させる洗練された動きや視覚効果を実現できます。
</details>

>結論：
 __DOMはウェブ開発において、ユーザー体験の向上や動的なコンテンツの管理、データの表示など多くの側面で役に立つらしい__

## DOMの特徴
>  1\.ツリー構造とも呼ばれる階層構造を取る（DOMツリー）
>  2\. それぞれノードという言葉で説明される
>  3\. WEBページとJavaScriptなどのプログラミング言語とを繋ぐ
>> \<body>を頂点として、下にいくつかの\<section>と、そのさらに下にいくつかの\<p>で構成されている。
>> ```ruby:DOMツリー
>> ├ <body> #親ノード
>> └ <section>　#基準ノード
>> │  ├ <p>　#子ノード
>> │  ├ <p>　#子ノード
>> │  └ <p>　#子ノード
>> └ <section>　#兄弟姉妹ノード
>>    ├ <p>　#子ノード
>>    ├ <p>　#子ノード
>>    └ <p>　#子ノード
>> ```

## DOMツリーの作成手順
__【以下手順は[こちら]の記事を参照】__

[こちら]: https://zenn.dev/antez/articles/b6eb22cb228a49
バイトデータ取得→HTMLドキュメント変換→トークン化→オブジェクト化→DOMツリー

## 最後に
JSの基礎で調べていたらDOMについては知っておくべき。と目にしたので調べました。
資料の内容が細かく書かれているおかげで少しは理解できたと思います。

* * *
* 参照サイト
・[JavaScript初心者でもすぐわかる！DOMとは何か？](https://eng-entrance.com/what-is-dom)
・[何度調べてもわからないDOMに決着をつける](https://zenn.dev/antez/articles/b6eb22cb228a49)
・[ChatGPT - OpenAI](https://openai.com/chatgpt)
LAN間接続装置の機能

### LAN間接続装置の種類
　LANを構築するときに用いられるこれらの装置をLAN間接続装置といいます。代表的なものはリピータ、ブリッジ、ルータ、ゲートウェイなど。これらはOSI基本参照モデルのどの層に位置し、どの層でデータを中継するのか、つまりどの層でネットワークを接続するのかが異なる。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/a7cdbc4f-7ee8-4d64-6f17-5bc74a9d9a37.png)
OSI基本参照モデルのとLAN間接続装置の対応を示しますが、それぞれの装置がどの層に位置して機能を果たすのは、アドレス情報で分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/94cf8ab5-cdf0-2c71-372a-255bf9017dc6.png)

#### リピータ（物理層で中継）
　リピータは、OSI基本参照モデルの物理層に位置し、伝送中に減衰した電気信号を再生、増幅する装置。伝送距離を延長。
　リピータだけで構成された（論理的一本のケーブルで繋げられている）ネットワークの区画をセグメントということがあります。
　リピータで多くのノードが接続されたネットワークを構築することができる。が、セグメント当たりのノードが多くなると、トラフィック量が増え、コリジョンが多くなる。
　ハブ（リピータハブ）、一対多のリピータ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/ffa302ad-acd1-f7ab-2f2a-44163b034f99.png)
#### ブリッジ（データリンク層でフレーム中継）
　ブリッジは、OSI基本参照モデルのデータリンク層（第二層）に位置し、ネットワーク上を流れるデータ（フレーム）のヘッダに含まれるMACアドレスを識別して、必要であればフレームを他のセグメントに中継する機能をもった装置です。
 macアドレス学習⇒MACアドレスをフィルタリング⇒トラフィック量軽減
##### スイッチングハブ、L2スイッチ（交换机）
ブリッジが古く、現在は高性能なスイッチングハブが使うようになった。類似機能を持ち、高性能で、コリジョンが発生しないが特性。
#### ネットワーク層でパケットの中継を行うルータ
ルータは、OSI基本参照モデルのネットワーク層に位置し、複数のネットワークをネットワーク層で接続する装置です。
　ルータは、ネットワーク上を流れるデータ（IPパケット）のヘッダに含まれる宛先IPアドレスを識別し、ルーティングテーブル（経路表）から、そのパケットの宛先ネットワークを探し、次の伝送先ノードにパケットを転送する。
　経路選択、ルーティング
##### L３スイッチ
　なお、ルータはIPパケットの転送処理をソフトウェア（プログラム）で行っていますが、これをハードウェアで行うことで大幅に高速化したのがL３スイッチ。ルータはソフトウェアで、L３スイッチはハードウェアでIPパケットの伝送処理を行う。
#### 七層すべての中継を行うゲートウェイ
　ゲートウェイ、トランスポート層以上が異なるLAN同士を中継する装置で、第一層から第七層までのすべての層でネットワークを接続する装置。よって、異なるネットワーク構造（アーキテクチャ）を接続することができる。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/ee2ed36c-9b47-85ce-ca20-2b85b61b1372.png)
#### LAN間接続装置のとデータ伝送の範囲
リピータ　物理層
ブリッジ　データリンク層
ルータ　ネットワーク層
ゲートウェイ　アプリケーション層で中継、全層接続する

#### 練習問題
リピータは、OSI基本参照モデルの物理層に位置し、伝送中に減衰した電気信号再生、増幅する装置です。
リピータと同じ機能を持つ集線装置をリピータハブという。
ブリッジは、データリンク層をもとにしてフレームを中継する。
スイッチングハブ（L2スイッチ）は、受信したデータを宛て先MACアドレスが存在するポートだけに伝送する、ブリッジと同じ機能をもった集線装置である。
ルータは、ネットワーク層を元にパケットを中継する。
ルータは、複数のLANをOSI基本参照モデルの第三層ネットワーク層で接続し、パケットを中継する。
ゲートウェイは、OSI基本参照モデルのトランスポート層以上が異なるLANシステム相互関でプロトコル変換を行う装置です。
プログラミング言語Python

### プログラミング初心者におすすめの言語Python
プログラミング言語は200種類以上あると言われているが、Pythonはプログラミング初心者にとって非常に習得しやすい言語である。
カレーライスで例えてみよう。
カレーにはたくさんのスパイスが調合されています。専門店に行き、聞いたことのない何十種類ものスパイス買ってきて調合する必要があります。料理経験が豊富な人であれば、独自の調合で成功するでしょう。しかし、我々一般人の多くは失敗すると思われます。そもそも、カレーをスパイスから作る人の方が少ないと思われます。普通は、スーパーで調合済みのカレールーを買いますよね。料理初心者なら尚更カレールーを買った方が良いでしょう。Pythonでのプログラミングはこれに似ています。他の言語に比べて覚えることが少ないのです。
Pythonを選ぶもう一つの理由に、Pythonに本格的なソフトウェア製作にも使えるという点があります。スーパーで買ったルーで作るカレーも、よく炒めた野菜で取ったダシを加えると、プロ顔負けの味を出すことができます。Pythonには柔軟な機能拡張の仕組みが備わっており、実用に耐える大規模で本格的なプログラミングも作ることができます。
PythonはGoogleやNASAの内部でも利用されています。
職業訓練校の思ひ出

私は現在、エンジニア歴が3年目に差し掛かろうとしているLaravel・Vueエンジニアです。

IT業界・エンジニアを目指した理由は様々ありましたが、エンジニアになれたきっかけは今振り返ると、間違えなく職業訓練校に通うことができたからだと思っています。(独学をしていた時期は比較対象がなく理解度などの立ち位置が不明だった)
Qiitaユーザーは現役エンジニアが多いと思っているので参考にはなり辛いと思いますが、エンジニアになりたい、プログラマーに興味がある、という方がこの記事を読んでいたら是非職業訓練校について知っていただければと思います。

## 職業訓練校とは?
> 公共職業訓練とは、主に雇用保険を受給している求職者の方が職業訓練によるスキルアップを通じて早期再就職を目指すための制度です。
> [公共職業訓練について](https://jsite.mhlw.go.jp/tokyo-roudoukyoku/hourei_seido_tetsuzuki/shokugyou_kunren/koukyoukunren_00005.html)

私はこの制度を使用し、6ヶ月間Java、Python、VBA、PHPなどを勉強をしていました。

## 入校までの流れ
職業訓練には様々な種類があり、期間も2ヶ月から2年のものまでそれぞれです。
> [ハロートレーニング（職業訓練）について](https://jsite.mhlw.go.jp/tokyo-roudoukyoku/hourei_seido_tetsuzuki/shokugyou_kunren/menu/shienkunren.html)

ハローワークで受講したいコースを選択し、エントリーシートに志望動機などを書いて応募します。書類審査が通れば面接を受け、合格であれば入校できます。当時からITエンジニア志望で学校に通いたいと思っていたため、合格した時はかなり嬉しかったです。面接では簡単な暗算問題も出題されました。

## 入校して良かったこと

- **質問時間が1日1時間ある**
  1日4時間の授業があり、5時間目は質問できる時間帯として任意で質問をすることができました。独学時には気軽に質問できないことに困っていたのでかなり贅沢に感じたことを覚えています。さらに質問していく受講者があまり多くなかったため時間を取って質問することもでき、独学で勉強していた際に躓いた質問にも答えていただけました。

- **授業料が無料、手当も支給される**
授業料が無料の上、交通費も支給されます。6ヶ月間でかかったお金は教科書代だけで、雇用保険などの条件を満たすと1月に学習費用も支給されます。金銭的に大きな不安を抱えることなく勉強に集中することができました。

- **ロードマップを教えてくれる**
授業の講師が現役、もしくは実務経験のあるエンジニアであったため、ある概念を理解した後は何を学習いいかなどの質問にも回答していただき、やるべきこと・やらなくていいことを明確にすることができました。未経験ながら学習に少し自信を持つことができたことを覚えています。

- **強制力がある**
国の制度ということもあり、遅刻欠席が多いとクビ(除籍)になります。未経験時に独学で勉強を始めて挫折したという方も多いと思いますが、休めない、テストに合格しないといけないとい縛りがあることで例えモチベが浮き沈みしたとしても頑張れると思います。

- **同志ができる**
入校後には自己紹介がある・教室内で他の受講者と協力して問題解決する機会がある・エンジニアとして就職したいという同じ志を持った方と一緒に授業を受ける、などのことから受講生同士ではかなり仲が良かったです。まだ付き合いがある卒業生も多いです。

- **短期間集中して勉強ができる**
経済状況にもよりますが、授業時間以外は予習復習に充てられるため集中して勉強できます。

- **訓練校でもハローワークでも1on1がある**
現状に問題はないか、就活はどう進めていきたいか、学習状況はどうかなどお話できる機会が月に1, 2回あったため安心して就職に向けた準備をすることができました。

- **面接対策の練習**
過去にエンジニアに関連する面接を受けたことがなかったため、アピールポイントや成果物などでどう内定に近づけるかといったお話もいただき安心することができました。

## 訓練期間にやったこと
- **ITパスポート取得**  
授業内容と並行して入校後最初の1ヶ月でITパスポートを取得しました。3英文字の略語やプロトコルなどを叩き込んだため、知識は増えたと思います。

- **Java Silver取得**  
ITパスポート取得後の2ヶ月目ではJava Silver取得しました。授業ではJavaをメインで学習していたため、授業のペースより早めに教科書を終わらせ黒本の勉強に入りました。黒本は相当読み込んだ記憶があります。

- **TOEIC取得**
バックパッカー経験があり英語を勉強していたため、スキルシートに書いて少しでもアピールになるようTOEICを取得しました。

- **教科書を2ヶ月ほどで終わらせる**
授業時間以外にはたまにバイトをする以外はかなり時間があったため、2ヶ月と少しで購入した教科書は全て終わらせました。

- **ポートフォリオを作る**
教科書を終わらせた後はJavaの教科書を見ながらポートフォリオを作成しました。今見るとしょっぱいアプリではありますが、自力で1つのアプリを設計、実装する経験はして良かったと思っています。

## 訓練校で勉強して身に付いたこと
- **開発者用語・概念分かるようになった**
ツールの名前やポリモフィズム・継承など、話を聞いてもちんぷんかんぷんだった用語が減っていき、ググる時にどう調べていいか分からなかったものがなくなっていきました。

- **自走力がつく**
用語や概念についての知識が増えていった結果、調べ方が分かり始め自己解決できることが増えていきました。

- **タイピングがかなり速くなった**
入校前は人差し指と中指のみで入力していたタイピングが、気が付いた時には全指を使ってキーボードを見ずにタッチタイピングができるようになっていました。(寿司打でたまに練習はしていました)

## 就職先の選び方について
訓練校とハローワークの方でいくつか求人を提供していただきましたが、私はWantedlyを中心にエントリーを進めました。理由としてはWantedlyの求人は応募者と企業との距離が近くカジュアル面談などもでき気軽に直接お話を聞くことができたからです。

## 結果
最終的に2社から内定をいただきまして、無事開発エンジニアとなることができました。面接は数社受けましたが、エンジニア未経験ということもあり技術よりもやる気を評価する会社が多かった印象でした。

## まとめ
今回改めて振り返っても時間をかなり贅沢にかけて学習に身を置ける環境であったため、今から未経験としてエンジニアになりたい・転職したいと思っている方は、時間的に余裕があればハローワークで職業訓練の問い合わせをすることをお勧めします。効率良く勉強していきましょう！！
以上、職業訓練校の紹介・振り返りでした。

:::note warn
注意
数年前と現在では職業訓練校の制度で変更点もあると思いますので、正確な情報についてはハローワークにお問い合わせをお願いします。
:::
numpy.argsortの仕様を再整理

# 要約
- numpy.argsortの仕様を勘違いしていたので改めて理解のために記載
- 昇順のインデックスをそのまま返してくれると勘違いしていた
- 実際はオリジナルのarrayベースでソートをしたうえで、その値がもともとどのインデックスだったのかを返してくれる

# 拝啓
ある実装の対応中、数値の大きい順に計算を行う必要があり、
numpy.argsortを用いて、実現しようと考えたが、アウトプットのイメージが自分のイメージと異なっており、嵌った。調べて理解はしたものの、まだふわっとしているため、図示をして直感的なイメージを持てるようにする。

# 勘違いしていた仕様
以下のように昇順のインデックスを愚直にreturnしてくれると勘違い
```python
>>> a = np.array([0.8, 0.0, 0.5, 0.7])
>>> a.argsort()
array([3, 0, 1, 2])
```

# 実際の仕様
実際には元の値で昇順にソートをしたのち、それがもともとどこのインデックスだったのかを返す
```python
>>> a = np.array([0.8, 0.0, 0.5, 0.7])
>>> a.argsort()
array([1, 2, 3, 0])
```

# イメージ図
- まず元のarrayでソート
- 元のarrayの値がインデックスに変換される
- 元の値で昇順に並べられたインデックスの完成→このインデックスが出力される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359289/0d86a8b0-2c40-85f3-4967-05253b5883e5.png)
React-routerでnavを作成する

現在、未経験からフロントエンド転職を目指し学習中のもうすぐアラサー会社員です

React？SPA？わからんが？？ナビゲーションどうすりゃええんや？？という状態から
ナビゲーションバーをなんとか作成したので個人的備忘録的な投稿です

※情報には誤りが含まれる可能性があります（ぜひご指摘いただきたいです！）




# 1. インストール


　　

```:npm
$ npm i react-router-dom
```

create-react-appやviteなど使用した場合はcssやApp.jsの中身要らないので消しておきます

　　

# 2. BrowserRouter

いろいろインポートした後BrouserRouterでAppコンポーネントを囲みます
仕組みについて全然わかっていませんが、その内調べて記事にしようと思います

[ReactRouterドキュメント](https://reactrouter.com/en/main/router-components/browser-router)

```:main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App.jsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
)

```

# 3. componentsの作成

navを含めページのcomponentを作成します
aタグはLinkに、'href'は 'to'になるので注意！
　　
```:Nav.jsx

<Link to="/hoge"> Hoge </Link>

```


# 4. ルーティング


ルーティングはRoutes, Routeを使用します
古い記事ではSwitchが使用されていましたが、インポートできないので注意
　　

```:App.jsx
        //ナビゲーションコンポーネント
        <Nav />

        <Routes>
            <Route exact path='/' element={<Home />} />
            <Route path='/hoge1' element={<Hoge1 />} />
            <Route path='/hoge2' element={<Hoge2 />} />
            <Route path='/hoge3' element={<Hoge3 />} />
          </Routes>

```
AIをフル活用してホラーゲームを作る (#1)

# 0. 前置き
#### はじめに
2作目のホラーゲームが作りてぇ!!

そう思い始めて約半年が経った。

しかし時間があまりにも足りなくて着手できずにいる。

\
実は今年の6月にひとり会社を設立しまして、SNSやWebサイトもやり始め、さらに今まで公開したアプリのアップデート、新規アプリの企画・開発...
社長になったとはいえ貧乏なので、昼間はプログラマとしてアルバイト...

やることが多すぎて時間がマジで足りない...

\
\
そこでAIが登場するわけよ。

全部AIにやらせるのよ。可能な限り。

\
企画する時間、コード考える・書く時間、リソースを作る・探す時間
を省略できるワケだ。

#### 全部AIができるの？
わかりません。。。
下調べもなく聞きかじった情報でやってみようってなってます。
いけるとこまでやってみる！！
※できない部分は人力で補完するかも

#### なんでホラーゲーム？
AIの画像生成で有名な「stable diffusion」
あれで怖い画像を生成したことがあって。

今は精度が上がってるかもですが、
なんか不気味なんですよね。AIが作る絵って。

最近なんかは3Dモデルも作れるようになってきてるらしく、
ゲームのリソースに当たる部分もそれらを活用して作っていけば、
人には理解できないような不気味さが出たりする
ゲームになるんじゃないかと考えています。


#### プラットフォーム
Unityを使います。
この企画で作ったゲームは、iOS・Android・Steamで公開予定なので、
マルチプラットフォーム開発に適したUnityを使っていきます。
Unity歴は5年くらいです。

#### 今後の投稿
なるべく全ての情報をオープンにするを目標に記事を書いていこうと思います。

投稿ペースは遅いかもしれません。
今やってるアプリのアップデートが完了したらひと段落つくので、
本格的にやっていける予定です！

# 1. 本題
ようやく本題ですが、
まずはゲームを作るにあたり何が必要なのかをざっくりリスト化します。
```ruby:リスト
・ 企画 (どんなものを作るか大枠)
・ 仕様 (ストーリーやマップ含むすべて)
・ リソース (BGM・効果音・人や建物のモデル)
・ プログラム
・ 実機テスト
```

これらを元に「chatgpt」や画像生成AIやモデリングAIに仕事を分担しつつ、
自分がディレクター的な役割で動いていく感じで進めていきます。

リスト化するとやること少ないようにも思えますが、
それぞれの項目に莫大な量の作業があったりします。


各項目の具体的な内容は今後の記事でAIを活用するタイミングで書いていこうと思います。

\
\
前置きより本題の方が短くなってしまいましたが、
今回は初回ということでこんな感じで終わっときます。
amplify×cognito×reactのセルフサインアップ制御について

<h1>要点</h1>
<div>
amplify×cognito×reactの入門者向け
withAuthenticatorを使った認証画面の、「create Account」タブを消したかったが
いまいち良くわかっていなかった。
公式の解決策としては、tab毎消してcognitoのuserpoolの設定でセルフサインアップを不能にするようにということ
</div>

<h1>コード</h1>
cssに
<code>.amplify-tabs {
  display: none !important;
}</code>を加えるのみ。
<h1>背景</h1>
spring bootでモノリシックなアプリでMVPを作っていたが、
cognitoの認証画面を日本語化できず、急遽reactを使ったマイクロサービスの構成に変更して
得られた気付き。
react uiで日本語化できるならhosted uiも翻訳してほしいなー
reduceってめっちゃ便利じゃね？って話

# 概要
JavaScriptの配列操作っていろいろなメソッドありますよね。

- forEach()
- map()
- filter()
- reduce()

ここら辺が主にあると思うんですが、皆さん何使ってますか？
僕はreduce()を推したい...!!
じゃあ何が嬉しいんだよってことで実際に動かして確認します。

# 実際にやってみた
先に結論言います。

**配列でも、文字列でもなんでも作れます**

filterとかmapだと、結果として新しい配列を作ることになります。
reduceだと配列でも、文字列でもなんでも作れます。

以下、サンプル。

まず文字列作る。
```文字列作る.js
const tanakaList = ["田中1.男", 
                    "田中2.女",
                    "田中3.男", 
                    "田中4.男", 
  			        "田中5.女",
                    "田中6.男"];

const genderCheck = (list) => {
  return list.reduce((pv, cv) => {
  	const [name, gender] = cv.split('.');
  	gender === "男" ? pv += name : '';
    return pv;
  }, "");
};

console.log(genderCheck(tanakaList));
```
```
"田中1田中3田中4田中6"
```

次に配列作る。

```配列作る.js
const tanakaList = ["田中1.男", 
                    "田中2.女",
                    "田中3.男", 
                    "田中4.男", 
  			        "田中5.女",
                    "田中6.男"];

const genderCheck = (list) => {
  test = []
  
  list.reduce((pv, cv) => {
  	const [name, gender] = cv.split('.');
  	gender === "男" ? test.push(name) : '';
  }, "");

  return test;
};

console.log(genderCheck(tanakaList));
```

```
Array ["田中1", "田中3", "田中4", "田中6"]
```
こんな感じ。
Ionic × Angular モバイルプレビューの背景を白にするには

ionic serve --labを実行すると、
defaultでbackground-color:#000;になっていました。
どうやら、ionicのアプリテーマが#000になっているみたいです。

このままだと、font等が見えないため不便を感じたため下記対応をしました。

```
ionic serve --lab
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677104/b88d209d-63aa-0b17-791b-2a9a5e1d5b52.png)

```src\theme\variables.scss
/** Ionic CSS Variables **/
:root {
  --ion-background-color: #FFF !important;
~~~~~~~~~
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677104/981cef04-9aa4-b3cf-7116-318d76339485.png)
Rails – 値が重複したレコードを削除してからDBに複合ユニーク制約を追加するマイグレーションの例

# 問題

重複レコードが残ったままだとユニーク制約をDBに追加できない

```
Caused by:
Mysql2::Error: Duplicate entry '1-1' for key 'users.index_users_on_first_name_and_last_name'
```

# 例

- first_name / last_name の組み合わせでDBにユニーク制約を持たせたい
- first_name / last_name が同じ組み合わせのユーザは重複分のレコードを削除したい (1個だけ残したい)

という場合

# コードの例

1個のマイグレーションでは重複レコードを削除する
up に ActiveRecord を直接書いてしまう


```rb
class RemoveDuplicateUsers < ActiveRecord::Migration[7.0]
  def up
    dupulicated_users = User.group(:first_name, :last_name).count.filter do |_k, v|
      v >= 2
    end

    dupulicated_users.each do |(first_name, last_name), _count|
      User.where(first_name:, last_name:).order(:id).drop(1).each(&:destroy)
    end
  end
end
```

次のマイグレーションでは普通に複合ユニーク制約を追加する

```rb
class AddUniquenessToUsers < ActiveRecord::Migration[7.0]
  def change
    add_index :users, %i[first_name last_name], unique: true
  end
end
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
ra
[Unity]LayoutGroupで調整されたUIのサイズを取得するコツ

# 概要
特定の場所にオブジェクトを並べる時はHorizontalLayoutGroupやVerticalLayoutGroupなどを使いますが、並べられたオブジェクトのサイズをコード上で取得しようとしても0が返ってきて困ることってあると思います。
# 本文
まず、うまくいかなかった場合の状況を再現してみます。
BoxオブジェクトにはHorizontalLayoutGroupが付いてるので中にあるImageは横方向に並べられる状態になっています。さらにImageの高さはBoxの高さと同じになるように設定してあります。
![スクリーンショット 2023-08-24 23.31.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/456bc10e-c88c-7b1b-f258-fe4c3a2571be.png)

ここで以下のようなコードを作成してImageにAddComponentしてもコンソールログにはImageの正しい高さは表示されず「0」と表示されてしまいます。

```cs

using UnityEngine;
using UnityEngine.UI;

public class SetSquare : MonoBehaviour
{
    private void Start()
    {
        Image image = GetComponent<Image>();
        float height = image.rectTransform.rect.height;
        Debug.Log(height);
    }
}
```

試しに以下のように書き換えてみると

```cs

using UnityEngine;
using UnityEngine.UI;

public class SetSquare : MonoBehaviour
{
    private void Update()
    {
        Image image = GetComponent<Image>();
        float height = image.rectTransform.rect.height;
        Debug.Log(height);
    }
}
```

ログには最初だけ0が表示されていますが、それ以降は正しく取得できていることが確認できます。
![スクリーンショット 2023-08-24 23.40.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/db4231ba-03fa-03c2-15c4-49be06640f5a.png)

最初の１フレーム目だけ正しい値が取得できないことさえ気をつければちゃんと値を取得できることがわかりました。

以下はImageの高さを正しく取得して横幅に代入するサンプルコードです。

```cs

using UnityEngine;
using UnityEngine.UI;

public class SetSquare : MonoBehaviour
{
    private void Start()
    {
        Image image = GetComponent<Image>();
        // この一行を加えれば1フレームを待たずにすぐサイズを取得できるようになります。
        Canvas.ForceUpdateCanvases();

        float height = image.rectTransform.rect.height;
        // 横幅に縦幅を指定する
        image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, height);
    }
}
```
正しく取得した高さを使って正方形に変形することができました。
![スクリーンショット 2023-08-24 23.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/6ea81e93-4a9a-8091-863e-42441ea076c1.png)

# 補足
同様のことを

```cs
LayoutRebuilder.ForceRebuildLayoutImmediate()
```
このメソッドでも出来るようです。上手くいかなかった場合はこちらも試してみてください！以下は実装例です。

```cs
using UnityEngine;
using UnityEngine.UI;

public class TitleController : MonoBehaviour
{
    public Text titleText;
    // Horizontal Layout Groupが付いてるオブジェクトのRectTransform
    public RectTransform titleContainer;

    public void SetTitle(string newText)
    {
        titleText.text = newText;
        
        // レイアウト再構築
        LayoutRebuilder.ForceRebuildLayoutImmediate(titleContainer);
    }
}
```
【TailwindCSS】アニメーションを適用する方法


## 作成方法
`tailwind.config.js`に以下のように記述することでアニメーションを作成できます。

```js:tailwind.config.js
module.exports = {
 // ...
  theme: {
    extend: {
      animation: {
        'scale-in-center':
          'scale-in-center 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both',
        'scale-out-center':
          'scale-out-center 0.25s cubic-bezier(0.550, 0.085, 0.680, 0.530) both',
      },
      keyframes: {
        'scale-in-center': {
          '0%': {
            transform: 'scale(0)',
            opacity: '1',
          },
          to: {
            transform: 'scale(1)',
            opacity: '1',
          },
        },
        'scale-out-center': {
          '0%': {
            transform: 'scale(1)',
            opacity: '1',
          },
          to: {
            transform: 'scale(0)',
            opacity: '1',
          },
        },
      },
    },
  },
}

```


## 参考

https://tailwindcss.com/docs/animation#customizing-your-theme

https://tail-animista.vercel.app/play/basic/scale-up/scale-up-center
【Xcode】テスト実行時に複数のシミュレータが立ち上がる時の対処法

# 概要
アプリの開発中にユニットテストを作成し、そのテストの実行時に複数のシミュレータが同時に起動してMacのパフォーマンスが低下するという課題に直面しました。
ここでは、その解決策として行った対処方法をメモとしてまとめておきます。

# 結論
まず、結論から先に述べます。
テスト実行時に発生する上記の課題を回避するために、以下の手順でXcodeの設定を変更します。
1. 対象のテスト（この例では「GitHubSampleTests」）を選択した状態で、「Edit Scheme」を選択します。
![スクリーンショット 2023-08-24 23.10.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1262759/e136e938-9fe7-46c1-435f-98ed6fd54416.png)

2. 次に、右側にある「Options」を選択し、「Excute in parallel(if possible)」のチェックを外します。
![スクリーンショット 2023-08-24 23.13.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1262759/6f6821fe-35a8-4bf7-f273-d7492559073c.png)

これにより、テストは1つのシミュレータで順次実行されるようになり、Macの負荷が軽減されます。

# 備考
この「Excute in parallel(if possible)」オプションのチェックを付ける/外すとどのような効果があるか、簡単に説明します。

プロジェクトの規模が拡大するにつれて、通常テストの数も増えます。
その結果、テストの実行時間も増加します。
1つのシミュレータでテストを実行すると、テスト数が増えるごとに実行時間が長くなる傾向があります。
ここで、「Excute in parallel(if possible)」を有効にすると、複数のシミュレータが同時にテストを実行し、実行時間を短縮することが出来ます。(並列実行)

逆に、このオプションを無効にすると、テストは1つのシミュレータで順番に実行されることになります。(順次実行)

# まとめ
私の場合、テストの実行速度よりもMacの負荷が問題となリましたので、「Excute in parallel(if possible)」オプションを無効にしました。
適切にオン/オフを切り替えることで、最適な開発環境を保つことが出来ると思いますのでご自身の状況に応じてオン/オフを使い分けて頂ければ幸いです。

以上、テスト実行時に複数のシミュレータが立ち上がる時の対処法でした。
スコープ名にモデル名を用いたモデル設計とStyle/ClassAndModuleChildren (ネスト記法) のオートコレクションについて

## 環境
| 対象 | バージョン |
|:-:|:-:|
|Rubocop|1.56.1   |
|`TargetVersion`|3.2|
|Rails|7.0.7|

# TL;DR
Style/ClassAndModuleChildren cop のオートコレクションは非安全である。特に既存のモデル名をスコープ名として使用している場合には、オートコレクションによってZeitwerkの定数解決に関するTypeErrorが発生する。

## 既存のモデル名をスコープ名としていた場合

以下の記事のように、既存のモデル名をスコープ名とするモデル設計を行っていたとする。

https://qiita.com/jkr_2255/items/68c94573d07d189f4c6f

図1のようなディレクトリ構造で与えられている `Post::Revision` モデルに対して、Style/ClassAndModuleChildren cop (EnforcedStyle: nested) のオートコレクションを適用する [^1] 。

```txt:図1
app/models
├── post.rb
└── post
    └── revision.rb
```

```rb:app/models/post.rb
class Post; end
```

```ruby:app/models/post/revision.rb
class Post::Revision; end
```

すると、`post/revision.rb` は次の変更を受ける。

```diff_ruby:app/models/post/revision.rb
- class Post::Revision; end
+ module Post
+     class Revision; end
+ end
```

この状態で `bin/rails server` などのコマンドを実行すると、「`Post` はモジュールではない」というメッセージを持つTypeErrorが発生する。

```
app/models/post/revision.rb:3:in `<main>': Post is not a module (TypeError)
app/models/project.rb:1: previous definition of Post was here
```

## 原因と解決

Zeitwerkは、まず `post.rb` を参照し `post` をクラスの定数であると解決する。その次に `post/revision.rb` の `module Post` を見て、「`post`はモジュールではないよ！」と怒る[^2]。



したがって、次のように `Post` をモジュール定数からクラス定数として書き換えればよい。

```diff_ruby:app/models/post/revision.rb
- module Post
+ class Post
     class Revision; end
 end
```

### そもそも……

そもそもRubocopドキュメントの『[Style/ClassAndModuleChildren](https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren)』節に、このcopのオートコレクションが非安全であり、手動による監督が必要であると明記されている。Rubocop はコンパクト記法 (`Post::Revision`) からネスト記法に移行する知識を (少なくとも現時点では) 持たないのだ。

> ## Safety
> Autocorrection is unsafe.
>
> Moving from compact to nested children requires **knowledge of whether the outer parent is a module or a class**. Moving from nested to compact requires verification that the outer parent is defined elsewhere. RuboCop does not have the knowledge to perform either operation safely and thus **requires manual oversight**.

そもそもモデル設計に関して、_admin_ などのクラス名とならないスコープ名は正しいものだが、「名前空間としてクラスを使」[^3]ったモデル名は避けるべきだろう。たとえば、Railsドキュメントの『[モデルを生成](https://railsdoc.com/page/rails_generate_model)』には、「階層を指定」してモデルを生成するコマンドとして

```
rails generate model admin/account
```

が例示されている。つまり、階層を表す接頭辞 (スコープ名) に既存のモデル名を充てることは推奨されないということだ。

[^1]: コマンド `rubocop -A <file>` で Rubocop の自動訂正を適用できる。
[^2]: Zeitwerkの名前解決アルゴリズムについては、『[Zeitwerkの壊し方](https://qiita.com/fursich/items/717a720d9f4465e4cbbb#5-%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%A8%E3%81%97%E3%81%A6%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%BF%E3%81%86)』を参照してほしい。
[^3]: https://qiita.com/fursich/items/717a720d9f4465e4cbbb#5-%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%A8%E3%81%97%E3%81%A6%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%BF%E3%81%86
DigitalOcean　FunctionのAPIでJSON形式でレスポンスさせる方法

# JSON形式になぜならないのか

```main.js
export function main(args) {
  const response = {
        "body":'abc',
    };
    return response;
}

```
```text:result
abc
```

となってしまいJSON形式にならない。

# 解決方法

https://docs.digitalocean.com/products/functions/reference/parameters-responses/#returns


の一番下に書いてある通り、

```text:https://docs.digitalocean.com/products/functions/reference/parameters-responses/#returns
If you only ever want to return JSON data from your function, 
you can ignore the above requirements 
and instead return any result that can be serialized to JSON. 
To access this option, add .json to the end of your function URL when invoking it.
```

:::note info
FunctionのURL(Web Function・REST APIのどちらでも)の後ろに「.json」とつける
:::

```text:例
https://faas-*********.doserverless.co/api/v1/web/***************/default/********.json
```
のようにすると

```text:result
{
    "body": "abc"
}
```
こうしてJSON形式でレスポンスできたとさ。めでたいわ。
【プラクティス紹介】1分でさらっと分かる「エレベーターピッチ」

![elepi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526800/0ce388c9-adbb-c090-b865-e3d2da4eb604.jpeg)

## プラクティス名（別名）
エレベーターピッチ　（エレベータースピーチ、Lift speeche、Elevator Statement）

## プラクティスの目的・狙い
* プロダクトの核となるコンセプトを明確化する
* チームの共通認識をつくる

## どんな時に使うか
* そもそもそのプロダクトの存在意義は何なのか、がハッキリしていない
* プロダクトに盛り込みたい要素は多数あるが、その中で最も大事な要素を見極めたい

## 実施手順
1. 自分たちが作るプロダクトまたはサービスに関して、下記テキストの**太字**部分を皆で話し合う
1. 書きやすい箇所から埋めてゆき、全部書けたら声に出して読み上げてみる
1. 違和感がある箇所があれば、文言を見直す
1. チーム全員が納得できる文言になったら完成

>[ **潜在的なニーズを満たしたり、潜在的な課題を解決したり** ]したい
>[ **対象顧客** ]向けの
>[ **プロダクト名** ]というプロダクトは
>[ **プロダクトのカテゴリ** ]です。
>これは[ **重要な利点、対価に見合う説得力のある理由** ]ができ、
>[ **代替手段の最右翼** ]とは違って
>[ **差別化の決定的な特徴** ]が備わっている。

## アレンジ例
* 書式が書きづらいようであれば、欄外の文言も適宜変更してよい
（形式に従うことよりも短い文章で伝わることが重要）

## アンチパターン
* 厳密に（網羅的に）書こうとしすぎて、長々とした文章になってしまう

## 参考情報

https://www.ohmsha.co.jp/book/9784274068560/

## こぼれ話（私的コメント）
エレベーターピッチはもともと起業家がアイデアを端的に伝えられるようにするためのワークが由来。想定するシチュエーションとしては、お目当ての出資者（忙しくてなかなか捕まえられない社長や投資家）とたまたまエレベーターで乗り合わせた時に、目的階に到着するまでの短い時間（15～30秒）で、自分のアイデアの核となる部分を伝えて「その話、今度詳しく聞かせてくれないか」とアポを取り付けることができるか！？という感じだそうです。

まだ世の中に存在しないプロダクトの良さを端的に伝えるのはなかなか難しいものです。余計な枝葉は切り落とし、真に核となるアイデアだけに絞らないと書けません。ですが、ひとたびそれを言語化できたならそのテキストはプロダクトの基本コンセプトとして機能します。

なお既存プロダクトであってもエレピをやる意味は十分にあります。コンセプト（≒存在意義）が再定義されることで今後の方向性が定まります。

エレピはインセプションデッキの中の１枚でもありますが、僕個人の経験としてはこれが一番人気ではないかと思います。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
Cisco機器に「共通パスワード」でログインしてるやつなんておらんよな？？？？ ～Ansibleで全機器にSSH公開鍵を一括で設定するの巻

>SE「今日から参画いたします〇〇です！よろしくお願いします！！！」
>PL「よろしくね～。ハイこれ、貸与PC。資料渡すからセットアップよろしく～」
>…
>SE「セットアップ終わりました！」
>PL「じゃあ検証環境の説明をするね。まずルータのパスワードは全機器共通のP@$$w0rdで……」

みたいなやり取りが「当たり前」だと思ってませんか？？？

えっ、全員知ってる共通パスワードでログイン出来るんですか？？？？？

えっ本番環境も共通パスワードで入れちゃうんですか？？？？？？？？？？

えっ大手キャリアもやってることだから問題ないと思ってるんですか？？？？？？

えっえっ、現場退場した人もネットワークに繋げられればログインできちゃうんですか？？？？？？？

## この記事の概要

この前書いた記事の続きです。

[Cisco機器にパスワード入力してログインしてるやつなんておらんよな？？？？ ～CiscoIOSにSSH公開鍵認証を設定するの巻 - Qiita](https://qiita.com/guskma/items/5960384cf5e1c84b7259)

上記記事ではCiscoIOS搭載機器にSSH公開鍵を登録し、パスワード入力無しでログインする方法を紹介しました。

前回の記事では特に書いてませんでしたが、ログインユーザを明確にすることは大事です。

不正侵入された時にどのアカウントを使われたかがわかりますし、障害発生時などの原因切り分けにも対象ユーザを特定することが出来るからです。

ただね。わかってますよ。インフラエンジニアの皆さんの声が聞こえてきますよ。

「そんなこと言ってもさ、メンバーが入退場するたびに鍵の登録/削除なんて現実的じゃないでしょ」

ですです。たとえ単純な構成のネットワークが1システム分しかないPJであっても、ルータと配下のスイッチで2台。冗長化してれば4台と。メンバーが入れ替わるたびに4台の設定を変更しなければならないわけですからね。

今回の記事では、そんな問題はAnsibleでサクッと自動化してしまおうというところの解説をしていきたいと思います。

サンプルコードもGitHubにて公開しています。使えそうなら使ってやってください。

[guskma/cisco-ios-pubkey-playbook - GitHub](https://github.com/guskma/cisco-ios-pubkey-playbook)

## サンプルコード使い方説明

GitHubのほうのREADME.mdに詳しいことは書いたので、使い方の説明は省略します。

じゃあなんでこの項をつくった。

## 終わりに

いかがだったでしょうか？？？？？(クソアフィブログ風味)

GitHubの方を充実させすぎてしまったため、こちらに書く内容がなくなってしまいました。

ITインフラの中でも、ネットワーク界隈はレガシーなものが多く、他のIT界隈と比べて新しい技術を取り入れる機会が少ないのが実情です。

そのせいで、本来改善されて然るべきセキュリティの強化と作業の効率化が放置されがちな傾向にあります。

しかし、残念なことにそれらを解決するための新しい技術はどんどん出てきています。

これまで身につけてきた技術に対する問題をクリアするための方法の一つとして、この記事が参考になれば幸いです。

(補足)
今回の記事はぶっちゃけ「Ansibleわからんけどネットワーク自動化したい」って人も対象にして書きたかったんですが、どこから書いていいかわからなかったのでところどころ抜けてる説明があると思います。
不明点などありましたら、コメントでボロクソに言ってもらえたら泣いて喜びます。嘘です私はMではありません。
Vue.jsとNext.jsの違いとどのようなプロジェクトに適しているか

# 結論
Vue.jsとNext.jsは、どちらもJavaScriptベースのフレームワークであり、ウェブアプリケーションの開発をサポートするために使われます。
Vue.jsは主にクライアントサイドのSPA開発に、Next.jsはReactをベースにしたサーバーサイドレンダリングや静的サイトジェネレーションを必要とするプロジェクトに適しています。どちらを選ぶかは、プロジェクトの要件や開発者の好みによります。
| Vue.js | Next.js |
|-------------------|---------|
|クライアントサイドのSPA開発 | SSRやSSGが必要な場合の開発 |

### SPA開発のプロジェクト例
SPAは、ユーザーエクスペリエンスを向上させるために、リアルタイムなデータ更新やスムーズな画面遷移が必要な場合に適しています。

1. **SNSアプリケーション:**
   - 例: Twitter、Instagram風のアプリ
   - ユーザーが投稿を作成し、コメントしたり共有したりするアプリケーション。
   - 動的にコンテンツがロードされ、ユーザーがインタラクティブに情報を共有できる。

2. **タスク管理アプリケーション:**
   - 例: Trello風のアプリ
   - ユーザーがタスクを作成、編集、削除できるアプリケーション。
   - タスクの状態（未完了、完了）を切り替えたり、期限を設定したりできる。

3. **eコマースアプリケーション:**
   - 例: Amazon風のアプリ
   - 商品の一覧表示、詳細表示、カート管理、支払いなどの機能を提供するアプリケーション。
   - 商品リスト、カート、チェックアウトなどの機能を提供し、ユーザーがシームレスな購買体験を楽しむ。

### サーバーサイドレンダリング（SSR）が必要なプロジェクト例
SSRはSSRは、ウェブページの内容をサーバーサイドで生成し、クライアントに提供する方法です。
初回表示の高速化やSEO対策、リアルタイムのデータ提供が必要とされる場合に適しています。

1. **ニュースポータル:**
   - ホームページや記事ページなど、SEO対策が重要であり、クローラーに対して効果的にコンテンツを提供する必要がある。
   - ページの初期表示の高速化が求められる。


2. **ダッシュボードアプリケーション:**
   - ユーザーがリアルタイムのデータや分析を必要とする。
   - サーバーサイドでデータをプリレンダリングして初期表示の速度を向上させたい。

3. **ブログ:**
   - 記事が定期的に更新されるため、最新情報を効果的にユーザーに提供する必要がある。
   - SEO向上とユーザーエクスペリエンスを両立させたい。


### 静的サイトジェネレーション（SSG）が必要なプロジェクト例
SSGは事前にウェブページの内容を生成しておき、それをクライアントに提供する方法です。
内容が頻繁に変わらず、クライアント側の操作によるデータ変更が少ない場合に適してます。

1. **企業ウェブサイト:**
   - ホームページ、サービスページなどの情報を提供する。
   - 定期的な更新が少なく、高速な読み込みとSEO対策を重視する。

2. **ポートフォリオ:**
   - クリエイティブな作品やプロジェクトを紹介する。
   - ページ数が限られており、迅速な読み込みが求められる。

3. **ドキュメンテーションサイト:**
   - ライブラリやプロダクトのマニュアルやドキュメントを提供する。
   - 頻繁に更新される可能性が低いが、ユーザーが迅速にアクセスできるようにしたい。


## Vue.js / Next.jsの違い
| 機能 / フレームワーク | Vue.js | Next.js |
|-------------------|--------|---------|
| ベース            | Vue.js | React   |
| レンダリング       | クライアントサイドでの動作を前提 | クライアントサイドとサーバーサイドの両方 |
| CSR/SSR/SSGの設定  | プロジェクトごとに設定<br>ページごとは不可  | ページごとに設定可能 |
| コンポーネント     | サポートされており、コンポーネントベースのアーキテクチャを提供 | Reactコンポーネントを使用 |
| ルーティング       | Vue Routerなどの追加ライブラリでサポート | Next.jsに内蔵されており、簡単にルーティングを設定可能 |
|データバインディング|双方向|　単方向　|
| 状態管理           | Vuex/Piniaなどの追加ライブラリを使用 | 組み込みの状態管理 |
| バンドルサイズ     | 一般的に軽量 | より大きなバンドルサイズ |
| SEO向上            | 追加の設定が必要 | SSRとSSGにより自動的にSEO向上 |
| 主な用途           | クライアントサイドのSPA開発 | SSRやSSGが必要な場合の開発 |


## Vue.js   
   - Vue.jsは、クライアントサイドで動作するJavaScriptフレームワークです。主にSPA（Single Page Applications）の開発に利用されます。
   - コンポーネントベースのアーキテクチャを提供し、アプリケーションを小さな再利用可能なコンポーネントに分割することができます。
   - リアクティブなデータバインディングと仮想DOM（Virtual DOM）により、UIの効率的な更新を実現します。
   - コアライブラリに加えて、Vue RouterやVuexなどの公式の追加ツールが提供され、ルーティングや状態管理を簡単に実装できます。
   - クライアントサイドでの動作を前提としており、サーバーサイドレンダリング（SSR）や静的サイトジェネレーション（SSG）のサポートはありますが、Next.jsほど強力ではありません。

## Next.js
   
   - Next.jsは、Reactをベースにしたサーバーサイドレンダリング（SSR）や静的サイトジェネレーション（SSG）を容易に実現するためのフレームワークです。
   - クライアントサイドとサーバーサイドの両方でレンダリングを行い、初回表示の高速化やSEO向上などのメリットがあります。
   - 静的サイトジェネレーションにより、事前にページを生成しておくことで、高速なパフォーマンスを実現します。
   - ルーティングやデータのフェッチなどの機能を含み、シンプルなAPIでこれらを操作できるようになっています。
   - フロントエンドとバックエンドを同じプロジェクト内で開発することができます。
認証と認可の違いについて

認証：きみ、誰？
例：ログイン時のID・パスワード認証、生体認証

認可：きみ、資格ある？
例：チケット、年齢確認

認証と認可が一緒になっている身近な例
パスポート→身分証明＆海外渡航許可
運転免許証→身分証明＆自動車運転許可

利用シーン
サービスへのログイン
Raspberrypiとtailscaleでポートフォリオを公開した話

# なんでわざわざラズパイ・・・？
今の時代クラウドあるしそっち使ったほうがいいんじゃね！？
って自分も思ったりするけど，無料で試せるってのはオンプレ（笑）のいいところですよね．．．

# 今回の構成
Raspberrypi上にDocker導入して，コンテナ上にSQL,Django,Nginxの3つのコンテナを動作させてます．

# 作成するにあたって苦労した点
Djangoでアプリを作ることはあっても，nginxに載せて運用する機会はあんまりなかったので，nginxとかの設定を確認したり調べたりするので結構時間がとられた．
あとはSQL周りも，Djangoに付属してるsqlliteを使っていたので，そこをPostgreSQLのコンテナを使って接続させるのが最初はよくわからなかったです

# 魔法のtailscale
tailscaleはもともとVPNを構築するためのものなのですが，　VPNを公開することができ，ポートを開ければアクセスできようになるので，家のポートを開放せずとも，アクセスしてもらう状況がつくれるといった優れものでした．

# ポートフォリオを作って成長したこと
実際アプリのコーディングを行うだけでなく，運用を行う段階まで持っていけたのは成長できたかなと思う．これまでは単独のコンテナで開発を行なっていたが，全体的な構成を踏まえたDocker環境を作れたのは自分にとっては大きいかなと思った．


# ポートフォリオサイト
https://raspberrypi4.tail6211f.ts.net/
QNAP Hybrid Backup Syncのエラーについて

# QNAP Hybrid Backup Syncでエラーが出たときにエラーコードから内容を確認する話

QNAP HBSでエラーログが出ることがある。
その際、エラーコードが書かれることがあるけどこれって別にQNAPなエラーコードではなく、たいていの場合はrsyncが吐いている一般エラーコード。

なので、以下のページとかを参照するとエラー内容がわかったりするかもしれない。
すごくいいページなので参照しておこう。

https://qiita.com/h2suzuki/items/0cc924cdd9d5c6d47448

HBSでエラーが出たときは、sshして同じ設定を施したrsyncコマンドを実行するとたいていエラーの内容がもっとよくわかりますのでそちらをするのをお勧め。


まあ、先日はエラーナンバー9「Bad file number」が出て調べたんだけど全然解決策わからなかったですけどね。
とはいえ、HBSのエラーなのかrsyncが吐いているエラーなのかがわかるだけでも対処が変わる。
プロビジョニングパッケージのメモ(使い方、AD参加)

<h2>プロビジョニングパッケージでつまずく</h2>
プロビジョニングパッケージなるものをやっていてつまずいたことをメモとして書きます。

プロビジョニングパッケージのダウンロードとか簡易エディターの説明はどのサイトでもやっているので省略します！
そこまでのサイトはいっぱいあるからね…

あ、一応作る際に日本語にしたい場合はadksetup.exeのイメージおよび構成デザイナー(ICD)からダウンロードしてね！


ちなみに自分の環境で問題だったのは「Active　Directoryへの登録」

登録したかったんだけどうまくいかなくて…　<h4>全然うまくいかなくってェ…</h4>
ってことでとりあえずBatファイルで実行するやり方に変更しました。

でもそれプロビジョニングパッケージ内でやる意味 p(*'ω'*)

てことでまずAD参加用のbatを作ります!

<h2>バッチファイルの中身</h2>
@echo off
rem DNSサーバーの指定　addr="xxx.xxx.xxx.xxx" xのところに入力してね

netsh interface ipv4 set add name="Wi-Fi" source=dhcp
netsh interface ipv4 set dns name="Wi-Fi" source=static addr="xxx.xxx.xxx.xxx" register=non validate=no

rem もしサブネットを指定したい場合のサブネットマスクの設定
rem netsh interface ipv4 add dns name="Wi-Fi" addr="8.8.8.8" index=2 validate=no

rem Wi-FiのIPv6をオフにする
powershell Disable-NetAdapterBinding -Name "Wi-Fi" -ComponentID ms_tcpip6


rem ドメイン参加の例
wmic ComputerSystem WHERE "name='%computername%'" CALL JoinDomainOrWorkgroup Name="contoso.com" Password="password" Username="user01" FJoinOptions=3

rem これはこのバッチ単体でやるときの再起動、普段はコメントにしておく
rem shutdown /r /t 0
*******************************************************************************

適当にこんな感じ！
果たして実際の環境でIPv6をオフにしたままやっていいのかはわからないけど…

<h2>詳細エディター</h2>

詳細エディターを開くのは左下の「詳細エディターに切り替える」を押します
![詳細はどこ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/efd9b128-aab3-b82a-2265-e5004a2eba0c.png)


そうするとわからんのがいっぱいでできます

多いね
![おおいね.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/8ed4c182-c267-26f2-c7a4-b40f4e4f8c8e.png)


この中の[ProvisioningCommands]ってやつに入れていくよ
![ここです.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/b4583c6d-9719-607e-e7af-b5aec3460769.png)

まず[ProvisioningCommands/DeviceContext]を開くと[CommandFiles]と
[CommandLine]が出てきます

最初にやることは[CommandFiles]を選択して実行したいコマンドファイル(BatやPs1等)を選択します。

![ネーミングセンス.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/c8de3a7d-c0da-e3f7-d478-078d4e945324.png)
選択するとこんな感じになるので[追加]を押すと
![やったね.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/59b8043d-fcbb-d852-2a4e-d4653674c261.png)
追加されます。それでは次に実行したいコマンドを追加していきましょう

<h2>コマンドの追加</h2>

コマンドの追加は[CommandLine]に書いていくよ
といっても今回そんなに実行するものがないので簡単に
![コマンドプロンプト.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/12b738e3-e124-66fd-5448-67b8593b185e.png)

cmd /c [実行するファイル名]　
これだけ・・・
<h3>これだけ～～～！！？？</h3>
これだけのためにサイトを探しまくって半日無駄にしました

これであとは左上のエクスポートをやって終わり、

最後に一つだけ注意点

USBなどを使ってプロビジョニングパッケージを実行すると思うんだけど
必ず作成したppkgファイルやcatファイル(アプリをインストールする際に使う)、batファイルは
![これで7時間無駄にした.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537922/7a744da7-3c24-f02c-2397-20db6ab0e09d.png)

<h3>絶対にフォルダ内に入れず保存媒体直下に入れよう！</h3>

そうじゃないと実行されないので要注意！

以上、終わり
Nuxt3で初期ページの内容を変える

Nuxt2の時と比べてインストール後のファイル構成が違いすぎて一瞬挫折しかけた。
でもここで諦めたら勉強にならないのでどうにか頑張る。

## ルートにあるapp.vueを確認してみる。
```
<template>
  <div>
    <NuxtWelcome />
  </div>
</template>
```
これがlocalhostで表示されている画面のようだけど、この`NuxtWelcom`っていう
コンポネントっぽいファイルはどこで読み込まれている？

https://nuxt.com/docs/getting-started/views

いろいろここに書いてあるっぽいので翻訳して読む。

### app.vue
```
<template>
  <div>
   <h1>Welcome to the homepage</h1>
  </div>
</template>
```
公式にこんな記述があったので、書き直してみよう。
localhostで表示されたページにも以下のように書いてあるしねー。
> Get started
Remove this welcome page by replacing <NuxtWelcome /> in app.vue with your own code.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1266796/e2a81e0d-39a8-1d1a-9f5e-d3d41839e453.png)

ほっほー、変わった。
Backlog APIのコメントでメンションを設定する方法

# はじめに
Backloｇを使用していると、レビュー依頼など同じコメントを何度もすることがあり、[API](https://developer.nulab.com/ja/docs/backlog/#)でなんとかできないかなと思ってドキュメントを参照して試してみたものの情報がなく、ググっても解決できなかったので備忘として記事にします。

# メンションを設定する方法

## 結論から

コメントに`<@U1111111>`のように`<U[UserId]>`と設定すればOKです。

## ユーザーIDを取得する

[プロジェクトユーザー一覧の取得](https://developer.nulab.com/ja/docs/backlog/api/2/get-project-user-list/#)から取得します。

## コマンドサンプル

```update.sh
#!/bin/sh

if [ $# -ne 1 ]; then
  echo "引数を入力してください"
  echo "Usage: sh update.sh <issue_number>"
  exit 1
fi

NO=$1
if ! [[ ${NO} =~ ^[0-9]+$ ]]; then
  echo "課題番号を数値で入力してください"
  echo "Usage: sh update.sh <issue_number>"
  exit 1
fi

BASE_URL=https://test.backlog.com
PROJECT_KEY=TEST
API_PATH=/api/v2/issues/${PROJECT_KEY}-${NO}
API_KEY=KEY
UPDATE_STATUS=2  # 処理中に更新

curl -X PATCH \
  -H "Content-Type: application/json" \
  -d '{
    "statusId": '${UPDATE_STATUS}',
    "comment": "<@U1111111> \nTESTです"
  }' \
  ${BASE_URL}${API_PATH}?apiKey=${API_KEY}
```

# さいごに
全然わからなくてWEBサイトでコメントしてみてネットワークログからリクエストを参照して試してみたらできました。
もうちょっと使い方とかサンプルとかを載せてもらえると嬉しいですね。
VSCode / C言語のIntelliSenceの挙動がおかしい時

Visual Studio Code で C言語ファイルを開いたときの IntelliSence の動作がおかしい時に試してみること。

# C/C++言語サーバのキャッシュを削除してみる
C/C++言語サーバーのキャッシュが保存されている`ipch`ディレクトリを削除してみる。
```bat:Windowsの場合
%LocalAppData%\Microsoft\vscode-cpptools\ipch
```
```shell:Linuxの場合
$HOME/.cache/vscode-cpptools/ipch
```
```shell:MacOSの場合
$HOME/Library/Caches/vscode-cpptools/ipch
```

https://code.visualstudio.com/docs/cpp/faq-cpp#_what-is-the-ipch-folder

# IntelliSenceデータベースを再作成（リセット）してみる
コマンドパレット(Ctrl+Shift+P)を開いて `C/C++: Reset IntelliSense Database` を実行

https://code.visualstudio.com/docs/cpp/faq-cpp#_how-do-i-recreate-the-intellisense-database

# 拡張機能の管理データベース
```bat:Windowsの場合
%APPDATA%\Code\User\workspaceStorage 配下の数字フォルダ群
```
```shell:Linuxの場合？
$HOME/.vscode-server/data/User/workspaceStorage 配下の数字フォルダ群
```
TypeScriptのGenerics

## Generics
Genericsは使用時に型を決定する機能。振る舞いが同じで型のみが異なる時、後から型定義する事で汎用的なコードを書く事ができます。

## サンプルコード
```ts
type Container<T> = {
    value: T;
}

let numberContainer: Container<number> = { value: 42 };
let stringContainer: Container<string> = { value: "Hello, Generics!" };

const main = () => {
    console.log(numberContainer.value);
    console.log(stringContainer.value);
}

main();
```

```shell:実行結果
~/develop/typescript$ ts-node test.ts 
42
Hello, Generics!
```

→このままだと、anyで定義した下記定義と同義。

```ts:
type Container = {
    value: any;
}

let numberContainer: Container = { value: 42 };
let stringContainer: Container = { value: "Hello, Generics!" };

const main = () => {
    console.log(numberContainer.value);
    console.log(stringContainer.value);
}

main();
```

```shell:実行結果
~/develop/typescript$ ts-node test.ts 
42
Hello, Generics!
```

## Genericsの活用

```ts:
type Container<T extends string | number> = {
    value: T;
}

let numberContainer: Container<number> = { value: 42 };
let stringContainer: Container<string> = { value: "Hello, Generics!" };

// コンパイルエラー
// エラー内容(型 'boolean' は制約 'string | number' を満たしていません。)
let boolean: Container<boolean> = { value: false };


const main = () => {
    console.log(numberContainer.value);
    console.log(stringContainer.value);
}

main();

```
→stringまたはnumberのみ定義しているため、booleanの値はエラーが発生する
Laravel用アクティビティログライブラリを作りました！！


こんにちは，ご覧いただきありがとうございます。

Laravel用のアクティビティログライブラリを作成しました。

https://github.com/ikepu-tp/laravel-activity-log

## 機能

- ユーザーのアクティビティを記録
- ログイン中ユーザーのアクティビティを表示

## 特徴

- ユーザーごとのアクティビティ履歴を保存できます
- ユーザーごとにアクティビティ履歴を表示できます

## インストール

### 1.composerでインストール

```bash
composer require ikepu-tp/laravel-activity-log
```

### 2.設定ファイルの設定

```bash
php artisan vendor:publish --tag=ActivityLog-config
```

### 3.マイグレーション

```bash
php artisan migrate
```

### 4.ミドルウェアを追加

```diff_php:app\Http\Kernel
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+       \ikepu_tp\ActivityLog\app\Http\Middleware\ActivityLogMiddleware::class,
    ];
```

これでインストールは終了です。
[http://localhost/activity-log](http://localhost/activity-log)にアクセスしてみてください。
あなたのアクティビティが表示されていると思います。

:::note info
もし`/activity-log`を変更したい場合，ルーティングを変更してください。

```php:/route/activity-log.php
Route::group([
    "middleware" => "auth"
], function () {
    Route::get("activity-log", [ActivityLogController::class, "index"])->name("activity-log.index");
                // ↑ここを変更してください。
});
```

:::

### 5. アクティビティの登録

設定ファイル(`/config/activity-log.php`)の`activities`を編集し，アクティビティを設定してください。

## 今後の更新予定

とりあえず公開したという感じなので今後も機能追加していきたいと思います。
よければGithubのスターやフォローをお願いします！
もちろん，プルリクもお待ちしています！！

## 更新履歴

- 公開しました
SQL 基本的なSELECT文

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/62c1c52d-db69-e888-2431-fb845b4cca9f.png)
　SQLは、関係データベースを操作する言語です。SQLを使えば、表を定義する、表にデータを登録する、表からデータを削除する、条件を指定してデータを検索するなど、さまざまな操作が可能です。

　関係データベースからデータを検索するときにはSELECT、データを追加するときにはINSERT、データを削除するときにはDELETEを使います。また、表を作るときには、CREATE TABLEを使います。

１：SELECT文
　条件を指定してデータを検索するにはSELECT文を使います。SELECT文の基本的な書式を示します。
＜SELECT文の基本的な書式＞
　SELECT ＜列名＞　　← 表示する列名を指定する。

FROM ＜表名＞　← 検索対象の表明を指定する。

WHWRE ＜条件＞　← 検索条件をして指定する。

＜条件式の書き方＞
条件式：列名＝X 意味：列の値＝X
条件式：列名＜X 意味：列の値＜X
条件式：列名＞X 意味：列の値＞X
条件式：列名＜＞X 意味：列の値≠X
条件式：列名＜＝X 意味：列の値≦X
条件式：列名　＞＝X 意味：列の値≧X
条件式：列名　IS NOT NULL 意味：列の値≠空値
条件式：列名　IS NULL 意味：列の値＝空値
条件式：列名　BETWEEN X AND Y 意味：X≦列の値≦Y
条件式：列名　IN (A,B,C) 意味：列の値がA, B, Cのいずれか
条件式：列名　NOT IN（A,B,C） 意味：列の値がA, B, Cのいずれでもない
条件式：列名　LIKEパターン　意味：列の値がパターンに一致する。
react-bootstrap-table2でrefを使って全選択する方法

## 概要
現在が参画しているプロジェクトではテーブルコンポーネントのベースとしてreact-bootstrap-table-nextを使っています。
ある日のタスクでテーブルの行の全選択と全解除を機能追加でつけることになりました。
一番楽なのはreact-bootstrap-table-nextの機能としてある行にチェックボックスをつけることです。
ただ、チェックボックスは小さいのと、クライアントが好んでいるのもボタンだったので
全選択/全解除ボタンを作ることにしました。

## 方針
全選択/全解除ボタンを押した時にtableコンポーネントに渡しているselectRowのonSelectAllを実行させる

## 実装

実際の業務のコードを抽象化したものです。

- useAllSelectフックでtableコンポーネントへのrefと全選択/解除のための
ボタンコンポーネントを受け取り、tableRefをテーブルコンポーネントに渡す

- AllSelectButtonのonClickが発火されたら
tableRef?.current.selectionContext.handleAllRowsSelectが実行される


selectionContext.handleAllRowsSelectが内部でonSelectRowに渡しているonSelectAllを実行している


```App.jsx
import React, { useRef } from "react";
import BootstrapTable from "react-bootstrap-table-next";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";
import { useAllSelect } from '../Hooks/AllSelect';

function App() {

  // 全選択/解除を行うためのカスタムフック
  const [tableRef, AllSelectButton] = useAllSelect();

  const handleSelectAll = (isSelected) => {
    // 全選択 or 全解除する時に行う処理
  };

  const columns = [
    // Define your columns here
  ];

  const data = [
    // Your data here
  ];

  const selectRow = {
    mode: "checkbox",
    hideSelectAll: true,
    onSelectAll: handleSelectAll,
  };

  return (
    <div>
      <AllSelectButton allSelectButtonName={'全選択'} allUnSelectButtonName={'全解除'} />
      <BootstrapTable
        ref={tableRef}
        keyField="id"
        data={data}
        columns={columns}
        selectRow={selectRow}
      />
    </div>
  );
}

export default App;

```

```AllSelect.jsx
import React, { memo, useRef } from 'react';
import Button from '../../../atoms/Button';

export function useAllSelect() {
  const tableRef = useRef(null);
  const handleAllUnSelect = (e) => {
    tableRef?.current.selectionContext.handleAllRowsSelect(e, true);
  };
  const handleAllSelect = (e) => {
    tableRef?.current.selectionContext.handleAllRowsSelect(e, false);
  };

  const AllSelectButton = memo(
    ({ color, allSelectButtonName = '全選択', allUnSelectButtonName = '全選択解除', ...props }) => (
      <div className="mt-5 flex gap-x-5">
        <Button color={'success'} onClick={(e) => handleAllUnSelect(e)}>
          {allUnSelectButtonName}
        </Button>
        <Button color={'success'} onClick={(e) => handleAllSelect(e)}>
          {allSelectButtonName}
        </Button>
      </div>
    )
  );

  return [tableRef, AllSelectButton];
}

```

## 最後に
ドキュメントだけでなく、ソースを見ることは大事だと改めて感じました。
refを使って実行するのはすぐにわかるが、何が全選択を行うものなのかが
ドキュメントを見てもわからなかった、qiitaやzennにも参考になるようなものがなかった
(もしかして調べ方が悪いだけかも、、、笑)
内部のソースを見てようやくselectionContextにアクセスすればいけると分かった
【Python】変数・関数・クラスなどについてまとめ

 # 【Python】変数・関数・クラスなどについてまとめ


①変数・・・値（データ）に名前をつけたもの
```py
my_name = "佐藤"  # my_nameが変数
number = 100      # numberが変数
```

②関数・・・様々な処理が１つにまとまっているもの


③クラス・・・変数や関数をまとめたもの

④オブジェクト・・・データと、そのデータに関する処理を行う関数が一塊になっているもの。

⑤インスタンス・・・オブジェクトと同じ意味（多分…）
【ちょっと便利な小技_part 6】VSCodeのカスタムSnippet編

今回の小技はVSCodeのカスタムSnippetについて解説します。
自分好みにカスタムしたSnippetを使うことで無駄な手間を省けて作業時間を短縮できます。
今回はflutterで使われているdartのSnippetを作成します。
とても簡単なので是非試してみてください

# カスタムSnippetの追加方法
**1\.VSCodeを開いて画面の左下にある設定を押して、『ユーザースニペット』を選択**
![スクリーンショット 2023-08-24 20.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/a9944322-7250-6a13-6143-4fab3463eaca.png)

**2\.下記の表示が出るのでその中からDartを選択**
※下記の画像の場合既にdartのSnippetが存在しているため一番上に表示されていますが、初めての追加の場合下から探して選択をしてください。
![スクリーンショット 2023-08-24 20.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/13778497-e3e9-004a-c304-0a87d74df519.png)

**3\.dart.jsonが開かれるのでそこに下記のフォーマットでコードを追加**

```ruby:dart.json
"ここにSnippet名を記載": {
  "prefix": "ここにトリガーとなるキーワードを記載",
  "body": [
    "ここに呼び出したいコードを記載",
    "ここに次の行の記載",
    "ここにその次の行を記載"
  ],
  "description": "ここにSnippetの説明を記載"
}
```

**4\.最後に実際に使ってみよう**
※確認は下記のSnippetで実施
```ruby:dart.json
"TestWidget": {
  "prefix": "testwidget",
  "body": [
    "Widget _testWidget() {",
    "    return Container(",
    "      height: 10,",
    "      width: 10,",
    "      color: Colors.black,",
    "      child: const Text(\"TestWidget\"),",
    "    );",
    "  }"
  ],
  "description": "TestWidget"
}
```

使いたいところでトリガーとなるキーワードを入力して作成したSnippetを選択すると・・・
![スクリーンショット 2023-08-24 21.22.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/09bd2e3f-4241-0d75-c07d-e4d512fcc7fb.png)


# 結果
出てきました！！！！
![スクリーンショット 2023-08-24 21.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/cda478e5-acae-87a8-8044-ed2bc61f3ee9.png)


# 最後に
これで自分のよく使うWidgetなどを作れば作業の短縮になります