iT邦幫忙

1

Python 閏年計算問題

想請問各位,以下計算閏年的寫法是否有錯誤??
year = eval(input())
if year % 4 ==0 and (year % 100 !=0 or year % 400==0):
print('It is a leap year')
else:
print('It is not a leap year')

謝謝~~~

柯柯 iT邦新手 3 級 ‧ 2019-11-14 13:33:08 檢舉
其實 wiki 有這個問題
https://zh.wikipedia.org/wiki/%E9%97%B0%E5%B9%B4
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
4
Darwin Watterson
iT邦好手 1 級 ‧ 2019-11-13 23:05:28

翻出以前 C 的課本
https://ithelp.ithome.com.tw/upload/images/20191113/20109107w8kp1IHmq1.jpg
是先判斷
能被 4 整除 但不能被 100 整除

再考慮其他的能不能被 400 整除

而你的寫法

year % 4 ==0 and (year % 100 !=0 or year % 400==0)

先排除
不能被 4 整除的
再進一步判斷
能被 4 整除的卻不被 100 整除
或者
能被 4 整除也能被 400 整除
感覺上有點不太一樣, 又好像一樣 /images/emoticon/emoticon06.gif
(1801-2400間的閏年似乎都能被4整除)

dragonH iT邦超人 5 級 ‧ 2019-11-13 23:23:41 檢舉

藍色小本本/images/emoticon/emoticon42.gif

3
paicheng0111
iT邦大師 5 級 ‧ 2019-11-13 23:05:33

印象中應該是這樣

year = int(input())
if (year % 4 ==0 and year % 100 !=0) or year % 400==0:
    print('It is a leap year')
else:
    print('It is not a leap year')

https://snakify.org/en/lessons/if_then_else_conditions/problems/leap_year/ 刷到這題

/images/emoticon/emoticon07.gif

小魚 iT邦大師 1 級 ‧ 2019-11-14 00:09:56 檢舉

感覺起來好像是一樣的結果...

Zed_Yang iT邦新手 3 級 ‧ 2019-11-14 09:54:40 檢舉
a = int(input())
if (a%4==0 and a%100!=0) or (a%400==0):
    print("LEAP")
else:
    print("COMMON")

我的解法跟你一樣~

3

基本上

if year % 4 ==0 and (year % 100 !=0 or year % 400==0):

的確是不太對的。

因為這樣子寫的話。會變成除於4會是必要條件。
但實際上閏年的計算方式。第一優先是只要能除400就算。所以除於400的要先當必要條件
也就是 y%400==0
再來才是能除於4但不能除於100。當條件。
所以就是(y%4==0 and y%100!=0)

區分出來這兩個條件後,只要其中一項有達到。就可以算是閏年。
整合起來就如下

y%400==0 or (y%4==0 and y%100!=0)

而原本的寫法

year%4 ==0 and (year % 100 !=0 or year % 400==0)

認真來說看起來結果好像是一樣的
但如果就依數學論來說。並不是完全正確的。
只是剛好能整除400的值。其實也是可以整除4。所以才會造成一樣的結果。
就程式而言結果是一樣。就數學而言算是大大的錯誤。

所以說。原本的寫法雖然結果是相同。但其實並不能說你是對的。
希望能明白我說的意思。因為在邏輯來說。像這種條件剛好可以雙向認証的機率不大。
但不能保証可不會在其它地方發生問題的。

您說的完全正確,所以我原本的寫法如下:

year = int(input())

if year%400==0:
    print("leap")
elif year%4 ==0 and year%100>0:
    print("leap")
else:
    print("normal")
0
阿展展展
iT邦好手 1 級 ‧ 2019-11-14 06:22:00

並不是全部都寫在一行比較簡潔...

我還是喜歡

if(){
    if(){
        if()
            ...
    }

}

這種感覺QQ

sion iT邦新手 4 級 ‧ 2019-11-14 09:31:54 檢舉

看到

if(){
    if(){
        if()
            ...
    }
}

就想用責任鍊/images/emoticon/emoticon39.gif

/images/emoticon/emoticon36.gif

1
一級屠豬士
iT邦大師 1 級 ‧ 2019-11-14 11:46:16

https://ithelp.ithome.com.tw/articles/10214650

之前剛好有寫一個. 另外有使用 calendar 模組,協助驗證.

def isLeapYear(n):
    year = int(n)
    return (year % 400 == 0) or ((year % 100 != 0) and (year % 4 == 0))
    

ylist = [2000, 1999, 2001, 2004, 1900]

xlist = [(x, isLeapYear(x)) for x in ylist]

import calendar as cal
xlist2 = [(x, cal.isleap(x)) for x in ylist]

>>> print(xlist)
[(2000, True), (1999, False), (2001, False), (2004, True), (1900, False)]

>>> print(xlist2)
[(2000, True), (1999, False), (2001, False), (2004, True), (1900, False)]

這個比較完整。連特規年也出現。這才完美啊!!太強了。

我要發表回答

立即登入回答