Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

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]
[Corion]: "If I wanted to work with flaps, I would have become a mailman"
[Corion]: (I'm not sure if the last one works in English too ;) )
[Eily]: it doesn't work in French AFAIK
[Eily]: I like the first one though :)
[erix]: balloonist, surely :P (or maybe baloneyist)
[marto]: afternoon all

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (9)
As of 2017-09-21 14:30 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (248 votes). Check out past polls.