## DEV Community

cu_0xff 🇪🇺 for DeepCode.AI

Posted on • Originally published at Medium

# DeepCode’s Top Findings#7: Python Use Real Floor Division

Language: Python
Defect: DivisionRounding
Diagnose: Use `//` 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):
...
...
if n == self.episode.goal_node_ids[goal_number][i]:
...

``````

`step_number` and `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.