Master

Text is numbers too

Characters are numbers underneath as well. A character is a code point, and text is a list of them, which is why text can be measured, indexed, and compared at all.

What you will see

True True

About 2 min of reading

Try It

Index, slice, and compare text by position.

1

Get the code point of a letter and back.

print(ord("A")) print(chr(65))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
65 A
2

Measure text and pick ends by position.

word = "owlww" print(len(word)) print(word[0]) print(word[-1])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
5 o w
3

Take a middle range. The end index is not included.

word = "owlww" print(word[1:4])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
lww
4

Compare two words and two cases. Case changes the order.

print("apple" < "banana") print("Zoo" < "apple")

Before you run it, say out loud what it will print. Then open the answer.

What it prints
True True
Uppercase code points are all below lowercase ones, so any capital sorts before any small letter. Sorting names case-insensitively means comparing lowercased copies.

Data Flow

Text is a sequence of code points, positions address them, and an encoding maps bytes to those code points.
1 "A" has code point 65
↓
2 len counts code points
↓
3 a slice takes a range
↓
4 comparison walks the code points
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

print(ord("A")) 65
print(chr(65)) A
Why this works
Why encoding matters

A file, a web page, and a keyboard all carry text as bytes. The encoding says which bytes mean which code point. Two tools that disagree about the encoding turn the same bytes into different text, which is the cause of the garbled characters you sometimes see.

When you have a choice

Positions versus content

A slice or an index works on positions, so it does not care what the text says. That is what makes the same trimming code work on any input, and it is also why a position count has to start at zero rather than one.

Examples

Ask for the number

print(ord("A"))
print(chr(65))

ord gives the code point of a character, chr goes back. The pair is the bridge between a character and the number stored for it, and both directions are exact.

Text is positions

word = "owlww"
print(len(word))
print(word[0])
print(word[-1])

len counts the code points. Brackets pick a position, counting from zero at the front, and minus one counts back from the end. Positions are the reason an off-by-one bug exists.

A slice is a range

word = "owlww"
print(word[1:4])
print(word[:2])

A slice takes from the first index up to but not including the second. Leaving an end off takes everything to that edge. Slices never fail on a range that is too big, which makes them safe for trimming.

Comparing text

print("apple" < "banana")
print("Zoo" < "apple")

Text compares code point by code point, so uppercase letters sort before lowercase. That is why a list of names can come out in an order that looks wrong but is perfectly consistent.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← What the machine holds underneath
Previous Lesson
What the machine holds underneath
Next Lesson
Designing the values of a whole program
Designing the values of a whole program →