<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Chapter 1
Modeling and Simulation in Python
Copyright 2021 Allen Downey
License
Step1:  Jupyter
Welcome to Modeling and Simulation in Python, and welcome to Jupyter.
This is a Jupyter notebook, which is a development environment where you can write and run Python code.  Each notebook is divided into cells.  Each cell contains either text (like this cell) or Python code.
To run a cell, hold down SHIFT and press ENTER.  
If you run a text cell, Jupyter formats the text and displays the result.
If you run a code cell, Jupyter runs the Python code in the cell and displays the result, if any.
If you run the following cell, it checks whether the libraries you need are installed.  If so, the cell produces no output.  If not, you'll see updates from the installer.
Step2:  If the previous cell runs without producing any error messages, you are all set.
Modeling
This book is about modeling and simulation of physical systems. The
following diagram shows what I mean by "modeling"
Step3:  A variable is a name that corresponds to a value. In this example, the name is a and the value is the number 9.8.
Suppose we let the penny drop for $3.4$ seconds (s).  I'll create a variable to represent this time
Step4:  Now we can compute the velocity of the penny after t seconds.
Step5:  Python uses the symbol * for multiplication.  The other arithmetic operators are + for addition, - for subtraction, / for division, and ** for exponentiation.
When you assign a value to a variable, Jupyter does not show the result automatically, but you can display the value of a variable like this
Step6:  After $3.4$ s, the velocity of the penny is about $33$ m/s (ignoring air resistance).  Now let's see how far it would travel during that time
Step7:  It would travel about $56$ m.  Now, going in the other direction, let's compute the time it takes to fall 381 m, the height of the Empire State Building.
Step8:  For this computation, we need the square root function, which is provided by a library called NumPy.
Before we can use it, we have to import it like this
Step9:  Now we can use it like this
Step10:  With no air resistance, it would take about $8.8$ s for the penny to reach the sidewalk.
Step11:  And its velocity on impact would be about $86$ m/s.
Python displays results with about 16 digits, which gives the impression that they are very precise, but don't be fooled.
The numbers we get out are only as good as the numbers we put in.
For example, the "roof height" of the Empire State Building is $380$ m according to Wikipedia.
I chose $h=381$ m for this example on the assumption that the observation deck is on the roof and you drop the penny from a 1 meter railing.
But that's probably not right, so we should treat this value as an approximation where only the first two digits are likely to be right.
If the precision of the inputs is two digits, the precision of the outputs is two digits, at most.
That's why, if the output is 86.41527642726142, I report it as "about 86".
Computation with units
The computation in the previous section uses numbers without units.
When we set h=381, we left out the meters, and when we set a=9.8, we left out the meters per second squared.
And, when we got the result v=86, we added back the meters per second.
Leaving units of out computation is common practice, but it tends to cause errors, including the very expensive failure of the Mars Climate Orbiter in 1999.
When possible, it is better to include units in the computation.
To represent units, we'll use a Python library called Pint.
The ModSim library initializes Pint and provides an object called units that contains variables representing pretty much every unit you've ever heard of.
We can import it like this
Step12:  To find out what other units are defined, type units. (including the period) in the next cell and then press TAB.  You should see a pop-up menu with a list of units.
We can use meter and second to create a variable named a and give it the value of acceleration due to gravity.
Step13:  The result is a quantity with two parts, called magnitude and units, which we can access like this
Step14:  Now we can create a quantity that represents $3.4$ s.
Step15:  And use it to compute the distance a penny would fall after t seconds with constant acceleration a.
Step16:  Notice that the units of the result are correct.
If we create a quantity to represent the height of the Empire State Building
Step17:  We can use it to compute the time to reach the sidewalk.
Step18:  And the velocity of the penny on impact
Step19:  As in the previous section, the result is about $86$, but now it has the correct units, m/s.
With Pint quantities, we can convert from one set of units to another like this
Step20:  If you are more familiar with miles per hour, this result might be easier to interpret.
And it might give you a sense that this model is not realistic.
Summary
This chapter introduces a modeling framework that consists of three steps
Step21:  Exercise
Step22:  NumPy provides other functions we'll use, including log, exp, sin, and cos.
Import sin and cos from NumPy and compute
$$sin^2 \pi/4 + cos^2 \pi/4$$
Note
Step23:  Exercise
Step24:  Exercise
Step25:  In this example, you should get a DimensionalityError, which is defined by Pint to indicate that you have violated a rules of dimensional analysis
Step26:  Exercise
Step27:  Exercise
Step28:  Exercise
<ASSISTANT_TASK:>
Python Code:
# install Pint if necessary
try:
    import pint
except ImportError:
    !pip install pint
# download modsim.py if necessary
from os.path import exists
filename = 'modsim.py'
if not exists(filename):
    from urllib.request import urlretrieve
    url = 'https://raw.githubusercontent.com/AllenDowney/ModSim/main/'
    local, _ = urlretrieve(url+filename, filename)
    print('Downloaded ' + local)
# import functions from modsim
from modsim import *
Explanation: Chapter 1
Modeling and Simulation in Python
Copyright 2021 Allen Downey
License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
End of explanation
# check if the libraries we need are installed
try:
    import pint
except ImportError:
    !pip install pint
    
# download modsim.py if necessary
from os.path import exists
filename = 'modsim.py'
if not exists(filename):
    from urllib.request import urlretrieve
    url = 'https://raw.githubusercontent.com/AllenDowney/ModSim/main/'
    local, _ = urlretrieve(url+filename, filename)
    print('Downloaded ' + local)
Explanation: Jupyter
Welcome to Modeling and Simulation in Python, and welcome to Jupyter.
This is a Jupyter notebook, which is a development environment where you can write and run Python code.  Each notebook is divided into cells.  Each cell contains either text (like this cell) or Python code.
To run a cell, hold down SHIFT and press ENTER.  
If you run a text cell, Jupyter formats the text and displays the result.
If you run a code cell, Jupyter runs the Python code in the cell and displays the result, if any.
If you run the following cell, it checks whether the libraries you need are installed.  If so, the cell produces no output.  If not, you'll see updates from the installer.
End of explanation
a = 9.8
Explanation: If the previous cell runs without producing any error messages, you are all set.
Modeling
This book is about modeling and simulation of physical systems. The
following diagram shows what I mean by "modeling":
<img src ="https://github.com/AllenDowney/ModSimPy/raw/master/book/figs/modeling_framework.png" width="400">
Starting in the lower left, the system is something in the real
world we are interested in. 
To model the system, we have to decide which elements of the real world to include and which we can leave out.
This process is called abstraction.
The result of abstraction is a model, which is a description of the system that includes only the features we think are essential. A model
can be represented in the form of diagrams and equations, which can be
used for mathematical analysis. It can also be implemented in the
form of a computer program, which can run simulations.
The result of analysis and simulation might be a prediction about
what the system will do, an explanation of why it behaves the way it
does, or a design intended to achieve a purpose.
We can validate predictions and test designs by taking
measurements from the real world and comparing the data we get
with the results from analysis and simulation.
For any physical system, there are many possible models, each one
including and excluding different features, or including different
levels of detail. The goal of the modeling process is to find the model
best suited to its purpose (prediction, explanation, or design).
Sometimes the best model is the most detailed. If we include more
features, the model is more realistic, and we expect its predictions to
be more accurate.
But often a simpler model is better. If we include only the essential
features and leave out the rest, we get models that are easier to work
with, and the explanations they provide can be clearer and more
compelling.
As an example, suppose someone asks you why the orbit of the Earth is
elliptical. If you model the Earth and Sun as point masses (ignoring
their actual size), compute the gravitational force between them using
Newton's law of universal gravitation, and compute the resulting orbit
using Newton's laws of motion, you can show that the result is an
ellipse.
Of course, the actual orbit of Earth is not a perfect ellipse, because
of the gravitational forces of the Moon, Jupiter, and other objects in
the solar system, and because Newton's laws of motion are only
approximately true (they don't take into account relativistic effects).
But adding these features to the model would not improve the
explanation; more detail would only be a distraction from the
fundamental cause. However, if the goal is to predict the position of
the Earth with great precision, including more details might be
necessary.
Choosing the best model depends on what the model is for. It is usually
a good idea to start with a simple model, even if it is likely to be too
simple, and test whether it is good enough for its purpose. Then you can
add features gradually, starting with the ones you expect to be most
essential. This process is called iterative modeling.
Comparing results of successive models provides a form of internal
validation, so you can catch conceptual, mathematical, and software
errors. And by adding and removing features, you can tell which ones
have the biggest effect on the results, and which can be ignored.
Comparing results to data from the real world provides external
validation, which is generally the strongest test.
The falling penny myth
Let's see an example of how models are used. You might have heard that a
penny dropped from the top of the Empire State Building would be going
so fast when it hit the pavement that it would be embedded in the
concrete; or if it hit a person, it would break their skull.
We can test this myth by making and analyzing a model. To get started,
we'll assume that the effect of air resistance is small. This will turn out to be a bad assumption, but bear with me.
If air resistance is negligible, the primary force acting on the penny
is gravity, which causes the penny to accelerate downward.
If the initial velocity is 0, the velocity after $t$ seconds is 
$$v = a t$$
and the distance the penny has dropped is 
$$x = a t^2 / 2$$ 
To find the time until the penny reaches the sidewalk, we can solve for $t$:
$$t = \sqrt{ 2 x / a}$$ 
Plugging in the acceleration of gravity, $a = 9.8$ m/s$^2$, and the height of the Empire State Building, $x = 381$ m, we get $t = 8.8$ s. 
Then computing $v = a t$ we get a velocity on impact of $86$ m/s, which is about 190 miles per hour. That sounds like it could hurt.
Of course, these results are not exact because the model is based on
simplifications. For example, we assume that gravity is constant. In
fact, the force of gravity is different on different parts of the globe, and it gets weaker as you move away from the surface. But these differences are small, so ignoring them is probably a good choice for this scenario.
On the other hand, ignoring air resistance is not a good choice. Once
the penny gets to about 29 m/s, the upward force of air resistance
equals the downward force of gravity, so the penny stops accelerating.
This is the terminal velocity of the penny in air.
Once the penny reaches terminal velocity, it doesn't matter how much farther it falls; it hits the sidewalk at about 29 m/s.
That's much less than 86 m/s, as the simple model predicts.
The statistician George Box famously said "All models are wrong, but
some are useful." He was talking about statistical models, but his wise words apply to all kinds of models. Our first model, which ignores air resistance, is very wrong, and probably not useful. The second model, which takes air resistance into account, is still wrong, but it's better, and it's good enough to refute the myth.
The television show Mythbusters has tested the myth of the falling
penny more carefully; you can view the results at
http://modsimpy.com/myth. Their work is based on a mathematical model of motion, measurements to determine the force of air resistance on a penny, and a physical model of a human head.
Computation
Let me show you how I computed the results from the
previous section using Python.
First we'll create a variable to represent acceleration due to gravity in meters per second squared (m/s^2).
End of explanation
t = 3.4
Explanation: A variable is a name that corresponds to a value. In this example, the name is a and the value is the number 9.8.
Suppose we let the penny drop for $3.4$ seconds (s).  I'll create a variable to represent this time:
End of explanation
v = a * t
Explanation: Now we can compute the velocity of the penny after t seconds.
End of explanation
v
Explanation: Python uses the symbol * for multiplication.  The other arithmetic operators are + for addition, - for subtraction, / for division, and ** for exponentiation.
When you assign a value to a variable, Jupyter does not show the result automatically, but you can display the value of a variable like this:
End of explanation
x = a * t**2 / 2
x
Explanation: After $3.4$ s, the velocity of the penny is about $33$ m/s (ignoring air resistance).  Now let's see how far it would travel during that time:
End of explanation
h = 381
Explanation: It would travel about $56$ m.  Now, going in the other direction, let's compute the time it takes to fall 381 m, the height of the Empire State Building.
End of explanation
from numpy import sqrt
Explanation: For this computation, we need the square root function, which is provided by a library called NumPy.
Before we can use it, we have to import it like this:
End of explanation
t = sqrt(2 * h / a)
t
Explanation: Now we can use it like this:
End of explanation
v = a * t
v
Explanation: With no air resistance, it would take about $8.8$ s for the penny to reach the sidewalk.
End of explanation
meter = units.meter
meter
second = units.second
second
Explanation: And its velocity on impact would be about $86$ m/s.
Python displays results with about 16 digits, which gives the impression that they are very precise, but don't be fooled.
The numbers we get out are only as good as the numbers we put in.
For example, the "roof height" of the Empire State Building is $380$ m according to Wikipedia.
I chose $h=381$ m for this example on the assumption that the observation deck is on the roof and you drop the penny from a 1 meter railing.
But that's probably not right, so we should treat this value as an approximation where only the first two digits are likely to be right.
If the precision of the inputs is two digits, the precision of the outputs is two digits, at most.
That's why, if the output is 86.41527642726142, I report it as "about 86".
Computation with units
The computation in the previous section uses numbers without units.
When we set h=381, we left out the meters, and when we set a=9.8, we left out the meters per second squared.
And, when we got the result v=86, we added back the meters per second.
Leaving units of out computation is common practice, but it tends to cause errors, including the very expensive failure of the Mars Climate Orbiter in 1999.
When possible, it is better to include units in the computation.
To represent units, we'll use a Python library called Pint.
The ModSim library initializes Pint and provides an object called units that contains variables representing pretty much every unit you've ever heard of.
We can import it like this:
Now we can create variables named meter and second.
End of explanation
a = 9.8 * meter / second**2
a
Explanation: To find out what other units are defined, type units. (including the period) in the next cell and then press TAB.  You should see a pop-up menu with a list of units.
We can use meter and second to create a variable named a and give it the value of acceleration due to gravity.
End of explanation
a.magnitude
a.units
Explanation: The result is a quantity with two parts, called magnitude and units, which we can access like this:
End of explanation
t = 3.4 * second
t
Explanation: Now we can create a quantity that represents $3.4$ s.
End of explanation
a * t**2 / 2
Explanation: And use it to compute the distance a penny would fall after t seconds with constant acceleration a.
End of explanation
h = 381 * meter
Explanation: Notice that the units of the result are correct.
If we create a quantity to represent the height of the Empire State Building:
End of explanation
t = sqrt(2 * h / a)
t
Explanation: We can use it to compute the time to reach the sidewalk.
End of explanation
v = a * t
v
Explanation: And the velocity of the penny on impact:
End of explanation
mile = units.mile
hour = units.hour
v.to(mile/hour)
Explanation: As in the previous section, the result is about $86$, but now it has the correct units, m/s.
With Pint quantities, we can convert from one set of units to another like this:
End of explanation
a = 9.8 * meter / second**2
t = 3.4 * second
v = a * t
v
Explanation: If you are more familiar with miles per hour, this result might be easier to interpret.
And it might give you a sense that this model is not realistic.
Summary
This chapter introduces a modeling framework that consists of three steps:
Abstraction is the process of defining a model, deciding which elements of the real world to include and which can be left out.
Analysis and simulation are ways to use a model to generate predictions, explain why things behave as they to, and design things that behave as we want.
Validation is how we test whether the model is right, often by comparing predictions with measurements from the real world.
As a first example, we modeled a penny dropped from the Empire State building, including gravity but ignoring air resistance.
In the exercises, you'll have a chance to try a better model, including air resistance.
This chapter also presents Pint, a library for doing computation with units, which is convenient for converting between different units and important for avoiding catastrophic errors.
Exercises
Exercise In mathematical notation, we can write an equation like $v = a t$ and it's understood that we are multiplying $a$ and $t$.
But that doesn't work in Python.  If you put two variables side-by-side, like this:
v = a t
you'll get a syntax error, which means that something is wrong with the punctuation of the program.
Try it out in the next cell so you see what the error message looks like.
End of explanation
from numpy import pi
pi
Explanation: Exercise: In this chapter we used the sqrt function from the NumPy library.  NumPy also provides a variable named pi that contains an approximation of the mathematical constant $\pi$.
We can import it like this:
End of explanation
# Solution
from numpy import sin, cos
sin(pi/4)**2 + cos(pi/4)**2
Explanation: NumPy provides other functions we'll use, including log, exp, sin, and cos.
Import sin and cos from NumPy and compute
$$sin^2 \pi/4 + cos^2 \pi/4$$
Note: A mathematical identity tells us that the answer should be $1$.
End of explanation
h = 381 * meter
# Solution
foot = units.foot
pole_height = 10 * foot
h + pole_height
# Solution
pole_height + h
Explanation: Exercise: Suppose you bring a 10 foot pole to the top of the Empire State Building and use it to drop the penny from h plus 10 feet.
Define a variable named foot that contains the unit foot provided by UNITS.  Define a variable named pole_height and give it the value 10 feet.
What happens if you add h, which is in units of meters, to pole_height, which is in units of feet?  What happens if you write the addition the other way around?
End of explanation
a = 9.8 * meter / second**2
t = 3.4 * second
Explanation: Exercise: Why would it be nonsensical to add a and t? What happens if you try?
End of explanation
# Solution
h = 381 * meter
v = 29 * meter / second
t = h / v
t
Explanation: In this example, you should get a DimensionalityError, which is defined by Pint to indicate that you have violated a rules of dimensional analysis: you cannot add quantities with different dimensions.
The error messages you get from Python are big and scary, but if you read them carefully, they contain a lot of useful information.
Start from the bottom and read up.
The last line usually tells you what type of error happened, and sometimes additional information.
The previous lines are a "traceback" of what was happening when the error occurred.  The first section of the traceback shows the code you wrote.  The following sections are often from Python libraries.
Before you go on, you might want to delete the erroneous code so the notebook can run without errors.
Exercise: Suppose instead of dropping the penny, you throw it downward at its terminal velocity, $29$ m/s.  How long would it take to fall $381$ m?
End of explanation
a = 9.8 * meter / second**2
h = 381 * meter
# Solution
v_terminal = 29 * meter / second 
# Solution
t1 = v_terminal / a
print('Time to reach terminal velocity', t1)
# Solution
h1 = a * t1**2 / 2
print('Height fallen in t1', h1)
# Solution
t2 = (h - h1) / v_terminal
print('Time to fall remaining distance', t2)
# Solution
t_total = t1 + t2
print('Total falling time', t_total)
Explanation: Exercise: So far we have considered two models of a falling penny:
If we ignore air resistance, the penny falls with constant acceleration, and we can compute the time to reach the sidewalk and the velocity of the penny when it gets there.
If we take air resistance into account, and drop the penny at its terminal velocity, it falls with constant velocity. 
Now let's consider a third model that includes elements of the first two: let's assume that the acceleration of the penny is a until the penny reaches $29$ m/s, and then $0$ m/s afterwards.  What is the total time for the penny to fall $381$ m?
You can break this question into three parts:
How long would the penny take to reach $29$ m/s with constant acceleration a.
How far would it fall during that time?
How long would it take to fall the remaining distance with constant velocity $29$ m/s?
Suggestion: Assign each intermediate result to a variable with a meaningful name.  And assign units to all quantities!
End of explanation
# Solution
# I suggest the following model: 
# 1. Let's ignore the motion of the ball toward home plate and
#    think about how far the ball would drop while it's in flight.
# 2. Let's ignore air resistance.  Since we are only thinking 
#    about the relatively slow motion in the vertical direction, 
#    this is probably a good assumption.
# 3. Let's also ignore the effect of spin.  This is probably a
#    less good assumption.
# The distance from the pitcher's mound to home plate is about 60
# feet, but the point where the ball is released is a bit closer.
# An average pitcher in high school might be able to throw a ball
# at 80 mph.
# Solution
v = (80 * mile / hour).to(meter/second)
x = (60 * foot).to(meter)
# Solution
t = x / v
t
# Solution
a = 9.8 * meter / second**2
h = a * t**2 / 2
h
# Solution
# In the time it takes the ball to reach home plate, it drops
# about 1.3 m.  If the release point is at 2 m, which is plausible,
# it would cross the plate at 0.7 m, which is in the strike zone.
# So I could be wrong -- it is plausible that the ball leaves
# the pitcher's hand at a downward angle, at least for some pitches.
Explanation: Exercise: When I was in high school, the pitcher on the baseball team claimed that, when he threw a fastball, he was throwing the ball down; that is, the ball was leaving his hand at a downward angle.
I was skeptical; watching from the side, I thought the ball was leaving his hand at an upward angle.
Can you think of a simple model you could use to settle the argument?  What factors would you include and what could you ignore?  What quantities would you have to look up or estimate?
I suggest you convert all quantities to SI units: meters and seconds.
End of explanation
mile = units.mile
kilometer = units.kilometer
minute = units.minute
# Solution
t = 52 * second + 44 * minute
t
# Solution
v = 10 * kilometer / t
v
# Solution
pace = (1 / v).to(minute / mile)
pace
# Solution
# To convert to minutes and seconds, we can use np.round.
# But we haven't covered that yet.
from numpy import round
round(pace)
# Solution
remainder = pace - round(pace)
remainder.to(second/mile)
Explanation: Exercise: Suppose I run a 10K race in 44:52.  What is my average page in minutes per mile?
End of explanation
<END_TASK>