-1

PFB the program. In that we have a condition block if curr > max_v or max_v == None:. This is giving an error

TypeError: '>' not supported between instances of 'int' and 'NoneType'

However, if I change the condition to max_v == None or curr > max_v: it works fine. What is the issue here. Please advice.

arr_ele = []

for arr_i in range(6):
    arr_t = [int(arr_temp) for arr_temp in input().strip().split()]
    arr_ele.append(arr_t)

length = len(arr_ele[0])


max_v = None
curr = 0
for i in range(length-2):
    for j in range(length-2):
        curr = arr_ele[i][j] + arr_ele[i][j+1] + arr_ele[i][j+2] + \
               arr_ele[i+1][j+1] + \
               arr_ele[i+2][j] + arr_ele[i+2][j+1] + arr_ele[i+2][j+2]


        if  curr > max_v or max_v == None:
            max_v = curr

print(max_v)
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 4
    Write in the opposite order to take advantage of short-circuiting: `if max_v is None or curr > max_v:`. – kaya3 Jan 29 '20 at 14:36
  • The issue is simply that you can't compare an integer to `None`. Unless you know what the minimum value of your list could be, `None` is a perfectly good way to initialize `max_v`; you just have to check for it properly by using `max_v is None`. – chepner Jan 29 '20 at 14:37
  • 2
    Does this answer your question? [Does Python evaluate if's conditions lazily?](https://stackoverflow.com/questions/13960657/does-python-evaluate-ifs-conditions-lazily) – Er... Jan 29 '20 at 14:37
  • An `or` statement is evaluated left to right, once one of the condition is evaluated `True`, the interpreter stops checking the rest. – r.ook Jan 29 '20 at 14:37
  • @DeepSpace That is not logically equivalent. `max_v` should always be updated when `max_v` is currently `None`, but your condition is false in that case. – kaya3 Jan 29 '20 at 14:38
  • 1
    Regarding the behaviour of `or`: *"The expression `x or y` first evaluates `x`; if `x` is true, its value is returned; otherwise, `y` is evaluated and the resulting value is returned."* Note that the second part is only evaluated if the first part is false. https://docs.python.org/3/reference/expressions.html#boolean-operations – kaya3 Jan 29 '20 at 14:39
  • 1
    @kaya3 Also worth noting that the `and` operator does exactly the opposite. Once a condition is returned `False`, the rest of the expression is not evaluated. – r.ook Jan 29 '20 at 14:40

2 Answers2

0

Python's interpreter is checking if max_v is None, if that is True then then statement becomes true and the block is executed running max_v = curr. if you switch places between statements, the curr > max_v is checked.

If the variable max_v is NoneType when the interpreter reaches the if condition then it throws an error because you can't check if an integer is bigger than None.

By putting curr > max_v first, that is the statement that is evaluated first, if you put max_v == None as the first statement then that is what is evaluated first.

Try to change the for loop to give a value to max_v or give it a value before the for loop.

Filip
  • 898
  • 1
  • 8
  • 24
0

When Python is processing a logical expression such, it evaluates the expression from left-to-right.
In curr > max_v or max_v == None, when the interpreter process curr > max_v, if the variable max_v has not changed its value (None) since its definition, it would try to compare an int and a NoneType, and this operation is not defined/allowed.
In the statement max_v == None or curr > max_v, if max_v is not an integer, the interpreter will never evaluate curr > max_v.
A solution would be to use something like:

import math
max_v = math.nan # Not a number
...
curr > max_v or max_v == math.nan:
...

btw, max_v == None is considered an anti-pattern.

Jose Raul Barreras
  • 849
  • 1
  • 13
  • 19