OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsのバージョンが低すぎてQiita CLIでエラー出した件

# Qiita CLI を使う前に Node.js のバージョンを確認しよう

PM試験の記事を書こーと思ってQiita見たら[Qiita CLI](https://qiita.com/Qiita/items/32c79014509987541130)というのがあるじゃないの、これは便利、ということで諸々設定して使おうとしたら、

```bash
npx qiita login
(中略)
Qiita APIへのリクエストでネットワークエラーが発生しました
  インターネットに接続されているかご確認ください
```

えええ？？トークンが払い出せてるというかQiitaが見られているってことはインターネットは接続できてるはずだけど？と思いながらChatGPT 4oにエラーメッセージぺたーで相談。

「node-fetchインストールしましたか？」と訊かれたのでとりあえずインストール。エラーメッセージ変わらず。

IssueやDiscussionを見ても特にこのエラーメッセージが生えた人は居ないということはおそらくパッケージではなくおま環問題と判断。

Node.jsとか知らんしこれはもう物理で (普通にプラットフォーム上で) 書くしか無いか... と思い、ふと[README](https://github.com/increments/qiita-cli?tab=readme-ov-file#1-%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99)を見て気づきました。

**Qiita CLI を使うには Node.js 18.18.0 以上が必要です。**

たーぶんこれじゃないか？そもそもいつの間にか`npm`とか使えるようになってるけどインストールした経緯覚えてないくらいだしこれはアプデもしてませんわ、と思ってChatGPTにNode.jsのバージョン確認方法を訊いて実行。

```bash
node --version
v17.9.0
```

全然足りてなかった！！ということでバージョンアップの方法もChatGPTにご相談。

```bash
nvm install --lts
```

```bash
Installing latest LTS version.
Downloading and installing node v20.18.0...
Downloading https://nodejs.org/dist/v20.18.0/node-v20.18.0-darwin-arm64.tar.xz...
############################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v20.18.0 (npm v10.8.2)
```

もう一度！

```bash
npx qiita login
(中略)
Hi Daku-on!

ログインが完了しました 🎉
以下のコマンドを使って執筆を始めましょう！
```

よっしゃあ！

ということでこの記事のpublishに至るわけです。ちゃんちゃん。

## 後日談

と思ったらタグのQiita CLIのスペースを入れてしまったことでGitHub Actionsが回らなくて大変焦りました。
JLCPCBで基板発注しました

## はじめに

東京農工大学 ロボット研究会R.U.Rで回路やってる人です。
高専3年の時のロボコンを最後に、もうロボコンには関わらないと思っていましたが大学でもロボコンサークルに入ってしまいました。

弊サークルではJLCPCB様に基板制作費用の一部をご支援いただいております。
今回はJLCPCBでの基板発注の様子と感想を書いていこうと思います。

# JLCPCBについて
![image-644x139.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/ffc0e6bb-ae58-c74e-52ae-66303e1f1e04.png)

https://jlcpcb.com/jp/

JLCPCBは中国に本社を置く企業で、世界中で180以上もの国や地域との取引実績を持っており、年間のPCB製造数は600万枚を超える企業です。個人で基板発注を行うことができる数少ない会社の一つであり、WEBで見積もりが完結することや、国内の企業に比べて非常に安価な価格で基板を作ることができる点が特徴です。

100mm * 100mm以内、FR-4、緑の基板であれば、もはや2層基板だろうが4層基板だろうが値段は変わりません。$2.00で発注できます。
送料は$20程度かかってしまうのですが、それが気にならない位の安さです。

高専在学中にもJLCPCBで基板発注したことがありました。
基板色で黒を選択すると他の基板メーカーと違って艶消し黒になるのでかっこよかった思い出があります。

# 発注してみよう
今回発注するのはサーボ基板です。サーボモーター動かすだけなので何の面白みもないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/90877e88-afe6-acb3-77b2-480472b45323.png)
ガーバーファイルはいい感じに生成しておきます。
できあがったガーバーファイルをzipでまとめ、JLCPCBのHPにアップロードするとこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/4907a10a-dbac-841e-4359-b60f031dc1bc.png)

Gerber Viewerで確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/aac0b575-1213-e210-301d-42372c00d558.png)

最近はGerber Viewerだけでなく、オンラインDFMツールまで提供されています。
すごいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/8a958297-3ee0-fdcb-dd2a-c61a9118f473.png)

JLCPCBのHPにガーバーファイルをアップロードし、SAVE TO CARTして支払いなど諸々済ませれば発注完了です。
最近はJLCMCの部品もまとめて発注できるので、送料を安く済ませたい方はぜひ。

# 届いた基板
大体一週間くらいで届きました。
綺麗に製造されていていい感じです。
最近だと無料で製造番号を消してくれるみたいです。(発注後に気づいた)

![IMG_20241011_180901.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/d8a83297-8145-d6a8-9add-65f9d9db6a4b.jpeg)

実装したらこんな感じ
![IMG_20241011_180743.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3061626/54c40498-372e-b6fd-fcd8-8d66668e3360.jpeg)

# さいごに
改めてになりますが、東京農工大学ロボット研究会R.U.RではJLCPCB様に基板製作費用の一部をご支援頂いております。
この場を借りてお礼申し上げます。

2年ぶりくらいに基板設計して発注したんですが、昔と比べてかなり安く発注できるようになった気がします。
2層基板は昔から安かったと思いますが、最近では4層基板も2層基板と変わらないような価格で発注できるようになりました。
最近では6層基板も安くなっているみたいですね。6層基板に使えるクーポンを沢山配っているので、かなりお得に発注できると思います。
JAWS DAYS 2025 やります！

# JAWS DAYS 2025 実行委員長を担当する新居田です

この度、[JAWS FESTA 2024 in 広島](https://jawsfesta2024.jaws-ug.jp/)で `JAWS DAYS 2025` を告知させていただきました。

## お前誰やねん

- name: 新居田晃史（にいだあきふみ）
- company: JBCCグループ JBアドバンスト・テクノロジー株式会社(JBAT)
    - 先進技術研究所　Technology Expert
- jawsug: JAWS-UG横浜支部コアメンバー (2016-)
- global_program: AWS Community Builder (Container) (2022-)
- about_me: フルマラソンを2時間29分56秒で走る現役ITエンジニア
- history : 愛媛県今治市→京都市→横浜市→川崎市


お声掛けいただけると嬉しいですー

## AWSとは
Amazon Web Servicesの略称です。
AWSのサービス数は200を超え、個人で学習するには難しい規模になっています。
よくあるWEB三層モデルから、サーバーレスアーキテクチャまで、ブロックを組み立てるように最適な構成を作っていけるのが特徴です。
そのためにも、多くのサービスを学び、自分の武器を増やしておくことが重要ですね。

## JAWS DAYSのテーマに込めた思い

2025のテーマは「**Connecting the dots**」です。

ご縁があって「実行委員長いかがですか？」とお声がけいただきました。

私自身、コミュニティに関わることでスキルアップはもちろんのこと、人との繋がりで自分の常識をアップデートできたり、サードプレイスとしてモチベーションを上げる熱量をもらったり、ロールモデルとなる人と出会って自分自身の成長機会に繋がったりと、とてつもなく恩恵を受けてきました。

特にJAWS-UGは助け合いの精神が強く、初めての登壇や運営など、思い切って踏み出した事に対するサポートがとてつもなく大きいように感じています。それに応えることが信頼関係に繋がって心地よさや新たな楽しさを発見することに繋がっているのかなと考えてます。

そんな素敵なコミュニティを **継続** していきたいというのが今回のJAWS DAYSに込める思いです。

こんなことを継続できたらいいなと思ってます。

- JAWS-UGに初めて来た人も今まで居た人もが心地よい場所
- 新しいことを知れて自分にとって持ち帰れるものがある
- 社内では通じない話題でも、共通の話題で盛り上がって仲良くなれる楽しさがある
- 新たな楽しさを気づくこともできる
- 新しいテクノロジーが新しいヒーローを生み、歓迎される
- 相互理解を深めることができる

これらの偶発的に起こる出来事は、「自律的」に活動する全国各地の支部が「集まる」 JAWS DAYS が一番作りやすいはずです。

支部、それを支える運営メンバー、企業、新しく参加する方々、いろんな **dot** が繋がることで気付きや発見、新陳代謝と継承が起こり、次のJAWSの姿を作っていくと考えています。

参加者全員で多くの知見共有、学び、交流によって、その姿を描いていきませんか？

## 最後に

生成AIやPlatform Engineeringなど新しいキーワードを織り交ぜつつ、
楽しみながら学ぶ姿勢を大切にしながら、心強い実行委員と共に最高のイベントを組み立てていきます。
  

**We are Builders！**


2025/3/1 寒さの残る時期ですが皆様の情熱で熱くしましょう！
池袋サンシャインシティでお待ちしています。
cssでフォントサイズを変更する方法 px % rem の使い方

今回はcssで文字の大きさを変更する方法について学びました。px % rem 3種類の使い方について解説します。

## フォントサイズの基準を指定しない場合
フォントサイズを特に指定しない場合、ブラウザのデフォルトでは16pxを基準にフォントサイズの調整をすることになります。
以下がソースコードです

``` index.html

<!DOCTYPE html>
<html lang ="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href = "style.css">
    </head>
    <body>
        
        <p class="size-pixel">これはテキストです。 30px</p>
        <p class="size-percent">これはテキストです。12px </p>
        <p class="size-rem">これはテキストです。16px</p>
        

    </body>
</html>

```

```style.css

.size-pixel{
    font-size: 30px;

}

.size-percent{

    font-size: 75%;

}

.size-rem{
    font-size: 1rem;

}

```
デフォルトの16pxを基準にフォントサイズが決まります。

## 親要素で大きさを指定した場合
次は親クラスを使ってフォントサイズを指定します。
この記述をすることでdivタグに囲まれた要素は60pxを基準にフォントサイズを調整します。
``` html
<div style="font-size: 60px;">

</div>
```

``` index.html

<!DOCTYPE html>
<html lang ="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href = "style.css">
    </head>
    <body>

        <div style="font-size: 60px;">
            <p class="size-pixel">これはテキストです。 30px</p>
            <p class="size-percent">これはテキストです。12px </p>
            <p class="size-rem">これはテキストです。16px</p>
        </div>
        

    </body>
</html>

```

```style.css

.size-pixel{
    font-size: 30px;

}

.size-percent{

    font-size: 75%;

}

.size-rem{
    font-size: 1rem;

}

```

実際に試してもらうとわかるのですが、親要素でフォントサイズを指定してもサイズに変化はありません。%を使った調整は親要素に依存しますが、remを使った調整は常にhtml要素 ルート要素に依存するため60pxではなく16pxになります。
親要素の基準に影響を受けません。

## html全体の大きさを指定した場合
html全体にフォントサイズを指定してみます。
今回はcssファイルのセレクター部分にhtmlを指定してフォントサイズを指定します。

``` index.html

<!DOCTYPE html>
<html lang ="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href = "style.css">
    </head>
    <body>
        
        <p class="size-pixel">これはテキストです。 20px</p>
        <p class="size-percent">これはテキストです。45px </p>
        <p class="size-rem1">これはテキストです。60px</p>
        <p class="size-rem2">これはテキストです。90px</p>
        

    </body>
</html>

```

```style.css
html{
    font-size: 60px;
}

.size-pixel{
    font-size: 20px;
}

.size-percent{

    font-size: 75%;

}

.size-rem1{
    font-size: 1rem;

}

.size-rem2{
    font-size: 1.5rem;

}

```
htmlファイル全体にフォントサイズを指定したことで% remを使って相対的に調整することができました。1remは1.0倍。1.5remは1.5倍になります。
また、この３種類のやり方を通してプロパティに
font-size: ○○px;と記述することで個別にフォントサイズを指定できることもわかりました。


今後はcss htmlを中心に学んだ内容を整理するために記事を投稿していきます。
Jetson Orin NXとJetPack 6.0でYOLOv8.3.11を動かす

### Jetson Orin NXをお借りできたので、YOLOv8をインストールしてみました。
* Ubuntu 22.04.4 LTS (Let's note RZ4)
* Jetson Orin NX 16GB
* Ediloca EN600 PRO SSD 512GB PCle 3.0x4 NVMe M.2 2280
* logicool C270N

## JetPack 6.0のインストール
※JetsonにHDMIディスプレイを接続し、Force Recovery Modeで起動します。

Target Hardware：Jetson Orin NX 16GB
SDK VERSION：JetPack 6.0(rev.2)

OEM Configuration：Pre-Config
Username：jetson
Password：jetson
Storage Device：NVMe

OSのFlashが完了したら、JetsonのUbuntuが起動します。ログイン画面が表示されたら、Installを実行します。

## YOLOv8.3.11のインストール
参考：
https://docs.ultralytics.com/ja/guides/nvidia-jetson/#install-onnxruntime-gpu

```
sudo apt install python3-pip
```

```
pip3 install ultralytics
reboot
```

Successfully installed filelock-3.16.1 fsspec-2024.9.0 jinja2-3.1.4 networkx-3.4.1 numpy-2.1.2 opencv-python-4.10.0.84 psutil-6.0.0 py-cpuinfo-9.0.0 seaborn-0.13.2 torch-2.4.1 torchvision-0.19.1 tqdm-4.66.5 typing-extensions-4.12.2 ultralytics-8.3.11 ultralytics-thop-2.0.9

```
sudo apt-get install libopenmpi-dev libopenblas-base libomp-dev -y
```

```
pip3 install --no-deps torch-2.3.0-cp310-cp310-linux_aarch64.whl 
```
Successfully installed torch-2.3.0

```
pip3 install torchvision-0.18.0a0+6043bc2-cp310-cp310-linux_aarch64.whl 
```
Successfully installed torchvision-0.18.0a0+6043bc2

```
wget https://nvidia.box.com/shared/static/48dtuob7meiw6ebgfsfqakc9vse62sg4.whl -O onnxruntime_gpu-1.18.0-cp310-cp310-linux_aarch64.whl
pip3 install onnxruntime_gpu-1.18.0-cp310-cp310-linux_aarch64.whl 
```

Successfully installed coloredlogs-15.0.1 flatbuffers-24.3.25 humanfriendly-10.0 onnxruntime-gpu-1.18.0

```
pip3 install numpy==1.23.5
```
Successfully installed numpy-1.23.5

```
sudo apt-get install nvidia-jetpack
```
参考：
https://forums.developer.nvidia.com/t/orin-pytorch-cuda-issue/262858/11

## YOLOv8の動作確認
```
yolo predict model=yolov8n.pt source="https://ultralytics.com/images/zidane.jpg"
```
:::note info
検出結果は「Home/runs/detect/predict」内に保存されます（zidane.jpg）。
:::

```
yolo task=detect mode=predict model=yolov8n.pt source=0 show=True imgsz=256
```

:::note info
Jetson Orin NX 16GB：1 frame：22.4ms
:::
Error: Failed to parse URL from ~というエラーの対処

# はじめに
app routerでのapiを叩く際にエラーが出たので対処法を書きます。
# 問題
以下のようにapiを叩いた際にfetch errorが出る。localhostを直書きしても良いのですが、それだとvercel等にデプロイした際本番URLでエラーになるのでなんとかする必要があります。
```page.tsx
import QiitaPage from './components/qiitaPage';
import MicrocmsPage from './components/microcmsPage';

export default async function Page() {
  // 問題の行
  const res = await fetch("/api/qiita", { cache: "no-store" });
  const data = await res.json();

  return (
    <div className="px-5 py-5">
      <QiitaPage data={data} />
      <MicrocmsPage />
    </div>
  );
}
```
# 解決策
app routerの場合、絶対パスでapiリクエストを投げる必要があるみたいです。クライアント側でレンダリングさせれば相対パスでも書けるみたいですが、せっかくNext.jsを使っているのでサーバサイドでレンダリングさせたいです。なのでnext/headersから現状のプロトコルとホストを取得して利用します。先ほどのコードに少し追加します。

```page.tsx
+ import { headers } from 'next/headers';
import QiitaPage from './components/qiitaPage';
import MicrocmsPage from './components/microcmsPage';

export default async function Page() {
   // ホストとプロトコルを取得
+  const headersData = headers();
+  const protocol = headersData.get('x-forwarded-proto') || 'http';
+  const host = headersData.get('host');
   // 絶対パスで指定してあげる
+  const apiBase = `${protocol}://${host}`;
+  const res = await fetch(`${apiBase}/api/qiita`, { cache: "no-store" });
// const res = await fetch("/api/qiita", { cache: "no-store" });

  const data = await res.json();

  return (
    <div className="px-5 py-5">
      <QiitaPage data={data} />
      <MicrocmsPage />
    </div>
  );
}
```

# おわりに
検索の仕方が悪く解決に少し時間がかかりました。

# 参考
https://qiita.com/Gma_Gama/items/86a68240b70448003fb1

https://wp-kyoto.net/fetch-nextjs-api-on-app-router/
Error: parameter is required (check serviceDomain and apiKey)

# はじめに
github actionsを使ったvercelデプロイ時にビルドの箇所でエラーが出たので、解決策を書きます。
# 問題
ローカルでのビルド成功するが、cicdのビルドステップではエラーが出る。
```
Error: parameter is required (check serviceDomain and apiKey)
```
エラー時のyml
```yml
name: Github Auto Deploy

on: push

env:
  VERCEL_ORG_ID: ${{ secrets.ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.PROJECT_ID }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Vercel CLI
        run: npm install --global vercel@latest

      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build Project Artifacts
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

```
# 解決策
ymlに環境変数を指定してあげれば直りました。正直エラー文に何が問題か書いてありますし、cicd時のみのエラーなので少し考えればわかりそうですが、vercelに環境変数を設定すればPROJECT_IDとかから勝手にgithub actions側で読み込んでくれると思い込んでいたためymlで指定していませんでした。(思い込み怖い)

```yml
name: Github Auto Deploy

on: push

env:
  VERCEL_ORG_ID: ${{ secrets.ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.PROJECT_ID }}
  # 環境変数を指定してあげる
  API_KEY: ${{ secrets.API_KEY }}
  SERVICE_DOMAIN: ${{ secrets.SERVICE_DOMAIN }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Vercel CLI
        run: npm install --global vercel@latest

      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build Project Artifacts
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
```
ビルド時に環境変数を渡してあげることで外部のapiとの通信が可能になります。(今回の場合はmicrocmsのapi)
# おわりに
vercel使いやすいです。
素数を判定するのを作ってみよう！(後編)

前回

https://qiita.com/yamina-Tjatmg-Gui-Creater/items/2f17cb915289d909621a

```js
function Is_prime(a){//素数判定


    if(a == 1){
        //そうだったら素数ではない
    }else{
        //そうじゃなかったらこれやる
        //2からa-1まで　しらみつぶし(そのしらみつぶししてる数をiにする)
            //aはiで割り切れる？
                //そうだったら素数ではない
                //そうではなかったら素数の可能性がある
    }
    

//素数か素数じゃないかを出す
}
```

前回はここまで進みました！

# javascriptの書き方　~しらみつぶし~

しらみつぶし関係の処理とかを書くときはfor文を使います！

```js
for(変数に数入れる; くりかえす条件; 変数を変える){
    //しらみつぶすコード
}

for(let i = 2; i <= a - 1; i++){
    //しらみつぶすコード
}

//これでしらみつぶし出来ます！

//iはindexの略です！
//i++はi = i + 1と同じ意味です。！
```

するとこのコードが書けます！

```js
function Is_prime(a){
    if(a == 1){
        //そうだったら素数ではない
    }else{
        for(let i = 2; i <= a - 1; i++){
            //aはiで割り切れる？
                //そうだったら素数ではない
                //そうではなかったら素数の可能性がある
        }
    }
    

//素数か素数じゃないかを出す
}
```

# 割り切れることの判定はどうやる？

aがiで割り切れる　=>　aをiで割ったあまりが0

つまり、``a % i == 0``で、割り切れることの判定ができます。

するとこのコードが書けます！

```js
function Is_prime(a){
    if(a == 1){
        //そうだったら素数ではない
    }else{
        for(let i = 2; i <= a - 1; i++){
            if(a % i == 0){
                //そうだったら素数ではない
            }else{
                //そうではなかったら素数の可能性がある
            }
        }
    }
    

//素数か素数じゃないかを出す
}
```

### ほぼ完成ですね！

素数なのか　素数じゃないのか

これを保存する変数を作ってみましょう！


```js
function Is_prime(a){
    let prime_is = true;
    if(a == 1){
        prime_is = false;
    }else{
        for(let i = 2; i <= a - 1; i++){
            if(a % i == 0){
                prime_is = false;
            }else{
                //何もしない
            }
        }
    }
    

//素数か素数じゃないかを出す
}

// trueはオン
// falseはオフ
// そういう感じ
```

`else{//何もしない}`はいらないのでこのようになります。


```js
function Is_prime(a){
    let prime_is = true;
    if(a == 1){
        prime_is = false;
    }else{
        for(let i = 2; i <= a - 1; i++){
            if(a % i == 0){
                prime_is = false;
            }
        }
    }
    

//素数か素数じゃないかを出す
}
```

# 値を返してみよう！
関数の中に、`return`と書くことで値を返せます。

値を返すと関数を式に、組み込めるようになります！

5 + a(8) * a(50)

こんな感じです。

では、最後です！

```js
function Is_prime(a){
    let prime_is = true;
    if(a == 1){
        prime_is = false;
    }else{
        for(let i = 2; i <= a - 1; i++){
            if(a % i == 0){
                prime_is = false;
            }
        }
    }
    return prime_is;
}
```

# 完成&使ってみよう
これで完成です！
使ってみましょう

```js
for(let i = 1; i < 100; i++){
  console.log(i + "は素数か？→" + Is_prime(i));
}


function Is_prime(a){
    let prime_is = true;
    if(a == 1){
        prime_is = false;
    }else{
        for(let i = 2; i <= a - 1; i++){
            if(a % i == 0){
                prime_is = false;
            }
        }
    }
    return prime_is;
}
```

是非やってみてください！


# 一応言っておきますが
これは初心者向けなので無駄が多いです。
もっと速くする方法があります。
今度作ってみます！
PowerShellでのエイリアスの設定方法（bashコマンドの拡充）


# 対象者
* WindowsのPowerShellのコマンドを簡易的にbashコマンドを拡充したい方
* エイリアス(別名)設定のため、完全にはbashコマンドと一致せず、細かい動作が異なる点に留意すること


# 概要
* PowerShellでは、ある程度bashのコマンドにエイリアスが設定されているが、未設定のコマンドは別途設定する必要がある
* 本ページでは、PowerShellでのエイリアスの設定方法を記載する
    * 例として、lsの色付けとtouchを記載

# 設定方法
* 以下のフォルダにPowerShellのプロファイル「Microsoft.PowerShell_profile.ps1」を作成する。フォルダがない場合は、フォルダも作成する。
  * フォルダ： %USERPROFILE%\Documents\WindowsPowerShell
    * {%USERPROFILE%}は、「C:\Users\{ユーザー名}」を表す環境変数
  * ファイル名：Microsoft.PowerShell_profile.ps1
* 作成したファイル内に登録したいコマンドを以下の書式で記載。参照：[エイリアスの作成（引数が複数ある場合）【BashとPowerShellの比較】](https://qiita.com/karakuri-t910/items/d751987065d4c52b3af4)
  * 引数がない場合
    ```
    set-alias ls myls
    ```
  * 引数がある場合
      ```
      function {省略形}
      {
          対象のコマンド
      }
    
      (例)
      function touch
      { 
        New-Item $args
      }
      ```

* PowerShellを新規起動し、設定したコマンドを実行できるかを確認する。起動時に以下のエラーが表示される場合は、実行ポリシーの設定変更をする
  * エラーメッセージ：　このスクリプトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」を参照してください
  * 対応方法： PowerShellを管理者として実行し、以下のコマンドで設定する。ポリシー名は[about_Execution_Policies](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4&viewFallbackFrom=powershell-7.3)を参照のこと
  * 【注意】実行ポリシーの設定変更に関しては、セキュリティ上問題ないかを確認の上で実行ください
    ```
    Set-ExecutionPolicy -ExecutionPolicy {ポリシー名}
    (例)
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
    ```



# 設定ファイルの例
* 例として、lsの色付けとtouchを記載
* lsは[PowerShellで色付きlsをつくる](https://aldente39.hatenadiary.org/entry/20120322/1332430627)を参照

```
rm alias:ls -force
set-alias ls myls

filter lsColor{
    if($_.mode[0] -eq "d"){
        Write-Host $_.name -ForeGroundColor Blue
    }
    elseif($_.get_Extension() -eq ".exe"){
        Write-Host $_.name -ForeGroundColor Green
    }
    else{
        Write-Host $_.name
    }
}

function myls{
    $c = "Get-ChildItem " + $args
    Invoke-Expression $c | lsColor
}

function touch {
    if ($args) {
        New-Item $args
    }
    else {
        echo "No arguments!"
    }
}
```

# 補足
* コマンドプロンプトについては、[コマンドプロンプトでのbashコマンドの使用(置換)方法](https://qiita.com/mmssyy00/items/b7d88793a0316698c0d1)を参照


# 参照サイト
* [【開発効率化】PowershellやGitBashで入力するコマンドにエイリアスを設定して省略コマンドで入力の手間を省く！](https://qiita.com/machbike/items/3eb6527a851622fab9b5)
* [エイリアスの作成（引数が複数ある場合）【BashとPowerShellの比較】](https://qiita.com/karakuri-t910/items/d751987065d4c52b3af4)
* [about_Execution_Policies](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4&viewFallbackFrom=powershell-7.3)
* [PowerShellで色付きlsをつくる](https://aldente39.hatenadiary.org/entry/20120322/1332430627)
Davinci Resolveでテロップの横幅を文字の長さと連動させる方法

個人的な備忘録としておいておきます。

Davinci Resolveでテキストの内容を変更した後に後ろの背景も直すのが面倒だったので、Expression（参照）を使って自動で変更してくれないか調べてみました。
<br>
これが
![Davinci_Resolve_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/bf4a526e-bbfa-7842-48cc-f43ed58108fc.png)

テキスト弄るだけでこうなる
![Davinci_Resolve_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/b81e1dba-358c-bf90-f4a3-0db46568b831.png)
<br>

マクロを組む際にも役に立つと思われます。
<br>
### Fusionコンポジションの作成
エディットページからFusionコンポジションを作成して、Fusionページに飛んでください。
今回はテキストと長方形の横幅が連動しているのを見たいだけなので、簡単な構成にしてあります。
![Davinci_Resolve_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/74491795-47e2-d4fa-0feb-023bd5259c43.png)
<br>
### ノードのパラメータ設定
この辺はまぁ何でも良いのですが、一応今回の自分の設定値を置いておきます。
<br>
Text1
![Davinci_Resolve_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/8b97d9b1-98f7-e18a-8388-92e6d50ca160.png)

Rectangle1
![Davinci_Resolve_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/82b061d0-5115-7fe5-e2e0-c54b3b7b991c.png)
<br>
 ### Expressionの設定
 Rectangle1のパラメータから「幅」を右クリックして「エクスプレッション」をクリックしてください。
 ![Davinci_Resolve_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/b3a45102-daad-ba32-fcf0-564e9a95aee4.png)

すると、Expressionの項目が追加されます。
![Davinci_Resolve_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/d8097cf5-ddf7-aad5-74b8-8eb735e1ec74.png)

この0.24を消して、以下のコードをコピペしてください。
（あんまり詳しくないのですが、どうやらこれはLuaという言語らしいです）
~~~
string.len(Text1.StyledText.Value)
~~~

すると、"Sample"は6文字なので幅には6が入力されました。
<br>
![Davinci_Resolve_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/15e6a9d3-3b78-041a-b274-d373c4fab81d.png)
<br>
これだと長すぎるので、÷25くらいしましょうか。
ここは要調整ですね。
~~~
string.len(Text1.StyledText.Value)/25
~~~
<br>

![Davinci_Resolve_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/3605fcee-c5bb-4db6-a7f7-44d74a50beef.png)

<br>
そうしたら、Text1の文言を好きに弄りましょう。
すると、文字数に合わせて長方形が勝手に伸縮するようになります。

<br>

文字を弄っただけ
![Davinci_Resolve_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909294/ba035015-85fd-dd70-a2b6-a9dbff448d42.png)

<br>
以上です。
お役に立てれば嬉しいです。

# 補足
* 空白や改行も1文字として認識されているっぽい
* 厳密には文字数ではなく、バイト数を返すようなので、日本語は3倍の数値が返ってくる
* 改行をして、各行で最も長い行に長方形の幅を合わせる・・・みたいな事をしようとするならば、ちゃんとLuaのお勉強をする必要があるかも
【AWS】J-Quants API + AWS Athenaを用いた金融データ分析

# 【AWS】J-Quants API + AWS Athenaを用いた金融データ分析

日本取引所グループ(JPX)が提供しているJ-Quants APIというサービスがあります。

https://jpx.gitbook.io/j-quants-ja

このサービスではJPXが公式に提供する金融情報(現物情報、デリバティブ情報、指数情報、企業情報など)をAPIエンドポイント経由で取得することができます。

無料/ライト/スタンダート/プレミアムの4種類の利用枠があり、無料利用枠でも企業の財務データや株価といった種々の情報を取得することができます。

今回はJ-Quants APIで各種金融データを取得してAWS Athenaで分析する、というシナリオを想定してハンズオンを行ってみます。

![jquants.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/f5511d53-6c65-3436-e4ee-d2e9ff4a136f.png)

## J-Quants APIの利用登録
以下のサイトにアクセスして利用登録を行います。

https://jpx-jquants.com/auth/signup/?lang=ja

今回は検証目的のため、無料利用枠で登録します。

登録が完了したらサインインし、トップページから**リフレッシュトークン**を取得します。
リフレッシュトークンはAPIアクセス用のトークン(**IDトークン**)を発行するためのトークンです。

取得したリフレッシュトークンを用いて、IDトークンを取得します。
各種情報を取得する際はこのIDトークンをAuthorizationヘッダに設定してAPIエンドポイントにリクエストを送る形となります。

各種トークンは
- リフレッシュトークン: 1週間
- IDトークン: 24時間

の有効期限があるため、トークン取得の流れは自動化orスクリプト化しておくと良さそうです。

## データ取得用のLambda関数の作成

APIエンドポイントにアクセスして金融情報(今回は「上場銘柄一覧」)を取得し、
取得結果をJSON形式でS3に保存します。

以下のpythonスクリプトをLambda関数としてデプロイしました。

https://github.com/OchiShuji/jquants_api_poc


Lambda実行ロール(s3:PutObjectが許可されたポリシーをアタッチしておきましょう)
を設定後、関数を実行して以下のようにjson形式でS3にデータが保存されれば成功です。

![スクリーンショット 2024-10-13 20.23.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/8013cc4f-9341-723a-a6b5-184b14038b1c.png)

:::note
実行するAPIによっては情報の取得にそれなりに時間がかかるため、
Lambda関数のタイムアウト値に留意しましょう。
:::

## 分析用テーブルの作成

分析用テーブルはAthenaでクエリ実行して作成しても良いのですが、面倒なのでAWS Glueを使用します。

AWSマネジメントコンソールからGlueのコンソールを開き、左ペインからData Catalog > Crawlerを選択します。

![スクリーンショット 2024-10-13 20.30.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/4af857b9-efc7-eadb-d65a-f3d4592bbad4.png)

Create Crawlerから新しいCrawlerを作成します。
Data Sourceには先ほどJSONファイルを保存したS3バケットを選択しましょう

![スクリーンショット 2024-10-13 20.32.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/7aafba60-ea83-fa65-2be4-09b5c67606be.png)

Crawlerの作成後、Run CrawlerからCrawlerを実行します。
実行が完了したら、左ペインのData Catalog > Database > Tables
から作成済みのテーブルを確認してみましょう。

以下のようにJSONファイルの内容に基づいてテーブルが作成されていればOKです。

![スクリーンショット 2024-10-13 20.33.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/c951920c-66d1-e499-a7fd-68d861acbaae.png)


## Athenaによるクエリ実行

AWSマネジメントコンソールからAthenaのコンソールを開き、クエリエディタを開きます。
先ほど作成したテーブルに対して、以下のようなクエリを実行してみます。

```sql
select *
from jquants_knowledge_base_bucket_s3
where sector17code='15';
```

![スクリーンショット 2024-10-13 20.36.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/d34c3f64-fe8f-ac4f-9246-e1b4c39c0b57.png)

クエリ実行の結果、以下のように17業種コードが15(業種名：銀行)の上場企業の一覧が取得できました。

![スクリーンショット 2024-10-13 20.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880214/509acd1f-2ecf-9973-cbb9-1b4c2c9832c0.png)

## まとめ
J-Quatns APIとAWS Athenaを用いることで、簡単に金融データの取得と分析を行うことができました。

個人的にJ-Quants APIを利用して嬉しいポイントは以下になります。
- 無料利用枠でもそれなりの情報にアクセスできる
- JPXが提供しているAPIのため、データの正確性や適時性が一定程度担保されている
- 日本語のAPI仕様書が充実している

今回は上場企業一覧の情報をサンプルとして用いましたが、企業の財務情報や株価の情報も公開されており、分析用途としては非常に充実している印象です。
React｜こんな感じでキャッチアップしてます

# はじめに

エンジニアのみなさま、日々の学習本当にお疲れ様です！
また本記事まで足を運んでいただき本当に感謝です。
約5分で読めるため、最後まで読んでもらえると幸いです。

---

案件でReactを使っています。現在はマネジメント業務を担当しているためコードを書くことはありませんが、少しでも開発メンバーの気持ちに寄り添える様に業務外の時間を使って学習をしてます。今までRubyやRuby on Railsなどのバックエンドの学習がメインだったため、フロンエンドの学習はほぼ皆無でした...
試行錯誤しながら学習を続けていき、個人的にしっくりきた学習方法をつらつら書いていきたいと思います。

# インプット

朝の通勤時間、満員電車に苦しみながら初めのインプットとしてはReactの公式ドキュメントを読みました。

https://ja.react.dev/learn

Reactの公式ドキュメントはサンプルコードがふんだんに使われています。また、チュートリアルとして「三目並べ」も掲載されており、ハンズオンで対応できる内容になっています。個人的には読みやすくて好きな公式ドキュメントです。

全体像をざっくり理解した後は、以下の順番でUdemyの以下講座の動画視聴にシフトしました。基本的にはハンズオンで対応できるものばかりですが、ここでは動画視聴のみとしてます。

https://www.udemy.com/course/react-3project-app-udemy/?couponCode=ACCAGE0923

Reactで「ポケモン図鑑アプリ」「ブログアプリ」「ノートアプリ」を実装する動画になります。認証機能やAPIフェッチング手法などを丁寧に解説してます。Reactの公式ドキュメントと同様、実装における全体像を把握するためにまずはこの動画を視聴しました。

https://www.udemy.com/course/modern_javascipt_react_beginner/?couponCode=ACCAGE0923

JavaScriptとReactでそれぞれTodoアプリを実装してます。JavaScriptと比較して、Reactがどれだけ簡素に記述できるかが理解できる動画になります。加えて、JavaScriptの基礎の理解も深まるため、個人的にオススメです。

https://www.udemy.com/course/react_stepup/?couponCode=ACCAGE0923

React実装における応用編。再レンダリングの最適化の方法やReact Routerを使った実践的な画面遷移の方法などが学べます。

# アウトプット

インプットばかりしても知識が定着しないため、仕事から帰ってきたら手を動かしてアウトプットする習慣をつけました。
#### 『困った時はToDoアプリだ！』

という事で、MDNで紹介されている以下サイトでまずはコードの写経をしてCRUDの基本的な考え方を理解しました。以下サイトで紹介している内容はReactのバージョンが古いです。今回は新しいバージョンで実装して、わざとエラーを出しながら古いバージョンとの書き方の違いやデバッグ手法も理解しました。

https://developer.mozilla.org/ja/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning

このサイトで作成できるToDoアプリの詳細は以下の記事でまとめてます。
時間があれば合わせて読んでみてください。

https://qiita.com/ho_na/items/92e085bcced0cc4e3c06

写経が終わったら、次は自力で実装していきます。
ChatGPTを活用して、コンポーネント実装の問題集を作成しました。以下添付の通り「初級10問」「中級20問」「上級20問」の合計50問を作成してもらい、現在1問ずつ対応してます。開発環境は[CodeSandbox](https://codesandbox.io/)を活用してます。

弊社ではSlackを使っているため、個人チャンネルで実装結果の動画を添付してます。1つの問題が完了したらCodeSandboxのコードを削除して、次の問題のコードを1から実装していきます。コンポーネント実装は手軽に対応できて、且つ、コードを書く反復練習になるため、ゲーム感覚で楽しみながら進めている段階です。

![スクリーンショット 2024-10-13 19.57.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/1b7a722f-21ac-d85e-0c0e-a1dbfdd8bb6b.png)

![スクリーンショット 2024-10-13 20.00.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/58836b4d-d250-e3fb-11ed-fbad14fd5391.png)

50問をコンプリートした後は、クローンアプリを実装する予定です。
実装する上で、自分に足りていない部分を認識しながら、インプットで利用しているコンテンツを逆引き辞書的な使い方で活用していきたいなと考えています。あとはコードレビューをAIが実施してくれる[CodeRabbit](https://coderabbit.ai/ja/) なるものも登場しています。コードレビューの観点でどの様な書き方があるかを理解しておく必要もあるため、こちらも活用していきたいなと考えてます。

# さいごに

いかがだったでしょうか？
個人的には新しい言語をキャッチアップするときに、「公式ドキュメントを読む」 → 「実装の全体像が分かる動画を見る」 → 「実際に手を動かして理解を深める」→ 「不明点は公式ドキュメントを見直す」のループで学習を続ければ、必要最低限の理解ができると考えています。しかしながら、学習方法が完全に我流のため、他に良い学習方法があれば教えていただけると非常に嬉しいです...！

# おまけ

弊社のご紹介もさせてください！

### 「日本で一番エンジニアが成長できる会社を創る」

https://prum.jp/

### エンジニアリングの募集

https://www.wantedly.com/projects/1808638

### PM・Webディレクションの募集

https://www.wantedly.com/projects/1355235

### セールス・事業開発の募集

https://www.wantedly.com/projects/1792065

### コーポレート系の募集

https://www.wantedly.com/projects/1752874

### コンサルティングの募集

https://www.wantedly.com/projects/1794481

弊社メンバーは日々学習した内容をアウトプットしております！
少しでもご興味を持たれた方は求人を見てみてください！
ご応募もお待ちしております！

### 最後までご覧いただき、ありがとうございました！
【MySQL】COALESCE関数を活用した日数の計算

# はじめに
ActiveRecordのメソッドだけでは表現できないような書き方についてまとめます。

きっかけは、Railsのselectメソッドで、SQLを直接書く場面があったことです。
その時にSQLの重要性がより理解できたので共有させて頂きます。

# 前提知識
## selectメソッド
データベースから取得するカラムを指定するためのメソッドです。
selectメソッドは、SQLの**SELECT句**に相当します。

### 基本的な書き方
```ruby
# 全てのカラムを取得
User.select("*")

# 特定のカラムのみを取得
User.select(:name, :email)
```

### 複数のテーブルを結合して取得
```ruby
# UserモデルとPostモデルを結合して、ユーザー名と投稿タイトルを取得
User.joins(:posts).select("users.name, posts.title")
```
:::note info
`joins`によるテーブル結合については[こちらの記事](https://qiita.com/k12da/items/2ea1b4196790f3ea9f3a)をご参考ください。
:::

このようなメソッドを利用することで、生のSQLを書かずにデータベースへの特定のクエリを実行するための引数を渡せるようになります。

# 本題

## 目的
ユーザーの**最新の投稿（posts）の更新日時**と、**現在の日時**の差を日数で計算する。

## 実装したコード
```ruby
  users.joins(:posts)
       .select(
          users.*,
          COALESCE(
            DATEDIFF(
              CURDATE(),
              (SELECT MAX(posts.update_at) FROM posts) 
            ), 0)
          )
       )
```

### 解説
#### COALESCE
複数の引数を受け取り、NULL ではない最初の引数を返すMySQLの関数です。
全ての引数がNULLの場合は、NULLを返します。

`COALESCE(expression1, expression2, ..., expression_n)`

[今回の例](#実装したコード)で言うと、最初の引数は`DATEDIFF()`の部分です。
引数の値がNULLのレコードは、0を返すように第2引数で設定しています。

#### DATEDIFF
ある日付から別の日付までの日数を返します。値の**日付部分のみ**が計算に使用されます。
時間または日付時間式ですが、両方の日付とも同じ型にする必要があります。

`DATEDIFF( <date_or_time_part>, <date_or_time_expr1>, <date_or_time_expr2> )`

:::note info
似たような関数で[TIMESTAMPDIFF](https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_timestampdiff)関数があります。
こちらはTIMEDIFF関数と違って、**式の一方が日付の型で、他方が日付時間の型**にすることもできます。
:::

##### サブクエリ（副問い合わせ）
`DATEDIFF`関数で、**サブクエリ**`(SELECT MAX(posts.update_at) FROM posts)`を書いてます。
これによってpostsテーブルの最新レコードの`updated_at`カラムの値を取得しています。

:::note info
サブクエリの基本については[こちらの記事](https://techplay.jp/column/1841)が分かりやすいと思います。
:::

###### サブクエリを書いた理由
理由は、日数の計算をするために**どのテーブルの、いつのレコードの更新日時（updated_atカラム）を参照するのかを明確にするため**です。

MySQLのやり取りを日常的な人間の会話に置き換えると、
```
人間「updated_atカラムの値を参照して！」
MySQL「いや、なんのっ?（どのテーブルのいつのレコードの？？）」
```
質問は具体的に...（特大ブーメラン🪃）


#### CURDATE()
現在の日付を`'YYYY-MM-DD'`または`YYYYMMDD`形式の値として返します。
```sql
mysql> SELECT CURDATE();
        -> '2008-06-13'
mysql> SELECT CURDATE() + 0;
        -> 20080613
```

# おわりに
MySQL関数を使うことで複雑な処理をより簡潔に書けるので有り難いなと思いました。
[MySQL 8.0 リファレンスマニュアル](https://dev.mysql.com/doc/refman/8.0/ja/)という公式ドキュメントも今回の件で知ったので、時間ある時に目を通しておきたいと思います。

# 参考記事
- [1 Active Recordクエリインターフェイスとは？](https://railsguides.jp/active_record_querying.html#active-record%E3%82%AF%E3%82%A8%E3%83%AA%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9%E3%81%A8%E3%81%AF%EF%BC%9F)
- [SQLのサブクエリ（副問合せ）を初心者向けに解説します](https://techplay.jp/column/1841)
- [MySQL 8.0 リファレンスマニュアル](https://dev.mysql.com/doc/refman/8.0/ja/)
- [COALESCE](https://dev.mysql.com/doc/refman/8.0/ja/comparison-operators.html#function_coalesce)
- [DATEDIFF](https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_datediff)
- [CURDATE()](https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_curdate)
(自分用)apache2の文字化けしたときの治す方法

# apacheで文字化けしたら
調べてもhttpdしか出てこなかったのでメモをしておく。
```
cd /etc/apache2/conf-availables/
sudo nano charset.conf
```
そしたら
```
# Read the documentation before enabling AddDefaultCharset.
# In general, it is only a good idea if you know that all your files
# have this encoding. It will override any encoding given in the files
# in meta http-equiv or xml encoding tags.

#AddDefaultCharset UTF-8
```
となっているので、UTF-8の人は、
```
# Read the documentation before enabling AddDefaultCharset.
# In general, it is only a good idea if you know that all your files
# have this encoding. It will override any encoding given in the files
# in meta http-equiv or xml encoding tags.

AddDefaultCharset UTF-8
```
#を消しましょう。
その他の人はUTF-8の部分を、ほかの文字コードに変えてください。
簡単
FreeCADのマクロ「z=0 XY平面に寸法線を作図しました。」

# 作図結果
#### 上空から

![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/b86db0f7-5b16-71c4-3b9c-82c683889915.png)

#### Isometric方向

![222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/9a0a6bf5-0b91-7c34-9a69-36a83e0da026.png)

# ソースコード

https://forum.freecad.org/viewtopic.php?t=91354

# 参考

https://qiita.com/mrrclb48z/items/3d0410b8c928e3c97d4a

https://wiki.freecad.org/index.php?search=Dimension&title=Special%3ASearch&wprov=acrw1_-1
WSL2 + devcontainer + dotfilesで最強になろうとしたらハマった話

## 何があったのか
VS CodeのDev Containers拡張機能には、dotfilesを自動で連携してくれる仕組みがある。
その仕組みがうまく起動せず、dotfilesを読み込んでくれなかった。

## 解決方法
Windows側の環境変数に、WSL上のgitへのパスを追加する。
（システム環境変数でもユーザー環境変数でもOK）

# 実行環境
- Windows11 (home)
- WSL2
    - Ubuntu 22.04
- VS Code (1.94.2)
    - devcontainer (v0.388.0)

# やったこと

Ctrl+P で「Dev Containers: Show Container Log」を選択するとdevcontainerのログを見ることができる (これに気づくのにすごく時間がかかった) 。
ログを確認すると、そもそもdotfiles関連のログが一切流れていなかったので、まずはsettings.jsonを見直す。WLS上のsettings.jsonにdotfiles関連の設定を記述していたが、Windows側のVS Codeのsettings.jsonに`dotfiles.repository`と`dotfiles.installCommand`の設定を書いてみた。

この状態で再度コンテナを起動してログを確認すると「\`git\` is not found」のようなエラーが出ていた。
検索対象のパスが「C:\\」から始まっていたことから、devcontainerのdotfilesではWindows側のPATH変数を見てgitを探しているらしい。

ということで、Windowsの環境変数（システム環境変数でもユーザー環境変数でもOK）にWSL上のgitへのパスを追加する。
Windows エクスプローラーでWSL上のディレクトリを参照できるので、そこからgitの配置されているディレクトリパスを調べる。
私の場合 `\\wsl.localhost\Ubuntu-22.04\usr\bin` をPATHに追加すると、dotfilesを読み込んでdevcontainerを起動できた。
UE5 ImGuiの導入メモ

## ImGUIを導入するときのメモ(UE5.4時点)

1.こちらで公開してくれているプラグインをダウンロードしてきます
https://github.com/IDI-Systems/UnrealImGui

2.zipファイルを解凍します
次に自身のプロジェクトのPluginsフォルダに必要なファイルをコピーしていきます

3.Pluginsフォルダが作られてない場合は自身で
```
[プロジェクト名]/Plugins
```
に作成します

4.まずはPlugins直下にImGuiフォルダを作成します

5.ImGuiフォルダ直下へ解答したzip直下に置いてあるImGui.upluginを配置します

6.zip直下に置いてあるSourceフォルダとResourceフォルダをImGuiフォルダにまるごとコピーします

こちらのような状態になったと思います

```
[プロジェクト名]/Plugins/ImGui
    Resources/
    Source/
    ImGui.uplugin    
```

7\. .uprojectファイルからVisual Studio projectを作り直します

8.リビルドをし直したらUnreal Editorを起動します
もしフォルダ構成に問題があったらビルドエラーになります

9.メニューから編集/プラグインを選択してImGuiがあったら正常に認識されています
![imgui.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173400/e2bef3e1-e636-e358-ba7c-c5c49e5744a5.jpeg)
IBM i 次世代技術者リーダーフォーラム in 天城（IBM i RiSING）で発表してきました

# 1. はじめに：IBM Power Communityイベントの概要
以下のイベントで発表してきました。

https://community.ibm.com/community/user/power/events/event-description?CalendarEventKey=303a0f20-ac0d-4d2f-8e1c-018fc6fe35bb&CommunityKey=2bf1e52c-a706-482b-86e8-018e81a19ab5&Home=%2fcommunity%2fuser%2fpower%2fcommunities%2fcommunity-home%2frecent-community-events


目的は以下の通りとのこと。

>IBM i 次世代エンジニアのための技術力向上と情報交換のため、若手エンジニアのためのコミュニティを立ち上げました！
>ワーキングチーム内で決定したテーマを全3回のプログラムを通じて研究していただくことで、IBM i 最新技術トレンドの学習とエンジニア同士のネットワーク構築を行います。

今年から始めたイベントのことのようで、会場の天城ホームステッドには40人前後の「若手」（IBM iを触り初めて10年以内）のIBM i技術者とIBMの若手メンバーが集まっていました。
通常は企業幹部などを集めたセミナーなどで利用される場所とのことでなかなか入ることができない特別な場所ということでした。

# 2. イベントの概要と主なセッション
タイムスケジュールは以下の通りです。

1日目
13:30- 開会宣言
13:40- IBM講演
14:20- グループワーク
15:50- ディスカッション
17:00- クロージング
17:10- 入浴
18:30- 夕食・懇親会

2日目
8:30- 準備/リハーサル
9:00- 成果発表会(前半)
12:00- 昼食
13:00- 成果発表会(後半)
14:10- 閉会の挨拶
14:40- 出発

会場は天城ホームステッドと呼ばれる、IBMが所有している静岡県内の施設でした。
伊東駅に到着してまず驚いたのがこれ。IBM塗装の大型バスが停まっていました。
![PXL_20241010_014538868 (中).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452338/9bdebc29-5ba5-d986-9c1f-a4212e808f7f.jpeg)


バスに揺られて40分。天城ホームステッドに到着です。
![PXL_20241010_034804224 (中).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452338/3ca0288b-ebf6-d152-65d4-956317f53ba6.jpeg)

到着後は荷物をおいたらすぐに昼食。
※このクオリティが毎食出ます。食器などすべてIBMのロゴ入り。

![PXL_20241010_030656392 (中).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452338/aa9cd93c-0c1b-b4a2-f8cf-b9b154d2cc41.jpeg)


その後にセミナーがありました。

# 3. セッション
- IBM講演
VScodeを利用したプログラム開発についての話でした。
IBM iではSEU(Source Entry Utility)というIBM iに組み込まれたエディタでプログラムを開発している方が多いのではないかと思いますが、VScodeと連携してプログラムの開発ができるという内容でした。
筆者はインフラの部門で働いているため、プログラムの開発を行う機会が多いわけではありませんが勉強になりました。


- グループワーク
IBM i技術者キャリアロードマップの作成というタスクを与えられ、事前に記入したワークシートをもとに
3年後のなりたい姿、5年後のなりたい姿、将来どのようになりたいか　をグループ内のメンバーとディスカッションしました。
みんな思いも思いの目標を立てていて参考になりました。


- 成果発表会
基本的には入れ替えを含み1チーム20分（発表15分、講評5分）です。
A~D, V-A~V-Dの8チームの発表があります。
・VScodeを利用したプログラムの開発
・生成AIとIBM iの融合
・RPG3, RPG4, FFRPGの変換
などの話題が多かったです。
発表内容は各々のグループでQiitaに掲載していると思うので割愛。
（誰かまとめてください！）

# 4. ネットワーキング
会場にはいろいろな方が来ていました。
- 事業会社でIBM iを利用している方
- IBMのパートナー企業から来ている方

ですが、やはりみなさん同じような課題を抱えているとのことのようでした。

- IBM iに関する知識を得る場所がない
- IBM i技術者の高齢化（人材育成）

私自身このようなユーザー同士の交流イベント参加するのが初めてということもありユーザー同士で会話ができる機会というのは新鮮でした。
IBM iの若手技術者ということで集まっていましたが、IBM iと関係ない雑談的な話のほうが多かったように思います。

# 5. イベントの総括と今後の展望
このような特別な場所に招待していただきIBMの皆さんありがとうございます！
来年もイベントを開催予定とのことですので少しでも興味があればぜひ参加してみてください！
これを機にIBM iコミュニティが活発になることを期待しています！
（筆者も時間のあるときにQiitaに投稿するようにします！）
Java Gold SE11対策 ネストしたクラスシリーズ③ ローカルクラスについて


前回の記事
[Java Gold SE11対策 ネストしたクラスシリーズ② staticインナークラスについて](https://qiita.com/hiroki1994/items/16ad6931f9fcce29cf4d)
の続きとして本記事では「ローカルクラス」についてまとめていく。

## ローカルクラスはメソッド内に定義されるもの
メソッド内に定義されるクラスがローカルクラスである。
ローカルクラスは定義されているメソッド内のみから利用することができる。

そのため、同じクラスでも別のメソッドからローカルクラスを利用することはできない。
これはローカル変数を別メソッドが利用できないのと同じだ。

下のSample.javaのsampleMethodメソッドのAgeクラスがローカルクラスである。

```Sample.java
public class Sample {
   // ローカルクラスを実装したメソッド
   void sampleMethod() {
      int age = 30;

      // ローカルクラス
      class Age{
         public void printAge() {
            System.out.println(age + "歳ですよ。");
         }  
      }

      // ローカルクラスへのアクセスと実行
      Age ageClass = new Age();
      ageClass.printAge();
   }
}
```


## ローカルクラスの付与可能なアクセス修飾子
ローカルクラスは前項でも説明した通り、それを定義したメソッドからしかアクセスができない。**他のクラスから利用できない**というのは言うまでもない。

そのため下記のアクセス修飾子をローカルクラスに付与することはできない。
・**public**
・**protected**
・**private**

一方で**abstract**を付けて抽象クラスにしたり、**final**で修飾することは可能だ。


## ローカル変数
ローカルクラスはそれを定義したメソッド内のローカル変数にアクセスすることができる。
改めて先ほど例に使用したSampleクラスを見ていただきたい。

ローカルクラスAgeでは、sampleMethodメソッド内のageというローカル変数を利用している。

```Sample.java
public class Sample {
   // ローカルクラスを実装したメソッド
   void sampleMethod() {
      int age = 30;

      // ローカルクラス
      class Age{
         public void printAge() {
            System.out.println(age + "歳ですよ。");
         }  
      }

      // ローカルクラスへアクセスと実行
      Age ageClass = new Age();
      ageClass.printAge();
   }
}
```

ただし、ローカルクラスから利用できるローカル変数には条件がある。

まず**ローカルクラスよりも前に宣言されている**ことだ。
先ほどの例でいうと、仮にローカル変数ageがローカルクラスよりも後に宣言されていたらコンパイルエラーが発生する。

もう一つの条件は**実質的finalである**ことだ。
次の例ではsampleMethodメソッドのローカルクラスの後にローカル変数ageを40に変更しているが、
この時点で値が変わっておりfinalな変数ではなくなって、**コンパイルエラーが発生する。**

```Sample.java
public class Sample {
   // ローカルクラスを実装したメソッド
   void sampleMethod() {
      int age = 30;

      // ローカルクラス
      class Age{
         public void printAge() {
            System.out.println(age + "歳ですよ。");
         }  
      }

      age = 40;

      // ローカルクラスへアクセスと実行
      Age ageClass = new Age();
      ageClass.printAge();
   }
}
```

これはローカル変数とローカルクラスのライフサイクルの違いによるものだ。
ローカル変数はメソッドの処理が終了するとメモリから消えてなくなるのに対し、
ローカルクラスのインスタンスはメソッドの処理が終了しても参照が残っていればメモリ上に存在し続ける。

このようにライフサイクルが異なるので、**ローカルクラスが必要としているのに、メモリ上にそのローカル変数が存在していなかったらアクセスができなくなってしまう**。なんてことも起きうるのだ。


そのようなことが起きないために、ローカルクラスにはそのローカル変数そのものではなく、**ローカル変数の値のコピー**を渡している。
コピーを渡していればローカルクラスが必要としているタイミングでローカル変数そのものがメモリ上から消えていても同じ値を持つためローカルクラスは正常に動作する。

しかし、正常に動作するのはコピーした値がお目当てのローカル変数と同じ値である ということが大前提。
そのためローカル変数の値を別の値に変えるような処理が存在すると、コピーした値と変更後のローカル変数の間で不整合が発生してコンパイルエラーが起きるのだ。



次回は匿名クラスについてまとめる。
Androidで動画再生のやり方のメモ「VideoView」

# はじめに
今回はあまり触れていなかった動画再生について、今後のために調べたのでそれのメモがわりとして記事にしておこうと思います。

# VideoView

xmlには**VideoView**を追加し、それ以外は特に専用のものを追加しなくてもいいっぽいです。
```
    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
```

```
   val videoView = findViewById<VideoView>(R.id.videoView)

    videoView.setVideoPath(~~~)
    または、        
    videoView.setVideoURI(Uri.parse("http://www.~~~~~~"))

    videoView.seekTo(0)
    videoView.start() 
```

setVideoPath()は動画のある場所を引数に渡します。
setVideoURI()で動画を指定するのも可。
seekTo(Int)は再生位置を引数に渡します。
アクションを起こした際に動画が初めから流したいのであれば、0を渡しておくのが無難かと思います。
start()で動画を再生します。


一時停止させる際は　videoView.pause()
停止させる際は　videoView.stopPlayBack()でそれぞれ動画の再生を停止できます。


# スリープモードにさせない
以下のコードは動画再生に使われるActivityに追記することで、動画再生中に端末の設定された時間で端末がスリープモードになる事を防ぎます。

```
   window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
```


# 参考

https://developer.android.com/reference/android/media/MediaPlayer

https://qiita.com/linkyuto/items/80e66964bf4d709a4fb0
【基本情報】独学マラソン プロトコル（VPN） Day 13

毎日が人生の新しいページ

:::note worn
この記事は自分用の備忘録です。
:::

# VPNの時によく使うプロトコルがあるらしいので
VPNはVirtual Private Network（バーチャル・プライベート・ネットワーク）の略。物理的な専用回線を設置せずに、仮想的な環境で専用回線を構築できるので、情報漏洩を防ぎながら安全な通信を確保し、コストを抑えることが可能になる

「VPNを利用して海外サーバ経由でアクセスして個人を特定されないようにする」みたいなスーパーハッカーの話によく出てくるよね

## **VPNプロトコルのOSI参照モデル別整理**

| **プロトコル** | **OSI層**        | **役割**             | **特徴**                                | **主な用途**      |
|----------------|------------------|----------------------|----------------------------------------|------------------|
| **L2TP**       | データリンク層 (第2層) | **トンネリング** | 単体では暗号化なし。**IPsecと併用**されることが多い | **企業VPN** |
| **IPsec**      | ネットワーク層 (第3層) | **暗号化と認証** | IPパケット全体を保護することで、高い機密性を実現 | **機密通信** |
| **TLS**        | トランスポート層 (第4層) | **暗号化** | **HTTPS**や**OpenVPN**で使用。セッション管理が強力 | **リモートワーク** |


## 3つのプロトコル（L2TP、IPsec、TLS）の詳細

### L2TP (Layer 2 Tunneling Protocol)
- L2TPは、トンネリングプロトコルの一種で、任意のアドレスの別の機器まで仮想トンネルを作成し（トンネリング）、データを送受信するためのプロトコル
- データを送る前に元のプロトコルとは別のプロトコルでラッピングしてから専用回線で送信するため、外部からの干渉を防ぎ安全な通信が可能となる
    - ただし、L2TP単独では暗号化がないため、通常はIPsecと併用することが多い

### IPsec (Internet Protocol Security)
- IPsecは、インターネット上のデータ通信を暗号化し、安全性を確保するためのプロトコル
    - IPパケット自体を暗号化し、改ざんや盗聴を防ぐ
- L2TP/IPsec構成のVPNでよく使われる

### TLS (Transport Layer Security)
- TLSは、通信の暗号化に使われるプロトコルで、インターネット上のHTTPS通信などでも利用されている
- SSLの後継（SSL3.0は脆弱性が見つかったとか）
    - TLSはSSLの設計を基に、より強力な暗号化とセキュリティ機能を備えて発展したもの
    - 現在ほぼすべての暗号化通信に使用されている
- 通信が途切れた場合でも、自動で再接続するセッション管理機能が強力
- リモートワークでの安全な通信を提供するためのVPNに広く採用

# カフェのwifiでVPN通信を使う場合の手順は？
AWSを使う場合

1.  AWSアカウントを作成
2.  EC2インスタンスの作成（サーバーの準備）
3.  OpenVPNのインストールと設定
4.  クライアントの設定ファイル（.ovpn）の作成 
5.  OpenVPNクライアントアプリをインストール
6.  .ovpnファイルをインポート
7.  接続確認


# 感想
場所に縛られない働き方ができるのはエンジニアの良いところだと思うので
海岸やリゾート、カフェとかでリモートしたい時に
VPNをきちんと使えるようにしておこうと思った

# 参考

https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_103.html

https://www.openupitengineer.co.jp/column/it-technology/3413

https://surfshark.com/ja/blog/what-is-open-vpn
最低限の環境構築① ～Next.js編～

頭の中ではうまくいっている実装でも、実際に動かしてみるとエラーになったり
予期しないWarningが発生することは多々ある。
その為、検証する環境を作っておく、またはすぐに作成できると便利だと思うので、
作業手順を備忘録の形で残しておく。

## 作業前の確認
Node.jsがインストールされていてnpx,npmのコマンドが実行できることを前提としている。
バージョン管理には、Voltaを使用。
エディタはVSCodeを使用。

## 1. まずはNext.jsのプロジェクトをWebページで表示する
好きな場所で以下コマンド実行して、プロジェクトの作成をする。
（コマンドの内容を知ることは大切だが、まずは動くものを作ることを重視）
```
npx create-next-app@latest --ts
```
最新の安定バージョンを取得するために、latestを指定。
また経験上、TypeScriptを使用しないプロジェクトはないので、--tsオプションも指定する。
（苦手でも必須になるので、必ずTypeScriptにして慣れること）

コマンドを実行すると質問が表示されるので、回答していく。
はじめての時はこれで戸惑うので、プロジェクトを作るときの回答例を載せておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513233/9d0f302e-cb03-f687-5e7d-5f49962a410f.png)

気にするのはこれらの質問
```
What is your project named? ... // 作成するプロジェクトの名前のこと
```
```
What import alias would you like configured? // とりあえずEnterを押下
```
他の質問は気にせず回答例通りにして、Enterを押下する。
※複雑にしたくないので、App Routerは未導入にする

作ったプロジェクトに移動したら、以下コマンドを実行する
```
npm run dev
```
次の画像のように表示されるので、 `http://localhost:3000`にカーソルを合わせてCtrl + クリックをする。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513233/51129288-3bb0-9e53-3abc-2f75625f013e.png)
このような画面が表示されれば、ここまでは成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513233/507d6de8-992d-f99c-7551-b4da64093067.png)

ここまでが難しい場合は、[こちらから](https://github.com/takanobu68/form_controls_next/tree/develop)クローンしてみてください。
クローン後、`npm install`すれば動きます。

## 2.Nodeのバージョンを固定する
正直個人ではあまり必要がないが、実務でプロジェクトを作るときの練習。
また、自分のPCが複数台あり、それぞれのNodeのバージョンが違うことで予期しないエラーが起きるのを防ぐために設定してみる。
Voltaがインストールできていれば、プロジェクトディレクトリで以下のコマンドを実行して完了。
```
volta pin node@latest
```
package.jsonに次のような設定が追加される。(2024年10月時点)
```
"volta": {
    "node": "22.9.0"
  }
```
[ここまでの作業](https://github.com/takanobu68/form_controls_next/tree/feature/node%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E5%9B%BA%E5%AE%9A) 

この記事では以下の作業を実施
1.create-next-appでのNext.jsのプロジェクト作成
2.VoltaでのNodeバージョン固定

最低限の環境構築②では、
フォーマットとLint周りの設定を行う。
Frog問題を勉強してみた

# 導入
 Frog問題について勉強してみた. 
# [Frog問題](https://atcoder.jp/contests/dp/tasks/dp_a?lang=ja)
```python
N = int(input())
h = [int(x) for x in input().split()]
dp = [0]*N
dp[0] = 0
dp[1] = abs(h[1] - h[0])
for i in range(2, N):
    dp[i] = min(dp[i - 1] + abs(h[i] - h[i - 1]), dp[i - 2] + abs(h[i] - h[i - 2]))
print(dp[N - 1])
```

## 解法の考え方
Step1. 値格納用のlistを作製する

Step2. 決まり切っている値を代入する
    ここではdp[0]には0,dp[1]には一つ進む以外ないのでdp[1]=abs(h[1]-h[0])しかない
    
Step3. 各状況においてmin()関数を使って最小の状況を求める
    ここではforループを用いてiを目標座標として二つのパターンにおけるスコアを求める。そのスコアが最小の方をそのその状況の最小のスコアとする。
アーキテクトの教科書（第2章）の読書メモ

# はじめに

前回に続き、アーキテクトの教科書を読んで思ったことを書き連ねていきます。

https://amzn.asia/d/7RgbJlQ

第2章は「ソフトウェア設計」です。

# 要求分析

UMLのユースケース図が紹介されていましたが、要求分析のフェーズであれば、SysMLの要求図の使用を検討してみても良いでしょう。

https://www.ogis-ri.co.jp/otc/hiroba/technical/SysEngSysML/SysEngSysML2.html

# CRCカード

CRCとは、Class（クラス）、Responsibility（責任）、Collaborator（コラボレータ）の頭文字です。

どうやら、複数人でクラス設計をするときに、カードで書いて、並べながら行うモデリング手法のようです。

一人でクラス設計する際は、私はよく、Mermaidのクラス図を書いています。

https://mermaid.js.org/syntax/classDiagram.html

Notionだと、コードを書くと、即座に図も表示されるため、試行錯誤しやすいです。

# 4つの抽象レベル（上ほど抽象度が高い）

* アーキテクチャ設計
* モジュール設計
    * コンポーネントの集合体
    * ユースケースの実行に必要な機能を提供する
    * 例：「注文モジュール」「在庫モジュール」「出荷モジュール」など
* コンポーネント設計
    * DIコンテナの管理対象となる。Helperクラスを含む。
    * 例：「注文コントローラ」「注文登録サービス」「注文リポジトリ」など
* クラス設計

本やネットでは「モジュール」と「コンポーネント」が様々な文脈で用いられることが多く、具体的な違いをイメージしづらかったのですが、本書ではこのように整理されていたため、一つの参考になりました。

ただし、Columnに記載されている通り、やはり文脈によって定義が変化するため、注意した方が良いですね。本書で提示されていた定義は一つの例として認識すると良さそうです。

# CLEANコード

以下の頭文字の集合体です。
* Cohesive（凝集性）
* Loosely Coupled（疎結合）
* Encapsulated（カプセル化）
* Assertive（断定的）
* Nonredundant（非冗長）

本書で詳しい内容が説明されていました。
設計やソースコードレビューの際に意識すると良さそうです。
「申請者による取り戻し」の実装メモ

# 「申請者による取り戻し」の実装メモ

## 完成系

### 自分が申請したレコード

![従業員ポータル内の自分の申請](https://raw.githubusercontent.com/gozu52/qiita-docs/main/ServiceNow/NowPlatform/employee_center/images/emp-center_tiket-page.png)

### クリック後

![申請キャンセルボタン押下後](https://raw.githubusercontent.com/gozu52/qiita-docs/main/ServiceNow/NowPlatform/employee_center/images/emp-center_ticket-page_after-btn-click.png)

## 構築情報

- 事前設定項目
  - [Standard Ticket Header]Widgetのクローン
  - My Request Filterでポータルページの設定

### HTML

- Widget: Standard Ticket Header
  - 44行目にキャンセルボタンを追加

```html: standard_ticket.html
<button class="cst-btn btn-danger" ng-click="c.cancelRequest()">申請をキャンセル</button>
```

### CSS

- Widget: Standard Ticket Header
  - classに命名
  - 命名に従って下記追加

```css: standard_ticket.css
.cst-btn {
    display: block;
    width: 150px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    margin-left: auto;
    text-decoration: none;
    border-radius: 4px;
}
```

### Client Script

- Widget: Standard Ticket Header
  - ボタンクリックによってサーバにキャンセルリクエストの送信
  - ServiceNowが用意しているアラートを使用しない場合はalertで代用
    - キャンセル成功の場合、失敗の場合にメッセージが出るよう設定

```JavaScript: standard_ticket_client.js
// 申請キャンセル機能
c.cancelRequest = function() {
    var confirmCancel = confirm("本当に申請をキャンセルしますか？");
    if (confirmCancel) {
        // サーバーにキャンセルリクエストを送信
        c.data.action = 'cancel';
        c.server.update().then(function(response) {
            if (response.success) {
                // alert("申請がキャンセルされました。");
                // 必要に応じて画面を更新
                c.data.status = 'cancelled';
            } else {
                // alert("キャンセルに失敗しました。");
            }
        });
    }
};
```

### Server Script

- Widget: Standard Ticket Header
  - 画面に表示されているレコードのテーブル情報を利用し、ステータスを更新
  - ServiceNowのアラートを利用する場合はこちらで設定

```JavaScript: standard_ticket_server

if(input && input.action == 'cancel'){
    var gr = new GlideRecord(tableName);
    if(gr.get(sysId)){
        // レコードのステータスを更新
        gr.setValue('state',7);
        gr.update();
        data.success = true;
        gs.addInfoMessage('申請がキャンセルされました。');
    }else {data.success = false;gs.addErrorMessage('キャンセルに失敗しました。');}
}
```

## メモ

### より業務に合わせた実装にするために必要な項目

- [ ] Client Script側にGlide Modalでポップアップの表示
- [ ] キャンセルボタンをステータスによって非表示