private static List <BusArrivalTime> InterleaveRouteScheduleAndEstimates(BusStopRouteSchedule routeSchedule,
                                                                                 Dictionary <string, List <int> > stopEstimates, DateTimeOffset currentTime)
        {
            var arrivalTimes = Enumerable.Empty <BusArrivalTime>();

            var daySchedule = routeSchedule.DaySchedules.FirstOrDefault(ds => DaysOfWeekUtils.IsToday(ds.Days, currentTime));

            if (daySchedule != null)
            {
                var relativeSchedule = MakeRelativeScheduleWithinCutoff(daySchedule, currentTime);
                arrivalTimes = relativeSchedule.Select(minutes => new BusArrivalTime(minutes, isEstimate: false));
            }

            if (stopEstimates.ContainsKey(routeSchedule.RouteNo))
            {
                var routeEstimates = stopEstimates[routeSchedule.RouteNo];
                arrivalTimes = arrivalTimes.Where(arrivalTime =>
                                                  !routeEstimates.Any(estimate =>
                                                                      Math.Abs(arrivalTime.MinutesFromNow - estimate) <= ESTIMATE_CORRELATION_TOLERANCE_MINUTES));
                arrivalTimes = arrivalTimes.Concat(
                    routeEstimates.Select(estimate => new BusArrivalTime(estimate, isEstimate: true)));
            }

            arrivalTimes = arrivalTimes.OrderBy(arrivalTime => arrivalTime);

            return(arrivalTimes.ToList());
        }
        public void RepeatChore_EveryMonWedFri_ShouldOccurOnMonWedFri()
        {
            int daysOfWeek = DaysOfWeekUtils.valueOf(new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday });

            var chore = new ChoreBuilder()
                        .WithRepeating(1, Models.RepeatingUnitType.Week)
                        .WithDaysOfWeek(daysOfWeek)
                        .Build();

            // spin through a week and check we have an occurance on the right days
            DateTime checkDate = DateTime.Now.Date;

            for (int i = 0; i < 7; i++)
            {
                if ((checkDate.DayOfWeek == DayOfWeek.Monday) ||
                    (checkDate.DayOfWeek == DayOfWeek.Wednesday) ||
                    (checkDate.DayOfWeek == DayOfWeek.Friday))
                {
                    chore.RecursOnDate(checkDate).ShouldBeTrue();
                }
                else
                {
                    chore.RecursOnDate(checkDate).ShouldBeFalse();
                }

                checkDate = checkDate.AddDays(1);
            }
        }
Exemple #3
0
        private static List <int> InterleaveRouteScheduleAndEstimates(BusStopRouteSchedule routeSchedule,
                                                                      Dictionary <string, List <int> > stopEstimates, DateTimeOffset currentTime)
        {
            var result = new List <int>();

            var daySchedule = routeSchedule.DaySchedules.FirstOrDefault(ds => DaysOfWeekUtils.IsToday(ds.Days, currentTime));

            if (daySchedule != null)
            {
                result.AddRange(ToMinutesFromNow(daySchedule, currentTime));
            }

            if (stopEstimates.ContainsKey(routeSchedule.RouteNo))
            {
                var routeEstimates = stopEstimates[routeSchedule.RouteNo];
                foreach (int estimate in routeEstimates)
                {
                    // When an estimate time is close to a scheduled time, overwrite the schedule with the estimate.
                    var scheduleIndex = result.FindIndex(i => Math.Abs(i - estimate) <= 10);
                    if (scheduleIndex != -1)
                    {
                        result[scheduleIndex] = estimate;
                    }
                    else
                    {
                        result.Insert(0, estimate);
                    }
                }
            }

            result.Sort();

            return(result);
        }
        public void RepeatChore_EverySaturday_ShouldBeActiveNextOnSaturday()
        {
            var chore = new ChoreBuilder()
                        .WithRepeating(1, Models.RepeatingUnitType.Week)
                        .WithDaysOfWeek(DaysOfWeekUtils.valueOf(DayOfWeek.Saturday))
                        .Build();

            DateTime checkDate = DateTime.Now.Date;

            for (int i = 0; i < 7; i++)
            {
                if (checkDate.DayOfWeek == DayOfWeek.Saturday)
                {
                    chore.RecursOnDate(checkDate).ShouldBeTrue();
                }
                else
                {
                    chore.RecursOnDate(checkDate).ShouldBeFalse();
                }

                checkDate = checkDate.AddDays(1);
            }
        }
        private static List <GoogleRouteSchedule> ParseScheduleCSV(ZipArchiveEntry entry)
        {
            using (var reader = new StreamReader(entry.Open()))
            {
                // skip format line
                reader.ReadLine();
                var lines = ReadLines(reader).ToList();

                var flatSchedule = lines.Select(line => line.Split(','))
                                   .Where(line => !string.IsNullOrWhiteSpace(line[1]))
                                   .Select(line => new
                {
                    route = s_routePattern.Match(line[0]).Groups[1].Value,
                    stop  = line[3],
                    order = line[4],
                    days  = DaysOfWeekUtils.GetDaysOfWeek(line[0]),
                    time  = ToTimeSpan(line[1].Replace("\"", string.Empty))
                });

                // Time to turn some totally flat data into totally structured data.
                var routeDayStopSchedules = flatSchedule.GroupBy(line => new
                {
                    route = line.route,
                    stop  = line.stop,
                    // stops can appear more than once in a route (particularly at the very beginning and very end)
                    // we want to separate each section of the schedule in which the same stop appears.
                    order = line.order,
                    days  = line.days
                })
                                            .Select(grouping => grouping.Aggregate(new List <TimeSpan>(),
                                                                                   (times, time) => { times.Add(time.time); return(times); },
                                                                                   times => new
                {
                    route         = grouping.Key.route,
                    days          = grouping.Key.days,
                    stopSchedules = new GoogleStopSchedule
                    {
                        Name  = grouping.Key.stop,
                        Times = times.Distinct().OrderBy(time => time).ToList()
                    }
                }));

                var routeDaySchedules = routeDayStopSchedules
                                        .GroupBy(line => new { route = line.route, days = line.days })
                                        .Select(grouping => grouping.Aggregate(new
                {
                    route       = grouping.Key.route,
                    daySchedule = new GoogleDaySchedule
                    {
                        Days          = grouping.Key.days,
                        StopSchedules = new List <GoogleStopSchedule>()
                    }
                }, (result, line) => { result.daySchedule.StopSchedules.Add(line.stopSchedules); return(result); }));

                // the aristocrats!
                IList <GoogleRouteSchedule> routeSchedules = routeDaySchedules
                                                             .GroupBy(line => line.route)
                                                             .Select(grouping => grouping.Aggregate(new GoogleRouteSchedule
                {
                    RouteNo = grouping.Key,
                    Days    = new List <GoogleDaySchedule>()
                }, (result, line) => { result.Days.Add(line.daySchedule); return(result); })).ToList();

                if (!routeSchedules.Any(x => x.RouteNo == "C1R"))
                {
                    routeSchedules.Add(GetC1RSchedule());
                }
                return(routeSchedules.ToList());
            }
        }