From Algorithms to
Building Python Programs
Part 2: Simple Functions in Python
Task Decomposition and
Stepwise Refinement
Algorithms
algorithm: A list of steps for solving a problem.
Example algorithm: "Bake sugar cookies"
• Mix the dry ingredients.
• Cream the butter and sugar.
• Beat in the eggs.
• Stir in the dry ingredients.
• Set the oven temperature.
• Set the timer for 10 minutes.
• Place the cookies into the oven.
• Allow the cookies to bake.
• Spread frosting and sprinkles onto the cookies.
• ...
Problems with algorithms
lack of structure: Many steps; tough to follow.
redundancy: Consider making a double batch...
• Mix the dry ingredients.
• Cream the butter and sugar.
• Beat in the eggs.
• Stir in the dry ingredients.
• Set the oven temperature.
• Set the timer for 10 minutes.
• Place the first batch of cookies into the oven.
• Allow the cookies to bake.
• Set the timer for 10 minutes.
• Place the second batch of cookies into the oven.
• Allow the cookies to bake.
• Mix ingredients for frosting.
• ...
Structured algorithms
structured algorithm: Split into coherent tasks.
1 Make the batter.
• Mix the dry ingredients.
• Cream the butter and sugar.
• Beat in the eggs. Remember
• Stir in the dry ingredients. “breaking down the task into subtasks”?
2 Bake the cookies.
• Set the oven temperature.
• Set the timer for 10 minutes.
• Place the cookies into the oven.
• Allow the cookies to bake.
3 Decorate the cookies.
• Mix the ingredients for the frosting.
• Spread frosting and sprinkles onto the cookies.
...
Removing redundancy
A well-structured algorithm can describe repeated tasks with less redundancy.
1 Make the cookie batter.
• Mix the dry ingredients.
• ...
2a Bake the cookies (first batch).
• Set the oven temperature.
• Set the timer for 10 minutes.
• ...
2b Bake the cookies (second batch).
• Repeat Step 2a
3 Decorate the cookies.
• ...
Functions
function: A named group of statements.
• denotes the structure of a program Function A
• eliminates redundancy by code reuse
statement
statement
statement
procedural decomposition:
dividing a problem into functions Function B
statement
statement
Writing a function is like adding Function C
statement
a new command to Python.
statement
• You determine what the command does
statement
Decomposing the “Make Cake”
Task
One Piece at a Time
Instead of trying to produce a complete working program all at once
Work on one piece at a time
• Select one piece to complete
• Then add another
• Then another
• Then another,
• etc.
Process is called iterative enhancement or stepwise refinement
Functions
Declaring a function
Gives your function a name so it can be executed
Syntax:
def name():
statement
statement
...
statement
Example:
def print_warning():
print("This product causes cancer")
print("in lab rats and humans.")
Calling a function
Executes the function’s code
Syntax:
name()
• You can call the same function many times if you like.
Example:
print_warning( #separate multiple words with underscores
• Output:
This product causes cancer
in lab rats and humans.
Using functions
1. Design (think about) the algorithm.
• Look at the structure, and which commands are repeated.
• Decide what are the important overall tasks.
2. Declare (write down) the functions. (We also use define)
• Arrange statements into groups and give each group a name.
3. Call (run) the function.
Program with functions
# This function prints the lyrics to my favorite song.
def rap():
print("Now this is the story all about how")
print("My life got flipped turned upside-down")
rap() # Calling (running) the rap function
print()
rap() # Calling the rap function again
Program with functions: Output
Output:
Now this is the story all about how
My life got flipped turned upside-down
Now this is the story all about how
My life got flipped turned upside-down
Functions calling functions
def message1():
print("This is message1.")
Output:
This is message1.
def message2(): This is message2.
print("This is message2.") This is message1.
message1() Done with message2.
print("Done with message2.") Done with main.
message1()
message2()
print("Done with everything.")
Control flow
When a function is called, the program's execution...
• "jumps" into that function, executing its statements, then
• "jumps" back to the point where the function was called.
def message1():
message1()
print("This is message1.")
message2()
def message2():
print("This is message2.")
message1()
print("Done with main.")
print("Done with message2.")
...
def message1():
print("This is message1.")
Structure of a program
No code should be placed outside a function. Instead use a main
function.
• The one exception is a call to your main function
def main():
message1() The main function is “the boss”
message2()
print("Done with everything.")
def message1():
print("This is message1.")
def message2():
print("This is message2.")
message1()
print("Done with message2.")
main()
When to use functions (besides
main)
Place statements into a function if:
• The statements are related structurally, and/or
• The statements are repeated.
You should not create functions for:
• An individual print statement.
• Only blank lines.
• Unrelated or weakly related statements.
(Consider splitting them into two or more smaller functions.)
Drawing complex
figures with
functions
______
Functions question /
/ \
\
\ /
Write a program to print these figures using \______/
functions. \ /
\______/
+--------+
______
/ \
/ \
| STOP |
\ /
\______/
______
/ \
/ \
+--------+
______
Development strategy /
/ \
\
\ /
First version (unstructured): \______/
Create an empty program.
\ /
Copy the expected output into it, surrounding
\______/
each line with print syntax.
+--------+
Run it to verify the output. ______
/ \
/ \
| STOP |
\ /
\______/
______
/ \
/ \
+--------+
def main():
Program version 1print(" ______")
print(" / \\")
# Underscores
print("/ \\")
print("\\ /")
print(" \\______/")
print()
print("\\ /")
print(" \\______/")
print("+--------+") # Hyphens
print()
print(" ______")
print(" / \\")
print("/ \\")
print("| STOP |")
print("\\ /")
print(" \\______/")
print()
print(" ______")
print(" / \\")
print("/ \\")
print("+--------+")
main()
______
Development strategy 2 /
/ \
\
\ /
Second version (structured, with redundancy): \______/
Identify the structure of the output. \ /
\______/
Divide the code into functions based on this +--------+
structure.
______
/ \
/ \
| STOP |
\ /
\______/
______
/ \
/ \
+--------+
______
/ \
Output structure /
\
\
/
\______/
The structure of the output:
initial "egg" figure \ /
second "teacup" figure
\______/
+--------+
third "stop sign" figure
fourth "hat" figure ______
/ \
/ \
This structure can be | STOP |
represented by functions: \ /
egg
\______/
tea_cup
stop_sign ______
hat
/ \
/ \
+--------+
Program version 2
def main(): def egg(): def stop_sign():
egg() print(" ______") print(" ______")
tea_cup() print(" / \\") print(" / \\")
stop_sign() print("/ \\") print("/ \\")
hat() print("\\ /") print("| STOP |")
print(" \\______/") print("\\ /")
print() print(" \\______/")
print()
def tea_cup(): def hat():
print("\\ /") print(" ______")
print(" \\______/") print(" / \\")
print("+--------+") print("/ \\")
print() print("+--------+")
______
Development strategy 3 /
/ \
\
\ /
Third version (structured, without redundancy): \______/
Identify redundancy in the output, and create \ /
functions to eliminate as much as possible. \______/
+--------+
Add comments to the program. ______
/ \
/ \
| STOP |
\ /
\______/
______
/ \
/ \
+--------+
______
Output redundancy /
/ \
\
The redundancy in the output: \ /
\______/
egg top: reused on stop sign, hat
egg bottom: reused on teacup, stop sign
\ /
\______/
divider line: used on teacup, hat +--------+
This redundancy can be fixed by functions: ______
egg_top
/ \
/ \
egg_bottom
| STOP |
line \ /
\______/
______
/ \
/ \
+--------+
Program version 3
def main():
egg() def tea_cup():
tea_cup() egg_bottom()
stop_sign() line()
hat() print()
def egg_top(): def stop_sign():
print(" ______") egg_top()
print(" / \\") print("| STOP |")
print("/ \\") egg_bottom()
print()
def egg_bottom():
print("\\ /") def hat():
print(" \\______/") egg_top()
line()
def egg():
egg_top() def line():
egg_bottom() print("+--------+")
print()
Program version 3 – with
comments added # Draws a teacup figure.
def tea_cup():
# Suzy Student, CSc 110, Spring 2094
# Prints several figures, with methods for structure and
egg_bottom()
redundancy. line()
print()
def main():
egg()
tea_cup() # Draws a stop sign figure.
stop_sign() def stop_sign():
hat() egg_top()
print("| STOP |")
# Draws the top half of an an egg figure.
def egg_top(): egg_bottom()
print(" ______") print()
print(" / \\")
print("/ \\") # Draws a figure that looks sort of like a
hat.
# Draws the bottom half of an egg figure.
def hat():
def egg_bottom():
print("\\ /") egg_top()
print(" \\______/") line()
# Draws a complete egg figure.
# Draws a line of dashes.
def egg():
egg_top() def line():
egg_bottom() print("+--------+")
print()
Activity 23 – More /
______
\
Decomposition /
\
\
/
\______/
Can you decompose the task even more?
\ /
\______/
+--------+
You may need/want to make some other
changes. ______
/ \
/ \
| STOP |
Submit to Exercise 14 in Canvas. \ /
\______/
______
/ \
/ \
+--------+
Activity 24 – Draw
Letters
Look at the letters in 9x5letters.xlsx
How can you decompose the letters so you
use just a few functions to draw them?
Work in pairs:
• Decide on a decomposition
• Divide up the letters between the two of you
• Work in class Finish up at home
• Draw your names (vertically)
Submit to Exercise 15 in Canvas.