Lesson 1 — Variables

By the end of this you can: put a value under a name, change what that name holds, tell a number from a piece of text, join text together, and print any of it.

This first lesson is plain Python. No game, no sprites, nothing to import — just the playground, a few lines, and Run. The last section puts a variable on the screen, once there is something worth putting there.

A name for a value

A program has to remember things. This is how:

score = 0
print(score)
0

Line 1 makes a variable. The name is score, and the value in it is 0. Line 2 asks Python to print what is in there.

Read the = as "put this in here", right to left. It is not the equals sign from maths, and reading it as one will confuse you within about four minutes. score = 0 is an instruction: make a box called score and put 0 in it.

You can put anything in a box, and print several at once:

score = 0
lives = 3
name = "Ada"

print(name, score, lives)
Ada 0 3

print takes as many values as you like, separated by commas, and puts a single space between them.

Changing what a name holds

A variable is not fixed. Give it a new value and the old one is gone:

score = 0
print(score)

score = 50
print(score)
0
50

Which leads to the line that stops everybody the first time they see it:

score = 50
score = score + 10
print(score)
60

As maths, score = score + 10 is nonsense — no number is ten more than itself. As Python it is perfectly ordinary, because = is not equals. Python does the right-hand side first: score + 10 is 60. Then it puts 60 into score. The old value was used to work out the new one and then thrown away.

That one line is most of what a game does. Score goes up, health goes down, the player moves a bit further right — all of it is "take what is in there, do something to it, put the answer back".

+= is the short way. score += 10 means exactly score = score + 10, and there is -= too. Use whichever you find easier to read; they are the same instruction.

Numbers and text

Two kinds of value turn up constantly, and the quotes are what tell them apart:

score = 10
label = "10"

print(score + 5)
print(label + "5")
15
105

Same +, two completely different answers. 10 is a number, so + adds. "10" is a string — a piece of text — so + sticks the two together end to end. "10" + "5" is "105" in the same way that "cat" + "fish" is "catfish".

Joining strings is how a game builds a label out of pieces:

name = "Ada"
print("Good luck, " + name + "!")
Good luck, Ada!

Notice the space after the comma, inside the quotes. Python joins exactly what you give it and adds nothing, so a missing space is a missing space.

Mixing the two

Try to join a number onto a string and Python refuses:

score = 10
print("Score: " + score)
TypeError: can only concatenate str (not "int") to str

It is being careful rather than difficult. + means add for numbers and join for text, and with one of each it has no way to know which you meant. So you say, with str(), which turns a value into its text:

score = 10
print("Score: " + str(score))
Score: 10

Or sidestep it entirely with a comma, which is usually nicer:

score = 10
print("Score:", score)
Score: 10

str() has an opposite, int(), which turns text into a whole number:

print(int("42") + 8)
50

That looks pointless here — why write "42" when you could write 42? It is the whole of the next lesson: everything a person types arrives as text, and int() is what makes it a number you can do sums with.

Picking names

Python has a few rules and everybody else has one preference.

The rules: a name is made of letters, digits and underscores, it cannot start with a digit, and it cannot have a space in it. high_score is fine. high score is two names Python does not understand, and 2nd_player is an error.

The preference: say what it holds. lives_left costs eight keystrokes more than l and saves you reading the whole program to remember what l was. Use lower case with underscores between the words — that is what Python code looks like everywhere.

And a name is only a name, so a typo makes a different one:

score = 10
print(scoer)
NameError: name 'scoer' is not defined

NameError nearly always means one of two things: a spelling mistake, or you used the name on a line above the one that created it. Python reads top to bottom and will not use a box you have not filled yet.

Now put it on the screen

Everything above works the same in a game — the only difference is where the value ends up. Here it goes on a window instead of in the output pane:

from kaypy import *

kaypy(width=800, height=600, background=[20, 24, 36])

name = "Ada"
score = 120
lives = 3

add([text("Player: " + name, size=28), pos(40, 40)])
add([text("Score: " + str(score), size=28), pos(40, 90)])
add([text("Lives: " + str(lives), size=28), pos(40, 140)])

Press Run and a window opens with three labels in it. This one does need from kaypy import * at the top, which is how the playground knows to open a window rather than just print.

Three things worth noticing, because all three are from this lesson:

  • str(score) — text() wants a string, and score is a number. Take the str() off and you get the same TypeError as before.
  • The labels are built by joining, exactly like "Good luck, " + name.
  • Change score to 9999 and run it again. One number changed; the window changed with it, and you did not touch the three add lines.

Watch for

= puts a value in a box. It is not a claim that two things are equal. Read it right to left.

Quotes make text. 7 is a number, "7" is a string, and + does a different job to each.

"Score: " + score is a TypeError when score is a number. Either str(score) or a comma.

NameError means Python has never heard that name — check the spelling, then check the order.

Name things after what they hold. You are the one who has to read it next week.

Classwork 1 — The Character Sheet

Start with this and press Run:

name = "Ada"
health = 100

print(name)
print(health)
Ada
100

Now change it, one step at a time, running after each:

  1. Add two more variables: gold, a number, and weapon, a piece of text.
  2. Replace the two print lines with one line that prints Ada the knight, 100 health, 40 gold — with your values in it, built by joining strings with +. You will need str() twice.
  3. Below that, take 30 off health using health = health - 30, and print the line again. The same print code, a different number: copy the line rather than retyping it.
  4. Double the gold with gold = gold * 2 and print once more.

Stretch: write the whole line with commas instead of + and str(), and compare the two. One of them needs more punctuation; the other gives you less control over the spaces. Which would you rather read?

Classwork 2 — The Scoreboard

A window with numbers on it that you can change from one place.

from kaypy import *

kaypy(width=800, height=600, background=[20, 24, 36])

coins = 7
coin_value = 25

add([text("Coins: " + str(coins), size=28), pos(40, 40)])
  1. Add a second label under the first, at pos(40, 90), showing coins * coin_value as the total. Work the total out into a variable of its own first — total = coins * coin_value — and put that on the screen.
  2. Add a third label with a title of your own at the top, in a bigger size.
  3. Change coins to 40 and run it again. Both numbers should move. If only one did, you typed a number where a variable should be.

Stretch: add bonus = 100 and make the total coins * coin_value + bonus. Then set bonus = 0 and check the screen agrees.

Check yourself

What does this print?

a = 5
b = a
a = 12

print(a, b)
12 5
Why is b still 5?

b = a copied the value that was in a at that moment, which was 5. It did not tie the two names together. When a was given 12 on the next line, nothing went looking for other names to update, because nothing was ever linked — b has held its own 5 since the line that put it there.

This catches people because b = a looks like it says "b is a". It says "put what is in a into b", once, on the line where it is written.



All nine lessons · Lesson 2 — Input →