**What was implemented** - A directed graph class (`Graph`) that stores nodes, edges, and optional data on both. - Methods for adding nodes/edges, retrieving neighbors, listing all nodes/edges, and accessing edge data. - Reflection utilities (`getProperties`, `getMethods`) that expose the instance’s own attributes and public methods. - Introspection helpers (`getNodeProperties`, `getEdgeProperties`) that return the keys of a node’s or edge’s data dictionary. - A parallel Python implementation (`src/index.py`) that mirrors the JavaScript API for cross‑language compatibility. **Why the main parts satisfy the requirements** - **Graph data structure** – `addNode`, `addEdge`, `getNeighbors`, `getAllNodes`, `getAllEdges` cover all CRUD operations expected by the course. - **Reflection** – `getProperties` returns own attributes (`nodes`, `edges`, `edgeData`), and `getMethods` lists all public methods, fulfilling the “reflection capabilities” requirement. - **Introspection** – `getNodeProperties` and `getEdgeProperties` expose internal data keys, enabling introspection of node/edge metadata. - **Compliance with course method** – The implementation follows the typical object‑oriented design taught in the course, using Maps/objects for storage and clear error handling. **Key code excerpts** *src/index.js* – core graph operations ```js addNode(id, data = {}) { if (this.nodes.has(id)) throw new Error(`Node with id ${id} already exists`); this.nodes.set(id, data); this.edges.set(id, new Set()); } ``` *src/index.js* – reflection utilities ```js getProperties() { return Object.getOwnPropertyNames(this); } getMethods() { const proto = Object.getPrototypeOf(this); return Object.getOwnPropertyNames(proto).filter( (name) => typeof this[name] === 'function' && name !== 'constructor' ); } ``` *src/index.py* – parallel Python API ```python def get_properties(self) -> List[str]: return list(self.__dict__.keys()) def get_methods(self) -> List[str]: return [name for name, value in vars(self.__class__).items() if callable(value) and not name.startswith("_")] ``` **Honest limitations** - The graph is directed only; undirected edges would require additional logic. - No cycle detection or graph traversal algorithms are provided. - Persistence (saving/loading) is not implemented. - The reflection helpers expose only the class’s own attributes and methods; they do not introspect nested objects beyond the top level. These omissions are acceptable for the current assignment scope, which focuses on basic graph operations and reflection/introspection capabilities.