Gustav P.
Gustav P.

Reputation: 33

Reading timestamps from a file and convert to ms

I'm trying to write a program in Python that will:

The code works when I write the timestamps in a variable, but nothing happens when I try to use a file as input. The program runs, but nothing is printed to the console.

This is how the code looks:

import csv
import datetime
from Tkinter import Tk
from tkFileDialog import askopenfilename

Tk().withdraw()
toopen = askopenfilename(filetypes=[("Text file","*.txt")])

with open(toopen, 'rb') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        code = row[0]
        times = row[1].split()
        times = [datetime.datetime.strptime(x, "%H:%M:%S.%f") for x in times]
        for i in range(len(times) - 1):
            delta = times[i + 1] - times[i]
            print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

Here's a sample of how my input file looks.

input23 13:13:05.674430
input47 13:13:06.623822
input52 13:13:07.573215
input66 13:13:08.522607

Any help is appreciated because I'm really stuck here! Thanks

Upvotes: 3

Views: 2383

Answers (1)

blubberdiblub
blubberdiblub

Reputation: 4135

Why are you splitting what row[1] returns? That's just one timestamp and you're making a list of one item from it.

Then, in the list comprehension, you're iterating over that list with one timestamp and make a list of one datetime instance from it.

Note that len(times) at that point is 1. So when doing for i in range(len(times) - 1), you're effectively iterating over range(0), which is an empty list.

What you actually want is to have the second for loop outside of the first. Or even better, replace the whole first for row in reader: loop with a simpler list comprehension, like so:

reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]

for i in range(len(times) - 1):
    delta = times[i + 1] - times[i]
    print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

If you want to, you can improve the remaining for loop by replacing range() and the indexing by iterating over pairs of a datetime instance and its successor by zip()ing up the list with a version of itself shifted by one place, which is arguably a wee bit more readable and pythonic:

reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]

for time1, time2 in zip(times, times[1:]):
    delta = time2 - time1
    print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

As J.F. Sebastian notes, you can get the total number of milliseconds a lot easier from the timedelta by using total_seconds() instead of combining all 3 components manually. Since that already returns a result with microsecond resolution (it's a float), you just need to multiply by 1000 to get milliseconds. If you want or don't mind the fractional part, you're done, otherwise you need to round() and/or convert to int():

    print(delta.total_seconds() * 1000)

or

    print(int(delta.total_seconds() * 1000))

Upvotes: 1

Related Questions