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
970a7f09
Commit
970a7f09
authored
Jun 27, 2013
by
Felix Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed some docstring formatting things.
Expanded test coverage a little.
parent
b6760ceb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
92 additions
and
30 deletions
+92
-30
common/lib/xmodule/xmodule/crowdsource_hinter.py
+10
-10
common/lib/xmodule/xmodule/tests/test_crowdsource_hinter.py
+15
-0
lms/djangoapps/instructor/hint_manager.py
+15
-15
lms/djangoapps/instructor/tests/test_hint_manager.py
+52
-5
No files found.
common/lib/xmodule/xmodule/crowdsource_hinter.py
View file @
970a7f09
...
@@ -129,11 +129,11 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
...
@@ -129,11 +129,11 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Called by hinter javascript after a problem is graded as incorrect.
Called by hinter javascript after a problem is graded as incorrect.
Args:
Args:
get
-- must be interpretable by capa_answer_to_str.
`get`
-- must be interpretable by capa_answer_to_str.
Output keys:
Output keys:
-
best_hint
is the hint text with the most votes.
-
'best_hint'
is the hint text with the most votes.
-
rand_hint_1 and rand_hint_2 are two random hints to the answer in get
.
-
'rand_hint_1' and 'rand_hint_2' are two random hints to the answer in `get`
.
-
answer
is the parsed answer that was submitted.
-
'answer'
is the parsed answer that was submitted.
"""
"""
answer
=
self
.
capa_answer_to_str
(
get
)
answer
=
self
.
capa_answer_to_str
(
get
)
# Look for a hint to give.
# Look for a hint to give.
...
@@ -176,10 +176,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
...
@@ -176,10 +176,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
The student got it correct. Ask him to vote on hints, or submit a hint.
The student got it correct. Ask him to vote on hints, or submit a hint.
Args:
Args:
get
-- not actually used. (It is assumed that the answer is correct.)
`get`
-- not actually used. (It is assumed that the answer is correct.)
Output keys:
Output keys:
-
index_to_hints
maps previous answer indices to hints that the user saw earlier.
-
'index_to_hints'
maps previous answer indices to hints that the user saw earlier.
-
index_to_answer
maps previous answer indices to the actual answer submitted.
-
'index_to_answer'
maps previous answer indices to the actual answer submitted.
"""
"""
# The student got it right.
# The student got it right.
# Did he submit at least one wrong answer?
# Did he submit at least one wrong answer?
...
@@ -217,10 +217,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
...
@@ -217,10 +217,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Tally a user's vote on his favorite hint.
Tally a user's vote on his favorite hint.
Args:
Args:
get
-- expected to have the following keys:
`get`
-- expected to have the following keys:
'answer': ans_no (index in previous_answers)
'answer': ans_no (index in previous_answers)
'hint': hint_pk
'hint': hint_pk
Returns key
hint_and_votes
, a list of (hint_text, #votes) pairs.
Returns key
'hint_and_votes'
, a list of (hint_text, #votes) pairs.
"""
"""
if
self
.
user_voted
:
if
self
.
user_voted
:
return
json
.
dumps
({
'contents'
:
'Sorry, but you have already voted!'
})
return
json
.
dumps
({
'contents'
:
'Sorry, but you have already voted!'
})
...
@@ -250,7 +250,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
...
@@ -250,7 +250,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Take a hint submission and add it to the database.
Take a hint submission and add it to the database.
Args:
Args:
get
-- expected to have the following keys:
`get`
-- expected to have the following keys:
'answer': answer index in previous_answers
'answer': answer index in previous_answers
'hint': text of the new hint that the user is adding
'hint': text of the new hint that the user is adding
Returns a thank-you message.
Returns a thank-you message.
...
...
common/lib/xmodule/xmodule/tests/test_crowdsource_hinter.py
View file @
970a7f09
...
@@ -192,6 +192,21 @@ class CrowdsourceHinterTest(unittest.TestCase):
...
@@ -192,6 +192,21 @@ class CrowdsourceHinterTest(unittest.TestCase):
self
.
assertTrue
(
'This is supposed to be test html.'
in
out_html
)
self
.
assertTrue
(
'This is supposed to be test html.'
in
out_html
)
self
.
assertTrue
(
'this/is/a/fake/ajax/url'
in
out_html
)
self
.
assertTrue
(
'this/is/a/fake/ajax/url'
in
out_html
)
def
test_gethtml_nochild
(
self
):
"""
get_html, except the module has no child :( Should return a polite
error message.
"""
m
=
CHModuleFactory
.
create
()
def
fake_get_display_items
():
"""
Returns no children.
"""
return
[]
m
.
get_display_items
=
fake_get_display_items
out_html
=
m
.
get_html
()
self
.
assertTrue
(
'Error in loading crowdsourced hinter'
in
out_html
)
def
test_gethtml_multiple
(
self
):
def
test_gethtml_multiple
(
self
):
"""
"""
Makes sure that multiple crowdsourced hinters play nice, when get_html
Makes sure that multiple crowdsourced hinters play nice, when get_html
...
...
lms/djangoapps/instructor/hint_manager.py
View file @
970a7f09
...
@@ -54,17 +54,17 @@ def get_hints(request, course_id, field):
...
@@ -54,17 +54,17 @@ def get_hints(request, course_id, field):
Load all of the hints submitted to the course.
Load all of the hints submitted to the course.
Args:
Args:
request
-- Django request object.
`request`
-- Django request object.
course_id
-- The course id, like 'Me/19.002/test_course'
`course_id`
-- The course id, like 'Me/19.002/test_course'
field
-- Either 'hints' or 'mod_queue'; specifies which set of hints to load.
`field`
-- Either 'hints' or 'mod_queue'; specifies which set of hints to load.
Keys in returned dict:
Keys in returned dict:
-
field
: Same as input
-
'field'
: Same as input
-
other_field: 'mod_queue' if field
== 'hints'; and vice-versa.
-
'other_field': 'mod_queue' if `field`
== 'hints'; and vice-versa.
-
field_label, other_field_label
: English name for the above.
-
'field_label', 'other_field_label'
: English name for the above.
-
all_hints
: A list of [answer, pk dict] pairs, representing all hints.
-
'all_hints'
: A list of [answer, pk dict] pairs, representing all hints.
Sorted by answer.
Sorted by answer.
-
id_to_name
: A dictionary mapping problem id to problem name.
-
'id_to_name'
: A dictionary mapping problem id to problem name.
"""
"""
if
field
==
'mod_queue'
:
if
field
==
'mod_queue'
:
other_field
=
'hints'
other_field
=
'hints'
...
@@ -92,8 +92,8 @@ def get_hints(request, course_id, field):
...
@@ -92,8 +92,8 @@ def get_hints(request, course_id, field):
def
answer_sorter
(
thing
):
def
answer_sorter
(
thing
):
"""
"""
thing is a tuple, where thing[0] contains an answer, and thing[1]
contains
`thing` is a tuple, where `thing[0]` contains an answer, and `thing[1]`
contains
a dict of hints. This function returns an index based on
thing[0]
, which
a dict of hints. This function returns an index based on
`thing[0]`
, which
is used as a key to sort the list of things.
is used as a key to sort the list of things.
"""
"""
try
:
try
:
...
@@ -131,10 +131,10 @@ def delete_hints(request, course_id, field):
...
@@ -131,10 +131,10 @@ def delete_hints(request, course_id, field):
"""
"""
Deletes the hints specified.
Deletes the hints specified.
request.POST
contains some fields keyed by integers. Each such field contains a
`request.POST`
contains some fields keyed by integers. Each such field contains a
[problem_defn_id, answer, pk] tuple. These tuples specify the hints to be deleted.
[problem_defn_id, answer, pk] tuple. These tuples specify the hints to be deleted.
Example
request.POST
:
Example
`request.POST`
:
{'op': 'delete_hints',
{'op': 'delete_hints',
'field': 'mod_queue',
'field': 'mod_queue',
1: ['problem_whatever', '42.0', '3'],
1: ['problem_whatever', '42.0', '3'],
...
@@ -158,8 +158,8 @@ def change_votes(request, course_id, field):
...
@@ -158,8 +158,8 @@ def change_votes(request, course_id, field):
"""
"""
Updates the number of votes.
Updates the number of votes.
The numbered fields of
request.POST
contain [problem_id, answer, pk, new_votes] tuples.
The numbered fields of
`request.POST`
contain [problem_id, answer, pk, new_votes] tuples.
- Very similar to
delete_hints
. Is there a way to merge them? Nah, too complicated.
- Very similar to
`delete_hints`
. Is there a way to merge them? Nah, too complicated.
"""
"""
for
key
in
request
.
POST
:
for
key
in
request
.
POST
:
...
@@ -176,7 +176,7 @@ def change_votes(request, course_id, field):
...
@@ -176,7 +176,7 @@ def change_votes(request, course_id, field):
def
add_hint
(
request
,
course_id
,
field
):
def
add_hint
(
request
,
course_id
,
field
):
"""
"""
Add a new hint.
request.POST
:
Add a new hint.
`request.POST`
:
op
op
field
field
problem - The problem id
problem - The problem id
...
...
lms/djangoapps/instructor/tests/test_hint_manager.py
View file @
970a7f09
...
@@ -74,13 +74,17 @@ class HintManagerTest(ModuleStoreTestCase):
...
@@ -74,13 +74,17 @@ class HintManagerTest(ModuleStoreTestCase):
rejected.
rejected.
"""
"""
out
=
self
.
c
.
post
(
self
.
url
,
{
'op'
:
'delete hints'
,
'field'
:
'all your private data'
})
out
=
self
.
c
.
post
(
self
.
url
,
{
'op'
:
'delete hints'
,
'field'
:
'all your private data'
})
# Keep this around for reference - might be useful later.
# request = RequestFactory()
# post = request.post(self.url, {'op': 'delete hints', 'field': 'all your private data'})
# out = view.hint_manager(post, 'Me/19.002/test_course')
print
out
print
out
self
.
assertTrue
(
'an invalid field was accessed'
in
out
.
content
)
self
.
assertTrue
(
'an invalid field was accessed'
in
out
.
content
)
def
test_switchfields
(
self
):
"""
Checks that the op: 'switch fields' POST request works.
"""
out
=
self
.
c
.
post
(
self
.
url
,
{
'op'
:
'switch fields'
,
'field'
:
'mod_queue'
})
print
out
self
.
assertTrue
(
'Hint 2'
in
out
.
content
)
def
test_gethints
(
self
):
def
test_gethints
(
self
):
"""
"""
Checks that gethints returns the right data.
Checks that gethints returns the right data.
...
@@ -93,6 +97,21 @@ class HintManagerTest(ModuleStoreTestCase):
...
@@ -93,6 +97,21 @@ class HintManagerTest(ModuleStoreTestCase):
expected
=
{
self
.
problem_id
:
[(
u'2.0'
,
{
u'2'
:
[
u'Hint 2'
,
1
]})]}
expected
=
{
self
.
problem_id
:
[(
u'2.0'
,
{
u'2'
:
[
u'Hint 2'
,
1
]})]}
self
.
assertTrue
(
out
[
'all_hints'
]
==
expected
)
self
.
assertTrue
(
out
[
'all_hints'
]
==
expected
)
def
test_gethints_other
(
self
):
"""
Same as above, with hints instead of mod_queue
"""
request
=
RequestFactory
()
post
=
request
.
post
(
self
.
url
,
{
'field'
:
'hints'
})
out
=
view
.
get_hints
(
post
,
self
.
course_id
,
'hints'
)
print
out
self
.
assertTrue
(
out
[
'other_field'
]
==
'mod_queue'
)
expected
=
{
self
.
problem_id
:
[(
'1.0'
,
{
'1'
:
[
'Hint 1'
,
2
],
'3'
:
[
'Hint 3'
,
12
]}),
(
'2.0'
,
{
'4'
:
[
'Hint 4'
,
3
]})
]}
self
.
assertTrue
(
out
[
'all_hints'
]
==
expected
)
def
test_deletehints
(
self
):
def
test_deletehints
(
self
):
"""
"""
Checks that delete_hints deletes the right stuff.
Checks that delete_hints deletes the right stuff.
...
@@ -119,7 +138,35 @@ class HintManagerTest(ModuleStoreTestCase):
...
@@ -119,7 +138,35 @@ class HintManagerTest(ModuleStoreTestCase):
print
json
.
loads
(
problem_hints
)[
'1.0'
][
'1'
]
print
json
.
loads
(
problem_hints
)[
'1.0'
][
'1'
]
self
.
assertTrue
(
json
.
loads
(
problem_hints
)[
'1.0'
][
'1'
][
1
]
==
5
)
self
.
assertTrue
(
json
.
loads
(
problem_hints
)[
'1.0'
][
'1'
][
1
]
==
5
)
def
test_addhint
(
self
):
"""
Check that instructors can add new hints.
"""
request
=
RequestFactory
()
post
=
request
.
post
(
self
.
url
,
{
'field'
:
'mod_queue'
,
'op'
:
'add hint'
,
'problem'
:
self
.
problem_id
,
'answer'
:
'3.14'
,
'hint'
:
'This is a new hint.'
})
view
.
add_hint
(
post
,
self
.
course_id
,
'mod_queue'
)
problem_hints
=
XModuleContentField
.
objects
.
get
(
field_name
=
'mod_queue'
,
definition_id
=
self
.
problem_id
)
.
value
self
.
assertTrue
(
'3.14'
in
json
.
loads
(
problem_hints
))
def
test_approve
(
self
):
"""
Check that instructors can approve hints. (Move them
from the mod_queue to the hints.)
"""
request
=
RequestFactory
()
post
=
request
.
post
(
self
.
url
,
{
'field'
:
'mod_queue'
,
'op'
:
'approve'
,
1
:
[
self
.
problem_id
,
'2.0'
,
'2'
]})
view
.
approve
(
post
,
self
.
course_id
,
'mod_queue'
)
problem_hints
=
XModuleContentField
.
objects
.
get
(
field_name
=
'mod_queue'
,
definition_id
=
self
.
problem_id
)
.
value
self
.
assertTrue
(
'2.0'
not
in
json
.
loads
(
problem_hints
)
or
len
(
json
.
loads
(
problem_hints
)[
'2.0'
])
==
0
)
problem_hints
=
XModuleContentField
.
objects
.
get
(
field_name
=
'hints'
,
definition_id
=
self
.
problem_id
)
.
value
self
.
assertTrue
(
json
.
loads
(
problem_hints
)[
'2.0'
][
'2'
]
==
[
'Hint 2'
,
1
])
self
.
assertTrue
(
len
(
json
.
loads
(
problem_hints
)[
'2.0'
])
==
2
)
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