import itertools
import string
from collections.abc import Generator, Iterable






def __lowerCAmelCase			(							UpperCamelCase__    ,  UpperCamelCase__    )     ->   Generator[tuple[str, ...], None, None]:
    __lowerCamelCase          =  iter(__lowerCAmelCase    )
    while True:
        __lowerCamelCase          =  tuple(itertools.islice(__lowerCAmelCase    ,  __lowerCAmelCase    )    )
        if not chunk:
            return
        yield chunk






def __lowerCAmelCase			(							UpperCamelCase__    )     ->   str:
    __lowerCamelCase          =  ''''''.join([c.upper() for c in dirty if c in string.ascii_letters]    )
    __lowerCamelCase          =  ''''''

    if len(__lowerCAmelCase    ) < 2:
        return dirty

    for i in range(len(__lowerCAmelCase    ) - 1    ):
        clean += dirty[i]

        if dirty[i] == dirty[i + 1]:
            clean += "X"

    clean += dirty[-1]

    if len(__lowerCAmelCase    ) & 1:
        clean += "X"

    return clean






def __lowerCAmelCase			(							UpperCamelCase__    )     ->   list[str]:
    __lowerCamelCase          =  '''ABCDEFGHIKLMNOPQRSTUVWXYZ'''
    # we're using a list instead of a '2d' array because it makes the math
    # for setting up the table and doing the actual encoding/decoding simpler
    __lowerCamelCase          =  []

    # copy key chars into the table if they are in `alphabet` ignoring duplicates
    for char in key.upper():
        if char not in table and char in alphabet:
            table.append(__lowerCAmelCase    )

    # fill the rest of the table in with the remaining alphabet chars
    for char in alphabet:
        if char not in table:
            table.append(__lowerCAmelCase    )

    return table






def __lowerCAmelCase			(							UpperCamelCase__    ,  UpperCamelCase__    )     ->   str:
    __lowerCamelCase          =  generate_table(__lowerCAmelCase    )
    __lowerCamelCase          =  prepare_input(__lowerCAmelCase    )
    __lowerCamelCase          =  ''''''

    # https://en.wikipedia.org/wiki/Playfair_cipher#Description
    for chara, chara in chunker(__lowerCAmelCase    ,  2    ):
        __lowerCamelCase          =  divmod(table.index(__lowerCAmelCase    )    ,  5    )
        __lowerCamelCase          =  divmod(table.index(__lowerCAmelCase    )    ,  5    )

        if rowa == rowa:
            ciphertext += table[rowa * 5 + (cola + 1) % 5]
            ciphertext += table[rowa * 5 + (cola + 1) % 5]
        elif cola == cola:
            ciphertext += table[((rowa + 1) % 5) * 5 + cola]
            ciphertext += table[((rowa + 1) % 5) * 5 + cola]
        else:  # rectangle
            ciphertext += table[rowa * 5 + cola]
            ciphertext += table[rowa * 5 + cola]

    return ciphertext






def __lowerCAmelCase			(							UpperCamelCase__    ,  UpperCamelCase__    )     ->   str:
    __lowerCamelCase          =  generate_table(__lowerCAmelCase    )
    __lowerCamelCase          =  ''''''

    # https://en.wikipedia.org/wiki/Playfair_cipher#Description
    for chara, chara in chunker(__lowerCAmelCase    ,  2    ):
        __lowerCamelCase          =  divmod(table.index(__lowerCAmelCase    )    ,  5    )
        __lowerCamelCase          =  divmod(table.index(__lowerCAmelCase    )    ,  5    )

        if rowa == rowa:
            plaintext += table[rowa * 5 + (cola - 1) % 5]
            plaintext += table[rowa * 5 + (cola - 1) % 5]
        elif cola == cola:
            plaintext += table[((rowa - 1) % 5) * 5 + cola]
            plaintext += table[((rowa - 1) % 5) * 5 + cola]
        else:  # rectangle
            plaintext += table[rowa * 5 + cola]
            plaintext += table[rowa * 5 + cola]

    return plaintext

'''simple docstring'''




def __lowerCAmelCase			(							UpperCamelCase__    ,  UpperCamelCase__    ,  UpperCamelCase__    )     ->   float:
    if principal <= 0:
        raise Exception('''Principal borrowed must be > 0'''    )
    if rate_per_annum < 0:
        raise Exception('''Rate of interest must be >= 0'''    )
    if years_to_repay <= 0 or not isinstance(UpperCamelCase__    ,  UpperCamelCase__    ):
        raise Exception('''Years to repay must be an integer > 0'''    )

    # Yearly rate is divided by 12 to get monthly rate
    __lowerCamelCase          =  rate_per_annum / 12

    # Years to repay is multiplied by 12 to get number of payments as payment is monthly
    __lowerCamelCase          =  years_to_repay * 12

    return (
        principal
        * rate_per_month
        * (1 + rate_per_month) ** number_of_payments
        / ((1 + rate_per_month) ** number_of_payments - 1)
    )


if __name__ == "__main__":
  import doctest

  doctest.testmod()
