Error in python - don't understand
I'm creating a game, and am quite new to Python generally.
I created a function 'descriptionGenerator()' which generates a description for characters and objects either randomly or using variables passed to it.
It seemed to be working, but every now and then it wouldn't work correctly. So i placed it in a loop, and it never seems to be able to complete the loop without one of the iterations having this problem.
The code is as follows:
#+------------------------------------------+
#| Name: bitsandpieces.py |
#| A module for the 'Europa I' game |
#| created for the Game Making Competition |
#| |
#| Date Created/Modified: |
#| 3/4/10 | 3/4/10 |
#+------------------------------------------+
# Import the required modules
# Import system modules:
import time
import random
# Import 3rd party modules:
# Import game modules:
# Define the 'descriptionGenerator()' function
def descriptionGenerator(descriptionVariables):
descriptionVariableSize = len(descriptionVariables)
if descriptionVariables[0] == 'char':
# If there is only one variable ('char'), create a random description
if descriptionVariableSize == 1:
# Define choices for descriptionVariables to be generated from
gender_choices = ['male', 'female']
hair_choices = ['black', 'red', 'blonde', 'grey', 'brown', 'blue']
hair_choices2 = ['long', 'short', 'cropped', 'curly']
size_choices = ['tubby', 'thin', 'fat', 'almost twig-like']
demeanour_choices = ['glowering', 'bright', 'smiling', 'sombre', 'intelligent']
impression_choices = ['likeable', 'unlikeable', 'dangerous', 'annoying', 'afraid']
# Define description variables
gender = random.choice(gender_choices)
height = str(float('0.' + str(random.randint(1, 9))) + float(random.randint(1, 2)))
if float(height) > 1.8:
height_string = 'tall'
if float(height) > 2:
height_string = 'very tall'
elif float(height) < 1.8 and float(height) > 1.5:
height_string = 'average'
elif float(height) < 1.5:
height_string = 'short'
if float(height) < 1.3:
height_string = 'very short'
hair = random.choice(hair_choices2) + ' ' + random.choi开发者_如何学Goce(hair_choices)
size = random.choice(size_choices)
demeanour = random.choice(demeanour_choices)
impression = random.choice(impression_choices)
# Collect description variables in list 'randomDescriptionVariables'
randomDescriptionVariables = ['char', gender, height, height_string, hair, size, demeanour, impression]
# Generate description using the 'descriptionGenerator' function
descriptionGenerator(randomDescriptionVariables)
# Generate the description of a character using the variables passed to the function
elif descriptionVariableSize == 8:
if descriptionVariables[1] == 'male':
if descriptionVariables[7] != 'afraid':
print """A %s man, about %s m tall. He has %s hair and is %s. He is %s and you get the impression that he is %s.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
elif descriptionVariables[7] == 'afraid':
print """A %s man, about %s m tall. He has %s hair and is %s. He is %s.\nYou feel that you should be %s of him.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
elif descriptionVariables[1] == 'female':
if descriptionVariables[7] != 'afraid':
print """A %s woman, about %s m tall. She has %s hair and is %s. She is %s and you get the impression that she is %s.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
elif descriptionVariables[7] == 'afraid':
print """A %s woman, about %s m tall. She has %s hair and is %s. She is %s.\nYou feel that you should be %s of her.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
else:
pass
elif descriptionVariables[0] == 'obj':
# Insert code here 2 deal with object stuff
pass
print
print
myDescriptionVariables = ['char']
i = 0
while i < 30:
print
print
print
descriptionGenerator(myDescriptionVariables)
i = i + 1
time.sleep(10)
When it fails to properly execute it says this:
Traceback (most recent call last):
File "/Users/Jasper/Development/Programming/MyProjects/Game Making Challenge/Europa I/Code/Code 2.0/bitsandpieces.py", line 79, in <module>
descriptionGenerator(myDescriptionVariables)
File "/Users/Jasper/Development/Programming/MyProjects/Game Making Challenge/Europa I/Code/Code 2.0/bitsandpieces.py", line 50, in descriptionGenerator
randomDescriptionVariables = ['char', gender, height, height_string, hair, size, demeanour, impression]
UnboundLocalError: local variable 'height_string' referenced before assignment
Thanks for any help with this
-----EDIT-----
Thanks for the help, fixed that problem, but now there is another one!
I changed this segment of code 2 take the strings as variables, then 'return' them, and then test them:
elif descriptionVariableSize == 8:
if descriptionVariables[1] == 'male':
if descriptionVariables[7] != 'afraid':
descriptionOutput = """A %s man, about %s m tall. He has %s hair and is %s. He is %s and you get the impression that he is %s.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
return descriptionOutput
elif descriptionVariables[7] == 'afraid':
descriptionOutput = """A %s man, about %s m tall. He has %s hair and is %s. He is %s.\nYou feel that you should be %s of him.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
return descriptionOutput
elif descriptionVariables[1] == 'female':
if descriptionVariables[7] != 'afraid':
descriptionOutput = """A %s woman, about %s m tall. She has %s hair and is %s. She is %s and you get the impression that she is %s.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
return descriptionOutput
elif descriptionVariables[7] == 'afraid':
descriptionOutput = """A %s woman, about %s m tall. She has %s hair and is %s. She is %s.\nYou feel that you should be %s of her.""" %(descriptionVariables[3], descriptionVariables[2], descriptionVariables[4], descriptionVariables[5], descriptionVariables[6], descriptionVariables[7])
return descriptionOutput
else:
print 'Incorrect number of variables contained within \'descriptionVariables\''
elif descriptionVariables[0] == 'obj':
# Insert code here 2 deal with object stuff
pass
myDescriptionVariables = ['char']
myOutput = descriptionGenerator(myDescriptionVariables)
print myOutput
However, when I run this, it gives the following output:
None
What am I doing wrong?
You define height_string inside if/else statements:
if float(height) > 1.8:
height_string = 'tall'
if float(height) > 2:
height_string = 'very tall'
elif float(height) < 1.8 and float(height) > 1.5:
height_string = 'average'
elif float(height) < 1.5:
height_string = 'short'
if float(height) < 1.3:
height_string = 'very short'
However, if height == 1.8 or height == 1.5, all if/elif statements are false, and therefore height_string is never defined. Simply change the second statement to have <= and >= signs instead:
elif float(height) <= 1.8 and float(height) >= 1.5:
In response to your edit:
You call the function with
myOutput = descriptionGenerator(["char"])
Notice that you're passing a list of length one. Therefore, your function sees descriptionVariableSize == 1
and creates the random description.
So far, so good.
But wait! At the end of that if statement, you have an elif:
elif descriptionVariableSize == 8:
Now you do have descriptionVariableSize == 8. However, you used elif - so you just spent all that time creating a random set of descriptions, but you never get to use it, because the first statement was true and this statement is only executed if the first statement was false.
The solution - just change that elif
to if
. Now, whether you pass in a complete statement or generate one in the function, you'll still reach the second section.
Edit the ... fifth ?
I didn't notice that you call the function again at the end of the random section. Note that you don't return
that call - so anything returned is lost to the void. Simply change it to
return descriptionGenerator(randomDescriptionVariables)
As an added note - your function is getting a bit unwieldy. The problem is that you're doing two completely different things in the function - one is generating a random list of qualities, and another is generating a description from those quallities. It may be better to move the stuff in the first if
block into its own function, generateRandomDescription()
, or something, that only gets called in that first if
block.
While you check to see if height
is greater than or less than 1.5 or 1.8, you have nothing in place if it is equal to one of those values. Change the comparisons around those points to either >=
and <
, or to >
and <=
.
精彩评论