<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def from_shorthand(shorthand_string, slash=None):
 """Take a chord written in shorthand and return the notes in the chord. The function can recognize triads, sevenths, sixths, ninths, elevenths, thirteenths, slashed chords and a number of altered chords. The second argument should not be given and is only used for a recursive call when a slashed chord or polychord is found. See http://tinyurl.com/3hn6v8u for a nice overview of chord patterns. Examples: ['A', 'C', 'E'] ['A', 'C', 'E', 'G#'] ['A', 'C#', 'E'] ['G', 'A', 'C#', 'E'] ['G', 'B', 'D', 'F', 'A'] Recognised abbreviations: the letters "m" and "M" in the following abbreviations can always be substituted by respectively "min", "mi" or "-" and "maj" or "ma". Example: True Triads: 'm', 'M' or '', 'dim' Sevenths: 'm7', 'M7', '7', 'm7b5', 'dim7', 'm/M7' or 'mM7' Augmented chords: 'aug' or '+', '7#5' or 'M7+5', 'M7+', 'm7+', '7+' Suspended chords: 'sus4', 'sus2', 'sus47' or '7sus4', 'sus', '11', 'sus4b9' or 'susb9' Sixths: '6', 'm6', 'M6', '6/7' or '67', '6/9' or '69' Ninths: '9' or 'add9', 'M9', 'm9', '7b9', '7#9' Elevenths: '11' or 'add11', '7#11', 'm11' Thirteenths: '13' or 'add13', 'M13', 'm13' Altered chords: '7b5', '7b9', '7#9', '67' or '6/7' Special: '5', 'NC', 'hendrix' """

    # warning reduce??
    if type(shorthand_string) == list:
        res = []
        for x in shorthand_string:
            res.append(from_shorthand(x))
        return res
    if shorthand_string in ['NC', 'N.C.']:
        return []

    # Shrink shorthand_string to a format recognised by chord_shorthand
    shorthand_string = shorthand_string.replace('min', 'm')
    shorthand_string = shorthand_string.replace('mi', 'm')
    shorthand_string = shorthand_string.replace('-', 'm')
    shorthand_string = shorthand_string.replace('maj', 'M')
    shorthand_string = shorthand_string.replace('ma', 'M')

    # Get the note name
    if not notes.is_valid_note(shorthand_string[0]):
        raise NoteFormatError, "Unrecognised note '%s' in chord '%s'"\
             % (shorthand_string[0], shorthand_string)
    name = shorthand_string[0]

    # Look for accidentals
    for n in shorthand_string[1:]:
        if n == '#':
            name += n
        elif n == 'b':
            name += n
        else:
            break

    # Look for slashes and polychords '|'
    slash_index = -1
    s = 0
    rest_of_string = shorthand_string[len(name):]
    for n in rest_of_string:
        if n == '/':
            slash_index = s
        elif n == '|':
            # Generate polychord
            return from_shorthand(shorthand_string[:len(name) + s],
                    from_shorthand(shorthand_string[len(name) + s + 1:]))
        s += 1

    # Generate slash chord
    if slash_index != -1 and rest_of_string not in ['m/M7', '6/9', '6/7']:
        res = shorthand_string[:len(name) + slash_index]
        return from_shorthand(shorthand_string[:len(name) + slash_index],
                              shorthand_string[len(name) + slash_index + 1:])
    shorthand_start = len(name)

    short_chord = shorthand_string[shorthand_start:]
    if chord_shorthand.has_key(short_chord):
        res = chord_shorthand[short_chord](name)
        if slash != None:
            # Add slashed chords
            if type(slash) == str:
                if notes.is_valid_note(slash):
                    res = [slash] + res
                else:
                    raise NoteFormatError, \
                        "Unrecognised note '%s' in slash chord'%s'" % (slash,
                            slash + shorthand_string)
            elif type(slash) == list:
                # Add polychords
                r = slash
                for n in res:
                    if n != r[-1]:
                        r.append(n)
                return r
        return res
    else:
        raise FormatError, 'Unknown shorthand: %s' % shorthand_string