本教程专为零基础学习者设计,采用循序渐进的方式,从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调用
- 项目实战:消防数据采集与分析平台
学习资源准备
学习前需要准备以下资源:
- 安装Python 3.10+版本(https://www.python.org/downloads/)
- 安装集成开发环境(推荐VS Code或PyCharm)
- 安装必要的Python库(如requests、pandas、numpy、scikit-learn、pyqt6、flask、django等)
- 准备一个GitHub账户(https://github.com/)
- 学习使用命令行工具(如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()
项目实战:控制台版计算器
- 安装Python和开发环境(VS Code或PyCharm)
- 学习使用print()和input()函数进行输入输出
- 实现基本的四则运算功能
- 添加异常处理,防止除数为零的情况
- 测试并运行计算器程序
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()
项目实战:猜数字游戏
- 学习使用random模块生成随机数
- 实现基本的猜数字逻辑
- 添加尝试次数统计功能
- 优化用户体验,添加提示信息
- 测试并运行游戏程序
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()
项目实战:文件批量重命名工具
- 学习使用os模块操作文件系统
- 掌握re模块进行正则表达式匹配
- 实现批量重命名功能
- 添加用户交互界面,获取文件夹路径和匹配模式
- 测试并运行工具,尝试不同匹配模式的效果
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()
项目实战:学生信息管理系统
- 学习定义Student类,包含姓名、学号和成绩属性
- 实现Student类的方法,获取学生信息
- 定义StudentManager类,管理学生信息
- 实现添加、移除和显示学生信息的功能
- 创建主程序,提供用户交互界面
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()
项目实战:简易日志记录器
- 学习使用logging模块记录日志
- 实现不同级别的日志记录(info、error等)
- 定义Logger类,封装日志记录功能
- 在主程序中使用Logger类记录日志
- 测试异常处理机制,观察日志输出效果
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()
项目实战:文本文件加密工具
- 学习使用cryptography库进行文件加密
- 实现生成加密密钥的功能
- 编写加密和解密文件的函数
- 创建主程序,提供用户交互界面
- 测试加密和解密功能,确保文件能够正确加密和解密
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()
项目实战:数据结构与算法应用
- 学习实现线性搜索算法
- 学习实现二分查找算法
- 学习实现冒泡排序算法
- 创建主程序,测试各种算法的效果
- 分析算法的时间复杂度,理解不同算法的适用场景
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()
项目实战:天气数据爬取系统
- 学习使用requests库发送HTTP请求
- 掌握BeautifulSoup解析HTML页面
- 实现获取城市天气信息的功能
- 添加请求头设置,模拟浏览器访问
- 测试不同城市的天气查询效果
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()
项目实战:豆瓣影评标题提取系统
- 学习使用requests库发送HTTP请求
- 掌握BeautifulSoup解析HTML页面
- 实现获取豆瓣影评标题的功能
- 添加动态请求头,模拟不同浏览器访问
- 测试不同电影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())
项目实战:简易文本编辑器与天气查询系统
- 学习安装PyQt6库
- 掌握QTabWidget创建标签页
- 实现文本编辑功能
- 添加天气查询功能,调用Day8的天气爬虫代码
- 测试并运行程序,观察不同标签页的功能
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())
项目实战:多标签页数据展示窗体
- 学习使用QTabWidget创建多标签页
- 掌握QGridLayout布局管理器
- 实现影评数据展示功能
- 添加用户信息输入和保存功能
- 测试并运行程序,观察不同标签页的数据展示效果
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版)
- 学习使用PyQt6创建图形界面
- 掌握信号与槽机制实现按钮点击事件
- 实现四则运算功能
- 添加错误处理,防止无效输入
- 测试并运行程序,验证计算功能
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())
项目实战:学生信息数据库管理工具
- 学习使用SQLite创建数据库和表
- 掌握SQL语句的编写和执行
- 实现添加、移除学生信息的功能
- 创建PyQt6界面展示学生信息
- 测试并运行程序,验证数据库操作功能
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()
项目实战:影评数据清洗与分析系统
- 学习使用re模块进行数据清洗
- 掌握数据分析和统计方法
- 实现影评标题长度分析功能
- 使用matplotlib进行数据可视化
- 测试并运行程序,观察分析结果
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基础应用开发
- 学习安装Flask库
- 掌握路由定义和模板渲染
- 实现影评数据上传和分析功能
- 创建前端模板展示分析结果
- 测试并运行程序,验证功能
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应用开发
- 学习使用Flask处理JSON数据
- 掌握RESTful API设计原则
- 实现影评数据爬取和分析API
- 创建前端界面调用API
- 测试并运行程序,验证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基础应用开发
- 学习安装Django框架
- 掌握MTV架构的理解和应用
- 实现火灾案例管理功能
- 创建数据库模型和表单
- 测试并运行程序,验证功能
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()
项目实战:影评情感分析可视化仪表盘
- 学习使用Pandas进行数据处理
- 掌握Matplotlib进行数据可视化
- 实现影评情感预测功能
- 创建可视化图表展示情感分布
- 测试并运行程序,验证分析效果
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()
项目实战:房价预测模型开发
- 学习使用Scikit-learn进行机器学习
- 掌握线性回归模型的训练和评估
- 实现房价预测功能
- 创建可视化图表展示预测结果
- 测试并运行程序,验证预测效果
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