Hello, and welcome to computational thinking. A course where we will be discussing some problem-solving approaches that we can use to prepare for computer programming, as we use computers to solve different kinds of problems. My name is Chris Quintana and I am an associate professor at the University of Michigan School of Education. Where I work on creating, using and evaluating different kinds of educational technologies. Well, I now work in the School of Education. My background also includes computer science. And before that, I can think back to my first home computer in high school, when I started to teach myself computer programming. So I've been working with in programming computers for a long time. And I'm glad to be part of this course with my colleagues to start talking about how we can use computers for problem-solving. Now in some respects, it may sound a bit strange to be making a big deal about how we can use computers to solve different kinds of problems. But in the big picture, it really hasn't been that long that computers have been helping us solve problems. If we think back to 40 or 50 years ago, computers look like this. They were large, room filling boxes, and they were primarily used by scientists, engineers, the military, and other specialized professions. Well, computers look like this. Most people really didn't need to think about using computers for their everyday activity. In the mid 1980s, we started to see personal computers, which gave more of us access to computing power. Those personal computers then evolved to the laptop computers, many of us use for our work and leisure. Now, we are seeing computers everywhere. And sometimes, we can take it for granted that we are increasingly being surrounded by computers. Of course, we now have smartphones, which are really computers we carry in our pockets. Many of us also now wearing computers, such is the case with smart watches. And the proliferation of computers continues, as we now have other examples like virtual reality equipment that we can wear as headsets that take us to other worlds. And robots of different types, whether they are learning to clean our homes, or even robots that can make cocktails, pastries and cakes. So well, computers were initially used by a small number of people to solve very specialized types of problems. As they became more ubiquitous, we now have a tremendous amount of power at our disposal to solve a variety of problems. But if we want to put computers to use to solve problems in our lives, and if there isn't a ready made piece of software for us to use, we might have to program the computer ourselves in order to help us with our problem-solving. In other words, we have to be able to tell the computer exactly what we want it to do using a very specific language. So as computers are now becoming more widely available, there is an explosion of interest in computer programming. And that's why you might be seeing a lot of courses, resources, books, activities, like hackathons all about computer programming. And that's why we are also seeing many resources available for learning different kinds of programming languages. You might have heard of some of these, like Python, C#, JavaScript, and many others. And so, there is now a bigger conversation about how computer programming is a valuable skill for everyone, as it gives people the opportunities to use computers in a problem-solving capacity more widely. Now here, when we talk about computer programming one way of describing what that means is that a computer program is a very specific set of instructions. Written in a programming language that a computer can interpret so that it can carry out actions that will hopefully give you some output that helps solve your problem. And here is where we use the programming languages I just mentioned to write those specific instructions for the computer. However, while we can write computer programs to solve different kinds of problems, writing the computer program is actually not the first problem-solving step. Before we write the program, we have to engage in some problem-solving practices and thinking to help us set up the approach that we will later implement in the computer program. Programs actually not the first step. I've been describing what we want to do this way. We programmed the computer to help us solve some problem. But actually, we might want to think about the approach in this way. We might have a problem in mind that we want to solve. But before we can write the computer program that can help solve that problem, first, we have to develop a more conceptual approach that describes how we might solve the problem. Then we can implement that conceptual approach using a programming language and submit that to the computer. Now the computer can run the program and give us some output that could help solve our problem, though realistically, many times we might have to address problems with the program we wrote, or maybe there's problems with our conceptual approach. So we might iterate, we might loop through this process a few times. But you can see there is some initial thinking that we have to do before we can start writing the computer program. So as I mentioned, while we're seeing a lot of activity and resources that are focused on the computer programming step, there isn't always as much attention and resources dedicated to helping people think about. Well, the thinking that comes before we write the actual computer program. This is the step where we have to do a lot of thinking about how we approach a potential solution. And how we might identify and gather different types of information and different kinds of data that can help us create this conceptual problem-solving approach. This is the focus of this course and this is what we want to discuss in the upcoming parts of the course. As we discuss the thinking that we do before and as we start writing a computer program, we can use the term computational thinking, which some of you might have heard before. It's a bit of a fluid term, and sometimes you might hear people talk about algorithmic thinking, or even problem-solving in a computational domain. But regardless of the technology that we use, what we are interested in is how do we move towards developing the algorithm or our conceptual problem-solving approach? This isn't necessarily the computer program itself, but you could think of it as a blueprint for the computer program. First, we need to think about developing this blueprint, then we can later implement the blueprint as a computer program using a programming language. If we return to the larger description of our approach, we are going to focus on the first part of this larger process. If we have a problem in mind that we want to solve, what is the conceptual approach that we develop to solve that problem? And as we start moving towards developing that conceptual problem-solving approach, there are some things that we want to think about throughout this process. Have we identified a problem that is solvable with a computer? Can we take the large problem we're working on and break it down into smaller pieces or smaller sub-problems? Can we see familiar patterns or characteristics that can lead us to potential solutions? And can we identify some non-essential aspects of our approach that we might need to ignore in order to get our solution completed? These are the kinds of thinking we want to do, and we can refer to these in more formal terms. Problem identification, problem decomposition, pattern recognition, and abstraction. And now we're going to briefly describe each of these and then we will come back with a small example to see these types of thinking in action. So first, we want to talk about problem identification. Have we identified a problem that is solvable with a computer? Because believe it or not, as powerful as computers are, some problems can't necessarily be solved with a computer. So we want to think about how do we know when a problem is a good candidate for using a computer to generate a solution. And we also want to think about, how we might incorporate different kinds of data to solve this type of problem. So for example, it might be difficult for a computer to help us solve a more subjective problem. Tell me what is the funniest movie I can watch on a Friday night, or the prettiest painting I can hang on my new bedroom wall. These are very subjective, and a computer doesn't always do subjective very well. Now there are techniques in the fields like artificial intelligence that might be widening the types of problems computers can help us with. But when we're thinking about the problem, we just need to make sure that our problem and the data and information that we have available are all actually usable and addressable by computers. So when you're thinking about a problem you want to solve, there's a few things to think about. You want to identify what's the big problem you're trying to solve, and can you state this in some sort of problem statement? Then we can think about whether that problem statement is too broad or too vague, and we'll say a little bit more about that in a second. We also want to think about what kind of information or data do we have available that could help us or contribute to a problem-solving approach? And we want to think about as you're doing that what other information or data might you need to go collect in order to help. And finally there's feasibility, can we solve the problem given what we know? Is it solvable with a computer, and do we have all the resources and information that we need to solve the problem? Next, we have problem decomposition. After we've identified a problem that we think we can solve using a computer, we might want to think about how we can break up or decompose that problem into smaller pieces that are easier to solve. You have a problem statement that you've written. So can you break the big problem down to these smaller sub-problems? If your problem statement is too big, it can be difficult to see how you're going to go about developing a conceptual solution. And that's why we want to think about decomposition because if we can break our large problem down into smaller and smaller sub-problems, we can think about solving those specific sub-problems. And then having these different solutions all contribute to solving the large problem. Solving the smaller pieces can help us arrive at a solution for our original statement. And when we do this, there are variety of ways we can do it. We can use flow charts, we can use a tree structure, or some other graphic organizer to help with this. So for example, we could have a tree structure like this, where we start out with the main problem we want to solve. And then we want to see if we can break that problem down into some number of sub-problems. And then we can look at the sub-problems and see, are those still too big? And we might want to break those down like sub-problem 2 here into some smaller sub-problems to help address that one. And we keep breaking problems down into smaller pieces so that we have a set of more easily solvable pieces that contribute to the main solution. Next, we can think about pattern recognition. And here what we want to do is think about whether we see some familiar patterns or we see some familiar characteristics in our problems that can lead us to potential solutions. Finding similarities, finding some problems that are similar to this that we have solved in the past, or maybe finding some patterns that are familiar to us can help us solve the smaller decompose problems more efficiently. And so here what you want to think about is, have you seen solutions to similar problems that you could use here? Or can you think of similar problems that have been solved before that can help you address these problems? You might also want to think about how is this problem the same or different from other problems you've identified or addressed in the past? And can you use those similarities to help arrive at a solution? We also then have abstraction and with abstraction, you can think about it in this way. We're trying to identify non-essential aspects of our problem that we might be able to ignore because they're actually distracting us or serving as a detour from a solution to our main problem. So sometimes we have to filter out or ignore parts of the problem, or some of the patterns we may have identified. So that we can concentrate on the necessary aspects of the problem we're trying to solve. And so here, you want to think about asking whether some parts of the problem you're solving are actually less relevant to a successful outcome. Are there any extraneous elements of the problem that are distracting and aren't really as important as we may have thought at the beginning? When we can identify instances of these unnecessary extraneous aspects or if we have too many components of a problem that we're trying to solve, it's going to lead to situations where we're actually just trying to do too much. And this can interfere with arriving at an effective problem solution.