Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
problem-builder
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
OpenEdx
problem-builder
Commits
bc879077
Commit
bc879077
authored
Sep 23, 2015
by
Tim Krones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Display score (percentage) and count of correct/partial/incorrect answers.
parent
ca1e9f95
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
4 deletions
+80
-4
problem_builder/mentoring.py
+52
-0
problem_builder/public/js/mentoring_with_steps.js
+23
-3
problem_builder/step.py
+1
-1
problem_builder/templates/html/mentoring_with_steps.html
+4
-0
No files found.
problem_builder/mentoring.py
View file @
bc879077
...
@@ -869,6 +869,12 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -869,6 +869,12 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
""" Get the usage_ids of all of this XBlock's children that are "Questions" """
""" Get the usage_ids of all of this XBlock's children that are "Questions" """
return
list
(
chain
.
from_iterable
(
self
.
runtime
.
get_block
(
step_id
)
.
steps
for
step_id
in
self
.
steps
))
return
list
(
chain
.
from_iterable
(
self
.
runtime
.
get_block
(
step_id
)
.
steps
for
step_id
in
self
.
steps
))
def
get_questions
(
self
):
""" Get all questions associated with this block, cached if possible. """
if
getattr
(
self
,
"_questions_cache"
,
None
)
is
None
:
self
.
_questions_cache
=
[
self
.
runtime
.
get_block
(
question_id
)
for
question_id
in
self
.
questions
]
return
self
.
_questions_cache
@property
@property
def
steps
(
self
):
def
steps
(
self
):
"""
"""
...
@@ -880,6 +886,21 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -880,6 +886,21 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
child_isinstance
(
self
,
child_id
,
MentoringStepBlock
)
child_isinstance
(
self
,
child_id
,
MentoringStepBlock
)
]
]
def
get_steps
(
self
):
""" Get the step children of this block, cached if possible. """
if
getattr
(
self
,
"_steps_cache"
,
None
)
is
None
:
self
.
_steps_cache
=
[
self
.
runtime
.
get_block
(
child_id
)
for
child_id
in
self
.
steps
]
return
self
.
_steps_cache
def
answer_mapper
(
self
,
answer_status
):
steps
=
self
.
get_steps
()
answer_map
=
[]
for
step
in
steps
:
for
answer
in
step
.
student_results
:
if
answer
[
1
][
'status'
]
==
answer_status
:
answer_map
.
append
({
'id'
:
answer
[
0
],
'details'
:
answer
[
1
]})
return
answer_map
@property
@property
def
has_review_step
(
self
):
def
has_review_step
(
self
):
from
.step
import
ReviewStepBlock
from
.step
import
ReviewStepBlock
...
@@ -900,6 +921,27 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -900,6 +921,27 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
assessment_message
=
_
(
"Note: you have used all attempts. Continue to the next unit"
)
assessment_message
=
_
(
"Note: you have used all attempts. Continue to the next unit"
)
return
'<p>{}</p>'
.
format
(
assessment_message
)
return
'<p>{}</p>'
.
format
(
assessment_message
)
@property
def
score
(
self
):
questions
=
self
.
get_questions
()
total_child_weight
=
sum
(
float
(
question
.
weight
)
for
question
in
questions
)
if
total_child_weight
==
0
:
return
Score
(
0
,
0
,
[],
[],
[])
steps
=
self
.
get_steps
()
questions_map
=
{
question
.
name
:
question
for
question
in
questions
}
points_earned
=
0
for
step
in
steps
:
for
question_name
,
question_results
in
step
.
student_results
:
question
=
questions_map
.
get
(
question_name
)
if
question
:
# Under what conditions would this evaluate to False?
points_earned
+=
question_results
[
'score'
]
*
question
.
weight
score
=
points_earned
/
total_child_weight
correct
=
self
.
answer_mapper
(
CORRECT
)
incorrect
=
self
.
answer_mapper
(
INCORRECT
)
partially_correct
=
self
.
answer_mapper
(
PARTIAL
)
return
Score
(
score
,
int
(
round
(
score
*
100
)),
correct
,
incorrect
,
partially_correct
)
def
get_message_content
(
self
,
message_type
,
or_default
=
False
):
def
get_message_content
(
self
,
message_type
,
or_default
=
False
):
for
child_id
in
self
.
children
:
for
child_id
in
self
.
children
:
if
child_isinstance
(
self
,
child_id
,
MentoringMessageBlock
):
if
child_isinstance
(
self
,
child_id
,
MentoringMessageBlock
):
...
@@ -938,6 +980,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -938,6 +980,7 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/mentoring_with_steps.js'
))
fragment
.
add_javascript_url
(
self
.
runtime
.
local_resource_url
(
self
,
'public/js/mentoring_with_steps.js'
))
fragment
.
add_resource
(
loader
.
load_unicode
(
'templates/html/mentoring_attempts.html'
),
"text/html"
)
fragment
.
add_resource
(
loader
.
load_unicode
(
'templates/html/mentoring_attempts.html'
),
"text/html"
)
fragment
.
add_resource
(
loader
.
load_unicode
(
'templates/html/mentoring_assessment_templates.html'
),
"text/html"
)
self
.
include_theme_files
(
fragment
)
self
.
include_theme_files
(
fragment
)
...
@@ -986,6 +1029,15 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
...
@@ -986,6 +1029,15 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
}
}
@XBlock.json_handler
@XBlock.json_handler
def
get_score
(
self
,
data
,
suffix
):
return
{
'score'
:
self
.
score
.
percentage
,
'correct_answers'
:
len
(
self
.
score
.
correct
),
'incorrect_answers'
:
len
(
self
.
score
.
incorrect
),
'partially_correct_answers'
:
len
(
self
.
score
.
partially_correct
),
}
@XBlock.json_handler
def
try_again
(
self
,
data
,
suffix
=
''
):
def
try_again
(
self
,
data
,
suffix
=
''
):
self
.
active_step
=
0
self
.
active_step
=
0
...
...
problem_builder/public/js/mentoring_with_steps.js
View file @
bc879077
...
@@ -4,8 +4,10 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -4,8 +4,10 @@ function MentoringWithStepsBlock(runtime, element) {
function
(
c
)
{
return
c
.
element
.
className
.
indexOf
(
'sb-step'
)
>
-
1
;
}
function
(
c
)
{
return
c
.
element
.
className
.
indexOf
(
'sb-step'
)
>
-
1
;
}
);
);
var
activeStep
=
$
(
'.mentoring'
,
element
).
data
(
'active-step'
);
var
activeStep
=
$
(
'.mentoring'
,
element
).
data
(
'active-step'
);
var
gradeTemplate
=
_
.
template
(
$
(
'#xblock-grade-template'
).
html
());
var
attemptsTemplate
=
_
.
template
(
$
(
'#xblock-attempts-template'
).
html
());
var
attemptsTemplate
=
_
.
template
(
$
(
'#xblock-attempts-template'
).
html
());
var
reviewStep
,
checkmark
,
submitDOM
,
nextDOM
,
reviewDOM
,
tryAgainDOM
,
assessmentMessageDOM
,
attemptsDOM
,
submitXHR
;
var
reviewStep
,
checkmark
,
submitDOM
,
nextDOM
,
reviewDOM
,
tryAgainDOM
,
assessmentMessageDOM
,
gradeDOM
,
attemptsDOM
,
submitXHR
;
function
isLastStep
()
{
function
isLastStep
()
{
return
(
activeStep
===
steps
.
length
-
1
);
return
(
activeStep
===
steps
.
length
-
1
);
...
@@ -43,11 +45,25 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -43,11 +45,25 @@ function MentoringWithStepsBlock(runtime, element) {
});
});
}
}
function
updateGrade
()
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'get_score'
);
$
.
post
(
handlerUrl
,
JSON
.
stringify
({}))
.
success
(
function
(
response
)
{
gradeDOM
.
data
(
'score'
,
response
.
score
);
gradeDOM
.
data
(
'correct_answer'
,
response
.
correct_answers
);
gradeDOM
.
data
(
'incorrect_answer'
,
response
.
incorrect_answers
);
gradeDOM
.
data
(
'partially_correct_answer'
,
response
.
partially_correct_answers
);
});
}
function
handleResults
(
response
)
{
function
handleResults
(
response
)
{
// Update active step so next step is shown on page reload (even if user does not click "Next Step")
// Update active step so next step is shown on page reload (even if user does not click "Next Step")
updateActiveStep
(
activeStep
+
1
);
updateActiveStep
(
activeStep
+
1
);
if
(
response
.
update_attempts
)
{
// If step submitted was last step of this mentoring block, update grade and number of attempts used
if
(
response
.
attempt_complete
)
{
updateNumAttempts
();
updateNumAttempts
();
updateGrade
();
}
}
// Update UI
// Update UI
...
@@ -96,6 +112,7 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -96,6 +112,7 @@ function MentoringWithStepsBlock(runtime, element) {
checkmark
.
removeClass
(
'checkmark-incorrect icon-exclamation fa-exclamation'
);
checkmark
.
removeClass
(
'checkmark-incorrect icon-exclamation fa-exclamation'
);
hideAllSteps
();
hideAllSteps
();
assessmentMessageDOM
.
html
(
''
);
assessmentMessageDOM
.
html
(
''
);
gradeDOM
.
html
(
''
);
attemptsDOM
.
html
(
''
);
attemptsDOM
.
html
(
''
);
}
}
...
@@ -117,12 +134,14 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -117,12 +134,14 @@ function MentoringWithStepsBlock(runtime, element) {
}
}
function
showAssessmentMessage
()
{
function
showAssessmentMessage
()
{
var
data
=
$
(
'.grade'
,
element
)
.
data
();
var
data
=
gradeDOM
.
data
();
assessmentMessageDOM
.
html
(
data
.
assessment_message
);
assessmentMessageDOM
.
html
(
data
.
assessment_message
);
}
}
function
showReviewStep
()
{
function
showReviewStep
()
{
reviewStep
.
show
();
reviewStep
.
show
();
var
data
=
gradeDOM
.
data
();
gradeDOM
.
html
(
gradeTemplate
(
data
));
submitDOM
.
hide
();
submitDOM
.
hide
();
nextDOM
.
hide
();
nextDOM
.
hide
();
reviewDOM
.
hide
();
reviewDOM
.
hide
();
...
@@ -226,6 +245,7 @@ function MentoringWithStepsBlock(runtime, element) {
...
@@ -226,6 +245,7 @@ function MentoringWithStepsBlock(runtime, element) {
tryAgainDOM
.
on
(
'click'
,
tryAgain
);
tryAgainDOM
.
on
(
'click'
,
tryAgain
);
assessmentMessageDOM
=
$
(
'.assessment-message'
,
element
);
assessmentMessageDOM
=
$
(
'.assessment-message'
,
element
);
gradeDOM
=
$
(
'.grade'
,
element
);
attemptsDOM
=
$
(
'.attempts'
,
element
);
attemptsDOM
=
$
(
'.attempts'
,
element
);
var
options
=
{
var
options
=
{
...
...
problem_builder/step.py
View file @
bc879077
...
@@ -154,7 +154,7 @@ class MentoringStepBlock(
...
@@ -154,7 +154,7 @@ class MentoringStepBlock(
'message'
:
'Success!'
,
'message'
:
'Success!'
,
'completed'
:
completed
,
'completed'
:
completed
,
'results'
:
submit_results
,
'results'
:
submit_results
,
'
update_attempts
'
:
self
.
is_last_step
'
attempt_complete
'
:
self
.
is_last_step
}
}
def
reset
(
self
):
def
reset
(
self
):
...
...
problem_builder/templates/html/mentoring_with_steps.html
View file @
bc879077
...
@@ -17,6 +17,10 @@
...
@@ -17,6 +17,10 @@
<div
class=
"grade"
<div
class=
"grade"
data-assessment_message=
"{{ self.assessment_message }}"
data-assessment_message=
"{{ self.assessment_message }}"
data-score=
"{{ self.score.percentage }}"
data-correct_answer=
"{{ self.score.correct|length }}"
data-incorrect_answer=
"{{ self.score.incorrect|length }}"
data-partially_correct_answer=
"{{ self.score.partially_correct|length }}"
>
</div>
</div>
<div
class=
"submit"
>
<div
class=
"submit"
>
...
...
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