Skip to content

Conversation

@oerc0122
Copy link
Owner

@oerc0122 oerc0122 commented May 1, 2025

No description provided.

@oerc0122 oerc0122 added the tools Relating to integrating with 3rd party codes label May 1, 2025
@oerc0122 oerc0122 requested a review from ajjackson May 1, 2025 13:35
@oerc0122 oerc0122 self-assigned this May 1, 2025
@github-actions
Copy link

github-actions bot commented May 1, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
3588 3314 92% 0% 🟢

New Files

File Coverage Status
castep_outputs/tools/md_geom_parser.py 90% 🟢
TOTAL 90% 🟢

Modified Files

File Coverage Status
castep_outputs/init.py 100% 🟢
castep_outputs/tools/init.py 100% 🟢
castep_outputs/utilities/filewrapper.py 90% 🟢
TOTAL 97% 🟢

updated for commit: 1358fed by action🐍

@oerc0122 oerc0122 force-pushed the add-md-geom-parser branch 4 times, most recently from 01feeba to 2ef9b18 Compare May 2, 2025 16:03
@oerc0122 oerc0122 force-pushed the add-md-geom-parser branch 2 times, most recently from f63a3ff to 2945a7c Compare May 21, 2025 15:23
@oerc0122 oerc0122 force-pushed the add-md-geom-parser branch from 2945a7c to 4e49a54 Compare June 10, 2025 23:23
@oerc0122 oerc0122 force-pushed the add-md-geom-parser branch 2 times, most recently from 7af8bf2 to 04f2946 Compare July 17, 2025 11:10
Copy link
Collaborator

@ajjackson ajjackson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems useful and nicely written!

I think I see a design issue, however, which can be solved with better separation of the "data container" and "generator" aspects of the object.

"""

def __init__(self, md_geom_file: Path | str) -> None:
self._next_frame = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self._next_frame = 0
self._next_frame: int | None = 0

pass
self._frame_len = self._handle.lineno - self._start_line - 1

self._byte_len = self._handle.tell() - self._start
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like _frame_bytes would be less confusing. byte_len is 8, surely 😎

self._len = int(len_est)

@property
def next_frame(self) -> int:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def next_frame(self) -> int:
def next_frame(self) -> int | None:


@property
def next_frame(self) -> int:
"""Get index of next frame to be read."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Get index of next frame to be read."""
"""Get index of next frame to be read, or None if at file end."""

MDGeomTimestepInfo
Parsed frame.
"""
if -len(self) > frame > len(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will always fail for positive values of len and frame.

>>> -3 > 1 > 3
False

Bid odd that it only raises a warning. But I assume that is how the tests are passing?

Comment on lines 137 to 154
def __iter__(self) -> Generator[MDGeomTimestepInfo, int, None]:
"""
Get generator over all frames in system.

Jumps permitted through ``send``.

Yields
------
MDGeomTimestepInfo
Frames in file.
"""
self._handle.file.seek(self._start)
self._handle._lineno = self._start_line
self._next_frame = 0
while self._next_frame is not None:
jump = yield next(self)
if jump is not None:
self._go_to_frame(jump)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some "fun" things (in Dwarf Fortress sense) can happen if multiple iterators are opened from the same instance, as each iterator mutates the same state.

There are some strong opinions on the topic at this StackOverflow: https://stackoverflow.com/questions/46941719/how-can-i-have-multiple-iterators-over-a-single-python-iterable-at-the-same-time

I think Python classes are not supposed to be used as both an Iterator and Iterable. Perhaps this class should choose to act like an Iterable collection (with get-item functionality), not providing a __next__ method. Then the __iter__ code (which acts as a Generator) should maintain its own position information, independent of the main object state, and be able to seek to the next position even if the underlying object is not in sync.

@oerc0122 oerc0122 requested a review from ajjackson September 26, 2025 13:21
@oerc0122 oerc0122 force-pushed the add-md-geom-parser branch 5 times, most recently from a78c3a5 to 1358fed Compare September 26, 2025 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools Relating to integrating with 3rd party codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants