21天学通Python全栈开发实战指南

本教程专为零基础学习者设计,采用循序渐进的方式,从Python基础语法到实际应用开发,每天学习2小时,21天掌握Python编程核心技能,并将后续复杂任务交给AI辅助完成。 教程涵盖Python基础语法、Web开发、数据分析、机器学习、网络爬虫和GUI开发等多个领域,每篇博客都包含理论知识点讲解、代码示例和实战项目,帮助学习者在实践中掌握Python编程技能。

21天学习路径概览

阶段 天数 主题领域 主要内容
基础阶段 1-7 Python基础语法 变量、数据类型、控制结构、函数、面向对象
进阶阶段 8-14 应用开发基础 网络请求、爬虫技术、GUI开发、文件操作、异常处理
实战阶段 15-21 全栈开发应用 Web开发框架、数据分析、机器学习、整合项目

学习路径设计遵循"理论与实践相结合"的原则,每天学习都包含理论讲解、代码示例和实战项目。 通过这种学习方式,学习者可以在掌握基础语法的同时,立即应用所学知识解决实际问题,增强学习动力和成就感。

每天学习内容概要

Day 1-2: Python环境搭建与基础语法

  • 安装Python和开发环境
  • 学习变量、数据类型和基本运算符
  • 项目实战:控制台版计算器

Day 3: 流程控制

  • 学习if/else条件语句
  • 掌握for和while循环
  • 项目实战:猜数字游戏

Day 4: 函数与模块

  • 学习函数定义和调用
  • 掌握模块导入和使用
  • 项目实战:文件批量重命名工具

Day 5: 面向对象编程

  • 学习类与对象的概念
  • 掌握继承、封装和多态
  • 项目实战:学生信息管理系统

Day 6: 异常处理与调试

  • 学习try/except异常捕获
  • 掌握调试工具的使用
  • 项目实战:简易日志记录器

Day 7: 文件操作

  • 学习文件读写和路径处理
  • 掌握文件加密与解密
  • 项目实战:文本文件加密工具

Day 8-10: 网络请求与爬虫基础

  • 学习Requests库发送HTTP请求
  • 掌握BeautifulSoup解析HTML页面
  • 项目实战:豆瓣影评爬取系统

Day 11-13: GUI开发基础

  • 学习PyQt6组件使用
  • 掌握布局管理器和信号槽机制
  • 项目实战:多标签页数据展示窗体

Day 14-16: Web开发基础

  • 学习Flask框架路由和模板
  • 掌握Django框架MTV架构
  • 项目实战:消防数据管理后台

Day 17-19: 数据分析与机器学习

  • 学习Pandas数据处理和Matplotlib可视化
  • 掌握Scikit-learn机器学习模型
  • 项目实战:影评情感分析可视化仪表盘

Day 20-21: 整合项目与AI辅助开发

  • 学习Django整合爬虫与数据分析
  • 掌握AutoML和Hugging Face API调用
  • 项目实战:消防数据采集与分析平台

学习资源准备

学习前需要准备以下资源

  1. 安装Python 3.10+版本(https://www.python.org/downloads/)
  2. 安装集成开发环境(推荐VS Code或PyCharm)
  3. 安装必要的Python库(如requests、pandas、numpy、scikit-learn、pyqt6、flask、django等)
  4. 准备一个GitHub账户(https://github.com/)
  5. 学习使用命令行工具(如Windows的PowerShell或macOS的Terminal)
Day 1: Python环境搭建与基础语法

知识点讲解:Python环境搭建、变量、数据类型、基本运算符、输入输出函数

代码示例

python 复制代码
# Day 1 - 计算器(控制台版)
def calculator():
    print("欢迎使用简易计算器!")
    print("支持加法(+), 减法(-), 乘法(*), 除法(/)")
    num1 = float(input("请输入第一个数字: "))
    operator = input("请输入运算符: ")
    num2 = float(input("请输入第二个数字: "))

    if operator == "+":
        result = num1 + num2
    elif operator == "-":
        result = num1 - num2
    elif operator == "*":
        result = num1 * num2
    elif operator == "/":
        if num2 == 0:
            print("错误:除数不能为零!")
            return
        result = num1 / num2
    else:
        print("错误:不支持的运算符!")
        return

    print(f"计算结果:{num1} {operator} {num2} = {result}")

# 运行计算器
calculator()

项目实战:控制台版计算器

  1. 安装Python和开发环境(VS Code或PyCharm)
  2. 学习使用print()和input()函数进行输入输出
  3. 实现基本的四则运算功能
  4. 添加异常处理,防止除数为零的情况
  5. 测试并运行计算器程序

AI辅助扩展:使用GitHub Copilot辅助代码生成

  • 在VS Code中安装GitHub Copilot扩展
  • 尝试输入"实现一个支持加减乘除的计算器",观察AI生成的代码
  • 对比AI生成的代码与手动编写的代码,理解两者的异同
Day 2: 数据类型与流程控制

知识点讲解:数据类型(字符串、列表、元组、字典)、条件语句、循环语句

代码示例

python 复制代码
# Day 2 - 猜数字游戏
import random

def guess_number():
    secret_number = random.randint(1, 100)
    attempts = 0
    print("欢迎来到猜数字游戏!")
    print("我已经想好了一个1到100之间的整数,你来猜猜看吧!")

    while True:
        guess = int(input("请输入你的猜测: "))
        attempts += 1

        if guess < secret_number:
            print("猜小了,再试试!")
        elif guess > secret_number:
            print("猜大了,再试试!")
        else:
            print(f"恭喜你,猜对了!你用了{attempts}次尝试。")
            break

# 运行游戏
guess_number()

项目实战:猜数字游戏

  1. 学习使用random模块生成随机数
  2. 实现基本的猜数字逻辑
  3. 添加尝试次数统计功能
  4. 优化用户体验,添加提示信息
  5. 测试并运行游戏程序

AI辅助扩展:使用GitHub Copilot优化游戏逻辑

  • 尝试输入"添加一个难度选择功能,简单难度范围是1-50,困难难度是1-100"
  • 观察AI生成的代码是否包含条件判断和范围设置
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助开发
Day 3: 函数与模块

知识点讲解:函数定义与调用、参数传递、返回值、常用内置模块

代码示例

python 复制代码
# Day 3 - 文件批量重命名工具
import os
import re

def batchrename(path, pattern, replacement):
    """批量重命名文件"""
    for filename in os.listdir(path):
        if re.search(pattern, filename):
            new_filename = re.sub(pattern, replacement, filename)
            src = os.path.join(path, filename)
            dst = os.path.join(path, new_filename)
            os.rename(src, dst)
            print(f"重命名文件:{filename} → {new_filename}")

def main():
    # 设置目标文件夹路径
    path = input("请输入目标文件夹路径: ")
    # 设置匹配模式
    pattern = input("请输入要匹配的模式(如'.txt$'): ")
    # 设置替换内容
    replacement = input("请输入替换内容: ")
    # 执行批量重命名
    batchrename(path, pattern, replacement)

if __name__ == "__main__":
    main()

项目实战:文件批量重命名工具

  1. 学习使用os模块操作文件系统
  2. 掌握re模块进行正则表达式匹配
  3. 实现批量重命名功能
  4. 添加用户交互界面,获取文件夹路径和匹配模式
  5. 测试并运行工具,尝试不同匹配模式的效果

AI辅助扩展:使用GitHub Copilot简化正则表达式编写

  • 尝试输入"编写一个匹配特定格式的正则表达式"
  • 观察AI生成的正则表达式是否符合需求
  • 对比AI生成的正则表达式与手动编写的正则表达式,理解正则表达式的编写技巧
Day 4: 面向对象编程

知识点讲解:类与对象、构造函数、实例方法、类方法、静态方法、继承、多态

代码示例

python 复制代码
# Day 4 - 学生信息管理系统
class Student:
    """学生类"""
    def __init__(self, name, student_id, grade):
        self.name = name
        self.student_id = student_id
        self.grade = grade

    def get_info(self):
        """获取学生信息"""
        return f"姓名: {self.name}, 学号: {self.student_id}, 成绩: {self.grade}"

class StudentManager:
    """学生信息管理类"""
    def __init__(self):
        self students = []

    def add_student(self, student):
        """添加学生"""
        self.students.append(student)
        print(f"已添加学生: {student.get_info()}")

    def remove_student(self, student_id):
        """根据学号移除学生"""
        for student in self.students:
            if student.student_id == student_id:
                self.students.remove(student)
                print(f"已移除学生: {student.get_info()}")
                return
        print("未找到该学号的学生!")

    def display_students(self):
        """显示所有学生信息"""
        print("\n当前学生信息:")
        for student in self.students:
            print(student.get_info())

def main():
    manager = StudentManager()
    while True:
        print("\n学生信息管理系统")
        print("1. 添加学生")
        print("2. 移除学生")
        print("3. 显示所有学生")
        print("4. 退出")
        choice = input("请输入你的选择: ")

        if choice == "1":
            name = input("请输入学生姓名: ")
            student_id = input("请输入学生学号: ")
            grade = float(input("请输入学生成绩: "))
            student = Student(name, student_id, grade)
            manager.add_student(student)
        elif choice == "2":
            student_id = input("请输入要移除的学生学号: ")
            manager.remove_student(student_id)
        elif choice == "3":
            manager.display_students()
        elif choice == "4":
            print("感谢使用学生信息管理系统!")
            break
        else:
            print("无效的选择,请重新输入!")

if __name__ == "__main__":
    main()

项目实战:学生信息管理系统

  1. 学习定义Student类,包含姓名、学号和成绩属性
  2. 实现Student类的方法,获取学生信息
  3. 定义StudentManager类,管理学生信息
  4. 实现添加、移除和显示学生信息的功能
  5. 创建主程序,提供用户交互界面

AI辅助扩展:使用GitHub Copilot生成类方法

  • 尝试输入"为Student类添加一个计算平均成绩的方法"
  • 观察AI生成的代码是否包含正确的逻辑
  • 对比AI生成的代码与手动编写的代码,理解面向对象编程的实现方式
Day 5: 异常处理与调试

知识点讲解:异常处理机制、try-except语句、自定义异常、调试工具使用

代码示例

python 复制代码
# Day 5 - 简易日志记录器
import logging
from datetime import datetime

class Logger:
    """日志记录器类"""
    def __init__(self, file_name):
        self.file_name = file_name
        self logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.INFO)

        handler = logging.FileHandler(file_name)
        handler.setLevel(logging.INFO)

        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)

        self.logger.addHandler(handler)

    def log_info(self, message):
        """记录信息日志"""
        self.logger.info(message)

    def log_error(self, message):
        """记录错误日志"""
        self.logger.error(message)

def main():
    try:
        # 创建日志记录器
        logger = Logger("app.log")
        # 记录信息日志
        logger.log_info("程序启动")
        # 模拟错误
        raise ValueError("发生了一个错误!")
    except ValueError as e:
        # 记录错误日志
        logger.log_error(f"错误信息: {str(e)}")
        print(f"捕获到错误: {str(e)}")
    finally:
        print("程序执行完毕,日志已记录。")

if __name__ == "__main__":
    main()

项目实战:简易日志记录器

  1. 学习使用logging模块记录日志
  2. 实现不同级别的日志记录(info、error等)
  3. 定义Logger类,封装日志记录功能
  4. 在主程序中使用Logger类记录日志
  5. 测试异常处理机制,观察日志输出效果

AI辅助扩展:使用GitHub Copilot生成异常处理代码

  • 尝试输入"添加一个异常处理机制,捕获所有可能的异常"
  • 观察AI生成的代码是否包含全面的异常处理
  • 对比AI生成的代码与手动编写的代码,理解异常处理的最佳实践
Day 6: 文件操作

知识点讲解:文件读写、路径处理、文件加密与解密、文件压缩与解压缩

代码示例

python 复制代码
# Day 6 - 文本文件加密工具
import os
from cryptography.fernet import Fernet

def generate_key():
    """生成加密密钥"""
    key = Fernet.generate_key()
    with open("key.key", "wb") as key_file:
        key_file.write(key)
    print("加密密钥已生成并保存到key.key文件。")
    return key

def encrypt_file(file_path, key):
    """加密文件"""
    cipher_suite = Fernet(key)
    with open(file_path, "rb") as file:
        file_data = file.read()
    encrypted_data = cipher_suite.encrypt(file_data)
    with open(file_path, "wb") as file:
        file.write(encrypted_data)
    print(f"文件{file_path}已加密。")

def decrypt_file(file_path, key):
    """解密文件"""
    cipher_suite = Fernet(key)
    with open(file_path, "rb") as file:
        encrypted_data = file.read()
    try:
        decrypted_data = cipher_suite.decrypt(encrypted_data)
        with open(file_path, "wb") as file:
            file.write(decrypted_data)
        print(f"文件{file_path}已解密。")
    except Exception as e:
        print(f"解密失败: {str(e)}")

def main():
    # 生成加密密钥
    if not os.path.exists("key.key"):
        key = generate_key()
    else:
        with open("key.key", "rb") as key_file:
            key = key_file.read()

    while True:
        print("\n文本文件加密工具")
        print("1. 加密文件")
        print("2. 解密文件")
        print("3. 退出")
        choice = input("请输入你的选择: ")

        if choice == "1":
            file_path = input("请输入要加密的文件路径: ")
            encrypt_file(file_path, key)
        elif choice == "2":
            file_path = input("请输入要解密的文件路径: ")
            decrypt_file(file_path, key)
        elif choice == "3":
            print("感谢使用文本文件加密工具!")
            break
        else:
            print("无效的选择,请重新输入!")

if __name__ == "__main__":
    main()

项目实战:文本文件加密工具

  1. 学习使用cryptography库进行文件加密
  2. 实现生成加密密钥的功能
  3. 编写加密和解密文件的函数
  4. 创建主程序,提供用户交互界面
  5. 测试加密和解密功能,确保文件能够正确加密和解密

AI辅助扩展:使用GitHub Copilot简化文件操作

  • 尝试输入"实现一个文件压缩功能,使用zip格式"
  • 观察AI生成的代码是否包含正确的压缩逻辑
  • 对比AI生成的代码与手动编写的代码,理解文件操作的最佳实践
Day 7: 数据结构与算法

知识点讲解:列表、元组、字典、集合、常用算法(搜索、排序、递归)

代码示例

python 复制代码
# Day 7 - 数据结构与算法示例
def linear_search(arr, target):
    """线性搜索算法"""
    for i in range(len(arr)):
        if arr[i] == target:
            return i
    return -1

def binary_search(arr, target):
    """二分查找算法"""
    low = 0
    high = len(arr) - 1

    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return -1

def bubble_sort(arr):
    """冒泡排序算法"""
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

def main():
    # 测试线性搜索
    arr = [3, 1, 4, 1, 5, 9, 2, 6, 5]
    target = 5
    index = linear_search(arr, target)
    print(f"线性搜索结果:{target}在索引{index}处")

    # 测试二分查找
    sorted_arr = sorted(arr)
    index = binary_search(sorted_arr, target)
    print(f"二分查找结果:{target}在索引{index}处(已排序数组)")

    # 测试冒泡排序
    sorted_arr = bubble_sort(arr.copy())
    print(f"冒泡排序结果:{sorted_arr}")

if __name__ == "__main__":
    main()

项目实战:数据结构与算法应用

  1. 学习实现线性搜索算法
  2. 学习实现二分查找算法
  3. 学习实现冒泡排序算法
  4. 创建主程序,测试各种算法的效果
  5. 分析算法的时间复杂度,理解不同算法的适用场景

AI辅助扩展:使用GitHub Copilot优化算法实现

  • 尝试输入"实现一个快速排序算法"
  • 观察AI生成的代码是否包含正确的快速排序逻辑
  • 对比AI生成的代码与手动编写的代码,理解算法实现的优化技巧
Day 8: 网络请求与爬虫基础

知识点讲解:HTTP请求原理、Requests库使用、状态码含义、请求头设置、反爬虫策略

代码示例

python 复制代码
# Day 8 - 天气数据爬取
import requests
from bs4 import BeautifulSoup

def get_weather(city):
    """获取城市天气信息"""
    base_url = "https://www.xiyouweather.com/{}"
    url = base_url.format(city)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # 检查请求是否成功

        soup = BeautifulSoup(response.text, "html.parser")
        temp = soup.find("div", class_="temp").text.strip()
        description = soup.find("div", class_="description").text.strip()
        return f"{city}的天气:{temp},{description}"
    except requests.exceptions.RequestException as e:
        return f"获取天气数据失败:{str(e)}"

def main():
    city = input("请输入要查询的城市名称: ")
    weather_info = get_weather(city)
    print("\n" + weather_info)

if __name__ == "__main__":
    main()

项目实战:天气数据爬取系统

  1. 学习使用requests库发送HTTP请求
  2. 掌握BeautifulSoup解析HTML页面
  3. 实现获取城市天气信息的功能
  4. 添加请求头设置,模拟浏览器访问
  5. 测试不同城市的天气查询效果

AI辅助扩展:使用GitHub Copilot优化爬虫代码

  • 尝试输入"添加分页功能,获取多天天气数据"
  • 观察AI生成的代码是否包含正确的分页逻辑
  • 对比AI生成的代码与手动编写的代码,理解爬虫开发的最佳实践
Day 9: HTML解析与爬虫进阶

知识点讲解:BeautifulSoup解析HTML、CSS选择器、标签树、属性访问、常见反爬虫策略

代码示例

python 复制代码
# Day 9 - 豆瓣影评标题提取
import requests
from bs4 import BeautifulSoup
import re
import time
import random
from fake_useragent import UserAgent

def get_douban_comments(url, count=20):
    """获取豆瓣影评标题"""
    headers = {
        "User-Agent": UserAgent().random,
        "Accept": "text/html, application/xhtml+xm, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Referer": "https://movie.douban.com/subject/30378158/"
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # 检查请求是否成功

        soup = BeautifulSoup(response.text, "html.parser")
        comments = soup.find_all("div", class_="评论")

        # 提取标题
        titles = []
        for comment in comments:
            title = comment.find("span", class_="标题").text.strip()
            titles.append(title)

        # 处理分页
        if len(titles) >= count:
            return titles[:count]
        else:
            return titles
    except requests.exceptions.RequestException as e:
        return f"获取影评数据失败:{str(e)}"

def main():
    # 设置要爬取的电影ID
    movie_id = "30378158"  # 《孤注一掷》电影ID
    base_url = f"https://movie.douban.com/subject/{movie_id}/comments"

    # 获取影评标题
    comments = get_douban_comments(base_url, 50)

    # 打印结果
    if isinstance(comments, list):
        print(f"共获取到{len(comments)}条影评标题:")
        for i, title in enumerate(comments, 1):
            print(f"{i}. {title}")
    else:
        print(comments)

    # 添加延时,避免频繁请求
    time.sleep(random.uniform(1, 3))

if __name__ == "__main__":
    main()

项目实战:豆瓣影评标题提取系统

  1. 学习使用requests库发送HTTP请求
  2. 掌握BeautifulSoup解析HTML页面
  3. 实现获取豆瓣影评标题的功能
  4. 添加动态请求头,模拟不同浏览器访问
  5. 测试不同电影ID的影评标题提取效果

AI辅助扩展:使用GitHub Copilot简化爬虫开发

  • 尝试输入"添加分页功能,自动获取多页影评数据"
  • 观察AI生成的代码是否包含正确的分页逻辑
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助爬虫开发
Day 10: GUI基础与PyQt6

知识点讲解:PyQt6框架介绍、组件分类、布局管理、信号与槽机制、事件处理

代码示例

python 复制代码
# Day 10 - 简易文本编辑器(PyQt6)
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QTabWidget, QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem, QAbstractScrollArea
from PyQt6.QtCore import Qt
from day8 import get_weather  # 假设天气数据爬取代码在day8.py中

class TextEditor(QMainWindow):
    """文本编辑器主窗口"""
    def __init__(self):
        super().__init__()
        self . setWindowTitle("简易文本编辑器")
        self . setGeometry(100, 100, 800, 600)

        # 创建中央部件
        centralWidget = QWidget()
        self . setCentralWidget(centralWidget)

        # 布局设置
        layout = QVBoxLayout()
        centralWidget . setLayout(layout)

        # 创建标签页部件
        self . tabWidget = QTabWidget()
        layout . addWidget(self . tabWidget)

        # 添加第一个标签页:文本编辑区
        text编辑页 = QWidget()
        text_layout = QVBoxLayout()
        text编辑页 . setLayout(text_layout)

        # 创建文本框
        self . textEdit =QTextEdit()
        self . textEdit . setMinimumSize(700, 500)
        text_layout . addWidget(self . textEdit)

        # 添加第二个标签页:天气数据展示
        weather_page = QWidget()
        weather_layout =QVBoxLayout()
        weather_page . setLayout(weather_layout)

        # 创建城市输入框和查询按钮
        city_layout =QHBoxLayout()
        city_label =QLabel("城市名称:")
        city_layout . addWidget(city_label)

        self . cityEdit =QLineEdit()
        city_layout . addWidget(self . cityEdit)

        query_button =QPushButton("查询天气")
        query_button . clicked . connect(self . query_weather)
        city_layout . addWidget(query_button)
        weather_layout . addLayout(city_layout)

        # 创建表格展示天气数据
        self . weatherTable =QTableWidget()
        self . weatherTable . setColumnCount(3)
        self . weatherTable . setHorizontalHeaderLabels(["日期", "温度", "描述"])
        self . weatherTable . setMinimumSize(700, 300)
        self . weatherTable . setEditTriggers(QAbstractScrollArea NoEditTriggers)
        weather_layout . addWidget(self . weatherTable)

        # 将标签页添加到标签页部件
        self . tabWidget . addTab(text编辑页, "文本编辑")
        self . tabWidget . addTab(weather_page, "天气查询")

    def query_weather(self):
        """查询天气并展示"""
        city = self . cityEdit . text()
        if not city:
            return

        # 获取天气数据
        weather_info = get_weather(city)
        if not isinstance(weather_info, str):
            return

        # 解析天气数据
        lines = weather_info . split("\n")
        if len(lines) < 2:
            return

        date_temp = lines[0] . split(":")
        if len(date_temp) != 2:
            return

        date, temp_desc = date_temp
        temp_desc = temp_desc . split(",")
        if len(temp_desc) != 2:
            return

        # 更新表格数据
        self . weatherTable . setRowCount(1)
        self . weatherTable . setItem(0, 0, QTableWidgetItem(date))
        self . weatherTable . setItem(0, 1, QTableWidgetItem(temp_desc[0]))
        self . weatherTable . setItem(0, 2, QTableWidgetItem(temp_desc[1]))

if __name__ == "__main__":
    app =QApplication(sys . argv)
    window =TextEditor()
    window . show()
    sys . exit(app . exec())

项目实战:简易文本编辑器与天气查询系统

  1. 学习安装PyQt6库
  2. 掌握QTabWidget创建标签页
  3. 实现文本编辑功能
  4. 添加天气查询功能,调用Day8的天气爬虫代码
  5. 测试并运行程序,观察不同标签页的功能

AI辅助扩展:使用GitHub Copilot优化GUI布局

  • 尝试输入"添加一个状态栏,显示当前文本长度"
  • 观察AI生成的代码是否包含正确的布局和组件添加
  • 对比AI生成的代码与手动编写的代码,理解PyQt6开发的最佳实践
Day 11: 布局管理与多标签页

知识点讲解:QGridLayout布局管理器、QTabWidget多标签页、布局嵌套、组件排列

代码示例

python 复制代码
# Day 11 - 多标签页数据展示窗体
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QGridLayout, QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem
from PyQt6.QtCore import Qt
from day9 import get_douban_comments  # 假设豆瓣影评爬虫代码在day9.py中

class DataDisplayApp(QMainWindow):
    """数据展示窗体"""
    def __init__(self):
        super().__init__()
        self . setWindowTitle("多标签页数据展示")
        self . setGeometry(100, 100, 800, 600)

        # 创建主布局
        main_layout = QGridLayout()
        centralWidget = QWidget()
        centralWidget . setLayout(main_layout)
        self . setCentralWidget(centralWidget)

        # 创建标签页部件
        self . tabWidget = QTabWidget()
        main_layout . addWidget(self . tabWidget, 0, 0, 3, 3)

        # 添加第一个标签页:影评数据
        comments_page = QWidget()
        comments_layout = QGridLayout()
        comments_page . setLayout(comments_layout)

        # 创建控件
        self . commentsTable = QTableWidget()
        self . commentsTable . setColumnCount(2)
        self . commentsTable . setHorizontalHeaderLabels(["序号", "标题"])
        self . commentsTable . setMinimumSize(700, 400)
        self . commentsTable . setEditTriggers(QAbstractScrollArea NoEditTriggers)

        load CommentsButton = QPushButton("加载影评数据")
        load CommentsButton . clicked . connect(self . load_comments)
        comments_layout . addWidget(self . commentsTable, 0, 0, 1, 2)
        comments_layout . addWidget(load CommentsButton, 1, 0, 1, 2)
        self . tabWidget . addTab(comments_page, "影评数据")

        # 添加第二个标签页:用户信息
        user_page = QWidget()
        user_layout = QGridLayout()
        user_page . setLayout(user_layout)

        # 创建控件
        user_layout . addWidget(QLabel("姓名:"), 0, 0)
        self . nameEdit = QLineEdit()
        user_layout . addWidget(self . nameEdit, 0, 1)

        user_layout . addWidget(QLabel("年龄:"), 1, 0)
        self . ageEdit = QLineEdit()
        user_layout . addWidget(self . ageEdit, 1, 1)

        save UserButton = QPushButton("保存用户信息")
        save UserButton . clicked . connect(self . save_user)
        user_layout . addWidget(save UserButton, 2, 0, 1, 2)
        self . tabWidget . addTab(user_page, "用户信息")

    def load_comments(self):
        """加载影评数据"""
        # 获取影评标题
        movie_id = "30378158"  # 《孤注一掷》电影ID
        comments = get_douban_comments(f"https://movie.douban.com/subject/{movie_id}/comments", 50)

        # 更新表格数据
        if isinstance(comments, list):
            self . commentsTable . setRowCount(len(comments))
            for i, comment in enumerate(comments):
                self . commentsTable . setItem(i, 0, QTableWidgetItem(str(i+1)))
                self . commentsTable . setItem(i, 1, QTableWidgetItem(comment))
        else:
            print(comments)

    def save_user(self):
        """保存用户信息"""
        name = self . nameEdit . text()
        age = self . ageEdit . text()

        if not name or not age:
            print("错误:姓名和年龄不能为空!")
            return

        try:
            age = int(age)
            print(f"已保存用户信息:姓名={name},年龄={age}")
        except ValueError:
            print("错误:年龄必须是整数!")

if __name__ == "__main__":
    app =QApplication(sys . argv)
    window =DataDisplayApp()
    window . show()
    sys . exit(app . exec())

项目实战:多标签页数据展示窗体

  1. 学习使用QTabWidget创建多标签页
  2. 掌握QGridLayout布局管理器
  3. 实现影评数据展示功能
  4. 添加用户信息输入和保存功能
  5. 测试并运行程序,观察不同标签页的数据展示效果

AI辅助扩展:使用GitHub Copilot优化布局代码

  • 尝试输入"为表格添加水平滚动条和垂直滚动条"
  • 观察AI生成的代码是否包含正确的布局设置
  • 对比AI生成的代码与手动编写的代码,理解PyQt6布局的最佳实践
Day 12: 事件处理与信号槽机制

知识点讲解:信号与槽机制、事件处理流程、常用信号类型、槽函数实现

代码示例

python 复制代码
# Day 12 - 计算器(GUI版)
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QGridLayout, QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem
from PyQt6.QtCore import Qt
from day1 import calculator  # 假设控制台计算器代码在day1.py中

class CalculatorApp(QMainWindow):
    """计算器应用"""
    def __init__(self):
        super().__init__()
        self . setWindowTitle("计算器(GUI版)")
        self . setGeometry(100, 100, 400, 300)

        # 创建主布局
        main_layout = QGridLayout()
        centralWidget = QWidget()
        centralWidget . setLayout(main_layout)
        self . setCentralWidget(centralWidget)

        # 创建输入框
        self . num1Edit = QLineEdit()
        self . num2Edit = QLineEdit()
        main_layout . addWidget(QLabel("数字1:"), 0, 0)
        main_layout . addWidget(self . num1Edit, 0, 1)
        main_layout . addWidget(QLabel("数字2:"), 1, 0)
        main_layout . addWidget(self . num2Edit, 1, 1)

        # 创建运算符按钮
        operators = ["+", "-", "*", "/"]
        self . operator Buttons = []

        for i, op in enumerate(operators):
            button = QPushButton(op)
            button . clicked . connect(lambda checked, op=op: self . calculate(op))
            self . operator Buttons . append(button)
            main_layout . addWidget(button, 2, i)

        # 创建结果显示区
        self . resultLabel =QLabel("结果:")
        main_layout . addWidget(self . resultLabel, 3, 0, 1, 2)

        # 创建重置按钮
        resetButton = QPushButton("重置")
        resetButton . clicked . connect(self . reset)
        main_layout . addWidget(resetButton, 4, 0)

        # 创建退出按钮
        exitButton =QPushButton("退出")
        exitButton . clicked . connect(sys . exit)
        main_layout . addWidget(exitButton, 4, 1)

    def calculate(self, operator):
        """执行计算操作"""
        try:
            num1 = float(self . num1Edit . text())
            num2 = float(self . num2Edit . text())
        except ValueError:
            self . resultLabel ..setText("错误:请输入有效的数字!")
            return

        # 调用控制台计算器函数
        result = calculator(num1, num2, operator)
        self . resultLabel ..setText(f"结果:{result}")

    def reset(self):
        """重置输入框"""
        self . num1Edit . clear()
        self . num2Edit . clear()
        self . resultLabel . clear()

if __name__ == "__main__":
    app =QApplication(sys . argv)
    window =CalculatorApp()
    window . show()
    sys . exit(app . exec())

项目实战:计算器(GUI版)

  1. 学习使用PyQt6创建图形界面
  2. 掌握信号与槽机制实现按钮点击事件
  3. 实现四则运算功能
  4. 添加错误处理,防止无效输入
  5. 测试并运行程序,验证计算功能

AI辅助扩展:使用GitHub Copilot优化事件处理

  • 尝试输入"添加一个历史记录功能,记录之前的计算操作"
  • 观察AI生成的代码是否包含正确的事件处理和数据存储逻辑
  • 对比AI生成的代码与手动编写的代码,理解PyQt6事件处理的最佳实践
Day 13: 数据库基础与SQLite

知识点讲解:数据库概念、SQLite介绍、SQL语法基础、CRUD操作、数据库连接

代码示例

python 复制代码
# Day 13 - 学生信息数据库管理工具
import sqlite3
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QGridLayout, QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem
from PyQt6.QtCore import Qt

class DatabaseApp(QMainWindow):
    """数据库管理应用"""
    def __init__(self):
        super().__init__()
        self . setWindowTitle("学生信息数据库管理")
        self . setGeometry(100, 100, 800, 600)

        # 创建主布局
        main_layout = QGridLayout()
        centralWidget = QWidget()
        centralWidget . setLayout(main_layout)
        self . setCentralWidget(centralWidget)

        # 创建数据库连接
        self . conn = sqlite3 . connect("students.db")
        self . cursor = self . conn . cursor()
        self . create_table()

        # 创建输入区
        input_layout = QGridLayout()
        main_layout . addWidget(QWidget(), 0, 0)
        main_layout . addWidget(QWidget(), 0, 1)
        main_layout . addLayout(input_layout, 0, 2, 2, 1)

        # 添加控件
        input_layout . addWidget(QLabel("姓名:"), 0, 0)
        self . nameEdit = QLineEdit()
        input_layout . addWidget(self . nameEdit, 0, 1)

        input_layout . addWidget(QLabel("学号:"), 1, 0)
        self . studentIdEdit = QLineEdit()
        input_layout . addWidget(self . studentIdEdit, 1, 1)

        input_layout . addWidget(QLabel("成绩:"), 2, 0)
        self . gradeEdit =QLineEdit()
        input_layout . addWidget(self . gradeEdit, 2, 1)

        addButton = QPushButton("添加学生")
        addButton . clicked . connect(self . add_student)
        input_layout . addWidget(addButton, 3, 0)

        removeButton = QPushButton("移除学生")
        removeButton . clicked . connect(self . remove_student)
        input_layout . addWidget(removeButton, 3, 1)

        # 创建表格展示区
        self . studentTable = QTableWidget()
        self . studentTable . setColumnCount(3)
        self . studentTable . setHorizontalHeaderLabels(["学号", "姓名", "成绩"])
        self . studentTable . setMinimumSize(600, 400)
        self . studentTable . setEditTriggers(QAbstractScrollArea NoEditTriggers)
        main_layout . addWidget(self . studentTable, 0, 0, 2, 2)

        # 加载数据
        self . load_data()

    def create_table(self):
        """创建学生信息表"""
        self . cursor . execute('''
            CREATE TABLE IF NOT EXISTS students (
                student_id TEXT PRIMARY KEY,
                name TEXT,
                grade REAL
            )
        ''')
        self . conn . commit()

    def add_student(self):
        """添加学生信息"""
        name = self . nameEdit . text()
        student_id = self . studentIdEdit . text()
        grade = self . gradeEdit . text()

        if not name or not student_id or not grade:
            print("错误:所有字段都不能为空!")
            return

        try:
            grade = float(grade)
        except ValueError:
            print("错误:成绩必须是数字!")
            return

        # 插入数据
        try:
            self . cursor . execute('''
                INSERT INTO students (student_id, name, grade)
                VALUES (?, ?, ?)
            ''', (student_id, name, grade))
            self . conn . commit()
            print(f"已添加学生:{name}(学号:{student_id})")
            self . load_data()
        except sqlite3 . IntegrityError:
            print("错误:学号已存在!")

    def remove_student(self):
        """移除学生信息"""
        student_id = self . studentIdEdit . text()

        if not student_id:
            print("错误:学号不能为空!")
            return

        # 移除数据
        self . cursor . execute('''
            DELETE FROM students WHERE student_id = ?
        ''', (student_id,))
        self . conn . commit()

        if self . cursor . rowcount > 0:
            print(f"已移除学号为{student_id}的学生")
            self . load_data()
        else:
            print(f"未找到学号为{student_id}的学生")

    def load_data(self):
        """加载数据到表格"""
        self . cursor . execute("SELECT * FROM students")
        rows = self . cursor . fetchall()

        self . studentTable . setRowCount(len(rows))
        for i, row in enumerate(rows):
            self . studentTable . setItem(i, 0, QTableWidgetItem(row[0]))
            self . studentTable . setItem(i, 1, QTableWidgetItem(row[1]))
            self . studentTable . setItem(i, 2, QTableWidgetItem(str(row[2])))

if __name__ == "__main__":
    app =QApplication(sys . argv)
    window =DatabaseApp()
    window . show()
    sys . exit(app . exec())

项目实战:学生信息数据库管理工具

  1. 学习使用SQLite创建数据库和表
  2. 掌握SQL语句的编写和执行
  3. 实现添加、移除学生信息的功能
  4. 创建PyQt6界面展示学生信息
  5. 测试并运行程序,验证数据库操作功能

AI辅助扩展:使用GitHub Copilot优化数据库操作

  • 尝试输入"添加一个查询功能,根据姓名搜索学生信息"
  • 观察AI生成的代码是否包含正确的SQL查询逻辑
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助数据库开发
Day 14: 文件操作与数据处理

知识点讲解:文件读写、CSV文件处理、JSON数据解析、数据清洗、文件操作最佳实践

代码示例

python 复制代码
# Day 14 - 影评数据清洗与分析
import csv
import json
import re
from collections import defaultdict
import matplotlib.pyplot as plt
from day9 import get_douban_comments  # 假设豆瓣影评爬虫代码在day9.py中

def clean_comments(comments):
    """清洗影评标题"""
    cleaned = []
    for comment in comments:
        # 去除特殊字符和空格
        cleaned_comment = re . sub(r"[^\w\s]", "", comment) . strip()
        # 分割标题为单词
        words = cleaned_comment . split()
        # 过滤空标题
        if words:
            cleaned . append(cleaned_comment)
    return cleaned

def analyze_length(comments):
    """分析标题长度"""
    lengths = [len(comment) for comment in comments]
    return {
        "平均长度": sum(lengths) / len(lengths),
        "最短长度": min(lengths),
        "最长长度": max(lengths),
        "长度分布": defaultdict(int, {(length // 5) * 5: lengths . count(length) for length in lengths})
    }

def save_analysis(analysis, file_name):
    """保存分析结果到JSON文件"""
    with open(file_name, "w", encoding="utf-8") as f:
        json . dump(analysis, f, ensure_ascii=False, indent=4)

def main():
    # 获取影评数据
    comments = get_douban_comments("https://movie.douban.com/subject/30378158/comments", 100)

    # 清洗数据
    cleaned Comments = clean_comments(comments)
    print(f"原始数据量:{len(comments)},清洗后数据量:{len(cleaned Comments)}")

    # 分析标题长度
    analysis = analyze_length(cleaned Comments)
    print(f"平均标题长度:{analysis['平均长度']:.2f}个字符")
    print(f"最短标题长度:{analysis['最短长度']}个字符")
    print(f"最长标题长度:{analysis['最长长度']}个字符")

    # 保存分析结果
    save_analysis(analysis, "comment_analysis.json")

    # 可视化长度分布
    lengths = list(analysis["长度分布"].keys())
    counts = list(analysis["长度分布"].values())

    plt . bar(lengths, counts)
    plt . title("影评标题长度分布")
    plt ..xlabel("长度(字符)")
    plt . ylabel("数量")
    plt . tight_layout()
    plt . show()

if __name__ == "__main__":
    main()

项目实战:影评数据清洗与分析系统

  1. 学习使用re模块进行数据清洗
  2. 掌握数据分析和统计方法
  3. 实现影评标题长度分析功能
  4. 使用matplotlib进行数据可视化
  5. 测试并运行程序,观察分析结果

AI辅助扩展:使用GitHub Copilot优化数据处理

  • 尝试输入"添加一个词频统计功能,统计影评标题中的常用词汇"
  • 观察AI生成的代码是否包含正确的词频统计逻辑
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助数据处理
Day 15: Flask框架基础

知识点讲解:Web开发概念、Flask框架介绍、路由定义、模板渲染、请求处理

代码示例

python 复制代码
# Day 15 - Flask基础应用
from flask import Flask, render_template, request, redirect, url_for
import json
from day14 import clean_comments, analyze_length, save_analysis  # 假设数据处理代码在day14.py中

app = Flask(__name__)

# 存储影评数据
comments_data = []

@app . route('/')
def home():
    """主页路由"""
    return render_template('home.html')

@app . route('/analyze', methods=['GET', 'POST'])
def analyze():
    """分析路由"""
    if request . method == 'POST':
        # 获取用户输入的影评数据
        user_comments = request . form . get('comments')
        if not user_comments:
            return redirect(url_for('home'))

        # 转换为列表
        comments = [line . strip() for line in user_comments . split('\n') if line . strip()]

        # 清洗数据
        cleaned_comments = clean_comments(comments)

        # 分析数据
        analysis = analyze_length(cleaned_comments)

        # 保存分析结果
        save_analysis(analysis, 'static/data/analysis.json')

        # 更新全局数据
        global comments_data
        comments_data = {
            '原始数据': comments,
            '清洗后数据': cleaned_comments,
            '分析结果': analysis
        }

        return redirect(url_for('results'))

    return render_template('analyze.html')

@app . route('/results')
def results():
    """结果路由"""
    return render_template('results.html', data=comments_data)

if __name__ == "__main__":
    app . run(debug=True)

项目实战:Flask基础应用开发

  1. 学习安装Flask库
  2. 掌握路由定义和模板渲染
  3. 实现影评数据上传和分析功能
  4. 创建前端模板展示分析结果
  5. 测试并运行程序,验证功能

AI辅助扩展:使用GitHub Copilot优化Flask开发

  • 尝试输入"添加一个JSON API接口,返回分析结果"
  • 观察AI生成的代码是否包含正确的API实现
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助Web开发
Day 16: Flask进阶与API开发

知识点讲解:Flask进阶功能、RESTful API设计、请求参数处理、响应格式控制、JSON数据处理

代码示例

python 复制代码
# Day 16 - Flask API应用
from flask import Flask, request, jsonify, render_template
import json
import requests
from day9 import get_douban_comments  # 假设豆瓣影评爬虫代码在day9.py中
from day14 import clean_comments, analyze_length, save_analysis  # 假设数据处理代码在day14.py中

app = Flask(__name__)

# 存储影评数据
comments_data = []

@app . route('/')
def home():
    """主页路由"""
    return render_template('home.html')

@app . route('/scrape', methods=['POST'])
def scrape():
    """爬取影评数据"""
    try:
        # 获取用户输入的电影ID
        movie_id = request . json . get('movie_id')
        if not movie_id:
            return jsonify({"error": "电影ID不能为空!"}), 400

        # 爬取影评数据
        comments_url = f"https://movie.douban.com/subject/{movie_id}/comments"
        comments = get_douban_comments(comments_url, 100)

        # 清洗数据
        cleaned_comments = clean_comments(comments)

        # 分析数据
        analysis = analyze_length(cleaned_comments)

        # 保存分析结果
        save_analysis(analysis, 'static/data/analysis.json')

        # 更新全局数据
        global comments_data
        comments_data = {
            '原始数据': comments,
            '清洗后数据': cleaned_comments,
            '分析结果': analysis
        }

        return jsonify({
            "status": "success",
            "movie_id": movie_id,
            "comment_count": len(comments),
            "cleaned_count": len(cleaned_comments)
        })
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app . route('/results')
def results():
    """结果路由"""
    return render_template('results.html', data=comments_data)

@app . route('/api/analyze', methods=['POST'])
def api_analyze():
    """分析API"""
    try:
        # 获取请求数据
        data = request . get_json()
        if not data or 'comments' not in data:
            return jsonify({"error": "数据格式不正确!"}), 400

        # 清洗数据
        cleaned_comments = clean_comments(data['comments'])

        # 分析数据
        analysis = analyze_length(cleaned_comments)

        return jsonify({
            "status": "success",
            "cleaned_comments": cleaned_comments,
            "analysis": analysis
        })
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    app . run(debug=True)

项目实战:Flask API应用开发

  1. 学习使用Flask处理JSON数据
  2. 掌握RESTful API设计原则
  3. 实现影评数据爬取和分析API
  4. 创建前端界面调用API
  5. 测试并运行程序,验证API功能

AI辅助扩展:使用GitHub Copilot优化API开发

  • 尝试输入"添加一个用户认证功能,保护API接口"
  • 观察AI生成的代码是否包含正确的认证逻辑
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助API开发
Day 17: Django框架基础

知识点讲解:Django框架介绍、MTV架构、模型定义、视图函数、模板渲染、路由配置

代码示例

python 复制代码
# Day 17 - Django基础应用
# models.py
from django . db import models

class FireCase(models.Model):
    """火灾案例模型"""
    date = models . DateField()
    location = models . CharField(max_length=100)
    cause = models . CharField(max_length=100)
    damage = models . FloatField()
    description = models . CharField(max_length=500)

    def __str__(self):
        return f"{self . date} - {self . location}火灾案例"

# views.py
from django . shortcuts import render
from . models import FireCase

def index(request):
    """主页视图"""
    fire_cases = FireCase . objects . all()
    return render(request, 'fire_app/index.html', {'fire_cases': fire_cases})

def add_case(request):
    """添加案例视图"""
    if request . method == 'POST':
        # 获取表单数据
        date = request . POST . get('date')
        location = request . POST . get('location')
        cause = request . POST . get('cause')
        damage = request . POST . get('damage')
        description = request . POST . get('description')

        # 验证数据
        if not all([date, location, cause, damage, description]):
            return render(request, 'fire_app/add_case.html', {'error': '所有字段都不能为空!'})

        try:
            damage = float(damage)
        except ValueError:
            return render(request, 'fire_app/add_case.html', {'error': '损失金额必须是数字!'})

        # 创建并保存案例
        case = FireCase(
            date = date,
            location = location,
            cause = cause,
            damage = damage,
            description = description
        )
        case . save()
        return render(request, 'fire_app/add_case.html', {'success': '火灾案例已成功添加!'})

    return render(request, 'fire_app/add_case.html')

# urls.py
from django . urls import path
from . import views

urlpatterns = [
    path('', views . index, name='index'),
    path('add_case/', views . add_case, name='add_case'),
]

项目实战:Django基础应用开发

  1. 学习安装Django框架
  2. 掌握MTV架构的理解和应用
  3. 实现火灾案例管理功能
  4. 创建数据库模型和表单
  5. 测试并运行程序,验证功能

AI辅助扩展:使用GitHub Copilot优化Django开发

  • 尝试输入"添加一个编辑功能,允许修改已有火灾案例"
  • 观察AI生成的代码是否包含正确的Django视图和模板逻辑
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助Django开发
Day 18: 数据分析与可视化

知识点讲解:Pandas数据处理、Matplotlib可视化、数据清洗、数据分析、数据可视化最佳实践

代码示例

python 复制代码
# Day 18 - 影评情感分析可视化仪表盘
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from day9 import get_douban_comments  # 假设豆瓣影评爬虫代码在day9.py中
from day14 import clean_comments, analyze_length  # 假设数据处理代码在day14.py中
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

def load_data(file_name):
    """加载影评数据"""
    try:
        with open(file_name, "r", encoding="utf-8") as f:
            data = json . load(f)
        return data['原始数据'], data['清洗后数据'], data['分析结果']
    except FileNotFoundError:
        print("错误:数据文件未找到!")
        return None, None, None

def predict_sentiment(comments, model):
    """预测情感"""
    vectorizer = TfidfVectorizer()
    X = vectorizer . fit_transform(comments)
    return model . predict(X)

def main():
    # 加载数据
    comments, cleaned_comments, analysis = load_data('static/data/analysis.json')
    if not comments:
        return

    # 准备训练数据
    # 假设影评情感标签:0表示负面,1表示正面
    labels = [1 if '喜欢' in comment else 0 for comment in cleaned_comments]

    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(cleaned_comments, labels, test_size=0.2, random_state=42)

    # 创建模型
    model = LogisticRegression()
    model . fit(X_train, y_train)

    # 评估模型
    y_pred = model . predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print(f"情感预测准确率:{accuracy:.2%}")

    # 可视化情感分布
    sentiment_counts = np . sum(y_pred)
    plt . figure(figsize=(8, 4))
    plt . bar(['负面', '正面'], [len(y_pred) - sentiment_counts, sentiment_counts], color=['red', 'green'])
    plt . title(f"影评情感分布(准确率:{accuracy:.2%})")
    plt . tight_layout()
    plt . savefig('static/images/sentiment.png')
    plt . close()

    # 保存分析结果
    analysis . update({
        "情感预测准确率": accuracy,
        "情感分布": {
            "负面": len(y_pred) - sentiment_counts,
            "正面": sentiment_counts
        }
    })
    save_analysis(analysis, 'static/data/analysis.json')

    # 在Flask应用中显示可视化结果
    # 在Flask的results.html中添加:
    # <img src="{{ url_for('static', filename='images/sentiment.png') }}" alt="情感分布图" class="weather-table">

if __name__ == "__main__":
    main()

项目实战:影评情感分析可视化仪表盘

  1. 学习使用Pandas进行数据处理
  2. 掌握Matplotlib进行数据可视化
  3. 实现影评情感预测功能
  4. 创建可视化图表展示情感分布
  5. 测试并运行程序,验证分析效果

AI辅助扩展:使用GitHub Copilot优化数据分析

  • 尝试输入"添加一个词云可视化功能,展示影评中的高频词汇"
  • 观察AI生成的代码是否包含正确的词云实现
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助数据分析
Day 19: 机器学习入门

知识点讲解:机器学习概念、Scikit-learn库介绍、线性回归、分类模型、模型训练与评估

代码示例

python 复制代码
# Day 19 - 房价预测模型
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
import matplotlib.pyplot as plt

def load_housing_data(file_name):
    """加载房价数据"""
    try:
        data = pd . read_csv(file_name)
        return data
    except FileNotFoundError:
        print("错误:数据文件未找到!")
        return None

def train_model(data):
    """训练房价预测模型"""
    # 数据预处理
    X = data[["卧室数量", "浴室数量", "面积", "楼层数", "建造年份"]]
    y = data["价格"]

    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # 创建并训练模型
    model = LinearRegression()
    model . fit(X_train, y_train)

    # 评估模型
    y_pred = model . predict(X_test)
    rmse = np . sqrt(metrics . mean_squared_error(y_test, y_pred))
    r2 = metrics . r2_score(y_test, y_pred)

    print(f"模型评估结果:")
    print(f"RMSE: {rmse:.2f}")
    print(f"R²: {r2:.2f}")

    return model

def predict_price(model,卧室数量,浴室数量,面积,楼层数,建造年份):
    """预测房价"""
    features = np . array([卧室数量,浴室数量,面积,楼层数,建造年份]). reshape(1, -1)
    return model . predict(features)[0]

def main():
    # 加载数据
    data = load_housing_data("housing.csv")
    if data is None:
        return

    # 训练模型
    model = train_model(data)

    # 示例预测
    prediction = predict_price(model, 3, 2, 1500, 2, 2000)
    print(f"预测房价:${prediction:.2f}")

    # 可视化实际与预测价格
    y_test = data["价格"].tail(len(data) - 20)  # 假设后20行是测试集
    y_pred = model . predict(data[["卧室数量", "浴室数量", "面积", "楼层数", "建造年份"]].tail(len(data) - 20))

    plt . scatter(y_test, y_pred)
    plt . plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
    plt ..xlabel("实际价格")
    plt . ylabel("预测价格")
    plt . title("房价预测结果")
    plt . tight_layout()
    plt . savefig('static/images/price .png')
    plt . close()

if __name__ == "__main__":
    main()

项目实战:房价预测模型开发

  1. 学习使用Scikit-learn进行机器学习
  2. 掌握线性回归模型的训练和评估
  3. 实现房价预测功能
  4. 创建可视化图表展示预测结果
  5. 测试并运行程序,验证预测效果

AI辅助扩展:使用GitHub Copilot优化机器学习代码

  • 尝试输入"添加一个随机森林分类器,预测房价是否超过中位数"
  • 观察AI生成的代码是否包含正确的分类器实现
  • 对比AI生成的代码与手动编写的代码,理解如何利用AI辅助机器学习开发
Day 20: 整合项目与消防数据平台

知识点讲解:Django与爬虫整合、数据存储与展示、前后端数据交互、API调用、项目整合

代码示例

python 复制代码
# Day 20 - 消防数据平台整合
# models.py
from django . db import models

class FireCase(models.Model):
    """火灾案例模型"""
    date = models . DateField()
    location = models . CharField(max_length=100)
    cause = models . CharField(max_length=100)
    damage = models . FloatField()
    description = models . CharField(max_length=500)
    sentiment = models . CharField(max_length=20, blank=True, null=True)

    def __str__(self):
        return f"{self . date} - {self . location}火灾案例"

# views.py
from django . shortcuts import render, redirect
from . models import FireCase
from . forms import FireCaseForm
from day19 import predict_price  # 假设房价预测代码在day19.py中
import json
from day9 import get_douban_comments  # 假设豆瓣影评爬虫代码在day9.py中
from day18 import predict_sentiment  # 假设情感分析代码在day18.py中

def index(request):
    """主页视图"""
    fire_cases = FireCase . objects . all()
    return render(request, 'fire_app/index.html', {'fire_cases': fire_cases})

def add_case(request):
    """添加案例视图"""
    if request . method == 'POST':
        # 获取表单数据
        form = FireCaseF
相关推荐
java1234_小锋1 小时前
基于Python深度学习的车辆车牌识别系统(PyTorch2卷积神经网络CNN+OpenCV4实现)视频教程 - 裁剪和矫正车牌
python·深度学习·cnn·车牌识别
苦荞米1 小时前
异步方法-C#中坑最大最深的功能
开发语言·c#
软件测试曦曦1 小时前
使用Python接口自动化测试post请求和get请求,获取请求返回值
开发语言·自动化测试·软件测试·python·功能测试·程序人生·职场和发展
陈奕昆1 小时前
n8n实战营Day2:复杂逻辑控制·HTTP请求+条件分支节点实操
网络·人工智能·python·网络协议·n8n
Aerelin1 小时前
爬虫playwright中的等待机制
前端·爬虫·python
p***s911 小时前
Windows安装Rust环境(详细教程)
开发语言·windows·rust
卡比巴拉—林2 小时前
Python print()函数详讲
开发语言·python
奶思图米球2 小时前
Python多环境管理
开发语言·python
Aerelin2 小时前
iframe讲解(爬虫playwright的特殊应用)
前端·爬虫·python·html