-1

I'm currently teaching myself how to code and I have a very broad question about Python (and every other language). How do you know when to put a variable before a period or within the parenthesis of the function?

For example - This expression will retrieve the correlation for the dataset.

df.corr()

However, why is the parenthesis left closed without any information inside of it? Why can't you put the variable within the expression like this -

corr(df)

I understand that the first expression is correct, I'd just like to at a high-level know why. Does anyone have any videos or tools that can explain this fundamental principle of coding?

I've historically used excel a lot in my past positions, which is probably why I instinctively to put everything within parenthesis.

Thank you for the help!

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
Derek24
  • 3
  • 1
  • 3
    See also [What's the difference between a method and a function?](https://stackoverflow.com/questions/155609/whats-the-difference-between-a-method-and-a-function) – kaya3 Feb 03 '20 at 15:40
  • ALL functions must have the parenthesis. `df.corr()` Means that the Object `df` has a member function (methods) called `corr()` It **may** or not have input parameters. `corr(df)` would be a function (not object memeber=> not a method ) that receives `df` as input parameter – Ivan Feb 03 '20 at 15:41
  • 1
    May I kindly suggest you do [the full official Python tutorial](https://docs.python.org/3/tutorial/index.html) ? Also if you don't have any basic CS knowledge, [this excellent (and free) book](https://greenteapress.com/wp/think-python-2e/) – bruno desthuilliers Feb 03 '20 at 15:56
  • NB: I reopened the question since I really don't think the dup suggested by kaya3 was a good match. – bruno desthuilliers Feb 03 '20 at 15:58
  • @Derek24, ...How did you know that `corr` existed at all? Whatever documentation told you it existed should also tell you if it's a method ("member function"), or a standalone function. – Charles Duffy Feb 03 '20 at 16:05

1 Answers1

0

However, why is the parenthesis left closed without any information inside of it?

df.corr()

Because there's nothing more to pass to the function. Or, more exactly (and assuming df is something like a panda dataframe instance or other similar object), because the only required argument (df) is, in this case, automagically passed to the function.

Why can't you put the variable within the expression like this -

corr(df)

You could do something like type(df).corr(df) if you really want, but that's a bit useless.

Ok, let's go a bit deeper: Python is an object oriented language. In OO, objects have "methods" - functions that act on the object on which they are called. In most OOPLs, the syntax for method calls is obj.method() instead of method(obj). Behind the scene, your language's compiler or interpreter (or whatever other mechanism) actually make obj available to the method, so there's no need to pass it explicitely.

The point of having things this way - instead of having a standard function - is that different objects can define the same method each in it's own way, so as a "client" of those objects, you don't have to check the exact type and call the object-specific version yourself, ie:

without objects:

def draw_rect(rect):
    # code to draw a rect here

def draw_line(line):
    # code to draw a line here

def draw_circle(circle):
    # code to draw a circle here


def draw_all(drawables):    
    for obj in drawables:
        if isinstance(obj, Rect):
            draw_rect(obj)
        elif isinstance(obj, Line):
            draw_line(obj)
        elif isinstance(obj, Circle):
            draw_circle(obj)

def main():
    # a list of various "drawable" objects
    objects = [Rect(), Line(), Cicle()]
    draw_all(objects)

with objects:

class Rect():
    def draw(self):
        # code to draw a rect here

class Line():
    def draw(self):
        # code to draw a line here

class Circle():    
    def draw(self):
        # code to draw a circle here


def draw_all(drawables):
    for obj in drawables:
        obj.draw() 


def main():
    # a list of various "drawable" objects
    objects = [Rect(), Line(), Cicle()]
    draw_all(objects) 

and behind the scene, Python will turn obj.draw() into type(obj).draw(obj). This is called "type-based polymorphic dispatch" and is really the most essential concept in OOP.

Now Python is not a "pure" OOPL, in that in doesn't force you into using only objects and methods - you can also write and use plain functions too (our draw_all and main functions above for example), which, of course, will work as you expect.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118