Skip to content
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

format.write([0, 1, None]) with format='(3I10)' runs into TypeError #21

Closed
hyperkang opened this issue Feb 10, 2022 · 10 comments
Closed
Labels
bug Something isn't working

Comments

@hyperkang
Copy link
Contributor

hyperkang commented Feb 10, 2022

>>> from fortranformat import FortranRecordWriter
>>> format = FortranRecordWriter('(3I10)')
>>> output = format.write([0, 1, None])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "D:\simright-dev\py-fortranformat\fortranformat\FortranRecordWriter.py", line 42, in write
    return _output(self._eds, self._rev_eds, values)
  File "D:\simright-dev\py-fortranformat\fortranformat\_output.py", line 93, in output
    sub_string = _compose_i_string(
  File "D:\simright-dev\py-fortranformat\fortranformat\_output.py", line 641, in _compose_i_string
    val = int(val)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
@hyperkang hyperkang changed the title format.write([0.0, 1.0, None]) with format='(3I10)' runs into TypeError format.write([0, 1, None]) with format='(3I10)' runs into TypeError Feb 10, 2022
@brendanarnold
Copy link
Owner

Hi, could you post what you expect the behaviour to be?

@hyperkang
Copy link
Contributor Author

Hi, could you post what you expect the behaviour to be?

I expect it behaves like the example in wiki guide:

>>> from fortranformat import FortranRecordWriter
>>> format = FortranRecordWriter('(3I10)')
>>> output = format.write([0.0, 1.0, None])
>>> output
'         0         1'

Or it might be easier to write None value into spaces with specified width, that is:

FortranRecordWriter('(3I10)').write([0, 1, None]) => '         0         1          '
FortranRecordWriter('(3I10)').write([0, None, 1]) => '         0                   1'

@hyperkang
Copy link
Contributor Author

BTW, I would expect real numbers behave the similar way, that is:

>>> FortranRecordWriter('(3E10.2)').write([1.0, 2.0, None])
'  0.10E+01  0.20E+01          '
>>> FortranRecordWriter('(3E10.2)').write([1.0, None, 2.0])
'  0.10E+01            0.20E+01'

However, currently the code behaves as follows:

FortranRecordWriter('(3E10.2)').write([1.0, 2.0, None])

>>> FortranRecordWriter('(3E10.2)').write([1.0, 2.0, None])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/FortranRecordWriter.py", line 42, in write
    return _output(self._eds, self._rev_eds, values)
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/_output.py", line 116, in output
    sub_string = _compose_float_string(w, e, d, state, val, 'E')
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/_output.py", line 253, in _compose_float_string
    sign_bit = val < 0
TypeError: '<' not supported between instances of 'NoneType' and 'int'

FortranRecordWriter('(3E10.2)').write([1.0, None, 2.0])

>>> FortranRecordWriter('(3E10.2)').write([1.0, None, 2.0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/FortranRecordWriter.py", line 42, in write
    return _output(self._eds, self._rev_eds, values)
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/_output.py", line 116, in output
    sub_string = _compose_float_string(w, e, d, state, val, 'E')
  File "/home/simright/.pyenv/versions/pypi_fortranformat/lib/python3.7/site-packages/fortranformat/_output.py", line 253, in _compose_float_string
    sign_bit = val < 0
TypeError: '<' not supported between instances of 'NoneType' and 'int'

@brendanarnold brendanarnold added the bug Something isn't working label Feb 10, 2022
@hyperkang
Copy link
Contributor Author

I have tried some local fixes. Will submit a PR later.

@hyperkang
Copy link
Contributor Author

@brendanarnold I have submitted two PRs for writting int and float strings (with None value) respectively.

It would be good to add tests to cover the expected behaviors. But I need more time to understand how to add test.

@brendanarnold
Copy link
Owner

brendanarnold commented Feb 11, 2022

By convention, None represents a FORTRAN variable that hasn't been initialised. IIRC FORTRAN has default values for variables e.g. 0 for integers. It might be better instead to see what uninitialised variables print out and do that instead.

Running the following in GFortran ...

      PROGRAM FEDOUT

      REAL :: myreal
      LOGICAL :: mybool
      INTEGER :: myint

      WRITE(*, '(A, F10.1, A)') '[', myreal, ']'
      WRITE(*, '(A, L10, A)') '[', mybool, ']'
      WRITE(*, '(A, I10, A)') '[', myint, ']'

      STOP
      END

Gives the following output

[       0.0]
[         T]
[         0]

... so it looks like numerical values are initialised to '0' and logical to .TRUE.. I'll write some tests to cover this and update the code.

@hyperkang
Copy link
Contributor Author

OK. So it looks we need to handle tailing None values in the list during "writing".

@brendanarnold
Copy link
Owner

brendanarnold commented Feb 11, 2022

Yep, here is a commit with tests showing how None values are handled de6d886

@hyperkang
Copy link
Contributor Author

Yep, here is a commit with tests showing how None values are handled de6d886

Great. Please feel free to close my PRs.

@brendanarnold
Copy link
Owner

Now released as v1.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants