Re: Basic Times Table excercise
by jcb (Parson) on Feb 17, 2016 at 04:50 UTC
|
#!/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. | [reply] [d/l] [select] |
|
|
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
| [reply] |
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,
| [reply] [d/l] [select] |
|
|
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
| [reply] |
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(;;){.
| [reply] [d/l] [select] |
|
|
| [reply] |
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.
| [reply] [d/l] |
|
|
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.
| [reply] |
|
|
| [reply] |
|
|
|
|
|
|
|
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?
²) 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!)
| [reply] [d/l] [select] |
|
|
|
|
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.
| [reply] |
|
|
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 | [reply] [d/l] [select] |
|
|
|
|
|
|
u65 is providing information that may actually be useful; you're the one polluting the thread with your hatred of Perl 6.
| [reply] |