Algebra: Expressions and Factoring
Working with variables: the rules of algebra, expanding and factoring, special products, and fractions, roots and logarithms that contain variables.
Variables and expressions
Kestrel Energy's simplest tariff charges €0.27 per kWh plus a fixed €6.50 per month. For a customer who uses 200 kWh, the bill is 0.27 × 200 + 6.50 = €60.50. For 350 kWh it is 0.27 × 350 + 6.50 = €101.00. The calculation is the same every time; only the number of kWh changes. Algebra writes that changing number as a letter:
Here x is a variable: a name for a number, just like a variable in a program. A combination of numbers, variables and operations such as this one is an algebraic expression. It does not have a value by itself; it gets one when you fill in the variable. Filling in is called substitution:
- Replace every x by the value, in brackets: 0.27 · (200) + 6.50.
- Work it out with the order of operations: first 0.27 · 200 = 54, then 54 + 6.50 = 60.50.
In code, an expression with a variable is a function that takes the variable as its parameter:
def monthly_bill(kwh):
return 0.27 * kwh + 6.50 # the expression 0.27x + 6.50
for kwh in (200, 350):
print(f"{kwh} kWh: {monthly_bill(kwh):.2f} euros")
200 kWh: 60.50 euros 350 kWh: 101.00 euros
Terms, coefficients and like terms
An expression is built from terms, the parts that are added or subtracted. In 3x^2 - 5x + 7 the terms are 3x^2, -5x and 7. The number in front of a variable is its coefficient (3 and −5 here), and a term without a variable, such as 7, is a constant. Remember that 3x means 3 times x, and that x on its own has coefficient 1.
Terms with exactly the same variable part are like terms, and you can combine them by adding the coefficients, just as 3 apples plus 4 apples are 7 apples:
x and x^2 are not like terms either: x apples and x² apples are different things.
The rules of algebra
Everything in algebra rests on a few properties of numbers that you already use without thinking. Written with letters, they hold for every number you could fill in.
The commutative property says that the order does not matter for addition and multiplication:
The associative property says that the grouping does not matter for addition and multiplication, so you can leave the brackets out:
The distributive property connects multiplication and addition: multiplying a sum is the same as multiplying each part and adding the results.
A check with numbers: 3 \cdot (4 + 5) = 3 \cdot 9 = 27, and 3 \cdot 4 + 3 \cdot 5 = 12 + 15 = 27. You use this property in mental arithmetic all the time: 7 × 102 = 7 × 100 + 7 × 2 = 714.
When the computer breaks the rules
These rules hold for real numbers, but a computer's floating-point numbers are approximations, rounded after every operation. With floats, the grouping can change the result:
from fractions import Fraction
# Algebra rules hold for exact numbers, not always for floats
print((0.1 + 0.2) + 0.3 == 0.1 + (0.2 + 0.3))
print((0.1 + 0.2) + 0.3, 0.1 + (0.2 + 0.3))
a, b, c = Fraction("0.1"), Fraction("0.2"), Fraction("0.3")
print((a + b) + c == a + (b + c), (a + b) + c)
False 0.6000000000000001 0.6 True 3/5
The two groupings round differently, so they differ in the last
digit. With exact fractions the associative property holds again.
This is why adding up thousands of meter readings in a different
order can give a slightly different total, and why Python offers
math.fsum for accurate sums of floats.
Expanding brackets
Expanding means using the distributive property to write an expression without brackets.
A number or variable times a bracket
Multiply every term inside the bracket by what is in front of it:
- 4(x + 3) = 4 \cdot x + 4 \cdot 3 = 4x + 12.
- x(2x - 5) = x \cdot 2x - x \cdot 5 = 2x^2 - 5x (because x \cdot x = x^2).
- A minus sign in front of a bracket flips the sign of every term inside: -(x - 3) = -x + 3, and 10 - 2(x + 1) = 10 - 2x - 2 = 8 - 2x.
Two brackets
To multiply two brackets, multiply every term of the first by every term of the second, and add all the results. Worked example, (x + 3)(x + 2):
- Take the x from the first bracket and multiply it by both terms of the second: x \cdot x + x \cdot 2 = x^2 + 2x.
- Take the 3 from the first bracket and do the same: 3 \cdot x + 3 \cdot 2 = 3x + 6.
- Add everything: x^2 + 2x + 3x + 6.
- Combine the like terms 2x + 3x = 5x: the result is x^2 + 5x + 6.
Two terms times two terms always give four products before you combine. A quick way to check any expansion is to substitute a few numbers into both forms; they must agree for every value:
# Expanding and factoring give the same value for every x
for x in (-3, 0, 1, 7):
print(x, (x + 3) * (x + 2), x ** 2 + 5 * x + 6, 4 * x + 12, 4 * (x + 3))
-3 0 0 0 0 0 6 6 12 12 1 12 12 16 16 7 90 90 40 40
A few agreeing values do not prove that two expressions are equal, but a single disagreeing value proves that they are not. It is the same idea as a unit test.
Factoring
Factoring is expanding in reverse: you write a sum as a product. It is the algebra version of prime factorization, and it makes expressions easier to simplify, to compute and to solve.
Taking out a common factor
Look for something that every term contains, and put it in front of a bracket. Worked example, 6x^2 + 9x:
- The numbers 6 and 9 have the greatest common divisor 3.
- Both terms contain at least one x (6x^2 = 6 \cdot x \cdot x).
- So the common factor is 3x. Divide each term by it: \frac{6x^2}{3x} = 2x and \frac{9x}{3x} = 3.
- Result: 6x^2 + 9x = 3x(2x + 3). Check by expanding: 3x \cdot 2x + 3x \cdot 3 = 6x^2 + 9x.
An IT example: a cloud bill for a server is 0.12 per hour for compute plus 0.03 per hour for storage, for h hours. The total 0.12h + 0.03h factors as (0.12 + 0.03)h = 0.15h: one hourly rate, one multiplication.
Factoring a quadratic expression
The expansion of (x + 3)(x + 2) showed a pattern: the constant 6 is 3 × 2, and the middle coefficient 5 is 3 + 2. So to factor an expression like x^2 + 7x + 12, look for two numbers that multiply to the constant and add to the middle coefficient:
- Pairs that multiply to 12: 1 and 12, 2 and 6, 3 and 4 (and their negatives).
- Which pair adds to 7? 3 + 4 = 7.
- So x^2 + 7x + 12 = (x + 3)(x + 4).
- Check: x^2 + 4x + 3x + 12 = x^2 + 7x + 12.
With negative numbers it works the same way: x^2 - x - 6 needs two numbers with product −6 and sum −1, which are −3 and 2, so it equals (x - 3)(x + 2). Factored forms are what you need to solve quadratic equations, on the equations page.
Special products
Three products come up so often that it pays to recognize them on sight. Each such special product is an ordinary two-bracket expansion with a fixed result:
Worked example for the first one, expanding (a + b)^2 = (a + b)(a + b) step by step:
- a \cdot a + a \cdot b + b \cdot a + b \cdot b.
- a \cdot b and b \cdot a are the same (commutative property), so together they are 2ab.
- Result: a^2 + 2ab + b^2.
In the third product the middle terms cancel: (a + b)(a - b) = a^2 - ab + ab - b^2 = a^2 - b^2. The picture below shows the first identity as areas.
The third product makes some mental arithmetic easy. 51 × 49 is (50 + 1)(50 − 1) = 50² − 1² = 2,500 − 1 = 2,499. Python confirms the identities for every pair of whole numbers from −20 to 20:
# Check special products for a range of whole numbers
ok = all((a + b) ** 2 == a * a + 2 * a * b + b * b
and (a - b) ** 2 == a * a - 2 * a * b + b * b
and (a + b) * (a - b) == a * a - b * b
for a in range(-20, 21) for b in range(-20, 21))
print(ok)
print(51 * 49, 50 ** 2 - 1 ** 2)
print((3 + 4) ** 2, 3 ** 2 + 4 ** 2)
True 2499 2499 49 25
Read from right to left, the special products are factoring tools: x^2 - 9 = (x + 3)(x - 3) and x^2 + 10x + 25 = (x + 5)^2.
Fractions with variables
Fractions with variables follow the same rules as fractions of numbers. The rule that causes the most trouble is simplifying: you may divide the top and the bottom by the same factor, something that multiplies the whole top and the whole bottom.
- \frac{6x}{3} = 2x: 3 is a factor of the whole top (6x = 3 · 2x).
- \frac{x^2 + 3x}{x} = \frac{x(x + 3)}{x} = x + 3, for x ≠ 0: factor first, then divide out the common factor x.
- \frac{x + 2}{2} cannot be simplified to x + 1: the 2 on top is a term, not a factor. Split the fraction instead: \frac{x + 2}{2} = \frac{x}{2} + \frac{2}{2} = \frac{x}{2} + 1.
Adding fractions with variables also needs a common denominator. Worked example, \frac{1}{x} + \frac{1}{x + 1}:
- A common denominator is the product x(x + 1).
- Rewrite each fraction: \frac{1}{x} = \frac{x + 1}{x(x + 1)} and \frac{1}{x + 1} = \frac{x}{x(x + 1)}.
- Add the tops: \frac{x + 1 + x}{x(x + 1)} = \frac{2x + 1}{x(x + 1)}.
from fractions import Fraction
x = 4
print(Fraction(x + 2, 2), Fraction(x, 2) + 1, x + 1)
# 1/x + 1/(x + 1) = (2x + 1) / (x(x + 1))
print(Fraction(1, x) + Fraction(1, x + 1), Fraction(2 * x + 1, x * (x + 1)))
3 3 5 9/20 9/20
A formula of this shape appears in IT, too: two servers that each handle a batch alone in x and x + 1 hours together handle \frac{1}{x} + \frac{1}{x + 1} batches per hour.
Roots and logarithms with variables
The exponent rules and logarithm rules work with variables exactly as with numbers:
One subtle case: \sqrt{x^2} is not always x. For x = −3, \sqrt{(-3)^2} = \sqrt{9} = 3. The square root is never negative, so the correct rule is \sqrt{x^2} = |x|, the absolute value.
Where an expression is defined
With numbers you see straight away whether a calculation is possible. With variables you have to ask: for which values of x does this expression have a value? Three rules cover almost everything:
- A denominator must not be 0. \frac{1}{x - 2} needs x \ne 2.
- An even root needs a number that is at least 0. \sqrt{x - 3} needs x \ge 3.
- A logarithm needs a number greater than 0. \log_2 (x - 2) needs x \gt 2.
A program meets the same limits, and fails at runtime when a value breaks one of them. Here three expressions are evaluated for three values of x; for x = 2 the square root of −1 fails first:
import math
for x in (4, 3, 2):
try:
print(x, math.sqrt(x - 3), 1 / (x - 2), math.log(x - 2))
except (ValueError, ZeroDivisionError) as error:
print(x, type(error).__name__, error)
4 1.0 0.5 0.6931471805599453 3 0.0 1.0 0.0 2 ValueError math domain error
Python's "math domain error" uses the mathematical word for the set of allowed inputs: the domain. Writing down where an expression is defined, before you code it, tells you which inputs to validate or test. The functions page treats domains in full.