<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 An introduction to Python syntax and plotting
(c) 2016 Griffin Chure. This work is licensed under a Creative Commons Attribution License CC-BY 4.0. All code contained herein is licensed under an MIT license  
In this tutorial, we will learn some of the basics of programming in Python. While this will all become muscle memory, it's useful to keep this as a reference. 
Hello, world
As is typical when learning any programming language, we'll start by making our computer speak to us. We'll do this by using one of the many standard functions in Python, the print function.
Step1:  In the above code, we called the print function and passed the text Hello, world. surrounded by single quotation marks ''. The text was passed as an argument to the print function by placing it in the parentheses. The quotation marks determined the type of the argument to be text, known as a string. While we used single quotations in the above code, we could also use double quotations "". These are exchangeable in Python.
While our 'Hello, world.' is a string, this function can also be used to print other types such as integers (ints), decimals (floats), and True/False (boolean) by passing them as arguments to the print function.
Step2:  In the above code, it would be nice to be able to add a comment about what the type of each variable is that we are printing, but we don't want this comment to be interpreted by Python. By adding a pound symbol (#) before a line of code, we can force Python to ignore it.
Step3:  We see that we get the same result.
Basic math
Arithmetic
The crux of scientific programming is the ability to perform mathematical operations. Python can do a variety of simple mathematical functions by default.
Step4:  Everything looks good, but what happened at the end? In Python, you exponentiate terms using a double asterisk (**) and not a carrot (^). The carrot executes a bitwise operation which is completely different than exponentiation.
Step5:  Note that the all mathematical operations other than addition (+) can only be done on ints, floats, or bool. The addition operator can be performed on strings too! Let's show this by adding two halves of a sentence together. We'll use the opening sentence from my favorite fiction series The Dark Tower as an example.
Step6:  While all of these operations are simple, we would like some way in which can store a number for further use. We can do this by assigning the output of an operation to a variable.
Step7:  Lists and tuples
So far, we've learned about floats, ints, bools, and strings as well as how to assign them to variables. But what about when we want to work with a series of these kinds of values? There are a few ways in which we can do this $-$ lists (values within brackets []), tuples (values within parenthesis ()), and arrays (which we'll learn about in the next section).
Step8:  Note that lists and arrays can have mixed types. Once we have a list or a tuple, we can extract a single value or a range of values by indexing.
Step9:  To get the first value of the list, I started with zero. In Python, indexing begins at 0. This is different than in other programming languages such as MATLAB which begins at 1.
So what exactly is the difference between tuples and lists? Lists are mutable. Tuples are not. This means once a value in a tuple is set in place, it can't be changed without redefining the tuple. Let's demonstrate this by trying to change the first value of our example_list and example_tuple.
Step10:  Python yelled at me and told me that I can't assign a current value in a tuple. This is a very important point. For example, if you want to have some process output a series of values you don't want to change, put them in a tuple. Otherwise, put them in a list or an array. 
Lists are mutable, but we have to be careful with performing arithmetic operations on them. For example, the operators +,-, **, and / will give you errors. However, the * operator will concatenate a list with itself.
Step11:  So how do we do more complicated mathematical operations on a series of numbers? How can I multiply each element of an array by five? How do I take the exponential of each element? How do I perform a dot product between two series? To perform such tasks, we will have to import another python module, NumPy. 
Importing modules and working with NumPy
When you open a Python interpreter or run a script, you are only loading the 'standard' Python packages. This means that you are not loading everything you could possibly want, but only the packages you need to perform the task. To perform more elaborate computation in Python, we will need to import an external module called NumPy.
Step12:  Whenever you write a Python script, you should always import the modules you will need at the very beginning. That way, all of the required packages will be loaded and ready to go when you start loading them. 
Let's talk about the syntax of the above line. I told the Python interpreter that it should import the module called numpy and give it the alias of np. This means whenever I have to call a  Numpy associated function, I can do so by typing np.function_name instead of numpy.function_name. The alias can be whatever you would like it to be, but you should stick by the community standards so your code is clear to everyone who is trying to figure out what you are doing. 
Numpy is the premier numerical computing module for Python. With it, we have myriad functions for peforming numerical operations.
Step13:  With numpy comes a new data type called numpy arrays. These are series of values which are mutable (just like lists) which cannot have a mixed data type (unlike lists and tuples).  We can also perform mathematical operations on arrays.
Step14:  Numpy arrays are not limited to being one-dimensional. We can create n-dimensional numpy arrays with ease.
Step15:  We can even make numpy make series of values for us! This will be very useful once we start manipulating images and making plots.
Step16:  It is impossible to perform scientific computing in Python without using numpy.
Checking type, length, and shape
It's useful to be able to see the properties of variables that we've created so far. We can check the type of our variables as follows
Step17:  Note that even though the elements of our list_type and tuple_type have mixed types, this command tells us what the type of the object is (i.e. list and tuple). We can force changes in the type of a variable with ease. Let's make that int a float and that tuple a list.
Step18:  We can  also convert numbers to strings. This is useful if we want to print a sentence including the output from some other operation.
Step19:  In addition to type, we can get some information about the shape and length of all of our variables. We can do this using the len function and the np.shape function that comes with NumPy.
Step20:  We've created a lot of variable so far in this tutorial. It's nice to be able to look at what variables exist in our environment as well as get some information. Let's take a look at everything we've made so far.
Step22:  We see that we get a relatively nicely ordered list of all of our variables, the type of the variable, and then information about their contents. We can see for our lists and arrays it tells us the number of rows and columns, how many elements there are, what the type of those elements are and so forth. 
Functions
Functions are arguably the most important components of efficient and effective programming. Functions are sections of code that are written to take an argument, perform some manipulation, and return the manipulated argument. In Python, these functions can be written in the same script where you want to use them.
In Python, spacing and indentation matters (this is why we set our Tab settings in the Atom text editor). When we define a function and perform looping, we have to be very aware of where our code exists in the script. Once you define a function, all operations that are to take place in that function should be indented from the rest of the code.  
The best way to learn is by doing. Let's write a function to add two strings together. We'll also have this function print out the final string if we tell it to.
Step23:  We did a lot of complicated procedures in this code, so let's go through it piece by piece.
We defined the function as adding_machine which takes the arguments value_1 and value_2 as well as a keyword argument print_value which has a default value of True.
We wrote some information about the what the function does and what arguments it takes.
We then performed the operation by adding together value_1 and value_2 and assigning it to a new variable called added_values.
We tested if the function should print the resut to the string. We did this by using an if statement. This tested if print_value was equal to True. If it that was the case, the print function was called and printed the value of added_values.
The variable added_values is returned and the function call ends. 
Each line in this function was one-tab away from the definition statement of the function. Note that we were never specific about what value_1 and what value_2 are. These could be floats, ints, or even strings. Let's give it a shot with a few values.
Step24:  Since we added the automatic printing of values as a keyword argument, we can easily tell our function to stop printing things.
Step25:  While this function was very simple (and frankly unnecessary), being able to write functions to automate tasks will be very valuable in the future $-$ especially when we start working with images. 
Our first for loop
Rather than using "boring" simple operations to learn some syntax, let's learn about the for loop by using a biological example. 
Let's say that we have a cell sitting in a tube of growth medium. If we place this tube at the right temperature, the cells will grow exponentially. We can write down a very simple model that as long as the cells are well below the carrying capacity of their environment, they will grow as 
$$
N(d) = 2^{d},
$$
where $N(d)$ is the number of cells at division $d$. To test this model, we'll write a very short simulation to test that the a cell would grow exponentially. 
Before we think of how the specific code should be written, let's write out what our thought process should be. 
We should first define the initial number of cells as well as the number of divisions to simulate.
For each cell division, we should multiply the number of cells that we had in the last division event. 
After each division, we should keep track of how many cells there are.
With this idea in place, let's go through the code.
Step26:  We covered a lot of syntax in that cell, so let's take a look at it piece by piece.  
number_of_cells = 1
Step27:  It looks like our function worked! But can we tell this is exponential growth? Because this is a simple case, we can see that the number of cells are doubling at each division. However, It would be very useful to plot these results. 
Plotting using matplotlib
There are many plotting utilities available for Python. Some notable examples include Bokeh for interactive plotting, Seaborn and Altair for statistical visualization, and a Python port of the popular R programming language plotting utility ggplot. While interactive plotting is likely the visualization tool of the future, the most common (and full featured) plotting utility for Python as of this writing is matplotlib. It was designed with the plotting syntax and style of MATLAB in mind and many of the commands are similiar. As is the case with numpy, matplotlib is not within the standard libray of Python and must be imported.
Step28:  We would like to see if our simulated cells appear to grow exponentially with time. To do so, we would like to plot the number of cells we have at division number $d$ as a function of $d$. Before we do any plotting, let's generate a vector of division times that matches the size of our N_d vector. We can do this using some of the arrangement methods that we used earlier with numpy. Since we had measure at $d=0$, our new division vector must have a length of number_of_divisions + 1.
Step29:  Now all that is left is to plot it! We can use the plot function of matplotlib to generate our scatterplot. We'll choose small circles as our markers and provide the approriate $x$ and $y$ labels as we always should. We'll also add a legend to our plot to show that these data poitns are from a simulation.
Step30:  In calling the plt.plot() function, we first passed it the $x$ and $y$ data, told it to plot the points as circles (through the 'o' argument), and finally gave it a label. 
To me, this plot is pretty ugly. Every aspect of this plot can be stylized to your liking, althought it will take a little bit of work. However, we can import the seaborn plotting utility which will stylize all of our plots and make them much clearer to interpret.
Step31:  Importing this function will likely give you an warning (as is seen above), but this can be ignored. With this imported, let's go ahead and remake the plot from above.
<ASSISTANT_TASK:>
Python Code:
print('Hello, world')
Explanation: An introduction to Python syntax and plotting
(c) 2016 Griffin Chure. This work is licensed under a Creative Commons Attribution License CC-BY 4.0. All code contained herein is licensed under an MIT license  
In this tutorial, we will learn some of the basics of programming in Python. While this will all become muscle memory, it's useful to keep this as a reference. 
Hello, world
As is typical when learning any programming language, we'll start by making our computer speak to us. We'll do this by using one of the many standard functions in Python, the print function.
End of explanation
print(10)
print(3.14159)
print(True)
Explanation: In the above code, we called the print function and passed the text Hello, world. surrounded by single quotation marks ''. The text was passed as an argument to the print function by placing it in the parentheses. The quotation marks determined the type of the argument to be text, known as a string. While we used single quotations in the above code, we could also use double quotations "". These are exchangeable in Python.
While our 'Hello, world.' is a string, this function can also be used to print other types such as integers (ints), decimals (floats), and True/False (boolean) by passing them as arguments to the print function.
End of explanation
# Print an integer
print(10)
# Print a float
print(3.14159)
# Print a bool
print(True)
Explanation: In the above code, it would be nice to be able to add a comment about what the type of each variable is that we are printing, but we don't want this comment to be interpreted by Python. By adding a pound symbol (#) before a line of code, we can force Python to ignore it.
End of explanation
print(1 + 1) # this should be 2
print(4 / 2) # this should be 2
print(40 - 38) # this should be 2
print(2^4) # this should be 16
Explanation: We see that we get the same result.
Basic math
Arithmetic
The crux of scientific programming is the ability to perform mathematical operations. Python can do a variety of simple mathematical functions by default.
End of explanation
print(2**4) # this should be 16
Explanation: Everything looks good, but what happened at the end? In Python, you exponentiate terms using a double asterisk (**) and not a carrot (^). The carrot executes a bitwise operation which is completely different than exponentiation.
End of explanation
print('The man in black fled across the desert' + ' and the gunslinger followed.')
Explanation: Note that the all mathematical operations other than addition (+) can only be done on ints, floats, or bool. The addition operator can be performed on strings too! Let's show this by adding two halves of a sentence together. We'll use the opening sentence from my favorite fiction series The Dark Tower as an example.
End of explanation
# Assign some values to variables. 
a = 1
b = 2
c = 2 * a / b - 2*b  # Should be -3
print(c)
Explanation: While all of these operations are simple, we would like some way in which can store a number for further use. We can do this by assigning the output of an operation to a variable.
End of explanation
# Generate some lists and arrays.
example_list = [1, 2, 3]
example_tuple = (1, 2, 3)
list_of_lists = [[1, 2, 3]]
tuple_of_lists = ([1, 2, 3], [200, 2], 1)
mixed_type_list = [1, 2, 'phsyical', 'biology', 10.028]
Explanation: Lists and tuples
So far, we've learned about floats, ints, bools, and strings as well as how to assign them to variables. But what about when we want to work with a series of these kinds of values? There are a few ways in which we can do this $-$ lists (values within brackets []), tuples (values within parenthesis ()), and arrays (which we'll learn about in the next section).
End of explanation
# Index some values.
print(example_list[0])  # should be 1
print(example_tuple[2])  # should be 3
print(example_list[0:2]) # should be 1 and 2
print(example_list[-1])  # This will give the last entry of the list 
Explanation: Note that lists and arrays can have mixed types. Once we have a list or a tuple, we can extract a single value or a range of values by indexing.
End of explanation
# Change the first entry to 1000 
example_list[0] = 1000
print(example_list)
example_tuple[0] = 1000
print(example_tuple)
Explanation: To get the first value of the list, I started with zero. In Python, indexing begins at 0. This is different than in other programming languages such as MATLAB which begins at 1.
So what exactly is the difference between tuples and lists? Lists are mutable. Tuples are not. This means once a value in a tuple is set in place, it can't be changed without redefining the tuple. Let's demonstrate this by trying to change the first value of our example_list and example_tuple.
End of explanation
# Do list arithmetic.
next_list = [2, 4, 6]
print(next_list * 2)  # Should be [2, 4, 6, 2, 4, 6]
print(next_list * 5)  # Should be the same list repeated five times.
Explanation: Python yelled at me and told me that I can't assign a current value in a tuple. This is a very important point. For example, if you want to have some process output a series of values you don't want to change, put them in a tuple. Otherwise, put them in a list or an array. 
Lists are mutable, but we have to be careful with performing arithmetic operations on them. For example, the operators +,-, **, and / will give you errors. However, the * operator will concatenate a list with itself.
End of explanation
# Import the NumPy module and give it an alias
import numpy as np
Explanation: So how do we do more complicated mathematical operations on a series of numbers? How can I multiply each element of an array by five? How do I take the exponential of each element? How do I perform a dot product between two series? To perform such tasks, we will have to import another python module, NumPy. 
Importing modules and working with NumPy
When you open a Python interpreter or run a script, you are only loading the 'standard' Python packages. This means that you are not loading everything you could possibly want, but only the packages you need to perform the task. To perform more elaborate computation in Python, we will need to import an external module called NumPy.
End of explanation
# Demonstrate the power of numpy.
print(np.exp(-1))
print(np.sin(1))
print(np.cos(2 * np.sin(5)))
Explanation: Whenever you write a Python script, you should always import the modules you will need at the very beginning. That way, all of the required packages will be loaded and ready to go when you start loading them. 
Let's talk about the syntax of the above line. I told the Python interpreter that it should import the module called numpy and give it the alias of np. This means whenever I have to call a  Numpy associated function, I can do so by typing np.function_name instead of numpy.function_name. The alias can be whatever you would like it to be, but you should stick by the community standards so your code is clear to everyone who is trying to figure out what you are doing. 
Numpy is the premier numerical computing module for Python. With it, we have myriad functions for peforming numerical operations.
End of explanation
# Demonstrate the magic of numpy arrays
my_array = np.array([1, 2, 3])
#Basic arithmetic
print(my_array * 2)  # Element-wise multiplication
print(my_array / 3)  # Element-wise division
print(my_array * my_array)  # Element-wise multiplication
print(np.dot(my_array, my_array)) # Dot product of two arrays
Explanation: With numpy comes a new data type called numpy arrays. These are series of values which are mutable (just like lists) which cannot have a mixed data type (unlike lists and tuples).  We can also perform mathematical operations on arrays.
End of explanation
# Create multi-dimensional arrays
one_dimensional_array = np.array([1, 2, 3, 4])
two_dimensional_array = np.array([[1, 2, 3, 4],
                                  [5, 6, 7, 8]])  
print(one_dimensional_array)
print(two_dimensional_array)
Explanation: Numpy arrays are not limited to being one-dimensional. We can create n-dimensional numpy arrays with ease.
End of explanation
# Automatically generate series of values.
linear_spaced = np.linspace(0, 10, 1000)  # Generates 1000 points between 0 and 10 
log_spaced = np.logspace(-1, 1, 200) # Generates 200 points logarithmically spaced 
                                     # between .1 and 10
aranged = np.arange(0, 50, 2)  # Generates values between 0 and 50 taking steps of 
                               # two.
Explanation: We can even make numpy make series of values for us! This will be very useful once we start manipulating images and making plots.
End of explanation
# Generate some variable with different types.
string_type = 'string'
float_type = 3.14159
bool_type = True
int_type = 3
list_type = ['a', 'b', 2]
tuple_type = ('c', 'd', 3)
nparray_type = np.ones_like(tuple_type)
# Print their types
print(type(string_type))
print(type(float_type))
print(type(bool_type))
print(type(int_type))
print(type(list_type))
print(type(tuple_type))
print(type(nparray_type))
Explanation: It is impossible to perform scientific computing in Python without using numpy.
Checking type, length, and shape
It's useful to be able to see the properties of variables that we've created so far. We can check the type of our variables as follows
End of explanation
# Change the type of a varible
int_to_float = float(int_type)
tuple_to_list = list(tuple_type)
print(int_to_float)
print(tuple_to_list)
Explanation: Note that even though the elements of our list_type and tuple_type have mixed types, this command tells us what the type of the object is (i.e. list and tuple). We can force changes in the type of a variable with ease. Let's make that int a float and that tuple a list.
End of explanation
# Convert a float to a string.
value_one = 10
value_two = 20
print("The product of value_one and value_two is " + str(value_one * value_two))
Explanation: We can  also convert numbers to strings. This is useful if we want to print a sentence including the output from some other operation.
End of explanation
# Print the length, size, and shape of our variables.
big_array = np.array([[1, 2, 3], [4, 5, 6]])
print(len(big_array))
print(np.shape(big_array))
Explanation: In addition to type, we can get some information about the shape and length of all of our variables. We can do this using the len function and the np.shape function that comes with NumPy.
End of explanation
whos
Explanation: We've created a lot of variable so far in this tutorial. It's nice to be able to look at what variables exist in our environment as well as get some information. Let's take a look at everything we've made so far.
End of explanation
def adding_machine(value_1, value_2, print_value=True):
    
    Adds together value_1 with value_2. If `print_value` is True,
    the resulting value will be printed to the screen.
    
    
    # Merge the strings together.
    added_values = value_1 + value_2 
    
    # Determine if the new string should be printed. 
    if print_value == True:
        print(added_values)
        
    # Return the smashed string.
    return added_values
Explanation: We see that we get a relatively nicely ordered list of all of our variables, the type of the variable, and then information about their contents. We can see for our lists and arrays it tells us the number of rows and columns, how many elements there are, what the type of those elements are and so forth. 
Functions
Functions are arguably the most important components of efficient and effective programming. Functions are sections of code that are written to take an argument, perform some manipulation, and return the manipulated argument. In Python, these functions can be written in the same script where you want to use them.
In Python, spacing and indentation matters (this is why we set our Tab settings in the Atom text editor). When we define a function and perform looping, we have to be very aware of where our code exists in the script. Once you define a function, all operations that are to take place in that function should be indented from the rest of the code.  
The best way to learn is by doing. Let's write a function to add two strings together. We'll also have this function print out the final string if we tell it to.
End of explanation
# Add some various values together.
x = adding_machine(10, 2) 
y = adding_machine(1.01, 1.08)
z = adding_machine('Python', ' Rules')
# Print the variables we assigned them to.
print(x, y, z)
Explanation: We did a lot of complicated procedures in this code, so let's go through it piece by piece.
We defined the function as adding_machine which takes the arguments value_1 and value_2 as well as a keyword argument print_value which has a default value of True.
We wrote some information about the what the function does and what arguments it takes.
We then performed the operation by adding together value_1 and value_2 and assigning it to a new variable called added_values.
We tested if the function should print the resut to the string. We did this by using an if statement. This tested if print_value was equal to True. If it that was the case, the print function was called and printed the value of added_values.
The variable added_values is returned and the function call ends. 
Each line in this function was one-tab away from the definition statement of the function. Note that we were never specific about what value_1 and what value_2 are. These could be floats, ints, or even strings. Let's give it a shot with a few values.
End of explanation
# Add some various values together.
x = adding_machine(10, 2, print_value=False) 
y = adding_machine(1.01, 1.08, print_value=False)
z = adding_machine('Python', ' Rules', print_value=False)
# Print the variables we assigned them to.
print(x, y, z)
Explanation: Since we added the automatic printing of values as a keyword argument, we can easily tell our function to stop printing things.
End of explanation
# Set the initial number of cells in the experiment.
number_of_cells = 1
# Set the number of division cycles for the experiment.
number_of_divisions = 10
# Set a list of number of cells at division d and start with 1 cell
N_d = [number_of_cells]
# Loop through each division event
for i in range(number_of_divisions):
    # Make the cells duplicate
    number_of_cells = number_of_cells * 2 
   
    # Add the new number of cells to our storage list.
    N_d.append(number_of_cells)
Explanation: While this function was very simple (and frankly unnecessary), being able to write functions to automate tasks will be very valuable in the future $-$ especially when we start working with images. 
Our first for loop
Rather than using "boring" simple operations to learn some syntax, let's learn about the for loop by using a biological example. 
Let's say that we have a cell sitting in a tube of growth medium. If we place this tube at the right temperature, the cells will grow exponentially. We can write down a very simple model that as long as the cells are well below the carrying capacity of their environment, they will grow as 
$$
N(d) = 2^{d},
$$
where $N(d)$ is the number of cells at division $d$. To test this model, we'll write a very short simulation to test that the a cell would grow exponentially. 
Before we think of how the specific code should be written, let's write out what our thought process should be. 
We should first define the initial number of cells as well as the number of divisions to simulate.
For each cell division, we should multiply the number of cells that we had in the last division event. 
After each division, we should keep track of how many cells there are.
With this idea in place, let's go through the code.
End of explanation
# Print the result of our simulation.
print(N_d)
Explanation: We covered a lot of syntax in that cell, so let's take a look at it piece by piece.  
number_of_cells = 1: We assigned our starting number of cells to a variable.
number_of_divisions = 10: We assigned a value for the total number of divisions to a variable.
N_d = [number_of_cells] We made a list where the first entry (our starting point) only has one cell.
Now we enter the for loop, which exectues our simulation.
for i in range(number_of_divisions): This starts the for loop. We are using the variable i as an iterator. Each time we go through the loop, i will take on the next value of the range function. The range function generates a list of integers starting from 0 to number_of_divisions which we set as 10.
number_of_cells = number_of_cells * 2: This performed the cell division, doubling the number of cells. We also reassigned the value of this variable. Through the next iteration of the loop, the number will double again.
N_d.append(number_of_cells): This is using the append method of the N_d list to add the number of cells at each division to our list before we go on to the next round of the loop. 
Also notice that, just like in functions, the code is indented. Everything that is indented to the same level will execute within the loop. 
Let's take a look at our N_d list and see how the number of cells changed over time.
End of explanation
# Load the plotting utility matplotlib with an alias plt.
import matplotlib.pyplot as plt
# The following line is used for this tutorial only and allows plots to be 
# displayed in this notebook.
%matplotlib inline
Explanation: It looks like our function worked! But can we tell this is exponential growth? Because this is a simple case, we can see that the number of cells are doubling at each division. However, It would be very useful to plot these results. 
Plotting using matplotlib
There are many plotting utilities available for Python. Some notable examples include Bokeh for interactive plotting, Seaborn and Altair for statistical visualization, and a Python port of the popular R programming language plotting utility ggplot. While interactive plotting is likely the visualization tool of the future, the most common (and full featured) plotting utility for Python as of this writing is matplotlib. It was designed with the plotting syntax and style of MATLAB in mind and many of the commands are similiar. As is the case with numpy, matplotlib is not within the standard libray of Python and must be imported.
End of explanation
# Establish a vector of the division cycles
division_vector = np.arange(0, number_of_divisions + 1, 1)
Explanation: We would like to see if our simulated cells appear to grow exponentially with time. To do so, we would like to plot the number of cells we have at division number $d$ as a function of $d$. Before we do any plotting, let's generate a vector of division times that matches the size of our N_d vector. We can do this using some of the arrangement methods that we used earlier with numpy. Since we had measure at $d=0$, our new division vector must have a length of number_of_divisions + 1.
End of explanation
# Generate the plot.
plt.plot(division_vector, N_d, 'o', label='simulation')
# Set the axis labels.
plt.xlabel('number of divisions')
plt.ylabel('number of cells')
# Add a legend
plt.legend()
Explanation: Now all that is left is to plot it! We can use the plot function of matplotlib to generate our scatterplot. We'll choose small circles as our markers and provide the approriate $x$ and $y$ labels as we always should. We'll also add a legend to our plot to show that these data poitns are from a simulation.
End of explanation
import seaborn as sns
Explanation: In calling the plt.plot() function, we first passed it the $x$ and $y$ data, told it to plot the points as circles (through the 'o' argument), and finally gave it a label. 
To me, this plot is pretty ugly. Every aspect of this plot can be stylized to your liking, althought it will take a little bit of work. However, we can import the seaborn plotting utility which will stylize all of our plots and make them much clearer to interpret.
End of explanation
# Generate the plot.
plt.plot(division_vector, N_d, 'o', label='simulation')
# Set the axis labels.
plt.xlabel('number of divisions')
plt.ylabel('number of cells')
# Add a legend
plt.legend()
Explanation: Importing this function will likely give you an warning (as is seen above), but this can be ignored. With this imported, let's go ahead and remake the plot from above.
End of explanation
<END_TASK>