ChatGPT真的能提升生产力吗?【AI版】
- 无意间的刷到的视频
- 一、提需求
- 二、ChatGPT用Python编写代码
- 三、意外的解释
- 四、ChatGPT改用Java编写代码
- 五、GPT第二次生成Java代码
- 尾巴
无意间的刷到的视频
晚上在家刷视频,突然看到一个在讲关于AI编程的视频,心里疑问:真的假的,这么厉害的吗?于是我看完他的讲解和操作,他这个视频中确实用ChatGPT实现了他所提出的要求,编写了一段代码,当然,up主要求用的Python编写的,我不知道用C++或者Java行不行得通,接下来我就亲自使用以下ChatGPT,验验货。
一、提需求
我需要将给定文件夹中的所有Excel表数据,汇总到一个给定的Excel表中,请按照以下要求,
编写Python:
一、每个分表中有两个sheet,第一个是班级基本信息,第二个是班级学生成绩排名;
二、班级基本信息sheet中,班级编号、教师姓名、班级人数、班长,教师姓名;
三、班级成绩排名sheet中,第一列是序号、第二列是学号、第三列是学生姓名、第四列是成绩;
四、总表只需要一个sheet,并且需将列设置为序号、班级编号、教师姓名、班级人数、班长、学号、学生姓名、成绩;
五、班级编号、教师姓名、班级人数,必须要和每个学生的成绩信息一一对应;
六、做一个程序运行进度条,表示已复制到的学生条目数。
二、ChatGPT用Python编写代码
下面是使用GPT的截图:
生成代码如下:
import os
import openpyxl
from tqdm import tqdm
# 定义常量
BASE_DIR = 'path/to/folder' # 文件夹路径
OUTPUT_FILE = 'path/to/output.xlsx' # 输出文件路径
SHEET_NAMES = ['基本信息', '成绩排名'] # sheet名称
HEADER_ROWS = [1, 1] # 表头所在行数
HEADER_COLS = [1, 1] # 表头所在列数
CLASS_INFO_COLS = [1, 2, 3, 4, 2] # 班级基本信息所在列数
RANK_COLS = [1, 2, 3, 4] # 成绩排名所在列数
# 初始化输出文件
output_wb = openpyxl.Workbook()
output_ws = output_wb.active
output_ws.append(['序号', '班级编号', '教师姓名', '班级人数', '班长', '学号', '学生姓名', '成绩'])
# 遍历文件夹中的Excel文件
for filename in tqdm(os.listdir(BASE_DIR)):
if not filename.endswith('.xlsx'):
continue
# 打开文件
filepath = os.path.join(BASE_DIR, filename)
wb = openpyxl.load_workbook(filepath)
# 遍历sheet
for i, sheet_name in enumerate(SHEET_NAMES):
ws = wb[sheet_name]
# 获取表头
header_row = HEADER_ROWS[i]
header_col = HEADER_COLS[i]
header = [cell.value for cell in ws[header_row] if cell.value]
# 获取班级基本信息
if sheet_name == '基本信息':
class_info = [ws.cell(row=header_row+1, column=col).value for col in CLASS_INFO_COLS]
# 获取成绩排名
elif sheet_name == '成绩排名':
for row in range(header_row+1, ws.max_row+1):
rank = [ws.cell(row=row, column=col).value for col in RANK_COLS]
output_ws.append([output_ws.max_row, *class_info, *rank])
wb.close()
# 保存输出文件
output_wb.save(OUTPUT_FILE)
这还不是最厉害的
三、意外的解释
更令人惊讶的是还会对代码进行解释,这就不得了了。接下来看看GPT对它所生成代码的解释:
解释一下代码的主要部分:
- 第1行导入了必要的模块,其中os用于文件操作,openpyxl用于读写Excel文件,tqdm用于显示进度条。
- 第5-9行定义了常量,包括文件夹路径、输出文件路径、sheet名称等。
- 第12-19行初始化输出文件,创建一个新的Excel文件,并在第一个sheet中添加表头。
- 第22-42行遍历文件夹中的Excel文件,打开每个文件并遍历其中的sheet。
- 第25-27行判断当前sheet是班级基本信息还是成绩排名,分别获取表头和班级基本信息。
- 第30-37行在成绩排名sheet中遍历每一行,获取学生的成绩信息,并将班级基本信息和成绩信息合并到输出文件中。
- 第40-41行关闭当前文件。
- 第44-46行保存输出文件。
其中使用了tqdm模块来显示进度条,可以让程序更加友好。如果没有安装该模块,可以使用以下命令进行安装:
pip install tqdm
这个效果非常不错了,如果运行上述代码有误,还可以复制错误提示让GPT分析并解决问题,可以说是保姆级别的开发助手了。
四、ChatGPT改用Java编写代码
本来到这里视频里up主就结束的,我又想了一下,能否用Java语言实现出来,于是就开始给GPT命令,很简单,只需把需求描述里的Python改为Java即可:
生成代码如下:
import java.io.File;
import java.io.IOException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class ExcelMerger {
public static final String BASE_DIR = "path/to/folder"; // 文件夹路径
public static final String OUTPUT_FILE = "path/to/output.xlsx"; // 输出文件路径
public static final String[] SHEET_NAMES = {"基本信息", "成绩排名"}; // sheet名称
public static final int[] HEADER_ROWS = {0, 0}; // 表头所在行数
public static final int[] HEADER_COLS = {0, 0}; // 表头所在列数
public static final int[] CLASS_INFO_COLS = {0, 1, 2, 3, 1}; // 班级基本信息所在列数
public static final int[] RANK_COLS = {0, 1, 2, 3}; // 成绩排名所在列数
public static void main(String[] args) {
// 初始化输出文件
Workbook outputWb = new XSSFWorkbook();
Sheet outputWs = outputWb.createSheet("汇总数据");
Row headerRow = outputWs.createRow(0);
headerRow.createCell(0).setCellValue("序号");
headerRow.createCell(1).setCellValue("班级编号");
headerRow.createCell(2).setCellValue("教师姓名");
headerRow.createCell(3).setCellValue("班级人数");
headerRow.createCell(4).setCellValue("班长");
headerRow.createCell(5).setCellValue("学号");
headerRow.createCell(6).setCellValue("学生姓名");
headerRow.createCell(7).setCellValue("成绩");
// 遍历文件夹中的Excel文件
File folder = new File(BASE_DIR);
File[] files = folder.listFiles();
int rowNum = 1; // 当前行号
for (File file : Objects.requireNonNull(files)) {
if (!file.isFile() || !file.getName().endsWith(".xlsx")) {
continue;
}
try {
// 打开文件
Workbook wb = new XSSFWorkbook(file);
for (int i = 0; i < SHEET_NAMES.length; i++) {
Sheet sheet = wb.getSheet(SHEET_NAMES[i]);
if (sheet == null) {
continue;
}
// 获取表头
int headerRowNum = HEADER_ROWS[i];
int headerColNum = HEADER_COLS[i];
Row headerRow = sheet.getRow(headerRowNum);
List<String> header = new ArrayList<>();
for (int j = headerColNum; j < headerRow.getLastCellNum(); j++) {
Cell cell = headerRow.getCell(j);
if (cell != null && cell.getCellType() == CellType.STRING) {
header.add(cell.getStringCellValue());
} else {
header.add("");
}
}
// 获取班级基本信息
if (SHEET_NAMES[i].equals("基本信息")) {
Row classInfoRow = sheet.getRow(headerRowNum + 1);
String classId = classInfoRow.getCell(CLASS_INFO_COLS[0]).getStringCellValue();
String teacherName = classInfoRow.getCell(CLASS_INFO_COLS[1]).getStringCellValue();
int studentCount = (int) classInfoRow.getCell(CLASS_INFO_COLS[2]).getNumericCellValue();
String monitor = classInfoRow.getCell(CLASS_INFO_COLS[3]).getStringCellValue();
for (int j = 4; j < header.size(); j++) {
if (header.get(j).equals("教师姓名")) {
header.set(j, teacherName);
}
}
for (int j = 1; j <= studentCount; j++) {
Row outputRow = outputWs.createRow(rowNum++);
outputRow.createCell(0).setCellValue(outputRow.getRowNum());
outputRow.createCell(1).setCellValue(classId);
outputRow.createCell(2).setCellValue(teacherName);
outputRow.createCell(3).setCellValue(studentCount);
outputRow.createCell(4).setCellValue(monitor);
}
}
// 获取成绩排名
else if (SHEET_NAMES[i].equals("成绩排名")) {
for (int j = headerRowNum + 1; j <= sheet.getLastRowNum(); j++) {
Row rankRow = sheet.getRow(j);
String studentId = rankRow.getCell(RANK_COLS[1]).getStringCellValue();
String studentName = rankRow.getCell(RANK_COLS[2]).getStringCellValue();
double score = rankRow.getCell(RANK_COLS[3]).getNumericCellValue();
Row outputRow = outputWs.createRow(rowNum++);
outputRow.createCell(0).setCellValue(outputRow.getRowNum());
for (int k = 1; k < header.size(); k++) {
if (header.get(k).equals("学号")) {
outputRow.createCell(k).setCellValue(studentId);
} else if (header.get(k).equals("学生姓名")) {
outputRow.createCell(k).setCellValue(studentName);
} else if (header.get(k).equals("成绩")) {
outputRow.createCell(k).setCellValue(score);
}
}
}
}
}
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 保存输出文件
try {
outputWb.write(outputFile);
outputWb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
本来接下来ChatGPT是输出解释上述生成代码的主要含义的,但它这句话还没说完输出就中断了,下面是对话截图:
于是我不得不自己输入命令来让它解释,结果可能我输入的命令不是很具体,它把每段代码输出下来,然后再对该段代码解释。我想要的是和它用Python编写代码时解释代码含义的格式一样,就是说几行到第几行,然后再解释。于是我再把命令输入详细点,如下图:
这样解释就对了,如下:
-
第2-4行:导入所需的类和定义常量。
-
第6-13行:创建输出文件,并创建表头。其中,第9-11行根据要求创建了表头的前3列,而第12行根据表头数组的长度创建了剩余的列。
-
第15-22行:遍历文件夹中的Excel文件,并根据文件名的后缀名判断是否是Excel文件,如果不是就跳过。同时,使用一个变量rowNum来记录当前的行号,用于在输出文件中创建新的行。
-
第24-29行:打开Excel文件,并根据SHEET_NAMES数组中的名称来获取对应的Sheet对象。如果Sheet对象不存在,则跳过该Sheet。在读取完数据后,需要关闭Workbook对象,以释放资源。
-
第31-57行:获取表头和班级基本信息。其中,第31-44行获取表头,第46-60行获取班级基本信息,并根据表头中“教师姓名”这一列的位置来更新表头。然后根据学生人数在输出文件中创建相应数量的行,并将班级基本信息填充到这些行中。
-
第62-72行:获取成绩排名。其中,第62-68行遍历成绩排名Sheet中的每一行,获取学生的学号、姓名和成绩。然后在输出文件中创建新的行,并将学号、姓名和成绩填充到对应的列中。
五、GPT第二次生成Java代码
当第二次生成Java代码时,和第一次不一样了,用的方法也不一样了,相比第一次,代码量要少一些。所以问这个ChatGPT相同的问题并不一定有相同的回答。
第二次代码如下:
以下是实现上述要求的Java代码,其中进度条使用了Swing组件JProgressBar:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JProgressBar;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelMerger {
private static final String[] SHEET_NAMES = {"班级基本信息", "班级学生成绩排名"};
private static final String[] HEADER = {"序号", "班级编号", "教师姓名", "班级人数", "班长", "学号", "学生姓名", "成绩"};
public static void mergeExcelFiles(String inputFolderPath, String outputFilePath, JProgressBar progressBar) throws IOException {
List<File> inputFiles = getExcelFiles(new File(inputFolderPath));
Workbook outputWorkbook = new XSSFWorkbook();
Sheet outputSheet = outputWorkbook.createSheet();
createHeaderRow(outputSheet);
int rowNum = 1;
for (int i = 0; i < inputFiles.size(); i++) {
File inputFile = inputFiles.get(i);
Workbook inputWorkbook = new XSSFWorkbook(new FileInputStream(inputFile));
for (int j = 0; j < SHEET_NAMES.length; j++) {
Sheet inputSheet = inputWorkbook.getSheet(SHEET_NAMES[j]);
if (inputSheet == null) {
continue;
}
if (j == 0) {
mergeBasicInfo(inputSheet, outputSheet, rowNum);
} else {
mergeScoreRanking(inputSheet, outputSheet, rowNum);
}
}
rowNum += getStudentCount(inputWorkbook);
inputWorkbook.close();
progressBar.setValue((i + 1) * 100 / inputFiles.size());
}
outputWorkbook.write(new FileOutputStream(outputFilePath));
outputWorkbook.close();
}
private static List<File> getExcelFiles(File folder) {
List<File> files = new ArrayList<>();
File[] allFiles = folder.listFiles();
for (File file : allFiles) {
if (file.isFile() && file.getName().toLowerCase().endsWith(".xlsx")) {
files.add(file);
}
}
return files;
}
private static void createHeaderRow(Sheet sheet) {
Row headerRow = sheet.createRow(0);
for (int i = 0; i < HEADER.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(HEADER[i]);
}
}
private static void mergeBasicInfo(Sheet inputSheet, Sheet outputSheet, int rowNum) {
Row inputRow = inputSheet.getRow(1);
Row outputRow = outputSheet.createRow(rowNum);
outputRow.createCell(0).setCellValue(rowNum - 1);
for (int i = 1; i < 5; i++) {
Cell cell = outputRow.createCell(i);
cell.setCellValue(inputRow.getCell(i).getStringCellValue());
}
}
private static void mergeScoreRanking(Sheet inputSheet, Sheet outputSheet, int rowNum) {
int studentCount = inputSheet.getLastRowNum();
for (int i = 2; i <= studentCount; i++) {
Row inputRow = inputSheet.getRow(i);
Row outputRow = outputSheet.createRow(rowNum);
outputRow.createCell(0).setCellValue(rowNum - 1);
for (int j = 1; j < 5; j++) {
Cell cell = outputRow.createCell(j);
cell.setCellValue(inputSheet.getRow(1).getCell(j).getStringCellValue());
}
for (int j = 5; j < HEADER.length; j++) {
Cell cell = outputRow.createCell(j);
cell.setCellValue(inputRow.getCell(j - 3).getStringCellValue());
}
rowNum++;
}
}
private static int getStudentCount(Workbook workbook) {
Sheet sheet = workbook.getSheet(SHEET_NAMES[0]);
return (int) sheet.getRow(0).getCell(1).getNumericCellValue();
}
}
主要代码解释:
- 第1行:定义常量SHEET_NAMES和HEADER。
- 第3-11行:定义getExcelFiles方法,通过File类的listFiles方法获取指定文件夹下的所有Excel文件。
- 第13-17行:定义createHeaderRow方法,创建合并后Excel文件的表头行。
- 第19-35行:定义mergeBasicInfo方法,合并班级基本信息工作表。
- 第37-57行:定义mergeScoreRanking方法,合并班级学生成绩排名工作表。
- 第59-63行:定义getStudentCount方法,获取班级人数。
- 第65-96行:定义mergeExcelFiles方法,对每个Excel文件进行合并,包括合并基本信息和成绩排名两个工作表,并将合并后的结果写入输出文件。在过程中使用进度条表示合并进度。
尾巴
本次的知识分享就到这了,谢谢你这么好看还关注我,我们下期再见!