views:

206

answers:

4

I'm trying to write a circuit schematic drawing tool in Python. I'm creating a simple database based on dictionaries which holds all the components and their properties. I'm also trying to create a simple query language where you can select, for example, all resistors with value>100ohms or footprint='0402'

So far, I can select things using some primitive predicate search and then union and intersection for more complex things.

However, I'm having trouble defining what the semantics ought to be for a purely negative search. For instance, something like

footprint != '0402'

should select all items with footprint not equal to 0402. But doing this with only intersection gives me a blank result. For this to work I need to select all components, then intersect with "not 0402" to remove the ones I don't want.

But this seems kind of brute force and seems like a fishy solution. I'm not interested in using a "real" database and query language, so please don't suggest that. I'm looking for the proper engineering rationale here, not necessarily a workaround to the problem.

This problem was covered to some degree in SICP book, but I got very confused, since I think they were also using continuations and stuff, which I don't get yet.

Can someone please explain what the 'proper' usage ought to be for negatively selecting stuff. I tried this in a commercial cad tool and it worked as expected, but then I've seen some SQL query examples (I think), which selected things first, then removed the unwanted ones.

thanks
michael

+3  A: 

It really depends on how you've implemented this "simple database based on dictionaries" as to why straight negation isn't working - you'll have to give us some more clues.

There's no reason why a straightforward negation match shouldn't work in Python, e.g.:

components = [
    { 'name': 'resistor', 'footprint': '0402', },
    { 'name': 'LED', 'footprint': '0100', },
    { 'name': 'speaker', 'footprint': '2000', },
]

[comp for comp in components if comp['footprint'] != '0402']
# [{'footprint': '0100', 'name': 'LED'}, {'footprint': '2000', 'name': 'speaker'}]

At a stretch, this is a simple database based on dictionaries - the specific capabilities are really going to depend on your actual implementation.

I'm resisting the temptation to suggest use of a real database and query language as I assume this is a learning exercise. It is a learning exercise, right? :)

Alabaster Codify
Yes, it's a learning exercise, also for fun, also to see if I can figure it out. I'm thinking about the logic of selecting stuff. Mathematically speaking, does doing a NOT search necessarily imply a 'search all' first? Suppose I wanted to compete with sql with my own db... what would I do? :)thx
In set theory, taking out set members based on their properties doesn't have an atomic notation or operation. It could be expressed as so, which does in a way have a "select all": T = { c : c ∈ C; footprint(c) ≠ 0402 }, if C is the set of components. Feels like you're mixing models, though...
Alabaster Codify
Oh, and I was happy to play along with "don't recommend using SQL", but please don't expect to get anywhere with a competitor to SQL as a query language unless you are addressing a completely new area. Completely new. Far too much inertia with SQL.
Alabaster Codify
+5  A: 

You'll be a lot happier with a proper database.

You have SQLite with your Python distribution. Simply define tables instead of dictionaries and use SQL.

If you need more power and sophistication, you can add SQLAlchemy (or SQLObject) and you won't struggle with these problems.

S.Lott
SQLite looks pretty simple actually. I was afraid I'd have to set up servers, configurations, etc. That's what I've been trying to avoid. It also seems to be implemented in C which gives an impression that it's probably pretty fast. thanks.
It's amazingly fast -- all in memory. Actually, the entire thing is implemented in "driver". No servers, no config, nothing.
S.Lott
+1 on SQLite, I've used it in quite a few situations where I didn't want a "database". You can throw in something like SQLAlchemy if you don't want to directly touch SQL.
Parand
Best of all, you can use SQLite even with an existing datasource by opening a database named ":memory:" and writing all your data to it. You can then manipulate your data with SQL and, if desired, write it back to your datasource afterward without ever writing anything to disk.
Ben Blank
+1  A: 

I agree with S.Lott that you would be happier with a real DB. SQLite is really light and fast, almost no drawbacks on using it.

if you really need to expose a simpler, yet complete, query language to the user, check JSONPath or JSONQuery (the second is a superset of the first). The exact syntax is (obviously) thought for JavaScript; but it should give you some ideas.

also, try to check similarities and differences with XPath and XQuery. it helps to see what is useful and what's culture-specific.

Javier
A: 

Can one of you DB-fluent people translate this google-like query into SQLite for me please, here with dotdict fields in the PyPI xmlrpc db --

summary: this that - butnotthis  version: > 0.1  author: James | Javier

i.e. d.summary ~ "this" and d.summary ~ "that" and d.summary !~ "butnotthis" and d.version > "0.1" and d.author ~ "James|Javier"

Aand, does anyone have a grammar and parser for such google-like queries ?

thanks, cheers -- denis

Denis