import collections


def readAsIntervals( gff_iterator, with_values = False, with_records = False,
                     use_strand = False ):
    """read tuples of (start, end) from a GFF file.

    If with_values is True, a value is added to the tuples.
    If with_records is True, the record is added to the tuples.
    with_values and with_records are exclusive.
    
    If use_strand is True, intervals will be grouped by contig and strand.
    The default is to group by contig only.

    Returns a dictionary of intervals by contig.
    """

    assert not (with_values and with_records), "both with_values and with_records are true."
    intervals = collections.defaultdict(list)
    if use_strand:
        keyf = lambda x: (x.contig, x.strand)
    else:
        keyf = lambda x: x.contig

    if with_values:
        for gff in gff_iterator:
            intervals[keyf(gff)].append( (gff.start,gff.end,gff.score) )
    elif with_records:
        for gff in gff_iterator:
            intervals[keyf(gff)].append( (gff.start,gff.end,gff) )
    else:
        for gff in gff_iterator:
            intervals[keyf(gff)].append( (gff.start,gff.end) )
    return intervals