jibberjabber has asked for the wisdom of the Perl Monks concerning the following question:

Hello everybody, I just joined and also this is my very first perl script. I had made one similar, but using qbasic about 20 years ago, since I only use linux now, perl seems like a more convenient option, and so far I really like it (perl). I had to of course read some tutorials, but never did find anything really with something like this, so I took what I could understand and put this together, it is a math program that give random multiplication problems, to help someone memorize the basic times tables 1 through 10. These days with modern calculators, etc. that might not seem important, but for simple multiplication it is faster when one can do it in their head, from memory. Any way this is what I came up with, I am happy with it except 1 thing, which I will get to, first the code (script)

#!/usr/bin/perl print "Type in the correct answer, \n"; print "Hit enter key to continue, if it is not correct\n "; print "the program will not move on to a new problem, \n "; print "think about your answer, and try again, when it is\n "; print "the correct answer, it will tell you, \n "; print "and give a new problem.\n "; for( ; ; ) { my $random = int rand 11; my $random2 = int rand 11; print "$random x $random2 = "; $x = $random * $random2; while ( $answer ne "$x" ) { $answer = <STDIN>; chomp $answer; ; } if ( $answer eq "$x" ) { } print "Great $answer is correct.\n"; print "hit enter to continue, ctr-c to exit."; $_ = <STDIN>; print "\033[2J"; #print "\033[2J"Might not work on some systems but it does on mine }

The one thing, I have not been able to get right, I would like it to give out put and say "sorry XX is not correct,please try again" XX= the number that was entered, so any way I would like it to say that if when a incorrect answer is given. I tried various things but they either displayed the previous answer from the previous problem, or caused the script to not work. I am kind of "stumped on that. More study on tutorials and I may eventually figure it out. Any way, I wanted to share my first perl script, and introduce myself, so that is about the only question I have at this point. Thanks for any feed back.

Replies are listed 'Best First'.
Re: Basic Times Table excercise
by jcb (Parson) on Feb 17, 2016 at 04:50 UTC

    Here is another version I quickly wrote as an example:

    #!/usr/bin/perl use strict; use warnings; print "[Instructions as before, ctrl-c or \"quit\" to exit]\n"; OUTER: { my ($x, $y) = map { int rand $_ } qw/11 11/; INNER: { print "$x x $y = "; local $_ = <STDIN>; chomp; last OUTER if m/^quit$/; redo INNER unless m/^\d+$/; if ($_ == ($x*$y)) { print "Right!\n"; redo OUTER } else { print "Try again.\n"; redo INNER } } }

    This is more to illustrate some features of Perl that are notably different from BASIC than to show "normal" Perl code, but I wrote it as a quick exercise.

    First, you should always use strict and use warnings in almost any Perl program. These pragmas help to avoid common mistakes that previous versions of Perl silently allowed; thus the need for pragmas to avoid breaking backwards compatibility outright whilst tightening the language spec somewhat.

    This version operates very similarly to yours. I didn't bother actually copying the instructions because they are of little value in teaching Perl.

    The random numbers are assigned to variables $x and $y. Both variables are assigned as a list. This is one of the common ways to put function arguments into named variables, often seen as my ($x, $y) = @_. Here the same syntax assigns the list of two values map returns to $x and $y. The qw// is another syntax for a list literal, used here to provide arguments to map.

    The reply from the user is stored in the default scratchpad variable $_ which is made local to the current dynamic scope. Because $_ is default for many operations, the chomp and the pattern match do not need to actually name the variable, although the same behavior does not apply to the subsequent test for numeric equality, where $_ must be explicitly named.

    The regex test is actually necessary, since Perl considers strings that are empty or not parsable as numbers to be equal to zero.

    Lastly, this program demonstrates two of Perl's loop control operators and their application to named blocks. Note the lack of explicit loops. Instead, the program repeatedly executes the OUTER and INNER blocks using the redo operator. If the user inputs "quit", the program exits the OUTER block using last. To be clear, this approach to iteration is not normal or recommended practice in Perl, but can occasionally produce more readable code and is out there.

      Thank you "JCB"

      This is nice, it does demonstrate a much better way

      On mine I had tried use strict, and use warnings, and it would not work at all, just goes to show. Thank you very much

Re: Basic Times Table excercise
by choroba (Cardinal) on Feb 16, 2016 at 22:51 UTC
    Hi jibberjabber, welcome to the Monastery!

    Once the while loop is left, you know the answer was correct (as that's the condition to exit the loop). You need to check for the wrong answer inside the loop:

    while (1) { chomp( my $answer = <STDIN> ); if ($answer eq $x) { print "Great, $answer is correct.\n"; print "Hit enter to continue, Ctrl+C to exit."; <STDIN>; last } else { print "Sorry, $x is not correct, please try again.\n"; } }

    Why do you use the string comparison eq instead of the numeric == ?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Thank you for the reply and the welcome,

      And the "tip", this makes sense to me now.

      Why did I use the string comparison eq instead of the numeric == ?

      Actually it is because when I wrote the script, I had not gotten that far into any tutorials. What I found was intended for text only. Then I looked at some on generating random numbers, but had not seen about the numeric comparisons yet. Just last night or yesterday I did see some on that, but still have not tried using the IE: == or != and I just had not yet tried doing with them. In a nutshell, I was not yet aware of the numeric options. Your reply gives me a "new approach" to this, and as soon as I get the chance I am going to experiment some more and see how it goes. Thanks a whole bunch on this and for taking the time. Thanks

Re: Basic Times Table excercise
by BillKSmith (Monsignor) on Feb 17, 2016 at 05:02 UTC

    Let me suggest a few additional improvements.

    You say you want numbers from 1 to 10, but compute numbers from 0 to 10. Use 1 + int rand 10.

    At the start of your script, use:

    use strict; use warnings;

    use <> rather than <STDIN>.

    use while (1) { rather than for(;;){.

    Bill

      Thank you Bill, for the additional tips

Re: Basic Times Table excercise [Perl6]
by u65 (Chaplain) on Feb 18, 2016 at 14:02 UTC

    Update: Perl6 added to end of subject.

    Welcome to the monastery, jibberjabber! Since you are just starting down your Perl journey, you might want to consider taking the new Perl 6 path. (See all the buzz of Perl 5's sister language, recently released Perl 6, at http://perl6.org). For comparison with Perl 5, I have translated your code (and contributions by jcb and choroba) into Perl 6:

    #!/usr/bin/env perl6 say q:heredoc/END/; Type in the correct answer, Hit enter key to continue, if it is not correct the program will not move on to a new problem, think about your answer, and try again, when it is the correct answer, it will tell you, and give a new problem. END while 1 { my $random = 11.rand.Int; my $random2 = 11.rand.Int; say "$random x $random2"; my $x = $random * $random2; while 1 { my $answer = get; if ($answer eq $x) { say "Great, $answer is correct."; say "Hit enter to continue, Ctrl+C to exit."; get; last; } else { say "Sorry, $x is not correct, please try again."; } } }

    Note that in Perl 6, the strict and warnings pragmas are the default so do not have to be explicitly used.

      jibberjabber, be warned that this poster is referring to an unfinished language that is NOT COMPATIBLE with Perl, and is not to be used in production, according to its own docs. "Perl6" is NOT the latest version of Perl.

      u65: are you seriously going to try to pollute every thread with a plug for your new hobby (well, I mean obviously only the ones with trivial questions that "Perl6" can solve) ?

      The way forward always starts with a minimal test.

        It's interesting to agree with both of you. I liked seeing the Perl6 code. I agree the thread was hijacked a bit and the caveats you gave would have been better in u65's node. Interesting times.

        1nickt, when exactly did I miss that you've been promoted to a moderator of the monastery who's in charge to censor contributions?

        Instead of using words like "pollute" and stirring an inquisition/witch hunt climate what about demonstrating your contributions to Perl5 and showing alternatives to development in a positive way?

        It's my personal believe that Perl6 should have been better named Perl++ from the beginning and that this resulted in a marketing disaster. ²

        But I'd really prefer to see positive contributions to Perl5 by the critics, instead of spilling hatred against the P6 folks.

        Nota Bene: it took Perl5 over 15 years to add function signatures to core and it's still experimental.

        Now how is this a convincing position to damage other contributions?

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        ²) well, easy to say in hindsight... but I'm repeating this since 2008 ( update and since it's Larry's decision I have to accept it. It's his language!)

        If there is a fault in what u65 posted, it may be in the lack of idiomatic form. I say meh, there.

        Personally, I welcome such contributions that concisely and conclusively demonstrate the merits of perl6 feature set, where it actually matters. In this regard, I want people with real perl6 expertise to be able to freely contribute, without the fear of backlash. You are not helping.

        Thanks "1nickt",for letting me know on this,it is important to know that and if it is not comaptible, I don't think I would want to install it. This would be a different topic,but using a Debian system,it is very important to only use programs that come from the Debian repos,and are compatible with the system. "perl" is. So in other words, the code would not work in perl ? I have not tried it yet. I like the part where the instructions are done like this:

        say q:heredoc/END/; Type in the correct answer, Hit enter key to continue, if it is not correct the program will not move on to a new problem, think about your answer, and try again, when it is the correct answer, it will tell you, and give a new problem. END
        I did just now try it from the command line,
        perl say q:heredoc/END/; Type in the correct answer, Hit enter key to continue, if it is not correct the program will not move on to a new problem, think about your answer, and try again, when it is the correct answer, it will tell you, and give a new problem. END
        But it does not seem to work with "perl"

        I guess that is why, perhaps once I get a better understanding of the basic perl commands ,etc I will be able to do more with that.

        Thank you as well, U65 for sharing that about perl6 , I don't see anything wrong with sharing it, but it would have been nice to mention it does not work with perl,but anyway thank you

        Well any way than you every body on this, I guess for now that is about it

        u65 is providing information that may actually be useful; you're the one polluting the thread with your hatred of Perl 6.