<think>我们需要为每一行代码前面添加一个缩进(4个空格)。注意:原始代码中已经有一些缩进,但根据要求,我们要在每一行前面再额外增加一个4空格的缩进。
注意:空行也需要加一个缩进(即空行变成4个空格加一个换行),但原代码中可能没有空行。另外,注释和代码都需要加。
但是,注意原代码中可能包含多行字符串(triple quoted strings),但我们这里只是简单地在每一行前面添加4个空格,不会破坏多行字符串,因为多行字符串内部的缩进也是字符串的一部分。
然而,我们注意到原始代码是Python代码,缩进非常重要。我们只需要在每一行的开头添加4个空格,包括那些已经缩进的行,这样整个代码块就会整体向右移动。
但是,注意:原始代码中可能包含一些行内注释,我们同样需要在它们前面加缩进。
步骤:
1. 将代码字符串按行分割。
2. 对每一行,在开头添加4个空格(如果该行是空行,那么添加4个空格后仍然是空行?实际上,空行就是只有换行符,我们在前面加上4个空格,那么它就变成了一个只有4个空格和换行符的行,这不会影响程序运行,但可能不太美观。不过,题目要求每行代码前面加一个缩进,所以空行也要加)。
3. 重新组合成字符串。
但是,注意:原始代码中可能包含一些不需要缩进的行?比如,在代码字符串中,我们只处理给定的代码行,而给定的代码行都是函数体内的代码,已经缩进了,所以再缩进一层也没问题。
另外,注意代码中已经有一些缩进,例如4个空格、8个空格等。我们统一在每一行前面再加4个空格。
但是,注意:在Python中,如果一行代码本身有缩进,那么再加缩进可能会改变其逻辑。不过,这个函数体我们是要嵌入到另一个函数中吗?题目没有说明,但根据要求,我们只做添加缩进的操作。
开始处理:
我们将整个代码字符串按行分割,然后在每一行前面加上4个空格(注意:不要用制表符,用空格)。
注意:原代码中第一行是`def process_types_stats_mode(self, scl_folder, prefix):`,我们也要在它前面加4个空格。这样,整个函数体就会再缩进一级。
但是,我们注意到,这个函数本身是一个方法,它已经在一个类里面了?所以再加一级缩进是可以的。
另外,注意文档字符串(docstring)也要加缩进。
我们直接处理整个字符串。
</think>
```python
def process_types_stats_mode(self, scl_folder, prefix):
"""处理类型统计模式:根据分组标识统计Q列值及其对应列的无色状态"""
# 检查输入文件是否存在
input_file = self.input_path_var.get()
if not input_file:
messagebox.showwarning("警告", "请先选择统计表")
self.logger.warning("未选择统计表")
return
if not os.path.exists(input_file):
messagebox.showerror("错误", f"统计表文件不存在: {input_file}")
self.logger.error(f"统计表文件不存在: {input_file}")
return
try:
# 使用openpyxl加载工作簿
wb = openpyxl.load_workbook(input_file)
sheet = wb.active
self.logger.info(f"工作簿加载成功, 工作表: {sheet.title}")
# 初始化处理器
processor = TypesStatusProcessor(self.color_detector)
# 获取分组信息(从N列开始)
group_config = {} # {分组前缀: (起始列, 结果列)}
start_col = 14 # N列是第14列
col = start_col
# 遍历第3行,获取分组前缀和对应的列位置
while col <= sheet.max_column:
cell = sheet.cell(row=3, column=col)
if not cell.value:
break
prefix_value = str(cell.value).strip()
if prefix_value:
# 确定该分组的结果列位置
# 每组4列:前缀列 + 频次列 + A列无色 + M列无色
group_config[prefix_value] = {
'prefix_col': col,
'count_col': col + 1,
'a_no_fill_col': col + 2,
'm_no_fill_col': col + 3
}
self.logger.info(f"分组配置: {prefix_value} -> 列 {col}-{col+3}")
# 每组占4列,移动到下一组
col += 4
if not group_config:
messagebox.showerror("错误", "未找到分组前缀信息")
self.logger.error("在第3行未找到分组前缀信息")
return
# 初始化统计结果存储
# 结构: {分组前缀: {n: {'count': int, 'a_no_fill': int, 'm_no_fill': int}}}
group_results = {prefix: defaultdict(lambda: {'count': 0, 'a_no_fill': 0, 'm_no_fill': 0})
for prefix in group_config}
# 处理每个分组
total_groups = len(group_config)
processed_groups = 0
problem_files = 0
start_time = time.time()
for prefix_value, col_info in group_config.items():
# 更新进度
processed_groups += 1
group_progress = (processed_groups / total_groups) * 100
self.progress_var.set(group_progress)
self.progress_label.config(text=f"{group_progress:.1f}%")
self.status_var.set(f"处理分组: {prefix_value} ({processed_groups}/{total_groups})")
self.root.update()
# 构建文件匹配模式
file_pattern = f"SCL_{prefix_value}*.xlsx"
self.logger.info(f"查找匹配文件: {file_pattern}")
# 查找匹配的文件
scl_files = glob.glob(os.path.join(scl_folder, f"SCL_{prefix_value}*.xlsx"))
if not scl_files:
scl_files = []
for root, _, files in os.walk(scl_folder):
for file in files:
if file.lower().startswith(f"scl_{prefix_value.lower()}") and file.lower().endswith(".xlsx"):
scl_files.append(os.path.join(root, file))
if not scl_files:
self.logger.warning(f"未找到匹配 {file_pattern} 的文件")
continue
total_files = len(scl_files)
self.logger.info(f"找到 {total_files} 个匹配文件")
# 处理每个文件
for idx, file_path in enumerate(scl_files):
file_progress = group_progress + (idx / total_files) * (100 / total_groups)
self.progress_var.set(file_progress)
self.progress_label.config(text=f"{file_progress:.1f}%")
self.status_var.set(f"处理文件: {os.path.basename(file_path)}")
self.root.update()
try:
# 处理文件并获取结果
results, _, _ = processor.process_file(file_path)
# 合并结果到当前分组
for n, count in results["q_values"].items():
group_results[prefix_value][n]['count'] += count
for n, count in results["a_colors"].items():
group_results[prefix_value][n]['a_no_fill'] += count
for n, count in results["m_colors"].items():
group_results[prefix_value][n]['m_no_fill'] += count
self.logger.info(f"文件处理成功: {os.path.basename(file_path)}")
except Exception as e:
problem_files += 1
self.logger.error(f"处理文件 {os.path.basename(file_path)} 时出错: {str(e)}")
# 清空之前的统计结果(每个分组的结果区域)
self.logger.info("清空之前的结果区域")
for prefix, col_info in group_config.items():
for col_idx in [col_info['count_col'], col_info['a_no_fill_col'], col_info['m_no_fill_col']]:
for row in range(4, sheet.max_row + 1):
if row not in TypesStatusProcessor.SKIP_ROWS:
sheet.cell(row=row, column=col_idx).value = None
# 写入新的统计结果
self.logger.info("开始写入统计结果")
for prefix_value, results in group_results.items():
col_info = group_config[prefix_value]
for n, stats in results.items():
target_row = 4 + n
# 跳过指定行
if target_row in TypesStatusProcessor.SKIP_ROWS:
continue
# 确保行存在
if target_row > sheet.max_row:
for _ in range(sheet.max_row + 1, target_row + 1):
sheet.append([""] * sheet.max_column)
# 写入统计结果到分组对应的列
sheet.cell(row=target_row, column=col_info['count_col']).value = stats['count']
sheet.cell(row=target_row, column=col_info['a_no_fill_col']).value = stats['a_no_fill']
sheet.cell(row=target_row, column=col_info['m_no_fill_col']).value = stats['m_no_fill']
# 保存修改后的Excel文件
output_path = input_file.replace(".xlsx", "_types_stats_processed.xlsx")
wb.save(output_path)
self.logger.info(f"结果已保存到: {output_path}")
elapsed_time = time.time() - start_time
status_msg = f"类型统计处理完成! 处理了 {len(group_config)} 个分组, {len(scl_files)} 个文件, 耗时 {elapsed_time:.2f} 秒"
if problem_files > 0:
status_msg += f", {problem_files} 个文件处理失败"
self.status_var.set(status_msg)
self.logger.info(status_msg)
# 更新结果文本框
self.result_text.config(state=tk.NORMAL)
self.result_text.delete(1.0, tk.END) # 清空之前的内容
self.result_text.insert(tk.END, f"{status_msg}\n")
self.result_text.insert(tk.END, f"结果已保存到: {output_path}\n\n")
# 添加分组统计摘要
self.result_text.insert(tk.END, "分组统计摘要:\n")
for prefix, col_info in group_config.items():
file_count = len([f for f in scl_files if f.lower().startswith(f"scl_{prefix.lower()}")])
n_count = len(group_results[prefix])
self.result_text.insert(tk.END, f"- {prefix}: {file_count} 个文件, {n_count} 个不同的n值\n")
self.result_text.see(tk.END)
self.result_text.config(state=tk.DISABLED)
messagebox.showinfo("完成", status_msg)
except Exception as e:
error_msg = f"处理过程中发生错误: {str(e)}"
self.logger.exception(error_msg)
messagebox.showerror("错误", error_msg)
self.status_var.set("处理失败!")
```