OmniAICreator/Qiita-1.07M huggingface dataset:
非同期処理と同期処理の違い（Promiseの例）

# モチベーション

「複数の仕事をする際に、反応を待たないで次の処理を実行する」という概念を現実的なシナリオに当てはめてみます。あなたのライフスタイルを通じて、非同期処理の考え方を理解しましょう。

# 非同期のライフスタイル

あなたは趣味でトマトをプランターで栽培しています。最初に、トマトの種をプランターの土に埋めました。トマトの成熟するまでの時間は分からないものの、実ったら美味しいカプレーゼを楽しもうと妄想します。その後、あなたはいつも通りの生活を過ごします。

あなたはプログラマーで、いつも家の窓際でPC作業をしています。時々窓の外に目を移して、プランターの様子を伺います。

2か月後、ついにその日がやってきました。赤いトマトが実ったのです！計画通り、トマトでカプレーゼを作ることにしました。トマトをスライスし、モッツァレラチーズと交互に並べ、オリーブオイルを完成！そして、辛口の白ワインと舌鼓、ああ、至福の時間…。

## 解説

この場合、あなたの振る舞いは非同期的です！あなたはトマト栽培とプログラミングのタスクを抱えていますが、トマトの成熟する間に他の作業もこなしています。もしいつ成熟するか分からないのにプランターの前で座していれば、プログラミングの仕事も進まないでしょう。実に賢明です。

そして、トマトが実ったら、待ってましたとばかりにカプレーゼに仕立て上げた手際も見事です！前々から調理するところを妄想していましたからね。

このように、トマトの成熟を待つ間に他の作業をこなし、成果を最大にする姿勢は非同期処理のイメージそのものです。

## Promiseの例

このシナリオをTypeScriptで表現すると以下のようになります。

```typescript
function live() {
  const tomatoEnjoy = new Promise<string>((resolve) => {
    // トマトが成熟する、これは時間がかかる処理
    // resolve(トマト);
  });

  tomatoEnjoy.then((トマト) => {
    // トマトをスライスする
    // トマトとチーズを交互に並べる
    // オリーブオイルをかける
    // 白ワインと一緒に楽しむ
  }).catch((error) => {
    // トマトが枯れてしまった…
  });

  // ここで、プログラミングの仕事を繰り返す
}

live();
```

Promiseを使った場合、then()の中でPromise完遂した時（トマトが実った後）にどうするかを記述することになります。また、catch()の中でPromise失敗した時（トマトが枯れた後）にどうするかを記述できます。

# 同期のライフスタイル（？）


もしくは、あなたはプランターの前でトマトが実るのを待つかもしれません。実る時期も、実るかどうかすら分かりません。それでもカプレーゼが楽しみで仕方がないのです！

## Promiseの例

プログラマーの仕事（それだけでなく、食事や睡眠も！）をカプレーゼの後に行うことを選ぶなら、トマトの成熟をawaitしましょう。

```typescript
async function live() {
  const tomatoEnjoy = new Promise<string>((resolve) => {
    // トマトができる、時間がかかる処理
    // resolve(トマト);
  });

  await tomatoEnjoy.then((トマト) => {
    // スライスする
    // チーズと交互に並べる
    // オリーブオイルをかける
    // 白ワインと一緒に楽しむ
  }).catch((error) => {
    // トマトが枯れてしまった…
  });

  // ここで、プログラミングの仕事を処理を繰り返す
}

live();
```

ここで、live()メソッドにも async キーワードが付加されていることに注目してください。awaitを使用する際には、それを含むメソッドをasyncに変更する必要があります。つまり、live()メソッド全体を非同期にします。

## 解説

こんなふうに考えるかもしれません。「トマト栽培とプログラミングを順番=同期的に行ったのに、どうして非同期なんだ！？」と。

じっくりと考えてみましょう。あなたがプログラミングの仕事に取りかかるタイミングは、いつトマトが実るかに影響されています。あなたの上司は、あなたがいつ与えたタスクを完了してくれるのか分かりません。あなたの奥さんは、あなたがいつ植木鉢とのにらめっこをやめて、家事を手伝ってくれるのか分かりません。

確かにあなたは自分の行動を同期的に進めています。しかし、あなたの周囲の人々にとって、あなたの生活は非同期的すぎるのです！おそらく、トマトが終わるのを見計らって、上司から次のタスクを、奥さんからお皿洗いの手伝いを頼まれるでしょう。

トマトを栽培しつつ、同期的に生活する（かつ、人間関係を損なわない）なんて無理な話なのです。トマトが成熟するタイミングが分からないのですから…

# おまけ：動くコード

ぜひ、TypeScript Playgroundで試してみてください。

```typescript
function live() {
  const tomatoEnjoy = new Promise<string>((resolve) => {
    let crop = 'tomato';
    let harvestPeriod = 5000;

    // 収穫に失敗した場合
    // throw new Error();

    // 収穫に成功した場合
    setTimeout(() => {
      resolve(crop);
    }, harvestPeriod);
  });

  // ここにawaitを加えることで、トマトの成長を待つことができる
  // その場合functionの先頭にasyncを加える
  tomatoEnjoy.then((crop: string) => {
    console.log('Cooking!');
    console.log('Enjoy ' + crop + '!');
  }).catch((error) => {
    console.log('Failure...');
    console.log(error);
  });
  
  console.log('programming life...');
}

live();
```

TypeScript初学者なので、解釈が間違っていることもあるかもしれません。何かお気づきの点がございましたら、ご指摘いただけると幸いです。
UIPathにおけるExcelアプリケーションスコープの罠

　皆様は、Excelアプリケーションスコープを使って構築時した後の検証でExcelでエラーが出まくった経験はないだろうか？

　特に、Excelアプリケーションスコープを複数接近させている場合だ。そうすると、動作如何で以下のエラーが出てくる。
Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED))

　この上記のエラーについてはフォーラムでもたびたび質問に上がっている。

https://forum.uipath.com/t/exception-from-hresult-0x80010108-rpc-e-disconnected/132638

https://forum.uipath.com/t/excel/82276/10

https://dobon.net/vb/bbs/log3-52/30892.html

# １，そもそもの原因
　エラーコード 0x80010108 (RPC_E_DISCONNECTED) の意味は以下の通り。
『アプリ側では参照を保持しているが、その参照は既に COM オブジェクト側から切断されている』
　
　例えば、以下のケースでエラーが発生したと致します。
『実際に、FileAからFileBに対してシートをコピーし、FileAを終了させて
FileBを保存してから終了する処理を実行したところ、FileBを保存するところで
エラー』

　この場合、FileAを動かしているExcelアプリをE1。本来、
FileAを閉じて、FileBを操作させたいExcelアプリをE2とします。

　本来であれば、以下のような動作順序であれば正常に動くはずです。
【本来の意図した動作】
FileAからFileBにシートをコピーしてFileAを終了・・・・・E1
FileBを保存して終了する処理の実行・・・・・・・・・・・E2
【実際の動き】
FileAからFileBにシートをコピーしてFileAを終了・・・・・E1
FileBを保存して終了する処理の実行・・・・・・・・・・・E1

　というようにE1→E2へプロセスが引き継がれる前にプログラムがExcelに動作させたため上記のエラーが出たものと推測されます。

　従って、フォーラムにあるように
１，Excel application scope を出る前に delayを入れる
２，Try catch等で、失敗した場合のRetry 処理を入れる。
の対応策になろうかと思います。

　しかし、それでも失敗することが多いと思いますので私が見つけた対応策を披露いたします。

# 効果的な対策案(仮)

　先ほどのフォーラムの対策案は、E1→E2への引継ぎの時間を延ばすための方策だと理解しております。一方で、E1を延命させる方法はないのでしょうか？実はあります。それが以下の方法です。

１，WorkbookApplication変数を用いて「出力」および「既存のブックを使用」に入れる。
２，WorkbookApplication型変数の出力時に「インスタンスのキャッシュ期間」をかなり長くして変更する。

参考は以下の通り。
https://docs.uipath.com/ja/activities/other/latest/productivity/excel-application-scope

　WorkbookApplication型変数を用いるとExcelアプリケーションスコープごとにExcelを閉じるという動作を防ぐことができます。それでも、COM オブジェクト側から切断される場合はインスタンスのキャッシュ期間を3000ミリ秒以上に変更すれば大量の処理の時でもエラーは発生しにくくなります。

　以上、お試しあれ。
【備忘録】主成分分析についての整理

# 概要
前回に引き続き、アウトプットをする意味も兼ねて学習した内容を整理していこうと思います。
今回は多変量解析手法の一つである、「主成分分析」について整理していきたいと思います！
正直勉強している中でわからないことがたくさんあって大変だったんですけど、その中でもわかった部分、重要だと思った部分を整理していけたらなぁと思います。
ではいきましょう。

# 主成分分析とは
主成分分析とは冒頭でもありましたが、多変量解析の手法の一つです。
主成分分析をするとどうなるか簡潔にいうとデータの次元が減ります。
どういうことかというと、例えば10種類の変数があるデータに対して主成分分析をすると変数が2つや3つに削減されます。

# どういう時に主成分分析をするのか
主成分分析では次元削減ができると前途でお伝えしました。
では何のために次元削減(変数の数を減らす)をするのでしょうか。

### 可視化したい時
人に物事をうまく伝えたい時や、データをより解釈しやすくするためには可視化がとても有効に働きます。しかしデータの次元が10次元もあったりすると人間が理解できるレベルの可視化ができません。
そこで次元削減をすることで10次元のデータを2次元・3次元などの人間が理解できるレベルの次元数に減らすことで可視化をすることができます。

### データ量を減らしたい時
数理モデルを作成するときは数値計算が伴います。そのとき次元数が多い=データ量が多いということになります。
つまり次元数を減らすとデータ量が減ることは明らかで、データ量が減ると計算量も減らすことができます。
計算量が減ると時間やコストの面で助かりますので、データ量を減らしたいときに主成分分析は用いられます。

# 主成分分析の重要な要素
主成分分析にはいくつかの重要な要素があります。

## 1. 寄与率 / 累積寄与率
これまでの説明で、主成分分析は元データから次元削減するための手法であることがわかったかと思います。ですが元々10次元あったデータが2次元のデータになった時に、当然完璧に元データを表現できる訳ではなく、ある程度のデータが次元削減とともに失われます。

寄与率とは主成分分析によって得られた主成分が元データをどれくらい表せているのかを示す値です。

例えば主成分分析によって10次元のデータから5つの主成分を生成したとき、第一主成分の寄与率が40%であれば、第一主成分は元データの40%を表しているということになります。

そして累積寄与率とは第一主成分から順に寄与率を足した値になります。

この寄与率と累積寄与率は主成分分析を評価する上で重要な値になります。
なぜなら寄与率が悪ければ主成分分析によって得られたデータが元データを表現できていないことになるからです。
評価の基準としては第四主成分までの累積寄与率が70~80%以上あると良いとされています。

## 2. 主成分得点
主成分得点とは主成分分析によって生成された主成分の数値のことを指します。
ただ主成分得点を見るだけではそれが何を表しているのかを理解・解釈するのは難しいです。
この主成分得点の結果を解釈するために先ほど説明した寄与率や、これから説明する主成分負荷量があります。

なので、主成分得点とは主成分分析によって新たに生成された変数の値であると理解して良いと思います。

## 3. 主成分負荷量
主成分負荷量とは元々のデータの変数と各種成分の関連の大きさを表しています。
主成分負荷量は正の値や負の値をとりますが、符号はそれぞれの方向性を表しており、絶対値が大きければ符号の方向に強い関連を持っているということになります。

例えば10科目の教科に対しての成績を表しているデータを主成分分析し、4つの主成分が得られたとします。
第二主成分を見たときに国語や英語などの文系科目が負の値を取っていて、数学や化学などの理系科目が正の値を取っているとき、第二主成分は文系理系を分ける軸であることがわかります。

ただしこれらの解釈に正解は無く、解釈についてはあくまで人間側で行う必要があるということに注意しなければいけません。

# 主成分分析の流れ
主成分分析をPythonで実装するときの流れを整理します。

1. データの前処理
    1. 相関のない不要な変数の削除
1. データの標準化
1. 主成分分析の実行
    1. インスタンス化
        1. 主成分の数の指定
        1. 乱数の指定
1. 寄与率の確認
1. 主成分負荷量の確認
1. 可視化
1. 結果の解釈


# まとめ
主成分分析ではデータ量の多いデータの次元削減をし、より解釈しやすい形で表現する分析手法でした。肝心となるのは少ない変数でできるだけ元データを表現できているかという点で、それは寄与率を確認することで評価できます。
また、主成分分析によって生成される主成分得点を見るだけではなかなか結果を解釈することができないので、主成分負荷量を求めることで、各主成分が元データのどの変数とどれくらい関連があるかを見ることで、結果の解釈につながります。

そして次元が削減されることで可視化がしやすくなるので、主成分分析を用いて各データの関連性を探ることができます。

以上が主成分分析の概要の整理でした。
ではまた。
既存のRailsのwebアプリをdocker化する方法

## 今回構築したい環境
- 既存のRailsのWebアプリをdocker化し、docker-compose upでRailsプロセスとdbが起動し、http://localhost:3000 でこのwebアプリにアクセスできるようにする。
- Rubyのバージョンは3.2.2を使用する。 
- DBはpostgresを使用し、バージョンは１２を使用する。
- ホストのファイルシステムとコンテナのファイルシステムを同期している。

## Dockerfileを作成
①下記のLinuxコマンドを実行し、空のDockerfileを作成します。
```cmd
$ touch Dockerfile
```

②作成したDockerfileに以下のようなDockerコマンドを記述していきます。
```Dockerfile
FROM ruby:3.2.2
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    postgresql-client \
    yarn
WORKDIR /rails-docker
COPY Gemfile Gemfile.lock /rails-docker/
RUN bundle install
```

## docker-compose.ymlを作成
①下記のLinuxコマンドを実行し、空のdocker-compose.ymlを作成します。
```cmd
$ touch docker-compose.yml
```

②作成したdocker-compose.ymlに今回構築したい環境の情報を記述していきます。
```yml
version: '3'

volumes:
  db-data:

services:
  # railsの設定
  web:
    build: .

    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    environment:
      - 'DATABASE_PASSWORD=postgres'
    volumes:
      - '.:/rails-docker'
    ports:
      - '3000:3000'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  # postgresqlの設定
  db:
    image: postgres:12
    volumes:
      - 'db-data:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
```

## database.ymlに環境情報を追記
①config/database.ymlの中のdefault: &defaultに以下を追記します。
```yml
  host: db
  user: postgres
  port: 5432
  password: <%= ENV.fetch("DATABASE_PASSWORD") %>
```


## docker imageをビルド
①下記のコマンドを実施し、docker imageをビルドします。
```cmd
$ docker-compose build
```

## docker-compose upでコンテナを起動
①下記のコマンドを実施し、コンテナを起動します。
```docker
$ docker-compose up
```

## DB 作成
①下記のコマンドを実施し、DBを作成します。
```docker
$ docker-compose run web rake db:create
```

## migrate を実施
①下記のコマンドを実施し、DBのmigrate を実施します。
```docker
$ docker-compose exec web bash
$ rails db:migrate
```

## localhostにアクセスする
①http://localhost:3000/ にアクセスしてrailsの画面が表示されていれば成功です。
pictureタグを使って画像をレスポンシブに切り替えるやり方の話

# 概要
最近、ご利用ガイドページのマークアップを修正するタスクがあったのですが、「あれ、PC版とSP版ってどうやってだし分ければいいだっけ」となり、その時の解決方法を備忘録的にも残しておこうと思い、執筆しました。
結論としてはpictureタグを使えばよかったです。下に実際のコード載せておきます。

# 実際に使ってみた
srcset属性を、media属性で条件が一致したときに表示する画像のパスにしてあげる。
使い方はこんな感じ。
```
<picture>
  <source srcset="画像のパス" media="(min-width: 1024px)">
  <img src="画像のパス" alt=”代替テキスト”>
</picture>
```

ちなみにsourceタグは複数使えます。
```
<picture>
  <source srcset="画像のパス" media="(min-width: 1024px)">
  <source srcset="画像のパス" media="(min-width: 768px)">
  <img src="画像のパス" alt=”代替テキスト”>
</picture>
```
これだと、最初のsourceタグの画像が最も優先度が高くなる。

ちなみに、画像を別で表示したいとき(ここでいうと画像1と画像2)はpictureタグは分けて作ってあげてね(当たり前やろ)。
僕はこれでやらかしたので。
```
<picture>
  <source srcset="画像1のパス" media="(min-width: 1024px)">
  <img src="画像1のパス" alt=”代替テキスト”>
</picture>

<picture>
  <source srcset="画像2のパス" media="(min-width: 1024px)">
  <img src="画像2のパス" alt=”代替テキスト”>
</picture>
```
divタグをpictureタグで代用もできそうだね。
めちゃくちゃ初歩的な記事だけど許して。
作業効率を上げるためにしたこと５点

## 初めに
作業効率を上げるために当たり前のことでやったことを5つ紹介させていただきます。
全て基本的なことですが効果は必ずあるというものです。
もっとこうしたほうがいいとか、こんなやり方もあるとか意見いただけると嬉しいです！

## 環境
| 開発環境   |バージョン    |
|-----------|------------|
| __Mac__ | M1 |

## 作業効率を上げるためにやったこと
### 1. タブを閉じる
　使用したブラウザのタブ、vscodeのタブを閉じることです。
　どういうことかというと、タブは意識して閉じていかないと、どんどん増えていき、
　どこに何があるかがわからなくなります。
　今日一日で頻度高く使う予定あるなーというタブ以外は基本的には閉じていいと思います。
　探す時間をできるだけ削減しましょう。

### 2. ブラウザのお気に入りを整理する
　ブラウザのお気に入りを整理することは、時間を有効に使う最高の方法です。
　「プロジェクト毎」、「開発ツール」、「管理（個人）」、「管理（業務）」等。
　１と組み合わせることで探す時間を大きく削減できます。

### 3. ショートカットキーを使う、試す
　ショートカットキーは色々なところで力を発揮します。
　スプレッドシートやvscode、ブラウザ操作などなど使うと数秒稼げるので、
　その分が積み重なり非常に大きな時間になります。
　ショートカットキーについても記事を書いていますので参考にして見てください。

https://qiita.com/fuku_rin/items/ccb540440ba38a18234b

https://qiita.com/fuku_rin/items/c8d2568ffb076b364aa5

### 4. Maccyを使う
　「Maccy」とは、「command + c」でコピーしたものを保持できるツールです。
　つまり過去にコピーしたものをもう一度使いたいなーって時とかに非常に便利です。
　windowsの方は、ツールのインストールは必要無く、「windowsボタン + v」で
　実行可能です。
　ぜひお試しください。地味に効率あがります。

https://maccy.app/

### 5. よく使用するコマンドをメモにまとめておく
　よく使用するコマンドはNotionなどのメモツールにまとめておいて、すぐに取り出せる
　ように準備しましょう。
　わかっているけど、できていない人が多くいます。
　できるけど、やっていないことを愚直にやってきましょう。

## 最後に
最後まで閲覧いただきありがとうございました。
ご意見、ご指摘ありましたら、コメントお願いいたします。
Cannot find module '@testing-library/jest-dom/extend-expect'エラーが出る

# はじめに

Jestを設定していたときにChatGPTに頼っていたところうまく行かなかったのでまとめます

# 問題

以下のテストを書いたところエラーが出ました

```tsx:page.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/dom";
import { About } from "../page";

describe("About", () => {
  it("Aboutというタイトルがあること", () => {
    render(About());
    const aboutImage = screen.getByTestId("about-image").querySelector("img");
    expect(aboutImage!).toBeInTheDocument();
  });
});
```

```
 Cannot find module '@testing-library/jest-dom/extend-expect' 
```

# 解決方法

そもそも最新の@testing-library/jest-domでは、extend-expectのインポートは不要になりました

なので以下をインポートするだけでうまく動くようになりました

```tsx:page.test.tsx
import '@testing-library/jest-dom';
```

# おわりに

ChatGPTに頼りすぎると思わぬところで沼ってしまうことがよくわかりました
ある程度のところでネットで調べたり、聞き方を変えてみたりしないといけないです
React testing-libraryのRenderでbut is being used as a type hereがでる

# はじめに

testing-libraryを初めて利用したのですが、そこでかなり解決までに時間がかかり、ChatGPTでは解決ができなかったのでまとめます

# 問題

以下のコードを書きました

```ts:test.spec.ts
describe("About", () => {
  it("Aboutというタイトルがあること", () => {
    render(<Page />);
    const aboutImage = screen.getByTestId("about-image").querySelector("img");
    expect(aboutImage!).toBeInTheDocument();
  });
});
```

しかし`render(<Page />);`で以下のエラーが発生します

```
'Page' refers to a value, but is being used as a type here. Did you mean 'typeof Page'?
```

# 解決方法

これは`拡張子`に問題が有りました

`page.spec.ts`ではなく`page.spec.tsx`が正しいです

# おわりに

なかなか同じようなところで困った人はいないようで解決までに苦労しました
普段関数のテストばかり書いていたのでそののりでファイル作成していました
[Python / numpy] np.datetime64 型のデータを ビルトインの datetime.datetime 型にしたい時

# 概要

これってどういう時必要なのか、というと、以下のような時。

```python:python
import numpy as np
from datetime import timedelta

np_today: np.datetime64 = np.datetime64("2023-08-24")
np_tomorrow: np.datetime64 = np_today + timedelta(days=1)

# NOTE: この時、以下のようなエラーが発生する
numpy.core._exceptions._UFuncBinaryResolutionError: ufunc 'add' cannot use operands with types dtype('<M8[ns]') and dtype('O')
```

1日足したいだけなのに。


# 調べたこと

調査中、頑張ってる人たちを見かけたけど、

https://qiita.com/Kanahiro/items/3ed1372358735c83884c

https://www.datasciencelearner.com/numpy-datetime64-to-datetime-implementation/#google_vignette


# 結論

`pd.Timestamp` だけで OK。

```python:python
import numpy as np
import pandas as pd
from datetime import timedelta

np_today: np.datetime64 = np.datetime64("2023-08-24")
# pd.Timestamp() で変換してあげると、 timedelta を加算できる
np_tomorrow: pd.Timestamp = pd.Timestamp(np_today) + timedelta(days=1)
np_tomorrow
>>> Timestamp('2023-08-25 00:00:00')
```


# 参考にした記事

結局 stackoverflow が強い。

https://stackoverflow.com/questions/13703720/converting-between-datetime-timestamp-and-datetime64


また、以下の記事によると、 `pd.Timestamp` は `datetime.datetime` 型を継承しているようです。

https://note.nkmk.me/python-pandas-datetime-timestamp/#:~:text=Timestamp%E5%9E%8B%E3%81%AFPython%E3%81%AE%E6%A8%99%E6%BA%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AAdatetime%E3%81%AEdatetime%E5%9E%8B%E3%82%92%E7%B6%99%E6%89%BF%E3%81%97%E6%8B%A1%E5%BC%B5%E3%81%97%E3%81%9F%E5%9E%8B%E3%80%82

つまり、 `datetime.datetime` 型で使えるメソッドは、 `pd.Timestamp` からも呼び出せると言えるのかなと思います。

ただし、以下の公式サイトを見ても、そのような記述は見つけられなかったので、実際に動作確認して使ってくださいね。

https://pandas.pydata.org/docs/reference/api/pandas.Timestamp.html
AWS WAF ベーシックな設定について

AWS WAF（Web Application Firewall）は、Amazon Web Services（AWS）が提供するウェブアプリケーションファイアウォールサービスです。このサービスは、ウェブアプリケーションを悪意のあるトラフィックや攻撃から保護するためのものです。

# AWS WAFとは？
AWS WAFは、ウェブアプリケーションやAPIに対する一般的なウェブ攻撃を検出し、ブロックするためのサービスです。これにより、SQLインジェクションやクロスサイトスクリプティング（XSS）などの攻撃を防ぐことができます。

# AWS WAFのメリット

カスタマイズ可能: AWS WAFは、特定のトラフィックパターンや攻撃を検出・ブロックするためのカスタムルールを設定することができます。
リアルタイムのモニタリング: AWS WAFは、リアルタイムでのトラフィックの監視とログの取得が可能です。
スケーラビリティ: AWSのインフラストラクチャを利用しているため、大量のトラフィックにも対応可能です。
統合性: AWSの他のサービスとの統合が容易で、例えばAmazon CloudFrontと組み合わせることで、エッジロケーションでのトラフィックのフィルタリングが可能です。
# AWS WAFのデメリット

コスト: 有料サービスであり、使用量や設定したルールの数に応じて料金が発生します。
学習曲線: 初心者にとっては設定やルールの作成が複雑に感じることがあります。
過度なブロック: 誤って正当なトラフィックをブロックするルールを設定すると、正常なユーザーがサービスを利用できなくなるリスクがあります。
WAFの設定は確かに手段の一つですが、その背後にはウェブアプリケーションのセキュリティを強化するという目的があります。WAFを適切に設定し、運用することで、ウェブアプリケーションのセキュリティを大幅に向上させることができます。

# 実際にお客様より相談いただいたケース
Q セキュリティ対策として、なんでもいいのでWAFを有効化していただきたい。
A CRSと、スロットリングを適用した
<jest> ts error: プロパティ 'toBeInTheDocument' は型 'JestMatchers<HTMLElement>' に存在しません。

Next.js v13 のテストに react-testing-library と jest を入れようとした時に遭遇した時のエラー

# 背景
[Next.js の公式](
https://nextjs.org/docs/pages/building-your-application/optimizing/testing#jest-and-react-testing-library)に従って jest を setup しました。
```bash:terminal
npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
# 載ってないけど追加
npm install --save-dev @types/jest
```

`testing-library/jest-dom` のインポート用にsetup.jest.js を追加してます。

```js:jest.config.mjs
import nextJest from 'next/jest.js'
 
const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})
 
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],  // 追加
  testEnvironment: 'jest-environment-jsdom',
}
 
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)
```

```jest.setup.js
import '@testing-library/jest-dom'
```


# エラー
![スクリーンショット 2023-08-26 17.48.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/35fa100a-bc0f-62a7-9def-8db36a12a8e6.png)

# 解決
tsconfig.json の include に `./jest.setup.js` を追加すれば ok

```json:tsconfig.json
{
  "include": [
    // ...
    "./jest.setup.js"
  ],
}
```

全ては公式に書いてあった

https://github.com/testing-library/jest-dom
ldapsearch②

## ldapseachの第2弾

色々調べていたらまた面白いコマンドを見つけた。

### 全量取得手順
```
ldapsearch -x
```


### 管理用情報取得手順

```
ldapsearch -x -s base "(objectclass=*)" "*" "+"
```


https://l-w-i.net/t/openldap/ldapsearch_001.txt
Python の浅いコピーと深いコピー

## はじめに

Python でオブジェクトをコピーした際にどこまで別オブジェクトとしてコピーされるかの整理です。


## 動作確認

### コピーなし

```python
# 共有渡し
# （同一オブジェクト）
x = ['1', ['2', '3']]
y = x
y[0] = 'A'
y[1][0] = 'B'

print(f'x = {x}')  # x = ['A', ['B', '3']]
print(f'y = {y}')  # y = ['A', ['B', '3']]
```

### 浅いコピー

```python
# 浅いコピー 
# (第1階層('1')は別オブジェクトになるが第2階層以降(['2, '3])は同一オブジェクト)
x = ['1', ['2', '3']]
y = list(x)
y[0] = 'A'
y[1][0] = 'B'

print(f'x = {x}')  # x = ['1', ['B', '3']]
print(f'y = {y}')  # y = ['A', ['B', '3']]
```

### 深いコピー

```python
# 浅いコピー 
#  (全オブジェクトが別オブジェクト)
import copy
x = ['1', ['2', '3']]
y = copy.deepcopy(x)
y[0] = 'A'
y[1][0] = 'B'

print(f'x = {x}')  # x = ['1', ['2', '3']]
print(f'y = {y}')  # y = ['A', ['B', '3']]
```

## 参考資料
- 『Pythonトリック』<br>https://www.amazon.co.jp/Python%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF-Dan-Bader/dp/4798157678


## おわりに

Pyhonに限ったことではありませんが、特に入れ子のオブジェクトの場合は、それぞれの階層のオブジェクトの値を変更した場合、代入元と代入先のそれぞれのオブジェクトの値がどのようになるのかを意識しないと痛い目に会いそうですね。
ldapsearch①

## ldapsearch

ユーザの情報の詳細を調べる必要があって
１つ１つのユーザに対してldapsearchを実行するのは大変だなって思っていました。

そうしたらいいコマンド見つけました

### 負荷させ気にならなければこのコマンドが一番いい。

```
 ldapsearch -x -b 'ou=People,dc=srv,dc=world'
```

### １つ１つのユーザ情報を取得する場合は

```
 ldapsearch -x -b 'uid=redhat,ou=People,dc=srv,dc=world'
```

https://www.server-world.info/query?os=CentOS_7&p=openldap&f=5
【流出解析】シリーズ　第12回　表面流モデル【定常降雨：後編】

# 移転のお知らせ

こちらの記事は下記のサイトに移転しました。

> [NNテックブログ](https://nnhiroba.xsrv.jp/nnTechBlog/Article/Article?ID=44)
Python で関数の動作を外部から変更したり拡張する

## はじめに

Python で全ての関数の実行前後に共通で開始と終了メッセージを表示させる効率的の方法がないかを調べていた時に見つけました。


## デコレータ [decorator]

### デコレータとは

関数をデコレート（ラッピング）することで、デコレートされた関数を実行する残後にコードを実行することができる機能。

### 実装例

```python
import functools

def trace(f):
    @functools.wraps(f)
    def decrated_function(*args, **kwargs):
        print(f'TRACE-S: {f} {args} {kwargs}')
        result = f(*args, **kwargs)
        print(f'TRACE-E: {result}')
    return decrated_function

@trace
def hoge(arg1, arg2):
    print('exec hoge.')

hoge('a', 'b')
# TRACE-S: <function hoge at 0x000001E0FFD27B50> ('a', 'b') {}
# exec hoge.
# TRACE-E: None
```

### 補足

- 入力関数（上記だとhoge）のメタデータアクセスしようとするとカスタムデコレータ（上記だとtrace）のメタデータが表示されるため、@functools.wraps(f)をカスタムデコレータに適用することで入力関数（上記だとhoge）のメタデータを引き継ぐようにする。

### デコレータを複数適用する場合
下から順に適用される。
```Python
@decorator2
@decorator1
def xxxxx:
    pass

# -> decorator2(decorator1(xxxxx))()
```

## 参考資料
- 『Pythonトリック』<br>https://www.amazon.co.jp/Python%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF-Dan-Bader/dp/4798157678


## おわりに

業務処理と共通処理を分離できるので効果的かなと。例外発生時のログ出力とかもログ機能と絡めて共通化して切り離せると尚よいですね。
Mac(x86)でqemuをお試し

※この記事は個人的なメモとしての役割が大きく、詳細な説明は致しません。

# はじめに
久しぶりにpodmanを利用しようとしたところ、`podman-machine-default`が動作せずに困りました。
せっかくなので今まで触れてこなかったqemuを少しでも扱えるようになろうと、お試しで動作させてみました。

# 環境
- OS
    - MacOS
- CPU
    - x86_64
- パッケージマネージャ
    - Homebrew 4.1.5
- qemu
    - 8.0.4

# インストール
```
brew install qemu
```

# OSイメージ
今回は無難にUbuntsu Serverを使用します。
以下からisoファイルを入手します。
https://jp.ubuntu.com/download

# disk img
`qemu-img`コマンドを使用して、VM用ハードディスクとなるdisk imgを作成します。
後ほど、このdisk imgを使用してVMを起動させます。

もっと詳細なオプションもありますが、基本的な書式は以下です。
```:書式
qemu-img create -f [フォーマット] [ファイル名] [容量]
```
今回は`qcow2`形式で`15GB`のイメージを作成します。
```:実行例
qemu-img create -f qcow2 ubuntu22.qcow2 15G
```

# 起動
## 初回
`qemu-system-x86_64`コマンドを使用して、VMを起動させます。
初回はインストールが必要なので、`cdrom`オプションがついています。
```:書式
qemu-system-x86_64 -cdrom [OS img] -boot order=d -m [メモリ容量] -drive file=[disk img file],format=[フォーマット]
```
上述の手順で作成したdisk imgを指定し、起動コマンドを実行します。今回のメモリ容量は8GBです。
```:実行例
qemu-system-x86_64 -cdrom ubuntu-22.04.3-live-server-amd64.iso -boot order=d -m 8G -drive file=ubuntu22.qcow2,format=qcow2
```

別ウィンドウが開いてUbuntu Serverのインストール画面が出力されれば成功です。

## 2回目以降
2回目以降はインストールが不要なので、`cdrom`オプションはありません。
こちらも、より詳細なオプションがありますが、基本的なものを記載します。
```:書式
qemu-system-x86_64 -boot order=d -m [メモリ容量] -drive file=[disk img file],format=[フォーマット]
```
今回のメモリ容量は16GBです。なんとなくです。
```:実行例
qemu-system-x86_64 -boot order=d -m 8G -drive file=ubuntu22.qcow2,format=qcow2
```


以上です。
はじめに書いた通り、メモ要素が強いので、今後もなにか進捗があれば(しれっと)追記するかもしれません。

# 参考
- [QEMU \- ArchWiki](https://wiki.archlinux.jp/index.php/QEMU)
【JavaScript】即時関数とは

### はじめに

JavaScriptの即時関数の理解が曖昧だったのでまとめました。

### 即時関数とは

 JavaScriptの関数の形態の一つで、**定義されるとすぐに実行される**という特徴を持ちます。
英語では**Immediately-Invoked Function Expression**、**IIFE**と呼ばれます。

構文は次のようになります。

```jsx
(function() {
	//処理
})();
```

もしくは

```jsx
((function() {
	//処理
}())
```

アロー関数の形では次のように書けます。

```jsx
(() => {
	//処理
})();
```

### 即時関数のメリット

**変数の有効範囲を狭くすることができる**ということです。

即時関数を使用すると処理が一時的なスコープの中で実行されるため、変数の有効範囲を狭くすることができます。

変数の有効範囲を狭くすることは、可読性や保守性を高めるために重要なことです。
(参考: [変数と関数の有効範囲を最小限にする](https://www.jpcert.or.jp/sc-rules/c-dcl19-c.html))

また、即時関数を使用することで変数名や関数名の衝突を防ぐこともできます。

### 即時関数のデメリット

- 関数の再利用ができない
- 即時関数を多用してスコープが多くなるとメモリを多く消費する可能性がある

などのデメリットもあります。

### 即時関数を使用する場面

- 変数のスコープを限定したい
- ライブラリやフレームワークとの名前の衝突を防ぎたい
- 初期化処理を一回だけ行いたい

### 参考サイト

[JavaScriptで即時関数を使う理由](https://qiita.com/katsukii/items/cfe9fd968ba0db603b1e)
[JavaScriptの即時関数](https://tokitsubaki.com/javascript-immediately-function/548/)
[変数と関数の有効範囲を最小限にする](https://www.jpcert.or.jp/sc-rules/c-dcl19-c.html)
QuestProでパススルー機能が透明にならない際の修正

# QuestProを利用したパススルー機能
QuestProのカラーパススルー機能を使ったアプリを作成しようとしました。その際にパススルー機能を使っていても透過されず、色がついている状態で表示されてしまいました。その修正方法です。

# パススルー機能の参考にしたサイト
パススルー機能自体は下記のサイトを参考にさせて頂きました。
自分は途中のOVR Passthrough Layerを追加するところを追加し忘れてパススルーが効かないこともありました。

https://zenn.dev/iwaken71/scraps/50ff851adfbe67

https://qiita.com/b0bmat0ca/items/bc5ce8e38979d4680402


# 今回の問題
パススルー自体は出来たのですが、透明でのパススルーではなく色味がついていたパススルーになってしまいました。

 # 問題の修正方法
この色味がOVRCameraRigのEyeAnchorに設定されているBackGroundの値を設定することで修正することが出来ました。
修正前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/c73da6ec-6a65-3910-dba0-0453915d58d7.png)
修正の際に設定する値はR:0, G:0, B:0, A:0で設定をして透明にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/397eaaad-c441-5031-7af8-9a8a3e843007.png)
修正後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/42de054f-6ab1-3cc2-03de-7337d0d90d00.png)

このように修正することによって、色味がついていない透明なパススルーを実現することが出来ました。
色味をつけたパススルーを実装する際にも利用することが出来そうです。

# まとめ
今回、QuestProで透明のカラーパススルーを実現する際に躓いたところと、その修正方法でした。
このシステムをカラーパススルー対応させる際に躓いていたのですが、解決することが出来たので良かったです。

https://qiita.com/Ah_/items/c6689292d3b8bc218bbb
「(最新) 図解でわかるPCアーキテクチャのすべて」を読んだメモ

こちらの本を読んだ際の雑なメモ。自分の知識として漏れていたところだけメモる。

https://www.njg.co.jp/book/9784534045706/

## (P.61) 論理回路

- 組み合わせ回路 `combinational circuit`
    - ①基本論理回路 `basic logic gates`
        - = AND回路/ OR回路/ NOT回路/ NAND回路/ NOR回路/ EXOR回路
    - ②算術演算器 (built with ①)
        - = 内部的には、Half Addrer と Full Adder の組み合わせ
- 順序回路 `sequential circuit`
    - ③フリップフロップ (built with ①)
    - ④カウンタ (built with ②③)
    - ⑤レジスタ (built with ②③)

## (P.107) バスマスタ

一昔前は、CPUがバスを占有していた。
現在は、マザーボードのチップセットにその権限を与えることで、負荷を軽減している。

例えば、メモリ<->HDD間のデータ転送は、マザーボード上のDMAコントローラがバスマスタとしてデータの転送を行なっている。

## (P.213) SRAM vs DRAM

SRAMは、フリップフロップ回路を使用している。複数個ののトランジスタにより１ビットを構成している。CPUのレジスタやキャッシュメモリはSRAMを使用している。

DRAMは、コンデンサなどへの電荷量により、メモリ機能を実現している。１つのトランジスタにより１ビットを構成している。メインメモリはDRAMを使っている。

## (P.150) CPUの並列実行技術

- パイプライン処理を並行実行する。
    - `スカラ` = 単一プロセッサ内で、パイプラインを並行実行するアーキテクチャ。
    - `スーパースカラ` = 複数のプロセッサで、パイプラインを並行実行するアーキテクチャ。

- `ハイパースレッディング` = 一つのCPUを擬似的に二つのCPUと認識させ、一つのCPUで複数のスレッドを同時実行。(パフォーマンスは30%程度向上)


## (P.195) マイクロアーキテクチャ

マイクロアーキテクチャとは、コンピュータのCPU（MPU/マイクロプロセッサ）内部の回路の設計や構造のこと。信号の伝送路や機能ブロックなどの物理的な構成、命令の実行制御の方式などを定めている。[ref](https://e-words.jp/w/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3.html)

以下二つ紹介する。

### (P.196) NetBurstマイクロアーキテクチャ

Inten社が2000年に発売したPentium Dで採用されている。
以下により性能向上を図った。

- 高クロック化
- プロセスルールの微粒化

しかし、多量の消費電力と熱の発生が問題となり、Coreマイクロアーキテクチャに取って代わられた。

### (P.201) Coreマイクロアーキテクチャ

Intel社が2007年に発売したCore2 Duoで採用されている。
以下の機能が含まれる。
- wide dynamic execution
- intelligent power capability
- advanced smart cache
- smart memory access

## (P.244) メモリマッピングの種類

- ページ方式
- セグメンテーション方式
- ページセグメンテーション方式


**TODO**: OSTEP [§20. Paging: Smaller Tables](https://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf) を読み直し、長所短所をまとめる。


## (P.309) ソフトウェアRAID vs ハードウェアRAID

ソフトウェアRAIDは、ソフトウェア(OSなど)が複数のディスクをRAIDとして統合利用する。手軽にRAIDを実現できるが、制御負荷がCPUにかかる。

ハードウェアRAIDは、専用のRAIDボードを増設し、これに対して複数のハードディスクを接続する。この専用ボード内の専用チップがRAID制御を行ってくれ、OS側には一台のハードディスクとして認識させることができる。高価なものが多い。

**TODO**: OSTEP [§38. Redundant Arrays of Inexpensive Disks: RAIDs](https://pages.cs.wisc.edu/~remzi/OSTEP/file-raid.pdf) を読み直し、長所短所をまとめる。
vCenter Server に SSH するときは公開鍵認証を切る

SSH できなかった。

```
$ ssh vcenter -l root  

VMware vCenter Server 7.0.0.10100

Type: vCenter Server with an embedded Platform Services Controller

Received disconnect from UNKNOWN port 65535:2: Too many authentication failures
Disconnected from UNKNOWN port 65535
```

公開鍵認証を着ればいいだけだった。

```
$ ssh vcenter.jn.sfc.keio.ac.jp -o 'PreferredAuthentications=password' -l root 

VMware vCenter Server 7.0.0.10100

Type: vCenter Server with an embedded Platform Services Controller

root@vcenter's password: 
Connected to service

    * List APIs: "help api list"
    * List Plugins: "help pi list"
    * Launch BASH: "shell"

Command>
```

## 参考文献

https://tcude.net/vcenter-too-many-authentication-failures/
Reactで動的な値を使ってMUIアイコンを表示する

実務の中でどのアイコンを使うか決まっていないコンポーネントを作成する必要があったのでその忘備録です。

イメージとしては新規に作成したアイテムに後からアイコンを紐づける感じです。
この場合、アイコン名が動的の要素となるので`<HogeIcon />`という呼び出し方が書けませんでした。
代わりの実現方法を調べた結果、モジュールの全てをインポート、動的な値でアクセスしたモジュールを`React.createElement()`を使ってReact要素を作成する方法が見つかりました。

1. モジュールの全てをインポート
`import * as muiIcons from "@mui/icons-material"`
2. モジュールのアクセス
`const icon = muiIcons[iconName]`
3. React要素の生成
`React.createElement(icon)`


## 実装例

CodeSandboxに実装例を置いています。
ここではセレクトメニューからアイコン名を選び、横の追加ボタンを押すことで選択中のアイコンが追加される例を作成しました。

https://codesandbox.io/embed/dynamicimporticons-forked-ysnqxw?fontsize=14&hidenavigation=1&theme=dark

## 参考記事

[React + Material UIで動的にMaterialアイコンを表示する](https://qiita.com/ntm718/items/d70dced7aaa77fea80b8)
VScodeのファイル検索時に新規ウィンドウでファイルを開く方法

# エクスプローラーからではなく、検索からファイルを開くとき
VScodeの左上の虫メガネボタンでファイル検索をして、検索結果をクリックすると、そのファイルの該当箇所を開くことができる。

開く際、既に開いているタブのファイル名が斜体になっていると、新規タブで開かず、斜体のウィンドウタブを消してしまう。

# 解決法その１
新規タブで開くには、検索結果をクリックするのではなく、ドラッグしてタブのところにもっていけばよい。
![画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603341/edcdf7b6-3e37-cbae-9ac6-284f7bda6784.png)

# 解決法その２
閉じたくないファイルを開くときに、クリックで開くのではなくダブルクリックする

# 解決法その３
閉じたくない斜体タブのファイル名のところをダブルクリックする
　

ちなみに、私は設定からenable previewオフとopen in new windowオンをやってもダメでした。
【React】コンポーネントのライフサイクルとは

### ライフサイクルとは

Reactコンポーネントが生成→更新→削除されるフローのことをライフサイクルと言います。

Reactではこれらの各過程を下記のように呼びます。

| 過程 | 呼び方 |
| --- | --- |
| 生成 | mount |
| 更新 | update |
| 削除 | unmount |

### ライフサイクルメソッドとは

Reactではライフサイクルの各過程において実行されるメソッドが用意されており、これを********************ライフサイクルメソッド********************といいます。ライフサイクルメソッドをオーバーライドすることで、特定の処理を特定の時点で実行することができます。

各時点で実行される代表的なライフサイクルメソッドがまとめられたチートシートがReact公式で用意されています。

[React公式 ライフサイクル図](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)

これらのライフサイクルメソッドは**クラスコンポーネント**です。

### useEffectとは

下記ライフサイクルメソッドをクラスコンポーネントではなく**関数コンポーネント**の中でまとめて実現できる機能です。

- componentDidMount (コンポーネントのマウント直後に呼び出される)
- componentDidUpdate (setStateuでコンポーネントの値が更新された後に呼び出される)
- componentWillUnmount (コンポーネントがアンマウントされて破棄される直前に呼び出される)

useEffectは**レンダリング後**と**再レンダリングされたとき**に呼び出されます。

### useEffectの使い方

useEffectは下記のように記述します。

```jsx
useEffect(() => {
	//第一引数
	//ここに記述した処理はレンダリング後に実行される(初回のレンダリング後に必ず実行)

	return () => {
		// クリーンアップ(アンマウント直前)の処理
		// 記述は任意
	}
}, 
	// 第二引数
	// この配列内の変数に変化があった場合のみuseEffectを実行する
	// 空の配列の場合は初回レンダリング後のみ実行
  [変数1, 変数2, …]
)
```

### 参考資料

[【React】useEffectの基本的な使い方・活用術・注意点](https://qiita.com/cheez921/items/f3ff76865f943345107c)

[【React入門】useEffectを初心者〜中級者がキチッとサクッと理解する](https://bear-fruit.online/react-useeffect/#index_id3)

[副作用フックの利用法](https://ja.legacy.reactjs.org/docs/hooks-effect.html)

[React HooksのuseEffectで関数コンポーネントにライフサイクルを持たせる](https://qiita.com/jima-r20/items/0e8de5dbf368ede29369)
geopandasを使ってみて迷ったこと

## Python環境で地図データを簡単に扱ってみたい

Google Colaboratoryを使ってShape形式ファイルを扱って簡単に地図を表示してみたいと思いたち、ネットをググってたらgeopandasというライブラリがあってそれを使えば簡単ですよってサイトが沢山見つかりました。

では早速やってみよう。

## geopandas自体はGoogle Colaboratoryに登録済み

メインのライブラリであるgeopandasをインストールしなければならないと思ってたら、標準でインストール済みでした。どうもありがとうGoogle。

で、geopandasの使い方自体は他のサイトをググってもらうほうがわかりやすいと思ってますが、一点だけどこにも書いてないことをお知らせします。

なお、これは国土地理院などから勝手にshape形式データをダウンロードしてきてgeopandasで使ってみようとした場合です。

ファイルの入手先はこちら（国土交通省　国土数値情報ダウンロードサイト）

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v3_1.html

## ファイルの読み込みエラーが発生

関連サイトからファイルをダウンロードすると、一般に.zipファイルとなっていて、中身としてshape形式として必須の３種類のファイルが含まれています。

.shp　図形の情報を格納するファイル
.bdf　図形の属性情報を格納するファイル
.shx　図形のインデックス情報を格納するファイル

wikipediaにはこのような説明がありました。
>必須ファイル：
>.shp —シェープ規格：地形情報の本体。
>.shx —シェープインデックス規格：地形データの前方検索、後方検索を高速にするための位置インデックス。
>.dbf —属性規格：各シェープに対する縦表形式の属性情報。dBASE IV形式準拠。

で、それらファイルをgeopandasで読み込むわけですがそのとき指定するファイル名は.shpの拡張子を持つファイルのみなんですね。

```
gdf = geopandas.file_read('xxxx.shp")
```

なので、知識が浅はかな私のようなものは、.zipファイルから.shpファイルだけを解凍してそいつだけフォルダにコピーして読ませようとしたわけです。

するとエラーが発生して全然読めない。

困ってしまってまたググっていろいろな先人が開陳されているサイトを見つけるのですが、どこにも同様のエラーが発生する状況についての説明がない。あっても３つの必須ファイルがありますよっていう説明があるだけ。

で、どうにも問題解決の情報が見つからないので、ものは試しと必須３ファイルをすべて解凍し、同じフォルダにおいてから読み込ませてみると、あら不思議、なんのエラーも発生せず簡単にデータ読み込みが終了致しました。

Google Colaboratoryで実行したときの画面は以下の通り。
同一フォルダに解凍したファイルをすべてアップロードしてます。
（データは神奈川県の行政区域データ）
![スクリーンショット 2023-08-26 15.52.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/80e310a0-a326-406d-bed7-9d5fa732b7f1.png)


## この投稿で一番大切なこと「必須３ファイルはとりあえず同じフォルダに置いとけ」

ということで、必須３ファイルは同じフォルダに置いとけば、geopandasが勝手に参照してgeoDataFrameにしてくれるっぽいです。

今回の投稿は外部から手に入れたshape形式ファイルをgeopandasで読み込むためのコツについて個人的な忘備録として残しますが、もし同じことで深く悩んでいる方がいらっしゃったら試してみてください。

今回私は簡単に試すことができるGoogle Colaboratoryでやってみましたが、おそらくローカルで試してみても同じだと思います。

追記　2024/09/03）
Copilotに「geopandasでシェープファイルを扱ううときの注意点を教えて」と聞いてみたら、ちゃんと３つのファイルを同じフォルダに置けと教えてくれました。その他にも細かい注意点を教えてくれた。Copilotくん、ありがとう
「機械学習のデータセットはどう失われるか」を更新しました

むかし書いた[「機械学習のデータセットはどう失われるか」](https://qiita.com/nonbiri15/items/043118f6f55fe70c1baf)を更新しました。

- 投稿当時には、GitやGoogle Cloud Storageなどのことを記載していませんでした。
それらを含めた注意点を追記しました。
- エンジニアが入れ替わっていく状況のなかで、どうやって引き継ぎを可能にしていくべきなのか
- 機械学習のシステムは「式年遷宮」をしていく必要があることを追記しました。
- 不幸にも、むかしの機械学習を引き継がなければならなくなった人が、どうやって、むかしのシステムを復元して、データにたどり着くのがいいのかを描き加えています。
- 機械学習のシステムの開発者側は、いずれ誰かが引き継ぐ必要があるのかを意識して、システムの構築とドキュメントを作成してほしいことを追加しました。
- それらのため、元の記事とは内容が大幅に増強されています。
- 引き継ぎ後の必要な手順を書いた文書を示して、それで引き継ぎ完了するのは危険です。
- 引き継ぎの手順を説明したあとに、後任者が実際にテータの追加・学習・評価のサイクルを回せることを確認しないと危険です。
- 起こりうること：
    - 説明が不足している場所があって、後任者には作業できない。
    - アクセスするファイルの権限がなくて、作業ができない。
    - 開発者のPCにコミットしきっていない差分があるため、git clone; git pull した環境で動作しきらない。
[ SwiftUI ] Custom Fontが適応されない

Xcode version 14.3.1

info.plistの設定もちゃんとできたのに、カスタムフォントが表示されない時の対処法です。

カスタムフォントのやり方は、<a href="https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app">こちら</a>


### やりたかったこと
フォントサイトでダウンロードしてきたフォントを使用したかった。

<Img width='30%' src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539223/e4e22aa7-7948-d2a4-f0e0-2a7a6d295d2e.png" />

```ruby:qiita.rb
Text("Hello World")
    .font(Font.custom("JdBaguesRegular-Ag87", size: 40)
```

上記のようにフォントファイルの名前を入れても適応されませんでした。

## 解決法

Macに元から入っているFont Bookにフォントをインポートすると、正常に作動するフォント名を確認することができました。

<Img width='50%' style="width:100px; height: auto;" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539223/04f3da53-1294-e50d-adea-e6971bc0409d.png" />

<Img width='30%' style="width:100px; height: auto;" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539223/84582ca3-c44c-4594-d090-231b7351a254.png" />

### コード

```ruby:qiita.rb
Text("Hello World")
    .font(Font.custom("Jd Bagues", size: 40)
```
ちなみに、フォント名のアルファベットのUpper/Lower caseは関係ないようです。

<Img width='40%' style="width:100px; height: auto;" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539223/d3316e34-b9fb-2e18-a253-fd5fb7c36f44.png" />


### References:

https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app

https://stackoverflow.com/questions/27006772/custom-font-not-working-programmatically-in-swift
達人に学ぶDB設計を読んだ感想

[達人に学ぶDB設計](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702)を一通り読むことができましたため、読んでみて、良かったところや学んだこと、難しかったことを記載します！

## 良かったところ

### 技術のメリットだけでなく、デメリット、目的が記載されているところ

例えば、正規化のメリットとして、データの整合性を維持することはすっきりわかるSQLにも書かれておりましたが、正規化のデメリットも書かれていたことです。正規化をすることで、テーブルが複数に分割されるため、複数テーブルを参照する際、結合を使います。 **結合は負荷が高い処理のため、パフォーマンスが悪くなってしまう原因であることを知りました。**

また、 **第一正規系の目的は一つのカラムに一つの値にすることで、一意にデータを絞ることができます。** 

**第二正規系の目的は異なるレベルのエンティティを明確にテーブルとして分けることです。** 例えば、会社と社員テーブルを一つとした場合、会社に商社Cだけあるものの、社員がいないというデータはテーブルに格納できません。なぜなら、社員情報がないため、主キーにデータが入らないからです。しかし、会社と社員を別テーブルにすれば、会社テーブルだけにC商社を入れることができます。

ちゃんと目的とメリット、デメリットを抑えて、技術選定できるようになりたいです💪


### インデックスを貼ると効果的なカラムについて詳しく書かれていたところ

スキリわかるSQLにはインデックスを貼ると効果的なのは結合条件のカラムや`WHERE`の完全一致、前方一致、`ORDER BY`などが書かれておりましたが、本書ではさらに詳しく書かれていて、勉強になりました！

以下のカラムにインデックス(B-tree)を貼ると効果的です。
- データ量が多いことです。約1万件以上になる場合。1万件以下の場合、インデックスを使用せず、フルスキャンの方がパフォーマンスが良いからです。
- データの種類（カーディナリティ）が多いこと。例えば、男、女、それ以外だとカーディナリティは3と少ないですが、受付日が365だとカーディナリティが高い方です。

:::note alert
カーディナリティが高くてもデータ量に偏りがある場合はインデックスの効果発揮されません。例えば、カーディナリティが100だとしても99%が100という値で残りの1％が1〜99だとインデックスの効果が発揮されません。
:::


## わかったこと

### 多段ビューはアンチパターンであること
前職でデータマート関連のシステム開発で多段ビューが使用されており、仕様を把握するのが難しいと思っていたのですが、やはりアンチパターンだったということを知れました😅

**アンチパターンなのは仕様把握が困難なだけでなく、パフォーマンスも悪いためです。**

ビューにはSELECT文が保存されております。また、そのビューをSELECTして、ビューからSELECTしているため、それが多段ビューですと複数回SELECTが行われるため、パフォーマンスが悪くなってしまうことを知りました。

それでは多段ビューを使用しないためにはどうすれば良いかというとマテリアライズドビューを使用した方が良いことです。

マテリアライズドビューはビューという名前がついているものの、テーブルにデータが入っております。ビューだとユーザがSQLを発行するたびに、ビューに定義されたSQLが発行されますが、マテリアライズドビューはビューに定義されたSQLの実行結果をテーブルに格納している状態です。そのため、ビューのように2回SQLを発行せず、パフォーマンスが悪化しません。

:::note alert
デメリットとしては、マテリアライズドビューに格納されているデータをリフレッシュする必要があります。
:::

### 列持ちテーブルはバットノウハウではなく、グレーノウハウであること

列持ちテーブルとは例えば、扶養家族テーブルの列に子供1、子供2、子供3などがあるテーブルのことです。
個人的には正規化できるから、アンチパターンかと思っていたのですが、メリット・デメリットを考慮した上で使用するにはグレーノウハウとのことです。

メリットはテーブルの中身を把握しやすいことです。また、テーブルからアプリケーションへデータを取り込む際にテーブル結合せず、SELECTするだけでデータが取れることです。

一方、デメリットは拡張性が低いことです。テーブルに列が増減したら、それによってアプリケーション側にも改修が必要です。また、NULLが入るカラムもあるため、SQL文を混乱させます。





## 難しかったこと
第9章の入れ子集合モデルで作成されたテーブルを参照する際に、自己結合とNOT EXISTSを使ったSQLが上手く理解できなかったため、学習していきます!
せんせー、ブロックコポリマー自己集合ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、ブロックコポリマー自己集合ってなに？

# ブロックコポリマー自己集合とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ブロックコポリマー自己集合って何？

みんな、レゴブロックを遊んだことありますよね。
レゴブロックは色々な形や色のブロックをつなげると、面白い形や物を作ることができます。
ブロックコポリマー自己集合も、ちっちゃな「レゴブロック」が自分たちで面白い形を作るようなものです。

## どういうこと？

ブロックコポリマーは、2つ以上の異なる種類の部分がつながった、長い鎖のようなものです。
これらが一緒になると、特定のパターンや形に自然に並ぶことができるんです。

## どうしてそれがすごいの？

この特別な並び方を使うと、新しい素材や、小さなマシン、電子部品などを作ることができます。
それは、科学や技術の発展に役立つかもしれないです。

## だから、ブロックコポリマー自己集合ってなに？

ブロックコポリマー自己集合は、ちっちゃな「レゴブロック」が自分たちで面白い形やパターンを作ることなんです。


# まとめ

このように、ブロックコポリマー自己集合は、
微小なスケールで特定のパターンや形に自然に並ぶ特別な物質のことを指します。
それを利用すると、新しい技術や素材の開発に役立つかもしれません。
【OCI】Windowsサーバーを踏み台にしてプライベート・エンドポイントのAutonomous Databaseのデータベース・アクションに接続する方法

# はじめに
プライベート・エンドポイントのAutonomous Database (ADB)の場合、自身のPCからではADBのデータベース・アクションをクリックしても以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/9d055c57-740a-485d-2d31-ba7c879f9438.png)
今回は、Windowsの踏み台 (Bastion)サーバーにリモートデスクトップ接続をすることで、プライベート・エンドポイント設定のADBでもデータベース・アクションに接続できる方法を紹介します。
# 検証環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/d8e1d040-7e4a-ca8f-6798-3b8e15601ee8.png)
自身のWindows PCから、パブリックサブネット上のWindowsの踏み台サーバーにリモートデスクトップ接続をして、プライベートサブネットのADBにログインしていきます。
# 前提
OCIのコンソールにログインして下記の表のリソースを作成します。
|リソース|項目|設定値|備考|
|:---|:---|:---|:---|
|VCN|CIDR|10.1.0.0/16||
|パブリック・サブネット|CIDR|10.1.1.0/24|踏み台サーバー用|
|プライベート・サブネット|CIDR|10.1.2.0/24|ADB用|
|インターネット・ゲートウェイ|||ルート表に追加する|
|セキュリティ・リスト(パブリック・サブネット用)|Ingress|	XXX.XXX.XXX.XXX/32, TCP 3389|接続元のIPアドレスを指定する（[確認くん](https://www.ugtop.com/spill.shtml)などのサイトで調べられる）|
||Egress|0.0.0.0/0, すべてのプロトコル|すべての宛先への通信許可|
|セキュリティ・リスト（プライベート・サブネット用）|Ingress|10.0.0.0/16, TCP All|踏み台サーバーからのアクセス許可|
||Egress|0.0.0.0/0, すべてのプロトコル|すべての宛先への通信許可|
|ルート表（パブリック・サブネット用）|ルール|ターゲット：インターネット・ゲートウェイ, 宛先：0.0.0.0/0||
|コンピュート・インスタンス|イメージ (OS)|Windows Server 2022 Standard||
|Autonomous Database|ネットワーク・アクセス|プライベート・エンドポイント・アクセスのみ|OCI VCN内のプライベート・エンドポイントへのアクセスを制限します。|
# 手順
## 1）リモートデスクトップ接続
自信のPCでリモートデスクトップ接続を開き、オプションの表示をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/d81d09a3-28a9-dba0-4692-7b3ace54b837.png)
OCIコンソールから接続する踏み台サーバーのパブリックIPアドレスとユーザー名を入力します。初期パスワードはログイン時にまた使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/8563b423-8358-43bd-34ce-175c7ceb21d4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/daafbe50-c69c-7a13-364e-69d2612dc926.png)
警告が出ますが、「はい」で接続して大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/5b7ff967-46d4-f044-14df-51078a5dd647.png)
初期パスワードを入力したら、新しいパスワードを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/3bbee237-86c0-57f2-4834-cc623941aef7.png)
## 2）踏み台サーバーからOCIコンソールにログイン
踏み台サーバーにリモートデスクトップ接続し、そのブラウザからOCIコンソールにログインして試してみると、データベース・アクションに接続することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/410500ab-4d7e-3bed-e0f4-82f0eb1ddc4f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/7d1e71ff-47b6-ea05-d2bb-7dede8f8f04d.png)

# まとめ
今回は踏み台サーバーがLinuxではなく、Windowsの場合のプライベート・エンドポイントのADBのデータベース・アクションに接続する方法を紹介しました。
Windowsの場合だと、楽にGUIでの操作が可能なので設定などもしやすくなります。
せんせー、モノクローナル抗体ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、モノクローナル抗体ってなに？

# モノクローナル抗体とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## モノクローナル抗体って何？

みんな、身体が風邪をひくと、体を守るために「戦士」が出てくるのを知ってますか。
この「戦士」たちは、病気の原因となるバイキンを攻撃してくれるんです。
モノクローナル抗体は、特定のバイキンや病気を攻撃する特訓された「戦士」のようなものです。

## どういうこと？

科学者たちは、特定の病気やバイキンに対して効果的に戦える「戦士」を作ることができます。
それがモノクローナル抗体なんです。

## どうしてそれがすごいの？

このモノクローナル抗体を使うと、特定の病気や問題に対して、効果的に戦うことができるからすごいんです。
新しい薬や治療法を作るときにも使われます。

## だから、モノクローナル抗体ってなに？

モノクローナル抗体は、特定の病気やバイキンに効果的に戦うために作られた特訓された「戦士」のことなんです。

# まとめ

このように、モノクローナル抗体は私たちの体を守るために科学者たちが作った特別な「戦士」で、
新しい薬や治療法を開発するのに役立っているんです。
Minecraft の本に記載することが出来る文字数について

# 本の1ページに書き込める文字数
- 半角英数字のみのとき
  - Unicode フォント強制時 : 320 文字
  - Unicode フォント非-強制時 : 320 文字 (例外あり)

- 日本語のみのとき
  - Unicode フォント強制時 : 168 字
  - Unicode フォント非-強制時 : 168 字

--- 

半角英数字のみ Unicode フォント強制
![スクリーンショット 2023-08-26 030132.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/bf64ec47-339e-60e8-a407-683082e6e3f8.png)

半角英数字のみ Unicode フォント非-強制
![スクリーンショット 2023-08-26 025407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/6f2291b5-f462-8bf2-4cb1-43f8274107ca.png)

日本語のみ Unicode フォント強制
![スクリーンショット 2023-08-26 024907.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/f89ae378-f76c-71fd-ef76-d3d3f153124c.png)

日本語のみ Unicode フォント非―強制
![スクリーンショット 2023-08-26 024931.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/2299f06a-63a4-651b-6071-37cdac399a88.png)

# JavaDoc
`BookMeta#addPage` に書かれているように 1 ページにつき 256 文字まで、とのこと。

> _"Adds new pages to the end of the book. Up to a maximum of 50 pages with 256 characters per page."_
>
>[Spigot JavaDoc BookMeta#addPage](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/meta/BookMeta.html#addPage(java.lang.String...))

# ソースコード

> ```java
> 31: static final int MAX_PAGE_LENGTH = 320; // 256 limit + 64 characters to allow for psuedo colour codes
> ```
> [CraftBukkit CraftMetaBook.java](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java)

_**256 limit + 64 characters to allow for psuedo colour codes**_
**訳 : 256文字制限＋擬似カラーコード用に64文字**

# 中間報告
~~ソースコードから読めることとして、JavaDoc に記載されている通り 256 文字の制限はある。しかし、(疑似)カラーコードを使用しない場合はそれらの分のスペース 64 文字分を使用することが出来るため 256 + 64 = 320 となり、~~ **1 ページに 320 文字まで書き込める。**

装飾コードを含めたときの半角英数字のみの文字数は `320 - (装飾コードの文字数)` になるので、文中にて装飾コードを 1 回だけ使用した場合の表示文字数は 318 文字になる。

ソースコードのコメントには「疑似カラーコード用に 64 文字」と書かれているが、別に疑似カラーコード(装飾コード)の文字数が 64 文字を超えても何が起こるというわけではなく、ただ普通に装飾コードの分だけ表示される文字数が減少するだけである。

# Unicode フォント強制のオンオフ
- Unicode フォントを強制していれば、半角英数字のみの場合であれば 320 文字を表示しきることが出来る。

- Unicode フォントを強制していなければ、半角英数字のみであっても 320 文字を表示しきれない場合がある。
  - i, j, l のような幅の細い文字以外を多く用いる場合は 320 文字すべてを表示しきることは難しい。(普通の英文だったら余裕でオーバーする)

- マルチバイト文字は Unicode フォント強制の影響を受けず、常に等幅フォントで表示される。

# まとめ
- Unicode フォントを強制して、半角英数字のみを使用した場合は 1 ページに 320 文字まで記載できる
- Unicode フォントを強制しない場合も 1 ページに 320 文字まで記載することが出来るが、幅の広い文字を使用する場合はその限りではない
- 平仮名、カタカナ、漢字、句読点のみを使用する場合は、 1 ページに 168 文字まで記載できる
- 日本語 + 半角英数字の文字列を記載する場合は、半角英数字 3 文字で日本語 2 文字分として換算するといい感じになる
Web PubSub - Azure - Memo

(自分用メモ)
Web PubSub を試す。

- [総目次](https://qiita.com/shokkaa/private/7a1633dbf58ddc81f894)
- [目次: Azure Development](https://qiita.com/search?sort=&q=tag%3AAzure+tag%3Adevelopment+user%3Ashokkaa)


# 環境
- Ubuntu 22.04
- [Azure CLI](https://qiita.com/shokkaa/items/e38803a481b9df33ee7a)

```sh:azコマンドでwebpubsubを使用できるようにする
az extension add --upgrade --name webpubsub
```

```sh:各種設定値
uniq=2311  # 他人とかぶらない文字列
resgr=trial # リソースグループ名
location=eastus # データセンター
pubsub=pubsub$uniq # PubSubリソース名
hub=hub1 # hub名
user=uid # ユーザ名

```

# Azureリソース準備

[参考](https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/quickstart-live-demo)

```sh:リソース準備
uniq=2311
resgr=trial
location=eastus
pubsub=pubsub$uniq

az group create --name $resgr --location $location
az webpubsub create --name $pubsub --resource-group $resgr --sku Free_F1 --location $location
```


```sh:接続文字列取得
az webpubsub key show --name $pubsub --resource-group $resgr --query primaryConnectionString
```
※Portalでは、Azure portal > Web PubSubリソース > キー > Primary 接続文字列

```sh: Hub管理
hub=hub1
user=uid

az webpubsub hub list --name $pubsub --resource-group $resgr
az webpubsub hub create   --name $pubsub --hub-name $hub --resource-group $resgr
```

# サンプルコード
## [Azure SDK版](https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/quickstart-use-client-sdk)
```
git clone https://github.com/kyoya-p/samples
cd samples/2023/Azure/WebPubSub
```

```sh:クライアント(モニター)起動
az webpubsub client start --name $pubsub --hub-name $hub --resource-group $resgr --user-id $user
```

```sh:受信側アプリ実行
token=`az webpubsub key show --name $pubsub --resource-group $resgr -o yamlc --query primaryConnectionString`

npm i
npx tsc
node build/sub.js "$token" $hub
```

```sh:送信側アプリ実行
token=`az webpubsub key show --name $pubsub --resource-group $resgr -o yamlc --query primaryConnectionString`

npm i
npx tsc
node build/pub.js "$token" $hub
```

# 参考

https://learn.microsoft.com/ja-jp/azure/azure-web-pubsub/tutorial-serverless-notification?tabs=javascript

https://blog.nomupro.com/entry/2021/04/30/150606
Nuxt3.7がリリースされました。Dockerで動かした際にエディタのimportが効かない不具合が修正されています

先日、以下の記事を投稿しましたが、本日リリースされたver3.7で解決されました。

https://qiita.com/teracy164/items/6a46c6e92fbc4ee1eec2


# 現象

.nuxt/tsconfig.jsonにて`compilerOptions.paths`が絶対パスになる  
⇒Dockerで動かす場合、コンテナ内の絶対パスになってしまいモジュールが見つからなくなる

# 検証

### コンテナ

シンプルなコンテナで確認します

```docker-compose.yml
version: '3'
services:
  my-app:
    image: node:18
    container_name: my-app
    working_dir: /app
    volumes:
      - .:/app
    command: npm run dev
    ports:
      - "3000:3000"
```

### Ver3.6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/0b57eee3-0e9b-0d04-3921-850877e33cbd.png)


### Ver3.7

ちゃんと相対パスになっています！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/f08a4f45-024d-005c-565d-c6b156bb4e7f.png)

# 最後に

ver3.6でもDocker使わずにホストOS側でnpm run devすればパスは問題ないんですが、WSL2＋Ubuntuで開発しているとウォッチ用のポートを開放しないとホットリロードが機能しないので、面倒だったんですよね。
これでようやく解決されたので開発がはかどりそうです^^
使わなくなったNASとHDDを二次バックアップとして使用する。

# はじめに
[前回](https://qiita.com/sakai00kou/items/4cf12aa1253a529b9116)、NASで使用しているHDDが故障したついでに新しいHDDとNASを購入して入れ替えましたが、故障していないHDDを余らせておくのももったいないと思い、新しいNASの二次バックアップ先として使ってみようと思います。

- 【前】[使えなくなったHDDを認識させてフォーマットする。](https://qiita.com/sakai00kou/items/4cf12aa1253a529b9116)

# 二次バックアップ先として使おうと思ったきっかけ
RAID1で組んでいたHDDの１本のみ余ったからというのもありますが、RAID1で使うために同時期に購入しているHDDなので同じタイミングで故障することも考えられるなぁと思ったのと、HDD故障した際の心の安定を取るため二次バックアップを行うことにしました。

# 今回の構成
以前使っていたNASはHDDが故障したのと同じくらいのタイミングで電源が故障してしまったため、更に以前に使用していたQNAPの`TS-112`を引っ張り出してきました。

どっちにしろ余ったHDDは１本のみだし、置き場的に収まりもいいのでちょうどよい感じです。

今使っている`TS-264`も二次バックアップとして使う`TS-112`もどちらもQNAP製なので、前回「[RTRRでQNAP NAS間同期を行う。](https://qiita.com/sakai00kou/items/22b6cdd6f89b9c3ab0d5)」でも使用した`HBS3`を使い、二次バックアップ先へ一方向同期によるバックアップを行います。

ただ、二次バックアップなので常時起動しておくほどのものでもないなぁと思うのと、常時起動しておくと割とファンの音もうるさいので、以下のように`TS-112`はバックアップを行うときにのみ起動して、終わったら停止するようにしたいと思います。

```mermaid
sequenceDiagram
    participant ts112 as TS-112（旧NAS）
    participant ts264 as TS-264（新NAS）
    Note left of ts112: 毎週金曜日1:00に起動
    ts112->>ts112: 自動起動
    Note left of ts264: 毎週金曜日1:30に実行
    ts264->>ts112: HBS3 一方向同期実行
    Note left of ts112: 毎週金曜日6:00に停止
    ts112->>ts112: 自動シャットダウン
```

## HBS3 HybridBackupSyncの有効化
新NASからの同期を受け付けるため、`TS-112`側に`HBS3`をインストールし、サーバ機能を有効化しておきます。

`TS-112`はすでにファームウェアの更新が行われていないので`TS-264`とは画面が若干異なりますが、`HBS3`自体はインストールできるため、インストールして以下のようにサーバ機能を有効化します。

![Monosnap_20230805_134609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/d594c770-5c3c-1d00-fd7f-520bfac23ad3.png)

## 共有フォルダの作成
新NASからの同期先となる共有フォルダを作成しておきます。

![Monosnap_20230805_140056.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/dea4e557-1b7a-b049-c3d1-8c510339261a.png)

## 電源設定
QNAPには電源スケジュールの設定を行うことができ、NASの起動も停止もスケジュール化することができます。

「**スケジュールを有効にする**」をチェックすることでアクションの設定が行うことができるので、以下のように設定を行いました。

以下スクリーンショットでは「**レプリケーションジョブの進行中にスケジュールされた再起動シャットダウンを延期する**」のチェックを忘れていますが、今回のような使い方をする場合はチェックを行ったほうが良いかと思います。

また、スケジュールする時間については、今回の場合`HBS3`によるレプリケーションなので、初回バックアップ時以外はここまで時間はかからないと思いますが、ひとまず毎週金曜日1:00に起動、6:00に停止としておきます。

![Monosnap_20230805_140813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/74789a62-5a95-5d73-c2ac-928d56760bd0.png)

## 新NASからの一方向同期実行
`TS-112`側の設定は完了したので、新しいNAS側で一方向同期の設定を行い、バックアップを行います。

新しいNASの同期設定は[前回](https://qiita.com/sakai00kou/items/22b6cdd6f89b9c3ab0d5)とほぼ同様となりますが、今回は以下のようにスケジュール設定を行い、定期的に同期を行うようにします。

![Monosnap_20230805_143117.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/7fef0aab-c55d-8aa4-01df-286b8d0ca7b4.png)

先程の`TS-112`側の電源設定で毎週金曜日1:00起動、6:00停止としているため、`TS-112`自体の起動に時間がかかることを見越し、新NASの`HBS3`のスケジュールは毎週金曜日1:30から実行するようにしました。

# おわりに
以前使っていた`TS-112`と余ったHDDを再利用でき、さらに電源スケジュールによりバックアップする際にだけ停止起動を行うようにしたため、二次バックアップも行いつつ、環境にも配慮した構成を組むことができました。

電源スケジュールで停止はともかく、起動も設定ができることを今回設定を行うまで知りませんでしたが、この設定のおかげで思った構成が組めて満足です！