OmniAICreator/Qiita-1.07M huggingface dataset:
ただのC言語演習メモ

# プログラミング演習 I メモ
ただの自己満メモ

## グローバル変数とローカル変数
* **グローバル変数**：関数外に宣言した変数、どこからでも呼び出せる。
* **ローカル変数**：関数内に宣言した変数、宣言した関数内でのみ呼び出せる。

同名の変数が存在する場合、呼び出し箇所と近い方の変数が優先される。<br>
グローバル変数は代入せずに宣言すると0を格納する。

## print関数の変換指定子
`%[フラグ][最小フィールド幅][.精度][修飾子]変換指定子`

|変換指定子| 変数の型 | 概要|
|--------|----------|-----|
|%c	|char	|文字|
|%s	|har *	|文字列|
|%d	|int	|10進整数|
|%hd|short int|半分の精度の10進整数|
|%ld|long int|倍精度の10進整数|
|%u	|unsigned int|符号なし10進整数|
|%hu|unsigned short int|符号なし半分の精度の10進整数|
|%lu|unsigned long int|符号なし倍精度の10進整数|
|%o	|int	|8進整数|
|%x	|int	|16進整数|
|%f	|float	|実数|
|%lf| double|倍精度の実数|
|%e	| float	|実数の指数表示|
|%g | float	|実数の最適表示|

## 桁数指定
```c
printf("%f"  , 3.14); // 3.140000（デフォルト）
printf("%.2f", 3.14); // 3.14    （下二桁）
printf("%.0f", 3.14); // 3       （小数点以下切り捨て）
printf("%.f" , 3.14); // 3       （小数点以下切り捨て）

printf("%5.2f", 3.14);   // " 3.14"（右詰め）
printf("%.2f", 0.0 / 0); // "nan"  （NaN）
printf("%.2f", 1.0 / 0); // "inf"  （Infinity）
```

## 前置演算と後置演算
前置演算は「先に<span style="color: red">演算</span>してから代入」
```c
int i = 10;
int j = ++i; //i = 11 j = 11;
```
後置演算は「先に代入してから<span style="color: red">演算</span>」
```c
int i = 10;
int j = i++; //i = 11 j = 10;
```

## 値渡し・ポインタ渡し・参照渡し
* **値渡し**：その値のコピーを関数に渡すため、<span style="color: red">関数の内部でその値を変更しても、関数を抜けた後にその影響が残らない。</span>
* **ポインタ渡し**：値のポインタ（メモリ上の住所）を関数に渡すため、関数の内部でそのメモリ上の値を変更すると、<span style="color: red">関数を抜けた後にはその影響が残ったままとなる。</span>
* **参照渡し（C++）**：ポインタ渡しと同様に、関数内部で値を変更すると、<span style="color: red">関数を抜けた後にもその影響が残る。</span>

|値渡し|ポインタ渡し|参照渡し|
|----|----|----|
|var|*var|&var|

値渡し
-----
```c 
#include <stdio.h>

void add1(int x) {
  x += 1;
}

int main(void){
    int a = 0;
    add1(a);
    printf("%d\n", a); // 0
    return 0;
}
```
ポインタ渡し
-----
```c
#include <stdio.h>

void add1(int *x) {
  *x += 1;
}

int main(void){
    int a = 0;
    add1(&a);
    printf("%d\n", a); // 1
    return 0;
}
```
エクセルで図形の反転

# 概要

この図形を…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0e60fd91-34a3-760c-a17a-15485833859f.png)

くるくるマークで回転させると、文字までひっくり返ってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b8de359c-2b1d-0daa-1a71-ebf951fee9c6.png)

**回転** ではなく **反転** をしたい。

# やり方

『図形の書式』は **図形を選択して初めて出てくるメニュー** なので注意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/65b3a96f-2943-40d1-48ed-d5222ca86108.png)

『配置』 → 『回転』に反転あり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4d41e17f-1114-7162-50be-0e4ab823837f.png)

# 蛇足

右クリックメニューや『サイズとプロパティ』内に無いから迷う。

# 参考サイトさん

https://support.microsoft.com/ja-jp/office/%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9-%E5%9B%B3%E5%BD%A2-%E3%83%AF%E3%83%BC%E3%83%89%E3%82%A2%E3%83%BC%E3%83%88-%E3%81%BE%E3%81%9F%E3%81%AF%E5%9B%B3%E3%82%92%E5%9B%9E%E8%BB%A2%E3%81%99%E3%82%8B-399e7a92-87e9-4d86-a03a-be120056fe3b

# バージョン

Microsoft Windows [Version 10.0.19045.3693]
Microsoft Excel for Microsoft 365 MSO (バージョン 2310 ビルド 16.0.16924.20054) 32 ビット
PHPSpreadSheetで3桁カンマで円マーク表記をする方法

PHPSpreadSheetはPHPでExcel等のファイルを生成するためのライブラリです。

https://github.com/PHPOffice/PhpSpreadsheet

こちらで円マークと3桁カンマを使って表示する方法がちょっと分からなかったので調べました。

結論としては`'"¥"#,##0'`と表記すると良いようです。**ダブルクォーテーションがないと、正しく認識してくれないので注意しましょう！**

```php
$sheet->setCellValue('A1', 1000);
$sheet
    ->getStyle('A1')
    ->getNumberFormat()
    ->setFormatCode('"¥"#,##0');
```

メモ程度ですが、忘れがちなので書いておきました。
css-loaderを4に上げたらfile-loaderでバンドルしたファイルが読み込めなくなった

## 原因
css-loaderはv4.0.0からesModuleがdefaultとなりました。
他のloderがCommonJSの場合、競合してしまいfile-loaderでバンドルしたファイルが読み込めなくなってしまいました。

```
T http://localhost:3000/[object%20Module] net::ERR_ABORTED 404 (Not Found)
```
 
>the esModule option is true by default
https://github.com/webpack-contrib/css-loader/releases/tag/v4.0.0

#### esModuleについて

https://webpack.js.org/loaders/css-loader/#esmodule

## 対応方法1
### Asset Modulesに変更する

webpack5からraw-loader,url-loader,file-loaderは非推奨になり、Asset Modulesが追加されました。
loaderを使用する設定を変更してAsset Modulesに切り替えます。


| 以前 | Asset Modules |
|:-:|:-:|
| file-loader | asset/resource |
| url-loader  | asset/inline   |
| raw-loader  | asset/source   |


下記リンクにある`type: 'javascript/auto'`はwebpackが様々な種類のJavaScriptモジュールを自動で判定する為の設定です。
今回はこの判定でCommonJSになってしまっていました。

#### Asset Modulesについて
https://webpack.js.org/guides/asset-modules/


## 対応方法2
### css-loaderをesModuleではなくCommonJSにする
 ```
  {
    loader: "css-loader",
    options: {
      esModule: false,
    },
  },      
 ```

## その他
Webpack5ガイドのAsset Modulesの日本語訳を見つけたので参考にどうぞ
https://note.com/stein2nd/n/n7502b20a3f4f
Electron+ReactでマルチウインドウするときはHashRouterを使う


一度に複数のレンダラープロセスを、画面遷移とかではなく起動したいときがある。

![overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/e7d24a5d-16b3-bddd-d92d-722bec7505de.png)

例えば、以下のように書く。

ディレクトリ構成。

```
.
├ index.html
├ routes.tsx
├ src/
    ├ main.ts
    ├ renderer/
        ├ about.tsx
        ├ contact.tsx
```

index.html は以下のような感じ。

```html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'" />
    <title>Example</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="routes.tsx"></script>
  </body>
</html>
```

`HashRouter`を使って component を読み込む。

```jsx:routes.tsx
import React from "react";
import { createRoot } from 'react-dom/client';
import { HashRouter, Route, Routes } from 'react-router-dom';
import { About } from "./src/renderer/About";
import { Contact } from "./src/renderer/Contact";

const root = createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <HashRouter>
    <Routes>
      <Route path='about' element={<About />} />
      <Route path='contact' element={<Contact />} />
    </Routes>
  </HashRouter>
);
```

これをメインプロセス側で以下のようにロードする。

```js:main.ts
// /about
aboutWindow.loadURL(`file://${__dirname}/../renderer/index.html#/about`);
// /contact
contactWindow.loadURL(`file://${__dirname}/../renderer/index.html#/contact`);
```

参考ページ。

https://reactrouter.com/en/main/router-components/hash-router
Azure Information Protection（AIP）の動的マーキングを評価してみた

初投稿となります。
Microsoft 365関連で調査、検証した内容をブログにしています。
今回はAIP（Azure Information Protection）についてです。

# ■はじめに
AIPでできることの1つとして、秘密度ラベルを付与したコンテンツ（メールやファイルなど）に対してヘッダー、フッター、透かしといったマーキングを付与することができます。

対象としては以下の公開情報にある通り、Officeアプリケーションで作成されたファイルやメールが対象となります。

[秘密度ラベルの詳細](https://learn.microsoft.com/ja-jp/purview/sensitivity-labels#what-sensitivity-labels-can-do)

今回、**後述するある理由**により、特定のアプリケーションのみに対してマーキングが付与されるような制御ができないかを検証したため、その結果を記載します。

 ### ■検証環境
ライセンス：Microsoft 365 Business Premium
Officeエディション：Microsoft 365 Apps for Business


 ### ■検証した理由
上記の公開情報を見ていただくと分かるのですが、動作対象となるアプリケーションにはOutlookも含まれています。
以下のようにシンプルにテキストでマーキングを設定した場合、送信したメールがどうなるかというと…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/31c85d49-b376-e9fd-c277-d4aea5119633.png)


下図の赤枠の部分のように、メールの本文中にヘッダー、フッターが挿入される動作となります。
※メールに透かしが挿入されないのは現時点（2023年12月時点）の製品仕様となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/a3d2b34c-7bc4-8dc7-52f9-b118e86c6e33.png)

メールの本文中に挿入されるのは、メールの内容によっては視認性が悪くなってしまうと思い、Outlookだけを挿入対象から除外することができるかを調べたところ、**動的マーキング**という設定方法を行えば実現できそうだったため、今回検証してみた形となります。

 ### ■動的マーキングとは
[上述した](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/31c85d49-b376-e9fd-c277-d4aea5119633.png)マーキングの設定値にテキストではなく、変数を定義することで挿入対象のアプリケーションを制御できる機能となります。
 変数の内容については、以下の公開情報に記載があります。
 
 [変数を使用した動的マーキング](https://learn.microsoft.com/ja-jp/purview/sensitivity-labels-office-apps#dynamic-markings-with-variables)

 ### ■設定内容
 今回はOutlookのみヘッダー、フッターを挿入しないという設定を行いました。
設定内容としては以下となり、コンテンツマーキングの設定にてヘッダー、フッターの設定に以下の変数を入力します。
```
${If.App.WXP}〈挿入したいテキスト内容〉 ${If.End}
```
※WXPはそれぞれのアプリケーション名を指してます。
　W ＝Word
　X ＝Excel
　P ＝PowerPoint
　O ＝Outlook

変数の内容としては、指定したテキストをラベルが付与されたファイルに挿入するが、対象とするアプリケーションからOutlookだけは除外するというものです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/6548af2a-d8c4-5bc7-06f2-3465957dd490.png)

 
### ■動作確認
新規作成したラベルに対して動的マーキングを設定し、Word、Outlookそれぞれで秘密度ラベルを付与しマーキングの動作を確認しました。

・Word
ラベル付与したファイルに対してヘッダー、フッターが挿入されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/842d8b46-e403-3787-c16d-7d4cc002bfa3.png)


・Outlook
ラベル付与したメールに対してヘッダー、フッターが挿入されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/434bc66b-f2b6-bd87-68ae-cf2ea46dafdf.png)



### ■最後に
動的マーキングを使うことで、Outlookのみ対象から除外することができました。
本設定は除外以外にも活用が可能で、例えば特定のアプリケーションだけ挿入するテキストの内容を変えるといったことも可能です。
（1つのラベルでWordにはAと挿入し、PowerPointにはBと挿入するイメージです）

AIPを導入する主な目的は機密文書に対するデータ保護を行うことだと思いますので、今回のようなヘッダー、フッター、透かしを挿入したいという要望は多いかと思います。
本記事の内容が何かの参考になれば嬉しいです。


初投稿からマニアックな内容となりましたが、今後もMicrosoft 365関連で調査、検証した内容はブログに残していこうと思います。
【PHP】nullを含む式についての評価まとめ

## はじめに

この記事ではPHPにおけるnullと他の型との比較をまとめます。
先日、nullを含む式が意図しない挙動をしインシデントが発生してしまったので、その際調べたことを主にまとめています。

※この記事では、PHP8を前提にしています。バージョンによって異なる型同士の比較の評価が異なるためご注意ください。

## ① nullとString型

この場合は、null を "" に変換して数値または文字として比較します。よって以下のような結果になります。

```php
var_dump(null < '0'); // bool(true)
var_dump(null < '1a2'); // bool(true)
var_dump(null < 'こんにちは'); // bool(true)
var_dump(null < ''); // bool(flase)
var_dump(null == '0'); // bool(flase)
var_dump(null == '1a2'); // bool(flase)
var_dump(null == 'こんにちは'); // bool(flase)
var_dump(null == ''); // bool(true)
var_dump(null === ''); // bool(flase)
```
注意するのはnull < '0'で、文字列'0'は文字列として評価されるためtrueとなることです。nullが「""」(長さ0の文字列)で数値形式ではないことから、文字列同士の比較となります。

 > オペランドが両方 数値形式の文字列 の場合、 もしくは一方が数値で、もう一方が 数値形式の文字列 の場合、 比較は数値として行われます。  -- PHP: 比較演算子 - Manual

 ## ②nullと数値型
 この場合は、両辺をbool型に変換して評価します。よって以下のような結果になります。

 ```php
 var_dump(null < 123); //bool(true)
var_dump(null < 0); //bool(false)
var_dump(null < 1.2); //bool(true)
var_dump(null < 0.1); //bool(true)
var_dump(null == 123); //bool(false)
var_dump(null == 0); //bool(true)
var_dump(null == 1.2); //bool(false)
var_dump(null == 0.1); //bool(false)
var_dump(null === 0); //bool(false)
var_dump(null === 0.1); //bool(false)
var_dump((bool)-1); //bool(true)
```

比較演算子が「===」や「!==」以外の場合は0以外はtrueとなるため、比較演算子が「<」の場合は右辺が0以外の場合はtrueと評価します。

## ③nullとそれ以外の型
それ以外の型についても数値型との比較と同様で、両辺をbool型に変換して評価します。
ここでは配列とオブジェクトを例に結果を見てみます。

```php
class Cuphead {
 public $color = 'red';
}

$array_fruits = ['lemon', 'melon'];
$array_cities = [];
$cuphead = new Cuphead();

var_dump(null < $array_fruits); //bool(true)
var_dump(null < $array_cities); //bool(false)
var_dump(null < $cuphead); //bool(true)
var_dump(null == $array_fruits); //bool(false)
var_dump(null == $array_cities); //bool(true)
var_dump(null === $array_fruits); //bool(false)
```
なお、配列は空の場合はfalseとなります。

## おわりに
PHPではnullの扱いは複雑なので、設計の時点でnullが入らないように考慮するのが無難かなと思いました。

## 参考サイト
[PHP: 比較演算子 - Manual ](https://www.php.net/manual/ja/language.operators.comparison.php)
ハードウェアデバイスの電気的な課題に対してファームウェア観点で立ち向かう話（電源電圧のドロップ対策）

# はじめに
この記事は[株式会社ビットキー Advent Calendar 2023 ](https://qiita.com/advent-calendar/2023/bitkey)8日目の記事です。

ハードウェア製品の品質保証（HWQA)を担当をしている高石 (@ksk_taka)が執筆します（今年のアドカレ2記事目）。
1記事目：[FIT(Failures In Time)という指標を用いて自社デバイスの品質を可視化したお話](https://qiita.com/ksk-taka/private/8f3be6f791400366188b)


# ハードウェアデバイス開発の構成要素と、開発する中で生じる制約
## ハードウェアデバイス開発の構成要素
製造業に従事している方ならすぐにイメージが湧くと思いますが、ハードウェアデバイスを開発する場合、大きく分けて以下の様な構成要素が存在します。そして、これらの要素ごとに専門の担当・チームが存在することが多いと思います。
- プロダクトデザイン
- 機構設計
- 電気設計
- ファームウェア設計

※上記に加えて更に「デバイスを制御するためのスマートフォンアプリ開発」なども加わることもあります。実際にビットキーでは、スマートフォンアプリ開発、Webアプリケーション開発、UI/UXデザインなど「開発」の領域が多岐にわたります。

## ハードウェアの課題を解消する場合に発生し得る制約
スマートフォンアプリ開発やWebアプリ開発などいわゆる「ソフトウェア開発」と異なり、ハードウェアデバイスの開発は「製品」という**物理的なモノ**が伴う開発となります。

製品の開発段階や、市場へのリリース後に課題が見つかった場合、対策を講じる際に例えば以下の様な制約を受ける場合があります
#### 制約の例
- 機構の「金型」が既にFIXしてしまっており、修正を掛けられない
- 電気の「基板」の製造を着手してしまっており、修正を掛けられない
- 数多くの製品を組み立ててしまっており、分解・再組み立てをする場合に非常に工数が掛かる
- 既に市場出荷してしまっており、電気・機構的な個別の対策が打つことが難しい

大まかなイメージですが、開発がある程度の段階まで進んだ状態で課題が発生した場合の対策の難しさは以下の様な順になるイメージです。

```math
機構>電気>物理的変更を伴う壁>ファームウェア>物理世界の壁>アプリ等
```
※あくまで筆者のイメージです

## 電気的な課題をファームウェアの修正で解決する
ファームウェアは、製品内部に組み込まれたCPUから各種センサやモーターなどの入出力部品を制御することができる、いわば「物理世界へのアクセスをソフトウェア制御できるもの」です。
また、ハードウェアデバイスの構成要素の中では、比較的「課題解消の為の打ち手が打ちやすい」という場合が多く、例えば製品について電気的な課題が生じた際、事象の内容によってはファームウェアの修正によって解決に導くことができる場合があります。

以下に、実際にファームウェア修正で解決した電気的な課題の例を記載します。

### 発生した電気的な課題の例
特定部品の電源制御信号をOFF→ONにした瞬間に、電源ラインに搭載されているコンデンサに突入電流が流れることにより大元の電源電圧自体がドロップしてしまい、予期せぬ製品再起動が起きる

#### 回路のイメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323105/ce2b5592-602a-8331-a7b5-9b14b5bfa10d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323105/c87b18ad-0519-ec3b-1e12-7d40e05474c0.png)




### 本来、対策として実施すべき内容
この課題は、製品の電気基板における**電源設計時**に**部品電源制御をOFF→ONにしたときに電源の仕様を満たすか**という観点のチェックが漏れていた事により起きたものです。

仮に設計時点で課題が見つかっていれば、当然回路の修正による課題対策を打つことができます。

**MOSFETを電源のスイッチとして扱う際、OFF→ONのタイミングで突入電流が発生する**ということは比較的よくある話で、FETのメーカーサイトにも対策の例が記載されています。

[MOSFETをロードスイッチとする場合、発生する突入電流をどう低減できますか（東芝デバイス＆ストレージ株式会社より）](https://toshiba.semicon-storage.com/jp/semiconductor/knowledge/faq/mosfet/when-using-a-mosfet-as-a-load-switch-how-do-i-reduce-the-inrush-.html)

しかし、冒頭でもお伝えしたように、「開発段階的に、回路的な対策を打つことができない」という状況に陥ることがあります。
その場合に、ファームウェアでの対策が打てないかを検討してみましょう。

### 上記に対するファームウェアによる修正方法の例

特定部品の電源制御信号を短期間でON/OFFすることで、コンデンサへの電荷チャージを段階的に行うことによって主電源側のドロップを抑制し、予期せぬ製品再起動の発生を防ぐ

#### FW修正前後のオシロスコープ波形（イメージ図）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323105/cac50beb-2332-50a4-05cd-2b674a66a462.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323105/1f47a045-25c4-1810-565b-a860b1b76b5c.png)




上記の様に、「電源電圧ドロップの発生」という電気的な課題に対して「ファームウェアの修正」によって対策を打つことができました。

## まとめ
ハードウェアデバイスは、機構・電気・ファームウェアなど複数の専門領域の組み合わせによって実現されます。基本的には、それぞれの要素について上流の設計時点でこまめなレビューや実機表かをするなどして高い品質を実現すべきだとは思います。

ただ、そうは言っても予期せぬ不具合が起こってしまうことはどうしてもあります。その対策を考える場合に、「機構の問題だから機構で解決する」「電気の問題だから電気で解決する」と決めつけず、複数の視点から解決策を検討してみるのも一つの手だと思います。

今回記載した内容がどこかで誰かの役に立てば幸いです。


9日目の株式会社ビットキー Advent Calendar 2023 は @utisam が担当します
Ruby – マルはUTF-8からShift-JIS ( CP932 / Windows-31J )に出来るがバツは変換できない Encoding::UndefinedConversionError 

# 例

```rb
'◯'.encode("CP932")
# => "\x{81FC}"

'☓'.encode("CP932")
# Encoding::UndefinedConversionError: U+2613 from UTF-8 to Windows-31J
```

# チャットメンバー募集



何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
年末年始による体重増加

# 初めに
　寒気が厳しくなってきた今日この頃クリスマスまで残すところ一週間となりました。この時期は多くの行事があり慌ただしい時期となっています。年末年始は、忘年会や新年会、帰省・旅行などでごちそうを食べる機会が増えるものです。お祝い事が重なりお酒やスイーツの摂取量も増える時期といえます。長期休みで生活習慣が乱れやすい時期に、短期間で何度も暴飲暴食を繰り返すことが正月太りの主な原因といえるでしょう。
　また、年末年始は冬の寒さの真っただ中にあるため、外に出て体を動かす機会も減ってしまう時期といえます。
 　**そこで正月太りが懸念される中BMIについて詳しくなっておきたいものです。**

  ## BMIとは？
  **BMIは「 Body Mass Index 」の略で、体の大きさを表す指数です。**


## BMIを出してみよう！？！？
　まず**HMTL**に以下のコードを書いていきます。

 ```html:HTML
 <!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BMI</title>
</head>
<body>
<div>身長 <input type="number" id="height">cm</div> 
<div>体重 <input type="number" id="weight">kg</div> 
<div><button type="button" onclick="calc()">計算</button></div> 
<div>あなたのBMIは<span id="kuuran">○○</span>です</div> 
    <script src="js/main.js"></script>
</body>
</html>
```
以下のようになります。
このままだと値を入力できるだけでボタンを押しても計算結果は出てきません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635184/0ebe1b88-1889-6968-4e67-023574d0987c.png)

ので、次にjavascriptに計算の中身を書いていきます。

```javascript:js
function calc(){ 
    var a, b,d;
    a = document.getElementById("height").value; 
    b	= document.getElementById("weight").value;
    
    c = b/( (a/100)*(a/100) );
    
    
    document.getElementById("kuuran").textContent =c;
   }
```

BMIは体重（キログラム）を身長（メートル）の二乗で割った値です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635184/442cf667-84e9-b4f3-9228-9abd62803b5b.png)

jsに計算の中身を書くと上記のように計算結果が出てきます。

![BMI判定表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635184/6be46b91-542b-c9d2-fd07-c29d8880d5b0.png)

## 最後に
　自分のBMIの結果を出してみてヤヴァと思い今年の年末年始は食べすぎには注意しようと思った人と、普通体重で安心した人がいると思うがみんな年末年始や正月太りには気を付けよう！！
AWS：強制的にMFAを設定させる方法

# 強制的にMFAを設定させるためのIAMポリシー
IAMユーザーに以下のポリシーを付与することで、強制的にMFAの設定をさせることができます。
もし、MFA認証をせずにログインした場合、MFA以外の全AWSリソースへアクセスできないためです。

```json
{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "iam:ChangePassword"
          ],
          "Resource": [
              "arn:aws:iam::*:user/${aws:username}"
          ]
      },
      {
          "Effect": "Allow",
          "Action": [
              "iam:GetAccountPasswordPolicy"
          ],
          "Resource": "*"
      },
      {
          "Sid": "AllowIndividualUserToManageTheirOwnMFA",
          "Effect": "Allow",
          "Action": [
              "iam:CreateVirtualMFADevice",
              "iam:DeleteVirtualMFADevice",
              "iam:DeactivateMFADevice",
              "iam:EnableMFADevice",
              "iam:ResyncMFADevice",
              "iam:ListMFADevices"
          ],
          "Resource": [
              "arn:aws:iam::*:mfa/${aws:username}",
              "arn:aws:iam::*:user/${aws:username}"
          ]
      },
      {
          "Sid": "BlockMostAccessUnlessSignedInWithMFA",
          "Effect": "Deny",
          "NotAction": [
              "iam:CreateVirtualMFADevice",
              "iam:DeleteVirtualMFADevice",
              "iam:DeactivateMFADevice",
              "iam:EnableMFADevice",
              "iam:ResyncMFADevice",
              "iam:ListMFADevices",
              "iam:ChangePassword",
              "iam:GetAccountPasswordPolicy",
              "iam:ListVirtualMFADevices"
          ],
          "Resource": "*",
          "Condition": {
              "BoolIfExists": {
                  "aws:MultiFactorAuthPresent": "false"
              }
          }
      }
  ]
}
```

# 注意点
- MFAの設定は添付画像の「**セキュリティ認証情報**」をクリックしてください。
![スクリーンショット 2023-12-05 14.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/0df5be72-e971-5ae6-9011-5f3eaa8bca01.png)


- MFA設定時のデバイス名は、**IAMユーザーの名前と同じ名前**にしてください。
![スクリーンショット 2023-12-05 14.13.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/3b245ed5-966f-58ff-acda-7dfcb41c279b.png)
API キーを手元に置かず（Azure の）OpenAI を叩く

Azure のコンソールから OpenAI の生 API キーをコピーしローカルで使うのは少し抵抗がある。
Azure OpenAI Service（AOAI）であれば Azure AD（Entra ID）の認証で API キーの管理から解放される。

# 事前準備

## 必要なロールを付与

[Azure のコンソール](https://azure.microsoft.com/en-us/)にて Cognitive Services OpenAI User を該当のプリンシパル（ユーザ）に付与する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287774/858be464-d1d5-9611-e14c-ff4b0579bd48.png)

## Azure CLI を導入

### インストール

下記は macOS の場合。

```sh
brew update && brew install azure-cli
```

https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli-macos

### ログイン

ターミナルにて Azure CLI にログインする。
コマンドを打つと通常のパブリッククラウドの CLI 同様 OAuth 的にブラウザ立ち上がって認証画面が出る。

```sh
az login
```

https://learn.microsoft.com/ja-jp/cli/azure/get-started-with-azure-cli

認証完了後`~/.azure`以下に認証情報やプロファイル情報が配置される。
これをソースコードが認証情報として参照するため API キーが不要になる。

# 実装

## コードを書く

準備完了したので、Azure CLI で生成したクレデンシャルを参照するように Python コードを書く。
[v1.0.0 discussions](https://github.com/openai/openai-python/discussions/631) にて議論されている通り、OpenAI Python SDK は v1 からだいぶ書き味が変わったので注意。

https://note.com/npaka/n/n27b94df96179

### v1 以降で書く

v1.1 にて動作確認済み。`AzureOpenAI()`を使う。

```py
import openai
 from openai import AzureOpenAI
 from azure.identity import DefaultAzureCredential, get_bearer_token_provider
 
 default_credential = DefaultAzureCredential()
 token_provider = get_bearer_token_provider(
     DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
 )
 
 client = AzureOpenAI(
     azure_ad_token_provider=token_provider,
     azure_endpoint="https://YOUR-DOMAIN.openai.azure.com",
     api_version="yyyy-mm-dd",
 )
 
 resp = client.chat.completions.create(
     model="YOUR-DEPLOYMENT-NAME",
     messages=[
         {"role": "system", "content": "You are a helpful assistant."},
         {"role": "user", "content": "Who won the world series in 2020?"},
         {
             "role": "assistant",
             "content": "The Los Angeles Dodgers won the World Series in 2020.",
         },
         {"role": "user", "content": "Where was it played?"},
     ],
 )
```

今後頻繁にシグネチャ変更があるとは考えづらいが、公式ドキュメントやリリースノート追うのをオススメする。

https://github.com/openai/openai-python#microsoft-azure-openai

DevDay で大幅なアップデートのあった今、v1 に移行する手筈を整えておくのが良さそう。

### v1 より前のバージョンで書く

手元では試していない。[Microsoft のドキュメント：Python を使用して OpenAI エンドポイントと Azure OpenAI エンドポイントを切り替える方法](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/switching-endpoints)のコードを参考にした。

```py
import openai
 from azure.identity import DefaultAzureCredential
 
 credential = DefaultAzureCredential()
 token = credential.get_token("https://cognitiveservices.azure.com/.default")
 
 openai.api_type = "azure_ad"
 openai.api_key = token.token
 openai.api_base = "https://YOUR-DOMAIN.openai.azure.com"
 openai.api_version = "yyyy-mm-dd"  # subject to change
 
 chat_completion = openai.ChatCompletion.create(
     messages="<messages>",
     deployment_id="gpt-4" # This must match the custom deployment name you chose for your model.
     #engine="gpt-4"
 ) 
```

## 補足

Zenn でも MS の方が本件に関する記事を書いていた。
よりセキュリティを高度化するための言及もある。

https://zenn.dev/microsoft/articles/9d33c143df589e
小さくOSS活動をし始めた話


この記事は、[Qiita株式会社のカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/qiita-inc)の6日目の記事です。

https://qiita.com/advent-calendar/2023/qiita-inc

---

2023年は何かしらOSSに関われれば良いなと思い、少しばかり行動をしてきました。
結果、貢献度は小さいかもしれませんがOSSに関わることができました。

この記事は「OSSに貢献したいけど怖い...」といった方に向けた内容です。

## 僕が2023年に関わることができたOSS

はじめに僕が2023年に関わることができたものを紹介します。

https://github.com/geum-ztmy/zutomayo_OCR/pull/2

https://github.com/creativenull/efmls-configs-nvim/pull/46

https://github.com/rouge-ruby/rouge/issues/1989

また、自分でもいくつか小さなOSSを公開しました。

https://github.com/ohakutsu/socks-copypath.nvim

https://github.com/ohakutsu/textlint-rule-period-in-header

https://github.com/ohakutsu/textlint-rule-table-align

https://github.com/ohakutsu/zutomoji-hg

いずれも大きな貢献ではないかもしれませんが、貢献できているかで言えばできているのではないかと思っています。

## 小さく始めることが重要

2023年にOSSに関わってみて僕が感じたことは、**大きな貢献でなくてもよい**ということです。
はじめから有名なフレームワークやプログラミング言語、ツールに貢献しようとすると、挫折してしまいがちなのではと思います。

また、貢献するOSSがないなどの悩みもあると思います。

そこで、小さくOSS活動を始めるために僕が心がけたことを紹介します。

### 1. 身の回りのものから始める

自分の好きなものや普段使っているエディタなど、自分がよく触れているものを対象とするようにしていました。
というのも、普段あまり使っていないものを改善するモチベーションというのはあまり上がらないことが多いと思っています。

自分がモチベーションを保ちつつやれることを見つけることがやり切るためのポイントだと思います。

### 2. 少しでも不便だな・こうなったら良いのにと思ったことは残しておく

普段使っているものであれば、こうなったら嬉しいのにと思う点は自然と見えてくると思います。そう感じたものは残しておくことが重要です。
というのも、残すことで今の自分にはできないものであっても将来的にできるようになるかもしれないからです。
将来にできるときが来たが、そのときには不要になっていたでも良いと思います。重要なのは、記録し、判断することです。

僕は死ぬまでにやりたいことリストを用意してそこに入れるようにしています。

## さいごに

「OSSに貢献したいけど怖い...」といった方が一歩を踏み出すキッカケになってくれると嬉しいです。
僕はまだまだ未熟ですが、小さく、徐々にできる範囲を広げていき、将来的に大きな貢献ができるように頑張ります。

---

記事を読んでいただきありがとうございます！
ぜひ、[Qiita株式会社のカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/qiita-inc)を購読設定して、明日の記事もご覧いただけると嬉しいです。
MVVMで、INotifyPropertyChangedを簡潔に使う。コードスニペット付き。

MVVMではプロパティを大量に使うことが多いです。
そうした時、INotifyPropertyChangedを、楽して使いたいですよね。
私は、次のようにしています。

## INotifyPropertyChangedをできる限りコードを減らして利用 

抽象クラスを準備します。

そして、
[Implementing INotifyPropertyChanged - does a better way exist?](https://stackoverflow.com/q/1315621)
の回答である、
https://stackoverflow.com/a/1316417
のコードを利用します。

`C# 8 で、 Nullable reference types`の場合は、次の通りです。

``` csharp
/// <summary>
/// https://stackoverflow.com/a/1316417
/// </summary>
public abstract class NotifyBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}
```

次のように`NotifyBase`を継承して利用します。
``` csharp
public class MainModel : NotifyBase
{
    private int _no;
    public int No
    {
        get => _no;
        set => SetField(ref _no, value);
    }

    public MainModel()
    {
    }
}
```

## コードスニペットの使い方

`propm`と入力すると、次が表示されます。

![20231205 132654 Anonymous.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/d4784a78-ff29-b4f5-377a-5c9042dbaa10.png)

バッキング フィールド名を変更します（標準的な命名では小文字ではじめる）。すると、プロパティ名も変更されます。
Tabキーで移動が便利。
![20231205 132721 Anonymous.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/4d817bd4-cd08-fe93-f904-bb3600bbbad5.png)


プロパティ名が小文字から始まるので大文字にします。
![20231205 132917 Anonymous.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/5397a88f-85ef-71a9-4962-500408442cd9.png)

### Visual Studio用 スニペット

バッキングフィールドとプロパティを作成するための、スニペット用コードです。

``` XML
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>propm</Title>
            <Shortcut>propm</Shortcut>
            <Description>プロパティとバッキング フィールド用のコード スニペット</Description>
            <Author>mikihiro</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>プロパティ型</ToolTip>
                    <Default>string</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>プロパティ名</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
                </Declarations>
            <Code Language="csharp"><![CDATA[
      
  private $type$ _$property$;
  public $type$ $property$
  {
      get => _$property$;
      set => SetField(ref _$property$, value);
  }
  $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>
```
50からの手習いでCBT試験を受験する心得

１．はじめに
バブル期の世代（本人）は、資格試験といえば、年に数回の開催で、大会場で記述やマークシート、というイメージしかありませんでした。
今や、自分で受験会場を探して、日程調整して、パソコンに「ポチポチ」するだけで受験が可能な便利な時代になりました。
しかし、それなりに以前とは違う準備や心得が必要であることに気が付きましたので書き留めました。

２．受験会場
僕が受験したのは大阪です。この場合、受験会場は大きく２つに分けられます。

①PC受験センター会場
②PC教室併用会場

①は、主にCBT受験を扱っているので、スタッフも慣れていて、会場も、受付、待合室、受験会場が分かれていて、落ち着いて受験できます。
②は、PC教室の講義をされる場合があります。よって、場合によっては静かではありません。隣の机で時間差で、別の試験が始まることもあり、その説明等でバタバタすることがあります。ただ、受験日や受験時間の選択肢が多く、受験のタイミングの自由度が高いことが多いです。（そうでない会場もあります）

３．受験準備
統計検定等を受験する際、「計算用紙とペン」を会場が準備されます。受験にとって、これは重要なアイテムですので、心配なら事前に確認した方が良いと思います。
多くの会場で受験した経験上、良かった順に挙げます。

①白紙の計算用紙にボールペン
②白紙の計算用紙に細マジック
③ラミネートフィルム（白）に細マジック
④ラミネートフィルム（薄い緑）に先が割れた細マジック

ラミネートフィルムはPC教室併用会場に多く、再利用することによる経費削減が目的と想定されます。細マジックは、字が汚い僕にとっては、書いたことが見直せないのは困りました。

４．老眼との闘い
最後に５０歳を超えると多くの人が抱える「老眼」というものにも対応しなければなりません。
会場には、電卓と身分証明書（免許証）しか持ち込めません。そのため、老眼鏡をケースに入れて持ち込むことはできません。裸眼で通常問題無く、試験の時だけ老眼鏡をかけるのは、そのまま眼鏡をかけて受験できますが、普段、近視眼鏡をかけている場合、老眼鏡を持ちこむと注意される場合があります。よって、本人確認が終わったら、近視眼鏡を外して鞄に入れ、老眼鏡を手で持つ。もしくは掛けて試験会場に入るしかありません。
この辺の改善を株式会社CBT-Solutionsに要望しようと思ったのですが、然るべき問い合わせ先が見当たらないので断念しました。どなたかがしていただけると幸いです。

５．おわりに
以前から言われている「学び直し」は、とても重要なことです。世界的に見ても日本人は大人になると勉強しないと言われています。ですが、もともと勤勉なお国柄ですから、是非、勉強に向き合っていただける一助になればと思いました。
UWSCRの新要素：UObject

`UObject`はjson互換のオブジェクトです。専用の組み込み関数によりjsonとUObjectの相互変換が可能です。また、jsonのリテラル表記からUObjectを得ることも可能です。

# UObjectの作成

jsonからUObjectを得る方法は以下の二通りあります。

## リテラル表記

`@@`の中にjsonを書くことで`UObject`に変換されます。

```php
obj = @{
    "foo": 123,
    "bar": {
        "qux": 345
    },
    "baz": [1, 2, 3]
}@

print obj // {"bar":{"qux":345},"baz":[1,2,3],"foo":123}
```

`@@`の内部は文字列として扱われるため、UWSCRの変数は利用できません。

```php
hoge = 123

// 変数hogeをリテラル表記で使うことはできない
// jsonパーサによりエラーになります
obj = @{
    "foo": hoge
}@
```

このような場合は変数展開表記を使ってください。

```php
hoge = 123
fuga = "ふがふが"

// json文字列は展開可能文字列であるため、<#変数名>表記が利用可能
obj = @{
    "foo": <#hoge>,
    "bar": "<#fuga>"
}@

print obj // {"bar":"ふがふが","foo":123}
```

## FromJson関数

json文字列をUObjectに変換します。パースに失敗した場合は`EMPTY`が返ります。

```php
json = fget(fopen("C:\uwscr\hoge.json", F_READ), F_ALLTEXT)
obj = fromjson(json)
if obj != EMPTY then
    print obj
endif
```

# UObjectをjsonにする

`ToJson`関数を使ってUObjectをjson文字列に変換します。

```php
obj = @{
    "foo": 123,
    "bar": {
        "qux": 345
    },
    "baz": [1, 2, 3]
}@

print tojson(obj) // {"bar":{"qux":345},"baz":[1,2,3],"foo":123}

// 第二引数TRUEで整形する
print tojson(obj, TRUE)
// {
//   "bar": {
//     "qux": 345
//   },
//   "baz": [
//     1,
//     2,
//     3
//   ],
//   "foo": 123
// }
```

# UObjectの使い方

UObjectの持つ値へは`.`表記やインデックス表記でアクセスできます。

```php
obj = @{
    "foo": 123,
    "bar": {
        "qux": 345
    },
    "baz": [1, 2, 3]
}@

// .で呼ぶ
print obj.foo     // 123
// インデックスでも良い
print obj["foo"]  // 123
// ネストの場合.で繋いでいく
print obj.bar.qux // 345
// 配列
print obj.baz     // [1, 2, 3]
// 配列のインデックス
print obj.baz[0]  // 1

try
    // 存在しないメンバを呼ぶとエラーになる
    print obj.quux
except
    print TRY_ERRMSG // [UObjectエラー] メンバが存在しない、または不正なインデックス: quux
endtry

// 代入もできる
obj.foo = 456
print obj.foo // 456
```

## ユーザー定義関数の引数型チェックにおけるUObject

ユーザー定義関数の引数の型としてUObjectを指定することが可能です。ただし、**UObjectであること**しか検査しないためオブジェクトの構成が正しいかどうかは関数内で精査する必要がある点には注意してください。

```php
obj = @{
    "foo": 123
}@

function MyFunc(value: uobject)
    try
        result = value.foo
    except
        // UObjectにfooが存在しない場合はエラーにする
        raise("オブジェクトにfooがありません", "MyFunc引数エラー")
    endtry
fend

print MyFunc(obj) // 123
print MyFunc(@{"hoge": 1}@) // [MyFunc引数エラー] オブジェクトにfooがありません
```
【AWS】IAMポリシー

# IAMポリシーとは
AWSリソースへのアクセス権限を制御する機能。
JSON形式で記載

プリンシパルに対してどのような権限を設定できるかのポリシーとして，以下がある。
* 管理ポリシー
    * AWS管理ポリシー
    * カスタム管理ポリシー 
* インラインポリシー

# AWS管理ポリシー
AWSが提供するポリシー。各サービスに対して設定できる。

# カスタム管理ポリシー
ユーザがJSONを利用して設定するポリシー。AWS管理ポリシーよりもさらに細かなポリシーを設定できる。

# インラインポリシー
グループやロールに個別に権限を設定するため，管理が複雑。現在は推奨されていない。

# JSONの見方
例:AdministratorAccess ポリシー(アイデンティティベースのポリシー)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/e867d6a4-a568-b94c-0db8-48ef4a3111ac.png)

**Version**
IAMポリシーの書式のバージョン

**Statement**
付与する権限と条件を記述。{}内をステートメントブロックといい，実際に制御する権限と条件を記述。

**Effect**
Actionに記述した内容を許可(Allow)または拒否(Deny)するかを記述

**Action**
制御したい操作を記述

**Resource**
制御するリソースの対象を指定。ワイルドカードも利用できる。

:::note info
**アイデンティティベースのポリシー**
IAMユーザに対して紐づけ
**リソースベースのポリシー**
S3のバケットなどリソースに対して紐づけ
:::

アイデンティティベースのポリシーとリソースベースのポリシーはAND条件になる。

# 参考
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html
https://www.wafcharm.com/jp/blog/aws-iam-for-beginners/
AWSの基本・仕組み・重要用語が全部わかる教科書
【AWS】IAM

# IAMユーザとは
AWSにアカウント登録をすると**ルートユーザ**が作成される。
ルートユーザはアカウントの契約変更や解約なども行える非常に強い権限を持つ。

:::note alert
原則ルートユーザではなくIAMユーザを使うことがAWSにおけるベストプラクティスである
:::

**IAMユーザ**はAWSアカウントで作成できるユーザ。マネジメントコンソールにアクセスしてAWSのリソースを操作できる。


# アクセスの種類
| アクセス先 | アクセス方法 |
| ---- | ---- |
| AWS CLI,SDK | アクセスキー |
| AWSマネジメントコンソール | パスワード |

:::note info
IAMユーザではアクセスキーIDとシークレットキーの項目を含む文字列(**アクセスキー**)を生成できる。
:::


# IAMグループとは
IAMユーザをグループ分けする機能であり，複数のユーザに対して一括で同一の権限を付与できる。またユーザは複数のグループに属すことができる。

# IAMロールとは
AWSリソースに紐づけられる役割で，アクセスキーなどの情報は持たない。
各リソースに対して1つ割り当てられ，EC2では**インスタンスプロファイル**と呼ばれるIAMロールの情報を格納している

:::note info
**インスタンスプロファイル**
IAM ロールのコンテナであり、インスタンスの起動時に EC2 インスタンスにロール情報を渡すために使用
:::

# プリンシパルとは
AWSのリソースにアクセスするユーザやアプリケーションのこと。ルートユーザーやIAMユーザー，IAMロールで認証を行ってAWSリソースを操作する。

# 参考
https://www.youtube.com/watch?v=sOTOIbTMxds
AWSの基本・仕組み・重要用語が全部わかる教科書
Canonicを使ってノーコードでAPIを作ってみた

# はじめに

Web開発をしていると必要になるDBとAPI
それらを簡単に用意できるサービス「Canonic」を紹介したいと思います。
ここではとあるレストランのメニューを返すAPIを作成しながら「Canonic」の使い方を紹介していきます。

# 目次

1.Canonicとは
2.アカウントの作成
3.プロジェクトの作成
4.テーブルの作成
5.APIの確認
6.参考

# Canonicとは

https://canonic.dev/


# アカウントの作成

<img width="400" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/d5cb1210-dfa9-dfef-7a85-cddbad63925a.png">

トップページ右上の「Start for Free」からアカウントの作成を行います。
名前、メールアドレス等を入力し簡単な質問に答えたら作成完了です。


# プロジェクトの作成

<img width="400" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/3abb21fc-8e70-6a1e-8eba-b56b8489788a.png">

ログイン後「Dashborad」の「Create Project」からプロジェクトの作成を行います。

<img width="400" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/a5a64923-d0e9-ae40-599a-b6b43e91c617.png">

プロジェクトの簡単な設定を行い「Create」でプロジェクトを作成します。

# テーブルの作成
<img width="400" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/906cfc11-981a-05dd-ea0b-f947231a7dad.png">

「DATASOURCES」からテーブルの作成を行います。

<img width="400" alt="6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/68148a30-fe08-3071-6bff-3a6ccacaf2cc.png">

Canonicではテーブルを元にAPIが生成されます。
「Generate endpoints」で選択したAPIが作成されますのでテーブルに対して全件取得を行うAPIが欲しい場合は「Get All」、キーを元に1件取得したい場合は「Get One」を選択します。
今回はメニューを返すAPIをなので「Get All」「Get One」を選択しました。

<img width="400" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/936bdde2-48f8-e2ca-cef5-326fb1044d9d.png">

テーブルを作成したら次はカラムを設定します。
カラム名、タイプ、プライマリーなどを設定したら「Deploy」を押します。

**これでAPIの作成は完了です!**

# APIの確認
<img width="400" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/eb78db71-97c8-8574-1f04-6c10f0594590.png">

Deploy後「WORKFLOWS」にテーブル作成時に選択したGet AllとGet OneのAPIが作成されます。
WORKFLOWSを選択して「DOCS」を押すことでAPIのドキュメントを見ることができます。

実際にAPIを叩いてみると動いていることが確認できます。

<img width="400" alt="9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618961/1a74ff5c-30fe-104b-e96d-8ec4653acc65.png">

実際に今回作成したAPIを貼りますのでよかったら叩いてみてください。

```
全件取得
https://can.canonic.dev/my-new-project-cfhb3e/api/menus

1件取得
https://can.canonic.dev/my-new-project-cfhb3e/api/menus?menuId=AA01
※menuIdは参考に書いたブログで紹介されている「番号」になります
```

# 参考

https://paiza.hatenablog.com/entry/2021/01/21/130000

https://kurobo0408.hatenablog.com/entry/2023/05/01/161331
S3互換クライアントでNutanix Objectsにアクセスしてみた

Nutanix ObjectsはNutanixの基盤の上でソフトウェアで実現するS3互換のオブジェクトストレージです。Prism Centralからのデプロイは他の方にお任せするとしてObject Browserでのアクセス確認までの記事は多いもののS3互換のクライアントからの記事がなかったので試してみました。
#

### S3互換クライアント
S3互換クライアントはネットワークドライブとしてオブジェクトストレージをマウントすることでエクスプローラーライクにファイルのアップロード、ダウンロードを可能にします。様々なクライアントがありますが今回は以下の３つを試してみました。

- WebDrive NextGen
https://webdrive.add-soft.jp/support/?page_id=3735
- JPCYBER S3 Drive
https://www.jpcyber.com/download
- CloudBerry Drive
https://www.msp360.com/drive/

### 確認項目
アクセス方法はObject Browserと同様でS3互換ストレージを選択し、Access Key IDとSecret Access Keyを入力して接続します。今回は以下の３点を確認しました。

- Objectsが正しくマウントできること
- マウントしたネットワークドライブからObjects内のファイルとフォルダが参照できること
- マウントしたネットワークドライブからファイルのアップロード・ダウンロードが可能なこと

### 結果
そしてそれぞれの結果は以下の通りでした。

#### 【WebDrive NextGen】
・マウントOK
・ファイルの参照OK?
・ファイルの書き込み、ダウンロードOK?
ただし全体的に動作が不安定で接続出来ないケース、ファイルが表示されないことも複数回発生
AWS S3を選択してObjectsのIPとBuckets名指定、オプションの古い形式サポートの有効化が必要
 
#### 【JPCYBER S3 Drive】
・マウントOK
・ファイルの参照OK
・ファイルの書き込み、ダウンロードOK
S3互換ストレージとして問題なく利用可能
 
#### 【CloudBerry Drive】
・マウントNG?
・ファイルの参照NG
・ファイルの書き込み、ダウンロードNG
疎通確認は出来るがマウント後にファイル無効なデバイスとして扱われて操作不可

S3互換ならば全部OKだという想定だったので意外な結果となりましたが、Objectsに限った話ではないので実際には使えるクライアントを選択頂いたり、Objects BrowserやAPIを利用していただけば普通に使えるので実用的な問題はない、といったところです。
#
もしこんなツールは使える、使えない、オススメなどがあれば是非コメントください。
明日のAdvent Calendarもお楽しみに！
[compose multiplatform 中級チュートリアル4]compose multiplatformのバックエンドを検証してみる

# 前回
[前回](https://qiita.com/shunk0616/private/8fe95658ab2f64aea302)では見た目を作ってみました。

# はじめに
前回までの章で作ったシンプルなTodoアプリのデータをDBに保存して安全に保ちたいのと、データ分析処理を行いたいのでバックエンドに接続したいです。

ただ、無限に選択肢があるので、検討した全てを書きます。


# 調査
## Firebaseは使えるか？
色々あるけど、Firestoreで実装できたら楽ですね。
ネイティブから直接DBにアクセスできるし、トリガーでfunctionsを呼んでデータ分析を行ったり便利ですからね。

### 良いライブラリはある？
現状のcompose multiplatformの状況から確認するとKotlinでFirebaseの接続をサポートするライブラリはあります。
[これ](https://github.com/GitLiveApp/firebase-kotlin-sdk?source=post_page-----0f3b8d3c84cb--------------------------------)ですね。
ただ、これってDesktopで使えるとは書いてあるものの、少し怪しいです。
[ここ](https://slack-chats.kotlinlang.org/t/519638/how-we-can-integrate-firebase-sdk-to-compose-desktop)の会話を見ると、これはnativeのFirebase SDKsのwrapperであり、java client sdk for firebaseがないらしいんですよねぇ。もしやりたかったらRESt APIを直接叩けとのこと。

どうなんだろう、実装してから動かなかったら無駄足になっちゃうのでライブラリをちょっとみてみましょう。

READMEを見たら英語だったので
ChatGPTに
```
上記のREADMEの中でcompose multiplatformのデスクトップアプリへの対応状況について書かれている箇所を抜き出して、解説お願いします。
```
と聞いてみたら以下のような回答をいただきました。

```
このREADME文書の中で、Compose Multiplatformのデスクトップアプリケーションへの対応状況に関する記述は、Firebase Kotlin SDKが多様なプラットフォームをサポートしていることを強調しています。具体的には、Firebase Kotlin SDKが「Kotlin-first」のアプローチを採用し、FirebaseをAndroid、iOS、デスクトップ、ウェブ向けの共通ソースコードから直接使用できるようにしている点です。

Compose Multiplatformへの言及は、このSDKがFirebaseをCompose Multiplatformプロジェクトのバックエンドとして使用できることを示唆しています。Compose Multiplatformは、異なるプラットフォーム（Android、デスクトップ、ウェブなど）で共通のUIコードを使用できるJetBrainsのフレームワークです。Firebase Kotlin SDKの多様なプラットフォームサポートにより、開発者はCompose Multiplatformを使用して作成したデスクトップアプリケーションにFirebaseの機能を統合しやすくなっています。

このREADMEには、Compose Multiplatformを利用した具体的な実装例やデスクトップアプリケーションへの具体的な対応状況についての詳細は記載されていませんが、Firebase Kotlin SDKの多様なプラットフォーム対応が、デスクトップアプリケーションの開発において有用であることを示唆しています。
```

一応ソースコードを見ると
今回使うFirestoreと今後使うFirebase authenticationの箇所は
> firebase-auth/src
> firebase-firestore/src

ですね。
その下にはjvmTestはありますね。
ということはデスクトップにも対応していそう？
でもjvmMainはないなぁ。
ってことは、対応していない？

と思って、それぞれのライブラリをみていたら普通に対応プラットフォームのことが書いてありました。
https://central.sonatype.com/artifact/dev.gitlive/firebase-firestore/1.10.4?smo=true#:~:text=common%20source%20targeting-,iOS%2C%20Android%20or%20JS.,-Snippets

desktopアプリには対応していないようですね。残念。
まぁAndroidとiOSのためにこのライブラリを利用して、Desktopは別のコードで実装しても良いのですが
今回はcompose multiplatformのチュートリアルなので全部一つのコードで実装したいです。
HTTPリクエストすることは可能ですが、一度Firebaseでの実装は考えないでおきます。

## Supabaseは使えるか？
最近、私の中で評価が高いSupabaseも見にいきます。
ほぼfirebaseと同じことができるのでsupabaseでも良いです。

### 良いライブラリはあるか？
ありましたー！
https://github.com/supabase-community/supabase-kt/tree/master/Postgrest

しかも全てのプラットフォームに対応している！
最高ですね。

[ドキュメント](https://supabase.com/docs/reference/kotlin/installing)もしっかりしている。

Supabaseでいきましょう！

# 結論
compose multiplatformで、AndroidとiOS以外のプラットフォームに対応するならバックエンドはsupabase！

# 次
[次の記事](https://qiita.com/shunk0616/private/64f9319d1067a7c6962d)はsupabaseの準備です。
複数GPU環境におけるPytorchでの使用GPU指定に関するTips

cuda環境でコードを走らせようとするとき、モデルやデータをGPUに載せる操作を以下のように記述していることがある。
```python
model = model.cuda()
data = data.cuda()
batch = batch.cuda()
```
Google Colaboratoryなど使用できるGPUがそもそも1つしかない場合はこのままで何ら問題はないが、複数GPUを使用できる環境であったり、他人と分担してGPUを使わなければならなかった場合はこのままだと困る場合がある。

## 使用GPUを指定できないと困るケース(例)
* 複数人で共同で使用している環境である場合

例えば`cuda:0`と`cuda:1`がある環境で同時に複数の人が`cuda:0`にアクセスしてしまうと`CUDA OUT OF MEMORY`のエラーが出てきてしまったり、動作が想定よりも遅くなってしまう場合がある。

* 使用すべきGPUが指定されている場合

そのため、研究室などで使用可能なGPUが何台かあって共同利用しなくてはならないときに「○○さんは何番と何番使ってください」と言われる場合がある。しかし、先述のような`.cuda()`を用いてGPUデバイスに送っていると常にデフォルトの`cuda:0`が選択されてしまうので注意が必要


以上の話は、機械学習のための全てのコードを自分で書いていたら、GPUに送る必要のあるオブジェクトすべてで`cuda:n(nは使用するGPUの番号)`を指定すれば済む話である。

```python
GPU_ID = 4 #使用するGPUのID
device = torch.device(f'cuda:{GPU_ID}' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
data = data.to(device)
batch = batch.to(device)
```

しかし、使用しているコードの一部がオープンソースなどの外部ライブラリに依存していて外部ライブラリが`.cuda()`を使用して転送していた場合、それら全部書き直すのは面倒だしそもそもできない場合もある。（筆者は今回このケースにぶち当たった。）

そこで、`.cuda()`をすべて`.to(device)`に書き換えなくても何とかなる方法をここでまとめる。

## 使用GPUを指定する方法

- 環境変数`CUDA_VISIBLE_DEVICES`で指定する

指定方法はスクリプト実行時に指定する方法とスクリプト内で指定する方法がある。
複数のGPUを指定する場合はカンマ(`,`)で区切る。
```shell
$ export CUDA_VISIBLE_DEVICES=4 #1つのGPUを指定する場合
$ export CUDA_VISIBLE_DEVICES=4,5,6,7 #複数のGPUを指定する場合
```
```python
import os

os.environ['CUDA_VISIBLE_DEVICES'] = '4' #1つのGPUを指定する場合
os.environ['CUDA_VISIBLE_DEVICES'] = '4,5,6,7' #複数のGPUを指定する場合
```

ただし、ここで複数のGPUを指定していた場合に、そのうちの特定のGPU(例えば4番)を使いたい場合は、`cuda:4`ではなく`cuda:0`としなければならない点に注意が必要。

恐らく番号順にインデックス0始まりで指定できるようになっていると考えられる。この例だと`cuda:1` -> 5番のGPU,`cuda:2` -> 6番のGPU,...というように。`cuda:4`を指定するとlistでいうところのout of rangeのGPUを指定してしまっていることになる(4つのGPUしか指定していないのでインデックスは0~3)ので、`invalid device ordinal`というエラーが出力される。

- `torch.cuda.set_device(hogehoge)`を使う

筆者のケースではなぜか上述の方法だと想定していないGPUにもデータが乗ってしまう場合があったので、これで解決した。
```python
torch.cuda.set_device(5) #使用したいGPUの番号を入れる
```
これをスクリプトの始めの方に書いておくと、指定したGPUがいわゆるデフォルトのデバイスになるので、`.cuda()`を使ったとしてもちゃんと指定したGPUにオブジェクトが乗ってくれた。ありがたい。

参考:https://pytorch.org/docs/stable/generated/torch.cuda.set_device.html
[compose multiplatform 中級チュートリアル1]compose multiplatformでアプリを作る準備編

# はじめに
これは、[前回のチュートリアル](https://qiita.com/shunk0616/items/747d651f2a94f6a6ec9c)からさらに進んで、バックエンド(Firebase)と接続したTodoアプリを作るチュートリアルの第一章です。
試行錯誤の過程も全部載せます。

# 準備編
環境構築はできている前提で。
[wiazard](https://terrakok.github.io/Compose-Multiplatform-Wizard/)を開いて適当なアプリ名を入力。
私はSaikyoTodoにしました（クソダサ）
必要なライブラリはわからんので、とりあえず絶対に使いそうなやつだけチェックしてダウンロードします。以下の画像を参考にしてください。

***[追加]Koinも入れてください！***
![](https://storage.googleapis.com/zenn-user-upload/b548382c01ec-20231109.png)

試行錯誤するので、git管理も導入しています。

# 初回立ち上げ編
入れたアプリをそのままAndroid Studio上でビルドしようとしたら読んでられないような大量のエラーが出た。
一度見なかったふりをして説明書（README）を見に行きます。

READMEに書いてあることをchatGPTに翻訳させたらこんな感じ。
```
以下は、Compose Multiplatform アプリケーションを実行する前のチェックリストと各プラットフォームでの実行方法についての案内です。

## 実行前に！
 - [KDoctor](https://github.com/Kotlin/kdoctor)でシステムをチェックしてください。
 - JDK 17をマシンにインストールしてください。
 - プロジェクトのルートに `local.properties` ファイルを追加し、そこにAndroid SDKへのパスを設定してください。

### Android
Androidデバイス/エミュレータでアプリケーションを実行するには：
 - Android Studioでプロジェクトを開き、インポートされたAndroid実行構成を実行してください。

アプリケーションバンドルをビルドするには：
 - `./gradlew :composeApp:assembleDebug` を実行してください。
 - `.apk` ファイルを `composeApp/build/outputs/apk/debug/composeApp-debug.apk` で見つけてください。

### デスクトップ
デスクトップアプリケーションを実行するには： `./gradlew :composeApp:run`

### iOS
iPhoneデバイス/シミュレータでアプリケーションを実行するには：
 - Xcodeで `iosApp/iosApp.xcproject` を開き、標準の構成を実行してください。
 - または、Android Studio用の [Kotlin Multiplatform Mobileプラグイン](https://plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile) を使用してください。

### ブラウザ
ブラウザアプリケーションを実行するには： `./gradlew :composeApp:jsBrowserDevelopmentRun`
```

local.propertiesファイルなんて入れてないなぁ。多分これかな。

簡単にやり方をまとめると
1. Android Studioを開く
2. メニューバーのtoolsを開く
3. SDK Managerを開く
4. 上の方に表示されているパスをコピー
5. プロジェクトのルートディレクトリにlocal.propertiesを作成
6. >sdk.dir = "さっきコピーしたパス"

Androidだけ動かない。
なんだこれは。。。

調べたらこれっぽいんだけど回答がついてないから一旦諦める
https://stackoverflow.com/questions/77418029/how-to-create-a-kotlin-project-using-kotlinx-datetime-and-share-it-across-differ

問題となっているdatetimeのライブラリを抜いたらビルドできるようになった、時間周りの処理はバックエンド側に任せることにする

そして立ち上がった見た目はこんな感じ

![](https://storage.googleapis.com/zenn-user-upload/6d37fddcd739-20231109.png)

予想外だったけどログインページのUIがついている！
ありがとう〜〜
作ったのは[Konstantinさん](https://github.com/terrakok)
ありがとう〜〜

一旦準備終了、[次の記事](https://qiita.com/shunk0616/private/7906f35e7093cc004805)はページ遷移です。
デコポンの皮の呪い（相関がある多次元データ）


・　相関がある高次元データの様子
・　ガウス分布（正規分布）で作成
・　可視化してみる


<a href = "https://qiita.com/emikosh/items/f74bf489851f0fb110f2">「メロンの皮の呪い」（互いに独立した正規分布の多変量）</a> 
https://qiita.com/emikosh/items/f74bf489851f0fb110f2

前回に引き続き、デコポンの皮の呪いも見てみました
<br>


前回は、相関がないガウス分布（正規分布）でデータの距離を計算してみましたが、今回は、がんばって、相関があるデータの皮の厚みが変わるか？を可視化してみました

<br>

### 球面化
変数どうしの間に相関があると、当然、ある変数で0に近いところの観測点は、他の変数でも0に近いところにいるわけで、そうそう中身（＝中心に近いとこ）がスカスカにならないでしょ、ということでどうなんでしょう？
<br>
実際に作ってみました
<br>

<img width="480" alt="gif movie of distribution of d" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/de756aad-dd58-590b-ec33-fb83cd7ccfce.gif">
<br>

<a href = ""https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/16c07523-1c7a-dfa0-986b-9e61931af7c8.gif">独立した正規分布の場合</a>と結構違いますねー。最後のほうがあんまり動かなくて、分散だけ大きくなっているのは、相関行列に使ったレーマー（Lehmer）配列の形が、次元が大きくなるとほぼいっしょになっちゃっているからですかね。


<br>

<img width="480" alt="gif movie of ircular image of d" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/0b0a277e-5845-1935-d047-4207e5d2ef3e.gif">
<br>


そして、円を描いてみると、最初はドーナツ状なんですが、終わりのほうは皮が厚めですね　しかも、分散が大きいので中のほうにもけっこう観測点があるという　

皮が厚めなので、今回題名をメロンではなく「デコポン」にしておきました！
<br>


### レーマー配列
<br>
<img width="480" alt="arry of lehmer" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/ee7bf7d1-6dfc-23ea-815f-271233913954.png">
<br>
<br>
さて、今回レーマー配列というものを使いましたが、最初、相関行列なんて簡単につくれるんじゃない？って、あんまり考えてなかったんですね

ところがどっこい、行列を作ってデータを作成する段になって、いきなりエラーに
こう言われまして　

    相関行列は「半正定値行列」でないといけないよ！




で、なにそれ？半正定値行列ってどうやって作ればいいの？とちょっとwikiを見て、ああ、行列計算！

そりゃそうだ　A変数とB変数と相関があって、B変数がC変数とも相関があったら、A変数とC変数も相関がないといけないわよね

めんどいことが（超）嫌いなので、すでにここであきらめモードでしたが、そのまま調べ続けたらレーマー配列というのを使えばいいそうで、それでとりあえず作ってみました　

ああ、よかった。

比較的簡単に計算できるみたいですが、今回はサンプルを拝借しました　
レーマー行列の中身はこちらで↓

https://en.wikipedia.org/wiki/Lehmer_matrix

<br>


```MATLAB:Decopom.m

% デコポンの皮（次元の呪い）の可視化
% R2023b Matlab 
% with Statistics and Machine Learning Toolbox

clear;
close all;

n = 100;
s = 1000;

rng();

% https://jp.mathworks.com/help/matlab/ref/gallery.html
a = gallery("lehmer", n);

mu = zeros(1, n);
R = mvnrnd(mu, a, s);

% https://jp.mathworks.com/help/stats/gplotmatrix.html#mw_55c0c754-d26e-491e-beac-4ac18cb15a95
gplotmatrix(R(:,1:4),[]) ;

% 原点からの距離の計算
d = zeros(s, 1);

for m = 1:s
    d(m) = norm(R(m, :));
end

figure;
c = 0:1:40;
histogram(d, c);
hold on;
md = mean(d);
st = std(d);
ax = gca;
ax.LineWidth = 1;
ax.FontSize = 14;
yL = ax.YLim;
plot([md, md], yL, '-m', 'LineWidth', 1.5);
plot([md - st, md - st], yL, '--m', 'LineWidth', 1.5);
plot([md + st, md + st], yL, '--m', 'LineWidth', 1.5);

% 注:subspace関数には列ベクトルの形で入力する
% 角度が小さすぎるので、+ rand(1,1) * Pi * 2 で見た目は円に

theta = zeros(s,1);

v1 = R(1, :);
for k= 1: s
    theta(k) = subspace(R(k,:)', v1') + rand(1,1) * pi * 2 ;
end

X = d .* cos(theta);
Y = d.*sin(theta);

figure;
plot(X,Y, '.');
axis equal;
ylim([-100, 100]);
ax = gca;
ax.LineWidth = 1;
ax.FontSize = 14;

```
ここでは相関があるデータを使いましたが、実データの場合で「球面化」というのは、データを固有空間に持っていったときに（超）球面上に観測点が乗ってくることです　次元（例えば400個）に比べてデータ数（例えば10個）が少ないときにそうなっちゃうみたいですね　高次元特有の現象ですね
IntelliJ で AWS CodeWhisperer を触ってみた

この記事は [ミライトデザイン Advent Calendar 2023](https://qiita.com/advent-calendar/2023/miraito-inc) の 5 日目の記事です。

前日の記事は[ブッチ](https://zenn.dev/t_kitamura)さんの ChatGPT の記事でした。

https://zenn.dev/t_kitamura/articles/f3292cf9f90b70

今日は AI 繋がりで、今更感はありますが、CodeWhisperer を触ってみました。

https://aws.amazon.com/jp/codewhisperer/

## 料金

無料で利用できるらしいので嬉しい。

https://aws.amazon.com/jp/codewhisperer/pricing/

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/36aecfed-7c8f-d7ba-3610-030313550e5e.png)

## 利用方法

https://aws.amazon.com/jp/codewhisperer/resources/#Getting_started/

今回は IntelliJ の PHPStorm で使ってみようと思います。

> サポートされている IDE には、Visual Studio (VS) Code と JetBrains の IDE (IntelliJ、PyCharm、CLion、GoLand、WebStorm、Rider、PhpStorm、RubyMine、DataGrip) が含まれます。

VS Code でも利用可能なようです。

 1. AWS Toolkit をインストール

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/fc6a036a-51ea-7687-0a7c-611769b06db6.png)

 インストールを実行して、Apply すると IntelliJ を再起動するか聞かれるので、再起動すると Tools の下に AWS の項目が現れました。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/35e53d3e-b5f3-4c77-39f2-566251aee816.png)

AWS にデータを送信したくない場合は、次の項目のチェックを外しておくと良さそうです。

![スクリーンショット 2023-12-03 18.19.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/d04c45ad-31d4-bb8a-97a7-4e9dc4f47d40.png)

https://docs.aws.amazon.com/codewhisperer/latest/userguide/sharing-data.html


同時に次の画像の項目も現れるので、公式サイトの指示通りに「スタート」ボタンをクリックします。

> AWS 拡張パネルを開き、[開発者ツール] > [CodeWhisperer] の下にある [スタート] ボタンを選択します。

![スクリーンショット 2023-12-03 18.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/c74230a0-5439-ec2d-0d9a-c929e1635f91.png)

すると AWS Builder ID で認証を行う選択肢が表示されるので、ID をすでに持っている場合は、ログインするか新規の ID を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/55f6e295-0530-c7e3-f31e-6c70a2f7fce1.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/0f2dcec4-db1e-394f-ef30-aa5c29ac55c7.png)

認証が完了すれば設定完了です。


## 使用してみる

コメントを書いてエンターで改行すると出てきました。
候補が出てきました。すごい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/74f9fbfb-f8b0-0350-53a8-789019b2dd52.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364773/3d5bc1d8-a129-b514-950f-70db51bf468d.png)

## さらに進化しているらしい

https://aws.amazon.com/jp/blogs/news/new-customization-capability-in-amazon-codewhisperer-generates-even-better-suggestions-preview/

コードを書かなくて良くなる日も近いかも？