# Path: string_utils/manipulation.py
# def roman_encode(input_number: Union[str, int]) -> str:
#     """
#     Convert the given number/string into a roman number.
# 
#     The passed input must represents a positive integer in the range 1-3999 (inclusive).
# 
#     Why this limit? You may be wondering:
# 
#     1. zero is forbidden since there is no related representation in roman numbers
#     2. the upper bound 3999 is due to the limitation in the ascii charset\
#     (the higher quantity sign displayable in ascii is "M" which is equal to 1000, therefore based on\
#     roman numbers rules we can use 3 times M to reach 3000 but we can't go any further in thousands without\
#     special "boxed chars").
# 
#     *Examples:*
# 
#     >>> roman_encode(37) # returns 'XXXVIII'
#     >>> roman_encode('2020') # returns 'MMXX'
# 
#     :param input_number: An integer or a string to be converted.
#     :type input_number: Union[str, int]
#     :return: Roman number string.
#     """
#     return __RomanNumbers.encode(input_number)


import binascii
import os
import random
import string
from typing import Generator
from uuid import uuid4
from .manipulation import roman_encode
    >>> for n in roman_range(start=7, stop=1, step=-1): print(n)
    >>> # prints: VII, VI, V, IV, III, II, I

    :param stop: Number at which the generation must stop (must be <= 3999).
    :param start: Number at which the generation must start (must be >= 1).
    :param step: Increment of each generation step (default to 1).
    :return: Generator of roman numbers.
    """

    def validate(arg_value, arg_name, allow_negative=False):
        msg = '"{}" must be an integer in the range 1-3999'.format(arg_name)

        if not isinstance(arg_value, int):
            raise ValueError(msg)

        if allow_negative:
            arg_value = abs(arg_value)

        if arg_value < 1 or arg_value > 3999:
            raise ValueError(msg)

    def generate():
        current = start

        # generate values for each step
        while current != stop:
            yield roman_encode(current)
            current += step

        # last value to return

# Path: string_utils/manipulation.py
# def roman_encode(input_number: Union[str, int]) -> str:
#     """
#     Convert the given number/string into a roman number.
# 
#     The passed input must represents a positive integer in the range 1-3999 (inclusive).
# 
#     Why this limit? You may be wondering:
# 
#     1. zero is forbidden since there is no related representation in roman numbers
#     2. the upper bound 3999 is due to the limitation in the ascii charset\
#     (the higher quantity sign displayable in ascii is "M" which is equal to 1000, therefore based on\
#     roman numbers rules we can use 3 times M to reach 3000 but we can't go any further in thousands without\
#     special "boxed chars").
# 
#     *Examples:*
# 
#     >>> roman_encode(37) # returns 'XXXVIII'
#     >>> roman_encode('2020') # returns 'MMXX'
# 
#     :param input_number: An integer or a string to be converted.
#     :type input_number: Union[str, int]
#     :return: Roman number string.
#     """
#     return __RomanNumbers.encode(input_number)


# Path: string_utils/generation.py
import binascii
import os
import random
import string
from typing import Generator
from uuid import uuid4
from .manipulation import roman_encode

    >>> for n in roman_range(start=7, stop=1, step=-1): print(n)
    >>> # prints: VII, VI, V, IV, III, II, I

    :param stop: Number at which the generation must stop (must be <= 3999).
    :param start: Number at which the generation must start (must be >= 1).
    :param step: Increment of each generation step (default to 1).
    :return: Generator of roman numbers.
    """

    def validate(arg_value, arg_name, allow_negative=False):
        msg = '"{}" must be an integer in the range 1-3999'.format(arg_name)

        if not isinstance(arg_value, int):
            raise ValueError(msg)

        if allow_negative:
            arg_value = abs(arg_value)

        if arg_value < 1 or arg_value > 3999:
            raise ValueError(msg)

    def generate():
        current = start

        # generate values for each step
        while current != stop:
            yield roman_encode(current)
            current += step

        # last value to return

        yield roman_encode(current)