Working With Learning Outcomes
Contents
Working With Learning Outcomes#
Learning outcomes can be created at various levels of abstraction: for example, at the unit level, at the block level, at the module level and at the qualification level.
Learning outcomes are distinguished elements in OU-XML documents, although not all materials make use of them.
We can search over learning outcomes specifically in order to discover teaching materials that presumably claim to deliver those outcomes specifically. We can also browse over or search on previously defined learning outcomes to provide inspiration or model phrases for creating new learning outcomes. (Using extracted structure data such as a learning outcomes as training data for machine learning systems is another possibility, although such applications are out of scope of this review.)
You can try such a search here. WARNING: 100MB+ download: this database application runs purely in your browser and may take a minute or two to load.
In this section, we will see how to extract learning outcomes from the OU-XML associated with a single OpenLearn unit, and then create a simple database table that allows us to search over the learning outcomes for all the OpenLearn units that represent them in a structured way.
The learning outcomes themselves will be stored in a separate database to database containing the original OU-XML material to try to keep the database sizes down so that we can store them in GitHub and also load them in to browser based query UIs in an efficient way.
Preparing the Ground#
As ever, we need to set up a database connection:
from sqlite_utils import Database
# Open raw XML database connection
xml_dbname = "all_openlean_xml.db"
xml_db = Database(xml_dbname)
# Open assets database
dbname = "openlean_assets.db"
db = Database(dbname)
And get a sample XML file, selecting one that we know contains structurally marked up learning outcome elements:
from lxml import etree
import pandas as pd
# Grab an OU-XML file that is known to contain glossary items
a210_xml_raw = pd.read_sql("SELECT xml FROM xml WHERE name='An introduction to interaction design'",
con=xml_db.conn).loc[0, "xml"]
# Parse the XML into an xml object
root = etree.fromstring(a210_xml_raw)
Extracting Learning Outcomes#
Individual learning outcomes are defined as simple text <LearningOutcome>
elements [docs] in a <LearningOutcomes>
block wrapper:
<LearningOutcomes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Paragraph>After studying this course, you should be able to:</Paragraph>
<LearningOutcome>understand what interaction design is, the importance of user-centred design and methods of user information gathering</LearningOutcome>
<LearningOutcome>understand how the sensory, cognitive and physical capabilities of users inform the design of interactive products</LearningOutcome>
...
</LearningOutcomes>
The individual learning outcomes can be extracted simply as the text associated with a <LearningOutcome>
element:
def get_lo_items(rro):
"""Extract learning outcomes from an OU-XML XML object."""
return [lo.text for lo in root.xpath('//LearningOutcome')]
Let’s see what that returns from our test document:
get_lo_items(root)
['understand what interaction design is, the importance of user-centred design and methods of user information gathering',
'understand how the sensory, cognitive and physical capabilities of users inform the design of interactive products',
'understand the process of interaction design, including requirements elicitation, prototyping, evaluation and the need for iteration',
'analyse and critique the design of interactive products',
'select, adapt and apply suitable interaction design approaches and techniques towards the design of an interactive product.']
Adding Learning Outcome Items to the Database#
It’s trivial to add learning outcomes for all our units to the database, along with support for full text search over all the items.
First, create appropriate tables to store the data:
all_lo_tbl = db["lo"]
all_lo_tbl.drop(ignore=True)
all_lo_tbl.create({
"code": str,
"name": str,
"lo": str,
"_id": str
})
# Note that in this case the _id is not unique
# because the same id may apply to multiple los
# The _id is a reference for joining tables only
# Prepare the full-text search table
db[f"{all_lo_tbl.name}_fts"].drop(ignore=True)
db[all_lo_tbl.name].enable_fts(["lo", "_id"], create_triggers=True)
<Table lo (code, name, lo, _id)>
We can now iterate throughall the OU-XML documents in out databases and create a comprehensive OpenElarn learning outcome database:
from xml_utils import create_id
for row in xml_db.query("""SELECT * FROM xml;"""):
root = etree.fromstring(row["xml"])
lo_items = get_lo_items(root)
# From the list of learning outcome items,
# create a list of dict items we can add to the database
lo_item_dicts = [{"lo": lo,
"code": row["code"],
"name": row["name"]} for lo in lo_items if lo ]
# Add a reference id for each record
create_id(lo_item_dicts, id_field="_id")
# Add items to the database
db[all_lo_tbl.name].insert_all(lo_item_dicts)
Now we can test a query:
pd.read_sql("SELECT * FROM lo LIMIT 3", con=db.conn)
code | name | lo | _id | |
---|---|---|---|---|
0 | L101 | A brief history of communication: hieroglyphic... | understand how different writing systems have ... | 1f194525072f4358f7639c471ee5289665d50a3f |
1 | L101 | A brief history of communication: hieroglyphic... | understand how technology influences what we c... | 1f194525072f4358f7639c471ee5289665d50a3f |
2 | H807 | Accessibility of eLearning | discuss the main challenges facing disabled st... | 78aec27976cb7d1ce356bf0eda6e8fb66ea532e9 |
Or a full-text search:
def fts(db, base_tbl, q):
"""Run a simple full-text search query
over a table with an FTS virtual table."""
_q = f"""SELECT * FROM {base_tbl}_fts
WHERE {base_tbl}_fts MATCH {db.quote(q)} ;"""
return pd.read_sql(_q, con=db.conn)
fts(db, "lo", "describe problems").to_dict(orient="records")
[{'lo': 'describe some of the characteristics of a range of mental health problems',
'_id': '2b053be7f2aaf259e6a32eec6648f4077fea20e0'},
{'lo': 'describe how a support network can benefit a young person experiencing mental health problems',
'_id': '2b053be7f2aaf259e6a32eec6648f4077fea20e0'},
{'lo': 'describe the referral processes for a young person experiencing mental health problems to access professional support',
'_id': '2b053be7f2aaf259e6a32eec6648f4077fea20e0'},
{'lo': 'describe the particular problems in digesting plant material',
'_id': '1a8a51c8df910e3bf45558c76cad33fb5f7f5b18'}]