diff --git a/knowledge/README.txt b/knowledge/README.txt new file mode 100644 index 0000000..0b98e36 --- /dev/null +++ b/knowledge/README.txt @@ -0,0 +1,70 @@ +Knowledge management, learning, and similar stuff +================================================= + + ($Id$) + +Let's first set up a tree of knowledge elements (topics) and their +interdependencies: + + >>> from cybertools.knowledge.element import KnowledgeElement + >>> progLang = KnowledgeElement() + >>> ooProg = KnowledgeElement() + >>> python = KnowledgeElement() + >>> pyBasics = KnowledgeElement() + >>> pyOo = KnowledgeElement() + >>> pySpecials = KnowledgeElement() + +The knowledge may be organized in a hierarchy (taxonomy) of topics; we +don't use this at the moment but it is important to give the knowledge +an overall structure. + + >>> python.parent = progLang + >>> pyBasics.parent = python + >>> pyOo.parent = python + >>> pySpecials.parent = python + +An important point here is that a knowledge element may depend on another; +this means that somebody first has to acquire one of the knowledge elements +before being able to acquire a dependent element. In our example one +would first have to study object-oriented programming in general and the +Python basics before being able to study object oriented programming +with Python. + + >>> pyOo.dependsOn(ooProg) + >>> pyOo.dependsOn(pyBasics) + +Now we create a person that knows about basic Python programming: + + >>> from cybertools.knowledge.knowing import Knowing + >>> john = Knowing() + >>> john.knows(pyBasics) + +Next we have a position that requires knowledge in object-oriented +programming with Python: + + >>> from cybertools.knowledge.position import Position + >>> pos01 = Position() + >>> pos01.requires(pyOo) + +Now we can ask what knowledge john is lacking if he would like to take +the position offered: + + >>> john.getMissingKnowledge(pos01) == (ooProg, pyOo,) + True + +Luckily there are a few elearning content objects out there that +provide some of the knowledge needed: + + >>> from cybertools.knowledge.provider import KnowledgeProvider + >>> doc01 = KnowledgeProvider() + >>> doc02 = KnowledgeProvider() + + >>> doc01.provides(ooProg) + >>> doc02.provides(pyOo) + +So that we are now able to find out what john has to study in order to +fulfill the position offered: + + >>> list(john.getProvidersNeeded(pos01)) + + diff --git a/knowledge/__init__.py b/knowledge/__init__.py new file mode 100644 index 0000000..4bc90fb --- /dev/null +++ b/knowledge/__init__.py @@ -0,0 +1,4 @@ +""" +$Id$ +""" + diff --git a/knowledge/element.py b/knowledge/element.py new file mode 100644 index 0000000..244b1af --- /dev/null +++ b/knowledge/element.py @@ -0,0 +1,72 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Represent knowledge elements and their interrelations. + +$Id$ +""" + +from zope.interface import implements +from cybertools.knowledge.interfaces import IKnowledgeElement + + +class KnowledgeElement(object): + + implements(IKnowledgeElement) + + def __init__(self): + self._parent = None + self._dependencies = {} + # backlinks: + self._children = set() + self._dependents = set() + self._knowers = set() + self._requiringPositions = set() + self._providers = set() + + def setParent(self, obj): + old = self._parent + if old is not None and old != obj: + del old._children[self] + if obj is not None and old != obj: + obj._children.add(self) + self._parent = obj + def getParent(self): return self._parent + parent = property(getParent, setParent) + + def getDependencies(self): + return self._dependencies + + def dependsOn(self, obj): + self._dependencies[obj] = True + obj._dependents.add(self) + + def removeDependency(self, obj): + del self._dependencies[obj] + del obj._dependents[self] + + def getDependents(self): + return self._dependents + + def getKnowers(self): + return self._knowers + + def getProviders(self): + return tuple(self._providers) + diff --git a/knowledge/interfaces.py b/knowledge/interfaces.py new file mode 100644 index 0000000..531ab4b --- /dev/null +++ b/knowledge/interfaces.py @@ -0,0 +1,139 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Interfaces for knowledge management and e-learning. + +$Id$ +""" + +from zope.interface import Interface, Attribute +from zope import schema +from zope.i18nmessageid import MessageFactory + +_ = MessageFactory('zope') + + +class IKnowledgeElement(Interface): + """ An entity denoting some sort of knowledge. + """ + + parent = Attribute('An optional parent element (sort of parent topic)') + + def getDependencies(): + """ Return a collection of knowledge elements this object depends on. + """ + + def dependsOn(element): + """ Add an element to the collection of elements this object + depends on. + """ + + def removeDependency(element): + """ Remove the element given from the collection of elements + this object depends on. + """ + + def getDependents(): + """ Return a collection of knowledge elements that are depending + on this object. + """ + + def getKnowers(): + """ Return a collection of Knowing objects that have this object + in their knowledge portfolio. + """ + + def getProviders(): + """ Return a collection of knowledge providers that provide this + object. + """ + + +class IKnowing(Interface): + """ Someone who knows something. + """ + + def getKnowledge(): + """ Return the collection of elements that constitute the + knowledge of this object. + """ + + def knows(self, element): + """ Add an element to the collection of elementsthat constitute the + knowledge of this object. + """ + + def removeKnowledge(element): + """ Remove the element given from the collection of elements + that constitute the knowledge of this object. + """ + + def getMissingKnowledge(position): + """ Return a tuple of knowledge elements that this object + is missing for fulfilling the position given. + """ + + def getProvidersNeeded(position): + """ Return two tuples: first a tuple of knowledge providers that + provide knowledge needed for fulfilling the position given, + second a tuple with the requirements that could not + be met by the available knowledge providers. + """ + + +class IPosition(Interface): + """ A position requires a certain knowledge. + """ + + def getRequirements(): + """ Return the collection of knowledge elements this object requires. + """ + + def requires(element): + """ Add a knowledge element to the collection of elements this + object requires. + """ + + def removeKnowledge(element): + """ Remove the element given from the collection of elements + this object requires. + """ + + +class IKnowledgeProvider(Interface): + """ An object that is able to provide a certain knowledge - that may + be a document or some sort of elearning content, ... + """ + + def getProvidedKnowledge(): + """ Return a collection of knowledge elements this object provides. + """ + + def provides(element): + """ Add a knowledge element to the collection of elements this + object provides. + """ + + def removeProvidedKnowledge(element): + """ Remove the element given from the collection of elements + this object provides. + """ + + + diff --git a/knowledge/knowing.py b/knowledge/knowing.py new file mode 100644 index 0000000..8ef0877 --- /dev/null +++ b/knowledge/knowing.py @@ -0,0 +1,55 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Manage objects (people) who know something. + +$Id$ +""" + +from zope.interface import implements +from cybertools.knowledge.interfaces import IKnowing + + +class Knowing(object): + + implements(IKnowing) + + def __init__(self): + self._knowledge = {} + + def getKnowledge(self): + return self._knowledge + + def knows(self, obj): + self._knowledge[obj] = True + obj._knowers.add(self) + + def removeKnowledge(self, obj): + del self._knowledge[obj] + del obj._knowers[self] + + def getMissingKnowledge(self, position): + # to be done + return tuple(position.getRequirements()) + + def getProvidersNeeded(self, position): + return ((k, k.getProviders()) + for k in self.getMissingKnowledge(position)) + + diff --git a/knowledge/position.py b/knowledge/position.py new file mode 100644 index 0000000..7f52ab1 --- /dev/null +++ b/knowledge/position.py @@ -0,0 +1,46 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Represent positions that require certain knowledge. + +$Id$ +""" + +from zope.interface import implements +from cybertools.knowledge.interfaces import IPosition + + +class Position(object): + + implements(IPosition) + + def __init__(self): + self._requirements = {} + + def getRequirements(self): + return self._requirements + + def requires(self, obj): + self._requirements[obj] = True + obj._requiringPositions.add(self) + + def removeRequirement(self, obj): + del self._requirements[obj] + del obj._requiringPositions[self] + diff --git a/knowledge/provider.py b/knowledge/provider.py new file mode 100644 index 0000000..73c608b --- /dev/null +++ b/knowledge/provider.py @@ -0,0 +1,46 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Knowledge providers provide knowledge. + +$Id$ +""" + +from zope.interface import implements +from cybertools.knowledge.interfaces import IKnowledgeProvider + + +class KnowledgeProvider(object): + + implements(IKnowledgeProvider) + + def __init__(self): + self._providedKnowledge = {} + + def getProvidedKnowledge(self): + return self._providedKnowledge + + def provides(self, obj): + self._providedKnowledge[obj] = True + obj._providers.add(self) + + def removeDependency(self, obj): + del self._providedKnowledge[obj] + del obj._providers[self] + diff --git a/knowledge/tests.py b/knowledge/tests.py new file mode 100755 index 0000000..7391542 --- /dev/null +++ b/knowledge/tests.py @@ -0,0 +1,28 @@ +#! /usr/bin/python + +""" +Tests for the 'cybertools.knowledge' package. + +$Id$ +""" + +import unittest, doctest +from zope.testing.doctestunit import DocFileSuite +from cybertools.knowledge.knowing import Knowing + +class TestKnowledge(unittest.TestCase): + "Basic tests for the knowledge package." + + def testBasicStuff(self): + p = Knowing() + + +def test_suite(): + flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS + return unittest.TestSuite(( + unittest.makeSuite(TestKnowledge), + DocFileSuite('README.txt', optionflags=flags), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite')