Deconstructing Ideas And Constructing Code • Using the Store-Repeat-Decide-Reuse Concept
Starting to code on a blank page • How do you convert your ideas into code?
One of the hardest aspects of programming is facing a blank page at the start of the process. You have a clear idea of the problem you'd like to solve. But how do you convert your "human" idea into computer code?
I call this the "Spanish problem". I'm lucky to come from a part of the world where it's common to speak several languages–human languages. However, my Spanish is stuck in that stage where I can read and understand it fairly well, but I freeze the moment I need to speak Spanish! ¡Mi español no es muy bueno!
A common comment I hear from many beginners and intermediate programmers is that they understand code quite well when it's explained to them or when they see it written down. However, they don't know where to start when they're trying to write code independently. This is the coding equivalent of my "Spanish problem".
There's no magic solution to this problem. However, I use the Store, Repeat, Decide, Reuse concept to help break down an idea and translate it from English (or whatever language you think in) into Python (or whatever programming language you code in).
Every aspect of a computer program falls under one of these four categories:
Store
Repeat
Decide
Reuse
Let's see how we can use this concept to help with the "Spanish problem", and we'll look at some examples.
Store-Repeat-Decide-Reuse
You can categorise what goes on within a computer program using one of these categories:
Store: You need to store some information within your program to use it later. Often, you do this by assigning data to a variable name. Data is key in any computer program. Later in this article, I'll claim that the Store part of this approach often includes some of the hardest decisions you need to make when planning a computer program
Repeat: You need to repeat a block of code several times in a row. The most common options for repeating code are using
for
orwhile
loopsDecide: You need the computer program to make a decision while the program is running. This is not a decision that you, the programmer, can take when writing the code. Instead, it's a decision you need the program to take during the execution of the code. You'll often use an
if
statement for these decisionsReuse: You have a block of code that you'll need to reuse in several places in your code, possibly using different data as input. Defining functions using the
def
keyword is one way of making code reusable
Reusing and repeating can seem similar, but there's an important distinction. You repeat a block of code several times in a row. You "package" code so you can reuse it in different parts of your program. You can also create functions even if you intend to use them once.
You should use these concepts as general guidelines to help you think about your program. Not everything falls neatly into just one category. Let's take a while
loop, for example. The while
loop falls under the Repeat part of this approach since it repeats a block of code. However, there's also a decision-making process that occurs in the while
statement: "Should the program repeat the code again?" The answer depends on whether the statement following while
is True
or False
(or more generally, truthy or falsy.)
We'll also discuss classes later in this article, which merge Store and Reuse into one entity.
We'll look at practical examples of using this approach soon. But first, let's talk about storing data a bit more.
There Are Many Different Types of Boxes to Store Things
I often ask students which of the four aspects they think will provide the biggest challenge when coding. Very few choose Store. However, that's the one I would choose as the trickiest of the lot.
The main reason I believe Store poses the biggest challenges is not just because you need to identify what needs to be stored—that too can be a challenge—but you need to decide which "type of box" to use to store these data. Which data type is best suited for the job?
There are times when the data type you need is obvious. An integer to store the number of people in a group. A string to store the name of a player in a game. But often, the structure of the data is more complex, and you need to consider several options. Should you store the students in a class as a list of strings, or perhaps a list of tuples, maybe named tuples? Or maybe, a sequence of dictionaries might work better? Why not a pandas dataframe along with other data relevant to each student?
The answer depends on many factors. It depends on what you want to achieve in your program, your coding style and preference, and other constraints and requirements. Indeed, there isn't just one "right" answer on how to store your data. There are always several options.
Thinking about these options before you start coding will save you from having to rewrite your code too many times as you change your mind about what data structures to use. Or worse still, you'll stick with the wrong choice because you've come too far to change!
Asking the Store, Repeat, Decide, and Reuse Questions
A quote I often use when mentoring learners is the one attributed to John Johnson: "First solve the problem, then write the code". I often like to distinguish between the subject-specific knowledge you need to solve the problem and the programming-specific knowledge needed to write the code. The tricky part is the interface between these two as you transition from solving the problem to figuring out how to write the code to implement your solution.
We'll look at some concrete examples soon. But let's outline the process first. As you write down the distinct steps which detail the solution to your problem, you need to ask yourself the following questions about each step in your plan:
Does this step require information to be stored? If you answer yes, you'll need to think about the structure of your data and how you want to use the data throughout the program. You can start shortlisting data structure options. You'll come back to review your decisions once you've gone through the whole project plan
Does this step involve repetition? Do you need to repeat the same actions several times? If the answer is yes, you can choose your tool for repeating. Often, this is likely to be either a
for
loop or awhile
loop, but there are other ways of repeating or iteratingDoes this step require the computer program to make a decision on what to do while the program is running? If the answer is yes, you may well need an
if
statement or some other tool with a conditional statement. As we've mentioned earlier, even awhile
loop includes a decision-making processDoes this step represent a distinct task you want to package into a self-contained "mini-program" by defining a function? You may choose to do this so that you can reuse this function whenever you want to perform this task
Let's look at this process through some examples.
Finding Goblins: An Example
The Goblin Hunt game is a project I often run at the beginning of introductory courses, as it provides a good overview of several of the key fundamental topics. I'll start with this example as it's a relatively simple program. It's a variant of the "guess the number" style of programs. It will help me explain the process of asking the right questions and making decisions on what's needed in your code. If you're already a proficient programmer, you'll find this exercise easy, perhaps even trivial. But the concept will help us with more complex tasks. We'll look at further examples later.
In this project, there's a goblin hiding in one of five kitchen cupboards. The program shows a welcome message and then asks the player to input their name. After showing the kitchen cupboards, the program asks the player to guess where the goblin is hiding. The game keeps going until the player guesses correctly. Here's the output from a run of this program:
Welcome to the Angry Goblin Hunt
An award-winning game full of adventure and excitement (!)
Type in your name: Stephen
Stephen, do you think you can find the goblin hiding in the kitchen cupboards?
|_||_||_||_||_|
Which cupboard do you think the goblin is in [type in number]: 2
Sorry! The goblin is still lurking somewhere else.
Which cupboard do you think the goblin is in [type in number]: 1
Well done!! You have found the goblin. He was so scared he ran away.
The goblin hides in a random cupboard each time you run the game. Here's a possible outcome of the planning stage for this program:
Show welcome message
Ask player to type in their name
Show another message, including showing the cupboards, to get the game started
Place the goblin in one of the cupboards
Ask player to guess where the goblin is hiding
If the player guesses correctly, show a "Well done" message and end the game, and if the player doesn't guess correctly, show another message
Go back to step 5 and repeat steps 5-7 until the player guesses correctly
When you use the Store, Repeat, Decide, Reuse concept, you go through each step and ask which one applies.
Step 1: This step simply displays a string to the user. In this case, you don't need any of the four actions, unless you wish to store the welcome message rather than use it once within the
print()
function. You use a function in this step,print()
. However, the Reuse term applies to writing your own functions rather than using pre-existing onesStep 2: STORE The player types their name and you need to store this information to use later. Therefore, you assign this to a variable name. In this case, a string is likely to be sufficient
Step 3: This is similar to step 1. However, you need to use the data you stored in step 2 within the message. The point of storing information is to use the data later in the program, after all!
Step 4: STORE The program chooses a cupboard at random. You need to store this value since the program needs this information later. An integer will do the job
Step 5: STORE The player types in a number. You need to store this number as it's needed later to check whether the player guessed correctly. You'll likely use
input()
for this, which returns a string. You could keep this as a string, or you can convert to an integer. Whichever option you choose will affect the rest of your codeStep 6: DECIDE The program needs to make a decision on how to proceed. You need to use data you stored earlier, but the program needs to choose which path to take next. Often, this means you'll need an
if
statement, possibly withelif
andelse
clausesStep 7: REPEAT You need to repeat many steps several times. Does the program need to repeat the block of code a fixed amount of times? In that case, you're likely to choose a
for
loop. Or will the program need to decide when to stop repeating the loop? Thewhile
loop is more suitable for this–it merges repeating code with a decision-making process to determine when to stop repeating
You can read a step-by-step description of this code in Chapter 1 of The Python Coding Book if you wish. However, I'll move on to another example in the next section.
Word Frequencies In A Novel: Another Example
We want to analyse a novel by finding all the words used in the novel and find how often each word is used. You have a text file containing the whole novel. As always, there are several options to solve this problem. Here are the steps for one such solution:
Bring the text of the novel into the Python program from the text file
Clean the data. In this case, making everything lowercase and removing punctuation marks are reasonable data-cleaning steps
Look at the first word in the novel. This is the first time this word appears in the novel. Therefore, you need to keep a record of this word and note that it's appeared once in the text so far
Look at the next word. If this is the first time this word appears in the text, keep a record of the word and note that the tally is 1. However, if you've already come across this word earlier in the text, then add 1 to the tally already linked to this word
Repeat step 4 until you reach the end of the novel
Let's review these steps and look at them with Store, Repeat, Decide, Reuse in mind.
Step 1: STORE You need to open and read the text file. However, you need to store its contents somehow within the Python program. Initially, you'll get a string when you read the file. But you should ask yourself whether this data type is the ideal one for the task you need to perform. Later steps require you to look at individual words rather than the whole text. Which data type would be better suited to store the words of the novel? Knowledge of data structures and experience will make this choice easier. You may decide that a sequence of individual words is what you need, such as a list of strings or a tuple of strings.
This process doesn't magically write the code for you, of course. It's a way of helping you focus your thinking to home in on the coding tools you need. You'll still need to figure out how to convert your string into a list of strings, say. You could use the string method
.split()
, which returns a list of strings. In this example, you'll likely make this change after step 2, but you still need to convert from one data type to another to write efficient code.Step 2: STORE / REPEAT / DECIDE Plenty is happening in this step. Changing the whole string you read from the text file to lowercase is not too difficult if you know about the string method
.lower()
. Or, you could choose to use.casefold()
, which may be more appropriate, but that's a discussion for another day.How about removing all the punctuation marks? This process includes both repetition and decision-making. Conceptually, you can look at each character in the text and ask the program to decide whether it's a punctuation mark. If it is, you can remove it. Now, we could translate 'repeat for every character in the text' into a loop, such as a
for
loop. And 'decide whether the character is a punctuation mark' could be dealt with using anif
statement. However, although we can easily associate loops with repeat andif
statements with decide, they're not the only ways to achieve these.For example, in this case, the string method
.replace()
does both the repetition and the decision-making process for us.my_string.replace("a", "b")
will replace all occurrences of"a"
with"b"
in the string. The repetition and decision-making are still there, but they're hidden within the.replace()
method. Therefore, when you explore existing tools, such asstr.replace()
, you can associate them with the concepts that are relevant. In this case, you can associatestr.replace()
with both repeat and decide.Step 3: STORE This step is when we start to visualise how the final data should look like. You started with a single string containing all the text. Then, you convert this to a list of strings. Now, you need to think about what your final data structure should be. You need to have all the words in the text in the final data structure. Each word should appear only once. And each word should have a number associated with it, showing the number of times that word appears in the novel.
It's now up to the programmer to rely on their knowledge of data structures to determine which one would suit these requirements best. A dictionary seems to do the trick. Items in a dictionary consist of a key-value pair. The key could be a string with the word, and its value is an integer with the tally. And each key only appears once in a dictionary.
The challenge with storing data is not identifying when you need to store information but what data structure is the most suitable "storage box".
Step 4: DECIDE When considering a word in the text, you need your program to make a decision: Is the first time it's encountered this word? There are two options. If this is the first occurrence of the word, the program needs to add it to the dictionary and assign the value 1 to the word. If this is not the first occurrence, the program should find the current value associated with the word and increment it by 1.
The "go-to" tool when the program needs to make a decision is the
if
statement. And this would be a suitable solution in this case. You can use anif
statement to check whether the word is already one of the dictionary keys and use anelse
clause to deal with the case when the word is not yet in the dictionary.However, you could also reach out for a
defaultdict
from thecollections
module. A default dictionary is similar to a dictionary but will create a key with a default value if the key doesn't already exist. The decision-making process is now taken over by thedefaultdict
data structure itself. There's still a decision being made. But you don't need to use anif
statement within your code. Default values can often be associated with a decision-making process. If a value is present, the program will use it. But if a value is missing, the default value is used.Step 5: REPEAT Whichever option you choose in step 4, you'll need to repeat the decision-making process for each word in the novel. The end of that last sentence had the solution written in plain English already: "for each word in the novel". You need a
for
loop to iterate through the list of words.
As we've seen in this example, some of the concepts can be abstracted away into other functions or classes. The .replace()
method for strings takes care of repeat and decide. A defaultdict
can deal with decide when looking at each word in the novel.
In fact, you could even use the Counter
class in the collections
module, which abstracts away both the repeat and the decide aspects from steps 4 and 5. If you pass a list of strings to Counter
, you'll get a mapping, similar to a dictionary, with all the words and a tally of how often they appear. It takes care of repeating the process for every word and deciding whether to add to the tally of a word or place the word in the mapping with a value of 1.
If you're using the Store, Repeat, Decide, Reuse mindset, when you look at a method such as .replace()
or classes such as defaultdict
or Counter
, you can make the link with the concepts such as repeat and decide that are abstracted away in these methods and classes. This will help you reach out for these tools when you need them.
Step 6: REUSE Wait a second! There was no step 6 in the planning steps listed above. However, you can ask yourself whether there are parts of this code that can be packaged into reusable units. You may want to read in different novels and then pass the string of text to a function which cleans the data and gives you back a list of words. You may then want to pass this to another function to find all the words and their frequencies. Therefore, you may choose to take parts of your code and turn them into functions to make them reusable.
This project is described in more detail in Chapter 4 | Data, Data Types and Data Structures in The Python Coding Book.
Space Invaders: A Final Example
You don't need me to explain a Space Invaders-type game in detail. You have a spaceship at the bottom that can move left and right and shoot. And there are aliens falling down from the top. If you hit them, they disappear, and you gain points. If an alien reaches the bottom of the screen, you lose. To simplify this discussion, we'll assume that aliens only move vertically downwards and can't move sideways.
Let's tackle this challenge in a different way to the previous examples. Instead of writing down the steps we'll need to break down this game, let's start asking the questions centred around the four key concepts of Store, Repeat, Decide, and Reuse.
Store: What things do we need to store?
Let's look at where you need to store information in your program and what data types you could use:
Spaceship
Position of the spaceship: If the spaceship can only move sideways, you only need a single float to represent its position
Step size when moving the spaceship: The spaceship moves by a set number of pixels each time we move it left or right. This is another float
Collection of aliens: There are several aliens on the screen at any time. You need to collect these in a data structure to store them in the same place. A list of aliens is probably all you need. The length of this list tells you how many aliens are in the game at any time
Alien
Position of each alien: You could use a pair of floats to represent the position
Step size when alien moves: As was the case with the player, you need a float to determine the speed of each alien. This number determines how many pixels an alien moves in each frame of the game
Spawn interval: How long does the program wait before it spawns a new alien? This could be a fixed time interval, which means a single number is all you need. Or it could be a random number generated in a range determined by a minimum and maximum value
Laser pulses
The spaceship shoots laser pulses. The laser pulse needs to also have a position and a speed, similar to the spaceship and aliens
You'll need another list to hold all the laser pulses
Score and Level: You need to keep track of how many aliens you shoot down, and you move up a level every so often. Both of these are integers. When you level up, you could change what's stored in the spawn interval variable and the alien speed variable, say
We could come up with more things that need to be stored in this game. However, this is a comprehensive set and will suffice for this discussion.
Repeat: What things require repetition?
When planning a computer program such as one writing a game like Space Invaders, we can ask two questions. What are the items in the game? And what actions do they take?
Some of those actions will need to be repeated. Let's think about the Space Invaders game and pinpoint any actions that need repetition:
Often in programs, and always in games like Space Invaders, we need a loop that repeats steps in every frame of the game. But let's break this down further:
Aliens need to move down by a certain step size in each frame. Therefore, you'll need to move each alien in the game loop. And each iteration of the game loop will move the aliens again
The aliens are all stored in a single data structure, such as a list. Therefore, anything you need to do to an alien, you'll need to repeat for all aliens in the list
The laser pulses follow the same pattern. They all move forward by a certain step size in each frame, and therefore, you'll need to move them in every iteration of the game loop. And you'll need to perform any actions required on each laser pulse present in the frame
There's a lot of repetition in games!
Decide: Where does the program need to make decisions?
How about decisions? What decisions does the program need to make during such a game? Lots. Let's look at the main ones:
Decide whether a laser pulse has hit an alien. If it has, remove the alien and assign a point to the player. If it hasn't, do nothing
Decide whether a laser pulse has left the screen. If it has, remove it from the program
Decide if an alien has reached the bottom of the screen. If it has, end the game
Decide whether to spawn a new alien at the beginning of a new frame. The program checks how much time has passed since the last alien was spawned and makes a decision based on that
Games are full of decisions that must be taken by the computer program. Every interaction in a game leads to a decision that needs to be taken.
Reuse: What things will we need to reuse?
Games also have several actions that need to happen from time to time, but not necessarily repeated in every frame. This is where you need functions you can call whenever you need them. Here are two key functions required in this game that represent blocks of code you need to reuse:
Move the spaceship left or right when a key is pressed: You need code that deals with changing the location of the spaceship, moving it by the required step size. This function is bound to a key on the keyboard, say, so that the function is called each time the key is pressed
Shoot a laser pulse: This is another block of code you need to reuse each time you want to shoot. This function creates a new laser pulse, sets its position to the location of the spaceship, adds the pulse to the list of laser pulses, and ensures the pulse is ready to start moving forward in each iteration of the game loop.
Classes and Objects
Let's look at object-oriented programming through the lens we're exploring in this article. A class definition is a blueprint for creating objects that share similar characteristics. You're creating a new data type when you define a class. In a sense, a class definition is a way of reusing the same code to create similar objects.
If we drill a bit further, we find that an object of a class has attributes. These could be data attributes or methods. Data attributes are variables linked to the object and they store data. They satisfy the Store part of Store, Repeat, Decide, Reuse. Methods are functions and we've associated functions with the Reuse concept. Therefore, defining classes and creating instances of a class straddles both Store and Reuse. An object carries with it data and the functions (or methods) needed to do stuff with the data.
You can read more about object-oriented programming in Chapter 7 | Object-Oriented Programming in The Python Coding Book or here on The Stack in the Harry Potter-themed series on object-oriented programming.
Final Words
Looking at a computer program from the Store, Repeat, Decide, Reuse perspective is a useful tool to separate the components of a computer program and guide you towards the tools you need to write each part of the code. It's not a magic recipe! And as we've seen in this article, some tools in coding span more than one of these concepts.
Think of this perspective as one of the techniques you can use to solve the "Spanish problem"—the hurdle we need to overcome when converting our ideas into Python code.
Stop Stack
Recently published articles on The Stack:
There's A Method To The Madness • Defining Methods In Python Classes. Year 3 at Hogwarts School of Codecraft and Algorithmancy • Defining Methods
Finding Your Way To The Right Value • Python's Mappings. Part 3 of the Data Structure Categories Series
Python's functools.partial() Lets You Pre-Fill A Function. An exploration of partial() and partialmethod() in functools
Let The Real Magic Begin • Creating Classes in Python. Year 2 at Hogwarts School of Codecraft and Algorithmancy • Defining Classes • Data Attributes
Sequences in Python. Sequences are different from iterables • Part 2 of the Data Structure Categories Series
Most articles will be published in full on the free subscription. However, a lot of effort and time goes into crafting and preparing these articles. If you enjoy the content and find it useful, and if you're in a position to do so, you can become a paid subscriber. In addition to supporting this work, you'll get access to the full archive of articles and some paid-only articles. Thank you!