# GESP等级：三级 | GESP Python 三级考点

"""
12第1节 · import与random——打开工具箱，摇骰子抽签
==================================================
课程对应：
  - 00:00-10:00 导入：工具箱比喻→import=打开工具箱
  - 10:00-30:00 知识点：①import random ②from...import ③randint摇骰子
                     ④choice抽签 ⑤random()0-1小数 ⑥uniform范围小数
  - 30:00-40:00 演示：random.choice(["red","blue","green"])随机颜色画圆
  - 40:00-55:00 实操：①填空import语法 ②randint摇骰子 ③choice随机颜色画彩虹
  - 55:00-60:00 小测："randint(1,6)可能返回?"
  - GESP 考点：#33 模块导入概念、#34 random模块基础应用

运行方式：
  每个函数独立运行，按教学节奏调用。
"""

import turtle
import random
import time


# ============================================================
# 阶段一：导入——工具箱比喻（00:00-10:00）
# ============================================================
def demo_intro_toolbox():
    """
    用"工具箱"比喻引入模块概念。
    老师演示：没有工具箱的烦恼 vs 有了工具箱的便利。
    """
    print("=" * 60)
    print(" 导入——工具箱比喻：import = 打开工具箱")
    print("=" * 60)
    print()

    print('场景：你想"摇骰子"得到一个1~6的随机数——')
    print()

    # ========== 第1步：没有工具箱 ==========
    print("--- 第1步：没有工具箱——自己造轮子 ---")
    print()
    print("  如果没有 random 模块，你需要自己写随机算法……")
    print("  → 太复杂了！而且容易出错！")
    print()

    # ========== 第2步：认识工具箱 ==========
    print("--- 第2步：认识工具箱（模块）---")
    print()
    print("  Python 自带了很多'工具箱'，每个工具箱里有专用的工具：")
    print()
    print("  ┌─────────────────────────────────────────────┐")
    print("  │  工具箱名      │   工具（函数）              │")
    print("  ├─────────────────────────────────────────────┤")
    print("  │  random        │  randint, choice, random…  │")
    print("  │  turtle        │  Turtle, forward, color…   │")
    print("  │  math          │  sqrt, pi, sin, cos…       │")
    print("  │  time          │  sleep, time…              │")
    print("  └─────────────────────────────────────────────┘")
    print()

    # ========== 第3步：两种打开工具箱的方式 ==========
    print("--- 第3步：两种打开方式 ---")
    print()
    print("  🔑 方式一：把整个工具箱搬到面前")
    print("     import random")
    print("     使用：random.randint(1, 6)    ← 要写工具箱名")
    print()
    print("  🔑 方式二：只拿一个工具放口袋")
    print("     from random import randint")
    print("     使用：randint(1, 6)           ← 直接用！")
    print()

    print("🎯 总结：")
    print("  模块（模块）= 工具箱")
    print("  import = 打开工具箱")
    print("  记忆钩子：'import = 打开工具箱'")
    print("  'randint = 摇骰子'")
    print("  'choice = 抽签'")


# ============================================================
# 阶段二：知识点讲解（10:00-30:00）
# ============================================================
def knowledge_import_all():
    """知识点①：import random 全部导入"""
    print("=" * 60)
    print(" 知识点①：import random 全部导入")
    print("=" * 60)
    print()

    print("--- 语法 ---")
    print("  import random")
    print()
    print("--- 示例 ---")
    import random as r1  # 临时使用别名避免污染
    print(f"  random.randint(1, 6)  = {r1.randint(1, 6)}   ← 摇骰子")
    print(f"  random.choice(['A','B','C']) = {r1.choice(['A','B','C'])}   ← 抽签")
    print(f"  random.random()       = {r1.random()}   ← 0~1小数")
    print(f"  random.uniform(1,10)  = {r1.uniform(1, 10)}   ← 范围小数")
    print()

    print("--- 特点 ---")
    print("  ① 导入整个 random 模块")
    print("  ② 使用时要加 random. 前缀 → random.函数名()")
    print("  ③ 导入一次，所有 random 函数都能用")
    print()

    print("💡 记忆钩子：import = 打开工具箱")
    print("   用的时候要写工具箱名 → random.函数名()")


