Skip to content

Commit

Permalink
Add hints and use custom answer-type in congruency_postulates
Browse files Browse the repository at this point in the history
  • Loading branch information
beneater committed Dec 27, 2011
1 parent f121bfd commit 6bcf8d2
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 53 deletions.
158 changes: 151 additions & 7 deletions exercises/congruency_postulates.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
<meta charset="UTF-8" />
<title>Congruency Postulates</title>
<script src="../khan-exercise.js"></script>
<style>
div#triangles {
outline-color: #999;
outline-style: dashed;
outline-width: 1px;
}
</style>
</head>
<body>
<div class="exercise">
Expand Down Expand Up @@ -35,6 +42,7 @@
<var id="REFLECTED">randRange( 0, 1 ) === 1 ? true : false</var>
<var id="ANSWER">{ "SSS": "Yes", "SAS": "Yes", "SAA": "Yes", "ASA": "Yes", "SSA": "No", "AAA": "No" }[ TYPE ]</var>
<var id="TRIANGLE">new Triangle( [ 0, 0 ], ANGLES, SCALE, {} )</var>
<var id="ROTATION">randRange( 0, 360 )</var>
</div>
<p class="problem">
<strong>Is <em><var>NAME</var></em> a triangle congruency postulate?</strong><br />
Expand All @@ -50,7 +58,7 @@
addMouseLayer();
initCongruence({ triangle: TRIANGLE, type: TYPE, reflected: REFLECTED });

TRIANGLE.rotate( randRange( 0, 360 ) );
TRIANGLE.rotate( ROTATION );
style({ stroke: "#b1c9f5", "stroke-width": 5 });
TRIANGLE.translate([
-5 - Math.min(TRIANGLE.points[0][0], TRIANGLE.points[1][0], TRIANGLE.points[2][0]),
Expand All @@ -62,12 +70,148 @@
</div>
</div>

<div class="solution" data-type="congruence">
<ul>
<li><input type="radio" name="solution" id="r1" value="Yes" /><label for="r1"><span class="value">Yes &mdash; And I've constructed a congruent triangle.</span></label></li>
<li><input type="radio" name="solution" id="r2" value="No" /><label for="r2"><span class="value">No &mdash; And I've proven it by constructing an incongruent triangle.</span></label></li>
</ul>
<div class="answer"><var>ANSWER</var></div>
<div class="solution" data-type="custom">
<div class="instruction">
<ul>
<li><input type="radio" name="solution" id="r1" value="Yes" /><label for="r1"><span class="value">
Yes &mdash; And I've constructed a congruent triangle.
</span></label></li>
<li><input type="radio" name="solution" id="r2" value="No" /><label for="r2"><span class="value">
No &mdash; And I've proven it by constructing an incongruent triangle.
</span></label></li>
</ul>
</div>
<div class="guess">[
jQuery( "#solutionarea" ).find( "input:checked" ).val(),
interactiveTriangle.points[0].coord,
interactiveTriangle.points[1].coord,
interactiveTriangle.points[2].coord,
interactiveTriangle.points[3].coord
]</div>
<div class="validator-function">
var saved = jQuery.map( new Array( 4 ), function( el, n ) {
return [ interactiveTriangle.points[ n ].coord ];
});
jQuery.map( guess.slice( 1 ), function( el, n ) {
interactiveTriangle.points[ n ].setCoord( el );
});
interactiveTriangle.update();
var isTriangle = interactiveTriangle.isTriangle;
var isCongruent = abs( getDistance( guess[1], guess[2] ) - TRIANGLE.sideLengths[ 0 ] ) &lt; 0.001
&amp;&amp; abs( getDistance( guess[2], guess[3] ) - TRIANGLE.sideLengths[ 1 ] ) &lt; 0.001
&amp;&amp; abs( getDistance( guess[3], guess[4] ) - TRIANGLE.sideLengths[ 2 ] ) &lt; 0.001;
jQuery.map( saved, function( el, n ) {
interactiveTriangle.points[ n ].setCoord( el );
});
interactiveTriangle.update();
if ( guess[0] == null ) {
return "";
} else if ( guess[0] !== ANSWER ) {
return false;
} else if ( !isTriangle ) {
return "Your answer is almost correct, but you haven't constructed a triangle.";
} else if ( ANSWER === "No" &amp;&amp; isCongruent ) {
return "Your answer is almost correct, but the two triangles are congruent. Prove your answer by trying to construct an incongruent triangle.";
} else {
return true;
}
</div>
<div class="show-guess">
jQuery.map( guess.slice( 1 ), function( el, n ) {
interactiveTriangle.points[ n ].setCoord( el );
});
interactiveTriangle.update();
</div>
<div class="show-guess-solutionarea">
jQuery( "#solutionarea" ).find( "input:checked" ).prop( 'checked', false );
if ( guess[0] != null ) {
jQuery( "#solutionarea" ).find( "input[value=" + guess[0] + "]" ).prop( 'checked', true );
}
</div>
</div>

<div class="hints">
<p>
To be a congruency postulate, there must be one, <em>and only one</em>, way to make a triangle
that's the same as the original triangle&mdash;except for being moved, rotated, or reflected.
</p>
<p data-if="ANSWER === 'Yes'">
With the constraints of <var>NAME</var>, there is exactly one way to make a triangle.
</p>
<p data-if="ANSWER === 'Yes'">
<strong><var>NAME</var> is a congruency postulate.</strong> Be sure to construct the congruent triangle and think
about why you're only able to construct the triangle in one way.
</p>

<p data-if="TYPE === 'SSA'">
With the constraints of <var>NAME</var>, there is more than one way to construct a triangle. See if you can find both ways.
</p>
<div data-if="TYPE === 'SSA'">
<p>Both of these triangles have the same adjacent Side, Side, and Angle, but they are not congruent:
<div class="graphie">
var triangle = new Triangle( [ 0, 0 ], ANGLES, SCALE, {} );
triangle.rotate( -ANGLES[1] );
init({ range: triangle.boundingRange( 0.4 ) });
addMouseLayer();
style({ stroke: "#b1c9f5", "stroke-width": 5 });
path( [ lineMidpoint( triangle.sides[ 2 ] ), triangle.points[2], triangle.points[1], triangle.points[0], lineMidpoint( triangle.sides[ 2 ] ) ] );
addTriangleDecorations( triangle, TYPE );
KhanUtil.currentGraph = jQuery( "div#triangles" ).data().graphie
</div>
<div class="graphie">
var points = [
[
TRIANGLE.sideLengths[ 1 ] - cos( ( 180 - ( 180 - ANGLES[ 0 ] ) - ANGLES[ 2 ] ) * PI / 180 ) * TRIANGLE.sideLengths[ 0 ],
-sin( ( 180 - ( 180 - ANGLES[ 0 ] ) - ANGLES[ 2 ] ) * PI / 180 ) * TRIANGLE.sideLengths[ 0 ]
],
[ TRIANGLE.sideLengths[ 1 ], 0 ],
[ 0, 0 ]
];
var triangle = new Triangle( [], [], 0, {}, points );
init({ range: triangle.boundingRange( 0.4 ) });
addMouseLayer();
style({ stroke: "#b1c9f5", "stroke-width": 5 });
path( [ lineMidpoint( triangle.sides[ 2 ] ), triangle.points[2], triangle.points[1], triangle.points[0], lineMidpoint( triangle.sides[ 2 ] ) ] );
addTriangleDecorations( triangle, TYPE );
KhanUtil.currentGraph = jQuery( "div#triangles" ).data().graphie
</div>
</div>
<p data-if="TYPE === 'SSA'">
Because we can create two triangles that are not congruent, we can show by counterexample that
<strong>Side-Side-Angle is not a congruency postulate.</strong> Be sure to construct the incongruent triangle above to prove it.
</p>

<p data-if="TYPE === 'AAA'">
With the constraints of <var>NAME</var>, there is more than one way to construct a triangle. See if you can find some different ways.
</p>
<div data-if="TYPE === 'AAA'">
<p>Both of these triangles have the same three angles, but they are not congruent (just similar):
<div class="graphie" style="float: left">
style({ stroke: "#b1c9f5", "stroke-width": 5 });
init({ range: TRIANGLE.boundingRange( 0.4 ) });
addMouseLayer();
style({ stroke: "#b1c9f5", "stroke-width": 5 });
path( [ lineMidpoint( TRIANGLE.sides[ 2 ] ), TRIANGLE.points[2], TRIANGLE.points[1], TRIANGLE.points[0], lineMidpoint( TRIANGLE.sides[ 2 ] ) ] );
addTriangleDecorations( TRIANGLE, TYPE );
KhanUtil.currentGraph = jQuery( "div#triangles" ).data().graphie
</div>
<div class="graphie" style="float: left">
var triangle = new Triangle( [ 0, 0 ], ANGLES, SCALE - 4, {} );
triangle.rotate( ROTATION );
style({ stroke: "#b1c9f5", "stroke-width": 5 });
init({ range: triangle.boundingRange( 0.4 ) });
addMouseLayer();
style({ stroke: "#b1c9f5", "stroke-width": 5 });
path( [ lineMidpoint( triangle.sides[ 2 ] ), triangle.points[2], triangle.points[1], triangle.points[0], lineMidpoint( triangle.sides[ 2 ] ) ] );
addTriangleDecorations( triangle, TYPE );
KhanUtil.currentGraph = jQuery( "div#triangles" ).data().graphie
</div>
</div>
<p data-if="TYPE === 'AAA'" style="clear: left">
Because we can create triangles that are not congruent, we can show by counterexample that
<strong>Angle-Angle-Angle is not a congruency postulate.</strong> Be sure to construct an incongruent triangle above to prove it.
</p>

</div>
</div>

Expand Down
12 changes: 8 additions & 4 deletions utils/answer-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ jQuery.extend( Khan.answerTypes, {
var guess = jQuery( this ).is( ":checked" ),
answer = jQuery( this ).data( "solution" ),
label_text = jQuery( this ).closest( "label" ).text();
if (label_text == "") {
if (label_text === "") {
label_text = "checked";
}
// un-checked boxes are recorded as "" to prevent the question from
Expand Down Expand Up @@ -957,19 +957,23 @@ jQuery.extend( Khan.answerTypes, {
return jQuery( el ).html();
});
ret.solution = "custom";
var showGuessSolutionCode = jQuery( solution ).find( ".show-guess-solutionarea" ).text() || "";
ret.showGuess = function( guess ) {
if ( isTimeline ) {
guessCorrect = validator( guess );
jQuery( solutionarea ).empty();
jQuery( solutionarea ).append( guessCorrect ? "Answer correct" : "Answer incorrect" );
jQuery( solutionarea ).append( guessCorrect === true ? "Answer correct" : "Answer incorrect" );
} else {
var code = "(function() { var guess = " + ( JSON.stringify( guess ) || "[]" ) + ";" + showGuessSolutionCode + "})()";
KhanUtil.tmpl.getVAR( code, KhanUtil.currentGraph );
}
}
};

var showGuessCode = jQuery( solution ).find( ".show-guess" ).text();
ret.showCustomGuess = function( guess ) {
var code = "(function() { var guess = " + JSON.stringify( guess ) + ";" + showGuessCode + "})()";
KhanUtil.tmpl.getVAR( code, KhanUtil.currentGraph );
}
};

return ret;
}
Expand Down
43 changes: 1 addition & 42 deletions utils/congruence.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ jQuery.extend( KhanUtil, {
triangle.isTriangle = true;
triangle.rotationPoint.setCoord([
1/3 * (triangle.points[0].coord[0] + triangle.points[1].coord[0] + triangle.points[2].coord[0]),
1/3 * (triangle.points[0].coord[1] + triangle.points[1].coord[1] + triangle.points[2].coord[1]),
1/3 * (triangle.points[0].coord[1] + triangle.points[1].coord[1] + triangle.points[2].coord[1])
]);
} else {
triangle.isTriangle = false;
Expand Down Expand Up @@ -674,44 +674,3 @@ jQuery.extend( KhanUtil, {
}

});


jQuery.extend( Khan.answerTypes, {
congruence: function( solutionarea, solution, fallback, verifier, input ) {
jQuery( solutionarea ).append( jQuery( solution ).clone().contents().tmpl() );
var correct = solutionarea.find( ".answer" ).text();
solutionarea.find( ".answer" ).empty();

ret = function() {
var triangle = KhanUtil.currentGraph.interactiveTriangle;
var guess = solutionarea.find( "input:checked" ).val();
ret.guess = [ guess, triangle.points[0].coord, triangle.points[1].coord, triangle.points[2].coord, triangle.points[3].coord ];
if ( guess === undefined ) {
// no guess, don't grade answer
ret.guess = "";
return false;
} else if ( guess !== correct) {
return false;
} else if ( !triangle.isTriangle) {
return "Your answer is almost correct, but you haven't constructed a triangle.";
} else if ( correct === "No" && triangle.isCongruent ) {
return "Your answer is almost correct, but the two triangles are congruent. Prove your answer by trying to construct an incongruent triangle.";
} else {
return true;
}
};
ret.examples = [ "the shapes to the left are part of your answer" ];
ret.solution = correct;
ret.showGuess = function( guess ) {
var triangle = KhanUtil.currentGraph.interactiveTriangle;
solutionarea.find( "input:checked" ).prop( 'checked', false );
solutionarea.find( "input[value=" + guess[0] + "]" ).prop( 'checked', true );
triangle.points[0].setCoord(guess[1]);
triangle.points[1].setCoord(guess[2]);
triangle.points[2].setCoord(guess[3]);
triangle.points[3].setCoord(guess[4]);
triangle.update();
};
return ret;
}
});

0 comments on commit 6bcf8d2

Please sign in to comment.