OmniAICreator/Qiita-1.07M huggingface dataset:
Slack Incoming Webhook

## Slack Incoming Webhook
- https://api.slack.com/apps?new_app=1

学習に時間がかかるAIモデルの学習時に，学習の進捗を通知したいという動機でSlack Incoming Webhookの使用を考えた．
上のURLからSlackチャネルのWebhookURLを取得して，指定する．

```python
import socket
import requests
from datetime import datetime


class slack_channel():
    def __init__(self, url, channel):
        self.url = url
        self.channel = channel
        
        self.hostname = socket.gethostname()
        self.icon_emoji = ":desktop_computer:"
        self.current_time = datetime.now().strftime("%Y/%m/%d-%H時%M分")
        
    def send(self, title, message):
        payload = {
            "channel": self.channel,
            "username": self.hostname,
            "icon_emoji": self.icon_emoji,
            "attachments": [
                {
                    "fallback": "Fallback text for older clients",
                    "pretext": None,
                    "color": "#36a64f",
                    "title": title,
                    "text": message,
                    "footer": self.current_time,            
                }
            ]
        }
        response = requests.post(self.url, json=payload)
        # エラーが出たらプリント
        if response.status_code == 200:
            pass
        else:
            print(f"エラーが発生しました: {response.status_code}")

slack = slack_channel(url='https://yourwebhookurl', channel='#your_channel_or_yourpersonalID')
slack.send(title='TEST SEND', message='this is test sending')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937639/6ac929b2-16f0-406b-a01b-10a5c0d440ea.png)

- 以下のような感じで通知できます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937639/0628a7d5-65ca-41da-a5a4-8d0b98e39545.png)
小ネタ OWASP ZAPのScriptをZest言語以外で作成したい

# 内容
OWASP ZAPにおいて、Scriptを書く際に、デフォルトだとZestという選択ししか表示されない。

# 結論
Pythonを使う際は、拡張機能をインストールしないといけなかった
（JavaScriptも別の拡張機能で対応可能らしい）

# 手順
ZAP Marketplaceにアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/b3c5a414-495f-48a9-b27a-a77a6b976b46.png)

【マーケットプレイス】タブを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/a7428ec4-d7f2-4f44-bbba-1d48669eed47.png)

`python`と入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/da9fb123-f1a5-4205-b441-7f108af55f32.png)

チェックボックスをONにし、選択済みをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/09ae5e09-65c9-4d83-a59e-a512541d9cce.png)

Script engineにpythonが選択可能に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/27ffe7c9-a020-497d-9430-27ae7bc2594b.png)

↓こんな感じに、PythonコードでScriptを書くことができました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/377c86f3-dca0-40ca-a61c-4c331ec9628a.png)


# 参考
https://github.com/zaproxy/zap-extensions/
Vercel + Supabase + Prismaでマイグレーションに失敗した時の対処


## はじめに
Vercel の **Storage** で Supabase のデータベースを作成し、Prisma を使ってマイグレーションを試みましたが、途中で止まってしまいました。
**Quickstart**にある、` POSTGRES_PRISMA_URL `　や、` POSTGRES_URL `を使用してみましたがうまくいかず、最終的に **Supabase の Connect 設定** に記載されたURLを使用することで解決できたので、その経緯をまとめます。

## 環境
- **OS**: Windows
- **Node.js**: 20.14.0
- **Prisma**: 6.4.0
- **PostgreSQL**: Supabase 上のデータベース
- **Next.js**: 15.1.6

## 問題点
Vercel の **Storage** の **Quickstart** に記載されているデータベースの接続 URL (`DATABASE_URL`) を `.env` に設定し、Prisma のマイグレーションを実行しましたが、  
以下のように止まってしまいました。

```sh
npx prisma migrate dev --name init
```

```
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Datasource "db": PostgreSQL database "<YOUR_DB_NAME>", schema "public" at "<YOUR_SUPABASE_HOST>:<YOUR_PORT>"
```

この状態で進まず、マイグレーションが適用されませんでした。

## 解決策
#### Supabase の Connect にある ORM 向けの設定を利用

Supabase の Connect → ORMs のセクションに記載されている接続方法に従い、` .env ` の ` DATABASE_URL `を以下のように変更しました。
（ホスト名・DB名・ユーザー名・パスワードは、Supabase の Connect に記載されている値 を使用してください。）

```env
# Connection Pooling 用 (通常のアプリ接続)
DATABASE_URL="postgresql://<YOUR_DB_USER>:<YOUR_DB_PASSWORD>@<YOUR_SUPABASE_HOST>:6543/<YOUR_DB_NAME>?pgbouncer=true"

# マイグレーション用 (Direct Connection)
DIRECT_URL="postgresql://<YOUR_DB_USER>:<YOUR_DB_PASSWORD>@<YOUR_SUPABASE_HOST>:5432/<YOUR_DB_NAME>"
```
#### ` prisma/schema.prisma ` に ` DIRECT_URL ` を追加
Prisma の ` schema.prisma `に ` DIRECT_URL ` を追加することで、マイグレーション時のみ direct connection を使うようにしました。

```prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}
```

### ` prisma migrate dev ` を再実行
```sh
npx prisma migrate dev --name init
```
すると、問題なくマイグレーションが適用されました。

## まとめ
Vercel の Storage Quickstart に書かれている DATABASE_URL は Connection Pooling 用のため、マイグレーションには適さないようです。
しくじり先生俺みたいな方法で基本情報をとるな！ 本レビュー:いちばんやさしい 基本情報技術者　絶対合格の教科書＋出る順問題集


皆様こんにちは
今回は基本情報をとった時の反省をまとめてこれを見た資格勉強をする人が、
参考になればと思って書いています。

## 自己紹介

<dt>お名前<dt>
<dd>かぼ<dd>

<dt>年齢<dt>
<dd>23歳<dd>

<dt>経歴<dt>
<dd>偏差値38高校⇒中堅情報系(笑)私立大学⇒メーカー総合職クラウド系<dd>

<dt>趣味<dt>
<dd>競プロ、筋トレ、ホテルステイ<dd>


## 使用参考書

資格勉強で使った参考書は
**いちばんやさしい 基本情報技術者　絶対合格の教科書＋出る順問題集**
を使いました。下に写真とAmazonリンク張っておきます。

結論から言うと自分のような初学者にも届かない人が
一冊目に取る本としてはおすすめです。

[参考書リンク](https://www.amazon.co.jp/%E3%80%90%E4%BB%A4%E5%92%8C%EF%BC%96%E5%B9%B4%E5%BA%A6%E3%80%91-%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E7%B5%B6%E5%AF%BE%E5%90%88%E6%A0%BC%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%EF%BC%8B%E5%87%BA%E3%82%8B%E9%A0%86%E5%95%8F%E9%A1%8C%E9%9B%86-%E9%AB%98%E6%A9%8B-%E4%BA%AC%E4%BB%8B-ebook/dp/B0CNGDN2MM)

■使用参考書の現在の姿

<img width="300" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795186/48ed5bfe-c7b2-4658-a889-ef1ffd94f2b4.jpeg>
<img width="300" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795186/52763559-b41c-45ce-b24d-f8815d7aea13.jpeg>

（プロテインこぼしたから汚いな・・・）



## 基本情報をとるまでにやったこと
**注意:最適なやり方ではありません最後に説明するので一旦読んでください。**

自分は競技プログラミング等を趣味にしており、
プログラミングはほぼノー勉です。軽く過去問したらパスしました。

ただ、専門用語から逃げ続ける大学生活を送っていたので
逆にそのほかの部分は壊滅的で、専門用語を重点的にやりました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795186/b0fccde7-0ef1-4746-bbbe-47922786d6ca.png)
\
\
・・・・・
\
\
実際に合格までにやったことは、

 - 参考書2週＋苦手な所(セキュリティ、ストラテジ系・・・)を1周
 
 - 過去問15年分

```mermaid
graph TD;
    参考書購入-->参考書通読1週目;
    参考書通読1週目-->参考書通読2週目;
    参考書通読2週目-->参考書苦手分野通読3週目;
    参考書苦手分野通読3週目-->過去問15年分;
    過去問15年分-->受験
```

です。

次に参考書についてお話します！

## 参考書だけではもちろん合格できない表面上の知識しかつかない
資格勉強慣れしてる方ならわかると思うのですが、
参考書2周と苦手分野をもう1周取り組み過去問にとりかかりましたが、


**え？なにこれ聞いたことないぞ・・・？**

という問題が半分くらい占めていました。(自分の記憶力にも問題有)
自分は結果的に合格までの知識は、**過去問でつけました。**

ただ、そういう意味では700ページの参考書を読むだけで、
必要最低限の知識が付くのは非常にコスパが良いと思いました。

最低限知識をつける目的であれば良い本だと思います。

## 過去問15年分？センター試験か？
次に過去問についてです。
ここまで読んだ方なら薄々お気づきかもしれませんが、
私、資格勉強慣れしてません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795186/3e4acda8-ef07-489a-a8b3-bbda15873933.png)
(素振り一万回したら流石にプロいけるやろ・・・)
上記のような思考回路の持ち主です。

\
基本情報は情報系の試験で、情報系はどんどん情報の更新が入ります。
賞味期限の短い情報ばかりの試験なのに自分は、

**うおー！15年分やれば大丈夫だ！！！(大学入試経験則)**

大丈夫ではありません。
情報系はどんどん知識がアップデートされていく世界です。
古い過去問を解けばその分古い情報にあたる事も増え、
誤った知識を身に着けてしまっているという事も十分ありえます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795186/22aa9d97-222f-4e01-a5ed-c9c2dcebfe15.png)


## 自分の反省点
まず、参考書はあくまでも表面上の知識しかつかないです。
ただ、それが悪いというわけではないです。
参考書を読み、勉強する事で自分の知識は、

**０⇒１０**

くらいにはなっていました。
そして過去問や自分で意味が分からない部分を調べる事で

**１０⇒８０**

くらいにして合格した。といった感じです。

なのでこの参考書で資格をとろう！という方は、
過去問を中心に、あくまでも参考書は０⇒１０であることを念頭において、
時間をかけすぎないようにしましょう。
ということを言いたかったのです。

ぶっちゃけ、他の本を読んでないので比較はできませんが、
700ページで必要最低限の知識が付くのはコスパが良いと思いました。

あと、過去問はもっと最近のものを何周もして感覚を身に着けるようにしましょう。

## もし自分が試験勉強方法を組むなら

もし今最適な勉強スケジュールを組むなら、
参考書１週⇒過去問10年分2週にすればよかったと思います。
そっちの方が、実践機会が増え、知識の定着や問題傾向の理解に繋がると思いました。

\
\
以上です。これから資格勉強する方は自分の反省を糧に頑張って下さい！
TA7291P

## TA7291Pモータードライバ
標準的なモータードライバ。正転・逆転・ストップ・ブレーキの4モードを２入力のデジタル信号で制御可能なブリッジドライバ。H型になっており、四つのトランジスタで制御する形式。レギュレータおよび保護回路(熱、過電流)付き。

https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/ta7291.pdf


TOSHIBA JAPAN \
TA7291P hogehoge \
って書いてある面を正面にして、左から1~10番までピンがある。
| ピン番号(P) | 記号 | 端子説明               |
| ----------- | ---- | ---------------------- |
| 1           | GND  | GND                    |
| 2           | OUT1 | 出力端子(モーター接続) |
| 3           |      | NC端子                 |
| 4           | Vref | 制御電源端子(PWM入力)  |
| 5           | IN1  | 入力端子(制御信号)     |
| 6           | IN2  | 入力端子(制御信号)     |
| 7           | Vcc  | ロジック側電源端子     |
| 8           | Vs   | 出力側電源端子         |
| 9           |      | NC端子                 |
| 10          | OUT2 | 出力端子(モーター接続) |



データシートを見つつ配線。下のブレッドボード図には抵抗入っているが、~~私は入れなかった~~。モータ出力と並列になっている方の抵抗は入れた。 \
VrefとVsで同じ信号を使うとき(PWM使わないとき)は抵抗2(データシート参照)が必要であることに注意。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937639/1e04ecd7-c9f4-4178-977b-39378b2f8117.png)




データシートのファンクションを見つつプログラムすれば動作する。切り替え時に貫通電流が流れるのでストップを挟むこと。
氣づき– AIを超えるために必要なこと


## はじめに

最近、「AI」という言葉を聞かない日はありません。

一般的に「AI」と言えば 人工知能 を指しますが、
この言葉には、ほかにも異なる意味があります。

- 愛 (Ai)
- アントニオ猪木 (Antonio Inoki)
- 人工知能 (Artificial Intelligence)

これらは一見まったく関係のないものに思えます。
しかし、共通しているのは 「人の意志と情熱があってこそ、本当の価値が生まれる」 ということです。

## パターンマッチと想像力

私は以前から [Elixir言語のパターンマッチ](https://www.google.com/search?q=Elixirパターンマッチ) に魅力を感じていました。
プログラムの中でパターンを見つけることで、シンプルで直感的なコード を書くことができます。
しかし、パターンマッチは プログラミングの概念にとどまらず、日常生活にも通じるもの だと感じています。

私たちは日々の経験の中で、共通するパターン を見つけることで、新しいアイデアを生み出します。
「AI」という言葉に複数の意味があることも、そのひとつの例です。

## AI時代に増えるもの、失われるもの

AI技術の発展によって、膨大な量のコンテンツが自動生成されるようになりました。
文章、画像、動画などのあらゆる分野でAIは活用されています。

しかし、その一方で 本当に価値のあるもの を見極めるのが難しくなっています。

- 情報が増えすぎて、どれが正しいのかわからなくなる
- ありふれた表現が増え、オリジナリティが失われる
- 便利になった分、自分で考えたり学ぶ機会が減る

このような状況の中で、私たちに求められるのは AIを使いこなしながら、それを超えていくこと です。

## AIは考えてくれない

幸いなことに、私の会社ではAIの利用をサポートしてくれています。
私も毎日のようにAIを活用し、業務の効率化を図っています。

https://qiita.com/torifukukaiou/items/9ac6c7258c8a1549674a

しかし、ある日 重要なことに氣づきました。

👉 AIは「自分の代わりに考えてくれる」わけではない。

AIは私の求める答えを 推測 してくれますが、 それが 本当に自分にとって必要なものとは限りません。

結局のところ、何を学び、何を作るかを決めるのは自分自身 です。

- 好奇心を持つのも、自分。
- 学びたいと思うのも、自分。
- 計画を立て、決断を下すのも、自分。

AIがどれだけ進化しても、主体性を持つのは人間でなければなりません。

ある同僚は「AIに教育をしている」と言っています。

https://qiita.com/torifukukaiou/items/aa0b0da419b62a4793cf

これは決して誇張ではなく、本当に重要なことです。

## AIを超えるために必要な3つのこと

では、AIを超えていくために何が必要なのでしょうか？
私は 3つの要素 が大切だと考えています。

### ① 情熱

何か すごいものを作りたい という気持ち。

優れた作品や技術は、強い情熱から生まれます。
それは AIには決して持つことができないもの です。

### ② 好奇心

新しいことを 学びたい、試したい という気持ち。

好奇心を持ち続けることで、成長し続けることができます。
これは、AIのように「データを蓄積すること」とは全く違う、人間ならではの強みです。

### ③ 楽しむこと

楽しんでいると、自然と いいものを作りたくなる ものです。
学ぶことを 義務ではなく、楽しみ に変えられる人こそが、AIを超えられるのではないでしょうか。

## AIを超える人たち

実際に、私の周りには AIを超えていく人たち がたくさんいます。

- カスタムキーボード を追求し、理想の操作感を求める人
- VS Code を駆使し、生産性を高める人
- インフラの自動化を推進し、最適な構成を模索する人

みんな 情熱と好奇心を持ち、楽しみながら 自分の道を進んでいます。
この姿勢こそが、AIには決して真似できないものです。

## 一般化の罠

AIは膨大なデータを分析し、パターンを見つけることが得意ですが、その過程で すべてを一般化してしまう 傾向があります。

これは、文化や歴史の深みが失われるリスクにつながります。

私は10年以上アメリカで暮らす中で、日本が持つ世界に誇れる強み を改めて実感しました。

https://qiita.com/mnishiguchi/items/7e212430f56f90eefc03

例えば、日本の神社では 「皇紀2600年」 という言葉をよく見かけます。
これほど長い歴史を持つ国は、世界でも珍しい存在です。

また、日本の哲学や価値観は、多くの書物にも受け継がれています。

- [アントニオ猪木自伝](https://www.google.com/search?q=アントニオ猪木自伝) —— 忍耐と挑戦の精神
- [渋沢栄一『論語と算盤』](https://www.google.com/search?q=渋沢栄一『論語と算盤』) —— 哲学とビジネスの融合

こうした知識や思想が、AIによる一般化の影響で薄れてしまうことは避けなければなりません。
だからこそ、価値あるものは次の世代に受け継いでいく必要があるのです。

https://note.com/awesomey/n/n4d8c355bc8f7

https://qiita.com/torifukukaiou/items/b6361f98194f3687a13c

## おわりに

これからの時代、AIを活用することは避けられません。
しかし、AIを ただの便利なツールとして使うのではなく、自分の力を高めるために使う ことが大切です。

そして、最終的に AIを超えていくのは人間 です。

私はこれからも、 物事をしっかり観察し、好奇心を持ち、良い仕事をしていきます。

AIを超えていきましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/dc1ddba7-ab4c-5e20-1331-143c842be143.jpeg)
![DSC_0082.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/f9f1b977-5bc1-4443-9fc1-8351176ee71d.jpeg)

https://www.haw.co.jp/blog/2025/02/10/qiita_advent2024/
Windows＆Python環境構築(venv)

# Windows & Python venv環境構築
### 以下でPythonをダウンロード
https://pythonlinks.python.jp/ja/index.html

- 二つのチェックボックスにチェックを入れてダウンロード

### PowerShell
インストール確認
```
python -V

##
Python x.x.x
```

### venv環境構築
```
cd <your venv project dir>
py -x.x -m venv <your env name>
# 後述↓
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
.\<your env name>\Scripts\activate

##
(your env name) PS C:\Users\
```


## セキュリティエラー回避
```
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
```
これを実行せずにアクティベートしようとすると

```
.\Scripts\activate : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\... を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?L
inkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\Scripts\activate
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```
と言われる．

### VScodeでの実行時
- 以下の設定を追加するとアクティベートできるようになる
```json:setting.json
{
        "terminal.integrated.env.windows": {
        "PSExecutionPolicyPreference": "RemoteSigned"
    }
}
```
Docker x Node.js

### 備忘録

完全個人用 Docker Node.js の簡易構築

### 1. Dockerfile
```docker
FROM node:22
EXPOSE 8888
```

### 2. build
```terminal
$ docker build -t node .
$ docker run -it --rm --name my-node-app node
```

### 3. bash
```terminal
$ docker container ls
$ docker exec -it containerID bash
$ npm -v
$ node -v
```
クリックしたらアニメーションが出るようにしてみた！

## はじめに
初めましての人もそうでない人もこんにちは！

さて2月になり寒さがかなり増してきましたね〜

私は、こたつに入りながらスマホゲームをしたりPCでYoutubeを見たりだらだら冬を越す予定です！
さて、ゲームによってはバレンタインイベントがあったのではないでしょうか？
そこで思ったこととしてはゲームってクリックする時なにかしらのアニメーションがでるなーと思いました！

そこで、このクリックした時のアニメーションを今作ることができれば今後の開発がちょっとだけオシャレになるのでは？と閃きました！

そうゆうことで今回は「TypeScriptとCSSを使ってクリックした時にアニメーションを出す」というプログラムを書いていこうと思います！

## 準備
さて今回はアニメーションを出すための画像を準備したいと思います！
今回使用する画像はこれ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631203/a4ccedd4-2d5a-ee18-8c54-ef8cd14f84b5.png)

ファイル名は「mahoujin.png」です！

この画像でなくても皆さんお好きな画像を使って開発してみてください！

今回はReactとTypeScriptを使うので以下のコマンドをターミナルにコピペしてください！
```
npx create-react-app effect --template typescript
cd effect
npm start
```

## 作ってみよう！
effect/srcにあるApp.tsxを開いてください！
そして以下のコードをコピペしてください

### 回転エフェクト
```src/App.tsx
import React, { useState, useRef } from 'react';
import './App.css';

interface Animation {
  id: number;
  x: number;
  y: number;
}

const App: React.FC = () => {
  const [animations, setAnimations] = useState<Animation[]>([]);
  const [nextId, setNextId] = useState(1);
  const containerRef = useRef<HTMLDivElement>(null);

  const handleClick = (e: React.MouseEvent) => {
    const { clientX, clientY } = e;
    const newAnimation = {
      id: nextId,
      x: clientX,
      y: clientY,
    };
    setAnimations((prevAnimations) => [...prevAnimations, newAnimation]);
    setNextId((prevId) => prevId + 1);

    setTimeout(() => {
      setAnimations((prevAnimations) =>
        prevAnimations.filter((anim) => anim.id !== newAnimation.id)
      );
    }, 2000);
  };

  return (
    <div
      ref={containerRef}
      onClick={handleClick}
      style={{ position: 'relative', width: '100vw', height: '100vh' }}
    >
      {animations.map((animation) => (
        <img
          key={animation.id}
          className="animated-image"
          src="/mahoujin.png"
          alt="Rotating"
          style={{
            left: `${animation.x}px`,
            top: `${animation.y}px`,
          }}
        />
      ))}
    </div>
  );
};

export default App;
```

```src/App.css
.animated-image {
  position: absolute;
  width: 100px;
  height: 100px;
  transform: translate(-50%, -50%);
  animation: rotate-in 1s linear, rotate-out 1s linear 1s;
}

@keyframes rotate-in {
  from {
    transform: translate(-50%, -50%) rotate(0deg) scale(0);
  }
  to {
    transform: translate(-50%, -50%) rotate(360deg) scale(1);
  }
}

@keyframes rotate-out {
  from {
    transform: translate(-50%, -50%) rotate(360deg) scale(1);
  }
  to {
    transform: translate(-50%, -50%) rotate(720deg) scale(0);
  }
}

.fade-out {
  animation: rotate-out 1s linear forwards;
}
```

次にmahoujin.pngをpublicフォルダの中に入れて完成です！

## おわりに
いかがだったでしょうか？
これが皆さんの開発物に良い刺激を与えれば嬉しいです！
またどこかの記事でお会いしましょう！
PostgreSQL(psqlコマンド)の実行結果をJSONにしてPowerShellで扱う

この記事は、先日書いた以下の記事のPostgreSQL(psqlコマンド)版です。

https://qiita.com/noobow/items/25efab18a2836abb668d

# まずは結果から
サンプルスクリプトは以下のGistに格納しました。
https://gist.github.com/noobow34/42e84ee5f9dec6f672051e72d9dd292b

https://gist.github.com/noobow34/42e84ee5f9dec6f672051e72d9dd292b
```powershell
PS C:\> .\Get-PsqlJsonData.ps1
-----------行を指定して使用する-----------

seq seq2
--- ----
  2    3
-----------行と列を指定して使用する-----------
3
-----------ループで処理する場合-----------
1:2
2:3
3:4
4:5
5:6
6:7
7:8
8:9
9:10
10:11
```

# やりかた
## 扱うデータ
Oracle版で使ったのと同じ結果になるSQLをChatGPTに作ってもらいました。
```sql
SELECT SEQ, SEQ + 1 AS SEQ2 
FROM generate_series(1,10) AS SEQ;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149348/4cd868ea-325e-4072-bd0d-5663b1095b82.png)
```powershell
PS C:\>  @"
>> SELECT SEQ, SEQ + 1 AS SEQ2
>> FROM generate_series(1,10) AS SEQ;
>> "@ | psql -h localhost -U noobow -d noobow
 seq | seq2
-----+------
   1 |    2
   2 |    3
   3 |    4
   4 |    5
   5 |    6
   6 |    7
   7 |    8
   8 |    9
   9 |   10
  10 |   11
(10 行)
```

## psqlの出力をJSONにする
PostgreSQL(psqlコマンド)では元のSQLを生かしたままXMLを出力することはできないようなので、JSONで出力します。以下のSQLで結果をJSONにすることができます。
```sql
SELECT json_agg(t) FROM (元のSQL) t;
```
オプション無しでpsqlコマンドで実行してみると以下のような結果になります。
```powershell
PS C:\Users\skywi> @"
>> SELECT json_agg(t) FROM (SELECT SEQ, SEQ + 1 AS SEQ2 FROM generate_series(1,10) AS SEQ) t;
>> "@ | psql -h server -U user -d database
        json_agg
------------------------
 [{"seq":1,"seq2":2},  +
  {"seq":2,"seq2":3},  +
  {"seq":3,"seq2":4},  +
  {"seq":4,"seq2":5},  +
  {"seq":5,"seq2":6},  +
  {"seq":6,"seq2":7},  +
  {"seq":7,"seq2":8},  +
  {"seq":8,"seq2":9},  +
  {"seq":9,"seq2":10}, +
  {"seq":10,"seq2":11}]
(1 行)
```
列名、行数、JSONの改行が+が表現されているという問題があるので、このままではPowerShellでパースしてJSON型のPowerShellにすることができません。
そこで`-t -A`の2つのオプションをつけます。意味は以下の通りです。
`-t`:行数と列名が出力されなくなる
`-A`:改行の+が出力されなくなる
```powershell
PS C:\Users\skywi> @"
>> SELECT json_agg(t) FROM (SELECT SEQ, SEQ + 1 AS SEQ2 FROM generate_series(1,10) AS SEQ) t;
>> "@ | psql -h server -U user -d database -t -A
[{"seq":1,"seq2":2},
 {"seq":2,"seq2":3},
 {"seq":3,"seq2":4},
 {"seq":4,"seq2":5},
 {"seq":5,"seq2":6},
 {"seq":6,"seq2":7},
 {"seq":7,"seq2":8},
 {"seq":8,"seq2":9},
 {"seq":9,"seq2":10},
 {"seq":10,"seq2":11}]
```

## JSONをPowerShellの変数にする
[SQLite版の記事を参照](https://qiita.com/noobow/items/1eafaed9f1ddf6380741#json%E3%82%92powershell%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%AB%E3%81%99%E3%82%8B)

## JSON変数の扱い方
[SQLite版の記事を参照](https://qiita.com/noobow/items/1eafaed9f1ddf6380741#json%E5%A4%89%E6%95%B0%E3%81%AE%E6%89%B1%E3%81%84%E6%96%B9)
素数判定プログラム

# はじめに
転職の応募に際し、コーディング試験があるため、復習として素数判定プログラムを書いてみた。
ある自然数`n`が素数であるかを判別します。
素数であれば`true`を、素数でなければ`false`を返します。

## コード
```java
public class Main {
    public static void main(String[] args) {
        System.out.println(isPrime(25));  // false
        System.out.println(isPrime(31));  // true
        System.out.println(isPrime(169));  // false
        System.out.println(isPrime(167));  // true
    }
    
    public static boolean isPrime(int n) {

        if (n == 1) {
            return false;
        }

        if (n == 2) {
            return true;
        }

        if (n % 2 == 0) {
            return false;
        } 

        int sqrt = (int) Math.sqrt(n);

        if (n == sqrt*sqrt) {
          return false;
        }
        
        for (int i = 3; i <= sqrt; i += 2) {
            if (n % i == 0) {
                return false;
            }
        }
        
        return true;
    }
}
```

## 解説
### `1`は素数ではないので、`false`を返す。
```java
if (n == 1) {
    return false;
}
```

### `2`は素数なので、`true`を返す。
```java
if (n == 2) {
    return true;
}
```

### `2`を除いた偶数は素数ではないので、`false`を返す。
```java
if (n % 2 == 0) {
    return false;
} 
```

### 数値`n`が素数かどうかは、`nの平方根`まで調べれば十分である。
`nの平方根`が自然数のとき、素数ではないので、`false`を返す。
```java
int sqrt = (int) Math.sqrt(n);

if (n == sqrt*sqrt) {
  return false;
}
```
`2`より大きい偶数は素数ではないことはわかっているので、`i`は`3`から2ずつ増やして素数の判別を行う。
```java
for (int i = 3; i <= sqrt; i += 2) {
    if (n % i == 0) {
        return false;
    }
}
```

### 上記すべてに当てはまらなければ、`true`を返す。
```java
return true;
```

# まとめ
計算量 $O(n^{1/2})$ で素数の判別ができる。
継承について

継承コード
```C#:sample.cs
namespace test
{
	public class Oya //親クラス
	{
		public string cat;
		public string dog;

		public void Method()
		{
			Console.WriteLine(this.cat);
		}
	}

	public class Child : Oya //親クラスを継承
	{
		public string sing;
		public void Method2()
		{
			Console.WriteLine(this.dog);
			Console.WriteLine(this.sing);
		}
	}

	internal class Program //実行クラス
	{
		static void Main(string[] args)
		{
			Child child = new Child();
			child.cat = "猫";
			child.dog = "犬";
			child.sing = "わー！！";

			child.Method();
			child.Method2();
		}
	}
}
```

実行結果
```C#:sample.cs
猫
犬
わー！！
```
MoviePyで作る数学アニメーション入門 : シンプルな関数グラフのアニメーション作成

「MoviePyで作る数学アニメーション入門」
数式の動きを動画として作成・視覚化する方法を解説しています。MoviePyとmatplotlibを組み合わせて、パラメータの変化をアニメーション化する手順を一から説明。Python初心者でも簡単に数学関数の動画教材が作れます。🍙

![マインドマップ (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/6aeb3e68-1346-4f69-b03c-84bbd2266f9e.png)

## はじめに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/7ec5d41c-4240-40d4-a6e1-29f6e71446ea.png)
数学の概念を視覚的に理解することは、学習効果を高める上で非常に重要です。本記事では、MoviePyを使って数学的なアニメーションを作成する方法を解説します。関数の動的な振る舞いを表現することで、静的な教科書では伝えきれない直感的な理解を促すことができます。

## 本記事で学べること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/1c133c2e-c0cf-410b-ab75-0783de4585d1.png)

- MoviePyとmatplotlibを組み合わせた基本的なアニメーション作成方法
- 関数グラフの動的な表現方法
- 数学教育コンテンツの作成テクニック

## 環境設定
必要なライブラリをインストールします：
```bash
pip install moviepy
pip install matplotlib
pip install numpy
```

## 実装コード
以下のコードでは、二次関数 f(x) = ax² のパラメータ a を時間とともに変化させ、グラフの形状が動的に変化するアニメーションを作成します。

```python
from moviepy.editor import VideoClip
from moviepy.video.io.bindings import mplfig_to_npimage
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8, 6), dpi=100)

def setup_plot():
    """グラフの基本設定を行う関数"""
    plt.clf()
    plt.grid(True)
    plt.axhline(y=0, color='k', linestyle='-', alpha=0.3)
    plt.axvline(x=0, color='k', linestyle='-', alpha=0.3)
    plt.xlim(-5, 5)
    plt.ylim(-2, 10)

def make_frame(t):
    """各フレームを生成する関数"""
    a = t + 0.5
    x = np.linspace(-5, 5, 100)
    y = a * x**2
    
    setup_plot()
    plt.plot(x, y, 'b-', label=f'f(x) = {a:.1f}x²')
    plt.title(f'Quadratic Function: f(x) = {a:.1f}x²')
    plt.legend()
    
    fig = plt.gcf()
    canvas = fig.canvas
    canvas.draw()
    width, height = fig.get_size_inches() * fig.get_dpi()
    image = np.frombuffer(canvas.buffer_rgba(), dtype=np.uint8)
    image = image.reshape(int(height), int(width), 4)
    return image[:, :, :3]

# アニメーションの作成と保存
duration = 5
animation = VideoClip(make_frame, duration=duration)
animation.write_videofile("quadratic_function.mp4", fps=24)
```

## 実行結果の解説
生成される動画では、以下のような変化を観察できます：
- パラメータ a が時間とともに増加（0.5から5.5まで）
- 放物線の開きが徐々に大きくなる様子
- グラフ上部の関数式が動的に更新

<iframe width="560" height="315" src="https://www.youtube.com/embed/4beTwS4OKF0?si=2VfEDxS5pXemgo3m" 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>

## 応用例とカスタマイズのヒント

### 異なる関数タイプへの拡張
```python
# 三角関数の例
y = np.sin(a * x)
# 指数関数の例
y = np.exp(a * x)
```

### 複数関数の同時表示
```python
plt.plot(x, y1, 'b-', label='function 1')
plt.plot(x, y2, 'r--', label='function 2')
```

### パラメータ変化パターンの変更
```python
# 正弦波による変化
a = 2 + np.sin(t)
# 指数的な変化
a = 0.5 * np.exp(0.5 * t)
```

## まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b90ec62a-5fa9-412b-ab4d-c1f053c1f49b.png)

MoviePyとmatplotlibを組み合わせることで、数学的な概念を動的に表現するアニメーションを作成できることを学びました。

## 参考文献とリソース
- [MoviePy公式ドキュメント](https://zulko.github.io/moviepy/)
- [Matplotlib公式ドキュメント](https://matplotlib.org/)
- [NumPy公式ドキュメント](https://numpy.org/doc/)
EUWでStaticMeshのデフォルトマテリアルをまとめて変えたい覚書

何千個とかのアセットを編集しないといけないあなたにお勧め！！！！！

作るのは、
アウトライナーで選択中のStaticMeshがFromMaterialに設定したMaterialが使われている場合、そのマテリアルをToMaterialに設定されたマテリアルに変更するEUWです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/ee6436d1-3fef-49f2-818d-f217d0228d93.png)


### EUWを作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/f4646dc7-45a1-4186-a48d-30a26151ad31.png)
好きな形式でEUWを作ります。

### Details Viewを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/f0331269-34ca-4586-89da-d62d08ec2017.png)
UEよくあるドロップダウン式アセット選択を作れるやつです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/65fdfad9-4149-45d8-b51c-5e5b539dfe5f.png)
置くとこんな感じ
Details Viewの詳細を開き、Categories to Showにインデックスを追加しお好みの名前を入力します（後で使います）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/c3ced951-9cdf-4b69-920f-7c371cbd0c7b.png)

### 選択先の変数を作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/35677fc9-c9df-480e-be53-4075ae869aa0.png)
マテリアルインターフェース形式で変数を作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/7c4d26a7-e3f4-48ae-b58d-1cd747a9d070.png)


詳細からカテゴリに先ほどDetiles ViewのCategories to Showに追加した名前を入力します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/ec301cdd-4795-4895-9a30-f1f409a31286.png)

### BPでDetails ViewにSet Objectする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/22a8b512-4ff1-46da-9db4-43e82d563d4e.png)
Pre ConstructからSetObjectで呼び出してセットします。
コンパイルするとデザイナー画面側のDetiles Viewがこんな感じになっています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/155c340d-6d3c-4d9a-8b7e-1b964588179f.png)

### ボタンを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/5379df6c-2b70-4e07-8039-9a4a77fe4001.png)

押したときにアップデートする用のボタンを配置します

### 機能を組む
追加したボタンを押したときに選択中のアセットからStaticMeshであるものを選別して、マテリアルスロットがNoneになるまで２０回マテリアルを確認しもしFromMaterialと一致したらToMaterialと交換するように書きます
![EUW_ChangeMaterials-EventGraph_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/9981631f-e064-4e32-8a36-55d1982feb2e.png)

### 実際に試す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/af4ad8fe-0091-4938-8b4c-a6f569b5f6f1.png)
こういう状態になってることありますよね？あるって言って

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/3c0a17bf-f136-4651-ac6e-f4dbd38ca8aa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/330882e5-06c6-4bac-923d-93429138088f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/baea9758-2a61-42a4-86e3-98362d01ae13.png)

スロットの色の順番もバラバラ、インスタンスとマテリアルが混ざってる、（3個ならまだしも）何千個とかあったらとても主導では直したくない状態です。

これをマテリアルを選んだ状態でアセットを選択し、ボタンを押すと…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/3eb273a8-4bdf-4464-9ce6-8b680d38976e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257391/d019b5c9-d695-4661-8e33-fb374772f1f4.png)
Red1を使ったマテリアルが変更！

なんて便利なんだEUW…
「バグが後を絶たない」という悩み

多くの開発現場が「バグが後を絶たない」という悩みを抱えています。既存バグを修正しきれていないうちに、新たなバグが次々と発生し、未解決のバグが山積みになってしまう状況が課題となります。

一見、どうにもならない問題に思えるかもしれませんが、実際にちゃんと向き合えば解決できます。
ただし、いくつかのポイントを押さえて取り組む必要があります：

- 仕様の明確化
- コードアーキテクチャ
- QAの自動化
- 開発環境の整備

バグ修正に追いつくことができない現場の共通点は：

- 仕様をちゃんと理解されていない。「こんな挙動が大丈夫でしたっけ？」と疑問が尽きない
- QAを実施するのに難易度が高くて、実際にQAされていないまま本番にリリースしてしまいます
- コードや設計が複雑すぎて理解・調査が困難で、修正まで時間がかかる

## (1) アプリの仕様

仕様が不明確だと、バグの多発もQAの成り立たないのも当然。

仕様書の管理できていない現場は是非ここ最優先で改善していただきたい。

効率のいい仕様書の特徴：

- 整理整頓：参照しやすい状態で保持されている
- 簡潔：１行で伝わるものが長文で書かれていない
- 明確：曖昧な表現を避け、正確な技術用語で記述

また、ビジネス側ではなく、テックリードが責任を持って管理してもらうほうがより効果的です。

この基盤が整えば、後の設計やテストの自動化がスムーズに進む土台となります。

## (2) コードの設計

コンピュータの基本動作は、「データの処理」と「データの入出力」の2つだけです。これは意見ではなく、誰も否定出来ない事実。

システムのあらゆる機能は、正しいデータの処理によって成り立っています。

従って、コードの設計はその事実を反映するように構築すると、
データの流れがわかりやすくなり、システム全体の保守性が大きく向上します。

データの流れを濁すような無駄な抽象化を排除しておかないと、バグの調査や修正は困難になって
しまいます。

## (3) QAの自動化

バグを修正した後、影響範囲の確認が必要になります。他の機能が壊されていないのかはよくある心配ですね。

信頼できる仕様書があれば手動テストでも対応できますが、時間がかかる上に細かいミスを見落とすリスクもあります。

多くの開発チームは「コードレビュー」や「単体テスト」に過度な時間を費やしますが、ほとんどの場合、それは非効率的なんです。確認したいのは、システム内部の細かな挙動ではなく、ユーザー視点での動作が劣化していないか。

単体テストより、システム全体を対象にした、いわゆるend-to-endテストを自動化する方が圧倒的に効果的です。

効果的なe2eテストの特徴：

- ユーザーがシステムを操作する流れを正確に再現
- モック利用せず、本番環境と同じ条件で関連するすべてのコードを実行
- システムの内部状態には関与せず、ユーザーの入力と出力のみを扱う

これらが揃えば、バグ修正を自信を持って進められるようになります。

## (4) 開発環境の整備

いうこともないはずですが、ここまでの努力も、テストが簡単に実行できる環境じゃないと効果を発揮しません。

快適な開発環境は、ワンコマンドでシステムを起動でき、編集・実行・デバッグのサイクルがスムーズに回る状態が理想です。

検証環境でも同様に、ワンコマンドでテスト実行できるようにしておくことが重要です。


## まとめ

参照しやすい仕様書、データの流れ把握しやすいコード、充実した自動QAテスト、円滑な開発環境——これらが揃えば、バグ修正を自信を持って進められ、「バグが後を絶たない」という地獄から脱出できるようになります。
#0052（2024/02/20）Linuxのパーミッション表示

# Linuxのパーミッション表示のパターンと意味

`ls -l` などで表示されるパーミッション表記は、ファイルやディレクトリの種類、アクセス権限、特殊ビット、拡張属性などを表しています。  
ここでは、さまざまなパターンとその意味を詳しく解説します。

---

## 1. ファイルタイプを示す先頭文字

先頭の1文字は、ファイルの種類を示します。代表的なものは以下の通りです。

| 文字 | 種類                                     |
|------|------------------------------------------|
| `-`  | 通常のファイル                           |
| `d`  | ディレクトリ                             |
| `l`  | シンボリックリンク                       |
| `c`  | キャラクタデバイス（文字デバイス）         |
| `b`  | ブロックデバイス                         |
| `p`  | FIFO（名前付きパイプ）                   |
| `s`  | ソケット                                 |

---

## 2. 標準のアクセス権限 (9文字)

先頭文字の後ろの9文字は、所有者、グループ、その他のユーザーに対する権限を3文字ずつ表します。  
基本的な記号は次の通りです。

- `r`: 読み取り権限
- `w`: 書き込み権限
- `x`: 実行権限（またはディレクトリの場合は中に入る権限）
- `-`: 該当権限がない

例えば、`rwxr-xr-x` は以下の意味です。

- **所有者:** `rwx` → 読み取り、書き込み、実行可能
- **グループ:** `r-x` → 読み取り、実行可能（書き込み不可）
- **その他:** `r-x` → 読み取り、実行可能（書き込み不可）

---

## 3. 特殊ビットと追加記号

標準の9文字以外に、表示の最後に付加される記号や、3文字の中に特殊な記号が入る場合があります。

### (a) セットユーザビット (setuid) / セットグループビット (setgid)

- **setuid:**
  - 所有者の実行位置に `s` または `S` が表示される。
  - 例: `rws`（実行権限もあり setuid 有り）または `rwS`（実行権限無しだが setuid 有り）。
- **setgid:**
  - グループの実行位置に `s` または `S` が表示される。
  - 例: `rws`（実行権限もあり setgid 有り）または `rwS`（実行権限無しだが setgid 有り）。

### (b) スティッキービット (sticky bit)

- **sticky bit:**
  - その他の実行位置に `t` または `T` として表示される。
  - 例: `rwt`（実行権限もあり sticky 有り）または `rwT`（実行権限無しだが sticky 有り）。
  - これは、ディレクトリの場合、ファイルの削除・名前変更の権限をそのファイルの所有者やrootに限定するために使われます。

### (c) 拡張ACLや属性の表示

- 行末に **`+`** が付いている場合：  
  拡張ACL (Access Control List) が設定されていることを意味します。
- 行末に **`.`** が付いている場合：  
  SELinuxのコンテキストなど追加の属性が設定されている場合があります（システムや設定による）。

---

## 4. 具体例とそのパターン

### 例1: `-rwxr-xr-x`
- **先頭:** `-` → 通常のファイル
- **所有者:** `rwx` → 読み取り、書き込み、実行可能
- **グループ:** `r-x` → 読み取り、実行可能
- **その他:** `r-x` → 読み取り、実行可能

### 例2: `drwxr-xr-x`
- **先頭:** `d` → ディレクトリ
- 標準のパーミッションは例1と同様

### 例3: `-rw-r--r--+`
- **先頭:** `-` → 通常のファイル
- **所有者:** `rw-` → 読み取り、書き込み可能
- **グループ:** `r--` → 読み取りのみ
- **その他:** `r--` → 読み取りのみ
- **末尾の `+`:** 拡張ACLが設定されている

### 例4: `-rwsr-sr-x`
- **先頭:** `-` → 通常のファイル
- **所有者:** `rws` → setuid が有効な上、実行権限あり
- **グループ:** `r-s` → setgid が有効な上、実行権限あり
- **その他:** `r-x` → 読み取り、実行可能

### 例5: `drwxrwxrwt`
- **先頭:** `d` → ディレクトリ
- **所有者、グループ:** `rwx` → フルアクセス
- **その他:** `rwt` → 通常は全ユーザーに読み取り・実行権限があり、さらに sticky bit (`t`) により削除権限が制限されている  
  - 典型的な例として `/tmp` ディレクトリがあります。

---

## まとめ

- **ファイルタイプ:** 先頭1文字でファイルの種類（通常ファイル、ディレクトリ、シンボリックリンクなど）を表す。
- **標準パーミッション:** 続く9文字は、所有者、グループ、その他のユーザーに対する読み取り、書き込み、実行の権限を示す。
- **特殊ビット:** setuid、setgid、stickyビットは、通常の権限表示に加え、セキュリティや操作の制御を行うための追加情報を提供する。
- **拡張属性:** 行末の `+` や `.` は、ACLや追加属性の設定を示す。
BoxDrive等のユーザーによってファイルパスが異なる場合のショートカット共有方法

ユーザーごとにファイルパスが異なる場合には、フォルダやファイルのショートカットを作成しても作成者本人にしか利用できません。
その場合のフォルダのショートカットの共有方法を考えてみました。



```bat:Windowsバッチファイル
@echo off
rem 目的：『C:\Users\12345\Desktop』を表示する。
rem ※『C:\Users\12345』部分は環境変数のため、それ以降を指定
rem echo %USERPROFILE%
set "targetPath=%USERPROFILE%\Desktop"

if not exist "%targetPath%" (
    echo フォルダが見つかりません。
    pause
    exit /b
)
start "" "%targetPath%"
```

実行前に実行してよいか確認したいなら、下記のコードです。

```bat:Windowsバッチファイル
@echo off
setlocal
rem 目的：『C:\Users\12345\Desktop』を表示する。
rem ※『C:\Users\12345』部分は環境変数のため、それ以降を指定

set "targetPath=%USERPROFILE%\【外】OneDrive"

:: フォルダのパスを表示
:RESTART
echo 指定されたフォルダ: "%targetPath%"

:: ユーザー入力を取得
set "choice="
set /p "choice=このフォルダを開きますか？ (Y/N): " 
set "choice=%choice:~0,1%"  & rem 先頭1文字のみ取得
set /a "choice=0x%choice%" >nul 2>&1 & if errorlevel 1 set choice=%choice:~0,1%

:: 大文字・小文字の区別なくYなら実行、それ以外は中止
if /i "%choice%"=="Y" (
    if exist "%targetPath%" (
        start "" "%targetPath%"
    ) else (
        echo フォルダが見つかりません。
        pause
    )
) else if /i "%choice%"=="N" (
    echo 処理を中止しました。
    pause
) else (
    echo もう一度入力してください。
    goto RESTART
)
```

また、上記のようにフォルダパスではなく、Excel等のファイルの場合も基本は同じです。

```bat:Windowsバッチファイル
@echo off
rem 目的：『C:\Users\81805\Downloads\テスト.xlsx』を表示する。
rem ※『C:\Users\12345』部分は環境変数のため、それ以降を指定
rem echo %USERPROFILE%
set "targetPath=%USERPROFILE%\Downloads\テスト.xlsx"

rem echo 指定されたフォルダ: %targetPath%

if not exist "%targetPath%" (
    echo フォルダが見つかりません。
    pause
    exit /b
)

start "" "%targetPath%"
```

Windowsでショートカットを相対パスで記載する方法もあるようですが、結構クセがあるため、より簡単なバッチファイルでの解決を考えてみました。
Elasticsearchを動かす

業務でElasticsearchを使う機会があったのですが、何も考えずに手順だけ追えば良い日本語の記事で、なおかつ新しい記事がなかったので、ここにElasticsearchを動かすことができる記事を残しておこうと思います。

公式ページはここですが、作業の枝分かれとかあったりして、Elasticsearchはもとより全般的な知識のない人だと作業の取捨選択に手こずりそうだなという印象を受けました。
https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html

WindowsでもLinuxでもMacOSで大丈夫です。
動かすのはシングルノードのクラスターです。
なお、Dockerはすでにインストール済みとします。

# ①Elasticsearch用の新しいDockerネットワークを作る
```shell
docker network create elastic
```

# ②ElasticsearchのDockerイメージをプルする
```shell
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.17.2
```

# ③Elasticsearchのコンテナを起動する
```shell
docker run --name es01 --net elastic -p 9200:9200 -it -m 1GB docker.elastic.co/elasticsearch/elasticsearch:8.17.2
```
コンテナを起動すると、下図のようなタイムスタンプが大量に表示され、次のコマンドが打てなくなります。
![スクリーンショット 2025-02-20 21.31.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/89f9892b-800d-4270-8a7e-f5983f066c20.png)
次の手順を実行するために、コマンドプロンプトを別タブで開く。
# ④Elasticsearchのパスワードとトークンを生成する
パスワード:
```shell
docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
```
トークン：
```shell
docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
```

# ⑤Elasticsearchのパスワードを環境変数に設定する
⑥で生成したパスワードを設定しておく

shellの場合:
```shell
export ELASTIC_PASSWORD="your_password
```

PowerShellの場合:
```powershell
setx ELASTIC_PASSWORD "your_password"
```

# ⑥コンテナからSSL証明書をコピーする
```shell
docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .
```

# ⑦KibanaのDockerイメージをプルする
KibanaはElasticsearchをブラウザで視認しやすくするためのソフトウェアです。
```shell
docker pull docker.elastic.co/kibana/kibana:8.17.2
```

# ⑧Kibanaのコンテナを起動する
```shell
docker run --name kib01 --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.17.2
```

# ⑨Kibanaをブラウザで表示する
`http://localhost:5601/app/home#/`にアクセスすると、さきほど生成したトークンの入力フォームが現れます。
![スクリーンショット 2025-02-20 21.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/8f072712-89b9-429e-92c5-c3745a2ba1d8.png)

トークンを入力すると、ローカルのターミナル(コンソール)に6桁の数字が表れるため、それも入力フォームに入力します。

![スクリーンショット 2025-02-20 21.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/d3497210-b69a-4e90-a141-ba9190c42a01.png)

上の画像の例だと`640590`ですね。

そして、ログインに使うusernameは`elastic`、パスワードはさきほど生成したものを使います。
![スクリーンショット 2025-02-20 21.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/71b5e7a2-ae24-4858-bdde-29e4079774ac.png)

上記を入力したら「Log in」をクリックしてください。

# ⑩完了
![スクリーンショット 2025-02-20 21.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/1a77afcf-2991-4108-832b-15d18d0f6655.png)


これでElasticsearchの状態がブラウザで見えるようになりました。
ServiceNow YokohamaリリースPDI触ってみた：リストコントロールのUI変更

# 概要
もうすぐ（？）Yokohamaリリースということで、リリースノートやPDIを見たりしてたらリストコントロールのUIがけっこう変わっている発見をしたので気づきのメモです。

**※記事を書いておきながら大変申し訳ないのですが、潔く最初に申し上げます。**
　**UIは変わりましたがWashingtonやXanaduからの新機能はありません。ただ私が気付いただけです！！**

リリースノートを徘徊してた時は気づかなかったので、やはり現物を触ってみることで得られる発見もありますね。（ちゃんと読んでないだけ説もありますがｗ）

# UI変更点

Xanaduまではリストコントロール画面を開くと、画面にずらっと設定項目が並ぶ感じでしたが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/5717e24b-8471-4916-994a-39f401381392.png)

Yokohamaからは、設定項目が3つのタブで構成される見た目に変わっています。
・Display Configuration
・Edit configuration
・Performance
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/877dd296-4482-4014-a668-2a1b3222c2ec.png)

#前バージョンからの差分
冒頭にも書きましたが、設定個所を順番に目検しても、docsを見比べてみても（コピペして生成AIに調べさせてみても）設定項目の差分はありませんでした。
ただ、新UIではタブで整理されたことにより設定項目が見やすく（たくさんあるものから1つ見つけるのではなく、パッ、パッと切り替えて目に入るように）なり、遅ればせながら「List edit insert row」を発見し、こんなことできるんだ！という気づきはありました。

https://x.com/_sasasaku_/status/1891656713704542605

・・・・・・よくよく調べたらUtahからあったらしいです。もっと早く気づけわたし。

# あとがき
XにてUIの変化を投稿したところLT向けのテーマですねとリプを頂き、ちょっと調べてみるかぁと思ったら機能差異はなかったというオチになってしまったので、こちらで供養させていただきます。
とはいえ、見た目の変化に気づく、新しいものを触ってみる、前からあった機能でも使い道を考えてみる、という視点は気づきを得るうえで大事だなぁと改めて思いました。
【開発者向け】無料でGPT-4o APIキーを取得する方法


## はじめに
OpenAI APIの有料版の使い方は広く知られていますが、開発者がテスト目的で使える無料のGPT-4o APIキーを取得する方法をご存知でしょうか？今回は、GitHubを通じて無料でGPT-4oを体験できる方法をご紹介します。

## APIキーの取得手順

### 1. GitHubマーケットプレイスにアクセス

まずは下記のリンクにアクセスしてください：
https://github.com/marketplace/models/azure-openai/gpt-4o/playground

### 2. APIキーの発行

#### 1. 画面右上の「Get API key」ボタンをクリックします

![スクリーンショット 2025-02-20 20.52.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827838/6572aeb1-c344-4d8a-91e1-f7943d5937f0.png)

#### 2. 表示されたダイアログで「Get developer key」ボタンをクリックします

![スクリーンショット 2025-02-20 20.54.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827838/eecfa6e5-c4fa-4736-b713-8acfb996c1fc.png)

#### 3. 遷移先のページで「Generate new token」ボタンを押してトークンを発行します

![スクリーンショット 2025-02-20 20.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827838/618dc3aa-8752-4a55-86c3-d98028d3b44c.png)

#### 4. 発行されたトークンをコピーし、安全なスペースに保存しましょう

## 実装手順

### 1. 環境設定
まずはNode.jsをインストールしてください。

### 2. プロジェクトの初期化
以下の内容で`package.json`を作成します：

```json
{
  "type": "module",
  "dependencies": {
    "openai": "latest"
  }
}
```

### 3. 依存関係のインストール
VSCodeでフォルダを開き、ターミナルで以下のコマンドを実行します：
```bash
npm install
```

### 4. 環境変数の設定
`.env`ファイルを作成し、以下の内容を記入してください。

```bash
# 忘れないように、YOUR_TOKENを置き換えてください。
GITHUB_TOKEN=YOUR_TOKEN
```

### 5. サンプルコードの実装
以下のコードを`sample.js`として保存します：

```javascript
import OpenAI from "openai";
import dotenv from "dotenv";

dotenv.config();

const token = process.env["GITHUB_TOKEN"];
const endpoint = "https://models.inference.ai.azure.com";
const modelName = "gpt-4o";

export async function main() {
  const client = new OpenAI({ baseURL: endpoint, apiKey: token });

  const response = await client.chat.completions.create({
    messages: [
      { role:"system", content: "You are a helpful assistant." },
      { role:"user", content: "What is the capital of France?" }
    ],
    temperature: 1.0,
    top_p: 1.0,
    max_tokens: 1000,
    model: modelName
  });

  console.log(response.choices[0].message.content);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});
```

### 6. 実行
ターミナルで以下のコマンドを実行します：
```bash
node sample.js
```

実行結果がターミナルに表示され、GPT-4oによって生成された回答を確認できます。

![スクリーンショット 2025-02-20 21.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827838/7ff76d5c-20b4-441f-a481-947bc7598427.png)

### 7. その他のサンプルコード実装
先のdialogの「Run a basic code sample」セクションには、以下のような様々なサンプルコードが用意されています。それぞれの実装例を自分で見てみましょう。

- Run a multi-turn conversation
- Stream the output
- Chat with an image input
- Identify and invoke tools

### 8. レート制限

こちらのページで確認しましょう
https://docs.github.com/en/github-models/prototyping-with-ai-models#rate-limits

## さいごに
この手順を従うことで、開発者は無料でGPT-4oのAPIを試すことができます。本番環境では正規のOpenAI APIの利用をお勧めしますが、初めてAPIを試したい初心者は、ぜひ遊んでみてください！

