# New exercise: Interactive telling time #8913

Merged
merged 42 commits into from Jan 3, 2012
+524 −45

## 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.

### stephjang added some commits Dec 18, 2011

 stephjang  refactored telling_time_interactive, extracted analogClock to time.js…  …, added fixedDistance snap to interactive.js bcc1b9d stephjang  Merge remote-tracking branch 'upstream/master' into interactive-telli…  …ng-time bc5eb7e stephjang  updated comment in interactive.js  e611b59 stephjang  revert to original telling time  9935161 stephjang  fixed mistaken code deletion in time.js  2d057df stephjang  revert again to original telling time  3922231
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...
 stephjang  reverted unit_circle.html and graphie-helpers.js back to original ver…  …sions 94b77c5
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 and 2 others commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
 @@ -0,0 +1,267 @@ + + + + + Telling time, interactive + + + +
+
+
+ +
+ randRange( 1, 12 )

#### 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 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 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 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) && (hourAngle == graph.correctHourAngle); + + +
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true ); + graph.hourPoint.moveTo( guess[1][0], guess[1][1], true ); +
+ + +
+ +

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 HOUR hours and MINUTE minutes.

#### 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."

Contributor

Revised. =)

### 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) && (hourAngle == graph.correctHourAngle); + + +
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true ); + graph.hourPoint.moveTo( guess[1][0], guess[1][1], true ); +
+ + +
+ +

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 HOUR hours and MINUTE minutes.

+ +

#### 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 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 and 1 other commented on an outdated diff Dec 19, 2011

exercises/telling_time_interactive.html
 +

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.

+ + +
+

If it is zero 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.

+

For example, if it's 5 hours and 45 minutes, the hour hand should be \Large{ \frac{45}{60} = \frac{3}{4} } of the way past the 5 hour mark.

+
+ +
+

+ The hour hand should be exactly at the HOUR hour mark. The minute hand should be at the tick mark labeled "12". +

+

+ The hour hand should be \Large{ \frac{MINUTE}{60} = \frac{MINUTE_FRACTION[0]}{MINUTE_FRACTION[1]} } of the way past the HOUR hour mark. The minute hand should be at the tick mark labeled \Large{ \frac{MINUTE}{5} = MINUTE/5}. +

+

#### 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 Dec 23, 2011

Contributor

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

### stephjang added some commits Dec 23, 2011

 stephjang  Merge remote-tracking branch 'upstream/master' into interactive-telli…  …ng-time ed476ff stephjang  added final hint hands  9c1d38c stephjang  prettified hint hands  39f1ae0 stephjang  refactored fraction code using math-format fraction() func  d81759c stephjang  fixed the first hint  fb40921 stephjang  refactored fraction code w/ math-format.js func, improved hints  f484892 stephjang  split up hints  2dcacc9 stephjang  data ensure that default hand placement is never selected for the pro…  …blem ad661fb stephjang  reverted word problems back to unaltered version  8bd5392 stephjang  split up last hint and used color coding in hints  706092a stephjang  changed title to 'Setting time'  62346cc stephjang  removed comma from time.js  7336f26

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

exercises/telling_time_interactive.html
 +
+ + 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 Dec 28, 2011

Owner

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

#### 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 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 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 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 Dec 28, 2011

Contributor

Yeah! I'm glad you like. =)

### 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 Dec 28, 2011

Owner

again, don't need KhanUtil in here

### 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 Dec 28, 2011

Owner

more KhanUtil.. you get the idea :)

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

exercises/telling_time_interactive.html
 +
+
+ Drag the two hands so the clock reads HOUR:NICE_MINUTE. +
+
+ [ graph.minutePoint.coord, graph.hourPoint.coord ] +
+
+ + 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) && (hourAngle == graph.correctHourAngle);

#### 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 Dec 28, 2011

Contributor

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

### 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 ); + + + + +
+
+ Drag the two hands so the clock reads HOUR:NICE_MINUTE. +
+
+ [ graph.minutePoint.coord, graph.hourPoint.coord ] +
+
+ + var minuteAngle = KhanUtil.coordToDegrees( graph.minutePoint.coord ); + var hourAngle = KhanUtil.coordToDegrees( graph.hourPoint.coord );

#### 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 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 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 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.

Contributor

Done!

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

exercises/telling_time_interactive.html
 + +
+ + 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) && (hourAngle == graph.correctHourAngle); + +
+
+ graph.minutePoint.moveTo( guess[0][0], guess[0][1], true ); + graph.hourPoint.moveTo( guess[1][0], guess[1][1], true ); +

#### beneater Dec 28, 2011

Owner

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

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

exercises/telling_time_interactive.html
 + +

First, let's set the minute hand.

+ +
+

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

+

Since we are MINUTE minutes past the hour, the minute hand should be at fraction(MINUTE, 5) = MINUTE/5. +

+ +

Next, let's set the hour hand.

+ +
+

The 12 long tick marks correspond to the hours in the day (assuming AM/PM time).

+

If it is zero 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.

+
+ +

For example, if it's 5 hours and 45 minutes, the hour hand should be fraction(45, 60) = fraction(45, 60, false, true) of the way past the 5 hour mark.

#### beneater Dec 28, 2011

Owner

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

#### stephjang Dec 28, 2011

Contributor

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

### 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 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 Dec 28, 2011

Contributor

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

### 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 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 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 Dec 28, 2011

Owner

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

### 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 Dec 28, 2011

Owner

Perhaps interactive or graphie? What do you think?

#### 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 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 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 Dec 28, 2011

Owner

Same, probably interactive or graphie.

### 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 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 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 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 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 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.

### stephjang added some commits Dec 28, 2011

 stephjang  used guess[] in validator function  835d61e stephjang  converted spaces to tabs in interactive.js  9d2b957 stephjang  converted spaces to tabs in time.js  6edcca7 stephjang  removed note abt redundancy in interative.js  a08cdcc stephjang  converted spaces to tabs in telling_time_interactive.html  c002c0c stephjang  Fixed little bugs or formatting in telling_time_interactive.html  3229980 stephjang  removed confusing hint and color-coded 'hour' and 'minute' in question  9556714 stephjang  clarified hints and color-co added color coding  d1320f6
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

### stephjang added some commits Dec 29, 2011

 stephjang  Merge remote-tracking branch 'upstream/master' into interactive-telli…  …ng-time d8bc6ea stephjang  removed KhanUtil from validator-function div  05fa3e5 stephjang  refactored coordToDegrees to crees to cartToPolar and moved to graphi…  …e.js 60fb7b7 stephjang  wrapped all involved varialbes wiables within data-ensure div  e6f93ca stephjang  if hands have not been moved, return empty string  2edeacb
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!

### stephjang added some commits Dec 31, 2011

 stephjang  Merge remote-tracking branch 'upstream/master' into interactive-telli…  …ng-time c38ff27 stephjang  renamed labelShown to showLabel in time.js  212f8d3 stephjang  refactored telling_time and telling_time_0.5 to use time.js & removed…  … graph. prefix from variables in telling_time_interactive b9fca4c stephjang  removed analogClock() function from graphie-helpers.js  073da29 stephjang  used tags for hour and minute numbers in hints  7ef3280 stephjang  removed unnecessary code tag in hint  hint 89e488a
Contributor

### stephjang commented Jan 1, 2012

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

### 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 Jan 1, 2012

Owner

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

#### stephjang Jan 2, 2012

Contributor

Whoops, fixed this.

### stephjang added some commits Jan 2, 2012

 stephjang  Merge remote-tracking branch 'upstream/master' into interactive-telli…  …ng-time 3b2a82a stephjang  revisecheck for undefined instead of truthiness in time.js  cdeab0f

### 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 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 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 and 1 other commented on an outdated diff Jan 3, 2012

exercises/telling_time_interactive.html
 +
+ Drag the two hands so the clock reads HOUR:NICE_MINUTE. +
+
+ [ minutePoint.coord, hourPoint.coord ] +
+
+ + 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 && hourAngle ==== hourStartAngle) {

#### beneater Jan 3, 2012

Owner

==== -> ===

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 added a commit that referenced this pull request Jan 3, 2012

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

Closed

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!