0


AI帮我写python脚本,效率提升N倍

当前在初创芯片公司,工作中经常需要通过脚本实现效率提升。因为公司人少,都需要自己空闲时间做一些脚本。最近使用AI做了两个尝试,明显能感觉到AI带给我的效率提升。以前是我需要自己梳理需求、写代码、调试。现在用上AI,我只需要自己提需求,然后迭代需求,测试和微调脚本即可。而且在使用AI的时候,也领会到一点和AI打交道的方法。

先介绍一下两个脚本的用途,最后会贴上可以使用的脚本代码。

脚本1:文件列表展开工具,命令行方式运行。因为芯片编译的filelist经常是嵌套的,且带环境变量的,但是有些工具(例如FPGA编译工具)需要读取打平的filelist。

脚本2:excel反标工具,带图形界面。在芯片开发末期,要做一些质量活动——就是确认下游是否覆盖了上游的需求,例如验证是否覆盖所有设计的功能点。经常需要在设计的功能点(excel文件A)上标注对应验证的测试点(excel文件B)的编号,这个工作就是需要从文件B中复制测试点编号的单元格内容,到文件A中。过程中有大量的ctrl+c和ctrl+v的操作,每次做下来,左手累的不行。希望有个脚本能实现ctrl+c和ctrl+v的动作。

1、文件列表展开脚本

要处理的文件层级如下:

顶层的filelist如下:

子级filelist内容如下:

AI提示词V1.0:

帮我写一个python脚本。工作环境为linux。filest文件中每一行是一个文件路径,把其中的环境变量展开,然后输出为一个新的文件。filelist中还会嵌套filelist,也需要展开。filelist的行前缀-f。删除文件路径两侧的空格。

生成的代码V1.0:

import os

def expand_env_variables(path):
    """展开环境变量"""
    return os.path.expandvars(path)

def process_file_list(file_list_path, output_path):
    """处理文件列表,展开环境变量,并输出到新文件"""
    expanded_paths = []
    with open(file_list_path, 'r') as file:
        for line in file:
            # 删除行首尾的空格
            line = line.strip()
            # 检查是否是文件列表的行
            if line.startswith('-f'):
                # 递归处理嵌套的filelist
                nested_file_list_path = expand_env_variables(line[2:])
                nested_paths = process_file_list(nested_file_list_path, output_path)
                expanded_paths.extend(nested_paths)
            else:
                # 展开环境变量并添加到列表
                expanded_path = expand_env_variables(line)
                expanded_paths.append(expanded_path)
    
    # 将展开后的路径写入到输出文件
    with open(output_path, 'w') as output_file:
        for path in expanded_paths:
            output_file.write(path + '\n')

# 脚本的入口点
if __name__ == "__main__":
    file_list_path = 'filelist'  # 假设你的文件名为filelist
    output_file_path = 'expanded_filelist'  # 输出文件的名称
    process_file_list(file_list_path, output_file_path)

这个脚本有3个问题:

1、就是process_file_list每次调用都会打开文件。但是递归调用的时候,写入有些问题

2、嵌套的filelist路径还会包含空格,会出错。看来去掉空格这个命令,AI理解的和我不同。

3、只处理嵌套的filelist,而且递归调用处理二级fielist时,会返回空(因为只处理前缀-f的行),导致运行出错。

AI提示词V2.0

帮我写一个python脚本。工作环境为linux。filest文件中每一行是一个文件路径,把其中的环境变量展开,然后输出为一个新的文件。filelist中还会嵌套filelist,也需要展开。filelist中嵌套的filelist的行前缀-f,其他的文件没有前缀。删除文件路径两侧的空格。文件路径提取后先保存在一个列表中,读取完成后,再一次性输出到文件。递归执行时,返回列表,不要直接写入文件。先把路径两侧可能存在的空格去掉,再展开环境变量。

生成的代码V2.0

import os

def expand_path(path):
    # 去除路径两侧的空格并展开环境变量
    return os.path.expandvars(os.path.expanduser(path.strip()))

def process_filelist(filelist_path, expanded_paths):
    # 读取filelist文件
    with open(filelist_path, 'r') as file:
        for line in file:
            original_line = line
            # 去除行首尾的空格
            stripped_line = line.strip()
            # 检查是否是嵌套的filelist文件
            if stripped_line.startswith('-f'):
                # 去除'-f'前缀并处理嵌套的filelist
                nested_filelist_path = expand_path(stripped_line[2:])
                if os.path.isfile(nested_filelist_path):
                    # 递归处理嵌套的filelist文件
                    process_filelist(nested_filelist_path, expanded_paths)
            else:
                # 展开环境变量
                expanded_path = expand_path(stripped_line)
                # 确保路径是文件并且存在,避免重复添加
                if os.path.isfile(expanded_path) and expanded_path not in expanded_paths:
                    expanded_paths.append(expanded_path)

    return expanded_paths

def main():
    # filelist文件的路径
    filelist_path = 'filelist'
    # 用于存储所有文件路径的列表
    expanded_paths = []
    # 处理filelist文件并获取所有路径
    expanded_paths = process_filelist(filelist_path, expanded_paths)
    # 将路径列表写入到新文件
    with open('expanded_file_paths.txt', 'w') as output_file:
        for path in expanded_paths:
            output_file.write(path + '\n')
    print(f"Expanded paths have been written to 'expanded_file_paths.txt'")

if __name__ == "__main__":
    main()

运行结果

2、excel反标工具

由于生成的代码比较长,我就每个都贴了。只是贴一下提示词,以及生成的脚本的缺点。

提示词V1.0

帮我写一个python脚本。使用pywin32和pyside6。需求如下:1、支持从当前已经打开的excel文件中选择excel文件;2、支持提取两个excel文件中选中的单元格的内容;3、提供界面,界面有2个下拉菜单,下拉菜单中为当前打开的excel文件名,支持从其中选择excel文件;还需要一个刷新按钮,更新下拉菜单; 4、支持界面置顶显示,也可以取消置顶显示,置顶选择按钮按下表示置顶,弹起表示取消置顶;5、支持通过一个按键(颜色为蓝色),关联两个单元格的内容——关联方式为,将其中一个文件单元格拷贝另一个文件的同一行的某列,列的位置,可以通过界面下拉菜单选择。6、界面有一个刷新按钮,用于更新excel文件列表。7、界面还支持一个按钮来表示复制的方向,按钮弹起时,表示从第一个文件复制到第二个文件的某个单元格,按键按下时表示从第二个文件复制到第一个文件的某个单元格,此单元格与excel中已选中的单元格同行,列的位置由界面选择的列位置来决定。

生成的GUI界面:

问题:可以生成图形界面每个按钮有对应的调用函数,但是调用函数里面只有一些打印提示,没有对应的功能(虽然我在提示词中对每个按钮的功能有描述,但是AI看起来只理解到对界面的诉求,没有理解按钮背后要做的动作。

提示词V2.0

提示词改进点:增加功能需求概述,放在提示词最前面;对界面显示区域进行划分。

帮我写一个python脚本。使用pywin32和pyside6。脚本支持从当前已经打开的excel文件中选择excel文件,支持复制其中一个excel文件中选中的单元格的内容,粘贴到另外一个excel选中的单元格中;脚本还支持界面。

脚本的界面需要分3个区域。

区域1包含如下控件:静态文本,内容为”Excel文件1”,按照最小长度显示;下拉菜单A,显示当前已经打开的excel的文件名,下拉菜单通过“更新”按钮刷新下拉选项。

区域2包含如下控件:静态文本,内容为”Excel文件2”,按照最小长度显示;下拉菜单A,显示当前已经打开的excel的文件名,下拉菜单通过“更新”按钮刷新下拉选项。

区域3包含控件:刷新按钮,按钮按下时,重新检测已经打开的excel文件,更新区域1和2中的下拉菜单,刷新前保留之前选中的文件名,更新下来菜单后,如果之前下拉菜单的选中的文件还在下来选项中,则还是选择和之前一样的文件名;方向按钮,弹起时表示从区域1的菜单A中选中的单元格,复制到区域2的菜单A文件当前激活的sheet的单元格,按下时,则相反,按钮支持check;关联按钮,无需check,填充浅蓝色,此按钮按下时,按照方向按钮的选择,将选中的单元格复制到另一个excel文件选中的单元格;置顶按钮,有check功能,按下时,表示置顶,此按钮填充为黄色,弹起时表示不置顶,无填充,默认为置顶。

运行效果:

生成的脚本还是有一点问题,修改后可以使用的代码如下:

import sys
import win32com.client
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
                               QLabel, QComboBox, QPushButton, QCheckBox)
