def genPeriod(chords = default_chords, bi11 = None, real_end = False):
    if bi11 == None:
        bi11 = gbi.genBasicIdea(chords=chords[:4])
    bi21 = gbi.genBasicIdea(prev_note = bi11.pits[-1], chords=chords[4:8])
    bi21cells = bi21.cells
    bi21cells[-1] = genending.genEnding(bi21cells[-2].pits[-1], chord=chords[7], authentic=False)
    bi21 = Chunk(sub_chunks = bi21cells)
    bi12 = tf.alterBasicIdea(bi = bi11, prev_note = bi21.pits[-1], chords = chords[8:12])
    bi22 = tf.alterBasicIdea(bi = bi21, prev_note = bi12.pits[-1], chords = chords[12:], cadence='authentic', real_end = real_end)
    return Chunk(sub_chunks=[Chunk(sub_chunks=[bi11,bi21]), Chunk(sub_chunks=[bi12, bi22])])
def genContinuationCadential(prev_note = random.choice([2,4,7]), end_chords = [[0,2,4], [3,5,7], [4,6,8], [0,2,4]]):
    cords = [[0,2,4], [1,3,5],[4,6,8], [-2,0,2],[1,3,5],[0,2,4]]
    cells = []
    for i in range(0, 3):
        for j in range(0,2):
            cell_type = CHORDAL if random.uniform(0,1) < 0.5 else SCALEWISE
            chord = cords[i*2 + j]
            cell = gc.genCell(prev_note = prev_note, length=2.0, chord=chord, durs=[0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25], cell_type=cell_type)
            for k in range(0,4):
                if (cell.pits[0] == cell.pits[2] and cell.pits[1] == cell.pits[3] or cell.pits[4] == cell.pits[6] and cell.pits[5] == cell.pits[7]):
                    cell = gc.genCell(prev_note = prev_note, length=2.0, chord=chord, durs=[0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25], cell_type=cell_type)
            cells.append(cell)
            prev_note = cells[-1].pits[-1]

    end_chord_durs = [[0.75,0.25,0.75,0.25],[0.75,0.25,0.75,0.25],[0.5,0.5,0.5,0.5],[1.0]]
    for i in range(0, len(end_chords) - 1):
        cells.append(gc.genCell(prev_note = prev_note, length=2.0, chord=end_chords[i], durs=end_chord_durs[i], cell_type=CHORDAL))
        prev_note = cells[-1].pits[-1]
        if prev_note > 14:
                prev_note -= 3
    cells.append(genending.genEnding(prev_note, chord=[0,2,4], authentic=True))
    return Chunk(sub_chunks=cells)
def genPhrase(
    prev_note=random.randint(0, 4),
    chords=[[0, 2, 4], [0, 2, 4], [4, 6, 8], [0, 2, 4], [0, 2, 4], [3, 5, 7], [4, 6, 8], [0, 2, 4]],
    basicIdea=None,
    authentic_cadence=False,
):
    phrase_cells = []
    if basicIdea == None:
        basicIdea = gb.genBasicIdea(prev_note=prev_note, chords=chords[:4], motif1=None)
    phrase_cells = basicIdea.cells
    # choose first or second motif of basic idea to transform for third motif
    which_motif_to_transform = random.choice([phrase_cells[:2], phrase_cells[2:]])
    third_motif = tf.transformMotif(which_motif_to_transform, phrase_cells[-1], chords[4:6])
    motif4cell1 = gc.genCell(
        2.0,
        third_motif[-1].pits[-1],
        first_note=None,
        chord=chords[6],
        durs=rhy.getDefiningRhythm(phrase_cells + third_motif),
    )
    motif4cell2 = genending.genEnding(motif4cell1.pits[-1], chords[-1], authentic_cadence)
    second_half = Chunk(sub_chunks=third_motif + [motif4cell1] + [motif4cell2], ctype="half")
    return Chunk(sub_chunks=[basicIdea, second_half], ctype="phrase")