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

はじめに - 「円安=物価高」という通説への挑戦 「円安だから物価が上がる」――ニュースで繰り返されるこのフレーズ。本当にそうなのか?統計総局の消費者物価指数(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

LeetCode 735: Asteroid Collision - スタックで衝突判定を美しく解く

問題概要 整数で表される小惑星の配列 asteroids が与えられる。各小惑星について: 絶対値:大きさ 符号:方向(正=右、負=左) 全て同じ速度で移動 衝突ルール: 小さい方が爆発 同じ大きさなら両方爆発 同じ方向に移動する小惑星は衝突しない 全ての衝突後の状態を返せ。 失敗した実装 from collections import deque class Solution: def asteroidCollision(self, asteroids: List[int]) -> List[int]: stack = [] for aster in asteroids: if len(stack) <= 0 or (aster <= 0) == (stack[-1] <= 0): stack.append(aster) else: while len(stack) > 0 and (aster <= 0) != (stack[-1] <= 0) and abs(aster) > abs(stack[-1]): stack.pop() if len(stack) <= 0 or (stack[-1] <= 0) == (aster <= 0): stack.append(aster) elif abs(aster) == abs(stack[-1]): stack.pop() return stack 問題点 同じ条件判定 if len(stack) <= 0 or (stack[-1] <= 0) == (aster <= 0) が2箇所に重複 制御フローが複雑で読みにくい (aster <= 0) != (stack[-1] <= 0) は「符号が異なる」を検出するが、衝突しないケースも含む 最適解 class Solution: def asteroidCollision(self, asteroids: List[int]) -> List[int]: stack = [] for asteroid in asteroids: while stack and asteroid < 0 < stack[-1]: # 右向き vs 左向きの衝突が発生 if abs(stack[-1]) < abs(asteroid): # 右向きが小さい → 爆発して次の右向きとも衝突判定 stack.pop() continue elif abs(stack[-1]) == abs(asteroid): # 同じ大きさ → 両方爆発 stack.pop() break else: # 衝突しなかった or 左向きが勝った stack.append(asteroid) return stack わかったこと 1. ループ条件の本質 asteroid < 0 < stack[-1] これは (asteroid < 0) and (0 < stack[-1]) と同じ。つまり: ...

January 13, 2026 · 2 min

Go言語でネットワークプログラミングを学ぶ - 第2章

2.1 プロジェクト構造 go-network-programming/ ├── go.mod ├── go.sum ├── main.go ├── packet.go ├── node.go ├── link.go ├── network_stats.go # 新規追加 └── bandwidth_limiter.go # 新規追加 この章では、ネットワークに時間の概念を本格的に導入します。実際のネットワークのように、帯域幅制限、パケット処理時間、スループット測定を実装し、大きなファイルの送信をシミュレートします。 2.2 ネットワーク統計の追加 ネットワークの性能を測定するための統計機能を追加します。 ファイル名: ./network_stats.go package main import ( "fmt" "sync" "time" ) // NetworkStats はネットワークの統計情報を管理する // 実際のネットワークモニタリングツールのような機能を提供 type NetworkStats struct { mu sync.RWMutex startTime time.Time totalPacketsSent int64 totalPacketsRecv int64 totalBytesSent int64 totalBytesRecv int64 packetLossCount int64 lastUpdateTime time.Time } // NewNetworkStats は新しい統計オブジェクトを作成 func NewNetworkStats() *NetworkStats { return &NetworkStats{ startTime: time.Now(), lastUpdateTime: time.Now(), } } // RecordSentPacket は送信パケットを記録 func (ns *NetworkStats) RecordSentPacket(packet *Packet) { ns.mu.Lock() defer ns.mu.Unlock() ns.totalPacketsSent++ ns.totalBytesSent += int64(packet.Size) ns.lastUpdateTime = time.Now() } // RecordReceivedPacket は受信パケットを記録 func (ns *NetworkStats) RecordReceivedPacket(packet *Packet) { ns.mu.Lock() defer ns.mu.Unlock() ns.totalPacketsRecv++ ns.totalBytesRecv += int64(packet.Size) ns.lastUpdateTime = time.Now() } // RecordPacketLoss はパケット損失を記録 func (ns *NetworkStats) RecordPacketLoss() { ns.mu.Lock() defer ns.mu.Unlock() ns.packetLossCount++ ns.lastUpdateTime = time.Now() } // GetThroughput は現在のスループットを計算(bps: bits per second) func (ns *NetworkStats) GetThroughput() float64 { ns.mu.RLock() defer ns.mu.RUnlock() duration := time.Since(ns.startTime).Seconds() if duration == 0 { return 0 } // バイト数をビット数に変換(1バイト = 8ビット) totalBits := float64(ns.totalBytesSent) * 8 return totalBits / duration } // GetPacketLossRate はパケット損失率を計算(0.0-1.0) func (ns *NetworkStats) GetPacketLossRate() float64 { ns.mu.RLock() defer ns.mu.RUnlock() if ns.totalPacketsSent == 0 { return 0.0 } return float64(ns.packetLossCount) / float64(ns.totalPacketsSent) } // Print は統計情報を表示 func (ns *NetworkStats) Print() { ns.mu.RLock() defer ns.mu.RUnlock() duration := time.Since(ns.startTime) throughputBps := ns.GetThroughput() throughputKbps := throughputBps / 1000 lossRate := ns.GetPacketLossRate() * 100 fmt.Printf("=== Network Statistics ===\n") fmt.Printf("Duration: %v\n", duration.Round(time.Millisecond)) fmt.Printf("Packets Sent: %d\n", ns.totalPacketsSent) fmt.Printf("Packets Received: %d\n", ns.totalPacketsRecv) fmt.Printf("Bytes Sent: %d\n", ns.totalBytesSent) fmt.Printf("Bytes Received: %d\n", ns.totalBytesRecv) fmt.Printf("Throughput: %.2f Kbps\n", throughputKbps) fmt.Printf("Packet Loss Rate: %.2f%%\n", lossRate) fmt.Printf("=========================\n") } 2.3 帯域幅制限機能の実装 実際のネットワークのように、帯域幅制限を実装します。 ...

January 11, 2026 · 7 min

Go言語でネットワークプログラミングを学ぶ - 第3章

3.1 プロジェクト構造 go-network-programming/ ├── go.mod ├── go.sum ├── main.go ├── packet.go ├── node.go ├── link.go ├── network_stats.go ├── bandwidth_limiter.go ├── mac_address.go # 新規追加 ├── ethernet_frame.go # 新規追加 └── switch.go # 新規追加 この章では、スイッチを実装して複数のノードを接続できるローカルネットワークを構築します。また、MACアドレスを導入してイーサネットレベルでの通信を実現します。 3.2 MACアドレスの実装 MACアドレス(Media Access Control Address)は、ネットワークインターフェースの物理アドレスです。 ファイル名: ./mac_address.go package main import ( "fmt" "math/rand" "strconv" "strings" ) // MACAddress はMAC(Media Access Control)アドレスを表現する // 実際のイーサネットで使用される6バイトの物理アドレス type MACAddress struct { bytes [6]byte // 6バイトのMACAアドレス(例:aa:bb:cc:dd:ee:ff) } // NewMACAddress は指定されたバイト配列からMACアドレスを作成 func NewMACAddress(bytes [6]byte) MACAddress { return MACAddress{bytes: bytes} } // ParseMACAddress は文字列からMACアドレスを解析 // 例:ParseMACAddress("aa:bb:cc:dd:ee:ff") func ParseMACAddress(s string) (MACAddress, error) { parts := strings.Split(s, ":") if len(parts) != 6 { return MACAddress{}, fmt.Errorf("invalid MAC address format: %s", s) } var mac MACAddress for i, part := range parts { val, err := strconv.ParseUint(part, 16, 8) if err != nil { return MACAddress{}, fmt.Errorf("invalid hex value in MAC address: %s", part) } mac.bytes[i] = byte(val) } return mac, nil } // RandomMACAddress はランダムなMACアドレスを生成 // ユニキャスト、ローカル管理アドレスとして生成 func RandomMACAddress() MACAddress { var mac MACAddress for i := 0; i < 6; i++ { mac.bytes[i] = byte(rand.Intn(256)) } // ユニキャスト(LSBを0に)、ローカル管理(2番目のLSBを1に)に設定 mac.bytes[0] = (mac.bytes[0] & 0xFC) | 0x02 return mac } // String はMACアドレスの文字列表現を返す func (mac MACAddress) String() string { return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", mac.bytes[0], mac.bytes[1], mac.bytes[2], mac.bytes[3], mac.bytes[4], mac.bytes[5]) } // Equals は2つのMACアドレスが等しいかチェック func (mac MACAddress) Equals(other MACAddress) bool { return mac.bytes == other.bytes } // IsUnicast はユニキャストアドレスかチェック func (mac MACAddress) IsUnicast() bool { return (mac.bytes[0] & 0x01) == 0 } // IsBroadcast はブロードキャストアドレスかチェック func (mac MACAddress) IsBroadcast() bool { return mac.bytes == [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} } // IsMulticast はマルチキャストアドレスかチェック func (mac MACAddress) IsMulticast() bool { return (mac.bytes[0] & 0x01) == 1 && !mac.IsBroadcast() } // BroadcastMAC はブロードキャストMACアドレスを返す func BroadcastMAC() MACAddress { return MACAddress{bytes: [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}} } 3.3 イーサネットフレームの実装 MACアドレスを含むイーサネットフレーム構造を実装します。 ...

January 11, 2026 · 12 min

Go言語でネットワークプログラミングを学ぶ - 第0章

参考・インスピレーション元 この教材は以下のサイトの構成を参考に、Go言語での実装として新たに構築したものです: CoNeCo|コンピュータネットワーク with Colab: https://www.conecolab.com/ 作者:中山悠(東京農工大学准教授) ライセンス:CC-BY-SA Google Colabを使用したPython実装によるネットワーク学習教材 本教材は上記の教育アプローチにインスピレーションを受けつつ、Go言語での独自実装として作成しています。 Go言語でネットワークプログラミングを学ぶ 第0章:環境構築とネットワーク基礎概念 0.1 環境構築 # Go 1.21以上をインストール go version # プロジェクト初期化 mkdir go-network-programming cd go-network-programming go mod init go-network-programming # 必要なパッケージ go get github.com/google/uuid go get gonum.org/v1/gonum/graph 0.2 なぜGo言語なのか? ネットワークプログラミングにおけるGo言語の利点: 並行処理のサポート:goroutineによる軽量な並行処理 型安全性:プロトコルの違いをコンパイル時に検証 シンプルな文法:複雑な仕様を直感的なコードで表現 標準ライブラリ:充実したネットワーク関連パッケージ 0.3 学習対象の基本概念 ノード (Node) ネットワーク上のデバイス(PC、スマートフォン、ルーターなど) パケットを送受信する機能 一意のアドレスを持つ リンク (Link) ノード間の接続 帯域幅、遅延、エラー率などの特性を持つ 双方向または単方向の通信 パケット (Packet) ネットワークで転送される情報の単位 ヘッダとペイロードから構成 プロトコル層によって内容が変化 0.4 基本アーキテクチャの設計 // ネットワークエンティティの基本インターフェース type NetworkEntity interface { ID() string String() string } // パケット処理のインターフェース type PacketHandler interface { Send(packet Packet, destination string) error Receive() <-chan Packet } // アドレス管理のインターフェース type Addressable interface { Address() Address SetAddress(addr Address) } 0.5 学習計画 第1章: 基本要素の実装 (Node, Link, Packet) 第2章: 時間と並行性の導入 第3章: スイッチングとMACアドレス 第4章: MACアドレス学習とループ回避 第5章: IPパケットとルーティング 第6章: 動的ルーティングプロトコル 第7章: レイヤ化とカプセル化 第8章: アドレス解決プロトコル 第9章: 動的IPアドレス設定とNAT 第10章: TCP接続の確立 第11章: 確認応答と再送制御 第12章: 輻輳制御とウィンドウ制御 第13章: QoSと優先制御 第14章: アプリケーション層プロトコル 第15章: セキュリティと暗号化 0.6 評価ポイント 各章で以下の観点から実装を評価します: ...

January 10, 2026 · 1 min

Go言語でネットワークプログラミングを学ぶ - 第1章

第1章:ネットワークの基本要素 - Node、Link、Packet 1.1 プロジェクト構造 go-network-programming/ ├── go.mod ├── go.sum ├── main.go ├── packet.go ├── node.go └── link.go この章では、ネットワークの基本的な構成要素であるノード、リンク、パケットをGo言語で実装します。実際のネットワーク機器と同じように、複数のプロセスが並行して動作し、channelを通じてパケットを送受信する仕組みを構築します。 1.2 パケットの実装 パケットは、ネットワークで送信される情報の基本単位です。送信元、宛先、データ本体、タイムスタンプなどの情報を含みます。 ファイル名: ./packet.go package main import ( "fmt" "time" "github.com/google/uuid" ) // Packet はネットワークで送信される基本単位を表現する // 実際のTCP/IPパケットのように、ヘッダ情報とペイロードを持つ type Packet struct { ID string // パケットの一意識別子 Source string // 送信元ノードの名前 Destination string // 宛先ノードの名前 Data []byte // 実際のデータ(ペイロード) Size int // データサイズ(バイト) Timestamp time.Time // パケット生成時刻 } // NewPacket は新しいパケットを生成する // 実際のネットワークスタックでパケットが生成される処理を模倣 func NewPacket(source, destination string, data []byte) *Packet { return &Packet{ ID: uuid.New().String(), Source: source, Destination: destination, Data: data, Size: len(data), Timestamp: time.Now(), } } // String はパケットの文字列表現を返す(デバッグ用) func (p *Packet) String() string { return fmt.Sprintf("Packet{ID: %s, From: %s, To: %s, Size: %d bytes}", p.ID[:8], p.Source, p.Destination, p.Size) } 1.3 ノードの実装 ノードは、ネットワーク上のデバイス(PC、スマートフォン、ルーターなど)を表現します。パケットの送受信機能を持ち、複数のリンクに接続できます。 ...

January 10, 2026 · 6 min

DFS/BFSの本質:深さと幅を支配するデータ構造の選択

DFS, BFSがわかりづらかったので、いくつかの記事を見て個人的に感じた疑問や 「こういうコード例が欲しい」という要望を踏まえて生成AIに生成してもらった。 生成された内容を検証し、コードを実際に動かして確認したところ、 自分の理解が深まる良い記事になったので、このまま公開することにした。 はじめに LeetCodeでMedium問題を解いていると、必ず遭遇するのがDFS(深さ優先探索)とBFS(幅優先探索)だ。 「Dは深さ、Bは幅」というのは知っている。でも、なぜスタックとキューを使い分けるのか?その本質を理解している人は意外と少ない。 今回は、入れ子リストの例を使って、DFS/BFSの動作原理とデータ構造の関係を視覚的に解説する。 問題設定:入れ子リストをフラット化する 以下のような入れ子構造のリストがあるとする。 data = [1, [4, 5, [6, 7, 8], 2], 3] これをフラットな配列にしたい。このとき、「どの順番で要素を取り出すか」がDFS/BFSの違いだ。 ツリー構造として可視化する 入れ子リストは、実はツリー構造として表現できる。 root / | \ 1 [] 3 | /|\ \ 4 5 [] 2 | /|\ 6 7 8 この木をどう巡回するかで、DFSとBFSが決まる。 DFS(深さ優先探索):とにかく深く潜る 動作イメージ 「見つけた枝があれば、まずそこを最後まで探索する」 訪問順序: 1 → [中に入る] → 4 → 5 → [さらに中] → 6 → 7 → 8 → [戻る] → 2 → [戻る] → 3 結果:[1, 4, 5, 6, 7, 8, 2, 3] ...

January 9, 2026 · 3 min

本が読めなかったから、仕事をやめました - 読書メモ

本の情報 タイトル: 本が読めなかったから、仕事をやめました 著者: [著者名不明] 読書期間: 2025年1月9日 読了状況: 大正時代まで(未完) まえがき - 衝撃の一文 本が読めなかったから、仕事をやめました★ ロックすぎる。 著者の状況 読書好き、本を買うために働く 週5勤務、21時まで残業 気づいたら1年間、本を読んでいない 時間があってもスマホを見てしまう 本を開いても目が閉じる、YouTubeに逃げる 3年半後、退職 退職後、ゆっくり読書できるようになった 著者の問題提起 会社で働きながら本を読むことは難しい 本を読む余裕のない社会はおかしい → SNSで多くの同意が集まる → 趣味全般を続けづらい社会への問い → 「あなたの文化は労働に搾取されている」 所感: 共感と違和感 共感ポイント 仕事のために生きている人が多数派でビビる 仕事は微妙、人間関係は辛い これ、私のことだ 読書好きでもこうなるのか…(本当なら) 余裕がない社会 働きながらX(Twitter)をやるのはマジで辛い 違和感 突然「搾取」という言葉が出てきて怖い 自称漫画家、バンドマンのようなゴミは働きながら続けるべき 辛いからこそ、続けるってことは熱量があるってこと 第1章: 労働と文化的生活の両立 著者の姿勢 文句だけ言っても仕方ない 歴史から学ぶアプローチ なぜ今、両立しなくなったのか どうしたら両立できるのか 『花束みたいな恋をした』分析 登場人物: 麦: 地方の花火職人 → 会社員 絹: 金持ち、大企業 展開: 就職後、麦は忙しくなる 漫画が続かない、頭に入らない パズドラしかやる気しない 絹からの本も無視 心が離れていく テーマ: 長時間労働と文化的生活は両立しないという前提の作品 速読・自己啓発ブームの意味 Amazonで速読、情報処理スキル、読書術が人気 趣味ではなく、自己啓発メイン 効率優先 → 労働と読書の両立をみんななんとかしようとした結果 ファスト教養も同じ構造 第2章: 格差と読書 階級格差が読書意欲に影響 麦(労働者)vs 絹(富裕層)の対比 働けど働けど暮らしは楽にならず 本を読む余裕さえなくなる 暮らしの格差が余暇の時間も奪う 『独学大全』の指摘 格差は動機づけの段階から現れる 学ぶ動機づけがない者 → 学問は役に立たない、僻む 意欲から格差が生まれる 第3章: 明治時代 - 長時間労働と読書の始まり 労働環境 この頃から長時間労働 工場労働者: 農民時代より断然長時間 平均残業時間: 2時間 …あれ? 化学工場: 12時間労働 …は? 労働組合はゴミ、割増料金が魅力的 → 今もだいたい同じ 明治時代の感覚 「最近はみんな忙しそうにしてる」 余裕がなくなった感じ、せっかち 近代化 = せっかち 読書革命 句読点と黙読の発明: ...

January 9, 2026 · 2 min

Audibleで学ぶヨーロッパ中世史:雑談メモ

はじめに Audibleでヨーロッパの歴史を聞きながら、メモを取っていたら思いのほか面白い内容になった。バシレイオス2世からカロリング朝の終焉まで、雑談形式で記録してみる。 バシレイオス2世「ブルガリア人殺し」 基本情報 在位: 976-1025年 異名: Βουλγαροκτόνος(ブルガリア人殺し) 業績: ビザンツ帝国最盛期を築く 有名なエピソード:クレイディオンの戦い(1014年) ブルガリア軍15,000人を捕虜に 捕虜全員の目を潰す(100人に1人だけ片目を残して案内役に) ブルガリア皇帝サムイルがショック死 第一次ブルガリア帝国滅亡 個人的感想 「こいつカスだなー、こいつ大帝でいいの?」 確かに現代の倫理観から見れば戦争犯罪者レベル。ただし中世の「大帝」基準では: 領土拡張 ✓ 敵国完全屈服 ✓ 後世まで語り継がれるインパクト ✓ 帝国繁栄 ✓ オットー2世とマラリア 人物像 在位: 973-983年 比較的穏健な統治者 学問保護、教会制度整備 問題: 南イタリア遠征で無茶をした 死因:マラリア 南イタリア遠征中に感染 983年、28歳で死去 当時のマラリアはほぼ死刑宣告 北欧系には特に致命的 感想: 「やっちゃったねぇ」 中世の皇帝は戦争で死ぬか病気で死ぬかの二択。現代医学があれば… リウトプランド・オブ・クレモナ 外交官としての活動 オットー1世の外交使節 ビザンツ皇帝ニケフォロス2世フォカスとの交渉担当 結果: 大失敗 失敗の原因 ビザンツ側が西欧を「野蛮人」として完全に見下し オットー1世の「ローマ皇帝」称号をビザンツが拒否 リウトプランド本人のプライドの高さ 文学的価値 外交官としては無能だったが、『コンスタンティノープル使節記』は貴重な史料。ルポライターとしては一流。 女帝イレーネ・アテネ女 母子の権力闘争 在位: 797-802年 息子コンスタンティノス6世の摂政として実権掌握 息子が独立を図る 797年: クーデターで息子の目を潰して廃位 史上初の女性単独皇帝 歴史的影響 西欧では「東に皇帝がいない」(女性は皇帝と認めない) 800年: カール大帝の「ローマ皇帝」戴冠の口実に 東西ローマ皇帝位問題の発端 最期 802年: ニケフォロスのクーデターで廃位 レスボス島に流刑 803年: 自然死(比較的穏やかな最期) サラセン人とアッシリア人の違い よくある混同 サラセン人: アラブ・イスラム勢力(中世ヨーロッパ人の呼称) アッシリア人: 古代メソポタミア系民族(主にキリスト教徒) 地理的分布(10-11世紀) サラセン人の拠点: ...

January 3, 2026 · 1 min