Data Types & Conversion

Pre-COSMOS Day 2, for Cluster 10: Robot Inventors, covered in depth. It covers the core types int, float, and str, plus bool, and checking a value with type(). It then explains that floats are approximate, covers // and %, points out that input() always returns text, and converts with int(), float(), and str() and with f-strings. From there it separates round() from the truncation that int() performs, covers the truthiness of bool(), and builds two calculators. The three high-confidence misconceptions each appear as a trap slide. Every snippet is runnable, and the outputs and error messages were copied verbatim from CPython 3.12.

Subject: Python · 79 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. What you will be able to do

Objectives

Sensor readings, typed answers, and LED colors all reach your robot's program as data. By the end of this deck you can:

1. Name Python's core types - int, float, str (and bool) - and use type() to check any value.

2. Convert text to a number with int() / float(), and a number to text with str() or an f-string.

3. Explain why "3" + "4" is "34", and why "5" + 5 stops the program with an error.

4. Predict what int(3.9) gives - and know it chops the decimal, it does not round.

5. Use input() knowing it always hands you text, and split a number with // and %.

2. Why types matter at camp

Concept

A distance sensor's reading and an LED's color both reach your program as data - but not the same KIND of data.

Numbers you can do math on. Text (a string) you can join together and display. Mix them up and Python stops you with an error.

So the first question about any value is always: what type is it? The type decides what you are allowed to do with it - add it, join it, or convert it first.

3. Break it if you can: Why types matter at camp

Counterexample

Discussion prompt

A distance sensor's reading and an LED's color both reach your program as data - but not the same KIND of data.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

Numbers you can do math on. Text (a string) you can join together and display. Mix them up and Python stops you with an error.

4. The three core types

Concept

int - a whole number: 7, 0, -12. No decimal point. Python ints can be as huge as you like - no limit.

float - a number with a decimal point: 3.5, 0.0, -2.9.

str - text in quotes: "50", "red", "hello". The quotes are what make it text.

string (str) — A sequence of characters wrapped in quotes. "50" is the two characters 5 and 0 - it is text, not the number 50, even though it looks like a number to you.

5. A fourth type you'll meet: bool

Concept

bool holds just two values: True and False. It is what every yes/no question and every comparison produces - 5 > 3 is True.

A bool is secretly a number: True counts as 1 and False counts as 0. You will lean on this when a robot decides whether to act. We come back to it at the end.

6. By analogy: A fourth type you'll meet: bool

Analogy

Discussion prompt

Explain A fourth type you'll meet: bool by analogy to something with no Python in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

A bool is secretly a number: True counts as 1 and False counts as 0. You will lean on this when a robot decides whether to act. We come back to it at the end.

7. Guess the shape of the answer: Check the type with type()

Estimation

Predict first

When you are unsure what you are holding, ask Python directly:

Commit before you compute: what does Check the type with type() come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Read the output

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Verified by execution - each line prints the class name of the value's type.

8. Check the type with type()

Worked example

When you are unsure what you are holding, ask Python directly:

print(type(7))
print(type(3.5))
print(type("hi"))
print(type(True))

type(value) reports the kind of thing a value is

Why: It does not change the value - it just tells you the label. Run it any time a result surprises you.

Read the output

Why: Verified by execution - each line prints the class name of the value's type.

expressionprintsthe type
type(7)<class 'int'>int - whole number
type(3.5)<class 'float'>float - has a decimal
type("hi")<class 'str'>str - text in quotes
type(True)<class 'bool'>bool - True or False

9. Fill in: prints for Check the type with type()

Comparison

Comparison matrix

From Check the type with type(): refill the prints column from what you know. The rest of the table is as it appeared.

expressionprintsthe type
type(7)<class 'int'>int - whole number
type(3.5)<class 'float'>float - has a decimal
type("hi")<class 'str'>str - text in quotes
type(True)<class 'bool'>bool - True or False

10. Every value wears a label

Intuition

Picture each value sitting in a box with a label saying what kind of thing it is. The label decides which tools work on it.

5 wears an int label, so + means add. "5" wears a str label, so + means glue text together.

Same + symbol, different job - because the labels differ. That single idea explains almost every surprise in this deck.

11. Teach it back: Every value wears a label

Explain it

Discussion prompt

Explain Every value wears a label to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Picture each value sitting in a box with a label saying what kind of thing it is. The label decides which tools work on it.

12. int vs float: the decimal point

Concept

The only difference is the dot. 3 is an int; 3.0 is a float. They look almost identical but Python treats them as different types.

One rule worth memorizing: dividing with / always gives a float, even when it divides evenly. 10 / 2 is 5.0, not 5.

