import re


def _match_fp_number(full_file, patterns):
    """Extract numbers from patterns in full_file (a string)

    patterns is a list of pairs, (key, pattern). Each pattern should be a
    regular expression with exactly one capture group. Any match for group will
    be parsed as a float.

    Returns a pair (nums, errs) where nums is a dictionary keyed by the keys in
    patterns. The value at K is a list of floats matching patterns[K] if there
    was more than one match. If there was exactly one match for the
    patterns[K], the value at K is that float (rather than a singleton list).

    errs is a list of error messages (caused by failed float conversions or
    when there is no match for a pattern).

    """
    nums = {}
    errs = []
    for key, pattern in patterns:
        floats = []
        matches = re.findall(pattern, full_file, flags=re.MULTILINE)
        if not matches:
            errs.append('Pattern {!r} of key {!r} not found'.format(
                pattern, key))
            continue

        for match in matches:
            try:
                floats.append(float(match))
            except ValueError as err:
                errs.append('ValueError: {}'.format(err))

        if floats:
            nums[key] = floats[0] if len(floats) == 1 else floats

    return (nums, errs)