From f62e5347e159386529e7fdb22a6dd8d8394efdfd Mon Sep 17 00:00:00 2001 From: zubair-arbi Date: Mon, 1 Dec 2014 14:53:59 +0500 Subject: [PATCH] round-off weight, min_count and drop_count values while returing grading policy TNL-884 --- cms/djangoapps/models/settings/course_grading.py | 3 +++ .../models/settings_course_grader_spec.coffee | 12 ++++++++---- cms/static/js/models/settings/course_grader.js | 16 +++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/cms/djangoapps/models/settings/course_grading.py b/cms/djangoapps/models/settings/course_grading.py index f00a5863ec..eb86f7e636 100644 --- a/cms/djangoapps/models/settings/course_grading.py +++ b/cms/djangoapps/models/settings/course_grading.py @@ -205,6 +205,9 @@ class CourseGradingModel(object): @staticmethod def jsonize_grader(i, grader): + # Warning: converting weight to integer might give unwanted results due + # to the reason how floating point arithmetic works + # e.g, "0.29 * 100 = 28.999999999999996" return { "id": i, "type": grader["type"], diff --git a/cms/static/coffee/spec/models/settings_course_grader_spec.coffee b/cms/static/coffee/spec/models/settings_course_grader_spec.coffee index 3007c5377f..23cf22d371 100644 --- a/cms/static/coffee/spec/models/settings_course_grader_spec.coffee +++ b/cms/static/coffee/spec/models/settings_course_grader_spec.coffee @@ -4,14 +4,18 @@ define ["js/models/settings/course_grader"], (CourseGrader) -> it "converts a float to an integer", -> model = new CourseGrader({weight: 7.0001, min_count: 3.67, drop_count: 1.88}, {parse:true}) expect(model.get('weight')).toBe(7) - expect(model.get('min_count')).toBe(3) - expect(model.get('drop_count')).toBe(1) + expect(model.get('min_count')).toBe(4) + expect(model.get('drop_count')).toBe(2) + + it "converts float value of weight to an integer with rounding", -> + model = new CourseGrader({weight: 28.999999999999996}, {parse:true}) + expect(model.get('weight')).toBe(29) it "converts a string to an integer", -> model = new CourseGrader({weight: '7.0001', min_count: '3.67', drop_count: '1.88'}, {parse:true}) expect(model.get('weight')).toBe(7) - expect(model.get('min_count')).toBe(3) - expect(model.get('drop_count')).toBe(1) + expect(model.get('min_count')).toBe(4) + expect(model.get('drop_count')).toBe(2) it "does a no-op for integers", -> model = new CourseGrader({weight: 7, min_count: 3, drop_count: 1}, {parse:true}) diff --git a/cms/static/js/models/settings/course_grader.js b/cms/static/js/models/settings/course_grader.js index 0fee8f6555..7f7716eb8b 100644 --- a/cms/static/js/models/settings/course_grader.js +++ b/cms/static/js/models/settings/course_grader.js @@ -9,14 +9,15 @@ var CourseGrader = Backbone.Model.extend({ "weight" : 0 // int 0..100 }, parse : function(attrs) { + // round off values while converting them to integer if (attrs['weight']) { - attrs.weight = parseInt(attrs.weight, 10); + attrs.weight = Math.round(attrs.weight); } if (attrs['min_count']) { - attrs.min_count = parseInt(attrs.min_count, 10); + attrs.min_count = Math.round(attrs.min_count); } if (attrs['drop_count']) { - attrs.drop_count = parseInt(attrs.drop_count, 10); + attrs.drop_count = Math.round(attrs.drop_count); } return attrs; }, @@ -35,7 +36,7 @@ var CourseGrader = Backbone.Model.extend({ } } if (_.has(attrs, 'weight')) { - var intWeight = parseInt(attrs.weight); // see if this ensures value saved is int + var intWeight = Math.round(attrs.weight); // see if this ensures value saved is int if (!isFinite(intWeight) || /\D+/.test(attrs.weight) || intWeight < 0 || intWeight > 100) { errors.weight = gettext("Please enter an integer between 0 and 100."); } @@ -50,15 +51,16 @@ var CourseGrader = Backbone.Model.extend({ } }} if (_.has(attrs, 'min_count')) { - var intMinCount = parseInt(attrs.min_count, 10); + var intMinCount = Math.round(attrs.min_count); if (!isFinite(intMinCount) || /\D+/.test(attrs.min_count) || intMinCount < 1) { errors.min_count = gettext("Please enter an integer greater than 0."); } else attrs.min_count = intMinCount; } if (_.has(attrs, 'drop_count')) { - var intDropCount = parseInt(attrs.drop_count, 10); - if (!isFinite(intDropCount) || /\D+/.test(attrs.drop_count) || isNaN(intDropCount) || intDropCount < 0) { + var dropCount = attrs.drop_count; + var intDropCount = Math.round(dropCount); + if (!isFinite(intDropCount) || /\D+/.test(dropCount) || (_.isString(dropCount) && _.isEmpty(dropCount.trim())) || intDropCount < 0) { errors.drop_count = gettext("Please enter non-negative integer."); } else attrs.drop_count = intDropCount;