### Test installed package with a simple command Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Verify that the project has been installed correctly in the virtual environment by running a simple Python command that uses the library's functionality. ```python python -c "from fortranformat import FortranRecordReader as FReader; assert FReader('(2f10.5)').read('1.0000000 2.0000000') == [1.0, 2.0]" ``` -------------------------------- ### Install local build into a virtual environment Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Install the locally built project distribution into the activated virtual environment using pip. This allows testing the installed package. ```bash pip install $(find ./dist -name "*.whl") ``` -------------------------------- ### Install Poetry using the official installer Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Use this command to install Poetry, a dependency management tool for Python. Ensure you have Python 3 available. ```bash curl -sSL https://install.python-poetry.org | python3 - ``` -------------------------------- ### Install project dependencies with Poetry Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md After navigating to your project directory, run this command to install all project dependencies managed by Poetry. ```bash poetry install ``` -------------------------------- ### INDEX Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html The INDEX procedure returns the starting position of a substring within a string. It supports optional backward searching. ```APIDOC ## INDEX Procedure ### Description Returns an integer that is the starting position of a substring within a string. ### Arguments - `string` (VARYING_STRING or CHARACTER) - The string to search within. - `substring` (VARYING_STRING or CHARACTER) - The substring to search for. - `back` (LOGICAL, OPTIONAL) - If true, searches backward from the end of the string. ### Result Attributes - Scalar of type default INTEGER. ### Result Value - If `back` is absent or false: Minimum positive integer `I` such that `EXTRACT(string, I, I + LEN(substring) - 1) == substring`, or 0 if no such value exists. Returns 0 if `LEN(string) < LEN(substring)`, and 1 if `LEN(substring) == 0`. - If `back` is true: Maximum integer `I` less than or equal to `LEN(string) - LEN(substring) + 1` such that `EXTRACT(string, I, I + LEN(substring) - 1) == substring`, or 0 if no such value exists. Returns 0 if `LEN(string) < LEN(substring)`, and `LEN(string) + 1` if `LEN(substring) == 0`. ``` -------------------------------- ### Create and activate a virtual environment Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Set up a new virtual environment for testing the project build. This isolates dependencies for the test environment. ```bash python -m venv test_env source ./test_env/bin/activate ``` -------------------------------- ### Run all tests with make Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Execute the full test suite for the project using the make command. Note that some floating-point edit descriptors may fail due to representation limitations. ```bash make runtests ``` -------------------------------- ### Reset configuration to defaults Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Demonstrates resetting all configuration options to their default values using `config.reset()`. Shows default values for RECORD_SEPARATOR, PROC_MAXINT, and RET_WRITTEN_VARS_ONLY. ```python import fortranformat.config as config config.reset() print(config.RECORD_SEPARATOR) # '\n' print(config.PROC_MAXINT) # 2147483648 print(config.RET_WRITTEN_VARS_ONLY) # False ``` -------------------------------- ### GET Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Reads characters from an external file into a string. Supports various forms for specifying input unit, string, maximum length, and termination set. ```APIDOC ## GET Procedure ### Description Reads characters from an external file into a string. ### Forms - CALL GET(string,maxlen,iostat) - CALL GET(unit,string,maxlen,iostat) - CALL GET(string,set,separator,maxlen,iostat) - CALL GET(unit,string,set,separator,maxlen,iostat) ### Arguments - **string** (VARYING_STRING) - The string to read characters into. - **maxlen** (INTEGER, OPTIONAL) - The maximum number of characters to read. If less than or equal to zero, no characters are read and string is set to zero length. If absent, a maximum of HUGE(1) is used. - **unit** (INTEGER) - The input unit to be used. Must be connected to a formatted file for sequential read access. If omitted, the default input unit is used. - **set** (VARYING_STRING or CHARACTER) - A set of characters, the occurrence of any of which will terminate the input. This terminal character is read but not included in the result string. - **separator** (VARYING_STRING, OPTIONAL) - If present, the actual character found which terminates the transfer is returned here. If the transfer is terminated by a character in 'set', that character is returned. If terminated otherwise, a zero-length string is returned. - **iostat** (INTEGER, OPTIONAL) - Used to return the status of the data transfer. 0 for valid read, positive for error, negative for end-of-file/record. If absent and an error/end-of-file occurs, program execution is terminated. ### Action Characters are read from the connected file starting with the next character in the current record or the first character of the next record. Input may be terminated by the end of a record or by a character in the 'set' argument. The file position after transfer is after the last character read. If 'separator' is present, the terminating character is returned. If 'iostat' is present, it indicates the status of the operation. ``` -------------------------------- ### Lexing a simple format string Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Demonstrates tokenization of a basic format string without parentheses. ```python lexer('4i4') [ Token: type=UINT, value=4, Token: type=ED6, value=I, Token: type=UINT, value=4] ``` -------------------------------- ### Build a local distribution with Poetry Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Create local distribution files (wheel and sdist) for the project using Poetry. This is useful for testing the package before publishing. ```bash poetry build ``` -------------------------------- ### Run minimal tests with make Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Execute a reduced test suite for the project when time and resources are limited. This provides a quicker check of core functionality. ```bash make runminimaltests ``` -------------------------------- ### Build tests with make Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Generate test files for the project using the make build system. This step is necessary before running the tests. ```bash make buildtests ``` -------------------------------- ### Run performance tests with make Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Execute performance tests, which currently focus on reading and writing floating-point numbers. This helps assess the efficiency of the library's I/O operations. ```bash make runperformancetests ``` -------------------------------- ### Reset Configuration to Defaults Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Use the reset() function to revert all configuration settings back to their original default values. ```python >>> config.RECORD_SEPARATOR = '|' >>> format = FortranRecordWriter('(2I10)') >>> format.write([0, 0, 0, 0]) ' 0 0| 0 0' >>> config.reset() >>> format.write([0, 0, 0, 0]) ' 0 0\n 0 0' ``` -------------------------------- ### Write Hexadecimal (Z) values Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Shows how to write integers in hexadecimal format using the Z descriptor. Output is right-aligned. ```python from fortranformat import FortranRecordWriter hexw = FortranRecordWriter('(Z10)') print(hexw.write([255])) ``` -------------------------------- ### Test record format matching with FortranRecordReader.match Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Use the `match()` method to check if a record string conforms to the reader's format without raising an exception. This is useful for format validation or detection before parsing. ```python from fortranformat import FortranRecordReader reader = FortranRecordReader('(3F10.3)') # Valid record print(reader.match(' 1.000 2.000 3.000')) # True # Invalid record (letters in a numeric field) print(reader.match(' 1.000 ABCDE 3.000')) # False # Use for conditional branching line = ' 1.000 0.000 0.500' if reader.match(line): values = reader.read(line) print(f"Parsed: {values}") else: print("Unrecognised format") # Parsed: [1.0, 0.0, 0.5] ``` -------------------------------- ### Lexing a format string with repetition and parentheses Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Illustrates tokenization of format strings with a repetition count preceding parentheses. ```python lexer('4(i4)') [ Token: type=UINT, value=4, Token: type=LEFT_PARENS, value=None, Token: type=ED6, value=I, Token: type=UINT, value=4, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Lexing a format string with parentheses Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Shows how the lexer handles format strings enclosed in parentheses. ```python lexer('(4i4)') [ Token: type=LEFT_PARENS, value=None, Token: type=UINT, value=4, Token: type=ED6, value=I, Token: type=UINT, value=4, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Testing _get_sign with Zero Value and No Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt When incl_plus is False, a zero value results in an empty string. ```python >>> incl_plus = False >>> _get_sign(val, incl_plus) '' ``` -------------------------------- ### Input/Output Procedures for Varying Length Strings Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Procedures to support input and output of varying-length string values with formatted sequential files. ```APIDOC ## Input/Output Procedures ### Description Provides procedures for input and output of varying-length string values with formatted sequential files. ### Procedures - **GET**: Inputs part or all of a record into a string. - **PUT**: Appends a string to an output record. - **PUT_LINE**: Appends a string to an output record and ends the record. ``` -------------------------------- ### Lexing empty parentheses Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Demonstrates the lexer's handling of an empty pair of parentheses. ```python lexer('()') [ Token: type=LEFT_PARENS, value=None, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Testing _get_sign with Zero Value and Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt When incl_plus is True, a zero value results in a '+' sign. ```python >>> val = 0 >>> _get_sign(val, incl_plus) '+' ``` -------------------------------- ### Validate formats before batch processing Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Illustrates validating a list of format strings and creating `FortranRecordReader` instances only for valid formats, catching `InvalidFormat` for any malformed strings. ```python from fortranformat import FortranRecordReader, InvalidFormat formats = ['(3F10.3)', '(I5, A10)', '(INVALID)', '(2L5)'] valid_readers = [] for fmt in formats: try: valid_readers.append(FortranRecordReader(fmt)) except InvalidFormat as e: print(f"Skipping '{fmt}': {e}") print(f"Loaded {len(valid_readers)} valid reader(s)") ``` -------------------------------- ### FortranRecordReader.match(record) Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Tests whether a record matches the format. Returns True if the record can be parsed without error, False otherwise. Useful for format detection or validation. ```APIDOC ## FortranRecordReader.match(record) — Test whether a record matches the format `match()` is a convenience wrapper around `read()` that returns `True` if the given record string can be parsed with the current format without raising an exception, and `False` otherwise. It is useful for format detection or validation before committing to a parse. ### Method Signature `match(record_string)` ### Parameters * **record_string** (string) - The text record to test. ### Returns * **bool** - True if the record matches the format, False otherwise. ### Example Usage ```python from fortranformat import FortranRecordReader reader = FortranRecordReader('(3F10.3)') # Valid record print(reader.match(' 1.000 2.000 3.000')) # Expected output: True # Invalid record (letters in a numeric field) print(reader.match(' 1.000 ABCDE 3.000')) # Expected output: False # Use for conditional branching line = ' 1.000 0.000 0.500' if reader.match(line): values = reader.read(line) print(f"Parsed: {values}") else: print("Unrecognised format") # Expected output: Parsed: [1.0, 0.0, 0.5] ``` ``` -------------------------------- ### Run pytest tests with Poetry Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Execute the project's test suite using pytest, managed by Poetry. This command ensures that the project's functionality is working as expected. ```bash poetry run pytest ``` -------------------------------- ### Write String to Record (Extending Bounds) Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_write_string_test.txt Shows how _write_string handles inserting a substring when the specified position is beyond the original record's length. The string is padded with spaces if necessary, and the substring is appended. ```python >>> pos = 7 >>> _write_string(record, sub_string, pos) (10, '12345 abc') ``` -------------------------------- ### Testing _get_sign with Positive Value and Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt When incl_plus is True, a positive value results in a '+' sign. ```python >>> incl_plus = True >>> val = 1 >>> _get_sign(val, incl_plus) '+' ``` -------------------------------- ### Lexing a comprehensive format string with various tokens Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Tests the lexer with a wide range of format specifiers, including single and multi-character types, quoted strings, and numeric values, separated by commas and enclosed in parentheses. ```python lexer('(A,B,BN,BZ,:,D,E,EN,ES,F,G,I,L,O,P,S,/,SP,SS,T,TL,TR,X,Z),I1.1,\'foo\', ``` ```python "bar",3Hbaz') [ Token: type=LEFT_PARENS, value=None, Token: type=ED4, value=A, Token: type=COMMA, value=None, Token: type=ED6, value=B, Token: type=COMMA, value=None, Token: type=ED1, value=BN, Token: type=COMMA, value=None, Token: type=ED1, value=BZ, Token: type=COMMA, value=None, Token: type=ED9, value=:, Token: type=COMMA, value=None, Token: type=ED5, value=D, Token: type=COMMA, value=None, Token: type=ED7, value=E, Token: type=COMMA, value=None, Token: type=ED7, value=EN, Token: type=COMMA, value=None, Token: type=ED7, value=ES, Token: type=COMMA, value=None, Token: type=ED5, value=F, Token: type=COMMA, value=None, Token: type=ED7, value=G, Token: type=COMMA, value=None, Token: type=ED6, value=I, Token: type=COMMA, value=None, Token: type=ED3, value=L, Token: type=COMMA, value=None, Token: type=ED6, value=O, Token: type=COMMA, value=None, Token: type=ED8, value=P, Token: type=COMMA, value=None, Token: type=ED1, value=S, Token: type=COMMA, value=None, Token: type=ED10, value=/, Token: type=COMMA, value=None, Token: type=ED1, value=SP, Token: type=COMMA, value=None, Token: type=ED1, value=SS, Token: type=COMMA, value=None, Token: type=ED3, value=T, Token: type=COMMA, value=None, Token: type=ED3, value=TL, Token: type=COMMA, value=None, Token: type=ED3, value=TR, Token: type=COMMA, value=None, Token: type=ED2, value=X, Token: type=COMMA, value=None, Token: type=ED6, value=Z, Token: type=RIGHT_PARENS, value=None, Token: type=COMMA, value=None, Token: type=ED6, value=I, Token: type=UINT, value=1, Token: type=DOT, value=None, Token: type=UINT, value=1, Token: type=COMMA, value=None, Token: type=QUOTED_STRING, value=foo, Token: type=COMMA, value=None, Token: type=QUOTED_STRING, value=bar, Token: type=COMMA, value=None, Token: type=QUOTED_STRING, value=baz] ``` -------------------------------- ### Lexing nested repetition with parentheses Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Demonstrates tokenization of complex format strings involving nested repetitions and parentheses. ```python lexer('4(4i4)') [ Token: type=UINT, value=4, Token: type=LEFT_PARENS, value=None, Token: type=UINT, value=4, Token: type=ED6, value=I, Token: type=UINT, value=4, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Testing _get_sign with Positive Value and No Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt When incl_plus is False, a positive value results in an empty string. ```python >>> incl_plus = False >>> val = 1 >>> _get_sign(val, incl_plus) '' ``` -------------------------------- ### Write Logical (L) values Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Demonstrates writing boolean values using the L format descriptor. Output is right-aligned within the specified width. ```python from fortranformat import FortranRecordWriter flags = FortranRecordWriter('(2L5)') print(flags.write([True, False])) ``` -------------------------------- ### Configure PROC_MAXINT for Overflow Behavior Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Mimic FORTRAN's integer overflow behavior and two's complement encoding for negative numbers. Set PROC_MAXINT to the maximum positive integer for your platform or None to disable overflow behavior. ```python >>> format = FortranRecordWriter('(Z10)') >>> format.write([-10]) ' FFFFFFF6' >>> config.PROC_MAXINT = None >>> format.write([-10]) ' -A' ``` -------------------------------- ### Testing _get_sign with Negative Value and Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt A negative value consistently results in a '-' sign, regardless of the incl_plus flag. ```python >>> incl_plus = True >>> _get_sign(val, incl_plus) '-' ``` -------------------------------- ### Read FORTRAN records with FortranRecordReader Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Use FortranRecordReader to parse text lines into Python lists based on a FORTRAN format string. Ensure the format string accurately reflects the structure of the input data. ```python >>> from fortranformat import FortranRecordReader >>> header_line = FortranRecordReader('(A15, A15, A15)') >>> header_line.read(' x y z') [' x', ' y', ' z'] >>> line = FortranRecordReader('(3F15.3)') >>> line.read(' 1.000 0.000 0.500') [1.0, 0.0, 0.5] >>> line.read(' 1.100 0.100 0.600') [1.1, 0.1, 0.6] ``` -------------------------------- ### Read Fortran Records Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Use FortranRecordReader to parse a Fortran-formatted string into a Python list. It requires a format string that matches the input data. ```python >>> from fortranformat import FortranRecordReader >>> format = FortranRecordReader('(3I10)') >>> format.read(' 0 1') [0, 1, None] ``` -------------------------------- ### Comparison Procedures (LT, LE, GE, GT) Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Compares the lexical ordering of two strings based on the ISO 646 : 1991 collating sequence. ```APIDOC ## Comparison Procedures ### Description Compares the lexical ordering of two strings based on the ISO 646 : 1991 collating sequence. ### Procedures * L_LT_(string_a, string_b) * L_LE_(string_a, string_b) * L_GE_(string_a, string_b) * L_GT_(string_a, string_b) ### Arguments * **string_a** (VARYING_STRING or CHARACTER) * **string_b** (VARYING_STRING or CHARACTER) ### Result Attributes Scalar of type default LOGICAL. ### Result Value The result value is true if string_a stands in the indicated relationship to string_b, and is false otherwise. The collating sequence used is that of the International Standard ISO 646 : 1991. If string_a and string_b are of different lengths, the comparison is done as if the shorter string were padded on the right with blanks. If either argument contains a character c not defined by the standard, the result value is processor dependent and based on the collating value for IACHAR(c). Zero length strings are considered to be lexically equal. ``` -------------------------------- ### FortranRecordReader(format) Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Parses a FORTRAN format string and provides a read() method to convert a text record into a Python list of typed values. The object should be constructed once per format string and reused across multiple records for best performance. ```APIDOC ## FortranRecordReader(format) — Read FORTRAN-formatted text into Python values `FortranRecordReader` parses a FORTRAN format string and provides a `read()` method that converts a text record into a Python list of typed values. The object should be constructed once per format string and reused across multiple records for best performance, since changing the format triggers an expensive re-parse. ### Method Signature `FortranRecordReader(format_string)` ### Parameters * **format_string** (string) - The FORTRAN format statement string. ### Example Usage ```python from fortranformat import FortranRecordReader # Integer (I) and character (A) edit descriptors header = FortranRecordReader('(A15, A15, A15)') result = header.read(' x y z') print(result) # Expected output: [' x', ' y', ' z'] # Fixed-point float (F) edit descriptor with repeat count coords = FortranRecordReader('(3F15.3)') print(coords.read(' 1.000 0.000 0.500')) # Expected output: [1.0, 0.0, 0.5] # Integer (I) edit descriptor ints = FortranRecordReader('(I4, I4, I4)') print(ints.read(' 12 34567')) # Expected output: [12, 3, 4567] # Partial record: fewer values than descriptors yield None padding partial = FortranRecordReader('(3I10)') print(partial.read(' 0 1')) # Expected output: [0, 1, None] # Logical (L), Exponential (E), and General (G) descriptors logicals = FortranRecordReader('(L5, L5)') print(logicals.read(' T F')) # Expected output: [True, False] exp_reader = FortranRecordReader('(E15.7)') print(exp_reader.read(' 1.0000000E+00')) # Expected output: [1.0] # Hexadecimal (Z) descriptor hex_reader = FortranRecordReader('(Z8)') print(hex_reader.read(' FF')) # Expected output: [255] ``` ``` -------------------------------- ### Testing _get_sign with Negative Value and No Include Plus Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_get_sign_test.txt A negative value consistently results in a '-' sign, regardless of the incl_plus flag. ```python >>> val = -1 >>> _get_sign(val, incl_plus) '-' ``` -------------------------------- ### FortranRecordWriter(format) Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Parses a FORTRAN format string and provides a write() method to format a Python list of values into a fixed-width FORTRAN-style string. The object should be created once per format string and reused for multiple records. ```APIDOC ## FortranRecordWriter(format) — Write Python values into FORTRAN-formatted text `FortranRecordWriter` parses a FORTRAN format string and provides a `write()` method that formats a Python list of values into a fixed-width FORTRAN-style string. Like `FortranRecordReader`, the object should be created once per format string and reused for multiple records. Passing `None` as a value causes the FORTRAN default to be emitted (e.g., `0` for integers). ### Method Signature `FortranRecordWriter(format_string)` ### Parameters * **format_string** (string) - The FORTRAN format statement string. ### Example Usage ```python from fortranformat import FortranRecordWriter # Character (A) fields header = FortranRecordWriter('(A15, A15, A15)') print(header.write(['x', 'y', 'z'])) # Expected output: ' x y z' # Fixed-point float (F) with repeat count line = FortranRecordWriter('(3F15.3)') print(line.write([1.0, 0.0, 0.5])) # Expected output: ' 1.000 0.000 0.500' print(line.write([1.1, 0.1, 0.6])) # Expected output: ' 1.100 0.100 0.600' # Integer (I) descriptor ints = FortranRecordWriter('(3I10)') print(ints.write([0, 1, None])) # None → FORTRAN default (0) # Expected output: ' 0 1 0' # Exponential (E) and scientific (ES) notation exp = FortranRecordWriter('(E15.7)') print(exp.write([1.0])) # Expected output: ' 0.1000000E+01' ``` ``` -------------------------------- ### Lexing complex nested format string Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Shows tokenization of a complex Fortran format string with nested structures and multiple elements. ```python lexer('2(i4,3(i4))') [ Token: type=UINT, value=2, Token: type=LEFT_PARENS, value=None, Token: type=ED6, value=I, Token: type=UINT, value=4, Token: type=COMMA, value=None, Token: type=UINT, value=3, Token: type=LEFT_PARENS, value=None, Token: type=ED6, value=I, Token: type=UINT, value=4, Token: type=RIGHT_PARENS, value=None, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Read FORTRAN-formatted text with FortranRecordReader Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Use `FortranRecordReader` to parse FORTRAN format strings and convert text records into Python lists of typed values. Construct the reader once per format string for optimal performance. Handles various edit descriptors including I, A, F, L, E, G, and Z. ```python from fortranformat import FortranRecordReader # --- Integer (I) and character (A) edit descriptors --- header = FortranRecordReader('(A15, A15, A15)') result = header.read(' x y z') print(result) # [' x', ' y', ' z'] # --- Fixed-point float (F) edit descriptor with repeat count --- coords = FortranRecordReader('(3F15.3)') print(coords.read(' 1.000 0.000 0.500')) # [1.0, 0.0, 0.5] print(coords.read(' 1.100 0.100 0.600')) # [1.1, 0.1, 0.6] # --- Integer (I) edit descriptor --- ints = FortranRecordReader('(I4, I4, I4)') print(ints.read(' 12 34567')) # [12, 3, 4567] (fields are fixed-width, not delimiter-separated) # --- Partial record: fewer values than descriptors yield None padding --- partial = FortranRecordReader('(3I10)') print(partial.read(' 0 1')) # [0, 1, None] # --- Logical (L), Exponential (E), and General (G) descriptors --- logicals = FortranRecordReader('(L5, L5)') print(logicals.read(' T F')) # [True, False] exp_reader = FortranRecordReader('(E15.7)') print(exp_reader.read(' 1.0000000E+00')) # [1.0] # --- Hexadecimal (Z) descriptor --- hex_reader = FortranRecordReader('(Z8)') print(hex_reader.read(' FF')) # [255] ``` -------------------------------- ### Catch InvalidFormat on construction Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Shows how to catch the `InvalidFormat` exception when constructing a `FortranRecordReader` with an invalid format string, such as one containing an unrecognized edit descriptor. ```python from fortranformat import FortranRecordReader, InvalidFormat try: reader = FortranRecordReader('(Q10)') # Q is not a valid edit descriptor except InvalidFormat as e: print(f"Bad format: {e}") ``` -------------------------------- ### Parse empty format string Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/parser_test.txt Parses an empty format string '()'. This demonstrates the handling of empty format specifications. ```python >>> tokens = lexer('()') >>> parser(tokens) ([], []) ``` -------------------------------- ### Configure G_INPUT_TRIAL_EDS for G descriptor ambiguity Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Controls how the FortranRecordReader resolves ambiguity for the G descriptor on input. By default, it tries to interpret the input as a float, then a logical, and finally a string. This can be configured to prioritize specific types. ```python from fortranformat import FortranRecordReader import fortranformat.config as config config.reset() g_reader = FortranRecordReader('(G10.2)') print(g_reader.read(' 0')) # tries F first → float print(g_reader.read(' .T.')) # tries L second → bool print(g_reader.read(' STR')) # falls back to A → string config.G_INPUT_TRIAL_EDS = ['A'] # always return string for G on input print(g_reader.read(' 0')) ``` -------------------------------- ### PUT Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Writes a string to an external file. Supports specifying the output unit and an optional status indicator. ```APIDOC ## PUT Procedure ### Description Writes a string to an external file. ### Forms - CALL PUT(string,iostat) - CALL PUT(unit,string,iostat) ### Arguments - **string** (VARYING_STRING or CHARACTER) - The string to write to the file. - **unit** (INTEGER) - The output unit to be used. Must be connected to a formatted file for sequential write access. If omitted, the default output unit is used. - **iostat** (INTEGER, OPTIONAL) - Used to return the status of the data transfer. 0 for valid write, positive for error. If absent and an error occurs, program execution is terminated. ### Action Characters of 'string' are appended to the current record or the start of the next record. The last character transferred becomes the last character of the current record. If 'iostat' is present, it indicates the status of the operation. ``` -------------------------------- ### Parse format with nested groups and different specifiers Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/parser_test.txt Parses a format string 'i4,i4,(i5,i5),i4' demonstrating a mix of simple and grouped integer formats. This is useful for understanding how the parser handles sequences and nested structures. ```python >>> tokens = lexer('i4,i4,(i5,i5),i4') >>> parser(tokens) ([, , , , ], [, , ]) ``` -------------------------------- ### Write Python values to FORTRAN-formatted text with FortranRecordWriter Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Use `FortranRecordWriter` to format Python lists of values into fixed-width FORTRAN-style strings based on a provided format string. Reusing the writer object for multiple records improves performance. Passing `None` for a value results in the FORTRAN default (e.g., 0 for integers). ```python from fortranformat import FortranRecordWriter # --- Character (A) fields --- header = FortranRecordWriter('(A15, A15, A15)') print(header.write(['x', 'y', 'z'])) # ' x y z' # --- Fixed-point float (F) with repeat count --- line = FortranRecordWriter('(3F15.3)') print(line.write([1.0, 0.0, 0.5])) # ' 1.000 0.000 0.500' print(line.write([1.1, 0.1, 0.6])) # ' 1.100 0.100 0.600' # --- Integer (I) descriptor --- ints = FortranRecordWriter('(3I10)') print(ints.write([0, 1, None])) # None → FORTRAN default (0) # ' 0 1 0' # --- Exponential (E) and scientific (ES) notation --- exp = FortranRecordWriter('(E15.7)') print(exp.write([1.0])) # ' 0.1000000E+01' ``` -------------------------------- ### TRIM Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Removes trailing blanks from a string. ```APIDOC ## TRIM ### Description Removes trailing blanks from a string. ### Arguments * **string** (VARYING_STRING) - A scalar of type VARYING_STRING. ### Result Attributes Scalar of type VARYING_STRING. ### Result Value The result value is the same as string except that any trailing blanks have been deleted. If the argument string contains only blank characters or is of zero length, the result is a zero-length string. ``` -------------------------------- ### VAR_STR Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Converts an intrinsic fixed-length character value into a varying-length string value. ```APIDOC ## VAR_STR Procedure ### Description Converts an intrinsic fixed-length character value into the equivalent varying-length string value. ### Argument - `char` (CHARACTER) - The scalar character value of any length to convert. ### Result Attributes - Scalar of type VARYING_STRING. ### Result Value - The result value is the same string of characters as the argument. ``` -------------------------------- ### Configure RET_UNWRITTEN_VARS_NONE Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Determine if unwritten variables during reading should be represented as None (default) or their FORTRAN default values (e.g., 0). Set to False for FORTRAN default behavior. ```python >>> format = FortranRecordReader('(3I10)') >>> config.RET_UNWRITTEN_VARS_NONE = True # default >>> format.read(' 0 1') [0, 1, None] >>> config.RET_UNWRITTEN_VARS_NONE = False >>> format.read(' 0 1') [0, 1] ``` -------------------------------- ### REPEAT Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Concatenates several copies of a string. ```APIDOC ## REPEAT ### Description Concatenates several copies of a string. ### Arguments * **string** (VARYING_STRING) - A scalar of type VARYING_STRING. * **ncopies** (INTEGER) - A scalar of type default INTEGER. The value must not be negative. ### Result Attributes Scalar of type VARYING_STRING. ### Result Value The result value is the string produced by repeated concatenation of the argument string, producing a string containing ncopies copies of string. If ncopies is zero, the result is of zero length. ``` -------------------------------- ### Write String to Record (Mid-Bounds) Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/output_write_string_test.txt Demonstrates inserting a substring into the middle of a record. The substring replaces characters from the specified position, and the resulting string is returned with its new length. ```python >>> pos = 2 >>> _write_string(record, sub_string, pos) (5, '12abc') ``` -------------------------------- ### Lexing repetition with empty parentheses Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/handwritten/doctests/lexer_test.txt Shows tokenization of a repetition count followed by empty parentheses. ```python lexer('3()') [ Token: type=UINT, value=3, Token: type=LEFT_PARENS, value=None, Token: type=RIGHT_PARENS, value=None] ``` -------------------------------- ### Handle multi-record output with F descriptor Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Illustrates how the FortranRecordWriter wraps output to new records when the number of values exceeds the number of descriptors in a single record. The default record separator is a newline character. ```python from fortranformat import FortranRecordWriter multi = FortranRecordWriter('(3F5.1)') print(repr(multi.write([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]))) ``` -------------------------------- ### INSERT Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Inserts a substring into a string at a specified position. ```APIDOC ## INSERT Procedure ### Description Inserts a substring into a string at a specified position. ### Synopsis ```fortran INSERT(string, start, substring) ``` ### Arguments - **string** (VARYING_STRING or CHARACTER) - The original string. - **start** (INTEGER) - The position at which to insert the substring. If `start` is greater than `LEN(string)`, `substring` is appended. If `start` is less than one, `substring` is inserted at the beginning. - **substring** (VARYING_STRING or CHARACTER) - The substring to insert. ### Result Attributes Scalar of type VARYING_STRING. ### Result Value A copy of `string` with `substring` inserted before the character at position `start`. ``` -------------------------------- ### Write Fortran Records Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Use FortranRecordWriter to format and write Python data structures into a Fortran-compatible string format. It takes a format string and a list of values. ```python >>> from fortranformat import FortranRecordWriter >>> format = FortranRecordWriter('(3I10)') >>> format.write([0, 1, None]) ' 0 1 0' ``` -------------------------------- ### Write FORTRAN records with FortranRecordWriter Source: https://github.com/brendanarnold/py-fortranformat/blob/master/README.md Use FortranRecordWriter to convert Python lists into formatted text strings according to a FORTRAN format statement. The output string will adhere to the specified field widths and formats. ```python >>> from fortranformat import FortranRecordWriter >>> header_line = FortranRecordWriter('(A15, A15, A15)') >>> header_line.write(['x', 'y', 'z']) ' x y z' >>> line = FortranRecordWriter('(3F15.3)') >>> line.write([1.0, 0.0, 0.5]) ' 1.000 0.000 0.500' >>> line.write([1.1, 0.1, 0.6]) ' 1.100 0.100 0.600' ``` -------------------------------- ### SCAN Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html The SCAN procedure scans a string for any character present in a specified set. It supports optional backward scanning. ```APIDOC ## SCAN Procedure ### Description Scans a string for any one of the characters in a set of characters. ### Arguments - `string` (VARYING_STRING or CHARACTER) - The string to scan. - `set` (VARYING_STRING or CHARACTER) - The set of characters to scan for. - `back` (LOGICAL, OPTIONAL) - If true, scans backward from the end of the string. ### Result Attributes - Scalar of type default INTEGER. ### Result Value - If `back` is absent or false and a character from `set` is found: The position of the left-most character of `string` that is in `set`. - If `back` is true and a character from `set` is found: The position of the right-most character of `string` that is in `set`. - Zero if no character of `string` is in `set`, or if the length of either `string` or `set` is zero. ``` -------------------------------- ### PUT_LINE Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Writes a string to an external file and ends the record. It supports writing to a specified unit or the default output unit. ```APIDOC ## PUT_LINE Procedure ### Description Writes a string to an external file and ends the record. ### Synopsis ```fortran CALL PUT_LINE(string, iostat) CALL PUT_LINE(unit, string, iostat) ``` ### Arguments - **string** (VARYING_STRING or CHARACTER) - The string to write. - **unit** (INTEGER) - Optional. The output unit to be used. Defaults to the default output unit if omitted. Must be connected to a formatted file for sequential write access. - **iostat** (INTEGER) - Optional. Used to return the status of the data transfer. 0 for success, positive for error. ### Action Appends the characters of `string` to the current record or the start of the next record. Positions the file after the written record. If `iostat` is absent and an error occurs, program execution is terminated. ``` -------------------------------- ### Configure RET_WRITTEN_VARS_ONLY for reader Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt Controls whether the FortranRecordReader returns None for unread slots or only the values that were actually read. Default is False (return None). ```python from fortranformat import FortranRecordReader import fortranformat.config as config config.RET_WRITTEN_VARS_ONLY = False # default: return None for unread slots reader = FortranRecordReader('(3I10)') print(reader.read(' 0 1')) config.RET_WRITTEN_VARS_ONLY = True # only return what was actually read print(reader.read(' 0 1')) ``` -------------------------------- ### Configure RECORD_SEPARATOR Source: https://github.com/brendanarnold/py-fortranformat/blob/master/docs/wiki/guide.md Set the string used to delimit records when writing. The default is a newline character. ```python >>> config.RECORD_SEPARATOR = '|' >>> FortranRecordWriter('(2I10)').write([0, 0, 0, 0]) ' 0 0| 0 0' ``` -------------------------------- ### SPLIT Procedure Source: https://github.com/brendanarnold/py-fortranformat/blob/master/tests/misc/raw/lib/VaryingLengthCharacterStringsInFortran.html Splits a string into two substrings based on a separator set. The procedure searches forward by default or backward if specified. It returns the separated parts and optionally the separator character. ```APIDOC ## SPLIT Procedure ### Description Splits a string into a two substrings with the substrings separated by the occurrence of a character from a specified separator set. The string is searched in the forward direction unless `back` is present with the value true, in which case the search is in the backward direction. ### Method Signature `CALL SPLIT(string, word, set, separator, back)` ### Arguments - **string** (VARYING_STRING) - The input string to be split. - **word** (VARYING_STRING) - Output: The part of the string before the separator. - **set** (VARYING_STRING or CHARACTER) - The set of characters to use as separators. - **separator** (VARYING_STRING, OPTIONAL) - Output: The actual separator character found. - **back** (LOGICAL, OPTIONAL) - If true, searches backward; otherwise, searches forward. ### Action - The string is divided at the first occurrence of a character from `set`. - If `back` is true, the search is backward. - Characters passed over in the search are returned in `word`. - The remainder of the string (excluding the separator) is returned in `string`. - If no separator is found or `set` is empty, the whole string is returned in `word`, and `string` is empty. - If `separator` is provided, the separator character is returned in it. ### Post-conditions - For a forward search: `word` // `separator` // `string` equals the initial string. - For a backward search: `string` // `separator` // `word` equals the initial string. ``` -------------------------------- ### Configure RET_UNWRITTEN_VARS_NONE for reader Source: https://context7.com/brendanarnold/py-fortranformat/llms.txt When RET_UNWRITTEN_VARS_NONE is True, the FortranRecordReader returns the FORTRAN default (0 for numeric types) instead of None for unread slots. This setting is merged with RET_WRITTEN_VARS_ONLY. ```python from fortranformat import FortranRecordReader import fortranformat.config as config config.reset() config.RET_UNWRITTEN_VARS_NONE = True reader = FortranRecordReader('(3I10)') print(reader.read(' 0 1')) ```