After the helpful review of this code, I would like to submit my latest assignment for collective criticism/suggestion. As with my previous post, I am not asking for help solving the problem. It has already been turned in and graded (100). So, what was the assignment?

Generate a Perl/Tk GUI which implements the basics of a "countdown to" application. You should provide a way for the user to select the Month, Day, Year, Hour, Minute, and Second to "countdown to" from the current time. Do not worry about handling the case in which the user selects a time which has occurred in the past. In addition to solving this problem, you must satisfy the following requirements:

Use at least one sub-routine
Use ternaries
Use grep
Use the configure method on one or more widgets
Use qw//
Use two of Tk's geometry managers(pack, place, grid)


So, I'd appreciate any and all suggestions/criticisms on my code. I am particularly curious about the time routines...which values are the "driving factors?" I've noticed that I can use out of range values for things such as day of the week/year and not receive any errors. Reading Time::Local indicates that timelocal performs error checking, I'm just curious about which values are the key ones.

#!/usr/bin/perl #--------------------------------------------------------------------- +------- #-- Author: Adam McManus #-- Date: 07/25/03 #-- File: countdown.pl #-- Description: A simple "countdown to" program #--------------------------------------------------------------------- +------- use strict; use Time::Local; use Tk; use Tk::LabFrame; use Tk::BrowseEntry; our %w; #-- all widgets in the GUI our %months; our %time; Initialize(); MainLoop(); #------------------------------- Sub-routines ------------------------ +------ sub CreateMainWindow { $w{main} = MainWindow->new(); $w{main}->geometry('+200+0'); $w{main}->title('Countdown'); $w{main}->appname('countdown'); $w{main}->optionAdd("countdown*font", "{Arial} 10 {normal}"); $w{main}->repeat(1000, \&Update); $w{remain_fr} = $w{main}->LabFrame(-label => 'Time Remaining', -labelside => 'acrosstop', -relief => 'groove') ->pack(-anchor => 'nw', -expand => 1, -fill => 'x'); $w{remain_lbl} = $w{remain_fr}->Label(-text => 'Computing...', -justify => 'center', -font => 'Arial 12 bold') ->pack(); $w{future_fr} = $w{main}->LabFrame(-label => 'Future Date', -labelside => 'acrosstop', -relief => 'groove') ->pack(-anchor => 'nw'); for my $time_type ( qw/month day year hour minutes seconds/ ) { $w{"${time_type}_bent"} = $w{future_fr}->BrowseEntry( -label => ucfirst($time_type) . ':', -width => 5, -variable => \$time{$time_type}, -state => 'readonly'); } =item test $w{month_bent} = $w{future_fr}->BrowseEntry(-label => 'Month:', -variable => \$time{month}, -width => 5, -state => 'readonly'); $w{day_bent} = $w{future_fr}->BrowseEntry(-label => 'Day:', -variable => \$time{day}, -width => 5, -state => 'readonly'); $w{year_bent} = $w{future_fr}->BrowseEntry(-label => 'Year:', -variable => \$time{year}, -width => 5, -state => 'readonly'); $w{hour_bent} = $w{future_fr}->BrowseEntry(-label => 'Hours:', -variable => \$time{hour}, -width => 5, -state => 'readonly'); $w{minutes_bent} = $w{future_fr}->BrowseEntry(-label => 'Minutes:', -variable => \$time{minutes}, -width => 5, -state => 'readonly') +; $w{seconds_bent} = $w{future_fr}->BrowseEntry(-label => 'Seconds:', -variable => \$time{seconds}, -width => 5, -state => 'readonly') +; =cut $w{month_bent}->grid($w{day_bent}, $w{year_bent}, -sticky => 'ne'); $w{hour_bent}->grid($w{minutes_bent}, $w{seconds_bent}, -sticky => +'ne'); } #-- END CreateMainWindow sub-routine sub Initialize { $time{month} = 'Dec'; $time{day} = 12; $time{year} = 2003; $time{hour} = 14; $time{minutes} = 0; $time{seconds} = 0; CreateMainWindow(); $. = 0; for( qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/ ) { $months{$_} = $.++; $w{month_bent}->insert('end', $_); } $w{day_bent}->insert('end', $_) for( 1 .. 31 ); $w{year_bent}->insert('end', $_) for( 2003 .. 2038 ); $w{hour_bent}->insert('end', $_) for( 0 .. 23 ); for( 0 .. 59 ) { $w{minutes_bent}->insert('end', $_); $w{seconds_bent}->insert('end', $_); } for( grep /bent/, keys %w ) { $w{$_}->configure(-command => \&CheckRanges); } } #-- END Initialize sub-routine sub Update { my $goal_time = timelocal($time{seconds}, $time{minutes}, $time{hou +r}, $time{day}, $months{$time{month}}, $time{ +year}, 9, 400, 1); my $current_time = timelocal(localtime); my $time_difference = $goal_time - $current_time; my ($days, $hours, $min, $sec) = format_time($time_difference); my $d_sfx = ($days != 1) ? 's' : ''; my $h_sfx = ($hours != 1) ? 's' : ''; my $m_sfx = ($min != 1) ? 's' : ''; my $s_sfx = ($sec != 1) ? 's' : ''; $w{remain_lbl}->configure(-text => "$days day$d_sfx, $hours hour$h_ +sfx, $min minute$m_sfx, $sec second$s_sfx"); $w{main}->update(); } #-- END Update sub-routine sub CheckRanges { my $old_day = $time{day}; my $small_months = join '|', qw/Apr Jun Sep Nov/; $w{day_bent}->delete(0, 'end'); if( $time{month} eq 'Feb' ) { my $end_day = ( ( ($time{year} % 4 == 0) && ($time{year} % 100 != 0) ) || ($time{year} % 400 == 0) ) ? 29 : 28; $w{day_bent}->insert('end', $_) for ( 1 .. $end_day ); $time{day} = $end_day if( $old_day > $end_day ); return; } elsif( $time{month} =~ /$small_months/ ) { $w{day_bent}->insert('end', $_) for ( 1 .. 30 ); $time{day} = 30 if( $old_day > 30 ); return; } else { $w{day_bent}->insert('end', $_) for ( 1 .. 31 ); } } #-- END CheckRanges sub-routine sub format_time { my $sec = shift; my $hours = int( $sec / (60 * 60) ); $sec -= ($hours * 60 * 60); my $min = int( $sec / 60 ); $sec -= ($min * 60); my $days = int( $hours / 24 ); $hours = $hours % 24; return($days, $hours, $min, $sec); } #-- END format_time sub-routine
Thanks,
Inelukii

In reply to Style and Coding Criticism (part 2) by inelukii

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.