WeBWorK Problems

Array construction problems, no idea how to fix it

Array construction problems, no idea how to fix it

by Nicole Wilson -
Number of replies: 6
I have written an subroutine to create a kmap from a column of a truth table.

It should take a list that includes a string (the output label) and list of values in a truth table for a digital logic course (4, 8, or 16 values probably strings each one can be one of four things 0, 1, X, or i -- technically i is a possible value but it would not be used when a kMap is required, though it is found in this sample question for reasons).

As a debugging exercise I have scaled back the subroutine to only deal with a list of 8 values in test2.pg.

So if the truth table is

A B C O1 O2
0 0 0 0 1
0 0 1 0 1
0 1 0 0 1
0 1 1 1 i
1 0 0 1 i
1 0 1 0 1
1 1 0 X 0
1 1 1 1 0

Then the rough Kmap answer table (that I am trying to create) should be:

O1 00 01 11 10
0 0 0 1 0
1 1 0 1 X
O2 00 01 11 10
0 1 1 i 1
1 i 1 0 0

I believe the problem is that I am making a 3d array using the subroutine but I'm not sure what to do differently.

I receive the following errors in my webwork question (I get the same output for test.pg).

ERRORS from evaluating PG file:
Not a HASH reference at line 35 of setWorking/test2.pg
   from within main::wrapCell called at line 45 of setWorking/test2.pg
   from within main::convertRow called at line 51 of setWorking/test2.pg
   from within main::PGMLTable called at line 488 of setWorking/test2.pg
I know the issue isn't in PGMLTable, convertRow, or wrapCell as those work for all the other tables in this problem.

At first I thought the issue was that I was pushing making a 3d table (as per lines 493 to 498 in test.pg) but I fixed that in the scaled down version and it didn't fix the issue. I didn't realize I could only attach one file to this post. I've put the code mentioned here (that is different in test.pg) at the bottom of this post.

In test2.pg the subroutine is on lines 62 to 93
Using the subroutine is on lines 481 to 489.
I have commented out the lines that call the PGMLTables function on lines 491 and 494.

FYI: This question has code provided by Andrew Parker. Among his work is all of the PGML helper functions on lines 22 to 59.

----------------------------
Code from test.pg (not test2.pg the scaled back version)
The subroutine for all sizes of Kmaps 

