Esempio n. 1
0
    def refresh(self):
        self.isEmpty = True
        self.history = None
        self.category = None
        self.rcInterp = set()
        self.rcNumTime = set()

        self.search.SelectAll()
        wx.CallAfter(self.Refresh)

        race = Model.race
        if race is None:
            self.clearGrid()
            return

        lastGridX, lastGridY = self.grid.GetViewStart()

        highPrecision = Model.highPrecisionTimes()

        if highPrecision or race.isTimeTrial:
            formatTime = lambda t: Utils.formatTime(t, True)
            formatTimeDiff = lambda a, b: Utils.formatTimeGap(
                TimeDifference(a, b, True), True)
        else:
            formatTime = Utils.formatTime
            formatTimeDiff = lambda a, b: Utils.formatTimeGap(
                TimeDifference(a, b, False), False)

        category = FixCategories(self.categoryChoice,
                                 getattr(race, 'historyCategory', 0),
                                 doSyncCategories=self.sync.GetValue())
        self.hbs.Layout()

        Finisher = Model.Rider.Finisher
        results = GetResults(category)
        lapsDown = {
            rr.num: rr.gap
            for rr in results if unicode(rr.gap).startswith('-')
        }
        position = {
            rr.num: pos
            for pos, rr in enumerate(results, 1) if rr.status == Finisher
        }
        winnerLaps = None
        if results and results[0].status == Finisher:
            winnerLaps = results[0].laps

        maxLaps = 0
        doLapsToGo = True
        if race.winAndOut:
            entries = GetEntries(category)
            if entries:
                try:
                    maxLaps = max(e.lap for e in entries if not e.interp)
                except ValueError:
                    pass
                if race.isRunning():
                    maxLaps += 2
        else:
            try:
                maxLaps = race.getNumLapsFromCategory(category)
            except Exception as e:
                maxLaps = race.numLaps
            doLapsToGo = True
            if not maxLaps:
                maxLaps = race.getMaxLap()
                if race.isRunning():
                    maxLaps += 2
                doLapsToGo = False

        entries = GetEntries(category)
        if maxLaps:
            entries = [e for e in entries if e.lap <= maxLaps]
        entries = [
            e for e in entries if e.lap <= race.getCategoryNumLaps(e.num)
        ]

        if race.isTimeTrial:
            entries = [
                Model.Entry(e.num, e.lap,
                            (race.riders[e.num].firstTime or 0.0) + e.t,
                            e.interp) for e in entries
            ]
            entries.sort(key=operator.attrgetter('t', 'num'))

        # Collect the number and times for all entries so we can compute lap times.
        numTimes = {(e.num, e.lap): e.t for e in entries}

        self.category = category

        # Trim out the lap 0 starts.
        entries = [e for e in entries if e.lap > 0]

        if not entries:
            self.clearGrid()
            return

        # Organize all the entries into a grid as we would like to see them.
        self.history = [[]]
        numSeen = set()
        lapCur = 0
        leaderTimes = [entries[0].t]
        for e in entries:
            if e.num in numSeen:
                numSeen.clear()
                lapCur += 1
                self.history.append([])
                leaderTimes.append(e.t)
            self.history[lapCur].append(e)
            numSeen.add(e.num)

        if not any(h for h in self.history):
            self.clearGrid()
            return

        # Show the values.
        self.isEmpty = False

        numTimeInfo = race.numTimeInfo

        colnames = []
        raceTime = 0
        for c, h in enumerate(self.history):
            try:
                lapTime = h[0].t - raceTime
                raceTime = h[0].t
            except IndexError as e:
                lapTime = 0

            colnames.append('{}\n{}\n{}\n{}'.format(
                c + 1, (maxLaps - c - 1) if doLapsToGo else ' ',
                formatTime(lapTime), formatTime(raceTime)))

        formatStr = ['$num']
        if self.showTimes: formatStr.append(', $raceTime')
        if self.showLapTimes: formatStr.append(', $lapTime')
        if self.showTimeDown: formatStr.append(', $downTime')
        if self.showRiderName: formatStr.append(', $riderName')
        template = Template(u''.join(formatStr))

        try:
            info = race.excelLink.read()
        except:
            info = {}

        def getName(num):
            d = info.get(num, {})
            return u', '.join(
                v for v in [d.get('LastName', None),
                            d.get('FirstName', None)] if v)

        templateSave = template
        data = []
        for col, h in enumerate(self.history):
            template = templateSave
            if col + 1 == winnerLaps:
                if self.showPosition:
                    formatStr.insert(0, '$pos$lapsDown: ')
                template = Template(u''.join(formatStr))

            data.append([
                template.safe_substitute({
                    'num':
                    e.num,
                    'pos':
                    Utils.ordinal(position.get(e.num, '')),
                    'lapsDown':
                    u' ({})'.format(lapsDown[e.num])
                    if e.num in lapsDown else u'',
                    'raceTime':
                    formatTime(e.t) if self.showTimes else '',
                    'lapTime':
                    formatTime(e.t - numTimes[(e.num, e.lap - 1)])
                    if self.showLapTimes and
                    (e.num, e.lap - 1) in numTimes else '',
                    'downTime':
                    formatTimeDiff(e.t, leaderTimes[col])
                    if self.showTimeDown and col < len(leaderTimes) else '',
                    'riderName':
                    getName(e.num) if self.showRiderName else '',
                }) for e in h
            ])
            self.rcInterp.update(
                (row, col) for row, e in enumerate(h) if e.interp)
            self.rcNumTime.update(
                (row, col) for row, e in enumerate(h)
                if numTimeInfo.getInfo(e.num, e.t) is not None)

        self.grid.Set(data=data, colnames=colnames)
        self.grid.AutoSizeColumns(True)
        self.grid.Reset()
        self.updateColours()
        self.grid.Set(textColour=self.textColour,
                      backgroundColour=self.backgroundColour)

        # Fix the grid's scrollbars.
        self.grid.FitInside()
        self.grid.Scroll(lastGridX, lastGridY)
Esempio n. 2
0
def GetSituationGaps( category=None, t=None ):
	race = Model.race
	if not race:
		return []
	
	if t is None:
		t = race.lastRaceTime() if not race.isRunning() else (datetime.datetime.now() - race.startTime).total_seconds()
	
	# Collect the race times from the results data.
	Finisher = Model.Rider.Finisher
	raceTimes, riderName = {}, {}
	for rr in GetResults(category):
		if not (rr.raceTimes and len(rr.raceTimes) >= 2) or rr._lastTimeOrig < t:
			continue
			
		raceTimes[rr.num] = rr.raceTimes
		riderName[rr.num] = rr.short_name(15)

	if not raceTimes:
		return []
	
	t = min( t, max(rt[-1] for rt in six.itervalues(raceTimes)) )
	
	psLeader = (-1, -1, None)
	positionSpeeds = []
	for bib, rt in six.iteritems(raceTimes):
		position, speed = GetPositionSpeed(t, rt)
		positionSpeeds.append( (position, speed, bib) )
		if positionSpeeds[-1][0] > psLeader[0]:
			psLeader = positionSpeeds[-1]
	
	leaderPosition, leaderSpeed, leaderRaceTimes = psLeader[0], psLeader[1], raceTimes[psLeader[2]]
	
	try:
		externalInfo = race.excelLink.read()
	except:
		externalInfo = {}
	
	def getInfo( bib, lapsDown ):
		name = riderName[bib]
		nameStr = u'' if not name else u' ' + name
		if lapsDown:
			lapsDownStr = u' ({})'.format(lapsDown)
			bibStr = u'\u2198{}'.format(bib)
		else:
			lapsDownStr = u''
			bibStr = six.text_type(bib)
		return u''.join([bibStr, nameStr, lapsDownStr])
	
	gaps = []
	for riderPosition, riderSpeed, bib in positionSpeeds:
		try:
			gap, lapsDown = GetLeaderGap( t,
				leaderPosition, leaderSpeed, leaderRaceTimes,
				riderPosition, riderSpeed, raceTimes[bib]
			)
		except TypeError:
			continue
		if gap is not None:
			gaps.append( (gap, getInfo(bib, lapsDown)) )
			
	gaps.sort()
	
	if gaps:
		gapMin = gaps[0][0]
		gaps = [[TimeDifference(g[0], gapMin), g[1]] for g in gaps]
	thisLap = GetLapLE(t, leaderRaceTimes)
	
	tCur = t
	tClock = race.raceTimeToClockTime( tCur )
	tETA = leaderRaceTimes[thisLap+1] - t if thisLap+1 != len(leaderRaceTimes) else None
	tAfterLeader = t - leaderRaceTimes[thisLap]
	laps = len(leaderRaceTimes) - 1
	lap = min( thisLap + 1, laps )
	lapsToGo = max(laps - lap, 0)
	
	title =  u'   {}: {}/{}   {}: {}'.format(
		_('Lap'), lap, laps,
		_('Laps to go'), lapsToGo,
	)
	if tCur is not None:
		title += u'    {}: {}'.format(_('Race'), Utils.formatTime(tCur))
	if tClock is not None:
		if title:
			title += u'   {}: {}'.format(_('Clock'), Utils.formatTime(tClock))
	if tETA is not None:
		title += u'   {}: {}'.format(_('Leader ETA'), Utils.formatTime(tETA))
	
	return gaps, tAfterLeader, title, tCur