Python实战项目02:学生成绩管理系统(控制台|CSV导出|完整落地)

📌 实战系列:Python零基础综合实战项目(第2/5套)

🎯 项目定位:结构化数据综合实战,巩固函数、列表字典、循环分支、文件读写、异常处理、sorted+lambda排序。模拟真实业务管理系统,完成学生信息增删改查、分数排序、导出CSV文件。

✅ 项目难度:⭐⭐

✅ 前置知识:1‑10章,容器、函数、lambda排序、文件读写、异常处理

✅ 学到的核心能力

  • 业务需求拆解,模块化函数拆分开发

  • 列表嵌套字典存储结构化业务数据

  • lambda + sorted完成多条件业务排序

  • CSV文件导出,办公软件直接打开查看数据

  • 输入校验、边界判断、异常捕获,防止程序闪退

  • 区分内存数据与磁盘持久化存储


一、项目需求说明

实现控制台版学生成绩管理系统,具备完整业务功能:

  1. 新增学生信息:姓名、学号、分数

  2. 查看全部学生列表

  3. 按学号查询学生信息

  4. 修改指定学号学生的成绩

  5. 按学号删除学生记录

  6. 按分数降序对学生数据排序展示(lambda实现)

  7. 将全部学生数据导出为 score.csv,Excel/WPS可直接打开

  8. 菜单循环交互,非法输入做容错处理,程序不崩溃


二、项目架构模块拆解

遵循单一职责原则,一个功能封装一个函数,避免大段堆砌代码。

  1. add_student():新增学生信息

  2. show_all():展示全部学生

  3. search_by_id():根据学号查询学生

  4. modify_score():修改学生成绩

  5. delete_student():按学号删除学生

  6. sort_by_score():分数排序展示,使用sorted + lambda

  7. export_csv():导出数据到csv文件

  8. main():主菜单调度入口

数据存储:内存使用列表嵌套字典保存学生数据;本版本内存存储,程序关闭数据丢失,拓展作业实现文件持久化保存。

复制代码
# =============================================
# 实战项目02:学生成绩管理系统 控制台版
# 功能:增删改查、分数排序、导出CSV
# =============================================

# 全局内存存储学生数据,列表嵌套字典
student_list = []


def add_student():
    """新增学生信息"""
    sid = input("请输入学生学号:").strip()
    # 判断学号是否重复
    for s in student_list:
        if s["sid"] == sid:
            print("❌ 该学号已经存在,不能重复添加!")
            return
    name = input("请输入学生姓名:").strip()
    try:
        score = float(input("请输入学生分数:").strip())
    except ValueError:
        print("❌ 分数必须输入数字!")
        return

    stu_dict = {
        "sid": sid,
        "name": name,
        "score": score
    }
    student_list.append(stu_dict)
    print("✅ 学生信息添加成功!")


def show_all():
    """展示全部学生信息"""
    if not student_list:
        print("📭 当前暂无学生数据!")
        return
    print("\n====================学生成绩列表====================")
    print(f"{'学号':<10}{'姓名':<10}{'分数':<10}")
    print("----------------------------------------------------")
    for stu in student_list:
        print(f"{stu['sid']:<10}{stu['name']:<10}{stu['score']:<10}")
    print("====================================================\n")


def search_by_id():
    """根据学号查询学生"""
    sid = input("请输入要查询的学生学号:").strip()
    for stu in student_list:
        if stu["sid"] == sid:
            print(f"\n✅ 查询结果:学号:{stu['sid']} 姓名:{stu['name']} 分数:{stu['score']}")
            return
    print("❌ 未找到该学号的学生!")


def modify_score():
    """修改学生成绩"""
    sid = input("请输入要修改成绩的学生学号:").strip()
    for stu in student_list:
        if stu["sid"] == sid:
            print(f"找到学生:{stu['name']},原分数:{stu['score']}")
            try:
                new_score = float(input("请输入新的分数:").strip())
            except ValueError:
                print("❌ 分数必须为数字!")
                return
            stu["score"] = new_score
            print("✅ 成绩修改完成!")
            return
    print("❌ 未找到该学号学生!")


def delete_student():
    """按学号删除学生"""
    sid = input("请输入要删除的学生学号:").strip()
    for index, stu in enumerate(student_list):
        if stu["sid"] == sid:
            del student_list[index]
            print("✅ 学生记录删除成功!")
            return
    print("❌ 未找到该学号学生!")


def sort_by_score():
    """按分数降序排序,使用sorted + lambda"""
    if not student_list:
        print("📭 暂无学生数据,无法排序!")
        return
    # lambda取score作为排序key,reverse=True降序
    sorted_stu = sorted(student_list, key=lambda x: x["score"], reverse=True)
    print("\n====================成绩降序排列====================")
    print(f"{'学号':<10}{'姓名':<10}{'分数':<10}")
    print("----------------------------------------------------")
    for stu in sorted_stu:
        print(f"{stu['sid']:<10}{stu['name']:<10}{stu['score']:<10}")
    print("====================================================\n")


def export_csv():
    """导出学生数据到score.csv文件,Excel/WPS打开"""
    if not student_list:
        print("📭 暂无数据,无法导出!")
        return
    try:
        with open("score.csv", "w", encoding="utf‑8‑sig") as f:
            # 写入表头
            f.write("学号,姓名,分数\n")
            for stu in student_list:
                line = f"{stu['sid']},{stu['name']},{stu['score']}\n"
                f.write(line)
        print("✅ 导出成功!文件名称:score.csv,可以用Excel直接打开")
    except Exception as e:
        print(f"❌ 文件导出异常:{e}")


def main():
    """主菜单"""
    print("========== 欢迎使用学生成绩管理系统 ==========")
    while True:
        print("\n【1】新增学生")
        print("【2】查看全部学生")
        print("【3】按学号查询学生")
        print("【4】修改学生成绩")
        print("【5】删除学生记录")
        print("【6】按分数降序排序展示")
        print("【7】导出数据到CSV文件")
        print("【0】退出系统")

        select = input("请输入功能序号:").strip()
        if select == "1":
            add_student()
        elif select == "2":
            show_all()
        elif select == "3":
            search_by_id()
        elif select == "4":
            modify_score()
        elif select == "5":
            delete_student()
        elif select == "6":
            sort_by_score()
        elif select == "7":
            export_csv()
        elif select == "0":
            print("👋 系统退出,感谢使用!")
            break
        else:
            print("❌ 输入无效,请选择菜单中0‑7的序号!")


if __name__ == "__main__":
    main()

四、项目运行说明

  • 运行程序之后出现功能菜单,输入数字序号调用对应功能

  • 新增学生时学号不能重复;分数输入非数字会捕获异常,不会直接崩溃

  • 功能6使用 sorted+lambda 完成分数降序排序,不修改原始内存数据

  • 导出CSV使用 utf‑8‑sig 编码,解决Excel打开中文乱码问题

  • ⚠️ 当前版本数据保存在内存,关闭程序全部丢失,拓展作业实现持久化


五、核心知识点复盘

  • 列表嵌套字典:业务系统最常用结构化数据存储方式

  • lambda + sorted排序:对字典列表按照指定字段排序

  • enumerate:同时获取索引与元素,用于删除列表指定项

  • try‑except异常捕获:拦截非法数字输入,提升程序健壮性

  • CSV文本导出:生成办公软件可识别的数据文件

  • 模块化函数开发思想:一个功能对应一个独立函数


六、课后拓展作业(必做,强化实战能力)

  1. 增加持久化功能:程序启动自动加载学生数据,操作完成保存到本地json文件,关闭程序数据不丢失。

  2. 拓展排序逻辑:实现多条件排序,分数相同按学号升序展示。

  3. 增加按分数区间筛选功能,输入最低、最高分,输出区间内所有学生。

  4. 增加统计功能:计算全班平均分、最高分、最低分。

七、课后拓展作业 完整参考答案

以下答案基于原有项目代码拓展,完全兼容原版程序,可直接复制替换运行,所有功能落地可用。

作业1:JSON数据持久化(启动加载 + 退出保存)

实现效果:程序重启不丢失学生数据,自动读写 student_data.json 文件

复制代码
import json

# 数据文件路径
DATA_FILE = "student_data.json"
# 全局学生数据
student_list = []


def load_data():
    """程序启动加载本地JSON数据"""
    global student_list
    try:
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            student_list = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        # 文件不存在/内容为空,初始化空列表
        student_list = []


def save_data():
    """实时保存数据到本地JSON文件"""
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(student_list, f, ensure_ascii=False, indent=2)


# ========== 原有所有函数不变(省略重复代码,直接复用) ==========
def add_student():
    sid = input("请输入学生学号:").strip()
    for s in student_list:
        if s["sid"] == sid:
            print("❌ 该学号已经存在,不能重复添加!")
            return
    name = input("请输入学生姓名:").strip()
    try:
        score = float(input("请输入学生分数:").strip())
    except ValueError:
        print("❌ 分数必须输入数字!")
        return
    stu_dict = {"sid": sid, "name": name, "score": score}
    student_list.append(stu_dict)
    save_data()  # 新增后自动保存
    print("✅ 学生信息添加成功!")

# 省略:show_all()、search_by_id()、modify_score()、delete_student()、export_csv()
# 【关键修改】:增/改/删功能后,全部添加 save_data() 即可持久化

def modify_score():
    sid = input("请输入要修改成绩的学生学号:").strip()
    for stu in student_list:
        if stu["sid"] == sid:
            print(f"找到学生:{stu['name']},原分数:{stu['score']}")
            try:
                new_score = float(input("请输入新的分数:").strip())
            except ValueError:
                print("❌ 分数必须为数字!")
                return
            stu["score"] = new_score
            save_data() # 修改后保存
            print("✅ 成绩修改完成!")
            return
    print("❌ 未找到该学号学生!")

def delete_student():
    sid = input("请输入要删除的学生学号:").strip()
    for index, stu in enumerate(student_list):
        if stu["sid"] == sid:
            del student_list[index]
            save_data() # 删除后保存
            print("✅ 学生记录删除成功!")
            return
    print("❌ 未找到该学号学生!")

# 完整主函数
def main():
    load_data() # 启动加载数据
    print("========== 欢迎使用学生成绩管理系统(持久化版) ==========")
    while True:
        print("\n【1】新增学生【2】查看全部学生【3】按学号查询")
        print("【4】修改成绩【5】删除学生【6】分数排序【7】导出CSV【0】退出")
        select = input("请输入功能序号:").strip()
        if select == "1":
            add_student()
        elif select == "2":
            show_all()
        elif select == "3":
            search_by_id()
        elif select == "4":
            modify_score()
        elif select == "5":
            delete_student()
        elif select == "6":
            sort_by_score()
        elif select == "7":
            export_csv()
        elif select == "0":
            print("👋 数据已自动保存,系统退出!")
            break
        else:
            print("❌ 输入无效,请选择0-7序号!")

if __name__ == "__main__":
    main()

作业2:多条件排序(分数降序、同分学号升序)

替换原 sort_by_score() 函数,实现精准多条件排序

复制代码
def sort_by_score():
    """多条件排序:分数降序 → 分数相同按学号升序"""
    if not student_list:
        print("📭 暂无学生数据,无法排序!")
        return
    # 负号实现分数降序,字符串默认升序排列学号
    sorted_stu = sorted(student_list, key=lambda x: (-x["score"], x["sid"]))
    print("\n====================多条件排序结果====================")
    print(f"{'学号':<10}{'姓名':<10}{'分数':<10}")
    print("----------------------------------------------------")
    for stu in sorted_stu:
        print(f"{stu['sid']:<10}{stu['name']:<10}{stu['score']:<10}")
    print("====================================================\n")

作业3:分数区间筛选功能

新增独立筛选函数,添加到菜单即可使用

复制代码
def filter_by_score():
    """根据分数区间筛选学生"""
    if not student_list:
        print("📭 暂无学生数据!")
        return
    try:
        min_score = float(input("请输入最低分数:"))
        max_score = float(input("请输入最高分数:"))
    except ValueError:
        print("❌ 请输入合法数字分数!")
        return

    # 筛选区间内的学生
    res_list = [s for s in student_list if min_score <= s["score"] <= max_score]
    if not res_list:
        print(f"📭 暂无{min_score}-{max_score}分数区间的学生!")
        return

    print(f"\n===== 分数区间【{min_score}-{max_score}】学生列表 =====")
    print(f"{'学号':<10}{'姓名':<10}{'分数':<10}")
    for stu in res_list:
        print(f"{stu['sid']:<10}{stu['name']:<10}{stu['score']:<10}")
    print("====================================================\n")

使用方式:在main主菜单添加对应选项即可:【8】分数区间筛选

作业4:班级成绩统计功能(平均分/最高分/最低分)

复制代码
def score_statistics():
    """统计全班成绩:最高分、最低分、平均分"""
    if not student_list:
        print("📭 暂无学生数据,无法统计!")
        return
    # 提取所有分数
    score_list = [s["score"] for s in student_list]
    max_s = max(score_list)
    min_s = min(score_list)
    avg_s = sum(score_list) / len(score_list)

    print("\n========== 班级成绩统计 ==========")
    print(f"✅ 学生总人数:{len(student_list)} 人")
    print(f"🏆 最高分:{max_s} 分")
    print(f"📉 最低分:{min_s} 分")
    print(f"📊 平均分:{avg_s:.2f} 分")
    print("================================\n")

拓展总结

  • 持久化功能核心:JSON文件读写 + 增删改后自动保存

  • 多条件排序核心:lambda 返回元组,设置主次排序规则

  • 筛选、统计功能基于列表推导式、内置函数实现,简洁高效

  • 所有拓展功能完全兼容原版代码,可直接嵌入项目使用


八、下期预告

下一个实战项目:项目03|批量文件重命名工具,学习os模块操作本地文件系统,写一个日常办公直接拿来用的小工具。

💖点赞 + 收藏 + 关注,跟随专栏完成全套Python零基础学习

相关推荐
qq5918406857 小时前
uiautomator2自动化安卓手机操作
python
80s7778 小时前
动态代理和静态代理的区别,动态代理怎么提高网络安全性
python
浪子明X8 小时前
十六位账本怎样发现传输差错:Internet Checksum 生活类比
开发语言
niucloud-admin9 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github
小叶肥辉9 小时前
LangChain链和LangGraph图的学习笔记【三】——分别用langchain_openai库和langchain_community库调用大模型
笔记·python·langchain
2401_8734794010 小时前
IP属地为什么有时显示外省?用IP查询工具核查动态分配、运营商出口与GeoIP库
python·tcp/ip·ip
xiangyun6111 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun6111 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
OKkankan12 小时前
LangChain 能力详解!:输出解析、RAG、向量数据库与 Retriever 检索器
数据结构·python·langchain·ai应用