Aligning out-of-sync subtitles

This is my 2nd program I wrote on my own, a pretty simple program consisting of two functions (those functions are not combined in any way yet though). The first function moves the display times of subtitles saved in .srt files by a specified amount of time.

The second function "warps" the display times by a specified multiplier to fix subtitles written on the base of sped up/slowed down versions of the video(which results in the subtitles syncing out after some time).

Everything works fine and as intended, but I'm pretty certain there are things I could have done more optimally.

For starters, the argument input could be improved, so that you can just input "+20" instead of "+20:00,000" to shift the subtitles by 20 seconds.

That's pretty much the only problem I can come up that I don't know how to solve right now. Of course there are probably more problems with the code I can't spot yet, so any input is appreciated.

import re; import datetime; import time

def timeChangeSRT(n, s):
t = time.time()
f, new = open(n, 'r'), open('new' + n, 'w')
offset = re.search('([\+\-])?((\d{1,2})\:)?(\d+)(\,(\d{1,3}))?', s)
offset = datetime.timedelta(minutes=int(s[1:3]), seconds=int(s[4:6]), milliseconds=int(s[7:10]))

for line in f:
parsed = re.search('(\d{2}:\d{2}:\d{2}.\d{3}) \-\-> (\d{2}:\d{2}:\d{2}.\d{3})', line)
if parsed:
start = datetime.timedelta(minutes=int(parsed.group(1)[3:5]), \
seconds=int(parsed.group(1)[6:8]), \
milliseconds=int(parsed.group(1)[9:12]))
end = datetime.timedelta(minutes=int(parsed.group(2)[3:5]), \
seconds=int(parsed.group(2)[6:8]), \
milliseconds=int(parsed.group(2)[9:12]))
if '-' in s:
start -= offset
end -= offset
newline = '0' + str(start)[:11] + " --> " + '0' + str(end)[:11] + '\n'
new.write(newline)
else:
start += offset
end += offset
newline = '0' + str(start)[:11] + " --> " + '0' + str(end)[:11] + '\n'
new.write(newline)

else:
new.write(line)
stop = time.time() - t
print('The %s file has been updated. New .srt file named %s has been created. The process took %s seconds.' % (n, 'new' + n, stop))

def warpSRT(n, w):
t = time.time()
f, new = open(n, 'r'), open('new' + n, 'w')
offset = w
for line in f:
parsed = re.search('(\d{2}:\d{2}:\d{2}.\d{3}) \-\-> (\d{2}:\d{2}:\d{2}.\d{3})', line)
if parsed:
start = datetime.timedelta(minutes=int(parsed.group(1)[3:5]), \
seconds=int(parsed.group(1)[6:8]), \
milliseconds=int(parsed.group(1)[9:12]))
end = datetime.timedelta(minutes=int(parsed.group(2)[3:5]), \
seconds=int(parsed.group(2)[6:8]), \
milliseconds=int(parsed.group(2)[9:12]))
start *= offset
end *= offset
newline = '0' + str(start)[:11] + " --> " + '0' + str(end)[:11] + '\n'
new.write(newline)

else:
new.write(line)
stop = time.time() - t
print('The %s file has been updated. New .srt file named %s has been created. The process took %s seconds.' % (n, 'new' + n, stop))


• At the top of your file you put all of your imports in one line, but from PEP8:

Imports should usually be on separate lines

• You define offset, but the next line you define it again. That makes the first definition completely useless.

• timeChangeSRT() should not be splitting up a string to get the right minutes, seconds, and milliseconds. Those should be passed as arguments.

• Those backslashes at the end of the lines are useless. The indentation tells the reader, and the unclosed parentheses tells the interpreter.

• You have two lines that are used both in the if and in the else blocks (the definition of newline and writing it to new). That is a sign that they should be outside of the blocks and executed just afterwards.

• Instead of using newline = '0' + str(start)[:11] + " --> " + '0'..., use a format string: newline = '0{} --> 0{}\n'.format(str(start)[:11], str(end)[:11])

• You use old-style string formatting, but from the docs on .format() from Python2:

This method of string formatting is the new standard in Python 3, and should be preferred to the % formatting described in String Formatting Operations in new code.

Your second function pretty much needs the same modifications as the first. Your second function, in fact, is so similar to the first that I am sure you could define some helper functions to do some of the work so as to reduce the duplicate code.