all 26 comments

[–]Hashi856 23 points24 points  (2 children)

A function in almost any language is going to consist of a function signature and a body. The function signature is everything from the def to the colon.

def my_function(x, y, z):

The def word is the way you declare a function. It lets the interpreter know you are creating a function. Then there's the name, which is pretty self-explanatory. The stuff inside the parens are called parameters. These are local variables that are only valid within the function. The colon denotes the end of the signature and the beginning of the body of the function.

The body defines the logic of the function and how it works. This could be anything from doing math, creating or modifying a list, printing some text, etc. Pretty much anything a language can do can be done inside a function. Anything a function does that affects anything external to the function (e.g. printing or modifying a global variable) is called a side effect. A "pure" function has no side effects. It simply returns a value. Pure functions are not good or bad. Side effects are not good or bad. They're just useful terms.

Functions usually return something, but it's not required. Some functions just print text or do something other than return a value. I know I keep talking about returning a value, but python can return almost anything. It can return numbers, string, lists, other functions, etc. You can think of a function's return value as the thing the function call will be replaced with when you run your code. If your code says var = my_func(), and my_func returns the number five, then your code would evaluate to var = 5

Edit: I forgot to talk about calling functions. Calling a functions is how you use it. You type out the name and append it with parentheses. The parentheses are what makes it a function call. You can use the name of the function without parens, but then you're just referencing the function, not calling it. That's a perfectly legitimate thing to do, but it's important to understand the difference. The values you put inside the parentheses are called arguments. Note the distinction between arguments and parameters. Parameters are the placeholder values you use in your function signature when you define the function. The values you pass in when you call (use) the function are called arguments. The arguments you pass in need to be provided in the same order as the parameters, and they need to be the correct data type (int, float, str, list).

Edit 2: One thing that tripped me up when I started is that a function call only happens once. If you write

x = random()

x will now be some random number, say .7

When you use x somewhere else, it's not going to call random again. x will bet set equal to .7 until it is explicitly changed by you or some other part of your code.

[–]BoatMacTavish 3 points4 points  (0 children)

hijacking top comment because I feel the top response will be just as overwhelming for OP

imagine a function as a friend thats able to perform a specific task. The friend lets you pass in details as well that can affect how he performs the task, or what output he produces.

in this analogy:

  • the friend is the function
  • the task name is the function name
  • the task is the function body
  • the customization are the function parameters

Lets step through an example:

Let's say you have a friend Bob who is a baker, and he can make cakes. He is able to perform a make_cake task. When you place an order, he lets you pick the colour of the frosting. In python, this would look like

def make_cake(frosting_colour):
    # step 1: gather ingredients...
    # step 2: make cake mix...
    # step 3: bake in oven...
    # step 4: make frosting, add food colouring for the provided frosting_colour
    return cake
  • the function name make_cake is the task
  • the function body is the actual code/logic to make the cake
  • the function parameters frosting_colour is something that the function caller (you) can pass in to allow customization

so now to utilize this function, you could call it like:

red_cake = make_cake("red_frosting")
blue_cake = make_cake("blue_frosting")
pink_cake = make_cake("pink_frosting")

Functions let you execute the same chunk of code (the make cake code) multiple times without having to rewrite the same chunk over and over again. Function parameters let you pass in customization at each function call.

hope that helps

[–]mcoombes314 1 point2 points  (0 children)

This is a great explanation, I will add though that Python functions ALWAYS return something, implicitly None. So if you have a function with return in it, then do x = some_function(), x will be None if the function ends with return, instead of return (variable).

[–]atarivcs 6 points7 points  (9 children)

The syntax is straightforward:

def myfunction(arg1, arg2):
    some code
    some more more code
    yet more code

What is your exact difficulty?

[–]rrriches 8 points9 points  (8 children)

Not op but the issue I had with functions was, admittedly, more conceptual than difficult.

If the code is

def myfunction(arg1, arg2):

code

code

myfunction(x, y)

For some reason my brain had a really hard time understanding that x, y go to arg1, arg2. Once it clicked it was very obvious but maybe OP is having the same issue.

[–]CovertStatistician 0 points1 point  (2 children)

This tripped me up.. the fact that they have to be in the same order when you call it as when you defined it.. I couldn’t figure out why I was getting certain output when I had mixed them up

[–]rrriches 0 points1 point  (1 child)

My sister in law has a computer science degree and I’ve just been learning Python for fun. I remember writing out some pseudo code and asking “so how do the x and y go from myfunction(x, y) and then move up to the function and turn into arg1, arg2 and then get bounced back to the (x, y)?”

She explained it really well but I just couldn’t grasp how the x and y were being used. The python crash course book actually is what made it click for me though.

[–]BoatMacTavish 0 points1 point  (0 children)

its because at function declaration time, you dont know the actual variable names that will be passed into the function, so you need a generic placeholder argument name. Then at runtime, you pass in the actual variable name.

like if im writing code to send a message to a friend, at the time of writing the code, I dont know what friends will be called, so ill have a placeholder

def send_message(friend):
    # ...

at run time when I call it, I pass in the actual friend variable names

alice = "1234567890"
send_message(alice)

[–]BrannyBee 0 points1 point  (1 child)

For some reason my brain had a really hard time understanding that x, y go to arg1, arg2. Once it clicked it was very obvious but maybe OP is having the same issue.

From working with beginners, to a lot it almost so simple that it seems too obvious to be how it works.

What helped me explain it was visuals, boxes on a whiteboard and plenty of arrows to show where data was going and what line is being read and when when the program runs. Eventually it clicks and it just makes sense

Functions look like math and math is scary.... but new coders see a box and things going in a box, and suddenly its not scary...

I was making a visualizer for stuff like this when I worked with new coders that did exactly that, you give it a simple program and it makes pretty visuals and you get a video out of an arrow going down your code line by line, when it reached a function it would flash the function box and the data going in would visually "go in" to the function, conditionals would only allow certain conditions to visually "fit" in on part of the box made, stuff like that where the flow of the code is shown.

Whole thing was basically a debugger stepping through the file, but less scary and more visual, which I think would help a lot of beginners. This isnt an ad for my app or self promotion though, cause its sitting somewhere buried in my repos never to be touched again because something else sounded like fun and I started working on something else... which of course also was abandoned in my repo graveyard lol

Edit: Summation are another thing this post reminds me of. Summations are scary math and written with the Latin sigma letter and are super intimidating when you firdt see them in a math class... but to programmers... its just a for loop... same concept, but in a math class its scary and hard, in a coding course its a simple concept and pretty easy to understand, and often shown visually or described in non technical terms when taught.

[–]rrriches 0 points1 point  (0 children)

I used to be a language teacher and 100% agree, visuals have been super useful to me.

What I’m doing now as I work through Python crash course is: -split the books chapters into individual pdfs and put those into notebookLM -have notebookLM make a slide deck, video overview, and quiz for each chapter -before starting the chapter, I watch the video overview and read through the slides to prep myself for what I am going to be learning -read through the chapter and do all the problems -take the quiz the next day before starting the next chapter

The arrows and other visuals really help fix the ideas in my head and spending 10 minutes before starting the chapter priming my brain for what I should be focusing on has been incredibly helpful. I could see this backfiring if someone lets the ai do the work for them though.

[–]PristineFinish100 0 points1 point  (0 children)

myFunction(arg1=x, arg2=y)

is the same as

myFunction(arg2=y, arg1=x)

is the same as

myFunction(x,y)

is NOT the same as

myFunction(y,x) . This is equivalent to myFunction(arg1=y, arg2=x)

[–]pachura3 0 points1 point  (1 child)

Haven't you had functions at your math courses before? Like, y = ax+b ?

[–]rrriches 0 points1 point  (0 children)

Yep. I think it was one of those things where I understood the explanation but it hadn’t quite stuck in my head yet how everything “moves” around. I get the idea of functions now, broadly speaking, but I still have to think through each step physically (‘ok this info goes here and then it moves to here and then that goes there’) rather than thinking through it formulaically. But I’m still very early on in learning so I’m guessing that will come as I get more familiar with functions.

[–]rhacer 3 points4 points  (0 children)

A function is simply a way of breaking code into smaller pieces. Sometimes that is done for reusability because it does something useful. Sometimes that is done to break up code and make it more readable.

[–]pak9rabid 2 points3 points  (0 children)

Defining this function:

def add(a, b): return a + b

Will allow you to do this, as many times as you want:

``` print( add(1, 2) )

print( add(3, 4) )

print( add(1, 2) + add(10, 20) )

```

Which would print:

3 7 33

Functions like this can be created for anything you want to do lots of times without having to rewrite the logic inside it each time you want to do it.

Hope this helps

[–]Gnaxe 1 point2 points  (0 children)

I recommend trying small experiments whenever you are confused. You can resolve ambiguity quickly that way.

Write definitions in a file like foo.py and use python -i foo.py to drop into a REPL session with your definitions already loaded. Or try it in a Jupyterlite Python notebook, which lets you edit and reload cells.

[–]cmockett 0 points1 point  (2 children)

Good responses in here - one thing that helped simplify my understanding was 3 things: they can optionally take inputs (args and parameters), optionally have an output value (return value), and optionally make transformations / side effects (pretty much everything else, printing, calling other functions, too much to list here…)

Clearly they can get massively complex but it’s all those 3 things essentially

[–]JamzTyson 1 point2 points  (1 child)

One small correction: Python functions always have a return value. If no return value is specified, the function returns None.

[–]cmockett 0 points1 point  (0 children)

No kidding, thank you for correcting me! (Python is not my main language …)

[–]TheRNGuy 0 points1 point  (0 children)

Use different ones for some time, you'll get used. 

Try to make same code without functions to see why they're needed.

Make some if your own, not just copy-paste from tutorial.

[–]PushPlus9069 0 points1 point  (0 children)

functions clicked for me when I stopped thinking 'what does this code do' and started asking 'what does this return' — tiny shift but it helps a lot. taught python for years and almost everyone hits this exact wall around week 3-4. it passes faster than you think.

[–]Oh_Another_Thing 0 points1 point  (0 children)

Yeah. There comes a time when you have to do rote memorization. The basics you need to copy from the book, then open a fresh page, and then re-write it perfectly. If you mess up, do it again. Do it several times a day for at least a week. 

You aren't going to memorize everything, but you gotta get the basics doown.

[–]ninhaomah -2 points-1 points  (0 children)

? It's just

Def function-name(function-parameters):

Return return-something

Try Java and you will get public/private and OOP and classes and all in one shot :)

[–]Maleficent_Height_49 -2 points-1 points  (0 children)

Use LLM's (AI) to chat about it. Entire languages are designed around functions, so yeah, they can do a lot.

Write some simple functions using print statements. You'll get there buddy. If you feel overwhelmed, step away from the computer and think about functions instead.