You are to write a function to transpose a guitar tab up or down a number of semitones. The amount to transpose is a number, positive or negative. The tab is given as an array, with six elements for each guitar string (fittingly passed as strings). Output your tab in a similar form.
Guitar tablature (or 'tab') is an alternative to sheet music, where notes are replaced by fret numbers and the five lines of the staff are replaced by six lines to represent each of the guitar's strings. It is still read from left to right like sheet music, and notes written directly above each other are played at the same time.
For example, Led Zeppelin's Stairway to Heaven begins:
```
e|-------5-7-----7-|-8-----8-2-----2-|-0---------0-----|-----------------|
B|-----5-----5-----|---5-------3-----|---1---1-----1---|-0-1-1-----------|
G|---5---------5---|-----5-------2---|-----2---------2-|-0-2-2-----------|
D|-7-------6-------|-5-------4-------|-3---------------|-----------------|
A|-----------------|-----------------|-----------------|-2-0-0---0--/8-7-|
E|-----------------|-----------------|-----------------|-----------------|
```
Transposed up two semitones, it would look like this:
```
e|-------7-9-----9-|-10-----10-4-----4-|-2---------2-----|------------------|
B|-----7-----7-----|----7--------5-----|---3---3-----3---|-2-3-3------------|
G|---7---------7---|------7--------4---|-----4---------4-|-2-4-4------------|
D|-9-------8-------|-7---------6-------|-5---------------|------------------|
A|-----------------|-------------------|-----------------|-4-2-2---2--/10-9-|
E|-----------------|-------------------|-----------------|------------------|
```
Note how when the 8th fret note on the top string in bar 2 gets transposed to the 10th fret, extra '-' are added on the other strings below so as to retain the single '-' that originally separated that beat (i.e. column) from the following note – fret 7 on the B string.
Each beat must retain at least one '-' separator before the next, to keep the tab legible. The inputted test tabs all obey this convention.
Electric guitars usually have 22 frets, with the 0th fret being an open string. If your fret numbers transpose to either negative values or values over 22, you should return 'Out of frets!' (and probably detune your guitar).
Tests include some randomly generated guitar tabs, which come with no guarantee of musical quality and/or playability...!

def transpose(amount, tab):    
    resultTab = ['' for tabStr in tab]
    numChars = set(char for char in '0123456789')
    
    i = 0
    while i < len(tab[0]):
        for tabNum, tabStr in enumerate(tab):
            try:
                valStr = tabStr[i]
                
                # Are we looking at the second character of a two character number
                if not (i > 0 and valStr in numChars and tabStr[i-1] in numChars): 
                    
                    # If the next character is a number to complete a two character number
                    if valStr is not '-' and i+1 < len(tabStr) and tabStr[i+1] in numChars:
                        valStr += tabStr[i+1]

                    val = int(valStr)
                    transposedVal = val + amount

                    if transposedVal > 22 or transposedVal < 0:
                        return 'Out of frets!'

                    resultTab[tabNum] += str(transposedVal)
                    
            except ValueError:
                resultTab[tabNum] += tabStr[i]
                
        maxLineLength = max([len(s) for s in resultTab])
        minLineLength = min([len(s) for s in resultTab])

        shouldTrim = False
        if maxLineLength != minLineLength:
            # This happens if the input string had a two character number that went down to a one
            # character number after the transpose
            shouldTrim = all([ (len(s) == minLineLength or s[len(s)-1] == '-') for s in resultTab])
            if shouldTrim:
                i += 1
        
        
        for resTabNum, resTabStr in enumerate(resultTab):
            if shouldTrim:
                resultTab[resTabNum] = (resTabStr)[0:minLineLength]
            resultTab[resTabNum] = (resTabStr + '-')[0:maxLineLength]
            
        i += 1
    
    return resultTab


def transpose(amount, tab):    
    resultTab = ['' for tabStr in tab]
    numChars = set(char for char in '0123456789')
    
    i = 0
    while i < len(tab[0]):
        for tabNum, tabStr in enumerate(tab):
            try:
                valStr = tabStr[i]
                
                # Are we looking at the second character of a two character number
                if not (i > 0 and valStr in numChars and tabStr[i-1] in numChars): 
                    
                    # If the next character is a number to complete a two character number
                    if valStr is not '-' and i+1 < len(tabStr) and tabStr[i+1] in numChars:
                        valStr += tabStr[i+1]

                    val = int(valStr)
                    transposedVal = val + amount

                    if transposedVal > 22 or transposedVal < 0:
                        return 'Out of frets!'

                    resultTab[tabNum] += str(transposedVal)
                    
            except ValueError:
                resultTab[tabNum] += tabStr[i]
                
        maxLineLength = max([len(s) for s in resultTab])
        minLineLength = min([len(s) for s in resultTab])

        shouldTrim = False
        if maxLineLength != minLineLength:
            # This happens if the input string had a two character number that went down to a one
            # character number after the transpose
            shouldTrim = all([ (len(s) == minLineLength or s[len(s)-1] == '-') for s in resultTab])
            if shouldTrim:
                i += 1
        
        
        for resTabNum, resTabStr in enumerate(resultTab):
            if shouldTrim:
                resultTab[resTabNum] = (resTabStr)[0:minLineLength]
            resultTab[resTabNum] = (resTabStr + '-')[0:maxLineLength]
            
        i += 1
    
    return resultTab
