OmniAICreator/Qiita-1.07M huggingface dataset:
Windows11でDockerを無料で使う。

# AIを頼りにする日々
久しぶりにIT系の勉強を再開したら、
VSCode上ではGithub copilotがいろいろと手伝ってくれるし、
わからないことはググるのではなくChatGPTやCopilotに聞けば教えてくれるし、
数年前とはまったく違う景色が広がっていました:open_mouth:

そして、[Windows10でDockerを商用利用でも無料で使いたい。](https://qiita.com/nacanaca/items/ec99855d18ce99e7f12c "Windows10でDockerを商用利用でも無料で使いたい。")という記事にコメントが付いていたことに数年たった今日初めて気付きました:sweat_smile:

:::note info
**Rancher Desktop**（Docker管理に使えるデスクトップアプリ）も **無料**で使えるとのこと！
:::
せっかく教えていただいたので少しだけ試してみることに。

# Rancher Desktop
## 特徴
- 無料
- Windows / macOS / Linux 対応
→ Windows の場合、Rancher Desktop が(?)Windows の中に Linux 環境（WSL2）を作り、その中で Kubernetes や containerd（または dockerd）を動かす。
- DockerだけでなくKubernetesも使える！
→　好みに応じて コンテナランタイムをDocker 互換環境または containerd を選択して使用可能。
- GUI での設定変更が簡単
→ 仮想マシンのメモリ、CPU、ネットワーク設定などが GUI で設定できる。
- kubectl、nerdctl、docker CLI 対応
→ Kubernetes やコンテナ操作が CLI で可能。

# Rancher Desktopをインストールしてみる！
## 手順1: まずはWindows11でLinux 環境（WSL2）を使えるようにする
1. Windows11で「Windowsの機能の有効化または無効化」の
「**Linux用Windowsサブシステム**」にチェックを入れて「OK」
![スクリーンショット 2025-04-06 211122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/21857679-0dc1-4de7-9c82-8d8267161f06.png)
2. 再起動
3. PowerShellを管理者モードで起動し
`wsl --install`
WSL2とUbuntu（デフォルトのLinuxディストリビューション）がインストールされる
![スクリーンショット 2025-04-06 220445.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/84bff68f-8f27-4760-8753-6356abe010b2.png)

## 手順2: Windows11でRancher Desktopをインストールする
1. Rancher Desktop公式[Rancher Desktop by SUSE](https://rancherdesktop.io/ "Rancher Desktop by SUSE")からWindows(x64)系のインストーラをダウンロード
→　Rancher.Desktop.Setup.1.18.2.msi
2. Rancher Desktopをインストール
2. ひとまずdockerさえ使えればいいので
kubernetesを使うかのチェックは外して、 **dockerd (moby)** としました。
※設定は後から変更可。

## 動作確認
1. Rancher Desktopを起動しておく
2. dockerエンジンの起動確認
PowerShellを起動し
`docker version` 
→　Versionが表示されるのを確認
3. コンテナの起動
続けてPowerShell上で
`docker run hello-world`
（初回はイメージのダウンロードが自動的に行われます）
なんかたくさんメッセージが表示されて一瞬失敗した？と思ってあせったけど
英語のメッセージをよく読んでみると、
このメッセージは正しく動作していることを示している旨のことが書いてありました:laughing:
![スクリーンショット 2025-04-06 221927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/4e619dcc-35d3-447c-8e04-81eda88bf76f.png)
4.Rancher Desktopにも表示されました。
![スクリーンショット 2025-04-06 224343.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/918332d4-0621-4eca-ba0b-c10fe4b7c6ac.png)

実はコマンドで実行する必要はありません。そのための RancherDesktop ！
コンテナイメージのダウンロードはここから。
![スクリーンショット 2025-04-06 224927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/88e46e6e-c17f-4756-a24f-079915dae8bc.png)
nginx(Webサーバー)のコンテナイメージを追加（ダウンロード）してみました。

RancherDesktopからコンテナを起動できるはずなのですが
Containersの画面に表示されなかったので、
PowerShellで `docker run -d -p 8080:80 nginx`
すると表示されました。
![スクリーンショット 2025-04-06 230708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/9959ca7d-ef30-4185-9e77-c843e9203c2b.png)

ブラウザでnginx(Webサーバー)が動作していることを確認
![スクリーンショット 2025-04-06 230950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/bf3c4a07-c135-4b38-a3a0-08a32a3e63f1.png)

# Rancher Desktop　いいね:thumbsup:
Kubernetesは環境を準備するのが難しそうなイメージがあったので
今までスルーしてきましたが
こんなに簡単に環境を準備できるのなら、勉強してみようと思えました:relieved:
Vimの削除コマンド３選

## はじめに
普段はIDEをメインで使ってるけど、たまーにVimを触る機会があって、「あれ？削除コマンドなんだっけ？」ってなります😅

というわけで、備忘のためVimのよく使いそうな削除コマンド3つをまとめました。

## 1. 内容を全部消す 🧹

「全部消して書き換えたい！」ってときのコマンドです。

```vim
:%d
```

使い方：
コマンドモードで`:%d` と入力してEnterキーを押す

```
# 実行前
line 1: import something
line 2: def function():
line 3: print("hello")
...

# コマンド実行
:%d

# 実行後
(何もない空のファイル)
```


ちなみに、`%` は「ファイル全体」を表していて、`d` は「削除」のコマンドです。

## 2. 一行または複数行を削除する ✂️

「この行いらないな」とか「ここの3行消したいな」ってときに使えるやつ。

```vim
dd または 5dd (5行の場合)
```

### 一行削除
使い方：
コマンドモードで削除したい行にカーソルを移動し、
`dd` と入力する（Enterキー不要）

```
# 実行前 (カーソルは2行目にある状態)
line 1: import something
line 2: # 不要 → ここにカーソルがある
line 3: def function():

# ddを入力

# 実行後
line 1: import something
line 2: def function(): → 元の3行目がここに来る
```

### 複数行削除
使い方：削除したい範囲の最初の行にカーソルを移動し、
`3dd` と入力（3行削除する場合。Enterキー不要）

```
# 実行前 (カーソルは2行目にある状態)
line 1: import something
line 2: # 不要 → ここにカーソルがある
line 3: # 不要
line 4: # 不要
line 5: def function():

# 3ddを入力

# 実行後
line 1: import something
line 2: def function(): → 元の5行目がここに来る
```



## 3. 空白行を全て削除する 🧽

コードの整理でめっちゃ便利！空白行がたくさんあって「全部消したい！」ってときに一発で消せるやつです。

```vim
:g/^$/d
```

使い方:

コマンドモードで `:g/^$/d` と入力してEnterキーを押す

```
# 実行前
line 1: import something

line 2:

line 3:

line 4: def function():

line 5:

line 6: print("hello")

# コマンド実行
:g/^$/d

# 実行後
line 1: import something
line 2: def function():
line 3: print("hello")
```


ちなみに、
* `:g` - 「global」の意味。ファイル全体に対して何かする
* `/^$/` - 「行頭(^)の直後に行末($)がある行」＝空行を検索
* `d` - 見つかった行を削除

## まとめ

1. `:%d` - ファイル内容を全部消す
2. `dd` または `5dd` - 一行または複数行(例：5行)を削除
3. `:g/^$/d` - 空白行を全て削除

この記事が役に立ったらいいね♪やコメントをいただけると嬉しいです。
Angular ng-content について

# 概要
`ng-content` は、親コンポーネントから子コンポーネントへHTMLコンテンツを埋め込む仕組みである。
この機能は Content Projection（コンテンツ投影） と呼ばれ、コンポーネントの再利用性を高めるために使われる。

# 親コンポーネントから子コンポーネントにデータを渡す
親コンポーネントのビュー(View)で、コンテンツを渡したい子コンポーネントのセレクター名`<app-child> `をHTMLのタグとして指定する。
``` parent.component.html
<!-- 親コンポーネント (app-parent) のhtmlファイル-->
<!-- 親コンポーネントのセレクター名をタグに指定(app-parent) -->
<app-child> 
  <!-- 親から子コンポーネントへ渡すコンテンツ -->
  <p>親コンポーネントから渡されました</p>
</app-child>
```

そして、以下のように子コンポーネントのビュー（View）に `<ng-content>` を明記してあげることで、親コンポーネントから渡されたコンテンツが、子コンポーネントに表示される。

``` child.component.ts
// 子コンポーネント (app-child)のtsファイル
import { Component } from '@angular/core';

@Component({
  selector: 'app-child',  // 子コンポーネントのセレクター
  template: `
    <div class="child-container">
      <h3>子コンポーネント</h3>
      <!-- 親から渡されたコンテンツがここに表示される -->
      <ng-content></ng-content> 
    </div>
  `
})
export class ChildComponent {}
```

子コンポーネントで以下のように表示される。
```
子コンポーネント
親コンポーネントから渡されました
```

ここで出てくる疑問として、複数の渡したいコンテンツがあった場合、どうするかである。

# 複数のコンテンツを渡す例
親コンポーネントから複数の異なるコンテンツを子コンポーネントに渡したい場合、`<ng-content>` に`select`属性を使用して、特定のコンテンツを特定の場所に投影することができる。

``` parent.component.html
<!-- 親コンポーネント (app-parent) のhtmlファイル-->
<app-child>
  <!-- 最初のコンテンツ -->
  <p class="content1">親からの最初のコンテンツ</p>
  
  <!-- 2番目のコンテンツ -->
  <p class="content2">親からの2番目のコンテンツ</p>
</app-child>

```

``` child.component.ts
// 子コンポーネント (app-child)のtsファイル
import { Component } from '@angular/core';

@Component({
  selector: 'app-child',  // 子コンポーネントのセレクター
  template: `
    <div class="child-container">
      <h3>子コンポーネント</h3>

      <!-- 最初のコンテンツをここに表示 -->
      <div class="content1-container">
        <ng-content select=".content1"></ng-content>
      </div>

      <!-- 2番目のコンテンツをここに表示 -->
      <div class="content2-container">
        <ng-content select=".content2"></ng-content>
      </div>
    </div>
  `
})
export class ChildComponent {}
```

子コンポーネントで以下のように表示される。

```
子コンポーネント
親からの最初のコンテンツ
親からの2番目のコンテンツ
```

# まとめ
`ng-content`は、親コンポーネントから子コンポーネントへコンテンツを埋め込む仕組み（コンテンツ投影）で、再利用性を高めるために使用される。複数のコンテンツを渡す場合、`select`属性を使い、異なる場所にコンテンツを投影でき、柔軟なレイアウトが実現可能になーる。
indexOf で一発検索！ループ不要の解決法

Paizaの問題を解いてたら、「配列の中で単語がどこにあるか？」を調べるシンプルな方法を発見したのでシェアします。最初は `for` ループを使ったんだけど、実は `indexOf` を使えば1行で解決 できるんです！

## <br>問題概要

1行目に 半角スペース区切りの文字列 が与えられ、
2行目に検索する単語 S が与えられる。

S が 1行目の文字列の何番目（インデックス）にあるかを出力せよ！
ただし、複数回登場する場合は最初の登場位置 を出力する。

<br>📌 入力例
```
red green blue blue green blue  
red  
```
📌 出力例
```
0  
```

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/word-count_06

## <Br> 🚨 最初のコード（for ループ版）

最初に書いたコードがこれ👇
```js
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', (input) => {
    lines.push(input);
});

rl.on('close', () => {
    const words = lines[0].split(" ");
    const S = lines[1];
    
    for (let i = 0; i < words.length; i++) {
        if (S === words[i]) {
            console.log(i);
            break; // 最初に見つかったらループを抜ける
        }
    }
});
```
✅ 動作はするけど…
- `for` ループを使うと コードが長い
- `break` を忘れると 無駄なループ が発生
- もっとスッキリ書ける方法 ないの？

## <br>✅ indexOf でスッキリ解決！

実は `indexOf` を使えばループ不要！
```js
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', (input) => {
    lines.push(input);
});

rl.on('close', () => {
    const words = lines[0].split(" ");
    const S = lines[1];
    console.log(words.indexOf(S)); // 一発取得！
});
```

### <br>🤔 indexOf を使うメリット

✅ コードがスッキリ！
　→ `words.indexOf(S)` だけで検索できるので、`for` ループ不要！

✅ 可読性が向上！
　→ 最初の出現位置を一発で取得 できるので、無駄な処理を減らせる！

✅ エラーが減る！
　→ `for` ループを回して `break` を忘れるミスを防げる！

### <br>💡 学んだことメモ

🔹 `indexOf(S)` は配列内で最初に `S` が出てくるインデックスを返す！
🔹 ループを回さず、シンプルに検索できる！
🔹 検索アルゴリズムを意識するとコードがもっと洗練される！

## <br>📌 まとめ

`indexOf` を使えば、ループなしで単語の位置を取得できる！
次のステップは、`lastIndexOf` を使って 最後の登場位置を取る 応用問題も（あるのかな？）やってみたい！

<br>[僕の失敗談と解決話！ 🚀](https://paizabeginner.wordpress.com/2025/04/06/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9aindexof%e3%81%a7%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%ab%e6%96%87%e5%ad%97%e5%88%97%e6%a4%9c%e7%b4%a2%ef%bc%81/)
Laravelのログイン可否をZabbix Webシナリオで監視してみた話

## はじめに

ZabbixのWebシナリオ機能は非常に強力ですが、  
LaravelのCSRFトークン（`_token`）やCookieの扱いには少し工夫が必要です。

今回は、

- Laravelのログイン画面にアクセス  
- ログイン処理  
- ログアウト処理

という一連の流れをZabbixのWebシナリオで監視する方法をまとめました。

---

## 環境

- Laravel 11.x（CSRF・Cookie有効）
- Zabbix 7.0
- Webサーバ：nginx + PHP-FPM
- セキュリティトークン：
  - hiddenフィールド `_token`
  - Cookie `XSRF-TOKEN`

---

## やりたかったこと

1. トップページにアクセスして、必要なトークンとセッションを取得
2. トークン＆Cookieを使ってログイン処理をPOST送信
3. 正常なログインができたことを確認
4. 最後にログアウト処理まで実施

---

## Webシナリオのステップ構成

### ステップ1：トップページアクセス

- **URL**：`https://your.domain.com/`
- **変数の取得**：
```text
  {XSRF-TOKEN}    = regex:XSRF-TOKEN=(.*?); #最短マッチ
  {_token}        = regex:name="_token" value="(.*?)" #最短マッチ
```

- 取得モード：ボディとヘッダー

---

### ステップ2：ログイン処理
- URL：https://your.domain.com/do_login
- POSTフィールド：

```
login_id = {login_id}
password = {password}
_token   = {_token}
```

- ヘッダー：

```
Cookie: XSRF-TOKEN={XSRF-TOKEN}; cpkim_session={cpkim_session}
```

- 期待するステータスコード：200

---

### ステップ3：ログアウト処理
- URL：https://your.domain.com/do_logout
- POSTデータなし（GETでもOK）
- 期待するステータスコード：200

---

## 工夫ポイント
- LaravelのCSRFトークンはページアクセスごとに変化するため、最初のステップで正確に取得が必要
- Cookieも同様に取得＆ステップ間で維持が必要
- POST時のヘッダーにCookieをセットしないと419エラーになる
- ステップを3つに分けることで、トラブル時の切り分けも容易に

---

## 監視の結果

- Zabbix Webシナリオでもここまでできれば、実質E2E監視と同等の信頼性が得られます
- Laravelベースの管理画面や業務アプリでも応用可能です

---

## 最後に

- Laravelの仕組みを理解すれば、Zabbixだけでかなり高度な監視が可能です
- CSRFトークンやCookieの扱いで悩んでいる方の参考になれば嬉しいです

ご要望があれば、スクリーンショット付きの詳細設定手順も追記いたします！
IaaS・PaaS・SaaSの違いをパン屋さん🍞で例えてみる

「クラウドサービスにはいろいろな種類があるって聞いたけど、違いがよくわからない…」  
そんな方に向けて、この記事では「IaaS」「PaaS」「SaaS」という3つの分類についてやさしく説明していきます


## そもそも、クラウドサービスって？

クラウドとは、インターネットを通じてソフトウェアやサーバー、開発環境などを利用できる仕組みのこと。  
その中でも、**何をどこまで提供するか**によって、クラウドサービスは大きく3つに分けられます。

- **IaaS（アイアース）**：インフラだけを借りる
- **PaaS（パース）**：インフラ＋開発環境を借りる
- **SaaS（サース）**：完成されたアプリをそのまま使う




## パン屋さんでたとえてみると？

この3つの違いを、**パン屋さん**にたとえてみましょう。

### 🍞 IaaS（Infrastructure as a Service）

**「パンを一から自分で焼く」イメージ。**

パンを作るための「オーブン」「作業台」「電気や水道」など、**設備だけを貸してもらえる**イメージです。  
材料やレシピ、焼き加減などはすべて自分で決める必要があります。

> ✔️ 自由度は高いけれど、そのぶん準備や管理の手間も多め。

**主なサービス例：**  
AWS（EC2）、Microsoft Azure、Google Cloud Platform

---

### 🥖 PaaS（Platform as a Service）

**「パン作りの道具とレシピ、材料が用意された状態」**

オーブンもあるし、粉やバターも揃っていて、生地作りのステップも決まっている。  
**あとは成形して焼くだけ！** という状態です。  
開発者はアプリの「中身」だけに集中できます。

> ✔️ パンを作るプロセスの大半が用意されているのでスピード重視のときに◎

**主なサービス例：**  
Heroku、Google App Engine、Microsoft Azure App Service

---

### 🥐 SaaS（Software as a Service）

**「すでに焼き上がったパンを買って食べる」感覚。**

自分で焼いたり、レシピを考えたりする必要はありません。  
**すぐに使える・食べられる**状態のサービスです。

> ✔️ 簡単・手間いらずで、誰でもすぐに使い始められるのが魅力です。

**主なサービス例：**  
Google Workspace（Gmail、Googleドライブなど）、Slack、Zoom、Salesforce、Dropbox


## まとめ：要件に合ったスタイルを選ぶことが大切

クラウドサービスには「何を自分でやって、何をほかに任せるか」の違いがあります。  
パン屋さんのたとえで振り返ると…

- **IaaS**：お店と設備だけ借りて、自分でパンを焼く（自由だけど手間がかかる）
- **PaaS**：パン作りの準備が整っていて、焼くだけ（手間はかかるがスピーディで効率的）
- **SaaS**：完成品を買ってすぐ食べられる（すでにある完成品を使うので手軽で便利）

どのサービスを使うべきかは、**導入する目的や制約条件、時間やリソース**によって変わります。

「カスタマイズして作りたい」「セキュリティを保証して作りたい」「とにかくすぐに使いたい」  
あなたのチームに合ったクラウドの使い方を見つけてみてくださいね🍞🌿
EPSG を紐解く (3)

## 目次

1. [EPSG を紐解く (1) 〜 はじめに](https://qiita.com/tohka383/items/ba3b6ab0c19c33bc8f8e)
1. [EPSG を紐解く (2) 〜 基準系、楕円体、本初子午線](https://qiita.com/tohka383/items/441614010d44b38f77d9)
1. EPSG を紐解く (3) 〜 座標参照系（測地座標参照系、鉛直座標参照系）、座標系
1. [EPSG を紐解く (4) 〜 座標参照系（投影座標参照系）、投影演算](https://qiita.com/tohka383/items/6bf762f8235c2c3022bb)
1. [EPSG を紐解く (5) 〜 座標参照系（複合座標参照系）](https://qiita.com/tohka383/items/dd338d9d594da4e72ea9)
1. [EPSG を紐解く (6) 〜 座標変換、 towgs84 句](https://qiita.com/tohka383/items/dcd611ab216cf91618f0)

## 座標参照系 (Coordinate Reference System)

JGD2011 関係の座標参照系 (CRS) のち、測地座標参照系（地心座標参照系、地理座標参照系）および鉛直座標参照系に関しては下記のものがそれぞれ登録されています。

- 地心座標参照系
  - [CRS:6666 JGD2011](https://epsg.io/6666) (geocentric)
- 地理座標参照系
  - [CRS:6667 JGD2011](https://epsg.io/6667) (geographic 3D)
    - 緯度、経度、楕円体高
  - [CRS:6668 JGD2011](https://epsg.io/6668) (geographic 2D)
    - 緯度、経度
- 鉛直座標参照系
  - [CRS:6695 JGD2011 (vertical)](https://epsg.io/6695)

これらに関わる主なレコードについて、 EPSG に登録されているものを整理すると下記になります。（ Usage / Area などや各値の単位などは省略）

![EPSG の主要レコード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/5113f64c-0fc4-4dfa-9020-90cac7077794.png)


## 基準系 (Datum)

基準系に関しては前回の記事で取り扱いました。

https://qiita.com/tohka383/items/441614010d44b38f77d9

## 座標系 (Coordinate System)

EPSG では座標参照系 (CRS) と座標系 (CS) はまったくの別物として扱われています。原典にあたれていないので詳しくはわかりませんが、 EPSG Dataset は ISO 19111 に準拠しているので、 ISO 19111 でもはっきりと区別されているはずです。

EPSG 上の座標系 (CS) には下記などがあり、軸の取り方、向き、軸の順序、座標値の単位などを表したものです。

- 直交座標系
  - [CS:6500 Cartesian 3D CS (geocentric). Axes: geocentric X Y Z.](https://epsg.io/6500-cs)
  - [CS:4530 Cartesian 2D CS. Axes: northing, easting (X,Y).](https://epsg.io/4530-cs)
- 楕円体座標系（地理座標系）
  - [CS:6423 Ellipsoidal 3D CS. Axes: latitude, longitude, ellipsoidal height.](https://epsg.io/6423-cs)
  - [CS:6422 Ellipsoidal 2D CS. Axes: latitude, longitude.](https://epsg.io/6422-cs)
- 鉛直座標系
  - [CS:6499 Vertical CS. Axis: height (H).](https://epsg.io/6499-cs)

前述の図を見ていただくとわかりますが、 `epsg_coordinatesystem` には各軸の情報を表す `epsg_coordinateaxis` / `epsg_coordinateaxisname` が関連付いており、どのような軸をもった座標系か説明しています。

GIS では座標参照系の軸の順序 (axis order) 問題があり、伝統的に横軸、縦軸の順とされていることが多いですが、 EPSG に登録されている情報を正しく読み取ると、地理座標系は latitude-longitude の順ですし、平面直角座標系で使用されている CS:4530 では Northing-Easting の順が正しい順となります（実際にも、告示による平面直角座標系の定義ではこの順）。

## 座標参照系の換算 (Conversion)

もっとも一般的に使われている緯度経度座標系である CRS:6668 JGD2011 (geographic 2D) には、 `base_crs_code : 6667`, `projection_conv_code : 15593` が含まれており、 CRS:6667 をベースとして [Operation:15593](https://epsg.io/15593) の演算を行って得られた座標参照系となっています。

同様に CRS:6667 JGD2011 (geographic 3D) は `base_crs_code : 6666`, `projection_conv_code : 15592` であり、 CRS:6666 をベースに [Operation:15592](https://epsg.io/15592) されたものです。

換算処理について詳しくは次の記事の投影座標参照系のところでもう少し詳しく説明します。

## 次の記事

次は投影座標参照系について扱います。

https://qiita.com/tohka383/items/6bf762f8235c2c3022bb
開発者サービスが利用可能かチェックする



# 開発者サービスについて
>Google Play開発者サービスは、GoogleアプリとGoogle Playアプリの更新に使用します。
Google Play開発者サービスは、Googleサービスへの認証、連絡先の同期、ユーザーの最新のプライバシー設定へのアクセス、高品質/低消費電力の現在地情報サービスといったコア機能を提供します。
Google Play開発者サービスには、オフライン検索の高速化、リアルな地図の提供、ゲームパフォーマンスの向上など、アプリのエクスペリエンスを向上させる働きもあります。

# 実践

```
int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
if(result == ConnectionResult.SUCCESS){

}
```

"GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)"
で取得したコードを使って、ConnectionResultクラス内での成功値と比較します。

https://developers.google.com/android/reference/com/google/android/gms/common/ConnectionResult

https://developers.google.com/android/reference/com/google/android/gms/common/GoogleApiAvailability

# 参考

https://qiita.com/Rei_2020/items/e9058c45ae39c5774544

https://qiita.com/outerlet/items/e2603a08cf9bb9716fc0
EPSG を紐解く (2)

## 目次

1. [EPSG を紐解く (1) 〜 はじめに](https://qiita.com/tohka383/items/ba3b6ab0c19c33bc8f8e)
1. EPSG を紐解く (2) 〜 基準系、楕円体、本初子午線
1. [EPSG を紐解く (3) 〜 座標参照系（測地座標参照系、鉛直座標参照系）、座標系](https://qiita.com/tohka383/items/ae4dcfd14fe8bfef8b42)
1. [EPSG を紐解く (4) 〜 座標参照系（投影座標参照系）、投影演算](https://qiita.com/tohka383/items/6bf762f8235c2c3022bb)
1. [EPSG を紐解く (5) 〜 座標参照系（複合座標参照系）](https://qiita.com/tohka383/items/dd338d9d594da4e72ea9)
1. [EPSG を紐解く (6) 〜 座標変換、 towgs84 句](https://qiita.com/tohka383/items/dcd611ab216cf91618f0)

## 基準系 (Datum)

JGD2011 関係では測地系 (Geodetic Datum) として [Datum:1128](https://epsg.io/1128-datum) が、鉛直基準系 (Vertical Datum) として [Datum:1131](https://epsg.io/1131-datum) がそれぞれ定義されています。

EPSG に登録されている内容を、各テーブルごとに整理すると下記のような構造になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/e54af996-f398-4a1b-94bf-840eec361e35.png)

測地系 (Geodetic Datum) の方は楕円体 (Ellipsoid) と本初子午線 (Prime Meridian) を参照しています。 JGD2011 の場合は [Ellipsoid:7019](https://epsg.io/7019-ellipsoid) の GRS 1980 と、 [PrimeMeridian:8901](https://epsg.io/8901-primem) の Greenwich となります。

鉛直基準系 (Vertical Datum) の方は楕円体等への参照はありません。これは JGD2011 (vertical) に限らず、 `datum_type:vertical` のレコード全般です。代わりに標高決定の実現方法を保持しており、 JGD2011 の場合、潮位計を基準とした水準測量ネットワークによる決定を意味する Levelling-based となっています。

## JGD2024 はどうなる？

この記事では書くことがあまりないので、 EPSG における JGD2024 対応について個人的な意見を書いておきます。

2025年4月に標高における測量成果の改定（元期：2024年6月）が行われ、その基準系を「日本測地系2024」とされました。ただし、緯度経度および緯度経度を投影した平面直角座標系について本質的には改定されていません。名称としては「日本測地系」すなわち測地系 (Geodetic Datum) の内容については改定なしで、鉛直基準系 (Vertical Datum) に対する改定となります。

https://www.gsi.go.jp/sokuchikijun/hyoko2024rev-QA.html

https://www.gsi.go.jp/sokuchikijun/datum-main.html

北米では [North American Datum 1983](https://epsg.io/6269-datum) と [North American Vertical Datum 1988](https://epsg.io/5103-datum) のように Datum と Vertical Datum を使い分けています。

日本の場合、一つ前の改定が東日本大震災の影響で同時に測地系と鉛直基準系（水準原点の標高値）両方であったため、どちらも「日本測地系2011」とみなされており、さほど問題にはなりませんでした。個人的には、 Verical Datum に対し「日本測地系2024 / JGD2024」という名称を使ったり、改定していない Geodetic Datum に対し「日本測地系2024 / JGD2024」とするのはやめて欲しかったなあ。と思います。

EPSG の対応については、鉛直基準系の改定ですので Datum:1131 の後継を追加する必要がありますが、測地系は改定されませんので Datum:1128 や、 Datum:1128 から派生する CRS:6668 などの座標参照系については後継を追加する必要は本質的にはありません。

EPSG Dataset の管理方針に関わるので可能かわかりませんが、「JGD2011 (JGD2024)」のような名称にリネームを行い、 Datum:1128 や CRS:6668 のコード自体は使用し続けるのとよいような気がします。

## 訳語について

Datum をなんと訳すか問題。

一般的には「測地系」と訳される Datum ですが、今回に関しては Datum の中に Geodetic Datum と Vertical Datum があり、そのそれぞれを区別したいわけです。 JIS X7111 などでは「原子」という訳をしていますが、さすがにそれは馴染みないしニュアンスすら伝わりにくいと思い却下。「データム」とカタカナで表すのも違う気がするので却下。

とりあえず Geodetic Datum を「測地系」と訳すとして、何かよい訳語がないか ChatGPT に聞いたところ「基準系」という訳を使っており、まあ悪くないかなと思い採用しました。 Vertical Datum は「鉛直系」としてもよかったのですが、「鉛直基準系」にしてみました。（なら Geodetic Datum も「測地基準系」でよかったのではという気もしますが）

## 次の記事

次の記事では座標参照系について扱います。

https://qiita.com/tohka383/items/ae4dcfd14fe8bfef8b42
MacのAirplayが映らない場合の対処方法

## ケース
動画ファイル（拡張子mp4）をMacのQuickTime Playerで再生する。
その画面を、Airplayを使ってテレビ等のモニターに映そうとするのだが
いつまで経っても表示されない。　という現象の解決策を記載します。
なお、同じWi-Fiに繋ぐ等の基本的な対処方法はここでは割愛するので、
最後の手段として見て頂ければと思います。

例：
以下のようにQuickTime Playerでミラーリングのボタンをクリックして、
ミラーリング先のデバイスにチェックを入れる。（画像ではテレビを選択）
![スクリーンショット 2025-04-06 22.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/b07b4c10-03e9-4390-b6fe-541286faafeb.png)
本来は動画が映ってほしいところだが、テレビには以下の画面が表示されたままとなってしまう。
![IMG_8634.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/a96aa935-77c1-4643-a011-a3a37a4e86b7.jpeg)


## 対処方法
結論として、QuickTime Playerのミラーリング機能をつかうのではなく、
Mac標準のミラーリング機能を使うことで表示されます。

![スクリーンショット 2025-04-06 22.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15241/de3dd261-8819-434d-a0a5-8d6f0fb225ff.png)

たったこれだけのことですが、なんでか分からずハマったのでここに残しておきます。
Cloud Schedulerを使ってCloud Runを定期実行しよう！

## 概要
Cloud Schedulerを使ってCloud Runを定期実行する方法について解説します

## 実装
Cloud Scheduler用のService Accountを作成します
今回はCloud SchedulerのAdmin権限とCloud Runを実行するinvokerの権限を付与します

```iam.tf
resource "google_service_account" "cloud_scheduler_sa" {
  account_id   = "cloud-scheduler-jobs-invoker"
  display_name = "Cloud Scheduler Jobs Invoker"
}

resource "google_project_iam_member" "cloud_scheduler_jobs_admin" {
  project = var.project
  role    = "roles/cloudscheduler.admin"
  member  = "serviceAccount:${google_service_account.cloud_scheduler_sa.email}"
}

resource "google_project_iam_member" "cloud_scheduler_jobs_invoker" {
  project = var.project
  role    = "roles/run.invoker"
  member  = "serviceAccount:${google_service_account.cloud_scheduler_sa.email}"
}
```

Cloud Schedulerを作成します
今回は5分に1回実行するよう設定します
また、uriは以下のようにgoogleapis.comを使って指定しているので認証はoauth_tokenを使用します

```scheduler.tf
resource "google_cloud_scheduler_job" "job_scheduler" {
  name        = "trigger-sample-job"
  region      = var.region
  description = "Trigger Cloud Run Job every 5 minutes"
  schedule    = "*/5 * * * *"
  time_zone   = "Asia/Tokyo"

  http_target {
    http_method = "POST"
    uri         = "https://${google_cloud_run_v2_job.cloud_run_job.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.project_number}/jobs/${google_cloud_run_v2_job.cloud_run_job.name}:run"

    oauth_token {
      service_account_email = google_service_account.cloud_scheduler_sa.email
    }
  }
}
```

## 実際に実行してみよう！
以下のように5分に一回Cloud Runが定期実行できれば成功です

![スクリーンショット 2025-04-06 22.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/60da297b-07f9-45e3-9c1b-d15063ab866a.png)

## 参考
https://cloud.google.com/run/docs/execute/jobs-on-schedule?hl=ja#terraform

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_scheduler_job

https://cloud.google.com/run/docs/troubleshooting?hl=ja#401

https://moito.com/blog/google-cloud-scheduler-call-to-cloud-functions-401-error/
LocalでWordPressサイトのデータベースをインポートする際に発生するFatal error: Allowed memory size ..の対処

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 200357520 bytes) in...

AdminerEvoでSQLのファイルをインポートしようとした結果、
上記のエラーが出て先に進めない。

All-in-One WP Migrationも高くて使えず、少し格闘したので備忘メモ。

## 解決策(Mac版): 
Adminerの「サーバーから実行」でインポートを実施した。
手順は以下の通り。

1. Finderで以下の階層をひらく
アプリケーション > Local > (右クリックで)パッケージの内容を表示 > Contents > Resources > extraResources > adminer

2. SQLのファイルを設置
上記の階層(adminer.phpと同じ階層)に、インポートしたいsqlのファイルを設置。
このとき、adminer.sql または adminer.sql.gz(gzipの場合こちら)と名前をつけ直す必要がある。

3. インポートを実行
AdminerEvo上にて
インポート > サーバーから実行（Webサーバファイル） > ファイルを実行 ボタン押下

これでエラーなくインポート完了できた。


AIに聞いたらwp-config.phpでメモリの上限を書き換えるとかいろいろ出てきたけど
試してもうまくいかず、最終的にこれで解決した。
Lenovo ThinkPad ハイブリッド USB Type-C/USB Type-A ドックを経由したM4 MacBook Airから外部モニタへの出力

# ハードウェア環境
- **M4 MacBook Air 13インチ**
- **Lenovo ThinkPad ハイブリッド USB Type-C/USB Type-A ドック**
- **Dell製 27インチモニター： D2721D**

## 結論
**Lenovo ThinkPad ハイブリッド USB Type-C/USB Type-A ドック**を経由して**M4 MacBook Air**から外部モニタに出力するには、単にケーブルを接続するだけではモニタが認識されません。**DisplayLink Manager**をインストールする必要があります。

## 手順

1. **DisplayLink Managerをインストール**
   - [DisplayLink Managerのダウンロードページ](https://www.synaptics.com/products/displaylink-graphics/downloads/macos)にアクセスし、「DisplayLink Manager」をダウンロードします。
   - ダウンロードページで「Accept」をクリックし、インストールファイルをダウンロードします。

2. **インストール**
   - ダウンロードしたインストーラーを開き、通常のアプリインストール手順に従ってインストールします。

3. **システム設定**
   - インストールが完了したら、**DisplayLink Manager**を起動します。画面記録の許可を求められるので、「システム環境設定」→「プライバシー」→「画面記録」から**DisplayLink Manager**にチェックを入れて許可します。

4. **外部モニタ接続**
   - これで、ThinkPadハイブリッドドックを経由してMacBook Airから外部モニタに出力できるようになります。

## 注意点
DisplayLinkを使用することで、外部モニタが正常に認識されますが、ドライバのインストールと設定が必須です。  
万一、不具合等が発生しても当方は一切の責任は負いません。
Llama.cr をAIに作ってもらった話 - Crystalでバインディングを作る時の注意点

## はじめに

前回の記事では、ONNX Runtime を Crystal から動かせるようになった話を紹介しました。

https://qiita.com/kojix2/items/cd7710d8dee4567b1ed1

ONNX Runtime が動かせるなら、`llama.cpp` も動かせるのでは？と思い、試してみたところ、あっさりと動いてしまいました。しかも、CLINE + Claude にとっては `llama.cpp` の方が ONNX Runtime よりも簡単だったようで、特に初速の立ち上がりがすごかったです。

## AIもメモリの扱いが苦手

しかし調子に乗って関数や機能をどんどん追加していくと、次第にエラーが発生するようになりました。

セグメンテーション違反（Segmentation Fault）が出るようになり、しかもなかなか修正してくれません。しばらくは改修をどんどん指示していたのですが、改善の兆しが見えなかったため、`gdb` などを使ってメモリリークの発生箇所を特定し、バックトレースをAIに渡したりもしました。しかし、それでもなかなか直らなかったので、自分でソースコードを見てみると……。

私の目にも明らかに「これはダメだな」とわかるような状態になっていました。

私は職業エンジニアではなく、半ば趣味でプログラミングをしている人間です。仕事で静的型付き言語を本格的に使ったこともありませんし、スキルが高いとはとても言えません。Ruby や Crystal の C ライブラリ向けバインディングを作っているので、C言語はほんの少しだけ読めるようになりましたが、自分で書けるわけではありません。

そんな私でもわかる程度に、コードにはアドホックなワークアラウンドがたくさん存在していました。

「AIって意外とメモリ管理が苦手なんだな」と思いました。

## CrystalでCバインディングを作成するときの一般原則

Crystal における C バインディングのメモリ管理が難しい最大の理由は、Crystal 側で確保したメモリは主に GC によって管理されるため、「どのタイミングで解放されるのか分からない」という点にあります。

最もよくないパターンは、同じ構造体について、Crystal 側で `malloc` により確保するケースと、C 言語側の関数で確保するケースが混在することです。Crystal の `malloc` は `libgc` のそれなので、私たちの知らないタイミングでメモリが解放されます。一方、C 側の関数で確保された構造体は、対応する C の関数を使って手動で解放する必要があります。

つまり、同じ構造体に対して、Crystal と C の両方でメモリ確保が行われる場合がある状態になると、Crystal 側で確保した場合であっても `finalize` メソッドが呼び出され、二重解放が発生してしまうのです。

そのため、ベストプラクティス（あくまで私がそう考えているだけかもしれませんが）は、以下のとおりです：

1. 各構造体ごとに、Crystal 側でメモリを確保すべきか、C 側で確保すべきかを事前に決めておく  
2. どうしても混在が避けられない場合は、フラグなどで管理し、メモリの確保方法に応じて解放方法も変える

こうした大原則はドキュメントとしてあまり整備されておらず、Crystal でいくつかバインディングを作ってみないと身につかない知識です。そのため、AI もまだ十分には理解していないのではないかと感じました。

このような基本が伝わっていなかったため、`gdb` のバックトレースなどを渡しても、どこで二重解放が起きているのかを特定できたとしても、問題解決にはつながらず、アドホックな対応ばかりが増えてしまいました。

## AIとは「話し合い」が重要

問題の所在が明らかになったので、CLINE の `ACT` を停止し、`PLAN` に切り替えて、Crystal のメモリ管理について AI に説明しました。

また、AI 側から「`llama.cpp` のコードを読みたい」というリクエストがあったので、コード全体を渡しました。すると Claude は、「`llama.cpp` の初期化処理が良くない」と言ってきました。まあ、確かにそうかもしれませんし、C++ ではよくあるスタイルなのかもしれません。

特に印象的だったのは、「AIは、アップストリームのリポジトリにプルリクエストを送って修正提案をする」といった発想はあまり持っていないのだな、ということです。

## まとめ

AI エージェントの力は素晴らしく、短時間で `llama.cpp` のバインディングを作成してくれました。  
私は LLM についてほとんど理解していないにもかかわらず、ダウンロードした GGFU ファイルを使って、PC 上で英語の文章を生成できるようになりました。

一方で、AI を使ったプログラミングには、いくつかの課題も見えてきました。

- Crystal における C バインディングの慣習など、学習資料が少ない分野では、AI も正しい結論にたどり着きにくい  
- AI は「アップストリームのライブラリ自体を修正する」という発想に乏しい  
- プロジェクトの立ち上げは簡単だが、どうメンテナンスするかという視点はまだ不十分  
- 現状では、まだまだコストがかかる

また、人間とプログラミングの関係性そのものも、大きく変わってきていると感じます。

これまで私は、Ruby や Crystal を好んで使ってきました。これは、それらの書き心地が好きだったからであり、趣味であるがゆえに、自分の好きな言語を選べたからです。

しかし、AI エージェントの時代では、やり取りする「日本語」や「自然言語」こそが、真のプログラミング言語になりつつあります。  
これまで人間が人間に対して行ってきたような「間接的なプロジェクト管理」こそが、今後は AI に対して求められる役割になっていくのではないかと感じています。

この記事は以上です。

---
本記事は、ChatGPTによる日本語の編集・校正を行っていますが、本文の内容は人間である私が全て書きました。
【備忘録】線形回帰モデルの評価：予測精度を正しく測るための指標と注意点

# 1. はじめに
　今回は線形回帰モデルの評価について、作成したモデルがどの程度予測を当てられるのか、その性能を正しく理解し、改善に繋げるための重要な指標と注意点をまとめていきます。

 # 2. 線形モデルの評価について
　線形回帰モデルを構築する目的は、入力変数（説明変数）と出力変数（目的変数）の間の線形な関係性を学習し、未知の入力に対して目的変数を予測することです。しかし、どんなに複雑なモデルを作ったとしても、その予測が的外れであれば意味がありません。

モデルの評価を行うことで、以下の点を把握できます。

**・モデルの予測精度**: 実際の値と予測値がどの程度一致しているか。
**・モデルの汎化性能**: 未知のデータに対しても同様の精度で予測できるか。
**・モデルの改善点**: 誤差の傾向を分析し、モデルの改良に繋げるヒントを得る。

適切な評価指標を選択し、モデルの特性を理解することで、より信頼性の高い予測モデルを構築できます。

# 3. 線形回帰モデルの主要な評価指標
### 3.1. 平均二乗誤差 (Mean Squared Error: MSE)
　各データポイントにおける予測値と実際の値の差（残差）を二乗し、その平均を取ったものです。
 ```math
 MSE=\frac{1}{n}\sum_{​i=1}^{n}​(y_i​−\hat{y_i}​)^2
 ```
**特徴**:
・誤差を二乗することで、誤差の大きさを強調し、大きな誤差に対してより大きなペナルティを与えます。
・単位は目的変数の単位の二乗になります。
・値が小さいほど、モデルの予測精度が高いと評価できます。
・外れ値の影響を受けやすいという欠点があります。

### 3.2. 二乗平均平方根誤差 (Root Mean Squared Error: RMSE)
　MSEの平方根を取ったものです。
```math
  RMSE = \sqrt{MSE}
```
**特徴**:

・MSEと同様に誤差の大きさを評価しますが、平方根を取ることで単位が目的変数と同じになり、解釈しやすくなります。
・MSEと同様に、値が小さいほどモデルの予測精度が高いと評価できます。
・こちらも外れ値の影響を受けやすいです。

### 3.3. 平均絶対誤差 (Mean Absolute Error: MAE)
　各データポイントにおける予測値と実際の値の差（残差）の絶対値を取り、その平均を取ったものです。
 ```math
 MSE=\frac{1}{n}\sum_{​i=1}^{n}​|y_i​−\hat{y_i}​|
 ```
 **特徴**:
・誤差の大きさを絶対値で評価するため、MSEやRMSEと比較して外れ値の影響を受けにくいです。
・単位は目的変数と同じで、誤差の大きさを直感的に理解しやすいです。
・MSEやRMSEほど微分可能性に優れていないため、最適化アルゴリズムによっては扱いにくい場合があります。

### 3.4. 決定係数 (R-squared)
 モデルによって説明できる目的変数の分散の割合(モデルが実際のデータに対してどれくらい当てはまっているか)を示します。0から1の間の値をとり、1に近いほどモデルの当てはまりが良いと評価されます。
```math
R^2 = 1 - \frac{RSS}{TSS}
```
ここで
RSSは残平方和(Residual Sum of Squares)
```math
 RSS=\sum_{​i=1}^{n}​(y_i​−\hat{y_i}​)^2
```
TSSは総平方和(Total Sum of Squares)
```math
 TSS=\sum_{​i=1}^{n}​(y_i​−\bar{y}​)^2
```
 **特徴**:
・モデルがデータの変動をどの程度説明できているかを示す、直感的で分かりやすい指標です。
・異なるスケールの目的変数を持つモデル同士の性能を比較するのに適しています。
・説明変数の数が増えると、見かけ上決定係数の値が上昇する傾向があるため、注意が必要です（自由度調整済み決定係数を用いることでこの影響を軽減できます）。
・モデルの予測誤差の大きさ自体を示すわけではありません。

### 3.5. 自由度調整済み決定係数 (Adjusted R-squared)
 決定係数を、説明変数の数とデータサイズに基づいて調整したものです。

```math
R_{adj}^2 = 1 - \frac{n - 1}{n - p - 1}(1 - R^2)
```
ここで、
**・R^2**：決定係数
**・n**：データサイズ
**・p**：説明変数の数

 **特徴**:
・説明変数の数を増やすことによる決定係数の過大評価を抑制します。
・不要な説明変数を追加すると値が低下するため、変数の選択の際に役立ちます。
・基本的な解釈は決定係数と同様です。

# 4. モデル評価時の注意点
　単に上記評価指標の数値を見るだけでなく、以下の点にも注意を払うことも必要となってきます。
 
 **・データの分割**: モデルの学習に使用したデータ（訓練データ）だけで評価を行うと、過学習（訓練データに特化しすぎて未知のデータに対する予測性能が低い状態）を見抜くことができません。必ず、学習には使用していない検証データやテストデータを用いて評価を行う必要があります。
 
 **・誤差の分布の確認**: 残差（実際の値と予測値の差）の分布をヒストグラムや散布図などで確認することで、誤差に偏りがないか、特定のパターンが見られないかなどを把握できます。誤差が正規分布に従っていることが理想的ですが、そうでない場合はモデルの改善が必要となる可能性があります。
 
 **・外れ値の影響**: MSEやRMSEは外れ値の影響を受けやすいため、データに外れ値が含まれる場合は注意が必要です。MAEなど、外れ値の影響を受けにくい指標と合わせて評価したり、外れ値への適切な対処を検討したりする必要があります。
 
 **・ドメイン知識の活用**: 評価結果を解釈する際には、そのデータに関するドメイン知識を考慮することが重要です。例えば、予測が難しい特定の状況が存在する場合や、データの収集方法に偏りがある場合などが考えられます。

 # 5. まとめ
　今回は、線形回帰モデルの評価について、主要な評価指標とその特徴、そして評価時の注意点についてまとめました。

**・MSE, RMSE**: 誤差の大きさを二乗で評価。外れ値に敏感。
**・MAE**: 誤差の大きさを絶対値で評価。外れ値に頑健。
**・決定係数**:モデルが実際のデータに対してどれくらい当てはまっているかを示す指標です。
**・自由度調整済み決定係数**: 説明変数の数を考慮し決定係数。
 
　これらの指標を適切に選択し、データの分割、誤差の分布、外れ値の影響、そしてドメイン知識を考慮することで、線形回帰モデルの性能をより深く理解することができます。
最後までお読みいただきありがとうございました。
【Raspberry Pi 5】純正クーラーのファンがずっとフル回転する問題の対処法

# 現象
Raspberry Pi 5にRaspberry Pi OSをインストールしたが、純正アクティブクーラーがずっとフル回転していた。
OSを再インストールしたり、他バージョンのRaspberry Pi OSをインストールしても治らなかった。

# 環境
- Raspberry Pi 5 (8GB)
- Raspberry Pi OS Lite (bookworm)

# 対処法
1. `/boot/firmware/config.txt`に以下の行を追記する
    ```text
    dtparam=cooling_fan=on
    ```
    
2. `sudo reboot`等で再起動を行う
WordPress.comのデータベースの中身がローカルで文字化けするときの対処

## 発生した問題
WordPress.comのデータベースの中身をローカル環境（Localを使用）に反映する際
日本語の部分が文字化けしてしまった。
（タイトル、本文などすべて「???」となってしまった）

DBのエクスポートは普段どおりWP管理画面の設定のところからphpmyadminに入り、
sql, gzipなどの形式でエクスポートした（それでうまく行く場合がほとんど）。

格闘すること半日、原因が特定できた。

## 原因・解決方法
### 結論
ローカル環境のwp-config.phpの、以下の部分を'latin1'に書き換えた。
define( 'DB_CHARSET', 'utf-8' );
↓
define( 'DB_CHARSET', 'latin1' );

### 詳細
文字コードの設定は以下の通りである。
#### 本番環境：
・wp-config.php：DB_CHARSETの記述なし
・データベース：「latin1_swedish_ci」（mysqlのデフォルト設定がこれらしい。）

#### 修正前のローカル環境
・wp-config.php：'DB_CHARSET', 'utf-8'
・データベース：「latin1_swedish_ci」(localのAdminerEvoで「照合順序」をチェック)

#### 修正後のローカル環境
・wp-config.php：'DB_CHARSET', 'latin1'
・データベース：「latin1_swedish_ci」

つまり、私のローカルで wp-configに書かれているDB_CHARSET(UTF-8)と
AdminerEvoのデータベースの「照合順序」（latin1）がチグハグになっていたため発生した問題と思われる。

だいぶパニクっていろいろ設定をいじっていたので 記憶違いもあるかもしれないが
少なくとも 私の環境ではこの設定を機に文字化けが修復できた。

追記：
あとからみると　ローカルの「照合順序」が　utf8_unicode_ci	になっていた。
もはや仕組みはよくわからないが、いったんローカルで文字コードの辻褄を合わせたあとで
実態に即した utf8 へDBが自動的に？更新されるのかもしれない。
データカタログを中心とした自律分散組織

データカタログは、自律分散組織を円滑に進める上で重要な役割を果たします。

データカタログ整備を含めたデータマネジメントを専門組織に任せるブームが過去に一時期的にありましたが、この体制があくまで過渡期であり一つの部門に負荷をかけすぎるため、長期的に目指す姿ではありません。

そんな中で、データカタログを中心に置きつつ、各ステークホルダーが自由にデータカタログのプラットフォーム上でGive&Takeし、データの提供と利用へのモチベーションを感じてもらう体制とアーキテクチャづくりこそ持続可能な体制かと思い、今回の記事の執筆に至りました。

## 背景： データの所在と管理を分散化
データの所有権とマネジメントを分散化することに重点を置いたアーキテクチャ（データメッシュ構造）において、データカタログが中心的な役割を担います。

データカタログの存在により、「データがほしいユーザー」、「データを提供するユーザー」が自由に出会い、「データ管理したいユーザー」が総合的に利用状況、データの質と量を把握することを可能にします。

以下が今回のアーキテクチャ図となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747743/895719ec-b24c-4efa-9833-b449e498b7fe.png)


## 必要な時に必要なデータをすべてのユーザーに提供 (Just In Time)
データカタログの価値としては、ユーザーにリアルタイムに情報を提供できる仕組みを可能にすることにあります。さらに日本の労働人口が日々減少し、定型の運用作業に人員を割けなくなっていくなかで、データを探したいユーザーのニーズだけでなく、データを提供したいユーザーやデータを管理する統制部門、システム部門のニーズも今回のアーキテクチャで考慮されております。今回の自助プラットフォームの実装では、様々な連携APIやWebhookを利用しております。

https://future-architect.github.io/images/20250310a/image_2.png


## ユーザーにデータ探索と共有の体験を提供
リアルタイム連携することで、データカタログの陳腐化を防げると同時に、定型作業のような「面倒くさい」ことを自動化させつつ、ユーザーに最高なデータ探索・共有の体験を提供できます

## あらゆるメタ情報と結びつける
自助プラットフォームの中で、フリーランスのデータエンジニアがコードベースで書いたデータスキーマ、いわゆるデータのメタデータのみならず、データスチュワード/データアーキテクトが定めたテーブル権限定義や運用ルール、定期的に集計されるユーザー利用状況などあらゆる情報も取得できます。各データのステークホルダーが各自プル型で情報を取得するようになります。

※我々の新しい取り組み「フリーランスプラットフォームの活用」について、別の記事を参考していただけるとうれしいです（リンク：https://future-architect.github.io/articles/20241029a/ by フューチャーアーキテクト　高瀬陸）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747743/52e1fde5-fb44-4ef7-a438-debfa0c197b9.png)

## ユーザーの業務とデータの認知マップ
あらゆるメタ情報を集約しても、まだ不十分です。なぜならば、ユーザーによって職種や今のIT経験にばらつきがあるからです。そういった性質を持ったユーザーを分類し、ユーザー群ごとに一番詳しい業務用語からデータを検索することで、自然とテーブル情報にたどり着けるように設定しております。

それに加え、ITリテラシーによってポータルサイトの入口を細分化するよう工夫しております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747743/6f8de6bc-8f68-4fa8-a005-d24e9d42e432.png)


## 自律分散組織を支えるアーキテクチャ
データカタログの自動処理レイヤについては、スキャニングレイヤとソーシャルレイヤで構成され、GCP内の情報を取得して表示したり、UIからの変更をBigQueryに反映したりできます。今回は、ユーザー側では既存のグループウェアNotionをすでに利用されていることに加え、複数軸で情報のビューを表示できることもあり、そのままNotionをデータカタログのUIとして採用することになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747743/7470c1d2-8462-4c6e-959e-8c4f39cef9d4.png)


以上が今回の自律分散組織をささえるアーキテクチャとそのポイントを紹介させていただきました。なにかヒントになれたら幸いです！

## 参考書籍
大規模データ管理 ―エンタープライズアーキテクチャのベストプラクティス （[kindle](https://www.amazon.co.jp/%E5%A4%A7%E8%A6%8F%E6%A8%A1%E3%83%87%E3%83%BC%E3%82%BF%E7%AE%A1%E7%90%86-%E2%80%95%E3%82%A8%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%97%E3%83%A9%E3%82%A4%E3%82%BA%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Piethein-Strengholt/dp/481440008X)）
Git基本操作の備忘録

# Gitコマンド備忘録
Gitの基本操作コマンドの備忘録

## 基本設定
```bash
# ユーザ名の設定
$ git config --global user.name "name"
# メールアドレスの設定
$ git config --global user.email "email"
```

## リポジトリ作成
```bash
$ git init
# Gitで管理しないファイルは、
# .gitignoreファイルを作成して、そこに無視したいファイルやディレクトリ名を書く
```

## リモートリポジトリをクローンする
```bash
$ git clone リモートリポジトリのパス
```

## リポジトリの状態を確認する
```bash
$ git status
```

## ファイルやディレクトリをステージングエリアに登録する
```bash
$ git add ファイル…
$ git add ディレクトリ…
# プロジェクトのすべてのファイルとディレクトリをGitの管理下に置く
$ git add .
```

## ステージの内容をコミットする
```bash
$ git commit
# 一行のコミットメッセージでコミットする
$ git commit -m "コミットメッセージ"
```

## コミットの履歴を見る
```bash
$ git log
$ git log --online
$ git log -- ファイル名
$ git log --all --graph
```

## 差分を表示する
```bash
# 作業ツリーとステージの差を表示する
$ git diff

# ステージとHEADの差を表示する
$ git diff --staged

# 作業ツリーとHEADの差を表示する
$ git diff HEAD

# コミットの間で変更した差を表示する
$ git diff コミット1 コミット2

# ファイルを指定して、そのファイルについての差分を表示する
$ git diff コミット1 コミット2 -- ファイル

# 1つ前のHEADとの比較
$ git diff HEAD^ HEAD

# 2個前のコミットとの比較
$ git diff HEAD~2 HEAD
```

## ローカルリポジトリでの操作を取り消す
```bash
# ワークツリーの変更を取り消す
$ git restore ファイル

# ステージングエリアの登録を取り消す
$ git restore --staged ファイルパスまたはディレクトリパス

# ワークツリーとステージングエリアの変更を同時に取り消す
$ git restore --staged --worktree ファイルパスまたはディレクトリパス
```

## コミットの情報を表示する
```bash
# 直近のコミット内容を表示
$ git show

# 指定したコミットの内容を表示
$ git show コミット
```

## ステージの内容を見る
```bash
# ステージ内になるファイルの一覧を表示する
$ git ls-files

# 詳細情報も併せて表示する
$ git ls-files -s
```

## ファイル名、ディレクトリ名を修正
```bash
$ git mv 元の名前 新しい名前
```

## ファイルやディレクトリをステージから取り除く
```bash
$ git rm ファイル
$ git rm -r ディレクトリ
```

## リモートリポジトリの確認
```bash
$ git remote -v
```

## ブランチ操作
```bash
# ローカルのブランチの確認をする
$ git branch

# リモートのブランチを確認する
$ git branch -r

# すべてのブランチを確認する
$ git branch -a

# ブランチ作成
$ git branch 作成するブランチ名

# ブランチ切り替え
$ git switch 切り替え先のブランチ名

# ブランチ作成と同時にスイッチする
$ git switch -c 作成し、切り替えたいブランチ名
```

## 変更をリモートリポジトリに反映する
```bash
$ git push
$ git push プッシュ先のリモートリポジトリの名前 プッシュするブランチ名
#例)$ git push origin testbranch
```

## リモートからローカルに反映するコマンド
```bash
$ git pull プル先のリモートリポジトリの名前 プルするブランチ
#例)$ git pull origin main

$ git fetch フェッチ先のリモートリポジトリ
#例)$ git fetch origin

# ローカルリポジトリに存在しないブランチを取得する
$ git fetch origin
$ git switch ブランチ名
```

## マージする
```bash
# 今いるブランチにマージする
$ git merge マージしたいブランチ名
```

## 過去のコミットに移動する
```bash
$ git checkout コミット名
```
【Go】pgxでErrNoRowsのエラーを判定する

## 概要
[Go のちょっと変わったORM sqlc の紹介](https://qiita.com/ktat/items/2ed13afcd29f49aee6a1)の記事で紹介されているsqlcですが、PostgreSQLで使用する際はドライバーのライブラリは[Getting started with PostgreSQL](https://docs.sqlc.dev/en/stable/tutorials/getting-started-postgresql.html)の公式ページで紹介されている通り、pgxの使用が推奨されています。
そのpgxでクエリの結果を取得した際に、1件もなかった時の判定をする際のメモ書きです。

## 前提
* 使用したpgxのバージョンは`v5.7.4`です。

## 判定方法
[:one without results is supposed to return "sql: no rows in result set" which is the same as database/sql.ErrNoRows but returning "no rows in result set"](https://github.com/sqlc-dev/sqlc/issues/3618)のissueで言及されている通り、エラーは`sql.ErrNoRows`ではなく`pgx.ErrNoRows`で返ってきます。ので、判定方法としても`pgx.ErrNoRows`と比較する形となります。

## 実装サンプル
pgxを設定した際のsqlcで、クエリ発行時のErrNoRowsの判定実装サンプルです。

```go
// ユーザIDが重複してるかチェック
func CheckUserAccountTest(ctx context.Context, queries *db.Queries, input model.NewUserAccount) error {
	// ユーザIDを条件にクエリを実行
	_, err := queries.SelectUserAccountByUserSettingId(ctx, input.UserSettingID)
	if err != nil {
		// pgxのErrNoRowで0件エラーか判定
		if err != pgx.ErrNoRows {
			return err
		}
	} else {
		// ユーザが取得できていたら重複エラー
		return &gqlerror.Error{
			Message: "Dupilicate userSettingId",
			Extensions: map[string]any{
				"code": 400,
			}}
	}

	return nil
}
```
約数関数：約数の数をカウントしグラフで観察

# プログラム
```java:Processing
PrintWriter output;

void setup() {
  output = createWriter("divisorNum.csv"); 
  output.println("n,divisorNum");
  for (int n=1; n<=100000; n++) {
    int count = countDivisors(n);
    output.println(n+","+count);
  }
  output.flush();
  output.close();
  exit();
}

int countDivisors(int number) {
  int count = 0;
  for (int i = 1; i <= number; i++) {
    if (number % i == 0) {
      count++;
    }
  }
  return count;
}
```
828 KBのファイルが出力されます。
計算時間は数秒

# エクセルで散布図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/cb411275-7a48-4006-8088-e11d5b62638f.png)

特徴①　層になる
特徴②　個数が存在しない層がある
特徴③　83160と98280の約数の個数は128個

# 出現回数のグラフ
横方向にぎゅっと詰めて、回数をカウント

# 関連サイト
https://ja.wikipedia.org/wiki/約数関数
【競技プログラミング:リハビリ】2次元累積和

# 雑記
AtCoderの問題を解けば解くほど、[競技プログラミングの鉄則](https://www.amazon.co.jp/%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E9%89%84%E5%89%87-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E7%B1%B3%E7%94%B0-%E5%84%AA%E5%B3%BB-ebook/dp/B0BDZGDM9J/ref=sr_1_1)という本の完成度の高さを感じます。
この本を買ったのは、2022年10月だったのだけど、当時読んでたときは「分かりやすい」という感想しかなかったけど、今は「凄い」という感想に。(もう2年半経つとか、時間感覚フリーレン状態ですわ)
スランプに陥ったときはこの本と、過去に完全に理解したことのあるアルゴリズムを読みながら、リハビリをすることにしています。
ということで、スランプ中の今は基本アルゴリズムを、[testcase-generator](https://github.com/naskya/testcase-generator)を使いながら、トレースしつつ眺めてみることにします。

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

# 二次元累積和
```python:sample_code.py
def cumulative_sum_2d(matrix):
    """
    二次元配列の累積和を計算する関数

    Args:
        matrix (list of list of int): 元の二次元配列

    Returns:
        list of list of int: 累積和を格納した二次元配列
    """
    if not matrix or not matrix[0]:
        return []

    # 元の行列のサイズ
    rows, cols = len(matrix), len(matrix[0])

    # 累積和を格納するための行列を初期化
    cum_sum = [[0] * cols for _ in range(rows)]

    # 累積和を計算
    for i in range(rows):
        for j in range(cols):
            cum_sum[i][j] = matrix[i][j]
            if i > 0:
                cum_sum[i][j] += cum_sum[i - 1][j]  # 上のセルを加算
            if j > 0:
                cum_sum[i][j] += cum_sum[i][j - 1]  # 左のセルを加算
            if i > 0 and j > 0:
                cum_sum[i][j] -= cum_sum[i - 1][j - 1]  # 重複部分を減算

    return cum_sum

if __name__=="__main__":
    # ファイル名を指定
    filename = "./input_data/01.txt"
    
    # 空のリストを準備
    matrix = []
    
    # ファイルを読み込む
    with open(filename, "r") as file:
        for line in file:
            # 行を読み取り、スペースで分割して整数に変換
            row = list(map(int, line.split()))
            matrix.append(row)

    result = cumulative_sum_2d(matrix)

    print("元の行列:")
    for row in matrix:
        print(row)

    print("\n累積和:")
    for row in result:
        print(row)
```

```./input_data/01.txt
77 7 44 55 88 66 48
71 85 19 39 55 4 81
90 72 80 2 0 93 32
20 1 16 67 70 58 30
70 3 21 67 93 79 13
41 24 75 87 75 28 92
88 65 74 93 16 44 31
```

# イメージ
## 読み込んだデータ
![2025年04月08日23時15分0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/84864ec8-4e45-4700-9e6c-55b7b8b9e6b2.png)

## 二次元累積和
![2025年04月08日23時15分1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/e49a163e-ae8c-4ae1-920e-992993464600.png)

## 求めたい領域
![2025年04月08日23時16分0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/7c079daf-4ce1-42cb-8e4d-0861011b630b.png)

### 累積和を用いた計算
$1842-947-561+402=736$
![base_image.create_20250408231619-ページ1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/ffba5c25-f34f-49ba-8420-7c731028f586.png)
#### 面積のイメージ
![base_image.create_20250408231619-ページ2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/4461dfe8-762f-4873-8130-ec8b3221ef01.png)
Mixin の極めてシンプルな例

# 元になるクラスの宣言
まず、Mixin をする 2 つのクラス ClassA, ClassB を作成する。
更に、継承元の BaseClass を作成する。
```prepare.ts
class ClassA {
    methodA() { console.log('method A'); }
}

class ClassB {
    methodB() { console.log('method B'); }
}


class BaseClass {
    member="member"
}
```

# Mixin の定義
はじめに、コンストラクタ型を一般的に定義しておく。
次に、作成したいクラス `MixinAB` のコンストラクタを `function` として定義する。
このとき、 `methodA`, `methodB` の実装は `ClassA` と `ClassB` に委譲する。
このままだと、常に `new MixinAB(BaseClass)` として呼び出す必要があり、`MixinAB` の利用先から `BaseClass` への非本質的な依存関係が生じる。
これを防ぐために、`MixinAB` を継承する形で `MergedClass` を定義する。
```Mixn.ts
type Constructor<T = {}> = new (...args: any[]) => T;

function MixinAB<B extends Constructor>(Base: B) {
    return class extends Base {
        methodA = new ClassA().methodA;
        methodB = new ClassB().methodB;
    };
}

class MergedClass extends MixinAB(BaseClass) {}
```

# Mixin の使用
```use.ts
const merged = new MergedClass();
merged.methodA(); // method A
merged.methodB(); // method B
console.log(merged.member); // member
```
やっと動いた…！初めてのブログアプリをRenderにデプロイした日

![](https://storage.googleapis.com/zenn-user-upload/18d4fd3c256d-20250406.png)
## MacでJava開発、ついにここまで

ついこの前まで、JavaでWebアプリを作るなんて夢のまた夢だと思っていました。  
HTMLとJavaScriptしか知らなかった頃の自分からすれば、「ログイン機能付きのブログアプリを自分で作って、しかも本番環境にデプロイした」なんて、正直かなりの成長です。

今日はその初めての個人開発の記録として、**Java（Spring Boot）製ブログアプリをMac環境で開発し、Renderにデプロイできるようになるまで**をまとめておこうと思います。

## ローカルでの開発：最初の一歩は地味でも大事
![](https://storage.googleapis.com/zenn-user-upload/b0881b6b0b9f-20250406.png)

Spring Bootでプロジェクトを立ち上げ、最初に表示された「Whitelabel Error Page」を見たときは、「ああ、自分で全部作らないといけないんだな」とちょっと絶望しました。  
でも、それと同時に、「これは完全に自分の自由な領域なんだ」とワクワクもしていました。

開発の過程では、**ChatGPTに何度も助けられました。**

- Spring Securityの設定で「ログインできない…」と詰まったとき  
- ControllerやRepositoryの書き方が不安なとき  
- エラーが読めなくて一歩も進めなかったとき  

質問を投げると、わかりやすいヒントやサンプルコードを返してくれて、ただの検索よりも一歩深く理解できた感覚があります。

## Gitとの出会い：バージョン管理ってすごい

今回、**Gitでの管理とGitHubとの連携も人生初でした。**

「とりあえずコードはフォルダに保存」みたいな自己流のやり方から、  
ちゃんとバージョン管理ツールを使ってコードの履歴を残せるようになったことも、個人的には大きな一歩です。

コミットの粒度や、どのタイミングでプッシュすべきかなど、まだ慣れていない部分もありますが、  
GitHubにコードが残っていくことで「積み重ねてる実感」が得られるのが嬉しかったです。

Renderとの連携もGitHub経由だったので、自然と学ぶきっかけになりました。

## 実装した機能たち
![](https://storage.googleapis.com/zenn-user-upload/4a40153ce453-20250406.png)

- **ユーザー登録画面／ログイン画面**の作成  
- **パスワードの保存方式や認証の処理**（Spring Security）  
- **投稿の作成・表示機能**  
- **ログイン済ユーザーだけが投稿できるように制御**

ここまでで、ローカル上では「ユーザー登録→ログイン→投稿→投稿一覧表示」までが一通り動くようになりました。

## 本番環境へのデプロイ：Renderを使ってみた

次に試したのが、Renderへのデプロイ。

最初は「Dockerが必要？」「GitHubとの連携？」「MySQLどうするの？」と不安でしたが、意外とスムーズ。  
無料プランで使えるRenderのWebサービスは、Spring Bootとの相性も悪くなかったです。

環境変数の設定やDBの接続設定に少し苦戦したものの、無事に動作確認ができたときは、  
「本当にこれ、ネットに公開されてるんだ…」と画面を何度もリロードして確認してしまいました。

## 作ってみて気づいたこと

- **「動くものがある」だけで自信につながる。**  
- **フルスクラッチで積み上げることの大切さ。**  
- **デプロイって怖くない。**  
- **AIに頼っていい。**  
  自分ひとりでは進まなかった場面も、ChatGPTに頼ることで前に進めた。  
  ある意味、初めての「ペアプロ」体験だったかもしれない。  
- **Gitは全エンジニアの味方。**  
  コードの履歴を残すこと、変更を振り返れること、こんなに便利だとは思わなかった。

## 次はどこを伸ばす？

- 投稿に画像アップロード機能を追加  
- 投稿編集・削除機能の追加  
- ログイン状態のセッション管理やユーザーごとの表示制御  
- テストコードを書いてみる！

## 最後に：エンジニア初心者でも、作れる

「自分にはまだ早いかも」と思っていたけど、  
やってみれば、わからないことを調べて、試して、失敗して…その繰り返しで、少しずつ動くものができてきました。

ChatGPTの力も借りながらではあるけれど、確かに自分の手で作ったアプリです。  
GitHubにコードを残せたことも、自分にとっては初めての「開発者の一歩」だったと思います。

これを見た誰かが「自分も作ってみようかな」と思ってくれたら嬉しいです。
ABC400 C - 2^a b^2【備忘録】

久しぶりにABCに参加してきました。

お恥ずかしながら、A、Bの２完でした・・・

C問題がわからなかったので復習しようと思います。

# C - 2^a b^2
### 問題文
問題文
正の整数 
X は、次の条件をみたすときかつその時に限り、良い整数と呼ばれます。

正の整数の組 (a,b) を用いて、
$X= 2^a × b^2$

と書ける。
例えば、400は$400=2^2×10^2$ と書けるため、良い整数です。
正の整数N が与えられるので、1 以上N 以下の良い整数の個数を求めてください。

### 制約
$1≤N≤10^{18} $
$ N は整数 $


#### まず何を考えるか
制約がやたらデカいので、全探索は無理だと考える。
おそらく素数判定の時と同じように探索範囲は$ \sqrt{N}$　は数くらいになるのでは？
と考える。対数を取ったらどうだろうか？とかゴニョゴニョ考える。
$2=2^1×1^2$(a,b)=(1,1)
$4=2^2×1^2$(a,b)=(2,1)
$8=2^3×1^2$(a,b)=(3,1)
$16=2^4×1^2$(a,b)=(4,1)
$18=2^1×3^2$(a,b)=(1,3)
おそらく次は$32=2^5×1^2$(a,b)=(5,1)
みたいな感じで具体例をあげてみるが時間がなくなってしまう．．．

### 解説を見て
bは奇数になるというところが正直ピンと来なかった。
おそらくXが$ 2^a$を含んでいるので、必ず偶数($ 2^a $)と奇数($ b^2$)の組み合わせとなる。（$b^2$が偶数だった場合、$2^{a+n}$というような形に変形できるため、自ずと$ b^2$は奇数となると理解）
式変換すると $ b^2 \leq \frac{N} {2^a}  $となり aを固定すると$ b \leq \sqrt\frac {N}{2^a}\ $
奇数となるbは$ \frac{\sqrt\frac {N}{2^a}\+1 }  {2}$を満たすとき

らしい．．．

解(a,b)は組み合わせのため、重複を選ばないようにする必要がある。

aはどこまで探索するばいいのか？
```python:temp.py
for i in range(1000):
    if 2**i>=10**18:
        #aは最大でも60
        a = i
        break
#aは最大でも60
print (a)
```
これを動かしてみるとわかるが$2^a$が$10^{18}$を超える時は60乗なのでaは1から61までを探索すれば良いことがわかる。


```python:temp.py
N = int(input())
from math import isqrt

ans = 0
for i in range(1,61):
    ans+= (isqrt(N//(2**i))+1)//2
print (ans)

```
ちなみに以下だとACできません。。。
たぶん誤差の問題だと思います

```python:temp.py
N = int(input())
import math

ans = 0
for i in range(1,61):
    ans+= int(math.sqrt(N//(2**i))+1)//2
print (ans)

```
誰かわかる方教えてください．．．．
AstroとCloudflareでブログを独自ドメインで作成した話

今回は未経験エンジニアの私がAstroとCloudflareを使って技術ブログを立ち上げるまでの全過程を解説します。

## 目次

- [環境](#環境)
- [目的](#目的)
- [具体的な手順](#具体的な手順)
  - [1. Astroプロジェクトの初期設定](#1-astroプロジェクトの初期設定)
  - [2. ブログのカスタマイズ](#2-ブログのカスタマイズ)
  - [3. Cloudflareへのデプロイ](#3-cloudflareへのデプロイ)
- [結果](#結果)
- [気づき](#気づき)
- [おわりに](#おわりに)

## 環境

```
OS: macOS M1 Macbook Air
Node.js: v18.20.4
npm: 10.8.2
Astro: 5.6
```

## 目的

- 独自ドメインで技術記事を作成する
- AstroとCloudflareで高速な静的サイト作成の手法を学ぶ

## 具体的な手順

### 1. Astroプロジェクトの初期設定

私はこちらの[AstroPaper](https://astro.build/themes/details/astropaper/)テーマのUIに強く惹かれたため、こちらを元に作成しました

```bash
npm create astro@latest -- --template satnaing/astro-paper
```

### 2. ブログのカスタマイズ

#### 日本語化と不要な機能の削除

私はアーカイブ機能やテレグラムへの共有機能は削除しました

> テレグラム怖いイメージあります

#### 記事の日付表示形式の変更

> デフォルトの日付形式もクールでしたが、わかりづらかったので  
> 見慣れているYYYY-MM-dd形式に変更しました

#### 自己紹介記事の作成

こちらの自己紹介記事を作成しました

https://poniblog.com/posts/tech/self-introduction/
#### 予約投稿機能に苦戦

はじめ、`markdown`ファイルtopの`draft`に悩まされました

```yaml
draft: false
```

draftの値に関係なく、ローカルで確認した際は記事が全部表示されていました  
→ デプロイすると`draft: true`の記事が表示されなくなりました  
おそらく、ローカルとデプロイ時では参照している時間が違うため、このようになったかと思われます

#### テーマの色変更

`src/styles/global.css`で全体の色を設定することができます  
黒にピンクの組み合わせが好きなので以下のように変更しました

```css
:root,
html[data-theme="light"] {
  --background: #ffffff;
  --foreground: #1a1a1a;
  --accent: #007bff;
  --muted: #f4f6f8;
  --border: #e1e4e8;
}

html[data-theme="dark"] {
  --background: #0d1117;
  --foreground: #c9d1d9;
  --accent: #ff69b4;
  --muted: #161b22;
  --border: #30363d;
}
```

### 3. Cloudflareへのデプロイ

こちらの記事を参考にデプロイしました

https://qiita.com/RyoWakabayashi/items/2d40b6e8ae7ddee092db

## 結果

完成したブログ:

https://poniblog.com/   

AstroPaperテーマのカスタマイズに成功  
GitHubとCloudflareの連携による継続的デプロイの実現

## 気づき

### 技術的学び

- Astroってすごい
- Cloudflareもすごい

### コスト面の考察

- 無料プランでも十分な機能が揃っている
- ドメイン費用（年間約1,500円）のみで運用可能
  > 安い！！

## おわりに

AstroとCloudflareがとにかく凄いなと思いました

このブログを通じて、フロントエンドからインフラまでの幅広い技術に触れながら、学びを共有していきたいと思います  
同じように技術ブログを始めたいと考えている方の参考になれば幸いです
【Unity】フォルダ階層メモ

## UnityのAssets内フォルダ構成
Asset
-> プロジェクト名のファイル
-> -> Scenes
-> -> Prefabs
-> -> Scripts
-> -> Animations
-> -> Materials
-> -> Physics Materials
-> -> Fonts
-> -> Textures
-> -> Audio
-> -> Resources

Packages

## 各ファイル内のテンプレート
ex)
Scenes
-> 0_StartUp
-> -> StartUpScene.unity
-> 1_Title
-> -> TitleScene.unity
-> 2_MainGame
-> -> MainGameScene.unity
-> 3_Game
-> -> GameScene.unity
-> 4_Result
-> -> ResultScene.unity

みたいな...
毎日kaggle頑張る　その１(タイタニック)

kaggleを勉強する目的
より深く機械学習の知識を深めたい。さまざまなケーススタディを通して実践力を強化。
（賞金が欲しい。。。）

とりあえずタイタニックチュートリアルに挑戦。
一旦ブログとか参考に要点をつまみながら提出。

ポイント1.欠損値の扱い方
欠損値をみると欠損値であることに意味があるので
削除ではなく、0やNAを代入する。

ポイント2.目的変数のグラフを見てみる。
右に長い裾野。
一部の高い住宅が影響してる。
→対数をとることで正規分布に近くなった。