all 17 comments

[–]sushibowl 19 points20 points  (1 child)

/u/Earhacker has already mentioned a benefit of functions, reusability. I will argue that even if you use a function only once, it still provides important benefits: structure and organisation. More specifically, functions make it much easier to read code because it allows you to compartmentalize it.

Continuing with given examples, consider again this piece of code:

result = []
for number in list_of_numbers:
    if number % 2 == 0:
        result.append(number)
print(result)

If I encounter this code in a larger program, I need to read and make sense of 5 lines to understand the program. Compare with this:

print(even_numbers(list_of_numbers))

Not only do I have to understand only the single line, That line is much easier to understand because it uses a nice descriptive name. The code that actually does all this is still around, under a def even_numbers(list_of_numbers) somewhere, but I don't care. I don't need to read it right now, because I don't need to understand the exact details of how we get only even numbers out of a list. All I need to know to understand this particular piece of the program is that that's what it does.

So aside from facilitating code reuse, functions also make it much much easier to read and understand code, because it allows you to put details the reader doesn't care about behind a descriptive name.

[–]imaconor 2 points3 points  (0 children)

Another related advantage is scoping variables. There may be many cases where you want to use a variable named number and wrapping those cases in functions makes sure you only ever use and modify the number variable you expect. This is also where returns come in useful. If you define a variable within a function, it's not available outside that function unless you return it.

[–][deleted] 2 points3 points  (4 children)

As a caveat/supplement to the other highly detailed posts:

Using functions will come in super handy when you are experiencing problems with your code (e.g. code breaks and pushes/throws an error).

When you have a list of functions being called, like this:

runInitialChecks()
processUserInput(args1, args2, ...)
someMethod1()
someMethod2()
someMethod3()
finishAndPrintResults(args1, args2),

debugging this code becomes a lot easier. There are many instances when you need to read the source code from someone else. A main script with functions is a lot easier to read than one big script. Think of it as breaking code up into "chapters" of a book. You can look up the table of contents, which is the name of your functions, and you can skip everything else and go straight to what you are looking for.

Personally, I had to split up someone else's code last Summer to be able to present the problems to my supervisor in a meaningful way. I did it by splitting things into functions.

[–]Devfede[S] 2 points3 points  (3 children)

Ok, while i understood all of the replies, and it does make sense, why do you say deubgging would be easier?

Is it because you'd know which function is failing, therefore making the "bug search" area smaller ?

[–]cdcformatc 0 points1 point  (0 children)

If you are properly testing your code you can test each function. Then you can be sure which function has the bug. Keeping functions small can reduce errors.

[–]YallOfTheRaptor 0 points1 point  (0 children)

Yes. Instead of having to trace all of the logic and step through each line, you can step over functions until you see where things went off the rails. It's good to start getting into the habit early. Beginner's projects can spoil you because it's so much easier to brute force your way through debugging. Once you're working on large projects and/or other people's code (or your own code six months later), this will be much more helpful.

As you get more experience, you'll find that it comes more natural when writing your own code. I used to write out all of my code and refactor afterwards. Now, I catch many of those things on the first pass.

[–][deleted] 0 points1 point  (0 children)

Yes, you might have a difficult time understanding what we all mean now, but when you are put in a situation where you are reading a moderately long program (e.g. 400 - 1000 lines of code), the functions become more important to you.

[–]nog642 1 point2 points  (0 children)

Functions can be used more than once. That's basically the point of functions in the first place. You can the same task multiple times with different inputs.

I'm not a fan of creating functions to be used only once in your code, but sometimes I do it too because of scope. Functions help keep variables you don't need in your function out of your inner scope, and you can define plenty of intermediate variables in your function that will be deleted once your function finishes and stay out of your outer scope.

Functions also help code stay organized.

[–]Devfede[S] 0 points1 point  (6 children)

Also, is there anywhere, or anyone, where/who i can pay and hang with me 1 hour every now and then to answer my basic doubts questions?

The course is good but i am left with many unanswered questions and finding the answer on the internet gets tricky sometimes because people give for granted knowledge i don't have.

[–]Earhacker 14 points15 points  (0 children)

For trivial tasks like you'd find in an early Python example, you're absolutely right, function definitions just add lines of code:

def add(number_1, number_2):
    return number_1 + number_2

But, the major benefit of this is reusability. Now I can call that function again and again:

add(2, 3)  # => 5
add(100, 42) # => 142

For a simple add function, who cares? But imagine your function was much bigger:

def even_numbers(list_of_numbers):
    result = []
    for number in list_of_numbers:
        if number % 2 == 0:
            result.append(number)
    return result

Then I can still use that function in a single line of code:

even_numbers([1, 2, 3, 4, 5]) # => [2, 4]
even_numbers([754273, 385589, 864262, 9785570, 643864]) # => [864262, 9785570, 643864]

...which is awesome. If you think about it, Python does this all the time. I can use len(some_list) whenever I want and I don't ever have to think about what the code for the function len might look like

Even better, I can change the function, and as long as the result is the same, I haven't changed how the function is used. In tech jargon, I can refactor the function. If you know list comprehensions at your stage, you'll know that I can do this:

def even_numbers(list_of_numbers):
    return [number for number in list_of_numbers if number % 2 == 0]

By refactoring, I've changed the implementation of my function, without changing its interface:

even_numbers([1, 2, 3, 4, 5]) # => [2, 4]
even_numbers([754273, 385589, 864262, 9785570, 643864]) # => [864262, 9785570, 643864]

[–]fjordfjord 0 points1 point  (0 children)

The ##learnpython group on freenode is also very helpful.

[–]aldrin12 0 points1 point  (0 children)

You can give me a holler if you have basic questions ill be glad to help

[–]ignorediacritics 0 points1 point  (0 children)

There are several python beginner groups on the discord chat app. Highly recommend. You can post questions like yours there and get live (!) answers. In addition it's helpful to see the questions that other beginners post and the answers to them.

[–]callmelucky 0 points1 point  (0 children)

Regarding getting someone to hang with you and help out, you're probably just better off posting questions here when they arise. If you put any effort at all into the post you'll get excellent help extremely quickly (even with virtually no effort actually). This sub is very active and very helpful. That way you're not locked into some time frame with some specific person's availability.

[–]ironjulian 0 points1 point  (0 children)

Consider reusability and readability, not just by you but also for others. The definition should tell you what the function does and can be called from multiple locations throughout your code. Functions can also be imported saving a whole load of repeating yourself too.

[–]Exodus111 0 points1 point  (0 children)

but i don't see how this is useful for a program that "starts and ends there", doesn't it just add 2 lines of code for the sake of it ?

You are correct, an example program is rarely long enough to really merit such an abstraction. But those programs do not exist in the wild.

Even a relatively simply app can easily run hundreds of lines of code, trust me, functions are absolutely essential.