----- Original Message ----- From: "Tiago Hori" <tiago.h...@gmail.com>
To: <beginners@perl.org>
Sent: Thursday, April 21, 2011 2:03 PM
Subject: Real Beginner

I was trying to do exercise 5 of the 5th edition of learning perl:
...
4. [10] Write a subroutine, named greet, that welcomes the person you name
by telling them the name of the last person it greeted:
...
5. [10] Modify the previous program to tell each new person the names of all
of the people it has previously greeted:
...
So I worked on it for a while and got something really close to what is in
the answers, but what you get as an output is grammatically incorrect, it is
missing the commas and such. I figured that in reality, eventually in the
real world, I would want the output to be correct or at least tab delimited.
So I went about trying to get commas in and I came up with this:


! /usr/bin/perl


use strict;

use 5.010;


sub greet {

    state @people;

    my $name = shift @_;

    print "Hi $name! ";

    if (@people){

my @peoplec = @people;

my $lastperson = shift @peoplec;

my $beforelast = shift @peoplec;

print "I've seen: ";

    foreach (@peoplec){

       print "$_, ";}

               print "$beforelast and ";

       print"$lastperson!\n";

                 }

                  else {

                print "You are the first here!\n";

                        }

             push @people, $name;

           }

&greet ("Fred");
&greet ("Barney");
&greet ("Wilma");
&greet ("Betty");
&greet ("Bamm-Bamm");

exit;

I am no perl expert, but this code looks really clunky to me, so I was just
looking for some input. If your input is your code sucks without any
constructive suggestion, please keep it for yourself, since I already know
that my code sucks! :P I am beginner, that's what newbies do, they suck (in
general, some people are brilliant and don't, not my case).


One quick alternative to the original problem would be to replace your loop logic with a simple print of the array as a string ("@peoplec"); or, if you want to insert commas, via the join() function.

 http://perldoc.perl.org/functions/join.html

(Though I don't know whether that would be jumping ahead, relative to where you are in the book. i.e. Was the exercise intended to learn more about looping?)

Here are a few thoughts relative to what you have so far (again, without knowing what tools you are "authorized" to use)...

- In shift-ing the names for comparison, what if you're the 2nd visitor? (i.e. there has only been one other visitor but you're currently trying to pull two names from the visitors list) Depending on how you construct your conditional logic, you would really only need to pull one name from the list.

- Would the existing method of shift-ing the names off the @people array result in a report of visitors in the order desired? (see: pop() function: http://perldoc.perl.org/functions/pop.html)

- Rather than looping, you could simply use a join() on your @peoplec array, after pop()-ing off the last visitor, and then just print out the last visitor prefixed with " and ."

- Rather than pulling and storing the names of the visitors for comparison, you could use available array parameters (number of elements) to index your way through the original @people variable, via a for loop. (There would no longer be a need for the second @peoplec array.)

e.g.  without over-supplying...
 for (my $inx=1; $inx <= $#people; $inx++){
   if ($inx < $#people){


Moving beyond a simple blast of previous visitors, possibly taking the project in a direction not explored in the book, does the wording of the problem require you to process the list of previous visitors to remove duplicates, and does the problem require display of the names alpahbetically or in ascending/descending order of their visits?

- How to reverse the listing of previous visitors, first-to-last and last-to-first?

- How well formatted should the display of visitors be? Can it just be one long line, regardless of the number of past visitors, or should it be formatted to look a bit nice, with a maximum length and a continuation indent?

- What if you want to see a list of previous individuals without duplication?

- What if you want to insure that each new person is uniquely identifiable?


Stop reading here.

////////////////////////////
/////  spoiler alert  //////
////////////////////////////

Below are the examples I played with to refresh my memory. One a slight modification of the original posted, one using join, and the last using array indexing.


sub greet_origtweak {

   state @people;

   my $name = shift @_;

   print "Hi $name! ";

   if (@people)
   {
       my @peoplec = @people;

       my $lastperson = pop @peoplec;

       print "I've seen: ";
       if (@peoplec)
       {
           print shift @peoplec;
           print ", $_" foreach (@peoplec);
           print " and ";
       }
       print"$lastperson!\n";
   }
   else
   {
       print "You are the first here!\n";
   }

   push @people, $name;
}

sub greet_join {

   state @people;

   my $name = shift @_;

   print "Hi $name! ";

   if (@people)
   {
       my @peoplec = @people;

       my $lastperson = pop @peoplec;

       print "I've seen: ";
       print join(", ",@peoplec) . " and " if (@peoplec);
       print "$lastperson!\n";
   }
   else
   {
       print "You are the first here!\n";
   }

   push @people, $name;
}


sub greet_index {

   state @people;

   my $name = shift @_;

   print "Hi $name!";

   if (@people)
   {
       print " I've seen: $people[0]";

       for (my $inx=1; $inx <= $#people; $inx++)
       {
           if ($inx < $#people)
           {
               print ", ";
           }
           else
           {
               print " and ";
           }
          print $people[$inx];
       }
       print "!\n";
   }
   else
   {
       print " You are the first here!\n";
   }

   push @people, $name;
}


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to