Example #1
0
        private string GetStats(Rally rallyInfo)
        {
            var outputSb = new StringBuilder("Stats");

            outputSb.AppendLine(Environment.NewLine);

            // participation stats
            var driversFinished = rallyInfo.DriverCount - rallyInfo.DriversDnf;

            outputSb.AppendLine("Participation Stats");
            outputSb.AppendLine("Drivers Entered," + rallyInfo.DriverCount);
            outputSb.AppendLine("Drivers Finished," + (driversFinished));
            outputSb.AppendLine("Drivers DNFd," + rallyInfo.DriversDnf);
            outputSb.AppendLine(String.Format("Completion Rate,{0:P2}", ((double)driversFinished / rallyInfo.DriverCount)));

            // stage wins
            outputSb.AppendLine();
            outputSb.AppendLine("Stage Wins");
            var stageWinners = rallyInfo.DriverInfoDict.Values.Where(x => x.StagesWon != 0).OrderByDescending(x => x.StagesWon);

            foreach (var driverInfo in stageWinners)
            {
                outputSb.AppendLine(driverInfo.Name + "," + driverInfo.StagesWon);
            }

            // manufacturer count
            outputSb.AppendLine();
            outputSb.AppendLine("Manufacturer Count");
            var carCounts = rallyInfo.VehicleCounts.OrderByDescending(x => x.Value);

            foreach (var car in carCounts)
            {
                outputSb.AppendLine(car.Key + "," + car.Value);
            }

            return(outputSb.ToString());
        }
Example #2
0
        private string GetCsvChartOutput(Rally rallyData)
        {
            var positiveOutputSB = new StringBuilder("Chart Data").AppendLine();
            var negativeOutputSB = new StringBuilder("Negated Chart Data").AppendLine();
            var positionDict     = new Dictionary <string, List <int> >();
            List <KeyValuePair <string, DriverTime> > sortedStageData = null;

            foreach (Stage stage in rallyData)
            {
                sortedStageData = stage.DriverTimes.ToList();
                sortedStageData.OrderBy(x => x.Value.OverallPosition == 0).ThenBy(x => x.Value.OverallPosition);

                foreach (KeyValuePair <string, DriverTime> driverTimeKvp in sortedStageData)
                {
                    if (driverTimeKvp.Value == null)
                    {
                        continue;
                    }

                    var driverKey = driverTimeKvp.Key;
                    var position  = driverTimeKvp.Value.OverallPosition;

                    if (!positionDict.ContainsKey(driverKey))
                    {
                        positionDict.Add(driverKey, new List <int>());
                    }

                    positionDict[driverKey].Add(position);
                }
            }

            // sortedStageData should contain the last stage, sorted by overall position
            if (sortedStageData == null)
            {
                return(null);
            }

            // keep a list of positionList that contains zeros
            var dnfDict = new Dictionary <string, List <int> >();

            var driverList = rallyData.DriverInfoDict.Values.OrderBy(x => x.OverallPosition == 0).ThenBy(x => x.OverallPosition);

            foreach (var driver in driverList)
            {
                var positionList = positionDict[driver.Name];
                if (positionList.Contains(0))
                {
                    dnfDict.Add(driver.Name, positionList);
                    continue;
                }

                string posline = driver.Name + "," + String.Join(",", positionList);
                string negline = driver.Name + "," + String.Join(",", positionList.Select(x => x * -1));
                positiveOutputSB.AppendLine(posline);
                negativeOutputSB.AppendLine(negline);
            }

            // remove zeros from dnfList
            foreach (var positionList in dnfDict.Values)
            {
                positionList.RemoveAll(x => x == 0);
            }

            foreach (var driverKvp in dnfDict.OrderByDescending(x => x.Value.Count))
            {
                string posline = driverKvp.Key + "," + String.Join(",", driverKvp.Value);
                string negline = driverKvp.Key + "," + String.Join(",", driverKvp.Value.Select(x => x * -1));
                positiveOutputSB.AppendLine(posline);
                negativeOutputSB.AppendLine(negline);
            }

            return(positiveOutputSB.ToString() + Environment.NewLine + negativeOutputSB.ToString());
        }
Example #3
0
        private string GetCsvOverallTimes(Rally rallyData)
        {
            var outputSB = new StringBuilder();

            int stageCount = 1;

            foreach (Stage stage in rallyData)
            {
                var dnfList = new List <DriverTime>();

                outputSB.AppendLine("SS" + stageCount + " - " + stage.Name);
                outputSB.AppendLine("Overall Times");
                outputSB.AppendLine("Pos, Pos Chng, Name, Vehicle, Time, Diff 1st, Diff Prev");

                List <KeyValuePair <string, DriverTime> > sortedStageData = stage.DriverTimes.ToList();
                sortedStageData.Sort((x, y) =>
                {
                    if (x.Value != null && y.Value == null)
                    {
                        return(-1);
                    }
                    else if (x.Value == null && y.Value != null)
                    {
                        return(1);
                    }
                    else if (x.Value == null && y.Value == null)
                    {
                        return(0);
                    }
                    else
                    {
                        return(x.Value.OverallTime.CompareTo(y.Value.OverallTime));
                    }
                });

                foreach (KeyValuePair <string, DriverTime> driverTimeKvp in sortedStageData)
                {
                    var driverName = driverTimeKvp.Key;
                    var driverTime = driverTimeKvp.Value;

                    // put DNFs into a separate list
                    if (driverTime.IsDnf)
                    {
                        dnfList.Add(driverTime);
                        continue;
                    }

                    if (driverTime != null)
                    {
                        var formatString = @"hh\:mm\:ss\.fff";
                        var line         = driverTime.OverallPosition + "," +
                                           driverTime.PositionChange + "," +
                                           driverTime.DriverName + "," +
                                           driverTime.Vehicle + "," +
                                           driverTime.OverallTime.ToString(formatString) + "," +
                                           driverTime.OverallDiffFirst.ToString(formatString) + "," +
                                           driverTime.OverallDiffPrevious.ToString(formatString);

                        outputSB.AppendLine(line);
                    }
                    else
                    {
                        outputSB.AppendLine(",,," + driverName + ",,DNF");
                    }
                }

                // put DNFs at the bottom
                foreach (var driverTime in dnfList)
                {
                    outputSB.AppendLine(",," + driverTime.DriverName + "," + driverTime.Vehicle + ",DNF");
                }

                outputSB.AppendLine("");
                stageCount++;
            }

            return(outputSB.ToString());
        }
Example #4
0
        private string GetCsvStageTimes(Rally rallyData)
        {
            var outputSB = new StringBuilder();

            int stageCount = 1;

            foreach (Stage stage in rallyData)
            {
                var dnfList = new List <DriverTime>();

                outputSB.AppendLine("SS" + stageCount + " - " + stage.Name);
                outputSB.AppendLine("Stage Times");
                outputSB.AppendLine("Pos, Name, Vehicle, Time, Diff 1st, Diff Prev");

                List <KeyValuePair <string, DriverTime> > sortedStageData = stage.DriverTimes.ToList();
                sortedStageData.Sort((x, y) =>
                {
                    if (x.Value != null && y.Value == null)
                    {
                        return(-1);
                    }
                    else if (x.Value == null && y.Value != null)
                    {
                        return(1);
                    }
                    else if (x.Value == null && y.Value == null)
                    {
                        return(0);
                    }
                    else
                    {
                        return(x.Value.StageTime.CompareTo(y.Value.StageTime));
                    }
                });

                foreach (KeyValuePair <string, DriverTime> driverTimeKvp in sortedStageData)
                {
                    var driverName = driverTimeKvp.Key;
                    var driverTime = driverTimeKvp.Value;

                    // put DNFs into separate list
                    if (driverTime.IsDnf)
                    {
                        dnfList.Add(driverTime);
                        continue;
                    }

                    // if a driver did not complete the pervious stage due to alt+f4 or a crash, the next stage
                    // will have a zero time for the CalculatedStageTime, so enter DNF
                    if (driverTime == null)
                    {
                        outputSB.AppendLine(",," + driverName + ",,DNF");
                    }
                    else
                    {
                        var formatString = @"hh\:mm\:ss\.fff";
                        var line         = driverTime.StagePosition + "," +
                                           driverTime.DriverName + "," +
                                           driverTime.Vehicle + "," +
                                           driverTime.StageTime.ToString(formatString) + "," +
                                           driverTime.StageDiffFirst.ToString(formatString) + "," +
                                           driverTime.StageDiffPrevious.ToString(formatString);

                        outputSB.AppendLine(line);
                    }
                }

                // put DNFs at the bottom
                foreach (var driverTime in dnfList)
                {
                    outputSB.AppendLine("," + driverTime.DriverName + "," + driverTime.Vehicle + ",DNF");
                }

                outputSB.AppendLine("");
                stageCount++;
            }

            return(outputSB.ToString());
        }
Example #5
0
        // Given a championship ID, event ID, and a file path:
        // Fetch all the stage data for the event
        // convert the stage data to CSV
        // save the data to disk
        public async Task SaveStageDataToCsv(string championshipId, string eventId, string filePath)
        {
            if (clubInfoCache == null)
            {
                return;   // TODO error handling?
            }
            // this gets the event results from the cache
            Event eventToOutput = null;

            for (int i = 0; i < clubInfoCache.RecentResults.Championships.Length; i++)
            {
                if (clubInfoCache.Championships[i].Id == championshipId)
                {
                    var championship = clubInfoCache.RecentResults.Championships[i];
                    for (int j = 0; j < championship.Events.Length; j++)
                    {
                        if (championship.Events[j].ChallengeId == eventId)
                        {
                            eventToOutput = championship.Events[j];
                            break;
                        }
                    }
                }
            }

            // if we didn't find the event, bail
            if (eventToOutput == null)
            {
                return;
            }

            // get the stage results from the event
            var stageResultResponses = new List <Tuple <HttpStatusCode, string> >();

            for (int i = 0; i < eventToOutput.Stages.Length; i++)
            {
                stageResultResponses.Add(await racenetApi.GetStageResults(eventToOutput.ChallengeId, eventToOutput.Id, i.ToString()));
            }

            var rallyData = new Rally();

            // go thru each response and create the internal data used
            for (int i = 0; i < stageResultResponses.Count; i++)
            {
                var stageResultResponse = stageResultResponses[i];
                if (stageResultResponse.Item1 != HttpStatusCode.OK || String.IsNullOrWhiteSpace(stageResultResponse.Item2))
                {
                    return; // TODO error handling
                }
                var stageApiData = JsonConvert.DeserializeObject <LeaderboardApiModel>(stageResultResponse.Item2);
                if (stageApiData == null)
                {
                    return; // TODO error handling
                }
                var stageData = new Stage(eventToOutput.Stages[i].Name);

                foreach (var driverEntry in stageApiData.Entries)
                {
                    stageData.AddDriver(CreateDriverTime(driverEntry));
                }

                rallyData.AddStage(stageData);
            }

            // now crunch the numbers
            // this will generate any data that is not provided by the API
            rallyData.ProcessResults();

            // get the CSV formatted output and write it to file
            // TODO this should probably be somewhere else for encapsulation and separation of concerns
            var outputString = GetHeaderData(championshipId, eventId, eventToOutput.Id);

            outputString += Environment.NewLine;
            outputString += GetCsvStageTimes(rallyData);
            outputString += Environment.NewLine;
            outputString += GetCsvOverallTimes(rallyData);
            outputString += Environment.NewLine;
            outputString += GetStats(rallyData);
            outputString += Environment.NewLine;
            outputString += GetCsvChartOutput(rallyData);

            File.WriteAllText(filePath, outputString, Encoding.UTF8);
        }