<jupyter_start><jupyter_text>Python4DS Quick Review - 5Based on Kaggle Python Course  LoopsLoops are a way to repeatedly execute some code. Here's an example:<jupyter_code>planets = [
    'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus',
    'Neptune'
]

for planet in planets:
    print(planet, end=' ')  # print all on same line<jupyter_output>Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune<jupyter_text>The ``for`` loop specifies - the variable name to use (in this case, `planet`)- the set of values to loop over (in this case, `planets`)You use the word "``in``" to link them together.The object to the right of the "``in``" can be any object that supports iteration. Basically, if it can be thought of as a group of things, you can probably loop over it. In addition to lists, we can iterate over the elements of a tuple:<jupyter_code>multiplicands = (2, 2, 2, 3, 3, 5)
product = 1

for mult in multiplicands:
    product = product * mult
product<jupyter_output><empty_output><jupyter_text>You can even loop through each character in a string:<jupyter_code>s = 'steganograpHy is the practicE of conceaLing a file, message, image, or video within another fiLe, message, image, Or video.'
msg = ''

# print all the uppercase letters in s, one at a time
for char in s:
    if char.isupper():
        print(char, end='')<jupyter_output>HELLO<jupyter_text>range()`range()` is a function that returns a sequence of numbers. It turns out to be very useful for writing loops.For example, if we want to repeat some action 5 times:<jupyter_code>for i in range(5):
    print("Doing important work. i =", i)<jupyter_output>Doing important work. i = 0
Doing important work. i = 1
Doing important work. i = 2
Doing important work. i = 3
Doing important work. i = 4<jupyter_text>``while`` loopsThe other type of loop in Python is a ``while`` loop, which iterates until some condition is met:<jupyter_code>i = 0
while i < 10:
    print(i, end=' ')
    i += 1<jupyter_output>0 1 2 3 4 5 6 7 8 9<jupyter_text>The argument of the ``while`` loop is evaluated as a boolean statement, and the loop is executed until the statement evaluates to False.  List comprehensionsList comprehensions are one of Python's most beloved and unique features. The easiest way to understand them is probably to just look at a few examples:<jupyter_code>squares = [n**2 for n in range(10)]
squares<jupyter_output><empty_output><jupyter_text>Here's how we would do the same thing without a list comprehension:<jupyter_code>squares = []
for n in range(10):
    squares.append(n**2)
squares<jupyter_output><empty_output><jupyter_text>We can also add an `if` condition:<jupyter_code>short_planets = [planet for planet in planets if len(planet) < 6]
short_planets<jupyter_output><empty_output><jupyter_text>(If you're familiar with SQL, you might think of this as being like a "WHERE" clause)Here's an example of filtering with an `if` condition *and* applying some transformation to the loop variable:<jupyter_code># str.upper() returns an all-caps version of a string
loud_short_planets = [planet.upper() + '!' for planet in planets if len(planet) < 6]
loud_short_planets<jupyter_output><empty_output><jupyter_text>People usually write these on a single line, but you might find the structure clearer when it's split up over 3 lines:<jupyter_code>[
    planet.upper() + '!' 
    for planet in planets 
    if len(planet) < 6
]<jupyter_output><empty_output><jupyter_text>(Continuing the SQL analogy, you could think of these three lines as SELECT, FROM, and WHERE)The expression on the left doesn't technically have to involve the loop variable (though it'd be pretty unusual for it not to). What do you think the expression below will evaluate to? Press the 'output' button to check.<jupyter_code>[32 for planet in planets]<jupyter_output><empty_output><jupyter_text>List comprehensions combined with functions like `min`, `max`, and `sum` can lead to impressive one-line solutions for problems that would otherwise require several lines of code. For example, compare the following two cells of code that do the same thing.<jupyter_code>def count_negatives(nums):
    """Return the number of negative numbers in the given list.
    
    >>> count_negatives([5, -1, -2, 0, 3])
    2
    """
    n_negative = 0
    for num in nums:
        if num < 0:
            n_negative = n_negative + 1
    return n_negative<jupyter_output><empty_output><jupyter_text>Here's a solution using a list comprehension:<jupyter_code>def count_negatives(nums):
    return len([num for num in nums if num < 0])<jupyter_output><empty_output><jupyter_text>Much better, right?Well if all we care about is minimizing the length of our code, this third solution is better still!<jupyter_code>def count_negatives(nums):
    # Reminder: in the "booleans and conditionals" exercises, we learned about a quirk of 
    # Python where it calculates something like True + True + False + True to be equal to 3.
    return sum([num < 0 for num in nums])<jupyter_output><empty_output><jupyter_text>Which of these solutions is the "best" is entirely subjective. Solving a problem with less code is always nice, but it's worth keeping in mind the following lines from [The Zen of Python](https://en.wikipedia.org/wiki/Zen_of_Python):> Readability counts.  > Explicit is better than implicit.So, use these tools to make compact readable programs. But when you have to choose, favor code that is easy for others to understand.  Exercises  1.Have you ever felt debugging involved a bit of luck? The following program has a bug. Try to identify the bug and fix it.<jupyter_code>def has_lucky_number(nums):
    """Return whether the given list of numbers is lucky. A lucky list contains
    at least one number divisible by 7.
    """
    for num in nums:
        if num % 7 == 0:
            return True
        else:
            return False<jupyter_output><empty_output><jupyter_text>Try to identify the bug and fix it in the cell below:<jupyter_code>def has_lucky_number(nums):
    """Return whether the given list of numbers is lucky. A lucky list contains
    at least one number divisible by 7.
    """
    for num in nums:
        if num % 7 == 0:
            return True
        else:
            return False<jupyter_output><empty_output><jupyter_text>2. a.Look at the Python expression below. What do you think we'll get when we run it? When you've made your prediction, uncomment the code and run the cell to see if you were right.<jupyter_code>#[1, 2, 3, 4] > 2<jupyter_output><empty_output><jupyter_text>bR and Python have some libraries (like numpy and pandas) compare each element of the list to 2 (i.e. do an 'element-wise' comparison) and give us a list of booleans like `[False, False, True, True]`. Implement a function that reproduces this behaviour, returning a list of booleans corresponding to whether the corresponding element is greater than n.<jupyter_code>def elementwise_greater_than(L, thresh):
    """Return a list with the same length as L, where the value at index i is 
    True if L[i] is greater than thresh, and False otherwise.
    
    >>> elementwise_greater_than([1, 2, 3, 4], 2)
    [False, False, True, True]
    """
    pass<jupyter_output><empty_output><jupyter_text>3.Complete the body of the function below according to its docstring.<jupyter_code>def menu_is_boring(meals):
    """Given a list of meals served over some period of time, return True if the
    same meal has ever been served two days in a row, and False otherwise.
    """
    pass<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08243064729194187, 'fraction_numerical': 0.00977542932628798, 'mean_word_length': 4.388612099644128, 'pattern_counts': {'":': 0, '<': 80, '<?xml version=': 0, '>': 82, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '442116', 'license': 'MIT', 'n_tokens_mistral': 2365, 'n_tokens_neox': 2257, 'n_words': 985, 'path': '00_Curso_Folder/1_Fundamentals/Class_4/notebooks/5_loops-and-list-comprehensions.ipynb', 'repo_name': 'vssorru/UNIFEI-IESTI01-T01-2021.1', 'size': '7570'}