divmod
同じ割り算を 2 回書いている
友だち 3 人で 1000 円ぶんのお菓子を割り勘するとき、知りたいのは「1 人いくらか」と「いくら余るか」の 2 つです。第 3 章の道具だけで書くと、// と % で同じ割り算を 2 回することになります。
Python には、この 2 つを 1 回で返す組み込み関数 divmod があります。
Python
hour, minute = divmod(170, 60)
print(hour, minute)2 50 が出ます。170 分は 2 時間 50 分だと 1 行で分かりました。前回学んだ複数の戻り値の実物が、標準の関数として最初から用意されているわけです。
返ってくるのは 2 つ組
divmod が返すのはタプルで、前が商、うしろが余りです。前回と同じくアンパックで 2 つの変数に分けられます。この学習環境の判定はリスト形式なので、演習では受け取ったあとにリストへ入れ直して返します。
// と % を 2 回書くのと、答えはまったく同じです。違いは 2 つあります。1 つは意図が伝わることで、divmod と書いてあれば「商と余りをセットで使う」とすぐ分かります。もう 1 つは、割り算を 1 回で済ませていることです。
引数の順番を逆にすると、エラーは出ないのに答えだけが変わります。divmod(3, 1000) は商が 0、余りが 3 です。割られる数が先、割る数があと、という並びは // や % と同じです。
商と余りをセットで使う場面は、割り勘のほかにもたくさんあります。秒を分と秒に、分を時間と分に、個数を箱と端数に。形が同じなら、同じ道具が使えます。
人数が 0 のとき
人数が 0 のとき、divmod は ZeroDivisionError になってプログラムが止まります。人数は外から来る値なので、0 が来ないという保証はどこにもありません。
前回と同じで、危ない入力は関数の入口で弾きます。0 以下が来たときに何を返すかを先に決めておけば、そのあとの行は安心して書けます。
割り算を書いたら、その場で「0 が来たらどうなるか」を考えます。あとから思い出すことは、まずありません。
やってみよう
関数 split_even(total, people) を実装してください。合計金額 total を people 人で割り勘したときの [1人ぶんの金額, 余り] というリストを return します。
商と余りは divmod で求めます。people が 0 以下のときは [0, 0] を返します。
手元では split_even(1000, 3) を実行して [333, 1] になることと、333 * 3 + 1 が 1000 に戻ることを確かめてみてください。
要件
- 関数名は split_even で、引数は total と people の 2 つ
- 戻り値は [1人ぶんの金額, 余り] のリスト
- divmod を使って商と余りを求める
- people が 0 以下のときは [0, 0] を返す
入出力例
split_even(1000, 3) → [333,1]
split_even(1200, 4) → [300,0]
split_even(500, 3) → [166,2]
split_even(0, 5) → [0,0]
split_even(1000, 0) → [0,0]