Forum archive 2000-2006

Edgar Fisher - Dynamic tables in text

Edgar Fisher - Dynamic tables in text

by Arnold Pizer -
Number of replies: 0
inactiveTopicDynamic tables in text topic started 6/15/2005; 7:14:15 PM
last post 7/3/2005; 5:17:58 PM
userEdgar Fisher - Dynamic tables in text  blueArrow
6/15/2005; 7:14:15 PM (reads: 1534, responses: 12)
Does anyone know of a way to build dynamic tables in the PG files? I have tried push onto a list and then joining with empty strings. It only generates table (html table) cells if I try it with ans_rule(#). Any help would be appreciated.

<| Post or View Comments |>


userDavide P. Cervone - Re: Dynamic tables in text  blueArrow
6/15/2005; 7:23:13 PM (reads: 1775, responses: 0)
Would you be a little more specific about what you are trying to do?

Davide

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
6/15/2005; 7:25:38 PM (reads: 1807, responses: 0)
I am trying to generate a table that has $size number of cells per row. In the first row I want to put in descriptive values, like Item 1, Item 2, etc. Then the next row would have an ans_rule(#) beneath each Item so that the answer could be placed directly below the value. I do not know previously how many items I will have, so can't (and also don't want) to do it beforehand.

<| Post or View Comments |>


userMichael Gage - Re: Dynamic tables in text  blueArrow
6/15/2005; 8:29:09 PM (reads: 1810, responses: 0)
The description at http://webhost.math.rochester.edu/webworkdocs/docs/pglanguage/pod/pgbasicmacros#macros_for_handling_tables should help. It defines the macros
begintable()
row()
and
endtable()

The files listed at http://webhost.math.rochester.edu/webworkdocs/docs/pglanguage/pgreference/ present one way to get at the "pod" documentation in each of the macro files. It's not always complete, but it's a place to start.

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
6/16/2005; 12:05:10 AM (reads: 1829, responses: 1)
This is what I have so far. I get the table idea, but I don't know how to have it be dynamically generated. That is, dynamic rows, info, values, etc. (There are some useless "for" loops right now because of testing purposes). The final for loop is for the list of ans_rule(5)'s evaluation. That by itself is a neat thing to have, so we are now working on the dynamic table.

 

for ($i = 0; $i < 1; $i++){
for ($j = 0; $j < $total; $j++){
$k = $j + 1;
push @table, $k, ', ';
}
pop @table;
}



TEXT $teststr = join '', @table;



for ($j = 0; $j < $total; $j++){
push @table, ans_rule(5);
}

BEGIN_TEXT
\{begintable(horiz_center=>'yes')}
{row('Subject','Mean','Stand. dev.'," score", " z score")}
{row(1, 1, 1, 'grade1', 'A')}
{row(2, 2, 2, 'grade2', 'B')}
{row(3, 3, 3, 'grade3', 'C')}
{row(4, 4, 4, 'grade4', 'D')}
{endtable()}
$PAR
{begintable($total)}
{join '', @table}
{row($teststr)}
{endtable()}
END_TEXT
for ($j = 0; $j < $total; $j++){
ANS(num_cmp($j+1));
<pre>
}

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
6/16/2005; 12:18:12 AM (reads: 1783, responses: 0)
If you test the code, the first table is generated nicely (I used horiz_center=>yes to try and center values horizontally) and the second generates a non-table entry, 15 cells in the table (the ans_rule's) and then a single cell which has the list from 1 to 15. I am trying to get the 1 to 15 single cell into 15 seperate cells in their own row.

<| Post or View Comments |>


userDavide P. Cervone - Re: Dynamic tables in text  blueArrow
6/16/2005; 7:59:11 AM (reads: 2123, responses: 0)
There are at least four mistakes that I see: first, the join '',@table that is in your BEGIN_TEXT...END_TEXT block it going to fall outside the table, since it is not containied in a row(), and second, row($teststr) is going to produce a row with only one entry because you passsing it a list of only one element (the string whose contents is a bunch of numbers separated by commas). The third error is that you haven't cleared out the @table array before you start pushing the answer rules onto it, so the table array will include all the numbers and commas as well as the answer rules. Finally, the begintable(horiz_center=>'yes') is not right. The begintable() command needs a column count as its parameter, not an attribute list. You need to use begintable($total) instead. There is no way to get centered values using begintable().

You can solve the last problem by adding @table = (); before the loop that pushes answer rules.

You could overcome the first problem by using row(@table) instead of join '', @table.

For the second problem, however, you can't use the string you created earlier, you need the array, so you probably want to keep a second array, one for the numbers, and one for the answer rules.

 


Here's my version of the problem:

 

    $total = 5;


for ($j = 1; $j <= $total; $j++) {
push @row1, $j;
push @row2, ans_rule(5);
push @cmp, num_cmp($j);
}


BEGIN_TEXT
\{
begintable(5) .
row('Subject','Mean','Stand. dev.','score','z score') .
row(1, 1, 1, 'grade1', 'A') .
row(2, 2, 2, 'grade2', 'B') .
row(3, 3, 3, 'grade3', 'C') .
row(4, 4, 4, 'grade4', 'D') .
endtable()
\}
$PAR
\{
begintable($total) .
row(@row1) .
row(@row2) .
endtable()
\}
END_TEXT


ANS(@cmp);

Here I have made several changes in addition to those discussed above. First, I got rid of the needless $i loop, and run the $j loop starting at 1 rather than 0 (avoiding the need for $k). Then I create three separate arrays, all in the same loop: @row1 contains the numbers used in row 1 of the table, @row2 contains the answer rules for row 2, and @cmp contains the answer evaluators to be submitted to ANS(). This puts all the information for one column together in one place, rather than scattered all over the problem, so it is more likely that the answer checkers and answers will match in the end.

Next, I put the table calls into a single \{...\} pair to make it easier to read. The commands are separated by ".", which is the string concatenation operator, so the combined result of all the table calls is the result. Note that the second table is made from the row of numbers and the row of answer rules.

The ANS() call takes the array of answer checkers and assigns them each to an answer blank.

 


I mentioned above that begintable() does not allow you to center the values. It also doesn't give you control over the spacing or other attributes of the table, and it always produces HTML tables with borders. There is an alternative set of table macros in unionTables.pl in the Union College union_problib/macros directory. The macros there give you more control over the spacing and alignment of the entries, and can produce tables without borders. Read the comments in that file to see how to control the macros.

Here is a version of the problem using those macros:

 

    loadMacros(
"unionMacros.pl",
"unionTables.pl"
);


$total = 5;


for ($j = 1; $j <= $total; $j++) {
push @row1, $j;
push @row2, ans_rule(5);
push @cmp, num_cmp($j);
}


%ropts = (separation=>0); # options for the table rows
sub BOLD {$BBOLD.(shift).$EBOLD};


BEGIN_TEXT
\{
BeginTable(border => 1, padding => 3, spacing => 2) .
AlignedRow([BOLD('Subject'),BOLD('Mean'),BOLD('Stand. dev.'),
BOLD('score'),BOLD('z score')],%ropts) .
AlignedRow([1, 1, 1, 'grade1', 'A'],%ropts) .
AlignedRow([2, 2, 2, 'grade2', 'B'],%ropts) .
AlignedRow([3, 3, 3, 'grade3', 'C'],%ropts) .
AlignedRow([4, 4, 4, 'grade4', 'D'],%ropts) .
EndTable()
\}
$PAR
\{
BeginTable(spacing => 3) .
AlignedRow([@row1],%ropts) .
AlignedRow([@row2],%ropts) .
EndTable()
\}
END_TEXT


ANS(@cmp);

Here the rows are generated as before. We use options to BeginTable() to specify the border size and extra spacing around the entries in the table, and AlignedRow() to get centered rows. The %ropts hash is used to give the same parameters to all rows; in this case, we override the default row separation. Note that while row() takes an array of enteries, AlignedRow() (and Row(), not used here) takes a reference to an array of entries, followed by options that affect the row. That's why the square brackets are used.

I also put the table headings in bold, to make them stand out more. That is done through the BOLD() command defined just before the first table.

 


Anyway, hope that clears things up for you.

Davide

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
6/16/2005; 12:18:11 PM (reads: 1756, responses: 1)
Thank you. That solves the problem. I knew that the table requested a column total, but it didn't seem to matter what I put in it so long as it wasn't empty. Thank you for the other option as well. Is it important to have the commas and periods at the end of the lines to continue the perl box?

<| Post or View Comments |>


userDavide P. Cervone - Re: Dynamic tables in text  blueArrow
6/16/2005; 1:43:53 PM (reads: 2030, responses: 0)
I knew that the table requested a column total, but it didn't seem to matter what I put in it so long as it wasn't empty.

The number of columns gets used only the TeX output, and is crucial there. So you would not see any problem until you tried to get hardcopy of the problem. Some authors forget about this crucial part of the development process: actually put the problem into a problem set and make a hardcopy of it to make sure there is no problem there. Problems that work fine on screen can fail completely in TeX output, as a completely different set of code is invoked by the hardcopy process.

 

Is it important to have the commas and periods at the end of the lines to continue the perl box?

Yes, they are important. The periods are Perl's string concatenation operator, so the periods at the ends of the lines combine the output of all the table and row commands and one big string out of all of them. If you didn't use them, you would get errors about missing operator. If you used commas or semicolons, you would not get all the complete table (only the result of the last command). So yes, you must have the periods. I'm not sure which comma you are talking about, but if it's there, you probably need it.

Davide

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
6/16/2005; 2:23:35 PM (reads: 1752, responses: 0)
That clears it up. Thank you. The comma to which I was refering was inside an AlignedRow, so was needed. Thanks again for the help.

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
7/3/2005; 2:06:58 PM (reads: 1742, responses: 0)
I have used these techniques and the result is as predicted. Now I am wanting to create a dynamic number of rows. I have tried a for loop inside { begintable(#)}. Any ideas?

<| Post or View Comments |>


userDavide P. Cervone - Re: Dynamic tables in text  blueArrow
7/3/2005; 5:00:06 PM (reads: 1719, responses: 0)
One way to do it would be te set up a string ahead of time that is the table. You can add rows to it dynamically and then simply insert the string into the text at the appropriate place. For example:

 

        $table = BeginTable(spacing => 3);
foreach $i (1..4) {$table .= AlignedRow([$i,$i,$i])}
$table .= EndTable();


BEGIN_TEXT
Here's the table:
$PAR
$table
END_TEXT

This table should produce the table

     1     1     1
2 2 2
3 3 3
4 4 4
(I didn't test the code, but I think it is right.)

Davide

<| Post or View Comments |>


userEdgar Fisher - Re: Dynamic tables in text  blueArrow
7/3/2005; 5:17:58 PM (reads: 1729, responses: 0)
Wow! You are good. First try and it is up and running. Thank you very much for your knowledge and your willingness and ability to share it.

<| Post or View Comments |>