Python for Everybody - Iterations: Loop Idioms

Tell us what’s happening:
Describe your issue in detail here.

Your code so far

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.41

Challenge: Python for Everybody - Iterations: Loop Idioms

Link to the challenge:

In the code:

smallest = None
print ("Before:", smallest)
for itervar in [3, 41, 12, 9, 74, 15]:
    if smallest is None or itervar < smallest:
        smallest = itervar
        break
    print ("Loop:", itervar, smallest)
print ("Smallest:", smallest)

we are getting output smallest: 3.

I request you to explain how it is giving 3 as output.
Also, how the code is running (in steps).

And why break is the line which will cause error.
Moreover as I did some alteration in the list I found out that it is giving the first element as the smallest in the output , so first how is it even showing the smallest number as none is the smallest and any real number is greater than none which means the if statement becomes false and second why it is giving the first element as the smallest element (even if it is a larger number).

so, does it not imply that the code is not right for finding the smallest element?

hoping for an early response

IF doesn’t need a break statement, but it’s also not indented to break the FOR loop. What is the break for? You want the loop to continue until it’s looked at each element.

It looks like it gets to:

if smallest is None

which is true, so then:

smallest = itervar

So now smallest = 3

break

End of loop / program exits.

1 Like

There’s a nice tool, that allows for visualizing code execution: https://pythontutor.com

1 Like

I ran your code in my IDE and did not get an error, if the break line is giving you an error try sending the error message so we can see what it is.
I think what you want this code to do is:

  1. start with smallest = None
  2. Iteratively select elements of the list
  3. If the current element is less than the value of the ‘smallest’ variable, we set ‘smallest’ equal to our current variable
    4… Proceed to next element of the list if there is one

But what it is actually doing is:

  1. Check the current value of ‘itervar’ against current value of ‘smallest’, and check if ‘smallest’ is equal to None. Since smallest is equal to None to start with, the loop breaks as expected without ever iterating through any of the other elements of the list.
1 Like
smallest = None
print ("Before:", smallest)
for itervar in [3, 41, 12, 9, 74, 15]:

    # The right side of or will not ever be True. Smallest is set to None
    if smallest is None or itervar < smallest:

        # Setting smallest to itervar and the breaking the loop
        # Will not ever make it to the next element in the loop
        smallest = itervar
        break

    # Will not ever print this because the loop exited
    print ("Loop:", itervar, smallest)
print ("Smallest:", smallest)

This is the language used in the original challenge:

Below is code to find the smallest value from a list of values. One line has an error that will cause the code to not work as expected. Which line is it?:

So the “error” in the instruction is not referred to the one that leads to error message during running, but the one that makes the code not work as expected. And the break
line is the bug as it breaks the for loop after the first iteration, in which smallest is set to be the first value of the list, and in this case the smallest value by coincidence.

And contrary to your reasoning, None is an unique data type, which means nothing, can’t be said to be smallest and can’t be compared to any value. If you type None < 0 in a cell and run it, it will give you a TypeError. In fact the line that raises my eyebrows is if smallest is None or itervar < smallest:. When smallest is set to None initially, the second condition is prone to give TypeError. What surprises me is that line does not raise an error code when it is running. It seems that in actual running of the or operator in Python, when the first condition is met, it will return True right away without checking the second condition. I have tried changing the order of the two conditions ( if itervar < smallest or smallest is None:), and it does raise a TypeError!

Given this loophole, the code runs in the following way:

  1. smallest is set to None
  2. “Before: None” is printed
  3. In the first interation of the for loop, itervar is set to 3
  4. The first condition of the if a or b statement is fulfilled (smallest is None), and thus smallest is set to be the value of itercar, which is 3
  5. The break statement breaks the for loop without running the line print ("Loop:", itervar, smallest)
  6. “Smallest: 3” is printed.

If we remove the break line, the code actually can give the smallest value in the list. If we add 10 as the first number and change the list to [10, 3, 41, 12, 9, 74, 15], after the first iteration of the for loop, smallest is set to 10, “Loop: 10, 10” is printed. And in the second iteration of the for loop, itervar is changed into 3, and since itervar(3) < smallest(10), the if a or b statement is True, and smallest is set to itervar(3) and “Loop: 3, 3” is printed. In the third iteration of the for loop, itervar is changed into 41, and both smallest(3) is None and itervar(41) < smallest(3) are not True, so the if a or b statement is False, smallest remains to be 3 and “Loop: 41, 3” is printed. After the for loop iterated over the last number of the list, “Smallest: 3” is printed.

1 Like