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

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

ただいまの
回答率

90.37%

  • Python

    12897questions

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

  • Python 3.x

    10772questions

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

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

受付中

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 361

sasuke_killer

score 34

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

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

↓一組目の類似関数

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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hayataka2049

    2018/08/17 11:43

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

    キャンセル

  • sasuke_killer

    2018/08/17 11:45

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

    キャンセル

  • sasuke_killer

    2018/08/17 11:48

    試してみます

    キャンセル

回答 5

+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〜意外と重要なスコープを理解しておこう〜 | プログラミング教室情報サイト【プロナビ】

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/17 13:00

    まず、関数内で処理されているものは関数を実行しないと処理もされません。
    関数外で定義した変数を関数内で処理したら、関数を実行すればその処理結果が表示されます。
    関数内で変数を上書きしても、関数を呼び出して処理しない限り変数が上書きされることはありません。

    といったところでしょうか...。
    コードを見直してきますね

    キャンセル

  • 2018/08/17 13:03

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

    キャンセル

+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で質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Python

    12897questions

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

  • Python 3.x

    10772questions

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