はじめに
これは日本工学院IS科1年1組の方向けの解説です...。もちろん公に投稿しているので非対象者の方も閲覧していただいて結構です。
**課題:Ex1-2-6
**において、疑問が多かったり、授業終わりに質問をくれる方が多かったので簡単に僕のコードを紹介します。紹介するものが完全回答ではありませんが、ご自身のソースコードと見比べてみると面白いかも知れません。
※この課題の提出期限は過ぎていますが、もし再提出がある方はまず自身で考えてみてください。言うまでもなくコピペして提出など以ての他です(ソースコードは個性がでるのでバレるし何より理解にも学びにもならない...)
問題解決にあたって考えること
数学で問題を解くのと似たように、問題解決には手順があります。
- アルゴリズムを考える
- ソースコードに書き落とす
アルゴリズム
金額を入力させ、金種(紙幣、貨幣の種類)がそれぞれ何枚になるかを出力するプログラムを作成してください。
アルゴリズムの部分は、ロジカルな思考が求められます。しかし実のところ、文章に起こしてしまえば簡単に解決しちゃいます。
この課題において達成すべきことは、
「①入力された貨幣を、②金種の額が大きい順に割っていくことで、その金種が何枚必要かをもとめる。ただし③前に大きな金額がある場合は、事前に消費した状態にすることで、前の大きな金額と重複した計算を防ぐ。」ということ。
①、②は理解できている方が多いかと思います。
③の、”前の大きな金額と重複した計算を防ぐ”というのが割とポイントかなと思います。僕が先生であればここも解説します。でも、ここまで読み進めているのは「課題を既に終えている」というのが前提なので、詳しく聞きたければ先生か、授業終わりなどに直接聞きにきてください。
ソースコード
僕はとにかく早く実装したかったので、かなりミニマムなコードになってます。正直実行結果は提示されたフォーマットと若干違っています(大事なのはプロセスと言い聞かせスルー)。
money = int(input('金額を入力してください >> '))
print(f'{money}円は...')
print(f'10000円札は{int(money / 10000)}枚')
money %= 10000
print(f'5000円札は{int(money / 5000)}枚')
money %= 5000
print(f'1000円札は{int(money / 1000)}枚')
money %= 1000
print(f'500円玉は{int(money / 500)}枚')
money %= 500
print(f'100円玉は{int(money / 100)}枚')
money %= 100
print(f'50円玉は{int(money / 50)}枚')
money %= 50
print(f'10円玉は{int(money / 10)}枚')
money %= 10
print(f'5円玉は{int(money / 5)}枚')
money %= 5
print(f'1円玉は{money}枚')
このコードの評価点
print(f'10000円札は{int(money / 10000)}枚')
このコードの特徴はこのように、変数展開(f'◯◯◯'
の部分)の中で除算を行なっていることです。これにより、余計な変数の確保を無くしています。ちなみに、変数の発生はメモリ領域の無駄遣いになりかねないので気をつけましょう...(簡単に言うと、**「変数が多いとプログラム重くなるから気をつけよう」**って感じです)。
あと、計算式(money / 10000
)に対してintメソッド(int関数)を実行しています。これは単純に、除算の結果がfloat型(小数型)で返ってくるので、整数に直しているだけです。
それから変数展開ですが、これは変数の文字列出力の際には必ずと言っていいほど使いましょう。理由は二つあります。一つは、単純に視覚的に理解しやすいからです。もう一つの理由は、皆さんの理解を高めるためにも「変数展開_メリット」などと検索して調べてみましょう(授業でもやったかもだけど)。ちなみに僕はアルバイトインターンでRubyと言う言語でプログラムをしているのですが、業務の場でも変数展開は多用します(僕は+
で文字列繋げたら注意された)
このコードの改善点
5分くらいで出来た即席コードなので突っ込みどころもあります(主に二つ)。
print(f'10000円札は{int(money / 10000)}枚') # 元のコード
print(f'10000円札は{money // 10000}枚') # 修正案
一つめは、変数展開中のintメソッドです。これは小数で返ってくるのを防ぐためでした。しかし、上の2行目にある//
演算子で、**「除算の商を整数で返す」**という意味になります。こっちの方がゴチャゴチャしてなくて見やすいですね。
二つめは、変数money
を直接計算に使ってしまっている点です。どういうことかというと、money
とはそもそも、**「入力された金額」**と言う意味です。もし仮に計算が終わった後になって「入力された金額」のデータが必要になった場合、そのデータはもうどこにもありません。
今回の課題においては考慮する必要はありませんが、大規模なシステムを組む際にはこの書き方はご法度です。改善案としては、money
とは別に、money_calc
(calculation:計算の意)などを用意し、そちらで計算を行う。もしくは、money
の値は更新せず計算するなどすることです。
改善例
「money
の値は更新せず計算する」のやり方は以下の感じです。
money = int(input('金額を入力してください >> '))
print(f'{money}円は...')
print(f'10000円札は{money // 10000}枚')
print(f'5000円札は{(money % 10000) // 5000}枚')
print(f'1000円札は{(money % 5000) // 1000}枚')
print(f'500円玉は{(money % 1000) // 500}枚')
print(f'100円玉は{(money % 500) // 100}枚')
print(f'50円玉は{(money % 100) // 50}枚')
print(f'10円玉は{(money % 50) // 10}枚')
print(f'5円玉は{(money % 10) // 5}枚')
print(f'1円玉は{money % 5}枚')
これなら、money
の値を更新せず計算が行えています。余計な代入処理もないので、コードも短くなりましたね。
ちなみに、for文(繰り返し処理)などを勉強すると、以下のような書き方ができるようになります。プログラミングは先走って損はないので、興味のある人はガンガン予習に使ってください。
money_values = [10000,5000,1000,500,100,50,10,5,1]
money = int(input('金額を入力してください >> '))
print('{}'.format(money))
for v in money_values:
print('{} : {}'.format(v, money // v))
money %= v
おわりに
正直記事の最後の方は難しかったかも知れません。今は全部は理解できなくて大丈夫です。
あと、僕のソースコードをみて、「俺or私のコード全然だめだなぁ」と思う方がいるかも知れませんが、それは違います。先ほども言ったように、ソースコードにはかなり個性が出ます。僕のコードに良いところも悪いところもあるように、それぞれ評価すべきポイントがあります。お互いのソースコードを見せ合って切磋琢磨するのも、プログラムが面白くなるきっかけの一つです。楽しんでいきましょう。
この記事でわからないことがあるとか、そもそもプログラム全然わからないから教えて欲しいとか、人によって色々だと思います。そのときは、この記事のコメント欄とか、LINEで聞いてきてOKです(できればみんなみれた方が楽)。ただし、質問する時はなるべく、**「自分は何がわからないのか」**を明確にしてください。ただ丸投げな質問をしていると、本人自身が考えなくなり、成長しません(どうしてもわからなくて進まない場合も、できるだけ質問内容を考えてきちんと伝えるようにしましょう)。
まあなにか偉そうなことを言っていますが、僕も皆さんと多分同じ18歳で、去年高校を出たばかりです。Python自体も全く未経験です。お互い頑張っていきましょう。よろしくお願いします。