def apply2_(self, string, ni, nf, evaluation): 'StringTake[string_,{ni_Integer,nf_Integer}]' if not isinstance(string, String): return evaluation.message('StringTake', 'strse') if ni.value == 0 or nf.value == 0: return evaluation.message('StringTake', 'take', 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 of range return evaluation.message('StringTake', 'take', ni, nf, fullstring) if posf < posi: String("") return String(fullstring[(posi - 1):posf])
def message(self, symbol, tag, *args) -> None: from mathics.core.expression import (String, Symbol, Expression, from_python) # Allow evaluation.message('MyBuiltin', ...) (assume # System`MyBuiltin) symbol = ensure_context(symbol) quiet_messages = set(self.get_quiet_messages()) pattern = Expression('MessageName', Symbol(symbol), String(tag)) if pattern in quiet_messages or self.quiet_all: return # Shorten the symbol's name according to the current context # settings. This makes sure we print the context, if it would # be necessary to find the symbol that this message is # attached to. symbol_shortname = self.definitions.shorten_name(symbol) if settings.DEBUG_PRINT: print('MESSAGE: %s::%s (%s)' % (symbol_shortname, tag, args)) text = self.definitions.get_value(symbol, 'System`Messages', pattern, self) if text is None: pattern = Expression('MessageName', Symbol('General'), String(tag)) text = self.definitions.get_value('System`General', 'System`Messages', pattern, self) if text is None: text = String("Message %s::%s not found." % (symbol_shortname, tag)) text = self.format_output( Expression('StringForm', text, *(from_python(arg) for arg in args)), 'text') self.out.append(Message(symbol_shortname, tag, text)) self.output.out(self.out[-1])
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 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 get_op(op): if not isinstance(op, String): op = MakeBoxes(op, f) else: op_value = op.get_string_value() if (f.get_name() == 'System`InputForm' and op_value in ['*', '^']): pass elif (f.get_name() in ('System`InputForm', 'System`OutputForm') and not op_value.startswith(' ') and not op_value.endswith(' ')): op = String(' ' + op_value + ' ') return op
def apply_makeboxes(self, datetime, gran, cal, tz, fmt, evaluation): "MakeBoxes[DateObject[datetime_List, gran_, cal_, tz_, fmt_], StandardForm|TraditionalForm|OutputForm]" # TODO: if fmt.sameQ(Symbol("Automatic")): fmt = Expression("List", "DateTimeShort") fmtds = Expression("DateString", datetime, fmt).evaluate(evaluation) if fmtds is None: return # tz = Expression("ToString", tz).evaluate(evaluation) tz = int(tz.to_python()) tz = String(str(tz)) return Expression("RowBox", Expression("List", "[", fmtds, " GTM", tz, "]"))
def apply(self, text, evaluation): '''%(name)s[text_String]''' root = parse_xml(parse_xml_file, text, evaluation) if isinstance(root, Symbol): # $Failed? return root def lines(): for line in root.itertext(): s = line.strip() if s: yield s plaintext = String('\n'.join(lines())) return Expression('List', Expression('Rule', 'Plaintext', plaintext))
def apply(self, alpha, evaluation): """Alphabet[alpha_String]""" alphakey = alpha.get_string_value() alphakey = alphabet_alias[alphakey] if alphakey is None: evaluation.message("Alphabet", "nalph", alpha) return alphabet = alphabet_descriptions.get(alphakey, None) if alphabet is None: evaluation.message("Alphabet", "nalph", alpha) return return Expression(SymbolList, *[String(c) for c in alphabet["Lowercase"]])
def apply_string(self, s, evaluation, options): 'DeleteStopwords[s_String, OptionsPattern[%(name)s]]' doc = self._nlp(s.get_string_value(), evaluation, options) if doc: is_stop = self._is_stop_lambda(evaluation, options) if is_stop: def tokens(): for token in doc: if not is_stop(token.text): yield token.text_with_ws else: yield token.whitespace_.strip() return String(''.join(tokens()))
def convert_unit(leaves): mag = leaves[0] unit = leaves[1].get_string_value() quantity = Q_(mag, unit) converted_quantity = quantity.to_base_units() return Expression( "Quantity", converted_quantity.magnitude, String(converted_quantity.units), )
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 apply_general(self, expr, f, evaluation): 'MakeBoxes[expr_, f:TraditionalForm|StandardForm|OutputForm|InputForm|FullForm]' if expr.is_atom(): x = expr if isinstance(x, Symbol): return String(x.name) elif isinstance(x, String): return String('"' + x.value + '"') elif isinstance(x, (Integer, Real)): return x.make_boxes(f.get_name()) elif isinstance(x, (Rational, Complex)): return x.format(evaluation, f.get_name()) else: head = expr.head leaves = expr.leaves f_name = f.get_name() if f_name == 'TraditionalForm': left, right = '(', ')' else: left, right = '[', ']' result = [MakeBoxes(head, f), String(left)] if len(leaves) > 1: row = [] if f_name in ('InputForm', 'OutputForm', 'FullForm'): sep = ', ' else: sep = ',' for index, leaf in enumerate(leaves): if index > 0: row.append(String(sep)) row.append(MakeBoxes(leaf, f)) result.append(RowBox(Expression('List', *row))) elif len(leaves) == 1: result.append(MakeBoxes(leaves[0], f)) result.append(String(right)) return RowBox(Expression('List', *result))
def message(self, symbol, tag, *args): from mathics.core.expression import String, Symbol, Expression, from_python if (symbol, tag) in self.quiet_messages or self.quiet_all: return if settings.DEBUG_PRINT: print 'MESSAGE: %s::%s (%s)' % (symbol, tag, args) pattern = Expression('MessageName', Symbol(symbol), String(tag)) text = self.definitions.get_value(symbol, 'Messages', pattern, self) if text is None: pattern = Expression('MessageName', Symbol('General'), String(tag)) text = self.definitions.get_value('General', 'Messages', pattern, self) if text is None: text = String("Message %s::%s not found." % (symbol, tag)) text = self.format_output(Expression('StringForm', text, *(from_python(arg) for arg in args))) self.out.append(Message(symbol, tag, text)) if self.out_callback: self.out_callback(self.out[-1])
def apply_truncated(self, s, n, m, expression, evaluation): "StringRepeat[s_String, n_Integer, m_Integer]" py_n = n.get_int_value() if isinstance(n, Integer) else 0 py_m = m.get_int_value() if isinstance(m, Integer) else 0 if py_n < 1: evaluation.message("StringRepeat", "intp", 2, expression) elif py_m < 1: evaluation.message("StringRepeat", "intp", 3, expression) else: py_s = s.get_string_value() py_n = min(1 + py_m // len(py_s), py_n) return String((py_s * py_n)[:py_m])
def test_print(self): expr = Expression("Print", String("Hello world")) cfunc = _compile(expr, []) # XXX Hack to capture the output saved_stdout = sys.stdout try: out = io.StringIO() sys.stdout = out cfunc() output = out.getvalue().strip() self.assertEqual(output, "Hello world") finally: sys.stdout = saved_stdout
def apply3_(self, string, ni, evaluation): 'StringDrop[string_,{ni_Integer}]' if not isinstance(string, String): return evaluation.message('StringDrop', 'strse', string) if ni.value == 0: return evaluation.message('StringDrop', 'drop', 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('StringDrop', 'drop', ni, ni, fullstring) return String(fullstring[:(posi - 1)] + fullstring[posi:])
def t_file_filename(self, t): r''' (?P<quote>\"?) (?# Opening quotation mark) [a-zA-Z0-9\`/\.\\\!\-\:\_\$\*\~\?]+ (?# Literal characters) (?P=quote) (?# Closing quotation mark) ''' s = t.value if s.startswith('"'): s = s[1:-1] s = self.string_escape(s) s = s.replace('\\', '\\\\') t.value = String(s) t.lexer.begin('INITIAL') return t
def apply(self, text, evaluation): """%(name)s[text_String]""" root = parse_xml(parse_xml_file, text, evaluation) if isinstance(root, Symbol): # $Failed? return root def lines(): for line in root.itertext(): s = line.strip() if s: yield s plaintext = String("\n".join(lines())) return Expression("List", Expression("Rule", "Plaintext", plaintext))
def apply_with_ni(self, string, ni, evaluation): "StringDrop[string_,{ni_Integer}]" if not isinstance(string, String): return evaluation.message("StringDrop", "strse", string) if ni.value == 0: return evaluation.message("StringDrop", "drop", 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("StringDrop", "drop", ni, ni, fullstring) return String(fullstring[: (posi - 1)] + fullstring[posi:])
def node_to_xml_element(node, strip_whitespace=True): if lxml_available: if isinstance(node, ET._Comment): items = [ Expression(Expression('XMLObject', String('Comment')), String(node.text)) ] if node.tail is not None: items.append(String(node.tail)) return items def children(): text = node.text if text: if strip_whitespace: text = text.strip() if text: yield String(text) for child in node: for element in node_to_xml_element(child): yield element tail = node.tail if tail: if strip_whitespace: tail = tail.strip() if tail: yield String(tail) def attributes(): for name, value in node.attrib.items(): yield Expression('Rule', from_python(name), from_python(value)) return [ Expression('XMLElement', String(node.tag), Expression('List', *list(attributes())), Expression('List', *list(children()))) ]
def format_plus(self, items, evaluation): "Plus[items__]" def negate(item): if item.has_form("Times", 1, None): if isinstance(item.leaves[0], Number): neg = -item.leaves[0] if neg.sameQ(Integer1): 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, Number): return -item.to_sympy() else: return Expression("Times", -1, item) def is_negative(value): if isinstance(value, Complex): real, imag = value.to_sympy().as_real_imag() if real <= 0 and imag <= 0: return True elif isinstance(value, Number) and value.to_sympy() < 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 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, items, evaluation): 'StringJoin[items___]' result = '' items = items.flatten(Symbol('List')) 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 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 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 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 apply(self, expr, evaluation, options): "Compress[expr_, OptionsPattern[Compress]]" if isinstance(expr, String): string = '"' + expr.value + '"' else: string = expr.format(evaluation, "System`FullForm") string = string.boxes_to_text(evaluation=evaluation, show_string_characters=True) string = string.encode("utf-8") # TODO Implement other Methods # Shouldn't be this a ByteArray? result = zlib.compress(string) result = base64.b64encode(result).decode("utf8") return String(result)
def testBoxes(self): self.check('\\(1 \\^ 2\\)', 'SuperscriptBox["1", "2"]') self.check('\\(1 \\^ 2 \\% 3\\)', 'SubsuperscriptBox["1", "3", "2"]') self.check('\\(1 \\_ 2\\)', 'SubscriptBox["1", "2"]') self.check('\\(1 \\_ 2 \\% 3\\)', 'SubsuperscriptBox["1", "2", "3"]') self.check('\\( 1 \\& 2 \\)', 'OverscriptBox["1", "2"]') self.check('\\( 1 \\& 2 \\% 3 \\)', 'UnderoverscriptBox["1", "3", "2"]') self.check('\\( 1 \\+ 2 \\)', 'UnderscriptBox["1", "2"]') self.check('\\( 1 \\+ 2 \\% 3 \\)', 'UnderoverscriptBox["1", "2", "3"]') self.check('\\( 1 \\/ 2 \\)', 'FractionBox["1", "2"]') self.check('\\( \\@ 2 \\)', 'SqrtBox["2"]') self.check('\\( \\@ 2 \\% 3 \\)', 'RadicalBox["2", "3"]') self.check('\\( 1 \\` 2 \\)', 'FormBox["2", Removed["$$Failure"]]') self.check('\\( FullForm \\` 2 \\)', 'FormBox["2", FullForm]') self.check('\\( \\)', String("")) self.check('\\( a \\)', String("a")) self.check('\\( \\@ 1 \\_ 2 \\)', 'SqrtBox[SubscriptBox["1", "2"]]') self.check('\\( a + b \\)', 'RowBox[List["a", "+", "b"]]') self.check('\\(1 \\` 2\\)', Expression('FormBox', Integer(2), Integer(1)))
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(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)])