def knowledge_import_from():
    """知识点②：from random import choice 部分导入"""
    print("=" * 60)
    print(" 知识点②：from ... import 部分导入")
    print("=" * 60)
    print()

    print("--- 语法 ---")
    print("  from 模块名 import 函数名")
    print()

    print("--- 示例 ---")
    from random import choice as c1
    from random import randint as r2
    print(f"  choice(['A','B','C']) = {c1(['A','B','C'])}   ← 直接使用")
    print(f"  randint(1, 6)         = {r2(1, 6)}   ← 直接使用")
    print()

    print("--- import vs from...import 对比 ---")
    print()
    print("  ┌──────────────────┬─────────────────────────────┐")
    print("  │  import random    │  from random import choice  │")
    print("  ├──────────────────┼─────────────────────────────┤")
    print("  │ 导入整个模块      │ 只导入某个函数              │")
    print("  │ random.函数名()   │ 函数名() 直接用            │")
    print("  │ 不会重名          │ 可能和自己写的函数重名      │")
    print("  │ 用很多函数时推荐   │ 只用一两个函数时推荐        │")
    print("  └──────────────────┴─────────────────────────────┘")
    print()

    print("--- 导入多个函数 ---")
    print("  from random import choice, randint  ← 逗号分隔")
    print()

    print("💡 记忆钩子：")
    print("  from工具箱 import 工具 → 直接把工具揣兜里，不用写工具箱名")


def knowledge_randint():
    """知识点③：randint(1,6) 摇骰子"""
    print("=" * 60)
    print(" 知识点③：randint(1,6) 摇骰子")
    print("=" * 60)
    print()

    print("--- 语法 ---")
    print("  random.randint(最小值, 最大值)")
    print()

    print("--- 示例 ---")
    for i in range(5):
        dice = random.randint(1, 6)
        print(f"  第{i+1}次摇骰子：{dice}")
    print()

    print("--- 关键规则 ---")
    print("  ① randint(a, b) 返回 a 到 b 之间的随机整数")
    print("  ② 包含两端！randint(1,6) 可能返回 1 也可能返回 6")
    print("  ③ 参数必须是整数，顺序是 小, 大")
    print()

    print("--- 生活中的应用 ---")
    print(f"  模拟掷骰子：{random.randint(1, 6)}")
    print(f"  抽奖号码(1-100)：{random.randint(1, 100)}")
    print(f"  随机页码(1-50)：{random.randint(1, 50)}")
    print()

    print("💡 记忆钩子：randint = 摇骰子")
    print("   randint(a, b) 包含 a 也包含 b")


def knowledge_choice():
    """知识点④：choice(列表) 抽签"""
    print("=" * 60)
    print(" 知识点④：choice(列表) 抽签")
    print("=" * 60)
    print()

    print("--- 语法 ---")
    print("  random.choice(列表)")
    print()

    colors = ["red", "blue", "green", "orange", "purple"]
    fruits = ["苹果", "香蕉", "橘子", "西瓜"]
    numbers = [10, 20, 30, 40, 50]

    print("--- 示例 ---")
    print(f"  colors = {colors}")
    print(f"  random.choice(colors) → '{random.choice(colors)}'")
    print()
    print(f"  fruits = {fruits}")
    print(f"  random.choice(fruits) → '{random.choice(fruits)}'")
    print()
    print(f"  numbers = {numbers}")
    print(f"  random.choice(numbers) → {random.choice(numbers)}")
    print()

    print("--- 规则 ---")
    print("  ① choice(列表) 从列表中随机选一个元素")
    print("  ② 不修改原列表")
    print("  ③ 列表元素可以是任何类型")
    print()

    print("--- 抽签模拟 ---")
    students = ["小明", "小红", "小刚", "小丽", "小华"]
    print(f"  班级名单：{students}")
    lucky = random.choice(students)
    print(f"  抽中回答问题：{lucky}")
    print()

    print("💡 记忆钩子：choice = 抽签")
    print("   从列表里随机选一个")


def knowledge_random_float():
    """知识点⑤⑥：random() 和 uniform() 小数"""
    print("=" * 60)
    print(" 知识点⑤⑥：random() 和 uniform()——随机小数")
    print("=" * 60)
    print()

    print("--- ⑤ random() → 0~1之间的小数 ---")
    print()
    print("  语法：random.random()")
    print()
    for i in range(3):
        print(f"  random.random() = {random.random()}")
    print()
    print("  特点：")
    print("  ① 返回 [0.0, 1.0) —— 包含0.0，不包含1.0")
    print("  ② 永远返回小数（float）")
    print("  ③ 配合乘法可以扩展范围")
    print(f"  random.random() * 10 → {random.random() * 10}")
    print(f"  random.random() * 100 → {random.random() * 100}")
    print()

    print("--- ⑥ uniform(1,10) → 范围小数 ---")
    print()
    print("  语法：random.uniform(最小值, 最大值)")
    print()
    for i in range(3):
        print(f"  random.uniform(1, 10) = {random.uniform(1, 10):.4f}")
    print()
    print("  特点：")
    print("  ① 返回 a 到 b 之间的随机小数")
    print("  ② 适合随机坐标、随机大小、随机位置")
    print()

    print("--- randint vs uniform ---")
    print()
    print("  ┌───────────────────────┬───────────────────────────┐")
    print("  │  random.randint(a,b)  │  random.uniform(a,b)      │")
    print("  ├───────────────────────┼───────────────────────────┤")
    print("  │  返回整数              │  返回小数                 │")
    print("  │  包含两端              │  范围两端                 │")
    print("  │  适合摇骰子、抽奖      │  适合坐标、大小、位置      │")
    print("  └───────────────────────┴───────────────────────────┘")
    print()

    print("💡 记忆钩子：")
    print("   random()   = 0到1之间的小数")
    print("   uniform    = 范围小数")


# ============================================================
# 阶段三：演示——随机颜色画圆（30:00-40:00）
# ============================================================
def demo_random_color_circle():
    """
    演示 random.choice + random.randint + turtle 画随机圆。
    每次运行画面都不一样！
    """
    print("=" * 60)
    print(" 演示：random.choice 随机颜色画圆")
    print("=" * 60)
    print()
    print("代码逻辑：")
    print("  colors = ['red', 'blue', 'green', 'orange', 'purple']")
    print("  color = random.choice(colors)   # 随机抽一个颜色")
    print("  t.color(color)")
    print("  t.circle(50)")
    print()

    t = turtle.Turtle()
    t.speed(4)
    t.pensize(3)

    colors = ["red", "blue", "green", "orange", "purple"]

    # ========== 第1步：随机选一种颜色画圆 ==========
    print("--- 第1步：随机选颜色画1个圆 ---")
    t.penup()
    t.goto(0, -100)
    t.pendown()

    color = random.choice(colors)
    t.color(color)
    t.circle(50)
    print(f"  random.choice(colors) → '{color}'")
    print(f"  画了一个{color}色的圆")
    print()

    time.sleep(1)
    t.clear()

    # ========== 第2步：摇骰子决定画几个圆 ==========
    print("--- 第2步：randint决定画几个圆 ---")
    count = random.randint(3, 8)
    print(f"  random.randint(3, 8) → {count} ← 画{count}个圆")
    print()

    t.penup()
    t.goto(-200, 0)
    t.pendown()

    for i in range(count):
        color = random.choice(colors)
        t.color(color)
        t.circle(30)
        print(f"  第{i+1}个圆：{color}色")
        t.penup()
        t.forward(60)
        t.pendown()

    print(f"  共画了{count}个不同颜色的圆")
    print()

    time.sleep(1)
    t.clear()

    # ========== 第3步：随机位置 + 随机颜色 + 随机大小 ==========
    print("--- 第3步：随机位置 + 随机颜色 + 随机大小 ---")
    print("  每次运行，圆的位置、颜色、大小都不一样！")
    print()

    for i in range(6):
        x = random.randint(-200, 200)
        y = random.randint(-200, 200)
        color = random.choice(colors)
        radius = random.randint(20, 60)

        t.penup()
        t.goto(x, y)
        t.pendown()
        t.color(color)
        t.circle(radius)

        print(f"  第{i+1}个圆：位置({x},{y}) 颜色={color} 半径={radius}")

    print()
    print("🎯 关键代码回顾：")
    print("  ① random.choice(colors)     ← 随机选颜色（抽签）")
    print("  ② random.randint(-200,200)  ← 随机位置（摇骰子）")
    print("  ③ random.randint(20,60)     ← 随机大小（摇骰子）")
    print("  ④ 每次运行结果都不同！")

    turtle.done()


# ============================================================
# 阶段四：实操练习（40:00-55:00）
# ============================================================
def practice_answers():
    """实操练习参考答案"""
    print("=" * 60)
    print(" 实操练习参考答案")
    print("=" * 60)
    print()

    # === 练习1：填空import语法 ===
    print("--- 练习1：填空import语法 ---")
    print()
    print("题目：")
    print("  # ① 全部导入 random 模块")
    print("  ____ random")
    print("  # ② 从 random 中只导入 choice")
    print("  ____ random ____ choice")
    print("  # ③ 使用 randint（全部导入方式）")
    print("  num = ___________________(1, 6)")
    print("  # ④ 使用 choice（部分导入方式——已导入）")
    print("  color = ___________([\"red\", \"blue\"])")
    print()

    print("答案：")
    print("  ① import random")
    print("  ② from random import choice")
    print("  ③ num = random.randint(1, 6)")
    print("  ④ color = choice([\"red\", \"blue\"])")
    print()

    # === 练习2：randint摇骰子 ===
    print("--- 练习2：randint摇骰子 ---")
    print()
    print("题目：用 randint(1,6) 模拟摇骰子")
    print()

    print("答案：")
    print("""  import random
  dice = random.randint(1, 6)
  print(f\"你摇到了{dice}点！\")
  if dice == 6:
      print(\"恭喜！最大点数！\")""")
    print()

    print("运行结果：")
    for i in range(3):
        dice = random.randint(1, 6)
        print(f"  你摇到了{dice}点！", end="")
        if dice == 6:
            print("  恭喜！最大点数！", end="")
        print()
    print()

    # === 练习3：随机颜色画彩虹 ===
    print("--- 练习3：random.choice随机颜色画彩虹 ---")
    print()
    print("题目：用 random.choice + turtle 画6个随机颜色的圆")
    print()

    print("参考代码：")
    print("""  import turtle
  import random
  t = turtle.Turtle()
  t.speed(3)
  colors = ["red", "orange", "yellow", "green", "blue", "purple"]
  t.penup()
  t.goto(-150, 0)
  t.pendown()
  for i in range(6):
      color = random.choice(colors)
      t.color(color)
      t.circle(25)
      t.penup()
      t.forward(50)
      t.pendown()""")
    print()

    # 实际运行
    print("运行结果：")
    t = turtle.Turtle()
    t.speed(3)
    t.pensize(3)
    colors = ["red", "orange", "yellow", "green", "blue", "purple"]
    t.penup()
    t.goto(-150, 0)
    t.pendown()
    for i in range(6):
        color = random.choice(colors)
        t.color(color)
        t.circle(25)
        print(f"  第{i+1}个圆：{color}色")
        t.penup()
        t.forward(50)
        t.pendown()
    print()
    print("💡 关键点：")
    print("  ① random.choice(colors) 每次随机选一个颜色")
    print("  ② 同一个颜色可能被选多次（完全随机）")
    print("  ③ 每次运行颜色顺序都不同")

    turtle.done()


# ============================================================
# 阶段五：小测（55:00-60:00）
# ============================================================
def demo_quiz():
    """小测题目及正确答案"""
    print("=" * 60)
    print(" 小测：randint(1,6) 可能返回？")
    print("=" * 60)
    print()

    print("--- 问题1：random.randint(1, 6) 可能返回哪些值？ ---")
    print()
    print("  A. 0,1,2,3,4,5,6")
    print("  B. 1,2,3,4,5")
    print("  C. 1,2,3,4,5,6     ← 正确答案")
    print("  D. 0,1,2,3,4,5")
    print()
    print("  解析：randint 包含两端，所以 1 和 6 都可能！")
    print()

    print("--- 问题2：import random 和 from random import choice 的区别？ ---")
    print()
    print("  答案：")
    print("  import random       → 用 random.函数名()")
    print("  from random import choice → 直接用 choice()")
    print("  前者导入整个模块，后者只导入一个函数")
    print()

    print("--- 问题3：random.choice(['A', 'B', 'C']) 可能返回什么？ ---")
    print()
    print("  A. 'A'")
    print("  B. 'B'")
    print("  C. 'C'")
    print("  D. 以上都有可能    ← 正确答案")
    print()

    print("--- 问题4：判断题 ---")
    print()
    print("  ① random.random() 返回 0 到 1 之间的整数")
    print("     → 错！返回的是小数（float）")
    print()
    print("  ② random.randint(1, 10) 可能返回 10")
    print("     → 对！randint 包含右端")
    print()
    print("  ③ from random import * 是导入所有函数")
    print("     → 对！但一般不推荐（可能重名）")
    print()
    print("  ④ import random 后可以直接用 randint(1,6)")
    print("     → 错！需要用 random.randint(1, 6)")
    print()

    print("--- 问题5：补全代码 ---")
    print()
    print("  题目：")
    print("  import random")
    print("  fruits = ['苹果', '香蕉', '橘子']")
    print("  f = random._______(fruits)")
    print()
    print("  答案：choice")
    print("  f = random.choice(fruits)")
    print()

    print("--- 记忆钩子复习 ---")
    print("  'import = 打开工具箱'")
    print("  'randint = 摇骰子'")
    print("  'choice = 抽签'")
    print("  'random() = 0到1之间的小数'")
    print("  'uniform = 范围小数'")


# ============================================================
# 入口
# ============================================================
if __name__ == "__main__":
    print(" 12第1节 · import与random——打开工具箱摇骰子抽签")
    print(" GESP #33 #34")
    print("=" * 60)
    print()
    print("请选择要运行的功能：")
    print("  1  - 导入：工具箱比喻（00:00-10:00）")
    print("  2  - 知识点①：import random 全部导入")
    print("  3  - 知识点②：from...import 部分导入")
    print("  4  - 知识点③：randint(1,6) 摇骰子")
    print("  5  - 知识点④：choice(列表) 抽签")
    print("  6  - 知识点⑤⑥：random() 和 uniform() 小数")
    print("  7  - 演示：随机颜色画圆（30:00-40:00）")
    print("  8  - 实操练习参考答案（40:00-55:00）")
    print("  9  - 小测答案（55:00-60:00）")
    print()

    try:
        choice = int(input("请输入数字 (1-9)，直接回车默认 7: ") or "7")
    except (ValueError, EOFError):
        choice = 7

    print()

    functions = {
        1: demo_intro_toolbox,
        2: knowledge_import_all,
        3: knowledge_import_from,
        4: knowledge_randint,
        5: knowledge_choice,
        6: knowledge_random_float,
        7: demo_random_color_circle,
        8: practice_answers,
        9: demo_quiz,
    }

    func = functions.get(choice)
    if func:
        func()
    else:
        print("无效选择，运行随机颜色画圆演示")
        demo_random_color_circle()
