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 |