im coding a game, and i have Square class
class Square:
def __init__(self, name, pos) -> None:
self.name = name
self.pos = pos #pos is (x,y)
self.unit = None
when i create a Square i give it the name Square+"x"+"y" using :
Square(("square"+str(x)+str(y)), (x,y))
But i dont know how to call this object. Let's say i want to change the unit that is on this square, i'd like to do
square+str(x)+str(y).unit = warrior
or something of the sort. How do use str(x) and str(y) to call my object?
I tried doing
square+str(x)+str(y).unit = warrior
but of cours square is not a string and cannot be added to strings.
"square"+str(x)+str(y).unit = warrior
obviously does not work either.
So i tried changing the name, to ("square", str(x)+str(y)) But then if i try to give my unit a square :
unit.square = ("square",str(x)+str(y))
this will not call the Square object, it is giving an attribute to my unit that is a pair of strings.
To sumarize, id like to be able to do :
for x in range(n):
for y in range(n):
square + str(x) + str(y) = Square(name, (x,y))
square + str(x) + str(y).unit = warrior
I suggest a bit of reading from w3schools to understand python objects.
In short you initialize an object by calling its class name and storing it into a variable.
I also suggest to use a bit more variable to make your code more readable.
//store the name
squareName = "square" + str(x) + str(y)
//store the "Square" object
mySquare = Square(squareName, (x,y))
//Change the property "unit"
mySquare.unit = newUnit
Related
I'm currently trying to build a simple animation for a queuing model and I want to set the coords of any graphical object in dependence of its predecessor object. To do so, I call a method of the object (o1), which I want to animate. This method creates an object (o2) of another class, which represents the image. While creating o2, I want to pass an attribute of o1. This looks, for instance, like this:
class Queue(salabim.Queue):
def setup(self, predecessor):
self.predecessor = predecessor
def animate(self, graphic):
self.graphic = graphic
buffer_preprocessing = Queue(
name = 'buffer_preprocessing',
predecessor = source)
if env.animation is True:
buffer_preprocessing.animate(graphic = Symbol_Queue(
width = 80,
height = ref_height,
slots = 5,
x = predecessor.graphic.x + predecessor.graphic.width + distance,
y = y0,
fillcolor = 'white'))
When compiling the program, I receive an error "[pylint] Undefined variable 'predecessor' [undefined-variable]".
Can somebody tell me, which keyword I need to use to refer to the attributes of the outside object "buffer_preprocessing"?
Thanks in advance :-)
Edit: It is possible to simplify my problem to the following code:
class OuterClass():
def __init__(self, A):
self.A = A
def do_stuff(self, stuff):
self.stuff = stuff
class InnerClass():
def __init_(self, B):
self.B = B
outerclass = OuterClass(A=1)
outerclass.do_stuff(stuff = InnerClass(B = 1 + A))
# Error: Undefined variable 'A'
# How can I refer to the calling object 'outerclass' without giving the explicit name?
I am guessing both the Queue and the Symbol_Queue since neither the name nor the predecessor parameters are part of python's queue.Queue.
If this is so, I believe the change needs to be implemented inside the code of the Queue class... maybe something along the lines:
First, expose the predecessor inside the Queue
class Queue(...):
def __init__(self, name, predecessor, ...):
...
# expose the predecessor
self.predecessor = predecessor
or alternatively, if you need to do some processing/checking you can expose a property
class Queue(...):
def __init__(self, name, predecessor, ...):
...
# expose the predecessor
self._predecessor = predecessor
#property
def predecessor(self):
# .. some checks or processing
return self._predecessor
Second, your code above will now become something like:
buffer_preprocessing = Queue(
name = 'buffer_preprocessing',
predecessor = source)
if env.animation is True:
buffer_preprocessing.animate(graphic = Symbol_Queue(
width = 80,
height = ref_height,
slots = 5,
x = buffer_preprocessing.predecessor.graphic.x + buffer_preprocessing.predecessor.graphic.width + distance,
y = y0,
fillcolor = 'white'))
There probably might be better ways to pass this by changing a little the implementation of the .animate, but it's hard to say without looking at the implementation of the Queue and Symbol_Queue classes.
EDIT 1: Using the simpler abstraction added to the question
I believe the key here would be to include some kind of logic inside the OuterClass.do_stuff, since in there you can access the things within self. Of course, it depends how much you can "hardcode" into this function on the OuterClass.
Here is a suggestion (I define the Inner first for better readability):
class InnerClass():
def __init_(self, B):
self.B = B
class OuterClass():
def __init__(self, A):
self.A = A
def do_stuff(self, stuff_to_create_inner):
new_inner = InnerClass(B = 1 + self.A, **stuff_to_create_inner)
# You can use "**" (dict unpacking), or pass them "by hand"
# ...
self.stuff = stuff
outerclass = OuterClass(A=1)
outerclass.do_stuff() # in your example you may want to pass the width, height, ...
Finally, should you need to use/keep track of that inner object you created (I'm guessing you don't since you simply create on inside the method call), you could always have OuterClass.do_stuff return the created object.
Thanks for the simplification. Now it’s much clearer. In that case, you can simply pass the class as well as the argument to do_stuff rather than creating an object when calling the do_stuff function. For example,
class OuterClass():
def __init__(self, A):
self.A = A
def do_stuff(self, my_class, other_input):
self.obj = my_class(other_input+self.A)
class InnerClass():
def __init_(self, B):
self.B = B
outerclass = OuterClass(A=1)
outerclass.do_stuff(my_class = InnerClass, other_input=1)
I am a bit confused what exactly is wrong in here. I've seen plenty of questions about below error but still can't find the right answer for my code. I am just starting with classes in Python and I wanted to decode a bit ( I got 5 different functions for different type of API data).
class Weather:
def __init__(self, R):
self.R = R = requests.get(
"http://api.openweathermap.org/data/2.5/weather?q=" + CITY + "," + COUNTRY + "&appid=xxx")
def temp(self):
"""Temp function with conversion to C degree"""
JSON_OBJECT = self.R.json()
TEMP_K = (JSON_OBJECT["main"]["temp"])
TEMP_C = TEMP_K - 273.15
return (TEMP_C)
Idea is to put those 2 into "variables" to avoid repetition:
requests.get(
"http://api.openweathermap.org/data/2.5/weather?q=" + CITY + "," + COUNTRY + "&appid=xxx")
JSON_OBJECT = self.R.json()
My error looks like that:
TypeError: temp() missing 1 required positional argument: 'self'
This is the line where error appears:
print("Current tempreture in {} is: {} C.".format(CITY, Weather.temp()))
You have defined temp as a method of the Weather class.
That means you should call it from an instance of the Weather class.
In this case, I would suggest not using a class at all.
A general piece of Python wisdom states that if you have a class with two methods, one of which is __init__, then you basically have a function. So use a function:
import requests
def get_weather_json(city, country):
R = requests.get("http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + country + "&appid=xxx")
return R.json()
So I am in an intro to python class and we are just getting into class basses coding in python. I am looking to get a list of areas out of the plants in my list so that I can then take those areas, get a sum, and then subtract them from the area in the bed. I am having the trouble figuring out how to make a list of the area of the plants in my bed, which is only blueberries for now. Any ideas are greatly appreciated.
class crop:
name = "Crop"
sizeW = 0
sizeL = 0
areaOfCrop=sizeL * sizeW
def print(self):
print("This is a ",self.name," and is ",self.sizeW,"X",self.sizeL, "and has an area of ",self.areaOfCrop)
def willItFit(self, W, L):
return self.sizeW <= W and self.sizeL <= L
def sameAs(self, crop):
return self.name == crop.name
class plant(crop):
name = "Plant"
sizeW = 1
sizeL = 1
areaOfCrop = sizeL * sizeW
class parsley(plant):
name = "Parsley"
class shrub(crop):
name = "Shrub"
sizeW = 2
sizeL = 2
areaOfCrop = sizeL * sizeW
class blueberries(shrub):
name = "Blueberries"
class tree(crop):
name = "tree"
sizeW = 3
sizeL = 3
areaOfCrop = sizeL * sizeW
class dwarfPeach(tree):
name = "Dwarf Peach"
class bed:
sizeL = int(input("What is the length? "))
sizeW = int(input("What is the width? "))
crops = [blueberries()] # The list of crops in this bed
areaOfAllCrops = [crops[areaOfCrop()]] #this is where my problem is
def print(self):
print("The bed is ", self.sizeL," x ", self.sizeW)
for c in self.crops:
c.print()
def maxSizeAvailable(self):
''' area of bed-total area of all crops in be '''
return (self.sizeW, self.sizeL)
def add(self, newCrop):
dimension = self.maxSizeAvailable()
if newCrop.willItFit(dimension[0], dimension[1]):
self.crops.append(newCrop)
def remove(self, existingCrop):
for c in self.crops:
if c.sameAs(existingCrop):
self.crops.remove(c)
def checkFit(self, crop):
dimension = self.maxSizeAvailable()
return crop.willItFit(dimension[0], dimension[1])
b = bed()
b.print()
You can add up the areas of the crop instances in the crops list with sum(x.areaOfCrop for x in crops). This is a generator expression that gets passed to the builtin function sum.
But I think you have a larger conceptual issue that will cause you problems later on even you get your immediate issue squared away. The issue is that you're exclusively using class attributes in your code, rather than instance attributes. While there are some situations where class attributes are useful, the overwhelming majority of the time you want to be dealing with instance attributes instead.
To create instance attributes, you need to make the assignments in a method, and assign to self.attr instead of just attr. Usually the place to initialize your instance attributes is the __init__ method, which Python will call for you after it creates the new instance.
To give an example, your crop class should probably start with:
class crop:
def __init__(self):
self.name = "Crop"
self.sizeW = 0
self.sizeL = 0
self.areaOfCrop = sizeL * size
# ...
Some of those values could be passed as arguments, rather than always getting set to the same constant. That leads me to a design question: Do you need all of your different plants to be instances of separate classes, or could they all be different instances of one class, with different data in their instance attributes attributes? (Don't be too concerned if you don't know the answer yet. It takes some experience with OOP to get good at designing classes.)
def areaOfRectangle (length,width):
area = length*width
sqArea = length**2
return area,sqArea
def areaOfSquare (length,):
areaOfRectangle (length,width)
return sqArea
#def radiusOfCircle (radius):
area = 3.14*(radius**2)
return area
#def volumeOfCylinder (radius,height):
volume = 3.14*(radius**2)*height
return volume
length = int(input("Input length: "))
width = int(input("Input width: "))
print()
print(areaOfRectangle (10,20))
print()
print(areaOfRectangle (24.3,6))
print()
print(areaOfRectangle (34.9,17.4))
print()
print(areaOfRectangle (length,width))
print()
print(areaOfSquare (10.3))
I need to make two functions, the first function to calculate the area of a rectangle given the length and width. The second function needs to calculate the area of a square given the length of one of its sides. The second function should call the previous function to perform the calculation. I know how to call a function within another function however I don't know how to bring a variable from the first function to the second.
I don't know how to bring a variable from the first function to the second
Typically, this is done through the use of parameters. Let's say you have a value x:
x = 0
You can pass the value to a function by inserting it into the call itself:
f(x)
Lastly, the function needs to be able to handle the parameter you give it:
def f(y): pass
A working example of what you describe:
def f2(y):
return y + 1
def f1():
x = 2
print(f2(x))
f1()
3 is printed.
I'm trying to get toBase10(101) to spit out 5. I also need it to work for numbers besides 101, I know that there is a binary converter built into python but I can't figure it out.
Right now I have
def toBase10(x):
int( 'x' , 2 ) == x
return x
I get the error can't convert non-string with explicit base. Why can't I use x in here?
def toBase10(x):
return int(x, 2)
I converted the integer into a string and then into binary with which I could easily convert into an integer:
def binaryconvert(x):
x = str(x)
binarynumber = int(x, base=2)
convertnumber = int(binarynumber)
return convertnumber
print(binaryconvert(101))
#the answer would be 5
There's also another way if your input is already binary:
def binaryconvert(x):
convertnumber = int(x)
return convertnumber
x = int(input("Input: "),2)
print(binaryconvert(x))
try
def toBase10(item):
return int(str(item),2)
then you can pass either string or int
print toBase10(101)
print toBase10('101')
i think the int cast error is because you are passing in a number not a string, although this looks odd --> "int( x , 2 ) == x" too