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

Reply via email to