Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #95720

Re: Casting to a "number" (both int and float)?

From Jussi Piitulainen <harvesting@makes.address.invalid>
Newsgroups comp.lang.python
Subject Re: Casting to a "number" (both int and float)?
Date 2015-08-28 08:46 +0300
Organization A noiseless patient Spider
Message-ID <lf56140klss.fsf@ling.helsinki.fi> (permalink)
References <0bdda01a-de29-4742-9851-0617dad602ae@googlegroups.com>

Show all headers | View raw


Victor Hooi writes:

> I'm reading JSON output from an input file, and extracting values.
>
> Many of the fields are meant to be numerical, however, some fields are
> wrapped in a "floatApprox" dict, which messed with my parsing.
>
> For example:
>
> {
>     "hostname": "example.com",
>     "version": "3.0.5",
>     "pid": {
>         "floatApprox": 18403
>     }
>     "network": {
>         "bytesIn": 123123,
>         "bytesOut": {
>             "floatApprox": 213123123
>         }
> }
>
> The floatApprox wrapping appears to happen sporadically in the input.
>
> I'd like to find a way to deal with this robustly.

So you want a value as is when it is a number - either an int or a
float. And otherwise the value is a dict and you want the value at a
known key. Here's a literal-minded expression of the spec:

   ( o if isinstance(o, (int, float)) else o['floatApprox'] )

> For example, I have the following function:
>
> def strip_floatApprox_wrapping(field):
>     # Extracts a integer value from a field. Workaround for the
>     # float_approx wrapping.
>     try:
>         return int(field)
>     except TypeError:
>         return int(field['floatApprox'])
>
> which I can then call on each field I want to extract.
>
> However, this relies on casting to int, which will only work for ints
> - for some fields, they may actually be floats, and I'd like to
> preserve that if possible.

You could try int first, float second; you should still return the
actual value.

   try:
     int(field)
     return field
   except TypeError: pass
   try:
     float(field)
     return field:
   except TypeError:
     return field['floatApprox']

There are a couple of reasons to return the actual value instead of the
result of the "cast". First, it appears to be what you want :) Second,
it allows you to have some confidence that the data actually is numeric
and not, say, strings that happen to look like numbers.

> (I know there's a isnumber() field - but you can only call that on a
> string - so if I do hit a floatApprox field, it will trigger a
> AttributeError exception, which seems a bit clunky to handle).
>
> def strip_floatApprox_wrapping(field):
>     # Extracts a integer value from a field. Workaround for the
>     # float_approx wrapping.
>     try:
>         if field.isnumeric():
>             return field
>     except AttributeError:
>         return field['floatApprox']

I take it you haven't tried this and the fields in question actually are
numeric, not strings. That exception would be taken for a wrong reason.

You could do the following, but str.isnumeric does not do what you want.
For example, "3.14".isnumeric() is as False as "{}".isnumeric().

    if str(field).isnumeric():
        return field
    else:
        return field['floatApprox']

> Is there a way to re-write strip_floatApprox_wrapping to handle both
> ints/floats, and preserve the original format?
>
> Or is there a more elegant way to deal with the arbitrary nesting with
> floatApprox?

Consider ... if isinstance(field, (int, float)) else ... .

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Casting to a "number" (both int and float)? Victor Hooi <victorhooi@gmail.com> - 2015-08-27 21:57 -0700
  Re: Casting to a "number" (both int and float)? Victor Hooi <victorhooi@gmail.com> - 2015-08-27 22:04 -0700
    Re: Casting to a "number" (both int and float)? "Sven R. Kunze" <srkunze@mail.de> - 2015-08-28 18:09 +0200
      Re: Casting to a "number" (both int and float)? Robin Koch <robin.koch@t-online.de> - 2015-08-28 18:15 +0200
        Re: Casting to a "number" (both int and float)? "Sven R. Kunze" <srkunze@mail.de> - 2015-08-30 13:38 +0200
        Re: Casting to a "number" (both int and float)? Steven D'Aprano <steve@pearwood.info> - 2015-08-30 22:00 +1000
        Re: Casting to a "number" (both int and float)? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-08-30 13:55 +0100
  Re: Casting to a "number" (both int and float)? Ben Finney <ben+python@benfinney.id.au> - 2015-08-28 15:44 +1000
    Re: Casting to a "number" (both int and float)? Jussi Piitulainen <harvestingn@makes.address.invalid> - 2015-08-28 09:03 +0300
    Re: Casting to a "number" (both int and float)? Jussi Piitulainen <harvesting@makes.address.invalid> - 2015-08-28 09:15 +0300
      Re: Casting to a "number" (both int and float)? Victor Hooi <victorhooi@gmail.com> - 2015-08-28 00:56 -0700
        Re: Casting to a "number" (both int and float)? Chris Angelico <rosuav@gmail.com> - 2015-08-28 19:23 +1000
  Re: Casting to a "number" (both int and float)? Jussi Piitulainen <harvesting@makes.address.invalid> - 2015-08-28 08:46 +0300
  Re: Casting to a "number" (both int and float)? random832@fastmail.us - 2015-08-28 01:54 -0400
  Re: Casting to a "number" (both int and float)? Laura Creighton <lac@openend.se> - 2015-08-28 07:59 +0200

csiph-web