OmniAICreator/Qiita-1.07M huggingface dataset:
ssl_error_rx_record_too_long

docker環境でapacheを立ち上げようとしてたところ
```
SSL received a record that exceeded the maximum permissible length.
```
なるエラーに遭遇

SSLなのになんか変なのがキター
ってことらしい。

以前もこんなこと起こったなぁ・・と思っていたので、
```apachectl -S```を実行したら443がいなさげ

```
# apachectl -S
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/sites-enabled/000-default-le-ssl.conf:1
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.24.0.2. Set the 'ServerName' directive globally to suppress this message
VirtualHost configuration:
*:80                   aaa.com (/etc/apache2/sites-enabled/000-default.conf:3)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex rewrite-map: using_defaults
Mutex ssl-stapling-refresh: using_defaults
Mutex ssl-stapling: using_defaults
Mutex ssl-cache: using_defaults
Mutex default: dir="/var/run/apache2/" mechanism=posixsem 
Mutex mpm-accept: using_defaults
Mutex watchdog-callback: using_defaults
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33
Group: name="www-data" id=33
```


443用の設定ファイルが無いので
/etc/apache2/sites-enabled
を覗いてみたら
 ../sites-available/000-default-le-ssl.conf
 を参照するシンボリックリンクが消えてた
ので、
自身はLet's Encripyで構築してたので
sites-available/000-default-le-ssl.confがあるのを確認して
```
ln -s ../sites-available/000-default-le-ssl.conf 000-default-le-ssl.conf
```
とした。
Dockerだとこのあたりの永続化が難しいよね
sites-availableとsites-enabledもイメージ外の外部永続できるようにマウント設定してなんとか対応

あと、一応、SSLEngine onも000-default-le-ssl.conf内に書き込んでおいた


また後日自分の記事を検索で引っ掛けることになるんだろうなぁ・・脳みそ記憶能力低くなってきた（泣）
wslで、最小のカーネルをコンパイル その13

# 概要
wslで、kernel.elfのコンパイル、やってみた。
cで、書いたカーネルで、俺言語を組み込んだ。
fizzbuzzを、打ち込んで、実行した。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/31cfc7b8-bcc2-5b0d-9d88-5e4a7e4e554d.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1ae32025-2742-c2b0-125a-484cc15fedb2.png)





以上。
IMEに日本語と繁体中文を設定し、OUTLOOK メールを作成するときに本文をメモ帳からコピペすると、句読点がおかしくなる場合がある

# 再現性あり
また、環境は日本語環境であり、Windows10である。Windows11でも確認。
管理言語は日本語。環境も日本語。
ただしIMEに繁体中文を設定し、ウィンドウズロゴキー+スペースで切り替えられるようになっている。
# 現象の正体
この現象の正体はコピペのときだけIMEが繁体中文になっていると、句読点だけフォントが繁体中文になることで句読点が真ん中に来てしまうというものである。

# 発生方法
1.メール本文をメモ帳で打つ。これは日本語。
この時の文字コードは不明

2.Outlookでメールを新規作成する
いわゆるインスペクター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/f2db3172-c8c6-1f0d-1259-a6d56ed9e7f3.png)
3.メモ帳からメール本文をコピペする
なぜか句読点がおかしくなる

# 原因
IMEの言語設定で日本語のほか、繁体中文を設定しているとき起きる。
まず句読点が真ん中にあるのは繁体中文の場合である。

https://tontotakumi.com/web-seisaku/bibo-roku/tw-marks/

それを再現できるフォントを使うと、以下のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/dc9b395a-06cc-ea72-90c4-029504515bba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/df0a44a9-e0ba-b2fd-de36-50df9d9bce27.png)
これは再現するためにわざと１行丸ごとMicorosoft JhengHei UI light設定しているが、実際は「句読点だけがフォントが変わっている」という状態になる。
行頭などにカーソルがあればMS P ゴシックなどと表示されており、フォントが変わっていることに気づきにくい。
メモ帳の状態では、日本語の句読点のように下位置に来ている。だがそこからコピペしOutlookのメール本文に張り付けると句読点だけが繁体中文になっている。また、これは件名でも発生することが分かった。

# 再現方法
Windows11だとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/e60223a2-5ce8-2f3f-7455-4dd120ca797d.png)


フォントはBIZ UDP 明朝
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/49616ffc-9ae6-446b-f0d1-9384837416cf.png)


まずメモ帳に日本語入力する。
Outlookのメール入力画面を起動
コピペする前にIMEを繁体中文に切り替える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/c1efa90b-57ab-57b0-032f-3bafd3e3f5c4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/00918919-e6b1-3219-c397-803700924d8e.png)
またこの時、メールの本文の冒頭にカーソルがあれば、Outlookの表示フォントは游ゴシック Lightである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/31f9754f-238c-6c49-3322-20a2eb17f993.png)
だが、句読点にカーソルを合わせると次のフォントになっていた。
PMingLiU
## この事象の背景
Outlookのメールのフォントの設定とメモ帳の設定より、IMEの言語設定の方が優先されていることがわかる。
特にWIndowsロゴキーとスペースは同時に押しがちなので、うっかり言語が変更されてしまう時がよくあり、筆者のような特殊な使い方をMicorosoftは想定していないものと思われる。

♯ 解決方法
メール本文全体を選択し、フォントをBIZ UD 明朝に変更する。
また、特に必要がなければIMEに多言語を設定しないほうがよい。
インボイス番号の調べ方

## 会社名でインボイス番号を調べる
&nbsp;

会社名からインボイス番号を調べる方法を紹介します。

&nbsp;
&nbsp;
### 法人番号公表サイトで会社名を入力
&nbsp;

法人番号公表サイトで会社名を検索（部分一致など可能）

https://www.houjin-bangou.nta.go.jp/

&nbsp;
&nbsp;
例として、Amazonアフィリエイトを管轄している「アマゾンジャパン合同会社」を検索します。

![インボイス番号-調べ方-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/f5a0672a-8755-afbf-3d8a-cf14ca5ab1ee.jpeg)


&nbsp;
&nbsp;

対象の法人番号に接頭辞「T」をつけたのがインボイス番号になります。
![インボイス番号-調べ方-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/16158e02-412b-546e-6124-40c5bd227a53.jpeg)

&nbsp;
&nbsp;
### 適格請求書発行事業者公表サイトで確認
&nbsp;

適格請求書発行事業者公表サイトで会社名を検索（部分一致など可能）

https://www.invoice-kohyo.nta.go.jp/

&nbsp;
&nbsp;
対象の法人番号に適格請求書発行事業者公表サイトにコピペ
![インボイス番号-調べ方-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/75fcf917-7381-844e-6c73-cb00ad5361c4.jpeg)


&nbsp;
&nbsp;
「アマゾンジャパン合同会社」のインボイス番号がわかる。
![インボイス番号-調べ方-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3336223/7aacd8a3-a8f9-7ff3-b06c-80dd10ee409e.jpeg)
&nbsp;
&nbsp;

以上！
ELB+EC2で複数台構成の環境を作成してみる（２）


ELB+EC2で複数台構成の環境を作成してみる（１）の続き


## 作成したEC2をターゲットグループにまとめる
![demo](https://gyazo.com/c317e3d433ba4c0655b9ed4e56d84db4/raw)
![demo](https://gyazo.com/1b04b1e7ee660d28538d2a3ee870c7cb/raw)
![demo](https://gyazo.com/988a86a91546663df05f7b5f8fadd51c/raw)

保留中として以下を含めるからインスタンスを追加できる
![demo](https://gyazo.com/2d0d5a94ffecb32872b5287d53c39343/raw)


## ロードバランサーを作成
・VPCやセキュリティグループはEC2インスタンスと同じものを設定
・リスナーとルーティングから先ほど作成したTGを選択する
![demo](https://gyazo.com/e5db0801278d88b5209f980688a22d69/raw)
![demo](https://gyazo.com/bbbbae942605d063b2e2b61df6eb4c30/raw)
![demo](https://gyazo.com/ab10599a036f8cdfb05444e16d49aed6/raw)


せっかくなのでそのままオートスケールまで作成してみる

## EC2インスタンスからAMIを作成
アクションからイメージを作成できそう
![demo](https://gyazo.com/e9e8a31be62960c687cc5737c5539a21/raw)
イメージ名以外は特にそんままで作成
![demo](https://gyazo.com/45b38c731120ded6e43d798030bf28e8/raw)
Amazon マシンイメージ (AMI）の部分で作成を確認できる
![demo](https://gyazo.com/3cea93503f009f51ff3c91a1703840a6/raw)

## 起動テンプレートを作成
![demo](https://gyazo.com/35f276388ec8880273a83cd154dfa781/raw)
![demo](https://gyazo.com/6051d17246d95e445879c48cc0870ee9/raw)
![demo](https://gyazo.com/5a8863667906bec266c4c3ce21c77c8c/raw)
![demo](https://gyazo.com/5e8cf0292098bd1b24c9df69aa785712/raw)
※キャプチャし忘れたがタグも新しいものを設定

## オートスケールを作成
Tgや起動テンプレートなどは今回作成したものをそれぞれ設定
![demo](https://gyazo.com/a6008ceba5e7af85e056033302205b33/raw)
![demo](https://gyazo.com/d7a4266c3baba97cedb5d0679f20b6bb/raw)
![demo](https://gyazo.com/d0e27ef4ef3f23b5db9104e4af0575ea/raw)
![demo](https://gyazo.com/102a2a46b7fefe76907aaf7ddc0b5c81/raw)

下記画面で負荷や時間に応じて、オートスケールを発動させる
![demo](https://gyazo.com/8cf819f2c64c1628b8b53dfff79402b3/raw)
![demo](https://gyazo.com/102a2a46b7fefe76907aaf7ddc0b5c81/raw)
ELB+EC2で複数台構成の環境を作成してみる（１）

# 流れ
1. VPCを作成する
1. サブネットを作成する
1. インターネットゲートウェイとルートテーブルを利用して、サブネットからインターネットにアクセスできるようにする
1. サブネット内にEC2を複数台配置する
1. 上記のEC2をターゲットグループにまとめる
1. ELBを作成して上記のターゲットグループを設定する


## VPCを作成する

![demo](https://gyazo.com/a513dcb3629186880d88505abf9cba48/raw)

IPV4 CIDRは『10.0.0.0/24』にしておく


## サブネットを作成する

VPC内に2つのサブネットを作成する（AZも異なるものにしておく）

サブネット1（10.0.0.0/25）
![demo](https://gyazo.com/b4b573cd837bd639564946a76aabbb4c/raw)

サブネット2（10.0.0.128/25）
![demo](https://gyazo.com/7692e6bcb8111cbdc8532c997524cda7/raw)


## インターネットゲートウェイを作成して、VPCにアタッチする

作成
![demo](https://gyazo.com/6f0d802d7335b49798c7a68c01219e5a/raw)

アタッチ
![demo](https://gyazo.com/dc9e12b0a47ade4282c022ab6d28100f/raw)


## ルートテーブルを作成する
![demo](https://gyazo.com/9bd02b91fe50d156a4514c3f8eb69ca9/raw)
ルートの編集からインターネットゲートウェイのルートを追加する
![demo](https://gyazo.com/1e8e4fe267b7cebc89441771436d9517/raw)
今回作成したサブネットを明示的なサブネットの関連付けにつけておく
![demo](https://gyazo.com/55138d7e5f78d29bfc643a128288f4aa/raw)


## EC2を作成する

名前やキーなどは任意なものを設定して、
ネットワーク設定の部分を下記のようにする
![demo](https://gyazo.com/f538e4c7aef2176345075dac66ecd38c/raw)
![demo](https://gyazo.com/cdfe03fef0dfc3ea46aa83a83ff7f1eb/raw)



参考記事
https://recipe.kc-cloud.jp/archives/35/
https://dev.classmethod.jp/articles/creation_vpc_ec2_for_beginner_1/#toc-11
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/subnet-sizing.html
VSCodeのCall Hierachy機能を使ってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600486/a4d64cd8-90d6-c67b-21c1-542afc0855fb.png)

# Extensionの説明

```
The extension generates C call hierarchy with your GTAGS. It is recommended to use it with the extension C/C++ GNU Global.

Features
This extension provides a call hierachy for C code.

Data based on GNU Global.
Register to VS Code native "Show Call Hierachy" command.
Compatible with other extension using GTAGS.
Requirements
You need to ensure glboal are installed on your device.

You have to first generate GTAGS, GPATH and GRTAGS via gtags command.

Usage
Prepare your Gtag database via gtags command.
Right click the function you want to trace and click "Show Call Hierarchy".
Trace the callers in "References" pane.
```

```
機能
この拡張機能は、Cコードのコール階層を提供します。

データはGNU Globalに基づいています。
VS Codeネイティブの "Show Call Hierachy "コマンドに登録。
GTAGSを使用する他のエクステンションと互換性があります。
必要条件
お使いのデバイスにglboalがインストールされていることを確認する必要があります。

gtagsコマンドでGTAGS、GPATH、GRTAGSを生成する必要があります。

使用方法
gtagsコマンドでGtagデータベースを準備します。
トレースしたい関数を右クリックし、"Show Call Hierarchy "をクリックします。
References "ペインで呼び出し元をトレースする。
```

# Requirement

glboalのインストール

参照: https://qiita.com/miyagaw61/items/b0603517d6a37b59bc14

sudo apt install exuberant-ctags -y

globalはソースのみしか配布されていない
https://ftp.gnu.org/pub/gnu/global/ からソースをダウンロード&自分でビルド
ビルド方法はINSTALLに書かれていた。

```
(base) mozaki@yoshitsune:~/000_DUSTBOX/global-6.6.12$ ./configure
(base) mozaki@yoshitsune:~/000_DUSTBOX/global-6.6.12$ make
(base) mozaki@yoshitsune:~/000_DUSTBOX/global-6.6.12$ sudo make install
```

globalの使い方
https://twinbird-htn.hatenablog.com/entry/2015/12/03/002153



- Usage
  - Prepare your Gtag database via gtags command. (Requirementと同じ??)
  - Right click the function you want to trace and click "Show Call Hierarchy".
  - Trace the callers in "References" pane.
JSLinux の FreeDOS にファイルを持ち込む

# 背景

[JSLinux](https://bellard.org/jslinux/) では、ブラウザ上で FreeDOS やその他の OS を動かすことができる。
この FreeDOS を利用し、書いたプログラムの実験をしたくなることがある。
しかし、JSLinux の Upload files 機能は [Linux VMs でしか動かないとされており](https://bellard.org/jslinux/faq.html)、FreeDOS では使えなそうである。
そこで、ファイルのデータを簡単に持ち込む方法を探した。

# 目的

テスト用の小規模なプログラムのデータ (数バイト～1KiB程度のバイナリ) を JSLinux 上の FreeDOS に簡単に持ち込む。

# 方法

今回紹介する方法では、以下のソフトウェアを用いる。

* FreeDOS 内部
  * uHex
  * Perl
* 外部
  * [CyberChef](https://gchq.github.io/CyberChef/)
  * [キーボードシミュレータ.NET](https://www.inasoft.org/icountt.html#autokeybn)

## 持ち込むデータを入力用に変換する

[CyberChef](https://gchq.github.io/CyberChef/) を用いて、持ち込むデータをキーボードシミュレータ.NET で uHex に入力する用のデータに変換する。
すなわち、以下の変換を行う。

1. データを十六進表現に変換する
2. 各バイトの間に `[VK_RIGHT]` を入れる

[To Hex, Find / Replace - CyberChef](https://gchq.github.io/CyberChef/#recipe=To_Hex%28%27Space%27,0%29Find_/_Replace%28%7B%27option%27:%27Simple%20string%27,%27string%27:%27%20%27%7D,%27%5BVK_RIGHT%5D%27,true,false,true,false%29)

## 持ち込むデータと同じサイズのファイルを作成する

次の手順で用いる uHex (バイナリエディタ) では、既存のバイトの値の変更はできるが、筆者は今のところバイトの追加や削除 (ファイルサイズの変更) を行う方法を見つけられていない。
そこで、FreeDOS 上 (C ドライブのルート) で以下のコマンドを実行し、持ち込むデータと同じサイズのファイルを作成する。

```
devel\perl\bin\perl -e "print 0 x ファイルサイズ;" > 作成するファイル名
```

:::note
日本語キーボードでは、`\` は `]` (む) キー、`"` は `Shift+:` (け) キーで入力できるようである。
ここで用いる他の文字は通常通り入力できるはずである。
:::

:::note warn
`x` の前後には必ず空白を入れること。
さもないと、`0x` から始まる十六進数として解釈されるなど、失敗の原因になる。
:::

持ち込むデータのファイルサイズは、CyberChef で入力として用いる際に表示される。
たとえば、256 バイトのファイル `A.TXT` を作成するには、以下のようにする。

```
devel\perl\bin\perl -e "print 0 x 256;" > a.txt
```

`-e` オプションを用いることで、コマンドラインで指定した Perl のプログラムを実行する。
実行するプログラムは、文字列を指定した回数繰り返した文字列を求める演算子 `x` を用いて、文字 `0` をファイルサイズの分だけ繰り返した文字列を生成・出力するものである。
この出力をリダイレクトすることで、ファイルを作成する。

## 持ち込むデータを流し込む

続いて、FreeDOS (C ドライブのルート) 上で以下のコマンドを実行する。

```
uhex 作成するファイル名
```

すると、うまくいけば uHex が起動し、以下のような画面になるはずである。

![uHex を起動した画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/e35416ca-d29f-5cf1-cf2b-1a01901e5ce3.png)

ここに、[キーボードシミュレータ.NET](https://www.inasoft.org/icountt.html#autokeybn) を用いて、持ち込むファイルのデータを流し込む。
入力モードは「キーボードシミュレートモード」にする。

入力欄に先ほど CyberChef で変換したファイルデータをコピペする。
これは、たとえば

```
74[VK_RIGHT]65[VK_RIGHT]73[VK_RIGHT]74
```

のような形式になっているはずである。

入力文字の間隔を適切に設定する。筆者の環境で試したところ、100 ミリ秒に設定して 1KiB のデータを欠けることなく流し込むことができた。

「入力開始」ボタンを押し、入力が始まるまでの間に JSLinux に対する入力ができる状態にする。
入力が終わるまで待つ。

入力が完了したら、`Alt+S` を押してファイルを保存し、`Esc` を押して uHex を終了する。

# 結論

uHex の「ファイルサイズを増やす方法がわからない」という欠点を、Perl を用いて作りたいサイズのファイルをあらかじめ作っておくことにより補うことで、JSLinux の FreeDOS に小規模なファイルを持ち込みやすくなった。
「現代数理統計学の基礎」演習問題解法メモ　第6章問14～16

これで第6章を終わります。
とにかく解答を作成することに注力を尽くしてきましたが、いざ試験となると時間との戦いのようですね。そうなると、いかに楽な解き方を選択するかという次のステージになりますね。
![第6章問14 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/c870f99e-c394-4272-2b50-181fca87ccf2.jpeg)
![第6章問14 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/aa9e0cf9-f80b-6804-7e8b-884d5686554b.jpeg)
![第6章問14 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/5d389211-be2e-572f-f93f-8e8ac07ed66c.jpeg)
![第6章問15 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/a5ca4006-0770-5bd9-b385-9fb338228a5e.jpeg)
![第6章問15 P2 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/a094c833-6816-b473-cc5c-6399b9bed303.jpeg)
![第6章問16 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/3c808ea8-7e30-5768-7938-eb7735fef520.jpeg)
![第6章問16 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/f6fa9588-5abc-d5bf-b3da-fdd08d65a8a4.jpeg)
![第6章問16 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/baaff29f-2214-416b-f555-093a1240a758.jpeg)
PHP セキュリティ攻撃・対策

# ①XSS (Cross Site Scripting)
:::note info
#### 概要
- 入力フォームにJavaScriptなどのScriptを仕込むことができる
:::

:::note warn
#### 対策
- 各formにサニタイズの処理を行う。
- サニタイズ　＝　特殊な文字を別の文字に置き換えること。
　　　　　　　　消毒、無害化、エスケープとも言う。
- 関数「htmlspecialchars」を使用する
:::

# ②クリックジャッキング
:::note info
#### 概要
- 通常のボタン上に、悪意のあるボタンを透明にして設置する
:::

:::note warn
#### 対策
- サーバーまたはPHP上に「X-FRAME-OPSIONS:DESY」を記述する
- PHPの場合は、header（'X-FRAME-OPSIONS:DESY'）を記述
:::

# ③CSRF (Cross Site Request Forgeries)
:::note info
#### 概要
- シーサーフと読む
- 「formが存在するページ」をForgeries(偽造)し、そこから悪意のあるページへ飛ばしたり、データを抜き取ろうとする手法
:::

:::note warn
#### 対策
- ランディングページ→登録ページ→登録完了ページの間でトークンを付加し、トークンを持つリクエストのみ処理できるようにする
- 具体的には、セッション（$_SESSION）を使用する
- GET,POST → 値の引き継ぎは、「一度きり」
- SESSION → 値の引き継ぎは、「消すまで残る」
:::

***

# ④SQLインジェクション
:::note info
#### 概要
- formにSQLを記載し、送信することでデータベース内のデータを取得、破壊する手法
:::

:::note warn
#### 対策
- プレスホルダーを使用して、バインドする（　->prepare, ->bind　)
:::

***
Excel VBA 和暦を設定したセルに日付を代入する場合、１年少なく表示される場合がある

# 再現困難
再現は困難だが、修復はすべてクリアで書式をすべてクリアし、再度設定すると、いったん解消された。

# セル表示形式
`[$-ja-JP]ggge"年"m"月"d"日"`
# 書式
横 均等割り付け（インデント０）
縦 中央揃え

# VBA

```vb
activecell = #03/15/2024#
```

本来はべつのセルに入っている日付を代入する

# 通常の結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/6f40f28d-9db3-1d5e-2c02-bacad64d3c72.png)
令和6年3月15日

# 実際に起きた結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/38adf403-7e87-894b-f2c6-fd0cb1f0c1ad.png)
令和5年3月15日

なぜか１年少なく表示された。
しかし中身は`2024/3/15`つまり令和6年3月15日である。

# 解決方法（上級者向け）

 1. 現在設定されている書式、セル幅、セルの高さ、フォント、フォントのサイズなど、必要な書式をメモする。
 2. 当然条件付き書式のようなものも記録する
 3. すべてクリアによって書式を消去
 4. 記録した書式設定等を再度設定する

# 原因
　そもそも１年少なく表示させる設定が思いつかない。
  とにかく設定を確認してマクロを実行するだけではなく、実際の表示結果を確認する必要もあるということが分かった。
Javascript 配列・連想配列

Javascript の勉強した内容のメモ書きをしていく

配列の場合、インデックス番号指定でデータを取得する。

```js:配列
const dog = [
    '秋田犬',
    'ポメラニアン',
];

console.log(dog[1]);
```


連想配列の場合、メンバー毎にドット(`.`)で区切り、欲しいデータを取得する。

```js:連想配列
const dog = {
    '秋田犬':{
        'color':'茶色',
        'size':'big'
    },
    'ポメラニアン':{
        'color':'茶色',
        'size':'mini'
    }
};

console.log(dog.ポメラニアン.size);   
```
imgIXのAI搭載の新機能

## はじめに

`imgIX` は、画像をオンデマンドで加工・最適化できるクラウドサービスです。開発者が直面する一般的な課題の一つに、アプリケーション内で扱う画像の管理と最適化があります。これらの画像は通常、`Amazon S3`、`Google Cloud Storage`、`Cloudflare R2` などのオブジェクトストレージに保存されます。`imgIX` は、これらのストレージサービスに保存された画像に対し、URLパラメータを用いて簡単にロゴの追加、テキストの挿入、サイズ変更、形状の調整、フォーマットの変更など、多岐にわたる加工を行うことができます。

`imgIX` は、オブジェクトストレージと連携し、画像をオンデマンドで処理するようなサービスとしては世界でもっとも使われてるようです。日本においては `さくらのクラウド` が提供する `ImageFlux` という類似のサービスがありますが、今回は `imgIX` が `AI` 搭載の新機能を出してるということなので、そちらをまとめます。

### Generative Fill

従来、アスペクト比を `1:1` から `16:9` に変更する際には、画像の一部が欠けてしまう問題がありました。しかし、`imgIX` の `Generative Fill` 機能を使用することで、`AI` が不足している部分を自動的に生成し、自然な形で画像を補完します。これにより、画像のアスペクト比を変更しても、品質を損なうことなく理想的なビジュアルを実現できます。

https://www.youtube.com/watch?v=NzKkFnSqpYM

### Super Resolution

解像度が低い画像を扱う際、`imgIX` の `Super Resolution` 機能がその解像度を最大4倍まで向上させることが可能です。この技術により、荒くピクセル化された画像も、細部まで鮮明に再現されます。

https://www.youtube.com/watch?v=KIJsaXHAAbg

### Background Removal

`Background Removal` 機能は、画像から物体を自動的に検出し、背景を除去することができます。この機能により、商品画像やポートレートの背景を簡単にクリアにし、目的に合わせた画像加工が可能になります。

https://www.youtube.com/watch?v=7N6gdcUk9NM

### Auto-Tagging

`Auto-Tagging` 機能では、画像内容を `AI` が解析し、適切なタグを自動で付与します。これにより、大量の画像を効率的に管理し、必要な画像を瞬時に検索できるようになります。

https://www.imgix.com/solutions/asset-management

## 参照

https://www.imgix.com/solutions/ai-features

https://imageflux.sakura.ad.jp/image/?gad_source=1&gclid=CjwKCAjw48-vBhBbEiwAzqrZVKo6WTmOknqxxl_8A4f5V9nFnBALgqKjejizL3zYew_Yf9hiWeNj3BoCkn4QAvD_BwE

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
Next.jsをGitHub挟んでCloudflare Pagesにデプロイする

# はじめに
色々詰まったので解決までかかった内容を全て書いておきます。Cloudflare C3を使ってプロジェクトを構築し、あとからGitHubを挟んだデプロイに変更してみます。
詳しくは理解していないので間違っている点あるかもしれないです。

https://developers.cloudflare.com/pages/framework-guides/nextjs/deploy-a-nextjs-site/

# 環境
* Ubuntu 22.04
* VirtualBox

（PC自体はWindows 11を使用）

まず最初にPowershellを試して、次にWSLを使ってみたがどちらも失敗してしまった。WSLについてはUbuntuを使ったが、```npm create```を行うとCMD.exeが起動してしまい、なんやかんやよくわからなかった。
ということでVirtualBoxにした。関連するエラーは以下のリンクに示す。

https://stackoverflow.com/questions/77152589/cannot-find-npm-on-appdata-roaming

https://ginpen.com/2020/10/02/close-vscode-when-npm-isntall-failed/

# Ubuntuを入れる
VirtualBoxをインストールして、UbuntuのISOでインストール。

# 環境構築
## apt
suでroot権限を得て、諸々インストールする。
```bash
su

sudo apt update
sudo apt upgrade
sudo apt install nodejs
sudo apt install npm
```

## nodeのバージョンアップ
nodeはv12.22.9、npmは8.5.1と古いのでこれで実行するとエラーを吐くので更新を行う。

https://qiita.com/cointoss1973/items/c000c4f84ae4b0c166b5

```
sudo apt install nodejs npm
sudo npm install n -g

sudo n lts
exit
```

# プロジェクトを作ってみる
```:bash
npm create cloudflare@latest my-next-app -- --framework=next
```
後は画面の指示通りに、とりあえずEnterでOK。

deployするか聞かれたときはyesにすると、GitHubを使わずCloudflare C3でダイレクトでデプロイが行われる。一度これでやってみて動作するかを見てみると初めての時はやりやすい気がする。
最初からGitHubでやるという方はNoにしてもできるかも。

てかなんならC3を使わなくてもいけそうな気もするが試していない。C3を使わなくていいならそもそもPowershellで完結できる（はじめにの項で書いた通りのエラーを回避できる）のでやってみたい。

## エラーが出る場合
```Cannot find module 'semver'```というエラーが出たので、以下の記事をもとに解決した。

https://qiita.com/nanakochi123456/questions/0e42c35f80490fbd46f0

```:bash
hash -r
```

# GitHubに変える
## リポジトリを作る
先ほど作成したプロジェクトはすでにGitで管理されているのでこれをプッシュする。

```
git branch -M main
git remote add origin https://github.com/<your-gh-username>/<repository-name>
git push -u origin main
```

ちなみにプッシュは認証を行う必要があるが、GitHubへのログインはパスワード認証は推奨されていないし多分弾かれる。
初心者だと```gh```を使うと分かりやすい。本当は他の方法も理解しておいた方がいい気がする、SSHとか。

https://docs.github.com/ja/github-cli/github-cli/about-github-cli

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/about-authentication-to-github

```
su
sudo apt install gh
exit

gh auth login
```

後は画面の指示に従うとできる。ブラウザを起動して認証、を選ぶと楽にできる。

# Cloudflare Pagesの設定
まずPagesでプロジェクトを作成する。「Pages > プロジェクトを作成 > Gitに接続」。プッシュした先ほどのリポジトリを選択。
次の画面で以下の設定を行う。

| キー | 値 |
|:-:|:-:|
| Production branch | main |
| Build command | npx @cloudflare/next-on-pages@1 |
| Build directory | .vercel/output/static |

これでプロジェクトを作るが、この時点ではデプロイは行われてもページの表示は失敗してしまう。```nodejs_compat```。これについては以下のページで述べられていた。

https://zenn.dev/microcms/articles/1b4331eca6e512

> Pagesのプロジェクトから、「設定 > Functions > 互換性フラグ」にてnodejs_compatを追加して保存します。

まさにこれが抜けていた。追加したらデプロイの再試行。これで表示に成功した。

雑記です。これからまた書き足りない部分を追加しようと思います。
【Xcode15】@Bindingを使ったViewの#Previewを表示する方法【SwiftUI】

# 問題のコード
@Bindingを使用したViewのプレビューを作成したいとき、#Previewの下で@Stateを付けた変数を定義して渡す必要があることは知られている。

```swift
#Preview {
    @State var hoge = "hoge"
    SecondView(foo: hoge)
}
```

しかし、それだけではこのような警告が表示されてしまう。

::: note warn
Result of 'SecondView' initializer is unused
:::

色々調べて試してみたところ、以下の方法で解決しました。

# 【解決】returnを付ける

```swift
#Preview {
    @State var hoge = "hoge"
    return SecondView(foo: hoge)
}
```
SecondViewのイニシャライザが使われていないという警告が出ていたため、このようにreturnを付けることで解決しました。

詳しい内容については私もまだ理解できていないため、ご存知の方がいれば教えていただきたいです。

# 参考
https://stackoverflow.com/questions/76468134/how-to-create-a-swiftui-preview-in-xcode-15-for-a-view-with-a-binding
paint-order が Chrome で実装されるので、HTML+CSSで縁取り文字

もともとSVGではできていましたが、Chrome123がHTMLでの`paint-order`に対応するようなので、プラウザ互換を気にせずに使えるようになりそうです。白系の背景に白文字を乗せるときとかに重宝します。

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="KKYNzXO" data-user="lhankor_mhy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lhankor_mhy/pen/KKYNzXO">
  paint-order</a> by lhankor_mhy (<a href="https://codepen.io/lhankor_mhy">@lhankor_mhy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

上の文字が`paint-order`の指定なし、下の文字が`paint-order: stroke`です。

```css
div{
  color: white;
  -webkit-text-stroke: #00000066 4px;
}
div+div{
  paint-order: stroke;  
}
```

Illustrator とかを使ってれば、あーあれね、という感じになるかと思いますが、線を塗りの後ろに回すやり方です。たぶん、Illustrator9 あたりのアピアランスとかで使えるようになった機能だと思うんですが、それまでは同じ文字を2つ書いてレイヤーで重ねたような記憶があります。なつい。
TypeScript 基礎とプロジェクト設定

>💡 主题と焦点：TypeScriptの基本概念、型システムの利点、およびTypeScriptプロジェクトの設定方法（`tsconfig.json`の設定を含む）について紹介します。

- [1 紹介](#紹介)
- [2 どうしてTypeScript](#どうしてTypeScript)
- [3 エンバイロメント設置](#エンバイロメント設置)
    - [3.1 インストール](#インストール)
    - [3.2 コーディング](#コーディング)
    - [3.3 コンパイル](#コンパイル)
    - [3.4 コード実行](#コード実行)
# 紹介
現代のWeb開発において、JavaScriptは不可欠な部分となっています。しかし、プロジェクトの規模が拡大するにつれて、JavaScriptの弱い型付けと柔軟性が時に見つけにくいバグや複雑なメンテナンス問題を引き起こすことがあります。これはTypeScriptが生まれた背景です。

TypeScriptは、Microsoftによって開発されたオープンソースの言語であり、JavaScriptの基盤の上にオプショナルな静的型宣言を追加します。強力な型システムとコンパイル時の型チェックを提供することで、TypeScriptは開発者が多くの一般的なエラーを捕捉し、コードの品質と保守性を向上させるのに役立ちます。

# どうしてTypeScript
- 型安全
    TypeScriptの最大の利点は、その強力な型システムにあります。これには、列挙型、インターフェース、クラスなどのサポートが含まれます
- ツールサポート
    型システムを利用して、TypeScriptはより良い自動補完、ナビゲーション、リファクタリング機能を提供します
- コミュニティ
    TypeScriptは広範なコミュニティのサポートを受けており、多くの人気のあるフレームワークやライブラリに採用されています

# エンバイロメント設置
## インストール
まずは、開発環境にTypeScriptをインストールする必要がありです。`npm`は`Node.js`のパッケージ管理ツールであり、それを通じて、TypeScriptのコンパイル器(`tsc`)がインストールできます。

以下のコマンドを実行してTypeScriptをインストールします。

```bash
npm install -g typescript
```

インストールした後、成功するかどうかのは`tsc --version`というコマンドを実行して検証できます。

## コーディング
1. プロジェクトディレクトリの作成：適切な場所に新しいフォルダを作成します。例えば、`typescript-demo`という名前で。

2. プロジェクトの初期化：プロジェクトフォルダ内で、ターミナルまたはコマンドラインインターフェースを開き、`npm init -y`を実行します。これにより、デフォルトの`package.json`ファイルが作成されます。
3. 新しいファイル「hello.ts」を作成し、以下のTypeScriptコードを追加します
```TypeScript
function greet(name: string) {
    return `Hello, ${name}!`;
}

console.log(greet("world"));
```
このコードは、`sayHello` 関数を定義しています。この関数は1つの文字列型のパラメーター `name` を取り、コンソールに挨拶文を出力します

## コンパイル
TypeScriptのコードを実行するためには、まずJavaScriptにコンパイルしなければなりません。「hello.js」ファイルを含まれるディレクトリで、以下のコマンドを実行します。
```bash
tsc hello.ts
```
これにより、コンパイルされたJavaScriptコードを含む新しい`hello.js`ファイルが生成されます。

## コード実行
最後に、Node.jsを使用してコンパイルされたJavaScriptファイルを実行します：

```bash
node hello.js
```
コンソールには"Hello, world!"という出力が表示されるはずです。

# tsconfig.json
TypeScriptのコンソールプロセスをより柔軟に制御するために、プルジェクトのルートディレクトリに`tsconfig.json`ファイルを作成することが一般的です。これファイルでは、コンパイルオプションを定義し、プロジェクトに含めるファイルを指定することができます。

`tsconfig.json`ファイルを作成し、以下の内容を書く
```json
{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "strict": true
    }
}
```
この設定は、コンパイラがTypeScriptを`ES5`標準に準拠するJavaScriptにコンパイルし、`CommonJS`モジュールを使用するように指定しています。`"strict": true`は、すべての厳格な型チェックオプションを有効にし、より安全なコードを書くのに役立ちます。

# サマリー
以上のプロセスを通じて、TypeScriptの開発環境を設置し、簡単なHello World機能を実装しました。
Paiza[構造体の更新 PHP編]

解いたので記録として載せておく。
最適解かどうかはわからない。

https://paiza.jp/works/mondai/class_primer/class_primer__change

```PHP:result.php
$input_line = fgets(STDIN);
$users = [];
$update_list = [];
$first_line = explode(" ", $input_line);
$people_num = $first_line[0];
$update_num = $first_line[1];
$sum_line = $first_line[0] + $first_line[1];

for ($i = 0; $i < $sum_line; $i++) {
    $s = fgets(STDIN);
    $s = str_replace(array("\r\n","\r","\n"), '', $s);
    $s = explode(" ", $s);

    if($people_num > $i){
        $users[$i]["nickname"] = $s[0];
        $users[$i]["old"] = $s[1];
        $users[$i]["birth"] = $s[2];
        $users[$i]["state"] = $s[3];
    }
    if($update_num <= $i) {
        $update_list[$i]["user_num"] = $s[0];
        $update_list[$i]["new_name"] = $s[1];
    }
}

foreach ($users as $user_i => $user_val){
    foreach ($update_list as $up_i => $up_val){
        if($up_val["user_num"] == $user_i + 1){
            $users[$user_i]["nickname"] = $up_val["new_name"];
        }
    }
    $result = implode(' ', $users[$user_i]);
    echo $result . "\n";
}
```
よく使うTerraformコマンド

# 1.開発環境の初期化
```
terraform init
```
・terraformの開発環境をセットアップする。
・開発を始めるときに必ず実行する。
・tfstateファイルの保存場所をS3に変更する場合再実行する。

# 2.ソースコードのフォーマット
```
terraform fmt
```
・ソースコードを綺麗にフォーマットする。
・インデントの位置などを揃えてくれる。（Eclipseのフォーマッターと同じ）
・すべてのソースファイルをまとめてフォーマットしてくれる。
・fmt、plan、apply -auto-approveはセットで頻繁に使う。

# 3.実行結果の確認
```
terraform plan
```
・terraform apply実行で構築される結果を事前に確認できる。
・ソース修正後に実行すると修正による変更内容を確認できる。
・fmt、plan、apply -auto-approveはセットで頻繁に使う。

# 4.実行
```
terraform apply
```
・ソースコードの内容で環境構築される。
・-auto-approveを引数指定しない場合、yesを入力する。
　⇒本番環境の構築など慎重な作業が必要な時は外した方が良さそう。
・fmt、plan、applyはセットで頻繁に使う。
# 5.元に戻す
```
terraform destroy
```
・applyで構築した環境を元に戻すことができる。
・-auto-approveを引数指定しない場合、yesを入力する

# 6.リソース一覧確認
```
terraform state list
```
・terraformが管理しているリソースを一覧表示する。
・tfstateファイルを見るのが面倒な時に使う。

# 7.リソース確認
```
terraform show
```
・terraformが管理しているリソースを表示する。
・tfstateファイルを見るのが面倒な時に使う。

以上、私が開発中によく使うTerraformコマンドでした。
開発をしていると大体以下の流れになります。

①ソースを修正する。
②terraform fmt でフォーマットする。
③terraform plan で実行結果を確認する。
④terraform apply -auto-approve で実行する。
⑤マネジメントコンソールで構築された結果を確認する。（AWSの場合）

以上
EC2 リザーブドインスタンスを日時指定して購入する方法


EC2 のリザーブドインスタンスを購入または更新したい日付や時間が、業務時間外（夜間・休日）で困ったことはありませんか？

EC2 のリザーブドインスタンスは指定した日付や時間での購入が可能なので、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ri-market-concepts-buying.html#ri-queued-purchase)をもとに画面キャプチャを付けて説明します。[1] 
最後には誤って購入した際のキャンセル方法も説明します。

ただし、残念ながら 2024年3月16日 現在は、RDS の購入予約は対応していません。将来のアップデートに期待しましょう。


## 購入してみた（最後にキャンセル）

EC2 のマネジメントコンソールにログインします。画面左のメニューよりリ`ザーブドインスタンス`を選択します。

![RI購入0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/918639c5-6edc-9df0-75bc-6788f7cbbd97.png)

`リザーブドインスタンスの購入`をクリックします。

![RI購入1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/c150a12c-4209-64ce-c0ef-41928a9b1b75.png)

条件を指定して購入したいインスタンスを検索します。今回は以下を指定します。

- プラットフォーム：Linux/UNIX
- テナンシー：デフォルト
- 提供クラス：スタンダード
- インスタンスタイプ：t3.micro
- 期間：1 年（1 ～ 12 か月）
- お支払方法：全前払い

![RI購入2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/78cbfbb5-b2fe-3ece-8426-73b02ff70bc2.png)

`希望数量`を指定することが出来るので、必要な数を入力してください。
購入を希望するインスタンスであることを確認し`カートに入れる`をクリックします。

![RI購入3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/42e9a10f-6aa9-7409-0afb-846875932d9b.png)

合計金額を確認し`カートを見る`をクリックします。

![RI購入4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/6f19276e-629f-a481-dac1-8ce967d9d37a.png)

`以下を注文`列の`現在`をクリックします。

![RI購入5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/65a2bccc-da15-0fb1-bcf5-884c0e3cd5d9.png)

カレンダーが表示されるので、購入したい日を選択します。

![RI購入6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/287b1d1a-a142-6e21-5f3b-55f90fced66c.png)

:::note info
時刻指定は AWS CLI のみで可能です。
```
--purchase-time "2020-12-01T00:00:00Z"
```
:::

あらためてカートの内容を確認をして、`すべて注文`をクリックします。

![RI購入7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/591cce9f-c7b9-4889-49e4-760b8b602e83.png)

注文が確定された画面です。閉じてください。

![RI購入8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/1a8b192c-e19f-65de-974d-19d9754ea9be.png)

キューに入っていることを確認できます。

![RI購入9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/5cb7dac2-48ad-605d-92f9-0299c1410ece.png)

インスタンスの詳細を表示できます。購入対象が正しかったか不安になった方（そうでない方も必ず）は確認しましょう。

![RI購入10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/ec9a63c4-a427-cd89-772a-0ef48a15c944.png)

もし、インスタンスを誤って購入した場合は対象のインスタンスを選択し、
アクション > キューに入っているリザーブドインスタンスを削除 を選択してください。

![RI購入11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/f1a01689-2aee-f5f3-6616-15a6ea333a72.png)

`削除`をクリックすることで、リザーブドインスタンスを削除できます。

![RI購入12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/55f3b1bd-d547-a138-229d-a31271db8e42.png)

`キューに入り削除されました`を確認してください。

![RI購入13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/7a41cff7-123c-cb20-bce5-49ef85c3b849.png)


## 参考資料
[1] [リザーブドインスタンスの購入 - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ri-market-concepts-buying.html#ri-queued-purchase)
恋愛したい系エンジニアがブログを作ってみた


こんにちは！
素直に恋愛したいだけなのに、圧倒的に出会いの母数がない…
そんな悩みから、恋人・恋人候補を作るべくメディア運営を開始することにした旨と、技術的な部分について少しばかりご紹介させて頂きます。

## 経緯

僕自身はそもそも二十歳まで全く恋愛事に関心がなかったのです。中高で気にしてくれた数少ない子達にも悪気もなく素っ気なくして、
今では自身の**人間的成長の不足**がいたたまれなく、申し訳なかったよなあと思い返すことができます。

わりと長く付き合いがあった彼女がいまして、その子との関わりの末、まあ普通に合わないなって別れたんですが、自身が**恋愛体質**なんじゃねと気づくこととなりました。

それからは、コーディングスタイルは「利益駆動型」から「恋愛駆動型」へと切り替わり、こんな一見して変なことも挑戦するようになった次第です。

恋愛（＝異性との深い人付き合い）は普通の人間関係・友好関係では触れることのできない領域まで**対人コミュニケーションの面白さ**を引き出してくれます。

より深い付き合いはより深い**認知・学び**の獲得に繋がります。
僕は自己成長が大好きなので、新しい関係により自身の認知がアップデートされることへの期待値は大きく、
それはプログラマーとしての度量を含めた**広域のスキルセットを強化してくれる価値**であると確信しています。

## 技術的な話

面白くない話は程々にして、技術の話をします。

と言っても普通の技術を普通に使っているだけだから話せることがない…😓

ああ、強いていうなら、このブログメディアは**自宅サーバー**で動かしています。僕んちのUbuntuパソコンです。
Vercelとか価格モデルが好きじゃないんだよね。（あとデプロイ遅そう。）

- Ubuntu
- Nginx 
- Docker (docker-compose)

VPSにSSHポートフォワーディングしてゲートウェイ的に活用。
SSH接続の恒久化のためにtmuxとautosshを使っています。

あとはNext.jsなので、もちろんフロントエンド系です。

- JavaScript / TypeScript
- Webpack
- Node.js
- Next.js / React.js
- Tailwind CSS / Styled-components / MDX

モバイル上でのデザイン調整やJSデバッグには、Chromeのremote debugging（`chrome://inspect/#devices`）の活用がお勧め。
「なんか実機のスマフォンだとデザインおかしいんよなあ」って詰まった時に手作業が捗ります。

同じくモバイルのデザイン調整はsocatでポートのフォークしてスマホから開発サーバーにアクセスできるようにすると、ライブリロード/ホットリロードが効くのでブラウザ表示のレスポンシブ最適化にお勧めです。

- Android Chrome / Kiwi / Firefox
- iPhone Safari
- Scrcpy
- Chrome remote debugging protocol

サムネイル画像はコマンドラインツールのimagemagickから自動生成されるようにしています。
contentlayerのソースコードをnode_modulesの中から書き換え、ビルド時に画像パスがMDXのフロントマッターに自動で設定されるようにしました。

- Shell / Bash (Zsh)
- imagemagick

開発・デバッグにはVSCodeを使用。

- VSCode
- Git / Gitlens Pro
- Github Copilot
- ESLint

普段からウェブアプリ運用してるので仮想化とファイアウォールは元々。

- kvm
- pfsense (dmz / vlan)

ちなみに当該パソコンのスペックはミドルロースペックくらいだと思います。
開発環境とデプロイ環境（docker-compose）一緒なので、メモリは20gbくらいVSCodeに取られてます（笑）

（普段はWindows 10の別PCを使用。LinuxはSSHやVSCodeのリモートデバッグが主です。）

- Intel i3 10th
- Ram 32gb
- Nvidia GTX 1650
- SSD 480gb

Next.jsのアプリくらいだったら最適化上手くすれば100インスタンスくらいなら動かせると思います。

## UI ／ デザイン

ツイートのような投稿のコンポーネントを作り記事中に設置しています。▼

## よくありそうな質問

Q: マッチングアプリでよくない？

A: 女性の特性からして、マッチングアプリに登録（＝とても面倒。ナンパされるよりは面倒。）するほどまでファネルを通過している方は、レア。やばい方かもしれないし、面白い方かもしれないけど、**母数が少なすぎて非能率的**。男女比と業者率がデータ。

Q: 会えた人いますか？

A: 連絡くれる人も会えた人もまだいないので**最初の一人になってください**。（別に男性でも友達やビジネスライク関係としてok。）

## 総括

長い記事にお付き合い頂きありがとうございます。

「変な記事やったなあ…」と思った貴方。
出会いとはいつも偶然で必然、唐突で異質な物です。僕や本記事に限らず、「**一期一会**」を大切に。
（まあ女子は**スルースキル**がなきゃそれも問題でしょうがね😅）

---

個人で活動しておりますので、ソフトウェア開発やコンサル・技術サポート等のご依頼、当方の運営するメディアサイトとの提携のご相談等につきましても、メールやラインでご連絡頂ければ対応可能です。

（参考）

- [リモートワークで失われたもの："出会い"や"コミュニティ"への需要の高まり #ポエム - Qiita](https://qiita.com/SFITB/items/66a5e9609638e5041785)
- [お前らエンジニアはもっと恋愛の実務経験を積んだ方がいい #キャリア - Qiita](https://qiita.com/irokoi/items/c6be8f62d0d66daf194e)
- [いい結婚相手を見つける最適な方法を検証してみた #Python - Qiita](https://qiita.com/katsu1110/items/248097d7aea58e643749)
- [誰でも爆速でマッチングサービスが作れる方法と対策 #AWS - Qiita](https://qiita.com/okamu_/items/a8577431749b72869aa3)
- [27歳エンジニアがマッチングアプリを使用して婚活してみた結果 #ポエム - Qiita](https://qiita.com/app_js/items/0e5aecbc3637816176c1)
- [【個人開発】「遠距離恋愛」をしている人のためのカップルアプリを開発しました！ #Rails - Qiita](https://qiita.com/akane_zark/items/9e90615b40f4353c4e1a)
- [ラブソングから読み解く男女の恋愛観の違い #Python - Qiita](https://qiita.com/JunNishimura/items/a284ee27e5295666dbfe)
Salesforce認定アドミニストレーターを受験することになったから過去問を解いてアウトプットしていこうと思う。Q111 ~ Q120

## Q111. 営業担当者は, Salesforceで終日の行動をどのように作成すればよいか？

解答: イベントの終日イベントチェックボックスをオンにする.
### 解説
終日イベントチェックボックスをオンにすることで, イベントは終日として設定される. 終日イベントとは, 特定の時間を持たずその日の全てをカバーすることを意味する. 終日 = 1日中

## Q112. Ideaコミュニティの利用目的は何か？2つ選択してください.

A. 他のユーザが投稿したアイデアに対してコメントや投稿をする.
B. あるテーマに関連するアイデアを投稿するために顧客やパートナー, 社員も招待できる.
C. アイデアの解決につながる記事のアクセス権を付与する.
D. ポータルのIdeaタブからケースを使って顧客のアイデアを登録する.

解答: A, B
### 解説
Ideaコミュニティの目的は, アイデアの共有とコラボレーションを促進することにある. 
CとDに関しては, Ideaコミュニティの直接的な目的ではなく, 知識管理や顧客サポートのプロセスに関連している.

## Q113. 管理者が商談フェーズごとに設定できる4つの機能はどれ？

A. 商品ファミリ
B. 種別
C. 目標値
D. 確度
E. 売上予測分類
F. グラフの色

解答: B, D, E, F
### 解説
Bについて, 種別とはそのフェーズが「不成立」なのか, 「成立」なのか「進行中」なのかを表す値のこと.
Dについて, 確度とは商談が成立する確率をパーセンテージで表す. これは, 売上の予測や期待値の計算に役立つ.
Eについて, 売上予測分類により売上の達成目標に対する進捗を評価することが可能になる.
Fについて, 商談フェーズごとに異なる色を設定することで, ダッシュボード上やレポート上で商談の進行状況を視覚的に識別しやすくなる.

## Q114. サポートは, ケースページレイアウトからドキュメントや同様のケースを見つけるために効率的な方法を探している, 管理者はこの要件をどのように満たせばいいか？

解答: ユーザーをグローバル検索に誘導して同様のケースを探す.
### 解説
Salesforceのグローバル検索は, 組織内のデータをオブジェクトや項目などを指定せずに検索できる機能である. サポートチームがケースページレイアウトを最適化したり, 関連するキーワードの使用を奨励したりすることで, 迅速かつ効率的に情報を見つけるための最適な方法の1つとなる.

-- グローバル検索について --
https://www.ccc.seraku.co.jp/service/columns/salesforce/01/127/

## Q115. 新しい取引先レコードが100万件ある. アップロードするための推奨される方法は？

解答: データローダ
### 解説
データのアップロード（インポート）方法には「データローダ」と「インポートウィザード」の2つがあり, それぞれ違いはあるが, 設問に多いのは「数」だと思う. 
データローダは5万〜500万のレコードを読み込む場合, インポートウィザードは5万件未満を読み込む場合にそれぞれ活用する.

## Q116. ケースを5時間以内に適切な担当者に転送したい. お客様は, 24時間サポートにアクセスできる. どのように構成すればよいか？

A. エスカレーションルール
B. 割り当てルール

解答: B
### 解説
Aについて, エスカレーションルールは, ケースが規定のサービスレベルを満たしておらず, 処理が遅れている場合の対応策として機能する.
Bについて, 割り当てルールはケースの初期割り当てに関連しており, ケースが作成された直後に適切なチームや担当者に自動的に割り当てる機能. 
AとBで設問に適しているのはB. なぜなら, 「5時間以内に適切な担当者に転送したい」というケースの初期割り当てに関連した指定があるから.

## Q117. 割り当てルールを利用してケースの所有者に割り当てることができるのは次のうちどれ？

A. ユーザー
B. ケースチーム

解答: A
### 解説
Bついて, ケースチームとは, ケースの解決に貢献する複数のユーザーで構成されるチームのこと. あくまでコラボレーションを促進するものだから, ケースの所有者に割り当てることはできない.
Aについて, 割り当てルールはケースやリードなどSalesforce内のレコードを特定のユーザーやキューに自動的に割り当てるために設定されている. 
よって, Aが正しい.

## Q118. Enterprise Editionでは, 積み上げ集計項目をカスタムオブジェクトにどれだけ作成できる？

解答: 40
### 解説
Salesforce Enterprise Editionでカスタムオブジェクトに作成できる積み上げ集計項目の数は, デフォルトで最大25個となっているが, さらに必要になった場合はSalesforceに問い合わせることによってこの制限を最大40個まで拡張することが可能である.

## Q119. 取引先に関連する未解決のケースの数をカウントするために週に1回実行する自動化されたビジネスプロセスがある. このビジネスプロセスの自動化をどのように推奨すればいいですか？

解答: アウトバウンドメッセージを使用してワークフロールールを作成する
### 解説
未解決のケース数をカウントし, それを週に1回実行する自動化されたビジネスプロセスを設計するいはワークフロー機能が適切. アウトバウンドメッセージを使用することでSalesforce外のシステムやサービスに対して情報を自動送信できるので, ワークフローとアウトバウンドメッセージの組み合わせは効果的である.

-- アウトバウンドメッセージ SOAP API 開発者ガイド --
https://developer.salesforce.com/docs/atlas.ja-jp.api.meta/api/sforce_api_om_outboundmessaging_understanding.htm

## Q120. 管理者がAppExchangeの使用を考慮しなくてはならないのはどんな時か？2つ選べ.

A. 標準Salesforce機能が拡張される必要があるとき.
B. Salesforceアプリケーションの機能強化のためのアイデアを送信するとき.
C. 前もって構築されたカスタムアプリケーションやツールを探しているとき.

解答: A, C
### 解説
Bについて, AppExchangeはアプリの拡張機能のマーケットプレイスなので, Bのような場合はIdeaコミュニティを利用する方が適しているので非選択.
電子工作メモ - RainbowLight

# RainbowLight

- カラーモデル
  0  : 赤
  85 : 緑
  170: 青
  255: 赤

  0  ～ 85  => 赤 ～ 緑
  85 ～170  => 緑 ～ 青
  170～255  => 青 ～ 赤

```python
from machine import Pin
from neopixel import myNeopixel
import time

NUM_LEDS = 8
np = myNeopixel(NUM_LEDS, 16)

red   = 0                #red
green = 0                #green
blue  = 0                #blue

# 255を2色で分ける
def wheel(pos):
    global red, green, blue

    # 2色選択
    WheelPos = pos % 255

    # 3分割しているので1/3の値を求める
    one_third = (WheelPos % 85)
    big   = one_third * 3
    small = 255 - big

    # 赤<=>緑
    if WheelPos < 85:
        red   = small
        green = big
        blue  = 0
    # 緑<=>青
    elif 85 <= WheelPos < 170:
        red   = 0
        green = small
        blue  = big
    # 青<=>赤
    else :
        red   = big
        green = 0
        blue  = small

np.brightness(20)
while True:
    for i in range(0, 255):
        for j in range(0, 8):
            wheel(i + j*255 // 8)
            np.set_pixel(j, red, green, blue)
        np.show()
        time.sleep_ms(1)
```
【ChatGPT有＋DALL-E3】で作った作品は、どう管理してますか？　私の場合。


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

　今回は、作った作品を、どう管理しているか、という話です。私の場合を書きますね。

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

　特にニュースがないので
　　さっそく本題に入ります。

　作った作品である画像を
　　どのように管理しているのか。

　これは
　　人それぞれかと
　　　思います。

　たいていは
　　ストレージに
　　　入れるとかかな？

　それとも
　　用がなくなって
　　　削除している？

　私の場合ですが
　　スマホで作業をしているので、
　　　パソコンほどの容量もなく
　　　　そのままではすぐに
　　　　　いっぱいになって
　　　　　　しまいます。

　多くの作品は
　　一過性のもので
　　　保存するほどでもないので
　　　　用が済んだら、削除します。

　でも
　　中には
　　　シリーズものや
　　　　優良作品として
　　　　　保存しておきたい
　　　　　　場合が出てきます。

　そこで
　　外部ストレージとして
　　　Discordを使っています。

　Discordとは何か？
　　Google SGEで尋ねました。
***
***Google SGE***
Discord（ディスコード）は、アメリカで開発された無料のコミュニケーションサービスです。テキストメッセージによるチャット機能や音声通話、ビデオ通話、画面共有などの機能が充実しています。

Discordは、ゲーマーであるジェイソン・シトロン氏が、よりゲームを楽しめるように考え、開発したプラットフォームです。当初はオンラインゲームをしながらコミュニケーションするためのサービスとして普及し、ゲームをしながら、遅延のない音声チャットができることで人気が高まりました。現在では一般的なチャットツールとして利用されています。

Discordは、グループチャット、個人チャット、通話、画面共有などの機能を備えています。ユーザーはそれぞれ「サーバー」を作ることができ、そこで仲間と交流します。﻿

Discordは、アニメや雑談など、さまざまなジャンルのコミュニティで利用されています。通話中に音楽を流す、PC画面を共有、プレイ中のゲームを友達に知らせるなど、さまざまな機能を搭載しています。﻿﻿
***

　このようなもので、
　　現在では、
　　　オンライン会議の場としての
　　　　用途にも使われています。
***
　まぁ、
　　それはともかく、
　　　本題に戻ります。

　Discordで
　　自分のサーバーを用意して、
　　　セッションを用途別に用意。

　そうして、
　　セッションごとに
　　　画像をポストしていきます。

　一度のポストで
　　10枚の画像を
　　　入れられるので
　　　　そうしています。

　保存を終えたら
　　スマホから
　　　保存した画像を
　　　　削除します。
***
　別に、
　　保存先が
　　　Discordだけとは
　　　　言いません。

　ただ
　　自分には
　　　Discordが
　　　　使い慣れていただけに
　　　　　過ぎません。

　とにかく、
　　自分が扱いやすいものを
　　　使いましょう。
***
　ふと思い付きました。

　プロンプトの保管にも
　　使えるな、と。

　よく使うプロンプトは
　　一部は、単語登録してはいますが、
　　　大きなものを登録はできません。

　それに
　　多岐にわたるので、
　　　これまで管理が
　　　　大変でした。

　でも
　　それをDiscordに
　　　保存しておけば、と
　　　　考えたわけです。

　これからは
　　そうしようと思います👍

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Stable Diffusion WebUI Forge をWSL2で使ってみた

高速なWebUIということで話題になっている、Stable Diffusin WebUI ForgeをWSL2のUbuntuにさくっとインストールして使ってみた。

webui_forge_cu121_torch21.7z は、PythonやGitのインストール等が必要無い反面、Extensionが上手く動かないなど制限事項が多いようなので、普通にGitのクローンから起動させることにした。

WSLにCUDA Toolkitのインストールは不要。WindowsにnvidiaのGPUドライバーが入っていれば動作する。

ここからは、デフォルトのUbuntuのコンソールを開いて、そこから作業する。

```
sudo apt update
sudo apt install -y python3.10-venv
sudo apt install -y libgoogle-perftools-dev libgl1-mesa-glx bc
```
venvを使っているので、上記のようにvenvをインストールが必要。

また、libGL.so.1が入っていないのと、ついでにgoogleのTCMallocをインストールしておく。

bcはあってもなくても問題ないようだが、起動スクリプトでエラーが出ているので、これも入れておく。

あと、デフォルトでは、WSLにはpython3 としてPythonがインストールされているので、pythonにエイリアスしておく。
```
alias python=python3
```
```
git clone https://github.com/lllyasviel/stable-diffusion-webui-forge.git
cd stable-diffusion-webui-forge
./webui.sh
```

とすると、pythonの環境設定と、モデルファイルのダウンロードなどが開始され、Webサーバーが起動する。
venvで仮想環境が作られるので、Pythonの環境が汚染されることは無い。

Windowsでは、自動的にWebブラウザが起動して使い始めることができますが、WSL2でXやChrome等がインストールされていない環境では何も起こらないので、自分でブラウザを起動して、コンソールに表示されたURLにアクセスします。http://localhost:7860 でいいと思います。

アクセスするURLは、こんな感じでコンソールに表示されるので、コピペすればよいです。

7行目です。

```
VAE dtype: torch.bfloat16
CUDA Stream Activated:  False
Using pytorch cross attention
ControlNet preprocessor location: /home/okuno/stable-diffusion-webui-forge/models/ControlNetPreprocessor
Loading weights [1a17bcd93d] from /home/okuno/stable-diffusion-webui-forge/models/Stable-diffusion/beautifulRealistic_v7.safetensors
2024-03-08 16:27:36,229 - ControlNet - INFO - ControlNet UI callback registered.
Running on local URL:  http://127.0.0.1:7860

```

あとはGUIから必要なパラメーターを入れて、画像生成を楽しめます。

# 備忘録
起動時に以下のメッセージが出た。

Hint: your device supports --pin-shared-memory for potential speed improvements.
Hint: your device supports --cuda-malloc for potential speed improvements.
Hint: your device supports --cuda-stream for potential speed improvements.

レコメンドとして、-–pin-shared-memory -–cuda-malloc -–cuda-stream　があったので、追加

export COMMANDLINE_ARGS="--pin-shared-memory --cuda-malloc --cuda-stream"
./webui.sh
VercelにGitHub Actionsを用いてデプロイする方法

GitHubレポジトリのフォルダ構成が以下のとおりであるという前提で、masterブランチにpushされたらfrontendをvercelにデプロイするようにします。
```
project
 ├backend
 └frontend
 └.github
     └workflows
         └preview.yaml
```
# 手順
preview.yamlに処理を書いていきますが、基本的には以下のドキュメントのとおりですが、masterブランチにpushされたときにデプロイするようにしたかったので以下のように変更しました。

https://vercel.com/guides/how-can-i-use-github-actions-with-vercel

```yml
# 変更前
on:
  push:
    branches-ignore:
      - main
```
```yml
# 変更後
on:
  push:
    branches: ["master"]
```
# VERCEL_ORG_IDとVERCEL_PROJECT_IDの調べ方
 ドキュメントで指定されている
 ${{ secrets.VERCEL_PROJECT_ID }}と、
 ${{ secrets.VERCEL_PROJECT_ID }}の調べ方を説明します。
まず、VERCEL_ORG_IDは以下のとおりAccount SettingsのVercel IDです。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/b6ffd422-3426-0b52-7139-15f550c9a376.png)
![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/b5506bde-e7e9-a407-9d17-25beff6f40e8.png)

次に、VERCEL_PROJECT_IDは以下のとおりprojectsのSettingsのProject IDです。
![画像6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/0b4ddd4b-a1af-37ec-6a31-ec3447ed157e.png)

![画像7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3439167/cc0ee205-5ed2-a74b-a8c6-b2530eee7d0d.png)

# VERCEL_TOKENについて
VERCEL_TOKENは以下の場所で作成したトークンを用います。

https://vercel.com/account/settings/tokens

# 注意点
frontendをデプロイしたかったのでyamlファイルで「working-directory」として「./frontend」を指定していました。しかし、以下の記事で紹介しているとおり、「Root Directory」で「frontend」を指定しているので、「working-directory」でも「./frontend」を指定すると、project/frontend/frontendを参照するようになりうまくいきません。したがって、yamlファイルで「working-directory」の指定は不要です。

https://qiita.com/tkms13/items/4f6b0a96bed1dab0217f
SAP IntegrationSuite その他サービス

Integration関連のその他サービスについてはこちらでまとめます

# Open Connectorの概要
SAP外のサービス（GoogleとかAmazon）と連携するためのConnector
これ自体は独自の機能を作るわけでなく、接続先側で提供されているAPIをまとめ、認証情報などを統合する

::: note warn
商用環境では最初にアクティベートしたユーザーが他のユーザーを追加するまでアクセス出来ません
アクティベートする人は気をつけてください
ちょっと古いですがこちらのブログを参考に追加ください
BTPのコクピット追加時はメールアドレスを使いますが、SIDを使って追加します

https://community.sap.com/t5/technology-blogs-by-sap/add-users-to-your-sap-cloud-platform-open-connectors-tenant/ba-p/13404738

:::

## チュートリアル
https://developers.sap.com/mission.apim-open-connectors.html

## 対象サービス
https://help.openconnectors.ext.hana.ondemand.com/home/catalog

## 対象外サービスの追加方法
Open Connector対象外のサービスでも下記の方法で追加可能です

https://community.sap.com/t5/technology-blogs-by-members/sap-cloud-platform-open-connectors%E3%81%A7chatwork%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B/ba-p/13359971

# Integration Advisor

https://help.sap.com/docs/PRODUCT_ID/368c481cd6954bdfa5d0435479fd4eaf/6b9fe2d753534bebadcfa9080228bd94.html?state=PRODUCTION&version=Cloud&locale=en-US

https://blogs.sap.com/2021/09/28/integration-advisor-overview-of-components-for-building-b2b-integration-content-and-further-reading/

# Trading Partner Management
https://help.sap.com/docs/CLOUD_INTEGRATION/9e51bec2356e4664b6d5fd1a336a9e12/41d98485f6be4a79a5405affbbd674fe.html

https://blogs.sap.com/2021/12/17/announcement-sap-trading-partner-management-and-b2b-monitoring-brand-new-capabilities-of-sap-integration-suite-is-released/

# Integration Assessment
https://blogs.sap.com/2022/05/15/getting-started-with-integration-assessment/

https://blogs.sap.com/2022/04/26/integration-assessment-capability-within-sap-integration-suite-is-general-available-now/

https://discovery-center.cloud.sap/missiondetail/3842/3912/

# SAP Cloud Connector
## 概要
https://help.sap.com/docs/CP_CONNECTIVITY/cca91383641e40ffbe03bdc78f00f681/e6c7616abb5710148cfcf3e75d96d596.html?locale=ja-JP

## 設定方法

https://github.com/SAP-samples/cloud-extension-s4hana-business-process/blob/mission/mission/cloud-connector/README.md
【メタデータ管理】TerraformでStreamlitの自作データカタログのメタデータ管理をやってみた

# 前置き
こんにちは。データエンジニアの山口歩夢です！

まずは宣伝をさせていただきます。
3/28(木)の18:30〜以下のイベントで
「StreamlitとTerraformでデータカタログを作った話」をします。

ソースコードも公開する予定なので、是非視聴していただけると嬉しいです！

https://datatech-jp.connpass.com/event/310548/



# 本題
それでは本題です。

以前、Streamlitを使ってデータカタログの作成に挑戦をしました。
機能としては、SnowflakeのテーブルのCOMMENTにメタデータを入れておいて、
それをStreamlitアプリ上に表示させるといったものになります。

https://speakerdeck.com/ayumu_yamaguchi/streamlittoterraformdedetakataroguwozuo-tutahua

データカタログは無事作成できたのですが、
毎回SnowFlakeでクエリを実行してCOMMENTにメタデータ入力して更新する必要があり不便だな...と感じておりました。

そこで、Terraformでメタデータの管理をやればyamlでメタデータも管理できるし、
毎回クエリを作成する必要を無くせるのではないかと思いました。


# 早速実装！
## ディレクトリの用意
まずはterraformのディレクトリをこういった形で用意します。
```
terraform/
├─modules
│  └─schema/
│     ├─tables.tf        # yamlをループ処理で読み込む
│     └─tables/          # テーブル毎にyamlを作成
│         ├─[テーブル名1].yaml
│         ├─[テーブル名2].yaml
│         └─[テーブル名3].yaml
└─tfroot
   ├─main.tf
   └─provider.tf
```

## ファイルにコードを書いていく
用意したファイルたちにコードを書いていきます。
### tables.tf
このファイルで、`tables`ディレクトリの中のyamlをループ処理で読み込んで一気にSnowflakeのテーブルのCOMMENTを更新する形にします。
```tf
locals {
 table_files = fileset("${path.module}/tables", "*.yaml")
 tables      = { for file in local.table_files : replace(file, ".yaml", "") => yamldecode(file("${path.module}/tables/${file}")) }
}

resource "snowflake_table" "tables" {
 for_each = local.tables

 database = "DEV_YAMAGUCHI"
 schema   = "TEST"
 name     = each.value.name
 comment  = each.value.comment

 dynamic "column" {
   for_each = each.value.columns
   content {
     name     = column.value.name
     type     = column.value.type
     comment  = column.value.comment
     nullable = column.value.nullable
   }
 }
}

```

### [テーブル名].yaml
yamlにメタデータをテーブル毎に以下のような形式で入れておきます。
こちらを`tables.tf`で読み込むようにしています。
```yaml
name: "EMPLOYEES"
comment: "従業員マスター"
change_tracking: false
columns:
 - name: "EMPLOYEE_ID"
   type: "NUMBER(38,0)"
   comment: "従業員の氏名。このテーブルの主キー。"
 - name: "FIRST_NAME"
   type: "VARCHAR(50)"
   comment: "名前。"
 - name: "LAST_NAME"
   type: "VARCHAR(50)"
   comment: "苗字。"
 - name: "SALARY"
   type: "NUMBER(38,0)"
   comment: "給与。ドル単位で格納。"
 - name: "HIRE_DATE"
   type: "DATE"
   comment: "雇用した日。日本時間にて格納。"
```

### main.tf
`terraform apply`を実行するときに、`tables.tf`のモジュールを呼び出すようにします。
```tf
module "meta_data_definition" {
  source = "../modules/schema/"
}
```
### provider.tf
Snowflakeに接続するためのproviderを用意します。
```tf
terraform {
  required_version = "~> 1.5.0"
    snowflake = {
      source  = "Snowflake-Labs/snowflake"
      version = "~> 0.87.2"
    }
  }
}

provider "snowflake" {
  profile = "[~/.snowflake/configファイルのSnowflakeの認証情報]"
  role    = "[Snowflakeで使いたいロール名]"
}
```

以上のようにファイルを用意し、`terraform apply`を実行すると、
yamlに書かれたメタデータを一括で更新することができました！

# まとめ
このように実装することによって、
以下のようなメリットを得ることができたと考えております。
* yamlファイルなのでデータエンジニア以外の人でも、
更新したいメタデータを簡単&自由に編集することもできる
* 常に最新のメタデータの情報をGitHub上で一元管理できる
* テーブルのメタデータを`terraform apply`で一括更新できる

イベントでは上記の詳しい話や、
上記に加えてメタデータの自動更新を可能にした方法などもお話しようと考えています！

https://datatech-jp.connpass.com/event/310548/



# 採用
GENDAデータチームではプロダクトのデータ解析や機械学習プロジェクトを推進できるデータサイエンティストを募集しています。
興味を持っていただけましたら、是非ご連絡いただけると幸いです！

https://hrmos.co/pages/genda/jobs/1700006587045969926