HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Finding the busiest time-frame in a parking lot

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thetimelotfindingbusiestframeparking

Problem

The text file containing cars' arrival and departure time will upload stuff from the parking lot.

Text will be like this:

10:10, 11:10
10:30, 12:40 
10:25, 11:10
11:10, 12:20


I created a ParkedCar class:

public class ParkerCar
{
    public DateTime ArrivalTime { get; set; }
    public DateTime DepartureTime { get; set; }
}


The method that parses the text file, fills into List, and sorts them by the cars' arrival time:

public class ParkingLotRepository
{
    public List getParkedCars()
    {
        List parkedCars = new List();
        foreach (string line in File.ReadLines(path))
        {
            string[] times = line.Split(',');
            bool isValid = true;
            DateTime dtStart;
            if (!DateTime.TryParseExact(times[0].Trim(), "HH:mm",
                CultureInfo.InvariantCulture,
                DateTimeStyles.NoCurrentDateDefault, out dtStart))
                isValid = false;

            DateTime dtEnd;
            if (!DateTime.TryParseExact(times[1].Trim(), "HH:mm",
                CultureInfo.InvariantCulture,
                DateTimeStyles.NoCurrentDateDefault, out dtEnd))
                isValid = false;

            if (isValid)
            {
                parkedCars.Add(new ParkedCar
                {
                    ArrivalTime = dtStart,
                    DepartureTime = dtEnd
                });
            }
        }
        parkedCars = parkedCars
            .OrderBy(c => c.ArrivalTime)
            .ThenBy(c => c.DepartureTime)
            .ToList();

        return parkedCars;
    }
}


I wrote the method shown below to find the busiest time-frame and how many cars were in the parking lot. I'm not sure if this is an effective way to do that:

```
public static ParkTimeframe getPickTimeframe(List cars)
{
List timeFrames = new List();
DateTime dtStart = cars.First().arrivalTime;
DateTime dtEnd = cars.First().leavingTime;
int count = 0;

foreach (ParkedCar car in

Solution

Naming Conventions

MSDN, General Naming Conventions

-
DO NOT use Hungarian notation:

  • [dt]Start in getPickTimeframe() --> DateTime currentFrameStartDate



  • [dt]End in getPickTimeframe() --> DateTime currentFrameEndDate



-
DO favor readability over brevity:

  • ParkedCar --> ParkingLog



  • getPickTimeframe(List [cars]) --> GetPeakTimeFrame(List parkingLogs)



  • public int [countCars]; --> public int TotalNumberOfParkedCars;



  • int [count] = 0; --> int currentFrameNumberOfParkedCars;



MSDN, Naming Guidelines / Capitalization Conventions

-
DO use PascalCasing for all public member, type, and namespace names consisting of multiple words:

  • [G]et[Pick]Time[F]rame() --> GetPeakTimeFrame()



  • class ParkTime[F]rame



  • ParkTime[F]rame.[S]tartTime



  • ParkTime[F]rame.[E]ndTime



  • ParkTime[F]rame.[C]ountCars --> Also see above for alternative name



  • ParkedCar.[A]rrivalTime



  • ParkedCar.[L]eavingTime



Implementation

Your current implementation, besides efficiency, is not working correctly.

For parkings as the following:

// Parking opens at 07:00
DateTime parkingOpenDate = DateTime.Now.Date.AddHours(7);

// t --xxxxxxxx--------------------------------07:02 - 07:10
// t ---xxxxxxxx-------------------------------07:03 - 07:11
// t --------------xxxxxxxx--------------------07:14 - 07:22
// t --------xxxxxxxxx-------------------------07:08 - 07:17
// t 001222223321112221111100000000000000000000

new ParkingLog[]
{
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(2), LeavingTime = parkingOpenDate.AddMinutes(10) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(3), LeavingTime = parkingOpenDate.AddMinutes(11) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(14), LeavingTime = parkingOpenDate.AddMinutes(22) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(8), LeavingTime = parkingOpenDate.AddMinutes(17) }
}


It should output

07:08.00 - 07:10:00 with 3 cars


However, it outputs:

07:02.00 - 07:10:00 with 2 cars


Here are my changes to the code, calculating the correct peak time frame, only assuming the LeavingDate of each ParkingLog (ParkedCar in your source) is greater than the ArrivalDate:

public class _113182
{
    private SortedList carParkCapacityTracker = new SortedList();

    public class ParkingTimeFrame
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public int TotalNumberOfParkedCars { get; set; }

        public override string ToString()
        {
            return string.Format("{0:HH:mm.ss} - {1:HH:mm:ss} | #Cars: {2}", StartTime, EndTime, TotalNumberOfParkedCars);
        }
    }

    public class ParkingLog
    {
        public DateTime ArrivalTime { get; set; }
        public DateTime LeavingTime { get; set; }

        public override string ToString()
        {
            return string.Format("{0:HH:mm:ss} - {1:HH:mm:ss}", ArrivalTime, LeavingTime);
        }
    }

    private void TrackCarParkingAction(DateTime actionDate, int actionEffect)
    {
        if (!carParkCapacityTracker.ContainsKey(actionDate))
        {
            carParkCapacityTracker.Add(actionDate, actionEffect);
        }
        else
        {
            carParkCapacityTracker[actionDate] += actionEffect;
        }
    }

    private void TrackCarParkingAction(ParkingLog parkingLog)
    {
        TrackCarParkingAction(parkingLog.ArrivalTime, +1);
        TrackCarParkingAction(parkingLog.LeavingTime, -1);
    }

    public ParkingTimeFrame GetPeakTimeFrame(List parkingLogs)
    {
        carParkCapacityTracker.Clear();

        parkingLogs.ForEach(TrackCarParkingAction);

        int currentNumberOfParkedCars = 0;
        int maximumNumberOfParkedCars = 0;
        int maximumCapacityFrameOffset = 0;

        for (int currentFrameOffset =  0; currentFrameOffset < carParkCapacityTracker.Count; currentFrameOffset++)
        {
            currentNumberOfParkedCars += carParkCapacityTracker.Values[currentFrameOffset];
            if (maximumNumberOfParkedCars <= currentNumberOfParkedCars)
            {
                maximumNumberOfParkedCars = currentNumberOfParkedCars;
                maximumCapacityFrameOffset = currentFrameOffset;
            }
        }

        return new ParkingTimeFrame()
        {
            StartTime = carParkCapacityTracker.Keys[maximumCapacityFrameOffset],
            EndTime = carParkCapacityTracker.Keys[maximumCapacityFrameOffset + 1],
            TotalNumberOfParkedCars = maximumNumberOfParkedCars
        };
    }
}


And here is the code to test it:

```
public static void Main()
{
Console.WriteLine("Enter to start..");
Console.ReadLine();

// Parking opens at 07:00
DateTime parkingOpenDate = DateTime.Now.Date.AddHours(7);

List parkingLogs = new List
(
// t --xxxxxxxx--------------------------------07:02 - 07:10
// t ---xxxxxxxx-------------------------------07:03 -

Code Snippets

// Parking opens at 07:00
DateTime parkingOpenDate = DateTime.Now.Date.AddHours(7);

// t --xxxxxxxx--------------------------------07:02 - 07:10
// t ---xxxxxxxx-------------------------------07:03 - 07:11
// t --------------xxxxxxxx--------------------07:14 - 07:22
// t --------xxxxxxxxx-------------------------07:08 - 07:17
// t 001222223321112221111100000000000000000000

new ParkingLog[]
{
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(2), LeavingTime = parkingOpenDate.AddMinutes(10) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(3), LeavingTime = parkingOpenDate.AddMinutes(11) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(14), LeavingTime = parkingOpenDate.AddMinutes(22) },
    new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(8), LeavingTime = parkingOpenDate.AddMinutes(17) }
}
07:08.00 - 07:10:00 with 3 cars
07:02.00 - 07:10:00 with 2 cars
public class _113182
{
    private SortedList<DateTime, int> carParkCapacityTracker = new SortedList<DateTime, int>();

