from typing import List, Optional, Any from dataclasses import dataclass from random import randint from datetime import datetime, timezone import logging logging.basicConfig() logger = logging.getLogger('seek_and_tell_app') logger.setLevel(logging.DEBUG) FILENAME: str = 'sample.txt' def create_file(name: str, content: Optional[str] = None,) -> None: """Creates a file with content""" if not content: content = f'Created at {datetime.now(tz=timezone.utc)}\n' with open(name, 'w') as f: f.write(content) @dataclass class Reader: """Reader reads file and save last know position in memory""" filename: str lines: Optional[List[bytes]] = None last_pos: Optional[int] = None def update_pos(self, binary: Any) -> None: """Update last know position""" position: Any = binary.tell() self.last_pos = int(position) def read(self): try: with open(self.filename, 'rb') as f: if self.last_pos: f.seek(self.last_pos) self.lines = f.readlines() logger.info(f"{self.lines}") self.update_pos(f) except (FileNotFoundError, OSError) as exc: logger.error(exc.__class__.__name__) def __len__(self) -> int: return len(self.lines) @dataclass class Writer: """Write writes N lines to given file""" filename: str def write(self, lines: int) -> None: try: with open(self.filename, 'a') as f: for line in range(lines): f.write(f"{randint(1, 10**10)}\n") except (FileNotFoundError, OSError) as exc: logger.error(exc.__class__.__name__) if __name__ == '__main__': # create a sample file create_file(FILENAME) # create Writer & Reader instances writer: Writer = Writer(FILENAME) reader: Reader = Reader(FILENAME) # logic reader.read() writer.write(10) # writes 10 new lines in file reader.read() assert 10 == len(reader) writer.write(3) # writes 3 new lines in sample file reader.read() # will fail, 2 != 3 assert 2 == len(reader)