VermiIIi0n / fuckZHS

自动刷智慧树课程的脚本
MIT License
680 stars 81 forks source link

[BUG] 无法识别全部课程,总有些课程被遗漏 #54

Closed gaotianchi closed 1 year ago

gaotianchi commented 1 year ago

描述问题 根据文档描述,命令 python main.py 会处理所有的课程,然而经过几次尝试发现它只能处理部分课程,而那些没有处理的课程则需要手动输入课程 ID 才行。另外,如果使用 -c 命令,在后面输入多个课程 ID 它也只能处理部分课程,而且那些遗漏的课程和上面使用 python main.py 命令遗漏的课程相同。

如何复现 您遇到问题前进行了什么操作:

  1. 直接使用命令 python main.py -l 20

  2. 等待程序终止

  3. 发现有一些课程没有被处理

  4. 使用命令 python main.py -l -c ID1 ID2 ID3

  5. 等待程序运行结束

  6. 发现部分课程没有被处理

您的操作系统和所使用的本代码版本

VermiIIi0n commented 1 year ago

明白了, 但我这边没有课程可以复现, 请问能发下 Debug 日志到邮箱 smaller.tipster_0x@icloud.com 吗? 加个参数 -d, 运行后再把./logs 文件夹打个包就可以.

里面可能包含敏感信息, 还请注意删除.

VermiIIi0n commented 1 year ago

因为这个脚本是我第一个超百行的 Python, 不得不说代码非常不规范, 踩到了个智熄的坑, 是个 Python list 奇葩的设计问题导致的. 在作为迭代器的时候是按 index 遍历的, 直到引发 IndexError 停止迭代, 所以迭代时内容发生改变的话会导致 index 与原本内容不对应. 按理说应该设计成像 dict 那样, 迭代时被修改的话要引发异常才合理.

看阁下也在学 Python, 就写在这分享下吧哈哈.

ls = [1,2,3,4]

for n in ls:
    print(n)  # > 1 2 3 4

# 上面这句 for 相当于:

from itertools import count
for i in count():
    try:
        print(ls[i])  # > 1 2 3 4
    except IndexError:
        break
# 所以如果中途删减了内容的话:
for n in ls:
    print(n)  # > 1 3, 就跳过 2 和 4 了
    ls.remove(n) # 在第二次循环时, ls 从 [1,2,3,4] 变成[2,3,4], ls[1]指向 3 了, 跳过了 2, 同理也跳过了 4.

总结就是对于 list, dict 这样的 Mutable Objects 在遍历时一定要记得 copy 一下

for n in ls.copy():
    print(n)  # > 1 2 3 4
    ls.remove(n)

最后, 感谢反馈, 没想到这么明显的 bug 藏了这么久.🤯