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 += 10means exactlyscore = 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, andscoreis a number. Take thestr()off and you get the sameTypeErroras before.- The labels are built by joining, exactly like
"Good luck, " + name. - Change
scoreto 9999 and run it again. One number changed; the window changed with it, and you did not touch the threeaddlines.
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:
- Add two more variables:
gold, a number, andweapon, a piece of text. - Replace the two
printlines with one line that printsAda the knight, 100 health, 40 gold— with your values in it, built by joining strings with+. You will needstr()twice. - Below that, take 30 off
healthusinghealth = health - 30, and print the line again. The same print code, a different number: copy the line rather than retyping it. - Double the gold with
gold = gold * 2and 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)])
- Add a second label under the first, at
pos(40, 90), showingcoins * coin_valueas the total. Work the total out into a variable of its own first —total = coins * coin_value— and put that on the screen. - Add a third label with a title of your own at the top, in a bigger size.
- Change
coinsto 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.