On Aug 24, 2008, at 7:20 PM, Kent Johnson wrote:
Forwarding to the list with my reply. Please use Reply All to reply
to the list.
Grr, sorry, I keep forgetting...
On Sun, Aug 24, 2008 at 1:02 AM, Eric Abrahamsen
<[EMAIL PROTECTED]> wrote:
On Aug 23, 2008, at 11:22 PM, Kent Johnson wrote:
On Sat, Aug 23, 2008 at 6:47 AM, Eric Abrahamsen
<[EMAIL PROTECTED]> wrote:
At first I thought the bisect module was the way to go, but it is
too
tightly tied to integer list indices, and works very awkwardly when
bisecting on datetime attributes.
I'm not sure what the problem is with bisect (to find the starting
point). Your list of model elements has integer indices. I think you
have to write a __cmp__ method for your model class that compares on
the datetime attribute, then it should work. You can also create a
list of (key, model) and sort/search that.
http://www.mail-archive.com/[EMAIL PROTECTED]/msg189443.html
The __cmp__ trick is very nice, and would do it, except I won't
have access
to the events model classes. I could get bisect to work by feeding
it a list
comprehension, but making the high and low parameters work required
integer
indices, which seemed like one half-hack too many...
I don't understand the issue. *All* lists have integer indices. If you
make a list of (key, model) pairs, the keys only need to be
comparable, not integers.
The main problem is that I don't have any control over the list of
models, and all I've got is the name of a datetime attribute to filter
by. The only way I could get bisect to work was like this:
index = bisect([getattr(x, attr_name) for x in model_list],
sentinel_date)
But that loops over the whole list, which is what I was trying to
avoid. And the only way I could provide high and low parameters to
bisect is by calling event_list.index(event), which doesn't work on
django querysets. I also experimented with itertools.groupby to
produce groups of events, but that turned out to be far slower than
simply looping over the whole event list and extracting events which
test true for c.start <= getattr(event, attr_name) < c.stop.
Ideally I could create a kind of concurrent iterator, that steps
through children's blocks of time and the object's event list in
tandem, rather than going over the whole events list once for every
child produced. Maybe that's not possible... I'm pasting the whole
function down below, just for the hell of it.
Thanks again,
Eric
def _iter_children(self, child, require_events=False):
"""
Iterate through an object's 'child' items.
If require_events == True, only return children with
events, otherwise return all children.
"""
while self.sentinel < self.stop:
c = child([], self.sentinel, self.start_attr,
rolling=self.rolling, counts_only=self.counts_only)
for e in self.events:
if c.start <= getattr(e,self.start_attr) < c.stop:
c.events.append(e)
self.sentinel += c.dt_range
if not require_events or c.has_events():
yield c
_______________________________________________
Tutor maillist - Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor