OmniAICreator/Qiita-1.07M huggingface dataset:
スクラム開発におけるPlatform Engineeringの重要性


## はじめに

スクラム開発を行う際に、クラウドベンダーの多様なサービスを活用することはもはや当たり前となっています。しかし、これらのサービスを効果的に利用するためには、Platform Engineeringの重要性を理解し、適切に実践することが不可欠です。本記事では、Platform Engineeringがなぜ重要なのか、そしてどのようにスクラム開発においてその価値を最大限に引き出すかについて解説します。

## Platform Engineeringとは？

Platform Engineeringとは、開発チームが効率的に作業を進めるための共通基盤を構築・運用することを指します。これには、インフラストラクチャの自動化、CI/CDパイプラインの整備、モニタリングとアラートの設定などが含まれます。これにより、開発者は本来の業務に集中でき、プロダクトの品質とスピードが向上します。

## なぜPlatform Engineeringが重要なのか？

### 1. 開発スピードの向上

Platform Engineeringを導入することで、開発環境のセットアップやデプロイメントが自動化され、手動作業が減少します。これにより、開発者はコードを書くことに集中でき、リリースサイクルが短縮されます。

### 2. 一貫性の確保

共通のプラットフォームを使用することで、環境の一貫性が保たれます。これにより、開発環境と本番環境の差異が減少し、バグの発生率が低下します。

### 3. コストの削減

自動化と効率化により、リソースの無駄遣いが減少します。例えば、インフラストラクチャのスケーリングが自動化されることで、必要なリソースだけを使用することができます。

### 4. セキュリティの向上

共通のプラットフォームを使用することで、セキュリティポリシーの一貫性が保たれます。これにより、セキュリティリスクが低減され、コンプライアンスも容易に達成できます。

## スクラム開発におけるPlatform Engineeringの実践

### 1. インフラストラクチャのコード化

TerraformやCloudFormationなどのツールを使用して、インフラストラクチャをコードとして管理します。これにより、環境の再現性が高まり、変更管理が容易になります。

### 2. CI/CDパイプラインの整備

JenkinsやGitLab CIなどのツールを使用して、CI/CDパイプラインを構築します。これにより、コードのビルド、テスト、デプロイが自動化され、リリースサイクルが短縮されます。

### 3. モニタリングとアラート

PrometheusやGrafanaなどのツールを使用して、システムのモニタリングとアラートを設定します。これにより、問題が発生した際に迅速に対応でき、システムの安定性が向上します。

### 4. セキュリティの自動化

セキュリティスキャンや脆弱性管理を自動化するツールを導入します。これにより、セキュリティリスクを早期に発見し、対策を講じることができます。

## まとめ

Platform Engineeringは、スクラム開発において非常に重要な役割を果たします。開発スピードの向上、一貫性の確保、コストの削減、セキュリティの向上など、多くのメリットがあります。これらを実現するためには、適切なツールとプロセスを導入し、継続的に改善していくことが必要です。皆さんもぜひ、Platform Engineeringを取り入れて、スクラム開発をさらに効率的に進めてみてください。
pytorch + GPUのコンテナ環境設定（マルチステージビルドを添えて）

## やりたかったこと
Dockerのマルチステージビルドを用いて、GPU付きマシンでpytorch学習環境を作ってみました。
下記ファイルを同ディレクトリに配置してビルドすれば通ります。

```env:.env
UID=
GID=
# bash idから取得
```

```yml:docker-compose.yml
version: '3.8'

services:
  app-name:
    build:
      context: .
      dockerfile: Dockerfile
      args:
      - USER=$USER
      - UID=$UID
      - GID=$GID
    env_file:
      - .env
    container_name: container
    runtime: nvidia
    shm_size: 64gb
    environment:
      - NVIDIA_VISIBLE_DEVICES=1
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
    volumes:
      - .:/workspace:cached
    tty: true
    restart: always
```

```Dockerfile:Dockerfile
# ベースイメージとして公式のCUDAイメージを使用
FROM nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04 as base
ENV DEBIAN_FRONTEND noninteractive

# 作業ディレクトリを設定
WORKDIR /workspace

# 必要なライブラリをインストール
RUN apt-get update && apt-get install -y --no-install-recommends \
    python3-pip \
    python3-dev \
    libgl1-mesa-glx \
    libnuma1 \
    && rm -rf /var/lib/apt/lists/*
    # libgl1-mesa-glx libnuma1 はCUDAのインストール時に必要、segfaultを防ぐために必要
FROM base as dev
ARG USER=user-name-goes-here
ARG UID=1000
ARG GID=$UID
ENV TZ=Asia/Tokyo

# Create the user
RUN groupadd --gid $GID $USER \
    && useradd --uid $UID --gid $GID -m $USER --shell /bin/bash \
    # Optional: Add sudo support
    && apt-get update \
    && apt-get install -y --no-install-recommends sudo procps gdb \
    && echo $USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USER \
    && chmod 0440 /etc/sudoers.d/$USER \
    && chown $UID:$GID -R /workspace

# Pythonパッケージをインストール
COPY requirements.txt /workspace/
RUN pip3 install --upgrade pip && \
    pip3 install -r /workspace/requirements.txt

# リポジトリの内容をコンテナ内にコピー
COPY . /workspace/

# Set the default user
USER $USER
```
```text:requirements.txt
numpy
opencv-python
matplotlib
seaborn
pandas
torch
torchvision
scikit-learn
````
Goのerrgroupで並行処理を実装する方法

Go言語で並行処理を実装する場合は、これまで`sync.WaitGroup`と同時実行数制御の`semaphore`を組み合わせて実装していました。しかし、`errgroup`を使うことで、より簡潔に実装できることを最近知ったので、実装方法を簡単にまとめます。

本記事でためした環境のGo version： 1.22.0

## errgroupの基本的な使い方
- `Go()`関数で並行処理を実行する
- `Wait()`関数で全ての並行処理が終了するのを待つ
- `SetLimit()`関数で同時実行数を制限

以下に例を記載します。

## 例

以下に基本的な例を示します。

```go
package main

import (
    "fmt"
    "sync"
    "golang.org/x/sync/errgroup"
)

func main() {
    var g errgroup.Group

    tasks := []func() error{
        func() error {
            // タスク1
            fmt.Println("Task 1")
            return nil
        },
        func() error {
            // タスク2
            fmt.Println("Task 2")
            return nil
        },
        func() error {
            // タスク3
            fmt.Println("Task 3")
            return nil
        },
    }

    for _, task := range tasks {
        g.Go(func() error {
            return task()
        })
    }

    if err := g.Wait(); err != nil {
        fmt.Printf("error: %v\n", err)
    }
    fmt.Println("success!!!")
}
```
```:Output
Task 3
Task 1
Task 2
success!!!
```

上記のコードでは、3つのタスクを並行して実行し、全てのタスクが完了するまで待ちつづけます。

## SetLimit()による同時実行の制御

CPUなどリソースへの負担を避けたいときは、`SetLimit()`を使用して同時実行数を制御することができます。

```go
package main

import (
    "fmt"
    "golang.org/x/sync/errgroup"
    "time"
)

func main() {
    var g errgroup.Group

    // 同時実行数を2に制限
    g.SetLimit(2)

    for i := range 5 {
        g.Go(func() error {
            fmt.Printf("Task %d started\n", i)
            time.Sleep(2 * time.Second)
            fmt.Printf("Task %d finished\n", i)
            return nil
        })
    }

    if err := g.Wait(); err != nil {
        fmt.Printf("error: %v\n", err)
    } 
    fmt.Println("success!!!")
}
```
```:Output
Task 1 started
Task 0 started
Task 1 finished
Task 2 started
Task 0 finished
Task 3 started
Task 2 finished
Task 4 started
Task 3 finished
Task 4 finished
success!!!
```

この例では、5つのタスクがある中で同時に実行されるのは最大2つまでとなります。
分かりにくいですがOutputをみてみると、最初にTask1,0がスタートして、Task1が終了時にTask2がスタートしています。
ちゃんと同時実行数が2に制御されていますね。

## for文で並列処理を行う際の注意点
go1.21以前では、forの各反復ではループ変数(iやv)が同じインスタンスを共有するため、for内のgoroutineに正しく変数を渡すことができません。
この問題についてはググるとたくさん出てくるので割愛します。


go1.22ではこの問題が解消されています。
内容は、以下リリースノートに詳しく記載されています。
https://tip.golang.org/doc/go1.22

もしgo1.21以前の場合は以下のように、loop変数を束縛する必要があります。

```go
for i := range 5 {
    i := i  // 新しい変数'i'でloop変数'i'を束縛
    g.Go(func() error {
        fmt.Printf("Task %d\n", i)
        return nil
    })
}
```

## 最後に
今回は、Goの`errgroup`パッケージでの並行処理の実装について紹介しました。

弊社HRBrainでは、Goでのバックエンド開発が行われており、エンジニアの仲間を募集しています。

弊社に興味がある方は、ぜひHPだけでも見に来てください。

https://www.hrbrain.co.jp/recruit
Rails7.1、ruby3.34を詰まらずインストールしたい人へ

rubyのインストール中にライブラリ不足によるコンパイルエラーが複数回発生し、解消したら次のエラー、それも解消したらまた次の・・・のように無駄に時間がかかったので、スムーズにインストールできるようにまとめてみました。

## 環境
WSL（Ubuntu 22.04.4 LTS）

## 手順

### 必要なライブラリをインストール
```console
sudo apt update -y
sudo apt upgrade -y
sudo apt install build-essential -y
sudo apt install -y libssl-dev libreadline-dev zlib1g-dev libyaml-dev libz-dev libffi-dev
```
### rbenvとrubyをインストール
```console
# rbenvをインストール
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL -l

# rubyをインストール
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv install 3.34
rbenv global 3.34
```
### railsをインストール
```console
# バージョン指定しなければ最新版に
gem install rails
# 動作確認
rails -v
```
## 参考
https://qiita.com/Gushi_maru/items/f3b5cc43e135e678085f
https://qiita.com/lionooil/items/a21fab7950517e48ed10
Amazonの適格請求書を一気に読み込んでCSVファイルにする

# Amazonの適格請求書（PDF)から一部を抜き出す方法
## 目的
Amazonの適格請求書（PDF）から、登録番号と合計金額を取り出してCSVファイルに変換したかったので、調べてpythonコードを作成しました。

## 前準備
pypdfが必要です。以下のコマンドでインストールします。

```
pip install pypdf
```

amazonの請求書は、`xxx_Amazon_invoice.pdf`という名前にしておきます。`xxx`は連番や商品名です。

## コード

コードは以下になります。`convert.py`などのファイル名で保存してください。

```python
import pypdf
import pandas as pd
from tqdm import tqdm
import glob

pdf_files = glob.glob("*Amazon_invoice.pdf")
F = []
T = []
P = []

for pdf_file in tqdm(pdf_files):
    reader = pypdf.PdfReader(pdf_file)
    F.append(pdf_file)
    T.append("")
    P.append("")
    for e in tqdm(reader.pages):
        txt = e.extract_text()
        for v in txt.split("\n"):
            if "登録番号" in v :
                v = v.split()[-1]
                T[-1] = v
            if "合計" in v :
                v = v.split()
                if len(v) > 3:
                    v = v[3].replace("合計", "") 
                    P[-1] = v[1:]


df = pd.DataFrame()
df["請求書ファイル名"]=F
df["登録番号"]=T
df["合計金額"]=P

df.to_csv("output.csv", index=False)
print(df)

```

## 実行
以下のように実行すると`output.csv`を作成します。
 
```
python3 convert.py
```

中身は、以下のようになります。

**output.csv**
請求書ファイル名,登録番号,合計金額
001_Amazon_invoice.pdf,Txxxxxxxxxxxxx,"29,800"
002_Amazon_invoice.pdf,Txxxxxxxxxxxxx,"5,292"
003_Amazon_invoice.pdf,Txxxxxxxxxxxxx,"2,090"

## 注意事項
アマゾンのinvoiceのフォーマットが変更された場合は修正が必要となります。以下の部分が、登録番号と合計を取り出している部分なので、ここを修正してください。

```python
        txt = e.extract_text()
        for v in txt.split("\n"):
            if "登録番号" in v :
                v = v.split()[-1]
                T[-1] = v
            if "合計" in v :
                v = v.split()
                if len(v) > 3:
                    v = v[3].replace("合計", "") 
                    P[-1] = v[1:]
```
パワーシェル検索

    $directory = "C:\MyDirectory"  # 検索対象のディレクトリを指定
    $pattern = '\b((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\b'  # IPv4アドレスの正規表現パターン
    $excludedExtensions = @(".dll", ".zip", ".jar")
    
    $filesWithIPs = @()
    
    Get-ChildItem -Path $directory -Recurse -File | ForEach-Object {
        if ($excludedExtensions -notcontains $_.Extension.ToLower()) {
            $matches = Select-String -Path $_.FullName -Pattern $pattern
            if ($matches) {
                $filesWithIPs += $_.FullName
            }
        }
    }
    
    # 重複を排除して表示
    $filesWithIPs | Sort-Object -Unique | ForEach-Object {
        $_
    }

んにゃ
@echo off
setlocal enabledelayedexpansion

rem ダイアログから置換対象文字列と置換後の文字列を入力
set /p old_string="置換対象の文字列を入力してください: "
set /p new_string="置換後の文字列を入力してください: "

rem バッチファイルが配置されているディレクトリを取得
set target_dir=%~dp0

rem 指定ディレクトリ内の全てのテキストファイルに対して処理を行う
for /r "%target_dir%" %%f in (*.txt) do (
    set "file=%%f"
    echo 処理中: !file!
    (for /f "delims=" %%i in ('type "%%f" ^| findstr /n "^"') do (
        set "line=%%i"
        set "line=!line:%old_string%=%new_string%!"
        echo !line!
    )) > "%%f.tmp"
    move /y "%%f.tmp" "%%f"
)

echo 完了しました。
pause

\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

    
    \b(?:(?:2[0-5][0-5]|1?\d{1,2})\.){3}(?:2[0-5][0-5]|1?\d{1,2})\b
LaravelでのCSRF除外設定について

# LaravelでのCSRF除外設定について

先日、PHPでLaravelを用いた勉強をしていた際、LINE MessagingAPIを導入した時にwebhookにアクセスが通らないという問題が発生しました。解決まで少し時間がかかったので、備忘録として記事を書いておきます。

## 問題の発生

LINE MessagingAPIを導入する際、POST通信を行うためにCSRFから除外する必要があります。通常、その除外するURLを設定するファイルは `app/Http/Middleware/VerifyCsrfToken.php` の中に記述します。しかし、このファイルが見当たりませんでした。プロジェクトファイルの作成時にミスったかと思い、手動で作成してみましたが、それでも問題は解決しませんでした。

## 解決策

シンプルにリサーチ不足でした。Laravel Ver.11では、デフォルトで `App\Http\Middleware\VerifyCsrfToken` がなくなるとのことです。そのため、`web.php` に直接記述する方法を取りました。以下の通りです。

```php
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;

Route::post('/webhook', [LineBotController::class, 'webhook'])
    ->withoutMiddleware(ValidateCsrfToken::class);
```
あれ？VerifyCsrfTokenじゃないじゃん！と思うかもしれませんが、これは一貫性のために名称が変更されたとのことです。
UUIDを使った一意識別子の生成方法

## はじめに

UUID（Universally Unique Identifier）は、128ビット長の一意識別子であり、データベースやネットワーク上での一意性を確保するために広く使われています。Pythonの標準ライブラリ`uuid`を使うと、簡単にUUIDを生成できます。

## UUIDの種類
UUIDにはいくつかのバージョンがあり、それぞれ異なる方法で識別子を生成します。以下は主なUUIDの種類です：

1. **UUID1**: タイムベースUUID
   - タイムスタンプとノード（通常はMACアドレス）に基づいて生成されます。
   - 時間順に生成されるため、タイムスタンプを元にした一意性が保証されます。

2. **UUID2**: DCEセキュリティUUID
   - ローカルドメイン、POSIX UID/GID、およびタイムスタンプに基づいて生成されます。
   - 一般的には使用されません。

3. **UUID3**: 名前ベースUUID（MD5）
   - 名前空間と名前のMD5ハッシュに基づいて生成されます。
   - 同じ名前空間と名前に対しては常に同じUUIDを生成します。
   - 名前空間には、`uuid.NAMESPACE_DNS`、`uuid.NAMESPACE_URL`、`uuid.NAMESPACE_OID`、`uuid.NAMESPACE_X500`などがあります。

4. **UUID4**: ランダムUUID
   - ランダムまたは擬似乱数に基づいて生成されます。
   - 非常に高い一意性が保証されますが、完全にランダムです。

5. **UUID5**: 名前ベースUUID（SHA-1）
   - 名前空間と名前のSHA-1ハッシュに基づいて生成されます。
   - UUID3と同様に、同じ名前空間と名前に対しては常に同じUUIDを生成します。

## UUIDの生成方法

```python
import uuid

# UUID1: タイムベース
print(f"UUID1: {uuid.uuid1()}")

# UUID3: 名前ベース（MD5）
print(f"UUID3: {uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')}")

# UUID4: ランダム
print(f"UUID4: {uuid.uuid4()}")

# UUID5: 名前ベース（SHA-1）
print(f"UUID5: {uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')}")
```

## UUIDの用途

- **データベース**: 一意のプライマリキーとして利用。
- **ソフトウェア**: モジュールやコンポーネントの識別子。
- **ネットワーク**: データパケットの識別子。
- **ファイルシステム**: ファイルの一意識別子。
Claude3.5の史上最強プロンプトはコレだ！（自分史上）

生成AIを使い始めて1年が過ぎ、手放せなくなっているのですが、「何に使うんだ？」と思っている人も多いでしょう。
もちろん、使い方はその人次第で無限の可能性があるのは周知の事実です。
では、自分が一番よく使う汎用性抜群だけど、自分しかしていないんじゃないか？というプロンプトを紹介します。

それがコレ！



## ギャル語だよー✡

私が一番使うのが、ギャル語にしてもらうこと。
もしくはChatGPTにギャルになってもらい、やり取りをする手法です！
これがとにかく汎用性抜群だと思っています。

## 例題
```claude3.5 Sonnet

以下のコードを解説してください。

import random

def guess_number():
# ランダムな数字を生成
secret_number = random.randint(1, 100)

print(“1から100までの数字を当ててください！”)

# ユーザーが当てるまでループ
while True:
try:
guess = int(input(“あなたの予想: “))
if guess < 1 or guess > 100:
print(“1から100までの数字を入力してください。”)
continue
if guess < secret_number:
print(“もっと大きい数字です！”)
elif guess > secret_number:
print(“もっと小さい数字です！”)
else:
print(“正解です！”)
break
except ValueError:
print(“有効な数字を入力してください。”)

# ゲームを実行
guess_number()
```
```Claude3.5の回答
はい、承知しました。このプログラムについて、一般的な解説を行います。
このPythonプログラムは、シンプルな数当てゲームを実装しています。以下にプログラムの主要な部分を説明します：

まず、randomモジュールをインポートしています。これは乱数生成に使用されます。
guess_number()という関数が定義されており、この中にゲームのロジックが含まれています。
random.randint(1, 100)を使用して、1から100までのランダムな整数を生成し、これを当てるべき数（secret_number）とします。
ゲームは無限ループ内で実行されます。ユーザーが正解するまで続きます。
ユーザーに数字の入力を求め、その入力を整数に変換します。
入力された数が1から100の範囲外の場合、エラーメッセージを表示して再入力を促します。
入力された数が秘密の数より小さければ「もっと大きい数字です！」、大きければ「もっと小さい数字です！」というヒントを表示します。
正解した場合、「正解です！」と表示してループを終了します。
数字以外の入力があった場合、ValueErrorをキャッチして適切なエラーメッセージを表示します。
最後に、guess_number()関数を呼び出してゲームを開始します。

このプログラムは、基本的なプログラミング概念（関数、ループ、条件分岐、例外処理）を使用しており、初心者向けの良い練習例となっています。
```

まぁ正しいけれど、スッと入ってこない人も多いのではないかと思います。
どうでしょうか？
これをギャル語でお願いしてみましょう。

## ギャル語で

```Claude3.5ギャル語回答

うおー！マジ卍なコードじゃん！💖🔥 ギャル語で解説しちゃうよ〜！超わかりやすくしてあげるからね！😘✨
まずさ、このコードってさ、超楽しい数字当てゲームなわけ！🎉🔢

import random って書いてあるじゃん？これマジ重要！ランダムな数字を出すのに使うんだよね〜。マジ運命の数字って感じ！🎲✨
guess_number() ってのがこのゲームの主役！ここでマジックが起こるわけ！😍🌟
secret_number = random.randint(1, 100) これがさ、1から100までの中からランダムで超秘密の数字を選んじゃうの！まじでシークレットな感じ！🤫💕
そっからループが始まんだけど、これがゲームの本体ってわけ！プレイヤーが正解するまでエンドレスに続くの！マジ粘り強いっしょ？💪😎
guess = int(input("あなたの予想: ")) ここでプレイヤーに数字を入力してもらうわけ。マジでドキドキするよね〜！💓
そっから入力した数字をチェックしていくの。小さすぎたら「もっと大きい！」って言うし、大きすぎたら「もっと小さい！」って教えてあげんの。超親切〜！😚👍
正解したら「正解です！」って祝福しちゃう！まじでハッピーエンドじゃん！🎊🎉
あと、変な入力とかしたらエラーメッセージ出すんだけど、これマジ優しい！初心者にも超配慮してんじゃん！😭💖

最後に guess_number() でゲームスタート！超盛り上がること間違いなしだよ〜！🥳🎮
これ、マジで楽しそうじゃない？
プログラミングって超クールだし、こんなの作れちゃうなんてマジ天才じゃん！🧠✨ 
みんなも挑戦してみて〜！💖🔥
```

## まじヤバくね？
超最高じゃん✨こっちまでテンションあがるーwww
では何故、分かりやすくなるのか？（自分だけかもしれないが、、、）

私はとても分かりやすく理解しやすいと思っているのですが、その要因は以下だと考えています：

+ カジュアル：ギャル語は感情表現が豊かで、絵文字も多用されます。これが、より親近感を与え、覚えやすくしていると思います。
+ リズム感：ギャル語特有の言い回しやテンポが、文章に独特のリズムを生み出しているように思います。それが読みやすさや記憶のしやすさにつながっていると思います。
+ 視覚的要素：絵文字の使用により、文字だけでなく視覚的にも情報が伝わるため、理解が促進されそうです！
+ 簡略化：複雑な概念を日常的な表現に置き換えることで、難しい内容も理解しやすくなる気がします！

## 絶対ギャル語じゃないといけない？

そんなことは全くなく、自分の場合は現状これが一番わかりやすいし、なんかテンションが上がるんですよね！
ギャルって結構前向きな印象があるんです。
「どうにかなるっしょ！」ってマインドは自分には無いもので、元気をもらえるわけです。
皆さんも是非1度やってみてくださいね！
マジ気分上がるから💓👍👍

他にもこの方が絶対わかりやすいとか、コレがいいとかあれば是非コメントにて教えて欲しいです！
学術情報ネットワーク(SINET6)からOCIへのFastConnect接続

## SINET6とは
学術情報ネットワーク(SINET※)は、日本全国の大学、研究機関等の学術情報基盤として、国立情報学研究所(NII)が構築、運用している情報通信ネットワークです。
※SINET: Science Information NETwork (サイネット)

SINETは、日本全国の大学、研究機関等の学術情報基盤として、全国約1,000の大学・研究機関等が加入し、300万人以上の研究者・学生等が利用しています。また、多くの海外研究ネットワークと相互接続しています。2022年4月に本格運用を開始するSINET6は、ネットワーク接続拠点を全国70カ所に拡充しました。ネットワーク接続速度400Gbpsを全国に整備し、モバイルSINETを5G対応に拡張することに加え、大学などが構築するローカル5Gへの対応、エッジ機能の配備、国際回線の帯域強化など、オープン・サイエンス実現のための研究データ基盤として本格展開します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/44b3dbae-37c2-e99d-81c3-96b2e6cba4b8.png)

## SINET6のクラウド接続サービス
SINETの「クラウド接続サービス」は、加入機関とクラウド提供事業者間のL2VPN接続を提供するものです。
クラウド接続においては、L2VPN方式のみが利用可能です。
「クラウド接続サービス」を利用すればOracle Cloud Infrastructure(OCI)を含め、[様々なサービス](https://www.sinet.ad.jp/service_provider/service_providers_list)との接続を実現することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/684586bf-7baf-b5b0-fa74-6ea7940b6785.png)

## SINET経由のOCI接続
「OCI」は、2019年からSINETに対応しており、「Oracle Cloud」の東京および大阪リージョンと接続しています。2019年の対応以来、理化学研究所、奈良先端科学技術大学院大学をはじめ、多くの大学・研究機関がSINET経由でOCIに接続しています。

理化学研究所が開発主体として推進しているスーパーコンピュータ「富岳」は、SINETを介して「OCI」と接続し、高度な計算資源の有効活用と研究成果創出を促進しています。SINET経由の「OCI」への高速、安全かつ低コストでの接続により、「富岳」を利用する大学や研究機関等は、「OCI」のセキュリティ、パフォーマンス、伸縮性に優れたコンピュートやストレージのリソースを「富岳」のネットワークから低コストで利用できます。

SINET経由の「OCI」への接続では、OCIの専用ネットワーク接続サービス[「Oracle Cloud Infrastructure FastConnect」](https://www.oracle.com/jp/cloud/networking/fastconnect/)（有償サービス）を利用します。「Oracle Cloud Infrastructure FastConnect」を利用することで、専用のプライベートな高帯域接続ができるだけでなく、上り/下りともに転送データ量に対する課金が無料となります。これにより、ペタバイト超となることもある膨大な研究データの転送コストを気にすることなく、「OCI」の高性能コンピュートやストレージ・リソースを予測可能なコストで利用できます。

## SINET-OCI接続時の構成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/b2e7020e-fcd5-5187-9aa0-cb4cde70fd2e.png)


## SINET-OCI接続のプロセス
SINETとOCI間接続のプロセスは以下の通りです。
複雑に見えるかもしれませんが、SINETは[FastConnectパートナー](https://www.oracle.com/jp/cloud/networking/fastconnect/partners/#apac-tokyo)の1種でありますので基本的な流れや設定方法は[FastConnectパートナー使用時](https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/fastconnectprovider.htm)と同様です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/8d9008af-d3b7-c177-6cd8-fd4244caaf89.png)

## 参考情報
・[SINET6](https://www.sinet.ad.jp/)
・[Oracle Cloud Infrastructureが、次期学術情報ネットワーク（SINET6）に対応](https://blogs.oracle.com/oracle4engineer/post/sinet6-oci)
・[Oracle Cloud Infrastructure ( OCI ) のSINET 接続について教えて下さい。](https://faq.oracle.co.jp/app/answers/detail/a_id/10149/~/oracle-cloud-infrastructure-%28-oci-%29-%E3%81%AEsinet-%E6%8E%A5%E7%B6%9A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E6%95%99%E3%81%88%E3%81%A6%E4%B8%8B%E3%81%95%E3%81%84%E3%80%82)
[Python]ジェネレータ

# ジェネレータ

ジェネレータ（generator）は、Pythonでイテレータ（iterator）を生成する関数です。通常の関数と異なる点は、関数が呼び出されるたびに `return` キーワードで値を返して終了する代わりに、`yield` キーワードを使用して値を返し、一時的に関数の状態を保持し、次に呼び出されたときに続きから実行できる点です。

ジェネレータ関数は呼び出されるとジェネレータオブジェクトを返し、このオブジェクトは `iterable` インターフェースを実装し、`next()` 関数を使用して値を順次取得することができます。ジェネレータはメモリを効率的に使用し、大容量のデータや無限シーケンスを扱うのに役立ちます。

### 例:

```python
def countdown(n):
    while n > 0:
        yield n
        n -= 1

# ジェネレータオブジェクトの作成
gen = countdown(5)

# 値を順次取得する
print(next(gen))  # 5
print(next(gen))  # 4
print(next(gen))  # 3
print(next(gen))  # 2
print(next(gen))  # 1
```

上記の例では、`countdown` 関数はジェネレータ関数であり、`yield` を使用して値を返し、関数の状態を保持します。`next()` 関数を呼び出して値を1つずつ取得できます。最後の値を取得すると `StopIteration` 例外が発生し、これ以上値がないことを通知します。

ジェネレータはイテレータを使用するすべての場面で使用でき、リストやタプルなどの他のコレクションタイプと同様に `for` ループを使用して処理することができます。

<br/>

# yield

`yield` キーワードは、主にジェネレータ（generator）関数内で使用される特別なキーワードです。このキーワードを使用すると、関数は呼び出されるたびに値を返し、その後も関数の実行状態を一時停止し、次に呼び出されたときにその続きから実行を再開することができます。

通常、関数が値を返すと、その時点で関数は終了し、次の呼び出し時には新たに実行されます。しかし、`yield` を使うと、関数は現在の実行状態を保持し、その状態で値を呼び出し元に返した後も、次の呼び出し時までその状態を覚えています。

簡単な例を使って `yield` の動作を説明します：

```python
def simple_generator():
    yield 1
    yield 2
    yield 3

# ジェネレータオブジェクトを作成
gen = simple_generator()

# 値を順に取得する
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
print(next(gen))  # StopIteration 例外が発生
```

上記の例では、`simple_generator` 関数がジェネレータ関数であり、各 `yield` 文がジェネレータオブジェクトが呼び出された時に値を返します。`next()` 関数を使って値を一つずつ取得し、すべての値を返した後に `StopIteration` 例外が発生して、これ以上の値がないことを示します。

`yield` は値を単に返すだけでなく、関数の実行状態を保持する点が重要です。そのため、ジェネレータ関数はイテラブル（iterable）オブジェクトを生成し、そのオブジェクトは `for` ループや他の反復処理で使用することができます。

<br/>

# next()

`next()` 関数は、Pythonでイテレータ（iterator）やジェネレータ（generator）を操作するための関数です。主に以下のような場面で使用されます。

1. **イテレータの値を取得する**:
   イテレータやジェネレータは、`next()` 関数を使って次の要素を順に取得できます。例えば、以下のように使用します。

   ```python
   my_iter = iter([1, 2, 3])
   print(next(my_iter))  # 1
   print(next(my_iter))  # 2
   print(next(my_iter))  # 3
   ```

   イテレータが最後の要素を返した後にさらに `next()` を呼び出すと、`StopIteration` エラーが発生します。

2. **ジェネレータの値を取得する**:
   ジェネレータ関数から生成されたジェネレータオブジェクトでも同様に使用できます。

   ```python
   def my_generator():
       yield 1
       yield 2
       yield 3

   gen = my_generator()
   print(next(gen))  # 1
   print(next(gen))  # 2
   print(next(gen))  # 3
   ```

   同様に、最後の要素を返した後に `next()` を呼び出すと `StopIteration` エラーが発生します。

3. **デフォルト値を指定する**:
   `next()` 関数の第二引数としてデフォルト値を指定することができます。これは、イテレータが最後に達したときに `StopIteration` エラーを発生させずに、代わりにデフォルト値を返すために使用されます。

   ```python
   my_iter = iter([1, 2])
   print(next(my_iter, 0))  # 1
   print(next(my_iter, 0))  # 2
   print(next(my_iter, 0))  # 0 (デフォルト値)
   ```

   上記の例では、イテレータが最後の要素を返した後に `next()` を呼び出すと、デフォルト値 `0` が返されます。

`next()` 関数は反復処理を行う際に非常に便利であり、特に動的なデータセットや無限のシーケンスを扱う際に役立ちます。
Oracleパートナーを使用したFastConnect接続

## Oracleパートナーを使用したFastConnect接続
OracleパートナーはOn-PremisesとFastConnect LocationのLogical Device間の経路を一貫して提供します。
またその接続は仮想回線単位で提供されるため、①納期が短い、②小さい帯域が選択可能、③コストが安価等といった特徴があります。

[Oracleパートナー](https://www.oracle.com/jp/cloud/networking/fastconnect/partners/)は2019年5月のOCI東京リージョン開設以来、徐々に数を増やしてきており、
現在はOCI東京リージョンで21サービス、OCI大阪リージョンで10サービスに対応しています。
国内の多くのプロバイダやデータセンター事業者に対応しているので既存On-Premises環境と専用線(閉域網)接続時に困ることはないでしょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/913c1b3e-b12a-43f1-988f-751f95566107.png)

## FastConnect Oracleパートナー一覧
OCI東京、大阪リージョンのFastConnect接続プロバイダー一覧
※最新情報は以下のURLをご確認
https://www.oracle.com/jp/cloud/networking/fastconnect/partners/#apac
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/48b2fa5c-48f0-b435-20ae-91c658762b7d.png)

## FastConnect OracleパートナーのOCI接続サービス
上で紹介しました通り、国内の多くのプロバイダがOracleパートナーとしてOCI接続サービスを提供しています。
その中からいくとかピックアップしてご紹介できればと思います。

①Flexible InterConnect(FIC) 【NTT Communications】
閉域網サービス「Arcstar Universal One」をはじめとするNTT Communicationsのネットワーク網を利用の
ユーザが各パブリッククラウドサービスに接続するためのサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/9129e3f7-91d9-b3d6-8735-2c83169d6deb.png)

FIC-Port(物理ポート)、FIC-Router(仮想ルータ)及びFIC-Connection(仮想回線)を利用して
閉域網とクラウド間を短い期間でかつ簡単に接続することが可能です。
※詳細は以下のURLをご確認
https://sdpf.ntt.com/services/docs/fic/service-descriptions/connection-oracle/connection-oracle.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/292d37eb-e1ab-f3cf-dc43-fc2e5d241da2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/8b250bcf-254c-d5d2-479b-d4ee07d9d08e.png)

②マルチクラウドゲートウェイ 【KDDI】
閉域網サービス「WVS2」を利用のユーザが各パブリッククラウドサービスに接続するためのサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/bccabc46-f6ca-27a6-cb26-75e28d6c2199.png)

1つのマルチクラウドゲートウェイ回線を使い、複数のパブリッククラウドに接続することができます
※詳細は以下のURLをご確認
https://news.kddi.com/kddi/business-topic/2023/10/7014.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/11fbe455-a0fc-87be-e7a3-f361ca9781aa.png)

③OnePort 【Softbank】
閉域網サービス「SmartVPN」を利用のユーザが各パブリッククラウドサービスに接続するためのサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/251722fa-08cd-fb09-f65d-a8d3e4b82158.png)

他社サービス同様に様々なパブリッククラウドに対応しているので、On-Premisesとパブリッククラウド間の接続だけでなく、マルチクラウド接続にも対応しています。
※詳細は以下のURLをご確認
https://www.softbank.jp/biz/services/network/cloud-connect/oneport/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/68f256ed-f7ee-2b34-e10c-08970dc4105b.png)

■まとめ
今回は国内大手3社のサービスをご紹介しました。
どちらのサービスもOn-Premisesとパブリッククラウド間を短期間で安価に接続でき、さらに最近種類になってきているマルチクラウド環境が簡単に構成できる点で類似しています。
少し前までは利用するパブリッククラウドに合わせてプロバイダを選択しないといけない時代もありましたが
今ではほとんどのプロバイダがいわゆる4大パブリッククラウドサービス(AWS、Azure、GCP、OCI)に標準で対応してきました。
既存のネットワーク環境のまま簡単にセキュアな接続が実現できるのでPoCなど、気軽にパブリッククラウドの
利用を始められるようになっているのではと思います。

今後もOracleパートナーの情報をアップデートしていきますので引き続き、宜しくお願い致します。
VMインスタンスの容量予約機能について

## VMインスタンスの容量タイプ
OCIのコンピュート・インスタンスの起動時に使用するホスト容量のタイプを選択できます。オンデマンド容量がデフォルトですが、かわりに、プリエンプティブル容量、容量予約または専用容量を使用できます。
各タイプの特徴は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/a128989d-c29b-fd4e-f680-ee2bd307e3bf.png)

## VMインスタンスのリソースの考え方
クラウドサービスの利点の1つに、必要な時にVMマシンを稼働させ利用した分だけ料金を支払うことができる点があると思います。On-Premisesではハードウェザを購入するか、リースするかの選択になり利用時間に関係なく導入からリプレイス(または返却)の間ずっと利用される前提のコストがかかってきますのでその意味ではクラウドはリソースを有効的に利用できますね。

一方でクラウド利用時に注意しなければいけないポイントの1つに基本的にクラウドサービスを提供するためのリソースは共有されるという点があります(ベアメタルサーバ等、リソース専有型のサービスは例外です)。

例えば構築済みのVMインスタンスを24H365D稼働せず、必要な時にだけ稼働させる運用をしている場合、
VMインスタンスが停止中の間、そのリソースはリリースされている状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/578057ee-5c5e-f716-d74b-086e0764775e.png)

パブリッククラウドサービスはきちんとしたリソース計画の下、管理されているので
通常時はリソース不足が原因でVMインスタンスを稼働できないといった不具合が発生する可能性は極めて低いですが、大きな災害等によりデータセンター全体が利用できなくなった場合は災害の影響を受けていないデータセンターの需要が急激に増えてリソース不足が発生する可能性があります。

システムの用途によっては人命に関わるものや、社会基盤を支えるものなど絶対に止められないものがあると思います。そういったシステムは災害が発生した際、以下に早く完全な状態で元の状態に戻すできるかがポイントになります。

## 容量予約機能を活用しよう
将来使用するために容量を予約し、いつでも必要に応じてコンピュート・インスタンスを作成するための容量を確保できます。予約済容量は、予約に対してインスタンスを起動するときに使用されます。
これらのインスタンスが終了すると、容量が予約に戻され、予約の未使用容量が増加します。未使用の予約済容量は、使用済の予約済容量とは異なる方法で計測されます。

容量予約機能を活用すれば有事の際に必要なリソースを確実に確保することができるので安心ですね。
また予約時(未使用時)は通常費用の85%課金になるので常時同じ環境を用意しなければいけないOn-Premisesと比較してコスト節約効果もあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411653/c8f3175c-592b-8ecd-11b2-57007e82593e.png)

## 参考情報
・[容量タイプ](https://docs.oracle.com/ja-jp/iaas/Content/Compute/Concepts/capacity-types.htm)
bacula 暗号化キーとリストア

# 初めに

baculaを利用したバックアップの暗号化に関して
bacula-fdの設定内容や検証内容について記載します。

## version
bacula(9.0系)

# 暗号化設定

以下公式より参照

[Data Encryption](https://bacula.org/9.6.x-manuals/en/main/Data_Encryption.html)

暗号化設定で必要なのは下３つの設定項目です。
鍵の生成方法は上記の公式にもコマンドが載っているので参考にしてください。

またpemファイルの生成に必要な証明書の有効期限には注意しましょう。
作成時にオプションで指定できます。

設定したらbacula-fdを再起動してください。

```
FileDaemon {
   Name = example-fd
   FDport = 9102                  # where we listen for the director
   WorkingDirectory = /var/bacula/working
   Pid Directory = /var/run
   Maximum Concurrent Jobs = 20
 
   PKI Signatures = Yes            # Enable Data Signing
   PKI Encryption = Yes            # Enable Data Encryption
   PKI Keypair = "/etc/bacula/fd-example.pem"    # Public and Private Keys
   PKI Master Key = "/etc/bacula/master.cert"    # ONLY the Public Key
}
```

# 暗号化キーの関係

暗号化を有効にした状態でbackupJobを実行した後、
Backupをリストア可能な鍵の条件は以下。

既存：backupJob実行前に作成した鍵
新規：backupJob実行後に作成した鍵

|master.cert|fd-example.pem|復号可能
--|--|--
|新規|新規|NO|
|新規|既存|OK|
|既存|新規|NO|
|既存|既存|OK|
|既存|新規(既存のmaster.keyからmaster.pemを作成)| OK|

ちなみに鍵を削除してもfdを再起動するまではrestoreできる。

クライアント(fd-exmaple.pem)の鍵を誤って紛失した場合であっても、
マスターキーからキーペアを作成しPKI Keypair に作成したファイルのパスを記載=> bacula-fd 再起動で復元可能となる。

また複数サーバの運用の場合、bacula-fdを各サーバにインストールして利用することになる。
暗号化したバックアップをリストアする際には当然一致する鍵がないfdを利用してリストアすることはできない。

# 終わりに（所感）

暗号化するだけでも鍵の管理など考えることが増えるので、
AWSなどのマネージドサービスを利用したほうが楽だな〜と改めて最近感じています。

jobの実行タイミングやVolumeの管理など全て自分で設定できるため自由ですが、
セキュリティ・バックアップなどの部分は特に検証が大事になってくると思いますので、その分面倒も増えますね。

以上
スコープについて

## はじめに
今回は学習中あらためて`scope`について調べてみたので、アウトプットの意味も込めて記事にしたいと思います。
どういうときに使用するものなのか、使用しないとどうなるのか等参考になれば幸いです。

## スコープとは
- スコープ（scope）は、モデルに対してよく使うクエリを簡潔に記述できる機能です
- スコープを使うことで、複雑なクエリを繰り返し記述することなく、簡単に再利用できるようになります
- つまり、コードの可読性と保守性を向上させるもの

### スコープを追加する場所
スコープは通常、モデルクラス内の他のスコープの定義と同じ場所に追加します。

### 語源は？
- 「scope」の語源はラテン語の「scopus」で、「目的・目標」という意味を持ちます
- 英語では、「scope」は元々「見る」「見通しを持つ」という意味で使われ、その後、特定の範囲や領域を意味するようになりました
- Railsにおいては、「scope」がデータベースクエリの範囲や視点を指す用語として使用されています。つまり、ある条件や視点で見たデータの集合を指定するという意味合いで使われています。

## スコープのメリット
- [ ] 再利用性
同じクエリロジックを複数箇所で再利用できるため、DRY（Don't Repeat Yourself）原則に従うことができます
- [ ] 可読性: クエリが短く明確になるため、コードの可読性が向上します
- [ ] 保守性: クエリの変更が必要な場合、一箇所を変更するだけで済むため、メンテナンスが容易です


## スコープが機能するタイミング
スコープは、モデルクラスに定義され、クエリを発行するときに使用され、以下のようなタイミングで機能します
- コントローラーでのデータ取得: コントローラーでモデルからデータを取得する際にスコープを使用します
- モデル内のメソッド: モデル内のメソッドからスコープを呼び出して、特定の条件に基づくデータを取得します
- メール送信メソッド: 上記のように、メール送信メソッド内でスコープを使ってデータを取得することができます


## スコープの使用例
- スコープを使用した場合
```
# app/models/user.rb

class User < ApplicationRecord
  # アクティブなユーザーを定義するスコープ
  scope :active, -> { where(active: true) }
end


# コントローラーでの使用例
@active_users = User.active
```

- スコープを使用しなかった場合
```
# app/models/user.rb

class User < ApplicationRecord
  # スコープを使わない場合の定義
  def self.active_users
    where(active: true)
  end
end


# コントローラーでの使用例
@active_users = User.active_users
```

スコープを使わない場合、同じ条件を他の場所で再利用する際には、同じ条件をコピーして使う必要があり、コードの重複が生じる可能性があります。それに対して、スコープを使うことで、一度定義すればどこからでも簡単にその条件を適用できるため、保守性や可読性が向上していることがわかります。


## さいごに
一貫性を保ちながらも複雑さを管理していくことで素晴らしいモノが完成し、私たちの暮らしの便利を支えるエンジニア。自分でいろいろ調べていくほどすごさが伝わってきます:star2:
便利なメソッドとか沢山ありすぎてわからなくならないよう、まずは数個の事例の流れを把握しよう
【Unity】モデルのリグがGenericでもあきらめない

# モデルとアニメーションのリグが違う！

Unityで開発している際に、
「Asset Storeで購入したモデルのリグが期待していたものとは異なっていた」
という状況に遭遇することが何度かあります。

原則として、リグが異なるモデルとアニメーションのセットは正常に動作しません。
そのため、GenericのモデルにHumanoidのアニメーションを適用することは難しいです。
**「Humanoidのアニメーションを再生させたいのにモデルのリグがGenericだった」**
というケースが一番多いのではないでしょうか。

# リグの異なるモデルにアニメーションを適用する

今回は、GenericのモデルにHumanoidのアニメーションを再生させる方法を紹介します。
ただし、必ずしも成功するとは限らないので、あくまで参考程度に見て頂ければ幸いです。

まず、モデルのメッシュを選択します。
選択すると、Inspectorウィンドウに画像のような表示があると思います。

次に、「Animation Type」を「Humanoid」に変更します。

最後に、右下の「Apply」をクリックして変更を適用します。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470968/acde7fb1-07b4-6713-56f6-c45376b375e0.png">

この状態で、適用したいアニメーションのモデルに、
今メッシュを変更したモデルを選択してプレビューを再生してみて下さい。

上手くいっている場合、アニメーションを再生するようになりました！
これは、人型に近いモデルほど成功するように感じます。

以上が「GenericのモデルにHumanoidのアニメーションを再生させる方法」でした。
最後までご覧いただきありがとうございました :laughing:
負荷テストを定期的に行う重要性とその実践方法


## はじめに
こんにちは、皆さん。今回は、ソフトウェア開発における負荷テストの重要性とその実践方法についてお話ししたいと思います。特に、クラウドベースのアプリケーション開発において、負荷テストを定期的に行うことがいかに重要かを強調したいと思います。

## 負荷テストの重要性
負荷テストは、システムが高負荷状態でも正常に動作するかを確認するためのテストです。これを怠ると、リリース後に予期せぬトラブルが発生し、ユーザー体験を損なう可能性があります。特に、クラウド環境ではスケーラビリティが求められるため、負荷テストは欠かせません。

### 1. パフォーマンスの確認
負荷テストを行うことで、システムのパフォーマンスを確認できます。どの程度のトラフィックに耐えられるのか、どの部分がボトルネックになっているのかを把握することができます。

### 2. スケーラビリティの検証
クラウド環境では、リソースを動的にスケールすることが可能です。負荷テストを通じて、スケーリングの設定が適切かどうかを確認できます。

### 3. コストの最適化
負荷テストを行うことで、必要なリソースを正確に見積もることができ、コストの最適化が図れます。過剰なリソースを割り当てることなく、必要最低限のリソースで運用することが可能です。

## 負荷テストの実践方法
では、具体的にどのように負荷テストを行うのか、その方法について説明します。

### 1. テストシナリオの作成
まずは、どのようなシナリオで負荷テストを行うかを決めます。ユーザーの行動パターンをシミュレートし、現実に即したシナリオを作成します。

### 2. ツールの選定
次に、負荷テストを行うためのツールを選定します。代表的なツールとしては、Apache JMeter、Gatling、Locustなどがあります。クラウドベースのサービスとしては、AWSのAWS Load Testing、AzureのAzure Load Testingなども利用できます。

### 3. テストの実行
選定したツールを使って、実際に負荷テストを実行します。テストの結果を分析し、システムのパフォーマンスやスケーラビリティを評価します。

### 4. 結果の分析と改善
テスト結果をもとに、システムの改善点を洗い出します。ボトルネックとなっている部分を特定し、必要に応じてアーキテクチャの見直しやコードの最適化を行います。

## 定期的な負荷テストの重要性
負荷テストは一度行えば終わりではありません。システムの変更やアップデートがあるたびに、定期的に負荷テストを行うことが重要です。これにより、常に高いパフォーマンスを維持し、ユーザーに快適な体験を提供することができます。

## まとめ
負荷テストを定期的に行うことは、クラウドベースのアプリケーション開発において非常に重要です。パフォーマンスの確認、スケーラビリティの検証、コストの最適化など、多くのメリットがあります。ぜひ、皆さんも定期的な負荷テストを実践し、より良いシステムを構築してください。

最後まで読んでいただき、ありがとうございました。この記事が皆さんの参考になれば幸いです。
技術スタックを定期的に見直す重要性とその方法


## はじめに
ソフトウェア開発において、技術スタックの選定はプロジェクトの成功に直結する重要な要素です。しかし、一度選んだ技術スタックをそのまま使い続けることが最善策とは限りません。技術の進化は日進月歩であり、定期的に技術スタックを見直すことが求められます。本記事では、技術スタックを定期的に見直す重要性とその方法について解説します。

## 技術スタックを見直す重要性
### 1. パフォーマンスの向上
新しい技術やツールは、しばしばパフォーマンスの向上をもたらします。例えば、新しいバージョンのフレームワークやライブラリは、より効率的なアルゴリズムや最適化が施されていることが多いです。これにより、アプリケーションのレスポンスが速くなり、ユーザー体験が向上します。

### 2. セキュリティの強化
古い技術スタックは、セキュリティホールが発見されやすくなります。定期的に技術スタックを見直し、最新のセキュリティパッチやアップデートを適用することで、セキュリティリスクを最小限に抑えることができます。

### 3. 開発効率の向上
新しいツールやフレームワークは、開発効率を向上させる機能を持っていることが多いです。例えば、最新のIDEやデバッガーは、コードの自動補完やリアルタイムのエラーチェック機能を提供し、開発者の生産性を向上させます。

## 技術スタックを見直す方法
### 1. 定期的なリサーチ
技術スタックを見直すためには、まず最新の技術動向を把握することが重要です。定期的に技術ブログやカンファレンス、コミュニティフォーラムをチェックし、最新の情報を収集しましょう。

### 2. プロトタイプの作成
新しい技術を導入する前に、小規模なプロトタイプを作成してみることをお勧めします。これにより、新しい技術が実際のプロジェクトにどのように影響を与えるかを事前に確認することができます。

### 3. チームでのディスカッション
技術スタックの見直しは、チーム全体で行うべきです。定期的にミーティングを開催し、各メンバーが新しい技術についての意見や経験を共有する場を設けましょう。これにより、より多角的な視点から技術スタックを見直すことができます。

### 4. 継続的な学習
技術は常に進化しています。開発者自身も継続的に学習し、新しい技術やツールに対する知識をアップデートすることが求められます。オンラインコースやワークショップに参加することで、最新の技術を習得しましょう。

## まとめ
技術スタックを定期的に見直すことは、プロジェクトの成功に不可欠です。パフォーマンスの向上、セキュリティの強化、開発効率の向上など、多くのメリットがあります。定期的なリサーチ、プロトタイプの作成、チームでのディスカッション、継続的な学習を通じて、最適な技術スタックを維持しましょう。

技術の進化に対応し続けることで、より良いプロダクトを提供し、ユーザーの期待に応えることができるでしょう。
【SQLServer】複数テーブルにまたがる情報を削除する

## 先にSQL文から

```SQL
BEGIN TRANSACTION;

