零基础MCP——第5章编程实战基础(网页、数据分析、调试与重构)

第5章:编程实战基础(网页、数据分析、调试与重构)

本章以实战为导向,围绕五类高频任务(网页原型、数据分析、调试修复、重构优化、文档注释)给出"从需求到验收"的端到端流程:包括提示词模板、落地代码片段、验证清单与常见陷阱。你可以将本章内容直接用于日常开发与教学演练。

5.1 通过自然语言创建简单网页(从需求到页面)

目标:基于文字需求生成一个可运行的响应式页面,含语义化结构、样式与基本交互,并完成可访问性与性能自检。

  • 需求示例:

    • "一个待办事项网页:添加、删除、标记完成;浅蓝主题;移动优先布局。"
  • 分阶段提示(建议分三步):

    1. 结构(HTML骨架与语义标签说明)
    2. 样式(CSS与响应式策略)
    3. 交互(JS逻辑与状态持久化可选)
  • 提示模板(示例):

    • 系统:
      • "你是资深前端工程师。输出中文。生成代码需语义化、可访问、移动优先,并附关键决策说明。"
    • 用户(第1步):
      • "根据以下需求生成页面骨架(仅HTML),并说明DOM结构与可访问性考虑:
        需求:待办网页,含输入框与'添加'按钮、待办列表、统计区域、浅蓝主题占位。"
  • 代码示例(精简版):

html 复制代码
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>待办事项</title>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <header class="site-header" role="banner">
    <h1>待办事项</h1>
  </header>

  <main id="app" role="main">
    <section aria-labelledby="todo-input-label" class="todo-input">
      <h2 id="todo-input-label" class="sr-only">添加新的待办事项</h2>
      <label for="newTodo" class="sr-only">待办内容</label>
      <input id="newTodo" type="text" placeholder="输入待办..." />
      <button id="addBtn" aria-label="添加待办">添加</button>
    </section>

    <section aria-labelledby="todo-list-label" class="todo-list">
      <h2 id="todo-list-label" class="sr-only">待办列表</h2>
      <ul id="list" aria-live="polite"></ul>
    </section>

    <section aria-labelledby="stats-label" class="todo-stats">
      <h2 id="stats-label" class="sr-only">统计信息</h2>
      <p>总数:<span id="total">0</span>,已完成:<span id="done">0</span></p>
    </section>
  </main>

  <footer role="contentinfo" class="site-footer">© 2025</footer>
  <script src="app.js"></script>
</body>
</html>
css 复制代码
/* styles.css */
:root { --primary: #e6f0ff; --accent: #2a6cf6; }
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }
.site-header, .site-footer { padding: 12px; background: var(--primary); }
main { padding: 12px; max-width: 680px; margin: 0 auto; }
.todo-input { display: flex; gap: 8px; }
input { flex: 1; padding: 8px; border: 1px solid #cbd5e1; border-radius: 6px; }
button { padding: 8px 12px; border: 0; border-radius: 6px; background: var(--accent); color: #fff; }
ul { list-style: none; padding: 0; }
li { display: flex; align-items: center; justify-content: space-between; padding: 8px; border-bottom: 1px solid #eee; }
li.completed { color: #64748b; text-decoration: line-through; }
@media (min-width: 768px) { main { padding: 24px; } }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
js 复制代码
// app.js
const inputEl = document.getElementById('newTodo');
const addBtn = document.getElementById('addBtn');
const listEl = document.getElementById('list');
const totalEl = document.getElementById('total');
const doneEl = document.getElementById('done');
const state = JSON.parse(localStorage.getItem('todos') || '[]');

function render() {
  listEl.innerHTML = '';
  state.forEach((item, idx) => {
    const li = document.createElement('li');
    li.className = item.done ? 'completed' : '';
    li.innerHTML = `
      <span>${item.text}</span>
      <div>
        <button aria-label="标记完成" data-action="toggle" data-idx="${idx}">✔</button>
        <button aria-label="删除" data-action="remove" data-idx="${idx}">✖</button>
      </div>`;
    listEl.appendChild(li);
  });
  totalEl.textContent = String(state.length);
  doneEl.textContent = String(state.filter(i => i.done).length);
  localStorage.setItem('todos', JSON.stringify(state));
}

addBtn.addEventListener('click', () => {
  const text = inputEl.value.trim();
  if (!text) return;
  state.push({ text, done: false });
  inputEl.value = '';
  render();
});

listEl.addEventListener('click', (e) => {
  const btn = e.target.closest('button');
  if (!btn) return;
  const idx = Number(btn.dataset.idx);
  const action = btn.dataset.action;
  if (action === 'toggle') state[idx].done = !state[idx].done;
  if (action === 'remove') state.splice(idx, 1);
  render();
});

render();
  • 验收清单:
    • 语义标签完整(headermainfootersectionul/li)。
    • 移动端断点表现良好,浅蓝主题统一。
    • 无控制台报错;交互可用;状态持久化生效。
    • 可访问性:为交互按钮添加aria-label,列表区域aria-live更新可读。

5.2 基础数据分析任务实现(CSV→脚本→图表与报告)

目标:读取CSV完成清洗、月度聚合、Top产品分析与趋势图生成,并输出可复现脚本与运行说明。

  • 数据示例(sales.csv):

    • 列:date(YYYY-MM-DD)productquantityrevenue
  • 提示模板(用户):

    • "读取sales.csv,完成清洗与月度聚合,输出Top产品与趋势图;请生成可复现的Python脚本、依赖与运行说明,并解释异常点。"
  • 代码示例(Python):

python 复制代码
# requirements: pandas matplotlib
# run: pip install pandas matplotlib
# usage: python analyze.py sales.csv
import sys, os
import pandas as pd
import matplotlib.pyplot as plt

if len(sys.argv) < 2:
    print("Usage: python analyze.py <csv_file>")
    sys.exit(1)

csv_path = sys.argv[1]
assert os.path.exists(csv_path), f"File not found: {csv_path}"

# 读取与基础清洗
df = pd.read_csv(csv_path)
df['date'] = pd.to_datetime(df['date'], errors='coerce')
df = df.dropna(subset=['date', 'product', 'quantity', 'revenue'])
df['month'] = df['date'].dt.to_period('M').astype(str)

# 纠正负值与异常(示例策略:过滤或取绝对值,视业务而定)
df = df[(df['quantity'] >= 0) & (df['revenue'] >= 0)]

# 月度聚合与Top产品
monthly = df.groupby(['month', 'product']).agg(
    quantity=('quantity', 'sum'),
    revenue=('revenue', 'sum')
).reset_index()

# 找出每月Top产品(按营收排序)
monthly['rank'] = monthly.groupby('month')['revenue'].rank(method='first', ascending=False)
monthly_top = monthly[monthly['rank'] == 1].sort_values('month')

print("月度Top产品:")
print(monthly_top[['month', 'product', 'revenue']].to_string(index=False))

# 趋势图(总营收按月)
trend = df.groupby('month')['revenue'].sum().reset_index()
plt.figure(figsize=(8,4))
plt.plot(trend['month'], trend['revenue'], marker='o')
plt.xticks(rotation=45)
plt.title('月度总营收趋势')
plt.xlabel('月份')
plt.ylabel('营收')
plt.tight_layout()
plt.savefig('monthly_trend.png')
print('已生成图表: monthly_trend.png')
  • 验收清单:
    • 能运行并输出月度Top产品与monthly_trend.png
    • 依赖与运行说明清晰;异常数据处理策略明确。
    • 代码结构可读;按需可扩展到"产品维度趋势"。

5.3 代码调试与错误修复(最小补丁原则)

目标:定位错误根因,给出最小修复补丁与验证步骤,避免过度改动。

  • 错误示例(日志片段):

    TypeError: Cannot read property 'length' of undefined
    at renderList (list.js:42)
    at update (app.js:17)

  • 调试提示模板:

    错误日志:[粘贴日志]
    期望行为:[描述]
    实际行为:[描述]
    上下文:[相关代码片段/运行环境]
    请定位根因并提供最小补丁与验证步骤,仅改动必要处。

  • 修复思路(示例):

    • 在调用renderList(items)前进行空值与类型检查;或在初始化阶段保证items为数组。
  • 最小补丁(示例,JavaScript):

js 复制代码
// before
function renderList(items) {
  for (let i = 0; i < items.length; i++) { /* ... */ }
}

// after(最小修复)
function renderList(items) {
  if (!Array.isArray(items)) return; // 防御式编程
  for (let i = 0; i < items.length; i++) { /* ... */ }
}
  • 验证步骤:
    • 构造空列表与非法输入;确认不报错且页面可用。
    • 运行原始用例,确保功能未回归;记录变更日志。

5.4 代码重构与优化建议(约束驱动)

目标:在不改动公共接口的前提下,提升可读性、内聚、性能与可测试性,并输出变更清单与测试用例。

  • 约束示例:

    • 不改动公共接口与外部依赖;命名规范与目录结构保持一致;新增单元测试覆盖率≥80%。
  • 重构提示模板:

    文件:[路径]
    痛点:[复杂度高/重复逻辑/副作用散落]
    约束:[不可变更项]
    目标:[可读性/内聚/性能/测试]
    请输出重构原则、变更清单与分段代码,并生成测试用例与运行说明。

  • 示例(前后对比,JavaScript):

js 复制代码
// before
function formatDate(d) {
  return d.getFullYear() + '-' + (d.getMonth()+1) + '-' + d.getDate();
}

// after(可读/可测试)
export function pad2(n) { return String(n).padStart(2, '0'); }
export function formatDate(d) {
  const y = d.getFullYear();
  const m = pad2(d.getMonth() + 1);
  const day = pad2(d.getDate());
  return `${y}-${m}-${day}`;
}
  • 单元测试(示例,Jest):
js 复制代码
import { formatDate } from './date';

test('formatDate should return YYYY-MM-DD', () => {
  const s = formatDate(new Date(2025, 0, 5)); // 1月5日
  expect(s).toBe('2025-01-05');
});
  • 验收清单:
    • 可读性提升、重复逻辑抽取、复杂度降低;
    • 行为未变更(接口与返回值一致);
    • 测试通过并达成覆盖率目标;
    • 记录ADR与变更日志,便于回溯。

5.5 文档生成与注释添加(从代码到说明)

目标:为生成或重构的代码产出技术说明、API参考与必要注释,降低协作成本。

  • 说明模板(技术文档):

    模块说明

    • 目的:
    • 设计:
    • 关键权衡:
    • 限制与风险:
    • 接口与用法:
  • 注释示例:

    • Python(Docstring):
python 复制代码
def monthly_top(df):
    """返回各月营收Top产品记录。
    参数:
        df (pd.DataFrame): 包含month/product/revenue字段的数据。
    返回:
        pd.DataFrame: 各月Top产品记录。
    """
    # 实现略
  • JavaScript(JSDoc):
js 复制代码
/**
 * 返回YYYY-MM-DD格式日期字符串。
 * @param {Date} d - 日期对象
 * @returns {string}
 */
export function formatDate(d) { /* ... */ }
  • README结构(项目级):

    项目名称

    • 简介与目标
    • 运行与依赖
    • 目录结构
    • 常见任务与提示模板
    • 验收清单与质量标准
  • 验收清单:

    • 文档覆盖目的/设计/限制;注释清晰、与接口一致;
    • README含运行说明与质量标准;
    • 生成内容可复用、便于团队协作与审计。

5.6 常见陷阱与对策(跨任务通用)

  • 一次性输出过长:分阶段生成与复核,避免截断与遗漏。
  • 缺少验收标准:将标准前置为Checklist,强制自检与补丁化修复。
  • 上下文漂移:重复声明不可变更项,固定系统提示中的规范。
  • 安全忽视:Web任务关注XSS/CSRF/鉴权;后端任务关注注入与越权。
  • 不留痕迹:维护变更日志与ADR,确保可回溯与团队共享。

5.7 本章小结与延展任务

  • 小结:本章提供五类常用任务的"提示→代码→验收"完整链路,可直接复制到你的工作流。
  • 延展任务:
    • 将待办网页扩展为组件化(如React/Vue),并新增持久化接口。
    • 将数据分析脚本封装为CLI或Notebook,添加参数与报告生成。
    • 引入静态检查与CI,自动化测试与文档校验。
相关推荐
G***T6911 小时前
Docker数据分析实战
docker·容器·数据分析
EAIReport1 小时前
通过数据分析自动化产品实现AI生成PPT的完整流程
人工智能·数据分析·自动化
京东零售技术5 小时前
【原理到实战】实验异质性分析
数据挖掘
魁首7 小时前
初识 ACP (Agent Client Protocol)
人工智能·ai编程·mcp
龙腾AI白云8 小时前
具身智能-高层任务规划(High-level Task Planning)
深度学习·数据挖掘
数据智研10 小时前
【数据分享】太湖及周边地区1985-2010年耕地空间分布TIF数据
信息可视化·数据分析
源码之家11 小时前
基于python新闻数据分析可视化系统 Hadoop 新闻平台 爬虫 情感分析 舆情分析 可视化 Django框架 vue框架 机器学习 大数据毕业设计✅
大数据·爬虫·python·数据分析·毕业设计·情感分析·新闻
以梦为马mmky12 小时前
25中国矿业大学通信考情数据分析
数据分析·通信考研·信号与系统·中国矿业大学
zenRRan14 小时前
英伟达提出“思考用扩散,说话用自回归”:实现语言模型效率与质量的双赢!
人工智能·机器学习·语言模型·数据挖掘·回归