开发者

My method is being recognized within my own program. Newbie mistake probably

Here's my code:

sentenceToTranslate = raw_input("Please write in 开发者_C百科the sentence you want to translate: ")
words = sentenceToTranslate.split(" ")

for word in words:
    if isVowel(word[0]):
        print "TEST"


def isVowel(letter):
    if letter.lower() == "a" or letter.lower() == "e" or letter.lower() == "i" or letter.lower() == "o" or letter.lower() == "u":
        return True
    else:
        return False

The error I get is:

NameError: name 'isVowel' is not defined

What am I doing wrong?


The function hasn't been defined yet, so the name 'isVowel' doesn't have a function bound to it: that only happens at the time when you say "def".

Solution: move your code below the def isVowel(letter).


Put the def isVowel definition at top.

You defined the function after it had already been called. Since, the source code is not compiled and interpreted at run-time, it does not check for this error.

Also, you can redefine the function as

def isVowel(letter):
    if letter.lower() in "aeiou":
        return True
    else:
        return False


At the risk of being downvoted again, here is some further insight into these "define before use" requirements.

Note that the body of a function is not processed for the existence of symbols in until that function gets called. So you could write code like this:

def A():
    # calls B - even though B is defined later in the module
    B()

def B():
    # calls A
    A()

And this works just fine. The interpreter/compiler works top-down through the module, but when it sees a function or class definition, it processes the definition of the function, but not the function itself.

The reason your code failed was because the reference to isVowel was not within a function, but was at module scope. Code in the module that is not within a function is executed immediately, so the interpreter needs to be able to resolve any names based on what it has seen so far.


Python executes all the statements that you put in your module when it encounters them, from top to bottom. What happens is that you try to call isVowel before you have defined that function. The python interpreter has not reached that code yet.

If you put the definition of isVowel at the top of your file you will be able to call it.


I think you need to define the function first, then call it after it has been defined.

def isVowel(letter):
    if letter.lower() == "a" or letter.lower() == "e" or letter.lower() == "i" or letter.lower() == "o" or letter.lower() == "u":
        return True
    else:
        return False

sentenceToTranslate = raw_input("Please write in the sentence you want to translate: ")
words = sentenceToTranslate.split(" ")

for word in words:
    if isVowel(word[0]):
        print "TEST"

Often you will put the function definitions in another file, and import them to avoid these problems.


Here are a couple of other points to make for a newbie Pythoner:

1) What is the point of writing this?

def isVowel():
    if boolean-expression:
        return True
    else:
        return False

You already have the True/False-ness captured in the value of the boolean expression, just:

def isVowel():
    return boolean-expression

2) Function calls are performance killers. Especially when you have such a limited set of items to check for, instead of calling .lower() so that you can check against "aeiou", check the character itself against both the lower and upper case letters, "aeiouAEIOU". Even though this is twice the length string to test for membership, it saves us the call to the lower() function.

Here are some performance test results:

import time
import string
time.clock()

reps = 100000
testString = (string.uppercase + string.lowercase) * reps

start = time.clock()
for c in testString:
    answer = c.lower() in "aeiou"
end = time.clock()
print end-start

start = time.clock()
for c in testString:
    answer = c in "aeiouAEIOU"
end = time.clock()
print end-start

start = time.clock()
for c in testString:
    pass
end = time.clock()

Prints:

3.27782246068
1.76839123408
0.713913919227

The third loop shows the time it takes just to iterate over the testString itself, so the time spent in the body of the loop (assuming pass takes negligible time) is:

2.563908541
1.054477315

By avoiding the lower() call, the second technique is more than twice as fast.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