Conditionals and recursion - here we go!

### Tools for Booleans

Python seems to have a large desire/need to utilize the **modulus operator** (%, that determines the remainder after division).

It's easy to forget that **boolean expressions** return the value of the equality (a bool). Don't forget this because it can help save some LOC's. Also, Python uses the following relation operators:

- x != y
- x > y
- x < y
- x >= y
- x <= y

The greater than or equals to and less than or equals to, must be in that order (eg. =< will not work).

Python makes use of logical operators (and, or, and not) like most any other language. Where one might get tripped up is if you tried to use `not`

on an integer.

```
#Examples of logical operators with non-bool terms
>>> 17 and True
True
>>> not 12
False
>>> not 0
True
```

### Looping

While loops seem to be a more intelligent method for recursion in Python. They seem less likely to result in an infinite loop. In order to break a loop, one needs only to make the while condition false or use the `break`

keyword in the loop under some condition.

We can also use these loops to recursively guess and check answers to complex mathematical questions, like calculating a square root. Using newton's method we can estimate a square root recursively:

```
# We are trying to find the square root of 'a'
# x is our guess
# y is our output/new input for the next loop
while True:
print x
y = (x + a/x) / 2
if y == x:
break
x = y
```

This works nicely, but that won't always be the case. Comparing floats can be questionable, and you'd be better off checking the difference between the old and new guesses. If you've written your **algorithm** correctly, then a small delta will mean we've reached some asymtote, or an approx answer.

### Worksheet 3.1.1

This was a little strange and even the instructor says that comparing functions was new to them! Alas, I knew the output, regardless of the comparison for the last question would be a function, so it passed by checker!

### Worksheet 3.1.2, 3.1.3, 3.1.4

Nothing surprising here, just some basic conditionals...zZzZzZ

### Worksheet 3.1.5

Now this was a bit of a challenge. More a math challenge, than a programming challenge but the two are rather intertwined so it was worth considering.

To start, one must consider that the objective is to return the middle value of the given 3 numbers. In order words, NOT the minimum or maximum. From there, you can try to parse your 3 numbers down to the two lower of the two. You do that by comparing all 3 possibles sets of 2 (lo/x, x/hi, lo/hi). This will give you the lowest number and the 2nd lowest number. Next, you simply find the highest number of this subset, which also happens to be the middle number.

Thank god for writing the test cases other the previous problemset because this would have been a nightmare to verify manually!

### Worksheet 3.2.1

Python is just the worst (or is it the best?) with numbers. I keep ending up with 0.0000000000001 differences in my solution. This made sense to me during division but this was addition. I'll need to look into exactly how Python does math. Well, I couldn't possibly explain this better than Stack Overflow so check them out and don't miss the comic in the comments! TL;DClick: It's a combination of some internet standard and truncation that computers perform when it meets that standard.

### Worksheet 3.2.2

Another math function to rebuild! I suppose it's educational to think about all the work that goes into such basic functions as those loaded by the Math module. The trick to this one being that you can pass in a negative to the iterative loops first argument (the one that adds up) but not the second argument (the one that determines the number of times you add).

### Worksheet 3.2.3, 3.2.4, 3.2.5, 3.26, 3.2.7

Nothing very interesting - more basic math functions.

As usual the solutions can be found on github