| Conditions | 18 |
| Total Lines | 97 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 3 | ||
| 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 Analyzer.extract_fields() 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 | # |
||
| 60 | def extract_fields(self, queryformat): |
||
| 61 | """Extract requested properties from -qf (--queryformat) |
||
| 62 | |||
| 63 | :param string queryformat: The query format string from parameter -qf |
||
| 64 | :return list: the list of all requested properties from -qf (--queryformat) |
||
| 65 | """ |
||
| 66 | |||
| 67 | fields = set() |
||
| 68 | |||
| 69 | state = 0 |
||
| 70 | ignorenext = False |
||
| 71 | field = "" |
||
| 72 | skip = -1 |
||
| 73 | length = len(queryformat) |
||
| 74 | |||
| 75 | # algorithm for detecting the requested properties |
||
| 76 | for idx, char in enumerate(queryformat): |
||
| 77 | # ignore the current char if needed |
||
| 78 | if ignorenext: |
||
| 79 | ignorenext = False |
||
| 80 | |||
| 81 | # if we are in the "capturing" state (1), we can just add the |
||
| 82 | # current char to our field string |
||
| 83 | if state == 1: |
||
| 84 | field += char |
||
| 85 | |||
| 86 | continue |
||
| 87 | |||
| 88 | # skip the current char if needed (user for escaping with '{') |
||
| 89 | if skip != -1 and skip == idx: |
||
| 90 | skip = -1 |
||
| 91 | continue |
||
| 92 | |||
| 93 | # this is also an escape detection but it is actually no longer needed. |
||
| 94 | # can be removed in future versions |
||
| 95 | if char == '\\': |
||
| 96 | ignorenext = True |
||
| 97 | continue |
||
| 98 | |||
| 99 | # if we are not in any capturing state (1), we jump into this condition if |
||
| 100 | # we found a '{'. '{' means, if there is not a second '{' after the current |
||
| 101 | # '{', this should be a capturing instruction |
||
| 102 | if char == '{' and state == 0: |
||
| 103 | # if we are not at the end of the string, we have a look onto the next |
||
| 104 | # character. If the next character also contains a '{', we are in a |
||
| 105 | # 'ignore everything in it' statement |
||
| 106 | if length-1 != idx: |
||
| 107 | if queryformat[idx+1] == '{': |
||
| 108 | # ok, we are in a 'ignore everything' statement. we skip now the next |
||
| 109 | # character (because that's the '{') and jump into the 'ignore everything' |
||
| 110 | # state (state 3) |
||
| 111 | skip = idx+1 |
||
| 112 | state = 3 |
||
| 113 | else: |
||
| 114 | # the next character is not a 'ignore everything' instruction. So we're |
||
| 115 | # in a 'capturing' state. (state 1) |
||
| 116 | state = 1 |
||
| 117 | else: |
||
| 118 | # we reached the end of the string - just jump into the 'capturing' statement |
||
| 119 | state = 1 |
||
| 120 | continue |
||
| 121 | |||
| 122 | # detect the end of the 'capturing' sequence. (the current character has to be a '}' and |
||
| 123 | # we also have to be in the 'capturing' state) |
||
| 124 | if char == '}' and state == 1: |
||
| 125 | state = 0 |
||
| 126 | |||
| 127 | # we copy our captured string into our 'fields' list - that is really important |
||
| 128 | # because we need all requested properties |
||
| 129 | fields.add(field) |
||
| 130 | |||
| 131 | # clear the string because we need it for the next capturing sequence |
||
| 132 | field = "" |
||
| 133 | continue |
||
| 134 | |||
| 135 | # detect the end of a 'ignore everything' sequence |
||
| 136 | if char == '}' and state == 3: |
||
| 137 | # check if we reached the end of the string - if not, look onto the next character. |
||
| 138 | # if the next character is a '}', we can leave the 'ignore everything' sequence. |
||
| 139 | # if not, just skip it |
||
| 140 | if length-1 != idx: |
||
| 141 | if queryformat[idx+1] == '}': |
||
| 142 | # go back into the 'nothing' (append until we found a new instruction) |
||
| 143 | # statement |
||
| 144 | state = 0 |
||
| 145 | skip = idx+1 |
||
| 146 | |||
| 147 | # if we're in the 'capturing' sequence, we have to append the current character |
||
| 148 | # to our 'field' string |
||
| 149 | if state == 1: |
||
| 150 | field += char |
||
| 151 | |||
| 152 | # make the fields list public - this will be needed for some other functions |
||
| 153 | # like 'fetch_data' since there is no option for passing the 'fields' list |
||
| 154 | # over the argument list |
||
| 155 | self.fields = fields |
||
| 156 | return self.fields |
||
| 157 | |||
| 287 |