Add get_equivalence_class util method
This way, we can partition songs into equivalence classes based on identicalness
This commit is contained in:
parent
8988bb820c
commit
d3d28777e7
4
karaokatalog/util/__init__.py
Normal file
4
karaokatalog/util/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
"""
|
||||
Utility functions completely independent of the root project (i.e., you could copy
|
||||
them to any other code project and they'd immediately work).
|
||||
"""
|
32
karaokatalog/util/get_equivalence_classes.py
Normal file
32
karaokatalog/util/get_equivalence_classes.py
Normal file
@ -0,0 +1,32 @@
|
||||
from collections.abc import Iterable, Sequence, Callable
|
||||
|
||||
type EquivalenceClass[T] = Sequence[T]
|
||||
|
||||
|
||||
def get_equivalence_classes[T](
|
||||
items: Iterable[T], is_equivalent: Callable[[T, T], bool]
|
||||
) -> Sequence[EquivalenceClass[T]]:
|
||||
"""
|
||||
Partition an iterable of items into equivalence classes under the given equivalence relation.
|
||||
The order of `items` is kept within the equivalence classes.
|
||||
|
||||
>>> from math import floor
|
||||
>>> get_equivalence_classes([1.0, 2.1, 1.1, 1.0, 2.2, 2.1, 3.3], lambda a, b: floor(a) == floor(b))
|
||||
((1.0, 1.1, 1.0), (2.1, 2.2, 2.1), (3.3,))
|
||||
"""
|
||||
equivalence_classes: list[list[T]] = []
|
||||
|
||||
for item in items:
|
||||
# Check if the item belongs into an already existing equivalence class
|
||||
for equivalence_class in equivalence_classes:
|
||||
# Pick an arbitrary representative of the equivalence class (we are allowed to do this
|
||||
# because it is an equivalence class)
|
||||
representative = equivalence_class[0]
|
||||
if is_equivalent(item, representative):
|
||||
equivalence_class.append(item)
|
||||
break
|
||||
else:
|
||||
# This item forms a new equivalence class, so we create one containing only the item and append it
|
||||
equivalence_classes.append([item])
|
||||
|
||||
return tuple(tuple(equivalence_class) for equivalence_class in equivalence_classes)
|
Loading…
x
Reference in New Issue
Block a user