Beispiel #1
0
def headerWriter(newFileType, fileDict, newFileName):
    """
    Updates the input file header and writes it on the desired new file.
    Requires: newFileType argument to be a string and to either be "Drones" or "Timetable". fileDict argument to be a dictionary containing the names of the input files. newFileName to be a string representing the name of the new file that is going to be written on.
    Ensures: updated header lines are written on the designated new file.
    """

    originalFile = fileDict["droneFile"]
    date = r.readHeader(originalFile)[c.headerDate]
    time = r.readHeader(originalFile)[c.headerTime]
    updatedTime = time
    company = r.readHeader(originalFile)[c.headerCompany]
    if newFileType == "Drones":
        updatedTime = str(t.FileNameTimeUpdate(time, 30))

    if t.FileNameTimestampConverter(
            updatedTime) > t.FileNameTimestampConverter("23h59"):
        updatedDate = t.FileNameDateUpdate(date)
    else:
        updatedDate = date

    newFile = open(newFileName, "a")
    newFile.write("Time:\n")
    newFile.write(updatedTime + "\n")
    newFile.write("Day:\n")
    newFile.write(updatedDate + "\n")
    newFile.write("Company:\n")
    newFile.write(company + "\n")
    if newFileType == "Drones":
        newFile.write("Drones:\n")
    if newFileType == "Timetable":
        newFile.write("Timeline:\n")
    newFile.close()
Beispiel #2
0
def timetableFileMaker(fileDict):
    """
    Creates timetable file and returns it's name.
    Requires: fileDict to be a dictionary containing the names of the input files.
    Returns: the timetable file's name.
    """

    originalFile = fileDict["parcelFile"]

    date = r.readHeader(originalFile)[c.headerDate]
    time = r.readHeader(originalFile)[c.headerTime]

    # simplifying date

    if len(date) == 9:
        Day = date[:1]
        Year = date[5:9]
        Month = date[2:4]

    elif len(date) == 10:
        Day = date[:2]
        Year = date[6:10]
        Month = date[3:5]

    updatedFileName = "timetable{0}h{1}_{2}y{3}m{4}.txt".format(
        time[:2], time[3:5], Year, Month, Day)

    updatedFile = open(updatedFileName, "w")
    updatedFile.close()

    return updatedFileName
Beispiel #3
0
def writeTimeTable(parcelsFile, dronesFile):
    file = open('timetableTest.txt', 'w')
    for item in rf.readHeader(parcelsFile):
        file.write(str(item) + '\n')
    file.write('Timeline:' + '\n')
    for item in org.match(parcelsFile, dronesFile):
        for i in item:
            file.write(str(i) + ' ')
        file.write('\n')

    file.close()
Beispiel #4
0
def droneFileMaker(fileDict):
    """
    Creates new drone file and returns it's name.
    Requires: fileDict to be a dictionary containing the names of the input files.
    Returns: the new drone file's name.
    """

    originalFile = fileDict["droneFile"]

    date = r.readHeader(originalFile)[c.headerDate]
    updatedDate = date
    time = r.readHeader(originalFile)[c.headerTime]
    updatedTime = str(t.FileNameTimeUpdate(time, 30))

    if t.FileNameTimestampConverter(
            updatedTime) > t.FileNameTimestampConverter("23h59"):
        updatedDate = t.FileNameDateUpdate(date)

    # simplifying updatedDate

    if len(date) == 9:
        updatedDay = updatedDate[:1]
        updatedYear = updatedDate[5:9]
        updatedMonth = updatedDate[2:4]

    elif len(date) == 10:
        updatedDay = updatedDate[:2]
        updatedYear = updatedDate[6:10]
        updatedMonth = updatedDate[3:5]

    updatedFileName = "drones{0}h{1}_{2}y{3}m{4}.txt".format(
        updatedTime[:2], updatedTime[3:5], updatedYear, updatedMonth,
        updatedDay)

    updatedFile = open(updatedFileName, "w")
    updatedFile.close()

    return updatedFileName
