public void NoPeriodsTest() { TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection(), new TimePeriodCollection()); Assert.Equal(0, periods.Count); } // NoPeriodsTest
public void CombineTest() { TimeRange period1 = new TimeRange( new DateTime( 2011, 3, 01 ), new DateTime( 2011, 3, 05 ) ); TimeRange period2 = new TimeRange( new DateTime( 2011, 3, 05 ), new DateTime( 2011, 3, 10 ) ); TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { period1, period2 }, new TimePeriodCollection() ); Assert.AreEqual( periods.Count, 1 ); Assert.IsTrue( periods[ 0 ].IsSamePeriod( new TimeRange( period1.Start, period2.End ) ) ); }
public void MomentTest() { TimeRange period1 = new TimeRange( new DateTime( 2011, 3, 1 ), new DateTime( 2011, 3, 10 ) ); TimeRange period2 = new TimeRange( new DateTime( 2011, 3, 5 ), new DateTime( 2011, 3, 05 ) ); TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { period1 }, new TimePeriodCollection { period2 } ); Assert.AreEqual( periods.Count, 1 ); Assert.IsTrue( periods[ 0 ].IsSamePeriod( period1 ) ); }
public void SinglePeriodAnytimeTest() { TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { TimeRange.Anytime }, new TimePeriodCollection { TimeRange.Anytime }); Assert.Equal(0, periods.Count); } // SinglePeriodAnytimeTest
public void CombineTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 05)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 10)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1, period2 }, new TimePeriodCollection()); Assert.Equal(1, periods.Count); Assert.True(periods[0].IsSamePeriod(new TimeRange(period1.Start, period2.End))); } // CombineTest
public void IntersectionPeriodsTest() { TimeRange period1 = new TimeRange( new DateTime( 2011, 3, 01 ), new DateTime( 2011, 4, 01 ) ); TimeRange period2 = new TimeRange( new DateTime( 2011, 3, 05 ), new DateTime( 2011, 3, 10 ) ); TimeRange period3 = new TimeRange( new DateTime( 2011, 3, 20 ), new DateTime( 2011, 3, 25 ) ); TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { period1 }, new TimePeriodCollection { period2, period3 } ); Assert.AreEqual( periods.Count, 3 ); Assert.IsTrue( periods[ 0 ].IsSamePeriod( new TimeRange( new DateTime( 2011, 3, 01 ), new DateTime( 2011, 3, 05 ) ) ) ); Assert.IsTrue( periods[ 1 ].IsSamePeriod( new TimeRange( new DateTime( 2011, 3, 10 ), new DateTime( 2011, 3, 20 ) ) ) ); Assert.IsTrue( periods[ 2 ].IsSamePeriod( new TimeRange( new DateTime( 2011, 3, 25 ), new DateTime( 2011, 4, 01 ) ) ) ); }
public void SubtractionNotCombineTest() { TimeRange sourcePeriod = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 10)); TimeRange subtractPeriod = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 05)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { sourcePeriod }, new TimePeriodCollection { subtractPeriod }, false); Assert.Equal(1, periods.Count); } // NoSubtractionNotCombineTest
public void NotCombineTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 05)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 10)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1, period2 }, new TimePeriodCollection(), false); Assert.Equal(2, periods.Count); Assert.True(periods[0].IsSamePeriod(period1)); Assert.True(periods[1].IsSamePeriod(period2)); } // NotCombineTest
public void MomentTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 1), new DateTime(2011, 3, 10)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 5), new DateTime(2011, 3, 05)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1 }, new TimePeriodCollection { period2 }); Assert.Equal(1, periods.Count); Assert.True(periods[0].IsSamePeriod(period1)); } // MomentTest
public void TouchingPeriodsTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 4, 01)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 10)); TimeRange period3 = new TimeRange(new DateTime(2011, 3, 20), new DateTime(2011, 4, 01)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1 }, new TimePeriodCollection { period2, period3 }); Assert.Equal(1, periods.Count); Assert.True(periods[0].IsSamePeriod(new TimeRange(new DateTime(2011, 3, 10), new DateTime(2011, 3, 20)))); } // TouchingPeriodsTest
public void NoSubtractionCombineTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 05)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 10)); TimeRange period3 = new TimeRange(new DateTime(2011, 3, 10), new DateTime(2011, 3, 15)); TimeRange period4 = new TimeRange(new DateTime(2011, 3, 15), new DateTime(2011, 3, 20)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1, period2 }, new TimePeriodCollection { period3, period4 }); Assert.AreEqual(periods.Count, 1); Assert.IsTrue(periods[0].IsSamePeriod(new TimeRange(period1.Start, period2.End))); } // NoSubtractionCombineTest
public void NoSubtractionTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 05)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 10)); TimeRange period3 = new TimeRange(new DateTime(2011, 3, 10), new DateTime(2011, 3, 15)); TimeRange period4 = new TimeRange(new DateTime(2011, 3, 15), new DateTime(2011, 3, 20)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1, period3 }, new TimePeriodCollection { period2, period4 }); Assert.Equal(2, periods.Count); Assert.True(periods[0].IsSamePeriod(period1)); Assert.True(periods[1].IsSamePeriod(period3)); } // NoSubtractionTest
public void IntersectionPeriodsTest() { TimeRange period1 = new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 4, 01)); TimeRange period2 = new TimeRange(new DateTime(2011, 3, 05), new DateTime(2011, 3, 10)); TimeRange period3 = new TimeRange(new DateTime(2011, 3, 20), new DateTime(2011, 3, 25)); TimePeriodSubtractor <TimeRange> periodSubtractor = new TimePeriodSubtractor <TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods(new TimePeriodCollection { period1 }, new TimePeriodCollection { period2, period3 }); Assert.AreEqual(periods.Count, 3); Assert.IsTrue(periods[0].IsSamePeriod(new TimeRange(new DateTime(2011, 3, 01), new DateTime(2011, 3, 05)))); Assert.IsTrue(periods[1].IsSamePeriod(new TimeRange(new DateTime(2011, 3, 10), new DateTime(2011, 3, 20)))); Assert.IsTrue(periods[2].IsSamePeriod(new TimeRange(new DateTime(2011, 3, 25), new DateTime(2011, 4, 01)))); } // IntersectionPeriodsTest
//public IEnumerable<UserTimeRange> ProcessPage(string html) //{ // var vacantSlots = FindVacantTimeSlots(html); // var userVacantSlots = vacantSlots.Select(i => new UserTimeRange(ItalkiHelper.UserId, i.Start, i.End)); // return userVacantSlots; //} // Find vacant time slots by subtracting the occupyed slots from the template slots. public IEnumerable <ITimePeriod> GetVacantPeriods(string html) { /* !!! Warning! If the balance on the account is low, the page does not have the schedule data, but shows payment offer. * After enabling error details in web.config, the error text is "Parsing the external service data. Snippet not found. 43 9" */ // Save on text parsing. Pre-extract the script texts. var paramScriptText = FindText(html, "function ShowMsgBox(title,scr,width,height)", "</script>");; var listScriptText = FindText(html, @"<script type=""text/javascript"">var sUseList", "</script>");; EnsureTimeIsUTC(paramScriptText); var firstDay = ParseFirstDay(paramScriptText); //var timeTy = ParseTimeTy(paramScriptText); var timeArrList = ProcessTimeArrList(listScriptText, firstDay); var tDaysOfWeekList = ProcessTDaysOfWeekList(listScriptText, firstDay); timeArrList.AddAll(tDaysOfWeekList); // Replicate the next week. The length of timeArrList and tDaysOfWeekList is 8 items, so we will produce some overlapped duplicates. The duplicates will be eliminated by the combining operation. var nextEightDays = timeArrList .Select(i => new TimeRange(i.Start.AddDays(7), i.Duration)) .ToList(); timeArrList.AddAll(nextEightDays); CombinePeriods(timeArrList); var tUseList = ProcessTUseList(listScriptText, firstDay); //var notUseTime = ProcessNotUseTime(listScriptText, firstDay); // We impose the deadline ourselves. //tUseList.AddAll(notUseTime); var subtractor = new TimePeriodSubtractor <TimeRange>(); var vacantPeriods = subtractor.SubtractPeriods(timeArrList, tUseList); // Do not shred long stretches into chunks because when they are processed down the stream they will be merged again. return(vacantPeriods); }
/// <summary> /// De-tangles a list of overlapping Verbrauch entries where entries can be subsets of other entries. /// </summary> /// <example> /// [---v1---) /// [-----v2------) /// [---------v3---------) /// is transformed into /// [--v1---) /// ........[-v2--) /// ..............[--v3--) /// </example> /// <param name="input"></param> /// <returns></returns> public static List <Verbrauch> Detangle(IEnumerable <Verbrauch> input) { //var filteredInput = KeepShortestSlices(input); HashSet <Verbrauch> resultSet = new HashSet <Verbrauch>(); var groups = input.OrderBy(v => (v.Startdatum, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit)).GroupBy(v => new Tuple <Wertermittlungsverfahren, string, Mengeneinheit> ( v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit )); foreach (var vGroup in groups) { HashSet <Verbrauch> subResult = new HashSet <Verbrauch>(); // find pairs (x,y) where x.end == y.start: // |----x----|--------y--------| //var adjacentVerbrauchs = from x in vGroup join y in vGroup on x.enddatum equals y.startdatum select new { x, y }; var adjacentVerbrauchs = from x in vGroup join y in vGroup on x.Enddatum equals y.Startdatum select new { x, y }; foreach (var av in adjacentVerbrauchs) { subResult.Add(av.x); subResult.Add(av.y); } // |----x----|--------y--------| // |-------------z-------------| // ==> delete z from result where z.start == x.start and z.end == y.end //var fullyRedundantVerbrauchs = from av in adjacentVerbrauchs join z in vGroup on new { av.x.startdatum, av.y.enddatum } equals new { z.startdatum, z.enddatum } select new { av, z }; var fullyRedundantVerbrauchs = from av in adjacentVerbrauchs join z in vGroup on new { av.x.Startdatum, av.y.Enddatum } equals new { z.Startdatum, z.Enddatum } select new { av, z }; foreach (var frv in fullyRedundantVerbrauchs) { if (frv.av.x.Wert + frv.av.y.Wert != frv.z.Wert) { throw new ArgumentException($"Inconsistent data detected: {JsonConvert.SerializeObject(frv.av.x)} + {JsonConvert.SerializeObject(frv.av.y)} ≠ {JsonConvert.SerializeObject(frv.z)}"); } subResult.Remove(frv.z); } // |----------x----------|---y---| // |---------------z-------------| // or // |---y---|----------x----------| // |---------------z-------------| // or // |---x1--|-----y------|---x2---| // |--------------z--------------| // y and z are given. find x such that x.value == y.value+z.value //subResult.UnionWith(vGroup); subResult.UnionWith(vGroup); foreach (Verbrauch z in new HashSet <Verbrauch>(subResult)) { var ys = subResult.Where(y => z.Contains(y) && !z.Equals(y)); if (ys.Count() > 0) { TimePeriodSubtractor <TimeRange> tps = new TimePeriodSubtractor <TimeRange>(); TimePeriodCollection source = new TimePeriodCollection { z.GetTimeRange() }; TimePeriodCollection subtract = new TimePeriodCollection(); subtract.AddAll(ys.Select(y => y.GetTimeRange())); ITimePeriodCollection subtractionResult = tps.SubtractPeriods(source, subtract); var xs = new HashSet <Verbrauch>(); foreach (var tr in subtractionResult) { Verbrauch v = new Verbrauch() { Einheit = z.Einheit, Wertermittlungsverfahren = z.Wertermittlungsverfahren, Obiskennzahl = z.Obiskennzahl, Startdatum = tr.Start, Enddatum = tr.End }; xs.Add(v); } var totalXWert = z.Wert - ys.Select(y => y.Wert).Sum(); var totalXDuration = xs.Select(x => x.GetDuration().TotalSeconds).Sum(); foreach (var x in xs) { x.Wert = (totalXWert * (decimal)x.GetDuration().TotalSeconds) / ((decimal)totalXDuration); } subResult.Remove(z); subResult.UnionWith(xs); } } resultSet.UnionWith(subResult); } List <Verbrauch> result = new List <Verbrauch>(resultSet); result.Sort(new VerbrauchDateTimeComparer()); return(result); }
public void NoSubtractionTest() { TimeRange period1 = new TimeRange( new DateTime( 2011, 3, 01 ), new DateTime( 2011, 3, 05 ) ); TimeRange period2 = new TimeRange( new DateTime( 2011, 3, 05 ), new DateTime( 2011, 3, 10 ) ); TimeRange period3 = new TimeRange( new DateTime( 2011, 3, 10 ), new DateTime( 2011, 3, 15 ) ); TimeRange period4 = new TimeRange( new DateTime( 2011, 3, 15 ), new DateTime( 2011, 3, 20 ) ); TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { period1, period3 }, new TimePeriodCollection { period2, period4 } ); Assert.AreEqual( periods.Count, 2 ); Assert.IsTrue( periods[ 0 ].IsSamePeriod( period1 ) ); Assert.IsTrue( periods[ 1 ].IsSamePeriod( period3 ) ); }
public void NoPeriodsTest() { TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection(), new TimePeriodCollection() ); Assert.AreEqual( periods.Count, 0 ); }
public void TimePeriodSubtractorSample() { DateTime moment = new DateTime( 2012, 1, 29 ); TimePeriodCollection sourcePeriods = new TimePeriodCollection { new TimeRange( moment.AddHours( 2 ), moment.AddDays( 1 ) ) }; TimePeriodCollection subtractingPeriods = new TimePeriodCollection { new TimeRange( moment.AddHours( 6 ), moment.AddHours( 10 ) ), new TimeRange( moment.AddHours( 12 ), moment.AddHours( 16 ) ) }; TimePeriodSubtractor<TimeRange> subtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection subtractedPeriods = subtractor.SubtractPeriods( sourcePeriods, subtractingPeriods ); foreach ( TimeRange subtractedPeriod in subtractedPeriods ) { Console.WriteLine( "Subtracted Period: {0}", subtractedPeriod ); } // > Subtracted Period : 29.01.2012 02:00:00 - 06:00:00 | 0.04:00 // > Subtracted Period : 29.01.2012 10:00:00 - 12:00:00 | 0.02:00 // > Subtracted Period : 29.01.2012 16:00:00 - 30.01.2012 00:00:00 | 0.08:00 }
public void SinglePeriodAnytimeTest() { TimePeriodSubtractor<TimeRange> periodSubtractor = new TimePeriodSubtractor<TimeRange>(); ITimePeriodCollection periods = periodSubtractor.SubtractPeriods( new TimePeriodCollection { TimeRange.Anytime }, new TimePeriodCollection { TimeRange.Anytime } ); Assert.AreEqual( periods.Count, 0 ); }