New exercise: Interactive telling time #8913

Merged
merged 42 commits into from Jan 3, 2012

Conversation

Projects
None yet
4 participants
Contributor

stephjang commented Dec 18, 2011

Trello bug: "Telling time, interactive" in "Queued up"
Feedback much appreciated!

CHANGED

telling_time_interactive.html

  • "Set the clock to 3:45". User moves clock hands accordingly.
  • Hints might need some editing from a more experienced hint-writer.

time.js

  • Copied and extended analogClock() from graphie-helpers.js to a more customizable addAnalogClock() function (modeled after addMovablePoint()) inside time.js
  • NOTE: the functions coordToDegrees() and degreesToCoord() may belong in other packages. Any ideas where?
  • NOTE: roundToNearest() belongs in math.js. See below.

interactive.js

  • Added a snapPoints option to movablePoint.constraints.fixedDistance to allow snapping around a circle (fixedDistance restricts the point's motion to a circle). snapPoints is the number of points that can be snapped to around the circle.
  • NOTE: to implement this functionality, there is a bit of redundancy with functions in angles.js and time.js, but this might be unavoidable since interactive.js may be used without the others.

angle.js

  • Added toDegrees() function

NO CHANGE CURRENTLY, BUT SHOULD CHANGE

telling_time.html & telling_time_0.5.html

  • NOTE: should be updated using new time.js package (if accepted)

math.js

  • NOTE: I tried to add roundToNearest() (currently in time.js) to math.js but for some reason I couldn't get it to work. Something about how math.js is compiled? Is it a special file compared to the others?

graphie-helpers.js

  • NOTE: if time.js is accepted and telling_time.html & telling_time_0.5.html are updated, we should remove the analogClock() function from here.
Contributor

stephjang commented Dec 18, 2011

Oh dang, I just saw that someone else attempted this already: #6362. But it seems they didn't finish...

Contributor

stephjang commented Dec 18, 2011

Whoops, I didn't mean to commit the changes to unit_circle.html or to graphie-helpers.js...

Contributor

mwahl commented Dec 19, 2011

Nice exercise @stchangg!! Great addition to the time setting series. Will be mentioning a few minor suggestions - will take a deeper look in the next few days.

@mwahl mwahl and 2 others commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html data-require="math math-format graphie interactive angles time">
+<head>
+ <meta charset="UTF-8" />
+ <title>Telling time, interactive</title>
+ <script src="../khan-exercise.js"></script>
+</head>
+<body>
+ <div class="exercise">
+ <div class="problems">
+ <div id="set-hands" data-weight="3">
+
+ <div class="vars">
+ <var id="HOUR">randRange( 1, 12 )</var>
@mwahl

mwahl Dec 19, 2011

Contributor

Time should never === 1:00 [default time shown on clock] - data-ensure should make sure this won't happen

@stephjang

stephjang Dec 23, 2011

Contributor

Just made this change... not entirely sure that this is the right way to use data-ensure, but after checking the other exercises, it seems OK to me.

@Christi

Christi Jan 1, 2012

Contributor

what if you had the clock randomly set to a time and make sure it doesn't match what the user is supposed to set it to? The idea of eliminating one time from the set seems wrong. Or you could make having the time match the answer a gimme

@mwahl mwahl and 1 other commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
+
+ minuteAngle = KhanUtil.roundToNearest( graph.minuteSnapDegrees, minuteAngle );
+ hourAngle = KhanUtil.roundToNearest( graph.hourSnapDegrees, hourAngle );
+
+ return (minuteAngle == graph.correctMinuteAngle) &amp;&amp; (hourAngle == graph.correctHourAngle);
+
+ </div>
+ <div class="show-guess">
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true );
+ graph.hourPoint.moveTo( guess[1][0], guess[1][1], true );
+ </div>
+ </div>
+
+ <div class="hints">
+
+ <p>The first part of the time is the hour. The second part of the time is the number of minutes past the hour. So, it is <var>HOUR</var> hours and <var>MINUTE</var> minutes.</p>
@mwahl

mwahl Dec 19, 2011

Contributor

Suggest: "The number before the :</b represents the hour, and the number after the : represents the number of minutes past the hours. So [time] represents MINUTES past the HOUR."

@stephjang

stephjang Dec 23, 2011

Contributor

Revised. =)

@mwahl mwahl and 1 other commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
+ hourAngle = KhanUtil.roundToNearest( graph.hourSnapDegrees, hourAngle );
+
+ return (minuteAngle == graph.correctMinuteAngle) &amp;&amp; (hourAngle == graph.correctHourAngle);
+
+ </div>
+ <div class="show-guess">
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true );
+ graph.hourPoint.moveTo( guess[1][0], guess[1][1], true );
+ </div>
+ </div>
+
+ <div class="hints">
+
+ <p>The first part of the time is the hour. The second part of the time is the number of minutes past the hour. So, it is <var>HOUR</var> hours and <var>MINUTE</var> minutes.</p>
+
+ <div>
@mwahl

mwahl Dec 19, 2011

Contributor

I'd recommend re-architecting the hints section to 1) set the minutes hand and b) set the hour hand. Think the largest point of confusion here is mis-positioning the hour hand to account for minutes. If we can first set the minute hand (independent of the hour hand), and then set the hour hand (dependent on the minute hand), we can change lives!

For example:

First, let's set the minute hand.

Each long tick mark represents an increment of 5 minutes, because 60 minutes / 12 tick marks = 5 minutes per tick mark.

Since we are MINUTES past the hour, the minute hand should be at MINUTES/12

Next, let's set the hour hand...

@stephjang

stephjang Dec 23, 2011

Contributor

Thanks for these suggestions. I somehow managed to make a simple concept complicated. By the way... the minute hand should be at MINUTES / 5. Is the hint misleading? Any further suggestions for how to make it clearer?

@mwahl mwahl and 1 other commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
+ <p>Multiply each long tick mark by 5 to get the corresponding number of minutes. For example, the tick mark labeled "9" corresponds to 45 minutes. The tick mark labeled "12" is an exception; it corresponds to 0 minutes.</p>
+ </div>
+
+ <div>
+ <p>If it is <strong>zero</strong> minutes, the hour hand belongs directly on the corresponding hour mark. However, for any other number of minutes, the hour hand should be proportionally past the hour mark.</p>
+ <p>For example, if it's 5 hours and 45 minutes, the hour hand should be <code>\Large{ \frac{45}{60} = \frac{3}{4} }</code> of the way past the 5 hour mark.</p>
+ </div>
+
+ <div>
+ <p data-if="MINUTE_IS_ZERO">
+ The hour hand should be exactly at the <var>HOUR</var> hour mark. The minute hand should be at the tick mark labeled "12".
+ </p>
+ <p data-else>
+ The hour hand should be <code>\Large{ \frac{<var>MINUTE</var>}{60} = \frac{<var>MINUTE_FRACTION[0]</var>}{<var>MINUTE_FRACTION[1]</var>} }</code> of the way past the <var>HOUR</var> hour mark. The minute hand should be at the tick mark labeled <code>\Large{ \frac{<var>MINUTE</var>}{5} = <var>MINUTE/5</var>}</code>.
+ </p>
+ <div class="graphie" data-update="clock">
@mwahl

mwahl Dec 19, 2011

Contributor

Not sure if I'd ever perfectly set the clock so that a student can just click "check answer" to move on from the problem. Think all of the value is in actually moving the clock around.

Perhaps we could have clock hands appear in the right place (w/ opacity ~0.5) to suggest the user move the hands to that place?

@stephjang

stephjang Dec 23, 2011

Contributor

Good idea! I just added the hint hands...

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ <div class="graphie" id="clock">
+
+ init({ range: [ [-4, 4 ], [ -4, 4 ] ], scale: 45 });
+
+ var clockRadius = 3.75;
+ var minuteSnapPoints = 12;
+ var hourSnapPoints = 12 * 60 / MINUTE_INCREMENT;
+
+ var outerPointRadius = clockRadius * 1.01;
+ var minuteRadius = clockRadius * 0.6;
+ var hourRadius = clockRadius * 0.45;
+
+ graph.minuteSnapDegrees = 360 / minuteSnapPoints;
+ graph.hourSnapDegrees = 360 / hourSnapPoints;
+
+ graph.clock = KhanUtil.addAnalogClock( { radius: clockRadius, minuteTicks: hourSnapPoints } );
@beneater

beneater Dec 28, 2011

Owner

Within a graphie div like this, you shouldn't have to prefix stuff with KhanUtil

@stephjang

stephjang Dec 28, 2011

Contributor

Oh, did not realize. Removed them. Question: does this also apply to the "validator-function" div, or do I need to use KhanUtil there?

@beneater

beneater Dec 28, 2011

Owner

Nope. You shouldn't need it in validator-function either. Generally if you need to reference KhanUtil it anywhere in the html file, something is probably wrong.

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ point.updateLineEnds();
+ return true;
+ }
+
+ graph.minutePoint = addMovablePoint({
+ coord: [ 0, minuteRadius ],
+ constraints: {
+ fixedDistance: {
+ dist: minuteRadius,
+ point: [ 0, 0 ],
+ snapPoints: 12
+ }
+ },
+ onMove: function( x, y ) {
+ return movePartnerPoint( { x: x, y: y, point: this, outerPoint: graph.outerMinutePoint, isOuterPoint: false } );
+ }
@beneater

beneater Dec 28, 2011

Owner

Oh cool! I didn't realize you can grab the end of the hands as well as the outer point.

@stephjang

stephjang Dec 28, 2011

Contributor

Yeah! I'm glad you like. =)

@beneater beneater commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+
+ graph.hourPoint = addMovablePoint({
+ coord: [ hourRadius * Math.cos( Math.PI/3 ), hourRadius * Math.sin( Math.PI/3 ) ],
+ constraints: {
+ fixedDistance: {
+ dist: hourRadius,
+ point: [ 0, 0 ],
+ snapPoints: hourSnapPoints
+ }
+ },
+ onMove: function( x, y ) {
+ return movePartnerPoint( { x: x, y: y, point: this, outerPoint: graph.outerHourPoint, isOuterPoint: false } );
+ },
+ normalStyle: {
+ fill: KhanUtil.BLUE,
+ stroke: KhanUtil.BLUE
@beneater

beneater Dec 28, 2011

Owner

again, don't need KhanUtil in here

@beneater beneater commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ dist: hourRadius,
+ point: [ 0, 0 ],
+ snapPoints: hourSnapPoints
+ }
+ },
+ onMove: function( x, y ) {
+ return movePartnerPoint( { x: x, y: y, point: this, outerPoint: graph.outerHourPoint, isOuterPoint: false } );
+ },
+ normalStyle: {
+ fill: KhanUtil.BLUE,
+ stroke: KhanUtil.BLUE
+ },
+ highlightStyle: {
+ fill: KhanUtil.BLUE,
+ stroke: KhanUtil.BLUE
+ }
@beneater

beneater Dec 28, 2011

Owner

more KhanUtil.. you get the idea :)

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ <div class="solution" data-type="custom">
+ <div class="instruction">
+ Drag the two hands so the clock reads <var>HOUR</var>:<var>NICE_MINUTE</var>.
+ </div>
+ <div class="guess">
+ [ graph.minutePoint.coord, graph.hourPoint.coord ]
+ </div>
+ <div class="validator-function">
+
+ var minuteAngle = KhanUtil.coordToDegrees( graph.minutePoint.coord );
+ var hourAngle = KhanUtil.coordToDegrees( graph.hourPoint.coord );
+
+ minuteAngle = KhanUtil.roundToNearest( graph.minuteSnapDegrees, minuteAngle );
+ hourAngle = KhanUtil.roundToNearest( graph.hourSnapDegrees, hourAngle );
+
+ return (minuteAngle == graph.correctMinuteAngle) &amp;&amp; (hourAngle == graph.correctHourAngle);
@beneater

beneater Dec 28, 2011

Owner

nit: we try to use === and !== instead of == or != most of the time (except maybe when comparing to null)

@stephjang

stephjang Dec 28, 2011

Contributor

Gotcha. Fixed, and will be sure to use === in the future.

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ graph.correctHourAngle = KhanUtil.roundToNearest( graph.hourSnapDegrees, graph.correctHourAngle );
+
+ </div>
+ </div>
+
+ <div class="solution" data-type="custom">
+ <div class="instruction">
+ Drag the two hands so the clock reads <var>HOUR</var>:<var>NICE_MINUTE</var>.
+ </div>
+ <div class="guess">
+ [ graph.minutePoint.coord, graph.hourPoint.coord ]
+ </div>
+ <div class="validator-function">
+
+ var minuteAngle = KhanUtil.coordToDegrees( graph.minutePoint.coord );
+ var hourAngle = KhanUtil.coordToDegrees( graph.hourPoint.coord );
@beneater

beneater Dec 28, 2011

Owner

I noticed a small issue when viewing this exercise in timeline mode for coaches (from ?debug mode, make a few wrong guesses, give the right answer, then click "Problem history")

When building the timeline view, each saved guess is fed through this validator function again so it shows correctly as red or green in the timeline at the top. Right now it's always showing it as wrong. It'll probably be enough to replace graph.minutePoint.coord with guess[ 0 ] and graph.hourPoint.coord with guess[ 1 ], but the custom answer type is all very new, so let me know if you run into any trouble.

@stephjang

stephjang Dec 28, 2011

Contributor

Ah, this worked. The timeline mode is really neat! I didn't know of it before, and was mainly modeling this solution format off of the Graphing Inequalities exercise.

Not sure if this is related, but occasionally in ?debug mode (I've only seen it here), the vars div doesn't seem to get processed first, so Firebug shows the error "MINUTE is not defined". This doesn't happen consistently though, so I'm not sure what's causing it...

@beneater

beneater Dec 28, 2011

Owner

It's probably not related at all.. though in looking back at your vars section, it's possible you're running into an issue with the data-ensure. I'd recommend wrapping the data ensure around the whole HOUR and MINUTE selection:

<div data-ensure="!( HOUR === 1 && MINUTE === 0 )">
  <var id="HOUR">randRange( 1, 12 )</var>
  <var id="MINUTE_INCREMENT">15</var>
  <var id="MINUTE">randRange( 0, 60 / MINUTE_INCREMENT - 1 ) * MINUTE_INCREMENT</var>
</div>
@beneater

beneater Dec 28, 2011

Owner

Also, while I'm thinking about it.. if you make an extra check in the validator-function for the case where the clock is set to 1:00, and return "" instead of true or false, it will prevent the question from being graded. It's probably a good idea to do that to prevent someone from clicking the check answer/next question button (which is the same button) too many times and having the question accidentally marked wrong.

It's something we need to go back and fix in some of the other custom-answer-type-using exercises too.

@stephjang

stephjang Dec 29, 2011

Contributor

Done!

@beneater beneater commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+ </div>
+ <div class="validator-function">
+
+ var minuteAngle = KhanUtil.coordToDegrees( graph.minutePoint.coord );
+ var hourAngle = KhanUtil.coordToDegrees( graph.hourPoint.coord );
+
+ minuteAngle = KhanUtil.roundToNearest( graph.minuteSnapDegrees, minuteAngle );
+ hourAngle = KhanUtil.roundToNearest( graph.hourSnapDegrees, hourAngle );
+
+ return (minuteAngle == graph.correctMinuteAngle) &amp;&amp; (hourAngle == graph.correctHourAngle);
+
+ </div>
+ <div class="show-guess">
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true );
+ graph.hourPoint.moveTo( guess[1][0], guess[1][1], true );
+ </div>
@beneater

beneater Dec 28, 2011

Owner

This part of the timeline view looks great! Makes it easy to see all the wrong guesses.

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

exercises/telling_time_interactive.html
+
+ <p>First, let's set the minute hand.</p>
+
+ <div>
+ <p>Each long tick mark is also an increment of 5 minutes, because 60 minutes / 12 tick marks = 5 minutes per tick mark.</p>
+ <p>Since we are <var>MINUTE</var> minutes past the hour, the minute hand should be at <code class="hint_orange"><var>fraction(MINUTE, 5)</var> = <var>MINUTE/5</var></code>.
+ </div>
+
+ <p>Next, let's set the hour hand.</p>
+
+ <div>
+ <p>The 12 long tick marks correspond to the hours in the day (assuming AM/PM time).</p>
+ <p>If it is <strong>zero</strong> minutes, the hour hand belongs directly on the corresponding hour mark. However, for any other number of minutes, the hour hand should be proportionally past the hour mark.</p>
+ </div>
+
+ <p>For example, if it's 5 hours and 45 minutes, the hour hand should be <code><var>fraction(45, 60)</var> = <var>fraction(45, 60, false, true)</var></code> of the way past the 5 hour mark.</p>
@beneater

beneater Dec 28, 2011

Owner

I wonder if the example will be confusing since it doesn't relate to the specific problem?

@stephjang

stephjang Dec 28, 2011

Contributor

Removed this example and adapted the other hints to explain this part.

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

utils/interactive.js
}
+
+ // NOTE: redundancy with functions in angles.js and time.js
@beneater

beneater Dec 28, 2011

Owner

I don't have a huge problem with that. There are a bunch of places in interactive.js where we reinvent radian/degree conversion, etc. Maybe some day someone will refactor it. Though I think it's best not to have a bunch of dependencies where including interactive requires tons of other modules.

@stephjang

stephjang Dec 28, 2011

Contributor

Hmm, that's what I thought. Thanks for replying to the note!

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

utils/interactive.js
+
+ var snapRadians = 2 * Math.PI / movablePoint.constraints.fixedDistance.snapPoints;
+ var radius = movablePoint.constraints.fixedDistance.dist;
+
+ // get coordinates relative to the fixedDistance center
+ var centerCoord = movablePoint.constraints.fixedDistance.point;
+ var centerX = (centerCoord[0] - graph.range[0][0]) * graph.scale[0];
+ var centerY = (-centerCoord[1] + graph.range[1][1]) * graph.scale[1];
+
+ var mouseXrel = mouseX - centerX;
+ var mouseYrel = -mouseY + centerY;
+ var radians = Math.atan(mouseYrel / mouseXrel);
+ var outsideArcTanRange = (mouseXrel < 0);
+
+ // adjust so that angles increase from 0 to 2 pi as you go around the circle
+ if (outsideArcTanRange) {
@beneater

beneater Dec 28, 2011

Owner

nit: you could just say if ( mouseXrel < 0 ) { and get rid of outsideArcTanRange (though, otoh, I suppose the variable name makes it a lot clearer what you're doing)

@stephjang

stephjang Dec 28, 2011

Contributor

Ah, I thought of that, but as you noted, I thought the variable name more clearly indicated what was going on, since it's not super intuitive. Let me know if I should change it.

@beneater

beneater Dec 28, 2011

Owner

I think I started to agree with you halfway into my last comment :)

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

utils/time.js
+ timeToDegrees: function( minutes ) {
+
+ // p is the proportion of total time
+ var p = minutes / 60;
+ var angleProportion;
+
+ if ( p <= 0.25 ) {
+ angleProportion = (0.25 - p);
+ } else {
+ angleProportion = (1.25 - p);
+ }
+
+ return 360 * angleProportion;
+ },
+
+ // TODO: not limited to time. belongs in another package.
@beneater

beneater Dec 28, 2011

Owner

Perhaps interactive or graphie? What do you think?

@stephjang

stephjang Dec 28, 2011

Contributor

I think graphie would make more sense. Actually, though, I'd like to refactor to be more like MATLAB's cart2pol function or OpenCV's cartToPolar... I'll try to get to this tomorrow morning.

@stephjang

stephjang Dec 29, 2011

Contributor

I found out that the degreesToCoord() function was pretty much replicating what polar() does in graphie, so I just refactored the exercise to use polar() instead. There was no equivalent of coordToDegrees(), so I made this function more general, renamed it to cartToPolar(), and added to graphie.

In the future, I'd suggest renaming graphie's polar() function to polarToCart() to be clearer.

@beneater beneater commented on an outdated diff Dec 28, 2011

utils/time.js
+ },
+
+ // TODO: not limited to time. belongs in another package.
+ coordToDegrees: function( coord ) {
+ var radians = Math.atan(coord[1]/coord[0]);
+
+ if (coord[0] < 0) {
+ radians += Math.PI;
+ } else if (coord[1] < 0) {
+ radians += 2*Math.PI;
+ }
+
+ return KhanUtil.toDegrees(radians);
+ },
+
+ // TODO: not limited to time. belongs in another package.
@beneater

beneater Dec 28, 2011

Owner

Same, probably interactive or graphie.

@beneater beneater and 1 other commented on an outdated diff Dec 28, 2011

utils/time.js
+ } else if (coord[1] < 0) {
+ radians += 2*Math.PI;
+ }
+
+ return KhanUtil.toDegrees(radians);
+ },
+
+ // TODO: not limited to time. belongs in another package.
+ degreesToCoord: function( radius, degrees ) {
+ var radians = KhanUtil.toRadians(degrees);
+ var x = radius * Math.cos( radians );
+ var y = radius * Math.sin( radians );
+ return [x, y];
+ },
+
+ // TODO: not limited to time... belongs in math.js
@beneater

beneater Dec 28, 2011

Owner

I think I saw somewhere you were having trouble getting this to work in math.js. Is that still the case?

@beneater

beneater Dec 28, 2011

Owner

Oh it was at the top of this pull request :) ... There shouldn't be anything special about math.js, so I'm not sure what problem you might have been running into.

@stephjang

stephjang Dec 28, 2011

Contributor

Anytime I try editing math.js, none of my changes seem to be used when the exercise loads (e.g., editing a function or adding a new function, however simple). I'm using Firefox to test, with caching disabled. I'm really not sure what is causing this, but it's preventing me from refactoring out these functions and testing. =/

@beneater

beneater Dec 28, 2011

Owner

Not sure what could be causing that other than overzealous caching somewhere. Worst case, I can try moving after we merge.

@stephjang

stephjang Dec 29, 2011

Contributor

Whoops, I realized I didn't do a complete job of disabling cache in firefox, my bad!

Owner

beneater commented Dec 28, 2011

This looks really awesome. You obviously have a really good understanding of the framework and interactive stuff!

I made a few comments (none of which I think are really major issues). I look forward to getting this merged in!

One other nit I noticed is that we tend to use tabs everywhere to indent and I noticed you've used spaces everywhere. Would you mind going through and replacing the spaces with tabs? I know, not a ton of fun, but we'd like to keep things consistent.

Contributor

stephjang commented Dec 28, 2011

I modified the hints and felt that the plural() function from word-problems.js could make them a bit smoother. However, will this affect load time/performance, since this exercise includes so many modules now? The full list is: math math-format graphie interactive angles time word-problems

Contributor

stephjang commented Dec 29, 2011

I'm pretty sure I made all of the latest requested changes. Let me know if there's anything left!

Contributor

stephjang commented Jan 1, 2012

@beneater I refactored the other time exercises and removed the old time code from graphie-helpers. :)

@beneater beneater and 1 other commented on an outdated diff Jan 1, 2012

utils/time.js
+ }
+
+ analogClock.draw = function() {
+ if ( this.hourTicks ) {
+ this.drawTicks( {n: this.hourTicks, p: this.hourTickLength} );
+ }
+ if ( this.minuteTicks ) {
+ this.drawTicks( {n: this.minuteTicks, p: this.minuteTickLength} );
+ }
+ // draw circles
+ this.set.push( this.graph.circle( [ 0, 0 ], this.radius ) );
+ this.set.push( this.graph.circle( [ 0, 0 ], this.radius/ 40 ) );
+ if ( this.showLabels ) {
+ this.drawLabels();
+ }
+ if ( this.hour && this.minute ) {
@beneater

beneater Jan 1, 2012

Owner

This should probably be if ( this.hour !== undefined && this.minute !== undefined ) {, so this doesn't happen.

@stephjang

stephjang Jan 2, 2012

Contributor

Whoops, fixed this.

@beneater beneater and 1 other commented on an outdated diff Jan 3, 2012

utils/time.js
+ }
+
+ analogClock.draw = function() {
+ if ( this.hourTicks ) {
+ this.drawTicks( {n: this.hourTicks, p: this.hourTickLength} );
+ }
+ if ( this.minuteTicks ) {
+ this.drawTicks( {n: this.minuteTicks, p: this.minuteTickLength} );
+ }
+ // draw circles
+ this.set.push( this.graph.circle( [ 0, 0 ], this.radius ) );
+ this.set.push( this.graph.circle( [ 0, 0 ], this.radius/ 40 ) );
+ if ( this.showLabels ) {
+ this.drawLabels();
+ }
+ if ( this.hour !== undefined && this.minute !== undefined ) {
@beneater

beneater Jan 3, 2012

Owner

hrm.. i just noticed it's drawing the hands at 12:00 in the interactive exercise now, so maybe these are defined but some other kind of falsey value? Haven't looked through to see exactly what's going on (you can probably figure it out faster than me), but something about this check isn't working right in the interactive version.

@stephjang

stephjang Jan 3, 2012

Contributor

Oh sorry, I made the change too hastily. This probably should be checking for false, not undefined, since I set default values for those params to false when instantiating the analogClock object. Just pushed the fix.

@beneater beneater and 1 other commented on an outdated diff Jan 3, 2012

exercises/telling_time_interactive.html
+ <div class="instruction">
+ Drag the two hands so the clock reads <var>HOUR</var>:<var>NICE_MINUTE</var>.
+ </div>
+ <div class="guess">
+ [ minutePoint.coord, hourPoint.coord ]
+ </div>
+ <div class="validator-function">
+
+ var minuteAngle = cartToPolar( guess[0] )[1];
+ var hourAngle = cartToPolar( guess[1] )[1];
+
+ minuteAngle = roundToNearest( minuteSnapDegrees, minuteAngle );
+ hourAngle = roundToNearest( hourSnapDegrees, hourAngle );
+
+ // if hands have not been moved, return `""`
+ if ( minuteAngle === minuteStartAngle &amp;&amp; hourAngle ==== hourStartAngle) {
@beneater

beneater Jan 3, 2012

Owner

==== -> ===

@stephjang

stephjang Jan 3, 2012

Contributor

Oops, fixed.

Stephanie H. Chang added some commits Jan 3, 2012

Stephanie H. Chang Merge remote-tracking branch 'upstream/master' into interactive-telli…
…ng-time
9490fbb
Stephanie H. Chang fixed ==== typo in telling_time_interactive.html; check for false val…
…ues instead of undefined before drawing hands in time.js
151ccdd
Owner

beneater commented Jan 3, 2012

Awesome! This is a really great exercise!
Looking forward to seeing many more :)

As I mentioned before, it might be another week or so before it goes live since Matt's out of town :(

@beneater beneater added a commit that referenced this pull request Jan 3, 2012

@beneater beneater Merge pull request #8913 from stchangg/interactive-telling-time
New exercise: Interactive telling time
4cde86f

@beneater beneater merged commit 4cde86f into Khan:master Jan 3, 2012

beneater referenced this pull request Jan 3, 2012

Closed

Interactive time-telling #6362

Contributor

mwahl commented Jan 3, 2012

Thanks @stchangg for rocking this - very slick. Will let you know when we push live later this week/weekend!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment