Conditions | 15 |
Total Lines | 97 |
Lines | 0 |
Ratio | 0 % |
Tests | 28 |
CRAP Score | 20.0511 |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like Type2JoinHelper._pass4() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | """ |
||
134 | 1 | def _pass4(self, rows): |
|
135 | """ |
||
136 | Merges adjacent and overlapping rows in the same group (i.e. with the same natural key). With proper reference |
||
137 | data overlapping rows MUST not occur. However, this method can handle overlapping rows. Overlapping rows are |
||
138 | resolved as follows: |
||
139 | * The interval with the most recent begin date prevails for the overlapping period. |
||
140 | * If the begin dates are the same the interval with the most recent end date prevails. |
||
141 | * If the begin and end dates are equal the last row in the data set prevails. |
||
142 | |||
143 | :param list[dict[str,T]] rows: The rows in a group (i.e. with the same natural key). |
||
144 | . |
||
145 | :rtype: list[dict[str,T]] |
||
146 | """ |
||
147 | 1 | ret = list() |
|
148 | |||
149 | 1 | prev_row = None |
|
150 | 1 | for row in rows: |
|
151 | 1 | if prev_row: |
|
152 | 1 | relation = Allen.relation(prev_row[self._key_start_date], |
|
153 | prev_row[self._key_end_date], |
||
154 | row[self._key_start_date], |
||
155 | row[self._key_end_date]) |
||
156 | 1 | if relation == Allen.X_BEFORE_Y: |
|
157 | # Two rows with distinct intervals. |
||
158 | # prev_row: |----| |
||
159 | # row: |-----| |
||
160 | 1 | ret.append(prev_row) |
|
161 | 1 | prev_row = row |
|
162 | 1 | elif relation == Allen.X_MEETS_Y: |
|
163 | # The two rows are adjacent. |
||
164 | # prev_row: |-------| |
||
165 | # row: |-------| |
||
166 | 1 | if self._equal(prev_row, row): |
|
167 | # The two rows are identical (except for start and end date) and adjacent. Combine the two rows |
||
168 | # into one row. |
||
169 | 1 | prev_row[self._key_end_date] = row[self._key_end_date] |
|
170 | else: |
||
171 | # Rows are adjacent but not identical. |
||
172 | 1 | ret.append(prev_row) |
|
173 | 1 | prev_row = row |
|
174 | 1 | elif relation == Allen.X_OVERLAPS_WITH_Y: |
|
175 | # prev_row overlaps row. Should not occur with proper reference data. |
||
176 | # prev_row: |-----------| |
||
177 | # row: |----------| |
||
178 | 1 | if self._equal(prev_row, row): |
|
179 | # The two rows are identical (except for start and end date) and overlapping. Combine the two |
||
180 | # rows into one row. |
||
181 | 1 | prev_row[self._key_end_date] = row[self._key_end_date] |
|
182 | else: |
||
183 | # Rows are overlapping but not identical. |
||
184 | 1 | prev_row[self._key_end_date] = row[self._key_start_date] - 1 |
|
185 | 1 | ret.append(prev_row) |
|
186 | 1 | prev_row = row |
|
187 | 1 | elif relation == Allen.X_STARTS_Y: |
|
188 | # prev_row start row. Should not occur with proper reference data. |
||
189 | # prev_row: |------| |
||
190 | # row: |----------------| |
||
191 | 1 | prev_row = row |
|
192 | 1 | elif relation == Allen.X_EQUAL_Y: |
|
193 | # Can happen when the reference data sets are joined without respect for date intervals. |
||
194 | # prev_row: |----------------| |
||
195 | # row: |----------------| |
||
196 | 1 | prev_row = row |
|
197 | elif relation == Allen.X_DURING_Y_INVERSE: |
||
198 | # row during prev_row. Should not occur with proper reference data. |
||
199 | # prev_row: |----------------| |
||
200 | # row: |------| |
||
201 | if not self._equal(prev_row, row): |
||
202 | prev_row[self._key_end_date] = row[self._key_start_date] - 1 |
||
203 | ret.append(prev_row) |
||
204 | prev_row = row |
||
205 | # Note: the interval after row[self._key_end_date] is discarded. |
||
206 | |||
207 | # Note: if the two rows are identical (except for start and end date) nothing to do. |
||
208 | elif relation == Allen.X_FINISHES_Y_INVERSE: |
||
209 | # row finishes prev_row. Should not occur with proper reference data. |
||
210 | # prev_row: |----------------| |
||
211 | # row: |------| |
||
212 | if not self._equal(prev_row, row): |
||
213 | prev_row[self._key_end_date] = row[self._key_start_date] - 1 |
||
214 | ret.append(prev_row) |
||
215 | prev_row = row |
||
216 | |||
217 | # Note: if the two rows are identical (except for start and end date) nothing to do. |
||
218 | else: |
||
219 | # Not in _pass3 the rows are sorted such that. |
||
220 | # prev_row[self._key_begin_date] <= row[self._key_begin_date]. Hence the following relation should |
||
221 | # not occur: X_FINISHES_Y, X_BEFORE_Y_INVERSE, X_MEETS_Y_INVERSE, X_OVERLAPS_WITH_Y_INVERSE, and |
||
222 | # X_STARTS_Y_INVERSE. Hence, we covered all 13 relations in Allen's interval algebra. |
||
223 | raise ValueError('Data is not sorted properly. Relation: %d' % relation) |
||
224 | else: |
||
225 | 1 | prev_row = row |
|
226 | |||
227 | 1 | if prev_row: |
|
228 | 1 | ret.append(prev_row) |
|
229 | |||
230 | 1 | return ret |
|
231 | |||
256 |