AmpèrePro
Interactive circuit-learning application with real-time simulation and level-based exercises for learning electricity concepts.
- Python
- PySide6
- NumPy
- Dacite
Motivation & approach
This was a school project developed with 4 other teammates. The goal was to make electricity concepts more intuitive by combining real-time circuit simulation with interactive, level-based learning challenges.
We structured the application around a clear separation between UI, simulation logic, and data models to improve maintainability and make circuit behavior immediately observable and easy to experiment with.
Technology used
- PySide6 — desktop UI and interaction system.
- NumPy — numerical computation for circuit simulation.
- Dacite — typed data validation and JSON serialization.
What I worked on
- Designed and implemented parts of the UI using PySide6.
- Built a type-safe save system using dataclasses + Dacite, including validation and fallback initialization.
- Worked with structured data models for circuits, levels, and progression systems.
- Collaborated in a team of 5 (including myself) using an Agile Scrum workflow to deliver features iteratively.
Save system (typed dataclasses + Dacite)
class Sauvegarde:
def __init__(self):
try:
self.data = from_dict(
SaveDTO,
read("data.json"),
config=Config(strict=True, check_types=True)
)
niveau = self.data.niveau
if len(niveau.ohm) != 5 or len(niveau.kirchoff) != 5 or len(niveau.resistance) != 5:
raise ValueError("Invalid progression data")
except (FileNotFoundError, ValueError, WrongTypeError, MissingValueError, UnexpectedDataError):
self.initialize_defaults()
def initialize_defaults(self):
default_data = SaveDTO([], NiveauDTO(
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
))
write("data.json", asdict(default_data))
self.data = default_data
def write(path: str, data: dict):
with open(path, "w") as file:
json.dump(data, file)
def read(path: str):
with open(path, "r") as file:
return json.loads(file.read())
Typed dataclasses are used with Dacite to deserialize JSON into structured models. This ensures consistency across the save system while keeping the solution lightweight.
Dacite was chosen over heavier validation frameworks (like Pydantic) to keep the system simple and sufficient for the project’s needs.
Data models
@dataclass
class CircuitDTO:
id: str
nom: str
fils: list[FilDTO]
noeuds: list[NoeudDTO]
derniere_sauvegarde: int
@dataclass
class NiveauDTO:
ohm: list[int]
kirchoff: list[int]
resistance: list[int]
@dataclass
class SaveDTO:
circuits: list[CircuitDTO]
niveau: NiveauDTO