13. Floats are approximate

Concept

Computers store decimals in binary, and most decimals can't be written exactly in binary - so floats carry tiny rounding errors.

floating-point — How computers store decimal numbers. Because the storage is approximate, 0.1 + 0.2 is not exactly 0.3. For money, work in whole cents (ints) to stay exact.

This is normal and happens in every language - not a bug in your code. Just don't expect two floats to be exactly equal.

14. Take the definitions apart: string (str) vs floating-point

Definition probe

Sort into buckets

Every line below is part of the definition of string (str) or of floating-point — one or the other, never both. Put each where it belongs.

string (str)
A sequence of characters wrapped in quotes.; "50" is the two characters 5 and 0 - it is text, not the number 50, even though it looks like a number to you.
floating-point
How computers store decimal numbers.; Because the storage is approximate, 0.1 + 0.2 is not exactly 0.3.; For money, work in whole cents (ints) to stay exact.
b1
A sequence of characters wrapped in quotes. "50" is the two characters 5 and 0 - it is text, not the number 50, even though it looks like a number to you.
b2
How computers store decimal numbers. Because the storage is approximate, 0.1 + 0.2 is not exactly 0.3. For money, work in whole cents (ints) to stay exact.

15. Predict the next row: Where floats sneak in

Pattern

Predict first

The table runs: 10 / 2 | 5.0 | float · 10 / 4 | 2.5 | float

In Where floats sneak in, given the rows so far: what is the next one — the row where expression is 0.1 + 0.2?

Correct: 0.1 + 0.2 | 0.30000000000000004 | float (approximate!)

expressionvaluetype
10 / 25.0float
10 / 42.5float
0.1 + 0.20.30000000000000004float (approximate!)

Why: The relationship between the columns, not the individual numbers, is what generates the next row. The / operator produces a float every time, so the answer carries a decimal point even though it divides evenly.

16. Where floats sneak in

Worked example

print(10 / 2)
print(10 / 4)
print(0.1 + 0.2)

Line 1: 10 / 2 is 5.0, not 5

Why: The / operator produces a float every time, so the answer carries a decimal point even though it divides evenly.

Line 3: 0.1 + 0.2 is not exactly 0.3

Why: Verified by execution - the tiny tail of digits is the float approximation, not a mistake.

expressionvaluetype
10 / 25.0float
10 / 42.5float
0.1 + 0.20.30000000000000004float (approximate!)

17. What each one costs: Where floats sneak in

Trade off

Comparison matrix

From Where floats sneak in: every row here is a choice with a cost. Fill the value column, then say which row you would actually pick and what you give up for it.

expressionvaluetype
10 / 25.0float
10 / 42.5float
0.1 + 0.20.30000000000000004float (approximate!)

18. // and %: whole division and remainder

Concept

// is floor division - it divides and throws away the remainder, giving a whole number: 7 // 2 is 3.

% is modulo - it gives only the remainder: 7 % 2 is 1. Together they split one number into a whole part and what's left over.

modulo (%) — The remainder after division. 125 % 60 is 5. Camp use: turn 125 total seconds into 2 minutes (125 // 60) and 5 seconds (125 % 60).

19. What has to happen first: Splitting seconds into minutes

Ranking

Put in order

Put the moves of Splitting seconds into minutes into the order they have to happen.

  1. Line 2: 125 // 60 is 2 - how many whole minutes fit
  2. Line 3: 125 % 60 is 5 - the leftover seconds
  3. Line 4: print joins everything with spaces

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Floor division keeps only the whole number of 60s inside 125.

20. Splitting seconds into minutes

Worked example

total = 125
minutes = total // 60
seconds = total % 60
print(minutes, "min", seconds, "sec")

Line 2: 125 // 60 is 2 - how many whole minutes fit

Why: Floor division keeps only the whole number of 60s inside 125.

Line 3: 125 % 60 is 5 - the leftover seconds

Why: Modulo returns what division left behind: 125 - (2 * 60) = 5.

Line 4: print joins everything with spaces

Why: Verified by execution: 2 min 5 sec. Note print() converts each piece to text for you - + would not.

expressionvaluemeaning
125 // 602whole 60s that fit
125 % 605what is left over
print(...)2 min 5 secprint space-joins, any type

21. Inspect it line by line: Splitting seconds into minutes

Error analysis

Annotate

Walk the callouts on Splitting seconds into minutes. Each one is a place this is easy to get subtly wrong.

  • Floor division keeps only the whole number of 60s inside 125.
  • Modulo returns what division left behind: 125 - (2 * 60) = 5.
  • Verified by execution: 2 min 5 sec. Note print() converts each piece to text for you - + would not.

22. str: text that can look like a number

Concept

Quotes turn anything into text. "50" is just the characters 5 and 0 - you cannot do math on it until you convert it.

This is exactly how a sensor reading or a typed-in answer arrives: as a string that looks like a number but isn't one yet.

23. input() always hands you text

Concept

input() pauses the program, lets the camper type, and gives back what they typed - always as a str, even if they type digits.

That is the whole reason this lesson matters: to do math on a typed-in or sensor value, you must convert it first with int() or float().

24. Proof: input() returns a str

Worked example

age = input("How old are you? ")
print(type(age))

input() gives back whatever was typed, as text

Why: No matter what the camper types, age is a str. type(age) confirms <class 'str'> every time.

Same result for digits, words, or decimals

Why: The quotes are invisible at the keyboard, but they are there. To compute with age you would write int(age).

the camper typesage becomestype(age)
12"12"str
hello"hello"str
3.5"3.5"str

25. What stays fixed: Proof: input() returns a str

Invariant

Step through it

Step through Proof: input() returns a str one row at a time. One of these columns never changes — find it, and say why it cannot.

  1. Step 1: the camper types is 12
  2. Step 2: the camper types is hello
  3. Step 3: the camper types is 3.5

26. Something is wrong here: "3" + "4" is not 7

Anomaly

Predict first

A student writes this, and it looks reasonable:

Goal: add the numbers 3 and 4.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: + between two strings concatenates - it glues the characters into "34".

Convert the text to numbers first, then add.

Why: + between two strings concatenates - it glues the characters into "34". It never adds them as numbers.

27. Trap: "3" + "4" is not 7

Trap

The trap

Goal: add the numbers 3 and 4.

print("3" + "4")

Both sides are strings, so + joins them

Why: + between two strings concatenates - it glues the characters into "34". It never adds them as numbers.

expressionyou might expectactual output
"3" + "4"734

The fix

Convert the text to numbers first, then add.

print(int("3") + int("4"))

int() on each string makes them numbers

Why: int("3") is 3 and int("4") is 4, so now + means add. Real output: 7.

expressionvalueoutput
int("3") + int("4")77

28. Text to number: int() and float()

Concept

int("50") reads the text "50" and hands back the number 50 - now you can do math with it.

float("3.5") does the same for decimals. It also accepts whole-number text: float("50") is 50.0.

One catch: int("3.5") fails - int() only accepts whole-number text. Use float() when the text has a decimal point.

29. Plan first: Converting a whole-number reading

Step zero

Discussion prompt

Converting a whole-number reading — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Line 1: reading is the TEXT "50"

Answer:

  1. Line 1: reading is the TEXT "50"
  2. Line 2: int(reading) turns it into 50, then adds 1
  3. Trace each value

30. Converting a whole-number reading

Worked example

A sensor sends "50" as text. Add one to it.

reading = "50"
n = int(reading) + 1
print(n)

Line 1: reading is the TEXT "50"

Why: It looks like a number, but its type is str - you cannot add to it yet.

Line 2: int(reading) turns it into 50, then adds 1

Why: int("50") is 50, and 50 + 1 is 51. The result n is an int.

Trace each value

Why: Verified by execution: the program prints 51.

stepexpressionvaluetype
1reading"50"str
2int(reading)50int
3int(reading) + 151int

31. Draw the shape of it: Converting a whole-number reading

Blank canvas

Draw it

Draw what Converting a whole-number reading just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

32. Guess the shape of the answer: Converting a decimal reading

Estimation

Predict first

A temperature sensor sends "3.5". Double it.

Commit before you compute: what does Converting a decimal reading come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Trace each value

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Verified by execution: 3.5 * 2 is 7.0, printed as 7.0 because a float stays a float.

33. Converting a decimal reading

Worked example

A temperature sensor sends "3.5". Double it.

reading = "3.5"
n = float(reading) * 2
print(n)

Use float(), not int(), because the text has a decimal

Why: float("3.5") is 3.5. int("3.5") would crash - this is the conversion you reach for with decimals.

Trace each value

Why: Verified by execution: 3.5 * 2 is 7.0, printed as 7.0 because a float stays a float.

stepexpressionvaluetype
1reading"3.5"str
2float(reading)3.5float
3float(reading) * 27.0float

34. Something is wrong here: int("3.5") is an error

Anomaly

Predict first

A student writes this, and it looks reasonable:

You have the decimal text "3.5" and reach for int().

It is wrong. Say what breaks — and say it before you turn the page.

Correct: int() only parses whole-number text like "3".

Use float() for decimal text. If you then want a whole number, chop it with int() after.

Why: int() only parses whole-number text like "3". The ".5" makes it refuse, and the program stops.

35. Trap: int("3.5") is an error

Trap

The trap

You have the decimal text "3.5" and reach for int().

print(int("3.5"))

int() rejects text that contains a decimal point

Why: int() only parses whole-number text like "3". The ".5" makes it refuse, and the program stops.

expressionresult
int("3.5")ValueError: invalid literal for int() with base 10: '3.5'

The fix

Use float() for decimal text. If you then want a whole number, chop it with int() after.

print(float("3.5"))
print(int(float("3.5")))

float() reads the decimal text; int() can chop it afterward

Why: float("3.5") is 3.5. If you need a whole number, int(3.5) then gives 3. Real outputs: 3.5 and 3.

expressionvalueoutput
float("3.5")3.53.5
int(float("3.5"))33

36. Break it on purpose: int("3.5") is an error

Break the constraint

Discussion prompt

The rule this trap just fixed:

Use float() for decimal text. If you then want a whole number, chop it with int() after.

Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?

Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.

Answer:

int() only parses whole-number text like "3". The ".5" makes it refuse, and the program stops.

37. Number to text: str()

Concept

str() goes the other way: str(50) gives the text "50". You need this to join a number into a message with +.

Reminder: print() already converts each piece for you, but + does not. So "Score: " + score fails unless you write str(score).

38. What has to happen first: Building a message with str()

Ranking

Put in order

Put the moves of Building a message with str() into the order they have to happen.

  1. Line 1: score is the number 100 (an int)
  2. Line 2: str(score) makes "100", then + joins
  3. Trace each value

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. You cannot join an int directly onto "Score: " with + - the types do not match.

39. Building a message with str()

Worked example

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

Line 1: score is the number 100 (an int)

Why: You cannot join an int directly onto "Score: " with + - the types do not match.

Line 2: str(score) makes "100", then + joins

Why: str(100) is "100", and "Score: " + "100" is "Score: 100". Now both sides of + are text.

Trace each value

Why: Verified by execution: the program prints Score: 100.

stepexpressionvaluetype
1score100int
2str(score)"100"str
3"Score: " + str(score)"Score: 100"str

40. Next level: f-strings

Concept

Joining with + str(...) works but gets clunky. An f-string lets you drop values straight into text: put f before the quotes and wrap each value in { }.

Inside the braces, Python converts the value to text for you automatically - no str() needed. f"Score: {score}" is the clean version of the last slide.

41. Teach it back: Next level: f-strings

Explain it

Discussion prompt

Explain Next level: f-strings to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Joining with + str(...) works but gets clunky. An f-string lets you drop values straight into text: put f before the quotes and wrap each value in { }.

42. Restore the missing line: The f-string version

Fill the middle

Fill in the blanks

From The f-string version — one line has had its right-hand side removed. Put it back.

name = "Robo"
score = 100
print(f"___ scored ___")

Why: score is what everything below it consumes, so the wrong expression here fails later and somewhere else. {name} becomes Robo and {score} becomes 100 - automatically converted, no str() call.

43. The f-string version

Worked example

name = "Robo"
score = 100
print(f"{name} scored {score}")

Each {...} is replaced by that value's text

Why: {name} becomes Robo and {score} becomes 100 - automatically converted, no str() call.

Trace the substitution

Why: Verified by execution: the program prints Robo scored 100. Same result as +, far easier to read.

piecefills in with
{name}Robo
{score}100
whole f-string"Robo scored 100"

44. Fill in: fills in with for The f-string version

Comparison

Comparison matrix

From The f-string version: refill the fills in with column from what you know. The rest of the table is as it appeared.

piecefills in with
{name}Robo
{score}100
whole f-string"Robo scored 100"

45. Something is wrong here: "5" + 5 is an error

Anomaly

Predict first

A student writes this, and it looks reasonable:

A sensor reading "5" plus the number 5.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: One side is text, the other a number.

Decide what you want - math, or joined text - and convert one side to match.

Why: One side is text, the other a number. Python refuses to guess and stops. (5 + "5" fails the same way, with the message worded the other direction.)

46. Trap: "5" + 5 is an error

Trap

The trap

A sensor reading "5" plus the number 5.

print("5" + 5)

You cannot + a str and an int together

Why: One side is text, the other a number. Python refuses to guess and stops. (5 + "5" fails the same way, with the message worded the other direction.)

expressionresult
"5" + 5TypeError: can only concatenate str (not "int") to str

The fix

Decide what you want - math, or joined text - and convert one side to match.

print(int("5") + 5)
print("5" + str(5))

Make both sides the same type first

Why: For math, convert the text to a number: int("5") + 5 is 10. For text, convert the number: "5" + str(5) is "55". Real outputs: 10 and 55.

expressionvalueoutput
int("5") + 51010
"5" + str(5)"55"55

47. int() chops, it does not round

Concept

Calling int() on a float removes the decimal part - it does not round. int(3.9) is 3, and int(3.2) is also 3. Both just drop everything after the dot.

truncate — To cut off the decimal part and keep only the whole-number part. int(3.9) truncates to 3 - it ignores how close 3.9 is to 4.

If you actually want the nearest whole number, that is a different tool: round().

48. Term to definition: Data Types & Conversion

Matching

Match the pairs

Match each term to the definition this lesson gave it — not the one you would guess from the word.

  • t1. string (str)
  • t2. floating-point
  • t3. modulo (%)
  • t4. truncate
  • d1. A sequence of characters wrapped in quotes. "50" is the two characters 5 and 0 - it is text, not the number 50, even though it looks like a number to you.
  • d2. How computers store decimal numbers. Because the storage is approximate, 0.1 + 0.2 is not exactly 0.3. For money, work in whole cents (ints) to stay exact.
  • d3. The remainder after division. 125 % 60 is 5. Camp use: turn 125 total seconds into 2 minutes (125 // 60) and 5 seconds (125 % 60).
  • d4. To cut off the decimal part and keep only the whole-number part. int(3.9) truncates to 3 - it ignores how close 3.9 is to 4.

Why: These are the working definitions of string (str), floating-point, modulo (%), truncate as Data Types & Conversion uses them. Pairing them correctly is the test of whether you could state each one with the slide switched off.

49. Watching int() truncate

Worked example

print(int(3.9))
print(int(3.2))
print(int(-2.9))

Each call drops the decimal and keeps the whole part

Why: 3.9 and 3.2 both become 3. The size of the decimal never matters - int() chops it off entirely.

Negatives chop toward zero

Why: Verified by execution: int(-2.9) is -2, not -3. int() moves toward zero, it does not round down.

expressionvaluewhat happened
int(3.9)3decimal chopped off
int(3.2)3decimal chopped off
int(-2.9)-2chopped toward zero, not down

50. Something is wrong here: int(3.9) gives 3, not 4

Anomaly

Predict first

A student writes this, and it looks reasonable:

You want to round 3.9 to the nearest whole number.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Because 3.9 is almost 4, people expect 4.

To round to the nearest whole number, use round().

Why: Because 3.9 is almost 4, people expect 4. But int() only chops the decimal, leaving 3.

51. Trap: int(3.9) gives 3, not 4

Trap

The trap

You want to round 3.9 to the nearest whole number.

print(int(3.9))

int() truncates - it ignores how close 3.9 is to 4

Why: Because 3.9 is almost 4, people expect 4. But int() only chops the decimal, leaving 3.

expressionyou might expectactual
int(3.9)43

The fix

To round to the nearest whole number, use round().

print(round(3.9))

round() picks the nearest whole number

Why: round(3.9) is 4 because 3.9 is closer to 4 than to 3. Use int() to chop, round() to round - pick the one you mean.

expressionvalueoutput
round(3.9)44

52. Which of these survive contact with Data Types & Conversion?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
A distance sensor's reading and an LED's color both reach your program as data - but not the same KIND of data.; A bool is secretly a number: True counts as 1 and False counts as 0. You will lean on this when a robot decides whether to act. We come back to it at the end.; Picture each value sitting in a box with a label saying what kind of thing it is. The label decides which tools work on it.
Breaks
Goal: add the numbers 3 and 4.; You have the decimal text "3.5" and reach for int().
sound
These are stated as this lesson states them — each one survives the edge cases Data Types & Conversion puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

53. round(): to the nearest - mostly

Concept

round(x) gives the nearest whole number. round(x, n) keeps n decimal places: round(3.14159, 2) is 3.14.

One surprise: an exact half rounds to the nearest even number, not always up. round(2.5) is 2, but round(3.5) is 4. This keeps large sums fair - just don't be shocked by it.

54. By analogy: round(): to the nearest - mostly

Analogy

Discussion prompt

Explain round(): to the nearest - mostly by analogy to something with no Python in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

round(x) gives the nearest whole number. round(x, n) keeps n decimal places: round(3.14159, 2) is 3.14.

55. round() in action

Worked example

print(round(3.14159, 2))
print(round(3.5))
print(round(2.5))

Second argument = how many decimals to keep

Why: round(3.14159, 2) keeps two places: 3.14.

Halves round to the nearest even number

Why: Verified by execution: round(3.5) is 4 (even), round(2.5) is 2 (even). Not a bug - it is the rule.

expressionvaluenote
round(3.14159, 2)3.14keep 2 decimal places
round(3.5)4nearest even
round(2.5)2nearest even (not 3!)

56. Draw the shape of it: round() in action

Blank canvas

Draw it

Draw what round() in action just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

57. bool(): is there something there?

Concept

bool(x) answers is this value truthy? Zero, an empty string, and nothing-at-all are falsy; everything else is truthy.

The classic trap: bool("0") is True. The string "0" is not empty - it has one character - so it counts as truthy, even though the number 0 is falsy.

58. Break it if you can: bool(): is there something there?

Counterexample

Discussion prompt

bool(x) answers is this value truthy? Zero, an empty string, and nothing-at-all are falsy; everything else is truthy.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

The classic trap: bool("0") is True. The string "0" is not empty - it has one character - so it counts as truthy, even though the number 0 is falsy.

59. Predict the next row: Truthy and falsy values

Pattern

Predict first

The table runs: bool(0) | False | zero is the only falsy number · bool(5) | True | any non-zero number is truthy · bool("") | False | an empty string is falsy

In Truthy and falsy values, given the rows so far: what is the next one — the row where expression is bool("0")?

Correct: bool("0") | True | non-empty string - even "0"

expressionvaluewhy
bool(0)Falsezero is the only falsy number
bool(5)Trueany non-zero number is truthy
bool("")Falsean empty string is falsy
bool("0")Truenon-empty string - even "0"

Why: The relationship between the columns, not the individual numbers, is what generates the next row. bool(0) is False; any non-zero number, like 5, is True.

60. Truthy and falsy values

Worked example

print(bool(0))
print(bool(5))
print(bool(""))
print(bool("0"))

Numbers: only 0 is falsy

Why: bool(0) is False; any non-zero number, like 5, is True.

Strings: only the empty string is falsy

Why: Verified by execution: bool("") is False, but bool("0") is True because the string holds a character.

expressionvaluewhy
bool(0)Falsezero is the only falsy number
bool(5)Trueany non-zero number is truthy
bool("")Falsean empty string is falsy
bool("0")Truenon-empty string - even "0"

61. Which is which, by value

Discrimination

Sort into buckets

Sort these by value, from memory, without looking back at Truthy and falsy values. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

False
bool(0); bool("")
True
bool(5); bool("0")
g1
value is "False" for bool(0), bool("") — that is what the table on "Truthy and falsy values" records, and it is the single property separating this group from the rest.
g2
value is "True" for bool(5), bool("0") — that is what the table on "Truthy and falsy values" records, and it is the single property separating this group from the rest.

62. Plan first: Build it: the area calculator

Step zero

Discussion prompt

Build it: the area calculator — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Lines 1-2: the measurements arrive as TEXT

Answer:

  1. Lines 1-2: the measurements arrive as TEXT
  2. Line 3: convert both to int, then multiply
  3. Line 4: convert the result back to text to display it
  4. Trace every line

63. Build it: the area calculator

Worked example

Two measurements arrive as text. Compute a rectangle's area and display it - the full text -> number -> text round trip.

length = "12"
width = "8"
area = int(length) * int(width)
print("Area = " + str(area))

Lines 1-2: the measurements arrive as TEXT

Why: length is "12" and width is "8" - strings, even though they look like numbers. You cannot multiply them yet.

Line 3: convert both to int, then multiply

Why: int("12") is 12, int("8") is 8, and 12 * 8 is 96. area is now an int.

Line 4: convert the result back to text to display it

Why: str(96) is "96", and "Area = " + "96" is "Area = 96". Both sides of + are text again.

Trace every line

Why: Verified by execution: prints Area = 96. This is the table to write on paper before you run anything.

linevariablevaluetype
1length"12"str
2width"8"str
3area96int
4(printed)Area = 96str

64. Watch it run: Build it: the area calculator

Pattern

Step through it

Step through Build it: the area calculator one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: line is 1
  2. Step 2: line is 2
  3. Step 3: line is 3
  4. Step 4: line is 4

65. What has to happen first: Build it bigger: temperature converter

Ranking

Put in order

Put the moves of Build it bigger: temperature converter into the order they have to happen.

  1. Line 1: input() gives text, int() wraps it into a number
  2. Line 2: the formula - and / makes it a float
  3. Line 3: an f-string drops both values into text

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. If the camper types 100, input() returns "100"; int("100") makes it 100.

66. Build it bigger: temperature converter

Worked example

Now with real input and an f-string. Read a Celsius temperature, convert to Fahrenheit, and display it cleanly.

celsius = int(input("Temp in C? "))
fahrenheit = celsius * 9/5 + 32
print(f"{celsius}C is {fahrenheit}F")

Line 1: input() gives text, int() wraps it into a number

Why: If the camper types 100, input() returns "100"; int("100") makes it 100. The int() is what lets the next line do math.

Line 2: the formula - and / makes it a float

Why: 100 * 9 / 5 + 32 is 212.0. Because / is used, fahrenheit is a float (note the .0).

Line 3: an f-string drops both values into text

Why: Verified by execution (typing 100): prints 100C is 212.0F. No str() calls needed - the braces convert for you.

linevariablevaluetype
1celsius100int (int() wrapped input)
2fahrenheit212.0float (/ made it a float)
3(printed)100C is 212.0Fstr (f-string built it)

67. Inspect it line by line: Build it bigger: temperature converter

Error analysis

Annotate

Walk the callouts on Build it bigger: temperature converter. Each one is a place this is easy to get subtly wrong.

  • If the camper types 100, input() returns "100"; int("100") makes it 100. The int() is what lets the next line do math.
  • 100 * 9 / 5 + 32 is 212.0. Because / is used, fahrenheit is a float (note the .0).
  • Verified by execution (typing 100): prints 100C is 212.0F. No str() calls needed - the braces convert for you.

68. The conversion recipe

Pattern

1. When in doubt, check the type with type(value)

Why: If it prints <class 'str'>, you have text and must convert before doing any math. Anything from input() is always a str.

2. Text to number: int() for whole numbers, float() for decimals

Why: int("50") is 50; float("3.5") is 3.5. int() rejects text that has a decimal point.

3. Number to text: str(), or just use an f-string

Why: "Score: " + str(score) works; f"Score: {score}" is the cleaner next-level way and converts for you.

4. Never + a str and a number together

Why: "5" + 5 is a TypeError. Convert one side so both are the same type first.

5. int() chops, round() rounds

Why: int(3.9) is 3; round(3.9) is 4. And remember floats are approximate - don't expect them to be exact.

69. Where this shows up: Data Types & Conversion

Real world

Discussion prompt

Outside this lesson: where does Data Types & Conversion actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of The conversion recipe is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

Pre-COSMOS Day 2 (Cluster 10: Robot Inventors), in depth. The core types int, float, str (plus bool); checking with type(); floats are approximate; // and %; input() always returns text; converting with int()/float()/str() and f-strings; round() vs int() truncation; bool() truthiness; and two build-it calculators.

70. Check yourself: joining text

Check

Decide the type of each side of the + first, then pick your answer.

print("3" + "4")
expressionoutput
"3" + "4"?

Check your understanding

What does this program display?

  • A. 7
  • B. 34 (correct)
  • C. 12
  • D. TypeError

Answer: B

Why: Both operands are strings, so + concatenates them into the text "34"; print shows it without the quotes. To add them as numbers you would convert first: int("3") + int("4") is 7. Verified by execution: this prints 34.

Why A tempts people
Treated the strings as numbers. + between two strings joins them; it never adds. You would need int() on each side to get 7.
Why C tempts people
Multiplied 3 by 4. + joins text - and even as numbers, 3 + 4 is 7, not 12.
Why D tempts people
Two strings concatenate cleanly, so there is no error. The TypeError only happens when you mix a str and a number, like "5" + 5.

71. Check yourself: chop or round?

Check

Trace it line by line - remember what int() does to a decimal.

x = int(3.9)
print(x + 1)
stepexpressionvalue
1int(3.9)?
2x + 1?

Check your understanding

What does this program print?

  • A. 4 (correct)
  • B. 5
  • C. 4.9
  • D. 3

Answer: A

Why: int(3.9) truncates - it chops the decimal to 3, it does not round to 4. Then 3 + 1 is 4. Verified by execution: this prints 4.

Why B tempts people
Assumed int(3.9) rounds up to 4, then 4 + 1 is 5. int() truncates to 3 - use round(3.9) if you want 4.
Why C tempts people
Kept the decimal: 3.9 + 1 is 4.9. int() removes the decimal entirely, leaving the whole number 3.
Why D tempts people
Stopped at int(3.9) = 3 and forgot to add the 1.

72. What each one costs: Check yourself: chop or round?

Trade off

Comparison matrix

From Check yourself: chop or round?: every row here is a choice with a cost. Fill the value column, then say which row you would actually pick and what you give up for it.

stepexpressionvalue
1int(3.9)?
2x + 1?

73. Check yourself: what did input() give?

Check

The camper runs this and types 12 at the prompt.

answer = input("How many? ")
print(type(answer))
typedanswertype(answer)
12??

Check your understanding

What does type(answer) print?

  • A. <class 'int'>
  • B. <class 'str'> (correct)
  • C. <class 'float'>
  • D. <class 'input'>

Answer: B

Why: input() always returns a str, even when the camper types digits. answer is the text "12", so type(answer) is <class 'str'>. To get a number you must wrap it: int(input(...)). Verified by execution.

Why A tempts people
input() does not detect numbers - it never returns an int. You only get an int if you wrap it yourself with int(input(...)).
Why C tempts people
input() does not return a float either. Typing 12 gives the text "12", not 12.0.
Why D tempts people
There is no 'input' type. input() hands back an ordinary str.

74. Rule out three: Check yourself: // vs /

Elimination

Eliminate the wrong options

What does this program print, line by line?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. 3 then 3.5
  • B. 3.5 then 3.5
  • C. 3 then 3
  • D. 4 then 3.5

Survives elimination: A

Why: // is floor division: 7 // 2 throws away the remainder and gives the int 3. / is true division: 7 / 2 gives the float 3.5. Verified by execution: the output is 3 then 3.5.

75. Check yourself: // vs /

Check

These two look similar but give different types. Trace both.

print(7 // 2)
print(7 / 2)
expressionvalue
7 // 2?
7 / 2?

Check your understanding

What does this program print, line by line?

  • A. 3 then 3.5 (correct)
  • B. 3.5 then 3.5
  • C. 3 then 3
  • D. 4 then 3.5

Answer: A

Why: // is floor division: 7 // 2 throws away the remainder and gives the int 3. / is true division: 7 / 2 gives the float 3.5. Verified by execution: the output is 3 then 3.5.

Why B tempts people
Used / for both lines. // is floor division and drops the remainder, giving 3 - not 3.5.
Why C tempts people
Assumed // and / behave the same. Only // floors; / always produces a float (3.5 here).
Why D tempts people
Rounded 7 // 2 up to 4. Floor division truncates toward the lower whole number, giving 3.

76. Fill in: value for Check yourself: // vs /

Comparison

Comparison matrix

From Check yourself: // vs /: refill the value column from what you know. The rest of the table is as it appeared.

expressionvalue
7 // 2?
7 / 2?

77. Check yourself: the bool surprise

Check

Falsy means zero or empty. Look carefully at the quotes.

print(bool("0"))
expressionoutput
bool("0")?

Check your understanding

What does this print?

  • A. True (correct)
  • B. False
  • C. 0
  • D. TypeError

Answer: A

Why: "0" is a string with one character, so it is non-empty and therefore truthy: bool("0") is True. Only the empty string "" is falsy. The number 0 is falsy, but the text "0" is not the number 0. Verified by execution.

Why B tempts people
Confused the text "0" with the number 0. The number 0 is falsy, but any non-empty string - including "0" - is truthy.
Why C tempts people
bool() returns True or False, never the number 0. bool(0) would be False, but here the argument is the string "0".
Why D tempts people
bool() accepts any value without error - strings included. There is no type mismatch here.

78. Connect it up: Data Types & Conversion

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — The conversion recipe · Why types matter at camp · The three core types · A fourth type you'll meet: bool · Every value wears a label. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

79. What you can do now

Recap

Core types - int, float, str, bool - and type() tells you which you have. int() / float() turn text into numbers; str() and f-strings turn numbers into text.

You haveYou wantUse
"50" (text)the number 50int("50")
"3.5" (text)the number 3.5float("3.5")
50 (number)it inside a messagestr(50) or f"...{50}..."
text from input()a number to compute withint(input()) / float(input())
3.9 (float)the whole number 3int(3.9) - chops
3.9 (float)the nearest whole, 4round(3.9)

And the two that trip everyone: "3" + "4" joins into "34", and "5" + 5 is an error. When a value surprises you, check its type and convert. Now go build the calculator.

Sources

  1. Python 3 Library Reference - Built-in Functions (int, float, str, bool, type, round, input)
  2. Python 3 Library Reference - Text Sequence Type str and f-strings
  3. Python 3 Tutorial - Floating-Point Arithmetic: Issues and Limitations
  4. All snippets executed under CPython 3.12; outputs and error messages copied from real runs. — Author verification run, 2026-06-12 (Pre-COSMOS Prep Plan, Day 2).

Want this taught 1-on-1? Alexander tutors Python — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108