def __evaluate_model(valid_world, batchsize, datatype, display_examples, max_exs=-1):
    """Evaluate on validation/test data.
    - valid_world created before calling this function
    - batchsize obtained from opt['batchsize']
    - datatype is the datatype to use, such as "valid" or "test"
    - display_examples is bool
    - max_exs limits the number of examples if max_exs > 0
    """
    print('[ running eval: ' + datatype + ' ]')

    valid_world.reset()
    cnt = 0
    for _ in valid_world:
        valid_world.parley()
        if cnt == 0 and display_examples:
            print(valid_world.display() + '\n~~')
            print(valid_world.report())
        cnt += batchsize
        if valid_world.epoch_done() or (max_exs > 0 and cnt >= max_exs):
            # note this max_exs is approximate--some batches won't always be
            # full depending on the structure of the data
            break
    valid_report = valid_world.report()

    print(datatype + ':' + str(valid_report))

    return valid_report, valid_world