Design Underground System
Tags: python, oop
Published: 2022-11-09 20:25:47

## Instructions
Implement the UndergroundSystem class with the following methods:

- checkIn(int id, string stationName, int t)
A customer with a card ID equal to id, checks in at the station stationName at time t.
A customer can only be checked into one place at a time.

- checkOut(int id, string stationName, int t)
A customer with a card ID equal to id, checks out from the station stationName at time t.

- getAverageTime(string startStation, string endStation)
Returns the average time it takes to travel from startStation to endStation.



Attempt [here](https://leetcode.com/problems/design-underground-system/).

## Approach

Some assumptions made when implementing the class

- The average time is computed from all the previous traveling times from startStation to endStation that happened directly, meaning a check in at startStation followed by a check out from endStation.

- The time it takes to travel from startStation to endStation may be different from the time it takes to travel from endStation to startStation.
- There will be at least one customer that has traveled from startStation to endStation before getAverageTime is called.

## Implementation

The Underground class which will have the three methods.
Attributes: a record of checkin times`check_in` and a record of the start and stop station and time taken between them. Use a dictionary to maintain these records`travel`.

```python
class UndergroundSystem:

    def __init__(self):
        #dictionary of checkin stationName and time of checkin. 
        self.check_in = dict()
        #dict of start and stop station and time taken btwn them. 
        self.travel = dict()
```

- 
The **checkIn** method adds the check in stationName and the time. These are stored as a tuple.

```python
def checkIn(self, id: int, stationName: str, t: int) -> None:
        self.check_in[id] = (stationName, t)
     
```

The **checkOut** method checks if the given customer id is in the checkin dictionary and gets the start stationName. This is used to
create a tuple of start and end station for a given id.
We also determine the time taken to travel between the stations.

```python
def checkOut(self, id: int, stationName: str, t: int) -> None:
        if id in self.check_in:
            startStation, t1 = self.check_in[id]
            
            # tuple of stations travelled
            stations = (startStation, stationName)
       
            #determine time taken btwn stations
            if stations in self.travel:
                self.travel[stations].append(t - t1)
            else:
                self.travel[stations] = [t - t1]
            #remove customer from checkin dictionary
          
            self.check_in.pop(id)
```

The **getAverageTime** method checks if the pair of startstation and end station are in the `travel` dictionary.
The average time is calculated by getting the total time divided by the number of times traveled between the two stations.

```python
def getAverageTime(self, startStation, endStation):
        stations = (startStation, endStation)
        if stations in self.travel:
            time_taken_list = self.travel[stations]
            return sum(time_taken_list) / len(time_taken_list)
```

[Here](https://github.com/wanguiwaweru/Object-Oriented/blob/main/undergroundsystem.py) is the entire code.