変数killが見当たらない理由(追記)
- 評価
- クリップ 0
- VIEW 1,026
キル数、ポータル獲得数の平均を求める関数型プログラムを作りました。
キル数とポータル獲得数の平均を求める関数を別に作っています。
そうすると、類似の処理が入った二組の関数があることに気付きました。
これらをまとめることはできませんでしょうか?
↓一組目の類似関数
def get_kill_count():
while True:
try:
return int(input("キル数は: "))
except ValueError:
print("整数値を入力してください")
def get_key_count():
while True:
try:
return int(input("ポータル獲得数は: "))
except ValueError:
print("整数値を入力してください")
↓二組目の類似関数
def calc_kill_count_average(kill_records, num_kill):
return (sum(kill_records) + num_kill) / (len(kill_records) + 1)
def show_kill_average(kill_records,num_kill):
print("平均キル数:{}".format(calc_kill_count_average(kill_records, num_kill)))
print("注意、記録は保持されません")
def calc_key_count_average(key_records, num_key):
return (sum(key_records) + num_key) / (len(key_records) + 1)
def show_key_average(key_records,num_key):
print("平均ポータル獲得数:{}".format(calc_key_count_average(key_records, num_key)))
print("注意、記録は保持されません")
↓全体コード
def get_kill_count():
while True:
try:
return int(input("キル数は: "))
except ValueError:
print("整数値を入力してください")
def get_key_count():
while True:
try:
return int(input("ポータル獲得数は: "))
except ValueError:
print("整数値を入力してください")
def ask_quit():
while True:
YesNoWitch = input("終了しますか? Yes/No: ")
if YesNoWitch == "Yes":
print("")
return True
if YesNoWitch == "No":
print("")
return False
print("Yes/Noを選択して入力してください")
def calc_kill_count_average(kill_records, num_kill):
return (sum(kill_records) + num_kill) / (len(kill_records) + 1)
def show_kill_average(kill_records,num_kill):
print("平均キル数:{}".format(calc_kill_count_average(kill_records, num_kill)))
print("注意、記録は保持されません")
def calc_key_count_average(key_records, num_key):
return (sum(key_records) + num_key) / (len(key_records) + 1)
def show_key_average(key_records,num_key):
print("平均ポータル獲得数:{}".format(calc_key_count_average(key_records, num_key)))
print("注意、記録は保持されません")
key_records=[1,2,1,3]
kill_records=[1,2,5,6]
while True:
show_kill_average(kill_records, get_kill_count())
show_key_average(key_records, get_key_count())
if ask_quit():
break
追記
まとめられそうな所はまとめられました。
クラスについては、勉強していこうと思います。
新たな問題が発生しました。「変数killが見当たりません」とのことです。
でもkillはget_count関数の時に定義しているはずです。
なぜ見当たらないのでしょうか?
def get_count():
while True:
try:
kill = int(input("キル数は: "))
key = int(input("ポータル獲得数は: "))
break
except ValueError:
print("整数値を入力してください")
def ask_quit():
while True:
YesNoWitch = input("終了しますか? Yes/No: ")
if YesNoWitch == "Yes":
print("")
return True
if YesNoWitch == "No":
print("")
return False
print("Yes/Noを選択して入力してください")
def calc_kill_count_average(B, kill):
return (sum(B) + kill) / (len(B) + 1)
def calc_key_count_average(A, key):
return (sum(A) + key) / (len(A) + 1)
def show_average(B, kill, A, key):
print("平均キル数:{}".format(calc_kill_count_average(B, kill)))
print("平均ポータル獲得数:{}".format(calc_key_count_average(A, key)))
print("注意、記録は保持されません")
A=key_records=[1,2,1,3]
B=kill_records=[1,2,5,6]
while True:
get_count()
show_average(B, kill, A, key)
if ask_quit():
break
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+3
質問や追記の文章、コードを見る限りだと、グローバル変数やローカル変数などの概念や、そもそも変数のスコープについて理解が浅い、不十分なのではないでしょうか。
たとえば、こんな動作がどうして生じているのか説明できますか?
>>> def f():
... s = "hoge"
... print(s)
...
>>> f()
hoge
>>> s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 's' is not defined
>>> t = "fuga"
>>> def g():
... print(t)
...
>>> g()
fuga
>>> u = "piyo"
>>> def h():
... u = "piyopiyo"
... print(u)
...
>>> h()
piyopiyo
>>> print(u)
piyo
ちゃんと説明できなければ理解不足、説明できれば凡ミスです。
参考:
Python超入門その14〜意外と重要なスコープを理解しておこう〜 | プログラミング教室情報サイト【プロナビ】
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
1つ目
def get_count(target):
while True:
try:
return int(input("%s数は: "%target))
except ValueError:
print("整数値を入力してください")
def get_kill_count():
target = "ポータル"
return get_count(target)
def get_key_count():
target = "キル"
return get_count(target)
1つ目はValueErrorが起こった場合のハンドリングが不十分です。考え直してください。
2つ目
def calc_average(records, num):
return (sum(records) + num) / (len(records) + 1)
def calc_kill_count_average(kill_records, num_kill):
return calc_average(kill_records, num_kill)
def calc_key_count_average(key_records, num_key):
return calc_average(key_records, num_key
def show_average_result(target, num):
print("平均%s数:%s",%(target,num))
print("注意、記録は保持されません")
def show_kill_average(kill_records,num_kill):
target = "キル"
kill_num = calc_key_count_average(kill_records, num_kill)
show_average_result(target, kill_num)
def show_key_average(key_records,num_key):
target = "ポータル獲得"
kill_num = calc_key_count_average(key_records, num_key)
show_average_result(target, key_num)
classを用いたほうがスッキリ書けますので勉強されてみてはいかがでしょう?
https://qiita.com/ykatonet/items/715418be62c119bb05b4
追記
グローバル変数とローカル変数をご存知でしょうか?
一度しっかりそこらへんを勉強されたほうがいいです。
https://qiita.com/maechabin/items/f916a5f4361583d12e26
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
1) calc_kill_count_average と calc_key_count_averageは、計算式が同等なのでまとめられる。
ただし、関数名にkillとかkeyとかが入っている事に意味があるなら、まとめるべきでない。
2) show_kill_average と show_key_average も表示するメッセージを引数にすることでまとめられる。
3) get_kill_count と get_key_count も表示するメッセージを引数にすることでまとめられる。
ぐらいかな?
質問のプログラムぐらいだと、関数をまとめても、コード行数が激減する訳ではないので、コードの読みやすさ優先で考えたほうが良いと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
*直接的な回答ではありません。
今回のようにコードを整理したいなーと感じた時に、どのような視点で整理すべきか、先人が整理してくれていたりします。
今回のコードにしても、メンテナンス性を保ちながらとか速度重視なのかとか、拡張性を考慮したいとか様々な視点がありそうですので、そのような開発・設計側の意図を踏まえながら整理する方法として「リファクタリング」があります。
書籍も色々と出ていますし、1度目を通されると、今後の開発に役にたつと思います。
pythonに特化したものはあまり見たことがありませんが、個人的にはいかがオススメです。
[https://www.amazon.co.jp/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-%E6%97%A2%E5%AD%98%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%89%E5%85%A8%E3%81%AB%E6%94%B9%E5%96%84%E3%81%99%E3%82%8B-OBJECT-TECHNOLOGY-Martin-Fowler/dp/427405019X/]
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
"キル数" や "ポータル獲得数" など、今後 他の項目も追加されることを措定して、
それらを連想配列にしてみました。
# import pdb
def get_count(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("整数値を入力してください")
def get_score(prompts):
return {key: get_count(prompts[key]) for key in prompts.keys()}
def ask_quit():
resp_yes = {"Yes", "yes", "Y", "y"}
resp_no = {"No", "no", "N", "n"}
while True:
resp = input("終了しますか? Yes/No: ")
if resp in resp_yes:
return True
if resp in resp_no:
return False
print("Yes/Noを選択して入力してください")
def calc_average(ary, data):
return (sum(ary) + data) / (len(ary) + 1)
def show_averages(records, score, labels):
averages = {key: calc_average(records[key], score[key]) for key in records.keys()}
for key in records.keys():
print(labels[key].format(averages[key]))
print("注意、記録は保持されません")
def main():
records = {
"kill": [1, 2, 5, 6],
"key": [1, 2, 1, 3]
}
prompts = {
"kill": "キル数は: ",
"key": "ポータル獲得数は: "
}
labels = {
"kill": "平均キル数:{}",
"key": "平均ポータル獲得数:{}"
}
while True:
score = get_score(prompts)
show_averages(records, score, labels)
if ask_quit():
break
print("")
main()
質問文のコードには
def calc_key_count_average(A, key):
...
A=key_records=[1,2,1,3]
のような記載があります。
これは
def calc_key_count_average(records, key):
...
key_records=[1,2,1,3]
のように記載するのが良いです。
変数宣言した名前と関数定義での引数の名前の関係を誤解しているような気がします。
関数呼び出し時の引数の記載で、変数と関数定義での引数が結びつけられます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.37%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
hayataka2049
2018/08/17 11:43
このままだと「丸投げの質問」なので、自分でやってみた結果を書きましょう。その上で「うまくいかなかったので教えてほしい」とか「こういうやり方にしてみたのだが良いやり方なのか?」とか質問すれば良いです
sasuke_killer
2018/08/17 11:45
分かりました。いろいろ試したみます。
sasuke_killer
2018/08/17 11:48
試してみます