BEGIN TRY
-- 子テーブルのデータを先に削除
DELETE ChildTable FROM 
    ChildTable
JOIN 
    ParentTable 
ON 
    ChildTable.ForeignKey = ParentTable.PrimaryKey
WHERE
    [条件];
    
-- 親テーブルのデータを削除
DELETE FROM 
    ParentTable
WHERE 
    [条件];
    
-- トランザクションのコミット
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- ロールバック処理
ROLLBACK TRANSACTION;
END CATCH;
```

## 詳細説明

```SQL
BEGIN TRANSACTION;
```
トランザクションの開始位置を示します．

https://learn.microsoft.com/ja-jp/sql/t-sql/language-elements/begin-transaction-transact-sql?view=sql-server-ver16

```SQL
BEGIN TRY
END TRY
BEGIN CATCH
END CATCH
```

エラー処理のブロックです．
TRYブロック内でエラーが発生するとCATCHブロックへ制御が渡ります．

https://learn.microsoft.com/ja-jp/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-ver16

```SQL
-- 子テーブルのデータを先に削除
DELETE ChildTable FROM 
    ChildTable
JOIN 
    ParentTable 
ON 
    ChildTable.ForeignKey = ParentTable.PrimaryKey
WHERE
    [条件];
    
```
テーブルに親子の依存関係がある場合，子テーブルから削除します．
依存関係の仕様上親テーブルを先に削除すると子テーブルが削除できなくなります．


```SQL
-- 親テーブルのデータを削除
DELETE FROM 
    ParentTable
WHERE 
    [条件];
```
親テーブルを消す

```SQL
COMMIT TRANSACTION;
```
トランザクションの途中で行われたすべての変更は一時的に保持されています．
`COMMIT TRANSACTION;` を実行することでデータベースに変更内容が確定されます．

https://learn.microsoft.com/ja-jp/sql/t-sql/language-elements/commit-transaction-transact-sql?view=sql-server-ver16

```SQL
-- ロールバック処理
ROLLBACK TRANSACTION;
```
トランザクションの途中で問題が発生したため，ロールバック処理をします．
今回の場合は
`BEGIN TRANSACTION;` の直前までロールバックされます．

https://learn.microsoft.com/ja-jp/sql/t-sql/language-elements/rollback-transaction-transact-sql?view=sql-server-ver16
スクラム開発でのSLO設定: クラウドサービスを活用した成功体験


## はじめに

こんにちは、皆さん。今回はスクラム開発におけるSLO（Service Level Objective）の設定についてお話しします。クラウドベンダーの多様なサービスを活用しながら、どのようにしてプロダクトの品質を高めるかについて、私の経験を交えてご紹介します。

## SLOとは？

まず、SLOとは何かを簡単に説明します。SLOはService Level Objectiveの略で、サービスのパフォーマンスや可用性に関する具体的な目標を指します。これにより、チーム全体が同じ目標に向かって動くことができ、ユーザーに対して一貫したサービスを提供することが可能になります。

## なぜSLOが重要なのか？

SLOを設定することで、以下のようなメリットがあります：

- **ユーザー満足度の向上**：ユーザーが期待するサービスレベルを明確にすることで、満足度を高めることができます。
- **チームの一体感**：全員が同じ目標に向かって動くことで、チームの一体感が生まれます。
- **問題の早期発見**：SLOをモニタリングすることで、問題が発生した際に早期に発見し、対応することができます。

## SLOの設定方法

### 1. 目標の明確化

まずは、どのような目標を設定するかを明確にします。例えば、以下のような項目が考えられます：

- **可用性**：サービスがどれだけの時間稼働しているか。
- **応答時間**：リクエストに対する応答時間。
- **エラーレート**：エラーが発生する割合。

### 2. メトリクスの選定

次に、目標を達成するためのメトリクスを選定します。クラウドベンダーが提供するモニタリングツールを活用すると良いでしょう。例えば、AWSのCloudWatchやGoogle CloudのStackdriverなどがあります。

### 3. モニタリングとアラート設定

選定したメトリクスをモニタリングし、目標を達成できていない場合にアラートを設定します。これにより、問題が発生した際に即座に対応することができます。

### 4. 定期的なレビュー

SLOは一度設定したら終わりではありません。定期的にレビューし、必要に応じて目標を見直すことが重要です。スクラムのスプリントレビューやレトロスペクティブの際に、SLOの達成状況を確認すると良いでしょう。

## クラウドサービスの活用

クラウドベンダーが提供するサービスを活用することで、SLOの設定とモニタリングが非常に簡単になります。例えば、以下のようなサービスがあります：

- **AWS CloudWatch**：メトリクスの収集とアラート設定が簡単に行えます。
- **Google Cloud Stackdriver**：多様なメトリクスをモニタリングし、アラートを設定できます。
- **Azure Monitor**：Azureのリソースを一元的にモニタリングできます。

これらのサービスを活用することで、SLOの設定とモニタリングが効率的に行えます。

## まとめ

SLOを設定することで、ユーザー満足度の向上やチームの一体感、問題の早期発見など多くのメリットがあります。クラウドベンダーのサービスを活用しながら、効果的にSLOを設定し、プロダクトの品質を高めていきましょう。

皆さんのプロジェクトが成功することを願っています。この記事が少しでもお役に立てれば幸いです。

## 参考リンク

- [AWS CloudWatch](https://aws.amazon.com/jp/cloudwatch/)
- [Google Cloud Stackdriver](https://cloud.google.com/stackdriver)
- [Azure Monitor](https://azure.microsoft.com/ja-jp/services/monitor/)
初めてのPythonで "error: externally-managed-environment" を解決する

これが完璧な解決策かは、わかりません。もっと良い方法があれば、教えてください。

## 前提
- 初めてに近い状態で、Python を使う
- Python の様々なモジュールを使う
- Homebrew で Python をインストール
- macOS (Apple Silicon)

## 背景
OpenAI の API を使って、様々な作業をさせるPythonスクリプトを作ろうと思い、Pythonを学び始めました。

しかし、モジュール(ライブラリ?)のインストールで、躓きまくりました。最終的には、エラーメッセージに案内される方法で解決しました。

## Pythonのインストール

homebrew を使います。詳しくは、たくさん記事があるので、それを参考にしてください。複雑なことは何もありません。

- [homebrew](https://brew.sh/)

```terminal
brew install python@3.12
```

## モジュールのインストールでエラーが出る

次に、使いたいモジュールをインストールしようとすると、エラーが発生

```terminal
pip3 install openai
```

![エラー画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193970/71c84711-a914-36f0-9c8d-141181217286.png)

後で分かったことですが、エラーメッセージの理解を間違いました。

> If you wish to install a Python library that isn't in Homebrew,
    use a virtual environment:
>    
>    python3 -m venv path/to/venv
>    source path/to/venv/bin/activate
>    python3 -m pip install xyz

homebrewの中ではないPythonライブラリを使いたいなら、以下のコマンドを実行せよとのこと。私は、続くしたのメッセージにしたがってしまって、ハマってしまいました。

> If you wish to install a Python application that isn't in Homebrew,
    it may be easiest to use 'pipx install xyz', which will manage a
    virtual environment for you. You can install pipx with
>    
>    brew install pipx

Homebrewの中ではない **Pythonアプリケーション** を使いたいなら、 pipx だと。アプリには、pipxということらしい。

では、homebrew の中の Python Library が使いたい場合はどうしたらいいの？という疑問が湧きますが、その時は別の方法？と思いきや、その方法はなさそうでした（私調べ）。


## 解決方法

少し面倒ですが、Pythonライブラリのインストールや、コードを勉強したり、実行するときは「仮想環境」を立ち上げて行うようにすることです。上記のメッセージ通りにやるだけです。

まず、仮想環境を起動するためのファイル群を生成します。このファイル群は、どこにおいてもOKなので、ホーム直下に置くことにしました。名前も、 `mypy` です。適当です。

```terminal
python3 -m venv ~/mypy
```

Pythonでライブラリ（パッケージ）をインストールしたり、コードを書いて、実行するときは、必ず以下のことをします。

```terminal
source ~/mypy/bin/activate
```

すると、ターミナルのプロンプト前方に「 (pyvenv) 」とつくようになります。この状態で、pipコマンドなどで、必要なライブラリをインストールします。※ notice が出る場合は、言われた通りにコマンドを実行したら解決します（後述）

```terminal
pip3 install openai
```



プログラミングが終わったら、

```terminal
deactivate
```

とします。このコマンドは、仮想環境を動かしている時だけ使えます。

## おまけ1 : 仮想環境の簡単呼び出し

ちょっとだけ面倒ですよね？そこで、エイリアス(別名コマンド)を追加します。

```
nano ~/.zshrc 
```

などで、zシェルの設定ファイルを開いて、以下のように記入します。

```shell
alias gopy = 'source ~/mypy/bin/activate'
```

これで次回からは、以下で仮想環境がスタートします。

```terminal
gopy
```

## おまけ2 : pip のバージョン問題

以下のようなメッセージが出ることがあります。

```terminal
[notice] A new release of pip is available: 24.0 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
```

シンプルに
```terminal
pip install --upgrade pip
```

とすればOKです。

## おまけ3 : Visual Studio Codeの設定

Visual Studio Code内のターミナルをひらけば、すぐに仮想環境で実行できます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193970/5369d4f0-e806-6353-cc81-a1bd0a9c6cef.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193970/61bb0149-d2c5-b547-2982-1b206f1eabb0.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193970/1ee21c7a-9fa7-6aa3-9095-7bc1f9820d24.png)
テキストの重複行の削除方法（サクラエディタ、Linux）

（自身の備忘録用です）
## さくらエディタの場合
1. ctrl+Aで全選択
　→この時末尾に一行空行追加しておく
  （末尾の行に改行が付与されていないと重複しているとみなされない場合がある）
1. alt+Aでソート
1. alt+mで重複行マージ
　→マージされた行数がポップアップメッセージで教えてくれる

## Linuxの場合
元ファイルを以下とする
```
$ cat test.txt
aaa
AAA
bbb
ccc
aaa
AAA
AAA
BBB
```
uniqするだけだと、行が離れている行がある場合に重複削除してくれない
```
$ uniq test.txt 
aaa
AAA
bbb
ccc
aaa
AAA
BBB
```
一度sortしてからuniqすると重複行削除してくれる
```
$ sort test.txt
AAA
AAA
AAA
BBB
aaa
aaa
bbb
ccc

$ sort test.txt | uniq
AAA
BBB
aaa
bbb
ccc
```
重複行数を知りたい場合はuniqのオプション-c（--count）で確認可能
```
$ sort test.txt | uniq -c
   3 AAA
   1 BBB
   2 aaa
   1 bbb
   1 ccc
```
さらに重複行数でsortしたい場合はさらにパイプで繋いで降順でsort
（もっと上手く書けそうな気もする。。）
```
$ sort test.txt | uniq -c | sort -gr
   3 AAA
   2 aaa
   1 ccc
   1 bbb
   1 BBB
```
見向きもしてなかったconfigについて、

## はじめに
configディレクトリに指定されたファイルやコードを今までなんとなく入力してきたわーちゃんです。
改めて、configってなんだ？と感じたので、頭の片隅においておくといいかもしれない知識としてアウトプットしていきます

## config ディレクトリについて
config ディレクトリは、Railsアプリケーションの設定ファイルが集まる場所で、ここには以下のようなファイルが含まれます。
- database.yml: データベースの設定
- routes.rb: ルーティングの設定
- secrets.yml: アプリケーションのシークレットキーや設定
- environments/: 環境ごとの設定（development, test, productionなど）
- initializers/: 初期設定を行うファイル
- locales/: ロケール設定

これらのファイルは、アプリケーションの動作や設定に関わる重要な情報を含んでおり、アプリケーションの各部分がどのように連携するかを決定します。これにより、アプリケーションの様々な側面を一元的に管理し、必要に応じてカスタマイズすることが可能です。

### 正式名称
config は「configuration（設定）」の略

## configにファイルが集まる理由
- 統一された設定管理
アプリケーションの設定を一箇所にまとめることで、管理が容易になります。開発者は設定変更が必要な場合、config ディレクトリ内のファイルを確認すれば済みます

- 環境ごとの設定の分離
開発、テスト、運用といった異なる環境ごとに設定を分けることができます。例えば、config/environments/ ディレクトリには、環境ごとの設定ファイルが含まれています。これにより、環境ごとに異なる設定を簡単に適用できます

- 初期設定とカスタマイズ
config/initializers/ ディレクトリには、アプリケーションの初期設定を行うためのファイルが含まれています。これらのファイルは、アプリケーションが起動する際に実行され、必要な初期設定を行います。

- セキュリティと機密情報の管理
config/secrets.yml などのファイルは、アプリケーションのシークレットキーやその他の機密情報を管理します。これにより、セキュリティが強化されます

- 国際化とロケール
config/locales/ ディレクトリには、アプリケーションのロケール設定ファイルが含まれています。これにより、多言語対応が容易になります

## config/routes.rbでの例
config/routes.rbファイルは、アプリケーションのルーティングを設定するための重要なファイルです。以下に、configを使ったルーティングの簡単な例と、configを使わない場合の違いを示します。

### configを使った場合
野菜を買うというアクションについて。
```
# config/routes.rb

Rails.application.routes.draw do
  # 野菜を買うというルーティング
  get '/buy_vegetables', to: 'vegetables#buy'
end
```

この設定では、/buy_vegetablesというパスにアクセスがあった際に、VegetablesControllerのbuyアクションが呼び出されるようになります。

### configを使わない場合
この時、ルーティングの設定は直接コントローラ内に記述することになります
```
# app/controllers/vegetables_controller.rb

class VegetablesController < ApplicationController
  # 野菜を買うアクション
  def buy
    # 買い物のロジック
  end
end
```
この場合、ルーティングはroutes.rbではなく、VegetablesController内のメソッドとして直接定義されます。具体的なURLパスとアクションの関連付けは、コントローラ内に記述されることになります。

### 選ぶ基準
どちらを選ぶかは、プロジェクトの規模や保守性、拡張性などによりますが、config/routes.rbを使用してルーティングを設定する方が一般的です。ルーティングとコントローラの分離が明確になり、管理が容易になります
しかし、小規模なアプリケーションや特定の場面では、コントローラ内で直接ルーティングを定義することもあります。

## さいごに
configだけに限らず、プロジェクト全体で共有される情報である場合や、複数のアクションに対して一貫した設定を適用したい場合、何かとまとめることが多いと感じています。
自分だけでなく、ほかの人の事も考えながらコードを考えなければいけない…その境地にたどりつけるよう頑張りたいところです:muscle_tone1:
部門コードを送信するとPOPを取り付けるか取り付けないか教えてくれる＋こぎつねの癒しを提供⁉【初心者のLINEbot作成チャレンジ】

# 初LINEBot「🦊対象部門お知らせYELL」

皆さま毎日お疲れ様です！
最近ME:Iというアイドル推しているアラサー会社員です。
今回はプログラミング初心者の私がノーコードでLINEBot作成にチャレンジした模様をお伝えしたいと思います。

![Screenshot_20240709-103307.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/9752eb38-7681-74e0-e0ba-2de585a7bd19.png)

# LINEBot作成チャレンジの背景
スーパーで買い物をしている時に、お客さまである皆さんが必ず目にしているもの、それは**POP**です。
商品には必ず値段を表示するPOPがありますが、今までは紙のPOPが当たり前でした。
しかし近年では各企業のDXが進み、紙のPOPから**電子棚札**に切り替わるお店が増えてきました。
その電子棚札の取付応援に行った際に困ったことがありました。
**「どの部門が電子棚札取付対象外かわからない！！」**
部門コードはPOPを見たらわかるけれど、取付範囲までは応援者がわからないのです。
そして別の作業をしている担当者にたびたび聞きに行く始末。。。
＋**日常のもやもやを解決するための隠し機能**も付け、ちょっとした癒しも提供してくれるようにしました。

まとめると、**部門コードを送信するとPOPを取り付けるか取り付けないか教えてくれる＋ちょっとした癒しをくれるLINEbot**を作成してみました！！


# 「LINEBot」とは？
そもそも **「LINEBot」** とは一体何でしょう？
ずばり **「ユーザーの書き込んだチャットメッセージに対して、自動返信をするLINE用のロボット」** です。
身近なところだと、郵便物の時間変更や再配達を行うときに各会社の専用アカウントがありますので使用しています。
すぐに応答してくれるのでとても便利ですよね。


# 使用したツール
- [Make](https://eu2.make.com/)
- [GoogleSpreadSheet](https://docs.google.com/spreadsheets/)
- [randomfox API](https://randomfox.ca/)


# 作成手順
MAKEを利用しましたが、
後ほどの店舗ごとに取付範囲を教えてくれるなどのアップデートに備え、
できるだけシンプルにシナリオを作れるよう考えながら作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/fc0421b0-fca9-9264-3bee-30ab500db5d4.png)

**Google Sheets**
電子棚札取付対象部門をGoogle Sheetsに書き出し、Google sheetsモジュール(Search Rows)を介して使用しました。

参照元にしたGoogle Sheets
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/b50f0ae8-bc6d-b591-76ed-9a7437f856df.png)

Google sheetsモジュール(Search Rows)抜粋
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/0da59547-a07b-07ab-f204-2491b7269b22.png)

**LINEでメッセージと画像を返信**
LINEモジュールにGoogle Sheetsからの返信 もしくは randomfoxから受け取った画像 を設定します。

入力された文字がGoogle Sheetsにあった場合、**記載内容を返信**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/1787c738-7d23-f6d9-6a4f-699ee195b2d8.png)

入力された文字がGoogle Sheetsにない場合、**テキストを返信**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/143302fe-d54e-d719-4fe3-f926bb877c6e.png)

入力された文字に**疲が含まれる場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/7852f43a-25b5-6cd3-4ec8-f71b1628ea6f.png)

:::note warn
**注意** 
Original Content URLと Preview Image URL を逆に入れると返信が返ってきません。
画像の返信がなかったら、ここを見てみてください！
:::


# 「🦊対象部門お知らせYELL」完成
送られてきたメッセージに対してLINEbotが返信してくれます！
![Screenshot_20240709-103307.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801565/9752eb38-7681-74e0-e0ba-2de585a7bd19.png)

# まとめ
このLINEbotを作れたことで、応援時にわざわざ担当者に聞きに行く無駄な時間を削減できます。
担当者はその間に他業務を進めることができるため、微力ながら業務の効率化を進められるはずです。
他の電子棚札を取り付けに行くメンバーにも共有して使ってもらいつつ、
今後もよりよい使い心地を目指して、グレードアップしたものを作っていきたいです！

以上、長い文章にお付き合いいただきありがとうございました！
【NoLang】を知っていますか？　ゆっくり解説動画を10秒でw


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

　今回は、NoLangというサービスをご紹介します。ゆっくり解説動画を10秒で、という感じのものですよ😸

:::note info
本記事は、NoLangの紹介です。
画像はあります。　あしからず。
:::

　ようやく、
　　酷暑のピークを過ぎて
　　　生きやすくなりましたね😅

　それでも
　　油断大敵ですよ😸
***
　さて、本題です。

　いつもは
　　ChatGPT関連を
　　　記事にしていますが、
　　　　今回は、とあるサービスの
　　　　　紹介になります。

　YouTubeなどで
　　よく「ゆっくり解説」系の
　　　動画がありますよね。

　私もたまに見てしまいます😅

　ずんだもんというキャラが
　　解説するのが有名ですね。

　あんな動画、
　　作るの大変そうです。

　内容を決めて、
　　必要な情報・素材を集めて、
　　　構成を決めて、
　　　　まとめ上げる。

　それを一日一本とか
　　数時間に一本とか、
　　　投稿されています。

　まぁ、
　　おそらく数人のスタッフで
　　　運用しているのでしょうね。

　それでも
　　制作するには
　　　知識や機材が必要です。

　そうした動画投稿を
　　はじめたい人には
　　　ハードルが高いものですね。
***
　そこに登場したのが
　　今回紹介するNoLang 2.0です。

　なんと、質問を
　　入力する手間だけで
　　　一分動画ができてしまいます。

　いや、ホントに😅

　まずは、
　　私が作った？サンプルを
　　　ごらんください。

　「タロットカードについて教えて」
　　と入力・送信しました。
　　　一分せずに、生成されました。
　　　　マジです。
[タロットカードの神秘的な世界](https://no-lang.com/video/738791c5-b372-4d55-a7d4-4ba637ed4c9a?type=vod)

　いかがでした？

　ちょっと
　　見入ってしまった方も多いのでは？

　残念なことに
　　ダウンロードは
　　　パソコンでないと
　　　　できないようですが。
***
　NoLang 2.0は、
　　東大発の生成AIスタートアップ
　　　Mavericksが開発した
　　　　リアルタイム解説動画AIです。

　内部では
　　GPT-4oやClaude 3.5 Sonnetを
　　　使っている、とか。

　リリースは
　　昨日（2024/07/08）です。

　有料プランは以下の三つ。
　・980円/月
　・2980円/月
　・7980円/月

　ちなみに、
　　【7/14までの期間限定】で
　　　全ユーザーに対し、
　　　　以下の特典が付与されます！

　①200クレジット
　②アバター付き動画生成の
　　　消費クレジット割引
***
　さて、
　　このサービスを使うには、
　　　どうしたらいいのでしょうか？

　NoLangのサイトを
　　探してもらってもいいのですが、
　　　下記にて、ジャンプしてください。

　[NoLangサイト](https://no-lang.com/)

　すると
　　こんなページになります。
　　　文字が変になっているのは
　　　　私のスマホが小型だからです😅
![Screenshot_20240709-105340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/2ea05ce1-37c7-4b76-f5ce-ab029216a82a.png)

　右上のログインボタンで
　　ログインします。

　Googleアカウントのみになります。

　ログインすると
　　ギャラリーになります。

　ほかの人が作成した
　　動画を見られます。

　作成するには、
　　下方にある入力枠に
　　　プロンプト（質問）を
　　　　入力して送信するだけです。

　少し待つと
　　作成された動画が
　　　表示されます。

　これが
　　基本の使い方になります。

　詳しい使い方は
　　ここでは触れません。

　YouTuber KEITOさんが
　　YouTubeで紹介されています。
　　　15分間の動画になります。
　　　　こちらの方が詳しいですよ。
[【本当は教えたくない】10秒でゆっくり解説と縦型ショート動画が出来るAI「No Lang 2.0」が神すぎる](https://youtu.be/StpmoL4UFv4?si=8lWLSVefxYcIRTVx)

　質問を入れるだけで
　　動画を作れる手軽さがいいですね。

　しかし、
　　これの真価は
　　　ChatGPTなどの生成AIが
　　　　吐き出す文章ではなく、
　　　　　動画にして説明してくれる
　　　　　　ところにある、と
　　　　　　　思います。

　動画で説明してくれることで
　　“読む”という能力を使うことなく
　　　理解に到達できるのです。

　これからは
　　こうした動画での説明が
　　　ビジネスでの活用に
　　　　広がっていくのかも
　　　　　しれませんね。

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

　今回は、ここまで。
【2024マラソン23】quest版ビートセイバーでアバター動画を撮る方法

# 何の記事？
ビートセイバーにmodを入れて、好きなアバターでプレイ動画を撮る方法について書きました。

# 誰向け？ どんな役にたつ？
- ビートセイバーでアバター動画を撮ってみたい人
- アバター動画を撮るまでのmod導入手順がイマイチわからない人
- アバター動画がどんな感じか気になる人

# アバター動画を撮るまでに必要なこと
まず、アバター動画を撮る機能は公式では用意されていません。
個人の方がアバターを読み込ませることができるmodが使える状態にする必要があります。
1. ビートセイバーのバージョンを下げる
1. modが使えるバージョンにする
1. vrmアバターを読み込ませる
……という、上記の手順を踏む必要があります。

# 具体的に何を使ったか

## 使った道具
- quest2
- ビートセイバー(quest版)
- PC(modの設定のみ)

## 全体的に参考にしたサイト

https://orentame.com/beatsaber-modded-enable-for-quest3/

https://orentame.com/quest-beassaber-use-vrmavatar/#st-toc-h-2

基本的には上記サイトを参考に、アバターmodと曲追加modが使えるようにしました。

## 導入したmod

それぞれのmodは下記リンクからDLしました。

https://orentame.com/questsaber-recommended-mods/#st-toc-h-10

### VRM Qavatars
アバターを表示する用のmodです。

### Replay
アバター動画のリプレイ作成用のmodです。

### BeatLeader
Replayと同様に、リプレイ作成用のmodです。

### HitScoreVisualizer
音ゲーのように、Excellentなどの表示が出るmodです。

### ClockMod
画面上部にquestの電池残量と現在時刻が表示されるmodです。

# 何をやったか
ここには概要を書きます。
詳しい手順は参考リンクを参考にしてください。

### 1. アバターmodが対応しているバージョンまで下げた後で、modが使えるようにする
今回は1.28のmod対応版にします。
まず、下記リンクのQAVSでバージョンを下げます。

https://orentame.com/how-to-install-qavs/

その後、modが使えるように下記リンクの手順でQuestPatcherを使って設定します。

https://orentame.com/beatsaber-modded-enable-for-quest3/#st-toc-h-6

### 2. vrmアバターを読み込ませる
QuestPatcherを使って、QuestにVRMファイルを読み込ませます。

### 3. いつも通りプレイする
プレイ時点ではアバターは非表示で大丈夫です。
プレイ後、収録できた動画をチェックするタイミングで表示させます。

### 4. アバター表示状態にして、リプレイモードを開始
一度トップのアバター表示メニューからアバターを表示させて、先程プレイした楽曲からリプレイを選択します。
すると、あたかもアバターがゲームをプレイしていたかのように表示されます。
ここで、リプレイ楽曲が終わるまでの間に実際に録画する際の録画角度や向きなどを設定します。

### 5. 短い曲で録画テスト
実際に録画したい楽曲で録画を開始すると、楽曲の時間+アルファの時間がかかります。
そのため、短い楽曲でテスト録画をして、画角が気に入ったものになっているか確認するとよいです。
Windows起動音という、6秒間だけの楽曲があるので、それをプレイし、リプレイメニューから録画を選択します。
録画できた動画を確認し、画角の修正が必要であれば再度録画したい曲のリプレイで調整を行います。

### 6. 録画を行う
実際に録画を行います。
録画方法はquest本体の録画機能を使うか、render録画というmod機能を使うかの2種類が選べます。

ただし、quest本体録画の場合は録画終了までquest2を動かさないように撮る必要があるため、render録画をオススメします。
render録画は終了までヘッドセットがスリープにならないようにする必要があるため、レンズ間中央に何か手乗りサイズのぬいぐるみなどを入れて、「チーン!!」と完了音が鳴るのを待ちます。

# 結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964152/114f6521-8310-9d8b-9bd7-b037508d3942.gif" width=300>

こんな動画ができます。
自分の気に入ったアバターで動画を撮って、後から鑑賞できるのは思った以上に楽しかったです。
また、リプレイ内容は同じままで、異なるアバターの動画を書き出すこともできます。
また、判定系のmodを入れている場合はプレイ中は夢中で気づけなかった判定ミスも振り返ることができて便利でした。

# デメリット、できなかったことなど
### フルトラッキング
SlimeVRなどのフルトラ機器があると、フルトラができるようなのですが、私はTDPTのiPhone版しかフルトラ環境がないため、できませんでした。
ビートセイバーのプレイ動画はフルトラだとかなり自由度が上がるのですが、今後のmodのアップデートなどに期待したいところです。

### 音ズレ対策
若干、映像と音楽にずれが生じます。
なので、youtube等外部にプレイ動画をアップする場合は動画編集ソフトなどでズレを解消してあげるといいかと思います。