by Dvir Borochov and Dolev Dublon
Files
- Ex1.py
- Building.py
- Elevator.py
- ElevatorCall.py
- allocate.py
- convertFiles.py
- B1.json - B4.json
- Call_a.csv - Calls_d.csv
This project deals with a design of a smart elevator System, which receives all the required input calls in advance, and should allocate an elevator for a call in the most optimal way, so that the average waiting time will be minimal. the input that we get is:
- json file that contain data about the building and the elevators.
- csv file that contain data about the calls that the elevators going to recived.
We were asked in this task, to write a program in Python that processes information and emits a new csv file where each call is acllocated to an elevator, so that the total wait time will be the lowest. The software gets a file with information about the building in json format and a file with information about the calls in csv format(Off-Line Algorithm) and emits a csv file, at the beginning of the task Dvir and I were not partners and after a week we decided to become partners. That is why our literary review is different. At first we did a brainstorm, and came up with a lot of good ideas, we tried to implement an algorithm based on the shortest time of an elevator to get to the call received, but we quickly found it very complex, we feel that maybe with a little more knowledge in Python we would succeed to calculate the timestamp and to take the exact elevator location,but after many attempts, writing and deleting, which can be seen in commits and in our branches, the code became very cumbersome and impossible Understand , we decided to Keep It Simple, Finally, we decided to produce a preference-based algorithm, meaning it prioritizes the fast elevators over the slower ones so that relatively fast elevators get more calls.
things to take to consideration Each building has a minimum and maximum floor and the number of elevators is known Each elevator has characteristics of stop time, movement start time, and speed (how many seconds does it take to move to the floor). The user has to tap the destination floor outside the elevators and then the system has to insert (assign) a specific elevator that is set for it and stop at the destination floor. The system will want to install the elevator that will reduce the arrival time to a minimum (the arrival time is set to be the time in seconds between the call to the elevator and the arrival to the destination floor) Given a collection of calls for lifts in time we would like to define an elevator placement strategy for calls that will minimize the total arrival time for all calls. Residential floors is 1 and up Entrance or exit floors to this building are 0 and below And there is no limit to the amount of people per elevator.
We used the links below to understand the problem in depth and formulate an algorithm that will lead to optimal performance.
the uml from out first assignment helped understanding how to build our code.
Clone the project
git clone https://github.com/dvirbo/Ex1_OOP.git
Go to the project directory
cd Ex1_OOP
Run
python Ex1.py B1.json Calls_a.csv output.csv
or on linux / mac
python3 Ex1.py B1.json Calls_a.csv output.csv
- Building: contain info about minFloor & maxFloor, and a list of elevators.
- Elevator: info about the parameters of the building. contain- speed, minFloor, close & open Time, start & stop Time, status: up/down or level A518 .
- ElevatorCall: info about each call that will help us to assign the call. contain: index of the Chosen Elev,timeStamp of the call,source & destination of the Call and the direction of the call- up/down.
- convertFiles: contain 3 functions: jsonBuildingToObj: convert json file that contain the data about the elevator and the building to objects of building & elevator. csvToList: convert csv file that contain the info about the calls that we get and make list of calls from the data. writeOutPutFile: write the elevators that we allocate To the right column un the csv file.
this is how we tried to understand how to choose with prefered answer in python by using
Google Collab
In the Screenshots above we tried to change the algorithm based on the average time of floor transition for each elevator.
finally, we decided to use an algorithm that favors speed.
this table shows the different between the two methods that we examine
link to the java simulator repo
We checked that indeed the amount of shows of the high-speed elevator appears more:
from convertFiles import jsonBuildingToObj, csvToList, writeOutPutFile
from allocate import allocate
if __name__ == '__main__':
# """
# requiring all the data needed for the program from the files
# python Ex1.py <Building.json> <Calls.csv> <output.csv> as specified to do.
# requiring building from its json file callList from csv and the output name
# and converting to something we can work with in python.
# """
building = jsonBuildingToObj(sys.argv[1])
callsList = csvToList(sys.argv[2])
allocate(callsList, building.elevators)
writeOutPutFile(callsList, sys.argv[3])
class Elevator:
def __init__(self, id: int,
speed: float,
minFloor: int,
maxFloor: int,
closeTime: float,
openTime: float,
startTime: float,
stopTime: float) -> None:
self.id = id
self.speed = speed
self.minFloor = minFloor
self.maxFloor = maxFloor
self.closeTime = closeTime
self.openTime = openTime
self.stopTime = stopTime
self.startTime = startTime
class ElevatorCall:
def __init__(self,
strElevatorCall: str,
timeStamp: float,
sourceOfCall: int,
destinationOfCall: int,
stateOfElevator: int,
idChosenElev: int) -> None:
self.strElevatorCall = strElevatorCall
self.timeStamp = timeStamp
self.sourceOfCall = sourceOfCall
self.destinationOfCall = destinationOfCall
self.stateOfElevator = stateOfElevator
self.idChosenElev = idChosenElev
import json
import csv
from Building import Building
from ElevatorCall import ElevatorCall
# from pathlib import Path
# data_folder = Path("./Outputs")
def jsonBuildingToObj(jsonBuilding: str):
"""
Traversy Media pyhton crash course
https://youtu.be/JJmcL1N2KQs startig from 1:26:17 he starts talking about working with files
:param callFile:
:return: calls tyoe : list
"""
try:
file = open(jsonBuilding, "r+")
buildingDict = json.load(file)
file.close()
return Building(buildingDict['_minFloor'], buildingDict['_maxFloor'], buildingDict['_elevators'])
# for some reason spread operator not working: return Building(**buildingDict)
except IOError as e:
print(e)
def csvToList(callFile: str):
"""
acording to amichai in his youTube video
https://www.youtube.com/watch?v=AgzaJpptbHE&ab_channel=CoreySchafer
we also watched Traversy Media pyhton crash course
https://youtu.be/JJmcL1N2KQs startig from 1:26:17 he starts talking about working with files
:param callFile:
:return: calls tyoe : list
"""
try:
calls = []
with open(callFile) as file:
csvReader = csv.reader(file)
for row in csvReader:
elevatorCall = ElevatorCall(
strElevatorCall=str(row[0]),
timeStamp=float(row[1]),
sourceOfCall=int(row[2]),
destinationOfCall=int(row[3]),
stateOfElevator=int(row[4]),
idChosenElev=int(row[5])
)
calls.append(elevatorCall)
return calls
except IOError as e:
print(e)
def writeOutPutFile(csvList: list, outPutName: str):
"""
acording to amichai in his youTube video
https://www.youtube.com/watch?v=AgzaJpptbHE&ab_channel=CoreySchafer starting from minute 18:40
there is a spesific way to write, we need to use the __dict__ method in order to be able to
write the calls back to the csv file, so we worked according to the instructions.
:param csvList:
:param outPutName:
:return: void
"""
# file_to_open = data_folder / outPutName
newCallList = []
for call in csvList:
newCallList.append(call.__dict__.values())
with open(outPutName, 'w', newline="") as outPutFile:
csvWriter = csv.writer(outPutFile)
csvWriter.writerows(newCallList)
from Elevator import Elevator
class Building:
def __init__(self, minFloor: int, maxFloor: int, elevators: list) -> None:
self.minFloor = minFloor
self.maxFloor = maxFloor
self.elevators = []
for elevator in elevators:
elv = Elevator(elevator['_id'],
elevator['_speed'],
elevator['_minFloor'],
elevator['_maxFloor'],
elevator['_closeTime'],
elevator['_openTime'],
elevator['_startTime'],
elevator['_stopTime']
)
self.elevators.append(elv)