The point of this node is pretty simple. I have an example of a brief little program, and I wonder what would be done to format it according to "best practices" of readability. Obviously, I expect that there will be several different answers to this, but I'd like to know the whys and wherefores of them. One must always strive to improve, after all.

The program itself does nothing more than take two integers as command line arguments and print the sum of the range of numbers defined by them to STDOUT. The default behavior desired is for the first argument to be the integer immediately preceding the first number of the range, and for the second argument to be the last integer of the range. Additional desired behavior is for a command line option to be available to specify that the first numerical argument is the first number of the range, rather than the preceding integer.

For bonus points, tell me how you might modify the program for usability purposes. For instance, how (if at all) would you handle improper input such as non-integer arguments (e.g. floating point numbers like 2.7)?

And now, the code:

#!/usr/bin/perl -l use strict; use warnings; use Getopt::Std; our ($opt_s); getopts('s'); if ($opt_s) { print( ($ARGV[1] - $ARGV[0] + 1) * ($ARGV[0] + $ARGV[1]) / 2 ) } else { print( ($ARGV[1] - $ARGV[0]) * ($ARGV[0] + $ARGV[1] + 1) / 2 ) }

edit: It is of at least minor historical interest that this method of determining the sum of a range of numbers is credited originally to Leonardo Fibonacci, and secondarily to Carl Gauss in a quaint tale of outsmarting his primary school teacher. In the latter case, the teacher gave the whole class an insipid busywork assignment, to add together all the whole numbers from 1 to 100 (inclusive). Gauss is said to have almost instantly blurted out the answer (5050), having quickly rediscovered the trick of determining the sum of the first and last numbers in the range and multiplying by half the total number of integers in the range.

UPDATE (12:15 MST, 15 JAN 2007): What follows is a newer version of this program, incorporating ideas that have come up in this discussion and ideas that came to me while I stared at the suggestions offered here.

#!/usr/bin/perl -l use strict; use warnings; use Getopt::Std; our $VERSION = '1.0'; $Getopt::Std::STANDARD_HELP_VERSION = 'true'; my $help = ' syntax: series [-s] <first integer> <second integer> --help prints this help text and exits: invoking the help argument causes all other arguments to be discarded by this utility -s takes no arguments: changes program behavior so that the first number specified is the first number of the range, and not the number preceding it (syntax: series a+1 n) -- this option must precede all numerical arguments to the series utility description: This utility takes two positive integers as arguments and produces the sum of the range of integers starting after the first argument and ending with the second argument. It allows 0 to be specified as the first argument, indicating that all numbers in the range are positive integers. credits: Chad L. Perrin (author) PerlMonks community (contributors) -- node 594743 license: This software is licensed CCD CopyWrite. See the webpage at http://ccd.apotheon.org for licensing details. '; our ($opt_s); getopts('s'); die $help unless defined $ARGV[1]; map { /^-?\d+$/ or die "Invalid input: '$_'$!" } @ARGV; die "Error: arguments in descending value order.\n$help" if ($ARGV[0] +> $ARGV[1]); my $start = $ARGV[0] + ( $opt_s ? 0 : 1); my $end = $ARGV[1]; print( ($end - $start + 1) * ($start + $end) / 2 ); sub HELP_MESSAGE { print $help }

Frankly, if I'd thought about it before I started all this, I would have specified positive integers for the range (allowing 0 for the first numerical argument without the -s option). Since I didn't think of it, though, I'm happy to consider the problem of how to fix the fact that for some reason this version of the program errors out when a negative number argument is supplied because it thinks the negative indicates a command line option.

print substr("Just another Perl hacker", 0, -2);
- apotheon
CopyWrite Chad Perrin


In reply to a simple exercise in readability by apotheon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.