tags:

views:

48

answers:

2

hi there.

Im doing som route(geo) calculations. I need to sort out some routes going in the "wrong" direction... all rides have "routes" and all routes consist of a lot of steps on the route.... each step has a lat. and a lng. pair. I hope this makes sense?

This is the way i do it now, and it works... however... im performing this operation on many(!) rides..routes...coordinate-pairs, so i could use a little speed-up in my code.

for ride in initial_rides:  
steps = ride.route.steps.all()  
    for step in steps:  
        if lat_min < step.latitude< lat_max and lng_min< step.longitude< lng_max:  
            approved_rides.append(ride)  
            break  

I better admit already that i'm no super programmer :)

i have tried construction something like this(without any luck):

for i in ride:  
    number  = sum(itertools.ifilter(lambda x: lat_min< x.latitude< lat_max and lng_min< x.longitude< lng_max, ride.route.steps.all()))  
    if number >= 1:  
        approved_rides.append(ride)  

tried to combine lambda and ifilter however i get an error saying operator doesn't support types "int" and "step"... Am i doing something wrong?

should i be using list comprehensions?? map()?? or something else?

i have read through http://www.python.org/doc/essays/list2str.html without any luck.

any help is greatly appreciated. thank you, and good day :)

Peter

A: 

To speed this up you should probably be using a better algorithm instead of trying all possible solutions. A* is a classic heuristic that could work on your problem.

You can try a comprehension like

approved_rides = [ride for ride in initial_rides if any(
          (lat_min < step.latitude< lat_max and \
           lng_min< step.longitude< lng_max) for step in ride.route.steps.all())]

which is your first code block as a oneliner.

If you can please give me a number how much faster it is, I'm interested :-)

THC4k
thanks :) Will be trying this out and post how much faster it is :)
Peter Møller
I have tried your method now. With a rather small number of initial_rides it's about 30% faster! :) However... with a lot(!) of rides and coordinates there's almost no difference in time. could this be because the comprehension is basically the same sort of code..? with the same kinda loops and so forth?from what i have read the map() function executes the code i C, so could do you think it's possible to make an algorith(like the one you just made) with the help of map() or something efficient of that sort? thanks.
Peter Møller
Peter Møller: That is pretty much what i expected. LCs are highly optimized (actually even more than `map`) and they pretty much spend all their time doing C code. As I said, you need a better algorithm, micro optimizations like this will get you nowhere.
THC4k
A: 

The reason for the error is that you are calling sum on a list of things that you can't sum, namely, ride.route.steps.all(). I assume that gives list of steps; what were you intending to do by summing them?

You can count the number of elements in a list with len.

I think you are trying to do the following:

key = lambda x: lat_min< x.latitude< lat_max and lng_min< x.longitude< lng_max
approved_rides = [ ride for ride in rides if any( map( key, ride.route.steps.all( ) ) ) ]

That will make approved_rides a list of the rides any of whose ride.roude.steps.all( ) satisfies key.

katrielalex
thanks. kinda of what i was looking for. but this clocked in at 0.69 actually :-Smy own simple method came in at 0.52 and THC4k's came in at 0.45...however both your methods do what i want so thanks for that :) perhabs i just can't increase the speed anymore. Perhabs i should reconsider the way im sorting these routes in the first place :-/thanks anyway :)
Peter Møller
Heh, this was in no way meant to be optimised for speed. THC4k's code is clearer and faster!
katrielalex