20070301a

From Wsms

Jump to: navigation, search

previous next
GO TO:
Parent class notes: Perl Programming Language class notes
Back to: Perl programming language
Angelica's complementary notes



Thursday March 01 2007

Contents

Quiz 26

Question 1 - formatted numbers with commas

( points) Write a program to read in a list of numbers and sort them numerically. Print out the resulting list in a right-justified column with commas in the numbers where appropriate. Round the decimal portion of the number to 2 places, and if the number contains only fractions print a leading 0 before the decimal point. Hint: You will need "sprintf"

#!/usr/bin/env perl
use warnings;
use strict;

my @nums = ();
while (<>) {
  chomp;
  push @nums, $_;
}

foreach (sort {$a <=> $b} @nums) {
  my $s_num = sprintf "%13.2f", $_;
  if ($_ >= 1000000) {
    $s_num = substr($s_num, 1, 3).",".substr($s_num, 4);
  }
  if ($_ >= 1000) {
    $s_num = substr($s_num, 1, 6).",".substr($s_num, 7);
  }
  printf $s_num."\n";
}

Test data:

1666
1222666.99
55.5
4.32
6.02
1222666.999
0.055

Output:

[ggeller@ws05 quiz26]$ ./1.pl < nums
         0.06
         4.32
         6.02
        55.50
     1,666.00
 1,222,666.99
 1,222,667.00

Quiz Question 1, Joe's Answer

#!/usr/bin/perl -w
#sorting and printing decimal numbers

#read in some numbers and store them in an array
print "please enter some numbers - \n";
while (<STDIN>)
    {chomp;
     @numbers = (@numbers, $_);
    }

#sort them numerically
@sorted_numbers = sort {$a <=> $b} @numbers;

#now print them (forget the commas this time)
foreach (@sorted_numbers)
    { 
     $f_number = sprintf("%0.2f", $_); 
     while ($f_number =~ s/(-?\d+)(\d\d\d)/$1,$2/)
        {1}
     printf ("%20s\n",$f_number);
    }

Quiz Question 1, my answer, generalized for larger numbers

#!/usr/bin/env perl
use warnings;
use strict;

my @nums = ();                      # raw numbers
while (<>) {
  chomp;
  push @nums, $_;
}

my $s = "";
@nums = sort {$a <=> $b} @nums;     # numeric sort.
$s = sprintf "%.2f", $nums[-1];     # this gets the length of the longest number
my $len = length($s);
my $n_comma = int(($len-3)/3);
my $flen = $len + $n_comma + 1;
my @s_nums_padded = ();             # Printed and padded to the right length
foreach (@nums) {
  $s = sprintf "%$flen.2f", $_;
  push @s_nums_padded, $s;
}

# Add commas
foreach (@s_nums_padded) {
  $s = $_;
  my $i_dot = index($s, ".");
  for (my $i = 1; $i_dot - $i * 4 > 0 ; $i++) {
    my $offset = $i_dot - $i * 4;
    if (substr($s, $offset, 1) ne " "){
      $s = substr($s, 1, $offset).",".substr($s, $offset + 1);
    }
  }
  print "$s\n";
}

Note: In PHP you can use the number_format function to add commas. See: http://php.net/number_format. The Perl Cookbook has another way to put camman in numbers:

sub commify {
    my $text = reverse $_[0];
    $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
    return scalar reverse $text;
}

Question 2

Write a program that will print the following hash's data sorted in case-insensitive alphabetical order by last name. When the last names are the same, sort those by first name (again case insensitive). That is, the first name in the output should be Fred's and the last one should be Betty's. All of the people with the same family name should be grouped together. Don't alter the data. The names should be printed with the same capitalization as shown here.

My %last_name = qw(
betty rubble
fred flintstone
Barney Rubble
Wilma Flintstone
);

Hint: Remember the \U ... \E escape sequence

#!/usr/bin/env perl
use warnings;
use strict;

my %last_name = qw(
betty rubble
fred flintstone
Barney Rubble
Wilma Flintstone
);

my @keys = sort {
  "\L$last_name{$a}" cmp "\L$last_name{$b}"  # by last name
   or
  "\L$a" cmp "\L$b"                          # by first name
} keys %last_name;

foreach (@keys) {
  print "$last_name{$_}, $_\n";              # Rubble,Bamm-Bamm
}

Output:

[ggeller@ws05 quiz26]$ ./2.pl
flintstone, fred
Flintstone, Wilma
Rubble, Barney
rubble, betty


Then we got to see a multimedia presentation on perl modules

see: http://209.129.16.203/webserver/Flash%20Animations/Modules/lesson-1-a-modules-final.exe

Installing CPAN Perl Modules on Linux

see: http://www.cpan.org/misc/cpan-faq.html#How_install_Perl_modules

[root@ws05 ~]# perl -MCPAN -e 'install Astro::Sunrise'
... (skipped lots of output)

Update the file indices.

[root@ws05 ~]# updatedb

See the documentation.

[ggeller@ws05 modules]$ perldoc Astro::Sunrise

Joes sample program, slightly modified:

#!/usr/bin/env perl
#Program to Demonstrate "using" a Perl Module
#written by J. McGerald 2002-11-12
use strict;
use warnings;

use Astro::Sunrise;

use vars qw /$sunrise $sunset/;

($sunrise, $sunset) = sunrise(2007,03,01,-117,32,-8,0);
print "Sunrise is $sunrise\n";
print "and Sunset is $sunset\n";

Output:

[ggeller@ws05 modules]$ ./sunrise.pl
Sunrise is 06:15
and Sunset is 17:45
Personal tools