>> So now, we've started learning a lot more of
Syntax and things we can do inside our code.
Now, I want to show you one of the ways you can write your code
more efficiently and that's done by using functions.
There's a lot of times,
because let's be honest, as coders,
most of us are pretty lazy,
and I know I'm extremely lazy when I write
code and "Copy and Paste" is our best friend.
So you will often find
yourself copying and pasting code from one place to another.
So in this case, I've got a fairly simple program,
and maybe I've been trying to figure
out why my program is taking so long to run.
So I've written some print statements inside my code.
They just tell me what time it is when the code is running,
so I can see what time it is at different stages in my code.
So I've just copied and pasted
a few lines of code that just print out the current date and time,
so I can see that my print statement didn't take so long,
the four-loop, how long that took to execute, and so on.
So just a little trick I was using to try and debug my code,
figure out what was taking a lot of time.
So at first glance,
it doesn't take me long to do this.
I just copy and paste the code.
But as soon as you find yourself copying and pasting
the exact same lines of code to more places in your program,
pause and ask yourself,
"If I'm copying and pasting that code, maybe,
just maybe, I should move that into a function.
Because if you're running a same code over and over again,
you can put it into a function.
Then every time you need that code to run,
you can simply call the function instead.
So what I've done here is you'll notice,
I've created a function called print_time.
So I've defined the definition of
the function with that D-E-F statements.
So define a function called print_time.
The parentheses on either side after a name, and then a colon.
That's for syntax for declaring a function.
Then you write the code that you want
executed every time you call the print_time function.
Be careful with the indentation.
Again, it needs to be indented by four spaces.
Just like when we were working with if statements and loops,
the indenting determines what code belongs to that function.
Then back in my program when I want to execute those statements,
I just call the print_time function.
This executes exactly the same way
in terms of how the logic is executed.
So what's the advantage
if the resulting code execution is the same?
What do I get out of moving this into a function?
The real advantage here, well, there's two.
One, it makes the code more readable.
If you actually take a look at the code,
you'll see things like, "I'm calling print_time."
It makes it very clear what's happening on this line of code.
Here I'm calling print_time, here I'm calling print_time.
So if you use good function names,
it almost makes the code more readable.
But the really big advantages, at some point you go,
"Hey, you know what, maybe there's
a better way to write that code."
So up here, you'll notice I imported datetime,
because I wanted to print out the current date and time.
Think way back to the module we did on dates and times.
You'll notice when I call datetime,
I have to call datetime.datetime.now.
Because I'm saying in the datetime library,
call the datetime object,
call the Now function of that datetime object. It's pretty clunky.
Back when we looked at the datetime function,
there was another way of calling this,
and we'll discuss this more in
the upcoming module on Libraries and Modules.
You can say, import from datetime import datetime.
We'll explain what that means later.
But that's just allows me to say, print datetime now.
So I go, "I've learned more about Python.
I found a cleaner way of calling that Now function.
So now, I only need to update it in one place,
right inside the function.
Because otherwise, what tends to
happen is when you copy and paste code,
and then you find a mistake,
we tend to forget to update it everywhere and we might update
it two out of three places or one out of two places.
By moving copied code into a function,
if I need to change something,
I only need to change it in one place.
That's a huge benefit of moving your code into a function.
Now, sometimes, we copy and paste
our code but we changed it a little bit when we move around.
In this case, I might have
different messages I want displayed each time.
So if the code is the same,
I want to display a message in
the timestamp after certain chunks of code,
but I want the message to be specific,
depending on what command I was running.
So can I still use the function?
Sure you can, because when you use functions,
you can pass in parameters.
So what I can do is when you call the print_time function,
just pass in a task_name.
I just made up the name for that parameter.
You can make up your own parameter names.
Just make them meaningful,
so it's easier for somebody to try and guess what values pass in.
Add some comments to it,
make sure you put some comments to explain what the function does.
It's easier for you to remember
later and for other programmers to understand your code.
Now, if you do have a parameter with a function,
then when you call it,
you have to pass in a value for that parameter.
So you can see here when I call print_time,
I pass in first name assigned.
So now when this function runs,
wherever you see task_name,
it will have the string "first name assigned."
So that way, I get the message I want when I want it.
I can control it each time I call the function.
So parameters allow you
a lot more flexibility when you're creating your functions.
Here's another example where the code looks slightly different,
but I'm actually doing the same logic
over and over again in my code.
So again, maybe a copy and paste
scenario which I want to clean up, and do more efficiently.
So I've decided I want to figure out someone's initials.
Maybe I'm working for a company where we're
generating user IDs for somebody who visits a website,
or a default e-mail address,
and we use people's initials to generate
that user ID or default e-mail address.
So what I do is I use the first name.
I take the first name that they pass in.
So I asked them to enter their first name.
Then I extract, and this is one of those tricks,
if you remember the module we did on list,
we learned how to extract values from a list,
I start at position zero,
and I asked for one character.
So that's asking for the first character of their name,
and I'm storing that in a variable called first_name_initial.
Then I ask for user to enter their last name,
and then I take the last name,
I start at position zero, which would be the first letter,
and I count one letter,
so that'll extract the first letter from their last name.
Put that into a variable called last_name_initial.
Then I use that, in this case,
I'm printing to get the screen, or I could be,
I said using that to generate
an e-mail address or a user ID for somebody.
So the code, at first glance, doesn't look the same.
But if you think about the logic that's happening,
both the highlighted lines of code,
are achieving the same task.
They're taking a string,
and asking for the first letter from that string.
I can move this to a function as well,
but it's going to be a slightly different syntax.
Because now, I want to have a function which accepts a value,
so I define a function called get_initial.
It accepts a parameter name,
so you pass in a name,
I will give you back the first letter of that name.
So I say take the name,
extract the first letter from it,
put it in a variable called initial.
But now what I'm doing is I'm actually
adding a return statement to my function.
So this function always passes back a value.
Now, that's going to change the way we call it.
Because since the function will pass a value back,
that means when you call a function,
you have to have a place to put the value that gets passed back.
So you'll notice in the code that when
I call the program get_initial and I pass it first name,
I say take the value passed back
and store it in the variable first_name_initial.
When I call it here,
I say call the get_initial function,
pass it last name,
when the value is passed back,
it'll be stored in the variable last_name_initial.
So same programming logic,
but by using functions, again,
I'm making the code a little more efficient.
I still have that wonderful advantage that if I
discover later I want to change something in the code like,
"Hey, wait a second, the initials came back lowercase.
What if I want those initials to always be forced into uppercase?"
All I have to do is change one line of code in the function,
and its fixed everywhere.
That's one of the biggest advantages of using functions.
Readability and the fact if you need to make a fix,
you'll only need to change it in one place.
Now, the other thing that's neat about functions,
is you will sometimes see coders getting very clever with them.
Because they return values,
you can call them in different ways.
You can either call them and take the value that you
receive and return it into a variable,
or you can actually call it directly inside statements.
So here, what I've done,
is I've actually moved the function calls.
So I have a first name entered by a user,
and last name entered by a user,
and then I just say print "Your initials
are," and right inside the print function,
I call the get_initial function which returns the first letter,
and then concatenates to that,
call the get_initial function,
passes me the next letter, and prints it out.
Some people look at this and go,"That's cool. I love it.
It's great. Very efficient.
One line of code. I didn't have to declare extra variables."
Other people look at this and go,"Now, I'm confused."
So really, it's a trade-off here.
It's up to you if you prefer to
nest your functions inside other calls,
or whether you prefer calling
them explicitly and putting the values into a variable.
You're going to see both examples when you're
looking at blog posts and tutorials.
So it's good to be aware of the two options.
But when you're writing your code, it's up to you.
So functions really do make
your code easier to maintain and more readable,
if you use good function names and good parameter names.
Always add comments to explain the purpose of your function.
So with each function declaration,
always include some comments saying,
"This is a function. This is what it does."
If it has parameters,
add comments to explain what each parameter is for.
It'll make life easier when you have
to come back to your code later.
That define function has to be declared
in your code before you have the code that calls a function.
All right. Now, let's go try it out in a Visual Studio Code.