Python:可变范围和参数问题

时间:2014-11-21 01:17:37

标签: python python-3.4

global

这是我目前的代码:

import random

def getSecretPhrase():
    secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
    x = random.randint(1,10)
    correctPhrase = secretPhrase[x-1]
    print("Please guess a letter.")
    correctLetters = input().lower()
    return correctPhrase
def createPhrase():
    blanks = '_' * len(correctPhrase)
    print(blanks)
    print(correctPhrase)
def main():
    getSecretPhrase()
    createPhrase()
    for i in range(len(secretPhrase)):
        if correctPhrase[i] in correctLetters:
            blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
    for letter in blanks:
        print(letter, end = ' ')
main()

预期输出应为:

Please guess a letter.
>>> e
#assuming the phrase is I like trains
_ - _ _ _ e - _ _ _ _ _ _

然而,我得到了

Traceback (most recent call last):
      File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 27, in <module>
        main()
      File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 21, in main
        createPhrase()
      File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 16, in createPhrase
        blanks = '_' * len(correctPhrase)
    NameError: name 'correctPhrase' is not defined

我试图在多个地方使用变量correctPhrase。这可能是一个范围问题。

5 个答案:

答案 0 :(得分:1)

我写了一些假设。首先,你想让它成为一种像游戏一样的刽子手,他们一直在猜测,直到他们得到它。为此,我已经为你做了一个课程。代码注释了解释

import random
import string


class WordGuesser(object):
    ## We store the possible secret phrases as a class variable and make sure they're lower case
    secretPhrase = map(string.lower, ['I like trains', 'Drop the bass',
                                      'YouTube is funny', 'Ebola is dangerous',
                                      'Python is cool', 'PHS is 116 years old',
                                      'I am a person', 'Sleep is overrated',
                                      'Programming is fun'])

    def __init__(self): 
        ## We pick a secret phrase
        self.correctPhrase = WordGuesser.secretPhrase[random.randint(1,10)-1]
        self.length = len(self.correctPhrase)
        ## We pick our 'blank' phrase
        self.blankPhrase = ''.join(('_' if letter != ' ' else ' ')
                                    for letter in self.correctPhrase)

    def gameLoop(self):
        print self.blankPhrase
        ## as long as our blank phrase is wrong we continue
        while self.blankPhrase != self.correctPhrase:                 
            guess = raw_input("Please guess a letter.").lower() ## Their guess
            temp = ""
            for i in range(self.length): ## we fill in the word
                if self.correctPhrase[i] == guess:
                    temp += guess
                else:
                    temp += self.blankPhrase[i]
            self.blankPhrase = temp
            print self.blankPhrase ## display what they have so far


def main():
    game = WordGuesser()
    game.gameLoop()

if __name__ == '__main__':
    main()

运行时,它看起来像这样

>>> 
___________ __ ___
Please guess a letter.a
_____a_____ __ ___
Please guess a letter.e
_____a_____ __ ___
Please guess a letter.i
_____a__i__ i_ ___
Please guess a letter.o
__o__a__i__ i_ ___
Please guess a letter.u
__o__a__i__ i_ _u_
Please guess a letter.p
p_o__a__i__ i_ _u_
Please guess a letter.m
p_o__ammi__ i_ _u_
Please guess a letter.y
p_o__ammi__ i_ _u_
Please guess a letter.e
p_o__ammi__ i_ _u_
Please guess a letter.l
p_o__ammi__ i_ _u_
Please guess a letter.s
p_o__ammi__ is _u_
Please guess a letter.r
pro_rammi__ is _u_
Please guess a letter.g
programmi_g is _u_
Please guess a letter.n
programming is _un
Please guess a letter.f
programming is fun
>>> 

答案 1 :(得分:1)

由于这显然是家庭作业,我决定尽可能少地编写代码来实现它,只是为了好玩。把它归结为4 ......

import random
phrase, board, guesses, tries = random.choice(["I like trains", "Drop the bass", "YouTube is funny", "Ebola is dangerous", "Python is cool", "PHS is 116 years old", "I am a person", "Sleep is overrated", "Programming is fun"]).lower(), lambda guesses: ' '.join(letter if letter in guesses else "-" if letter == " " else "_" for letter in phrase), set(), 0
while board(guesses) != board(phrase.replace(" ", "-")): print board(guesses); guesses.add(raw_input("What is your guess? ").lower()); tries += 1
print "YOU WIN! It took you {} tries and {} unique guesses to guess {}".format(tries, len(guesses), board(guesses))

您可以在此处试用:http://repl.it/4cg

所以回答你原来的问题......

import random

def getSecretPhrase():
    secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
    x = random.randint(1,10)
    correctPhrase = secretPhrase[x-1]
    print("Please guess a letter.")
    correctLetters = input().lower()
    return correctPhrase
def createPhrase(correctPhraseArgument): # this method accepts an argument and stores it in a variable named `correctPhraseArgument`
    blanks = '_' * len(correctPhraseArgument)
    print(blanks)
    print(correctPhraseArgument)
def main():
    secretPhrase = getSecretPhrase() # assign the returned value to a variable in this scope
    createPhrase(secretPhrase) # pass the variable to this method
    for i in range(len(secretPhrase)):
        if correctPhrase[i] in correctLetters:
            blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
    for letter in blanks:
        print(letter, end = ' ')
main()

这仍然会有问题,但我想告诉你导致你提到的错误的原因......

在方法内部声明的变量存在于这些方法中。要在不使用全局变量的情况下从其他方法访问它们,您需要将它们作为参数传递并返回值。然后,您需要将这些返回的值分配给新变量。

答案 2 :(得分:1)

我在这里做了很多评论,希望你能跟进:

import random

def get_secret_phrase():
    # Instead of using one long string and creating a list from it, just make a list!
    phrases = ["I like trains","Drop the bass","YouTube is funny","Ebola is dangerous","Python is cool","PHS is 116 years old","I am a person","Sleep is overrated","Programming is fun"]
    # We have a list, we can get its length by using `len()` so there is no need to hardcode a value of 10
    # We also know that lists are 0-indexed, so we can tell `randint()` to get an int between 0 and the length of the list - 1
    index = random.randint(0, len(phrases) - 1)
    # Now we get the phrase at the random `index` we just created
    secret_phrase = phrases[index]
    # An alternative, more pythonic way to do the previous 2 lines is to use `random.choice()` which does the same logic
    #secret_phrase = random.choice(phrases)
    # Finally, return `secret_phrase` and make it lowercase so we can use it in another method
    return secret_phrase.lower()

def get_user_guess():
    # We want to make this separate from `get_secret_phrase()` because this will be called every time we want the user to guess
    print("What is your guess? ")
    # Assign the user input to a variable
    guess = input().lower()
    print("You guessed: {}".format(guess))
    return guess

def get_phrase_progress(secret_phrase, guessed_letters):
    # We want to generate a string that will represent how many letters the user has gotten correctly
    # We will call this every time so that it is always accurate based on what was guessed
    blanks = ''
    for letter in secret_phrase:
        if letter == ' ' or letter in guessed_letters:
            blanks = blanks + letter
        else:
            blanks = blanks + '_'
    return blanks

def get_phrase_progress_pythonic(secret_phrase, guessed_letters):
    # Here's a really pythonic way to do this
    return ''.join(letter if letter == ' ' or letter in guessed_letters else '_' for letter in secret_phrase)

def main():
    guessed_letters = list() # First, create a `list` to store the guessed letters
    secret_phrase = get_secret_phrase() # Next, call `get_secret_phrase()` and assign it's value to a variable in the scope of `main()`

    # Uncomment the following to see that the pythonic version returns the same thing
    # print(get_phrase_progress(secret_phrase, guessed_letters))
    # print(get_phrase_progress_pythonic(secret_phrase, guessed_letters))

    guessed_phrase = get_phrase_progress(secret_phrase, guessed_letters)
    # We want to loop until the user guesses the whole phrase
    while guessed_phrase != secret_phrase:
        print(guessed_phrase)
        # We call `get_user_guess()` to prompt the user to enter a letter
        letter = get_user_guess()
        # Next we want to make sure they entered just 1 letter
        # We can use the built in `str.isalpha()` to check if the string entered by the user is alphabetical and at least 1 character long
        if not letter.isalpha():
            # However, we only want them to guess a single letter, so we also check that the length == 1
            if len(letter) != 1:
                print('You need to guess something...')
            else:
                print('You can only guess a single letter, you tried to guess: {}'.format(letter))
        # Next we check if the user already guessed the letter, if so, tell them!
        elif letter in guessed_letters:
            print('You already guessed {}'.format(letter))
        else:
            guessed_letters.append(letter)
        # Here we calculate `guessed_phrase` every loop to make sure it always takes into account what letters have been guessed
        guessed_phrase = get_phrase_progress(secret_phrase, guessed_letters)

    # If the user escapes the while loop, they won, they guessed the secret phrase
    # We can calculate a score based on how many letters they guessed, this isn't great but it works for a simple scoring method
    print('You won! It took you {} guesses to guess {}'.format(len(guessed_letters), secret_phrase))

main()

答案 3 :(得分:0)

怎么样:

import random

def getSecretPhrase():
    secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
    x = random.randint(1,10)
    correctPhrase = secretPhrase[x-1]
    print("Please guess a letter.")
    correctLetters = input().lower()
    return correctPhrase
def createPhrase(correctPhrase):
    blanks = '_' * len(correctPhrase)
    print(blanks)
    print(correctPhrase)
def main():
    secretPhrase = getSecretPhrase()
    createPhrase(secretPhrase)
    for i in range(len(secretPhrase)):
        if correctPhrase[i] in correctLetters:
            blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
    for letter in blanks:
        print(letter, end = ' ')
main()

答案 4 :(得分:0)

好吧,不仅“correctLetters”,你的代码中存在很多变量范围问题。

correctLetters在getSecretPhrase()中定义,并且仅在此方法中处于活动状态。因此,方法()不知道什么是correctLetters,这就是你看到这个异常的原因。

有很多方法可以解决这个问题

首先在方法外定义“correctLetters”,并使用关键字global

其次,您可以返回变量,例如:

def createPhrase():

    blanks = '_' * len(correctPhrase)

    return blanks

所以在main()中,你可以得到返回值:

blanks = createPhrase()