I am new to Python and creating a program within Maya, that creates a solar system. This is part of my code that is causing the problems (hopefully enough to understand). The first function defines the radius of the planet, and then creates a sphere accordingly. The second function needs to use the variable planetRadiusStr to determine the radius of the Torus(ring). However, planetRadiusStr is only defined in the first function, so I know I need to somehow pass the variable between functions. However, I cannot seem to get this to work. Can anyone help?
def planetRadius():
planetRadiusStr = raw_input("Please enter the radius of the planet:")
if float(planetRadiusStr)<float(sunRadiusStr):
cmds.polySphere(radius=float(planetRadiusStr), n='planet1')
else:
print "Planet Radius must be less than Sun Radius"
planetRadius()
def planetRings():
ringsStr = raw_input("Would you like this planet to have a ring?").lower()
if str(ringsStr) == "yes":
cmds.polyTorus(r=float(planetRadiusStr)*2, sr=0.5, n='ring1')
cmds.scale(1,0.2,1)
elif str(ringsStr) == "no":
pass
else:
print "Please enter 'yes' or 'no'."
planetRings()
(I can upload a photo of my code if that will be easier to read.)
Thanks!
A couple of things to consider here.
First, I'd get this working using only standard functions and not using raw_input(). Until you have other users you can just type the values you want into the listener; when you do have users you can create a proper GUI that just passes arguments into the functions.
So, I'd suggest you try it by just making functions that take the info you need:
def create_planet(name, radius):
planet, shape = cmds.polySphere(n = name, r = radius)
return planet
def create_sun (radius):
cmds.polySphere(name = "sun", r = radius)
In this case, you don't need to track the planet radius: you can derive it from the history of the planet itself if you know which planet to look at
def create_ring (planet):
planet_history = cmds.listHistory(planet) or []
pSphere = cmds.ls(*planet_history , type = 'polySphere')[0]
planet_radius = cmds.getAttr(pSphere + ".radius")
ring, ring_shape = cmds.polyTorus(r = planet_radius * 2, sr = .5, n = planet + "_ring")
cmds.scale(1,0.2,1)
cmds.parent(ring, planet, r=True)
With all that in place, you can manage the passing of arguments from one function to another manually in the listener:
p = create_planet("saturn", 1)
create_ring(p)
or, you can create another function that does multiple passes:
def add_planet (sun, planet, distance):
cmds.parent(planet, sun, r=True)
cmds.xform(planet, t= (distance, 0 ,0), r=True)
def solar_system ():
sun = create_sun (10)
mercury = create_planet( 'mercury', .5)
add_planet(sun, mercury, 20)
venus = create_planet( 'venus', .7)
add_planet(sun, venus, 40)
earth = create_planet( 'earth', .8)
add_planet(sun, earth, 50)
mars = create_planet( 'mars', .75)
add_planet(sun, mars, 60)
jupiter = create_planet( 'jupiter', 2)
add_planet(sun, jupiter, 70)
saturn = create_planet( 'satun', 1.2)
add_planet(sun, saturn, 80)
create_ring(saturn)
As you can see, as long as you're inside the function solar_system you can keep variables alive and pass them around -- you'll also notice that create_planet() returns the name of the planet created (maya may rename it behind you back, so it's a good idea to check this way) so you can pass that name along to other functions like 'create_ring' or 'add_planet' which need to know about other objrects.
def planetRadius():
planetRadiusStr = 42
#blas
planetRings(planetRadiusStr)
def planetRings(planetRadiusStr):
#blas
def planetRadius():
size = 4
return size
def planetRings(inputSize):
"function placed here"
print('my planet size was ' + str(inputSize))
var01 = planetRadius()
planetRings(var01)
#result : 'my planet size was 4'
If you are planning to create a UI, keep in mind that you should set your def as this :
def planetRadius(*args):
Indeed, maya UI output a default boolean variable and will create an error if you don't put *args.
Furthermore, if you try to pass a variable through a UI as yours:
def planetRings(inputSize, *args):
"function placed here"
print('my planet size was ' + str(inputSize))
You will have to look for the module functools.partial to specify the input size :
from functools import partial
import maya.cmds as cmds
cmds.button(l='exec', c=partial(planetRings, inputSize))
Related
The first function calls to make the tic tac toe board, and the code before creates the screen and turtle.
#import needed modules
import turtle
#make a screen
ttts = turtle.Screen()
#set up the pen
d = turtle.Turtle()
d.color("indigo")
d.pensize(4)
d.speed(5)
d.penup()
#make number list
number_list = ["1","2","3","4","5","6","7","8","9"]
current_number = "1","2","3","4","5","6","7","8","9"
#set beginning position
d.goto(-150,100)
#make square (function)
def square(*squares):
squares = 0
columns = 0
rows = 0
x = -75
y = 100
while (squares < 4):
d.pendown()
d.forward(225)
d.right(90)
squares = squares + 1
d.right(90)
while (columns < 2):
d.goto(x,y)
d.pendown()
d.forward(225)
d.penup()
x = x + 75
columns = columns + 1
d.right(90)
while (rows < 3):
d.goto(x,y)
d.pendown()
d.forward(225)
d.penup()
y = y + -75
rows = rows + 1
square()
This code above is fine, I have made sure to debug all the functions below as well. I'm just having trouble calling the functions at the end.
#make the numbers
def numbers():
d.penup()
d.color("yellow")
d.goto(-120, 50)
d.write(1, align='left', font = ('arial', 16))
d.goto(-45, 50)
d.write(2, align='left', font = ('arial', 16))
d.goto(30, 50)
d.write(3, align='left', font = ('arial', 16))
d.goto(-120, -25)
d.write(4, align='left', font = ('arial', 16))
d.goto(-45, -25)
d.write(5, align='left', font = ('arial', 16))
d.goto(30, -25)
d.write(6, align='left', font = ('arial', 16))
d.goto(-120, -100)
d.write(7, align='left', font = ('arial', 16))
d.goto(-45, -100)
d.write(8, align='left', font = ('arial', 16))
d.goto(30, -100)
d.write(9, align='left', font = ('arial', 16))
d.hideturtle()
numbers()
#function for defining symbols(x and o)
def draw_symbol(number_list):
number_list
symbolc()
symbolxs()
#functions for x and o
c = turtle.Turtle()
xs = turtle.Turtle()
def symbolc(circle):
circle = 0
def check_number_1():
if (current_number == "1"):
c.goto(-120,70)
ttts.onkeypress(check_number_1, "1")
def check_number_2():
if (current_number == "2"):
c.goto(-45,70)
ttts.onkeypress(check_number_2, "2")
def check_number_3():
if (current_number == "3"):
c.goto(30,70)
ttts.onkeypress(check_number_3, "3")
def check_number_4():
if (current_number == "4"):
c.goto(-120,-5)
ttts.onkeypress(check_number_4, "4")
def check_number_5():
if (current_number == "5"):
c.goto(-45,-5)
ttts.onkeypress(check_number_5, "5")
def check_number_6():
if (current_number == "6"):
c.goto(30,-5)
ttts.onkeypress(check_number_6, "6")
def check_number_7():
if (current_number == "7"):
c.goto(-120,-80)
ttts.onkeypress(check_number_7, "7")
def check_number_8():
if (current_number == "8"):
c.goto(-45,-80)
ttts.onkeypress(check_number_8, "8")
def check_number_9():
if (current_number == "9"):
c.goto(30,-80)
ttts.onkeypress(check_number_9, "9")
#--- main ---
if (circle < 1):
c.penup()
c.color("red")
c.circle(20)
circle = circle + 1
#crosses
def symbolxs(cross):
cross = 0
while (cross < 4):
def check_number_1():
if (current_number == "1"):
xs.goto(-120,70)
ttts.onkeypress(check_number_1, "1")
def check_number_2():
if (current_number == "2"):
xs.goto(-45,70)
ttts.onkeypress(check_number_2, "2")
def check_number_3():
if (current_number == "3"):
xs.goto(30,70)
ttts.onkeypress(check_number_3, "3")
def check_number_4():
if (current_number == "4"):
xs.goto(-120,-5)
ttts.onkeypress(check_number_4, "4")
def check_number_5():
if (current_number == "5"):
xs.goto(-45,-5)
ttts.onkeypress(check_number_5, "5")
def check_number_6():
if (current_number == "6"):
xs.goto(30,-5)
ttts.onkeypress(check_number_6, "6")
def check_number_7():
if (current_number == "7"):
xs.goto(-120,-80)
ttts.onkeypress(check_number_7, "7")
def check_number_8():
if (current_number == "8"):
xs.goto(-45,-80)
ttts.onkeypress(check_number_8, "8")
def check_number_9():
if (current_number == "9"):
xs.goto(30,-80)
ttts.onkeypress(check_number_9, "9")
xs.penup()
xs.color("lime")
xs.right(45)
xs.pendown()
xs.forward(10)
cross = cross + 1
#turns - Circles goes first always. I hope you know how to play tic tac toe.
c.stamp()
xs.stamp()
c.stamp()
xs.stamp()
c.stamp()
xs.stamp()
c.stamp()
xs.stamp()
c.stamp()
ttts.listen()
turtle.mainloop()
If you see an immediate error, please comment on enter code hereit. However, keep in mind that this is code made by a very young (early teen) student. Thanks a bunch!
ps, sorry if the code looks bad on this. I do not know how to use this app, as it is my first question here. :)
Ok, some things to think about when coding:
OOP (Object orientated programming):
OOP is creating your own object which will make your code cleaner and mean you don't use excessive global variables when using a structured/function approach.
In python, OOP is done by creating a class:
# OOP Example
class MyObject:
def __init__(self): # this is the constructor class and it is called when the object is initialised
# Below are two types of useful variable types that can be accessed in the object. They are properties of the object and act as global variables across all of the functions in the class (with the exception of static functions)
self.example_public_variable = None # public variable (can be accessed from the object variable
self._example_private_variable = None # private variable (can only be accessed from within the object)
# This is a function as part of the object and can be called from an object instance. It takes one parameter that can be passed in. A parameter is a variable that the function can access from the script that has called it.
def example_function(self, param):
pass
obj = MyObject() # I am creating a variable of my new object type which is calling the __init__ function. NOTE: the self parameter is the current instance of the object and is automatically passed in.
var = obj.example_public_variable # accessing the public variable
obj.example_function() # calling an object's function
Object Orientated programming is very helpful in keeping your code neat and can be used in your case like this:
class Game:
def __init__(self):
# do the turtle initialisation, window drawing and listener binds
def _on_right_click(self, event):
# handle right click event
# ... (and so on)
if __name__ == "__main__": # clean way of starting your executable code
Game()
OOP is quite advanced and you can find help here:
https://www.geeksforgeeks.org/introduction-of-object-oriented-programming/
https://realpython.com/python3-object-oriented-programming/
IDE (Integrated Development Environment):
It is significantly easier to code with help, and luckily, there are special text editors dedicated to this. IDEs check for syntax errors, tell you how you could improve the look and style of your code and it tells you how to follow PEP. I would recommend Pycharm for python. Jetbrains also do a student programme where you can get the pro version for free as well as their other tools which could help you if you move on to a more complicated language.
Pycharm: https://www.jetbrains.com/pycharm/
Nested functions:
I see you have used a lot of nested functions which is not best practice because it negates the need for functions in the first place as they are for cleaning up your code and making pieces of code accessible again and again.
Global Variables:
If you don't want to use OOP, then try to stay away from too many global variables. These litter your namespace and make it harder to keep track of the variables your current function is interested in. Try to have all external variables passed in as parameters. This also makes it easier for you to keep track of the variables needed to call a function and reduces your chances of coming across one of those annoying bugs that don't throw an error.
Don't repeat code:
A rule I go by is: 'if I have to rewrite the code, even once, throw it into a function. It is cleaner and easier to understand.'
Use __name__:
This is more for when you start writing libraries or you have multiple files, use the statement if __name__ == "__main__": before writing any code that is run when the file is run. It doesn't litter the namespace when imported and means the user that imports your code doesn't call any functions that they don't want to.
Create meaningful variable names:
A lot of your variables do not describe what they contain (e.g. c, d, tttk). To make it easier for yourself, name variables appropriately.
This will all make your code easier to debug and read.
I know that I have a misunderstanding of how Python attributes work because I'm here writing this problem, but I don't know exactly what I'm misunderstanding. I'm trying to get
self.card = self.hand[self.card_number].split()
self.card_val = deck.ranks.get(self.card[0])
to attain their values based on self.hand, which I pass to __init__ upon instantiation. Throughout the game I am altering .hand, and I want .card & .card_val to change every time I change .hand, instead of having to tell it to do that elsewhere (outside of the attribute definitions). I know there is a way to do this, or at least I think there is, and by that I mean simply by defining their values as inherited based on whatever .hand is at any given time, without calling an internal or external function.
In the posted code, I have altered it to work as the game instructions require, using...
def get_card_vals(p1, p2):
for player in [p1, p2]:
player.card = player.hand[player.card_number].split()
player.card_val = deck.ranks.get(player.card[0])
print("{a} vs. {b}".format(a = p1.card, b = p2.card))
print("---------------------------")
...but that's what I want to change. I want what that function is doing to be executed more concisely inside of the attribute definitions upon handling of the instance. Basically my question is why can't these two attributes get their values directly from the first attribute that I define via "hand" passed to the init?
Any help would be appreciated, and more importantly, I think more than just solutions, it would help me even more to understand what I am misunderstanding about how attributes, instances, and instantiation and all that works so that I know where my thinking is wrong. Thanks!
import random
from random import shuffle
from collections import deque
class Deck():
def __init__(self):
self.ranks = {"Ace":14, "King":13, "Queen":12, "Jack":11, "10":10, "9":9, "8":8, "7":7, "6":6, "5":5, "4":4, "3":3, "2":2}
self.suites = ["Heart", "Diamond", "Spade", "Club"]
self.cards = []
def create_cards(self):
for suite in self.suites:
for key in self.ranks.keys():
self.cards.append(key + " " + suite)
def shuffle(self):
random.shuffle(deck.cards)
deck = Deck()
deck.create_cards()
deck.shuffle()
class Player():
def __init__(self, hand):
self.name = "name"
self.hand = hand
self.card_number = 1
self.card = self.hand[self.card_number].split()
self.card_val = deck.ranks.get(self.card[0])
def war(bool, p1, p2):
if bool == True:
for player in [p1, p2]:
player.card_number = 4
else:
for player in [p1, p2]:
player.card_number = 0
p2 = Player(deque(deck.cards[::2]))
p1 = Player(deque(deck.cards[1::2]))
p2.name = "The Computer"
def get_card_vals(p1, p2):
for player in [p1, p2]:
player.card = player.hand[player.card_number].split()
player.card_val = deck.ranks.get(player.card[0])
print("{a} vs. {b}".format(a = p1.card, b = p2.card))
print("---------------------------")
def cant_war_lose(winner, loser):
print("{a} doesn't have enough cards to go to war, so {b} wins the Battle!".format(a = loser, b = winner))
def battle_win(winner, loser):
print("{a} has run out of cards, therefore {b} has won via Battle!".format(a = loser, b = winner))
def play_cards(p1, p2):
war(False, p1, p2)
get_card_vals(p1, p2)
if p1.card_val > p2.card_val:
p1.hand.append(p2.hand.popleft())
p1.hand.rotate(-1)
elif p1.card_val == p2.card_val:
if len(p1.hand) < 5 or len(p2.hand) < 5:
if len(p1.hand) > len(p2.hand):
cant_war_lose(p1.name, p2.name)
else:
cant_war_lose(p2.name, p1.name)
return 0
else:
input("War is inititated! Press Enter to continue!")
print("---------------------------")
war(True, p1, p2)
get_card_vals(p1, p2)
if p1.card_val > p2.card_val:
for i in range(0,5):
p1.hand.append(p2.hand.popleft())
p1.hand.rotate(-5)
elif p1.card_val < p2.card_val:
for i in range(0,5):
p2.hand.append(p1.hand.popleft())
p2.hand.rotate(-5)
else:
p1.hand.rotate(-1)
p2.hand.rotate(-1)
elif p1.card_val < p2.card_val:
p2.hand.append(p1.hand.popleft())
p2.hand.rotate(-1)
if len(p1.hand) != 0 and len(p2.hand) != 0:
input("After the last round of Battle, {a} now has {b} cards, and {c} now has {d} cards! Press Enter to continue!".format(a = p1.name, b = len(p1.hand), c = p2.name, d = len(p2.hand)))
print("---------------------------")
else:
if len(p1.hand) > len(p2.hand):
battle_win(p1.name, p2.name)
else:
battle_win(p2.name, p1.name)
return 0
def game_run():
run = 1
p1.name = input("Player 1's name? ")
print("---------------------------")
while run == 1:
if play_cards(p1, p2) == 0:
run = 0
game_run()
You can use the property decorator to create a calculated property
class Player():
def __init__(self, hand):
self.name = "name"
self.hand = hand
self.card_number = 1
#property
def hand(self):
return self._hand
#hand.setter
def hand(self, value):
self._hand = value
self.card = self._hand[self.card_number].split()
self.card_val = deck.ranks.get(self.card[0])
What you misunderstand is variables, not instances. For instance, the attribute card is a scalar variable attached to the instance. Assigning to it with
self.card = <blah>
does not bind it to blah for constant recomputation. This is a value assignment, not a memory mapping. If you want that long-term binding, you must either write the maintenance routine yourself -- which you've already done, in a way, with the consistent recomputation -- or you must assign a mutable reference to self.card, so that card refers to teh same object as the expression you created.
Given that you are consistently rotating and altering the hand, this is not feasible in your design. Instead, simply write an access routine, perhaps get_next_card(hand), which will rotate the hand, extract the card, and return the desired rank and suit.
If you plan to program more card games, you will also find it handy to define a class card and class hand, with appropriate support routines. Maintain the card as a pair of integers; convert to strings only for printing.
Does that get you moving?
For anyone who wanted to compare a before and after of the problem & final solution, below is the working code for my specific issue. All I had to do was convert self.card and self.card_val to a calculated property. By passing in hand, and subsequently handling only hand, self.card & self.card_val are calculated, since every time I handle the instance of the class (by handling hand), these "method attributes" are being called and altered. Thanks for the input, guys!
class Player():
def __init__(self, hand):
self.name = "name"
self.card_number = 1
self.hand = hand
#property
def card(self):
return self.hand[self.card_number].split()
#property
def card_val(self):
return deck.ranks.get(self.card[0])
(For those who saw this question the last time I asked it, I sincerely apologize, I used the term "module" when I meant "function", but thank you for your very helpful advice nontheless! I'll make sure to keep it in mind when I begin to add other files into the equation.)
I'm trying to make a text based adventure game using python, and as a result it requires a lot of variables, and as backtracking is a must, I need to use global variables for the essential ones. I have run into speed bumps when trying to get these to be read by other functions. This is the line of code used to define the universal variables, and their starting value
def reset():
global gold, exp, etnl, maxHP, curHP, maxmana, curmana, attack, defence, helm, armtop, armbot, boots, gloves, weapons
gold = 0
exp = 0
etnl = 100 #exp to next level
maxHP = 50
curHP = 50
maxmana = 10
curmana = 10
attack = 5
defence = 5
helm = "none"
armtop = "none"
armbot = "none"
boots = "none"
gloves = "none"
weapon = "fists"
And for example, when I try to display one of the global variables, it shows up as the variable being undefined, as shown here:
def gamestart():
clear() #this command is fine, simply to make it look neater when it is run again
print("you wake up in a clearing in the forest, you can't remember what happened.")
print("you feel numb, you realize you're lying flat on your back.")
print
print("HP " + str(curHP) + "/" + str(maxHP))
Can someone help me out with this?
Is there an easier way to do this?
All help is appreciated!
(yes, I make sure to run the reset function before the newgame function)
A much simpler version if this, at least according to me is:
def variable():
global foo
foo = 7
def trigger():
variable():
output():
def output():
print(foo)
You could store those things into a class used as storage-container. If you declare them classvariables and any accessors as #classmethods you do not need an instance.
class GameState:
gold = 0
exp = 0
etnl = 100 #exp to next level
maxHP = 50
curHP = 50
maxmana = 10
curmana = 10
helm = "none"
armtop = "none"
armbot = "none"
boots = "none"
gloves = "none"
weapon = "fists"
weapons = {"fists":(5,5),"sword":(15,12),"mace":(30,3),"cushion":(2,20)}
#classmethod
def reset(cls):
cls.gold = 0
cls.exp = 0
cls.etnl = 100 #exp to next level
cls.maxHP = 50
cls.curHP = 50
cls.maxmana = 10
cls.curmana = 10
cls.helm = "none"
cls.armtop = "none"
cls.armbot = "none"
cls.boots = "none"
cls.gloves = "none"
cls.weapon = "fists"
#classmethod
def attack(cls):
return cls.weapons.get(cls.weapon,(0,0))[0]
#classmethod
def defense(cls):
return cls.weapons.get(cls.weapon,(0,0))[1]
for w in State.weapons:
State.weapon = w
print("{} has attack {} and defense {}.".format(w, State.attack(),State.defense()))
Output:
fists has attack 5 and defense 5.
sword has attack 15 and defense 12.
mace has attack 30 and defense 3.
cushion has attack 2 and defense 20.
You might want to seperate some things out - f.e. an extra class for the weapon/damage/defense related stuff ...
More reading:
What is the difference between #staticmethod and #classmethod?
https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables
Instead of global variables have you considered storing all the stats in a class/struct? Create an instance of the class at the start of the game, with its default values being specified in the constructor.
G = StartClass()
def gamestart():
print("you wake up in a clearing in the forest, you can't remember what happened.")
print("you feel numb, you realize you're lying flat on your back.")
print("HP " + str(G.curHP) + "/" + str(G.maxHP))
Alternatively, declaring G globally and passing it into gamestart(G) and/or re-instantiating in the reset() function might be options.
Here is a simple example of what I think you are trying to accomplish. If you are using global variables, then you need to be sure you are not inadvertently creating local variables with the same names in your functions (when you mean to be modifying the global variable).
You should look at using classes which I think would help you with some of the semantic confusion here.
value = 10
def reset():
global value
value = 10
def start():
print(f'initial value: {value}')
global value
value += 1
print(f'updated value: {value}')
reset()
print(f'reset value: {value}')
start()
# OUTPUT
# initial value: 10
# updated value: 11
# reset value: 10
I'm not even sure I'm calling those by their correct names but here's what I'm working with. I'm working on a simple hockey simulator that only uses math at this time to simulate the results of the games. Currently there is no names or anything like that and I've just generated a "list" of names for "team1" when the scorers are chosen. That's where this comes in. I want to create a list of players for each team and figured functions would be best...if its not please let me know an easier way. So here's the function right now:
def c1():
_name = "Jason Delhomme"
_overall = random.choice((6.00, 7.44, 8.91))
And the _overall variable would need to be called in some places whereas the _name variable would be called in another place. Is this possible?
tm1center = ((c1 * .5) + (c2 * .35) + (c3 * .15)) * 3
Instead of "c1" above I would replace that with _overall from the c1 function. I'm not sure how to do that or if its possible.. sorry for repeating myself here lol...
And then I have this (below) for the player list:
tm1players = ["player1", "player2", "player3", "player4", "player5"]
Ideally, I would replace all of those with the _name variable in each function. The player functions would also go into more depth with their speed, hands, shooting, etc. ratings as well. I don't know how sim sports handle this as I'm very new to coding (just started school) and I wrote the original engine in excel, which is why its just numbers and not physics or plays.
If this doesn't explain it well enough please let me know and I'll further explain what I'm trying to do.
In your case, its better to use a class and assign two variable to that class then create instances of it, for example:
class Player:
def __init__(self, name):
self.name = name
self.overall = random.choice((6.00, 7.44, 8.91))
player1 = Player('Jason Delhomme')
player2 = Player('Another Player')
tm1center = (player1.overall * .5) + (player2.overall * .35)
tm1players = [player1.name, player2.name]
EDIT:
to add overall when creating the class you need to change the init method to :
def __init__(self, name, overall):
self.name = name
self.overall = overall
then pass it when creating the class:
player1 = Player('Player Name', 6.23)
You can create a list of players at start and append each instance of player to that list for future use, for example:
player_list = []
player1 = Player('Player Name', 5)
player_list.append(player1)
player2 = Player('Player2 Name', 2.5)
player_list.append(player2)
# dynamically create tm1players and tm1center
tm1players = [x.name for x in player_list]
tm1center = [x.overall for x in player_list]
You have to read about object oriented programming, and then start working with classes, methods, and from that creating objects. This is an example for using different functions (methods) under the umbrella of a Class. Note how the use of self is necessary for accessing variables between the different methods:
ClassHockey():
def __init__(self):
self.description = "in here you would define some 'you always use'
variables"
def c1(self):
self._name = "Jason Delhome"
self._overall = random.choice((6.00, 7.44, 8.91))
def c2(self):
self._new_name = self._name + "Jefferson"
return self._new_name
hockeyName = ClassHockey()
hockeyName.c2()
If you run this you'll get the _new_name "Jason Delhome Jefferson", and you can apply this example to all kinds of operations between your class methods.
While manually creating a class is a great solution for this problem, I believe that generating one via collections.namedtuple could also work in this senario.
from collections import namedtuple
import random
Player = namedtuple("Player", "name overall")
player1 = Player("Jason Delhomme", random.choice((6.00, 7.44, 8.91)))
player1 = Player("Other Name", random.choice((6.00, 7.44, 8.91)))
final_overall = (player1.overall * .5) + (player2.overall * .35)
Using list comprehension, you could built your entire team:
list_of_players = [Player(input("Enter player: "), random.choice((6.00, 7.44, 8.91))) for i in range(5)]
tm1center = ((list_of_players[0].overall * .5) + (list_of_players[1].overall * .35) + (list_of_players[2].overall * .15)) * 3
Python lets you group info and data together using classes. In your case, you mostly have information about each player, like a name and various stats. You could define a class like:
class Player:
def __init__(self, name):
self.name = name
self.overal = random.choice((6.00, 7.44, 8.91))
Now you can create a bunch of objects from the class:
c1 = Player("player1")
c2 = Player("player2")
c3 = Player("player3")
And you could calculate
tm1center = ((c1.overall * .5) + (c2.overall * .35) + (c3.overall * .15)) * 3
Since you already have a list of player names, you can use a list comprehension to get a list of players in one step:
tm1players = ["player1", "player2", "player3", "player4", "player5"]
tm1 = [Player(name) for name in tm1players]
Now you can access each element in that list, and get their name and overall attributes to do with them as you see fit.
If you want to extend the tm1center1 calculation to include all five players now, you can assign a weight to each one:
class Player:
def __init__(self, name, weight):
self.name = name
self.weight = weight
self.overal = random.choice((6.00, 7.44, 8.91))
tm1center = sum([p.overall * p.weight for p in tm1]) * len(tm1)
where tm1 is defined something like:
tm1players = ["player1", "player2", "player3", "player4", "player5"]
tm1weights = [0.5, 0.3, 0.05, 0.1, 0.05]
tm1 = [Player(name, weight) for name, weight in zip(tm1players, tm1weights)]
Python is a pretty flexible language. Go crazy with it!
I want to make a text-based fighting game, but in order to do so I need to use several functions and pass values around such as damage, weapons, and health.
Please allow this code to be able to pass "weapons" "damage" "p1 n p2" throughout my code. As you can see I have tried using parameters for p1 n p2, but I am a little bit a newbie.
import random
def main():
print("Welcome to fight club!\nYou will be fighting next!\nMake sure you have two people ready to play!")
p1=input("\nEnter player 1's name ")
p2=input("Enter player 2's name ")
print("Time to get your weapons for round one!\n")
round1(p1,p2)
def randomweapons(p1,p2):
weapon=["Stick","Baseball bat","Golf club","Cricket bat","Knife",]
p1weapon=random.choice(weapon)
p2weapon=random.choice(weapon)
print(p1 +" has found a "+p1weapon)
print(p2 +" has found a "+p2weapon)
def randomdamage():
damage=["17","13","10","18","15"]
p1damage=random.choice(damage)
p2damage=random.choice(damage)
def round1(p1,p2):
randomweapons(p1,p2)
def round2():
pass
def round3():
pass
def weaponlocation():
pass
main()
There are a few options.
One is to pass the values as parameters and return values from your various functions. You're already doing this with the names of the two players, which are passed as parameters from main to round1 and from there on to randomweapons. You just need to decide what else needs to be passed around.
When the information needs to flow the other direction (from a called function back to the caller), use return. For instance, you might have randomweapons return the weapons it chose to whatever function calls it (with return p1weapon, p2weapon). You could then save the weapons in the calling function by assigning the function's return value to a variable or multiple variables, using Python's tuple-unpacking syntax: w1, w2 = randomweapons(p1, p2). The calling function could do whatever it wants with those variables from then on (including passing them to other functions).
Another, probably better approach is to use object oriented programming. If your functions are methods defined in some class (e.g. MyGame), you can save various pieces of data as attributes on an instance of the class. The methods get the instance passed in automatically as the first parameter, which is conventionally named self. Here's a somewhat crude example of what that could be like:
class MyGame: # define the class
def play(self): # each method gets an instance passed as "self"
self.p1 = input("Enter player 1's name ") # attributes can be assigned on self
self.p2 = input("Enter player 2's name ")
self.round1()
self.round2()
def random_weapons(self):
weapons = ["Stick", "Baseball bat", "Golf club", "Cricket bat", "Knife"]
self.w1 = random.choice(weapons)
self.w2 = random.choice(weapons)
print(self.p1 + " has found a " + self.w1) # and looked up again in other methods
print(self.p2 + " has found a " + self.w2)
def round1(self):
print("Lets pick weapons for Round 1")
self.random_weapons()
def round2(self):
print("Lets pick weapons for Round 2")
self.random_weapons()
def main():
game = MyGame() # create the instance
game.play() # call the play() method on it, to actually start the game