# GESP等级：四级 | GESP Python 四级考点
"""
==============================================================
14_异常处理 / 第2节_finally综合
    03_演示_try_except_finally.py
    时间段: 30:00-40:00  演示
    核心演示: try-except-finally 保护 turtle 画圆程序
==============================================================

演示代码:
    try:
        n = int(input("请输入半径: "))
        t.circle(n)
    except ValueError:
        print("请输入数字!")
    finally:
        print("程序结束")

结构拆解:
    try     →  尝试获取用户输入并画圆
    except  →  如果输入不是数字，捕获 ValueError
    finally →  无论成功/失败，都打印"程序结束"
"""

import turtle

print("=" * 58)
print("🎯 演示: try-except-finally 保护画图程序")
print("=" * 58)

# ────────────────────────────────────────────────────────────
# 演示1: 最简版本 —— 对应课程00:30:00的演示代码
# ────────────────────────────────────────────────────────────
def demo_basic():
    """最简演示: try → except ValueError → finally 收尾。"""
    # 创建画布和画笔
    t = turtle.Turtle()
    t.speed(5)
    t.pensize(3)
    t.pencolor("blue")
    turtle.title("try-except-finally 画圆演示")

    # ★ 核心: try-except-finally
    try:
        n = int(input("请输入圆的半径: "))   # ← 可能抛出 ValueError
        t.circle(n)                          # ← 正常则画圆
    except ValueError:
        print("请输入数字!")                 # ← 处理输入错误
    finally:
        # ★ 不管出不出错，一定会执行
        print("程序结束")                    # ← 保底收尾

    # 点击关闭窗口
    turtle.done()


# ────────────────────────────────────────────────────────────
# 演示2: 增强版本 —— 加入更多异常处理和else
# ────────────────────────────────────────────────────────────
def demo_enhanced():
    """增强演示: 多异常 + else + finally。"""
    t = turtle.Turtle()
    t.speed(5)
    t.pensize(3)
    turtle.title("增强版: 多异常 + else + finally")

    try:
        n = int(input("请输入圆的半径(1-500): "))
        if n <= 0:
            # 手动抛出一个异常，演示except的覆盖能力
            raise ValueError("半径必须为正数！")
        t.circle(n)
    except ValueError as e:
        # ValueError 包括: int()转换失败 + 我们手动抛出的
        print(f"输入错误: {e}")
    except turtle.TurtleGraphicsError as e:
        print(f"绘图错误: {e}")
    else:
        # ★ 没有异常时才执行
        print(f"✅ 成功画了一个半径为{n}的圆！")
    finally:
        # ★ 无论如何都会执行
        print("【finally】程序结束，收尾工作完成。")

    turtle.done()


# ────────────────────────────────────────────────────────────
# 演示3: 时间轴走查 —— 模拟三种不同输入的结果
# ────────────────────────────────────────────────────────────
print("""
┌─────────────────────────────────────────────────────────────┐
│  【时间轴走查: 三种不同输入的执行路径】                       │
│                                                              │
│  输入: 100 (合法数字)                                         │
│    try:   int("100") → 100  ✓                                │
│           t.circle(100)    ✓                                 │
│    else:  输出"成功画圆"                                     │
│    finally: 输出"程序结束" ← 必执行                          │
│                                                              │
│  输入: abc (非法内容)                                         │
│    try:   int("abc") → ValueError ✗  → 跳转到 except         │
│    except ValueError: 输出"请输入数字!"                      │
│    finally: 输出"程序结束" ← 必执行                          │
│                                                              │
│  输入: -50 (逻辑错误，但int转换成功)                           │
│    try:   int("-50") → -50  ✓                                │
│           t.circle(-50)    ✓  (turtle接受负数，反向画圆)     │
│    else:  输出"成功画圆"                                     │
│    finally: 输出"程序结束" ← 必执行                          │
└─────────────────────────────────────────────────────────────┘
""")


# ────────────────────────────────────────────────────────────
# 演示4: 动画演示 —— 展示finally的执行过程
# ────────────────────────────────────────────────────────────
def demo_with_trace():
    """逐步跟踪: 展示每个块的执行过程。"""
    t = turtle.Turtle()
    t.speed(3)
    t.pensize(3)
    turtle.title("finally执行过程跟踪")

    print("→ 程序启动，进入 try 块...")
    try:
        raw = input("请输入圆的半径: ")
        n = int(raw)
        print(f"→ int('{raw}') = {n}，准备画圆...")
        t.circle(n)
        print("→ 画圆完成。")
    except ValueError:
        print(f"→ int('{raw}') 失败! ValueError 被捕获。")
    else:
        print("→ else 块: 一切顺利，没有异常发生。")
    finally:
        # ★ 关键: 标记finally的执行位置
        print("★ ★ ★ 【finally】执行中... 程序结束 ★ ★ ★")

    turtle.done()


# ════════════════════════════════════════════════════════════
# 运行说明
# ════════════════════════════════════════════════════════════
print("""
【运行说明】
  这4个演示函数都在使用 turtle 图形界面。
  请逐个取消注释下方的调用并运行。

推荐顺序:
  1. demo_basic()         → 最简洁版，对应课程演示代码
  2. demo_enhanced()      → 增强版，多异常 + else
  3. demo_with_trace()    → 带过程跟踪，理解执行顺序
""")

# ── 取消注释即可运行 ──

# 演示1: 最简版本（对应课程核心演示）
# demo_basic()

# 演示2: 增强版本
# demo_enhanced()

# 演示3: 过程跟踪
# demo_with_trace()


print("=" * 58)
print("📝 总结")
print("=" * 58)
print("""
  代码结构:
      try:
          n = int(input("请输入半径: "))
          t.circle(n)
      except ValueError:
          print("请输入数字!")
      finally:
          print("程序结束")

  执行流程:
      用户输入 ─→ try 块 ─→ 成功? ─→ 画圆 ─→ finally
                        │                           ↑
                        └→ 失败 ─→ except ──────────┘

  finally 的价值:
      保证"程序结束"这行代码无论如何都能被执行。
      即使异常没被捕获，finally 也会先执行再崩溃。
""")
