OmniAICreator/Qiita-1.07M huggingface dataset:
beforeCreate


## beforeCreate

beforeCreateフックははインスタンスが生成され始めた直後に呼び出される。
つまりインスタンスが初期化される前に呼び出されるのでdataオプションに記述されてる
データの更新や参照はできない。
100分は一件にしかずということで実際にやってみた

以下のコードは単純でbeforeCreateでdataのmessageを呼び出している
↑のbeforeCreateフックの説明が正しけばdataオプションはまだ初期化されてないので
undefindが出力されるはず

```vue
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'test'
    };
  },
  // インスタンスが初期化する前に呼び出される
  beforeCreate() {    
    console.log(this.message)
  }
};
</script>
```
出力結果
```bash
undefined
```
想像の通りundefindが出力された

で、次は更新してみよう。<br />
beforeCreate内でmessageの値を'Test Message'に更新して出力してみる。
データ初期化前にデータを更新しようとしたら恐らくReferenceError、TypeError
等になるはず
実際に試し目見る

```vue
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'test'
    };
  },
  // インスタンスが初期化する前に呼び出される
  beforeCreate() {
    this.message = 'Test Message'
    console.log(this.message)
    
  }
};
</script>
```
出力結果
```bash
Test Message
```
ファ！？！？！？！？更新されてる！？！？

この現象について調べてみたけどあまりピンとくる記事がなかったのでChatGPTさんに質問した<br />
↓GPTさんによる考察

```
beforeCreate フック内で this.message の更新が実行されているように見えますが
それは Vue.js の内部的な仕組みやブラウザの実行環境により、意図せず動作している可能性があります。
これは、Vue の一部のバージョンや特定のブラウザ環境では発生する場合がありますが
Vue の仕様上は beforeCreate フック内で data プロパティに依存しないのが原則です。
```
とのことです。
まあそもそもインスタンス初期化が完了する前にbeforeCreateでdataオプションの値を更新することなんて滅多にないと思うのでdataオプションの更新は大人しくcreated以降のフックで行うようにしましょう。
【 一発合格】情報処理安全確保支援士の勉強方法と教材まとめ

# 目次
[1.はじめに](#はじめに)
[2.教材紹介](#教材紹介)
[3.スケジュール](#スケジュール)
[4.おわりに](#おわりに)

# はじめに
これから情報処理安全確保支援士を受験しようという方の一助となるよう、私が実施した勉強方法を紹介します。

結論を言うと、以下の記事で紹介されている方法を基本に進めて合格しました。
リンク先の記事は2年近く経過していますが、方法論としては全く廃れていないです。

https://qiita.com/shiva_it/items/7caec8799dca78db313e

# スペック
業界5年目で今は情シスに身をやつしています。元々はバリバリの開発畑でしたが、キャッチアップのために情報処理試験はなるべく受けるようにしています。開発時代にサーバーを触ることがあったのと、ネットワークについて仕事上触ることになるのである程度は知識がある状態でした。

今回受験しようと思ったのは、業務上、ISMSの関係でセキュリティのトピックを（不本意ながら）扱う機会が多く、その知識補完と権威付けのために情報処理安全確保支援士を受験することにしました。

2021年に応用情報に合格してますが、3年経過してますので午前Ⅰは免除ではありませんでした。

# 教材紹介

## 午前I対策
ここはもうみんな大好き過去問道場だけ。自分の周りでこれをやってない人は見たことがないです。
応用情報や他の高度試験を合格された方であれば、大体のトピックは頭にあるかと思うので、参考書を買う必要はないと思います。
私の場合、応用情報を取ってからだいぶ時間が経っていたせいもありAIや映像処理周りで知らない用語が複数あったのでAmazonで購入しましたが、正直ほとんど読んでおらず立ち読みで良かったと思いました。でも買っておくと精神的なお守り代わりにはなるかもしれません。

https://www.amazon.co.jp/%E5%85%A8%E6%96%87PDF%E3%83%BB%E5%8D%98%E8%AA%9E%E5%B8%B3%E3%82%A2%E3%83%97%E3%83%AA%E4%BB%98-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E6%95%99%E7%A7%91%E6%9B%B8-%E4%BB%A4%E5%92%8C7%E5%B9%B4%E5%BA%A6/dp/4295020397/ref=sr_1_5

## 午前Ⅱ
総合的な試験対策本を通読して、一緒に記載されている問題を解きました。

https://www.amazon.co.jp/%E4%BB%A4%E5%92%8C07%E5%B9%B4-%E3%80%90%E6%98%A5%E6%9C%9F%E3%80%91%E3%80%90%E7%A7%8B%E6%9C%9F%E3%80%91%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB-%E5%90%88%E6%A0%BC%E6%95%99%E6%9C%AC-%E5%B2%A1%E5%B6%8B-%E8%A3%95%E5%8F%B2/dp/4297145162

参考書ってざっくり講義形式なのか否かで派閥が別れると思うんですが、私の場合文字数が多いと飽きてしまうので、本屋さんで立ち読みして1番淡々と情報が書かれていると思った上記の本を選びました。
最近の参考書は基本的に出来が良いので、アマゾンレビューが相当酷くない限りはどれを選んでも大丈夫だと思います。レビューに書かれる批判的な意見もほぼ似通ったものなので気にするだけ時間の無駄です。

## 午後対策
まず前提として未経験やネットワークインフラ関連の知識の無い方は、午後対策するのはかなり鬼門なのでまずはこちらでネットワークについて勉強しておくことをお奨めします。

https://www.amazon.co.jp/%E5%9B%B3%E8%A7%A3%E5%85%A5%E9%96%80TCP-IP-%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E5%8B%95%E4%BD%9C%E3%81%8C%E8%A6%8B%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8B-%E3%81%BF%E3%82%84%E3%81%9F-%E3%81%B2%E3%82%8D%E3%81%97/dp/4815604975/ref=sr_1_1

資格試験はとにかく早めに過去問を解くことが早道なので、午前対策の参考書を読んだ後すぐに過去問を1年分解きました。過去問はIPAからダウンロードしました。問題に対する解説は掲載されていませんが、どうせこの時点では正答率など30%も行かないので別になくても良いです。

過去問にてどんな問題が出るかの感触をつかんだあと、午後の対策として下記を使用しました。

https://www.amazon.co.jp/2025-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB%E3%80%8C%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98-%E5%8D%88%E5%BE%8C%E5%95%8F%E9%A1%8C%E3%80%8D%E3%81%AE%E9%87%8D%E7%82%B9%E5%AF%BE%E7%AD%96-%E4%B8%89%E5%A5%BD%E5%BA%B7%E4%B9%8B/dp/4865753370/ref=sr_1_7

こちらの本、各技術に対して細かい知識まで網羅されていて非常に良かったです。
そのあとは気になる年度の過去問をIPAからダウンロードしてちょろちょろと解き、本番に挑みました。

# スケジュール
私の場合、午前Ⅰの免除が受けられなかったので、対策のために時間を多めにとって3か月前から開始しました。

### 3ヶ月前～2ヶ月前
- 過去問道場：応用情報技術者試験 午前試験 過去問 10回分
- 過去問道場：情報処理安全技術者試験 午前試験 過去問 10回分 

### 2ヶ月前～1ヶ月前
- 参考書通読
- 過去問 1回分
- 重点対策本の問題解く

### 1ヶ月前～直前

- 午後Ⅰ過去問 4回分
- 午後Ⅱ過去問 3回分くらい

# 反省
午前Ⅰの免除が無かったのは想像以上に苦行でした。応用情報や他の高度試験に受かった人は免除があるうちに、早めに情報処理安全技術者を受けられることをおすすめします。

# その後
とりあえずまだ支援士の登録はしてないです。登録料高いし。。。
情報処理安全技術者だけだと少し物悲しいので、他の高度試験受かって名刺作るときに改めて考えます。
Oracle Analytics Cloud：マップに表示したデータポイント選択の可・不可を設定してみる

はじめに
---
2024/3 アップデートから Data Visualizationのマップに表示したデータポイントの選択を可能にするのか、不可能にするのか制御ができるようになりました。例えば複数のマップレイヤーがある場合に、1つのレイヤーを不可にしておくと地図上でのデータポイントを選択する際、選択可能に設定しているレイヤーのデータポイントのみが選択対象となります
設定を試してみます。

![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/3f5cde89-7dca-7bb6-9fe6-b49ce5954fe7.jpeg)

記載時のOACバージョン：OAC 2024 Nov版

前提
---
・ Data Visualizationでワークブックを作ったことがある
・ ワークブック作成で利用するデータセットがある

ワークブックの作成
---
ワークブックを作成します
マップのビジュアライゼーションを追加します
イメージでは県、受注金額を選択、右クリックしてメニューからビジュアライゼーションの選択、マップを追加しています。
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/6842c71a-dd9a-122d-199f-6c8c983edda3.jpeg)

マップ、レイヤーの追加
---
マップのビジュアライゼーションで、作成済のレイヤーの右部にあるメニュー（・・・縦）アイコンをクリック、メニューからレイヤーの追加、データ・レイヤーの追加をクリックします
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/ec2ef116-f798-25f4-cd24-6745d645191f.jpeg)

追加したレイヤーに項目を配置します
イメージでは、市、前年比の項目を追加しています
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/1cc27d62-8b47-f8b6-fdd1-f39e04aca39b.jpeg)

プロパティタブを開き、真ん中の"レイヤー"タブをクリックします。市のレイヤーで、レイヤータイプを点に変更します
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/28e8c9bb-e778-a09b-8ef6-1477c8eacee1.jpeg)

サイズを変更します。イメージでは12に変更しています
![g6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/7d4b62e7-6299-619a-ab92-a96ba7ed86b9.jpeg)

市のレイヤーでデータポイントの選択を不可にします。選択の有効化をオフに変更します
![g7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/09cbbbc9-1fee-fa96-97d9-4e52906c3352.jpeg)

まとめ
---
Data Visualizationのマップに表示したデータポイントの選択を可能にするのか、不可能にするのか制御を実施しました

以上
Cloudflareで取得したドメインをAmazon SESで使う方法

# はじめに
Cloudfrareで取得したドメインを使用して、``no-reply@<取得したドメイン>``のようなアドレスからメールを送付できるように設定したときの備忘録です。


# ドメインの取得
Cloudflareからドメインを取得します。取得方法は以下をご参照ください。

https://www.cloudflare.com/ja-jp/products/registrar/

https://zenn.dev/pino0701/articles/cloudflare_registrar


# AWS SESでのドメイン登録
SESのコンソール > ID > IDの作成から設定を行います。ドメインを選択し、Cloudflareで取得したドメインを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/9d979efb-0b0f-de1a-36e9-53b1080dc3b4.png)

DKIM署名キーの長さはRSA_2048_BIT、DKIM 署名の有効化を選択します。この状態で作成ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/a99cf00f-24bb-c92f-8c59-3d2f8568b2b1.png)

作成が完了するとDKIM欄にDNSレコードのタブが現れます。ここのCNAMEをメモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/324e387a-5e25-dd7e-b789-82463bc054dc.png)

またDMARCについても同様にDNSレコードが発行されるため、これを控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/fd5950cf-96f0-7dae-f8dc-37a1e4c1839d.png)

# CloudflareでCNAME登録
取得したドメインのDNS設定を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/c13856c2-1bbc-dc5f-a8dd-186438e6230f.png)

レコードの追加から、前段でメモしたCNAMEとTXレコードをすべて登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/8ce0d3c3-0de6-52e9-fbff-573dbead547f.png)

登録が完了ししばらくすると、メールアドレスにセットアップ完了の通知が来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/7f5f8301-b249-80c1-7126-ce46442027cf.png)

SESのコンソールからもDKIMのステータスを確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/c630a278-f5f7-c30b-c98f-9817129097d1.png)

# メールテスト
IDページのテストEメールの送信からメールを送信できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/6caba6a3-fbe1-aab9-0abe-6409d49b4b84.png)

``From-addres``には任意の文字を挿入可能です。"no-reply"などを入力しSubmitを行うと、対象のアドレスに``no-reply@<取得したドメイン>``からのメールを受信することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918398/d6ef3ebd-8cc5-f179-3b89-ec383489376d.png)
Mac アプリの終了方法について

この記事はプログラミング学習者がアプリ開発中に躓いた内容を備忘録として記事におこしたものです。内容に不備などあればご指摘頂けると助かります。

生成AIについて学習中にgithub copilot chatを導入することになりました。しかし、導入はしたものの使用しているエディター(VSCode)が最新の状態ではないので、github copilot chatが機能していませんでした。そこでVSCodeを更新しようとしたのですが、エラーが発生。ダウンロードフォルダにVSCodeが入っているので更新できないとのこと。VSCodeをアプリケーションフォルダに移動させると更新することができました。そこで再起動するべく、左上の「❌」ボタンを押しましたが状況は変わりませんでした。アプリはしっかり閉じているのに、、、なぜ、、、更新の内容が反映されないんだ。。。
ここで初めてアプリの再起動方法を調べました。
「❌」を押してるのにおかしいなぁ〜と思いながら。。。
「❌」ボタンってウィンドウを閉じるだけなんですね、知らなかった(ﾊｽﾞｶｼｰ
小さい頃からPCはWindowsしか触ったことがなく、他のOSはFedora, UbuntuなどのLinuxくらいしか触ったことがありませんでした。
約1年前に初めてMacbookAirを買って使い始めたところです。
Windowsの感覚で「❌」ボタンを約1年も使っていました。
Macに慣れてきたとはいえ、まだまだ知らない機能がたくさんありそうです。
その他の機能はプログラミングしながら少しずつMacの使い方も身に付けていきたいと思います。

そして、同じような感覚でMacを使われている方が居るかもしれないなぁと思い、記事を起こすことにしました。

## アプリ終了の方法
#### 1, 左上にあるアプリ名を左クリックして、一番下に表示される`終了`ボタンを押す。
下のサンプル画像では`Quit Visual Studio Code`を押す。

![スクリーンショット 2024-11-26 19.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508918/e1243ab1-0c90-eb40-c0ba-5d635884e576.png)


#### 2, アプリを開いた状態でショートカットキー`Command + Q`を押す。

#### 3, Dock(全体画面の下部)内にある対象アプリのアイコンを右クリック or 長押しでメニューを表示させて一番下に表示される`終了`を押す。
![スクリーンショット 2024-11-26 19.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508918/7763a79e-4647-3262-b851-5492f20cbad5.png)

## おまけ
Dock(全体画面の下部)内に表示されているアイコンのうちアプリが動いているものはアイコンの下にグレーの小さい丸が表示されます。先に紹介した終了コマンドのいずれかを実行すればグレーの小さい丸が消えてアプリが終了したことを確認することができます。
下のサンプル画像ではFinder, Safari, Slack, Visual Studio Codeが起動中であることを確認することができます。

![スクリーンショット 2024-11-26 19.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508918/b7b88939-ef84-3edd-211c-e1d4dd9d3a9c.png)


ここまで記事を読んで頂きありがとうございました。

## 参考にした記事
[Code won't update on macOS
](https://github.com/microsoft/vscode/issues/7426#issuecomment-425093469)
[アプリをウィンドウの左上の赤いバツ印のボタンをクリックして終了すると…](https://discussionsjapan.apple.com/thread/250445725?sortBy=rank)
Laravel11とInertia.js、ReactでStorybookから`public`にある画像を読み込む


# はじめに

こんにちは、エンジニアのkeitaMaxです。

Laravel11とInertia.js、Reactを使用して開発している時、
Storybookから`public`にある画像を読み込むようする方法を備忘録として書きます。

# 内容

`.storybook.ts`ファイルに以下を追加するだけです。

```ts:.storybook.ts
import type { StorybookConfig } from "@storybook/react-vite"

const config: StorybookConfig = {
    stories: [
        "../resources/**/*.stories.@(js|jsx|mjs|ts|tsx)",
        "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
    ],
    addons: [
        "@storybook/addon-onboarding",
        "@storybook/addon-links",
        "@storybook/addon-essentials",
        "@chromatic-com/storybook",
        "@storybook/addon-interactions",
    ],
    framework: {
        name: "@storybook/react-vite",
        options: {},
    },
    staticDirs: ["../public"], // 追加
}
export default config

```

以下のようにコンポーネントで画像を表示できるようにして、Storybookを立ち上げると画像が表示されています。

```ts
<img
 src="/img/test.svg"
/>
```

# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

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

# 参考


https://qiita.com/RYA234/items/0b040132532ea71580f4
AWS network advanced対策 Direct connect 基礎

# 基礎の基礎

まずネットワークの一般的な知識をつけましょう。特にDirect connectではBGPについて知ることが重要です。
次のような動画で、BGPについて理解できます。
このBGPの概要を把握していることがこの後解き進めていくうえで、必須の基礎体力となります。

一言で言うと、BGPがインターネットを作っていると言っても過言ではない、という理解が得られます。

この辺きっちりやっておくと、後半の問題解きまくりフェーズが楽しくなります。
問題解きまくりフェーズで疲弊したら、この辺の動画に戻ってリスニングしながら散歩でもしましょう。

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




ここで広めに基礎をつけておかないと、問題を解いていくうえで、なぜこれが問題になるのか？なぜこの観点が？という根本がわからないまま、解いていく感じになってしまいます。

いったんゆったりめにいきましょう。

そのあと、ブラックベルト動画を見るとベストです。

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

また用語集的に使えるこれもわかりやすいです。

https://aws.amazon.com/jp/directconnect/faqs/


# 用語

次のような用語がよく使われて、問題文でも特に注釈なく出てきます。

・advertise（アドバタイズ）


## アドバタイズ
広報と訳されることもありますが、このカタカナのまま出てくることも多いです。

こんな感じで出てきます。
>AWS Direct Connect を使用してパブリック AWS サービスにアクセスする場合、BGP 経由でアドバタイズするには、パブリック IPv4 プレフィックスまたは IPv6 プレフィックスを指定する必要があります。

https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/routing-and-bgp.html

次の定義を受け取っておきましょう。GCP側の記事ですが。

https://cloud.google.com/network-connectivity/docs/router/concepts/advertised-routes?hl=ja

>アドバタイズされたルートは、BGP ピアにアドバタイズされた Cloud Router BGP プレフィックスです。たとえば、BGP ピアがオンプレミス ネットワーク内のルーターの場合、アドバタイズされたルートにより、オンプレミス ネットワーク内のシステムは VPC ネットワーク内のリソースにパケットを送信できます。




# パス

Direct connetctを二つつくり、一つのDGWに対して
ルートを優先度を決める方法として次のようなものが挙げられます。

・AS_PATH prepend

・specific

・コミュニティタグ

・local preference

## AS_PATH prepend

小さい方の値が優先されます。
つまり、冗長化させた方で、普段は優先的に使わないほうのDirect connectには、大きい値をつけるのです。
次のような値をつけます。

①6500
②6500 6500 6500

この①②の場合どちらが優先されるでしょうか。
答えは①ですね。①の経路が優先されます。

## specific

これは、特に用語ではないのですが、
より細かに指定されている方の経路が優先されます。

subnetで言うと、より細かく切っていたり、/24のように一意に決まるルートが優先されるということです。

## コミュニティタグ

次のような値をつけて優先度を決めることもできます。

>BGPコミュニティのローカル優先度設定
7224:7100 - 優先設定: 低

7224:7200 - 優先設定: 中

7224:7300 - 優先設定: 高

https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/routing-and-bgp.html

この7300が優先設定高となります。
選択肢として与えられるので、7224:7300のような数値は丸暗記する必要はなく、大きい方が優先されるコミュニティタグというようなものがあるのだな、という理解があればよいです。

## local preference
これも数字が大きいほうが優先されます。

## 優先度まとめ

これらの優先度は、
次のような問題で直接的に問われます。
せっかくなので解いてみてください。

https://www.examtopics.com/discussions/amazon/view/116412-exam-aws-certified-advanced-networking-specialty-ans-c01/


# 他にもまだまだある


## いろんな構成図を見ることが重要&用語が重要

パブリックゲートウェイ、プライベートゲートウェイ、カスタマーゲートウェイ、トランジットゲートウェイなど、様々な組み合わせでどれが正しいかを問われます。
色々な構成図を見て、通信経路を頭に入れておきましょう。

暗号化方式(MACsecなど）、LAG、SiteLinkなどここに書かれている内容は全て出題されます。
    https://aws.amazon.com/jp/directconnect/faqs/

あと、ECMP(equal cost multi path)も出ますね。このあたりの基礎的なネットワークの理解が問われる試験です。

#### ポイントはこれらは使ったことがなければ理解しにくい、
#### よって問題を解くことで理解できます！
Sitelinkなんかは読んでもしっくりこないと思います。

site linkの問題はこんな感じです。

簡単め
https://www.examtopics.com/discussions/amazon/view/116845-exam-aws-certified-advanced-networking-specialty-ans-c01/

難しめ
https://www.examtopics.com/discussions/amazon/view/103156-exam-aws-certified-advanced-networking-specialty-ans-c01/

こんな感じで問題ごとに比較することで、抽象的な概念も具体化して理解できます。

transit peeringとかもわかりにくいですね。
次の問題が便利です。




#### 問題を解くことで、理解することができる。
#### 問題は敵ではなく、仲間です。

たぶん。

# 追伸

Gateway load balancer対策してたのに出なかった。
サードパーティのセキュリティアプライアンスでインスペクションできるやつ。
Oracle Analytics Cloud：メニューやメッセージの表示言語を変更する

はじめに
---
2024/3 アップデートから Data Visualizationの表示言語をサインインユーザーのプロファイルで設定できます。従来は、ブラウザの言語設定を変更することでメッセージや、メニューの表示言語を変更できました。明示的に設定していない場合、ブラウザの言語設定で言語が表示されます。加えて、OACのサインインユーザーのプロファイル設定で言語設定ができるようになりました。
表示言語の設定を試してみます。

日本語
![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/74f07497-fd90-69e7-8cb8-7150f92aa4c6.jpeg)

英語
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/abde658c-f3c2-1004-9b29-4f143fe89790.jpeg)

記載時のOACバージョン：OAC 2024 Nov版

前提
---
・OAC EEサービスが作成されている

Data Visualizationの言語設定
---
OACにサインインします
右上部のアカウントアイコンをクリックし、メニューからプロファイルを選択します。
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/35272b3c-1e02-dfd3-335a-4085356e3c05.jpeg)

マイプロファイルで、言語、ロケールを設定します。イメージではそれぞれ"英語"に変更しています
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/4a1a66c4-820e-3d21-651f-c0ae3300a560.jpeg)

「・・・次回ログイン後に有効になります。」とメッセージが表示されます。OKをクリックします。
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/d6abc3e1-b663-e1b0-f115-458f041bed0a.jpeg)

サインアウト後、再度サインインします
メニューや、メッセージがマイプロファイルで指定した言語で表示されます
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/0e96290b-533a-1a31-bfd6-8dd35c8e0618.jpeg)

補足：Classicメニューの表示言語の設定
---
Classic機能は、Classicのマイアカウントで指定します。
Classicの方で、上部右のアカウントアイコンをクリックします。マイ・アカウントを選択します。
![g6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/912a20e9-120e-1f5c-e7ca-c380d3f53825.jpeg)

"プリファレンス"タブで、ロケール、ユーザーインターフェース言語を変更します。イメージは英語に変更しています。OKをクリックします
![g7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/69549385-352b-1b52-e8ae-18f5633345e0.jpeg)

サインアウト後、サインインすると、メニューやメッセージの言語設定が変更されます。
![g8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/e9bd25df-b2e5-b6e5-e022-02d33de6285b.jpeg)

まとめ
---
 Data Visualizationの表示言語をサインインユーザーのプロファイルで設定してみました。また、OAC EEを利用している場合は、Data Visualizationの表示言語に加えてClassic側でも表示言語を設定します。

以上
YouTubeAPIを使用するハンズオン (TypeScript)

# 今回やること
  - google cloudからAPI KEYを作成
  - 公式サイトからサクッとAPIリクエストのURLを取得する
  - 自身の環境でAPIを叩く

具体を下で解説していきます。
公式サイトの「最初の準備」のドキュメントも貼っておきます。
https://developers.google.com/youtube/v3/getting-started?hl=ja#before-you-start

## google cloudからAPI KEYを作成
YouTubeDataAPIはAPI_KEY使用してリクエストします。
OAuth 2.0で認証する方法もありますが、今回はAPI KEYにします。
API KEY(=認証情報)を取得していきます。

google cloudのアカウントを作成し、画面上部の検索から「APIとサービス」を検索し選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/2d7f553a-32d0-20ac-dc13-692ad8dbf7dd.png)

YouTube Data API v3を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/f7f5a917-ca0d-7faf-708e-9b04bee781e8.png)

「認証情報の作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/24da4de1-a2af-5c52-fa40-0aef7bc0e884.png)

基本そのままで完了を押下で大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/30553219-6490-b056-396f-f0f4327354a2.png)

完了を押すと遷移後の画面でAPI_KEYを取得できます。
このAPI_KEYは後からでも閲覧可能です。

## 公式サイトからサクッとAPIリクエストのURLを取得する
今回は人気の動画を取得していこうと思います。
YouTube Data APIのサイトからAPIリクエスト用のURLを取得します。
サイトは以下です。
https://developers.google.com/youtube/v3/docs?hl=ja

左のサイドメニューから動画を選択し、「list (most popular videos)」を押下すると右のインプットに必要なプロパティがセットされます。
これでURLが作成された状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/5563ec5d-1177-3eb9-b668-89d0f301c4c8.png)
executeするとレスポンスが返ってきます。

画面を拡大するとHTTP等でURLが取得できるのでコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810842/58d531fc-f066-12b0-bd8c-2bb786e1a0fe.png)

## TypeScriptでリクエストしてみる
```
import axios from "axios"

const API_KEY = 'xxxxxxxx'
const BASE_URL = `https://youtube.googleapis.com/youtube/v3/videos`

const getVideos = async () => {
  const res = await axios.get(BASE_URL, {
    params: {
      part:'snippet,contentDetails,statistics',
      chart: 'mostPopular',
      regionCode: 'JP',
      key: API_KEY
    }
  })
  console.log(res);
  
}

getVideos()
```

こんな感じでいけます。

## 最後に
google cloudのライブラリとして認証を通せるのを今回初めて知れました。
UIでサクッと認証作れるので非常に楽でした。

参考になれば幸いです。
【FileMaker】API使う？ならPostmanでまずテスト

[FileMaker](https://www.claris.com/ja/) でAPI、叩いてますか？
私は相変わらず叩いてます。
[Claris Connect](https://www.claris.com/ja/connect/)も気になりつつも、スクリプトから叩いてます。

ということで、今回はタイトルの通りですが、この↓一言に限ります。

# FileMakerでAPI使うなら先にPostmanで網羅せよ！

いきなりスクリプトでAPIを実装するのに「[URL から挿入](https://help.claris.com/ja/pro-help/content/insert-from-url.html)」で使うのはあまりいい方法ではないです。
そのやり方は、例えば、キャベツとレタスの区別がつかないのに初めてのレシピで好きピに作ってあげる行為（それはそれでハッピーだが）と等しい、と個人的主観を持っています。

いきなり苦戦するよりは、まずは失敗を許容してくれる踏み台で練習して、好きピに一発で美味しい料理を作ってあげましょう。

その踏み台が、

[Postman](https://www.postman.com/)

です。

# FileMaker屋さんはPostmanをどう使う？

こちらは、shopify APIをFileMakerに組み込んだときに使っていたPostmanのshopifyコレクションです。
![スクリーンショット 2024-11-26 19.13.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/4c51139d-4333-5ff0-44de-26f4c4c96a1d.png)

まだまだたくさん、お試しで送信するAPIを書いてはテスト、書いてはテスト、という感じでずらっと並んでいます。

Postmanは、世の中にある結構な数のAPIに対応しています。
どういうことかというと、Postmanで対象のAPIの構文が間違っていると、「違うよ」と言ってくれて、送信テストをする前に教えてくれます。
APIバージョンごとにスキーマ情報を自動で取得しているので、「あのバージョンだと有効だけど、このバージョンだとdepricatedだよ」というケアレスミスも防げます。

![スクリーンショット 2024-11-26 19.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/bb21967a-9cc6-049d-318b-0b821889c4b9.png)

もちろん、認可も取り揃えているので、設定するだけです。
![スクリーンショット 2024-11-26 19.20.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/b11be369-351e-f92b-c8bd-c48ab12b604a.png)

「URL から挿入」でどう書くかわからない？
大丈夫、コードも確認できるからね！

![スクリーンショット 2024-11-26 19.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/2874bbec-697c-9842-7567-6c4de2a89579.png)

このコードを、「URL から挿入」に割り当てます。

割り当て方は、こちらを参照すると、一発解決。

https://qiita.com/tyuma/items/7f0c161509f3c5c78257

# Postmanと友達になろう

ということなので、FileMakerでAPIを叩くとき、ちょっと敷居が高いな〜と思っている人は、Postmanと友達になって色々踏み台になってもらおうね！
Javaのコードカバレッジを測定する

# はじめに
現在参画している案件で、「テストのカバレッジ測定したい」というお話をいただきました。
あー、またかと思いつつ、Javaの場合は最近どんなやり方やるんだろうなと思い、調べてみました。古くは、Cobertura を使ってレポートしてましたが、最近の動向は抑えてなかったので、調べるところから


# 調査結果

以下ようなものを見つけて試してみました。
- Clover ・・・ atlassianの製品みたい。途中まで進めるもライセンスファイル要求され断念
- Kover ・・・Android用。Javaでも使えるっぽい。テストは実行できるもカバレッジ出ず断念
- JaCoCo ・・・まだ0.8.12であるものの、以前にも使ったので、結果としてはこれを採用

# 環境
Java 21
Gradle 8.8
JaCoCo

# やってみる
## Gradleの設定ファイルを作る

```groovy:build.gradle
plugins {
	id 'java'
    id 'jacoco'
    id 'application'
}

group = 'com.example'
version = '0.0.1'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(21)
	}
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}


repositories {
	mavenCentral()
}

dependencies {
    ・・・必要な依存関係は適宜追加してください・・・
}

jacoco {
    applyTo tasks.run // runタスクにJacocoを適用
}

tasks.register('applicationCodeCoverageReport', JacocoReport) {
    executionData tasks.test // 実行データをテストタスクのものに設定
    sourceSets sourceSets.main // ソースコードをメインソースセットに設定
    reports {
        html.required = true // HTMLレポートを生成
        xml.required = false // XMLレポートは不要
    }
}

// "test" タスクの設定。JUnit 5 を使用してテストを実行する
tasks.named("test", Test) {
    useJUnitPlatform() // JUnit 5 を使用する
    include '**/*Test.class' // 特定の名前のテストクラス（*Test.class）を対象にする
}

// すべてのコンパイルタスクで使用する文字コードを UTF-8 に固定
tasks.withType(AbstractCompile).each { 
    it.options.encoding = 'UTF-8' // ソースコードのエンコーディングを UTF-8 に設定
}

// すべてのテストタスクで実行時に使用するファイルエンコーディングを UTF-8 に固定
tasks.withType(Test) {
    systemProperty "file.encoding", "UTF-8" // 実行環境の文字コードを UTF-8 に設定
}

// テストタスク (test) が終了した後に、コードカバレッジのレポートを生成するタスク (jacocoTestReport) を実行
test.finalizedBy jacocoTestReport

// Jacoco のカバレッジレポートから除外するクラスファイルを定義
def coverageExcludeFiles = [
    '**/*$*.class', // ネストされたクラス（インナークラス）を除外
    '**/*$lambda$*.class', // ラムダ式に対応するクラスを除外
]

// Jacoco のテストカバレッジレポートの設定
jacocoTestReport {
    // レポートの出力形式を設定
    reports {
        html.required = true // HTML レポートを有効化
        xml.required = false // XML レポートは無効化（必要に応じて変更可能）
    }
    
    // Jacoco のクラスファイル設定を後から評価して適用
    afterEvaluate {
        // クラスディレクトリのファイルリストを収集し、除外設定を適用
        classDirectories = files(classDirectories.files.collect {
            fileTree(
                dir: it, // 各クラスファイルのディレクトリ
                exclude: coverageExcludeFiles // 除外するクラスファイルパターン
            )
        })
    }
}
```

## 実行する

```bash
./gradlew test
```

### 実行結果
こんな感じで、パッケージ単位のサマリも出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/f052b020-bc0c-5952-d892-d7490cac55fe.png)

クラス毎のカバレッジも、以下のように参照が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/c2f7e3c1-7a14-c07d-efa1-79b171dcc0e0.png)

# おわりに
いろいろ試してみましたが、結局以前に使ったことのあるJaCoCoに落ち着きました。
Koverの情報がもう少し整ってくれば、乗り換えも検討したいと思います。
LinuC202 合格記 (2024/11受験)

### はじめに
2024/11/4 に LinuC202 を受験して無事一発合格しました。
参考までに合格するまでの学習方法を記載します。

ちなみに LinuC 歴は 3年前くらいに LinuC レベル1 を合格し、2023 年末に LinuC201 を合格しました。

業務ではぼちぼち Linux を触るくらいでそこまで詳しくはないです。

### 使った教材
1. Linux教科書 LinuCレベル2
https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LinuC%E3%83%AC%E3%83%99%E3%83%AB2-Version-10-0%E5%AF%BE%E5%BF%9C-%E4%B8%AD%E5%B3%B6/dp/4798167967
2. Linux教科書 LinuCレベル2 スピードマスター問題集
https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LinuC%E3%83%AC%E3%83%99%E3%83%AB2-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version-10-0%E5%AF%BE%E5%BF%9C/dp/4798167975/ref=pd_lpo_d_sccl_1/355-2074029-4859304?pd_rd_w=mzy9f&content-id=amzn1.sym.855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_p=855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_r=Q1YQGKBYQHNKJHJYEYDP&pd_rd_wg=5kMQs&pd_rd_r=95818d93-619f-4ef2-9d14-0d31d31cf351&pd_rd_i=4798167975&psc=1
3. Ping-t (LinuC202 は有料プラン)
https://mondai.ping-t.com/

### 学習方法
1. 一旦、「Linux教科書 LinuCレベル2」の 202 の範囲をざっと読む
    ・理解しなきゃいけない項目をなんとなく把握する感じ。数日で読み終わるくらいのペース
    <br>
2. Ping-t の問題集を解き進める
    ・問題を解いてみる ⇒ 解説を見る ⇒ 教科書を見る の流れで各項目を理解
    ・実機を触らないと理解が進まないなーと思ったら WSL2 を使って実際に構築してみる
    　(CentOS ベースの問題が主なので、ディストリビューションはまだ CentOS がいいです)
     <br>
3. Ping-t の各分野の問題のステータスがすべて "ヒット" になったら次の分野に進む
    ・各ジャンルで 2~3 を繰り返して解き進める
    ・たぶん最後の方まで進むと最初の方の分野の記憶は抜けてる(私はそうでした)
    <br>
4. 3 が終わったらまた最初の分野に戻って、今度は問題のステータスがすべて "コンボ" になるまで解いて次の分野に進む
    ・ちゃんと理解できている問題はずんずん進める。
    ・ちょっとでも理解できてないなーと思ったら解説読んだり、教科書読んだり、実機触ってみたり。
    <br>
5. 4 が終わったら「Linux教科書 LinuCレベル2 スピードマスター問題集」の問題を解いて、Ping-t がカバーできてない範囲を理解する
    ・Ping-t で大体の範囲は抑えられているのでこれはいらないかも
    <br>
6. Ping-t の模擬試験を繰り返して安定して 9割正答できるようにする
<br>
以上

### 勉強期間
だらだら勉強してましたが、ぎゅっとすると 1か月半～2か月くらいです。
(一日 1時間勉強するとして)

### 反省点
点数は以下の通りでした。
・得点　　: 586点
・合格基準: 480点

割とぎりぎりだったのでもう少し時間をかけて勉強しておけばよかったかなと。

あと LinuC なので 2～3問くらいコマンドを入力する問題がでます。
実機をなんとなく触ったし大丈夫でしょと思ってましたが、いざとなると「あれ？」となりました。
コマンド入力問題を間違えても不合格になるわけではないと思いますが、正確に覚えておくと点数が高くなるかなと。

### 最後に
試験を合格する、という目的であればやっぱり Ping-t は便利。
試験のツボを押さえた問題が作られてます。

次は LinuC303 を受ける予定です。
Advent of code 2015 Day 15 Part 2 を Livebook で楽しむ

## はじめに

Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます

本記事では Day 15 の Part 2 を解きます

問題文はこちら

https://adventofcode.com/2015/day/15

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day15_part2.livemd

Part 1 はこちら

https://qiita.com/RyoWakabayashi/private/6af8f84a73bd9c653e98

## セットアップ

Kino AOC と Nx をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"},
  {:nx, "~> 0.9.2"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

Nx による行列演算を導入します

https://github.com/elixir-nx/nx/tree/main/nx

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 15 の入力を取得します

![スクリーンショット 2024-11-26 18.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/9758fa80-5e38-7dae-c986-1d866e0c03e4.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>回答</summary>

Part 2 ではカロリーも含めて行列化します

```elixir
get_ingredients_tensor = fn rows ->
  rows
  |> Enum.map(fn row ->
    Regex.named_captures(
      ~r/(?<ingredient>[a-zA-Z]+): .+ (?<capacity>\-*\d+), .+ (?<durability>\-*\d+), .+ (?<flavor>\-*\d+), .+ (?<texture>\-*\d+), .+ (?<calories>\-*\d+)/,
      row
    )
    |> then(fn %{"capacity" => capacity, "durability" => durability, "flavor" => flavor, "texture" => texture, "calories" => calories} ->
      [
        String.to_integer(capacity),
        String.to_integer(durability),
        String.to_integer(flavor),
        String.to_integer(texture),
        String.to_integer(calories)
      ]
    end)
  end)
  |> Nx.tensor()
end
```

カロリーは使用方法が他のプロパティとは異なるため、分離しておきます

```elixir
{ingredients, calories} =
  puzzle_input
  |> String.split("\n")
  |> get_ingredients_tensor.()
  |> Nx.split(4, axis: 1)
```

実行結果

```elixir
{#Nx.Tensor<
   s32[4][4]
   [
     [5, -1, 0, 0],
     [-1, 3, 0, 0],
     [0, -1, 4, 0],
     [-1, 0, 0, 2]
   ]
 >,
 #Nx.Tensor<
   s32[4][1]
   [
     [5],
     [1],
     [6],
     [8]
   ]
 >}
```

Part 1 と同じく、合計が 100 になる組み合わせを全て取得します

```elixir
all_combinations =
  for sprinkles <- 0..100,
      peanut_butter <- 0..100,
      frosting <- 0..100,
      sugar <- 0..100,
      sprinkles + peanut_butter + frosting + sugar == 100 do
    [sprinkles, peanut_butter, frosting, sugar]
  end
```

無条件に全組み合わせの合計スコアを計算します

```elixir
all_products =
  all_combinations
  |> Nx.tensor()
  |> Nx.dot(ingredients)
  |> Nx.max(0)
  |> Nx.product(axes: [1], keep_axes: true)
```

各組み合わせについてカロリーが 500 なら 1 、それ以外なら 0 になるカロリー条件行列を生成します

```elixir
valid_calories =
  all_combinations
  |> Nx.tensor()
  |> Nx.dot(calories)
  |> Nx.equal(500)
```

実行結果

```elixir
#Nx.Tensor<
  s32[176851][1]
  [
    [0],
    [0],
    [0],
    ...
  ]
>
```

合計スコアとカロリー条件行列を結合して積を求めます

カロリーが 500 の組み合わせ以外はスコアが 0 になり、条件をクリアした値のうちの最大値が求められます

```elixir
Nx.concatenate([all_products, valid_calories], axis: 1)
|> Nx.product(axes: [1])
|> Nx.reduce_max()
```

</details>

## まとめ

かなりややこしい問題ですが、 Nx の力でクリアできました
【競技プログラミング】AtCoder Beginner Contest 197_D問題

# 問題
https://atcoder.jp/contests/abc197/tasks/abc197_d

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)


# アプローチ
正N角形の性質と与えられた情報を利用して、中心点を求める。
その中心を基準に回転変換を行うことでp1の座標を計算する。


# 解法手順
1. 入力からN, (x0, y0), (xN/2, yN/2)を取得する。

2. 正N角形の中心座標(Ox, Oy)を計算する。
   - Ox = (x0 + xN/2) / 2
   - Oy = (y0 + yN/2) / 2

3. 正N角形の1辺に対応する回転角度radを計算する。
   - rad = π / (N/2)

4. 回転変換関数rotateを定義する。
   - 中心を原点とする座標系に変換
   - 回転行列を適用
   - 元の座標系に戻す

5. p0(x0, y0)を中心(Ox, Oy)周りにrad回転させて、p1(x1, y1)を求める。
   - (x1, y1) = rotate(x0, y0, Ox, Oy, rad)

6. 求めたx1とy1を出力する。



# ACコード
```python:ac.py
import math

def solve(N, x0, y0, xN2, yN2):
    # 2. 正N角形の中心座標(Ox, Oy)を計算する
    Ox = (x0 + xN2) / 2
    Oy = (y0 + yN2) / 2

    # 3. 正N角形の1辺に対応する回転角度radを計算する
    rad = math.pi / (N / 2)

    # 5. p0(x0, y0)を中心(Ox, Oy)周りにrad回転させて、p1(x1, y1)を求める
    x1, y1 = rotate(x0, y0, Ox, Oy, rad)

    # 6. 求めたx1とy1を出力する
    print(f"{x1:.10f} {y1:.10f}")

# 4. 回転変換関数rotateを定義する
def rotate(x, y, cx, cy, angle):
    # 中心を原点とする座標系に変換
    x -= cx
    y -= cy
    
    # 回転行列を適用
    new_x = x * math.cos(angle) - y * math.sin(angle)
    new_y = x * math.sin(angle) + y * math.cos(angle)
    
    # 元の座標系に戻す
    new_x += cx
    new_y += cy
    
    return new_x, new_y

if __name__=="__main__":
    # 1. 入力からN, (x0, y0), (xN/2, yN/2)を取得する
    N = int(input())
    x0, y0 = map(float, input().split())
    xN2, yN2 = map(float, input().split())
    solve(N, x0, y0, xN2, yN2)
```
【LaTeX】TeX Live 2024のインストールで困った話 ～環境変数の罠～

# はじめに
私が先日、Re:Viewの環境構築の一環で下のサイトに沿って TeX Live 2024 をインストールしたときにつまづいたことを紹介します。

https://tm23forest.com/contents/texlive2020-install-latex-begin

# 何につまづいたのか
インストールまでは順調だったのですが、上のサイトに沿って**コンパイルのテスト**をした時にコマンドプロンプトで次のエラーが出ました。

```
'platex' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

まあよくあるパスが通せていない類のエラーなのですが、私は**しっかりインストール時にパスを通す設定にしたのです**。

もちろんファイルがそもそも正常にインストールされていない可能性も考慮してそのフォルダもチェックしてみました。でもそのフォルダにはしっかりすべての実行ファイルが入っていたのです。

# 解決へ
それで早速環境変数をチェックしに行きました。

Pathには何が登録されているのかなと思って見ると、そこにはしっかり `D:\texlive\2024\bin` があるではありませんか！

ここで困惑するわけです。ちゃんと Tex Live のやつっぽいパスがあるのになぜコマンドが認識されないのかなと。

そして実際にそのフォルダを見てみました。

![texlive_bin_explorer.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685120/6b65d81a-bf62-c0e9-70ba-66707159b421.png)

<br>

### <b>windows...?
<br>

結果的には、**Tex Live の Path を `D:\texlive\2024\bin\windows` にするだけで解決できた** のですが、ここにたどり着くまでに1時間くらいかかりました。悔しい。

<br>

最後までお読みいただきありがとうございました。
以上、私の初投稿でした。


# 参考

https://kauplan.org/reviewstarter/reviewstarter-usersguide-20210314.pdf

https://tm23forest.com/contents/texlive2020-install-latex-begin
ReactのsetStateの誤用によってデータ取得に失敗した話

## はじめに
同じミスを繰り返してしまったため、今後の参考として記録しておきます。

## やろうとしていたこと
Cloud Firestoreからデータを取得し、そのデータをsetPostList関数を使ってpostListに保存し、画面に出力しようとしていました。

## 最初に書いていたコード
以下は、Cloud Firestoreからデータを取得するために私が書いていたコードです。
```js
const [postList, setPostList] = useState([]);
  useEffect(() => {
    const getPosts = async () => {
      const querySnapshot = await getDocs(collection(db, "posts"));
      querySnapshot.forEach((doc) => {
        setPostList(doc.data());
      });
    }
    getPosts();
  }, []) 
```

## 起きたこと
postListが空の配列として出力され、期待した情報を取得できませんでした。

## 問題の原因
以下のコードが原因でした。
```js
querySnapshot.forEach((doc) => {
  setPostList(doc.data());
});
```

## 何が起きていたのか
ReactのsetState（今回の場合はsetPostList）関数は、状態を上書きする動作をします。そのため、ループ内でsetPostListを繰り返し呼び出すと、最後に処理された値だけがpostListに残ることになります。

さらに、setPostListは非同期的に動作するため、タイミングのズレが生じ、意図したデータが保存されないことがあります。

このため、今回は空配列となってしまいデータを正しく取得することができませんでした。

## 正しい修正方法
以下のように修正することで、正しくデータを保存できます。

①新しい配列を作成する
②setPostListに直接値を代入するのではなく、まとめて更新を行う

```js
useEffect(() => {
  const getPosts = async () => {
    const querySnapshot = await getDocs(collection(db, "posts"));
    const posts = [];
    querySnapshot.forEach((doc) => {
      posts.push(doc.data()); // 配列に追加
    });
    setPostList(posts); // 最後に状態を更新
  };
  getPosts();
}, []);
```

## リファクタリング
forEachの代わりにmapを使うと、新しい配列を返してくれるので、この方法だとよりシンプルに書けるなと思いました。
```js
useEffect(() => {
    const getPosts = async () => {
      const querySnapshot = await getDocs(collection(db, "posts"));
      const posts = querySnapshot.docs.map(doc => doc.data()); // mapを使って配列を作成
      setPostList(posts); // 最後に状態を更新
    };
    getPosts();
  }, []);
```

## まとめ
- ReactのsetState関数は上書き動作をするため、ループ内で直接呼び出すと正しくデータが保存されない。
- 配列を使ってデータをまとめて管理することで、状態を一度に更新するようにすることが大切。


## 参考
今回コードを書くにあたり、こちらの動画を受講しています。
firebaseとReactの連携をわかりやすく教えてくださる素晴らしい動画でした！
ありがとうございました。

https://www.udemy.com/course/react-3project-app-udemy/?couponCode=BFCPSALE24JP

また記事執筆にあたり、こちらのリソースを参考にしています。

https://ja.react.dev/reference/react/useState
On-premises GitLab

# ローカルにGitlabサーバーをインストール

```bash
#関連パッケージのインストール
$sudo apt install -y curl openssh-server ca-certificates
#セキュリティーのためにキーを追加
$curl https://packages.gitlab.com/gpg.key | sudo apt-key add -
#インストールパッケージのダウンロード元を追加
$sudo add-apt-repository "deb https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/ $(lsb_release -cs) main"
#GITLABのインストール 1Gぐらいある
$ sudo apt install gitlab-ce
```


```shell:/etc/gitlab/gitlab.rb
#GITLABのアクセスURLの設定
external_url "http://127.0.0.1"
```

```bash
#設定の反映
$sudo gitlab-ctl reconfigure
```

# アドミンユーザーの設定
ユーザー名はroot初期パスワードは以下に書いてある。
```shell-session
$cat etc/gitlab/initial_root_password
sudo cat /etc/gitlab/initial_root_password 
[sudo] password for student: 
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: bKORzwipG166LWNQmj5uQMHxfVR18Q7fVDwxP9F8Ha4=

# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
```
CIDRとは

# サブネットで節約してもルーティングテーブルの問題がある
>大学などの組織のネットワークの境目にあるルーターは、それぞれのサブネットの項目を備え、各ネットワークに接続する回線の情報を保持する必要がある。組織外にあるルーターに対しては、組織とインターネットを繋ぐISPに向けてパケットを送信すればよい、という単純なルールをデフォルトとして良い。それ以外の、組織内のすべての宛先アドレスは、ルーティング・テーブルのどこかになくてはならない。

### デフォルトフリーゾーン(DFZ)
>デフォルト経路を必要とせずに運用している、 すべてのインターネットにおけるネットワークの集まりを指します。

https://www.nic.ad.jp/ja/tech/glos-ta.html#:~:text=%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%83%95%E3%83%AA%E3%83%BC%E3%82%BE%E3%83%BC%E3%83%B3,%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

# ルーティングテーブルが大きいとサーバにかかる負担も大きい
>インターネットにどれだけ多くのネットワークが繋がっているかを本当に分かっている人はいないが、その数は少なくとも100万はあると考えられている。つまり巨大なテーブルが必要になるということである。
...
実際にはルーターはこのテーブルを全てのパケットに対して参照しなければならないし、大きなISPのルーターともなれば、1秒に数百万ものパケットを処理しなければならない。このような頻度でパケットを処理するためには、`普通の用途向けのコンピュータではなく、特別なハードウェアと高速なメモリが必要`となる

# ネットワークをまとめてルーティングテーブルを小さくする　ルータ集約
>ルーティングテーブルの大きさを小さくする方法がある。サブネット化が同じようにして、IPアドレスが異なる長さのプレフィックスに属していれば、異なる場所にルーターがあるとわかる。しかしここでは、アドレスブロックをサブネットに分割する代わりに、`いくつかの小さなプレフィックスをまとめて、一つの大きなプレフィックスにする`。このプロセスは`ルータ集約`と呼ばれている。アドレス・ブロックを分割したものがサブネットと呼ばれるに対して、`このプロセスで得られた大きなプレフィックス`は`スーパーネット`と呼ばれている

# CIDR
>集約により、`IPアドレスはさまざまな長さのプレフィックス`を含むことになる。同じIPアドレスでも、あるルーターはこれを/22として扱うかもしれないし、`ある程度のルーターでアドレスがどのプレフィックス情報を対応しているかによって決まる`。サブネット化と合わせたこの働きのことをCIDR-クラスレス・インタードメイン・ルーティングと呼び、「サイダー」と読む。

# 一つのプレフィックスで送ることができる
>ロンドンでのルーティング・プロセスではこれに対して、３つのプレフィックスをまとめて194.24.0.0/19という一つのプレフィックスに集約し、ニューヨークのルーターに教える

>集約により３つのプレフィックスは一つに減り、ニューヨークのルーターのルーティング・テーブルに必要な項目が減るのである。

# 集約のルールは最長マッチング・プレフィックスへ送る
>集約は自律的なプロセスである。プレフィックスがインターネット上のどこに位置しているかに依存し、管理者がネットワークにアドレスを割り当てるのには依存しない。集約はインターネットで広く使われており、`ルーティング・テーブルの大きさを20万程度のプレフィックスに抑える`ことができる。
　さらには、プレフィックスのオーバーラップが許されている。そのルールは、パケットは最も具体的なルートの方向、言い換えれば、`最も少ないIPアドレスを持つ最長マッチング・プレフィックス(longest matching prefix)の方向へ送る`というものである。

### CIDRはルーティングテーブルで探し、最長プレフィックスが使われていると最長のプレフィックスに対して送る
 >CIDRは以下に述べるように働く。`パケットが来るとルーティング・テーブルを検索し、宛先がプレフィックスの中にあるかどうかを調べる`。`最長プレフィックスが使われていると、プレフィックスの長さが異なる複数の項目がマッチすることもあるが、その場合は最も長いエントリを採用`する。例えば、/20のマスクと/24のマスクがマッチした場合には、パケットを送る回線としては/24のエントリが用いられる。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

# 感想
ルーティングテーブルを小さくするためにルート集約して最長マッチング・プレフィックスに流す。
CIDRはこれを利用して流していると思ってる
難しいけど理解したい。
初心者がサーブレット&JSPでキャラクター管理システムを作ってみる話2

前回([大学生がサーブレット&JSPでキャラクター管理システムを作ってみる話１](https://qiita.com/Ruku_/items/b3372fd23ed7a308bb15)
)の最後に、次回は更新・削除作業の画面遷移を考えるとか言いましたが、「次の画面遷移考えるより、考え終わった登録の画面遷移はどれだけ有用なのか確かめてみてもいいかもな」と思ったので、登録機能の実装に取り組み始めました。
登録の画面遷移で考え不足のところがあったら、その次に考える予定の画面遷移でも考えが足りなくて、プログラミングの時に困っちゃいそうですしね。

そしていざ登録機能の開発を始めてみたらなんと問題が発覚。

とりあえず、前回時点での画面遷移を見てください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842140/c54eb634-073e-dd3b-b1aa-af70f2400a48.png)

ゲーム：(ドロップボタンで選択)

という文がありますよね。
ここはGAMESテーブルからゲーム情報を取得し、ドロップダウンで表示・選択して情報を取得するという流れを考えていました。
ですが皆さま、気づきましたでしょうか。
GANESテーブルからデータを取得する流れがないことに。
このテーブルを操作するDAOも記載していません。
流れを考えてはいましたが、画面遷移図に書いていなかったのです。
愚かなことに、自分は「まぁ、これくらい図が無くてもできるでしょ！」と甘く見てプログラムを進めようとしましたが、頭がごちゃついてしまい、結局、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842140/4fdcf05f-21e4-df9a-8fda-4cbe789cd07e.png)
簡単に流れを書きました。

これくらい流れが無くても作れるでしょ、と思ったかもしれません。
でも、サーブレットもJSPもまだ使いこなせていないので「あれ、これってどう書くんだっけ...」「あれ、DAOがDBとやり取りするんだよね...?」というふうになり、頭がごちゃごちゃになってしまうのです...。はやく頭の中で流れとプログラムの書き方を紐づけられるようになりたいです。

そして、思っていたよりも時間がかかってしまいましたが、ゲームをドロップダウンで選択できるようになりました。
![{4AAEFB85-E9D6-484D-B66D-3CDE2A1387EB}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842140/e15375ce-dbf3-cb26-3ec8-73743005547e.png)
やったね。

ここができたらもうできる。
ということで、characterのDAOやBO、結果表示のjspもろもろを作り、登録画面のフォームに入力し、送信しました。登録完了の画面に遷移できたのを確認したので、h2コンソールでちゃんとデータが格納できているか確認した結果、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842140/c04776fa-2ea4-999c-c0cd-17b16cdbedc3.png)
しっかり登録できているのがわかりました。よかった。
(UPDATE-DATEの日付が違うのは、この間に風邪でダウンしてたからです...。ちゃんと実行した日の日付が格納されています)

## 閑話
ところで、Date型ってjava側とsql側で違うんですね...。
最初、DAOでSQL文のプレースホルダに更新日の値を代入しようとして、
```diff_java
    Date date = new Date();
    pStmt.setDate(6, date);
```
というようなプログラムを書いて怒られたんです。
そこでネットで調べたりGPTに聞いたりしたら、このDate型のdateをSQLのDate型にしなきゃいけなかったらしく、
```diff_java
    java.util.Date utilDate = character.getUpdate_date();
	java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    pStmt.setDate(6, date);
```
このように修正したらできました。
名前がどちらも「Date型」だからといって、気軽に手渡せるとは限らないことを学びました。

次は一覧表示の画面遷移と実装をしようかな。
PythonでExcelの行の高さと列の幅を調整する

Excelでは、デフォルトの行の高さと列の幅では、セルの内容が完全に表示されない場合があります。行の高さと列の幅を調整することで、すべてのデータが完全に表示され、コンテンツが切り捨てられるのを防ぐことができます。行の高さと列の幅を適切に調整することで、特に多くのデータを含むテーブルをすっきりとプロフェッショナルに見せることができます。

この記事では、**Pythonを使ってExcelで行の高さと列の幅を調整する方法と、行の高さと列の幅を自動フィットする方法**を紹介します。


## Python Excelライブラリ
PythonでExcelドキュメントを操作するには、サードパーティライブラリ[**Spire.XLS for Python**](https://www.e-iceblue.com/Introduce/xls-for-python.html)が必要です。以下のpipコマンドで直接インストールできます：
> pip install Spire.XLS

(製品パッケージをダウンロードし、ローカルパスからインストールすることもできます)

https://www.e-iceblue.com/Download/Spire-XLS-Python.html

## PythonでExcelの行の高さと列の幅を調整する 
Spire.XLS for Pythonは、Excelのワークシートを表現するための`Worksheet`クラスを提供します。指定した行や列の高さや幅を設定するには、Worksheetクラスの **`SetRowHeight(rowIndex, height)`** メソッドや **`SetColumnWidth(columnIndex, width)`** メソッドを使用します。


> Pythonのコード：
```python
from spire.xls import *
from spire.xls.common import *

# Excel文書を読み込む
workbook = Workbook()
workbook.LoadFromFile("input.xlsx")

# 最初のワークシートを取得する
worksheet = workbook.Worksheets[0]

# 最初の行の高さを設定する
worksheet.SetRowHeight(1, 40)

# 最初の列の幅を設定する
worksheet.SetColumnWidth(1, 18)

# ファイルを保存する
workbook.SaveToFile("RowHeightColumnWidth.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```


## PythonでExcelの行の高さと列の幅を自動フィットする 
Excelのオートフィット機能は、セルの内容に基づいて行の高さと列の幅を自動的に調整し、すべてが完全に表示されるようにします。セル範囲の行の高さと列の幅を調整するには、 **`CellRange.AutoFitRows()`** と **`CellRange.AutoFitColumns()`** メソッドを使います。

>Pythonのコード：
```python
from spire.xls import *
from spire.xls.common import *

# Excel文書を読み込む
workbook = Workbook()
workbook.LoadFromFile("input.xlsx")
 
# 最初のワークシートを取得する
sheet = workbook.Worksheets[0]

# データを含むワークシートの領域を取得する
range = sheet.AllocatedRange

# 行の高さの自動調整
range.AutoFitRows()
# 列幅の自動調整
range.AutoFitColumns()
 
# ファイルを保存する
workbook.SaveToFile("Autofit.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```
上記の2つの例を通して、Pythonコードを通してExcel表の行の高さと列の幅を簡単に調整することができ、データの読みやすさと美しさを向上させることができる。
 * * *
Excelドキュメントを操作するためのPythonの他の機能については、以下のリンクからチュートリアルをチェックしてください：

https://www.e-iceblue.com/Tutorials/Python/Spire.XLS-for-Python/Program-Guide/Spire.XLS-for-Python-Program-Guide-Content.html
Cloud Monitoringでログ監視をやってみた

# はじめに

どうも、@to-fmakです。最近、Cloud Monitoringでログ監視をやってみたので、設定手順を簡単に共有したいと思います。

# ログベースの指標の作成

アラートを作成する前に、ログベースの指標を作成する必要があります。
「Cloud Monitoring」->「ログベースの指標」を開き、「指標の作成」をクリックします。

![Screenshot 2024-11-21 at 15.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/c5d33921-833f-2b14-3f68-f45463460e65.png)

指標タイプを選択し、詳細を入力します。

![Screenshot 2024-11-21 at 15.27.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/851c9f73-485e-f226-e4c8-702a8b7233ca.png)

ログベースの指標を定義し、フィルタを作成します。

![Screenshot 2024-11-21 at 15.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/f755f302-9019-9a6a-1b23-8885e045e11b.png)

以下は、特定の Cloud Functions または Cloud Run サービスのエラーログを対象とするフィルタの例です。

```txt
(resource.type = "cloud_function"
resource.labels.function_name = "sample-function"
resource.labels.region = "asia-northeast1")
 OR
(resource.type = "cloud_run_revision"
resource.labels.service_name = "sample-function"
resource.labels.location = "asia-northeast1")
 severity>=ERROR
```

# アラートの作成

ログベースの指標の作成後、該当指標を選択し、「指標に基づいた通知を作成する」をクリックします。

![Screenshot 2024-11-21 at 15.28.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/9cbda85e-b891-1236-7284-ebd0fd8b86bf.png)

アラート作成の画面が表示されるので、監視要件にしたがって設定していきます。

![Screenshot 2024-11-25 at 17.38.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/9aa32664-c527-0cac-3bce-fb942c136e7f.png)

# 参考URL

https://cloud.google.com/logging/docs/alerting/monitoring-logs?hl=ja

# エンジニア募集

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています！！
ぜひお気軽にカジュアル面談へお越しください！！

https://gakken-leap.co.jp/recruit/
Windows Server バックアップのGUIが出てこないんだけど！🤬

# 前提
ふとある時、Windows Server バックアップの画面が消えてしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314743/3fafbfc1-6747-7c7f-06f2-0d6b1357ec1b.png)

サーバーの機能に追加しているのにツールにWindows Server バックアップが出てこない
機能のアンインストール、再インストールしても出てこない
wbadminも開けない(開いた瞬間閉じる)

# 解決策
NLB(ネットワーク負荷分散)を入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314743/1442bc10-50c9-6287-28ae-c47f1dc81e4a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314743/2676b1df-7b23-5d6d-6932-85f835a26815.png)

出てきた…
意味がわからん！なんでやねん！🤬
Proj #001 キャンバスアプリで支払申請のフォームを作成するゾ～第4回 Requiredプロパティを使わずに必須項目の制御をしよう～

https://qiita.com/Novskiiiiiiiiii/items/e9aac700a479dfa0c393

DataCardではなくテキスト入力フィールドの必須入力を設定する方法を残しておく。
めっちゃ手こずったので消えたら泣いちゃうから残しておく。

取引先コードが99999999の場合、取引先情報を新規で入力してもらう必要があるとする。

その場合、フォームのValid関数では事足りないので、新規入力フィールドについて必須の確認をしたい。

条件としては以下の条件で登録ボタンのDisplayModeを切り替えたい。

* Form2 が有効（Valid）であり、かつ以下のいずれかの条件が満たされている場合にボタンを有効化する
* dc_client_code_value が '10999999' に選択されていて、すべてのテキストフィールドが空でない
* dc_client_code_value が '10999999' 以外に選択されている

ValidがTrueになっている事は前提として、DataCardで選択した取引先コードによって
特定のフィールドの入力チェックをしたい。

dc_client_code_value が '10999999'の場合は、取引先情報すべて必須にする
dc_client_code_value が '10999999'じゃない場合は、取引先情報が入っていなくてもよい

で、最終的に登録ボタンのDisplayModeプロパティに設定したのは以下のコード

    If(
        And(
            Form2.Valid, 
            Or(
                And(
                    dc_client_code_value.Selected.Value = "10999999", 
                    !IsBlank(txt_client_name_spot.Text),
                    !IsBlank(txt_kouza_name_spot.Text),
                    !IsBlank(txt_bank_code_spot.Text),
                    !IsBlank(txt_bank_name_spot.Text),
                    !IsBlank(txt_branch_code_spot.Text),
                    !IsBlank(txt_branch_name_spot.Text),
                    !IsBlank(txt_kouza_kbn_spot.Text),
                    !IsBlank(txt_kouza_number_spot.Text)
                ), 
                dc_client_code_value.Selected.Value <> "10999999"
            )
        ), 
        DisplayMode.Edit, 
        DisplayMode.Disabled
    )

インデントつけてると見やすいけど、Microsoftさんのプロパティ設定欄、狭すぎネ！

順を追ってQiitaに残そうと思ってたけど納期が近いので先に実装終わらせてから書きます。

今回は上記コードが消えたら泣いちゃうので残しておいた。
（もちろん、社内の環境にも残してあります）

キャンバスアプリ、楽しいネ！
時間がどんどん溶けていくヨ！
朝から体調悪かったのになんだかんだもうこんな時間ネ！
ワタシ着替えも洗顔もしてないネ！

でも微熱あるのでぼちぼち退勤するネ！
この記事がどこかで誰かの役に立つとウレシーね！

質問あればコメント残してくれれば暇な時見るヨ！

ニホンのミンナPower Apps覚えるとセーサンセー上がるネ！

それではまたアルヨ！

https://qiita.com/Novskiiiiiiiiii/items/6048795780fe515346fd
エスケープシーケンスにハマった

# エスケープシーケンスにハマった
PostgreSQLのCOPYを使用してテーブルをCSV出力する際ヘッダーとレコードを二重引用符`""`で囲みたかった。
質問に希望の回答は帰ってこず自分で試行錯誤した結果と心情をまとめる。

https://qiita.com/isOwO/questions/37fde79f7c8f7d8ec0c1

## PostgreSQLのCOPY
まず、ヘッダーの出力とレコードを`""`で囲っていく。
```sql:
COPY sample_table TO 'C:/tmp/test1.csv' WITH csv header force quote *;
```
`csv`形式で `header`を含め `force quote *`で全カラムの非NULL値も強制的に`""`で囲む。
```csv:test1.csv
no,name,sex_cd
"1","藍沢","1"
"2","石田","0"
"3","及川","0"
```

#### ここからは試行錯誤
ヘッダーを任意の名前で出力しよう
```sql:
COPY (SELECT no as "番号",name as "名前",sex_cd as "性別" FROM sample_table) 
    TO 'C:/tmp/test2.csv' WITH csv header force quote *;
```
```csv:test2.csv
番号,名前,性別
"1","藍沢","1"
"2","石田","0"
"3","及川","0"
```
よし、このまま`""`を文字列に入れて完璧やな

文字列認識させるためにエスケープしてと

エスケープ方法を[Document](https://www.postgresql.jp/document/14/html/sql-syntax-lexical.html)より
> 引用符付き識別子は、コード0の文字以外であればどのような文字でも使えます （二重引用符を含めたい場合は、二重引用符を2つ入力します）。 これにより、空白やアンパサンド（&）を含むテーブル名や列名など、この方法がなければ作れないような名前のものを作ることが可能になります。 この場合においても長さの制限は適用されます。
```sql:
COPY (SELECT no as """番号""",name as """名前""",sex_cd as """性別""" FROM sample_table) 
    TO 'C:/tmp/test3.csv' WITH csv header force quote *;
```
```csv:test3.csv
"""番号""","""名前""","""性別"""
"1","藍沢","1"
"2","石田","0"
"3","及川","0"
```

???なんで???
エスケープできてないのか？SELECT文だけ確認
```sql:
SELECT no as """番号""",name as """名前""",sex_cd as """性別""" FROM sample_table;
```
| "番号" | "名前" | "性別" |
|:-:|:-:|:-:|
|  1 | 藍沢 |  1  |
|  2 | 石田 |  0  |
|  3 | 及川 |  0  |

できてるなぁ

その他のオプションを変更して入力した`"""番号"""`がそのまま表示されたわけじゃないことを確認していく。
`quote`をデフォルトの`"`から変更
```sql:
COPY (SELECT no as """番号""",name as """名前""",sex_cd as """性別""" FROM sample_table) 
    TO 'C:/tmp/test4.csv' WITH csv header force quote * quote '?';
```
```csv:test4.csv
"番号","名前","性別"
?1?,?藍沢?,?1?
?2?,?石田?,?0?
?3?,?及川?,?0?
```
`escape`をデフォルトの`"`から変更
```sql:
COPY (SELECT no as """番号""",name as """名前""",sex_cd as """性別""" FROM sample_table) 
    TO 'C:/tmp/test5.csv' WITH csv header force quote * escape '?';
```
```csv:test5.csv
"?"番号?"","?"名前?"","?"性別?""
"1","藍沢","1"
"2","石田","0"
"3","及川","0"
```

なるほど。
カラム名の文字としての`"`と`quote`の`"`区別できないから`escape`の`"`を文字の`"`の前につけるよーってことか。
だから`quote`を`?`にしたときはヘッダーを二重引用符で囲めたのね。
#### 結果
ヘッダーを取るとレコードが、レコードを取るとヘッダーがって
今の自分にはこれ以上COPY文でどうにもなりそうにないので別の方法しかないのかなぁ。
「SQLアンチパターン」の気づき（DB物理設計2）

## はじめに

こんにちは。小川です。
以前から気になっていた「SQLアンチパターン」という本を読みました。
とても良い本で今まで気づかずにやっていたことがSQLアンチパターンなんだと知ることができました。
勉強になったので、学んだことを言語化して量が多いのでいくつかの記事に分けて紹介していこうと思います。
今回は第Ⅱ部のDB物理設計のアンチパターンについて記載します。
この記事は[「SQLアンチパターン」の気づき（DB物理設計1）](https://qiita.com/pesysyon/items/034b9413561a48fc0819)の続きになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/edfcea05-fe0b-f2b8-c4c9-0881241eae1e.png)

## 11章.ファントムファイル（幻のファイル）

#### アンチパターン
画像をファイルシステムにファイルとして格納し、ファイルパスをVARCHARとしてデータベースに格納するアンチパターンです。

#### デメリット
1. ファイルの削除時における問題
DBで画像へのパスを削除しても、そのパスの指定先のファイルは削除されない。
参照元の行を削除すると同時に、対応する画像ファイルも自動的に削除されるように設計しない限り、「孤児」となったファイルが蓄積されてしまう
1. トランザクション分離の問題
一般的な設計では、エラーが発生した際にはトランザクションをロールバックします。
DELETEによって参照元の行と同時に対応する画像ファイルも削除する場合に、この変更をロールバックするとDBの業削除はロールバック対象なので元に戻りますが、ファイルはロールバック対象ではないので削除されたままになる。
1. データベースのバックアップツール使用時における問題
データベース製品のバックアップツールには、VARCHAR型に格納されたパス名が参照する先のファイルをバックアップ対象にすることができない。
そのために、画像ファイルは別途ファイルシステム用のバックアップツールを実行する必要がある。
1. 格納されている画像のパスはただの文字列のため、ファイルパスが正しいものであるかはデータベースでは検証できない。

#### 解決策：必要に応じてBLOB型を採用する
画像を外部ファイルではなく、DBの内部に格納することを考えるべきです。
ほぼすべてのDB製品は、あらゆるバイナリ型を格納できるBLOB型をサポートしている。

## 12章.インデックスショットガン（闇雲インデックス）

#### アンチパターン
インデックスを使うか否かの判断をインデックスを理解しないまま使用してしまうアンチパターンです。

#### デメリット
闇雲にインデックスを使用してしまうと以下の３つのミスのどれかが起こってしまいます。
1. インデックスを全く定義しないか、少ししかインデックスを定義しなくなる
1. インデックスを多く定義しすぎるか、役立たないインデックスを定義してしまう
1. インデックスを活用しないクエリを実行してしまう

#### 解決策：「MENTOR」の原則に基づいて効果的なインデックス管理を行う
最適なインデックス作成を行うためのチェックリストとして、MENTORというものがあります。
MENTORとはMeasure(測定)、Explain(解析)、Nominate(指名)、Test(テスト)、Optimize(最適化)、Rebuild(再構築)のことです。

・Measure：クエリの実行時間を測定し、最大のコストがかかっている操作を識別する
・Explain：実行計画によって、クエリ実行にどのインデックスを使うか判断する
・Nominate：クエリがインデックスを使わないでテーブルにアクセスしている箇所を探す
・Test：インデックス作成後、どの程度の効果をもたらしたか確認する
・Optimize：キャッシュに割り当てるシステムのメモリ量を調整する
・Rebuild：インデックスを再構築する

データとクエリについての理解を深め、MENTORの原則に基づいてインデックスを管理することが大切

## まとめ
今回は第Ⅱ部のDB物理設計のアンチパターンについて一部まとめてみました。
この記事はこの本を読んで、私がこういう理解をしましたということを言語化してみました。
とても勉強になる本なので皆様もぜひ読んでみてください。

以上、小川でした。