sub KmapMaker {
    # row number locations in Kmap
    @kmapOrder = (
        [[0, 1], [2, 3]],
        [[0, 1, 3, 2], [4, 5, 7, 6]],
        [[0, 1, 3, 2], [4, 5, 7, 6], [12, 13, 15, 14], [8, 9, 11, 10]]
    );
    my $nVar = ($#_ == 16 ? 4 : ($#_ == 8 ? 3 : 2));
    my $nRow = ($nVar < 4 ? 2 : 4);
    my $nCol = ($nVar < 3 ? 2 : 4);
    my $label = shift;

    @cLabels;
    push @cLabels, $label;

    if ($nVar < 3) {
        push @cLabels, "0";
        push @cLabels, "1";
    } else {
        push @cLabels, "00";
        push @cLabels, "01";
        push @cLabels, "11";
        push @cLabels, "10";
    }
    
    @rLabels; 
    if ($nVar < 4) {
        @rLabels = ["0", "1"];
    } else {
        @rLabels = ["00", "01", "11", "10"];
    }
      

    my @kmap = ($cLabels);
    for $i (0 .. $nRow-1) {
        my @row;
        push @row, $rlabels[$i]; 
        for $j (0..$nCol-1) {
            push @row, $_[$kmapOrder[$nVar-2][$i][$j]];
        }
        push @{ $kmap[ $i + 1 ] }, ~~@row;
    }

    return @kmap;
}

Using the subroutine and making a 3d array .... I think

@kmapAns;
for my $i (0 .. $#f) {
    my @column;
      push @column, map {$ans[$i][$j]} (0 .. $numRows-1);
    push @kmapAns, KmapMaker($fLabel[$i], @column);
}
In reply to Nicole Wilson

Array construction problems, no idea how to fix it

by Alex Jordan -

Lines 34 and 35 of test2.pg are:

        my $data = shift @$cell;
        $opts = {%$cell};

The first of these lines expects $cell to be an array reference, and the second expects $cell to be a hash reference. I haven't dug into which kind of thing $cell is actually supposed to be, but there is some mistake here.

Does changing the latter line to
$opts = {@$cell};
fix things for you? For me it clears the error but I'm not paying attention to if the problem statement is what it should be and if answer checking is behaving as expected.

Once the perl error is removed though, there are PG warnings about how you are constructing the table. But there's a lot going on and I didn't dig deep to try to understand the table construction. Even the reduced test2.pg file is over 500 lines long. If you have a more minimal problem file I could look at, I might be able to suggest a more direct way to produce the PGML table.

In reply to Alex Jordan

Array construction problems, no idea how to fix it

by Nicole Wilson -
I appreciate you taking a look at this code but that approach will cause more problems for me than I have time to fix.
I've already used the PGMLTable subroutine 11 times in this problem so, I'm too deeply invested to change that.

Since it has worked for 11 other tables, I must be doing something different trying to make this table.

My biggest issue is that I have never written a subroutine before.

I have removed all the code that is not necessary for the Kmap to work from this version of the question.

You can see that the PGMLTable subroutine works three times
246 $PGMLLabelTable = PGMLTable(~~@fLabelTable);
247 $PGMLTable = PGMLTable(~~@table);
248 $PGMLAnsTable = PGMLTable(~~@ansTable);

But fails here
260 $PGMLAnsKMaps = PGMLTable(~~@kmapAns);

I'm trying to determine why @kmapAns has a different format than @fLabelTable, @table, @ansTable.

It has to be something in either "sub KmapMaker" (lines 62 to 93) or the creation of kmapAns (lines 250 to 258).
In reply to Nicole Wilson

Array construction problems, no idea how to fix it

by Alex Jordan -

Hi Nicole, in the test3 file, you have not made the change that I think is the main issue that I mentioned in the last post. Change line 35 from

$opts = {%$cell};

to

$opts = {@$cell};

After making that change, the problem will render.

For me at least, using the soon-to-be-released version 2.20 of WeBWorK, at this point I see tons of PG warnings that say "Table text must be in cells", which indicate that your string for the table is not using [. and .] surrounding some sort of content within the table.

In reply to Alex Jordan

Array construction problems, no idea how to fix it

by Nicole Wilson -
I have, I believe tracked down the errors in my KmapMaker subroutine or more accurately started over.

I build the subroutine in perl, where it does work, then brought it back to pg.
I have changed all instances of \@arrayName to ~~@arrayName
Is there an easy way to determine if the array returned by my function is correct?
Is there an easy way to determine if the array I am sending as a parameter contains the correct values?
In reply to Nicole Wilson

Array construction problems, no idea how to fix it

by Alex Jordan -
In case this is helpful...

Using test3 as an example, it has this line:
$PGMLLabelTable = PGMLTable(~~@fLabelTable);

and further below:
[$PGMLLabelTable]**

You could change those (respectively) to the following. I laid it out here with extra line breaks and comments to help understand how it works, but it doesn't need all the line breaks and comments.
$PGMLLabelTable = DataTable(
# one big array ref containing the rows of the table
[
# each row of the table is an array ref with three things
map {[
$fLabel[$_],
'=',
$f[$_]->TeX
]} (0 .. $#f)
],
# wrap each cell's content with math delimiters
encase => [$BM,$EM]
);

and:
[$PGMLLabelTable]*

and the output is identical. The idea here is to directly use the DataTable() subroutine instead of using PGML markup. If you gave the same treatment to the other tables, you would not need the PGMLTable subroutine, nor the subroutines it depends on (PGMLopts, convertRow, wrapCell).

Of course this is just an option. It may be easier to debug things without all those helper subroutines.