相关文章
暂无评论...
大型语言模型基本上是一台可以理解和生成文本的机器。根据训练方式,有时模型可以生成文本以外的其他内容。ChatGPT 就是这么大的语言模型。如果提示正确,它可以生成编程代码。在这篇文章中,您将学习如何让 ChatGPT 为您生成程序。具体来说,您将学习
让我们开始吧。
这篇文章分为两部分;他们是:
让我们考虑一个简单的项目:您想要设置一个 REST API 服务器,它可以帮助您对所提供的 URL 的整个网页进行“屏幕捕获”。(可选)REST API 可以接受电子邮件地址的附加可选参数。在这种情况下,屏幕截图不会返回,而是通过电子邮件发送。
这是一个涉及多个组件的项目。您需要能够像 REST API 服务器一样监听 HTTP 请求并做出相应响应的东西。您还需要像普通网络浏览器一样获取 URL 并截取屏幕截图。其中还有一个逻辑,取决于是否提供了电子邮件地址;输出可以是返回的图像文件,或者发送带有附件的电子邮件。
如果您不熟悉如何创建 REST API 服务器或不知道可用的工具,可以向 ChatGPT 寻求帮助。只需记下提示中的所有详细信息并询问:
我需要创建一个 REST API 服务器,它接受 URL 作为输入,将网页屏幕截图捕获为 JPEG 格式并将其作为输出返回。可选地,用户可以提供电子邮件地址作为附加输入。在这种情况下,应该通过电子邮件发送屏幕截图而不是返回。你能帮我完成这个程序吗?
由此,ChatGPT 会产生以下建议:
当然!我可以帮助你。要创建一个捕获网页屏幕截图并处理可选电子邮件功能的 REST API 服务器,您可以使用 Node.js 以及一些附加包。以下是您可以遵循的步骤的概述:
1. 设置一个新的 Node.js 项目并使用 npm 对其进行初始化:
123 mkdir screenshot–apicd screenshot–apinpm init2. 安装必要的软件包。您需要
express
API 服务器puppeteer
来捕获屏幕截图和nodemailer
发送电子邮件:
1 npm install express puppeteer nodemailer3. 创建
index.js
文件并使用 Express 设置基本服务器:
1234567891011121314151617 const express = require(‘express’);const app = express();const port = 3000;app.get(‘/screenshot’, async (req, res) => {const url = req.query.url;const email = req.query.email;// Capture the screenshot using Puppeteer// Handle the response based on whether an email is provided});app.listen(port, () => {console.log(`Server is running on port ${port}`);});4. 在
/screenshot
路由内,使用 Puppeteer 捕获网页屏幕截图并相应处理响应:
1234567891011121314151617181920212223242526272829 const puppeteer = require(‘puppeteer’);app.get(‘/screenshot’, async (req, res) => {const url = req.query.url;const email = req.query.email;// Launch Puppeteerconst browser = await puppeteer.launch();const page = await browser.newPage();// Navigate to the provided URLawait page.goto(url);// Capture the screenshotconst screenshotBuffer = await page.screenshot({ fullPage: true });// Close the browserawait browser.close();// Handle the response based on whether an email is providedif (email) {// Send the email with the screenshot attachment using Nodemailer} else {// Send the screenshot as the responseres.type(‘image/jpeg’);res.send(screenshotBuffer);}});5. 要处理发送带有屏幕截图附件的电子邮件,请在块内添加以下代码
if (email)
:
1234567891011121314151617181920212223242526272829303132333435 const nodemailer = require(‘nodemailer’);// Create a transporter using your email service provider’s detailsconst transporter = nodemailer.createTransport({service: ‘your-email-service-provider’,auth: {user: ‘your-email@example.com’,pass: ‘your-email-password’,},});// Define the email optionsconst mailOptions = {from: ‘your-email@example.com’,to: email,subject: ‘Web Page Screenshot’,text: ‘Please find the attached screenshot.’,attachments: [{filename: ‘screenshot.jpg’,content: screenshotBuffer,},],};// Send the emailtransporter.sendMail(mailOptions, (error, info) => {if (error) {console.error(error);res.status(500).send(‘Failed to send email.’);} else {console.log(`Email sent: ${info.response}`);res.send(‘Screenshot emailed successfully!’);}});请务必将
'your-email-service-provider'
、'your-email@example.com'
、 和替换'your-email-password'
为您实际的电子邮件服务提供商的详细信息。6.最后启动服务器:
1 node index.js现在,当您向 发出 GET 请求时
http://localhost:3000/screenshot?url={URL}
,服务器将捕获所提供 URL 的屏幕截图。如果还提供了电子邮件地址email={EMAIL}
,服务器会将屏幕截图作为电子邮件附件发送,而不是直接返回。请记住根据您的要求处理错误并添加任何必要的错误检查或验证。
就是这样!您现在拥有一个基本的 REST API 服务器,可以捕获网页屏幕截图并可以选择通过电子邮件发送它们。请随意根据您的需要进一步增强它。
这是一个非常详细的结果,告诉您如何完成此编程任务。响应涵盖了所有要求,但您应该注意到,当您没有在提示中明确指定时,ChatGPT 将为您做出一些设计决策,例如使用哪种编程语言。
第一次运行时考虑到所有细节并不容易,但 ChatGPT 的性质允许您提供后续提示以修改答案,例如:
对于上述问题,我想使用Python和FastAPI作为Web框架,并使用Selenium作为Web浏览器。你能重写这个吗?
ChatGPT 的响应现在变为:
当然!这是该解决方案的修订版本,使用 Python、FastAPI 作为 Web 框架,以及 Selenium 用于 Web 浏览器自动化。
1. 安装必要的软件包。您需要
fastapi
,uvicorn
来运行服务器,selenium
,webdriver_manager
来管理网络驱动程序:
12 pip install fastapi uvicorn selenium webdriver_manager2. 创建一个名为 的新文件
main.py
并导入所需的模块:
1234567891011 from fastapi import FastAPI, HTTPExceptionfrom fastapi.responses import FileResponsefrom pydantic import BaseModelfrom selenium import webdriverfrom webdriver_manager.chrome import ChromeDriverManagerfrom selenium.webdriver.chrome.options import Optionsfrom selenium.common.exceptions import WebDriverExceptionfrom io import BytesIOapp = FastAPI()3. 定义请求模型来处理输入数据:
1234 class ScreenshotRequest(BaseModel):url: stremail: str = None4、创建网页截图的路由:
123456789101112131415161718192021222324252627282930 @app.get(“/screenshot”)async def capture_screenshot(request: ScreenshotRequest):options = Options()options.headless = Truetry:# Set up the Chrome webdriverdriver = webdriver.Chrome(ChromeDriverManager().install(), options=options)driver.set_window_size(1280, 720)# Navigate to the provided URLdriver.get(request.url)# Capture the screenshotscreenshot = driver.get_screenshot_as_png()screenshot_buffer = BytesIO(screenshot)# Close the browserdriver.quit()if request.email:# Send the email with the screenshot attachmentreturn “Screenshot emailed successfully!”else:# Return the screenshot as a responsereturn FileResponse(screenshot_buffer, media_type=“image/png”)except WebDriverException:raise HTTPException(status_code=400, detail=“Failed to capture screenshot.”)5.使用Uvicorn启动服务器:
1 uvicorn main:app —reload现在,当您向 发出 GET 请求时
http://localhost:8000/screenshot?url={URL}
,服务器将捕获所提供 URL 的屏幕截图。如果还提供了电子邮件地址,您可以使用请求中的字段email={EMAIL}
处理发送带有屏幕截图附件的电子邮件。请记住根据您的要求处理错误并添加任何必要的错误检查或验证。
注意:此解决方案假设您的计算机上安装了 Chrome。如果您使用不同的浏览器,则需要相应地调整网络驱动程序。
就是这样!您现在拥有一个使用 Python、FastAPI 和 Selenium 的 REST API 服务器来捕获网页屏幕截图并处理可选的电子邮件功能。
您可以看到,除了提到“上述问题”之外,您没有在后续提示中提供任何不必要的细节,但 ChatGPT 可以准确地将 Node.js 实现“翻译”为 Python 并使用您指定的库。
这是一个非常棒的结果,尽管您可能仍然需要完善代码。一个例子是,浏览器屏幕大小肯定会影响网页的呈现方式,但在上面的大小是硬编码的,因为您没有指定它应该在提示中调整。完善生成的代码的另一个潜在原因是捕获其他编码风格问题或针对安全问题添加防御措施。
总之,与其他用例一样,在提示中足够清晰地输入更多详细信息是获得有用响应的关键。在编程任务的情况下,布置细节至关重要
程序可能会遇到哪些不同的情况以及这些情况应该如何处理
有时,您想要编写的不是一个大程序,而是一个较小的函数。您可以使用类似于上面的提示要求 ChatGPT 为您生成一个函数,但您需要指定输出格式,例如函数或类。
事实上,你也可以反过来,即向 ChatGPT 提供代码并要求其用英文解释。它有时很有用,特别是在破译别人的代码时。让我们考虑以下示例:
请解释以下代码的作用:
1234567891011121314151617181920212223242526272829303132333435363738 ```float det(float** a, float k) {float s = 1, ret = 0, **b;int i, j, m, n, c;if (k == 1) {return a[0][0];} else {b = (float**) malloc(sizeof(float*)*k);for (i = 0; i < k; i++)b[i] = (float*) malloc(sizeof(float)*k);ret = 0;for (c = 0; c < k; c++) {m = 0;n = 0;for (i = 0; i < k; i++) {for (j = 0; j < k; j++) {b[i][j] = 0;if (i != 0 && j != c) {b[m][n] = a[i][j];if (n < (k – 2))n++;else {n = 0;m++;}}}}ret = ret + s * (a[0][c] * det(b, k – 1));s = s * –1;};for (i = 0; i < k; i++)free(b[i]);};free(b);return ret;}```
这个提示很简单:只有一个关键词,“解释”。但请注意如何向 ChatGPT 提供代码:使用反引号遵循 Markdown 的代码栅栏语法来引用程序。这有助于识别哪些是您的指令,哪些不是。
虽然这不是一个很长的程序,但 ChatGPT 非常详细地解释了代码。它还确定了高层的意图,即计算矩阵的行列式。以下是回应:
您提供的代码是使用拉普拉斯展开计算方阵行列式的递归实现。
以下是代码功能的逐步细分:
- 该函数
det
采用两个参数:指向表示矩阵的二维数组 (float** a
) 的指针和矩阵的大小 (float k
)。- 它声明了一些变量:
s
用于符号、ret
用于行列式值以及**b
作为临时矩阵。- 它检查是否
k
等于 1。如果是,则意味着我们已经达到 1×1 矩阵的基本情况,并且该函数返回矩阵中的单个值,即行列式。- 如果
k
大于1,则继续计算。b
它为大小为k
x 的临时矩阵动态分配内存k
。- 它初始化
ret
为0。- 它进入一个循环,迭代矩阵第一行的每一列
a
。- 在循环内,它将索引
m
和重置n
为 0。- 它进入一个嵌套循环,迭代矩阵的每个元素
a
。b
在嵌套循环内,它将临时矩阵中位置m
,处的元素设置n
为 0。- 它检查当前元素是否不在第一行 (
i != 0
) 且不在当前列 (j != c
) 中。- 如果该元素不在第一行或当前列中,则会将值从矩阵复制到位置 , 处的
a
临时矩阵。b
m
n
m
它根据n
中下一个元素的位置更新索引b
。- 嵌套循环之后,它通过使用临时矩阵和 size
b
递归调用该函数来计算子矩阵的行列式。det
b
k - 1
- 它将子矩阵的行列式乘以符号
s
(交替符号)。- 它将符号
s
乘以 -1 以切换下一次迭代的符号。- 它将符号、第一行中的元素 (
a[0][c]
) 以及子矩阵的行列式的乘积添加到运行和 中ret
。- 循环继续到下一列。
- 循环结束后,它释放为临时矩阵的每一行分配的内存
b
。- 它释放为临时矩阵分配的内存
b
。- 最后,它返回计算出的行列式值
ret
。总之,代码通过沿第一行执行拉普拉斯展开来递归计算方阵的行列式。它使用一个临时矩阵来存储排除第一行和所选列得到的子矩阵。递归继续直到到达 1×1 矩阵的基本情况。
后续改进代码
这段代码乍一看不太容易理解。可能有一种方法可以让它更容易阅读。确实,ChatGPT 在这种情况下可以做得很好,只需一个非常简单的后续提示:
为了清晰起见,您可以重写此代码并添加注释吗?
这里的关键词是“为了清晰起见”和“添加评论”。ChatGPT 提供以下响应:
当然!这是代码的修订版本,其中包含解释每个步骤的注释:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 float determinant(float** matrix, int size) {float sign = 1; // Sign of the determinantfloat result = 0; // Determinant valuefloat** submatrix; // Temporary submatrixint i, j, m, n, c; // Loop variables// Base case: 1×1 matrixif (size == 1) {return matrix[0][0];}else {// Allocate memory for the temporary submatrixsubmatrix = (float**)malloc(sizeof(float*) * size);for (i = 0; i < size; i++) {submatrix[i] = (float*)malloc(sizeof(float) * size);}// Calculate the determinantfor (c = 0; c < size; c++) {m = 0;n = 0;// Create the submatrix by excluding the first row and the current columnfor (i = 0; i < size; i++) {for (j = 0; j < size; j++) {submatrix[i][j] = 0;// Copy values to the submatrixif (i != 0 && j != c) {submatrix[m][n] = matrix[i][j];// Update submatrix indicesif (n < (size – 2)) {n++;}else {n = 0;m++;}}}}// Calculate the determinant of the submatrix recursivelyresult += sign * matrix[0][c] * determinant(submatrix, size – 1);// Flip the sign for the next iterationsign *= –1;}// Free the memory allocated for the submatrixfor (i = 0; i < size; i++) {free(submatrix[i]);}free(submatrix);return result;}}我在代码的每个重要部分上方添加了注释来解释它的作用。这应该使代码更具可读性和更容易理解。
这个版本无疑更容易阅读。
此外,你还可以要求更多。例如要求捕获代码中的错误或潜在的安全问题。让我们要求 ChatGPT 生成一些单元测试代码:
你能给我一些单元测试用例来确保这个功能运行良好吗?
不需要任何进一步的解释,以下是响应:
当然!下面是几个单元测试用例来验证函数的正确性
determinant
:测试用例 1:2×2 矩阵
12345 float matrix1[2][2] = {{2, 3},{1, 4}};float** ptrMatrix1 = (float**)matrix1;float det1 = determinant(ptrMatrix1, 2);// Expected output: 5测试用例2:3×3矩阵
123456 float matrix2[3][3] = {{6, 1, 1},{4, –2, 5},{2, 8, 7}};float** ptrMatrix2 = (float**)matrix2;float det2 = determinant(ptrMatrix2, 3);// Expected output: -306测试用例3:4×4矩阵
1234567 float matrix3[4][4] = {{1, 0, 2, –1},{3, 0, 0, 5},{2, 1, 4, –3},{1, 0, 5, 0}};float** ptrMatrix3 = (float**)matrix3;float det3 = determinant(ptrMatrix3, 4);// Expected output: -20这些测试用例涵盖不同大小的矩阵(2×2、3×3 和 4×4),并包括正、负和零行列式值。通过将计算出的行列式值与预期输出进行比较,您可以验证该
determinant
函数是否正常工作。但很明显,单元测试代码错过了一个极端情况:1×1 矩阵。这表明 ChatGPT 并不总是完美的。您只能将其用作您的助手,而不是替代品。您应该始终验证结果。
概括
在这篇文章中,您了解了 ChatGPT 如何帮助您进行编程。它不仅可以生成代码作为对您的问题的响应的一部分,而且还可以弄清楚您提供的代码的意图。具体来说,您已经了解到:
- 您可以使用 ChatGPT 生成软件项目的初始代码,或生成功能的测试代码
- 您可以要求 ChatGPT 向您解释代码
- 您可以利用 ChatGPT 来重构和清理代码