zbparse/flask_app/test_case/test_extract_matching_keys.py

242 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
from flask_app.货物标.技术参数要求提取后处理函数 import extract_matching_keys
import re
from collections import defaultdict
#12.27之前版本
# def extract_matching_keys(data, good_list, special_keys=None, parent_key=''):
# def get_suffix(n):
# """
# 根据数字n返回对应的字母后缀。
# 1 -> 'a', 2 -> 'b', ..., 26 -> 'z', 27 -> 'aa', 28 -> 'ab', ...
# """
# suffix = ''
# while n > 0:
# n, r = divmod(n - 1, 26)
# suffix = chr(97 + r) + suffix
# return suffix
#
# def count_matching_keys(data, patterns, special_keys, counter=None):
# """递归统计匹配键的出现次数,仅统计值为列表的键"""
# if counter is None:
# counter = defaultdict(int)
#
# if isinstance(data, dict):
# for key, value in data.items():
# clean_key = key.replace(" ", "") # 去除键中的空格
# if isinstance(value, list):
# if clean_key not in special_keys and any(pattern.match(clean_key) for pattern in patterns):
# counter[clean_key] += 1
# elif isinstance(value, dict):
# count_matching_keys(value, patterns, special_keys, counter)
# elif isinstance(data, list):
# for item in data:
# if isinstance(item, (dict, list)):
# count_matching_keys(item, patterns, special_keys, counter)
#
# return counter
#
# def process_data(data, patterns, special_keys, key_counter, suffix_map, filtered_data, parent_key):
# """递归处理数据并构建结果"""
#
# def get_suffix_label(key):
# suffix_map[key] += 1
# return get_suffix(suffix_map[key])
#
# if isinstance(data, dict):
# for key, value in data.items():
# clean_key = key.replace(" ", "") # 去除键中的空格
# if isinstance(value, list):
# # 处理值为列表的键
# if any(pattern.match(clean_key) for pattern in patterns):
# # 检查是否以特殊符号开头
# if clean_key.startswith(('▲', '★','●','■','◆','☆','△','◇','○','□')):
# symbol = clean_key[0]
# stripped_key = clean_key[1:]
# new_key = generate_key(stripped_key, parent_key, key_counter, suffix_map, special_keys)
# # 将符号添加到每个字符串的开头
# new_value = [symbol + item for item in value]
# filtered_data[new_key] = new_value
# else:
# new_key = generate_key(clean_key, parent_key, key_counter, suffix_map, special_keys)
# filtered_data[new_key] = value
# elif isinstance(value, dict):
# # 继续递归处理嵌套字典
# new_parent_key = clean_key if parent_key == '' else f"{parent_key}的{clean_key}"
# process_data(value, patterns, special_keys, key_counter, suffix_map,
# filtered_data, new_parent_key)
# elif isinstance(data, list):
# for item in data:
# if isinstance(item, (dict, list)):
# process_data(item, patterns, special_keys, key_counter, suffix_map,
# filtered_data, parent_key)
#
# def generate_key(key, parent_key, key_counter, suffix_map, special_keys):
# """生成新的键名"""
# if key in special_keys and parent_key:
# return f"{parent_key}的{key}"
# elif key_counter[key] > 1:
# suffix = get_suffix(suffix_map[key] + 1)
# suffix_map[key] += 1
# return f"{key}-{suffix}"
# return key
#
# if special_keys is None:
# special_keys = ["系统功能"] # 默认值为 ["系统功能"]
#
# # 去除 good_list 中的空格
# clean_good_list = [g.replace(" ", "") for g in good_list]
#
# # 构建匹配的正则表达式
# patterns = [re.compile(r'^' + re.escape(g) + r'(?:-\d+)?$') for g in clean_good_list]
#
# # 先统计所有匹配键的出现次数,仅统计值为列表的键
# key_counter = count_matching_keys(data, patterns, special_keys)
#
# # 初始化后缀映射
# suffix_map = {key: 0 for key, count in key_counter.items() if count > 1}
#
# # 用于存储最终结果
# filtered_data = {}
#
# # 递归处理数据
# process_data(data, patterns, special_keys, key_counter, suffix_map, filtered_data, parent_key)
#
# return filtered_data
def test_extract_matching_keys():
# 定义测试数据
data = {
"采购需求": {
"显示系统": {
"系统功能":["1","2"],
"★LED全彩显示屏": [
"1、显示尺寸6m±0.3W× 1.5m±0.2(H),单屏分辨率≥3744 × 1040",
"2 、像素间距≤1.53mm",
"3 、亮度≥450nits 色温: 3000-15000K 可调, 对比度: 5000:1",
"4 、峰值功耗≤440W 平均功耗≤146W 带有智能(黑屏) 节电功 能, 开启智能节电功能比没开启节能 40%以上;",
"5 、水平可视角度≥160 ° , 垂直可视角度≥140 ° ;",
"6 、亮度均匀性≥97% 刷新率≥3840 Hz 发光点中心距偏差3%",
"7 、色域覆盖率≥100% 低亮高灰: 100%亮度时, 16 bits 灰度20% 亮度时, 12bits 灰度;",
"8 、铝底壳材质, 无风扇散热结构;",
"9 、模组电源接口采用4P 接插头, 免工具维护, 同时有防呆设计, 预防接错电源线短路而导致的烧毁模组行为,采用集成 HUB 接收卡 控制, 支持通讯状态监控;",
"10 、冗余备份, 支持双电网供电, 当其中一路交流电网跳闸后, 另 外一路电网继续供电, 实现不间断供电, 支持热备份, 当其中一块 电源失效后, 另一块电源继续工作, 从而实现不间断供电;",
"11 、屏体发光模组采用 4.5 VDC 的安全电压供电;",
"12 、彩色信号处理位数≥16bit",
"13 、具备故障自诊及排查功能;",
"14 、 图像有降噪 、增强 、运动补偿 、色坐标变换处理 、钝 化处理无 几何失真和线性失真现象 、消除鬼影拖尾, 无“毛毛虫 ”“鬼影 ” 跟随现象;",
"15 、防护等级符合 IP6X 显示屏具有防潮 、防尘 、防腐蚀 、防电磁 干扰 、防静电等功能, 并具有过流、短路 、过压 、欠压保护等功能;",
"16 、工作噪音声压等级一米处≤7.8 dB (A),盐雾符合 10 级要求, PCB 阻燃等级达到 UL 94 V-0 级要求, 通过 9 级烈度地震模拟实验。"
],
"☆钢结构底座及铝型材支架": [
"1 、主体钢架结构及定制型材;",
"2 、确保楼层承受力许可,按需加固楼层地面;",
"3 、钢结构。"
]
},
"摄像系统": {
"系统功能": ["a", "b"],
"☆钢结构底座及铝型材支架": [
"1 、主体钢架结构及定制型材wwww",
"2 、确保楼层承受力许可,按需加固楼层地面;",
"3 、钢结构。"
]
},
"视频处理系统": {
"★高清视频拼控矩阵(16*16)": [
"1 、8U 切换主箱体, 支持输入 13 槽, 输出 4.5 槽, 支持 8 路高分采集, 支持冗余电源, 标配 1 个电源模块; 本项目配置输入接 口 16 路和 1 张字幕卡, 输出接口 16 路;",
"2 、设备应为纯硬件 FPGA 架构, CrossPoint 全总线交换技术, 背板 等效带宽;",
"3 、单张板卡支持 4 通道输入或输出, 紧凑型机箱,模拟视频单板卡 支持 16 路同时输入, 单卡支持 2 种信号源任意组合;",
"4、输入输出板卡可热插拔输入板卡热插拔恢复时间 2s输出板 卡热插拔恢复时间8s",
"5 、开机时间≤10s 启动电源至输出最总画面的时间间隔;",
"6 、平均故障时间间隔 MTBF 不小于 96000 小时, 保证设备能够 稳定运行;",
"7 、最大单机背板信号处理带宽不小于 720Gbps",
"8、对各个输入通道采用纯硬件处理技术采用独享带宽方式为每个 输入通道分配带宽, 切换过程中对其他信号无影响, 实现了对输入 通道的实时处理;",
"9、支持集中采集 DVI、VGA、CVBS、HDBaseT、HDMI、SDI、YPbPr 、 光纤等 2K 信号Dual-link DVI、HDMI 1.4、DisplayPort 等 4K 信号;",
"10 、支持 DVI 、HDBaseT 、HDMI 、SDI 、光纤 、CVBS 、Ypbp r 等常见的 2K 信号输出, Dual-link DVI 、HDMI 1.4 等 4K 信号输出;",
"11、设备可实现任意一路画面的任意比例缩放、漫游、 跨屏 、叠加、 开窗;",
"12 、设备支持图像无缝实时切换功能, 无缝切换时间20 ms ",
"13 、支持场景保存及快速调用, 支持场景轮巡, 适应于不同的应用 场景;",
"14 、支持信号源预监功能, 支持浏览所有输入信号源的实时预览画 面;",
"15 、支持大屏图像回显, 可显示整面拼接墙的显示图像;",
"16 、支持设置拼接屏的拼缝补偿, 可精确到 1 个像素;",
"17 、支持 RRTA 分辨率实时全兼容技术, 单台 设备应支持同时控制 4 组不同分辨率的大屏幕显示;",
"18 、设备具备静态底图功能, 设备支持超大分辨率底图显示, 横纵 分辨率最大 65535 像素。"
],
"分量信号接口器": [
"用于现有视频会议专业对接高清矩阵接口器"
],
"高清四画面分割器": [
"画面预览使用, 具有画中画 、独立单画面放大功能。"
]
},
}
}
good_list = [
"★LED全彩显示屏",
"控制盒及电源",
"大屏播控系统",
"配电柜(含PLC)",
"☆钢结构底座及铝型材支架",
"电缆及信号线缆",
"控制终端",
"50寸液晶电视机",
"50寸电视机地面推车",
"高清监视器",
"★高清摄像机",
"摄像机三脚架",
"摄像机壁装架",
"摄像机控制键盘",
"★高清视频拼控矩阵(16*16)",
"分量信号接口器",
"高清四画面分割器",
"数字会议发言主机",
"方形短杆代表话筒",
"专用连接线缆",
"手持无线话筒",
"▲多点控制器",
"★多串口控制服务器",
"★综合会议管理调度平台",
"★高清会议终端(主会场)",
"★高清会议终端(分会场)",
"65寸电视机移动推车(9楼)",
"65寸液晶电视机(分会场)",
"控制平板及软件",
"鹅颈话筒",
"时序电源",
"多媒体地插盒",
"线材辅料",
"墙体拆除及修复",
"系统功能"
]
special_keys = ["系统功能", "dairy"] # 假设 'dairy' 也是特殊键
# 注意:根据您的函数逻辑,特殊键会被排除,且嵌套的 'fruits' 会被处理
# 这里我们需要根据函数实际行为调整预期输出
# 让我们根据函数逻辑重新定义预期输出
# 函数会生成新的键名,对于重复的 'fruits' 会添加后缀
# 'grains' 内的 'whole' 和 'whole-1' 也会被处理为 'whole-a', 'whole-b'
# 'chips' 和 'chips-1' 会被处理为 'chips-a', 'chips-b'
# 'dairy' 是特殊键,应被排除
# '系统功能' 和 '系统 功能' 是特殊键,应被排除
# 运行函数
result = extract_matching_keys(data, good_list, special_keys)
# 打印结果
print("测试用例: 提取匹配键并处理各种情况")
print("good_list:", good_list)
print("special_keys:", special_keys)
print("实际输出:", json.dumps(result,ensure_ascii=False,indent=4))
# 运行测试
if __name__ == "__main__":
test_extract_matching_keys()