From 20df61969317fc83ba4ebcc35930a1a0a39acfcd Mon Sep 17 00:00:00 2001 From: sesufv Date: Sat, 4 Apr 2026 00:29:56 +0200 Subject: [PATCH] hotovson --- __pycache__/tasks.cpython-313.pyc | Bin 0 -> 3181 bytes .../tests.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 69116 bytes skj_class.xml | 1 + tasks.py | 67 ++++++++ tests.py | 151 ++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 __pycache__/tasks.cpython-313.pyc create mode 100644 __pycache__/tests.cpython-313-pytest-9.0.2.pyc create mode 100644 skj_class.xml create mode 100644 tasks.py create mode 100644 tests.py diff --git a/__pycache__/tasks.cpython-313.pyc b/__pycache__/tasks.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ad882ac29545615b64a8a92bcd009011ecd86d4 GIT binary patch literal 3181 zcmcJRPi)gx9LHZ`$4Q;GVRh&~5WKbFk4M{Zpb`|c%jlpjZBUK3X-uk2VoFM4SIp!;FCwhO zfDK42SWXIn4N4r?(5z1k{zgMgCEZB$8w(c$SLJ&!_mPaIeQ>jDNWNibRzT8 zxbWC>!8E9fj) zymK>?PTlNm>@RXw@M>C1DVdDL%&Ml<;%#C1M=x2tl)EyTQM2&y7GtQU$XcPrY-Wb& zx=HBYN@xbHu%_Oaadt5142EIFuEg8SKl)R>p>_wu_sY%m_OB3VqI*8NB_T4Tl`eR>HfTa1 zyQH1EwpU%fj74FRX3aPU1~L|UWyZ>_(L0Hi#QM2st+Ah4JGO%~X(1Gj7NY|tez3?6 zl06VBNvU!NeHi)}l|R5Vm7EVDIjqdSj%t8+BQ5e21hj~zJRk=eM)lGp`x|SK>_w6T z8BfjZlm}?aA@%m>@!5kH0{$gQ6olh4YLh7&RAOk5yd-5ooa}`HlNaGxy zQ&XCLO~8`K|RN}TTz>^El`%CO|ocF?}JX+2FbEV9k*P@lO>>)qdU)XVla0f9C=XsDvbc1(;5`K z;I%|b1U77F8?{1v`KVzd3uuZ!u@|J7_Gth9U%j!WgoLt6D8e^|2EJ2bs8$6w`h=Dt zq30t)4*{f`njSD>a92$b3U{p_tPpLEbPt36TXto*wGnn29$h5|V08d4V;M|Sby0pr zUG(-BW2Z{JBgNQ4H zQca?&L(W<565Lw>d&&ye%~c_%4V=(UPN-DdToMd-kC076_4z|*vU)0)QQszqV2P&I oh=F;@_i_@% literal 0 HcmV?d00001 diff --git a/__pycache__/tests.cpython-313-pytest-9.0.2.pyc b/__pycache__/tests.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5198ca45104f7433afbaca1990660c9ccfa689c GIT binary patch literal 69116 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 s((LaQsdl3IO5lz^Aa~tqt(GU`J3C&H444045504444321112323444412505542140252202231415 \ No newline at end of file diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..f5126a5 --- /dev/null +++ b/tasks.py @@ -0,0 +1,67 @@ +import xml.etree.ElementTree as ET + +def create_student(xml_root, student_id): + ''' + Vytvořte studenta dle loginu. + Ujistěte se, že student neexistuje, jinak: raise Exception('student already exists') + ''' + for student in xml_root.findall('student'): + if student.get('student_id')==student_id: + raise Exception('student already exists') + new_student = ET.SubElement(xml_root, "student") + new_student.set("student_id", student_id) + return new_student + +def remove_student(xml_root, student_id): + ''' + Odstraňte studenta dle loginu + ''' + for student in xml_root.findall('student'): + if student.get('student_id')==student_id: + xml_root.remove(student) + return + raise Exception('student does not exist') + + +def set_task_points(xml_root, student_id, task_id, points): + ''' + Přepište body danému studentovi u jednoho tasku + ''' + + for student in xml_root.findall('student'): + if student.get('student_id')==student_id: + + for task in student.findall('task'): + if task.get('task_id')==task_id: + task.text=str(points) + return + + + return + raise Exception('student does not exist') + + +def create_task(xml_root, student_id, task_id, points): + ''' + Pro daného studenta vytvořte task s body. + Ujistěte se, že task (s task_id) u studenta neexistuje, jinak: raise Exception('task already exists') + ''' + for student in xml_root.findall('student'): + if student.get('student_id')==student_id: + for task in student.findall('task'): + if task.get('task_id')==task_id: + raise Exception('task already exists') + new_task = ET.SubElement(student, 'task') + new_task.set('task_id', task_id) + new_task.text = str(points) + return + + +def remove_task(xml_root, task_id): + ''' + Napříč všemi studenty smažte task s daným task_id + ''' + for student in xml_root.findall('student'): + for task in student.findall('task'): + if task.get('task_id')==task_id: + student.remove(task) \ No newline at end of file diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..2184664 --- /dev/null +++ b/tests.py @@ -0,0 +1,151 @@ +import xml.etree.ElementTree as ET +import copy + +import pytest + +from tasks import create_student, remove_student, set_task_points, create_task, remove_task + +INPUT_XML = '444045504444321112323444412505542140252202231415' + + + +def test_create_student(): + root = ET.fromstring(INPUT_XML) + original_length = len([s.attrib['student_id'] for s in root]) + + create_student(root, "TST0000") + assert len([s.attrib['student_id'] for s in root]) == original_length+1 + assert "TST0000" in [s.attrib['student_id'] for s in root] + + with pytest.raises(Exception, match="^student already exists$"): + create_student(root, "ABC0123") + + + +def test_remove_student(): + root = ET.fromstring(INPUT_XML) + original_length = len([s.attrib['student_id'] for s in root]) + + remove_student(root, "ABC0123") + assert len([s.attrib['student_id'] for s in root]) == original_length-1 + assert "ABC0123" not in [s.attrib['student_id'] for s in root] + + + +def test_set_task_points(): + root = ET.fromstring(INPUT_XML) + assert int(root[0][0].text) == 4 + assert int(root[1][1].text) == 4 + assert int(root[2][2].text) == 3 + assert int(root[3][3].text) == 5 + assert int(root[4][4].text) == 2 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'ABC0123', '1', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 4 + assert int(root[2][2].text) == 3 + assert int(root[3][3].text) == 5 + assert int(root[4][4].text) == 2 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'DEF4567', '2', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 3 + assert int(root[3][3].text) == 5 + assert int(root[4][4].text) == 2 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'GHI8901', '3', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 5 + assert int(root[4][4].text) == 2 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'JKL2345', '4', '0') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 0 + assert int(root[4][4].text) == 2 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'MNO6789', '5', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 0 + assert int(root[4][4].text) == 5 + assert int(root[5][5].text) == 4 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'PQR0123', '6', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 0 + assert int(root[4][4].text) == 5 + assert int(root[5][5].text) == 5 + assert int(root[0][6].text) == 5 + assert int(root[1][7].text) == 1 + set_task_points(root, 'ABC0123', '7', '0') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 0 + assert int(root[4][4].text) == 5 + assert int(root[5][5].text) == 5 + assert int(root[0][6].text) == 0 + assert int(root[1][7].text) == 1 + set_task_points(root, 'DEF4567', '8', '5') + assert int(root[0][0].text) == 5 + assert int(root[1][1].text) == 5 + assert int(root[2][2].text) == 5 + assert int(root[3][3].text) == 0 + assert int(root[4][4].text) == 5 + assert int(root[5][5].text) == 5 + assert int(root[0][6].text) == 0 + assert int(root[1][7].text) == 5 + + + +def test_create_task(): + root = ET.fromstring(INPUT_XML) + + create_task(root, 'PQR0123', '9', '5') + assert len(root[5]) == 9 + assert root[5][-1].text == '5' + assert root[5][-1].attrib['task_id'] == '9' + + create_task(root, 'PQR0123', '10', '1') + assert len(root[5]) == 10 + assert root[5][-1].text == '1' + assert root[5][-1].attrib['task_id'] == '10' + + with pytest.raises(Exception, match="^task already exists$"): + create_task(root, 'PQR0123', '1', '50') + + + +def test_remove_task(): + root = ET.fromstring(INPUT_XML) + + assert int(root[0][2].attrib['task_id']) == 3 + remove_task(root, '3') + assert int(root[0][2].attrib['task_id']) == 4 + assert int(root[0][3].attrib['task_id']) == 5 + remove_task(root, '5') + assert int(root[0][3].attrib['task_id']) == 6 + assert int(root[0][0].attrib['task_id']) == 1 + remove_task(root, '1') + assert int(root[0][0].attrib['task_id']) == 2 + remove_task(root, '2') + assert int(root[0][0].attrib['task_id']) == 4 \ No newline at end of file