Commits on Dec 17, 2015
  1. Differentiate between error types when failing to load an exercise.

    We used to only blame the user's internet.  But it seems sometimes it is
    our fault too.  So now we differentitate between the different errors,
    to be less confusing to users whose internet is not to blame, and to
    help devs debug any particular issue based upon what our users report.
    This is to fix:
    Test Plan:
    git grep warnTimeout
    see that we weren't using this anywhere else.
    on dev khan exercise files if they exist get served directly.  So to test we
    can change the name so that it uses the exercises/
    diff --git a/khan-exercise.js b/khan-exercise.js
    index 8a9bcfd..eb048c3 100644
    --- a/khan-exercise.js
    +++ b/khan-exercise.js
    @@ -2048,7 +2048,7 @@ function loadExercise(exerciseId, fileName) {
         debugLog("loadExercise start " + fileName);
         // Packing occurs on the server but at the same "exercises/" URL
    -    $.get(urlBase + "exercises/" + fileName).done(function(data) {
    +    $.ajax({url:urlBase + "exercises/Z" + fileName, timeout:1000}).done(function(data) {
             debugLog("loadExercise got " + fileName);
             // Get rid of any external scripts in data before we shove data
    See 404 message.
    Then in webapp:
    diff --git a/exercises/ b/exercises/
    index 5aa90bd..03a1c8f 100644
    --- a/exercises/
    +++ b/exercises/
    @@ -17,6 +17,8 @@ class RawExercise(request_handler.RequestHandler):
             would also cause problems for the a/b tests in
    +        import time
    +        time.sleep(5000)
             path = self.request.path
             filename = urllib.unquote(path.split('/', 3)[3])
    See timeout message.
    Then in webapp:
    diff --git a/exercises/ b/exercises/
    index 5aa90bd..9e1728a 100644
    --- a/exercises/
    +++ b/exercises/
    @@ -17,6 +17,7 @@ class RawExercise(request_handler.RequestHandler):
             would also cause problems for the a/b tests in
    +        1/0
             path = self.request.path
             filename = urllib.unquote(path.split('/', 3)[3])
    See the generic error message.
    Then in javascript console do:
    See the MathJax error message mentioning some.js.
    Reviewers: emily, lauren
    Subscribers: kevindangoor
    Differential Revision:
    tzjames committed Dec 16, 2015
Commits on Dec 15, 2015
  1. Don't point people to GitHub to report content issues

    When users report an issue with an exercise, that issue report generally gets
    automatically sent to JIRA where the content team goes through and resolves
    any legitimate content problems. Previously if communication with JIRA failed,
    we'd ask users to submit an issue report to GitHub instead. Unfortunately as
    the content team has grown and evolved, they're relying soley on JIRA and not
    looking at GitHub anymore. Consequently, we shouldn't ask users to file issues
    there as it will simply be a waste of their time. Instead if JIRA fails, we
    should simply thank them for their feedback.
    Of course if JIRA fails, this means their feedback has gone into a black hole
    never to be seen again :(. For now, we're okay with that because any legitimate
    problem with an exercise will elicit scores (or even hundreds) of similar issue
    reports, so we don't expect this'll mean we miss out on anything.
    Test Plan:
    Modify `` to always return an error:
     def do_post(handler, url, data, headers):
    +    handler.response.set_status(500)
    +    return
    Loaded an exercise page (e.g., `/e/addition_1`) and reported an error. Upon submitting, saw the helpful "Thank you for your feedback!" message and saw a 500 error in the network panel for the /jirapost POST.
    Reviewers: johnsullivan
    Reviewed By: johnsullivan
    Differential Revision:
    beneater committed Nov 20, 2015
Commits on Dec 11, 2015
  1. Explicitly require base modules

    Dynamically requiring the base modules makes their necessity undetectable by JavaScript bundlers.
    This diff separates the loading of the base modules from the dynamic loading of other exercise-
    specific modules and makes the loading of the base modules include explicit string-based "require"
    Some additional context: On Android, we want to try and bundle the necessary assets from
    khan-exercises so that we can slim down our app, and it'd be preferable to have these dependencies
    made explicit by khan-exercises, rather than, e.g., configuring RequireJS to load the base modules
    from a configuration file in the Android repo.
    Test Plan:
    - Run khan-exercises (`python -m SimpleHTTPServer`).
    - Load an exercise.
    - Verify that there are no JS errors, and that the exercise loads sanely.
    - Complete the problem, and verify that the next problem loads sanely.
    Reviewers: eater, emily
    Reviewed By: emily
    Subscribers: benkomalo
    Differential Revision:
    crm416 committed Dec 5, 2015
Commits on Dec 8, 2015
  1. Answer major question in README.

    This answers the three questions laid out in the community lead handbook:
    * What should I do if I found a bug?
    * What should I do if I have a question?
    * What should I do if I want to contribute time to this project?
    Test Plan:
    Use GitHub's preview tab to ensure the Markdown is valid.
    brownhead committed Dec 8, 2015
Commits on Nov 30, 2015
  1. Do not assume window.localStorage's presence implies usability

    This commit is almost entirely a source-code comment; please see the
    comment for further details.
    Test Plan: Repro'd in IE11, verified this fix allows getting past the exact issue specified in the original Asana ticket, then made a huge comment and hoped for the best.
    Reviewers: amy, eliana, jordan, kevindangoor
    Reviewed By: kevindangoor
    Subscribers: kevindangoor, #support
    Differential Revision:
    bpollack committed Nov 24, 2015
Commits on Nov 24, 2015
  1. Reintroduce offline cheating detection.

    We removed the offline cheating detection because it was misfiring too
    often. I've come up with two potential causes of this misfiring and
    fixed both of them:
    1) We were not keying the `OfflineHintRecord` on the user ID (doh).
    2) We were not checking the the `userExercise` object had a name (when
       content creators look at a preview in Perseus One the exercise
       name will be undefined).
    Because the symptoms of this bug are somewhat severe (students being
    unable to get X in a row succsefully) I'm rolling this out tentatively.
    Every time we detect cheating, we'll send a message to the server that
    will make its way into our logs. I'll look at the frequency of these
    logs, as well as the percentage of coached users (most likely to cheat)
    that are caught with this, to see if the code is working or not.
    Test Plan:
    1) Open up any exercise.
    2) Disconnect from the internet or kill your app server.
    3) Take a hint.
    4) Close the tab (or refresh to get a blank screen)
    5) Reconnect or bring back up your app server
    6) See no hints, but see that the added Ajax request fired succesfully.
    Reviewers: eliana
    Reviewed By: eliana
    Subscribers: #sat
    Differential Revision:
    brownhead committed Oct 23, 2015
Commits on Nov 20, 2015
  1. Merge pull request #161545 from Khan/brownhead-update-readme

    Cleanup README and make status clearer.
    brownhead committed Nov 20, 2015
Commits on Nov 16, 2015
  1. Add some text to ellipse_intuition to help explain the exercise better.

    This is a follow-up to:
    It adds in some helpful, explanatory, text to the exercise.
    Test Plan:
    Load up the exercise, e.g.:
    See that it looks ok:
    Reviewers: emily, csilvers
    Reviewed By: csilvers
    Subscribers: csilvers
    Differential Revision:
    jeresig committed Nov 12, 2015
Commits on Nov 14, 2015
  1. Cleanup README and make status clearer.

    This makes the purpose of the repo a little clearer, but there's still
    more work to be done around defining the kinds of contributions we
    Test Plan:
    brownhead committed Nov 14, 2015
Commits on Nov 12, 2015
  1. Merge pull request #161539 from Christi/patch-1

    Update division 1.5 to remove 2 digit divisors...
    jeresig committed Nov 12, 2015
Commits on Nov 9, 2015
  1. Update division 1.5 to remove 2 digit divisors...

    Should satisfy the request under
    Removes all 2 digit divisors and adds 4 digit divisors.
    Christi committed Nov 9, 2015
Commits on Nov 7, 2015
  1. Merge pull request #161433 from rhc2104/patch-1

    Update copyright on README
    brownhead committed Nov 7, 2015
  2. Merge pull request #161495 from mankal111/master

    Change equal sign to approx if MEAN is rounded
    brownhead committed Nov 7, 2015
  3. Add support for two new problem-error types.

    In a separate commit (in webapp), we are going to change the options
    that we show when you click on 'report a problem' at the bottom-right
    of pages like
    This handles the backend (khan-exercises) support for this: Mapping
    the new options (indexed by element-id) to the jira name we use for
    them, and to the placeholder text we associate with them.
    Test Plan:
    Fingers crossed -- I don't know how to test this until the webapp
    changes are in too, and everything is deployed!
    Reviewers: eater
    Reviewed By: eater
    Subscribers: cameron
    Differential Revision:
    csilvers committed Nov 6, 2015
Commits on Nov 5, 2015
  1. Add missing apostrophe

    Summary: This is basically the same as but that wouldn't merge since this i18n thingy has changed. It seemed easiest to make a new branch.
    Reviewers: eater
    Reviewed By: eater
    Differential Revision:
    petercollingridge committed Nov 4, 2015
Commits on Nov 4, 2015
  1. Change histogram to dotplot

    Summary: Reword question description and make number mathy. For
    Reviewers: emily, eater
    Reviewed By: eater
    Differential Revision:
    petercollingridge committed Oct 11, 2015
  2. Reword question

    I don't know how worthwhile these changes are, but they do make the questions better.
    Slightly reword question.
    Reviewers: emily, eater
    Reviewed By: eater
    Differential Revision:
    petercollingridge committed Oct 11, 2015
  3. Make coordinate plural

    Summary: For
    Reviewers: emily, eater
    Reviewed By: eater
    Differential Revision:
    petercollingridge committed Oct 11, 2015
Commits on Oct 29, 2015
  1. Update khan-exercises to remove all references to Jed.

    As of D22753, i18n.js doesn't use Jed anymore!  Nothing else does
    either.  So we can remove it.
    I did this by running and then running `git grep -iw
    jed` and deleting all references.
    Auditors: john
    Test Plan:
       python -mSimpleHTTPServer
    and visited
    and saw it load correctly.  There's no easy way to check i18n from the
    local-server, so I'll check it once I update webapp with this.
    csilvers committed Oct 29, 2015
  2. Fix $_ in local i18n.js so that Perseus can use it when running locally

    /local-only/i18n.js defined window.$_ using an unspecified reference to
    createFragment, which didn't cause an error when testing locally because
    khan-exercises doesn't include any React code. However, the same local
    javscript file is used when running Perseus locally - and Perseus uses
    $_ all over the place.
    Test Plan:
    I ran ./local-only/ as part of this commit. Since the
    newest i18n.js no longer exports $._ I grepped to make sure it was no
    longer used in any exercise/util:
    grep -E '(jQuery|\$)\._\(|(jQuery|\$)\.ngettext|(jQuery|\$)\.i18nDoNotTranslate' -r .
    make lint
    python build/
    make pack
    Checked that both [unpacked](http://localhost:8000/exercises/decimals_on_the_number_line_1.html) and [packed](http://localhost:8000/exercises-packed/decimals_on_the_number_line_1.html?lang=es) exercises work
    Updated the khan-exercises submodule in the Perseus repo and verified
    that [widgets using $_](http://localhost:9000/test.html#content=%7B%22question%22%3A%7B%22content%22%3A%22%5B%5B%E2%98%83%20radio%201%5D%5D%22%2C%22images%22%3A%7B%7D%2C%22widgets%22%3A%7B%22radio%201%22%3A%7B%22type%22%3A%22radio%22%2C%22alignment%22%3A%22default%22%2C%22static%22%3Afalse%2C%22graded%22%3Atrue%2C%22options%22%3A%7B%22choices%22%3A%5B%7B%7D%2C%7B%7D%5D%2C%22randomize%22%3Afalse%2C%22multipleSelect%22%3Afalse%2C%22displayCount%22%3Anull%2C%22hasNoneOfTheAbove%22%3Afalse%2C%22onePerLine%22%3Atrue%2C%22deselectEnabled%22%3Afalse%7D%2C%22version%22%3A%7B%22major%22%3A1%2C%22minor%22%3A0%7D%7D%7D%7D%2C%22answerArea%22%3A%7B%22type%22%3A%22multiple%22%2C%22options%22%3A%7B%22content%22%3A%22%22%2C%22images%22%3A%7B%7D%2C%22widgets%22%3A%7B%7D%7D%2C%22calculator%22%3Afalse%2C%22periodicTable%22%3Afalse%7D%2C%22itemDataVersion%22%3A%7B%22major%22%3A0%2C%22minor%22%3A1%7D%2C%22hints%22%3A%5B%5D%7D) render properly.
    Reviewers: csilvers
    Reviewed By: csilvers
    Differential Revision:
    alopatin committed Oct 29, 2015
Commits on Oct 22, 2015
  1. Simplify the local-only script since i18n.js already defines window.i…

    Now the 'local' version of i18n.js (used for local testing) is more
    similar to the 'real' version from webapp (used in prod).
    I ran, which also picked up some khan-site.css
    changes.  I guess our css has gotten simpler!
    Test Plan:
       python -mSimpleHTTPServer
    and visited
    and saw it render without error.
    Reviewers: john
    Reviewed By: john
    Subscribers: emily
    Differential Revision:
    csilvers committed Oct 22, 2015
  2. Change from $._ and $.ngettext over to i18n._ and i18n.ngettext.

    With D22593 and followups, we can now move from $._ to i18n._,
    removing an (arbitrary) dependence of translation code on jquery.
    This is a mostly-automated process: .  First I found files that use $._
    and changed them to i18n._.  Then I added the necessary require lines,
    either reusing an existing require of i18n.js if it exists, or adding
    a new one if it didn't:
        git grep -l '$\._(' | xargs perl -pli -e 's/\$\._/i18n._/g'
        git grep -l '$\.ngettext(' | xargs perl -pli -e 's/\$\.ngettext/i18n.ngettext/g'
    I then cleaned up, particularly
    I also had to add 'no-undef' eslint directives to a bunch of files,
    since khan-exercises doesn't have a proper require() system, and
    depends on i18n being a global.
    Test Plan:
       python -mSimpleHTTPServer
    and visited
    and saw it render properly.
    Reviewers: john
    Reviewed By: john
    Subscribers: emily
    Differential Revision:
    csilvers committed Oct 22, 2015
  3. Copy over an ES5-compatible version of i18n.js.

    It turns out that some of the tests in khan-exercises use phantomjs,
    which doesn't know about all those cool new ES6/7 features.  Luckily,
    we have a transpiled version of i18n.js around to use instead.  So
    Auditors: jlfwong
    Test Plan:
    phantomjs test/runner.js test/index.html
    csilvers committed Oct 22, 2015
Commits on Oct 21, 2015
  1. Update the local files, and update the local script as well.

    i18n.js has been rewritten a lot since the last time we updated locals
    (in mid-2014).  In particular it now uses our new build scheme with
    require lines and module.exports and a bunch of other stuff
    khan-exercises doesn't like.  This massages things so they work
    again.  It's fragile, but working!
    Auditors: jlfwong
    Test Plan:
       python -mSimpleHTTPServer
    and visited
    and saw it render properly.
    csilvers committed Oct 21, 2015
Commits on Oct 13, 2015
  1. Add a bunch of eslint-disable comments for legacy code.

    We're introducing a new, stricter js/jsx linter in the khan-linter
    repo: eslint.  It has a bunch of rules to enforce our style guide,
    that the old jshint did not have.  But most legacy code doesn't follow
    our style guide so well.
    This change allows us to upgrade to the new linter for new code, while
    keeping old code compliant.  I do this by adding 'eslint-disable'
    directives everywhere.
    Here's the mondo command I ran to do this all automatically.  First, I
    applied D22374 in my khan/devtools/khan-linter rule.  Then, in
    khan-exercises/, I ran this mondo command:
      ~/khan/devtools/khan-linter/ > /var/tmp/le
      cat /var/tmp/le | grep -v 'File ignored' | perl -nle '/^([^:]*):\d+:\d+: [EW]([^ ]*)/ and print "$1 $2"' | sort -u | perl -ane '$t{$F[0]} .= " $F[1],"; if (eof) {for $k (keys %t) { chop $t{$k}; open(OLD, $k); open(NEW, ">$k.tmp"); print NEW qq{/* TODO(csilvers): fix these lint errors ( */\n/* eslint-disable$t{$k} */\n/* To fix, remove an entry above, run ka-lint, and fix errors. */\n\n}; while (<OLD>) {print NEW $_}; close(OLD); close(NEW); rename("$k.tmp", "$k") }}'
    It's not as bad as it looks.  Basically it runs the linter, munges the
    output to be 'filename violated-rule-name' pairs, and then uses some
    perl to collect all the violated-rules for a single filename in one
    place, and to prepend the appropriate eslint-disable comment on to the
    Test Plan:
    In khan-exercises/, ran
    and saw no errors.
    Reviewers: emily, kevinb
    Subscribers: john
    Differential Revision:
    csilvers committed Oct 13, 2015
  2. Add more specific types to fix 2 exercises on mobile

    Points, Lines and Planes & Caesar Cipher Decryption were both unanswerable on
    mobile, because they both want something other than an equasion or a number.
    With more specific grammars, (and in conjunction with a recent update to the
    iOS app), they can now be answered!
    These are the only two exercises that I found which were unanswerable for
    grammar-related reasons, and I don't think there are any more, at least within
    Test Plan:
    Fire up khan-exercises locally (see readme), and try out both affected
    exercises. Verify that they are still answerable on the web.
    Reviewers: charlie, emily
    Reviewed By: emily
    Subscribers: andy, bryan, #ios
    Differential Revision:
    jaredly committed Oct 13, 2015
Commits on Oct 8, 2015
  1. Add processText function.

    This adds a `processText` function analogous to the
    `processMath` function which allows labels which aren't mathy to be
    re-rendered as non-mathy.
    This is used for graphie label jipt, so we can re-render text labels
    with the translated text.
    Test Plan:
     - Visit http://exercises.ka.local/exercises/division_1.html
     - Take all the hints.
     - See that the "We can make a row of n circles" and "How many circles
       are there if we make m rows?" labels look good.
     - In the console, run
       `label = KhanUtil.currentGraph.label([0, 0], "test", "center", false)`
     - See that a label appears over the division, centered on the left
     - Run `label.processText("this is a longer string")`, see that the new
       string is rendered and is appropriately centered.
    Reviewers: eater, emily
    Reviewed By: eater
    Subscribers: kevinb
    Differential Revision:
    kevinbarabash committed Oct 8, 2015
Commits on Oct 1, 2015
  1. Temporarily don't detect offline hints.

    Hopefully fixes
    The plan is to monitor Zendesk for a day after this is deployed.
    If this reduces the number of reports of hints being seen
    substantially, we con probably fix this by including the item
    sha in the hint detection and we can do this. A real repro has been
    a bear to reproduce, so this test plan is the best we can do.
    Test Plan:
    In Firefox, Chrome, Safari, and incognito for each of those:
    1. Open an exercise on your learning dashboard that has hints.
    2. Kill your dev server
    3. Take a hint
    4. Refresh the page to show a blank page
    5. Start your dev server
    6. Refresh the page to show the exercise again
    7. Verify there are no errors (though stil no hints)
    8. Congrats! You're a cheater
    Reviewers: johnsullivan
    Reviewed By: johnsullivan
    Differential Revision:
    eliawry committed Oct 1, 2015
  2. Revert change to remove mathzoom from khan-exercises

    The change didn't have the effect I expected; in testing, this change seemed to stop MathJax from attempting to load MathZoom.js (which used to cause a 'File failed to load' error in the iOS app), but after landing & testing again, the error returned.
    Reverting instead of updating webapp to point to the version of khan-exercise with the rebuilt mathjax.
    Test Plan:
    Check out problems like 'finding absolute value' and 'subtracting within 1000' in webapp; they still load!
    I can't check the behavior in the iOS app right now because exercises crash on load in Xcode 7, and I suspect Xcode 6 is failing to build while Xcode 7 is open looking at the project (while Xcode 7 downloads iOS 8 simulators). I'd like to land this before checking on iOS, though, so we don't risk someone bumping the k-e submodule without updating MathJax references in socrates & the webapp html template.
    Reviewers: kevinb, emily, jared, james
    Reviewed By: james
    Subscribers: james, #ios
    Differential Revision:
    lsavino committed Oct 1, 2015
Commits on Sep 30, 2015
  1. Remove MathZoom from, and rebuild MathJax

    MathZoom was still being linked from MathJax, and mobile clients were showing a "File failed to load" error every time a user first loaded an exercise. This removes (hopefully) the last reference to MathZoom.
    Still TODO: Once this is landed, update socrates.js with the link to the appropriate KAthJax config file.
    Test Plan:
    Load a new khan-exercises exercise in iOS ('finding absolute value' is favorite); you can interact with the exercise and the 'file failed to load' error no longer shows.
    Make the same changes in webapp (remove the MathZoom reference & rebuild), and khan-exercises still load & show progress.
    Reviewers: emily, kevinb
    Reviewed By: kevinb
    Subscribers: andy, #ios
    Differential Revision:
    lsavino committed Sep 30, 2015
Commits on Sep 24, 2015
  1. Send Travis alerts to Slack instead of HipChat

    Summary: See also D21940 in perseus.
    Test Plan: fingers crossed.
    Reviewers: eater, mroth
    Reviewed By: mroth
    Subscribers: benjaminpollack
    Differential Revision:
    benjaminjkraft committed Sep 23, 2015
Commits on Sep 22, 2015
  1. Fix rounding whole numbers

    Users are stuck on rounding whole numbers because the place they are supposed to round to is not being displayed.
    Perhaps the problem is with casting TPLACE to a string. This does that manually.
    The relevant asana task is
    Before this diff, debug information would display
    TPLACE as {}, now it will display as "ten" or whatever the appropriate number is. TPLACEPLURAL will be "tens" or the corresponding number.
    I hope this works - I wasn't able to repro the bug on my machine, and no one at KA has been able to. I'll follow up a day after deploy and see if this has fixed the problem. I suspect it will.
    Test Plan:
    The debug information seems more sensible now - instead of logging TPLACE as {}, it logs it as the appropriate number.
    I wish I could repro, but so far no one's been able to do so. I think it makes sense to deploy this and see if the problems go away. Another option would be to replace this exercise with a perseus exercise with the same content.
    Reviewers: eater, emily
    Reviewed By: emily
    Differential Revision:
    eliawry committed Sep 22, 2015
Commits on Sep 17, 2015
  1. Remove MathZoom.js from MathJax

    In a previous diff I added MathZoom.js from MathJax because some browsers were
    requesting.  This diff removes the file and removes it from the list of extensions
    we might load.  In a follow up diff I will update references to the old MathJax
    config in webapp so that they're pointing at this new build.
    Test Plan:
    - load http://localhost:8080/math/algebra/systems-of-linear-equations/introduction-to-systems-of-linear-equations/e/verifying-solutions-to-systems-of-equations?mp-r-id=yqKY-Ao=
    - verify that MathJax.js loads but that the browser doesn't load (or try to load) MathZoom.js
    Reviewers: emily
    Subscribers: eater
    Differential Revision:
    kevinbarabash committed Sep 17, 2015
Commits on Sep 16, 2015