Cherish's Notebook
切换到深色模式
菜单
Wiki--浏览次数--访问次数--跳出率--平均停留

Python教程

参考黑马程序员 Python 快速入门路线整理的零基础到综合案例笔记

12. 综合案例与复习路线

12.1 综合项目应该练什么

学完基础语法后,不要只刷零散语法题,应该做小项目,把知识串起来。

一个合格的入门综合项目最好覆盖:

  1. 输入输出。
  2. 判断和循环。
  3. 函数拆分。
  4. 列表、字典等容器。
  5. 文件持久化。
  6. 异常处理。
  7. 模块拆分。
  8. 可选:面向对象。
  9. 可选:数据可视化。

本章整理两个方向:

  1. 学生管理系统。
  2. 销售数据统计和可视化。

12.2 项目一:学生管理系统

12.2.1 需求

实现一个命令行学生管理系统:

  1. 添加学生。
  2. 删除学生。
  3. 修改学生。
  4. 查询学生。
  5. 显示所有学生。
  6. 保存到 JSON 文件。
  7. 程序启动时自动读取 JSON 文件。

学生字段:

CODE
学号 student_id
姓名 name
年龄 age
成绩 score

12.3 函数版学生管理系统

CODE
import json
from pathlib import Path

DATA_FILE = Path("students.json")


def load_students():
    if not DATA_FILE.exists():
        return []

    try:
        with open(DATA_FILE, "r", encoding="utf-8") as file:
            return json.load(file)
    except json.JSONDecodeError:
        print("数据文件格式错误,已使用空数据启动")
        return []


def save_students(students):
    with open(DATA_FILE, "w", encoding="utf-8") as file:
        json.dump(students, file, ensure_ascii=False, indent=2)


def show_menu():
    print("====== 学生管理系统 ======")
    print("1. 添加学生")
    print("2. 删除学生")
    print("3. 修改学生")
    print("4. 查询学生")
    print("5. 显示所有学生")
    print("0. 退出系统")


def find_student(students, student_id):
    for student in students:
        if student["student_id"] == student_id:
            return student
    return None


def input_int(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("请输入整数")


def input_float(prompt):
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print("请输入数字")


def add_student(students):
    student_id = input("请输入学号:")

    if find_student(students, student_id):
        print("学号已存在")
        return

    name = input("请输入姓名:")
    age = input_int("请输入年龄:")
    score = input_float("请输入成绩:")

    students.append({
        "student_id": student_id,
        "name": name,
        "age": age,
        "score": score,
    })
    save_students(students)
    print("添加成功")


def delete_student(students):
    student_id = input("请输入要删除的学号:")
    student = find_student(students, student_id)

    if student is None:
        print("学生不存在")
        return

    students.remove(student)
    save_students(students)
    print("删除成功")


def update_student(students):
    student_id = input("请输入要修改的学号:")
    student = find_student(students, student_id)

    if student is None:
        print("学生不存在")
        return

    name = input("请输入新姓名:")
    age = input_int("请输入新年龄:")
    score = input_float("请输入新成绩:")

    student["name"] = name
    student["age"] = age
    student["score"] = score

    save_students(students)
    print("修改成功")


def query_student(students):
    student_id = input("请输入要查询的学号:")
    student = find_student(students, student_id)

    if student is None:
        print("学生不存在")
        return

    print_student(student)


def print_student(student):
    print(
        f"{student['student_id']}\t"
        f"{student['name']}\t"
        f"{student['age']}\t"
        f"{student['score']}"
    )


def show_all_students(students):
    if not students:
        print("暂无学生")
        return

    print("学号\t姓名\t年龄\t成绩")
    for student in students:
        print_student(student)


def main():
    students = load_students()

    while True:
        show_menu()
        choice = input("请输入操作:")

        if choice == "1":
            add_student(students)
        elif choice == "2":
            delete_student(students)
        elif choice == "3":
            update_student(students)
        elif choice == "4":
            query_student(students)
        elif choice == "5":
            show_all_students(students)
        elif choice == "0":
            print("退出系统")
            break
        else:
            print("输入错误")


if __name__ == "__main__":
    main()

这个项目串联了:

  1. 菜单循环。
  2. 函数封装。
  3. 列表字典。
  4. JSON 读写。
  5. 异常处理。
  6. if __name__ == "__main__"

12.4 面向对象版设计思路

可以进一步拆成两个类:

  1. Student:表示单个学生。
  2. StudentManager:负责学生增删改查和文件保存。

示意代码:

CODE
from dataclasses import dataclass


@dataclass
class Student:
    student_id: str
    name: str
    age: int
    score: float

    def to_dict(self):
        return {
            "student_id": self.student_id,
            "name": self.name,
            "age": self.age,
            "score": self.score,
        }

    @classmethod
    def from_dict(cls, data):
        return cls(
            data["student_id"],
            data["name"],
            data["age"],
            data["score"],
        )

管理器示意:

CODE
class StudentManager:
    def __init__(self):
        self.students = []

    def find_by_id(self, student_id):
        for student in self.students:
            if student.student_id == student_id:
                return student
        return None

    def add(self, student):
        if self.find_by_id(student.student_id):
            return False
        self.students.append(student)
        return True

如果项目逻辑越来越多,面向对象版会比纯函数版更容易扩展。

12.5 项目二:销售数据统计

12.5.1 数据结构

CODE
sales = [
    {"date": "2024-10-01", "category": "手机", "amount": 12000},
    {"date": "2024-10-01", "category": "电脑", "amount": 18000},
    {"date": "2024-10-02", "category": "手机", "amount": 15000},
    {"date": "2024-10-02", "category": "电脑", "amount": 16000},
]

12.5.2 按日期统计

CODE
daily_total = {}

for item in sales:
    date = item["date"]
    amount = item["amount"]
    daily_total[date] = daily_total.get(date, 0) + amount

print(daily_total)

12.5.3 按类别统计

CODE
category_total = {}

for item in sales:
    category = item["category"]
    amount = item["amount"]
    category_total[category] = category_total.get(category, 0) + amount

print(category_total)

12.5.4 找销售额最高的一天

CODE
top_date, top_amount = max(daily_total.items(), key=lambda item: item[1])
print(top_date, top_amount)

12.6 绘制柱状图

CODE
from pyecharts import options as opts
from pyecharts.charts import Bar

category_total = {
    "手机": 27000,
    "电脑": 34000,
    "耳机": 8000,
}

bar = Bar()
bar.add_xaxis(list(category_total.keys()))
bar.add_yaxis("销售额", list(category_total.values()))
bar.set_global_opts(
    title_opts=opts.TitleOpts(title="品类销售额"),
    xaxis_opts=opts.AxisOpts(name="品类"),
    yaxis_opts=opts.AxisOpts(name="销售额"),
)
bar.render("category_sales.html")

12.7 绘制时间线柱状图

时间线适合展示不同日期、月份、年份的数据变化。

CODE
from pyecharts import options as opts
from pyecharts.charts import Bar, Timeline

data = {
    "2024-10-01": {"手机": 12000, "电脑": 18000},
    "2024-10-02": {"手机": 15000, "电脑": 16000},
    "2024-10-03": {"手机": 17000, "电脑": 19000},
}

timeline = Timeline()

for date, category_data in data.items():
    bar = Bar()
    bar.add_xaxis(list(category_data.keys()))
    bar.add_yaxis("销售额", list(category_data.values()))
    bar.set_global_opts(title_opts=opts.TitleOpts(title=f"{date}销售额"))
    timeline.add(bar, date)

timeline.render("timeline_sales.html")

12.8 绘制地图

地图适合展示地区数据。

CODE
from pyecharts import options as opts
from pyecharts.charts import Map

data = [
    ("北京", 120),
    ("上海", 150),
    ("广东", 200),
    ("浙江", 180),
]

map_chart = Map()
map_chart.add("销售额", data, "china")
map_chart.set_global_opts(
    title_opts=opts.TitleOpts(title="地区销售额"),
    visualmap_opts=opts.VisualMapOpts(max_=200),
)
map_chart.render("map_sales.html")

地图数据的地区名称要和 pyecharts 内置地图名称匹配,否则可能显示不出来。

12.9 项目拆分建议

当代码超过一个文件时,可以这样组织:

CODE
sales_project/
  main.py
  data/
    sales.json
  services/
    __init__.py
    sales_service.py
  charts/
    __init__.py
    chart_builder.py
  utils/
    __init__.py
    file_utils.py

职责:

  1. main.py:程序入口。
  2. file_utils.py:读写 JSON。
  3. sales_service.py:统计销售数据。
  4. chart_builder.py:生成图表。

12.10 Python基础复习清单

语法基础:

  1. 会写变量、注释、输入输出。
  2. 会使用 int、float、str、bool。
  3. 会做类型转换。
  4. 会使用 f-string 格式化输出。

流程控制:

  1. 会写 if elif else
  2. 会写 whilefor
  3. 理解 breakcontinue
  4. 能写嵌套循环。

函数:

  1. 会定义和调用函数。
  2. 理解参数和返回值。
  3. 知道局部变量和全局变量。
  4. 会使用默认参数、关键字参数、不定长参数。

容器:

  1. 会使用列表增删改查。
  2. 会遍历列表、字典。
  3. 会使用切片。
  4. 会用集合去重。
  5. 会处理列表嵌套字典。

文件和模块:

  1. 会读写文本文件。
  2. 会读写 JSON。
  3. 会捕获常见异常。
  4. 会导入模块和第三方包。
  5. 会创建简单包结构。

项目能力:

  1. 能把代码拆成函数。
  2. 能把数据保存到文件。
  3. 能处理用户输入错误。
  4. 能写一个完整菜单程序。
  5. 能用 pyecharts 生成图表。

12.11 推荐练习顺序

  1. 猜数字游戏。
  2. ATM 菜单程序。
  3. 学生成绩统计。
  4. 学生管理系统函数版。
  5. 学生管理系统文件持久化版。
  6. 学生管理系统面向对象版。
  7. 销售数据统计。
  8. 销售数据可视化。

12.12 常见学习误区

  1. 只看视频不敲代码。
  2. 一报错就复制错误去搜,不先读报错位置。
  3. 变量名随便写,后续自己看不懂。
  4. 所有代码都写在一个文件一个函数里。
  5. 不保存练习代码,复习时没有材料。
  6. 还没掌握列表字典就急着学框架。
  7. 不会读官方文档,只依赖教程。

12.13 如何读报错

报错通常从下往上看最后几行。

示例:

CODE
ValueError: invalid literal for int() with base 10: 'abc'

说明:

  1. 异常类型是 ValueError
  2. 原因是 int() 无法把 'abc' 转成整数。
  3. 应该检查输入内容或增加异常处理。

再看文件名和行号:

CODE
File "main.py", line 10, in <module>

表示错误发生在 main.py 第 10 行。

12.14 后续学习方向

Python 基础完成后,可以按兴趣选择方向:

  1. 自动化办公:openpyxlpython-docxpdfplumber
  2. 数据分析:numpypandasmatplotlib
  3. Web 后端:FlaskFastAPIDjango
  4. 爬虫:requestsBeautifulSoupScrapy
  5. 测试开发:pytestselenium、接口测试。
  6. 人工智能:numpypandaspytorch
  7. 运维脚本:ossubprocessparamiko

不要所有方向同时学。先把 Python 基础和一个小项目做扎实,再选择方向。

12.15 结课练习

  1. 完成函数版学生管理系统。
  2. 给学生管理系统增加 JSON 持久化。
  3. 给学生管理系统增加异常处理。
  4. 把学生管理系统改成面向对象版。
  5. 使用 pyecharts 绘制学生成绩柱状图。
  6. 读取销售 JSON 数据,统计每日销售额并绘制折线图。
  7. 按品类统计销售额并绘制柱状图。
  8. 写一份自己的 Python 学习路线图。