easy +10 pts

Event emitter basics

Build a minimal event emitter class with on, off, emit, listener_count, and remove_all methods.

Create a class `EventEmitter` that mimics a minimal event system. The class should have the following methods: - `on(event, callback)`: registers a callback to be invoked when the event is emitted. The callback receives any arguments passed to `emit`. Returns a function that, when called, unsubscribes the callback (i.e., removes it so future emissions do not call it). - `emit(event, *args)`: invokes all registered callbacks for the given event in the order they were subscribed. Passes `*args` to each callback. Returns `True` if at least one callback was invoked, `False` otherwise. - `off(event, callback)`: removes the specific callback from the event. If the callback is not found or the event has no listeners, do nothing. - `listener_count(event)`: returns the number of currently registered callbacks for the given event. - `remove_all(event=None)`: if `event` is provided, removes all callbacks for that event. If `event` is `None`, removes all callbacks for all events. Requirements: - Multiple callbacks for the same event are allowed. - Callbacks should be invoked in the order they were added. - `on` should return an unsubscribe function that works even if the callback has already been removed via `off` (i.e., it should not raise an error). - `emit` should not break if a callback is removed during emission; it should only call callbacks that were registered at the time of emission (i.e., copy the list before iterating).

Constraints

You may assume `event` is a hashable string (or similar). Callbacks are callable objects. The number of callbacks per event is at most 10^4. Total operations are at most 10^4. The class should have O(1) average time for `on`, `off` (if you use dict of lists), and O(k) for `emit` where k is number of callbacks.

Example

>>> emitter = EventEmitter()
>>> logs = []
>>> unsub = emitter.on('greet', lambda name: logs.append(f'Hello {name}'))
>>> emitter.emit('greet', 'Alice')
True
>>> logs
['Hello Alice']
>>> unsub()
>>> emitter.emit('greet', 'Bob')
False
>>> logs
['Hello Alice']
10 points ~15 min

Recent Submissions

No submissions yet — hit Run Tests to try!

Hints

Store listeners in a dictionary mapping event names to a list of callbacks.
The unsubscribe function returned by `on` should close over the event and callback, and when called use `off` (or directly remove from the list).
In `emit`, make a copy of the current listener list before iterating to handle mid-emission removals safely.
For `remove_all(None)`, clear the entire dictionary.
Python 3
All tests passed!
Test Results
Press Ctrl+Enter or click Run Tests to execute your code.