Python - 检查两次旅行(日期)是否重叠

时间:2015-04-17 17:52:28

标签: python class methods

我必须使用我已编写的方法检查两次跳闸是否重叠。除了我自己的Date类,我无法导入任何东西。这是我的代码

class Date:
    """
    A class for establishing a date.
    """
    min_year = 1800

    def __init__(self, month = 1, day = 1, year = min_year):
        """
        Checks to see if the date is real.
        """
        self.themonth = month
        self.theday = day
        self.theyear = year
        monthdays = [31, 29 if self.year_is_leap() else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

        if self.themonth < 1 or self.themonth > 12:
            raise Exception("Not a valid month")
        elif self.theday > monthdays[self.themonth-1] or self.theday > 31 or self.theday < 1:
            raise Exception("Not a valid day")
        elif self.theyear < self.min_year:
            self.theyear = self.min_year

    def month(self):
        """
        A function for returning the month of Date.
        """
        return self.themonth

    def day(self):
        """
        A function for returning the day of Date.
        """
        return self.theday

    def year(self):
        """
        A function for returning the year of Date.
        """
        return self.theyear

    def year_is_leap(self):
        """
        Returns true if date is a leap year, false otherwise.
        """
        if self.theyear % 4 == 0 and self.theyear % 100 != 0 or self.theyear %400 == 0:
            return True
        else:
                return False

    def daycount(self):
        """
        Returns the amount of days between two dates.
        """
        counter = 0
        m = Date(self.themonth, self.theday, self.theyear)
        monthdays = [31, 29 if m.year_is_leap() else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

        for x in range(self.min_year, m.theyear):
            y = Date(self.themonth, self.theday, x)
            if y.year_is_leap() == True:
                counter += 366
            else:
                counter += 365
        daysthisyear = self.theday + sum(monthdays[0:self.themonth-1])
        counter += daysthisyear
        return counter

    def day_of_week(self):
        """
        Returns the day of the week for a real date.
        """
        z = Date(self.themonth, self.theday, self.theyear)
        if z.daycount() % 7 == 0: return str('Wednesday')
        if z.daycount() % 7 == 1: return str('Tuesday')
        if z.daycount() % 7 == 2: return str('Monday')
        if z.daycount() % 7 == 3: return str('Sunday')
        if z.daycount() % 7 == 4: return str('Saturday')
        if z.daycount() % 7 == 5: return str('Friday')
        if z.daycount() % 7 == 6: return str('Thursday')

    def __repr__(self):
        """
        Returns the date.
        """
        return '%s/%s/%s' % (self.themonth, self.theday, self.theyear)

    def nextday(self):
        """
        Returns the date of the day after given date.
        """
        m = Date(self.themonth, self.theday, self.theyear)
        monthdays = [31, 29 if m.year_is_leap() else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        maxdays = monthdays[self.themonth-1]

        if self.theday != maxdays:
            return Date(self.themonth, self.theday+1, self.theyear)
        elif self.theday == maxdays and self.themonth == 12:
            return Date(1,1,self.theyear+1)
        elif self.theday == maxdays and self.themonth != 12:
            return Date(self.themonth+1, 1, self.theyear)

    def prevday(self):
        """
        Returns the date of the day before given date.
        """
        m = Date(self.themonth, self.theday, self.theyear)
        monthdays = [31, 29 if m.year_is_leap() else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        if self.theday == 1 and self.themonth == 1 and self.theyear == 1800:
            raise Exception("No previous date available.")
        if self.theday == 1 and self.themonth == 1 and self.theyear != 1800:
            return Date(12, monthdays[11], self.theyear-1)
        elif self.theday == 1 and self.themonth != 1:
            return Date(self.themonth -1, monthdays[self.themonth-1], self.theyear)
        elif self.theday != 1:
            return Date(self.themonth, self.theday - 1, self.theyear)

    def __add__(self, n):
        """
        Returns a new date after n days are added to given date.
        """
        g = self.nextday()
        for x in range(1, n):
            g = g.nextday()
        return g

    def __sub__(self, n):
        """
        Returns a new date after n days are subtracted from given date.
        """
        h = self.prevday()
        for y in range(1,n):
            h = h.prevday()
        return h

    def __lt__(self, other):
        """
        Returns True if self comes before other, False otherwise.
        """
        if self.theyear == other.theyear:
            if self.themonth < other.themonth:
                return True
            elif self.themonth == other.themonth:
                if self.theday < other.theday:
                    return True
                else:
                    return False
            elif self.themonth > other.themonth:
                return False
        if self.theyear < other.theyear:
            return True
        else:
            return False

    def __eq__(self, other):
        """
        Returns True if self and other are the same dates, False otherwise.
        """
        if self.theyear == other.theyear:
            if self.themonth == other.themonth:
                if self.theday == other.theday:
                    return True
        else:
            return False

    def __le__(self, other):
        """
        Returns True if self comes before or is the same as other, False otherwise.
        """
        if self.theyear == other.theyear:
            if self.themonth < other.themonth:
                return True
            elif self.themonth == other.themonth:
                if self.theday < other.theday:
                    return True
                elif self.theday == other.theday:
                    return True
                else:
                    return False
            else:
                return False
        if self.theyear < other.theyear:
            return True
        else:
            return False

    def __gt__(self, other):
        """
        Returns True if self comes after other, False otherwise.
        """
        if self.theyear == other.theyear:
            if self.themonth > other.themonth:
                return True
            elif self.themonth == other.themonth:
                if self.theday > other.theday:
                    return True
                else:
                    return False
            else:
                return False
        if self.theyear > other.theyear:
            return True
        else:
            return False
    def __ge__(self, other):
        """
        Returns True if self comes after or is the same as other.
        """
        if self.theyear == other.theyear:
            if self.themonth > other.themonth:
                return True
            elif self.themonth == other.themonth:
                if self.theday > other.theday:
                    return True
                elif self.theday == other.theday:
                    return True
                else:
                    return False
            else:
                return False
        if self.theyear > other.theyear:
            return True
        else:
            return False

    def __ne__(self, other):
        """
        Returns True if self and other are unequal, False otherwise.
        """
        if self.theyear != other.theyear:
            if self.themonth != other.themonth:
                if self.theday != other.theday:
                    return True
        else:
            return False
    from date import *
class Trip:
    """
    Stores the date and duration of employees' trips.
    """

    def __init__(self, destination = None, depdate=Date(1, 1, 2015), duration=1):
        """
        Set the destination, when, and how long it will be.
        """
        self.thedestination = destination
        self.thedepdate = depdate
        self.theduration = duration

    def setDestination(self, newdestination):
        """
        This function lets the user change the destination.
        """
        self.thedestination = newdestination
        return self.thedestination

    def setDeparture(self, newdeparture):
        """
        This function lets the user change the departure date.
        """
        self.thedepdate = newdeparture
        return self.thedepdate

    def setDuration(self, newduration):
        """
        This function lets the user change the duration.
        """
        self.theduration = newduration
        return self.theduration

    def destination(self):
        """
        This function returns the destination of the trip.
        """
        return self.thedestination

    def departure(self):
        """
        This function returns the destination of the trip.
        """
        return self.thedepdate

    def duration(self):
        """
        This function returns the duration of the trip.
        """
        return self.theduration

    def arrival(self):
        """
        This function returns the date of arrival of a person's trip.
        """
        return self.thedepdate.__add__(self.theduration)

    def overlaps(self, other):
        """
        Returns True if the trips self and other overlap, False otherwise.
        """
        m = Trip(self.thedestination, self.thedepdate, self.theduration)
        g = self.thedepdate
        if self.thedepdate == other.thedepdate:
            return True
        while g != other.thedepdate:
            for x in range(1, self.theduration):
                g = self.thedepdate.nextday()

如您所见,我的最后一个函数是overlapps()方法。我所拥有的就是我想出的东西,但它并不是很正常。显然这是家庭作业,所以我不是在寻找一个勺子喂食的答案,而是解释我如何得出答案。感谢。

1 个答案:

答案 0 :(得分:2)

让我们暂时忘记你的日期和旅行物品的细节,看看如何检查两个范围是否重叠。

如果它们重叠,则必须满足以下一个或多个条件:

  • 第二个范围在第一个范围内开始。
  • 第二个范围在第一个范围内结束。
  • 第二个范围包含第一个范围。

还有其他等效的配方,其中一些可能对您的使用情况感觉更自然或更有效(不是那可能很重要);只要仔细考虑并选择对你有意义的那个。

您可以将其转换为Python,如:

(start1 <= start2 <= end1 or
 start1 <= end2 <= end1 or
 start2 <= start1 and end2 >= end1)

当然,实际细节会略有不同,具体取决于您的边界条件(您的范围是关闭还是半开;如果是半开,边缘日是否与自身重叠 * ),但这应该足以让你开始。

现在,回到你的班级。有没有办法获得每次旅行的开始和结束日期?如果是这样,你应该能够轻松地写出来。

如果没有,如果您可以获得开始日期和持续时间,并且您可以获得两个日期之间的差异,则可以改为使用这些值来重写相同的测试。


*在考虑这些边界情况时,现在是编写单元测试的好时机。最好自己进行测试,而不是上交作业并将其标记为你没想到的案例。 (或者,现实世界相当于,发布程序,然后必须熬夜调试并发布快速补丁,因为你为所有用户打破了你的程序。)