OmniAICreator/Qiita-1.07M huggingface dataset:
Hello Worldからの復習 ～型変換編～

こうやって復習を軸にアウトプットしていると少しづつだけど脳みそに知識がしみ込んでいく感覚がある。私は理解が人の数倍時間がかかるので、人一倍というより人三倍行動しないと追っつかないのでやるかやらないか。
いや、やらないという選択肢はないかな。

やらないことはやらないけど。


**お品書き**
+ 基本データ型の型変換
+ ◆型変換Sample
+ ◆コマンドラインから任意の金額を入力する場合

---

**基本データ型の型変換**
-
数値同士の演算や代入をするときに、データ型の変換が自動か手動か・・・

**自動**: 表現できる値の幅が**小から大**
**キャスト**で明示する: 表現できる値の幅が**大から小**

データ型のサイズ一覧は　↓

https://qiita.com/tianshandafu894/items/73c7ac456e1b389a74ed


一部抜粋　↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336940/49f5393e-1a2e-b884-d998-1d5fec53d987.png)

小さい箱に入っていたデータは大きい箱には問題なく入るよね。
でも
大きい箱に入っているデータは小さい箱に入れようものなら溢れちゃいません？

て話。

ですよね。

このままではコンパイルエラーが出てしまうから**大から小は明示的に入れられるように教えてあげる**必要がある。

その為に、**キャスト**という記述をします。

例:
`int i :`
`double d :`

`d = i :` →自動
`i = (int)d :` →`(int)`がキャスト。()内は型変換後の型

どんな時使うの？
結構多いのが少数の計算結果を整数に変えたいときとか。
例えば,
1980円のものを買って消費税8%がついた場合の総額の計算。(2024年の今は10%だけど。。。)
`1980x1.08=2138.4`となり少数が出るけど税込み価格にはないので、小数点以下を切り捨てて整数にしたいとき`(int)`を使う。

**◆型変換Sample**
-
```java:java
class Aaa{
	public static void main (String[] args){
		int i; 
		double a ;
		double d ;
		
		i = 1980 ;
		a = 1.08 ;
		d = i * a ; //税込み価格の計算
		d = (int)d ; //double型をintのキャストをつけて明示的に型変換
		
		System.out.println(i * a); //小数点込み結果
		System.out.println(d); //小数点以下切り捨て結果
	}
}
```
少々雑だけど簡単に書くとこんな感じ。

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

C:\Java\1>java Aaa
2138.4 //小数点あり
2138.0 //小数点以下切り捨て
```

切り捨て成功。

**◆コマンドラインから任意の金額を入力する場合**
-

```java:java
class Aaa{
	public static void main (String[] args){
		int price = Integer.parseInt(args[0]); //コマンドラインからデータ入力
		double rate = 0.08; //消費税率の初期化
		int amount; //計算結果の変数宣言
		
		amount = (int)(price * (1 + rate)); //消費税率に1を足して税込み価格に計算しキャストで型変換
		System.out.println("税込み価格:" + amount + "円"); //計算結果
	}
}
```
```cmd:cmd
C:\Java\1>java Aaa 1980
税込み価格:2138円
```

こんな感じ。
後者のほうがスマートですかね。

ちなみに、型変換しないとどうなるか？

```java:java
class Aaa{
	public static void main (String[] args){
		int price = Integer.parseInt(args[0]);
		double rate = 0.08;
		int amount;
		
		amount = price * (1 + rate); //double型の計算結果がint型の変数に代入される
		System.out.println("税込み価格:" + amount + "円");
	}
}
```


```cmd:cmd
C:\Java\1>javac Aaa.java
Aaa.java:7: エラー: 不適合な型: 精度が失われる可能性があるdoubleからintへの変換
                amount = price * (1 + rate);
                               ^
エラー1個
```
エラーが出ましたね。
HTTPステータスコード【備忘】

# はじめに

今回はHTTPステータスコードについて忘れないように軽くまとめてみました。

# HTTPステータスコードの基本
HTTPステータスコードは、ウェブサーバーからの応答の一部としてクライアント（通常はウェブブラウザ）に送信される、3桁の数字です。

これらのコードは、リクエストが成功したか、リダイレクトが必要か、エラーが発生したかなどの、リクエストの結果を示します。

ステータスコードは、100から500までの範囲に分類され、各範囲は特定の種類の応答を表します。

たとえば、200番台のコードは成功を、400番台はクライアントのエラーを、500番台はサーバーのエラーをそれぞれ示します。

詳しくは次項で、、

# 範囲ごとのHTTPステータスコード
|コード範囲 | 分類 | 内容 |
|:-:|:-:|:-:|
| 100番台  | 情報レスポンス  | 継続処理中  |
| 200番台  | 成功レスポンス  | リクエスト成功  |
| 300番台  | リダイレクトメッセージ  | 転送中 |
| 400番台  | クライアントエラーレスポンス  | クライアント側のエラー  |
| 500番台  | サーバーエラーレスポンス  | サーバー側のエラー  |


<details><summary>全てのステータスコードはこちら</summary>


https://developer.mozilla.org/ja/docs/Web/HTTP/Status

</details>

# よく使われるHTTPステータスコード
200 OK: リクエストが成功し、応答が期待どおりであることを示します。

301 Moved Permanently: リクエストされたリソースが恒久的に新しいURLに移動されたことを示します。
このステータスコードは、ウェブサイトがリニューアルし、ディレクトリが変わった場合に利用されます。

404 Not Found: サーバーがリクエストされたリソースを見つけることができなかったことを示します。
これは、ウェブ上でよく目にするエラーですね。

500 Internal Server Error: サーバー側で何らかのエラーが発生し、リクエストを処理できなかったことを示します。

# HTTPエラーコードのトラブルシューティング
エラーコードが表示された場合の対処方法の例を簡単に、、
【ユーザー視点】
404エラーの場合は、そもそもURLが存在しない場合や、URLのスペルミスやリダイレクトの設定ミスなどURL関係のエラーです。
対処としてはURLが正しいか確認をしてページを表示すること。
ケアレスミスで起こるエラーですので注意しましょう。

500番台エラーはサーバー側の問題なので、ウェブサイトの管理者に連絡するのが最善です。

管理者の立場の場合の500番台エラーは
原因究明が難航するそうです。
ご参考までに

https://www.profuture.co.jp/mk/column/55855



なお、トラブルシューティングの際は、ブラウザのキャッシュのクリアや、異なるデバイスやブラウザからアクセスを試みるなどの基本的な手順も役立つそうですね。


# まとめ
HTTPステータスコードは、想像以上に大量にありますね。
ですが、エラーコードの内容は明確に示されているので、
ユーザー側からすると、適切な対応を取ることができます。
今後も目にする機会は多いと思われますが、これらを理解し、
エラーに対応できるようになれればと思いました。

## 参考

https://www.itmanage.co.jp/column/http-www-request-response-statuscode/

https://www.seohacks.net/blog/1147/
Snowflake 初期設定：⑧SYSADMIN編 スキーマ作成

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
Snowflakeのトライアルおよびご契約後の初期設定を行うため
管理者ロールの段階を理解するため

### ■前回の記事
[Snowflake 初期設定：⑦SYSADMIN編 データベース作成](
https://qiita.com/taku_tachibana/items/171df9a2be79ba4f805f)

### ■今回の作業
SYSADMINでスキーマを作成していきます。
スキーマを利用できるロールを割り当てます。

### ■スキーマを作成する。
以下のコマンドで作成していきます。
```
use role SYSADMIN ;
use database <データベース>;
create schema <スキーマ>;

例）
use role SYSADMIN ;
use database TEST_DB ;
create schema TEST_SC;
```
前回、行ったタイムトラベル設定ですが、スキーマレベルでも設定可能です。
下位オブジェクトのタイムトラベル設定が優先されるため、詳細に設定される場合は
仕様を理解しておきましょう。

### ■スキーマの使用権を割り当てる。
作成後は、所有者しかスキーマを使用できないので、
前段で作成したアクセスロールに使用権を割り当てます。
```
use role SYSADMIN ;
use database <データベース>;
grant USAGE on schema <スキーマ> to role <アクセスロール>;

例）
use role SYSADMIN ;
use database TEST_DB;
grant USAGE on schema TEST_SC to role TEST_ACCESS_SELECT_ROLE ;
grant USAGE on schema TEST_SC to role TEST_ACCESS_ALL_ROLE ;
```

### ■注意点
データベース、スキーマの使用権ですが、これをいずれも割り当てないと
スキーマ配下のオブジェクトを参照および操作・利用することはできません。

### ■あとがき
スキーマ作成までを初期設定として、ここで初期設定セクションは終わりです。

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
Snowflakeの記述作法について

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
　
### ■本記事の目的
Snowflakeのワークシート利用やスクリプト開発における
データベース、スキーマ、ウェアハウス、ロールの4つのオブジェクトを
セッションで使用するときの記述について取りまとめます。

オブジェクト作成における意図しない結果を防ぐための作法として
捉えていただけると幸いです。

### ■記述法について
以下の2つの記述形式が存在します。
①セッションコンテキスト
　説明：USE文を使用し、対象セッションのオブジェクトを指定します。
　　　　セッションの利用者（ロール）や利用環境を確定するイメージです。
```
USE ROLE [ロール名];
USE WAREHOUSE [ウェアハウス名];
USE DATABASE [データベース名];
USE SCHEMA [スキーマ名];
※セッションで各オブジェクト種類ごとで、一つのみ指定可能です。
```

ワークシートで、利用するとコンテキストとして指定されます。
![コンテキスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/2b4121f9-2f89-b0bc-6462-69c3d8d25b3e.png)

　
②完全修飾名
　説明：データベース、スキーマをクエリ内部で明示的に記述します。
```
[データベース名].[スキーマ名].[オブジェクト名]
※オブジェクトは、スキーマオブジェクトのこと
```
　
補足事項1：①②の関係性について
　②を記述しない場合、①のコンテキストが指定されます。
　②を記述した場合、①よりも優先的にオブジェクトを指定します。

補足事項2：PUBLICスキーマ
　①からスキーマ名を除くかつ②を記述しない場合、
 　PUBLICスキーマが適用されることがあります。
　PUBLICスキーマは、データベースのデフォルトスキーマとして存在します。

### ■ロール利用
Snowflakeのオブジェクト作成において、意図しない所有者になることは、ロールおよび作成ルールを理解していないときに起こりがちです。
特に、ACCOUNTADMINですべてのオブジェクトを作成してしまうことはアンチパターンとして、ご留意ください。

以下は、システムロールの初回のベストプラクティスです。※オプションは省略
 
USERADMINの例
```
USE ROLE USERADMIN;
CREATE USER [ユーザー名];
CREATE ROLE [ロール名];
```
　
SECURITYADMINの例
```
USE ROLE SECURITYADMIN;
CREATE NETWORK POLICY [ネットワークポリシー名];
```
　
SYSADMIN（または各作成権限のあるカスタムロールでも可）の例
```
USE ROLE SYSADMIN;
CREATE DATABASE [データベース名];
```

上記の例のように、ワークシート上のオブジェクトを作成では
USE ROLE [ロール名]; を作成クエリの前に配置、使用することが定石です。
意図しない動作を防ぐためにも定型文として覚えましょう。


### ■データベース・スキーマ利用
Snowflakeのオブジェクト作成において、意図しないデータベースおよびスキーマの所属になることは、複数のデータベース・スキーマをまたがって取り扱っているときに起こりがちです。
時には、データ事故につながるケースもあります。

以下は、データベース・スキーマ作成におけるベストプラクティスです。
いずれかの例で、防ぐことが可能です。
　
コンテキスト利用の例
```
USE DATABASE [データベース名];
USE SCHEMA [スキーマ名];
CREATE TABLE [テーブル名](カラム名 データ型,…);
```
　
完全修飾名の例
```
CREATE TABLE [データベース名].[スキーマ名].[テーブル名](カラム名 データ型,…);
```
　
上記の例のように、ワークシート上のデータベースオブジェクト作成では、
USE DATABASE [データベース名];、USE SCHEMA [スキーマ名] を作成クエリの前に配置、使用する
または　完全修飾名により明示的にどのオブジェクトを作成・操作することを明確にすることが定石です。
意図しない所属やデータ置換を防ぐためにも定型文として覚えましょう。

### ■ストアドプロシージャにおけるケース
ストアドプロシージャなどのスクリプトを作成される際は、注意が必要です。
内部のプログラムが複数または別のデータベース・スキーマにまたがって処理されるか整理し、記述法を検討する必要があります。
※ストアドプロシージャの環境間の移行時の考慮なども含む
内部のプログラムで、完全修飾名を利用していない場合、ストアドプロシージャの所属データベース・スキーマが適用される仕様となっています。

### ■ウェアハウス利用
利用するウェアハウスを指定します。誤指定による重大なデータ事故につながることはありませんが、ワークシート、ジョブ（外部からのクエリ実行）、ストアドプロシージャ、タスクで指定する必要があります。

ウェアハウス利用の例
```
USE WAREHOUSE [ウェアハウス名];
SELECT * FROM [データベース名].[スキーマ名].[テーブル名];
```

サイズ（XS,S…）ごとでウェアハウスを定義している場合は、意図しないクレジット利用の過多を防ぐためにも、指定を行いましょう。


### ■あとがき
今回の記事作成の経緯については、Snowflakeを使い始めた方が
どのようにワークシートを使うかを迷われていた方が多かったため
取りまとめました。
また、ACCOUNTADMINによる各種オブジェクト作成（アンチパターン）を防ぐためにも残した方が良いと考えました。
Snowflake独自のルールが意外と多いため、今後もポイントがあれば
このような記事を作っていきたいと思います。
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
Hello Worldからの復習 〜演算子〜

趣味でギターを弾くけど、〇〇スケール等、専門的な音階がいっぱいあって、良く〇〇スケールて何度と何度の音だっけ？てのがあったなぁ。
エンジニアの実務でも「どっちだっけ？」て聞いたり聞かれたりは別に良くあること。
スムーズに答えれたりしたらスマートだなと思う。

**お品書き**
+ 演算子って？

----

**演算子って？**
-
計算するとき足したり引いたりするやつです。

もっと言うと、足す、引く、掛ける、割る、余りを出す、比較するとかいうやつです。

| |  |  | |  |  |
|:-:|:-:|:-:|:-:|:-:|:-:|
|①|++|--|   |   | +l -l |
|②| * | / | % |   | × ÷ 余り|
|②| + | - |   |   | + - |  |
|③| < | > | <= | >= | 大小比較|
|③| == | != |   |   | 等しいか|
|④| && | ll |   |   | かつ、または|
|⑤| = | += | -= |   |代入   |
|⑤| *= | /= | %= |   |  複合代入 |

##### ①インクリメント・デクリメント演算子
`a++` → `aに1を加える` ※`a = a + 1`、`a += 1`と同じ
##### ②算術演算子
`8/5` → `1` `8%5` → `3`
##### ③関係演算子
`a >= 0` → `aが0以上`ならtrue ※結果は必ず**true**か**false**
##### ④論理演算子
`( a >= 0)&&( b >= 0)` →　`aが0以上`**かつ**`bが0以上`なら**true**
##### ⑤代入・複合代入演算子
`a += b` → `aにbを加えて`**a**に代入 ※`a = a + b`と同じ

```java:java
class Aaa{
  public static void main(String[] args){
    // コマンドラインから入力したデータ（文字列型）を
    // int型に変換する
    int a = Integer.parseInt(args[0]);
    int b = Integer.parseInt(args[1]);
    
    System.out.println("a = " + a + ", b = " + b);
    System.out.println("a + b = " + (a + b));
    System.out.println("a - b = " + (a - b));
    System.out.println("a * b = " + (a * b));
    System.out.println("a / b = " + (a / b));
    System.out.println("a % b = " + (a % b));
    System.out.println("a >= 0：" + (a >= 0));
    System.out.println("(a >= 0) && (b >= 0)：" + ((a >= 0) && (b >= 0)));
  }
}
```

```cmd:cmd
C:\Java\1>java Aaa 8 5
a = 8, b = 5
a + b = 13
a - b = 3
a * b = 40
a / b = 1
a % b = 3
a >= 0：true  //aは0より大きい
(a >= 0) && (b >= 0)：true //aは0より大きい かつ bより大きい
```
値を変えてみよう
```cmd:cmd
C:\Java\1>java Aaa -8 -5
a = -8, b = -5
a + b = -13
a - b = -3
a * b = 40
a / b = 1
a % b = -3
a >= 0：false //aは0より小さい
(a >= 0) && (b >= 0)：false //aは0より小さい かつ bより小さい
```

ちなみにこの記述の補足
 `Integer.parseInt(args[ ]);`
 コマンドラインから入力されるとき、mainメソッドのargsの部分に入るのだが、文字列で入力されるため、改めてint型に変換してあげる記述が必要。

 記述しないと

 ```cmd:args
 java Aaa 8 5と入力の場合
    ↓
　85になる。
 ```

数値ではなく文字列を入力すると・・
```cmd:cmd
C:\Java\1>java Aaa a b
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.base/java.lang.Integer.parseInt(Integer.java:652)
        at java.base/java.lang.Integer.parseInt(Integer.java:770)
        at Aaa.main(Aaa.java:5)
```
        
 `NumberFormatException`というエラーが出ました。
 これは`Integer.parseInt`文字列を数値に変換したいのに「a」という文字が入力されて変換できませんと怒られています。

 このエラーになったときは数値の形式になっているか見てみましょう。
Snowflake S3データロード：②ファイル形式

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
Snowflakeのデータロードを理解する。
ユーザー管理のAmazonS3からSnowflakeにデータロードを行います。
S3バケットとフォルダおよび取込用のテストデータ（CSV形式）は、事前に作成済みとします。

### ■前回の記事
[Snowflake S3データロード：①ストレージ統合](https://qiita.com/taku_tachibana/items/42f5e424c2325db5bfae)

### ■概要
ファイル形式を作成していきます。
外部ステージを作成・利用するためには、パラメータオプションによりスキップしてもよいのですが、
実際の運用を想定し、定義しておくことをお勧めします。

### ■前提として
ファイル形式利用による外部ステージ作成ですが、前提として以下を行っておく必要があります。
・外部ステージで参照するS3の特定フォルダ内は、すべて同一のファイル形式で統一されていること
・異なるファイル形式の場合、フォルダごとの区画整理が最適化されていること。

　上記、2点を行っておかないと、ロード時にエラーが起こり、またフォルダ内部のファイルをロードする際の設計や仕様としても非効率になります。

 ### ■ファイルを参照する。
作成前に、ロードするファイルの内容を整理しましょう。
　
以下が代表的な考慮点にはなります。
・拡張子：csv、jsonなど
・エンコード：utf-8、shift-jisなど
・列区切り：カンマ、タブ、パイプなど
・囲い文字："（ダブルクォーテーション）など
・圧縮方式：圧縮なし、gzipなど
・ヘッダーの有無
・日付・タイムスタンプ

他にある場合は[公式リファレンス](https://docs.snowflake.com/ja/sql-reference/sql/create-file-format)を参照ください。

※特に考慮しなくていい場合は、デフォルトオプションで良いです。
　
　
今回の記事では以下のテストデータ（CSV形式）をロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/2e38f5f7-7465-d630-c33a-8dd6d132a846.png)
　↓↓↓↓
ファイルについて整理したところ以下のようになりました。
・拡張子：csv
・エンコード：utf-8
・列区切り：カンマ
・囲い文字：なし
・圧縮方式：圧縮なし
・ヘッダーの有無：あり
・タイムスタンプ：Snowflakeのデフォルト形式である。


### ■ファイル形式を作成する。
スキーマオブジェクトのため、作成権を持っているロールで作成します。
前段で整理したファイル内容と[公式リファレンス](https://docs.snowflake.com/ja/sql-reference/sql/create-file-format)からの設定値を、
作成文のオプションに反映します。

```
use role <ロール>;
use database <データベース>;
use schema <スキーマ>;

create file format <ファイル形式>
type = CSV 
compression = AUTO 
field_delimiter =',' 
skip_header = 1 
field_optionally_enclosed_by = NONE
encoding = 'UTF8' 
;
/*※オプションは例です。適宜追加・変更してください。*/
```

### ■ファイル形式の命名について
ファイル形式の名称ですが、筆者は各オプションを英数3文字以内で
"_"区切りで命名していることが多いです。※[N]は、NO,NONEを表す
　例）CSV_HE_CM_NFO_U8
 
ファイル形式の種類が多い場合は、外部ステージから接頭辞付きの類似の名前で定義するのも良いと考えます。運用で利用するファイル形式の共通利用が最適であるかなどは、別途ご検討ください。

### ■注意点
 ファイル形式ですが、ロード/アンロードは、オプションが異なるため、分けてファイル形式を定義することをお勧めします。※外部ステージも同様に分けて定義する。

### ■あとがき
他案件で、ファイル形式を作成しないパターン（外部ステージに直接ファイル形式オプションを入力する）を拝見したことがありますが、コードの冗長化を防ぐためにも定義はしておいた方が良いと思われます。また、定義書作成時も参照整理がしやすくなるメリットがあるので是非活用しましょう。

### ■次の記事
[Snowflake S3データロード：③外部ステージ](https://qiita.com/taku_tachibana/items/030ed2720ee25039dc12)
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
Font Awesomとは（自分用）

・Font Awesomeとは
無料で利用可能なWebアイコンフォント。

・使い方
CDNプラットフォームを読み込む。
htmlファイルのhead内に入れる。
```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
```

・ポイント
外部サイトでの接続で表示されているのでインターネット環境は必須。
Snowflake S3データロード：③外部ステージ

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
Snowflakeのデータロードを理解する。
ユーザー管理のAmazonS3からSnowflakeにデータロードを行います。
S3バケットとフォルダおよび取込用のテストデータ（CSV形式）は、事前に作成済みとします。

### ■前回の記事
[Snowflake S3データロード：②ファイル形式](https://qiita.com/taku_tachibana/items/6ca0f9a49158260c1e39)

### ■概要
外部ステージを作成していきます。
前回、作成したストレージ統合、ファイル形式を利用し作成します。

### ■外部ステージを作成する。
スキーマオブジェクトのため、作成権を持っているロールで作成します。
作成済みのストレージ統合、ファイル形式を以下の構文に入れてください。
```
use role <ロール名>;
use database <データベース名>;
use schema <スキーマ名>;

create or replace stage <外部ステージ名>
storage_integration=<ストレージ統合名>
url='<s3バケット/フォルダのURI>'
file_format=<ファイル形式名>
--directory=(enable=true)--ディレクトリテーブル使用する場合は付加する。

例）
use role SYSADMIN;
use database TEST_DB;
use schema TEST_SC;
create or replace stage TEST_STAGE
storage_integration=TEST_INTEG
url='s3://backet_name/folder/csv'
file_format=CSV_HE_CM_NFO_U8 
;
```
S3のURIのフォルダ階層を、ストレージ統合で設定したフォルダの配下階層で、参照制限することが可能です。基本的には、1つのストレージ統合（バケット）から複数の外部ステージを作成し、各配下フォルダの参照を制限することが一般的な利用方法になります。
※運用、監視、セキュリティなどの観点は考慮しましょう。

### ■参照の確認
Snowflakeからの外部ステージのS3参照の確認方法はいくつかありますが、
代表的なものを紹介します。
　

LIST文：S3バケット/フォルダ配下のファイルリストを出力できます。
```
LIST @<外部ステージ>;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/687cde87-3e8d-427c-e61b-e9e9a3fc79c1.png)

　
外部ステージへのクエリ：外部ステージに対して直接クエリします。
```
SELECT $1,$2,…,$N -- 区切り列の分だけ調整
FROM @<外部ステージ>;
```
※ファイル形式が適合していれば、列番で参照可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/aa4e333b-f961-0408-2acf-fba01ef133b4.png)

　
ディレクトリテーブルへのクエリ：※外部ステージへの有効化設定が必要
```
SELECT * FROM 
DIRECTORY(@<外部ステージ>);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/3ae10776-e444-7537-cc84-04191188a66f.png)



### ■エラーが出た場合
以下をご確認ください。
〇ユーザー管理のAWS
・ロールに許可しているIAMポリシー
・IAMロールの信頼ポリシー

〇Snowflake
・外部ステージ使用権
・ファイル形式使用権

### ■あとがき
次回は、実際にテーブルにデータをロードします。
S3とSnowflakeをどの粒度でストレージ統合を構成するかを図式化したほうが良いと考えています。番外編として作成してみます。

### ■次の記事
[Snowflake S3データロード：④COPY INTOによるデータロード](https://qiita.com/taku_tachibana/items/9c54f4a4dde5f1cf9853)
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
「プログラマの夫」から学んだ事

# 「プログラマの夫」とは
「プログラマの夫」とは以下のジョークのことです。
>“Could you please go shopping for me and buy one carton of milk, and if they have eggs, get 6!”
>ある妻がプログラマの夫に「買い物にいって牛乳を1つ買ってきてちょうだい。卵があったら6つお願い」と言った。
>
>A short time later the husband comes back with 6 cartons of milk.
>夫はしばらくして、牛乳を6パック買ってきた。
>
>The wife asks him, “Why the hell did you buy 6 cartons of milk?”
>妻は聞いた「なんで牛乳を6パックも買ってきたのよ！」
>
>He replied, “They had eggs.”
>夫いわく「だって、卵があったから……」

「卵があったら6つお願い」において買うものの指定がないため、前命令の牛乳を買うを引き継いで解釈してしまい、卵は牛乳の個数を左右するフラグとして解釈してしまったというジョークです。

卵があったら　→　牛乳を6つ買う
卵がなかったら　→　牛乳を1つ買う

こんな状況は実際には中々あり得ないでしょう。
結婚できるプログラマなんて聞いたことがありません。

# 本題
冗談はさておき本題ですが、この問題は家庭であれば夫に非があると思われますが、仕事であれば妻に非があります。
(ジョークにマジレスするという行為が非常にナンセンスであることは自覚しております。何卒お許しください。)
## 問題点
まずは何故牛乳と卵が必要になったのかが不明です。
しっかりと牛乳と卵が将来的に必要になるため、このおつかいを頼んでいるのだという背景を、前提として伝えるべきです。

いつも飲む牛乳が切れそうだから1パック買ってきてほしい。
もしも卵が売り場にあったら卵を6個買ってきてほしい。
パック売りで丁度6個の卵が無かったら、最も6個に近い個数のパックを1つ買ってきてほしい。

少なくともこの程度の依頼をしなければ、食い違いがあった場合に自分の責任となってしまうと思います。

~~そして両者共に結婚しているのにここまでお互いのことを理解していないのも問題です。
普段から相手を知ろうとしていればこのような事態にはならなかったのでは？~~

## 仕事に活きる？
そしてこれはきっと仕事にも通ずるのではないでしょうか。
ITであれば要件定義、基本設計、詳細設計と段階を踏んでいく訳ですが、お互いの認識がずれ、誤った要件定義になってしまうと、牛乳を腐らせるとは比にならないほどの被害を生み出してしまいます。
そこでこの教訓を活かし、要望をすべて正しく伝え、お互いに最終的なゴールを共有することで、このような被害を減らせるわけです。
また、ITでなかったとしても、仕事には往々にして人に指示を出さなくてはならない場面があります。
小さな仕事の指示であっても、正しく指示を伝え、同じゴールを見ているか逐一確認することが大切だと思います。

こういった指示がない場合にも、作業を実施する際に、この作業おかしくないかと疑問を持つことも大切です。
指示された作業をただこなすのではなく、作業を自分事として捉え、意味を考えながら作業を進めていくことも求められます。

# まとめ
今回は「プログラマの夫」から学んだ事をまとめてみました。
ジョークを解説してマジレスするという、ジョークに対する侮辱のようなことをしてしまって、大変心苦しい限りです。
これから妻の立場にも夫の立場にも立つことになるので、ここでまとめたことを意識していこうと感じています。
もし結婚したら、妻の言いたいことを察せる夫を目指します。
Snowflake S3データロード：ストレージ統合設計

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
ストレージ統合を理解する。
ストレージ統合の作成単位（バケット／フォルダ）について整理する。

### ■前回の記事
[Snowflake S3データロード：④COPY INTOによるデータロード](https://qiita.com/taku_tachibana/items/9c54f4a4dde5f1cf9853)

### ■概要
ストレージ統合は、
Snowflakeとクラウドストレージのセキュリティ情報を定義するオブジェクトですが、
どの単位で定義しておくべきか気になったので、記事にします。
S3バケット/フォルダとSnowflakeオブジェクトの構成に図式化します。
ストレージ統合設計については、考え方あると思いますが、いくつかご紹介します。

### ■構成図
AmazonS3とSnowflakeのストレージ統合および外部ステージの構成です。
※ケースとして、統合3パターンほど複合的に記載しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/49b177ff-671e-33c4-90d6-32048ddc2af5.png)
⇒各操作権限（READ／WRITE）によっては、構成を考慮したほうが良さそうです。

### ■ストレージ統合の構成の考え方
ストレージ統合の作成ケースのポイントとしては以下が挙げられます。
　・ストレージ階層のセキュアアクセスの統合・分散
　・ストレージ階層の選択的参照
　・READ,WRITE操作の共通・分散
 
評価ポイントとしては以下が挙げられます。
　・運用
　・監視
　・セキュリティ
　
過去のご要件で挙がった事例としては、以下のようなものがあります。
　・AWS CloudWatchなどで監視性（ロールの操作履歴）を担保したい
　・システム種類ごとのIFロード処理とロールを紐づけ、それをポリシーによって制限したい
　・運用の簡易さを優先するためできるだけオブジェクトは統合したい
　・ストレージのセキュリティ性を担保するため分散させたい

顧客ごとで要件は変わるため、応じてストレージ統合を構成する必要があります。
メリット、デメリットを説明する必要があると思いますので、事項でまとめます。

### ■マトリックス表
事項に応じて、記載しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/c2755636-5ba8-7491-d42f-d7d2ccbd6c8c.png)
選択的参照は、セキュアアクセスの分散に含まれるのでここでは集約しています。
担保したい観点を増やすほど、関係性としてはトレードオフです。

### ■あとがき
ストレージ統合を設計される際の参考にご利用いただけますと幸いです。
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
Cognos Analytics 11.2 でのログメンテについて

Cognos Analytics 11.2でのログメンテナンス対象をまとめた資料を公開しました。
ログメンテを検討する際、参考にしてみてください。

Cognos Analytics 11.2.4 FP2 on Linuxで確認した内容になっています。

https://www.slideshare.net/slideshow/cognos-analytics-11242-log-maintenance-2dfc/267299949
ZED  SDK を使いこなす object

[ZED SDK](https://www.stereolabs.com/developers/release) の使い方が覚えきれていないのでメモを残す。
ZED SDK はStereoLabs がZED2やZED Xなどのステレオカメラ用に提供しているSDKである。

## Objectに関する公式のドキュメント
https://www.stereolabs.com/docs/object-detection

## ZED SDK で取得できる object のデータ構造

コードの断片
```.py:
# インスタンスを予め用意しておく必要がある。
objects = sl.Objects()
# 引数のobjectsに値が設定される。
zed.retrieve_objects(objects, obj_runtime_param)
for obj in objects.object_list:
    print(obj)

```

出力例

```.py:
obj=<pyzed.sl.ObjectData object at 0xffff91166310>
action_state IDLE
bounding_box [[-0.7521685   0.2714799   0.0135718 ]
 [-0.7505594   0.17110072 -1.1674953 ]
 [ 0.43461442  0.19009982 -1.1674953 ]
 [ 0.43300533  0.290479    0.0135718 ]
 [-0.74268794 -0.31991953  0.0638479 ]
 [-0.74107885 -0.4202987  -1.1172192 ]
 [ 0.4440949  -0.4012996  -1.1172192 ]
 [ 0.4424858  -0.30092043  0.0638479 ]]
bounding_box_2d [[   0.  149.]
 [1133.  149.]
 [1133.  715.]
 [   0.  715.]]
confidence 95.82266235351562
dimensions [1.1853261  0.59360832 1.1853261 ]
head_bounding_box []
head_bounding_box_2d []
head_position [nan nan nan]
id 0
label Person
mask n/a sl::Mat not initialised
position [-0.15359642 -0.0553547  -0.55263519]
position_covariance [3.24492521e-06 7.19377411e-08 7.18192496e-07 3.88015178e-06
 2.58829715e-07 2.58403406e-06]
raw_label 0
sublabel Person
tracking_state OFF
unique_object_id 45987a7d-2b95-430f-99d0-6c23a2286498
velocity [nan nan nan]
```
InnoRules7.1のJDKを11にアップグレードする際の注意点

# 背景
InnoRulesサーバとTomcatを共有しているWebアプリにおいてJDK11の機能が必要となった。
JDKを11にアップグレードしたところTomcatが起動しなくなったので解決策を記録する。

# 環境
- Windows Server 2019
- JDK 1.8.0_144
- InnoRules 7.1
- Tomcat 7.0.53

# 発生した問題

## Tomcatが起動しない
`java.endorsed.dirs`オプションが原因。
JDK8まで存在していたJava推奨標準優先メカニズム機能がJDK9で削除されている。
そのためこのオプションが指定されていると起動しない。

### 解決策1
`catalina.bat`内の`-Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%"`を削除する。

### 解決策2
`bin` `lib`フォルダを最新Tomcat7のものに置き換える。
https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.109/bin/

## java.lang.NoClassDefFoundErrorが発生する
`java.activation`モジュールがJDK9で削除されたことが原因。

### 解決策
`javax.activation-1.2.0.jar`を入手し以下の２箇所に配置する。
- `innorules-home\lib`
- `innorules-home\innorules-server\apache-tomcat-7\lib`

https://mvnrepository.com/artifact/com.sun.activation/javax.activation/1.2.0

# 参考
https://docs.oracle.com/javase/jp/9/migrate/toc.htm

https://jpn.nec.com/webotx/download/info/from_JDK8_to_JDK11.pdf

https://www.hitachi.co.jp/Prod/comp/soft1/cosminexus/apserver/document/download/wp_dev_ope_jdk11_09_87.pdf
モダンなLinuxコマンドを使ってみた

最近自分が見かけたコマンドをまとめてみました。

## eza
lsコマンドの上位互換的なコマンド。lsと違いシンタックスハイライトしてくれます。また`--icons`を使用するとファイルアイコンまで表示してくれます。`ls -l`よりちょっと見やすい気がします。

```sh
eza -l --icons
```
![スクリーンショット 2024-02-28 14.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/e8d30fd8-eced-f407-5ac1-6ba034e2f239.png)
[eza](https://github.com/eza-community/eza)

## z
cdのようにディレクトリ移動できます。`cd`を使うことで、頻繁に使用するディレクトリを覚え重要度を出します。重要度の高いディレクトリにアクセスしてくれます。
![スクリーンショット 2024-02-28 14.50.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/0313f430-536b-a302-0880-8c4c0a0df0c2.png)

## bat
catコマンドの上位互換的なものになります。シンタックスハイライトされ`less`のような機能も持っています。
コマンド上に残ります。
```sh
bat resources/views/welcome.blade.php
```
![スクリーンショット 2024-02-28 14.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/e8110b39-d253-cbc1-e0c8-b6d414e56394.png)
[bat](https://github.com/sharkdp/bat/blob/master/doc/README-ja.md)
## fzf
インクリメンタル検索、曖昧検索ができるコマンド。
検索がすごく速いように感じました。まだ把握しきれてないですが便利そうです。
こちらで詳しく解説されていました。
https://envader.plus/course/7/scenario/1039
![スクリーンショット 2024-02-28 14.46.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/61ad24e1-608e-349b-64b2-7166db88e96a.png)
[fzf](https://github.com/junegunn/fzf)
## fd
`find`の上位互換のコマンドで並列ディレクトリトラバーサルによりfindより速いです。
[fd](https://github.com/sharkdp/fd)

## ripgrep
`grep`の上位互換でより速いです。
[ripgrep](https://github.com/BurntSushi/ripgrep)

## dog
`dig`に似たコマンドです。
`dig`と`dog`の違いです。dogの方が情報が絞り込まれてます。
```
dig google.com
```
![スクリーンショット 2024-02-28 14.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/9676dbd8-3f46-ec86-76d4-8a3cc25b1d33.png)
```
dog google.com
```
![スクリーンショット 2024-02-28 14.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/189d9e39-b5db-5bc9-5095-95e18f9de309.png)

## gpin
グラフィカルなpingコマンドです。
![スクリーンショット 2024-02-28 14.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/bfaf4b1f-a89b-f907-0e72-88fac2098a57.png)

## httpie
curlより直感的に使える
```sh
http POST http://httpbin.org/post X-API-Token:123 name=John
```
![スクリーンショット 2024-02-28 14.49.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295926/51be5d6d-df58-821a-ea49-d18194746ea6.png)

## まとめ
簡単にでしたがまとめました。使いこなしていきたいです！
PythonでPDFをHTMLに変換する

## はじめに
特定の目的により、PDFをHTML形式に変換する必要が出てくる場合もあります。これは、内容物を直接Webページに埋めめ込むことができ、アクセシビリティを向上させる助けになります。また、PDFをHTMLに変換することで、簡単に編集や内容の更新が行えるようになります。具体的な方法は以下の通りです。
## ツール
* Python 3.12.0
* [Spire.PDF for Python](https://www.e-iceblue.com/Introduce/pdf-for-python.html)

このライブラリは購入する必要がありますが、30 日間の無料試用版も提供されています。
もっと多いサンプルコードについて、[Spire.PDF for Python](https://www.e-iceblue.com/Download/Spire-PDF-Python.html)をダウンロードして参照してください。

## インストール
まず、Spire.PDF for Pythonと plum-dispatch v1.7.4を VS Code にインポートしください。
* Pythonをダウンロードしてインストールします。
* VS Codeで「Extensions」をクリックし、「Python」を検索してインストールします。
* 「Explorer」-「NO FOLRDER OPENED」-「Open Folder」
* フォルダーを選択し、そこに「.py」ファイルを追加します。
* 「Terminal」-「New Terminal」
* 次のコマンドを入力します。
**pip install Spire.PDF**

## コード
```python
from spire.pdf.common import *
from spire.pdf import *

# PdfDocument クラスのインスタンスを作成
pdf = PdfDocument()

# Sample.pdf ファイルから PDF ドキキュメントをロード
pdf.LoadFromFile("C:/Users/Administrator/Desktop/Sample.pdf")

# PdfToHtml.html ファイルに PDF ドキキュメントを保存 (HTML 形式)
pdf.SaveToFile("C:/Users/Administrator/Desktop/ToHTML.html", FileFormat.HTML)

# ドキキュメント オオブジオブジェクトを閉じる
pdf.Close()  
```

## 説明
このコードは、Spire.PDF for Pythonライブラリを使って「Sample.pdf」ファイルを「ToHTML.html」ファイルに変換しています。**PdfDocument**クラスの**LoadFromFile**メメソッドを使用して PDF ドキキュメントを読み込み、**SaveToFile**メソッドを使用して HTML 形式に変換して保存しています。最後に**Close**メメソッドを呼び出して、ドキュキュメント オブオブジェクトを正確に終了させます。

## その他
変換時には、必要に応じて変換オプションを設定することもできます。この場合、**PdfConvertOptions**クラスの **SetPdfToHtmlOptions**メメソッドを使用します。
このメソッドは次のパラメーターを含みます。
* **useEmbeddedSvg**: SVG を埋め込め込むかどうか。
* **useEmbeddedImg**: 画像を埋めめ込むかどうか。**useEmbeddedSvg**が「False」に設定されている場合にのみ適用されます。
* **maxPageOneFile**: 1つのHTMLファイルに対する最大ページ数。**useEmbeddedSvg**が「False」に設定されている場合にのみ適用されます。
* **useHighQualityEmbeddedSvg**: 生成されたファイル内で高品質の埋めめ込み SVG を使用するかどうか。**useEmbeddedSvg**が「True」に設定されている場合にのみ適用されます。
Blenderで、見えている映像そのものを画像作成する方法

# なんかレンダリングすると、思った感じの画像が得られない

みたいなことが、僕はよくあります。

単純に技術が足りていないだけですが、今見えてるそのものが保存できたらいいのに！みたいになります（笑）

#  ビューから保存
次の手続きで、見えている画像そのものを保存することが可能です。
1. 左上のビューを選択
1. ビューで画像をレンダリング

これだけです。

# グリッドについて
このままだと、グリッドなどが残ったままになるので、これを消しましょう
1. 右上のボタンからオーバーレイを表示します。
1. ここで、床や座標軸を消せます。

# 最後に
本来はこういったずるい方法ではなく、もっとネイティブにできる方法があるはずなのですが、なかなか見つからない。。。。（笑）
CSSのmin() / max()がStylusのビルトイン関数と競合する件

## 結論
```stylus
.hoge
  width @css{max(0px, 100vh - 10px)}

.fuga
  width "min(%s)" %  (50vh, 500px)

// Stylus変数を一緒に使う場合
.piyo
  width "min(%s, %s)" % (value_a value_b)
```

## 何が問題か
Stylusにはビルトイン関数というものがあります。
便利な機能を元々用意してくれているのですね。

[Built-in Functions | Stylus](https://stylus-lang.com/docs/bifs.html)
[Stylusのビルトイン関数まとめ · GitHub](https://gist.github.com/ejointjp/8e0992cbf83565095adbf695d8bf65fc)

その中にはmin()とmax()という関数があります。
2つの数字を与えると、小さい方 or 大きい方を返してくれます。

`min(1, 5) // 1が返る`

ここで問題なのが、CSSにもmin()とmax()があることです。
昔はなかったので、Stylusを久々に触ってアカンやん！となりました。

CSSのmin()とmax()は、その値の最小値 or 最大値を指定できる関数です。

[min() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/min)
[max() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/max)
[CSSの比較関数が便利すぎる！ min(), max(), clamp()の使い方を詳しく解説 | コリス](https://coliss.com/articles/build-websites/operation/css/css-about-min-max-clamp.html)

レスポンシブデザインとの相性の良さから、非常に便利な関数です。

## 解決策
CSSとStylusに、同じ名前で違う関数が存在してしまっていることがわかりました。

これを回避するために、StylusのCSSリテラルという機能が使えます。
`@css{}`で囲むことで、プレーンなCSSとして扱えるようです。
[CSS Literal | Stylus](https://stylus-lang.com/docs/literal.html)

以下のように記載します。

```stylus
.hoge
  width @css{max(0px, 100vh - 10px)}
```

これでCSSのmaxを使えるようになりました（モチロンminも同様です）。

### Stylusの変数を使う場合
これで解決と思いきや。
Stylusの変数を組み合わせて使いたい場合は、`@css`ではうまくいきませんでした。

`@css`で囲むとStylusの機能ではなくCSSで出力してねという意味になるので、Stylusの変数が効かなくなってしまいました。

変数も同時に使いたい場合は、以下のように記載します。

```stylus
.piyo
  width "min(%s, %s)" % (value_a value_b)
```

Stylusで変数を使うときの記法で`%s`を使う書き方があるのですが、それと併用することで使えました。
（いつ見てもクセ強いんだよな……）

解決。

## 終わりに
カッコもコロンも要らないStylus、私は大好きなのですが世はPostCSS or Sassって印象です。
てかピュアなCSSも相当高機能になってきてますしおすし。

でも使うもんね！と思って久々に触ってみたら今回の罠にかかりました。
私がStylusガッツリ使ってたのは、calc()すげええぇぇ！ってなってたくらい昔だったので……ヘヘ……。

CSS自体と競合してしまってるのは、正直かなり微妙やなーと思いました。
また動向を見守っていきたい所存です。

では！

## 参考
[how can i use max()/min() as css-math-functions instead of stylus-bulidin-functions - Stack Overflow](https://stackoverflow.com/questions/59486233/how-can-i-use-max-min-as-css-math-functions-instead-of-stylus-bulidin-functi)
[Stylus should not overwrite CSS built-in functions, such as min and max · Issue #2584 · stylus/stylus · GitHub](https://github.com/stylus/stylus/issues/2584)
Snowflake S3データロード：④COPY INTOによるデータロード

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
Snowflakeのデータロードを理解する。
ユーザー管理のAmazonS3からSnowflakeにデータロードを行います。
S3バケットとフォルダおよび取込用のテストデータ（CSV形式）は、事前に作成済みとします。

### ■前回の記事
[Snowflake S3データロード：③外部ステージ](https://qiita.com/taku_tachibana/items/030ed2720ee25039dc12)

### ■概要
前回までで、ロードするためのオブジェクト作成を完了したため、空テーブルを作成しデータをロードします。
COPY INTO テーブルによりロードを行います。

### ■テーブルを作成する。
データをロードするためには、テーブルオブジェクトが必要になります。
ファイルに合わせて、列を定義してください。
```
USE DATABASE <データベース>;
USE SCHEAMA <スキーマ>;
CREATE TABLE <テーブル>
(
<COLUMN_NAME_1> <DATA_TYPE>,
<COLUMN_NAME_2> <DATA_TYPE>,
・
・
・
<COLUMN_NAME_N> <DATA_TYPE>
)
/*他テーブルオプションなど*/
;

例）
USE DATABASE TEST_DB;
USE SCHEAMA TEST_SC;
CREATE TABLE TEST_TB
(
TARGET_YM VARCHAR(6),
ORG_CD VARCHAR(10),
ORG_NM VARCHAR(200),
AC_CD VARCHAR(10),
AC_NM VARCHAR(200),
BG_AM NUMBER(28,0),
RS_AM NUMBER(28,0),
RG_TS TIMESTAMP_NTZ
)
;

```

### ■データをロードする。
COPY INTO文でデータをロードします。
この処理には、ウェアハウスを指定してください。
```
USE ROLE <ロール名>;
USE WAREHOUSE <ウェアハウス名>;
USE DATABASE <データベース名>;
USE ROLE <スキーマ名>;

COPY INTO <テーブル名>
FROM @<外部ステージ名>
;

例）
USE ROLE SYSADMIN;
USE WAREHOUSE SYSADMIN\XS;
USE DATABASE TEST_DB;
USE ROLE TEST_SC;
COPY INTO TEST_TB
FROM @TEST_STAGE
;
```

### ■ロードの確認
正常にロードされると、ワークシートでは以下のように出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/95dfe2cd-3f9c-0c64-ce5d-4832aa109fd7.png)
　
履歴を確認する場合、以下で確認可能です。
```
/*14日以内のCOPY INTOによるロードを確認する。*/
SELECT * FROM INFORMATION_SCHEMA.LOAD_HISTORY;
```

### ■あとがき
以上、全4回に渡って、S3からデータロードを行ってきました。
直近の案件で、Pythonから構造化データのExcelファイルを取り込む検証というのも行ったため、全2回でご紹介させていただければと思います。

### ■次の記事
[Snowflake S3データロード：ストレージ統合設計](https://qiita.com/taku_tachibana/items/ff335fd3b39e2eb9029e)
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
【新卒ゲームエンジニア就活】大いにやらかしても内定をもらった話

# はじめに
本記事は「ゲーム業界は高倍率って聞くけど、自分でも大丈夫？」と不安に思う【ゲーム業界志望の学生】の方々に向けた記事となります。

たくさんやらかした私でも内定を頂けた就活対策術、役に立ったサービスなどを語ることで、ゲーム業界を目指す方を勇気づけられたら幸いです。

# 筆者プロフィール
- 情報系大学院生1年
- コンシューマー向けゲーム開発を主とする企業に内定
- ゲーム制作経験あり
- 就活開始：大学院1年生の5月末～

内定を頂いた企業に対して行ったやらかしの一部抜粋
- 当然のように夏インターン落ち
- 早期選考に呼ばれるもコーディングテストを1ヶ月以上先延ばしにする
- 2次面接でも志望職種がブレブレ

これでも真剣に就活に取り組んだつもりなのですが...(泣)
これだけやらかしても内定をもらえるチャンスはあるので、**気になっている企業には必ずエントリーしましょう。**

# 就活対策
私の就活戦略は勝機のありそうな中堅SIerを多めに受けつつ、志望度の高いゲーム企業を何社か受けるという方針で進めました。
しかし、このあたりの意思決定は個人によるものが大きいと考えますので、就活対策を一般化するため大きく4段階に分けてご紹介いたします。
1. ガクチカを用意する
1. 就活を勝ち抜くための情報収集
1. 面接等の選考対策
1. 就活先を決めるための情報収集

# ガクチカを用意しよう
私の就活戦略では正直これが一番重要です。
就活の最も効果的な対策は学生生活を充実させることにあると思います。
面接ではチームでの活動経験を問われることが多かったため、他者と協力する活動もいくつかあると良いでしょう。
私はゲームをチームで制作した経験を面接で話しましたが、技術面とチーム内での立ち回りの両方を話せたためそこそこ評価してもらえたように思います。
面接で聞かれるからではなく、**自分の目指す社会人像を見据えて行動しましょう。**

とは言っても、急ぎでガクチカを錬成する必要のある方もいらっしゃるでしょう。
そのような場合、ゲームジャムやハッカソンであれば比較的短期間で経験を積めるのではないかと思います。
私はそのようなイベントにはあまり詳しくないため、そのあたり話は他の方に任せたいと思います。

# 就活を勝ち抜くための情報収集をしよう
就活を勝ち抜くには「企業との出会い」や「巧い立ち回りを知る」など多くの情報が必要になります。
そのために私が就活中お世話になったサービスを共有させていただこうと思います。

## 逆求人ナビ（株式会社ジースタイラス）
- 企業の方へ個別面談の形で直接アピールできる逆求人イベント
- 早期から企業の方と直接お話しできる機会が得られるうえ、フィードバックをもらえて自分の武器を知ることができる
- サポーターの方に面談の練習やES添削を手伝ってもらえる
- 褒められたことではないと思いますが、筆者は逆求人に関係ない企業のESも添削してもらいました。学生想いな運営に圧倒的感謝！

https://www.studenthunting.com/

## offerbox
- プロフィールやガクチカを書いておくことで企業から選考やイベントの案内が届く
- BtoB企業など見つけにくい企業が向こうから声をかけてくれる
- 就活初期のES練習に書いた文章をもとに継続的にオファーが来るのでコスパが良かった
- オファーが届くとSNSでいいねを貰ったみたいでちょっと楽しい

https://offerbox.jp/

## onecareer
- 企業ごとに面接での質問事項や過去の受験者が書いたESなどが掲載されている
- 企業によっては面接でここに書かれている通りのことが聞かれたので一見の価値あり

# 選考対策をしよう
ガクチカを用意しても面接官に適切に伝えられなくては選考を進むことができません
そこで、私が行った面接対策フローをご紹介させていただきます。
1. 逆求人ナビのサポーターの方と面接練習
1. 逆求人ナビやofferbox経由でインターンや選考にエントリーし面接の回数を重ねる
1. 面接の頻出質問やonecareerの過去問を見て面接想定回答集を作成する

私はいわゆるコミュニケーション能力には自信がありませんでした。
しかし、面接で求められるのは**自身の経験や価値観を言語化し伝える能力**であるため、内向的な方でも大丈夫です。
たとえ相手が大企業の役員と言えども、極論を言うとただの人間です。緊張しすぎず普通に会話することを心掛けましょう。

# 就活先を決めるための情報収集をしよう
就活を勝ち抜くための話はよく耳にする一方で、内定を獲得した後の戦いについて語られることは少ないように感じます。
しかし、就活とは内定を獲得するための戦いではなく、その後の生活を充実させるための戦いであると私は考えているため、入社する企業は慎重に見定める必要があります。
そこで、入社後を見据えた情報を集められるサービス等を共有させていただきます。

## OpenWork, ライトハウス
- 企業の口コミサイト
- 外からだと分かりづらい会社の内情を伺うことができる
- 情報提供者は転職していく人が多くバイアスのかかった個人の情報であるため、利用には一定のリテラシーが必要

## 有価証券報告書, 投資家向け決算資料
- 企業の経営状況や主力事業、中長期の経営ビジョンなどを知ることができる
- 資産の流動比率などから企業の健全性を推し測ることができる
- 一次情報に基づき自己責任で意思決定ができる **（重要）**

openworkや先輩などの情報は個人のバイアスがかかっていたり、内定先の人事の方は内定者を逃さない仕事をしているという意味で利害関係者であったりするため、よりフラットな視点から企業分析を行いたい場合には投資家向け情報が役に立つかもしれません。

## 社員面談
- 企業の雰囲気を知るためには現場で働く方から直接お話を伺うのが一番（個人の見解）
- 業務内容も担当している方に直接聞いたほうが理解を深められる
- OBやOGがいれば良いが、筆者のように伝手がなくても内定後に人事の方にお願いすれば社員の方と面談をセッティングしてくれる場合がある
    - 会社訪問お断りと書いてある企業にも頼んでみれば面談してくれるところもある

# さいごに
ゲーム業界の就活は高倍率と言われ不安になることも多いと思います。
かくいう私も良さげな中堅SIerから内定を頂くまでは、ゲーム業界に対しかなり弱気で逃げ腰な就活をしてしまいました。
選考が進むたびに「今度こそ落ちた...」と愚痴をこぼしたり、開き直っておもしろ社会科見学のつもりでヤケクソに面接を受けたりしました。
一方で、もし受かる実力があってもエントリーしなければ内定は獲得できません。
たとえ明らかな上位企業であったとしても、母校から内定者が出ていなくてもエントリーだけは行うようにしましょう。
本記事が少しでも読者の方のお役に立てれば幸いです。
Snowflake Excelデータロード：Pythonによるロード（単一ファイル）

[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)

### ■本記事の目的
Snowflakeに、構造化データで記載されたExcelファイルを直接テーブルにロードする検証を行うため。
SnowflakeのPythonワークシートにて、SnowPark、PandasなどのPythonライブラリによるプログラム検証を行うため。

### ■概要
[Snowflake S3データロード：③外部ステージ](https://qiita.com/taku_tachibana/items/030ed2720ee25039dc12) から派生して検証する。
ストレージ統合、外部ステージはそのまま流用で、検証を行う。
今回は、単一のファイルをロードすることを行う。

### ■Pythonライブラリ
Pythonのコマンドは、以下をインストールします。
・snowpark
・pandas
・openpyxl

### ■検証テストデータ
Excel内のテストデータは、以下のようにA1セルから始まる構造化データの状態で、
xlsxの拡張子でS3に配置します。
※1行目はヘッダー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/02d2d950-831d-c7aa-aa42-7b9d698d9193.png)

件数は、ヘッダー除きの17974件です。

### ■ストアドプロシージャ（Pythonプログラム）
ストアドプロシージャで定義します。※任意の名前で良いです。
ロードするテーブル名は、プログラム内で決定しておく必要があります。
ストアドプロシージャとテーブルの所属のデータベース・スキーマは同一である必要があります。
引数に、ファイルパスを設定しておきます。
このプログラムは、単一のファイルだけロードする仕様です。
```
CREATE OR REPLACE PROCEDURE import_excel_sp(file_path string)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python', 'pandas', 'openpyxl')
HANDLER = 'main'
AS
$$
#ライブラリをインポートする。
from snowflake.snowpark.files import SnowflakeFile
from openpyxl import load_workbook
import pandas as pd

#ファイルパスURLからExcelファイルを展開する。
#Excelファイルデータをデータフレームに変換する。
#データフレームをテーブルにINSERTする。
def main(session, file_path):
 with SnowflakeFile.open(file_path, 'rb') as f:
     workbook = load_workbook(f)
     sheet = workbook.active
     data = sheet.values
 
     # 最初の行をヘッダーとして設定
     columns = next(data)[0:]
     # 2行目以降のデータに基づいてDataFrameを作成する
     df = pd.DataFrame(data, columns=columns)
 
     df2 = session.create_dataframe(df)
     #洗替の時は、mode("overwrite")に変更する。
     df2.write.mode("append").save_as_table("<テーブル>")
 
 return True

if __name__ == "__main__":
    main()

$$;
```

### ■ストアドプロシージャを実行する。
実行する前にテーブルを0件にしておきます。
```
TRUNCATE TABLE <テーブル>;
```
0件確認
```
SELECT COUNT(*) FROM <テーブル>;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/62900f3c-b7f7-de5c-0d67-e1df189426e3.png)

　
実行します。
build_scoped_file_url()関数は、外部ステージのパスからURLを生成します。
```
CALL IMPORT_EXCEL_SP(build_scoped_file_url(@<外部ステージ>, '/<フォルダ>/<ブック>.xlsx'));
```
実行結果は正常でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/62eee7d2-858c-3662-feab-ae36baf9c16e.png)
　
件数も想定どおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731433/d59b5420-4b8a-385e-9e61-646bb5b8151f.png)

### ■考慮点
CSVかつCOPY INTOでのロードと比べると、同じデータ内容でも10秒くらい差があると感じました。ウェアハウスのコスト・パフォーマンスを考えると、連続的な利用はあまり推奨はできない方法かもしれません。

### ■参考文献
今回のロード処理の参考で一番シンプルで分かりやすい参考でした。
https://medium.com/snowflake/simplify-data-ingestion-with-snowpark-python-file-access-f2bc0e4cd887

openpyxlで不明な構文があったための参考です。
https://www.soudegesu.com/en/post/python/pandas-with-openpyxl/

### ■あとがき
単一ファイルはロードできることは判明しました。
次回は、COPY INTOのように特定フォルダ内の複数ブックのエクセルファイルを一つのプログラムでロードできるか検証しようと考えています。

### ■次の記事
[Snowflake Excelデータロード：Pythonによるロード（特定フォルダ内の複数ファイル）](https://qiita.com/taku_tachibana/items/795ec176cc1d179b8426)
　
[目次に戻る](https://qiita.com/taku_tachibana/items/408686a031b9624e981e)
Illuminate\Database\QueryException     could not find driver (Connection: mysql, SQL: select table_name as `name`, (data_length + index_length) as `size`, table_comment as `comment`, engine as `engine`, table_collation as `collation` from information_

Ubuntu: 22.04
XAMPP: xampp-linux-x64-8.2.12-0-installer 
laravel: 10.x

```
php artisan migrate
```
エラーが表示される
```
 Illuminate\Database\QueryException 

  could not find driver (Connection: mysql, SQL: select table_name as `name`, (data_length + index_length) as `size`, table_comment as `comment`, engine as `engine`, table_collation as `collation` from information_schema.tables where table_schema = 'mysql' and table_type in ('BASE TABLE', 'SYSTEM VERSIONED') order by table_name)
```
解決方法
```
sudo apt install php-mysql
```
php-mysqlをインストール後、php artisan migrateを実行する。
その後、次のエラーが表示された場合の解決方法
```
SQLSTATE[HY000] [2002] No such file or directory ..................
````
解決方法

/opt/lampp/etc/my.cnfファイルのsocketの設定値を確認する
```
socket		=/opt/lampp/var/mysql/mysql.sock
```
シンボリックリンクを作成する
```
sudo ln -s /opt/lampp/var/mysql/mysql.sock /tmp/mysql.sock
```
CodeIgniter3でAWS SESを使ってメールを送る方法

# はじめに
https://qiita.com/qwe001/items/b340628c2aaffbb12e7a

以前、上記の記事を書いたのはCI3でSESを使ってメールを送る方法がわからず、調べる時間もなかったためでした。
phpMailerで送れるならCI標準機能でも送れるはずだと思って、改めて調査しなおしました。
# 実装
以下のようにすれば、CodeIgniter3の標準機能を利用してSESからメールが送れます。
```php:application/config/email.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$config = array(
    'useragent'      => 'CodeIgniter',
    'protocol'       => 'smtp', // AWS SES の場合は smtp を指定すること
    'mailpath'       => '/usr/sbin/sendmail', // Sendmail へのパス
    'smtp_host'      => 'email-smtp.ap-northeast-1.amazonaws.com', // e.g. AWS SES のエンドポイントを指定
    'smtp_user'      => 'AKI...OF', // e.g. AWS SES のSMTPユーザーアクセスキー
    'smtp_pass'      => 'BPF...H5', // e.g. AWS SES のSMTPユーザーシークレットキー
    'smtp_port'      => 587, // e.g. 25, 465(gmail smtp ssl), 587(AWS SES)
    'smtp_timeout'   => 5, // seconds
    'smtp_keepalive' => FALSE, // 持続的SMTP接続の有効化
    'smtp_crypto'    => 'tls', // e.g. AWS SES 'tls', smtp_hostのプロトコルになる e.g. 'tls://email-smtp.ap-northeast-1.amazonaws.com'
    'wordwrap'       => FALSE, // ワードラップの有効化設定
    'wrapchars'      => 76, // 何番目の文字で折り返すか
    'mailtype'       => 'text', // e.g. 'text', 'html'
    'charset'        => 'utf-8', // e.g. 'utf-8', 'iso-8859-1'
    'validate'       => TRUE, // メールアドレスを検証するかどうか
    'priority'       => 3, // メールの優先度。1～5。 1 = 最高 3 = 通常 5 = 最低
    'crlf'           => "\r\n", // 必ずダブルクオーテーションにすること。シングルだと送れないしエラーも出ない e.g. "\r\n", "\n", "\r"
    'newline'        => "\r\n", // 必ずダブルクオーテーションにすること。シングルだと送れないしエラーも出ない e.g. "\r\n", "\n", "\r"
    'bcc_batch_mode' => FALSE, // BCC バッチモードを有効にするかどうか
    'bcc_batch_size' => 200, // 各 BCC バッチで送るメール件数。
    'dsn'            => TRUE // サーバーからのメッセージ通知を有効にする
);
```

```php:application/controllers/Test.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Test extends MY_Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        $isSent = $this->_sendMailTest();
        echo $isSent ? "メール送った" : "メール送れなかった";
        exit;
    }

    private function _sendMailTest()
    {
        $this->load->library('email'); // @see config/email.php

        $fromAddr = 'noreply@example.com'; // SESに登録済のアドレスでしか送れない。適当なアドレスで送っても届かない
        $fromName = 'システム管理者'; // ここは適当な名前で送っても大丈夫
        $toAddr = 'me@example.com';
        $this->email->from($fromAddr, $fromName);
        $this->email->to($toAddr);

        $subject = "メールタイトルです";
        $message = "メール本文です";
        $this->email->subject($subject);
        $this->email->message($message);

        $isSent = $this->email->send(); // boolean
        return $isSent;
    }
```
# 躓きポイント
* プロトコルは `smtp` を指定すること
* ポートは `587` にすること
* 暗号化プロトコルは `tls` にすること
* 差出人(`from`)のアドレスはSESに登録されたものしか使用できない
    * 適当なアドレスで送るとメールが届かない
* 改行の囲み文字は必ずダブルクオーテーションにすること
    * シングルクオーテーションだとメールが届かないしエラーも出ない
unset関数を使用して引数の値を消そう

## はじめに
unset関数を使用すれば引数で渡した変数の値を消すことができます。(未定義扱いになります。値がnullになることはありません)

## 使ってみる
```php
$num = 12345;
var_dump($num);
unset($num);
var_dump($num);
```
```
int(12345)
Warning: Undefined variable $num in sample.php on line 
NULL
```
値がないと警告がでました。3行目にNULLが出力されていてなぜかと調べてみると値がない場合NULLを格納してくれるそうです。

ということは値の無い変数を使用してif文を実行した場合elseが処理されるはずです。
```php
if($num){
    echo 'trueです。';
}else{
    echo 'falseです。';
}
```
```
Warning: Undefined variable $num in sample.php on line 
falseです。
```
nullが入っている扱いなのでelseが処理されるんですね。

## 終わりに
unset関数を使用すると、nullじゃなくて未定義扱いにすることができました。nullとごっちゃになりそうなんで覚えておきたいです
RHL系/Ubuntu/Debian LinuxのIPアドレス固定（設定）方法

# RHL系/Ubuntu/Debian LinuxのIPアドレス固定（設定）方法
最近proxmox使って色々とLinuxを触っているのですが、いざIPアドレス固定したいと思ったときに毎回ググルのでメモしておきます。

# RHL系
nmcliコマンド もしくは nmtuiコマンド（画面GUI）で設定する。

https://infra-exp.com/linux_ip/

# Ubuntu
netplan 使って設定する。下記のようにyamlで設定する。yamlなのでスペースに気つける必要あり。

```yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp6s18:
      dhcp4: false
      dhcp6: false
      addresses: [192.168.0.21/24]
      routes:
        - to: default
          via: 192.168.0.1
      nameservers:
       addresses: [8.8.8.8]
```

https://qiita.com/zen3/items/757f96cbe522a9ad397d

# Debian 
`/etc/network/interfaces` に設定。画面GUIっぽいのがあったような気がするけど・・・。

https://ararabo.jp/2023-07-01/?p=12757
[解決方法考え中] Datadog のアラートが Resolve 直後に再発してしまう

## 前提

Datadogで以下のようにMonitorを定義したとする。

「Lambdaの実行でエラーが発生した場合アラートを発する」

alertの条件は以下のように定義した。

> Query: `sum(last_1h):aws.lambda.errors{functionname:my-function}.as_count() > 0`
> つまり、
> - Alert threshold: `> 0`
> - Evaluation Details: Evaluate the `sum` of the query over the `last 1 hour`

## 発生する問題

- 1:00pm: Lambda実行失敗。**エラー発生**
- 1:01pm: Datadogがevaluateする(`evaluation window=12:01-1:01`) -> アラートが発生する。
- 1:15pm: Lambdaのバグ修正、Lambdaをリトライして実行が成功。
- 1:20pm: DatadogのUIでモニターを`Resolve`する。
- 1:21pm: Datadogがevaluateする(`evaluation window=12:21-1:21`) -> アラートが再び発生する。


つまり、アラートをResolveした直後に、その直前のエラーが理由でアラートが再び発されてしまう。


## 解決方法

1:20pmの時点で、`Resovle`ではなく、1時間 `Mute` とかにすべきなんだろうか。

あるいは、`sum(last_1h)`を`sum(last_5m)`にすれば、この場合に限っては解決しそう。

あるいは、1:21pmの時点での`evaluation window`を`1:15-1:21`にできたらいいのだが。

あるいは、[evaluation frequency](https://docs.datadoghq.com/monitors/configuration/?tab=thresholdalert#evaluation-frequency) を1時間に1回にすれば良い。


## Ref.

https://docs.datadoghq.com/monitors/manage/status/

https://docs.datadoghq.com/monitors/configuration/?tab=thresholdalert#evaluation-window

https://docs.datadoghq.com/monitors/configuration/?tab=thresholdalert#evaluation-frequency

https://docs.datadoghq.com/monitors/guide/custom_schedules/?tab=day
カラフルなバーの表示（Angular）

## はじめに
参画プロジェクトにて、値に応じてバッテリーの増減を確認できるものがほしいとのことでカラフルなバーを自作:construction_worker_tone2:

## ソース

色の異なる3つのバーをかぶせるように配置する
```.html
<div class="barContainer">
        <div class="colorful-bar" [style.zIndex]="1"></div>
        <div class="gray-bar" [style.width.%]="grayBarWidth" [style.right.px]="0" [style.zIndex]="2"></div>
        <div class="additional-bar" [style.zIndex]="3"></div>
</div>
```

```.css
.barContainer {
    position: relative;
    width: 70%;
}

.colorful-bar {
    top: 0;
    height: 30px;
    background: linear-gradient(90deg,
            #EB5757 0%, #EB5757 20%,
            #F3994A 20%, #F3994A 40%,
            #F2C94B 40%, #F2C94B 60%,
            #26AE60 60%, #26AE60 80%,
            #2296F3 80%, #2296F3 100%);
}

.gray-bar {
    position: absolute;
    top: 0;
    height: 30px;
    background-color: gray;
}

.additional-bar {
    position: absolute;
    top: 0;
    height: 30px;
    width: 100%;
    background: linear-gradient(90deg,
            rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 9%, rgb(255, 255, 255) 9%, rgb(255, 255, 255) 10%, rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, 0) 19%, rgb(255, 255, 255) 19%, rgb(255, 255, 255) 20%,
            rgba(0, 0, 0, 0) 20%, rgba(0, 0, 0, 0) 29%, rgb(255, 255, 255) 29%, rgb(255, 255, 255) 30%, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 39%, rgb(255, 255, 255) 39%, rgb(255, 255, 255) 40%,
            rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0) 49%, rgb(255, 255, 255) 49%, rgb(255, 255, 255) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0) 59%, rgb(255, 255, 255) 59%, rgb(255, 255, 255) 60%,
            rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 0) 69%, rgb(255, 255, 255) 69%, rgb(255, 255, 255) 70%, rgba(0, 0, 0, 0) 70%, rgba(0, 0, 0, 0) 79%, rgb(255, 255, 255) 79%, rgb(255, 255, 255) 80%,
            rgba(0, 0, 0, 0) 80%, rgba(0, 0, 0, 0) 89%, rgb(255, 255, 255) 89%, rgb(255, 255, 255) 90%, rgba(0, 0, 0, 0) 90%, rgba(0, 0, 0, 0) 99%, rgb(255, 255, 255) 99%, rgb(255, 255, 255) 100%);
}
```
 tsで"grayBarWidth"の値を変更し、増減を表現する
 ```.ts
        grayBarWidth: number = (100 - "適当な数値");
        
```

## イメージ
"grayBarWidth"が5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725667/7f0ada99-d2c3-b6bb-c82e-4dad4a5fa5e4.png)

"grayBarWidth"が80
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725667/73e9df77-7186-fc77-1e57-173e65b8cb26.png)

## 終わりに
参考になりましたら「いいね」を押していただけると励みになりますのでよろしくお願いします:sunny::camel:
2024年がうるう年か判定する方法【閏年】

備忘録

```javascript
const isうるう都市 = year => (year % 4 == 0 && year % 100 > 0) || [200, 600].includes(year % 900)
console.log(isうるう都市(2024))
```

https://ja.wikipedia.org/wiki/%E9%96%8F%E5%B9%B4#:~:text=修正ユリウス暦
ffmpegでGPUエンコードするにはソースコードから自前でビルドする必要があると思ってた話（令和最新版）

# 要約
ffmpegでGPUエンコードするにはソースコードから自前でビルドする必要があると思ってたがそんなことはなかったぜ！

# 手順
環境としてはWin11上のWSL2のUbuntu22.04（-pattern_type globを使いたいがためだけにWSLを持ち出している）
GPUはGeForce RTX4070

---

シンプルにapt-getして
```
sudo apt-get install ffmpeg
```


コーデックの指定はこれ↓（ここで当初libx265_nvencと書いていたせいでエラーが出て，ビルドが必要だと勘違いして右往左往する羽目になった）
```
-vcodec hevc_nvenc
```


いざエンコード…爆速！

…
…
…えっこんな簡単でいいの？昔やった時は相当ひーひー言いながらビルドした気がするんだけど…
まさか実はCPUエンコードしてるとか？いやでも爆速だし，タスクマネージャで見る限りGPUはちゃんと回ってるし？？？
ググってみてもみんなCUDA入れてソースコードとってきてとか書いてあるんだけど…


というか，何ならCUDAもcuDNNも入れてないような気がする．ホストはともかく少なくともWSL内には入れてない．（ホストについてはKerasの環境構築時に四苦八苦してたので結局入れたのか否かの記憶が曖昧．でもnvccコマンドが効かないのでたぶん入ってない．ドライバだけはインストールした気がする）

ちなみにWindows版のバイナリも公式からダウンロードしたそのままでhevc_nvencが使えた．

---

軽く調べてみるとpytorchはCUDAが同梱されているので個別でCUDAとか入れなくても動く的な情報（これまた初耳なんですけど…）を発見したので，ffmpegも知らない間にそうなってたのかもしれない．知らんけど．

いい時代になったもんだけど，簡単すぎて誰も解説記事を書かないせいで古い情報が目立ち続けるのは良くないですね…
プライマリーコンストラクターの注意点

## 参考
この記事は、以下の動画を参考にしています。詳しくは、動画をご覧ください。

https://youtu.be/Gvz4eSYJFWk?si=n6qhn7N1E4goeFnC

## プライマリーコンストラクター
コンストラクターに渡したオブジェクトを、他のメンバーで利用する場合、
- オブジェクトを格納するフィールドを用意
- コンストラクターで、フィールドにコンストラクター引数を代入
- 他のメンバーで、フィールドを参照する

というコードが必要になる。
```C#
// .NET 7
public class MyService
{
    private readonly IDependent _dependent; // フィールド

    public MyService(IDependent dependent)
    {
        _dependent = dependent; // フィールドにコンストラクター引数を代入
    }
    
    public void Do()
    {
        _dependent.DoWork();
    }
}
```

プライマリーコンストラクターを使えば、
- コンストラクター引数（実態はフィールド）を、他のメンバーから参照できる

ようになる。
```C#
// .NET 8
public class MyService(IDependent dependent) // プライマリーコンストラクター
{
    public void Do()
    {
        dependent.DoWork();
    }
}
```

## 注意点
プライマリーコンストラクターのコンストラクター引数は、他のメンバーから代入が可能である。
```C#
// .NET 8
public class MyService(IDependent dependent)
{
    public void Do()
    {
        dependent = null; // コンストラクター引数へ代入できる
        dependent.DoWork();
    }
}
```

書き換えられないことを保証するために、フィールドには`readonly`を付けることができるが、プライマリーコンストラクターでは`readonly`を付けることができない。

安全なコードを記述するには、 ~~従来の記述を使う必要がある。~~`readonly`なフィールドを定義し、初期値をコンストラクター引数にするとよい。（下記、@juner さんのコメントを参照してください）
ECCUBE4.2系でmake:entityコマンドを使用してCustomize配下にEntityを作成させる。[メモ]

```
bin/console make:entity Test
```

だと下記のようなエラーが出る。

```
Cannot find the entity manager for class "App\Entity\Customize"
```

下記だととりあえず動きそう。

```
bin/console make:entity Customize\\Entity\\Test　--regenerate
```

Entityファイルの作成だけだと上記で良さそうだが、実際はフィールドを追加してgetter,setterを自動生成してくれるところまでやりたい。

https://symfony.com/bundles/SymfonyMakerBundle/current/index.html#configuration
これを読むと設定ファイルを追加すれば良さそう。

下記を追加。

```config/packages/dev/maker.yaml
maker:
    root_namespace: 'Customize'
```

Test.phpにフィールドを追加

```Customize\Entity\Test.php
/**
 * @var \DateTime
 *
 * @ORM\Column(name="create_date", type="datetimetz")
 */
private $create_date;
```

```
php bin/console m:e --overwrite --regenerate
```
を実行し、

```
Enter a class or namespace to regenerate [Customize\Entity]:
 >
```

と聞かれるので、`Enter`

```Customize\Entity\Test.php
public function getCreateDate(): ?\DateTimeInterface
{
    return $this->create_date;
}

public function setCreateDate(\DateTimeInterface $create_date): self
{
    $this->create_date = $create_date;

    return $this;
}
```

上記が自動生成されたのでやりたいところまでできた気がする。

参考：https://github.com/symfony/maker-bundle/issues/133