Commit 9e18b261 by Piotr Mitros

Refactoring into module, part 1

parent cc1de22e
......@@ -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
......@@ -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
......
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
......@@ -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]
......@@ -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, filename):
def render_x_module(request, xml_module):
# 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):
......
......@@ -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 ""
......
......@@ -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')),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment