// instead of
/ to make sure the value is rounded to an integer and not fractional. %function% expects an int as its first argument.
This example is sponsored by
tensorflow / models and you can follow along by loading it into your dashboard on deepcode.ai
I was fascinated by this as it shows a difference between Python 2.7 and 3. The code snippet below shows the interesting parts.
... def take_action(self, current_node_ids, action, step_number): ... goal_number = step_number / self.task_params.num_steps ... if n == self.episode.goal_node_ids[goal_number][i]: ...
self.task_params.num_steps are both integers. In Python 2.7, the division operator
/ works as a floor division. But dividing integers will always result in an integer.
Python 2.7.16 (default, Jul 13 2019, 16:01:51) [GCC 8.3.0] on linux > 3/4 0 > 9/10 0
This is no longer true with Python 3.
Python 3.7.4 (default, Jul 9 2019, 00:06:43) [GCC 6.3.0 20170516] on linux > 3/4 0.75 > 9/10 0.9 > 4/2 2.0
See the difference? In Python 3, the division behaves differently, so you need to be careful. A division between two integers results in a floating-point number, even if there is no remainder.
What DeepCode did under the hood was a type analysis and it inferred that
goal_number is a floating-point number. It traced
goal_number to its definition and found it to be a result of a division of two integers. But it is later used as the parameter for an index operator which needs to be an integer. If the program calls the index-operator with float, it results in
TypeError. DeepCode learned from scanning thousands of open source repos that typically this should have been a real floor division
// instead of a division
/. And it happens quite frequently when porting code from Python 2.7 to Python 3.
Python 3.7.4 (default, Jul 9 2019, 00:06:43) [GCC 6.3.0 20170516] on linux > table = [1,2,3,4,5,6,7,8,9,10] > a = 30 > b = 10 > table[a/b] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: list indices must be integers or slices, not float > table[a//b] 4
To "simulate" the Python 2.7 behavior, you can use the floor division operator
Python 3.7.4 (default, Jul 9 2019, 00:06:43) [GCC 6.3.0 20170516] on linux > 3//4 0 > 9//10 0
Not sure if this still is of interest but in Python 2.7
// works on integers just as expected so it is safe to use.