Using Functions in Python 3.7 for Efficient Programming

Categories: Technology

Abstract

Functions are a cornerstone of Python programming, enabling a sequence of instructions to perform a task to be bundled as a cohesive unit. This essay explores the syntax, benefits, and strategic use of functions in Python 3.7, highlighting their role in reducing code duplication, improving code readability, traceability, and hiding implementation details.

Introduction

A function is a sequence of instructions that perform a task, bundled as a unit. This unit can then be imported and used wherever it’s needed. There are many advantages to using functions in your code, as we’ll see shortly.

As you can see, a function is a block of instructions, packaged as a whole, like a box. Functions can accept input arguments and produce output values. Both of these are optional, as we’ll see in the examples in this chapter.

A function in Python is defined by using the def keyword, after which the name of the function follows, terminated by a pair of parentheses (which may or may not contain input parameters), and a colon (:) signals the end of the function definition line.

Get quality help now
writer-Charlotte
writer-Charlotte
checked Verified writer

Proficient in: Technology

star star star star 4.7 (348)

“ Amazing as always, gave her a week to finish a big assignment and came through way ahead of time. ”

avatar avatar avatar
+84 relevant experts are online
Hire writer

Immediately afterward, indented by four spaces, we find the body of the function, which is the set of instructions that the function will execute when called. Note that the indentation by four spaces is not mandatory, but it is the number of spaces suggested by PEP 8, and, in practice, it is the most widely used spacing measure.

A function may or may not return an output. If a function wants to return an output, it does so by using the return keyword, followed by the desired output.

Get to Know The Price Estimate For Your Paper
Topic
Number of pages
Email Invalid email

By clicking “Check Writers’ Offers”, you agree to our terms of service and privacy policy. We’ll occasionally send you promo and account related email

"You must agree to out terms of services and privacy policy"
Write my paper

You won’t be charged yet!

If you have an eagle eye, you may have noticed the little * after Optional in the output section of the preceding diagram. This is because a function always returns something in Python, even if you don’t explicitly use the return clause. If the function has no return statement in its body, or no value is given to the return statement itself, the function returns None. The reasons behind this design choice are outside the scope of an introductory chapter, so all you need to know is that this behavior will make your life easier. As always, thank you, Python.

Functions are among the most important concepts and constructs of any language, so let me give you a few reasons why we need them:

They reduce code duplication in a program. By having a specific task taken care of by a nice block of packaged code that we can import and call whenever we want, we don’t need to duplicate its implementation. They help in splitting a complex task or procedure into smaller blocks, each of which becomes a function.

  1. They hide the implementation details from their users.
  2. They improve traceability.
  3. They improve readability.
  4. Let’s look at a few examples to get a better understanding of each point.

Reducing Code Duplication

Imagine that you are writing a piece of scientific software, and you need to calculate primes up to a limit, as we did in the previous chapter. You have a nice algorithm to calculate them, so you copy and paste it to wherever you need. One day, though, your friend, B. Riemann, gives you a better algorithm to calculate primes, which will save you a lot of time. At this point, you need to go over your whole code base and replace the old code with the new one.

This is actually a bad way to go about it. It’s error-prone, you never know what lines you are chopping out or leaving in by mistake, when you cut and paste code into other code, and you may also risk missing one of the places where prime calculation is done, leaving your software in an inconsistent state where the same action is performed in different places in different ways. What if, instead of replacing the code with a better version of it, you need to fix a bug, and you miss one of the places? That would be even worse.

So, what should you do? Simple! You write a function, get_prime_numbers(upto), and use it anywhere you need a list of primes. When B. Riemann comes to you and gives you the new code, all you have to do is replace the body of that function with the new implementation, and you’re done! The rest of the software will automatically adapt since it’s just calling the function.

Your code will be shorter, it will not suffer from inconsistencies between old and new ways of performing a task, or undetected bugs due to copy-and-paste failures or oversights. Use functions, and you’ll only gain from it, I promise.

Splitting a Complex Task

Functions are also very useful for splitting long or complex tasks into smaller ones. The end result is that the code benefits from it in several ways, for example, readability, testability, and reuse. To give you a simple example, imagine that you’re preparing a report. Your code needs to fetch data from a data source, parse it, filter it, polish it, and then a whole series of algorithms need to be run against it, in order to produce the results that will feed the Report class. It’s not uncommon to read procedures like this that are just one big do_report(data_source) function. There are tens or hundreds of lines of code that end with return report.

These situations are slightly more common in scientific code, which tends to be brilliant from an algorithmic point of view, but sometimes lack the touch of experienced programmers when it comes to the style in which they are written. Now, picture a few hundred lines of code. It’s very hard to follow through, to find the places where things are changing context (such as finishing one task and starting the next one). Do you have the picture in your mind? Good. Don’t do it! Instead, look at this code:

http://data.science.example.py

def do_report(data_source):

fetch and prepare data

data = fetch_data(data_source)

parsed_data = parse_data(data)

filtered_data = filter_data(parsed_data)

polished_data = polish_data(filtered_data)

# run algorithms on data

final_data = analyse(polished_data)

The previous example is fictitious, of course, but can you see how easy it would be to go through the code? If the end result looks wrong, it would be very easy to debug each of the single data outputs in the do_report function. Moreover, it’s even easier to exclude part of the process temporarily from the whole procedure (you just need to comment out the parts you need to suspend). Code like this is easier to deal with.

Hiding Implementation Details

Let’s stay with the preceding example to talk about this point as well. You can see that, by going through the code of the do_report function, you can get a pretty good understanding without reading one single line of implementation. This is because functions hide the implementation details. This feature means that, if you don’t need to delve into the details, you are not forced to, in the way you would if do_report was just one big, fat function. In order to understand what was going on, you would have to read every single line of code. With functions, you don’t need to. This reduces the time you spend reading the code and since, in a professional environment, reading code takes much more time than actually writing it, it’s very important to reduce it by as much as we can.

Improving Readability

Coders sometimes don’t see the point in writing a function with a body of one or two lines of code, so let’s look at an example that shows you why you should do it.

Imagine that you need to multiply two matrices:

Would you prefer to have to read this code:

http://matrix.multiplication.nofunc.py a = [[1, 2], [3, 4]]

b = [[5, 1], [2, 1]]

c = [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)] for r in a]

Or would you prefer this one:

http://matrix.multiplication.func.py

this function could also be defined in another module def matrix_mul(a, b):

return [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)] for r in a]

a = [[1, 2], [3, 4]]

b = [[5, 1], [2, 1]]

c = matrix_mul(a, b)

It’s much easier to understand that c is the result of the multiplication between a and b in the second example. It’s much easier to read through the code and, if you don’t need to modify that multiplication logic, you don’t even need to go into the implementation details. Therefore, readability is improved here while, in the first snippet, you would have to spend time trying to understand what that complicated list comprehension is doing.

Improving Traceability

Imagine that you have written an e-commerce website. You have displayed the product prices all over the pages. Imagine that the prices in your database are stored with no VAT (sales tax), but you want to display them on the website with VAT at 20%. Here are a few ways of calculating the VAT-inclusive price from the VAT-exclusive price:

# http://vat.py

price = 100 # GBP, no VAT

final_price1 = price * 1.2

final_price2 = price + price / 5.0

final_price3 = price * (100 + 20) / 100.0

final_price4 = price + price * 0.2

All these four different ways of calculating a VAT-inclusive price are perfectly acceptable, and I promise you I have found them all in my colleagues’ code, over the years. Now, imagine that you have started selling your products in different countries and some of them have different VAT rates, so you need to refactor your code (throughout the website) in order to make that VAT calculation dynamic.

How do you trace all the places in which you are performing a VAT calculation? Coding today is a collaborative task and you cannot be sure that the VAT has been calculated using only one of those forms. It’s going to be hell, believe me.

So, let’s write a function that takes the input values, vat and price (VAT-exclusive), and returns a VAT-inclusive price:

# http://vat.function.py

def calculate_price_with_vat(price, vat):

return price * (100 + vat) / 100

Now you can import that function and use it in any place in your website where you need to calculate a VAT-inclusive price, and when you need to trace those calls, you can search for calculate_price_with_vat. Note that, in the preceding example, the price is assumed to be VAT-exclusive, and vat is a percentage value (for example, 19, 20, or 23).

Scopes and Name Resolution

Finally, we can talk about functions and this will make everything easier to understand. Let’s start with a very simple example:

http://scoping.level.1.py def my_function:

test = 1 # this is defined in the local scope of the function print('my_function:', test)

test = 0 # this is defined in the global scope

my_function()

print('global:', test)

Conclusion

Functions in Python 3.7 serve as a powerful tool for organizing and structuring code in a logical, readable, and maintainable manner. By leveraging functions, developers can reduce redundancy, enhance code clarity, and encapsulate complex logic, making their programs more efficient and easier to manage.

Updated: Feb 23, 2024
Cite this page

Using Functions in Python 3.7 for Efficient Programming. (2024, Feb 23). Retrieved from https://studymoose.com/document/using-functions-in-python-3-7-for-efficient-programming

Live chat  with support 24/7

👋 Hi! I’m your smart assistant Amy!

Don’t know where to start? Type your requirements and I’ll connect you to an academic expert within 3 minutes.

get help with your assignment