Created
July 6, 2018 15:24
-
-
Save echarles/54c594cfac60335f1e4bb03dbcd6d31b to your computer and use it in GitHub Desktop.
lab01.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Lab 1: Expressions\n", | |
| "\n", | |
| "Welcome to Data Science 8: Foundations of Data Science! Each week you will complete a lab assignment like this one. You can't learn technical subjects without hands-on practice, so labs are an important part of the course.\n", | |
| "\n", | |
| "Before we get started, there are some administrative details.\n", | |
| "\n", | |
| "Labs are required. There are two ways to receive credit for each lab.\n", | |
| "\n", | |
| "1. (The normal way) Come to your lab section and work on the lab as directed. Before you leave, you need to submit the lab **and** have a staff member check you off to confirm that you came to lab section and attempted to make progress while you were there. You do not need to finish the lab or answer every question correctly to receive full credit. However, you do need to try; that's why we check you off. Expect to discuss your progress briefly with a staff member before they will check you off.\n", | |
| " \n", | |
| "2. (The hard way) Lab assignments will be posted Monday night. If you complete the entire lab so that all tests pass and submit it by 11:59pm on Tuesday, then you don't need to physically attend lab for the rest of the week.\n", | |
| "\n", | |
| "Collaborating on labs is more than okay -- it's encouraged! You should rarely be stuck for more than a few minutes on questions in labs, so ask a neighbor or an instructor for help. (Explaining things is beneficial, too -- the best way to solidify your knowledge of a subject is to explain it.) Please don't just share answers, though.\n", | |
| "\n", | |
| "You can read more about [course policies](http://data8.org/su17/policies.html) on the [course website](http://data8.org/su17).\n", | |
| "\n", | |
| "#### Today's lab\n", | |
| "\n", | |
| "In today's lab, you'll learn how to:\n", | |
| "\n", | |
| "1. navigate Jupyter notebooks (like this one);\n", | |
| "2. write and evaluate some basic *expressions* in Python, the computer language of the course;\n", | |
| "3. call *functions* to use code other people have written; and\n", | |
| "4. break down Python code into smaller parts to understand it.\n", | |
| "\n", | |
| "This lab covers parts of [Chapter 3](http://www.inferentialthinking.com/chapters/03/programming-in-python.html) of the online textbook. You should read the book, but not right now. Instead, let's get started!" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# 1. Jupyter notebooks\n", | |
| "This webpage is called a Jupyter notebook. A notebook is a place to write programs and view their results.\n", | |
| "\n", | |
| "## 1.1. Text cells\n", | |
| "In a notebook, each rectangle containing text or code is called a *cell*.\n", | |
| "\n", | |
| "Text cells (like this one) can be edited by double-clicking on them. They're written in a simple format called [Markdown](http://daringfireball.net/projects/markdown/syntax) to add formatting and section headings. You don't need to learn Markdown, but you might want to.\n", | |
| "\n", | |
| "After you edit a text cell, click the \"run cell\" button at the top that looks like ▶| to confirm any changes. (Try not to delete the instructions of the lab.)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 1.1.1.** This paragraph is in its own text cell. Try editing it so that this sentence is the last sentence in the paragraph, and then click the \"run cell\" ▶| button . This sentence, for example, should be deleted. So should this one." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 1.2. Code cells\n", | |
| "Other cells contain code in the Python 3 language. Running a code cell will execute all of the code it contains.\n", | |
| "\n", | |
| "To run the code in a code cell, first click on that cell to activate it. It'll be highlighted with a little green or blue rectangle. Next, either press ▶| or hold down the `shift` key and press `return` or `enter`.\n", | |
| "\n", | |
| "Try running this cell:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "print(\"Hello, World!\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "And this one:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "print(\"\\N{WAVING HAND SIGN}, \\N{EARTH GLOBE ASIA-AUSTRALIA}!\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "The fundamental building block of Python code is an expression. Cells can contain multiple lines with multiple expressions. When you run a cell, the lines of code are executed in the order in which they appear. Every `print` expression prints a line. Run the next cell and notice the order of the output." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "print(\"First this line is printed,\")\n", | |
| "print(\"and then this one.\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 1.2.1.** Change the cell above so that it prints out:\n", | |
| "\n", | |
| " First this line,\n", | |
| " then the whole 🌏,\n", | |
| " and then this one.\n", | |
| "\n", | |
| "*Hint:* If you're stuck on the Earth symbol for more than a few minutes, try talking to a neighbor or a TA. That's a good idea for any lab problem." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 1.3. Writing Jupyter notebooks\n", | |
| "You can use Jupyter notebooks for your own projects or documents. When you make your own notebook, you'll need to create your own cells for text and code.\n", | |
| "\n", | |
| "To add a cell, click the + button in the menu bar. It'll start out as a text cell. You can change it to a code cell by clicking inside it so it's highlighted, clicking the drop-down box next to the restart (⟳) button in the menu bar, and choosing \"Code\".\n", | |
| "\n", | |
| "**Question 1.3.1.** Add a code cell below this one. Write code in it that prints out:\n", | |
| " \n", | |
| " A whole new cell! ♪🌏♪\n", | |
| "\n", | |
| "(That musical note symbol is like the Earth symbol. Its long-form name is `\\N{EIGHTH NOTE}`.)\n", | |
| "\n", | |
| "Run your cell to verify that it works." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 1.4. Errors\n", | |
| "Python is a language, and like natural human languages, it has rules. It differs from natural language in two important ways:\n", | |
| "1. The rules are *simple*. You can learn most of them in a few weeks and gain reasonable proficiency with the language in a semester.\n", | |
| "2. The rules are *rigid*. If you're proficient in a natural language, you can understand a non-proficient speaker, glossing over small mistakes. A computer running Python code is not smart enough to do that.\n", | |
| "\n", | |
| "Whenever you write code, you'll make mistakes. When you run a code cell that has errors, Python will sometimes produce error messages to tell you what you did wrong.\n", | |
| "\n", | |
| "Errors are okay; even experienced programmers make many errors. When you make an error, you just have to find the source of the problem, fix it, and move on.\n", | |
| "\n", | |
| "We have made an error in the next cell. Run it and see what happens." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "print(\"This line is missing something.\"" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "You should see something like this (minus our annotations):\n", | |
| "\n", | |
| "<img src=\"error.jpg\"/>\n", | |
| "\n", | |
| "The last line of the error output attempts to tell you what went wrong. The *syntax* of a language is its structure, and this `SyntaxError` tells you that you have created an illegal structure. \"`EOF`\" means \"end of file,\" so the message is saying Python expected you to write something more (in this case, a right parenthesis) before finishing the cell.\n", | |
| "\n", | |
| "There's a lot of terminology in programming languages, but you don't need to know it all in order to program effectively. If you see a cryptic message like this, you can often get by without deciphering it. (Of course, if you're frustrated, ask a neighbor or a TA for help.)\n", | |
| "\n", | |
| "Try to fix the code above so that you can run the cell and see the intended message instead of an error." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 1.5. Submitting your work\n", | |
| "All assignments in the course will be distributed as notebooks like this one, and you will submit your work from the notebook. We will use a system called OK that checks your work and helps you submit. At the top of each assignment, you'll see a cell like the one below that prompts you to identify yourself. Run it and follow the instructions. Please use your @berkeley.edu address when logging in." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Don't change this cell; just run it. \n", | |
| "# The result will give you directions about how to log in to the submission system, called OK.\n", | |
| "# Once you're logged in, you can run this cell again, but it won't ask you who you are because\n", | |
| "# it remembers you. However, you will need to log in once per assignment.\n", | |
| "from client.api.notebook import Notebook\n", | |
| "ok = Notebook('lab01.ok')\n", | |
| "_ = ok.auth(inline=True)\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "When you finish an assignment, you need to submit it by running the submit command below. It's OK to submit multiple times, OK will only try to grade your final submission for each assignment. Don't forget to submit your lab assignment at the end of section, even if you haven't finished everything." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.submit()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# 2. Numbers\n", | |
| "\n", | |
| "Quantitative information arises everywhere in data science. In addition to representing commands to print out lines, expressions can represent numbers and methods of combining numbers. The expression `3.2500` evaluates to the number 3.25. (Run the cell and see.)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "3.2500" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Notice that we didn't have to `print`. When you run a notebook cell, if the last line has a value, then Jupyter helpfully prints out that value for you. However, it won't print out prior lines automatically." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true, | |
| "scrolled": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "print(2)\n", | |
| "3\n", | |
| "4" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Above, you should see that 4 is the value of the last expression, 2 is printed, but 3 is lost forever because it was neither printed nor last.\n", | |
| "\n", | |
| "You don't want to print everything all the time anyway. But if you feel sorry for 3, change the cell above to print it." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 2.1. Arithmetic\n", | |
| "The line in the next cell subtracts. Its value is what you'd expect. Run it." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "3.25 - 1.5" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Many basic arithmetic operations are built in to Python. The textbook section on [Expressions](http://www.inferentialthinking.com/chapters/03/1/expressions.html) describes all the arithmetic operators used in the course. The common operator that differs from typical math notation is `**`, which raises one number to the power of the other. So, `2**3` stands for $2^3$ and evaluates to 8. \n", | |
| "\n", | |
| "The order of operations is what you learned in elementary school, and Python also has parentheses. For example, compare the outputs of the cells below. Use parentheses for a happy new year!" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "1+6*5-6*3**2*2**3/4*7" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "1+(6*5-(6*3))**2*((2**3)/4*7)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "In standard math notation, the first expression is\n", | |
| "\n", | |
| "$$1 + 6 \\times 5 - 6 \\times 3^2 \\times \\frac{2^3}{4} \\times 7,$$\n", | |
| "\n", | |
| "while the second expression is\n", | |
| "\n", | |
| "$$1 + (6 \\times 5 - (6 \\times 3))^2 \\times (\\frac{(2^3)}{4} \\times 7).$$\n", | |
| "\n", | |
| "**Question 2.1.1.** Write a Python expression in this next cell that's equal to $5 \\times (3 \\frac{10}{11}) - 50 \\frac{1}{3} + 2^{.5 \\times 22} - \\frac{7}{33}$. That's five times three and ten elevenths, minus fifty and a third, plus two to the power of half 22, minus 7 33rds. By \"$3 \\frac{10}{11}$\" we mean $3+\\frac{10}{11}$, not $3 \\times \\frac{10}{11}$.\n", | |
| "\n", | |
| "Replace the ellipses (`...`) with your expression. Try to use parentheses only when necessary.\n", | |
| "\n", | |
| "*Hint:* The correct output should start with a familiar number." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "..." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# 3. Names\n", | |
| "In natural language, we have terminology that lets us quickly reference very complicated concepts. We don't say, \"That's a large mammal with brown fur and sharp teeth!\" Instead, we just say, \"Bear!\"\n", | |
| "\n", | |
| "Similarly, an effective strategy for writing code is to define names for data as we compute it, like a lawyer would define terms for complex ideas at the start of a legal document to simplify the rest of the writing.\n", | |
| "\n", | |
| "In Python, we do this with *assignment statements*. An assignment statement has a name on the left side of an `=` sign and an expression to be evaluated on the right." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "ten = 3 * 2 + 4" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "When you run that cell, Python first evaluates the first line. It computes the value of the expression `3 * 2 + 4`, which is the number 10. Then it gives that value the name `ten`. At that point, the code in the cell is done running.\n", | |
| "\n", | |
| "After you run that cell, the value 10 is bound to the name `ten`:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "ten" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "The statement `ten = 3 * 2 + 4` is not asserting that `ten` is already equal to `3 * 2 + 4`, as we might expect by analogy with math notation. Rather, that line of code changes what `ten` means; it now refers to the value 10, whereas before it meant nothing at all.\n", | |
| "\n", | |
| "If the designers of Python had been ruthlessly pedantic, they might have made us write\n", | |
| "\n", | |
| " define the name ten to hereafter have the value of 3 * 2 + 4 \n", | |
| "\n", | |
| "instead. You will probably appreciate the brevity of \"`=`\"! But keep in mind that this is the real meaning.\n", | |
| "\n", | |
| "**Question 3.1.** Try writing code that uses a name (like `eleven`) that hasn't been assigned to anything. You'll see an error!" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "A common pattern in Jupyter notebooks is to assign a value to a name and then immediately evaluate the name in the last line in the cell so that the value is displayed as output. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "close_to_pi = 355/113\n", | |
| "close_to_pi" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Another common pattern is that a series of lines in a single cell will build up a complex computation in stages, naming the intermediate results." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "bimonthly_salary = 840\n", | |
| "monthly_salary = 2 * bimonthly_salary\n", | |
| "number_of_months_in_a_year = 12\n", | |
| "yearly_salary = number_of_months_in_a_year * monthly_salary\n", | |
| "yearly_salary" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Names in Python can have letters (upper- and lower-case letters are both okay and count as different letters), underscores, and numbers. The first character can't be a number (otherwise a name might look like a number). And names can't contain spaces, since spaces are used to separate pieces of code from each other.\n", | |
| "\n", | |
| "Other than those rules, what you name something doesn't matter *to Python*. For example, this cell does the same thing as the above cell, except everything has a different name:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "a = 840\n", | |
| "b = 2 * a\n", | |
| "c = 12\n", | |
| "d = c * b\n", | |
| "d" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**However**, names are very important for making your code *readable* to yourself and others. The cell above is shorter, but it's totally useless without an explanation of what it does.\n", | |
| "\n", | |
| "According to a famous joke among computer scientists, naming things is one of the two hardest problems in computer science. (The other two are cache invalidation and \"off-by-one\" errors. And people say computer scientists have an odd sense of humor...)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 3.2.** Assign the name `seconds_in_a_decade` to the number of seconds between midnight January 1, 2010 and midnight January 1, 2020.\n", | |
| "\n", | |
| "*Hint:* If you're stuck, the next section shows you how to get hints." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Change the next line so that it computes the number of\n", | |
| "# seconds in a decade and assigns that number the name\n", | |
| "# seconds_in_a_decade.\n", | |
| "seconds_in_a_decade = ...\n", | |
| "\n", | |
| "# We've put this line in this cell so that it will print\n", | |
| "# the value you've given to seconds_in_a_decade when you\n", | |
| "# run it. You don't need to change this.\n", | |
| "seconds_in_a_decade" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 3.1. Checking your code\n", | |
| "Now that you know how to name things, you can start using the built-in *tests* to check whether your work is correct. Try not to change the contents of the test cells. Running the following cell will test whether you have assigned `seconds_in_a_decade` correctly in Question 3.2. If you haven't, this test will tell you the correct answer. Resist the urge to just copy it, and instead try to adjust your expression. (Sometimes the tests will give hints about what went wrong...)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Test cell; please do not change!\n", | |
| "_ = ok.grade('q32')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 3.2. Comments\n", | |
| "You may have noticed this line in the cell above:\n", | |
| "\n", | |
| " # Test cell; please do not change!\n", | |
| "\n", | |
| "That is called a *comment*. It doesn't make anything happen in Python; Python ignores anything on a line after a #. Instead, it's there to communicate something about the code to you, the human reader. Comments are extremely useful.\n", | |
| "\n", | |
| "<img src=\"http://imgs.xkcd.com/comics/future_self.png\">" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 3.3. Application: A physics experiment\n", | |
| "\n", | |
| "On the Apollo 15 mission to the Moon, astronaut David Scott famously replicated Galileo's physics experiment in which he showed that gravity accelerates objects of different mass at the same rate. Because there is no air resistance for a falling object on the surface of the Moon, even two objects with very different masses and densities should fall at the same rate. David Scott compared a feather and a hammer.\n", | |
| "\n", | |
| "You can run the following cell to watch a video of the experiment." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from IPython.display import YouTubeVideo\n", | |
| "# The original URL is:\n", | |
| "# https://www.youtube.com/watch?v=U7db6ZeLR5s\n", | |
| "YouTubeVideo(\"U7db6ZeLR5s\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Here's the transcript of the video:\n", | |
| "\n", | |
| "**167:22:06 Scott**: Well, in my left hand, I have a feather; in my right hand, a hammer. And I guess one of the reasons we got here today was because of a gentleman named Galileo, a long time ago, who made a rather significant discovery about falling objects in gravity fields. And we thought where would be a better place to confirm his findings than on the Moon. And so we thought we'd try it here for you. The feather happens to be, appropriately, a falcon feather for our Falcon. And I'll drop the two of them here and, hopefully, they'll hit the ground at the same time. \n", | |
| "\n", | |
| "**167:22:43 Scott**: How about that!\n", | |
| "\n", | |
| "**167:22:45 Allen**: How about that! (Applause in Houston)\n", | |
| "\n", | |
| "**167:22:46 Scott**: Which proves that Mr. Galileo was correct in his findings." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Newton's Law.** Using this footage, we can also attempt to confirm another famous bit of physics: Newton's law of universal gravitation. Newton's laws predict that any object dropped near the surface of the Moon should fall\n", | |
| "\n", | |
| "$$\\frac{1}{2} G \\frac{M}{R^2} t^2 \\text{ meters}$$\n", | |
| "\n", | |
| "after $t$ seconds, where $G$ is a universal constant, $M$ is the moon's mass in kilograms, and $R$ is the moon's radius in meters. So if we know $G$, $M$, and $R$, then Newton's laws let us predict how far an object will fall over any amount of time.\n", | |
| "\n", | |
| "To verify the accuracy of this law, we will calculate the difference between the predicted distance the hammer drops and the actual distance. (If they are different, it might be because Newton's laws are wrong, or because our measurements are imprecise, or because there are other factors affecting the hammer for which we haven't accounted.)\n", | |
| "\n", | |
| "Someone studied the video and estimated that the hammer was dropped 113 cm from the surface. Counting frames in the video, the hammer falls for 1.2 seconds (36 frames)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 3.3.1.** Complete the code in the next cell to fill in the *data* from the experiment." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# t, the duration of the fall in the experiment, in seconds.\n", | |
| "# Fill this in.\n", | |
| "time = ...\n", | |
| "\n", | |
| "# The estimated distance the hammer actually fell, in meters.\n", | |
| "# Fill this in.\n", | |
| "estimated_distance_m = ..." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.grade('q331')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 3.3.2.** Now, complete the code in the next cell to compute the difference between the predicted and estimated distances (in meters) that the hammer fell in this experiment.\n", | |
| "\n", | |
| "This just means translating the formula above ($\\frac{1}{2}G\\frac{M}{R^2}t^2$) into Python code. You'll have to replace each variable in the math formula with the name we gave that number in Python code." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# First, we've written down the values of the 3 universal\n", | |
| "# constants that show up in Newton's formula.\n", | |
| "\n", | |
| "# G, the universal constant measuring the strength of gravity.\n", | |
| "gravity_constant = 6.674 * 10**-11\n", | |
| "\n", | |
| "# M, the moon's mass, in kilograms.\n", | |
| "moon_mass_kg = 7.34767309 * 10**22\n", | |
| "\n", | |
| "# R, the radius of the moon, in meters.\n", | |
| "moon_radius_m = 1.737 * 10**6\n", | |
| "\n", | |
| "# The distance the hammer should have fallen over the\n", | |
| "# duration of the fall, in meters, according to Newton's\n", | |
| "# law of gravity. The text above describes the formula\n", | |
| "# for this distance given by Newton's law.\n", | |
| "# **YOU FILL THIS PART IN.**\n", | |
| "predicted_distance_m = ...\n", | |
| "\n", | |
| "# Here we've computed the difference between the predicted\n", | |
| "# fall distance and the distance we actually measured.\n", | |
| "# If you've filled in the above code, this should just work.\n", | |
| "difference = predicted_distance_m - estimated_distance_m\n", | |
| "difference" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.grade('q332')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 4. Calling functions\n", | |
| "\n", | |
| "The most common way to combine or manipulate values in Python is by calling functions. Python comes with many built-in functions that perform common operations.\n", | |
| "\n", | |
| "For example, the `abs` function takes a single number as its argument and returns the absolute value of that number. The absolute value of a number is its distance from 0 on the number line, so `abs(5)` is 5 and `abs(-5)` is also 5." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "abs(5)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "abs(-5)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 4.1. Application: Computing walking distances\n", | |
| "Chunhua is on the corner of 7th Avenue and 42nd Street in Midtown Manhattan, and she wants to know far she'd have to walk to get to Gramercy School on the corner of 10th Avenue and 34th Street.\n", | |
| "\n", | |
| "She can't cut across blocks diagonally, since there are buildings in the way. She has to walk along the sidewalks. Using the map below, she sees she'd have to walk 3 avenues (long blocks) and 8 streets (short blocks). In terms of the given numbers, she computed 3 as the difference between 7 and 10, *in absolute value*, and 8 similarly. \n", | |
| "\n", | |
| "Chunhua also knows that blocks in Manhattan are all about 80m by 274m (avenues are farther apart than streets). So in total, she'd have to walk $(80 \\times |42 - 34| + 274 \\times |7 - 10|)$ meters to get to the park.\n", | |
| "\n", | |
| "<img src=\"map.jpg\"/>\n", | |
| "\n", | |
| "**Question 4.1.1.** Finish the line `num_avenues_away = ...` in the next cell so that the cell calculates the distance Chunhua must walk and gives it the name `manhattan_distance`. Everything else has been filled in for you. **Use the `abs` function.**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Here's the number of streets away:\n", | |
| "num_streets_away = abs(42-34)\n", | |
| "\n", | |
| "# Compute the number of avenues away in a similar way:\n", | |
| "num_avenues_away = ...\n", | |
| "\n", | |
| "street_length_m = 80\n", | |
| "avenue_length_m = 274\n", | |
| "\n", | |
| "# Now we compute the total distance Chunhua must walk.\n", | |
| "manhattan_distance = street_length_m*num_streets_away + avenue_length_m*num_avenues_away\n", | |
| "\n", | |
| "# We've included this line so that you see the distance\n", | |
| "# you've computed when you run this cell. You don't need\n", | |
| "# to change it, but you can if you want.\n", | |
| "manhattan_distance" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Be sure to run the next cell to test your code." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.grade('q411')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "##### Multiple arguments\n", | |
| "Some functions take multiple arguments, separated by commas. For example, the built-in `max` function returns the maximum argument passed to it." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "max(2, -3, 4, -5)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# 5. Understanding nested expressions\n", | |
| "Function calls and arithmetic expressions can themselves contain expressions. You saw an example in the last question:\n", | |
| "\n", | |
| " abs(42-34)\n", | |
| "\n", | |
| "has 2 number expressions in a subtraction expression in a function call expression. And you probably wrote something like `abs(7-10)` to compute `num_avenues_away`.\n", | |
| "\n", | |
| "Nested expressions can turn into complicated-looking code. However, the way in which complicated expressions break down is very regular.\n", | |
| "\n", | |
| "Suppose we are interested in heights that are very unusual. We'll say that a height is unusual to the extent that it's far away on the number line from the average human height. [An estimate](http://press.endocrine.org/doi/full/10.1210/jcem.86.9.7875?ck=nck&) of the average adult human height (averaging, we hope, over all humans on Earth today) is 1.688 meters.\n", | |
| "\n", | |
| "So if Aditya is 1.21 meters tall, then his height is $|1.21 - 1.688|$, or $.478$, meters away from the average. Here's a picture of that:\n", | |
| "\n", | |
| "<img src=\"numberline_0.png\">\n", | |
| "\n", | |
| "And here's how we'd write that in one line of Python code:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "abs(1.21 - 1.688)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "What's going on here? `abs` takes just one argument, so the stuff inside the parentheses is all part of that *single argument*. Specifically, the argument is the value of the expression `1.21 - 1.688`. The value of that expression is `-.478`. That value is the argument to `abs`. The absolute value of that is `.478`, so `.478` is the value of the full expression `abs(1.21 - 1.688)`.\n", | |
| "\n", | |
| "Picture simplifying the expression in several steps:\n", | |
| "\n", | |
| "1. `abs(1.21 - 1.688)`\n", | |
| "2. `abs(-.478)`\n", | |
| "3. `.478`\n", | |
| "\n", | |
| "In fact, that's basically what Python does to compute the value of the expression." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Question 5.1.** Say that Botan's height is 1.85 meters. In the next cell, use `abs` to compute the absolute value of the difference between Botan's height and the average human height. Give that value the name `botan_distance_from_average_m`.\n", | |
| "\n", | |
| "<img src=\"numberline_1.png\">" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Replace the ... with an expression to compute the absolute\n", | |
| "# value of the difference between Botan's height (1.85m) and\n", | |
| "# the average human height.\n", | |
| "botan_distance_from_average_m = ...\n", | |
| "\n", | |
| "# Again, we've written this here so that the distance you\n", | |
| "# compute will get printed when you run this cell.\n", | |
| "botan_distance_from_average_m" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.grade('q51')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## 5.1. More nesting\n", | |
| "Now say that we want to compute the most unusual height among Aditya's and Botan's heights. We'll use the function `max`, which (again) takes two numbers as arguments and returns the larger of the two arguments. Combining that with the `abs` function, we can compute the biggest distance from the average among the two heights:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Just read and run this cell.\n", | |
| "\n", | |
| "aditya_height_m = 1.21\n", | |
| "botan_height_m = 1.85\n", | |
| "average_adult_human_height_m = 1.688\n", | |
| "\n", | |
| "# The biggest distance from the average human height, among the two heights:\n", | |
| "biggest_distance_m = max(abs(aditya_height_m - average_adult_human_height_m), abs(botan_height_m - average_adult_human_height_m))\n", | |
| "\n", | |
| "# Print out our results in a nice readable format:\n", | |
| "print(\"The biggest distance from the average height among these two people is\", biggest_distance_m, \"meters.\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "The line where `biggest_distance_m` is computed looks complicated, but we can break it down into simpler components just like we did before.\n", | |
| "\n", | |
| "The basic recipe is repeated simplification of small parts of the expression:\n", | |
| "* We start with the simplest components whose values we know, like plain names or numbers. (Examples: `aditya_height_m` or `5`.)\n", | |
| "* **Find a simple-enough group of expressions:** We look for a group of simple expressions that are directly connected to each other in the code, for example by arithmetic or as arguments to a function call.\n", | |
| "* **Evaluate that group:** We evaluate the arithmetic expressions or function calls they're part of, and replace the whole group with whatever we compute. (Example: `aditya_height_m - average_adult_human_height_m` becomes `-.478`.)\n", | |
| "* **Repeat:** We continue this process, using the values of the glommed-together stuff as our new basic components. (Example: `abs(-.478)` becomes `.478`, and `max(.478, .162)` later becomes `.478`.)\n", | |
| "* We keep doing that until we've evaluated the whole expression.\n", | |
| "\n", | |
| "You can run the next cell to see a slideshow of that process." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from IPython.display import IFrame\n", | |
| "IFrame('https://docs.google.com/presentation/d/1urkX-nRsD8VJvcOnJsjmCy0Jpv752Ssn5Pphg2sMC-0/embed?start=false&loop=false&delayms=3000', 800, 600)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Ok, your turn. \n", | |
| "\n", | |
| "**Question 5.1.1.** Given the heights of the Splash Triplets from the Golden State Warriors, write an expression that computes the smallest difference between any of the three heights. Your expression shouldn't have any numbers in it, only function calls and the names `klay`, `steph`, and `kevin`. Give the value of your expression the name `min_height_difference`." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# The three players' heights, in meters:\n", | |
| "klay = 2.01 # Klay Thompson is 6'7\"\n", | |
| "steph = 1.91 # Steph Curry is 6'3\"\n", | |
| "kevin = 2.06 # Kevin Durant is officially 6'9\", but many suspect that he is taller.\n", | |
| " # (Further complicating matters, membership of the \"Splash Triplets\" \n", | |
| " # is disputed, since it was originally used in reference to \n", | |
| " # Klay Thompson, Steph Curry, and Draymond Green.)\n", | |
| "\n", | |
| "# We'd like to look at all 3 pairs of heights, compute the absolute\n", | |
| "# difference between each pair, and then find the smallest of those\n", | |
| "# 3 absolute differences. This is left to you! If you're stuck,\n", | |
| "# try computing the value for each step of the process (like the\n", | |
| "# difference between Klay's heigh and Steph's height) on a separate\n", | |
| "# line and giving it a name (like klay_steph_height_diff).\n", | |
| "min_height_difference = ..." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.grade('q511')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "You're done with Lab 1! Be sure to run the tests and verify that they all pass, then choose **Save and Checkpoint** from the **File** menu, then run the final cell (two below this one) to submit your work. If you submit multiple times, your last submission will be counted." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# For your convenience, you can run this cell to run all the tests at once!\n", | |
| "import os\n", | |
| "_ = [ok.grade(q[:-3]) for q in os.listdir(\"tests\") if q.startswith('q')]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Important.** Before you leave lab, run this final cell to submit your work." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "_ = ok.submit()" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "anaconda-cloud": {}, | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.5.3" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 1 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment