Lesson 6: Functions and Top-Down Design
This lesson presents a top-down problem-solving strategy for designing solutions to programming problems. Students use a worksheet to learn about top-down design, and then on paper, design a solution to a new turtle drawing challenge with a partner. Having practiced this approach on paper and in code, students will be re-presented with the 3x3 square challenge from an earlier lesson and asked to improve upon their old solution by designing multiple layers of functions.
The main purpose here is to familiarize students with the concept of developing "procedural abstractions." One of the main learning objectives in the CSP framework is: "2.2.1 Develop an abstraction when writing a program...". Furthermore the AP Performance Task: Create requires students to "develop an abstraction to manage complexity of your program." For all intents and purposes, developing abstractions starts with writing reusable functions (or procedures) in your code that encapsulate and give a name to multi-line segments of code that other parts of your code calls upon.
A technique for deciding what functions you should write is to look at the problem with a "top-down design" perspective. The process of creating software begins long before the first lines of code are written. Breaking a problem down into layers of sub-tasks, and writing well-named functions that solve those tasks is a creative act of abstraction. It also leads to good code that is more efficient, easier to read, and therefore easier to debug when problems arise.
In professional settings, teams of people first identify the problems and sub-problems the particular software will be addressing and how it will be used. This approach to designing software is critical when facing large-scale programming tasks. Once the problem is well understood, it can be broken into parts that teams or individual programmers can begin to work on solving at the same time. Full software systems take advantage of the power of abstraction; each programmer in a team can write code, assuming the subproblems will be solved and written by other teammates.
Getting Started (5 min)
Students will be able to:
- Write a complete program with functions that solve sub-tasks of a larger programming task.
- Explain how functions are an example of abstraction.
- Use a “top-down” problem-solving approach to identify sub-tasks of a larger programming task.
- Review this explanation of Top-Down Design
Heads Up! Please make a copy of any documents you plan to share with students.
For the Students
- Top-Down Design - Worksheet
- Abstraction - a simplified representation of something more complex. Abstractions allow you to hide details to help you manage complexity, focus on relevant concepts, and reason about problems at a higher level.
- Function - A named bit of programming instructions.
- Top Down Design - a problem solving approach (also known as stepwise design) in which you break down a system to gain insight into the sub-systems that make it up.
Getting Started (5 min)
What Does Efficiency Mean?
In the previous lesson we wrote a program that used layers of functions (functions that called other functions) to get the turtle to draw a diamond-shaped figure.
"Imagine that you have two programs that drew the diamond-shaped figure. One program uses functions as we did in the previous lesson. The other doesn’t use functions; it’s just a long sequence of the turtle’s primitive commands. Which program is more efficient? Make an argument for why one is more efficient than the other."
Have students briefly share their arguments for one program over the other and steer the conversation to these points… “Efficient” can mean several different things here:
- It could mean the total number of primitive operations performed by the turtle.
- It could mean number of lines of code.
- It could hinge on the ability to reuse code within your own code.
- It could be about the speed and clarity with which you can write the program.
All of these are valid arguments for a student to make.
Transition: Efficiency is an interesting thing to think about, but functions also introduce the ability to leverage the power of abstraction: when we write a function, it solves a small piece of a bigger problem. Having the small problem solved allows us to ignore its details and focus on bigger problems or tasks.
Today we’ll get more practice with thinking about how to break problems down into useful functions.
Comparing solutions on paper
The point of having students compare top-down designs is mostly just to see that people think about problems differently. Pairs should move to Code Studio after working out a solution on paper.
More practice with top down design?
If you want to give students more practice with top-down design you can make up almost any geometric shape that has some patterns or repetitions in it. Virtually any symmetrical figure you can create with the turtle would have some elements worth breaking into functions. Here's a trick to make your own: make a function that has the turtle draw something. Then call that function a few times, perhaps turning or moving between each call. Use the resulting figure as an interesting exercise.
Evidence of good design
An interesting thing to look at is the name of the top-level function students come up with, which should be a description of what they think they are drawing.
Guide students to come up with descriptive function names that give insight to their thinking. A high-level function named something like
drawThing is not that great. Something like
antenna is better because it lets the reader see what the programmer is thinking about.
Distribute the Top-Down Design - Worksheet
- Students should work in pairs.
- Read the first page of the worksheet that describes the top-down problem solving process.
- Design a solution to the problem on the second page by writing down the functions they would write to solve the problem.
- After a pair has come up with a solution on paper, have them compare with another group to see similarities and differences.
Transition to Code Studio
Here is a quick reference guide for what students will see in Code Studio.
Some points about functions and abstraction:
- When we layer functions - with functions that call other functions - we are creating layers of abstraction.
- In programming, writing functions helps us create layers of abstraction that allow us to design and create increasingly complex systems.
- We’ve seen layers of abstraction before in the design of Internet protocols, or in the binary encoding of information.
- Solving a fundamental piece of a problem that can be reliably reused in a different context frees us to think about more complex problems because we can trust the piece that has been solved and don’t have to worry about its details.
- Solving small problems - like how to send a single bit from one place to another - allows us to think about bigger problems, like sending numbers, or text, or images, to multiple people, over networks, in packets...etc., etc., etc.
Prompt: "Where else in your life have you seen layers of abstraction? Connect the idea of layers of abstraction to some other activity."
- There are many possible connections to make since almost any task in life can be broken down ad-infinitum. In the video about functions from the previous lesson, Chris Bosh makes a connection to basketball. Once you know how to dribble and shoot, then you learn some moves to do, and once you know that, you run plays that rely on the fact that those fundamental elements (or the problems) have been solved.
If you wish, you may assess the two programs written in Code Studio; the criteria are the same for both the “snowflake” program and the new version of the 3x3 grid:
- The program draws the figure correctly.
- The program defines multiple layers of functions.
- The functions defined have descriptive and meaningful names.
- The program is “kicked off” with a single call to a function that makes calls to subsequent functions.
- The program looks clean and organized.
Consider the figure below. Use top-down thinking to design a solution to the problem. In the space provided write a list of just the names of the functions that you would write in a program that draws this figure. (Assume that the long line segments are 6 turtle moves long.)
Which of the following statements about writing functions and Top-Down Design is NOT true?
- Writing functions helps manage complexity in a program.
- Top-Down Design leads to programs which feature multiple layers of abstraction.
- Two programmers solving the same problem using Top-Down Design should arrive at identical programs.
- Top-Down Design relies upon identifying subproblems of a larger problem.
- Top-Down Design assists in identifying the layers of functions that will be used to solve a programming problem.
In the Create Performance Task you will be asked to identify an abstraction in your program and explain how it helps manage the complexity of the program. Functions are a form of abstraction. Pick a function you wrote in your solution to the 3x3 square problem and explain how it helps manage the complexity of your program.
NOTE: this is a problem from the worksheet. Students are now being asked to write code for it.
Students' solutions should involve writing multiple layers of functions following the principles of top-down design.
You should have already worked with a partner to break down the design below into its multiple layers of functions. Now you'll have an opportunity to program your solution. Here are a few things to keep in mind:
- Identify useful patterns that can be reused and give them their own functions.
- Remember: The functions you design can call one another. This is how you create layers of abstraction.
- Functions should be given names that are descriptive and meaningful.
- Your program should be kicked off with a single call to a function that makes calls to subsequent functions.
Then we revisit the 3x3 grid challenge; this time students can write much more efficient and clear solutions by using a top-down design strategy to figure out good functions to write.
- It’s very possible that in writing a solution with functions, the turtle might actually execute more primitive operations than in the student’s previous version.
- That’s OK, because the code should be much shorter and much easier to read.
- We will trade a well-designed, well-written program for a clumsy hard-to-read program at the cost of a few primitive operations.
We're going to revisit a familiar problem, drawing the 3x3 square as efficiently as possible. The only difference is that this time you are armed with the ability to create layers of functions to help you design more elegant and efficient solutions. Use the techniques you've learned for breaking down problems into layers of functions in order to improve upon your previous solution.
- AP Practice Response - Design Process
- (click tabs to see student view)
AP Practice - Performance Task Response
Top-down design is design process and strategy for breaking down complex things. The AP Create Peformance task asks you to write about your development process when writing code.
Let's take a minute to understand this writing prompt and how it is scored. Here is the actual writing prompt 2b from the AP Create Task guidelines:
Your response to this prompt can get up to 2 points, and is scored looking at two major things:
(1 point) Do you describe a real iterative process for writing the whole program - "Incremental and iterative" means that you continuously improved your program based on testing, reflection, or feedback from a partner.
(1 point) Do you actually describe two points in time while writing your code, what the specific issue was, and how you got past it by reflecting or incorporating feedback from a collaborative partner.
Here are the actual scoring guidelines:
Now you try it
Try to write a response to this AP Prompt thinking about either how you developed the idea for the snowflake drawing program, or how you resolved to make the 3x3 grid program. You might have to use a little bit of imagination to assume that it's part of a larger program you created yourself. The point is to practice writing about your development process.
NOTE: Writing a response like this will take some time to think about and compose.
Consider the figure below. Use top-down thinking to design a solution to the problem. In the space provided write a list of just the names of the functions that you would write in a program that draws this figure. (Assume that the long line segments are 6 turtle moves long).
- Two programmers solving the same problem using Top-Down Design should arrive at identical programs.
- Explanation: Often, there are multiple correct ways to arrive at a solution. Two programmers working separately on the same problem could come up with different ways to solve that problem, so their programs will also be different.
In the Create Performance Task, you will be asked to identify an abstraction in your program and explain how it helps manage the complexity of the program. Functions are a form of abstraction. Pick a function you wrote in your solution to the 3x3 square problem and explain how it helps manage the complexity of your program.
CSTA K-12 Computer Science Standards (2011)
CL - Collaboration
- CL.L2:3 - Collaborate with peers, experts and others using collaborative practices such as pair programming, working in project teams and participating in-group active learning activities.
CPP - Computing Practice & Programming
- CPP.L1:6-06 - Implement problem solutions using a block based visual programming language.
- CPP.L2:4 - Demonstrate an understanding of algorithms and their practical application.
- CPP.L2:5 - Implement problem solutions using a programming language, including: looping behavior, conditional statements, logic, expressions, variables and functions.
- CPP.L3A:3 - Use various debugging and testing methods to ensure program correctness (e.g., test cases, unit testing, white box, black box, integration testing)
- CPP.L3A:4 - Apply analysis, design, and implementation techniques to solve problems (e.g., use one or more software lifecycle models).
CT - Computational Thinking
- CT.L2:1 - Use the basic steps in algorithmic problem-solving to design solutions (e.g., problem statement and exploration, examination of sample instances, design, implementing a solution, testing and evaluation).
- CT.L2:12 - Use abstraction to decompose a problem into sub problems.
- CT.L2:4 - Evaluate ways that different algorithms may be used to solve the same problem.
- CT.L2:6 - Describe and analyze a sequence of instructions being followed (e.g., describe a characterâ€™s behavior in a video game as driven by rules and algorithms).
- CT.L3A:1 - Use predefined functions and parameters, classes and methods to divide a complex problem into simpler parts.
- CT.L3A:4 - Compare techniques for analyzing massive data collections.
Computer Science Principles
2.2 - Multiple levels of abstraction are used to write programs or create other computational artifacts
2.2.1 - Develop an abstraction when writing a program or creating other computational artifacts. [P2]
- 2.2.1A - The process of developing an abstraction involves removing detail and generalizing functionality.
2.2.2 - Use multiple levels of abstraction to write programs. [P3]
- 2.2.2A - Software is developed using multiple levels of abstractions, such as constants, expressions, statements, procedures, and libraries.
- 2.2.2B - Being aware of and using multiple levels of abstraction in developing programs helps to more effectively apply available resources and tools to solve problems.
2.2.3 - Identify multiple levels of abstractions that are used when writing programs. [P3]
- 2.2.3A - Different programming languages offer different levels of abstraction.
- 2.2.3D - In an abstraction hierarchy, higher levels of abstraction (the most general concepts) would be placed toward the top and lower level abstractions (the more specific concepts) toward the bottom.
5.1 - Programs can be developed for creative expression, to satisfy personal curiosity, to create new knowledge, or to solve problems (to help people, organizations, or society).
5.1.2 - Develop a correct program to solve problems. [P2]
- 5.1.2A - An iterative process of program development helps in developing a correct program to solve problems.
- 5.1.2B - Developing correct program components and then combining them helps in creating correct programs.
- 5.1.2C - Incrementally adding tested program segments to correct, working programs helps create large correct programs.
5.1.3 - Collaborate to develop a program. [P6]
- 5.1.3A - Collaboration can decrease the size and complexity of tasks required of individual programmers.
- 5.1.3B - Collaboration facilitates multiple perspectives in developing ideas for solving problems by programming.
- 5.1.3C - Collaboration in the iterative development of a program requires different skills than developing a program alone.
- 5.1.3D - Collaboration can make it easier to find and correct errors when developing programs.
- 5.1.3E - Collaboration facilitates developing program components independently.
- 5.1.3F - Effective communication between participants is required for successful collaboration when developing programs.
5.3 - Programming is facilitated by appropriate abstractions.
5.3.1 - Use abstraction to manage complexity in programs. [P3]
- 5.3.1A - Procedures are reusable programming abstractions.
- 5.3.1B - A function is a named grouping of programming instructions.
- 5.3.1C - Procedures reduce the complexity of writing and maintaining programs.
- 5.3.1D - Procedures have names and may have parameters and return values.
CSTA K-12 Computer Science Standards (2017)
AP - Algorithms & Programming
- 2-AP-13 - Decompose problems and subproblems into parts to facilitate the design, implementation, and review of programs.
- 3A-AP-17 - Decompose problems into smaller components through systematic analysis, using constructs such as procedures, modules, and/or objects.
- 3A-AP-18 - Create artifacts by using procedures within a program, combinations of data and procedures, or independent but interrelated programs.
- 3B-AP-14 - Construct solutions to problems using student-created components, such as procedures, modules and/or objects.