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
de585e2c
Commit
de585e2c
authored
Feb 02, 2012
by
Bridger Maxwell
Browse files
Options
Browse Files
Download
Plain Diff
Merged with profile changes again. Last time was backwards
parents
b7fe049f
9b38e8c5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
156 additions
and
23 deletions
+156
-23
courseware/content_parser.py
+37
-5
courseware/models.py
+1
-1
courseware/module_render.py
+5
-3
courseware/modules/capa_module.py
+3
-3
courseware/views.py
+110
-11
No files found.
courseware/content_parser.py
View file @
de585e2c
import
json
import
hashlib
import
logging
from
lxml
import
etree
from
mako.template
import
Template
...
...
@@ -11,14 +12,14 @@ try: # This lets us do __name__ == ='__main__'
except
:
settings
=
None
''' This file will eventually form an abstraction layer between the
course XML file and the rest of the system.
TODO: Shift everything from xml.dom.minidom to XPath (or XQuery)
'''
log
=
logging
.
getLogger
(
"mitx.courseware"
)
def
fasthash
(
string
):
m
=
hashlib
.
new
(
"md4"
)
m
.
update
(
string
)
...
...
@@ -83,11 +84,40 @@ def id_tag(course):
if
elem
.
get
(
'id'
):
pass
elif
elem
.
get
(
default_ids
[
elem
.
tag
]):
new_id
=
elem
.
get
(
default_ids
[
elem
.
tag
])
# Convert to alphanumeric
new_id
=
""
.
join
([
a
for
a
in
new_id
if
a
.
isalnum
()])
new_id
=
elem
.
get
(
default_ids
[
elem
.
tag
])
new_id
=
""
.
join
([
a
for
a
in
new_id
if
a
.
isalnum
()])
# Convert to alphanumeric
# Without this, a conflict may occur between an hmtl or youtube id
new_id
=
default_ids
[
elem
.
tag
]
+
new_id
elem
.
set
(
'id'
,
new_id
)
else
:
elem
.
set
(
'id'
,
fasthash
(
etree
.
tostring
(
elem
)))
elem
.
set
(
'id'
,
fasthash
(
etree
.
tostring
(
elem
)))
def
propogate_downward_tag
(
element
,
attribute_name
,
parent_attribute
=
None
):
''' This call is to pass down an attribute to all children. If an element
has this attribute, it will be "inherited" by all of its children. If a
child (A) already has that attribute, A will keep the same attribute and
all of A's children will inherit A's attribute. This is a recursive call.'''
if
(
parent_attribute
==
None
):
#This is the entry call. Select all due elements
all_attributed_elements
=
element
.
xpath
(
"//*[@"
+
attribute_name
+
"]"
)
for
attributed_element
in
all_attributed_elements
:
attribute_value
=
attributed_element
.
get
(
attribute_name
)
for
child_element
in
attributed_element
:
propogate_downward_tag
(
child_element
,
attribute_name
,
attribute_value
)
else
:
'''The hack below is because we would get _ContentOnlyELements from the
iterator that can't have due dates set. We can't find API for it. If we
ever have an element which subclasses BaseElement, we will not tag it'''
if
not
element
.
get
(
attribute_name
)
and
type
(
element
)
==
etree
.
_Element
:
element
.
set
(
attribute_name
,
parent_attribute
)
for
child_element
in
element
:
propogate_downward_tag
(
child_element
,
attribute_name
,
parent_attribute
)
else
:
#This element would have already been found by Xpath, so we return
#for now and trust that this element will get its turn to propogate
#to its children later.
return
template_lookup
=
TemplateLookup
(
directories
=
[
settings
.
DATA_DIR
],
module_directory
=
settings
.
MAKO_MODULE_DIR
)
...
...
@@ -101,6 +131,8 @@ def course_file(user):
tree
=
etree
.
XML
(
data_template
.
render
(
**
options
))
id_tag
(
tree
)
propogate_downward_tag
(
tree
,
"due"
)
propogate_downward_tag
(
tree
,
"graded"
)
return
tree
def
module_xml
(
coursefile
,
module
,
id_tag
,
module_id
):
...
...
courseware/models.py
View file @
de585e2c
...
...
@@ -24,7 +24,7 @@ class StudentModule(models.Model):
module_id
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
)
# Filename for homeworks, etc.
student
=
models
.
ForeignKey
(
User
,
db_index
=
True
)
class
Meta
:
unique_together
=
((
'student'
,
'module_id'
,
'module_type'
),)
unique_together
=
((
'student'
,
'module_id'
),)
## Internal state of the object
state
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
...
...
courseware/module_render.py
View file @
de585e2c
import
StringIO
import
json
import
logging
import
os
import
sys
import
sys
...
...
@@ -32,6 +33,8 @@ import courseware.modules.seq_module
import
courseware.modules.vertical_module
import
courseware.modules.video_module
log
=
logging
.
getLogger
(
"mitx.courseware"
)
## TODO: Add registration mechanism
modx_modules
=
{
'problem'
:
courseware
.
modules
.
capa_module
.
LoncapaModule
,
'video'
:
courseware
.
modules
.
video_module
.
VideoModule
,
...
...
@@ -59,11 +62,10 @@ def make_track_function(request):
def
modx_dispatch
(
request
,
module
=
None
,
dispatch
=
None
,
id
=
None
):
''' Generic view for extensions. '''
# Grab the student information for the module from the database
s
=
StudentModule
.
objects
.
filter
(
module_type
=
module
,
student
=
request
.
user
,
s
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
,
module_id
=
id
)
if
len
(
s
)
==
0
:
print
"ls404"
,
module
,
request
.
user
,
id
log
.
debug
(
"Couldnt find module for user and id "
+
str
(
module
)
+
" "
+
str
(
request
.
user
)
+
" "
+
str
(
id
))
raise
Http404
s
=
s
[
0
]
...
...
courseware/modules/capa_module.py
View file @
de585e2c
...
...
@@ -46,13 +46,13 @@ class LoncapaModule(XModule):
def
get_html
(
self
):
return
render_to_string
(
'problem_ajax.html'
,
{
'id'
:
self
.
filename
,
{
'id'
:
self
.
item_id
,
'ajax_url'
:
self
.
ajax_url
,
})
def
get_init_js
(
self
):
return
render_to_string
(
'problem.js'
,
{
'id'
:
self
.
filename
,
{
'id'
:
self
.
item_id
,
'ajax_url'
:
self
.
ajax_url
,
})
...
...
@@ -100,7 +100,7 @@ class LoncapaModule(XModule):
html
=
render_to_string
(
'problem.html'
,
{
'problem'
:
content
,
'id'
:
self
.
filename
,
'id'
:
self
.
item_id
,
'check_button'
:
check_button
,
'reset_button'
:
reset_button
,
'save_button'
:
save_button
,
...
...
courseware/views.py
View file @
de585e2c
...
...
@@ -43,6 +43,12 @@ def profile(request):
chapters
=
dom
.
xpath
(
'//course[@name=$course]/chapter'
,
course
=
course
)
responses
=
StudentModule
.
objects
.
filter
(
student
=
request
.
user
)
response_by_id
=
{}
for
response
in
responses
:
response_by_id
[
response
.
module_id
]
=
response
total_scores
=
{}
for
c
in
chapters
:
chname
=
c
.
get
(
'name'
)
...
...
@@ -53,31 +59,124 @@ def profile(request):
scores
=
[]
if
len
(
problems
)
>
0
:
for
p
in
problems
:
id
=
p
.
get
(
'
filename
'
)
id
=
p
.
get
(
'
id
'
)
correct
=
0
for
response
in
responses
:
if
response
.
module_id
==
id
:
if
response
.
grade
!=
None
:
correct
=
response
.
grade
else
:
correct
=
0
if
id
in
response_by_id
:
response
=
response_by_id
[
id
]
if
response
.
grade
!=
None
:
correct
=
response
.
grade
total
=
courseware
.
modules
.
capa_module
.
LoncapaModule
(
etree
.
tostring
(
p
),
"id"
)
.
max_score
()
# TODO: Add state. Not useful now, but maybe someday problems will have randomized max scores?
scores
.
append
((
int
(
correct
),
total
))
scores
.
append
((
int
(
correct
),
total
,
(
True
if
s
.
get
(
'graded'
)
==
"True"
else
False
)
))
section_total
=
(
sum
([
score
[
0
]
for
score
in
scores
]),
sum
([
score
[
1
]
for
score
in
scores
]))
graded_total
=
(
sum
([
score
[
0
]
for
score
in
scores
if
score
[
2
]]),
sum
([
score
[
1
]
for
score
in
scores
if
score
[
2
]]))
#Add the graded total to total_scores
format
=
s
.
get
(
'format'
)
if
s
.
get
(
'format'
)
else
""
if
format
and
graded_total
[
1
]
>
0
:
format_scores
=
total_scores
[
format
]
if
format
in
total_scores
else
[]
format_scores
.
append
(
graded_total
)
total_scores
[
format
]
=
format_scores
score
=
{
'course'
:
course
,
'section'
:
s
.
get
(
"name"
),
'chapter'
:
c
.
get
(
"name"
),
'scores'
:
scores
,
'section_total'
:
section_total
,
'format'
:
format
,
}
hw
.
append
(
score
)
def
totalWithDrops
(
scores
,
drop_count
):
sorted_scores
=
sorted
(
enumerate
(
scores
),
key
=
lambda
x
:
-
x
[
1
][
'percentage'
]
)
#Note that this key will sort the list descending
dropped_indices
=
[
score
[
0
]
for
score
in
sorted_scores
[
-
drop_count
:]]
# A list of the indices of the dropped scores
aggregate_score
=
0
for
index
,
score
in
enumerate
(
scores
):
if
index
not
in
dropped_indices
:
aggregate_score
+=
score
[
'percentage'
]
aggregate_score
/=
len
(
scores
)
-
drop_count
return
aggregate_score
,
dropped_indices
#Figure the homework scores
homework_scores
=
total_scores
[
'Homework'
]
if
'Homework'
in
total_scores
else
[]
homework_percentages
=
[]
for
i
in
range
(
12
):
if
i
<
len
(
homework_scores
):
percentage
=
homework_scores
[
i
][
0
]
/
float
(
homework_scores
[
i
][
1
])
summary
=
"{:.0
%
} ({}/{})"
.
format
(
percentage
,
homework_scores
[
i
][
0
],
homework_scores
[
i
][
1
]
)
else
:
percentage
=
0
summary
=
"0
%
(?/?)"
summary
=
"Homework {} - {}"
.
format
(
i
+
1
,
summary
)
homework_percentages
.
append
(
{
'percentage'
:
percentage
,
'summary'
:
summary
}
)
homework_total
,
homework_dropped_indices
=
totalWithDrops
(
homework_percentages
,
2
)
#Figure the lab scores
lab_scores
=
total_scores
[
'Lab'
]
if
'Lab'
in
total_scores
else
[]
lab_percentages
=
[]
for
i
in
range
(
12
):
if
i
<
len
(
lab_scores
):
percentage
=
lab_scores
[
i
][
0
]
/
float
(
lab_scores
[
i
][
1
])
summary
=
"{:.0
%
} ({}/{})"
.
format
(
percentage
,
lab_scores
[
i
][
0
],
lab_scores
[
i
][
1
]
)
else
:
percentage
=
0
summary
=
"0
%
(?/?)"
summary
=
"Lab {} - {}"
.
format
(
i
+
1
,
summary
)
lab_percentages
.
append
(
{
'percentage'
:
percentage
,
'summary'
:
summary
}
)
lab_total
,
lab_dropped_indices
=
totalWithDrops
(
lab_percentages
,
2
)
midterm_score
=
(
120
,
150
)
midterm_percentage
=
midterm_score
[
0
]
/
float
(
midterm_score
[
1
])
final_score
=
(
200
,
300
)
final_percentage
=
final_score
[
0
]
/
float
(
final_score
[
1
])
grade_summary
=
[
{
'category'
:
'Homework'
,
'subscores'
:
homework_percentages
,
'dropped_indices'
:
homework_dropped_indices
,
'totalscore'
:
{
'score'
:
homework_total
,
'summary'
:
"Homework Average - {:.0
%
}"
.
format
(
homework_total
)},
'weight'
:
0.15
,
},
{
'category'
:
'Labs'
,
'subscores'
:
lab_percentages
,
'dropped_indices'
:
lab_dropped_indices
,
'totalscore'
:
{
'score'
:
lab_total
,
'summary'
:
"Lab Average - {:.0
%
}"
.
format
(
lab_total
)},
'weight'
:
0.15
,
},
{
'category'
:
'Midterm'
,
'totalscore'
:
{
'score'
:
midterm_percentage
,
'summary'
:
"Midterm - {:.0
%
} ({}/{})"
.
format
(
midterm_percentage
,
midterm_score
[
0
],
midterm_score
[
1
])},
'weight'
:
0.30
,
},
{
'category'
:
'Final'
,
'totalscore'
:
{
'score'
:
final_percentage
,
'summary'
:
"Final - {:.0
%
} ({}/{})"
.
format
(
final_percentage
,
final_score
[
0
],
final_score
[
1
])},
'weight'
:
0.40
,
}
]
user_info
=
UserProfile
.
objects
.
get
(
user
=
request
.
user
)
context
=
{
'name'
:
user_info
.
name
,
'username'
:
request
.
user
.
username
,
'location'
:
user_info
.
location
,
'language'
:
user_info
.
language
,
'email'
:
request
.
user
.
email
,
'homeworks'
:
hw
,
'homeworks'
:
hw
,
'grade_summary'
:
grade_summary
,
'csrf'
:
csrf
(
request
)[
'csrf_token'
]
}
return
render_to_response
(
'profile.html'
,
context
)
...
...
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