In [1]:
numbers_str = '496,258,332,550,506,699,7,985,171,581,436,804,736,528,65,855,68,279,721,120'
In the following cell, complete the code with an expression that evaluates to a list of integers derived from the raw numbers in numbers_str
, assigning the value of this expression to a variable numbers
. If you do everything correctly, executing the cell should produce the output 985
(not '985'
).
In [2]:
numbers = [int(i) for i in numbers_str.split(',')] # replace 'None' with an expression, as described above
max(numbers)
Out[2]:
Great! We'll be using the numbers
list you created above in the next few problems.
In the cell below, fill in the square brackets so that the expression evaluates to a list of the ten largest values in numbers
. Expected output:
[506, 528, 550, 581, 699, 721, 736, 804, 855, 985]
(Hint: use a slice.)
In [3]:
sorted(numbers)[-10:]
Out[3]:
In the cell below, write an expression that evaluates to a list of the integers from numbers
that are evenly divisible by three, sorted in numerical order. Expected output:
[120, 171, 258, 279, 528, 699, 804, 855]
In [4]:
sorted([i for i in numbers if i % 3 == 0])
Out[4]:
Okay. You're doing great. Now, in the cell below, write an expression that evaluates to a list of the square roots of all the integers in numbers
that are less than 100. In order to do this, you'll need to use the sqrt
function from the math
module, which I've already imported for you. Expected output:
[2.6457513110645907, 8.06225774829855, 8.246211251235321]
(These outputs might vary slightly depending on your platform.)
In [5]:
from math import sqrt
[sqrt(i) for i in numbers if i < 100]
Out[5]:
Still looking good. Let's do a few more with some different data. In the cell below, I've defined a data structure and assigned it to a variable planets
. It's a list of dictionaries, with each dictionary describing the characteristics of a planet in the solar system. Make sure to run the cell before you proceed.
In [6]:
planets = [
{'diameter': 0.382,
'mass': 0.06,
'moons': 0,
'name': 'Mercury',
'orbital_period': 0.24,
'rings': 'no',
'type': 'terrestrial'},
{'diameter': 0.949,
'mass': 0.82,
'moons': 0,
'name': 'Venus',
'orbital_period': 0.62,
'rings': 'no',
'type': 'terrestrial'},
{'diameter': 1.00,
'mass': 1.00,
'moons': 1,
'name': 'Earth',
'orbital_period': 1.00,
'rings': 'no',
'type': 'terrestrial'},
{'diameter': 0.532,
'mass': 0.11,
'moons': 2,
'name': 'Mars',
'orbital_period': 1.88,
'rings': 'no',
'type': 'terrestrial'},
{'diameter': 11.209,
'mass': 317.8,
'moons': 67,
'name': 'Jupiter',
'orbital_period': 11.86,
'rings': 'yes',
'type': 'gas giant'},
{'diameter': 9.449,
'mass': 95.2,
'moons': 62,
'name': 'Saturn',
'orbital_period': 29.46,
'rings': 'yes',
'type': 'gas giant'},
{'diameter': 4.007,
'mass': 14.6,
'moons': 27,
'name': 'Uranus',
'orbital_period': 84.01,
'rings': 'yes',
'type': 'ice giant'},
{'diameter': 3.883,
'mass': 17.2,
'moons': 14,
'name': 'Neptune',
'orbital_period': 164.8,
'rings': 'yes',
'type': 'ice giant'}]
Now, in the cell below, write a list comprehension that evaluates to a list of names of the planets that have a diameter greater than four earth radii. Expected output:
['Jupiter', 'Saturn', 'Uranus']
In [7]:
[i['name'] for i in planets if i['diameter'] > 4]
Out[7]:
In the cell below, write a single expression that evaluates to the sum of the mass of all planets in the solar system. Expected output: 446.79
In [8]:
sum([i['mass'] for i in planets])
Out[8]:
Good work. Last one with the planets. Write an expression that evaluates to the names of the planets that have the word giant
anywhere in the value for their type
key. Expected output:
['Jupiter', 'Saturn', 'Uranus', 'Neptune']
In [9]:
[i['name'] for i in planets if 'giant' in i['type']]
Out[9]:
EXTREME BONUS ROUND: Write an expression below that evaluates to a list of the names of the planets in ascending order by their number of moons. (The easiest way to do this involves using the key
parameter of the sorted
function, which we haven't yet discussed in class! That's why this is an EXTREME BONUS question.) Expected output:
['Mercury', 'Venus', 'Earth', 'Mars', 'Neptune', 'Uranus', 'Saturn', 'Jupiter']
In [10]:
[i['name'] for i in sorted(planets, key=lambda planet: planet['moons'])]
Out[10]:
In the following section, we're going to do a bit of digital humanities. (I guess this could also be journalism if you were... writing an investigative piece about... early 20th century American poetry?) We'll be working with the following text, Robert Frost's The Road Not Taken. Make sure to run the following cell before you proceed.
In [11]:
import re
poem_lines = ['Two roads diverged in a yellow wood,',
'And sorry I could not travel both',
'And be one traveler, long I stood',
'And looked down one as far as I could',
'To where it bent in the undergrowth;',
'',
'Then took the other, as just as fair,',
'And having perhaps the better claim,',
'Because it was grassy and wanted wear;',
'Though as for that the passing there',
'Had worn them really about the same,',
'',
'And both that morning equally lay',
'In leaves no step had trodden black.',
'Oh, I kept the first for another day!',
'Yet knowing how way leads on to way,',
'I doubted if I should ever come back.',
'',
'I shall be telling this with a sigh',
'Somewhere ages and ages hence:',
'Two roads diverged in a wood, and I---',
'I took the one less travelled by,',
'And that has made all the difference.']
In the cell above, I defined a variable poem_lines
which has a list of lines in the poem, and import
ed the re
library.
In the cell below, write a list comprehension (using re.search()
) that evaluates to a list of lines that contain two words next to each other (separated by a space) that have exactly four characters. (Hint: use the \b
anchor. Don't overthink the "two words in a row" requirement.)
Expected result:
['Then took the other, as just as fair,',
'Had worn them really about the same,',
'And both that morning equally lay',
'I doubted if I should ever come back.',
'I shall be telling this with a sigh']
In [12]:
[line for line in poem_lines if re.search(r'\b\w{4}\s\w{4}\b', line)]
Out[12]:
Good! Now, in the following cell, write a list comprehension that evaluates to a list of lines in the poem that end with a five-letter word, regardless of whether or not there is punctuation following the word at the end of the line. (Hint: Try using the ?
quantifier. Is there an existing character class, or a way to write a character class, that matches non-alphanumeric characters?) Expected output:
['And be one traveler, long I stood',
'And looked down one as far as I could',
'And having perhaps the better claim,',
'Though as for that the passing there',
'In leaves no step had trodden black.',
'Somewhere ages and ages hence:']
In [13]:
# TA-COMMENT: Could also use the ? quantifier instead of {0,1}
[line for line in poem_lines if re.search('\w{5}\.{0,1}$', line)]
Out[13]:
Okay, now a slightly trickier one. In the cell below, I've created a string all_lines
which evaluates to the entire text of the poem in one string. Execute this cell.
In [14]:
all_lines = " ".join(poem_lines)
Now, write an expression that evaluates to all of the words in the poem that follow the word 'I'. (The strings in the resulting list should not include the I
.) Hint: Use re.findall()
and grouping! Expected output:
['could', 'stood', 'could', 'kept', 'doubted', 'should', 'shall', 'took']
In [15]:
re.findall('I\s(.*?)\s', all_lines)
Out[15]:
Finally, something super tricky. Here's a list of strings that contains a restaurant menu. Your job is to wrangle this plain text, slightly-structured data into a list of dictionaries.
In [16]:
entrees = [
"Yam, Rosemary and Chicken Bowl with Hot Sauce $10.95",
"Lavender and Pepperoni Sandwich $8.49",
"Water Chestnuts and Peas Power Lunch (with mayonnaise) $12.95 - v",
"Artichoke, Mustard Green and Arugula with Sesame Oil over noodles $9.95 - v",
"Flank Steak with Lentils And Tabasco Pepper With Sweet Chilli Sauce $19.95",
"Rutabaga And Cucumber Wrap $8.49 - v"
]
You'll need to pull out the name of the dish and the price of the dish. The v
after the hyphen indicates that the dish is vegetarian---you'll need to include that information in your dictionary as well. I've included the basic framework; you just need to fill in the contents of the for
loop.
Expected output:
[{'name': 'Yam, Rosemary and Chicken Bowl with Hot Sauce ',
'price': 10.95,
'vegetarian': False},
{'name': 'Lavender and Pepperoni Sandwich ',
'price': 8.49,
'vegetarian': False},
{'name': 'Water Chestnuts and Peas Power Lunch (with mayonnaise) ',
'price': 12.95,
'vegetarian': True},
{'name': 'Artichoke, Mustard Green and Arugula with Sesame Oil over noodles ',
'price': 9.95,
'vegetarian': True},
{'name': 'Flank Steak with Lentils And Tabasco Pepper With Sweet Chilli Sauce ',
'price': 19.95,
'vegetarian': False},
{'name': 'Rutabaga And Cucumber Wrap ', 'price': 8.49, 'vegetarian': True}]
In [17]:
menu = []
for item in entrees:
dictitem = {}
dictitem['name'] = re.search('(.*)\s\$', item).group(1) # why 1? 0 = whole match?
dictitem['price'] = float(re.search('\d{1,2}\.\d{2}', item).group())
dictitem['vegetarian'] = bool(re.match('.*v$', item))
menu.append(dictitem)
menu
Out[17]:
Great work! You are done. Go cavort in the sun, or whatever it is you students do when you're done with your homework
In [ ]: