<!DOCTYPE html><html lang="zh" data-theme="dark"><head><meta charset="utf-8"><meta name="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>在 AI 恐慌的时代,熟练度是一种累赘 · Cytrogen 的个人博客</title><meta name="description" content="近日我在一项限时一小时的小组作业里被教授控诉使用 AI 且不承认,而她的理由让我大跌眼镜。"><link rel="icon" href="../favicon.png"><link rel="canonical" href="https://cytrogen.icu/posts/d38e.html"><link rel="webmention" href="https://webmention.io/cytrogen.icu/webmention"><link rel="me" href="https://m.otter.homes/@Cytrogen"><link rel="me" href="https://github.com/cytrogen"><meta name="fediverse:creator" content="@Cytrogen@m.otter.homes"><link rel="preload" href="../fonts/opensans-regular-latin.woff2" as="font" type="font/woff2" crossorigin="anonymous"><style>@font-face {
font-family: 'Open Sans';
src: url('../fonts/opensans-regular-latin.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
size-adjust: 107%;
ascent-override: 97%;
descent-override: 25%;
line-gap-override: 0%;
}
</style><script>(function() {
try {
// 优先级:用户选择 > 系统偏好 > 默认浅色
const saved = localStorage.getItem('theme');
const theme = saved ||
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
} catch (error) {
// 失败时使用默认主题,不阻塞渲染
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script><link rel="stylesheet" href="../css/ares.css"><script data-netlify-skip-bundle="true">(function() {
document.addEventListener('DOMContentLoaded', function() {
const theme = document.documentElement.getAttribute('data-theme');
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper && theme) {
pageWrapper.setAttribute('data-theme', theme);
}
});
})();
</script><!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 8.1.1"><link rel="alternate" href="atom.xml" title="Cytrogen 的个人博客" type="application/atom+xml">
</head><body><div id="page-wrapper"><a class="skip-link" href="#main-content">跳到主要内容</a><div class="wrap"><header><a class="logo-link" href="../index.html"><img src="../favicon.png" alt="logo"></a><div class="h-card visually-hidden"><img class="u-photo" src="https://cytrogen.icu/favicon.png" alt="Cytrogen"><a class="p-name u-url u-uid" href="https://cytrogen.icu">Cytrogen</a><p class="p-note">Cytrogen 的个人博客,Cytrogen's Blog</p><a class="u-url" rel="me noopener" target="_blank" href="https://m.otter.homes/@Cytrogen">Mastodon</a><a class="u-url" rel="me noopener" target="_blank" href="https://github.com/cytrogen">GitHub</a></div><nav class="site-nav"><div class="nav-main"><div class="nav-primary"><ul class="nav-list hidden-mobile"><li class="nav-item"><a class="nav-link" href="../index.html">首页</a></li></ul><div class="nav-tools"><div class="language-menu"><button class="language-toggle" type="button"><svg class="icon icon-globe" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855A7.97 7.97 0 0 0 10.855 12H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z"></path></svg><span>中文</span></button><div class="language-dropdown"></div></div></div><div class="nav-controls"><div class="more-menu hidden-mobile"><button class="more-toggle" type="button"><span>更多</span><svg class="icon icon-chevron-down" width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1s.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0s.3.8 0 1.1l-3.3 3.3c-.1.1-.3.2-.5.2z"></path></svg></button><div class="more-dropdown"><ul class="dropdown-list"><li class="dropdown-item"><a class="nav-link" href="../archives/index.html">归档</a></li><li class="dropdown-item"><a class="nav-link" href="../categories/index.html">分类</a></li><li class="dropdown-item"><a class="nav-link" href="../tags/index.html">标签</a></li><li class="dropdown-item"><a class="nav-link" href="../about/index.html">关于</a></li><li class="dropdown-item"><a class="nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></div><div class="theme-switcher"><button class="theme-toggle" type="button" role="switch" aria-pressed="false" aria-label="切换主题"><div class="theme-icon moon-icon"><svg class="icon icon-moon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"></path></svg></div><div class="theme-icon sun-icon"><svg class="icon icon-sun" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path></svg></div></button></div><details class="mobile-menu-details hidden-desktop"><summary class="hamburger-menu" aria-label="nav.menu"><svg class="icon icon-bars" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg><span class="menu-text">nav.menu</span></summary><div class="mobile-menu-dropdown"><ul class="mobile-nav-list"><li class="mobile-nav-item"><a class="mobile-nav-link" href="../index.html">首页</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../archives/index.html">归档</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../categories/index.html">分类</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../tags/index.html">标签</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../about/index.html">关于</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></details></div></div></div></nav></header><main class="container" id="main-content" tabindex="-1"><div class="post"><article class="post-block h-entry"><div class="post-meta p-author h-card visually-hidden"><img class="author-avatar u-photo" src="../favicon.png" alt="Cytrogen"><span class="p-name">Cytrogen</span><a class="u-url" href="https://cytrogen.icu">https://cytrogen.icu</a></div><a class="post-permalink u-url u-uid visually-hidden" href="https://cytrogen.icu/posts/d38e.html">永久链接</a><div class="p-summary visually-hidden"><p>近日我在一项限时一小时的小组作业里被教授控诉使用 AI 且不承认,而她的理由让我大跌眼镜。</p></div><div class="visually-hidden"><a class="p-category" href="../categories/%E4%B8%AA%E4%BA%BA%E9%9A%8F%E6%83%B3/">个人随想</a><a class="p-category" href="../tags/Python/">Python</a><a class="p-category" href="../tags/%E5%A4%A7%E5%AD%A6%E8%AF%BE%E7%A8%8B/">大学课程</a><a class="p-category" href="../tags/%E9%80%BB%E8%BE%91%E5%AD%A6/">逻辑学</a></div><h1 class="post-title p-name">在 AI 恐慌的时代,熟练度是一种累赘</h1><div class="post-info"><time class="post-date dt-published" datetime="2025-11-20T21:36:50.000Z">11/20/2025</time><time class="dt-updated visually-hidden" datetime="2026-02-09T17:16:55.213Z"></time></div><div class="post-content e-content"><html><head></head><body><p>近日我在一项限时一小时的小组作业里被教授控诉使用 AI 且不承认,而她的理由让我大跌眼镜。</p>
<span id="more"></span>
<h2 id="背景"><a class="markdownIt-Anchor" href="#背景"></a> 背景</h2>
<p>我这个学期正在上一节 CIS(计算机信息系统)课程,内容是 Python 入门,上课方法是网课。开课时的第一周,教授便给我们分配了一项作业:介绍自己并且告知我们是否有课外经验,好让她了解我们的能力以及对我们的作业有多大的期待。</p>
<p>我于数年前便学习过 Python,且学习了很长一段时间爬虫、网页自动化操作和 JavaScript 逆向(关于 JavaScript 逆向,你可以在 <a href="/tags/%E7%BD%91%E9%A1%B5%E9%80%86%E5%90%91/">这里</a> 找到一些我过往写过的文章。我也有当时学习这三个内容的笔记,未来可以发出来)。</p>
<p>于是我填写了表单,表示我学习过 Python 并且懂得如何使用许多库,其中便包括了这次的主角:BeautifulSoup。</p>
<h2 id="起因"><a class="markdownIt-Anchor" href="#起因"></a> 起因</h2>
<p>教授要求我们在一小时内完成一个小组作业,要求如下:</p>
<blockquote>
<h4 id="网页抓取书籍数据"><a class="markdownIt-Anchor" href="#网页抓取书籍数据"></a> 网页抓取书籍数据</h4>
<p>目标网站: <a target="_blank" rel="noopener" href="http://books.toscrape.com/">Books to Scrape</a></p>
<p>任务:</p>
<ol>
<li>从网站的 <strong>第一页</strong> <strong>提取书籍信息</strong>,包括:
<ul>
<li>书籍的 <strong>标题</strong></li>
<li><strong>价格</strong></li>
<li><strong>库存状态</strong></li>
</ul>
</li>
<li>将每本书的数据存储为一个 <strong>字典</strong></li>
</ol>
<p>输出示例:</p>
<figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">A Light in the Attic : {'Price': '£51.77', 'In Stock': 'In stock'}</span><br><span class="line">Tipping the Velvet : {'Price': '£53.74', 'In Stock': 'In stock'}</span><br></pre></td></tr></tbody></table></figure>
<p>作业说明:</p>
<ul>
<li>遵循课上讨论的步骤和方法</li>
<li>你可以使用 AI 工具来获取关于从网站抓取数据的指导或澄清,但 <strong>请勿复制完整的解决方案</strong>。任何 AI 提供的建议 <strong>都必须经过修改,以符合课上讨论的方法和步骤</strong>,以此证明你自己的理解并应用了所学知识</li>
<li><strong>直接提交来自外部来源的解决方案将得零分</strong></li>
<li>如果你使用了 AI,请 <strong>明确注明</strong> 你使用的 AI 工具,包含你提供的提示词,以及 AI 生成的输出内容</li>
<li>请像课上演示的那样,<strong>一步步展示你的进度</strong>。只提交完整的解答而没有展示过程或小测试将不被接受</li>
</ul>
<p>进阶挑战:</p>
<ul>
<li>从网站的 <strong>前 5 页</strong> <strong>提取书籍信息</strong></li>
<li>同时 <strong>提取</strong> <strong>评分</strong></li>
</ul>
</blockquote>
<p>这里有一些内容需要补充:</p>
<ol>
<li>教授本身不懂 HTML,也没讲过 HTML</li>
<li>关于网页爬虫的内容,教授只讲了一堂课</li>
</ol>
<p>这也是为什么教授允许我们使用 AI 工具:因为一些内容她根本没提到,需要 AI 辅助。</p>
<p>回到小组。我因为本来就懂爬虫,也懂怎么使用 BeautifulSoup(不过我更喜欢 lxml~),所以我直接告诉了小组成员我们要如何编写这套代码。不过这里出现了一个小插曲:我误以为需要进入到书本详情页才能获取到标题等内容,还白白写了一套「获取所有链接、访问链接再抓取数据」的代码。实际上直接在首页抓就好了。后面被小组成员提醒才赶忙修回来。</p>
<p>好了这不是重点!</p>
<p>这是首页源代码里一本书的内容:</p>
<figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">article</span> <span class="attr">class</span>=<span class="string">"product_pod"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"image_container"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"catalogue/sapiens-a-brief-history-of-humankind_996/index.html"</span>></span><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"media/cache/be/a5/bea5697f2534a2f86a3ef27b5a8c12a6.jpg"</span> <span class="attr">alt</span>=<span class="string">"Sapiens: A Brief History of Humankind"</span> <span class="attr">class</span>=<span class="string">"thumbnail"</span>></span><span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span> <span class="attr">class</span>=<span class="string">"star-rating Five"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-star"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-star"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-star"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-star"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-star"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="tag"><<span class="name">h3</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"catalogue/sapiens-a-brief-history-of-humankind_996/index.html"</span> <span class="attr">title</span>=<span class="string">"Sapiens: A Brief History of Humankind"</span>></span>Sapiens: A Brief History ...<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">h3</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"product_price"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span> <span class="attr">class</span>=<span class="string">"price_color"</span>></span>£54.23<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span> <span class="attr">class</span>=<span class="string">"instock availability"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"icon-ok"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> </span><br><span class="line"> In stock</span><br><span class="line"> </span><br><span class="line"> <span class="tag"></<span class="name">p</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">form</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary btn-block"</span> <span class="attr">data-loading-text</span>=<span class="string">"Adding..."</span>></span>Add to basket<span class="tag"></<span class="name">button</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">form</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">article</span>></span></span><br></pre></td></tr></tbody></table></figure>
<p>这里需要特别说一下首页标题:</p>
<figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">h3</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"catalogue/sapiens-a-brief-history-of-humankind_996/index.html"</span> <span class="attr">title</span>=<span class="string">"Sapiens: A Brief History of Humankind"</span>></span>Sapiens: A Brief History ...<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">h3</span>></span></span><br></pre></td></tr></tbody></table></figure>
<p>如果直接 <code>a.text</code> 的话,只会得到被裁剪的标题。真正的标题在其中的 <code>title</code> 属性里。那直接写 <code>a["title"]</code> 就可以了吗?当然不是了,不是所有的 <code>a</code> 标题都带有 <code>title</code> 属性,真跑起来的话不就报错了?</p>
<p>这里有两个方法:</p>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> soup.find(<span class="string">"a"</span>)[<span class="string">"title"</span>]:</span><br></pre></td></tr></tbody></table></figure>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">soup.find(<span class="string">"h3"</span>).find(<span class="string">"a"</span>)[<span class="string">"title"</span>]</span><br></pre></td></tr></tbody></table></figure>
<div class="danger"> 当然了方法还有很多,我这里只说我当时第一时间想到的。
</div>
<p>用第一个办法最保险,但是对于这个简单的作业,我直接写的第二个。这里虽然是我不够严谨了,不过当时实际敲代码的并不是我。单是口头指导屏幕另一边的小组成员怎么写东西、要点击什么东西就已经够累人了,我还需要告诉他们为什么我要这么做、用的方法是做什么使的…… 因为小组成员好像没有一个人知道怎么做哎!反正代码向来都是能用就可以,我觉得这个处理方式没有任何问题。</p>
<p>其余内容没什么好说的,我直接让小组成员开始写字典、照教授所要的方法打印出来字典…… 唯一的问题是打印出来的价格会多出一个神秘符号 <code>Â</code>,感觉是编码问题。我们加了一个 <code>.replace("Â", "")</code> 来去掉它。</p>
<p>这时候我们已经快到了截止时间。我们不仅需要在这个时间里写完代码,还需要填写成员评估表单交上去。这是最终代码(因为是 <code>ipynb</code>,所以一个代码块等同于一个单元格):</p>
<details>
<summary>所有代码</summary>
<blockquote>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%pip install requests</span><br></pre></td></tr></tbody></table></figure>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">url = <span class="string">"https://books.toscrape.com/"</span></span><br><span class="line"></span><br><span class="line">response = requests.get(url)</span><br><span class="line"></span><br><span class="line">response</span><br></pre></td></tr></tbody></table></figure>
<blockquote>
<p><code>response</code> 返回的内容:</p>
<figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><Response [200]></span><br></pre></td></tr></tbody></table></figure>
</blockquote>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br></pre></td></tr></tbody></table></figure>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">soup = BeautifulSoup(response.text, <span class="string">'html.parser'</span>)</span><br><span class="line"></span><br><span class="line">soup</span><br></pre></td></tr></tbody></table></figure>
<blockquote>
<p><code>soup</code> 返回的内容:</p>
<figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"></span><br><span class="line"><span class="comment"><!--[if lt IE 7]> <html lang="en-us" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--></span></span><br><span class="line"><span class="comment"><!--[if IE 7]> <html lang="en-us" class="no-js lt-ie9 lt-ie8"> <![endif]--></span></span><br><span class="line"><span class="comment"><!--[if IE 8]> <html lang="en-us" class="no-js lt-ie9"> <![endif]--></span></span><br><span class="line"><span class="comment"><!--[if gt IE 8]><!--></span> <span class="tag"><<span class="name">html</span> <span class="attr">class</span>=<span class="string">"no-js"</span> <span class="attr">lang</span>=<span class="string">"en-us"</span>></span> <span class="comment"><!--<![endif]--></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">title</span>></span></span><br><span class="line"> All products | Books to Scrape - Sandbox</span><br><span class="line"><span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">content</span>=<span class="string">"text/html; charset=utf-8"</span> <span class="attr">http-equiv</span>=<span class="string">"content-type"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">content</span>=<span class="string">"24th Jun 2016 09:29"</span> <span class="attr">name</span>=<span class="string">"created"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">content</span>=<span class="string">""</span> <span class="attr">name</span>=<span class="string">"description"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">content</span>=<span class="string">"width=device-width"</span> <span class="attr">name</span>=<span class="string">"viewport"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">content</span>=<span class="string">"NOARCHIVE,NOCACHE"</span> <span class="attr">name</span>=<span class="string">"robots"</span>/></span></span><br><span class="line"><span class="comment"><!-- Le HTML5 shim, for IE6-8 support of HTML elements --></span></span><br><span class="line"><span class="comment"><!--[if lt IE 9]></span></span><br><span class="line"><span class="comment"> <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script></span></span><br><span class="line"><span class="comment"> <![endif]--></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"static/oscar/favicon.ico"</span> <span class="attr">rel</span>=<span class="string">"shortcut icon"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"static/oscar/css/styles.css"</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">type</span>=<span class="string">"text/css"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"static/oscar/js/bootstrap-datetimepicker/bootstrap-datetimepicker.css"</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"static/oscar/css/datetimepicker.css"</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">type</span>=<span class="string">"text/css"</span>/></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span> <span class="attr">class</span>=<span class="string">"default"</span> <span class="attr">id</span>=<span class="string">"default"</span>></span></span><br><span class="line">...</span><br><span class="line"> });</span><br><span class="line"> <span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="comment"><!-- Version: N/A --></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br><span class="line">Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure>
</blockquote>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">books = soup.find_all(<span class="string">"article"</span>, class_=<span class="string">"product_pod"</span>)</span><br><span class="line">books</span><br></pre></td></tr></tbody></table></figure>
<blockquote>
<p><code>books</code> 返回的内容:</p>
<figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">[<article class="product_pod"></span><br><span class="line"> <div class="image_container"></span><br><span class="line"> <a href="catalogue/a-light-in-the-attic_1000/index.html"><img alt="A Light in the Attic" class="thumbnail" src="media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg"/></a></span><br><span class="line"> </div></span><br><span class="line"> <p class="star-rating Three"></span><br><span class="line"> <i class="icon-star"></i></span><br><span class="line"> <i class="icon-star"></i></span><br><span class="line"> <i class="icon-star"></i></span><br><span class="line"> <i class="icon-star"></i></span><br><span class="line"> <i class="icon-star"></i></span><br><span class="line"> </p></span><br><span class="line"> <h3><a href="catalogue/a-light-in-the-attic_1000/index.html" title="A Light in the Attic">A Light in the ...</a></h3></span><br><span class="line"> <div class="product_price"></span><br><span class="line"> <p class="price_color">£51.77</p></span><br><span class="line"> <p class="instock availability"></span><br><span class="line"> <i class="icon-ok"></i></span><br><span class="line"> </span><br><span class="line"> In stock</span><br><span class="line"> </span><br><span class="line"> </p></span><br><span class="line"> <form></span><br><span class="line"> <button class="btn btn-primary btn-block" data-loading-text="Adding..." type="submit">Add to basket</button></span><br><span class="line"> </form></span><br><span class="line"> </div></span><br><span class="line"> </article>,</span><br><span class="line">...</span><br><span class="line"> <form></span><br><span class="line"> <button class="btn btn-primary btn-block" data-loading-text="Adding..." type="submit">Add to basket</button></span><br><span class="line"> </form></span><br><span class="line"> </div></span><br><span class="line"> </article>]</span><br><span class="line">Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...</span><br></pre></td></tr></tbody></table></figure>
</blockquote>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">books_data = {}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> book <span class="keyword">in</span> books:</span><br><span class="line"></span><br><span class="line">title = book.find(<span class="string">"h3"</span>).find(<span class="string">"a"</span>)[<span class="string">"title"</span>]</span><br><span class="line"></span><br><span class="line">price = book.find(<span class="string">"p"</span>, class_=<span class="string">"price_color"</span>).text.replace(<span class="string">"Â"</span>, <span class="string">""</span>)</span><br><span class="line"></span><br><span class="line">availability = book.find(<span class="string">"p"</span>, class_=<span class="string">"instock availability"</span>).text.strip()</span><br><span class="line"></span><br><span class="line">books_data[title] = { <span class="string">"price"</span>: price, <span class="string">"in stock"</span>: availability }</span><br></pre></td></tr></tbody></table></figure>
<figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> title, info <span class="keyword">in</span> books_data.items():</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(title, <span class="string">":"</span>, info)</span><br></pre></td></tr></tbody></table></figure>
<blockquote>
<p>最终 <code>print</code> 出来的内容(原文太长了删减一下):</p>
<figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">A Light in the Attic : {'price': '£51.77', 'in stock': 'In stock'}</span><br><span class="line">Tipping the Velvet : {'price': '£53.74', 'in stock': 'In stock'}</span><br><span class="line">Soumission : {'price': '£50.10', 'in stock': 'In stock'}</span><br><span class="line">Sharp Objects : {'price': '£47.82', 'in stock': 'In stock'}</span><br></pre></td></tr></tbody></table></figure>
</blockquote>
</blockquote>
</details>
<p>数日后成绩下来了,我们拿了 F,而这是教授的反馈:</p>
<blockquote>
<p>作业说明明确指出:「就像课堂上演示的那样,一步步展示你的过程。不展示过程或小测试的完整解答将不被接受。」你提交的作业不包含任何测试或循序渐进的过程。你只是把完整的解答拆分到了不同的单元格里。依然没有测试。此外,也未披露使用了 AI。</p>
<p>关于你的代码:这一行是从哪里来的?<code>books = soup.find_all('article', class_='product_pod')</code>。还有,你是怎么在 for 循环下直接写出这些的: <code>book.h3.a['title']</code> <code>book.find('p', class_='price_color').text</code> <code>book.find('p', class_='instock availability').text.strip()</code> 像我在练习中做过多次的那样,针对这些代码的测试在哪里?</p>
</blockquote>
<p>我当时看到的第一反应是:<em><strong>什么叫他妈的我们没有披露使用 AI?</strong></em></p>
<h2 id="第一次回复"><a class="markdownIt-Anchor" href="#第一次回复"></a> 第一次回复</h2>
<p>这节课的 WhatsApp 群组里有人表示,我们不是唯一拿了 F,并且被指控使用了 AI 的小组。</p>
<p>一些拿了分的小组提到教授要求我们像她的笔记那样,记录每一步尝试。他们直接照着她的笔记捣鼓,拿了满分。但这和我有什么关系?我又不是新手,我为什么还要退一步、装自己什么也不懂?难道抄教授的思路就好了?</p>
<p>也有人向教授说话,说因为教授自己也不懂 HTML,因此不期待我们懂 HTML,才叫我们用 AI 来了解 HTML。这番言论一说出来便遭到了其他已经学习过网页开发的校友的嘲讽:<em>教授自己都不懂自己分配的作业,反过来指责我们这些懂的人用了 AI。这不搞笑吗?</em> 这是我自己想出来的代码,用我学过的东西、自己写出来的!现在你告诉我,<em>我未披露自己使用了 AI</em>?要知道,AI 可是有一定的可能性,被喂了我所曾经想出来的代码方案哎!</p>
<p>我的一位小组成员(以下简称甲)找到我,希望我可以和她一起出面、找教授说清楚。我告诉甲我们的代码绝对不是 AI 生成的,我也已经就我的想法给出了我的步骤。如果不是因为教授要求我们给出步骤,我甚至不会去打印那么多次变量、将它们分成多个单元格。有必要去装模作样测试那么多次吗?没有!</p>
<p>不过呢,我因为次日还有个演讲,完全忘记了发邮件这件事…… 直到演讲前的一小时,甲给我发了她和教授之间的对话:</p>
<blockquote>
<p>甲:</p>
<blockquote>
<p>晚上好,</p>
<p>我阅读了您关于第 5 次作业的反馈。关于「逐步展示过程」,就我们的理解而言,我们确实是照做了。我觉得我们可能没理解题目到底要求我们做什么。</p>
<p>我们并没有使用 AI,所以我不知道您为什么会觉得我们用了。</p>
<p>能不能请您再给我们一次机会来修正那段代码或提交类似的代码?在作业里拿个 0 分并不能激励我继续前进。</p>
<p>致以诚挚的问候,</p>
<p>甲</p>
</blockquote>
<p>教授:</p>
<blockquote>
<p>嗨甲,</p>
<p>这次作业的要求非常明确,而且我在上课一开始就强调过,我期望看到你们的 <strong>过程</strong>,而不仅仅是最终的解决方案。这次作业旨在评估你们 <strong>循序渐进的过程</strong>,而不仅仅是最终结果。我已经在反馈中解释了我对 AI 使用的顾虑。其他披露了使用 AI 的小组实际上也使用了相同的代码。让我给你一个更详细的解释。</p>
<p>使用 <code>h3.a["title"]</code> 这一点,如果没有 AI 的协助,你们也是想不出来的。如果你们是独立完成的,你们很可能会从像 <code>first_book.find("a", class_="title")</code> 这样的代码开始,观察到它不起作用,然后再转向其他方法。它之所以不起作用,是因为标题的 HTML 结构与价格和库存的结构不同。然而,你们并没有关于这部分的 AI 使用披露,也没有尝试用我教过的方式来提取标题。这种用法是直接由 AI 生成的解决方案,这也违反了作业要求。我从来没有教过将标签(h3, a)当作函数 / 属性来使用。这些信息是从哪里来的?为什么在提取价格和库存时使用的是 <code>book.find('p', class_="price_color")</code> 和 <code>book.find('p', class_='instock availability')</code>,却偏偏在提取标题时使用 <code>h3.a["title"]</code>?</p>
<p>如果你们参考过我的教学课件,你们就不会那样去构建代码中的字典部分。你们使用的这种风格是一种 <strong>优化过的方法</strong>:先通过 <code>soup.find_all('article', class_="product_pod")</code> 一次性提取所有项目,然后再遍历每一项进行抓取。你们是怎么知道可以这样做的?然而,这并不是我在课上展示的内容。我演示的是如何通过一步步审查 HTML 结构来单独定位每一条信息。我并没有教过你们如何先提取所有数据,然后再在一个单一的循环中检索内部的子数据点。你们提交的方法并不能反映我所教授的过程或方法论。</p>
<p>很遗憾,我无法接受你们修改后的重新提交。课程政策不允许重新提交作业。</p>
<p>祝好,</p>
<p>教授</p>
</blockquote>
</blockquote>
<p>我看到后立马想到(以至于我之后的演讲因为头脑混乱讲的很差):</p>
<ol>
<li>这个教授的整个底层逻辑有问题</li>
<li>她不懂爬虫、不懂 AI,也不懂学习!</li>
</ol>
<h2 id="教授的指控和逻辑"><a class="markdownIt-Anchor" href="#教授的指控和逻辑"></a> 教授的指控和逻辑</h2>
<p>先说教授的底层逻辑。她默认学生们什么都不会,没有教过的内容等同于学生们不会。这里有两个问题:</p>
<ol>
<li>
<p>学生们要是不会,去问 AI 完全没有问题。但是她没有考虑到会的学生啊!我都会了,我还要去搜 AI、告诉你我用了 AI 吗?肯定不是啊!</p>
<p>在大学环境里,<strong>「教授没教」怎么可能去等同于「学生不可能知晓」呢?</strong> 我们完全可以去提前阅读文档、验证假设、应用这些知识。更何况这是编程课程,自主学习本来就应该被鼓励才对。</p>
<p>按照她的逻辑,独立实验是被禁止的、主观能动性是受惩罚的、学术成长也是被视为作弊的证据。要求我们的思维过程必须与她教授的路径一致,这既不合理、在学术上站不住脚,也绝对不是高等教育的运作方式。</p>
</li>
<li>
<p>既然原先就这么默认,那么起初的编程经验调查的意义何在?只是为了完成学校部门的要求吗?</p>
</li>
</ol>
<p>这是上文我重点提及的代码:</p>
<figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">h3</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"catalogue/sapiens-a-brief-history-of-humankind_996/index.html"</span> <span class="attr">title</span>=<span class="string">"Sapiens: A Brief History of Humankind"</span>></span>Sapiens: A Brief History ...<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">h3</span>></span></span><br></pre></td></tr></tbody></table></figure>
<p>她认为我所写的 <code>h3.a["title"]</code> 是学生无法独立想出的内容、是直接用 AI 生成的解决方案。就和我上文所说的那样,莫名其妙,毫无逻辑。宣称学生们想不出来,根本是否认了他们思考的权利。再加上,为什么死认我们使用 AI,而不是阅读 BeautifulSoup 的文档?难道阅读文档在现在这个时代也过时了?</p>
<p>教授所要求的「展示步骤」也是愚蠢至极,根本无法像她所想的那样防住使用 AI 作弊的学生:<em>我只要把教授的课件全部炼化,然后让 AI 生成相同效果的代码不就好了?</em> 并且会大大打击那些已经学会了如何写代码的学生。已经有数个学生反映她的课对已经学习过编程的人来说是一种折磨:<em>我就是会啊,你还想我怎样!</em></p>
<p>可怕的是,<strong>教授对我们使用 AI 的指控没有任何可靠的证据,完全出于她自己的臆测</strong>。她将这一条写在解释之前,因此我猜测这是她认为我们有罪的最大证据:<em>其他披露了使用 AI 的小组实际上也使用了相同的代码。</em> 额…… 不然呢?BeautifulSoup 提取标签属性值的方法本来就那几个啊。难道和 AI 一样说 1 + 1 = 2 的人,也全都是 AI?</p>
<p>而最让我意外的是,许多被无辜指控的学生都放弃了澄清。当时向着教授说话的不在少数,这些观点也险些让我也失去了沟通的勇气。我可以为我任何的不足负责,但我绝不为我未曾做过的事道歉。如果对方要用臆测代替证据,她所要负起的,不止是一次误判的责任,更是对学术公正和个体尊严的损害。</p>
<h2 id="第二次回复"><a class="markdownIt-Anchor" href="#第二次回复"></a> 第二次回复</h2>
<p>既然找出了教授所有的逻辑漏洞,我也得负起小组领导的职责、向教授再一次沟通。这是我最终的邮件:</p>
<blockquote>
<p>尊敬的教授:</p>
<p>我已阅读了您发给我的队友甲的关于我们作业反馈的邮件。我写这封信是为了澄清关于我们要代码逻辑的误解以及对我们使用 AI 的指控,因为是我主导了我们组的编码逻辑。</p>
<p>关于基于特定语法(如 <code>h3.a['title']</code>)而指控我们使用 AI 一事,我必须澄清这段代码并非由 AI 生成。我在 HW1 的学生概况调查中曾表示过我有网络爬虫的经验。我最初尝试使用 <code>soup.find("a")["title"]</code> 来提取标题,但我很快意识到这会导致报错,因为文档结构中并非所有的 <code><a></code> 标签都拥有 "title" 属性。随后我将代码改进为 <code>soup.find("h3").find("a")["title"]</code>,因为所有带有 "title" 属性的 <code><a></code> 标签都嵌套在 <code>"h3"</code> 标签内。之后在循环中我使用了 <code>book.find("h3").find("a")["title"]</code>,因为我写了一个 <code>for</code> 循环从 <code>soup.find_all("article", class_="product_pod")</code> 中获取所有的书籍。由于当时时间紧迫,我便保留了这段代码未做改动。</p>
<p>您还提到其他披露使用了 AI 的小组也提交了类似的代码。我认为相关性并不意味着因果关系。<code>a["title"]</code> 这种语法是标准的简写形式,并且可以说是浏览这种特定 HTML 结构最直接的方式。</p>
<p>关于我们没有展示逐步推进过程的顾虑,这是对我们在时间限制下构建代码方式的误解。正如提交的 Notebook 所示,我在单独的单元格中展示了 <code>response</code>、<code>soup</code> 和 <code>books</code> 列表的输出。然而,对于循环内部具体的提取逻辑,我们在组内协调上遇到了一些挑战,这拖慢了我们的进度。尽管我尽力引导团队完成,但当我们开始编写最终的提取脚本时,距离截止时间已经非常近了。在时间压力下,我不得不依靠我之前的经验,直接基于分析编写了循环。</p>
<p>如果我们的作业能被重新评估,我将不胜感激。</p>
<p>非常感谢。</p>
<p>诚以此致,</p>
<p>我</p>
</blockquote>
<p>十分私人的想法还是留给自己(以及你们,嘻嘻)吧…… 没必要增加更多的误会,只要回复教授的问题以及指出其他问题即可。</p>
<p>说来好笑,我最初拟的版本被室友吐槽「不像人在说话」。她认为我是博客写多了,现在写邮件也会在里面穿插一些大道理,并且有许多重复的内容。我认为没有办法啊,有些东西我不重复讲一下不能表达出我的急切。总之让她帮我修改了一下,也是上文这个版本。</p>
<p>至于后续如何,也不是特别重要了。值得感叹的是,<strong>就算是到了 AI 时代,能够熟练使用某项技能也会被古板的教育系统视为「有罪」</strong>。</p>
</body></html></div></article></div></main><footer><div class="paginator"><a class="prev" href="d4e5.html">上一篇</a><a class="next" href="dfa8.html">下一篇</a></div><!-- Webmention 显示区域--><div class="webmention-section" data-page-url="posts/d38e.html" data-full-url="https://cytrogen.icu/posts/d38e.html" data-mode="static">
<h3 class="webmention-title">Webmentions (<span class="webmention-count">1</span>)</h3><div class="webmention-group webmention-group-mentions"><h4 class="webmention-group-title">提及 (1)</h4><div class="webmention-list">
<div class="webmention-item" id="webmention-1962114" data-webmention-id="1962114">
<div class="webmention-author">
<span class="webmention-author-name">Anonymous</span>
<span class="webmention-date">2025/12/26</span>
</div>
<div class="webmention-content">
</div>
<div class="webmention-meta">
<a class="webmention-source" href="https://www.geedea.pro/essays/prejudice-of-college-education/" target="_blank" rel="noopener ugc">查看原文</a>
</div>
</div></div></div></div><div class="copyright"><p class="footer-links"><a href="../friends/index.html">友链</a><span class="footer-separator"> ·</span><a href="../links/index.html">邻邦</a><span class="footer-separator"> ·</span><a href="../contact/index.html">联络</a><span class="footer-separator"> ·</span><a href="../colophon/index.html">营造记</a><span class="footer-separator"> ·</span><a href="../atom.xml">RSS订阅</a></p><p>© 2025 - 2026 <a href="https://cytrogen.icu">Cytrogen</a>, powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/cytrogen/hexo-theme-ares" target="_blank">hexo-theme-ares</a>.</p><p><a href="https://blogscn.fun" target="_blank" rel="noopener">BLOGS·CN</a></p></div></footer></div></div><a class="back-to-top" href="#top" aria-label="返回顶部"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M3.293 9.707a1 1 0 010-1.414L9.586 2a2 2 0 012.828 0l6.293 6.293a1 1 0 01-1.414 1.414L11 3.414V17a1 1 0 11-2 0V3.414L2.707 9.707a1 1 0 01-1.414 0z"></path></svg></a><script>document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('figure.highlight');
codeBlocks.forEach(block => {
let caption = block.querySelector('figcaption');
if (!caption) {
caption = document.createElement('figcaption');
block.insertBefore(caption, block.firstChild);
}
const info = document.createElement('div');
info.className = 'info';
const filename = caption.querySelector('span');
if (filename) {
filename.className = 'filename';
info.appendChild(filename);
}
const lang = block.className.split(' ')[1];
if (lang) {
const langSpan = document.createElement('span');
langSpan.className = 'lang-name';
langSpan.textContent = lang;
info.appendChild(langSpan);
}
const sourceLink = caption.querySelector('a');
if (sourceLink) {
sourceLink.className = 'source-link';
info.appendChild(sourceLink);
}
const actions = document.createElement('div');
actions.className = 'actions';
const codeHeight = block.scrollHeight;
const threshold = 300;
if (codeHeight > threshold) {
block.classList.add('folded');
const toggleBtn = document.createElement('button');
toggleBtn.textContent = '展开';
toggleBtn.addEventListener('click', () => {
block.classList.toggle('folded');
toggleBtn.textContent = block.classList.contains('folded') ? '展开' : '折叠';
});
actions.appendChild(toggleBtn);
}
const copyBtn = document.createElement('button');
copyBtn.textContent = '复制';
copyBtn.addEventListener('click', async () => {
const codeLines = block.querySelectorAll('.code .line');
const code = Array.from(codeLines)
.map(line => line.textContent)
.join('\n')
.replace(/\n\n/g, '\n');
try {
await navigator.clipboard.writeText(code);
copyBtn.textContent = '已复制';
copyBtn.classList.add('copied');
setTimeout(() => {
copyBtn.textContent = '复制';
copyBtn.classList.remove('copied');
}, 3000);
} catch (err) {
console.error('复制失败:', err);
copyBtn.textContent = '复制失败';
setTimeout(() => {
copyBtn.textContent = '复制';
}, 3000);
}
});
actions.appendChild(copyBtn);
caption.innerHTML = '';
caption.appendChild(info);
caption.appendChild(actions);
const markedLines = block.getAttribute('data-marked-lines');
if (markedLines) {
const lines = markedLines.split(',');
lines.forEach(range => {
if (range.includes('-')) {
const [start, end] = range.split('-').map(Number);
for (let i = start; i <= end; i++) {
const line = block.querySelector(`.line-${i}`);
if (line) line.classList.add('marked');
}
} else {
const line = block.querySelector(`.line-${range}`);
if (line) line.classList.add('marked');
}
});
}
});
});</script><script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const themeToggle = document.querySelector('.theme-toggle');
if (!themeToggle) return;
const getCurrentTheme = () => {
return document.documentElement.getAttribute('data-theme') || 'light';
};
const updateUI = (theme) => {
const isDark = theme === 'dark';
themeToggle.setAttribute('aria-pressed', isDark.toString());
};
const setTheme = (theme) => {
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper) {
pageWrapper.setAttribute('data-theme', theme);
}
// Find and remove the temporary anti-flicker style tag if it exists.
// This ensures the main stylesheet takes full control after the initial load.
const antiFlickerStyle = document.getElementById('anti-flicker-style');
if (antiFlickerStyle) {
antiFlickerStyle.remove();
}
localStorage.setItem('theme', theme);
updateUI(theme);
};
const toggleTheme = () => {
const current = getCurrentTheme();
const newTheme = current === 'light' ? 'dark' : 'light';
setTheme(newTheme);
};
updateUI(getCurrentTheme());
themeToggle.addEventListener('click', toggleTheme);
if (window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', function(e) {
if (!localStorage.getItem('theme')) {
const theme = e.matches ? 'dark' : 'light';
setTheme(theme);
}
});
}
});
})();
</script><script src="../js/details-toggle.js" defer></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const backToTopBtn = document.querySelector('.back-to-top');
if (!backToTopBtn) return;
const toggleButtonVisibility = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const shouldShow = scrollTop > 200;
if (shouldShow) {
backToTopBtn.classList.add('is-visible');
} else {
backToTopBtn.classList.remove('is-visible');
}
};
let ticking = false;
const handleScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
toggleButtonVisibility();
ticking = false;
});
ticking = true;
}
};
const scrollToTop = (event) => {
event.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
window.addEventListener('scroll', handleScroll);
backToTopBtn.addEventListener('click', scrollToTop);
toggleButtonVisibility();
});
})();</script></body></html>