21
$\begingroup$

This is a question for those of you who have an intro class before AP Computer Science (or maybe even just an intro class). What order do you teach the topics in your intro class? I start with if statements, then go in the following order:

  • While Loops
  • Variables (I do some hand-waving with variables before this point)
  • For Loops
  • Arrays
  • OOP

I used to start with variables a few years ago, but students seemed to have trouble getting the concept that early in the course. I'm not sure if I should go back to that now that I have more teaching experience and have a better idea of how to teach variables.

$\endgroup$
13
  • 7
    $\begingroup$ What about functions and procedures. $\endgroup$ Jul 20, 2017 at 17:43
  • 2
    $\begingroup$ Also consider using Objects as easier (to be done before) creating objects. $\endgroup$ Jul 20, 2017 at 17:58
  • 2
    $\begingroup$ @richard : In real computer hardware, functions, and non-mutating variables as computation results don't exist. The program counter jumps, and state bits mutate. Why jump to an abstraction so early? $\endgroup$
    – hotpaw2
    Jul 20, 2017 at 19:51
  • 2
    $\begingroup$ I thought it was interesting that the CodeHS curriculum for AP CS A started with Karel language, commanding a dog character to navigate various obstacles. There's a trend in K-12 CS education to develop computational thinking skills, independent of programming languages. Computational thinking skill can be developed without the use of computers. On that note, csunplugged.org is a great supplemental resource that can add some variety to class and make it more interesting for everyone. $\endgroup$
    – ThisClark
    Jul 22, 2017 at 4:17
  • 2
    $\begingroup$ Related: The order of subjects in beginner's curriculum $\endgroup$
    – TuringTux
    Jul 24, 2017 at 18:39

8 Answers 8

11
$\begingroup$

I think this depends entirely on the programming language you use. Or maybe more accurately, you should choose a language that allows you to introduce the concepts in the order you want.

I would use a language called Processing, which is built on top of Java and allows you to create visual, animated programs without any boilerplate code.

I'd start with calling functions. Here's an entire Processing program:

ellipse(20, 30, 40, 50);

This program shows a window and draws a 40x50 oval at coordinates 20,30. There are other functions in Processing. Have the students draw a basic scene.

Then I'd talk about using variables. Processing has a few predefined variables that come in handy:

size(500, 500);
ellipse(width/2, height/2, 200, 200);

This program creates a 500x500 window and shows a circle in the middle of it. Have the students modify their scenes so they stretch to fit the screen, using the width and height variables.

Then I'd talk about creating variables. Have students create their own variables that allow them to move their scene around, or easily change the color, etc.

Then comes creating functions. Here's an example program:

void setup(){
   size(500, 500);
}

void draw(){
   ellipse(mouseX, mouseY, 25, 25);
}

This program shows a window that draws a circle wherever the mouse is, 60 times per second.

Hopefully this gives you an idea of Processing and the general approach. From here I'd cover these topics:

  • Debugging
  • If Statements
  • Animation
  • For Loops
  • Arrays
  • User Input
  • Using Objects
  • Creating Classes
  • ArrayLists
  • Images
  • Libraries
  • Deploying your code

Shameless self-promotion: I've put together a series of tutorials that cover all of these topics, available at HappyCoding.io. I'd be happy to help adapt these tutorials into an introductory curriculum.

$\endgroup$
14
  • $\begingroup$ setup and draw are procedures not functions (though C and its derivative incorrectly call them functions). $\endgroup$ Jul 20, 2017 at 18:39
  • 2
    $\begingroup$ @richard In an introductory course, the distinction does not matter. (I would go a step further and say the distinction doesn't matter in real life either, but I digress.) Processing calls these functions, so they're functions in Processing. In more advanced courses you can make a distinction between procedures and functions, but at an introductory level "functions tell the computer to do stuff" is about all you should be saying. $\endgroup$ Jul 20, 2017 at 18:42
  • 1
    $\begingroup$ The importance of the distinction between function and procedures is that if we make the distinction, then they have the same meaning as in real life: functions as in maths, procedures as in follow the correct procedure. The other importance is in which one we teach first. $\endgroup$ Jul 20, 2017 at 18:51
  • 3
    $\begingroup$ @richard I guess I'll respectfully disagree with you here. At no point in my career have I needed to stop and remember whether I was writing a function or a procedure. So I wouldn't recommend spending any time making the distinction in an intro course, where students are already going to be inundated with new information. Maybe you just teach a different kind of course than I would. :p $\endgroup$ Jul 20, 2017 at 19:00
  • 2
    $\begingroup$ +1 to its depending on the programming language. The rest of your answer is good too. :-) $\endgroup$ Jul 22, 2017 at 0:15
10
$\begingroup$

I'm self-taught, but here are my thoughts.

0. Language

I learned using a combination of Python (once I started to get more serious about programming, I actually don't remember how I stumbled across it) and JavaScript. Consequently, I have good indentation habits, and I haven't had to worry about problems you do have to worry about with some lower level languages. It also allows you to dabble in OOP but also not if you don't want to, which is also nice. Here's the general order of events for me, as best as I can remember it.

1. Motivation

Drawing shapes in JavaScript, printing things in Python, all stuck out to me as "whoa, cool" moments that made me want to keep going. I also saw cool projects that others had made on Khan Academy, where I started learning. It was exciting, and I wanted to be able to do all the stuff that the other users did.

2. Printing

This is almost step -1, but just thought I'd point it out here. This is also useful for the next thing.

3. Variables

Here, you can progress from

print("Hello, World!")

to

print_this = "Hello, World!"
print(print_this)

I learned using the classic buckets analogy - when you define a variable, you put something in a bucket that's labelled whatever you name the variable. When you call the variable elsewhere, the computer looks for the name, and grabs whatever's inside the bucket.

4. if statements

This again builds off the previous concept - for example, you might do

print_this = "Hello, World!"
do_i_print = True
if do_i_print == True: #this can also be written as 'if do_i_print:'
    print(print_this)
else:
    print("Nobody's home!")

Project 1

All learning is more fun when it's motivated by something. With the information students have learned so far, they can now create a choose-your-own-adventure story with the introduction of one simple built-in in python - input(). For example, a very simple one might be:

first_choice = input("Your sister is missing when you wake up. Do you go to the kitchen to eat first, or go straight out to the barn to check if she's there? Input 'barn' or 'kitchen': ")
if first_choice = 'barn':
    print("You found your sister!")
elif first_choice = 'kitchen':
    print("Your mom scolds you for being a glutton and sends you to do your chores. Maybe you can find your sister later.")

You might also introduce basic input sanitization, and tell them this is what working programmers have to consider.

5. Numbers/math

Previously, you've used strings in the variables. Now, generalize to other types of variables - numbers, which can be whole or with decimals (integers and floats), lists, etc. Starting with numbers, you can then teach math operations (this'll become useful in a couple of steps). For example:

my_num = 5
print(my_num**2)

6. Functions

You can now generalize the previous step -

a = 5
b = 2

def multiply(a, b):
    return a*b

multiply(a, b)

Project 2

Now, a bigger project, and one they'll really enjoy (or at least, nerdy me did). If this is early highschool or middle school, they'll appreciate a program to solve quadratic equations for them. (I can provide my own, probably overly long solution if you want. Provide bonus points if they get their program to accommodate imaginary numbers. Hint: it has to do with the difference between the square root functions in math and cmath.)

7. More types - lists and dictionaries

Lists can be fun for later projects. Lists should probably be explained first, and then dictionaries.

8. while loops

Here, we can do something to all the elements in a list, which flows nicely into 9 and 10.

classmates = ['Bob', 'Jerry', 'Joe', 'Anna', 'Joan', 'Teresa']
ages = []
counter = 0
while counter < len(classmates):
    student = classmates[counter]
    print(student)
    age = input("What is the age of " + student + "?")
    ages.append(age)
    counter+=1

Rather a poor example, because that really should be a dictionary, but then you could I suppose do dict(zip(classmates, ages)) - either way, it's a poor scheme. I'll try to replace it if I think up something better. Anyway.

9. for and foreach loops

Now, this gets shorter. For loops progress from while loops:

classmates = ['Bob', 'Jerry', 'Joe', 'Anna', 'Joan', 'Teresa']
ages = []
for(i = 0; i < len(classmates); i++):
    student = classmates[i]
    print(student)
    age = input("What is the age of " + student + "?")
    ages.append(age)

Or, you could just do

classmates = ['Bob', 'Jerry', 'Joe', 'Anna', 'Joan', 'Teresa']
ages = []
for student in classmates:
     print(student)
     age = input("What is the age of " + student + "?")
     ages.append(age)

Project 3

And now, another project! This one you can do something in the lines of codecademy's python project - using functions, dictionaries, lists, math, etc - to build a project.

10. OOP

I don't think I understand/have used OOP enough to suggest analogies/etc, but I do suggest introducing it last along with an accompanying project.

Project 4

OOP focused project.

11. Exploration

From here, perhaps let them explore. One kid might be excited for robotics, another, for the theoretical stuff, another, for scientific programming, another, game programming. Perhaps an ideal method: a unit on programming to control peripherals, using, say, the arduino, a unit on some theoretical stuff - logic gates, truth tables, and so forth, and a unit on specific programming applications - GUIs, game programming, scientific programming, websites - and allowing students to dabble in all of these.

$\endgroup$
4
  • 3
    $\begingroup$ Why while before for? A for loop (the Python-like version with in, not the C-like version) seems simpler to me: you know in advance how many iterations there are, and it can be introduced simply as a shortcut to write many similar lines. While loops usually rely on complex, mutating state. $\endgroup$ Jul 21, 2017 at 17:03
  • $\begingroup$ This is basically what I was taught in my first college course. For loops before while loops though. Python was a great learning tool, and we used turtles to draw for the "Whoa, cool" moment. $\endgroup$ Jul 21, 2017 at 18:57
  • $\begingroup$ @FedericoPoloni I find for loops a condensed version of while loops - see for example this answer and the others to that question. The Python version of a while loop, the for each loop, is nice, but it's better to know what that syntax really means, and the for each is basically a condensed while loop. $\endgroup$
    – auden
    Jul 21, 2017 at 20:22
  • $\begingroup$ My self-teaching experience in 9th grade was the same, I came up with more and more ambitious ways to make shapes on the terminal screen with asterisks, using BASIC. $\endgroup$
    – user737
    Jul 22, 2017 at 16:42
6
$\begingroup$

In Structure and Interpretation of Computer Programs (SICP) (a book, video series, and university course), they do not cover variable mutation until around half way. They covered what seemed like everything I know before this. Including functions (not procedures) and object orientation.

My thought are that these partial sequences makes sense:

statements → sequences → functions → parametrised functions → just about everything else → variable mutation

infinite loops → bounded loops for each → unbounded loops for(int i=0; i<10; i++) (while this is bounded, the construct is unbounded).

non-mutating variables (possibly function parameters) → selection

If these partial sequences are correct (work), then they need to be interleaved to make a sequence.

SICP may do it a bit different, so worth a look.

$\endgroup$
5
  • 1
    $\begingroup$ I think that in SICP they would much rather not have included explicit state (variables) at all, but then decided that Functional Programming wasn't the entire world. Sadly. An somewhere, optimization of programs would, perhaps, need to be done. ;-) $\endgroup$
    – Buffy
    Jul 20, 2017 at 18:05
  • $\begingroup$ @Buffy they had to do mutation, because without it a random-number function is a complete mess. A random number function is not a function, it has internal state (if you have mutation). With out mutation, you end up with a pure function, now the only place for the state is in the stack, this breaks modularity as now the user of the function is keeping the state and it is well ugly. In most other cases it is best to avoid mutation; It is more elegant without it. Secondly a functional language with lambdas, can just go and implement mutation, and banning lambdas would be a big mistake. $\endgroup$ Jul 20, 2017 at 18:30
  • 1
    $\begingroup$ @nocomprende variables are not a problem, mutation is a problem (mostly see comment to buffy). If you avoid ever reusing a variable then your code will be more elegant, easier to read, easier to optimise, less buggy … The only place where this is impossible is in loop counters. This is why scheme uses recursion. However sometimes it is better to use mutation (but not much). Programs should be 80% to 90% functional, and mutation should be encapsulated. $\endgroup$ Jul 20, 2017 at 18:35
  • $\begingroup$ @nocomprende I can't remember when they covered domain specific languages in SICP, probably before mutation. They use scheme (the language that they are teaching in), to define the language, all but the lexer. Then they wrote the lexer in scheme. All functional. — the real power of functional is that it will make you program better in other languages. $\endgroup$ Jul 20, 2017 at 18:46
  • 1
    $\begingroup$ @richard, actually I would say that variables (explicit capture of state for later testing especially) is a problem. But this isn't the place for such a discussion. Why "remember" something for later action, if you can capture the action itself (either in an object (OOP) or an expression (Functional). Your background leads you to a different conclusion than mine, of course. $\endgroup$
    – Buffy
    Jul 20, 2017 at 18:48
4
$\begingroup$

I am of the school of thinking that starting at an abstract level causes too many students to consider computation as inscrutable magic. And that can lead to broken mental models and buggy ideas about how to code stuff.

A 1970's vintage UC Berkeley Intro to Computing course (for non-EECS majors) used a cardboard computer with pencil-and-eraser-mutable memory cells ( https://en.wikipedia.org/wiki/CARDboard_Illustrative_Aid_to_Computation ). The professor also talked about physical adding machines (maybe Pascaline or abacus equivalents) before diving into coding in an HLL. Programming became something that controlled a visualizable machine, not math that became transmuted by magic incantations.

I would start there (at a very non-abstract level), and then show how modern HLL's make it so much easier to solve higher level problems.

$\endgroup$
1
3
$\begingroup$

My answer, for the past 20 years is

  • OOP - but primarily as enabling composition, not inheritance. The notion of a class as a "bundle of behavior". Inheritance via interfaces, not classes, or the equivalent when not in a statically typed language.
  • reference variables (no primitive data)
  • Some design patterns to reinforce good OOP thinking (Strategy especially)
  • problem solving ......
  • collections (list, set, ...) Not ALL collections, just enough.
  • selection
  • recursion if I can manage it.
  • looping - while before for, but iterators before all.
  • recursion here if not earlier
  • .....
  • primitive data (int, char, ...)
  • arrays

The focus is on design and on building things, not mathematical puzzles. This needs a graphical system in which to work. Greenfoot is a good UI for this.

Also. Classes should be simple and methods (very) short and very simple. At statement number 5 in a method I start to itch. Put the complexity into the interactions between objects, not in the methods of the class. This may be the most transformational message of all, here. Another way to think of it is to capture "state" in the program counter, not in fields and variables - the "state of the computation", not in explicitly "remembered" values.

Note that this "mind set" is radically different from that of a C or even (the typical) C++ programmer. It is as radical as the mindset of a functional programmer.

$\endgroup$
11
  • $\begingroup$ Yes, I understand and agree. But we would likely still disagree. $\endgroup$
    – Buffy
    Jul 20, 2017 at 18:44
  • $\begingroup$ @nocomprende top down or bottom up: what we are trying to do first, or how it is done first: human first or machine first. $\endgroup$ Jul 20, 2017 at 18:56
  • 2
    $\begingroup$ @Richard You are missing the point. The number that is shown on the calculator display is stored in a variable. And if you insist that calculators should have a reverse polish interface because that satisfies your prejudices about the one and only way to design software properly, IMO your whole philosophy is bass ackwards so far as real world computer system design is concerned. $\endgroup$
    – alephzero
    Jul 21, 2017 at 5:40
  • 1
    $\begingroup$ @Richard : If a calculator seems to do either RPN or BODMAS, it is just an illusion. There are registers connected to an ALU actually doing the real grunt work. Kids have built simple calculators out of Lego's. That's a real (and realizable) foundation. $\endgroup$
    – hotpaw2
    Jul 21, 2017 at 23:09
  • 2
    $\begingroup$ Is the goal of Intro to CS to create users of interfaces? Or start kids on the path to becoming competent computer scientists, programmers, and software engineers who really understand how to make stuff that works? $\endgroup$
    – hotpaw2
    Jul 21, 2017 at 23:31
2
$\begingroup$

Here is my recipe.

  1. Begin with the language's type system. If the language has a REPL, use it.
  2. Introduce variables. Indicate if variables have type (statically-compiled languages) or if they are typeless names (a la Python).
  3. Introduce the idea of object (state/identity/behavior). Objects are smart data and they can do work for you. Have the students manipulate the fundamental types of objects in the REPL. At this juncture, all programs are "boring" because they run their lines in seriatum
  4. It's time to divide the world into two types of statements, worker statements and boss statements.
    Worker statements are imperative statements with the tacit subject "computer." Boss statements "own" chunks of code. They are grammatically incomplete sentences. They alter the flow of execution in a program.
  5. It's time for the first boss statement, the function. Explain how computing functions differ from mathematical ones. Make sure you do a careful explanation of mathematical functions and show examples (such as string length) of mathematical functions that occur often in computing.
  6. Time for three more boss statements: if, elif/else if, and else.
  7. A little recursion please, before we break out loops.
  8. Iteration: indefinite (while) and definite(for) loops. This opens the door to fileIO.
  9. Creating custom objects using classes and OO.
$\endgroup$
2
  • $\begingroup$ This is quite an interesting and different ordering than I'm used to. I assume that recursion (and functions in general) don't entirely "stick" yet, but must be revisited later. Is this impression correct? If so, this is an excellent ordering to begin a nice spiral through introductory programming. $\endgroup$
    – Ben I.
    Dec 4, 2020 at 23:36
  • $\begingroup$ Functions come first. They are a key way of avoiding "repeating yourself." Remembering a procedure under a name is key. $\endgroup$ Dec 7, 2020 at 1:06
1
$\begingroup$

In touch of class — Bertrand Meyer, He start with the big stuff: object orientation, working programs. And then breaks it down toward the detail. So an top down approach, as opposed to the often seen bottom up.

e.g. bounded loops (foreach) before unbounded loops (and how to implement bounded loops using unbounded once).

Using objects before creating them.

I can not see how to teach by starting with explaining each of the bricks, before teaching how to but the bricks together. I think it is better to explain what a house is, and then break it down, to explain how to make one, and as you do this explain the properties of the bricks.

$\endgroup$
2
  • 1
    $\begingroup$ To support "using objects before creating them" start with an already built framework that the students work within, so that the most "primitive" thing they see is an object with behavior and that can interact with others. You build this, or find one, and the students extend it. Karel J Robot is an example of this way of thinking. Unfortunately it overuses inheritance a bit so needs to be used with some care and thought. $\endgroup$
    – Buffy
    Jul 20, 2017 at 18:58
  • 1
    $\begingroup$ To explain houses from bricks, I like using a historical approach. Show them an abacus, human computers with mechanical adders, Baggage engine, core memory big enough to see each bit. Throw in some stories about Ada, Turing, Shannon, and Hopper (the recent movie "Hidden Figures") to keep them interested. Humans made lots of bricks way before learning to make beautiful cathedrals. Teaching engineering and science is a bit different from teaching Art appreciation. $\endgroup$
    – hotpaw2
    Jul 22, 2017 at 17:25
1
$\begingroup$

I feel like "loops", "variables", "conditionals", etc is a pretty loose distinction. For example, even that technically eternal loop is just a an example of while loop, mentally it is a much much bigger thing, completely different. Or, another example, temporary variable is mentally different from initial or result variables.

What makes it worse, "conditionals" are simple to define, but vastly increase possible ways to write a program. Like:

  • without loops and conditionals you can write programs, though those look simple (slightly more interesting if events are already introduced)
  • with loops (but without conditionals) you can write repetetive programs, a big class of programs. For example, you can now compute $\pi$
  • with conditionals (but without loops) you can't write much sensible programs. Even if you write one, it doesn't look fun
  • with both loops and conditionals program space EXPLODES, however, beginner can't see that this explosion is zillion times larger than what was before.

FWIW, is to introduce "incomplete" concepts, kinda "cliff-hangers". The eternal loop allows you to iterate things. Uh-oh, that you can't use to bound iterations, otherwise you could do X1, X2, X3, X4, .... (here students have to feel that "uh-oh"). Next lesson: Hang on, but we actually can do bounded iteration! (introduce for loop, students should recall which things they should be able to implement now).

Cliffhanger stuff (know ahead stuff you have no way doing at this point of learning) is underestimated in education.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.