topical media & game development

game-javascript-math-kennedy-happyFractions.htm / htm

```
<html>
<title>Happy Fractions!</title>
<script language="JavaScript">
// constants
var kMultiplication = 'x';
var kAddition = '+';
var kSubtraction = '-';
var kDivision = '\367';  // this is the octal representation of the division sign.
//var kEquivalentFractions = '=';  // to be added later
// perhaps a test for simplifying fractions would be nice, too.

var gProblem1 = {fraction1:0, operation:kAddition, fraction2:0, anwer:0};
var gProblem2 = {fraction1:0, operation:kAddition, fraction2:0, anwer:0};

// functions
function assert(isTrue, message) { if (!isTrue) { alert(message) } }

function myPop (string){
var generator=window.open('',
'name',
'width=400,height=100,toolbar=0,scrollbars=0,screenX=200,screenY=200,left=200,top=200');

generator.document.write(string);
generator.document.write('<center><a href="javascript:self.close()">Close</a></center>');
generator.document.write('</body></html>');
generator.document.close();
}

function getCurrentTimeInSeconds(){
return Math.round(new Date().valueOf()/1000);
}

function isSimplified(){
// this case is an improper fraction...
if ((1*this.numerator) > (1*this.denominator)) { return false; }

// sorry this probably isn't efficient...
for (var i=2; i <= this.numerator; i++){
if (0 == (this.numerator\%i) &&
0 == (this.denominator\%i)){ return false; }
}
return true;
}

function Simplify(){
// sorry this probably isn't efficient...
var tempNumerator = this.numerator;
var tempDenominator = this.denominator;

if ((1*this.numerator) > (1*this.denominator)){
// on improper fractions, return...
}

for (var i=2; i <= this.numerator;){
if (0 == (tempNumerator\%i) &&
0 == (tempDenominator\%i)){
tempNumerator=tempNumerator/i;
tempDenominator=tempDenominator/i;
i=2;
}
else { i++ }
}
this.numerator=tempNumerator;
this.denominator=tempDenominator;
}

function Fraction(numerator, denominator){
/* assert(((1*numerator) < (1*denominator)),
"Fraction(" + numerator + ", " + denominator + "): don't support improper fractions.");
*/
this.numerator=1*numerator;
this.denominator=1*denominator;
this.toString = function(){return (this.numerator + "/" + this.denominator);};
this.toDecimal = function(){return (this.numerator/this.denominator);};
this.isSimplified = isSimplified;
this.Simplify = Simplify;
}

function ImproperFraction(numerator, denominator){
this.numerator=1*numerator;
this.denominator=1*denominator;
this.toString = function(){return (this.numerator + "/" + this.denominator);};
this.toDecimal = function(){return (this.numerator/this.denominator);};
this.isSimplified = isSimplified;
this.Simplify = Simplify;
}

assert((1>(fraction1.toDecimal()+fraction2.toDecimal())),
"AddFractions(" + fraction1 + ", " + fraction2 + "): don't support sums >= 1.");
var sum =
new Fraction((fraction1.numerator*fraction2.denominator+fraction2.numerator*fraction1.denominator),
fraction1.denominator*fraction2.denominator);
sum.Simplify();
return sum;
}

function SubtractFractions(fraction1, fraction2){
assert((fraction1.toDecimal() >= fraction2.toDecimal()),
"SubtractFractions: Negative answers are not handled.");

var difference =
new Fraction((fraction1.numerator*fraction2.denominator-fraction2.numerator*fraction1.denominator),
fraction1.denominator*fraction2.denominator);
difference.Simplify();
return difference;
}

function MultiplyFractions(fraction1, fraction2){
var product = new Fraction((fraction1.numerator*fraction2.numerator),
(fraction1.denominator*fraction2.denominator));
product.Simplify();
return product;
}

function DivideFractions(fraction1, fraction2){
var quotient = new Fraction((fraction1.numerator*fraction2.denominator),
(fraction1.denominator*fraction2.numerator));
quotient.Simplify();
return quotient;
}

function getRandomNumberInRange(rangeStart, rangeEnd){
if (rangeStart==rangeEnd) return rangeStart;
assert((rangeStart<rangeEnd),
"getRandomNumberInRange(" + rangeStart + ", " + rangeEnd + "): Invalid Input");
var randomNumber = Math.round(Math.random()*(rangeEnd-rangeStart));
return (rangeStart+randomNumber);
}

function getRandomFractionLessThanHalf(){
// this is an ugly function...
var maxDecimal = .49;
var numerator = getRandomNumberInRange(1, 4);
var firstValidDenominator = numerator+1;
while(maxDecimal<(numerator/firstValidDenominator)) { firstValidDenominator++; }
var denominator = getRandomNumberInRange(firstValidDenominator, 10);
var fraction = new Fraction(numerator, denominator);
fraction.Simplify();
assert((maxDecimal>=fraction.toDecimal()),
"getRandomFractionLessThan(): failed to create valid fraction.");
return fraction;
}

function getRandomFractionMoreThanHalf(){
// this is an ugly function...
var minDecimal = .5;
var denominator = getRandomNumberInRange(2, 10);
var firstValidNumerator = 1;
while(minDecimal>(firstValidNumerator/denominator)) { firstValidNumerator++; }
var numerator = getRandomNumberInRange(firstValidNumerator, denominator-1);
var fraction = new Fraction(numerator, denominator);
fraction.Simplify();
assert((minDecimal<=fraction.toDecimal() && 1>fraction.toDecimal()),
"getRandomFractionMoreThanHalf(): failed to create valid fraction.");
return fraction;
}

function requestHelp(){
var generator=window.open('','name','height=400,width=700,scrollbars=1');

generator.document.write('<h1><center>Happy Fractions!</center></h1>');

generator.document.write('Fractions show parts of a whole. ');
generator.document.write('You can <i>add</i>, <i>subtract</i>, <i>multiply</i>, and <i>divide</i> fractions.<br><br>');

generator.document.write('<h2><center>Parts of a Fraction</center></h2>');

generator.document.write('A fraction has three parts: <i>numerator</i>, <i>denominator</i>, and <i>fraction bar</i>.<br><br>');
generator.document.write('<i>Denominators</i> tell how many pieces make the whole.<br><br>');
generator.document.write('<i>Numerators</i> show how many pieces of the whole you have.<br><br>');

generator.document.write('<font color="blue">Example:</font> What fraction of stars are red?');
generator.document.write('<center><pre><font size="+3" color="red">*  *  *  *  *</font><br>');
generator.document.write('<font size="+3" color="green">*  *  *  *</font></center>');

generator.document.write('There are 9 stars. So the denominator is 9.<br>');
generator.document.write('Of the 9 stars, 5 are red stars. So the numerator is 5.<br><br>');

generator.document.write('<u>5</u> are red!<br>');
generator.document.write('9<br>');

generator.document.write('To add fractions, add the numerators of the fractions if the denominators are the same.   ');
generator.document.write('If the denominators are different then find equivalent fractions so the denominators are the same.<br><br>');

generator.document.write('<font color="blue">Example:</font> Add 1/5 and 2/3.<br>');

generator.document.write('<table border="0">');
generator.document.write('<tr><td><u>1</u></td><td rowspan="2">+</td><td><u>2</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>1 x 3</u></td><td rowspan="2">+</td><td><u>2 x 5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>3</u></td><td rowspan="2">+</td><td><u>10</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>13</u></td></tr>');
generator.document.write('<tr><td>5</td><td>3</td>');
generator.document.write('<td>5 x 3</td><td>3 x 5</td>');
generator.document.write('<td>15</td><td>15</td>');
generator.document.write('<td>15</td></tr></table>');

generator.document.write('<br><h2><center>Subtracting Fractions</center></h2>');

generator.document.write('When adding fractions, add the numerators of the fractions if the denominators are the same. ');
generator.document.write('If the denominators are different then you must find equivalent fractions so the denominators are the same.<br><br>');

generator.document.write('<font color="blue">Example:</font> Subtract  4/5 from 2/3.<br>');

generator.document.write('<table border="0">');
generator.document.write('<tr><td><u>4</u></td><td rowspan="2">-</td><td><u>5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>4 x 3</u></td><td rowspan="2">-</td><td><u>2 x 5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>12</u></td><td rowspan="2">-</td><td><u>10</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>2</u></td></tr>');
generator.document.write('<tr><td>5</td><td>3</td>');
generator.document.write('<td>5 x 3</td><td>3 x 5</td>');
generator.document.write('<td>15</td><td>15</td>');
generator.document.write('<td>15</td></tr></table>');

generator.document.write('<br><h2><center>Multiplying Fractions</center></h2>');
generator.document.write('Multiplying fractions is easy. ');
generator.document.write('Just multiply the numerators and denominators. ');
generator.document.write('<br><font color="blue">Example:</font><br>');
generator.document.write('<table border="0">');
generator.document.write('<tr><td><u>1</u></td><td rowspan="2">of</td><td><u>5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>1</u></td><td rowspan="2">x</td><td><u>5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>1 x 5</u></td><td rowspan="2">=</td><td><u>5</u></td></tr>');
generator.document.write('<tr><td>2</td><td>6</td>');
generator.document.write('<td>2</td><td>6</td>');
generator.document.write('<td>2 x 6</td><td>12</td></tr></table>');

generator.document.write('<h2><center>Dividing Fractions</center></h2>');
generator.document.write('8 \367 2/1  = 8 \367 2  = 8/2  = 4<br><br>');

generator.document.write('8 x  1/2 = 8/1 x 1/2 = 8 x 1/1 x 2 = 4<br><br>');

generator.document.write('Notice the answers are the same. ');
generator.document.write('When you divide fractions it is the same as multiplying by the reciprocal .  ');
generator.document.write('The reciprocal is when you make a new fraction by switching the numerator and denominator.<br>');
generator.document.write('<br><font color="blue">Example:</font><br>');
generator.document.write('What is 2/3 \367 5/2?. (<i>Note:</i> The reciprocal of 5/2 is 2/5.)<br>');

generator.document.write('<table border="0">');
generator.document.write('<tr><td><u>2</u></td><td rowspan="2">\367</td><td><u>5</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>2</u></td><td rowspan="2">x</td><td><u>2</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>2 x 2</u></td><td rowspan="2">=</td><td><u>4</u></td></tr>');
generator.document.write('<tr><td>3</td><td>2</td>');
generator.document.write('<td>3</td><td>5</td>');
generator.document.write('<td>3 x 5</td><td>15</td></tr></table>');

generator.document.write('<h2><center>Simplifying Fractions</center></h2>');
generator.document.write('Sometimes, we have ugly fractions that we can make simpler, nicer to look at. ');
generator.document.write('If you can divide the numerator and denominator of a fraction by the same number so there is no remainder, ');
generator.document.write('then you should simplify the fraction.<br>');
generator.document.write('<br><font color="blue">Example:</font> Simplify 45/99.<br>');

generator.document.write('<table border="0">');
generator.document.write('<tr><td><u>45</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>45 \367 9</u></td><td rowspan="2">=</td>');
generator.document.write('<td><u>5</u></td></tr>');
generator.document.write('<tr><td>99</td>');
generator.document.write('<td>99 \367 9</td>');
generator.document.write('<td>11</td></tr></table>');

generator.document.write('<br><br><b><center>Remember, ask your teacher if you do not understand.</center></b>');
generator.document.write('<center><a href="javascript:self.close()">Close this window.</a></center>');
generator.document.write('</body></html>');
generator.document.close();
}

function requestPrintTest(operation){
if (document.getElementById) {
// clear the old answers.
// clear old dynamically created table stuff.
clearChildNodes("problem1Num1");
clearChildNodes("problem1Num2");
clearChildNodes("problem2Num1");
clearChildNodes("problem2Num2");
clearChildNodes("problem1Operation");
clearChildNodes("problem2Operation");
clearChildNodes("problem1Den1");
clearChildNodes("problem1Den2");
clearChildNodes("problem2Den1");
clearChildNodes("problem2Den2");
clearChildNodes("problem1Results");
clearChildNodes("problem2Results");
clearChildNodes("testResults");

// assure bug-free redraw in Gecko engine by letting window show cleared table
if (navigator.product && navigator.product == "Gecko") {
setTimeout("printTest("+"'"+operation+"'"+")", 0);
}
else {
printTest(operation);
}
}
else {
alert("Sorry, dynamic table feature works with IE5 or later for Windows, and Netscape 6 or later.");
}
}

function requestPrintResults(){
// disable the "I am finished!" button
document.happyFractions.finishedButton.disabled=true;

if (document.getElementById) {
clearChildNodes("problem1Results");
clearChildNodes("problem2Results");
clearChildNodes("testResults");

// assure bug-free redraw in Gecko engine by letting window show cleared table
if (navigator.product && navigator.product == "Gecko") {
setTimeout("printResults()", 0);
}
else {
printResults();
}
}
else {
alert("Sorry, dynamic table feature works with IE5 or later for Windows, and Netscape 6 or later.");
}
}

function printTest(operation){
printChallengeProblems(operation);
enableFinishedButton();
}

function enableFinishedButton(){
// enable the "I am finished!" button
document.happyFractions.finishedButton.disabled=false;
}

// sorry this is probably inefficient
function getLCD(denominator1, denominator2){
if (denominator1 == denominator2) { return denominator1; }
else if (denominator1 < denominator2) { var lcd = denominator2; }
else { var lcd = denominator1; }

while (!((0 == (lcd % denominator1)) && (0 == (lcd % denominator2)))){
lcd++;
}
return lcd;
}

function constructSolutionString(fraction1, operation, fraction2, answer){
var problem = (fraction1 + " " + operation + " " + fraction2 + " = ");

switch(operation){
case kAddition: // fall through
case kSubtraction:
var lcd = getLCD(fraction1.denominator, fraction2.denominator);
var showHowToGetLCD = ("(" + fraction1.numerator + " x " + lcd/fraction1.denominator + ")/" +
"(" + fraction1.denominator + " x " + lcd/fraction1.denominator +
") " + operation + " (" +
fraction2.numerator + " x " + lcd/fraction2.denominator + ")/" +
"(" + fraction2.denominator + " x " + lcd/fraction2.denominator + ") = ");
var problemWithLCD = (fraction1.numerator*(lcd/fraction1.denominator) + "/" + lcd +
" " + operation + " " +
fraction2.numerator*(lcd/fraction2.denominator) + "/" + lcd + " = ");
return (problem + problemWithLCD + answer);
//return (problem + showHowToGetLCD + problemWithLCD + answer);
case kMultiplication:
var multiplyWork = ("(" + fraction1.numerator + " x " + fraction2.numerator + ")/(" +
fraction1.denominator + " x " + fraction2.denominator + ") = ");
return (problem + multiplyWork + answer);
case kDivision:
var recipricolFraction2 = (fraction2.denominator + "/" + fraction2.numerator);
var multiplyByRecipricol = (fraction1 + " x " + recipricolFraction2 + " = ");
var multiplyWork = ("(" + fraction1.numerator + " x " + fraction2.denominator + ")/(" +
fraction1.denominator + " x " + fraction2.numerator + ") = ");
return (problem + multiplyByRecipricol + multiplyWork + answer);
default:
alert("constructSolutionString(" + operation + "): bad operation.");
}
}

function printResults(){
// check their answers
var numCorrect = 2;

if ('' == document.happyFractions.answer1Num.value ||
numCorrect--;
writeTxtAtTDidOptions("problem1Results",
constructSolutionString(gProblem1.fraction1,
gProblem1.operation,
gProblem1.fraction2,
"-1", "red");
}
else{
numCorrect--;
writeTxtAtTDidOptions("problem1Results",
constructSolutionString(gProblem1.fraction1,
gProblem1.operation,
gProblem1.fraction2,
"-1", "red");
}
writeTxtAtTDidOptions("problem1Results",
("Simplify!  " + userAnswer1 + " = " + gProblem1.answer),
"-1", "red");
}
}

if ('' == document.happyFractions.answer2Num.value ||
numCorrect--;
writeTxtAtTDidOptions("problem2Results",
constructSolutionString(gProblem2.fraction1,
gProblem2.operation,
gProblem2.fraction2,
"-1", "red");
}
else{
numCorrect--;
writeTxtAtTDidOptions("problem2Results",
constructSolutionString(gProblem2.fraction1,
gProblem2.operation,
gProblem2.fraction2,
"-1", "red");
}
writeTxtAtTDidOptions("problem2Results",
("Simplify!  " + userAnswer2 + " = " + gProblem2.answer),
"-1", "red");
}
}

// print the results (the score)
if (2 == numCorrect)
writeTxtAtTDid("testResults", "Perfect!  Great Job!", "+2", "black");
else if (1 == numCorrect)
writeTxtAtTDid("testResults", "One correct. Try again.", "+1", "black");
else
writeTxtAtTDid("testResults", "Zero correct. Meme ange, you need to practice more.", "+1", "black");

}

function writeTxtAtTDid(tBodyID, string){
writeTxtAtTDidOptions(tBodyID, string, "+1", "black");
}

function writeTxtAtTDidOptions(tBodyID, string, sizeString, colorString){
var tbody = document.getElementById(tBodyID);
// create holder for accumulated tbody elements and text nodes
var frag = document.createDocumentFragment();

var font = document.createElement("font");
font.setAttribute("size", sizeString);
font.setAttribute("color", colorString);
var txt = document.createTextNode(string);
font.appendChild(txt);
frag.appendChild(font);

if (!tbody.appendChild(frag)) {
alert("This browser doesn't support dynamic tables.");
}
}

function printChallengeProblems(operation){
// problem1Num1                  problem1Num2         problem2Num1                problem2Num2
// ---------   problem1Operation ---------  =          --------- problem2Operation ---------  =
// problem1Den1                  problem1Den2         problem2Den1                problem2Den2
setProblems(operation);

writeTxtAtTDid("problem1Num1", gProblem1.fraction1.numerator);
writeTxtAtTDid("problem1Den1", gProblem1.fraction1.denominator);

writeTxtAtTDid("problem1Num2", gProblem1.fraction2.numerator);
writeTxtAtTDid("problem1Den2", gProblem1.fraction2.denominator);

writeTxtAtTDid("problem2Num1", gProblem2.fraction1.numerator);
writeTxtAtTDid("problem2Den1", gProblem2.fraction1.denominator);

writeTxtAtTDid("problem2Num2", gProblem2.fraction2.numerator);
writeTxtAtTDid("problem2Den2", gProblem2.fraction2.denominator);

writeTxtAtTDid("problem1Operation", gProblem1.operation);
writeTxtAtTDid("problem2Operation", gProblem2.operation);
}

function setProblems(operation)
{
gProblem1.operation=operation;
gProblem2.operation=operation;

switch(operation){
gProblem1.fraction1= getRandomFractionLessThanHalf();
gProblem1.fraction2= getRandomFractionLessThanHalf();
gProblem2.fraction1= getRandomFractionLessThanHalf();
gProblem2.fraction2= getRandomFractionLessThanHalf();
break;
case kSubtraction:
gProblem1.fraction1= getRandomFractionMoreThanHalf();
gProblem2.fraction1= getRandomFractionMoreThanHalf();
gProblem1.fraction2= getRandomFractionLessThanHalf();
gProblem2.fraction2= getRandomFractionLessThanHalf();

break;
case kMultiplication:
gProblem1.fraction1= getRandomFractionLessThanHalf();
gProblem1.fraction2= getRandomFractionLessThanHalf();
gProblem2.fraction1= getRandomFractionLessThanHalf();
gProblem2.fraction2= getRandomFractionLessThanHalf();
break;
case kDivision:
gProblem1.fraction1= getRandomFractionLessThanHalf();
gProblem2.fraction1= getRandomFractionLessThanHalf();
gProblem1.fraction2 = new ImproperFraction(getRandomNumberInRange(2,4),
getRandomNumberInRange(1,2));
gProblem2.fraction2 = new ImproperFraction(getRandomNumberInRange(2,4),
getRandomNumberInRange(1,2));
gProblem1.fraction2.Simplify();
gProblem2.fraction2.Simplify();
break;
default:
alert("setProblems(" + operation + "): Bad operation!");
}
}

// Remove existing content of an element
function clearChildNodes(elemID) {
var elem = document.getElementById(elemID);
while (elem.childNodes.length > 0)
{
elem.removeChild(elem.firstChild);
}
}
</script>

<table width="100%" valign="top" align="center"><tr>
<td align="left"><b>
<font face="Comic Sans MS" size="+2" color="Black">Happy Fractions!</font>
</b></td>
<td><b><a href="javascript:requestPrintTest('+');" style="text-decoration: none">
<font size="+4" color="brown">+</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('-');" style="text-decoration: none">
<font size="+4" color="blue">&#150</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('x');" style="text-decoration: none">
<font size="+4" color="red">&#215;</font></a></b></td>
<td><b><a href="javascript:requestPrintTest('\367');" style="text-decoration: none">
<font size="+4" color="green">&#247;</font></a></b></td>
<td><b><a href="javascript:requestHelp();" style="text-decoration: none">
<font size="+4" color="purple">?</font></a></b></td>
<td align="right"><font size="-1">
<a href="javascript:myPop('Made in Namibia for Namibians to improve their fraction skills...
Tested in IE6, Mozilla Firefox and Konqueror.');">About This Site</a> |
<a href="mailto:aarontkennedy@gmail.com">;Suggestions</a>
</font></td>
</tr></table><br><br>

<form name="happyFractions">
<table align="center" width="80%" border="0">
<tr>
<td align="center" width="6%" id="problem1Num1"></td>
<td align="center" width="6%"></td>
<td align="center" width="6%" id="problem1Num2"></td>
<td width="6%"></td>
<td align="center" width="6%"><input type"text" size="3" name="answer1Num"></td>
<td align="center" width="40%"></td>
<td align="center" width="6%" id="problem2Num1"></td>
<td width="6%"></td>
<td align="center" width="6%" id="problem2Num2"></td>
<td width="6%"></td>
<td align="center" width="6%"><input type"text" size="3" name="answer2Num"></td>
</tr>
<tr>
<td align="center">
<td align="center" id="problem1Operation"></td>
<td align="center"><font size="+1">
<td align="center"><font size="+1">=</font></td>
<td align="center"><font size="+1">
<td></td>
<td align="center">
<td align="center" id="problem2Operation"></td>
<td align="center"><font size="+1">
<td align="center"><font size="+1">=</font></td>
<td align="center"><font size="+1">
</tr>
<tr>
<td align="center" id="problem1Den1"></td>
<td></td>
<td align="center" id="problem1Den2"></td>
<td></td>
<td align="center"><input type"text" size="3" name="answer1Den"></td>
<td></td>
<td align="center" id="problem2Den1"></td>
<td></td>
<td align="center" id="problem2Den2"></td>
<td></td>
<td align="center"><input type"text" size="3" name="answer2Den"></td>
</tr>
</table>

<table align="center" border="0">
<tr><td align="center" id="problem1Results"></td></tr>
<tr><td align="center" id="problem2Results"></td></tr>
<tr><td align="center" id="testResults"></td></tr>
</table>

<center>
<input name="finishedButton" type="button" value="I am finished!"
onClick="requestPrintResults();  return false;">
</center>
</form><br>

<table width="100%" border="0" valign="bottom" align="center"><tr>
<td align="center"><a href="javascript:requestPrintTest('+');" style="text-decoration: none">
<td align="center"> | </td>
<td align="center"><a href="javascript:requestPrintTest('-');" style="text-decoration: none">
<font size="-1" color="blue">Subtraction</font></a></td>
<td align="center"> | </td>
<td align="center"><a href="javascript:requestPrintTest('x');" style="text-decoration: none">
<font size="-1" color="red">Multiplication</font></a></td>
<td align="center"> | </td>
<td align="center"><a href="javascript:requestPrintTest('\367');" style="text-decoration: none">
<font size="-1" color="green">Division</font></a></td>
<td align="center"> | </td>
<td align="center"><a href="javascript:requestHelp();" style="text-decoration: none">
<font size="-1" color="purple">Help Me!</font></a></td>
</tr></table>

</body>
</html>
```

(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.