What if we had some code that we wanted to perform a whole bunch of times?
For example, let’s say I had a log file, and each entry in the log file looked like this:
001|LOGIN_SUCCESS|lawsonje@nsa.gov|20200201|1344
002|LOGIN_SUCCESS|smithda@nsa.gov|20200202|1344
003|LOGIN_FAIL|trevamo@nsa.gov|20200203|0850
004|LOGIN_SUCCESS|trevamo@nsa.gov|20200203|0851
005|LOGIN_FAIL|cartersh@nsa.gov|20200203|0904
Let’s also say that I wanted to determine whether each entry was a successful login or a failed login. I could do that really easy as long as each line was stored as a string variable. For example, the first two lines might be:
|
|
You may recall that we can get a substring of a string by using the [
and ]
characters. For example, I can pull out the first three characters of a string
like this:
|
|
So if we wanted to pull out the string that indicates whether the login is successful or it failed, we just need to know the position of each character in the array:
|
|
(Remember: the first position of a string is [0]
, not [1]
).
We can determine if each entry in the log file is a LOGIN_SUCCESS or LOGIN_FAILED by checking the value of those string slices:
|
|
Of course, if we want to DO something with the knowledge that the line
contained LOGIN_SUCCESS
or LOGIN_FAILED
, we would want to store that
knowledge in a variable, like this:
|
|
This is fine for one or two lines, but what happens if we want to check a file that contains hundreds of lines? Surely there must be something easier than:
|
|
Can you imagine having to exhaustively go through each and every line like this? There are a number of problems with this approach:
-
It is nearly impossible to update. What happens when the log format changes? Because format and syntax changes to log output is common, especially if some developer pushes new updates and decides to switch an application into full logging mode and now we have NEW types of lines in the file. Are you supposed to account for every type and variant of log entry in the file? Yikes!
-
It does not account for variable length log files. In the real world, log files don’t have a set number of lines and that’s it. Some log files might be 100 lines long, others might be 1,000,000 lines long. Are we going to make a single variable for each possible line that could exist in a log file? Talk about exhausting!
Thankfully we don’t have to process a file like this. Instead, we can think about what we want to do to each line and then package up that work into a group of statements called a function.
We’re not going to be parsing a log file in this module, but I want you to be familiar with what we just talked about and the examples I provided. Our final project–the Network Intelligence Project–will make heavy use of log file parsing, so the problems we ran into earlier here are the same exact problems you’ll be facing in the last month of this course.
What is a function?
A function in programming is exactly the same as a function in mathematics. For example:
- You can substitute a function for a variable.
- Functions can have arguments, which are the inputs to the function.
- Functions can return a value.
- Functions can perform a task, return a value, or both.
How to declare a function
A function is declared by defining it using the def
keyword, and will
have, at a minimum, two empty parentheses after it’s name:
|
|
The scope of a function can be seen as anything that is indented below it.
|
|
How to return a value from a function
A function can return a value, turning its call into an expression, or it can return a value into a variable:
|
|
Functions can be used in place of an expression. For example, if I have a
function that evaluates to True
, I can store it in a variable like this:
def get_python_fun_factor():
return True
is_python_fun = get_python_fun_factor()
# is_python_fun == True
Functions can return many different types. For example, here is a function that returns a string:
|
|
You can see an interactive example here.
How to call a function
In addition to calling a function to return its value to a variable or as an expression, you can simply call a function by itself to make it process all the statements it contains. Calling a function just means activating it.
You do this by just writing the function by itself:
|
|
Again, you can also return the value of a function, which treats the function as an expression:
|
|
How to pass arguments to a function
Just like in math, a function can receive an argument. Do do this, it must be declared with placeholders for each argument:
|
|
Further study
- How to Define Functions in Python 3
Read through this whole tutorial to get very comfortable with functions, and pay CLOSE ATTENTION to the section on usingmain()
as a function. - Python Functions Examples: Call, Indentation, Arguments & Return Values
This is a good overview of functions in Python if, at this point, you are still not very confident about them.