| Conditions | 16 |
| Total Lines | 62 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 3 | ||
| Bugs | 1 | 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 fmt_table() 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 | """Helper functions and classes""" |
||
| 17 | if TYPE_CHECKING: |
||
| 18 | from .wm import WindowManager # NOQA |
||
| 19 | |||
| 20 | # pylint: disable=C0103 |
||
| 21 | PercentRect = Tuple[float, float, float, float] |
||
| 22 | Strut = Tuple[int, int, int, int, int, int, int, int, int, int, int, int] |
||
| 23 | |||
| 24 | # FIXME: Replace */** with a dict so I can be strict here |
||
| 25 | CommandCB = Callable[..., Any] |
||
| 26 | except: # pylint: disable=bare-except |
||
| 27 | pass |
||
|
|
|||
| 28 | |||
| 29 | def clamp_idx(idx, stop, wrap=True): |
||
| 30 | # type: (int, int, bool) -> int |
||
| 31 | """Ensure a 0-based index is within a given range [0, stop). |
||
| 32 | |||
| 33 | Uses the same half-open range convention as Python slices. |
||
| 34 | |||
| 35 | @param wrap: If C{True}, wrap around rather than saturating. |
||
| 36 | """ |
||
| 37 | if wrap: |
||
| 38 | return idx % stop |
||
| 39 | else: |
||
| 40 | return max(min(idx, stop - 1), 0) |
||
| 41 | |||
| 42 | def powerset(iterable): # type: (Iterable[Any]) -> Iterator[Sequence[Any]] |
||
| 43 | """C{powerset([1,2,3])} --> C{() (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)} |
||
| 44 | |||
| 45 | @rtype: iterable |
||
| 46 | """ |
||
| 47 | i = list(iterable) |
||
| 48 | return chain.from_iterable(combinations(i, j) for j in range(len(i) + 1)) |
||
| 49 | |||
| 50 | def fmt_table(rows, # type: Any |
||
| 51 | headers, # type: Sequence |
||
| 52 | group_by=None # type: Optional[int] |
||
| 53 | ): # type: (...) -> str |
||
| 54 | """Format a collection as a textual table. |
||
| 55 | |||
| 56 | @param headers: Header labels for the columns |
||
| 57 | @param group_by: Index of the column to group results by. |
||
| 58 | @type rows: C{dict} or iterable of iterables |
||
| 59 | @type headers: C{list(str)} |
||
| 60 | @type group_by: C{int} |
||
| 61 | |||
| 62 | @attention: This uses C{zip()} to combine things. The number of columns |
||
| 63 | displayed will be defined by the narrowest of all rows. |
||
| 64 | |||
| 65 | @rtype: C{str} |
||
| 66 | """ |
||
| 67 | output = [] # type: List[str] |
||
| 68 | |||
| 69 | if isinstance(rows, dict): |
||
| 70 | rows = list(sorted(rows.items())) |
||
| 71 | |||
| 72 | groups = {} # type: Dict[str, List[str]] |
||
| 73 | if group_by is not None: |
||
| 74 | headers = list(headers) |
||
| 75 | headers.pop(group_by) |
||
| 76 | rows = [list(row) for row in rows] |
||
| 77 | for row in rows: |
||
| 78 | group = row.pop(group_by) |
||
| 79 | groups.setdefault(group, []).append(row) |
||
| 182 |
Except handlers which only contain
passand do not have anelseclause can usually simply be removed: