package ONO::FW::Edu::Apps::Modules::Fractions;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2022-2026 Jos Kirps and The Joopita Project [ASBL]
# Copyright (C) 2011-2022 Jos Kirps and Joopita Research ASBL
# Copyright (C) 2006-2011 Jos Kirps and The Joopita Project
# Copyright (C) 2001-2006 Jos Kirps and The WobbleWolf Project
#
# This file, as well as many other parts of the ONO Software Project or
# related elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
#: This module is a front end application module wrapper that has been
#: created for the Morzino Project (morzino.com) and that has been released
#: as Open Source software.
#:
#: Note that this is NOT a self-contained application, it is only a wrapper
#: that makes heavy use of the ONO Perl Framework application engine.
use strict;
use ONO::FW::Edu::Apps::ToolBox;
use ONO::FW::Edu::Apps::Modules::WorksheetMaker::Input;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::Lib::PDF::Elements;
use ONO::Lib::Math;
use ONO::Lib::Math::HTML;
use ONO::FW::Apps::Core;
use ONO::FW::Apps::Core::Graphics;
use ONO::FW::Apps::Core::Math;
use ONO::FW::Apps::Core::Check;
use ONO::Lib::Parser;
use ONO::FW::Apps::PDF;
use ONO::FW::Apps::ToolBox;
use ONO::IO;
use ONO::Lib::UI::Check;
use ONO::Lib::UI::Select;
sub learn {
my (
$self,
$option,
$vars_ref,
$HTTP,
$BASE,
) = @_;
################################################################
# INIT - BEGIN
################################################################
my (
$db,
$community,
$action_url,
$form,
$format,
$canvas,
$pdfkey,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp,
$lang,
$BLK_ref,
$vars_ref,
) = ONO::FW::Apps::Core->init($vars_ref);
my %vars = %$vars_ref;
my %BLK = %$BLK_ref;
my $app = "fractions";
my @txt = (
"calculate",
"reduce",
"to number",
"compare",
"charts (pies, bars, )",
"easy (often common denominator)",
"medium difficulty",
"hard (reduction often required)",
"max. 3 fractions",
"mix randomly",
);
if ($vars{'app_lang'} eq "de") {
@txt = (
"rechnen",
"kürzen",
"in Zahl umwandeln",
"vergleichen",
"Diagramme (Torten, Kästen, )",
"einfach (oft gemeinsamer Nenner)",
"mittel schwierig",
"schwierig (Kürzen oft erforderlich)",
"max. 3 Brüche",
"zufällig mischen",
);
}
if ($vars{'app_lang'} eq "lu") {
@txt = (
"rechnen",
"kierzen",
"an Zuel emwandelen",
"vergläichen",
"Diagrammer (Taarten, Këschten, ...)",
"einfach (oft gemeinsame Nenner)",
"mëttel schwéier",
"schwiereg (Kierzen oft néideg)",
"max. 3 Bréch",
"zufälleg meschen",
);
}
if ($vars{'app_lang'} eq "fr") {
@txt = (
"calculer",
"réduire",
"en nombres",
"comparer",
"diagrammes (tartes, boîtes, ...)",
"facile (souvent dénominateur commun)",
"difficulté normale",
"difficile (réductions souvent requises)",
"max. 3 fractions",
"mélanger par hasard",
);
}
ONO::FW::Apps::Core->now("",$app,$vars{'app_lang'});
my $WEB;
$WEB .= ONO::FW::Apps::Core->output_paper_save($pdfkey,$BLK_ref,\%vars,$HTTP,$BASE,"$year$mon$mday");
if (ONO::FW::Apps::Core->running(\%vars,$db)) {
$WEB .= ONO::FW::Apps::Core->blockbackbutton($BASE,$vars_ref);
#############################################################
# WORKSHEET MAKER
#############################################################
if ($vars{'output_worksheet_maker'}) {
$vars_ref = ONO::FW::Edu::Apps::Modules::WorksheetMaker::Input->vars(\%vars);
%vars = %$vars_ref;
}
#############################################################
# ONLINE TRAINING
#############################################################
if ($vars{'output_web'} || $vars{'output_paper'}) {
my $question_number = ONO::FW::Apps::Core->question_number($vars{'output_web_question_number'});
my ($focus_on,$page,$pages,%cache,$whilecounter,$stats_switches,$PDF_OPTS);
my ($stat_correct,$stat_wrong,$stat_todo,$stat_todo_total);
my $op_symbol_opts;
my $questions_per_page = 1;
if ($vars{'output_paper'}) {
$PDF_OPTS = ONO::FW::Apps::Core->headers_options($BLK_ref,$vars_ref);
ONO::FW::Apps::PDF->new("$BASE/pdf/pdf-$pdfkey.pdf","",$format);
$vars{'app_input_multiple_questions_per_page'}++;
$questions_per_page = 24;
$op_symbol_opts = "p";
if ($vars{'output_worksheet_maker'}) {
$questions_per_page = 6;
}
}
foreach my $copy (ONO::FW::Apps::Core->unique_copies($vars{'app_input_print_options_unique_copies'})) {
my ($pdf_x,$pdf_y) = (4.5,12);
my @corr_cache;
if ($vars{'output_paper'}) {
if ($copy > 1) {
ONO::FW::Apps::PDF->page("",$format);
}
ONO::FW::Apps::Core->headers(\%vars,$format);
ONO::FW::Apps::PDF->title($vars{'app_input_print_options_title'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"HV",$vars_ref);
# ONO::Lib::PDF::ToolBox->canvas_test($canvas);
}
if ($vars{'output_web_next_question'}) {
$question_number++;
$vars{'output_web_question_number'}++;
foreach my $key (keys %vars) {
if ($key =~ /^output_web_(answer|cache)/) {
$vars{$key} = "";
}
}
}
if ($vars{'output_web'}) {
$WEB .= qq~<$form>~;
$op_symbol_opts = "c";
$WEB .= ONO::FW::Apps::Core->question_progress($vars{'app_input_number_of_questions'},$question_number);
}
if (ONO::FW::Apps::Core->question_progress_done($vars{'app_input_number_of_questions'},$question_number) || $vars{'output_web_finish'}) {
$vars{'output_progress_done'}++;
$WEB .= ONO::FW::Apps::Core->question_progress_done_msg($app,$db,$community,$form,$action_url,$vars{'app_input_number_of_questions'},$vars{'output_web_mistakes'},$lang,$BLK_ref,\%vars);
} else {
my @extypes;
foreach my $opt ('calc','redu','numb','comp','visu') {
if ($vars{"app_input_extype_$opt"}) {
@extypes = (@extypes,$opt);
}
}
my $extype_num = @extypes;
if (!$extype_num) {
$vars{"app_input_extype_calc"}++;
@extypes = ('calc');
$extype_num++;
}
for (my $i = 0; $i < $questions_per_page; $i++) {
if ($vars{'output_web'}) {
$stat_todo++;
for (my $j = 0; $j < 3; $j++) {
$vars{"output_web_answer_${i}_$j"} =~ s~\,~\.~g;
$vars{"output_web_answer_${i}_$j"} = uc $vars{"output_web_answer_${i}_$j"};
$vars{"output_web_answer_${i}_$j"} =~ s~[^0-9\-\.]~~gi;
}
}
my ($DEBUG,$qtype,$qsize,$items,$illegal,$hide_ref,$nums_ref,$nums_simple_ref,$ops_ref,$visu_ref,@hide,@nums,@nums_simple,@ops,%visu,$whilecounter,$div_by_zero);
my $exclude = 1;
my $transmitted = 0;
if ($vars{'output_web_cache_qtype'} && $vars{'output_web_cache_items'}) {
$transmitted = 1;
$qtype = $vars{'output_web_cache_qtype'};
$items = $vars{'output_web_cache_items'};
for (my $t = 0; $t < 8; $t++) {
$nums[$t] = $vars{"output_web_cache_num_$t"};
$ops[$t] = $vars{"output_web_cache_ops_$t"};
$hide[$t] = $vars{"output_web_cache_hide_$t"};
}
foreach my $key (keys %vars) {
if ($key =~ /^output_web_cache_visu_(.*?)$/) {
$visu{$1} = $vars{$key};
}
}
}
while ($whilecounter < 256 && $exclude && !$transmitted) {
$exclude = 0;
$div_by_zero = 0;
$whilecounter++;
(
$DEBUG,
$qtype,
$qsize,
$items,
$illegal,
$hide_ref,
$nums_ref,
$nums_simple_ref,
$ops_ref,
$visu_ref,
) = &number_generator(
"",
$i,
\@extypes,
$extype_num,
\%vars,
);
if (ONO::IO->devstation) {
$WEB .= $DEBUG;
}
@hide = @$hide_ref;
@nums = @$nums_ref;
@nums_simple = @$nums_simple_ref;
@ops = @$ops_ref;
%visu = %$visu_ref;
$vars{"qsize_$i"} = $qsize;
# exclude if numbers are too big
if (abs($nums[0]) > $vars{'app_input_range_to'} || abs($nums[2]) > $vars{'app_input_range_to'} || abs($nums[4]) > $vars{'app_input_range_to'} || abs($nums[6]) > $vars{'app_input_range_to'}) {
$exclude++;
}
# exclude if two first numbers are integers (step 1)
my ($num1_is_int,$num2_is_int);
if ($nums[0] == 0 || $nums[1] == 1 || $nums[0] == $nums[1]) {
$num1_is_int++;
}
if ($nums[2] == 0 || $nums[3] == 1 || $nums[2] == $nums[3]) {
$num2_is_int++;
}
if ($num1_is_int && $num2_is_int) {
$exclude++;
}
if (!$vars{'app_input_negative'} && ($nums[0] < 0 || $nums[1] < 0 || $nums[2] < 0 || $nums[3] < 0 || $nums[4] < 0 || $nums[5] < 0 || $nums[6] < 0 || $nums[7] < 0)) {
$exclude++;
}
# exclude if division by zero
if ($illegal) {
$exclude++;
}
if ($nums[1] == 0 || $nums[3] == 0 || $nums[5] == 0 || $nums[7] == 0) {
$exclude++;
$div_by_zero++;
}
if ($ops[1] eq "div" && (($nums[2] ne "" && $nums[2] == 0) || ($nums[4] ne "" && $nums[4] == 0) || ($nums[6] ne "" && $nums[6] == 0))) {
$exclude++;
$div_by_zero++;
}
}
# cache the qtype and items for the number generator, to enable mixing visus and 4-items calcs for example...
$vars{"cache_qtype_$i"} = $qtype;
$vars{"cache_items_$i"} = $items;
# last check to kill divs by zero...
if ($div_by_zero) {
$items = 3;
@nums = ('1','1','1','1','1','1');
@ops = ("","div","=");
}
# output paper
if ($vars{'output_paper'}) {
# transfer visu to cache, for correction sheet
foreach my $key (keys %visu) {
$vars{"cache_visu_${i}_$key"} = $visu{$key};
}
# paper layout
if ($vars{'app_input_range_to'} > 100 || $items > 3) {
$qsize = "large";
$vars{"qsize_$i"} = "large";
}
if ($i > 11) {
my $j = $i-12;
my $k = $i-24;
if ($vars{"qsize_$j"} eq "large") {
$qsize = "large";
}
if ($vars{"qsize_$k"} eq "large") {
$qsize = "none";
}
}
if ($qsize eq "small" || $qsize eq "large") {
my @pos = (3,10.25,17.5, 25 ,32.5,39.75,47);
my $add_x;
if ($items == 2) {
@pos = (3,17.25,31.5);
$add_x = 9;
}
if ($qtype eq "comp" || $qtype eq "redu") {
$add_x = 0;
}
if ($qtype eq "numb") {
@pos = (3,10,20);
$add_x = 0;
}
if ($qtype eq "visu") {
@pos = (0,25,32.5,39,44);
$items = 2;
$add_x = 0;
$ops[1] = "=";
$hide[2]++;
}
my $mul_x = 1.05;
if ($qsize eq "large") {
$mul_x = 1.4;
}
$corr_cache[$i] = "$qtype\^$pdf_x\^$pdf_y\^$add_x\^$mul_x\^$items\^";
$corr_cache[$i] .= "$hide[1]\^$hide[2]\^$hide[3]\^$hide[4]\^";
$corr_cache[$i] .= "$pos[0]\^$pos[1]\^$pos[2]\^$pos[3]\^$pos[4]\^$pos[5]\^";
$corr_cache[$i] .= "$nums_simple[0]\^$nums_simple[1]\^$nums_simple[2]\^$nums_simple[3]\^$nums_simple[4]\^$nums_simple[5]\^$nums_simple[6]\^$nums_simple[7]\^";
$corr_cache[$i] .= "$ops[1]\^$ops[2]\^$ops[3]\^";
&pdf_gen_line(
"",
"",
$qtype,
$canvas,
$pdf_x,
$pdf_y,
$add_x,
$mul_x,
$items,
\@hide,
\@pos,
\@nums,
\@ops,
\%visu,
$vars{'app_input_integers'},
);
}
$pdf_y = $pdf_y + 20;
if ($i%2 != 0) {
$pdf_y = $pdf_y + 7.5;
}
if ($pdf_y > 190 || (($vars{'output_worksheet_maker'}) && $pdf_y > 40)) {
my $next_col_offset = 59;
if ($qsize eq "large") {
$next_col_offset = 65;
}
$pdf_x = $pdf_x + $next_col_offset;
$pdf_y = 12;
}
}
if ($vars{'output_web'}) {
my (@PARTS,@OPS,@CHK,$transmit_disabled,$answer_found,$answer_is_correct,$answer_incomplete);
my $CHK_SWITCHES = "BCS";
for (my $a0 = 0; $a0 < 4; $a0++) {
for (my $a1 = 0; $a1 < 2; $a1++) {
if ($vars{"output_web_answer_${a0}_${a1}"} ne "") {
$answer_found++;
}
}
}
if ($answer_found) {
my $relval;
if ($vars{'output_web_answer_0_1'}) {
$relval = $vars{'output_web_answer_0_0'}/$vars{'output_web_answer_0_1'};
}
if ($qtype eq "visu" && (($vars{'output_web_answer_0_0'} == $nums[0] && $vars{'output_web_answer_0_1'} == $nums[1]) || $relval == $nums[0]/$nums[1])) {
$answer_is_correct++;
}
if ($qtype eq "redu" && $vars{'output_web_answer_2_0'} == $nums[2] && $vars{'output_web_answer_2_1'} == $nums[3]) {
$answer_is_correct++;
}
if ($qtype eq "numb" && (!$relval || $relval == $nums[0]/$nums[1]) && $vars{'output_web_answer_0_2'} == $nums[0]/$nums[1]) {
$answer_is_correct++;
}
if ($qtype eq "calc") {
my ($errs,$errs_hard);
for (my $a = 0; $a < $items; $a++) {
my $aa0 = $a*2;
my $aa1 = $a*2+1;
if ($nums[$aa1]) {
my $err = 1;
my $err2;
if ($vars{"output_web_answer_${aa0}_1"}) {
if ($vars{"output_web_answer_${aa0}_0"}/$vars{"output_web_answer_${aa0}_1"} == $nums[$aa0]/$nums[$aa1]) {
$err = 0;
} else {
$errs_hard++;
}
}
if ($nums[$aa0] && $nums[$aa1] && (!$vars{"output_web_answer_${aa0}_0"} || !$vars{"output_web_answer_${aa0}_1"})) {
$answer_incomplete++;
}
$errs = $errs + $err;
}
}
if ($errs_hard) {
$answer_incomplete=0;
}
if (!$errs) {
$answer_is_correct++;
}
}
if ($answer_is_correct) {
$CHK_SWITCHES .= "G";
$WEB .= qq~<input type="hidden" name="output_web_next_question" value="1">
<script>onojs_submit_delayed(2);</script>
~;
} else {
if ($qtype eq "visu" || $qtype eq "redu") {
$CHK_SWITCHES .= "R";
$vars{'output_web_mistakes'}++;
}
if ($qtype eq "calc" && !$answer_incomplete) {
$CHK_SWITCHES .= "R";
$vars{'output_web_mistakes'}++;
}
if ($answer_incomplete) {
$CHK_SWITCHES .= "Y";
}
if ($qtype eq "numb") {
if ($relval && $relval != $nums[0]/$nums[1]) {
$CHK_SWITCHES .= "R";
$vars{'output_web_mistakes'}++;
}
if ($vars{'output_web_answer_0_2'} ne "" && $vars{'output_web_answer_0_2'} != $nums[0]/$nums[1]) {
$CHK_SWITCHES .= "R";
$vars{'output_web_mistakes'}++;
}
}
}
}
$WEB .= ONO::FW::Apps::Core->input_vars(\%vars);
if ($answer_is_correct) {
$CHK_SWITCHES .= "L";
} else {
$CHK_SWITCHES .= "b";
}
for (my $p = 0; $p < 4; $p++) {
if ($p < $items) {
my $pp0 = $p*2;
my $pp1 = $p*2+1;
if ($nums[$pp0] ne "" && $nums[$pp1] ne "") {
$PARTS[$p] = ONO::Lib::Math::HTML->display_number("$nums[$pp0]/$nums[$pp1]","fM");
$CHK[$p] = ONO::Lib::Math::HTML->display_number("$nums[$pp0]/$nums[$pp1]","fMiI","output_web_answer_$pp0",qq~$vars{"output_web_answer_${pp0}_0"}/$vars{"output_web_answer_${pp0}_1"}~);
if ($answer_is_correct || $qtype eq "comp") {
$CHK[$p] = $PARTS[$p];
}
if ($hide[$p+1] || $qtype eq "visu") {
$PARTS[$p] = qq~<div class="bold lightred ml10 mr10" style="font-size:64px">?</div>~;
$CHK[$p] = ONO::Lib::Math::HTML->display_number("$nums[$pp0]/$nums[$pp1]","fMiD","output_web_answer_$pp0",qq~$vars{"output_web_answer_${pp0}_0"}/$vars{"output_web_answer_${pp0}_1"}~);
}
if ($qtype eq "redu") {
$CHK[0] = ONO::Lib::Math::HTML->display_number("$nums[0]/$nums[1]","fM");
}
if ($answer_is_correct && $qtype eq "visu") {
$CHK[$p] = ONO::Lib::Math::HTML->display_number("$nums[$pp0]/$nums[$pp1]","fM");
}
}
if ($ops[$p]) {
$OPS[$p] = ONO::Lib::Math::HTML->op_to_symbol($ops[$p],"C");
}
}
}
my @OPS2 = @OPS;
if ($qtype eq "visu") {
$visu{'html'}++;
# $visu{'debug'}++;
$PARTS[0] = ONO::Lib::PDF::Elements->chart($canvas,$visu{'type'},0,0,280,140,1,\%visu);
$PARTS[1] = "";
$CHK[1] = "";
}
if ($qtype eq "comp") {
for (my $q = 1; $q < 3; $q++) {
if ($ops[$q] =~ /^comp-(.*?)$/) {
my $correct = $1;
my $CORR = 0;
if ($correct eq "eq") {
$CORR = 1;
}
if ($correct eq "gt") {
$CORR = 2;
}
my $SOL = ONO::Lib::Math::HTML->op_to_symbol($correct);
my $SYM;
my @BUTS = ONO::FW::Apps::Core::Math->compare_buttons($i,$CORR,$SOL,$SYM,$stat_wrong,$questions_per_page,\%vars);
$WEB .= ONO::FW::Apps::Core::Math->compare_script();
$WEB .= qq~<input type="hidden" name="output_web_next_question" value="1">~;
# $OPS[$q] = qq~<div class="block40 bg_yellow bo lightred bold radius20">?</div>~;
$OPS2[$q] = qq~<table class="default_table">
<tr>
<td class="p0">$BUTS[0]</td>
<td class="p0">$BUTS[1]</td>
<td class="p0">$BUTS[2]</td>
</tr>
</table>
~;
}
}
}
if ($qtype eq "numb") {
my $res = $nums[0]/$nums[1];
my $PLA;
if (ONO::IO->devstation) {
$PLA = qq~ placeholder="$res"~;
}
$CHK[1] = qq~<div class="pad10_2"><input type="text" name="output_web_answer_0_2" value="$vars{'output_web_answer_0_2'}" class="w100"$PLA></div>~;
}
$WEB .= ONO::FW::Apps::Core::Math->compare_input($stat_correct,$vars{'output_web_mistakes'},$stat_wrong,$stat_todo);
if (!$transmit_disabled) {
$WEB .= qq~<input type="hidden" name="output_web_cache_qtype" value="$qtype">
<input type="hidden" name="output_web_cache_items" value="$items">
~;
for (my $t = 0; $t < 8; $t++) {
$WEB .= qq~<input type="hidden" name="output_web_cache_num_$t" value="$nums[$t]">
<input type="hidden" name="output_web_cache_ops_$t" value="$ops[$t]">
<input type="hidden" name="output_web_cache_hide_$t" value="$hide[$t]">
~;
}
foreach my $key (keys %visu) {
$WEB .= qq~<input type="hidden" name="output_web_cache_visu_$key" value="$visu{$key}">~;
}
}
$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"ctmW");
$WEB .= qq~<div class="inline auto">~;
if ($qtype eq "comp") {
$WEB .= qq~<div class="block32"></div>~;
} else {
$CHK_SWITCHES .= "T";
$WEB .= qq~ <div class="box_black flat_bottom mt20">
<div class="box_paper xlarge">
<table class="wide_table">
<tr>
<td class="p0 center">$PARTS[0]</td>
<td class="p0 center">$OPS[1]</td>
<td class="p0 center">$PARTS[1]</td>
<td class="p0 center">$OPS[2]</td>
<td class="p0 center">$PARTS[2]</td>
<td class="p0 center">$OPS[3]</td>
<td class="p0 center">$PARTS[3]</td>
</tr>
</table>
</div>
</div>
~;
}
$WEB .= ONO::FW::Apps::Core::Check->check_custom(
qq~<td class="p0">$CHK[0]</td>
<td class="p0">$OPS2[1]</td>
<td class="p0">$CHK[1]</td>
<td class="p0">$OPS2[2]</td>
<td class="p0">$CHK[2]</td>
<td class="p0">$OPS2[3]</td>
<td class="p0">$CHK[3]</td>
<td class="p0"><img id="loading_img" class="hide" src="/ono/osr/images/spacer/trans.gif" alt=""></td>
~,
$CHK_SWITCHES,
"",
"",
$BLK{'do_correct'},
);
$WEB .= qq~ </div>
</form>
~;
}
}
}
if (ONO::FW::Apps::Core->print_corrections("$BASE/pdf/pdf-$pdfkey-corr.pdf","",$format,$vars_ref)) {
ONO::FW::Apps::Core->headers(\%vars,$format,"c");
ONO::FW::Apps::PDF->title($BLK{'Corrections'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"HV",$vars_ref);
# ONO::Lib::PDF::ToolBox->canvas_test($canvas);
for (my $c = 0; $c < $questions_per_page; $c++) {
my (@hide,@pos,@nums,@ops,%visu);
my ($qtype,$pdf_x,$pdf_y,$add_x,$mul_x,$items,@rest) = split(/\^/,$corr_cache[$c]);
(
$hide[1],$hide[2],$hide[3],$hide[4],
$pos[0],$pos[1],$pos[2],$pos[3],$pos[4],$pos[5],
$nums[0],$nums[1],$nums[2],$nums[3],$nums[4],$nums[5],$nums[6],$nums[7],
$ops[1],$ops[2],$ops[3],
) = @rest;
foreach my $key (keys %vars) {
if ($key =~ /^cache_visu_${c}_(.*?)$/) {
my $key2 = $1;
$visu{$key2} = $vars{$key};
if ($key =~ /element_(.*?)_color/ && $vars{$key} ne "0:244:244:244") {
$visu{$key2} = "0:111:111:111";
}
}
}
&pdf_gen_line(
"",
"c",
$qtype,
$canvas,
$pdf_x,
$pdf_y,
$add_x,
$mul_x,
$items,
\@hide,
\@pos,
\@nums,
\@ops,
\%visu,
$vars{'app_input_integers'},
);
}
}
}
if ($vars{'output_web'}) {
# ($stat_correct,$stat_todo_total) = ONO::FW::Apps::Core->stats_multi_pages($vars{'app_input_number_of_questions'},$stat_correct,$stat_wrong,$page,$pages);
$stat_correct = $question_number-1;
$stat_todo_total = $vars{'app_input_number_of_questions'} - $stat_correct;
$WEB = ONO::FW::Apps::Core->stats_replace($WEB,$stat_correct,$stat_wrong,$stat_todo_total,$vars{'output_web_mistakes'},$page,$pages,$vars{'output_web_completed'});
}
if ($vars{'output_paper'}) {
ONO::FW::Apps::PDF->end;
$WEB .= ONO::FW::Apps::PDF->please_wait($pdfkey,\%BLK,\%vars,"",$HTTP,$BASE);
}
}
} else {
#############################################################
# EXERCISE SETUP
#############################################################
if (!$vars{'app_input_number_of_questions'}) {
$vars{'app_input_number_of_questions'} = 20;
}
$WEB .= ONO::FW::Apps::Core->infopics(
"screen:320:50:50::fractions_screenshot_1.jpg",
"sheet:168:180:135:15:fractions_sheet_1.jpg",
"sheet:168:40:155:-10:fractions_sheet_2.jpg",
);
if (!$vars{'app_input_range_to'}) {
$vars{'app_input_range_to'} = 50;
}
if (!$vars{'app_input_extype_redu'} && !$vars{'app_input_extype_calc'} && !$vars{'app_input_extype_numb'} && !$vars{'app_input_extype_comp'} && !$vars{'app_input_extype_visu'}) {
$vars{'app_input_integers'}++;
$vars{'app_input_extype_visu'}++;
$vars{'app_input_extype_redu'}++;
$vars{'app_input_extype_numb'}++;
$vars{'app_input_extype_comp'}++;
$vars{'app_input_extype_calc'}++;
$vars{'app_input_select_level'} = "hard";
}
if (!$vars{'app_input_range_opts'}) {
$vars{'app_input_range_opts'} = "auto";
}
if (!$vars{'app_input_extype_status'}) {
$vars{'app_input_extype_status'} = "std";
}
my (%setup,$hide);
my @tabs = ("std:green:a + b = ?","var:green:a + ? = c","mix:green:mix");
my $CUSTOM2 = ONO::Lib::UI::Select->buttons(
"app_input_extype",
$vars{'app_input_extype_status'},
\@tabs,
"",
"f",
$BLK_ref,
\%setup,
);
my $IFP = " , $BLK{'if_possible'} ";
$IFP =~ s~\ \;~ ~g;
my $CONF;
$CONF .= ONO::FW::Apps::ToolBox->conf_input("range", $BLK_ref,\%vars,"",1,100,9999,"Dhmu","auto=$txt[8];-;mix=$txt[9] ( 1 - 4 );-;1=1 ( A$IFP);2=2 ( A, B$IFP);3=3 ( A, B, C$IFP);4=4 ( A, B, C, D$IFP)");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("intneg", $BLK_ref,\%vars,"");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars,"","s");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("ops", $BLK_ref,\%vars,"","asmd-AS");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars,"","s");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("select", $BLK_ref,\%vars,"","easy=$txt[5];mid=$txt[6];hard=$txt[7]","",$vars{'app_input_select_level'},"","level");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars,"","s");
$CONF .= ONO::FW::Apps::ToolBox->conf_input_box_open("paper");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","extype_visu",$vars{'app_input_extype_visu'},"$txt[4]");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","extype_comp",$vars{'app_input_extype_comp'},"$txt[3] ( < = > )");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","extype_redu",$vars{'app_input_extype_redu'},"$txt[1] ( 2/4 → 1/2 )");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","extype_numb",$vars{'app_input_extype_numb'},"$txt[2] ( 1/2 → 0.5 )");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","extype_calc",$vars{'app_input_extype_calc'},"$txt[0] ( + / – / • / : )");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("custom", $BLK_ref,\%vars,"","",qq~<div class="inline ml30">$CUSTOM2</div>~);
$CONF .= ONO::FW::Apps::ToolBox->conf_input_box_close();
$WEB .= ONO::FW::Apps::Core->conf_box(
$db,
$community,
$app,
$form,
"",
$action_url,
$CONF,
$lang,
$BLK_ref,
\%vars,
"op-ncdi-CDI-lsu-N",
);
if (!$vars{'exercise'}) {
$WEB .= ONO::FW::Apps::Core->info_display(
ONO::FW::Apps::Core->info("info_online_print",$vars{'app_lang'}),
ONO::FW::Apps::Core->info("info_indiv_diff", $vars{'app_lang'}),
);
}
}
my ($status,$WEB) = ONO::Lib::Parser->parse($WEB,$vars_ref);
$WEB .= ONO::FW::Apps::Core->vardump($vars_ref);
$WEB = ONO::FW::Edu::Apps::ToolBox->apps_gate($WEB,$vars_ref);
return $WEB;
}
###################################################################
# SUBS
###################################################################
sub number_generator {
my (
$self,
$i,
$extypes_ref,
$extype_num,
$vars_ref,
) = @_;
my @extypes = @$extypes_ref;
my %vars = %$vars_ref;
# main logic for web and paper
my $items = 2;
my $qsize = "small";
my ($DEBUG,@ops,@hide,%visu,$illegal);
my $qtype = $extypes[int(rand($extype_num))];
if ($qtype eq "comp" || $qtype eq "calc") {
if ($vars{'app_input_range_opts'} eq "auto" || $vars{'app_input_range_opts'} == 1) {
$items = 2;
}
if ($vars{'app_input_range_opts'} =~ /^(2|3|4)$/) {
$items = $vars{'app_input_range_opts'};
}
if ($vars{'app_input_range_opts'} eq "mix") {
$items = 2+int(rand(3));
}
if ($qtype eq "comp" && $vars{'app_input_extype_calc'} && int(rand(100)) > 33) {
$items = 3;
}
}
# make sure mixing visus and others will work properly...
if ($items == 4) {
my $j = $i-12;
my $k = $i-24;
if ($vars{"cache_qtype_$j"} eq "visu" || $vars{"cache_qtype_$k"} eq "visu") {
$items = 3;
}
}
# if ($qtype eq "visu") {
#
# my $j = $i-12;
## my $k = $i-24;
#
# if ($vars{"cache_qtype_$j"} ne "visu" && $vars{"cache_items_$j"} == 4) {
# $qtype = $vars{"cache_qtype_$j"};
# # $items = 4;
# # $qtype = "calc";
# }
#
# }
if ($qtype eq "calc") {
if ($items < 3) {
$items = 3;
}
for (my $o = 1; $o < $items+1; $o++) {
$ops[$o] = ONO::FW::Apps::Core->random_operation(ONO::FW::Apps::Core->get_operations($vars_ref));
}
# if ($vars{'app_input_extype_status'} eq "std") {
$ops[$items-1] = "=";
# $hide[$items]++;
# }
# if ($vars{'app_input_extype_status'} eq "var" || $vars{'app_input_extype_status'} eq "mix") {
# $ops[1+int(rand($items-1))] = "=";
# $hide[1+int(rand($items-1))]++;
# }
}
my @nums = (1,1,1,1,1,1,1,1);
my $common = 1+(int(rand($vars{'app_input_range_to'}))-1);
my $max = sqrt($vars{'app_input_range_to'})*1.5;
if ("$ops[1]$ops[2]$ops[3]" =~ /(mul|div)/) {
$max = $max/2;
}
($nums[0],$nums[2],$nums[4],$nums[6]) = (int(rand($max)),int(rand($max)),int(rand($max)),int(rand($max)));
($nums[1],$nums[3],$nums[5],$nums[7]) = ($common,$common,$common,$common);
# make zeroes less probable
foreach my $z (0,2,4,6) {
if ($nums[$z] == 0 && int(rand(100)) > 33) {
$nums[$z] = 1+int(rand($max));
}
}
# no easy mode, or mul/div -> don't use common denominator
if ($vars{'app_input_select_level'} ne "easy" || "$ops[1]$ops[2]$ops[3]" =~ /(mul|div)/) {
my (@alt,$cumul,$whilecounter);
while ($whilecounter < 256 && ($cumul < 2 || $cumul > $vars{'app_input_range_to'})) {
$whilecounter++;
@alt = (1+int(rand($max)),1+int(rand($max)),1+int(rand($max)));
$cumul = $alt[0]*$alt[1];
if ($items > 3) {
$cumul = $alt[0]*$alt[1]*$alt[2];
}
}
if ($cumul > 1 && $cumul < $vars{'app_input_range_to'}) {
($nums[1],$nums[3],$nums[5]) = @alt;
}
}
if ($vars{'app_input_negative'}) {
# randomly insert negative numbers
for (my $n = 0; $n < 8; $n++) {
if (int(rand(100)) > 66) {
$nums[$n] = -$nums[$n];
}
}
} else {
# avoid negative results
if ($qtype eq "calc") {
if ($items == 3 && $ops[1] eq "sub" && $nums[1] && $nums[3]) {
if ($nums[0]/$nums[1] < $nums[2]/$nums[3]) {
my @cache = ($nums[0],$nums[1]);
($nums[0],$nums[1]) = ($nums[2],$nums[3]);
($nums[2],$nums[3]) = @cache;
}
}
}
}
# calculate results
if ($qtype eq "calc") {
if ($items == 3) {
($nums[4],$nums[5]) = ();
if ($ops[1] eq "add") {
$nums[4] = ($nums[0]*$nums[3]+$nums[2]*$nums[1]);
$nums[5] = $nums[1]*$nums[3];
}
if ($ops[1] eq "sub") {
$nums[4] = ($nums[0]*$nums[3]-$nums[2]*$nums[1]);
$nums[5] = $nums[1]*$nums[3];
}
if ($ops[1] eq "mul") {
$nums[4] = $nums[0]*$nums[2];
$nums[5] = $nums[1]*$nums[3];
}
if ($ops[1] eq "div") {
$nums[4] = $nums[0]*$nums[3];
$nums[5] = $nums[1]*$nums[2];
}
if (($vars{'app_input_extype_status'} eq "var" || $vars{'app_input_extype_status'} eq "mix")) {
if (($ops[1] eq "add" || $ops[1] eq "sub") && $vars{'app_input_op_add'} && $vars{'app_input_op_sub'}) {
# this currently only works for add and sub...
my @nums = ($nums[4],$nums[5],$nums[0],$nums[1],$nums[2],$nums[3],1,1);
my $rev = "add";
if ($ops[1] eq "add") {
$rev = "sub";
}
@ops = ("","=",$rev);
}
}
my $question = 3;
if ($vars{'app_input_extype_status'} eq "var") {
$question = 1+int(rand(2));
}
if ($vars{'app_input_extype_status'} eq "mix") {
$question = 1+int(rand(3));
}
if ($nums[0] == 0 || $nums[2] == 0 || $nums[3] == 0) {
$question = 3;
}
$hide[$question]++;
($nums[$question+1],$nums[$question+2]) = ONO::Lib::Math->fraction_reducer($nums[$question+1],$nums[$question+2],1);
}
if (ONO::IO->devstation()) {
# @ops=('','div','div','=');
}
if ($items == 4) {
($nums[6],$nums[7]) = ();
my $top1 = $nums[0]*$nums[3]*$nums[5];
my $top2 = $nums[2]*$nums[1]*$nums[5];
my $top3 = $nums[4]*$nums[1]*$nums[3];
$nums[7] = $nums[1]*$nums[3]*$nums[5];
if ($ops[1] eq "add") {
if ($ops[2] eq "add") {
$nums[6] = $top1+$top2+$top3;
}
if ($ops[2] eq "sub") {
$nums[6] = $top1+$top2-$top3;
}
if ($ops[2] eq "mul") {
$nums[6] = $top1+$top2*$top3;
}
if ($ops[2] eq "div") {
if ($top3 == 0) {
$illegal++;
} else {
my $div1 = $nums[2]*$nums[5];
my $div2 = $nums[4]*$nums[3];
$nums[6] = ($nums[0]*$div2+$nums[1]*$div1);
$nums[7] = $nums[1]*$div2;
}
}
}
if ($ops[1] eq "sub") {
if ($ops[2] eq "add") {
$nums[6] = $top1-$top2+$top3;
}
if ($ops[2] eq "sub") {
$nums[6] = $top1-$top2-$top3;
}
if ($ops[2] eq "mul") {
$nums[6] = $top1-$top2*$top3;
}
if ($ops[2] eq "div") {
if ($top3 == 0) {
$illegal++;
} else {
my $div1 = $nums[2]*$nums[5];
my $div2 = $nums[4]*$nums[3];
$nums[6] = ($nums[0]*$div2-$nums[1]*$div1);
$nums[7] = $nums[1]*$div2;
}
}
}
if ($ops[1] eq "mul") {
if ($ops[2] eq "add") {
$nums[6] = $top1*$top2+$top3;
}
if ($ops[2] eq "sub") {
$nums[6] = $top1*$top2-$top3;
}
if ($ops[2] eq "mul") {
$nums[6] = $top1*$top2*$top3;
}
if ($ops[2] eq "div") {
if ($top3 == 0) {
$illegal++;
} else {
$nums[6] = $nums[0]*$nums[2]*$nums[5];
$nums[7] = $nums[1]*$nums[4]*$nums[3];
}
}
}
if ($ops[1] eq "div") {
if ($ops[2] eq "add") {
if ($top2 == 0) {
$illegal++;
} else {
my $div1 = $nums[0]*$nums[3];
my $div2 = $nums[2]*$nums[1];
$nums[6] = ($nums[4]*$div2+$nums[5]*$div1);
$nums[7] = $nums[5]*$div2;
}
}
if ($ops[2] eq "sub") {
if ($top2 == 0) {
$illegal++;
} else {
my $div1 = $nums[0]*$nums[3];
my $div2 = $nums[2]*$nums[1];
$nums[6] = ($nums[5]*$div1-$nums[4]*$div2);
$nums[7] = $nums[5]*$div2;
}
}
if ($ops[2] eq "mul") {
if ($top2 == 0 || $top3 == 0) {
$illegal++;
} else {
$nums[6] = $nums[0]*$nums[3]*$nums[4];
$nums[7] = $nums[1]*$nums[2]*$nums[5];
}
}
if ($ops[2] eq "div") {
if ($top2 == 0 || $top3 == 0) {
$illegal++;
} else {
$nums[6] = $nums[0]*$nums[3]*$nums[5];
$nums[7] = $nums[1]*$nums[2]*$nums[4];
}
}
}
my $question = 4;
if ($vars{'app_input_extype_status'} eq "var") {
$question = 1+int(rand(3));
}
if ($vars{'app_input_extype_status'} eq "mix") {
$question = 1+int(rand(4));
}
if ($nums[0] == 0 || $nums[2] == 0 || $nums[3] == 0 || $nums[4] == 0) {
$question = 4;
}
$hide[$question]++;
($nums[$question+2],$nums[$question+3]) = ONO::Lib::Math->fraction_reducer($nums[$question+2],$nums[$question+3],1);
}
}
# generate comp numbers
if ($qtype eq "comp") {
if ($items == 4) {
$items = 3;
}
if ($items == 2) {
$ops[1] = "comp";
if ($nums[1] && $nums[3]) {
my $num1 = $nums[0]/$nums[1];
my $num2 = $nums[2]/$nums[3];
$ops[1] = "comp-".ONO::Lib::Math->comp($num1,$num2);
}
}
if ($items == 3) {
my ($num1,$num2,$num3);
if ($nums[1] && $nums[3] && $nums[5]) {
$num1 = $nums[0]/$nums[1];
$num2 = $nums[2]/$nums[3];
$num3 = $nums[4]/$nums[5];
}
my $rand_max = 3;
if ($vars{'output_web'}) {
$rand_max = 2;
}
my $rand = int(rand($rand_max));
if ($rand == 0) {
$ops[1] = ONO::FW::Apps::Core->random_operation(ONO::FW::Apps::Core->get_operations($vars_ref));
if (!$num2) {
$ops[1] = "add";
}
my $res = ONO::Lib::Math->calc($num1,$num2,$ops[1]);
$ops[2] = "comp-".ONO::Lib::Math->comp($res,$num3);
}
if ($rand == 1) {
$ops[2] = ONO::FW::Apps::Core->random_operation(ONO::FW::Apps::Core->get_operations($vars_ref));
if (!$num3) {
$ops[2] = "add";
}
my $res = ONO::Lib::Math->calc($num2,$num3,$ops[2]);
$ops[1] = "comp-".ONO::Lib::Math->comp($num1,$res);
}
if ($rand == 2) {
$ops[1] = "comp-".ONO::Lib::Math->comp($num1,$num2);
$ops[2] = "comp-".ONO::Lib::Math->comp($num2,$num3);
}
}
}
# reductions
if ($qtype eq "redu") {
$items = 2;
$ops[1] = "=";
$hide[2]++;
if (int(rand(100)) > 20) {
my @rands = (2,3,4,5,6,7); #,8,9,10,11,12,13);
my $rands_num = @rands;
if ($nums[0] == 0) {
$nums[0] = $rands[int(rand($rands_num))];
}
my $whilecounter;
if ($whilecounter < 32 && $nums[0] < $vars{'app_input_range_to'}/1.5 && $nums[1] < $vars{'app_input_range_to'}/1.5) {
$whilecounter++;
my $rand = $rands[int(rand($rands_num))];
if ($nums[0]*$rand < $vars{'app_input_range_to'} && $nums[1]*$rand < $vars{'app_input_range_to'}) {
$nums[0] = $nums[0]*$rand;
$nums[1] = $nums[1]*$rand;
}
}
}
($nums[2],$nums[3]) = ONO::Lib::Math->fraction_reducer($nums[0],$nums[1],1);
}
# fraction to number
if ($qtype eq "numb") {
$items = 2;
$ops[1] = "=";
$hide[2]++;
my $res = $nums[0]/$nums[1];
my $whilecounter;
while ($whilecounter < 64 && length $res > 4) {
$whilecounter++;
$nums[0] = 1;
$nums[1] = 2;
$res = $nums[0]/$nums[1];
}
if (length ($nums[0]/$nums[1]) > 5) {
$nums[0] = 1;
$nums[1] = 2;
}
$nums[2] = $nums[0];
$nums[3] = $nums[1];
}
# cache initial numbers
my @nums_simple = @nums;
# hard mode: make numbers bigger, reduction required
if ($vars{'app_input_select_level'} eq "hard") {
my @opts = (0,2);
if ($items == 4) {
@opts = (0,2,4);
}
if ($qtype eq "redu" || $qtype eq "numb") {
@opts = (0);
}
foreach my $n (@opts) {
if ($nums[$n] != $nums[$n+1] || int(rand(100)) > 66) {
my $rand = 1+int(rand($max));
if ($nums[$n]*$rand < $vars{'app_input_range_to'} && $nums[$n+1]*$rand < $vars{'app_input_range_to'}) {
$nums[$n] = $nums[$n]*$rand;
$nums[$n+1] = $nums[$n+1]*$rand;
}
}
}
}
if ($qtype eq "visu") {
$qsize = "small";
my $max = $vars{'app_input_range_to'};
if ($max > 32) {
$max = 32;
}
$nums[1] = 1+int(rand($max));
$nums[0] = int(rand($nums[1]+1));
$nums[2] = $nums[0];
$nums[3] = $nums[1];
$nums_simple[0] = $nums[0];
$nums_simple[1] = $nums[1];
$nums_simple[2] = $nums[0];
$nums_simple[3] = $nums[1];
$visu{"elements"} = $nums[1];
my ($r,$g,$b) = (25+int(rand(175)),25+int(rand(175)),25+int(rand(175)));
for (my $p = 1; $p < $visu{"elements"}+1; $p++) {
if ($visu{"elements"} > 1) {
$visu{"element_${p}_degrees"} = 360/$visu{"elements"};
}
$visu{"element_${p}_percent"} = 100/$visu{"elements"};
if ($p < $nums[0]+1) {
$visu{"element_${p}_color"} = "0:$r:$g:$b";
} else {
$visu{"element_${p}_color"} = "0:244:244:244";
}
}
if (($nums[1] < 10 || ($nums[1]%2 == 0 && $nums[1] < 13)) && int(rand(100)) > 50) {
$visu{"type"} = "pie";
} else {
if ($nums[1] < 11 && int(rand(100)) > 50) {
$visu{'rows'} = 1;
$visu{'cols'} = $nums[1];
$visu{"type"} = "bar";
if ($nums[1] < 6 && int(rand(100)) > 50) {
$visu{'rows'} = $nums[1];
$visu{'cols'} = 1;
$visu{'ori'} = "v";
}
} else {
if ($nums[1]%4 == 0 && int(rand(100)) > 10) {
$visu{'rows'} = 4;
$visu{'cols'} = $nums[1]/4;
$visu{"type"} = "bar";
} else {
if ($nums[1] < 31 && $nums[1]%3 == 0 && int(rand(100)) > 20) {
$visu{'rows'} = 3;
$visu{'cols'} = $nums[1]/3;
$visu{"type"} = "bar";
} else {
if ($nums[1] < 21 && $nums[1]%2 == 0 && int(rand(100)) > 30) {
$visu{'rows'} = 2;
$visu{'cols'} = $nums[1]/2;
$visu{"type"} = "bar";
} else {
$visu{"type"} = "dots";
}
}
}
}
}
}
return ($DEBUG,$qtype,$qsize,$items,$illegal,\@hide,\@nums,\@nums_simple,\@ops,\%visu);
}
sub pdf_gen_line {
my (
$self,
$switches,
$qtype,
$canvas,
$pdf_x,
$pdf_y,
$add_x,
$mul_x,
$items,
$hide_ref,
$pos_ref,
$nums_ref,
$ops_ref,
$visu_ref,
$integers,
) = @_;
my @hide = @$hide_ref;
my @pos = @$pos_ref;
my @nums = @$nums_ref;
my @ops = @$ops_ref;
my %visu = %$visu_ref;
my @hide_dev;
if ($switches =~ /c/) {
@hide = ();
}
if ($qtype eq "visu") {
my %data = %visu;
my $visu_x = $mul_x*($pdf_x+$pos[0])+$add_x/2;
my $visu_w = 21;
if ($data{'type'} eq "pie") {
$visu_x = $visu_x + 4;
$visu_w = 14;
}
ONO::Lib::PDF::Elements->chart( $canvas,$data{'type'},0.5+$visu_x,$pdf_y-7,$visu_w,14,1,\%data);
}
if ($qtype ne "visu") {
&pdf_gen_line_item("", 1,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$hide[1],$hide_dev[1],$pos[0],$nums[0],$nums[1],$qtype,$integers,$switches);
}
&pdf_gen_line_op("", 1,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$pos[1],$ops[1],$qtype,$switches);
if ($items > 1) {
&pdf_gen_line_item("", 2,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$hide[2],$hide_dev[2],$pos[2],$nums[2],$nums[3],$qtype,$integers,$switches);
if ($items > 2) {
&pdf_gen_line_op("", 3,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$pos[3],$ops[2],$qtype,$switches);
&pdf_gen_line_item("", 4,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$hide[3],$hide_dev[3],$pos[4],$nums[4],$nums[5],$qtype,$integers,$switches);
if ($items > 3) {
&pdf_gen_line_op("", 5,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$pos[5],$ops[3],$qtype,$switches);
&pdf_gen_line_item("", 6,$canvas,$pdf_x,$pdf_y,$add_x,$mul_x,$hide[4],$hide_dev[4],$pos[6],$nums[6],$nums[7],$qtype,$integers,$switches);
}
}
}
}
sub pdf_gen_line_item {
my (
$self,
$id,
$canvas,
$pdf_x,
$pdf_y,
$add_x,
$mul_x,
$hide,
$hide_dev,
$pos,
$num1,
$num2,
$qtype,
$integers,
$switches,
) = @_;
if (!$hide) {
my $alt;
if ($qtype eq "numb" && $id == 2 && $switches =~ /c/) {
$alt = $num1/$num2;
$alt = substr($alt,0,10);
}
if ($alt eq "" && ($qtype !~ /(redu|numb)/ || $switches =~ /c/) && $integers && ($num1 == 0 || $num2 == 1 || $num1 == $num2)) {
if ($num1 == $num2) {
$num1 = 1;
}
ONO::Lib::PDF::Draw->text( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2, $pdf_y+1, $num1,"c");
} else {
if ($alt ne "") {
ONO::Lib::PDF::Draw->text( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2-6, $pdf_y+1, $alt,"");
} else {
ONO::Lib::PDF::Draw->line( $canvas,$mul_x*($pdf_x+$pos-3), $pdf_y, $mul_x*($pdf_x+$pos+3)+$add_x, $pdf_y);
ONO::Lib::PDF::Draw->text( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2, $pdf_y-1.5, $num1,"c");
ONO::Lib::PDF::Draw->text( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2, $pdf_y+4, $num2,"c");
}
}
if ($hide_dev) {
ONO::Lib::PDF::Draw->line( $canvas,$mul_x*($pdf_x+$pos-3), $pdf_y, $mul_x*($pdf_x+$pos)-1, $pdf_y,5);
}
} else {
if ($qtype eq "numb") {
ONO::Lib::PDF::Draw->rect( $canvas,$mul_x*($pdf_x+$pos-5)+$add_x/2, $pdf_y-5, $mul_x*($pdf_x+$pos+5)+$add_x+14, $pdf_y+5,1,"0:0:0:0","0:244:244:244",2);
} else {
ONO::Lib::PDF::Draw->rect( $canvas,$mul_x*($pdf_x+$pos-5)+$add_x/2, $pdf_y-7, $mul_x*($pdf_x+$pos+5)+$add_x, $pdf_y+7,1,"0:0:0:0","0:244:244:244",2);
}
}
}
sub pdf_gen_line_op {
my (
$self,
$id,
$canvas,
$pdf_x,
$pdf_y,
$add_x,
$mul_x,
$pos,
$op,
$qtype,
$switches,
) = @_;
if ($op =~ /^comp/) {
ONO::Lib::PDF::Draw->circle( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2, $pdf_y, 3.5);
if ($switches =~ /c/ && $op =~ /^comp-(.*?)$/) {
ONO::Lib::PDF::Draw->text( $canvas,$mul_x*($pdf_x+$pos)+$add_x/2, $pdf_y+1, $1,"c",0,"M");
}
} else {
ONO::Lib::PDF::Draw->text_math_symbol($canvas,$mul_x*($pdf_x+$pos)+$add_x/2,$pdf_y,2.5,$op);
}
}
###################################################################
#### THAT'S IT :-D
###################################################################
1;
__END__