Design a Data Helper for Beginners in Python
Build a beginner-friendly DataHelper class that loads, saves, appends, and summarizes JSON data with atomic file writes.
Python code
54 linesimport json
from datetime import datetime
from pathlib import Path
class DataHelper:
"""A beginner-friendly helper for common data operations."""
def __init__(self, data=None, filepath=None):
self.data = data if data is not None else []
self.filepath = Path(filepath) if filepath else None
@classmethod
def from_json(cls, filepath):
"""Load data from a JSON file."""
with open(filepath, "r", encoding="utf-8") as f:
payload = json.load(f)
return cls(data=payload, filepath=filepath)
def save_json(self, filepath=None):
"""Persist data as JSON atomically (write-temp-then-replace)."""
target = Path(filepath) if filepath else self.filepath
if not target:
raise ValueError("No filepath provided")
target.parent.mkdir(parents=True, exist_ok=True)
tmp = target.with_suffix(".tmp")
with open(tmp, "w", encoding="utf-8") as f:
json.dump(self.data, f, indent=2)
tmp.replace(target)
return target
def add_record(self, record):
"""Append a record with an automatic timestamp."""
record = dict(record)
record.setdefault("created_at", datetime.utcnow().isoformat())
self.data.append(record)
return record
def summary(self):
"""Return a short summary of the dataset."""
first = self.data[0] if self.data else {}
return {
"count": len(self.data),
"keys": list(first.keys()) if isinstance(first, dict) else None,
}
if __name__ == "__main__":
helper = DataHelper()
helper.add_record({"name": "Alice", "score": 42})
helper.add_record({"name": "Bob", "score": 17})
saved = helper.save_json("sample_data.json")
reloaded = DataHelper.from_json(saved)
print(json.dumps(reloaded.summary(), indent=2))
Output
{
"count": 2,
"keys": ["name", "score", "created_at"]
}
How it works
The DataHelper class wraps common data operations, making it easy for beginners to load, modify, and persist JSON data. The from_json classmethod reads a file and returns a new instance, while save_json uses a temporary file then replace() to avoid corruption. add_record automatically stamps each entry with a UTC timestamp, and summary gives a quick view of the dataset's size and fields. The use of pathlib.Path ensures cross-platform path handling and simplifies directory creation.
Common mistakes
- Using `open()` without specifying encoding='utf-8' when writing files that may contain non-ASCII characters.
- Forgetting to call `mkdir(parents=True, exist_ok=True)` which fails if the target directory doesn't exist.
- Assuming `data` is always a list, but the class accepts any object; `summary()` handles non-dict items by setting keys to None.
- Using `datetime.utcnow()` which is deprecated in Python 3.12; prefer `datetime.now(timezone.utc)`.
Variations
- Use `dataclasses` to represent records with typed fields and validation instead of plain dictionaries.
- Implement `__enter__` and `__exit__` to make the helper a context manager, simplifying automatic saving.
Real-world use cases
- Creating a small configuration manager that reads and writes JSON settings for a desktop app.
- Building a simple data-capture script that appends sensor readings and periodically exports them to a file.
- Prototyping a lightweight persistence layer for a CLI tool that stores user preferences locally.
Sponsored
More from Production deployment patterns
- Auto Rollback on Error Rate Exceeded in Python medium
- Automate Semantic Versioning with Conventional Commits in Python medium
- Docker healthcheck CMD mock in Python easy
- Generate a Mock Artifact Version Tag in Python easy
- Generate a docker-compose.yml with mock services in Python easy
- How to Attach an SBOM to a Release in Python (Mock) easy
Keep learning
Related tutorials and quizzes for this topic.