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

"""
10第4节 · 字典遍历——keys() / values() / items()
==================================================
课程对应：
  - 00:00-10:00 导入：字典里有好多键值对→怎么全部拿出来？
  - 10:00-30:00 知识点：①d.keys()所有键 ②d.values()所有值
                ③d.items()所有(键,值)对 ④for k,v in d.items()遍历
  - 30:00-40:00 演示：for c,cn in colors.items(): print(f"{c}→{cn}");
                t.color(c); circle(20)
  - 40:00-55:00 实操：①填空遍历方法 ②补全遍历字典画彩色圆
                ③用items()打印完整字典
  - 55:00-60:00 小测："items()返回什么?"
  - GESP 考点：#41 字典基本操作（遍历部分）

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

import turtle
import time


# ============================================================
# 阶段一：导入——字典里有好多键值对，怎么全部拿出来？（00:00-10:00）
# ============================================================
def demo_intro_dict_traverse():
    """
    用"列表遍历 vs 字典遍历"对比引入。
    老师演示：列表可以直接 for 遍历，字典呢？
    """
    print("=" * 60)
    print(" 导入——字典里有好多键值对，怎么全部拿出来？")
    print("=" * 60)

    print("\n场景：假如你有3种颜色——")
    print()

    # ========== 第1步：列表遍历（复习） ==========
    print("--- 第1步：列表遍历（复习） ---")
    colors_list = ["red", "blue", "green"]
    print(f"  colors_list = {colors_list}")
    print("  for c in colors_list:")
    for c in colors_list:
        print(f"    → {c}")
    print("  列表遍历：直接 for c in 列表 → 拿到每个元素")
    print()

    # ========== 第2步：字典直接遍历——取到的是？ ==========
    print("--- 第2步：字典直接遍历 ---")
    colors_dict = {"r": "red", "b": "blue", "g": "green"}
    print(f"  colors_dict = {colors_dict}")
    print("  for x in colors_dict:")
    for x in colors_dict:
        print(f"    → {x}")
    print("  发现：直接遍历字典，拿到的是【键】！不是值！")
    print()

    # ========== 第3步：引出三种方法 ==========
    print("--- 第3步：那怎么拿值？怎么同时拿键和值？ ---")
    print()
    print("  Python 提供了3个方法：")
    print("  ① d.keys()   → 取所有键")
    print("  ② d.values() → 取所有值")
    print("  ③ d.items()  → 取所有(键, 值)对")
    print()
    print("🎯 记忆钩子：")
    print("   'keys()取所有键，values()取所有值，items()取全部成对输出'")


# ============================================================
# 阶段二：知识点讲解（10:00-30:00）
# ============================================================
def knowledge_keys():
    """知识点①：d.keys() —— 取所有键"""
    print("=" * 60)
    print(" 知识点①：d.keys() —— 取所有键")
    print("=" * 60)
    print()

    colors = {"r": "red", "b": "blue", "g": "green"}
    print(f"  colors = {colors}")
    print()

    print("--- 语法 ---")
    print("  d.keys() → 返回所有键的视图")
    print()

    print("--- 示例 ---")
    keys = colors.keys()
    print(f"  colors.keys() = {keys}")
    print(f"  类型：{type(keys)}")
    print()

    print("--- 遍历所有键 ---")
    print("  for k in colors.keys():")
    print("      print(k)")
    print("  输出：")
    for k in colors.keys():
        print(f"    → {k}")
    print()

    print("--- 简写形式 ---")
    print("  for k in colors:       # 和 for k in colors.keys() 等价")
    print("      print(k)")
    print("  输出：")
    for k in colors:
        print(f"    → {k}")
    print()

    print("💡 记忆：keys() = 所有键的钥匙串")


def knowledge_values():
    """知识点②：d.values() —— 取所有值"""
    print("=" * 60)
    print(" 知识点②：d.values() —— 取所有值")
    print("=" * 60)
    print()

    colors = {"r": "red", "b": "blue", "g": "green"}
    print(f"  colors = {colors}")
    print()

    print("--- 语法 ---")
    print("  d.values() → 返回所有值的视图")
    print()

    print("--- 示例 ---")
    vals = colors.values()
    print(f"  colors.values() = {vals}")
    print(f"  类型：{type(vals)}")
    print()

    print("--- 遍历所有值 ---")
    print("  for v in colors.values():")
    print("      print(v)")
    print("  输出：")
    for v in colors.values():
        print(f"    → {v}")
    print()

    print("--- 实际应用：统计总分 ---")
    scores = {"语文": 88, "数学": 95, "英语": 90}
    print(f"  scores = {scores}")
    total = 0
    for score in scores.values():
        total += score
    print(f"  总分 = {total}")
    print()

    print("💡 记忆：values() = 只看值，不看键")


def knowledge_items():
    """知识点③：d.items() —— 取所有(键,值)对"""
    print("=" * 60)
    print(" 知识点③：d.items() —— 取所有(键,值)对")
    print("=" * 60)
    print()

    colors = {"r": "red", "b": "blue", "g": "green"}
    print(f"  colors = {colors}")
    print()

    print("--- 语法 ---")
    print("  d.items() → 返回所有(键, 值)对的视图")
    print()

    print("--- 示例 ---")
    items = colors.items()
    print(f"  colors.items() = {items}")
    print(f"  类型：{type(items)}")
    print()

    print("--- 每个元素是元组 ---")
    for item in colors.items():
        print(f"    {item}  ← 类型：{type(item)}")
    print()

    print("--- 转换成列表查看 ---")
    items_list = list(colors.items())
    print(f"  list(colors.items()) = {items_list}")
    print(f"  每个元素是：{type(items_list[0])}")
    print()

    print("💡 记忆：items() = 每个item是一对(键, 值)")


def knowledge_items_traverse():
    """知识点④：for k, v in d.items() —— 双变量遍历"""
    print("=" * 60)
    print(" 知识点④：for k, v in d.items() —— 双变量遍历")
    print("=" * 60)
    print()

    colors = {"r": "red", "b": "blue", "g": "green"}
    print(f"  colors = {colors}")
    print()

    print("--- 方式一：用两个变量接收（推荐）---")
    print("  for k, v in colors.items():")
    print("      print(f'键={k}, 值={v}')")
    print("  输出：")
    for k, v in colors.items():
        print(f"    键={k}, 值={v}")
    print()

    print("--- 方式二：用一个变量接收元组 ---")
    print("  for item in colors.items():")
    print("      k = item[0]")
    print("      v = item[1]")
    print("      print(f'键={k}, 值={v}')")
    print("  输出：")
    for item in colors.items():
        k = item[0]
        v = item[1]
        print(f"    键={k}, 值={v}")
    print()

    print("--- 实际应用：格式化输出字典内容 ---")
    student = {"姓名": "张三", "年龄": 9, "班级": "3班"}
    print(f"  student = {student}")
    print("  for k, v in student.items():")
    print("      print(f'{k}: {v}')")
    print("  输出：")
    for k, v in student.items():
        print(f"    {k}: {v}")
    print()

    print("💡 三种方法对比：")
    print("  只拿键  → for k in d.keys():   或 for k in d:")
    print("  只拿值  → for v in d.values():")
    print("  同时拿  → for k, v in d.items():    ★ 最常用")
    print()

    print("⚠️ 常见错误：")
    print("  ① 忘记括号：d.keys 是方法对象，d.keys() 才是调用！")
    print("  ② 混淆 keys 和 items：keys 只拿键，items 拿全部对")
    print("  ③ 遍历时不要增删字典的键！")


# ============================================================
# 阶段三：演示——用字典遍历画彩色圆（30:00-40:00）
# ============================================================
def demo_items_circles():
    """
    演示用字典 + items() + turtle 画彩色圆。
    字典键是中文名，值是英文名 → items() 同时取到。
    """
    print("=" * 60)
    print(" 演示：用 items() 遍历字典 + turtle 画彩色圆")
    print("=" * 60)
    print()
    print("代码逻辑：")
    print("  colors = {")
    print("      '红色': 'red',")
    print("      '蓝色': 'blue',")
    print("      '绿色': 'green',")
    print("  }")
    print("  for c, cn in colors.items():")
    print("      print(f'{c}→{cn}')")
    print("      t.color(cn)")
    print("      t.circle(20)")
    print("      t.penup(); t.forward(60); t.pendown()")
    print()

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

    # ========== 第1步：3种颜色 ==========
    print("--- 第1步：3种颜色 ---")
    colors = {
        "红色": "red",
        "蓝色": "blue",
        "绿色": "green",
    }
    print(f"  colors = {colors}")
    print()

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

    for c, cn in colors.items():
        print(f"  {c}→{cn}")
        t.color(cn)
        t.circle(20)
        t.penup()
        t.forward(60)
        t.pendown()

    print()
    time.sleep(1)

    # ========== 第2步：5种颜色（扩展） ==========
    print("--- 第2步：5种颜色 ---")
    t.clear()
    t.penup()
    t.goto(-180, 0)
    t.pendown()

    colors = {
        "红色": "red",
        "橙色": "orange",
        "黄色": "yellow",
        "绿色": "green",
        "蓝色": "blue",
    }
    print(f"  colors = {colors}")
    print(f"  len(colors) = {len(colors)}   ← 5种颜色")
    print()

    for c, cn in colors.items():
        print(f"  {c}→{cn}    ← 画一个{cn}色的圆")
        t.color(cn)
        t.circle(25)
        t.penup()
        t.forward(55)
        t.pendown()

    print()
    print("🎯 关键代码回顾：")
    print("  ① colors = {'红色': 'red', ...}  ← 创建字典")
    print("  ② for c, cn in colors.items():  ← items()双变量遍历")
    print("  ③ t.color(cn)                   ← 用值(英文)设颜色")
    print("  ④ print(f'{c}→{cn}')            ← 同时用键和值")

    turtle.done()


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

    # === 练习1：填空遍历方法 ===
    print("--- 练习1：填空遍历方法 ---")
    print()
    print("题目：")
    scores = {"小明": 90, "小红": 85, "小刚": 92}
    print(f"  scores = {scores}")
    print("  ① 遍历所有键：for name ____ scores.____():")
    print("  ② 遍历所有值：for score ____ scores.____():")
    print("  ③ 遍历所有键值对：for name, score ____ scores.____():")
    print()

    print("答案：")
    print("  ① for name in scores.keys():")
    print("  ② for score in scores.values():")
    print("  ③ for name, score in scores.items():")
    print()

    print("运行结果：")
    print("  --- keys() ---")
    for name in scores.keys():
        print(f"    {name}")
    print("  --- values() ---")
    for score in scores.values():
        print(f"    {score}")
    print("  --- items() ---")
    for name, score in scores.items():
        print(f"    {name}: {score}")
    print()

    # === 练习2：补全遍历字典画彩色圆 ===
    print("--- 练习2：补全遍历字典画彩色圆 ---")
    print()
    print("题目：补全代码，用 items() 遍历 colors 字典画彩色圆")
    print()
    print("参考代码：")
    print("""    import turtle
    t = turtle.Turtle()
    t.speed(3)
    colors = {
        "red": "红色",
        "orange": "橙色",
        "yellow": "黄色",
        "green": "绿色",
        "blue": "蓝色",
    }
    for en, cn in colors.items():
        t.color(en)          # 用英文键设置颜色
        print(f"画了一个{cn}色的圆")   # 用中文值打印
        t.circle(25)
        t.penup()
        t.forward(55)
        t.pendown()""")
    print()

    # 运行演示
    print("运行结果：")
    t = turtle.Turtle()
    t.speed(3)
    t.pensize(3)
    colors = {
        "red": "红色",
        "orange": "橙色",
        "yellow": "黄色",
        "green": "绿色",
        "blue": "蓝色",
    }
    t.penup()
    t.goto(-150, 0)
    t.pendown()
    for en, cn in colors.items():
        t.color(en)
        print(f"  画了一个{cn}色的圆")
        t.circle(25)
        t.penup()
        t.forward(55)
        t.pendown()
    print()
    print("💡 关键点：")
    print("  ① items() 同时取出键(en)和值(cn)")
    print("  ② 键(英文)传给 t.color() 设置画笔")
    print("  ③ 值(中文)用于 print() 友好显示")
    print()

    # === 练习3：用 items() 打印完整字典 ===
    print("--- 练习3：用 items() 打印完整字典 ---")
    print()
    print("题目：使用 items() 逐行打印 student 字典的全部内容")
    print()

    student = {"姓名": "张三", "年龄": 9, "班级": "3班", "爱好": "编程"}
    print(f"  student = {student}")
    print()
    print("答案：")
    print("  for k, v in student.items():")
    print("      print(f'{k} → {v}')")
    print()
    print("运行结果：")
    for k, v in student.items():
        print(f"  {k} → {v}")
    print()

    print("💡 记忆钩子复习：")
    print("  'keys()取所有键，values()取所有值，items()取全部成对输出'")


# ============================================================
# 阶段五：小测（55:00-60:00）
# ============================================================
def demo_quiz():
    """小测题目及正确答案"""
    print("=" * 60)
    print(" 小测：'items()返回什么?'")
    print("=" * 60)
    print()

    colors = {"r": "red", "b": "blue", "g": "green"}

    print("--- 问题1：items() 返回什么？ ---")
    print()
    print("  A. 所有键的列表")
    print("  B. 所有值的列表")
    print("  C. 所有(键, 值)对的视图    ← 正确答案")
    print("  D. 所有键值对的个数")
    print()
    print(f"  验证：colors.items() = {colors.items()}")
    print(f"  类型：{type(colors.items())}")
    print()

    print("--- 问题2：下面哪段代码正确？ ---")
    print()
    print("  d = {'a': 1, 'b': 2}")
    print("  A. for k in d.keys(): print(k)         → 正确")
    print("  B. for v in d.values(): print(v)       → 正确")
    print("  C. for k, v in d.items(): print(k,v)   → 正确")
    print("  D. for k in d.items(): print(k)        → 不报错但k是元组")
    print()

    print("--- 问题3：补全代码 ---")
    info = {"name": "Tom", "age": 8}
    print(f"  info = {info}")
    print("  for ____, ____ in ____.____():")
    print("      print(f'{____} = {____}')")
    print()
    print("  答案：")
    print("  for k, v in info.items():")
    print("      print(f'{k} = {v}')")
    print()
    print("  运行结果：")
    for k, v in info.items():
        print(f"    {k} = {v}")
    print()

    print("--- 问题4：判断对错 ---")
    print("  直接用 for k in d: 遍历字典，得到的是值。")
    print("  答案：错！得到的是键。")
    print(f"  for k in {colors}: 遍历得到 k = ", end="")
    for k in colors:
        print(k, end=" ")
    print(" ← 都是键！")
    print()

    print("--- 记忆钩子复习 ---")
    print("  'keys()取所有键，values()取所有值，items()取全部成对输出'")
    print("  'for k, v in d.items() —— 两个变量同时拿，键值对全不怕'")


# ============================================================
# 辅助函数：查看完整代码演示
# ============================================================
def demo_all_in_one():
    """
    一次性演示所有知识点：创建字典 → 三种遍历方法 → 画彩色圆
    """
    print("=" * 60)
    print(" 完整演示：字典遍历 keys / values / items")
    print("=" * 60)
    print()

    # 1. 创建一个颜色字典
    colors = {
        "红色": "red",
        "橙色": "orange",
        "黄色": "yellow",
        "绿色": "green",
        "蓝色": "blue",
    }
    print(f"1. 字典：{colors}")
    print()

    # 2. 三种遍历方法
    print("2. 三种遍历方法：")
    print()

    print("  ① d.keys() —— 所有键：")
    for k in colors.keys():
        print(f"     {k}")
    print()

    print("  ② d.values() —— 所有值：")
    for v in colors.values():
        print(f"     {v}")
    print()

    print("  ③ d.items() —— 所有(键,值)对：")
    for k, v in colors.items():
        print(f"     {k} → {v}")
    print()

    # 3. 实际应用：创建字典并格式化输出
    print("3. 实际应用：学生信息")
    student = {"姓名": "李四", "年龄": 10, "年级": "四年级"}
    for k, v in student.items():
        print(f"   {k}: {v}")


# ============================================================
# 入口
# ============================================================
if __name__ == "__main__":
    print(" 10第4节 · 字典遍历——keys() / values() / items()")
    print(" GESP #41")
    print("=" * 60)
    print()
    print("请选择要运行的功能：")
    print("  1  - 导入：字典遍历引入（00:00-10:00）")
    print("  2  - 知识点①：d.keys()——取所有键")
    print("  3  - 知识点②：d.values()——取所有值")
    print("  4  - 知识点③：d.items()——取所有(键,值)对")
    print("  5  - 知识点④：for k,v in d.items()——双变量遍历")
    print("  6  - 演示：用 items() 画彩色圆（30:00-40:00）")
    print("  7  - 实操练习参考答案（40:00-55:00）")
    print("  8  - 小测答案（55:00-60:00）")
    print("  9  - 完整演示：三种方法一览")
    print()

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

    print()

    functions = {
        1: demo_intro_dict_traverse,
        2: knowledge_keys,
        3: knowledge_values,
        4: knowledge_items,
        5: knowledge_items_traverse,
        6: demo_items_circles,
        7: practice_answers,
        8: demo_quiz,
        9: demo_all_in_one,
    }

    func = functions.get(choice)
    if func:
        func()
    else:
        print("无效选择，运行彩色圆演示")
        demo_items_circles()
