def run(command, inp):
    command = dynamic_cast(T_STRING, command).value
    args = map(T_STRING.create_from, inp)
    args = list(map(lambda v: v.value, args))

    print("Running '{}' with arguments {}".format(command, args))
    subprocess.call([command] + args)
def less_equals(i, inp):
    i = dynamic_cast(T_INT, i).value
    return inp <= i
def less_than(i, inp):
    i = dynamic_cast(T_INT, i).value
    return inp < i
def greater_equals(i, inp):
    i = dynamic_cast(T_INT, i).value
    return inp >= i
def greater_than(i, inp):
    i = dynamic_cast(T_INT, i).value
    return inp > i
def contains(substring, inp):
    substring = dynamic_cast(T_STRING, substring).value
    return substring in inp
def replace(old, new, inp):
    old = dynamic_cast(T_STRING, old)
    new = dynamic_cast(T_STRING, new)
    return inp.replace(old.value, new.value)
def take(count, inp):
    count = dynamic_cast(T_INT, count).value
    return inp[0:int(count)]
def add(num, inp):
    num = dynamic_cast(T_INT, num).value
    return inp - num
def has_ext(ext, inp):
    ext = dynamic_cast(T_STRING, ext).value
    (_, file_ext) = os.path.splitext(inp)
    file_ext = file_ext[1:]  # strip leading dot
    return file_ext == ext
def replace_ext(new_ext, inp):
    new_ext = dynamic_cast(T_STRING, new_ext).value
    (base, ext) = os.path.splitext(inp)
    if ext != "":
        return base + "." + new_ext
    return inp
def index(idx, inp):
    idx = dynamic_cast(T_INT, idx).value
    try:
        return T_STRING.create_from(inp[idx]).value
    except IndexError:
        panic("array index out of range")
def join(separator, inp):
    separator = dynamic_cast(T_STRING, separator).value
    vals = map(lambda x: T_STRING.create_from(x).value, inp)
    return separator.join(vals)
def split(separator, inp):
    separator = dynamic_cast(T_STRING, separator)
    return map(add_dynamic_type, inp.split(separator.value))
def starts_with(pattern, inp):
    pattern = dynamic_cast(T_STRING, pattern).value
    return inp.startswith(pattern)
def append(suffix, inp):
    return inp + dynamic_cast(T_STRING, suffix).value
def prepend(prefix, inp):
    return dynamic_cast(T_STRING, prefix).value + inp
def mul(num, inp):
    num = dynamic_cast(T_INT, num).value
    return inp * num
def drop(count, inp):
    count = dynamic_cast(T_INT, count).value
    return inp[int(count):]
def substr(start, end, inp):
    start = dynamic_cast(T_INT, start).value
    end = dynamic_cast(T_INT, end).value
    return inp[start:end]