0

My apologies if this is a stupid question but

if we have

x=3+5j

then x.imag would give its imaginary part x.conjugate() would give its complex conjugate. Why do we need to put a () to call the conjugate function?

I am thinking whether x can be thought to be a struct in C++

imag is a public attribute of x, where conjugate is a member function. Is this way of thinking correct? I apologise if this makes no sense. Admittedly, my knowledge of C++ and Python are both quite limited.

Billy
  • 5,179
  • 2
  • 27
  • 53
Lost1
  • 990
  • 1
  • 14
  • 34
  • 10
    If you don't need a `()` then it's probably not a function, just an attribute (non callable) of the object. You can experiment with the `callable` builtin for this – Moses Koledoye Nov 17 '16 at 17:24
  • @MosesKoledoye i didnt put a (), it gave me built-in method conjugate of complex object at (some address) – Lost1 Nov 17 '16 at 17:25
  • @MooingRawr I am just asking why x.imag does not need a barcket and x.conjugate needs one when x is a complex number. Complex numbers are built in in Python, no? – Lost1 Nov 17 '16 at 17:33
  • Yes, you are absolutely right. One cool thing you could do with python is run `type(x.imag)` and that will tell you that it is a float, and `type(x.conjugate)` which will say that it is a builtin function or method – Rodolfo Nov 17 '16 at 17:34
  • @Rodolfo but the type(x.conjugate()) returns complex! yes. I see. thank you! – Lost1 Nov 17 '16 at 17:43

2 Answers2

2

So, on top of other problems, you sometimes have programming functions which arnt the same thing as maths functions. Generally speaking, an struct that has functions (which is basically what an object is), is where the function always has a starting context.

Historically before objects, you would have to mkae a function that took the A and B, so you would make a function called addthing(A, B), where now, we can make a function on the thign called add, so you can do A.add(B). Ok.. these are functions on the object

But objects can also have properties. Now some programmers will tell you you shouldnt have public things, you should use getters and setters, and then C# does something awesome to make that better: but I like public properties, so I can imagine making a 'class' (which is the definition of an object) being representing a coordinate or a vector, so i can define it to have an X and a Y, so these arn't functions but properties.

Wierd bit 1) But we want to do things sometimes a bit implicitly. like doo vector = vector_a + vector_b that would be awesome right? Well, you can! objects inherit basic Objects, but the default __add__ function on the object doesnt know how to add nother one together, so I can implement that on my object. Theres actually tons of these default functions which are called... effectively the compile rewrites anything like x = y + z into x = y.__add__(z). What else can you override? __str__ is whats called when you convert it to a string (like print(mycoord) gets converted (effectivly) into print(str(mycoord)) which in turn is print(mycoord.__str__()). Theres also a ton of things like comparison, meaning your objects can be sorted by lists and other cool things...

wierd bit 2) ok sometimes you want a property to actually be a function. WHAAAAAAT? We often call these 'getters and setters'. They look like a property or attribute, but they're actually a function... so..

# in a class...
@property
def x(self):
    """I'm the 'x' property."""
    return self._x

# sometime later...
print(myobject.x) # <-- effectivly calls myobject.x()

now this means you can do things on the setter where you might validate the input, control how its set, maybe force it to be a particular type (not quite inline with the zen of python, but sometimes very useful).

Hope that helps!

Jmons
  • 1,766
  • 17
  • 28
1

x is not a struct, it is an object of type complex (although sometimes it helps to think of objects as structs with methods bound to them).

>>> type(x)
<class 'complex'>
>>> x = 3+5j
>>> type(x)
<class 'complex'>

x.imag is not a function, it's an attribute of the object x that is a float object. An attribute does not have to be called with the parentheses () in order to retrieve its value. Its value is 5 in your example. You can test if it's a function by calling callable on it. float objects are not callable.

>>> x.imag
5.0
>>> type(x.imag)
<class 'float'>
>>> callable(x.imag)
False

x.conjugate is a function, since callable(x.conjucate) returns True. You call the function by putting the parentheses () after it with the function parameters inside the parentheses. When called, it returns a new object of type complex, which in turn also has the method conjugate which can be called.

>>> x.conjugate
<built-in method conjugate of complex object at 0x00000000034D2C90>
>>> callable(x.conjugate)
True
>>> x.conjugate()
(3-5j)
>>> type(x.conjugate())
<class 'complex'>
>>> x.conjugate().conjugate()
(3+5j)
Billy
  • 5,179
  • 2
  • 27
  • 53
  • This is perhaps a stupid question: what is the difference between object and struct? from the very little of C++ knowledge I have, struct and classes are the same except one has private attributes by default and the other has public attribute by default. – Lost1 Nov 17 '16 at 17:44
  • 1
    I'm not familiar with C++ either (a cursory search returns this: http://stackoverflow.com/questions/54585/when-should-you-use-a-class-vs-a-struct-in-c). In C, a `struct` looks a lot like a `class` in Python or C++, but without an inherent namespace and without an easy way to bind methods to it. – Billy Nov 17 '16 at 17:49