Python 为什么今天的计数器产生错误的结果?
您好,我是Python的初学者,目前正在PyCharm上使用Python 3.4.1。我最近做了一个项目,计算两个日期之间的天数,但有两个问题Python 为什么今天的计数器产生错误的结果?,python,python-3.x,calendar,pycharm,Python,Python 3.x,Calendar,Pycharm,您好,我是Python的初学者,目前正在PyCharm上使用Python 3.4.1。我最近做了一个项目,计算两个日期之间的天数,但有两个问题 def get_first_day(): while True: try: print('First Date') day = int(input('Day:')) month = int(input('Month:')) year =
def get_first_day():
while True:
try:
print('First Date')
day = int(input('Day:'))
month = int(input('Month:'))
year = int(input('Year:'))
print(day, '/', month, '/', year)
date = [day, month, year * 365]
get_second_day(date)
except ValueError:
print('You were supposed to enter a date.')
def get_second_day(date_1):
while True:
try:
print('Second Date')
day = int(input('Day:'))
month = int(input('Month:'))
year = int(input('Year:'))
print(day, '/', month, '/', year)
date = [day, month, year * 365]
convert_dates_and_months(date_1, date)
except ValueError:
print('You were supposed to enter a date.')
def convert_dates_and_months(date_1, date_2):
days_unfiltered = [date_1[0], date_2[0]]
months_unfiltered = [date_1[1], date_2[1]]
year = [date_1[2], date_2[2]]
date_unfiltered = zip(days_unfiltered, months_unfiltered, year)
for d, m, y in date_unfiltered:
if m in [1, 3, 5, 7, 8, 10, 12]:
a = 31
elif m in [4, 6, 9, 11]:
a = 30
elif m in [2, 0] and int(y) % 4 is 0:
a = 29
else:
a = 28
m *= a
days = list(filter(lambda x: 0 < x < (a + 1), days_unfiltered))
months = list(filter(lambda x: 0 < x < 13, months_unfiltered))
date_1 = [days[0], months[0], year[0]]
date_2 = [days[1], months[1], year[1]]
determine_date_displacement(date_1, date_2)
def determine_date_displacement(date_1, date_2):
full_dates = zip(date_1, date_2)
days = -1
for k, v in full_dates:
days += (int(v) - int(k))
if days < 0:
days *= -1
print(days)
get_first_day()
我知道在2003年9月10日到2006年6月6日之间有1000天的时间,但项目的回报是1087天
如果有人能解释为什么这个项目返回一个错误的数字,以及为什么它要求我在最后再次填写第二个日期,那将是完美的
由于这是我的第一个问题,而且我是Python的初学者,因此,对于这个问题中出现的任何奇怪的措辞/错误做法,我提前表示歉意。问题1:
您的闰年计算已关闭:
闰年是年份%4==0
但仅适用于年份%100==0
除非
它们也是年份%400==0
:
2004,2008,2012 : leap year (%4==0, not %100==0)
1700,1800,1900 : no leap year (%4 == 0 , % 100 == 0 but not %400 == 0)
1200,1600,2000 : leap years (* 1200 theor. b/c gregorian cal start)
问题2:
在您的输入中,您通过365对一年进行预乘,不检查闰年-他们可能有366天,但得到365天-这将导致在计算该闰年的天数(ed)时缺少天数
问题3:
您有一个控制流问题:get\u second\u day()
会重复,因为您会:
get_first_date()
while without end:
do smth
call get_second_date(..)
while without end:
do smth
call some calculation functions
that calc and print and return with None
back in get_second_date(), no break, so back to the beginning
of its while and start over forever - you are TRAPPED
- 在
之后放置一个转换日期和月份(日期1,日期)
,中断
在
获取第二天(…)
建议: 您可以通过减少
get_first_day()
和get_second_day()
之间的重复代码量来简化输入-这遵循了干燥原则(Don'tRepeatY我们自己):
一个更好的解决方案将利用,特别是如果你想处理输入验证和闰年估计,你将需要更多的检查 使用
datetime
模块可以简化这一点:
import datetime
def getDate(text):
while True:
try:
print(text)
day = int(input('Day:'))
month = int(input('Month:'))
year = int(input('Year (4 digits):'))
print(day, '/', month, '/', year)
# this will throw error on invalid dates:
# f.e. 66.22.2871 or even (29.2.1977) and user
# gets a new chance to input something valid
return datetime.datetime.strptime("{}.{}.{}".format(year,month,day),"%Y.%m.%d")
except (ValueError,EOFError):
print('You were supposed to enter a valid date.')
def get_first_day():
return getDate("First Date")
def get_second_day():
return getDate("Second Date")
# while True: # uncomment and indent next lines to loop endlessly
first = get_first_day() # getDate("First Date") and getDate("Second Date")
second = get_second_day() # directly would be fine IMHO, no function needed
print( (second-first).days)
输出:
First Date
Day:10
Month:9
Year (4 digits):2003
10 / 9 / 2003
Second Date
Day:6
Month:6
Year (4 digits):2006
6 / 6 / 2006
1000
读得好:-遵循它,至少可以让您了解控制流问题。我知道您可能想自己动手学习,但我可以建议一种简单的方法:我建议使用库
datetime
及其方便的函数来完成此主题。@JeffProd感谢链接@正如JeffProd所说,我知道datetime,但我从内置创建它只是为了学习。不过还是要谢谢你!另外,arrow
软件包非常有用和快捷
import datetime
def getDate(text):
while True:
try:
print(text)
day = int(input('Day:'))
month = int(input('Month:'))
year = int(input('Year (4 digits):'))
print(day, '/', month, '/', year)
# this will throw error on invalid dates:
# f.e. 66.22.2871 or even (29.2.1977) and user
# gets a new chance to input something valid
return datetime.datetime.strptime("{}.{}.{}".format(year,month,day),"%Y.%m.%d")
except (ValueError,EOFError):
print('You were supposed to enter a valid date.')
def get_first_day():
return getDate("First Date")
def get_second_day():
return getDate("Second Date")
# while True: # uncomment and indent next lines to loop endlessly
first = get_first_day() # getDate("First Date") and getDate("Second Date")
second = get_second_day() # directly would be fine IMHO, no function needed
print( (second-first).days)
First Date
Day:10
Month:9
Year (4 digits):2003
10 / 9 / 2003
Second Date
Day:6
Month:6
Year (4 digits):2006
6 / 6 / 2006
1000