OmniAICreator/Qiita-1.07M huggingface dataset:
Node16.20.2環境でhusky+lint-stagedを使ってlinterを自動化する(no use prettier)

# 背景
Gitへのコミット時に、linterのルールに則ってないコードを弾きたい。
業務でNode16.20.2指定の環境だったので、最新の導入記事が参考にならない。
また、巷の記事ではセットでprettierを使って自動整形をしているが、意図しない変更が加わるため無駄な変更を増やしたくない。
コードの整形はESlintでカバーできない範囲は手動で行いたいのでprettierは利用したくない。

# 使用モジュール(執筆当時の最新バージョン)
- husky@8.0.3(9.0.11が最新版)
- lint-staged@14.0.1(15.2.2が最新版)

ひとまずNode16に対応しているかで上記バージョンを選択

# 設定手順
### 1. モジュール類のインストール
```sh
$ npm i --save-dev lint-staged@14.0.1
$ npm i --save-dev husky@8.0.3
```

### 2. huskyのセットアップ
下記サイトが参考になった。ありがとうございます。

https://zenn.dev/g_okawara/articles/850d8e6729edfb#husky

1. Git hooksの有効化
    ```sh
    $ npx husky install
    ```

1. npm installをトリガーとしてhusky installを実行するスクリプトを用意する
    これをすることにより自分以外のプロジェクトメンバーは、 `npm install`するだけで同時に `husky insatll`も実行されるようになるらしい
    ```sh
    $ npm pkg set scripts.prepare="husky install"
    ```
    実行するとpackage.jsonに下記のような記述が追加される
    ```jsonc
    {
      "scripts": {
        "prepare": "husky install" //追加されたとこ
      },
      "dependencies": {
        ...
      },
      "devDependencies": {
        ...
      }
    }
    ```
1. `npm run prepare`の実行
    `husky install`が実行されていないため下記を実行する
    ```sh
    $  npm run prepare
    ```
    これを実行すると`.husky/`ディレクトリが作成される
    ここからhuskyのスクリプトを作成する
1. Git Hooksをトリガーとして実行するコマンドを追加
    ```sh
    $ npx husky add .husky/pre-commit "npx lint-staged"
    ```
    これを実行すると`.husky/`ディレクトリ配下に`pre-commit`ファイルが作成され、その末尾にコマンドが追記されているのがわかる

### 3. lint-stagedのセットアップ
よく記事ではprettierを利用したコミット時の自動整形も行うことが多いが、今回は整形を手動で行うのでprettierは入れない。

1. lint-stagedの設定
    `package.json`に下記の設定を追加
    ```jsonc
    {
      "script": {
        "prepare": "husky install" //huskyセットアップで追加されたやつ
      },
      "dependencies": {
        ...
      },
      "devDependencies": {
        ...
      },
      "lint-staged": {
        "*.{tsx, ts}": "eslint --fix"
      }
    }
    ```
    これでコミット時、直前にESlintが走り、ルール違反がある場合は弾かれる。

# 参考
https://zenn.dev/g_okawara/articles/850d8e6729edfb

https://kic-yuuki.hatenablog.com/entry/2019/05/27/090515

https://qiita.com/memomaruRey/items/de9e2f9e108ca8a27e61

https://www.npmjs.com/package/husky/v/8.0.3

https://www.npmjs.com/package/lint-staged/v/14.0.1
【ChatGPT有＋DALL-E3】ネガティブプロンプトの書き込み。失敗談。


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

　今回は、DALL-E3へのネガティブプロンプトの書き込みについてです。やってみた、に近いかな（予防線w）

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

***
　今日のニュースから。

　一昨日（2024/03/03）
　　書きましたけど、
　　　ChatGPT Web版ですが、
　　　　音声出力が可能に
　　　　　なっている、そうです。再掲

　まだ、私のところは
　　なっていません(泣)

　ですが
　　OpenAIから
　　　新たな発表が
　　　　ありました。

　今度は、
　　アプリの方に
　　　音声出力が追加されました。

　こちらは
　　iOSもAndroidも
　　　無料版も有料版も
　　　　オールカバーの開放に
　　　　　なりました。

　やり方は簡単。

　ChatGPTから
　　出力された文章を
　　　長押しロングタップすると
　　　　CopyとかSelect Textとかの
　　　　　ポップアップメニューが
　　　　　　出てきます。

　このメニューの
　　一番下に、追加されています。
　　　“Read aloud”がそれです。

　タップしてみると、
　　少し待って（長さにもよる？）
　　　発声されます。

　発声の声は
　　アプリに設定した声が流れます。
　　　何度かやってみました👍
***
　次のニュース。

　Anthropicが
　　Claude 3を発表。

　以下の３モデル
　　Claude 3 Haiku
　　Claude 3 Sonnet
　　Claude 3 Opus

　なんでも
　　ベンチマークで
　　　GPT-4を凌駕したとか。

　一部には
　　こちらがテストしているのを
　　　察しているかのような返答を
　　　　してきた、との報告も
　　　　　ありました。X-Twitterより。

　もちのろんですが
　　有料ですw
***
　さて、
　　本題に移りましょう。

　昨日（2024/03/04）の記事は
　　ネガティブプロンプトについて
　　　ChatGPTさんにお尋ねしました。
[ChatGPT有＋DALL-E3】にもネガティブプロンプトはあるのか？](https://qiita.com/kabumira/items/5de0b67eb3d357fcbed2)

　今回は、
　　ネガティブプロンプトを
　　　どのように扱えば
　　　　いいのかを実験してみます。

　まずは、
　　ふつうに描画指示すると
　　　ネガティブなものが
　　　　出てくるようなプロンプトを
　　　　　投げてみます。

　と思ったけど、
　　出てこないパターンだね、これ。
***
***user***
若い日本人男性。
黒髪ロング。
白い道着、金属のベルト、青いスパッツ、メタリックレッドのブーツ、前腕に黒い腕甲、金属のヘルメットとメタリックレッドのバイザー。
描画

***ChatGPT***
![A_young_Japanese_man_with_long_black_hair,_wearing.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/6c0243b1-973a-fff9-98e4-0614738f743e.jpeg)
***
　ヘルメットとバイザーが
　　ありませんねぇ。

　次に、
　　ネガティブプロンプトを
　　　組み込んでみます。
***
***user***
#アクティブプロンプト
若い日本人男性。
黒髪ロング。
白い道着、金属のベルト、青いスパッツ、メタリックレッドのブーツ、前腕に黒い腕甲、金属のヘルメットとメタリックレッドのバイザー。

#ネガティブプロンプト
金属のヘルメットとメタリックレッドのバイザーは必須。

#最終指示
描画

***ChatGPT***
![A_young_Japanese_man_converted.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/95625ca0-bfa8-fe07-a963-6c0495ac8eeb.jpeg)
***
　深津式プロンプト的な
　　フレームワークを
　　　使ってみました。

　おっ、かぶってくれました。

　……

　いろいろと
　　やってみましたけど、
　　　バイザーをヘルメットの上に
　　　　載せられませんでした(泣)

　……

　よくよく考えたら
　　“名称が違う？”と
　　　思い付き、
　　　　ググってみたら
　　　　　案の定、違いました。

　それでも
　　何度か試行錯誤して
　　　こうなりました。
***
***user***
#アクティブプロンプト
若い日本人男性。
黒髪ロング。
白い道着、金属のベルト、青いスパッツ、メタリックレッドのブーツ、前腕に黒い腕甲、金属のバイク用ヘルメット。

#ネガティブプロンプト
・ヘルメットは、かぶる。必須。
・ヘルメットにシールドはない。

#最終指示
描画

***ChatGPT***
![A_young_Japanese_man_with_long_black_hair,_wearing (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/7b3ca9a2-f6c0-06c1-8b4f-5c1d3c6476ec.jpeg)
***
　“バイク用”としたのは、
　　どうやら、DALL-E3さんが、
　　　武術なんだから、
　　　　フェンシング的な
　　　　　ヘルメットでいいだろう、と
　　　　　　思ったのではないかと
　　　　　　　思った次第。

　そんな感じの
　　ヘルメットでしたからねw

　まるで、
　　『仮面ライダー龍騎』の
　　　ヘルメットでしたから。

　しかし、
　　なんか苦しそうな
　　　画像になりましたね。

　リトライして、
　　“突きを放つ構え”を
　　　取らせました。

　そしたら
　　ヘルメットが
　　　なくなりました(泣)

　続けてやろう、と
　　思ったら、
　　　また制限が
　　　　来てしまいましたw

　もう少し
　　方法を試行してみます。
***
　こんなことが
　　みなさんの
　　　作品制作の糧に
　　　　なるとは思えませんが
　　　　　失敗談ということで……

　今回は、ここまで。
『体験しながら学ぶ ネットワーク技術入門』をやってみる@勉強記録②

今回は前回に引き続きChapter2 レイヤー2プロトコルを知ろうの勉強記録となります。
前回のBlog：[『体験しながら学ぶ ネットワーク技術入門』をやってみる@勉強記録①](https://qiita.com/kota-horiguchi/items/e77e051db68abdbfb396)
学習書：[体験しながら学ぶ ネットワーク技術入門](https://www.amazon.co.jp/%E4%BD%93%E9%A8%93%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80-%E3%81%BF%E3%82%84%E3%81%9F-%E3%81%B2%E3%82%8D%E3%81%97/dp/4815618593)

# Chapter2 レイヤー2プロトコルを知ろう
この賞ではデータリンク層で利用されるプロトコルの学習


データリンク層
- MACアドレスを使用し、同じネットーワークに存在するか確認
- 物理層のデジタルデータを信号の相互に変換
- 現在使用されるL2プロトコルは有線のイーサネットと無線のWi-Fi

イーサネット
- カプセル化とエラー検知が定義されている
- イーサネットによってカプセル化されたパケットをイーサネットフレームという
- イーサネットフレームはプリアンプル、宛先/送信元MACアドレス、タイプ、イーサネットペイロード、FCSから構成されている
- 宛先/送信元MACアドレスをイーサネットヘッダー、FCSをイーサネットトレーラーと呼ぶ

「プリアンプル」でフレームの始まりを合図して、「宛先/送信元のMACアドレス」で通信相手の情報を伝えて、「タイプ」で上位のレイヤーで利用するプロトコルの予告をして、「ペイロード」で送りたいデータの内容を入れて、「FCS」でフレームの品質チェックをしている。

MACアドレスのI/G、U/Lビットについて
- I/Gビットはユニキャストかマルチキャストか示している。本書には載っていないが調べたところ、マルチキャストの場合はマルチキャストグループにホストを入れる必要があり、マルチキャストグループに参加したユーザーは、自分のユニキャスト用のMACアドレスとブロードキャストに加えて追加されたマルチキャストグループのMACアドレス宛のフレームも自分宛のフレームと認識するようになるよう。
- ユニバーサルアドレスかローカルアドレスか示す


### tcudump,wiresharkを利用してパケットをみてみる
wslのコンテナ上のパケットをtcpdump取得してwindows上のWireshakrで解析する流れ

開発環境の端末1から端末2にpingした際のパケットキャプチャ
プリアンプルは除かれており、FCSは表示しない設定となっているが、wireshark上でDestinationとSourceのMacアドレスが表示されており、TypeからIPv4のIPアドレスにパケットを送信していることがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269528/3a106e6f-481f-5399-fc35-6f4ee34efde0.png)
Hello Worldからの復習 ～オーバーロード編～

話の枕を書かずにやってみたら、シンプルになった。

あたりまえかw


##### お品書き
+ オーバーロードって？
+ メリットは？
+ Sample

----

◆オーバーロードって？
-
設計図クラスを作るときに、同じ名前で引数の型や数が違うメソッドをいくつも定義できる。
メソッドを複数定義することをいう。

----

**setDataをオーバーロードしている**↓
```java:java
class Student{
  void setData(String n){ //名前の引数のみ
  .
  .
}
 void aetData(String n, int e, int m){ //名前とint型の点数を2つ
 .
 .
 }
}
```

**オーバーロードしたのを呼び出すmainメソッド**↓
```java:java

main( ～ ){
  Student stu = new Student(); //Studentクラスを基に変数stuを作りインスタンス化
  stu.setData("大輔");
  stu.setData("大輔", 80, 90);
  .
  .
  }
```

**インスタンス化した時のイメージ図**↓
```mermaid
classDiagram
    direction RL
    setData <|-- stu
class setData{
+setData（String）｛...｝
+setData（String, int, int）｛...｝
}
```

呼び出すメソッドは**名前**と**引数**の組み合わせで決めている。
もし、名前と引数の組み合わせで合うものがなければ、コンパイルエラーになる。

※戻り値の型は合っていなくても問題はない。


◆メリットは？
-
**設計図クラス**としては、
同じデータを設定するためのメソッドなのでSetDataという同じ名前にした方が、同じような処理をしているのが見た目でわかるという
**プログラム自体がわかりやすくなる**のが大きなメリット。


メソッドをたくさん作った場合、その分別々の名前を付けることになると大変。
setData1..setData2..setData5..どれがどれ？みたいな。

これが、同じ名前で良いなら名前を付けるのがラク。

**メソッドを呼び出す側**としては、
メソッド名が変わらないため、使いやすいというメリット。

例えば、
`System.out.println()`
これもオーバーロードして使用されている。
そのため、int,double,boolean,Stirng等、全部`println`メソッドとして呼び出して使える。

◆Sample
-

```java:java
class Student2{
  String name;
  int engScore;
  int mathScore;

  void setData(String n){ //オーバーロード
    name = n;
  }
  void setData(String n, int e, int m){ //オーバーロード
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}

```

```java:java
class StuSample2{
  public static void main(String[] args){
    Student2 stu1 = new Student2(); //インスタンス化
    Student2 stu2 = new Student2(); //インスタンス化

    stu1.setData("大輔"); //インスタンス化した変数にデータ格納
    stu1.setScore(90, 80); // 同上
    stu1.display(); //表示するdisplayメソッドの呼び出し

    stu2.setData("湊丞", 75, 100); //引数を3つまとめて格納
    stu2.display();
  }
}
```

```cmd:cmd
C:\Java\1>javac StuSample2.java

C:\Java\1>java StuSample2
大輔さん
英語90点・数学80点
湊丞さん
英語75点・数学100点

C:\Java\1>
```

メソッドの呼び出しの時にはメソッド名と引数の2つの情報を見て、呼び出すメソッドを決めているのがポイント。


オーバーロードとは引数の型や数が違ければ、同じ名前で複数定義出来るということですな。
【AtCoder C++】B- ABC076 - Addtion and Multiplication

## 学習記録用 -B-Addition and Multiplication

https://atcoder.jp/contests/abc076/tasks/abc076_b

~~~c++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int N,K;
  cin >> N >> K;
  int sum = 1;
  //A(1*2),B(1+K)を合計でN回繰り返す。その最初値
  //A,Bを比較(if)して、値が小さいほうを実行。その繰り返し
  for (int i = 0; i < N; i++){
    int A = sum * 2;
    int B = sum + K;
    
    if(A<=B){
      //sum += Aではなくて、sum = A。sum += Aだと、sum = sum + A(sum*2)でsumを2回使って格納しているから間違い。
      sum = A;
    }else{
      sum = B;
    }
  }
  cout << sum << endl;
  
}
~~~

最初sum += A / sum += Bにしていて、間違えていた！修正した！
ChromebookにCentOS8 インストール

インストール時に意外とコマンドが多かったのでメモ

[CTRL]+[ALT]+[T] でターミナル起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/adb8b5b2-5936-85cf-dbc3-cb66d47cdde5.png)
※
```console
$ vmc list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/a22b7825-d204-f492-eed9-0fc3bffbc11b.png)
```console
$ vmc start termina
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/dfcbb564-d981-e28b-08b0-a872770d5e33.png)
```console
$ lxc list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/afbefef8-aa18-9e62-6c06-8d1b446f8a44.png)
```console
$ lxc image list images: | grep centos
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/9bb0523c-b67e-7a72-0aff-875868def766.png)
```console
$ lxc launch images:centos/8-Stream CentOS
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/caa916b6-7934-e1f9-a48f-20d59f31f640.png)
```console
$ lxc list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/706eb2c4-6fa9-6dcc-1c0a-8efc0392604d.png)
```console
$ lxc stop CentOS
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/621604f3-2ea8-8bca-0043-eae0ceb582ea.png)
```console
$ lxc start CentOS
$ lxc list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/4c7c156f-1f01-a0f5-5a81-a4f6b48405f2.png)
```console
$ lxc exec CentOS bash
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/bd0ca85c-8a94-c9a3-ae3f-0f9e9452791d.png)
```console
# ls -a
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/29d5a242-501a-6260-189e-1c5c54bff4aa.png)

コンテナを削除する場合
```console
$ lxc stop CentOS
$ lxc delete CentOS
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/07a63d23-68c0-2314-a539-47aa3817093f.png)

最新版にアップデート
```console
# sudo dnf update
```

必要なコマンドをインストール
```console
# yum install -y man; yum reintall --setopt-tsflags='' -y bash
# yum install -y tree; yum reintall --setopt-tsflags='' -y bash
```
.htaccess でメンテナンス中の表示にする方法

## .htaccess でメンテナンス中の表示にする方法
普段、業務では、a-blog cmsという、cmsを使用しています。
動的なサイトって、　**どうやってメンテナンス中の画面表示をするんだろう・・・？**　と疑問に思い、調べてみました。
思いの外、簡単に設定できたので、下記に記述します:sunny:

### そもそも、　.htaccess ってなんだろう。

メンテナンスの画面は、.htaccess に記述するみたいです。
よく触ることがある.htaccess ですが、なんなのか分からないまま触っていたため、この機会に調べてみました。
メンテナンスの設定方法だけ知りたい方は、次の見出しに飛んでください。

私は、下記のようにSEO対策の目的でよく使っています。

:::note info
.htaccess の使い所
- リダイレクト設定をする時
- ホームページのwwwの有り無しを統一する時
:::

下記の記事がとても分かりやすかったです。

https://qiita.com/sanogemaru/items/7e5bd6e8dc9b04c9978e

自分なりに解釈した限り、　**サーバーの権限を持っていない私たちでも、.htaccessを使えば、サーバーの設定も最低限変えられるよ**　ということかな？と思いました。
.htaccess が少し理解できたので、本題に戻ります:star2:

### メンテナンス中の表示実装方法

私は、下記の記事を参考にしました！

https://webtan.impress.co.jp/e/2009/06/16/5880

https://zenn.dev/15/articles/b39faf0674ac41149080

#### 　1.maintenance.htmlを作成し、下図の箇所に設置


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/44ee4613-b378-ef2d-2aaf-b09c0c32453f.png)

#### 　2. .htaccessに下記を追記

```
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/maintenance.html
  RewriteRule ^.*$ - [R=503,L]
</IfModule>
```
※.htaccessは、エディタによっては隠しファイルになっている場合があります。お使いのエディタで隠しファイルを表示設定にすると表示されることがあります。

#### 　３.サイトを確認

おお〜！出ました:clap:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/33391f9c-4fea-815a-d2bb-c1248b985f25.png)

とっても簡単に設定できたので、実践的に活用したいと思います！
cscの作法 その468

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
qiitaの、feedを読め。

# 参考にしたページ

https://qiita.com/t13801206/items/c20547ff3c3d60400161


# サンプルコード

```

using System.Collections;
using System;
using System.Net;
using System.Net.Http;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Linq;

namespace app
{
	class test0 {
		static void Main() {
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
			//var client = new HttpClient();
			XNamespace xNamespace = @"http://www.w3.org/2005/Atom";
			var feed = XDocument.Load(@"https://qiita.com/popular-items/feed");
			var entries = feed.Element(xNamespace + "feed").Elements(xNamespace + "entry");
			List<string> authorList = new List<string>();
			foreach (var entry in entries)
			{
		    	string author = entry.Element(xNamespace + "author").Value;
				Console.WriteLine(author);
    			authorList.Add(author);
			}
		}
	}
}



```

# 実行結果

```
>qiita0
TakahikoKawasaki
kossyprg
har1101
zumax
minorun365
SabaCrevette
nogizakapython
_mi
inoue_d
kana_zzzz
takavfx
moromi25
Sicut_study
yuzu_juice
hiramax
ike_s_muramatsu
ccHarvestasya
m_pig
shunii
shiminori0612
matoruru
miya_gis
hcrane
minorun365
Shikimum
minorun365
minorun365
cyberBOSE
HarukiIdo
Takashi_Masumori

```


以上。
【AtCoder C++】ABC080 B - Harshad Number

## 学習記録用 - Harshad Number

https://atcoder.jp/contests/abc080/tasks/abc080_b

~~~c++
// 148
// No
#include <bits/stdc++.h>
using namespace std;

int main(){
  int N;
  cin >> N;
  int Harshad = N;
  int sum = 0;
  //各桁の和をsum変数に格納
  //%10で桁取得、//10で進む
  //割り切れば"Yes" else
  while(N > 0){
    sum += N % 10;
    N /= 10;
  }
  
  if (Harshad % sum == 0){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
}
~~~

最初Nの格納用変数Harshadを用意していなくて、wrongが出た！
Oracleで不具合を生む禁じ手「INTERVAL YEAR TO MONTHで日付操作」

※こちらはOracle限定の話となります。

## 日付操作について
SQLで日付操作する時に使用されるINTERVALがあります。
使い方としては以下のような形で使用できます。

```sql
select sysdate + INTERVAL '1' DAY from dual;
```

DAYの部分をYEARやMONTHにを変えることで操作することができます。

## そもそもINTERVALとは何か
少し古い仕様書ですが、Oracleのリンクを記載します。

https://docs.oracle.com/cd/E57425_01/121/SUTIL/GUID-169DE9FB-36A5-4087-9857-7F03DCF8D3C6.htm

ここに書かれている通り、INTERVALとはSQLの操作ではなく期間を表す変数です。
なのでINTERVAL '1' DAYで一つの値を表します。

INTERVALは厳密にはINTERVAL YEAR TO MONTH、INTERVAL DAY TO SECONDの二つの型に分かれます。つまりX年Y月加算することはできますが、X年Y月Z日加算することは型の境界を超えるので一回で計算できません。

```sql
1年2ヶ月と3日前の日付を計算するSQL
NG:SELECT  sysdate - (INTERVAL '1-2-3' YEAR TO DAY)  AS  time_value FROM dual


OK:SELECT  sysdate - (INTERVAL '1-2' YEAR TO MONTH) - (INTERVAL '3' DAY)  AS  time_value FROM dual
```

## 発生する不具合
これがなぜ不具合を生むことになるかというと、月末の日付の調整してくれないという問題があるためです。
末日を判断してくれないことでなにが起こるかというと、存在しない日付が生成されエラーになるということです。
```
例)
1/31の１ヶ月後とすると2/31
```

ただ、なぜか　- (INTERVAL '1' DAY)はエラーなく正常な値を返してくれます。
(これを正しく返してくれるのであればX年やY月の操作でも正しく返してくれても良いのに)

```sql
SELECT  to_date('20240301','yyyymmdd') - INTERVAL '1' day AS  time_value FROM dual
→2024-02-29 00:00:00.000

SELECT  to_date('20240229','yyyymmdd') + INTERVAL '1' day AS  time_value FROM dual
→2024-03-01 00:00:00.000
```

## エラーコード
実際に実行すると以下のエラーコードとエラーメッセージが返されます。
```
ORA-01839: 指定された月に対して日付が無効です
原因: 日付で指定された月単位の日付が、指定された月に対して無効でした。月単位の日付(DD)は、1から月の日数の間である必要があります。

処置: 指定した月に対する有効な月単位の日付を入力してください。
```

## なぜ禁じ手なのか
このSQLを基本的に使用してはいけない理由は以下の通りです。
### 1.時と場合によって動くSQLになる
先に書いた通り末日処理がされないことで、あるときは動くがある時は動かないという問題が起きる。
2月に作成した時はうまく動いたのに他の月ではうまく動かない場合が発生し、テストで見逃されてしまう可能性が出てきます。

正常に常に動かすためには末日を考慮した処理をする必要が出てきます。
結果として、処理が複雑化してしまうという問題を生んでしまいます。

### 2.INTERVALにはデフォルトで制限がある
INTERVALの型に設定できるデフォルトの値の制限があります。
```
INTERVAL YEAR TO MONTH→99年11ヶ月が最大
INTERVAL DAY TO SECOND→99日23時間59分59秒が最大
```

100年後を計算することは実際の運用上ないと思いますが、100日後の計算は現実的にありうると思われます。
登録日のX日後までに何かしないというような期限を持たせる、期限までの日付は時と場合によって変わるような登録を行うときに何も指定しなければ99日以降の計算をSQLで行うとエラーが発生します。


## 対処方法
### 1.Oracleのadd_monthsなどの関数を使用して計算する
上記関数を使用すると1/31の1月後の計算でも計算のエラーが出なくなります。

```sql
SELECT ADD_MONTHS(to_date('20240130','yyyymmdd'),1) FROM dual
→2024-02-29 00:00:00.000
```

存在しない日付をした場合は、計算された存在しない日付より以前に存在する最も近い日付が返却されます
2024年の1/31の1ヶ月後も1/30の1ヶ月後も2/29になります。

ただこちらにも問題があり、末日の１ヶ月後とすると次の月の末日が返されるという動きになります。
そのため2024年2月28日にADD_MONTHSで一月後とすると2024年3月28日となりますが、2023年2月28日にADD_MONTHSで一月後とすると2023年3月31日となります。

### 2.日付単位で加算する
1ヶ月=31日もしくは30日(1年は365日)で仕様の中で定義して計算する。さらに計算するもとのデータがDate型の場合は数値計算で日付の計算ができます。

```sql
1日後の計算
SELECT  to_date('20240229','yyyymmdd') +1 AS  time_value FROM dual

```
もしくはSQLを見たときにすぐにどのような操作がされているか分かるようにするため、INTERVAL '1' DAYを使用する。
※DAY(3)などと桁数を指定することができるので、デフォルトの2桁を超えた3桁の1年を365日としても実行することはできる

```sql
SELECT  INTERVAL '365' day(3) AS  time_value FROM dual

```

### 3.プログラム側で指定する
1や2は日付操作の結果がデータベースに依存するということで、SQLを実行するプログラム側で日付をそのものを計算してしまうことで、DBの依存から切り離すのも手だと思われます。
仮にプログラム側で定義できれば、データベースを変更する際にSQLのエラーに悩まされることがなくなります。


## まとめ
INTERVALでの日時操作に関するエラーについてまとめました。
最新のOracle環境で確かめられて言いませんが、同じようなエラーのことを書いている記事があったのでこの仕様は現在でも有効かと思います。
個人的には、対処方法の2もしくは3での対応をするのが現実的に不具合になりにくいのではと思いました。
Oracle Data Pump実行時のジョブの中断、再開、強制終了の方法

## はじめに
Oracle Data Pump実行中に、途中でエラーが出てしまったり、条件を変更してやり直したいという場合に備え、本記事ではエクスポート時の<INS>**ジョブの中断、再開、強制終了の方法**</INS>について解説します。
特にOracle Data Pumpのエクスポートやインポートは数時間、データ量によっては数10時間かかる場合がありますので、知っておくべき操作になります。

また、本記事の内容は、

**第8回 Oracle DBaseCamp**
**【Oracle Data Pumpによるエクスポートとインポート】**

に登壇した際の内容になります。

詳細についてご覧になりたい方は、以下の録画や資料を参考にしてみてください。
* 録画

https://youtu.be/ysJdrpuwkNY

*資料

https://speakerdeck.com/oracle4engineer/oracle-dbasecamp-8

## ジョブの中断
Oracle Data Pumpでエクスポートおよびインポートの実行を中断したい場合は、「Ctrl + C」を1回押します。
その後、stop_jobコマンドを実行し、続いての確認に対して「yes」と入力することで、エクスポートが中断され、コンソールに復帰します
~~~
stop_job
~~~
:::note warn
「Ctrl + C」を2回押してしまうと実行中のままコンソールに復帰してしまうので注意
:::

## ジョブの再開
ジョブを中断した後、ジョブを再開させるには、先ほど実行していたジョブ名をコマンドに入力する必要があります。
ジョブ名の確認方法の1つとしては、エクスポート実行時のログを確認する方法があります。
~~~
Starting “demo"."SYS_EXPORT_FULL_02":  demo/********@pdb1 parfile=expdp.par
      ----Data Pumpの実行ログ----
~~~
上記の例だと、SYS_EXPORT_FULL_02と書いているのがジョブ名になります。

もう1つの確認方法としては、ジョブを中断する前に実行中のユーザーでSQL*Plusへ接続して、実行しているジョブを確認する方法があります。
~~~SQL
SELECT * FROM USER_DATAPUMP_JOBS;
~~~
上記のSQLを実行することで、実行中のジョブの場合、STATE列に「**EXECUTING**」と表示されます。
~~~
JOB_NAME             OPERATION  JOB_MODE   STATE               DEGREE ATTACHED_SESSIONS DATAPUMP_SESSIONS
-------------------- ---------- ---------- --------------- ---------- ----------------- -----------------
SYS_EXPORT_FULL_01   EXPORT     FULL       NOT RUNNING              0                 0                 0
SYS_EXPORT_FULL_02   EXPORT     FULL       EXECUTING                0                 0                 0
~~~
このジョブ名を用いて、ジョブを再開させるには、以下のコマンドを実行します。
~~~
expdp <ユーザー名>/ <パスワード> attach=<ジョブ名>
~~~
その後、「**start_job**」と入力するとジョブを再開させることができます。
~~~
start_job
~~~

## ジョブの強制終了
Oracle Data Pumpでエクスポートおよびインポートの実行を強制終了したい場合は、「Ctrl + C」を1回押します。
その後、kill_jobコマンドを実行し、続いての確認に対して「yes」と入力することで、実行が強制終了され、コンソールに復帰します
~~~
kill_job
~~~
:::note warn
強制終了したジョブは再開できず、制御表およびダンプ・ファイルが削除されます。
ログ・ファイルは、削除されません。
:::


## おわりに
今回は、Oracle Data Pump実行時のジョブの中断、再開、強制終了の方法について解説しました。
Oracle Data Pumpについて、更に詳しく知りたい方は以下の記事もご参考にしてみてください。

:::note info
* [Oracle Data Pumpによるエクスポートとインポートの基礎](https://qiita.com/yunagash/items/15625a0b6010ee83de1a)
* [Oracel Data Pumpのアーキテクチャから理解する「PARALLELパラメータとワーカー・プロセスの関係」](https://qiita.com/yunagash/items/d9654d74257b19145619)
* [Oracle Data Pumpの機能紹介 ～Enterprise Editionおよびオプションで利用できる機能～](https://qiita.com/yunagash/items/57cb29729bfdad52da2d)
* [Oracle Data Pumpのベスト・プラクティスと代表的なパラメータ](https://qiita.com/yunagash/items/aa41b3a2d916761807dc)
* [Oracle Data Pumpによる移行方法（クラウドリフト時の移行ケースと注意点）](https://qiita.com/yunagash/items/f2c037b1062753821c89)
:::
【AtCoder C++】ABC073 - Theater

## 学習記録用 B - Theater
https://atcoder.jp/contests/abc073/tasks/abc073_b

~~~c++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int N;
  cin >> N;
  int result = 0;
  
  int l,r;
  for (int i = 0; i < N; i++){
    cin >> l >> r;
    result += r - l + 1;
  }
  cout << result;
}

// 2
// 6 8
// 3 3

// 4


~~~
これはすんなりいけた！嬉しい！
Amazon BedrockのAnthropic's Claude 3 Sonnetモデルでグラフ画像を解読させてみた

2024年3月4日にAmazon BedrockにClaude 3が登場しました。
https://aws.amazon.com/jp/about-aws/whats-new/2024/03/anthropics-claude-3-sonnet-model-amazon-bedrock/

(2024年3月6日追記) AWSブログの日本語訳も出ました。電光石火で巷にClaude情報が溢れ始めています。
https://aws.amazon.com/jp/blogs/news/unlocking-innovation-aws-and-anthropic-push-the-boundaries-of-generative-ai-together/


グラフ画像をどのように解読できるか、取り急ぎ3つほど試してみました。

環境：
* Amazon Bedrock (オレゴンregion)
* Claude 3 Sonnet v1
* チャットのプレイグラウンドで動作を確認

検証日：
2024年3月5日(JST)


# 人口ピラミッドの画像

https://dashboard.e-stat.go.jp/ のサイトで公開されている人口ピラミッドのグラフをスクショした画像を読み込ませてみました。

画像はこちら
![スクリーンショット 2024-03-05 9.33.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/fc19eaf1-b686-15bb-411d-9127567e59c7.png)

結果はこちら
![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/343ebf61-81f1-3c5d-2970-8ec5641e474c.png)

ちゃんと読み取ってくれているようです。内容も妥当なものに見えますが、本当に画像から読み取ったのか、元々学習しているデータから生成しただけなのかは、これでは判別できませんでした。

# PPT資料（架空）のグラフ画像

業務での活用度合いをみるため、社内資料を想定した架空のPowerPoint 1ページを作り、画像化して読み込ませてみました。

画像はこちら
![image (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/1f903ebe-f969-2ab6-6303-2c3dadf73e65.png)

結果はこちら
![image (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/1ee56ee7-1008-8615-b92a-17d12b15ec0c.png)

このデータは私が今作った、Claudeに事前に学習されていないデータですが、ちゃんと傾向を読み取っているようです。欄外の備考のコメントや、赤枠の意味などもちゃんと答えてくれました。なかなか優秀です。

# Excel方眼紙データの画像

政府統計 https://www.e-stat.go.jp/ の国勢調査のExcelファイルをダウンロードして、Excelファイルの画面をスクショして読ませてみました。

画像はこちら
![image (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/9734dddf-ef0c-983e-db60-0ef5f4b22859.png)

結果はこちら
![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397277/2011aa9a-6a2b-ec97-4f13-95d36508e419.png)

「５年おき」という部分は読み取れているようですが、「1920年から2015年まで」は間違っているかも。データの画像は1920年〜1960年の部分しかないですし、元データも1920年〜２０００年(令和2年）です。ただ、令和2年の1つ前(2020年-5年=2015年)までのデータだとClaudeが推測したのだとすると、それはそれで計算面の機能がすごそうです。ここは要検証。
データの傾向も一応答えてくれましたが、こちらは学習された情報から答えている可能性はあるかもしれません。

# 考察

テキスト + イメージのタスクには、業務利用においてもかなり使えそうな印象です。
【AtCoder C++】ABC089 B - Hina Arare 

## 学習記録用 Hina Arare -B- for構文練習

https://atcoder.jp/contests/abc089/tasks/abc089_b?lang=ja

~~~c++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int N;
  char Color;
  string judge = "Three";
  
  cin >> N;
  //Colorが黄色だったらcout << Four, その他cout << Three
  for (int i = 0; i < N; i++){
    cin >> Color;
    if (Color == 'Y'){
      judge = "Four";
      break;
    }
  }
  cout << judge << endl;
}
//入力例
// 8
// P Y W G Y W Y Y

~~~
最初Color変数をstringにして、forブロック外で`cin >> Color`をしていた。これでは入力が複数回できない系でCEエラーが出たため、char型に変更して、forブロック内に`cin >> Color`を入れて、複数回入力できるようにした。
初心者の私には分かりやすいコードだと思う✨
GitHubの使い方まとめ

# 初めに

GitHubについて下記のサイトで勉強したので、使い方をまとめていきたいと思います。

https://www.r-staffing.co.jp/engineer/archive/category/マンガ・Git

ITSTAFFINGエンジニアスタイルさん
マンガでわかる~Gitコマンド編~
漫画でわかりやすく解説しているのでとてもわかりやすかったです。

# コマンド一覧

## Gitのバージョンを確認する

```
git --version 
```
上記のコマンドを打てばGitのバージョンを確認できます。

## ローカルリポジトリを作成する

```
git init
```
ローカルリポジトリを作成したいディレクトリで上記のコマンドを実行すると、ローカルリポジトリが作成されます。


## ディレクトリ内の状態を確認する
```
git status
```
作業ディレクトリ内の状態が確認できます。
ファイルのステージング状況などが確認できます。

## ファイルをステージングエリアに乗せる
```
git add ファイル名
```
指定したファイル名をステージングエリアに乗せることができます。

## ステージングエリアから下ろす
```
git reset HEAD ファイル名
```

## ステージングしたファイルをコミットする
```
git commit -m "コミットメッセージを書く"
```
ステージングしたファイルをコミットします。
-mでコミットメッセージを書くのが普通です。

## コミットログを確認する
```
git log
```
コミットされたかを確認することができます。
--graphをつけると色付きで確認することができます。

## リモートリポジトリについて

https://qiita.com/opatu07/items/948d47f1ee238dff72aa

この記事で詳しくローカルリポジトリとリモートリポジトリを連携させる設定方法について解説しています。
ここではローカルリポジトリとリモートリポジトリを結びつけるコマンドを書いておきます。

```
git remote add origin リモートリポジトリのURL
```

## ローカルリポジトリの内容をリモートリポジトリに反映させる

```
git push リモートリポジトリ名　ブランチ名
```
例: リモートリポジトリ名originで、ブランチ名がmainの場合

```
git push origin main
```

## ブランチを作成する
```
git branch ブランチ名
```
例: ブランチ名がdevelopの場合

```
git branch develop
```

## ローカルブランチの一覧を確認する
```
git branch 
```
-aを加えるとリモートリポジトリも確認できる

## ブランチを切り替える
```
git checkout ブランチ名
```
例: ブランチ名がdevelopの場合
```
git checkout develop
```
## ローカルブランチを作成して移動する
```
git checkout -b ブランチ名
```
例: ブランチ名がdevelopの場合
```
git checkout -b develop
```
## リモートブランチを作成
```
git push origin ブランチ名
```
例: ブランチ名がdevelopの場合
```
git push origin develop
```

## リモートブランチを削除
```
git push origin -d ブランチ名
```

## ローカルブランチを削除
```
git branch --delete ブランチ名
```

# 最後に

これからもGitについて勉強していくので、記事を追記していきます。
パスキーの同期について調べてみた

## 背景
認証・認可周りの本を読んでいるときにFIDOについて興味を持ったのがきっかけです。
FIDOだと機種変更時に認証が通らなくなって困るのでは? と思ったので対策を調べていました。

どうやらパスキーを使えば鍵が同期されて、複数デバイス間で共有できるらしい...
つまり秘密鍵を渡すということでしょうか?
整理も兼ねてパスキーの同期の仕組みについて調べました。

## FIDO認証
パスキーはFIDO認証に関わりがあるので、まずはFIDO認証の確認からです。
FIDO認証は公開鍵暗号方式を利用して認証をします。
サービスへの鍵の登録、認証の仕方は以下の手順で行なっています。


### 鍵登録の手順
- サービスへ登録するときにサービスに対する秘密鍵と公開鍵のペアを生成する
- 秘密鍵はデバイス内に保存され、公開鍵のみをサービスのサーバに保存する

```mermaid
sequenceDiagram
  actor U as ユーザ
  participant S as サーバ
  U->>+U: 公開鍵と秘密鍵を生成する
  U->>+S: 公開鍵のみをサーバに送る
  S->>-S: 公開鍵を保存する
```

### 認証の仕方
- サーバから送られてくるチャレンジに対して、登録した公開鍵に対応した秘密鍵で署名したチャレンジをサーバに送る
- その後、サーバに登録した公開鍵で、チャレンジの署名を検証する
- 検証が通れば認証成功

```mermaid
sequenceDiagram
  actor U as ユーザ
  participant S as サーバ
  U->>+S: ログインを試みる
  S-->>-U: チャレンジ(文字列)を送信する
  U->>+U: チャレンジを秘密鍵で署名する
  U->>+S: 署名つきのチャレンジをサーバに送り返す
  S->>S: 署名を登録してある公開鍵で検証する
  S-->>-U: 検証が正しくできればログイン成功 
```

## パスキー(マルチデバイス対応FIDO認証資格情報)
パスキーはFIDO認証で利用する資格情報(秘密鍵)を同期できるようにした鍵です。
FIDO認証では各デバイスにのみ秘密鍵が保存されているため、機種変更などの際にパスキーの移動に手間がかかりました。
パスキーでは複数デバイス間で秘密鍵を同期させる仕組みがあり、移動の手間がかかりません。

### パスキーの同期
パスキーはFIDOの認証に使う秘密鍵をアカウントに紐付け、暗号化してクラウドで管理します。
クラウド上に秘密鍵を置いておくので、異なるデバイスでも同じ鍵を使うことができるということです。
その際のクラウドとのやり取りも暗号化しているため安全に共有できるということのようです。

デバイス1からデバイス2に秘密鍵を同期する例を示します。

```mermaid
sequenceDiagram

  participant D1 as デバイス1
  participant D2 as デバイス2
  participant C as クラウド
  D1->>+C: 暗号化した秘密鍵をクラウドに送る
  C->>-C: クラウドに保存する
  C->>+D2: 秘密鍵を同期する
```

appleの場合は、iCloudキーチェインを使ってクラウド内に秘密鍵を暗号化し保存します。
それをユーザのアカウントに紐づいたデバイスと共有することで、他デバイスとの秘密鍵を共有できるという仕組みのようです。

秘密鍵を暗号化しているからクラウドに保存しても安心ってことでしょうか...
秘密鍵が外に出ないFIDO認証とは異なり、外部へ送るリスクについても考える必要がありそうです。

## 終わりに
パスキーは生成したサービスごとの秘密鍵をクラウド上で暗号化して保存し、共有する仕組みであることがわかりました。
秘密鍵を共有する点に違和感を覚えていたので、理解がなかなか進みませんでした。
今後パスキーは普及していくと考えられるので、アプリケーションで実装する方法についても調べていきたいです。
npmとnpxの違い

日頃の業務開発で気づいたこと、わからなかったことを超簡潔にメモ的なことを残していくシリーズ。
その名も「(後で考える)」

# 今日のお題
`npm`と`npx`の違い

# 結論
`npm`はパッケージ管理。
`npx`はインストールなしでのパッケージ実行

# 解説
### npm
`npm`は`node package manager`でパッケージの管理を目的としている。
`package.json`に記載されているインストール済みのパッケージを指定して利用したい場合に使用する。
npmでインストールされたものはnpmを利用して実行される必要がある。
```sh
$ npm install --save {xxxx}
$ npm run {xxxx}
```

### npx
`npx`は`node package executer`で、パッケージの実行を目的としている。
npmとの大きな違いは、__パッケージをインストールせずに直接実行できる__ というところ。
特にプロジェクト作成時に一回だけ実行したい場合や、linter系のその場だけ実行するもの等が該当しやすい。
```sh
$ npx xxx

## e.g.
$ npx eslint --fix src/hogehoge.ts
```


# 参考
https://docs.npmjs.com/about-npm#use-npm-to---

https://docs.npmjs.com/cli/v10/commands/npx

https://zenn.dev/844/articles/d06bfdbd2677a3
[Java] java.util.Date型からシリアル値を取得する

JavaでGoogle Sheets APIを使用する上で
エクセルやスプレットシート上で扱うシリアル値を扱う必要が出てきましたので
簡単にはですがここに備忘録として残します。

**シリアル値とは？**
1900年1月1日を1として何**日**経過したかを示す値

**UNIX時間とは？**
1970年1月1日 0時0分0秒を0として何**秒**経過したかを示す値

### 1. Date型からシリアル値に変更する際の考え方
UNIX時間を日数に変更して、シリアル値とUNIX時間の日数の差を足します。

① UNIX時間を日数に変更
　getTimeで取得したUNIX時間(ミリ秒)を１日のミリ秒で割って日数にします。
　もし、Dateが日本標準時の場合は、割る前のミリ秒に9時間(ミリ秒)を足します。
```
　date.getTime()/(24*60*60*1000)
//(date.getTime()+(9*60*60*1000))/(24*60*60*1000)
 ```
② 1900年1月1日と1970年1月1日の差を足す
　0スタート、1スタートの違いと閏年も考えて、日数を差を足します。
　差分は「25569」となります。
　プログラムで出していますが、不変の値なので固定値を使用します。
```
LocalDateTime t1 = LocalDateTime.of(1900,1,1,0,0);
LocalDateTime t2 = LocalDateTime.of(1970,1,1,0,0);
long diff = Duration.between(t1,t2).toDays();

//その日も含めるので＋１（例えば、3/1と3/2の差分は1日ですが、3/2の終わりまでの差分は+1の２日）
//片方が０スタートなので＋１
System.out.println(diff+1+1);
```

### 2. プログラム
実行環境を考えれば普通はJSTですが、DBに保存した値などを使う場合を考えて
Date型がJSTとUTCのパターンを記します。

**java.util.DateがJST(日本標準時)の場合**
```
Date date = new Date();

(int)((date.getTime()+(9*60*60*1000))/(24*60*60*1000)) + 25569;
```

**java.util.DateがUTC(協定世界時)の場合**
```
Date date = new Date();

(int)(date.getTime()/(24*60*60*1000)) + 25569;
```
<br>
<br>
おしまい。。
Railsでのデータ取得: アソシエーションメソッドと直接クエリの選択

## 問題定義
Railsアプリケーションにおいて、特定の日付に勤務するスタッフのスケジュールを取得する必要がありました。条件は以下の通りです。

- `at_work`カラムが`true`であること。
- `date`カラムが指定された日付(`@date`)であること。

この情報は、スタッフが提供可能なサービスの時間帯を表示するために使用されます。

## 解決策の提案
直接クエリを使用して、指定された条件に合致するスタッフのスケジュールを取得する方法を選択しました。このアプローチを選んだ理由は、特定のフィルタリング条件に基づくデータセットの抽出が必要であり、アソシエーションを通じた方法よりも直接クエリによる方が効率的であると判断したからです。

## サンプルコード

```ruby
# @dateに勤務可能なスタッフ
@working_staffs_on_date = @company.staffs.joins(:schedules)
                              .where(schedules: {at_work: true, date: @date})
```

このクエリは、指定された日に`at_work`が`true`であるスタッフのスケジュールを取得します。さらに、以下のクエリを使用して、これらのスタッフのすべてのスケジュールを取得します。

```ruby
# @dateに勤務可能なスタッフのスケジュール
@working_staff_schedules_on_date =
  Schedule.where(staff_id: @working_staffs_on_date.select(:id), at_work: true, date: @date)
```

## 判断基準と考察
アソシエーションメソッドと直接クエリのどちらを使用するかの判断基準は、主に以下のポイントに依存します。

- **パフォーマンス**: 大規模なデータセットや複雑なクエリが関わる場合、直接クエリの方がパフォーマンスの面で有利な場合があります（差異は実際に試験して比較しないとわかりませんでした。予測を立てる方法があれば知りたいです）
- **複雑性**: 特定の条件や複雑なデータの組み合わせを扱う場合、直接クエリを使用すると、より細かい制御が可能です。
- **再利用性と保守性**: アソシエーションメソッドはコードの可読性と再利用性を高めますが、複雑なロジックを実装する場合は直接クエリの方が柔軟性があります。

今回のケースでは、特定の日付に対する複雑な条件を満たすスタッフのスケジュールを効率的に取得する必要があったため、直接クエリを使用するアプローチが適していると判断しました。
Git でファイル名の大文字小文字の変更が検出されない

表題の件、年に1回あるかないかくらいのペースで毎回ハマって調べているので自分でも記事にまとめて知識の定着化を狙います。

## 起こった現象

git で管理しているファイル名を次のような大文字/小文字のみの変更を行った場合に、git ではファイル名の変化が検知できませんでした。

例）Kit**k**at.cs => Kit**K**at.cs （太字部分が、小文字の`k`から大文字の`K`に変更されています。）

これは `core.ignorecase` が `true` のときに発生します。

https://git-scm.com/docs/git-config/2.14.6#Documentation/git-config.txt-coreignoreCase

> If true, this option enables various workarounds to enable Git to work better on filesystems that are not case sensitive, like FAT. For example, if a directory listing finds "makefile" when Git expects "Makefile", Git will assume it is really the same file, and continue to remember it as "Makefile".
> The default is false, except git-clone[1] or git-init[1] will probe and set core.ignoreCase true if appropriate when the repository is created.

上記引用部分をDeepLで翻訳した結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/dcfac2e2-354d-75ba-5c8a-098a536c1928.png)

なるほどです。たしかに Makefile は大文字/小文字関係なく同じファイルと認識して欲しいケースな気がします。（Makefile を扱ったことがないので適当に言っています。）

## 対策

1. git mv でファイル名をリネームする
1. core.ignorecase false にする

### git mv でファイル名をリネームする

 私はこちらで対応しました。
```shell
 git mv ./Kitkat.cs ./KitKat.cs
 ```
 
 https://git-scm.com/docs/git-mv
 
### core.ignorecase false にする

```shell
git config core.ignorecase false
```

こちらの対応をする場合は注意が必要そうです。もともと true で成立していた作りが壊れる可能性があるかもしれません。
ちなみにこれを私が参加しているプロジェクトで行うと、今までは大文字/小文字が区別なく同一ファイルとしてみなされていたファイルが、ファイル名が変わったと認識されて git の変化点として出現してきました。

メリットとデメリットを把握したうえで設定が必要そうです。

## 参考にした記事

https://zenn.dev/soma3134/articles/20220726_folder_case_sensitive

https://zenn.dev/msksgm/articles/20211122-clearify-upper-lower
メイン画像をPC画面の縦横  ピッタリに収める

# ファーストビュー
サイトにアクセスしたとき、モニタ画面に表示される領域を
ファーストビューといいます。

# ファーストビューを作る
• 画像とキャッチコピーをグループ化
• 親にposition指定(rerative)
• 画像の横幅100%にする
• キャッチコピー部分にposition指定(absolute)
• とりあえずキャッチコピー部分にtop:50px left:50pxを指定

![firstview-html-css.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717619/498a268c-1562-54b9-3d7d-869c9daa8e13.png)


表示されたもの↓
![firstviewimg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717619/b910185a-b37b-aa6d-e0f5-21d967e60298.png)


## 画面からはみ出した画像をPC画面いっぱいに表示させる
・画像とキャッチコピーのグループに高さ100vhを指定する
・overflowを使ってはみ出し部分を消す
```css
.firstview{
    position: relative;
    height: 100vh;
    overflow: hidden;
}

.firstview img{
    width: 100%;
}
.catch{
    position: absolute;
    top: 50px;
    left: 50px;
}
```
![firstviewimg1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717619/a42c7a5c-eca8-581e-75e1-4d71b40e2727.png)

## キャッチコピーを真ん中に
・top50%,left50%ではキャッチコピーの開始地点が50%の位置になるだけなのでtransformプロパティをつかい位置を調整する
```css
.firstview{
    position: relative;
    height: 100vh;
    overflow: hidden;
}

.firstview img{
    width: 100%;
}
.catch{
    position: absolute;
    /* top: 50px; */
    /* left: 50px; */

    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}
```
![firstviewimg2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717619/81a7c5f3-7545-59a2-f2a5-3a8dee6af4e8.png)
LWC packageに関するエラー

[LWC エラーの対処方法びに戻る](https://qiita.com/Keiji_otsubo/items/480135e98f6b0144ee63)



# Node fs Error: EPERM: operation not permitted, open

+ [Unable to save yml file in "Create a Packaging Org" for CumulusCI for Managed Packages Trail](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JfyW2SAJ)

:::note
On my Windows 10 machine, I encountered this error when running an old Node JS project. I think Node version 10.16.

In any case, it was trying to modify a dotfile in my project. Be sure that the file isn't hidden on Windows. After unchecking the hidden option in the file properties pop up. Everything worked.

So to fix:

Right click file in Windows Explorer
Select properties
Uncheck Hidden
Click Ok
Re-run your command.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f2da4997-bbe8-e480-daa5-9d39f4c7b905.png)

https://stackoverflow.com/questions/33419474/node-fs-error-eperm-operation-not-permitted-open
:::

# Error (1): The Package Id: 0Hoxxx isn't defined in the sfdx-project.json. Add it to the packageDirectories section and add the alias to packageAliases with its 0Ho ID.

+ [Getting error at the time of building the package version for the module "Build Your First Unlocked Package"](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZAmWt)


# SfdxError: No supported Android API package found

+ [Stuck with: Use Salesforce Mobile Developer Tools](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgGjW)

:::note
Please check this article.

https://salesforce.stackexchange.com/questions/385146/sfdxerror-no-supported-android-api-package-found
:::
コンテンツについて(自分用)


コンテンツの最大横幅は〇〇です。
↓
コンテンツと聞いてわからなかったのでメモ用に残しておきます。



# コンテンツモデル
HTML５で導入された新しい概念。あるタグに含めることのできる要素の内容を定義するものです。

# フローコンテンツ
<body>内に記述できるほぼすべての要素はフローコンテンツになるらしい。

# フレージングコンテンツ
フローコンテンツに属するコンテンツ。テキストの一部を修飾するタイプの要素はフレージングコンテンツ。HTML4などでインラインレベル要素と呼ばれていたものと同じ要素が該当するらしい。

例
```html
<div>・・・フローコンテンツ
<strong>・・・フレージングコンテンツ
```

メリットとしては、コンテンツモデルを理解して使いこなせるようになるとSEOが向上したり、変更もしやすくなったり。
【iOS】Swift初心者がARKitを使ってARアプリを作成する

# はじめに

こんにちは、iOSアプリ開発の初心者のkeitaMaxです。

XCodeを使用してARのアプリを作成していきたいと思います。

https://zenn.dev/yoshiyoshipy/articles/e254bf8f43edda

この記事の通りに作成していきますが、初心者ですので、まずは実機にアプリをデプロイするところまでやろうと思います。


# プロジェクトの作成

まずXCodeでプロジェクトを作成します。

プロジェクトの作成　→　iOS　→ Argumented Reality App を選択します。

![スクリーンショット 2024-03-03 21.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/64a8e756-1ffc-1c22-bee6-05ce909cc7bc.png)


次の画面でプロジェクトの名前を入力します。
今回は名前を`example-ar-app`にしました、

すると以下のような感じでXc![スクリーンショット 2024-03-03 22.54.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/0258e0da-6bdc-81f9-169a-1739b77f6e46.png)
odeの画面が表示されます。



これでプロジェクトが作成されました。

# 実機にアプリを入れてみる

自分のiOSと接続し、上の方にある`iPhone 15`という表記の部分をクリックしてアプリをいれたいバージョンのiPhneを選択します。

![スクリーンショット 2024-03-03 21.43.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/6f00aefd-615d-074a-820a-257a5b5a115b.png)

これでビルドボタンを押すと、以下のように怒られてしまいました。
```
/develop/example-ar-app/example-ar-app.xcodeproj Signing for "example-ar-app" requires a development team. Select a development team in the Signing & Capabilities editor.
```

### チームの登録

チームに登録してないよというようなエラーのようです。

エラーの赤いところをおすとTeamを登録する画面に飛ぶので、`Add Acount`を押してチームを作成して、作成したものを登録します。

そして再度デプロイボタンを押すと、信頼されていないデベロッパがでてアプリがビルドできなかったので、以下の記事の通りにして、設定からデベロッパを信頼することで解決することができました。

https://softmoco.com/devenv/how-to-fix-untrusted-developer.php

### ビルドエラー

また、以下のエラーがでてビルドできない時がありましたが、

`A build only device cannot be used to run this target.`

iPhoneとMacBookを再起動させたら直りました。

### 実機にビルド

これでビルドボタンを押すと実機に入れることができました。

以下のようにポップアップが出てくるので許可を押します。

<img width="190" alt="IMG_6154.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/5d166db1-05b3-4875-90ff-5276fb1b6340.png">

許可をおすと、以下のようにカメラが起動し、目の前にキューブが出てきました。

<img width="190" alt="IMG_6155.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/54f4815d-46f1-9fa2-fda3-28874cd800ef.png">

これでARのアプリを作成することができました。

ここから色々いじって自分のすきなARのアプリを作ることができます。

# 出てくるものをキューブから球体にしてみる

初期のアプリから少しだけ変えてみようと思います。

`ContentView`の以下の記述を、

```swift:ContentView
        let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 0.005)
```

以下のように修正してビルドしてみます。

```swift:ContentView
        let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 1)
```

すると、先ほどまでキューブだった物体が球体に変化します。

<img width="190" alt="IMG_6156.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/1512006c-f7f3-810d-ccf0-584d8e52abab.png">


# さいごに

`A build only device cannot be used to run this target.`

このエラーに結構苦しめられました。

ただ、無事ARアプリの開発に取り掛れそうなので良かったと思います。

次回以降はiPhoneでできるARについて色々試していこうと思ってます。


やり方が違ったり、もっといいやり方があるというご指摘がある方はコメントしていただけると幸いです。

最後まで読んでいただきありがとうございました。


# 参考文献

https://zenn.dev/yoshiyoshipy/articles/e254bf8f43edda

https://softmoco.com/devenv/how-to-fix-untrusted-developer.php
2024年おすすめeラーニングサービス10選

## eラーニングとは
eラーニングとは、パソコンやスマートフォンを使用して、インターネット上で学ぶ学習形態のことです。 
いつでもどこでも受講できるため、在宅勤務やテレワークでも効率的に社員教育を行うことができます。
本記事は、2024年eラーニングシステムのおすすめ10選を紹介します。

## SAKU-SAKU Testing
導入企業は累計1,300社以上、月間利用ユーザ数は180,000人の安心の実績。
さらに操作マニュアルいらずの簡単操作でサクサク受講できることが特徴です。

https://www.tosho.co.jp/service/sakutes/

## etudes
人材育成の専門家が、20年にわたるeラーニングの歴史を踏まえて開発したeラーニングシステム。
なんと教材のアップロードが無制限です。

https://etudes.jp/

## Schoo
月額1500円/IDで、7,000本以上の研修動画が見放題。
ビジネスの第一線で活躍する講師から実践的なスキルを学べます。

https://schoo.jp/biz/landing/v8

## 学びばこ
ユーザ登録数無制限。
とにかくシンプルな設計で、誰でも直感的に使うことができます。

https://manabibako.com/index.php

## AirCourse
月額200円/ID～で、650コース4000本以上の動画研修受け放題。
新入社員から管理職まで、各階層で必要な知識・スキルを学習できる、充実した階層別研修が用意されています。

https://aircourse.com/

## Smart Boarding
累計40,000アカウント突破。
研修満足度94％超えの動画学習＋ライブ型レッスンが受け放題です。

https://www.smartboarding.net/

## GLOPLA LMS
「直感的に操作できるデザイン」「手厚い導入・活用サポート」によって、誰でも使いこなせることを実現した学習管理システム。
導入後の定着から運用まで、徹底的にサポートしてくれるので安心です。

https://glopla.globis.co.jp/

## ITERACY
初期費用0円、年間約10万円で始めることができる圧倒的コストパフォーマンス。
豊富な機能を低価格で提供するeラーニングサービスです。

https://www.sgnet.co.jp/iteracy/

## LEC eラーニング
大手企業、官公庁等での豊富な導入実績あり。
法律・会計・人事労務などの専門分野に強く、約200にも及ぶコンテンツラインナップがあります。

https://partner.lec-jp.com/biz/elearning/

## Learning Tracker
大阪ガスグループのセキュリティ基盤で、高水準のセキュリティ対策を実施。
さらに要望にあわせて、オリジナル教材の制作サポートもしてくれます。

https://web.i-netschool.com/system/index.html

## まとめ
以上10サービスをご紹介しましたが、もちろん他にも様々なeラーニングサービスがあります。
eラーニング導入を検討の際は、自社の課題と予算などを照らし合わせ、マッチするサービスを根気強く探してみてください。
spring-security-testのアノテーション使用時に気をつけること


## この記事でわかること 
spring-security-testを行う時に注意すべきアノテーションについてまとめております。
spring-securutyの知識がある前提でお読みください。


## @WithMockUser 
このアノテーションを使用すれば、特定のユーザーとしてどのようにテストを最も簡単に実行する方法です。
`@WithMockUser`を付加することでユーザー名 "user"、パスワード "password"、ロール "ROLE_USER" を持つユーザーとして実行されます。
```java:
@Test
    @DisplayName("todo情報を1件削除")
    @WithMockUser
    void deleteTodo() throws Exception {
        doNothing().when(todoService).deleteTodo(anyInt());
        mockMvc.perform(delete("/api/todos/999999")
                        .with(csrf().asHeader()))
                .andExpect(status().isNoContent());
        verify(todoService, times(1)).deleteTodo(anyInt());
    }
```

ユーザーオブジェクトをモックするため、ユーザー名がuserのユーザーは存在する必要はありません。
`User` のユーザー名は `user` です。
`User` のパスワードは `password` です。
`ROLE_USER` という名前の単一の `GrantedAuthority` が使用されます。


## @WithUserDetails
このアノテーションは`UserDetailsService`からユーザー情報を取得して認証情報を設定するためのものです。
`UserDetailsService` を検索するための明示的な Bean 名を指定することもできます。次のテストでは、Bean 名が `myUserDetailsService` の `UserDetailsService` を使用して、`customUsername` のユーザー名を検索します。


```java:
@Test
@WithUserDetails(value="customUsername", userDetailsServiceBeanName="myUserDetailsService")
public void getMessageWithUserDetailsServiceBeanName() {
String message = messageService.getMessage();
...
}
```

## @WithAnonymousUser
このアノテーションを使用すると、匿名ユーザーとして実行できます。これは、特定のユーザーでほとんどのテストを実行したいが、匿名ユーザーとしていくつかのテストを実行したい場合に特に便利です。

```java:
public　class WithAnonymousUserSample {

    //...
    @Test
    @WithAnonymousUser
    public void get_WithAnonymousUser() {
        ...
    }
    //...

}
```

## おわりに
spring-security-testのアノテーション使用時に気をつけることについてまとめました。
他にも書きたいアノテーションがあるので、改めて更新します。

## 参考記事
https://spring.pleiades.io/spring-security/reference/servlet/test/method.html

https://qiita.com/yokobonbon/items/7d729bd8085f3fb898bb

https://spring.pleiades.io/spring-security/site/docs/current/api/org/springframework/security/access/expression/SecurityExpressionRoot.html#hasRole(java.lang.String)
値段を見ながらClaude 3にワクワクする

Claude 3が発表されました。

https://www.anthropic.com/news/claude-3-family

Amazon BedrockでもすでにClaude 3 Sonnetがオレゴンリージョンで利用可能になっている模様です。

これまでのClaudeモデルの料金と比較してみます。

## 価格比較


100万トークンあたりの価格（Bedrockの価格表は1,000トークンの金額）

[安い] <-----------------> [高い]

* Claude

| IN<br/>OUT | Claude 3 Haiku<br/>[公式]|Claude Instant<br/>[Bedrock] | Claude 3 Sonnet<br/>[公式 / Bedrock]  | Claude 2.0/2.1<br/>[Bedrock]  | Claude 3 Opus<br/>[公式] | 
| --- | --: | --: | --: | --: | --: | 
| IN | $0.25  |$0.80 | $3.00  | $8.00 |$15.00 | 
| OUT | $1.25  |$2.40 | $15.00  | $24.00 |$75.00 | 

* 参考)OpenAI

| IN<br/>OUT | GPT-3.5 Turbo<br/>[OpenAI] | GPT-4 Turbo<br/>[Open AI] |  GPT-4<br/>[OpenAI |
| --- | --: | --: | --: | 
| IN | $0.50 | $10.00| $30.00 |
| OUT | $1.50 |$30.00| $60.00 |


* おそらくOpenAIの価格をみて、ちょっと安くしてる気がする
* Claude 3 Sonnetの価格はAnthripic公式とBedrockは同じ。なので他の2モデルも同じになると期待
* Claude 3 Haikuの価格はClaude Instantの約1/3。安い
* Claude 3 Sonnetの価格はClaude 2.0/2.1の1/2.6。こちらも安い
* 逆にClaude 2.0/2.1の約倍の値段のClaude 3 Opusは、性能がやばそう
Kali Linux 2024.1 Release (Micro Mirror)

# はじめに
2024年2月28日、[Kali Linux 2024.1 Release (Micro Mirror)](https://www.kali.org/blog/kali-linux-2024-1-release/)の通りにKaliの新しいリリースが公開されています。

今回のリリースでは、2024年1回目のリリースということで新しいテーマが公開されました。また、カーネルの更新や新しいツールも追加されています。詳細については、上記公式のブログ記事をご参照ください。

本記事では、今回のアップデート内容の一部について記載しています。

## アップデート方法
公式ドキュメントの[Updating Kali](https://www.kali.org/docs/general-use/updating-kali/)を踏まえて、Kaliのアップデート方法を以下に記載します。

前提として、`/etc/apt/sources.list`が適切に設定されていることを確認した上で以下のコマンドを実行します。

`$ sudo apt update`
`$ sudo apt full-upgrade -y`

上記コマンド実行後、OS再起動を行います。
OS再起動後、`/etc/os-release`ファイルを参照してディストリビューションのバージョンが更新されたことを確認します。

```console
VERSION_ID="2024.1"
VERSION="2024.1"
VERSION_CODENAME=kali-rolling
```

## Micro Mirror CDN
ブログ記事の冒頭では、Micro Mirror CDNのトピックが紹介されています。

Kaliを配信しているミラーサイトが強化されたといった様な内容ですが、ネットワークのインフラストラクチャに興味がある場合は面白い内容だと思います。

以下のURLを参照することで、クライアントのIP addressを基に最適化したルートでミラーサイトにアクセスしていることが確認できます。

- [mirrorlist](https://http.kali.org/README?mirrorlist)



## 2024年の新しいテーマ
通常のKaliエディション及びKali Purpleエディションで使用されるデスクトップの壁紙が更新されました。

以下は新しいデスクトップの壁紙ですが、洗練されたデザインになっています。

![スクリーンショット 2024-02-29 23.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/7d70c107-f52c-b845-6a73-b62edb9fc660.png)

## その他のデスクトップの変更点
Xfceデスクトップに便利な拡張機能が導入されました。

デスクトップ右上に表示されているVPNのIPアドレスですが、IPアドレスをクリックすることで、クリップボードにIPアドレスをコピーできるようになりました。地味に便利です。

拡張機能としてxclipを有効にするためには、以下のコマンドを実行してパッケージをインストールします。

`$ sudo apt update && sudo apt -y install xclip`

## New Tools
新しいツールとして、侵入検知ツールのSnortが追加されました。

https://www.snort.org/

以下は昔に書いた記事ですが、Snortはオープンソースのネットワーク型のIDSとして機能します。

- [Linuxセキュリテイ対策　Snortによる侵入検知](https://qiita.com/Brutus/items/b11c3324492a4e25a152)

# おわりに
2024年もKaliのアップデートを楽しみにしています。

個人的にはSnortの追加がサプライズでした。また、xclipの拡張機能も気に入ってます。

仮想マシンでもKali Linuxを動かすことはできますが、不自由なくパフォーマンスを発揮するためには自作PCなどで動かすのもお勧めです。

以前書いた以下の記事では、自作PCにKali Linuxを導入及び構築する方法について記載しています。

- [自作PCの組み立て方　ベアメタルで構築するKali Linux【PC組み立て編】](https://qiita.com/Brutus/items/4d6da6a989f2a64ec9a2)
- [自作PCの組み立て方　ベアメタルで構築するKali Linux【構築編】](https://qiita.com/Brutus/items/a35654b7644fb358b9cd)
PACファイル (プロキシ自動設定ファイル)とは

# 1. はじめに
社用パソコンでネットワークに接続するためにPACファイルの使用を求められましたが、中身の理解はできていませんでした。
そこで、PACファイルについて調べた内容を記事としてまとめます。

# 2. PACファイルとは
PACファイル（プロキシ自動設定ファイル）は、Webブラウザの動作を指定する設定ファイルであり、特定のプロキシサーバを経由してアクセスするかどうかを指定するためのものです。このファイルでは、ホスト名やURLに基づいて直接アクセスとプロキシ経由の使い分けが可能です。一般的なファイル拡張子は「.pac」です。

補足するとプロキシサーバは、WebブラウザがWebサーバにアクセスする際に中継してくれるサーバです。プライベートネットワークからインターネットへのアクセスなど、直接通信が難しい場合には、クライアントの代理（proxy）としてデータの送受信を行います。

# 3. PACファイルの具体例
スクリプトの処理内では、条件に合ったプロキシサーバーの宛先 (URL、もしくはIPアドレス) とポート番号を返します。

PAC ファイルを記載する場合は、必ず FindProxyForURL関数を記載する必要があります。PACファイルの処理時には、このFindProxyForURLの関数が実行されます。

FindProxyForURL 関数の第一引数である url はアクセス先の URL、第二引数である host はアクセス先の URL から取得したホスト名を表します。例えば、http://shuncask.com/ という URL にアクセスする際には、url が http://shuncask.com/ 、host が shuncask.com/ となります。これらの値を様々な関数を用い条件分けし、最終的に経由するサーバーを返す (return) するような処理を作成します。以下に PAC ファイルの具体例を挙げて、説明します。

```javascript
function FindProxyForURL (url, host) {
 if (isPlainHostName (host)) {
    return "DIRECT";
  } else {
  if (shExpMatch(url, "http://shuncask.com/")) {
      return "PROXY shuncask-proxy.com:6060";
    } else if (shExpMatch(url, "http://www.microsoft.com/")) {
      return "PROXY microsoft-proxy.com:7070";
    } else {
      return "PROXY other-proxy.com:8080";
    }
  }
}
```
先述のPACファイルには、isPlainHostName関数とshExpMatch関数が含まれています。isPlainHostName関数は、引数のhostにピリオドが含まれていなければtrueを、含まれていればfalseを返す関数です。一方で、shExpMatch関数は文字列の部分比較を行い、第一引数の文字列が、シェル表現パターンを使用した第二引数の文字列にマッチする場合はtrueを、マッチしない場合はfalseを返します。

このPACファイルを用いて、例えば http://shuncask.com/ にアクセスした場合、戻り値としては shuncask-proxy.com というプロキシサーバーに 6060 番ポートでアクセスするよう指定されます。同様に、http://www.google.com/ にアクセスした場合の戻り値は www.other-proxy.com となり、プロキシサーバーには 8080 番ポートで接続されます。ブラウザでは、これらの戻り値に基づき、対応するプロキシサーバーへの接続を試み、接続が確立されるとHTTP通信がプロキシ経由で行われます。

また、hostにピリオドが含まれていない場合、isPlainHostNameがtrueとなり、return DIRECTが戻り値となります。IEでは、return DIRECTが返されると、プロキシサーバーを経由せずに直接接続が行われる動作になります。

# 4. おわりに
PACファイルについて理解を深めていただけたら幸いです。
Jestでテスト実行時に" If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file"の警告が出た

# はじめに
現在、React×TypeScriptでアプリを作成しています。
今回はテスト実行時に遭遇したエラーについてまとめます。
# 問題
**Jestでテスト実行時に " If you have issues related to imports, you should consider setting esModuleInterop to true in your TypeScript configuration file" の警告が出ました。**

案の定テストも失敗したのですが、`render(<App />);`において、"TypeError: Cannot read properties of undefined (reading 'createElement')"と出ていました。
**つまり、Appコンポーネントが正しくレンダリングされていないということです。**
上記の警告文が原因に関与していそうです。

以下が実際のテストケースです。
```tsx:Appcomponent.spec.tsx
/**
 * @jest-environment jsdom
 */

import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import App from "../App";

describe("title", () => {
it("should render title", () => {
    render(<App />);
    expect(screen.getByText("Hello world!")).toBeInTheDocument();
});
});
```
# 解決方法
tsconfig.jsonの`compilerOptions`に下記を追記しました。
```json:teconfig.json
"compilerOptions": {
    "esModuleInterop": true 
  }
```
# おわりに
**esModuleInteropとは**
CommonJSモジュールとESモジュールの相互運用性を向上させるためのオプションです。
特に、CommonJSモジュールをESモジュールとしてインポートする際の問題を解決します。

例えば、**あるモジュールを別のモジュールでインポートする場合、TypeScriptはモジュールの解決方法に関するルールを必要とします。** しかし、さまざまなモジュール形式（例えば、CommonJSやESモジュール）が存在するため、それらを正しく解釈する必要があります。

**つまり、esModuleInteropをtrueに設定すると、TypeScriptが異なるモジュール形式を正しく相互運用できるようになります。具体的には、CommonJS形式のモジュールをESモジュール形式としてインポートする場合に、TypeScriptが適切な変換を行ってくれます。**

# 参考
本記事と内容は異なりますが、esModuleInteropについて説明してくれています。

https://qiita.com/eyuta/items/fccebb53d88798c76da5