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
304e9682
Commit
304e9682
authored
Jun 07, 2012
by
Calen Pennington
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move tests for xmodules into the xmodule library, and make them run without django
parent
c144bb47
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
100 additions
and
124 deletions
+100
-124
common/lib/capa/capa_problem.py
+0
-2
common/lib/capa/inputtypes.py
+19
-21
common/lib/capa/responsetypes.py
+6
-8
common/lib/xmodule/capa_module.py
+6
-8
common/lib/xmodule/graders.py
+20
-25
common/lib/xmodule/html_module.py
+1
-4
common/lib/xmodule/seq_module.py
+2
-4
common/lib/xmodule/template_module.py
+1
-3
common/lib/xmodule/test_files/imageresponse.xml
+0
-0
common/lib/xmodule/test_files/multi_bare.xml
+0
-0
common/lib/xmodule/test_files/multichoice.xml
+0
-0
common/lib/xmodule/test_files/optionresponse.xml
+0
-0
common/lib/xmodule/test_files/test_files/symbolicresponse.xml
+0
-0
common/lib/xmodule/test_files/truefalse.xml
+0
-0
common/lib/xmodule/tests.py
+2
-3
common/lib/xmodule/vertical_module.py
+3
-3
common/lib/xmodule/video_module.py
+7
-7
common/lib/xmodule/x_module.py
+0
-7
lms/djangoapps/courseware/grades.py
+3
-24
lms/djangoapps/courseware/module_render.py
+4
-1
lms/lib/dogfood/views.py
+1
-0
rakefile
+25
-4
No files found.
common/lib/capa/capa_problem.py
View file @
304e9682
...
@@ -21,8 +21,6 @@ from lxml import etree
...
@@ -21,8 +21,6 @@ from lxml import etree
from
lxml.etree
import
Element
from
lxml.etree
import
Element
from
xml.sax.saxutils
import
escape
,
unescape
from
xml.sax.saxutils
import
escape
,
unescape
from
mako.template
import
Template
from
util
import
contextualize_text
from
util
import
contextualize_text
import
inputtypes
import
inputtypes
...
...
common/lib/capa/inputtypes.py
View file @
304e9682
...
@@ -27,8 +27,6 @@ import shlex # for splitting quoted strings
...
@@ -27,8 +27,6 @@ import shlex # for splitting quoted strings
from
lxml
import
etree
from
lxml
import
etree
from
mitxmako.shortcuts
import
render_to_string
def
get_input_xml_tags
():
def
get_input_xml_tags
():
''' Eventually, this will be for all registered input types '''
''' Eventually, this will be for all registered input types '''
return
SimpleInput
.
get_xml_tags
()
return
SimpleInput
.
get_xml_tags
()
...
@@ -54,7 +52,7 @@ class SimpleInput():# XModule
...
@@ -54,7 +52,7 @@ class SimpleInput():# XModule
return
[
'capa_input'
,
'capa_transform'
]
return
[
'capa_input'
,
'capa_transform'
]
def
get_html
(
self
):
def
get_html
(
self
):
return
self
.
xml_tags
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
msg
)
return
self
.
xml_tags
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
system
.
render_template
,
self
.
msg
)
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
self
.
xml
=
xml
self
.
xml
=
xml
...
@@ -144,7 +142,7 @@ def register_render_function(fn, names=None, cls=SimpleInput):
...
@@ -144,7 +142,7 @@ def register_render_function(fn, names=None, cls=SimpleInput):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
def
optioninput
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
Select option input type.
Select option input type.
...
@@ -171,12 +169,12 @@ def optioninput(element, value, status, msg=''):
...
@@ -171,12 +169,12 @@ def optioninput(element, value, status, msg=''):
'options'
:
osetdict
,
'options'
:
osetdict
,
}
}
html
=
render_to_string
(
"optioninput.html"
,
context
)
html
=
render_template
(
"optioninput.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
def
choicegroup
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
Radio button inputs: multiple choice or true/false
Radio button inputs: multiple choice or true/false
...
@@ -199,11 +197,11 @@ def choicegroup(element, value, status, msg=''):
...
@@ -199,11 +197,11 @@ def choicegroup(element, value, status, msg=''):
ctext
+=
choice
.
text
# TODO: fix order?
ctext
+=
choice
.
text
# TODO: fix order?
choices
[
choice
.
get
(
"name"
)]
=
ctext
choices
[
choice
.
get
(
"name"
)]
=
ctext
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'type'
:
type
,
'choices'
:
choices
}
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'type'
:
type
,
'choices'
:
choices
}
html
=
render_to_string
(
"choicegroup.html"
,
context
)
html
=
render_template
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
@register_render_function
@register_render_function
def
textline
(
element
,
value
,
state
,
msg
=
""
):
def
textline
(
element
,
value
,
state
,
render_template
,
msg
=
""
):
'''
'''
Simple text line input, with optional size specification.
Simple text line input, with optional size specification.
'''
'''
...
@@ -213,13 +211,13 @@ def textline(element, value, state, msg=""):
...
@@ -213,13 +211,13 @@ def textline(element, value, state, msg=""):
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
size
=
element
.
get
(
'size'
)
size
=
element
.
get
(
'size'
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
state
,
'count'
:
count
,
'size'
:
size
,
'msg'
:
msg
}
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
state
,
'count'
:
count
,
'size'
:
size
,
'msg'
:
msg
}
html
=
render_to_string
(
"textinput.html"
,
context
)
html
=
render_template
(
"textinput.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
textline_dynamath
(
element
,
value
,
status
,
msg
=
''
):
def
textline_dynamath
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
Text line input with dynamic math display (equation rendered on client in real time during input).
Text line input with dynamic math display (equation rendered on client in real time during input).
'''
'''
...
@@ -237,13 +235,13 @@ def textline_dynamath(element, value, status, msg=''):
...
@@ -237,13 +235,13 @@ def textline_dynamath(element, value, status, msg=''):
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'count'
:
count
,
'size'
:
size
,
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'count'
:
count
,
'size'
:
size
,
'msg'
:
msg
,
'msg'
:
msg
,
}
}
html
=
render_to_string
(
"textinput_dynamath.html"
,
context
)
html
=
render_template
(
"textinput_dynamath.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
## TODO: Make a wrapper for <codeinput>
## TODO: Make a wrapper for <codeinput>
@register_render_function
@register_render_function
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
def
textbox
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
The textbox is used for code input. The message is the return HTML string from
The textbox is used for code input. The message is the return HTML string from
evaluating the code, eg error messages, and output from the code tests.
evaluating the code, eg error messages, and output from the code tests.
...
@@ -261,12 +259,12 @@ def textbox(element, value, status, msg=''):
...
@@ -261,12 +259,12 @@ def textbox(element, value, status, msg=''):
'mode'
:
mode
,
'linenumbers'
:
linenumbers
,
'mode'
:
mode
,
'linenumbers'
:
linenumbers
,
'rows'
:
rows
,
'cols'
:
cols
,
'rows'
:
rows
,
'cols'
:
cols
,
}
}
html
=
render_to_string
(
"textbox.html"
,
context
)
html
=
render_template
(
"textbox.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
def
schematic
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
eid
=
element
.
get
(
'id'
)
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
height
=
element
.
get
(
'height'
)
width
=
element
.
get
(
'width'
)
width
=
element
.
get
(
'width'
)
...
@@ -285,13 +283,13 @@ def schematic(element, value, status, msg=''):
...
@@ -285,13 +283,13 @@ def schematic(element, value, status, msg=''):
'analyses'
:
analyses
,
'analyses'
:
analyses
,
'submit_analyses'
:
submit_analyses
,
'submit_analyses'
:
submit_analyses
,
}
}
html
=
render_to_string
(
"schematicinput.html"
,
context
)
html
=
render_template
(
"schematicinput.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
### TODO: Move out of inputtypes
### TODO: Move out of inputtypes
@register_render_function
@register_render_function
def
math
(
element
,
value
,
status
,
msg
=
''
):
def
math
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
This is not really an input type. It is a convention from Lon-CAPA, used for
This is not really an input type. It is a convention from Lon-CAPA, used for
displaying a math equation.
displaying a math equation.
...
@@ -316,7 +314,7 @@ def math(element, value, status, msg=''):
...
@@ -316,7 +314,7 @@ def math(element, value, status, msg=''):
# mathstr = mathstr.replace('\\displaystyle','')
# mathstr = mathstr.replace('\\displaystyle','')
#else:
#else:
# isinline = True
# isinline = True
# html
=render_to_string
("mathstring.html",{'mathstr':mathstr,'isinline':isinline,'tail':element.tail})
# html
= render_template
("mathstring.html",{'mathstr':mathstr,'isinline':isinline,'tail':element.tail})
html
=
'<html><html>
%
s</html><html>
%
s</html></html>'
%
(
mathstr
,
element
.
tail
)
html
=
'<html><html>
%
s</html><html>
%
s</html></html>'
%
(
mathstr
,
element
.
tail
)
xhtml
=
etree
.
XML
(
html
)
xhtml
=
etree
.
XML
(
html
)
...
@@ -326,7 +324,7 @@ def math(element, value, status, msg=''):
...
@@ -326,7 +324,7 @@ def math(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
solution
(
element
,
value
,
status
,
msg
=
''
):
def
solution
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
This is not really an input type. It is just a <span>...</span> which is given an ID,
This is not really an input type. It is just a <span>...</span> which is given an ID,
that is used for displaying an extended answer (a problem "solution") after "show answers"
that is used for displaying an extended answer (a problem "solution") after "show answers"
...
@@ -341,13 +339,13 @@ def solution(element, value, status, msg=''):
...
@@ -341,13 +339,13 @@ def solution(element, value, status, msg=''):
'size'
:
size
,
'size'
:
size
,
'msg'
:
msg
,
'msg'
:
msg
,
}
}
html
=
render_to_string
(
"solutionspan.html"
,
context
)
html
=
render_template
(
"solutionspan.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
@register_render_function
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
def
imageinput
(
element
,
value
,
status
,
render_template
,
msg
=
''
):
'''
'''
Clickable image as an input field. Element should specify the image source, height, and width, eg
Clickable image as an input field. Element should specify the image source, height, and width, eg
<imageinput src="/static/Physics801/Figures/Skier-conservation of energy.jpg" width="388" height="560" />
<imageinput src="/static/Physics801/Figures/Skier-conservation of energy.jpg" width="388" height="560" />
...
@@ -378,5 +376,5 @@ def imageinput(element, value, status, msg=''):
...
@@ -378,5 +376,5 @@ def imageinput(element, value, status, msg=''):
'state'
:
status
,
# to change
'state'
:
status
,
# to change
'msg'
:
msg
,
# to change
'msg'
:
msg
,
# to change
}
}
html
=
render_to_string
(
"imageinput.html"
,
context
)
html
=
render_template
(
"imageinput.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
common/lib/capa/responsetypes.py
View file @
304e9682
...
@@ -256,8 +256,7 @@ def sympy_check2():
...
@@ -256,8 +256,7 @@ def sympy_check2():
self
.
expect
=
xml
.
get
(
'expect'
)
or
xml
.
get
(
'answer'
)
self
.
expect
=
xml
.
get
(
'expect'
)
or
xml
.
get
(
'answer'
)
self
.
myid
=
xml
.
get
(
'id'
)
self
.
myid
=
xml
.
get
(
'id'
)
if
settings
.
DEBUG
:
log
.
debug
(
'answer_ids=
%
s'
%
self
.
answer_ids
)
log
.
info
(
'answer_ids=
%
s'
%
self
.
answer_ids
)
# the <answer>...</answer> stanza should be local to the current <customresponse>. So try looking there first.
# the <answer>...</answer> stanza should be local to the current <customresponse>. So try looking there first.
self
.
code
=
None
self
.
code
=
None
...
@@ -271,7 +270,7 @@ def sympy_check2():
...
@@ -271,7 +270,7 @@ def sympy_check2():
# ie the comparison function is defined in the <script>...</script> stanza instead
# ie the comparison function is defined in the <script>...</script> stanza instead
cfn
=
xml
.
get
(
'cfn'
)
cfn
=
xml
.
get
(
'cfn'
)
if
cfn
:
if
cfn
:
if
settings
.
DEBUG
:
log
.
info
(
"cfn =
%
s"
%
cfn
)
log
.
debug
(
"cfn =
%
s"
%
cfn
)
if
cfn
in
context
:
if
cfn
in
context
:
self
.
code
=
context
[
cfn
]
self
.
code
=
context
[
cfn
]
else
:
else
:
...
@@ -346,7 +345,7 @@ def sympy_check2():
...
@@ -346,7 +345,7 @@ def sympy_check2():
# this is an interface to the Tutor2 check functions
# this is an interface to the Tutor2 check functions
fn
=
self
.
code
fn
=
self
.
code
ret
=
None
ret
=
None
if
settings
.
DEBUG
:
log
.
info
(
" submission =
%
s"
%
submission
)
log
.
debug
(
" submission =
%
s"
%
submission
)
try
:
try
:
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
# handle variable number of arguments in check function, for backwards compatibility
# handle variable number of arguments in check function, for backwards compatibility
...
@@ -358,9 +357,8 @@ def sympy_check2():
...
@@ -358,9 +357,8 @@ def sympy_check2():
for
argname
in
argspec
.
args
[
nargs
:]:
for
argname
in
argspec
.
args
[
nargs
:]:
kwargs
[
argname
]
=
self
.
context
[
argname
]
if
argname
in
self
.
context
else
None
kwargs
[
argname
]
=
self
.
context
[
argname
]
if
argname
in
self
.
context
else
None
if
settings
.
DEBUG
:
log
.
debug
(
'[customresponse] answer_given=
%
s'
%
answer_given
)
log
.
debug
(
'[courseware.capa.responsetypes.customresponse] answer_given=
%
s'
%
answer_given
)
log
.
debug
(
'nargs=
%
d, args=
%
s, kwargs=
%
s'
%
(
nargs
,
args
,
kwargs
))
log
.
info
(
'nargs=
%
d, args=
%
s, kwargs=
%
s'
%
(
nargs
,
args
,
kwargs
))
ret
=
fn
(
*
args
[:
nargs
],
**
kwargs
)
ret
=
fn
(
*
args
[:
nargs
],
**
kwargs
)
except
Exception
,
err
:
except
Exception
,
err
:
...
@@ -368,7 +366,7 @@ def sympy_check2():
...
@@ -368,7 +366,7 @@ def sympy_check2():
# print "context = ",self.context
# print "context = ",self.context
log
.
error
(
traceback
.
format_exc
())
log
.
error
(
traceback
.
format_exc
())
raise
Exception
,
"oops in customresponse (cfn) error
%
s"
%
err
raise
Exception
,
"oops in customresponse (cfn) error
%
s"
%
err
if
settings
.
DEBUG
:
log
.
info
(
"[courseware.capa.responsetypes.customresponse.get_score] ret =
%
s"
%
ret
)
log
.
debug
(
"[courseware.capa.responsetypes.customresponse.get_score] ret =
%
s"
%
ret
)
if
type
(
ret
)
==
dict
:
if
type
(
ret
)
==
dict
:
correct
=
[
'correct'
]
*
len
(
idset
)
if
ret
[
'ok'
]
else
[
'incorrect'
]
*
len
(
idset
)
correct
=
[
'correct'
]
*
len
(
idset
)
if
ret
[
'ok'
]
else
[
'incorrect'
]
*
len
(
idset
)
msg
=
ret
[
'msg'
]
msg
=
ret
[
'msg'
]
...
...
common/lib/xmodule/capa_module.py
View file @
304e9682
...
@@ -5,13 +5,11 @@ import json
...
@@ -5,13 +5,11 @@ import json
import
logging
import
logging
import
traceback
import
traceback
import
re
import
re
import
StringIO
from
datetime
import
timedelta
from
datetime
import
timedelta
from
lxml
import
etree
from
lxml
import
etree
## TODO: Abstract out from Django
from
mitxmako.shortcuts
import
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
from
capa.capa_problem
import
LoncapaProblem
,
StudentInputError
from
capa.capa_problem
import
LoncapaProblem
,
StudentInputError
log
=
logging
.
getLogger
(
"mitx.courseware"
)
log
=
logging
.
getLogger
(
"mitx.courseware"
)
...
@@ -72,10 +70,10 @@ class Module(XModule):
...
@@ -72,10 +70,10 @@ class Module(XModule):
return
self
.
lcp
.
get_max_score
()
return
self
.
lcp
.
get_max_score
()
def
get_html
(
self
):
def
get_html
(
self
):
return
render_to_string
(
'problem_ajax.html'
,
return
self
.
system
.
render_template
(
'problem_ajax.html'
,
{
{
'id'
:
self
.
item_id
,
'id'
:
self
.
item_id
,
'ajax_url'
:
self
.
ajax_url
,
'ajax_url'
:
self
.
ajax_url
,
})
})
def
get_problem_html
(
self
,
encapsulate
=
True
):
def
get_problem_html
(
self
,
encapsulate
=
True
):
html
=
self
.
lcp
.
get_html
()
html
=
self
.
lcp
.
get_html
()
...
@@ -138,7 +136,7 @@ class Module(XModule):
...
@@ -138,7 +136,7 @@ class Module(XModule):
'explain'
:
explain
,
'explain'
:
explain
,
}
}
html
=
render_to_string
(
'problem.html'
,
context
)
html
=
self
.
system
.
render_template
(
'problem.html'
,
context
)
if
encapsulate
:
if
encapsulate
:
html
=
'<div id="problem_{id}" class="problem" data-url="{ajax_url}">'
.
format
(
id
=
self
.
item_id
,
ajax_url
=
self
.
ajax_url
)
+
html
+
"</div>"
html
=
'<div id="problem_{id}" class="problem" data-url="{ajax_url}">'
.
format
(
id
=
self
.
item_id
,
ajax_url
=
self
.
ajax_url
)
+
html
+
"</div>"
...
...
lms/djangoapps/coursewar
e/graders.py
→
common/lib/xmodul
e/graders.py
View file @
304e9682
import
abc
import
abc
import
logging
import
logging
from
django.conf
import
settings
from
collections
import
namedtuple
from
collections
import
namedtuple
log
=
logging
.
getLogger
(
"mitx.courseware"
)
log
=
logging
.
getLogger
(
"mitx.courseware"
)
...
@@ -11,6 +9,26 @@ log = logging.getLogger("mitx.courseware")
...
@@ -11,6 +9,26 @@ log = logging.getLogger("mitx.courseware")
# Section either indicates the name of the problem or the name of the section
# Section either indicates the name of the problem or the name of the section
Score
=
namedtuple
(
"Score"
,
"earned possible graded section"
)
Score
=
namedtuple
(
"Score"
,
"earned possible graded section"
)
def
aggregate_scores
(
scores
,
section_name
=
"summary"
):
total_correct_graded
=
sum
(
score
.
earned
for
score
in
scores
if
score
.
graded
)
total_possible_graded
=
sum
(
score
.
possible
for
score
in
scores
if
score
.
graded
)
total_correct
=
sum
(
score
.
earned
for
score
in
scores
)
total_possible
=
sum
(
score
.
possible
for
score
in
scores
)
#regardless of whether or not it is graded
all_total
=
Score
(
total_correct
,
total_possible
,
False
,
section_name
)
#selecting only graded things
graded_total
=
Score
(
total_correct_graded
,
total_possible_graded
,
True
,
section_name
)
return
all_total
,
graded_total
def
grader_from_conf
(
conf
):
def
grader_from_conf
(
conf
):
"""
"""
This creates a CourseGrader from a configuration (such as in course_settings.py).
This creates a CourseGrader from a configuration (such as in course_settings.py).
...
@@ -162,18 +180,6 @@ class SingleSectionGrader(CourseGrader):
...
@@ -162,18 +180,6 @@ class SingleSectionGrader(CourseGrader):
percent
=
0.0
percent
=
0.0
detail
=
"{name} - 0
%
(?/?)"
.
format
(
name
=
self
.
name
)
detail
=
"{name} - 0
%
(?/?)"
.
format
(
name
=
self
.
name
)
if
settings
.
GENERATE_PROFILE_SCORES
:
points_possible
=
random
.
randrange
(
50
,
100
)
points_earned
=
random
.
randrange
(
40
,
points_possible
)
percent
=
points_earned
/
float
(
points_possible
)
detail
=
"{name} - {percent:.0
%
} ({earned:.3n}/{possible:.3n})"
.
format
(
name
=
self
.
name
,
percent
=
percent
,
earned
=
float
(
points_earned
),
possible
=
float
(
points_possible
))
breakdown
=
[{
'percent'
:
percent
,
'label'
:
self
.
short_label
,
'detail'
:
detail
,
'category'
:
self
.
category
,
'prominent'
:
True
}]
breakdown
=
[{
'percent'
:
percent
,
'label'
:
self
.
short_label
,
'detail'
:
detail
,
'category'
:
self
.
category
,
'prominent'
:
True
}]
return
{
'percent'
:
percent
,
return
{
'percent'
:
percent
,
...
@@ -244,17 +250,6 @@ class AssignmentFormatGrader(CourseGrader):
...
@@ -244,17 +250,6 @@ class AssignmentFormatGrader(CourseGrader):
percentage
=
0
percentage
=
0
summary
=
"{section_type} {index} Unreleased - 0
%
(?/?)"
.
format
(
index
=
i
+
1
,
section_type
=
self
.
section_type
)
summary
=
"{section_type} {index} Unreleased - 0
%
(?/?)"
.
format
(
index
=
i
+
1
,
section_type
=
self
.
section_type
)
if
settings
.
GENERATE_PROFILE_SCORES
:
points_possible
=
random
.
randrange
(
10
,
50
)
points_earned
=
random
.
randrange
(
5
,
points_possible
)
percentage
=
points_earned
/
float
(
points_possible
)
summary
=
"{section_type} {index} - {name} - {percent:.0
%
} ({earned:.3n}/{possible:.3n})"
.
format
(
index
=
i
+
1
,
section_type
=
self
.
section_type
,
name
=
"Randomly Generated"
,
percent
=
percentage
,
earned
=
float
(
points_earned
),
possible
=
float
(
points_possible
)
)
short_label
=
"{short_label} {index:02d}"
.
format
(
index
=
i
+
1
,
short_label
=
self
.
short_label
)
short_label
=
"{short_label} {index:02d}"
.
format
(
index
=
i
+
1
,
short_label
=
self
.
short_label
)
breakdown
.
append
(
{
'percent'
:
percentage
,
'label'
:
short_label
,
'detail'
:
summary
,
'category'
:
self
.
category
}
)
breakdown
.
append
(
{
'percent'
:
percentage
,
'label'
:
short_label
,
'detail'
:
summary
,
'category'
:
self
.
category
}
)
...
...
common/lib/xmodule/html_module.py
View file @
304e9682
import
json
import
json
import
logging
import
logging
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
from
lxml
import
etree
from
lxml
import
etree
...
@@ -34,8 +32,7 @@ class Module(XModule):
...
@@ -34,8 +32,7 @@ class Module(XModule):
except
:
# For backwards compatibility. TODO: Remove
except
:
# For backwards compatibility. TODO: Remove
if
self
.
DEBUG
:
if
self
.
DEBUG
:
log
.
info
(
'[courseware.modules.html_module] filename=
%
s'
%
self
.
filename
)
log
.
info
(
'[courseware.modules.html_module] filename=
%
s'
%
self
.
filename
)
#return render_to_string(self.filename, {'id': self.item_id})
return
self
.
system
.
render_template
(
self
.
filename
,
{
'id'
:
self
.
item_id
},
namespace
=
'course'
)
return
render_to_string
(
self
.
filename
,
{
'id'
:
self
.
item_id
},
namespace
=
'course'
)
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
...
...
common/lib/xmodule/seq_module.py
View file @
304e9682
...
@@ -2,8 +2,6 @@ import json
...
@@ -2,8 +2,6 @@ import json
from
lxml
import
etree
from
lxml
import
etree
from
mitxmako.shortcuts
import
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
# HACK: This shouldn't be hard-coded to two types
# HACK: This shouldn't be hard-coded to two types
...
@@ -77,9 +75,9 @@ class Module(XModule):
...
@@ -77,9 +75,9 @@ class Module(XModule):
'tag'
:
self
.
xmltree
.
tag
}
'tag'
:
self
.
xmltree
.
tag
}
if
self
.
xmltree
.
tag
in
[
'sequential'
,
'videosequence'
]:
if
self
.
xmltree
.
tag
in
[
'sequential'
,
'videosequence'
]:
self
.
content
=
render_to_string
(
'seq_module.html'
,
params
)
self
.
content
=
self
.
system
.
render_template
(
'seq_module.html'
,
params
)
if
self
.
xmltree
.
tag
==
'tab'
:
if
self
.
xmltree
.
tag
==
'tab'
:
self
.
content
=
render_to_string
(
'tab_module.html'
,
params
)
self
.
content
=
self
.
system
.
render_template
(
'tab_module.html'
,
params
)
self
.
rendered
=
True
self
.
rendered
=
True
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
...
...
common/lib/xmodule/template_module.py
View file @
304e9682
import
json
import
json
from
mitxmako.shortcuts
import
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
from
lxml
import
etree
from
lxml
import
etree
...
@@ -24,4 +22,4 @@ class Module(XModule):
...
@@ -24,4 +22,4 @@ class Module(XModule):
xmltree
=
etree
.
fromstring
(
xml
)
xmltree
=
etree
.
fromstring
(
xml
)
filename
=
xmltree
[
0
]
.
text
filename
=
xmltree
[
0
]
.
text
params
=
dict
(
xmltree
.
items
())
params
=
dict
(
xmltree
.
items
())
self
.
html
=
render_to_string
(
filename
,
params
,
namespace
=
'custom_tags'
)
self
.
html
=
self
.
system
.
render_template
(
filename
,
params
,
namespace
=
'custom_tags'
)
lms/djangoapps/coursewar
e/test_files/imageresponse.xml
→
common/lib/xmodul
e/test_files/imageresponse.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/test_files/multi_bare.xml
→
common/lib/xmodul
e/test_files/multi_bare.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/test_files/multichoice.xml
→
common/lib/xmodul
e/test_files/multichoice.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/test_files/optionresponse.xml
→
common/lib/xmodul
e/test_files/optionresponse.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/test_files/test_files/symbolicresponse.xml
→
common/lib/xmodul
e/test_files/test_files/symbolicresponse.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/test_files/truefalse.xml
→
common/lib/xmodul
e/test_files/truefalse.xml
View file @
304e9682
File moved
lms/djangoapps/coursewar
e/tests.py
→
common/lib/xmodul
e/tests.py
View file @
304e9682
...
@@ -13,9 +13,8 @@ import numpy
...
@@ -13,9 +13,8 @@ import numpy
import
xmodule
import
xmodule
import
capa.calc
as
calc
import
capa.calc
as
calc
import
capa.capa_problem
as
lcp
import
capa.capa_problem
as
lcp
import
courseware.graders
as
graders
from
xmodule
import
graders
from
courseware.graders
import
Score
,
CourseGrader
,
WeightedSubsectionsGrader
,
SingleSectionGrader
,
AssignmentFormatGrader
from
xmodule.graders
import
Score
,
aggregate_scores
from
courseware.grades
import
aggregate_scores
from
nose.plugins.skip
import
SkipTest
from
nose.plugins.skip
import
SkipTest
class
I4xSystem
(
object
):
class
I4xSystem
(
object
):
...
...
common/lib/xmodule/vertical_module.py
View file @
304e9682
import
json
import
json
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
from
lxml
import
etree
from
lxml
import
etree
...
@@ -19,7 +17,9 @@ class Module(XModule):
...
@@ -19,7 +17,9 @@ class Module(XModule):
return
[
"vertical"
,
"problemset"
]
return
[
"vertical"
,
"problemset"
]
def
get_html
(
self
):
def
get_html
(
self
):
return
render_to_string
(
'vert_module.html'
,{
'items'
:
self
.
contents
})
return
self
.
system
.
render_template
(
'vert_module.html'
,
{
'items'
:
self
.
contents
})
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
...
...
common/lib/xmodule/video_module.py
View file @
304e9682
...
@@ -3,8 +3,6 @@ import logging
...
@@ -3,8 +3,6 @@ import logging
from
lxml
import
etree
from
lxml
import
etree
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
x_module
import
XModule
,
XModuleDescriptor
from
x_module
import
XModule
,
XModuleDescriptor
log
=
logging
.
getLogger
(
"mitx.courseware.modules"
)
log
=
logging
.
getLogger
(
"mitx.courseware.modules"
)
...
@@ -38,11 +36,13 @@ class Module(XModule):
...
@@ -38,11 +36,13 @@ class Module(XModule):
return
self
.
youtube
return
self
.
youtube
def
get_html
(
self
):
def
get_html
(
self
):
return
render_to_string
(
'video.html'
,{
'streams'
:
self
.
video_list
(),
return
self
.
system
.
render_template
(
'video.html'
,
{
'id'
:
self
.
item_id
,
'streams'
:
self
.
video_list
(),
'position'
:
self
.
position
,
'id'
:
self
.
item_id
,
'name'
:
self
.
name
,
'position'
:
self
.
position
,
'annotations'
:
self
.
annotations
})
'name'
:
self
.
name
,
'annotations'
:
self
.
annotations
})
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
def
__init__
(
self
,
system
,
xml
,
item_id
,
state
=
None
):
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
XModule
.
__init__
(
self
,
system
,
xml
,
item_id
,
state
)
...
...
common/lib/xmodule/x_module.py
View file @
304e9682
from
lxml
import
etree
from
lxml
import
etree
import
courseware.progress
def
dummy_track
(
event_type
,
event
):
def
dummy_track
(
event_type
,
event
):
pass
pass
...
@@ -71,11 +69,6 @@ class XModule(object):
...
@@ -71,11 +69,6 @@ class XModule(object):
### Functions used in the LMS
### Functions used in the LMS
def
get_completion
(
self
):
''' This is mostly unimplemented.
It gives a progress indication -- e.g. 30 minutes of 1.5 hours watched. 3 of 5 problems done, etc. '''
return
courseware
.
progress
.
completion
()
def
get_state
(
self
):
def
get_state
(
self
):
''' State of the object, as stored in the database
''' State of the object, as stored in the database
'''
'''
...
...
lms/djangoapps/courseware/grades.py
View file @
304e9682
...
@@ -25,8 +25,8 @@ import types
...
@@ -25,8 +25,8 @@ import types
from
django.conf
import
settings
from
django.conf
import
settings
from
courseware
import
global_course_settings
from
courseware
import
global_course_settings
from
coursewar
e
import
graders
from
xmodul
e
import
graders
from
coursewar
e.graders
import
Score
from
xmodul
e.graders
import
Score
from
models
import
StudentModule
from
models
import
StudentModule
import
courseware.content_parser
as
content_parser
import
courseware.content_parser
as
content_parser
import
xmodule
import
xmodule
...
@@ -116,7 +116,7 @@ def grade_sheet(student,coursename=None):
...
@@ -116,7 +116,7 @@ def grade_sheet(student,coursename=None):
graded
=
False
graded
=
False
scores
.
append
(
Score
(
correct
,
total
,
graded
,
p
.
get
(
"name"
))
)
scores
.
append
(
Score
(
correct
,
total
,
graded
,
p
.
get
(
"name"
))
)
section_total
,
graded_total
=
aggregate_scores
(
scores
,
s
.
get
(
"name"
))
section_total
,
graded_total
=
graders
.
aggregate_scores
(
scores
,
s
.
get
(
"name"
))
#Add the graded total to totaled_scores
#Add the graded total to totaled_scores
format
=
s
.
get
(
'format'
,
""
)
format
=
s
.
get
(
'format'
,
""
)
subtitle
=
s
.
get
(
'subtitle'
,
format
)
subtitle
=
s
.
get
(
'subtitle'
,
format
)
...
@@ -146,27 +146,6 @@ def grade_sheet(student,coursename=None):
...
@@ -146,27 +146,6 @@ def grade_sheet(student,coursename=None):
return
{
'courseware_summary'
:
chapters
,
return
{
'courseware_summary'
:
chapters
,
'grade_summary'
:
grade_summary
}
'grade_summary'
:
grade_summary
}
def
aggregate_scores
(
scores
,
section_name
=
"summary"
):
total_correct_graded
=
sum
(
score
.
earned
for
score
in
scores
if
score
.
graded
)
total_possible_graded
=
sum
(
score
.
possible
for
score
in
scores
if
score
.
graded
)
total_correct
=
sum
(
score
.
earned
for
score
in
scores
)
total_possible
=
sum
(
score
.
possible
for
score
in
scores
)
#regardless of whether or not it is graded
all_total
=
Score
(
total_correct
,
total_possible
,
False
,
section_name
)
#selecting only graded things
graded_total
=
Score
(
total_correct_graded
,
total_possible_graded
,
True
,
section_name
)
return
all_total
,
graded_total
def
get_score
(
user
,
problem
,
cache
,
coursename
=
None
):
def
get_score
(
user
,
problem
,
cache
,
coursename
=
None
):
## HACK: assumes max score is fixed per problem
## HACK: assumes max score is fixed per problem
id
=
problem
.
get
(
'id'
)
id
=
problem
.
get
(
'id'
)
...
...
lms/djangoapps/courseware/module_render.py
View file @
304e9682
...
@@ -27,7 +27,7 @@ class I4xSystem(object):
...
@@ -27,7 +27,7 @@ class I4xSystem(object):
of the courseware (e.g. import into other types of courseware, LMS,
of the courseware (e.g. import into other types of courseware, LMS,
or if we want to have a sandbox server for user-contributed content)
or if we want to have a sandbox server for user-contributed content)
'''
'''
def
__init__
(
self
,
ajax_url
,
track_function
,
render_function
,
filestore
=
None
):
def
__init__
(
self
,
ajax_url
,
track_function
,
render_function
,
render_template
,
filestore
=
None
):
self
.
ajax_url
=
ajax_url
self
.
ajax_url
=
ajax_url
self
.
track_function
=
track_function
self
.
track_function
=
track_function
if
not
filestore
:
if
not
filestore
:
...
@@ -37,6 +37,7 @@ class I4xSystem(object):
...
@@ -37,6 +37,7 @@ class I4xSystem(object):
if
settings
.
DEBUG
:
if
settings
.
DEBUG
:
log
.
info
(
"[courseware.module_render.I4xSystem] filestore path =
%
s"
%
filestore
)
log
.
info
(
"[courseware.module_render.I4xSystem] filestore path =
%
s"
%
filestore
)
self
.
render_function
=
render_function
self
.
render_function
=
render_function
self
.
render_template
=
render_template
self
.
exception404
=
Http404
self
.
exception404
=
Http404
self
.
DEBUG
=
settings
.
DEBUG
self
.
DEBUG
=
settings
.
DEBUG
...
@@ -117,6 +118,7 @@ def get_module(user, request, xml_module, module_object_preload, position=None):
...
@@ -117,6 +118,7 @@ def get_module(user, request, xml_module, module_object_preload, position=None):
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
lambda
x
:
render_x_module
(
user
,
request
,
x
,
module_object_preload
,
position
),
render_function
=
lambda
x
:
render_x_module
(
user
,
request
,
x
,
module_object_preload
,
position
),
render_template
=
render_to_string
,
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
OSFS
(
data_root
),
filestore
=
OSFS
(
data_root
),
)
)
...
@@ -225,6 +227,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
...
@@ -225,6 +227,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
# Create the module
# Create the module
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
render_function
=
None
,
render_template
=
render_to_string
,
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
OSFS
(
data_root
),
filestore
=
OSFS
(
data_root
),
)
)
...
...
lms/lib/dogfood/views.py
View file @
304e9682
...
@@ -179,6 +179,7 @@ def quickedit(request, id=None, qetemplate='quickedit.html',coursename=None):
...
@@ -179,6 +179,7 @@ def quickedit(request, id=None, qetemplate='quickedit.html',coursename=None):
# Create the module (instance of capa_module.Module)
# Create the module (instance of capa_module.Module)
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
render_function
=
None
,
render_template
=
render_to_string
,
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
#role = 'staff' if request.user.is_staff else 'student', # TODO: generalize this
#role = 'staff' if request.user.is_staff else 'student', # TODO: generalize this
...
...
rakefile
View file @
304e9682
...
@@ -58,10 +58,31 @@ task :pylint => LMS_REPORT_DIR do
...
@@ -58,10 +58,31 @@ task :pylint => LMS_REPORT_DIR do
end
end
end
end
desc
"Run all django tests on our djangoapps"
[
:lms
].
each
do
|
system
|
task
:test
=>
LMS_REPORT_DIR
do
task_name
=
"test_
#{
system
}
"
ENV
[
'NOSE_XUNIT_FILE'
]
=
File
.
join
(
LMS_REPORT_DIR
,
"nosetests.xml"
)
report_dir
=
File
.
join
(
REPORT_DIR
,
task_name
)
sh
(
django_admin
(
:lms
,
:test
,
'test'
,
*
Dir
[
'lms/djangoapps'
].
each
))
directory
report_dir
desc
"Run all django tests on our djangoapps for the
#{
system
}
"
task
task_name
=>
report_dir
do
ENV
[
'NOSE_XUNIT_FILE'
]
=
File
.
join
(
report_dir
,
"nosetests.xml"
)
sh
(
django_admin
(
:lms
,
:test
,
'test'
,
*
Dir
[
'lms/djangoapps'
].
each
))
end
task
:test
=>
task_name
end
Dir
[
"common/lib/*"
].
each
do
|
lib
|
task_name
=
"test_
#{
lib
}
"
report_dir
=
File
.
join
(
REPORT_DIR
,
task_name
)
directory
report_dir
desc
"Run tests for common lib
#{
lib
}
"
task
task_name
do
ENV
[
'NOSE_XUNIT_FILE'
]
=
File
.
join
(
report_dir
,
"nosetests.xml"
)
sh
(
"nosetests
#{
lib
}
"
)
end
task
:test
=>
task_name
end
end
desc
<<-
desc
desc
<<-
desc
...
...
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