OmniAICreator/Qiita-1.07M huggingface dataset:
Alternating Updates for Efficient Transformers

# 1. 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/9e552029-616e-1edd-cbb2-9f8836e43173.png)

大規模言語モデル(LLM)のバックボーンに使われるトランスフォーマーネットワークは、情報の質と性能を飛躍的に向上させている。なぜ各レイヤーでアテンションを用いて高次元特徴を抽出してうまく情報が取れるのかや、各レイヤーで繰り返しトークンをよりよく表現する代表ベクトルをアップデートしながら抽出するのか、という点に立ち返ると、次元を増やしてベクトルの表現の幅が広がった方がより多くの情報表現ができるので精度が向上しそうと考えられる。
この研究では、Alternating Updates(AltUp)という、トークンをよりよく表現する代表ベクトルを次元を拡張させて大規模化する手法を、計算時間を変えずに実現する方法を提案している。

---

# 2. 新規性
トランスフォーマーネットワークのモデル容量を増加させるシンプルな方法を提案している。トークンをよりよく表現する学習済みのベクトルを拡張しているが、推論の遅延など演算時間はほとんど増加しない点が新規ポイントになっている。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/db645454-49c4-e16f-d96c-534b2ae4fea5.png)

この研究では、レイヤーの深さ(depth)と特徴表現できるベクトルの幅(width)に対してベクトルの幅を拡張したほうが計算時間を考慮しても情報表現能力が高まると考え、深さを半分にして幅を2倍にした場合で考えている。
各レイヤー内で不活性のブロックを軽量に予測して重みをアップデートしていくパラメータ(predict-and-correct)を追加している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/5c292722-7de9-c091-6029-64bc18eabfa5.png)

 - Predictio: o(K^2 * d)
   - 各ブロック内では、2つのブロックを混合して重みづけを行う
   - ブロック間の情報を受け渡す
 - Correction: o(K * d) 
   - 結合したブロックから非アクティブなブロックについて重みを更新する

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/bbb902aa-1d21-1a28-9876-d6aab704cf43.png)

トランスフォーマーを用いたモデル(T5+AltUp)を言語タスクであるSuperGLUEやSQuaDベンチマークで評価したところ、最大87%の高速化を達成しつつ精度を維持することに成功した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/ebcaa0e6-1465-a0a1-8ad8-5f4c54b8490b.png)

T5のSmall/Base/Largeに提案手法のAltUpをKの値を変動させながら評価した結果を示している。提案手法では、トランスフォーマーの性能を効率的に向上させつつ、計算コストと推論の遅延を抑えることに成功している。

---

Paper URL: <https://openreview.net/forum?id=1p6teT6F73>

last updates: May. 29 2024
WindowsにRufusをインストールする

## 1.Rufusとは
Rufusとは、USBドライブのブート可能なメディアを作成するためのツールです。以下の手順でWindowsにRufusをインストールしてください。

## 2. Rufusのダウンロード

1. Webブラウザを開き、[Rufus](https://rufus.ie/)の公式サイトにアクセスします。


2. ページをスクロールして「**ダウンロード**」を見つけます。

3. 最新のRufusバージョンを確認し、適したリンクをクリックして、Rufusの実行可能ファイル（.exe）をダウンロードします。

以下のような基準でダウンロードするリンクを選択してください。
- タイプ
    - 標準 : インストール版
    - Portable : ポータブル版。インストールせずにUSBドライブやその他のストレージメディアから直接実行できる。持ち運びしたい時や複数のPCで使いたい場合に適している。

- プラットフォーム
数字はビット数を表しています。どれが良いか分からない場合は、自分のパソコンのビット数を確認しましょう。Windows10または11の場合、ビット数は「設定→システム→バージョン情報→システムの種類」で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850895/34ed1f68-56b2-b4cb-c495-caa4188eda4a.png)


## 3. Rufusの実行

1. ダウンロードしたファイル（通常は「rufus-x.x.exe」）をダブルクリックして実行します。

2. ユーザーアカウント制御（UAC）が表示された場合、「**はい**」をクリックして続行します。

## 4. Rufusの設定

1. Rufusが起動すると、以下の設定を行います。デバイスとISOファイルを選択すると他の設定は自動的に最適なものが選択されます。
   - **デバイス**：使用するUSBドライブを選択する。
   - **ブートの選択**：使用するISOファイルやディスクを選択する。
   - **保存領域のサイズ**：USBドライブのどのくらいをインストーラーに使用するかを表す。０で問題なし。
   - **パーティション構成**：対応しているものが不明な場合はMBR、もし対応しているのであればGPTを選択する。
   - **ファイルシステム**：基本的にはFAT32、より大きいデータや速い速度を求める場合はNTFSを選択する。
   - **クラスターサイズ**：ディスクに保存する時の単位のこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850895/c2efa327-11ab-4d65-de18-fbcb834ea5b1.png)

2. 設定が完了したら「**スタート**」ボタンをクリックします。

3. 警告メッセージが表示された場合、内容を確認して「**OK**」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850895/94f8af90-e132-06a3-45be-52887e2491f2.png)


4. Rufusが処理を開始し、USBドライブの作成が完了するまで待ちます。

## 5. インストールの完了
1. 処理が完了すると、「**準備完了**」と表示されます。これでUSBドライブの作成が完了です.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850895/3c1b14b9-7d4f-d238-b15c-6f7602bab922.png)

2. Rufusを閉じて、USBドライブを取り出します。

以上で、Rufusのインストールが完了しました。必要に応じて、他の設定やオプションを確認してみてください。
Zero-Shot Anomaly Detection via Batch Normalization

# 1. 概要

異常検出 (AD:Anomaly Detection) は、産業界でよく用いられるタスクの一つである。しかし、従来の異常検出モデルは、データの分布が変化してしまうと性能が低下することが課題だった。特に、新しい分布の学習データがない場合の推論は大きな課題で、学習済みモデルで未知のケースを推論するゼロショット推論はよく求められるAIモデルである。
この研究では、ゼロショットで異常検出を行うACR(Adaptive Centered Representations)を提案している。提案手法では、一般的な異常検出モデル(deep SVDDなど)を複数の関連する訓練データ分布に適応させるように汎用性を持たせて学習させ、さらにバッチ正規化(Batch Normalization)を組み合わせることで、未知の異常検出タスクに対してもゼロショットでの推論を可能にしている。

---

# 2. 新規性
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/4709e3c0-1265-10ab-c7b5-d0c814a45561.png)

従来の生成AIを用いた異常検知はCLIP(Contrastive Language-Image Pretraining)をベースにしているモデルがあり、テキストと画像のモダリティのみ対応していた。また、プロンプトエンジニアリングなど、人のインプットによる精度のばらつきが大きかった。
提案手法では、表形式や画像など複数のモダリティやデータの種類に異常検知を適用できるようにしている。特に、画像のゼロショット推論による異常検知とセグメンテーションでは、従来手法を大きく超える精度を達成している。

---

# 3. 実現方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/5e52b375-2257-870e-7a8c-36a9dbd40c59.png)

まず、メタ学習として複数のクラスを学習する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/b209e796-a205-f914-5c97-896a8d14febd.png)

ここで、バッチ正規化(BN: Batch Normalization)に着目すると、ミニバッチの中のすべてのデータを自動的に平均してくれるため、バッチレベルで何のクラスなのかを予測するのに利用する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/1e3b0448-cc4a-4d74-ebf2-cceda4f5a84d.png)

メタ学習で学習されたクラスの分布から、分布の中心部分はバッチ正規化で取得できるため、未知のデータ種類に対しても同様に分布の中心を求め異常検知ができるように一般化している。

---

# 4. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/dc141324-870a-53ad-b7d5-1c3baf4772a7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/8a735fdd-3977-c845-d256-65d1dcad25cb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/68cbd3aa-24ef-5227-829c-e501396a8fd6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158742/21aee1d1-619a-c60d-f7e8-5ad9926d3e67.png)

表形式のデータにおける異常検知、画像のクラスに対する異常検知、画像のピクセルレベルでの異常検知のそれぞれのタスクで評価し、従来手法を超える精度を達成している。

---

Paper URL: <https://openreview.net/forum?id=d1wjMBYbP1>

last updates: May. 29 2024
YouTube の新しい AI ツールが、あなた専用のカスタムラジオ ステーションを作成します

本記事では https://lifehacker.com/ より翻訳します。

YouTubeのツールはAIを使用してカスタムラジオ局を作成しますこの実験的な機能は、現在一部のユーザーのみが利用できます。

休日の週末に鋭い目を持つRedditユーザーがこれに気づきました。会社がこの機能について公に言及していない一方で、Redditユーザーのkater_proがYouTube Musicアプリを閲覧中に発見しました。これは現在、限られたユーザーに対してテスト中である可能性があります。kater_proのスクリーンショットには「実験」タグが目立っており、この機能が一般に公開される時期は不明です。

kater_proによると、この機能を有効にすると「お好きな方法で音楽をリクエストしてください」という小さなテキストボックスが表示されます。kater_proは「クィアヒップホップビーツ」をリクエストしたところ、AIはJanelle Monáe、Lil Nas X、RuPaulの曲を含むラジオ局を生成しました。このラジオ局の説明には「心からのライムとフロー、ヒップホップアートにおけるクィアプライドの祝福」と書かれています。

インターフェイスの下部には小さなチャットボックスがあり、「アップビートポップアンセム」や「モスクワのロックシーン」など、ユーザーにさまざまな提案を促します。ユーザーは応答を入力するか、音声で応答することができます。

この機能は、Spotifyの「AI DJ」やSpotifyとApple Music向けのサードパーティアプリ「PlaylistAI」に似ています。ChatGPTからの単純なテキストの推奨よりも便利ですが、Discover Weeklyのような標準的な推奨機能よりも優れているかどうかはまだ分かりません。

kater_proが有料購読者かどうかは明確にしていないため、この機能がペイウォールの背後に隠されるかどうかは不明です（ただし、過去のAI YouTube機能ではそのようなケースがありました）。

AI動画生成・編集に興味があるなら[UniFab](https://ja.unifab.ai/)がおすすめです。 UniFab は、強力な AI ビデオ編集ツールを提供するだけでなく、動画の高画質化も簡単に実現することもできます。ビデオ制作が簡単かつ効率的になります。同時に、UniFab は複数の形式での出力もサポートしており、ビデオをさまざまなプラットフォームで完璧に表示できるようにします。
【Flutter】go_routerを使用した、画面に戻ってきた時の判定


## 問題
go_routerを使用していて、
遷移した先の画面から遷移元画面に戻ってきた時に処理を追加したかったが、
initStateなどで検知できなく、戻ってきたことを判定できなかった
## 対応
GoRouterDelegateにlistenerを追加して、監視を行うことで戻ってきたかを判定

```controller.dart

@override
  Widget build(BuildContext context, WidgetRef ref) {
    final router = ref.read(goRouterProvider); // GoRouterを取得

    // 監視対象が変わった時の処理を記載
    void listener() {
      // UI描画後
      WidgetsBinding.instance.addPostFrameCallback((_) {
        // Config(RouteMatchList)を取得
        final config = router.routerDelegate.currentConfiguration;
        
        // 変更後のfullPathを取得
        final fullPath = config.fullPath

        /* 
        fullpath以外もあるので要確認
        config.last.matchedLocation;
        config.pathParameters;
        config.uri.queryParameters;
        */

        // 取得した情報を元に処理を記載
        if(fullPath == 'URL') {
            // API呼び出しや再描画などを呼び出し
        }

      });
    }
    
    useEffect(() {
      // リスナーに追加
      router.routerDelegate.addListener(listener);
      return () {
        // disposeでリスナーから削除
        router.routerDelegate.removeListener(listener);
      };
    }, []);
  }

```

## 改善案
今回はGoRouterをprovider管理していたのでWidgetRefで取得してきたが、
MaterialApp.routerで監視設定してURLを取得しProviderで管理すれば
他画面での実装が必要な時にそのProviderをwatchするだけでよさそう
ssh-agentの設定

# はじめに
前回のrailsのDevcontainerでsshが組み込まれてないので、git関係が利用できていなかったので、それを対応した備忘録です
似た記事がたくさんあるので、詳細な説明は割愛します

# 確認
以前利用した環境は、こちらになります

https://qiita.com/youfuku/items/797cf0f745c7c7bbf0f6

コンテナ内でgitコマンドを実行するとこんな感じになります
```
$ git pull
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

# 確認
こちらを利用させていただきました（ありがとうございます）

https://zenn.dev/nayushi/articles/5d577c93e03a9b#keychain%E5%B0%8E%E5%85%A5%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%A7%A3%E6%B1%BA

wslを再起動
```
wsl --shutdown
```

ubuntuの関係パッケージを最新に更新
```
sudo apt-get update && sudo apt dist-upgrade -y && sudo apt autoremove -y
sudo apt install -y vim
```

ssh-agentの存在確認
```
ssh-add -l
```

ssh-agentが動いていない場合、以下のようになります
```
$ ssh-add -l
Could not open a connection to your authentication agent.
```

ssh-agentを起動
```
eval `ssh-agent`
```

確認
```
ssh-add -l
```
おそらく、初期の状態だと以下のように表示されます
```
$ ssh-add -l
The agent has no identities.
```

# keychainのインストールおよび設定
インストール
```
sudo apt-get install keychain
```

SSHの秘密鍵をロード
```
/usr/bin/keychain -q --nogui $HOME/.ssh/id_rsa
```

keychainを起動
```
source $HOME/.keychain/$(hostname)-sh
```

確認
```
ssh-add -l
```
すると登録されている鍵が以下のように表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/81e8e9c2-2046-9aeb-4c08-d01bd5d4ea3d.png)

# 起動で自動で動くように設定
毎回起動時に上記のコマンドをたたくのも面倒なので、「~/.bashrc」に登録しておきます
```
vim ~/.bashrc
```
```追記内容
# keychain
/usr/bin/keychain -q --nogui $HOME/.ssh/id_rsa # SSHの秘密鍵を読み込み
source $HOME/.keychain/$(hostname)-sh
```

# 確認
wslを再起動した後、railsのDevcontainerに接続。
その後、コンテナ内で「git pull」をすると以下のようになるはず！
```
$ git pull
Already up to date.
```

# さいごに
この操作は毎回設定する物ではありませんが、丁度wslを初期化する機会があったので、備忘録として記録しました。
正直、似た記事はたくさんありますので、詳細説明は他のサイトを見ることをお勧めします。
Pythonによるソケット通信

クライアント側、サーバ側の両方は基本的にsocketを設立して以下のシーケンスのように通信を行う。
```plantuml
@startuml

participant Client
participant Server

Server -> Server : listen
Client -> Server : connect
Server -> Server : accept
Server -> Client : send"Hello,World"

@enduml
```

## サーバ側
以下のように実装を書いた。
```python
import socket
import time

host = '127.0.0.1'
port = 65000
buff = 1024

# ソケットを設立する
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((host, port))

while True:
  # クライアントからの接続を待つ
  server.listen(1)
  print('Waiting for connection')
  # クライアントからの接続を受け取る
  client, addr = server.accept()
  print('Established connection')

  while True:
    try:
      # クライアントへメッセージを送信する
      client.send('Hello,World'.encode("utf-8"))
      time.sleep(1)
    except socket.error:
      client.close()
      break
```

## クライアント側
以下のように実装を書いた。
```python
import socket
import time

host = '127.0.0.1'
port = 65000
buff = 1024

# ソケットを設立し、サーバへ接続する関数
def make_connection(_host, _port):
  while True:
    try:
      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      sock.connect((_host, _port))
      print('connected')
      return sock
    except socket.error as e:
      print('failed to connect, try reconnect')
      time.sleep(1)

# サーバに接続する
socket = make_connection(host, port)

try:
    # サーバからメッセージを受け取る
    msg = socket.recv(buff)
    print('Client received: %s' % msg)
    time.sleep(1)
except socket.error as e:
    print('connection lost, try reconnect')
```


## 参考
https://docs.python.org/ja/3/howto/sockets.html
systemd timer

## はじめに
Amazon Linux には、デフォルトでは crontab がインストールされていません。crontab を利用したい場合は、下記などを参考に、cronie パッケージをインストールする必要があります。

https://github.com/amazonlinux/amazon-linux-2023/issues/300

一方で、既定で備わっている systemd の timer 機能を利用することで、crontab と同じようにジョブのスケジュール実行が可能です。

## スクリプト
実行するスクリプトを準備します。例えば、[こちら](https://qiita.com/ExtremeCarvFJ/items/35b8b58aa90514bbe29c)にあるような Python プログラムを起動するシェルを以下のように記述します。

```shell:python 起動
#! /usr/bin/python

python /usr/local/python/Redshift.py
```

この時重要なのが、プログラム内のパスを全て絶対パスで指定することです。私の場合、Python プログラムの中で一つでも相対パスの指定があると、systemd timer がファイルの位置を認識できず、エラーで処理が終了していました。

作成したスクリプトを /usr/local/sh/python.sh に保存します。

## サービス
スケジュール実行を登録する場合、.service ファイルと .timer ファイルを作成します。.service に実行するジョブの内容を、.timer にジョブの実行タイミングに関する内容を定義します。両ファイルが unit となって動作します。

まずは、/etc/systemd/system/python.service を作成します。

```text: python.service
[Unit]
Description=”Executing python program”

[Service]
Type=simple
User=testuser
ExecStart=/usr/bin/bash /usr/local/sh/python.sh

[Install]
WantedBy=multi-user.target
```
各項目での設定内容は以下の通りです。

|項目|説明|
|---|---|
|Description|サービスファイルの内容を任意で記述|
|Type|起動完了の判断。デフォルトは Simple で、実行時に起動完了の判定|
|User|実行ユーザーの指定|
|ExecStart|実行するスクリプト|
|WantedBy|enable 時にこの unit の .wants ディレクトリにシンボリックリンクを作成|

作成したサービスを有効化します。
```shell:サービス有効化
sudo systemctl enable python
```

## タイマー
/etc/systemd/system/python.timer を作成します。

```text:python.timer
[Unit]
Description=”Executing python program”

[Timer]
OnCalendar=*-*-* 01:30:00
Unit=python.service

[Install]
WantedBy=multi-user.target
```

|項目|説明|
|---|---|
|OnCalendar |実行のタイミング|
|Unit|先に作成した service ファイルを指定|

上記例では、毎日午前 1 時 30 分にジョブが実行されます。
様々なタイミングで実行が可能です。OnCalendar に定義する内容に関しては、下記サイトに記述例も含めとても分かりやすく説明されているので、是非参考にしてみてください。

https://takuya-1st.hatenablog.jp/entry/2020/04/24/032822

作成した timer を開始して有効化します。
```shell:enable timer 
sudo systemctl start python.timer
sudo systemctl enable python.timer
```

なお、.service ファイルと .timer ファイルは、いずれも /etc/systemd/system/ ディレクトリ直下に配置する必要があるようです。サブディレクトリを作成して、その配下に unit ファイルをまとめたいとも考えたのですが、どうやらできない様子です。

https://unix.stackexchange.com/questions/773523/can-i-group-a-set-of-related-systemd-service-files-into-a-common-directory-under

## 登録状況の確認
下記コマンドを実行して、スケジューラーの登録状況を確認します。登録されているジョブが一覧で表示され、前回実行や次回実行のタイミングなどを確認することができます。
```shell:list-timers
systemctl list-timers
```

実行ログを確認する場合は、journalctl コマンドを使用します。記述内容に問題がある場合には、問題個所を確認することができます。
```shell:list-timers
sudo journalctl -u python
```

## タイマー停止・無効化
スケジュール実行が不要になった場合は、タイマーを停止し、無効化します。
```shell:python
sudo systemctl stop python.timer
sudo systemctl disable python.timer
```

## 最後に
systemd timer を使ってジョブを登録する場合、service と timer を別々に作成し、かつ必要な unit 分これらを作成しなければいけないため、crontab と比較して、少々手間がかかるかなとも思いました。ただ、一度登録してしまえば、登録状況も一覧で確認出来ます。要は慣れですね。
Yellowfin が参照するデータを最新化するためには、夜間バッチなどで情報を更新する必要があります。Linux でジョブをスケジュール実行する時には、是非 systemd timer の利用をご検討ください。

では皆様、良いデータ分析を!

## 参考情報

https://qiita.com/aosho235/items/7656d5568af8f48b2dc1

https://takuya-1st.hatenablog.jp/entry/2020/04/24/032822

https://documentation.suse.com/sle-micro/6.0/html/Micro-systemd-working-with-timers/index.html
JavaScriptでWebサイト作業自動化

## JavaScriptでWebサイトの作業を自動化
Webサイトで行う作業を自動化したかったので、JavaScript（以下、js）で簡単に作ってみました。
備忘録がてら、基本的なことを記録してます。js経験者やプログラミングできる人は比較的楽で簡単に使えるかと思います。
本作業はNode.jsを使用します。
また、当方はwindows11環境になります。

## Node.jsのインストール
以下より、Node.jsのインストーラをダウンロードし、インストールをしてください。
https://nodejs.org/en/download/prebuilt-installer

## プロジェクトフォルダを作成
ソースを格納するフォルダを任意の場所に用意します。例では「AutoJS」というフォルダ名にします。
コマンドで行う場合は、mkdirで作成できます。

## nodeからpuppeteerをインストールする
コマンドプロンプトで先程作成したプロジェクトフォルダ（以下、pjフォルダ）にカレントディレクトリを移動して、以下を入力します。

**npm install puppeteer**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804239/ded8f395-b892-bfc7-44b3-5e8dd0077fb3.png)

インストールが完了しましたら、pjフォルダ内にいくつかフォルダとファイルが作成されます。
コマンドプロンプトはjsファイル作成後、実行する際に使用するのでそのまま開いててください。

## jsファイルを作成する
pjフォルダ直下に、拡張子jsのファイルを作成します。例では「testProject.js」というファイル名で作成します。
コマンドで行う場合は、以下で作成できます。
```dosbatch
type nul > testProject.js
```

## jsファイルを編集
とりあえずソースです。先程作成したjsファイルをテキストエディタで開いてコピペしてください。

```javascript:testProject.js
const puppeteer = require('puppeteer');

(async () => {
    // puppeteer・Chromium起動
    const browser = await puppeteer.launch({
        headless:false // この行をコメントアウトすることでサイトウィンドウを非表示にします。
    });

    const page = await browser.newPage();
    // サイトに接続・ページが完全に読み込まれるまで待機
    await page.goto('https://google.com/', { waitUntil: 'networkidle2' });

    // ページ内でjsを実行
    await page.evaluate(() => {
        // 検索テキストボックス要素をIDで取得
        const searchBox = document.getElementById('APjFqb');
        // 検索窓に値入力
        searchBox.value = 'Qiita';

        // フォーム要素をCSSセレクタで取得
        const form = document.querySelector('form[action="/search"][method="GET"][role="search"]');
        // 送信
        form.submit();
    });

    // 3秒後にブラウザを閉じる
    setTimeout(function() {
        browser.close();
    }, 3000);
    
})();
```

内容としては、Googleサイトに訪問し、検索窓に「Qiita」と入力して検索するという流れです。
詳細は割愛しますが、応用してお好みで作成するのであれば、サイトアドレスと動作部分（ページ内でjsを実行）を変えれば良いかと思います。
例のソースでは、**headless:false**でブラウザウィンドウを表示してますが、テスト時以外は不要だと思いますので、必要に応じてコメントアウトや削除してください。
併せて、**setTimeout**で3秒後にブラウザを閉じるようにしてますが、動きを理解するためにあえて設けているものになるのでこちらも削除して問題ありません。

## 作成したjsファイルをNodeで実行する
jsファイルを保存しましたら、先程のコマンドプロンプトの画面で以下のコマンドを入力して実行します。

```dosbatch
node testProject.js
```

## おわりに
無事動作しましたでしょうか。
実際に何か自動化したいと思った際はもっと実行処理が他に必要があるかと思いますが、まずは入門として簡単に紹介させていただきました。
お使いの環境によってはプロキシ認証が必要であったりなど、読者様でもあらゆるパターンが想定されるかと思いますが、ぜひ探求してみてください。
date-fnsをCDN経由で使う方法(とちょっとだけkintoneの日付型について)

# date-fns
date-fnsは日付変換を行うJavaScriptライブラリです。
ぼくはkintoneのカスタマイズでよく使っています。

https://www.npmjs.com/package/date-fns

https://date-fns.org/


いつもの方法は、NPM経由でインストールして、モジュールでimportするのですが、お仕事でどうしてもトランスパイル禁止されてしまって、CDNから使うことになりました。

# やりかた
公式のドキュメントによるとJSDelivrにて提供されているようです。

```html
<script src="https://cdn.jsdelivr.net/npm/date-fns@3.6.0/cdn.min.js"></script>
<script>
  dateFns.addDays(new Date(2014, 1, 11), 10);
  //=> Tue Feb 21 2014 00:00:00
</script>
```
3.6.0の部分はバージョンを入れればよろしい。

dateFnsがグローバルプロパティに登録されるようです。


# date-fns@kintone
せっかくなので、kintoneでの利用法を書いておきます。
```javascript
//てきとうな日付文字列 から Date
dateFns.parse('2024年11月11日','yyyy年MM月dd日', new Date())
//=> "2024-11-10T15:00:00.000Z"

//Date から DATETIME型@kintone
new Date().toISOString()
//ライブラリなしでできる。

//DATETIME型@kintone から Date
new Date(record.日時.value)
//ライブラリなしでできる。

//Date から TIME型@kintone
dateFns.format(new Date(), 'HH:mm')
//kintoneは秒がない。HHに注意（hhにすると12時間表記)

//Date から DATE型@kitnone
dateFns.format(new Date(), 'yyyy-MM-dd')
//MMに注意。mmにすると分のことになる。

```

# CDNによる利用の注意点
date-fnsはDateを取り扱うためか、他のフレームワークと一緒に使う場合は、CDNの読み込み順序を先にしないとエラーになります。

ぼくの場合はすでに導入されていたjQueryと一緒に使った場合でエラーを起こしていました。

importで導入する分には起こらないので、CDN特有の問題だと思います。


# ほかのライブラリと比較して
luxonやmomentといったライブラリがありますよね。ぼくはdate-fnsを利用することが多いです。

luxonはDateを拡張した型を使ってしまうし、momentは終了したプロジェクトですので、ぼくが選択する場合はdateFnsになります。

ただ、dayjsと比較すると、CDNを利用する場合はdayjsのほうが軽量ですので軍配が上がるかもしれません。ただし、dayjsはタイムゾーンの概念がないので注意が必要で...とまあ、いろいろ考えることが多いです。

date-fnsは個別で関数をimportしたときの軽量さがうりのライブラリだと思っているので、CDNでまるごと入れる是非は問われそうです。

他にも楽しいライブラリがあるかもしれません。あったら教えてください！

この記事の内容は以上です。ありがとうございます。

---

https://www.pulsar-works.jp/

kintoneのプラグイン開発や研修などを行っています。
お仕事のお話はこちらまで。
リモナビ：プライベートネットワークの「データベース」「サーバーシステム」への接続

リモナビは SaaS でリモート接続のインフラを実現し、どこからでも、どこへでも接続すします。　これによって以下のことができます。

- **🔹異なる閉域網のセキュアな Peer to Peer 接続**
    - 閉域網から、リモナビSaaS（Publicクラウド配備）へ接続が必要になります
    - <INS>エンタープライズ版ではお客様の要望に応えて、リモナビSaaS を閉域網間からアクセスできる網内に個別配備することにも対応します。（この場合は細かな調整が必要です）</INS>
- **🔹リモナビSaaSのエンタープライズ版では利用者別のACL設定が可能です**
    - 利用者ごとの詳細な接続先の絞り込みが可能になります。
    - 接続設定を OFF できるため、接続負荷状態を容易に構成できます。
- **🔹全ての通信の接続ログを保存しています**
    - いつ、だれが、どこ（Client IPaddr）から接続して、切断したのかが全てアクセスログに記憶され、システムでは自動削除しません。

## ローカル環境への通信の基本項目
- 接続元、接続先のネットワーク上に Sender, Receiver をインストールします。
    - Windowsアプリか Docker で提供
- リモナビSaaS を介して Sener, Receiver 間に仮想TCPコネクションが構築されます。
    - アクセストークンによる認証
    - インターネット間通信は全て暗号化
    - 送信側アクセストークンのアカウントのACL適用
    - Receiver 側のFW設定は不要
- リモナビを介した全ての通信ログを保存


以下に、具体的な利用シーンや接続イメージを説明します。

## ローカル環境の「データベース」へのアクセス

<img width="1240px" src="https://remonavi.com/img/remonavi_conn_db.png">

Sender, Receiver 間に仮想TCPコネクションを確立し、宛先をSenderにして通信します。
1. Sender, Receiver はそれぞれのネットワーク上にインストール
    1. アクセストークン、リモナビSaaS情報を設定してリモナビSaaSと接続します。
    1. リモナビSaaSと接続できたら、ACLで許可された「SecureGateway設定」一覧を参照することができるようになります。
1. リモナビSaaS で 「SecureGateway設定（宛先）を登録」
1. Receiver側で、当該SecureGateway設定を「利用」設定
1. Sender側で、当該SecureGateway設定を「利用」設定
    1. Sender側の受付IPポート番号を指定

## ローカル環境の「サーバシステム」へのアクセス
クラサバ・システムにおける接続も、前項「データベース」へのアクセスと同じです。

以下は、ローカル環境のWEBシステムへの接続イメージを示します。

<img width="1240px" src="https://remonavi.com/img/remonavi_conn_web.png">

リモナビSaaS, Receiver間は「仮想TCPコネクション」ですが、前段はリバースプロキシによって実現されます。

:::note warn
 リバースプロキシでは以下のURL変換をします。
 html, javascript, css ファイル等で、以下の変換ができないケースがある場合、当該URLへのアクセスが異常になります。
 　　　http://**{private-host}**/<INS>{path}</INS>
　　　　　　↓
　　　https://**{remonavi-saas-host}/securegw/{gw-id}**/<INS>{path}</INS>
:::
1ファイルでファイラーになる tinyfilemanager.php

## 1ファイルでファイラーになる

https://github.com/prasathmani/tinyfilemanager

## ダウンロード

```sh
wget https://raw.githubusercontent.com/prasathmani/tinyfilemanager/refs/heads/master/tinyfilemanager.php
```


## 設定

* tinyfilemanager.php を直接書き換える。

### ユーザー認証をスキップする場合

```diff
- $use_auth = true;
+ $use_auth = false;
```

### 読み取り専用にする

```diff
- $global_readonly = false;
+ $global_readonly = true;
```

### タイムゾーン

```diff
- $default_timezone = 'Etc/UTC'; // UTC
+ $default_timezone = 'Asia/Tokyo'; // JST
```

### ファイルまでの絶対パスの修正

```diff
- $root_path = $_SERVER['DOCUMENT_ROOT'];
+ $root_path = '/srv/share/';
```


### WEBブラウザからの相対パスの修正

```diff
- $root_url = '';
+ $root_url = '/share';
```


### 日付表示の修正

```diff
- $datetime_format = 'm/d/Y g:i A';
+ $datetime_format = 'Y/m/d h:i';
```


## ファイルが表示されない場合

phpのモジュールが不足していて`ctype_digit`が使用できない場合、ファイル一覧が表示されない。
その場合はis_numericに書き換えることで動作する。

```diff
 // Path display mode when viewing file information
 // 'full' => show full path
@@ -2720,9 +2722,9 @@
         $cmd = $iswin ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg");
         @exec($cmd, $output);

-        if (!empty($output) && ctype_digit($size = trim(implode("\n", $output)))) {
+        if (!empty($output) && is_numeric($size = trim(implode("\n", $output)))) {
             return $size;
         }
     }

     // Attempt Windows COM interface for Windows systems
@@ -2730,9 +2732,9 @@
         try {
             $fsobj = new COM('Scripting.FileSystemObject');
             $f = $fsobj->GetFile(realpath($file));
-            if (ctype_digit($size = $f->Size)) {
+            if (is_numeric($size = $f->Size)) {
                 return $size;
             }
         } catch (Exception $e) {
             // COM failed, fallback to filesize
         }
```
3年目に突入したばかりのエンジニアがGoogle Cloud Next Tokyo 2024行ってきた

先日8/1(木)に、パシフィコ横浜ノースで開かれたGoogle Cloud Next Tokyo 2024に参加してきました！
オフラインでこういった大規模なエンジニア関連イベントに参加したのは初めてなので内容と感想を書き留めておこうと思います。

## 概要
Google Cloud Next Tokyo 2024
パシフィコ横浜ノースにて8/1(木)、8/2(金)の2日間開催
詳細：https://cloudonair.withgoogle.com/events/next-tokyo-24

内容としては基調講演や協賛企業などによる講演（セッション）と、ブース展示の大きく2つです。

私自身はインフラ周りを中心に複数の講演に参加しました。またブース展示も見て、クイズなどにも参加しました！
会場は人が多く賑わっていて、オフのイベントだからこそ感じられるライブ感も感じられました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991958/5568d116-6bc6-ec1a-2204-e821c9de68a0.png)
ブースの様子

## 講演の内容
受講した講演の内容を簡単にまとめます。
Google Cloudからアーカイブ動画も公開される予定です。
https://cloudonair.withgoogle.com/events/next-tokyo-24

### 基調講演
Google Cloud平手代表をはじめ、GoogleのエンジニアやGoogle Cloud利用企業の登壇者から、AI(Gemini)活用について事例を紹介いただきました。
AIを単に業務効率向上だけでなく、ユーザーに価値を届けるために実際のプロダクトに組み入れてる事例が多かったです。
フリマアプリで商品紹介文をAIが入力してくれる、などの事例がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991958/6ae1a28f-aa22-c2da-67e1-54f21e09a51e.png)
基調講演の様子：サテライトでの視聴でした。人とても多かったです。


### Sansan x Splunk: Cloud Run環境のオブザーバビリティを高める方法
SansanおよびSplunkのエンジニアからゆるい感じでSplunk導入→オブザーバビリティ向上の実例を話していただきました。
改めてですが全体把握においてレイテンシとエラー通知が重要であること、Splunkを導入したことでエラー発生の原因究明が適切に、かつスピーディになったという話などがありました。

### Security Command Center と BigQuery を利用したセキュリティ ガバナンス事例の紹介
リクルート社内では、社内プロジェクト向けにインフラ基盤を提供しているが、そこでの統合的なセキュリティモニタリングの事例を紹介いただきました。
①セキュリティリスクを横断的に可視化したい、②リスクのある設定を速やかに修正したい、③可視化した後の運用できる仕組みを作りたい、といった目的からGoogle Cloud Security Command Centerを利用し始めたという話でした。

### Google Cloud モニタリング ベスト プラクティス
ユビーの社内において、GMP(Google Cloud Managed Service for Prometheus)を用いてモニタリングをしているという話でした。
Prometheus(オープンソース監視ツール)は高機能なものの導入ハードルが高く、GoogleがサポートしているGMPを利用するのがベストプラクティスだそうです。
Grafana(Prometheusで利用できるダッシュボード)やPromQL(Prometheusで用いるクエリ言語)も紹介いただきました。

### Google Cloud のインフラストラクチャ構成のベスト プラクティスを一挙に紹介
Google Cloudを用いてマルチクラウドやオンプレ+クラウド、マルチリージョンなどの大規模システムを構築する際のベストプラクティスを表題通り一挙に紹介いただきました。
NCC(Network Connectivity Center)が便利という話や、Cloud Armorが機械学習を用いてDDoS対策をしているという話が印象的でした。


## ブースの内容
様々な企業や、Google Cloudの各サービスがブース展開していました。
実際に社内で使用しているプロダクトや、知らないプロダクトもあり面白かったです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991958/d1569048-4702-b82b-238f-c8a91c58113c.png)
BigQueryのブースの様子：レースの結果をセンサーを用いてリアルタイムにBigTableに格納する。そのデータを元に、Geminiがどういうことをしたいのかをユーザーに問いかけながら、BigQueryのクエリ文を作成してくれる。


## 感想
全体感としては、初めて参加するオフの大規模イベントだったので、過去参加してきたオンラインイベントと比較して、生な感じ、ライブな感じが良かったです。また来年も参加します。
講演の対象は比較的大規模なプロダクトが中心で、今自分が触っているシステムに直接そのまま活かせる事例が多かったわけではないですが、そういった事例を知れたことを今後に活かせたらなと感じました。
ブースイベントでクイズがあり、Cloud Runのアクスタを貰えたので家宝にしようと思います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991958/33fe4a43-b1b7-20df-d466-599697bb66f4.png)
Cloud Run アクスタ
Super SSH picoCTF writeup for beginner

<h3>記事説明</h3>
CTF初めて一カ月の主がPicoCTFのEasyをbeginnerむけに書いている記事です。CTFのwriteupではCTF常識が前提になっている記事が多く無知すぎてよくわからなかったので書くことにしました。至らぬところ等あると思いますのでご指摘いただけると嬉しいです。
#picoCTFbeginner


<h3>事前知識</h3>
<h4>ssh</h4>
遠隔でコンピューターにログインするためのプロトコル。


<h4>ssh使い方</h4>
参考

https://qiita.com/Aichi_Lover/items/6d2b04a851ec7e435edf

<h3>flag獲得方法</h3>

```cmd
$ ssh -p 52178  ctf-player@titan.picoctf.net
The authenticity of host '[titan.picoctf.net]:52178 ([3.139.174.234]:52178)' can't be established.
ED25519 key fingerprint is SHA256:4S9EbTSSRZm32I+cdM5TyzthpQryv5kudRP9PIKT7XQ.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:1: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[titan.picoctf.net]:52178' (ED25519) to the list of known hosts.
ctf-player@titan.picoctf.net's password: 
Welcome ctf-player, here's your flag: picoCTF{s3cur3_c0nn3ct10n_8969f7d3}
Connection to titan.picoctf.net closed.

```
SNS侍を使いこなすための完全ガイド

## 1. はじめに

[SNS侍](https://maruwa-web.jp/products/instagram-followers-japanese)は、企業や個人がソーシャルメディア上でのプレゼンスを向上させるための包括的な支援ツールです。ソーシャルメディアの重要性がますます高まる現代において、フォロワーの増加やエンゲージメントの向上は成功の鍵となります。SNS侍は、このニーズを満たすための様々なサービスを提供し、ユーザーが競争の激しいオンライン市場で成功を収めるための強力なサポートを行います。

## 2. SNS侍のサービス概要

SNS侍は、主要なSNSプラットフォームに対応した多様なサービスを提供しています。これにより、ユーザーは自分のニーズに合わせて最適なプランを選択し、効果的なSNSプロモーションを実現することができます。

提供されるサービスの種類

フォロワー増加サービス
いいね、リツイート、再生回数の増加サービス
エンゲージメント向上サービス
対応SNSプラットフォーム

Instagram
Twitter
TikTok
YouTube
## 3. SNS侍の利用メリット

SNS侍を利用することで、以下のようなメリットがあります。

効果的なフォロワー増加
SNS侍のフォロワー増加サービスは、各プラットフォームごとに最適化されており、迅速に効果を実感できます。特に、日本人フォロワーの追加サービスは信頼性が高く、多くのユーザーに支持されています。

エンゲージメントの向上
いいねやリツイート、再生回数の増加は、エンゲージメントの重要な指標です。SNS侍は、これらの数値を効果的に増加させるサービスを提供し、ユーザーの投稿がより多くの人々に届くように支援します。

ブランド認知度の拡大
SNS侍を利用することで、ブランドの認知度を迅速に拡大することができます。フォロワーやいいねの数が増えることで、信頼性が高まり、ブランドイメージの向上に繋がります。

## 4. 初回限定クーポンの利用方法

SNS侍では、新規ユーザー向けに初回限定クーポンを提供しています。これにより、サービスをお得に試すことができ、効果を実感しやすくなります。

クーポンの取得手順

公式LINEを追加する。
クーポンコードを自動取得。
決済画面でクーポンコードを入力して適用。
クーポン利用による具体的なメリット
初回限定クーポンを利用することで、最大80%OFFの割引が適用されます。これにより、リーズナブルにサービスを試すことができ、SNSプロモーションの効果を実感できます。

## 5. サービスの使い方

SNS侍の利用は非常に簡単です。以下の手順でサービスを開始することができます。

登録方法と初期設定

公式サイトでアカウントを作成。
必要な情報を入力し、希望するSNSサービスを選択。
決済を完了してサービス開始。
各種プロモーションサービスの利用方法
各プラットフォームごとに提供されるサービスを選択し、設定を完了することで、フォロワー増加やエンゲージメント向上を図ることができます。

## 6. 公式LINEの便利機能

SNS侍の公式LINEには、ユーザーが簡単に情報を確認し、サービスを利用するための便利なリッチメニューが用意されています。これにより、効率的にサービスを管理することができます。

リッチメニューの活用

サービス概要: 利用方法やクーポンの利用方法を確認。
納期: 各サービスの納期を確認。
よくある質問: よく寄せられる質問とその回答を確認。
購入後のお客様: 購入後の追加状況や注文情報の変更を確認。
購入後のサポートと情報管理
公式LINEを利用することで、カスタマーサポートに迅速にアクセスでき、問題が発生した場合でも迅速に対応してもらえます。

## 7. 実際のユーザー事例

多くのユーザーがSNS侍の効果に満足しており、成功事例が多数報告されています。

成功事例の紹介
「短期間で多くのフォロワーを獲得できた」「いいねが増えたことでブランドの認知度が上がった」など、具体的な成功事例が多数あります。

ユーザーレビューの抜粋
ユーザーからのポジティブなフィードバックが多く、サービスの質と効果に満足している声が多数寄せられています。

## 8. 納期と反映時間の管理

SNS侍は、各サービスの納期についても詳細な情報を提供しています。これにより、ユーザーはサービスの効果が現れるまでの時間を把握しやすくなっています。

各サービスの標準納期

Instagram: 日本人フォロワー追加は20分から6時間以内
Twitter: 日本人フォロワー追加は8時間から48時間以内
TikTok: フォロワー追加は1時間から24時間以内
YouTube: 登録者追加は1時間から24時間以内
迅速な対応の実例
注文後、迅速にサービスが反映されるため、ユーザーは効果をすぐに実感できます。

## 9. まとめと今後の展望

SNS侍の総合評価
SNS侍は、各SNSプラットフォームに対応し、迅速かつ効果的なフォロワー増加サービスを提供しています。初回限定クーポンを利用することで、リーズナブルにサービスを試すことができる点も魅力です。

将来の展望とさらなる期待
今後もサービスの向上と新しい機能の追加が期待されており、ますます多くのユーザーに利用されることでしょう。SNSの効果的な活用を目指す方にとって、SNS侍は非常に頼りになるパートナーとなるでしょう。
RSpecでインスタンスの無効な状態を検知するためにvalid?メソッドが必要な理由

# 通らなかったテスト
RSpec でテストを学び始めたが、

```ruby
  it "nicknameが存在しなければ無効な状態であること" do
    user = User.new(nickname: nil)
    user.valid?
    expect(user.errors[:nickname]).to include("can't be blank")
  end
```

このコードで、なぜ

```ruby
user.valid?
```

の部分が必要になるのかわからなかった。ただ単に expect()メソッドに引数を渡してあげればいいのでは？と思い user.valid?を省略したらテストが通らなかったのでその理由を調査。

# valid?メソッド

そもそも valid?メソッドは Rails ガイドによると

> Rails は、Active Record オブジェクトを保存する直前にバリデーションを実行します。バリデーションで何らかのエラーが発生すると、オブジェクトを保存しません。
> valid?メソッドを使って、バリデーションを手動でトリガすることもできます。valid?を実行するとバリデーションがトリガされ、オブジェクトにエラーがない場合は true を返し、エラーの場合は false を返します。

手動でバリデーションを行い、true/false を返してくれるものらしい。

> Active Record でバリデーションが行われた後で errors インスタンスメソッドを使うと、失敗したバリデーションにアクセスできます。このメソッドはエラーのコレクションを返します。 その名の通り、バリデーション実行後にコレクションが空である場合はオブジェクトは有効です。

逆にいうとバリデーションが行われた後でないと失敗したバリデーションにアクセスできないということか。

> ただし、new でインスタンス化されたオブジェクトは、それが厳密には無効であってもエラーは出力されないので、注意が必要です。これは、create や save メソッドなどによってオブジェクトが保存されるときのみ、バリデーションが自動的に実行されるためです。

new のインスタンス化ではエラーは出力されないと。だからエラーを出力するために手動で valid?メソッドを行う必要がある。

# errors[]

errors はどのようなメソッドなのか。これも Rails ガイドによると

> errors[:attribute]を使うと、特定のオブジェクトの属性が有効かどうかを確認できます。このメソッドは、:attribute のすべてのエラーの配列を返します。指定された属性でエラーが発生しなかった場合は、空の配列が返されます。

> このメソッドが役に立つのは、バリデーションを実行した後だけです。このメソッドはエラーのコレクションを調べるだけで、バリデーションそのものをトリガしないからです。

# まとめ

つまり、errors 自体はバリデーションをトリガーしないため、user.valid?を行わないとエラーが出力されない。そのため、バリデーション前に errors[:nickname]は空配列となってしまい、テストが通らない。
Time Machine picoCTF writeup for beginner

<h3>記事説明</h3>
CTF初めて一カ月の主がPicoCTFのEasyをbeginnerむけに書いている記事です。CTFのwriteupではCTF常識が前提になっている記事が多く無知すぎてよくわからなかったので書くことにしました。至らぬところ等あると思いますのでご指摘いただけると嬉しいです。
#picoCTFbeginner


<h3>事前知識</h3>
<h4>git</h4>
プロジェクトのソースコードの変更を追跡し、複数の開発者が同時に作業できるようにする分散バージョン管理システム。
各開発者が自身の完全なリポジトリのコピーを持っていて、その変更をオンライン上のリポジトリにpushしたり、他人が行った変更をpullしたりできる。

<h4>git log</h4>
直近のコミット(変更)履歴をみることができる。


<h3>事前準備</h3>
<h4>gitのインストール方法</h4>
OSによって違うため要確認

参考
https://kinsta.com/jp/knowledgebase/install-git/


<h3>解き方</h3>
Downloadしたファイルのディレクトリに行き、git logを打つ。
直近のコミット履歴がまとめられており、flagがある。

```cmd
:~/ダウンロード/challenge/drop-in$ git log
commit 705ff639b7846418603a3272ab54536e01e3dc43 (HEAD -> master)
Author: picoCTF <ops@picoctf.com>
Date:   Sat Mar 9 21:10:36 2024 +0000

    picoCTF{t1m3m@ch1n3_b476ca06}

```
【超初心者向け】HTMLの基本的なタグ名の元となる英単語のまとめ

# 概要
HTMLの基本的なタグ名がどういった英単語の意味なのかをまとめました。
使用方法についてはいろいろなサイトに既に記載があるので、割愛しています。

# 目次
アルファベット順に並べています。
- [\<a>](#a)
  - [herf](#herf)
- [\<b>](#b)
- [\<div>](#div)
- [\<em>](#em)
- [\<h>](#h)
- [\<hr>](#hr)
- [\<html>](#html)
- [\<i>](#i)
- [\<li>](#li)
- [\<ol>](#ol)
- [\<p>](#p)
- [\<tr>](#tr)
- [\<ul>](#ul)

## a
### 元となる英単語
anchor
#### 意味
イカリを下す、固定する

### 属性
#### herf
Hypertext Referenceの略。
セットの「a href」で、「アンカーエイチレフ」と読む。

## \<b>
### 元となる英単語
bold
#### 意味
太字

## \<div>
### 元となる英単語
division
#### 意味
分割

## \<em>
### 元となる英単語
emphasis (エンファシス)
#### 意味
協調、注目

## \<h>
### 元となる英単語
heading
#### 意味
見出し

## \<hr>
### 元となる英単語
horizontal rule
#### 意味
水平方向の罫線

## \<html>
### 元となる英単語
Hyper Text Markup Language

## \<i>
### 元となる英単語
Italic
#### 意味
斜体文字

## li
### 元となる英単語
List Item
#### 意味
リスト項目

## ol
### 元となる英単語
ordered list
#### 意味
順序のあるリスト

## \<p>
### 元となる英単語
Paragraph
#### 意味
段落、節

## \<tr>
### 元となる英単語
table row
#### 意味
表の行

## ul
### 元となる英単語
unordered list (アンオーダードリスト)
#### 意味
順序がないリスト

### 備考
\<ul>～\</ul>、\<ol>～\</ol>の間で使用できる

## \<hr>
### 元となる英単語
horizontal rule
#### 意味
水平方向の罫線
AWS CLIを使ったプロファイルの管理方法


### AWSプロファイルとは？
AWSプロファイルは、AWS CLIで使う設定情報をまとめたものです。例えば、異なるAWSアカウントやプロジェクトごとに設定を切り替えることができます。

### プロファイルの構造
プロファイルは通常、以下のような構造で設定ファイル（`~/.aws/credentials` と `~/.aws/config`）に保存されます。

`~/.aws/credentials`ファイル:
```
[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY

[my-profile]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
```

`~/.aws/config`ファイル:
```
[default]
region = ap-northeast-1
output = json

[profile my-profile]
region = ap-northeast-1
output = text
```

### 現在の設定を確認する

```sh
aws configure list
```

このコマンドを実行すると、現在のプロファイル、リージョン、出力形式、およびその他の設定が表示されます。

### すべてのプロファイルを一覧表示する

```sh
aws configure list-profiles
```

### プロファイルを変更する
特定のコマンドで別のプロファイルを使用するには、`--profile`フラグを使います。

```sh
aws s3 ls --profile my-profile
```

### セッションのデフォルトプロファイルを設定する
AWS_PROFILE環境変数を設定します。

LinuxやmacOSの場合:
```sh
export AWS_PROFILE=my-profile
```

Windowsのコマンドプロンプトの場合:
```sh
set AWS_PROFILE=my-profile
```

Windows PowerShellの場合:
```sh
$env:AWS_PROFILE="my-profile"
```

### AWS_PROFILE環境変数を設定していない場合
もしAWS_PROFILE環境変数を設定していない場合は、AWS CLIはデフォルトプロファイル（`default`）を使用します。つまり、`~/.aws/credentials`ファイルや`~/.aws/config`ファイルに記載されている`[default]`セクションの設定が使用されます。

### 永続的にプロファイルを切り替える
設定ファイル（`~/.aws/config`）を編集します。このファイルにデフォルトプロファイルを指定する行を追加します。

```ini
[default]
region = ap-northeast-1
output = json
```

もしくは、特定のプロファイルをデフォルトにしたい場合は、以下のように設定します。

```ini
[default]
include_profile = my-profile
```

### プロファイルを設定する
新しいプロファイルを設定または既存のプロファイルを更新するには、次のコマンドを実行します。

```sh
aws configure --profile my-profile
```

このコマンドを実行すると、以下の情報を入力するよう求められます。
- AWSアクセスキーID
- AWSシークレットアクセスキー
- デフォルトリージョン名
- デフォルト出力形式
【XAI】DeepLIFT: ニューラルネットワークの解釈可能性を高める手法

※ このページは「Learning Important Features Through Propagating Activation Differences」の要約と周辺知識の解説になります。

## このページでわかること
DeepLIFT は、ニューラルネットワークの出力予測を各入力特徴量への貢献度として分解し、解釈可能性を向上させる手法。
参照活性化との差分に基づいて貢献度を計算し、勾配がゼロの場合でも情報を伝播させることができます。

## 対象読者
1. **機械学習研究者および開発者**：ニューラルネットワークの解釈可能性向上に関心があり、特にモデルの出力予測を詳細に分析したい人
2. **データサイエンティスト**：実際のアプリケーションにおいてモデルの予測を解釈可能にすることで、より信頼性の高い意思決定を支援したいと考える人
3. **ゲノミクスや画像認識などの専門分野の研究者**：特定の分野でニューラルネットワークを使用しており、DeepLIFTのような手法を活用して重要な特徴を特定し、解釈可能なモデルを構築したいと考える人


## 従来手法の問題点
SHAP は XAI (Explainable AI; 説明可能な AI) を実現するための一手法です。
ご存じの通り、AI は内部がブラックボックスになっていることで以下のような様々な問題点があります。

- 複雑な機械学習モデル（例：アンサンブルモデルやディープラーニングモデル）は高い予測精度を持つ一方で、その予測結果の解釈が非常に困難である
- そのため、開発したモデルの分析も難しく、また開発したモデルの予測に対するユーザーからの信頼を得ることが難しい

これらを踏まえると、XAI であることが非常に望ましいのですが、XAI を実現するのにも壁があります。
というのも、XAI を実現する手法は SHAP 以外にもいくつかありますが、実はそれらの手法にも欠点があります。

1. **既存手法の限界**：従来の勾配ベースや摂動ベースの方法では、勾配がゼロになる場合や非連続な勾配だと正確な重要度の予測が困難
2. **計算効率**：多くの既存手法は計算コストが高く、特に大規模なネットワークやデータセットに対して効率的に適用するのが難しい

## DeepLIFT とは？
DeepLIFT（Deep Learning Important FeaTures）は、ニューラルネットワークの出力予測を各入力特徴量への貢献度として分解する手法。
各ニューロンの活性化を「参照活性化」と比較し、その差に基づいて貢献度を計算します。

なお、参照活性化とは、特定の入力（通常は「参照入力」と呼ばれる）に対するニューラルネットワークのニューロンの出力値のことです。参照入力は、モデルが通常の入力と比較する基準となるデフォルトの入力状態であり、この参照入力に対する各ニューロンの出力を「参照活性化」と呼びます。

この方法により、ネットワークの出力に対する各入力の重要性を明確にし、モデルの解釈可能性を向上させます。

### メリット
1. **解釈可能性の向上**：DeepLIFTは各入力特徴量がどの程度出力に寄与しているかを明示するため、モデルの予測を理解しやすくなる
2. **勾配がゼロでも情報を伝播**：勾配ベースの手法では情報が失われる場合でも、DeepLIFTは参照活性化との差分に基づくため、勾配がゼロの時でも正確な貢献度を計算できる
3. **計算効率**：DeepLIFTは1回のバックワードパスで貢献度を効率的に計算することができ、他の摂動ベースの手法に比べて計算コストが低い

### デメリット

1. **参照入力の選択が難しい**：
   - 適切な参照入力を選ぶことが難しい場合がある
       - 参照入力の選択はドメイン知識に依存することが多く、不適切な参照を選ぶと結果が信頼できないものになる
       - 例えば、画像データの場合、全てのピクセルがゼロの画像を参照とすることが一般的ですが、他のデータセットや問題設定では適切な参照入力を見つけるのが難しいことがある

2. **多層ネットワークでの計算コスト**：
   - DeepLIFT は1回のバックワードパスで貢献度を計算するため、従来の勾配ベースの方法よりも計算効率が良い
   - が、非常に深いネットワークや大規模データセットに対しては依然として計算コストが高くなる可能性がある

4. **線形性の仮定**：
   - DeepLIFT は各ニューロンの出力がその入力に対して局所的に線形であることを仮定していますが、この仮定が必ずしもすべてのネットワーク構造やデータセットで適用できるわけではない
   - 非線形な振る舞いが強いネットワークでは、この仮定が結果に影響を与えることがある


### 手順
DeepLIFT を用いて XAI（Explainable AI）を実現するための大まかな方法は以下のようになります。

### 1. モデルの準備

まず、解釈を行いたいニューラルネットワークモデルを用意します。

### 2. 参照入力の選定

次に、DeepLIFT を適用するための参照入力を選定します。この参照入力は、ネットワークの出力を比較する基準となる入力データです。参照入力として何を選ぶかは問題のドメインに依存します。

例えば、代表的なドメインで利用される参照入力の例を以下のようなものです。

- **画像データ**: 全てゼロの画像（黒い画像）
- **テキストデータ**: 空のテキストや平均的な単語の埋め込み
- **遺伝子データ**: 背景周波数に基づくシーケンス

### 3. 参照活性化の計算

参照入力をネットワークに入力し、各層のニューロンの出力（参照活性化）を計算します。
このステップで、参照入力に対する各ニューロンのベースラインとなる活性化値が得られます。

### 4. 差分の計算

実際の入力データに対しても同様に各層のニューロンの出力を計算し、それを参照活性化と比較して差分を求めます。
この差分が、各入力特徴量がどの程度ネットワークの出力に影響を与えているかを示します。

### 5. 貢献度の割り当て

DeepLIFT のアルゴリズムを使用して、各入力特徴量への貢献度を計算します。
具体的には、各ニューロンの差分を逆伝播させることで、入力特徴量に対する貢献度スコアを求めます。

- **リニアルール**: 全ての線形変換（Dense層やConvolution層など）に対して適用されるルール
- **リスケールルール**: 非線形変換（ReLU、tanh、sigmoidなど）に対して適用されるルール
- **リビールキャンセルルール**: 特定の状況（正と負の貢献を区別する必要がある場合）に適用されるルール

### 6. 結果の解釈と可視化

5 によって得られた貢献度スコアを使用して、各入力特徴量がネットワークの出力にどのように影響を与えているかを解釈できるようになります。
これらのスコアを可視化するのもおすすめです。


## まとめ
以上が DeepLIFT の要約でした。
SHAP とは異なるアプローチで DeepLIFT は XAI を実現しています。
どちらの方法にしても制約が存在するので、どちらが上位互換というより使い分けが重要ですね。

おわり。
wslを初期化


# はじめに

Cドライブの容量が少ないなーと思った際、調べたらwsl(ubuntu)が容量をバカ食いしてたため、wslを初期化した際の備忘録となります

# 調べてみる
自分はubuntuをインストールしているため、ubuntuで検索し、アプリの設定ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/8326bf76-5953-cef0-a436-c1a8fb3dcabc.png)

表示された画面のこの辺を覗くと、取られてる容量がおおよそが見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/da681d6b-ee39-64a3-bd81-079ec19c6af9.png)


:::note warn
上の写真は初期値の状態です！
:::

# ubuntuのアンインストール

wsl上で利用しているディストリビューションを調べます

```
wsl -l -v
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/13866cb5-387c-1770-07a4-ce648e75c507.png)

上記の「調べてみる」で開いた画面から、ubuntuをアンインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/f7adb577-4ec8-7166-5674-4f6538d41464.png)


ディストリビューションからも削除
```
wsl --unregister Ubuntu
```

確認すると消えているはずです
```
wsl -l -v
```

問題なければ、念のために再起動しておきましょう

# 再インストール
wslを最新(プレリリース版)に更新します
```
wsl --update --pre-release
```

いつの間にか色々な機能がリリースされてたりするので、この機に最新にしておきます
下記URLで、追加された設定なども説明がありますので、ご参考ください

https://zenn.dev/dozo/articles/dd574ffa43d3f7

:::note warn
時間がかかりますので、気長にお待ちください
:::

ここからは定番のコマンドになります

ubuntuインストール
```
wsl --install -d Ubuntu
```

ubuntuをデフォルトのディストリビューションに設定
```
wsl -s ubuntu
```
もしバージョンが１の場合、下記コマンドで２にバージョンアップ
```
wsl --set-version ubuntu 2
```

ここまで終わったら、念のための再起動

作業としては以上となります

# さいごに
職場PCで調べたところ、優に２００Gを超えており衝撃でした。
皆さんもCドライブの容量が心もとなく感じた際には、一度調査してみてください。
SNSフォロワー増加の救世主『SNS侍』の魅力を徹底解説！

SNSのフォロワー数やエンゲージメントは、現代のマーケティングにおいて成功の鍵を握る重要な指標です。「[SNS侍](https://maruwa-web.jp/)」は、これらの指標を大幅に向上させるためのサービスとして、多くの企業や個人に支持されています。本記事では、「SNS侍」の詳細や利便性、実際の利用者の声を紹介します。

## SNS侍の概要
「SNS侍」は、Instagram、Twitter、TikTok、YouTube、LINEなどの主要なSNSプラットフォーム向けに、フォロワーやいいね、再生回数などを販売するサービスを提供しています。このサービスの特徴は、リアルアカウントからのフォローを提供し、スパムの心配がない点です。これにより、フォロワー減少率が非常に低く、長期的なエンゲージメントの向上が期待できます。

## SNS侍の利用方法
まず、「SNS侍」の公式LINEに登録することで、初回限定クーポン（最大80%OFF）が自動的に発行されます。このクーポンを利用することで、お得にサービスを開始することができます。

次に、利用したいSNSプラットフォームとサービスを選択します。例えば、Instagramのフォロワー増加やTwitterのリツイート増加、YouTubeの再生回数増加など、目的に応じたサービスを選ぶことができます。

最後に、決済画面でクーポンコードを入力し、サービスの反映を待つだけです。納期は最短で20分から反映され、迅速に結果を得ることができます。

## サービスの詳細
「SNS侍」では、各SNSプラットフォーム向けに多様なサービスを提供しています。以下に、代表的なサービスを紹介します。

Instagram向けサービス：フォロワー、いいね、ブックマーク、リール再生回数など
Twitter (X)向けサービス：フォロワー、いいね、リツイート、インプレッションなど
TikTok向けサービス：フォロワー、いいね、再生回数など
YouTube向けサービス：登録者、高評価、再生回数など
公式LINE向けサービス：友だち追加
これらのサービスを組み合わせることで、総合的なSNSプロモーションを実現し、短期間で効果を上げることが可能です。

参考：[SNS侍の詐欺や違法性は？複数サイトの購入経験からメリット・デメリットをレビュー](https://startlife.jp/sns-samurai-review/)

## 利用者の声と成功事例
「SNS侍」を利用したユーザーからは、多くのポジティブな声が寄せられています。例えば、「短期間でフォロワーが急増し、売上が向上した」「サポートが迅速で信頼できた」などの成功事例が報告されています。

また、具体的な事例として、ある企業が「SNS侍」を利用した結果、わずか数週間でInstagramのフォロワーが数千人増加し、その影響で新商品の売上が大幅に伸びたという報告もあります。このように、「SNS侍」は多くのユーザーにとって有益なツールであることが証明されています。

## SNS侍の効果的な利用方法
「SNS侍」を最大限に活用するためには、効果的なプロモーション計画を立てることが重要です。例えば、新商品やキャンペーンの開始時にフォロワーやいいねを増やすことで、初動のインパクトを高めることができます。また、定期的にサービスを利用することで、継続的なエンゲージメントの維持・向上が可能です。

さらに、各SNSプラットフォームの特性を理解し、適切なタイミングでサービスを利用することで、より効果的なプロモーションを実現できます。例えば、Instagramでは投稿後すぐにいいねやコメントを増やすことが効果的ですが、YouTubeでは動画公開後の再生回数や高評価を増やすことが重要です。

## まとめ
「SNS侍」は、短期間でSNSプロモーションの効果を最大化するための最適なツールです。初回限定クーポンや迅速なサポートが魅力的で、多くのユーザーから支持されています。フォロワーやエンゲージメントの購入を通じて、ブランドの認知度や売上を向上させることができます。競合他社に負けないSNSプロモーションを実現するために、ぜひ「SNS侍」をご利用ください。

参考リンク
公式サイト：[SNS侍](https://maruwa-web.jp/)
納期に関する詳細：納期（反映時間）について
クーポン利用方法：SNS侍のクーポン利用方法について
公式LINEの便利機能：公式LINEの便利機能の使い方
＃21　『フォルダ』を検索してコピーするバッチを作ってみました

## はじめに
前回は、指定したフォルダ内を検索し検索ワードとファイル名が部分一致するファイルをコピーするバッチを作成しましたが、今回はフォルダ用のバッチを作成しました。
前回から変更した点もございますので、ぜひ併せてご覧ください。

↓ 前回の記事はこちら ↓
 [『ファイル』を検索してコピーするバッチを作ってみました](https://qiita.com/nxted_sapporo/items/719fe58c3397f400acea) 

## 今回のバッチについて
### やりたいこと
今回作成したバッチファイルでは以下のことを行います。

・指定したフォルダの配下から検索ワードと合致するフォルダを探し出す
・探し出したフォルダを中身ごとコピーし指定した別フォルダに貼り付ける

### 前回からの変更点
①フォルダとファイルを見分けられるよう、パスの最後に『\』まで含んで記述しています。

②『setlocal』～『endlocal』をつけ足すことで、
『set』をグローバル変数ではなく、ローカル変数に設定しています。

詳細は『コマンドの説明』にて記述します。

### バッチの中身
バッチファイルの中身は以下の通りです。

```batchfile
@echo off

echo 検索ワードが含まれるフォルダを指定ディレクトリへコピーします
pause

setlocal
rem 検索ワード(SearchStrの部分)をセット
set str=SearchStr

rem コピー元パスをセット
set src=C:\ParentDirA\ChildDirA\

rem コピー先パスをセット
set dest=C:\ParentDirB\ChildDirB\
endlocal

echo フォルダをコピーします

rem コピー元ディレクトリへ移動
cd %src%
rem 検索ワードと部分一致するフォルダを探してリスト化する
dir /b /ad *%str%* > %src%list.txt

rem リストのフォルダをコピー先にコピーする
for /f %%a in (%src%list.txt) do (
  xcopy /e "%src%%%a¥" "%dest%%%a¥"
)

rem 一時ファイルを削除
del %src%list.txt

echo 終了します
pause

```

### コマンドの説明
前回の記事で解説したコマンドについては省略しています。

```plaintext
『setlocal』～『endlocal』
この間で『set』した変数はローカル変数として扱われ、『endlocal』の後には参照できなくなります。
グローバル変数の場合、バッチ実行後にもコマンドプロンプトに定義が残ってしまうため、変数名が同じ場合他のバッチからも呼び出されてしまうことがあります。
```

```plaintext
xcopy コピー元フォルダ コピー先フォルダ
フォルダ（ディレクトリ）ごとコピーする
```

```plaintext
xcopy /e
空のディレクトリも含めコピーする
```

```plaintext
『"%src%%%a¥"』
『%src%』『%%a』『\』と最後に『\』をつけることでパスがフォルダ名であることを示しています。

『xcopy』を実行すると、
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

 C:\Users\tarou\Desktop\hoge は受け側のファイル名ですか、
またはディレクトリ名ですか
(F= ファイル、D= ディレクトリ)?

＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

と聞かれますが、『\』をつけることで省略できます。
```
#### dirコマンドについて
```plaintext
dir のみ、オプションをつけない場合以下のような結果が出力されます。
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は XXXX-XXXX です

 C:\Users\tarou\Desktop\piyo のディレクトリ

2023/07/19  22:37                 0 piyo.txt
2023/07/19  22:30    <DIR>          piyoo
2023/07/19  22:37                 0 piyoo.txt
2023/07/23  17:53    <DIR>          piyooo
               3 個のファイル                   0 バイト
               2 個のディレクトリ  XXX,XXX,XXX,XXX バイトの空き領域
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
```

```plaintext
dir /b
フォルダ・ディレクトリ名のみを出力し、その他の情報は出力しません。
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

piyo.txt
piyoo
piyoo.txt
piyooo
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
```

```plaintext
dir /ad
ファイル名は出力せず、フォルダ名とその他の情報を出力します。
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は XXXX-XXXX です

 C:\Users\tarou\Desktop\piyo のディレクトリ

2023/07/19  22:30    <DIR>          piyoo
2023/07/23  17:53    <DIR>          piyooo
               0 個のファイル                   0 バイト
               2 個のディレクトリ  XXX,XXX,XXX,XXX バイトの空き領域
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
```

```plaintext
dir /b /ad
フォルダ名のみ出力されます。
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

piyoo
piyooo
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
```

## 最後に
コピーの対象がファイルかフォルダかでバッチの書き方が異なること、同じ処理でもいろいろな書き方があることがわかりました。
初歩的な内容でしたが参考にしていただけたら幸いです。
ご覧いただき、ありがとうございました。

出典：
https://www.tohoho-web.com/ex/bat.html
https://jj-blues.com/cms/quick_search/wanttodo/
Microsoft Graph API を Graph Client Service を利用せずに GET PUT POST を HTTPで実行する（C#）

## 1. はじめに

本記事は、[こちら](https://qiita.com/Takuma_Kondo/items/855689abecc02e81e828)の記事の続きです。よろしければ先にご覧ください。

では早速、Microsoft Graph API の GET PUT POST をHttpClientで実行するメソッドを実装していきましょう。

## 2. 実装

HTTPメソッドにおける、 GET PUT POST についての詳細な説明は[こちら](https://learn.microsoft.com/ja-jp/graph/use-the-api?context=graph%2Fapi%2F1.0&view=graph-rest-1.0#http-methods)をご覧ください。

### 2.1. GET

```C#
private async Task<string> GetHttpContentWithToken(string endPoint, string token)
{
    try
    {
        //認証ヘッダーをトークンに追加
        var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, endPoint);
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

        var response = await m_HttpClient.SendAsync(request);
        var content = await response.Content.ReadAsStringAsync();

        return content;
    }
    catch (Exception ex)
    {
        return ex.ToString();
    }
}
```
endPointにはエンドポイントなるものが、tokenには、[前回の記事](https://qiita.com/Takuma_Kondo/items/855689abecc02e81e828)で取得した認証トークンが入ります。  

エンドポイントの例を以下に記します。
```
$@"https://graph.microsoft.com/v1.0/me/drive"
```
これは自身のファイル情報を取得するものになります。  
エンドポイントを指定することで、他にも様々な情報の取得が可能になります。
取得できる情報を知りたい方は、[MSの公式ドキュメント](https://learn.microsoft.com/ja-jp/graph/api/overview?view=graph-rest-1.0&preserve-view=true)を参照してください。

### 2.2. PUT

今回は、ファイルのアップロードに使用しました。
従ってfilePthには、アップロードするファイルのパスを設定しています。

```C#
private async Task<string> PutHttpContentWithToken(string endPoint, string token, string filePath)
{
    try
    {
        //認証ヘッダーをトークンに追加
        var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Put, endPoint);
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

        byte[] binaryData = FileToByteArray(filePath);
        ByteArrayContent binArrayContent = new ByteArrayContent(binaryData);
        request.Content = binArrayContent;

        var response = await m_HttpClient.SendAsync(request);
        var content = await response.Content.ReadAsStringAsync();

        return content;
    }
    catch (Exception ex)
    {
        return ex.ToString();
    }
}
```

レクエストには、ファイルの中身をバイナリにして渡しています。

### 2.3. POST

```C#
private async Task<bool> PostHttpContentWithToken(string endPoint, string token)
{
    try
    {
        //認証ヘッダーをトークンに追加
        var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, endPoint);
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

        var response = await m_HttpClient.SendAsync(request);
        var isSuccess = response.IsSuccessStatusCode;

        return isSuccess;
    }
    catch
    {
        return false;
    }
}
```

## 3. 終わり

今回は、HTTPを使って、Microsoft Graph APIを実行しました。
このメソッドさえあれば、あとは任意のAPIをendpointに当てはめるだけで、さまざまなAPIの実行が可能になります。

引き続き、さまざな記事を投稿していこうかと思います。
Paidy Checkoutで送信する注文情報を、Stripeで簡単に取得・収集する方法


決済手段としてPaidyを追加する場合、顧客がPaidy以外で注文を行った履歴情報を送信する必要があります。この記事では、Stripeを利用している場合に、Paidyへ送信する情報を集める方法を紹介します。

## [関連記事] Stripeを使って「クレジットカード」と「Paidy」両方に対応した決済フォームを作る方法

Stripe Elementsを利用すると、Paidyとクレジットカード決済それぞれをサポートする決済フォームが簡単に作れます。実装方法や注文データの扱いについては、以下の記事をご覧ください。

https://qiita.com/hideokamoto/items/6d4653067bd4456cc6da

## Paidyでは「Paidy決済以外」での注文履歴情報が必要

Paidyでの決済を行うPaidy Checkoutを利用するには、与信のために顧客の情報をいくつか送信する必要があります。特徴的なのは、顧客の氏名や住所だけでなく、「Paidy以外での購入履歴」についても送信が必要なことです。Paidyのドキュメントを見ると、次の値が必須とされています。

- `order_count`
- `ltv`
- `last_order_amount`
- `last_order_at`

この４項目を送信するには、ショップにおける、Paidy以外を利用した際の注文回数・合計金額と、最後の注文情報が必要です。このほかにも直近3ヶ月の行動なども送信することができます。Paidyのドキュメントを確認して、オプションとされている値をどこまでサポートするかを検討しましょう。

https://paidy.com/docs/jp/paidycheckout.html#buyer_data_pay

## Stripe上での直近の注文内容を取得する方法

クレジットカード決済やApple Pay / Google Pay、そして銀行振込・コンビニ決済などをStripeで提供している場合、最後の注文情報はStripe APIから取得できます。

まず取得には、StripeのCustomer IDが必要です。これはログインユーザーのIDと紐づけたデータベースや、ユーザー情報テーブルのメタデータに保存するなどして、取得できるようにしておきましょう。このCustomer IDを利用して、Stripe上での決済履歴を取得します。

`last_order_amount`と`last_order_at`では、キャンセル・拒否・返金された取引を除外する必要があります。そのため、Search APIを利用して、「支払いが成功し、全額返金されていない支払い」を特定します。

```js
async function getLastStripeOrder(customerId) {
  const charges = await stripe.charges.search({
    query: `customer:"${customerId}" AND -refunded:"true" AND status:"succeeded"`,
    limit: 1,
  });
  // @TODO 必要な情報を取得・計算する
};
```

:::note warn
**マルチキャプチャ機能を利用する場合**
2024/08時点ではベータ機能ですが、複数回のキャプチャを実施できる機能が開発中です。

https://docs.stripe.com/payments/multicapture

この機能を利用した場合、1つの注文でChargeが複数作成されます。そのため、今回紹介している手法では注文の一部金額しか取得できなくなることがありますのでご注意ください。
:::

取得した結果から、最後の決済日と決済金額を取得しましょう。注文の一部を返品している場合など、部分的に返金を行なっていることがありますので、返金した金額を差し引く処理も追加しています。

```diff_javascript
async function getLastStripeOrder(customerId) {
  const charges = await stripe.charges.search({
    query: `customer:"${customerId}" AND -refunded:"true" AND status:"succeeded"`,
    limit: 1,
  });
+  if (!charges.data) {
+    return null;
+  }
+ const lastCharge = charges.data[0]
+ const lastOrderAt = new Date(lastCharge.created * 1000).toISOString();
+ const lastOrderAmount = lastCharge.amount_captured - lastCharge.amount_refunded;
+  return {
+    lastOrderAt,
+    lastOrderAmount,
+  };
};
```

## 注文回数とLTVは、集計用データベースを用意しよう

同様の方法で注文回数やLTVの計算もできます。ただし注文回数の多い顧客では、APIから取得するデータの量が多くなるため、サイトの表示や処理に時間がかかる可能性があります。そのため、Stripe Webhookを利用して、累計金額を計算する処理とデータベースを作ることをお勧めします。

この場合、決済に成功したことを通知する`charge.succeeded`イベントと返金が発生した場合に送信される`charge.refunded`イベントの２つは少なくとも受信する必要があります。


## Paidyの組み込み効率化にも、Stripeを活用しよう

今回の記事では、Paidy Checkoutで使用する決済履歴データをStripeから収集する方法を紹介しました。Stripe上のデータは、Search APIを使った検索やWebhookを利用したデータ連携で簡単に取得・収集できます。LTVや注文回数の計算をWebhook経由で実施することで、ユーザーの注文フローを遅延なく提供できるようにシステムを構築しましょう。