def article(work, volume, article_):
    return {'work': work, 'volume': int(volume), 'article': int(article_)}

def paragraph(work, volume, article_, paragraph_):
    return {'work': work,
            'volume': int(volume),
            'article': int(article_),
            'paragraph': int(paragraph_)}

def uid(text):
    result = "{work}_{volume}_{article}".format(**text)
    if 'paragraph' in text:
        result = f"{result}_{text['paragraph']}"
    return result

def fromUID(uid_):
    components = uid_.split('_')
    if len(components) == 3:
        return article(*components)
    elif len(components) == 4:
        return paragraph(*components)
    else:
        print(f"'{uid}' doesn't represent a valid text UID")

def relativePath(text, extension):
    result = "{work}/T{volume}/{article}".format(**text)
    if 'paragraph' in text:
        result = f"{result}/{text['paragraph']}"
    return f"{result}.{extension}"

def toKey(text):
    result = (text['work'], text['volume'], text['article'])
    if 'paragraph' in text:
        result = result + (text['paragraph'],)
    return result

def fromKey(key):
    if len(key) == 3:
        return article(*key)
    elif len(key) == 4:
        return paragraph(*key)
    else:
        print(f"{key} isn't a valid text key")