From 6e3a084a5e0ae8f4de11c13be9307d543dc13b31 Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Fri, 21 Mar 2025 16:46:19 +0100 Subject: [PATCH 1/3] Roman Numerals Test Scenarios List A List of test scenarios --- src/{romannumerlas.py => interfaces.py} | 0 src/romannumerals.py | 0 tests/test_romannumerals.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/{romannumerlas.py => interfaces.py} (100%) create mode 100644 src/romannumerals.py create mode 100644 tests/test_romannumerals.py diff --git a/src/romannumerlas.py b/src/interfaces.py similarity index 100% rename from src/romannumerlas.py rename to src/interfaces.py diff --git a/src/romannumerals.py b/src/romannumerals.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_romannumerals.py b/tests/test_romannumerals.py new file mode 100644 index 0000000..e69de29 -- GitLab From 401661ef32cee29570b691053918f8279456a687 Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Fri, 21 Mar 2025 22:13:19 +0100 Subject: [PATCH 2/3] Romannumerals Interface and Test --- src/interfaces.py | 6 ++ src/romannumerals.py | 23 ++++++++ tests/test_romannumerals.py | 108 ++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/src/interfaces.py b/src/interfaces.py index e69de29..fc64573 100644 --- a/src/interfaces.py +++ 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 index e69de29..3f3eaf1 100644 --- a/src/romannumerals.py +++ 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/tests/test_romannumerals.py b/tests/test_romannumerals.py index e69de29..9a774cc 100644 --- a/tests/test_romannumerals.py +++ 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 -- GitLab From 23a0c648d7998e0a716a38ab4d5190a3ab88f7c1 Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Fri, 21 Mar 2025 22:18:41 +0100 Subject: [PATCH 3/3] Change environment --- .idea/.gitignore | 3 +++ .idea/PraxisprojektModernDev.iml | 10 +++++++++ .idea/inspectionProfiles/Project_Default.xml | 20 ++++++++++++++++++ .../inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 +++++++ .idea/vcs.xml | 6 ++++++ src/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 142 bytes src/__pycache__/interfaces.cpython-310.pyc | Bin 0 -> 505 bytes src/__pycache__/romannumerals.cpython-310.pyc | Bin 0 -> 894 bytes .../test_romannumerals.cpython-310.pyc | Bin 0 -> 2632 bytes 11 files changed, 57 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/PraxisprojektModernDev.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 src/__pycache__/__init__.cpython-310.pyc create mode 100644 src/__pycache__/interfaces.cpython-310.pyc create mode 100644 src/__pycache__/romannumerals.cpython-310.pyc create mode 100644 tests/__pycache__/test_romannumerals.cpython-310.pyc diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /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 0000000..0065e62 --- /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 0000000..ea35d86 --- /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 0000000..105ce2d --- /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 0000000..b907810 --- /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 0000000..8483bb3 --- /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 0000000..35eb1dd --- /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 GIT binary patch literal 142 zcmd1j<>g`kf(cjdri19mAOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUS;XRDatlG2pS z(%hJUqQr{K;)0_5tkmoh-~5!+qCA(>vY6tc<e2#Q%)HE!_;|g7%3B;Zx%nxjIjMFa Lql%e;1PcQIlj9)p literal 0 HcmV?d00001 diff --git a/src/__pycache__/interfaces.cpython-310.pyc b/src/__pycache__/interfaces.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95e7981751754055c5e10944cc00468b50941e10 GIT binary patch literal 505 zcmY*Vy-ou$49?FL9Tlw@kl+DWx^!Vf2o;Ki7&sxiolc6<OA3X{r6hNVGSa>b55y9Q ziHTQW!oI4aSh8cspY6}Kolcv8%s)Qw-r)VhU{fLp2B7{Bj3SB_#L$!)mNH5%iDHT` ziQ<|rc*<2YBE8l(AW4q}es(?#T{-rZlX+!yb#GOUxlQ2^3_$$>7)?^DNXj%<RIw#l z&@@sUdPbppb!&|*liFw}3!gK9uLXSyIt2AdSP`h9$vd)$ye=kzm$h*%NHyl?Xn35B zs#;BJlifJ^GW9cOAM|5&ZIyQAg?`Sw%d=@&X*ZF%_WjvB#FZ5eN#F>NLnHRO|DRWX zjY)c~5DQUCqlE}<A&gaZf&PvVPqi#o8HfA3?KQDKiY~@KoP-F!1tunpc4_mMz(u$m d=MGt{dLVS8yxA3dg!p7N`V>#poM)Hpv0o*tY}5b% literal 0 HcmV?d00001 diff --git a/src/__pycache__/romannumerals.cpython-310.pyc b/src/__pycache__/romannumerals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6197cf9b2af49383222064fa3d7a160c943eea6 GIT binary patch literal 894 zcmY+CPiqrF7{=$%ZkmRqDnt*0uxbVO5~zY25fRcN0UN|ZDNAHoGt*@4?rb}=TW#2Y zn0^31f_U=-c^UB3i@kgDAinR$LORR5^P6X8o_Tj>vR11>pq%{pIX+{AoMC6VIM8_k z)p!sD5i}tw4JaiqiC}`C62T>%^MDCwhxqO}%pyLuYyCG_8mU2%N*yI;gz|EMtroUz z07(KW2v|_TPD#K82P?<6E?eM|i&6vNP<v3#1VT<qn$tNmt2x-r>1SGk*#R}zpyday zz7D#B`j`m!8=WyxoAHuulDF+4n>jPLq@@G%HcDQ)j|q%H{|T9a59;RL(XA5GS{Y1l zZ^ddHy^~&A7~{!UNpBpfsq}(ql6VFLO(CWD>lH$#>y=o|oPLPSXd;!j;T1}F54+v2 zm&9@`mEZDN{0n}_(rutqB-TUx4NjJB0)0VZJ-~AT?w0m|0wlJF_@EMB0o`ASh<LY_ z?g6b<Vjt11#9bh~T+8~1n6agOOMGq{v5A$*BQ=ti$11mt-6$#Kme!f}Yt}I`*$=oX zQp=B{#MZPlMUq<=I)w~YU;r=uJJEN*^v|Q-)8S5Dh`30HuXXe>HitTUFAwtVOh~OZ z<?+zy(NN=i`M=b34o_@7&%#Q?e9cV=4O*vHq1KtR(!>_OzwDF4r#CLWmCnV|0X(C6 z7^*0hVQ3p+m}a6#kegw6R7A;QM6ZK;mF-fviyGVn!Ba9A>ZD04W#IE*4U+D_;Yht7 ejik}|JgdPa3;chLKDPdBvGa30=gO=}+Wa5JLfq#7 literal 0 HcmV?d00001 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 GIT binary patch literal 2632 zcmcguPjB2r6rZuZyWWjAX(_an{y|hAx+(;MfCJDf;8bW)yedsuj1|dpc1$$s{t07m zXrr7+IMYu6$uZx612;Yc7fYNt6pI_-#3lTm-N5c<m%Sjynm2FW%zHEM_ukC7SFKhU z%EO<2UjO|ZW4};muo&npqDHqs1QWc?JZiNz?`WRJ*@sN%!q{WN2-$|dt9wRR5QY1i zx)QSe;sN8(S;=axn8F5Y)Ob?8+v^0~M!yrPpdGbHJXkbz7Ez-mkdS#?Fi#U)XnV}l z^W{846hsmIf+z_SZBdj(1#L;p2n($#s$v#xS<J1l+L`3+y)cT0m*ud2Qi!KzZPdsD ziP<jOVLq0II&ai8MZ-zC)$4ABDh|~lPmCyRe}2eR2_t{rwBK1>iTgtKJF9n8@IXeJ zs<#o|kDZ<fRd*@eT8*)VD5Jh20J={AnBRPu6rwQxWOIR*r-dxOec{xO=d(Gj(R~*% zpZ0z92xN!tqi*nh0CoV#4iKXOnGTsTA}c^v9FdhEGe=})$SNbU8OW>=SrxKbl4aP< zHB#De!s{t*G~vyZQZC_c`bO3+ry^@@`3EK@d`bSQQ|lb+$xIMMK>PL={h+NV7ZWq? z<=`o@mO-BrlSa=G#Qw<?e=Ue)>rD(C&4N75|M{Nf+b^BQcZ~LAw0B@~0NMW)?F`v! zBPB>Yt=>$_Ipe0+Gsay`y_~V-BcSSO_LAHKtY92<0YhWqyEqI$)L)BL(28ZRdlM>0 zbS{P<yfF>J0Sgm>RF`4424^Vm;Y>ZnK5@|N;EI{3Sx+gtp3x-P)oj#t-Skc-Tn0PY zrSros1wu&j=QdQ;HIVJ=(|kBlnd|`Na}9Y;N#^M;!hx$a<J|NLafa*G-Sm~5UB-AT zXYINxf1vOb?Ijm-`Itgfv>g{ClYJV=@{W8E3I`U|C6MWPoz0)<O>_@N{_DKX^0nNM z6k1Pn>hee2nO?=Q9f}^pDj$=e<TyYIz3=AGD?1J*{5uqvhQr$q)OzUSUR?`S)Py4u zB~G5RIP$Mfi}jHHDTv6HO-4UL%m|_whyI&cx?nf7eVr~`&OXJpXW-k_IqRAWEIR)s zr1X7;Iz~$ytF<si3m5sAwU(!78Dq89r)aUUT3?OTn)@3KJS)RHq$B_y-wx_!iBW7Q z0Ls#16uFPkC;Iyz*z3=K{oBXiUo9`zjKs>{fxCf>!YHXUgLXf>tyE8CkAk`g?Xefy zGsEd2yIVn9idBl?iy#)C<(H2wZ8E)fy#4aDq<LbsQL7}T?{|Yv==({<_d7k&Zxe6% zK0RRhh@z`nJxAmPA~hnf5qX`+TSVxGVt`QIDV!WeGomvfCNsIIn`M(q*(zqEw0b9y zUEi;jJhR`GF?sKujZ|xX=zk;sl`+XLJHY!&rq$aZi9z}UD`y*_<rDM0+?`t#sq7EQ PykYUDbn{({8^?bEe*s~n literal 0 HcmV?d00001 -- GitLab