How can I label a certain mob, and pull it later - python

I send this code through a program to decide which mobs the user will be fighting, but every time it gets to this it produces "Headless_Horseman (or whichever mob it picks) is undefined." I cannot figure out how to 'define' the name.
def mob_picker_randmob1 ():
global Zombie
global Zambie
global Giant_Worm
global Headless_Horseman
global Skeleton
global Ghost
global Ghoul
global Baby_Sister
global Little_Sister
global Big_Sister
randmob1=random.randint(1,5)
if randmob1 == 1:
randmob1 = Zombie
mob_picker_randmob2 ()
elif randmob1 == 2:
randmob1 = Skeleton
mob_picker_randmob2 ()
elif randmob1 == 3:
randmob1 = Giant_Worm
mob_picker_randmob2 ()
elif randmob1 == 4:
randmob1 = Headless_Horseman
mob_picker_randmob2 ()
elif randmob1 == 5:
randmob1 = Zambie
mob_picker_randmob2 ()

you will need to assign values to the variables in your main function, since you are declaring these as global variables.
Zombie = 'zombie'
Zambie = 'zAmbie'
Giant_Worm = 'big worm'
Headless_Horseman = 'horseman without head'
Also, consider using random.choice()
choices = (
Zombie, Zambie, Giant_Worm, Headless_Horseman, Skeleton,
Ghost, Ghoul, Baby_Sister, Little_Sister, Big_Sister,
)
return random.choice(choices)

Related

unexpected indent error inside a definition for a function

I have this code for the movement of a monster to move randomly between rooms but I get an unexpected intention error for the global value.
def monster(): """moves the monster randomly"""
global monster_current_room
if monster_current_room["name"] != current_room:
print('The monster is currently in', monster_current_room["name"])
exits = list(monster_current_room["exits"].values())
if random.randint(1, 4) == 4:
monster_current_room = rooms[random.choice(exits)]
elif monster_current_room["name"] == current_room:
game_over = True
if I unindent the global value it acts as the end of the definition and wants two lines between the definition and global value. when I try to run with the indent the program fails with the error.
You have misplaced the function comment:
def monster():
"""
moves the monster randomly
"""
global monster_current_room
if monster_current_room["name"] != current_room:
print('The monster is currently in', monster_current_room["name"])
exits = list(monster_current_room["exits"].values())
if random.randint(1, 4) == 4:
monster_current_room = rooms[random.choice(exits)]
elif monster_current_room["name"] == current_room:
game_over = True
or if you prefer an inline comment you can do like that
def monster(): # moves the monster randomly
global monster_current_room
if monster_current_room["name"] != current_room:
print('The monster is currently in', monster_current_room["name"])
exits = list(monster_current_room["exits"].values())
if random.randint(1, 4) == 4:
monster_current_room = rooms[random.choice(exits)]
elif monster_current_room["name"] == current_room:
game_over = True
when you write a multiline string like
"""
moves the monster randomly
"""
it has to respect the rules of the classic sentences of the python code. So you can't place them whenever you want like comments.

Labels appearing buffered, but Python code is running unbuffered

I am currently creating a blackjack game using Python3 on Sublime Text. When the dealers cards are drawn one by one, you can see it being drawn one by one in the console using the after() to call on different functions, but in the actual GUI all the cards are appearing at the same time, right at the end.
Here is a portion of the code:
def d_pick_a_card():
global d_hand
global card
global deck
global d_counter
global cvpath
global cardvalue
global d_card_relx
global cv
cardvalue = 0
card = deck.pop(0)
print('Drew',card)
if card == 'J':
cardvalue = 10
cvpath = 11
elif card == 'Q':
cardvalue = 10
cvpath = 12
elif card == 'K':
cardvalue = 10
cvpath = 13
elif card == 'A':
cardvalue = 11
cvpath = 14
else:
cardvalue = card
cvpath = card
d_hand.append(cardvalue)
random.shuffle(deck)
random.shuffle(deck)
d_counter += 1
#THIS IS THE FUNCTION THAT SHOWS THE VISUAL CARD ON THE GUI
def d_pick_vis(cardvalue, d_counter):
global dealers_turn
global card_frame
card_frame = tk.Label(top, image = cv[cvpath])
card_frame.place(relx= d_card_relx[d_counter], rely=.18, anchor='center')
widgetList.append(card_frame)
def dturnfunc():
global dealersturn_img
holding_img1.pack_forget()
dealersturn_img = tk.Label(top, image = dealersturn)
dealersturn_img.img = dealersturnpath
dealersturn_img.pack()
top.after(500, dealers_turn())
def dealers_turn():
global cardvalue
global d_counter
d_pick_a_card()
d_pick_vis(cardvalue, d_counter)
print("The Dealers hand is:", sum(d_hand))
print('\n')
if sum(d_hand) <= sum(hand):
print('Dealer picks again')
top.after(500,dealers_turn_2())
elif sum(d_hand) == 21:
print('Dealer Wins')
elif sum(d_hand) >= 22:
print('You win!')
else:
print('Dealer Wins')
You are calling the functions in your calls to after(), instead do this:
top.after(500, dealers_turn) # Note: just pass in the name of the function
...
top.after(500, dealers_turn_2)
You need to pass in a reference to the function and after() will call that function after the time elapses.
When you were calling the functions yourself, you pass in the return value, which is probably None which, I'm guessing, after() ignores.

Local variable referenced before assignment global doesn't work

how can I make this function working? Is there a good subsitute for global??
position=0
score=0
eggY=300
eggX=0
def egglg():
while True:
global eggX
global eggY
if eggX<330:
eggX+=5
eggY+=0.8
elif eggX>=330:
eggY=eggY+2
if eggY>450:
terminate()
elif eggY<450 and eggY>350 and position ==1:
score+=1
return
#rest of my code, with chaning position to 1 when i press w
egglg()
somehow it returns 0
Since you want to write to the global variables eggX, eggY and score you've to declare all 3 variables global:
position=0
score=0
eggY=300
eggX=0
def egglg():
global eggX, eggY, score
# [...]
Note, the variable position is just read, so there is no necessity to declare it golabal.

Name 'variable' is not defined after implementing 'global variable' inside the function

I am currently working on my first program on python, however, when I've encountered a problem concerning the scope of definition of my variables. Here is the problematic sample of my code :
def listen(topLeft, bottomRight):
timeless = 0
# The key combination to check
COMBINATIONS = [
{keyboard.Key.shift, keyboard.KeyCode(char='b')}
]
# The currently active modifiers
current = set()
def execute():
global topLeft,bottomRight,timeless
print("Do Something")
if timeless == 0:
topLeft = mouse.position
timeless += 1
elif timeless == 1:
bottomRight = mouse.position
timeless += 1
elif timeless >= 2:
return False
def on_press(key):
global timeless
if any([key in COMBO for COMBO in COMBINATIONS]):
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
execute()
def on_release(key):
if any([key in COMBO for COMBO in COMBINATIONS]):
current.remove(key)
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
Basically, once the Listener calls on_press, execute is called. In order to pass the timeless variable, I use the global tag. However, once the program comes to executing the execute function, I receive the following error code : NameError: name 'timeless' is not defined.
Any help would be appreciated, as I have tried pretty much everything I could
Since timeless is actually a local variable in the function listen, it's not a global variable, and in fact your error comes from the fact that there is no global variable named timeless. What execute needs is to declare timeless (and probably topLeft and bottomRight as well) as nonlocal, so that it refers to the first binding in the stack of containing lexical scopes.
def listen(topLeft, bottomRight):
timeless = 0
# The key combination to check
COMBINATIONS = [
{keyboard.Key.shift, keyboard.KeyCode(char='b')}
]
# The currently active modifiers
current = set()
def execute():
# modify the local variables in listen
nonlocal topLeft,bottomRight,timeless
print("Do Something")
if timeless == 0:
topLeft = mouse.position
timeless += 1
elif timeless == 1:
bottomRight = mouse.position
timeless += 1
elif timeless >= 2:
return False
...
In a function defined at the global scope, global and nonlocal are identical, as the first containing scope is the global scope. In a nested function, global jumps straight to the global scope, while nonlocal walks up the nesting scopes one at a time.
You declare a global variable outside of any function. You can reference a global variable inside a function without using the keyword. You only need to use the keyword global when you are assigning a new value to the variable, sort of as a way of specifying that you want to assign the value to the global variable and not to a new local variable that shares the same name. See this for examples. For your example, first define your globals outside of any function, then use them in the functions, using the global keyword when you want to modify:
# Global variable definitions outside of any function.
timeless = 0
topLeft = 0
bottomRight = 0
# Define the function that uses the variables.
def execute():
print("Do Something")
global timeless
if timeless == 0:
global topLeft # modifying the global variable with this name!
topLeft = mouse.position
timeless += 1
elif timeless == 1:
global bottomRight # modifying the global variable!
bottomRight = mouse.position
timeless += 1
elif timeless >= 2:
return False
All of that said, it's probably best to avoid globals in general. You could define a class instead and use a member property for those things that need to be modified and referenced in multiple methods. For example, something like:
class Listener:
def __init__(self):
self.timeless = 0
self.top_left = 0
self.bottom_right = 0
def execute(self, mouse): # pass some mouse object in, otherwise what's "mouse"?
print('Do something')
if self.timeless == 0:
self.top_left = mouse.position
self.timeless += 1
elif self.timeless == 1:
...
timeless = 0
topLeft = 0
bottomRight = 0
current = set()
def listen(topLeft, bottomRight):
timeless = 0
# The key combination to check
COMBINATIONS = [
{keyboard.Key.shift, keyboard.KeyCode(char='b')}
]
# The currently active modifiers
current = set()
def execute():
print("Do Something")
if timeless == 0:
topLeft = mouse.position
timeless += 1
elif timeless == 1:
bottomRight = mouse.position
timeless += 1
elif timeless >= 2:
return False
def on_press(key):
if any([key in COMBO for COMBO in COMBINATIONS]):
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
execute()
def on_release(key):
if any([key in COMBO for COMBO in COMBINATIONS]):
current.remove(key)

TicTacToe project in Python 2: I am trying to avoid using global variables and return variables instead

I am working on a project, and I have no idea how to avoid using global variables. I have a list of functions that perform bits and pieces but I am not able to pass variables between them!
Here is my current code:
===================
def player_names_input():
global player_A_name,player_B_name
player_A_name = raw_input("Please enter name for Player A : ")
player_B_name = raw_input("Please enter name for Player B : ")
def coin_flip():
global player_A_name,player_B_name,start_player,end_player,game_state
game_state = "running"
import random
print "\nFlipping a coin to see who starts first..."
random_int = random.randint(0, 1)
if random_int == 0:
coin = 'Heads'
start_player = player_A_name
end_player = player_B_name
else:
coin = 'Tails'
start_player = player_B_name
end_player = player_A_name
print '\nCoin flip --> ',coin
print '\nStarting player --> ',start_player
print '\nStarting player gets "X"'
player_names_input()
coin_flip()
Here is my failed attempt to use return instead of global:
=========================================================
def player_names_input():
player_A_name = raw_input("Please enter name for Player A : ")
player_B_name = raw_input("Please enter name for Player B : ")
return player_A_name,player_B_name
def coin_flip(player_A_name,player_B_name):
game_state = "running"
import random
print "\nFlipping a coin to see who starts first..."
random_int = random.randint(0, 1)
if random_int == 0:
coin = 'Heads'
start_player = player_A_name
end_player = player_B_name
else:
coin = 'Tails'
start_player = player_B_name
end_player = player_A_name
print '\nCoin flip --> ',coin
print '\nStarting player --> ',start_player
print '\nStarting player gets "X"'
player_names_input()
coin_flip(player_A_name,player_B_name)
1- Please help make my second code run, I really wanna avoid global variables as everyone recommends.
2- Please critique my code, I am in the beginning and I am trying to learn writing good code (not just code). How bad is my attempt?
Since you have defined player_names_input() to return a 2-tuple (the two values, player_A_name and player_B_name), you could just assign them like so in the scope you are using that function,
player_A_name, player_B_name = player_names_input()
Now, when this is called:
coin_flip(player_A_name, player_B_name)
The two variables will be available for use.
You may want to consider wrapping the actual main program in a main method like
def main():
player_A_name, player_B_name = player_names_input()
coin_flip(player_A_name, player_B_name)
And call that if that file was directly executed - this is done by checking the magic __name__ variable to equal to the string '__main__', so add this too to the end of your program file.
if __name__ == '__main__':
main()

Categories

Resources