{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Homework 2: Arrays and Tables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Recommended Reading**: \n",
"* [Data Types](https://www.inferentialthinking.com/chapters/04/data-types.html) \n",
"* [Sequences](https://www.inferentialthinking.com/chapters/05/sequences.html)\n",
"* [Tables](https://www.inferentialthinking.com/chapters/06/tables.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please complete this notebook by filling in the cells provided. Before you begin, execute the following cell to load some necessary information for the assignment. \n",
"\n",
"Homework 2 is due Thursday, 1/30 at 11:59pm. Start early so that you can come to office hours if you're stuck. Check the website for the office hours schedule.\n",
"Late work will not be accepted as per the policies of this course. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Don't change this cell; just run it. \n",
"\n",
"import numpy as np\n",
"from datascience import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Creating Arrays\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 1.1.** Make an array called `weird_numbers` containing the following numbers (in the given order):\n",
"\n",
"1. -2\n",
"2. the sine of 1.2\n",
"3. 3\n",
"4. 5 to the power of the cosine of 1.2\n",
"\n",
"*Hint:* `sin` and `cos` are functions in the `math` module."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Our solution involved one extra line of code before creating\n",
"# weird_numbers.\n",
"...\n",
"weird_numbers = ...\n",
"weird_numbers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 1.2.** Make an array called `book_title_words` containing the following three strings: \"Eats\", \"Shoots\", and \"and Leaves\"."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"book_title_words = ...\n",
"book_title_words"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Strings have a method called `join`. `join` takes one argument, an array of strings. It returns a single string. Specifically, the value of `a_string.join(an_array)` is a single string that's the [concatenation](https://en.wikipedia.org/wiki/Concatenation) (\"putting together\") of all the strings in `an_array`, **except** `a_string` is inserted in between each string.\n",
"\n",
"**Question 1.3.** Use the array `book_title_words` and the method `join` to make two strings:\n",
"\n",
"1. \"Eats, Shoots, and Leaves\" (call this one `with_commas`)\n",
"2. \"Eats Shoots and Leaves\" (call this one `without_commas`)\n",
"\n",
"*Hint:* If you're not sure what `join` does, first try just calling, for example, `\"foo\".join(book_title_words)` ."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with_commas = ...\n",
"without_commas = ...\n",
"\n",
"# These lines are provided just to print out your answers.\n",
"print('with_commas:', with_commas)\n",
"print('without_commas:', without_commas)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Indexing Arrays\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These exercises give you practice accessing individual elements of arrays. In Python (and in many programming languages), elements are accessed by *index*, so the first element is the element at index 0. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 2.1.** The cell below creates an array of some numbers. Set `third_element` to the third element of `some_numbers`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"some_numbers = make_array(-1, -3, -6, -10, -15)\n",
"\n",
"third_element = ...\n",
"third_element"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 2.2.** The next cell creates a table that displays some information about the elements of `some_numbers` and their order. Run the cell to see the partially-completed table, then fill in the missing information in the cell (the strings that are currently \"???\") to complete the table."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"elements_of_some_numbers = Table().with_columns(\n",
" \"English name for position\", make_array(\"first\", \"second\", \"???\", \"???\", \"fifth\"),\n",
" \"Index\", make_array(\"???\", \"1\", \"2\", \"???\", \"4\"),\n",
" \"Element\", some_numbers)\n",
"elements_of_some_numbers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 2.3.** You'll sometimes want to find the *last* element of an array. Suppose an array has 142 elements. What is the index of its last element?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"index_of_last_element = ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"More often, you don't know the number of elements in an array, its *length*. (For example, it might be a large dataset you found on the Internet.) The function `len` takes a single argument, an array, and returns the `len`gth of that array (an integer).\n",
"\n",
"**Question 2.4.** The cell below loads an array called `president_birth_years`. The last element in that array is the most recent birth year of any deceased president as of 2017. Assign that year to `most_recent_birth_year`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"president_birth_years = Table.read_table(\"president_births.csv\").column('Birth Year')\n",
"\n",
"most_recent_birth_year = ...\n",
"most_recent_birth_year"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 2.5.** Finally, assign `sum_of_birth_years` to the sum of the first, tenth, and last birth year in `president_birth_years`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sum_of_birth_years = ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Basic Array Arithmetic\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3.1.** Multiply the numbers 42, 4224, 42422424, and -250 by 157. For this question, **don't** use arrays."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"first_product = ...\n",
"second_product = ...\n",
"third_product = ...\n",
"fourth_product = ...\n",
"print(first_product, second_product, third_product, fourth_product)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3.2.** Now, do the same calculation, but using an array called `numbers` and only a single multiplication (`*`) operator. Store the 4 results in an array named `products`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"numbers = ...\n",
"products = ...\n",
"products"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3.3.** Oops, we made a typo! Instead of 157, we wanted to multiply each number by 1577. Compute the fixed products in the cell below using array arithmetic. Notice that your job is really easy if you previously defined an array containing the 4 numbers."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fixed_products = ...\n",
"fixed_products"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3.4.** We've loaded an array of temperatures in the next cell. Each number is the highest temperature observed on a day at a climate observation station, mostly from the US. Since they're from the US government agency [NOAA](https://www.noaa.gov), all the temperatures are in Fahrenheit. Convert them all to Celsius by first subtracting 32 from them, then multiplying the results by $\\frac{5}{9}$. Make sure to **ROUND** each result to the nearest integer using the `np.round` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"max_temperatures = Table.read_table(\"temperatures.csv\").column(\"Daily Max Temperature\")\n",
"\n",
"celsius_max_temperatures = ...\n",
"celsius_max_temperatures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 3.5.** The cell below loads all the *lowest* temperatures from each day (in Fahrenheit). Compute the size of the daily temperature range for each day. That is, compute the difference between each daily maximum temperature and the corresponding daily minimum temperature. **Give your answer in Celsius!** Make sure **NOT** to round your answer for this question!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"min_temperatures = Table.read_table(\"temperatures.csv\").column(\"Daily Min Temperature\")\n",
"\n",
"celsius_temperature_ranges = ...\n",
"celsius_temperature_ranges"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. World Population\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"The cell below loads a table of estimates of the world population for different years, starting in 1950. The estimates come from the [US Census Bureau website](https://www.census.gov/en.html)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"world = Table.read_table(\"world_population.csv\").select('Year', 'Population')\n",
"world.show(4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The name `population` is assigned to an array of population estimates."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"population = world.column(1)\n",
"population"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this question, you will apply some built-in Numpy functions to this array."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"The difference function `np.diff` subtracts each element in an array by the element that preceeds it. As a result, the length of the array `np.diff` returns will always be one less than the length of the input array."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"The cumulative sum function `np.cumsum` outputs an array of partial sums. For example, the third element in the output array corresponds to the sum of the first, second, and third elements."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 4.1.** Very often in data science, we are interested understanding how values change with time. Use `np.diff` and `np.max` (or just `max`) to calculate the largest annual change in population between any two consecutive years."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"largest_population_change = ...\n",
"largest_population_change"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 4.2.** Describe in words the result of the following expression. What do the values in the resulting array represent (choose one)?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.cumsum(np.diff(population))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1) The total population change between consecutive years, starting at 1951.\n",
"\n",
"2) The total population change between 1950 and each later year, starting at 1951.\n",
"\n",
"3) The total population change between 1950 and each later year, starting inclusively at 1950 (with a total change of 0)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Assign cumulative_sum_answer to 1, 2, or 3\n",
"cumulative_sum_answer = ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Old Faithful\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Old Faithful is a geyser in Yellowstone that erupts every 44 to 125 minutes (according to [Wikipedia](https://en.wikipedia.org/wiki/Old_Faithful)). People are [often told that the geyser erupts every hour](http://yellowstone.net/geysers/old-faithful/), but in fact the waiting time between eruptions is more variable. Let's take a look."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 5.1.** The first line below assigns `waiting_times` to an array of 272 consecutive waiting times between eruptions, taken from a classic 1938 dataset. Assign the names `shortest`, `longest`, and `average` so that the `print` statement is correct."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"waiting_times = Table.read_table('old_faithful.csv').column('waiting')\n",
"\n",
"shortest = ...\n",
"longest = ...\n",
"average = ...\n",
"\n",
"print(\"Old Faithful erupts every\", shortest, \"to\", longest, \"minutes and every\", average, \"minutes on average.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 5.2.** Assign `biggest_decrease` to the biggest decrease in waiting time between two consecutive eruptions. For example, the third eruption occurred after 74 minutes and the fourth after 62 minutes, so the decrease in waiting time was 74 - 62 = 12 minutes. \n",
"\n",
"*Hint*: You'll need an array arithmetic function [mentioned in the textbook](https://www.inferentialthinking.com/chapters/05/1/arrays.html#Functions-on-Arrays).\n",
"\n",
"*Hint 2*: The function you use may report positive or negative values. You will have to determine if the biggest decrease corresponds to the highest or lowest value. Ultimately, we want to return the absolute value of the biggest decrease so if it is a negative number, make it positive."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"biggest_decrease = ...\n",
"biggest_decrease"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 5.3.** If you expected Old Faithful to erupt every hour, you would expect to wait a total of `60 * k` minutes to see `k` eruptions. Set `difference_from_expected` to an array with 272 elements, where the element at index `i` is the absolute difference between the expected and actual total amount of waiting time to see the first `i+1` eruptions. *Hint*: You'll need to compare a cumulative sum to a range.\n",
"\n",
"For example, since the first three waiting times are 79, 54, and 74, the total waiting time for 3 eruptions is 79 + 54 + 74 = 207. The expected waiting time for 3 eruptions is 60 * 3 = 180. Therefore, `difference_from_expected.item(2)` should be $|207 - 180| = 27$."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"difference_from_expected = ...\n",
"difference_from_expected"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 5.4.** If instead you guess that each waiting time will be the same as the previous waiting time, how many minutes would your guess differ from the actual time, averaging over every wait time except the first one.\n",
"\n",
"For example, since the first three waiting times are 79, 54, and 74, the average difference between your guess and the actual time for just the second and third eruption would be $\\frac{|79-54|+ |54-74|}{2} = 22.5$."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"average_error = ...\n",
"average_error"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Tables\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.1.** Suppose you have 4 apples, 3 oranges, and 3 pineapples. (Perhaps you're using Python to solve a high school Algebra problem.) Create a table that contains this information. It should have two columns: \"fruit name\" and \"count\". Give it the name `fruits`.\n",
"\n",
"**Note:** Use lower-case and singular words for the name of each fruit, like `\"apple\"`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Our solution uses 1 statement split over 3 lines.\n",
"fruits = ...\n",
" ...\n",
" ...\n",
"fruits"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.2.** The file `inventory.csv` contains information about the inventory at a fruit stand. Each row represents the contents of one box of fruit. Load it as a table named `inventory`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"inventory = ...\n",
"inventory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.3.** Does each box at the fruit stand contain a different fruit?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Set all_different to \"Yes\" if each box contains a different fruit or \n",
"# to \"No\" if multiple boxes contain the same fruit\n",
"all_different = ...\n",
"all_different"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.4.** The file `sales.csv` contains the number of fruit sold from each box last Saturday. It has an extra column called \"price per fruit (\\$)\" that's the price *per item of fruit* for fruit in that box. The rows are in the same order as the `inventory` table. Load these data into a table called `sales`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sales = ...\n",
"sales"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.5.** How many fruits did the store sell in total on that day?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"total_fruits_sold = ...\n",
"total_fruits_sold"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.6.** What was the store's total revenue (the total price of all fruits sold) on that day?\n",
"\n",
"*Hint:* If you're stuck, think first about how you would compute the total revenue from just the grape sales."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"total_revenue = ...\n",
"total_revenue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Question 6.7.** Make a new table called `remaining_inventory`. It should have the same rows and columns as `inventory`, except that the amount of fruit sold from each box should be subtracted from that box's count, so that the \"count\" is the amount of fruit remaining after Saturday."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"remaining_inventory = ...\n",
" ...\n",
" ...\n",
" ...\n",
"remaining_inventory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. Submission\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"Once you're finished, submit your assignment as a .ipynb (Jupyter Notebook) and .pdf (download as .html, then print to save as a .pdf) on the class Canvas site."
]
}
],
"metadata": {
"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.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 1
}