-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug fix for issue #318 | intfmt
: error for strings which contain integer values
#319
Bug fix for issue #318 | intfmt
: error for strings which contain integer values
#319
Conversation
@@ -1229,6 +1229,8 @@ def _format(val, valtype, floatfmt, intfmt, missingval="", has_invisible=True): | |||
if valtype is str: | |||
return f"{val}" | |||
elif valtype is int: | |||
if isinstance(val, str): | |||
intfmt = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe convert val
to int
instead, similarly to what happens when valtype
is float
? That way, an int
in a string would still get formatted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as requested.
Thank you for identifying the issue and proposing a bug fix! I was wondering that maybe we should rather convert Also, I see you added a nice test for colored |
In fact, it was one of my first solutions, but this breaks some unit tests. I made several changes before arriving at the proposed solution, but the most important thing is that after all these experiments, I discovered that Unit testHere are the results of the unit tests with this change: elif valtype is int:
# if isinstance(val, str):
# intfmt = ""
return format(int(val), intfmt) Unit tests results:
ConclusionsDescriptionIf we made this change, the strings which contain integers will be formatted. It is not bad, but I was thinking that if I want some number as a string is because maybe I would rather not format as an integer. It will be a hard decision for the owners and maintainers of this Python package. In the test We need to explore the way to solve the colored numbers. I'll research in the code if there is something that I can reuse or create a new functionality to detect the colored number and format the integer. Taking advantage of this talk, I would like to recommend that each data value be treated independently, since apparently if it encounters at least one floating number, it takes all numbers as floats, even if they are not. @pytest.mark.skip(reason="It detects all values as floats but there are strings and integers.")
def test_intfmt_with_string_with_floats():
"Output: integer format"
result = tabulate([[82000.38], ["1500.47"], ["2463"], [92165]], intfmt=",", tablefmt="plain")
expected = "82000.4\n 1500.47\n 2,463\n92,165"
assert_equal(expected, result) For this, data
Furthermore, I noticed that the float test_intfmt_with_string_as_integertabulate([[82642], ["1500"], [2463]], intfmt=",", tablefmt="plain") Expected: Got: test_intfmt_with_colorstabulate(colortable, colorheaders, "grid", intfmt=",") ValueError: invalid literal for int() with base 10: -- test_alignment_of_colored_cellscolortable = [
("test", 42, "\x1b[31m42\x1b[0m"),
("test", 101, "\x1b[32m101\x1b[0m"),
]
colorheaders = ("test", "\x1b[34mtest\x1b[0m", "test")
formatted = tabulate(colortable, colorheaders, "grid") ValueError: invalid literal for int() with base 10: test_ansi_color_bold_and_fgcolorValueError: invalid literal for int() with base 10: Final noteI look forward to your reply or guide to start working on solutions. Otherwise, I could make code, but I really don't know if it aligns with where you want to go. |
It would be the solution for the colored numbers, at least at Regular Expression level. Regular expression: For this example
Match for these examples:
|
In the above commit: e45cac1; I added the validation and formatting when the number is colored. |
Here other option to format the strings which contain integers. For example, in this data The only change that needs to be performed is adding some elif val.isdigit():
val = format(int(val), intfmt) In this code: if valtype is str:
return f"{val}"
elif valtype is int:
if isinstance(val, str):
val_striped = val.encode('unicode_escape').decode('utf-8')
colored = re.search(r'(\\[xX]+[0-9a-fA-F]+\[\d+[mM]+)([0-9.]+)(\\.*)$', val_striped)
if colored:
total_groups = len(colored.groups())
if total_groups == 3:
digits = colored.group(2)
if digits.isdigit():
val_new = colored.group(1) + format(int(digits), intfmt) + colored.group(3)
val = val_new.encode('utf-8').decode('unicode_escape')
elif val.isdigit():
val = format(int(val), intfmt)
intfmt = ""
return format(val, intfmt) This is the result of the test result = tabulate([[82642], ["1500"], [2463]], intfmt=",", tablefmt="plain")
expected = "82,642\n 1500\n 2,463"
Note:If you think this change is important and relevant to your package, please let me know, so I can add this change to the pull requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the suggested changes.
@@ -1229,6 +1229,8 @@ def _format(val, valtype, floatfmt, intfmt, missingval="", has_invisible=True): | |||
if valtype is str: | |||
return f"{val}" | |||
elif valtype is int: | |||
if isinstance(val, str): | |||
intfmt = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as requested.
Bug fix for issue #318 |
intfmt
: error for strings which contain integer valuesDescription.
Resolved the problem with the
intfmt
argument.Added tests for these changes.
Test results:
308 passed, 2 skipped in 1.10s
.