Skip to content

Commit b7b3280

Browse files
committed
calculate points
1 parent ad8ebc0 commit b7b3280

File tree

7 files changed

+203
-21
lines changed

7 files changed

+203
-21
lines changed

.github/workflows/pytest.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
name: Pytest
22

3-
on:
4-
push:
5-
branches: [ "main" ]
6-
pull_request:
7-
branches: [ "main" ]
3+
on: [push, pull_request]
84

95
permissions:
106
contents: read

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ CSV musí být ve formátu `kód;body`, tedy například `001234AA7;5`. Preferov
2323
oddělovačem je středník, lze ale použít libovolně i čárky, mezery nebo
2424
tabulátory. Uvozovky jsou ignorovány. Více oddělovačů za sebou je složených do
2525
jednoho.
26+
27+
### Testování
28+
Pro spuštění testů stačí spustit `pytest`. Pro vytvoření statistik o podchycení
29+
lze využít `coverage run -m pytest` a následně `coverage report` pro vypsání
30+
nebo `coverage html` pro vygenerování html.

src/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import json
99
import glob
1010

11+
from src.teams import getTeamPoints
12+
1113
from .lines import parseFile
1214

1315
TEAM_JSON = 'teams.json'
@@ -57,9 +59,13 @@ def process():
5759
print("No input files found")
5860
sys.exit()
5961

60-
tasks = {}
62+
teamTasks = {}
6163
for inputFile in inputFiles:
62-
parseFile(inputFile, tasks)
64+
parseFile(inputFile, teamTasks)
65+
print(teamTasks)
66+
67+
teamPoints = getTeamPoints(teamTasks)
68+
print(teamPoints)
6369

6470

6571
def main():

src/lines.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
22

3+
from .teams import appendTeamsData
34
from .code import extractCodeData
45

56

@@ -26,15 +27,13 @@ def splitLine(line: str):
2627
def extractLineData(line: str):
2728
line = line.strip()
2829
split = splitLine(line)
29-
if split is None:
30-
return None
3130
(code, points) = split
32-
print(f"Code: {code}")
33-
print(f"Points: {points}")
34-
extractCodeData(code)
31+
(teamId, task) = extractCodeData(code)
32+
return (teamId, task, int(points))
3533

3634

37-
def parseFile(inputFile, tasks):
35+
def parseFile(inputFile: str, teamTasks: dict):
3836
with open(inputFile, 'r') as file:
3937
for line in file:
40-
extractLineData(line)
38+
(teamId, task, points) = extractLineData(line)
39+
appendTeamsData(teamId, task, points, teamTasks)

src/lines_test.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
from src.lines import splitLine
1+
from src.lines import extractLineData, splitLine
22

33

44
def test_split():
55
assert splitLine('1234AA1;5') == ('1234AA1', '5')
6-
assert splitLine('1234AA1,5') == ('1234AA1', '5')
7-
assert splitLine('1234AA1 5') == ('1234AA1', '5')
8-
assert splitLine('1234AA1\t5') == ('1234AA1', '5')
6+
assert splitLine('1234AA1,3') == ('1234AA1', '3')
7+
assert splitLine('1234AA1 2') == ('1234AA1', '2')
8+
assert splitLine('1234AA1\t1') == ('1234AA1', '1')
99

1010

1111
def test_split_multiple():
1212
assert splitLine('1234AA1;;;5') == ('1234AA1', '5')
13-
assert splitLine('1234AA1,,,5') == ('1234AA1', '5')
14-
assert splitLine('1234AA1;,;5') == ('1234AA1', '5')
15-
assert splitLine('1234AA1 , 5') == ('1234AA1', '5')
13+
assert splitLine('1234AA1,,,3') == ('1234AA1', '3')
14+
assert splitLine('1234AA1;,;2') == ('1234AA1', '2')
15+
assert splitLine('1234AA1 , 1') == ('1234AA1', '1')
1616
assert splitLine('1234AA1\t\t5') == ('1234AA1', '5')
1717

1818

@@ -21,3 +21,8 @@ def test_quotes():
2121
assert splitLine('1234AA1,"5"') == ('1234AA1', '5')
2222
assert splitLine('"1234AA1" "5"') == ('1234AA1', '5')
2323
assert splitLine('"1234AA1\t5"') == ('1234AA1', '5')
24+
25+
26+
def test_extract():
27+
assert extractLineData('001234AA8;5\n') == (1234, 'AA', 5)
28+
assert extractLineData('012345BC2;3\n') == (12345, 'BC', 3)

src/teams.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
class DuplicatePointsEntryException(Exception):
2+
def __init__(self, teamId, task) -> None:
3+
super().__init__(f"Duplicate points entry for team {teamId} \
4+
for task {task} with different points.")
5+
6+
7+
class InvalidPointsException(Exception):
8+
def __init__(self, points, teamId, task) -> None:
9+
super().__init__(
10+
f"Invalid points {points} for team {teamId} on task {task}")
11+
12+
13+
class InvalidTaskException(Exception):
14+
def __init__(self, task, teamId) -> None:
15+
super().__init__(
16+
f"Invalid task {task} for team {teamId}")
17+
18+
19+
def appendTeamsData(teamId: int, task: str, points: int, teamTasks: dict) -> None:
20+
# validate date before insersion
21+
if points not in [1, 2, 3, 5]:
22+
raise InvalidPointsException(points, teamId, task)
23+
24+
if len(task) != 2:
25+
raise InvalidTaskException(task, teamId)
26+
27+
if task[0] not in 'ABCDEFGH' or task[1] not in 'ABCDEFGH':
28+
raise InvalidTaskException(task, teamId)
29+
30+
if not teamId in teamTasks:
31+
teamTasks[teamId] = {}
32+
33+
if task in teamTasks[teamId]: # if already present, then it's a duplicate
34+
# raise error if points are not the same
35+
if teamTasks[teamId][task] != points:
36+
raise DuplicatePointsEntryException(teamId, task)
37+
38+
teamTasks[teamId][task] = points
39+
40+
41+
def getTeamPoints(teamTasks: dict) -> dict:
42+
teamPoints = {}
43+
for teamId in teamTasks:
44+
pointsSum = 0
45+
pointsCount = {}
46+
for task in teamTasks[teamId]:
47+
points = teamTasks[teamId][task]
48+
pointsSum += points
49+
if points in pointsCount:
50+
pointsCount[points] += 1
51+
else:
52+
pointsCount[points] = 1
53+
teamPoints[teamId] = {
54+
'sum': pointsSum,
55+
'counts': pointsCount
56+
}
57+
return teamPoints
58+
59+
60+
# def orderTeams(teamPoints: dict):
61+
# teams = []
62+
# for ()

src/teams_test.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import pytest
2+
3+
from src.teams import DuplicatePointsEntryException, InvalidPointsException, InvalidTaskException, appendTeamsData, getTeamPoints
4+
5+
6+
def test_simple():
7+
teamTasks = {}
8+
appendTeamsData(1234, 'AA', 5, teamTasks)
9+
appendTeamsData(1234, 'BA', 3, teamTasks)
10+
appendTeamsData(1234, 'CD', 2, teamTasks)
11+
appendTeamsData(1234, 'EG', 1, teamTasks)
12+
appendTeamsData(1235, 'HA', 5, teamTasks)
13+
assert teamTasks == {
14+
1234: {
15+
'AA': 5,
16+
'BA': 3,
17+
'CD': 2,
18+
'EG': 1,
19+
},
20+
1235: {
21+
'HA': 5,
22+
}
23+
}
24+
25+
26+
def test_duplicate_valid():
27+
teamTasks = {}
28+
appendTeamsData(1234, 'AA', 5, teamTasks)
29+
appendTeamsData(1234, 'BA', 3, teamTasks)
30+
appendTeamsData(1234, 'CD', 2, teamTasks)
31+
appendTeamsData(1234, 'AA', 5, teamTasks)
32+
appendTeamsData(1234, 'EG', 1, teamTasks)
33+
appendTeamsData(1235, 'HA', 5, teamTasks)
34+
assert teamTasks == {
35+
1234: {
36+
'AA': 5,
37+
'BA': 3,
38+
'CD': 2,
39+
'EG': 1,
40+
},
41+
1235: {
42+
'HA': 5,
43+
}
44+
}
45+
46+
47+
def test_duplicate_invalid():
48+
teamTasks = {}
49+
appendTeamsData(1234, 'AA', 5, teamTasks)
50+
with pytest.raises(DuplicatePointsEntryException):
51+
appendTeamsData(1234, 'AA', 3, teamTasks)
52+
53+
54+
def test_invalid_points():
55+
with pytest.raises(InvalidPointsException):
56+
appendTeamsData(1234, 'AA', 4, {})
57+
with pytest.raises(InvalidPointsException):
58+
appendTeamsData(1234, 'AA', 0, {})
59+
with pytest.raises(InvalidPointsException):
60+
appendTeamsData(1234, 'AA', -1, {})
61+
with pytest.raises(InvalidPointsException):
62+
appendTeamsData(1234, 'AA', 6, {})
63+
64+
65+
def test_invalid_task():
66+
with pytest.raises(InvalidTaskException):
67+
appendTeamsData(1234, 'A', 5, {})
68+
with pytest.raises(InvalidTaskException):
69+
appendTeamsData(1234, 'AAA', 5, {})
70+
with pytest.raises(InvalidTaskException):
71+
appendTeamsData(1234, 'AI', 5, {})
72+
with pytest.raises(InvalidTaskException):
73+
appendTeamsData(1234, 'aa', 5, {})
74+
with pytest.raises(InvalidTaskException):
75+
appendTeamsData(1234, 'IA', 5, {})
76+
with pytest.raises(InvalidTaskException):
77+
appendTeamsData(1234, 'HI', 5, {})
78+
with pytest.raises(InvalidTaskException):
79+
appendTeamsData(1234, 'IH', 5, {})
80+
81+
82+
def test_points_sum():
83+
teamTasks = {
84+
1234: {
85+
'AA': 5,
86+
'BA': 3,
87+
'BB': 3,
88+
'EG': 1,
89+
},
90+
1235: {
91+
'HA': 3,
92+
}
93+
}
94+
assert getTeamPoints(teamTasks) == {
95+
1234: {
96+
'sum': 12,
97+
'counts': {
98+
5: 1,
99+
3: 2,
100+
1: 1,
101+
}
102+
},
103+
1235: {
104+
'sum': 3,
105+
'counts': {
106+
3: 1
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)