うるう年を判定するプログラムを作ろう

学習の目的

  • うるう年を正しく判定できる条件式が作成できる

うるう年を判定するプログラム

ある西暦年がうるう年であるかどうかを調べるプログラムを作成します。

うるう年を判定するプログラムは、日時を計算するときには必要となる処理です。

うるう年になる条件って知ってますか?

えーっと、オリンピックのある時だったかな?

知ってます!4年に一回です。

亜美さん、よくわかりましたね。うるう年は4年に1回あります。

確かに夏のオリンピックの時はうるう年ですが、夏季五輪の有無ではなく、年の数値から判定できる規則を使いましょう。

うるう年は「4の倍数の年」が候補です(例:2016、2020、2024)。
しかし、単純に「4の倍数の年すべて」がうるう年というわけではありません。

例えば、西暦2000年はうるう年ですが、西暦1900年は4の倍数であるにもかかわらず、うるう年ではありません。
つまり、正しくうるう年を判定するには「4の倍数かどうか」だけでなく、後で説明する 例外(100年・400年の規則) にも注意する必要があります。

ここからは、条件を少しずつ追加しながら、うるう年かどうかを判定するプログラムを完成させていきます。
まずは最初の条件、「西暦年が4で割り切れるかどうか」 を調べるところから始めましょう。


西暦年が4で割り切れるかどうか調べるプログラム

Pythonで4で割り切れるかどうかってどうやって判定しますか?

4で割り切れるってことは、4で割ったときに余りが0ということですよね。

そうです。

Pythonには余りを求める演算子がありましたが、覚えてますか?

えーっと・・・なんだっけな。

あっ!「%」です。たしか「剰余」という演算子だった!

よく覚えてましたね。余りを求める演算子「%」を使って4の倍数か調べる手順をフローチャートにしてみましょう。

次のフローチャートは西暦年(変数 year)が4で割り切れるかどうか調べるためのフローチャートで、4で割り切れるときは「うるう年」、そうでない場合はうるう年ではないので「平年」と表示します。
例として変数 year に2000を代入しています。

フローチャートには「条件①」が空欄になっており、ここに入れる条件式を考えます。

西暦年が4で割り切れるかを調べるには、次の手順で考えます。

1. year を4で割り余りを求める

2. 余りが0かどうかを比較する

この2つの処理は計算式を条件の中に記述することで1つの文にまとめることができます。

「1. year を4で割り余りを求める」と「2. 余りが0かどうかを比較する」を1つにまとめた条件式は次のように記述します。

year % 4 == 0

この条件式は、yearを4で割った余りの計算「year % 4」の結果を「== 0」で「0」と比較することで、「0」と一致すれば 4 で割り切れる値と判定しています。

条件式をフローチャートに当てはめると次のようになります。

Pythonでは次のように記述します。プログラムはリンクから「Google Colab」を開き実行して確かめましょう。

year = 2000
if year % 4 == 0:
  print("うるう年")
else:
  print("平年")

プログラムはGoogle Colabで実行しましょう。西暦2000年はうるう年なので、「うるう年」と表示されます。

これで4年ごとにうるう年の判定は出来るようになりましたが、うるう年かどうかは、もう少し複雑な条件があります。

条件を付け足して、正しく判定できるようにしていきましょう。

うるう年の判定をするプログラムを完成させよう

うるう年の判定は実は4で割り切れるだけではありません。4で割り切れる年でもうるう年ではない年もあります。

うるう年を正しく判定するには次の条件が必要です。

うるう年の判定条件

  • 条件1 4年ごとにうるう年
  • 条件2 100年ごとにうるう年ではなく平年
  • 条件3 400年ごとにうるう年

うーん・・・よくわからないです。

ややこしいですよね。

西暦年が4で割り切れれば「うるう年」なのですが、100年ごとに「うるう年」ではなくなるので西暦100年、200年、300年は4で割れますが「うるう年」ではなく「平年」です。

ただし、400年ごとに「うるう年」になるので、西暦400年は100で割れますが「うるう年」です。

今のプログラムは条件1だけってことですよね?

そうです。それでは条件2から1つずつ条件を追加しましょう。

条件2 「100年ごとにうるう年ではなく平年」を追加する

条件2は「100年ごとにうるう年ではない」という条件です。ここで100年ごとという判定をするには、「100 で割って余りが 0 である」という条件式が必要です。

次のフローチャートを見てみましょう。

条件②にはどんな条件が入ると思いますか?

「year % 4 == 0」がYesのときの条件なので、4で割り切れた後の処理ということですよね。

4で割り切れた後は、100で割り切れるかどうか判定をしなければなりません。

ただし、注意が必要です。フローチャートの②をよく見ると、②の条件が Yes の時に「うるう年」と表示しています。

えーっと、100年、200年はうるう年ではなかったから、100で割り切れなかった時が「うるう年」。

ということは、②の条件は「year が 100 で割り切れない時に真」になるような条件式を入れればよいのか!

よく考えられましたね。

条件②は「year が 100 で割り切れない時に真」になる条件式が入ります。

「year % 100 == 0」は 100 で割り切れるときに真です。これを変更して②にあてはまる条件式を埋めてみましょう。
わからない場合はヒントを見てみましょう。

ヒント

「year % 100 == 0」は 100 で割り切れた時に真になります。

今回は 100 で割り切れない場合に真なので、比較演算子の「!=」や論理演算子の「not」を使うと逆の時に真の判定が行われます。

②にあてはまる条件式を記述してください。

続いて、Pythonのプログラムで②の条件部分を完成させて実行してみましょう。

year = 2000
if year % 4 == 0:
  if     ⓶       :
    print("うるう年")
  else:
    print("平年")
else:
  print("平年")

プログラムを実行すると2000年は100で割り切れるので「平年」と表示されます。

条件3 「400年ごとにうるう年」を追加する。

条件2を追加すると西暦2000年は「平年」になります。しかし、実際は「うるう年」です。それは条件3で 400 年ごとにうるう年の条件にあてはまるためです。

400 年ごとということは 400 で割り切れるということです。

また、400で割り切れる数は、4 でも 100 でも割り切れます。そのため 4 で割り切れても、 100 で割り切れても関係なく 400 で割り切れれば「うるう年」になります。

条件3はフローチャートではどの位置に入れるのが良いでしょうか?

100で割り切れた中で、400でも割り切れたものがうるう年だから、100で割り切れたあとのここかな?

私だったらこっちかな?最初に判定しても正しく判定できると思う。

二人ともよく考えてますね。どちらも「year % 4 == 0」を条件に入れれば、正しく実行されますね。

条件③を反映する場合、育人君の方法と亜美さんの方法とのどちらのアルゴリズム選びますか?。
選んだ理由とあわせて答えてください。

選んだアルゴリズムはどちらですか?

選んだ理由を答えてください。
例:○○の方が処理がわかりやすい。○○の方が実行する処理が少ない など思ったことを答えてください。

最大 500 文字

この2つのアルゴリズムをPythonで記述すると次のようになります。

育人君のアルゴリズム

year = 2000
if year % 4 == 0:
  if     ⓶       :
    print("うるう年")
  elif year % 400 == 0:
    print("うるう年")
  else:
    print("平年")
else:
  print("平年")

亜美さんのアルゴリズム

year = 2000
if year % 400 == 0:
  print("うるう年")
elif year % 4 == 0:
  if    ⓶        :
    print("うるう年")
  else:
    print("平年")
else:
  print("平年")

正しくプログラムができていれば、「2000年はうるう年」、「1900年は平年」と表示されます。変数yearの値を変えて実行してみましょう。

※この再現版では提出は行いません(送信先は未接続です)

Well done!

次のステップに進みましょう!

次のステップに進む

← 前のステップにもどる