Created
July 11, 2020 12:39
-
-
Save thomasforth/9c794dd6786c59e8b5b44194f893b6de to your computer and use it in GitHub Desktop.
Big Belly Analysis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CsvHelper; | |
using CsvHelper.Configuration; | |
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.IO; | |
using System.Linq; | |
using System.Security.Cryptography.X509Certificates; | |
using System.Threading; | |
namespace BigBellyAnalysis | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
List<BinCollection> BigBellyBinCollections = new List<BinCollection>(); | |
using (StreamReader reader = new StreamReader(@"Assets/Daily Collection Activity - CLEAN.csv")) | |
{ | |
using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture)) | |
{ | |
csv.Configuration.RegisterClassMap<BinsClassMap>(); | |
BigBellyBinCollections = csv.GetRecords<BinCollection>().ToList(); | |
} | |
} | |
foreach (BinCollection bc in BigBellyBinCollections) | |
{ | |
if (bc.FullnessLevelatCollection == " Alert - Unknown Fullness") | |
{ | |
bc.FullnessLevelAtCollectionDecimal = 0; | |
} | |
else | |
{ | |
bc.FullnessLevelAtCollectionDecimal = Decimal.Parse(bc.FullnessLevelatCollection.Replace("%", "")) / 100; | |
} | |
} | |
Dictionary<string, BinLocation> BinLocationsDictionary = new Dictionary<string, BinLocation>(); | |
using (StreamReader reader = new StreamReader(@"Assets/Account Assets - CLEAN.csv")) | |
{ | |
using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture)) | |
{ | |
csv.Configuration.RegisterClassMap<BinLocationClassMap>(); | |
BinLocationsDictionary = csv.GetRecords<BinLocation>().ToDictionary(x => x.Serial, x => x); | |
} | |
} | |
List<string> UniqueBins = BigBellyBinCollections.Select(x => x.Serial).Distinct().ToList(); | |
// We assume that a Big Belly bin at 100% holds 500 litres of uncompacted waste -- compressed by a factor of 4 to 125 litres. | |
// We round all of our times to days, with the cut off at midday. | |
// Let's assume that a Big Belly bin fills at a constant rate between emptyings. | |
int binvolume = 500; | |
List<BinCumulative> CumulativeBins = new List<BinCumulative>(); | |
List<BinCumulative> InterpolatedWasteCollections = new List<BinCumulative>(); | |
foreach (string BinSerial in UniqueBins) | |
{ | |
DateTime StartDate = BigBellyBinCollections.Where(x => x.Serial == BinSerial).Min(x => x.CollectionTime).Date; | |
DateTime LatestDate = BigBellyBinCollections.Where(x => x.Serial == BinSerial).Max(x => x.CollectionTime).Date; | |
decimal lastCumulativeWaste = 0; | |
for (DateTime day = StartDate; day <= LatestDate; day = day.AddDays(1)) | |
{ | |
BinCumulative bc = new BinCumulative(); | |
bc.Serial = BinSerial; | |
bc.Date = day; | |
bc.CumulativeWasteDeposited_litres = BigBellyBinCollections.Where(x => x.Serial == BinSerial && | |
x.CollectionTime.Date < day.AddDays(0.5)).Sum(x => x.FullnessLevelAtCollectionDecimal) * binvolume; | |
bc.EstimatedWasteDepositedThisDay_litres = bc.CumulativeWasteDeposited_litres - lastCumulativeWaste; | |
lastCumulativeWaste = bc.CumulativeWasteDeposited_litres; | |
CumulativeBins.Add(bc); | |
} | |
// now interpolate | |
List<BinCumulative> BCsToSpreadWasteAcross = new List<BinCumulative>(); | |
foreach (BinCumulative bc in CumulativeBins.Where(x => x.Serial == BinSerial)) | |
{ | |
if (bc.EstimatedWasteDepositedThisDay_litres == 0) | |
{ | |
BCsToSpreadWasteAcross.Add(bc); | |
} | |
else if (BCsToSpreadWasteAcross.Count != 0) | |
{ | |
BCsToSpreadWasteAcross.Add(bc); | |
int count = BCsToSpreadWasteAcross.Count; | |
decimal increment = Math.Round(bc.EstimatedWasteDepositedThisDay_litres / count, 2); | |
BCsToSpreadWasteAcross.ForEach(x => x.EstimatedWasteDepositedThisDay_litres = increment); | |
BCsToSpreadWasteAcross.Clear(); | |
} | |
else | |
{ | |
InterpolatedWasteCollections.Add(bc); | |
} | |
} | |
} | |
// fix cumulative and add bin location | |
foreach (BinCumulative bc in CumulativeBins) | |
{ | |
bc.CumulativeWasteDeposited_litres = CumulativeBins.Where(x => x.Serial == bc.Serial && x.Date <= bc.Date).Sum(x => x.EstimatedWasteDepositedThisDay_litres); | |
bc.Latitude = Math.Round(BinLocationsDictionary[bc.Serial].Lat,5); | |
bc.Longitude = Math.Round(BinLocationsDictionary[bc.Serial].Lng,5); | |
} | |
using (TextWriter _textWriter = File.CreateText("CumulativeBins.csv")) { | |
using (CsvWriter _csvwriter = new CsvWriter(_textWriter, CultureInfo.CurrentCulture)) | |
{ | |
_csvwriter.WriteRecords(CumulativeBins); | |
} | |
} | |
} | |
} | |
public class BinCumulative | |
{ | |
public string Serial { get; set; } | |
public DateTime Date { get; set; } | |
public decimal EstimatedWasteDepositedThisDay_litres { get; set; } | |
public decimal CumulativeWasteDeposited_litres { get; set; } | |
public decimal Latitude { get; set; } | |
public decimal Longitude { get; set; } | |
} | |
public class BinCollection | |
{ | |
public string Serial { get; set; } | |
public string Description { get; set; } | |
public string Capacity { get; set; } | |
public string StreamType { get; set; } | |
public string Reason { get; set; } | |
public string FullnessLevelatCollection { get; set; } | |
public decimal FullnessLevelAtCollectionDecimal { get; set; } | |
public DateTime CollectionTime { get; set; } | |
} | |
public class BinsClassMap : ClassMap<BinCollection> | |
{ | |
public BinsClassMap() | |
{ | |
Map(m => m.Serial).Name("Serial"); | |
Map(m => m.Description).Name("Description"); | |
Map(m => m.Capacity).Name("Capacity"); | |
Map(m => m.StreamType).Name("Stream Type"); | |
Map(m => m.Reason).Name("Reason"); | |
Map(m => m.FullnessLevelatCollection).Name("Fullness Level at Collection"); | |
Map(m => m.CollectionTime).Name("Collection Time"); | |
} | |
} | |
public class BinLocation | |
{ | |
public string Description { get; set; } | |
public string Serial { get; set; } | |
public string Streams { get; set; } | |
public string Model { get; set; } | |
public string Capacity { get; set; } | |
public string Status { get; set; } | |
public string FullnessThreshold { get; set; } | |
public string AgeThreshold { get; set; } | |
public string LastCalled { get; set; } | |
public decimal Lat { get; set; } | |
public decimal Lng { get; set; } | |
} | |
public class BinLocationClassMap : ClassMap<BinLocation> | |
{ | |
public BinLocationClassMap() | |
{ | |
Map(m => m.Description).Name("Description"); | |
Map(m => m.Serial).Name("Serial"); | |
Map(m => m.Streams).Name("Streams"); | |
Map(m => m.Model).Name("Model"); | |
Map(m => m.Capacity).Name("Capacity"); | |
Map(m => m.Status).Name("Status"); | |
Map(m => m.FullnessThreshold).Name("Fullness Threshold"); | |
Map(m => m.AgeThreshold).Name("Age Threshold"); | |
Map(m => m.LastCalled).Name("Last Called"); | |
Map(m => m.Lat).Name("Lat"); | |
Map(m => m.Lng).Name("Lng"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment