清华开源ChatGPT自动编程ChatDev项目codes.py代码解读

  • 这段代码定义了一个Codes类,这个类是用于管理生成的代码的类,它可以根据LLM的回复来提取、格式化、更新和保存代码。
  • Codes类的__init__()方法是类的构造函数,它接受一个参数generated_content,表示LLM的回复内容。它首先初始化了以下几个属性:
    • self.directory: 一个字符串,表示代码保存的目录。
    • self.version: 一个浮点数,表示代码的版本号。
    • self.generated_content: 一个字符串,表示LLM的回复内容。
    • self.codebooks: 一个字典,表示代码的集合,以文件名为键,以代码内容为值。
  • 然后它定义了两个内部函数extract_filename_from_line()和extract_filename_from_code(),用于从LLM的回复中提取文件名。这两个函数都接受一个参数lines或code,表示LLM的回复中的一部分内容。这两个函数都使用re模块来进行正则表达式匹配,并返回匹配到的文件名。如果没有匹配到文件名,则返回空字符串。
  • 接下来,如果generated_content参数不为空,则它使用re模块来遍历LLM的回复中包含在“`符号中的代码段,并将其保存在code变量中。然后它判断code变量是否包含”CODE”字符串,如果是,则跳过这个代码段,因为这是一个占位符。然后它调用extract_filename_from_line()函数来从LLM的回复中提取文件名,并将其保存在filename变量中。如果filename变量为空,则它判断code变量是否包含”__main__“字符串,如果是,则将filename变量赋值为”main.py”,因为这是主程序文件。如果filename变量仍然为空,则它调用extract_filename_from_code()函数来从code变量中提取文件名,并将其保存在filename变量中。最后它断言filename变量不为空,并将其作为键,将经过_format_code()方法格式化后的code变量作为值,添加到self.codebooks字典中。
  • _format_code()方法用于对代码进行格式化,例如去除多余的空行等。它接受一个参数code,表示代码内容。它首先使用splitlines()方法和join()方法来去除空行,并返回格式化后的代码。
  • _update_codes()方法用于更新生成的代码,根据新的LLM的回复来比较、修改和保存代码。它接受一个参数generated_content,表示新的LLM的回复内容。它首先创建一个新的Codes对象new_codes,并将generated_content作为参数传递给其构造函数。然后它导入difflib模块,用于进行文本比较。接着它遍历new_codes对象中的self.codebooks字典,对于每个键值对(即文件名和代码内容),它判断是否存在于self.codebooks字典中,或者是否与self.codebooks字典中相同键对应的值不同。如果是,则表示需要更新代码,并执行以下操作:
    • 创建一个字符串update_codes_content,并赋值为”[Update Codes]\n\n”,表示开始更新代码。
    • 在update_codes_content字符串后面追加”{} updated.\n”.format(key),表示更新了哪个文件。
    • 创建两个字符串old_codes_content和new_codes_content,并分别赋值为self.codebooks字典中相同键对应的值(即旧代码)和new_codes对象中相同键对应的值(即新代码)。如果self.codebooks字典中不存在相同键,则将old_codes_content赋值为”# None”。
    • 使用splitlines()方法将old_codes_content和new_codes_content分割成行列表,并分别赋值给lines_old和lines_new。
    • 使用difflib.unified_diff()函数来生成两个行列表之间的差异,并返回一个生成器对象unified_diff。
    • 使用join()方法将unified_diff生成器对象转换为一个字符串,并赋值给unified_diff。
    • 在update_codes_content字符串后面追加”\n\n” + “””“` ‘’’

‘’’\n”“” + unified_diff + “\n“`”,表示显示代码的差异。 – 调用utils.log_and_print_online()函数来将update_codes_content字符串记录到日志文件中,并打印出来。 – 将new_codes对象中相同键对应的值赋值给self.codebooks字典中相同键对应的值,表示更新代码。

  • _rewrite_codes()方法用于重写代码,根据self.codebooks字典中的内容来修改和保存代码。它接受一个参数git_management,表示是否进行Git管理。它首先获取self.directory属性,表示代码保存的目录,并创建一个字符串rewrite_codes_content,用于记录重写过程。然后它判断目录是否存在并且不为空,如果是,则将self.version属性加一,表示代码的版本号增加。如果目录不存在,则使用os模块的mkdir()函数来创建目录,并在rewrite_codes_content字符串后面追加”{} Created\n”.format(directory),表示创建了目录。
  • 接着它遍历self.codebooks字典中的键值对(即文件名和代码内容),对于每个键值对,它使用os模块的join()函数来拼接目录和文件名,得到文件路径,并将其保存在filepath变量中。然后它使用open()函数和write()方法来打开并写入文件,并在rewrite_codes_content字符串后面追加os.path.join(directory, filename) + ” Wrote\n”,表示写入了文件。
  • 如果git_management参数为真,则表示需要进行Git管理,它会使用os模块的system()函数来执行一些Git命令,例如初始化仓库、添加文件、提交更改等,并将self.version属性作为提交信息。
  • 最后它调用utils.log_and_print_online()函数来将rewrite_codes_content字符串记录到日志文件中,并打印出来。
  • _get_codes()方法用于获取代码,根据self.codebooks字典中的内容来生成一个字符串,表示代码的集合。它首先创建一个空字符串content,然后遍历self.codebooks字典中的键值对(即文件名和代码内容),对于每个键值对,它在content字符串后面追加”{}\n{}\n{}\n\n\n”.format(filename, “python” if filename.endswith(“.py”) else filename.split(“.”)[-1], self.codebooks[filename]),表示显示文件名和代码内容,并根据文件扩展名来指定语言类型。最后它返回content字符串。
  • _load_from_hardware()方法用于从硬盘中加载代码,根据给定的目录来读取并保存代码。它接受一个参数directory,表示代码所在的目录。它首先断言目录中存在以.py结尾的文件,然后使用os模块的walk()函数来遍历目录中的所有文件。对于每个文件,如果文件以.py结尾,则使用open()函数和read()方法来读取文件内容,并将其保存在code变量中。然后将经过_format_code()方法格式化后的code变量作为值,将文件名作为键,添加到self.codebooks字典中。最后调用utils.log_and_print_online()函数来记录并打印”{} files read from {}”.format(len(self.codebooks.keys()), directory),表示从目录中读取了多少个文件。

codes.py的代码如下:

import os
import refrom chatdev.utils import log_and_print_online
import difflibclass Codes:def __init__(self, generated_content=""):self.directory: str = Noneself.version: float = 1.0self.generated_content: str = generated_contentself.codebooks = {}def extract_filename_from_line(lines):file_name = ""for candidate in re.finditer(r"(\w+\.\w+)", lines, re.DOTALL):file_name = candidate.group()file_name = file_name.lower()return file_namedef extract_filename_from_code(code):file_name = ""regex_extract = r"class (\S+?):\n"matches_extract = re.finditer(regex_extract, code, re.DOTALL)for match_extract in matches_extract:file_name = match_extract.group(1)file_name = file_name.lower().split("(")[0] + ".py"return file_nameif generated_content != "":regex = r"(.+?)\n```.*?\n(.*?)```"matches = re.finditer(regex, self.generated_content, re.DOTALL)for match in matches:code = match.group(2)if "CODE" in code:continuegroup1 = match.group(1)filename = extract_filename_from_line(group1)if "__main__" in code:filename = "main.py"if filename == "":  # post-processingfilename = extract_filename_from_code(code)assert filename != ""if filename is not None and code is not None and len(filename) > 0 and len(code) > 0:self.codebooks[filename] = self._format_code(code)def _format_code(self, code):code = "\n".join([line for line in code.split("\n") if len(line.strip()) > 0])return codedef _update_codes(self, generated_content):new_codes = Codes(generated_content)differ = difflib.Differ()for key in new_codes.codebooks.keys():if key not in self.codebooks.keys() or self.codebooks[key] != new_codes.codebooks[key]:update_codes_content = "**[Update Codes]**\n\n"update_codes_content += "{} updated.\n".format(key)old_codes_content = self.codebooks[key] if key in self.codebooks.keys() else "# None"new_codes_content = new_codes.codebooks[key]lines_old = old_codes_content.splitlines()lines_new = new_codes_content.splitlines()unified_diff = difflib.unified_diff(lines_old, lines_new, lineterm='', fromfile='Old', tofile='New')unified_diff = '\n'.join(unified_diff)update_codes_content = update_codes_content + "\n\n" + """```
''''''\n""" + unified_diff + "\n```"log_and_print_online(update_codes_content)self.codebooks[key] = new_codes.codebooks[key]def _rewrite_codes(self, git_management) -> None:directory = self.directoryrewrite_codes_content = "**[Rewrite Codes]**\n\n"if os.path.exists(directory) and len(os.listdir(directory)) > 0:self.version += 1.0if not os.path.exists(directory):os.mkdir(self.directory)rewrite_codes_content += "{} Created\n".format(directory)for filename in self.codebooks.keys():filepath = os.path.join(directory, filename)with open(filepath, "w", encoding="utf-8") as writer:writer.write(self.codebooks[filename])rewrite_codes_content += os.path.join(directory, filename) + " Wrote\n"if git_management:if self.version == 1.0:os.system("cd {}; git init".format(self.directory))os.system("cd {}; git add .".format(self.directory))os.system("cd {}; git commit -m \"{}\"".format(self.directory, self.version))log_and_print_online(rewrite_codes_content)def _get_codes(self) -> str:content = ""for filename in self.codebooks.keys():content += "{}\n```{}\n{}\n```\n\n".format(filename,"python" if filename.endswith(".py") else filename.split(".")[-1], self.codebooks[filename])return contentdef _load_from_hardware(self, directory) -> None:assert len([filename for filename in os.listdir(directory) if filename.endswith(".py")]) > 0for root, directories, filenames in os.walk(directory):for filename in filenames:if filename.endswith(".py"):code = open(os.path.join(directory, filename), "r", encoding="utf-8").read()self.codebooks[filename] = self._format_code(code)log_and_print_online("{} files read from {}".format(len(self.codebooks.keys()), directory))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/587121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

conftest.py 配置

章节目录: 一、概述二、场景说明三、代码示例3.1 最外层3.2 商品模块测试3.3 订单模块测试3.4 用户模块测试3.5 执行结果 四、关于 conftest.py 配置 fixture五、结束语 一、概述 “conftest.py” 是 pytest 测试框架中的一个特殊的配置文件,它能够为整个…

分布式技术之缓存技术

文章目录 什么是分布式缓存?分布式缓存原理Redis 分布缓存原理Memcached 分布式缓存原理对比分析 在计算机领域的各个方面,缓存都非常重要,是提升访问性能的一个重要技术。为什么这么说呢?从单个计算机的体系结构来看,…

【并发设计模式】聊聊等待唤醒机制的规范实现

在多线程编程中,其实就是分工、协作、互斥。在很多场景中,比如A执行的过程中需要同步等待另外一个线程处理的结果,这种方式下,就是一种等待唤醒的机制。本篇我们来讲述等待唤醒机制的三种实现,以及对应的应用场景。 G…

守护青山绿水 千巡翼Q20无人机变身护林员

守护青山绿水 千巡翼Q20无人机变身护林员 无人机目前在林业上的应用主要在森林资源调查、森林资源监测、森林火灾监测、森林病虫害监测防治、野生动物监测等方面。传统手段在森林资源调查中需要耗费大量人力物力,利用无人机技术可快速获得所需区域高精度信息&#…

SpringMVC学习与开发(四)

注&#xff1a;此为笔者学习狂神说SpringMVC的笔记&#xff0c;其中包含个人的笔记和理解&#xff0c;仅做学习笔记之用&#xff0c;更多详细资讯请出门左拐B站&#xff1a;狂神说!!! 11、Ajax初体验 1、伪造Ajax 结果&#xff1a;并未有xhr异步请求 <!DOCTYPE html> &…

关于蚁剑(AntSword)的溯源反制

中国蚁剑(AntSword) RCE漏洞 此漏洞在AntSword2.7.1版本上修复 &#xff0c;所以适用于AntSword2.7.1以下版本。 下面介绍被低版本蚁剑攻击后如何进行溯源反打 以物理机为攻击机&#xff0c;虚拟机kali模拟受害者&#xff0c;之后使用kali进行溯源反制 物理机内网ip地址&…

nodejs+vue网上书城图书销售商城系统io69w

功能介绍 该系统将采用B/S结构模式&#xff0c;使用Vue和ElementUI框架搭建前端页面&#xff0c;后端使用Nodejs来搭建服务器&#xff0c;并使用MySQL&#xff0c;通过axios完成前后端的交互 系统的主要功能包括首页、个人中心、用户管理、图书类型管理、图书分类管理、图书信…

计算机操作系统(OS)——P3内存管理

1、内存的基础知识 学习目标&#xff1a; 什么是内存&#xff1f;有何作用&#xff1f; 内存可存放数据。程序执行前__需要先放内存中才能被CPU处理__——缓和CPU与硬盘之间的速度矛盾。 【思考】在多道程序程序下&#xff0c;系统会有多个进程并发执行&#xff0c;也就是说…

基于电商场景的高并发RocketMQ实战-Consumer端队列负载均衡分配机制、并发消费以及消费进度提交

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…

4、内存泄漏检测(多线程)

4、内存泄漏多线程 多线程下使用Valgrind 工具的memcheck检查. 安装 sudo apt install valgrind使用 valgrind --toolmemcheck --leak-checkfull ./app_main 指令效果如下所示. wqwq-Virtual-Machine:~/work/test_zlog/build$ valgrind --toolmemcheck --leak-checkfull .…

解锁新可能:小红书笔记详情API的创意应用案例

一、引言 在当今信息爆炸的时代&#xff0c;内容创新已成为品牌和个人脱颖而出的关键。小红书&#xff0c;作为全球最大的消费类口碑库之一&#xff0c;每天产生大量的用户生成内容。这些内容不仅是用户分享的日常记录&#xff0c;更是品牌、商家和内容创作者获取灵感、洞察市…

深度学习 | ModernTCN模型结构

目录 基本介绍模型结构模型设计参考资料基本介绍 ModernTCN(Modern Temporal Convolutional Network)是一种用于时间序列建模的模型结构,它基于传统的Temporal Convolutional Network(TCN)并进行了一些改进。TCN是一种使用卷积神经网络(CNN)进行时间序列建模的方法,它…

MySQL面试题(很多大厂都在用)

问题1&#xff1a;char、varchar的区别是什么&#xff1f; varchar是变长而char的长度是固定的。如果你的内容是固定大小的&#xff0c;你会得到更好的性能。 问题2: TRUNCATE和DELETE的区别是什么&#xff1f; DELETE命令从一个表中删除某一行&#xff0c;或多行&#xff0c;…

【ArcGIS微课1000例】0082:地震灾害图件制作之DEM晕渲图(山体阴影效果)

以甘肃积石山县6.2级地震为例,基于震中100km范围内的DEM数据,制作数字高程模型山体阴影晕渲图。 文章目录 一、效果展示二、实验数据三、晕渲图制作一、效果展示 基于数字高程模型制作的山体阴影晕渲图如下所示: 二、实验数据 本试验所需要的数据包括: 1. 震中位置矢量数…

MariaDB单机多实例的配置方法

1、什么是数据库的单机多实例 数据库的单机多实例是指在一台物理服务器上运行多个数据库实例。这种部署方式允许多个数据库实例共享相同的物理资源&#xff0c;如CPU、内存和存储&#xff0c;从而提高硬件利用率并降低成本。每个数据库实例可以独立运行&#xff0c;处理不同的…

flask web学习之flask与http(二)

文章目录 1. HTTP响应1.1 响应报文1.2 常见HTTP状态码1.3 在flask中如何生成响应1.3.1重定向1.3.2错误响应 1.4响应格式 在flask程序中&#xff0c;客户端发出的请求触发相应的视图函数&#xff0c;获取返回值会作为响应的主体&#xff0c;最后生成完整的响应&#xff0c;即响应…

C#多线程(补充)

C#多线程&#xff08;补充&#xff09; C# 多线程的补充在C#中使用多线程1. Thread类2. 线程池3. Parallel类4. Task类启动任务接收任务的返回值同步调用指定连续任务任务的层次结构 5. BackgroundWorker控件 C# 多线程的补充 在C#中使用多线程 1. Thread类 使用Thread类通过…

ASM-HEMT射频建模

关于ASM-HEMT RF模型 ASM-HEMT是指用于氮化镓高迁移率电子晶体管的先进SPICE模型。该模型于2018年由紧凑模型委员会&#xff08;CMC&#xff09;进行了标准化。 ASM-HEMT模型涵盖了氮化镓器件在射频&#xff08;RF&#xff09;和功率电子应用中的应用。模型手册提供了模型方程…

力扣每日一题day39[105. 从前序与中序遍历序列构造二叉树]

思路 根据两个顺序构造一个唯一的二叉树&#xff0c;以 后先序数组的第一个元素为切割点&#xff0c;先切中序数组&#xff0c;根据中序数组&#xff0c;反过来在切先序数组。一层一层切下去&#xff0c;每次先序数组第一个元素就是节点元素。 第一步&#xff1a;如果数组大小…

【docker】—— Docker 简介

目录 &#xff08;一&#xff09;容器技术发展史 1、Jail 时代 2、云时代 3、云原生时代 &#xff08;二&#xff09;编排与容器的技术演进之路 1、DockerClient 2、RUNC&Shim 3、CRI-Containerd 4、CRI-O 5、Containerd &#xff08;三&#xff09;Docker 简介…