Note that there are some explanatory texts on larger screens.

plurals
  1. POBest way to assert that multiple values are defined in Perl (0 and "" are defined)
    text
    copied!<p>The program that I am writing needs to do this:</p> <ul> <li>read every line of a file</li> <li>if the line contains an ordered pair (x,y) store the ordered pair</li> <li>before the next ordered pair, there will be a line of the file that starts with "Results" <ul> <li>store the ordered pair at the end of that line as a "value" and "error"</li> </ul></li> <li>print out the corresponding x, y, value, error in CSV format</li> <li>read the next (x,y) value and so on, the (x,y) lines and (value,error) lines will alternate in the file</li> </ul> <p>This is not a homework assignment. As you can see, I already have code that works down to 17 lines. I'm wondering if I can accomplish this task with any fewer lines or cleaner code, while maintaining at least the level of readability that this version has, and maintaining Perl style (such as the line break between includes and the first executable line).</p> <p>The line that I am least thrilled with is </p> <pre><code>if (defined($x) &amp;&amp; defined($y) &amp;&amp; defined($val) &amp;&amp; defined($err)) </code></pre> <p>Is there a better way to do an an assertion to take care of the alternating data in the file? If I don't use the defined() function, the program does not function as intended, because some of the x and y coordinates are 0 values.</p> <pre><code>#!/usr/bin/perl use strict; print "X,Y,Val\n"; foreach (@ARGV){ open log,$_ or die $!; my ($x,$y,$val,$err); while(&lt;log&gt;){ chomp; ($x,$y) = ($1,$2) if (/\((\d*|-\d*),(\d*|-\d*)\)/); ($val,$err) = ($1,$2) if (/^Results.*\((.*),(.*)\)$/); if (defined($x) &amp;&amp; defined($y) &amp;&amp; defined($val) &amp;&amp; defined($err)){ print "$x,$y,$val:$err\n"; ($x,$y,$val,$err) = undef; } } } </code></pre> <p>Thank you everyone for the answers, I'm learning a lot of new Perl syntax. I've figured out how to get this script down to 10 lines. I was challenging myself on the number of lines in which I could write this.</p> <pre><code>#!/usr/bin/perl use strict; print "X,Y,Val\n"; open LOG,"&lt;@ARGV[0]" or die $!; while(&lt;LOG&gt;){ chomp; print "$1,$2," if (/\((\d*|-\d*),(\d*|-\d*)\)/); print "$1:$2\n" if (/^Results.*\((.*),(.*)\)$/); } </code></pre> <p>Another Update. Using the information in the answers, I was able to get this down to 8 lines. I also improved the regex and made sure that the header would only be printed once if multiple files were provided.</p> <pre><code>#!/usr/bin/perl use strict; while(&lt;&gt;){ print "X,Y,Val\n" if ($. == 1); print "$1,$2," if (/.*\((-?\d+),(-?\d+)\)/); print "$1:$2\n" if (/^Results.*\((.*)\).*\((.*)\)$/); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload