Computer programming gives us a helpful way of solving problems, not to mention a structured way of thinking about problems and solutions. Every engineer should be able to express solutions to certain classes of problems using algorithms (structured, step-by-step solutions to problems). Many first-year Engineering students think this is the last they’ll hear of programming, but Statistics begs to differ, as does Fluid Dynamics, as does seismic analysis… even effective use of spreadsheets is greatly helped by some fundamental understanding of programming. And, of course, good software designers are always in demand in the job market!
Even if you don’t write much software in your career, we live in a digital world that cannot be mastered without some understanding of the way computers work. Engineers use computers in lots of ways, whether we put computers into the systems we just use computer software to help us design things. Engineers are responsible for their use of computers: you can’t blame your tools for faulty design! “My software gave me the wrong answer” is no better an excuse than “my calculator is broken”, so we need to understand how to gain confidence that software is working correctly.
Finally, whether or not you currently believe it, I hope to show you this term that programming can be fun!
A good way to underperform in this course is to come to lectures, passively consume them, only do the things you are explicitly told to do and let you lab partner do things without your understanding. The value you get out of this course will be proportional to the effort you put in to explore and understand the material. Specifically, it is helpful to:
Software design and development, like other kinds of Engineering design, blends both science and art. I will teach you things about designing software-based solutions to problems, but you can’t really say you’ve learned design unless you practice designing. This is much like learning to play a musical instrument, you need to learn some theory, but you also need to practice. The Tools page provides details on how to get set up with software tools for writing, compiling and testing C++ code. Please take a look at this page and make sure that you are comfortable with at least one of these tools during the first week of lectures.
Like every other engineering discipline, software engineering is about designing solutions to complex problems. When problems get complex, one valuable strategy employed by engineers is divide and conquer. Designing a modern aircraft is a complex problem, too complex for one person to do by themselves, but if one team can design the engines, another team can design the wings, another team the avionics, etc., then we might just be able to get somewhere! Of course, each of these individual components is themselves a complex system that needs to be broken into smaller design tasks, which themselves might be broken down again and so on until we arrive at manageable-sized problems, things that an individual engineer or team of engineers can design appropriate solutions to.
We use software to address incredibly complex problems, from building self-driving cars (or self-driving submarines, as some folks do here at Memorial) to training ship’s crews to securing networks against hackers (as in my own research). In fact, computer programs are among the most complex artifacts ever built. Consider that:
How do we design solutions to these problems? In the same way as the other disciplines we described: by breaking problems down into parts until the parts are small enough to solve. Once we have small modules that address particular aspects of the problem, we can put them together into a hierarchy of ever-more-complex modules to build up the whole system. This requires an understanding of the problems themselves, but it also requires an understanding of our basic building blocks, i.e., how computers work at the lowest levels.
We can think of a computer as containing three major functional parts:
These three functional components allow the computer to compute, to remember and to communicate. There are lots of other things inside of a modern computer, but they all exist to serve and facilitate these main tasks.
The CPU is the brain of the computer, and we will spend most of our time thinking about how it does its work (later courses in programming, microprocessors and data structures spend more time on these). The key thing to keep in mind is that a CPU follows instructions, and it does this one step at a time. Such a set of step-by-step instructions for accomplishing a task is called an algorithm. Here’s an example of an algorithm that tests whether a number $x$ is even:
Here is another, slightly more sophisticated algorithm (from the Great British Bake-off’s Mary Barry):
Software, whether written in C++, Java, Python or another programming language, is a way of describing algorithms to a computer. Consider the following implementations of the algorithm from above that checks whether or not a number is even. Here’s one implementation written in the Python programming language:
y = x / 2 if (2 * y == x): print(x, 'is even!')
Here is the same algorithm implemented in C++:
int y = x; if (2 * y == x) cout << x << " is even!" << endl;
We will spend most of our time in this course using C++. You should note that these two code snippets look a bit different, as the details of the two programming languages are different, but the fundamentals of algorithms are the same.
To the right is a block diagram of the 3pi robot that you will use in the lab: This robot, although very different from a “normal” desktop or laptop computer, has the same key components: a CPU, some memory and some I/O devices. Instead of a mouse, keyboard or hard drive, however, the 3pi robot has sensors, a little LCD display, some buttons and two motor controllers to make the 3pi drive around.
In fact, the computer in the lab, the computer on your 3pi robot, the computer that monitors sensors in a car and the computer that makes a smart watch work all have this same structure. What’s different about them is the power of their CPUs, the quantity of their memories and the kind of I/O devices they have.
(c) 2009–2016 Michael Bruce-Lockhart, Theo Norvell, Dennis Peters and Jonathan Anderson. Licensed under a Creative Commons Attribution–Noncommercial–Share-Alike 2.5 Canada License. Permissions beyond the scope of this license may be available at theteachingmachine.org.