A basis of a vector space is a set of vectors in that space that can be used as coordinates for it. [1]

I just read Dan Meyer‘s quick review of the Graspable Math tool. While I did briefly investigate Graspable Math, and also glanced at Desmos, the tool where Dan is head of teaching, what really struck me was how Dan’s writing shows him to be “on the inside” of math teaching and learning. As I am too. That is, there’s a room called “math”, both of us are inside it, and we’re familiar with the rules of the game.

As I love computer programming and am always looking for new ways to teach it, the question arose in my mind: what is the minimal set of constructs to teach students so that they can take off from there and learn the rest of computer programming, in any language, pretty much by themselves?

I did a quick search for “minimal constructs of programming” and found Software Design & Development: Programming Constructs (pdf) from The High School of Dundee in Scotland. Nice and clear, but according to the table of contents, roughly 30 topics. That feels like too many to be minimal.

When faced with the question of how to teach, I usually first turn back to myself – how do I learn? That answer is not likely to be the best or complete answer, because most students are not me. (A valuable lesson for teachers, that I struggle to keep in mind!) But it’s an OK start, and often it’s all I have.

When I learn a new programming language, what constructs do I look for?

Variables (scalars, vectors; and assignment – same “=” sign means something very different from math)

Operators (may look very different in, say, Python vs APL vs AWK)

Conditionals

Loops

Input/Output

Functions (could be an intermediate level topic, but so important for clear code that I put it here)

How to run (both in editor and from command line — so “command line” is a concept too)

How to interact with the program (where do I put input? where do I see output?)

The absolute minimum count of the above is 10 topics. Is that the minimum? Is that the right set? And, is it a set of topics where each one makes sense to a student who is new to computer programming? That last one is so important because (as above), my students are not me.

Thus, towards a second draft of the list, and maybe some hints to what kinds of explanations, exercises, and even learning-support tools (like the math environments mentioned at the beginning of this post, only for computer programming), I want to consider the question in some new ways. Based less on how I learn computer programming, and more on how people, even children, learn things from each other:

If computer programming were an outdoor game played at recess, and I were ten years old, how would I teach my friends the rules of the game?

Declaring the end from the beginning, and from ancient times things that are not yet done; saying: ‘My counsel shall stand, and all My pleasure will I do’

(Isaiah 46:10)

In elementary school we learned about numbers as if they were only for counting and calculating, skipping right over all the beauty of numbers and their meaning. So I was happy to have this “Calculator Puzzle” brought to my attention via a Twitter post. Not just for the mental exercise, but for the insights it brought about different parts of math (calculation, algebra, and geometry) to name a few, and about how my mind progresses from problem to solution. Definitely not by a straight line. But also not by a random walk.

Spolier Alert:
If you want to try to solve the problems yourself, do NOT read this post, nor my replies on the Twitter thread!

That said, here was my thought process:

Background

calculator is not working properly. Only the add and reciprocal buttons work, as well as the numbers 0-9.

Well that was interesting. Reciprocal is not a key that I often use on a calculator.

Question 1

Can you work out how to halve any number?

I admit, my first reaction, and the one I went with, was to try a specific example first. And, as above in Isaiah, to “declare the end from the beginning”.

Say, half of 5. That would be 5/2.

How could I get from “5” and “half” to 5/2, with only “+” and “1/x”?

Impressed by the unusual button — reciprocal — I immediately asked: could I get 2/5?

Well, yes. 1/5 + 1/5 is 2/5.

That was it: 5, 1/x, +, 5, 1/x, = would give 2/5. Another press on 1/x would give 5/2. Q.E.D.

Insight 1a*

Better than solving the problem, though, is that as an electrical engineer, I felt a sense of “coming home”. I hadn’t seen it at first, but this was “reciprocal of the sum of the reciprocals”. Well known as the resistance of a set of resistors in parallel. So it would certainly work for every case, because two equal resistors is two equal paths instead of one, offering half the resistance. Whether you feel that math or electricity is the original depends on whether you’re a mathematician or an engineer.

* Where’s 1b?? You’ll have to wait for that. I did.

Question 2

Now the subtract button has started working.

I think this means I can now square any number – can you work out how?

Back to my specific example. 5. 5 squared is 25. No way I would get directly to 25, but now that I was friends with that reciprocal button, I sought 1/25.

After a few minutes of that, I realized that I would have to use the “-” button. Surely it was working (in the problem) for a reason.

1/25 is pretty small. I would get it by subtracting fractions (which I could generate with the 1/x button). But I couldn’t think of any fractions to subtract, certainly not with a numerator of 1, that would yield 1/25. I did realize that fractions with denominators close to each other would yield significantly smaller fractions. How about 1/4 – 1/5 = 1/20. OK, 1/20 was not 1/25, but maybe I could fix it up. 1/20 would yield 20 (after pressing 1/x). Then simple enough to add 5 and get to 25.

Why is 1/4 – 1/5 = 1/20? What’s special there? Suddenly, though I had never seen it written down, I thought: “Consecutive integers are relatively prime.” Then I looked that up to be sure. I read some proof discussions, and then left off that to continue the problem.

Question 3

Now, I think I can also calculate the product of any number. How?

Here, I was onto the power of algebra to solve problems “automatically”. Instead of one number n, I would have two numbers x and y. I asked myself what product expressions involving x and y I was familiar with. The product (x+y)(x-y) came to mind. In high school it always seemed nice because it produced a sum of squares “cleanly” with no annoying middle term in xy. But here, I realized, “xy” was just what I was looking for. So the product would be the “messier” one: (x+y)(x+y). Which, by the way, is (x+y)^2. Aha! Is this is why the problem author tried to take me by the hand from square to product?

Anyway, (x+y)(x+y) = x^2 + 2xy + y^2. That could be solved for xy:

xy = ((x+y)(x+y)-(x^2 + y^2))/2.

Insight 3

I like geometrical interpretations more than, or at least in addition to, purely algebraic interpretations. Even if algebra works, I feel better seeing a picture too. So I went back and asked myself what picture matched that equation. Here it is (freehand drawing):

Insight 1b

Now, even though I had solved question 1 without any algebraic symbols, I challenged myself to find a geometric interpretation for the reciprocal of the sum of the reciprocals, with two equal numbers yielding a half.

One geometric interpretation of reciprocal is the (negative of the) slope of the perpendicular. With that in mind, the picture came pretty quickly:

Question 4

Are there any other operations I can do with only add, subtract and reciprocal?

I left this for when I find more time. Or maybe a reader would like to offer some thoughts? Not just the “answers”, but your thought process, and any insights that come up for you!

While preparing a course syllabus on coding in Python, for an upcoming high school class, I remembered static analysis. I haven’t decided how soon to introduce the topic, but I thought I’d better check how my own sample program fared.

No warnings or errors from Python itself. (If there had been I would have addressed them already!).

So I installed Pylint and tried its default settings. How about that. Not zero at all!

It was easy enough to clean up whitespace issues (helped to turn on “view whitespace” in my Notepad2).

And yes, many comment lines were too long. I left-justified (but indented for Python) for easy reading.

Some of the warnings are for my “TODO” comments — an extra reminder to do, or drop, next steps I’d identified earlier. Pylint message count is now down to 2 informational messages, 28 coding convention, 13 warnings, and 1 to refactor. They are valuable for my future Python learning (and teaching):

Locally disabling unused-variable (W0612) (locally-disabled)

I disabled those warnings because I know the code needs those variables. But I’ll have to explain why.

……..#Read from the file, line by line:
……..for line in initialGenerationFile:
…………listLine = list(line.rstrip(‘\r\n’))
…………self.mainBoard.append(listLine) #add the line, in Python list format, to the mainBoard

……..#Determine dimensions of the board after reading in
……..#WARNING: dimensions are 1 larger than largest index, since indices start at 0
……..self.maxRowMain = len(self.mainBoard)
……..self.maxColMain = len(self.mainBoard[0])

….def makeBoardCurrent(self): #TODO: Think of a better name — means to copy from the next-generation workingBoard to mainBoard
……..self.mainBoard = self.workingBoard
……..
….def calculateNextGeneration(self):
……..#Calculate next generation on workingBoard based on mainBoard

……..#Initialize work area
……..self.workingBoard = [] #A work area for creating the next Life generation

……..#Calculate next generation on workingBoard based on mainBoard
……..for mainRowIndex, mainRow in enumerate(self.mainBoard):

…………#Initialize working row before using for each row
…………workingRow = [] #for building up workingBoard row by row

#Generate and display following generations
for generationIndex in range(1,numGenerations+1): #NOTE:Add 1 because range end is always one less than value
….myLife.calculateNextGeneration()
….myLife.makeBoardCurrent()
….if (generationIndex % periodOfDisplay) == 0: #NOTE: “%” is Python modulus — checking for evening divisible by period of display
……..print(“Generation #”,generationIndex)
……..myLife.displayBoard()
……..print()

And here’s some output. The 4-generation-period “glider” on a 25 x 25 grid, starts its flight from upper-left towards lower-right.
The command I ran was

….def __init__(self):
……..#instance attributes: define and initialize (some more later after reading in file)
……..self.mainBoard = [] #The board of cells
……..self.workingBoard = [] #A work area for creating the next Life generation
….
….def readBoardFromFile(self, filename):
……..#Open the file
……..initialGenerationFile = open(filename)

……..#Read from the file, line by line:
……..for line in initialGenerationFile:
…………listLine = list(line.rstrip(‘\r\n’))
…………self.mainBoard.append(listLine) #add the line, in Python list format, to the mainBoard

……..#Determine dimensions of the board after reading in
……..#WARNING: dimensions are 1 larger than largest index, since indices start at 0
……..self.maxRowMain = len(self.mainBoard)
……..self.maxColMain = len(self.mainBoard[0])

#Run the methods in the right order
myLife.readBoardFromFile(initialGenerationFilename())
myLife.displayBoard() #TEST: display the mainBoard before generating
print()
myLife.calculateNextGeneration()
myLife.makeBoardCurrent()
myLife.displayBoard()

For an upcoming course to help science students master the computer as a tool for their work, by learning to code, I need to learn Python. I reviewed discussions on Python 2 vs Python 3, and chose the latter.

To operate in a new language, I only need to learn and practice four things:

After my first 2 hours in Python, with Python 3.4.3 installed, and Google for answering my questions, I’ve covered command line arguments (though still without argparse for user error handling), input from text file, output to console, line-by-line storage, and character-by-character retrieval from a Python list.

print("\nHere is the file as it's being read in: \n")
#Read from the file, line by line:
for line in myFile:
....print(line, end='') #display each line
....myList.append(line) #add the line to the list

#Close the file
myFile.close

print("\nFile should be closed now.\n")

print("Here's the contents of the list... \n")

#Display the contents of the list
for row in myList:
....print(row, end='') #entire rows
....print()
....for iCharacterIndex in range(len(row)):
........print(row[iCharacterIndex]) #character by character