AI 驱动的开发者(MEAP)(二)(4)

简介: AI 驱动的开发者(MEAP)(二)

AI 驱动的开发者(MEAP)(二)(3)https://developer.aliyun.com/article/1516331

6.3 搜索错误

在这一部分,我们将使用一个基本的(尽管相当牵强)示例来演示我们如何使用 Copilot 来查找和修复我们代码中的问题。 这段代码应该循环遍历整数列表并计算总和。 但是,存在一个“眨眼就会错过”的错误。 总和被赋予了 i 的值,而不是将 i 的值添加到累加总和中。

列表 6.11 简单循环遍历整数列表并计算总和
l = [1, 2, 3, 4, 5]
if __name__ == '__main__':
    sum = 0
    for i in l:
        sum = i
    print("sum is", sum)

要调试此问题,我们将引入一个新工具:Copilot 实验室。在 Copilot 聊天之前,Copilot 实验室是我们的 IDE 中某些功能可用的唯一方式,具体来说是 VS Code。例如,我们需要使用 Copilot 实验室来查找和修复错误。Copilot 实验室今天仍然具有的主要优势是,它可以访问编辑器窗格中突出显示的内容。此功能使 Copilot 实验室能够直接在您的 IDE 中的可编辑代码上操作。安装扩展到您的 IDE 后,您应该在 IDE 的左侧看到一个 Copilot 实验室工具包。如果您需要提醒如何将扩展安装到您的 IDE 中,请参考附录 A 到 C,其中包含有关安装扩展的说明。

图 6.1 Copilot 实验室工具包菜单,其中包括查找和修复错误的选项。该工具包还提供增强您的代码以及对其进行文档化的功能。


我们将暂时更改 main.py 文件的内容为列表 6.9 中列出的代码。完成此更改后,请突出显示代码,并在 Copilot 实验室工具包中按下“修复 Bug”按钮。您应该会看到类似于图 6.2 中的输出。Copilot 实验室能够确定此代码中的问题,并提供解决此问题的建议。

图 6.2 Copilot 实验室,使用 GPT 模型,已经识别出了错误以及如何解决此错误


或者,我们可以将这段代码复制到 ChatGPT 中,并要求它找到错误。然而,可以争论的是,这可能不太方便,因为在请求 ChatGPT 修复之前,您必须知道代码中存在错误。

6.4 覆盖代码

代码覆盖率是衡量您的代码被测试覆盖程度的一种指标。通常以百分比表示,代表您的代码被测试执行的比例。

代码覆盖率可以用作评估测试效果的指标。如果您的代码覆盖率较低,可能表示您的代码的某些部分未经过测试,这可能导致未捕获的错误和其他问题。另外,如果代码覆盖率高,则您可以放心您的代码经过了充分测试。这并不保证您的代码是无错的,但应该表明对于应该在测试中捕获的错误,您具有很高的信心。

为了确定我们的 Python 项目中的代码覆盖率,我们将使用 coverage 库中提供的代码覆盖率工具 coverage。coverage 库通过对我们的代码进行工具化来收集运行时的覆盖率数据。它可以收集任何 Python 代码的覆盖率数据,包括测试、脚本和模块。通过使用像 coverage 这样的代码覆盖率工具,我们可以更好地了解我们的代码有多少被我们的测试所覆盖,并识别可能需要更多测试的代码区域。

首先,让我们使用 pip 安装 coverage:pip install coverage. 接下来,让我们使用 coverage 运行我们的测试:coverage run -m pytest. 这将运行您的测试并收集覆盖率数据。

接下来,我们将生成一个覆盖率报告。覆盖率报告将显示项目中每个文件的代码覆盖率。我们使用以下命令创建基于文本的覆盖率报告:coverage report 或使用以下命令生成报告的 HTML 版本:coverage html。报告的 HTML 版本将位于 htmlcov 目录中。图 6.3 显示了覆盖率报告。

图 6.3 代码覆盖率报告显示了我们信息技术资产管理系统项目中每个文件的覆盖情况。


代码覆盖率达到 70% 是一个不错的起点。在现实世界中,我们将继续与我们的团队和生成式人工智能小伙伴合作,将这个指标提高到高 90%。

我们将转向一个新的主题:使用生成式人工智能为我们描述代码列表。

6.5 将代码转换成描述 - 从代码到描述

通常,人们会交给你现有的源代码。确定这段代码的确切入口点、代码的目的以及棕地项目的整体结构可能是具有挑战性的。幸运的是,这正是生成式人工智能真正擅长的领域之一:将代码翻译成文本描述。

首先,我们将把(有 bug 的)代码从上一节复制到 Copilot 聊天对话框中,并加上提示语:“这段代码是做什么的?

图 6.4 上一节的有 bug 代码,并附有提示,要求 Copilot 聊天向我们解释这段代码。


这个解释引人注目的地方在于,Copilot 聊天检测到代码中存在一个 bug,并提出了如何修复这个 bug 的建议。

图 6.5 Copilot 聊天解释了代码的目的,识别了 bug,并提出了修复建议。


接下来,我们将提出一个更具挑战性的问题。我们将要求它解释我们在本章前面设置的行为测试。将代码复制到 Copilot 聊天窗口中,并询问这个类做什么。您可能会收到类似以下清单的回复。

列表 6.12 Copilot Chat 解释了我们之前编写的行为测试的行为。
The code you provided is not a class but a series of step definitions for a Behavior-Driven Development (BDD) test using the Behave framework in Python. These steps correspond to a specific scenario written in Gherkin language (Given, When, Then format).
These step definitions describe how to interact with an AssetManager class and an InMemoryAssetRepository class. They're meant to test the creation of assets and the calculation of the total cost of all assets.
Let's go through each step:
@given('the Asset Manager is running'): This sets up the initial state for the test. It initializes the AssetManager with an InMemoryAssetRepository (which presumably stores assets in memory during the execution of the test) and a mocked AssetLocationMediator.
@given('the InMemoryAssetRepository is initialized') and @given('the AssetLocationMediator is mocked'): These steps appear to be placeholders, as they don't execute any actions.
@when('I create an asset with a cost of ${cost}') and @when('I create another asset with a cost of ${cost}'): These steps create Asset instances with the given cost and add them to the AssetManager.
@then('the total cost of all assets should be ${total_cost}'): This step retrieves all the assets from the AssetManager, calculates the total cost, and checks that it matches the expected total cost.
This sequence of steps allows the user to test the process of creating assets and validating the total cost of all assets in the AssetManager.
    # Question: What does this method do?
    # Answer: It gets an asset by its id
    async def get_asset(self, asset_id: int):
        asset = self._asset_rest_port.read(asset_id)
        if asset is None:
            raise HTTPException(status_code=404, detail="Asset not found")
        return from_asset(asset)

6.6 从一种语言翻译成另一种语言

看起来很遥远,您可能会发现自己正在查看一个语言只是稍有了解的编程语言编写的代码库。或者,您可能想在当前语言中使用来自另一种语言的特定函数。例如,以 JavaScript 重写 AssetFundingDetails 类会是什么样子呢?好吧,让我们问问 Copilot Chat。

列表 6.13 Copilot Chat 将我们的 AssetFundingDetails 类翻译成了 JavaScript。
class Asset {
  constructor(id, name, status, category, cost, useful_life, salvage_value, purchase_date, locations, funding_details) {
    this.id = id;
    this.name = name;
    this.status = status;
    this.category = category;
    this.cost = cost;
    this.useful_life = useful_life;
    this.salvage_value = salvage_value;
    this.purchase_date = purchase_date;
    this.locations = locations;
    this.funding_details = funding_details;
  }
}
class FundingDetails {
  constructor(asset, funding_source, funding_amount) {
    this.asset = asset;
    this.funding_source = funding_source;
    this.funding_amount = funding_amount;
  }
}

我们可能会认为翻译一个或两个类太容易了。好吧,我们将尝试更复杂的事情。如果用 JavaScript 写 AssetManager 行为测试,它会是什么样子?

列表 6.14 Copilot Chat 将我们的 AssetManager 行为测试翻译成了 JavaScript。
const AssetManager = require('./asset_manager');
const Asset = require('./asset');
describe('AssetManager', () => {
  let assetManager;
  beforeEach(() => {
    assetManager = new AssetManager();
  });
  describe('addAsset', () => {
    it('should add an asset to the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      expect(assetManager.assets.length).toBe(1);
      expect(assetManager.assets[0]).toBe(asset);
    });
  });
  describe('removeAsset', () => {
    it('should remove an asset from the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      assetManager.removeAsset(asset);
      expect(assetManager.assets.length).toBe(0);
    });
  });
  describe('getAssetById', () => {
    it('should return the asset with the given ID', () => {
      const asset1 = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      const asset2 = new Asset(2, 'Printer', 'Active', 'Hardware', 500.0, 3, 50.0, new Date(), [], null);
      assetManager.addAsset(asset1);
      assetManager.addAsset(asset2);
      const result = assetManager.getAssetById(2);
      expect(result).toBe(asset2);
    });
    it('should return null if no asset with the given ID is found', () => {
      const result = assetManager.getAssetById(1);
      expect(result).toBeNull();
    });
  });
});

另外,您可能希望让 GPT 以惯用的 JavaScript 重写代码。您只需要说:“用惯用的 JavaScript 编写 AssetManager。”Copilot Chat 将告诉您它使用 ES6 中引入的 class 语法来定义 AssetManager 类。

