Listing Total Right Wrong and Percentage? [closed] - perl

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Ok, for a school project I'm doing, I'm creating a little quiz in Perl,
#########################################
# Solar Game #
# #
# (C) 2013 Donovan Roudabush #
# GPU/Creative Commons #
# #
# sharksfan98#gmail.com #
# github.com/sharksfan98/solargame #
#########################################
print " _________ .__ ________ \n";
print " / _____/ ____ | | _____ _______ / _____/_____ _____ ____ \n";
print " \_____ \ / _ \| | \__ \\_ __ \ / \ ___\__ \ / \_/ __ \ \n";
print " / ( <_> ) |__/ __ \| | \/ \ \_\ \/ __ \| Y Y \ ___/ \n";
print "/_______ /\____/|____(____ /__| \______ (____ /__|_| /\___ > \n";
print " \/ \/ \/ \/ \/ \/ \n";
print "Version 1.0 Beta\n\n";
print "Developed by Donovan Roudabush\n";
print "https://github.com/sharksfan98/solargame\n\n";
print "Press enter to start\n";
$ok = <STDIN>;
chomp $ok;
print "Enter the number of players\n";
$num = <STDIN>;
chomp $num;
my #names;
for (1 .. $num) {
print "Please enter your name\n";
my $name = <STDIN>;
chomp $name;
push #names, $name;
}
print "Hello, Players! Have you played before? (Y/N)\n";
$exp = <STDIN>;
chomp $exp;
if ($exp == Y) {
print "Ok! The game will begin.\n";
print "Press Enter to begin the questions\n\n";
}
if ($exp == N) {
print "Then I will explain the rules\n";
$ok2 = <STDIN>;
chomp $ok2;
} # Add rules here later
print "Part 1: Measurements\n\n";
print "Question 1\n";
print "What measurement is used to measurements within our Solar System?\n\n";
print "A) Astronomical Unit (AU)\n";
print "B) Light Year\n";
print "C) Parsec\n";
$q1 = <STDIN>;
chomp $q1;
if ($q1 == A) {
print "Correct!\n\n";
}
if ($q1 == B) {
print "Wrong!\n\n";
}
if ($q1 == C) {
print "Close! The Parsec is only used by Professionals, like NASA\n\n";
}
print "Question 2\n\n";
print "What do you use to measure farther objects, like stars and galaxies?\n";
print "A) Astronomical Unit (AU)\n";
print "B) Light Year\n";
print "C) Parsec\n";
$q2 = <STDIN>;
chomp $q2;
if ($q2 == A) {
print "Wrong!\n\n";
}
if ($q2 == B) {
print "Correct!\n\n";
}
if ($q2 == C) {
print "Wrong!\n\n";
}
print "Question 3\n";
print "Which measurement would you use to measure Earth to the Sun?\n\n";
print "A) Astronomical Unit (AU)\n";
print "B) Light Year\n";
print "C) Parsec\n";
$q3 = <STDIN>;
chomp $q3;
if ($q3 == A) {
print "Correct!\n\n";
}
if ($q3 == B) {
print "Wrong!\n\n";
}
if ($q3 == C) {
print "Wrong!\n\n";
}
print "Question 4\n";
print "Which measurement would you use measure the Sun to Polaris?\n\n";
print "A) Astronomical Unit (AU)\n";
print "B) Light Year\n";
print "C) Parsec\n";
$q4 = <STDIN>;
chomp $q4;
if ($q4 == A) {
print "Correct!\n\n";
}
if ($q4 == B) {
print "Wrong!\n\n";
}
if ($q4 == C) {
print "Wrong!\n\n";
}
print "Question 5\n";
print "Which would you use to measure Earth to Uranus?\n\n";
print "A) Astronomical Unit (AU)\n";
print "B) Light Year\n";
print "C) Parsec\n";
$q5 = <STDIN>;
chomp $q5;
if ($q5 == A) {
print "Correct!\n\n";
}
if ($q5 == B) {
print "Wrong!\n\n";
}
if ($q5 == C) {
print "Wrong!\n\n";
}
At the end of my code, I want to calculate and list the amount of questions right and wrong, and the percentage right. How do I go about doing this?

You could have a variable that gets incremented each time a question is answered correctly, and one that's incremented each time that a question is answered incorrectly.
my $correct = 0;
my $incorrect = 0;
...
if ($q1 eq 'A') {
print "Correct!\n\n";
$correct++;
} else {
print "Wrong!\n\n";
$incorrect++;
}
print "Percentage: ", int($correct/($correct + $incorrect) * 100 + 0.5), "%\n";
You can't use bare words like A to compare text. Use the string equals operator (eq) with a string. Like $q1 eq 'A'. You can also use an else block instead of comparing with everything else.
You actually only need a variable for the number of questions answered correctly if you're going to have a fixed number of questions, because then $incorrect will be the same as (total questions) - $correct, and $correct + $incorrect will always be the total number of questions.

Related

print truth table in to odt file

i want to print truth table in to a table in an adt file, t got a program but i don know how to get vale or value to print to odt file, this program just print result on screen !
sub truth_table {
my $s = shift;
#print "$s\n";
my #vars;
for ($s =~ /([a-zA-Z_]\w*)/g) {
push #vars, $_ ;
}
#print "$s\n";
#print "$_\n";
#print Dumper \#vars;
#print "\n", join("\t", #vars, $s), "\n", '-' x 40, "\n";
#print Dumper \#vars;
#vars = map("\$$_", #vars);
$s =~ s/([a-zA-Z_]\w*)/\$$1/g;
$s = "print(".join(',"\t",', map("($_?'1':'0')", #vars, $s)).",\"\\n\")";
$s = "for my $_ (0, 1) { $s }" for (reverse #vars);
eval $s;
}
truth_table 'A ^ A_1';
Get the result of eval with Capture::Tiny, then split the string into a two-dimensional array based on https://stackoverflow.com/a/4226073/5100564.
use Capture::Tiny 'capture_stdout';
sub truth_table {
#...the rest of your code here...
my $stdout = capture_stdout {
eval $s;
};
return $stdout;
}
$truth_string = truth_table 'A ^ A_1';
my #truth_array;
foreach my $line (split "\n", $truth_string) {
push #truth_array, [split ' ', $line];
}
foreach my $line (#truth_array) {
foreach my $val (#$line) {
print $val;
}
print "\n";
}
For this to work, I executed the following commands based on What's the easiest way to install a missing Perl module?
cpan
install Capture::Tiny
However, I would solve this problem in LibreOffice with a Python macro instead. APSO makes it convenient to enter and run this code.
import uno
from itertools import product
def truth_table():
NUM_VARS = 2 # A and B
columns = NUM_VARS + 1
rows = pow(2, NUM_VARS) + 1
oDoc = XSCRIPTCONTEXT.getDocument()
oText = oDoc.getText()
oCursor = oText.createTextCursorByRange(oText.getStart())
oTable = oDoc.createInstance("com.sun.star.text.TextTable")
oTable.initialize(rows, columns)
oText.insertTextContent(oCursor, oTable, False)
for column, heading in enumerate(("A", "B", "A ^ B")):
oTable.getCellByPosition(column, 0).setString(heading)
row = 1 # the second row
for p in product((0, 1), repeat=NUM_VARS):
result = truth_function(*p)
for column in range(NUM_VARS):
oTable.getCellByPosition(column, row).setString(p[column])
oTable.getCellByPosition(column + 1, row).setString(result)
row += 1
def truth_function(x, y):
return pow(x, y);
g_exportedScripts = truth_table,
Using product in this way is based on Creating a truth table for any expression in Python.
More documentation for Python-UNO can be found at https://wiki.openoffice.org/wiki/Python.

Perl: Why can I call subroutine A recursively, but I can't call A from B, which is called from an earlier A?

Try to "Play again" by answering Y when asked. Or am I just missing something completely obvious?
#!/usr/bin/perl
sub calc() {
$circ = 2 * $radius * 3.141592654;
print "The circumference is $circ\nPlay again (Y/n)? ";
$again = <STDIN>;
if ($again eq "Y") {
dialog();
} else {print "Bye!\n";
}
}
sub dialog {
print "What's the radius of the circle you'd like the circumference of?\n> ";
$radius = <STDIN>;
if ($radius eq "\n") {
print "That was just a blank line!\n";
dialog();
} elsif ($radius < 0) {
print "That was negative! Let's assume radius is 0.\n";
$radius = 0;
calc();
} else {calc();
}
}
dialog();
You don't chomp your input from STDIN
chomp($again = <STDIN>);
Also, always include use strict; and use warnings; at the top of each and EVERY perl script.
Finally, instead of doing recursion, a simple loop is sufficient. The following is a cleaned up version of your code:
#!/usr/bin/perl
use strict;
use warnings;
while (1) {
print "What's the radius of the circle you'd like the circumference of?\n> ";
chomp(my $radius = <STDIN>);
if ($radius eq "") {
print "That was just a blank line!\n";
next;
}
if ($radius < 0) {
print "That was negative! Let's assume radius is 0.\n";
$radius = 0;
}
my $circ = 2 * $radius * 3.141592654;
print "The circumference is $circ\nPlay again (Y/n)? ";
chomp(my $again = <STDIN>);
if ($again ne "Y") {
print "Bye!\n";
last;
}
}

Perl. How can I make output disappear after several seconds?

I'm prompting a user for a correct answer for example:
/> 13 + 7 ?
is it any way of making this output disappear after 2 seconds for example ?
..thanks' for any suggestions
You're asking for a few things combined, I think:
1) how do you erase a line
2) how do you wait for input for a while and then give up on waiting (ie, a timer)
The following code will do what you want (there are other ways of accomplishing both of the above, but the below shows one way for each of the above tasks):
use strict; use warnings;
use IO::Select;
my $stdin = IO::Select->new();
$stdin->add(\*STDIN);
# always flush
$| = 1;
my $question = "/> 7 + 3 ? ";
print $question;
if ($stdin->can_read(2)) {
print "you entered: " . <STDIN>;
} else {
print "\010" x length($question);
print " " x length($question);
print "too late\n";
}
Use select on STDIN to see whether there is any input within 2 seconds. If not, overwrite the output with a carriage return (\r) or multiple backspaces (\b).
Proof of concept:
$| = 1; # needed because print calls don't always use a newline
$i = int(rand() * 10);
$j = int(rand() * 10);
$k = $i + $j;
print "What is $i + $j ? ";
$rin = '';
vec($rin, fileno(STDIN), 1) = 1;
$n = select $rout=$rin, undef, undef, 2.0;
if ($n) {
$answer = <STDIN>;
if ($answer == $k) {
print "You are right.\n";
} else {
print "You are wrong. $i + $j is $k\n";
}
} else {
print "\b \b" x 15;
print "\n\n";
print "Time's up!\n";
sleep 1;
}
When you are ready for a more advanced solution, you could probably check out Term::ReadKey (so you don't have to hit Enter after you type in your answer) or something like Curses to exercise more control over writing to arbitrary spots on your terminal.

Rejecting Answers that are Not Valid?

I'm creating a Q&A Game using some Perl Code I wrote,
#########################################
# Solar Game #
# #
# (C) 2013 Donovan Roudabush #
# MIT License #
# #
# sharksfan98#gmail.com #
# github.com/sharksfan98/solargame #
#########################################
use strict; use warnings;
# predeclare subs for nicer syntax
sub prompt;
sub ask_question;
print banner();
prompt "Press enter to start...";
my $num = prompt "Enter the number of players:";
my #names;
for (1 .. $num) {
push #names, prompt "Player $_, please enter your name:";
}
my $exp = lc prompt "Hello, Players! Have you played before? (Y/N):";
unless ($exp =~ /^y/) {
print "These are the rules:\n\n",
"There are 50 questions that will be presented in several parts.\n",
"When presented a question, enter the correct answer according to the chronological number.\n\n",
"For example, you would enter 3 below since 2+2 = 4.\n\n";
"2+2=...\n";
"2\n",
"3\n";
"4\n";
"5\n\n";
"At the end, your stats will be presented\n\n";
}
print "Ok! The game will begin.\n";
prompt "Press Enter to begin the questions...";
my $correct = 0;
my $incorrect = 0;
my $question_counter = 0;
print "\nPart 1: Measurements",
"\n====================\n\n";
ask_question
"What measurement is used to measurements within our Solar System?",
1 => [
"Astronomical Unit (AU)",
"Light Year",
"Parsec",
];
ask_question
"What do you use to measure farther objects, like stars and galaxies?",
2 => [
"Astronomical Unit (AU)",
"Light Year",
"Parsec",
];
ask_question
"Which measurement would you use to measure Earth to the Sun?",
1 => [
"Astronomical Unit (AU)",
"Light Year",
"Parsec",
];
ask_question
"Which measurement would you use measure the Sun to Polaris?",
2 => [
"Astronomical Unit (AU)",
"Light Year",
"Parsec",
];
ask_question
"Which would you use to measure Earth to Uranus?",
1 => [
"Astronomical Unit (AU)",
"Light Year",
"Parsec",
];
print "\nPart 2: Galaxies",
"\n====================\n\n";
ask_question
"What is a galaxy?",
3 => [
"Another word for planet",
"Our Universe",
"A large gravitationally bound system composed of gas and dust",
];
ask_question
"Which is NOT A Type of Galaxy?",
4 => [
"Elliptical",
"Spiral",
"Irregular",
"Triangular",
],
ask_question
"How many stars are usually in a Galaxy?",
4 => [
"Tens to Hundreds",
"Hundreds to Thousands",
"Thousands to Millions",
"Billions to Trillions",
],
ask_question
"What is the name of our Galaxy?",
2 => [
"NGC 4414",
"Milky Way",
"PS2",
"Rolo",
],
my $percentage = int($correct/($correct + $incorrect) * 100 + 0.5);
print "Percentage: $percentage%\n";
exit;
sub prompt {
print "#_ ";
chomp(my $answer = <STDIN>);
return $answer;
}
sub ask_question {
my ($question, $correct_answer, $answers) = #_;
$question_counter++;
print "Question $question_counter\n";
print "$question\n\n";
for my $i (1 .. #$answers) {
print "$i) $answers->[$i-1]\n";
}
my $answer = prompt "Your answer is:";
if ($answer == $correct_answer) {
print "Correct!\n\n";
$correct++;
} else {
print "Wrong\n\n";
$incorrect++;
}
}
sub banner {
return <<'BANNER_END';
/ _____/ ____ | | _____ _______ / _____/
\_____ \ / _ \| | \__ \\_ __ \ / \ ___\__ \ / \_/ __ \
/ ( <_> ) |__/ __ \| | \/ \ \_\ \/ __ \| Y Y \ ___/
/_______ /\____/|____(____ /__| \______ (____ /__|_| /\___ >
\/ \/ \/ \/ \/ \/
Version 1.4.1 Alpha
Developed by Donovan Roudabush
https://github.com/sharksfan98/solargame
BANNER_END
}
Suppose if I wanted to prompt users that they must submit an answer that is 1-4 if they try to submit an invalid answer (i.e. Letters or Punctuation). How would I go about doing this?
if( $answer !~ /^\d+/ || $answer < 1 || $answer > scalar( #$answers ) ) {
printf "You can only answer with a number betweeen 1 and %d\n\n", scalar( #$answers );
} elsif( $answer == $correct_answer ) {
...
This prints a range warning if (a) they don't provide a number, or (b) they do, but it's outside the number of answers in the $answers arrayref.

Simple compiler Errors: Too new to Perl to know how to fix them

Hello I just began learning Perl. I have this simple temperature application but it is not compiling, I dont understand what are the errors & how I can fix them?
Can you point out what I am doing wrong & how I fix them:
#!/usr/local/bin/perl
use strict;
use warnings;
use constant false >= 0;
use constant true >= 1;
# Experimentation: Array & Hashes:
my #ar = ("a", "b", "c"); # error here
print $ar, "\n";
print $ar[0], "\n";
print $#ar, "\n";
print "The size of array = $#ar \n";
print "Trying to print $ar[1] within a string: ", $ar[1], " \n";
my %ha = ( "a" => 1, "b", "c", "d" ); # error here
print $ha, "\n";
print $ha{"a"}, "\n";
print $#ha, "\n";
print "The size of hash = $#ha \n";
print "Trying to print $ha{'b'} within string: ", $ha{'b'}, " \n";
# Functions:
sub isfloat
{
my $val = shift;
return $val =~ m/^\d+.\d+$/;
}
sub toFahrenheit
{
my $val = #_[0];
# if param var is a float
if ( isFloat($val) == 0 ) # Error here: Scalar value #_[0] better written as $_[0]
{
return -1;
}
return ( ($val * (9/5)) + 32 );
}
sub toCelsius
{
if ( isFloat(#_[0]) == 0 )
{
return -1;
}
return ( (#_[0] - 32) * (5/9) );
}
# Main Program:
my $programEnd = 0;
while ( $programEnd == 0 )
{
my $menu = "*** Welcome to Temperature Converter *** \n\n1. Convert from Celsius to Fahrenheit \n2. Convert from Fahrenheit to Celsius \n3. Exit \n Enter decision (1,2 or 3): ";
print $menu;
my $decision = <>;
if ( $decision == 3 )
{
$programEnd = 1;
# Could also just do this
# break;
}
print "Please enter a number: ";
my $val = <>;
if ( isfloat($val) )
{
$conVal = -1;
if ( decision == 1 )
{
$conVal = toFahrenheit( $val );
print $val, " C in Fahrenheit is: ", $conVal, " F \n";
}
else
{
$conVal = toCelsius( $val );
print $val, " F in Celsius is: ", $conVal, " C \n";
}
}
else { print $val, " is not a number \n"; }
}
The unhelpful messages about "Subroutine BEGIN redefined" actually is caused by these two lines:
use constant false >= 0;
use constant true >= 1;
You mean them to be:
use constant false => 0;
use constant true => 1;
The error "Scalar value #_[0] better written as $_[0]" is because in perl when you refer to an element of an array #arr, you say $arr[0], not #arr[0], because the element itself is a scalar.
>= ≠ =>