years later DeprecationWarning

D

Dan Jacobson

Here's the deal: I have to maintain this long gone guy's programs and
lately they've been saying
../north_pass.py:14: DeprecationWarning: integer argument expected, got float
fl=range(1000*(math.floor(25000*f2m/1000)),46000*f2m,1000)

As I don't know python, I tried sticking an int( ) in various places
in that line but couldn't get whatever is bothering python to shut up. Help.

(That long-gone guy is actually me, according to the notes in the program.
However those brain cells are long gone now, so it might as well not be me.)
 
T

Terry Reedy

Dan Jacobson said:
Here's the deal: I have to maintain this long gone guy's programs and
lately they've been saying
./north_pass.py:14: DeprecationWarning: integer argument expected, got
float
fl=range(1000*(math.floor(25000*f2m/1000)),46000*f2m,1000)

The warning is from the range function. If f2m is float, so too the first
2 args. Either convert f2m to int first or both args to int. The second
is what happens now. A long too large to convert to int also raises an
error.

Terry Jan Reedy
 
C

Chris Lasher

Two things:
1) math.floor returns a float, not an int. Doing an int() conversion on
a float already floors the value, anyways. Try replacing
math.floor(...) with int(...)
e.g.5

2) What kind of data is in f2m? If f2m is a float, you will get float
values in the expressions that f2m is a multiplicand.
 
B

Ben Finney

Dan Jacobson said:
Here's the deal: I have to maintain this long gone guy's programs and
lately they've been saying
./north_pass.py:14: DeprecationWarning: integer argument expected, got float
fl=range(1000*(math.floor(25000*f2m/1000)),46000*f2m,1000)

You haven't shown us the value of all the terms there; specifically,
we don't know what value has been bound to 'f2m'.

Ideally, this code would have been written to be more easily readable
and explicit. This is an illustration that it's never too late to do
so, and that it can help you understand what the heck is going wrong.

Replace those literals with named constants, that indicate what the
heck they are.

import math
f2m = 1.0 # assuming this is where the float value gets introduced
some_increment_thing = 1000
some_starting_count = 25
some_ending_count = 46
some_starting_scale = some_starting_count * some_increment_thing
some_ending_scale = some_ending_count * some_increment_thing
fl = range(some_increment_thing*(math.floor(some_starting_scale*f2m/some_increment_thing)), some_ending_scale*f2m, some_increment_thing)

Use names that make sense in the problem domain, of course. The idea
is to not keep the reader (that's you, months or years from now)
guessing why '1000' is used three times, or whether it's mere
coincidence that all the other values seem to be multiples of 1000, or
whether each of those 1000s is meant to be the same thing, or whether
one of them can change, etc.

Split out this mess into separate operations, so you can see what's
failing.

range_start = some_increment_thing * math.floor(some_starting_scale*f2m/some_increment_thing)
range_limit = some_ending_scale * f2m
fl = range(range_start, range_limit, some_increment_thing)

That will get you closer to the point of knowing what's causing the
error. It will also (if you've chosen meaningful names) make the code
much more understandable; and perhaps even give you ways to re-think
the algorithm used.
(That long-gone guy is actually me, according to the notes in the
program. However those brain cells are long gone now, so it might
as well not be me.)

One should always write code for some unknown future person, months or
years after the original context of the problem is forgotten, to
understand, without the benefit of your explanation. As you've found,
that person is most frequently oneself.
 
E

Enigma Curry

(That long-gone guy is actually me, according to the notes in the program.
However those brain cells are long gone now, so it might as well not be me.)

I had a great long laugh with this bit. I guess it's because I can
relate so well :)
 
S

Steven D'Aprano

Two things:
1) math.floor returns a float, not an int. Doing an int() conversion on
a float already floors the value, anyways.

No it doesn't, or rather, int() is only equivalent to floor() if you limit
the input to non-negative numbers:

int(-2.2) => -2, but floor(-2.2) should give -3.

The standard definition of floor() and ceil() are:

floor(x) = maximum integer n such that n <= x
ceil(x) = minimum integer n such that n >= x

or as Python functions:

def floor(x):
"Returns the maximum integer less than or equal to x"
if x >= 0:
return int(x)
else:
if x % 1: return int(x)-1
else: return int(x)

def ceil(x):
"Returns the minimum integer greater than or equal to x"
return -floor(-x)

or even simpler:

from math import floor, ceil

(Caution: the functions defined in the math module return the floor and
ceiling as floats, not int, so you may want to wrap them in a call to int.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top