# Why Algebra?

Algebra is study of mathematical symbols (you might have seen: x, y, θ) and the rules for manipulating them. We most often use algebra to express relatioships between things (the symbols) and numbers.

But do we really need algebra? Can we just get along without it? Those symbols and all those rules are really confusing at first, is it worth the effort to learn them?

Here’s a real life example…

A bike hire shop could set the cost of renting a bike as a fixed cost plus an amount per day that the bike is rented. We could use algebra to work out costs for different customers or we could just have a big table of all the possible hire options and costs.

Let’s use Lego and a bit of Python programming to find out…

If you don’t have Python installed, head over to Repl.it to try it online. Also check out The Little Pythoner to learn the basics.

## Building Pyramids

Imagine you are building a pyramid from lego cubes (the ones with 4 studs on top). How many blocks do you need to find for each level?

How would we work this out? Well it depends upon how high the pyramid is. Let’s say we were building a little pyramid, 5 levels high. It would look like this from the side:

```
5 *
4 * *
3 * * *
2 * * * *
1 * * * * *
```

Level 1, the first level has 5 blocks by 5 blocks, which is 25.

So in answer to the question: how many blocks for each level:

```
1 → 25
2 → 16
3 → 9
4 → 4
5 → 1
```

This is called a mapping: a sequence of numbers and their results.

We can turn this mapping into a Python function so that we can play with it and try out different versions. Just like the mapping above, we want our function to return the number of blocks we need for each level for a 5 level pyramid:

```
def pyramid_blocks(level):
mapping = { 1: 25,
2: 16,
3: 9,
4: 4,
5: 1 }
return mapping[level]
```

This function is a bit tedious to type in, but it is fairly easy to see that it does the same thing as the mapping above. Plus we’ve not had to use any algebra.

You can use it like this:

```
>>> pyramid_blocks(1)
1
>>> pyramid_blocks(3)
9
```

How about if we wanted to build a 10 level pyramid? How would we change the function to accommodate this? Well we know that the first level would require more bricks. Let’s draw it first:

```
10 *
9 * *
8 * * *
7 * * * *
6 * * * * *
5 * * * * * *
4 * * * * * * *
3 * * * * * * * *
2 * * * * * * * * *
1 * * * * * * * * * *
```

OK, so our new function looks like this:

```
def pyramid_blocks(level):
mapping = { 1: 100,
2: 81,
3: 64,
4: 49,
5: 36,
6: 25,
7: 16,
8: 9,
9: 4,
10: 1}
return mapping[level]
```

However, now that function only works for 10 high pyramids, how would we get it to work for both?

We could pass in the height and use another if-statement like this:

```
def pyramid_blocks(level, height):
if height == 5:
mapping = { 1: 25,
2: 16,
3: 9,
4: 4,
5: 1 }
return mapping[level]
elif height == 10:
mapping = { 1: 100,
2: 81,
3: 64,
4: 49,
5: 36,
6: 25,
7: 16,
8: 9,
9: 4,
10: 1}
return mapping[level]
```

OK, so I think we can see that this approach is not going to work if we keep changing the pyramid size – it’s a lot of typing and we have to change it each time we want to build a different size pyramid.

Surely we can do better?

We can, using algebra!

## Introducing algebra

Algebra allows us to express answers in terms of relationships with other numbers. So we can express how many blocks in terms of the level and the height of the pyramid.

The challenge is this: What’s the relationship between the level, the height and the number of blocks?

Let’s start with the first function we wrote:

```
def pyramid_blocks(level):
mapping = { 1: 25,
2: 16,
3: 9,
4: 4,
5: 1 }
return mapping[level]
```

Those numbers 25, 16, 9, 4 and 1 are actually square numbers (makes sense since we’re building squares), so we can rewrite this function using this knowledge:

```
def pyramid_blocks(level):
mapping = { 1: 5*5,
2: 4*4,
3: 3*3,
4: 2*2,
5: 1*1 }
return mapping[level]
```

Now we can see a relationship between the level and square number – the level runs from 1 to 5 and the width of the square runs from 5 to 1, so we can further improve the function to this:

```
def pyramid_blocks(level):
width = 6-level
return width * width
```

Let’s test it:

```
>>> pyramid_blocks(3)
9
>>> pyramid_blocks(1)
25
```

Great stuff! Our new function produces the correct results.

OK so now let’s adapt this for different heights. Let’s start with the really long function we had before, but with the algebra we’ve worked out already:

```
def pyramid_blocks(level, height=5):
if height == 5:
width = 6-level
return width * width
elif height == 10:
mapping = { 1: 10*10,
2: 9*9,
3: 8*8,
4: 7*8,
5: 6*6,
6: 5*5,
7: 4*4,
8: 3*3,
9: 2*2,
10: 1*1}
return mapping[level]
```

We can see a very similar (inverse) relationship as we saw before when height was 5: this time level runs from 1 to 10, and the width of the square runs from 10 to 1, so we can rewrite again:

```
def pyramid_blocks(level, height):
if height == 5:
width = 6-level
return width * width
elif height == 10:
width = 11-level
return width * width
```

Those return statements are the same so we can simplify a bit more:

```
def pyramid_blocks(level, height):
if height == 5:
width = 6-level
elif height == 10:
width = 11-level
return width * width
```

This function still only works for 2 pyramids: 5 and 10 blocks high. However there’s one simple change we can make to make it work for any height. Can you see the relationship between height and how we calculate the width? The number is simply height + 1.

Here is the final function:

```
def pyramid_blocks(level, height):
width = height + 1 - level
return width * width
```

Now we have a function that works for any height pyramid we want to build, and it is only two lines long.

Let’s test it:

```
>>> pyramid_blocks(3,5)
9
>>> pyramid_blocks(1,5)
25
>>> pyramid_blocks(3,10)
64
>>> pyramid_blocks(1,10)
100
>>> pyramid_blocks(1,100)
10000
>>> pyramid_blocks(50,100)
2601
```

Finally let’s express that function using algebra:

b = ( h + 1 - l )

^{2}where b is the number of blocks, h is height, l is level

Algebra allows us to express concisely the relationship between the number of blocks we need, the height and the level we’re building, which is much simpler to express than providing a list of all the possible values, as we did in our first attempts.

## What next?

Here are some interesting questions to explore:

- How would this algebra work in Minecraft?
- What if you were building hollow pyramids?
- What about a roof for a house (a triangular prism)?