総合 ポイント管理台帳
師範 / 目安 25分
松田さんが、机の上に手書きの帳面を積み上げて言いました。「集大成だ! 会員登録、ポイント付与、ランク一覧、それに保存。全部入りのやつを頼む!」。事務局の10問目、最後の依頼です。
ここまでで、付与の計算、ランクの判定、辞書での集計、ファイルへの保存を、それぞれ別々の道具として作ってきました。最後の課題は、その道具を1つの台帳にまとめることです。完成済みの道具をひな形として渡します。自分で書くのは、それらを正しい順番でつなぐ本体の5行です。
事務局の窓口には、1日ぶんの操作が伝票の束になって届きます。台帳はその束を上から順に処理し、最後に締めの報告を出します。伝票には不備もあります。同じ人が二重に登録されていたり、登録されていない人へ付与が来たりします。不備は落とさず数えて報告するのが事務員の仕事です。名前の検索と不備の判定は、準備済みの apply_operation が担当します。
完成条件
run_ledger(operations) という関数を定義してください。
名前にはカンマや改行を含まないものとします。operations は操作を並べたリストです。1つの操作は [種別, 名前, 値] の3つ組で、種別は次の2つです。
"登録"— その名前の会員を、値を初期ポイントとして台帳の末尾に追加します"付与"— その名前の会員に、値を会計金額としてポイントを足します。付くポイントは 100円で1ポイント、端数は切り捨て です
不備の扱いは次のとおりです。どれも台帳を変えずに読み飛ばし、件数だけ数えます。
- すでに同じ名前が登録されているのに、また
"登録"が来た - 登録されていない名前へ
"付与"が来た - 種別が
"登録"でも"付与"でもない
全部の操作を処理し終えたら、台帳を ledger_final.txt に上書きモードで保存します。1行に1会員、名前,ポイント の形です。保存したらそのファイルを読み直し、読み直したデータをもとに締めの報告を組み立てて返してください。
返す辞書のキーは4つです。
members—{"name": ..., "points": ...}の辞書のリスト。並びは登録した順ranks— ランクごとの人数の辞書。ランクは1000以上が"ゴールド"、500以上が"シルバー"、それ未満が"ブロンズ"。該当者が0人のランクはキーごと入れませんtotal— 全会員の保有ポイントの合計skipped— 読み飛ばした不備の件数
準備済みの道具の受け渡し
| 道具 | 渡す値 | 仕事と戻り値 |
|---|---|---|
| apply_operation | 台帳、操作1件 | 台帳を更新し、成功なら0、不備なら1を返す |
| save_and_load | 台帳 | ledger_final.txt に上書きして読み直し、復元したリストを返す |
| summarize_members | 復元したリスト | ランク人数の辞書と合計を、この順で返す |
| build_report | 復元したリスト、人数、合計、不備件数 | 4つのキーを持つ報告の辞書を返す |
芯は「1件ずつ操作する」と「その結果を次の道具へ渡す」の2か所です。入力のリスト自体を変更する必要はありません。空の操作でも保存と復元、集計、報告まで進めます。
別の題材として、単価に個数を掛け、手数料を加えた結果を次の関数に渡します。
Python
def item_cost(price, quantity):
return price * quantity
def add_fee(cost):
return cost + 20
cost = item_cost(80, 3)
charged = add_fee(cost)
print(charged) # 260関数に渡すのは、前の関数から受け取った値です。順番を逆にすると違う計算になります。値を2つ受け取る例は width, height = [4, 7] です。集計の戻り値もこの書き方で受け取れます。
補助関数の中の None は「該当する値がない」を表します。target is None は見つからなかった場合、target is not None は見つかった場合の判定です。return 0 と return 1 で処理結果を件数として返せば、呼ぶ側は足すだけで不備を数えられます。
集計用の 辞書.get(キー, 0) は、そのキーがないとき0を返します。たとえば stock = {"本": 2} のとき、stock.get("本", 0) は2、stock.get("鉛筆", 0) は0です。問7と違い、今回は0人のランクを辞書に入れないため、この道具を使う集計を準備済みにしています。
進め方
ひな形の「ここに書く」を完成させてください。準備済みのコードはそのまま使えます。手が止まったら、①方針、②使う構文、③部分解の順にヒントを開けます。
数分考えて手が止まったら、①から確認してください。本文の別の題材の例を動かし、今回の値に置き換えて考えましょう。
run_ledger の繰り返しの内側では apply_operation を呼び、戻り値を skipped に足します。繰り返しの外で保存と復元、集計、報告を順に行います。補助関数を書き直す必要はありません。
ランク判定と付与計算は準備済みです。確認するのは、すべての操作が終わってから保存しているか、復元したリストを集計と報告の両方へ渡しているかです。
これで10問すべてです。松田さんは帳面を閉じて、静かに言いました。「商店街のDX、完成や…!」
師範が奥から一枚の紙を持って出てきます。そこには Python道場・師範代を允許する と書かれていました。表示の1行から始めて、いまあなたは小さな道具をつなぎ、人の仕事を引き受けるプログラムの流れを組み立てられます。
要件
- 準備済みの補助関数を使い、run_ledger(operations) の本体だけを完成させること。operations は [種別, 名前, 値] の3つ組のリスト
- 操作を順に apply_operation(members, operation) へ渡し、戻り値を skipped に足すこと。成功は0、不備は1で、台帳の更新は補助関数が行う
- 登録の値は初期ポイント、付与の値は会計金額。二重登録・未登録者への付与・未知の種別は不備として台帳を変えず読み飛ばす。これらは補助関数に用意済み
- すべての操作の後に save_and_load(members) を呼び、ledger_final.txt へ上書き保存して読み直したリストを受け取ること。名前にはカンマや改行を含まない
- 復元したリストを summarize_members に渡し、ランク人数の辞書と合計を受け取ること。1000以上がゴールド、500以上がシルバー、それ未満がブロンズで、0人のランクを含めない集計は準備済み
- 復元したリスト・ランク人数・合計・不備件数を build_report に渡し、members・ranks・total・skipped の4つのキーを持つ辞書を返すこと。members の並びは登録順
ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです