Recipe3.4.Summing Durations of Songs


Recipe 3.4. Summing Durations of Songs

Credit: Anna Martelli Ravenscroft

Problem

You want to find out the total duration of a playlist of songs.

Solution

Use the datetime standard module and the built-in function sum to handle this task:

import datetime def totaltimer(times):     td = datetime.timedelta(0)    # initial value of sum (must be a timedelta)     duration = sum([         datetime.timedelta(minutes=m, seconds=s) for m, s in times],         td)     return duration if _ _name_ _== '_ _main_ _':        # test when module run as main script     times1 = [(2, 36),        # list containing tuples (minutes, seconds)               (3, 35),               (3, 45),]     times2 = [(3, 0),               (5, 13),               (4, 12),               (1, 10),]     assert totaltimer(times1) == datetime.timedelta(0, 596)     assert totaltimer(times2) == datetime.timedelta(0, 815)     print ("Tests passed.\n"            "First test total: %s\n"            "Second test total: %s" % (             totaltimer(times1), totaltimer(times2)))

Discussion

I have a large playlist of songs I listen to during workouts. I wanted to create a select list but wanted to know the total duration of the selected songs, without having to create the new playlist first. I wrote this little script to handle the task.

A datetime.timedelta is normally what's returned when calculating the difference between two datetime objects. However, you can create your own timedelta instance to represent any given duration of time (while other classes of the datetime module, such as class datetime, have instances that represent a point in time). Here, we need to sum durations, so, clearly, it's exactly timedelta that we need.

datetime.timedelta takes a variety of optional arguments: days, seconds, microseconds, milliseconds, minutes, hours, weeks. So, to create an instance, you really should pass named arguments when you call the class to avoid confusion. If you simply call datetime.timedelta(m, n), without naming the arguments, the class uses positional notation and treats m and n as days and seconds, which produces really strange results. (I found this out the hard way . . . a good demonstration of the need to test!)

To use the built-in function sum on a list of objects such as timedeltas, you have to pass to sum a second argument to use as the initial valueotherwise, the default initial value is 0, integer zero, and you get an error as soon as you try to sum a timedelta with that int. All objects in the iterable that you pass as sum's first argument should be able to support numeric addition. (Strings are specifically disallowed, but, take my earnest advice: don't use sum for concatenating a lot of lists either!) In Python 2.4, instead of a list comprehension for sum's first argument, we could use a generator expression by replacing the square brackets, [ and ], with parentheses, ( and )which might be handy if you're trying to handle a playlist of several thousand songs.

For the test case, I manually created a list of tuples with the durations of the songs in minutes and seconds. The script could be enhanced to parse the times in different formats (such as mm:ss) or to read the information from a file or directly from your music library.

See Also

Library Reference on sum and datetime.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net