質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

5回答

407閲覧

変数killが見当たらない理由(追記)

sasuke_killer

総合スコア42

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/08/17 02:33

編集2018/08/17 03:23

キル数、ポータル獲得数の平均を求める関数型プログラムを作りました。
キル数とポータル獲得数の平均を求める関数を別に作っています。
そうすると、類似の処理が入った二組の関数があることに気付きました。

これらをまとめることはできませんでしょうか?

↓一組目の類似関数

python3

1def get_kill_count(): 2 while True: 3 try: 4 return int(input("キル数は: ")) 5 except ValueError: 6 print("整数値を入力してください") 7 8def get_key_count(): 9 while True: 10 try: 11 return int(input("ポータル獲得数は: ")) 12 except ValueError: 13 print("整数値を入力してください")

↓二組目の類似関数

python3

1def calc_kill_count_average(kill_records, num_kill): 2 return (sum(kill_records) + num_kill) / (len(kill_records) + 1) 3 4def show_kill_average(kill_records,num_kill): 5 print("平均キル数:{}".format(calc_kill_count_average(kill_records, num_kill))) 6 print("注意、記録は保持されません") 7 8 9def calc_key_count_average(key_records, num_key): 10 return (sum(key_records) + num_key) / (len(key_records) + 1) 11 12def show_key_average(key_records,num_key): 13 print("平均ポータル獲得数:{}".format(calc_key_count_average(key_records, num_key))) 14 print("注意、記録は保持されません")

↓全体コード

python3

1def get_kill_count(): 2 while True: 3 try: 4 return int(input("キル数は: ")) 5 except ValueError: 6 print("整数値を入力してください") 7 8def get_key_count(): 9 while True: 10 try: 11 return int(input("ポータル獲得数は: ")) 12 except ValueError: 13 print("整数値を入力してください") 14 15 16def ask_quit(): 17 while True: 18 YesNoWitch = input("終了しますか? Yes/No: ") 19 if YesNoWitch == "Yes": 20 print("") 21 return True 22 if YesNoWitch == "No": 23 print("") 24 return False 25 print("Yes/Noを選択して入力してください") 26 27 28def calc_kill_count_average(kill_records, num_kill): 29 return (sum(kill_records) + num_kill) / (len(kill_records) + 1) 30 31def show_kill_average(kill_records,num_kill): 32 print("平均キル数:{}".format(calc_kill_count_average(kill_records, num_kill))) 33 print("注意、記録は保持されません") 34 35 36def calc_key_count_average(key_records, num_key): 37 return (sum(key_records) + num_key) / (len(key_records) + 1) 38 39def show_key_average(key_records,num_key): 40 print("平均ポータル獲得数:{}".format(calc_key_count_average(key_records, num_key))) 41 print("注意、記録は保持されません") 42 43 44key_records=[1,2,1,3] 45kill_records=[1,2,5,6] 46while True: 47 show_kill_average(kill_records, get_kill_count()) 48 show_key_average(key_records, get_key_count()) 49 if ask_quit(): 50 break

追記

まとめられそうな所はまとめられました。
クラスについては、勉強していこうと思います。

新たな問題が発生しました。「変数killが見当たりません」とのことです。
でもkillはget_count関数の時に定義しているはずです。

なぜ見当たらないのでしょうか?

python3

1def get_count(): 2 while True: 3 try: 4 kill = int(input("キル数は: ")) 5 key = int(input("ポータル獲得数は: ")) 6 break 7 except ValueError: 8 print("整数値を入力してください") 9 10 11def ask_quit(): 12 while True: 13 YesNoWitch = input("終了しますか? Yes/No: ") 14 if YesNoWitch == "Yes": 15 print("") 16 return True 17 if YesNoWitch == "No": 18 print("") 19 return False 20 print("Yes/Noを選択して入力してください") 21 22 23def calc_kill_count_average(B, kill): 24 return (sum(B) + kill) / (len(B) + 1) 25 26def calc_key_count_average(A, key): 27 return (sum(A) + key) / (len(A) + 1) 28 29def show_average(B, kill, A, key): 30 print("平均キル数:{}".format(calc_kill_count_average(B, kill))) 31 print("平均ポータル獲得数:{}".format(calc_key_count_average(A, key))) 32 print("注意、記録は保持されません") 33 34 35A=key_records=[1,2,1,3] 36B=kill_records=[1,2,5,6] 37while True: 38 get_count() 39 show_average(B, kill, A, key) 40 if ask_quit(): 41 break

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2018/08/17 02:43

このままだと「丸投げの質問」なので、自分でやってみた結果を書きましょう。その上で「うまくいかなかったので教えてほしい」とか「こういうやり方にしてみたのだが良いやり方なのか?」とか質問すれば良いです
sasuke_killer

2018/08/17 02:45

分かりました。いろいろ試したみます。
guest

回答5

0

質問や追記の文章、コードを見る限りだと、グローバル変数やローカル変数などの概念や、そもそも変数のスコープについて理解が浅い、不十分なのではないでしょうか。

たとえば、こんな動作がどうして生じているのか説明できますか?

python

1>>> def f(): 2... s = "hoge" 3... print(s) 4... 5>>> f() 6hoge 7>>> s 8Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10NameError: name 's' is not defined 11>>> t = "fuga" 12>>> def g(): 13... print(t) 14... 15>>> g() 16fuga 17>>> u = "piyo" 18>>> def h(): 19... u = "piyopiyo" 20... print(u) 21... 22>>> h() 23piyopiyo 24>>> print(u) 25piyo 26

ちゃんと説明できなければ理解不足、説明できれば凡ミスです。

参考:
Python超入門その14〜意外と重要なスコープを理解しておこう〜 | プログラミング教室情報サイト【プロナビ】

投稿2018/08/17 03:31

編集2018/08/17 03:32
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasuke_killer

2018/08/17 04:00

まず、関数内で処理されているものは関数を実行しないと処理もされません。 関数外で定義した変数を関数内で処理したら、関数を実行すればその処理結果が表示されます。 関数内で変数を上書きしても、関数を呼び出して処理しない限り変数が上書きされることはありません。 といったところでしょうか...。 コードを見直してきますね
hayataka2049

2018/08/17 04:03

3つめのpiyoの例で、外のuと中のuが別物ということを理解しているかどうか 中のuに代入しても関数の外には何も影響が及ばないということを理解しているかどうか が問題なのかなと
guest

0

*直接的な回答ではありません。

今回のようにコードを整理したいなーと感じた時に、どのような視点で整理すべきか、先人が整理してくれていたりします。
今回のコードにしても、メンテナンス性を保ちながらとか速度重視なのかとか、拡張性を考慮したいとか様々な視点がありそうですので、そのような開発・設計側の意図を踏まえながら整理する方法として「リファクタリング」があります。
書籍も色々と出ていますし、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/]

投稿2018/08/17 03:21

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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 も表示するメッセージを引数にすることでまとめられる。

ぐらいかな?

質問のプログラムぐらいだと、関数をまとめても、コード行数が激減する訳ではないので、コードの読みやすさ優先で考えたほうが良いと思います。

投稿2018/08/17 03:05

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1つ目

python

1def get_count(target): 2 while True: 3 try: 4 return int(input("%s数は: "%target)) 5 except ValueError: 6 print("整数値を入力してください") 7 8def get_kill_count(): 9 target = "ポータル" 10 return get_count(target) 11 12def get_key_count(): 13 target = "キル" 14 return get_count(target)

1つ目はValueErrorが起こった場合のハンドリングが不十分です。考え直してください。

2つ目

python

1def calc_average(records, num): 2 return (sum(records) + num) / (len(records) + 1) 3 4def calc_kill_count_average(kill_records, num_kill): 5 return calc_average(kill_records, num_kill) 6 7def calc_key_count_average(key_records, num_key): 8 return calc_average(key_records, num_key 9 10 11 12def show_average_result(target, num): 13 print("平均%s数:%s",%(target,num)) 14 print("注意、記録は保持されません") 15 16def show_kill_average(kill_records,num_kill): 17 target = "キル" 18 kill_num = calc_key_count_average(kill_records, num_kill) 19 show_average_result(target, kill_num) 20 21def show_key_average(key_records,num_key): 22 target = "ポータル獲得" 23 kill_num = calc_key_count_average(key_records, num_key) 24 show_average_result(target, key_num)

classを用いたほうがスッキリ書けますので勉強されてみてはいかがでしょう?
https://qiita.com/ykatonet/items/715418be62c119bb05b4

###追記
グローバル変数とローカル変数をご存知でしょうか?
一度しっかりそこらへんを勉強されたほうがいいです。
https://qiita.com/maechabin/items/f916a5f4361583d12e26

投稿2018/08/17 02:58

編集2018/08/17 03:42
_Victorique__

総合スコア1392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

"キル数" や "ポータル獲得数" など、今後 他の項目も追加されることを措定して、
それらを連想配列にしてみました。

python3

1# import pdb 2def get_count(prompt): 3 while True: 4 try: 5 return int(input(prompt)) 6 except ValueError: 7 print("整数値を入力してください") 8 9 10def get_score(prompts): 11 return {key: get_count(prompts[key]) for key in prompts.keys()} 12 13 14def ask_quit(): 15 resp_yes = {"Yes", "yes", "Y", "y"} 16 resp_no = {"No", "no", "N", "n"} 17 while True: 18 resp = input("終了しますか? Yes/No: ") 19 if resp in resp_yes: 20 return True 21 if resp in resp_no: 22 return False 23 print("Yes/Noを選択して入力してください") 24 25 26def calc_average(ary, data): 27 return (sum(ary) + data) / (len(ary) + 1) 28 29 30def show_averages(records, score, labels): 31 averages = {key: calc_average(records[key], score[key]) for key in records.keys()} 32 for key in records.keys(): 33 print(labels[key].format(averages[key])) 34 print("注意、記録は保持されません") 35 36 37def main(): 38 records = { 39 "kill": [1, 2, 5, 6], 40 "key": [1, 2, 1, 3] 41 } 42 prompts = { 43 "kill": "キル数は: ", 44 "key": "ポータル獲得数は: " 45 } 46 labels = { 47 "kill": "平均キル数:{}", 48 "key": "平均ポータル獲得数:{}" 49 } 50 while True: 51 score = get_score(prompts) 52 show_averages(records, score, labels) 53 if ask_quit(): 54 break 55 print("") 56 57 58main() 59

質問文のコードには

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]

のように記載するのが良いです。
変数宣言した名前と関数定義での引数の名前の関係を誤解しているような気がします。
関数呼び出し時の引数の記載で、変数と関数定義での引数が結びつけられます。

投稿2018/08/17 22:29

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問