Skip to content

Instantly share code, notes, and snippets.

@yozx
Created April 13, 2020 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yozx/18a9067ceaeb87d2f5443dc7109714ab to your computer and use it in GitHub Desktop.
Save yozx/18a9067ceaeb87d2f5443dc7109714ab to your computer and use it in GitHub Desktop.
seek_and_tell_basic_example
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment