← 返回 Python 7天入门专题

Day 7 · 实战项目

3个完整项目 · 综合运用全部知识 | 建议时长:4-5小时
第一性原理:前6天学了所有零件——变量、循环、函数、类、文件、异常。但零件不会自动变成机器。Day 7 把零件组装成能用的程序。3个项目从易到难,每个都综合运用多天知识。完成它们,你就真正"会"Python了。

项目总览

项目1:待办事项管理器 (Todo List)

命令行待办事项工具:增删改查、优先级标记、JSON持久化。

变量/类型 控制流 列表/字典 函数 文件/JSON

项目2:学生成绩管理系统

面向对象的成绩管理:多班级多学生、统计分析、文件存储。

控制流 嵌套结构 函数 OOP 文件/异常

项目3:简易网页爬虫+数据分析

爬取网页数据,解析提取信息,统计分析并生成报告。

字符串 循环 字典/Counter 函数/lambda OOP 模块/正则/文件

项目1:待办事项管理器

需求分析

完整代码

"""
待办事项管理器
综合运用:列表、字典、函数、文件操作、JSON、异常处理
"""
import json
import os

TODO_FILE = "todos.json"

# === 数据层:文件读写 ===
def load_todos():
    """从JSON文件加载待办列表"""
    if not os.path.exists(TODO_FILE):
        return []
    try:
        with open(TODO_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    except (json.JSONDecodeError, IOError):
        print("⚠️ 数据文件损坏,重新开始")
        return []

def save_todos(todos):
    """保存待办列表到JSON文件"""
    with open(TODO_FILE, "w", encoding="utf-8") as f:
        json.dump(todos, f, ensure_ascii=False, indent=2)

# === 业务层:操作函数 ===
def add_todo(todos, title, priority="中"):
    """添加待办事项"""
    todo = {
        "id": len(todos) + 1,
        "title": title,
        "priority": priority,
        "done": False
    }
    todos.append(todo)
    save_todos(todos)
    print(f"✅ 已添加: [{priority}] {title}")

def list_todos(todos):
    """列出所有待办事项"""
    if not todos:
        print("📭 暂无待办事项")
        return

    # 按优先级排序:高>中>低
    priority_order = {"高": 0, "中": 1, "低": 2}
    sorted_todos = sorted(todos, key=lambda t: (
        priority_order.get(t["priority"], 99),
        t["id"]
    ))

    print("\n{'='*40}")
    print("📋 待办事项列表")
    print("{'='*40}")
    for t in sorted_todos:
        status = "✅" if t["done"] else "⬜"
        priority_mark = {"高": "🔴", "中": "🟡", "低": "🟢"}.get(t["priority"], "⚪")
        print(f"{status} [{t['id']}] {priority_mark}{t['priority']} | {t['title']}")

    done_count = sum(1 for t in todos if t["done"])
    print(f"\n总计: {len(todos)}项, 已完成: {done_count}项")

def complete_todo(todos, todo_id):
    """标记完成"""
    for t in todos:
        if t["id"] == todo_id:
            t["done"] = True
            save_todos(todos)
            print(f"✅ 已完成: {t['title']}")
            return
    print("❌ 未找到该事项")

def delete_todo(todos, todo_id):
    """删除事项"""
    for i, t in enumerate(todos):
        if t["id"] == todo_id:
            removed = todos.pop(i)
            save_todos(todos)
            print(f"🗑️ 已删除: {removed['title']}")
            return
    print("❌ 未找到该事项")

# === 交互层:主循环 ===
def main():
    todos = load_todos()
    print("📌 待办事项管理器")

    while True:
        print("\n操作: 1.添加 2.查看 3.完成 4.删除 5.退出")
        choice = input(">>> ").strip()

        if choice == "1":
            title = input("事项标题: ").strip()
            if not title:
                print("标题不能为空")
                continue
            priority = input("优先级(高/中/低, 默认中): ").strip() or "中"
            if priority not in ("高", "中", "低"):
                priority = "中"
            add_todo(todos, title, priority)

        elif choice == "2":
            list_todos(todos)

        elif choice == "3":
            list_todos(todos)
            try:
                todo_id = int(input("完成事项ID: "))
                complete_todo(todos, todo_id)
            except ValueError:
                print("请输入有效数字")

        elif choice == "4":
            list_todos(todos)
            try:
                todo_id = int(input("删除事项ID: "))
                delete_todo(todos, todo_id)
            except ValueError:
                print("请输入有效数字")

        elif choice == "5":
            print("再见!")
            break
        else:
            print("无效选择")

if __name__ == "__main__":
    main()
代码架构解析:这个项目分三层——数据层(load/save)负责文件读写、业务层(add/list/complete/delete)负责核心逻辑、交互层(main)负责用户交互。分层让代码清晰、易维护。

项目2:学生成绩管理系统(面向对象)

需求分析

完整代码

"""
学生成绩管理系统 (OOP版)
综合运用:类、继承、魔术方法、文件操作、异常处理
"""
import json
import os

# === Student类 ===
class Student:
    def __init__(self, student_id, name):
        self.student_id = student_id
        self.name = name
        self.scores = {}  # {科目: 分数}

    def add_score(self, subject, score):
        if not (0 <= score <= 100):
            raise ValueError(f"分数必须在0-100之间,输入了{score}")
        self.scores[subject] = score

    @property
    def average(self):
        if not self.scores:
            return 0
        return sum(self.scores.values()) / len(self.scores)

    @property
    def grade(self):
        avg = self.average
        if avg >= 90: return "A"
        elif avg >= 80: return "B"
        elif avg >= 70: return "C"
        elif avg >= 60: return "D"
        else: return "F"

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

    @classmethod
    def from_dict(cls, data):
        s = cls(data["student_id"], data["name"])
        s.scores = data["scores"]
        return s

    def __str__(self):
        scores_str = ", ".join(f"{k}:{v}" for k, v in self.scores.items())
        return f"[{self.student_id}] {self.name} | {scores_str} | 均:{self.average:.1f}({self.grade})"

# === Classroom类 ===
class Classroom:
    def __init__(self, name):
        self.name = name
        self.students = {}  # {student_id: Student}

    def add_student(self, student):
        if student.student_id in self.students:
            print(f"学号{student.student_id}已存在")
            return False
        self.students[student.student_id] = student
        return True

    def get_student(self, student_id):
        return self.students.get(student_id)

    def remove_student(self, student_id):
        if student_id in self.students:
            del self.students[student_id]
            return True
        return False

    def list_students(self, sort_by="average"):
        students = list(self.students.values())
        if sort_by == "average":
            students.sort(key=lambda s: s.average, reverse=True)
        elif sort_by == "id":
            students.sort(key=lambda s: s.student_id)
        return students

    def class_stats(self):
        if not self.students:
            return "班级为空"
        averages = [s.average for s in self.students.values()]
        return {
            "人数": len(averages),
            "最高分": max(averages),
            "最低分": min(averages),
            "平均分": sum(averages) / len(averages),
            "及格率": sum(1 for a in averages if a >= 60) / len(averages)
        }

    def __len__(self):
        return len(self.students)

    def __str__(self):
        return f"班级[{self.name}] - {len(self)}人"

# === GradeSystem类 (主控) ===
class GradeSystem:
    DATA_FILE = "grade_system.json"

    def __init__(self):
        self.classrooms = {}  # {班级名: Classroom}

    def add_classroom(self, name):
        if name not in self.classrooms:
            self.classrooms[name] = Classroom(name)
            print(f"创建班级: {name}")

    def save(self):
        data = {}
        for name, classroom in self.classrooms.items():
            data[name] = [s.to_dict() for s in classroom.students.values()]
        with open(self.DATA_FILE, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)

    def load(self):
        if not os.path.exists(self.DATA_FILE):
            return
        try:
            with open(self.DATA_FILE, "r", encoding="utf-8") as f:
                data = json.load(f)
            for class_name, students in data.items():
                self.add_classroom(class_name)
                for s_data in students:
                    s = Student.from_dict(s_data)
                    self.classrooms[class_name].add_student(s)
        except Exception as e:
            print(f"加载数据失败: {e}")

    def run(self):
        self.load()
        print("🎓 学生成绩管理系统")

        while True:
            print("\n1.选班级 2.添加学生 3.录成绩 4.查看排名 5.班级统计 6.保存退出")
            choice = input(">>> ").strip()

            if choice == "1":
                name = input("班级名(新建或选择): ").strip()
                self.add_classroom(name)
                print(f"当前班级: {name}")

            elif choice == "2":
                class_name = input("班级: ").strip()
                if class_name not in self.classrooms:
                    print("班级不存在")
                    continue
                sid = input("学号: ").strip()
                name = input("姓名: ").strip()
                if self.classrooms[class_name].add_student(Student(sid, name)):
                    print(f"添加成功: {name}")

            elif choice == "3":
                class_name = input("班级: ").strip()
                sid = input("学号: ").strip()
                classroom = self.classrooms.get(class_name)
                if not classroom:
                    print("班级不存在"); continue
                student = classroom.get_student(sid)
                if not student:
                    print("学生不存在"); continue
                subject = input("科目: ").strip()
                try:
                    score = float(input("分数: "))
                    student.add_score(subject, score)
                    print(f"已录入: {subject} = {score}")
                except ValueError as e:
                    print(f"错误: {e}")

            elif choice == "4":
                class_name = input("班级: ").strip()
                classroom = self.classrooms.get(class_name)
                if not classroom:
                    print("班级不存在"); continue
                print(f"\n{classroom} — 成绩排名")
                for rank, s in enumerate(classroom.list_students(), 1):
                    print(f"  第{rank}名 {s}")

            elif choice == "5":
                class_name = input("班级: ").strip()
                classroom = self.classrooms.get(class_name)
                if not classroom:
                    print("班级不存在"); continue
                stats = classroom.class_stats()
                print(f"\n📊 {classroom} 统计:")
                for k, v in stats.items():
                    if isinstance(v, float):
                        print(f"  {k}: {v:.1%}" if "率" in k else f"  {k}: {v:.1f}")
                    else:
                        print(f"  {k}: {v}")

            elif choice == "6":
                self.save()
                print("💾 已保存,再见!")
                break
            else:
                print("无效选择")

if __name__ == "__main__":
    GradeSystem().run()

项目3:文本数据分析工具

需求分析

完整代码

"""
文本数据分析工具
综合运用:字符串操作、正则、Counter、文件读写、OOP、异常处理
"""
import re
import json
from collections import Counter
from datetime import datetime

class TextAnalyzer:
    """文本分析器"""

    def __init__(self, text):
        self.text = text
        self._results = {}

    @classmethod
    def from_file(cls, filepath):
        """从文件创建分析器"""
        try:
            with open(filepath, "r", encoding="utf-8") as f:
                return cls(f.read())
        except FileNotFoundError:
            print(f"文件不存在: {filepath}")
            return None
        except Exception as e:
            print(f"读取失败: {e}")
            return None

    @classmethod
    def from_input(cls):
        """从用户输入创建"""
        print("输入文本(空行结束):")
        lines = []
        while True:
            line = input()
            if not line:
                break
            lines.append(line)
        return cls("\n".join(lines))

    def analyze(self):
        """执行完整分析"""
        text = self.text

        # 基础统计
        lines = text.splitlines()
        chars = len(text)
        chars_no_space = len(text.replace(" ", "").replace("\n", ""))

        # 提取英文单词
        english_words = re.findall(rr'[a-zA-Z]+', text.lower())

        # 提取中文字符
        chinese_chars = re.findall(rr'[\u4e00-\u9fff]', text)

        # 词频统计
        word_freq = Counter(english_words)
        char_freq = Counter(chinese_chars)

        # 平均词长
        avg_word_len = sum(len(w) for w in english_words) / len(english_words) if english_words else 0

        self._results = {
            "总行数": len(lines),
            "总字符数": chars,
            "无空格字符数": chars_no_space,
            "英文单词数": len(english_words),
            "中文字符数": len(chinese_chars),
            "平均词长": round(avg_word_len, 2),
            "英文词频Top10": word_freq.most_common(10),
            "中文字频Top10": char_freq.most_common(10),
        }
        return self

    def display(self):
        """显示分析结果"""
        r = self._results
        print("\n📊 文本分析报告")
        print("=" * 40)
        print(f"总行数:       {r['总行数']}")
        print(f"总字符数:     {r['总字符数']}")
        print(f"无空格字符数: {r['无空格字符数']}")
        print(f"英文单词数:   {r['英文单词数']}")
        print(f"中文字符数:   {r['中文字符数']}")
        print(f"平均词长:     {r['平均词长']}")

        print(f"\n🔤 英文词频 Top 10:")
        for word, count in r["英文词频Top10"]:
            bar = "█" * min(count, 30)
            print(f"  {word:15s} {count:3d} {bar}")

        print(f"\n🀄 中文字频 Top 10:")
        for char, count in r["中文字频Top10"]:
            print(f"  '{char}' {count}次")

    def save_report(self, filename=None):
        """保存分析报告"""
        if filename is None:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"report_{timestamp}.json"

        report = {
            "分析时间": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "分析结果": self._results
        }
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(report, f, ensure_ascii=False, indent=2)
        print(f"\n💾 报告已保存: {filename}")


# === 主程序 ===
def main():
    print("📖 文本数据分析工具")
    print("1.分析文件 2.分析输入文本")
    choice = input("选择: ").strip()

    analyzer = None
    if choice == "1":
        filepath = input("文件路径: ").strip()
        analyzer = TextAnalyzer.from_file(filepath)
    elif choice == "2":
        analyzer = TextAnalyzer.from_input()

    if analyzer is None:
        print("没有可分析的文本")
        return

    analyzer.analyze().display()

    save = input("\n保存报告? (y/n): ").strip().lower()
    if save == "y":
        analyzer.save_report()

if __name__ == "__main__":
    main()

7天完整回顾

7天知识地图

天数主题核心概念第一性原理
Day 1数据基础变量、int/float/str/bool、运算符、输入输出程序=数据+操作,变量是数据的标签
Day 2控制流if/elif/else、for、while、break/continue程序需要"判断"和"重复"
Day 3数据结构list、tuple、dict、set、嵌套结构不同的容器组织不同的数据
Day 4函数def、参数、返回值、作用域、lambda、递归把重复逻辑封装成可复用单元
Day 5面向对象类、对象、继承、多态、封装、魔术方法把数据+动作打包成整体
Day 6文件/异常/模块文件读写、try/except、import、标准库与外部世界交互
Day 7实战项目3个项目综合运用把零件组装成机器

下一步怎么走?

记住:编程不是"学"会的,是"写"会的。7天给你的是知识框架,真正的能力来自不断写代码、改bug、做项目。保持每天写代码的习惯,3个月后你会惊讶于自己的进步。