OmniAICreator/Qiita-1.07M huggingface dataset:
Latexの出力内容を切り替える

## 動機

高校生向けに教材作成をしていたところ、生徒用（問題のみ表示）とカンペ用（解答も含めて表示）の切り替えがしたいなぁ〜と思ったので。

## 方法①：プリアンプルで一括設定する

`comment`パッケージの`\excludecomment`コマンド
`xparse`パッケージの`\NewDocumentEnvironment`コマンド

```latex:プリアンプル
    \usepackage{comment}
    \usepackage{xparse}

    \NewDocumentEnvironment{outputstyle1}{O{}}{}{}
    \NewDocumentEnvironment{outputstyle2}{O{}}{}{}

    % \excludecomment{outputstyle1} %%表示させたい場合はコメントアウト
    \excludecomment{outputstyle2} %%表示させたい場合はコメントアウト
```

上記の場合、`outputstyle2`環境の内容が非表示となる。
（`outputstyle1`環境の内容は普通に表示される。）

## 方法②：本文中で切り替える
Boolean変数`\answershow`を定義して`\if`による条件分岐を行う。
`\answershowtrue` `\answershowfalse`によって本文中で変数を設定し直すことが可能。

```latex:プリアンプル
    \NewDocumentEnvironment{answer}{O{}}{}{}
    \newif\ifanswershow
    % \answershowtrue % 非表示にさせたい場合コメントアウト
    \answershowfalse  % 表示させたい場合コメントアウト
    \ifanswershow \else
    \excludecomment{answer}
    \fi

```

```latex:本文
    \answershowtrue %% 以下answer環境が表示される
    %% 例題
    \begin{enumerate}[(1)]
    \item $x^2+2x-3=0$を解け。
    \item $2x^2-x+1=0$を解け。
    \end{enumerate}
    \begin{answer}
    %% ここに解答を記入 %%
    \end{answer}
    \answershowfalse %% 以下answer環境が非表示となる
    %% 練習問題
```

## 使用例

問題文を`question#.tex`ファイルに記述し、`answer`環境に解答を記述。

```latex:本文

\begin{outputstyle1}
    \section{演習問題}
    \answershowfalse
    \subsection{微分と不等式}
    \begin{enumerate}
    \item \input{question1.tex}
    \item \input{question2.tex}
    \item \input{question3.tex}
    \end{enumerate}
\end{outputstyle1}

\begin{outputstyle2}
    \section{演習問題}
    \answershowtrue
    \subsection{微分と不等式}
    \begin{enumerate}
    \item \input{question1.tex}
    \item \input{question2.tex}
    \item \input{question3.tex}
    \end{enumerate}
\end{outputstyle2}
```

```latex:question#.tex
    \begin{enumerate}[(1)]
    \item #問題文
        \begin{answer}
        #解答
        \end{answer}
    \item #問題文
        \begin{answer}
        #解答
        \end{answer}
    \end{enumerate}
```

レイアウトにこだわる場合には調整などを行う手間は結局変わらないが、ファイルを2つ用意するのが面倒な時には便利。そもそも問題をファイル管理する必要はあり。

ダミー環境を用意して`\excludecomment{環境名}`で隠すという発想でした。
Shell で、Chrome のアカウントを指定してURLを開く方法。デフォルト以外のブラウザで開く。


Mac のShellコマンドにて、Safari をデフォルトにしていようがお構いなく、

Chrome のアカウントを指定してURLを開く方法を共有します。

以下参照

```
open -n -a "Google Chrome.app" --args YOUR_URL  --profile-directory="Profile 1"
```

YOUR_URL に　`https://~` リンクを、

`Profile 1` 部分には、　`Profile 2`, `Profile 3` などを指定する。

（確かFinder で見つけられたはず、　`Library > Application なんとか > Google > Chrome` とかだったかな。うろ覚え）
【祝】Qiita初投稿＆自己紹介

## はじめに
ついにQiita初投稿です…！わいわい
技術的にも人間的にも成長が必要だなーとひしひしと感じる毎日です。
ちなみに最近の悩みはこんな感じ。

 - 勉強した内容が頭に入ってこなくなってきた…（年）
 - 周りのエンジニアの先輩がすごすぎて比べて自信をなくす日々
 - ふとした時の技術トークに入っていけない
 - 自分の成長が実感できにくく、業務で達成感を感じられない
 - 以前は自然に吸収＆アウトプットできていたことが最近は意識しないとできない

などなど尽きません。
学習した内容を書き残したり、ためになった記事をストックしていくことが↑の解消に少しはつながるのではないかなと思っています。

## 自己紹介
主に使う言語：HTML/CSS（SCSS）/JavaScript

- ~2020年 広告代理店に勤めWebに興味を持つ
- 2021年 職業訓練校で約半年コーディングを学ぶ
- 2022年 訓練校卒業->未経験からフロントエンドエンジニアとして就職
:hatching_chick:現在に至ります:hatching_chick:

普段はLPの作成や運用保守をメインに行なっています。
jsが苦手なので知識と実践力をつけたいところです。

趣味は映画鑑賞。直近で観た映画は実写版の「クルエラ（2021）」。
入ってるサブスクはディズニー＋、Netflix、AmazonPrime。どこも切れなくて困っています…。

## 目的
- はじめに書いたモヤモヤの解消
- 知識の定着、実践（具体的にはjsでできることを増やしたい）
- 学習したことを目に見えるカタチで残す
- ふりかえりに使う
- 「勉強してるぞー！」という達成感を得る

## 最後に
こんなこともわからんのか・・・・・と自分に絶望する日もあるのですが、まずはこつこつやっていきたいと思います！

:seedling:他人ではなく【昨日の自分】と比較する
:seedling:些細なことでも達成感を大事にする

マイペースに頑張ります💪


Qiitaをはじめるにあたって、背中を押してもらった記事を貼っておきます。

https://qiita.com/kojimadev/items/f4a6539e4fbc641c6fa0

https://qiita.com/kojimadev/items/1e4d7e83eacb7381ccc5
【Go】gRPCのprotoc-gen-validateでenumの必須&値チェックを行いたい

## 概要
以前に[【Go】protoc-gen-validateを含めたprotoファイルでコード出力時に`protoc-gen-go: invalid Go import path`が発生](https://qiita.com/someone7140/items/1a129c69e433cde4d366)の記事で紹介した通り、protoc-gen-validateはprotoファイルでバリデートの定義を設定できるライブラリです。
gRPCではenumも型として使用できるのですが、今回はenumのバリデートを行う際のメモです。

## 前提
* 使用したprotoc-gen-validateのバージョンは`v1.0.2`になります。

## 課題
protoc-gen-validateのドキュメントの[Enums](https://github.com/bufbuild/protoc-gen-validate#enums)に、設定できるバリデーションが記載されています。
これに従って`defined_only`の設定を行えば良いかとなると、今度は[gRPCのEnumを必須チェックしたい](https://qiita.com/yamatok/items/a800742baa85e1d6c3c6)の記事にある通り、null値の場合は自動で「0」値が設定されるので必須かどうかのチェックが上手く行えません。なお、proto3の仕様だと[Enumerations](https://protobuf.dev/programming-guides/proto3/#enum)のドキュメントにある通り、値が「0」始まりからでないとenumが設定できません。

## 対応案
対応として以下の方針が案として挙げられます。
* 「0」の値は`UNKNOWN`として、異常値として扱う。
* 「0」の値は`not_in`の設定でバリデーションで弾く。
* 「0」 以外の値は、`defined_only`でチェック。

## 設定サンプル
上記方針で、リクエストのenum部分の設定について、以下の通り設定のサンプルを記載します。

```proto
enum AuthMethod {
    UNKNOWN = 0;
    GOOGLE = 1;
    EMAIL = 2;
  }

message SampleRequest {
    AuthMethod authMethod = 1 [(validate.rules).enum = {defined_only: true, not_in: [0]}];
}
```
firebase-admin initializeApp の違い


<br>
firebase-adminのinitializeAppについて、「書き方いろいろ出てくるけど何が違うんだ？」と思ったのでまとめる。

:::note 
cjsで書いたけどだけどemsでも同じ
最近はmoduleベースもあるのでimport方法は異なる場合あり。
:::

## Pattern 1
```js
const admin = require('firebase-admin');
const app = admin.initializeApp()
```
GCPで動かしている場合のみ動くとのこと。

>アプリケーションが Google Cloud 環境内で実行されていて、その環境にサービス アカウントが接続されている場合、アプリケーションはそのサービス アカウントの認証情報を取得できます。
https://cloud.google.com/docs/authentication/production?hl=ja

他にもemulatorで動かしたい時はこれで良い。
```js
if (process.env.NODE_ENV === 'production') {
  // 本番用初期化
} else {
  // emulator
  admin.initializeApp()
}
```

## Pattern 2
```js
// Initialize the default app
const admin = require('firebase-admin');
const app = admin.initializeApp({
  credential: admin.credential.applicationDefault()
});
```

credential json(firebaseからダウンロードできる)へのpathを環境変数に入れると自動で読み込む設定。変数名は決められており、`GOOGLE_APPLICATION_CREDENTIALS`にする必要がある。

つまり`export GOOGLE_APPLICATION_CREDENTIALS=<json path>`すれば良い。
ただ、 json file には認証情報が載っており git で管理してはいけない。
vercelなどにあげる時は Pattern 3 を使う。

## Pattern 3
```js
// Initialize the default app
const admin = require('firebase-admin');
const app = admin.initializeApp({
  credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n'),
   })
});
```

service account の json から抜き出して環境変数に突っ込む





# 参考

https://cloud.google.com/identity-platform/docs/install-admin-sdk?hl=ja

https://zenn.dev/hasehiro0828/articles/ff696aa68ba853

https://blog.ojisan.io/firebase-admin-init/
Qiita始めてみました。対戦よろしくお願いします。

# Qiita始めてみました。 :v:

Qiitaが面白そうだったので、始めてみました。
# 自己紹介

Minecraftサーバー(MCSV-JE&BE)を運営している、ringoXDです。
Skriptで自分が作りたいものをのんびり作って遊んでいます。
* Minecraft Server: https://mcsv.life/
* xyl: https://xyl.lol/ringoxd
* Github: https://github.com/ringo360
* Discord: ringoxd

## 趣味

Minecraftばっかりしてます。
> Q. 飽きないの?
> A. 飽きないんだよなぁこれが


たまにosu!もやります。
[![My Osu! stats](https://osu-sig.vercel.app/card?user=P360Rythm&mode=std&lang=en&blur=6&animation=true&hue=307&mini=true)](https://osu.ppy.sh/users/24734251/)
あんまりやり込んでいる訳ではないので、スコアはそんなに高くありません。
楽しければヨシ！

***

~~(ロリコンです)~~ かわいい二次元の子が好きです
最近はごちうさ観てます
チノちゃんかわいいね

## 得意な事
Skriptで特殊アイテムを作ったり~~要らない機能を量産したり~~する事です。
後はサーバーの基本的な管理とか... (Dockerが全く分からないのでお勉強中です。)

> サーバー管理を2021年9月ぐらいから始めていますが、未だに慣れていない事が多いです。
> どんどん指摘してください。

# 最後に
Skriptが一番得意なので、のんびりチュートリアル的なものでも書いていけたらなと思います。
(日本語記事が少ないので...新しいSkripterのためにも日本語記事を増やしていけたらなと)
後は、サーバー管理中につまづいた所を記事にして残していったりしていきます。
よろしくお願いします :wave:
S3で静的ウェブサイトをホスティングしてみた

# はじめに
S3のバケットにhtmlファイルをアップロードしブラウザからの表示をAWSマネジメントコンソールとTerraformの両方で試してみた。

# 1.S3の作成
1.下記表を参照し、S3を作成します。

| 項目 | 値 |
|:-:|:-:|
| バケット名 | 任意のバケット名 |
| AWS リージョン | ap-northeast-1 |
| パブリックアクセスをすべて ブロック | ✓を外す |
| 現在の設定により、このバケットとバケット内のオブジェクトが公開される可能性があることを承認します。 | ✓ |

2.バケット > バケット名 > アクセス許可 > バケットポリシーを編集します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "{$バケットARN}/*"
        }
    ]
}
```

3.index.htmlファイルを作成します。

```html
<!doctype html>
<html lang="ja">
  <body>
    Hello world!
  </body>
</html>
```

4.バケット > バケット名 > オブジェクトからindex.htmlをアップロードします。
5.バケット > バケット名 > プロパティ > 静的ウェブサイトホスティングを下記表を参照し、編集します。

| 項目 | 値 |
|:-:|:-:|
| 静的ウェブサイトホスティング | 有効にする |
| ホスティングタイプ　| 静的ウェブサイトをホストする　|
|　インデックスドキュメント　|　index.html　|

6.変更の保存を選択します。
7.バケットウェブサイトエンドポイントのリンクを選択し`Hello world!`が表示されることを確認します。
![スクリーンショット 2023-08-08 0.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088692/bad3ea7f-8594-786e-1c2a-f8276fea7b03.png)

# 2.Terraformで作成する場合
```terraform
#S3
resource "aws_s3_bucket" "example" {
  #グローバルで一意のバケット名に変更
  bucket = "test-bucket"
}

#静的ウェブサイトホスティングの有効化
resource "aws_s3_bucket_website_configuration" "example" {
  bucket = aws_s3_bucket.example.id

  index_document {
    suffix = "index.html"
  }
}

#パブリックアクセスの有効化
resource "aws_s3_bucket_public_access_block" "example" {
  bucket = aws_s3_bucket.example.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

#バケットポリシー
data "aws_iam_policy_document" "example" {
  statement {
    sid       = "PublicReadGetObject"
    effect    = "Allow"
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.example.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
  }
}

#S3とバケットポリシーの紐付け
resource "aws_s3_bucket_policy" "example" {
  bucket = aws_s3_bucket.example.id
  policy = data.aws_iam_policy_document.example.json

  #パブリックアクセスの有効化を先に実行しないとエラーになる
  #https://zenn.dev/hige/articles/01b69444ccaa3d
  depends_on = [
    aws_s3_bucket_public_access_block.example
  ]
}
```

apply後にindex.htmlをアップロード、`Hello world!`が表示されることを確認します。
中国でGFWを超える方法

# 問題

中国だとgoogleとかyoutubeとか使えない


# 解決方法

- VPN (tailscale exit-node)
- shadowsocks
- socks5

## VPN

個人的にはtailscaleが好きなので、自分の家のサーバーをexit-nodeとして使っていたが、たまに激遅になったりしたんで、たぶんGFWに検知されたんだと思う

## shadowsocks

socks5経由だとGFWに検知されにくいということで使ったが全然悪くなかった
が、中国外のサイトを見るにはいいが、中国内のサイトを見ると激遅になるので帯に短し襷に長し

## socks

これがサーバーだとアプリ毎でproxyとして指定できるので、chromeは中国内サイトを、firefoxは中国外サイトをと言うふうに振り分けて使えるので便利と聞いたのでやってみた

### socksサーバー構築

兎にも角にも中国外にサーバーが必要なので、VPSなり自宅のサーバーなりをどうにかする

その上でdockerをインストールする
（今のバージョンならdocker composeもついてくる）

https://hub.docker.com/r/serjs/go-socks5-proxy/

```yml:docker-compose.yml
version: '3'

services:
  socks5:
    image: serjs/go-socks5-proxy
    container_name: socks5
    ports:
      - "1080:1080"
    environment:
      PROXY_USER: your_user_name
      PROXY_PASSWORD: your_password
    restart: always
```

`your_user_name` `your_password`は自分で書き換えるとして、これを中国外のサーバー上で起動するだけでOK

```
$ sudo docker compose up -d
```

### socks クライアント設定

クライアントとしてはsocks5の設定が楽なfirefoxを通常は使うようで、ブラウザの設定で`socks`と検索してみると

![Screenshot 2023-08-08 at 23.33.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/fb4c39bb-9131-c3f7-7250-3863e01fb25c.png)

とあるが、ID/PASSの設定ができない（ID:PASS@IP_ADDRESSとしてもだめだった）

ので、どうやら通常はextensionを入れるらしい

自分はこれを使った
https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/

- サーバーのIPなりドメイン名なり
- ポート番号（上の設定のままなら1080）
- ID
- PASS

を設定すればすぐに繋がるはず

### が、遅い...

socks5でyoutubeなりを見れるようになったが激遅

### 速度の解決

参考にしたのは下の記事

https://qiita.com/ymfj/items/0e22e0c9b11643a03b3d

https://qiita.com/hotchpotch/items/ada8a2a1297e2e461ac3

```
$ wget https://raw.githubusercontent.com/teddysun/across/master/bbr.sh
$ bash bbr.sh
```

をサーバー側で実行して、表示されるままにエンターを押すと設定が終わり、一応

```
$ docker compose down
$ docker compose up -d
```

と再起動をして繋げ直すとむちゃくちゃ早くなった


## 因みにshadowsocks

https://hub.docker.com/r/shadowsocks/shadowsocks-libev#docker

```yml:docker-compose.yml
version: '3'

services:
  shadowsocks:
    image: shadowsocks/shadowsocks-libev
    container_name: shadowsocks
    ports:
      - "8388:8388"
      - "8388:8388/udp"
    environment:
      PASSWORD: your_password
    restart: always

```

`your_password`は変えるとして、


```
$ sudo docker compose up
```

とあえて`-d`はつけずにまず起動してみた方がいい
表示されるログにどの`encrypt_method`が使われているのか表示されるはず

## shadowsocks クライアント

- サーバーのIPなりドメイン名なり
- ポート番号（上の設定のままなら8388）
- PASS
- encrypt_method

をshadowsocksのクライアントに設定でOK

windows クライアント
https://github.com/shadowsocks/shadowsocks-windows/releases

mac クライアント
https://github.com/shadowsocks/ShadowsocksX-NG/releases
ATtiny406のCCLを使って、GPIO上にAND回路やOR回路を作ってみる

# CCLとは
通常マイコンでは、各ピンのHIGHやLOWの出力についてはプログラミングによって制御を行います。そこで複数のピンの状態によって特定のピンへの出力を設定したい場合、ピンの状態変化による割り込み処理や、loop()関数の中で入力ピンの状態を読み込み出力ピンを設定する処理を記述する必要があります。しかしこの方法だと、AND回路やOR回路といった比較的単純な論理回路を実装したい場合、処理の割に実装が泥臭い感じになってしまいます。さらにこの処理でCPU時間を取られてしまい、他のプログラムへの影響も発生します。
そこでATtinyにはCCL(Configurable Custom Logic)と呼ばれるペリフェラルが用意されています。これは構成設定可能な論理回路で、あらかじめ決められた真理値表を設定することで、入力ピンの状態から出力ピンを自動的に制御することができ、AND回路やOR回路なども比較的簡単に実装することが出来ます。また単純な論理回路だけでなく、RSラッチやDフリップフロップなども設定させることが可能です。
# AND/OR/XORの実装
本稿ではANDやOR、XORといった単純な論理回路を設定する方法について解説します。
ラッチやフリップフロップについてはまだ実装したことがないので、そのうち知見が得られたらまとめたいと思います。
## 構成
CCLはこのような構成になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/e868e3b2-d781-4e59-156b-526f71547ddf.png)
入力ソースの指定はINSELで行いますが、今回はピンを指定します。INSELの指定次第ではCCLの出力をつないだり、UARTやSPIの送信線を指定したりもできます。画像のTRUTHは真理値表になり、どの入力に対してどう1や0を出力させるかを設定させます。FILTSELやEDGEDETはよくわからないので、入力をそのまま出力させるように設定しています。
SEQSELは単純な論理回路か、またRSラッチやDフリップフロップなどを使うかを設定できます。今回は単純な論理回路を設定したいので、000を指定します。
## 初期化
前節のような設定を行うための初期化処理はこのようになります。
```cpp:初期化処理
  // おまじない
  CCL.CTRLA = 0x00;
  // 単純な論理回路として利用することを指定
  CCL.SEQCTRL0 = 0x00;
  // 入力0は使用しない、入力1はPIN_PA1として設定
  CCL.LUT0CTRLB = 0x50;
  // 入力2はPIN_PA2として設定
  CCL.LUT0CTRLC = 0x05;
  // 真理値表　詳細は後節で
  CCL.TRUTH0 = 0x3C;
  // 出力PINとLUT0を有効化
  CCL.LUT0CTRLA = 0x09;
  // CCLを有効化
  CCL.CTRLA = 0x01;
```
簡単に解説します。
```cpp:おまじない
CCL.CTRLA = 0x00;
```
最初に下記のCCLのペリフェラルを無効かさせるおまじないを行います(これがないと正常動作しなかったです)。エラッタの「2.4.3. 単一LUT構成変更にCCLの禁止が必要」あたりが怪しいのかな？と思ってますが確証はありません。
```cpp:単純な論理回路として利用することを指定
CCL.SEQCTRL0 = 0x00;
```
次に単純な論理回路として利用することを、下位3ビットに000にセットすることで設定します。RSラッチは100、Dラッチは011(エラッタから動作はしないらしい)、JKFFは010、DFFは001を指定します。詳しい説明については省略します。
```cpp:入力ソースの指定
CCL.LUT0CTRLB = 0x50;
CCL.LUT0CTRLC = 0x05;
```
次に入力ソースを指定します。LUT0CTRLBの下位4ビットは入力0のソースを、上位4ビットは入力1のソースを指定します。またLUT0CTRLCの下位4ビットは入力2のソースを指定します(上位4ビットは不使用)。今回、入力0は不使用(0b0000)、入力1と入力2はピンをそのまま利用(0b0101=0x5)します。ATtiny406の場合LUT0の入力0はUPDIとピンが一致(PIN_PA0)するため、GPIOとして利用することが難しいので不使用としました。他の入力ソースを指定したい場合は、ATtiny406のデータシートの27.5.4や27.5.5を参照してください。
```cpp:真理値表の指定
CCL.TRUTH0 = 0x3C;
```
今回はXORを実現させるために0x3Cを設定しています。詳細については後節にて解説します。
```cpp:真理値表の指定
CCL.LUT0CTRLA = 0x09;
CCL.CTRLA = 0x01;
```
LUT0CTRLAに0x09を設定することでLUT0の有効化と、LUT0の出力をLUT0OUTピン(PIN_PA4)に接続します。そして最後にCCL.CTRLAに0x01を設定することで、CCLの設定の反映とCCLの有効化を行います。
## 真理値表
真理値表は、入力0、入力1、入力2に対してどのような出力を行うかを定めた表になります。CCLのLUT0ではTRUTH0で真理値表を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/c0d4f3c5-a2c5-3bcc-e92a-7a650dd51a0c.png)
これは真理値表を設定する際の参考図になります(データシートより)。LUTn-TRUTHSEL0は入力0、LUTn-TRUTHSEL1は入力1、LUTn-TRUTHSEL2は入力2になります。TRUTHnXは直感的に逆となりややこしいですが、TRUTHn0は最下位ビット、TRUTHn7は最上位ビットとなります。従って0x42を設定した場合TRUTHn1とTRUTHn6が1でそれ以外は0となるため、入力0,入力1,入力2がそれぞれ1,0,0と0,0,1の時に1が出力される真理値表となります。今回、入力0は不使用であることを踏まえると、単純な論理回路の真理値表は入力1と入力2の値で判断しますので、AND回路の真理値表は0xC0、OR回路は0xFC、XOR回路は0x3C、XNOR回路は0xC3、NAND回路は0x3F、NOR回路は0x03となります。
# 最後に
今回はAND回路やOR回路といった単純な論理回路をCCLに設定する方法について記述しました。次はJKFFやDFF、RSラッチについても記述したいと思っています。
aws kms & kotlin で localstack と 商用を両方利用する場合にこうやった

暗号化に AWS Key Management Service(kms)を利用して、バックエンドを kotlin を使っている場合に開発環境と商用環境両方を考慮した実装方法がなかなか見つからなかったのでこうやったって話を記載します。

# 前提

- 開発環境は アプリ側はtomcatで起動、kmsはlocalstackを利用している
- 商用環境は アプリ側はeksでpodを起動、AWS kmsを利用してterraformでprincipalsでpodのiamロールでアクセスを許可

# 実現方法

ポイントはKmsClientの生成方法。

localstackを利用している開発環境はKmsClientをbuildするときに、endpointを指定することでVPCを経由することになりモックで強制的にハックすることができる。

## 利用したライブラリー

ちょっとハマったので利用するライブラリーも記載。

``` gradle
    kotlin("jvm") version "1.9.0"
    kotlin("plugin.spring") version "1.9.0"

    implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.11")
    implementation("aws.sdk.kotlin:kms:0.21.5-beta")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.7.3")
```

localstackは1.4を利用。

## 実装

1 . application.yaml はこんな感じ
``` yaml
aws:
  region: "${AWS_REGION}"
  kms:
    endpoint: "${AWS_KMS_ENDPOINT:}"
    keyId: "${AWS_KMS_MASTER_KEY_ID:}"
```
2 . 環境変数を変える
- 開発環境は以下のように設定する
``` env
AWS_REGION=ap-northeast-1
AWS_KMS_MASTER_KEY_ID=alias/hodeservice/hoge
AWS_KMS_ENDPOINT=http://localhost:4566
```
- 商用環境は以下のように設定する
``` env
AWS_REGION=ap-northeast-1
AWS_KMS_MASTER_KEY_ID=alias/hodeservice/hoge
```
AWS_KMS_ENDPOINTを指定しない

3 . KmsClientの生成を工夫する

``` kotlin
    private val kmsClient: KmsClient = KmsClient {
        region = awsConfig.region
        endpointUrl = awsConfig.kms.endpoint?.takeIf { it.isNotEmpty() }?.let { Url.parse(it) }
    }

    suspend fun decryptCiphertextKeyToPlainTextKey(ciphertextKey: ByteArray): ByteArray {
        val decryptKeyRequest = DecryptRequest {
            this.ciphertextBlob = ciphertextKey
            this.keyId = awsConfig.kms.keyId
        }
        return kmsClient.decrypt(decryptKeyRequest).plaintext ?: throw FailedToDecryptDataKey()
    }
```

こんな感じでAWS_KMS_ENDPOINTの設定有無で生成するKmsClientの方法を変えることで、EndpointProviderが適切になり両環境で上手く動作するようになる。
簡易メモアプリ開発 序章 〜完〜

# とりあえず完成報告と共有
https://github.com/Yu1111111/FrontOnlyMEMO
GitHub PagesのURLがなかなか発行されないのでそちらは後日付け加えます。
ボロボロではありますがとりあえず作り終えました。
ファイルデータとテキストデータの紐付けはできているのですが肝心のフロント画面がボロボロのため、ただ登録したファイルとテキストが一覧表示されるだけの代物になります。
あまりに中途半端なため実用性の無いメモアプリになってしまいましたが「アプリを自力で作って公開する」と「データを運用する」を達成できたのでヨシ！
# 学んだこと・得られたもの
- 命名規則の重要性(関数・データ・要素のID)
- コードの振り分けの重要性
- UIデザインの必要性
# 命名規則の重要性
初めは思いつきでタグのidや関数名、変数名、キーを割り振っていたためしばらくすると「このadd-fileってなんだっけ...表示する場所か？それともトリガーか？」と迷いが生じてしまいました。
そこで今回は以下のように命名規則を作って開発しました。
データ名 →　大文字とアンダーバー(snake_case)
変数や関数 →　動詞は小文字、名詞は大文字で始まる(camelCase)
要素id　→　表示する場所を表す場合は"Display + 名詞"、引き金を表す場合は"Trigger + 動詞"
命名規則はチーム開発の場に限らず個人開発であっても重要なスキルだと思うので癖をつけておきたいものです。
# コードの振り分けの重要性
何せ初めは一つのJSファイルに思いつきで必要な処理を記述していたため途中から「グロいな...」と思い整理することにしました。
たまたま知っていたMVCモデルを活用して役割毎にファイルを分けたかったのですがイマイチ紙に書き起こしても整理ができなかったため断念。
結局は単純にユーザー視点からみた「目的」毎にファイルを分けて開発しました。
再利用性を考慮して開発しようか悩みましたが無理でした。次回に期待。
# UIデザインの必要性
今回は紙になんとなくのイメージを書いてそれに沿ってどうにかHTMLとBootstrapを用いて組み立てるという行き当たりばったりな感じのUI開発となりました。
後々になって「あれがないから付け加えなきゃ」などということがあり、手が止まることが度々ありました。
正直いって気持ちよくない。UIデザインはコードを書く前にFigmaあたりを使ってきっちり明確にしておくべきでしょう。
# 今後の予定
フレームワーク使って開発してぇ。メンテナンス性を高めてぇ。
てなわけでReactを学んでいこうと思います。
他にもBootstrapと異なり、より自由度の高いデザインが可能なCSSフレームワーク"Tailwind CSS"も気になっているのでかじりたい。
DB操作とバックエンド(Node.js+Express)あたりはお預け状態になってしまいそうです。
状態管理を担うReduxも気になるんだよなぁ...
直近ではReact ,Redux ,TailwindCSSをかじり、今回開発した簡易メモ帳をより実用的なものにグレードアップすることを目標にぼちぼちやっていこうと思います。

# 最後に
頭がうるさくて眠れない方は大人しく市販の睡眠安定剤を飲んでくださいね。睡眠不足ほど人を殺すものもないと思うので。
ではでは。
【VS Code】Docker コンテナを使用した開発環境

# 参考記事

以下を参考に Docker コンテナを使用した開発環境を構築する

https://code.visualstudio.com/docs/devcontainers/containers


# 前提条件
* VS Code に Dev Containers が導入されていること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/a39fba06-7f92-a685-9adb-d94b6957ff46.png)

* Docker Desktop が導入されていること

# Docker コンテナ作成・起動 (その1)

以下の「リモートウィンドウを開きます」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/d01c0903-f302-770d-eaf9-23e37316b965.png)

以下の「新しい開発コンテナー...」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/2870fed2-5412-7f8e-7b82-c5496dd4d050.png)

適当に Ubuntu を入力し、選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/81c96405-cf67-efd6-2d51-79e02cae83e2.png)

「その他のオプション...」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/bbe03036-3824-2cc8-99ac-f62356afa359.png)

「jammy」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/0757de55-266c-5875-5509-e3901aa68efc.png)

適当に AWS 関連の機能を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/4b128378-dfcf-a2a2-aead-ee2934c54b1b.png)

以下のように Ubuntu 環境が立ち上がる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/54cb3d8b-2c98-840a-9c1e-512370f62ff1.png)


# Docker コンテナ作成・起動 (その2)

任意のフォルダに以下のファイルを作成

```
.devcontainer/devcontainer.json
```

以下は `devcontainer.json` のサンプル

```devcontainer.json
{
	"name": "Ubuntu",
	"image": "mcr.microsoft.com/devcontainers/base:jammy",
	"features": {
		"ghcr.io/devcontainers/features/aws-cli:1": {},
		"ghcr.io/devcontainers-contrib/features/aws-cdk:2": {}
	},
	"customizations": {
		"vscode": {
			"extensions": [
				"hediet.vscode-drawio",
				"hashicorp.terraform"
			]
		}
	}
}

```

「コンテナーでフォルダーを開く...」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/8adcbc84-a0ba-ee1e-c12e-f14686d473c2.png)

準備したフォルダを開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/4f01275c-6cbb-c2f0-d514-bc30e0174645.png)

以下のように Ubuntu 環境が立ち上がる。

`devcontainer.json` の `extensions` で指定した拡張機能も導入済み。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/0ed18ecc-5ece-7c5a-dc7a-c755d1b49917.png)
苦労しないコーディング方法

皆さんこんばんは。
毎日個人制作をするために残業をやめようと決意したまちゅです。

昨日は1日目にしてインプットしている時間が取れず、
3時頃まで夜更かししてしまいました。
無茶をすると取り組みが継続できないのでやり方を考えねば・・と悩んでます。
良いやり方を見つけたいです。

# 本題
結論から言いますと、
苦労しないコーディング方法は分割をしっかりとすることです。

どういうことか。


エンジニアリングは出力という明確な回答があるのに対して、
デザインやUX/UIには答えがありません。
一般的にマテリアルデザインと言われるものも理想のUX近似値にすぎません。

ではその不毛な思考、消耗をやめるために必要なことは何か。
それが領域毎の作業の分割です。
具体的な行動は

- CSS上でデザインを弄繰り回さない。
- 見た目の実装と機能の実装を行ったり来たりしない。
- デザインと実装の間で共通の規則を決める。

です。
上から解説します。

## 1. CSS上でデザインを弄繰り回さない。
最悪手です。
必ず、デザイン→実装の順番を守るようにします。
デザインボードに起こさない状態で実装に走ると、デザイン変更→吟味→デザイン変更→・・・といった、デザインのレビューサイクル速度が著しく低下し消耗します。
figmaはドラッグ1つで見た目を変えられますが、それをコード上でしようとすると、ホットリロードを活用したとしてもたった1pxの変更でさえ毎回文字を入力する→保存する→反映をまつという時間が発生します。

それに加え、ゴールが見えない状態で走ることになるので、しっくりこない点があると掛け算で作業時間が肥大化してかなりしんどいです。
デザインボードを再現することをとりあえずのゴールにしましょう。


## 2. 見た目の実装と機能の実装を行ったり来たりしない。
機能の実装をしている時に見た目の変更をするのをやめましょう。
あっちこっちいくのは、考えないといけないジャンルが雑多になって消耗し、成果物の質が落ちます。
しっかりと見た目実装と機能実装の作業フェーズを分割しましょう。

補足ですが、
実装で最も効果的な方法は、
見た目は雑で機能だけ作る→デザインに沿って見た目を整える
です。
なぜ機能が先かというと、
サイトは世の中を便利にする機能があって、その先に見た目がある、が本質だからです。

例えば、
- 見た目が汚くても機能に不備が無く使いやすいサイト
- 機能はバグだらけだが見た目が良いサイト


の2つを比較した場合には、前者が圧倒的に評価されます。
世の中の大半の人は、製作者が思っているよりもサイトのデザインを気にしていません。
サイトのメイン価値はそこではないからです。

なので、先に機能を仕上げておいてあげるとサイトはサイトとしての最低限の職能を全うでき、なおかつ不具合などに極力意識を割かずにデザインに没頭できるというメリットが発生します。

よって、しっかりと見た目と機能別で分けて実装に取り組んだ方が成果物の質が高くなります。


## 3. デザインと実装の間で共通の規則を決める。
デザインとエンジニアリングを薪のように分割した後は、
それを蝶番で繋がなければいけません。
両者のインターフェースとして、独自のコーディング規則を作ります。

例ですが、
- marginは8の倍数にする
- フォントサイズのバリエーションは5個まで
- ブレークポイントは768pxと1080pxの2点


など、ここは独自ルールで構いません。
広く使われているTailwindCSSなどでは、`ml-4`のようなクラスがあり、これは`margin-left: 1rem`と同義です。figmaでは`grid layout`を活用しましょう。

フォントサイズでは`text-xs`などがあります。これは、figmaでも`Typograpy`としてフォントサイズの定数化ができるので上手く使いたいですね。

端末のブレークポイントは、`$xs: 375px;`のような定数化をしてsassのメディアクエリで使用します。
figmaではレイアウト制約やオートレイアウト、コンポーネントを活用して管理コストを下げましょう。

コーディング規則のメリットは、管理コストが下がることもありますが
具体的な数値に悩むことが無くなることが良いです。
「規則で決まっているのだから、ここはこれでいいんだ」という割り切りができ悩む時間が減ります。


# さいごに
個人開発だと特に、メンテナンスにかける時間は極力少なくしてモチベ高く施策に注力をしていきたいですよね。

上記の3つを守って運用してあげると気持ちよく制作活動ができるかもしれません。

明日はグリッドレイアウトの活用について書きます。
タイピングのロジックを考えよう

# はじめに
タイピングソフトを作りたい人向けの記事です
丁寧な導入は省略して、理論の話をします。
プログラムが見たい人は以下のリンクから見てください。

https://github.com/ei1821/Typing

# 作成するタイピングゲームの要件
* 半角文字とひらがなを受け付ける
* ひらがなはローマ字入力のみとする
* ひらがなの変換は概ねすべてを対応する(例えば「っ」を入力する方法4通り全て可能）

# 本題

## 日本語入力の嫌なところ
日本語入力は面倒くさく、面倒くさい原因は特に以下二点が挙げられます。
* 1つのかな文字に対して複数のローマ字が対応している​
* 規則性が薄い

例えば、「し」というかな文字を入力するためには、"si"と"shi"の2種類があります。
「っ」(小さいつ)を入力する方法は"ltu", "xtu", "ltsu", "xtsu"の4種類があります。
このような1文字に対して複数の入力方法があれば、複数文字を同時に入力する方法もあります。
特に、「っし」という文字列は"ssi"や"sshi"と入力すれば一度に入できます。もちろん、「っ」と「し」に分けて入力することもできます。

「ざっしゅ」という文字列を入力する方法がいくつあるかご存知ですか？

<details><summary>一覧</summary>

* zassyu​
* zasshu​
* zassixyu​
* zassilyu​
* zasshixyu​
* zasshilyu​
* zaltusyu​
* zaltushu​
* zaltusilyu​
* zaltusixyu​
* zaltushilyu​
* zaltushixyu​
* zaxtusyu​
* zaxtushu​
* zaxtusilyu​
* zaxtusixyu​
* zaxtushilyu​
* zaxtushixyu​
* zaltsusyu​
* zaltsushu​
* zaltsusilyu​
* zaltsusixyu​
* zaltsushilyu​
* zaltsushixyu​
* zaxtsusyu​
* zaxtsushu​
* zaxtsusilyu​
* zaxtsusixyu​
* zaxtsushilyu​
* zaxtsushixyu​
</details>
なんと怒涛の20通りです。

タイピングゲームを作成するにあたって、この複数入力への対応は必須になるでしょう。

これらがなんらかの規則に則っていれば簡単に対応できたかもしれませんが、アルファベットとローマ字入力に規則はほぼないと言ってよく、残念ながら愚直に変換テーブルを作成せざるをえません。

## 用語設定
* センテンス
タイピングゲームで入力するお題の文章を指します。
* ワード
1度にローマ字からひらがなに変換できる文字列を指します。
例:「し」、「っし」、「っくぁ」など 
「おかき」というひらがなを1度に変換する方法はないので、これは1ワードではない

## アルゴリズム
まず、お題をタイピングゲームで使いやすくするための前処理に、
「センテンスとしてひらがなの文字列を入力すると1ワードを1つのノードとした、文字列入力の有向グラフを出力する」ようなアルゴリズムを考えます。

1. ワードを判定するテーブルを作成する
1. センテンスを頭から走査し、ワードをみつける
1. 隣接するワード同士にエッジをはり、つなげる

以上

### 変換テーブルの作成
変換テーブルとは、「し」が入力されたら"si", "shi"という入力が可能、というワードとローマ字の辞書です。
このテーブルを作成すれば、ワードごとの入力方法がわかると同時に、この文字列はワードであるか？ という問に答えることができます。

このテーブルの作成は、手作業で頑張りました。どの入力方法を採用するかは、wikipediaを参考にしています。
実際の変換テーブルは上GitHubリンクからソースコードを確認してください。

https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%9E%E5%AD%97%E5%85%A5%E5%8A%9B


### ワードの検索
該当部分のソースコードを引用します
余計な部分もありますが、雰囲気で読んでください。
```C#
for (int l=0, r=1; l < Sentence.Length; l++, r=l + 1) {
    edge[l]=new List<TypeWord>(); // l文字目からはじまるワードのリストを初期化
    while (r <=Sentence.Length) { // センテンス長をこえない間
        string kana_substr=Sentence[l..r]; // [l, r)の連続部分文字列を取得
        // テーブル上に存在しなければbreak
        if (TypeUtils.kana2romaList.TryGetValue(kana_substr, out string[]? val)==false) break;
        foreach (var romaji in val) {
            edge[l].Add(new TypeWord(kana_substr, romaji)); // 可能な入力方法の分だけ追加
        }
        r++;
    }
}
```

#### 解説
edge[l]は、文字列の$l$番目から始まるワードのリストです。
例えば、”っし”という文字列のとき、$edge[0]$は{"っ", "っし"}という集合を持ちます(コードではリストですが)
forで各文字から始まるワードを、ワード長を1文字、2文字と増やしながら検索していきます。
文字列長を伸ばして、ワードが見つからなかったら、$l$文字目から始まるワードの検索を終えます。
これは、センテンスを$S$とすると、$S_{l..l+i}$という$i$文字の部分
文字列がワードでないならば、部分文字列$S_{l..l+i+1}$がワードであることはない、という理屈に基づいています。

$edge[l]$には、ワードの集合を持ちますので、もちろんそれぞれのワード長がわかります。
$l$文字目から始まる$n$文字のワードが入力されたら、次に入力すべきは$l+n$文字目のワードである、ということなので、これを有向グラフと見立てることで、以下のような有向グラフが完成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283808/2470fbc5-78a1-66f8-5c49-f97e938c2c35.png)


# 最後に
とりあえずここまでで解説を終了します。
以上の前処理を実際にどう利用しているか気になる人はページトップのリンクからソースコードを読んで見てください。
いつか続きを書きます。
【Azure App Service】最も安くWebサーバーを運用できるリージョンはどこ？

# 結論（※ ひと月あたりで計算しています）
米国全リージョン、スウェーデンの Sweden Central、ポーランドの Poland Central、ヨーロッパの West Europe と North Europe、アジア太平洋の East Asia と Southeast Asia で **4,537.11 円** になります。

逆に最も高いリージョンはアフリカの South Africa West で **13,920.68 円** になります。
3倍近くも高い！！！

ちなみに日本の Japan East では **7,115.01 円**、Japan West では **6,290.09 円** になります。
地味に高い・・・

私は、アジア太平洋の East Asia にデプロイして、運用しています^^
会社で個人が使える Azure の利用金額の上限を超えてしまうという失敗経験がありました。
Azure App Service を使っている方でなるべく安くコストを抑えたい方はぜひ参考にしてください～～～
もしかすると他のクラウドサービスもリージョンごとで金額が違うかも？？

https://qiita.com/official-events/e9f582bec72278130942

# はじめに
Azure App Service は以下の通りです。
> Azure App Service は、Web アプリケーション、REST API、およびモバイル バックエンドをホストするための HTTP ベースのサービスです。 開発には、.NET、.NET Core、Java、Node.js、PHP、Python のうち、お気に入りの言語をご利用いただけます。 アプリケーションの実行とスケーリングは、Windows ベースの環境と Linux ベースの環境の両方で容易に行うことができます。

https://learn.microsoft.com/ja-jp/azure/app-service/overview

今回、コスト計算は Microsoft が提供している料金計算ツールを使用しました。

https://azure.microsoft.com/ja-jp/pricing/calculator/

料金計算ツールで選択した App Service の設定は以下の通りです。
- オペレーティングシステム：Windows
- レベル：B1（1コア、1.75GB RAM、10GB ストレージ）
- インスタンス数：1
- 期間：月

B1 は選択した理由は、「常時接続」、「独自のドメインの割り当て」、「無料の SSL 証明書 & SSL 接続」ができるところになります！


# 全リージョンの計算結果
料金計算ツールを使って計算できるすべてのリージョンで算出してみました。

※2023年8月8日、1 USD = 141.26 JPY

## 米国
|リージョン|価格（円）|
|:-:|:-:|
|West US|4,537.11|
|West US 2|4,537.11|
|West US 3|4,537.11|
|West Central US|4,537.11|
|South Central US|4,537.11|
|Central US|4,537.11|
|North Central US|4,537.11|
|East US|4,537.11|
|East US 2|4,537.11|

## イギリス
|リージョン|価格（円）|
|:-:|:-:|
|UK West|9,692.92|
|UK South|9,692.92|

## アラブ首長国連邦
|リージョン|価格（円）|
|:-:|:-:|
|UAE Central|9,094.84|
|UAE North|8,558.64|

## スイス
|リージョン|価格（円）|
|:-:|:-:|
|Switzerland West|5,842.87|
|Switzerland North|8,088.64|

## スウェーデン
|リージョン|価格（円）|
|:-:|:-:|
|Sweden Central|4,537.11|
|Sweden South|5,898.24|

## カタール
|リージョン|価格（円）|
|:-:|:-:|
|Qatar Central|4,990.82|

## ポーランド
|リージョン|価格（円）|
|:-:|:-:|
|Poland Central|4,537.11|

## ノルウェー
|リージョン|価格（円）|
|:-:|:-:|
|Norway West|5,866.69|
|Norway East|4,990.82|

## 韓国
|リージョン|価格（円）|
|:-:|:-:|
|Korea Central|5,980.74|
|Korea South|5,980.74|

## 日本
|リージョン|価格（円）|
|:-:|:-:|
|Japan West|6,290.09|
|Japan East|7,115.01|

## インド
|リージョン|価格（円）|
|:-:|:-:|
|Central India|5,980.74|
|South India|5,362.04|
|West India|5,980.74|

## ドイツ
|リージョン|価格（円）|
|:-:|:-:|
|Germany West Central|8,146.18|
|Germany North|8,867.99|

## フランス
|リージョン|価格（円）|
|:-:|:-:|
|France Central|9,692.92|
|France South|10,002.27|

## ヨーロッパ
|リージョン|価格（円）|
|:-:|:-:|
|West Europe|4,537.11|
|North Europe|4,537.11|

## カナダ
|リージョン|価格（円）|
|:-:|:-:|
|Canada Central|4,949.58|
|Canada East|4,949.58|

## ブラジル
|リージョン|価格（円）|
|:-:|:-:|
|Brazil Southeast|9,181.46|
|Brazil South|5,980.74|

## Azure Government
|リージョン|価格（円）|
|:-:|:-:|
|US Gov Taxas|7,011.90|
|US Gov Virginia|7,011.90|
|US Gov Arizona|7,011.90|

## オーストラリア
|リージョン|価格（円）|
|:-:|:-:|
|Australia Central|5,980.74|
|Australia Central 2|5,980.74|
|Australia East|5,980.74|
|Australia Southeast|5,980.74|

## アジア太平洋
|リージョン|価格（円）|
|:-:|:-:|
|East Asia|4,537.11|
|Southeast Asia|4,537.11|

## アフリカ
|リージョン|価格（円）|
|:-:|:-:|
|South Africa West|13,920.68|
|South Africa North|11,342.78|
Git 権限777のファイルなのに755で登録される

# 概要

- Git管理されいているファイルの権限を任意の権限から777に変更した。差分を確認すると「644 →　755」に変更された旨の内容が出た。どうして777のファイルが755で扱われているのか気になって調べてみた。

# Gitはファイルの権限情報を基本は保持しない

- 当たり前と言ったら当たり前なのだがGitはファイルの中身の差分しか基本的に保持しない。
- ただし例外的に`core.filemode`という設定が`true`になっているときだけ権限情報を保持する。
    - `core.filemode`の設定値はローカルリポジトリで`$ git config -l`を実行した出力内容の中に記載されている。
- しかし`core.filemode`が`true`になっていようともGitが管理する権限はファイル所有者の権限が「読み書き実行（7）」かどうかのみ保持する。

# そもそもファイルの権限とは

- Linuxのファイルの権限は下記の3種類である。
    - 読み
    - 書き
    - 実行
- その権限にはそれぞれ整数が振られている。
    - 読み → 1
    - 書き → 2
    - 実行 → 4
- 権限は整数の足し算で表される。
- 例えば「読み、書き、実行」権限がある場合「1 + 2 + 4 = 7」ということになる。
- Linuxのファイルに対するユーザーは書きの3種類である。
    - 所有者
    - 同グループユーザー
    - その他ユーザー
- Linuxのファイル権限は必ず「3種類のユーザー」に対して設定され、「所有者、同グループユーザー、その他ユーザー」の順番で表される。
- 例えば下記のような権限のファイルがあったとする。
    - 所有者が「読み書き実行（7）」できる
    - 同グループユーザーが「読み実行（5）」できる
    - その他ユーザーが「読み実行（5）」できる
- その場合当該ファイルの権限は「755」となる。

# `core.filemode`が`true`だったとして

- 設定がONだったとしてもファイル所有者の権限がファイル所有者の権限が「読み書き実行（7）」かどうかのみGitは保持すると記載した。これはどういうことなのか。
- これは例えば「721」という権限のファイルだった場合、頭の7、つまり当該ファイルの所有者の権限が「読み書き実行」かどうかだけを保持する。
- そしてGitは権限の頭の数値が7の場合、強制的に「755」として保持する。
- なのでファイル権限が「777」だろうが「711」だろうが「741」だろうが頭の数値が7の場合必ず「755」として保持する。
- 逆に頭の数値が7以外の場合、権限が何であろうとも「644」として保持する。

# まとめ

- Gitは基本権限情報を保持しない。
- `core.filemode`という設定が`true`になっていると権限情報を保持する。
- ただし、ファイル所有者の権限が「読み書き実行（7）」かどうかしか保持しない。
- ファイル所有者の権限が7の場合Gitは「755」として権限を保持する。同グループユーザーやその他ユーザーの権限は何であれ関係ない。とにかく権限の頭が7なら「755」として保持する。
Rubyのセットアップ(WSL)

## 背景
Java,C#,VB.NET,Swift,Rust,TypeScript,Pythonなどは書いたり環境構築したことがあるが(Pythonはちょっと経験少ないが)、Rubyはまだまともに書いたことなかったので、Hello Worldくらいやってみようと思ったのでちょっとやってみる。
最近は環境構築はDockerのほうがいいかもだけども。

## 環境
- WSL2(Ubuntu22.04)

## 手順

### 1. パッケージ更新して、rbenv を入れる。

`apt-get install rbenv`すると、ちょっと古いやつが落ちてくるので、git cloneする

```bash
$ sudo apt-get update
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
```

### 2. パス設定 & 反映
```bash
$ echo 'eval "$(~/.rbenv/bin/rbenv init - bash)"' >> ~/.bashrc
$ source ~/.bashrc
```

### 3. ruby-buildを入れる
```bash
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
```

### 4. libyaml-devを入れる
ruby3.2系をいれる際には別途インストールが必要になったらしいとのこと
```bash
$ sudo apt install libyaml-dev # ubuntuだと -dev をつけたパッケージ名らしい
```
### 5. rubyをいれる
```bash
$ rbenv install 3.2.2 # 2023.08.08の最新っぽいやつ
```

##### (補足) libyaml入れてないとエラーで落ちる
```bash
BUILD FAILED (Ubuntu 22.04 using ruby-build 20230717-11-g4d4678b)

Inspect or clean up the working tree at /tmp/ruby-build.20230808232212.1709.r0qEPi
Results logged to /tmp/ruby-build.20230808232212.1709.log

Last 10 log lines:
*** Fix the problems, then remove these directories and try again if you want.
make[1]: Leaving directory '/tmp/ruby-build.20230808232212.1709.r0qEPi/ruby-3.2.2'
Generating RDoc documentation
/tmp/ruby-build.20230808232212.1709.r0qEPi/ruby-3.2.2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
make: *** [uncommon.mk:598: rdoc] Error 1
```

#### 6. 一旦確認
```bash
$ rbenv local 3.2.2
$ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
$ echo "print \"Hello World\"" > hello.rb
$ ruby hello.rb
Hello World
```

## Railsの設定
### 1. bundlerのインストール
```bash
$ sudo gem install bundler
```

### 2. 適当なディレクトリでinitして、Gemfileを修正
```bash
$ bundler init
```

``` title:Gemfile
gem "rails" # add this line
```

### 3. ruby-devをいれる
```bash
$ rbenv install 3.2.0-dev
```
### 4. install
これでrailsがインストールされる
```bash
$ bundle install
```

### 5. 適当なディレクトリでrailsのプロジェクト作成
```bash
$ rails new .
```
### 備考
けっこう環境構築ハマりどころが多いな、ruby。
【初投稿】物理削除と論理削除について

# 初めに

私、約1年ほど前に本格的にプログラミングをやり始めた身でございます。
技術記事もこれが初めてでどのように書いた良いのか、模索中でございます。
拙い文章になってしまうかもしれませんが、何卒よろしくお願い申し上げます。

# 私の紹介
名前：ヨシキックス
年齢：20代
生息地：関西地方

現在、エンジニアを目指して、日々勉強中でございます。
前置きはここまでにして、本題に入りたいと思います。


## 経緯

現在、とある学習サイトにてJavaのSpring Boot というフレームワークを使って学習しております。その中で、データベース(以下、DBと略す)の物理削除と論理削除のやり方・考え方について備忘録または誰かの問題解決のヒントとして残せたらと思い、当記事を投稿しました。

### 物理削除

DBにおいてDELETE文などを実行し、データまたはレコードを直接消してしまう方法。

<br>

<br>

例) EMPLOYEESテーブル(社員テーブル)


### Before


|ID | NAME|AGE|DEPARTMENT| POST|
| -- | -- | -- | -- | -- |
| 1 | 山田太郎| 22 |  営業部  | -|
| 2 | 田中次郎| 30 |  総務部  | 課長|
| 3 | 高橋三郎| 25 |  製造部  | 主任|
| 4 | 鈴木四郎| 45 |  設計部  | 部長|
| 5 | 佐藤花子| 22 |  経理部部  | -|



``` sql
-- 社員テーブルの4と5のレコードを削除するsqlを実行
DLETE FROM EMPLOYEES WHERE ID = 4 OR ID = 5;

```

### After

|ID | NAME|AGE|DEPARTMENT| POST|
| -- | -- | -- | -- | -- |
| 1 | 山田太郎| 22 |  営業部  | -|
| 2 | 田中次郎| 30 |  総務部  | 課長|
| 3 | 高橋三郎| 25 |  製造部  | 主任|

このように、テーブルのデータ自体を削除する。

### メリット

・DBのパフォーマンス向上


### デメリット
・一度、消すと修復が困難

### 論理削除


論理削除はデータ自体は削除しないが、システム上では消したように見せかける方法。


<br>

<br>

例) EMPLOYEESテーブル(社員テーブル)


### Before


|ID | NAME|AGE|DEPARTMENT| POST| DELETED_AT |
| -- | -- | -- | -- | -- | -- |
| 1 | 山田太郎| 22 |  営業部  | -| NULL |
| 2 | 田中次郎| 30 |  総務部  | 課長| NULL |
| 3 | 高橋三郎| 25 |  製造部  | 主任| NULL |
| 4 | 鈴木四郎| 45 |  設計部  | 部長| NULL |
| 5 | 佐藤花子| 22 |  経理部部  | -| NULL |



``` sql
-- 社員テーブルの4と5のレコードを論理的に削除するsqlを実行
UPDATE EMPLOYEES SET DELETED_AT  = NOW() WHERE ID = 4 OR ID = 5;

```

### After

|ID | NAME|AGE|DEPARTMENT| POST| DELETED_AT |
| -- | -- | -- | -- | -- | -- |
| 1 | 山田太郎| 22 |  営業部  | -| NULL |
| 2 | 田中次郎| 30 |  総務部  | 課長| NULL |
| 3 | 高橋三郎| 25 |  製造部  | 主任| NULL |
| 4 | 鈴木四郎| 45 |  設計部  | 部長| 実行した日時 |
| 5 | 佐藤花子| 22 |  経理部部  | -| 実行した日時 |

<br>

このように、データ自体は残っているが、レコードを `UPDATE` することにより、削除対象とそれ以外の切り分けを行うことが出来る。あとはプログラム自体に、`DELETED_AT` が `NULL` でなければシステム上から見えなくする処理を実装すれば、削除したように見せかけることが出来る。

### メリット

・データの修復が容易

### デメリット

・データが増えることによってはパフォーマンスの低下する恐れがある



# まとめ

初投稿でどういったものを書けばいいか、わからなかったが今回は物理削除や論理削除などのDB関係の知識は今後、エンジニアになるうえでは大事なってくるので、こういった機会に情報の整理をしっかりして理解に努めたいと思いました。

# まとめ

- [論理削除と物理削除の違い](https://qiita.com/miyuki_samitani/items/4b7b1ed0202d48171030)

- [SQL で理解する DB の物理削除と論理削除](https://zenn.dev/kotahashihama/articles/f9676a52bd83c9)
【TailwindCSS】font-familyの設定方法


## `tailwind.config.js`に`fontFamily`を記述する

`tailwind.config.js`に以下のように`fontFamily`を追記します。


```js:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        body: [
          'Helvetica Neue',
          'Arial',
          'Hiragino Kaku Gothic ProN',
          'Hiragino Sans',
          'Meiryo',
          'sans-serif',
        ],
      },
    },
  },
}
```

`body`の部分は`body`以外の名称でも大丈夫です。

## クラスを適用する

上記の設定をすると`font-body`が使用できるようになるのでこれを`class`に記述します。

```index.html
<html>
  <!-- ... -->
 <body class="font-body">
  <!-- ... -->
 </body>
</html>
```

## 参考

https://tailwindcss.com/docs/font-family#customizing-your-theme
PF作成：８日目

予想はしていたが、今日は学習時間が確保できなかった。こういう日もあるとは思うが、焦りが出てしまう。

## 進捗
- サイドバーのレイアウトに着手


## 学習
- ブートストラップがおかしな動きをしていたら、閉じタグがおかしい場合が多いので、閉じタグを確認する。
- lg md sm　の使い方。ブートストラップの基本的な考え方の一つで画面を１２分割するという考え方があるらしい。lgが一番大きい分割方法で　lg-3などのように設定すると3/12というような考え方をするらしい。そしてレスポンシブで対応しきれなくなるとlg-3と記述されていても次のサイズであるmd-12が使用されるらしい。基本的な考え方はなんとなく理解できたが、使いこなすにはまだまだ慣れが必要。
- wー２５などの記述は画像サイズを指定するものでは実際ではないらしい。だが、画像のクラスに直接指定してあげることで簡単に画像サイズは変更できる。変更サイズは（２５、５０、７０、１００）
- デフォルメ日本地図の導入<br>
（参考資料：https://kinocolog.com/pref_select/）<br>
参考資料をもとに作成して、HTMLで記述していたコードをRubyの記述へ変更。それとCSSファイルを反映させるためにスタイルシートファイルをapp/assets/stylesheets の下に作成し、反映させたいファイルに<%= stylesheet_link_tag "custom", :media => "all" %>を記述して反映させることに成功。<br>（参考資料：https://materializer.co/lab/blog/25）


## 明日の予定
今日は全然進まなかった上に、ここ３日間くらい寺社投稿ページで止まっているので、明日はここを完成させて次へ進みたい。<br>なので明日の予定としては寺社投稿ページのレイアウトを整えるのと、サイドバー二つ。検索のサイドバーとユーザー詳細サイドバーのレイアウトだけでも完成させることを目安に頑張っていこう。
Rviz視点変更のコードを読む

# はじめに

Rvizの視点変更の動きが良いなと思い、内部の計算を見てみることにしました.
調査対象の視点タイプは`Orbit`というものでデフォルトで指定されている視点タイプのものです.

# 調査結果(UI側)

### parameter
`Oribit`視点の持つパラメータについて主要と思われるものを列挙します.
- `Distance`: 対象までの距離
- `Yaw`: 視点 横回転 (範囲：0 ~ 6.28)
- `Pitch`: 視点 縦回転 (範囲：-1.54 ~ 1.54)
- `Focal Point`：焦点位置
### 挙動

- 左クリック：回転
- 右クリック + マウス：Z移動
- shift + 左クリック + マウス：X/Y移動


# 調査結果(コード)

[orbit_view_controller.cpp
](http://docs.ros.org/en/jade/api/rviz/html/c++/orbit__view__controller_8cpp_source.html) より

### 視野の回転

マウスの移動による視野の回転はxの移動量に対して,`Yaw`をyの移動量に対して`pitch`を増減させることでおこなっています.

```cpp
00129   else if( dragging_ && event.type == QEvent::MouseMove )
00130   {
00131     diff_x = event.x - event.last_x;
00132     diff_y = event.y - event.last_y;
00133     moved = true;
00134   }
00135 
00136   // regular left-button drag
00137   if( event.left() && !event.shift() )
00138   {
00139     setCursor( Rotate3D );
00140     yaw( diff_x*0.005 );
00141     pitch( -diff_y*0.005 );
00142   }
```

次は、設定された`yaw`,`pitch`,`distance`がどのようにカメラの位置、姿勢に変換されているかを見ていきます.

まず、位置については以下のように計算されます.
```cpp
00254   float x = distance * cos( yaw ) * cos( pitch ) + focal_point.x;
00255   float y = distance * sin( yaw ) * cos( pitch ) + focal_point.y;
00256   float z = distance *              sin( pitch ) + focal_point.z;
```
DiscordのWebhookでNotionのURLがうまく表示されない件の対応メモ


こんな感じの通知を送りたいなと思った時にWebhookで送信するとうまくいかなかったという話です。

- 理想
> ![スクリーンショット 2023-08-05 17.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/9d58ea17-69ef-53fd-b189-ef7b5fc3c880.png "スクリーンショット 2023-08-05 17.38.34.png")

- 現実
> ![スクリーンショット 2023-08-08 23.29.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/6225e0f6-ed7b-42da-1840-20785c086c00.png "スクリーンショット 2023-08-08 23.29.57.png")

こんな感じでURLがうまく表示されません。

表示されないだけでなくクリックしても無効なリンクになってしまっています。

## NotionのページURLに`-_-`という箇所がある

実際には`_`が悪さをしてそうでした。

以下はコードの試した時の一部抜粋です。

- パターン1

```js
const sendMsg = `[最終更新: ${editTimeJP}] ${studentName}さんのページ（ ${update.url}）を${update.block.last_edited_user?.name}さんが更新。 ${update.block.text} \n\n`;
```

- パターン2

```js
const sendMsg = `[最終更新: ${editTimeJP}] ${studentName}さんの[メンタリング情報](${update.url})を${update.block.last_edited_user?.name}さんが更新。 ${update.block.text} \n\n`;
```

という感じで`( https://~~~~~ )`やマークダウンにして`[テキスト](https://~~~~~)`といった指定でもうまくいかず、最初に貼った画像のように`_`が消え去ってURLは開けない状態になってました。


## ユーザー名にも_が含まれていた

`PO0000-○○さん_詳細`といったDBのレコードタイトル付けになっていて、`PO0000-○○さん_詳細さんの情報を更新しました。 https://hogehoge.com/hoge-_-hogehoge` といったURLになっていました。

これによって_と_で囲まれる部分が発生してマークダウンとして機能してしまってうまく表示できない といった状態になってました。

```js
const sendMsg = `${studentName}さんの_[対象ページ](${update.url})  \n`;
```

といった形で`_`をつけた上でURLを展開するとURLの展開前に一旦`_`のブロックが閉じられるので次のURL部分はちゃんとURLとして認識されるといった流れのようでした。

SQLインジェクションっぽいですね。

## ユーザー名側の`_`を先に消しておく

結果どうなったかというと、ユーザー名側の"_詳細"の部分をsplitして削除する処理を挟み、、

```js
const studentName = (update.studentName) ? update.studentName.split('_')[0] : '';
```

マークダウンの`[テキスト](URL)`の形式にしてあげることで回避できました。

```js        
const sendMsg = `[最終更新: ${editTimeJP}] ${studentName}さんの[メンタリング情報](${update.url})を${update.block.last_edited_user?.name}さんが更新。 ${update.block.text} \n\n`
```

## まとめ - `_`が入るURL注意

1回のDiscord Webhookに送る文章を複数の変数を展開して作る時には`_`などが含まれてしまってないかを確認しましょう。自戒。

`~`はURLになることはほぼない気もするけど、`*`や`-`や`_`は注意したいなと思いました。

https://www.ipentec.com/document/web-url-invalid-char
Google CloudでVMインスタンスを立てて、HTTPサーバを設定する方法(CLI)


# Google CloudでVMインスタンスを立てて、HTTPサーバを設定する方法(CLI)

## 目次

1. [導入](#導入)
2. [gcloudの設定](#gcloudの設定)
3. [VMインスタンスの作成](#vmインスタンスの作成)
4. [HTTPサーバの設定](#httpサーバの設定)
5. [余談](#余談)

## 導入 <a name="導入"></a>

Google CloudでHTTPサーバを立ててみました。

**注意：** 今回はdefault VPCを利用します。あと筆者は基本的にマネコンに疎いので、GCloudでの操作が基本です。

## gcloudの設定 <a name="gcloudの設定"></a>

まず、Google Cloud Shellを起動します。ここでは、gcloudの設定を行います。

Cloud Shellをアクティブにするをクリックし、CloudShellを開きましょう。何か確認メッセージが出てきたら適当に許可しましょう()

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113287/df41cfcb-88a9-a511-2a8f-01bed476663b.png)


```shell
gcloud config set project my-project-id
gcloud config set compute/zone asia-northeast1-b
```

- `my-project-id`：GCPプロジェクトIDを設定します。
- `asia-northeast1-b`：zoneを設定します。

以下で確認ができます。
```shell
gcloud config list compute/zone
```
下みたいな結果が返ってきます。
```shell
[compute]
zone = asia-northeast1-b

Your active configuration is: [cloudshell-xxxxx]
```

## VMインスタンスの作成 <a name="vmインスタンスの作成"></a>

次に、Google CloudのCompute Engine上にVMインスタンスを作成します。以下のコマンドを実行してください：

```shell
gcloud compute instances create my-http-server --machine-type=e2-medium --image-family=debian-10 --image-project=debian-cloud
```

このコマンドのパラメータは以下の通りです：

- `my-http-server`：作成するインスタンスの名前
- `e2-medium`：インスタンスのマシンタイプ
- `debian-10`：使用するOSのイメージファミリー
- `debian-cloud`：使用するOSのイメージプロジェクト

結果は以下のような感じです。
```shell
Created [https://www.googleapis.com/compute/v1/projects/deductive-state-xxxxxx/zones/asia-northeast1-b/instances/my-http-server].
NAME: my-http-server
ZONE: asia-northeast1-b
MACHINE_TYPE: e2-medium
PREEMPTIBLE: 
INTERNAL_IP: YOUR_PRIVATE_IP
EXTERNAL_IP: YOUR_PUBLIC_IP
STATUS: RUNNING
```
また念のため、作成されたインスタンスを確認しましょう。
```shell
gcloud compute instances list --filter="name:my-http-server"
```
```shell
NAME: my-http-server
ZONE: asia-northeast1-b
MACHINE_TYPE: e2-medium
PREEMPTIBLE: 
INTERNAL_IP: YOUR_PRIVATE_IP
EXTERNAL_IP: YOUR_PUBLIC_IP
STATUS: RUNNING
```
が返ってくるはずです。

## HTTPサーバの設定 <a name="httpサーバの設定"></a>

次に、作成したVMインスタンス上でHTTPサーバを設定します。以下のコマンドを実行して、VMインスタンスにSSH接続します：

```shell
gcloud compute ssh my-http-server
```

次に、以下のコマンドを実行してApache HTTPサーバをインストールします：

```shell
sudo apt-get update
sudo apt-get install apache2 -y
```

Apache HTTPサーバが正常にインストールされたはずです。

```shell
curl localhost:80
```
これでApacheのデフォルトのhtmlが返ってきたら成功です。

##後片付け
最後に作成したインスタンスを削除しましょう。
```shell
gcloud compute instances delete my-http-server
```
念のため確認。
```shell
gcloud compute instances list --filter="name:my-http-server"
```
以下結果。
```shell
Listed 0 items.
```


## 余談
以下のコマンドを使用することでstartup-script(インスタンス起動時に実行されるスクリプト)でApacheサーバを起動できます。
```shell
gcloud compute instances create my-http-server \
--machine-type=e2-medium \
--image-family=debian-10 \
--image-project=debian-cloud \
--metadata=startup-script='#! /bin/bash
sudo apt-get update
sudo apt-get install apache2 -y'
```
【C++】opencvを導入する【手順書】

## 概要
Visual Studio(2022)にOpenCVを導入するまでのステップを記します。
ざっくりしてます。

## 前提条件
Visual Studio 2022をインストールしていること

## 手順

### OpenCVをダウンロードしよう

下記URLからOpencvをダウンロードしましょう。
.exeを実行して、ファイルを展開します。
opencvフォルダが生成されると思うので、好きな場所に置きましょう。
(この記事ではCドライブ直下に置きます)

https://opencv.org/releases/

### OpenCVを使うための設定
OpenCVをVisual Studioで利用するために、環境変数の設定を行う。
システム環境変数の「Path」に「(opencvフォルダをおいた場所)/\build\x64\vc16\bin」を記述する。


### VisualStudio側の設定
任意のソリューションを開いて、
メニューの「プロジェクト」→「(プロジェクト名)のプロパティ」を選択する。

「C/C++」→「全般」を選択し、
「追加のインクルードディレクトリ」に「 C:\opencv\build\include 」を記述。

![include.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942596/51d3f479-03cf-8c77-9219-f7e9d72fa4a8.png)

同じプロパティのページで「リンカー」→「全般」を選択し、
「追加のライブラリディレクトリ」に「 C:\opencv\build\x64\vc16\lib 」を記述。

![add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942596/4d6b8a10-8e09-732e-3643-0a7beb1cbda1.png)

---
以上となります。
後は
``` 
#include<opencv2/opencv.hpp>
```
なり
```
#ifdef _DEBUG
#pragma comment(lib, "opencv_world480d.lib")
#else
#pragma comment(lib, "opencv_world480.lib")
#endif
```
なりお好きに設定して実装してください。
以上です。
【メモ】Auroraマイナーバージョンアップ

## バージョンの見方
Auroraバージョンでは、major.minor.patch スキームを使用する。
Aurora PostgreSQL バージョン例 : 14.3.3、13.7.3、12.11.3、11.16.3、10.21.3


## Aurora PostgreSQL DBクラスターのエンジンバージョンをアップグレードする手順
1.AWS Management Console にサインインし、Amazon RDS コンソール (https://console.aws.amazon.com/rds/) を開く。
2.ナビゲーションペインで、[データベース] を選択して、アップグレードする DB クラスターを選択する。
3.[Modify] (変更) を選択します。[DB クラスターの変更] ページが表示される。
4.[Engine version] (エンジンバージョン) で、新しいバージョンを選択する。
5.[続行] を選択して、変更の概要を確認する。
※変更をすぐに反映させるには、[Apply immediately] を選択する。
しかし、このオプションを選択すると、停止状態になる場合があるため注意。
6.確認ページで、変更内容を確認し、正しい場合は、[クラスターの変更] を選択して変更を保存する。
変更内容に間違いがある場合は、[戻る] を選択して変更を編集するか、[キャンセル] を選択して変更をキャンセルする。

## レコメンデーション
RDSコンソールを使用して、設定のレコメンデーションメニューを開くことにより、Aurora PostgreSQL DBクラスターで使用可能なアップグレードまたはパッチを特定することができる。
そこには、古いマイナーバージョンなど、さまざまなメンテナンスの問題のリストを確認できる。
本番環境に応じて、アップグレードをスケジュール(メンテナンスウィンドウ)するか、[今すぐ適用] を選択することですぐにアクションを実行することを選択可能。
メンテナンスウィンドウの自動アップグレードが無効でもマイナーバージョンアップが可能。
マイナーバージョンアップ後も自動アップグレードが有効になったりはしない。
SQLで「変更があった場合だけUPDATEする」テクニック！効率的なデータ更新方法をマスターしよう


更新操作が一般的なデータベース作業であることは誰もが知っていますが、変更があった場合だけ更新を行う方法はどうでしょうか？この記事では、無駄な更新を減らし、パフォーマンスを向上させる効率的な方法を紹介します。

## 目次
1. [はじめに](#introduction)
2. [基本的なUPDATE構文](#basic-update)
3. [変更があった場合のみの更新](#conditional-update)
4. [実際の例](#example)
5. [まとめ](#conclusion)

### <a name="introduction"></a>1. はじめに

データベースにおける更新操作は一般的ですが、常に必要なわけではありません。特定の条件下でのみ更新を行いたい場合、どうすればよいのでしょうか？この記事でその答えを見つけましょう。

### <a name="basic-update"></a>2. 基本的なUPDATE構文

一般的なUPDATE文の例を見てみましょう。

```sql
UPDATE employees
SET salary = 50000
WHERE department_id = 10;
```

このクエリは、部門IDが10のすべての従業員の給与を50,000に設定します。

### <a name="conditional-update"></a>3. 変更があった場合のみの更新

では、新しい給与が現在の給与と同じでない場合にのみ更新を行いたい場合はどうでしょう？

```sql
UPDATE employees
SET salary = new_salary
WHERE salary != new_salary AND department_id = 10;
```

このクエリは、部門IDが10で、現在の給与と新しい給与が異なる従業員だけを対象に更新します。

### <a name="example"></a>4. 実際の例

例として、以下のデータがあるとします。

| id | name  | salary | department_id |
|----|-------|--------|---------------|
| 1  | Alice | 40000  | 10            |
| 2  | Bob   | 50000  | 10            |

新しい給与が50,000である場合、上記のクエリはBobのレコードのみを更新します。

### <a name="conclusion"></a>5. まとめ

変更があった場合のみの更新は、無駄な操作を減らし、データベースの効率を高める素晴らしい方法です。このテクニックをマスターすることで、より洗練されたデータベース操作が可能になります。

---

この記事を気に入った方は、いいねやシェアをお願いします！
laravel Mix と viteの違い

仕事でLaravelを使う機会が多いのですが、
最近Laravelの知識をアップデートできていないなぁと感じ、自己学習でLaravel10を触っている者です。
学習を進めていく中で、LaravelのデフォルトビルドツールがLaravel MixからViteに変わったことを知り、Viteとは?となったので、調べてみました。


# Laravel Mixとは（振り返り）

Laravel Mixとはなんだったか。
Laracastsを作ったJeffrey Wayが開発したパッケージで、中身はwebpackです。
Laravel Mixを使用すると、アプリケーションのCSSファイルとJavaScriptファイルを簡単にコンパイルして圧縮できます。

webpack.mix.jsにエントリポイントを設定することで、コンパイル/バンドルを行うことができます。

sass（コンパイル）
`mix.sass('resources/sass/app.scss', 'public/css');`

js（バンドル）
```
mix.js([
  'src/test_1.js',
  'src/test_2.js'
], 'dist/bundle.js');
```

Laravel Mixについてもっと知りたい方はこちら。
https://qiita.com/minato-naka/items/bfc3bbd9a388084e6f17

# Viteとは

Viteとは何ぞやというと、webpack や Rollup、Parcelのようなビルドツールの1つ。
これらの役割としては、プロジェクトすべてのファイルをコンパイル・結合して一つの塊（バンドル）となったファイルを生成してくれます。
※ちなみにVite(ヴィート)はフランス語で「素早い」という意味の単語

前述した通り、Laravelのバージョン9.18以降はViteがデフォルトビルドツールとなっているので、
create-projectしたらすぐ使えます。
※Laravel Breezeも結構便利で、Reactの勉強に使っています。


Viteがwebpackなどの従来ツールより高速となっている理由は2つ。
1. HMRが全てのソースコードを同時に読み込むのではなく、修正された部分のみを読み込むから
2. Viteは、依存関係の解決をesbuildで事前バンドルするようしており、これにより、多くの内部モジュールを持つ依存関係を単一のモジュールに変換して、その後のページロードのパフォーマンスを向上させている。
※最終的なビルドには、esbuildではなくRollupを用いている。
　現状Rollup の方がパフォーマンスと柔軟性のトレードオフに優れているからとのこと。
　将来的にはesbuildが使用されることもありそうです。

詳しく知りたい方はこちら
https://ja.vitejs.dev/guide/why.html

### 推奨環境

LaravelでViteを動かすためにはこちらのバージョンが必要。
PHP 8.0 以上
Node 16 以上

・Viteが使用できるブラウザ
Native ESMをサポートしているブラウザを対象としています。
IE11はデフォルトでは対象外。
※IE11で使用できるようにする方法設定はある。
https://ics.media/entry/210708/#contents-anchor-ie11

### 導入手順
Viteをとりあえず試してみたいという方向けの導入手順。

一旦Nodeのバージョン確認。
バージョンが古い場合はアップデートしましょう。
```
node --version
```

下記のnpmコマンドを実行
```
npm create vite@latest
```

プロジェクト名やテンプレのオプションをつける場合
```
# npm 6.x
npm create vite@latest my-app-name --template react

# npm 7+ は追加で 2 つのダッシュが必要
npm create vite@latest my-app-name -- --template react
```

フレームワークを選択
```
? Select a framework: › - Use arrow-keys. Return to submit.
   vanilla
    vue
❯   react
    preact
    lit
    svelte
```

作成されたプロジェクトフォルダに移動して、初期インストール
```
cd my-app-name
npm install
```

後は、動作を確認する場合
```
npm run dev
```

本番用にビルドする場合
```
# dist/ディレクトリに吐き出される
npm run build
```


### Viteの注意事項

ViteはTypeScriptをサポートしてますが、型チェックは行ってくれないので注意が必要です。 
型チェックはIDE とビルドプロセスによって処理してねとのこと。
※型チェックを行うと、Viteの持ち味である速さが損なわれてしまうらしいです。

## 所感
プロジェクトの規模が大きくなればなるほど、Viteの速さは活きてくるかもしれないです。
個人開発レベルの小さなシステムだと、実感しにくいかもしれないです...
フロントに力を入れた開発をあまり行ったことがないので、Laravel Mix（webpack）にストレスをそもそも感じていないからかも。


## 参考サイト
- Vite公式ドキュメント
- Laravel Mixとは？webpackをより便利に、簡単に。Laravel以外でも使えるよ。
- jQueryからTypeScript・Reactまで！Viteで始めるモダンで高速な開発環境構築