dipesh777 has asked for the wisdom of the Perl Monks concerning the following question:

can anybody please let me know why this program terminates/ do not give the expected output at the end. Expected:it should call write (FAILED); and output should be FAILED for some comparisons. Hence returning 0 . But its does not write the output. the program: Its compares the given hashes in the array and prints the output of comparison on the screen
use Data::Dumper; sub my_compare { my ( $VAR1, $VAR2 ) = @_; #--------------------------------------format variables--------------- +------- my $key_name=""; my $key_value_1 =""; my $key_value_2 =""; my $var_j =""; my $var_k =""; my $matched_total =""; my $indexed =""; my $no =""; my $pass_ignored =""; my $pass_j =""; my $pass_k =""; my $fail_j =""; #--------------------------------------------------------------------- +------ my $hashref1; my $hashref2; my @array; my $result = "PASS"; my $flag = 0; my $total; my $string ="id,spam_stat_id,avg_latency,av_stat_id,max_latency, min_latency,av_virus_stat_id,creation_time,receiver_time,wall_conf +ig_id, creation_time,cpu_stat_id,start_time,is_macro,is_repairable"; print `clear`; #--------------------------------------------------------------------- +------- # Formatting start. format MY_TOP = ---------------------------------------------------------------------- +------------------------------------------------------------- Previously matched rows @##### History of matched rows ^* $matched_total $indexed Iteration: Comparing @##### with @<<<<< $var_j $var_k - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - -- No: KEY: Value[8.6]: + Value[8.7]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - -- . format STDOUT = @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<< +<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $no $key_name $key_value_1 + $key_value_2 . format MISMATCH = @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<< +<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< MISMATCH $no $key_name $key_value_1 + $key_value_2 . format UNDEF = @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<< +<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< UNDEFINED $no $key_name $key_value_1 + $key_value_2 . format IGNORED = @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<< +<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< IGNORED $no $key_name $key_value_1 + $key_value_2 . format PASS = Total keys Ignored: @##### $pass_ignored PASSED comparing for: @##### with @<<<<< row/record. $pass_j $pass_k ---------------------------------------------------------------------- +------------------------------------------------------------- . format FAIL = FAILED comparing for: @##### with all. $fail_j ---------------------------------------------------------------------- +------------------------------------------------------------- . format FAILED = FAILED for some comparisons. Hence returning 0 ---------------------------------------------------------------------- +------------------------------------------------------------- . format PASSED = PASSED ALL COMPARIONS, RETURNING 1. ---------------------------------------------------------------------- +------------------------------------------------------------- . format COMP_FAIL = Comparing Mismatched @##### with @<<<<< $var_j $var_k ---------------------------------------------------------------------- +------------------------------------------------------------- . # formatting complete #--------------------------------------------------------------------- +-------- # extract the size of two tables.$file_no1 is @array of 8.6 # and $file_no2 is @array of 8.7 my $file_no1 = scalar(@$VAR1); my $file_no2 = scalar(@$VAR2); # if number of rows in 8.6 is greater than 8.7 then do not process +. if ( $file_no1 gt $file_no2 ) { print"\nNumber of Entries in table not equal. Comparison faile +d. No further Processing for this table\n"; print "Dumping the data:\nFOR 8.6:\n"; print Dumper @$VAR1; print "\nDumping the data:\nFOR 8.7:\n"; print Dumper @$VAR2; return 0; } # if 0 records then pass. else { if ( $file_no1 eq 0 ) { print "\nPASS as both tables are empty.\n"; return 1; } print "\nNumber of entries in table are equal. Processing furt +her.\n"; print "\nTotal number of rows to compare $file_no1\n"; print "Dumping the data:\nFOR 8.6.\n"; print Dumper @$VAR1; print "\nDumping the data:\nFOR 8.7.\n"; print Dumper @$VAR2; } for ( my $j = 0 ; $j < $file_no1 ; $j++ ) { $hashref1 = @$VAR1[$j]; #get the jst row f +rom 8.6 # sort the @array in ascending order. COMP: for (my $k = 0 ;$k < $file_no2;$k++) { $total=@array; my $temp =0; $matched_total=$total; $indexed= "\("; foreach my $index (@array) { $temp=$index+0; $indexed="$indexed $temp"; $indexed="$indexed,"; } $indexed ="$indexed \)"; foreach my $mkey (@array) { if ( $mkey eq $k ) { if ($k eq $file_no1-1 ) { last COMP; } elsif($k<$file_no1-1) { $k++; } } } # Print the iteration count and comparion count. $var_j=$j+0; $var_k=$k+0; #printf("\nIteration comparing of row/record number %d wit +h %d row/ #record now\n\n",$j + 1, $k + 1 ); write (MY_TOP); my $count1 = 0; # Total number of keys in a table my $count2 = 0; # Matched + Undefined + Ingonerd values + for key my $count3 = 0; # Number of keys exactly matched # get the kth element from second @array. $hashref2 = @$VAR2[$k]; # Start of key comparison WID: # alias name foreach my $key ( keys %$hashref1 ) { $count1++; # number of keys. $no=$count1; #my $str = $key; if( $string =~ /$key/ ) { $count2++; $key_name=$key; $key_value_1=$hashref1->{$key}; $key_value_2=$hashref2->{$key}; write (IGNORED); } elsif(!defined($hashref1->{$key})|| !defined($hashref2 +->{$key})) { $count2++; $key_name=$key; if (!defined($hashref1->{$key})) { $key_value_1="undef"; } else { $key_value_1=$hashref1->{$key}; } if ( !defined($hashref2->{$key})) { $key_value_2="undef"; } else { $key_value_2=$hashref2->{$key}; + } write (UNDEF); print ""; } elsif ( $hashref1->{$key} eq $hashref2->{$key} ) { $count2++; $count3++; #write matched keys with value. $key_name=$key; $key_value_1=$hashref1->{$key}; $key_value_2=$hashref2->{$key}; write; } else { #Write mismatched keys and values. $key_name=$key; $key_value_1=$hashref1->{$key}; $key_value_2=$hashref2->{$key}; write (MISMATCH); last WID; } } # End of key comparison if ( $count1 eq $count2 ) { $result = "PASS"; push @array, $k; # Sort the array now because we pushed the value in ar +ray. my $srt; for (my $s=0;$s<@array; $s++) { for (my $r=0;$r<@array;$r++) { if ($s ne $r) { if($array[$s]<$array[$r]) { $srt=$array[$s]; $array[$s]=$array[$r]; $array[$r]=$srt; } } } } $pass_ignored= $count2 - $count3; $pass_j = $j+0; $pass_k = $k+0; write (PASS); $k = $file_no2; } else { $result = "FAIL"; write(COMP_FAIL); } } # End of k loop if ( $result eq "FAIL" ) { $flag = 1; $fail_j=$j+0; write(FAIL); print ""; } } #$k=$file_no2; # End ok J loop. if ( $flag eq 1 ) { write (FAILED); return 0; } elsif ( $result eq "PASS" ) { write (PASSED); print "\nReturning 1 Hence:PASS: "; return 1; } } my @array1= ( { 'total_dns_bl' => '0', 'total_spam_connections' => '0', 'total_gray' => '0', 'total_spam' => '0', 'avg_latency' => '672', 'total_sender_wl' => '0', 'total_connection_wl' => '0', 'total_brightmail_wl' => '0', 'total_gray_recipients' => '0', 'unique_ip_count' => '1', 'total_brightmail_bl' => '0', 'ipfreq_aggro' => undef, 'total_received_pass' => '0', 'total_noverdict' => '1', 'max_latency' => '672', 'total_ipfreqsa' => '0', 'wall_id' => '86091', 'total_connection_bl' => '0', 'total_dns_wl' => '0', 'version' => 'Conduit;$Name: smssmtp500-2006-05-15_01 $;SMSS +MTP v5.0.0;windows.x86', 'total_sender_bl' => '0', 'min_latency' => '0', 'esp_total_spam' => '0', 'total_recipients' => '1', 'total_reinsertions' => '0', 'total_suspect' => '0', 'total_messages' => '1', 'total_spam_recipients' => '0', 'total_gray_connections' => '1', 'suspect_threshold' => undef, 'spam_stat_id' => '9113553593' } ); my @array2 = ( { 'total_dns_bl' => '0', 'total_spam_connections' => '0', 'total_gray' => '0', 'total_spam' => '0', 'avg_latency' => '672', 'total_sender_wl' => '0', 'total_connection_wl' => '0', 'total_brightmail_wl' => '0', 'total_gray_recipients' => '0', 'unique_ip_count' => '1', 'total_brightmail_bl' => '0', 'ipfreq_aggro' => undef, 'total_received_pass' => '0', 'total_noverdict' => '1', 'max_latency' => '672', 'total_ipfreqsa' => '0', 'wall_id' => '86091', 'total_connection_bl' => '0', 'total_dns_wl' => '0', 'version' => 'Conduit;$Name: smssmtp500-2006-05-15_01 $;SMSS +MTP v5.0.0;windows.x86', 'total_sender_bl' => '0', 'min_latency' => '672', 'esp_total_spam' => '0', 'total_recipients' => '1', 'total_reinsertions' => '0', 'total_suspect' => '0', 'total_messages' => '1', 'total_spam_recipients' => '0', 'total_gray_connections' => '0', 'suspect_threshold' => undef, 'spam_stat_id' => '9113553804' } ); $my_var1 = \@array1; $my_var2 = \@array2; if (my_compare($my_var1,$my_var2)) { } else { print "\nSTILL SOMETHING HAVE TO DO\n"; }

Replies are listed 'Best First'.
Re: Unexpected output for given program with write function
by GrandFather (Saint) on Jun 10, 2011 at 12:12 UTC

    Generally it helps to whittle your code down to just enough code and data to demonstrate your issue. Of course most of the time when you do that you find the problem yourself, but that really shouldn't prevent you from trying.

    I suspect your lines of the form:

    write (MY_TOP);

    should look like:

    $~ = 'MY_TOP'; write;
    True laziness is hard work

      You can also use it like the first form in a secure way with a twist:

      sub wryte { local $~ = shift; write; } wryte "MY_TOP";

      Enjoy, Have FUN! H.Merijn
      Worked very well. Thanks.
Re: Unexpected output for given program with write function
by ww (Archbishop) on Jun 10, 2011 at 12:35 UTC
    I think you'll do better with a post that requires a lot less code. Asking strangers -- even kindly ones like (some of) the Monks -- to scrub 400 lines of code is a bit much.

    OTOH, in the spirit of Charity (it seems to be paying its decennial visit) and despite the fact this isn't the root of your problem, use strict; use warnings would tell you that:

    Use of comma-less variable list is deprecated at F:\_wo\_perl\pl_test\ +909098.pl line 43. ... Use of comma-less variable list is deprecated at F:\_wo\_perl\pl_test\ +909098.pl line 101.

    I'm running 5.12, and too lazy to check the delta to see when the deprecation began, so maybe your perl won't produce that series, but you should check, anyway.

    And, though again not the cause of your problem, $my_var1 and $my_var2 are not declared before use in the 390s (Note: my line numbers are offset from your by about 5 or 6).

    And -- Charity not yet satisfied (well, neither am I) and still urging kindness -- the construct at your 391 - 394 is a tad suspect; an if with ONLY an else. Your script seems to arrive here with the conditional in a false value, suggesting you focus on your compare sub... but even Charity is exhausted now.

    Give her a break; if attacking the issue with debug is too hard, insert some (more) print statements to test conditions at various points in your script... and then submit a boiled down version -- 10 to 20 lines -- which illustrates the failure, assuming that hasn't illuminated your understanding.

      Thank you very much, this the first post ever i made and i am so gad that the issue is solved very quickly. i will use this forum for ever.. And also will follow your advice. Thanks once again.
Re: Unexpected output for given program with write function
by jwkrahn (Abbot) on Jun 10, 2011 at 13:36 UTC
    if ( $file_no1 gt $file_no2 )

    You are using text comparison on numbers which will not work correctly:

    $ perl -le'print "$ARGV[0] is ", $ARGV[0] gt $ARGV[1] ? "" : "NOT ", " +greater than $ARGV[1]"' 12 18 12 is NOT greater than 18 $ perl -le'print "$ARGV[0] is ", $ARGV[0] gt $ARGV[1] ? "" : "NOT ", " +greater than $ARGV[1]"' 12 10 12 is greater than 10 $ perl -le'print "$ARGV[0] is ", $ARGV[0] gt $ARGV[1] ? "" : "NOT ", " +greater than $ARGV[1]"' 7 10 7 is greater than 10

    Also wrong on these lines:

    if ( $file_no1 eq 0 ) if ( $mkey eq $k ) if ($k eq $file_no1-1 ) if ( $count1 eq $count2 ) if ( $flag eq 1 )


    $indexed= "\("; foreach my $index (@array) { $temp=$index+0; $indexed="$indexed $temp"; $indexed="$indexed,"; } $indexed ="$indexed \)";

    Or just:

    $indexed = "(" . join ", ", @array, ")";


    $hashref2 = @$VAR2[$k];

    That is correctly written as:

    $hashref2 = $VAR2->[$k];


    my $srt; for (my $s=0;$s<@array; $s++) { for (my $r=0;$r<@array;$r++) { if ($s ne $r) { if($array[$s]<$array[$r]) { $srt=$array[$s]; $array[$s]=$array[$r]; $array[$r]=$srt; } } } }

    That is usually written as:

    for my $s ( 0 .. $#array ) { for my $r ( 0 .. $#array ) { if ( $s != $r && $array[ $s ] < $array[ $r ] ) { @array[ $r, $s ] = @array[ $s, $r ]; } } }

    Or as:

    @array = sort { $a <=> $b } @array;
      Thanks, I am newbie to perl and there tricks will surely helped me. is " $hashref2 = $VAR2->$k " deprecated ? I tried to use this, but shows the warning with same, Can i use
      if ( $file_no1 eq 0 ) if ( $mkey eq $k ) if ($k eq $file_no1-1 ) if ( $count1 eq $count2 ) if ( $flag eq 1 )
      as
      if ( $file_no1 == 0 ) if ( $mkey == $k ) if ($k == $file_no1-1 ) if ( $count1 == $count2 ) if ( $flag == 1 )
      ? and how do i compare string if i want to, Thanks, Dipesh

        No $hashref2 = $VAR2->[$k]; is not deprecated, and what warning did you get?

        Perl uses different operators for comparing numbers or strings.    See perlop for details.

        Also, I was thinking about this code in your program:

        push @array, $k; # Sort the array now because we pushed the value in ar +ray. my $srt; for (my $s=0;$s<@array; $s++) { for (my $r=0;$r<@array;$r++) { if ($s ne $r) { if($array[$s]<$array[$r]) { $srt=$array[$s]; $array[$s]=$array[$r]; $array[$r]=$srt; } } } }

        You are adding one element to an array and then sorting the whole array using an algorithm that is O( N2 ).    And even if you switched to Perl's built-in sort function:

        @array = sort { $a <=> $b } @array, $k;
        that would at best be O( log N ).    However, you don't really need to sort the array, just insert $k in the correct place which would give you an O( N ) algorithm:

        my $index = 0; ++$index while $k >= $array[ $index ]; splice @array, $index, 0, $k;
Re: Unexpected output for given program with write function
by Anonymous Monk on Jun 10, 2011 at 13:12 UTC
    Instead of
    my $count1 = 0; # Total number of keys in a table my $count2 = 0; # Matched + Undefined + Ingonerd values for key my $count3 = 0; # Number of keys exactly matched
    better names might be $nKeysInTable, $nValsMUI, $nKeysMatchedExactly, its self-documenting code :)

    Also, see Re: Formats and Variable Scope for how to make your formats easier to use by making them functions , and eliminating all those format variables.

Re: Unexpected output for given program with write function
by Anonymous Monk on Jun 10, 2011 at 14:30 UTC
      I am very appreciated by your comment for this. Thanks.

        I'm fairly sure annony monk meant that cross posting is generally considered a bad thing to do and that at the very least you should mention that you have cross posted in your initial node.

        It is good to see however that you have replied to your post in the other forum with a link back to this thread.

        True laziness is hard work
Re: Unexpected output for given program with write function
by dipesh777 (Novice) on Jun 10, 2011 at 15:17 UTC
    Working well when i changed the code as per comments