def is_met(self, variables, event_counter): ismet, err = ParseUtil.evaluate(self.cond, variables, event_counter, ParseUtil.STOP_COND) if err: raise ParseException(self.lineno, err) if type(ismet) is not bool: raise ParseException(self.lineno, f"Condition '{self.cond}' is not a boolean expression.") return ismet
def _parse_plot(self, lineno, linesplit_space): """ @plot expr {mpl_prop} """ cmd = linesplit_space[0] if len(linesplit_space) == 1: # @plot raise ParseException(lineno, f"Invalid {cmd} command.") expr0, mpl_prop = ParseUtil.get_ending_dict(linesplit_space[1]) if mpl_prop is None: mpl_prop = dict() expr = expr0 all_stimulus_elements = self.parameters.get(kw.STIMULUS_ELEMENTS) all_behaviors = self.parameters.get(kw.BEHAVIORS) err = None if cmd == kw.VPLOT: expr, err = ParseUtil.parse_element_behavior( expr0, all_stimulus_elements, all_behaviors) elif cmd == kw.VSSPLOT: expr, err = ParseUtil.parse_element_element( expr0, all_stimulus_elements) elif cmd == kw.PPLOT: stimulus, behavior, err = ParseUtil.parse_stimulus_behavior( expr0, all_stimulus_elements, all_behaviors, self.variables) expr = (stimulus, behavior) elif cmd == kw.NPLOT: expr, err = ParseUtil.parse_chain(expr0, all_stimulus_elements, all_behaviors) if err: raise ParseException(lineno, err) return expr, mpl_prop, expr0
def _evalparse(self, lineno, parameters): """Handles parameters that depend on currently defined runs.""" if len(self.all_run_labels) == 0: raise ParseException(lineno, "There is no @RUN.") run_label = parameters.get(kw.EVAL_RUNLABEL) if len(run_label) == 0: run_label = self.all_run_labels[-1] parameters.val[kw.EVAL_RUNLABEL] = run_label else: if run_label not in self.all_run_labels: raise ParseException(lineno, f"Unknown run label '{run_label}'.")
def _parse_export(self, lineno, linesplit_space): """ @export expr @export expr filename @hexport @hexport filename """ cmd = linesplit_space[0] filename_param = self.parameters.get(kw.FILENAME) if cmd == kw.HEXPORT: if len(linesplit_space) == 1: # @hexport if len(filename_param) == 0: raise ParseException(lineno, f"Invalid {cmd} command.") else: filename = filename_param else: # @hexport filename filename = linesplit_space[1] return None, filename, None if len(linesplit_space) == 1: # @export raise ParseException(lineno, f"Invalid {cmd} command.") args = linesplit_space[1] expr0, filename = ParseUtil.split1_strip(args) expr = expr0 if filename is None: if len(filename_param) == 0: raise ParseException(lineno, f"No filename given to {cmd}.") else: filename = filename_param all_stimulus_elements = self.parameters.get(kw.STIMULUS_ELEMENTS) all_behaviors = self.parameters.get(kw.BEHAVIORS) err = None if cmd == kw.VEXPORT: expr, err = ParseUtil.parse_element_behavior( expr0, all_stimulus_elements, all_behaviors) elif cmd == kw.VSSEXPORT: expr, err = ParseUtil.parse_element_element( expr0, all_stimulus_elements) elif cmd == kw.PEXPORT: stimulus, behavior, err = ParseUtil.parse_stimulus_behavior( expr0, all_stimulus_elements, all_behaviors, self.variables) expr = (stimulus, behavior) elif cmd == kw.NEXPORT: expr, err = ParseUtil.parse_chain(expr0, all_stimulus_elements, all_behaviors) if err: raise ParseException(lineno, err) return expr, filename, expr0
def _parse_row(row, convert, fill_missing, use_cols): entries = [] for ix, column in enumerate(row): if not use_cols or ix in use_cols: # Only use data if in use_cols or no use_cols given column = column.strip() try: if column: try: converted = convert[str(ix)](column) # Convert it convert function given # If we get two values from one entry. Happens with input strings if type(converted) in (list, tuple): entries += converted else: entries.append(converted) except KeyError: # No converter defined entries.append(column) else: raise ParseException(0) except ParseException as e: if str(ix) in fill_missing: # Fill if for this column there is a fill value given entries += fill_missing[str(ix)] else: raise return entries
def add(self, run_obj, label, lineno): # , world, mechanism_obj, n_subjects): if label in self.runs: raise ParseException(lineno, f"Run label {label} is duplicated.") self.run_labels.append(label) self.runs[ label] = run_obj # ScriptRun(label, world, mechanism_obj, n_subjects)
def parse_value(self, expression): if isinstance(expression, NumericConstant): return expression.value else: if expression.symbol not in self.objects: raise ParseException( "Functions need to be instantiated to plain objects") return expression.symbol
def _parse_goto(self, goto_str, lineno, all_linelabels, global_variables): self.goto = list() err = f"Invalid condition '{goto_str}'. " lbls_and_probs = goto_str.split(',') lbls_and_probs = [lbl_and_prob.strip() for lbl_and_prob in lbls_and_probs] for lbl_and_prob in lbls_and_probs: if lbl_and_prob in all_linelabels: if len(lbls_and_probs) > 1: raise ParseException(lineno, f"Invalid condition '{goto_str}'.") self.goto.append([1, lbl_and_prob]) else: if '(' and ')' in lbl_and_prob: if lbl_and_prob.count('(') > 1 or lbl_and_prob.count(')') > 1: raise ParseException(lineno, err + "Too many parentheses.") lindex = lbl_and_prob.find('(') rindex = lbl_and_prob.find(')') if lindex > rindex: raise ParseException(lineno, err + "Mismatched parentheses.") lbl = lbl_and_prob[0:lindex] if lbl not in all_linelabels: raise ParseException(lineno, err + f"Unknown line label '{lbl}'.") prob_str = lbl_and_prob[(lindex + 1): rindex] isprob, prob = ParseUtil.is_prob(prob_str, global_variables) if not isprob: if prob is not None: raise ParseException(lineno, err + f"Expected a probability, got '{prob_str}'.") prob = prob_str for prob_lbl in self.goto: if prob_lbl[1] == lbl: raise ParseException(lineno, err + f"Label '{lbl}' duplicated.") self.goto.append([prob, lbl]) else: raise ParseException(lineno, err + f"Invalid line label '{goto_str}'.")
def next_line(self, response, global_variables, local_variables, event_counter): for i, condition in enumerate(self.conditions): omit_learn1 = self.phase_obj.perform_actions(self.lineno, condition.unconditional_actions) condition_met, label = condition.is_met(response, global_variables, local_variables, event_counter) if condition_met: omit_learn2 = self.phase_obj.perform_actions(self.lineno, condition.conditional_actions) return label, (omit_learn1 or omit_learn2) raise ParseException(self.lineno, f"No condition in '{self.logic_str}' was met for response '{response}'.")
def _parse_legend(self, lineno, linesplit_space): if len(linesplit_space) == 1: # @legend mpl_prop = dict() elif len(linesplit_space) == 2: # @legend {mpl_prop} arg = linesplit_space[1] is_dict, mpl_prop = ParseUtil.is_dict(arg) if not is_dict: raise ParseException(lineno, f"Invalid @legend argument {arg}.") return mpl_prop
def _goto_if_met(self, variables): goto_prob_cumsum = list() cumsum = 0 for i in range(len(self.goto)): prob = self.goto[i][0] if type(prob) is str: self.goto[i][0], err = ParseUtil.evaluate(prob, variables=variables) if err: raise ParseException(self.lineno, err) cumsum += self.goto[i][0] goto_prob_cumsum.append(cumsum) if cumsum > 1: raise ParseException(self.lineno, f"Sum of probabilities is {cumsum}>1.") ind = ParseUtil.weighted_choice(goto_prob_cumsum) if ind is None: return None else: return self.goto[ind][1]
def convert_timestamp(timestamp): if int(timestamp) > time.time(): timestamp = timestamp[:-3] ERRS[str(2)] += 1 try: date = datetime.utcfromtimestamp(int(timestamp)) except ValueError: raise ParseException(2) return date.isoformat(sep=' ')
def parse(self, parameters, global_variables): self.parameters = parameters self.global_variables = global_variables stimulus_elements = parameters.get(STIMULUS_ELEMENTS) behaviors = parameters.get(BEHAVIORS) phase_lines_afterlabel = list() linenos = list() # First iteration through lines: Create list of lines (and labels) for line_lineno in self.lines: line, lineno = line_lineno label, afterlabel = ParseUtil.split1_strip(line) if afterlabel is None: raise ParseException(lineno, "Phase line contains only label.") coincide_err = f"The phase line label '{label}' coincides with the name of a " if label in stimulus_elements: raise ParseException(lineno, coincide_err + "stimulus element.") elif label in behaviors: raise ParseException(lineno, coincide_err + "behavior.") if label in self.linelabels and not self.is_inherited: raise ParseException(lineno, f"Duplicate of phase line label '{label}'.") self.linelabels.append(label) phase_lines_afterlabel.append(afterlabel) linenos.append(lineno) if self.first_label is None: # Set self.first_label to the label of the first line self.first_label = label # Second iteration: Create PhaseLine objects and put in the dict self.phase_lines for label, after_label, lineno in zip(self.linelabels, phase_lines_afterlabel, linenos): self.phase_lines[label] = PhaseLine(self, lineno, label, after_label, self.linelabels, self.parameters, self.global_variables) if label == "new_trial": # Change self.first_label to the new_trial line self.first_label = label self.initialize_local_variables() self.event_counter = PhaseEventCounter(self.linelabels, self.parameters) self.subject_reset() self.is_parsed = True
def is_met(self, response, global_variables, local_variables, event_counter): variables_both = Variables.join(global_variables, local_variables) if self.condition is None: ismet = True elif self.condition_is_behavior: ismet = (self.condition == response) else: ismet, err = ParseUtil.evaluate(self.condition, variables_both, event_counter, ParseUtil.PHASE_LINE) if err: raise ParseException(self.lineno, err) if type(ismet) is not bool: raise ParseException(self.lineno, f"Condition '{self.condition}' is not a boolean expression.") if ismet: label = self._goto_if_met(variables_both) if label is None: # In "ROW1(0.1),ROW2(0.3)", goto_if_met returns None with prob. 0.6 ismet = False else: label = None return ismet, label
def parse(self, debug=False): stack = [self.T.END_OF_PROGRAM, self.axiom] a = self.next_token() node_stack = [self.root] while True: x = stack.pop() if x == self.T.END_OF_PROGRAM: break node = node_stack.pop() if x in self.T: if debug: print("STACK TOP T:", x.name) if x == a.tag: node.set_values(a, self.get_token_name(a)) a = self.next_token() else: raise ParseException(a.coords) else: if debug: print("STACK TOP NT:", x, ", CUR T:", self.token_repr(a)) _tuple = (a.tag, x) if _tuple in self.table: chain = list(self.table[_tuple]) while chain: symbol = chain.pop() if symbol in self.T: new_node = TerminalNode() else: new_node = NonTerminalNode(symbol) node.add_children(new_node) node_stack.append(new_node) stack.append(symbol) if debug: print("STACK:", stack) else: raise ParseException(a.coords)
def _check_symbol_in_initial_state(s, symbols): # A small helper if s == 'total-cost': # We ignore the 'total-cost' initial specification return False if util.is_external(s): raise RuntimeError( "The extension of an external symbol cannot ne specified in the initial state" ) if s not in symbols: raise ParseException("Unknown symbol: '{}'".format(s)) return True
def check_action(action, parameters, global_variables, lineno, all_linelabels): if action.count(':') == 1 or action.count('=') == 1: if action.count('=') == 1: sep = '=' else: sep = ':' var_name, _ = ParseUtil.split1_strip(action, sep=sep) var_err = is_valid_name(var_name, parameters, kw) if var_err is not None: raise ParseException(lineno, var_err) if global_variables.contains(var_name): raise ParseException(lineno, "Cannot modify global variable inside a phase.") elif action.startswith("count_reset(") and action.endswith(")"): behaviors = parameters.get(BEHAVIORS) stimulus_elements = parameters.get(STIMULUS_ELEMENTS) event = action[12:-1] if event not in stimulus_elements and event not in behaviors and event not in all_linelabels: raise ParseException(lineno, f"Unknown event '{event}' in count_reset.") elif action == "@omit_learn": pass else: raise ParseException(lineno, f"Unknown action '{action}'.")
def _perform_action(self, lineno, action): """ Sets a variable (x:3) or count_reset(event). """ omit_learn = False # No action to perform if len(action) == 0: pass # Setting a variable elif action.count(':') == 1 or action.count('=') == 1: if action.count('=') == 1: sep = '=' else: sep = ':' var_name, value_str = ParseUtil.split1_strip(action, sep=sep) variables_join = Variables.join(self.global_variables, self.local_variables) value, err = ParseUtil.evaluate(value_str, variables_join) if err: raise ParseException(lineno, err) err = self.local_variables.set(var_name, value, self.parameters) if err: raise ParseException(lineno, err) # count_reset elif action.startswith("count_reset(") and action.endswith(")"): event = action[12:-1] self.event_counter.reset_count(event) # omit_learn elif action == "@omit_learn": omit_learn = True else: raise ParseException(lineno, "Internal error.") # Should have been caught during Pase.parse() return omit_learn
def __init__(self, phase_obj, lineno, label, after_label, all_linelabels, parameters, global_variables): self.lineno = lineno self.label = label self.parameters = parameters self.all_linelabels = all_linelabels self.is_help_line = False self.stimulus = None # A dict with an intensity for each element in stimulus_elememts self.action = None self.action, logic = ParseUtil.split1_strip(after_label, sep=PHASEDIV) if logic is None: raise ParseException(lineno, f"Missing separator '{PHASEDIV}' on phase line.") action_list = ParseUtil.comma_split_strip(self.action) first_element, _, _ = ParseUtil.parse_element_and_intensity(action_list[0], variables=None, safe_intensity_eval=True) self.is_help_line = (len(action_list) == 1) and (first_element not in parameters.get(STIMULUS_ELEMENTS)) if self.is_help_line: self.stimulus = None if action_list[0] != '': check_action(action_list[0], parameters, global_variables, lineno, all_linelabels) else: self.stimulus, err = ParseUtil.parse_elements_and_intensities(self.action, global_variables, safe_intensity_eval=True) if err: raise ParseException(lineno, err) for element in self.stimulus: if element not in parameters.get(STIMULUS_ELEMENTS): raise ParseException(lineno, f"Expected a stimulus element, got '{element}'.") self.action = None if len(logic) == 0: raise ParseException(lineno, f"Line with label '{label}' has no conditions.") self.conditions = PhaseLineConditions(phase_obj, lineno, self.is_help_line, logic, parameters, all_linelabels, global_variables)
def parse_course_detail(content, doc_only): """parse course video and doc detail from response body or xxx.json file""" # json_file_path = os.path.join(output_folder, '{}.json'.format(tid)) # if os.path.exists(json_file_path): # return json.load(open(json_file_path, 'r', encoding='utf-8')) term = dict() last_week_name = '' last_lesson_name = '' for line in content.splitlines(): line = line.decode('unicode_escape') week_match = week_ptn.findall(line) if week_match: last_week_name = clean_filename(week_match[0]) term[last_week_name] = dict() logger.info(last_week_name) continue lesson_match = lesson_ptn.findall(line) if lesson_match and last_week_name in term: last_lesson_name = clean_filename(lesson_match[0]) term[last_week_name][last_lesson_name] = list() logger.info(' %s', last_lesson_name) continue if not doc_only: video_match = video_ptn.findall(line) if video_match and last_lesson_name in term[last_week_name]: content_id, _id, lecture_name, term_id = video_match[0] file_url = get_file_url(content_id, _id) postfix = 'mp4' if 'mp4' in file_url else 'flv' term[last_week_name][last_lesson_name].append( ('{}.{}'.format(lecture_name, postfix), file_url)) logger.info(' %s', '{}.{}'.format(lecture_name, postfix)) doc_match = doc_ptn.findall(line) if doc_match and last_lesson_name in term[last_week_name]: content_id, _id, lecture_name, term_id = doc_match[0] file_url = get_file_url(content_id, _id, file_type='doc') postfix = 'doc' if '.doc' in file_url else 'pdf' term[last_week_name][last_lesson_name].append( ('{}.{}'.format(lecture_name, postfix), file_url)) logger.info(' %s', '{}.{}'.format(lecture_name, postfix)) if last_week_name == '': raise ParseException('no video information in response body, %s' % content.decode('unicode_escape')) # dump_course_detail(term, json_file_path) return term
def _parse_frange_part(frange): """ Internal method: parse a discrete frame range part. :type frange: str :param frange: single part of a frame range as a string (ie "1-100x5") :rtype: tuple (start, end, modifier, chunk) :raises: :class:`fileseq.exceptions.ParseException` if the frame range can not be parsed """ match = FRANGE_RE.match(frange) if not match: msg = 'Could not parse "{0}": did not match {1}' raise ParseException(msg.format(frange, FRANGE_RE.pattern)) start, end, modifier, chunk = match.groups() start = int(start) end = int(end) if end is not None else start chunk = abs(int(chunk)) if chunk is not None else 1 # a zero chunk is just plain illogical if chunk == 0: msg = 'Could not parse "{0}": chunk cannot be 0' raise ParseException(msg.format(frange)) return start, end, modifier, chunk
def __init__(self, sequence): if not hasattr(self, '_frameSet'): self._frameSet = None try: # the main case, padding characters in the path.1-100#.exr path, frames, self._pad, self._ext = SPLIT_RE.split( sequence, 1) self._dir, self._base = os.path.split(path) self._frameSet = FrameSet(frames) except ValueError: # edge case 1; we've got an invalid pad for placeholder in PAD_MAP.keys(): if placeholder in sequence: msg = "Failed to parse FileSequence: {0}" raise ParseException(msg.format(sequence)) # edge case 2; we've got a single frame of a sequence a_frame = DISK_RE.match(sequence) if a_frame: self._dir, self._base, frames, self._ext = a_frame.groups() # edge case 3: we've got a single versioned file, not a sequence if frames and not self._base.endswith('.'): self._base = self._base + frames self._pad = '' elif not frames: self._pad = '' self._frameSet = None else: self._frameSet = FrameSet(frames) if self._frameSet: self._pad = FileSequence.getPaddingChars( len(frames)) else: self._pad = '' self._frameSet = None # edge case 4; we've got a solitary file, not a sequence else: path, self._ext = os.path.splitext(sequence) self._dir, self._base = os.path.split(path) self._pad = '' if self._dir: if not self._dir.endswith(os.sep): self._dir += os.sep else: self._dir = '' self._zfill = sum([PAD_MAP[c] for c in self._pad])
def _parse_run(self, after_run, lineno): """ Parses a @RUN line ("@RUN phase1,phase2,... [runlabel:lbl]") and returns the run label and a list of phase labels. """ match_objs_iterator = re.finditer(r' runlabel[\s]*:', after_run) match_objs = tuple(match_objs_iterator) n_matches = len(match_objs) if n_matches == 0: label = f'run{self.unnamed_run_cnt}' self.unnamed_run_cnt += 1 phases_str = after_run elif n_matches == 1: match_obj = match_objs[0] start_index = match_obj.start() + 1 # Index of "l" in "label" end_index = match_obj.end() # Index of character after ":" label = after_run[end_index:].strip() phases_str = after_run[0:start_index].strip() else: raise ParseException( lineno, f"Maximum one instance of 'runlabel:' on a {kw.RUN} line.") if label in self.all_run_labels: raise ParseException(lineno, f"Duplication of run label '{label}'.") else: self.all_run_labels.append(label) phase_labels = phases_str.strip(',').split(',') phase_labels = [phase_label.strip() for phase_label in phase_labels] for phase_label in phase_labels: if not self.phases.contains(phase_label): raise ParseException(lineno, f"Phase {phase_label} undefined.") return label, phase_labels
def main(url, username, password, output, doc_only): login(username, password) course_id = get_course_id_from_url(url) course_info = get_course_base_info(course_id, url) term = None for tid in course_info['tids'][::-1]: try: term = get_download_urls(tid, doc_only=doc_only) break except ParseException: logger.warning('开课id:{}未发现视频资源,本次开课已经关闭'.format(tid)) if term is None: raise ParseException('未找到视频资源,可能因为所有开课都已关闭') output_folder = get_output_course_folder(output, course_info['course_name'], course_info['university_name']) export_catalog(term, output_folder) download_file(term, output_folder)
def run(self, simulation_data, progress=None): self.parameters.scalar_expand( ) # If beta is not specified, scalar_expand has not been run filename = self.parameters.get(kw.EVAL_FILENAME) if len(filename) == 0: raise ParseException( self.lineno, f"Parameter {kw.EVAL_FILENAME} to {self.cmd} is mandatory.") # if not filename.endswith(".csv"): # filename = filename + ".csv" file = open(filename, 'w', newline='') try: if self.cmd == kw.HEXPORT: self._h_export(file, simulation_data) else: self._vwpn_export(file, simulation_data) except EvalException as ex: file.close() raise ex
def clean_script(text): lines = text.split('\n') in_comment_block = False lineno_multicomment_delimiter = 0 for lineno0, orig_line in enumerate(lines): lineno = lineno0 + 1 line = orig_line # Replace each tab with a space line = line.replace('\t', ' ') # Strip leading and trailing blanks line = line.strip() # Remove line comment and strip leading and trailing blanks after comment removal line_is_multicomment_delimiter = (line == '###') if not line_is_multicomment_delimiter: line = line.split('#')[0].strip() # Handle comment block if line_is_multicomment_delimiter: line = '' in_comment_block = not in_comment_block # Toggle status lineno_multicomment_delimiter = lineno # Line number used in error message if in_comment_block: line = '' if lineno == len(lines): msg = f"Comment block start '###' on line {lineno_multicomment_delimiter} has no matching end." raise ParseException(lineno, msg) lines[lineno0] = line # Remove all blank lines at the end of the script while lines and lines[-1] == '': lines.pop() return lines
def process_expression(self, exp): """ Process an arbitrary expression """ if isinstance(exp, FunctionalTerm): self.check_declared(exp.symbol) return self.process_functional_expression(exp) elif isinstance(exp, (Atom, NegatedAtom)): self.check_declared(exp.predicate) return self.process_predicative_expression(exp) elif isinstance(exp, ExistentialCondition): # return self.process_existential_expression(exp) return exp elif isinstance(exp, Conjunction): return ConjunctivePredicate(self.process_arguments(exp.parts)) elif isinstance(exp, conditions.Truth): return Truth() elif isinstance(exp, str): if exp[0] == '?': return ParameterExpression(exp) elif is_int(exp): return NumericExpression(exp) else: return ObjectExpression(exp) else: raise ParseException("Unknown expression type for expression '{}'".format(exp))
def __init__(self, frange): # if the user provides anything but a string, short-circuit the build if not isinstance(frange, basestring): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._items = frozenset(map(int, frange)) self._order = tuple(sorted(self._items)) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): items = set() order = unique(items, map(int, frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # in all other cases, cast to a string else: try: frange = str(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method self._frange = str(frange).translate(None, ''.join(PAD_MAP.keys())) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = FrameSet._parse_frange_part(part) # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': for stagger in xrange(chunk, 0, -1): frames = xfrange(start, end, stagger) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': not_good = frozenset(xfrange(start, end, chunk)) frames = xfrange(start, end, 1) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)
def convert_basestring(base_string): if 27 <= len(base_string) <= 34: return base_string else: raise ParseException(1)
def convert_sha256(input): if len(input) != 64: raise ParseException(3) else: return input