From: Sebastian H. <ha...@ms...> - 2006-08-03 04:31:44
|
Hi! I just finished maybe a total of 5 hours tracking down a nasty bug. So I thought I would share this: I'm keeping a version of (old) SciPy's 'plt' module around. (I know about matplotlib - anyway - ...) I changed the code some time ago from Numeric to numarray - no problem. Now I switched to numpy ... and suddenly the zooming does not work anymore: it always zooms to "full view". Finally I traced the problem down to a utility function: "is_number" - it is simply implemented as def is_number(val): return (type(val) in [type(0.0),type(0)]) As I said - now I finally saw that I always got False since the type of my number (0.025) is <type 'float64scalar'> and that's neither <type 'float'> nor <type 'int'> OK - how should this have been done right ? Anyway, I'm excited about the new numpy and am looking forward to it's progress Thanks, Sebastian Haase |
From: Robert K. <rob...@gm...> - 2006-08-03 04:43:43
|
Sebastian Haase wrote: > Hi! > I just finished maybe a total of 5 hours tracking down a nasty bug. > So I thought I would share this: > I'm keeping a version of (old) SciPy's 'plt' module around. > (I know about matplotlib - anyway - ...) > I changed the code some time ago from Numeric to numarray - no problem. > Now I switched to numpy ... and suddenly the zooming does not work > anymore: it always zooms to "full view". > > Finally I traced the problem down to a utility function: > "is_number" - it is simply implemented as > def is_number(val): > return (type(val) in [type(0.0),type(0)]) > > As I said - now I finally saw that I always got > False since the type of my number (0.025) is > <type 'float64scalar'> > and that's neither <type 'float'> nor <type 'int'> > > OK - how should this have been done right ? It depends on how is_number() is actually used. Probably the best thing to do would be to take a step back and reorganize whatever is calling it to not require specific types. Quick-and-dirty: use isinstance() instead since float64scalar inherits from float. However, float32scalar does not, so this is not a real solution, just a hack to get you on your merry way. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco |
From: Travis O. <oli...@ie...> - 2006-08-03 05:02:53
|
Sebastian Haase wrote: > Hi! > I just finished maybe a total of 5 hours tracking down a nasty bug. > > Finally I traced the problem down to a utility function: > "is_number" - it is simply implemented as > def is_number(val): > return (type(val) in [type(0.0),type(0)]) > > As I said - now I finally saw that I always got > False since the type of my number (0.025) is > <type 'float64scalar'> > and that's neither <type 'float'> nor <type 'int'> > > OK - how should this have been done right ? > > Code that depends on specific types like this is going to be hard to maintain in Python because many types could reasonably act like a number. I do see code like this pop up from time to time and it will bite you more with NumPy (which has a whole slew of scalar types). The scalar-types are in a hierarchy and so you could replace the code with def is_number(val): return isinstance(val, (int, float, numpy.number)) But, this will break with other "scalar-types" that it really should work with. It's best to look at what is calling is_number and think about what it wants to do with the object and just try it and catch the exception. -Travis |
From: Sebastian H. <ha...@ms...> - 2006-08-03 05:17:11
|
Travis Oliphant wrote: > Sebastian Haase wrote: >> Hi! >> I just finished maybe a total of 5 hours tracking down a nasty bug. >> >> Finally I traced the problem down to a utility function: >> "is_number" - it is simply implemented as >> def is_number(val): >> return (type(val) in [type(0.0),type(0)]) >> >> As I said - now I finally saw that I always got >> False since the type of my number (0.025) is >> <type 'float64scalar'> >> and that's neither <type 'float'> nor <type 'int'> >> >> OK - how should this have been done right ? >> >> > > Code that depends on specific types like this is going to be hard to > maintain in Python because many types could reasonably act like a > number. I do see code like this pop up from time to time and it will > bite you more with NumPy (which has a whole slew of scalar types). > > The scalar-types are in a hierarchy and so you could replace the code with > > def is_number(val): > return isinstance(val, (int, float, numpy.number)) > > But, this will break with other "scalar-types" that it really should > work with. It's best to look at what is calling is_number and think > about what it wants to do with the object and just try it and catch the > exception. > > -Travis > Thanks, I just found numpy.isscalar() and numpy.issctype() ? These sound like they would do what I need - what is the difference between the two ? (I found that issctype worked OK while isscalar gave some exception in some cases !? ) - Sebastian |
From: Travis O. <oli...@ie...> - 2006-08-03 05:43:52
|
Sebastian Haase wrote: > Thanks, > I just found > numpy.isscalar() and numpy.issctype() ? > These sound like they would do what I need - what is the difference > between the two ? > Oh, yeah. numpy.issctype works with type objects numpy.isscalar works with instances Neither of them distinguish between scalars and "numbers." If you get errors with isscalar it would be nice to know what they are. -Travis |
From: Sebastian H. <ha...@ms...> - 2006-08-03 16:32:34
|
On Wednesday 02 August 2006 22:43, Travis Oliphant wrote: > Sebastian Haase wrote: > > Thanks, > > I just found > > numpy.isscalar() and numpy.issctype() ? > > These sound like they would do what I need - what is the difference > > between the two ? > > Oh, yeah. > > numpy.issctype works with type objects > numpy.isscalar works with instances > > Neither of them distinguish between scalars and "numbers." > > If you get errors with isscalar it would be nice to know what they are. I'm still trying to reproduce the exception, but here is a first comparison that - honestly - does not make much sense to me: (type vs. instance seems to get mostly the same results and why is there a difference with a string ('12') ) >>> N.isscalar(12) True >>> N.issctype(12) True >>> N.isscalar('12') True >>> N.issctype('12') False >>> N.isscalar(N.array([1])) False >>> N.issctype(N.array([1])) True >>> N.isscalar(N.array([1]).dtype) False >>> N.issctype(N.array([1]).dtype) False # apparently new 'scalars' have a dtype attribute ! >>> N.isscalar(N.array([1])[0].dtype) False >>> N.issctype(N.array([1])[0].dtype) False >>> N.isscalar(N.array([1])[0]) True >>> N.issctype(N.array([1])[0]) True -Sebastian |
From: Christopher B. <Chr...@no...> - 2006-08-03 17:34:06
|
Sebastian Haase wrote: > Finally I traced the problem down to a utility function: > "is_number" - it is simply implemented as > def is_number(val): > return (type(val) in [type(0.0),type(0)]) > OK - how should this have been done right ? Well, as others have said, python is uses "duck typing", so you really shouldn't be checking for specific types anyway -- if whatever is passed in acts like it should, that's all you need not know. However, sometimes it does make sense to catch the error sooner, rather than later, so that it can be obvious, or handled properly, or give a better error message, or whatever. In this case, I still use a "duck typing" approach: I don't need to know exactly what type it is, I just need to know that I can use it in the way I want, and an easy way to do that is to turn it into a known type: def is_number(val): try: float(val) return True except ValueError: return False Though more often, I'd just call float on it, and pass that along, rather than explicitly checking This works at least with numpy float64scalar and float32scalar, and it should work with all numpy scalar types, except perhaps the long types that don't fit into a Python float. it'll also turn string into floats if it can, which may or may not be what you want. -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chr...@no... |
From: Sebastian H. <ha...@ms...> - 2006-08-03 20:42:31
|
On Thursday 03 August 2006 13:19, Travis Oliphant wrote: > Sebastian Haase wrote: > >On Wednesday 02 August 2006 22:43, Travis Oliphant wrote: > >>Sebastian Haase wrote: > >>>Thanks, > >>>I just found > >>>numpy.isscalar() and numpy.issctype() ? > >>>These sound like they would do what I need - what is the difference > >>>between the two ? > >> > >>Oh, yeah. > >> > >>numpy.issctype works with type objects > >>numpy.isscalar works with instances > >> > >>Neither of them distinguish between scalars and "numbers." > >> > >>If you get errors with isscalar it would be nice to know what they are. > > > >I'm still trying to reproduce the exception, but here is a first > > comparison that - honestly - does not make much sense to me: > >(type vs. instance seems to get mostly the same results and why is there > > a difference with a string ('12') ) > > These routines are a little buggy. I've cleaned them up in SVN to > reflect what they should do. When the dtype object came into > existence a lot of what the scalar types where being used for was no > longer needed. Some of these functions weren't updated to deal with > the dtype objects correctly either. > > This is what you get now: > >>> import numpy as N > >>> N.isscalar(12) > > True > > >>> N.issctype(12) > > False > > >>> N.isscalar('12') > > True > > >>> N.issctype('12') > > False > > >>> N.isscalar(N.array([1])) > > False > > >>> N.issctype(N.array([1])) > > False > > >>> N.isscalar(N.array([1]).dtype) > > False > > >>> N.issctype(N.array([1]).dtype) > > True > > >>> N.isscalar(N.array([1])[0].dtype) > > False > > >>> N.issctype(N.array([1])[0].dtype) > > True > > >>> N.isscalar(N.array([1])[0]) > > True > > >>> N.issctype(N.array([1])[0]) > > False > > > -Travis Great! Just wanted to point out that '12' is a scalar - I suppose that's what it is. (To determine if something is a number it seems best to implement a try: ... except: ... something like float(x) - as Chris has suggested ) -S. |