OmniAICreator/Qiita-1.07M huggingface dataset:
AWS上に、検索拡張生成(RAG)を使用した生成系AIを作成する

ChatGPTをはじめとする、生成系AIは活用されていますか？

・下記のコードのエラー箇所を指摘してください。
・EC2の特徴について教えてください。

ソースコードの推敲や、サービスの特徴をまとめてもらったりと、何かと便利な生成系AIですが、下記のような質問では正しい回答を得られないことが多いです。

・出勤打刻を漏らした際に必要な申請について教えてください。
・○○システムにおける××の運用ルールについて。

これは、生成系AI(ChatGPT)のインプットデータがWebページや書籍・学術論文を主としており、世間的に回答が一致する内容は得意ですが、組織やシステムごとにルールや仕様が異なる内容についての回答はニガテであるためです。
逆に言えば、インプットデータを組織内のデータに制限することができれば、各組織やシステムに関する回答が可能になるのではないでしょうか。
それを実現するのが、本記事で紹介する検索拡張生成(RAG)になります。

### 使用する機能

#### Amazon Bedrock
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/a0b653eb-0163-486f-4d1d-fab1633eee4d.png)

生成AIの基盤モデルをAPIを通じて利用できるようにするサービス。
AWS上でChatGPTの利用を可能にするサービスのようなイメージ。

#### Amazon Kendra
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/d3b64b38-f189-72a2-bd2a-bdae80726179.png)
機械学習を利用した高精度な文書検索サービス。
BedRockにインプットするデータを、指定したデータソースのデータに限定する役割で使用。
データソースにはS3やRDS、SharePointが指定可能。

#### データストレージ(S3)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/ee77d4cb-b8c1-52f4-174b-5931bb44150b.png)
BedRockにインプットするデータの保存先として使用。
予め、S3にインプットするデータを格納しておく。(今回は社内で開催されたライトニングトーク会の内容についてのデータを格納)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/d71ec123-63ae-01cc-7f36-3592aee79a29.png)




### 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/907909b8-4a5a-b448-ddf7-da93939ef0b7.png)

### デモ
#### ChatGPT
まずはインプットデータを制限していないChatGPTにLT(ライトニングトーク)について質問してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/c379bb5a-6d56-8026-ac4e-c5b3803d4bc7.png)

当然、インプットデータを制限していないChatGPTに質問した場合はあらゆるLTに関する回答がなされ、適切な回答を得ることができません。

#### RAGを実装した生成系AI
続いてインプットデータを制限した生成系AIにLTについて質問してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/495d02b7-850f-1032-9b19-79868febd2dd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680855/b373ab41-de9b-6b9c-8dd7-78e8403dc25f.png)

インプットデータを制限することで、LTについて適切な回答を得ることができました。

検索拡張生成を使用することで、特定の組織やプロジェクト内のルールや仕様についての回答を得ることができる、生成系AIの作成が可能になります。
useRouteとuseRouterの違いは？

## はじめに
新卒1年目のポテトです。🍟
仕事をしていく中で学んだことをアウトプットしたいと思い、Qiitaを始めるになりました！
今回は案件で使用しているVue Routerの、useRouter と useRouteの違いについてまとめていきます。

## useRouteとuseRouterの定義元
https://router.vuejs.org/

Vue Routerの useRouter と useRoute は、Vue 3のComposition APIを使ってルーティング関連の機能にアクセスするための関数です。
```
/**
 * Returns the current route location. Equivalent to using `$route` inside
 * templates.
 */
export declare function useRoute(): RouteLocationNormalizedLoaded;


/**
 * Returns the router instance. Equivalent to using `$router` inside
 * templates.
 */
export declare function useRouter(): Router;
```

## **useRoute**
https://router.vuejs.org/api/#useRoute
- 現在のアクティブなルートに関する情報を取得するために使う。
- `useRoute`は 現在のルートのRouteオブジェクトを返す。(`path`、`query`、`params`など、現在のURLの情報が含まれる。)
-  URLパラメーターやクエリパラメーターを取得する際に使用。

```jsx
const route = useRoute();
const userId = route.params.id; // URLからidパラメーターを取得
```

## **useRouter**
https://router.vuejs.org/api/#useRouter
- プログラムによるルーティング（ページ遷移など）を行うために使う。
- `useRouter`は`Router`インスタンスを返す。
- 新しいページに遷移する、履歴を操作するなどに使用。

```jsx
const router = useRouter();
router.push('/home'); // ホームページに遷移
```

## **まとめ**

- `useRoute`は現在のルート（URL）の情報を取得するために使う。
- `useRouter`はルートのナビゲーション（ページ遷移など）を制御するために使う。
---
今回はそれぞれの違いについて、軽くですがまとめてみました。普段案件で使っているけど深く理解できていないことを、再度深掘りすることはすごく大切だなと感じました！
区切り文字で複合化されたリストから冒頭アイテムを抽出する(SPSS Modeler データ加工逆引き2-19)

# 区切り文字で複合化されたリストから冒頭アイテムを抽出する

![スクリーンショット 2023-12-26 11.30.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fa33c0fb-944e-d91d-6052-8ace63201519.png)

列展開ではなく縦持ちにする場合には逆引き7-16を参照ください。

https://qiita.com/416nishimaki/items/fc892638dc4eca265dd4

また以下のようなセル内の改行リストの列展開は逆引き7-18を参照ください。

![スクリーンショット 2023-12-26 11.40.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2bd897f5-8c10-ed4e-4784-1e3a8ae3b479.png)

https://qiita.com/kawada2017/items/5439710395aa146de63f

## 1.想定される利用目的

・区切り記号による商品マスタ内枝番から代表アイテムを抽出する
・解約/不正予測モデルのための初動の特徴量作成
・故障予測モデルのためのの直前ログ特徴量作成

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/text_split.str

## 3.サンプルストリームの説明

![スクリーンショット 2023-12-26 12.59.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0e679113-2336-0d0f-1a95-fc2ee922f812.png)

a.入力するデータは以下の通りです。このデータをトランザクションから作成する手順は逆引き7-19で紹介しています。

![スクリーンショット 2023-12-26 13.02.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0048938e-c208-3115-eddb-8301ea8ff0a6.png)

b.[フィールド作成]ノードを編集します。　区切り文字カンマのリストのN番目を抽出する関数です。

![スクリーンショット 2023-12-26 13.03.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f11390a1-c843-97aa-ebe2-5f44b26494d2.png)

[テーブル]を表示します。

![スクリーンショット 2023-12-26 13.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f02f744d-8755-012f-342e-e6987f6da639.png)

c.[フィールド作成]ノードを編集します。リストの2番目を抽出します。

![スクリーンショット 2023-12-26 13.04.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1a5599f5-0bb3-2517-c965-4ada57f402b5.png)

[テーブル]を表示します。

![スクリーンショット 2023-12-26 13.04.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e04d8ffa-1be2-ae2b-c1ac-67ce07065c01.png)

#### 注意事項

リストの数だけ展開する場合には逆引き7-18を参考にしてください。

## 4.参考情報

#### トランザクションデータからの初回や2回目購入を抽出する

https://qiita.com/416nishimaki/items/63e47df549fa8ac8582b

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
RHEL8のEC2インスタンスにCloudWatch Agentをインストールする手順

# 概要
新規にCloudWatch AgentをLinuxサーバ（RHEL8）にインストールする手順。

# 目次
- 現在CloudWatch Agentがないことを確認
- CloudWatch Agentインストール
- バージョン確認

## 現在CloudWatch Agentがないことを確認
以下コマンドを実行して現在の環境にCloudWatch Agentがないことを確認。
```
dnf info amazon-cloudwatch-agent
```
```
cd /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d
```
## CloudWatch Agentインストール
以下コマンドを実行してCloudWatch Agentをインストールする。
```
sudo dnf install https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/redhat/amd64/latest/amazon-cloudwatch-agent.rpm
```

## バージョン確認
以下コマンドを実行して、正常にインストールできていることとインストールされているバージョンを確認する。
```
dnf info amazon-cloudwatch-agent
```
```
cd /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d
```
AWS SystemsManager Agent（SSM Agent）インストール手順

# 概要
新規にAWS SystemsManager Agent（以下SSM Agent）をLinuxサーバ（RHEL8）にインストールする手順。

# 目次
- 現在インストールがされていないことを確認
- SSM Agentインストール
- バージョン確認

## 現在インストールがされていないことを確認
以下コマンドを実行して、現在の環境にSSM Agentがインストールされていないことを確認する。
```
dnf info amazon-ssm-agent
```

## SSM Agentインストール
以下コマンドを実行してzip、unzipパッケージをインストールする。
```
sudo dnf install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
```

## バージョン確認
以下コマンドを実行してバージョンを確認する。
```
dnf info amazon-ssm-agent
```
(続)SVG帳票

前回（[SVG帳票](https://qiita.com/mackey1966/items/94242499eb85b5374cf2)）、SVGで帳票を作れるようにしたが問題がいくつかある。印刷ダイアログで調整が必要になる、ページ繰越しをどうするかなどだ。

印刷ダイアログではそのままだと（自分の環境では？）なぜか縮小されてしまうので200%などにしないとあわない。ダイアログは最後の状態を記憶しているので毎回設定する必要はないが別の帳票などで変更したりすると再度設定の必要があり使い勝手が悪い。いろいろ試したがうまくいかないので諦めて次の課題、ページ繰越しに移ることにした。

ページ繰越しのロジックを作ってそのまま複数ページにすることもできるがページ毎にダイアログがでる訳でそんなアホなことはしたくない。また、SVGにはページの概念がないので複数ページをくっつけて一つにしてもうまくいかないだろう。さて、どうするか。PDFに変換してまとめればよいのではないか。ツールを探すとlibrsvgでできそうだ。これを誰がやるか。クライアントサイドでやるにはユーザーにダウンロードさせたりしなくてはならず面倒そう。サーバーに投げて結果を返してもらえばよい。サーバーサイドはFastAPIなのでそれにやらせることにした。

```rb
UPLOAD_DIR = "./files"
def get_pdf(db: Session, request: schemas.File):
    # SVGを保存
    i = 0
    for svg in request.file:
        f = open(os.path.join(UPLOAD_DIR, str(i).zfill(3) + "-" + request.name + ".svg"), 'w')
        f.write(svg)
        f.close
        i += 1
    # PDFに変換
    subprocess.run("rsvg-convert -f pdf -o " + os.path.join(UPLOAD_DIR, request.name + ".pdf") + " " + os.path.join(UPLOAD_DIR, "*" + request.name + ".svg"), shell=True)
    response = FileResponse(
        path = os.path.join(UPLOAD_DIR, request.name + ".pdf"),
        filename = request.name + ".pdf"
    )
    subprocess.run("rm -f " + os.path.join(UPLOAD_DIR, "*" + request.name + ".svg"), shell=True)
    return response
```
こんな感じ。
Vue側ではSVGのArrayをAxiosで投げる
```js
getPdf: function(name) {
    setTimeout(() => {                   
        const data = {
            fid: this.$store.state.facilityId,
            name: name, 
            file: this.uploadSvg,                 
        };
        const url = this.$store.state.apiUrl + "/files/"
        axios
            .post(url, data, {
                withCredentials: true,
                responseType: 'blob', // これ重要 blob or arraybuffer
            })
            .then((res) => {                           
                const blob = new Blob([res.data], { type: "application/pdf" })
                const url = URL.createObjectURL(blob)
                this.$router.go(-1) // 戻る
                const winPrint = window.open(url)
                winPrint.print()                         
            })
            .catch((error) => {
                console.log(error);   
            })
            .finally()
    }, this.wait)
},
```
こんな感じ。responseTypeはblobでもarraybufferでもよいみたいだがこれがないと真っ白なページが返ってきて1日悩むことになるので注意。

SVGで200%拡大しないといけない問題も同時に解決した。しかし、試してみると1ページなら問題ないが複数ページだとPDFのウインドウが開いたり開かなかったりする。調べるとFastAPI側でPDFはちゃんと作られている。あれこれ悩んだが最終的にブラウザにポップアップをブロックされていることが原因だった。これはブラウザで許可してやるしかない。

あと、SVGでは文字数が多いとsvg-paperが横に圧縮していい感じに収めてくれていたがPDFではフォントそのそのまなので枠からはみ出る。これは事前に文字数をカウントしてsetAttributeでフォントサイズを小さくすることで対応した。

ということで帳票はなんとかなりそうだ。
ツンデレ女子のAIチャットボットを作ろう😤

# はじめに
AIチャットボットの超簡単な作り方を書いていきます。
基本は流れだけで、詳細は実際に参考にさせていただいた記事のリンクを貼らせていただいてます🙇‍♀️

ツンデレ女子である必要は一切ありません笑

# システム構成

Slack上でボットにメンションすると OpenAI が返事を考えてくれます。
Webサーバーには Fly.io を使ってます。

![systemConfiguration.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71897/a3fc31a7-fe67-c4ba-1b0a-c0dfbdc893ca.png)

# サンプルコード

細かい設定はコードを見ていただければと。

https://github.com/miyukikoga/ai-chat-bot/tree/v1.0.0

# 作り方
## Slack アプリを作成する

ngrok を使うので、**Event Subscriptions** の設定は bot 作成後に行います。

**Bot Token Scopes** は以下の二つでとりあえずは会話できるようになります。

- app_mentions:read
- chat:write

細かい点は違いますが、以下記事が分かりやすかったです:thumbsup:

https://qiita.com/odm_knpr0122/items/04c342ec8d9fe85e0fe9

## Bolt を使って Slack bot を作成する

Bolt は Slack アプリ開発のための公式フレームワークです。
これ使うとめちゃめちゃ簡単にボットが作れます。

https://slack.dev/bolt-js/ja-jp/tutorial/getting-started

※ Soketモードのやり方が書いてありますが、ngrok を使うので設定不要です。

## OpenAI API にリクエストする

[openai](https://www.npmjs.com/package/openai) ライブラリを使用します。

https://github.com/openai/openai-node#readme

OpenAIに登録していない場合はまずは登録から。

https://nicecamera.kidsplates.jp/help/feature/ai-kata/openapi_apikey/

## ngrok でサービスを公開する

ngrok はローカル PC 上で稼働しているサービスを外部公開できるサービスとのことで、めっちゃ便利です。

https://qiita.com/mininobu/items/b45dbc70faedf30f484e

作ったボットを起動させてサービスを公開します。


## Slack アプリに URL を登録する
ngrok で公開時に表示された URL（Forwardingの箇所です） をSlack アプリの **Event Subscriptions** に登録します。

同じページの **Subscribe to bot events** に必要な権限を設定して、保存します。

まだローカルで起動しているだけですが、これで Slack 上でツンデレ女子と会話できるようになっているはずです🎉

## WEB サーバーを作る

Fly.io で WEB サーバーを作ります。
公式ドキュメントの通りにやっていけばすぐにできます。

https://fly.io/docs/speedrun/

※無料枠で使いたい場合はメモリを 256MB に変更する必要があります。デフォルトでは1GBが設定されています。

Fly.io で作られた URL をSlack アプリに登録します。（ngrok の URL 設定した箇所を上書きます。）

これで全て完成です🎉

## その他

### 自動デプロイ

GitHub Actions で Fly.io　に自動デプロイする方法です。

https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/

## 最後に

こんなに簡単にできるとは...！って感じです。
ツンデレ女子以外にも猫ちゃんとか色々な子とおしゃべりできるので一人で楽しんじゃってます🤭

参考にさせていただた記事には感謝です:thumbsup:
ローカルにDBの環境を作成する

ローカル環境にSQL Serverをインストールし、SSMSでアクセスできるようにする手順をまとめました。

# 手順

1. SQL Serverをインストールする
1. ローカルの接続情報を取得する
1. SSMSをインストールする
1. SSMSでローカルのDBに接続する

# 1. SQL Serverをインストールする

以下のサイトから、SQL Serverをインストールします。

https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads

ダウンロードするのは右のExpressです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/9982d707-91dc-38a7-9dc7-d835e9037b0b.png)

インストーラがダウンロードされたら開きます。
左の「基本」を選択し、ライセンスに同意、インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/e32d7018-0835-350e-4641-6fc7ae6f0773.png)

# 2. ローカルの接続情報を取得する

ローカルにSQL Serverが作られたので、接続情報を取得します。
コマンドプロンプトを起動し、以下のコマンドを実行します。

```
sqllocaldb info
```

以下のように表示されるので、今回は一番上の「MSSQLLocalDB」をコピーしておきます。
![image_20240124_07.50.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/e63285ca-8cd2-623b-b5ae-eb41d1e6fc3c.png)

# 3. SSMSをインストールする

以下のサイトから、SQL Server Management Studio (SSMS)のインストーラをダウンロードします。

https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms

日本語が良い場合は少しスクロールし、以下の「日本語」リンクを踏みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/973088e8-ce64-a411-28f5-060b8cae6153.png)

インストーラがダウンロードされたら開き、インストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/401bcd1a-0c1e-7251-1931-f4f5e320a7cd.png)

# 4. SSMSでローカルのDBに接続する

インストールしたSSMSを開きます。
アプリ一覧の場合、「Microsoft SQL Server Tools 18 > Microsoft SQL Server Management Studio 18」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/c14256f3-a720-1581-441f-3bd642a1240c.png)

起動すると画像のようになっています。
![image_20240124_08.14.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/6e368c58-9ac2-d64e-431d-1e894f6e983d.png)

ローカルに接続するので、2. ローカルの接続情報を取得する で取得した「MSSQLLocalDB」を使って以下のように入力します。

サーバの種類：データベースエンジン（デフォルト）
サーバー名：(localdb)\MSSQLLocalDB
認証：Windows認証（デフォルト）
![image_20240124_08.19.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/c187de78-d7e7-74ba-dd35-bb3dea589e95.png)

そのまま「接続」を押すと、ローカルのDBにアクセスすることができます。
[EIP141] INVALIDオペコードの仕組みについて理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、の仕組みを提案している**EIP141**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-141

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

特定の「**命令**」を意図的に「**無効**」にするように指定します。

# 動機

「**無効な命令は、実行を中止する明確な理由として使用できる**」という文は、コンピュータプログラムやシステムにおいて重要なセキュリティ及び安全対策の1つを示しています。
プログラムが意図しない動作をする原因として、無効な命令が実行されることがあります。
このような無効な命令が検出された場合、システムはこれをエラーとみなし、プログラムの実行を安全に中止させることができます。
これにより、さらなる誤動作やデータの損失、システムの不安定化を防ぐことができます。
例えば、オペレーティングシステムやクリティカルなアプリケーションでは、このような安全対策が特に重要です。
無効な命令が検出されると、システムはエラーメッセージを表示し、プログラムの実行を中断するか、または適切なエラーハンドリング処理を行うことが一般的です。
このプロセスは、プログラムの信頼性を高めるために不可欠です。

# 仕様

オペコード`0xfe`は`INVALID`（無効）命令です。これは実行を中止するために使用できます（つまり、`ABORT`[中止]命令としての役割も果たします）。
オペコード（操作コード）とは、コンピュータプロセッサが実行する命令を指定するコードです。
`0xfe`という値を持つこのオペコードは、無効な操作を示していますが、同時にプログラムの実行を安全に中止させるための手段としても機能します。
これは、プログラムが予期しない状態に遭遇した時に、安全な方法で停止させるために設計された命令です。
プログラムがこのオペコードを実行すると、プログラムはエラー状態として中断され、これによりプログラムの安定性を保持したり、データ損失を防ぐことができます。
このような命令は、プログラムのエラーハンドリングや例外処理の戦略の一部として重要です。

:::note info
`INVALID`については以下の記事を参考にしてください。
:::

https://zenn.dev/heku/books/aef33b86ded3c0/viewer/27cd5d#invalid

# 互換性

この指示は使われたことがないため、過去のコントラクトには何の影響もないです。

# 引用

Alex Beregszaszi (@axic), "EIP-141: Designated invalid EVM instruction," Ethereum Improvement Proposals, no. 141, February 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-141.

# 最後に

今回は「」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
Code Serverのインストール (Ubuntu 22.04)

# Code Serverとは?
サーバーで使えるVSCodeみたいなものです

SSHなどで手元のVSCodeからサーバーにアクセスして操作する方が多いと思いますが、管理者権限が必要ななディレクトリの処理ができず、面倒なこともあります。

Webブラウザからアクセスするだけで、そのサーバー上の開発をVSCodeライクで出来るのでめちゃくちゃ便利です

## 環境
Ubuntu 22.04

## インストール
### Code Serverのインストール
```
sudo apt update
sudo apt upgrade
```

```
curl -fsSL https://code-server.dev/install.sh | sh
sudo systemctl enable --now code-server@$USER
```

## 設定
### Code Serverの起動確認
```
sudo systemctl start code-server@${USER}
```

### パスワードとポートの設定
標準は8080だが、今回は8090にしている
```
vim ~/.config/code-server/config.yaml

bind-addr: 192.168.xxx.xxx:8090 #サーバーのIPとポートの設定
auth: password
password: xxxxx   #任意のパスワードに
cert: false
```
### サービスの再起動
```
sudo systemctl restart code-server@${USER}
```

## 動作確認
ローカルのWebブラウザから入力したIPアドレスを入力
その後パスワードを聞かれるので入力
少し設定すればVS Codeに似た画面に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532124/53765adb-5510-d845-079d-f7f44db82542.png)

## 感想
最近はGitHub Copilotに慣れてしまっているため、Server側で動かしていることを忘れてて、コード生成されないことに戸惑うこともあった。

慣れは怖いです

短い記事で申し訳ありません
jQueryの読み込みについて

# はじめに
jqueryを記述できても読み込めていなければ使えないので、jqueryライブラリの読み込み方法についてまとめます。
# jQueryの読み込み
jQueryを使用するには、jQueryライブラリを読み込む必要があります。ライブラリはインターネット経由で読み込むのが一般的です。`<head>`タグの中で以下のようにURLを読み込むことで、jQueryが使用できるようになります。
```html
<head>
    <script src="https://...jquery.min.js"></script>
</head>
```
# jQueryファイルの読み込み
jQueryは、.jsファイルにコードを書きます。HTMLファイルで、`<script src="ファイルのURL"></script>`と書くことで、jQueryのコードを記述するファイルが読み込まれます。
`<script>`は、CSSファイルの読み込みのように`<head>`タグの中にもかけますが、`</body>`の直前に書くことで、WEBベー時の表示速度を速くすることができます。
```html
<body>

    //bodyの終了タグの直前で読み込む
    <script src = "script.js"></script>
</body>
```
# jQueryを使ったスクリプトの書き方
jQueryはHTMLの中身を操作するため、HTMLの読み込みが完了してからjQueryの操作を開始するようにします。
そのためにはreadyイベントを使用し、`$(document).ready()`の中身にjQueryの処理を書きます。また、この構文は`$function(){}`のように省略して書くことができ、省略形で書くことが一般的です。
```js
//基本的な書き方
$(document).ready(function() {
    //ここにjQueryを書く
});

//省略形
$(function() {
    //ここにjQueryを書く
});
```
流行りのパルワールドのサーバーを建てた (Ubuntu 22.04)

## はじめに
流行りのパルワールドについに手を出しました。パブリックサーバーが混みあってるらしく、友達にサーバー建ててほしい！と言われて建てました。よいPC使っちゃった

## 環境
|  | サーバースペック |
| :--- | :--- |
| CPU | AMD Ryzen 9 7900X3D |
| Memory | 96GB (DDR5) |
|SSD|2TB (m.2 PCIe5.0)
|OS| Ubuntu 22.04|

## やったこと
### SteamCMDのインストール
https://developer.valvesoftware.com/wiki/SteamCMD#Linux
```
sudo add-apt-repository multiverse; sudo dpkg --add-architecture i386; sudo apt update
sudo apt install steamcmd
steamcmd
```
SteamCMDコマンドが使えればOKです。quitでプロンプトが終了できます。

### パルワールドサーバーのセットアップ
https://tech.palworldgame.com/dedicated-server-guide
```
steamcmd +login anonymous +app_update 2394010 validate +quit
cd ~/Steam/steamapps/common/PalServer
```

このままだとsteamclient.soが無いとエラーが出るので対処
```
mkdir -p ~/.steam/sdk64/
steamcmd +login anonymous +app_update 1007 +quit
cp ~/Steam/steamapps/common/Steamworks\ SDK\ Redist/linux64/steamclient.so ~/.steam/sdk64/
```

### パルワールド サーバーの起動
オプション指定すると「マルチスレッドCPU環境において性能を向上させます。」と書かれているのでそのまま試した。
オプションの詳細が見つからないので正しいことがわからない。普通スレッド数とか指定しそうなものですが、、、

```
./PalServer.sh -useperfthreads -NoAsyncLoadingThread -UseMultithreadForDS
```
起動できたらCtrl+Cなどで一旦落としてよし

## ポート開放
構成としてはこんなイメージ。IPアドレス、ポートはもちろんフェイクです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532124/dd4a0952-70d3-14a5-971b-b2b38ca8ceaa.png)

### ルータのポートマッピング設定例
上記構成でAtermならこんな感じ

* LAN側ホスト: 192.168.10.3 (サーバーPCのIPアドレス)
* プロトコル: UDP (初期設定のままなら)
* 変換対象ポート番号: 61472 (任意)
* 宛先ポート番号: 8211 (初期設定のままなら)

### ufwの設定
ufwの確認と有効
```
sudo ufw status
sudo ufw enable
```
初期設定のまま設定した場合は8211/udpを許可
```
sudo ufw allow 8211/udp
sudo ufw reload
sudo ufw status
```


### アクセス方法
アクセスする友達には下記を教えてあげてください
* グローバルIP:61472 (上の変換対象ポート番号)

自分はローカルIPでアクセスします
* 192.168.10.3:8122

下のボックスに入力したらアクセスできます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532124/40b9e22a-cd0b-e4a4-5786-72ca2a849d4c.png)


## TIPS
### サーバーデータを消してやり直したいとき
適当にキャラメイクしたがやり直したかったのでいろいろ確認
とりあえずPalディレクトリのSavedディレクトリ消せばできた。ワールドごと消えるので注意
```
cd ~/Steam/steamapps/common/PalServer/Pal
sudo rm -r Saved
```

## 動作感
常時8人ぐらいアクセスして使ってみたが、特にラグはなかった
(ゲーム自体の問題でガクガクすることはあったが。。。)

今のままだと管理コマンド使えないので、次回書くならその辺を説明したいです
PyPy メモ化再帰でTLEを回避する方法

# 困ってる事

Nが大きい時、PyPyでメモ化再帰を使うとTLEになる。

# 解決策

再帰で呼び出す前に、メモに値があるかを調べて、関数の呼び出しを１回分減らすようにする。

次の様に自分自身を呼び出してる場合、
```Python
        ret += n(i-1,j,k)*i
```

メモに値がある場合は、メモを使い、ない場合は呼び出すようにする。
```Python
        ret += n(i-1,j,k)*i if dp[i-1][j][k] ==-1  else dp[i-1][j][k]*i
```

DPまとめコンテストのJを通したコード

```Python

dp = [[[-1]*(N+1) for _ in range(N+1)] for _ in range(N+1)]
dp[0][0][0] = 0

def n(i,j,k):
    ret = N
    if i>0:
        ret += n(i-1,j,k)*i if dp[i-1][j][k] ==-1  else dp[i-1][j][k]*i
    if j>0:
        ret += n(i+1,j-1,k)*j if dp[i+1][j-1][k] ==-1  else dp[i+1][j-1][k]*j
    if k>0:
        ret += n(i,j+1,k-1)*k if dp[i][j+1][k-1] ==-1  else dp[i][j+1][k-1]*k
    # print(i,j,k,ret)
    ret /= i+j+k
    dp[i][j][k] = ret
    return ret

cnt = Counter(A)
ans = n(cnt[1], cnt[2], cnt[3])
print(ans)
```

メモ化再帰ではない再帰の場合も再帰の末端の判定を再帰関数の最初に行うのではなく、再帰関数を呼び出すところに移動させると同様の効果があります。

bootstrapというのがあって、これを使うと高速化できるらしいので試そうかとおもってたんですが、この方法で、余裕でACできるコードになったので、記事にしてみました。

メモ化再帰は`@cache`で簡単に書きたい！けど、TLE回避の為には仕方ないですね。
Java / Google Drive APIでファイルをごみ箱に入れる方法

# 結論
```java
File file = new File();
file.setTrashed(true);
service.files().update(Id, file).execute();
```

以上。

# 補足

Python, Node.jsでの書き方は公式ドキュメントを参照されたし。https://developers.google.com/drive/api/guides/delete?hl=ja#python_1


すでにアップロードされているファイルを`service.files().get(Id)`で取得し、`.setTrash(true).execute()`として直接書き込むことはできない。やろうとすると以下のエラーが出る。
```json
{
  "code": 403,
  "errors": [
    {
      "domain": "global",
      "message": "The resource body includes fields which are not directly writable.",
      "reason": "fieldNotWritable"
    }
  ],
  "message": "The resource body includes fields which are not directly writable."
}
```

また、ファイルを削除したい場合は`service.files().delete(Id).execute()`でできるが、`service.files().trash(Id).execute()`は使えない。
【PostgreSQL】SELECTしてきた値をタイムゾーン補正を行い、指定したフォーマットで日付と時刻を変換する方法

## はじめに
DBからSELECTしてきた値をタイムゾーン補正を行い、指定したフォーマットで日付と時刻を変換する機会があったので、その方法をまとめておこうと思います。

 PostgreSQLでは動作確認済みですが、他のDBでは確認していないのでその点よろしくお願いします。

## 9時間マイナスする場合
 ```sample.sql
SELECT TO_CHAR(your_column_name::timestamp - INTERVAL '9 hours', 'YYYY-MM-DD"T"HH24:MI:SS') AS adjusted_date
FROM your_table_name;
 ```

 ## 9時間プラスする場合
 ```sample.sql
 SELECT TO_CHAR(your_column_name::timestamp + INTERVAL '9 hours', 'YYYY-MM-DD"T"HH24:MI:SS') AS adjusted_date
FROM your_table_name;
 ```

 ## 解説
 1. your_column_name::timestamp

値をtimestamp型に変換

 1. \- INTERVAL '9 hours'

取得したタイムスタンプから9時間マイナスする
UTCから JSTへ変換したいときは、9時間プラスしてあげれば良いです。
Android開発 FirebaseCrashlyticsの実装に少しつまづいた話 備忘録


FirebaseCrashlyticsをAndroidアプリに実装するにあたり、
公式ドキュメントを参考に進めていたのだが、、、

https://firebase.google.com/docs/crashlytics/get-started?hl=ja&platform=android#kotlin+ktx_1


```app/build.gradle
plugins {
    id 'com.android.application'

    // Make sure that you have the Google services Gradle plugin
    id 'com.google.gms.google-services'

    // Add the Crashlytics Gradle plugin
    id 'com.google.firebase.crashlytics'
    ...
}
```

これをどこに書けばいいのかわからなかった。


調べるとどうやら

```app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
```

を書き換えた状態らしい。

このpluginsの書き方は新しい書き方らしく、
https://plugins.gradle.org/
このリポジトリで利用可能である必要が必要があるそうだ。


参考
https://www.web-dev-qa-db-ja.com/ja/groovy/gradle%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%92%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84/1056004156/
【Unity】ノーコードでサイコロアプリを作ってみる（統計）

# これはなに？
Unity初心者がサイコロアプリを作るまでの過程をまとめた記事になります
アセット以外のところは、ビジュアルスクリプティングを利用して作成したいと思います

# 作ってみる
今回、作っていくのはコチラ
- 統計を更新する

ノーコードで作るのに、結構複雑になってしまったので更新と表示の説明をわけようと思います

完成した画面はコチラになります

![StatsView.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/dbed4149-8b85-cb23-8ecf-f58632fb5bba.png)

## 統計を更新する

グラフの表示の最大値を100％にしたいので、最大数を保持するようにしました
最大数の求め方ですが、出目が確定したときに、保持している最大数と比較して更新するようにしました

### やること
- Listを作成する
- Integerを作成する
- ビジュアルスクリプティング
    - 統計Dictを更新する
    - 最大値を更新する

#### Listを作成する

- 出た出目の出現回数を保存するためのリストオブジェクトを用意します

ビジュアルスクリプティングがあるオブジェクトの「インスペクター」パネルの「Variables」に「DictionaryDiceStats(Aot Dictionary)」を追加します

![StatsSave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/a9367c51-a58b-c063-6eec-f9a0287c3536.png)

- 端折ってますが、シーン開始時にGraphScriptで初期化しています
    - 初期化のために、サイコロの個数・面の数をシーン変数にしました

#### Integerを作成する

- もっとも出た出目の出現回数を保存するための数値オブジェクトを用意します

ビジュアルスクリプティング内の「Graph Variables」に「StatsMaxCount(Integer)」を追加します

![StatsGraphVariable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/e52ba796-dcd2-826d-5e06-943528c09fac.png)

#### ビジュアルスクリプティング

- 統計Dictを更新する
    - `Dictionary GetItem`ノードを利用します
        - Dictionary 参照元は`Get Variable`ノードで取得します
        - Key: この処理の前に結果を表示するためにString型の目の合計を渡します
        - Output: 統計Dictに格納されている出目の出現回数が返ってきます
    - `Add Inputs2`ノードでインクリメントします
    - `Dictionary SetItem`ノードを利用します
        - Dictionary 参照元は`Get Variable`ノードで取得します
        - Key: この処理の前に結果を表示するためにString型の目の合計を渡します
        - Value: `Add Inputs2`の結果を渡します

→出目の出現回数をDictに記録しました
![StatsScript1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/e631f380-598e-7d84-df63-50a338cbc38c.png)

- 最大値を更新する
    - `For Each Loop Dictionary`ノードを利用します
        - Dictionary 参照元は`Get Variable`ノードで取得します
        - Output Value: 統計Dictに格納されている出目ごとの出現回数が返ってきます
    - `Greater`ノードで最大値と比較します
        - A: `For Each Loop Dictionary`の`Output Value`
        - B: 最大値（参照元は`Get Variable`ノードで取得します）
    - `if`ノードで最大値を超えているかチェック
        - True: 超えている
    - `Set Variable`ノードで最大値を更新します

→これで出目の出現回数で一番多いのを記録しました
![StatsScript2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/d559679e-94f5-af73-a581-6255e06f74c1.png)

# さいごに
どうやってグラフを作ろうというのが苦戦した点です
普通のグラフみたいにしてしまうと、画面を突き出る恐れがあったので、グラフの幅を固定にしたくてこんな仕組みになりました

# 連載記事

https://qiita.com/acronhub/items/a46c6f5c16c4d262728c

https://qiita.com/acronhub/items/ccbdda267de28730d68e

https://qiita.com/acronhub/items/25d626d7ae2956942735

https://qiita.com/acronhub/items/7fa83565ffdd05576605

https://qiita.com/acronhub/items/7c3a39d384c0b6ea277c

https://qiita.com/acronhub/items/c273a54507b07a5937e3
【Linux】sshコマンドで別のサーバにSSH接続する

# 1.はじめに
どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏（にいくら）と申します♪
(/・ω・)/

備忘録的なものを投稿します。

Linux、みんな好きですよね。
先日Linuxのsshコマンドを使用して別のサーバにログインしました。

そこで今回は**Linuxのsshコマンドについて**記事にしたいと思います！
IT初心者の方、Linuxについて勉強中の方の参考になれば幸いです。
(*^^)v

# 2.sshコマンドとは
まず初めに、sshコマンドが何かについてですが
**「別のサーバにssh接続するコマンド」** となります。

基本的な使い方としては以下の様にsshの後ろに、
「接続先のユーザ名」と「接続先のIPアドレス」を指定します。

```:192.XXX.YYY.ZZZのサーバにuser2でssh接続するコマンド
ssh user2@192.XXX.YYY.ZZZZ
```

コマンドを実行した後はパスワードを聞かれるので、
ssh接続が完了します。

```:例
user1@server1:~$ ssh user2@192.XXX.YYY.ZZZ
user2@192.XXX.YYY.ZZZ's password:

user2@server2:~$
```

:::note info
上記の例ではCLIの表示が
```user1@server1:~$　→　user2@server2:~$```
に変化しており、SSH接続ができたことが確認できます。

不安な場合は「hostname」コマンド等で確認することもできます。
:::

## 2.1.ポートを指定する
sshコマンドでは接続先のポートを指定することができます。

具体的にはsshコマンド実行後に、
「-p （ポート番号）」を入力し、エンターキーを押します。

```:192.XXX.YYY.ZZZのサーバの1234番ポートに対して、user2でssh接続するコマンド
ssh user2@192.XXX.YYY.ZZZZ -p 1234 
```

# 3.おわりに
ここまで読んで下さり、ありがとうございます！！！
(^^)

今回もサクッと備忘録的な内容でしたが、sshコマンドについてまとめてみました。
次回も何かしら記事にします♪
(:3_ヽ)_
Ubuntu で特定の screen をグループ間で共有できるようにする

# はじめに
雑記です。許してね。
色々書こうかと思ってるけど、追記しないかも。許してね。

screen は事前にインストールされているものとするよ。

# 環境
Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-91-generic x86_64)

# まとめ
以下を行うと screen をグループ間で共有できるようになる。
```shell:Setup
sudo chmod u+s /usr/bin/screen
sudo chmod 755 /var/run/screen

# 0755 に書き換えちゃってもいいかも
sudo rm /etc/tmpfiles.d/screen-cleanup.conf
```

```shell:Exec_example
screen -dmS <session_name> <command>
/path/to/screen-addgrp.sh <group_name> <session_name>
```

```shell:/path/to/screen-addgrp.sh
#!/bin/bash
screen -p 0 -S $2 -X eval "multiuser on"

users=(`getent group $1 | cut -d ':' -f 4 | tr -s ',' ' '`)
for usr in "${users[@]}" ; do
        #echo "[ ${usr} ]"
        screen -p 0 -S $2 -X eval "acladd ${usr}"
done
```

他ユーザーで以下のようなコマンドを実行することでアタッチできる
```
screen -ls <owner_user>/               # セッション名を確認
screen -x <owner_user>/<session_name>  # アタッチ
```

## Systemd によって作り出す screen をグループ間で共有
`ExecStart` の部分を以下のような構造にする
```shell:in_hogehoge.service
ExecStart=/usr/bin/screen -DmS <session_name> /bin/sh -c '/path/to/screen-addgrp.sh <group_name> <session_name>;/path/to/start/<command> <argument_list>'
```

# 参考URL
https://qiita.com/coleyon/items/883eae4a8748513609df
内部結合・外部結合について

## 参考資料
https://ja.stackoverflow.com/questions/48789/idが紐づいている別テーブルのレーコード件数を取得したい/48804#48804

https://style.potepan.com/articles/26226.html

https://www.sejuku.net/blog/73003

https://www.sejuku.net/blog/54072
MySQL　CASE文

CASEを使用することで条件に当てはまるデータが登録されたレコードへ指定した表示ができる

```terminal:terminal
mysql> select name from users;
+--------+
| name   |
+--------+
| 佐藤   |
| 田中   |
| 渡辺   |
| 佐々木 |
+--------+
4 rows in set (0.00 sec)

SELECT カラム名, CASE WHEN 条件式 THEN 結果 ELSE 例外の表示 END FROM テーブル名;
select name, case when name = "田中" then "aaaaa" else null end from users;
mysql> select name, case when name = "田中" then "aaaaa" else null end from users;
+--------+----------------------------------------------------+
| name   | case when name = "田中" then "aaaaa" else null end |
+--------+----------------------------------------------------+
| 佐藤   | NULL                                               |
| 田中   | aaaaa                                              |
| 渡辺   | NULL                                               |
| 佐々木 | NULL                                               |
+--------+----------------------------------------------------+
4 rows in set (0.00 sec)
```
[C言語] atoiをゼロから書く

# ゼロからシリーズ
この記事はゼロからｃのライブラリを再実装するシリーズです。

# `atoi` の動作概要
atoi は `char *` 型の値を `int` 型の値へ変換するものです。

# 詳しい動作
- [appleの `atoi` ](https://opensource.apple.com/source/Libc/Libc-262/stdlib/atoi.c.auto.html)を参照すると `strtol` の `long` の値を `int` をキャストしているようです。
- [appleの `strtol` ](https://opensource.apple.com/source/Libc/Libc-825.25/stdlib/FreeBSD/strtol.c.auto.html)を参照すると詳しいことが見えてきそうです。
  - はじめのcharポインタから `isspace(3)` に準拠したスペースはすべて無視する仕様のようです。
    - `isspace(3)` **->** ` `, `\t`, `\n`, `\v`, `\f`, `\r`
  - はじめの空白を除いたcharポインタは `-` か `+` を１バイトだけ許容する仕様のようです。
  - 上記のcharポインタの次に複数の数字を`0`~`9`を許容するようで、数字でないものがcharポインタに入っているとそこで処理を抜ける仕様のようです。
  -  `char *` 型の値を `long` 型の値へ変換する際にlongをオーバーフローしたら `LONG_MAX` か `LONG_MIN` をreturnするようです。

# `atoi` 実装
### `isspace` 実装
```c
int	ft_isspace(char c)
{
	if (c == ' ' || c == '\t' || c == '\n'
		|| c == '\v' || c == '\f' || c == '\r')
		return (1);
	return (0);
}
```

### `long` のオーバーフロー検知を実装
```c
int	overflowl(int sign, long l, char next)
{
	if (sign == 1)
		if (LONG_MAX / 10 < l
			|| (LONG_MAX / 10 == l && LONG_MAX % 10 <= next - '0'))
			return (1);
	if (sign == -1)
		if (LONG_MIN / -10 < l
			|| (LONG_MIN / -10 == l && LONG_MIN % -10 * -1 <= next - '0'))
			return (-1);
	return (0);
}
```

### `atoi` を実装
```c
#include <limits.h>

int	ft_atoi(const char *str)
{
	long	ret;
	int		sign;

	ret = 0;
	sign = 1;
	while (ft_isspace(*str))
		str++;
	if (*str == '-' || *str == '+')
		if (*str++ == '-')
			sign = -1;
	while (*str)
	{
		if ('0' <= *str && *str <= '9')
		{
			if (overflowl(sign, ret, *str) == 1)
				return ((int)LONG_MAX);
			if (overflowl(sign, ret, *str) == -1)
				return ((int)LONG_MIN);
			ret = ret * 10 + (long)(*str - '0');
			str++;
		}
		else
			break ;
	}
	return ((int)(ret * sign));
}
```

# まとめ
今回はatoiをゼロから再実装しました。
<details><summary>All in one code</summary>

```c
#include <limits.h>

int	ft_isspace(char c)
{
	if (c == ' ' || c == '\t' || c == '\n'
		|| c == '\v' || c == '\f' || c == '\r')
		return (1);
	return (0);
}

int	overflowl(int sign, long l, char next)
{
	if (sign == 1)
		if (LONG_MAX / 10 < l
			|| (LONG_MAX / 10 == l && LONG_MAX % 10 <= next - '0'))
			return (1);
	if (sign == -1)
		if (LONG_MIN / -10 < l
			|| (LONG_MIN / -10 == l && LONG_MIN % -10 * -1 <= next - '0'))
			return (-1);
	return (0);
}

int	ft_atoi(const char *str)
{
	long	ret;
	int		sign;

	ret = 0;
	sign = 1;
	while (ft_isspace(*str))
		str++;
	if (*str == '-' || *str == '+')
		if (*str++ == '-')
			sign = -1;
	while (*str)
	{
		if ('0' <= *str && *str <= '9')
		{
			if (overflowl(sign, ret, *str) == 1)
				return ((int)LONG_MAX);
			if (overflowl(sign, ret, *str) == -1)
				return ((int)LONG_MIN);
			ret = ret * 10 + (long)(*str - '0');
			str++;
		}
		else
			break ;
	}
	return ((int)(ret * sign));
}
```
</details>
Mysqlでのdamp作成

## damp作成
```
◆dump作成
mysqldump -u ユーザー名 -p -h ホスト名 DB名 > 出力ファイル名
mysqldump -u root -p -h localhost test > C:\dump\sample.dump

◆テーブル指定
mysqldump -u ユーザー名 -p DB名 テーブル名 > 出力ファイル名
// 単一
mysqldump -u root -p test users > C:\dump\users.dump

mysqldump -u ユーザー名 -p DB名 テーブル名1 テーブル名2 > 出力ファイル名
// 複数
mysqldump -u root -p test users users2 > C:\dump\users11.dump

◆テーブルデータのみ(-t オプションを付ける)
mysqldump -u root -p test users -t> C:\dump\users.dump
```

## damp復元
```
mysql -u ユーザー名 -p DB名 < 読み込むdumpファイル名
mysql -u root -p test < C:\dump\sample.dump
```

## 実際に動かしてみる
```terminal:terminal
DBを作成
mysql> create database test;
Query OK, 1 row affected (0.02 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| localdb            |
| mysql              |
| performance_schema |
| sakila             |
| sys                |
| test               |
| world              |
+--------------------+
8 rows in set (0.00 sec)

mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)

テーブルを作成し、データを挿入
mysql> CREATE TABLE users (id INT AUTO_INCREMENT, name TEXT, PRIMARY KEY (id));
Query OK, 0 rows affected (0.07 sec)
mysql> insert into users value(1,"佐藤");
Query OK, 1 row affected (0.01 sec)
mysql> insert into users value(2,"田中");
Query OK, 1 row affected (0.01 sec)
mysql> insert into users value(3,"渡辺");
Query OK, 1 row affected (0.01 sec)
mysql> insert into users value(4,"佐々木");
Query OK, 1 row affected (0.01 sec)

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| users          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | 佐藤   |
|  2 | 田中   |
|  3 | 渡辺   |
|  4 | 佐々木 |
+----+--------+
4 rows in set (0.00 sec)
```

* dumpファイルを作成
```
C:\>mysqldump -u root -p -h localhost test > C:\dump\sample.dump
Enter password: ****
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/7740db4a-0527-8450-36f7-97a62e9e13cf.png)

* 先程作成したテーブルを削除
```terminal:terminal
mysql> drop table users;
Query OK, 0 rows affected (0.03 sec)
mysql> show tables;
Empty set (0.00 sec)
```

* dumpファイルを読み込む
```
C:\>mysql -u root -p test < C:\dump\sample.dump
Enter password: ****
```

* 確認
```terminal:terminal
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| users          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | 佐藤   |
|  2 | 田中   |
|  3 | 渡辺   |
|  4 | 佐々木 |
+----+--------+
4 rows in set (0.00 sec)
```

## 参考
https://qiita.com/PlanetMeron/items/3a41e14607a65bc9b60c#%E3%81%9D%E3%81%AE%E4%BB%96%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3
ProxmoxでZFSを組むと謎に多く容量を食う時のトラブルシューティング

# 解決方法
データセンター→ストレージ→対象のZFS→Thin プロビジョニングにチェックを入れる
あとから有効にした場合は
```
datasets=$(zfs list -H -o name); for dataset in $datasets; do zfs set refreservation=none $dataset; done;
```

を実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314743/909ec5c0-dbac-5824-f498-2f950b2a3cb1.png)

# Thin プロビジョニングとは？
ディスクを作成した際に、VMとProxmoxにはフルに使っていると見せかけて実際にはディスク側で使った容量だけしかZFSディスクを消費しない状態です。
この状態では、次のメリットとデメリットがあります。
- メリット
  - ディスクの空き容量をあまり考慮しなくて済む
  - 実際に逼迫してきたときに追加するだけで良い
- デメリット
  - 実際の空き容量に対して過剰にディスクをデプロイできてしまうので場合によってはデータを失う可能性がある(要監視)
  - (多分)耐障害性が落ちてる(気がする)

検証環境目的での利用などに留め、本番や重要なマシンではあまり使わないほうがいいかもしれません。
それかLVM使うか…
GitHubでプルリクエスト

* 「Compare & pull request」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/e867804e-e8e6-d972-045d-59f54e43aa7b.png)

* 「Add a description」に必要な情報を入力後、「Create pull request」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/0a1ea5a4-3578-bb11-ad79-a8460c8b8cd9.png)

* 「Merge pull request」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/2851dda1-e85e-d5ac-bda7-9e4cb29c504b.png)

:::note info
**※マージの種類について**
`` ・Merge Commit（マージコミット） ``
これは最も一般的なマージ方法で、プルリクエストの全てのコミットをメインブランチにマージします。
このプロセスはマージコミットを生成し、プルリクエストのコミット履歴がそのままメインブランチに追加される。

``・Squash and Merge（スカッシュマージ） ``
この方法では、プルリクエスト内の全てのコミットが1つのコミットに統合されてからメインブランチにマージされる。
これにより、履歴が綺麗に保たれ、不要な中間コミットが除去されますが、個々のコミットの詳細は失われる。

``・Rebase and Merge（リベースマージ） ``
この方法では、プルリクエストのコミットがメインブランチの最新コミットの上に再配置（リベース）されてからマージされる。
これにより、リニアなコミット履歴が保たれますが、リベースの過程でコンフリクトが発生する可能性がある。
:::

* 「Confirm merge」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/ffa56bed-80d2-f796-8eb3-e656ac399a9f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/947326cb-9dee-0628-8dc2-755a494a3a25.png)


## 補足
* 「Delete branch」を押下するとブランチを削除出来る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/947326cb-9dee-0628-8dc2-755a494a3a25.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2981742/42e66701-335e-20b0-9e70-0e14b85b1137.png)


## 参考
https://style.potepan.com/articles/33561.html

https://dev.classmethod.jp/articles/pull-request-template/
IDCAMSの活用：VSAMデータセットの効率的な管理

## IDCAMSの活用：VSAMデータセットの効率的な管理
IDCAMSは、メインフレーム環境におけるVSAM（仮想ストレージアクセス方式）データセットの管理に不可欠なユーティリティです。このツールは、VSAMデータセットの定義、削除、コピー、および再構築を行うために広く使用されています。

### IDCAMSの主な機能
IDCAMSを使用することで、以下のような多様な操作が可能です。

VSAMデータセットの定義: 新しいVSAMデータセットを定義し、構成します。
データセットの削除: 不要になったVSAMデータセットを削除します。
データセットのコピー: 他のデータセットからVSAMデータセットへデータをコピーします。
データセットの再構築: 破損したデータセットを修復します。
使用例
以下は、VSAMデータセットを作成し、その後でデータをコピーする一般的なJCLコードの例です。

```
//DEFJOB JOB (ACCT),'DEFINE JOB',CLASS=A,MSGCLASS=X
//STEP01  EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=A
//SYSIN    DD *
  DEFINE CLUSTER(NAME(your.vsam.dataset) -
  VOLUMES(XXXX) -
  TRACKS(10 5) -
  INDEXED -
  KEYS(11 0) -
  RECORDSIZE(80 80)) -
  DATA(NAME(your.vsam.dataset.data)) -
  INDEX(NAME(your.vsam.dataset.index))
/*
```
この例では、新しいVSAMデータセット your.vsam.dataset を定義しています。データセット名、ボリューム、トラック数、キーの長さなどは状況に応じて適切に置き換えてください。

### 注意点
VSAMデータセットの操作は複雑であり、誤った操作はデータ損失につながる可能性があるため、使用する際は注意が必要です。特に新しいデータセットの定義には、システムの容量や構成に合わせたパラメータ設定が必要です。

VSAMファイルの作成とデータコピーを行うJCL
VSAMデータセットの作成後、データをコピーするためのJCLは以下のようになります。

```
//COPYJOB JOB (ACCT),'COPY VSAM',CLASS=A,MSGCLASS=X
//STEP01  EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=A
//SYSIN    DD *
  REPRO INFILE(your.input.dataset) OUTFILE(your.vsam.dataset)
/*
```
このJCLでは、非VSAMデータセット your.input.dataset から先ほど定義したVSAMデータセット your.vsam.dataset へデータをコピーしています。入力ファイルと出力ファイルのデータセット名は、それぞれの環境に応じて変更してください。

IDCAMSとこれらの操作は、データ管理の柔軟性と効率性を提供しますが、使用する際は慎重に行う必要があります。
ADRDSSU MOVE機能でデータセットの格納VOLUMEを移動

## ADRDSSU MOVE機能でデータセットの格納VOLUMEを移動
### ADRDSSUユーティリティについて
ADRDSSU（DFSMSdssの一部）は、IBMメインフレームで使用される強力なバックアップとリストアユーティリティです。このツールは、データセットのバックアップ、リストア、コピー、移動など、多くのデータ管理タスクを実行するために使用されます。今回は、特にMOVE機能に焦点を当てます。

### データセットの格納VOLUMEの移動
ADRDSSUのMOVE機能を使用して、データセットを一つのVOLUME（記憶装置）から別のVOLUMEに移動するJCL例を以下に示します。

```
//MOVEJOB  JOB (ACCT),'MOVE JOB',CLASS=A,MSGCLASS=A
//STEP01   EXEC PGM=ADRDSSU
//SYSPRINT DD  SYSOUT=A
//SYSIN    DD  *
  MOVE DSNAME(INCLUDE(your.dataset.name)) -
      OUTDYNAM(NEWVOL)
/*
```
このJCLは、your.dataset.nameというデータセットを現在の格納VOLUMEからNEWVOLという新しいVOLUMEに移動します。SYSPRINTは、操作のログやメッセージを出力するためのデータセットです。SYSINセクションでは、移動するデータセットとその目的地を指定します。

注意点
ADRDSSUを使用する際のいくつかの注意点:

- 正確な指定: 移動するデータセット名は正確に指定する必要があります。不正確な指定は、予期しない結果を招く可能性があります。
- VOLUMEの確認: 移動先のVOLUMEは、十分な容量があること、そしてアクセス可能であることを事前に確認してください。
- バックアップの取得: 移動操作を行う前に、対象のデータセットのバックアップを取っておくことを推奨します。万が一の事態に備えるためです。
IEBGENERの活用：データセット操作の基本

## IEBGENERの活用：データセット操作の基本
IBMメインフレーム上でのデータセット操作には、IEBGENERという強力なユーティリティがよく使用されます。これは、データセットのコピー、作成、変換を行うための多目的ユーティリティです。

### IEBGENERの主な機能
IEBGENERを使用することで、以下のような多様な操作が可能です。

- データセットのコピー: 一つのデータセットから別のデータセットへデータをコピーします。
- データセットの作成: 新しいデータセットを作成し、特定の情報を書き込むことができます。
- データ形式の変換: データセットのレコードフォーマットを変更する際に使用します。
使用例
以下は、IEBGENERを使用してデータセットをコピーする一般的なJCLコードの例です。

```
//COPYJOB JOB (ACCT),'COPY JOB',CLASS=A,MSGCLASS=X
//STEP01  EXEC PGM=IEBGENER
//SYSUT1  DD DSN=your.input.dataset,DISP=SHR
//SYSUT2  DD DSN=your.output.dataset,DISP=(NEW,CATLG,DELETE),
//        SPACE=(TRK,(10,5),RLSE),UNIT=SYSDA
//SYSPRINT DD SYSOUT=A
//SYSIN    DD DUMMY
```
この例では、your.input.datasetからyour.output.datasetへデータをコピーしています。データセット名は状況に応じて適切に置き換えてください。

### 注意点
IEBGENERは非常に強力なツールですが、誤った使用はデータ損失につながる可能性があるため、使用する際は注意が必要です。

### OSコマンドを発行するJCL
OSコマンドを実行するためのJCLは、IBMメインフレーム上での操作に依存します。一般に、メインフレーム環境では、JCLを使用して直接的にOSコマンドを実行することは一般的ではありません。しかし、特定のユーティリティやプログラムを介して間接的にコマンドを実行することは可能です。

例えば、REXXスクリプトやCLISTを使用してコマンドを実行し、そのスクリプトをJCLから呼び出す方法が考えられます。以下に一例を示します。

```
//CMDJOB JOB (ACCT),'CMD JOB',CLASS=A,MSGCLASS=X
//STEP01  EXEC PGM=IKJEFT01,DYNAMNBR=20,REGION=0M
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
  %your_rexx_script
/*
```
この例では、IKJEFT01（TSO環境を提供するプログラム）を使用して、REXXスクリプト（your_rexx_script）を実行しています。このスクリプト内でOSコマンドが実行されることになります。スクリプト名は、実際のスクリプトに合わせて変更してください。

注意点として、メインフレームの環境や構成によっては、上記の方法が利用できない場合があります。そのため、特定の環境での使用については、システム管理者や経験豊富なメインフレームオペレーターに相談することをお勧めします。
TSのinterfaceをJSONスキーマに変換する(VSCode拡張)

しょーもない記事ばかりすみません。記憶力低下とノウハウ散逸の対策でここに全部書くって決めたんです……。

## 目的

TypeScript で、 JSON 形式の手作り設定ファイルを読み込むと何もかも `any` で気持ち悪いので インターフェースを定義して `as` してみる→

+ キーがサジェストされる（インテリセンス）ようになる
+ 値の型が決まる

でも、ほんとうに値が入っていて望みの型になっているか分からない
→拡張で解決！

+ JSON記入時にサジェストされ、キーの不足や名前誤り、書式不正が指摘される

→バリデーションしなくてすむ！（スキーマ使ってバリデーションしろパッケージあるから）

## VSCode 拡張のインストール
[Typescript JSON schema generator - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=marcoq.vscode-typescript-to-json-schema)

## 使用手順

1. 設定
  `settings.json` に設定を追加する。 
   + `json.schemas`  
     対象ファイル（globっぽく `*,**,!` が使える[^1]）とスキーマファイルの組を指定。これは拡張ではなくVSCode標準の設定。
   + `generateJSONSchema.jsDoc`
     `extended` にすると JSDoc の説明がインテリセンスに表示される。
   + `generateJSONSchema.additionalProperties`  
      定義されてないキーを書くのを許可するかどうか。継承先の項目まであえて管理しないとか、コメント用キーを許してあげたいなど用途に応じてどうぞ。

   ```json
   {
     "json.schemas": [
       {
         "fileMatch": ["config/example/*.json"],
         "url": "./config/schema/schema-example.json"
       },
     ],
     "generateJSONSchema.jsDoc": "extended",
     "generateJSONSchema.additionalProperties": true
   }
   ```

1. スキーマ生成
  目的のインターフェースが書かれている `.ts` ファイルを開き、コマンド `Generate JSON Schema for type...` を実行し数秒待つ
1. 保存
  スキーマが出力されるので、そのへんに `.json` ファイルとして格納する

## 応用

### 各種制約の定義

[JSON Schema](https://json-schema.org/understanding-json-schema/reference) で使用されるキーワードを JSDocにタグ（`@xxx`）として記述すると、それがスキーマに書き込まれる。数値なら最大値であったり、文字列なら長さや書式（URLや日付）であったりを制限できる。ただし、 `@type` は使えない[^2]。

```ts:typescript-json-schema の README 引用・一部改変
export interface Shape {
    /**
     * The size of the shape.
     *
     * @minimum 0 ←最小値
     * @maximum 10 ←最大値
     * @TJS-type integer ←効きません
     */
    size: number;
}
```

### 整数の制約をつくりたい

`@multipleOf 1` とすれば 1 刻みの数すなわち整数とすることができる。
いちいちJSDocを書きたくないのであれば、

```ts
/**
 * 整数
 * @multipleOf 1
 */
type integer = number;

// とか

/**
 * 自然数
 * @multipleOf 1
 * @minimum 0
 */
type natural = number;
```

を定義して目的のプロパティの型を `integer` 等に置き換えてしまえば良い[^3]。

## 改修時の注意

スキーマの変更は自動反映されない(場合がある？)。 VSCode を再起動するか、 `json.schemas` の `url` あたりをいじって保存すると再読込される。 `JSON: Clear Schema Cache` というそれっぽいコマンドがあるが、効かない。 [^4]

[^1]: 説明文にはワイルドカードが使えるよ、とは書いてあるが、 glob が使えるとは書いてない。でもそうか、 glob って一言に言ってもたくさん実装があるから、使える記号が定まらないよね。
[^2]: `@type` が使えたら使えたでプログラムのほうがおかしなことになるので仕方ない。この拡張は内部で [ts-json-schema-generator](https://github.com/vega/ts-json-schema-generator) という npm ツールを使っており、さらにこれは [typescript-json-schema](https://github.com/YousefED/typescript-json-schema) という npm パッケージをもとに作られているので、細かい挙動はリンク先を参照。 `type` 使えない問題のワークアラウンドが本家にはあるが移植されていないので注意。
[^3]: 型のエイリアスを作る方法は本家でも紹介されているけど、アノテーションを使わないとうまく行かなかったので形を変えてご紹介。
[^4]: [VSCode の GitHub で提起されたけど新機能リクエスト扱いされてた](https://github.com/microsoft/vscode/issues/170612) ので仕様です。
IEHPRGMの活用：メインフレームデータセットの効率的管理

## IEHPRGMの活用：メインフレームデータセットの効率的管理
IBMメインフレームで使用されるIEHPRGMは、データセットやデータセットの一部を効果的に削除するための重要なユーティリティです。このツールは、特に大規模なシステムでのデータ管理において不可欠です。

## IEHPRGMの主な機能
IEHPRGMは、以下のような様々なタスクに使用されます。

- データセットの完全削除: 不要になったデータセットをシステムから完全に削除します。
- データセット内の特定部分の削除: データセット内の特定のレコードやセクションを削除することが可能です。
- 破損したデータセットの処理: 破損または不整合を含むデータセットを削除し、システムの整合性を保ちます。
使用例
以下は、IEHPRGMを使用してデータセットを削除する一般的なJCLコードの例です。

```
//JOBNAME JOB (ACCT),'NAME',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP01 EXEC PGM=IEHPRGM
//SYSPRINT DD SYSOUT=A
//SYSUT1 DD DSN=your.dataset.name,DISP=(MOD,DELETE,DELETE)
```
このコードは、指定されたデータセット your.dataset.name を削除します。重要なのは、データセット名を自分の状況に合わせて適切に変更することです。

### 注意点
IEHPRGMを使用する際には、削除するデータセットを慎重に選択する必要があります。一度削除されたデータは復元できないため、誤って重要なデータを失うリスクがあります。

### メンバー名を変更するJCL
JCL自体には直接的にファイルやメンバーの名前を変更するコマンドはありませんが、IEBCOPYを使用してメンバーをコピーし、新しい名前を与えることで実質的に名前の変更が可能です。以下はその一例です。

```
//JOBNAME JOB (ACCT),'NAME',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP01  EXEC PGM=IEBCOPY
//SYSPRINT DD SYSOUT=A
//SYSUT1   DD DSN=your.original.dataset,DISP=SHR
//SYSUT2   DD DSN=your.target.dataset,DISP=OLD
//SYSIN    DD *
  COPY OUTDD=SYSUT2,INDD=SYSUT1
  SELECT MEMBER=(OLDNAME,NEWNAME)
/*
```
このJCLは、your.original.datasetの中のOLDNAMEというメンバーを、your.target.datasetにNEWNAMEとしてコピーします。これにより、実質的にメンバー名が変更されます。ただし、元のメンバーはそのまま残りますので、必要に応じて削除する操作を追加する必要があります。
IEBCOPYユーティリティと使い方

### IEBCOPYユーティリティについて
IEBCOPYは、IBMのメインフレームシステムで使用されるユーティリティプログラムで、パーティションド・データセット（PDS）またはパーティションド・データセット・エクステンデッド（PDSE）のメンバーのコピー、削除、圧縮などを行います。このユーティリティは、データセットのメンテナンス作業に不可欠です。

### メンバーのコピー
IEBCOPYを使用して、あるPDSから別のPDSへメンバーをコピーする一般的なJCL例を以下に示します。

```
//COPYJOB  JOB (ACCT),'COPY JOB',CLASS=A,MSGCLASS=A
//COPY01   EXEC PGM=IEBCOPY
//SYSPRINT DD  SYSOUT=A
//INDD     DD  DSN=your.input.dataset,DISP=SHR
//OUTDD    DD  DSN=your.output.dataset,DISP=OLD
//SYSIN    DD  *
  COPY OUTDD=OUTDD,INDD=INDD
  SELECT MEMBER=(COPY1,COPY2),ACTION=COPY
/*
```
この例では、your.input.datasetからyour.output.datasetへCOPY1とCOPY2というメンバーがコピーされます。SYSPRINTは、ジョブのログやメッセージを出力するためのデータセットです。SYSINセクションでは、コピーするメンバーとそのアクションを指定します。

### 注意点
IEBCOPYの使用にはいくつかの注意点があります。

データセットの指定: 入力と出力のデータセットは正しく指定する必要があります。間違ったデータセット名を指定すると、予期しない結果になる可能性があります。
データセットの状態: コピー先のデータセットはDISP=OLDでオープンすることが一般的です。これにより、そのデータセットが使用中でないことが保証されます。
メンバーの選択: SELECTステートメントを使用して、特定のメンバーのみをコピーすることができます。すべてのメンバーをコピーする場合は、このステートメントを省略できます。
IBM JCLとIEFBR14ユーティリティの概要

### IBM JCLとIEFBR14ユーティリティの概要
## JCL（Job Control Language）とは
JCLは、IBMのメインフレームシステムでジョブを制御するためのスクリプト言語です。JCLは、ジョブの実行に必要なデータセットやプログラムの指定、実行順序の制御などを行います。

## IEFBR14ユーティリティの説明
IEFBR14は、非常にシンプルなIBMユーティリティプログラムです。このプログラムは何も操作を行わず、ただ終了コード0を返すだけの機能を持っています。しかし、JCLのステップで使用されると、データセットの作成、削除、またはカタログ登録などの重要な役割を果たします。

## 使用例
IEFBR14を使用して、データセットを作成または削除するJCLの一般的な例を以下に示します。

データセットの作成
```
//STEP1    EXEC PGM=IEFBR14
//DD1      DD  DSN=your.dataset.name,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(TRK,(1,1),RLSE),
//            DCB=(LRECL=80,BLKSIZE=800,RECFM=FB)
```
このJCLスニペットでは、新しいデータセットが作成され、カタログに登録され、使用後に削除されます。

データセットの削除
```
//STEP1    EXEC PGM=IEFBR14
//DD1      DD  DSN=your.dataset.name,
//            DISP=(MOD,DELETE,DELETE)
```
ここでは、既存のデータセットを削除します。DISP=(MOD,DELETE,DELETE)は、データセットが存在する場合はそれを変更し、存在しない場合は新しく作成してから削除します。

POファイルの再作成
PO（Partitioned Organization）ファイルを再作成するためのJCLの例を以下に示します。

```
//RECREATE EXEC PGM=IEFBR14
//DD1      DD  DSN=your.po.dataset.name,
//            DISP=(MOD,DELETE,DELETE),
//            SPACE=(CYL,(1,1),RLSE),
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=800)
//DD2      DD  DSN=your.po.dataset.name,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(1,1),RLSE),
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=800)
```
このJCLでは、最初にPOファイルを削除し（存在する場合）、次に新しいPOファイルを作成します。
JCLマスターガイド：主要ユーティリティIEFBR14、IEBCOPY、IEHPRGM、IEBGENER、ADRDSSU、IDCAMSの解説

# JCLマスターガイド：主要ユーティリティIEFBR14、IEBCOPY、IEHPRGM、IEBGENER、ADRDSSU、IDCAMSの解説

JCL（Job Control Language）はIBMメインフレームで使用されるスクリプト言語で、ジョブの実行を制御します。以下では、JCLで使われるいくつかの主要なユーティリティについて解説します。

## 1. IEFBR14
- **概要**: IEFBR14は、実質的に何もしないユーティリティです。データセットの作成や削除、またはカタログのエントリを管理するために使用されます。
- **使用例**: 新しいデータセットを作成、既存のデータセットを削除、またはデータセットの属性を変更。

## 2. IEBCOPY
- **概要**: IEBCOPYは、PDS（パーティション化されたデータセット）やPDSE（パーティション化されたデータセット拡張）のコピー、圧縮、管理に使用されます。
- **使用例**: データセット間でメンバーをコピー、不要なメンバーを削除してデータセットを圧縮。

## 3. IEHPRGM
- **概要**: IEHPRGMは、データセットやデータセットの一部を削除するためのユーティリティです。
- **使用例**: 不要になったデータセットや破損したデータセットの削除。

## 4. IEBGENER
- **概要**: IEBGENERは、データセットのコピー、作成、または変換を行う汎用ユーティリティです。
- **使用例**: データセットから別のデータセットへのデータコピー、データセットのフォーマット変更、レコードの生成。

## 5. ADRDSSU MOVE
- **概要**: ADRDSSUは、データセットのバックアップ、復元、および移動を行うユーティリティです。「MOVE」オプションは、データセットを異なる場所に移動する際に使用されます。
- **使用例**: システムの再構成やメンテナンスのためにデータセットを別のストレージデバイスに移動。

## 6. IDCAMS
- **概要**: IDCAMSは、VSAM（仮想ストレージアクセス方式）データセットの管理に使用されるユーティリティです。
- **使用例**: VSAMデータセットの定義、削除、コピー、再構築など。

JCLとこれらのユーティリティの詳細な使用法や機能については、IBMの公式ドキュメントや専門書を参照してください。この記事が、JCLのユーティリティについての基本的な理解を深めるのに役立つことを願っています。