Coverage for rfpy/api/fix/qtables.py: 100%
42 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-31 16:00 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-31 16:00 +0000
1from operator import attrgetter
3from rfpy.model.questionnaire import QuestionDefinition
6def fix_spans(qdef: QuestionDefinition):
7 if qdef.is_table_valid:
8 return True
9 if qdef.occupied_area < qdef.grid_area:
10 # there are gaps, so increase spans of cells with biggest spans
11 for _i in range(50):
12 by_colspan = sorted(qdef.elements, key=attrgetter('colspan'), reverse=True)
13 by_rowspan = sorted(qdef.elements, key=attrgetter('rowspan'), reverse=True)
14 if _i % 2:
15 for el in by_rowspan:
16 if el.colspan == 1:
17 el.rowspan += 1
18 break
19 else:
20 for el in by_colspan:
21 if el.rowspan == 1:
22 el.colspan += 1
23 break
24 else:
25 # if rowspan and colspan are greater than one incrementing in steps of one
26 # results in the area increasing by more than one, so cannot hit target
27 # therefore if this simple approach isnt working, scrap it and set all rowspans
28 # to 1
29 for el in qdef.elements:
30 el.rowspan = 1
31 if qdef.is_table_valid or (qdef.occupied_area > qdef.grid_area):
32 break
34 if qdef.occupied_area > qdef.grid_area:
35 # reduce spans until it fits
36 for el in qdef.elements:
37 # Reset obviously wrong values
38 if el.colspan > qdef.column_count:
39 el.colspan = qdef.column_count
40 if el.rowspan > qdef.row_count:
41 el.rowspan = qdef.row_count
42 for _i in range(50):
43 by_colspan = sorted(qdef.elements, key=attrgetter('colspan'), reverse=True)
44 by_rowspan = sorted(qdef.elements, key=attrgetter('rowspan'), reverse=True)
45 col_el = by_colspan[0]
46 row_el = by_rowspan[0]
47 if col_el.colspan >= row_el.rowspan and col_el.colspan > 1:
48 col_el.colspan -= 1
49 elif row_el.rowspan > 1:
50 row_el.rowspan -= 1
51 if qdef.is_table_valid:
52 break
54 if not qdef.is_table_valid:
55 raise Exception(f"Unable to fix spans for question {qdef}")
57 return True