diff --git a/lms/djangoapps/grades/course_grade.py b/lms/djangoapps/grades/course_grade.py index a396bbf64f..1af0421ee3 100644 --- a/lms/djangoapps/grades/course_grade.py +++ b/lms/djangoapps/grades/course_grade.py @@ -1,19 +1,22 @@ """ CourseGrade Class """ +from __future__ import absolute_import + from abc import abstractmethod from collections import OrderedDict, defaultdict +import six +from ccx_keys.locator import CCXLocator from django.conf import settings from lazy import lazy -from ccx_keys.locator import CCXLocator from xmodule import block_metadata_utils from .config import assume_zero_if_absent +from .scores import compute_percent from .subsection_grade import ZeroSubsectionGrade from .subsection_grade_factory import SubsectionGradeFactory -from .scores import compute_percent class CourseGradeBase(object): @@ -33,7 +36,7 @@ class CourseGradeBase(object): def __unicode__(self): return u'Course Grade: percent: {}, letter_grade: {}, passed: {}'.format( - unicode(self.percent), + six.text_type(self.percent), self.letter_grade, self.passed, ) @@ -64,7 +67,7 @@ class CourseGradeBase(object): a dict keyed by subsection format types. """ subsections_by_format = defaultdict(OrderedDict) - for chapter in self.chapter_grades.itervalues(): + for chapter in six.itervalues(self.chapter_grades): for subsection_grade in chapter['sections']: if subsection_grade.graded: graded_total = subsection_grade.graded_total @@ -93,7 +96,7 @@ class CourseGradeBase(object): keyed by subsection location. """ subsection_grades = defaultdict(OrderedDict) - for chapter in self.chapter_grades.itervalues(): + for chapter in six.itervalues(self.chapter_grades): for subsection_grade in chapter['sections']: subsection_grades[subsection_grade.location] = subsection_grade return subsection_grades @@ -104,7 +107,7 @@ class CourseGradeBase(object): Returns a dict of problem scores keyed by their locations. """ problem_scores = {} - for chapter in self.chapter_grades.itervalues(): + for chapter in six.itervalues(self.chapter_grades): for subsection_grade in chapter['sections']: problem_scores.update(subsection_grade.problem_scores) return problem_scores @@ -205,6 +208,7 @@ class CourseGradeBase(object): """ chapter_subsection_grades = self._get_subsection_grades(course_structure, chapter.location) return { + # xss-lint: disable=python-deprecated-display-name 'display_name': block_metadata_utils.display_name_with_default_escaped(chapter), 'url_name': block_metadata_utils.url_name_for_block(chapter), 'sections': chapter_subsection_grades, @@ -271,7 +275,7 @@ class CourseGrade(CourseGradeBase): if assume_zero_if_absent(self.course_data.course_key): return True - for chapter in self.chapter_grades.itervalues(): + for chapter in six.itervalues(self.chapter_grades): for subsection_grade in chapter['sections']: if subsection_grade.all_total.first_attempted: return True @@ -322,4 +326,4 @@ class CourseGrade(CourseGradeBase): def _uniqueify_and_keep_order(iterable): - return OrderedDict([(item, None) for item in iterable]).keys() + return list(OrderedDict([(item, None) for item in iterable]).keys()) diff --git a/lms/djangoapps/grades/models.py b/lms/djangoapps/grades/models.py index 278a5ef31d..a287f4d314 100644 --- a/lms/djangoapps/grades/models.py +++ b/lms/djangoapps/grades/models.py @@ -8,12 +8,15 @@ a student's score or the course grading policy changes. As they are persisted, course grades are also immune to changes in course content. """ +from __future__ import absolute_import + import json import logging from base64 import b64encode from collections import defaultdict, namedtuple from hashlib import sha1 +import six from django.apps import apps from django.contrib.auth.models import User from django.db import models @@ -22,11 +25,12 @@ from lazy import lazy from model_utils.models import TimeStampedModel from opaque_keys.edx.django.models import CourseKeyField, UsageKeyField from opaque_keys.edx.keys import CourseKey, UsageKey +from simple_history.models import HistoricalRecords +from six.moves import map from coursewarehistoryextended.fields import UnsignedBigIntAutoField, UnsignedBigIntOneToOneField -from lms.djangoapps.grades import events, constants +from lms.djangoapps.grades import constants, events from openedx.core.lib.cache_utils import get_cache -from simple_history.models import HistoricalRecords log = logging.getLogger(__name__) @@ -85,10 +89,10 @@ class BlockRecordList(object): """ list_of_block_dicts = [block._asdict() for block in self.blocks] for block_dict in list_of_block_dicts: - block_dict['locator'] = unicode(block_dict['locator']) # BlockUsageLocator is not json-serializable + block_dict['locator'] = six.text_type(block_dict['locator']) # BlockUsageLocator is not json-serializable data = { u'blocks': list_of_block_dicts, - u'course_key': unicode(self.course_key), + u'course_key': six.text_type(self.course_key), u'version': self.version, } return json.dumps( @@ -450,11 +454,11 @@ class PersistentSubsectionGrade(TimeStampedModel): PersistentSubsectionGradeOverride.prefetch(user_id, course_key) - map(cls._prepare_params, grade_params_iter) + list(map(cls._prepare_params, grade_params_iter)) VisibleBlocks.bulk_get_or_create( user_id, course_key, [params['visible_blocks'] for params in grade_params_iter] ) - map(cls._prepare_params_visible_blocks_id, grade_params_iter) + list(map(cls._prepare_params_visible_blocks_id, grade_params_iter)) grades = [PersistentSubsectionGrade(**params) for params in grade_params_iter] grades = cls.objects.bulk_create(grades)