尧图精选

Python零基础必看:学生成绩录入统计系统完整实现与调试复盘

🕒 发布时间:2026/10/1 4:14:34 📁 来源:尧图网络
连续带了两届零基础学员我发现一个特别有意思的现象Python课程的第二次作业才是真正的劝退点。第一次作业无非是print(Hello World)、input收个名字照着课件敲一遍基本都能过。可到了第二次作业变量、类型转换、分支判断、while循环、列表、定义函数这些概念一股脑全压过来很多人的代码就开始花式报错了。这篇文章就是一次真实的Python第二次作业复盘题目是学生成绩录入与统计系统。我用最基础的知识把它完整实现了一遍顺便把环境配置、调试排错、边界测试这些老师课件里不会细讲的东西也梳理出来给正在被第二次作业折磨的朋友一个可以直接抄的答案也给零基础入门者一份看得懂的python基础语法实战参考。1. 先搞清楚第二次作业到底在考察什么1.1 为什么偏偏是第二次作业最容易劝退第一次作业通常只是让你把环境跑通print个字符串、input收个名字就交差了哪怕你对语法一知半解也能糊弄过去。到了第二次作业几乎所有核心基础概念会在同一个题目里汇合数据结构怎么设计、类型怎么转换、循环怎么写、分支怎么判断、函数怎么封装。很多同学还停留在照着课件抄能跑就行的阶段突然要自己从零组织一段几十行的代码思维很容易断档。我见过太多人在第二次作业里犯同样的错误把所有逻辑堆在一个大块里中间变量乱起名输入成绩不转类型导致字符串和数字相加报错列表索引越界也不知道为什么。说到底这一份作业考的不是你会不会写某个语法而是你有没有建立最基本的编程思维——先把问题拆开再一步步用代码表达出来。想明白这一点第二次作业就不再是背书而是在练逻辑。1.2 这次作业的题面与验收标准我这次选的题目非常典型老师布置了一个学生成绩录入与统计系统。需求并不复杂但正好能把第二次作业该有的知识点全部覆盖到。题面大致是这样的用户能录入若干名学生的姓名和语文、数学、英语三科成绩。程序要为每名学生计算总分、平均分并按平均分给出等级90分及以上为优秀80到89为良好70到79为中等60到69为及格60以下为不及格。全部录入完成后统计全班平均分、最高总分、最低总分并列出总分前三名。要求至少定义两个函数一个负责录入一个负责统计。这个题目看着不难踩点却不少。验收时会看程序能不能稳定跑通输入异常数据时会不会崩溃代码是不是缩进规范、命名清楚、有必要的注释。其实很多老师不会明说但第二次作业的评分重点往往不是功能实现而是代码质量。同样的功能有人用一堆散乱代码也能跑但函数封装清晰、边界处理到位的版本分数就是高一档。2. 动工之前环境、编辑器与代码习惯2.1 装好Python之后先确认命令行能跑起来很多人一上来就打开编辑器写代码结果连最基本的python命令都调不通后面全是连锁反应。第一次作业如果是在网页编辑器或IDLE里糊弄过去的第二次作业开始建议务必将Python装到本地并且确认打开终端能直接运行。Windows下我一般会让学员先按WinR输入cmd然后敲一句python --version。如果能正常显示版本号说明解释器装好并且环境变量配好了。如果提示python 不是内部或外部命令多半是安装时忘了勾选Add Python to PATH。这时候倒不用急着折腾手动加PATH最简单的办法是卸载重装一次安装界面第一步就把底部的Add Python to PATH勾上一路Next就行。Mac和Linux环境下情况稍有不同。Mac通常自带Python 2所以建议用python3 --version检查Linux则要看发行版Ubuntu等系统可以这样确认python3版本。类Unix系统里常常是python3而不是python第一次接触的人容易在这里卡住。我的建议是只要确认了哪个命令能跑通后面在编辑器里配置解释器时保持一致就行不必过分纠结版本号差异。检查完命令行以后顺手把pip --version也敲一下。pip是Python的包管理工具后面积累经验想装openpyxl写Excel、装requests学爬虫都得靠它。如果pip提示找不到命令Windows下可以试试python -m pip --version这条命利用模块方式运行绕开文件路径的坑。2.2 VS Code里的Python环境三件套编辑器我用得最多的是VS Code免费、轻量、插件生态成熟。第二次作业阶段不需要装太重的东西但有三件事一定要做对。第一安装Python扩展。打开VS Code左侧的扩展商店搜索Python认准微软官方发布的那个安装量最高、图标是蓝底黄字的。装好之后VS Code才能提供代码高亮、智能提示和调试功能。第二选定解释器。这一步常被忽略却是vscode python环境配置里最大的坑。按CtrlShiftP打开命令面板输入Python: Select Interpreter选择刚才确认能用的那个Python版本。很多人的代码一直在右下角提示No interpreter或者明明在终端能跑点运行按钮却找不到模块基本都是因为这一步没选对。第三把默认终端跑通。VS Code里可以直接按Ctrl打开集成终端确认你在这个终端里运行python --version也能出来版本号。这样按右上角的运行三角按钮或者直接在终端输入python 文件名.py效果是一样的。我建议第二阶段开始就习惯终端运行脚本 print看结果这个工作流因为后续调试复杂程序时终端里的报错信息比编辑器面板更完整。2.3 写代码前先培养的三个好习惯第一个习惯是缩进统一用四个空格。Python用缩进表示代码块Tab和空格混用会在运行时报IndentationError而且肉眼很难看出来。VS Code默认会把Tab转成四个空格你只要不在设置里乱改基本没问题。第二个习惯是变量命名要见名知意别用a、b、c满天飞。比如存所有学生的列表叫students存总分叫total_scores读代码的人不费力就能看懂。第三个习惯是保留必要的print输出。在打通逻辑之前我会在每个关键步骤后面临时加一句print(变量名)确认数据确实按预期流到了这里。这不算笨办法反而是快速定位问题最有效的思路。3. 从零实现成绩统计系统核心代码逐段拆解3.1 先定数据结构用列表嵌套列表写代码最忌讳上来就敲键盘。哪怕是一份第二次作业也值得先花两分钟想想数据怎么存。我这里选了最基础、也最贴合课堂知识的方案用列表嵌套列表来表示多个学生。每个学生是一行数据比如[张三, 89, 92, 88]列表里的第一个元素是姓名后面三个是成绩。所有学生再放进外层列表形成一个二维结构students [ [张三, 89, 92, 88], [李四, 76, 85, 91] ]这样设计的好处非常直接可以通过索引访问任意数据。students[0]拿到第一个学生的完整信息students[0][0]拿到姓名students[0][1]拿到第一科成绩。更重要的是后面要算某个学生的三科总和时可以直接用切片students[0][1:]取出从索引1开始到末尾的所有成绩正好跳过姓名。这一手就是热搜词里常说的python数组切片的典型用法在第二次作业里就已经能派上用场了。为什么不提前教字典因为第二次作业通常还没到字典。用列表嵌套列表虽然看起来朴素但能逼你熟练掌握下标访问和循环遍历这是更底层的肌肉记忆。3.2 录入函数类型转换与格式化的第一次实战录入部分我封装成一个input_students()函数核心是循环录入和类型转换。直接看代码def input_students(): students [] count int(input(请输入学生人数)) for i in range(count): name input(f请输入第{i 1}名学生的姓名) chinese float(input(f请输入{name}的语文成绩)) math float(input(f请输入{name}的数学成绩)) english float(input(f请输入{name}的英语成绩)) students.append([name, chinese, math, english]) return students这里有两个重点。第一个是int()和float()的强制类型转换。input()接收到的永远是一个字符串如果不转成数字后面89 92 88就会变成字符串拼接得到899288这肯定不是你要的结果。Python的type()函数可以随时查看变量类型遇到为什么结果不对的诡异问题时先打印一下type(变量)往往能立刻找到原因。第二个是f-string格式化字符串。f请输入第{i 1}名学生的姓名里的{}可以嵌入变量和表达式相比老式的%d % i或.format()写法直观得多。Python 3.6之后就支持这个语法强烈建议养成使用f-string的习惯以后写日志、拼输出、做报错提示都离不开它。录入函数执行完后students这个二维列表就带着全部数据返回给调用方。注意函数内部定义的变量在外部是访问不到的必须通过return students把结果交出去这个函数作用域概念是第二次作业里最容易懵的地方。3.3 等级判断函数if-elif结构的顺序之美等级判断逻辑单独抽成一个函数是练习定义函数和判断结构的好机会def get_grade(score): if score 90: return 优秀 elif score 80: return 良好 elif score 70: return 中等 elif score 60: return 及格 else: return 不及格这个函数虽然简单但有一个很关键的习惯必须养成判断条件从高到低排。如果先写if score 60那90分也会先撞进这个分支返回及格后面的优秀判断永远执行不到。这种逻辑顺序错误不报语法错只会在结果上出问题恰恰是最难排查的一类bug。写完这段代码后强烈建议用70、85、90、59这几个临界分数分别测试一次确认每个分数落到的等级都是预期值。代码里return直接结束函数并返回结果所以不需要在每个elif后面再加else。这比写一个变量grade存值再最后统一返回要轻快得多也更符合找到结果就退出的直觉。3.4 统计函数总和、平均分、最值和前三名统计逻辑封装在analyze_scores(students)函数里。这个函数比较长我拆成几块解释。先算出每个人的总分、平均分和等级total_scores [] for stu in students: total sum(stu[1:]) total_scores.append([total, stu[0]]) avg total / 3 grade get_grade(avg) print(f{stu[0]}总分 {total:.1f}平均分 {avg:.1f}等级 {grade})这里的stu[1:]就用上了切片取当前这个学生列表里从第1个元素到末尾的所有成绩。sum()函数可以直接对这个切片求和省去手写累加循环。我用total_scores.append([total, stu[0]])把总分和学生姓名绑定在一起存成一个子列表这样后面排序的时候不会丢掉姓名。后面计算全班统计量if not total_scores: print(没有录入任何学生无法统计。) return class_total sum(item[0] for item in total_scores) class_avg class_total / len(total_scores) max_score max(item[0] for item in total_scores) min_score min(item[0] for item in total_scores) print(f班级平均分{class_avg:.1f}) print(f最高总分{max_score}) print(f最低总分{min_score}) total_scores.sort(reverseTrue) print(总分前三名) for rank, item in enumerate(total_scores[:3]): print(f第{rank 1}名{item[1]} {item[0]}分)这段代码里有几个地方值得展开说。sum(item[0] for item in total_scores)用了一个生成器表达式把每个学生的总分单独取出来求和。如果你还没学生成器第一次作业阶段也可以写成普通循环慢慢累加效果完全一样。max()和min()同理都是对一个可迭代对象取极值。排序这里我用total_scores.sort(reverseTrue)对列表做原地降序排序。因为每个子列表是[总分, 姓名]的结构排序时Python会先比较第一项总分相等时才会比较姓名所以主要顺序按总分降序排列没有问题。排完之后total_scores[:3]通过切片取出前三项再用enumerate拿到名次序号。打印平均分时用.1f格式化保留一位小数避免出现一长串浮点数。如果班级有0个人sum / len会直接报ZeroDivisionError所以我在统计之前加了空列表判断有意识地补上这个边界保护。3.5 main函数把所有零件串联起来最后用main()做组织调度def main(): students input_students() analyze_scores(students) if __name__ __main__: main()if __name__ __main__:在第二次作业阶段可能还讲不到但它是Python脚本的通用入口写法。简单说Python在执行一个文件时会内置一个__name__变量如果这个文件是被直接运行的__name__就是__main__于是执行下面的main()如果这个文件将来被别的程序当模块导入__name__就不是__main__就不会自动执行避免重复运行。把逻辑拆进函数还有一个好处你可以在交互环境里单独测试某个函数不用每次把整个流程跑一遍。比如我只想验证等级判断就直接调用get_grade(85)立刻能看到良好。3.6 完整代码汇总把上面的片段拼起来就是一份可以直接运行的完整版本def get_grade(score): if score 90: return 优秀 elif score 80: return 良好 elif score 70: return 中等 elif score 60: return 及格 else: return 不及格 def input_students(): students [] count int(input(请输入学生人数)) for i in range(count): name input(f请输入第{i 1}名学生的姓名) chinese float(input(f请输入{name}的语文成绩)) math float(input(f请输入{name}的数学成绩)) english float(input(f请输入{name}的英语成绩)) students.append([name, chinese, math, english]) return students def analyze_scores(students): total_scores [] for stu in students: total sum(stu[1:]) total_scores.append([total, stu[0]]) avg total / 3 grade get_grade(avg) print(f{stu[0]}总分 {total:.1f}平均分 {avg:.1f}等级 {grade}) if not total_scores: print(没有录入任何学生无法统计。) return class_total sum(item[0] for item in total_scores) class_avg class_total / len(total_scores) max_score max(item[0] for item in total_scores) min_score min(item[0] for item in total_scores) print(f班级平均分{class_avg:.1f}) print(f最高总分{max_score}) print(f最低总分{min_score}) total_scores.sort(reverseTrue) print(总分前三名) for rank, item in enumerate(total_scores[:3]): print(f第{rank 1}名{item[1]} {item[0]}分) def main(): students input_students() analyze_scores(students) if __name__ __main__: main()整个文件大约60行功能完整知识点密度足够交一份漂亮的第二次作业。4. 运行结果、边界测试与踩坑实录4.1 正常流程跑一遍我把代码保存为homework2.py在终端运行python homework2.py输入三组数据试了试输出效果如下请输入学生人数3 请输入第1名学生的姓名张三 请输入张三的语文成绩89 请输入张三的数学成绩92 请输入张三的英语成绩88 请输入第2名学生的姓名李四 请输入李四的语文成绩76 请输入李四的数学成绩85 请输入李四的英语成绩91 请输入第3名学生的姓名王五 请输入王五的语文成绩58 请输入王五的数学成绩63 请输入王五的英语成绩59 张三总分 269.0平均分 89.7等级 优秀 李四总分 252.0平均分 84.0等级 良好 王五总分 180.0平均分 60.0等级 及格 班级平均分233.7 最高总分269.0 最低总分180.0 总分前三名 第1名张三 269.0分 第2名李四 252.0分 第3名王五 180.0分功能逻辑完全符合预期。注意张三平均分是89.666…….1f格式化后四舍五入为89.7等级按90分线判定为优秀这里没问题。4.2 三个必测的边界场景作业不是跑通一条正常路径就完了老师验收时往往会故意输入一些极端数据。我自己总结出三个最容易翻车的场景建议提交前都测一遍。第一个是录入人数为0。输入0后程序会跳过循环进入统计函数这时class_total sum(item[0] for item in total_scores)会因为total_scores为空而算不出结果触发ZeroDivisionError。我上面的代码加了if not total_scores空列表保护会打印提示然后退出。如果作业没加这个保护这就是一个明显的扣分点。第二个是输入负数或超过100的成绩。比如有人手滑输入-10程序不会报错但会出现不及格的闹剧结果。对这个阶段来说可以在成绩输入时加一个简单的循环校验while True: chinese float(input(f请输入{name}的语文成绩)) if 0 chinese 100: break print(成绩必须在0到100之间请重新输入。)这种写法用到了while True加break逻辑清楚老师一看就知道你考虑了非法输入。第三个是输入非数字内容比如用户输入字母abc。float(abc)会直接抛出ValueError: could not convert string to float: abc程序当场崩溃。处理思路是把转换过程套进try/except这是很多初学者还没学到的技巧但提前掌握绝对不吃亏while True: try: chinese float(input(f请输入{name}的语文成绩)) break except ValueError: print(请输入数字。)try/except是Python异常处理的基石用在这里既解决了输入校验又提前接触了一个重要概念。4.3 常见报错与排查技巧速查表我在带人做作业时整理了下面这个高频报错对照表非常实用报错信息出现原因排查与解决IndexError: list index out of range访问了列表不存在的索引比如列表只有3个元素却取[3]用len()打印列表长度检查索引从0开始TypeError: unsupported operand type(s) for : str and int忘记做类型转换字符串和数字直接相加检查input()返回值统一用int()或float()转换ValueError: invalid literal for int()输入非数字内容后强行转换加try/except捕获或用字符串的isdigit()先判断IndentationError: unexpected indent缩进不一致Tab和空格混用在VS Code里全选代码用命令面板Convert Indentation to Spaces统一NameError: name xxx is not defined函数内部变量在函数外使用或变量名拼错确认数据通过return传递出来检查拼写排查时我的固定流程是先看报错类型再定位到报错行号最后在那一行前后加print()输出中间变量。比如IndexError就把整个列表打印出来数一数元素个数问题一般就清楚了。千万不要盯着代码干瞪眼打印是最直接的调试手段。4.4 提交前的自查清单每次交作业前我都会过一遍这个清单所有输入提示是否清楚用户知道下一步该输入什么吗非法输入会不会让程序崩溃临界分数比如59、60、69、70、79、80、89、90是否正确分级函数之间数据传递是否顺畅有没有把测试用的临时print删掉最后再看一眼文件名是不是容易读的英文名比如homework2_scores.py而不是带空格的中文名。5. 交作业之后从第二次作业延伸出去的路线5.1 一个立刻能加分的扩展写入Excel如果这份作业做完了还有余力我最推荐做的扩展是把统计结果导出成Excel表格。很多同学听到python写入excel就觉得很难其实用openpyxl库只需要十几行代码。先用pip安装pip install openpyxl然后在代码里加一个导出函数from openpyxl import Workbook def export_to_excel(students, filename成绩单.xlsx): wb Workbook() ws wb.active ws.title 成绩表 ws.append([姓名, 语文, 数学, 英语, 总分]) for stu in students: total sum(stu[1:]) ws.append([stu[0], stu[1], stu[2], stu[3], total]) wb.save(filename) print(f已导出到 {filename})这个功能一加上整个作业的完成度直接高出一个层级因为它顺带演示了文件操作和第三方库的使用。注意openpyxl只处理.xlsx格式老式的.xls文件需要换成xlwt库别搞混了。5.2 交作业前忍不住想试的三道预热题如果第二次作业对你已经完全不是压力我建议你开始挑战三道预热题它们分别是第三次、第四次作业的高频考点预告。第一道是列表去重给定一个包含重复元素的列表用尽量少的内置函数写出一个去重版本。这道题会逼你思考列表、循环和集合的综合使用。第二道是字符串频次统计输入一串英文句子统计每个单词出现的次数并打印。这题开始接触字典是很多人第一次从列表思维跳出来的转折点。第三道是简单猜数字游戏程序随机出一个1到100之间的数用户循环猜猜中为止同时统计猜了多少次。这题同时练习随机数、while循环和条件判断难度适中趣味性很强。三道题都完成后你基本已经越过新手村了。5.3 第二次作业和后续学习方向的关系你可能已经注意到热搜词里凡是带python教程、python基础语法的内容都会强调基础知识的重要性。第二次作业里的列表、循环、分支和函数其实是后面所有方向的地基。想学爬虫得先理解列表怎么存数据、循环怎么遍历页面结果想做数据分析得先用列表或数组组织数据再进行统计计算想接触量化交易那一整套数据整理、条件判断、批量计算的思路本质上就是你在统计成绩时做的事只是把语文数学英语换成了行情数据。这个阶段我不建议急着看太偏门的方向。把第二份作业吃透能独立完成、能讲清楚每一行代码为什么这么写才是真正把基础握在了手里。后面无论是往爬虫、数据分析还是自动化办公走你可能都会感谢今天踏踏实实写完的这份成绩统计系统。我个人最大的体会是第二次作业不是用来证明我会Python的而是用来暴露我哪里还没搞懂的。每次报错都是一次提示每回调试都是一次练习。把这份作业当作一个调试游戏来玩你会发现自己比想象中上手得更快。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →