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() >>> tracks = TrackingStorage()
We can now create a ScormAPI adapter. Note that this adapter is stateless 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 >>> from cybertools.scorm.base import ScormAPI
>>> api = ScormAPI(tracks, 'a001', 0, 'user1') >>> 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 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 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): >>> for t in sorted(tracks.values(), key=lambda x: x.timeStamp):
... print t.data ... print t.data
@ -48,3 +48,17 @@ to care about the storage in different track objects.
('q007', '0') ('q007', '0')
>>> api.getValue('cmi.interactions.1.result') >>> api.getValue('cmi.interactions.1.result')
('incorrect', '0') ('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' 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): class ScormAPI(object):
""" ScormAPI objects are temporary adapters created by """ ScormAPI objects are temporary adapters created by
@ -81,8 +94,18 @@ class ScormAPI(object):
def getValue(self, element): def getValue(self, element):
tracks = self.storage.getUserTracks(self.taskId, self.runId, self.userId) 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) prefix, key = self._splitKey(element)
data = self._getTrackData(tracks, prefix) or {} data = self._getTrackData(tracks, prefix)
if key in data: if key in data:
return data[key], OK return data[key], OK
else: else:
@ -103,8 +126,26 @@ class ScormAPI(object):
return '', element return '', element
def _getTrackData(self, tracks, prefix): def _getTrackData(self, tracks, prefix):
track = None
for tr in reversed(sorted(tracks, key=lambda x: x.timeStamp)): for tr in reversed(sorted(tracks, key=lambda x: x.timeStamp)):
if tr and tr.data.get('key_prefix', None) == prefix: if tr and tr.data.get('key_prefix', None) == prefix:
return tr.data return tr.data
return {} 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'