ValueError: could not convert string to float: 'True'
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
- ---
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']])
Duplicate of #209 ?
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'.
All these bugs happen in _format(): https://github.com/astanin/python-tabulate/blob/83fd4fb98926c8a6fdf45caa1b91ee8913b64dcb/tabulate/init.py#L1213-L1247 ...when
- a bool represented as a string is subjected to explicit conversion into a float (L1244),
- 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