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
8b03ad39
Commit
8b03ad39
authored
Jan 27, 2015
by
Matt Drayer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decoupled entrance exam scoring from milestone fulfillment
parent
a9127c18
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
53 additions
and
29 deletions
+53
-29
common/djangoapps/util/milestones_helpers.py
+31
-0
common/djangoapps/util/module_utils.py
+0
-0
lms/djangoapps/courseware/grades.py
+1
-1
lms/djangoapps/courseware/module_render.py
+21
-28
No files found.
common/djangoapps/util/milestones_helpers.py
View file @
8b03ad39
...
...
@@ -7,6 +7,8 @@ from django.conf import settings
from
django.utils.translation
import
ugettext
as
_
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
courseware.models
import
StudentModule
from
xmodule.modulestore.django
import
modulestore
from
milestones.api
import
(
...
...
@@ -148,6 +150,35 @@ def fulfill_course_milestone(course_key, user):
add_user_milestone
({
'id'
:
user
.
id
},
milestone
)
def
calculate_entrance_exam_score
(
user
,
course_descriptor
,
exam_modules
):
"""
Calculates the score (percent) of the entrance exam using the provided modules
"""
exam_module_ids
=
[
exam_module
.
location
for
exam_module
in
exam_modules
]
student_modules
=
StudentModule
.
objects
.
filter
(
student
=
user
,
course_id
=
course_descriptor
.
id
,
module_state_key__in
=
exam_module_ids
,
)
exam_pct
=
0
if
student_modules
:
module_pcts
=
[]
ignore_categories
=
[
'course'
,
'chapter'
,
'sequential'
,
'vertical'
]
for
module
in
exam_modules
:
if
module
.
graded
and
module
.
category
not
in
ignore_categories
:
module_pct
=
0
try
:
student_module
=
student_modules
.
get
(
module_state_key
=
module
.
location
)
if
student_module
.
max_grade
:
module_pct
=
student_module
.
grade
/
student_module
.
max_grade
module_pcts
.
append
(
module_pct
)
except
StudentModule
.
DoesNotExist
:
pass
if
module_pcts
:
exam_pct
=
sum
(
module_pcts
)
/
float
(
len
(
module_pcts
))
return
exam_pct
def
milestones_achieved_by_user
(
user
,
namespace
):
"""
It would fetch list of milestones completed by user
...
...
lms/djangoapps/courseware
/module_utils.py
→
common/djangoapps/util
/module_utils.py
View file @
8b03ad39
File moved
lms/djangoapps/courseware/grades.py
View file @
8b03ad39
...
...
@@ -15,6 +15,7 @@ import dogstats_wrapper as dog_stats_api
from
courseware
import
courses
from
courseware.model_data
import
FieldDataCache
from
student.models
import
anonymous_id_for_user
from
util.module_utils
import
yield_dynamic_descriptor_descendents
from
xmodule
import
graders
from
xmodule.graders
import
Score
from
xmodule.modulestore.django
import
modulestore
...
...
@@ -22,7 +23,6 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from
xmodule.util.duedate
import
get_extended_due_date
from
.models
import
StudentModule
from
.module_render
import
get_module_for_descriptor
from
.module_utils
import
yield_dynamic_descriptor_descendents
from
submissions
import
api
as
sub_api
# installed from the edx-submissions repository
from
opaque_keys
import
InvalidKeyError
...
...
lms/djangoapps/courseware/module_render.py
View file @
8b03ad39
...
...
@@ -25,7 +25,6 @@ from courseware.models import StudentModule
from
lms.djangoapps.lms_xblock.field_data
import
LmsFieldData
from
lms.djangoapps.lms_xblock.runtime
import
LmsModuleSystem
,
unquote_slashes
,
quote_slashes
from
lms.djangoapps.lms_xblock.models
import
XBlockAsidesConfig
from
.module_utils
import
yield_dynamic_descriptor_descendents
from
edxmako.shortcuts
import
render_to_string
from
eventtracking
import
tracker
from
psychometrics.psychoanalyze
import
make_psychometrics_data_update_handler
...
...
@@ -59,7 +58,8 @@ from util.sandboxing import can_execute_unsafe_code, get_python_lib_zip
if
settings
.
FEATURES
.
get
(
'MILESTONES_APP'
,
False
):
from
milestones
import
api
as
milestones_api
from
milestones.exceptions
import
InvalidMilestoneRelationshipTypeException
from
util.milestones_helpers
import
serialize_user
from
util.milestones_helpers
import
serialize_user
,
calculate_entrance_exam_score
from
util.module_utils
import
yield_dynamic_descriptor_descendents
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -382,7 +382,21 @@ def get_module_system_for_user(user, field_data_cache,
request_token
=
request_token
,
)
def
_fulfill_content_milestones
(
course_key
,
content_key
,
user_id
):
# pylint: disable=unused-argument
def
_calculate_entrance_exam_score
(
user
,
course_descriptor
):
"""
Internal helper to calculate a user's score for a course's entrance exam
"""
exam_key
=
UsageKey
.
from_string
(
course_descriptor
.
entrance_exam_id
)
exam_descriptor
=
modulestore
()
.
get_item
(
exam_key
)
exam_module_generators
=
yield_dynamic_descriptor_descendents
(
exam_descriptor
,
inner_get_module
)
exam_modules
=
[
module
for
module
in
exam_module_generators
]
exam_score
=
calculate_entrance_exam_score
(
user
,
course_descriptor
,
exam_modules
)
return
exam_score
def
_fulfill_content_milestones
(
user
,
course_key
,
content_key
):
"""
Internal helper to handle milestone fulfillments for the specified content module
"""
...
...
@@ -395,30 +409,9 @@ def get_module_system_for_user(user, field_data_cache,
entrance_exam_enabled
=
getattr
(
course
,
'entrance_exam_enabled'
,
False
)
in_entrance_exam
=
getattr
(
content
,
'in_entrance_exam'
,
False
)
if
entrance_exam_enabled
and
in_entrance_exam
:
exam_key
=
UsageKey
.
from_string
(
course
.
entrance_exam_id
)
exam_descriptor
=
modulestore
()
.
get_item
(
exam_key
)
exam_modules
=
yield_dynamic_descriptor_descendents
(
exam_descriptor
,
inner_get_module
)
ignore_categories
=
[
'course'
,
'chapter'
,
'sequential'
,
'vertical'
]
module_pcts
=
[]
exam_pct
=
0
for
module
in
exam_modules
:
if
module
.
graded
and
module
.
category
not
in
ignore_categories
:
module_pct
=
0
try
:
student_module
=
StudentModule
.
objects
.
get
(
module_state_key
=
module
.
scope_ids
.
usage_id
,
student_id
=
user_id
)
if
student_module
.
max_grade
:
module_pct
=
student_module
.
grade
/
student_module
.
max_grade
except
StudentModule
.
DoesNotExist
:
pass
module_pcts
.
append
(
module_pct
)
exam_pct
=
sum
(
module_pcts
)
/
float
(
len
(
module_pcts
))
exam_pct
=
_calculate_entrance_exam_score
(
user
,
course
)
if
exam_pct
>=
course
.
entrance_exam_minimum_score_pct
:
exam_key
=
UsageKey
.
from_string
(
course
.
entrance_exam_id
)
relationship_types
=
milestones_api
.
get_milestone_relationship_types
()
content_milestones
=
milestones_api
.
get_course_content_milestones
(
course_key
,
...
...
@@ -426,7 +419,7 @@ def get_module_system_for_user(user, field_data_cache,
relationship
=
relationship_types
[
'FULFILLS'
]
)
# Add each milestone to the user's set...
user
=
{
'id'
:
user
_
id
}
user
=
{
'id'
:
user
.
id
}
for
milestone
in
content_milestones
:
milestones_api
.
add_user_milestone
(
user
,
milestone
)
...
...
@@ -470,9 +463,9 @@ def get_module_system_for_user(user, field_data_cache,
# thanks to the updated grading information that was just submitted
if
settings
.
FEATURES
.
get
(
'MILESTONES_APP'
,
False
):
_fulfill_content_milestones
(
user
,
course_id
,
descriptor
.
location
,
user_id
)
def
publish
(
block
,
event_type
,
event
):
...
...
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