cybertools.scorm package basically operating

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1713 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-05-04 15:47:44 +00:00
parent 76ae5d8bbf
commit b65f9d1a6d
2 changed files with 59 additions and 4 deletions

View file

@ -10,7 +10,7 @@ In order to work with the SCORM API we first need a tracking storage.
>>> tracks = TrackingStorage()
We can now create a ScormAPI adapter. Note that this adapter is stateless
as it is usually created anew upon each request.
as usually a new instance is created upon each request.
>>> from cybertools.scorm.base import ScormAPI
>>> api = ScormAPI(tracks, 'a001', 0, 'user1')
@ -31,7 +31,7 @@ Then we can set some values.
Depending on the data elements the values entered are kept together in
one track or stored in separate track objects. So there is a separate
track for each interaction and one track for all the other elements.
track for each interaction and one additional track for all the other elements.
>>> for t in sorted(tracks.values(), key=lambda x: x.timeStamp):
... print t.data
@ -48,3 +48,17 @@ to care about the storage in different track objects.
('q007', '0')
>>> api.getValue('cmi.interactions.1.result')
('incorrect', '0')
We can also query special elements like _count and _children.
>>> api.getValue('cmi.objectives._count')
(0, '0')
>>> api.getValue('cmi.interactions._count')
(2, '0')
>>> api.getValue('cmi.interactions._children')
(('id', 'type', 'objectives', 'timestamp', 'correct_responses',
'weighting', 'learner_response', 'result', 'latency', 'description'), '0')
>>> api.getValue('cmi.objectives.5.score._children')
(('scaled', 'raw', 'min', 'max'), '0')

View file

@ -31,6 +31,19 @@ from cybertools.tracking.btree import TrackingStorage
OK = '0'
_children = {
'cmi.comments_from_learner': ('comment', 'location', 'timestamp'),
'cmi.comments_from_lms': ('comment', 'location', 'timestamp'),
'cmi.interactions': ('id', 'type', 'objectives', 'timestamp',
'correct_responses', 'weighting', 'learner_response',
'result', 'latency', 'description'),
'cmi.learner_preference': ('audio_level', 'language',
'delivery_speed', 'audio_captioning'),
'cmi.objectives': ('id', 'score', 'success_status', 'completion_status',
'description'),
'score': ('scaled', 'raw', 'min', 'max'),
}
class ScormAPI(object):
""" ScormAPI objects are temporary adapters created by
@ -81,8 +94,18 @@ class ScormAPI(object):
def getValue(self, element):
tracks = self.storage.getUserTracks(self.taskId, self.runId, self.userId)
if element.endswith('._count'):
base = element[:-len('._count')]
if element.startswith('cmi.interactions.'):
return self._countSubtracks(tracks, base), OK
else:
data = self._getTrackData(tracks, '')
return self._countSubelements(data, base), OK
if element.endswith('_children'):
base = element[:-len('._children')]
return self._getChildren(base)
prefix, key = self._splitKey(element)
data = self._getTrackData(tracks, prefix) or {}
data = self._getTrackData(tracks, prefix)
if key in data:
return data[key], OK
else:
@ -103,8 +126,26 @@ class ScormAPI(object):
return '', element
def _getTrackData(self, tracks, prefix):
track = None
for tr in reversed(sorted(tracks, key=lambda x: x.timeStamp)):
if tr and tr.data.get('key_prefix', None) == prefix:
return tr.data
return {}
def _countSubelements(self, data, element):
result = set()
for key in data:
if key.startswith(element) and key not in result:
result.add(key)
return len(result)
def _countSubtracks(self, tracks, base):
return len([tr for tr in tracks if tr.data.get('key_prefix').startswith(base)])
def _getChildren(self, base):
if base.endswith('.score'):
base = 'score'
if base in _children:
return _children[base], OK
else:
return '', '401'