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
9e18b261
Commit
9e18b261
authored
Dec 07, 2011
by
Piotr Mitros
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactoring into module, part 1
parent
cc1de22e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
109 additions
and
82 deletions
+109
-82
courseware/capa_module.py
+31
-9
courseware/capa_problem.py
+2
-8
courseware/content_parser.py
+25
-0
courseware/models.py
+7
-4
courseware/views.py
+34
-59
courseware/x_module.py
+8
-0
urls.py
+2
-2
No files found.
courseware/capa_module.py
View file @
9e18b261
...
...
@@ -4,26 +4,48 @@
import
random
,
numpy
,
math
,
scipy
,
sys
,
StringIO
,
os
,
struct
,
json
from
x_module
import
XModule
from
capa_problem
import
LoncapaProblem
from
xml.dom.minidom
import
parse
,
parseString
class
LoncapaProblem
(
XModule
):
## TODO: Abstract out from Django
from
django.conf
import
settings
from
djangomako.shortcuts
import
render_to_response
,
render_to_string
class
LoncapaModule
(
XModule
):
xml_tags
=
[
"problem"
]
id_attribute
=
"filename"
def
get_state
(
self
):
print
"got"
return
self
.
lcp
.
get_state
()
def
get_score
(
self
):
return
self
.
lcp
.
get_score
()
def
max_score
(
self
):
return
len
(
lcp
.
questions
)
def
get_html
(
self
):
inner_html
=
self
.
lcp
.
get_html
()
content
=
{
'name'
:
self
.
name
,
'html'
:
inner_html
}
return
render_to_string
(
'problem.html'
,
{
'problem'
:
content
,
'id'
:
self
.
filename
})
def
handle_ajax
(
self
,
json
):
def
__init__
(
self
,
filename
,
id
=
None
,
state
=
None
):
def
__init__
(
self
,
xml
,
item_id
,
ajax_url
=
None
,
track_url
=
None
,
state
=
None
):
XModule
.
__init__
(
self
,
xml
,
item_id
,
ajax_url
,
track_url
,
state
)
dom
=
parseString
(
xml
)
node
=
dom
.
childNodes
[
0
]
self
.
filename
=
node
.
getAttribute
(
"filename"
)
filename
=
settings
.
DATA_DIR
+
self
.
filename
+
".xml"
self
.
name
=
node
.
getAttribute
(
"name"
)
print
state
self
.
lcp
=
LoncapaProblem
(
filename
,
item_id
,
state
)
if
__name__
==
'__main__'
:
p
=
LoncapaProblem
(
'<problem name="Problem 1: Resistive Divider" filename="resistor" />'
)
# Temporary
print
p
.
getHtml
()
print
p
.
getContext
()
print
p
.
getSeed
()
# Chef and puppot
def
check_problem
(
self
,
get
):
pass
courseware/capa_problem.py
View file @
9e18b261
...
...
@@ -26,16 +26,10 @@ class LoncapaProblem():
return
{
'score'
:
correct
,
'total'
:
len
(
self
.
questions
)}
def
max_score
(
self
):
pass
def
get_html
(
self
):
''' Return the HTML of the question '''
return
self
.
text
def
handle_ajax
(
self
,
json
):
pass
def
__init__
(
self
,
filename
,
id
=
None
,
state
=
None
):
''' Create a new problem of the type defined in filename.
By default, this will generate a random problem. Passing
...
...
@@ -71,7 +65,7 @@ class LoncapaProblem():
ot
=
False
## Are we in an outtext context?
for
e
in
dom
.
childNodes
:
if
e
.
localName
==
'script'
and
context
==
None
:
if
e
.
localName
==
'script'
:
exec
e
.
childNodes
[
0
]
.
data
in
g
,
self
.
context
if
e
.
localName
==
'endouttext'
:
ot
=
False
...
...
@@ -85,7 +79,7 @@ class LoncapaProblem():
self
.
text
=
buf
.
getvalue
()
self
.
text
=
self
.
contextualize_text
(
self
.
text
)
self
.
filename
=
filename
text
=
""
context
=
{}
# Execution context from loncapa/python
...
...
courseware/content_parser.py
0 → 100644
View file @
9e18b261
from
django.conf
import
settings
from
xml.dom.minidom
import
parse
,
parseString
def
toc_from_xml
(
active_chapter
,
active_section
):
dom
=
parse
(
settings
.
DATA_DIR
+
'course.xml'
)
course
=
dom
.
getElementsByTagName
(
'course'
)[
0
]
name
=
course
.
getAttribute
(
"name"
)
chapters
=
course
.
getElementsByTagName
(
'chapter'
)
ch
=
list
()
for
c
in
chapters
:
sections
=
list
()
for
s
in
c
.
getElementsByTagName
(
'section'
):
sections
.
append
({
'name'
:
s
.
getAttribute
(
"name"
),
'time'
:
s
.
getAttribute
(
"time"
),
'format'
:
s
.
getAttribute
(
"format"
),
'due'
:
s
.
getAttribute
(
"due"
),
'active'
:(
c
.
getAttribute
(
"name"
)
==
active_chapter
and
\
s
.
getAttribute
(
"name"
)
==
active_section
)})
ch
.
append
({
'name'
:
c
.
getAttribute
(
"name"
),
'sections'
:
sections
,
'active'
:(
c
.
getAttribute
(
"name"
)
==
active_chapter
)})
return
ch
courseware/models.py
View file @
9e18b261
...
...
@@ -44,10 +44,13 @@ class StudentModule(models.Model):
state
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
grade
=
models
.
FloatField
(
null
=
True
,
blank
=
True
)
student
=
models
.
ForeignKey
(
User
)
MODULE_TYPES
=
((
'
hw'
,
'homework
'
),)
module_type
=
models
.
CharField
(
max_length
=
32
,
choices
=
MODULE_TYPES
,
default
=
'
hw
'
)
module_id
=
models
.
CharField
(
max_length
=
255
)
# Filename
MODULE_TYPES
=
((
'
problem'
,
'problem
'
),)
module_type
=
models
.
CharField
(
max_length
=
32
,
choices
=
MODULE_TYPES
,
default
=
'
problem
'
)
module_id
=
models
.
CharField
(
max_length
=
255
)
# Filename
for homeworks, etc.
created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
modified
=
models
.
DateTimeField
(
auto_now
=
True
)
class
Meta
:
unique_together
=
((
'student'
,
'module_id'
),)
unique_together
=
((
'student'
,
'module_id'
,
'module_type'
),)
def
__unicode__
(
self
):
return
self
.
module_type
+
'/'
+
self
.
student
.
username
+
"/"
+
self
.
module_id
+
'/'
+
str
(
self
.
state
)[:
20
]
courseware/views.py
View file @
9e18b261
...
...
@@ -12,9 +12,11 @@ from django.shortcuts import redirect
import
StringIO
from
django.http
import
Http404
import
urllib
import
capa_problem
import
capa_
module
,
capa_
problem
from
models
import
StudentModule
...
...
@@ -22,6 +24,8 @@ import urllib
from
django.conf
import
settings
from
content_parser
import
*
template_imports
=
{
'urllib'
:
urllib
}
def
profile
(
request
):
...
...
@@ -49,9 +53,7 @@ def profile(request):
correct
=
response
.
grade
else
:
correct
=
0
# CRITICAL TODO: Benchmark, and probably cache. We shouldn't recalculate this
# every time. By modularity, this also belongs inside LoncapaProblem.
total
=
len
(
capa_problem
.
LoncapaProblem
(
settings
.
DATA_DIR
+
id
+
'.xml'
,
id
=
id
)
.
questions
)
total
=
capa_module
.
LoncapaModule
(
p
,
id
=
id
)
.
max_score
()
scores
.
append
((
int
(
correct
),
total
))
score
=
{
'course'
:
course
.
getAttribute
(
'name'
),
'section'
:
s
.
getAttribute
(
"name"
),
...
...
@@ -71,27 +73,6 @@ def profile(request):
}
return
render_to_response
(
'profile.html'
,
context
)
def
toc_from_xml
(
active_chapter
,
active_section
):
dom
=
parse
(
settings
.
DATA_DIR
+
'course.xml'
)
course
=
dom
.
getElementsByTagName
(
'course'
)[
0
]
name
=
course
.
getAttribute
(
"name"
)
chapters
=
course
.
getElementsByTagName
(
'chapter'
)
ch
=
list
()
for
c
in
chapters
:
sections
=
list
()
for
s
in
c
.
getElementsByTagName
(
'section'
):
sections
.
append
({
'name'
:
s
.
getAttribute
(
"name"
),
'time'
:
s
.
getAttribute
(
"time"
),
'format'
:
s
.
getAttribute
(
"format"
),
'due'
:
s
.
getAttribute
(
"due"
),
'active'
:(
c
.
getAttribute
(
"name"
)
==
active_chapter
and
\
s
.
getAttribute
(
"name"
)
==
active_section
)})
ch
.
append
({
'name'
:
c
.
getAttribute
(
"name"
),
'sections'
:
sections
,
'active'
:(
c
.
getAttribute
(
"name"
)
==
active_chapter
)})
return
ch
def
render_accordion
(
request
,
course
,
chapter
,
section
):
''' Draws accordion. Takes current position in accordion as
parameter. Returns (initialization_javascript, content)'''
...
...
@@ -138,28 +119,43 @@ def vertical_module(request, module):
return
{
'js'
:
js
,
'content'
:
render_to_string
(
'vert_module.html'
,{
'items'
:
contents
})}
def
render_
problem
(
request
,
filenam
e
):
def
render_
x_module
(
request
,
xml_modul
e
):
# Check if problem has an instance in DB
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
filename
)
module_id
=
xml_module
.
getAttribute
(
capa_module
.
LoncapaModule
.
id_attribute
)
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
module_id
)
if
len
(
s
)
==
0
:
# If not, create one, and
return
it
problem
=
capa_
problem
.
LoncapaProblem
(
settings
.
DATA_DIR
+
filename
+
'.xml'
,
id
=
filename
)
# If not, create one, and
save
it
problem
=
capa_
module
.
LoncapaModule
(
xml_module
.
toxml
(),
module_id
)
smod
=
StudentModule
(
student
=
request
.
user
,
module_id
=
filename
,
module_id
=
module_id
,
state
=
problem
.
get_state
())
smod
.
save
()
elif
len
(
s
)
==
1
:
# If so, render it
problem
=
capa_
problem
.
LoncapaProblem
(
settings
.
DATA_DIR
+
filename
+
'.xml'
,
id
=
filename
,
state
=
s
[
0
]
.
state
)
problem
=
capa_
module
.
LoncapaModule
(
xml_module
.
toxml
()
,
module_id
,
state
=
s
[
0
]
.
state
)
else
:
raise
Exception
(
"Database is inconsistent (1)."
)
return
problem
.
get_html
()
def
reset_problem
(
request
):
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
request
.
GET
[
'id'
])
return
{
'content'
:
problem
.
get_html
()}
def
modx_dispatch
(
request
,
dispatch
=
None
,
id
=
None
):
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
id
)
if
len
(
s
)
==
0
:
raise
Http404
if
dispatch
==
'problem_check'
:
return
check_problem
(
request
)
elif
dispatch
==
'problem_reset'
:
return
reset_problem
(
request
,
id
)
else
:
print
"AAA"
raise
Http404
def
reset_problem
(
request
,
id
):
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
id
)
s
[
0
]
.
delete
()
return
HttpResponse
(
json
.
dumps
({}),
mimetype
=
"application/json"
)
...
...
@@ -194,32 +190,11 @@ def check_problem(request):
return
HttpResponse
(
js
,
mimetype
=
"application/json"
)
def
problem_module
(
request
,
module
):
filename
=
module
.
getAttribute
(
'filename'
)
content
=
{
'name'
:
module
.
getAttribute
(
'name'
),
'html'
:
render_problem
(
request
,
filename
)}
return
{
'content'
:
render_to_string
(
'problem.html'
,
{
'problem'
:
content
,
'id'
:
filename
})}
def
homework_module
(
request
,
module
):
content
=
{
'name'
:
module
.
getAttribute
(
'name'
),
'problems'
:[]}
filename
=
module
.
getAttribute
(
'filename'
)
dom
=
parse
(
settings
.
DATA_DIR
+
filename
)
homework
=
dom
.
getElementsByTagName
(
'homework'
)[
0
]
for
e
in
homework
.
childNodes
:
if
e
.
nodeType
==
1
:
problem
=
{
'name'
:
e
.
getAttribute
(
'name'
),
'html'
:
render_problem
(
request
,
e
.
getAttribute
(
'filename'
))}
content
[
'problems'
]
.
append
(
problem
)
return
{
'content'
:
render_to_string
(
'homework.html'
,
{
'homework'
:
content
})}
module_types
=
{
'video'
:
video_module
,
'html'
:
html_module
,
'tab'
:
tab_module
,
'vertical'
:
vertical_module
,
'homework'
:
homework_module
,
'problem'
:
problem_module
}
'problem'
:
render_x_module
}
#'lab':lab_module,
def
render_module
(
request
,
module
):
...
...
courseware/x_module.py
View file @
9e18b261
...
...
@@ -3,6 +3,14 @@ class XModule:
Initialized on access with __init__, first time with state=None, and
then with state
'''
def
get_xml_tags
():
''' Tags in the courseware file guaranteed to correspond to the module '''
return
[]
def
get_id_attribute
():
''' An attribute in the XML scheme that is guaranteed unique. '''
return
"name"
def
get_state
(
self
):
return
""
...
...
urls.py
View file @
9e18b261
...
...
@@ -9,8 +9,8 @@ urlpatterns = patterns('',
url
(
r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$'
,
'courseware.views.index'
),
url
(
r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/$'
,
'courseware.views.index'
),
url
(
r'^courseware/(?P<course>[^/]*)/$'
,
'courseware.views.index'
),
url
(
r'^courseware
/problem_check$'
,
'courseware.views.check_problem'
),
url
(
r'^courseware/
problem_reset$'
,
'courseware.views.
reset_problem'
),
# url(r'^courseware/modx/(?P<id>[^/]*)
/problem_check$', 'courseware.views.check_problem'),
url
(
r'^courseware/
modx/(?P<id>[^/]*)/(?P<dispatch>[^/]*)$'
,
'courseware.views.modx_dispatch'
),
#
reset_problem'),
url
(
r'^courseware/$'
,
'courseware.views.index'
),
url
(
r'^profile$'
,
'courseware.views.profile'
),
# url(r'^admin/', include('django.contrib.admin.urls')),
...
...
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