OmniAICreator/Qiita-1.07M huggingface dataset:
Next.jsでmarkdownで記事を書けるようする ①

# はじめに
現在、個人ブログサイトを開発中です。
markdownで記事を投稿できるようにしようと思っています。
実装途中ですが経過を共有します。

## 前提
next.jsの開発環境は構築済でmarkdownを適用するところを実装します。

## ステップ 1: ライブラリをインストール
まず、MarkdownをHTMLに変換するため、gray-matterとremark（およびremark-html）をインストールします。

|ライブラリ名|使用目的|
| ---- | ---- |
|gray-matter|Markdownファイル内のフロントマター*を解析します。|
|remark|Markdownの構文解析を行い、データ変換を行います。|
|remark-html|remarkで解析されたデータをHTMLに変換します。|

:::note info
フロントマターとは、Markdownファイルの先頭に記述するメタデータのことです。
```:フロントマターのイメージ
---
title: "My First Post"
date: "2024-09-07"
---
```
:::

では以下のコマンドでインストールします
```bash
npm install gray-matter remark remark-html
```

## ステップ 2: Markdownファイルの作成

`posts`ディレクトリを作成し、その中にMarkdownファイルを作成します。例として、`first-post.md`というファイルを作成します。


```md:posts/first-post.md:
---
title: "My First Post"
date: "2024-09-07"
---

This is my **first blog post** written in Markdown!
```

### ステップ 3: getStaticProps と getStaticPaths で Markdown を取得

pages/posts/[slug].js というページを作成し、動的にMarkdownファイルを取得してHTMLに変換します。

```ts:pages/posts/[slug].js:

import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';

const postsDirectory = path.join(process.cwd(), 'posts');

export async function getStaticPaths() {
  const filenames = fs.readdirSync(postsDirectory);

  const paths = filenames.map((filename) => ({
    params: {
      slug: filename.replace(/\.md$/, ''),
    },
  }));

  return {
    paths,
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  const fullPath = path.join(postsDirectory, `${params.slug}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');

  const { data, content } = matter(fileContents);

  const processedContent = await remark().use(html).process(content);
  const contentHtml = processedContent.toString();

  return {
    props: {
      post: {
        ...data,
        contentHtml,
      },
    },
  };
}

export default function Post({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
    </article>
  );
}
```

# ステップ 4: ブラウザで確認

これで、`posts/first-post.md`の内容が`/posts/first-post`というURLで表示されます。
ブラウザで`http://localhost:3000/posts/first-post`にアクセスすると、
以下のように表示され、markdownがHTML変換されていることを確認できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3369754/8ccaf959-be78-5f60-bb1a-11cc254bf601.png" width=80%>

# まだまだ課題あり

Qiitaのようにもっとリッチなmarkdownになるように調整して続きを投稿していきます。
Promiseについて

promiseについて勉強したのでメモ

promiseのインスタンス化
```js
new Promise((resolve,reject)=>{
    処理
})
```
resolveとrejectはどこから受け取るのか？

JavaScriptエンジンが自動的に提供する。これらの引数は実行関数である。

`.then` resolveしたときに呼び出される

`.catch` rejectされたときに呼び出される

例
```js
const myPromise = new Promise((resolve, reject) => {
    const success = true; // 成功した場合

    if (success) {
        resolve('成功しました!'); // ここで呼び出されるのはJavaScriptエンジンが提供したresolve関数
    } else {
        reject('失敗しました!'); // ここで呼び出されるのはJavaScriptエンジンが提供したreject関数
    }
});

// 使用例
myPromise
    .then((message) => {
        console.log(message); // "成功しました!" が表示される
    })
    .catch((error) => {
        console.error(error); // エラーが発生した場合に呼び出される
    });
```
上の場合const success = true;としてるので、resolveの方が呼び出される。
【ChatGPT＋Code Interpreter】で画像内のパネルを認識できない？　報告と改善


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

　今回は、画像内のパネルを認識できない？問題が発生しましたので、その報告と改善です。

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

　ニュースはないので、
　　さっそく本題です。

　今回は、
　　先日（2024/09/06）と
　　　昨日（2024/09/07）の
　　　　Promptでは
　　　　　画像内のパネルを
　　　　　　正しく認識できないという
　　　　　　　問題が発生しました。
　　　　　　　　その報告と改善です。
[【ChatGPT＋Code Interpreter】で画像内の吹き出しを認識して、赤枠で囲みます。](https://qiita.com/kabumira/items/0ccd8c1e40b77d98ab7a)

[【ChatGPT＋Code Interpreter】で画像の吹き出しに日本語を入れます。](https://qiita.com/kabumira/items/db3a02d54e06964f2440)

　いくつか
　　別の画像を生成して
　　　それに対して、
　　　　上記Promptを実施。
　　　　　すべてOKでした。

　さて、
　　スケッチブックやカンペも
　　　試したし、大きなパネルに挑戦。

　ついでだから、と
　　アニメスタイルから
　　　実写的な画像にしました。

　ところが、
　　範囲認識のPromptだと、
　　　パネル全体を認識しません。

　いやまぁ、
　　危惧はしていましたよ。
　　　危惧は😅

　アニメスタイルだと
　　平らで、白くなる板状のものでも
　　　実写的な画像になると、
　　　　パネル全体が
　　　　　同一の白ではなく、
　　　　　　光の当たり具合で
　　　　　　　うっすら影になる
　　　　　　　　ということは。

　このため、
　　パネルの半分ほどだけが
　　　認識されたんですね。

　人間の目では同じように見えても
　　人工知能からは、はっきりと
　　　違いがわかるわけです。

　さて、どうしよう？

　そこで
　　ChatGPTさんに
　　　“白の閾値は影を考慮して広げて”
　　　　と指示しました。

　“閾値”とは、
***
***Perplexity***
閾値とは

「閾値」（いきち、しきいち）とは、ある基準を超えると変化が生じる境界となる数値のことを指します。これは、特定の反応や動作が起こるために必要な最小の刺激量や作用の大きさを表します。この概念は、生物学や物理学、ITなど多くの分野で使われています。

例えば、ITの分野では、電子回路における高電位と低電位の区別に使われ、プログラミングでは条件分岐の基準として用いられます[4]。また、生理学や心理学では、感覚受容器が反応を起こすために必要な最小の刺激量を指します。

「閾値」は英語で「threshold」と訳され、一般的には「限界」や「境界線」として理解されます。この値を超えると、システムや生体が異なる状態に移行するため、重要な指標となります。
***

　簡単に言うと、
　　ここでは“白い領域”と
　　　指示したわけですが、
　　　　これを“白っぽい領域”と
　　　　　したわけです。

　この指示に達するまで
　　紆余曲折あったのは
　　　想像に難くないのでは？
　　　　オイラだけ？😅
***
　さて、手順に行きましょう。

　手順は
　❶GPT-4oであることを確認
　❷元画像をアップロード
　❸Prompt入力
```Text:吹き出しに赤枠Prompt（New）
OpenCVを使用して、画像内の白い（白の閾値は影を考慮して広げておく）領域を検出し、その領域を輪郭として抽出してください。その後、検出された白い領域の中から最も大きい矩形を特定し、その矩形だけの周りに赤い枠を描画してください。
```
　❹送信
　❺ダウンロードリンクが表示

　出来上がったのがこちら。
![1725763225729.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/d3359c18-6041-bcaf-6e01-1ef55e94400c.jpeg)

　持っている手は
　　範囲外ですが
　　　使用用途的には
　　　　大丈夫ですよね😅

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

　今回は、ここまで。
【忘備録】私がWindows Setupの時に必ずやること

### 私がセットアップ時に必ずやることを忘備録としてメモする
ほかにあれば随時記載したいChromeの保存機能のおかげでやることがかなり減りましたが、メインPCをLinuxにする為、またどこかいつかWindowsに変更するときのために、、

- [x] Wifiの設定
- [x] Onedriveのアンインストール
- [x] Google Chromeのインストール
- [x] Windows + V の有効化
- [x] [作業メモツール](https://qiita.com/qb96messy/items/790b202bfb4c1e3563f6 "自動作業記録ツールを作りたい")の導入
- [x] もし外部ツールのインストールができない場合[VBSで簡易バージョン管理ツール](https://qiita.com/qb96messy/items/6b1503cead7c97b69dd5"管理バージョンツール")を作成したい
- [x] Notionにログイン 
- [x] 上記ツールをStartUpに(Ctrl+Rでshell:setup)に格納
- [x] Git Bashのインストール(ssh接続のため)
- [x] Sakura Editorのインストール
- [x] Pythonのインストール
- [x] Vscodeのインストール
- [x] Android Studioのインストール
- [x] Send Anywhereのインストール
- [x] [Setting] モニターの位置調整
- [x] SSHのインストール 
- [x] 公開鍵の設定
```
#ipaddress確認
$ifconfig
#hostとしての設定
$ssh-keygen -t RSA -b 4096
$ssh-copy-id -i id_rsa user@192.168.1.1
```
- [x] WindowsUpdate 
- [x] [管理ユーザーでフォルダが開けるか確認](https://answers.microsoft.com/ja-jp/windows/forum/all/%E7%AE%A1%E7%90%86%E3%83%A6%E3%83%BC%E3%82%B6/5fd7e04a-65e4-4b95-9ad0-ceae12c87d8c)
uartのこと

SOCやワンチップマイコンにはシリアルのインターフェースがたいていついています。

もともとはuartとはシリアルインターフェースチップの呼び名でしたが、最近はシリアルインターフェースの総称として使わることが多いです。

送信のタイミングはプログラムでわかるのですが、受信はちょっとやっかいです。

受信するには以下の方法があります。
 
* FIFOを当てにしてダイレクトに処理

* タイマーなどのポーリングでバッファ使用

* 受信割り込みでバッファ使用

データ通信での使用でなければ、大量のデータが送られることはなく、一番上の方法でも十分対応できることもあります。

ただしFIFOがオーバーフローするとデータが無くなります。FIFOがフルになる前に処理しなければなりません。

9600bpsで16バイトのFIFOがある場合、1バイトは10ビットで送らるので、0.016秒でFIFOがフルになります。

シリアル通信の重要度も下がっていて、あまり複雑にしないほうがよいかもしれません。

処理系によって受信の関数は受信するまで待つものと、待たないものがあります。また受信しているかを確認する関数を用意していることもあります。

受信と送信は非対称な処理になります。

USBのCDCでもシリアルインターフェースとして使えますが、処理が大変なので、物理的なuartの方が楽です。
iphoneのsafariで電話番号が勝手に改行されてしまう

# はじめに
開発者ツールのモバイル版で電話アイコンと電話番号を横並びに表示するよう実装していたのですが、iphone(ios)のsafari上ではアイコンと電話番号が改行されていました。

# 原因
先輩からの助言もあり、問題特定のために、iphoneとmacを接続し、macの開発者ツールを起動しました。電話番号箇所を確認すると、**テキストからaタグに変換されていたこと**が原因でした。cssファイルでaタグを`display: block;`に指定していたため、予期せぬ形で`display: block;`が効き改行されていました。このaタグへの変換はios特有の動きらしいです。

# 解決策
電話番号箇所のaタグを`display: inline;`に指定することで改行されずにアイコンと電話番号を横並びに表示できました。

# 参考記事
- https://qiita.com/yutomaeda5510/items/f78d60038e2af34f67f0
- https://mubouan.hatenablog.com/entry/2021/06/12/133600
- https://toriton.link/coding/tel_style/
- https://code-sq.com/invalid_tell_link/
認証と認可の違い

# はじめに
ログインや機能制限を持つシステムに関わってきたが、
今ある仕組みを理解し動きで理解していた。
一段上の概念レベルで理解する機会がなかったので情報を整理する。

### 認証（Authentication）
定義：ユーザが誰かを確認し、利用する権利があるか判断する
目的：ユーザの身元を確認する

利用例：
- システムへのログイン（ユーザIDとパスワード、生体認証（指紋、顔認証）
- ログイン後の検証（セッション、トークン）

### 認可（Authorization）
定義：認証されたユーザがどの資源や機能にアクセスできるかを決定するか判断する
目的：適切なアクセス権を付与する

利用例：
- 認証済みユーザの利用可能な資源や機能の制御

### 認証（Authentication）と認可（Authorization）の関係
認証が成功した後に認可を行う。
まず認証、ユーザがシステムにログイン、
その後認可、認証されたユーザがどの資源や機能にアクセス可否が決定する。

### 所感
認証の「証」から個人を証明すること、
認可の「可」から可否を決定することって覚えておくのが良さそう。
[Ruby] if文とcase文の使い分け

社内勉強会でcase文の中でfindパターンができた話を聞いていたら、if文とcase文ってなんで別々に存在するのだろう、という疑問が湧いた。

なんとなく分岐が多い時に可読性をあげたりすることができるのかなと思っていたが、caseの優れたところがあったため、まとめてみた。

## `===`演算子の活用
そもそもRubyって`===`演算子があるの？というところから始まった。JavaScriptだとよく見かけるのだが...以下ブログがすごくわかりやすかった。

https://qiita.com/Siva0410/items/c0b6ed52017ffada8bf4

要するにゆるい`==`で、サブクラスの所属まで検知してくれるとのこと。
なので、オブジェクトや`..`を使った範囲内のものに属するかを検知することができる。

以下がその例である。

### 1. 数値の範囲
``` ruby
age = 25
case age
when 0..12
  puts "子供"
when 13..19
  puts "10代"
when 20..64
  puts "大人"
else
  puts "シニア"
end
```

### 2. 正規表現

``` ruby
email = "user@example.com"
case email
when /^[a-z0-9]+@gmail\.com$/
  puts "Gmailアドレス"
when /^[a-z0-9]+@yahoo\.com$/
  puts "Yahooアドレス"
else
  puts "その他のメールアドレス"
end
```

### 3. クラスの比較

``` ruby
obj = [1, 2, 3]
case obj
when String
  puts "文字列です"
when Array
  puts "配列です"
when Hash
  puts "ハッシュです"
else
  puts "その他のオブジェクトです"
end
```

### 4. Procオブジェクト

``` ruby
is_even = proc { |n| n.even? }
number = 4
case number
when is_even
  puts "偶数です"
else
  puts "奇数です"
end

# 同等のif文
if is_even.call(number)
  puts "偶数です"
else
  puts "奇数です"
end
```

## 他にも違いが

- 構文の簡潔さ: case文は複数の条件を比較する際に、if-elsif-else構造よりも簡潔に書くことができる
- 値の代入: case文では、whenの条件に合致した場合の値を直接代入できる
- パフォーマンス: 多くの条件分岐がある場合、case文の方がif-elsif構造よりもちょっとだけ早いことがある

## おわりに
そういえばJSではifとswitchの差があるのだろうか。調べてみたい。
vim備忘録 1日目

# vimを使い始めた経緯
B3夏休みの自由研究(?)としてraspberrypiを使ってみた。VNCによるGUI操作でもよかったが、折角ということでCLI操作をしたくなったので、おのずとvim操作が必要になった。
bashでvimコマンドを打ってファイルを開く方法は省略。今回はvimエディタ内でのコマンドをどう覚えていったか記録する。

# vimをそこそこ使いこなせてる感になるまで
### ノーマルモードと挿入モード
`Esc`　ノーマルモード(困ったらこれ押して安置移動)
`i` 挿入モード(ファイルを編集したいとき)

まずはここを理解した。google colabで似た操作をしたことがあった。
挿入モードは文字を実際に操作するモード。ノーマルモードは普段のvscodeにはないような、メタモード。初めは挿入モードが自分にとってのノーマルな気がしたので違和感があった。
この二つを覚えれば編集ができる。


### やり直し
`u`　undo (windowsの`Ctrl + z`)
(`Esc`押した状態で)

意外とこれを知るのが遅くて苦戦していた。どんな編集をしても`u`を連打すればもとに戻るので安心。一応`Ctrl +Z`で強制終了しても元に戻る。

### ファイルの保存
`:w` ファイルの保存
`:q` vimを終了する
ノーマルモード(メタモード)の時に`:`を押すことで、画面の下の方にターミナルのようなメタメタモード(?)が現れる。
ここでファイルレベルでの操作ができる。`:w`からの`:q`でvimから脱出！


## ここまでのまとめ
`Esc`でファイルを俯瞰操作して、`i`でメモ帳やvscodeのような通常のファイル編集。変なことしてやり直したくなったら
`Esc`で逃げて`u`連打。ひとまずvimってこんなものかと体験できたら、`:w`で保存して`:q`でvimから抜け出す。

これに慣れたら、予測変換ってどうするんだろう？移動をもっと早くできないかな？ファイル間の移動は？コピペは？...という風に次のステップに進んでいった。
[Binary Tree] 2分木の走査法

# 一覧
|走査法|詳細|
|:--|:--|
|幅優先探査|根に近い順に調べる|
||![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/4e2af02d-e2a8-872e-1d08-a8704a3aff5a.png)|
|深さ優先探査||
|先行順|**節**→左部分木→右部分木|
||![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/978f732e-84fe-0aad-4cbc-33c7f6fbb09b.png)|
|後行順|左部分木→右部分木→**節**|
||![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/da4edb31-b2a1-f7f3-66d3-76496bf23eca.png)|
|中間順|左部分木→**節**→右部分木|
||![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/ca9b6418-5535-1bf0-be21-1de2891f1402.png)|


# 参考リンク
- [令和3春6](https://www.ap-siken.com/kakomon/17_aki/q10.html)
JavaScriptの関数とオブジェクトとクラス

# はじめに
「クラス」と「オブジェクト」と「関数」について使い分け方を迷ったので整理する。
選択肢は適材適所に応じて選べるメリットだが選べることで適さない選択してしまう可能性もある。
そこで少しでも悪い選択をしないように特性を把握しておく。

<table>
  <caption>違い（簡易比較）</caption>
  <thead>
    <tr>
      <th>対象</th> 
      <th>typeof</th> 
      <th>説明</th> 
      <th>用途</th> 
    </tr>
  </thead>
  <tr>
    <td> 関数</td> 
    <td>function</td> 
    <td>一連の命令をカプセル化したもの（オブジェクトの一種）</td> 
    <td>特定のタスクを実行</td> 
  </tr>
  <tr>
    <td>オブジェクト</td> 
    <td>object</td> 
    <td>キーと値のペアのコレクション</td> 
    <td>データの構造を表現</td> 
  </tr>
  <tr>
    <td>クラス</td> 
    <td>function</td> 
    <td>プロパティとメソッドを持つオブジェクトのテンプレートとして機能する構文</td> 
    <td>インスタンスを生成してオブジェクトを作成</td> 
  </tr>
</table>

# 例として宣言する処理
円の半径を受け取って円の面積(半径×半径×3.14(= 円周率))を求める

# 関数
```javascript
function calculateCircleArea(radius) {
    const PI = 3.14;
    return PI * radius * radius;
}
console.log(calculateCircleArea(5));               // 出力: 78.5
```
# オブジェクト
```javascript
let circle = {
    getArea: function(radius) {
        const PI = 3.14;
        return PI * radius * radius;
    }
};
console.log(circle.getArea(5));                    // 出力: 78.5
```
# クラス

```javascript
class Circle {
    getArea(radius) {
        const PI = 3.14;
        return PI * radius * radius;
    }
}

let circle = new Circle();
console.log(circle.getArea(5));                    // 出力: 78.5
```

クラスのみnewする必要はあるが似た構文で同じ結果を得ることが可能。

上記３つの例は無理やり似た記載にしたので修正する。
修正としては本来オブジェクトは「データ構造を表現」し、クラスは「インスタンスを生成してオブジェクトを作成」するものなので半径をプロパティに修正。

# オブジェクト（プロパティ追加）
```javascript
let circle = {
    radius: 0,                                     // 半径
    setRadius: function(r) {                       // 半径のset
        this.radius = r;
    },
    getArea: function() {                          // 円の面積を計算
        const PI = 3.14;
        return PI * this.radius * this.radius;
    }
};
circle.setRadius(5);                               // 半径を設定
console.log(circle.getArea());                     // 出力: 78.5
```

# クラス（コンストラクタとプロパティ追加）
```javascript
class Circle {
    constructor(radius = 0) {                      // コンストラクタ
        this.radius = radius;                      // 半径
    }

    setRadius(radius) {                            // 半径のset
        this.radius = radius;
    }

    getArea() {                                    // 円の面積を計算
        const PI = 3.14;
        return PI * this.radius * this.radius;
    }
}

let circle = new Circle();
circle.setRadius(5);
console.log(circle.getArea()); // 出力: 78.5
```

# 使いわけ
#### 関数
- 単純な計算や処理を行う場合
#### オブジェクト
- 状態と振る舞いを持つ単一のエンティティを表現する場合
#### クラス
- 複数のインスタンスを生成する必要がある場合

（場数を踏んでもう少しメリデメを感じて使い分け方を洗練する必要がありそう）
JavaScriptの関数定義

# はじめに
JavaScriptの関数は複数の異なる記載方法で同じ動きをする`関数`を定義できる。

書き方と書き方による違い理解していないと困るので整理する。
また、関数定義方法と`this`の動作の違いを分類する。

最終的にどう書くかは、
各々が好きな方法ではなくコーディングルールの沿って書くことが望ましい。

## 例として宣言する関数
入力された二つの引き数の合計値を戻す関数

## 関数定義方法の一覧（４種類）

### （１／４）通常の関数
```javascript
function add(a, b) {
    return a + b;
}
console.log(add(2, 3)); // 出力: 5
```

### （２／４）関数式
```javascript
const add = function(a, b) {
    return a + b;
};
console.log(add(2, 3)); // 出力: 5
```

### （３／４）アロー関数（その1）
```javascript
const add = (a, b) => {
    return a + b;
};
console.log(add(2, 3)); // 出力: 5
```

### （３／４）アロー関数（その2、return省略）
```javascript
const add = (a, b) => a + b;
console.log(add(2, 3)); // 出力: 5
```


### （４／４）即時実行関数（IIFE）
※ IIFE：Immediately Invoked Function Expression
```javascript

(function(a, b) {
    console.log(a + b);
})(2, 3); // 出力: 5
```

結論として即時実行関数は、
JavaScriptのバージョンアップにより現在は積極的に使う必要はない。

以下の目的で使うことができるが前述のとおりいずれも代替可能で、
「どちらが良いか」となったときに即時実行関数を優先することはない。

**【即時実行関数で表現できること】**
+ スコープの分離
+ 初期化コードの実行
+ プライベート変数の作成
+ コードのモジュール分割


## グローバルスコープにおける関数定義方法とthisの動作の違い
JavaScriptにおいてthisは関数以外で使用すると意味が変わる。
癖があるのでグローバルスコープにおける関数定義方法で動作に違いがあるという情報の記載に留める。

大きく以下の２つの動作。
#### 【thisはグローバルオブジェクトを参照】
- （１／４）通常の関数宣言
- （２／４）関数式
- （４／４）即時実行関数（IIFE）

#### 【thisは外側のスコープを参照】
- （３／４）アロー関数
【覚書き】Base64エンコードは圧縮やセキュリティー向上ためのものではないらしい

# 初めに
今までなんとなく利用していたBase64エンコードですが、実際どんなことをしているのかよく分かっていませんでした。
「圧縮してパフォーマンス向上？」「暗号化してセキュリティー向上？」くらいに思っていたのですが、どうやらそんなことはないみたいです。

今回は、Base64エンコードの方法とその目的についてまとめます。

# Base64エンコードとは
Base64エンコードとはエンコードの手法の一つです。データを64種類の文字で表すようにエンコードをします。

64種類の文字はアルファベット（`a-z`と`A-Z`）、数字（`0-9`）そして一部記号（`+`,`/`）の64種類で構成されます。

# Base64が圧縮できない理由
本題です。Base64ではデータを圧縮することはできません。
その理由は、Base64のアルゴリズムにあります。

以下はBase64のアルゴリズムの説明です。

```: Base64のアルゴリズム
Hello

　↓　バイナリデータ（2進数）に変換

0100100001100101011011000110110001101111

 ↓　6ビットごとに区切る

010010 000110 010101 101100 011011 000110 1111

 ↓　6ビットに足りない場合、0埋めする

010010 000110 010101 101100 011011 000110 111100

 ↓　各6ビットを対応する文字に置き換える

S G V s b G 8

 ↓　数が4の倍数個になるように、「=」で埋める

SGVsbG8=
```

この通り、「Hello」の5文字が「SGVsbG8=」という8文字にエンコードされました。

Base64では変換の過程でバイナリデータを6ビットごとに分割します。対して、UTF-8でエンコードされた文字は1文字に8～32ビットを使います。そのため、Base64でエンコードをした際は文字が長くなってしまいます。


## Base64がセキュリティ向上で使われない理由

上述のエンコード過程をご参照ください。
Base64では各6ビット配列を文字に直すことしかしていません。だれでも簡単にデコードすることが可能です。そのため、セキュリティー向上のために利用することはできないのです。

# Base64エンコードの目的
圧縮もセキュリティ向上もできないBase64は何目的で利用されるのでしょうか。

## 目的1：バイナリデータの送信
HTTPなど一部のプロトコルは、画像や音声などのバイナリデータをそのまま扱うことはできません。扱うためにはテキストデータに直す必要があります。
Base64はバイナリデータをテキストに変換することが可能なため、その用途で利用されます。

## 目的2：非ASCIIデータをASCIIに変換
SMTPやURLなどでは、漢字やひらがななどの非ASCIIデータを扱うことができません。
Base64で扱う文字は全てASCIIデータのため、そのようなプロトコルで非ASCIIデータを扱うために利用されます。

:::note info
ASCIIとは、英語のアルファベット、数字、記号、制御文字を7ビットで表現する文字コードのことです。
7ビットなので、6ビットのBase64の倍の128種類の文字が利用されます。
:::


# 終わりに
今までよくわからずに使っていたBase64ですが、アルゴリズムや目的が理解するのは面白いですね。
Base64以外にも様々なエンコード方式がありますが、ただ仕様に沿って実装するだけでなく、目的やアルゴリズムを理解した上で実装するのが大切ですね。

ここまでご覧いただきありがとうございました！

# 参考
https://qiita.com/PlanetMeron/items/2905e2d0aa7fe46a36d4
プログラム爆発の予感(杞憂?)について

# はじめに
ちょっと、衝撃的な考え方かもしれませんが、いま、自分でプログラムを作成していて、そんな予感をもっています。もしかしたら、自分だけかもしれませんが、どのような予感なのかを述べてみたいと思います。

# その予感とは 
今まで、いろいろなコードを作成してきました。それまでは、何とか不具合を起こすことなく、動作してきたと思っています。それはたまたまだったのかもしれません。

世の中を見ると、至るところで、プログラムの不具合が発生していて、基幹システムでも発生しています。エラーが全くないシステムはないのかもしれません。おそらく、ある程度のエラーはあらかじめ想定内のことなのかもしれません。エラーのないシステムはありえないということかもしれません。

ソフトに限らず、ハードである車や水道管なども経年変化による不具合が発生しています。そのため、システム維持のための保守が必要になります。残念ながら、きちんと保守をしているから大丈夫ということは100%言えないと思います。保守をしていても不具合は起こります。

航空機でさえ、そうです。人命を預かっていますが、やはり不具合による事故は起こっています。こう考えると、不具合によるトラブルは想定内のこととして、認めていることだと思います。

100%安全なシステムはありえないということだと思います。

若い頃、あるシステム装置の電子回路基板を設計・開発していました。
それは、油圧装置の力を利用して制御バーをコントロールするための基板でしたが、電子回路上は、制御してオーバーコントロールしないようにしていましたが、万が一のことを考えて、暴走を止めるための機械的なストッパーを設けていました。油圧の力で、人を押しつぶさないようにするためです。

話がそれてしまいましたが、今の時代は、どんなシステムにもプログラムを組み込んでいます。プログラムは人が作っています。最近AI(人口知能)が作っているとはいいますが、ベースは人が作ったものです。

そのプログラムですが、増々、複雑化してきて、今作成しているプラグインのプログラムは自分でもわからないくらいです。原因のもとは、動的処理のためのイベント処理が複雑に入り乱れてきたためです。様々なケースがあるため、デシジョンテーブルを作って、組み込んでいますがうまく動作しません。

不具合のもとは、おそらく、複雑な条件表の実装で起こっているのかと思います。複数の条件があり、それらの条件を満たしたときにある処理を行うというのものですが、この組み合わせが膨大になるともうお手上げです。

整理すれば、もっとシンプルになるのかもしれませんが、いま、取り組んでいるところです。

冒頭のタイトルにある、プログラム爆発ですが、これは、火山の爆発と同じで、どうにもこうにも耐えきれなくなり、爆発するというものです。今、世の中のシステムは過去から作ってきた膨大なプログラムで運用されてきています。多くの人手により作成してきたものです。

プログラムのもとは、0か1のビット単位のデジタルをもとに作られています。だからと言って、スキッキリと割り切れたものかというとそうではありません。中にはかなり危険スレスレのところで動作しているかもしれません。そのうち、耐えきれなくなり、ダムが決壊するように、火山が爆発するようになることが心配です。

# あとがき
これは、杞憂かもしれません。今後は、整合性のとれたきちんとしたプログラムシステムで社会が動いてゆくのかもしれません。AIが助けてくれるのかもしれません。
プログラム爆発が起こらないことを願うのみです。
意思決定理論を一貫性テストとして捉える

# はじめに

Itzhak Gilboaの不確実性下の意思決定理論を学びます。

https://www.youtube.com/watch?v=UxGyX5BnM-I


https://www.keisoshobo.co.jp/book/b147056.html


## スライドまとめ

https://speakerdeck.com/__ymgc__/itzhak-gilboa-talks-on-decision-theory-as-a-test-of-coherence

---
## Appendix
### Wicked problem

Wicked problemとは、複雑で定義が困難な社会的または文化的な問題のことを指す。この概念は1970年代にHorst Rittelとmelvin Webberによって提唱さた。

典型的なWicked problemの例としては、気候変動、貧困、教育改革、都市計画など。

Wicked problemの主な特徴は以下の通り。
- 明確な定義が難しい
- 完全な解決策がない
- 解決策は「正解」または「不正解」ではなく、「より良い」または「より悪い」と評価される
- 問題の理解と解決策が相互に依存している
- 一回限りの解決策では対処できない
- 多くのステークホルダーが関与し、それぞれ異なる価値観や目標を持っている
- 他の問題と密接に関連している

典型的なWicked problemの例としては、気候変動、貧困、教育改革、都市計画などが挙げられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/27ffd2a5-225a-a1be-c136-ba178b5a05b4.png)

引用元：https://creativeog.com/?p=539
PCのファンがうるさい

### 概要
　win10とlinuxの両方から、TurboBoostを無効にする方法。

### 背景
　win10とlinux_mintのデュアルブートPCを作りたくて、もともとwin8がプリインストールされていたパソコンを格安で入手した。起動すると、ファンがフル回転で、うるさすぎる。

　CPUのグリスを塗り直したり、ファンの清掃をしてみたものの、起動と同時にファンがフル回転する。

　調べてみると、このパソコンは、OSがCPUの温度をモニターし、CPUが70度を超えないように、ファンが回るようだ。ファンの回転数を下げるのは危険すぎる。
 
　さらに調べてみると、このパソコンで使われているCPUには、TurboBoostという機能があり、デフォルトで有効になってるらしい。（800MHz-2.30GHz、TurboBoost 3.40GHz）

　TurboBoostは、クロック数を引き上げることで、CPUの性能を高める機能で、いわば、日常的にオーバークロックするような機能である。これでは、ファンがフル回転のはずである。

　そこで、TurboBoostの無効を試みる。

　TurboBoostの有効／無効の切り替えは、パソコンによっては、BIOSで設定できる。しかし、このパソコンのBIOSには、そのような項目がない。そのような場合は、OSで設定するようだ。今回は、dualbootなので、win10とlinuxの両方から設定する必要がある。

### win10からTurboBoostを無効にする

「電源プランの編集」＞「詳細な電源設定の変更」＞「プロセッサの電源管理」に入る。

しかし、TurboBoostの有効／無効を設定できるはずの「プロセッサ パフォーマンスの向上モード」がない。

そこで、レジストリエディタ(regedit.exe)を起動する。

レジストリエディタのアドレスバーに以下を入力する。 `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\54533251-82be-4824-96c1-47b60b740d00\be337238-0d82-4146-a960-4f3749d470c7`
`Attributes` を `2` にする。

レジストリへの設定が完了すると、以下のように「プロセッサ パフォーマンスの向上モード」が追加されるので、「無効」にする。

![TurboBoost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224341/75ffec39-a5db-0e8e-ad56-267fe90fa914.png)


結果、win10を起動しても、静かになった。

しかし、linuxを起動すると、当たり前だが、ファンはフル回転である。

### linuxからTurboBoostを無効にする

```console:bash
$ apt install cpufrequtils // toolをinstall

$ cpufreq-info // cpu情報を取得、800MHz-3.40GHzだとわかる。
hardware limits: 800 MHz - 3.40 GHz
current policy: frequency should be within 800 MHz and 3.40 GHz.

$ nano /etc/default/cpufrequtils // 設定ファイルを作成、中身は下記のとおり。
ENABLE="true"
GOVERNOR="powersave"
MAX_SPEED=2.30GHz
MIN_SPEED=800MHz

$ sudo systemctl restart cpufrequtils // サービスを再起動

$ cpufreq-info // cpu情報を取得、800MHz-2.30Mhzに制限されているのがわかる。
hardware limits: 800 MHz - 3.30 GHz
current policy: frequency should be within 800 MHz and 2.30 GHz.
```

結果、linuxを起動しても、ファンは静かになった。
不確実性下の意思決定理論 に入門する

# はじめに

不確実性下の意思決定理論を学びます。

https://www.keisoshobo.co.jp/book/b147056.html


## スライドまとめ

https://speakerdeck.com/__ymgc__/bu-que-shi-xing-xia-noyi-si-jue-ding-li-lun-ru-men


## 不確実性下の意思決定とは
- 意思決定理論は「よりよい意思決定」を追究する学問領域
- 意思決定の定義：ある状況下で複数の選択肢から1つを選ぶこと
- 数学的表現：
  - 状況 $x=(x_1,x_2,\ldots,x_N)$、選択肢 $y=(y_1,y_2,\ldots,y_M)$
  - 意思決定の結果：$c_{ij}=f(x_i,y_j)$
- 不確実性下の意思決定：状況が確率的にしか判断できない場合の問題
- 理論的アプローチ：結果 $c_{ij}$ の期待値最大化を考える

## 意思決定と情報量
- 情報量は意思決定の精度向上に重要
- 情報量の定義：「不確実性の減少量」
- 情報エントロピー（H）を用いた不確実性の数値化：
  - $H(x)=-\sum_{i=1}^N P(x_i)\log_2P(x_i)$
- 具体例：
  - 2つの状況（N=2）で最大不確実性：$H(x)=1$
  - 新情報により確率更新（50%→75%）：$H(x)\approx0.81$
  - 情報量：$1-0.81=0.19$ bit
- 情報量がゼロの情報も存在（何も言っていない文章など）

## 情報の価値
- 定義：情報使用/不使用時の結果の期待値の差異
- 情報の価値の3ステップ：
  1. 情報による行動の変化
  2. 行動変化による結果の変化
  3. 変化前後の結果の差異
- 行動変容を引き起こさない情報に価値はない
- 「分からない」という情報にも価値がある場合がある
- 情報取得のコストを考慮する必要性

## 意思決定の実践
- 意思決定パラメータ数の削減が重要
- パラメータ削減の3つの方法：
  1. 変数の独立性評価
  2. 変数の不確実性評価
  3. 意思決定の階層化
- 人間が議論する場合、パラメータ数は3つ以内が理想的
- KPIツリーの活用：
  - KGIの設定とKPIツリーへの分解
  - 変数間の独立性/従属性の整理
  - 従属性の高い変数の統合
- 不確実性の高いパラメータの優先的選択
- 意思決定プロセスの適切な粒度での分割・委譲
  - 例：プロダクトチーム vs. 経営企画チーム

## 意思決定とセンスメイキング
- 規範的アプローチ：
  - 数学的論理に基づく客観的な最適解を追求
  - 公理的ルールと数学的論理を使用
- 現実社会の意思決定：
  - 人々は必ずしも数学的に最適な選択をしない（行動経済学の知見）
  - 合理性は主観的で、人によって異なる
- 集団における意思決定の難しさ：
  - 様々な考え（合理性）を持つ人々の存在
  - 政策決定などの社会全体に影響を与える意思決定
- センスメイキングの重要性：
  - 意思決定（decision making）に加えて
  - 人々が意思決定に納得するプロセス（sense making）も考慮

## まとめ
- 不確実性下の意思決定理論：不確かな状況下でのよりよい意思決定のための科学的アプローチ
- 情報量：不確実性の減少量を表す指標
- 情報の価値：行動変容と意思決定結果の変化に基づく
- 実践的アプローチ：
  - 意思決定パラメータの削減
  - 変数の独立性・不確実性評価
  - 意思決定プロセスの分割・委譲
- 合理性の主観性：個人や集団によって異なる
- 集団意思決定におけるセンスメイキングの重要性

---
## Appendix
### Wicked problem

Wicked problemとは、複雑で定義が困難な社会的または文化的な問題のことを指す。この概念は1970年代にHorst Rittelとmelvin Webberによって提唱さた。

典型的なWicked problemの例としては、気候変動、貧困、教育改革、都市計画など。

Wicked problemの主な特徴は以下の通り。
- 明確な定義が難しい
- 完全な解決策がない
- 解決策は「正解」または「不正解」ではなく、「より良い」または「より悪い」と評価される
- 問題の理解と解決策が相互に依存している
- 一回限りの解決策では対処できない
- 多くのステークホルダーが関与し、それぞれ異なる価値観や目標を持っている
- 他の問題と密接に関連している

典型的なWicked problemの例としては、気候変動、貧困、教育改革、都市計画などが挙げられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/27ffd2a5-225a-a1be-c136-ba178b5a05b4.png)

引用元：https://creativeog.com/?p=539
ABC370回答メモ

# 0.はじめに
　久々にデイリートレーニング等をやって気合を入れて挑戦。
　結果はABCの3問しかとけずいつも通り・・・。
　Dは行けそうに感じましたが、解説を見たら行けそうになかったです。
　レートは-1とまぁレートにあった成績だったようです。


# 1.A - Raise Both Hands
　ちょっと問題文の理解に時間がかかった問題。
　まぁ素直に言葉通りに
　L=1、R=0の時 Yes
　L=0、R=1の時 No
　上記以外はInvalid
　と、実装してACでした。

　https://atcoder.jp/contests/abc370/submissions/57506634

# 2.B - Binary Alchemy
　Bなのにややこしいなと思いましたが、
　インプットをもとにリストを作ったら
　あとは、
　ansに1をセット
　for文で、iを1～Nで回す
　　ans>=iの時はansにA[ans-1][i-1]をセット
　　ans<iの時はansに=A[i-1][ans-1]をセット
　最後にansを出力
　でACでした。

　最初、問題文をよく読まず、初手を1と1の融合ではなく
　１と2の融合で作ってしまい、WAとなってしまいました。
　引っかかった人多そうだなと思いました。

　https://atcoder.jp/contests/abc370/submissions/57518138


# 3.C - Word Ladder
　こちらも問題文をよく読まず、簡単だな！と思ってしまいましたが
　最後のリストが辞書順にならないといけないというのを見落としてました。

　提出前に気づき、考察。解説には素直に全パターン試しても間に合うとありましたが
　コンテスト時はC問題だし間に合わないだろうと以下のような考え方で実装
　【考え方】
　　まず、Ｓ[i]>T[i]の箇所を先頭からＳ→Ｔに変換
　　その後、S[i]<T[i]の箇所を末尾からＳ→Ｔに変換
　　こうすることで、辞書順に小さい方からのリストができる。
　【実装】
　　1.各入力を読み込む（SとTはリスト化して入力）
　　2.答えを格納するリストXを空で定義
　　3.リストLを空で定義
　　　リストLは、以下の2要素で構成されるタプル型を格納
　　　要素１：Ｓ[i]>T[i]の時0、S[i]<T[i]の時1
　　　要素２：要素１が0の時i、1の時i×-1（ソートした時、降順に並ぶように）
　　4.SとTを一文字ずつ比較して、リストLを作成
　　5.リストLを昇順ソート
　　6.リストLを順に読み、以下の処理を実行
　　　-1.要素１が0の時、S[要素2]にT[要素2]をセット
　　　-2.要素１が1の時、S[要素2*-1]にT[要素2*-1]をセット
　　　-3.XにリストSをjoinして追加
　　7.Xの長さを出力
　　8.Xを1つずつ出力

　https://atcoder.jp/contests/abc370/submissions/57532862


# 4.D - Cross Explosion
　コンテスト時はどうしてもTLEが消えず、時間切れ。
　解説をみるとちょっと理解できませんでしたが
　Union-Find木をを用いた別解を見てしっくりきて
　解説の実装例を模写しつつ、自分なりに解説を
　加えて理解できました。

　以下余談

　コンテスト時1回目の解答
　　・試しに素直に実装してどれくらい時間が足りないかをつかむ
　　　爆弾が落ちた時の処理は落ちたマスの隣のマスから1つずつ
　　　→TLE４つと意外とちょっとした工夫で行けそうな感じ
　コンテスト時２回目の解答
　　・そのマスに爆弾が落ちた回数を記録しておき
　　　爆弾が落ちた時の処理は落ちたマスの落ちた爆弾数分先のマスから1つずつ行う
　　　→TLE3つとちょっと改善。
　コンテスト時３回目の解答
　　・そのマスに爆弾が落ちたかと、落ちた時は前回落ちた時何マス先の壁を壊したかを記録しておき
　　　爆弾が落ちた時の処理は、何マス先の壊したかの記録分先のマスから1つずつ行う
　　　→時間が迫っていて慌てたためかＷＡ、ＴＬＥも1個あったのでどのみちだめ。
　と、あがいていました。

　https://atcoder.jp/contests/abc370/submissions/57562413


以上
小道具：IPv6 - ULA プリフィクスの生成


RFC 4193 - 3.2.2 を使って Ethernet などの MAC アドレスから Unique Local IPv6 Unicast Addresses プリフィクスを生成します。

```python:genulaprefix.py
#!/usr/bin/env python3

import argparse
import hashlib
import time
from struct import pack, unpack


parser = argparse.ArgumentParser()
parser.add_argument('ether', metavar='MAC')
args = parser.parse_args()

mac = bytes([int(b, 16) for b in args.ether.replace('-', ':').split(':')])
if len(mac) != 6:
    print(f'未知の MAC アドレス: "{args.ether}"')
else:
    # 現在時刻を 64bit NTP 形式で得る
    #   [date(1970,1,1) - date(1900,1,1) = 25567 days] * 86400 = 2208988800
    ntp64 = pack('>Q', ((time.time_ns() + 2208988800 * 10**9) << 32) // (10**9))

    # EUI-64 を MAC アドレスから作る
    eui64 = bytes([mac[0] ^ 2, *mac[1:3], 0xff, 0xfe, *mac[3:]])

    # SHA1 を使って Global ID を得る
    fh = hashlib.sha1()
    fh.update(ntp64 + eui64)
    gid = fh.digest()[-5:]

    # IPv6 アドレス プリフィクスを作る
    ulap = ':'.join(f'{h:x}' for h in unpack('>3H', b'\xfd' + gid))
    print(f'ULA Prefix = {ulap}::/48')
```

```console:実行結果
$ python3 genulaprefix.py 12:34:56:78:9a:bc
ULA Prefix = fdd2:f08b:fba8::/48
$ python3 genulaprefix.py 12:34:56:78:9a:bc
ULA Prefix = fd95:b84:924f::/48
```

現在時刻を time.time_ns() で取得しているので毎回変わります。
【理論】ゲーム制作に於けるクオリティの上げ方

## はじめに

僕が子供向けプログラミングサイトの「Scratch」を約9年、
3Dゲームの開発などで使われる「Unity」を約3年使ってきた中で、
経験を基としてゲームのクオリティの上げ方を書いたものです。

:::note warn

現在は趣味の中でのプログラミングですので、
プロと比べるとやや情報としては劣ってしまうかもしれませんがご了承ください。
:::

## STEP1 : 要素を羅列しよう

まずはゲームにどんな要素があるか知る必要があります。
基本的に **「競争」「運・偶然」「模擬・模倣」「眩暈」** に分類[^1]されます。
例えばアクションゲーム[^2]なら下のように分類できます。
| 分類 | 例 |
|:-:|:-:|
| 競争  | 敵を倒すこと  |
| 運・偶然  |  敵の行動 |
| 模擬・模倣| 派手な演出 |
| 眩暈 | 必殺技|

## STEP2 : 改善点を挙げよう
面白くできそうな要素が見つかったらそれを良くしていきましょう。
具体的には下のようにするのが基本です。

| 分類 | 面白くする方法 |
|:-:|:-:|
|競争|ゲームバランスの改善|
|運・偶然|運による損得やCPUの改善|
|模擬・模倣|細かなシステムの追加[^3]|
|眩暈|演出|

 **「ゲームバランスの改善」** は簡単です。
対戦などで敵の攻撃力を下げたり、自分の攻撃力を下げたりと要はゲームを簡単に
クリア、ゲームオーバーさせないようにすることです。

 **「運による損得やCPUの改善」** は理不尽なところをなくすことです。
例えばソシャゲのガチャで良いものが全く出ないだとか
セーブポイントに敵が近寄るだとか初見の人にとって理不尽な環境をなくすことです。

 **「細かなシステムの追加」** はRPGのシンボルエンカウントなどで草むらに隠れていれば
モンスターが追って来ないなどの知っていれば得になるネタのことです。

 **「演出」** はキャラクターのカットインや敵の登場など驚くようなことです。

 これを先ほどの例として挙げたアクションゲームの改善点に当てはめるとこうなります。

 | 改善点 | 改善方法 |
|:-:|:-:|
| ゲームバランスの改善  | 敵の攻撃力を自分のHPの1/8ぐらいにする  |
| 運による損得やCPUの改善  | CPUがガードを使う確率を減らし膠着状態になるのを避ける  |
| 細かなシステムの追加  | 隠し場所でアイテムが手に入るようにする  |
| 演出  | 必殺技にカットインをつける  |

## STEP3 : 試行錯誤や微調整をしよう

数値などを修正したから終わりではなくて、試行錯誤し、
ゲームとして成り立っているか確認する必要があります。
例えば先ほどの例だとこのようなことが起きる可能性があります。

 | 改善方法 | 微調整するべき点 |
|:-:|:-:|
| 敵の攻撃力を自分のHPの1/8ぐらいにする  | 全くプレイヤーが倒されない  |
| CPUがガードを使う確率を減らし膠着状態になるのを避ける  | CPUがずっとプレイヤーに突っ込んでくる[^4]  |
| 隠し場所でアイテムが手に入るようにする  | 隠し場所が見つからない  |
| 必殺技にカットインをつける  | カットインが邪魔でうまく攻撃できない  |

もちろんこれだけではなく分類としては挙げられないほど多い
「世界観が～ではないといけない」だとか
「～の絵が不自然」などの細かいことがあります。
これらを解決して初めてクオリティの高いゲームとなります。

:::note info
 **そもそもクオリティとは？** 
考え方はいろいろありますが、不自然さがない、細かいことにこだわる、
作者がプレイしていて面白いと思えるゲームのことだと思っています。
:::

## おわりに

意外と書いてみたら短い記事でした。
自分で実際にゲーム制作しないと分からないことがあるので
こんな記事見るよりゲーム制作に移った方が良いです。
それでも記事を見て下さった方、ありがとうございます。
またどこかでお会いしましょう。

[^1]: これは社会学者であるロジェ・カイヨワが提唱した分類です。
[^2]: 「ストリートファイターⅡ」などのゲームを想定しています。
[^3]: いわゆる小ネタです。
[^4]: ハメ技として逆に面白くする要素となる場合があります。
表示に必要なデータのみをzodのスキーマでsafeParseする

# はじめに

この記事では、zodという型検証ライブラリを使って、データのバリデーションを行います。今回は私がプロジェクトで必要なデータのみを抽出する方法について、理解できたので紹介します。

# zodとは

zodは、データの型や構造を検証（バリデーション）するためのライブラリです。特にAPIからのレスポンスや外部から提供されたデータが、期待通りの構造かを確認したいときに便利です。zodを使うと、型の定義と検証を同時に行うことができ、コードの安全性や信頼性を高めることができます。

# 実装

### スキーマを作成

まず、DBから取得したデータが想定通りのものかを確認するため、zodを使ってスキーマ（データの構造や型）を定義します。

```tsx
export const articleSchema = z.object({
  id: z.string(),
  title: z.string()
})
```
ここでは、`id`と`title` が文字列であることを定義しています。記事のコンテンツ（`content`）や作成日（`created_at`）などのデータは今回表示には不要なため、スキーマには含めません。

### データの取得

次に、DBからデータを取得してくる関数を実行します。

```tsx
const res = await getArticles();
console.log("res.article", res.articles);
```

この関数は、記事データのリストを返します。
例えば、以下のような形でデータが返ってきます。

```tsx
res.article [
  {
    id: '1',
    title: 'おはよう',
    content: 'こんにちは',
    created_at: '2024-08-22T23:35:07.079Z',
    updated_at: '2024-08-22T23:35:07.079Z'
  },
  {
    id: '2',
    title: 'こんにちは',
    content: 'つかれた',
    created_at: '2024-08-23T08:30:38.926Z',
    updated_at: '2024-08-23T08:30:38.926Z'
  }
]
```

### zodでデータを検証して必要な部分のみを抽出

取得したデータには、`content`や`created_at` など、表示に不要な情報が含まれています。これらを削除し、必要なデータ（`id`と`title`）だけを残すために、zodの `safeParse` メソッドを使います。

`safeParse` は、データを検証し、期待通りのデータであればそのデータを返します。そうでなければ、エラーメッセージを出力します。

```tsx
const parsedArticles = res.articles
    .map((article: Article) => {
      const result = articleSchema.safeParse(article);
      
      if (result.success) {
        return result.data; // id と title のみ
      } else {
        console.error(result.error);
        return null; // エラーハンドリング
      }
    })
    .filter(Boolean); // nullを除外
  
  console.log('parsedArticles', parsedArticles);
```
このコードでは、`res.articles` に含まれる各記事データを `articleSchema` で検証し、idとtitleだけを抽出しています。エラーが発生した場合には、`console.error` でエラーメッセージを出力し、その記事を除外します。

### 結果の出力

最終的に、検証に成功したデータのみが `parsedArticles` として保存されます。

```tsx
console.log('parsedArticles', parsedArticles);
```

出力結果は以下のようになります。

```tsx
 parsedArticles [
  { id: '1', title: 'おはよう' },
  { id: '2', title: 'こんにちは' }
]
```

# おわりに

zodを使うことで、APIからのレスポンスデータの型や構造を厳密に検証し、必要なデータだけを安全に取り出すことができます。特に、型が動的な外部データを扱う際には、データの整合性を保ちながらコードの安全性を高めることができます。

初めてzodを使う方でも、簡単にデータのバリデーションが行えるので、ぜひプロジェクトに取り入れてみてください。
Pytorch Executorについてのメモ

## 結論
Android上でPytorchのモデルを動かすには現時点（2024/9）では、Pytorch Mobileが適切なようです。

## PyTorch Executorとは
PyTorch Executorは、モバイルや組み込みデバイス向けに最適化されたPyTorchのサブセットで、以下のような特徴があります:

### 主な特徴

- **ポータビリティ**: スマートフォンから組み込みシステム、マイクロコントローラーまで幅広いプラットフォームに対応

- **生産性**: PyTorchのツールチェーンやSDKを使って、モデル作成からデバッグ、デプロイメントまで一貫して開発可能

- **パフォーマンス**: 軽量なランタイムとハードウェア(CPU、NPU、DSPなど)の能力を最大限に活用

### パフォーマンスと安定性

- メモリ使用量が少なく、動的メモリフットプリントが小さいため、PyTorch Mobileと比較して優れたパフォーマンスとポータビリティを実現

- コアランタイムライブラリはカーネルやバックエンドなしで50kB未満とコンパクト

- 実行オーバーヘッドが低く、オペレーションあたりマイクロ秒からナノ秒オーダーの処理が可能

- メモリ管理が効率的で、定数テンソルは.pteファイルデータを直接参照し、コピーを回避

- バックエンドデリゲートを使用して、アーキテクチャ固有の最適化や異種アーキテクチャの活用が可能

### 開発ツール

- プロファイリング機能を提供し、モデルのロード時間、オペレータレベルの実行時間、推論の全体実行時間などを測定可能

- 実行されたオペレータをPythonコードの該当行にリンクバックできるユニークな機能あり

- デバッグやプロファイリングのためのSDKとツールチェーンを提供

ただし、一部のユーザーからは特定のモデル(MobileNet V3など)でPyTorch Mobileよりも遅いケースが報告されており、使用するモデルや設定によってはさらなる最適化が必要な可能性があります。全体としては、ExecuTorchは軽量で効率的なランタイムを提供し、幅広いデバイスでの推論に適していると言えます。

このページは、PyTorchのExecuTorchフレームワークを使用してAndroidデモアプリを構築する方法について説明しています。以下に主要なポイントを解説します:

## ExecuTorch Android Demo Appの要約
https://pytorch.org/executorch/stable/demo-apps-android.html
ExecuTorchは、モバイルや組み込みデバイス向けに最適化されたPyTorchのサブセットです。このガイドでは、画像セグメンテーションタスク用のモデルを使用したAndroidデモアプリの構築方法を説明しています。ExecuTorchを使用してAndroidアプリに機械学習モデルを組み込む方法を示す実践的なガイドとなっています。

## 主要なステップ

1. **環境設定**:
   - Android NDKのダウンロードとインストール
   - 対応OS: CentOS, macOS Ventura (M1/x86_64)
   - Qualcomm HTP使用時は追加の要件あり

2. **モデルのエクスポート**:
   - XNNPACKバックエンド用またはQualcomm Hexagon NPU用にモデルをエクスポート
   - 生成されたモデルファイルをアプリのassetsディレクトリにコピー

3. **ランタイムのビルド**:
   - XNNPACKまたはQualcomm Hexagon NPU用のExecuTorchランタイムライブラリをビルド
   - CMakeを使用してビルド
   - JNIラッパーを含む`libexecutorch_jni.so`を生成

4. **デバイスへのデプロイ**:
   - ビルドしたライブラリとモデルファイルをアプリのディレクトリ構造に配置
   - Qualcomm HTP使用時は追加のライブラリが必要

5. **アプリの実行**:
   - Android Studioでプロジェクトを開く
   - アプリをビルドして実行

## 技術的ポイント

- ExecuTorchは、モバイルデバイス上で効率的に動作するように最適化されています。
- XNNPACKとQualcomm Hexagon NPUの2つのバックエンドオプションが提供されています。
- JNIを使用してネイティブライブラリをJavaコードから呼び出しています。
- CMakeを使用してクロスコンパイルを行い、Android用のライブラリを生成しています。

引用:
[1] https://pytorch.org/executorch/stable/llm/getting-started.html
[2] https://pytorch.org/tutorials/recipes/recipes/benchmark.html
[3] https://pytorch.org/executorch/stable/intro-how-it-works
[4] https://pytorch.org/executorch/stable/runtime-overview.html
[5] https://pytorch.org/executorch/stable/intro-overview.html
[6] https://www.exxactcorp.com/blog/Deep-Learning/pytorch-1-7-0-now-available
[7] https://pytorch.org/executorch/stable/sdk-profiling.html
[8] https://github.com/pytorch/executorch/issues/4005
WebDeveropperBootcamp  HTML/CSS/JavaScript編

# 本日から本格的にプログラミング勉強を始める
## 必ず守ること
- 焦らない
- Baby step & Jaiant straide
- 飛ばさない
- ドツボにはまらない
- ひたすらハンズオン
- 視聴率100％

# JavaScript
## 配列の操作
基本的に**元の配列に操作が加えられる**ことに注意する
追加:push(),unshift
削除：pop(),shift()

**以下は元の配列には変更がないことに注意**

forEach():配列.forEach(function 関数(){})で**配列の各要素に対して**関数を適用できる

map():配列.map(関数{**return**})で**配列の各要素に関数を適用**し、**新しい配列を作る**

filter:配列.filter(関数{**return**})で特定条件を満たすものだけを配列から抽出し、**新しい配列を作る**

reduce:配列.reduce(蓄積,各々の値){処理　**return**}で蓄積に値返す

結合: 配列.concat(配列)

切り出し:配列.slice()

取り除き:配列.slice(開始,個数)



### constで宣言すると
- 中身は変えられるが再代入はできない

## オブジェクト

### 操作
- 再代入不可能
- 値の操作は可能
- オブジェクトobjに対して新たにlokking="good"というプロパティを追加したいとき→obj.lokking ="good"
- メソッド：`{ key:value,メソッド名(引数){}}`というようにfunctionを省略した関数のような書き方をする
- メソッドで使う変数がオブジェクト内の変数(プロパティ)だったときはthisをつける。

### 重要　オブジェクトのキーとバリューの取得
- testscoresという名前のオブジェクトについて
- キーを取得したい→Object.keys(testscore)
- バリューを取得したい→Object.values(testscore)


## 関数

### Return
- 関数の値を変数に代入したいならreturnが必要

### レキシカルスコープ
- 関数の参照する変数は関数を定義した時点で決まる

### 引数にない変数
- グローバルに探しに行く

### 関数で宣言した変数
- 関数外では使えない

### アロー関数
#### 引数が1つの場合(無名関数)
- 引数 => {処理}
#### 引数1つ、処理１行(無名関数)
- 引数 => 処理


### setTimeoutとsetInterval
- setTimeout(関数,時間）で指定した時間の後に関数を実行
- id = setInterval(関数,時間)出間隔を置いて実行
- setIntervalはclearInterval(id)でストップ


## 演習事項

## その他大事な事項
-テンプレートリテラル：`my name is ${name}` ※バックウォート`で囲む
美大でデザインを学んでいる自分が、卒制でアプリを制作する話

初めまして！！よろしくお願いします！

<h3>[この投稿について]</h3>
　私は、普段美大でデザインを学んでいるのですが、今年の4月から卒制でアプリを制作する過程を記事に残せたら良いなぁ！という軽い思いで初めてみました！今回の投稿では、2024年3月から現在（9月）までの進捗を共有できたらと思います！
 
<h3>[私の技術力について]</h3>
学外で少しコーダーとしてwebサイト制作に触れているレベルになります。なので、webアプリは制作したことがありませんでした。（一時期コピペで動作させた事はありましたが笑）

<h3>[開発のキッカケ]</h3>
　さて本題ですが、今回は何を作るかというと「店舗共有マップ型SNSアプリ」です！とくに、古着屋さんに特化したモノになります。私は、美大に入ってから徐々に服に興味を持ったのですが（いやぁ〜服って色々な雰囲気を作れるので魅力的ですよね！）、古着というものに手を出した事がありませんでした。加えて、あまり交友関係も広くないので良い古着屋を共有するキッカケもありません。そんな私にとって、良い古着屋はどこなんだろう？？古着の良いモノってなんだろう？なんか、小さなビル内にあって古着屋って入りにくいなぁ~店主の人柄とかキッカケがあれば入りやすいだろうなぁ〜という思い？不満？がたくさんありました。
　しかし、それを解決してくれるサービスがありませんでした。現状、古着に特化した情報サイトはありますが、古着のお店に行きたくなるような仕組み？があるようなサービスは見つかりませんでした。（WEARやインスタをはじめ、ほとんどがコーデの共有でした）その不満が、webアプリを作ろうというキッカケになります。

 <h3>[webの仕組みを学ぶ]</h3>
 最初の開始は、Udemyで簡単なSNSwebアプリを作成してみました。DBの作成はこうやるんだ！APIってなんや！！？バグったぞ！？？という風に試行錯誤しながら、なんとか動画を見ながらですが完成する事ができました。それと同時に、写真の様に、古着アプリの要件も固まりつつありました。（この間に講評が上手くいかずに単位を落としそうになりましたが笑）<br></br><br></br>
 
![スクリーンショット 2024-09-08 3.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1731700/051bd54e-225d-847c-8680-416b36366f3b.png)




<h3>[技術構成]</h3>
・フロントエンド<br></br>
　・言語-Next.js<br></br>
　・デプロイ場所-Vercel<br></br>
・バックエンド<br></br>
　・言語-Node.js<br></br>
　・デプロイ場所-Render<br></br>
・データベース<br></br>
　・ORM-Prisma<br></br>
　・BaaS-supabase</br>

<h3>[開発の取り掛かり/AIサービスの進展]</h3>
　そして、8月から本格的に開発に入り、DB設計に苦労しながら(Userテーブル/Profileテーブル/Storeテーブル/Postテーブル/FavoriteUserテーブル/StoreSaveテーブル/Commentテーブル/Likeテーブルなどテーブルの多さに驚きました)、現在は一連の主要な体験まで実装が終わったという感じになります。残りはAPIの微調整とフロントの磨き込みになります。加えて、この間にChat-GPTやv0(フロント画面を自然言語で出力できるサービス)などのAIサービスのものすごい進展があり、それらのサービスにとても助けられています！要件とwebの仕組みさえ分かれば、とりあえず動作するモノは作れるような気がします！引き続きwebアプリを頑張っていきますので、応援をよろしくお願いします！！
 
最後までお読み頂き、ありがとうございました！

（補足）
デザインしたロゴです！
また、もし良ければインスタのフォローをお願いします！
　・https://www.instagram.com/furup2024
![](https://storage.googleapis.com/zenn-user-upload/d86efbe19580-20240908.jpg)
DVWAを構築しSplunkにログを取り込んでみた

お世話になっております。gashiと申します。
自己学習のためにDVWAを構築してApacheのログをSplunkに取り込んでみました。

## DVWA構築
以下のページを参考にさせていただきました。
https://qiita.com/picato1123/items/84945913eb706e9c616a

投稿者様はkaliを使ったようですが、私はubuntu serverでやってみました。

特に問題なく、ページを開くことができました。なんとなくhostsファイルに名前を追加してみた。そのうちDNSサーバも触ってみたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3191990/e66aa3cf-6fd4-a6a7-fe42-8aa0adee6f74.png)


## Splunkへのログ取り込み
やったことは以下のとおり
１．ホストOS（windows）にSplunk Enterpriseをインストール
２．ubuntu（DVWA）にUniversal Forwarderをインストール
３．各種設定

VirtualBoxのNW設定とかで少々手間取ったけど、何とかログ収集までいけました。
切り分けの勉強になった。GPT先生ありがとう。
Splunkの設定自体は大したことをしてません。
Splunk Enterprise側で受信ポート設定（9997）したのと、DVWAにインストールしたUniversal Forwarderで以下の設定を入れた程度。

``` inputs.conf
[monitor:///var/log/apache2/access.log]
index = web
sourcetype = apache:access:combined
host = dvwa
```

``` outputs.conf
[tcpout]
defaultGroup=indexer

[tcpout:indexer]
server=SplunkのIP:9997
```

## 結果
Splunk上でこんな感じでアクセスログが見れます。Add-on入れているのでログフィールドの判定も問題なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3191990/8ca00225-242c-740e-6578-ac5660a2e0cd.png)

## 次の目標
１．DVWAで各種攻撃を試してみる。
２．「１」をもとに、Splunk側での検知ルールを考えて遊びたい。
7days To Die V1.0 におけるシングルで作成したセーブデータをConoHa for Gameに移管した話

## はじめに

みなさん7days to Dieやってますか！？正式版リリースから何か月たったんでしょうか！
わかりません！

自分は最近はじめてどはまり中です ← どういうつながり？

そんなこんなで、自分が作成したローカルのセーブデータにフレンドを招待して絶賛プレイ中です。

そんな中、マルチサーバーを借りたいと思って、
> サーバーにこれまで遊んできたセーブデータを移管したい

というニーズが発生してしまったため、備忘録的な意味で残します。

## 対象者
結構用語を端折ってたりするので、
- ターミナル触れる人
- 特段説明なくsshやscp等がわかるかた


が対象となります。

## ゴール
- ローカルに保存されているセーブデータをConoHa VPS for Game上にアップロードできること

をゴールとして、本記事は作成いたしました。

## 借りたVPSについて
今回お借りしたのはConoHa VPS for Game をお借りしました。
https://www.conoha.jp/game/

こちら借りる利点として、
- 長期割引がきくこと
- ゲームテンプレートから選べば爆速でマルチサーバーを立てられること
- SSHログインしたときに必要な情報をターミナル内に出力してくれること（IPアドレスとかログインパスワードとか）

その他、ConoHa VPSについては割愛します。

## ディレクトリ構成について
この節では、ローカルとサーバー上の2つに分けてご紹介いたします。

### ローカル側
環境としては
- Windows 11 Home
- Steam

を使用しています。（それ以外でできるのかわかんない）

#### セーブデータの保存先
デフォルトで設定されているのは
`C:\Users\<<user_name>>\AppData\Roaming\7DaysToDie\Saves\<<game_world>>\<<game_name>>`
> user_name : Windowsのログインユーザー
game_world : 7days to die のセーブデータ作成時に選ぶ`Navezgane`などのワールドタイプ
game_name : 新規セーブデータ作成時に入れたセーブデータ名

となります。game_name直下部に、そのセーブデータの記録が保管されています。

### ConoHa VPS for Game側
ここまでは、記事を漁ればよくでてくるラインだとは思うのですが、ConoHaのほうがわからなかった。
Linuxサーバー上で構築されているサーバーではあるのですが、Windowsとのディレクトリの差異があるため、時間がかかりました。

結論を言うと、ローカルのセーブデータへの移管先は以下のディレクトリになります。
`/home/sdtd/.local/share/7DaysToDie/Saves/<<game_world>>/<<game_name>>`

こちらにSCPコマンド等で、ローカルのセーブデータを渡してあげると無事に移管は終了します。

### サーバー側の設定
セーブデータをSCPコマンド等でコピーしただけでは、server上でセーブデータが反映されません。
なぜなら、サーバー上の設定で、ほかのセーブデータを参照しているためです。
そのため、セーブデータの向き先を変更する必要があります。

`/opt/7dtd/7dtd_server/`直下に`severconfig.xml`というxmlファイルが存在します。
こちらのファイル内に以下のような記述部があると思います。
（コメントや、スペース等は省いております）
```
 <!-- GAMEPLAY -->
        <!-- World -->
        <property name="GameWorld" value="Navezgane"/>                     
        <property name="WorldGenSeed"  value="syAdv0eJ"/>
        <property name="WorldGenSize" value="6144"/>
        <property name="GameName" value="MyGame"/>
        <property name="GameMode" value="GameModeSurvival"/>
```

この中の`GameWorld`, `GameName`を以下のように修正します。
適宜、GameWorldとGameNameは変更ください。あくまで例となります。

```
        <!-- World -->
        <property name="GameWorld" value="Pregen080k1"/> <!-- Navezgane → Pregen080k1-->                
        <property name="WorldGenSeed"  value="syAdv0eJ"/>
        <property name="WorldGenSize" value="6144"/>
        <property name="GameName" value="MyGameMulti"/> <!-- MyGame → MyGameMulti-->        
        <property name="GameMode" value="GameModeSurvival"/>
```

これにより、サーバー上でセーブデータの向き先が変更されます。

#### 注意事項
- 本記事と同様に移管した場合、経過日数が1日からとなってしまいます
- その他、インベントリや装備品、スキルなどなどは引き継がれます

一応、経過日数に関しては、管理者権限を自身に付与後、経過日数を変更するコマンドがありますので、そのコマンドを実行すれば解決します。

#### 詰まったところ
私だけなのかは不明ですが、一応メモ程度に残しておきます。

##### サーバー再起動時にエラーが発生する
移管したセーブデータ内部に`Player`ディレクトリがあり、ユーザーがログインをするとその中のディレクトリやファイルを読み取る仕様でした。

そのため、この部分の書き込み読み込み権限を適切に選択しなければ、サーバーがずっと初期化しています。で止まってしまったり、サーバーに参加できないという問題が発生します。

そのため、chmodなどで権限ユーザーをrootに変更後、権限を775に設定を変更する必要がありました。

## まとめ
そこまで難しくはないのですが、ネットの海を渡ってもなかなかほしい情報にはありつけず苦労したので、今回は記事として残します。

ここまでご覧いただきありがとうございました。

### ref
#### ConoHa VPS for Game
https://www.conoha.jp/game/

#### serverconfig.xml について
https://server.sakuru-games.com/customize-7dtd-config/
Makefile:2: *** missing separator.  Stop.エラーでMakefileが実行できない

# はじめに
makefileを実行する際にエラーが出たので、解決方法をまとめます。

# 事象
以下のMakefileを実行しようとした際にエラーが発生
```makefile:Makefile
deploy:
  npm run build
  firebase deploy
```

```bash
$ make deploy

Makefile:2: *** missing separator.  Stop.
```

# 原因
コピペで持ってきたときに、先頭の行にスペースが入っていた

makefileはタブでインデントされている必要がある

# 解決方法
先頭行をタブでインデントする

これでもうまくいかない場合はvscodeの設定で空白がスペースになっている可能性がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/d801b37a-7240-71a6-8922-68e88a541743.png)

スペースをクリックして、タブのインデントに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/64b9020d-aa74-719f-913d-2733ba76d3e7.png)

2を選択(選択する数字は任意)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/aab1474d-da06-ca20-af75-d78f39d1e61e.png)

# 終わりに
タブとスペースを分けて認識するものはよくあるので、注意したい。
WinUI 3での実用的なWindowサイズの設定

WinUI 3のWindowにはサイズを直接設定できるプロパティがないので、実行時にメソッドで変える必要があります。このためにAppWindow.Resizeを使う方法がよく説明されますが、実際にアプリを作るとなるとこれは実用的でないので、どうすればいいかという話です。

## 1. AppWindow.ResizeよりAppWindow.ResizeClient

[AppWindow.Resize](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow.resize)で指定するサイズは、Windowサイズを変更する他のメソッドや関数と同じく、Non-Clientエリア（タイトルバー等）と見た目上のWindowの左右下にあるスペースを含めたサイズになります。

したがって、WindowのコンテントのUI要素にきっちり合わせたサイズにするには、Clientエリアのサイズにこれらの分の幅を加える必要がありますが、これは少々手間です。そんな計算をするぐらいなら、Clientエリアのサイズそのままで指定できる[AppWindow.ResizeClient](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow.resizeclient)を使った方がいいです。というか、WPFでもこの機能が欲しかった。

## 2. サイズはモニターのDPIに合わせて調整が必要

AppWindow.ResizeClientでは（AppWindow.Resizeでも）サイズをSizeInt32で渡すことになりますが、この単位は実ピクセルです。UI要素の設定で使うDIP（Device Independent Pixel）とは違います。

一方、WinUIではWindowのコンテントのUI要素のサイズはモニターのDPIに合わせて自動調整されます。したがって、ClientエリアのサイズもモニターのDPIに合わせて手動で調整した上で渡さないと、コンテントに合わなくなってしまいます。

## 3. 具体例

まずモニターのDPIは、WinUIにはDPIを取得するメソッドはないので、Win32で取得することになりますが、簡単なのは[GetDpiForWindow](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow)関数です。取得できる値は一つだけですが、X方向とY方向のDPIが違うケースは実用的にはないと思われるので、十分でしょう。DPIそのままより96を基準としたスケール（倍数）にした方が使いやすいので、こんな感じです。

```csharp
using System.Runtime.InteropServices;
using Microsoft.UI.Xaml;

internal static class WindowHelper
{
    [DllImport("User32.dll")]
    private static extern int GetDpiForWindow(nint hwnd);

    public const double DefaultPixelsPerInch = 96D;

    public static double GetWindowDpiScale(Window window)
    {
        nint windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);
        return GetDpiForWindow(windowHandle) / DefaultPixelsPerInch;
    }
}
```

次にClientエリアのサイズは、UI要素と同じ場所で設定した方が一覧性が高いので、XAMLに書くことにして、UI要素のルートになるGrid（名前をRootGridとする）で指定します。

```html
<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="WinuiSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid x:Name="RootGrid"
          Width="400" Height="300"
          Background="#EEEEEE">
        <Grid Width="360" Height="80" Background="Red">
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
                       Foreground="White"
                       FontSize="40" FontWeight="Black"
                       Text="Sample"/>
        </Grid>
    </Grid>
</Window>
```

その上でWindowのコンストラクターでAppWindow.ResizeClientを実行します。

```csharp
using Microsoft.UI.Xaml;
using Windows.Graphics;

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        double dpiScale = WindowHelper.GetWindowDpiScale(this);
        AppWindow.ResizeClient(new SizeInt32(
            (int)(RootGrid.Width * dpiScale),
            (int)(RootGrid.Height * dpiScale)));
    }
}
```

これで以下のようなWindowになります。DPIは175%なので、実ピクセルでは幅400×1.75+2=702です（2はアウトラインの線の分）。

<img width="400" alt="WindowSample" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60028/9506025e-f67b-86ad-f3eb-e9f180972913.png">

簡単ですが、以上です。
GitHubにSSH接続する設定手順

## SSH接続
- SSH（Secure Shell）とは、リモートコンピュータと通信するためのプロトコル
- 公開鍵認証方式であるため、パスワードを使用せずセキュアな認証を行える
- SSH接続をするには、SSHキーの作成とGitHubへの公開鍵の登録が必要

## 1. SSHキーを作成する
```terminal
$ ssh-keygen -t ed25519 -C <email_address_registered_on_GitHub>
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/[user_name]/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/[user_name]/.ssh/id_ed25519
Your public key has been saved in /Users/[user_name]/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [email_address]
The key's randomart image is:
+--[ED25519 256]--+
|           .+=Bo=|
|      .   . +*+*o|
|     E . o ooo*+.|
|      o B   +X.=o|
|       =So  .+* B|
|    . o .. o.  .=|
|     o .  o .  . |
|           .     |
|                 |
+----[SHA256]-----+
```
（何か聞かれたらエンターを押せばOK）

- `ssh-keygen`：SSHキーを生成するためのコマンド
- `-t <type>`：キーのタイプを指定するオプション
- `-C <comment>`：キーにコメントを追加するオプション

このコマンドを実行すると、ED25519方式のSSHキーが生成され、指定したメールアドレスがコメントとしてキーに追加される。

## 2. SSH公開鍵をコピーする
1で生成されたキーは、`~/.ssh`ディレクトリ下の`id_ed25519`（秘密鍵）と`id_ed25519.pub`（公開鍵）というファイルに保存されている。

```terminal
$ ls ~/.ssh
id_ed25519　　id_ed25519.pub
```

接続設定に必要な公開鍵をコピーしておく。

```terminal
$ pbcopy < ~/.ssh/id_ed25519.pub
```
- `pbcopy`：標準入力からデータを読み取り、クリップボードにコピーするコマンド
- `<（リダイレクト演算子）`：ファイルの内容をコマンドの標準入力として提供するもの

## 3. GitHubにSSH公開鍵を追加する
① GitHubのヘッダー右にあるプロフィール画像を押下し、その中の「**Settings**」を押下。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853295/d64930d0-ca27-e7d8-3e2a-007cf7996ea2.png" width="300">

② 「**SSH and GPG keys**」を選択し、「**New SSH key**」を押下。

![スクリーンショット 2024-09-07 20.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853295/d42d297d-3b82-7aab-86eb-b36531716d99.png)

③ 「**Title**」に任意のキー名を、「**Key**」に2でコピーした公開鍵を入力し、「**Add SSH Key**」を押下。

![スクリーンショット 2024-09-07 20.40.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853295/f9e26d56-097b-f605-ba3e-a0812c4ca867.png)

これでSSH接続の準備が完了。

## 4. SSH接続を確認する
```terminal
$ ssh -T git@github.com
The authenticity of host 'github.com (XX.XX.XXX.XXX)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Hi [user_name]! You've successfully authenticated, but GitHub does not provide shell access.
```
- `ssh`：リモートサーバーにシェルセッションを開き、暗号化された通信を使ってリモート接続をするコマンド
- `-T`：主に接続テストや認証確認のために、リモートシェルを開かずに接続するオプション

GitHubのユーザー名が表示されたら接続成功。