[OpenAI Documentation](https://platform.openai.com/docs/overview)
[OpenAIのAPI利用登録とAPIキー発行方法（動画）](https://www.youtube.com/watch?v=rTP5jPVO2CY)
Terraform/Azure/azurerm_network_security_ruleについて

# azurerm_network_security_ruleについて

このリソースは、Azure のネットワークセキュリティグループ（NSG）に適用する個別のセキュリティルールを定義するために使用します。受信（Inbound）および送信（Outbound）のトラフィックを制御でき、許可（Allow）または拒否（Deny）を設定可能です。

[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_rule)

# 必須パラメータ
| パラメーター名 | 型 | 説明 |
|---|---|---|
| name | string | ルールの名前 |
| priority | number | ルールの適用順<br>（100～4096、小さいほど優先） |
| direction | string | Inbound（受信）<br>Outbound（送信） |
| access | string | Allow（許可）<br> Deny（拒否） |
| protocol | string | Tcp、Udp、Icmp、Esp、Ah、<br>*（すべてのプロトコル） |
| source_port_range | string | 送信元ポートの範囲<br>（* で全ポート指定） |
| destination_port_range | string | 宛先ポートの範囲<br>* で全ポート指定） |
| source_address_prefix | string | 送信元 IP アドレスまたは範囲<br>（例: 10.0.0.0/24） |
| destination_address_prefix | string | 宛先 IP アドレスまたは範囲<br>（例: 0.0.0.0/0 は全宛先） |
| resource_group_name | string | リソースグループの名前 |
| network_security_group_name | string | 適用する NSG の名前 |

# 任意パラメータ
| パラメーター名 | 型 | 説明 |
|---|---|---|
| description | string | ルールの説明 |
| source_port_ranges | list(string) | 複数の送信元ポート範囲を<br>指定する場合に使用 |
| destination_port_ranges | list(string) | 複数の宛先ポート範囲を<br>指定する場合に使用 |
| source_address_prefixes | list(string) | 複数の送信元 IP を<br>指定する場合に使用 |
| destination_address_prefixes | list(string) | 複数の宛先 IP を<br>指定する場合に使用 |


# サンプルコード
以下は、SSH（ポート 22）を全ての送信元 IP から許可するルール を作成する Terraform の例です。

```main.tf
resource "azurerm_network_security_rule" "allow_ssh" {
  name                        = "AllowSSH"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "22"
  source_address_prefix       = "0.0.0.0/0"
  destination_address_prefix  = "*"
  resource_group_name         = "example-resources"
  network_security_group_name = "example-nsg"
}
```
AIエディタ Cursorで関数定義ジャンプができなかったけど解決

# AIエディタ Cursorで関数定義ジャンプする

### 事象

CursorでVSCodeのように関数の定義ジャンプをしようとしたができなくて困ってました。

開発言語はPHPです。

### 解決方法

VSCodeと同様、PHP開発のための拡張機能 **PHP Intelephense** をインストールしました。

![スクリーンショット 2025-02-20 21.17.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290442/28287c63-9824-43c3-81d6-ef5fa6d29e92.png)


拡張機能をインストール & 有効化し、関数名を `Ctrl + Click` すると表示されるダイアログにVSCodeのときと同様「Go To Definition」が表示され、クリックすると関数の定義先にジャンプできるようになりました。

![スクリーンショット 2025-02-20 21.32.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290442/923bfeb5-4cca-4a17-9c2f-b6b7f4502c97.png)

また、PHPの他にもPythonでは、Python専用エクステンション（たぶん一番有名なヤツ）をインストールすることで同様に定義ジャンプが可能になりました。

![スクリーンショット 2025-02-20 21.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290442/422cab9d-6878-41c3-80bf-b317eebb5401.png)


とても単純な話でしたが、VSCodeにはエクステンションを入れて使っているのが当たり前すぎて気が付かなかったです。

その他の開発言語については試してませんが、おそらく同様にその言語用の拡張機能をインストールすれば問題は解決するのではないでしょうか。
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for db failed: Name or service not known (Connection: mysql, SQL: delete from `cache`)

## 概要
dockerコンテナを切り替え時にMysql,PHPMyadminに接続できなくなり、DBに関わる作業ができなくなった。

## 原因調査
Qiitaの他の記事やGoogle検索をしたところ、docker-compose.ymlファイルとenvファイルのDB名に差異があると発生することがある模様。
ただ、今回は元々使用できていたアプリに対して特に変更を実施していなかったため関係ないと考えましたが念のため確認。
特に問題は見受けられなかったため、次はdocker psで他の環境が起動してないか確認。

![スクリーンショット 2025-02-20 20.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880277/3f6ab491-3dca-4425-aadc-15302750b549.png)

→特に起動してない模様。

他に考えられる原因がないか調べたところ、下記記事を発見。
https://qiita.com/greencha/items/9acf33959ea310fdbae1

volumeを一括削除することで、解決することもあるらしくdockerが停止されていることを確認した後下記コマンドを実施。
```
docker volume prune

WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
以下省略

Total reclaimed space: 15.248GB
```
→こちらでも解決されず。

最終手段として、下記コマンドを実施。
バックアップが必要なものバックアップを取るなどして、下記コマンドを実行。
未使用のネットワークなどを削除してしまうため、避けたかったですが業務に支障が出たためやむを得ず実行。
```
docker system prune
```

→上記コマンドで、解決

## 感想
解決は出来ましたが特定の原因究明には至らず、少々不完全燃焼な形となりました。dockerについての理解などがまだ足りてない部分などはさらに学習が必要と認識できたため、ある種良い機会になったと感じました。
同じ現象が起きた方の解決の手助けになると幸いです。
AITRIOS WASM Logを見る

Edge Applicationが出力するログ（WASM Log）を見る手順です。
環境はConsole Developer Edition + AIH-IVRW2です。

先にポイントを書いておくと、

* デバイスにWASM Log出力を有効/無効設定します。
* `Connected`の状態じゃないと、WASM Log出力を有効化するときにエラーになります。
* デバイスの電源をオフするとWASM Log出力は無効になります。
* WASM Log出力が有効になっていると、WASM LogがConsoleに保存されます。

# 1. REST APIのアクセストークンを取得

WASM Logの有効化はConsole REST APIを使いますので、それ用のアクセストークンを取得します。

## 1-1. API KeyとSecretをbase64エンコード

```
echo -n "{API Key}:{Secret}" | openssl enc -e -base64
```

## 1-2. Access Tokenを取得

```
curl --request POST \
--url 'https://auth.aitrios.sony-semicon.com/oauth2/default/v1/token' \
--header 'accept: application/json' \
--header "authorization: Basic {base64したAPI KeyとSecret}" \
--header 'cache-control: no-cache' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials&scope=system'
```

こんなJSONが返ってきます。
`access_token`がアクセストークンです。

> アクセストークンの有効期限は1時間です。

```
{
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "{Access Token}",
    "scope": "system"
}
```

# 2. デバイスを接続

デバイスを起動してConsoleに接続しておきます。

# 3. WASM Logを有効化

```
curl --request PUT \
--url 'https://console.aitrios.sony-semicon.com/api/v1/devices/{Device ID}/configuration/applog' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {Access Token}' \
--data '{"enable": true}'
```

成功するとこんなJSONが返ってきます。

```
{"result":"SUCCESS"}
```

# 4. 推論の実行と停止

`Console > Manage Device > Device > <Device> の Settings > Inference Control > Get Inference Data`で推論を実行すると、デバイスのWASM LogがConsoleに送られて保存されます。
推論し続けるとConsoleの負担になると思うので、推論の実行は短時間にするよう心がけましょう。

# 5. WASM Logを確認

`Console > Manage Device > Device > <Device> の Status > WASM Log`で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/06ea7c78-a825-494a-a9f5-57259a07cb91.png)
【async await】delete後の再表示で削除したデータが表示される

# はじめに
削除機能を実装中に再表示で削除したデータが表示される事象に詰まってしまったため、備忘録として記事にします。

# 問題
削除ボタン押下後もデータが表示されたまま、リロードをすると消える状態
![レコーディング 2025-02-20 200056.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/ed718043-5a64-453b-88ad-02dc482c6ddc.gif)

DBでは該当データが消えることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/f1267434-39a8-4d43-a91d-7a573406738c.png)

この時のコード
```react:App.jsx
const [records, setRecords] = useState([]);
// 削除ボタン押下
const onClickDelete = (id) => {
    deleteData(id);
    // 削除後のデータを全件取得する
    const datas =  getAllDatas();
    datas.then((data) => {setRecords(data)});
};
```

deleteData(id);の処理が完了する前に、const datas =  getAllDatas();の処理が走っていたことが原因でした。

```javascript:supabaseFunctions.js
import { supabase } from "./spabase"

export const getAllDatas = async() => {
  const datas = await supabase.from("study-record").select("*"); 
  return datas.data;
};

export const deleteData = async(props) => {
  const response = await supabase.from("study-record").delete().eq('id', props)
};
```

# 解決方法
### async awaitを使う

参考記事より引用
>async とは?
async を関数の前に付けることで、その関数は非同期であることを示します。
関数（プログラムのまとまり）の前に async を付けると、「この関数の中には、終わるのを待たなければいけない作業があるかも」とプログラムに教えることができます。

>await とは?
await を使うと、「この作業が終わるのを待つよ」という指示が出せます。await は必ず async 関数の中で使用する必要があります。

```reactApp.jsx
  const [records, setRecords] = useState([]);
  const getDatas =  async() => {
    const datas = await getAllDatas();
    setRecords(datas);
  }
  // 削除ボタン押下
  const onClickDelete = async (id) => {
    await deleteData(id);
    getDatas();
  };
```

1. deleteData(id);にawaitを適用して完全にデータ削除処理が終わるのを待ってもらってから、getAllDatas();を呼ぶように修正
2. getAllDatas();もawaitを適用、完全にデータを取得する処理が終わるのを待ってから、useStateでsetするように修正


# おわりに
講師の方に質問したところ爆速で解決しました。
身近に有識者がいるのは本当にありがたい。

# 参考
カレーの例えが非常にわかりやすかったです。

https://zenn.dev/singularity/articles/360d69fde8322d