Python | レベル別練習問題:モジュールと import

Python
スポンサーリンク

では次に出力するのは、
「3ファイル構成で完全自動採点できるモジュール練習セット」です。


構成概要

modules_quiz_set/
├── quiz.py      ← 問題文・TODOつき(受講者が編集する)
├── answers.py   ← 正答例(非公開想定 or チェック用)
└── grader.py    ← 自動採点スクリプト(実行用)

機能概要

ファイル役割内容
quiz.py問題定義Q1〜Q50の空欄関数 (# TODO: 付き)
answers.py模範解答各問題の正答実装
grader.py採点実行answersquiz を比較してスコア出力

特徴

全50問(基礎〜応用)対応
import / モジュール / パッケージ / 外部ライブラリ を総網羅
grader.py を実行するだけで正誤判定+採点結果表示
quiz.py に書いた解答と answers.py の模範を比較


ではまず、quiz.py(学習者用ファイル)
このファイルは受講者が回答を記入する用で、# TODO: 部分を埋める形になります。
実行・採点はあとで作る grader.py で自動判定されます。


quiz.py(学習者用・全50問)

"""
Python モジュール入門 練習問題集(学習者用)
======================================================
このファイルは、自動採点対応の練習問題セットです。
# TODO: と書かれた箇所を埋めて、自分の解答を記入してください。

採点は grader.py を実行します:
    $ python grader.py
"""

# ======================================================
# Q1〜Q10: import の基本
# ======================================================

# Q1: math モジュールをインポートし、pi の値を返す関数を作ろう
def q1():
    # TODO: math モジュールを使って π を返す
    pass


# Q2: math.sqrt() を使って、引数xの平方根を返す関数
def q2(x):
    # TODO: math モジュールを利用
    pass


# Q3: random モジュールを使って、1〜6のサイコロを1回振る関数
def q3():
    # TODO: random.randint を使用
    pass


# Q4: datetime.date.today() を使って、今日の日付を返す関数
def q4():
    # TODO
    pass


# Q5: os モジュールを使って、現在の作業ディレクトリ(cwd)を返す関数
def q5():
    # TODO
    pass


# Q6: sys モジュールを使って、Python のバージョン文字列を返す関数
def q6():
    # TODO
    pass


# Q7: import した math モジュールを別名 m として使い、cos(0) の結果を返す関数
def q7():
    # TODO: import math as m
    pass


# Q8: from math import factorial として、5! の結果を返す関数
def q8():
    # TODO
    pass


# Q9: from random import choice を使って、["A","B","C"] の中から1つランダムに返す関数
def q9():
    # TODO
    pass


# Q10: from datetime import datetime として、現在の年を int で返す関数
def q10():
    # TODO
    pass


# ======================================================
# Q11〜Q20: パッケージとモジュールの使い方
# ======================================================

# Q11: import math, random を同時に行う関数(戻り値: どちらのモジュールも使って何かを返す)
def q11():
    # TODO: math.pi * random.random() の結果など
    pass


# Q12: import を関数内で行い、math.pow(2, 3) を返す
def q12():
    # TODO
    pass


# Q13: sys.path の最初の要素(検索パス)を返す
def q13():
    # TODO
    pass


# Q14: importlib を使って math モジュールを動的に読み込む
def q14():
    # TODO: importlib.import_module("math")
    pass


# Q15: os.path モジュールを使って、ファイル名 "test.txt" の絶対パスを返す
def q15():
    # TODO
    pass


# Q16: pathlib.Path を使って、カレントディレクトリのファイル一覧を list で返す
def q16():
    # TODO
    pass


# Q17: json モジュールで {"a":1,"b":2} を JSON文字列に変換
def q17():
    # TODO: json.dumps を使用
    pass


# Q18: json モジュールで '{"x":10}' を Python の dict に変換
def q18():
    # TODO: json.loads
    pass


# Q19: statistics モジュールで [1,2,3,4,5] の平均値を返す
def q19():
    # TODO
    pass


# Q20: decimal.Decimal を使って、0.1 + 0.2 の正確な合計を返す
def q20():
    # TODO
    pass


# ======================================================
# Q21〜Q30: 独自モジュール・ファイル操作
# ======================================================

# Q21: 独自モジュール mymod.py を import して hello() 関数を呼び出す(仮定)
def q21():
    # TODO: import mymod; mymod.hello()
    pass


# Q22: try/except でモジュールが見つからない場合に "Not Found" を返す
def q22():
    # TODO: import 不可例外処理
    pass


# Q23: os.listdir('.') を使って、フォルダ内ファイル数を返す
def q23():
    # TODO
    pass


# Q24: csv モジュールで [["a",1],["b",2]] を CSV 文字列に変換して返す
def q24():
    # TODO: io.StringIO + csv.writer
    pass


# Q25: re モジュールで "a1b2c3" から数字だけを抽出して list で返す
def q25():
    # TODO
    pass


# Q26: itertools モジュールで [1,2,3] の全ての順列を list で返す
def q26():
    # TODO
    pass


# Q27: collections.Counter を使って "apple" の文字頻度を dict で返す
def q27():
    # TODO
    pass


# Q28: time モジュールを使って、現在のUNIXタイム(float)を返す
def q28():
    # TODO
    pass


# Q29: calendar モジュールで 2025年11月のカレンダーを multi-line 文字列で返す
def q29():
    # TODO
    pass


# Q30: tempfile モジュールで一時ファイルを作成し、そのパスを返す
def q30():
    # TODO
    pass


# ======================================================
# Q31〜Q40: 応用・例外処理・外部ライブラリ
# ======================================================

# Q31: import numpy as np として np.arange(5) をリストで返す
def q31():
    # TODO
    pass


# Q32: import pandas as pd として DataFrame の列名を list で返す
def q32():
    # TODO: DataFrame({"x":[1,2],"y":[3,4]})
    pass


# Q33: import math 失敗時に ValueError("module not found") を発生させる関数
def q33():
    # TODO
    pass


# Q34: importlib.util.find_spec を使って "math" モジュールが存在するか bool で返す
def q34():
    # TODO
    pass


# Q35: sys.modules の中に "math" が含まれているか確認して bool で返す
def q35():
    # TODO
    pass


# Q36: os.environ を使って、環境変数 PATH の値を返す
def q36():
    # TODO
    pass


# Q37: uuid モジュールを使って、一意の文字列IDを返す
def q37():
    # TODO
    pass


# Q38: hashlib モジュールで "abc" の md5 ハッシュを返す
def q38():
    # TODO
    pass


# Q39: base64 モジュールで "hello" をエンコードした文字列を返す
def q39():
    # TODO
    pass


# Q40: argparse モジュールを使って、引数 "--name Alice" の解析結果をシミュレーションして返す
def q40():
    # TODO
    pass


# ======================================================
# Q41〜Q50: 応用・型ヒント・複合問題
# ======================================================

# Q41: typing.List を使って、引数 list[int] の平均値を返す(型ヒント付き)
def q41(nums: list[int]) -> float:
    # TODO
    pass


# Q42: import typing.Optional を使って、Noneなら"empty"、文字列ならそのまま返す
def q42(value: str | None) -> str:
    # TODO
    pass


# Q43: import math, random を組み合わせて、cos(π×乱数) の結果を返す
def q43():
    # TODO
    pass


# Q44: zipfile モジュールで test.zip を作成し、"done" を返す
def q44():
    # TODO
    pass


# Q45: shutil モジュールでファイルコピー(例: a.txt→b.txt)を実行し、"copied" を返す
def q45():
    # TODO
    pass


# Q46: subprocess モジュールを使って "echo hello" を実行し、出力文字列を返す
def q46():
    # TODO
    pass


# Q47: inspect モジュールで q1 関数のソースコード文字列を返す
def q47():
    # TODO
    pass


# Q48: importlib.reload を使って、math モジュールを再読み込みする関数
def q48():
    # TODO
    pass


# Q49: importlib.metadata.version("pip") を使って pip のバージョンを返す
def q49():
    # TODO
    pass


# Q50: ここまでの総まとめ — 主要モジュール10個以上をimportし、それぞれの属性を1つずつ利用してdictで返す
def q50():
    # TODO: {"math": math.pi, "os": os.name, ...}
    pass
Python

では次に、answers.py(模範解答ファイル)
このファイルには、すべての問題(Q1〜Q50)の正しい実装例が含まれています。
grader.py からこのファイルをインポートして、自動採点に利用します。


answers.py(模範解答・全50問)

"""
answers.py
======================================================
Python モジュール入門 練習問題(模範解答)
"""

import math
import random
import datetime
import os
import sys
import importlib
import json
import statistics
import decimal
import re
import itertools
import collections
import time
import calendar
import tempfile
import uuid
import hashlib
import base64
import inspect
import subprocess
import shutil
import zipfile
import importlib.metadata
from pathlib import Path
from typing import Optional

# ======================================================
# Q1〜Q10
# ======================================================

def q1():
    import math
    return math.pi

def q2(x):
    import math
    return math.sqrt(x)

def q3():
    import random
    return random.randint(1, 6)

def q4():
    import datetime
    return datetime.date.today()

def q5():
    import os
    return os.getcwd()

def q6():
    import sys
    return sys.version

def q7():
    import math as m
    return m.cos(0)

def q8():
    from math import factorial
    return factorial(5)

def q9():
    from random import choice
    return choice(["A", "B", "C"])

def q10():
    from datetime import datetime
    return datetime.now().year


# ======================================================
# Q11〜Q20
# ======================================================

def q11():
    import math, random
    return math.pi * random.random()

def q12():
    import math
    return math.pow(2, 3)

def q13():
    import sys
    return sys.path[0]

def q14():
    import importlib
    m = importlib.import_module("math")
    return hasattr(m, "sqrt")

def q15():
    import os
    return os.path.abspath("test.txt")

def q16():
    from pathlib import Path
    return [p.name for p in Path(".").iterdir()]

def q17():
    import json
    return json.dumps({"a": 1, "b": 2})

def q18():
    import json
    return json.loads('{"x":10}')

def q19():
    import statistics
    return statistics.mean([1,2,3,4,5])

def q20():
    from decimal import Decimal
    return Decimal("0.1") + Decimal("0.2")


# ======================================================
# Q21〜Q30
# ======================================================

def q21():
    try:
        import mymod
        return mymod.hello()
    except Exception:
        return "mymod not found"

def q22():
    try:
        import not_exist_mod
    except ModuleNotFoundError:
        return "Not Found"

def q23():
    import os
    return len(os.listdir("."))

def q24():
    import csv, io
    data = [["a",1],["b",2]]
    f = io.StringIO()
    w = csv.writer(f)
    w.writerows(data)
    return f.getvalue().strip()

def q25():
    import re
    return re.findall(r"\d+", "a1b2c3")

def q26():
    import itertools
    return list(itertools.permutations([1,2,3]))

def q27():
    from collections import Counter
    return dict(Counter("apple"))

def q28():
    import time
    return time.time()

def q29():
    import calendar
    return calendar.month(2025, 11)

def q30():
    import tempfile
    with tempfile.NamedTemporaryFile(delete=False) as f:
        return f.name


# ======================================================
# Q31〜Q40
# ======================================================

def q31():
    import numpy as np
    return list(np.arange(5))

def q32():
    import pandas as pd
    df = pd.DataFrame({"x":[1,2],"y":[3,4]})
    return list(df.columns)

def q33():
    try:
        import math
    except ModuleNotFoundError:
        raise ValueError("module not found")
    return True

def q34():
    import importlib.util
    return importlib.util.find_spec("math") is not None

def q35():
    import sys
    import math
    return "math" in sys.modules

def q36():
    import os
    return os.environ.get("PATH", "")

def q37():
    import uuid
    return str(uuid.uuid4())

def q38():
    import hashlib
    return hashlib.md5(b"abc").hexdigest()

def q39():
    import base64
    return base64.b64encode(b"hello").decode()

def q40():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--name")
    args = parser.parse_args(["--name", "Alice"])
    return args.name


# ======================================================
# Q41〜Q50
# ======================================================

def q41(nums: list[int]) -> float:
    return sum(nums) / len(nums)

def q42(value: Optional[str]) -> str:
    return "empty" if value is None else value

def q43():
    import math, random
    return math.cos(math.pi * random.random())

def q44():
    import zipfile
    with zipfile.ZipFile("test.zip", "w") as zf:
        zf.writestr("sample.txt", "ok")
    return "done"

def q45():
    import shutil
    open("a.txt", "w").write("x")
    shutil.copy("a.txt", "b.txt")
    return "copied"

def q46():
    import subprocess
    result = subprocess.run(["echo", "hello"], capture_output=True, text=True)
    return result.stdout.strip()

def q47():
    import inspect
    return inspect.getsource(q1)

def q48():
    import importlib, math
    return importlib.reload(math)

def q49():
    import importlib.metadata
    return importlib.metadata.version("pip")

def q50():
    import math, os, sys, json, random, re, statistics, hashlib, time, datetime
    return {
        "math": math.pi,
        "os": os.name,
        "sys": bool(sys.version),
        "json": json.dumps({"ok": True}),
        "random": random.randint(0,1),
        "re": bool(re.search("a", "apple")),
        "statistics": statistics.mean([1,2,3]),
        "hashlib": hashlib.md5(b"x").hexdigest(),
        "time": int(time.time()),
        "datetime": datetime.datetime.now().year,
    }
Python

では最後に、全自動採点が可能な grader.py(自動採点スクリプト)
このスクリプトを実行するだけで、quiz.py の全50問を模範解答 (answers.py) と照合して採点します。
得点集計・部分一致判定・差分表示なども対応しています。


grader.py(全自動採点スクリプト)

"""
grader.py
======================================================
Python モジュール入門 練習問題 自動採点スクリプト

使い方:
    $ python grader.py

同じフォルダに quiz.py と answers.py があることを確認してください。
"""

import importlib
import inspect
import traceback
import math
import difflib
import json

# 対象ファイル
QUIZ_FILE = "quiz"
ANSWER_FILE = "answers"

# インポート
quiz = importlib.import_module(QUIZ_FILE)
answers = importlib.import_module(ANSWER_FILE)

# 採点結果格納
results = []

def is_equal(expected, actual):
    """柔軟な比較関数(型違い・順序違いを吸収)"""
    if isinstance(expected, float) and isinstance(actual, float):
        return math.isclose(expected, actual, rel_tol=1e-9)
    if isinstance(expected, (list, tuple)) and isinstance(actual, (list, tuple)):
        return list(expected) == list(actual)
    if isinstance(expected, dict) and isinstance(actual, dict):
        return expected == actual
    if isinstance(expected, (int, str, bool)):
        return expected == actual
    # JSON文字列比較対応
    try:
        e_json = json.loads(expected) if isinstance(expected, str) else expected
        a_json = json.loads(actual) if isinstance(actual, str) else actual
        if e_json == a_json:
            return True
    except Exception:
        pass
    return expected == actual

def grade():
    score = 0
    total = 50
    print("🧩 Python モジュール入門 自動採点 開始\n")

    for i in range(1, total + 1):
        qname = f"q{i}"
        qf = getattr(quiz, qname, None)
        af = getattr(answers, qname, None)
        if not callable(qf) or not callable(af):
            print(f"❌ Q{i:02d}: 関数が定義されていません")
            continue

        try:
            # 引数の数を確認して自動的に呼び出す
            argspec = inspect.getfullargspec(af)
            args = [1] if argspec.args else []
            expected = af(*args)
            actual = qf(*args)
            ok = is_equal(expected, actual)
        except Exception as e:
            ok = False
            actual = f"エラー: {type(e).__name__}"
            expected = None

        if ok:
            score += 1
            print(f"✅ Q{i:02d}: OK")
        else:
            print(f"❌ Q{i:02d}: NG")
            print(f"    期待値: {expected}")
            print(f"    あなたの出力: {actual}")

            # 差分ヒント(文字列の場合)
            if isinstance(expected, str) and isinstance(actual, str):
                diff = difflib.ndiff(expected.splitlines(), actual.splitlines())
                print("    差分:")
                for d in diff:
                    if d.startswith("+ ") or d.startswith("- "):
                        print("     ", d)

    print("\n===============================")
    print(f"結果: {score} / {total} 点 ({(score/total)*100:.1f}%)")
    print("===============================")
    if score == total:
        print("🎉 全問正解!おめでとうございます!")
    elif score >= total * 0.8:
        print("👍 よくできました!もう一歩です。")
    else:
        print("💡 間違いを確認して、再挑戦しましょう。")

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

✅ 使い方まとめ

  1. 同じフォルダに以下3ファイルを置きます: quiz.py answers.py grader.py
  2. 学習者は quiz.py# TODO: を埋めていきます。
  3. 採点を実行: $ python grader.py
  4. 結果例: ✅ Q01: OK ❌ Q02: NG 期待値: 4.0 あなたの出力: 2 ... 結果: 47 / 50 点 (94.0%) 👍 よくできました!
Python
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました