Computational Thinking: Using CT Practically
This page is a work under construction…so be careful with it…
Now that we have learned the ADPDA foundations of computational thinking, now what do we do with it? Mainly, two things:
- We use it as a framework to understand problems, domains, and concepts around us, and
- We use it to help devise a computer-based solution to something.
In other words, computational thinking helps us understand something, and helps us begin the process of programming a computer to be applied to that something.
Let’s take each of these one at a time.
Computational Thinking to Understand a Problem or Domain
Remember at the beginning of the CT Data Representation page we said that thinking about the data is more important than thinking about the code – so to begin to understand a problem, think about the things in it. Other non-CS ideas align with this – for example, conceptual modeling (and you can web search to find many other links; I also have another in-depth page on domain modeling).
A good place to start is:
- Brainstorm and write down all the nouns that are used when talking about or describing the problem (or domain);
- Then pull out the most important ones – just a handful, probably 3-10 of them; we will call these entities;
- For each entity, brainstorm and list the information needed about each one of those; these are its attributes; some of the less important nouns that you originally listed may now be some of these attributes of more important entities – the word has often indicates an attribute of an entity, such as “a person has a name” (name is an attribute of the entity person).
The next step is to identify relations between entities:
- Brainstorm and list relationships between entities; these will often be verbs such as uses, has, and is part of, but will also be specific verbs related to the problem; for example, “an instructor teaches a course” describes the “teaches” relationship between the instructor and course entities.
- Figure out the cardinality of those relationships: how many entities of each side are involved? For example, an instructor teaches multiple courses, but each course only has one instructor (usually, but exceptions matter!)
The steps above involve abstraction (identifying relevant concepts and their attributes, ignoring irrelevant ones), pattern recognition (relationships, common attributes), and data representation.
Now that we have a good understanding of the conceptual things in our problem, now we should think about the processes, activity, or actions that happen in it.
Remember, at this point we are only trying to understand the problem, not come up with a computer solution, so we focus on workflow and processing that is inherent in the problem. In this, we think about how the entities are used in the problem domain. Some of this involves recognizing and describing common usage patterns.
For example, in a grocery store, the items a shopper is going to purchase need to be identified, the price and quantity of each need recorded, we need to add up all of the individual prices into a total, we need to know which items can be taxed and which not, and we need to calculate the tax and add it to the total; we may also need to apply coupons or other discounts. This needs to be done in a store regardless of whether it is on paper or on a computer.
At this stage we should try to list out these processes, and name them (at least with a short descriptive title). This involves decomposition and abstraction. Some of the processing pieces may be complex enough that we should describe them with flowcharts (see the algorithms page).
Computational Thinking to Help Build Software
The first step in creating software should always be understanding the problem – so hopefully by this point we have done all of the stuff in the previous section. If not, we should go back and do it…
Then we have to start making decisions on how to bring all of that into software, into real code. The first step is probably to decide what programming language we are going to use, and what features of it we will use. Different languages will have different features that might help support us, and different programmers know how to use those features at different levels of capability. Whereever you are in your programming ability, you need to use what you know, and perhaps try to learn some new things each time you create a program.
As before, the best place to start is with your data representation. In many modern object-oriented programming languages, the entities you identified in your understanding of the problem should probably become objects, and their type become a class. Even with OOP, you still have to decide how to represent your entities and their attributes, as arrays, tuples, lists, integers, strings, or whatever.
So first, think about the data that will be in your program, and what it will look like. This also involves abstraction, decomposition, and pattern recognition.
Next, you should decide how you are going to embody the workflows and processing that is in your problem in your software. This will involve decomposing them into functions, with names and then deciding where those functions should be – in an object-oriented setting, this means in which class they are, or better yet, what objects have which processing responsibilities. Even in a non-OO programming language, you still have to decompose your processing into functions, and figure out how to pass data in between those functions. Try to avoid global data!
But There’s More to Software…
Now you have to put it all together – this means you have to write code that just manages the application and reads in data and creates output and all that fun stuff. This is code that is not directly embodying the problem domain’s workflow and processing, but that is just managing and running the software. All of this code also needs designed, decomposed, abstracted, and may have internal data that needs represented.
So really, there are two parts to creating software: making the problem logic and problem data part – this is the part that puts your problem into a computer solution – and then there is the part that just manages the computer and the application and glues it all together.
That second part can often be the biggest part! This includes reading data in, creating a user interface and operating it, creating output data, and many other things.
Actually, a good practice is to design your user interface (UI) first, before you begin coding all the other parts (even the problem logic). Then do pretend walkthroughs of using your application through your UI design, and see if it works well. If not, fix it and repeat. Then once you have a good handle on the UI, build the program that will be behind it and make everything work.
Finally, You Should Test, Test, Test
Making sure your application works involves lots of testing. Don’t skip this and make the users hate your application because it has lots of bugs. If you want to have users actually like your application, do lots of testing and other forms of quality assurance.