I am new to python and object language. I am learning class in python now. but the code below confused me.
class math:
def __init__(self, a, b):
self.a = a
self.b = b
math.add = self.a+self.b
def sum(self):
math.sum = self.a+self.b
s= math(2,1)
x = math.add
y = math.sum
the results look not right. x is 3 but y is not 3. where is my problem?
thanks
I'm guessing what you wanted to do was this.
class math:
def __init__(self, a, b):
self.a = a
self.b = b
self.add = self.a+self.b
def sum(self):
return self.a+self.b
s= math(2,1)
x = s.add
y = s.sum()
print(x)
print(y)
The errors were as follows
You were not calling your instance of math. As these are instance methods, they must reference an instance x = math.add should be x = s.add.
You created a method sum but did not call it y = s.sum simply creates a reference to the function and does not call it, instead you should use y = s.sum()
Your function sum doesn't return anything, so assigning a value to its return value will yield a value of None. To resolve this return a value from sum i.e. return self.a + self.b.
self.add is also quite strange, as it named like a function, but its actually a value, this will not be expected by others looking at your code. A better name for it might be total or remove it since it provides the same functionality as sum.
Related
I am python beginner.
I have to define a method distanceFromOther() that takes the different dot as a factor and returns the distance between itself and the other point.
Class Point is for treating points (x,y) in a two-dimensional plane as objects.
This is the code that I made.
import math
class Point:
def __init__(self, x=0, y=0):
self._x= x
self._y= y
def dFO(self, a, b):
self.a = a
self.b = b
otResult = math.sqrt(math.pow(self._x-self.a,2)+math.pow(self._y-self.b,2))
return otResult
def __str__(self):
return f"({self._x}, {self._y})"
I made two objects a and b.
a = Point(1,1)
b = Point(2,3)
I have to figure out the distance between a and b using method dFO().
I should input 'b' as factor, but I made the method to put the values of points x,y. I don't know how to input object 'b' that I made as the factor.
a.dFO(2,3)
a.dFO(b)
The former is what I made, and the latter is what I want to make.
If you know how to do it, please help me!
You just need to access the _x and _y attributes:
import math
class Point:
def __init__(self, x=0, y=0):
self._x= x
self._y= y
def distanceFromOther(self, b):
x = b._x
y = b._y
otResult = math.sqrt(math.pow(self._x-x,2) + math.pow(self._y-x,2))
return otResult
def __str__(self):
return f"({self._x}, {self._y})"
Also, you don't need to convert parameters of a method into attributes of that object.
I have a method (dosomething) that defines an attribute (self.b). Dummy code below:
class foo:
def __init__(self):
self.a = 1
def dosomething(self, i):
self.b = 2 * self.a + i
return self.b ** 2
testobj = foo()
Attribute a can change - so dosomething is called to determine b given the current value of a.
I want to write a list comprehension like the one below. Except, I need to call dosomething for b to change. The dummy code below would just repeat the current value of self.b 20 times.
[testobj.b for i in range(20)] # pass i to dosomething then store self.b
The quick way is to just return self.b but, the return statement is preoccupied for another value that's much more complicated. If I could return self.b, then the following statement would work:
[testobj.dosomething(i) for i in range(20)]
Attribute b is just an intermediate value that I want to access. Is there a one liner list comprehension for this situation? I was considering defining a function within the method that returns self.b but, I'm not sure how I would be able to access it properly. So something like foo().dosomething(1).getb() wouldn't work because dosomething(1) evaluates to a number.
class foo:
def __init__(self):
self.a = 1
def dosomething(self, i):
self.b = 2 * self.a + i
def getb():
return self.b
return self.b ** 2
I guess I should also add that I don't want to be returning a data structure of different values. It would effect much of my code elsewhere.
Not a good use case for list comprehensions.
I have a simple class that adds 2 nos. Before adding 2 nos I pass a helper function that appends 2 zeros and passes the result.
When I try to print the add_nos.provide(append_zeros) it always shows None.
def append_zeros(x,y):
x = int(str(x) + '00' )
y = int(str(y) + '00')
print x+y
return x + y
class Add_Nos():
def __init__(self,input_array):
self.input_array = input_array
def provide(self,callback):
for each in self.input_array:
x,y = each
callback(x,y)
add_nos = Add_Nos([(1,2),(3,4)])
print add_nos.provide(append_zeros)
The method add_nos.provide(self, callback) has no return statement, thus it returns nothing, which in python means that it returns None.
To avoid this, either add a return statement to provide() or simply call the method without print.
It's not entirely clear what you are trying to do, but provide does not return anything. In python, the default return type of any function is None, so implicitly printing add_nos.provide(append_zeros) will do the function call, and then return None behind the scenes.
One option you have is to return self.input_array:
class Add_Nos():
def __init__(self,input_array):
self.input_array = input_array
def provide(self,callback):
for each in self.input_array:
x,y = each
callback(x,y)
return self.input_array
Note that you can also do for x, y in self.input_array: :)
Presumably, you actually want to be getting a new list out with the result of the computation. In this case, this is an excellent candidate for a list comprehension:
def provide(self,callback):
return [callback(x, y) for x, y in self.input_array]
This is a one-line equivalent of doing
def provide(self, callback):
ret = []
for x, y in self.input_array:
ret.append(callback(x, y))
return ret
You said:
I want the result to be 300 in the first instance and 700 in the
next instance, kind of generate a iterator object.
So you simply need to turn the .provide method into a generator, and then call it appropriately. Like this:
def append_zeros(x,y):
x = int(str(x) + '00')
y = int(str(y) + '00')
#print x+y
return x + y
class Add_Nos():
def __init__(self,input_array):
self.input_array = input_array
def provide(self,callback):
for each in self.input_array:
x,y = each
yield callback(x,y)
add_nos = Add_Nos([(1,2),(3,4)])
for t in add_nos.provide(append_zeros):
print t
output
300
700
That append_zeros function is a bit strange. Rather than converting the args to strings so you can append the zeros and then converting the results back to ints to do the arithmetic yu should simply multiply each arg by one hundred.
Also, you can make the .provide method a little more streamlined by using "splat" unpacking. And as tyteen4a03 mentioned, in Python 2 your Add_Nos class ought to inherit from object so that you get a new-style class instead of the deprecated old-style class. So here's another version with those changes; it produces the same output as the above code.
def append_zeros(x, y):
return x * 100 + y * 100
class Add_Nos(object):
def __init__(self, input_array):
self.input_array = input_array
def provide(self, callback):
for each in self.input_array:
yield callback(*each)
add_nos = Add_Nos([(1,2),(3,4)])
for t in add_nos.provide(append_zeros):
print t
Sorry if it is confusing; making an example.
def functionA():
x=10
b()
def functionB():
Y=22
return Y
Is there a way to access x from B, without pass it as parameter when I call B?
I would like to avoid to have to do something like
def functionB(var):
From my understanding, I can't call super because B is not part of A, it is just called from it. I would like to call B from A, and access in B a variable in A (or more than one; I am exploring the concept); but without pass it as parameter to B.
Is this even possible in Python?
Yes, you actually can:
import inspect
def A():
X = 42
B()
def B():
print(inspect.stack()[1][0].f_locals['X'])
A()
But you shouldn't.
Here come the downvotes.
This is how you can make sure you only execute it when the caller is "functionA" and you retrieve it's last local value before the call.
This is very sketchy though. Don't do this.
import sys
def functionA():
x=10
x = 5
functionB()
x = 3
def functionB():
frame = sys._getframe()
outer = frame.f_back
if outer.f_code.co_name == "functionA":
print outer.f_locals["x"]
Y=22
return Y
if both are just functions, no. but if you made both functions methods of a containing class, you could make a's variable accessible to fuction b's.
class Wrapper(object):
def __init__():
self.a_val = None
def functionA(self):
self.a_val = 123
self.functionB()
def functionB(self):
# you can access self.a_val here fine.
once you have this, you would call functionA as
Wrapper().functionA()
Well yes, what you want is a global variable:
def functionA():
global x
x=10
functionB()
def functionB():
Y=22
print 'X from B:', x
return Y
functionA()
Of course as any responsible programmer would tell you, be careful with global variables as they can easily turn your code into spaghetti.
The standard way to do that is, naturally, to use a class...
However, for argument sake, there is another way to do it, that will make that variable shared between those two functions and still not be global, using a closure:
def defineFuns():
global functionA, functionB
x = 10
def functionA():
print 'X from A:', x
functionB()
def functionB():
Y=22
print 'X from B:', x
return Y
defineFuns()
functionA()
Or playing with the function's dictionary...
def functionA():
x = 10
print 'X from A:', x
functionB.func_globals['x'] = x
functionB()
def functionB():
Y=22
print 'X from B:', x
return Y
functionA()
This is a perfect case for nested functions.
def a():
x = 10
def b():
y = 22 + x
return y
b()
Function b returns 32 (22+10). The x in function b is the same as the x in a. You can't call b from outside of a, but that makes perfect sense because the value of x would be undefined in that case.
I'm pretty new with Python and programming in general, so excuse the lack of "fu". :)
I'm having trouble understanding this class call:
snippet
class bar:
def __init__(self, a):
self.a = a
def __add__(self, b):
s = self.a + b.a
return s
end snippet
So, from the interpreter, if I issue:
x = bar(10)
y = bar(20)
z = x + y
print(z)
I get '30' back. That's correct.
I see how self.a is created, but I don't understand how b.a is getting created to do the addition.
Any guidance is appreciated.
When you call x + y it is actually translated to:
x.__add__(y)
Therefore, this method is called:
__add__(self, b) # __add__(x, y)
Which results in:
s = x.a + y.a # 30
return 30
In this code, b.a isn't being created, it is being accessed. You're basically passing in y as the argument b, which already has an a attribute associated with it since it is an object of type bar. If you want to step through your code go to http://www.pythontutor.com
x = bar(a) creates an object of the class bar with an a value of 'a'. Each bar object has a property/variable named a.
In x + y, the function add of x is called using y as the parameter.
So b = y, meaning b.a = y.a = 20.