Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
1b1bb948
Commit
1b1bb948
authored
Sep 22, 2016
by
Eric Fischer
Committed by
GitHub
Sep 22, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13522 from edx/efischer/standardize_grades_logging
Standardize logged errors
parents
42025461
9b9ab2e4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
36 additions
and
12 deletions
+36
-12
lms/djangoapps/grades/new/course_grade.py
+25
-6
lms/djangoapps/grades/new/subsection_grade.py
+5
-5
lms/djangoapps/grades/scores.py
+6
-1
No files found.
lms/djangoapps/grades/new/course_grade.py
View file @
1b1bb948
...
@@ -40,7 +40,6 @@ class CourseGrade(object):
...
@@ -40,7 +40,6 @@ class CourseGrade(object):
graded_total
=
subsection_grade
.
graded_total
graded_total
=
subsection_grade
.
graded_total
if
graded_total
.
possible
>
0
:
if
graded_total
.
possible
>
0
:
subsections_by_format
[
subsection_grade
.
format
]
.
append
(
graded_total
)
subsections_by_format
[
subsection_grade
.
format
]
.
append
(
graded_total
)
self
.
_log_event
(
log
.
info
,
u"subsections_by_format"
)
return
subsections_by_format
return
subsections_by_format
@lazy
@lazy
...
@@ -52,7 +51,6 @@ class CourseGrade(object):
...
@@ -52,7 +51,6 @@ class CourseGrade(object):
for
chapter
in
self
.
chapter_grades
:
for
chapter
in
self
.
chapter_grades
:
for
subsection_grade
in
chapter
[
'sections'
]:
for
subsection_grade
in
chapter
[
'sections'
]:
locations_to_weighted_scores
.
update
(
subsection_grade
.
locations_to_weighted_scores
)
locations_to_weighted_scores
.
update
(
subsection_grade
.
locations_to_weighted_scores
)
self
.
_log_event
(
log
.
info
,
u"locations_to_weighted_scores"
)
return
locations_to_weighted_scores
return
locations_to_weighted_scores
@lazy
@lazy
...
@@ -66,7 +64,10 @@ class CourseGrade(object):
...
@@ -66,7 +64,10 @@ class CourseGrade(object):
self
.
subsection_grade_totals_by_format
,
self
.
subsection_grade_totals_by_format
,
generate_random_scores
=
settings
.
GENERATE_PROFILE_SCORES
generate_random_scores
=
settings
.
GENERATE_PROFILE_SCORES
)
)
self
.
_log_event
(
log
.
info
,
u"grade_value"
)
# can't use the existing properties due to recursion issues caused by referencing self.grade_value
percent
=
self
.
_calc_percent
(
grade_value
)
letter_grade
=
self
.
_compute_letter_grade
(
percent
)
self
.
_log_event
(
log
.
warning
,
u"grade_value, percent: {0}, grade: {1}"
.
format
(
percent
,
letter_grade
))
return
grade_value
return
grade_value
@property
@property
...
@@ -82,7 +83,7 @@ class CourseGrade(object):
...
@@ -82,7 +83,7 @@ class CourseGrade(object):
"""
"""
Returns a rounded percent from the overall grade.
Returns a rounded percent from the overall grade.
"""
"""
return
round
(
self
.
grade_value
[
'percent'
]
*
100
+
0.05
)
/
100
return
self
.
_calc_percent
(
self
.
grade_value
)
@property
@property
def
letter_grade
(
self
):
def
letter_grade
(
self
):
...
@@ -114,7 +115,6 @@ class CourseGrade(object):
...
@@ -114,7 +115,6 @@ class CourseGrade(object):
grade_summary
[
'totaled_scores'
]
=
self
.
subsection_grade_totals_by_format
grade_summary
[
'totaled_scores'
]
=
self
.
subsection_grade_totals_by_format
grade_summary
[
'raw_scores'
]
=
list
(
self
.
locations_to_weighted_scores
.
itervalues
())
grade_summary
[
'raw_scores'
]
=
list
(
self
.
locations_to_weighted_scores
.
itervalues
())
self
.
_log_event
(
log
.
warning
,
u"grade_summary, percent: {0}, grade: {1}"
.
format
(
self
.
percent
,
self
.
letter_grade
))
return
grade_summary
return
grade_summary
def
compute_and_update
(
self
,
read_only
=
False
):
def
compute_and_update
(
self
,
read_only
=
False
):
...
@@ -123,7 +123,6 @@ class CourseGrade(object):
...
@@ -123,7 +123,6 @@ class CourseGrade(object):
If read_only is True, doesn't save any updates to the grades.
If read_only is True, doesn't save any updates to the grades.
"""
"""
self
.
_log_event
(
log
.
warning
,
u"compute_and_update, read_only: {}"
.
format
(
read_only
))
subsection_grade_factory
=
SubsectionGradeFactory
(
self
.
student
,
self
.
course
,
self
.
course_structure
)
subsection_grade_factory
=
SubsectionGradeFactory
(
self
.
student
,
self
.
course
,
self
.
course_structure
)
for
chapter_key
in
self
.
course_structure
.
get_children
(
self
.
course
.
location
):
for
chapter_key
in
self
.
course_structure
.
get_children
(
self
.
course
.
location
):
chapter
=
self
.
course_structure
[
chapter_key
]
chapter
=
self
.
course_structure
[
chapter_key
]
...
@@ -139,10 +138,23 @@ class CourseGrade(object):
...
@@ -139,10 +138,23 @@ class CourseGrade(object):
'sections'
:
chapter_subsection_grades
'sections'
:
chapter_subsection_grades
})
})
subsections_total
=
sum
(
len
(
x
)
for
x
in
self
.
subsection_grade_totals_by_format
.
itervalues
())
subsections_read
=
len
(
subsection_grade_factory
.
_unsaved_subsection_grades
)
# pylint: disable=protected-access
subsections_created
=
subsections_total
-
subsections_read
blocks_total
=
len
(
self
.
locations_to_weighted_scores
)
if
not
read_only
:
if
not
read_only
:
subsection_grade_factory
.
bulk_create_unsaved
()
subsection_grade_factory
.
bulk_create_unsaved
()
self
.
_signal_listeners_when_grade_computed
()
self
.
_signal_listeners_when_grade_computed
()
self
.
_log_event
(
log
.
warning
,
u"compute_and_update, read_only: {0}, subsections read/created: {1}/{2}, blocks accessed: {3}"
.
format
(
read_only
,
subsections_read
,
subsections_created
,
blocks_total
,
)
)
def
score_for_module
(
self
,
location
):
def
score_for_module
(
self
,
location
):
"""
"""
...
@@ -166,6 +178,13 @@ class CourseGrade(object):
...
@@ -166,6 +178,13 @@ class CourseGrade(object):
possible
+=
child_possible
possible
+=
child_possible
return
earned
,
possible
return
earned
,
possible
@staticmethod
def
_calc_percent
(
grade_value
):
"""
Helper for percent calculation.
"""
return
round
(
grade_value
[
'percent'
]
*
100
+
0.05
)
/
100
def
_compute_letter_grade
(
self
,
percentage
):
def
_compute_letter_grade
(
self
,
percentage
):
"""
"""
Returns a letter grade as defined in grading_policy (e.g. 'A' 'B' 'C' for 6.002x) or None.
Returns a letter grade as defined in grading_policy (e.g. 'A' 'B' 'C' for 6.002x) or None.
...
...
lms/djangoapps/grades/new/subsection_grade.py
View file @
1b1bb948
...
@@ -33,7 +33,7 @@ def persistence_safe_fallback():
...
@@ -33,7 +33,7 @@ def persistence_safe_fallback():
except
DatabaseError
:
except
DatabaseError
:
# Error deliberately logged, then swallowed. It's assumed that the wrapped code is not guaranteed to succeed.
# Error deliberately logged, then swallowed. It's assumed that the wrapped code is not guaranteed to succeed.
# TODO: enqueue a celery task to finish the task asynchronously, see TNL-5471
# TODO: enqueue a celery task to finish the task asynchronously, see TNL-5471
log
.
warning
(
"Persistent Grades:
Persistence Error, falling
back.
\n
{}"
.
format
(
format_exc
()))
log
.
warning
(
"Persistent Grades:
database_error.safe_fall
back.
\n
{}"
.
format
(
format_exc
()))
class
SubsectionGrade
(
object
):
class
SubsectionGrade
(
object
):
...
@@ -80,7 +80,7 @@ class SubsectionGrade(object):
...
@@ -80,7 +80,7 @@ class SubsectionGrade(object):
student
,
descendant_key
,
course_structure
,
scores_client
,
submissions_scores
,
persisted_values
=
{},
student
,
descendant_key
,
course_structure
,
scores_client
,
submissions_scores
,
persisted_values
=
{},
)
)
self
.
all_total
,
self
.
graded_total
=
graders
.
aggregate_scores
(
self
.
scores
,
self
.
display_name
,
self
.
location
)
self
.
all_total
,
self
.
graded_total
=
graders
.
aggregate_scores
(
self
.
scores
,
self
.
display_name
,
self
.
location
)
self
.
_log_event
(
log
.
warning
,
u"init_from_structure"
,
student
)
self
.
_log_event
(
log
.
info
,
u"init_from_structure"
,
student
)
def
init_from_model
(
self
,
student
,
model
,
course_structure
,
scores_client
,
submissions_scores
):
def
init_from_model
(
self
,
student
,
model
,
course_structure
,
scores_client
,
submissions_scores
):
"""
"""
...
@@ -112,7 +112,7 @@ class SubsectionGrade(object):
...
@@ -112,7 +112,7 @@ class SubsectionGrade(object):
section
=
self
.
display_name
,
section
=
self
.
display_name
,
module_id
=
self
.
location
,
module_id
=
self
.
location
,
)
)
self
.
_log_event
(
log
.
warning
,
u"init_from_model"
,
student
)
self
.
_log_event
(
log
.
info
,
u"init_from_model"
,
student
)
@classmethod
@classmethod
def
bulk_create_models
(
cls
,
student
,
subsection_grades
,
course_key
):
def
bulk_create_models
(
cls
,
student
,
subsection_grades
,
course_key
):
...
@@ -275,7 +275,7 @@ class SubsectionGradeFactory(object):
...
@@ -275,7 +275,7 @@ class SubsectionGradeFactory(object):
If read_only is True, doesn't save any updates to the grades.
If read_only is True, doesn't save any updates to the grades.
"""
"""
self
.
_log_event
(
self
.
_log_event
(
log
.
warning
,
u"create, read_only: {0}, subsection: {1}"
.
format
(
read_only
,
subsection
.
location
)
log
.
info
,
u"create, read_only: {0}, subsection: {1}"
.
format
(
read_only
,
subsection
.
location
)
)
)
block_structure
=
self
.
_get_block_structure
(
block_structure
)
block_structure
=
self
.
_get_block_structure
(
block_structure
)
...
@@ -298,7 +298,7 @@ class SubsectionGradeFactory(object):
...
@@ -298,7 +298,7 @@ class SubsectionGradeFactory(object):
"""
"""
Bulk creates all the unsaved subsection_grades to this point.
Bulk creates all the unsaved subsection_grades to this point.
"""
"""
self
.
_log_event
(
log
.
warning
,
u"bulk_create_unsaved"
)
self
.
_log_event
(
log
.
info
,
u"bulk_create_unsaved"
)
with
persistence_safe_fallback
():
with
persistence_safe_fallback
():
SubsectionGrade
.
bulk_create_models
(
self
.
student
,
self
.
_unsaved_subsection_grades
,
self
.
course
.
id
)
SubsectionGrade
.
bulk_create_models
(
self
.
student
,
self
.
_unsaved_subsection_grades
,
self
.
course
.
id
)
...
...
lms/djangoapps/grades/scores.py
View file @
1b1bb948
...
@@ -89,7 +89,12 @@ def get_score(user, block, scores_client, submissions_scores_cache, weight, poss
...
@@ -89,7 +89,12 @@ def get_score(user, block, scores_client, submissions_scores_cache, weight, poss
if
possible
is
None
:
if
possible
is
None
:
possible
=
score
.
total
possible
=
score
.
total
elif
possible
!=
score
.
total
:
elif
possible
!=
score
.
total
:
log
.
error
(
u"Persisted Grades: possible value {} != score.total value {}"
.
format
(
possible
,
score
.
total
))
log
.
error
(
u"Persistent Grades: scores.get_score, possible value {} != score.total value {}"
.
format
(
possible
,
score
.
total
)
)
else
:
else
:
# This means we don't have a valid score entry and we don't have a
# This means we don't have a valid score entry and we don't have a
# cached_max_score on hand. We know they've earned 0.0 points on this.
# cached_max_score on hand. We know they've earned 0.0 points on this.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment