You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求协助完善Waiver系统:实现错误文件与waiver.csv的匹配逻辑

需求说明

需要为工作场景构建一套Waiver系统,使用提供的waiver.csv文件。错误信息已输出至input.txt文件中,需将input.txt内的每条错误与waiver.csv按stage、process、block三个维度进行匹配,并生成指定格式的输出。现有一段Perl代码片段,需完善错误文件与waiver.csv的匹配逻辑。

waiver.csv示例

#process,#Block,#Stage name,#Waiver owner,#Justification,#Error msg
process1,block1,stage1,Alex,testing,Error: Port 0 does not exist
process1,block1,stage1,Alex,testing,Error: Port 1 does not exist
process1,block1,stage1,Alex,testing,Error: Port a0 does not exist

错误文件input.txt示例

Stage: stage1
Process: process1
Block: block1

Error: Port 0 does not exist
Error: Port 1 does not exist
Error: Port a0 does not exist
Error: Port a1 does not exist
Error: Port b3 does not exist
Error: Nothing matched for port_list (SEL-005)
Error: Nothing matched for port_list (SEL-005)
Error: Port c5 does not exist
Error: Nothing matched for port_list (SEL-005)
Error: Nothing matched for port_list (SEL-005)

预期输出

WAIVED (3 waiver, 0 errors) - stage1,process1,block1:
    Error: Port 0 does not exist
    Error: Port 1 does not exist
    Error: Port a0 does not exist
    Waiver Owner: Alex
    Justification: testing

FAILED (No waiver, 4 errors) - stage1,process1,block1:
    Error: Nothing matched for port_list (SEL-005)
    Error: Port a1 does not exist
    Error: Port b3 does not exist
    Error: Port c5 does not exist

现有Perl代码片段

#!/usr/bin/perl

use strict;
use warnings;
use Text::CSV;

# Define the file paths
my $input_file = 'input.txt';
my $waiver_file = 'waiver.csv';

# Read the waiver.csv file
my @waiver_msgs;
my $csv = Text::CSV->new({ binary => 1 }) or die "Cannot use CSV: " . Text::CSV->error_diag();
open(my $waiver_fh, '<', $waiver_file) or die "Cannot open $waiver_file: $!";
while (my $row = $csv->getline($waiver_fh)) {
    push @waiver_msgs, $row->[5];  # Assuming error messages are in the 6th column (index 5)
}
close($waiver_fh);

# Read the input.txt file
open(my $input_fh, '<', $input_file) or die "Cannot open $input_file: $!";
while (my $line = <$input_fh>) {
    chomp $line;
    if ($line =~ /^Error: (.+)$/) {
        my $error_msg = $1;
        print "$error_msg\n";
        if (grep { $_ eq $error_msg } @waiver_msgs) {
            print "Error message '$error_msg' is waived.\n";
        } else {
            print "Error message '$error_msg' is not waived.\n";
        }
    }
}
close($input_fh);

完善后的Perl代码

现有代码仅匹配了错误消息,未考虑stage/process/block的维度匹配,以下是修复后的完整代码:

#!/usr/bin/perl

use strict;
use warnings;
use Text::CSV;

# Define file paths
my $input_file = 'input.txt';
my $waiver_file = 'waiver.csv';

# 构建waiver数据结构:{ "stage|process|block" => { errors => {msg=>1}, owner=>'', justification=>'' } }
my %waiver_data;
my $csv = Text::CSV->new({ binary => 1 }) or die "Cannot use CSV: " . Text::CSV->error_diag();
open(my $waiver_fh, '<', $waiver_file) or die "Cannot open $waiver_file: $!";

# 跳过表头
my $header = $csv->getline($waiver_fh);
while (my $row = $csv->getline($waiver_fh)) {
    my ($process, $block, $stage, $owner, $justification, $error_msg) = @$row;
    my $key = "$stage|$process|$block";
    
    # 初始化分组数据
    unless (exists $waiver_data{$key}) {
        $waiver_data{$key} = {
            errors => {},
            owner => $owner,
            justification => $justification
        };
    }
    # 标记该错误已豁免
    $waiver_data{$key}{errors}{$error_msg} = 1;
}
close($waiver_fh);

# 读取input.txt,提取上下文和错误信息
my ($current_stage, $current_process, $current_block);
my @current_errors;

open(my $input_fh, '<', $input_file) or die "Cannot open $input_file: $!";
while (my $line = <$input_fh>) {
    chomp $line;
    next if $line =~ /^\s*$/; # 跳过空行
    
    if ($line =~ /^Stage: (.+)$/) {
        $current_stage = $1;
    } elsif ($line =~ /^Process: (.+)$/) {
        $current_process = $1;
    } elsif ($line =~ /^Block: (.+)$/) {
        $current_block = $1;
    } elsif ($line =~ /^Error: .+$/) {
        push @current_errors, $line;
    }
}
close($input_fh);

# 生成输出
my $context_key = "$current_stage|$current_process|$current_block";
my $context_label = "$current_stage,$current_process,$current_block";

# 处理豁免的错误
my @waived_errors;
my @failed_errors;

if (exists $waiver_data{$context_key}) {
    my $waiver = $waiver_data{$context_key};
    foreach my $err (@current_errors) {
        if (exists $waiver->{errors}{$err}) {
            push @waived_errors, $err;
        } else {
            push @failed_errors, $err;
        }
    }
} else {
    @failed_errors = @current_errors;
}

# 去重失败的错误(因为示例中有重复的SEL-005错误)
my %unique_failed = map { $_ => 1 } @failed_errors;
@failed_errors = sort keys %unique_failed;

# 输出WAIVED部分
if (@waived_errors) {
    my $waiver_count = scalar @waived_errors;
    print "WAIVED ($waiver_count waiver, 0 errors) - $context_label:\n";
    foreach my $err (@waived_errors) {
        print "    $err\n";
    }
    if (exists $waiver_data{$context_key}) {
        print "    Waiver Owner: $waiver_data{$context_key}{owner}\n";
        print "    Justification: $waiver_data{$context_key}{justification}\n";
    }
    print "\n";
}

# 输出FAILED部分
if (@failed_errors) {
    my $error_count = scalar @failed_errors;
    my $waiver_note = @waived_errors ? "No new waiver" : "No waiver";
    print "FAILED ($waiver_note, $error_count errors) - $context_label:\n";
    foreach my $err (@failed_errors) {
        print "    $err\n";
    }
}

代码说明

  1. 数据结构优化:将waiver数据按stage|process|block的复合键分组,每个分组存储豁免的错误集合、负责人和理由,确保维度匹配准确。
  2. 上下文提取:读取input.txt时先提取当前的stage、process、block信息,再收集所有错误。
  3. 错误匹配:根据当前上下文找到对应的豁免规则,将错误分为豁免和未豁免两类。
  4. 去重处理:对未豁免的错误进行去重,符合预期输出的格式。
  5. 格式输出:严格按照预期的格式输出结果,包含豁免数量、错误数量、上下文标签、错误列表及豁免信息。

内容的提问来源于stack exchange,提问作者user22081427

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:27:02