Catalogue¶
A catalogue is a simple file-based database to store parametric combinations for components.
Analogy¶
If a Component
is a blueprint, the parameters
of its inherited ParametricObject
are the measurements, or metrics corresponding to the blueprint.
A Catalogue
is an exhaustive list of all parameter combinations,
for the context of manufacture, or purchase.
Each catalogued item can also contain information about the item that aren’t necessarily in the blueprint. Such as make, model, and product code, as well as ids for compatible items, and even calculated metrics like area (from length and width parameters).
Storage¶
A catalogue is represented in a single json
file, using tinydb
to read & write.
Note
More cataloguing methods may exist in future, but at this time only
JSONCatalogue
is implemented.
Usage¶
Let’s create an empty JSONCatalogue
, and push some
Component
instances into it.
Create a new Catalogue¶
Let’s say you’d like to save your catalogue in the file:
>>> filename = 'my_catalogue.json'
Then create the empty database:
>>> # Instantiate Catalogue
>>> from cqparts.catalogue import JSONCatalogue
>>> catalogue = JSONCatalogue(filename)
Add items¶
Now let’s create a few Box
parts,
of varying lengths, and add them to the catalogue
.
Using the JSONCatalogue.add()
method, we give each box a unique id
,
some criteria
, and of course the obj
Box
instance we’d like to add.
>>> from cqparts_misc.basic.primatives import Box
>>> # Add a few items
>>> for length in [10, 20, 30]:
... name = "box_L%g" % length
... box = Box(length=length)
... index = catalogue.add(
... id=name,
... criteria={
... 'type': 'box',
... 'lengthcode': 'L%i' % int(length),
... },
... obj=box
... )
At this point, we can close the file:
>>> catalogue.close()
which will commit the data to disk, ready for another script to read the catalogue to search and instantiate the recorded items.
For this tutorial, we’ll leave it open though. If you ran the above
close()
code, you can just re-open it with:
>>> catalogue = JSONCatalogue(filename)
Searching items¶
Now that we have items in our catalogue
, we can search them with
search()
, and find()
.
find()
will search the catalogue, and assert that
1, and only 1 result is returned. Otherwise an exception is raised.
>>> # Find
>>> item = catalogue.get_query()
>>> result = catalogue.find(item.id == 'box_L20')
>>> result.keys()
[u'obj', u'id', u'criteria']
>>> result['obj']['params']['length']
20.0
If you’re less certain that your query will yield a single result,
search()
will return a list of positively
matching items.
>>> # Search
>>> item = catalogue.get_query()
>>> results = catalogue.search(item.criteria.type == 'box')
>>> len(results) # all 3 boxes
3
To learn more about a catalogue’s content, you can see its contents quite easily from the items table:
>>> len(catalogue.items.all()) # everything in the catalogue
3
>>> i = catalogue.items.all()[0]
>>> i['obj']['params']['length']
10.0
>>> i['id']
u'box_L10'
>>> # from this we've learnt that we can search with:
>>> item = catalogue.get_query()
>>> result = catalogue.find(item.obj.params.length == 10)
>>> result['obj']['params']['length']
10.0
>>> result['id'] # the same item we got earlier
u'box_L10'
To learn more about searching, read the tinydb
docs.
Deserialize items¶
Once an item has been selected from a catalogue, it can be instantiated by deserializing it:
>>> # Get our catalogued 20mm long box
>>> result = catalogue.find(item.id == 'box_L20')
>>> # Creating object
>>> catalogue.deserialize_item(result)
<Box: height=1.0, length=20.0, width=1.0>
To streamline things, we can also do all of this in one line with the
get()
method”
>>> # Search and deserialize in one line
>>> catalogue.get(item.obj.params.length > 25)
<Box: height=1.0, length=30.0, width=1.0>
Note
All searching is done by tinydb
, so
search()
, find()
and get_query()
are simply pass-throughs
to the underlying tinydb.TinyDB
instance in the db
attribute
of this class.
Please read the tinydb
documentation, and query the database
directly with this classes db
attribute.
Item database example¶
Each catalogue item is stored in an items
table within the database.
The items
table is stored as a list, one of the elements stored in the
above example may be stored like this:
{
'id': 'box_L20',
'criteria': {'lengthcode': 'L20', 'type': 'box'},
'obj': {
'class': {
'module': 'cqparts_misc.basic.primatives',
'name': 'Box',
},
'lib': {
'name': 'cqparts',
'version': '0.1.0',
},
'params': {
'_render': {'alpha': 1.0, 'color': [192, 192, 192]},
'_simple': False,
'height': 1.0,
'length': 20.0,
'width': 1.0,
}
}
}