# Bei Eingabe der Zahl 1 soll "I" ausgegeben werden
# Bei Eingabe der Zahl 2 soll "II" ausgegeben werden
# Bei Eingabe der Zahl 3 soll "III" ausgegeben werden
# Bei Eingabe der Zahl 4 soll "IV" ausgegeben werden
# Bei Eingabe der Zahl 5 soll "V" ausgegeben werden
# Bei Eingabe der Zahl 9 soll "IX" ausgegeben werden
# Bei Eingabe der Zahl 10 soll "X" ausgegeben werden
# Bei Eingabe der Zahl 21 soll "XXI" ausgegeben werden
# Bei Eingabe der Zahl 50 soll "L" ausgegeben werden
# Bei Eingabe der Zahl 100 soll "C" ausgegeben werden
# Bei Eingabe der Zahl 500 soll "D" ausgegeben werden
# Bei Eingabe der Zahl 1000 soll "M" ausgegeben werden
# Bei Eingabe der Zahl 1111 soll "MCXI" ausgegeben werden
# Bei Eingabe der Zahl 99 soll "XCIX" ausgegeben werden
# Bei Eingabe der Zahl 0 soll "Es gibt keine römische Null" ausgegeben werden
# Bei Eingabe der Zahl 40 soll "XL" ausgegeben werden
# Bei Eingabe eines Strings soll "Bitte ganze Zahlen eingeben" ausgegeben werden -> geändert aufgrund der Aufgabenstellung
# Bei Eingabe von Float-Werten (z.B. 4,3) soll "Bitte ganze Zahlen eingeben" ausgegeben werden.
# Bei Eingabe von negativen Werten (z.B. -5) soll "Es sind nur positive Zahlen zum konvertieren erlaubt" ausgegeben werden

import unittest
from abc import ABC, abstractmethod

class IConverter(ABC):
    @abstractmethod
    def convert(self, num: int) -> str:
        pass

class Converter(IConverter):
    def convert(self, num: int) -> str:
        roman_numbers = [(1000, 'M'), (500, 'D'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
        
        roman_str = ''

        '''Wenn eine 0 eingegeben wird muss eine Exception folgen'''
        if num == 0:
            return "Es gibt keine römische Null"
        

        if isinstance(num, int):
            if num < 0:
                return "Es sind nur positive Zahlen zum konvertieren erlaubt"
            
            for value, numeral in roman_numbers:

                while num >= value:
                    roman_str += numeral
                    num -= value

            return roman_str
        else: 
            return "Bitte ganze Zahlen eingeben"


class TestConverter(unittest.TestCase):
    def setUp(self):
        self.c = Converter()

    def test_convertOne(self):
        res = self.c.convert(1)
        self.assertEqual(res, 'I')
    
    def test_convertTwo(self):
        res = self.c.convert(2)
        self.assertEqual(res, 'II')
    
    def test_convertThree(self):
        res = self.c.convert(3)
        self.assertEqual(res, 'III')

    def test_convertFour(self):
        res = self.c.convert(4)
        self.assertEqual(res, 'IV')

    def test_convertFive(self):
        res = self.c.convert(5)
        self.assertEqual(res, 'V')

    def test_convertNine(self):
        res = self.c.convert(9)
        self.assertEqual(res, 'IX')

    def test_convertTen(self):
        res = self.c.convert(10)
        self.assertEqual(res, 'X')

    def test_convertTwentyTwo(self):
        res = self.c.convert(21)
        self.assertEqual(res, 'XXI')

    def test_convertFifty(self):
        res = self.c.convert(50)
        self.assertEqual(res, 'L')

    def test_convertHundred(self):
        res = self.c.convert(100)
        self.assertEqual(res, 'C')

    def test_convertFiveHundred(self):
        res = self.c.convert(500)
        self.assertEqual(res, 'D')

    def test_convertThousand(self):
        res = self.c.convert(1000)
        self.assertEqual(res, 'M')
    
    def test_convertFourDigit(self):
        res = self.c.convert(1111)
        self.assertEqual(res, 'MCXI')

    def test_convertNintyNine(self):
        res = self.c.convert(99)
        self.assertEqual(res, 'XCIX')

    def test_convertZero(self):
        res = self.c.convert(0)
        self.assertEqual(res, 'Es gibt keine römische Null')

    def test_convertFourty(self):
        res = self.c.convert(40)
        self.assertEqual(res, 'XL')

    def test_convertString(self):
        res = self.c.convert('HUIHIN')
        self.assertEqual(res, "Bitte ganze Zahlen eingeben")

    def test_convertFloat(self):
        res = self.c.convert(4.3)
        self.assertEqual(res, "Bitte ganze Zahlen eingeben")

if __name__ == "__main__":
    unittest.main()