Reading and comparing lines in a file using Python
I have a file of the following format.
15/07/2010 14:14:13 changed_status_from_Offline_to_Available
15/07/2010 15:01:09 changed_status_from_Available_to_Offline
15/07/2010 15:15:35 changed_status_from_Offline_to_Away became_idle
15/07/2010 15:16:29 changed_status_from_Away_to_Available became_unidle
15/07/2010 15:45:40 changed_status_from_Available_to_Away became_idle
15/07/2010 16:05:40 changed_status_from_Away_to_Available became_unidle
15/07/2010 16:51:39 changed_status_from_Available_to_Offline
20/07/2010 13:07:26 changed_status_from_Offline_to_Available
I need to create a function in python that has to arguments: date and time. It should read the file and return the second status if the date matches and time is less than the time in the function ca开发者_开发知识库ll. That is
Lets say i call the function returnstatus(15/07/2010, 15:10:01). The function should go to the file and return the status of the user on that day at that time, which in this case is "Offline".
I am a Python newbie and any help would be really appreciated.
import datetime
import time
def lines( path_to_file ):
'''Open path_to_file and read the lines one at a time, yielding tuples
( date of line, time of line, status before line )'''
with open( path_to_file ) as theFile:
for line in theFile:
line = line.rsplit( " ", 1 )
yield (
datetime.datetime.strptime( line[ 0 ], "%d/%m/%Y %H:%M:%S" ),
line[ 1 ].split( "_" )[ 3 ]
)
def return_status( statDate ):
for lineDate, lineStatus in lines( path_to_file ):
if statDate > lineDate:
continue
return lineStatus
Does that make sense, or would you like me to explain any of it?
Edit
Did you mean what you said above?
date matches and time is less than the time in the function call
In other words, what should happen if you call return_status( 16/07/2010, <some.time> )
? Should you get "Offline"?
Another Edit
I have edited it to do sensible datetime
comparisons. I think you have read the inequality the wrong way around: we loop through lines in the file until the first line after the date we wish to fetch (keep reading while statDate > lineDate
). Once this test fails, line
is the first line after the desired date, so its from
value is the status at the time we requested. You should call the function with a datetime.datetime
.
I suggest you have a read in the python docs, specifically the time module and the function strptime which can parse textual representation of times into a programmatic representation.
Calling returnstatus
the way you wrote in the question will surely fail, you might want to call it with a string representation of the time (i.e. "15/07/2010 15:10:01") or by passing one of the datatypes defined in the time module.
EDIT: obviously if you pass in a string time then finding it in the file is much easier:
if substring in line:
# do stuff
As Yoni said, you're probably better served by passing a string argument (if you have one). You may also find the types in datetime useful. You'll also want to look into the split function.
Basically, what you need to do is pull out the dates and times from your log into a easy-to-compare format. Enter datetime
.
import datetime
def getStatus(log_list, dt, tm):
#filter the list
log_list = [a_log_entry for a_log_entry in log_list if a_log_entry[0] == dt and a_log_entry[1] <= tm]
#sort it
log_list.sort(cmp=lambda x,y: cmp(x[1], y[1]))
if log_list is []:
return 'No status available for this day and time.'
#pull out the status
status_to_return = log_list[-1][2].split('_')[-1].strip()
return status_to_return
if __name__ == '__main__':
in_file = open('a.log', 'rU')
a_list = []
for line in in_file:
if line.strip() is not '': #handle whitespace
a_list.append(line.split(' '))
#convert string dates and times to datetime objects
a_list = [ [datetime.datetime.strptime(el[0], '%d/%m/%Y'),
datetime.datetime.strptime(el[1], '%H:%M:%S'),
el[2]] for el in a_list]
a_date = datetime.datetime(2010, 7, 15)
a_time = datetime.datetime(1900, 1, 1, 16, 1, 0)
print getStatus(a_list, a_date, a_time)
Try this:
import datetime
filein = open("filein", "r")
class Status:
def __init__(self, date, time, status):
print date.split('/')
day, month, year = map(int, date.split('/'))
hour, minute, second = map(int, time.split(':'))
self.date_and_time = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
self.status = status
list = []
line = filein.readline().rstrip('\n')
while line != "":
print line
date, time, status = line.split(' ')[:3]
status = status.split('_')
status.reverse()
status = status[0]
status_it = Status(date=date, time=time, status=status)
line = filein.readline().rstrip('\n')
list.append(status_it)
def query (date, time):
day, month, year = map(int, date.split('/'))
hour, minute, second = map(int, time.split(':'))
date_and_time = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
for counter, it in enumerate(list):
if date_and_time >= it.date_and_time and (date_and_time < list[counter + 1].date_and_time or counter == len(list) - 1):
print it.status
return
print "I don't know the status"
query("15/07/2010", "15:10:01")
From the question user392409 most probably wants to pass the parameters as string
and wants a single function.
Lets say i call the function returnstatus(15/07/2010, 15:10:01). The function should go to the file and return the status of the user on that day at that time, which in this case is "Offline".
import datetime
import time
def returnstatus(d, t):
d = datetime.datetime.strptime(d, "%d/%m/%Y")
t = time.strptime(t, "%H:%M:%S")
f = open("log.txt")
for line in f:
line = line.split(" ")
line_date = datetime.datetime.strptime(line[0], "%d/%m/%Y")
line_time = time.strptime(line[1], "%H:%M:%S")
if d != line_date and t >= line_time:
continue
# Returns the first occurrence. To get all store in a list or print.
f.close()
return line[2].split("_")[3]
精彩评论