Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re^2: 2 newby questions

by Socrates440 (Acolyte)
on Jun 14, 2012 at 23:22 UTC ( #976327=note: print w/replies, xml ) Need Help??

in reply to Re: 2 newby questions
in thread 2 newby questions

Wow, I did not expect this much feedback. Thank you all. I took what you posted, what my book recommended, and some other bits and pieces of information and I tried to reconstruct the program in my own way as best I could. Any critiques would be helpful. Particularly, how I could condense the program into fewer lines. Thanks!
#!/usr/bin/perl -w use strict; my ($counter, $words, %counter) ; print "This program records all of the words you type and counts how o +ften you type them.\nPlease type in a list of words. Type done when +you are finished.\n" ; chomp ($words = <STDIN>) ; while ($words ne "done") { chomp ($words = <STDIN>) ; if ($words eq "done") { last ; } $counter{$words}++ ; } foreach $words (keys%counter) { if ($counter{$words} <= 1) { print "You typed $words $counter{$words} time." } else { print "You typed $words $counter{$words} times." ; } }

Replies are listed 'Best First'.
Re^3: 2 newby questions
by aaron_baugher (Curate) on Jun 15, 2012 at 04:38 UTC

    You're kind of repeating yourself inside and outside your while loop, so that can be condensed. Here's a more perlish way to do it. It confines the $word variable to the smallest possible scope, and uses a statement modifier after last to shorten things and make the logic clearer (in my opinion).

    while( my $word = <STDIN> ){ chomp $word; last if $word eq 'done'; $counter{$word}++; }

    On your foreach loop, you can eliminate the if/else with a ternary operator:

    for my $word (keys %counter){ print "You typed $word $counter{$word} time" .($counter{$word}>1 ? ' +s' : ''). ".\n"; # or printf "You typed %s %d time%s.\n", $word, $counter{$word}, ($counte +r{$word}>1?'s':''); }

    Aaron B.
    Available for small or large Perl jobs; see my home node.

Re^3: 2 newby questions
by hbm (Hermit) on Jun 15, 2012 at 11:57 UTC

    You can shorten your while loop:

    $counter{$_}++ while chomp($_ = <>) && !/^done$/i;

    I threw in !/^done$/i to terminate on "Done", "DONE", etc.

    And note the subtle suggestion of others to change $words to $word, which is clearer.

Re^3: 2 newby questions
by Anonymous Monk on Jun 15, 2012 at 13:09 UTC

    What about this one, is this code condensed enough?

    #!/usr/bin/perl -w use strict; use warnings; my %counter; print "This program records all of the words you type and counts how oft +en you type them.\nPlease type in a list of words. Type done when yo +u are finished.\n"; $counter{$_}++ while chomp($_ = <STDIN>) && !/^done$/i; foreach my $line ( sort keys %counter ) { printf "You typed '$line' $counter{$line} time%s.\n", ($counter{$l +ine} == 1) ? "" : "s"; }

    Also note the 'my' in the foreach, always use this idiom!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://976327]
shmem puts down the Canon garments and dresses as Chancellor
[vrk]: Congratulations. You should have Cookies
[shmem]: thanks vrk - but I'll rather have a plate of "silly con charme"
Lady_Aleena is trying to explain perl regexen to people right now and explaining how variables expand in regexen.

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2017-04-28 09:37 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (520 votes). Check out past polls.