Beispiel #5
0
def headerWriter(originalFileNames, newFileNames):
    """
    Given the names of the original input files and the names of the new files, writes the header for the two new files.
    Requires: originalFileNames is a FileNames object containing the names of the two input files. newFileNames is a 
    FileNames object containing the names of the two new files (drones and timetable).
    Ensures: a corresponding updated header is written in each of the updated files.

    """
    newFileNameTuple = (newFileNames.getDroneFileName(),
                        newFileNames.getParcelFileName())
    originalFile = originalFileNames.getDroneFileName()

    for fileName in newFileNameTuple:
        header = r.readHeader(originalFile)
        date = header.getDate()
        time = header.getTime()
        company = header.getCompany()

        # updating time and date to day after if updated drone time is past 20:00

        if "drone" in fileName:
            time = t.updateTime(time, 30)
            if t.hourToDatetime(time) > t.hourToDatetime("20h00"):
                time = "08h00"
                date = t.updateDate(date, 1)

        if "drone" in fileName:
            scope = "Drones:"
        if "timetable" in fileName:
            scope = "Timeline:"

        newFile = open(fileName, "a")
        newFile.write("Time:\n")
        newFile.write(time + "\n")
        newFile.write("Day:\n")
        newFile.write(date + "\n")
        newFile.write("Company:\n")
        newFile.write(company + "\n")
        newFile.write(scope + "\n")
        newFile.close()
Beispiel #6
0
def FileMaker(FileNameCombo):
    """
    Creates the files where the updated data will be placed.
    Requires: FileNameCombo is a FileNames object containing the names of the original input files.
    Ensures: creation of two new files with the new correct names.
    """

    droneFileName = FileNameCombo.getDroneFileName()
    parcelFileName = FileNameCombo.getParcelFileName()

    ################################################# CREATING PARCEL FILE

    droneDate = r.readHeader(droneFileName).getDate()
    updatedDroneDate = droneDate
    time = r.readHeader(droneFileName).getTime()
    updatedDroneTime = str(t.updateTime(time, 30))

    if t.hourToDatetime(updatedDroneTime) > t.hourToDatetime("20:00"):
        updatedDroneTime = "08h00"
        updatedDroneDate = t.updateDate(droneDate, 1)

    # breaking down dates into separate day, year and month parts

    if updatedDroneDate[1] == "-" or updatedDroneDate[2] == "-":
        updatedDroneDay = updatedDroneDate.split("-")[0]
        updatedDroneYear = updatedDroneDate.split("-")[2]
        updatedDroneMonth = updatedDroneDate.split("-")[1]

    else:
        updatedDroneDay = updatedDroneDate.split("-")[2]
        updatedDroneYear = updatedDroneDate.split("-")[0]
        updatedDroneMonth = updatedDroneDate.split("-")[1]

    if updatedDroneDay[0] == "0":
        updatedDroneDay = updatedDroneDay[1]

    # formatting new file's name

    updatedDroneFileName = "drones{0}h{1}_{2}y{3}m{4}.txt".format(
        updatedDroneTime[:2], updatedDroneTime[3:5], updatedDroneYear,
        updatedDroneMonth, updatedDroneDay)

    updatedDroneFile = open(updatedDroneFileName, "w")
    updatedDroneFile.close()

    ################################################# CREATING PARCEL FILE

    parcelDate = r.readHeader(parcelFileName).getDate()
    parcelTime = r.readHeader(parcelFileName).getTime()

    # breaking down date into separate day, year and month parts

    if parcelDate[1] == "-" or parcelDate[2] == "-":
        updatedParcelDay = parcelDate.split("-")[0]
        updatedParcelYear = parcelDate.split("-")[2]
        updatedParcelMonth = parcelDate.split("-")[1]

    else:
        updatedParcelDay = parcelDate.split("-")[2]
        updatedParcelYear = parcelDate.split("-")[0]
        updatedParcelMonth = parcelDate.split("-")[1]

    # formatting new file's name

    updatedParcelFileName = "timetable{0}h{1}_{2}y{3}m{4}.txt".format(
        parcelTime[:2], parcelTime[3:5], updatedParcelYear, updatedParcelMonth,
        updatedParcelDay)

    updatedParcelFile = open(updatedParcelFileName, "w")
    updatedParcelFile.close()

    return FileNames(updatedDroneFileName, updatedParcelFileName)
Beispiel #7
0
def allocate(fileNameDrones, fileNameParcels):
    """
    Assign given drones to given parcels.
    
    Requires: fileNameDrones, fileNameParcels are str, with the names
    of the files representing the list of drones and parcels, respectively,
    following the format indicated in the project sheet.
    Ensures: Two output files, respectively, with the listing of scheduled
    transportation of parcels and the updated listing of drones, following the format
    and naming convention indicated in the project sheet.
    """
    fileNameDate = fileNameDrones[20:].strip(".txt") + "-" + fileNameDrones[17:19] + "-" + fileNameDrones[12:16]
    fileNameHour = fileNameDrones[6:8] + ":" + fileNameDrones[9:11]

    droneList = readFiles.readlistdrones(fileNameDrones)  # this is the list of the drones from the drone file
    parcelsList = readFiles.readlistparcels(fileNameParcels)  # this is the list of the parcels from the parcel file
    header = readFiles.readHeader(fileNameDrones)
    droneAssignment = []  # this will be the list of parcels with assigned drones that will be sent to the timetable
    droneAssignmentCancelled = []  # this will be the list of cancelled parcels that will be sent to the timetable

    for i in parcelsList:
        # assign the available drones for each delivery
        availableDroneList = []
        for d in droneList:
            if constants.getLocationParcel(i) == constants.getLocationDrone(d):   # the drone must be located in the
                # same zone as the request
                totalDistance = int(constants.getDistanceParcel(i))*2
                droneRange = float(constants.getMaxDistanceDrone(d))*1000
                if totalDistance <= droneRange:  # the drone must have enough range to get to the request location
                    # and come back
                    packageWeight = int(constants.getWeightParcel(i))
                    droneMaxWeight = int(constants.getMaxWeightDrone(d))
                    if packageWeight <= droneMaxWeight:  # the drone must be able to take the weight of the package
                        deliveryDistance = int(constants.getDistanceParcel(i))
                        droneMaxDistance = int(constants.getMaxDistanceDrone(d))
                        if deliveryDistance <= droneMaxDistance:  # the distance of the request can't be bigger than
                            # the drone's max distance
                            availableDroneList.append(d)  # if it meets all these requirements, the drone is assigned
                            # to its respective parcel

        delivery = []
        if len(availableDroneList) == 1:  # if there is only one drone assigned then that will be the drone to use
            delivery = availableDroneList[0].copy()
        elif len(availableDroneList) > 1:  # if there is more than one drone assigned we have to pick only one
            delivery = organize.untieDrones(availableDroneList).copy()  # unties the drones and picks the winner

        if delivery:  # if there is an assigned drone
            # The delivery date/hour will the the latest one between the request date/hour and the drone availability
            if dateTime.getHours(constants.getHourDrone(delivery)) < dateTime.getHours(constants.getHourParcel(i)):
                delivery[7] = constants.getHourParcel(i)
            elif dateTime.getHours(constants.getHourDrone(delivery)) == dateTime.getHours(constants.getHourParcel(i)):
                if dateTime.getMinutes(delivery[7]) < dateTime.getMinutes(constants.getHourParcel(i)):
                    delivery[7] = constants.getHourParcel(i)

            # we need to verify if the time needed to deliver the parcel exceeds the closing time (20:00)
            # if it does, then the date/time is set to the next day at the opening time (08:00)
            delivery[6] = dateTime.finalDateTimeCustomer(constants.getDateDrone(delivery), constants.getHourDrone(delivery), constants.getTimeParcel(i))[0]
            delivery[7] = dateTime.finalDateTimeCustomer(constants.getDateDrone(delivery), constants.getHourDrone(delivery), constants.getTimeParcel(i))[1]

            # now we assign the date, hour, name of the parcel and name of the drone assigned to a new list
            # this will be the list that will be sent to the timetable
            droneAssignment.append([constants.getDateDrone(delivery), constants.getHourDrone(delivery), constants.getNameParcel(i), constants.getNameDrone(delivery)])

            # now we need to update the mileage and range on the drone assigned
            newMileage = float(constants.getMileageDrone(delivery)) + (float(constants.getDistanceParcel(i))*2)/1000
            newRange = float(constants.getRangeDrone(delivery)) - (float(constants.getDistanceParcel(i))*2)/1000

            # here we're going to search for every drone on the drone list for the one that was assigned to the delivery
            # and update its available date, time, mileage and range
            for d in droneList:
                if constants.getNameDrone(delivery) == constants.getNameDrone(d):
                    d[6] = dateTime.finalDateTime(constants.getDateDrone(delivery), constants.getHourDrone(delivery), constants.getTimeParcel(i))[0]  # date
                    d[7] = dateTime.finalDateTime(constants.getDateDrone(delivery), constants.getHourDrone(delivery), constants.getTimeParcel(i))[1]  # time
                    d[4] = round(newMileage, 1)  # mileage
                    d[5] = round(newRange, 1)  # range

        else:  # if no drone was assigned to the delivery we're going to join the parcel to the cancelled list
            droneAssignmentCancelled.append([constants.getDateParcel(i), constants.getHourParcel(i), constants.getNameParcel(i), "cancelled"])

    # now we need to order these lists
    # the parcel list will be ordered by assigned date/hour and lexicographically, both ascending
    droneAssignment = organize.orderTimetable(droneAssignment, droneAssignmentCancelled)
    # the drone list will be ordered by availability, remaining range and lexicographically, all ascending
    droneList = organize.orderDroneList(droneList)

    # finally, these tables are sent to the functions that create the output files
    writeFiles.writeTimetable(header, droneAssignment, fileNameDate, fileNameHour)
    writeFiles.writeDroneList(header, droneList, fileNameDate, fileNameHour)
Beispiel #8
0
    # now we need to order these lists
    # the parcel list will be ordered by assigned date/hour and lexicographically, both ascending
    droneAssignment = organize.orderTimetable(droneAssignment, droneAssignmentCancelled)
    # the drone list will be ordered by availability, remaining range and lexicographically, all ascending
    droneList = organize.orderDroneList(droneList)

    # finally, these tables are sent to the functions that create the output files
    writeFiles.writeTimetable(header, droneAssignment, fileNameDate, fileNameHour)
    writeFiles.writeDroneList(header, droneList, fileNameDate, fileNameHour)


inputFileName1, inputFileName2 = sys.argv[1:]

try:
    headerDrones = readFiles.readHeader(inputFileName1)
    headerParcels = readFiles.readHeader(inputFileName2)

    # these lines will extract the date and time from the file names
    # this is done by slicing the string to get only the relevant information
    droneFileNameHour = inputFileName1[6:8] + ":" + inputFileName1[9:11]
    droneFileNameDate = inputFileName1[20:].strip(".txt")+ "-" + inputFileName1[17:19] + "-" + inputFileName1[12:16]
    parcelsFileNameHour = inputFileName2[7:9] + ":" + inputFileName2[10:12]
    parcelsFileNameDate = inputFileName1[20:].strip(".txt") + "-" + inputFileName1[17:19] + "-" + inputFileName1[12:16]

    # the program runs two assertion tests to make sure the header info is consistent with the file name info
    # if not, it throws an input error
    assert droneFileNameDate == constants.getDateHeader(headerDrones) and droneFileNameHour == constants.getHourHeader(headerDrones), "Input error: name and header inconsistent in file " + inputFileName1 + "."
    assert parcelsFileNameDate == constants.getDateHeader(headerParcels) and droneFileNameHour == constants.getHourHeader(headerParcels), "Input error: name and header inconsistent in file " + inputFileName2 + "."

    # the program runs one more assertion test to make sure the headers from the drones and parcels files are consistent