<jupyter_start><jupyter_text>**Practice:**        Delete the following sentence and replace it with the future name of your firstborn daughter:     Multiple correct responses.<jupyter_code>print("My favorite animal is a")
print("cat, but I am a")
print("human")<jupyter_output>My favorite animal is a
cat, but I am a
human<jupyter_text>**Practice:** Change the cell above so that the output looks like this    My favorite animal is a    cat, but I am a    human<jupyter_code>print("Trump says the system is broken")<jupyter_output>Trump says the system is broken<jupyter_text>The last line of the error output attempts to tell you what went wrong.  The *syntax* of a language is its structure or the set of rules that governs it. `SyntaxError` tells you that you have created an illegal structure, or in other words, you broke the rules.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, you can often get by without deciphering it.**Practice**: Now fix it so that it runs<jupyter_code>12+(4*7-(6*3))**4*(2**5/3)*6<jupyter_output><empty_output><jupyter_text>In standard math notation, the expression is$$12 + 4 \times 7 - 6 \times 3^4 \times \frac{2^5}{3} \times 6,$$**Practice:** Change the code so that it evaluates to$$12 + (4 \times 7 - (6 \times 3))^4 \times (\frac{2^5}{3} \times 6).$$When you run the code, the output should be 640012.0**Practice:** Now remove the `...` in the cell below and replace it with an expression 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}$.<jupyter_code>5 * (3 + 10/11) - 50 * 1/3 + 2**(0.5*22) - (7/33)
topic_sentence = 1<jupyter_output><empty_output><jupyter_text>**Practice:** Assign a value to the variable above so that there are no errors.You can also assign numbers or mathematical expressions to variables. **Practice:** Follow the instructions in the following cell of code to calculate the area of a rectangle given by three coordinate points A(2, 7), B(-1, 3), C(-10, 16) and then find the unknown last point D(?, ?):<jupyter_code># First visualize where these three points lie in order for the following directions to make sense

# Calculate the lengths of the two sides below using the Distance Formula (the Pythagorean Theorem) 
# Note: the square root of x is also equal to x^0.5
side_AB = ((2-(-1))**2 + (7-3)**2)**0.5
side_AC = ((2 - (-10))**2 + (7 - 16)**2)**0.5

# Now using side_AB and side_AC, you can calculate the area
area_rec = side_AB * side_AC

# Now find the coordinates for the missing point on the rectangle D. Feel free to draw this out on a piece
# of paper to visualize. Also, we recommend using mutliple lines.
...
D_x = -7
D_y = 20
print("(" + str(D_x) + ", " + str(D_y) + ")")<jupyter_output>(-7, 20)<jupyter_text>**Practice:** Using only one line of code set `largest_abs_product` to the value of the largest possible absolute value of a product of two of the following numbers: `-7, 2, -4, 6`.<jupyter_code># Note: possible combinations of two of -7, 2, -4, 6 are -7 & 2, -7 & -4, -7 & 6, 2 & -4, 2 & 6, -4 & 6.
# Make sure Python is doing all the computation for you!
largest_abs_product = max(abs(-7 * 2), abs(-7 * 4), abs(-7 * 6), abs(2 * -4), abs(2 * 6), abs(-4 * 6))<jupyter_output><empty_output><jupyter_text>**Practice:** In the next cell, import the `IPython.display` module.Then use the `Image` function within the module using your intuition about how to call methods from modules. The `Image` function takes in the URL of a picture as a string and returns the image. Put this link in the function:    `https://i.ytimg.com/vi/IcWtX1UvIks/maxresdefault.jpg`<jupyter_code>import IPython.display
art = IPython.display.Image("https://i.ytimg.com/vi/IcWtX1UvIks/maxresdefault.jpg")
art<jupyter_output><empty_output><jupyter_text>**Practice:** Define a function that takes in four numbers, calculates the average, and then returns true if the average is larger than Euler's number and false if it is not. Make sure to test your function.Note: It'll be useful to know some comparative *operators*:`==` returns `True` if the values on either side of it are equal to each other`!=` returns `True` if the values on either side of it are *not* equal to each other`>` returns `True` if the value on the left is larger than the one the right`>=` returns `True` if the value on the left is greater than or equal the one on the right`<` and `<=` do what you would expect.<jupyter_code>def four_avg(a,b,c,d):
    return (a + b + c + d) / 4 > math.e<jupyter_output><empty_output><jupyter_text>**Practice:** Define a function named `type_of_triangle` that takes in the lengths of the three sides of a triangle and returns whether the triangle is an equilateral, isosceles, or scalene triangle.For example, `type_of_triangle(4, 4, 6)` should return `"isosceles"`.Try to use up as few lines as you can.<jupyter_code>def type_of_triangle(a,b,c):
    if a == b or b == c or a == c:
        if a == b and b == c:
            return 'equilateral'
        else:
            return 'isosceles'
    return 'scalene'<jupyter_output><empty_output><jupyter_text>**Practice:** Use what you've learned to fill in the following code:<jupyter_code>import numpy as np
#The following two lines splits up the first few paragraphs of a NY Times article into an array of words in the article
article_as_string = "It sounds like a Hollywood blockbuster. Day Zero is coming to Cape Town this April. Everyone, be warned. The government cautions that the Day Zero threat will surpass anything a major city has faced since World War II or the Sept. 11 attacks. Talks are underway with South Africa’s police because normal policing will be entirely inadequate. Residents, their nerves increasingly frayed, speak in whispers of impending chaos. The reason for the alarm is simple: The city’s water supply is dangerously close to running dry. If water levels keep falling, Cape Town will declare Day Zero in less than three months. Taps in homes and businesses will be turned off until the rains come. The city’s four million residents will have to line up for water rations at 200 collection points. The city is bracing for the impact on public health and social order. When Day Zero comes, they’ll have to call in the army,” said <NAME>, who was filling his white S.U.V. with big containers of water at a natural spring where people waited in a long, anxious line. It wasn’t supposed to turn out this way for Cape Town. This city is known for its strong environmental policies, including its careful management of water in an increasingly dry corner of the world."
article_as_array = np.array(article_as_string.split())

#Notice the len() function returns the length of an array or string
print(len(article_as_array))
print(len("Everything"))
#Define a function num_long_words that takes in an array of words, and returns to the number of words in the array that has more
#than 4 characters
def num_long_words(array):
    num_words = 0
    for i in array:
        if len(i) > 4:
            num_words += 1
    return num_words

num_long_words(article_as_array)<jupyter_output><empty_output><jupyter_text>Exercises **Practice**: You dropped your phone in the toilet, so you've lost all of your contacts! You've heard about this mythical technology called *The Yellow Pages*, which has the contacts of everyone in Berkeley. Someone has stored all of the contacts in *The Yellow Pages* in Python in the following way:It is a dictionary with 26 keys, each corresponding to each letter of the alphabet. The value corresponding to each letter is a list of all contacts whose first name starts with that letter. Each of the values in the list is another dictionary which stores the information about a person.Here's an abbreviated example of this:<jupyter_code>yellow_pages_abbrev = {
    'A': [
        {
            'first': 'Ajay',
            'last': 'Raj',
            'phone_number': '5551234',
            'address': 'Not My Address 94709'
        },
        {
            'first': 'Ajay',
            'last': 'NotRaj',
            'phone_number': '5554321',
            'address': 'Fake Address 94720'
        }
    ]
}
def get_phone_number(yellow_pages, first_name, last_name):
    """Searches The Yellow Pages (stored in yellow_pages) for the phone number of someone whose first name and last name are given. 
    
    >>> get_phone_number(yellow_pages_abbrev, 'Ajay', 'Raj')
    '5551234'
    """
    for letter in yellow_pages:
        for person in yellow_pages[letter]:
            if person['first'] == first_name and person['last'] == last_name:
                return person['phone_number']

get_phone_number(yellow_pages_abbrev, 'Ajay', 'Raj')<jupyter_output><empty_output><jupyter_text>**Practice**: The Fibonacci sequence is defined as follows: $$f_n = f_{n-1} + f_{n-2}$$ where $f_i$ is the $i$th element of the sequence. The 0th and 1st elements of the sequence are 0 and 1.Fill in the following function to compute the $n$th element of the sequence.<jupyter_code># Hint: this is how the range() function works
for i in range(1, 5):
    print(i)
# If you are having some trouble, take a look back at the Lists and Arrays section!
def fib(n):
    """
    >>> [fib(i) for i in range(8)]
    [0, 1, 1, 2, 3, 5, 8, 13]
    """
    f = [0, 1]
    for i in range(2, n + 1):
        f.append(f[i - 1] + f[i - 2])
    return f[n]
# you can check your answer by running this cell, if it does not error, your code is correct
assert [fib(i) for i in range(8)] == [0, 1, 1, 2, 3, 5, 8, 13]<jupyter_output><empty_output><jupyter_text>**Practice**: While working on your Jupyter Notebook for learning python, you suddenly teleported to the ESPN sports center, where people now believe that you’re a basketball analyst! Luckily, you’ve watched basketball for a while, and can speak on players’ performances, but a lot of your analysis also comes from the stats that players have in the game. However, the stats recorded for the game for each player aren’t as clean as you might want them to be- they’re only recorded by quarter! Here’s an example of what the stats look like (they also only contain points per quarter):<jupyter_code>game_stats = {
   '<NAME>': [7,5,5,9],
   '<NAME>': [10,2,3,5],
   '<NAME>': [3,12,4,8],
   '<NAME>': [2,4,3,26]
}<jupyter_output><empty_output><jupyter_text>For now, the only metric as an analyst you care about are the points. However, just from the points, you can answer all sorts of questions!Determine the number of points each player got throughout the game.<jupyter_code>def points(name, stats):
    """
    >>> points('<NAME>', game_stats)
    26

    >>> points('<NAME>-Smith', game_stats)
    35
    """
    return sum(stats[name])<jupyter_output><empty_output><jupyter_text>Determine who had the most points throughout the game (hint: You may need a variable to store who’s had the highest number of points so far and another to variable to compare the points function above with.<jupyter_code>def highest_points(stats):
    """
    >>> highest_points(game_stats)
    '<NAME>'
    """
    greatest = ("", 0)
    for person in stats:
        if sum(stats[person]) > greatest[1]:
            greatest = (person, sum(stats[person]))
    return greatest[0]<jupyter_output><empty_output><jupyter_text>Determine who stayed the most consistent throughout the game by calculating the standard deviation for each player. (Hint: standard deviation can be calculate with np.std)<jupyter_code>def most_consistent(stats):
    """
    >>> most_consistent(game_stats)
    '<NAME>'
    """
    most_consistent = ("", 1E99)
    for person in stats:
        if np.std(stats[person]) < most_consistent[1]:
            most_consistent = (person, np.std(stats[person]))
    return most_consistent[0]<jupyter_output><empty_output><jupyter_text>Challenge Problem **Note: this is for people who already know the Python basics.**Some "refresher" documentation:- https://docs.python.org/3/tutorial/datastructures.htmllist-comprehensions- https://docs.python.org/2/library/itertools.htmlitertools.combinations- https://docs.python.org/2/library/functions.html<jupyter_code>from geopy.geocoders import Nominatim
geolocator = Nominatim()
building_names = []
with open('buildings.txt', 'r') as f:
    for line in f.readlines():
        building_names.append(line.strip())
names_and_coordinates = {}
for i, building_name in enumerate(building_names):
    location = geolocator.geocode(building_name)
    if location and 'Berkeley' in location.address:
        names_and_coordinates[building_name] = (location.latitude, location.longitude)
    print('Halls scanned: {0}/{1}'.format(i + 1, len(building_names)), end='\r')
from itertools import combinations
from math import sin, cos, sqrt, atan2, radians
def haversine(lat1, lon1, lat2, lon2):
    """Calculates the straight line distance between two latitude-longitude coordinates"""
    # approximate radius of earth in miles
    R = 3959.0

    lat1_r = radians(lat1)
    lon1_r = radians(lon1)
    lat2_r = radians(lat2)
    lon2_r = radians(lon2)

    dlon = lon2_r - lon1_r
    dlat = lat2_r - lat1_r

    a = sin(dlat / 2)**2 + cos(lat1_r) * cos(lat2_r) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))

    return R * c<jupyter_output><empty_output><jupyter_text>You are trying to create the most evil schedule on campus, which contains back-to-back classes in buildings that are the furthest apart on campus. You are given the buildings and coordinates of those locations in a dictionary that can be queried as follows:<jupyter_code>names_and_coordinates['Soda Hall'], names_and_coordinates['Cory Hall']<jupyter_output><empty_output><jupyter_text>Write a function that returns a tuple of the furthest two buildings on campus, and the distance in miles between the two.<jupyter_code># Solution
def furthest_walk_on_campus(names_and_coordinates):
    def key_fn(entry):
        (bname1, (lat1, lon1)), (bname2, (lat2, lon2)) = entry
        return haversine(lat1, lon1, lat2, lon2)
    (bname1, (lat1, lon1)), (bname2, (lat2, lon2)) = max(
        combinations(
            names_and_coordinates.items(),
            2
        ),
        key=key_fn
    )
    return bname1, bname2, haversine(lat1, lon1, lat2, lon2)
print('The furthest walk on campus is {0} to {1}, which is {2} miles'.format(*furthest_walk_on_campus(names_and_coordinates)))<jupyter_output>The furthest walk on campus is Koshland Hall to Simon Hall, which is 0.7209184926896222 miles
{'fraction_non_alphanumeric': 0.10239162929745889, 'fraction_numerical': 0.024120125016986002, 'mean_word_length': 4.116093152589503, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 105, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '286208', 'license': 'MIT', 'n_tokens_mistral': 4740, 'n_tokens_neox': 4460, 'n_words': 1861, 'path': 'Python/intro-python-18/Introduction to Python (Answers).ipynb', 'repo_name': 'susa-berkeley/crash-course', 'size': '14788'}