OmniAICreator/Qiita-1.07M huggingface dataset:
フロントエンド vs バックエンド：どっちか迷ったら〇〇！

Webエンジニアとしてキャリアを歩む上で、フロントエンドとバックエンド、どちらを選ぶべきか悩んでいませんか？実はどちらを選ぶべきかという問いに対する、明確な答えはありません。

なぜならフロントエンドエンジニアはいずれバックエンドの知識を必要とする場面に直面し、バックエンドエンジニアもフロントエンドの知識を学ぶ必要が出てくるからです。**どちらの道を選んだとしても、最終的には両方の領域を学ぶ**ことになります。私自身もともとはバックエンド側でしたが、結局フロント側の実装経験もあります。

この記事ではフロントエンドとバックエンドの違いやそれぞれの役割、そしてどちらを選ぶべきかという疑問に対する私なりの考えを解説します。この記事を読むと、ご自身に合ったキャリアパスを選択するためのヒントを得ることができます。

[>> IT未経験者にはインフラエンジニアが狙い目！？](https://taishi-official.com/2024/05/01/2236/)


<iframe width="560" height="315" src="https://www.youtube.com/embed/6-UF0fxXd2M?si=SMmEc4_sc1sLfQPd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## フロントエンドとバックエンドの違い
こちらでフロントエンド・バックエンドの違いについて、ご紹介します。ただフロントエンド・バックエンドは明確に区分があるわけでなく、人によって技術範囲が異なります。こちらで紹介するものを一種の目安として、ご認識ください。

### フロントエンドとは
WebサイトやWebアプリケーションにおいて、ユーザーが直接目にする部分、つまり見た目や操作性に関わる部分をフロントエンドと呼びます。フロントエンドはWebサイトの顔となる部分であり、ユーザーエクスペリエンス（UX）に大きく影響します。

例えばWebサイトのデザイン、ボタンの配置、文字の大きさ、アニメーションなど、ユーザーがWebサイトにアクセスした際に目にするもの、操作するものはすべてフロントエンドの領域です。

[>> フロントエンドで使われる技術](https://taishi-official.com/2025/02/25/3196/#toc3)

[>> フロントエンドエンジニアの仕事内容と必要なスキル](https://taishi-official.com/2025/02/25/3196/#toc4)

### バックエンドとは
WebサイトやWebアプリケーションにおいて、ユーザーからは直接見えない部分、つまりデータの処理や管理に関わる部分をバックエンドと呼びます。バックエンドはWebサイトの裏側を支える部分であり、Webサイトの機能を実現するために重要な役割を果たします。

例えば、ユーザーのログイン認証、データの保存、データベースとの連携、サーバーの管理など、ユーザーがWebサイトを利用する上で必要な処理はすべてバックエンドで行われています。

[>> バックエンドで使われる技術](https://taishi-official.com/2025/02/25/3196/#toc6)

[>> バックエンドエンジニアの仕事内容と必要なスキル](https://taishi-official.com/2025/02/25/3196/#toc7)

## 結局フロントエンドとバックエンドのどちらを選べばいい？
エンジニアを目指す方にとって、最初の大きな分岐点となるのがフロントエンドとバックエンドの選択です。悩めば悩むほど、より深みにはまっていくかもしれません。こちらではその悩みに対する具体的な判断材料と、私なりの回答について共有します。

### 結論：基本的にはどちらを選んでもOK
結論から言うと、フロントエンドとバックエンドのどちらから始めても問題ありません。なぜならエンジニアとしてのキャリアを積んでいく中で、**最終的には両方の知識が必要**になってくるからです。

特に現代のWeb開発では、**フロントエンドとバックエンドの境界線が徐々に曖昧**になってきています。Node.jsのようにJavaScriptをサーバーサイドでも使えるようになったり、フルスタックフレームワークが普及したりと、技術の融合が進んでいます。

[>> その理由の詳細はコチラ！](https://taishi-official.com/2025/02/25/3196/#toc10)

### 私の回答：迷ったらバックエンドがおすすめ
とはいえ「どちらを最初に学ぶべきか」という問いに対して、個人的な意見を述べさせていただきます。もしあなたがどちらを選ぶか迷っているのであれば、**個人的にはバックエンドをおすすめ**します。

[>> バックエンドをおすすめする理由](https://taishi-official.com/2025/02/25/3196/#toc12)

### 最終的には自分の興味を優先しよう
バックエンドを推奨することを述べてきましたが、最も重要なのは自分自身の興味や適性です。

- 視覚的なフィードバックがモチベーションになる方はフロントエンド
- データや論理的な思考が好きな方はバックエンド
- デザインや直感的なインターフェースに関心がある方はフロントエンド
- システム設計やパフォーマンス最適化に興味がある方はバックエンド

どちらから始めても、追々もう片方の領域も学ぶことになります。そのため最初は自分が興味を持てる方、**モチベーションを維持しやすい方を選ぶ**のが良いでしょう。結局のところ、エンジニアとしての成長には継続的な学習が不可欠です。

## まとめ
今回はこれからエンジニアを目指したい方向けに、フロントエンドとバックエンドの違いと、どちらを選べばいいのかについて紹介しました。また開発でAIを活用している所感として、私個人としては**悩むのならバックエンド**がおすすめなことを述べました。

ただこれからはAIなどの進歩によって、**フロントエンドとバックエンドの垣根がどんどん曖昧**になっていくことが想定されます。フロントエンドとバックエンドのどちらか一方ではなく、どちらを先に学びたいかの観点で、ご自身の興味・関心に合わせて選択いただければなと思います。

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- YouTube：https://www.youtube.com/@Engineer_ILLBE

<br>

最後にいいねお願いします:thumbsup:
UCB1（Upper Confidence Bound）とは？


## **1. はじめに**
強化学習やモンテカルロ木探索（MCTS）において、探索（Exploration）と活用（Exploitation）のバランスを取ることは非常に重要です。その中で代表的な手法の一つが**UCB1（Upper Confidence Bound 1）**です。

UCB1は、マルチアーム・バンディット問題（Multi-Armed Bandit Problem）でよく使用される手法であり、各選択肢（アーム）に対して「**どれくらい試行すべきか**」を決定します。MCTSでも、どのノード（局面）を探索すべきかを決める際に使われます。


## **2. UCB1の数式と直感的な理解**
UCB1のスコアは次の式で計算されます。

\[
UCB1 = \frac{w_i}{n_i} + C \sqrt{\frac{\log N}{n_i}}
\]

ここで、
- \( w_i \) : アーム \( i \) の累積報酬（勝利回数など）
- \( n_i \) : アーム \( i \) が選ばれた回数
- \( N \) : 全体の試行回数
- \( C \) : 調整パラメータ（探索の強さを決める）

この数式には、以下の2つの要素が含まれています。
1. **平均報酬（Exploitation）**: \( \frac{w_i}{n_i} \) は、そのアームがこれまでに得た報酬の平均値を表します。
2. **探索の重要度（Exploration）**: \( \sqrt{\frac{\log N}{n_i}} \) は、そのアームが選ばれていない場合の不確実性を示します。

この2つの要素を足し合わせることで、報酬が高いアーム（手）を活用しながら、まだ十分に試行されていないアーム（手）も探索することができます。


## **3. UCB1の動作の流れ**
1. 各アーム（手）を最初に1回ずつ試す。
2. 以降、各アームのスコアをUCB1の式で計算する。
3. 最もスコアが高いアームを選択する。
4. そのアームの報酬を記録し、試行回数を更新する。
5. 2〜4を繰り返す。

このアルゴリズムの特長は、**試行回数が少ないアームには高いスコアが与えられる**ため、未知の選択肢を探索しつつ、報酬の高いアームを活用できる点です。


## **4. UCB1の応用例**
### **① マルチアーム・バンディット問題**
カジノのスロットマシンのように、複数の選択肢（アーム）の中から最適なものを選びたい場合に適用できます。

### **② モンテカルロ木探索（MCTS）**
MCTSでは、ゲームの局面を探索する際にUCB1を使って「どのノードをさらに探索するべきか」を決定します。例えば、囲碁や将棋のAIが次の手を選ぶ際に使用されます。

### **③ オンライン広告の最適化**
異なる広告（バナーや動画）を配信し、ユーザーのクリック率を最大化するために、UCB1を利用して最適な広告を選択できます。


## **5. まとめ**
UCB1は、**既存の良い選択肢を活用しつつ、新しい選択肢も試すというバランスを取るための手法**です。特に、マルチアーム・バンディット問題やMCTSなどの分野で広く使われています。

この手法を活用することで、限られた試行回数の中で効率的に最適な選択肢を見つけることが可能になります。AIや強化学習に興味がある方は、ぜひUCB1を実装して試してみてください！
個人的備忘録：fatal: a branch named '〇〇' already exists の対処法とブランチ管理のポイントについてまとめてみた

## はじめに
Gitを使用していると、ブランチを確認したり、切り替えたりする機会が多くあります。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、ブランチの確認や変更に関する基本的なコマンドを紹介します。

## 書こうと思ったきっかけ
Gitを利用している際に、`fatal: a branch named 'feature/generateHandler' already exists` というエラーに遭遇し、その対処法を調べることがありました。

また、日々の開発でブランチ操作を頻繁に行うため、基本的なコマンドを整理しておきたいと思い、この記事を書くことにしました。

## 1. Gitのブランチを確認するコマンド
### ローカルブランチを確認
```sh
git branch
```
現在のローカルリポジトリ内のブランチ一覧を表示し、現在チェックアウトされているブランチには `*` が付きます。

### リモートブランチを確認
```sh
git branch -r
```
リモートリポジトリに存在するブランチ一覧を表示します。

### ローカル・リモートの両方のブランチを確認
```sh
git branch -a
```
ローカルとリモートのすべてのブランチを表示します。

### 現在のブランチ名のみを取得
```sh
git rev-parse --abbrev-ref HEAD
```
現在のブランチ名だけを表示したい場合に便利です。

### ブランチの詳細情報を確認
```sh
git show-branch
```
ブランチの詳細な履歴を確認できます。

### ブランチの最新のコミット情報も含めて一覧表示
```sh
git branch -v
```
各ブランチの最新のコミット情報も一緒に表示できます。

## 2. Gitのブランチを変更する方法
### 既存のブランチに切り替える
```sh
git switch ブランチ名
```
または
```sh
git checkout ブランチ名
```
`git switch` は `git checkout` の代替として導入されたコマンドで、ブランチの切り替えに特化しています。

### 新しいブランチを作成して切り替える
```sh
git switch -c 新しいブランチ名
```
または
```sh
git checkout -b 新しいブランチ名
```

### 前のブランチに戻る
```sh
git switch -
```
または
```sh
git checkout -
```
直前にいたブランチに戻ることができます。

### リモートブランチに切り替える
```sh
git switch --track origin/リモートブランチ名
```
または
```sh
git checkout -b ローカルブランチ名 origin/リモートブランチ名
```
リモートのブランチをローカルにチェックアウトする場合に使います。

### 変更をコミットせずにブランチを変更する場合
```sh
git stash
git switch 切り替えたいブランチ名
git stash pop  # 必要なら変更を戻す
```
`git stash` で一時的に変更を退避し、`git switch` でブランチを切り替え、`git stash pop` で元に戻せます。

### 変更をコミットせずに強制的にブランチを変更する
```sh
git switch -f ブランチ名
```
または
```sh
git checkout -f ブランチ名
```
変更を破棄してブランチを切り替えたい場合に使用します。（※注意: 未コミットの変更が消えるため慎重に使用してください。）

## 3. `fatal: a branch named 'feature/generateHandler' already exists` の対処方法
このエラーは `feature/generateHandler` というブランチがすでに存在しているため、新規作成ができないことを示しています。

### 既存のブランチの確認
```sh
git branch -a
```
ローカルとリモートのブランチをすべて確認できます。

### 既存のブランチに切り替える
```sh
git switch feature/generateHandler
```
または
```sh
git checkout feature/generateHandler
```

### リモートブランチがある場合
```sh
git switch --track origin/feature/generateHandler
```
または
```sh
git checkout -b feature/generateHandler origin/feature/generateHandler
```
リモートのブランチをローカルにチェックアウトする場合に使います。

### 既存のブランチを削除して作り直したい場合
⚠️ **注意: 既存のブランチを削除すると、コミットが失われる可能性があるため慎重に実行してください。**

#### ローカルブランチを削除
```sh
git branch -d feature/generateHandler
```
（もしマージされていない変更がある場合、強制削除 `-D` を使う）
```sh
git branch -D feature/generateHandler
```

#### 削除後、新しく作成して切り替える
```sh
git switch -c feature/generateHandler
```
または
```sh
git checkout -b feature/generateHandler
```

## まとめ
1. `git branch -a` でブランチの存在を確認する。
2. 既存のブランチなら `git switch feature/generateHandler` で切り替える。
3. リモートブランチなら `git switch --track origin/feature/generateHandler` で取得。
4. もし作り直したいなら、`git branch -D feature/generateHandler` で削除後、新規作成。

以上の手順で、適切な方法を選んでブランチを管理しましょう！
内部結合(INNER JOIN)と外部結合(OUTER JOIN)


今回は内部結合と外部結合について勉強したのでまとめてみました
以下は記述なんですけど、間違っている場合は教えてください。
まず、２つテーブルには共通のカラムが必要になります。

　　　　goodslist　　　　　　　    batch_number

<img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/4648c4ec-7f4f-43c9-a41a-c500825024e8.png">  <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/d9034de5-8adf-4102-a855-ab1b53eb3db7.png">



## 内部結合(INNER JOIN)

共通のカラムを軸に情報を表示します。

SQL文：
SELECT * FROM テーブル名１ INNER JOIN テーブル名２ ON テーブル名１.共通のカラム名 = テーブル名２. 共通のカラム名;

※	INNERはなくでも大丈夫


SQL文：

```ruby:qiita.rb
SELECT * FROM テーブル名１ INNER JOIN テーブル名２ ON テーブル名１.共通のカラム名 = テーブル名２. 共通のカラム名;
```

そしてこの実例には

```ruby:qiita.rb

 SELECT * FROM goodslist INNER JOIN batch_number ON goodslist.id = batch_number.goods_id;
```
となります。

実行すると下図となります。
![截圖 2025-02-21 18.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/361df943-b66a-4e45-87d6-f6f5df70f517.png)


更に絞りたい時の場合は「*」を「テーブル名.カラム名」一つずつ(示したいカラム)に替わります。

```ruby:qiita.rb
SELECT
    batch_number.id ,
    goodslist.id ,
    goodslist.name ,
    batch_number.batch_number ,
    batch_number.quantity ,
    batch_number.enterdate ,
    batch_number.order_number 
FROM goodslist 
INNER JOIN batch_number 
    ON goodslist.id = batch_number.goods_id
```
実行すると下図となります。
![截圖 2025-02-21 19.24.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/2d773daf-82f6-4b34-bc67-649234abc966.png)


## 外部結合(OUTER JOIN)
テーブル側を軸に情報を表示します。

### 「LEFT JOIN」と「RIGHT JOIN」
LEFTは左の意味である、つまりLEFT JOINを使うとFROMで指定した側のテーブルを軸に情報を表示します。
右の意味であるRIGHT JOINを使うとJOINで指定した側のテーブルを軸に情報を表示します。


SQL文：
```ruby:qiita.rb
SELECT * FROM テーブル名１ LIFT JOIN テーブル名２ ON テーブル名１.共通のカラム名 = テーブル名２. 共通のカラム名;

SELECT * FROM テーブル名１ RIGHT JOIN テーブル名２ ON テーブル名１.共通のカラム名 = テーブル名２. 共通のカラム名;
```

実行すると下図となります。

```ruby:qiita.rb
SELECT * FROM goodslist LEFT JOIN batch_number ON goodslist.id = batch_number.goods_id;
```
![截圖 2025-02-21 20.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/616e18b8-d6c8-4f8d-89e6-f5cade344094.png)


```ruby:qiita.rb
SELECT * FROM goodslist RIGHT JOIN batch_number ON goodslist.id = batch_number.goods_id;
```
![截圖 2025-02-21 18.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017245/361df943-b66a-4e45-87d6-f6f5df70f517.png)
WSL2へKali LinuxをインストールしてTryHackMeへVPN接続する(2025/2月)

# 概要、目的
[7日間でハッキングをはじめる本(ISBN: 9784798181578)](https://www.shoeisha.co.jp/book/detail/9784798181578) を読みながらTryHackMeで学習するにあたって、本書に記載されている VirtualBox ではなく WSL2 で Kali Linuxの環境を作ったので、備忘のための記録です。

# 0.前提
- OS : Windows 11 Home 23H2
- ストレージに30GB以上の空きがあること（インストール後、28GB程度の仮想ディスクが作成されます。空き容量無くなりかけました、、）
- WSL2がインストール済であること

## 参考にした情報
- (a) [Kali LinuxをWSL2に導入(Qiita, san_bay3さん)](https://qiita.com/san_bay3/items/9c0c0f4a250e4fa73ede)
- (b) [Kali Linux をWSL2にインストールする(Qiita, ryotaro76さん)](https://qiita.com/ryotaro76/items/6d96784edb62ec8fc90a)
- (c) [Kali Linux WSL2 cannot execute Windows binaries due to systemd(Github)](https://github.com/microsoft/WSL/issues/9887)
    - kexでウィンドウが開かなかったのでInteropの設定追加をしました
- (d) [Debianでlocaleの設定(Zenn)](https://zenn.dev/oto/articles/9d18a4de1a15e5)
    - 本書にも記載の dpkg-reconfigure での locale 設定は古いとかいう記述や、それ以前に locale は日本語化しないほうがいいというコメントがあったので、各手順の要否をご自身で判断ください。（私は locale 変更しませんでした）

# 1.WSL2 へ Kali Linuxをインストールする

参考情報(a), (b)

## インストール
```powershell:powershell
wsl --update && wsl --install -d kali-linux
```

インストールしたら```wsl -d kali-linux```で起動します。

## パッケージアップデート、解析ツール類インストール

```sh:shell
sudo apt update && sudo apt upgrade && sudo apt autoclean
sudp apt install kali-linux-large
```

時間がかかるので、終わるまで梅昆布茶でもお楽しみください。途中、入力を求められたので、それぞれ以下のように入力しました。
1. Configuring macchanger : yes
1. Configuring kismet-capture-common : yes / kali
1. Configuring wireshark-common : yes
1. (名前失念、sslhをinetd経由で実行するかstandalone serverで実行するか) : inetd

## GUIのインストール

参考情報(a)～(d)

1. (c)に従って設定ファイルを新規作成します
    ```sh:shell
    sudo vi /usr/lib/binfmt.d/WSLInterop.conf
    ```
    ```conf:/usr/lib/binfmt.d/WSLInterop.conf
    :WSLInterop:M::MZ::/init:PF
    ```
1. GUIのインストール
    ```sh:shell
    sudo apt install kali-win-kex
    ```
    ```kex --win -s -m```でウィンドウが起動すればOK。初回はパスワード設定を要求されるので、テキトーな6文字以上のパスワードを設定してください。その後聞かれることはない、、はず。
1. 日本語化やChromeのインストール
    - 本書に記載されている各種準備は、各自の判断で必要なものを実施すると良いです。私はどれもやってないので、本記事では割愛します。

## TryHackMeへのVPN接続

本記事では詳細割愛し、概要と躓きポイントだけ。

1. TryHackMeへの登録
1. Kali Linux上のFirefoxでTryHackMeへログイン
1. 右上のアイコン＞Access をクリック
1. "Access via OpenVPN"の画面で、"Download configuration file"ボタンで設定ファイルをダウンロード
1. ダウンロードしたファイル(~/Downloads/XXXXXX.ovpn)を確認し、ターミナルで以下コマンドを実行
    ```sh:shell
    sudo openvpn ~/Downloads/XXXXXX.ovpn
    ```
1. ↑を実行したターミナルは開いたままにして、Firefoxで http://10.10.10.10 へ接続。エラー出ない画面が開けばOK。
    - 本書では"Access via OpenVPN"の画面でリフレッシュボタンを押すと接続確認できる、と記載されていたが、私の環境では"Connected"になりませんでした。Firefoxだからかな？

以上
C#でExcelの画像の位置を取得する

Excelの画像の位置を取得するとは、Excelのワークシートやドキュメント内の画像を特定し、位置を特定するプロセスを指します。これは、適切な配置の確保、一貫性のあるレイアウトの作成、画像の配置に関する問題のトラブルシューティングなど、さまざまな目的に役立ちます。この記事では、無料の.NET Excelライブラリを使用して、**C#でExcelワークシート内の画像の位置を取得する**方法を紹介します。

## 無料ライブラリーのインストール
始める前に、まず[**Free Spire.XLS for .NET**](https://www.e-iceblue.com/Introduce/free-xls-component.html)というライブラリをインストールする必要があります。これは、Microsoft Officeをインストールすることなく、.NETアプリケーションでXLSまたはXLSXファイルを操作するためのスタンドアロンのフリーExcelライブラリです。

以下のリンクからライブラリをダウンロードするか、[NuGet](http://www.nuget.org/packages/FreeSpire.XLS/)経由で直接インストールすることができます。

https://www.e-iceblue.com/Download/download-excel-for-net-free.html


## C#でExcelの画像の位置を取得する
ここで、エクセルの画像の座標は、実際には画像の左上隅が位置する特定の行と列を指す。 以下は、エクセルのワークシートで画像の位置を取得する手順です：
1. `Workbook`クラスのオブジェクトを作成する。
1. `Workbook.LoadFromFile()`メソッドでExcelファイルをロードする。
1. `Workbook.Worksheets[int]`プロパティで特定のワークシートを取得する。
1. **`Worksheet.Pictures[int]`** プロパティを通して特定の画像を取得する。
1. **`ExcelPicture.TopRow`** プロパティと **`ExcelPicture.LeftColumn`** プロパティを通して、画像の左上が位置する行と列を取得する。

**サンプルC#コード：**
```csharp
using Spire.Xls;

namespace GetImgLocation
{
    class Program
    {
        static void Main(string[] args)
        {
            // Excelファイルを読み込む
            Workbook wb = new Workbook();
            wb.LoadFromFile("ExcelPicture.xlsx");

            // 最初のワークシートを取得する
            Worksheet sheet = wb.Worksheets[0];

            // ワークシートの最初の画像を取得する
            ExcelPicture picture = sheet.Pictures[0];

            // 画像の左上隅が位置する行と列を取得する
            string row = picture.TopRow.ToString();
            string column = picture.LeftColumn.ToString();

            // 結果を出力する
            Console.Write("location:(" + row + "，" + column + ")");
            Console.ReadLine();
        }
    }
}
```
**出力結果：（画像は7行4列目に位置する）**
![ExcelPictureLocation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/701db666-b0cb-45cc-9ec1-408e1777f766.png)

* * *

無料の.NETライブラリは、その他多くのエクセル処理機能もサポートしている。より多くのデモについては、以下のリンクをチェックしてください：

https://www.e-iceblue.com/Tutorials/Spire.XLS/Spire.XLS-Program-Guide/Spire.XLS-Program-Guide-Content.html
追伸: AsyncIterator.withResolvers は ReadableStream 内のメソッドを外部化した方が作りやすい？

[前回](https://qiita.com/juner/items/a805099707b944274b74) あんなに長いコードを書いていたのに、よくよく考えると ReadableStream も asyncIterator が実装されていることを思い出したのでもっと簡単に書けることに気が付きました。

https://streams.spec.whatwg.org/#rs-asynciterator

具体的には ReadableStream の内部で使われている ReadableStreamDefaultController を使うとですね。

https://developer.mozilla.org/ja/docs/Web/API/ReadableStreamDefaultController

Promise.withResolvers の作り方と同じ感じに作ると次の様な感じで作れます
（ ※ReadableStream の start は 同期的に実行されます。

```js
(globalThis.AsyncIterator ??= {}).withResolvers ??= ({ cancel } = {}) => {
  let controller;
  const stream = new ReadableStream({
    start(controller_) {
      controller = controller_;
    },
    cancel() {
      if (typeof cancel === "function") cancel();
    },
  });
  return {
    values: stream.values(),
    resolve: controller.enqueue.bind(controller),
    complete: controller.close.bind(controller),
    reject: controller.error.bind(controller),
  };
};
```

※ 直接 ReadableStrem を values として返していますが、 ReadbleStream は cancel できるので withResolvers の引数として cancel コールバックを追加しています。 ニュアンス signal を返してもよいかもしれません

以上。

[playground](https://livecodes.io/?x=id/gnqs253etpq)

# 追伸の追伸

ReadableStream.prototype.values() ってよくよく思ったら Stream の transferable と同様に Safari ではまだ実装できていないやんけ！！！(2025/2/28 現在)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32143/dba8d83a-ab0e-4a25-afb5-6a8d290728f2.png)
https://caniuse.com/mdn-api_readablestream_values

なので Gemini さんに次の様なお願いすると次の様なコードになりました。 
（cancel ってこの動きであっているっけ？

```text
次のコードを ReadableStream を使わない形に修正していただけませんでしょうか？
(※コードは先述のものｎ省略）
```

```js
(globalThis.AsyncIterator ??= {}).withResolvers ??= ({ cancel } = {}) => {
  const queue = [];
  let closed = false;
  let error = null;

  const asyncIterator = {
    [Symbol.asyncIterator]() {
      return this;
    },
    async next() {
      if (error) {
        throw error;
      }
      if (queue.length === 0 && closed) {
        return { done: true };
      }
      if (queue.length === 0) {
        await new Promise(resolve => {
          const check = () => {
            if (queue.length > 0 || closed || error) {
              resolve();
            } else {
              setTimeout(check, 0);
            }
          };
          check();
        });
      }
      return { value: queue.shift(), done: false };
    },
    return() {
      closed = true;
      if (typeof cancel === "function") cancel(); // キャンセル処理
      return Promise.resolve({ done: true });
    },
    throw(err) {
      error = err;
      if (typeof cancel === "function") cancel(); // キャンセル処理
      return Promise.reject(err);
    }
  };

  return {
    values: asyncIterator,
    resolve: (value) => { queue.push(value); },
    complete: () => {
      closed = true;
      if (typeof cancel === "function") cancel(); // キャンセル処理
    },
    reject: (err) => {
      error = err;
      if (typeof cancel === "function") cancel(); //キャンセル処理
    },
  };
};
```
【Rails】セッション固定攻撃(Session Fixation)

# はじめに
こんにちは。私はアメリカで独学でエンジニアを目指している者です。
前回はRailsにおけるセッションの役割と保存場所について解説しましたが、今回はセッション固定攻撃（Session Fixation）についてご説明いたします。

### セッション固定攻撃とは

セッション固定攻撃とは、**攻撃者があらかじめ用意したセッションIDをユーザーに使用させ、その後ユーザーが認証を行った際に、その固定されたセッションIDに認証情報が紐づいてしまう**攻撃手法です。

なお、セッションハイジャックという手法も存在しますが、こちらは暗号化されていない通信や脆弱なランダム生成アルゴリズムを狙い、セッションIDを盗聴または予測する手法であり、セッション固定攻撃とは異なります。

#### 仕組み
1. 攻撃者があらかじめセッションIDを用意し、URLにセッションを埋め込んだりレスポンスヘッダを追加してCookieを強制する方法などで押し付けます
2. ユーザーがログインすると、セッションIDが再生成されていない場合、その固定されたIDのまま認証情報が紐づく可能性があります。
3. 攻撃者はそのセッションIDを知っているため、ユーザーになりすますことができます。

#### 被害とリスク
- ユーザーアカウントの乗っ取り
- 個人情報や機密情報の漏えい
- 不正操作による損害

---

### Railsでのセッション管理と対策

#### 1. `reset_session` の活用
ログイン時に必ず `reset_session` を呼び出すことで、既存のセッションを破棄し、新しいセッションIDを発行します。これによって、攻撃者が固定したセッションIDは無効化され、ユーザーのログイン後のセッションを保護できます。

##### コード例
```ruby
class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])
    if user && user.authenticate(params[:password])
      reset_session #これを追加する
      session[:user_id] = user.id
      redirect_to dashboard_path, notice: "ログインしました"
    else
      flash.now[:alert] = "メールアドレスまたはパスワードが違います"
      render :new
    end
  end
end
```

#### 2. Cookieのセキュリティ設定

- **Secure属性**：HTTPS通信時のみCookieが送信されるように設定。
- **HttpOnly属性**：JavaScriptからのアクセスを禁止し、XSSによるCookie窃取を防止。

Railsの `config/initializers/session_store.rb` などで設定する例:
```ruby
Rails.application.config.session_store :cookie_store,
  key: '_app_session',
  secure: Rails.env.production?,
  httponly: true
```

#### 3. セッションタイムアウト
一定時間操作がない場合はセッションを破棄し、再度ログインを要求することで、不正なセッション利用を防ぎます。

#### 4. CSRF対策
RailsではデフォルトでCSRFトークンによるフォーム保護が有効です。セッション固定攻撃を直接防ぐものではありませんが、セッションを悪用される一部の攻撃リスクを低減できます。

---

### まとめ

- セッション固定攻撃を防ぐためには、**ログイン後のセッションID再生成（`reset_session`）** が不可欠。
- 併せて、Cookieの属性（`Secure`, `HttpOnly`）やセッションタイムアウトの適切な設定、CSRF対策などを組み合わせることで、総合的にセッション安全性を高められます。Railsの標準機能を活用し、脆弱性のない安全なWebアプリケーションを構築しましょう。
rex0220 印刷屋プラグイン 一覧画面のPDF作成

[rex0220 印刷屋プラグイン](https://qiita.com/rex0220/items/9be2d9b20a3a1f016c76)で、一覧画面の印刷をしてみます。

# 概要

一覧画面のレコードを PDF に出力します。
一覧画面で表示されている並び順で作成されます。

![2025-02-28_11h34_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5f0e5f60-dc98-4e36-81ad-8bf771ac7fc4.png)

# 一覧画面表示中のレコードを対象

表示中のレコード（最大100件）を対象にします。

![2025-02-28_11h36_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c107d5c3-016a-4122-8adf-441709d46750.png)

# 一覧画面で選択したレコードを対象

「選択したレコードのみ一括処理」をチェックして、レコードを選択後に「案件情報」ボタンをクリック

![2025-02-28_11h39_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4b4ebb41-399a-4494-82c3-342a20ca90eb.png)

# 印刷屋プラグイン設定

![2025-02-28_11h45_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/73238b3b-6fdd-4a37-a73f-ff18de0fc819.png)

一覧画面を対象にした場合は、PDF ダウンロードのみとなり、添付ファイル項目を選択できません。

![2025-02-28_11h47_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6f8b2d4f-51ce-4890-ba35-84e972dc9118.png)

複数ページを考慮して、行の高さを固定にします。

```css:
.pcraft-table-row {
  height: 60px;
}
```

タイトルの当日日付を表示します。
RECS_HTML 関数を指定した場合、$rseq の変数に、レコード処理順の番号（0始まり）が設定されますので、項番に使います。

RECS_HTMLで指定した項目は、項目の設定に従ってカンマ区切り等の書式を適用します。
独自の書式や計算結果を表示したい場合は、ARRAY関数で、項目タイトル、値、クラス名を指定してください。

```js:
RECS_HTML(
    OPT("title","案件情報 " & TODAY() ,
       "pagination","Y",
       "perPage","10"
    ),
    ARRAY("#",$rseq+1),
    顧客名,部署名, 案件名,
    ARRAY("確度",確度,"value-center"),
    プラン費用,オプション費用,合計費用
)
```
[.NetMaui]BindablePropertyの定義で躓いたところ

## 背景
ContentViewを使って、CustomButtonというカスタムコントロールを作ろうとした

## 問題
カスタムコントロールに円を含めようとしたので、CustomRadiusという円の半径を表すプロパティを定義した。
その際double型のBindablePropertyをコードビハインドに定義したが、Exceptionエラーが出てアプリが落ちるようになった。

## 原因
初期値を80という整数にしていたことが原因だった。厳密に80.0など小数点を使って初期値を定義すれば解決した。


    public static readonly BindableProperty CustomRadiusProperty =
        BindableProperty.Create(nameof(CustomRadius), typeof(double), typeof(CustomButton), 80.0, propertyChanged:OnCustomRadiusChanged);

	public double CustomRadius
	{
        get => (double)GetValue(CustomRadiusProperty);
        set => SetValue(CustomRadiusProperty, value);
    }

    static void OnCustomRadiusChanged (BindableObject bindable, object oldValue, object newValue)
    {
        ～～
    }
    #endregion CustomRadius Property
参照仕様をリモートにプッシュできません。最初に pull を実行して変更を統合してください。の予想外の直し方

# エラーが出た経緯
VSCodeを使い始めて数ヶ月して、GitHubと連携することになったので、ネットで見つけた[サイト](https://zenn.dev/ojk/books/github-vscode/viewer/vscode-git)を参考にしてメールアドレスとユーザー名の設定を...
あれ？設定用のメールアドレスってどこだ？
![Email settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4022438/99385220-f819-41d4-aee3-e961b0fdd6b5.png)
([github.com/settings/emails](github.com/settings/emails)の下の方にある設定)
お！この設定を有効にしたら設定用のメールアドレスが出てきたぞ！
これで登録できる！
# エラーの内容
VSCodeでプログラムを書けたから、GitHubにコミットして同期しよ
```参照仕様をリモートにプッシュできません。最初に pull を実行して変更を統合してください。```
？なんだ？とりあえず言う通りにするか→直らず
その後ネットで色々調べてきて
まずは強制的にpull→直らず
次にローカルリポジトリの再作成→直らず
最後に強制的push→直らず
その他諸々→直らず
**もうだめだぁ　おしまいだぁ**
# 解決法
一応意味わからないと思うけどエラーの内容見るか
```git-error.txt
> git push origin main:main
remote: error: GH007: Your push would publish a private email address.        
remote: You can make your email public or disable this protection by visiting:        
remote: https://github.com/settings/emails        
To https://github.com/[ユーザー名]/[リポジトリ名].git
 ! [remote rejected] main -> main (push declined due to email privacy restrictions)
error: failed to push some refs to 'https://github.com/[ユーザー名]/[リポジトリ名].git'
```
```push declined due to email privacy restrictions```
日本語にすると「電子メールによるプライバシー保護のため、プッシュはお断りします。」
メールアドレス？設定見るか
![Email settings-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4022438/6b5e8552-eb4b-425c-8ce8-f2f85409a025.png)
### これだ
この下の設定を切ったら何事もなかったかのようにpush出来ました
めでたしめでたし。
167.Two-sum-Ⅱ　input-array-is-sorted 解答例・ポイント

# 問題内容
与えられたリスト内の数字について、和が目標の数になるような2つの数字の組み合わせをリストにして返しなさいというもの。

# 解答例
```python:sample
class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        left = 0
        right = len(numbers) - 1

        while left < right:
            total = numbers[left] + numbers[right]

            if total == target:
                return [left + 1, right +1]
            elif total > target:
                right -= 1
            else:
                left += 1
```

# この問題の難しいところ
「リスト内の数字をいろいろと組み合わせて作ることができる数字を羅列してから目標の数字と比べる」という考え方をすると処理時間がデータ量次第で膨大になったり、エラーが発生しやすくなったりする。

# ポイント
解答例では、「まずリスト左右の端にポインタを置き、ポインタが指す数字の和と目標値の大小を見て調整する」という考え方のもとプログラムされている。和が目標値よりも大きければ左のポインタをずらすことで和を小さくできる。逆も同様。このような調整は入力されるリストがソート済みであるため可能になっている。
[IaCを学ぼう第4回] Terraform(HCL)におけるリソースIDの動的参照

## これは何？

IaCを学ぼうの第4回、Terraform(HCL)を使う場合のリソースIDの動的参照について説明する記事です。

## どういうこと？

前回までの記事で以下のように`aws_vpc`を利用してVPCを作成したと思います。

```HCL
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "test-vpc"
  }
}
```

今回はここに追加でサブネットを作成できるようにコードを書いてみたいと思います。
書き方は以下です。

```HCL
resource "aws_subnet" "subnet" {
  vpc_id                  = "サブネットを紐づけるVPCのID"
  cidr_block              = "サブネットのIP範囲"
  availability_zone       = "サブネットを作成するアベイラビリティーゾーン"
  map_public_ip_on_launch = "サブネット内に起動したリソースに対してパブリックIPを自動付与するか？"

  tags = {
    Name = "名前タグ名"
  }
}
```

見るとわかる通り、`vpc_id`としてサブネット作成時に「どのVPCに紐づけるか？」という情報が必要になるため
Terraformのコードにおいても紐づけるVPCのIDを記載する必要があります。
ところでこのID、VPC作成後に判明するので`terraform apply`を実行していない状況だとわからないですよね。

じゃあコード書けないじゃんどうすんの？というのが今回の主題となります。

## どうすればいい？

Terraformは`terraform apply`を実行して作成されたリソースが持つ属性(Attribute)を動的参照することができます。

```HCL
resource "aws_subnet" "subnet" {
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = "true"

  tags = {
    Name = "public-subnet-1a"
  }
}
```

上記のように`aws_vpc`の`vpc`という名前のリソースの`id`を参照してねという書き方ができます。
このように書いておくと、サブネットもTerraformで作成したVPCに紐づく形で作成してくれます。

## まとめ

この書き方はほぼ確実に多用するので是非覚えておきましょう。
次回は繰り返し構文について書きますー。
Watson Studio で GPU を使用した Jupyter Notebook を使うには

Watson Studio にはデフォルトで Python 環境 `Runtime 24.1 on Python 3.11` が組み込まれています。

一方、GPUを使用したい場合（GPUを使用したJupyter Notebookを使用したい場合など）に必要なサービス `Runtime 24.1 on Python 3.11 for GPU` はデフォルトではインストールされていません。使用したい場合は別途インストールする必要があります。`Runtime 24.1 on Python 3.11 for GPU` をインストールしたうえで、新しい GPU 環境テンプレートを作成すると、GPU環境を使用できるようになります。

## デフォルトの状態

デフォルトの状態では、GPU環境のテンプレートは存在せず、`新規テンプレート` からも GPU構成は選べません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/153e6c47-0f66-4461-8331-7c8b3a38467c.png)


## Runtime 24.1 on Python 3.11 for GPU のインストール



手順は[こちら](https://www.ibm.com/docs/en/software-hub/5.1.x?topic=installing-runtime-241-python-311-gpu)ですが、IBM Software Hub の他のサービスと同様のインストール手順でインストールできます。

＊ インストールコマンドとしては、次のとおり components として、`ws_runtimes` を指定し、`--extra-vars="cr_name=ibm-cpd-ws-runtime-241-pygpu"` を指定しています。

```
cpd-cli manage apply-cr \
--components=ws_runtimes \
--release=${VERSION} \
--cpd_instance_ns=${PROJECT_CPD_INST_OPERANDS} \
--extra-vars="cr_name=ibm-cpd-ws-runtime-241-pygpu" \
--license_acceptance=true
```

この結果、`cpd-cli manage get-cr-status` で確認すると、デフォルトのRuntimeに加えて、GPU使用のRuntimeが追加されています（最終行）。
```
Component    CR Kind          CR Name                       Creation Timestamp    Namespace    Expected Version    Reconciled Version    Operator Information    Progress    Progress Message               Reconcile History    Status
-----------  ---------------  ----------------------------  --------------------  -----------  ------------------  --------------------  ----------------------  ----------  -----------------------------  -------------------  ---------
ws_runtimes  NotebookRuntime  ibm-cpd-ws-runtime-241-py     2025-02-17T01:44:59Z  wx           10.0.0              10.0.0                10.0.0034               100%        Last reconciliation succeeded  N/A                  Completed
ws_runtimes  NotebookRuntime  ibm-cpd-ws-runtime-241-pygpu  2025-02-27T00:48:38Z  wx           10.0.0              10.0.0                10.0.0034               100%        Last reconciliation succeeded  N/A                  Completed
```

## GPU 環境テンプレートの作成
サービスのインストール後、`新規テンプレート` 作成画面では、Type で `GPU` を選択できるようになっています。GPUを選択すると、自動的にSoftware version に `GPU Runtime 24.1 on Python 3.11` が選択されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/7ca2d89d-3428-4636-8366-c39dd4230266.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/38ab5fa9-0476-4537-8a1c-5faf2966a367.png)

テンプレート作成後、Notebook作成画面で、このランタイムを選択し使用できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/979b3aae-58c5-4800-b016-ca663d4c345c.png)


## 参考

https://www.ibm.com/docs/ja/watsonx/w-and-w/2.1.x?topic=environments-notebook

https://www.ibm.com/docs/ja/watsonx/w-and-w/2.1.x?topic=environments-gpu
CSS 絶対位置と相対位置（メモ）

### 質問
```css
.scholarship05__content01-image {
  position: relative;
  max-width: 832px;
  max-height: 148px;
}

.scholarship05__content01-innerItems {
  position: absolute;
  top: 79.8%;
  left: 45%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.scholarship05__content01-innerText {
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: 32px;
  line-height: 64px;
  letter-spacing: 0%;
  text-align: center;
  padding-left: 20px;
}

<div class="scholarship05__contents">
<div class="scholarship05__content01">
  <img src="./img/scholarship-images/Rectangle 2355.png" alt="" class="scholarship05__content01-image">
  <div class="scholarship05__content01-innerItems">
    <img src="./img/scholarship-images/Group.png" alt="" class="scholarship05__content01-innerIcon">
    <div class="scholarship05__content01-innerText">ご相談</div>
  </div>
</div>
<div class="scholarship05__content02"></div>
<div class="scholarship05__content03"></div>
<div class="scholarship05__content04"></div>
<div class="scholarship05__content05"></div>
</div>
```

上記、
```css
<div class="scholarship05__content01-innerItems">
<img src="./img/scholarship-images/Group.png" alt="" class="scholarship05__content01-innerIcon">
<div class="scholarship05__content01-innerText">ご相談</div>
</div>
```
を、画面サイズが変わってもスタイルがずれないようにしたいです。


### Claude先生より。
画面サイズが変わっても `scholarship05__content01-innerItems` の位置がずれないようにするには、絶対位置指定（`position: absolute`）から相対的な位置指定に変更するのがよいでしょう。

以下のように CSS を修正することをお勧めします：

```css
.scholarship05__content01 {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}

.scholarship05__content01-image {
  width: 100%;
  max-width: 832px;
  height: auto;
  max-height: 148px;
  display: block;
}

.scholarship05__content01-innerItems {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  /* 絶対位置指定から変更 */
  bottom: 0;
  transform: translateY(50%);
}

.scholarship05__content01-innerText {
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: clamp(24px, 5vw, 32px); /* レスポンシブフォントサイズ */
  line-height: 1.5;
  letter-spacing: 0%;
  text-align: center;
  padding-left: 20px;
}

/* 画像のレスポンシブ対応 */
.scholarship05__content01-innerIcon {
  height: auto;
  width: auto;
  max-height: 40px;
}
```

この変更点：

1. `top: 79.8%; left: 45%;` のような固定位置指定を削除し、`bottom: 0; transform: translateY(50%);` に変更して、画像の下部中央に配置するようにしました。

2. フォントサイズを `clamp()` を使って画面サイズに応じて変化するように設定しました。

3. 親要素 `.scholarship05__content01` に `display: flex` と中央揃えの設定を追加し、コンテンツを中央に配置しやすくしました。

4. 行の高さを固定値から相対値に変更して、フォントサイズが変わっても適切な行の高さを維持できるようにしました。

5. アイコン画像にもレスポンシブ対応のスタイルを追加しました。

これにより、画面サイズが変わっても「ご相談」の部分の位置が維持されるようになります。
【競技プログラミング】AtCoder Beginner Contest 377_D問題

# 問題
https://atcoder.jp/contests/abc377/tasks/abc377_c

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)


# 解法手順1
## 1. 入力処理
コード内の`io_func()`関数を用いて、以下の入力を処理する
- **1行目**: 盤面サイズ $N$ とコマ数 $M$ を取得。
- **2行目以降**: 各コマの位置（行番号、列番号）を取得。

## 2. ナイトの移動ルールを定義
ナイトが移動できる8方向をタプルで定義する
```python
moves = [(2, 1), (1, 2), (-1, 2), (-2, 1),
         (-2, -1), (-1, -2), (1, -2), (2, -1)]
```

---

## 3. 禁止リスト（`forbidden`）の構築
禁止リストには以下を含める
1. **既存のコマが置かれているマス**。
2. **既存のコマがナイトで到達可能なすべてのマス**。

#### 手順
- 各コマ位置 $(a, b)$ を禁止リストに追加。
- 各コマ位置からナイトが移動可能な全てのマス $(na, nb)$ を計算し、範囲内なら禁止リストに追加。

#### 範囲チェック:
ナイトの移動した結果が盤面外の場合は無視します:
```python
if 1 <= na <= n and 1 <= nb <= n:
    forbidden.add((na, nb))
```

---

## 4. 配置可能な空きマス数を計算
盤面全体の総マス数 $N^2$（$N \times N$）から、禁止リストに登録されたマス数を引くことで、配置可能な空きマス数を求める
```python
ans = n * n - len(forbidden)
```

---

# ACコード1
```python:ac.py
import logging

# ロガーのセットアップ関数
def setup_logger(debug_mode):
    logger = logging.getLogger(__name__)
    if not logger.handlers:  # ハンドラが存在しない場合のみ追加
        logger.setLevel(logging.DEBUG if debug_mode else logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        
        file_handler = logging.FileHandler('program_trace.log', encoding="utf8")
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)
    
    logger.debug(f"ロガーのセットアップが完了しました。デバッグモード: {debug_mode}")
    return logger

def io_func():
    # 最初の行で n, m を取得
    n, m = map(int, input().split())
    
    # 次の m 行でコマの位置情報をリストとして取得
    pieces = []
    for _ in range(m):
        a, b = map(int, input().split())
        pieces.append((a, b))
    
    return n, m, pieces


# メインのロジック
def solve():
    logger = setup_logger(debug_mode=True)  # デバッグモード有効化
    n, m, pieces = io_func()
    
    logger.debug(f"盤面サイズ: {n}x{n}, コマの数: {m}")
    
    forbidden = set()
    moves = [(2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1)]

    for a, b in pieces:
        forbidden.add((a, b))
        logger.debug(f"コマの位置: ({a}, {b}) を追加")
        
        for da, db in moves:
            na, nb = a + da, b + db
            if 1 <= na <= n and 1 <= nb <= n:
                forbidden.add((na, nb))
                logger.debug(f"コマ ({a}, {b}) による移動先 ({na}, {nb}) を禁止リストに追加")

    ans = n * n - len(forbidden)
    logger.debug(f"禁止マス数: {len(forbidden)}, 配置可能マス数: {ans}")
    
    print(ans)

# エントリーポイント
def main():
    solve()

if __name__ == "__main__":
    main()

```
【Go】簡単なFactoryパターンのサンプルコード


## 概要


Goで簡単Factoryパターンを実装。


内容はポケモンをFactoryパターンを用いて生成するもの。


## サンプルコード


```go
package main

// IPokemon インターフェース: ポケモンの基本的な振る舞いを定義
type IPokemon interface {
	setName(name string)
	setAttack(attack string)
	getAttack() string
	getName() string
}

// Pokemon 構造体: ポケモンの共通のプロパティを保持
type Pokemon struct {
	name   string
	attack string
}

// setName: ポケモンの名前を設定
func (p *Pokemon) setName(name string) {
	p.name = name
}

// setAttack: ポケモンの攻撃技を設定
func (p *Pokemon) setAttack(attack string) {
	p.attack = attack
}

// getAttack: ポケモンの攻撃技を取得
func (p *Pokemon) getAttack() string {
	return p.attack
}

// getName: ポケモンの名前を取得
func (p *Pokemon) getName() string {
	return p.name
}

// Pikachu 構造体: ポケモンの一種 (ピカチュウ)
type Pikachu struct {
	Pokemon
}

// NewPikachu: ピカチュウを生成するファクトリーメソッド
func NewPikachu() IPokemon {
	return &Pikachu{
		Pokemon: Pokemon{
			name:   "ピカチュウ",
			attack: "電気ショック",
		},
	}
}

// Eevee 構造体: ポケモンの一種 (イーブイ)
type Eevee struct {
	Pokemon
}

// NewEevee: イーブイを生成するファクトリーメソッド
func NewEevee() IPokemon {
	return &Eevee{
		Pokemon: Pokemon{
			name:   "イーブイ",
			attack: "たいあたり",
		},
	}
}

// GetPokemon: ポケモンの名前を指定してインスタンスを取得
func GetPokemon(name string) IPokemon {
	switch name {
	case "ピカチュウ":
		return NewPikachu()
	case "イーブイ":
		return NewEevee()
	default:
		return nil
	}
}

func main() {
	pikachu := GetPokemon("ピカチュウ")
	eevee := GetPokemon("イーブイ")

	// 生成したポケモンの名前と技を出力
	println(pikachu.getName(), "の技: ", pikachu.getAttack())
	println(eevee.getName(), "の技: ", eevee.getAttack())
}

// 出力
// ピカチュウ の技:  電気ショック
// イーブイ の技:  たいあたり
```
ECSの設定項目　～クラスター、タスク定義、サービス

ECSに関して、クラスター、サービス、タスク、タスク定義などがどういったものかよく忘れてしまうので、各設定項目を確認することでイメージを持ちやすくしようと思います。


## クラスター
#### インフラストラクチャ
・Fargateを使うかEC2を使うか

#### モニタリング
・Container Insightsの設定

⇒全体の大枠（サービスやタスクもこの中で確認できる）

## タスク定義
#### インフラストラクチャ：
　・起動タイプ：Fargateを使うかEC2を使うか
　・OS
　・CPU、メモリサイズ
　・タスクロール：タスクのコンテナから他のAWSサービスへの権限
　・タスク実行ロール：コンテナエージェントがAWS APIリクエストを行うための権限
　　・ECRに対する有効なトークンの発行
　　・コンテナイメージの詳細情報の取得
　　・ログストリームの作成　など

#### コンテナ（複数設定可能）：
　・コンテナイメージ
　・ポートマッピング

⇒タスクの詳細内容

## サービス
#### デプロイ設定
・タスク定義名
・必要なタスク数

#### 自動スケーリング
・タスクの最小数/最大数

⇒コンテナ/タスクの開始/停止方法
Go言語のポインタレシーバと値レシーバを徹底解説！違いと使い分けのポイント

## はじめに 

Go言語でメソッドを定義するとき、**ポインタレシーバ**と**値レシーバ**のどちらを使うべきか迷ったことはありませんか？本記事では、それぞれの特徴や違い、使い分けのポイントについて具体例を交えて分かりやすく解説します。

## レシーバとは？

Go言語では、構造体に関連付けられたメソッドを定義する際、レシーバを指定します。レシーバは、構造体のインスタンスを受け取り、そのメソッド内で利用できるようにするものです。

例として、次のような構造体とメソッドを考えてみましょう。

```go
type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}
```

ここで注目すべき点は、`Area`メソッドが**値レシーバ**を、`Scale`メソッドが**ポインタレシーバ**を使用していることです。それぞれの違いを詳しく見ていきましょう。


## 値レシーバとは？

**値レシーバ**は、構造体のコピーをレシーバとして受け取ります。メソッド内でレシーバを操作しても、元の構造体には影響を与えません。

### 値レシーバの特徴
- レシーバの値は関数内でコピーされる。
- 元の値を変更しないメソッド（例: 計算、読み取り）に適している。

```go
func main() {
    r := Rectangle{Width: 5, Height: 10}
    fmt.Println(r.Area()) // => 50
    fmt.Println(r.Width)  // => 5 （元の値は変更されない）
}
```

## ポインタレシーバとは？

**ポインタレシーバ**は、構造体のポインタをレシーバとして受け取ります。これにより、メソッド内でレシーバの元の値を変更することが可能になります。

### ポインタレシーバの特徴
- レシーバはコピーされず、元の値が直接操作される。
- 構造体のフィールドを変更するメソッドに適している。
- 大きな構造体の場合、コピーのコストを回避できる。

```go
func main() {
    r := Rectangle{Width: 5, Height: 10}
    r.Scale(2)
    fmt.Println(r.Width)  // => 10 （元の値が変更される）
    fmt.Println(r.Height) // => 20
}
```

## 値レシーバとポインタレシーバの使い分け

### 1. 元の値を変更するかどうか
- **元の値を変更する必要がある場合** → ポインタレシーバを使用。
- **元の値を変更しない場合** → 値レシーバを使用。

### 2. パフォーマンスの観点
- 構造体が小さい場合は、値レシーバでも十分なパフォーマンス。
- 構造体が大きい場合は、ポインタレシーバを使う方が効率的。

### 3. 一貫性の観点
Goのコーディング規約として、構造体の全メソッドでポインタレシーバか値レシーバのどちらかに統一することが推奨されます。

## レシーバの選択がもたらす影響

### コピーの影響を理解する
値レシーバでは、構造体のフィールドを変更しても、元の値には影響を与えません。

```go
func (r Rectangle) ChangeWidth(newWidth float64) {
    r.Width = newWidth
}

func main() {
    r := Rectangle{Width: 5, Height: 10}
    r.ChangeWidth(20)
    fmt.Println(r.Width) // => 5 （元の値は変わらない）
}
```

一方、ポインタレシーバでは、元の構造体が変更されます。

## 実践的な例: 値型と参照型の違い

次のようなユースケースを考えてみてください。

1. **読み取り専用のメソッド**
   - 構造体の状態を参照するだけの場合、値レシーバを使用。

```go
   func (r Rectangle) String() string {
       return fmt.Sprintf("Width: %f, Height: %f", r.Width, r.Height)
```

2. **状態を変更するメソッド**
   - 構造体のフィールドを変更する必要がある場合、ポインタレシーバを使用。

```go
   func (r *Rectangle) Resize(newWidth, newHeight float64) {
       r.Width = newWidth
       r.Height = newHeight
   }
```

## おわりに

ポインタレシーバと値レシーバの違いを理解することで、より明確で効率的なコードが書けるようになります。本記事を参考に、自分のコードに適したレシーバを選び、Go言語の特性を最大限に活用しましょう！
SMACSSチートシート

# SMACSSのLayout（L）カテゴリで頻出するクラス名一覧

SMACSS（Scalable and Modular Architecture for CSS）でよく使われるクラス名を一覧にしました。  

## **頻出クラス名一覧**

**レイアウト**
| クラス名 | 役割・用途 |
|---------|-----------|
| `.l-wrapper` | サイト全体を囲むラッパー（コンテナ） |
| `.l-header` | ヘッダー（サイト全体の上部） |
| `.l-main` | メインコンテンツエリア |
| `.l-sidebar` | サイドバー（ナビゲーションや補助情報） |
| `.l-footer` | フッター（サイトの下部） |
| `.l-content` | メインのコンテンツエリア |
| `.l-grid` | グリッドレイアウトを管理するコンテナ |
| `.l-section` | 大きなセクションを定義する |
| `.l-container` | コンテンツ中央揃えのためのコンテナ |
| `.l-column` | カラム（カラムレイアウトで使用） |
| `.l-row` | 行（グリッドシステムの行） |
| `.l-page` | 1ページ全体を囲む要素 |
| `.l-nav` | ナビゲーションエリア |
| `.l-hero` | ヒーローエリア（ファーストビューの大きなエリア） |

## **ポイント**

- **レイアウトの大枠を決めるクラス** なので、デザインの詳細（色・フォント・マージンなど）はModule（M）側で管理することが多い。
- **レイアウトを汎用化** しておくことで、再利用性を高める。
[プロジェクト管理]分担って大事

# デキる人にだけやらせるな!!
管理者としては「この人に任せれば時短で上手いこと片してくれる」みたいな考えなんでしょうが、作業者側としては「そんなことでコッチに仕事振ってくんなよ、他の暇そうな奴にやらせて知見溜めろや」と思いながらも **「はいよろこんで。あなたがたのため」** とやるわけですよ。
※暇そうな奴に任せて出来ない時のとばっちりを喰らいたくないため

# 分けて受け持つこと・分けて負担すること
【分担】の意味らしいのですが、大量のタスクがある中で、
どれを誰に分ければいいのかみたいなのがキチンと認識できない、
もしくはとりあえずこの人に振ればいいか精神のPM/PLが上に立っちゃうと、
作業者はそれはそれは大混乱になって回るものも回らない状態になり、
デスマだったり特定人物が高負荷に陥ってしまうクソみたいな状況になるわけで。。。

# まずやるべきこと
問い合わせだったり、コーディングだったりタスクはいっぱいあるかと思うが、まず何よりも先に優先度を付けることが大事だと思います。

全部大事なタスクなのは分かるけど、同時に全部こなすとかは無理なので、期限が近いとかこれが出来てないと他が回らないような、早くやらないといけないものを精査してその中でも更にランク付けして割り振る事が大事なのかと。

簡単に出来そうだからとショボいタスクを沢山こなしてイキってちゃダメ！

# 人の振り方について
どんなプロジェクトにもだいたい1人や2人ぐらい、生き字引みたいな、なんでもそつなくこなすマンがいるかと思います。
その人に全部振っちゃえば簡単に終わるのは分かって入るけど、そんなんされちゃうとその人のモチベーションを落としたり、チームとしてのナレッジが溜まらずに結局特定の人に振ると言うクソみたいな悪循環が出来上がってしまうため、まずはチーム内のランク付けをしてみるのも手かと。
> Sランク：直ぐに何でもデキる人
> Aランク：時間はかかるが何でもデキる人
> Bランク：難しいのは無理だけど、基本的なことはデキる人
> Cランク：言われたことしか出来ない人
> Dランク：正直いらない人（いてもいなくても別にいい人

そのうえで、さっきのタスクの難易度・優先度と組み合わせて人をアサインするのもありかなと。

# 要は。。。
きちんと順位を決めて、それに担う人を上手いこと割り当ててねってお話でした。
※当たり前過ぎてこうやって記事にするのも憚れそうですが。。。出来てないマネージャー層が結構いるので。。。

# 見ろ、人がアリのようだ（ﾊﾞﾙｽ
アリの社会は、「２：６：２」の割合で「普段からよく働く：普通に働く：あまり働かない（急なイベント時の予備軍）」という構成になっているのはよく聞く話ですが、コレは人間社会でも割と当てはまっているみたいです。

上で言う「Dランク」は書き方が酷い感じもしますが、何故か割とどの会社やチーム・グループでも一定数存在します。

なんでこんなスキルで採用されたか分からないようなデキの悪さだったり、言われたことにとにかく言い訳などゴネたり、作業させても余計な事やって周りに迷惑かけたりするような、色んな意味でとんでもない人材ですが、会社としては会社都合とかで辞めさせるわけにもいかないため（体裁的なアレや離職率的なアレなど）、「この案件で、このSランクの下で働かせれば成長するやろ」みたいな軽いノリで、完全にSランクのお荷物なポジションでアサインさせたがるんですよね。
→で、Sランクが鬱になってプロジェクトが火の車になる未来。

アリの世界では急なイベント時にはちゃんと働く2割の怠け者ですが、自分が知ってる中ではDランクの人が炎上してる時にちゃんと働く姿なんかみたこと無いので、ホントに体裁とか気にせずドンドン切っていって淘汰（IT向かないので他業種への転職）されて欲しいなぁと思う今日このごろでした。
NetworkXでノードごとに異なる形を設定する

## はじめに
NetworkXでグラフを描画する際、ノードごとに異なる形を設定したいときがあります。例えば、以下のように一部のノードを円形、他のノードを四角形にする、みたいな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813135/9fc06c65-a231-44dd-ae21-2402ff2dca85.png)

複数種類のノードを使いたい場合や、特定のノードを強調表示したい場合に役に立つと思います。

## 実装方法
### コード
ノード `0, 1` を円形、ノード `2, 3` を四角形で描画するコードです。
```python
import networkx as nx
import matplotlib.pyplot as plt

# ランダムなグラフを生成
G = nx.gnm_random_graph(n=4, m=4, seed=42)

# ノードの形を設定
node_shapes = {
    "o": [0, 1],  # 円形ノード
    "s": [2, 3]   # 四角形ノード
}

# ノードの配置を決定
pos = nx.spring_layout(G)

plt.figure(figsize=(5, 5))

# 形ごとにノードを描画
for shape, nodes in node_shapes.items():
    nx.draw_networkx_nodes(
        G,
        pos=pos,
        nodelist=nodes,
        node_color="skyblue",
        node_size=700,
        node_shape=shape
    )
    
# エッジを描画
nx.draw_networkx_edges(G, pos=pos)

# ノードのラベルを描画
nx.draw_networkx_labels(G, pos)

plt.axis('off')  # 軸を非表示にする
plt.show()
```

### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813135/38934a81-0754-4044-a8ba-5e3bcbfcff31.png)

## 解説
networkx の描画関数として一般的に使われる`nx.draw`では、ノードの形を一括で変更することはできます。
```python
nx.draw(G, node_shape='s')  # すべてのノードを四角形にする
```
しかし、「ノードごとに異なる形状を設定する」ことはできません。
解決策として、形状ごとに分けてノードを描画します。
![ノードの形を個別に描画.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813135/ece2e431-bc5e-4c63-8855-8f2dab56133a.png)

そのために、`nx.draw_networkx_nodes`を使います。これはノードだけを描画する関数で、指定したノードだけを描画できます。
```python
# 形ごとにノードを描画
for shape, nodes in node_shapes.items():
    nx.draw_networkx_nodes(
        G,
        pos=pos,
        nodelist=nodes,
        node_color="skyblue",
        node_size=700,
        node_shape=shape
    )
    
# エッジを描画
nx.draw_networkx_edges(G, pos=pos)
```

## おわりに
複数種類のノードがあるネットワークも多いです。そういう場合、ノードの形を変えることで情報を分かりやすく伝えられます。ぜひ試してみてください。
Slack × Zapier × OpenAI（ChatGPT）を使った自動返信システムの構築


## 概要
Slackに送られてきたメールの内容をZapierを介してOpenAI（ChatGPT）に送り、適切な返信文を生成してSlackに返す自動化システムを構築しました。  
このシステムは、以下の流れで動作します：
1. **Slack** にメール内容が投稿される  
2. **Zapier** がトリガーを検知して **OpenAI** にメッセージを送信  
3. **OpenAI** が返信文を生成  
4. 生成された **返信文をSlackに自動投稿**  

## 使用するツール
- **Slack**: メール内容が投稿されるチャンネルを作成  
- **Zapier**: SlackとOpenAI（ChatGPT）を連携して自動化  
- **OpenAI (ChatGPT)**: メール内容に基づいた返信文の生成  

---

## 1. Slackの設定
### Slack純正のZapierアプリをインストール
- [Slack App Directory](https://slack.com/apps) から「Zapier」アプリをインストールします。  
- インストール時に、**特定のチャンネル** へZapierを追加してください。

### トリガーの設定
- メッセージをトリガーにして動作させるため、**Zapierに対して権限を付与** します。  
- メール内容が投稿される **特定のチャンネル** に対してZapierアプリがアクセスできることを確認。

---

## 2. Zapierの設定
### 2.1 トリガーの設定
- トリガー: **Slack - New Message Posted to Channel**  
  - 条件: 特定のチャンネルにメッセージが投稿された時に発動  
  - ts（timestamp）でメッセージを識別します。

### 2.2 アクション1：OpenAIにメッセージを送信
- アクション: **OpenAI - Send Prompt**  
  - Slackから取得したメッセージ内容をOpenAIに送ります。  
  - プロンプト例：  
    ```text
    「以下のメールに対する返信文を考えてください。  
    メール内容: {Slackメッセージ}」
    ```

### 2.3 アクション2：Slackに返信文を送信
- アクション: **Slack - Send Message**  
  - OpenAIから生成された返信文を、Slackに送信します。  
  - ts（timestamp）を利用して、元メッセージにスレッド返信する形で表示。

---

## 3. メッセージフローの詳細
1. Slackの **特定チャンネル** にメール内容が投稿される。  
2. Zapierが **New Message Posted to Channel** トリガーを検知。  
3. メッセージ内容を **OpenAI** に送信し、返信文を生成。  
4. 生成された返信文を **Slack** にスレッド形式で自動投稿。

---

## 4. 注意点・ポイント
- **OpenAIのトークン** をZapierに設定する必要があります。  
- **Slackの権限設定** により、Zapierがメッセージを読み取り、返信することが可能になります。  
- **ts (timestamp)** を利用することで、元メッセージに対してスレッド形式で返信できます。

---

## 5. 応用例
- カスタマーサポートの一次対応自動化  
- 社内問い合わせの自動応答  
- FAQの自動返信システム  

---

## 6. まとめ
- Slack、Zapier、OpenAIを連携させることで、**効率的なメール返信の自動化** が可能になりました。  
- 特に、ts（timestamp）を利用することで、**スレッド形式の返信** を実現でき、メッセージの流れをスムーズに保てます。  
- 今回の構築方法は、**カスタマーサポートや社内問い合わせの自動化** にも応用可能です。

---

## 7. 今後の展望
- **返信内容の精度向上** のためのプロンプトエンジニアリング  
- **複数チャンネル対応** や **条件分岐** を用いたより高度な自動化  
- **OpenAIのモデル更新** に伴う返信内容の質の向上  

---

## 8. 参考リンク
- [Slack API Documentation](https://api.slack.com)  
- [Zapier Integration with Slack](https://zapier.com/apps/slack/integrations)  
- [OpenAI API Documentation](https://platform.openai.com/docs)

---
家計簿アプリを作る＃２

続いて、index.tsxファイルでも、不要な文を削除します。
![スクリーンショット 2025-02-28 093344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/bd2869d0-2f8e-4666-b9cf-0791933222f7.png)


コメントの部分と最後の文を削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/6409a0e7-c5fb-4fb6-bf4c-bcd513e2c155.png)



これで、準備は完了です。
サーバーを立ち上げて、画面を確認します。
npm startで立ち上がります。

![スクリーンショット 2025-02-27 101426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/87bd1c7c-7c6b-4cdd-967a-ffdeec0a7656.png)
👆の状態になれば、準備完了です。
家計簿アプリを作る＃１


まず初めに下記の写真のように、不要なファイルを削除していきます。

![スクリーンショット 2025-02-28 092738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/287a27f5-8deb-43a5-a754-7db5a399b9cd.png)


不要な記述を削除していきます。
![スクリーンショット 2025-02-28 092901.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/d4d6efa4-6e9d-4fc7-ae20-d3fc6403b237.png)


ヘッドの部分も削除します
![スクリーンショット 2025-02-28 092952.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/29d47419-b508-4a75-aca9-eeb4a3712f9e.png)
Qualysについて

## はじめに
Qualysというセキュリティサービスに触れる機会がありました。
Qualysは、企業のITインフラを保護するための脆弱性管理やセキュリティスキャンを提供するクラウドベースのプラットフォームです。
今回は、Qualysの基本的な機能や、学んだことを紹介したいと思います。
本記事ではQualysのVMDR(Vulnerability Management Detection & Response)という脆弱性診断機能についての記事になります。

https://cdn2.qualys.com/docs/mktg/jp/qualys-vmdr-v2.0-platform_japanese.pdf

## Qualysとは
Qualys社が提供する、クラウドベースのセキュリティおよび、脆弱性管理機能を提供するサービスです。
検知された脆弱性はクラウド上で管理され、WEBブラウザ(ダッシュボード)で参照できます。

https://www.qualys.com/

## Qualysの特徴
・スケジュールスキャン(定期・自動)、オンデマンドスキャンに対応
・検出した脆弱性の重要度(severity)の自動判定
・脆弱性診断レポートの自動生成・カスタマイズ、Eメールなどでの通知
・日本語対応(全てではない)
など、その他にも色々と特徴があります。
※レポート生成、脆弱性通知をさせるには、事前に脆弱性スキャンを実施する必要があります。

https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/schedules/schedules_basics.htm

https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/knowledgebase/severity_levels.htm

https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/reports/reporting_basics.htm

## Qualysの脆弱性スキャンの方式
脆弱性スキャンは、グローバルIPまたはプライベートIPをもつ機器(ホスト)をスキャンします。

https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/scans/scanning_basics.htm#:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3%E3%81%99%E3%82%8B%E3%83%9B%E3%82%B9%E3%83%88%E3%82%92%E8%AD%98%E5%88%A5%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95,%E3%81%AE%20IP%20%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%9F%E3%82%8A%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82,-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AB%E3%81%82%E3%82%8B

またスキャンの方式は以下になります。
|方式 |説明  |条件  |
|---|---|---|
|認証スキャン  |リモートログインを行い情報を収集して、脆弱性を調査します |リモートログインの許可と認証情報の設定が必要  |
|エージェントスキャン  |エージェントが情報を収集し脆弱性を調査します  |エージェントのインストールが必要 |
|ポートスキャン  |オープンポートに対して通信を行い、応答内容から脆弱性を調査します  |特になし  |

https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/scans/vm_scans_lp.htm

またイントラネット上で脆弱性をスキャンするために、Qualys スキャナー(物理/仮想)の導入が可能です。

https://docs.qualys.com/en/scanner/configure-vlan/#t=scanner_appliance%2Fgetting_started.htm

またアセットにグループ(アセットグループ)設定を行うことで、重要度や優先順位のグループ化を行い、そのグループ単位でのスキャンの実行が可能です。


https://qualysguard.qualys.com/qwebhelp/jp/fo_portal/scans/scanning_basics.htm#:~:text=%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%E8%A9%B3%E7%B4%B0-,%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%A8%E3%81%AF,%E3%82%84%E6%94%B9%E5%96%84%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E7%AE%A1%E7%90%86%E3%81%8C%E5%AE%B9%E6%98%93%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%E8%A9%B3%E7%B4%B0,-%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%82%BF%E3%82%B0%E3%81%A8%E3%81%AF

## まとめ
Qualysを導入することで、セキュリティ管理や脆弱性対応の効率性を高めてくれると感じました。
まだ使えていない/理解していない機能も多く、新たな発見があれば記事にしていきたいと思います。
## 参考

https://www.qualys.com/documentation/jp/
touchendをclickの代替として使う人へ


## 言いたいこと

スマホでスクロールを目的としてスワイプしたときに、touchendイベントが誤爆するとストレスがたまるから、
~~touchstartイベントとtouchendイベントが発火した座標を比較したほうがいいかも。~~
同じ要素内でtouchstartイベントとtouchendイベントが発火したかを確認したほうがいいかも。

終わり。

## 関連

https://unolabo.boo.jp/archives/2011/06/06-iphone%E3%81%A7%E3%82%BF%E3%83%83%E3%83%97%E3%81%AE%E5%8F%8D%E5%BF%9C%E3%81%8C%E9%81%85%E3%81%84%E3%81%A8%E6%84%9F%E3%81%98%E3%81%9F%E3%82%89.html

https://webfrontend.ninja/js-click-and-touchend-events/

https://webcreatetips.com/coding/145/