Python collections.deque() Examples
The following are 30
code examples of collections.deque().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
collections
, or try the search function
.

Example #1
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def handleOpenSizeArrays(lines): """ When an array size is left with an open number of elements, use the list of initialisers to provide the array size. Const variables are also generated for the array size. """ openArrayRe = r"^\s*declare\s+%s%s\s*\[\s*\]\s*:=\s*\(" % (persistenceRe, variableNameRe) newLines = collections.deque() for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() m = re.search(openArrayRe, line) if m: stringList = ksp_compiler.split_args(line[line.find("(") + 1 : len(line) - 1], line) numElements = len(stringList) name = m.group("name") newLines.append(lines[lineIdx].copy(line[: line.find("[") + 1] + str(numElements) + line[line.find("[") + 1 :])) newLines.append(lines[lineIdx].copy("declare const %s.SIZE := %s" % (name, str(numElements)))) else: newLines.append(lines[lineIdx]) replaceLines(lines, newLines) #=================================================================================================
Example #2
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def buildLines(self): newLines = collections.deque() offset = 1 if self.direction == "downto": self.step = -self.step offset = -1 if not ((self.minVal > self.maxVal and self.direction == "to") or (self.minVal < self.maxVal and self.direction == "downto")): if not self.isSingleLine: for i in range(self.minVal, self.maxVal + offset, self.step): newLines.append(self.line.copy("%s(%s)" % (self.macroName, str(i)))) else: for i in range(self.minVal, self.maxVal + offset, self.step): newLines.append(self.line.copy(self.macroName.replace("#n#", str(i)))) return(newLines)
Example #3
Source File: model.py From tmhmm.py with MIT License | 6 votes |
def parse(file_like): """ Parse a model in the TMHMM 2.0 format. :param file_like: a file-like object to read and parse. :return: a model """ contents = _strip_comments(file_like) tokens = collections.deque(_tokenize(contents)) tokens, header = _parse_header(tokens) states = {} while tokens: tokens, (name, state) = _parse_state(tokens) states[name] = state assert not tokens, "list of tokens not consumed completely" return header, _to_matrix_form(header['alphabet'], _normalize_states(states))
Example #4
Source File: utils.py From dynamic-training-with-apache-mxnet-on-aws with Apache License 2.0 | 6 votes |
def topsort(nodes): n = len(nodes) deg = [0]*n g = [[] for _ in xrange(n)] for i,node in enumerate(nodes): if 'inputs' in node: for j in node['inputs']: deg[i] += 1 g[j[0]].append(i) from collections import deque q = deque([i for i in xrange(n) if deg[i]==0]) res = [] for its in xrange(n): i = q.popleft() res.append(nodes[i]) for j in g[i]: deg[j] -= 1 if deg[j] == 0: q.append(j) new_ids=dict([(node['name'],i) for i,node in enumerate(res)]) for node in res: if 'inputs' in node: for j in node['inputs']: j[0]=new_ids[nodes[j[0]]['name']] return res
Example #5
Source File: compare_layers.py From dynamic-training-with-apache-mxnet-on-aws with Apache License 2.0 | 6 votes |
def _bfs(root_node, process_node): """ Implementation of Breadth-first search (BFS) on caffe network DAG :param root_node: root node of caffe network DAG :param process_node: function to run on each node """ from collections import deque seen_nodes = set() next_nodes = deque() seen_nodes.add(root_node) next_nodes.append(root_node) while next_nodes: current_node = next_nodes.popleft() # process current node process_node(current_node) for child_node in current_node.children: if child_node not in seen_nodes: seen_nodes.add(child_node) next_nodes.append(child_node)
Example #6
Source File: compare_layers.py From dynamic-training-with-apache-mxnet-on-aws with Apache License 2.0 | 6 votes |
def _bfs(root_node, process_node): """ Implementation of Breadth-first search (BFS) on caffe network DAG :param root_node: root node of caffe network DAG :param process_node: function to run on each node """ from collections import deque seen_nodes = set() next_nodes = deque() seen_nodes.add(root_node) next_nodes.append(root_node) while next_nodes: current_node = next_nodes.popleft() # process current node process_node(current_node) for child_node in current_node.children: if child_node not in seen_nodes: seen_nodes.add(child_node) next_nodes.append(child_node)
Example #7
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def handleIterateMacro(lines): scan = False newLines = collections.deque() for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() if line.startswith("iterate_macro"): scan = True m = re.search(r"^iterate_macro\s*\((?P<macro>.+)\)\s*:=\s*(?P<min>.+)\b(?P<direction>to|downto)(?P<max>(?:.(?!\bstep\b))+)(?:\s+step\s+(?P<step>.+))?$", line) if m: iterateObj = IterateMacro(m.group("macro"), m.group("min"), m.group("max"), m.group("step"), m.group("direction"), lines[lineIdx]) newLines.extend(iterateObj.buildLines()) else: newLines.append(lines[lineIdx]) else: newLines.append(lines[lineIdx]) replaceLines(lines, newLines) return scan #=================================================================================================
Example #8
Source File: gym_utils.py From fine-lm with MIT License | 6 votes |
def __init__(self, env, warm_up_examples=0, ball_down_skip=0, big_ball=False, include_direction_info=False, reward_clipping=True): super(BreakoutWrapper, self).__init__( env, warm_up_examples=warm_up_examples, warmup_action=BreakoutWrapper.FIRE_ACTION) self.warm_up_examples = warm_up_examples self.observation_space = gym.spaces.Box(low=0, high=255, shape=(210, 160, 3), dtype=np.uint8) self.ball_down_skip = ball_down_skip self.big_ball = big_ball self.reward_clipping = reward_clipping self.include_direction_info = include_direction_info self.direction_info = deque([], maxlen=2) self.points_gained = False msg = ("ball_down_skip should be bigger equal 9 for " "include_direction_info to work correctly") assert not self.include_direction_info or ball_down_skip >= 9, msg
Example #9
Source File: GameOfLife.py From BiblioPixelAnimations with MIT License | 6 votes |
def __init__(self, width, height, depth, rand_max, table=None): self.toroidal = True self._rand_max = rand_max if table: self.table = table self.depth = len(table) self.height = len(table[0]) self.width = len(table[0][0]) else: self.height = height self.width = width self.depth = depth self.genNewTable() self._oldStates = deque() for i in range(3): self._oldStates.append([]) self.offsets = list(itertools.product([-1, 0, 1], repeat=3)) self.offsets.remove((0, 0, 0)) # remove center point
Example #10
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def createBuiltinDefines(lines): # Create date-time variables timecodes = ['%S', '%M', '%H', '%I', '%p', '%d', '%m', '%Y', '%y', '%B', '%b', '%x', '%X'] timenames = ['__SEC__','__MIN__','__HOUR__','__HOUR12__','__AMPM__','__DAY__','__MONTH__','__YEAR__','__YEAR2__','__LOCALE_MONTH__','__LOCALE_MONTH_ABBR__','__LOCALE_DATE__','__LOCALE_TIME__'] defines = ['define {0} := \"{1}\"'.format(timenames[i], strftime(timecodes[i], localtime())) for i in range(len(timecodes))] newLines = collections.deque() # append our defines on top of the script in a temporary deque for string in defines: newLines.append(lines[0].copy(string)) # merge with the original unmodified script for line in lines: newLines.append(line) # replace original deque with modified one replaceLines(lines, newLines) #=================================================================================================
Example #11
Source File: cbpro_wrapper.py From TradzQAI with Apache License 2.0 | 6 votes |
def __init__(self, authClient=None, product_id=None, userorder=None, orders_class=None): self.authClient = authClient self.product_id = product_id self.maxthreads = 10 self.lastb_thread = 0 self.lasts_thread = 0 self.lastc_thread = 0 self.order = [] self.orders_class = orders_class self.orders = None self.size = 0 self.price = 0 self.allocated_funds = 0 self.rejected = False self.no_funds = False self.adduserorder = userorder self.bnthreads = deque(maxlen=self.maxthreads) self.snthreads = deque(maxlen=self.maxthreads) self.cancelnthreads = deque(maxlen=self.maxthreads) self.buildThreads(n=self.maxthreads)
Example #12
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def handleLiterateMacro(lines): scan = False newLines = collections.deque() for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() if line.startswith("literate_macro"): scan = True m = re.search(r"^literate_macro\s*\((?P<macro>.+)\)\s+on\s+(?P<target>.+)$", line) if m: name = m.group("macro") targets = ksp_compiler.split_args(m.group("target"), lines[lineIdx]) if not "#l#" in name: for text in targets: newLines.append(lines[lineIdx].copy("%s(%s)" % (name, text))) else: for text in targets: newLines.append(lines[lineIdx].copy(name.replace("#l#", text))) continue newLines.append(lines[lineIdx]) replaceLines(lines, newLines) return scan
Example #13
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def handleListBlocks(lines): listBlockStartRe = r"^list\s*%s\s*(?:\[(?P<size>%s)?\])?$" % (variableNameRe, variableOrInt) listBlockEndRe = r"^end\s+list$" newLines = collections.deque() listBlockObj = None isListBlock = False for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() m = re.search(listBlockStartRe, line) if m: isListBlock = True listBlockObj = ListBlock(m.group("whole"), m.group("size")) elif isListBlock and not line == "": if re.search(listBlockEndRe, line): isListBlock = False if listBlockObj.members: newLines.extend(listBlockObj.buildLines(lines[lineIdx])) else: listBlockObj.addMember(line) else: newLines.append(lines[lineIdx]) replaceLines(lines, newLines) #=================================================================================================
Example #14
Source File: network_repr.py From Recipes with MIT License | 6 votes |
def _insert_header(network_str, incomings, outgoings): """ Insert the header (first two lines) in the representation.""" line_1 = deque([]) if incomings: line_1.append('In -->') line_1.append('Layer') if outgoings: line_1.append('--> Out') line_1.append('Description') line_2 = deque([]) if incomings: line_2.append('-------') line_2.append('-----') if outgoings: line_2.append('-------') line_2.append('-----------') network_str.appendleft(line_2) network_str.appendleft(line_1) return network_str
Example #15
Source File: helpers.py From apted with MIT License | 6 votes |
def from_text(cls, text): """Create tree from bracket notation Bracket notation encodes the trees with nested parentheses, for example, in tree {A{B{X}{Y}{F}}{C}} the root node has label A and two children with labels B and C. Node with label B has three children with labels X, Y, F. """ tree_stack = [] stack = [] for letter in text: if letter == "{": stack.append("") elif letter == "}": text = stack.pop() children = deque() while tree_stack and tree_stack[-1][1] > len(stack): child, _ = tree_stack.pop() children.appendleft(child) tree_stack.append((cls(text, *children), len(stack))) else: stack[-1] += letter return tree_stack[0][0]
Example #16
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def handleArrayConcat(lines): arrayConcatRe = r"(?P<declare>^\s*declare\s+)?%s\s*(?P<brackets>\[(?P<arraysize>.*)\])?\s*:=\s*%s\s*\((?P<arraylist>[^\)]*)" % (variableNameRe, concatSyntax) newLines = collections.deque() for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() if "concat" in line: m = re.search(arrayConcatRe, line) if m: concatObj = ArrayConcat(m.group("whole"), m.group("declare"), m.group("brackets"), m.group("arraysize"), m.group("arraylist"), lines[lineIdx]) concatObj.checkArraySize(lineIdx, lines) if m.group("declare"): newLines.append(lines[lineIdx].copy(concatObj.getRawArrayDeclaration())) newLines.extend(concatObj.buildLines()) continue # The variables needed are declared at the start of the init callback. elif line.startswith("on"): if re.search(initRe, line): newLines.append(lines[lineIdx]) newLines.append(lines[lineIdx].copy("declare concat_it")) newLines.append(lines[lineIdx].copy("declare concat_offset")) continue newLines.append(lines[lineIdx]) replaceLines(lines, newLines) #=================================================================================================
Example #17
Source File: many_to_one.py From matchpy with MIT License | 6 votes |
def _match_regular_operation(self, transition: _Transition) -> Iterator[_State]: subject = self.subjects.popleft() after_subjects = self.subjects operand_subjects = self.subjects = deque(op_iter(subject)) new_associative = transition.label if issubclass(transition.label, AssociativeOperation) else None self.associative.append(new_associative) for new_state in self._check_transition(transition, subject, False): self.subjects = after_subjects self.associative.pop() for end_transition in new_state.transitions[OPERATION_END]: yield from self._check_transition(end_transition, None, False) self.subjects = operand_subjects self.associative.append(new_associative) self.subjects = after_subjects self.subjects.appendleft(subject) self.associative.pop()
Example #18
Source File: many_to_one.py From matchpy with MIT License | 6 votes |
def _internal_add(self, pattern: Pattern, label, renaming) -> int: """Add a new pattern to the matcher. Equivalent patterns are not added again. However, patterns that are structurally equivalent, but have different constraints or different variable names are distinguished by the matcher. Args: pattern: The pattern to add. Returns: The internal id for the pattern. This is mainly used by the :class:`CommutativeMatcher`. """ pattern_index = len(self.patterns) renamed_constraints = [c.with_renamed_vars(renaming) for c in pattern.local_constraints] constraint_indices = [self._add_constraint(c, pattern_index) for c in renamed_constraints] self.patterns.append((pattern, label, constraint_indices)) self.pattern_vars.append(renaming) pattern = rename_variables(pattern.expression, renaming) state = self.root patterns_stack = [deque([pattern])] self._process_pattern_stack(state, patterns_stack, renamed_constraints, pattern_index) return pattern_index
Example #19
Source File: many_to_one.py From matchpy with MIT License | 6 votes |
def _process_pattern_stack(self, state, patterns_stack, renamed_constraints, pattern_index): while patterns_stack: if patterns_stack[-1]: subpattern = patterns_stack[-1].popleft() variable_name = getattr(subpattern, 'variable_name', None) if isinstance(subpattern, Operation): if isinstance(subpattern, OneIdentityOperation): non_optional, added_subst = check_one_identity(subpattern) if non_optional is not None: stack = [q.copy() for q in patterns_stack] stack[-1].appendleft(non_optional) new_state = self._create_expression_transition(state, _EPS, variable_name, pattern_index, added_subst) self._process_pattern_stack(new_state, stack, renamed_constraints, pattern_index) if not isinstance(subpattern, CommutativeOperation): patterns_stack.append(deque(op_iter(subpattern))) state = self._create_expression_transition(state, subpattern, variable_name, pattern_index) if isinstance(subpattern, CommutativeOperation): subpattern_id = state.matcher.add_pattern(subpattern, renamed_constraints) state = self._create_simple_transition(state, subpattern_id, pattern_index) else: patterns_stack.pop() if len(patterns_stack) > 0: state = self._create_simple_transition(state, OPERATION_END, pattern_index) self.finals.add(state.number)
Example #20
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def buildLines(self): """ Return all the lines needed to perfrom the concat. """ newLines = collections.deque() numArgs = len(self.arraysToConcat) offsets = ["0"] offsets.extend(["num_elements(%s)" % arrName for arrName in self.arraysToConcat]) addOffset = "" if numArgs != 1: addOffset = " + concat_offset" newLines.append(self.line.copy("concat_offset := 0")) offsetCommand = "concat_offset := concat_offset + #offset#" templateText = [ "for concat_it := 0 to num_elements(#arg#) - 1", " #parent#[concat_it%s] := #arg#[concat_it]" % addOffset, "end for"] for j in range(numArgs): if j != 0 and numArgs != 1: newLines.append(self.line.copy(offsetCommand.replace("#offset#", offsets[j]))) for text in templateText: newLines.append(self.line.copy(text.replace("#arg#", self.arraysToConcat[j]).replace("#parent#", self.arrayToFill))) return(newLines)
Example #21
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 6 votes |
def post_macro_functions(lines): """ This function is called after the regular macros have been expanded. lines is a collections.deque of Line objects - see ksp_compiler.py.""" handleIncrementer(lines) handleConstBlock(lines) handleStructs(lines) handleUIArrays(lines) handleSameLineDeclaration(lines) handleMultidimensionalArrays(lines) handleListBlocks(lines) handleOpenSizeArrays(lines) handlePersistence(lines) handleLists(lines) handleUIFunctions(lines) handleStringArrayInitialisation(lines) handleArrayConcat(lines) #=================================================================================================
Example #22
Source File: obst.py From indras_net with GNU General Public License v3.0 | 6 votes |
def _check_for_obst(self, steps, vector_mag, clear_x, clear_y): """ Look for obstacles in the path 'steps' and stop short if they are there. clear_x and clear_y start out as the agent's current pos, which must, of course, be clear for this agent to occupy! If there happens to be an obstacle less than tolerance - 1 from the agent's initial square, well, we just stay put. """ lag = self.tolerance - 1 lookahead = deque(maxlen=lag + 1) for (x, y) in steps: lookahead.append((x, y)) if not self.env.is_cell_empty(x, y): return (clear_x, clear_y) elif lag > 0: lag -= 1 else: (clear_x, clear_y) = lookahead.popleft() return (clear_x, clear_y)
Example #23
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def handleConstBlock(lines): constBlockStartRe = r"^const\s+%s$" % variableNameRe constBlockEndRe = r"^end\s+const$" constBlockMemberRe = r"^%s(?:$|\s*\:=\s*(?P<value>.+))" % variableNameRe newLines = collections.deque() constBlockObj = None inConstBlock = False for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() if line.startswith("const"): m = re.search(constBlockStartRe, line) if m: constBlockObj = ConstBlock(m.group("name")) inConstBlock = True continue elif line.startswith("end"): if re.search(constBlockEndRe, line): if constBlockObj.memberValues: newLines.extend(constBlockObj.buildLines(lines[lineIdx])) inConstBlock = False continue elif inConstBlock: m = re.search(constBlockMemberRe, line) if m: constBlockObj.addMember(m.group("whole"), m.group("value")) continue elif not line.strip() == "": raise ksp_compiler.ParseException(lines[lineIdx], "Incorrect syntax. In a const block, list constant names and optionally assign them a constant value.") newLines.append(lines[lineIdx]) replaceLines(lines, newLines) #=================================================================================================
Example #24
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def getListDeclaration(self, line): """ This function returns the lines for a list declaration. Because the size of the list caluated based on how many list_add() functions have been use, this function must be called after all list_add() are resolved. """ newLines = collections.deque() if not self.isMatrix: newLines.append(line.copy("declare %s %s%s[%s]" % (self.persistence, self.prefix, self.name, self.inc))) newLines.append(line.copy("declare const %s.SIZE := %s" % (self.noUnderscoreName, self.inc))) else: listMatrixTemplate = [ "declare #list#.sizes[#size#] := (#sizeList#)", "declare #list#.pos[#size#] := (#posList#)", "property #list#", "function get(d1, d2) -> result", "result := _#list#[#list#.pos[d1] + d2]", "end function", "function set(d1, d2, val)", "_#list#[#list#.pos[d1] + d2] := val", "end function", "end property"] newLines.append(line.copy("declare %s %s%s[%s]" % (self.persistence, self.prefix, self.name, self.inc))) newLines.append(line.copy("declare const %s.SIZE := %s" % (self.noUnderscoreName, len(self.sizeList)))) sizeCounter = "0" posList = ["0"] for i in range(len(self.sizeList) - 1): sizeCounter = simplfyAdditionString("%s+%s" % (sizeCounter, self.sizeList[i])) posList.append(sizeCounter) for text in listMatrixTemplate: replacedText = text.replace("#list#", self.noUnderscoreName)\ .replace("#sizeList#", ",".join(self.sizeList))\ .replace("#posList#", ",".join(posList))\ .replace("#size#", str(len(self.sizeList))) newLines.append(line.copy(replacedText)) return(newLines)
Example #25
Source File: atari_wrappers.py From HardRLWithYoutube with MIT License | 5 votes |
def __init__(self, env, k): """Stack k last frames. Returns lazy array, which is much more memory efficient. See Also -------- baselines.common.atari_wrappers.LazyFrames """ gym.Wrapper.__init__(self, env) self.k = k self.frames = deque([], maxlen=k) shp = env.observation_space.shape self.observation_space = spaces.Box(low=0, high=255, shape=(shp[0], shp[1], shp[2] * k), dtype=env.observation_space.dtype)
Example #26
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def pre_macro_functions(lines): """ This function is called before the macros have been expanded. lines is a collections.deque of Line objects - see ksp_compiler.py.""" createBuiltinDefines(lines) removeActivateLoggerPrint(lines) handleDefineConstants(lines) # Define literals are only avilable for backwards compatibility as regular defines now serve this purpose. handleDefineLiterals(lines)
Example #27
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def buildLines(self, line): """ Return the the commands for the whole const block. """ newLines = collections.deque() newLines.append(line.copy("declare %s[%s] := (%s)" % (self.name, len(self.memberNames), ", ".join(self.memberValues)))) newLines.append(line.copy("declare const %s.SIZE := %s" % (self.name, len(self.memberNames)))) for memNum in range(len(self.memberNames)): newLines.append(line.copy("declare const %s.%s := %s" % (self.name, self.memberNames[memNum], self.memberValues[memNum]))) return(newLines)
Example #28
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def handleSameLineDeclaration(lines): """ When a variable is declared and initialised on the same line, check to see if the value needs to be moved over to the next line. """ newLines = collections.deque() famCount = 0 for lineIdx in range(len(lines)): line = lines[lineIdx].command.strip() famCount = countFamily(line, famCount) if line.startswith("declare"): m = re.search(r"^declare\s+(?:(polyphonic|global|local)\s+)*%s%s\s*:=" % (persistenceRe, variableNameRe), line) if m and not re.search(r"\b%s\s*\(" % concatSyntax, line): valueIsConstantInteger = False value = line[line.find(":=") + 2 :] if not re.search(stringOrPlaceholderRe, line): try: # Ideally this would check to see if the value is a Kontakt constant as those are valid # inline as well... eval(value) # Just used as a test to see if the the value is a constant. valueIsConstantInteger = True except: pass if not valueIsConstantInteger: preAssignmentText = line[: line.find(":=")] variableName = m.group("name") if famCount != 0: variableName = inspectFamilyState(lines, lineIdx) + variableName newLines.append(lines[lineIdx].copy(preAssignmentText)) newLines.append(lines[lineIdx].copy(variableName + " " + line[line.find(":=") :])) continue newLines.append(lines[lineIdx]) replaceLines(lines, newLines) #=================================================================================================
Example #29
Source File: preprocessor_plugins.py From SublimeKSP with GNU General Public License v3.0 | 5 votes |
def buildUiPropertyLines(self, line): """ Return the set ui property commands, e.g. name -> par := val """ newLines = collections.deque() for argNum in range(len(self.args)): newLines.append(line.copy("%s -> %s := %s" % (self.uiId, self.functionType.args[argNum], self.args[argNum]))) return(newLines)
Example #30
Source File: env.py From indras_net with GNU General Public License v3.0 | 5 votes |
def disp_log(self): """ Display last 16 lines of log file. """ MAX_LINES = 16 logfile = None if self.props is not None: logfile = self.props.get_logfile() else: self.user.tell("Props missing; cannot identify log file!", type=user.ERROR, text_id=1, reverse=False) return if logfile is None: self.user.tell("No log file to examine!", type=user.ERROR, text_id=1, reverse=False) return last_n_lines = deque(maxlen=MAX_LINES) # for now hard-coded with open(logfile, 'rt') as log: for line in log: last_n_lines.append(line) self.user.tell("Displaying the last " + str(MAX_LINES) + " lines of logfile " + logfile, text_id=1, reverse=False) for line in last_n_lines: self.user.tell(line.strip(), text_id=1, reverse=False)