in reply to Writing to a file using Formats

This format thing is great in the right situation and I have used it. But often it is not the best way. It is "sort of an in-between approach". I think that better is: a) use printf or b) use a very zoomy Perl module.

There are some problems with your command loop. Normally this question of "are you finished or not?" is a bad idea. Instead of "another Pair of numbers? Y/N?", just prompt for the next pair of numbers like at the first prompt. If I don't have another set of numbers, then I quit, exit, CTL-C or whatever.

I may have goofed up something below, but I did run this code on my machine and it should give you some ideas about the command loop and how to use printf() for this problem.

#!usr/bin/perl -w use strict; my $title = "SOME REPORT TITLE"; my $LINES_PER_PAGE =10; my $page =1; my $line =9999; sub get_header_string { "\n$title , Page $page\n". " ---------------------------------\n". " NUMBER1 || NUMBER2 || ADDITION\n". " ---------------------------------\n"; } while ( (print "Enter a pair of numbers (space between) or quit: "), (my $line =<STDIN>) !~ /^\s*q(uit)?\s*$/i ) { next if $line =~ m/^\s*$/; #re-prompt for blank lines my ($num1, $num2, $kruft) = split(/\s+/,$line); if ( $kruft #user input validation is || ($num1 =~ m/\D/) #important, I like this style || ($num2 =~ m/\D/) #of formatting, others like ) #something different { print_command_error(); next; } foreach (1..100) { output ($num1, $num2, $num1+$num2); $num1++; $num2++; } } sub print_command_error { print "Illegal command args....\n"; print "some other message..probably usage message\n"; } sub output { my ($num1, $num2, $sum) = @_; if ($line++ >= $LINES_PER_PAGE) { if ($page >1) {print "\f"} print get_header_string; $line = 1; $page++; } printf (" %-9d %-10d %-10d\n", $num1, $num2, $sum); } __END__ C:\TEMP>useprintf.pl Enter a pair of numbers (space between) or quit: 1 2 SOME REPORT TITLE , Page 1 --------------------------------- NUMBER1 || NUMBER2 || ADDITION --------------------------------- 1 2 3 2 3 5 3 4 7 4 5 9 5 6 11 6 7 13 7 8 15 8 9 17 9 10 19 10 11 21 \f SOME REPORT TITLE , Page 2 --------------------------------- NUMBER1 || NUMBER2 || ADDITION --------------------------------- 11 12 23 12 13 25 13 14 27 14 15 29 15 16 31 16 17 33 17 18 35 18 19 37 19 20 39 20 21 41 \f SOME REPORT TITLE , Page 3 ...blah....
Update: I fiddled with this some more to get error handling right, etc. Not any big deal, but appended...There are some fancy Perl modules for tabular output. But this app only appears to need less than a dozen lines of real formatting code (the output() routine below).
#!usr/bin/perl -w use strict; #File Add2Num.pl my $title = "SOME REPORT TITLE"; my $LINES_PER_PAGE =10; my $ITERATIONS = 100; my $page =1; my $line =9999; if (@ARGV) { print " Usage: add2nums\n". " No command line args allowed\n". " program will prompt for a range of integers\n"; exit(-1); } sub display_range_error { print "ERROR!\n"; print "MUST have 2 positive numbers like: 11 23\n"; } sub page_header { "\n$title , Page $page\n". " ---------------------------------\n". " NUMBER1 || NUMBER2 || ADDITION\n". " ---------------------------------\n"; } while ( (print "Enter a pair of numbers (space between) or quit: "), (my $line =<STDIN>) !~ /^\s*q(uit)?\s*$/i ) { next if $line =~ m/^\s*$/; #re-prompt for blank lines my ($num1, $num2, $kruft) = split(/\s+/,$line); if ( $kruft #user input validation is || ($num1 =~ m/\D/) #important, I like this style || ($num2 =~ m/\D/) #of formatting, others like ) #something different { display_range_error(); next; } foreach (1..$ITERATIONS) { output ($num1, $num2, $num1+$num2); $num1++; $num2++; } } sub output { my ($num1, $num2, $sum) = @_; if ($line++ >= $LINES_PER_PAGE) { if ($page >1) {print "\f"} print page_header; $line = 1; $page++; } printf (" %-9d %-10d %-10d\n", $num1, $num2, $sum); } __END__ C:\TEMP>useprintf.pl Enter a pair of numbers (space between) or quit: 1 2 SOME REPORT TITLE , Page 1 --------------------------------- NUMBER1 || NUMBER2 || ADDITION --------------------------------- 1 2 3 2 3 5 3 4 7 4 5 9 5 6 11 6 7 13 7 8 15 8 9 17 9 10 19 10 11 21 \f SOME REPORT TITLE , Page 2 --------------------------------- NUMBER1 || NUMBER2 || ADDITION --------------------------------- 11 12 23 12 13 25 13 14 27 14 15 29 15 16 31 16 17 33 17 18 35 18 19 37 19 20 39 20 21 41 \f SOME REPORT TITLE , Page 3

Replies are listed 'Best First'.
Re^2: Writing to a file using Formats
by biohisham (Priest) on Aug 03, 2009 at 11:14 UTC
    I will use your code to train on error handling, I heard of existence of tabular modules, the thing is, I don't want to go through shortcuts, I want to learn Perl and what all there could be to it before advancing to these shortcuts employment, like when you know how something works base up is better than landing at its peak and not knowing how to climb down if you needed sometimes.. I will refer to your code for this basic error handling idea too... Thanks for your generosity
    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind
      Yes, I would say the use of "warnings" and "strict" is THE most important thing here.

      I hope that you also are able to use the standard command line loop I gave you to great effect during the coming years. This is a standard pattern that you will use over and over again.

      When you write a "while" loop, you want the main termination condition to be right there in the while()! Not buried further on down in the guts. That's not to say that other exit conditions can't exist in the "body", just that the "normal" situation should be apparent.

      The technique that I used is called the "comma operator". I guess crudely put, this is way to cram 2 or more statements into the place where normally just one would go. The truth of the while() is determined by the last comma statement, in this case whether this is a "quit" command or not.

      Now, some folks go "crazy" with this comma thing. I mean you could pretty much cram 10 statements in there. That is a bad idea!

      Yes, there are many fancy Perl modules for formatting text. I think that once you really understand printf() you will use either it or one of those modules and this format statement will fall by the wayside - or that's what happened in my learning experience. The format thing just didn't work out to give me as much control as I often needed.

        In particular, I enjoyed the idea in the while() loop, many a times I used to end up on infinite loops but when I saw the way you did the while() and I remembered I saw that concept before but did not employ it, it looked convoluted, Now it looks precise, neat and sharp and I started doing it in my exercises.

        I used the printf() and sprintf() but not so exclusively, I mean, well, they are easier of course, in formatting you have the placeholders and alignment left, right, center and for numbers you have a different placeholder ####, now this can be frustrating if you did not know what that is or why your numbers don't show and you can't realize you had to use @####.##### instead of @<<<<, ask me about it :P

        I got stuck at formatting earlier and for that reason I abandoned learning Perl for two years and imagine coming back again and at formatting I did not wanna give up so I summoned an extra vigor. Practice Makes Perfect, I would Practice and I am cherishing all the replies from the Monks in here to get back to them every other while and see where I stand.

        thanks again and best of luck

        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind