Question
You will often use functions or procedures that have been written by someone else (perhaps as part of a library). You don't need to understand the internal details of those procedures; you might not even have access to the source code! However, documentation for the Application Programming Interface (API) will tell you everything you need to know to use the functions successfully. Using procedures without worrying about internal details is called procedural abstraction.
You might also find yourself writing the same code or block of logic more than one time within your program. There are many advantages to creating functions out of those similar blocks of code. By creating functions that can be reused in different situations, you are demonstrating modularity.
Using Procedural Abstraction
Programmers love to reuse code. By simply calling a function from your program, you can accomplish a task without duplicating the statements in the body of the function in your own program. Consider some of the built-in Python functions you have already used like print() and input(). You can call these functions - as demonstrated by the program below - without any idea how they really work. This is procedural abstraction in action!
Try It Now
To call a function, you just need to know the function's name, parameters, expected behavior, and expected output. This kind of information can be found in API documentation; you don't need to look at the function's source code. print() and input() may use very complex logic to display information to the screen or get text input from the user, but they are simple for you to use.
Similarly, we can import modules like random to use other procedures without knowing how they are coded. Look at this example:
Try It Now
To call the randrange() function in the random library, we just need to write the function name, provide a couple of numeric parameters, and understand that a random number between those parameters will be returned as a result.
Generating a random (or random-like) number is actually pretty complex for a computer. Procedures like randrange() will use an algorithm to produce a result. There are different algorithms to produce random numbers, and some may work faster or produce better results than others. What happens if a new version of Python includes a different internal algorithm inside the randrange() function? Your code will continue to work just fine as long as the function name, parameters, behavior, and results are the same!
Functions can be improved internally without impacting anyone who is using that function.
Advantages of Procedural Abstraction
Let's summarize the main advantages of using procedural abstraction.
Your programs are easier to write. You don't need to understand the internal workings of existing functions.
Your program code is shorter. You don't have to duplicate code that already exists.
Your program code is less complex and simpler to read and understand. It is easier to understand the purpose of a single statement making a function call as compared to reading a block of code to figure out what it is doing.
Improvements can be made to a function without impacting users. As long as your function name, parameters, behavior, and return data are the same, you can make other internal improvements to functions and programs using it will continue to work.
When writing your own programs, you should look for opportunities to use procedural abstraction. For example, if you identify a task that would fit nicely into a function, try looking for a function in a Python library that already does that task before writing your own logic. If you try to reinvent everything from scratch, your programs will be more complex, harder to write, and harder to understand.
Modularity
Careful use of functions or procedures allows programmers to break larger programs into smaller pieces. This is called modularity. Instead of writing a single, complex, hard-to-understand, and hard-to-test block of logic, we write a main program that uses modules or functions to do much of the work. Our main program code is then easier to understand, write, and maintain.
To use modularity, you need to look for opportunities to create functions that can be used more than once in your program. Let's explore an example program that can be simplified with modularity. We want our program to determine letter grades (A, B, C, D, F) based on a numeric score between 0 and 100%. A score of 90% to 100% is an A, 80% to 89% is a B, and so on.
Grade Scale
Our program needs to convert three numeric grades. If we do not use modularity to create a procedure, our code might look something like this.
grade1 = 90
if grade1 >= 90:
print("A")
elif grade1 >= 80:
print("B")
elif grade1 >=70:
print("C")
elif grade1 >= 60:
print("D")
else:
print("F")
grade2 = 77
if grade2 >= 90:
print("A")
elif grade2 >= 80:
print("B")
elif grade2 >=70:
print("C")
elif grade2 >= 60:
print("D")
else:
print("F")
grade3 = 85
if grade3 >= 90:
print("A")
elif grade3 >= 80:
print("B")
elif grade3 >=70:
print("C")
elif grade3 >= 60:
print("D")
else:
print("F")
Copy
As you can see, this code is long and has duplicate logic. What happens if we wanted to fix an error in an "if" statement or change the grading scale? You would need to find and fix those problems in every one of those similar sets of "if" blocks. As a wise programmer, you identify these "if" statements as something that can be wrapped up as a neat function that can be called more than once.
Designing Functions
When you want to define a function, be sure to identify these important characteristics:
Function name
Function parameters
Function return data
Function behavior
In this example, we will call our function "calculateGrade". It will have one input parameter, which is the numeric score from 0 - 100. It will not have any return data. Internally, the function will compare the input parameter against the grading scale to determine the letter grade ("A", "B", "C", "D", "F") and print that grade to the screen.
With only this function design - but no written function yet - you can already envision your main program getting reduced to just 3 statements!
calculateGrade(92)
calculateGrade(60)
calculateGrade(85)
Copy
Let's fully implement this program, including the function, and observe the modularity at work.
Try It Now
While not all procedures have parameters, those that do tend to be more flexible and powerful. Without any input parameters, a function will always do the same thing each time it is called. When you provide parameters, the function logic can make decisions and produce different outputs or behavior based on that input. A more flexible function is more useful and can often handle a wider variety of tasks.
Solving Problems with Modularity
Given a large problem or task, programmers will usually start thinking about modularity right away. It is often easier to split a large program into a series of smaller problems and then solve those smaller problems individually. When we have a collection of modules that work individually, we can combine them to solve the larger problem.
Let's design a program that will display the words to the "Old MacDonald Had a Farm" nursery rhyme. The lyrics are repetitive but change slightly each time you move to a new animal that makes a new sound. This example shows the lyrics for a "cow" that makes a "moo" sound.
"Old MacDonald had a farm, E-I-E-I-O. And on this farm he had a cow, E-I-E-I-O. With a moo moo here and a moo moo there, here a moo, there a moo, everywhere a moo moo, Old MacDonald had a farm, E-I-E-I-O."
The words in bold (cow and moo) change each time a new animal is added, but the rest of the words are the same. We can generalize the output for any <animal> making any <sound> as shown below.
"Old MacDonald had a farm, E-I-E-I-O. And on this farm he had a <animal>, E-I-E-I-O. With a <sound> <sound> here and a <sound> <sound> there, here a <sound>, there a <sound>, everywhere a <sound> <sound>, Old MacDonald had a farm, E-I-E-I-O."
Our program wants to repeat these lyrics over and over again with small changes. This seems like a great place for a function! Clearly, our function should have two parameters - an animal and a sound. We could also decide that our function will internally print the final text on the screen instead of returning any data.
def oldMacDonald(animal, sound):
Copy
With this function defined, we can imagine our main program works by simply calling the function with different parameters.
oldMacDonald("cow", "moo")
oldMacDonald("pig", "oink")
Copy
Now we just need to write the function itself, and our program is done. Check out the results below!
Try It Now
Is there anything we could do to make this program even more modular? Let's review our oldMacdonald() function and see if any parts of that logic seem repetitive. While much of the output text is unique, the "E-I-E-I-O. " text is repeated several times. We could create a small function to help build the overall result. It is common for functions to call other functions to get things done!
Let's define a small function called EI() that will take no parameters and simply return the "E-I-E-I-O." text. We'll then call that function as needed from within oldMacDonald().
Try It Now
The program output is the same, but the program logic is more modular. In fact, you can easily create a new version of the song by changing the EI() function to return something else! Can you produce a song that uses "W-A-W-A-O" instead?
Let's review our program in terms of modularity and procedural abstraction.
To create a modular program, we studied the desired output or behavior and found patterns that repeated. We then wrote a function to handle that repetitive task. To make the function more powerful, we added input parameters so the function could produce the right output for any kind of animal. We refined the program by continuing to divide one task into smaller pieces that worked together.
Our main program logic was reduced to three statements by using procedural abstraction. It simply calls a function several times with different parameters to get things done. When we first visualized the main logic, we didn't even know how the oldMacdonald() function would work internally, but we knew what input data it needed and what it would do for the main program. We also demonstrated that the smaller modules or functions could be changed slightly without breaking the main program logic.
What is procedural abstraction? How do you practice it when writing your own programs?
What are some examples of functions you have called without understanding their internal workings?
What are the advantages of using procedural abstraction?
What is modularity? How do you practice it when writing programs?
What key pieces of information do you need when designing your own functions?
How do you make procedures more flexible and powerful?
How do modular programs reduce code complexity, improve readability, and support maintainability?
You might also find yourself writing the same code or block of logic more than one time within your program. There are many advantages to creating functions out of those similar blocks of code. By creating functions that can be reused in different situations, you are demonstrating modularity.
Using Procedural Abstraction
Programmers love to reuse code. By simply calling a function from your program, you can accomplish a task without duplicating the statements in the body of the function in your own program. Consider some of the built-in Python functions you have already used like print() and input(). You can call these functions - as demonstrated by the program below - without any idea how they really work. This is procedural abstraction in action!
Try It Now
To call a function, you just need to know the function's name, parameters, expected behavior, and expected output. This kind of information can be found in API documentation; you don't need to look at the function's source code. print() and input() may use very complex logic to display information to the screen or get text input from the user, but they are simple for you to use.
Similarly, we can import modules like random to use other procedures without knowing how they are coded. Look at this example:
Try It Now
To call the randrange() function in the random library, we just need to write the function name, provide a couple of numeric parameters, and understand that a random number between those parameters will be returned as a result.
Generating a random (or random-like) number is actually pretty complex for a computer. Procedures like randrange() will use an algorithm to produce a result. There are different algorithms to produce random numbers, and some may work faster or produce better results than others. What happens if a new version of Python includes a different internal algorithm inside the randrange() function? Your code will continue to work just fine as long as the function name, parameters, behavior, and results are the same!
Functions can be improved internally without impacting anyone who is using that function.
Advantages of Procedural Abstraction
Let's summarize the main advantages of using procedural abstraction.
Your programs are easier to write. You don't need to understand the internal workings of existing functions.
Your program code is shorter. You don't have to duplicate code that already exists.
Your program code is less complex and simpler to read and understand. It is easier to understand the purpose of a single statement making a function call as compared to reading a block of code to figure out what it is doing.
Improvements can be made to a function without impacting users. As long as your function name, parameters, behavior, and return data are the same, you can make other internal improvements to functions and programs using it will continue to work.
When writing your own programs, you should look for opportunities to use procedural abstraction. For example, if you identify a task that would fit nicely into a function, try looking for a function in a Python library that already does that task before writing your own logic. If you try to reinvent everything from scratch, your programs will be more complex, harder to write, and harder to understand.
Modularity
Careful use of functions or procedures allows programmers to break larger programs into smaller pieces. This is called modularity. Instead of writing a single, complex, hard-to-understand, and hard-to-test block of logic, we write a main program that uses modules or functions to do much of the work. Our main program code is then easier to understand, write, and maintain.
To use modularity, you need to look for opportunities to create functions that can be used more than once in your program. Let's explore an example program that can be simplified with modularity. We want our program to determine letter grades (A, B, C, D, F) based on a numeric score between 0 and 100%. A score of 90% to 100% is an A, 80% to 89% is a B, and so on.
Grade Scale
Our program needs to convert three numeric grades. If we do not use modularity to create a procedure, our code might look something like this.
grade1 = 90
if grade1 >= 90:
print("A")
elif grade1 >= 80:
print("B")
elif grade1 >=70:
print("C")
elif grade1 >= 60:
print("D")
else:
print("F")
grade2 = 77
if grade2 >= 90:
print("A")
elif grade2 >= 80:
print("B")
elif grade2 >=70:
print("C")
elif grade2 >= 60:
print("D")
else:
print("F")
grade3 = 85
if grade3 >= 90:
print("A")
elif grade3 >= 80:
print("B")
elif grade3 >=70:
print("C")
elif grade3 >= 60:
print("D")
else:
print("F")
Copy
As you can see, this code is long and has duplicate logic. What happens if we wanted to fix an error in an "if" statement or change the grading scale? You would need to find and fix those problems in every one of those similar sets of "if" blocks. As a wise programmer, you identify these "if" statements as something that can be wrapped up as a neat function that can be called more than once.
Designing Functions
When you want to define a function, be sure to identify these important characteristics:
Function name
Function parameters
Function return data
Function behavior
In this example, we will call our function "calculateGrade". It will have one input parameter, which is the numeric score from 0 - 100. It will not have any return data. Internally, the function will compare the input parameter against the grading scale to determine the letter grade ("A", "B", "C", "D", "F") and print that grade to the screen.
With only this function design - but no written function yet - you can already envision your main program getting reduced to just 3 statements!
calculateGrade(92)
calculateGrade(60)
calculateGrade(85)
Copy
Let's fully implement this program, including the function, and observe the modularity at work.
Try It Now
While not all procedures have parameters, those that do tend to be more flexible and powerful. Without any input parameters, a function will always do the same thing each time it is called. When you provide parameters, the function logic can make decisions and produce different outputs or behavior based on that input. A more flexible function is more useful and can often handle a wider variety of tasks.
Solving Problems with Modularity
Given a large problem or task, programmers will usually start thinking about modularity right away. It is often easier to split a large program into a series of smaller problems and then solve those smaller problems individually. When we have a collection of modules that work individually, we can combine them to solve the larger problem.
Let's design a program that will display the words to the "Old MacDonald Had a Farm" nursery rhyme. The lyrics are repetitive but change slightly each time you move to a new animal that makes a new sound. This example shows the lyrics for a "cow" that makes a "moo" sound.
"Old MacDonald had a farm, E-I-E-I-O. And on this farm he had a cow, E-I-E-I-O. With a moo moo here and a moo moo there, here a moo, there a moo, everywhere a moo moo, Old MacDonald had a farm, E-I-E-I-O."
The words in bold (cow and moo) change each time a new animal is added, but the rest of the words are the same. We can generalize the output for any <animal> making any <sound> as shown below.
"Old MacDonald had a farm, E-I-E-I-O. And on this farm he had a <animal>, E-I-E-I-O. With a <sound> <sound> here and a <sound> <sound> there, here a <sound>, there a <sound>, everywhere a <sound> <sound>, Old MacDonald had a farm, E-I-E-I-O."
Our program wants to repeat these lyrics over and over again with small changes. This seems like a great place for a function! Clearly, our function should have two parameters - an animal and a sound. We could also decide that our function will internally print the final text on the screen instead of returning any data.
def oldMacDonald(animal, sound):
Copy
With this function defined, we can imagine our main program works by simply calling the function with different parameters.
oldMacDonald("cow", "moo")
oldMacDonald("pig", "oink")
Copy
Now we just need to write the function itself, and our program is done. Check out the results below!
Try It Now
Is there anything we could do to make this program even more modular? Let's review our oldMacdonald() function and see if any parts of that logic seem repetitive. While much of the output text is unique, the "E-I-E-I-O. " text is repeated several times. We could create a small function to help build the overall result. It is common for functions to call other functions to get things done!
Let's define a small function called EI() that will take no parameters and simply return the "E-I-E-I-O." text. We'll then call that function as needed from within oldMacDonald().
Try It Now
The program output is the same, but the program logic is more modular. In fact, you can easily create a new version of the song by changing the EI() function to return something else! Can you produce a song that uses "W-A-W-A-O" instead?
Let's review our program in terms of modularity and procedural abstraction.
To create a modular program, we studied the desired output or behavior and found patterns that repeated. We then wrote a function to handle that repetitive task. To make the function more powerful, we added input parameters so the function could produce the right output for any kind of animal. We refined the program by continuing to divide one task into smaller pieces that worked together.
Our main program logic was reduced to three statements by using procedural abstraction. It simply calls a function several times with different parameters to get things done. When we first visualized the main logic, we didn't even know how the oldMacdonald() function would work internally, but we knew what input data it needed and what it would do for the main program. We also demonstrated that the smaller modules or functions could be changed slightly without breaking the main program logic.
What is procedural abstraction? How do you practice it when writing your own programs?
What are some examples of functions you have called without understanding their internal workings?
What are the advantages of using procedural abstraction?
What is modularity? How do you practice it when writing programs?
What key pieces of information do you need when designing your own functions?
How do you make procedures more flexible and powerful?
How do modular programs reduce code complexity, improve readability, and support maintainability?
Answers
Answer
1. What is procedural abstraction? How do you practice it when writing your own programs?
2. What are some examples of functions you have called without understanding their internal workings?
3. What are the advantages of using procedural abstraction?
4. What is modularity? How do you practice it when writing programs?
5. What key pieces of information do you need when designing your own functions?
6. How do you make procedures more flexible and powerful?
7. How do modular programs reduce code complexity, improve readability, and support maintainability?
2. What are some examples of functions you have called without understanding their internal workings?
3. What are the advantages of using procedural abstraction?
4. What is modularity? How do you practice it when writing programs?
5. What key pieces of information do you need when designing your own functions?
6. How do you make procedures more flexible and powerful?
7. How do modular programs reduce code complexity, improve readability, and support maintainability?
Answer
Make the sentences shorter
There are no AI answers yet. The ability to request AI answers is coming soon!
Submit Your Answer
We prioritize human answers over AI answers.
If you are human, and you can answer this question, please submit your answer.