# Notes On Python: Truth and Modulo

Today I learnt how to be less verbose when using the `%`

operator in Python.

**SPOILER:** I learnt this while trying to apply a functional approach to the first problem on Project Euler and I describe my answer here.

So, to set the scene, the first problem on Project Euler is presented as such:

*“If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.*

*Find the sum of all the multiples of 3 or 5 below 1000.”*

I initially answered this with the following function:

```
def sum_mul_three_five(end_num):
"""
Returns the sum of all the multiples of 3 or 5 below end_num
"""
total = []
for num in range(end_num):
if num % 3 == 0 or num % 5 == 0:
total.append(num)
return sum(total)
```

This code is pretty self-explanatory, but the line I want to focus on is the `if`

statement. The `%`

operator returns the remainder of a division, and is popularly used in Python for such things as sorting even numbers.
For instance:

```
>>> numbers = range(10)
>>> numbers
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in numbers:
... if number % 2 == 0:
... print number
...
0
2
4
6
8
```

Here we iterate through a simple list of numbers. The `if`

statement uses the `%`

operator to check what the remainder will be when each number is divided by `2`

. If there is no remainder, ie. the result is `0`

then the number is equally divided by `2`

and therefore `even`

…

```
>>> for number in range(10):
... if number % 2 == 0:
... print "%d is even" % number
... else:
... print "%d is odd" % number
...
0 is even
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
```

So, in my solution for Project Euler I am using `%`

to test whether each number is divisible by 3 or 5. When I tried to refactor this with a more Functional approach using a list comprehension, I got this long mess:

```
def sum_mul_three_five(end_num):
"""
Returns the sum of all the multiples of 3 or 5 below end_num
"""
total = []
[total.append(num) for num in range(end_num) if num % 3 == 0 or num % 5 == 0]
return sum(total)
```

*Eeek!* As I have been told, while this works, it’s probably the wrong way. What I didn’t realise is that we can be more concise with the modulo statements, and use them as a `True/False`

test. This is because `0`

and `1`

, the two results we can get from using `%`

, equate to `False`

and `True`

respectively.

** EDIT** See Below…

This may seem simple but it’s perhaps overlooked when learning Python, especially for those without a CS background, such as myself, or perhaps my view of the wood was blocked by the trees.

```
>>> 1 == True
True
>>> 0 == False
True
```

Therefore `if num % 3 == 0`

is specifying the condition is met when the remainder of dividing a number by 3 is `0`

, which also corresponds to `False`

, or `not True`

.

```
>>> 0 != True
True
>>> 1 != True
False
```

Now, the `if`

condition of an `if/else`

conditional expression is met when the condition is `True`

, or `not False`

. This is where my mind started to fold over into itself. So, to return the numbers divisible by `3`

in an `if`

statement the result needs to be `True`

, whereas with `%`

it is `False`

…

```
>>> for number in range(10):
... if number % 3:
... print number
...
1
2
4
5
7
8
>>> for number in range(10):
... if not number % 3:
... print number
...
0
3
6
9
```

Basically we’re replacing `== 0`

with the concept of `True`

and `False`

, which ends up as this:

```
def sum_mul_three_five(end_num):
"""
Returns the sum of all the multiples of 3 or 5 below end_num
"""
total = []
[total.append(num) for num in range(end_num) if not num % 3 or not num % 5]
return sum(total)
```

Which is saying *return the number if it is not True, ie. False*, a condition met when the remainder is

`0`

when the number is divided by `3`

.Though this is still a bit ugly, so let’s simplify the rest a bit…

```
def sum_mul_three_five(end_num):
"""
Returns the sum of all the multiples of 3 or 5 below end_num
"""
return sum([num for num in range(end_num) if not num % 3 or not num % 5])
```

Ahh yes ain’t that fresh. Everybody wants to get down like that.

I think that makes sense, I hope it does.

** EDIT** Ok, so I totally overlooked that the result of

`%`

isn’t restricted to `0`

or `1`

, so this example is perhaps not as black and white as I first believed.```
>>> for number in range(10):
... print number % 2
...
0
1
0
1
0
1
0
1
0
1
>>> for number in range(10):
... print number % 3
...
0
1
2
0
1
2
0
1
2
0
>>> for number in range(10):
... print number % 5
...
0
1
2
3
4
0
1
2
3
4
```

So, what happens with remainders that aren’t `0`

or `1`

? Well, they are interpreted as `False`

in this case

```
>>> for number in range(10):
... if number % 3:
... print "False: \tNumber: %d \tRemainder: %d" % (number, number % 3)
... else:
... print "True: \tNumber: %d \tRemainder: %d" % (number, number % 3)
...
True: Number: 0 Remainder: 0
False: Number: 1 Remainder: 1
False: Number: 2 Remainder: 2
True: Number: 3 Remainder: 0
False: Number: 4 Remainder: 1
False: Number: 5 Remainder: 2
True: Number: 6 Remainder: 0
False: Number: 7 Remainder: 1
False: Number: 8 Remainder: 2
True: Number: 9 Remainder: 0
```

I have to admit, this hasn’t totally clicked in my brain yet. I mean, I get it, but the whole *is it True, is it False?* thing is a little hard to keep track of y’know.