I just started programming with Python, and have some simple questions (probably). What I would like to do is compare some timestamps to find the closest that isn’t later then now.
Basically what Iam trying to do is getting the current track played on the radio, and they have a feed that show the next 20 or so with time for when the track starts. I want to get whats playing right now!
Here is an example array of strings:
examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
Now what I would like to do is compare the time closest to now (but not later) to see whats currently playing.
This is my script so far:
import datetime, itertools, time
currentTimeMachine = datetime.datetime.now()
now = currentTimeMachine.strftime("%Y-%m-%d %H:%M:%S")
examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
tmsg = examples.strftime('%d%b%Y')
print [x for x in itertools.takewhile( lambda t: now > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), examples )][-1]
The last bit there I picked up somwhere else, but I cant seem to get it to work.
Any help would be greatly appreciated!
The other answers have fixed your errors, so your algorithm now runs properly.
But the algorithm itself is wrong. You want to get the closest to the present without going over. But what you’ve written is:
Think about what this means. First,
takewhilewill return examples until one of them fails the predicate. Then you’re taking the last one that succeeded. So, if your examples looked like this:First,
takewhilewill yieldnow-3, now-10, now-5and then stop becausepred(now+3)returns False. Then, you take the last one,now-5.This would work if you sorted the examples in ascending order:
Now
takewhilewill yield everything up tonow-1, so the last thing it yields is the one you want.But the example in your initial question were in descending order, and in the comment to Anthony Kong’s answer, you added some more that aren’t in any order at all. So, you obviously can’t rely on them being in sorted order. So, one possible fix is to sort them:
Or, to make things a bit more readable, break up that last line, and get rid of the extraneous list comprehension:
However, this is kind of a silly way to do things. What you really want is the maximum value in examples that isn’t after the present. So just translate that English sentence into code:
Let’s put it all together:
I used a generator expression rather than a list for
exampleDatesbecause you don’t actually need the list for anything you just need to iterate over it once. If you want to keep it around for inspection or repeated use, change the parens to square brackets.Also, I changed the
<to<=, because you said “isn’t later then now” rather than “is earlier than now” (in other words, now should count).As a side note, because you happen to have ISO-esque timestamps, you actually can sort them as strings:
There’s no good reason to do things this way, and it will invariably lead you to bugs when you get timestamps in slightly different formats (e.g.,
'2012-12-10 02:06:45'compares before'2012-12-10Z01:06:45'), but it isn’t actually a problem with your original code.