from PySide6.QtCore import Qt
from PySide6.QtGui import QColor,  QShortcut, QKeySequence
import os

class ExcelManager(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.direction = 'to2'  # 'to1' or 'to2'

    def initUI(self):
        # 设置窗口标题和初始大小
        self.setWindowTitle('Excel Manager')
        self.setGeometry(100, 100, 800, 200)

        # 创建垂直布局
        layout = QVBoxLayout(self)

        # 区域1
        self.region1_layout = QHBoxLayout()
        self.label1 = QLabel('Excel文件1')
        self.label1.setMinimumWidth(self.label1.sizeHint().width())
        self.comboBoxA1 = QComboBox()
        self.region1_layout.addWidget(self.label1)
        self.region1_layout.addWidget(self.comboBoxA1, stretch=5)
        layout.addLayout(self.region1_layout)

        # 区域2
        self.region2_layout = QHBoxLayout()
        self.label2 = QLabel('Excel文件2')
        self.label2.setMinimumWidth(self.label2.sizeHint().width())
        self.comboBoxA2 = QComboBox()
        self.region2_layout.addWidget(self.label2)
        self.region2_layout.addWidget(self.comboBoxA2, stretch=5)
        layout.addLayout(self.region2_layout)

        # 区域3
        self.region3_layout = QHBoxLayout()
        self.refreshButton = QPushButton('刷新')
        self.directionButton = QPushButton('方向:1-->2')
        self.directionButton.setCheckable(True)
        self.assocButton = QPushButton('关联')
        self.assocButton.setStyleSheet("background-color: lightblue")
        self.stickyButton = QCheckBox('置顶')
        self.region3_layout.addWidget(self.refreshButton)
        self.region3_layout.addWidget(self.directionButton)
        self.region3_layout.addWidget(self.assocButton)
        self.region3_layout.addWidget(self.stickyButton)

        layout.addLayout(self.region3_layout)

        # # 创建一个全局快捷键 F4
        # self.shortcut = QShortcut(QKeySequence(Qt.Key_F4), self, context=Qt.ApplicationShortcut)
        # self.shortcut.activated.connect(self.copy_cells)

        # 连接信号和槽
        self.refreshButton.clicked.connect(self.refresh_comboboxes)
        self.directionButton.clicked.connect(self.toggle_direction)
        self.assocButton.clicked.connect(self.copy_cells)
        self.stickyButton.stateChanged.connect(self.sticky_logic)
        self.stickyButton.setChecked(True) # 默认选中

        # 刷新下拉菜单
        self.refresh_comboboxes()
        # 设置下拉菜单的默认值

    def refresh_comboboxes(self):
        # 使用pywin32获取打开的Excel文件列表
        app = win32com.client.Dispatch("Excel.Application")
        excel_files = []
        
        try:
            for book in app.Workbooks:
                excel_files.append(book.FullName)
        except (IndexError, AttributeError):
            pass
        current_selection1 = self.comboBoxA1.currentText()
        current_selection2 = self.comboBoxA2.currentText()

        self.comboBoxA1.clear()
        self.comboBoxA2.clear()
        self.comboBoxA1.addItems(excel_files)
        self.comboBoxA2.addItems(excel_files)

        if current_selection1 in excel_files:
            self.comboBoxA1.setCurrentText(current_selection1)
        if current_selection2 in excel_files:
            self.comboBoxA2.setCurrentText(current_selection2)

    def toggle_direction(self):
        # 切换方向
        if self.direction == 'to2' :
            self.direction = 'to1' 
            self.directionButton.setText('方向:文件1<--2')
        else: 
            self.direction = 'to2'
            self.directionButton.setText('方向:文件1-->2')
        print(f"方向已切换到: {self.direction}")
        

    def copy_cells(self):
        # 复制单元格内容
        if self.comboBoxA1.currentIndex() == -1 or self.comboBoxA2.currentIndex() == -1:
            print("请先选择两个Excel文件")
            return
        if(self.comboBoxA1.currentText() == self.comboBoxA2.currentText()):
            print("请先选择两个不同的Excel文件")
            return            
        xls_app = win32com.client.Dispatch("Excel.Application")
        original_display_alerts = xls_app.DisplayAlerts  # 保存原始状态
        # # 关闭警告,以便在操作过程中不显示任何对话框
        # xls_app.DisplayAlerts = False
        comboBoxA1_filename = os.path.basename(self.comboBoxA1.currentText())
        comboBoxA2_filename = os.path.basename(self.comboBoxA2.currentText())
        for wb in xls_app.Workbooks:

            if(wb.Name == comboBoxA1_filename):
                wb1=wb
            if(wb.Name == comboBoxA2_filename):
                wb2 = wb

        try:

            if self.direction == 'to2':
                wb1.Activate()
                selected_range1 = wb1.Application.Selection
                value1 = selected_range1.Value
                wb2.Activate()
                selected_range2 = wb2.Application.Selection
                if(selected_range2.Text != ""):
                    selected_range2.Value +='\n'+ value1
                else:
                    selected_range2.Value = value1
                # print(wb1.Name, selected_range1.Row, selected_range1.Column, value1)
                # print(wb2.Name, selected_range2.Row, selected_range2.Column, selected_range2.Value)
                # print('\n')
            else:
                wb2.Activate()
                selected_range2 = wb2.Application.Selection
                value2 = selected_range2.Value 
                wb1.Activate()
                selected_range1 = wb1.Application.Selection
                if(selected_range1.Text != ""):
                    selected_range1.Value +='\n'+ value2
                else:
                    selected_range1.Value = value2

        except Exception as e:
            print(f"复制出错: {e}")
        # finally:
        #     excel1.Close(SaveChanges=False)
        #     excel2.Close(SaveChanges=False)

    def sticky_logic(self, state):
        if state == Qt.Checked:
            self.stickyButton.setStyleSheet("background-color: yellow")
            self.setWindowFlags(Qt.WindowStaysOnTopHint)
        else:
            self.stickyButton.setStyleSheet("")
            self.setWindowFlags(Qt.Window)
        self.show()

def main():
    app = QApplication(sys.argv)
    excel_manager = ExcelManager()
    excel_manager.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()

copy_cells函数调整过,和我想要的有差异。但是感觉文字不好描述。

3、总结

避免错误的提示词

filelist的提示词中的

先把路径两侧可能存在的空格去掉,再展开环境变量。

我也是试过另一个错误的表述:

替换环境变量前,先去掉路径的空格

这个“前”被AI理解为位置关系,而不是操作顺序关系。

推荐使用总分结构组织提示词

建议使用总分结构。就是先描述整体的功能,然后再描述细分的功能。只描述细节的功能,感觉AI就像一个新同事一样,不知道你在说什么。先要给它一个概括的描述,然后再层层展开。

效率提升效果

首先,我自己经常使用pywin32来操作excel,对于这个库比较熟悉,所以改起来就很快。如果你对这个库一无所知,AI还很难一次做对。

但是对于第二个脚本一共接近180行,如果我自己写、调试至少需要1天的时间。但是用AI生成,我自己只是改脚本,就变得轻松狠多。

所以AI对于有一定编程经验(但不需要达到高手的水平)的人来说,提升效果很明显。


本文转载自: https://blog.csdn.net/flashman911/article/details/142416181
版权归原作者 flashman911 所有, 如有侵权,请联系我们删除。

“AI帮我写python脚本,效率提升N倍”的评论:

还没有评论