Пример #1
0
class Appointment(object):
    """
    An encounter with fixed start and end times, and one patient
    """
    def __init__(self, idnum, start, duration_in_mins, patient, location,
                 priority, provider, interpreter):
        """
        Initialize the Appointment class
        :param idnum: An integer representing the appointment id number
        :param start: A Time object of the appointment start time
        :param duration_in_mins: The minutes from appointment start to finish
        :param patient: A string representing patient name
        :param location: A string representing the title of the location
        :param priority: A number for the appointment weight
        :param provider: A string representing the provider name
        :param interpreter: A string representing the interpreter name
        """
        self.idnum = idnum
        self.start = Time(start, TIME_FORMAT)
        self.duration = duration_in_mins
        self.finish = Time(start, TIME_FORMAT)
        self.finish.add_time(hours=0, minutes=duration_in_mins)
        self.patient = patient
        self.location = location
        self.priority = priority
        self.provider = provider
        self.interpreter = interpreter
        self.late_allowed = 0

    def brief(self):
        """
        Returns a briefer representation of class methods than __str__
        :return: String
        """
        temp_str = ""
        separator_char = "|"
        properties_lst = [
            self.idnum, self.start, self.finish, self.patient,
            self.location.coordinates, self.interpreter
        ]
        num_iterated = 0
        for val in properties_lst:
            if len(temp_str) < 1:
                temp_str = str(val)
            else:
                temp_str += str(val)
            if num_iterated < (len(properties_lst) - 1):
                temp_str += separator_char
            num_iterated += 1
        return temp_str

    def copy(self):
        return copy.deepcopy(self)

    def distance_from(self, other):
        """
        Distance from another Appointment using Pythagorean distance formula
        :param other: Another Interval object compared to self
        :return: A float representing distance
        """
        dist = self.location.distance_from(other.location)
        return dist

    def overlaps_with(self, other):
        appts = sorted([self, other])
        return appts[0].finish <= appts[1].start

    def is_compatible(self, other):
        return self.overlaps_with(other)

    def is_compatible_arrival(self, other):
        """
        Test whether self and other are not overlapping appointments
        :param other: An Appointment object
        :return: Boolean indicating if they're compatible
        """
        appts = [self, other]
        appts.sort(key=attrgetter('start'), reverse=False)
        first_appt = appts[0]
        second_appt = appts[1]
        arrival_time = calc_arrival(first_appt, second_appt)
        second_time = second_appt.start.copy()
        second_time.add_time(hours=0, minutes=self.late_allowed)
        return arrival_time <= second_time

    def calc_prior(self, others):
        lst = copy.deepcopy(others)
        lst.sort(key=attrgetter('finish'), reverse=False)
        finish = [other.finish for other in others]
        pos = bisect.bisect(finish, self.finish)
        valid_others = [
            other for other in others[:pos] if other.finish <= self.start
        ]
        if valid_others:
            return valid_others[-1]

    def get_prior_num(self, others):
        """
        Handle output of calc_prior, coercing None to 0
        :param others: a list of Interval objects
        :return: An integer idnum
        """
        prior = self.calc_prior(others)
        if prior is None:
            prior_num = 0
        else:
            # prior_num = others.index(prior)
            prior_num = prior.idnum
        return prior_num

    def __str__(self):
        temp_str = ""
        delimiter = "|"
        num_keys_iterated = 0
        attributes = self.__dict__
        for key, val in attributes.items():
            if len(temp_str) < 1:
                temp_str = str(val)
            else:
                temp_str += str(val)
            if num_keys_iterated < (len(attributes) - 1):
                temp_str += delimiter
            num_keys_iterated += 1
        return temp_str

    def __eq__(self, other):
        if not isinstance(other, Appointment):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        if not isinstance(other, Appointment):
            return True
        return self.__dict__ != other.__dict__

    def __lt__(self, other):
        """
         Facilitate sorting by start times by comparing Time objects
         :param other: Another Interval object
         :return: Boolean indicating comparison result
        """
        if not isinstance(other, Appointment):
            raise TypeError("'<' not supported between instances of '" +
                            typedef(self) + "' and other types")

        return self.start < other.start