#!/usr/bin/python
#
# Execute a mapper or reducer. Call like this:
#
#   ./mr.py module-name
#
# module should be the name a module file (i.e., mymodule is in
# mymodule.py) locatable on the current module path. The module should
# define one or the other of the following functions (but not both):
#
#   def mapper(key, value)
#   def reducer(key, values)
#
# The input will be mapped or reduced based on the appropriate
# behavior given the name of the function defined in the module. It is
# an error to define both mapper and reducer in a single module.
#

import sys, imp, MapReduce

if len(sys.argv) < 2:
    print >>sys.stderr, "Requires module file argument"
    exit(1)

name = sys.argv.pop(1)
m = imp.load_module(name, *imp.find_module(name))

if 'mapper' in m.__dict__ and not 'reducer' in m.__dict__:
    c = MapReduce.Mapper
    f = m.mapper
elif 'reducer' in m.__dict__ and not 'mapper' in m.__dict__:
    c = MapReduce.Reducer
    f = m.reducer
else:
    print >>sys.stderr, "%s must contain mapper or reducer function" % name

class Handler(c):
    def dispatch(self, key, value):
        f(key, value)

handler = Handler()
handler.process(sys.stdin)