<jupyter_start><jupyter_text>Midterm miscellanea Data 765 tutoringYou have a midterm! Uh, I guess there's not much more to say in terms of an introduction. Control flow (iteration and branching) Explain, write, or fix the following loops<jupyter_code>coordinates = []

for x in range(25):
    coordinates.append([])
    for y in range(10):
        coordinates[x].append([])
        for z in range(5):
            coordinates[x][y].append(z)<jupyter_output><empty_output><jupyter_text>What's wrong with this loop?**Hint**: Three issues.Would a `for` loop be better here?<jupyter_code>animals = ["cat", "giraffe", "duck", "rabbit"]
i = 0
while i <= len(animals):
    print(animals[0])<jupyter_output><empty_output><jupyter_text>Guessing gameFill out the guessing game below. Guesses higher than the `target` should print "Too high" or something similar. Guesses lower than `target` should print "Too low." Correct guesses should end the loop.Users may input garbage values such as strings. You need a `try` block  to catch and consume `ValueError`s. You can allow other errors to bubble up unless you have a better way of handling them.<jupyter_code>import random

def guessing_game(low=0, high=10):
    """A guessing game!

    Parameters
    ----------
    low: int
        Lower range of the guessing game. Must be < high.
    high: int
        Upper range of the guessing game.
    """
    if low > high:
        raise ValueError(f"{low} > {high}; lower bounds higher than upper.")
    # Generate a random number
    # See: https://docs.python.org/3/library/random.html
    target = random.randrange(low, high)

    # The := or walrus operator is new, and you don't have to know it.
    # := allows assigning to variables in the middle of an expression.
    # The variable guess is scoped within the while loop, but it's also
    # evaluated as the while loop's condition. As a result, empty strings
    # would automatically break the while loop because they're falsey
    # while non-empty strings would continue the loop. The result is elegant.
    while guess := input(f"Guess a number between {low} and {high}: "):
        # Check for invalid input that cannot be coerced to integers.
        ____:
            # Convert guess to an integer from a string.
            guess = int(guess)

            ____ ____ ____ ____:
                ____
            ____ ____ ____ ____:
                print("Too low!")
            else:
                print(f"Correct! The number is {target}")
                ____
        ____ ValueError:
            pass

guessing_game()<jupyter_output><empty_output><jupyter_text>Complete the `if` statements Age GateWrite a small age gate function that checks if a person is allowed to watch a movie or purchase a video game.Instead of the ESRB, we'll just have three maturity checks: "adults", "teens", and "kids."* "adults": Only people >= 18 are granted access.* "teens": Only people >= 13 are granted access.* "kids": Everyone has access.Invalid ages (i.e. < 0) or ratings should raise a `ValueError`.`age_gate` should be declared with two parameters, one for `age` and another for `rating`, a string.<jupyter_code>def age_gate(age, rating):
    pass

def age_gate_test():
    # This would be better with a fuzzer
    msg = "Test failed with age: {} and rating: {}"
    assert age_gate(18, "kids"), msg.format(18, "kids")
    assert not age_gate(10, "adults"), msg.format(10, "adults")
    assert age_gate(7, "kids"), msg.format(7, "kids")
    assert age_gate(13, "teens"), msg.format(13, "teens")
    assert age_gate(13, "adults"), msg.format(13, "adults")

    # Invalid cases
    valueerror_msg = "ValueError not raised when expected."
    try:
        bad_return = age_gate(-1, "kids")
        assert bad_return and not bad_return, valueerror_msg
    except ValueError:
        pass

    try:
        bad_return = age_gate(26, "meow")
        assert bad_return and not bad_return, valueerror_msg
    except ValueError:
        pass
    

age_gate_test()<jupyter_output><empty_output><jupyter_text>Flat iterComplete the if statement below. The function should check if the element is an `Iterable`.**Note:** You don't need to understand `yield` or `yield from` in order to complete the loop.However, for those of you who are curious, `yield` is for generators. `yield` pauses the execution of a function and returns a value. The use case for this is to generate values without creating all of the values at once and holding them in memory. Instead, `yield` allows you you to create values when requested. `range()` is something like a generator which is why `list(range())` for a loop is wrong.<jupyter_code>from collections.abc import Iterable

def flat_iter(iterator):
    """Return elements over arbitrarily nested iterables.
    
    Parameters
    ----------
    iterator: Iterable
        Iterator; may be nested.

    Yields
    ------
    Consecutive elements of an iterator.
    """

    for element in iterator:
        ____ ____(____, ____):
            yield from flat_iter(element)
        else:
            yield element<jupyter_output><empty_output><jupyter_text>How would you test `flat_iter()`?What would the following code output? Hint: Read the docstring.<jupyter_code>nested = [1, 2, [3], [14], [42, 56, 70, [84, 98]]]

for x in flat_iter(nested):
    print(x, end=' ')<jupyter_output><empty_output><jupyter_text>What would the code snippet below print?<jupyter_code>max_nested = max(flat_iter([[[list(range(1000))]]]))

