Beginner"s Introduction to Perl 5.10 exercise solution commentary

Beginner"s Introduction to Perl 5.10 exercise solution commentary

am 13.12.2010 01:52:42 von Onteria

--------------enig0B5C92F128A19D191A831371
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I just finished working on a solution for the exercises provided in the
tutorial located here:

A Beginner's Introduction to Perl 5.10 - Perl.com
http://bit.ly/dHvsqC
(shortened to prevent cutoff)

Instructions for the exercise:
"Given a month and the day of the week that's the first of that month,
print a calendar for the month."

and would like to request feedback on the solution with regards to ways
I could potentially improve this code. Also any mention of perldocs or
other documentation to look over would be most appreciated. Thank you
ahead of time for any feedback.

Note: Leap year logic is intentionally left out to make sure I
understood the basics.

===3D Code ===3D
use warnings;
use strict;

use List::Util qw(first);

my %days_in_months =3D (
'Jan' =3D> 31,
'Feb' =3D> 29,
'Mar' =3D> 31,
'Apr' =3D> 30,
'May' =3D> 31,
'Jun' =3D> 30,
'Jul' =3D> 31,
'Aug' =3D> 31,
'Sep' =3D> 30,
'Nov' =3D> 31,
'Dec' =3D> 31
);

my @days_of_the_week =3D ('Sun','Mon', 'Tue', 'Wed', 'Thu', 'Fri','Sat');=


sub PrintHeaders {
print "Sun\tMon\tTue\tWed\tThu\tFri\tSat\n";
}

sub GetDayOfWeekIndex {
my $day_of_the_week_name =3D shift;
my $index_value =3D first { $days_of_the_week[$_] eq
$day_of_the_week_name } 0 .. $#days_of_the_week;
return $index_value;
}

sub PrintCalendar {
my($month, $start_day) =3D @_;
my $start_day_of_the_week =3D GetDayOfWeekIndex $start_day;
my $day_of_week_counter =3D 0;

# If the first day of the week doesn't start on Sunday
# we will need to add some visual padding.
if($start_day_of_the_week !=3D $day_of_week_counter)
{
# -1 is used here because we need to loop this for
# the days up to but not including the start day of
# the week
for my $i (0..($start_day_of_the_week-1))
{
print "\t";
}

$day_of_week_counter =3D $start_day_of_the_week;
}

for my $day (1..$days_in_months{$month})
{
print $day;

if($day_of_week_counter == $#days_of_the_week)
{
print "\n";
$day_of_week_counter =3D 0;
}
else
{
print "\t";
$day_of_week_counter++;
}
} ## end for

}

PrintHeaders;
PrintCalendar "Jan", "Fri";

== Output ==
Sun Mon Tue Wed Thu Fri Sat
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31=09

(Verified by looking at a calendar for January 2010 with Friday as the
first day of the week.)
--=20
Onteria
Will you change the world, or will the world change you?


--------------enig0B5C92F128A19D191A831371
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.16 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNBW5gAAoJENUMyiCtNwJ+f1MIAKbhyiCh24dqKj+EWqA7 0eB/
GF3eIkf1VvnXDiE2sru6V9dh7+LIkWP/s2dyh+SyBs4yYiFHDNqkCIZMFPmY UMHp
n/csJQFVNd7Sr7CegCdBND/uKXjYCADFDEqqMsdBKSNJRABKP16T/lorucTE 9MzL
lL7AbBYD5oUunLNuTerqX+RsCbyJfKuuiIBFX71kDhWIDynzqlA0BhbT3jzQ SMuZ
CuM80e9mtsCSNj85Vil4tAIbosk/bvAhrtFN8pm1aqtWdw4irDU2BcOjW2R/ efac
aaaGhlATWl3t/4kGxuDP/zSoMGCX9dnhJ5JuENoWMWPsEx0KIx7DS0IJce7C iFQ=
=JnJu
-----END PGP SIGNATURE-----

--------------enig0B5C92F128A19D191A831371--

Re: Beginner"s Introduction to Perl 5.10 exercise solution commentary

am 13.12.2010 02:04:16 von Shawn Wilson

On Sun, Dec 12, 2010 at 7:52 PM, Onteria wrote:
> I just finished working on a solution for the exercises provided in the
> tutorial located here:
>
> A Beginner's Introduction to Perl 5.10 - Perl.com
> http://bit.ly/dHvsqC
> (shortened to prevent cutoff)
>
> Instructions for the exercise:
> "Given a month and the day of the week that's the first of that month,
> print a calendar for the month."
>
> and would like to request feedback on the solution with regards to ways
> I could potentially improve this code. Also any mention of perldocs or
> other documentation to look over would be most appreciated. Thank you
> ahead of time for any feedback.
>

wow, that's a bunch of code. this is why i use Date::Manip; for this
sort of thing. it includes leap year. however, if you want to add leap
year to this, maybe use something like if ($year % 4)... don't
remember when leap year is, so adjust as needed. i also store all of
my timestamps in epoch format which makes things easy (print time() ).

however, if this is just an exercise and nothing practical, ignore all
of this. however, since Date::Manip is pretty mature, you might look
through that code for some decent ideas.

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

Re: Beginner"s Introduction to Perl 5.10 exercise solution commentary

am 13.12.2010 08:04:21 von Shlomi Fish

Hi Onteria,

On Monday 13 December 2010 02:52:42 Onteria wrote:
> I just finished working on a solution for the exercises provided in the
> tutorial located here:
>
> A Beginner's Introduction to Perl 5.10 - Perl.com
> http://bit.ly/dHvsqC
> (shortened to prevent cutoff)
>
> Instructions for the exercise:
> "Given a month and the day of the week that's the first of that month,
> print a calendar for the month."
>
> and would like to request feedback on the solution with regards to ways
> I could potentially improve this code. Also any mention of perldocs or
> other documentation to look over would be most appreciated. Thank you
> ahead of time for any feedback.
>
> Note: Leap year logic is intentionally left out to make sure I
> understood the basics.

OK.

>
> === Code ===
> use warnings;
> use strict;
>

Nice.

> use List::Util qw(first);
>
> my %days_in_months = (
> 'Jan' => 31,
> 'Feb' => 29,
> 'Mar' => 31,
> 'Apr' => 30,
> 'May' => 31,
> 'Jun' => 30,
> 'Jul' => 31,
> 'Aug' => 31,
> 'Sep' => 30,
> 'Nov' => 31,
> 'Dec' => 31
> );

1. You should not be using one-space indentation, because the code is
difficult to read that way. Either use tabs or use something like four spaces.

>
> my @days_of_the_week = ('Sun','Mon', 'Tue', 'Wed', 'Thu', 'Fri','Sat');

You can use qw() here:

my @days_of_the_week = qw(Sun Mon Tue Wed Thu Fri Sat);

See:

* http://perlmeme.org/howtos/perlfunc/qw_function.html

* http://perldoc.perl.org/functions/qw.html

>
> sub PrintHeaders {
> print "Sun\tMon\tTue\tWed\tThu\tFri\tSat\n";
> }

This can be written using (untested):

print join("\t", @days_of_the_week), "\n";

And you can also use say in perl 5.10 and above.

Furthermore, I see you're using CamelCase for functions. You should be using
words_separated_by_underscore for that too.

>
> sub GetDayOfWeekIndex {
> my $day_of_the_week_name = shift;
> my $index_value = first { $days_of_the_week[$_] eq
> $day_of_the_week_name } 0 .. $#days_of_the_week;
> return $index_value;
> }

Maybe use a hash here instead. And the variables are too long and redundant
for my taste.

>
> sub PrintCalendar {
> my($month, $start_day) = @_;

You should have a space between the "my" and the "(".

> my $start_day_of_the_week = GetDayOfWeekIndex $start_day;
> my $day_of_week_counter = 0;
>
> # If the first day of the week doesn't start on Sunday
> # we will need to add some visual padding.
> if($start_day_of_the_week != $day_of_week_counter)
> {
> # -1 is used here because we need to loop this for
> # the days up to but not including the start day of
> # the week
> for my $i (0..($start_day_of_the_week-1))
> {
> print "\t";
> }

This can be done without a loop using the "x" operator":

http://perldoc.perl.org/perlop.html#Multiplicative-Operators

>
> $day_of_week_counter = $start_day_of_the_week;
> }
>
> for my $day (1..$days_in_months{$month})
> {
> print $day;
>
> if($day_of_week_counter == $#days_of_the_week)
> {

It will be less confusing if you increment $day_of_week_counter before the
conditional and check that it equals to @days_of_the_week in scalar context.

> print "\n";
> $day_of_week_counter = 0;
> }
> else
> {
> print "\t";
> $day_of_week_counter++;
> }
> } ## end for
>
> }
>
> PrintHeaders;
> PrintCalendar "Jan", "Fri";
>

You should also make sure you print a trailing newline because otherwise some
shells won't display the last line properly.

Regards,

Shlomi Fish

> == Output ==
> Sun Mon Tue Wed Thu Fri Sat
> 1 2
> 3 4 5 6 7 8 9
> 10 11 12 13 14 15 16
> 17 18 19 20 21 22 23
> 24 25 26 27 28 29 30
> 31
>
> (Verified by looking at a calendar for January 2010 with Friday as the
> first day of the week.)

--
------------------------------------------------------------ -----
Shlomi Fish http://www.shlomifish.org/
What Makes Software Apps High Quality - http://shlom.in/sw-quality

Chuck Norris can make the statement "This statement is false" a true one.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

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

Re: Beginner"s Introduction to Perl 5.10 exercise solution commentary

am 13.12.2010 13:52:44 von Onteria

--------------enig6A1BCB008F007E7E195E8A75
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: quoted-printable

Hi Shlomi,

Thanks for your detailed response, I really appreciate it. It looks as
though I need to tweak my editor a bit more and do more research on perl
style guidelines. I'll also take a look at the documentation you
provided to expand my knowledge more. Once again thanks for taking the
time to answer!

Best Regards,
Onteria
--=20
Onteria
Will you change the world, or will the world change you?


--------------enig6A1BCB008F007E7E195E8A75
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.16 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNBhcgAAoJENUMyiCtNwJ+mtgH/jHJxhaZsB6wN6HkkkxV OJYk
8uwNKm4/onhNWTA8QR8FlmNCEZ3Js6WCiERdpKqG/CMg6/S/EUTsA8XT5mPK x14F
GXqm6wgrw29S5LlS7re+CpbcLC0aryLUFCdYbRn2lfsIKozLCmfHaX9nYY8Q DDE2
UcSoRsd4K04AXJEDzUdrCF0kIey8Oy9ltZOrpCzd6OvhABskJa6XCFpyBCZG zGgs
coMrb9ec6eDG5R1+VczqKTIhCgFEVyRcrEiEr+tbc5xUCf6mFiHYojCGQwXm LkBN
km4xl9TdkiVODqgnzP3p4qAr5Weyc2r6oMgBZJ/KmV6Rs3490bMlwYuMHNWU x9s=
=XyTe
-----END PGP SIGNATURE-----

--------------enig6A1BCB008F007E7E195E8A75--