获取事件未完成的年数?

2024-09-23 22:22:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做以下编程练习:No musical。声明如下:

In my school, a grand musical is performed every 4 years. This means that every student who comes to this school will get to see a musical performed exactly once in their 4-year stay. This is not always the case in other schools though.

For a given duration of time, an interval after which a musical is performed, and the duration of class enrolment, can you determine how many class-years did not get to have a musical performed in their school? A musical is always performed for the start_class.

Example:

no_musical(start_class = 2000, end_class = 2010,
musical_performed_every = 5, duration_of_enrolment_in_school = 3) = 4

Explanation: Only the class of 2000 gets to see the musical performed in 2000. The next musical will be in 2005 so only the class of 2003 in their last year, 2004 in their second year, and 2005 in their first year, get to see it. The next musical will be in 2010 so only the class of 2008, 2009 and 2010 get to see it. This leaves us with the class of 2001, 2002, 2006 and 2007 who never get to see a musical, a total of 4 classes :(

TO NOTE:

In this kata, if duration of enrolment in school is, say, 4 years, members of a class that starts in 2000 will graduate in 2003, not

2004. Their years of enrolment in the school would be 2000, 2001, 2002 and 2003. (In the standard way that we are used to the term 'class of', they would be the class of 1999 as they would graduate in 2003, but we do not do that here) As seen in the example, the range is end-inclusive. The last class should also be accounted for. Very minor note, we assume all the students in the school will actually go to watch the musical - not that it matters for this kata anyway. That said, I am not really a musical person :-(

5 sample tests, 50 randomized tests.

Good luck.

我们编写了以下Python代码:

import math
def no_musical(start_class, end_class, musical_performed_every, enrolment_duration):
    print("start_class: ",start_class)
    print("end_class: ",end_class)
    print("musical_performed_every: ",musical_performed_every)
    print("enrolment_duration: ",enrolment_duration)
    if(start_class>=end_class): return 0
    if(musical_performed_every==0): return end_class-start_class+1
    if(enrolment_duration>musical_performed_every): return 0
    allCourses=end_class-start_class
    print("allCourses: ",allCourses)
    numberOfMusicals=math.ceil((allCourses)/musical_performed_every)
    print("numberOfMusicals: ",numberOfMusicals)
    coursesWhichSeeMusical=numberOfMusicals*enrolment_duration
    print("coursesWhichSeeMusical: ",coursesWhichSeeMusical)
    coursesWhichNotSeeMusical=allCourses-coursesWhichSeeMusical
    return 0 if coursesWhichNotSeeMusical<0 else coursesWhichNotSeeMusical

有三个测试我们的代码没有给出预期的输出:

# Use test.describe (or Test.describe) to describe your test suite
test.describe("Musicals")

# What if the start and end year are the same?
test.assert_equals(no_musical(2000,2000,100,3), 0)

# What if the school does not do musicals?
test.assert_equals(no_musical(2000,3000,0,50), 1001)

# What if all the students get to see musicals?
test.assert_equals(no_musical(2000,2020,2,4), 0)

# But are you doing it right though?
test.assert_equals(no_musical(2000, 3000, 5, 2), 600)

test.assert_equals(no_musical(2000, 2010, 5, 3), 4)

#our code fails in this test, by 1 year
test.assert_equals(no_musical(2910, 3505, 4, 3), 149)

#our code fails in this test, by 2 years
test.assert_equals(no_musical(2483, 3309, 18, 2), 736)

#our code fails in this test, by 4 years
test.assert_equals(no_musical(2969, 3508, 17, 4), 415)

我们在最后三次测试中观察到以下痕迹:

开始上课:2910 完班:3505 音乐剧每四点演出一次 入学时间:3 所有课程:595 音乐剧数目:149 音乐类课程:447 148应该等于149

起始班:2483 完班:3309 音乐剧表演时间:18 入学时间:2 所有课程:826 音乐剧数量:46部 音乐类课程:92门 734应该等于736

起始班:2969 完班:3508 音乐剧表演时间:17 入学时间:4 所有课程:539 音乐剧数量:32部 音乐类课程:128门 411应等于415

我们读到:

我们如何调试这段代码


Tags: ofthetonointeststartclass
2条回答

从逻辑上讲,这个问题可以直接转化为以下代码,该代码遍历所有的课程年数,并统计那些注册年数不在任何音乐演出年份的学生数:

def no_musical(start_class, end_class, musical_performed_every, enrollment_duration):
    return sum(
        not musical_performed_every or
        all(
            year + i not in range(start_class, end_class + 1, musical_performed_every) 
            for i in range(enrollment_duration)
        ) for year in range(start_class, end_class + 1)
    )

通过以下测试:

assert no_musical(2000,2000,100,3) == 0
assert no_musical(2000,3000,0,50) == 1001
assert no_musical(2000,2020,2,4) == 0
assert no_musical(2000, 3000, 5, 2) == 600
assert no_musical(2000, 2010, 5, 3) == 4
assert no_musical(2483, 3309, 18, 2) == 736
assert no_musical(2969, 3508, 17, 4) == 415

但不是这个:

assert no_musical(2910, 3505, 4, 3) == 149

因为no_musical(2910, 3505, 4, 3)将返回151

我会质疑这个特定的测试用例是否具有正确的预期值

演出的音乐剧数量应为班级年数除以音乐表演频率,四舍五入,而不是向上,因此更改:

numberOfMusicals=math.ceil((allCourses)/musical_performed_every)

致:

numberOfMusicals=math.floor((allCourses)/musical_performed_every)

或者简单地说:

numberOfMusicals = allCourses // musical_performed_every

您将通过除no_musical(2910, 3505, 4, 3) == 149之外的所有测试,因为no_musical(2910, 3505, 4, 3)返回151,而不是预期的149。但由于这与我的另一个答案的结果相匹配,我会质疑这个特定的测试用例是否具有正确的期望值

相关问题 更多 >