2017-06-20 15 views
1

私は少し前にプログラミングを学び始めたばかりです。私はユーザーの入力(ダイ上の面の数とダイスの数)に基づいてダイスをロールする小さなプログラムを書いた。ここでは、コードがあります:私は最初の無効な入力を提供しようとすると、私は有効な入力(側面とサイコロのための6,6のようなので、桁)を提供する場合Python関数は、ユーザー入力が有効かどうかをチェックした後にNoneを返します。

from random import randrange 


def number_of_sides(): 
    n = input("How many sides? ") # Get input from the user 
    if n.isdigit(): # Check if the input is a digit 
     n = int(n) # If it is, turn it into an integer 
     return n # And return the value of n 
    else: 
     print("Invalid input. ") # If test returns false, rerun function 
     number_of_sides() 


def number_of_dice(): 
    m = input("How many dice? ") # Get input from the user 
    if m.isdigit(): # Check if the input is a digit 
     m = int(m) # If it is, turn it into an integer 
     return m # And return the value of m 
    else: 
     print("Invalid input. ") # If test returns false, rerun function 
     number_of_dice() 


def play_again() -> object: # Checks if user answered yes or no, then reruns everything or exits with exit code 0 
    answ = input("Do you want to play again?(yes/no) ") 
    if answ == "yes": 
     dice_roll() 
    elif answ == "no": 
     print("Ok then") 
     return True 
    else: 
     print("Input invalid, trying again") 
     play_again() 


def dice_roll(): # sides - for number of sides, dice - for number of dice. 
    sides = number_of_sides() # Whatever number the function returns 
    dice = number_of_dice() # Whatever number the function returns 
    results = [] # empty list, here is where results will be appended 
    for i in range(1, dice + 1): # That returns values for each dice specified in the dice variable 
     throw = randrange(1, sides + 1) 
     results.append(throw) 
     results_str = " | ".join(str(i) for i in results) # Turn the list into string, separate results with a pipe 
    print(results_str) # Print the results of throws 
    play_again() # Ask the user to play again 


dice_roll() 

すべてがうまく動作、それは、しかし、クラッシュします。何らかの理由number_of_sides(用)と、彼らが最初に供給された無効な入力だと、その後dice_roll()関数内のforループのコードをクラッシュするときnumber_of_dice()関数はNoneを返す:

How many sides? a 
Invalid input. 
How many sides? 6 
How many dice? 6 
Traceback (most recent call last): 
    File "<directory>/dice_roll.py", line 48, in <module> 
    dice_roll() 
    File "<directory>/dice_roll.py", line 41, in dice_roll 
    throw = randrange(1, sides + 1) 
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' 

Process finished with exit code 1 

私は別に、これらの機能をテストしました彼らはうまく動作しているようです。このスニペット:

def number_of_sides(): 
    n = input("How many sides? ") 
    if n.isdigit(): 
     n = int(n) 
     print(n, ", ", type(n)) 
     return n 
    else: 
     print(n, ", ", type(n)) 
     number_of_sides() 

文字列を指定する場合はstrを、数字を指定する場合はintを返します。私はこの奇妙な行動を引き起こしている可能性があることを知りたい。

+0

'number_of_sides'と' number_of_dice'の 'else'ブロックから何かを'返す '必要があります。明示的な 'return'文がない場合、Pythonは暗黙のうちに' return None'を返します。ここでは再帰/相互再帰を使用しないことをお勧めします。それは理性をつけることを難しくするだけです。 –

答えて

2

問題は、number_of_diceを再帰的にと呼びますが、その結果は無視されます。あなたはと再帰呼び出しを置き換える必要があります。

return number_of_dice() 

またはより良い、再帰を取り除く簡単なwhileループを使用することにより:

def number_of_dice(): 
    while True: 
     m = input("How many dice? ") # Get input from the user 
     if m.isdigit(): # Check if the input is a digit 
      m = int(m) # If it is, turn it into an integer 
      return m # And return the value of m 
     else: 
      print("Invalid input. ") 

は、明らかに、他の機能のために同じ成り立ちます。

+0

EAFPについてはどうですか? –

+0

@AzatIbrakovはい、 'if'を' try'に置き換えることも私の心に来ましたが、それは質問に直接関係していません。 –

0

関数number_of_sides()とnumber_of_dice()は、最初の入力が正しい場合にのみ有効な値を返します。それ以外の場合はループしますが、新しい入力はmain関数に返されません。 その場合再帰性は良くないと思います。あなたはこのようなnumber_of_dices変換することができ

:あなたの情報については

def number_of_sides(): 
    nb_sides = input("How many sides? ") 

    while (nb_sides.isdigit())==False: 
     print("Invalid input. ") 
     nb_sides=input("How many sides? ") 

    return int(nb_sides) 

を、あなたも使用することができます。

import pdb 
pdb.set_trace() 

特定の行

+0

ループした後に新しい入力を返さない理由を理解できないようです。 – Mroov

+0

実際には、さらに調査した結果、あなたの関数にreturn文がありません: –

+0

def number_of_sides(): n = input( "何辺?")#ユーザからの入力を受け取りますの値を返します。 n = int(n)#そうであれば、整数に変換します。 return n#そして、n の値を返します。 print( "Invalid input。" )#テストがfalseを返した場合は、関数を再実行 return number_of_sides() –

0

"リターン" 文でコードを一時停止しますあなたの失敗事例は2つのステートメントにはありません

from random import randrange 


def number_of_sides(): 
    n = input("How many sides? ") # Get input from the user 
    if n.isdigit(): # Check if the input is a digit 
     n = int(n) # If it is, turn it into an integer 
     return n # And return the value of n 
    else: 
     print("Invalid input. ") # If test returns false, rerun function 
     return number_of_sides() 


def number_of_dice(): 
    m = input("How many dice? ") # Get input from the user 
    if m.isdigit(): # Check if the input is a digit 
     m = int(m) # If it is, turn it into an integer 
     return m # And return the value of m 
    else: 
     print("Invalid input. ") # If test returns false, rerun function 
     return number_of_dice() 


def play_again() -> object: # Checks if user answered yes or no, then reruns everything or exits with exit code 0 
    answ = input("Do you want to play again?(yes/no) ") 
    if answ == "yes": 
     dice_roll() 
    elif answ == "no": 
     print("Ok then") 
     return True 
    else: 
     print("Input invalid, trying again") 
     play_again() 


def dice_roll(): # sides - for number of sides, dice - for number of dice. 
    sides = number_of_sides() # Whatever number the function returns 
    dice = number_of_dice() # Whatever number the function returns 
    results = [] # empty list, here is where results will be appended 
    for i in range(1, dice + 1): # That returns values for each dice specified in the dice variable 
     throw = randrange(1, sides + 1) 
     results.append(throw) 
     results_str = " | ".join(str(i) for i in results) # Turn the list into string, separate results with a pipe 
    print(results_str) # Print the results of throws 
    play_again() # Ask the user to play again 


dice_roll() 
関連する問題