列表 6.15 AssetManager 类被以惯用的 JavaScript 重写。
class AssetManager {
  constructor() {
    this.assets = [];
  }
  addAsset(asset) {
    this.assets.push(asset);
  }
  removeAsset(asset) {
    const index = this.assets.indexOf(asset);
    if (index !== -1) {
      this.assets.splice(index, 1);
    }
  }
  getAssetById(id) {
    return this.assets.find(asset => asset.id === id) || null;
  }
}

这是 AssetManager 行为测试在 JavaScript 中使用 Jest 测试框架的示例(Copilot Chat 在没有我们的建议的情况下包含了这个):

列表 6.16 Copilot Chat 用惯用的 JavaScript 重写了我们的 AssetManager 测试。
const AssetManager = require('./asset_manager');
const Asset = require('./asset');
describe('AssetManager', () => {
  let assetManager;
  beforeEach(() => {
    assetManager = new AssetManager();
  });
  describe('addAsset', () => {
    it('should add an asset to the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      expect(assetManager.assets.length).toBe(1);
      expect(assetManager.assets[0]).toBe(asset);
    });
  });
  describe('removeAsset', () => {
    it('should remove an asset from the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      assetManager.removeAsset(asset);
      expect(assetManager.assets.length).toBe(0);
    });
  });
  describe('getAssetById', () => {
    it('should return the asset with the given ID', () => {
      const asset1 = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      const asset2 = new Asset(2, 'Printer', 'Active', 'Hardware', 500.0, 3, 50.0, new Date(), [], null);
      assetManager.addAsset(asset1);
      assetManager.addAsset(asset2);
      const result = assetManager.getAssetById(2);
      expect(result).toBe(asset2);
    });
    it('should return null if no asset with the given ID is found', () => {
      const result = assetManager.getAssetById(1);
      expect(result).toBeNull();
    });
  });
});

在此示例中,我们使用 Jest 测试框架为 AssetManager 类定义了一组行为测试。我们使用 describe 库确定测试套件和单个测试。

在每个测试中,我们创建 AssetManager 类的一个实例并对其执行某些操作,例如添加或删除资产。然后,我们使用 expect 函数对 AssetManager 类的行为进行断言,例如检查资产是否已添加到资产列表或资产是否已从资产列表中删除。

请注意,在 JavaScript 中,定义类和构造函数的语法与 Python 略有不同,我们使用 required 函数从各自的模块中导入 AssetManager 和 Asset 类。

最后,为了大结局:我们将开始一个新的 ChatGPT 4.0 会话,并将第三章中的 Mermaid 图表粘贴到其中。请以提示“这是我应用程序的 Mermaid 图表,请用 Golang 实现。”为主导。它将返回用 Golang 渲染的代码。

列表 6.17 Copilot Chat 用惯用的 Golang 重写了我们的 Asset 类。
type Asset struct {
    id            int
    name          string
    status        string
    category      string
    fundingDetails *FundingDetails
}
func NewAsset(name, status, category string, fundingDetails *FundingDetails) *Asset {
    return &Asset{
        name:          name,
        status:        status,
        category:      category,
        fundingDetails: fundingDetails,
    }
}

接下来,告诉它切换到 Java。

列表 6.18 Copilot Chat 用惯用的 Java 重写了我们的 Asset 类。
class Asset {
    private int id;
    private String name;
    private String status;
    private String category;
    private FundingDetails fundingDetails;
    public Asset(String name, String status, String category, FundingDetails fundingDetails) {
        this.name = name;
        this.status = status;
        this.category = category;
        this.fundingDetails = fundingDetails;
    }

6.7 摘要

  • 单元测试:重点测试代码的单个组件或单元,以识别特定单元内的错误和问题。单元测试将是您代码库中数量最多的部分。
  • 集成测试:测试软件的不同组件或模块之间的交互,以确保无缝集成并检测通信问题。
  • 行为测试:从最终用户的角度测试系统的功能,确保其符合要求和规格。
  • 模拟对象:以受控的方式模拟自然对象的行为,对于测试和模拟错误条件非常有用。Mock 对象特别擅长模仿测试运行所需但不在测试范围内的系统的某些部分。例如,如果您的类有一个构造函数参数为数据库,但您不想直接测试数据库,因为数据可能会更改,导致您的测试无法得出结论、不可重复或不确定。
  • 圈复杂度:衡量软件模块独立路径的数量,表示复杂性和潜在漏洞。
  • Halstead 复杂度度量:根据独特的运算符和操作数评估软件复杂度,提供关于代码大小和认知复杂度的见解。
  • 可维护性指数:组合了圈复杂度、代码行数和 Halstead 度量等因素,评估软件的可维护性。
  • 代码覆盖率:用于评估测试效果的衡量标准,表示代码被测试的程度以及出现未捕获错误的潜力。通常情况下,覆盖率越高越好。
  • 语言熟悉度:需要在一个陌生的编程语言中导航代码或希望在当前语言中使用另一种语言的功能。


相关文章
|
7天前
|
人工智能 数据管理 API
阿里云百炼又获大奖!阿里云百炼入选 2024 最受开发者欢迎的 AI 应用开发平台榜15强
2024年最受开发者欢迎的AI应用开发平台榜单发布,阿里云百炼入选15强。持续推动AI开发者生态建设,提供开放平台、培训支持、行业解决方案,注重数据安全与合规,致力于生态合作与共赢,加速企业数智化转型。
|
6天前
|
机器学习/深度学习 人工智能 算法
转载:【AI系统】AI 发展驱动力
本文介绍了AI的起源与发展历程,强调了2016年AlphaGo胜利对AI关注度的提升。文中详细解析了AI技术在搜索引擎、图片检索、广告推荐等领域的应用,并阐述了机器学习、深度学习和神经网络之间的关系。文章还深入探讨了AI的学习方法,包括模型的输入输出确定、模型设计与开发、训练过程(前向传播、反向传播、梯度更新)及推理过程。最后,文章概述了AI算法的现状与发展趋势,以及AI系统出现的背景,包括大数据、算法进步和算力提升三大关键因素。
转载:【AI系统】AI 发展驱动力
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
AI驱动的个性化学习路径优化
在当前教育领域,个性化学习正逐渐成为一种趋势。本文探讨了如何利用人工智能技术来优化个性化学习路径,提高学习效率和质量。通过分析学生的学习行为、偏好和表现,AI可以动态调整学习内容和难度,实现真正的因材施教。文章还讨论了实施这种技术所面临的挑战和潜在的解决方案。
53 7
|
20天前
|
机器学习/深度学习 人工智能 自然语言处理
智能化软件测试:AI驱动的自动化测试策略与实践####
本文深入探讨了人工智能(AI)在软件测试领域的创新应用,通过分析AI技术如何优化测试流程、提升测试效率及质量,阐述了智能化软件测试的核心价值。文章首先概述了传统软件测试面临的挑战,随后详细介绍了AI驱动的自动化测试工具与框架,包括自然语言处理(NLP)、机器学习(ML)算法在缺陷预测、测试用例生成及自动化回归测试中的应用实例。最后,文章展望了智能化软件测试的未来发展趋势,强调了持续学习与适应能力对于保持测试策略有效性的重要性。 ####
|
21天前
|
机器学习/深度学习 人工智能 算法
【AI系统】AI芯片驱动智能革命
本课程深入解析AI模型设计演进,探讨AI算法如何影响AI芯片设计,涵盖CPU、GPU、FPGA、ASIC等主流AI芯片,旨在全面理解AI系统体系,适应后摩尔定律时代的技术挑战。
34 5
|
19天前
|
人工智能 机器人 数据库
使用FlowiseAI轻松搭建AI驱动的交互式应用
FlowiseAI 是一款开源低代码工具,旨在帮助开发者构建自定义的语言学习模型应用。它提供拖放界面,支持与多种AI模型和数据库集成,适用于创建聊天机器人等交互式应用。使用阿里云的计算巢,用户可通过一键部署快速启动FlowiseAI,并通过简单的步骤配置和运行自定义的LLM应用。
|
20天前
|
人工智能 大数据 云计算
【AI系统】AI 发展驱动力
本文介绍了阿里云在2023年云栖大会上发布的多项新技术和产品,涵盖云计算、大数据、人工智能等领域,展示了阿里云最新的技术成果和行业解决方案,助力企业数字化转型。
|
22天前
|
数据采集 人工智能 机器人
AMD的CIO谈AI驱动转型和IT的未来
AMD的CIO谈AI驱动转型和IT的未来
|
25天前
|
机器学习/深度学习 人工智能 运维
智能运维:AI驱动的IT运维革命###
【10月更文挑战第21天】 随着数字化转型的深入,智能运维(AIOps)正逐步成为企业IT管理的核心。本文将探讨AI技术如何赋能运维领域,通过自动化、智能化手段提升系统稳定性和效率,降低运营成本,并分享实施智能运维的最佳实践与挑战应对策略。 ###
53 1
|
22天前
|
机器学习/深度学习 人工智能 自然语言处理
【AI系统】AI 发展驱动力
AI起源于20世纪50年代,经历起伏后,2016年AlphaGo的胜利重燃公众热情。实际上,AI技术早已在互联网公司广泛应用,如搜索引擎、广告推荐等。机器学习是实现AI的方法之一,深度学习则是机器学习的重要技术,通过神经网络实现。近年来,随着大数据积累、算法进步及算力增强,AI取得了显著成就,特别是在图像识别、自然语言处理等领域。AI系统的设计需考虑数据驱动、算法优化及高性能计算,以适应更大规模、更复杂的应用需求。
58 0