"""任务 3 · 生成器表达式：什么时候算、能不能反复用

把列表推导式的方括号换成圆括号，就是**生成器表达式**：产生的值一样，算的时机不一样。
这一份用「会数自己被调用几次」的函数 slow_square，把四件事变成看得见的数字：

  · 惰性：生成器写出来时一个都还没算（计数 0），要一个才算一个；
  · 只能走一遍：第一次取完就空了，第二次要什么都没有，而且不会重新算；
  · 表能反复用：列表推导式是建表时就把元素全算好，之后想用几次用几次；
  · 短路：判定类函数能确定结果就不再往下取值（所以计数会停在某个数上）。

文件最后还给判分脚本留了一个函数接口 squares_gen(n)：它要交回一个**生成器**——
判分拿它去试 len 与下标，看你会不会说清「生成器没有长度、也不能下标」。

带 print 的行是判分接口，别改；要写的是标着 TODO 的那几行。

跑： py task3_generator.py
判： py run_tests.py
"""

calls = 0                                  # 别改：下面用它数 slow_square 被调用了几次


def slow_square(x):
    """算 x 的平方，并把「被调用了一次」记进 calls（别改）。"""
    global calls
    calls += 1
    return x * x


# ══ TODO 01 ═════════════════════════════════════════════════
# 下面这一行现在是列表推导式版（建好就把 6 个数全算完了）。
# 改成生成器版：方括号换圆括号。改完 01 那一行应该打出 0。
calls = 0                                  # 别改
gen = [slow_square(x) for x in range(6)]
print('01 建好之后 calls', calls)           # 别改：期望 0（一个都还没算）
print('02 第一次 sum', sum(gen))            # 别改：期望 55
print('03 第一次 sum 之后 calls', calls)     # 别改：期望 6
print('04 第二次 sum', sum(gen))            # 别改：期望 0（已经空了）
print('05 第二次 sum 之后 calls', calls)     # 别改：期望 6（没有重新算）


# ══ TODO 02 ═════════════════════════════════════════════════
# 这一行要换成列表推导式版：建表时就把 6 个数全算好，之后能反复用。
calls = 0                                  # 别改
lst = []
print('06 建表之后 calls', calls)           # 别改：期望 6
print('07 表能反复用', sum(lst), sum(lst))   # 别改：期望 55 55


# ══ TODO 03 ═════════════════════════════════════════════════
# 下面这两个函数体写在文件最后，是给判分脚本用的接口（现在交回的是空列表，改成生成器）。
# 提示：只要把 TODO 01 的写法套进 squares_gen(n) 就行 —— 交回生成器，不是列表。

# ══ TODO 04 ═════════════════════════════════════════════════
# 用「存在一个满足就为真」的函数写一行：range(6) 里平方后大于 3 的有没有？
# 提示：喂给它的写成生成器表达式（slow_square(x) > 3 for x in range(6)）。
calls = 0                                  # 别改
has_big = None
print('08 any 提前停 calls', calls)         # 别改：期望 3（到 4 就定下了，后面的不再算）
print('09 any 的值', has_big)               # 别改：期望 True


# ══ TODO 05 ═════════════════════════════════════════════════
# 再用「全部满足才为真」的函数写一行：平方后是不是都小于 5？
calls = 0                                  # 别改
all_small = None
print('10 all 提前停 calls', calls)         # 别改：期望 4（到 9 出现反例就定下了）
print('11 all 的值', all_small)             # 别改：期望 False


# ── 给好的（别改）：map 交回来的也是迭代器，同样只能用一次 ──────────────
data_str = ['3', '-1', '4']
m = map(int, data_str)
print('12 map 第一次', list(m))             # 别改：期望 [3, -1, 4]
print('13 map 第二次', list(m))             # 别改：期望 []


# ══ TODO 03（函数体在这里）═══════════════════════════════════
def squares_gen(n):
    """交回一个生成器表达式（判分接口，函数名与参数别改）。"""
    return []
