【问题标题】:Python - Check if two trips(dates) overlap [closed]Python - 检查两次旅行(日期)是否重叠[关闭]
【发布时间】:2015-04-17 17:52:27
【问题描述】:

我必须使用我已经编写的方法检查两次行程是否重叠。除了我自己的 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()

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

【问题讨论】:

  • “不太正确”?!帮我一个忙……
  • 请给我们一个minimal, complete, verifiable example。这意味着 (a) 不是所有代码,仅足以重现问题,以及 (b) 解释“它不能正常工作”的含义——例如,具有预期和实际答案的测试用例,以及原因你认为你的代码应该给出预期的答案,理想情况下,根据你已经完成的任何调试,你认为它可能出错的地方。
  • 我只添加了所有这些以显示我有哪些比较日期的选项。
  • 但是同时,如果你能得到每次旅行的第一个和最后一个日期,或者如果你能得到每次旅行的第一个日期和持续时间以及任何两个日期之间的差异,你就不需要迭代所有的日子;如果trip2在trip1期间开始或结束,反之亦然,它们重叠。

标签: python class methods


【解决方案1】:

让我们暂时忘记日期和行程对象的详细信息,看看如何检查两个范围是否重叠。

如果它们重叠,则以下一项或多项必须为真:

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

还有其他等效的公式,其中一些可能对您的用例感觉更自然或更有效(这可能并不重要);请仔细考虑并选择对您有意义的那个。

您可以将其翻译成 Python,如下所示:

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

当然,实际细节会根据您的边界条件略有不同(您的范围是封闭的还是半开放的;如果是半开放的,边缘日是否与其自身重叠* ),但这应该足以让您入门。

现在,回到你的课堂。有没有办法获得每次旅行的开始和结束日期?如果是这样,您应该可以轻松编写。

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


* 当您考虑这些边界情况时,现在是编写单元测试的好时机。最好自己测试一下,而不是上交作业并为一个你没有想到的案例打分。 (或者,现实世界中的等价物,发布程序,然后不得不熬夜在周五调试并发布一个快速补丁,因为您为所有用户破坏了您的程序。)

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多