-3

I have this code that adds 10 to either the variable x or y but it also has a method that prevents those values to go above 100 or below 0. The program asks for user input about which value to increment either x or y values:

class X_increment(object):

     x=0
     y=0

     def x_y(self,min=0,max=100):

        if self.x<=min:
            self.x=0
        elif self.x>=max:
            self.x=100

        if self.y<=min:
            self.y=0
        elif self.y>=max:
            self.y=100



x1=X_increment()
x2=X_increment()

while (True):

  z=input("Press x to increase x")

  if z=='x':
    x1.x+=10
    x1.y-=5
    x1.x_y()
    print(x1.x,x1.y)

  elif z=='y':
    x1.y+=10
    x1.x-=5
    x1.x_y()
    print(x1.x,x1.y)

  elif z=='e':
    break

  else:
    print("not valid")

print("the value of x and y is:",x1.x,x1.y)
print("the value of x and y of the x2 instance is",x2.x,x2.y)

I was using it to test how to modify values of an instance and it worked, but i tried the same code but initializing the variables like this:

def __init__(self):

    x=0
    y=0

And it didn't work, i tried it calling the variables in multiple ways but it just didn't work so i figured there is something i was doing wrong or maybe you can't change variables in a "constructor" like i am tryingto do?, i don't know, i am pretty new to programming and python and i really get confused by this.

Hagogs
  • 53
  • 1
  • 9
  • 2
    Did you mean `self.x = 0` and `self.y = 0`? – Christian Dean Aug 31 '17 at 22:38
  • I mean i removed the first variables x=0 and y=0 and just declared them in the constructor. Because i was trying to see the difference between having them as static variables of the class or having them inside the constructor.I wanted to know how to modify them when being static (which i already did) and when you declare them in a constructor (which i failed because i don't understand how to use them like this). – Hagogs Aug 31 '17 at 22:44

2 Answers2

1

When you declare attributes in the class definition, like

class X_increment(object):
    x = 0
    y = 0

x and y are attributes of the class object X_increment. When you access them on an instance like x1 = X_increment(), x1.x, the attribute lookup fails on the instance x1, then goes up to the class object, where it finds it. Incidentally, since x and y are class attributes, x1 and x2 share x and y (i.e., x1.x and x2.x refer to the same value).

When you declare the attributes in __init__, you need to explicitly set them on the instance you're creating:

class X_increment(object):
    def __init__(self):
        self.x = 0
        self.y = 0

The reason you can't simply do x = 0 anymore is that the __init__ function isn't executing in the class body, so as soon as the function is finished the local variables x and y would vanish. Once you've defined __init__ this way, things should work as expected: each instance (x1 and x2) has its own values of x and y. self is a reference to the individual instance you're calling the method on.

You may also be interested in properties, which are a more general and powerful way of writing your x_y method.

Josh Karpel
  • 2,110
  • 2
  • 10
  • 21
  • How would i call these variables in a different method, like in my example i have the method def x_y, i think this is when i had the problem because i didn't know how to use them inside this method. – Hagogs Aug 31 '17 at 23:11
  • @Hagogs you refer to them as `self.x` and `self.y`, which you're already doing correctly in `x_y`. – Josh Karpel Aug 31 '17 at 23:14
  • =O... i will try to just modify how i declared the variables and test it. – Hagogs Aug 31 '17 at 23:20
  • WTF... i swear this wasn't working before... i probably had other errors that i corrected when i did the other version that i posted on the main topic... wow – Hagogs Aug 31 '17 at 23:24
0

The difference between a class variable and an instance variable is that the class variable doesn't need an instance to be accessed. In the following example, I declare and use class variables:

class Test:
    classVariable = 5

#no need to create an instance of the class
print(Test.classVariable) #prints 5
Test.classVariable = 10
print(Test.classVariable) #prints 10

Whereas an instance variable can have a different value on each instance that has been created:

class Test:
    def __init__(self):
        self.instanceVariable = 0;

#creating 2 instances of the same class
instance1 = Test()
instance2 = Test()

#they start with the same value
print("1=%s, 2=%s" % (instance1.instanceVariable, instance2.instanceVariable))
#prints "1=0, 2=0"

#but we can modify the value on each instance separatly
instance1.instanceVariable = 5;
print("1=%s, 2=%s" % (instance1.instanceVariable, instance2.instanceVariable))
#prints "1=5, 2=0"

print(Test.instanceVariable) #this won't work

Variables declared outside functions in a class are class variables. Instance variables can be declared several ways, one of them is using self.xxx in the constructor or other functions

  • How would i call these variables in a different method, like in my example i have the method def x_y, i think this is when i had the problem because i didn't know how to use them inside this method. – Hagogs Aug 31 '17 at 23:11