Newbie here, I am currently writing a "game" in ex 36 of LearnPythonTheHardWay.
If I wanted to ask for the user's name in one function. How can I recall that persons name in all the other functions without asking for it again, or setting it = to the name again? From my understanding variables in a function don't affect other functions, but what if I want it to?
def room_1():
name = raw_input("What is your name?")
print "hi %s" % name
def room_7():
print "Hi %s" % name
Two ways, first would be to create a class and set an attribute called playername. Something like:
class Game(object):
def __init__(self,playername=None):
if playername is None: self.playername = raw_input("What's your name? ")
else: self.playername = playername
# initialize any other variables here
def run(self):
# all your code goes here, and self.playername
# is always your player's name.
game = Game()
game.run()
The other was is widely (and properly!) frowned upon. You could use a global
global name
name = raw_input("What is your name? ")
Now so long as you don't overwrite name in any of your functions, they can call name and access it as if it were a local variable.
EDIT: It looks like you're trying to build a game that should implement a Finite State Machine which is almost certainly beyond your ability to make right now. You can CERTAINLY do it without one, but the code will always have that "spaghetti" feel to it. class Game is the first step towards the FSM, but there's a long way to go :)
You should declare it as global when asking for the name, so it is available in other functions:
def room_1():
global name
name = raw_input("What is your name?")
print "hi %s" % name
def room_7():
print "Hi %s" % name
For now you can define a variable outside of a function, then call it with the global keyword.
Normally you would use a class for this sort of thing, but you'll get there eventually :o)
name = ''
def room_1():
global name
name = raw_input("What is your name?")
print "hi %s" % name
def room_7():
global name
print "Hi %s" % name
Related
I'm trying to make a class, Player, and I'd like the user to create objects, say to add to their team.
Every tutorial will have something like this to create new players, say Jordan.
class Player:
def __init__(self, name):
self.name = name
p1 = Player('Jordan')
p2 = Player('Kobe')
But I want the user to have the ability to create new players, and they're not going to code, right?
And I would rather the object variable be just the player name, like, "Jordan", or "Kobe".
So if everything was manual, I could say,
jordan = Player('Jordan')
kobe = Player('Kobe')
So to come up with a function to have users create players, what should it look like? And what would the variable be? Any way to get it assigned as the player name? Or at least a serialized number like p1, p2, p3, ...?
def create_player():
new_player = input("Which player would you like to create? ")
name_of_variable_for_player = Player(new_player)
Ok, so follow on question.
What happens when you just have a static variable in the create function?
def create_player():
p = Player(input("What player would you like to make? ")
Use a dict instead of dynamic variables. For more details see How do I create a variable number of variables?
In this case that might look something like this:
class Player:
def __init__(self, name):
self.name = name
def __repr__(self): # Adding this for better output
cls_name = type(self).__name__
return '{}({!r})'.format(cls_name, self.name)
my_team = {}
name = input("Which player would you like to create? ")
my_team[name] = Player(name)
print(my_team)
Example run:
Which player would you like to create? Shaq
{'Shaq': Player('Shaq')}
How to turn that into a function might vary based on what you're trying to do, but you could start here:
def add_player_to_roster(roster):
name = input("Which player would you like to create? ")
roster[name] = Player(name)
my_team = {}
add_player_to_roster(my_team)
print(my_team)
Im having some issues with player not defined errors this is the error and the codes i have putten links to the pictures of it.Im pretty new at python and i don't understand most of the errors,i will be happy if someone could help.
Player not defined errors
Code
Code
I have created a minimal working code about your attached pictures. Mostly your global variable handling was not correct. You can find my comments in the below code as comments.
Code:
# Define global variable
current_player = None
class Player(object):
def __init__(self, name):
self.name = name
self.other = 100
def main():
option = input("Option: ")
if option == "1":
start()
def start():
# Use the global variable inside the function.
global current_player
user_name = input("Name: ")
# Assign the Player instance to the global variable.
current_player = Player(name=user_name)
start1()
def start1():
# Use the global variable inside the function.
global current_player
# Get the "name" attribute of the "Player" object.
print("Hello my friend: {}".format(current_player.name))
main()
Output:
>>> python3 test.py
Option: 1
Name: Bill
Hello my friend: Bill
>>> python3 test.py
Option: 1
Name: Jill
Hello my friend: Jill
Note:
I suggest to get rid of the global variable usage. Pass the required variables as parameters. I have implemented a version which doesn't contain global variables.
def start():
user_name = input("Name: ")
# Assign the Player instance to the global variable.
current_player = Player(name=user_name)
start1(current_player)
def start1(current_player_info):
# Get the "name" attribute of the "Player" object.
print("Hello my friend: {}".format(current_player_info.name))
PS:
In your next question, do not attach or link pictures. Please add a minimal code and your issue (traceback). Please read it: https://stackoverflow.com/help/how-to-ask
I have a global variable that I change in a function but when I call the global variable later in code in a different function, it doesn't store the change when the variable is first called:
name = "noname"
def username():
print ("It would help if I had a name to go by, please enter a name.")
global name
name = input()
def character():
global name
print ("Character overview:\nName:"+name+"")
And the output of character() is noname instead of the input.
Is there a way keeping the change in the first function?
This works for me.
name = "noname"
def user():
global name
name = input()
def char():
# Works with or without global here
print(name)
user()
char()
I'm having some trouble with classes at the minute, and I not sure of how to solve my problem. I've read the docs and I can't connect anything said there with the problem I'm having.
I'm trying to make some simple classes for a game. I have a Weapon class and a Person class. I'm trying to pass a Weapon to the Person class (I hope this makes sense), so that the Person (Bob) can use the weapon. I'm having trouble accessing the methods and attributes in the Weapon class. I've considered making Person a child class of Weapon so that it can call the method easily, but that doesn't seem intuitive to me . . .
class Weapon:
def __init__(self, weapon_name, weapon_damage):
self.weapon_name = weapon_name
self.weapon_damage = weapon_damage
def display_weapon_name(self):
print('Weapon Name: %s' %self.weapon_name)
class Person:
def __init__(self, person_name, health, ranged_weapon):
self.person_name = person_name
self.health = health
Weapon.ranged_weapon = ranged_weapon
def display_person_info(self):
print('Name: %s' %self.person_name)
print('Ranged Weapon :%s' %Weapon.display_weapon_name)
def ranged_attack(self, ranged_weapon, target):
target.health -=ranged_weapon.weapon_damage
print("Weapon: %s" %ranged_weapon.weapon_name)
print(target.person_name + "'s Health: "+str(target.health))
pistol = Weapon("Pistol", 40)
bob = Person("Bob", 100, pistol)
bob.display_person_info()
Running this gives me:
Name: Bob
Ranged Weapon :<function Weapon.display_weapon_name at 0x02E23030>
Running:
bob.ranged_attack(pistol, bob)
Gives:
Weapon: Pistol
Bob's Health: 60
My questions are, am I passing the Weapon object correctly to the Person class? It seems weird writing Weapon.ranged_weapon in _init__ rather than self.ranged_weapon.
How can I get the display_weapon_info to show the string 'Weapon Name: Pistol', rather than the reference? It seems to work when I call it in ranged_attack, but not in the display info.
Really appreciate any help I can get with this. Apologies if a similar question has been asked before, but I couldn't find anything I could relate to my issue.
Rich
Person doesn't actually need to reference the Weapon class directly; it just needs to save a reference to whatever is passed as the ranged_weapon argument and know what it can do with that object. The code implicitly assumes that ranged_weapon is an instance of Weapon, but will work with any object that is suitably similar to an instant of Weapon.
class Person:
def __init__(self, person_name, health, ranged_weapon):
self.person_name = person_name
self.health = health
self.weapon = ranged_weapon
def display_person_info(self):
print('Name: %s' %self.person_name)
# display_weapon_name already calls print; but
# you probably don't need this method at all.
self.weapon.display_weapon_name()
# Instead, do this (actually, you already do this
# in ranged_attack())
# print('Weapon: %s' % self.weapon.weapon_name)
def ranged_attack(self, ranged_weapon, target):
target.health -= self.weapon.weapon_damage
print("Weapon: %s" % self.weapon.weapon_name)
print(target.person_name + "'s Health: "+str(target.health))
def display_person_info(self):
print('Name: %s' %self.person_name)
print('Ranged Weapon :%s' %Weapon.display_weapon_name)
Looking at this function, the compiler sees the following:
Line 1: A function named display_person_info with the parameter self.
Line 2: Print "Name: " and then print the name of self
Line 3: Print "Ranged Weapon: " and then Weapon.display_weapon_name.
In line 3, the compiler, rather than printing the weapon name, it is printing the function display_weapon_name itself! What you need to do instead is replace Line 3 with this:
print('Ranged Weapon :%s' %self.weapon.display_weapon_name())
That way, the value returned by the function is printed, rather than the function's pointer.
Am new to Python OOP. Please dont be harsh. Here is my code which calculates which is the fastest time of an athlete from a list and displays them. But When Running, I get this error:
z= add.mylist.min()
NameError: global name 'add' is not defined
My Code:
class Athlete:
def add(self):
list=[]
mylist=[]
for i in range(2):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time: ")
list.append(self.name)
mylist.append(self.fastest_time)
print "Names: ",list
print "Fastest times: ",mylist
def display(self):
z= add.mylist.min()
w= add.mylist.index(z)
print "Minimum time: ",z
print "Name of athelte with fastest time: ",list[w]
x = Athlete()
x.add()
x.display()
You need to refer to methods on the instance with the self parameter. In addition, your add() method needs to return the mylist variable it generates, you cannot refer to method local variables as attributes on methods:
def display(self):
mylist = self.add()
z = min(mylist)
w = mylist.index(z)
def add(self):
list=[]
mylist=[]
for i in range(2):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time: ")
list.append(self.name)
mylist.append(self.fastest_time)
print "Names: ",list
print "Fastest times: ",mylist
return mylist
That is what self is for, as a reference point to find instance attributes and other methods on the same object.
You may want to rename list to something that does not shadow the built-in type.
Martijn has already answered your question, so here are some remarks and code style tips:
New-style classes derive from object
You have both athlete names and their times, those belong together as key-value pairs in a dictionary instead of two separate lists
Don't use print statements inside class methods, a class method should return an object that you then can print
what if you have more then 2 athletes for which you want to enter the time? If you make the number of athletes an argument of your function, you can add a variable number of athlethes
give descriptive variable names (not mylist) and don't use names of builtin functions (like list) as variable name
variables that you want to use throughout your class can be initalized in an __init__method.
For printing, use the format function instead of using commas
use if __name__ == '__main__' so that your Python file can act as either reusable modules or as standalone program
Taking these into account, I would rewrite your code to something like this:
from collections import defaultdict
class Athlete(object): # see (1)
def __init__(self): # see (6)
self.athlete_times = defaultdict(str) # see (2)
def add_athletes_and_times(self, n): # see (4)
for i in range(n):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time (in seconds): ")
self.athlete_times[self.fastest_time] = self.name
def get_fastest_time(self):
return min(self.athlete_times) # see (3)
if __name__ == '__main__': # see (8)
x = Athlete()
x.add_athletes_and_times(2)
for fast_time in x.athlete_times:
print "The fastest time of athlete {0} is {1} seconds.".format(
x.athlete_times[fast_time], fast_time) # see (7)
fastest_time = x.get_fastest_time()
print "The overall fastest time is: {0} seconds for athlete {1}.".format(
fastest_time, x.athlete_times[fastest_time])