diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/PraxisprojektModernDev.iml b/.idea/PraxisprojektModernDev.iml new file mode 100644 index 0000000000000000000000000000000000000000..0065e628be1ecb98edd03e0933b7ba67b9665271 --- /dev/null +++ b/.idea/PraxisprojektModernDev.iml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="PYTHON_MODULE" version="4"> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/ModernDev" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..ea35d863fafb149a54df9e5426144f5c32d5793c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,20 @@ +<component name="InspectionProjectProfileManager"> + <profile version="1.0"> + <option name="myName" value="Project Default" /> + <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="ignoredPackages"> + <value> + <list size="7"> + <item index="0" class="java.lang.String" itemvalue="pypdf2" /> + <item index="1" class="java.lang.String" itemvalue="future" /> + <item index="2" class="java.lang.String" itemvalue="tk" /> + <item index="3" class="java.lang.String" itemvalue="pytesseract" /> + <item index="4" class="java.lang.String" itemvalue="DateTime" /> + <item index="5" class="java.lang.String" itemvalue="bcrypt" /> + <item index="6" class="java.lang.String" itemvalue="Pillow" /> + </list> + </value> + </option> + </inspection_tool> + </profile> +</component> \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..105ce2da2d6447d11dfe32bfb846c3d5b199fc99 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ +<component name="InspectionProjectProfileManager"> + <settings> + <option name="USE_PROJECT_PROFILE" value="false" /> + <version value="1.0" /> + </settings> +</component> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..b90781060a784d8ff4d501d3b91a20ecd9ebe680 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (PraxisprojektModernDev)" project-jdk-type="Python SDK" /> +</project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..8483bb34f8e9b6e9d1d75271aa056d56aa879f0f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/PraxisprojektModernDev.iml" filepath="$PROJECT_DIR$/.idea/PraxisprojektModernDev.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/src/__pycache__/__init__.cpython-310.pyc b/src/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4155c6cc3f22b5cdf03255ec978f442867072db Binary files /dev/null and b/src/__pycache__/__init__.cpython-310.pyc differ diff --git a/src/__pycache__/interfaces.cpython-310.pyc b/src/__pycache__/interfaces.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95e7981751754055c5e10944cc00468b50941e10 Binary files /dev/null and b/src/__pycache__/interfaces.cpython-310.pyc differ diff --git a/src/__pycache__/romannumerals.cpython-310.pyc b/src/__pycache__/romannumerals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6197cf9b2af49383222064fa3d7a160c943eea6 Binary files /dev/null and b/src/__pycache__/romannumerals.cpython-310.pyc differ diff --git a/src/interfaces.py b/src/interfaces.py new file mode 100644 index 0000000000000000000000000000000000000000..fc645736ebe7edf2091db66c3738825f50fd923f --- /dev/null +++ b/src/interfaces.py @@ -0,0 +1,6 @@ +from abc import ABC, abstractmethod + +class IRomanNumerals(ABC): + @abstractmethod + def to_roman(self, num): + pass \ No newline at end of file diff --git a/src/romannumerals.py b/src/romannumerals.py new file mode 100644 index 0000000000000000000000000000000000000000..3f3eaf1e8e956ca023c64ae71e38caefb1198940 --- /dev/null +++ b/src/romannumerals.py @@ -0,0 +1,23 @@ +from src.interfaces import IRomanNumerals + + +class RomanNumerals(IRomanNumerals): + def to_roman(self, num): + if not isinstance(num, int): + raise ValueError("Eingabe muss eine ganze Zahl sein") + if num <= 0 or num >= 4000: + raise ValueError("Zahl muss zwischen 1 und 3999 liegen") + + val = [ + (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), + (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), + (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), + (1, "I") + ] + + result = "" + for (value, numeral) in val: + while num >= value: + result += numeral + num -= value + return result \ No newline at end of file diff --git a/src/romannumerlas.py b/src/romannumerlas.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tests/__pycache__/test_romannumerals.cpython-310.pyc b/tests/__pycache__/test_romannumerals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e14f2572a91805d1b33f9c03c0890bd6a036010c Binary files /dev/null and b/tests/__pycache__/test_romannumerals.cpython-310.pyc differ diff --git a/tests/test_romannumerals.py b/tests/test_romannumerals.py new file mode 100644 index 0000000000000000000000000000000000000000..9a774cc92787102f3ef685b0c6a80138e5bbcedf --- /dev/null +++ b/tests/test_romannumerals.py @@ -0,0 +1,108 @@ +# Basisfälle +# Bei Eingabe der Zahl 1, erhalte ich das Ergebnis I +# Bei Eingabe der Zahl 5, erhalte ich das Ergebnis V +# Bei Eingabe der Zahl 10, erhalte ich das Ergebnis X +# Bei Eingabe der Zahl 50, erhalte ich das Ergebnis L +# Bei Eingabe der Zahl 100, erhalte ich das Ergebnis C +# Bei Eingabe der Zahl 500, erhalte ich das Ergebnis D +# Bei Eingabe der Zahl 1000, erhalte ich das Ergebnis M +# Substraktionsregel +# Bei Eingabe der Zahl 4, erhalte ich das Ergebnis IV +# Bei Eingabe der Zahl 9, erhalte ich das Ergebnis IX +# Bei Eingabe der Zahl 40, erhalte ich das Ergebnis XL +# Bei Eingabe der Zahl 90, erhalte ich das Ergebnis XC +# Bei Eingabe der Zahl 400, erhalte ich das Ergebnis CD +# Bei Eingabe der Zahl 900, erhalte ich das Ergebnis CM +# Additionsregel +# Bei Eingabe der Zahl 2 erhalte ich das Ergebnis "II" +# Bei Eingabe der Zahl 3 erhalte ich das Ergebnis "III" +# Bei Eingabe der Zahl 6 erhalte ich das Ergebnis "VI" +# Bei Eingabe der Zahl 8 erhalte ich das Ergebnis "VIII" +# Bei Eingabe der Zahl 30 erhalte ich das Ergebnis "XXX" +# Bei Eingabe der Zahl 80 erhalte ich das Ergebnis "LXXX" +# Kombination aus Addition und Subtraktion +# Bei Eingabe der Zahl 14 erhalte ich das Ergebnis "XIV" +# Bei Eingabe der Zahl 19 erhalte ich das Ergebnis "XIX" +# Bei Eingabe der Zahl 29 erhalte ich das Ergebnis "XXIX" +# Bei Eingabe der Zahl 44 erhalte ich das Ergebnis "XLIV" +# Bei Eingabe der Zahl 99 erhalte ich das Ergebnis "XCIX" +# Bei Eingabe der Zahl 444 erhalte ich das Ergebnis "CDXLIV" +# Bei Eingabe der Zahl 999 erhalte ich das Ergebnis "CMXCIX" +# Größere Zahlen +# Bei Eingabe der Zahl 1001 erhalte ich das Ergebnis "MI" +# Bei Eingabe der Zahl 1987 erhalte ich das Ergebnis "MCMLXXXVII" +# Bei Eingabe der Zahl 2023 erhalte ich das Ergebnis "MMXXIII" +# Bei Eingabe der Zahl 3999 erhalte ich das Ergebnis "MMMCMXCIX" +# Fehlerfälle +# Bei Eingabe der Zahl 0 erhalte ich eine Fehlermeldung +# Bei Eingabe der Zahl -1 erhalte ich eine Fehlermeldung +# Bei Eingabe der Zahl 4000 erhalte ich eine Fehlermeldung +# Bei Eingabe der Zeichenfolge "ABC" erhalte ich eine Fehlermeldung +# Bei Eingabe von None erhalte ich eine Fehlermeldung +# Bei Eingabe der Zahl 3.14 erhalte ich eine Fehlermeldung + +import unittest +from src.romannumerals import RomanNumerals + + +class TestRomanNumerals(unittest.TestCase): + def setUp(self): + self.converter = RomanNumerals() + + def test_to_roman_basic(self): + self.assertEqual(self.converter.to_roman(1), "I") + self.assertEqual(self.converter.to_roman(5), "V") + self.assertEqual(self.converter.to_roman(10), "X") + self.assertEqual(self.converter.to_roman(50), "L") + self.assertEqual(self.converter.to_roman(100), "C") + self.assertEqual(self.converter.to_roman(500), "D") + self.assertEqual(self.converter.to_roman(1000), "M") + + def test_to_roman_subtraction(self): + self.assertEqual(self.converter.to_roman(4), "IV") + self.assertEqual(self.converter.to_roman(9), "IX") + self.assertEqual(self.converter.to_roman(40), "XL") + self.assertEqual(self.converter.to_roman(90), "XC") + self.assertEqual(self.converter.to_roman(400), "CD") + self.assertEqual(self.converter.to_roman(900), "CM") + + def test_to_roman_addition(self): + self.assertEqual(self.converter.to_roman(2), "II") + self.assertEqual(self.converter.to_roman(3), "III") + self.assertEqual(self.converter.to_roman(6), "VI") + self.assertEqual(self.converter.to_roman(8), "VIII") + self.assertEqual(self.converter.to_roman(30), "XXX") + self.assertEqual(self.converter.to_roman(80), "LXXX") + + def test_to_roman_mixed(self): + self.assertEqual(self.converter.to_roman(14), "XIV") + self.assertEqual(self.converter.to_roman(19), "XIX") + self.assertEqual(self.converter.to_roman(29), "XXIX") + self.assertEqual(self.converter.to_roman(44), "XLIV") + self.assertEqual(self.converter.to_roman(99), "XCIX") + self.assertEqual(self.converter.to_roman(444), "CDXLIV") + self.assertEqual(self.converter.to_roman(999), "CMXCIX") + + def test_to_roman_large_numbers(self): + self.assertEqual(self.converter.to_roman(1001), "MI") + self.assertEqual(self.converter.to_roman(1987), "MCMLXXXVII") + self.assertEqual(self.converter.to_roman(2023), "MMXXIII") + self.assertEqual(self.converter.to_roman(3999), "MMMCMXCIX") + + def test_to_roman_invalid(self): + with self.assertRaises(ValueError): + self.converter.to_roman(0) + with self.assertRaises(ValueError): + self.converter.to_roman(-1) + with self.assertRaises(ValueError): + self.converter.to_roman(4000) + with self.assertRaises(ValueError): + self.converter.to_roman("ABC") + with self.assertRaises(ValueError): + self.converter.to_roman(None) + with self.assertRaises(ValueError): + self.converter.to_roman(3.14) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file