Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Refer calculated fields

by roboticus (Chancellor)
on Feb 11, 2020 at 17:57 UTC ( #11112792=note: print w/replies, xml ) Need Help??


in reply to Refer calculated fields

pragovnj:

There's not enough information in your question to be able to give a serious answer. Perl doesn't have native 'table', so I would have to make a guess as what you actually mean:

  • Perhaps you're using table as a synonym for an array?
  • You might be talking about a database?
  • Maybe you're working with an HTML table?
  • or a Text::Table?
  • or a PDF::Table?
  • or a spreadsheet?
  • ... other stuff I didn't think of...

Add a bit more information to your question, and I'm sure someone here may be able to lend a hand.

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: Refer calculated fields
by pragovnj (Novice) on Feb 11, 2020 at 18:14 UTC
    Hi,

    I am sorry for nor providing enough details. Can I call a field,sum(PvcCount) inside as shown below?

    $cmd = "ssh $id '. ~/q; \$Q/AgnNniGatewayList4-4.X -date $end_date' 2 +>/dev/null |"; open (input , $cmd); #print "$cmd\n"; while ($INPUT_LINE = <input>) { chomp($INPUT_LINE); ($dat{sum(PvcCount)}, $dat{sum(LCir)}, $dat{sum(RCir)}) = spli +t(/ /, $INPUT_LINE); $KEY = $EquipName . "." . $slot . "." . $port; $sum(PvcCount){$KEY} = $dat2{sum(PvcCount)}; $sum(LCir){$KEY} = $dat2{sum(LCir)}; $sum(RCir){$KEY} = $dat2{sum(RCir)};

    Is this correct?

    Thanks,
    Pragov

      No - with (pure) Perl, you will have to calculate such stuff yourself.

      What you can do is map your Array of Hashes to a DBD::SQLite table, backed by your Perl data structure and then just use SQL to query your Perl data structures:

      use DBI; use DBD::SQLite; # ... sub import_data( $self, $book ) { my $dbh = DBI->connect('dbi:SQLite:dbname=:memory:',undef,undef,{A +utoCommit => 1, RaiseError => 1,PrintError => 0}); $dbh->sqlite_create_module(perl => "DBD::SQLite::VirtualTable::Per +lData"); my $sql_name = "mytable"; my $colnames = join ", ", qw(PvcCount LCir RCir); local $table_000 = \@data; my $tablevar = __PACKAGE__ . '::table_000'; my $sql = qq(CREATE VIRTUAL TABLE temp."$sql_name" USING perl($col +names, arrayrefs="$tablevar");); $dbh->do($sql); my $sum = $dbh->selectall_arrayref(<<'SQL'); select sum( PvcCount ) , sum(LCir) , sum(RCir) , EquipName from mytable group by EquipName SQL

      pragovnj:

      I'm still a bit fuzzy on what you're asking. From your question title, it seems like you want to defer some calculations to a later time. While that's possible, the rest of your code implies that you're new to Perl.

      So let's see if something simple will do what you want, first. Here's a bit of code that will keep a running sum of the input values. This lets you track the totals, but doesn't defer any calculations:

      use strict; use warnings; # Place to accumulate the values my %sum; my $EquipName = "Switch"; my $slot = "1"; my $port = "FF"; while (my $INPUT_LINE = <DATA>) { chomp $INPUT_LINE; my $KEY = $EquipName . "." . $slot . "." . $port; # Fetch out the values for the current line my ($PvcCount, $LCir, $RCir) = split /\s+/, $INPUT_LINE; # Add the values to the accumulators $sum{PvcCount}{$KEY} += $PvcCount; $sum{LCir}{$KEY} += $LCir; $sum{RCir}{$KEY} += $RCir; # Print the current values print "Line $.: (PvcCount, LCir, RCir) " . "CUR:($PvcCount, $LCir, $RCir) " . "TTL:($sum{PvcCount}{$KEY}, $sum{LCir}{$KEY}, $sum{RCir}{$KE +Y})\n"; } __DATA__ 1 2 3 2 4 9 3 8 27 4 16 81

      This should give you the following results:

      $ perl pm_11112793.pl Line 1: (PvcCount, LCir, RCir) CUR:(1, 2, 3) TTL:(1, 2, 3) Line 2: (PvcCount, LCir, RCir) CUR:(2, 4, 9) TTL:(3, 6, 12) Line 3: (PvcCount, LCir, RCir) CUR:(3, 8, 27) TTL:(6, 14, 39) Line 4: (PvcCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120)

      As you see, we created a hash called %sum to hold the totals as we read them in. So while processing a line, we have access to the total so far but aren't able to know the final total until the final line. If we wanted the output to be like this:

      Line 1: (PvcCount, LCir, RCir) CUR:(1, 2, 3) TTL:(10, 30, 120) Line 2: (PvcCount, LCir, RCir) CUR:(2, 4, 9) TTL:(10, 30, 120) Line 3: (PvcCount, LCir, RCir) CUR:(3, 8, 27) TTL:(10, 30, 120) Line 4: (PvcCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120)

      Then we'd have to read all the data before generating the output, because once we print a line, we can no longer change the values.

      Some formats let you put things into the file in any order you like, such as PDF. If you were writing a PDF file, you could simply "remember" the locations to write the final values, and then when you hit the last line and can compute your totals, you could then write the totals in the remembered locations. For a Spreadsheet, you could provide a formula for computing the values and let the spreadsheet do the work when the spreadsheet user opens the sheet.

      For a text file, though, you'd usually just parse the information and store it in a convenient format, and then after you're done reading the data, you'd then generate the report, something like this:

      use strict; use warnings; # Place to accumulate the values my %sum; # Place to store data before we print it. When the KEY field changes, + we can then # print all this data to the output my @data; my $previous_KEY=""; while (my $INPUT_LINE = <DATA>) { chomp $INPUT_LINE; # Fetch out the values for the current line my ($EquipName, $slot, $port, $PvcCount, $LCir, $RCir) = split /\s+/, $INPUT_LINE; # Create the key to add the data to the proper thing my $KEY = $EquipName . "." . $slot . "." . $port; # If KEY doesn't match the old KEY, print the data then delete # the data we no longer need. if ($previous_KEY ne $KEY) { print_data(); # then discard the (now unneeded) data and totals @data = (); %sum = (); $previous_KEY = $KEY; } # Add the values to the accumulators $sum{PvcCount} += $PvcCount; $sum{LCir} += $LCir; $sum{RCir} += $RCir; # Store the data so we can print it later push @data, [ $., $PvcCount, $LCir, $RCir ]; } # Print data that may still be in @data and %sums print_data(); # We made a subroutine to print the data because we need to # call it from different places. Inside the loop, we need to # print the data when the key changes. But we also need to # call this it the end because there will probably still be # some data in @data and %sum. sub print_data { my $KEY = shift; for my $row (@data) { print "Line $row->[0]: (PrvCount, LCir, RCir) " . "CUR:($row->[1], $row->[2], $row->[3]) " . "TTL:($sum{PvcCount}, $sum{LCir}, $sum{RCir})\n"; } } __DATA__ Switch 1 FF 1 2 3 Switch 1 FF 2 4 9 Switch 1 FF 3 8 27 Switch 1 FF 4 16 81 Router 5 DA 8 5 1 Router 5 DA 9 6 3 Router 5 DA 7 1 9 $ perl pm_11112793.pl Line 1: (PrvCount, LCir, RCir) CUR:(1, 2, 3) TTL:(10, 30, 120) Line 2: (PrvCount, LCir, RCir) CUR:(2, 4, 9) TTL:(10, 30, 120) Line 3: (PrvCount, LCir, RCir) CUR:(3, 8, 27) TTL:(10, 30, 120) Line 4: (PrvCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120) Line 5: (PrvCount, LCir, RCir) CUR:(8, 5, 1) TTL:(24, 12, 13) Line 6: (PrvCount, LCir, RCir) CUR:(9, 6, 3) TTL:(24, 12, 13) Line 7: (PrvCount, LCir, RCir) CUR:(7, 1, 9) TTL:(24, 12, 13)

      As you can see, there's more work involved it you want to "go back in time" and print the final totals on earlier lines. It's also not normally needed. Usually in reports we'll just print the totals *after* all the details, which you can do with code more like the first example.

      Hopefully this will help you with your project.

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

      I edited the code. Thanks, Prasad

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11112792]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2020-05-26 13:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (150 votes). Check out past polls.

    Notices?