Module 0: Introduction

  • Why study programming?

  • How can I succeed?

  • How do we solve problems with software?

Why study programming?

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!

How to succeed

Active engagement

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:

Ask questions : In class or labs, in Office Hour or the Help Centre, with friends or with me, via Top Hat or in D2L, if you don’t understand something, ask.

Try things out : When I show you some example code and explain how it works, don’t take my word for it: try it yourself! Try running the same code with different inputs to see if you can predict how it will react. Try finding different solutions to the same problem or to slightly different problems to gauge your own understanding of the material.

Practice, practice, practice!

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.

Work together, work independently

Most students will find that, to help them truly succeed, they need to both work with other students on some things and work alone on others. In this course you will encounter lots of exercises and examples that you should work through, and you may find it helpful to do so with your peers so that you can help each other out as your grow in your understanding of the material. You will also have (at least) one partner with whom you will work on prelab questions, experiments and writing. So, there will be plenty of opportunity to work in groups and in pairs to help you form your ideas about programming and how it’s done.

It’s also a good idea to complete at least some of the exercises by yourself to check that you’re able to think algorithmically yourself, not just when you’re working with others. After you’ve formed your understanding together, checking your understanding individually can help give you confidence that you are building mastery of this material. Assignments must be completed individually.

Solving problems with software

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.

So how about software?

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:

  • a 700 page novel occupies 2.6 MB of disk space,

  • Windows 7 takes about 2.5 GB and

  • Eclipse is about 18 million lines of code.

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.

How do computers work?

We can think of a computer as containing three major functional parts:

  1. a central processing unit (CPU) that executes instructions, one at a time,

  2. some memory (often called Random Access Memory or RAM) that stores information and

  3. some input/output (I/O) devices that allow the CPU to communicate with a user, disks and other computers.

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.

This overall structure is the same for the computer you’re using to read these lecture notes, the Arduino computers that you’ll use in the lab, the computer(s) inside your watch and even the computers that run cars, lighting fixtures, solar panel trackers, etc.! All of these computers have the same structure. What’s different about them is the power of their CPUs, the quantity of their memories and the kinds of I/O devices they have.

CPUs work one step at a time

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:

  1. Let $y = \frac{x}{2}$.

  2. If $2y = x$, $x$ is even.

Note that this is more than just a mathematical formula or equation: it involves a step-by-step approach that may (for many algorithms) be difficult to represent as an equation.

Let’s think about how to find the sum of a set of numbers (say, $S = \{4, 7, 2, 11, 5, 8, 1\}$). We can represent this with a mathematical expression such as $\sum_{i=1}^n S\_{1..n}$, but let’s also think about how we could find the answer to this problem using a step-by-step approach (to be done in class). Determining what type of values we need to remember to use an algorithm is one key aspect of developing algorithms (i.e., of programming).

Real-world algorithms

Here is another algorithm (from the Great British Bake-off’s Mary Barry):

  1. Preheat the oven to 180C/350F/Gas 4.

  2. Grease and line 2 x 20cm/8in sandwich tins: use a piece of baking or silicone paper to rub a little baking spread or butter around the inside of the tins until the sides and base are lightly coated. Line the bottom of the tins with a circle of baking or silicone paper (to do this, draw around the base of the tin onto the paper and cut out).

  3. Break the eggs into a large mixing bowl, then add the sugar, flour, baking powder and baking spread.

  4. Mix everything together until well combined. The easiest way to do this is with an electric hand mixer, but you can use a wooden spoon. Put a damp cloth under your bowl when you’re mixing to stop it moving around. Be careful not to over-mix – as soon as everything is blended you should stop. The finished mixture should be of a soft ‘dropping’ consistency – it should fall off a spoon easily.

  5. Divide the mixture evenly between the tins: this doesn’t need to be exact, but you can weigh the filled tins if you want to check. Use a spatula to remove all of the mixture from the bowl and gently smooth the surface of the cakes.

  6. Place the tins on the middle shelf of the oven and bake for 25 minutes. Don’t be tempted to open the door while they’re cooking, but after 20 minutes do look through the door to check them.

  7. The cakes are done when they’re golden-brown and coming away from the edge of the tins. Press them gently to check – they should be springy to the touch. Remove them from the oven and set aside to cool in their tins for five minutes. Then run a palette or rounded butter knife around the inside edge of the tin and carefully turn the cakes out onto a cooling rack.

  8. To take your cakes out of the tins without leaving a wire rack mark on the top, put the clean tea towel over the tin, put your hand onto the tea towel and turn the tin upside-down. The cake should come out onto your hand and the tea towel – then you can turn it from your hand onto the wire rack.

  9. Set aside to cool completely.

  10. To assemble the cake, place one cake upside down onto a plate and spread it with plenty of jam. If you want to, you can spread over whipped cream too.

  11. Top with the second cake, top-side up. Sprinkle over the caster sugar.

This, too, is a step-by-step approach to solving a problem (in this case, baking a delicious Victoria sponge!).

Another real-world algorithm with an important twist (pardon the pun!) is that of how to change a tire. The twist comes in step 7: repeat. In our lecture, we will attempt to describe the process of rotating tires without using the word "repeat", then show how repetition makes our description of the algorithm much more succinct and understandable. Describing this kind of repetitive activity is a key aspect of programming.

What is software?

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 / 2;
if (2 * y == x)
        cout << x << " is even!" << endl;

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.

In both the Python and C++ examples, a program has to convert the programmer-readable source code into computer-readable machine code for the CPU to execute. In the C++ world, this program is called a compiler; the process of compiling source code into machien code is illustrated in the figure to the right. You will get to get to know the compiler well over the course of, well, this course. You will mostly use programs that let you both edit (work on) source code and run the compiler. Such programs are called integrated development environments (IDEs); I have provided information about getting started with an IDE on the tools page.

What is C++?

Although the goal of the course is to introduce you to the fundamentals of programming, we need a language to practice with. In this course, that language will be C++. C++ is a very useful language because it supports many different ways of thinking about programming and it provides a good foundation from which you can learn other programming languages. However, please remember throughout the course that our goal is to learn about programming in general, not just a particular programming language.

License: CC BY-NC-SA

(c) 2009–2018 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