print(max_nested)<jupyter_output><empty_output><jupyter_text>Complete the function below by filling out the `for` loop. You don't need to know RegEx in order to complete the loop.<jupyter_code>import re

fake_tweets = ["#cats are amazing!!!!!!!!!!!111111111111111",
               "Everyone loves castst #cats #kitty #meow",
               "I just spent $50000 onCHOCOLATE!! #yum",
               "ppl say recrusion is divine but its rly just a headache #programming",
               "Python is better than R #python #rlang"
               ]

def hashtags(tweets):
    """Pull out hashtags from Tweets.

    Parameters
    ----------
    tweets: Iterable[str]
        Iterable of Tweets as strings.

    Return
    ------
    List[str]
        Hashtags
    """
    octothorpes = []
    pattern = r"(#[\w\d]+)"

    for ____ in ____:
        ____.____(re.findall(pattern, tweet))
    
    return octothorpes

hashtags(fake_tweets)<jupyter_output><empty_output><jupyter_text>Which data structure is _better_ than a `list` here if we're only concerned about **unique hashtags**?  Standard libraryPython's standard library contains modules for basic data structures, higher level function tools, statistics, sockets, and many more. Python is often called "batteries included" because of its standard library. You should be familiar with the basic data types as well common data structure operations. For example, you should know that you can append, extend, and remove elements from a `list`. You should understand what a dictionary is and when you'd use one over a `list`.[Python's standard library](https://docs.python.org/3/library/)[Python's built-in functions](https://docs.python.org/3/library/functions.html)[List methods](https://docs.python.org/3/tutorial/datastructures.htmlmore-on-lists)[Dictionary methods](https://docs.python.org/3/tutorial/datastructures.htmldictionaries)[String methods](https://docs.python.org/3/library/string.html) Mean function$\bar{X} = \frac{\sum_{i = 0}^{N} X_i}{N}$Write a function to calculate a mean using built in functions. Raise a `ValueError` if the input is empty. Are these strings equal? Why or why not?<jupyter_code># First
"cat" == "Cat"

# Second
"cat " == "cat"<jupyter_output><empty_output><jupyter_text>Would this expression evaluate to `True` or `False`?<jupyter_code>"." and "cat".upper() == "CAT".lower() == "cat".upper() or not False<jupyter_output><empty_output><jupyter_text>Capitalize and remove whitespace from this string using string methods.<jupyter_code>id_soft = ("the communities for Doom 1 & 2 and the Quakes are still flourishing "
           "decades after release because their engines are open source  ")<jupyter_output><empty_output><jupyter_text>What are the contents of the two `list`s below? Why?<jupyter_code>animals = ["cat", "giraffe"]
more_animals = animals

animals.append("duck")<jupyter_output><empty_output><jupyter_text>What about these two `list`s? Why?<jupyter_code>pokemon = [["Espeon", "Psyduck"]]
more_pokemon = pokemon[0].copy()

more_pokemon.extend(["Drampa", "Skitty"])<jupyter_output><empty_output><jupyter_text>Why can't we use `list`s as dictionary keys? What does this say about `list`s? In other words, why is this illegal?<jupyter_code>broken_map = {
    ["Espeon",
     "Umbreon"]: ["Eeveelution", "Gen2", "Cat", "Dog"]
}<jupyter_output><empty_output><jupyter_text>Why do we need `if ch in chain_iter` in the code below?<jupyter_code>import itertools

engines_one = "ECS, or entity-component-system, game engines are designed to leverage SIMD and MIMD."
engines_two = "Unlike OOP, ECS is closer to functional programming."
engines_three = "ECS may seem more abstract at first, but ultimately ECS is great for performance."
engines_four = "NumPy's benefits are similar to ECS. This is known as data-driven programming."

def count(iterable):
    """Count unicode characters.
    
    Parameters
    ----------
    iterable: Iterable[str]
        Iterable of strings from which to count chars.
    
    Return
    ------
    dict[str, int]
        Dictionary of counts.
    """
    chain_iter = map(lambda ch: ch.lower(),
                     itertools.chain.from_iterable(iterable))

    counts = {}
    for ch in chain_iter:
        ch_count = counts.get(ch)
        counts[ch] = ch_count + 1 if ch_count else 1
    return counts

count([engines_one, engines_two, engines_three, engines_four])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10762241292276628, 'fraction_numerical': 0.009187279151943463, 'mean_word_length': 3.596751740139211, 'pattern_counts': {'":': 3, '<': 64, '<?xml version=': 0, '>': 65, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '223756', 'license': 'Unlicense', 'n_tokens_mistral': 3095, 'n_tokens_neox': 2931, 'n_words': 1048, 'path': 'notebooks/05-midterm_miscellanea.ipynb', 'repo_name': 'joshuamegnauth54/data765_tutoring', 'size': '9905'}