Skip to content

Instantly share code, notes, and snippets.

@lambda-fairy
Last active December 21, 2015 10:18
Show Gist options
  • Save lambda-fairy/6290775 to your computer and use it in GitHub Desktop.
Save lambda-fairy/6290775 to your computer and use it in GitHub Desktop.
Count the number of comparisons performed by a program
"""
A simple mixin that counts the number of comparisons performed. Each
class it is mixed into keeps its own counter, which can be retrieved and
reset at whim. The code is written generically, and will work with any
orderable type.
In the COSC122 (first year computer science) course at the University of
Canterbury, one of the assignments is to implement a binary search. To
verify the algorithm, students have to manually increment a counter
every time they compare two values. This is annoying and error-prone,
and distracts from the purpose of the task.
This proposes a novel approach to the problem, by bumping the counter
automatically.
For an example, see the end of this module.
By Lambda Fairy (github.com/lfairy). Released into the public domain.
"""
import sys
if sys.version_info < (3, 0):
raise RuntimeError('This module only works under Python 3')
class Counter:
_counters = {}
@classmethod
def _reset(cls):
cls._counters[id(cls)] = 0
@classmethod
def _get(cls):
return cls._counters.get(id(cls), 0)
@classmethod
def _increment(cls):
cls._counters[id(cls)] = 1 + cls._get()
def __lt__(self, other):
self._increment()
return super().__lt__(other)
def __gt__(self, other):
self._increment()
return super().__gt__(other)
def __le__(self, other):
self._increment()
return super().__le__(other)
def __ge__(self, other):
self._increment()
return super().__ge__(other)
def __eq__(self, other):
self._increment()
return super().__eq__(other)
if __name__ == '__main__':
# Mix everything together
class CountingInt(Counter, int): # Counter must come first
pass
# Create a list of values
import random
data = [CountingInt(x) for x in range(16)]
random.shuffle(data)
# Sort it
CountingInt._reset()
data.sort()
print('Sorting required', CountingInt._get(), 'comparisons')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment