Emacsのdotfilesをモジュール化してメンテナンス性を向上させた話

背景 約900行に肥大化したmypackage.elを整理し、機能ごとにファイル分割してメンテナンス性を向上させるリファクタリングを実施した。 課題 単一ファイルの肥大化: mypackage.elが900行超えで見通しが悪い 機密情報の混在: API keyがコード内に散在 使っていない設定: コメントアウトされた設定が残存 パッケージの把握困難: 何を使っているか不明瞭 新しいディレクトリ構成 dotfiles/emacs/ ├── init.el # エントリーポイント ├── early-init.el # 起動高速化 ├── core/ │ ├── env.el # 環境変数・基本設定 │ ├── custom.el # UI基本設定 │ ├── keymap.el # キーバインド │ └── util.el # ユーティリティ関数 ├── packages/ │ ├── manager.el # straight.el設定 │ ├── core.el # 基盤パッケージ │ ├── completion.el # 補完系 (Vertico, Corfu) │ ├── search.el # 検索系 (Consult, Embark) │ ├── git.el # Magit等 │ ├── lsp.el # Eglot等 │ ├── languages.el # 言語別設定 │ ├── ai.el # GPTel, Ollama │ ├── writing.el # Denote, Org, Markdown │ ├── ui.el # テーマ、アイコン │ └── optional.el # たまに使うもの ├── templates/ # Tempelテンプレート └── docs/ └── README.md 重要な学び: require vs load 問題: requireでパッケージが読み込まれない 当初、init.elで(require 'completion)のように読み込んでいたが、以下の問題が発生: ...

February 6, 2026 · 3 min

三竦(さんすくみ)要件定義書

1. 概要 1.1 ゲームコンセプト 「三竦(さんすくみ)」は、犬・猿・雉の三すくみ関係を利用した追跡型対戦ゲーム。プレイヤーは召喚獣を配置して相手を攻撃しつつ、敵の召喚獣から逃げ切る戦略性とアクション性を兼ね備えたリアルタイムバトルゲーム。 1.2 コアメカニクス 三すくみ関係: 犬 → 猿 → 雉 → 犬 追跡システム: 召喚獣は相手プレイヤーを自動追跡 相性バトル: 有利な召喚獣は相手を一方的に倒す 戦略的配置: 召喚位置とタイミングが勝敗を分ける 1.3 開発目標 シンプル: ルールが3分で理解できる 完成優先: 1ヶ月以内にプレイアブル版完成 Android専用: Expo使用、まずCPU対戦のみ 2. ゲーム仕様 2.1 基本ルール 勝利条件 HP制: 各プレイヤーHP 3 制限時間: 3分 勝敗判定: 相手のHPを0にした方が勝ち 3分経過時、HP多い方が勝ち 同点の場合は引き分け ゲームフロー graph TD A[ゲーム開始] --> B[3分タイマー開始] B --> C{ゲーム中} C --> D[プレイヤー移動] C --> E[召喚獣配置] C --> F[召喚獣追跡] F --> G{当たり判定} G -->|当たった| H[HP-1] G -->|外れた| C H --> I{HP=0?} I -->|Yes| J[ゲーム終了] I -->|No| C C --> K{3分経過?} K -->|Yes| J K -->|No| C J --> L[リザルト表示] 2.2 召喚獣仕様 三すくみ関係 graph LR A[犬] -->|勝つ| B[猿] B -->|勝つ| C[雉] C -->|勝つ| A パラメータ表 召喚獣 速度 寿命 クールダウン 特性 犬 🐕 速い 10秒 10秒 素早く追跡、短命 猿 🐒 中速 10秒 10秒 バランス型 雉 🐦 遅い 10秒 10秒 遅いが長持ち 共通ルール: ...

February 6, 2026 · 6 min

GEMINI.mdでAIに開発履歴を管理させる方法

問題:AIは過去の失敗を忘れる Gemini や ChatGPT などの AI にコード生成を依頼するとき、こんな問題がありませんか? 同じミスを何度も繰り返す 前回指摘したルールを忘れる プロジェクト固有の制約を無視する 毎回「Expo では react-native-vector-icons じゃなくて @expo/vector-icons を使って」と指示するのは面倒です。 解決策:GEMINI.md でルールを管理 プロジェクトルートに GEMINI.md ファイルを作成し、AI に従ってほしいルールをすべて記載します。 # Gemini AI Coding Rules ## General Principles - Always provide complete, working code - Include all necessary imports - Add TypeScript types for all functions ## Expo/React Native Specific - Use Expo SDK compatible packages only - Prefer `npx expo install` over `npm install` ## Expo Specific Rules - Use `@expo/vector-icons` instead of `react-native-vector-icons` - Import example: `import { MaterialCommunityIcons } from '@expo/vector-icons';` AI に指示を出すときは、必ず「GEMINI.md を読んでから実装して」と伝えます。 ...

January 31, 2026 · 3 min

Gemini CLIでExpo Todoアプリを爆速開発した話

やりたかったこと WSL2 環境で Expo を使った Todo アプリを作りたい。ただし、UI ライブラリの選定やナビゲーション設定など、細かい作業は Gemini に任せて効率化したい。 GEMINI.md でルール管理 プロジェクトルートに GEMINI.md を作成し、Gemini に従ってほしいルールを記載しました。 # Gemini AI Coding Rules ## Expo/React Native Specific - Use Expo SDK compatible packages only - Prefer `npx expo install` over `npm install` - Use functional components with hooks ## Expo Specific Rules - Use `@expo/vector-icons` instead of `react-native-vector-icons` - Never use packages that require native linking ## Tech Stack (Fixed) - Expo with TypeScript - React Native Paper for UI - AsyncStorage for persistence このファイルを事前に作っておくことで、Gemini が一貫した品質のコードを生成してくれます。 ...

January 31, 2026 · 2 min

React NativeでTextInputの日本語入力が壊れる問題と解決方法

最近趣味の方でモバイル開発を始めた。 Android端末を普段遣いしている点、仕事上iOSのアプリ周りのリリースがクソだるいことを知っているため Expoで開発しつつも、Androidのみを想定した開発を行っている。 その延長線で引っかかった部分とかをメモに残そうと思ったので記事にした。 問題:日本語入力で変換候補が消える Expo/React Native で Todo アプリを作っていたときTextInput で日本語を入力すると変換候補が一瞬で消えてしまう問題に遭遇。 // 問題のあるコード const [text, setText] = useState(''); <TextInput value={text} onChangeText={setText} /> 「あ」と入力しても変換候補が表示されず、即座に確定されてしまい、ローマ字入力も正常に動作しない。 原因:State更新による再レンダリング React Native の TextInput は制御コンポーネント(value + onChangeText)として使うと、以下の流れで問題が発生する。 日本語入力で「あ」と入力 OS が変換候補を表示するために内部バッファを保持 onChangeText が発火して State 更新 再レンダリングで TextInput が新しい value で再構築 controlled component としての value の強制が、IME の内部バッファと衝突する ← ここが問題! 変換候補が消える autoComplete や autoCorrect が有効だと、OS の補完機能が value の強制にさらに抵抗するため、IME との同期がズレやすくなる。 解決方法:autoComplete と autoCorrect を OFF // 修正後のコード <TextInput value={text} onChangeText={setText} autoComplete="off" autoCorrect={false} /> この2つのプロパティを追加するだけで、IME が安定して動作した。 ...

January 31, 2026 · 1 min

Proxmox LXCコンテナでJupyterLab環境構築 - 試行錯誤とトラブルシューティング

はじめに Proxmox上にJupyterLabのLXC環境を構築しました。当初はGeminiに任せて試行錯誤しましたが、最終的にベストプラクティスに辿り着いたので、その過程と解決策をまとめます。 構築の基本方針 当初は「Root + グローバル環境」で構築しようとしましたが、最終的に**「専用ユーザー + 仮想環境(venv)」**による安全でクリーンな構成に落ち着きました。 最終構成 OS: Ubuntu 24.04 LTS (LXC Container) ユーザー: jupyter (非Root運用) Jupyter: JupyterLab (v4.x) 環境: /opt/jupyter/venv (OSと分離した仮想環境) 環境構築手順 1. OSの準備 Ubuntu 24.04の最小構成に必要なパッケージをインストールします。 apt update && apt upgrade -y apt install -y python3-full build-essential python3-fullが重要です。これがないと後述するPEP 668の問題に直面します。 2. 専用ユーザーとディレクトリの作成 # 専用ユーザー作成 useradd -m -s /bin/bash jupyter # Jupyter本体用のディレクトリ準備 mkdir -p /opt/jupyter chown jupyter:jupyter /opt/jupyter 3. 仮想環境の構築 jupyterユーザーとして、OSの制限を受けない独立した環境を作ります。 su - jupyter python3 -m venv /opt/jupyter/venv source /opt/jupyter/venv/bin/activate # JupyterLabとカーネルのインストール pip install jupyterlab ipykernel pandas 4. systemdによるデーモン化 /etc/systemd/system/jupyter.serviceを作成します。 ...

January 26, 2026 · 2 min

PythonとWorld Bankデータで世界の産業構造を可視化する方法

はじめに 世界の国々の経済は、どのように変化しているのでしょうか?今回は、World Bank(世界銀行)が提供するオープンデータを使って、各国の産業構造の変化を可視化してみました。 この記事では、Pythonのpandasとmatplotlibを使って、1997年から2024年までの約30年間の産業構造の変化をグラフにする方法を紹介します。 産業構造とは? 経済学では、産業を3つに分類します: 第一次産業:農業、林業、漁業など(自然から直接資源を得る産業) 第二次産業:製造業、建設業など(原材料を加工する産業) 第三次産業:サービス業、金融、小売など(形のないサービスを提供する産業) 国が経済発展すると、第一次産業から第二次産業へ、そして第三次産業へとシフトしていく傾向があります。これを「産業構造の高度化」と呼びます。 使用したデータ World Bankが提供している以下のデータを使用しました: 第一次産業: Agriculture, forestry, and fishing, value added (% of GDP) 第二次産業: Industry (including construction), value added (% of GDP) 第三次産業: Services, value added (% of GDP) これらは各産業がGDP(国内総生産)に占める割合を示しています。 分析対象国 今回は、経済発展段階や地域が異なる10カ国を選びました: 日本(JPN): 先進国・アジア 中国(CHN): 新興国・急成長 アメリカ(USA): 先進国・北米 ドイツ(DEU): 先進国・欧州 インド(IND): 新興国・南アジア 韓国(KOR): 先進国・アジア インドネシア(IDN): 新興国・東南アジア ベトナム(VNM): 新興国・急成長 シンガポール(SGP): 先進国・都市国家 タイ(THA): 新興国・東南アジア ポーランド(POL): 中所得国・欧州 Pythonコード 以下が実際に使用したコードです。 # 第一次: https://data.worldbank.org/indicator/NV.AGR.TOTL.ZS # 第二次: https://data.worldbank.org/indicator/NV.IND.TOTL.ZS # 第三次: https://data.worldbank.org/indicator/NV.SRV.TOTL.ZS # 産業付加価値GDP import pandas as pd import matplotlib.pyplot as plt # CSVデータ取得 df_1 = pd.read_csv('1.csv', skiprows=3) df_2 = pd.read_csv('2.csv', skiprows=3) df_3 = pd.read_csv('3.csv', skiprows=3) # 国名のマッピング country_names = { 'JPN': 'Japan', 'CHN': 'China', 'USA': 'United States', 'DEU': 'Germany', 'IND': 'India', 'KOR': 'South Korea', 'IDN': 'Indonesia', 'VNM': 'Vietnam', 'SGP': 'Singapore', 'THA': 'Thailand', 'POL': 'Poland', } def to_chart(df, codes, begin, end, title, filename): plt.figure(figsize=(14, 9)) for code in codes: data = df[df['Country Code'] == code] years = [str(year) for year in range(begin, end)] dict_data = data[years].iloc[0].to_dict() years = list(dict_data.keys()) values = list(dict_data.values()) line = plt.plot(years, values, marker='o', linewidth=2, markersize=4) # 線の最初(スタート地点)に国名ラベルを表示 plt.text(years[0], values[0], f'{country_names.get(code, code)} ', verticalalignment='center', horizontalalignment='right', fontsize=9, color=line[0].get_color(), fontweight='bold') plt.xlabel('Year', fontsize=11) plt.ylabel('Value (%)', fontsize=11) plt.title(f'{title} ({begin}-{end})', fontsize=13) plt.grid(True, alpha=0.3) plt.xticks(rotation=45) plt.tight_layout() # 画像として保存 plt.savefig(filename, dpi=300, bbox_inches='tight') plt.close() # 3つのグラフを生成 to_chart(df_1, list(country_names.keys()), 1997, 2024, "第一次産業 (Agriculture, forestry, and fishing)", "chart_primary.png") to_chart(df_2, list(country_names.keys()), 1997, 2024, "第二次産業 (Industry including construction)", "chart_secondary.png") to_chart(df_3, list(country_names.keys()), 1997, 2024, "第三次産業 (Services)", "chart_tertiary.png") 分析結果 第一次産業(農業・林業・漁業) ...

January 26, 2026 · 2 min

ラズパイ6台で作る、絶対に止まらない最強の自宅ネットワーク冗長化計画

はじめに 「自宅サーバーを構築したが、1台落ちただけで家族全員のネットが止まった」 そんな苦い経験(特にDNS/DHCP周りでの同期失敗)を経て、今回はRaspberry Pi 6台(+α)を駆使した「高可用性(HA)」に特化した自宅ネットワークを再設計します。 今回のコンセプトは「速度よりも、止まらないこと」。 北欧神話の神々の名を冠した6台のラズパイによる、3層の冗長化レイヤーを構築します。 1. ネットワーク全体像 上位ルーターとはWi-Fiで接続し、内部ネットワークは有線L2スイッチを中心に構成します。物理的に役割を分離することで、障害時の原因切り分けを容易にしています。 階層化の設計案 Edge層 (L1): インターネットへの門番。KeepalivedでゲートウェイIPを共有。 Core層 (L2): DHCPやDNS、認証など、NWの頭脳となる機能を同期。 Service層 (L3): ファイルサーバーなどの実データをレプリケーションして保持。 2. サーバー構成表:北欧神話の神々 物理筐体 ホスト名 役割 冗長化の仕組み Pi 3 (A) Odin 主系Gateway / VPN Keepalived (VIP: 192.168.1.1) Pi 3 (B) Frigg 副系Gateway / VPN Odinと仮想IPを共有 Pi 3 (C) Huginn DNS / DHCP Primary ISC-DHCP Failover / Gravity Sync Pi 3 (D) Muninn DNS / DHCP Secondary Huginnとリアルタイム同期 Pi 3 (E) Mjolnir ストレージ (NAS) GlusterFS + Keepalived (VIP: .200) Pi 3 (F) Gungnir ストレージ (NAS) Mjolnirとデータレプリケーション 3. 過去の失敗を防ぐ「守り」の技術選定 ① DNS/DHCP:仮想IPに頼らない 過去、DNSやDHCPを仮想IP(Keepalived)で制御しようとして失敗した経験から、今回はプロトコル標準の冗長化を採用します。 ...

January 24, 2026 · 1 min

データが暴く物価高騰の真実 - エネルギー価格と為替の相関分析で見えた意外な結論

はじめに - 「円安=物価高」という通説への挑戦 「円安だから物価が上がる」――ニュースで繰り返されるこのフレーズ。本当にそうなのか?統計総局の消費者物価指数(CPI)と為替レートのデータを使って、この仮説を検証してみた。 データ準備 使用データ 消費者物価指数:統計総局『tmi2020a.csv』(2020年基準) 為替レート:みずほ銀行『quote.csv』(日次データを月次平均化) 期間:2023年1月〜2026年1月(3年間) 前処理 import pandas as pd import matplotlib.pyplot as plt from scipy.stats import linregress # CPI読み込み(ヘッダー5行スキップ) cpi_df = pd.read_csv('./tmi/tmi2020a.csv') cpi_clean = cpi_df.iloc[5:].copy().reset_index(drop=True) cpi_clean['エネルギー'] = pd.to_numeric(cpi_clean['エネルギー'], errors='coerce') # 為替読み込み(日次→月次平均) fx_df = pd.read_csv('./doru/quote.csv', encoding='utf-8') fx_clean = fx_df.iloc[2:].copy() fx_clean['日付'] = pd.to_datetime(fx_clean.iloc[:, 0], format='%Y/%m/%d') fx_clean['USD'] = pd.to_numeric(fx_clean.iloc[:, 1], errors='coerce') fx_clean['年月'] = fx_clean['日付'].dt.strftime('%Y%m') monthly_fx = fx_clean.groupby('年月')['USD'].mean().reset_index() monthly_fx.columns = ['年月', 'ドル円'] # データ結合 recent = cpi_clean[cpi_clean['類・品目'] >= '202301'].copy() data = recent.merge(monthly_fx, left_on='類・品目', right_on='年月', how='left') まず全体像を把握する グラフから見える3つの真実 1. エネルギー価格の激しい変動 オレンジ線を見ると、2023年初頭の135から2023年秋には104まで急落(-23%)。その後も上下を繰り返し、最終的に122で着地。地政学リスクがそのまま価格に反映されている。 2. 食料価格の不可逆的上昇 ピンク線は2023年から2025年にかけてほぼ一直線に上昇(109→127、+16%)。一度上がった食品価格は下がらない構造的問題が見える。 3. 総合指数の「マイルド感」 青線は安定的に上昇(104→112、+7%)。しかし国民が実感する物価高は、日常的に買う食料品の16%上昇の方。統計と実感の乖離がここに現れている。 ...

January 23, 2026 · 2 min

K3s実験環境構築マニュアル:安全に実験→破壊→復元のサイクルを回す

Proxmox上のK3s環境で安全に実験・破壊・復元サイクルを回すための完全ガイド

January 19, 2026 · 4 min