Menu

Programming Fundamentals

Casting

Contents

  1. Casting
  2. The str() Function
  3. int() and float() Conversions
  4. bool() Conversions
  5. Invalid and Chained Casts
  6. Evaluating Casts in Expressions

Casting means taking a value and producing a new version of it with a different data type. Python gives you four casting functions, and you use one by putting the value inside its brackets: str() produces a string, int() produces an integer, float() produces a real number and bool() produces a Boolean.

Each cast hands back a brand new value of the type you asked for. That new value can be printed, stored in a different variable or used straight away inside an expression.

The cast is used only where it is written

Casting does not change a variable by itself. The variable keeps its original type and value; only the single place where the cast appears works with the new type:

distance = "42"
print(int(distance) + 8)
print(distance + "8")
distance = int(distance)  # the cast result is stored back
print(distance + 8)

Output:

50
428
50

On line 2 the cast is worked out first, so 8 is added to the integer 42 to give 50. Line 3 contains no cast, so distance is still a string and + joins the text instead. Line 4 assigns the cast result back into the same variable, so from then on distance really does hold an integer and line 5 adds two integers.

Where casting is useful

Python is a high-level language, and real programs use casting to control the data type used in one particular expression or assignment:

  • Doing arithmetic on text that holds digits but is still a string.
  • Turning a number into a string so it can be joined to a message with +.
  • Setting the data type for one expression or assignment while the rest of the program carries on using the variable as it was.

Casting with str() turns a value into a string of text. You put the value inside the brackets, and str() hands back a new text version of it that you can use straight away.

This matters because the + operator does two different jobs depending on data type. Given two strings it joins them together; given two numbers it adds them. Given one string and one number it can do neither, so the program stops with an error. Casting with str() makes both operands text, so + joins them and a number can appear inside a message.

Worked example: a school's locker booking program stores the number of free lockers in an integer variable called lockers, but it needs that count inside a sentence. Writing str(lockers) where the count is needed gives text such as "24", which + can attach to the rest of the message. The cast happens only where it is written, so lockers is still an integer and you can carry on adding and subtracting with it.

badge = "Visitor"
lockers = 24
print(badge + " can use " + str(lockers) + " lockers.")

Output:

Visitor can use 24 lockers.

str() accepts any value you give it, so a real number such as 2.5 becomes the text "2.5", keeping the decimal point as a character.

ExpressionWhat happens
"Free lockers: " + "24"Two strings, so they are joined: Free lockers: 24
"Free lockers: " + 24A string and a number, so the program stops with an error
"Free lockers: " + str(24)The number is cast first, then joined: Free lockers: 24
crew = "Ground staff"
gates = 6
print("Gates opened by " + crew + ": " + gates)

Output:

TypeError: can only concatenate str (not "int") to str (line 3)

int() and float() are casting functions. Each one takes a value and produces a value of the requested data type: int() gives an integer (a whole number), while float() gives a real number, written with a decimal point.

int() and truncation

Give int() a value that represents a whole number, such as the text "76", and you get that whole number back as an integer. Give it a real number and it truncates: the fractional part is cut off and only the whole number part is kept, so 9.75 becomes 9 and 12.99 becomes 12.

Truncating is not rounding. Rounding would push 12.99 up to 13, but int() simply removes everything after the decimal point, so it does not round up to the next whole number.

float() and real numbers

float() converts a value that represents a number into a real number. Text such as "18.5" becomes the real value 18.5, and an integer is rewritten with a decimal part, so float(45) gives 45.0. The size of the number stays the same; only its data type changes.

Converting between the two types

Starting valueint() of the valuefloat() of the value
"76"7676.0
9.7599.75
313131.0

The direction of the cast decides what happens. Real to integer gives a new integer value without the fractional part, because truncation throws it away. Integer to real keeps the same value and writes it with a decimal part.

race_time = 47.92
whole_seconds = int(race_time)
print(whole_seconds)
print(float(whole_seconds))

Output:

47
47.0

bool() is a casting function that turns a value into a Boolean, so the result is either True or False. It does not read the meaning of a value; it only checks whether the value is empty or zero.

Text values

Any string with at least one character gives True, even if the characters spell a word that means false. Only the empty string gives False.

ExpressionResultWhy
bool("x")TrueThe string has a character
bool("off")TrueThe string is not empty, even though it means off
bool("")FalseThe string is empty

bool() counts characters, so it cannot tell that "off" means not on.

Number values

Zero is the only number that gives False. Every other number gives True, whether it is positive or negative, whole or real.

  • bool(0) gives False
  • bool(-4) gives True
  • bool(0.0) gives False
  • bool(2.5) gives True

Getting a Boolean from text

Because bool() only checks whether text is empty, it cannot turn a label into False. Instead, compare the text with the wording you have decided means true: if the text matches, the comparison gives True, and if it does not, the comparison gives False.

switchSetting = "off"
lightsOn = switchSetting == "on"  # comparison gives a Boolean
print(lightsOn)
print(bool(switchSetting))
print(bool(""))
print(bool(0))

Output:

False
True
False
False

The comparison tests what the text means, so a setting of "off" is treated as not on. The bool() calls show the rule the other way round: any text at all counts as true, whatever it says.

A cast only works when the value makes sense as the new type. For int() the text must be a whole number such as "-12", and for float() it may also contain one decimal point. If the value cannot sensibly represent the target type, the program stops with an error rather than guessing what you meant.

For example, int("4,000") stops with an error because the comma is just formatting, not part of a Python number. float("4,000") also fails. In each case the program stops at that line, so nothing after it runs.

Strings that hold a decimal point

Text containing a decimal point is a valid real number but not a valid integer, so int("18.99") fails. The value is numeric, just not a whole number, and int() will not quietly chop the .99 off text for you.

The fix is a chained cast: cast the text to a real first, then cast that real to an integer. Written as one expression, int(float("18.99")) works from the inside out, giving 18.99 and then 18. Now that the value is a real number rather than text, int() can do its normal job of dropping the fractional part.

Casts on casts

A cast can be applied to the result of another cast, because each cast hands back an ordinary value of the new type. The rule is simply to work out the innermost cast first, then apply the next one to what it produced.

ExpressionInnermost cast givesResult
str(int(11.2))11"11"
float(int(12.8))1212.0
int(float("23.45"))23.4523

Chaining is useful when data arrives in the wrong type twice over, such as text holding a decimal that you need as a whole number for counting.

# Text with a decimal point needs two casts to become an integer
distance = "7.65"
whole_km = int(float(distance))
print(whole_km)
print(whole_km + 3)

# A failed cast stops the program part-way through
label = "7 km"
print(int(label))

Output:

7
10
ValueError: invalid literal for int() with base 10: '7 km' (line 9)

When an expression contains a cast, work through it in a fixed order: work out the cast first to produce a value of the new data type, then apply the operator using those resulting data types. The cast has to come first because an operator behaves differently depending on the types it is handed.

Take int("15") + 5. The cast is worked out first, turning the text into the integer 15. The expression is now 15 + 5, so both values are integers and + adds them to give 20. Leave the cast out and "15" + 5 tries to combine text with a number, which is not allowed, so the program stops with an error.

The same order applies to str(). In str(9) + " lives" the cast runs first and gives the string "9". Both values are now strings, so + joins them into "9 lives" instead of adding anything.

Worked through, step by step

ExpressionCast worked out firstWhat the operator then works onResult
int("23") - 62323 - 6 (two integers)17
float("0.75") * 80.750.75 * 8 (a real and an integer)6.0
str(9) + " lives""9""9" + " lives" (two strings)"9 lives"

One expression can hold more than one cast. In int("6") + float("2.25") each cast is worked out first, giving an integer 6 and a real 2.25. Adding an integer and a real gives a real, so the answer is 8.25.

# Each cast is worked out first, then the operator is applied
cost = int("7") * 5
print(cost)

label = str(3) + "rd"
print(label)

share = float("9") / 2
print(share)

Output:

35
3rd
4.5

Also useful