    public class ParkingTimeFrame
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public int TotalNumberOfParkedCars { get; set; }

        public override string ToString()
        {
            return string.Format("{0:HH:mm.ss} - {1:HH:mm:ss} | #Cars: {2}", StartTime, EndTime, TotalNumberOfParkedCars);
        }
    }

    public class ParkingLog
    {
        public DateTime ArrivalTime { get; set; }
        public DateTime LeavingTime { get; set; }

        public override string ToString()
        {
            return string.Format("{0:HH:mm:ss} - {1:HH:mm:ss}", ArrivalTime, LeavingTime);
        }
    }

    private void TrackCarParkingAction(DateTime actionDate, int actionEffect)
    {
        if (!carParkCapacityTracker.ContainsKey(actionDate))
        {
            carParkCapacityTracker.Add(actionDate, actionEffect);
        }
        else
        {
            carParkCapacityTracker[actionDate] += actionEffect;
        }
    }

    private void TrackCarParkingAction(ParkingLog parkingLog)
    {
        TrackCarParkingAction(parkingLog.ArrivalTime, +1);
        TrackCarParkingAction(parkingLog.LeavingTime, -1);
    }

    public ParkingTimeFrame GetPeakTimeFrame(List<ParkingLog> parkingLogs)
    {
        carParkCapacityTracker.Clear();

        parkingLogs.ForEach(TrackCarParkingAction);

        int currentNumberOfParkedCars = 0;
        int maximumNumberOfParkedCars = 0;
        int maximumCapacityFrameOffset = 0;

        for (int currentFrameOffset =  0; currentFrameOffset < carParkCapacityTracker.Count; currentFrameOffset++)
        {
            currentNumberOfParkedCars += carParkCapacityTracker.Values[currentFrameOffset];
            if (maximumNumberOfParkedCars <= currentNumberOfParkedCars)
            {
                maximumNumberOfParkedCars = currentNumberOfParkedCars;
                maximumCapacityFrameOffset = currentFrameOffset;
            }
        }

        return new ParkingTimeFrame()
        {
            StartTime = carParkCapacityTracker.Keys[maximumCapacityFrameOffset],
            EndTime = carParkCapacityTracker.Keys[maximumCapacityFrameOffset + 1],
            TotalNumberOfParkedCars = maximumNumberOfParkedCars
        };
    }
}
public static void Main()
{
    Console.WriteLine("Enter to start..");
    Console.ReadLine();

    // Parking opens at 07:00
    DateTime parkingOpenDate = DateTime.Now.Date.AddHours(7);

    List<ParkingLog> parkingLogs = new List<ParkingLog>
    (
        // t --xxxxxxxx--------------------------------07:02 - 07:10
        // t ---xxxxxxxx-------------------------------07:03 - 07:11
        // t --------------xxxxxxxx--------------------07:14 - 07:22
        // t --------xxxxxxxxx-------------------------07:08 - 07:17
        // t 001222223321112221111100000000000000000000

        new ParkingLog[]
        {
            new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(2), LeavingTime = parkingOpenDate.AddMinutes(10) },
            new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(3), LeavingTime = parkingOpenDate.AddMinutes(11) },
            new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(14), LeavingTime = parkingOpenDate.AddMinutes(22) },
            new ParkingLog() { ArrivalTime = parkingOpenDate.AddMinutes(8), LeavingTime = parkingOpenDate.AddMinutes(17) }
        }
    );

    // Should output 07:08 - 07:10 with 3 cars
    Console.WriteLine("{0}", new _113182().GetPeakTimeFrame(parkingLogs));
}

Context

StackExchange Code Review Q#113182, answer score: 7

Revisions (0)

No revisions yet.