python-tabulate icon indicating copy to clipboard operation
python-tabulate copied to clipboard

ValueError: could not convert string to float: 'True'

Open wjfwzzc opened this issue 4 years ago • 4 comments

version: 0.8.9, Python 3.6.9, reproduction code:

In [1]: from tabulate import tabulate
   ...: data = dict(a=0.1, b=True, c="c")
   ...: table = [(str(k), str(v)) for k, v in data.items()]

In [2]: print(tabulate(table))
-  ----
a  0.1
b  True
c  c
-  ----

In [3]: print(tabulate(table[:2]))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-16d27c33d4d2> in <module>
----> 1 print(tabulate(table[:2]))

/usr/local/lib/python3.6/dist-packages/tabulate.py in tabulate(tabular_data, headers, tablefmt, floatfmt, numalign, stralign, missingval, showindex, disable_numparse, colalign)
   1299             missing_vals.extend( (len(cols)-len(missing_vals)) * [_DEFAULT_MISSINGVAL] )
   1300     cols = [[_format(v, ct, fl_fmt, miss_v, has_invisible) for v in c]
-> 1301              for c, ct, fl_fmt, miss_v in zip(cols, coltypes, float_formats, missing_vals)]
   1302 
   1303     # align columns

/usr/local/lib/python3.6/dist-packages/tabulate.py in <listcomp>(.0)
   1299             missing_vals.extend( (len(cols)-len(missing_vals)) * [_DEFAULT_MISSINGVAL] )
   1300     cols = [[_format(v, ct, fl_fmt, miss_v, has_invisible) for v in c]
-> 1301              for c, ct, fl_fmt, miss_v in zip(cols, coltypes, float_formats, missing_vals)]
   1302 
   1303     # align columns

/usr/local/lib/python3.6/dist-packages/tabulate.py in <listcomp>(.0)
   1298         if len(missing_vals) < len(cols):
   1299             missing_vals.extend( (len(cols)-len(missing_vals)) * [_DEFAULT_MISSINGVAL] )
-> 1300     cols = [[_format(v, ct, fl_fmt, miss_v, has_invisible) for v in c]
   1301              for c, ct, fl_fmt, miss_v in zip(cols, coltypes, float_formats, missing_vals)]
   1302 

/usr/local/lib/python3.6/dist-packages/tabulate.py in _format(val, valtype, floatfmt, missingval, has_invisible)
    766             return val.replace(raw_val, formatted_val)
    767         else:
--> 768             return format(float(val), floatfmt)
    769     else:
    770         return "{0}".format(val)

ValueError: could not convert string to float: 'True'

If I replace str(v) by v:

In [1]: from tabulate import tabulate
   ...: data = dict(a=0.1, b=True, c="c")
   ...: table = [(str(k), v) for k, v in data.items()]

In [2]: print(tabulate(table))
-  ----
a  0.1
b  True
c  c
-  ----

In [3]: print(tabulate(table[:2]))
-  ---
a  0.1
b  1
-  ---

wjfwzzc avatar Jul 30 '21 04:07 wjfwzzc

The basic assumption of tabulate is that values in the same column are of the same type. Though I agree that the exception should not be thrown. The minimal example to reproduce this error is this one:

tabulate([[0.1], ['True']])

astanin avatar Oct 19 '22 12:10 astanin

Duplicate of #209 ?

astanin avatar Oct 19 '22 15:10 astanin

While looking into this issue I found a similar bug:

>>> tabulate([[1000], ['True']], intfmt=',')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2176, in tabulate
    cols = [
           ^
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2177, in <listcomp>
    [_format(v, ct, fl_fmt, int_fmt, miss_v, has_invisible) for v in c]
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2177, in <listcomp>
    [_format(v, ct, fl_fmt, int_fmt, miss_v, has_invisible) for v in c]
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 1231, in _format
    return format(val, intfmt)
           ^^^^^^^^^^^^^^^^^^^
ValueError: Cannot specify ',' with 's'.

And another one:

>>> tabulate([["1000"]], intfmt=',')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2176, in tabulate
    cols = [
           ^
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2177, in <listcomp>
    [_format(v, ct, fl_fmt, int_fmt, miss_v, has_invisible) for v in c]
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 2177, in <listcomp>
    [_format(v, ct, fl_fmt, int_fmt, miss_v, has_invisible) for v in c]
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ibo\Python\python-tabulate\tabulate\__init__.py", line 1231, in _format
    return format(val, intfmt)
           ^^^^^^^^^^^^^^^^^^^
ValueError: Cannot specify ',' with 's'.

ilya112358 avatar Dec 31 '22 12:12 ilya112358

All these bugs happen in _format(): https://github.com/astanin/python-tabulate/blob/83fd4fb98926c8a6fdf45caa1b91ee8913b64dcb/tabulate/init.py#L1213-L1247 ...when

  1. a bool represented as a string is subjected to explicit conversion into a float (L1244),
  2. a bool (or an integer) represented as a string is subjected to some integer formatting (L1231).

I'll have a go at fixing those.

Interestingly, this is one of the core functions of the library. It existed as early as in the first commit a83993e2be0ac5a3937842517490c194c17c0a40 of this repo, made more than 10 years ago, although it was much cuter at the time: https://github.com/astanin/python-tabulate/blob/a83993e2be0ac5a3937842517490c194c17c0a40/tabulate.py#L26-L32

ilya112358 avatar Dec 31 '22 16:12 ilya112358