OmniAICreator/Qiita-1.07M huggingface dataset:
【簡単Kubernetes】【CRI】KubernetesにおけるCRI（Container Runtime Interface）とは？


Kubernetes（k8s）は、コンテナを管理・オーケストレーションするためのプラットフォームですが、**コンテナを実際に動かす役割は**「**コンテナランタイム (Container Runtime)**」が担っています。

## 🔍 CRIとは？

**CRI**（Container Runtime Interface）は、Kubernetesの`kubelet`と、さまざまなコンテナランタイムとの間の**標準化されたインターフェース**（API）です。

Kubernetesが複数のランタイムと柔軟に連携できるようにするために設計されており、`kubelet`とコンテナランタイム間の通信を**gRPC**で行います。

---

## 🎯 CRI導入の背景

かつてのKubernetesは主に**Docker**に依存していましたが、以下の課題がありました：

- DockerはKubernetes専用ではなく、不要な機能が多く含まれていた
- 他の軽量ランタイム（例：containerd、CRI-O）との連携が困難だった

これを解決するため、**CRIによってランタイムとkubeletを疎結合に**する方針が取られました。

---

## 🧱 アーキテクチャ概要

```
+--------------------+
|      kubelet       |
+--------+-----------+
         |
         | gRPC (CRI)
         ↓
+--------+-----------+
| Container Runtime  | 例: containerd, CRI-O
+--------+-----------+
         ↓
     runc などの低レベルランタイム
```

---

## 🧰 対応ランタイム例

| ランタイム     | 概要                                           |
|----------------|------------------------------------------------|
| **containerd**  | Docker由来の軽量ランタイム。K8s公式推奨。       |
| **CRI-O**       | Kubernetes向けに開発されたシンプルなランタイム。 |
| **Docker**      | v1.24で非推奨（`dockershim`が削除されました）。 |

---

## 🗂️ CRIが提供する主な機能

CRIは以下のような操作をkubeletに提供します：

- Podの作成・削除
- コンテナの起動・停止
- イメージのプル
- ログの取得

---

## 📌 Kubernetes v1.24以降の注意点

Kubernetes v1.24 以降では、**DockerはCRIのサポート対象外**となっています。  
もしDockerを使い続けたい場合は、containerdやCRI-Oへの移行が必要です。

---

## 📝 まとめ

- **CRIはKubernetesとランタイム間の通信を標準化するための仕組み**です。
- CRIの導入により、Kubernetesはさまざまなランタイムに対応可能となり、柔軟性が向上しました。
- 現在は`containerd`や`CRI-O`が主流です。

---

## 🔗 参考リンク

- [Kubernetes公式ドキュメント（CRI）](https://kubernetes.io/ja/docs/concepts/architecture/cri/)
- [containerd公式](https://containerd.io/)
- [CRI-O公式](https://cri-o.io/)
複数選択リスト項目で特定の値の場合入力規則でエラーが出る方法

本橋孝昭です

今回は複数選択リスト項目で特定の値の場合入力規則でエラーが出る方法をご紹介します

例　複数選択リスト項目　好きな食べ物項目（API参照名test1__c）で「選択にないのでテキスト入力」を選択した場合テキスト項目（API参照名test2__c）が空欄の場合がエラーがでる


入力規則の数式
INCLUDES(test1__c, "選択にないのでテキスト入力") && ISBLANK(test2__c)


数式の解説
- INCLUDES(test1__c, "選択にないのでテキスト入力")
→ test1__c が 複数選択リスト であるため、特定の選択肢が含まれているかを判定します。
- ISBLANK(test2__c)
→ test2__c が空白かどうかをチェックします。
- 両方の条件が満たされた場合にエラーを表示し、ユーザーにテキスト入力を促します。


実際に試したところ複数選択リスト項目　好きな食べ物項目（API参照名test1__c）で「選択にないのでテキスト入力」を選択した場合テキスト項目（API参照名test2__c）が空欄の場合がエラーがでました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e7cb01f5-2e8d-4008-90fa-0794a30f4d58.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/aad89eeb-391f-4e1f-9e72-9ab8fb32860a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/19d96da3-7189-4d2e-9ecf-04a91e108e24.png)
【Python/Django】環境構築・文法疲れも解決！実践で学ぶWeb開発の第一歩

こんにちは、Hibikiです。

Python/Djangoを学びたいと思っている皆さん、こんな経験ありませんか？

:confounded:文法ばかりで退屈！飽きてしまった．．．
:confounded:そもそも環境構築でつまづいて、プログラミングに辿り着けない．．．
:confounded:勉強はしてみたけど、本当にこれで仕事できるようになるのか不安．．．

これらの問題を解決する学習リソースを用意してみました。

人によって合う、合わないはあると思います。

上記のような問題を抱えているなら、一度試してみてはいかがでしょうか？

## 🔹概要🔹
本記事は、Django（ジャンゴ）を使ったWebプログラミング学習のテキストです。

ユーザー認証（ログイン）機能の開発をテーマにDjangoを学ぶ構成となっています。

Pythonに詳しくなくても理解頂ける内容になっています。

本記事に掲載しているテキストは第1弾となりますので、今後のカリキュラムについても楽しみにお待ち頂けると幸いです

## 🔹システム構成🔹
Python 3.11.12
Django 5.2
Poetry ※環境構築時の最新版

## 🔹進め方🔹
### 1️⃣学習コンセプトを一読
テキストは、下記の学習コンセプトに基づいてカリキュラムを作っています。

https://qiita.com/Hibiki-Iwamoto/private/aaa3a75aa5d1a66b8d60

学習コンセプトの理解は必須ではありませんが、読んで頂くとなぜカリキュラムがこのような構成になっているのか納得感を持って進めることができます。

ぜひご一読ください。

### 2️⃣開発環境の構築
次に開発環境の構築です。

開発環境構築の記事も作成していますので、記事を参考にしながら必要なソフトウェアのインストールおよび設定をお願いします。

https://qiita.com/Hibiki-Iwamoto/private/892c423ee313f5ff92c7

インストールするソフトウェアは最低限に絞っています。
Pythonすらインストール不要です。
難しい設定は不要なので、ここでつまづくことは無いでしょう。

もしエラーが出て進まないことがあれば、ぜひご連絡ください。

### 3️⃣学習テキストに沿って学習
あとは学習テキストに沿って進めるだけです。

次のテキストを参照しながら、学習を進めてください。

## 🔹学習テキスト🔹
<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/52269N/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/hibiki-iwamoto/52269N-PLS-Django-Auth01">[PLS]Python/Django Webプログラミング学習 - ユーザ認証機能 - by @hibiki-iwamoto</a></div>
AIへの指示が迷子になる前に──ヒントは“7”という数字

# 整理されていない構造に、知らず知らず慣れてしまっていませんか？

こんな経験はないでしょうか。

>・1つのクラスに、数え切れないほどのメソッドやメンバー変数  
>・1つのフォルダに、無数のクラスファイル  
>・ドキュメントも、一つのフォルダに、嫌になるほどのファイルの数  

──結果、どこに何があるのか、すぐに見つけられない。

そんな状況に「なんとなく慣れてしまっている」ことが、  
私たちの設計と認知の限界を曖昧にしているのかもしれません。

そして最近では、AIが出力したコードや設計のアウトプットも増えてきました。  
そのレビューで、思わず「もう見たくない…」と感じたことはありませんか？  
（もちろん、指示の出し方が悪かった──という反省もありますが）


# 美しいコードとの出会いと、謎の違和感

「読みやすいコード」「美しいコード」──  
その理想像を語るとき、多くの人が思い浮かべるのが名著『リーダブルコード』でしょう。  
私も例にもれず、その本から多くのことを学びました。

けれど、どこか物足りなさを感じていたのも事実です。  
「もっと本質的な、なにかがあるのではないか？」──そう思っていたとき、  
ある過去の体験を思い出しました。

まだ駆け出しだった頃、私はCOBOLのレガシー案件に携わっていました。  
当時のコードは、増改築を繰り返した“どこに何があるか分からない構造”ばかり。
正直、うんざりしながらも、納期を守るために残業地獄の日々でした。

ところがある日、そのプロジェクトでふと古い設計書とコードに出会ったのです。  
それは、30年以上前に書かれたものでした。

----

驚きました。  
そのコードは、あまりにも整っていたのです。

>・フォルダ構成は3階層以内  
>・ファイルごとに責任が明確  
>・一つの関数もシンプルで、まるで建築図面のような構造

初めて「見とれるほど読みやすいコード」を体験した瞬間でした。
誰が作ったのかわかりませんでしたが、  
その設計とコードを手がけた名もなきエンジニアに、  
私は心から尊敬の念を抱きました。今でもその記憶は色褪せません。

ただ当時の私は、それがなぜ“美しい”と感じたのか、言葉にできませんでした。  
ただ──「妙にスッと頭に入る」──そんな印象だけが残っていたのです。

# “美しさ”の正体──マジカルナンバー7±2

その疑問が解けたのは、後に出会った師匠の言葉でした。

>設計は、“人の脳”の構造を意識しないとダメなんだよ。
>ひと目で理解できないものは、設計とは呼べない。

そう語った師匠が教えてくれたのが、心理学者ジョージ・ミラーの論文です。  
いわゆる「マジカルナンバー7（±2）」──

人間の短期記憶で、一度に処理・認識できる情報は5～9個が限界である、という有名な実験結果です。

みなさんも、職場で次のような適性検査を受けたことはありませんか？

「画面に表示されたボールの数を、すぐに答えてください」  
──そういった形式のものです。

3〜6個程度なら、感覚的にすぐに判断できます。  
ところが、7個を超えた途端に「あれ……何個だっけ？」と迷いが生まれる。
そんな経験、心当たりはありませんか？

実際、思い返してみると、あの美しかったCOBOLのコードは、まさにこの原理に沿っていたのです。

>・フォルダ内のファイル数：7つ以下  
>・クラス内のメソッド数：多くても7±2  
>・1つの処理ステップで追うべき変数：5～9個以内
>・設計ドキュメントも、一枚絵で7つ以内のモジュール構成

つまり、**「ひと目で理解できる単位**になるよう、すべてが構造化されていたのです。

# 現代のコード、そしてAI出力が壊す“構造”

一方で、現在の現場では、構造が見えないまま開発が進むような状況を、私自身も何度も経験してきました。

クラスは肥大化し、画面を何度もスクロールしないと構造が把握できない。  
数十個の引数、数百行の関数──  
もはや「全体をひと目で把握すること」は不可能になりつつあります。

最近ではAIがコードや設計・要件まで出力するようになりました。  
確かに便利です。驚くほど大量のコードを、一瞬で出力できます。

しかし。

>・要件が20個並んでいるが、優先順位も依存関係もわからない  
>・クラスの役割が重なっていて、どこに何を追加すべきか迷う  
>・“一望できない構造”のまま、量だけが膨らむ

──これでは、結局人間が“見て判断する”負荷は減りません。

むしろ、認知限界を超えるアウトプットによって、破綻のリスクが増しています。

# AIと人間の“共作”には、構造というルールが必要

では、どうすればいいのでしょうか。

答えはシンプルです。

人が認知しやすい構造を、AIにも守らせる。  
そのための“設計ガイド”を与えるのです。

たとえば：

>・1ファイルあたりの関数数は7つ以内  
>・フォルダ階層は3段まで  
>・if文やswitchは5分岐以内に抑える  

構造が深くなるなら分割する

実際に、CやC++などの分野では、MISRAやAUTOSARといった業界ガイドラインでも  
「構成要素を限定する」ことが推奨されています。

これは単なる“ルール”ではなく、  
**人間が安全に理解・判断するために必要な“認知設計**なのです。

# おわりに──設計とは、“人の目にやさしい構造”をつくること

設計とは、ロジックを書くことではありません。  
**「人間が理解しやすいように、構造を整えること**です。

その観点でいえば、AIが出力するものも同じ。  
「人に見せるコード」「人が読む構造」である以上、  
AIに対しても、**人に優しい構造**を求めるべきなのです。

---
この視点に立つことで、  
私たちはAIと“並んで仕事する”時代にふさわしい設計力を、改めて磨いていけるのではないでしょうか。

そして最後に──  
整った構造の美しさを教えてくれた先人たちに、心から感謝を伝えたいと思います。  
あの時出会った設計とコードがなければ、今の自分の設計観は生まれていませんでした。

---

また、今回紹介した内容をより実践的に学びたい方には、以下のUdemy講座もおすすめです。

 

## Udemyコース（8,800円 → クーポンで割引中）

 

▶️ [AIとC#で極める！クリーンコードの技法（限定クーポン付き）](https://www.udemy.com/course/aic-hjke/?couponCode=C49C4B16FBE249DDFFDA)

 

C#でクリーンコードと設計力を身につける実践講座  

ChatGPTの活用方法や、伝わるコードの考え方を解説

 

## 出版書籍『あきらめない者たち』

 

▶️ [Amazonで見る](あきらめない者たち〜日陰に芽吹く花〜 )

 

技術の基礎からやり直すために、なぜ一歩勇気を振り絞れたのかのノンフィクション作品です。
180度、回転(電光表示板用)(ビット操作


いろいろ注意
----

- arduinoでの予定は、未定


プログラム
----

オンラインコンパイラpaiza




```c++


#define b_put(aa) for(int ii=8;ii!=0;ii--){if(aa & 0x80){printf("#");}else{printf(" ");}aa=aa<<1;}
#define bit8_put(bb) for(int jj=0;jj<8;jj++){b_put(bb[jj]);printf("\n");}

#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    
//8ビットの並び順を逆転させるデータセット(テーブル)
unsigned char rev[] = {
0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
};


    unsigned char font[] = {
        0b00100000,
        0b01111100,
        0b00100000,
        0b01111100,
        0b10101010,
        0b10110010,
        0b01100100,
        0b00000000
    };   

    int c;
    c = font[0];
    font[0] = rev[font[7]];
    font[7] = rev[c];

    c = font[1];
    font[1] = rev[font[6]];
    font[6] = rev[c];

    c = font[2];
    font[2] = rev[font[5]];
    font[5] = rev[c];

    c = font[3];
    font[3] = rev[font[4]];
    font[4] = rev[c];
    
    bit8_put(font);//フォントの表示　注意!!入力は、破壊される

}

```

```

        
  #  ## 
 #  ## #
 # # # #
  ##### 
     #  
  ##### 
     #  


```
Node.jsをWindowsにインストールして簡単なHTTPサーバーを作る方法【初心者向け】

Node.jsの入門学習を始めるにあたり、「Windowsでのインストール方法がわからない」「コマンドが動かない」といった壁にぶつかる方は多いです。本記事では、Node.jsをWindowsにインストールし、簡単なHTTPサーバーを作って動かすまでの手順を、初心者向けに丁寧に解説します。

---

## 1. Node.jsのインストール（Windows編）

### ステップ1：公式サイトへアクセス

以下のURLからNode.jsの公式ページにアクセスします。
[https://nodejs.org/ja](https://nodejs.org/ja)

### ステップ2：インストーラーをダウンロード

LTS（推奨版）を選び、「Windows Installer（.msi）」をクリックしてダウンロードします。
例：`node-v20.x.x-x64.msi`

### ステップ3：インストール

ダウンロードした `.msi` ファイルをダブルクリックして起動。すべてデフォルト設定のまま「Next」 → 「Install」で進めます。
インストールが完了したら「Finish」で閉じてOKです。

---

## 2. Node.jsが正しくインストールされたか確認

### コマンドプロンプトを開く

Windowsキー + R → 「cmd」と入力してEnter。

以下のコマンドを実行：

```sh
node -v
```

バージョン番号（例：`v20.10.0`）が表示されればインストール成功です。

---

## 3. JavaScriptファイル（index.js）を作成

### フォルダを作成

`C:\node-app` など、任意の作業用フォルダを作成します。

### index.jsを作成

以下のコードをコピーして、`index.js` というファイル名で保存します。

```js
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello, Node.js!');
});

server.listen(3000, () => {
  console.log('サーバーが http://localhost:3000 で起動しました');
});
```

---

## 4. サーバーの実行方法

### コマンドプロンプトで移動

作成したフォルダに移動します。

```sh
cd C:\node-app
```

### サーバーを起動

```sh
node index.js
```

以下のメッセージが表示されます：

```
サーバーが http://localhost:3000 で起動しました
```

### ブラウザで確認

Google ChromeやEdgeで以下のURLにアクセス：

```
http://localhost:3000
```

画面に「Hello, Node.js!」と表示されれば成功です。

---

## 補足：PowerShellでも大丈夫？

コマンドプロンプト（cmd）でもPowerShellでもどちらでもOKです。
初心者の方は、動作がわかりやすい **コマンドプロンプト（cmd）推奨**です。

---

## まとめ

* Node.jsのインストールは公式サイトからLTS版の.msiを使えば簡単
* JavaScriptファイル（index.js）は好きなフォルダに保存してOK
* コマンドプロンプトで `cd` 移動 → `node ファイル名` で実行
* ブラウザで `localhost:3000` にアクセスすれば結果が見られる

---

## 参考リンク

* Node.js公式: [https://nodejs.org/ja](https://nodejs.org/ja)
* Visual Studio Code（おすすめエディタ）: [https://code.visualstudio.com/](https://code.visualstudio.com/)

---
Agentforce Knowledge Summary のエラー



+ [Hi I need help Use web search](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWBhx0AH)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/61522d1d-0eee-465e-a71e-84e9a0fef2a2.png)
ChatGPTを使用したアプリ開発記【プロフィール画像の更新機能を実装】

## バックエンドコード
```EditProfile.js

 const handleImageChange = (e) => {

 	//	意味：<input type="file"> の files プロパティから、最初のファイルを取得します。
	//	files[0]：ユーザーが選択した最初のファイル。基本的に単一ファイルアップロードを想定している場合はこれで十分です。
    const file = e.target.files[0];

  	//	意味：ファイルが選択されていれば（＝nullやundefinedでなければ）、以下の処理を実行します。
	//	目的：ユーザーがキャンセルした場合など、ファイルが存在しないケースを避けるための安全チェック。
    if (file) {

    	//	意味：Reactの状態（state）に選択されたファイルを保存します。
	//	目的：後で画像をアップロードする処理などでこのファイルを利用するため。
      setImageFile(file);
    }
  };
　　　　// もし imageFile（選択された画像ファイル）が存在すれば、以下の処理を実行します。
      if (imageFile) {

      // Firebase Storage を使うための初期化を行い、storage インスタンスを取得します。
        const storage = getStorage();

        // userIcons/{userId} というパスにファイルを保存するための参照（Reference）を作成します。
        const imageRef = ref(storage, `userIcons/${userId}`);

        // 選択された画像ファイル（imageFile）を、指定されたストレージ参照（imageRef）にアップロードします。
       // アップロード完了を待ってから次の処理に進むため、await を使っています。
        await uploadBytes(imageRef, imageFile);

      //  アップロードした画像の公開URL（ダウンロードURL）を取得して、updatedPhotoURL に代入します。
      // プロフィールに表示できるように、画像のURLを取得して保存します。
        updatedPhotoURL = await getDownloadURL(imageRef);

        // React の状態（state）に画像のURLを保存します。
        // プロフィールに表示できるように、画像のURLを取得して保存します。
        setPhotoURL(updatedPhotoURL);
      }

// ユーザーのプロフィール情報（名前、メール、自己紹介、アイコンURL）を Firestore に保存・更新します。
      await setDoc(
        doc(db, 'users', userId),
        { name, mail, bio, photoURL: updatedPhotoURL },
        { merge: true }
      );
```
## フロントコード
```EditProfile.js
          <label className="block mb-1">プロフィール画像</label>
          {photoURL && (
            <img src={photoURL} alt="プロフィール画像" className="w-24 h-24 rounded-full mb-2" />
          )}
          <input type="file" accept="image/*" onChange={handleImageChange} />
        </div>
```
## つまずいた箇所

```Firebase.js
const firebaseConfig = {
  // 下記のバケット名が間違っていた。
  storageBucket: "keruma-sns-app.firebasestorage.app",
};
```

## Firestore

![スクリーンショット 2025-05-14 10.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/d1228793-e7ed-4188-ab0f-365ada0e15ad.png)

## UI

![スクリーンショット 2025-05-14 10.58.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/13cad610-850b-4a5e-9c74-b8a7b84aa1b0.png)
【公ド読】API のレート制限の処理

【公式ドキュメントを読もうシリーズ】API のレート制限の処理

## シリーズ概要

[https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3](https://qiita.com/yasu_programming/items/cec66f9e8d5d571e9ce3)

## URL

[https://docs.github.com/ja/copilot/copilot-chat-cookbook/debugging-errors/handling-api-rate-limits](https://docs.github.com/ja/copilot/copilot-chat-cookbook/debugging-errors/handling-api-rate-limits)

## 説明

APIレート制限のロジックの追加の方法が具体的に書かれている。
APIを提供している場合には入れることで、効率的にできるのかもしれない。

## 所感

APIを公開するときにはレート制限以外にも、考える項目あると思うので、こういうのはAIに原案お願いするのも良さそうですね。
競プロ日記#25/05/18

# アルゴ式
[モンティ・ホール問題](https://algo-method.com/tasks/769)
- 昔から有名な条件付確率チックな話題だけど直感的に理解しにくくて...
```
int main() {
	long double ans1 = (long double)2.0 / 3;
    long double ans2 = (long double)1.0 / 3;
    cout << fixed << setprecision(10);
    cout << ans1 << endl << ans2 << endl;

	return 0;
}
```

[席替え](https://algo-method.com/tasks/815)
- ご丁寧に以下のような但し書きが問題にあったので最初は「馬鹿にされているのか？」と思ったが、取り扱っている題材としてはとても面白かった。 
> ランダムな席替えとは、人と座席の組み合わせとしてありうる N! 通りの中から等確率に一つのパターンを選ぶことを指します。

 ```
 int main() {
    cout << 1 << endl;
}
```
今日から始めるNext.js～環境構築編～

## What's Next.js?
Reactがライブラリ、ReactベースのフレームワークがNext.jsです。

#### What's React?
https://qiita.com/tags/react

#### What's フレームワーク?
https://qiita.com/shimajiri/items/cbe403326f0bb18dd638

環境構築をフロントエンド開発初心者視点で解説していきます。

## 環境構築にあたっての前提
VS CodeとNode.jsがインストールされていることです。

#### VS Codeのインストール
https://qiita.com/YurimyMiyu/items/5ce7821f1e3e5905c3ee

#### Node.jsのインストール
https://qiita.com/YurimyMiyu/items/d4fe132fc9bc8189eff4

## 環境構築手順
VSCodeを開き、どこかのディレクトリにフォルダを作成したのち、新しいターミナルを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4088298/f63177d3-4cb8-4023-8564-530284737a2e.png)

プロジェクトを作成したいディレクトリで以下のコマンドを実行
```powershell
npx create-next-app [プロジェクト名]
```

コマンドを実行すると以下の質問をされますので必要に応じて Yes or Noを選択しましょう。

1. Would you like to use TypeScript? 
    TypeScriptはJavaScriptの上位互換の言語
    https://typescriptbook.jp/
2. Would you like to use ESLint?
    ESLintは構文エラーやコーディング規約をチェックしてくれるツール
    https://qiita.com/mzmz__02/items/63f2624e00c02be2f942

3. Would you like to use Tailwind CSS
    Tailwind CSSはCSSのフレームワーク
    https://zenn.dev/yohei_watanabe/books/c0b573713734b9/viewer/275f32
4. Would you like your code inside a `src/` directory?
    ディレクトリにsrcを含めるかどうか
5.  Would you like to use App Router?
    App Routerとはディレクトリ構造がそのままURLにしてくれる機能だそう
    こちらの方の記事がわかりやすかったです
    https://zenn.dev/blueish/articles/4b2ae3781ade57
6. Would you like to use Turbopack for `next dev`?
    TurbopackはモジュールバンドラでTypeScriptやJavaScriptの依存関係を解決してくれるもの
    読み込み時間を爆速にしてくれるそう
    https://zenn.dev/rem/articles/864a6fe32e666c
    インポートエイリアスは別コンポーネントなどを参照する際のパスを相対パスではなくて@をルートディレクトリとして扱ってくれます。
7. What import alias would you like configured?（6の質問をYesにすると聞かれる）
    インポートエイリアスを以外にする場合は変えましょう

上記の質問に答えるとプロジェクトが作成されます。
質問の答えが間違っていた場合はctrl + Cでプロジェクト作成をキャンセルし、再作成しましょう。
※もしほかにいい方法がありましたらご指摘ください

## プロジェクトを立ち上げる

```powershell
cd [プロジェクト名]
npm run dev
```
cd→スペース入力→Tabキー入力でも候補を出してくれます。

プロジェクトが立ち上がれば以下にアクセスしてみてください。
Next.jsの画面が立ち上がれば成功です！
http://localhost:3000

ctrl + Cで終了します。


## 参考文献
[Reactとは?](https://qiita.com/tags/react "https://qiita.com/tags/react")
[非エンジニアに向けてフレームワークについて簡単に説明してみた](https://qiita.com/shimajiri/items/cbe403326f0bb18dd638 "https://qiita.com/shimajiri/items/cbe403326f0bb18dd638")
[Visual Studio Code のインストール方法](https://qiita.com/YurimyMiyu/items/5ce7821f1e3e5905c3ee "https://qiita.com/YurimyMiyu/items/5ce7821f1e3e5905c3ee")
[Node.js のインストール方法](https://qiita.com/YurimyMiyu/items/d4fe132fc9bc8189eff4 "https://qiita.com/YurimyMiyu/items/5ce7821f1e3e5905c3ee")
[サバイバルTypeScript](https://typescriptbook.jp/ "https://typescriptbook.jp/")
[フロントエンドやるなら入れておくべきESlintってなに？](https://qiita.com/mzmz__02/items/63f2624e00c02be2f942 "https://qiita.com/mzmz__02/items/63f2624e00c02be2f942")
[Tailwind CSS とは](https://zenn.dev/yohei_watanabe/books/c0b573713734b9/viewer/275f32 "https://zenn.dev/yohei_watanabe/books/c0b573713734b9/viewer/275f32")
[App Routerの基本的な仕組みとファイル構造](https://zenn.dev/blueish/articles/4b2ae3781ade57 "https://zenn.dev/blueish/articles/4b2ae3781ade57")
[Turbopackとは何なのか調べてみる](https://zenn.dev/rem/articles/864a6fe32e666c "https://zenn.dev/rem/articles/864a6fe32e666c")
【Python初心者】関数定義時の特殊な引数記法まとめ（/, *, *args, **kwargs, デフォルト引数）

Pythonの関数定義には、少し特殊な記法がいくつかあります。  
初めて見たときに戸惑いやすい「`/`」「`*`」「`*args`」「`**kwargs`」「デフォルト引数」などについて、学習中の自分用にまとめてみました。

## 1. `/`（スラッシュ）：位置専用引数

Python 3.8 以降では、関数定義で `/` を使うことで「この引数は**位置指定のみ**で渡してね」という制限をつけることができます。

### 使い方

```python
def func(a, /):
    print(a)
```

この関数は、以下のように**位置でのみ引数を渡す**ことができます。

```python
func(5)       # OK
func(a=5)     # エラーになる（TypeError）
```

### 意味と用途

- ライブラリやAPIの使用者に「この引数はキーワードで指定しないでね」と伝えるときに使います。
- 内部処理の高速化やインターフェースの固定にも使われます。

## 2. `*`（アスタリスク）：キーワード専用引数

関数定義における `*` は、「ここから後ろの引数は**キーワード指定必須**ですよ」という意味になります。

### 使い方

```python
def func(*, b):
    print(b)
```

この関数は、以下のように**キーワード付きでのみ**引数を渡すことができます。

```python
func(b=10)     # OK
func(10)       # エラーになる（TypeError）
```

### 💡補足：`/` と `*` を組み合わせることもできる

たとえば以下のように書くと、aは位置専用、bはどちらでもOK、cはキーワード専用という指定ができます。

```python
def sample(a, /, b, *, c):
    print(a, b, c)

sample(1, 2, c=3)       # OK
sample(a=1, b=2, c=3)   # NG（aは位置専用）
```

## 3. 可変長引数：`*args` と `**kwargs`

引数の数が決まっていないときに、まとめて受け取ることができます。

### 3.1 `*args`：位置引数をまとめて受け取る

```python
def func(*args):
    print(args)

func(1, 2, 3)   # 出力: (1, 2, 3)
```

引数はタプルとして `args` にまとめられます。

### 3.2 `**kwargs`：キーワード引数をまとめて受け取る

```python
def func(**kwargs):
    print(kwargs)

func(a=1, b=2)   # 出力: {'a': 1, 'b': 2}
```

キーワード引数は辞書として `kwargs` に渡されます。

### 🔍 補足：呼び出し側のアンパック記法

このように受け取った `*args` や `**kwargs` は、関数を呼び出す側でも「展開」して渡すことができます。

```python
def func(a, b, c):
    print(a, b, c)

args = (1, 2, 3)
func(*args)  # → func(1, 2, 3)

kwargs = {"a": 1, "b": 2, "c": 3}
func(**kwargs)  # → func(a=1, b=2, c=3)
```

## 4. デフォルト引数

### 4.1 デフォルト引数の基本

Pythonの関数では、引数にあらかじめ値を設定しておくことができます。これを「**デフォルト引数（既定値）**」と呼びます。

```python
def greet(name="World"):
    print(f"Hello, {name}!")

greet()         # Hello, World!
greet("Alice")  # Hello, Alice!
```

このように、引数を渡さなかった場合はデフォルト値が使われ、渡した場合はその値で上書きされます。

複数の引数がある場合は、**デフォルト引数は必ず後ろに書く必要**があります。

```python
def add(a, b=10):
    return a + b
```

```python
def add(a=10, b):  # ❌ エラー：デフォルト引数は後ろにまとめる必要がある
    ...
```

---

### 4.2 注意：ミュータブルなデフォルト引数は共有される

リストや辞書など、変更可能なオブジェクト（ミュータブルなオブジェクト）をデフォルト引数に使うと、**関数定義時に1度だけ生成されて、それがずっと使い回されてしまう**という仕様があります。

#### 問題のある例

```python
def append_item(item, lst=[]):
    lst.append(item)
    return lst

print(append_item(1))  # [1]
print(append_item(2))  # [1, 2] ← 2回目でも同じリストが使われてしまう！
```

#### 安全な書き方（定型パターン）

```python
def append_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

print(append_item(1))  # [1]
print(append_item(2))  # [2]
```

`None` を使うことで、関数が呼ばれるたびに**新しいリスト**を生成するようにできます。Pythonではこの書き方が“お作法”として広く使われています。

#### 💡 補足

- `list`, `dict`, `set` などの **ミュータブル型**は共有されるため注意
- `int`, `str`, `tuple` などの **イミュータブル型**なら問題なし

## おわりに

今回は関数定義時の少し特殊な記法について、自分なりに整理してまとめました。  
特に `/` や `*` は初めて見ると意味が分かりにくいので、実際に動かして試してみると理解が進みました。

今後、関数を定義するときやライブラリの関数定義を読むときに活かせるようにしていきたいです。
人の認証に関する基本の整理

証券の不正取引で気になったので、時事ネタ追いかけるついでにお勉強。
参考文献：「情報処理安全確保支援士教科書 令和6年度」瀬戸美月／齋藤健一

## 認証とは

人や物の正当性を確認すること。

二者間認証と三者間認証がある。

※認証が成功したユーザに対して、どのようなアクセス権を与えるか判断するのは「認可」という。

## 本人認証
一般的な「人の認証」のこと。パスワードログインなどが含まれる。

## 認証の3要素
<dl>
<dt>記憶要素</dt> <dd>ある情報を持っていることによる認証。パスワードなど。</dd>
<dt>所持要素</dt> <dd>ある物を持っていることによる認証。ICカード認証、スマホSMS、秘密鍵など。</dd>
<dt>生体要素</dt> <dd>身体的特徴による認証。いわゆる生体認証。顔認証、指紋認証など。</dd>
</dt>

※ この「認証」については、おそらくコンピュータを離れた現実でも通じると思っている。「合言葉で入場」「観覧チケットの確認」「免許証の顔写真の確認」など。

また、一般には言われている(と思う)こととして、
* 記憶要素の場合、一般には「本人しか知らない情報」を使う。誕生日や語呂合わせのパスワードは、他人から推測しやすいため避けたほうが良い
* 「通っていた学校」「ペットの名前」の秘密の質問も、他人が知ることが出来るため、認証として良くないとされる


## MFA(多要素認証)、または2要素認証
Multi Factor Authentication = 多要素認証。 2要素認証は多要素認証に含まれる。
上であげた認証の3要素のうち、2種類(以上)を使ってログインすること。

例)
* パスワード(知識)＋認証アプリ(所持)
* パスワード(知識)＋顔認証(生体)
* ICカード(所持)＋指紋認証(生体)

## 2段階認証

2段階認証≠多要素認証。
「1段目の認証→2段目の認証、の順で認証を行うこと」「2回認証があること」ぐらいのことを指す。「認証の3要素」を何種類使うかについては言及していない呼称。

※ 最近読んだ文章を総合すると、少なくとも一般の語法ではどこまでを「2段階認証」と言うのかは幅がある印象。また、現在の実装は9割がた「2要素認証＝2段階認証」のため、内容は2要素認証でも、口頭では「2段階認証」と呼んでいる例もある。

「2要素認証ではない2段階認証」の例としては

* __パスワード__ でログインすると、Webメールにワンタイムパスワードが送られる
* メールに __パスワードで__ ログインし、ワンタイムパスワードを取得する

が挙げられる。2回パスワードを使う分、1段階認証よりは強くなるが、2要素認証の条件は満たさない。


ただ、たとえばGoogleの2段階認証では

* パスワードでログインする。(記憶要素の認証：本人はパスワードを知っている)
* スマホに通知が来るので「はい」を押す。(所持要素の認証：本人は本人のスマホを持っている。)

となっている。これは2要素認証になっているが、名称は「2段階認証」となっている。
おそらく「2段階認証」の言葉ほうが、早くから使われ始めたので、こういった呼称になっているだと思う。

参考文献では「認証は1段階でも2段階でも構わない」「理想は"1段階・2要素認証"」と書いている。

## Bot避け (人間か機械か)

CAPTHCAも「認証」と呼ばれるが、主には「人かBotか」を判断するために使う。
言葉にするなら「あなたは誰かとしてログインしようとしていますが、生身の人間がPCの前にいます？」ぐらいのところ。
主要なBot避けには個人の区別をする機能はなく、パスワード入力と一緒に使われることが多い。
Botやスパム対策として、サイバーセキュリティには効果がある。

## たぶんこういうこと

* 銀行ATM：キャッシュカード(所持要素)と暗証番号(知識要素)の __多要素認証__
* 顔パス：一種の生体認証
* パスワードログイン＋SMSワンタイムパスワード：知識要素と所持要素の __多要素認証__
* 「ワンタイムパスワードをWebメールに送り、アプリで読む」場合：__多要素認証ではない__ 
  *  スマホ以外の環境からでもメールが読めてしまうので「所持要素の認証」の条件を満たさない
  *  ただし「ワンタイムパスワード」が悪意ある人に入手されしくいという点で、セキュリティ強化の効果はある
* 「住所氏名と生年月日を教えてください」の確認は認証か
  * 住所と生年月日は公に公開されていない、かつあてずっぽうも困難なので、知識要素の認証と言える
  * ただし、住所も生年月日も、本人以外に知っている人はいるため、「本人しか知らない情報」とは言い難い
  * 「本人確認」くらいの強さだと思われる

と、理解してます。

## 最近気になること
「2要素でない2段階認証を『2要素認証』と言っちゃってないか？」という点です。

正直、去年まで自分も深く気にしていなかった。上記のような知識を身に着けてから、ニュースやSNSの発言が気になり始めました。

サイバー攻撃に対して本格的に対策が始まりそうな現在、「セキュリティ強化しましょう」というとき、きちんと2要素認証にしたいのか、あるいは単にワンタイムパスワードの導入だけでいいのか、あるいはBot避けがしたいのか、違いを理解して考える必要があると思いました。

おしまい。
GeminiとCopilotでコンピュータを使う魔法少女を描いてみた。

# 概要

GeminiとCopilotでコンピュータを使う魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
光のコンピュータを使う魔法少女を描いてください。
```

![光のコンピュータを使う魔法少女_20250519.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f629ce07-1405-4432-8d84-246f1eaa4b16.png)




```
闇のコンピュータを使う魔法少女を描いてください。
```

![闇のコンピュータを使う魔法少女_20250519.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f19ed11c-07ba-478d-b2fb-e30ac97887ab.png)




```
聖なるコンピュータを使う魔法少女を描いてください。
```
![聖なるコンピュータを使う魔法少女（Copilot）_20250519.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/3e76fa0a-0e4f-4b0e-96c8-43e379d845f0.png)


# まとめ

光の子が可愛いかも。
何かの役に立てばと。
IPA資格は役に立たない。その①「双方向リスト」

双方向リストとは、端的に言えば「前後の要素を参照できる」データ構造のことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287660/66935cdf-f328-433d-ad5a-9a6d06e51d1f.png)
引用：[双方向連結リスト](https://ufcpp.net/study/algorithm/col_blist.html)

これを学んだからと言って何になるのでしょうか。
試験対策で学習しても、現場で使えなければただのゴミです。
Webページを作り、APIを設計し、DBからデータを取得しても、だいたい使うのは配列なのだから、配列でいいでしょう。

たとえばnginxのファイルキャッシュ

https://github.com/nginx/nginx/blob/master/src/http/ngx_http_file_cache.c

にはそのデータ構造に双方向リストが使用されていますが、

https://github.com/nginx/nginx/blob/master/src/core/ngx_queue.h

nginxなんてプログラミングしてるだけなら使わないし、nginxの開発者でもなければ、nginxみたいなミドルウェアを開発する予定もないから知っておかなくてもいいでしょう。

他にも、Linuxのメモリ管理で双方向リストが使われていますが、

https://www.coins.tsukuba.ac.jp/~yas/coins/os2-2020/2021-01-13/

別にLinuxの内部構造を知ったからって業務が捗るわけでもないし、ましてやOS開発をしているわけでもないので、やっぱり現場で役に立つ問題を出さないIPA資格なんて意味ないでしょう。
Designing a Platform to Share Sensory Triggers in Public Spaces・Year 1

In my first year, I aimed to design a platform to share sensory triggers in public spaces. Sensory sensitivity is a characteristic that often appears as part of developmental disorders, and research shows that around 80% of individuals with developmental disorders feel they have some form of sensory sensitivity. Additionally, Highly Sensitive Persons (HSPs) are estimated to make up about 15–20% of the population. This condition is more common than people might think, and I created this platform with the hope that those affected can find more peaceful routes and environments in their daily lives.

![スクリーンショット 2025-05-19 3.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817279/4f7cb58f-e7c5-4e89-a85b-58149edb3e7c.png)


![スクリーンショット 2025-05-19 2.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817279/f49b00a9-492b-41e5-a75d-36c512225b15.png)
Zetaプロジェクト - LLMを自作する道のり

(Zennで反響が良かったのでこっちにも投稿しました: [元記事はこちら](https://zenn.dev/techcat56/articles/3b2cd6035b9902))

*2021年、OpenAIが非営利団体として立ち上げられ、GPTを公開した。*
*GPT-2までは現在も公開されている。*
*GPT-3.5のあたりから、ChatGPTについて話題になり、ちょうどその時にOpenAIアカウントを作った。*
*夢のような体験をした。*
*その後、GPTの仕組みを応用し、さまざまな企業が会話型のLLMを作り始めた。*
*その後、あることに気付いた。*
***誰でも作れるのではないか？** と。*

## はじめに
この記事は、実際にLLMを作った後の、落ち着いてから書いたまとめ的なものです。
もちろんただの素人プログラマーの記事なので、期待しすぎない程度に読んでください。

## 1. 始まり
まず考えたのは、膨大なデータを無料で提供している場所について。
Wikipediaのデータ量について考え、情報源を探し、**Wikipediaが全データを公開している**ということがわかった。
ライセンスについては置いておき、自分で使うだけの用途のためとして、作業を始めた。
そして、やはりプログラミングの力が必要になった。
しかし、プログラミングが得意な友人なんているわけがなく、ChatGPT(ただしgpt-3.5-turbo)にお願いした。
出てきたコードはもう保管しておらず、確認はできないのだが、TransformerやTensorFlowすら使わないという意味不明なコードだった。
もちろん、疑うこともできず、普通に実行。
結局、実行している間にあることに気がついてしまった。
**Wikipediaって、会話じゃなくてただの知識データじゃん**
そう、元々作ろうと思っていたのは**会話型**のLLM。
一方で、Wikipediaは、人間が知識を増やすために特化したようなサイト。
全く合わないのである。
そして、めんどくさくなった自分は、プロセスを止め、その後結局全然手をつけなかった。

## 2. 転換点
Pythonが意外と上達してきた時、やはり何かに気がつく。
**前にやってたの、全く機械学習じゃねぇじゃん**
Wikipedia以前の問題だと気がついた。
その時は死にたくなっていた。
GPTについて調べたところ、**Generative Pre-trained Transformer**と出てきた。
そう、Transformerについて調べるときが来た。

## 3. 初めの一歩 Azuki.ai
早速調べ、Pythonにtransformersというライブラリがあることを知った。
ちょうどPythonが上達してきたので、すごく良かった。
そして、HuggingFaceのドキュメントのごく一部を見て、なんとか作成したLLM。
Azuki.ai 1ができた。
名前は、**近くにたまたま、おしるこがあったから**という、とてもどうでもいい名前だった。
結局、Azuki.aiの作成を続けていた。
もちろん、データセットを手作業で作るのもあり、特にその時は疲れすぎていた時期なので、LLMの回答は全ておかしいものだった。

## 4. HINODE AI
もう一度作ろうと思えたのは、もうGemma 2が出てきた頃。
さらに良くするために、新しいステップに切り替えたことを名前に反映するため「HINODE AI」とした。
もちろん、モチベーションを上げるためにすぎないが。
そうして、HINODE AIを作成した。
やはり応答はおかしいものの、少しまともになってきた感じだった。
結局、また忘れ去られた。

## 5. Zeta 1
さて、*ここまで来ると、もっとまともなものを作りたくなる。*
**もちろん**Azuki.aiの頃からそのつもりだったが、より張り切っているのだ。
そうして、Zeta 1を作成しようとした。
データセットの質などを考慮しないとして、いろんな人に使ってもらいたい。
結局、英語がいいと判断した。
当時はやはり英語力はないし、今もあまりない。
*Google翻訳に感謝しながら作成した。*
(一部、別の言語も混ぜておいた)
**我らが人間のためのWikipediaを、人間が間に入り、データセットを作る**という謎状態で進んでいった。
そうして、意外といい回答をできるようになった、Zeta 1ができた。
(なんと**2025年4月の最後らへん**。とても最近。)
...疲れた。

## 6. 親切な人のチーム
多くのLLMは、より速く動かせるように、量子化やGGUFへの変換を、親切な人がやってくれている。
なぜこの話をしているのかというと、**Zeta 1を見つけて、さらに量子化とGGUFへの変換をしてくれた**人が現れたのだ。
Zeta 1のモデルページのツリーを見て、二度見したのはもちろん、当たり前だが感謝した。
感謝しすぎているため、その人のリンクをここに貼っておこうと思う
(ちなみに、誰でも無料でLLMの変換を依頼できるらしい)

https://huggingface.co/mradermacher

## 7. Zetaのその後

![](https://storage.googleapis.com/zenn-user-upload/c88b0642dd4f-20250517.png)

頑張りすぎて、**Zeta 2を5月12日あたり**、**Zeta 3は16日**という、意味不明なスピードになっていた。
今は疲れて休んでいる。とても褒めて欲しい。
というかこの画像も自作...

## おわりに
**真似するな、体が壊れるぞ**
(実際、パソコンの前にいることが当たり前になり、足が筋肉痛になるのは当たり前、家で歩くのすらしんどいです。)

スクリプトとかをGitHubに公開してるので、体が壊れるのを覚悟で使ってください。
ちなみにZeta 2以降はmradermacherさんに変換の依頼してます。

[スクリプト in GitHub](https://github.com/Zeta-LLM/Zeta-Tool)
[HuggingFace上のZeta 3](https://huggingface.co/Zeta-LLM/Zeta-3)
[みんな大好きOllama...のZeta 3](https://ollama.com/DiamondGotCat/Zeta-3)

また別の記事で！Bye!
プリザンターを1.4.6.1から1.4.16.1へバージョンアップする

# はじめに
前回の[投稿](https://qiita.com/maki_s/items/c7a241afaf93239f9732)からかなりバージョンアップができてなかったので、違い等があるのか検証してみました。

結論で言うと、特に問題なくアップデートができました。

## アップデート環境

OS：windows 11 pro
DB：SQL Server 2019
プリザンター：1.4.6.1

:::note info
**アップデートするプリザンターについて**
プリザンターはRDS.jsonしか変更していません。
つまり、データベース接続の設定のみで、メール設定等は行っていない状態です。
:::

:::note info
**プリザンターのインストール場所**
今回はプリザンターのチュートリアルと同じ場所にプリザンターを格納しています。

```
C:\web\pleasanter
```
:::

# 【補足】アップデートについて

下記に詳細な手順が掲載されています。
バージョンが大きく異なる場合は一読した方が良いとおもいます。

https://pleasanter.org/manual/version-up-net

# アップデート手順
今回行った1.4.6.1から1.4.16.1へアップデートする手順となります。

### １．RDS.jsonのバックアップ

RDS.jsonをバックアップします。

```
C:\web\pleasanter\Implem.Pleasanter\App_Data\Parameters\Rds.json
```

### ２．既存のプリザンターを退避する
「インターネット インフォメーション サービス（IIS）マネージャー」からプリザンターを停止し、別領域へ退避させます。

:::note info
**公式見解**
公式は **念の為、既存のC:\web\pleasanter\をC:\web\pleasanter_bk\などとリネームしてバックアップしたうえで、新バージョンを配置することを推奨します。** とあるので、バックアップを推奨します。
:::

### ３．プリザンターのコピー
プリザンター（1.4.16.1）をコピーします。

```
C:\web\pleasanter
```

### ４．CodeDefinerの実行
インストール手順では変更されていますが、本家のバージョンアップ資料はコマンドが古いので、新しいコマンドで実行します。

```bat
cd C:\web\pleasanter\Implem.CodeDefiner
dotnet Implem.CodeDefiner.dll _rds /l "ja" /z "Tokyo Standard Time"
```

CodeDefiner実行時、Community Editionでの利用か確認するメッセージが追加されていました。

```terminal
<INFO> Configurator.OutputLicenseInfo: This edition is "Community Edition".
Type "y" (yes) if the license is correct, otherwise type "n" (no).
```

### ５．プリザンターの起動確認
「インターネット インフォメーション サービス（IIS）マネージャー」からプリザンターを起動します。
無事プリザンターが起動できているかと思います。


# 参考

* [releases](https://github.com/Implem/Implem.Pleasanter/releases)
* [プリザンターをWindowsにインストールする](https://pleasanter.org/manual/getting-started-pleasanter-windows)
constを使うと何が変わる？Flutterパフォーマンスの基本

こんにちは、株式会社ダイアログでFlutterエンジニア2年目のエンジニアです。

Flutterで開発を始めたばかりの頃、`const`って正直「なんか付けとけばいいや」くらいの感覚で使っていませんでしたか？

この記事では、

- **Flutterの`const`が何をしているのか？**
- **なぜ使うことでパフォーマンスが上がるのか？**

をわかりやすく解説します。

---

## ✅ 結論! ：constは「インスタンスを再利用する」ための宣言

Flutterの`const`は、**同じ構造のWidgetを再利用できるようにする**ための仕組みです。

```dart
const Text('Hello');
```
このように書くと、「これはコンパイル時に定数として確定するから、再利用できる」とFlutterは認識します。

※コンパイル時定数：プログラムのコンパイル時にすでに値が決まっているconst修飾子がついた定数。
※実行時定数：プログラムの実行中に決まるfinal修飾子がついた定数。


## 💡 constを使うことで得られる2つのメリット

### 1. Widgetの再生成を防ぐ

以下のコードを見てください：

```dart
// constあり
body: const Text('Hello');

// constなし
body: Text('Hello');
```

constがない場合、`build()`メソッドが呼ばれるたびに `Text('Hello')` のインスタンスが毎回新しく生成されます。
これはパフォーマンスに悪影響を及ぼします。

一方、`const`を使うとFlutterは：

> 「このウィジェット、前にも全く同じのがあったから再利用していいね！」

と判断し、無駄な再生成を防ぐことができます。

---

## 2. Elementの再利用がしやすくなる

FlutterのUIは、以下の3層のオブジェクトで構成されています：

- **Widget**（設計図）
- **Element**（ウィジェットのインスタンス）
- **RenderObject**（実際に画面上に描画されるオブジェクト）

FlutterはWidgetの構造を比較し、「変更があったかどうか」を判断します。  
`const`ウィジェットは **「絶対に変更されない」** ことが保証されているため、Flutterはそれを再利用できます。

その結果：

- ✅ **Elementの差分判定(再描画するか否か）が高速に**
- ✅ **不要な再構築を防止**
- ✅ **スクロールやアニメーション中のパフォーマンスも向上**

というメリットにつながります。

## 🔎 buildが何度も呼ばれる理由とconstの関係

Flutterでは、`setState()` や `Provider` などの変更通知によって、`build()` が何度も呼ばれます。

しかし、毎回 Widget を新しく作っていたら **パフォーマンスが落ちてしまいます**。  
そのため、`const` で再利用可能な Widget を定義しておくことが重要です。

---

### 例：`const` がないと…

```dart
Widget build(BuildContext context) {
  return Column(
    children: [
      Text('Hello'), // 毎回新しいインスタンス
    ],
  );
}
```

### 例：`const` があると…

```dart
Widget build(BuildContext context) {
  return Column(
    children: const [
      Text('Hello'), // インスタンスの再利用が可能
    ],
  );
}
```

## ⚠️ 注意：constは万能ではない

`const` は便利ですが、**すべてのケースで使えるわけではありません**。

- **動的に変わる値** を使いたいときは `const` にできません。
- 状態を持つウィジェット（`StatefulWidget`）で **変更される内部のデータ** がある場合も、`const` の使用は制限されます。

---

## 🔚 まとめ

- `const` を使うと、**Widgetの再生成を防ぎ、Elementの再利用が可能**になる  
- **Flutterアプリのパフォーマンス向上**に直結する  
- **意図を明示**でき、コードの**可読性・保守性**もアップ  

👉 使えるところには **積極的に `const` を使っていこう！**
パーソナルブログコンポーネント - ターミナル風自己紹介ページ、フルイドホームページ、ギャラリー

ナビゲーション用のクリエイティブなホームページ、インタラクティブな自己紹介ページ、そしてダイナミックなフォトギャラリーを含む、3つのオープンソースプロジェクトを共有させていただきます。

# [オープンソース] TermFolio - ターミナル風個人情報表示コンポーネント
[https://github.com/SimonAKing/TermFolio](https://github.com/SimonAKing/TermFolio)

TermFolioは、開発者向けに設計された、個人情報、プロジェクト経験、技術スキルを紹介するためのターミナル風コンポーネントです。主な特徴：

本物のターミナル体験：
- `ls`、`cd`、`pwd`などの一般的なコマンドをサポート
- Tabキーによるスマートなコマンド補完
- 矢印キーでコマンド履歴をナビゲート
- 高度にカスタマイズ可能：コマンド、プロンプト、表示内容をカスタマイズ可能

技術ブログの自己紹介ページや開発者のオンラインレジュメに最適です。

[デモサイト](https://simonaking.com/about/)

# [オープンソース] ブログホームページテンプレート：WebGLフルイドアニメーション + インタラクティブなゲーム風背景
[https://github.com/SimonAKing/HomePage](https://github.com/SimonAKing/HomePage)

フルイドアニメーション背景とスムーズなページ遷移を特徴とする、エレガントで使いやすいパーソナルホームページテンプレートです。開発者、デザイナー、クリエイティブな専門家が素早く個人のショーケースウェブサイトを構築するのに最適です。設定ファイルを変更するだけで、完全にパーソナライズすることができます。

[デモサイト](http://simonaking.com)

# [オープンソース] エレガントなフォトギャラリーテンプレート：画像プレビューと圧縮機能搭載
プロジェクトリポジトリ：
[https://github.com/SimonAKing/AnimatedGallery](https://github.com/SimonAKing/AnimatedGallery)

プロジェクト説明：
このオープンソースフォトギャラリープロジェクトは、メイソンリーレイアウトを使用して画像を表示し、モバイルとデスクトップの両方に完璧に対応するレスポンシブデザインを特徴としています。
BlurHashを実装して優雅な画像読み込みを実現し、遅延読み込み戦略と組み合わせてパフォーマンスを向上させています。Sharpを使用して画像圧縮を行い、読み込み速度と表示品質のバランスを自動的に調整します。
すぐに使用可能で、指定されたディレクトリに写真を配置するだけでギャラリーを更新できます。

[デモサイト](http://simonaking.com/gallery)
【Rails】application.rbについて

# 記事概要
Ruby on Railsの設定ファイルについて、まとめる

# 前提
- Ruby on Railsでアプリケーションを作成している

# 基本情報
## ファイルパス
config/application.rb

# まとめ
## コントローラー生成時に不要なファイルを生成しない
`rails g`コマンドでコントローラーを作成すると、自動で関連ファイルが作成されるが、ファイルを自動生成しないように設定する

```application.rb
config.generators do |g|
  # 生成したファイルに対応したスタイルシートを生成しない
  g.stylesheets false
  # 生成したファイルに対応したJavaScriptファイルを生成しない
  g.javascripts false
  # 生成したファイルに対応したヘルパーを生成しない
  g.helper false
  # アプリケーションをテストするためのファイルを生成しない
  g.test_framework false
end
```

## デフォルトの言語設定
`config.i18n.default_locale = :ja`を追記することで、デフォルトの言語を日本語に変更できる
※`devise`のエラーメッセージも日本語化するよう求められる

```application.rb
module アプリ名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.1
    
    # アプリのデフォルトの言語設定を日本語に変更
    config.i18n.default_locale = :ja
    # 省略
  end
end
```

## デフォルトのタイムゾーン設定
`config.time_zone = 'Tokyo'`を追記することで、東京のタイムゾーンに変更できる

```application.rb
module アプリ名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.1
    
    # アプリのデフォルトのタイムゾーン設定を東京に変更
    config.time_zone = 'Tokyo'
    # 省略
  end
end
```

# コントローラー
https://qiita.com/likapantrip/items/66a30e887ffe20ad08a4
Dockerコマンドメモ


## 基本コマンド

```sh
# イメージ取得
docker pull nginx:1.21.4-alpine
docker pull php:8.1.0-fpm-alpine3.15
docker pull mysql:5.7

# 初回コンテナ立ち上げ
docker run -d --name nginx -p 80:80 nginx:1.21.4-alpine
docker run -d --name php-fpm php:8.1.0-fpm-alpine
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=root mysql:5.7

# コンテナ状態確認
docker ps -a

# コンテナに入る
docker exec -it nginx sh

# コンテナ停止
docker stop nginx

# コンテナ起動
docker start nginx

# コンテナ削除
docker rm nginx
```

## イメージ作成〜Pushまで

今回はPython＆node環境を作成

```sh
# ①ベースにしたいイメージからコンテナ起動
docker run --rm -it ubuntu:24.04 sh

# ②コンテナ内で必要なモジュールを確認＆インストール
sh# apt update
sh# apt install -y curl git

# ③ある程度見通しが立ったらそれを元にDockerfile作成
vi Dockerfile

# Dockerfileをビルドしてイメージ作成。エラーになったらベースイメージから確認して①〜③の繰り返し
docker build --no-cache -t npy:v1 -f Dockerfile .
docker run --rm -it npy:v1 sh
# ローカルのファイルや環境変数を使用する場合
docker run --rm -it -v ./requirements.txt:/app/requirements.txt -v ./scripts:/app/scripts --env-file=.env npy:v1 sh

# 今回はGitHub Container registryにイメージをPush
# https://docs.github.com/ja/packages/working-with-a-github-packages-registry/working-with-the-container-registry#personal-access-token-classic
export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u xxxxx --password-stdin

# イメージをPush
docker build -t ghcr.io/NAMESPACE/npy:v1 -f Dockerfile .
docker push ghcr.io/NAMESPACE/npy:v1

# 手元のイメージ削除
docker rmi npy:v1
docker rmi ghcr.io/NAMESPACE/npy:v1

# PushしたイメージをPullして動作確認
docker run --rm -it ghcr.io/NAMESPACE/npy:v1 sh
```

今回作ったDockerfile

```Dockerfile
FROM ubuntu:24.04

ARG PYTHON_VERSION=3.12.10
ARG NODE_VERSION=22.2.0

# https://github.com/astral-sh/uv/pkgs/container/uv
COPY --from=ghcr.io/astral-sh/uv:0.7.5 /uv /uvx /bin/

WORKDIR /app

RUN apt update
RUN apt install -y curl git make

# pythonバージョン管理 uv
# https://docs.astral.sh/uv/
RUN uv venv --python $PYTHON_VERSION
ENV PATH="/app/.venv/bin:$PATH"

# nodeバージョン管理 n
# https://github.com/tj/n
RUN curl -L https://bit.ly/n-install | bash -s -- -y $NODE_VERSION
ENV PATH="/root/n/bin:$PATH"
```

サクッと動作確認したかったのでメモ
【VSCode】ER図の作成

# 記事概要
VSCodeでER図を作成する方法について、まとめる。

# 前提
- VSCodeはインストール済みである
- 拡張機能「Draw.io Integration」をインストール済みである

# 手順(ER図作成)
1. アプリケーションを開く
1. 拡張子`.dio`で、新規ファイルを作成する
    ※拡張子を`.drawio.png`にすると、ファイル出力せずに画像が作成される
1. 画面左下の「＋その他の図形...」をクリック
1. 「ER」にチェックを入れて適用をクリックすると、ER図作成に適した図形を扱える
    ※新たにテーブルを追加したい場合には、「ER」から使用するテーブルの図形をドラッグ＆ドロップで設置
    ※同様の方法で、カラムも追加できる
    [![Image from Gyazo](https://i.gyazo.com/7e20401935793732500f7f440179c66e.png)](https://gyazo.com/7e20401935793732500f7f440179c66e)

# 手順(ファイル出力)
1. 左上の「File」をクリック
1. 「Export」を選択
1. 「.png」を選択
1. 保存場所を選択し、右下の「保存」をクリック

# 手順(README添付)
1. READMEに下記を記述する
    ```readme.md
    ![](ファイル名)
    ```

# 備考
- VSCodeのインストールは、[こちらの記事](https://qiita.com/likapantrip/items/16cce74e3160a2acf560)を参照する
ヘッダーとメインから見る、セマンティクスとデザインの両立について

模写コーディングの過程で、「ヘッダーとメインコンテンツの背景を同じ色（または画像）でつなげたい」という場面に出くわしました。

いざ実装しようとすると、HTMLのセマンティクス（意味）とデザインの見た目上の要請が衝突し、どのように書くのが正解か迷うことがありました。

この記事では、その疑問を整理しながら、HTML5 の基本ルールを守りつつ、見た目も破綻しない実装パターンを3つ紹介します。


## やりたいこと

- **ヘッダー（ロゴ・ナビ）と Hero エリア** を 1 つの大きな背景にまとめたい  
- Hero エリアの後ろからは通常の白背景で記事が続く



## よくないやり方

```html
<header class="hero-area">…</header>
<div class="timer hero-area">…</div>
```

| 問題点 | なぜ問題か |
|-------|-----------|
| **構造と役割の混乱** | 意味の異なる要素に同じクラスを付けると「このクラスは何を示すのか？」が判別しづらく、HTML を読むだけで構造が把握しにくい |
| **スタイルの分散** | 背景色や余白などのスタイルが複数タグに広がり、一箇所で調整できず副作用が出やすい |
| **再利用しづらい** | `.hero-area` が特定画面に強く依存し、別画面で流用しようとするとレイアウト崩れなどのトラブルになりやすい |

## よりよい 3 つのパターン

### パターン A — `<main>` を外に出し、Hero を `<section>` として内包（**推奨**）

```html
<header class="site-header">…ナビ…</header>

<main>
  <section class="hero-area">
    <!-- Hero コンテンツ -->
  </section>

  <section class="content">
    …記事本文…
  </section>
</main>
```

**ポイント**

- `<main>` は **1 ページに 1 つ** の原則を順守  
- Hero と本文を **兄弟 `<section>`** として並べ、構造が明快  
- ヘッダーの背景は透過させるか、Hero 上端まで背景を延ばす

---

### パターン B — ラッパーで `<header> + <main>` を包む

```html
<div class="hero-area">
  <header class="site-header">…ナビ…</header>
  <main>
    <!-- Hero コンテンツ -->
  </main>
</div>

<section class="content">
  …記事本文…
</section>
```

- Hero 用 `<main>` しか存在しない ⇒ **後続コンテンツは `<section>` 等で構造化**  
- セマンティクス的には **ややグレー** だが、コードが最小で中央寄せが楽

---

### パターン C — `.hero-area` を 2 つ配置してヘッダーと Hero を分割

```html
<div class="hero-area">
  <header class="site-header">…ナビ…</header>
</div>

<main>
  <div class="hero-area">
    <!-- Hero コンテンツ -->
  </div>

  <section class="content">
    …記事本文…
  </section>
</main>
```

**メリット**

- `<header>` はページ先頭、`<main>` は 1 つ、セマンティクスは問題ない 
- `.hero-area` クラスは **1 か所に定義** すれば OK

**デメリット**

- HTML だけ見た人には **Hero が 2 つある** 構造に見える  
- 2 つの `.hero-area` が ピタッと重ならないと隙間 が出るおそれ  
- 高さ調整を誤ると背景が切れる


## 比較
| 案 | セマンティクス |  実装難度 | 採用場面 |
|----|----------------|----------|----------|
| **A** | ◎ 正しい |  ○ 普通 | 基本形 |
| **B** | △ ややズレ |  ◎ 最短 | スピード重視 |
| **C** | ◎ 正しい |  △ 手間 | LP など |


## まとめ

- **パターン A** を選べば間違いなし
- **パターン B** はプロトタイプや小規模サイトで有効  
- **パターン C** はヘッダーを独立制御したい LP 向け  
- どの案でもクラス名とコメントで意図を明示するとチーム全体で迷わない


## 感想

模写コーディングを通して、HTMLには意味としての正しさと見た目としての美しさの両立が求められることを実感しました。

見た目が整っていればいいように感じてしまいがちですが、構造を意識して記述することで、後々の保守や拡張が格段に楽になると感じました。
Pull Requestのマージ方法にはいくつか種類があるんだぜ

GitHub を用いたチーム開発をしている時、Pull Requestを取り込む方法はいくつかあります。
それは、「`Create a merge commit`」「`Squash and merge`」「`Rebase and merge`」の3方式です。
以下のようにPull Requestをマージするボタンの三角ボタンを押すと出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3026821/7b3af553-1925-4dd1-bde5-25421d8029a0.png)

ここに、上記で書いた、3種類のマージ方法があります。
今回の記事ではどのような使い分けをすればいいのかを書いていこうと思います。

## なぜマージ方法が複数あるのか
GitHub は分散型バージョン管理システム「Git」を使用したアプリケーションのため、Git の設計思想が多く取り込まれています。そのため、以下のような利点があります。
第一に、**誰が、いつ、どのような変更を行ったかを詳細に記録できる**こと。第二に**過去の変更履歴を参照することで、バグの原因を特定しやすくなる**こと。第三に**履歴を通じて、プロジェクトの設計意図や議論の経緯を新しいメンバーと共有できる**こと。

これらのことから、履歴は単なる記録ではなく、プロジェクトの知的資産として機能します。それらをチーム規模や開発方針によってうまく運用・適応させるため、複数のマージ方法が存在します。

## 実際の使い分け
### `Create a merge commit`

デフォルトで設定されている `Create a merge commit` ですが、これは、**複数のブランチを統合する際に、新たなマージコミットを作成**します。図に表すと以下の通り。feature ブランチは、新しい差分を作成するために作ったブランチ名だと捉えてください。

![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3026821/c4e689fb-c659-4e16-9006-ad98f074bc4c.png)

流れとしては、
1. main が存在する
1. feature ブランチに分岐、新しい差分を追加
1. main に対してPull Request（PR）として作成
1. マージ（マージコミットFが作成される）

Fのコミットは、DとEの差分が含まれており、マージコミットと呼ばれます。これは「マージされたよ」というコミットです。どこのブランチからマージされたかという情報を含んでいます。マージコミットを作成するので、「`Create a merge commit`」という方法なのです。

この方法は、誰が、いつ、どのような変更を行ったかを明確にするために有効です。そして、**main ブランチ と feature ブランチは親子関係が残ります**。しかし、マージコミットが増えることで、履歴が複雑になりがちです。

これを利用するケースとしては、「複数のブランチが頻繁にやり取りされる大規模なプロジェクト」や、「機能ごとのマージ履歴を明確に残したい場合」、「履歴を「どのブランチから取り込んだか」ベースで把握したい場合」に適していています。

### `Squash and merge`

続いて`Squash and merge`についてです。これは、**複数のコミットを1つにまとめてからマージ**します。
図で表すと以下の通り。

![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3026821/6637b2a0-b050-41ae-a4eb-35653c86d149.png)


流れとしては、
1. main が存在する
1. feature ブランチに分岐、新しい差分を追加（ここまでは同じ）
1. main に対してPull Request（PR）として作成
1. 新しいコミットが main ブランチに作成される

この新しいコミットは、先ほどのマージコミットとは違い、**main ブランチ と feature ブランチは直接の親子関係を持ちません**。そのため、履歴上にマージコミットは存在せず、直線的な履歴が保たれます。つまり、履歴が完結になり、見やすくなります。
しかし、マージコミットが存在しないため、どのブランチからマージされたのかが履歴上で明確に分からないという注意点も存在します。

これを利用するケースは、「作業途中のコミットをまとめて、1つの意味ある変更単位として履歴を残したい場合」や、「コードレビュー単位で履歴を残したいとき」に適しています。

### `Rebase and merge`

![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3026821/92a3b3ed-6bef-4551-ba2c-519ac4a3e06b.png)

この操作では、feature ブランチの各コミットが main ブランチの末尾に「再適用（rebase）」され、新たなコミットとして追加されます。
そのため、main ブランチにはマージコミットは作成されず、履歴は直線的な流れになります。

この直線的な履歴により、git log での読みやすさや git bisect による不具合調査がしやすくなるなどのメリットがあります。
ただし注意点として、Rebase により元のコミットとは別物（新しい SHA を持つ）として扱われるため、履歴の正確な出所（どのブランチで書かれたかなど）は履歴上からは判別しづらくなります。

:::note warn
実際、rebase を行うと、差分自体は main の 先頭に追加されるものの、feature ブランチの の D、E の差分のコミットIDと、main ブランチの の D、E の差分のコミットIDは異なります。
:::

これを利用するケースとして、「各コミットを分解して追える状態で残したい場合」や「履歴をできるだけシンプルかつ直線的に保ちたい場合」に適しています。

## おわりに

今回、GitHubで使用することのできる3つのPull Requestのマージ方法を紹介してきましたが、それぞれ規模感やチーム体制によって大きく左右されます。
「どれが正しい」ではなく、「どれが今のプロジェクトに合っているか」を意識することが大切です。本記事が、マージ方法の選択やブランチ戦略の整理に役立てば幸いです。

## 参考記事
https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges

https://qiita.com/ko-he-8/items/94e872f2154829c868df
仕事で使えるシンプルなタスク管理アプリ作ってみた

初めまして。新卒エンジニアのとりです。配属されてから２週間経って、少しづつ仕事も与えてもらえるようになりました。

働き始めて気づいたのが、タスク管理の難しさです。
具体的には、スケジュール帳に書くような主なタスクの管理ではなく、細々とした作業の把握です。会議中に出た分からない用語を調べておく、すぐに返せなかった返信をする、マニュアルを読んでおく、といった後回しにしている小さいことを業務中に覚えていることが大変です。小さいタスクはその場でするようにしていますが、どうしてもできないこともあります。

そこで、仕事でも使えるようなシンプルなタスク管理アプリを作ってみました。
こういうのは、作ったはいいもののそのうち使わなくなるのが目に見えていたので、使うのが面倒くさくならない超シンプルなアプリにしました。
条件として、社内情報をwebに載せないようローカルで完結させること、npm startみたいに毎回立ち上げないで済ませるということの２つがあります。そこで、LocalStorageを使うことにしました。

LocalStorage、以前学んだ気がするけど、ちゃんと使ったことがなかったので、改めて知るよい機会になりました。長くなるので、LocalStorageやアプリの実装方法はこちらのページでまとめました。

[リンク]


アプリのUIはこんな感じです。
![スクリーンショット 2025-05-18 235849.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090951/a513d030-8d95-4fd7-a346-d94e4628ef5b.png)


タスクを追加する、完了したらクリックして下に移動させる、下からも消したかったら削除する、それだけです。一応下の完了したタスクは３日間経過で消えるようになっています。作成日時と完了日時はホバーすれば見えるようになっています。

非常にシンプルにできました！あとはファイルのリンクをブラウザに記憶させれば、毎日の使用も面倒くさくなくなります。とりあえず仕事に慣れるまでは使ってみようと思います。

[githubリポジトリ](https://github.com/katsushi-torii/task-manager)
sysの使い方について（Python）

## はじめに
お久しぶりです。takimonです！

今回は、Pythonプログラミングでよく利用するsysモジュールについてご紹介します。

sysモジュールの中でも私が特によく使う機能（関数や属性）をいくつか紹介していきます。

## `sys`について
sysモジュールは、Pythonインタプリタが使用・管理する変数や、インタプリタの動作に深く関連する関数、そして実行環境に関する情報などを提供しています。

###  `sys.argv`
`sys.argv`は、スクリプトに渡されたコマンドライン引数のリストを出力します。

例えば、以下のコマンドで`print(sys.argv)`が書かれたPythonスクリプトを実行します。

```
python sample.py -a b
```
すると下記のように出力されます。

```
['sample.py', '-a', 'b']
```
sys.argv[0]は実行されたスクリプトのファイル名になり、それ以降の要素にはコマンドライン引数が格納されます。

###  `sys.path`
`sys.path`は、Pythonがモジュールを検索するパスを示す文字列のリストを出力します。import文を使ってモジュールを読み込む際、Pythonはこの`sys.path`に含まれるディレクトリの中から該当のモジュールを探しに行きます。

もし、importしたいモジュールが`sys.path`に含まれるパスにない場合、そのままではインポートできません。

外部のモジュールや自分で作成したモジュールを`sys.path`に追加したい場合は、以下のように記述します。

```python:script.py
import sys
sys.path.append("/path/to/your_module") 
```

###  `sys.exit()`
`sys.exit()`は、スクリプトの実行を任意のタイミングで終了させます。

この関数の引数に0を渡すと正常終了、0以外の整数を渡すと異常終了として扱われます。引数を省略した場合も0を渡したときと同じく正常終了となります。

## おわりに
いかがでしたでしょうか？

今回は簡単にではありますが、sysモジュールの私がよく使う関数について紹介しました。

今回紹介した機能の他にも、sysモジュールには便利な関数などが数多く存在します。

ぜひ、以下のPython公式ドキュメントで詳細を確認してみてください。

https://docs.python.org/ja/3/library/sys.html
【SQL】UNIONとUNION ALLの違い

SQL初心者ですが、備忘録です。

UNIONはオプティマイザで実行計画が2つになるので、あまりよくないと言いますが、例えばステータスの確認で１回実行するだけの時に役に立ちます。あまり考えずに結果セットを合体させたい時はUNIONで十分な気がしています。

例えばこんな感じで似た構造の異なるテーブルからデータを取り、結果をページに反映させたい時、便利です。

```get_task_schedule.sql
select task_id, task_status
from task_schedule_main
UNION
select  task_id, task_status
from task_schedule_sub
```

UNIONは重複排除なので、distinctしているのと同じです。
重複も確認したい時は、UNION ALLを使いましょう。
UNIONをした場合はOracleのROWIDが使えずエラーになりますが、UNION ALLでは使えます。


以下、ChatGPT4oによる記事チェック。

>「UNIONはオプティマイザで実行計画が2つになるので、あまりよくない」
>　→ 必ずしも悪いとは限らない。実行計画が2つになるのは事実だが、最適化されることもある。パフォーマンスが悪くなるかはケースバイケース。
>
>「UNIONはdistinctしているのと同じ」
>　→ 厳密には正しいが、「ソートが発生する可能性がある＝コストが高くなることもある」点には触れていない。
>
>「UNIONではROWIDが使えずエラーになる」
>　→ 正確には、UNIONの結果にROWIDを含めようとするとエラーになる。ROWIDは物理行に紐づくため、UNIONで複数テーブルをマージすると意味を持たなくなる。