尝试避免在Python函数中使用全局变量

huangapple go评论65阅读模式
英文:

Trying to avoid Globals in Python Functions

问题

我还在不断地学习Python3的各个方面,通过多种来源(如《LPTHW》等书籍和在线资源)来学习。我喜欢将所学的东西融合到一些任务中……只是这个任务让我感到困惑,因为我来自有限的C/嵌入式背景,我知道全局变量(可写)是非常不被赞同的,这也是我尽量避免使用任何全局变量的原因。

只是在这种情况下,我对如何处理以下代码中的num_guesses有些困惑(因为在当前状态下它被num_guesses破坏了):

import random

min_num = 1
max_num = 100

def generate_number(min_num, max_num):
    """This function generates a random number within a specified range"""
    return random.randint(min_num, max_num)

def get_guess():
    """This function asks the player to guess a number"""
    guess = input("Guess a number between 1 and 100:")
    return int(guess)

def check_guess(guess, target):
    """This function checks if the player's guess matches the target number"""
    if guess == target:
        print("Congratulations! You guessed the number!")
        return True
    elif guess < min_num or guess > max_num:
        print("Your guess is out of bounds. Try again.")
        return False
    elif num_guesses[-2]:
        if abs(target-guess) < abs(target-num_guesses[-2]):
            print("Warmer!")
            return False
        else:
            print("Colder!")
            return False
    else:
        if abs(target-guess) <= 10:
            print("Warm!")
            return False
        else:
            print("Cold!")
            return False

def play_game():
    """This function runs the game"""
    #min_num = 1
    #max_num = 100
    target = generate_number(min_num, max_num)
    guesses = []
    num_guesses = 0

    while True:
        guess = get_guess()
        num_guesses += 1

        if guess in guesses:
            print("You already guessed that number. Try again.")
        else:
            guesses.append(guess)
            if check_guess(guess, target):
                print("You guessed the number in", num_guesses, "guesses!")
                break

    play_again = input("Do you want to play again? (yes or no)")
    if play_again == "yes":
        play_game()
    else:
        print("Thanks for playing!")

play_game()

我还没有处理面向对象方面的内容,所以试图通过使用我目前学到的东西来保持这个问题相对简单,以便进入下一步(即面向对象部分,我对此一无所知)。

这个游戏[应该是]一个简单的“猜数字”类型的游戏,其中检查输入是否在范围内,然后根据你离数字有多近来判断“热”或“冷”。

关于如何修复这个问题以便我能学到最佳实践的任何指点都将不胜感激 尝试避免在Python函数中使用全局变量

谢谢

编辑:

由于下面的答案,我也能理解如何将min_num和max_num整数传递给各种函数而不是全局变量。

我还添加了一些文本并整理了其他部分,以使其更用户友好 尝试避免在Python函数中使用全局变量

import random

def show_instructions(min_num, max_num):
    """This function displays the rules/instructions for playing the game"""
    print("\n\n")
    print("*" * 61)
    print("*** Welcome to the Random Number Guess GeneRatoR [RNG GRR]***")
    print("*" * 61)
    print("\nTo play:\n")
    print("Enter a value between the range shown at the start of the game")
    print("After each guess you will be told 'Warmer' if getting closer to the value")
    print("If further away, then it will show 'Colder'.")
    print("If within 10 of the value it will say 'Very Warm!'\n")
    print(f"To begin: enter a number between the {min_num} and {max_num}")

def generate_number(min_num, max_num):
    """This function generates a random number within a specified range"""
    return random.randint(min_num, max_num)

def get_guess(min_num, max_num):
    """This function asks the player to guess a number"""
    guess = input("> ")
    return int(guess)

def check_guess(guess, target, guesses, min_num, max_num):
    """This function checks if the player's guess matches the target number"""
    if guess == target:
        print("Congratulations! You guessed the number!")
        return True
    elif guess < min_num or guess > max_num:
        print("Your guess is out of bounds. Try again.")
        print(f"The number is between {min_num} and {max_num}.")
        return False
    elif abs(target - guess) <= 10:
            print("Very warm!")
            return False
    elif len(guesses) > 1:
        if abs(target-guess) < abs(target-guesses[-2]):
            print("Warmer!")
            return False
        else:
            print("Colder!")
            return False
    else:
        print("Quite far out, try again")
        return False

def play_game():
    """This function runs the game"""
    min_num = 1
    max_num = 100
    target = generate_number(min_num, max_num)
    guesses = []
    num_guesses = 0

    show_instructions(min_num, max_num)

    while True:
        guess = get_guess(min_num, max_num)
        num_guesses += 1

        if guess in guesses:
            print("You already guessed that number. Try again.")
        else:
            guesses.append(guess)
            if check_guess(guess, target, guesses, min_num, max_num):
                print("You guessed the number in", num_guesses, "guesses!")
                break

    play_again = input("Do you want to play again? (yes or no)")
    if play_again == "yes":
        play_game()
    else:
        print("\n***Thanks for playing!\n\n")

play_game()
英文:

I'm still munching through learning the ins and outs of Python3 through multiple sources (books like LPTHW and online resources) and I like to mash up everything I have learned in some of the tasks... only this one has me stumped as I come from a limited C/Embedded background and I know that (writeable) globals are very much frowned upon which is why I am trying to avoid any globals where possible.

Only in this instance my mind has gone blank as to how to deal with num_guesses in the following code (as it's broken by num_guesses in it's current state):

import random

min_num = 1
max_num = 100

def generate_number(min_num, max_num):
    &quot;&quot;&quot;This function generates a random number within a specified range&quot;&quot;&quot;
    return random.randint(min_num, max_num)

def get_guess():
    &quot;&quot;&quot;This function asks the player to guess a number&quot;&quot;&quot;
    guess = input(&quot;Guess a number between 1 and 100: &quot;)
    return int(guess)

def check_guess(guess, target):
    &quot;&quot;&quot;This function checks if the player&#39;s guess matches the target number&quot;&quot;&quot;
    if guess == target:
        print(&quot;Congratulations! You guessed the number!&quot;)
        return True
    elif guess &lt; min_num or guess &gt; max_num:
        print(&quot;Your guess is out of bounds. Try again.&quot;)
        return False
    elif num_guesses[-2]:
        if abs(target-guess) &lt; abs(target-num_guesses[-2]):
            print(&quot;Warmer!&quot;)
            return False
        else:
            print(&quot;Colder!&quot;)
            return False
    else:
        if abs(target-guess) &lt;= 10:
            print(&quot;Warm!&quot;)
            return False
        else:
            print(&quot;Cold!&quot;)
            return False

def play_game():
    &quot;&quot;&quot;This function runs the game&quot;&quot;&quot;
    #min_num = 1
    #max_num = 100
    target = generate_number(min_num, max_num)
    guesses = []
    num_guesses = 0

    while True:
        guess = get_guess()
        num_guesses += 1

        if guess in guesses:
            print(&quot;You already guessed that number. Try again.&quot;)
        else:
            guesses.append(guess)
            if check_guess(guess, target):
                print(&quot;You guessed the number in&quot;, num_guesses, &quot;guesses!&quot;)
                break

    play_again = input(&quot;Do you want to play again? (yes or no)&quot;)
    if play_again == &quot;yes&quot;:
        play_game()
    else:
        print(&quot;Thanks for playing!&quot;)

play_game()

I've yet to tackle the object orientated side of things so trying to keep this fairly simple using what I have learned so far as I move into the next step (which is the object orientated part of which I have no experience at all!).

The game is [supposed to be] a simple 'guess the number' type game where the input is checked for validity within the range and then hot/cold based on how close you get to the number based off your previous guess.

ANY pointers on how to go about fixing this so I can learn best practises would be greatly appreciated 尝试避免在Python函数中使用全局变量

Thanks

EDIT:

Thanks to the answer below I was also able to understand how to pass min_num and max_num integers to various functions without being a global variable.

I also added some text and tidied up other parts to make it more user friendly 尝试避免在Python函数中使用全局变量

import random

def show_instructions(min_num, max_num):
    &quot;&quot;&quot;This function displays the rules/instructions for playing the game&quot;&quot;&quot;
    print(&quot;\n\n&quot;)
    print(&quot;*&quot; * 61)
    print(&quot;*** Welcome to the Random Number Guess GeneRatoR [RNG GRR]***&quot;)
    print(&quot;*&quot; * 61)
    print(&quot;\nTo play:\n&quot;)
    print(&quot;Enter a value between the range shown at the start of the game&quot;)
    print(&quot;After each guess you will be told &#39;Warmer&#39; if getting closer to the value&quot;)
    print(&quot;If further away, then it will show &#39;Colder&#39;.&quot;)
    print(&quot;If within 10 of the value it will say &#39;Very Warm!&#39;\n&quot;)
    print(f&quot;To begin: enter a number between the {min_num} and {max_num}&quot;)

def generate_number(min_num, max_num):
    &quot;&quot;&quot;This function generates a random number within a specified range&quot;&quot;&quot;
    return random.randint(min_num, max_num)

def get_guess(min_num, max_num):
    &quot;&quot;&quot;This function asks the player to guess a number&quot;&quot;&quot;
    guess = input(&quot;&gt; &quot;)
    return int(guess)

def check_guess(guess, target, guesses, min_num, max_num):
    &quot;&quot;&quot;This function checks if the player&#39;s guess matches the target number&quot;&quot;&quot;
    if guess == target:
        print(&quot;Congratulations! You guessed the number!&quot;)
        return True
    elif guess &lt; min_num or guess &gt; max_num:
        print(&quot;Your guess is out of bounds. Try again.&quot;)
        print(f&quot;The number is between {min_num} and {max_num}.&quot;)
        return False
    elif abs(target - guess) &lt;= 10:
            print(&quot;Very warm!&quot;)
            return False
    elif len(guesses) &gt; 1:
        if abs(target-guess) &lt; abs(target-guesses[-2]):
            print(&quot;Warmer!&quot;)
            return False
        else:
            print(&quot;Colder!&quot;)
            return False
    else:
        print(&quot;Quite far out, try again&quot;)
        return False

def play_game():
    &quot;&quot;&quot;This function runs the game&quot;&quot;&quot;
    min_num = 1
    max_num = 100
    target = generate_number(min_num, max_num)
    guesses = []
    num_guesses = 0

    show_instructions(min_num, max_num)

    while True:
        guess = get_guess(min_num, max_num)
        num_guesses += 1

        if guess in guesses:
            print(&quot;You already guessed that number. Try again.&quot;)
        else:
            guesses.append(guess)
            if check_guess(guess, target, guesses, min_num, max_num):
                print(&quot;You guessed the number in&quot;, num_guesses, &quot;guesses!&quot;)
                break

    play_again = input(&quot;Do you want to play again? (yes or no)&quot;)
    if play_again == &quot;yes&quot;:
        play_game()
    else:
        print(&quot;\n***Thanks for playing!\n\n&quot;)

play_game()

答案1

得分: 1

I have changed your code as follows:

我已将您的代码更改如下:

I passed in the guesses list to your check_guess function, as I believe that is what you were trying to index when you used num_guesses[-2].

我将猜测列表传递给了您的check_guess函数,因为我认为这是您在使用num_guesses[-2]时尝试索引的内容。

For readability, I also modified your if statement to verify the length of the list instead of checking for an existence of a -2 index.

为了提高可读性,我还修改了您的if语句,以验证列表的长度,而不是检查是否存在-2索引。

import random

min_num = 1
max_num = 100

def generate_number(min_num, max_num):
    """This function generates a random number within a specified range"""
    return random.randint(min_num, max_num)

def get_guess():
    """This function asks the player to guess a number"""
    guess = input("猜一个1到100之间的数字:")
    return int(guess)

def check_guess(guess, target, guesses):
    """This function checks if the player's guess matches the target number"""
    if guess == target:
        print("恭喜!你猜对了数字!")
        return True
    elif guess < min_num or guess > max_num:
        print("你的猜测超出范围。请重试。")
        return False
    elif len(guesses) > 1:
        if abs(target - guess) < abs(target - guesses[-2]):
            print("更暖和了!")
            return False
        else:
            print("更冷了!")
            return False
    else:
        if abs(target - guess) <= 10:
            print("温暖!")
            return False
        else:
            print("冷!")
            return False

def play_game():
    """This function runs the game"""
    #min_num = 1
    #max_num = 100
    target = generate_number(min_num, max_num)
    guesses = []
    num_guesses = 0

    while True:
        guess = get_guess()
        num_guesses += 1

        if guess in guesses:
            print("你已经猜过那个数字。请重试。")
        else:
            guesses.append(guess)
            if check_guess(guess, target, guesses):
                print("你在", num_guesses, "次猜测中猜对了数字!")
                break

    play_again = input("你想再玩一次吗?(是或否)")
    if play_again == "是":
        play_game()
    else:
        print("谢谢你的参与!")

play_game()

num_guesses isn't necessary in the function, as in check_guess you only care about the previous guesses, and not the number of guesses.

函数中不需要num_guesses,因为在check_guess中,你只关心先前的猜测,而不是猜测的数量。

英文:

I have changed your code as follows:
I passed in the guesses list to your check_guess function, as I believe that is what you were trying to index when you used num_guesses[-2].
For readability, I also modified your if statement to verify the length of the list instead of checking for an existence of a -2 index.

import random
min_num = 1
max_num = 100
def generate_number(min_num, max_num):
&quot;&quot;&quot;This function generates a random number within a specified range&quot;&quot;&quot;
return random.randint(min_num, max_num)
def get_guess():
&quot;&quot;&quot;This function asks the player to guess a number&quot;&quot;&quot;
guess = input(&quot;Guess a number between 1 and 100: &quot;)
return int(guess)
def check_guess(guess, target, guesses):
&quot;&quot;&quot;This function checks if the player&#39;s guess matches the target number&quot;&quot;&quot;
if guess == target:
print(&quot;Congratulations! You guessed the number!&quot;)
return True
elif guess &lt; min_num or guess &gt; max_num:
print(&quot;Your guess is out of bounds. Try again.&quot;)
return False
elif len(guesses) &gt; 1:
if abs(target-guess) &lt; abs(target-guesses[-2]):
print(&quot;Warmer!&quot;)
return False
else:
print(&quot;Colder!&quot;)
return False
else:
if abs(target-guess) &lt;= 10:
print(&quot;Warm!&quot;)
return False
else:
print(&quot;Cold!&quot;)
return False
def play_game():
&quot;&quot;&quot;This function runs the game&quot;&quot;&quot;
#min_num = 1
#max_num = 100
target = generate_number(min_num, max_num)
guesses = []
num_guesses = 0
while True:
guess = get_guess()
num_guesses += 1
if guess in guesses:
print(&quot;You already guessed that number. Try again.&quot;)
else:
guesses.append(guess)
if check_guess(guess, target, guesses):
print(&quot;You guessed the number in&quot;, num_guesses, &quot;guesses!&quot;)
break
play_again = input(&quot;Do you want to play again? (yes or no)&quot;)
if play_again == &quot;yes&quot;:
play_game()
else:
print(&quot;Thanks for playing!&quot;)
play_game()

num_guesses isn't necessary in the function, as in check_guesses you only care about the previous guesses, and not the number of guesses.

huangapple
  • 本文由 发表于 2023年4月4日 04:37:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923592.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定