def apply(self, f, x, xstart, xstop, y, ystart, ystop, evaluation, options): 'DensityPlot[f_, {x_Symbol, xstart_, xstop_}, {y_Symbol, ystart_, ystop_}, OptionsPattern[DensityPlot]]' x = x.get_name() y = y.get_name() color_function = self.get_option(options, 'ColorFunction', evaluation, pop=True) color_function_scaling = self.get_option(options, 'ColorFunctionScaling', evaluation, pop=True) color_function_min = color_function_max = None if color_function.get_name() == 'Automatic': color_function = String('LakeColors') if color_function.get_string_value(): func = Expression('ColorData', color_function.get_string_value()).evaluate(evaluation) if func.has_form('ColorDataFunction', 4): color_function_min = func.leaves[2].leaves[0].get_real_value() color_function_max = func.leaves[2].leaves[1].get_real_value() color_function = Expression('Function', Expression(func.leaves[3], Expression('Slot', 1))) else: evaluation.message('DensityPlot', 'color', func) return if color_function.has_form('ColorDataFunction', 4): color_function_min = color_function.leaves[2].leaves[0].get_real_value() color_function_max = color_function.leaves[2].leaves[1].get_real_value() color_function_scaling = color_function_scaling.is_true() try: xstart, xstop, ystart, ystop = [value.to_number(n_evaluation=evaluation) for value in (xstart, xstop, ystart, ystop)] except NumberError, exc: expr = Expression('DensityPlot', f, Expression('List', x, xstart, xstop), Expression('List', y, ystart, ystop), *options_to_rules(options)) evaluation.message('DensityPlot', 'plln', exc.value, expr) return
def _load_spacy(self, evaluation, options): language_code = None language_name = self.get_option(options, 'Language', evaluation) if language_name is None: language_name = String('Undefined') if isinstance(language_name, String): language_code = _SpacyBuiltin._language_codes.get(language_name.get_string_value()) if not language_code: evaluation.message(self.get_name(), 'lang', language_name, strip_context(self.get_name())) return None instance = _SpacyBuiltin._spacy_instances.get(language_code) if instance: return instance try: if 'SPACY_DATA' in os.environ: instance = spacy.load(language_code, via=os.environ['SPACY_DATA']) else: instance = spacy.load(language_code) _SpacyBuiltin._spacy_instances[language_code] = instance return instance except RuntimeError as e: evaluation.message(self.get_name(), 'runtime', str(e)) return None
def apply_int(self, n, prop, evaluation): "ElementData[n_?IntegerQ, prop_]" from mathics.core.parser import parse py_n = n.to_python() py_prop = prop.to_python() # Check element specifier n or "name" if isinstance(py_n, int): if not 1 <= py_n <= 118: evaluation.message("ElementData", "noent", n) return elif isinstance(py_n, six.string_types): pass else: evaluation.message("ElementData", "noent", n) return # Check property specifier if isinstance(py_prop, six.string_types): py_prop = str(py_prop) if py_prop == '"Properties"': result = [] for i, p in enumerate(_ELEMENT_DATA[py_n]): if p not in ["NOT_AVAILABLE", "NOT_APPLICABLE", "NOT_KNOWN"]: result.append(_ELEMENT_DATA[0][i]) return from_python(sorted(result)) if not (isinstance(py_prop, six.string_types) and py_prop[0] == py_prop[-1] == '"' and py_prop.strip('"') in _ELEMENT_DATA[0]): evaluation.message("ElementData", "noprop", prop) return iprop = _ELEMENT_DATA[0].index(py_prop.strip('"')) result = _ELEMENT_DATA[py_n][iprop] if result == "NOT_AVAILABLE": return Expression("Missing", "NotAvailable") if result == "NOT_APPLICABLE": return Expression("Missing", "NotApplicable") if result == "NOT_KNOWN": return Expression("Missing", "Unknown") result = parse(result, evaluation.definitions) if isinstance(result, Symbol): result = String(strip_context(result.get_name())) return result
def apply(self, items, evaluation): "StringJoin[items___]" result = "" items = items.flatten(SymbolList) if items.get_head_name() == "System`List": items = items.leaves else: items = items.get_sequence() for item in items: if not isinstance(item, String): evaluation.message("StringJoin", "string") return result += item.value return String(result)
def apply3_(self, string, ni, evaluation): 'StringTake[string_,{ni_}]' if not isinstance(string, String): return evaluation.message('StringTake', 'strse') if ni.value == 0: return evaluation.message('StringTake', 'take', ni, ni) fullstring = string.get_string_value() lenfullstring = len(fullstring) posi = ni.value if posi < 0: posi = lenfullstring + posi + 1 if posi > lenfullstring or posi <= 0: return evaluation.message('StringTake', 'take', ni, ni, fullstring) return String(fullstring[(posi - 1):posi])
def apply_mathml(self, expr, evaluation): 'MakeBoxes[expr_, MathMLForm]' boxes = MakeBoxes(expr).evaluate(evaluation) try: xml = boxes.boxes_to_xml(evaluation=evaluation) except BoxError: evaluation.message( 'General', 'notboxes', Expression('FullForm', boxes).evaluate(evaluation)) xml = '' # mathml = '<math><mstyle displaystyle="true">%s</mstyle></math>' % xml # #convert_box(boxes) mathml = '<math>%s</math>' % xml # convert_box(boxes) return Expression('RowBox', Expression('List', String(mathml)))
def apply(self, pattern, evaluation): 'Names[pattern_]' pattern = pattern.get_string_value() if pattern is None: return names = set([]) for full_name in evaluation.definitions.get_matching_names(pattern): short_name = strip_context(full_name) names.add(short_name if short_name not in names else full_name) # TODO: Mathematica ignores contexts when it sorts the list of # names. return Expression('List', *[String(name) for name in sorted(names)])
def apply_makeboxes(self, items, sep, f, evaluation): 'MakeBoxes[Row[{items___}, sep_:""], f:StandardForm|TraditionalForm|OutputForm]' items = items.get_sequence() if not isinstance(sep, String): sep = MakeBoxes(sep, f) if len(items) == 1: return MakeBoxes(items[0], f) else: result = [] for index, item in enumerate(items): if index > 0 and not sep.same(String('')): result.append(sep) result.append(MakeBoxes(item, f)) return RowBox(Expression('List', *result))
def apply(self, items, evaluation): 'StringJoin[items___]' result = '' items = items.flatten(Symbol('List')) if items.get_head_name() == 'List': items = items.leaves else: items = items.get_sequence() for item in items: if not isinstance(item, String): evaluation.message('StringJoin', 'string') return result += item.value return String(result)
def __init__(self, add_builtin=False, builtin_filename=None): super(Definitions, self).__init__() self.builtin = {} self.user = {} if add_builtin: from mathics.builtin import modules, contribute from mathics.core.evaluation import Evaluation from mathics.settings import ROOT_DIR loaded = False if builtin_filename is not None: builtin_dates = [ get_file_time(module.__file__) for module in modules ] builtin_time = max(builtin_dates) if get_file_time(builtin_filename) > builtin_time: builtin_file = open(builtin_filename, 'r') self.builtin = pickle.load(builtin_file) loaded = True if not loaded: contribute(self) if builtin_filename is not None: builtin_file = open(builtin_filename, 'w') pickle.dump(self.builtin, builtin_file, -1) for root, dirs, files in os.walk( # noqa os.path.join(ROOT_DIR, 'autoload')): for path in [ os.path.join(root, f) for f in files if f.endswith('.m') ]: Expression('Get', String(path)).evaluate( Evaluation(None, self, timeout=30)) # Move any user definitions created by autoloaded files to # builtins, and clear out the user definitions list. This # means that any autoloaded definitions become shared # between users and no longer disappear after a Quit[]. # # Autoloads that accidentally define a name in Global` # could cause confusion, so check for this. # if any([name.startswith('Global`') for name in self.user]): raise ValueError("autoload defined a Global` symbol") self.builtin.update(self.user) self.user = {}
def xml_object(tree): declaration = [ Expression( Expression("XMLObject", String("Declaration")), Expression( "Rule", String("Version"), String(tree.docinfo.xml_version or "1.0") ), Expression( "Rule", String("Standalone"), String("yes") if tree.docinfo.standalone else String("no"), ), Expression("Rule", String("Encoding"), String(tree.docinfo.encoding)), ) ] return Expression( Expression("XMLObject", String("Document")), Expression("List", *declaration), *node_to_xml_element(tree.getroot()) )
def format_plus(self, items, evaluation): 'Plus[items__]' def negate(item): if item.has_form('Times', 1, None): if isinstance(item.leaves[0], (Integer, Rational, Real, Complex)): neg = Number.from_mp(-item.leaves[0].to_sympy()) if neg.same(Integer(1)): if len(item.leaves) == 1: return neg else: return Expression('Times', *item.leaves[1:]) else: return Expression('Times', neg, *item.leaves[1:]) else: return Expression('Times', -1, *item.leaves) elif isinstance(item, (Integer, Rational, Real, Complex)): return Number.from_mp(-item.to_sympy()) else: return Expression('Times', -1, item) def is_negative(value): if isinstance(value, (Integer, Rational, Real)) and value.to_sympy() < 0: return True if isinstance(value, Complex): real, imag = value.to_sympy().as_real_imag() if real <= 0 and imag <= 0: return True return False items = items.get_sequence() values = [Expression('HoldForm', item) for item in items[:1]] ops = [] for item in items[1:]: if (item.has_form('Times', 1, None) and is_negative(item.leaves[0])) or is_negative(item): item = negate(item) op = "-" else: op = "+" values.append(Expression('HoldForm', item)) ops.append(String(op)) return Expression('Infix', Expression('List', *values), Expression('List', *ops), 310, Symbol('Left'))
def format_output(self, expr): from mathics.core.expression import Expression, String, BoxError if self.format == 'text': result = expr.format(self, 'OutputForm') elif self.format == 'xml': result = Expression('StandardForm', expr).format(self, 'MathMLForm') elif self.format == 'tex': result = Expression('StandardForm', expr).format(self, 'TeXForm') else: raise ValueError try: boxes = result.boxes_to_text(evaluation=self) except BoxError: self.message('General', 'notboxes', String('%s' % result)) boxes = None return boxes
def testInstances(self): # duplicate instantiations of same content (like Integer 5) to test for potential instantiation randomness. _test_group( list( map( lambda f: (f(), f()), ( lambda: Integer(5), lambda: Rational(5, 2), lambda: MachineReal(5.12345678), lambda: Complex(Integer(5), Integer(2)), lambda: String("xy"), lambda: Symbol("xy"), ), ) ) )
def quiet_evaluate(expr, vars, evaluation, expect_list=False): """ Evaluates expr with given dynamic scoping values without producing arithmetic error messages. """ expr = Expression('N', expr) quiet_expr = Expression('Quiet', expr, Expression( 'List', Expression('MessageName', Symbol('Power'), String('infy')))) value = dynamic_scoping(quiet_expr.evaluate, vars, evaluation) if expect_list: if value.has_form('List', None): value = [chop(item).get_real_value() for item in value.leaves] if any(item is None for item in value): return None return value else: return None else: return chop(value).get_real_value()
def apply_tex(self, expr, evaluation): 'MakeBoxes[expr_, TeXForm]' boxes = MakeBoxes(expr).evaluate(evaluation) try: tex = boxes.boxes_to_tex(evaluation=evaluation) # Replace multiple newlines by a single one e.g. between asy-blocks tex = MULTI_NEWLINE_RE.sub('\n', tex) tex = tex.replace(' \uF74c', ' \, d') # tmp hack for Integrate except BoxError: evaluation.message( 'General', 'notboxes', Expression('FullForm', boxes).evaluate(evaluation)) tex = '' return Expression('RowBox', Expression('List', String(tex)))
def apply(self, f, x, xstart, xstop, y, ystart, ystop, evaluation, options): 'DensityPlot[f_, {x_Symbol, xstart_, xstop_}, {y_Symbol, ystart_, ystop_}, OptionsPattern[DensityPlot]]' x = x.get_name() y = y.get_name() color_function = self.get_option(options, 'ColorFunction', evaluation, pop=True) color_function_scaling = self.get_option(options, 'ColorFunctionScaling', evaluation, pop=True) color_function_min = color_function_max = None if color_function.get_name() == 'Automatic': color_function = String('LakeColors') if color_function.get_string_value(): func = Expression( 'ColorData', color_function.get_string_value()).evaluate(evaluation) if func.has_form('ColorDataFunction', 4): color_function_min = func.leaves[2].leaves[0].get_real_value() color_function_max = func.leaves[2].leaves[1].get_real_value() color_function = Expression( 'Function', Expression(func.leaves[3], Expression('Slot', 1))) else: evaluation.message('DensityPlot', 'color', func) return if color_function.has_form('ColorDataFunction', 4): color_function_min = color_function.leaves[2].leaves[ 0].get_real_value() color_function_max = color_function.leaves[2].leaves[ 1].get_real_value() color_function_scaling = color_function_scaling.is_true() try: xstart, xstop, ystart, ystop = [ value.to_number(n_evaluation=evaluation) for value in (xstart, xstop, ystart, ystop) ] except NumberError, exc: expr = Expression('DensityPlot', f, Expression('List', x, xstart, xstop), Expression('List', y, ystart, ystop), *options_to_rules(options)) evaluation.message('DensityPlot', 'plln', exc.value, expr) return
def p_boxes(self, args): '''boxTOKEN : box | boxTOKEN box boxes : boxTOKEN |''' if len(args) == 1: args[0] = String("") if len(args) == 2: if isinstance(args[1], list): if len(args[1]) > 1: args[0] = Expression('RowBox', *args[1]) else: args[0] = args[1][0] else: args[0] = [args[1]] elif len(args) == 3: args[1].append(args[2]) args[0] = args[1]
def xml_object(root): if lxml_available: tree = root.getroottree() declaration = [ Expression(Expression('XMLObject', String('Declaration')), Expression('Rule', String('Version'), String(tree.docinfo.xml_version)), Expression('Rule', String('Encoding'), String(tree.docinfo.encoding)))] else: declaration = [] return Expression( Expression('XMLObject', String('Document')), Expression('List', *declaration), *node_to_xml_element(root))
def apply(self, pattern, evaluation): "Names[pattern_]" headname = pattern.get_head_name() if headname == "System`StringExpression": pattern = re.compile(to_regex(pattern, evaluation)) else: pattern = pattern.get_string_value() if pattern is None: return names = set([]) for full_name in evaluation.definitions.get_matching_names(pattern): short_name = strip_context(full_name) names.add(short_name if short_name not in names else full_name) # TODO: Mathematica ignores contexts when it sorts the list of # names. return Expression("List", *[String(name) for name in sorted(names)])
def apply(self, var, evaluation): "GetEnvironment[var___]" if isinstance(var, String): env_var = var.get_string_value() tup = ( env_var, "System`None" if env_var not in os.environ else String(os.environ[env_var]), ) return Expression(SymbolRule, *tup) env_vars = var.get_sequence() if len(env_vars) == 0: rules = [ Expression(SymbolRule, name, value) for name, value in os.environ.items() ] return Expression(SymbolList, *rules)
def apply(self, word, evaluation, options): 'WordData[word_, OptionsPattern[%(name)s]]' if word.get_head_name() == 'System`StringExpression': return Expression('DictionaryLookup', word) elif isinstance(word, String) or word.get_head_name() == 'System`List': pass else: return wordnet, language_code = self._load_wordnet(evaluation, self._language_name(evaluation, options)) if not wordnet: return py_word = self._parse_word(word) if not py_word: return senses = self._senses(py_word, wordnet, language_code) return Expression('List', *[ [String(s) for s in desc] for syn, desc in senses])
def apply_with_ni_nf(self, string, ni, nf, evaluation): "StringDrop[string_,{ni_Integer,nf_Integer}]" if not isinstance(string, String): return evaluation.message("StringDrop", "strse", string) if ni.value == 0 or nf.value == 0: return evaluation.message("StringDrop", "drop", ni, nf) fullstring = string.get_string_value() lenfullstring = len(fullstring) posi = ni.value if posi < 0: posi = lenfullstring + posi + 1 posf = nf.value if posf < 0: posf = lenfullstring + posf + 1 if posf > lenfullstring or posi > lenfullstring or posf <= 0 or posi <= 0: # positions out or range return evaluation.message("StringDrop", "drop", ni, nf, fullstring) if posf < posi: return string # this is what actually mma does return String(fullstring[: (posi - 1)] + fullstring[posf:])
def autoload_files( defs, root_dir_path: str, autoload_dir: str, block_global_definitions: bool = True ): from mathics.core.evaluation import Evaluation # Load symbols from the autoload folder for root, dirs, files in os.walk(os.path.join(root_dir_path, autoload_dir)): for path in [os.path.join(root, f) for f in files if f.endswith(".m")]: Expression("Get", String(path)).evaluate(Evaluation(defs)) if block_global_definitions: # Move any user definitions created by autoloaded files to # builtins, and clear out the user definitions list. This # means that any autoloaded definitions become shared # between users and no longer disappear after a Quit[]. # # Autoloads that accidentally define a name in Global` # could cause confusion, so check for this. for name in defs.user: if name.startswith("Global`"): raise ValueError("autoload defined %s." % name)
def _property(self, word, py_property, py_form, evaluation, options): if py_property == 'PorterStem': if isinstance(word, String): return String(WordStem.porter(word.get_string_value())) else: return wordnet, language_code = self._load_wordnet(evaluation, self._language_name(evaluation, options)) if not wordnet: return py_word = self._parse_word(word) if not py_word: return if py_property == 'PartsOfSpeech': return self._parts_of_speech(py_word, wordnet, language_code) try: return self._standard_property(py_word, py_form, py_property, wordnet, language_code, evaluation) except MessageException as e: e.message(evaluation)
def apply(self, seq, evaluation): 'ToExpression[seq__]' # Organise Arguments py_seq = seq.get_sequence() if len(py_seq) == 1: (inp, form, head) = (py_seq[0], Symbol('InputForm'), None) elif len(py_seq) == 2: (inp, form, head) = (py_seq[0], py_seq[1], None) elif len(py_seq) == 3: (inp, form, head) = (py_seq[0], py_seq[1], py_seq[2]) else: assert len(py_seq) > 3 # 0 case handled by apply_empty evaluation.message('ToExpression', 'argb', 'ToExpression', Integer(len(py_seq)), Integer(1), Integer(3)) return # Apply the differnet forms if form == Symbol('InputForm'): if isinstance(inp, String): from mathics.core.parser import parse, ParseError try: result = parse( inp.get_string_value(), evaluation.definitions) except ParseError: evaluation.message('ToExpression', 'sntxi', String('')) return Symbol('$Failed') else: result = inp else: evaluation.message('ToExpression', 'interpfmt', form) return # Apply head if present if head is not None: result = Expression(head, result).evaluate(evaluation) return result
def apply_alpha_str(self, chars: List[Any], alpha: String, evaluation): "LetterNumber[chars_, alpha_String]" alphakey = alpha.get_string_value() alphakey = alphabet_alias.get(alphakey, None) if alphakey is None: evaluation.message("LetterNumber", "nalph", alpha) return if alphakey == "English": return self.apply(chars, evaluation) alphabet = alphabet_descriptions.get(alphakey, None) if alphabet is None: evaluation.message("LetterNumber", "nalph", alpha) return # TODO: handle Uppercase if isinstance(chars, String): py_chars = chars.get_string_value() if len(py_chars) == 1: # FIXME generalize ord("a") res = alphabet["Lowercase"].find(py_chars) + 1 if res == -1: res = alphabet["Uppercase"].find(py_chars) + 1 return Integer(res) else: r = [] for c in py_chars: cp = alphabet["Lowercase"].find(c) + 1 if cp == -1: cp = alphabet["Uppercase"].find(c) + 1 r.append(cp) return Expression(SymbolList, *r) elif chars.has_form("List", 1, None): result = [] for leaf in chars.leaves: result.append(self.apply_alpha_str(leaf, alpha, evaluation)) return Expression(SymbolList, *result) else: return evaluation.message(self.__class__.__name__, "nas", chars) return None
def apply(self, word, evaluation, options): 'SpellingCorrectionList[word_String, OptionsPattern[%(name)s]]' import enchant language_name = self.get_option(options, 'Language', evaluation) if not isinstance(language_name, String): return language_code = SpellingCorrectionList._languages.get( language_name.get_string_value(), None) if not language_code: return evaluation.message('SpellingCorrectionList', 'lang', language_name) d = SpellingCorrectionList._dictionaries.get(language_code, None) if not d: d = enchant.Dict(language_code) SpellingCorrectionList._dictionaries[language_code] = d py_word = word.get_string_value() if d.check(py_word): return Expression('List', word) else: return Expression('List', *[String(s) for s in d.suggest(py_word)])
def xml_object(root): if lxml_available: tree = root.getroottree() declaration = [ Expression( Expression("XMLObject", String("Declaration")), Expression("Rule", String("Version"), String(tree.docinfo.xml_version)), Expression("Rule", String("Encoding"), String(tree.docinfo.encoding)), ) ] else: declaration = [] return Expression(Expression("XMLObject", String("Document")), Expression("List", *declaration), *node_to_xml_element(root))
def apply(self, string, patt, evaluation, options): "StringSplit[string_, patt_, OptionsPattern[%(name)s]]" if string.get_head_name() == "System`List": leaves = [self.apply(s, patt, evaluation, options) for s in string._leaves] return Expression(SymbolList, *leaves) py_string = string.get_string_value() if py_string is None: return evaluation.message( "StringSplit", "strse", Integer1, Expression("StringSplit", string) ) if patt.has_form("List", None): patts = patt.get_leaves() else: patts = [patt] re_patts = [] for p in patts: py_p = to_regex(p, evaluation) if py_p is None: return evaluation.message("StringExpression", "invld", p, patt) re_patts.append(py_p) flags = re.MULTILINE if options["System`IgnoreCase"] == SymbolTrue: flags = flags | re.IGNORECASE result = [py_string] for re_patt in re_patts: result = [t for s in result for t in mathics_split(re_patt, s, flags=flags)] return string_list( SymbolList, [String(x) for x in result if x != ""], evaluation )
def construct_graphics(self, triangles, mesh_points, v_min, v_max, options, evaluation): mesh_option = self.get_option(options, "Mesh", evaluation) mesh = mesh_option.to_python() color_function = self.get_option(options, "ColorFunction", evaluation, pop=True) color_function_scaling = self.get_option(options, "ColorFunctionScaling", evaluation, pop=True) color_function_min = color_function_max = None if color_function.get_name() == "Automatic": color_function = String("LakeColors") if color_function.get_string_value(): func = Expression("ColorData", color_function.get_string_value()).evaluate(evaluation) if func.has_form("ColorDataFunction", 4): color_function_min = func.leaves[2].leaves[0].get_real_value() color_function_max = func.leaves[2].leaves[1].get_real_value() color_function = Expression("Function", Expression(func.leaves[3], Expression("Slot", 1))) else: evaluation.message("DensityPlot", "color", func) return if color_function.has_form("ColorDataFunction", 4): color_function_min = color_function.leaves[2].leaves[0].get_real_value() color_function_max = color_function.leaves[2].leaves[1].get_real_value() color_function_scaling = color_function_scaling.is_true() v_range = v_max - v_min if v_range == 0: v_range = 1 if color_function.has_form("ColorDataFunction", 4): color_func = color_function.leaves[3] else: color_func = color_function if color_function_scaling and color_function_min is not None and color_function_max is not None: color_function_range = color_function_max - color_function_min colors = {} def eval_color(x, y, v): v_scaled = (v - v_min) / v_range if color_function_scaling and color_function_min is not None and color_function_max is not None: v_color_scaled = color_function_min + v_scaled * color_function_range else: v_color_scaled = v v_lookup = int(v_scaled * 100 + 0.5) # calculate and store 100 different shades max. value = colors.get(v_lookup) if value is None: value = Expression(color_func, Real(v_color_scaled)) value = value.evaluate(evaluation) colors[v_lookup] = value return value points = [] vertex_colors = [] graphics = [] for p1, p2, p3 in triangles: c1, c2, c3 = eval_color(*p1), eval_color(*p2), eval_color(*p3) points.append( Expression( "List", Expression("List", *p1[:2]), Expression("List", *p2[:2]), Expression("List", *p3[:2]) ) ) vertex_colors.append(Expression("List", c1, c2, c3)) graphics.append( Expression( "Polygon", Expression("List", *points), Expression("Rule", Symbol("VertexColors"), Expression("List", *vertex_colors)), ) ) if mesh == "Full": for xi in range(len(mesh_points)): line = [] for yi in range(len(mesh_points[xi])): line.append(Expression("List", mesh_points[xi][yi][0], mesh_points[xi][yi][1])) graphics.append(Expression("Line", Expression("List", *line))) elif mesh == "All": for p1, p2, p3 in triangles: line = [from_python(p1[:2]), from_python(p2[:2]), from_python(p3[:2])] graphics.append(Expression("Line", Expression("List", *line))) return graphics
def create_infix(items, operator, prec, grouping): if len(items) == 1: return items[0] else: return Expression('Infix', Expression('List', *items), String(operator), prec, Symbol(grouping))
def construct_graphics(self, triangles, mesh_points, v_min, v_max, options, evaluation): mesh_option = self.get_option(options, 'Mesh', evaluation) mesh = mesh_option.to_python() color_function = self.get_option( options, 'ColorFunction', evaluation, pop=True) color_function_scaling = self.get_option( options, 'ColorFunctionScaling', evaluation, pop=True) color_function_min = color_function_max = None if color_function.get_name() == 'Automatic': color_function = String('LakeColors') if color_function.get_string_value(): func = Expression( 'ColorData', color_function.get_string_value()).evaluate(evaluation) if func.has_form('ColorDataFunction', 4): color_function_min = func.leaves[2].leaves[0].get_real_value() color_function_max = func.leaves[2].leaves[1].get_real_value() color_function = Expression('Function', Expression( func.leaves[3], Expression('Slot', 1))) else: evaluation.message('DensityPlot', 'color', func) return if color_function.has_form('ColorDataFunction', 4): color_function_min = \ color_function.leaves[2].leaves[0].get_real_value() color_function_max = \ color_function.leaves[2].leaves[1].get_real_value() color_function_scaling = color_function_scaling.is_true() v_range = v_max - v_min if v_range == 0: v_range = 1 if color_function.has_form('ColorDataFunction', 4): color_func = color_function.leaves[3] else: color_func = color_function if (color_function_scaling and # noqa color_function_min is not None and color_function_max is not None): color_function_range = color_function_max - color_function_min colors = {} def eval_color(x, y, v): v_scaled = (v - v_min) / v_range if (color_function_scaling and # noqa color_function_min is not None and color_function_max is not None): v_color_scaled = color_function_min + \ v_scaled * color_function_range else: v_color_scaled = v # Calculate and store 100 different shades max. v_lookup = int(v_scaled * 100 + 0.5) value = colors.get(v_lookup) if value is None: value = Expression(color_func, Real(v_color_scaled)) value = value.evaluate(evaluation) colors[v_lookup] = value return value points = [] vertex_colors = [] graphics = [] for p in triangles: points.append( Expression('List', *(Expression('List', *x[:2]) for x in p))) vertex_colors.append( Expression('List', *(eval_color(*x) for x in p))) graphics.append(Expression( 'Polygon', Expression('List', *points), Expression('Rule', Symbol('VertexColors'), Expression('List', *vertex_colors)))) if mesh == 'Full': for xi in range(len(mesh_points)): line = [] for yi in range(len(mesh_points[xi])): line.append(Expression('List', mesh_points[xi][yi][0], mesh_points[xi][yi][1])) graphics.append(Expression('Line', Expression('List', *line))) elif mesh == 'All': for p in triangles: graphics.append(Expression( 'Line', Expression('List', *(from_python(x[:2]) for x in p)))) return graphics
def apply(self, symbol, evaluation): "SymbolName[symbol_Symbol]" # MMA docs say "SymbolName always gives the short name, # without any context" return String(strip_context(symbol.get_name()))