def listDoctorForExport(params):
    output = None
    result = DB.searchByParams(params)
    curInterval = ''
    curDate = ''
    lastNumber = ''
    segment = {}
    printTitle = True

    for row in result:
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        name        = row[2]
        dept        = row[3]
        room        = row[4]
        interval    = row[5]
        if row[6] != '{"over":true}':
            continue
        curnumber   = row[7]
        start       = datetime.datetime.fromtimestamp( int(row[8]) ).strftime('%H:%M:%S')
        duration    = transfer_minute(row[10])

        if output == None:
            line = '%s/%s-%s.txt' % (params['filePath'], dept, name)
            output = open(line, 'w')

        if printTitle == True:
            curInterval = interval
            curDate = date
            line = '%s (%d)\t%s\t%s\t%s' % (date, week, unicode(name), unicode(dept), unicode(interval))
            output.write(line.encode('utf-8') + '\n')
            printTitle = False

        if curInterval == interval and curDate == date:
            # segment[int(curnumber)] = start
            # lastNumber = curnumber
            # print '%s %s' % (curnumber, start)
            if row[6] == '{"over":true}':
                output.write('%d (over)\t%s\n' % (curnumber, start))
            else:
                output.write('%d\t%s\n' % (curnumber, start))
        else:
            printTitle = True
        # else:
        #     for i in range(1, int(lastNumber)):
        #         if i not in segment:
        #             segment[i] = ''
        #         output.write('%d\t%s\n' % (i, segment[i]))
        #     output.write('\n')
        #     segment = {}

    # for i in range(1, int(lastNumber)):
    #     if i not in segment:
    #         segment[i] = ''
    #     output.write('%d\t%s\n' % (i, segment[i]))
    if output != None:
        output.close()
def calculate(config):
    data = {}
    data['name'] = '林永國'
    result = DB.searchByParams(data)
    today = ''
    totalGap = 0
    lastNumber = 0
    count = 0
    gap = 0

    totalDelta = 0
    deltaCount = 0

    for row in result:
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        name        = row[2]
        dept        = row[3]
        room        = row[4]
        interval    = row[5]
        curnumber   = row[7]
        start       = datetime.datetime.fromtimestamp( int(row[8]) ).strftime('%H:%M:%S')
        duration    = row[10]

        if week != 4:
            continue

        if row[6] == '{"over":true}':
            continue

        if '' == today:
            today = date
        elif date != today:
            today = date
            # print 'totalGap: %d, count: %d, average gap: %.3f\n' % (totalGap, count, math.ceil((float)(totalGap)/count))
            totalGap = 0
            lastNumber = 0
            count = 0
            gap = 0

        if duration < 50:
            continue

        if lastNumber == 0:
            lastNumber = curnumber
            continue
        else:
            gap = curnumber - lastNumber
            totalGap += gap
            count += 1
            lastNumber = curnumber

        if curnumber == config:
            totalDelta += (float)(duration/gap)
            deltaCount += 1
            print '%s(%s)\t%s\t%d\t%d,\t\tgap:\t%s,\tdelta:\t%.3f' % (date, week, name, curnumber, duration, gap, (float)(duration)/gap)
def listDoctor(params):
    result = DB.searchByParams(params)
    for row in result:
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        if 'weekday' in params:
            if int(params['weekday']) != week:
                continue
        name        = row[2]
        dept        = row[3]
        room        = row[4]
        interval    = row[5]
        if row[6] == '{"over":true}':
            comment = "(PASS)"
        else:
            comment = '\t'
        curnumber   = row[7]
        start       = datetime.datetime.fromtimestamp( int(row[8]) ).strftime('%Y-%m-%d %H:%M:%S')
        duration    = transfer_minute(row[10])

        line = '%s (%d)\t%s\t%s\t%s\t%s%s\t%s\t%s' % (date, week, unicode(name), unicode(dept), unicode(interval), two_digit_number(curnumber), comment, start, duration)
        print line
def getDoctorWeekAverageStd(docName, numberRange):
    result = DB.searchByParams({'name':docName})

    weekDurations = {1:[], 2:[], 3:[], 4:[], 5:[], 6:[], 7:[]}
    weekSum = {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}
    weekCount = {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}

    lastInterval = ''
    lastday = ''
    lastweek = 0
    timeList = []

    for row in result:
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(row[1], '%Y-%m-%d').weekday() + 1
        interval    = row[5]

        if row[6] == '{"over":true}':
            continue

        duration = row[10]
        if duration < 50:
            continue

        if numberRange.getHigh(week) != 0 and duration > numberRange.getHigh(week):
            continue
        if numberRange.getLow(week) > duration:
            continue

        if lastday != date or lastInterval != interval:
            # print '==========%s(%s)===========' % (lastday, lastweek)
            timeList = sorted(timeList)
            length = len(timeList)
            percent = int(length * 0.15)

            for i in range(0,percent):
                timeList.pop()
                timeList.pop(0)

            for i in timeList:
                weekDurations[lastweek].append(i)
                weekSum[lastweek] += i
                weekCount[lastweek] += 1

            lastday = date
            lastweek = week
            lastInterval = interval
            timeList = []

        timeList.append(duration)

    #     weekDurations[week].append(duration)
    #     weekSum[week] += duration
    #     weekCount[week] += 1

    # for i in range(1,8):
    #     tempList = sorted(weekDurations[i])
    #     length = len(tempList)
    #     percent = length / 10

    #     for j in range(0,percent):
    #         tempList.pop()
    #         tempList.pop(0)

    #     weekDurations[i] = tempList
    #     weekCount[i] = len(tempList)
    #     weekSum[i] = 0
    #     for j in tempList:
    #         weekSum[i] += j

    weekAverage = {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}
    weekSTD = {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}
    for week in range(1,8):
        if weekCount[week] == 0:
            continue
        weekAverage[week] = weekSum[week]/weekCount[week]
        weekSTD[week] = numpy.std(weekDurations[week])
        # print 'week %d: average: %d, STD: %d' % (week, weekAverage[week], weekSTD[week])
    return NumberRange(weekAverage, weekSTD, weekCount)
def generateData(doctorName):
    result = DB.searchByParams({'name':doctorName})

    today = None
    lastNumber = None
    lastStartTime = None
    lastInterval = None
    lastweek = None

    recordNumber = None
    increaseTimeList = None
    weeksData = {1:{}, 2:{}, 3:{}, 4:{}, 5:{}, 6:{}, 7:{}}

    breakFlag = False

    debugFile = open('debug.txt', 'a')

    for row in result:
        # use struct data instead of
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        interval    = row[5]
        curNumber   = row[7]
        start       = int(row[8])
        duration    = row[10]

        line = '%s %s %s(%d) %s %s %s' % (doctorName, interval, date, week, curNumber, datetime.datetime.fromtimestamp( start ).strftime('%H:%M:%S'), duration)
        debugFile.write(line.encode('utf-8') + '\n')

        # remove data
        if row[6] == '{"over":true}':
            continue
        if duration < 50:
            continue

        if today != date or lastInterval != interval:
            if lastweek != None:
                if today not in weeksData[lastweek]:
                     weeksData[lastweek][today] = {}
                if lastInterval.encode('utf-8') == '上午診':
                    name_interval = 'morning'
                elif lastInterval.encode('utf-8') == '下午診':
                    name_interval = 'afternoon'
                else:
                    name_interval = 'night'                    
                weeksData[lastweek][today][name_interval] = increaseTimeList
            today = date
            lastInterval = interval
            lastNumber = curNumber
            lastStartTime = start
            lastweek = week
            recordNumber = 1
            increaseTimeList = {}
            continue

        timeDiff = start - lastStartTime
        numberDiff = curNumber - lastNumber
        if numberDiff==0:
            breakFlag = True
            break
        increaseTime = (float) (timeDiff) / numberDiff;
        for i in range(recordNumber, curNumber+1):
            increaseTimeList[i] = increaseTime
        recordNumber = curNumber

        lastNumber = curNumber
        lastStartTime = start

    ###test

    if breakFlag==False:
        f = open('temp/%s.txt' % doctorName, 'w')
        for k in range(1,8):
            store_n = {"morning":{}, "afternoon":{},"night":{}}
            #f.write("=====(%d)======\n" %k)
#            for k in range(len(weeksData[lastweek][today]))
            for i in weeksData[k]:
                for interval in weeksData[k][i]:
                    for j in weeksData[k][i][interval]:
                        if j not in store_n[interval] :
                            store_n[interval][j] = []
                            store_n[interval][j].append(weeksData[k][i][interval][j]) 
                        else:
                            store_n[interval][j].append(weeksData[k][i][interval][j]) 
            #print(store_n)
            for inn in store_n:
                f.write("=====(%d %s)======\n" %(k,inn))
                for num in range(len(store_n[inn])):
                    #print (num+1, len(store_n[inn][num+1]))
                    store_n[inn][num+1].sort()
                    size_num = len(store_n[inn][num+1])
                    f.write('%d\t%.2f\t%d\t%s\n' %(num+1,store_n[inn][num+1][int(size_num/2)], size_num,inn))
        f.close()
    debugFile.close()
    def __init__(self, params):

        result = DB.searchByParams(params)
        # self.__doctorName = params['name'].encode('utf-8').decode('utf-8')
        self.__doctorName = params['name']
        lastDate = None
        lastShift = None
        lastRegularNumber = 0
        order = 1
        passedCount = 0

        for row in result:
            # DB row 1:Date, 2:Name, 3:Dept, 4:Room, 5:shift, 6:Comment, 7:CurNumber, 8:time, 9:End, 10:Duration
            curDate = unicode(row[1])
            curWeekday = datetime.datetime.strptime(curDate, '%Y-%m-%d').weekday() + 1
            curName = row[2].encode('utf-8').decode('utf-8')
            curDept = row[3]
            curShift = row[5].encode('utf-8').decode('utf-8')
            # Problematic flag for passed patients, deprecated in favor of simple decreasing number judging
            # if row[6] != '{"over":true}':
            #    continue
            curNumber = int(row[7])
            # TODO: 用字串處理的方法似乎會慢很多
            curDatetime = datetime.datetime.fromtimestamp(int(row[8]))
            curTime = curDatetime.strftime('%H:%M:%S')
            # 這不是真正計算時使用的調整過的等效duration
            durationSeconds = row[10]

            if not (curWeekday == 6 and curShift == u'上午診'):
                continue

            # TODO: 把後一號(後幾號)都解釋成過號,篩掉太短duration的
            ####### WHAT TO DO WITH THESE GUYS WHO JUST WON'T LEAVE!!??? (Some of them with good reasons maybe)
            if self.__number_came(curDate, curShift, curNumber):
                continue
            # TODO: Duration的篩選要切在多少?
            if durationSeconds < 30:
                continue

            if curShift != lastShift or curDate != lastDate:
                lastShift = curShift
                lastDate = curDate
                lastRegularNumber = 0
                order = 1
                passedCount = 0

            #PASSED patients:
            #if row[6] == '{"over":true}': # <== This is problematic. Some times patients were skipped too fast that regular patient would be viewed as passed by system
            if curNumber < lastRegularNumber:
                passedCount -= 1
                patient = {'number': curNumber, 'date': curDate.encode('utf-8'), 'time': curTime.encode('utf-8'), 'shift': curShift.encode('utf-8'), 'order': order, 'isPassed': 1, 'passedCount': passedCount}
                # self.__session_append(curDate, curShift, patient)
                ModelBuilder.dict_append_leaf(patient, self.__sessionData, curDate, curShift)

            # REGULAR patients:
            else:
                numDiff = curNumber - lastRegularNumber
                passedCount += numDiff - 1
                lastRegularNumber = curNumber
                patient = {'number': curNumber, 'date': curDate.encode('utf-8'), 'time': curTime.encode('utf-8'), 'shift': curShift.encode('utf-8'), 'order': order, 'isPassed': 0, 'passedCount': passedCount}
                # self.__session_append(curDate, curShift, patient)
                ModelBuilder.dict_append_leaf(patient, self.__sessionData, curDate, curShift)

            # answerTime[Date][shift][number] = answer in timeSeconds
            ModelBuilder.dict_update_recursive(self.__answerTime, {curDate: {curShift: {curNumber: timestamp_to_sec(curTime)}}})

            # End of iteration preparation
            order += 1

        for curDate, branch in self.__sessionData.items():
            for curShift, patients in branch.items():
                curWeekday = datetime.datetime.strptime(curDate, '%Y-%m-%d').weekday() + 1
                lastRegularNumber = 0

                localMaxNumber = max(patients, key=lambda p:p['number'])['number']
                self.__numberCount += localMaxNumber
                self.__orderCount += len(patients)

                for i in range(1, len(patients)):
                    curHour = int(patients[i - 1]['time'].split(':')[0])
                    curDuration = timestamp_to_sec(patients[i]['time']) - timestamp_to_sec(patients[i - 1]['time'])
                    patients[i - 1]['duration'] = curDuration
                    self.__durationSum += curDuration
                    ModelBuilder.dict_append_leaf(curDuration, self.__durationPool, curWeekday, curShift, patients[i - 1]['number'])
                    # try:
                    #     self.__durationPool[curWeekday][curShift][patients[i - 1]['number']].append(curDuration)
                    # except KeyError:
                    #     branch = {curWeekday: {curShift: {patients[i - 1]['number']: [curDuration]}}}
                    #     ModelBuilder.dict_update_recursive(self.__durationPool, branch)

                    if patients[i - 1]['isPassed'] == 1:
                        try:
                            self.__recoverProb[curWeekday][curShift][curHour]['appeared'] += 1
                            self.__recoverProb[curWeekday][curShift][curHour]['denominator'] += patients[i - 1]['passedCount'] * curDuration
                        except KeyError:
                            branch = {curWeekday: {curShift: {curHour: {'appeared': 1, 'denominator': patients[i - 1]['passedCount'] * curDuration}}}}
                            ModelBuilder.dict_update_recursive(self.__recoverProb, branch)
                    elif patients[i - 1]['isPassed'] == 0:
                        numDiff = patients[i - 1]['number'] - lastRegularNumber
                        try:
                            self.__passProb[curWeekday][curShift][curHour]['pass'] += numDiff - 1
                            self.__passProb[curWeekday][curShift][curHour]['total'] += numDiff
                        except KeyError:
                            branch = {curWeekday: {curShift: {curHour: {'pass': numDiff - 1, 'total': numDiff}}}}
                            ModelBuilder.dict_update_recursive(self.__passProb, branch)
                        try:
                            self.__recoverProb[curWeekday][curShift][curHour]['denominator'] += patients[i - 1]['passedCount'] * curDuration
                        except KeyError:
                            branch = {curWeekday: {curShift: {curHour: {'appeared': 0, 'denominator': patients[i - 1]['passedCount'] * curDuration}}}}
                            ModelBuilder.dict_update_recursive(self.__recoverProb, branch)
                        lastRegularNumber = patients[i - 1]['number']
        self.__boring_model_init(result)
Beispiel #7
0
def generateData(doctorName):
    result = DB.searchByParams({'name':doctorName})

    today = None
    lastNumber = None
    lastStartTime = None
    lastInterval = None
    lastweek = None

    recordNumber = None
    increaseTimeList = None
    weeksData = {1:{}, 2:{}, 3:{}, 4:{}, 5:{}, 6:{}, 7:{}}

    breakFlag = False

    debugFile = open('debug.txt', 'a')

    for row in result:
        # use struct data instead of
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = row[1]
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        interval    = row[5]
        curNumber   = row[7]
        start       = int(row[8])
        duration    = row[10]

        line = '%s %s %s(%d) %s %s %s' % (doctorName, interval, date, week, curNumber, datetime.datetime.fromtimestamp( start ).strftime('%H:%M:%S'), duration)
        debugFile.write(line.encode('utf-8') + '\n')

        # remove data
        if row[6] == '{"over":true}':
            continue
        if duration < 50:
            continue

        if today != date or lastInterval != interval:
            if lastweek != None:
                weeksData[lastweek][today] = increaseTimeList
            today = date
            lastInterval = interval
            lastNumber = curNumber
            lastStartTime = start
            lastweek = week
            recordNumber = 1
            increaseTimeList = {}
            continue

        timeDiff = start - lastStartTime
        numberDiff = curNumber - lastNumber
        if numberDiff==0:
            breakFlag = True
            break
        increaseTime = (float) (timeDiff) / numberDiff;
        for i in range(recordNumber, curNumber+1):
            increaseTimeList[i] = increaseTime
        recordNumber = curNumber

        lastNumber = curNumber
        lastStartTime = start

    if breakFlag==False:
        f = open('temp/%s.txt' % doctorName, 'w')
        for k in range(1,8):
            for i in weeksData[k]:
                f.write( "=====%s(%d)======\n" % (i, k) )
                for j in weeksData[k][i]:
                    f.write( '%d\t%.2f\n' % (j, weeksData[k][i][j]) )
        f.close()
    debugFile.close()
def listDoctorForOrderExport(params):
    #Exporting format:
    #number, date, time, interval, order(actual order meeting doctor), isPassed(whether the patient is late, 0 == False, 1 == True), passedCount(including missing ones), lateCount, lateOriginalOrder: 遲到者原本的Order, Duration, diffEst, Est

    output = None
    result = DB.searchByParams(params)
    curInterval = u''
    curDate = ''
    lastRegularStart = None #last start time datetime object
    lastRegularNumber = 0
    order = 1
    passedCount = 0
    curDate = ''
    curInterval = ''
    signBook = [] #record the number that did came to the doctor
    lateSignBook = {} #record the passed patients' original order
    sessionData = []
    summary = []
    peopleSeconds = 0 #record the people*seconds of passed patients, as the denominator for the frequeny of late person showing up
    totalPassedCount = 0
    durationSum = 0 #As the denominator for calculating average session time
    # TODO: 應該要把每個Interval每一個小時都填上0或1
    #以每小時紀錄略過號碼的比例
    #Format: 診次:{小時:{pass:A, total:X}}
    passProbHour = {u'上午診':{}, u'下午診':{}, u'夜間診':{}}
    #以每小時紀錄遲到者出現的比例
    #Format: 診次:{小時:{appeared:A, denominator:X}}
    recoverProbHour = {u'上午診':{}, u'下午診':{}, u'夜間診':{}}

    #Signal as EOF
    result.append(['','1970-1-1','','','','','',0,0,0,0])

    for row in result:
        # Datetime, Name, Dept, Room, Interval, Comment, CurNumber, Start, End, Duration
        date        = unicode(row[1])
        week        = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() + 1
        #if week != 2:
        #    continue
        name        = row[2]
        dept        = row[3]
        room        = row[4]
        interval    = row[5]
        #if row[6] != '{"over":true}':
        #    continue
        number   = int(row[7])
        time = datetime.datetime.fromtimestamp(int(row[8]))
        start       = time.strftime('%H:%M:%S')
        duration    = transfer_minute(row[10])
        durationSeconds = row[10]

        if output == None:
            line = u'%s/%s-%s.txt' % (params['filePath'].encode('utf-8').decode('utf-8'), dept.encode('utf-8').decode('utf-8'), name.encode('utf-8').decode('utf-8'))
            output = open(line, 'w')
            output.write('number\tdate\ttime\tinterval\torder\tisPassed\tpassedCount\tlateCount\tlateOriginalOrder\tduration\n')

        #Initialization for each intervals, and the outputting of data when each interval is processed
        #1. Read everything into sessionData.
        #2. Add lateCount before processing the next interval
        if curInterval != interval or curDate != date:
            if len(signBook) > 0:
                lastRegularNumber = 0
                for i in range( 0 , len(sessionData)):
                    if i == 0:
                        lastLateCount = 0
                    else:
                        lastLateCount = sessionData[i-1]['lateCount']
                    if sessionData[i]['isPassed'] == 0:
                        delta = sessionData[i]['number'] - lastRegularNumber
                        if delta > 1:
                            for steps in range(1, delta):
                                index = sessionDataIndex(sessionData, 'number', sessionData[i]['number'] - steps)
                                if index != -1 and sessionData[index]['number'] in signBook:
                                   lastLateCount += 1
                        sessionData[i]['lateCount'] = lastLateCount
                        lastRegularNumber = sessionData[i]['number']
                    else:
                        sessionData[i]['lateCount'] = lastLateCount - 1
                for p in sessionData:
                    output.write('%d\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%s\n' % (p['number'] , p['date'] , p['start'] ,p['interval'] , p['order'] , p['isPassed'] , p['passedCount'], p['lateCount'], p['lateOriginalOrder'], p['duration']))

            if len(sessionData) > 1:
                summary.append([sessionData[len(sessionData)-1]['number'],sessionData[len(sessionData)-1]['passedCount']])

            if interval == '': # EOF
                break

            #Formatting the dictionary for each Interval
            sessionData = []
            signBook = []
            lateSignBook = {}
            curInterval = interval
            curDate = date
            lastRegularNumber = 0
            order = 1
            passedCount = 0
            lastRegularStart = None

        # TODO: 把後一號(後幾號)都解釋成過號,篩掉太短duration的
        if number in signBook:########### WHAT TO DO WITH THESE GUYS WHO JUST WON'T LEAVE!!??? (Some of them with good reasons maybe)###############
            continue

        #PASSED : decrease passedCount
        #if row[6] == '{"over":true}': # <== This is problematic. Some times patients were skipped too fast that regular patient would be viewed as passed by SYSTEM
        elif number < lastRegularNumber:
            passedCount -= 1
            if time.hour in recoverProbHour[interval]:
                recoverProbHour[interval][time.hour]['appeared'] += 1
                recoverProbHour[interval][time.hour]['denominator'] += passedCount * (time - lastRegularStart).total_seconds()
            else:
                recoverProbHour[interval][time.hour] = {'appeared': 1, 'denominator': passedCount * (time - lastRegularStart).total_seconds()}
            sessionData.append({'number':number,'date':date.encode('utf-8'),'start':start.encode('utf-8'),'interval':interval.encode('utf-8'),'order':order,'isPassed':1,'passedCount':passedCount,'lateCount':0, 'lateOriginalOrder':lateSignBook[number], 'duration':duration})

        #Regular: might encounter passing
        else:
            delta = number - lastRegularNumber
            passedCount += delta - 1
            if time.hour in passProbHour[interval]:
                passProbHour[interval][time.hour]['pass'] += delta -1
                passProbHour[interval][time.hour]['total'] += delta
            else:
                passProbHour[interval][time.hour] = {'pass':delta - 1, 'total': delta}
            if time.hour in recoverProbHour[interval] and passedCount > 0 and order > 1:
                recoverProbHour[interval][time.hour]['denominator'] += passedCount * (time - lastRegularStart).total_seconds()
            elif time.hour not in recoverProbHour[interval] and passedCount > 0 and order > 1:
                recoverProbHour[interval][time.hour] = {'appeared': 0, 'denominator': passedCount * (time - lastRegularStart).total_seconds()}
            for steps in range(1, delta):
                lateSignBook[number - steps] = order

            lastRegularNumber = number
            lastRegularStart = time
            sessionData.append({'number':number,'date':date.encode('utf-8'),'start':start.encode('utf-8'),'interval':interval.encode('utf-8'),'order':order,'isPassed':0,'passedCount':passedCount,'lateCount':0, 'lateOriginalOrder':0, 'duration':duration})

        signBook.append(number)
        order += 1
        peopleSeconds += sessionData[len(sessionData)-1]['passedCount'] * durationSeconds
        totalPassedCount += sessionData[len(sessionData)-1]['isPassed']
        durationSum += durationSeconds

    if output != None:
        output.close()

    #Estimating session time for patients with order > 10
    #Target: Whenever meeting a guy with order > skip+vision, and who was not a late patient, we trace back [vision] patients and try using the information back then to estimate his session time. This way we make sure we got the actual answer for on time patients, as we expected of the end-user.
    skipping = 0
    total = 0
    for p in summary:
        #output.write('%d\t%d\n' % (p[0], p[1]))
        skipping += p[1]
        total += p[0]
    averageTime = durationSum / total

    with open(line,'r+') as fp:
        content = fp.readlines()
        fp.seek(0)
        fp.truncate()
        #Write back the header from the input stream and adding another column for difference between estimation and acutal session time
        fp.write(content[0].rstrip() + '\tdiffForEst\test\n')

        #lastOrder = 0
        #lastDate = ''
        #lastInterval = ''
        lastRegularNumber = 0
        skip = 10 #How many patients skipped before start estimating
        vision = 10 #How far we are trying to estimate
        for i in range(1, len(content)):# Starting from 1 skipping the header
        #Column format: 0:number\1:date\2:time\3:interval\4:order\5:isPassed\6:passedCount\7:lateCount\8:lateOriginalOrder\9:duration\10:answer-etimation\11:estimation
            items = content[i].rstrip().split('\t')
            if int(items[4]) < skip + vision or int(items[5]) == 1:
                fp.write(content[i].rstrip() + '\tNA\tNA\n')
                continue
            else:
                j = i-vision
                pastItems = content[j].rstrip().split('\t')
                pastInterval = pastItems[3].decode('utf-8')
                pastHour = datetime.datetime.strptime(pastItems[2], '%H:%M:%S').hour
                try:
                    averageSkip = (float(passProbHour[pastInterval][pastHour]['pass']) / passProbHour[pastInterval][pastHour]['total'])
                    #其實這是計算完全消失的比例而非跳號的可能性,時間會高估。但是也可以說假設這些短期遲到的馬上都跑回來看了
                    reappearanceFrequency = float(recoverProbHour[pastInterval][pastHour]['appeared']) / recoverProbHour[pastInterval][pastHour]['denominator']
                except KeyError:
                    print 'KeyError, time=', pastItems[2], 'date=', pastItems[1], 'Keys are:', recoverProbHour[pastInterval].keys(), 'Interval is:', pastInterval
                    sys.stdout.flush()
                lastRegularNumber = int(pastItems[0])
                isPassed = int(pastItems[5])
                while isPassed == 1:#Finding the closest regular patient near the start of vision
                    j -= 1
                    backTraceItems = content[j].rstrip().split('\t')
                    isPassed = int(backTraceItems[5])
                    lastRegularNumber = int(backTraceItems[0])
                #預期準時扣掉會遲到的人
                estimatedRegular = math.floor((int(items[0]) - lastRegularNumber) * (1.0 - averageSkip))
                #預期已經遲到但是又會再出現的人
                estimatedReappearance = math.floor(int(pastItems[6]) * averageTime * estimatedRegular * reappearanceFrequency)
                estimation = (estimatedRegular + estimatedReappearance) * averageTime
                answer = (datetime.datetime.strptime(items[2], '%H:%M:%S') - datetime.datetime.strptime(pastItems[2],'%H:%M:%S')).total_seconds()
                diff = answer - estimation
                fp.write(content[i].rstrip() + '\t%d\t%d\n' % (diff, estimation))