WeBWorK Problems

Setting up a chemistry problem

Setting up a chemistry problem

by Eric Stroyan -
Number of replies: 9
Sorry in advance for the length of this.
I am trying to set up a problem in which students are to predict the products of a chemical reaction.
The reactants and products are currently stored in a macro file with the following format
%reactions=(
1=>{equation=>"N_{2} + H_{2} \longrightarrow NH_{3}",
class=>"combination",
components=>[
{type=>"reactant", compound=>"N_{2}", coef=>1 },
{type=>"reactant", compound=>"H_{2}", coef=>3 },
{type=>"product", compound=>"NH_{3}", coef=>2 },]},
2=>{equation=>"P + O_{2} \longrightarrow P_{2}O_{5}",
class=>"combination",
components=>[
{type=>"reactant", compound=>"P", coef=>4 },
{type=>"reactant", compound=>"O_{2}", coef=>5 },
{type=>"product", compound=>"P_{2}O_{5}", coef=>2 },]},
3=>{equation=>"C_{2}H_{6} + O_{2} \longrightarrow CO_{2} + H_{2}O",
class=>"combustion",
components=>[
{type=>"reactant", compound=>"C_{2}H_{6}", coef=>2 },
{type=>"reactant", compound=>"O_{2}", coef=>7 },
{type=>"product", compound=>"CO_{2}", coef=>4 },
{type=>"product", compound=>"H_{2}O", coef=>6 },]},
4=>{equation=>"KClO_{3} \longrightarrow KCl + O_{2}",
class=>"decomposition",
components=>[
{type=>"reactant", compound=>"KClO_{3}", coef=>2 },
{type=>"product", compound=>"KCl", coef=>2 },
{type=>"product", compound=>"O_{2}", coef=>3 },]},

The problem that I have working asks the student to predict one of the two products (code attached). I would like to develop a problem with two (or more, as the reaction warrants) answer blanks that students would enter the products in LaTeX format. I have set one up that will check answers, the problem is the products must be in a specific order. I would like to be able to let students enter the products in any order. I'm pretty much shot as to how to do this.
Any suggestions/help would be appreciated.
In reply to Eric Stroyan

Re: Setting up a chemistry problem

by Michael Gage -
You can try this:

....
loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"PGchoicemacros.pl",
"PGanswermacros.pl",
"PGauxiliaryFunctions.pl",
#"rexn_type_rand_10.pl",
"MathObjects.pl",
"parserAutoStrings.pl",
);

TEXT(&beginproblem);
$showPartialCorrectAnswers = 1;
AutoStrings();

......

ANS(List( String("H_{2}"),String("H_[2]O") )->cmp);

I didn't have your macro file so I don't know which chemical formulas you want as an answer. The code above will accept either H_{2},H_[2]O or H_{2},H_[2]O as an answer. Put your answerstring inside the String()functions. The error messages for malformed strings may not be very helpful, otherwise I think it will work.


for more on MathObjects: http://webwork.maa.org/wiki/Category:MathObjects
In reply to Michael Gage

Re: Setting up a chemistry problem

by Eric Stroyan -
THanks.
I'll give that a try.
I've also attached the macro file I was using.
I'm trying to set up a general sort of problem so I only have to change the macro file to give access to a collection of different reactions.
In reply to Michael Gage

Re: Setting up a chemistry problem

by Eric Stroyan -
I tried the suggested code.
That will work for some types of problems, but I'm trying to produce something more general.
I'v attached what I currently have working (along with the macro file at the top of the pg file, I couldn't figure out how to attach two files). This will generate as many answer boxes as needed (some reactions have two or more products), but if the student does not enter answers in the same order as they appear in the macro file, the problem is marked wrong. I suppose I could give enough attempts to allow students to try all possible combinations, but I'd like to be able to restrict attempts to one in some cases.

Thanks again for your help.
In reply to Eric Stroyan

Re: Setting up a chemistry problem

by Davide Cervone -
I think the way to do this "right" is to create a context specifically for chemical reaction formulas. It would have operators + and -->, and possibly _ and implied multiplication as well. It would generate a new Reaction MathObject, and the equality check would compare the two reactions for equality. This would be done one an operator by operator basis, so that two --> nodes would be equal if their left-hand sides were equivalent and their right-hand sides are equivalent. Two + nodes would be equal if their operands were operands were equal, in either order. (Hmmm, that would only work for two reactants or products. Perhaps + would have to produce a list and they would be sorted and then compared).

One could then have the student write something like
4P + 5O_2 --> 2P_2O_5
(or with braces if you prefer).

It might be interesting for me to give this a try.

Davide
In reply to Davide Cervone

Re: Setting up a chemistry problem

by Eric Stroyan -
I agree that some reaction/chemical formulae specific macro would be the way to go. I've toyed with the idea of using pattern matching to extract information form a formula (or reaction) and use that to calculate molar masses and perform stoichiometric calculations.
I currently have a large number of formulae in a macro file with information as to the composition. I have another subroutine that I place in-line in a problem that will calculate formula masses (I've not been successful at placing it in the macros folder, the whole global/local variable nonsense. It ain't pretty but it works.)
I could send you copies of what I have if you are interested.
It always seems as I start to work on these things other matters get in the way. As mentioned I do have something that can be used, but I would need to give students multiple tries until the get the same ordering as that in the macro file describing the reaction.
In reply to Eric Stroyan

Re: Setting up a chemistry problem

by Davide Cervone -
I'm not talking about a macro, but an actual MathObject for reactions. Pattern matching for something like this is too fragile; you need the power of an actual formula parser, which is what MathObjects provides. The thing that is needed is the definitions required to make the parser understand chemical formulas, and that means a MathObject Context with the right definitions and support code.

I have put such a context together, and have added it to the pg/macros directory. You can get it from the HEAD version of the CVS repository. There are comments at the top of the file that explain how it works, which I also provide below.

I'm not a chemist, so I don't know if this is exactly what you need, but it looks like it should handle the problems that you illustrated in your initial question. Let me know if it needs adjusting.

Here is the documentation from the file:


contextReaction.pl - Implements a MathObject class for checmical reactions.

This file implements a Context in which checmical reactions can be specified and compared. Reactions can be composed of sums of integer multiples of elements (possibly with subscripts), separated by a right arrow (indicated by "-->"). Helpful error messages are given when a reaction is not of the correct form. Sums of compounds can be given in any order, but the elements within a compound must be in the order given by the correct answer; e.g., if the correct answer specifies CO_2, then O_2C would be marked incorrect.

To use the context include

    loadMacros("contextReaction.pl");
    Context("Reaction");
at the top of your PG file, then create Formula() objects for your reactions. For example:
    $R = Formula("4P + 5O_2 --> 2P_2O_5");
Reactions know how to create their own TeX versions (via $R->TeX), and know how to check student answers (via $R->cmp), just like any other MathObject.

The Reaction Context also allows you to create parts of reactions. E.g., you could create

    $products = Formula("4CO_2 + 6H_2O");
which you could use in a problem as follows:
    loadMacros("contextReaction.pl");
    Context("Reaction");

    $reactants = Formula("2C_2H_6 + 7O_2");
    $products  = Formula("4CO_2 + 6H_2O");

    Context()->texStrings;
    BEGIN_TEXT
    \($reactants \longrightarrow\) \{ans_rule(30)\}.
    END_TEXT
    Context()->normalStrings;

    ANS($products->cmp);

Note that sums and products are not simplified in any way, so that Formula("O + O") and Formula("2O") and Formula("O_2") are all different and unequal in this context.

All the elements of the periodic table are available within the Reaction Context. If you need additional terms, like "Heat" for example, you can add them as variables:

    Context()->variables->add(Heat => $context::Reaction::CONSTANT);
Then you can make formulas that include Heat as a term. These "constants" are not allowed to have coefficients or subscripts, and can not be combined with compounds except by addition. If you want a term that can be combined in those ways, use $context::Reaction::ELEMENT instead.


Hope that does what you need.

Davide

In reply to Davide Cervone

Re: Setting up a chemistry problem

by Eric Stroyan -
Thanks!
Wow you're fast.
I'll give it a try as soon as possible.
In reply to Eric Stroyan

Re: Setting up a chemistry problem

by Davide Cervone -
Not fast, but obsessive. :-)

Let me know how it works out.

Davide
In reply to Davide Cervone

Re: Setting up a chemistry problem

by Eric Stroyan -
Works nicely!
I've not played around with it any more than to set up a problem that randomly accesses reactions from a macro file.
As the week progresses I'll try some other things.
I've included the sample macro file and the pg file in-line below.
You certainly have saved me quite a bit of work.
Thanks again!

macro (rexn_rand_chemicalReaction.pl):
%reactions=(
1=>{equation=>"N_{2} + 3H_{2} \longrightarrow 2NH_{3}",
class=>"combination",
reactants=>"N_{2} + 3H_{2}",
products=>"2NH_{3}"},
2=>{equation=>"4P + 5O_{2} \longrightarrow 2P_{2}O_{5}",
class=>"combination",
reactants=>"4P + 5O_{2}",
products=>"2P_{2}O_{5}"},
3=>{equation=>"2C_{2}H_{6} + 7O_{2} \longrightarrow 4CO_{2} + 6H_{2}O",
class=>"combustion",
reactants=>"2C_{2}H_{6} + 7O_{2}",
products=>"4CO_{2} + 6H_{2}O"},
4=>{equation=>"2KClO_{3} \longrightarrow 2KCl + 3O_{2}",
class=>"decomposition",
reactants=>"2KClO_{3}",
products=>"2KCl + 3O_{2}"},
5=>{equation=>"NaHCO_{3} + HCl \longrightarrow NaCl + H_{2}O + CO_{2}",
class=>"neutralization",
reactants=>"NaHCO_{3} + HCl",
products=>"NaCl + H_{2}O + CO_{2}"},
);

Problem.
DOCUMENT();

loadMacros(
"PG.pl",
"PGbasicmacros.pl",
"PGchoicemacros.pl",
"PGanswermacros.pl",
"PGauxiliaryFunctions.pl",
"MathObjects.pl",
"Parser.pl",
"PGstandard.pl",
"rexn_rand_chemicalReaction.pl",
"contextReaction.pl");
Context("Reaction");

$count=keys %reactions;
@items=(1..$count);
$S = list_random(@items);

$reactants = $reactions{$S}{reactants};
$products = $reactions{$S}{products};

$react = Formula($reactants);
$prod = Formula($products);

Context()->texStrings;
BEGIN_TEXT
Predict the products for the following chemical reaction$BR
\($react \longrightarrow\) \{ans_rule(30)\}.
END_TEXT
Context()->normalStrings;

ANS($prod->cmp);
ENDDOCUMENT();