Python | 1 日 60 分 × 7 日アプリ学習:Python文法を学ぶアプリ 単位変換編

Web APP Python
スポンサーリンク
スポンサーリンク
  1. 単位変換アプリ 2日目のゴール
  2. 今日扱う単位変換(例)
  3. メニュー形式とは何か(初心者向けにかみ砕いて)
  4. 変換処理を関数に分ける理由
  5. 長さの変換(メートル → キロメートル)
  6. 重さの変換(kg → g)
  7. 温度の変換(℃ → ℉)
  8. 履歴を表示する機能
  9. メニューを表示する関数
  10. main を「メニュー形式」にする(最重要)
  11. 2日目の完成コード(まとめ)
  12. 2日目で本当に掴んでほしいこと
    1. ● メニュー形式は「アプリの基本構造」
    2. ● 関数を分けることでアプリが整理される
    3. ● ファイル操作は「アプリに記憶を持たせる技術」
  13. 次のステップ(3日目の予告)
  14. 単位変換アプリ 3日目のゴール
  15. 逆変換とは何か(初心者向けにかみ砕いて)
  16. 逆変換を追加する理由
  17. 長さの逆変換(km → m)
  18. 重さの逆変換(g → kg)
  19. 温度の逆変換(℉ → ℃)
  20. 履歴検索機能(部分一致検索)
    1. 深掘りポイント
  21. メニューに逆変換と検索を追加する
  22. main に逆変換と検索機能を追加する
  23. 3日目で本当に掴んでほしいこと
    1. ● 逆変換は「計算式が変わる」ため条件分岐の練習になる
    2. ● 履歴検索は「文字列処理+繰り返し+条件分岐」の総合練習
    3. ● 関数を分けることでアプリが整理される
  24. 次のステップ(4日目の予告)
  25. 単位変換アプリ 4日目のゴール
  26. 入力チェック(バリデーション)とは何か
  27. 数値入力チェックの基本テンプレート
    1. 深掘りポイント
  28. 長さ変換(m → km)を安全にする
  29. 重さ変換(kg → g)を安全にする
  30. 温度変換(℃ → ℉)を安全にする
  31. 逆変換も安全にする
    1. km → m
    2. g → kg
    3. ℉ → ℃
  32. メニュー番号の入力チェック
  33. メニュー(安全版)
  34. main(安全版)
  35. 4日目で本当に掴んでほしいこと
    1. ● 入力チェックは「アプリを壊れにくくする技術」
    2. ● try / except は初心者が必ず覚えるべき安全装置
    3. ● 関数を分けることで安全処理を再利用できる
  36. 次のステップ(5日目の予告)
  37. 単位変換アプリ 5日目のゴール
  38. JSONとは何か(初心者向けにかみ砕いて)
  39. 今日やることの全体像
  40. JSONを扱うためのモジュール:json
  41. JSON版:履歴を読み込む関数
    1. 深掘りポイント
  42. JSON版:履歴を保存する関数
    1. 深掘りポイント
  43. JSON版:履歴を追加する関数(最重要)
  44. JSON版:長さ変換(m → km)
  45. JSON版:重さ変換(kg → g)
  46. JSON版:温度変換(℃ → ℉)
  47. JSON版:履歴一覧表示
  48. JSON版:履歴検索(種類で検索)
  49. JSON版:履歴を並び替える(入力値順)
  50. メニュー(JSON版)
  51. main(JSON版)
  52. 5日目で本当に掴んでほしいこと
    1. ● JSONは「辞書とリストをそのまま保存できる魔法の箱」
    2. ● 履歴を辞書のリストにすると検索・並び替えが簡単になる
    3. ● 関数を分けることでアプリが整理される
  53. 次のステップ(6日目の予告)
  54. 単位変換アプリ 6日目のゴール
  55. JSON履歴を扱うための基本関数(復習)
    1. 履歴を読み込む
    2. 履歴を保存する
  56. 履歴編集機能(最重要)
    1. 深掘りポイント
  57. 履歴削除機能
    1. 深掘りポイント
  58. 履歴バックアップ機能
  59. メニュー(編集・削除・バックアップ追加版)
  60. main(編集・削除・バックアップ対応版)
  61. 6日目で本当に掴んでほしいこと
    1. ● JSONは「辞書のリストをそのまま保存できる」
    2. ● 編集は「辞書の値を書き換えるだけ」
    3. ● 削除は「残したいものだけを集める」
    4. ● バックアップは「読み込み → 書き込み」でOK
  62. 次のステップ(7日目の予告)
  63. 単位変換アプリ 7日目のゴール
  64. 完成アプリの構造を理解する
    1. ● データ構造(JSON)
    2. ● 機能(関数)
    3. ● アプリの流れ(main)
  65. JSON読み込み関数(完成版)
  66. JSON保存関数(完成版)
  67. 履歴追加関数(完成版)
  68. 入力チェック関数(完成版)
  69. メニュー番号チェック(完成版)
  70. 変換機能(長さ・重さ・温度)
    1. 長さ(m → km)
    2. 重さ(kg → g)
    3. 温度(℃ → ℉)
  71. 逆変換機能(完成版)
    1. km → m
    2. g → kg
    3. ℉ → ℃
  72. 履歴一覧表示(完成版)
  73. 履歴検索(種類)
  74. 履歴並び替え(入力値順)
  75. 履歴編集(完成版)
  76. 履歴削除(完成版)
  77. バックアップ(完成版)
  78. メニュー(完成版)
  79. main(完成版)
  80. 7日目で本当に掴んでほしいこと
    1. ● JSONは「辞書とリストをそのまま保存できる魔法の箱」
    2. ● アプリは「メインループ+機能の集合」でできている
    3. ● 関数を分けることでアプリが整理される
  81. 次のステップ(応用編への橋)

単位変換アプリ 2日目のゴール

2日目のテーマは 「複数の単位変換を選べる“メニュー形式アプリ”へ進化させ、変数・条件分岐・繰り返し・関数・ファイル操作を総合的に使えるようになること」 です。

1日目では

  • メートル → キロメートル
  • 変換結果をファイルに保存
  • 繰り返し処理で何度も変換

という最小の単位変換アプリを作りました。

2日目ではこれを 複数の単位変換を選べるアプリ に育てます。

今日扱う単位変換(例)

  • 長さ:メートル → キロメートル
  • 重さ:キログラム → グラム
  • 温度:摂氏(℃)→ 華氏(℉)

この3つをメニュー形式で選べるようにします。

メニュー形式とは何か(初心者向けにかみ砕いて)

メニュー形式とは、 「ユーザーが番号を選ぶことで機能を切り替える仕組み」 です。

例:

1: 長さの変換
2: 重さの変換
3: 温度の変換
4: 履歴を見る
5: 終了する

この形式は 条件分岐 繰り返し 関数 をまとめて使うため、アプリ開発の基礎として非常に重要です。

変換処理を関数に分ける理由

単位変換は種類が増えるほど複雑になります。 そこで、変換処理を関数に分けることで、

  • コードが読みやすくなる
  • 機能ごとに整理できる
  • 後で機能を追加しやすくなる

というメリットがあります。

長さの変換(メートル → キロメートル)

def convert_length():
    """
    長さの単位変換(m → km)
    """
    meter = float(input("メートルを入力してください: "))
    kilometer = meter / 1000
    print(f"{meter} m は {kilometer} km です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[長さ] {meter} m → {kilometer} km\n")
Python

重さの変換(kg → g)

def convert_weight():
    """
    重さの単位変換(kg → g)
    """
    kg = float(input("キログラムを入力してください: "))
    gram = kg * 1000
    print(f"{kg} kg は {gram} g です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[重さ] {kg} kg → {gram} g\n")
Python

温度の変換(℃ → ℉)

華氏の計算式は ℉ = ℃ × 1.8 + 32

def convert_temperature():
    """
    温度の単位変換(℃ → ℉)
    """
    celsius = float(input("摂氏(℃)を入力してください: "))
    fahrenheit = celsius * 1.8 + 32
    print(f"{celsius} ℃ は {fahrenheit} ℉ です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[温度] {celsius} ℃ → {fahrenheit}\n")
Python

履歴を表示する機能

def show_history():
    """
    変換履歴を表示する
    """
    try:
        with open("convert_history.txt", "r", encoding="utf-8") as f:
            print("=== 変換履歴 ===")
            print(f.read())
            print("================")
    except FileNotFoundError:
        print("まだ履歴がありません。")
Python

メニューを表示する関数

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 2日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 履歴を見る")
    print("5: 終了する")
    print("------------------------------")
Python

main を「メニュー形式」にする(最重要)

def main():
    print("Python 単位変換アプリ 2日目")
    print("複数の単位変換を選べるアプリを作っていきます。")

    while True:
        show_menu()
        choice = input("番号を入力してください(1〜5): ")

        if choice == "1":
            convert_length()
        elif choice == "2":
            convert_weight()
        elif choice == "3":
            convert_temperature()
        elif choice == "4":
            show_history()
        elif choice == "5":
            print("単位変換アプリを終了します。おつかれさまでした。")
            break
        else:
            print("1〜5 の番号を入力してください。")
Python

2日目の完成コード(まとめ)

import json

def convert_length():
    meter = float(input("メートルを入力してください: "))
    kilometer = meter / 1000
    print(f"{meter} m は {kilometer} km です。")
    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[長さ] {meter} m → {kilometer} km\n")


def convert_weight():
    kg = float(input("キログラムを入力してください: "))
    gram = kg * 1000
    print(f"{kg} kg は {gram} g です。")
    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[重さ] {kg} kg → {gram} g\n")


def convert_temperature():
    celsius = float(input("摂氏(℃)を入力してください: "))
    fahrenheit = celsius * 1.8 + 32
    print(f"{celsius} ℃ は {fahrenheit} ℉ です。")
    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[温度] {celsius} ℃ → {fahrenheit}\n")


def show_history():
    try:
        with open("convert_history.txt", "r", encoding="utf-8") as f:
            print("=== 変換履歴 ===")
            print(f.read())
            print("================")
    except FileNotFoundError:
        print("まだ履歴がありません。")


def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 2日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 履歴を見る")
    print("5: 終了する")
    print("------------------------------")


def main():
    print("Python 単位変換アプリ 2日目")
    print("複数の単位変換を選べるアプリを作っていきます。")

    while True:
        show_menu()
        choice = input("番号を入力してください(1〜5): ")

        if choice == "1":
            convert_length()
        elif choice == "2":
            convert_weight()
        elif choice == "3":
            convert_temperature()
        elif choice == "4":
            show_history()
        elif choice == "5":
            print("単位変換アプリを終了します。")
            break
        else:
            print("1〜5 の番号を入力してください。")


if __name__ == "__main__":
    main()
Python

2日目で本当に掴んでほしいこと

● メニュー形式は「アプリの基本構造」

繰り返し・条件分岐・関数がひとつにまとまると、 アプリらしさが一気に生まれます。

● 関数を分けることでアプリが整理される

変換処理を関数に分けることで、 アプリが「部品の集合」として理解しやすくなります。

● ファイル操作は「アプリに記憶を持たせる技術」

履歴が残ることで、 アプリが“道具”として使えるようになります。

次のステップ(3日目の予告)

3日目では、単位変換アプリをさらに育てて、

  • 逆変換(km → m、g → kg、℉ → ℃)
  • 入力値のチェック(条件分岐の応用)
  • 履歴の検索機能

という「探せる単位変換アプリ」へ進化させます。


単位変換アプリ 3日目のゴール

3日目のテーマは 「単位変換アプリを“探せる・逆変換できるアプリ”へ進化させ、変数・条件分岐・繰り返し・関数・ファイル操作をさらに深く理解すること」 です。

ここまででアプリは、

  • 長さ(m → km)
  • 重さ(kg → g)
  • 温度(℃ → ℉)
  • 履歴の保存・表示

という「複数の単位変換ができるアプリ」になりました。

3日目ではここに 逆変換(km → m、g → kg、℉ → ℃)履歴の検索機能 を追加し、 「探せる単位変換アプリ」へ進化させます。

逆変換とは何か(初心者向けにかみ砕いて)

逆変換とは 「元に戻す変換」 のことです。

例:

  • 1 km → 1000 m
  • 500 g → 0.5 kg
  • 98 ℉ → 36.6 ℃

逆変換を追加することで、 アプリがより実用的になります。

逆変換を追加する理由

  • 単位変換は「行き」と「戻り」がセットで使われることが多い
  • 計算式が変わるため、条件分岐の練習になる
  • 履歴検索と組み合わせると「探せるアプリ」になる

長さの逆変換(km → m)

def convert_km_to_m():
    """
    長さの逆変換(km → m)
    """
    km = float(input("キロメートルを入力してください: "))
    meter = km * 1000
    print(f"{km} km は {meter} m です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[長さ逆] {km} km → {meter} m\n")
Python

重さの逆変換(g → kg)

def convert_g_to_kg():
    """
    重さの逆変換(g → kg)
    """
    gram = float(input("グラムを入力してください: "))
    kg = gram / 1000
    print(f"{gram} g は {kg} kg です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[重さ逆] {gram} g → {kg} kg\n")
Python

温度の逆変換(℉ → ℃)

華氏 → 摂氏の計算式は ℃ = (℉ – 32) ÷ 1.8

def convert_f_to_c():
    """
    温度の逆変換(℉ → ℃)
    """
    fahrenheit = float(input("華氏(℉)を入力してください: "))
    celsius = (fahrenheit - 32) / 1.8
    print(f"{fahrenheit} ℉ は {celsius} ℃ です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[温度逆] {fahrenheit} ℉ → {celsius}\n")
Python

履歴検索機能(部分一致検索)

履歴はテキストファイルなので、 文字列検索(部分一致) を使います。

def search_history():
    """
    履歴をキーワードで検索する機能
    """
    keyword = input("検索したいキーワードを入力してください: ")

    try:
        with open("convert_history.txt", "r", encoding="utf-8") as f:
            lines = f.readlines()

        print(f"=== 履歴検索:{keyword} を含む行 ===")
        found = False

        for line in lines:
            if keyword in line:
                print(line.strip())
                found = True

        if not found:
            print("該当する履歴は見つかりませんでした。")

    except FileNotFoundError:
        print("まだ履歴がありません。")
Python

深掘りポイント

  • keyword in line → 部分一致検索
  • テキスト検索は「繰り返し+条件分岐+文字列処理」の総合練習
  • 履歴を扱うことで「ファイル操作の応用」が身につく

メニューに逆変換と検索を追加する

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 3日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 長さの逆変換(km → m)")
    print("5: 重さの逆変換(g → kg)")
    print("6: 温度の逆変換(℉ → ℃)")
    print("7: 履歴を見る")
    print("8: 履歴を検索する")
    print("9: 終了する")
    print("------------------------------")
Python

main に逆変換と検索機能を追加する

def main():
    print("Python 単位変換アプリ 3日目")
    print("逆変換と履歴検索ができるアプリに進化させます。")

    while True:
        show_menu()
        choice = input("番号を入力してください(1〜9): ")

        if choice == "1":
            convert_length()
        elif choice == "2":
            convert_weight()
        elif choice == "3":
            convert_temperature()
        elif choice == "4":
            convert_km_to_m()
        elif choice == "5":
            convert_g_to_kg()
        elif choice == "6":
            convert_f_to_c()
        elif choice == "7":
            show_history()
        elif choice == "8":
            search_history()
        elif choice == "9":
            print("単位変換アプリを終了します。おつかれさまでした。")
            break
        else:
            print("1〜9 の番号を入力してください。")
Python

3日目で本当に掴んでほしいこと

● 逆変換は「計算式が変わる」ため条件分岐の練習になる

単位変換は種類が増えるほど条件分岐が重要になります。

● 履歴検索は「文字列処理+繰り返し+条件分岐」の総合練習

テキスト検索はアプリ開発で頻出する技術です。

● 関数を分けることでアプリが整理される

逆変換・検索など機能が増えても、 関数で整理すれば迷わず拡張できます。

次のステップ(4日目の予告)

4日目では、単位変換アプリをさらに育てて、

  • 入力値のバリデーション(数値チェック)
  • エラー処理の追加
  • メニュー構造の改善

という「より安全で使いやすい単位変換アプリ」へ進化させます。


単位変換アプリ 4日目のゴール

4日目のテーマは 「単位変換アプリを“安全で使いやすいアプリ”へ進化させ、入力チェック(バリデーション)・エラー処理・条件分岐の応用を身につけること」 です。

ここまででアプリは、

  • 複数の単位変換(m→km、kg→g、℃→℉)
  • 逆変換(km→m、g→kg、℉→℃)
  • 履歴保存・履歴検索
  • メニュー形式

という「便利な単位変換アプリ」になりました。

しかし、実際に使うと次のような問題が出てきます。

  • 数字以外を入力するとエラーになる
  • 空文字を入力すると落ちる
  • マイナス値を入力してもそのまま計算されてしまう
  • メニュー番号を間違えると混乱する

そこで 4日目では、 入力チェック(バリデーション)+エラー処理 を追加し、 「安心して使える単位変換アプリ」へ進化させます。

入力チェック(バリデーション)とは何か

バリデーションとは 「入力された値が正しいかどうかを確認すること」 です。

例:

  • 数字かどうか
  • 空文字ではないか
  • マイナス値を許可するか
  • 許可されていない文字が入っていないか

これを行うことで、アプリが落ちることを防ぎます。

数値入力チェックの基本テンプレート

初心者が必ず覚えておきたいテンプレートです。

def get_float(prompt):
    """
    数値が入力されるまで繰り返し聞く関数
    """
    while True:
        value = input(prompt)

        # 空文字チェック
        if not value.strip():
            print("入力が空です。数値を入力してください。")
            continue

        # 数値チェック
        try:
            return float(value)
        except ValueError:
            print("数値を入力してください。")
Python

深掘りポイント

  • strip() → 空白を除去して空文字か確認
  • try / except → 数値変換できなければエラー処理
  • 正しい値が入るまで while True で繰り返す

この関数を使うことで、 すべての単位変換が安全に動くようになります。

長さ変換(m → km)を安全にする

def convert_length():
    """
    長さの単位変換(m → km)+入力チェック
    """
    meter = get_float("メートルを入力してください: ")
    kilometer = meter / 1000

    print(f"{meter} m は {kilometer} km です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[長さ] {meter} m → {kilometer} km\n")
Python

重さ変換(kg → g)を安全にする

def convert_weight():
    """
    重さの単位変換(kg → g)+入力チェック
    """
    kg = get_float("キログラムを入力してください: ")
    gram = kg * 1000

    print(f"{kg} kg は {gram} g です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[重さ] {kg} kg → {gram} g\n")
Python

温度変換(℃ → ℉)を安全にする

def convert_temperature():
    """
    温度の単位変換(℃ → ℉)+入力チェック
    """
    celsius = get_float("摂氏(℃)を入力してください: ")
    fahrenheit = celsius * 1.8 + 32

    print(f"{celsius} ℃ は {fahrenheit} ℉ です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[温度] {celsius} ℃ → {fahrenheit}\n")
Python

逆変換も安全にする

km → m

def convert_km_to_m():
    km = get_float("キロメートルを入力してください: ")
    meter = km * 1000
    print(f"{km} km は {meter} m です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[長さ逆] {km} km → {meter} m\n")
Python

g → kg

def convert_g_to_kg():
    gram = get_float("グラムを入力してください: ")
    kg = gram / 1000
    print(f"{gram} g は {kg} kg です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[重さ逆] {gram} g → {kg} kg\n")
Python

℉ → ℃

def convert_f_to_c():
    fahrenheit = get_float("華氏(℉)を入力してください: ")
    celsius = (fahrenheit - 32) / 1.8
    print(f"{fahrenheit} ℉ は {celsius} ℃ です。")

    with open("convert_history.txt", "a", encoding="utf-8") as f:
        f.write(f"[温度逆] {fahrenheit} ℉ → {celsius}\n")
Python

メニュー番号の入力チェック

メニュー番号も安全に扱います。

def get_menu_choice():
    """
    メニュー番号を安全に取得する
    """
    while True:
        choice = input("番号を入力してください(1〜9): ")

        if choice.isdigit():
            return int(choice)
        else:
            print("数字を入力してください。")
Python

メニュー(安全版)

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 4日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 長さの逆変換(km → m)")
    print("5: 重さの逆変換(g → kg)")
    print("6: 温度の逆変換(℉ → ℃)")
    print("7: 履歴を見る")
    print("8: 履歴を検索する")
    print("9: 終了する")
    print("------------------------------")
Python

main(安全版)

def main():
    print("Python 単位変換アプリ 4日目")
    print("入力チェックとエラー処理を追加して、安全なアプリにします。")

    while True:
        show_menu()
        choice = get_menu_choice()

        if choice == 1:
            convert_length()
        elif choice == 2:
            convert_weight()
        elif choice == 3:
            convert_temperature()
        elif choice == 4:
            convert_km_to_m()
        elif choice == 5:
            convert_g_to_kg()
        elif choice == 6:
            convert_f_to_c()
        elif choice == 7:
            show_history()
        elif choice == 8:
            search_history()
        elif choice == 9:
            print("単位変換アプリを終了します。おつかれさまでした。")
            break
Python

4日目で本当に掴んでほしいこと

● 入力チェックは「アプリを壊れにくくする技術」

ユーザーは必ず間違った入力をします。 その前提でアプリを作ることが重要です。

● try / except は初心者が必ず覚えるべき安全装置

数値変換・ファイル操作・ネット通信など、 あらゆる場面で使います。

● 関数を分けることで安全処理を再利用できる

get_float() を作ることで、 すべての単位変換が安全になります。

次のステップ(5日目の予告)

5日目では、単位変換アプリをさらに育てて、

  • JSON形式で履歴を保存する
  • 履歴を辞書のリストとして扱う
  • 検索・並び替えをより簡単にする

という「データ構造を強化した単位変換アプリ」へ進みます。


単位変換アプリ 5日目のゴール

5日目のテーマは 「履歴を“JSON形式で保存・読み込みできるアプリ”へ進化させ、データ構造を強化しながら変数・条件分岐・繰り返し・関数・ファイル操作を総復習すること」 です。

ここまでで単位変換アプリは、

  • 複数の単位変換
  • 逆変換
  • 履歴保存(テキスト)
  • 履歴検索
  • 入力チェック
  • メニュー形式

という「便利で安全な単位変換アプリ」になりました。

しかし、テキスト形式の履歴には弱点があります。

  • データ構造が扱いづらい
  • 検索・並び替えが複雑
  • 編集が難しい
  • 他のアプリと連携しにくい

そこで 5日目では、 履歴を JSON 形式で保存し、辞書のリストとして扱えるようにします。

これにより、履歴の検索・並び替え・編集が圧倒的に簡単になります。

JSONとは何か(初心者向けにかみ砕いて)

JSON(JavaScript Object Notation)は 「辞書やリストをそのまま保存できるファイル形式」 です。

例:

{
  "type": "長さ",
  "from": "m",
  "to": "km",
  "input": 500,
  "result": 0.5
}

Pythonの辞書とほぼ同じ形なので、 読み込むとそのまま辞書として使える という大きなメリットがあります。

今日やることの全体像

  • 履歴を JSON 形式で保存する
  • JSON 形式の履歴を読み込む
  • 履歴を辞書のリストとして扱う
  • 履歴を並び替える(種類順・入力値順)
  • 履歴を検索する(辞書のまま検索)

これにより、履歴機能が「データ管理アプリ」レベルに進化します。

JSONを扱うためのモジュール:json

Pythonには標準で json モジュールがあります。

  • json.dump() → 辞書やリストを JSONファイルに保存
  • json.load() → JSONファイルを辞書やリストとして読み込む

この2つを使うだけで、 データ構造をそのまま保存・読み込みできます。

JSON版:履歴を読み込む関数

import json

def load_history_json():
    """
    history.json を読み込んで、辞書のリストとして返す関数
    """
    try:
        with open("history.json", "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        return []  # 初回は空リスト
Python

深掘りポイント

  • JSON → Python辞書・リストへの変換
  • ファイルがないときは空リストで安全に動作

JSON版:履歴を保存する関数

def save_history_json(entries):
    """
    entries(辞書のリスト)を history.json に保存する
    """
    with open("history.json", "w", encoding="utf-8") as f:
        json.dump(entries, f, ensure_ascii=False, indent=2)
Python

深掘りポイント

  • indent=2 → 読みやすい整形済みJSON
  • ensure_ascii=False → 日本語をそのまま保存

JSON版:履歴を追加する関数(最重要)

すべての単位変換で共通して使えるようにします。

def add_history(entry):
    """
    1件分の履歴(辞書)を JSON に追加する
    """
    entries = load_history_json()
    entries.append(entry)
    save_history_json(entries)
Python

JSON版:長さ変換(m → km)

def convert_length():
    meter = get_float("メートルを入力してください: ")
    kilometer = meter / 1000
    print(f"{meter} m は {kilometer} km です。")

    entry = {
        "type": "長さ",
        "from": "m",
        "to": "km",
        "input": meter,
        "result": kilometer
    }
    add_history(entry)
Python

JSON版:重さ変換(kg → g)

def convert_weight():
    kg = get_float("キログラムを入力してください: ")
    gram = kg * 1000
    print(f"{kg} kg は {gram} g です。")

    entry = {
        "type": "重さ",
        "from": "kg",
        "to": "g",
        "input": kg,
        "result": gram
    }
    add_history(entry)
Python

JSON版:温度変換(℃ → ℉)

def convert_temperature():
    celsius = get_float("摂氏(℃)を入力してください: ")
    fahrenheit = celsius * 1.8 + 32
    print(f"{celsius} ℃ は {fahrenheit} ℉ です。")

    entry = {
        "type": "温度",
        "from": "℃",
        "to": "℉",
        "input": celsius,
        "result": fahrenheit
    }
    add_history(entry)
Python

JSON版:履歴一覧表示

def show_history_json():
    entries = load_history_json()

    if not entries:
        print("まだ履歴がありません。")
        return

    print("=== 履歴一覧(JSON) ===")
    for e in entries:
        print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
        print("------------------------------")
Python

JSON版:履歴検索(種類で検索)

def search_history_by_type():
    keyword = input("検索したい種類(長さ・重さ・温度): ")

    entries = load_history_json()

    found = False
    for e in entries:
        if keyword == e["type"]:
            print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
            print("------------------------------")
            found = True

    if not found:
        print("該当する履歴は見つかりませんでした。")
Python

JSON版:履歴を並び替える(入力値順)

def sort_history_by_input():
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    sorted_entries = sorted(entries, key=lambda e: e["input"])

    print("=== 入力値順に並び替えた履歴 ===")
    for e in sorted_entries:
        print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
        print("------------------------------")
Python

メニュー(JSON版)

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 5日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 履歴一覧(JSON)")
    print("5: 履歴検索(種類)")
    print("6: 履歴並び替え(入力値順)")
    print("7: 終了する")
    print("------------------------------")
Python

main(JSON版)

def main():
    print("Python 単位変換アプリ 5日目")
    print("履歴を JSON 形式で管理するアプリに進化させます。")

    while True:
        show_menu()
        choice = get_menu_choice()

        if choice == 1:
            convert_length()
        elif choice == 2:
            convert_weight()
        elif choice == 3:
            convert_temperature()
        elif choice == 4:
            show_history_json()
        elif choice == 5:
            search_history_by_type()
        elif choice == 6:
            sort_history_by_input()
        elif choice == 7:
            print("単位変換アプリを終了します。")
            break
Python

5日目で本当に掴んでほしいこと

● JSONは「辞書とリストをそのまま保存できる魔法の箱」

テキスト解析が不要になり、 データ管理が圧倒的に楽になります。

● 履歴を辞書のリストにすると検索・並び替えが簡単になる

  • sorted()
  • keyword == e["type"]
  • e["input"]

など、辞書のまま扱えるのが強力です。

● 関数を分けることでアプリが整理される

履歴追加・読み込み・保存を関数化することで、 アプリが「部品の集合」として理解しやすくなります。

次のステップ(6日目の予告)

6日目では、単位変換アプリをさらに育てて、

  • JSON履歴の編集
  • JSON履歴の削除
  • バックアップ機能

という「データ管理アプリとしての完成形」に近づけていきます。


単位変換アプリ 6日目のゴール

6日目のテーマは 「JSONで管理している履歴データを“編集・削除・バックアップできるアプリ”へ進化させ、データ管理アプリとしての完成形に近づけること」 です。

ここまでで単位変換アプリは、

  • 複数の単位変換
  • 逆変換
  • 入力チェック
  • 履歴の JSON 保存
  • 履歴検索・並び替え

という「安全で便利な単位変換アプリ」になりました。

6日目ではここに 履歴の編集・削除・バックアップ を追加し、 「履歴を自由に管理できるアプリ」へ進化させます。

JSON履歴を扱うための基本関数(復習)

履歴を読み込む

import json

def load_history_json():
    """
    history.json を読み込んで辞書のリストとして返す
    """
    try:
        with open("history.json", "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        return []
Python

履歴を保存する

def save_history_json(entries):
    """
    entries(辞書のリスト)を history.json に保存する
    """
    with open("history.json", "w", encoding="utf-8") as f:
        json.dump(entries, f, ensure_ascii=False, indent=2)
Python

履歴編集機能(最重要)

履歴は辞書のリストなので、 編集したい履歴を選んで辞書の値を書き換えるだけ で編集できます。

def edit_history():
    """
    履歴を編集する機能
    """
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    # 履歴一覧を番号付きで表示
    print("=== 編集可能な履歴一覧 ===")
    for i, e in enumerate(entries):
        print(f"{i}: [{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
    print("------------------------------")

    # 編集したい番号を取得
    index = input("編集したい履歴番号を入力してください: ")

    if not index.isdigit() or int(index) >= len(entries):
        print("正しい番号を入力してください。")
        return

    index = int(index)
    target = entries[index]

    print("=== 現在の内容 ===")
    print(f"種類: {target['type']}")
    print(f"入力値: {target['input']}")
    print(f"変換前単位: {target['from']}")
    print(f"変換後単位: {target['to']}")
    print(f"結果: {target['result']}")

    # 新しい値を入力(空なら変更なし)
    new_input = input("新しい入力値(空なら変更なし): ")
    new_result = input("新しい結果(空なら変更なし): ")

    if new_input.strip():
        try:
            target["input"] = float(new_input)
        except ValueError:
            print("数値を入力してください。")
            return

    if new_result.strip():
        try:
            target["result"] = float(new_result)
        except ValueError:
            print("数値を入力してください。")
            return

    save_history_json(entries)
    print("履歴を編集しました。")
Python

深掘りポイント

  • 辞書の値を書き換えるだけで編集できる
  • 番号で選ぶ方式は初心者にとって扱いやすい
  • 数値チェックは try / except で安全に処理

履歴削除機能

削除は「残したいものだけを新しいリストに集める」ことで実現できます。

def delete_history():
    """
    履歴を削除する機能
    """
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    print("=== 削除可能な履歴一覧 ===")
    for i, e in enumerate(entries):
        print(f"{i}: [{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
    print("------------------------------")

    index = input("削除したい履歴番号を入力してください: ")

    if not index.isdigit() or int(index) >= len(entries):
        print("正しい番号を入力してください。")
        return

    index = int(index)

    # 削除処理(番号以外のものを残す)
    new_entries = [e for i2, e in enumerate(entries) if i2 != index]

    save_history_json(new_entries)
    print("履歴を削除しました。")
Python

深掘りポイント

  • リスト内包表記で削除が簡単に書ける
  • 番号で選ぶ方式はミスが少ない
  • JSON保存なのでデータ構造が壊れない

履歴バックアップ機能

バックアップは「ファイルを丸ごとコピーする」だけでOKです。

def backup_history():
    """
    history.json をバックアップする機能
    """
    try:
        with open("history.json", "r", encoding="utf-8") as f:
            data = f.read()

        with open("history_backup.json", "w", encoding="utf-8") as bf:
            bf.write(data)

        print("バックアップを作成しました。(history_backup.json)")
    except FileNotFoundError:
        print("まだ履歴がありません。")
Python

メニュー(編集・削除・バックアップ追加版)

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 6日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 履歴一覧(JSON)")
    print("5: 履歴検索(種類)")
    print("6: 履歴並び替え(入力値順)")
    print("7: 履歴を編集する")
    print("8: 履歴を削除する")
    print("9: 履歴をバックアップする")
    print("10: 終了する")
    print("------------------------------")
Python

main(編集・削除・バックアップ対応版)

def main():
    print("Python 単位変換アプリ 6日目")
    print("履歴を編集・削除・バックアップできるアプリに進化させます。")

    while True:
        show_menu()
        choice = get_menu_choice()

        if choice == 1:
            convert_length()
        elif choice == 2:
            convert_weight()
        elif choice == 3:
            convert_temperature()
        elif choice == 4:
            show_history_json()
        elif choice == 5:
            search_history_by_type()
        elif choice == 6:
            sort_history_by_input()
        elif choice == 7:
            edit_history()
        elif choice == 8:
            delete_history()
        elif choice == 9:
            backup_history()
        elif choice == 10:
            print("単位変換アプリを終了します。")
            break
Python

6日目で本当に掴んでほしいこと

● JSONは「辞書のリストをそのまま保存できる」

編集・削除が圧倒的に簡単になります。

● 編集は「辞書の値を書き換えるだけ」

テキスト解析が不要になるため、コードが短くなる。

● 削除は「残したいものだけを集める」

リスト内包表記が非常に強力です。

● バックアップは「読み込み → 書き込み」でOK

実用的なアプリでは必須の安全機能です。

次のステップ(7日目の予告)

7日目では、単位変換アプリを完成版として整理し、

  • コード構造の最終調整
  • 関数の再整理
  • メニューの改善
  • 全体の仕上げ

という「完成版単位変換アプリ」を作ります。


単位変換アプリ 7日目のゴール

7日目のテーマは 「6日間で積み上げてきた機能を“ひとつの完成アプリ”としてまとめ、変数・条件分岐・繰り返し・関数・ファイル操作を総復習しながらコード構造を理解すること」 です。

ここまでで単位変換アプリは、

  • 複数の単位変換(長さ・重さ・温度)
  • 逆変換
  • 入力チェック(バリデーション)
  • 履歴の JSON 保存
  • 履歴検索・並び替え
  • 履歴編集・削除・バックアップ

という、初級者が学ぶべき機能をすべて体験してきました。

7日目では、これらを 「完成版単位変換アプリ」 として整理し、 アプリの構造を理解しながら、どこをどう改善できるかまで見えるようにします。

完成アプリの構造を理解する

単位変換アプリは、次のような構造でできています。

● データ構造(JSON)

  • 1件分の履歴 → 辞書
  • 全体 → 辞書のリスト
  • 保存形式 → history.json

● 機能(関数)

  • 変換(長さ・重さ・温度)
  • 逆変換(長さ・重さ・温度)
  • 履歴一覧表示
  • 履歴検索(種類)
  • 履歴並び替え(入力値順)
  • 履歴編集
  • 履歴削除
  • バックアップ
  • 入力チェック(get_float / get_menu_choice)
  • JSON読み込み・保存
  • メニュー表示
  • アプリ全体の流れ(main)

● アプリの流れ(main)

  • メニューを表示
  • ユーザーの選択を受け取る
  • 条件分岐で機能を呼び出す
  • while で繰り返す

この構造は、 どんなコンソールアプリでも応用できる基本パターン です。

JSON読み込み関数(完成版)

import json

def load_history_json():
    """
    history.json を読み込んで辞書のリストとして返す
    """
    try:
        with open("history.json", "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        return []
Python

JSON保存関数(完成版)

def save_history_json(entries):
    """
    entries(辞書のリスト)を history.json に保存する
    """
    with open("history.json", "w", encoding="utf-8") as f:
        json.dump(entries, f, ensure_ascii=False, indent=2)
Python

履歴追加関数(完成版)

def add_history(entry):
    entries = load_history_json()
    entries.append(entry)
    save_history_json(entries)
Python

入力チェック関数(完成版)

def get_float(prompt):
    while True:
        value = input(prompt)
        if not value.strip():
            print("入力が空です。数値を入力してください。")
            continue
        try:
            return float(value)
        except ValueError:
            print("数値を入力してください。")
Python

メニュー番号チェック(完成版)

def get_menu_choice():
    while True:
        choice = input("番号を入力してください: ")
        if choice.isdigit():
            return int(choice)
        print("数字を入力してください。")
Python

変換機能(長さ・重さ・温度)

長さ(m → km)

def convert_length():
    meter = get_float("メートルを入力してください: ")
    kilometer = meter / 1000
    print(f"{meter} m は {kilometer} km です。")

    entry = {
        "type": "長さ",
        "from": "m",
        "to": "km",
        "input": meter,
        "result": kilometer
    }
    add_history(entry)
Python

重さ(kg → g)

def convert_weight():
    kg = get_float("キログラムを入力してください: ")
    gram = kg * 1000
    print(f"{kg} kg は {gram} g です。")

    entry = {
        "type": "重さ",
        "from": "kg",
        "to": "g",
        "input": kg,
        "result": gram
    }
    add_history(entry)
Python

温度(℃ → ℉)

def convert_temperature():
    celsius = get_float("摂氏(℃)を入力してください: ")
    fahrenheit = celsius * 1.8 + 32
    print(f"{celsius} ℃ は {fahrenheit} ℉ です。")

    entry = {
        "type": "温度",
        "from": "℃",
        "to": "℉",
        "input": celsius,
        "result": fahrenheit
    }
    add_history(entry)
Python

逆変換機能(完成版)

km → m

def convert_km_to_m():
    km = get_float("キロメートルを入力してください: ")
    meter = km * 1000
    print(f"{km} km は {meter} m です。")

    entry = {
        "type": "長さ逆",
        "from": "km",
        "to": "m",
        "input": km,
        "result": meter
    }
    add_history(entry)
Python

g → kg

def convert_g_to_kg():
    gram = get_float("グラムを入力してください: ")
    kg = gram / 1000
    print(f"{gram} g は {kg} kg です。")

    entry = {
        "type": "重さ逆",
        "from": "g",
        "to": "kg",
        "input": gram,
        "result": kg
    }
    add_history(entry)
Python

℉ → ℃

def convert_f_to_c():
    fahrenheit = get_float("華氏(℉)を入力してください: ")
    celsius = (fahrenheit - 32) / 1.8
    print(f"{fahrenheit} ℉ は {celsius} ℃ です。")

    entry = {
        "type": "温度逆",
        "from": "℉",
        "to": "℃",
        "input": fahrenheit,
        "result": celsius
    }
    add_history(entry)
Python

履歴一覧表示(完成版)

def show_history_json():
    entries = load_history_json()

    if not entries:
        print("まだ履歴がありません。")
        return

    print("=== 履歴一覧 ===")
    for e in entries:
        print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
        print("------------------------------")
Python

履歴検索(種類)

def search_history_by_type():
    keyword = input("検索したい種類(長さ・重さ・温度など): ")

    entries = load_history_json()
    found = False

    for e in entries:
        if keyword in e["type"]:
            print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
            print("------------------------------")
            found = True

    if not found:
        print("該当する履歴は見つかりませんでした。")
Python

履歴並び替え(入力値順)

def sort_history_by_input():
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    sorted_entries = sorted(entries, key=lambda e: e["input"])

    print("=== 入力値順に並び替えた履歴 ===")
    for e in sorted_entries:
        print(f"[{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
        print("------------------------------")
Python

履歴編集(完成版)

def edit_history():
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    print("=== 編集可能な履歴一覧 ===")
    for i, e in enumerate(entries):
        print(f"{i}: [{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
    print("------------------------------")

    index = input("編集したい番号を入力してください: ")

    if not index.isdigit() or int(index) >= len(entries):
        print("正しい番号を入力してください。")
        return

    index = int(index)
    target = entries[index]

    print("=== 現在の内容 ===")
    print(target)

    new_input = input("新しい入力値(空なら変更なし): ")
    new_result = input("新しい結果(空なら変更なし): ")

    if new_input.strip():
        target["input"] = float(new_input)
    if new_result.strip():
        target["result"] = float(new_result)

    save_history_json(entries)
    print("履歴を編集しました。")
Python

履歴削除(完成版)

def delete_history():
    entries = load_history_json()

    if not entries:
        print("履歴がありません。")
        return

    print("=== 削除可能な履歴一覧 ===")
    for i, e in enumerate(entries):
        print(f"{i}: [{e['type']}] {e['input']} {e['from']}{e['result']} {e['to']}")
    print("------------------------------")

    index = input("削除したい番号を入力してください: ")

    if not index.isdigit() or int(index) >= len(entries):
        print("正しい番号を入力してください。")
        return

    index = int(index)
    new_entries = [e for i2, e in enumerate(entries) if i2 != index]

    save_history_json(new_entries)
    print("履歴を削除しました。")
Python

バックアップ(完成版)

def backup_history():
    try:
        with open("history.json", "r", encoding="utf-8") as f:
            data = f.read()

        with open("history_backup.json", "w", encoding="utf-8") as bf:
            bf.write(data)

        print("バックアップを作成しました。(history_backup.json)")
    except FileNotFoundError:
        print("まだ履歴がありません。")
Python

メニュー(完成版)

def show_menu():
    print("------------------------------")
    print("Python 単位変換アプリ 7日目 メニュー")
    print("1: 長さの変換(m → km)")
    print("2: 重さの変換(kg → g)")
    print("3: 温度の変換(℃ → ℉)")
    print("4: 長さの逆変換(km → m)")
    print("5: 重さの逆変換(g → kg)")
    print("6: 温度の逆変換(℉ → ℃)")
    print("7: 履歴一覧(JSON)")
    print("8: 履歴検索(種類)")
    print("9: 履歴並び替え(入力値順)")
    print("10: 履歴編集")
    print("11: 履歴削除")
    print("12: バックアップ作成")
    print("13: 終了する")
    print("------------------------------")
Python

main(完成版)

def main():
    print("Python 単位変換アプリ 7日目")
    print("JSON形式で履歴を管理する完成版アプリです。")

    while True:
        show_menu()
        choice = get_menu_choice()

        if choice == 1:
            convert_length()
        elif choice == 2:
            convert_weight()
        elif choice == 3:
            convert_temperature()
        elif choice == 4:
            convert_km_to_m()
        elif choice == 5:
            convert_g_to_kg()
        elif choice == 6:
            convert_f_to_c()
        elif choice == 7:
            show_history_json()
        elif choice == 8:
            search_history_by_type()
        elif choice == 9:
            sort_history_by_input()
        elif choice == 10:
            edit_history()
        elif choice == 11:
            delete_history()
        elif choice == 12:
            backup_history()
        elif choice == 13:
            print("終了します。")
            break
        else:
            print("1〜13 を入力してください。")
Python

7日目で本当に掴んでほしいこと

● JSONは「辞書とリストをそのまま保存できる魔法の箱」

テキスト解析が不要になり、 データ管理が圧倒的に楽になります。

● アプリは「メインループ+機能の集合」でできている

この構造を理解すると、 どんなコンソールアプリでも作れるようになります。

● 関数を分けることでアプリが整理される

機能ごとに分けることで、 アプリが「部品の集合」として理解しやすくなります。

次のステップ(応用編への橋)

この単位変換アプリはまだまだ育てられます。

  • GUI版(画面付きアプリ)
  • Webアプリ化(Flask)
  • 履歴のグラフ化(matplotlib)
  • 単位変換の種類を増やす(速度・面積・体積など)

7日間の学習を終えた読者は、 もう Pythonで実用的なアプリを作れる人 です。

タイトルとURLをコピーしました