[Note] 最小环 环计数 三元环计数

本文探讨了在竞赛图中寻找三元环的问题,详细介绍了如何通过度数分类和边定向来有效计数三元环,同时提供了暴力枚举和优化算法的实现思路。

最小环
此处


环计数
是 NP 问题。状压,请
此处


Handshaking Lemma
∑ v ∈ V d e g ( v ) = 2 ∣ E ∣ \sum\limits_{v\in V}deg(v)=2|E| vVdeg(v)=2E


竞赛图三元环计数
一个竞赛图中如果存在环,则一定是三元环
你可以直接环计数
也可以用公式


求三元环
边定向度数大→度数小
度数相同则编号小→编号大(自然编号这个反过来也无所谓)
然后暴枚 u→Mark(v), u→v→Mark(w)
意思是:对于每一个点,把相邻所有点标记。
对于上面所说的相邻所有点,如果它们的相邻点里面某一个有标记就找到一个三元环。
证明
有一种简单粗暴好证明的方法是直接对度数分类不过常数可能过大
在有向图中只需要判断一下定向后的方向是否跟原有向图中的一样,就能够知道某个三元环是否合法。

class SCLRuleProcessor: """SCL规则处理器,包含详细的颜色映射逻辑""" def __init__(self, color_detector=None): self.color_detector = color_detector or ExcelColorDetector() # 创建专用日志记录器 self.logger = logging.getLogger('SCLProcessor.RuleProcessor') if not self.logger.handlers: # 如果没有处理器,添加控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) console_handler.setFormatter(formatter) self.logger.addHandler(console_handler) self.logger.setLevel(logging.INFO) # 固定列位置 self.COLUMN_MAPPING = { "差分種別": 12, # L列 "变更内容": 13, # M列 "判断列": 14, # N列 "判断理由": 15, # O列 "变更背景": 16, # P列 "备注": 17 # Q列 } # 新增规则的关键词 - 添加更多变体 self.keywords = [ "波形図の尾の延長、非機能変更と判定されました。", "波形図の尾の延長", "非機能変更", "選択肢的补充说明,不属于功能变更。", "补充说明", "不属于功能变更", "空白行が追加され、非機能変更と判定された", "空白行追加", "空行が削除され、非機能変更と判定された", "空行削除", "无效更改,判定为无功能变更。", "无效更改", "書式変更で機能変更ではないと判断されました。", "書式変更", "仅修改了背景色,不影响软件设计,判定为无功能变更。", "仅修改背景色", "背景色修改", "非功能变更", "无功能变更", "書式調整", "非機能修正" ] # 创建关键词正则表达式模式 self.keyword_pattern = self._create_keyword_pattern() # 规则映射到目标列 self.RULE_MAPPING = { # 规则1-18: 备注值统计 "diff_no_fill": 16, # P列 "diff_fill": 23, # W列 "diff_add_no_fill": 27, # AA列 "diff_add_fill": 30, # AD列 "diff_change_no_fill": 34, # AH列 "diff_change_fill": 37, # AK列 "diff_delete_no_fill": 42, # AP列 "diff_delete_fill": 45, # AS列 "valid_yes_no_fill": 50, # AX列 "valid_yes_fill": 53, # BA列 "valid_no_no_fill": 57, # BE列 "valid_no_fill": 60, # BH列 "valid_yes_reason_no_fill": 64, # BL列 "valid_yes_reason_fill": 67, # BO列 "valid_no_reason_no_fill": 71, # BS列 "valid_no_reason_fill": 74, # BV列 "background_no_fill": 78, # BZ列 "background_fill": 85, # CG列, # 规则19-59: 计数统计 "rule19": 14, # N列 "rule20": 15, # O列 "rule21": 17, # Q列 "rule22": 18, # R列 "rule23": 19, # S列 "rule24": 20, # T列 "rule25": 21, # U列 "rule26": 22, # V列 "rule27": 25, # Y列 "rule28": 26, # Z列 "rule29": 28, # AB列 "rule30": 29, # AC列 "rule31": 32, # AF列 "rule32": 33, # AG列 "rule33": 35, # AI列 "rule34": 36, # AJ列 "rule35": 47, # AU列 "rule36": 48, # AV列 "rule37": 49, # AW列 "rule38": 51, # AY列 "rule39": 52, # AZ列 "rule40": 55, # BC列 "rule41": 56, # BD列 "rule42": 58, # BF列 "rule43": 59, # BG列 "rule44": 62, # BJ列 "rule45": 63, # BK列 "rule46": 65, # BM列 "rule47": 66, # BN列 "rule48": 69, # BQ列 "rule49": 70, # BR列 "rule50": 72, # BT列 "rule51": 73, # BU列 "rule52": 76, # BX列 "rule53": 77, # BY列 "rule54": 79, # CA列 "rule55": 80, # CB列 "rule56": 81, # CC列 "rule57": 82, # CD列 "rule58": 83, # CE列 "rule59": 84, # CF列 "rule60": 40, # AF列 "rule61": 41, # AG列 "rule62": 43, # AI列 "rule63": 44, # AJ列 "rule64": 7, # G列 "rule65": 8, # H列 "rule66": 9, # I列 } self.HEADER_ROW = 3 # 表头固定在第三行 self.DATA_START_ROW = 4 # 数据从第四行开始 def get_cell_color_status(self, cell, column_name=None): """ 获取单元格的颜色状态(增强版) 返回: (颜色名称, 颜色HEX值, 是否无填充) column_name: 列名,用于确定是否进行特殊颜色判断 """ # 检查是否有填充 has_fill = self.color_detector.has_fill(cell) # 获取颜色HEX值(如果有填充) hex_color = self.color_detector.get_cell_color_hex(cell) if has_fill else None # 处理无填充情况 if not has_fill: return "无填充", None, True # 处理M列特殊颜色判断 if column_name == "变更内容": # 假设M列是"变更内容" # 检查是否为特殊颜色 if hex_color in self.hex_to_name: color_name = self.hex_to_name[hex_color] return color_name, hex_color, False # 其他颜色视为普通填充 return "普通填充", hex_color, False # 其他列处理 return "普通填充", hex_color, False def _create_keyword_pattern(self): """创建关键词匹配的正则表达式模式""" # 转义特殊字符并创建模式 escaped_keywords = [re.escape(kw) for kw in self.keywords] # 创建不区分大小写的模式 pattern_str = "|".join(escaped_keywords) return re.compile(pattern_str, re.IGNORECASE) def contains_keyword(self, text): """ 使用正则表达式检查文本是否包含任意关键词(更健壮的匹配) 返回: 匹配结果和匹配到的关键词列表 """ if not text: return False, [] text = str(text).strip() matches = self.keyword_pattern.findall(text) return bool(matches), matches def split_note_values(self, note_value): """拆分备注值,支持多种分隔符""" if not note_value: return [] # 支持的分隔符:中文顿号、全角逗号、半角逗号、分号、空格 separators = ['、', ',', ',', ';', ';', ' '] # 替换所有分隔符为统一的分隔符 normalized = str(note_value) for sep in separators: normalized = normalized.replace(sep, '|') # 分割并过滤空值 values = [v.strip() for v in normalized.split('|') if v.strip()] # 过滤掉值为“-”的项 values = [v for v in values if v != "-"] return values def format_note_stats(self, data_dict): """格式化备注统计结果,确保每个值一行""" try: # 尝试按数值排序 sorted_items = sorted( data_dict.items(), key=lambda x: int(x[0]) if x[0].isdigit() else x[0] ) except Exception: # 如果无法转换为数字,则按字符串排序 sorted_items = sorted(data_dict.items()) # 格式化为每行一个值 return "\n".join([f"{value},{count}" for value, count in sorted_items]) def create_column_letter_map(self): """创建列号到列字母的映射""" column_letter_map = {} # 生成A-Z列 for i in range(1, 27): column_letter_map[i] = chr(64 + i) # 生成AA-AZ列 for i in range(1, 27): column_letter_map[26 + i] = f"A{chr(64 + i)}" # 生成BA-BZ列 for i in range(1, 27): column_letter_map[52 + i] = f"B{chr(64 + i)}" # 生成CA-CZ列 for i in range(1, 27): column_letter_map[78 + i] = f"C{chr(64 + i)}" # 添加已知的特殊列 column_letter_map.update({ 16: "P", 23: "W", 27: "AA", 30: "AD", 34: "AH", 37: "AK", 42: "AP", 45: "AS", 50: "AX", 53: "BA", 57: "BE", 60: "BH", 62: "BL", 65: "BO", 71: "BS", 74: "BV", 78: "BZ", 85: "CG" }) return column_letter_map def log_cell_value_counts(self, rule_name, cell_stats): """记录规则对应的每个单元格值的计数""" total_count = sum(cell_stats.values()) self.logger.info(f"{rule_name}: 详细单元格统计 (共 {total_count} 个单元格)") # 按计数值降序排序 sorted_items = sorted(cell_stats.items(), key=lambda x: x[1], reverse=True) # 记录每个值的计数 for value, count in sorted_items: # 处理空值 display_value = "(空)" if value is None or value == "" else value self.logger.info(f" - {display_value}: {count} 次") # 记录唯一值计数 unique_values = len(cell_stats) self.logger.info(f" 共 {unique_values} 个唯一值") def process_file(self, file_path): """ 处理单个SCL文件并返回所有统计结果 返回: (results, color_report) - results: 规则统计结果 - color_report: 颜色分析报告 """ results = {} missing_data = [] # 存储缺失数据信息 try: self.logger.info(f"开始处理SCL文件: {file_path}") # 加载SCL文件 scl_wb = openpyxl.load_workbook(file_path) scl_sheet = scl_wb.active self.logger.info(f"工作表加载成功: {scl_sheet.title}, 总行数: {scl_sheet.max_row}") # 检查是否有足够的数据行 if scl_sheet.max_row < self.DATA_START_ROW: self.logger.info("文件没有数据行,跳过处理") return results, "", missing_data # 初始化统计结果 stats = { # 规则1-18: 备注值统计 "diff_no_fill": defaultdict(int), # 规则1: 変更内容无颜色填充 "diff_fill": defaultdict(int), # 规则2: 変更内容有颜色填充 "diff_add_no_fill": defaultdict(int), # 规则3: 差分种别="追加"且无颜色填充 "diff_add_fill": defaultdict(int), # 规则4: 差分种别="追加"且有颜色填充 "diff_change_no_fill": defaultdict(int), # 规则5: 差分种别="変更"且无颜色填充 "diff_change_fill": defaultdict(int), # 规则6: 差分种别="変更"且有颜色填充 "diff_delete_no_fill": defaultdict(int), # 规则7: 差分种别="削除"且无颜色填充 "diff_delete_fill": defaultdict(int), # 规则8: 差分种别="削除"且有颜色填充 "valid_yes_no_fill": defaultdict(int), # 规则9: 判断="有意"且无颜色填充 "valid_yes_fill": defaultdict(int), # 规则10: 判断="有意"且有颜色填充 "valid_no_no_fill": defaultdict(int), # 规则11: 判断="無効"且无颜色填充 "valid_no_fill": defaultdict(int), # 规则12: 判断="無効"且有颜色填充 "valid_yes_reason_no_fill": defaultdict(int), # 规则13: 判断="有意"且理由无颜色填充 "valid_yes_reason_fill": defaultdict(int), # 规则14: 判断="有意"且理由有颜色填充 "valid_no_reason_no_fill": defaultdict(int), # 规则15: 判断="無効"且理由无颜色填充 "valid_no_reason_fill": defaultdict(int), # 规则16: 判断="無効"且理由有颜色填充 "background_no_fill": defaultdict(int), # 规则17: 背景无颜色填充 "background_fill": defaultdict(int), # 规则18: 背景有颜色填充, # 规则19-59: 计数统计 "rule19": 0, # 规则19: 包含关键词且无颜色填充 "rule20": 0, # 规则20: 不包含关键词且无颜色填充 "rule21": 0, # 规则21: 包含关键词且猩红填充 "rule22": 0, # 规则22: 不包含关键词且猩红填充 "rule23": 0, # 规则23: 包含关键词且钢蓝填充 "rule24": 0, # 规则24: 不包含关键词且钢蓝填充 "rule25": 0, # 规则25: 包含关键词且巧克力黄填充 "rule26": 0, # 规则26: 不包含关键词且巧克力黄填充 "rule27": 0, # L列="追加"且无颜色填充且M列包含关键词 "rule28": 0, # L列="追加"且无颜色填充且M列不包含关键词 "rule29": 0, # L列="追加"且有颜色填充且M列包含关键词 "rule30": 0, # L列="追加"且有颜色填充且M列不包含关键词 "rule31": 0, # L列="変更"且无颜色填充且M列包含关键词 "rule32": 0, # L列="変更"且无颜色填充且M列不包含关键词 "rule33": 0, # L列="変更"且有颜色填充且M列包含关键词 "rule34": 0, # L列="変更"且有颜色填充且M列不包含关键词 "rule35": 0, # L列="差分無し"的计数 "rule36": 0, # N列="有意"且无颜色填充且M列包含关键词 "rule37": 0, # N列="有意"且无颜色填充且M列不包含关键词 "rule38": 0, # N列="有意"且有颜色填充且M列包含关键词 "rule39": 0, # N列="有意"且有颜色填充且M列不包含关键词 "rule40": 0, # N列="無効"且无颜色填充且M列包含关键词 "rule41": 0, # N列="無効"且无颜色填充且M列不包含关键词 "rule42": 0, # N列="無効"且有颜色填充且M列包含关键词 "rule43": 0, # N列="無効"且有颜色填充且M列不包含关键词 "rule44": 0, # N列="有意"且O列无颜色填充且M列包含关键词 "rule45": 0, # N列="有意"且O列无颜色填充且M列不包含关键词 "rule46": 0, # N列="有意"且O列有颜色填充且M列包含关键词 "rule47": 0, # N列="有意"且O列有颜色填充且M列不包含关键词 "rule48": 0, # N列="無効"且O列无颜色填充且M列包含关键词 "rule49": 0, # N列="無効"且O列无颜色填充且M列不包含关键词 "rule50": 0, # N列="無効"且O列有颜色填充且M列包含关键词 "rule51": 0, # N列="無効"且O列有颜色填充且M列不包含关键词 "rule52": 0, # P列无颜色填充且M列包含关键词 "rule53": 0, # P列无颜色填充且M列不包含关键词 "rule54": 0, # 0 "rule55": 0, # 0 "rule56": 0, # P列有颜色且M列包含关键词 "rule57": 0, # P列有颜色且M列不包含关键词 "rule58": 0, # 0 "rule59": 0, # 0 "rule60": 0, # L列="削除"且无颜色填充且M列包含关键词 "rule61": 0, # L列="削除"且无颜色填充且M列不包含关键词 "rule62": 0, # L列="削除"且有颜色填充且M列包含关键词 "rule63": 0, # L列="削除"且有颜色填充且M列不包含关键词 "rule64": 0, # M列有内容 "rule65": 0, # N列="有意" "rule66": 0, # 0 } all_notes_empty = True # 新增:标记整列备注是否全为空 # 遍历所有数据行 for row_idx in range(self.DATA_START_ROW, scl_sheet.max_row + 1): # 获取所有需要的单元格 diff_content_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["变更内容"]) diff_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["差分種別"]) note_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["备注"]) valid_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["判断列"]) reason_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["判断理由"]) background_cell = scl_sheet.cell(row_idx, self.COLUMN_MAPPING["变更背景"]) # 获取单元格值 diff_value = str(diff_cell.value).strip() if diff_cell.value else "" note_value = str(note_cell.value).strip() if note_cell.value else "" valid_value = str(valid_cell.value).strip() if valid_cell.value else "" # 获取备注值并处理多值情况 note_values = self.split_note_values(note_value) # 获取M列值 m_value = str(diff_content_cell.value) if diff_content_cell.value else "" # 检查是否包含关键词(使用增强版匹配) contains_keyword, matched_keywords = self.contains_keyword(m_value) # 记录匹配结果(调试用) if contains_keyword: self.logger.debug(f"行 {row_idx} 匹配到关键词: {', '.join(matched_keywords)}") else: self.logger.debug(f"行 {row_idx} 未匹配到关键词") # 获取单元格颜色状态 l_color_name, l_color_hex, l_no_fill = self.get_cell_color_status(diff_cell) m_color_name, m_color_hex, m_no_fill = self.get_cell_color_status(diff_content_cell) n_color_name, n_color_hex, n_no_fill = self.get_cell_color_status(valid_cell) o_color_name, o_color_hex, o_no_fill = self.get_cell_color_status(reason_cell) p_color_name, p_color_hex, p_no_fill = self.get_cell_color_status(background_cell) # 检查备注列是否有数据 if note_value: all_notes_empty = False # 规则1-18处理 # 规则1: 変更内容无颜色填充 if m_no_fill and note_values: for nv in note_values: stats["diff_no_fill"][nv] += 1 # 记录到规则统计 # 规则2: 変更内容有颜色填充 if not m_no_fill and note_values: for nv in note_values: stats["diff_fill"][nv] += 1 # 规则3: 差分种别="追加"且无颜色填充 if diff_value == "追加" and l_no_fill and note_values: for nv in note_values: stats["diff_add_no_fill"][nv] += 1 # 规则4: 差分种别="追加"且有颜色填充 if diff_value == "追加" and not l_no_fill and note_values: for nv in note_values: stats["diff_add_fill"][nv] += 1 # 规则5: 差分种别="変更"且无颜色填充 if diff_value == "変更" and l_no_fill and note_values: for nv in note_values: stats["diff_change_no_fill"][nv] += 1 # 规则6: 差分种别="変更"且有颜色填充 if diff_value == "変更" and not l_no_fill and note_values: for nv in note_values: stats["diff_change_fill"][nv] += 1 # 规则7: 差分种别="削除"且无颜色填充 if diff_value == "削除" and l_no_fill and note_values: for nv in note_values: stats["diff_delete_no_fill"][nv] += 1 # 规则8: 差分种别="削除"且有颜色填充 if diff_value == "削除" and not l_no_fill and note_values: for nv in note_values: stats["diff_delete_fill"][nv] += 1 # 规则9: 判断="有意"且无颜色填充 if valid_value == "有意" and n_no_fill and note_values: for nv in note_values: stats["valid_yes_no_fill"][nv] += 1 # 规则10: 判断="有意"且有颜色填充 if valid_value == "有意" and not n_no_fill and note_values: for nv in note_values: stats["valid_yes_fill"][nv] += 1 # 规则11: 判断="無効"且无颜色填充 if valid_value == "無効" and n_no_fill and note_values: for nv in note_values: stats["valid_no_no_fill"][nv] += 1 # 规则12: 判断="無効"且有颜色填充 if valid_value == "無効" and not n_no_fill and note_values: for nv in note_values: stats["valid_no_fill"][nv] += 1 # 规则13: 判断="有意"且理由无颜色填充 if valid_value == "有意" and o_no_fill and note_values: for nv in note_values: stats["valid_yes_reason_no_fill"][nv] += 1 # 规则14: 判断="有意"且理由有颜色填充 if valid_value == "有意" and not o_no_fill and note_values: for nv in note_values: stats["valid_yes_reason_fill"][nv] += 1 # 规则15: 判断="無効"且理由无颜色填充 if valid_value == "無効" and o_no_fill and note_values: for nv in note_values: stats["valid_no_reason_no_fill"][nv] += 1 # 规则16: 判断="無効"且理由有颜色填充 if valid_value == "無効" and not o_no_fill and note_values: for nv in note_values: stats["valid_no_reason_fill"][nv] += 1 # 规则17: 背景无颜色填充 if p_no_fill and note_values: for nv in note_values: stats["background_no_fill"][nv] += 1 # 规则18: 背景有颜色填充 if not p_no_fill and note_values: for nv in note_values: stats["background_fill"][nv] += 1 # 规则19-59处理 # 规则19: 包含关键词且无颜色填充 if contains_keyword and m_no_fill: stats["rule19"] += 1 # 规则20: 不包含关键词且无颜色填充 if not contains_keyword and m_no_fill: stats["rule20"] += 1 # 规则21: 包含关键词且猩红填充 if contains_keyword and m_color_name == "猩红": stats["rule21"] += 1 # 规则22: 不包含关键词且猩红填充 if not contains_keyword and m_color_name == "猩红": stats["rule22"] += 1 # 规则23: 包含关键词且钢蓝填充 if contains_keyword and m_color_name == "钢蓝": stats["rule23"] += 1 # 规则24: 不包含关键词且钢蓝填充 if not contains_keyword and m_color_name == "钢蓝": stats["rule24"] += 1 # 规则25: 包含关键词且巧克力黄填充 if contains_keyword and m_color_name == "巧克力黄": stats["rule25"] += 1 # 规则26: 不包含关键词且巧克力黄填充 if not contains_keyword and m_color_name == "巧克力黄": stats["rule26"] += 1 # 规则27: L列="追加"且无颜色填充且M列包含关键词 if diff_value == "追加" and l_no_fill and contains_keyword: stats["rule27"] += 1 # 规则28: L列="追加"且无颜色填充且M列不包含关键词 if diff_value == "追加" and l_no_fill and not contains_keyword: stats["rule28"] += 1 # 规则29: L列="追加"且有颜色填充且M列包含关键词 if diff_value == "追加" and not l_no_fill and contains_keyword: stats["rule29"] += 1 # 规则30: L列="追加"且有颜色填充且M列不包含关键词 if diff_value == "追加" and not l_no_fill and not contains_keyword: stats["rule30"] += 1 # 规则31: L列="変更"且无颜色填充且M列包含关键词 if diff_value == "変更" and l_no_fill and contains_keyword: stats["rule31"] += 1 # 规则32: L列="変更"且无颜色填充且M列不包含关键词 if diff_value == "変更" and l_no_fill and not contains_keyword: stats["rule32"] += 1 # 规则33: L列="変更"且有颜色填充且M列包含关键词 if diff_value == "変更" and not l_no_fill and contains_keyword: stats["rule33"] += 1 # 规则34: L列="変更"且有颜色填充且M列不包含关键词 if diff_value == "変更" and not l_no_fill and not contains_keyword: stats["rule34"] += 1 # 规则35: L列="差分無し"的计数 if diff_value == "差分無し": stats["rule35"] += 1 # 规则36: N列="有意"且无颜色填充且M列包含关键词 if valid_value == "有意" and n_no_fill and contains_keyword: stats["rule36"] += 1 # 规则37: N列="有意"且无颜色填充且M列不包含关键词 if valid_value == "有意" and n_no_fill and not contains_keyword: stats["rule37"] += 1 # 规则38: N列="有意"且有颜色填充且M列包含关键词 if valid_value == "有意" and not n_no_fill and contains_keyword: stats["rule38"] += 1 # 规则39: N列="有意"且有颜色填充且M列不包含关键词 if valid_value == "有意" and not n_no_fill and not contains_keyword: stats["rule39"] += 1 # 规则40: N列="無効"且无颜色填充且M列包含关键词 if valid_value == "無効" and n_no_fill and contains_keyword: stats["rule40"] += 1 # 规则41: N列="無効"且无颜色填充且M列不包含关键词 if valid_value == "無効" and n_no_fill and not contains_keyword: stats["rule41"] += 1 # 规则42: N列="無効"且有颜色填充且M列包含关键词 if valid_value == "無効" and not n_no_fill and contains_keyword: stats["rule42"] += 1 # 规则43: N列="無効"且有颜色填充且M列不包含关键词 if valid_value == "無効" and not n_no_fill and not contains_keyword: stats["rule43"] += 1 # 规则44: N列="有意"且O列无颜色填充且M列包含关键词 if valid_value == "有意" and o_no_fill and contains_keyword: stats["rule44"] += 1 # 规则45: N列="有意"且O列无颜色填充且M列不包含关键词 if valid_value == "有意" and o_no_fill and not contains_keyword: stats["rule45"] += 1 # 规则46: N列="有意"且O列有颜色填充且M列包含关键词 if valid_value == "有意" and not o_no_fill and contains_keyword: stats["rule46"] += 1 # 规则47: N列="有意"且O列有颜色填充且M列不包含关键词 if valid_value == "有意" and not o_no_fill and not contains_keyword: stats["rule47"] += 1 # 规则48: N列="無効"且O列无颜色填充且M列包含关键词 if valid_value == "無効" and o_no_fill and contains_keyword: stats["rule48"] += 1 # 规则49: N列="無効"且O列无颜色填充且M列不包含关键词 if valid_value == "無効" and o_no_fill and not contains_keyword: stats["rule49"] += 1 # 规则50: N列="無効"且O列有颜色填充且M列包含关键词 if valid_value == "無効" and not o_no_fill and contains_keyword: stats["rule50"] += 1 # 规则51: N列="無効"且O列有颜色填充且M列不包含关键词 if valid_value == "無効" and not o_no_fill and not contains_keyword: stats["rule51"] += 1 # 规则52: P列无颜色填充且M列包含关键词 if p_no_fill and contains_keyword: stats["rule52"] += 1 # 规则53: P列无颜色填充且M列不包含关键词 if p_no_fill and not contains_keyword: stats["rule53"] += 1 # 规则54: P列颜色为猩红且M列包含关键词 stats["rule54"] = 0 # 规则55: P列颜色为猩红且M列不包含关键词 stats["rule55"] = 0 # 规则56: P列颜色为钢蓝且M列包含关键词 if not p_no_fill and contains_keyword: stats["rule56"] += 1 # 规则57: P列颜色为钢蓝且M列不包含关键词 if not p_no_fill and not contains_keyword: stats["rule57"] += 1 # 规则58: P列颜色为巧克力黄且M列包含关键词 stats["rule58"] = 0 # 规则59: P列颜色为巧克力黄且M列不包含关键词 stats["rule59"] = 0 # 规则60: L列="削除"且无颜色填充且M列包含关键词 if diff_value == "削除" and l_no_fill and contains_keyword: stats["rule60"] += 1 # 规则61: L列="変更"且无颜色填充且M列不包含关键词 if diff_value == "削除" and l_no_fill and not contains_keyword: stats["rule61"] += 1 # 规则62: L列="削除"且有颜色填充且M列包含关键词 if diff_value == "削除" and not l_no_fill and contains_keyword: stats["rule62"] += 1 # 规则63: L列="削除"且有颜色填充且M列不包含关键词 if diff_value == "削除" and not l_no_fill and not contains_keyword: stats["rule63"] += 1 # 规则64: L列="変更"且无颜色填充且M列不包含关键词 if m_value : stats["rule64"] += 1 # 规则65: L列="削除"且有颜色填充且M列包含关键词 if valid_value == "有意": stats["rule65"] += 1 # 规则66: L列="削除"且有颜色填充且M列不包含关键词 stats["rule66"] = 0 # 处理统计结果 for rule, data in stats.items(): # 对于规则1-18,输出备注值及其出现次数 if rule in ["diff_no_fill", "diff_fill", "diff_add_no_fill", "diff_add_fill", "diff_change_no_fill", "diff_change_fill", "diff_delete_no_fill", "diff_delete_fill", "valid_yes_no_fill", "valid_yes_fill", "valid_no_no_fill", "valid_no_fill", "valid_yes_reason_no_fill", "valid_yes_reason_fill", "valid_no_reason_no_fill", "valid_no_reason_fill", "background_no_fill", "background_fill"]: # 新增功能:如果备注列全为空,不填入任何数据 if all_notes_empty: self.logger.info(f"{rule}: 备注列全为空,不填入数据") continue # 检查是否有数据 if not data: # 字典为空 results[rule] = "/" self.logger.info(f"{rule}: 无数据,输出 '/'") continue # 格式化备注统计结果 results[rule] = self.format_note_stats(data) self.log_cell_value_counts(rule, data) # 优化日志输出:分行显示 self.logger.info(f"{rule}: 结果:") for line in results[rule].split('\n'): self.logger.info(f" {line}") else: # 对于规则19-59,直接输出计数值 results[rule] = data self.logger.info(f"{rule}: 结果 {results[rule]}") # 生成颜色报告 color_report = self.color_detector.generate_color_report() self.logger.info("\n" + color_report) return results, color_report, missing_data except Exception as e: error_msg = f"处理SCL文件失败: {str(e)}" logger.exception(f"处理SCL文件失败: {file_path} - {str(e)}") # 返回错误信息 return {rule: f"错误: {str(e)}" for rule in self.RULE_MAPPING}, f"错误: {error_msg}", [{ 'row': 0, 'col': 0, 'col_name': '错误', 'message': error_msg }] 怎么用新的颜色检测类
最新发布
08-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值