<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 A jupyter notebook is a browser-based environment that integrates
Step1:  Create a variable
Step2:  Print out the value of the variable
Step3:  or even easier
Step4:  Datatypes
In computer programming, a data type is a classification identifying one of various types that data
can have. 
The most common data type we will see in this class are
Step5:  NumPy (Numerical Python) is the fundamental package for scientific computing with Python.
Load the numpy library
Step6:  pi and e are  built-in constants
Step7:  Here is a link to all Numpy math functions.
Arrays
Each element of the array has a Value
The position of each Value is called its Index
Our basic unit will be the NumPy array
Step8:  Indexing
Step9:  Slices
x[start
Step10:  There are lots of different methods that can be applied to a NumPy array
Step11:  Help about a function
Step12:  NumPy math works over an entire array
Step13:  Masking - The key to fast programs
Step14:  Fancy masking
Step15:  Sorting
Step16:  Control Flow
Like all computer languages, Python supports the standard types of control flows including
Step17:  For loops are different in python.
You do not need to specify the beginning and end values of the loop
Step18:  Loops are slow in Python. Do not use them if you do not have to!
Step19:  Functions
In computer science, a function (also called a procedure, method, subroutine, or routine) is a portion
of code within a larger program that performs a specific task and is relatively independent of the
remaining code. The big advantage of a function is that it breaks a program into smaller, easier
to understand pieces. It also makes debugging easier. A function can also be reused in another
program.
The basic idea of a function is that it will take various values, do something with them, and return a result. The variables in a function are local. That means that they do not affect anything outside the function.
Below is a simple example of a function that solves the equation
Step20:  The results of one function can be used as the input to another function
Step21:  Creating Arrays
Numpy has a wide variety of ways of creating arrays
<ASSISTANT_TASK:>
Python Code:
print("Hello World!")
# lines that begin with a # are treated as comment lines and not executed
# print("This line is not printed")
print("This line is printed")
Explanation: A jupyter notebook is a browser-based environment that integrates:
A Kernel (python)
Text
Executable code
Plots and images
Rendered mathematical equations
Cell
The basic unit of a jupyter notebook is a cell. A cell can contain any of the above elements. 
In a notebook, to run a cell of code, hit Shift-Enter. This executes the cell and puts the cursor in the next cell below, or makes a new one if you are at the end.  Alternately, you can use:
Alt-Enter to force the creation of a new cell unconditionally (useful when inserting new content in the middle of an existing notebook).
Control-Enter executes the cell and keeps the cursor in the same cell, useful for quick experimentation of snippets that you don't need to keep permanently.
Hello World
End of explanation
g = 3.0 * 2.0
Explanation: Create a variable
End of explanation
print(g)
Explanation: Print out the value of the variable
End of explanation
g
Explanation: or even easier:
End of explanation
a = 1
b = 2.3
c = 2.3e4
d = True
e = "Spam"
type(a), type(b), type(c), type(d), type(e)
a + b, type(a + b)
c + d, type(c + d)    # True = 1
a + e
str(a) + e
Explanation: Datatypes
In computer programming, a data type is a classification identifying one of various types that data
can have. 
The most common data type we will see in this class are:
Integers (int): Integers are the classic cardinal numbers: ... -3, -2, -1, 0, 1, 2, 3, 4, ...
Floating Point (float): Floating Point are numbers with a decimal point: 1.2, 34.98, -67,23354435, ...
Floating point values can also be expressed in scientific notation: 1e3 = 1000
Booleans (bool): Booleans types can only have one of two values: True or False. In many languages 0 is considered False, and any other value is considered True.
Strings (str): Strings can be composed of one or more characters: ’a’, ’spam’, ’spam spam eggs and spam’. Usually quotes (’) are used to specify a string. For example ’12’ would refer to the string, not the integer.
Collections of Data Types
Scalar: A single value of any data type.
List: A collection of values. May be mixed data types. (1, 2.34, ’Spam’, True) including lists of lists: (1, (1,2,3), (3,4))
Array: A collection of values. Must be same data type. [1,2,3,4] or [1.2, 4.5, 2.6] or [True, False, False] or [’Spam’, ’Eggs’, ’Spam’]
Matrix: A multi-dimensional array: [[1,2], [3,4]] (an array of arrays).
End of explanation
import numpy as np
Explanation: NumPy (Numerical Python) is the fundamental package for scientific computing with Python.
Load the numpy library:
End of explanation
np.pi, np.e
Explanation: pi and e are  built-in constants:
End of explanation
np.random.seed(42)                 # set the seed - everyone gets the same random numbers
x = np.random.randint(1,10,20)     # 20 random ints between 1 and 10
x
Explanation: Here is a link to all Numpy math functions.
Arrays
Each element of the array has a Value
The position of each Value is called its Index
Our basic unit will be the NumPy array
End of explanation
x[0]    # The Value at Index = 0
x[-1]    # The last Value in the array x
Explanation: Indexing
End of explanation
x
x[0:4]           # first 4 items
x[:4]            # same
x[0:4:2]         # first four item, step = 2
x[3::-1]         # first four items backwards, step = -1
x[::-1]          # Reverse the array x
print(x[-5:])    # last 5 elements of the array x
Explanation: Slices
x[start:stop:step]
start is the first Index that you want [default = first element]
stop  is the first Index that you do not want [default = last element]
step  defines size of step and whether you are moving forwards (positive) or backwards (negative) [default = 1]
End of explanation
x.size                   # Number of elements in x
x.mean()                 # Average of the elements in x
x.sum()                  # Total of the elements in x
x[-5:].sum()              # Total of last 5 elements in x
x.cumsum()                # Cumulative sum
x.cumsum()/x.sum()        # Cumulative percentage
x.
Explanation: There are lots of different methods that can be applied to a NumPy array
End of explanation
?x.min
Explanation: Help about a function:
End of explanation
y = x * 2
y
sin(x)     # need to Numpy's math functions
np.sin(x)
Explanation: NumPy math works over an entire array:
End of explanation
mask1 = np.where(x>5)
x, mask1
x[mask1], y[mask1]
mask2 = np.where((x>3) & (x<7))
x[mask2]
Explanation: Masking - The key to fast programs
End of explanation
mask3 = np.where(x >= 8)
x[mask3]
# Set all values of x that match mask3 to 0
x[mask3] = 0
x
mask4 = np.where(x != 0)
mask4
#Add 10 to every value of x that matches mask4:
x[mask4] += 100
x
Explanation: Fancy masking
End of explanation
np.random.seed(13)                 # set the seed - everyone gets the same random numbers
z = np.random.randint(1,10,20)     # 20 random ints between 1 and 10
z
np.sort(z)
np.sort(z)[0:4]
# Returns the indices that would sort an array
np.argsort(z)
z, z[np.argsort(z)]
maskS = np.argsort(z)
z, z[maskS]
Explanation: Sorting
End of explanation
xx = -1
if xx > 0:
    print("This number is positive")
else:
    print("This number is NOT positive")
xx = 0
if xx > 0:
    print("This number is positive")
elif xx == 0:
    print("This number is zero")
else:
    print("This number is negative")
Explanation: Control Flow
Like all computer languages, Python supports the standard types of control flows including:
IF statements
FOR loops
End of explanation
z
for value in z:
    print(value)
for idx,val in enumerate(z):
    print(idx,val)
for idx,val in enumerate(z):
    if (val > 5):
        z[idx] = 0
for idx,val in enumerate(z):
    print(idx,val)
Explanation: For loops are different in python.
You do not need to specify the beginning and end values of the loop
End of explanation
np.random.seed(42)
BigZ = np.random.random(10000)    # 10,000 value array
BigZ[:10]
# This is slow!
for Idx,Val in enumerate(BigZ):
    if (Val > 0.5):
        BigZ[Idx] = 0
BigZ[:10]
%%timeit
for Idx,Val in enumerate(BigZ):
    if (Val > 0.5):
        BigZ[Idx] = 0
# Masks are MUCH faster
mask = np.where(BigZ>0.5)
BigZ[mask] = 0
BigZ[:10]
%%timeit -o
mask = np.where(BigZ>0.5)
BigZ[mask] = 0
Explanation: Loops are slow in Python. Do not use them if you do not have to!
End of explanation
def find_f(x,y):
    
    result = (x ** 2) * np.sin(y)           # assign the variable result the value of the function
    return result                           # return the value of the function to the main program
np.random.seed(42)
array_x = np.random.rand(10) * 10
array_y = np.random.rand(10) * 2.0 * np.pi
array_x, array_y
value_f = find_f(array_x,array_y)
value_f
Explanation: Functions
In computer science, a function (also called a procedure, method, subroutine, or routine) is a portion
of code within a larger program that performs a specific task and is relatively independent of the
remaining code. The big advantage of a function is that it breaks a program into smaller, easier
to understand pieces. It also makes debugging easier. A function can also be reused in another
program.
The basic idea of a function is that it will take various values, do something with them, and return a result. The variables in a function are local. That means that they do not affect anything outside the function.
Below is a simple example of a function that solves the equation:
$ f(x,y) = x^2\ sin(y)$
In the example the name of the function is find_f (you can name functions what ever you want). The function find_f takes two arguments x and y, and returns the value of the equation to the main program. In the main program a variable named value_f is assigned the value returned by find_f. Notice that in the main program the function find_f is called using the arguments array_x and array_y. Since the variables in the function are local, you do not have name them x and y in the main program.
End of explanation
def find_g(z):
    
    result = z / np.e
    return result
find_g(value_f)
find_g(find_f(array_x,array_y))
Explanation: The results of one function can be used as the input to another function
End of explanation
# a new array filled with zeros
array_0 = np.zeros(10)
array_0
# a new array filled with ones
array_1 = np.ones(10)
array_1
# a new array filled with evenly spaced values within a given interval
array_2 = np.arange(10,20)
array_2
# a new array filled with evenly spaced numbers over a specified interval (start, stop, num)
array_3 = np.linspace(10,20,5)
array_3
# a new array filled with evenly spaced numbers over a log scale. (start, stop, num, base)
array_4 = np.logspace(1,2,5,10)
array_4
Explanation: Creating Arrays
Numpy has a wide variety of ways of creating arrays: Array creation routines
End of explanation
<END_TASK>