<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Python Basics
Unit 3, Lecture 2
Numerical Methods and Statistics
Prof. Andrew White, February 6, 2018
Suggested Reading
https
Step1:  A 'decimal' in binary is challenging to think about, because each integer location is a $1 / 2^{n}$, where $n$ is the location. That means to represent a binary-mantissa exacly, its denominator must be a power of $2$. For example
Step2:  Do not use == with floats!
Using Functions and Modules
Step3:  Imports and Modules
Try typing math.fa and hit TAB in ipython notebook. You should see suggestions. Next, type math.fabs( and hit TAB and ipython notebook will tell you what the function does.
Step4:  Boolean Logic
Step5:  Boolean Logic uses Short-Circuiting - only as much as necessary is evaluated.
Step6:  Flow with Boolean
You can make code only accessible if a condition is true with if. You can also use else and elif for alternatives.
To indicate where your if code is located, press tab (which adds 4 spaces).
Step7:  Full list of boolean operators
Here are the boolean operators
Step8:  is None is special case. None is used as a "sentinel" value to indicate if something is not ready or invalid.
Step9:  Default Boolean - Don't Rely on this!
Just to be aware of, Python has a way of checking if an object is False based on its value (0 or None).
Step10:  It is better to just be explicit and give a full boolean expression. You'll most often see these used by accident
Floating Point Boolean
Step11:  The solution?
Only use &lt;, &gt;. Never use == with boolean
Step12:  Lists
In python, groups of values can be stored together into lists, which are like groups of variables.
Step13:  Individual elements can be accessed with []. The thing that goes inside the brackets is called the index. Recall that python starts counting from 0
Step14:  Slicing Lists
You can access multiple elements with the 
Step15:  The last element to the slice operator is not inclusive, so 0
Step16:  If it's more convienent, you can count backwards from the end of the list by using negative indices. The trick is that -0 is not really a thing, so the last element in the list is -1.
Step17:  The index arguments to a slice are optional.
Step18:  You can add a third argument by adding another 
Step19:  The other slicing indices are optional.
Step20:  Using a negative stepsize allows you to count downwards
Step21:  Note that we still include the first slice index (4), but not the second one (0).  
A common idiom is to reverse the order of list this way
Step22:  Notice that Python was clever and knew with a step-size of -1, we actually wanted to start at the far end and count downwards.
List Functions
Generally, most functions (like cos) do not take a list. One common function that we need is len, which returns the length of a list.
<ASSISTANT_TASK:>
Python Code:
from IPython.display import Math
from math import frexp, pi
import math
    
#Convert a float into its mantissa and exponent and print as LaTeX
def fprint(x):
    m,e = frexp(x)
    return Math('{:4} \\times 2^{{{:}}}'.format(m, int(e)))
#Convert a mantissa from decimal to binary and print as LaTeX
def ffrac_ltx(x, terms=10):
    bits = []
    exp = 1
    latex = ''
    while x > 0 and exp < terms:
        bits.append(int(x / 2.0 ** -exp))
        x -= bits[-1] * 2.0 ** -exp
        latex += '\\frac{{ {} }}{{ 2^{{ {} }} }} + '.format(bits[-1], exp)
        exp += 1
    return Math(latex[:-3] + ' = {}'.format(sum([b * 2**-i for b,i in zip(bits,range(1,exp))])))
def ffrac(x, terms=10):
    bits = []
    exp = 1
    while x > 0 and exp < terms:
        bits.append(int(x / 2.0 ** -exp))
        x -= bits[-1] * 2.0 ** -exp
        exp += 1
    return ''.join(['{}'.format(x) for x in bits])
fprint(4.3)
fprint(0.1)
fprint(pi)
Explanation: Python Basics
Unit 3, Lecture 2
Numerical Methods and Statistics
Prof. Andrew White, February 6, 2018
Suggested Reading
https://docs.python.org/3.6/tutorial/
https://en.wikipedia.org/wiki/Floating-point_arithmetic#Floating-point_numbers
Floating Point Representation
Floating point numbers are represented with a mantissa and exponent:
$$\underbrace{0.3423}{\textrm{mantissa}}\times{}\underbrace{10^{-2}}{\textrm{exponent}}$$
We are working with computers though, so the mantissa is a binary and the exponent is in powers of 2. Let's look at them as decimals to begin though.
End of explanation
ffrac_ltx(0.5)
ffrac_ltx(0.75)
ffrac_ltx(0.5232)
#This is the maximum number of bits used in the 0.1 Mantissa as a string.
print(ffrac(0.1, 100))
print('{:0.28f}'.format(0.1))
0.1 + 0.2 == (1.0 + 2.0) / 10.0
Explanation: A 'decimal' in binary is challenging to think about, because each integer location is a $1 / 2^{n}$, where $n$ is the location. That means to represent a binary-mantissa exacly, its denominator must be a power of $2$. For example:
End of explanation
print(abs(-43))
x = -5
x = abs(x)
print(x)
Explanation: Do not use == with floats!
Using Functions and Modules
End of explanation
from math import fabs
print(fabs(-4.34322))
from math import fabs, sin, cos
print(fabs(sin(4) * cos(43.)))
from math import *
print(e)
Explanation: Imports and Modules
Try typing math.fa and hit TAB in ipython notebook. You should see suggestions. Next, type math.fabs( and hit TAB and ipython notebook will tell you what the function does.
End of explanation
print(2 == 5)
a = 3
print(a == 3)
print(a <= 0)
print(a > 0 and a < 4)
Explanation: Boolean Logic
End of explanation
print(True or 1 / 0.)
print(True and 1 / 0.)
Explanation: Boolean Logic uses Short-Circuiting - only as much as necessary is evaluated.
End of explanation
x = 65
if x > 43:
    print('Surprise! {} is greater than 43'.format(x))
x = 54
if x < 0:
    print('{} is negative'.format(x))
elif x > 0:
    print('{} is positive'.format(x))
else:
    print('{} is 0'.format(x))
x = -32
if x < 0:
    if abs(x) > 5:
        print('{} is less than 0 and has magnitude greater than 5'.format(x))
    else:
        print('{} is not interesting'.format(x))
        
#or you can do:
if x < 0 and abs(x) > 5:
  print('{} is less than 0 and has magnitude greater than 5'.format(x))
if x < 0 and not abs(x) > 5:
        print('{} is not interesting'.format(x))
Explanation: Flow with Boolean
You can make code only accessible if a condition is true with if. You can also use else and elif for alternatives.
To indicate where your if code is located, press tab (which adds 4 spaces).
End of explanation
a = 28238
b = 28238
print(a is b, a == b)
a = b
print(a is b)
Explanation: Full list of boolean operators
Here are the boolean operators: &gt;, &lt;, &gt;=, &lt;=, ==, !=, is
Recall our keywords from Lecture 1: and, or, and not
is is used to see if a variables is None or if two variables point to the same memory address.
End of explanation
var = None
print(var is None)
a = 43
b = 23
print(a != b)
Explanation: is None is special case. None is used as a "sentinel" value to indicate if something is not ready or invalid.
End of explanation
x = 1
if(x):
    print('True')
else:
    print('False')
x = None
if(x):
    print('True')
else:
    print('False')
x = 'Hello'
if(x):
    print('True')
else:
    print('False')
x = ''
if(x):
    print('True')
else:
    print('False')
x = math.sin(0.0)
if(x):
    print('True')
else:
    print('False')
Explanation: Default Boolean - Don't Rely on this!
Just to be aware of, Python has a way of checking if an object is False based on its value (0 or None).
End of explanation
x = 0.15 + 0.15
y = 0.1 + 0.2
print(x == y)
Explanation: It is better to just be explicit and give a full boolean expression. You'll most often see these used by accident
Floating Point Boolean
End of explanation
x = 0.15 + 0.15
y = 0.1 + 0.2
abs(x - y) < 10**-8
Explanation: The solution?
Only use &lt;, &gt;. Never use == with boolean
End of explanation
numbers = [4,7,24,11,2]
print(numbers)
Explanation: Lists
In python, groups of values can be stored together into lists, which are like groups of variables.
End of explanation
print(numbers[0], numbers[1])
Explanation: Individual elements can be accessed with []. The thing that goes inside the brackets is called the index. Recall that python starts counting from 0
End of explanation
print(numbers[0:3])
Explanation: Slicing Lists
You can access multiple elements with the : symbol, which is called slicing.
End of explanation
numbers[2:5]
Explanation: The last element to the slice operator is not inclusive, so 0:3 means 0, 1, 2. Why? Becuase you expect $3 - 0$ elements, which is three, starting from the $0$ index.
End of explanation
print(numbers)
print(numbers[-1], numbers[-2])
Explanation: If it's more convienent, you can count backwards from the end of the list by using negative indices. The trick is that -0 is not really a thing, so the last element in the list is -1.
End of explanation
print(numbers[:4])
print(numbers)
print(numbers[:-1])
print(numbers[3:])
print(numbers[-3:])
Explanation: The index arguments to a slice are optional.
End of explanation
print(numbers)
print(numbers[0:-1:2])
Explanation: You can add a third argument by adding another : It is the step-size.
End of explanation
print(numbers[0::2])
print(numbers)
print(numbers[::2])
print(numbers[2::2])
Explanation: The other slicing indices are optional.
End of explanation
print(numbers[4:0:-1])
Explanation: Using a negative stepsize allows you to count downwards
End of explanation
print(numbers, numbers[::-1])
Explanation: Note that we still include the first slice index (4), but not the second one (0).  
A common idiom is to reverse the order of list this way:
End of explanation
x = range(100)
len(x)
x = range(10)
print(max(x))
import math
math.cos(x)
Explanation: Notice that Python was clever and knew with a step-size of -1, we actually wanted to start at the far end and count downwards.
List Functions
Generally, most functions (like cos) do not take a list. One common function that we need is len, which returns the length of a list.
End of explanation
<END_TASK>