Python: NameError: global name 'lol' is not defined - python

I know there are a lot of these but i've been searching for an hour and nothing is working.
ship2X=eg.passwordbox("Player " + str(playerNumber) + " input the x co-ordinate for your SECOND ship ")
ship2Y=eg.passwordbox("Player " + str(playerNumber) + " input the y co-ordinate for your SECOND ship ")
return[ship2X, ship2Y]
The above code is in a function.
def haveShot(playerNumber, ship, ship2, board):
global ship2
eg.msgbox("Player " + str(playerNumber) + " your shot")
hit=False
shotX=eg.enterbox("Enter the x-coordinate for your shot: ")
shotY=eg.enterbox("Enter the y-coordinate for your shot: ")
.... error checking here....
if int(shotX) == int(ship[0]) and int(shotY) == int(ship[1]):
board[5 - int(shotY)][int(shotX) - 1] = "X"
eg.msgbox("Nice shot! You hit ship 1")
hit = True
elif int(shotX) == int(ship2[0]) and int(shotY) == int(ship2[1]):
board[5 - int(shotY)][int(shotX) - 1] = "X"
eg.msgbox("Nice shot! You hit ship 2")
hit = True
elif board[5 - int(shotY)][int(shotX) - 1] == "o":
eg.msgbox("You already tried that shot! D'oh!")
else:
board[5 - int(shotY)][int(shotX) - 1] = "o"
eg.msgbox("Unlucky - you missed!")
Ye, I have an if before that.
Then I have this near the end:
hit = False
winner = "0"
p1 = 0
p2 = 0
while hit == False:
hit = haveShot("1", player2Ship, player2Ship, player1Board)
if hit:
p1 = p1+1
hit = haveShot("2", player1Ship, player1Ship, player2Board)
if hit:
p2 = p2+2
I copied it from the first enter ship thing so I'm super confused as to why that's happening...
Any ideas?
If you want to see the full code you can see it at: http://pastebin.com/TAyHtnTs
The error I have is if I do enter the correct co-ordinate for the second ship it says I missed it, however if I enter the correct co-ordinates for the first ship it says I hit it like it shoul.
Thanks for the help you can provide :)

Couple of things:
Line 81
You can't have two subsequent return statements. The first one will exit the function. If you want to return two sets of coordinates return a nested list:
return [[x1, y1], [x2, y2]]
Line 161
Then use unpacking to get these:
p1ship1, p1ship2 = inputCoords("1")
p2ship1, p2ship2 = inputCoords("2")
Line 171/176
Make sure the two ships you're passing in are different (currently they're the same):
hit = haveShot("1", player2Ship, player2Ship, player1Board)
to
hit = haveShot("1", p2ship1, p2ship2, player1Board)
Line 170
The while hit == False condition means that the game will exit as soon as player 1's ship is hit. Use another variable to check if the game is over, such as:
while player1ShipCount > 0 and player2ShipCount > 0:
#play game
And keep track of each players' available ships.

I don't have enough reputation to comment, or I would, but...
You haven't defined "lol", you have defined "lolX" and "lolY", which are separate variables.
If you want to define a list or a dictionary with values inside, you cannot just write lolX or lolY, you would have to do (I use a dictionary here since it seems to be what you want):
lol = {}
lol[X]=eg.passwordbox("Player " + str(playerNumber) + " input the x co-ordinate for your SECOND ship ")
Then you can access the value in lol by lol[X].
You have defined separate variables, rather than define a specific value of that variable.

Related

how do I get the mov function to work properly

So, I have this input command that's supposed to give the user unprompted input and if it's an invalid command to output 'input' is an invalid command. However, go north, west, etc. is a valid command but the code does not recognize it as so. Pls help :)
btw, player is a module that has a class in it for moving the player's location.
Code:
import world, tiles
from player import Player
game = "play"
while game == "play":
x = input()
y = " is not a valid command"
string = x + y
if x == "go north":
Player.go_north
if x == "go south":
Player.go_south
if x == "go east":
Player.go_east
if x == "go west":
Player.go_west
if x == "pick up":
print("pick up what?")
else:
print(string)
There seems to be a couple of things wrong potentially. First, Player.go_* are being referenced as attributes, but I expect they should be functions if they do something? Technically I guess they could be properties, but this feels like the wrong way to use them.
Second, I think your if/else logic is not what you want. You check for each direction, but even if it suceeds, it drops down to the next if statement. So what happens is at the last check, if it's not "pick up", it will always print the invalid command string. You either want every conditional to be part of a if/elif/else so that once it hits one, it skips the others, or you need to have a continue after any successful check, since if you find a match, you just want to continue with the loop.
So something like:
import world, tiles
from player import Player
player = Player()
game = "play"
while game == "play":
x = input()
y = " is not a valid command"
string = x + y
if x == "go north":
player.go_north()
elif x == "go south":
player.go_south()
elif x == "go east":
player.go_east()
elif x == "go west":
player.go_west()
elif x == "pick up":
print("pick up what?")
else:
print(string)

Python fill-in-the-blanks code

I am a programming beginner and I am trying to build a fill-in-the-blank quiz. I am almost finished but I am stuck on 2 problems I am not able to solve, whatever I do. I would really appreciate your help with this. Thank you for helping me with this!
If you try to run the code and play the game:
1) It prints the quiz according to the difficulty(easy-insane) and quiz you want to play(apple, bond and programming quiz) which is great but afterwards it prompts you to choose difficulty again (the player_level() function keeps going even though the player/user has already chosen the difficulty level. I don't really understand why it does it? The player_level() procedure seems perfectly okay and logical to me.
2) The errors:
a) local variable blanks_index referenced before assignment
b) global name list_of_answers is not defined.
I know that it is related to the initialize_game() function but I don't know how to change the code so it refers all the variables (blanks_index, answers_index, player_lives) correctly.
It could be solved by creating global variables(I guess) but that is not a good practice so I am trying to avoid it. Formerly, the whole function initialise_game() and play_game() were one function, but as there are over 25 lines of code in one function, it is not a good practice as it is long and messy and I know that I can separate it but I don't know how.
Here is the code:
"""3 diffferent quizzes : Apple quiz, James Bond quiz, Programming quiz"""
"""Quiz and answers about Apple"""
Apple_quiz = ("The most valuable company in terms of market cap in 2016 is, ___1___."
"It was founded in ___2___. Its flagship product is called ___3___."
"___1___ has many competitors, the biggest rival is ___4___,founded by"
" nobody but the richest man on the planet,___5___ ___6___.")
list_of_answers_Apple = ["Apple", "1976", "Iphone", "Microsoft", "Bill", "Gates"]
"""Quiz and answers about Bond"""
Bond_quiz = ("James Bond is agent ___1___. He serves his country,___2___ ___3___"
" against its enemies. His car of choice is usually ___4___ ___5___."
" His favorite drink is ___6___.")
list_of_answers_Bond = ["007", "United", "Kingdom", "Aston", "Martin", "Martini"]
"""Quiz and answers about programming basics"""
Programming_quiz = ("___1___ are created with the def keyword. ___1___ are also called ___2___"
" You specify the inputs a ___1___ take by adding ___3___ separated by commas"
" between the parentheses. ___3___ can be standard data types such as string, number"
" ,dictionary, tuple, and ___4___ or can be more complicated such as ___5___"
" and ___6___ functions.")
list_of_answers_Programming = ["Functions", "procedures", "arguments", "lists", "objects", "lambda"]
blank_space = ["___1___", "___2___", "___3___", "___4___", "___5___", "___6___]"]
#List of levels with corresponding lives/guesses that player can have
quiz_list = ["Apple", "Bond", "Programming"]
level_list = ["easy", "medium", "hard", "superhard", "insane"]
lives_easy = 5
lives_medium = 4
lives_hard = 3
lives_superhard = 2
lives_insane = 1
def choose_quiz():
""" Prompts player to pick a type of quiz and loads the quiz """
#Input = player_quiz (raw input from player)
#Output = loaded quiz, player chose
while True:
player_quiz = raw_input("Please, select a quiz you want to play: "
"(Apple, Bond or Programming): ")
if player_quiz == "Apple":
return Apple_quiz
elif player_quiz == "Bond":
return Bond_quiz
elif player_quiz == "Programming":
return Programming_quiz
else:
print "We don't have such quiz, pick again!"
def answers_for_quiz():
""" Loads appropiate answers to the quiz that player has chosen"""
#Input = player quiz (raw input from player)
#Output = loaded quiz answers from the quiz player chose
player_quiz_pick = choose_quiz()
if player_quiz_pick == Apple_quiz:
return list_of_answers_Apple
elif player_quiz_pick == Bond_quiz:
return list_of_answers_Bond
elif player_quiz_pick == Programming_quiz:
return list_of_answers_Programming
def player_level():
""" Loads a difficulty that player chooses """
#Input = player_level_input (raw input of player choosing a difficulty)
#Output = corresponding number of lives:
#Easy = 5 lives, Medium = 4 lives
#Hard = 3 lives, Superhard = 2 lives
#Insane = 1 life
while True:
player_level_input = raw_input("Please type in a difficulty level: "
"(easy, medium, hard, superhard, insane): ")
if player_level_input == "easy":
return lives_easy #Easy = 5 lives
elif player_level_input == "medium":
return lives_medium #Medium = 4 lives
elif player_level_input == "hard":
return lives_hard #Hard = 3 lives
elif player_level_input == "superhard":
return lives_superhard #Superhard = 2 lives
elif player_level_input == "insane":
return lives_insane #Insane = 1 life
else:
print "We do not have such difficulty! Pick again!"
def correct_answer(player_answer, list_of_answers, answers_index):
""" Checks, whether the the answer from player matches with the answer list. """
#Input: player_answer (raw input that player enters in order to fill in the blank)
#Output: "Right answer!" or "Wrong! Try again!" this output will be later used in the game
if player_answer == list_of_answers[answers_index]:
return "Right answer!"
return "Wrong! Try again!"
def initialize_game():
"""Functions that sets up a game so we can play it """
player_quiz_pick, player_level_pick, list_of_answers = choose_quiz(), player_level(), answers_for_quiz()
print player_quiz_pick
print "\nYou will get maximum " + str(player_level_pick) + " guesses for this game. Good luck.\n"
blanks_index, answers_index, player_lives = 0, 0, 0
#for elements in blank_space:
while blanks_index < len(blank_space):
player_answer = raw_input("Please type in your answer for " + blank_space[blanks_index] + ": ")
if correct_answer(player_answer,list_of_answers,answers_index) == "Right answer!":
print "Correct answer! Keep going!\n"
player_quiz_pick = player_quiz_pick.replace(blank_space[blanks_index],player_answer)
answers_index += 1
blanks_index += 1
print player_quiz_pick
if blanks_index == len(blank_space):
print "Congratulations! You nailed it! You are the winner!"
else:
player_level_pick -= 1
if player_level_pick == 0:
print "Game over! Maybe next time!"
break
else:
print "One life less, that sucks! Have another shot!"
print "You have " + str(player_level_pick) + " guesses left."
initialize_game()
Your main problem is that you keep calling the same functions over and over again and do not save the input into variables. Here are some tips about your code and questions:
You are not doing anything with your player_level() method call, so the player doesn't actually chooses a level in a way that affects the game. You should change the function call, so the returned value will be stored.
//the call to the method:
player_level_pick = player_level()
Afterwards, you keep calling the player_level() method, and not using the actual answer that the user supplied. Change all player_level() appearences to player_level_pick - the variable you use to save the answer (as I showed above). Same goes to all other unneeded function calls such as choose_level().
You should initialize number_of_guesses, player_lives, list_of_answers, and other vars to a matching value to player_level_pick as well, so it will hold the right value according to the level. Likewise, you should change this line:
# the line that checks if game is over
# change from:
if number_of_guesses == player_lives:
# to :
if number_of_guesses == 0:
In order to return multiple values, you have to use tuples. Using multiple return statements one after the other does not work anywhere.
so, instead of:
return list_of_answers
return number_of_guesses
return blanks_index
return answers_index
return player_lives
you should use tuples, and unpack them properly:
# the return statement:
return (list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives)
# and the unpacking in the calling function:
list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives = initialize_game()
this way, all of the returned values go into the wanted variables in the calling function. this way, you need to call the initialize_game() from play_game(). it will be the efficient way for you.
Just saying it again, as I said in the end of (4) - you should unit initialize_game() and play_game() into a single function (because a lot of data is the same needed data), or just call initialize_game() from play_game().
Better practice then using this recursivly: return choose_level(), you should use a while True: loop, and just brake when you get a proper answer.

How do I eliminate the "'str' object is not callable"?

I get the following error on the code below, and have no idea what is going on. I'm very much a beginner and need some help. I am trying to make a very basic game of tic-tac-toe in the console, and am having trouble.
Traceback (most recent call last):
File "D:/Eric/Projects/Tic Tac Toe/Tic Tac Toe.py", line 68, in <module>
printboard()
File "D:/Eric/Projects/Tic Tac Toe/Tic Tac Toe.py", line 15, in printboard
print("",c[0],"|",c[1],"|",c[2],"\n-----------\n",c[3],"|",c[4],"|",c[5],"\n-----------\n",c[6],"|",c[7],"|",c[8])
TypeError: 'str' object is not callable
Code:
import random, time
#Variables
c = [str(i) for i in range(1,10)] #Cells
cpuletter = "string input"
coinoptions = ["heads", "tails"]
coinflip = random.choice(coinoptions)
play = ""
playercell = 0
#Functions
def printboard(): #Prints the gameboard with the cell variables in the spaces
print("",c[0],"|",c[1],"|",c[2],"\n-----------\n",c[3],"|",c[4],"|",c[5],"\n-----------\n",c[6],"|",c[7],"|",c[8])
return
#Introduction
print("Welcome to Tic Tac Toe. Below is the playing table.") #Welcome + Explanation
printboard()
print("The playing spaces are numbered 1 through 9.\nYou will use these numbers to refer to the places you would like to play your piece.\n")
#X or O?
playerletter = input("Would you like to be X's or O's?\n")
playerletter = playerletter.capitalize()
playerletter = playerletter[0]
while playerletter not in ["X", "O"]: #Confirm choice == "X" or "O." If not, ask again.
playerletter = input("""Sorry, that's not a valid option. Please choose "X" or "O."\n""")
playerletter = playerletter.capitalize()
playerletter = playerletter[0]
if playerletter == "X":
cpuletter = "O"
elif playerletter == "O":
cpuletter = "X"
#Who goes first?
playercoin = input("Randomizing who goes first:\nDo you choose heads or tails?\n") #Asking for "heads" or "tails"
playercoin = playercoin.lower()
while playercoin not in ["heads", "tails"]: #Confirm choice == "Heads" or "Tails." If not, ask again.
playercoin = input("""Sorry, that's not a valid option. Please choose "heads" or "tails."\n""")
playercoin = playercoin.lower()
print("...")
time.sleep(1) #Waits 1 seconds
if coinflip != playercoin: #Tells player who goes first
print("It landed " + coinflip + "! I will go first.")
play = 0
elif coinflip == playercoin:
print("It landed " + coinflip + "! You will go first.")
play = 1
#Game
input("""Ready to play? Press "Enter" to begin!\n""")
if play == 0:
random_index = random.randrange(9) #Randomly selects a cell to change to cpuletter
c[random_index] = cpuletter
print = ("Here is my move.")
printboard()
elif play == 1: #Allows player to choose cell to change to playerletter
printboard()
playercell = int(input("It's your turn. Type a cell number to choose where you play.\n"))
playercell = playercell - 1
c[playercell] = playerletter
printboard()
Edit: Forgot to say that this only happens when the computer goes first, and not the player. I fixed the print = ("Here is my move.") but am still having problems.
print = "Here is my move."
That line reassigns the builtin print function to a string. Don't do that.
Why make such a complex printing function? Format would come very handy right about now:
def printboard(): #Prints the gameboard with the cell variables in the spaces
table = \
'''
{} | {} | {}
----------
{} | {} | {}
----------
{} | {} |
'''
print(table.format(c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8]))
return
And finally to fix your error, change line 65:
move = ("Here is my move")
I ran your code, but I did not get any errors. This particular TypeError is usually caused by programmers mistakenly switching out square brackets with parentheses (therefore "calling" it as if the string was a function, which it's not.). Please check and run your code again.
EDIT: Solution: Change the variable name of print = "Here is my move." on line 65 to something else, like movePrint = "Here is my move".

Python 2 game coordinates class

I wanted to create a x-y coordinate system even though this is supposed to be a text RPG as to keep track of where everything is. So, I was experimenting on making a function and test for that function that would let the character move on a x-y grid, however, no matter what I try, I cannot make it work. Here is the code:
class Player:
def movement(charactor_movement):
proceed = 0
if charactor_movement == "left":
character.position_x = character.position_x - 1
proceed = 1
elif charactor_movement == "right":
character.position_x = character.position_x + 1
proceed = 1
elif charactor_movement == "forward":
character.position_y = character.position_y + 1
proceed = 1
elif charactor_movement == "backward" or charactor_movement == "back":
character.position_y = character.position_y - 1
proceed = 1
charactor = Player()
charactor.position_x = 0
charactor.position_y = 0
proceed = 0
while proceed == 0:
print "You are at",
print charactor.position_x,
print"x and",
print charactor.position_y,
print"y."
global charactor_movement
charactor_movement = raw_input("Where are you going?")
charactor.movement()
At this point, it does what it is supposed to do up to changing the coordinates, as it prints "You are at 0 x and 0 y" and "Where are you going?" no matter what I type. I have tried adding an else to the function which it defaulted to no matter what I typed and gave me "Sorry, I cannot understand you." Any comments on fixing or generally improving the code would be appreciated.(Note: For the testing I purposely did not add a way to exit. The class is what i need fixed.)
You are getting the same coordinates with each iteration because your values within your while loop are not changing. Incrementing character.position_x within movement will never change the value of character.position_x within your while loop, as it is outside your function's scope. You have to use the global keyword within your movement function for each variable you are changing should you want your current logic to remain the same. Additionally, why not just pass charactor_movement as a parameter to your movement function, as opposed to using global as you currently are doing.
A minimal example:
Consider the following:
def somefunct(x):
mycode = x
mycode = 'no codez'
while True:
print mycode
codez = raw_input('gimme teh codez: ')
somefunct(codez)
which outputs
>>>[evaluate untitled-1.py]
no codez
gimme teh codez: codez!
no codez
Declaring mycode as global in the function places it in the scope of the while loop when assigned, thus
def somefunct(x):
global mycode #make variable global here
mycode = x
mycode = 'no codez'
while True:
print mycode
codez = raw_input('gimme teh codez: ')
somefunct(codez)
results in the output
>>>[evaluate untitled-1.py]
no codez
gimme teh codez: codez!
codez!

Beginner to Python - why the heck is my while loop not working?

I am trying to write a program for an assignment where you input a specific command and you can play Rock-Paper-Scissors-Lizard-Spock against the computer.
It was done and working until I realized that the assignment instructions wanted me to make it so that you keep playing the game until one person gets five wins.
So I thought, no big deals, let's throw in a while loop and some variables to track the wins. But when I run the program, it only runs once still. I don't know what I am doing wrong - as this should work. This is my first time working with Python (version 3.3) and this IDE, so I really need some help. Usually I'd just debug but I can't figure out how to work the one in this IDE.
Here is my code. The trouble while-loop is at the way bottom. I am nearly positive everything inside the class works. I would like to note that I already tried while(computerWins < 5 and userWins < 5), so I don't think the condition is the problem.
import random
computerWins = 0
userWins = 0
print ('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\nSpock = sp')
class rockPaperScissorsLizardSpock:
#Two methods for converting from strings to numbers
#convert name to number using if/elif/else
#also converts abbreviated versions of the name
def convertName(name):
if(name == 'rock' or name == 'r'):
return 0
elif(name == 'Spock' or name == 'sp'):
return 1
elif(name == 'paper' or name == 'p'):
return 2
elif(name == 'lizard' or name == 'l'):
return 3
elif(name == 'scissors' or name == 'sc'):
return 4
else:
print ('Error: Invalid name')
#convert number to a name using if/elif/else
def convertNum(number):
if(number == 0):
return 'rock'
elif(number == 1):
return 'Spock'
elif(number == 2):
return 'paper'
elif(number == 3):
return 'lizard'
elif(number == 4):
return 'scissors'
else:
print ('Error: Invalid number')
#User selects an option, and their selection is saved in the 'choice' variable
#Using a while loop so that the user cannot input something other than one of the legal options
prompt = True
while(prompt):
i = input('\nEnter your selection: ')
if(i=='r' or i=='p' or i=='sc' or i=='l' or i=='sp'):
prompt = False
else:
print('Invalid input.')
prompt = True
#Convert the user's selection first to a number and then to its full string
userNum = convertName(i)
userChoice = convertNum(userNum)
#Generate random guess for the computer's choice using random.randrange()
compNum = random.randrange(0, 4)
#Convert the computer's choice to a string
compChoice = convertNum(compNum)
print ('You chose', userChoice)
print ('The computer has chosen', compChoice)
#Determine the difference between the players' number selections
difference = (compNum - userNum) % 5
#Use 'difference' to determine who the winner of the round is
if(difference == 1 or difference == 2):
print ('The computer wins this round.')
computerWins = computerWins+1
elif (difference == 4 or difference == 3):
print ('You win this round!')
userWins = userWins+1
elif(difference == 0):
print ('This round ended up being a tie.')
#Plays the game until someone has won five times
while(computerWins != 5 and userWins != 5):
rockPaperScissorsLizardSpock()
if(computerWins == 5 and userWins != 5):
print ('The computer wins.')
elif(computerWins != 5 and userWins == 5):
print ('You win!')
The essential problem is that rockpaperscissorslizardspock is a class, where you expect it to be a function. The code inside it runs exactly once, when the whole class definition is parsed, rather than each time you call the class as you seem to expect.
You could put the relevant code into an __init__ method - this is a fairly direct analogue of a Java constructor, and hence is is run each time you call the class. But in this case, you probably don't need it to be in a class at all - calling the class creates a new instance (like doing new MyClass() in Java), which you don't use. You would also in this case (or if you made it into a function) need to make some more modifications to make sure the game state persists properly.
The easiest actual solution is to:
delete the line class rockpaperscissorslizardspock: (and unindent everything below it)
Take all the code that was under the class but not in a function - everything from the player makes a selection to determining the winner of the round - and paste it in place of the call to rockpaperscissorslizardspock() in the bottom loop.
The first thing is that you are using a class where you should probably be using a function.
Your code initially runs because python is loading the class.
However, the line rockPaperScissorsLizardSpock() is creating new anonymous instances of your class which calls a constructor that you haven't defined so it does nothing.
One of the interesting things about python is that it allows nested functions so if you change the class to a def you're almost there.
After that, you'll run into trouble with global variables in a local context. That problem is already explained in another StackOverflow question: Using global variables in a function other than the one that created them.
Here is my suggestion for the skeleton to a more simple solution. Use some ideas from here if you like.
import random
legal_shapes = ['r', 'p', 'sc', 'sp', 'l']
scoreboard = [0, 0]
print('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\n'
'Spock = sp')
while(max(scoreboard) < 5):
print("\nScore is {}-{}".format(*scoreboard))
# pick shapes
p1_shape = input('Enter your selection: ')
if p1_shape not in legal_shapes:
print('Not legal selection!')
continue
p2_shape = random.choice(legal_shapes)
print('\np1 plays {} and p2 plays {}'.format(
p1_shape.upper(), p2_shape.upper()))
# determine int values and result indicator
p1_shape_int = legal_shapes.index(p1_shape)
p2_shape_int = legal_shapes.index(p2_shape)
res = (p1_shape_int - p2_shape_int) % 5
if res != 0:
res = abs((res % 2) - 2)
# Print winner
if res == 0:
print(' -> Draw!!')
else:
print(' -> p{} wins'.format(res))
scoreboard[res-1] += 1
print("\nThe game is over!!")
print("p{} won with score {}-{}".format(res, *scoreboard))
It outputs something like
(env)➜ tmp python3 rsp.py
SELECTION KEY:
Rock = r
Paper = p
Scissors = sc
Lizard = l
Spock = sp
Score is 0-0
Enter your selection: T
Not legal selection!
Score is 0-0
Enter your selection: l
p1 plays L and p2 plays SP
-> p2 wins
Score is 0-1
Enter your selection: l
p1 plays L and p2 plays SC
-> p2 wins
...
The game is over!!
p2 won with score 2-5

Categories

Resources