def attributes(): for name, value in node.attrib.items(): if name == 'xmlns': name = _namespace_key else: name = from_python(name) yield Expression('Rule', name, from_python(value))
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() graphics = [] for p1, p2, p3 in triangles: graphics.append( Expression( "Polygon", Expression("List", Expression("List", *p1), Expression("List", *p2), Expression("List", *p3)), ) ) # Add the Grid 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], mesh_points[xi][yi][2]) ) graphics.append(Expression("Line", Expression("List", *line))) elif mesh == "All": for p1, p2, p3 in triangles: line = [from_python(p1), from_python(p2), from_python(p3)] graphics.append(Expression("Line", Expression("List", *line))) return graphics
def apply_makeboxes(self, expr, n, f, evaluation): '''MakeBoxes[BaseForm[expr_, n_], f:StandardForm|TraditionalForm|OutputForm]''' base = n.get_int_value() if base <= 0: evaluation.message('BaseForm', 'intpm', expr, n) return if not (isinstance(expr, Integer) or isinstance(expr, Real)): return Expression("MakeBoxes", expr, f) p = dps(expr.get_precision()) if isinstance(expr, Real) else 0 try: val = convert_base(expr.get_real_value(), base, p) except ValueError: return evaluation.message('BaseForm', 'basf', n) if f.get_name() == 'System`OutputForm': return from_python("%s_%d" % (val, base)) else: return Expression( 'SubscriptBox', from_python(val), from_python(base))
def apply(self, interval, n, evaluation): 'RandomPrime[interval_?ListQ, n_]' if not isinstance(n, Integer): evaluation.message('RandomPrime', 'posdim', n) return py_n = n.to_python() py_int = interval.to_python() if not (isinstance(py_int, list) and len(py_int) == 2): evaluation.message('RandomPrime', 'prmrng', interval) imin, imax = min(py_int), max(py_int) if imin <= 0 or not isinstance(imin, int): evaluation.message('RandomPrime', 'posint', interval.leaves[0]) return if imax <= 0 or not isinstance(imax, int): evaluation.message('RandomPrime', 'posint', interval.leaves[1]) return try: if py_n == 1: return from_python(sympy.ntheory.randprime(imin, imax + 1)) return from_python([sympy.ntheory.randprime(imin, imax + 1) for i in range(py_n)]) except ValueError: evaluation.message('RandomPrime', 'noprime') return
def apply_spec(self, epochtime, evaluation): 'AbsoluteTime[epochtime_]' datelist = self.to_datelist(epochtime, evaluation) if datelist is None: return date = _Date(datelist=datelist) tdelta = date.date - EPOCH_START if tdelta.microseconds == 0: return from_python(int(total_seconds(tdelta))) return from_python(total_seconds(tdelta))
def apply_min(self, xmin, ymin, zmin, evaluation): 'Cuboid[{xmin_, ymin_, zmin_}]' xmin, ymin, zmin = [value.round_to_float(evaluation) for value in (xmin, ymin, zmin)] if None in (xmin, ymin, zmin): return # TODO (xmax, ymax, zmax) = (from_python(value + 1) for value in (xmin, ymin, zmin)) (xmin, ymin, zmin) = (from_python(value) for value in (xmin, ymin, zmin)) return self.apply_full(xmin, ymin, zmin, xmax, ymax, zmax, evaluation)
def apply_min(self, xmin, ymin, zmin, evaluation): 'Cuboid[{xmin_, ymin_, zmin_}]' try: xmin, ymin, zmin = [value.to_number( n_evaluation=evaluation) for value in (xmin, ymin, zmin)] except NumberError: # TODO return (xmax, ymax, zmax) = (from_python(value + 1) for value in (xmin, ymin, zmin)) (xmin, ymin, zmin) = (from_python(value) for value in (xmin, ymin, zmin)) return self.apply_full(xmin, ymin, zmin, xmax, ymax, zmax, evaluation)
def message(self, symbol, tag, *args): 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 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 pyobject(self, ex, obj): from mathics.core import expression from mathics.core.expression import Number if obj is None: return expression.Symbol('Null') elif isinstance(obj, (list, tuple)) or is_Vector(obj): return expression.Expression('List', *(from_sage(item, self.subs) for item in obj)) elif isinstance(obj, Constant): return expression.Symbol(obj._conversions.get('mathematica', obj._name)) elif is_Integer(obj): return expression.Integer(str(obj)) elif isinstance(obj, sage.Rational): rational = expression.Rational(str(obj)) if rational.value.denom() == 1: return expression.Integer(rational.value.numer()) else: return rational elif isinstance(obj, sage.RealDoubleElement) or is_RealNumber(obj): return expression.Real(str(obj)) elif is_ComplexNumber(obj): real = Number.from_string(str(obj.real())).value imag = Number.from_string(str(obj.imag())).value return expression.Complex(real, imag) elif isinstance(obj, NumberFieldElement_quadratic): # TODO: this need not be a complex number, but we assume so! real = Number.from_string(str(obj.real())).value imag = Number.from_string(str(obj.imag())).value return expression.Complex(real, imag) else: return expression.from_python(obj)
def apply(self, f, expr, n, evaluation): 'FixedPointList[f_, expr_, n_:DirectedInfinity[1]]' if n == Expression('DirectedInfinity', 1): count = None else: count = n.get_int_value() if count is None or count < 0: evaluation.message('FixedPoint', 'intnn') return interm = expr result = [interm] index = 0 while count is None or index < count: evaluation.check_stopped() new_result = Expression(f, interm).evaluate(evaluation) result.append(new_result) if new_result == interm: break interm = new_result index += 1 return from_python(result)
def apply(self, string, patt, evaluation, options): 'StringSplit[string_, patt_, OptionsPattern[%(name)s]]' py_string = string.get_string_value() if py_string is None: return evaluation.message('StringSplit', 'strse', Integer(1), 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) if py_p is None: return evaluation.message('StringExpression', 'invld', p, patt) re_patts.append(py_p) flags = re.MULTILINE if options['System`IgnoreCase'] == Symbol('True'): 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 from_python([x for x in result if x != ''])
def compute(user_hash, py_hashtype): hash_func = Hash._supported_hashes.get(py_hashtype) if hash_func is None: # unknown hash function? return # in order to return original Expression h = hash_func() user_hash(h.update) return from_python(int(h.hexdigest(), 16))
def fold(self, x, l): # computes fold(x, l) with the internal _fold function. will start # its evaluation machine precision, and will escalate to arbitrary # precision if or symbolical evaluation only if necessary. folded # items already computed are carried over to new evaluation modes. yield x # initial state init = None operands = list(self._operands(x, l)) spans = self._spans(operands) for mode in (self.FLOAT, self.MPMATH, self.SYMBOLIC): s_operands = [y[1:] for y in operands[spans[mode]]] if not s_operands: continue if mode == self.MPMATH: from mathics.core.numbers import min_prec precision = min_prec(*[t for t in chain(*s_operands) if t is not None]) working_precision = mpmath.workprec else: @contextmanager def working_precision(_): yield precision = None if mode == self.FLOAT: def out(z): return Real(z) elif mode == self.MPMATH: def out(z): return Real(z, precision) else: def out(z): return z as_operand = self.operands.get(mode) def converted_operands(): for y in s_operands: yield tuple(as_operand(t) for t in y) with working_precision(precision): c_operands = converted_operands() if init is not None: c_init = tuple((None if t is None else as_operand(from_python(t))) for t in init) else: c_init = next(c_operands) init = tuple((None if t is None else out(t)) for t in c_init) generator = self._fold( c_init, c_operands, self.math.get(mode)) for y in generator: y = tuple(out(t) for t in y) yield y init = y
def apply(self, n, k, evaluation): 'NextPrime[n_?NumericQ, k_?IntegerQ]' py_k = k.to_python(n_evaluation=evaluation) py_n = n.to_python(n_evaluation=evaluation) if py_k >= 0: return from_python(sympy.ntheory.nextprime(py_n, py_k)) # Hack to get earlier primes result = n.to_python() for i in range(-py_k): try: result = sympy.ntheory.prevprime(result) except ValueError: # No earlier primes return from_python(-1 * sympy.ntheory.nextprime(0, py_k - i)) return from_python(result)
def apply(self, filename, evaluation): 'Import[filename_]' result = self.importer(filename, evaluation) if result is None: return Symbol('$Failed') return from_python(result['Data'])
def _add_continuous_widget(self, symbol, label, default, minimum, maximum, evaluation): minimum_value = minimum.to_python() maximum_value = maximum.to_python() if minimum_value > maximum_value: raise IllegalWidgetArguments(symbol) else: defval = min(max(default.to_python(), minimum_value), maximum_value) widget = _create_widget(FloatSlider, value=defval, min=minimum_value, max=maximum_value) self._add_widget(widget, symbol.get_name(), lambda x: from_python(x), label)
def print_out(self, text): from mathics.core.expression import from_python text = self.format_output(from_python(text), 'text') self.out.append(Print(text)) self.output.out(self.out[-1]) if settings.DEBUG_PRINT: print('OUT: ' + text)
def apply_elements(self, filename, elements, evaluation): 'Import[filename_, elements_]' elements = elements.to_python() if not (isinstance(elements, basestring) and elements[0] == elements[-1] == '"'): return Symbol('$Failed') elements = elements.strip('"') result = self.importer(filename, evaluation) if result is None: return Symbol('$Failed') if elements == "Elements": result = result.keys() result.sort() return from_python(result) return from_python(result[elements])
def apply_makeboxes(self, expr, n, f, evaluation): """MakeBoxes[BaseForm[expr_, n_], f:StandardForm|TraditionalForm|OutputForm]""" base = n.get_int_value() if base <= 0: evaluation.message("BaseForm", "intpm", expr, n) return if not (isinstance(expr, Integer) or isinstance(expr, Real)): return Expression("MakeBoxes", expr, f) p = dps(expr.get_precision()) if isinstance(expr, Real) else 0 val = convert_base(expr.get_real_value(), base, p) if f.get_name() == "OutputForm": return from_python("%s_%d" % (val, base)) else: return Expression("SubscriptBox", from_python(val), from_python(base))
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, string, seps, evaluation): 'StringSplit[string_String, seps_List]' py_string, py_seps = string.get_string_value(), seps.get_leaves() result = [py_string] for py_sep in py_seps: if not isinstance(py_sep, String): evaluation.message('StringSplit', 'strse', Integer(2), Expression('StringSplit', string, seps)) return py_seps = [py_sep.get_string_value() for py_sep in py_seps] for py_sep in py_seps: result = [t for s in result for t in s.split(py_sep)] return from_python(filter(lambda x: x != u'', result))
def apply(self, f, expr, n, evaluation): 'NestList[f_, expr_, n_Integer]' n = n.get_int_value() if n is None or n < 0: return interm = expr result = [interm] for k in range(n): interm = Expression(f, interm).evaluate(evaluation) result.append(interm) return from_python(result)
def _add_discrete_widget(self, symbol, label, default, minimum, maximum, step, evaluation): minimum_value = minimum.to_python() maximum_value = maximum.to_python() step_value = step.to_python() if minimum_value > maximum_value or step_value <= 0 or step_value > (maximum_value - minimum_value): raise IllegalWidgetArguments(symbol) else: default_value = min(max(default.to_python(), minimum_value), maximum_value) if all(isinstance(x, Integer) for x in [minimum, maximum, default, step]): widget = _create_widget(IntSlider, value=default_value, min=minimum_value, max=maximum_value, step=step_value) else: widget = _create_widget(FloatSlider, value=default_value, min=minimum_value, max=maximum_value, step=step_value) self._add_widget(widget, symbol.get_name(), lambda x: from_python(x), label)
def apply(self, filename, evaluation): 'FileFormat[filename_?StringQ]' path = filename.to_python().strip('"') if path.startswith("ExampleData/"): path = ROOT_DIR + 'data/' + path if not os.path.exists(path): evaluation.message('FileFormat', 'nffil', Expression('FileFormat', filename)) return Symbol('$Failed') if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mimetypes = FileFormat.detector.match(path) mimetypes = set(mimetypes) #TODO: Add more file formats result = 'Binary' if 'image/gif' in mimetypes: result = 'GIF' elif 'image/jpeg' in mimetypes: result = 'JPEG' elif 'application/pdf' in mimetypes: result = 'PDF' elif 'image/png' in mimetypes: result = 'PNG' elif 'image/tiff' in mimetypes: result = 'TIFF' else: for mimetype in mimetypes: if mimetype.startswith('text'): result = 'Text' break elif 'xml' in mimetype: result = 'XML' break else: # TODO: text file recognition is not perfect if path.lower().endswith('.txt'): result = 'Text' return from_python(result)
def apply_name(self, name, prop, evaluation): "ElementData[name_?StringQ, prop_]" py_name = name.to_python().strip('"') names = ['StandardName', 'Name', 'Abbreviation'] iprops = [_ELEMENT_DATA[0].index(s) for s in names] indx = None for iprop in iprops: try: indx = [element[iprop] for element in _ELEMENT_DATA[1:]].index(py_name) + 1 except ValueError: pass if indx is None: evaluation.message("ElementData", "noent", name) return return self.apply_int(from_python(indx), prop, evaluation)
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message( 'FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) result = [] for key in mimetype_dict.keys(): if key in mime: result.append(mimetype_dict[key]) # the following fixes an extremely annoying behaviour on some (not all) # installations of Windows, where we end up classifying .csv files als XLS. if len(result) == 1 and result[0] == 'XLS' and path.lower().endswith('.csv'): return String('CSV') if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def apply(self, string, rule, evaluation): 'StringReplace[string_, rule_]' args = self.check_arguments(string, rule, None, evaluation) if args is None: return None (py_string, py_rules) = args def do_replace(s): for sp in py_rules: s = s.replace(sp[0], sp[1]) return s if isinstance(py_string, list): result = [do_replace(s) for s in py_string] else: result = do_replace(py_string) return from_python(result)
def apply(self, n, b, evaluation): 'IntegerExponent[n_, b_]' py_n, py_b = n.to_python(), b.to_python() expr = Expression('InegerExponent', n, b) if not (isinstance(py_n, int) or isinstance(py_n, long)): evaluation.message('IntegerExponent', 'int', expr) py_n = abs(py_n) if not (isinstance(py_b, int) and py_b > 1): evaluation.message('IntegerExponent', 'ibase', b) #TODO: Optimise this (dont need to calc. base^result) result = 1 while py_n % (py_b**result) == 0: result += 1 return from_python(result-1)
def apply(self, n, b, evaluation): 'IntegerExponent[n_Integer, b_Integer]' py_n, py_b = n.to_python(), b.to_python() expr = Expression('IntegerExponent', n, b) if not isinstance(py_n, six.integer_types): evaluation.message('IntegerExponent', 'int', expr) py_n = abs(py_n) if not (isinstance(py_b, int) and py_b > 1): evaluation.message('IntegerExponent', 'ibase', b) # TODO: Optimise this (dont need to calc. base^result) # NOTE: IntegerExponent[a,b] causes a Python error here when a or b are # symbols result = 1 while py_n % (py_b ** result) == 0: result += 1 return from_python(result - 1)
def apply(self, string, evaluation): "ToCharacterCode[string_]" exp = Expression('ToCharacterCode', string) if string.has_form('List', None): string = [ substring.get_string_value() for substring in string.leaves ] if any(substring is None for substring in string): evaluation.message('ToCharacterCode', 'strse', Integer(1), exp) return None else: string = string.get_string_value() if string is None: evaluation.message('ToCharacterCode', 'strse', Integer(1), exp) return None if isinstance(string, list): codes = [[ord(char) for char in substring] for substring in string] elif isinstance(string, basestring): codes = [ord(char) for char in string] return from_python(codes)
def apply(self, argnames, expr, code, args, evaluation): 'CompiledFunction[argnames_, expr_, code_CompiledCode][args__]' argseq = args.get_sequence() if len(argseq) != len(code.args): return py_args = [] for arg in argseq: if isinstance(arg, Integer): py_args.append(arg.get_int_value()) elif arg.same(Symbol('True')): py_args.append(True) elif arg.same(Symbol('False')): py_args.append(False) else: py_args.append(arg.round_to_float(evaluation)) try: result = code.cfunc(*py_args) except (TypeError, ctypes.ArgumentError): return evaluation.message('CompiledFunction', 'argerr', args) return from_python(result)
def apply_n(self, string, rule, n, evaluation): 'StringReplace[string_, rule_, n_]' args = self.check_arguments(string, rule, n, evaluation) if args is None: return None (py_string, py_rules, py_n) = args def do_replace(s): for sp in py_rules: if py_n is None: s = s.replace(sp[0], sp[1]) else: s = s.replace(sp[0], sp[1], py_n) return s if isinstance(py_string, list): result = [do_replace(s) for s in py_string] else: result = do_replace(py_string) return from_python(result)
def apply(self, epochtime, form, evaluation): 'DateString[epochtime_, form_]' datelist = self.to_datelist(epochtime, evaluation) if datelist is None: return date = _Date(datelist=datelist) pyform = form.to_python() if not isinstance(pyform, list): pyform = [pyform] pyform = [x.strip('"') for x in pyform] if not all(isinstance(f, six.string_types) for f in pyform): evaluation.message('DateString', 'fmt', form) return datestrs = [] for p in pyform: if str(p) in DATE_STRING_FORMATS.keys(): # FIXME: Years 1900 before raise an error tmp = date.date.strftime(DATE_STRING_FORMATS[p]) if str(p).endswith("Short") and str(p) != "YearShort": if str(p) == "DateTimeShort": tmp = tmp.split(' ') tmp = ' '.join([s.lstrip('0') for s in tmp[:-1]] + [tmp[-1]]) else: tmp = ' '.join([s.lstrip('0') for s in tmp.split(' ')]) else: tmp = str(p) datestrs.append(tmp) return from_python(''.join(datestrs))
def evaluate(self, evaluation): return from_python(sorted(EXPORTERS.keys()))
def apply(self, filename, elements, evaluation): 'Import[filename_, elements_]' # Check filename path = filename.to_python() if not (isinstance(path, basestring) and path[0] == path[-1] == '"'): evaluation.message('Import', 'chtype', filename) return Symbol('$Failed') findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('Import', 'nffil') return findfile # Check elements if elements.has_form('List', None): elements = elements.get_leaves() else: elements = [elements] for el in elements: if not isinstance(el, String): evaluation.message('Import', 'noelem', el) return Symbol('$Failed') elements = [el.get_string_value() for el in elements] # Determine file type for el in elements: if el in IMPORTERS.keys(): filetype = el elements.remove(el) break else: filetype = Expression( 'FileFormat', findfile).evaluate(evaluation=evaluation).get_string_value() if filetype not in IMPORTERS.keys(): evaluation.message('Import', 'fmtnosup', filetype) return Symbol('$Failed') # Load the importer (conditionals, default_function, posts, importer_options) = IMPORTERS[filetype] # XXX OptionsIssue # function_channels = importer_options.get(String("FunctionChannels")) function_channels = importer_options.get(Symbol("FunctionChannels")) # XXX OptionsIssue # default_element = importer_options.get(String("DefaultElement")) default_element = importer_options.get(Symbol("DefaultElement")) def get_results(tmp_function): if function_channels == Expression('List', String('FileNames')): tmp = Expression(tmp_function, findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenRead', findfile).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') return None tmp = Expression(tmp_function, stream).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO print appropriate error message raise NotImplementedError tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} return dict((a.get_string_value(), b) for (a, b) in map(lambda x: x.get_leaves(), tmp)) # Perform the import defaults = None if elements == []: defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') if default_element == Symbol("Automatic"): return Expression( 'List', *(Expression('Rule', String(key), defaults[key]) for key in defaults.keys())) else: result = defaults.get(default_element.get_string_value()) if result is None: evaluation.message('Import', 'noelem', default_element, from_python(filetype)) return Symbol('$Failed') return result else: assert len(elements) == 1 el = elements[0] if el == "Elements": defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') # Use set() to remove duplicates return from_python( sorted( set(conditionals.keys() + defaults.keys() + posts.keys()))) else: if el in conditionals.keys(): result = get_results(conditionals[el]) if result is None: return Symbol('$Failed') if len(result.keys()) == 1 and result.keys()[0] == el: return result.values()[0] elif el in posts.keys(): # TODO: allow use of conditionals result = get_results(posts[el]) if result is None: return Symbol('$Failed') else: if defaults is None: defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') if el in defaults.keys(): return defaults[el] else: evaluation.message('Import', 'noelem', from_python(el), from_python(filetype)) return Symbol('$Failed')
Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmin, ymax, zmin), Expression('List', xmax, ymax, zmin)), Expression('List', Expression('List', xmin, ymin, zmin), Expression('List', xmax, ymin, zmin), Expression('List', xmax, ymax, zmin)), Expression('List', Expression('List', xmin, ymin, zmax), Expression('List', xmin, ymax, zmax), Expression('List', xmax, ymax, zmax)), Expression('List', Expression('List', xmin, ymin, zmax), Expression('List', xmax, ymin, zmax), Expression('List', xmax, ymax, zmax)), ] return Expression('Polygon', Expression('List', *polygons)) def apply_min(self, xmin, ymin, zmin, evaluation): 'Cuboid[{xmin_, ymin_, zmin_}]' try: xmin, ymin, zmin = [value.to_number(n_evaluation=evaluation) for value in (xmin, ymin, zmin)] except NumberError, exc: #TODO return xmax, ymax, zmax = [from_python(value+1) for value in (xmin, ymin, zmin)] xmin, ymin, zmin = [from_python(value) for value in (xmin, ymin, zmin)] return self.apply_full(xmin, ymin, zmin, xmax, ymax, zmax, evaluation) class _Graphics3DElement(InstancableBuiltin): def init(self, graphics, item=None, style=None): if item is not None and not item.has_form(self.get_name(), None): raise BoxConstructError self.graphics = graphics self.style = style self.is_completely_visible = False # True for axis elements class Sphere3DBox(_Graphics3DElement): def init(self, graphics, style, item): super(Sphere3DBox, self).init(graphics, item, style)
def apply(self, date1, date2, units, evaluation): 'DateDifference[date1_, date2_, units_]' # Process dates pydate1, pydate2 = date1.to_python(), date2.to_python() if isinstance(pydate1, list): # Date List idate = _Date(datelist=pydate1) elif isinstance(pydate1, (float, int)): # Absolute Time idate = _Date(absolute=pydate1) elif isinstance(pydate1, basestring): # Date string idate = _Date(datestr=pydate2.strip('"')) else: evaluation.message('DateDifference', 'date', date1) return if isinstance(pydate2, list): # Date List fdate = _Date(datelist=pydate2) elif isinstance(pydate2, (int, float)): # Absolute Time fdate = _Date(absolute=pydate2) elif isinstance(pydate1, basestring): # Date string fdate = _Date(datestr=pydate2.strip('"')) else: evaluation.message('DateDifference', 'date', date2) return try: tdelta = fdate.date - idate.date except OverflowError: evaluation.message('General', 'ovf') return # Process Units pyunits = units.to_python() if isinstance(pyunits, basestring): pyunits = [unicode(pyunits.strip('"'))] elif (isinstance(pyunits, list) and all(isinstance(p, basestring) for p in pyunits)): pyunits = map(lambda p: p.strip('"'), pyunits) if not all(p in TIME_INCREMENTS.keys() for p in pyunits): evaluation.message('DateDifference', 'inc', units) def intdiv(a, b, flag=True): 'exact integer division where possible' if flag: if a % b == 0: return a / b else: return a / float(b) else: return a / b if not isinstance(pyunits, list): pyunits = [pyunits] # Why doesn't this work? # pyunits = pyunits.sort(key=TIME_INCREMENTS.get, reverse=True) pyunits = [(a, TIME_INCREMENTS.get(a)) for a in pyunits] pyunits.sort(key=lambda a: a[1], reverse=True) pyunits = [a[0] for a in pyunits] seconds = int(total_seconds(tdelta)) result = [] flag = False for i, unit in enumerate(pyunits): if i + 1 == len(pyunits): flag = True if unit == 'Year': result.append([intdiv( seconds, 365 * 24 * 60 * 60, flag), "Year"]) seconds = seconds % (365 * 24 * 60 * 60) if unit == 'Quarter': result.append([intdiv( seconds, 365 * 6 * 60 * 60, flag), "Quarter"]) seconds = seconds % (365 * 6 * 60 * 60) if unit == 'Month': result.append([intdiv( seconds, 365 * 2 * 60 * 60, flag), "Month"]) seconds = seconds % (365 * 2 * 60 * 60) if unit == 'Week': result.append([intdiv( seconds, 7 * 24 * 60 * 60, flag), "Week"]) seconds = seconds % (7 * 24 * 60 * 60) if unit == 'Day': result.append([intdiv(seconds, 24 * 60 * 60, flag), "Day"]) seconds = seconds % (24 * 60 * 60) if unit == 'Hour': result.append([intdiv(seconds, 60 * 60, flag), "Hour"]) seconds = seconds % (60 * 60) if unit == 'Minute': result.append([intdiv(seconds, 60, flag), "Minute"]) seconds = seconds % 60 if unit == 'Second': result.append([intdiv(seconds + total_seconds( tdelta) % 1, 1, flag), "Second"]) if len(result) == 1: if pyunits[0] == "Day": return from_python(result[0][0]) return from_python(result[0]) return from_python(result)
def apply_all_properties(self, evaluation): 'ElementData[All, "Properties"]' return from_python(sorted(_ELEMENT_DATA[0]))
def apply_name(self, expr, prop, evaluation): "ElementData[expr_, prop_]" if isinstance(expr, String): py_name = expr.to_python(string_quotes=False) names = ["StandardName", "Name", "Abbreviation"] iprops = [_ELEMENT_DATA[0].index(s) for s in names] indx = None for iprop in iprops: try: indx = [element[iprop] for element in _ELEMENT_DATA[1:] ].index(py_name) + 1 except ValueError: pass if indx is None: evaluation.message("ElementData", "noent", expr) return # Enter in the next if, but with expr being the index expr = from_python(indx) if isinstance(expr, Integer): py_n = expr.value 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", expr) return else: evaluation.message("ElementData", "noent", expr) return # Check property specifier if isinstance(py_prop, str): 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, str) 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 = evaluation.parse(result) if isinstance(result, Symbol): result = String(strip_context(result.get_name())) return result
def apply_rational_without_base(self, n, evaluation): "RealDigits[n_Rational]" return self.apply_rational_with_base(n, from_python(10), evaluation)
def __init__( self, definitions, style: str, want_completion: bool, use_unicode: bool, prompt: bool, ): super(TerminalShellCommon, self).__init__("<stdin>") self.input_encoding = locale.getpreferredencoding() self.lineno = 0 self.terminal_formatter = None self.mma_pygments_lexer = PygmentsLexer(MathematicaLexer) self.prompt = prompt self.session = PromptSession(history=FileHistory(HISTFILE)) # Try importing readline to enable arrow keys support etc. self.using_readline = False self.history_length = definitions.get_config_value( "$HistoryLength", HISTSIZE) self.using_readline = sys.stdin.isatty() and sys.stdout.isatty() self.ansi_color_re = re.compile("\033\\[[0-9;]+m") colorama_init() if style == "None": self.terminal_formatter = None self.incolors = self.outcolors = ["", "", "", ""] else: # self.incolors = ["\033[34m", "\033[1m", "\033[22m", "\033[39m"] self.incolors = ["\033[32m", "\033[1m", "\033[22m", "\033[39m"] self.outcolors = ["\033[31m", "\033[1m", "\033[22m", "\033[39m"] if style is not None and not is_pygments_style(style): style = None if style is None: dark_background = is_dark_background() if dark_background: style = "inkpot" else: style = "colorful" try: self.terminal_formatter = Terminal256Formatter(style=style) except ClassNotFound: print( "Pygments style name '%s' not found; No pygments style set" % style) self.pygments_style = style self.definitions = definitions self.definitions.set_ownvalue("Settings`$PygmentsShowTokens", from_python(False)) self.definitions.set_ownvalue("Settings`$PygmentsStyle", from_python(style)) self.definitions.set_ownvalue("Settings`$UseUnicode", from_python(use_unicode)) self.definitions.set_ownvalue("Settings`PygmentsStylesAvailable", from_python(ALL_PYGMENTS_STYLES)) read_inputrc(use_unicode=use_unicode) self.definitions.add_message( "Settings`PygmentsStylesAvailable", Rule( Expression( "System`MessageName", Symbol("Settings`PygmentsStylesAvailable"), from_python("usage"), ), from_python( "A list of Pygments style that are valid in Settings`$PygmentsStyle." ), ), ) self.definitions.set_attribute("Settings`PygmentsStylesAvailable", "System`Protected") self.definitions.set_attribute("Settings`PygmentsStylesAvailable", "System`Locked") self.definitions.set_attribute("Settings`$UseUnicode", "System`Locked") self.completer = MathicsCompleter( self.definitions) if want_completion else None
def apply(self, n, evaluation): 'PrimePi[n_?NumericQ]' return from_python(sympy.ntheory.primepi(n.to_python(n_evaluation=evaluation)))
def find_root_secant(f, x0, x, opts, evaluation) -> (Number, bool): region = opts.get("$$Region", None) if not type(region) is list: if x0.is_zero: region = (Real(-1), Real(1)) else: xmax = 2 * x0.to_python() xmin = -2 * x0.to_python() if xmin > xmax: region = (Real(xmax), Real(xmin)) else: region = (Real(xmin), Real(xmax)) maxit = opts["System`MaxIterations"] x_name = x.get_name() if maxit.sameQ(Symbol("Automatic")): maxit = 100 else: maxit = maxit.evaluate(evaluation).get_int_value() x0 = from_python(region[0]) x1 = from_python(region[1]) f0 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x0}, evaluation) f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x1}, evaluation) if not isinstance(f0, Number): return x0, False if not isinstance(f1, Number): return x0, False f0 = f0.to_python(n_evaluation=True) f1 = f1.to_python(n_evaluation=True) count = 0 while count < maxit: if f0 == f1: x1 = Expression( "Plus", x0, Expression( "Times", Real(0.75), Expression("Plus", x1, Expression("Times", Integer(-1), x0)), ), ) x1 = x1.evaluate(evaluation) f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x1}, evaluation) if not isinstance(f1, Number): return x0, False f1 = f1.to_python(n_evaluation=True) continue inv_deltaf = from_python(1.0 / (f1 - f0)) num = Expression( "Plus", Expression("Times", x0, f1), Expression("Times", x1, f0, Integer(-1)), ) x2 = Expression("Times", num, inv_deltaf) x2 = x2.evaluate(evaluation) f2 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x2}, evaluation) if not isinstance(f2, Number): return x0, False f2 = f2.to_python(n_evaluation=True) f1, f0 = f2, f1 x1, x0 = x2, x1 if x1 == x0 or abs(f2) == 0: break count = count + 1 else: evaluation.message("FindRoot", "maxiter") return x0, False return x0, True
def attributes(): for name, value in node.attrib.items(): yield Expression('Rule', from_python(name), from_python(value))
def apply_empty(self, string, evaluation): 'StringSplit[string_String]' py_string = string.get_string_value() result = py_string.split() return from_python([x for x in result if x != ''])
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) # TODO: Add more file formats typedict = { 'application/dicom': 'DICOM', 'application/dbase': 'DBF', 'application/dbf': 'DBF', 'application/eps': 'EPS', 'application/fits': 'FITS', 'application/json': 'JSON', 'application/mathematica': 'NB', 'application/mdb': 'MDB', 'application/mbox': 'MBOX', 'application/msaccess': 'MDB', 'application/octet-stream': 'OBJ', 'application/pdf': 'PDF', 'application/pcx': 'PCX', 'application/postscript': 'EPS', 'application/rss+xml': 'RSS', 'application/rtf': 'RTF', 'application/sla': 'STL', 'application/tga': 'TGA', 'application/vnd.google-earth.kml+xml': 'KML', 'application/vnd.ms-excel': 'XLS', 'application/vnd.ms-pki.stl': 'STL', 'application/vnd.oasis.opendocument.spreadsheet': 'ODS', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'XLSX', # nopep8 'application/vnd.sun.xml.calc': 'SXC', 'application/vnd.msaccess': 'MDB', 'application/vnd.wolfram.cdf': 'CDF', 'application/vnd.wolfram.cdf.text': 'CDF', 'application/vnd.wolfram.mathematica.package': 'Package', 'application/xhtml+xml': 'XHTML', 'application/xml': 'XML', 'application/x-3ds': '3DS', 'application/x-cdf': 'NASACDF', 'application/x-eps': 'EPS', 'application/x-flac': 'FLAC', 'application/x-font-bdf': 'BDF', 'application/x-hdf': 'HDF', 'application/x-msaccess': 'MDB', 'application/x-netcdf': 'NetCDF', 'application/x-shockwave-flash': 'SWF', 'application/x-tex': 'TeX', # Also TeX 'audio/aiff': 'AIFF', 'audio/basic': 'AU', # Also SND 'audio/midi': 'MIDI', 'audio/x-aifc': 'AIFF', 'audio/x-aiff': 'AIFF', 'audio/x-flac': 'FLAC', 'audio/x-wav': 'WAV', 'chemical/seq-na-genbank': 'GenBank', 'chemical/seq-aa-fasta': 'FASTA', 'chemical/seq-na-fasta': 'FASTA', 'chemical/seq-na-fastq': 'FASTQ', 'chemical/seq-na-sff': 'SFF', 'chemical/x-cif': 'CIF', 'chemical/x-daylight-smiles': 'SMILES', 'chemical/x-hin': 'HIN', 'chemical/x-jcamp-dx': 'JCAMP-DX', 'chemical/x-mdl-molfile': 'MOL', 'chemical/x-mdl-sdf': 'SDF', 'chemical/x-mdl-sdfile': 'SDF', 'chemical/x-mdl-tgf': 'TGF', 'chemical/x-mmcif': 'CIF', 'chemical/x-mol2': 'MOL2', 'chemical/x-mopac-input': 'Table', 'chemical/x-pdb': 'PDB', 'chemical/x-xyz': 'XYZ', 'image/bmp': 'BMP', 'image/eps': 'EPS', 'image/fits': 'FITS', 'image/gif': 'GIF', 'image/jp2': 'JPEG2000', 'image/jpeg': 'JPEG', 'image/pbm': 'PNM', 'image/pcx': 'PCX', 'image/pict': 'PICT', 'image/png': 'PNG', 'image/svg+xml': 'SVG', 'image/tga': 'TGA', 'image/tiff': 'TIFF', 'image/vnd.dxf': 'DXF', 'image/vnd.microsoft.icon': 'ICO', 'image/x-3ds': '3DS', 'image/x-dxf': 'DXF', 'image/x-exr': 'OpenEXR', 'image/x-icon': 'ICO', 'image/x-ms-bmp': 'BMP', 'image/x-pcx': 'PCX', 'image/x-portable-anymap': 'PNM', 'image/x-portable-bitmap': 'PBM', 'image/x-portable-graymap': 'PGM', 'image/x-portable-pixmap': 'PPM', 'image/x-xbitmap': 'XBM', 'model/x3d+xml': 'X3D', 'model/vrml': 'VRML', 'model/x-lwo': 'LWO', 'model/x-pov': 'POV', 'text/calendar': 'ICS', 'text/comma-separated-values': 'CSV', 'text/csv': 'CSV', 'text/html': 'HTML', 'text/mathml': 'MathML', 'text/plain': 'Text', 'text/rtf': 'RTF', 'text/scriptlet': 'SCT', 'text/tab-separated-values': 'TSV', 'text/texmacs': 'Text', 'text/vnd.graphviz': 'DOT', 'text/x-csrc': 'C', 'text/x-tex': 'TeX', 'text/x-vcalendar': 'VCS', 'text/x-vcard': 'VCF', 'video/avi': 'AVI', 'video/quicktime': 'QuickTime', 'video/x-flv': 'FLV', # None: 'Binary', } result = [] for key in typedict.keys(): if key in mime: result.append(typedict[key]) if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def apply_2(self, n, b, evaluation, nr_elements=None, pos=None): "RealDigits[n_?NumericQ, b_Integer]" expr = Expression("RealDigits", n) rational_no = ( True if isinstance(n, Rational) else False ) # it is used for checking whether the input n is a rational or not py_b = b.get_int_value() if isinstance(n, (Expression, Symbol, Rational)): pos_len = abs(pos) + 1 if pos is not None and pos < 0 else 1 if nr_elements is not None: n = Expression( "N", n, int(mpmath.log(py_b**(nr_elements + pos_len), 10)) + 1).evaluate(evaluation) else: if rational_no: n = Expression("N", n).evaluate(evaluation) else: return evaluation.message("RealDigits", "ndig", expr) py_n = abs(n.value) if not py_b > 1: return evaluation.message("RealDigits", "rbase", py_b) if isinstance(py_n, complex): return evaluation.message("RealDigits", "realx", expr) if isinstance(n, Integer): display_len = (int(mpmath.floor(mpmath.log(py_n, py_b))) if py_n != 0 and py_n != 1 else 1) else: display_len = int( Expression( "N", Expression( "Round", Expression( "Divide", Expression("Precision", py_n), Expression("Log", 10, py_b), ), ), ).evaluate(evaluation).to_python()) exp = int(mpmath.ceil(mpmath.log( py_n, py_b))) if py_n != 0 and py_n != 1 else 1 if py_n == 0 and nr_elements is not None: exp = 0 digits = [] if not py_b == 10: digits = convert_float_base(py_n, py_b, display_len - exp) # truncate all the leading 0's i = 0 while digits and digits[i] == 0: i += 1 digits = digits[i:] if not isinstance(n, Integer): if len(digits) > display_len: digits = digits[:display_len - 1] else: # drop any leading zeroes for x in str(py_n): if x != "." and (digits or x != "0"): digits.append(x) if pos is not None: temp = exp exp = pos + 1 move = temp - 1 - pos if move <= 0: digits = [0] * abs(move) + digits else: digits = digits[abs(move):] display_len = display_len - move list_str = Expression("List") for x in digits: if x == "e" or x == "E": break # Convert to Mathics' list format list_str.leaves.append(from_python(int(x))) if not rational_no: while len(list_str.leaves) < display_len: list_str.leaves.append(from_python(0)) if nr_elements is not None: # display_len == nr_elements if len(list_str.leaves) >= nr_elements: # Truncate, preserving the digits on the right list_str = list_str.leaves[:nr_elements] else: if isinstance(n, Integer): while len(list_str.leaves) < nr_elements: list_str.leaves.append(from_python(0)) else: # Adding Indeterminate if the length is greater than the precision while len(list_str.leaves) < nr_elements: list_str.leaves.append( from_python(Symbol("Indeterminate"))) return Expression("List", list_str, exp)
def apply_empty(self, string, evaluation): 'StringSplit[string_String]' py_string = string.get_string_value() result = py_string.split() return from_python(filter(lambda x: x != u'', result))
def fold(self, x, l): # computes fold(x, l) with the internal _fold function. will start # its evaluation machine precision, and will escalate to arbitrary # precision if or symbolical evaluation only if necessary. folded # items already computed are carried over to new evaluation modes. yield x # initial state init = None operands = list(self._operands(x, l)) spans = self._spans(operands) for mode in (self.FLOAT, self.MPMATH, self.SYMBOLIC): s_operands = [y[1:] for y in operands[spans[mode]]] if not s_operands: continue if mode == self.MPMATH: from mathics.core.numbers import min_prec precision = min_prec( *[t for t in chain(*s_operands) if t is not None]) working_precision = mpmath.workprec else: @contextmanager def working_precision(_): yield precision = None if mode == self.FLOAT: def out(z): return Real(z) elif mode == self.MPMATH: def out(z): return Real(z, precision) else: def out(z): return z as_operand = self.operands.get(mode) def converted_operands(): for y in s_operands: yield tuple(as_operand(t) for t in y) with working_precision(precision): c_operands = converted_operands() if init is not None: c_init = tuple( (None if t is None else as_operand(from_python(t))) for t in init) else: c_init = next(c_operands) init = tuple( (None if t is None else out(t)) for t in c_init) generator = self._fold(c_init, c_operands, self.math.get(mode)) for y in generator: y = tuple(out(t) for t in y) yield y init = y
def apply_all(self, evaluation): 'ElementData[All]' iprop = _ELEMENT_DATA[0].index('StandardName') return from_python([element[iprop] for element in _ELEMENT_DATA[1:]])
def apply_now(self, evaluation): 'AbsoluteTime[]' return from_python(total_seconds(datetime.now() - EPOCH_START))
def apply(self, image, val, evaluation): 'PixelValuePositions[image_Image, val_?RealNumberQ]' rows, cols = numpy.where( skimage.img_as_float(image.pixels) == float(val.to_python())) p = numpy.dstack((cols, rows)) + numpy.array([1, 1]) return from_python(p.tolist())
def apply(self, functions, x, start, stop, evaluation, options): '''%(name)s[functions_, {x_Symbol, start_, stop_}, OptionsPattern[%(name)s]]''' expr_limits = Expression('List', x, start, stop) expr = Expression(self.get_name(), functions, expr_limits, *options_to_rules(options)) functions = self.get_functions_param(functions) x_name = x.get_name() try: start = start.to_number(n_evaluation=evaluation) except NumberError: evaluation.message(self.get_name(), 'plln', start, expr) return try: stop = stop.to_number(n_evaluation=evaluation) except NumberError: evaluation.message(self.get_name(), 'plln', stop, expr) return if start >= stop: evaluation.message(self.get_name(), 'plld', expr_limits) return # PlotRange Option def check_range(range): if range in ('Automatic', 'All'): return True if isinstance(range, list) and len(range) == 2: if (isinstance(range[0], numbers.Real) and # noqa isinstance(range[1], numbers.Real)): return True return False plotrange_option = self.get_option(options, 'PlotRange', evaluation) plotrange = plotrange_option.to_python(n_evaluation=evaluation) x_range, y_range = self.get_plotrange(plotrange, start, stop) if not check_range(x_range) or not check_range(y_range): evaluation.message(self.get_name(), 'prng', plotrange_option) x_range, y_range = [start, stop], 'Automatic' # x_range and y_range are now either Automatic, All, or of the form # [min, max] assert x_range in ('Automatic', 'All') or isinstance(x_range, list) assert y_range in ('Automatic', 'All') or isinstance(y_range, list) # Mesh Option mesh_option = self.get_option(options, 'Mesh', evaluation) mesh = mesh_option.to_python() if mesh not in ['None', 'Full', 'All']: evaluation.message('Mesh', 'ilevels', mesh_option) mesh = 'None' # PlotPoints Option plotpoints_option = self.get_option(options, 'PlotPoints', evaluation) plotpoints = plotpoints_option.to_python() if plotpoints == 'None': plotpoints = 57 if not (isinstance(plotpoints, int) and plotpoints >= 2): return evaluation.message(self.get_name(), 'ppts', plotpoints) # MaxRecursion Option max_recursion_limit = 15 maxrecursion_option = self.get_option( options, 'MaxRecursion', evaluation) maxrecursion = maxrecursion_option.to_python() try: if maxrecursion == 'Automatic': maxrecursion = 3 elif maxrecursion == float('inf'): maxrecursion = max_recursion_limit raise ValueError elif isinstance(maxrecursion, int): if maxrecursion > max_recursion_limit: maxrecursion = max_recursion_limit raise ValueError if maxrecursion < 0: maxrecursion = 0 raise ValueError else: maxrecursion = 0 raise ValueError except ValueError: evaluation.message(self.get_name(), 'invmaxrec', maxrecursion, max_recursion_limit) assert isinstance(maxrecursion, int) # Exclusions Option # TODO: Make exclusions option work properly with ParametricPlot def check_exclusion(excl): if isinstance(excl, list): return all(check_exclusion(e) for e in excl) if excl == 'Automatic': return True if not isinstance(excl, numbers.Real): return False return True exclusions_option = self.get_option(options, 'Exclusions', evaluation) exclusions = exclusions_option.to_python(n_evaluation=evaluation) # TODO Turn expressions into points E.g. Sin[x] == 0 becomes 0, 2 Pi... if exclusions in ['None', ['None']]: exclusions = 'None' elif not isinstance(exclusions, list): exclusions = [exclusions] if (isinstance(exclusions, list) and # noqa all(check_exclusion(excl) for excl in exclusions)): pass else: evaluation.message( self.get_name(), 'invexcl', exclusions_option) exclusions = ['Automatic'] # exclusions is now either 'None' or a list of reals and 'Automatic' assert (exclusions == 'None' or isinstance(exclusions, list)) # constants to generate colors hue = 0.67 hue_pos = 0.236068 hue_neg = -0.763932 def get_points_minmax(points): xmin = xmax = ymin = ymax = None for line in points: for x, y in line: if xmin is None or x < xmin: xmin = x if xmax is None or x > xmax: xmax = x if ymin is None or y < ymin: ymin = y if ymax is None or y > ymax: ymax = y return xmin, xmax, ymin, ymax def zero_to_one(value): if value == 0: return 1 return value def get_points_range(points): xmin, xmax, ymin, ymax = get_points_minmax(points) if xmin is None or xmax is None: xmin, xmax = 0, 1 if ymin is None or ymax is None: ymin, ymax = 0, 1 return zero_to_one(xmax - xmin), zero_to_one(ymax - ymin) function_hues = [] base_plot_points = [] # list of points in base subdivision plot_points = [] # list of all plotted points mesh_points = [] graphics = [] # list of resulting graphics primitives for index, f in enumerate(functions): points = [] xvalues = [] # x value for each point in points tmp_mesh_points = [] # For this function only continuous = False d = (stop - start) / (plotpoints - 1) for i in xrange(plotpoints): x_value = start + i * d point = self.eval_f(f, x_name, x_value, evaluation) if point is not None: if continuous: points[-1].append(point) xvalues[-1].append(x_value) else: points.append([point]) xvalues.append([x_value]) continuous = True else: continuous = False base_points = [] for line in points: base_points.extend(line) base_plot_points.extend(base_points) xmin, xmax = automatic_plot_range([xx for xx, yy in base_points]) xscale = 1. / zero_to_one(xmax - xmin) ymin, ymax = automatic_plot_range([yy for xx, yy in base_points]) yscale = 1. / zero_to_one(ymax - ymin) if mesh == 'Full': for line in points: tmp_mesh_points.extend(line) def find_excl(excl): # Find which line the exclusion is in for l in range(len(xvalues)): # TODO: Binary Search faster? if xvalues[l][0] <= excl and xvalues[l][-1] >= excl: break if (xvalues[l][-1] <= excl and # nopep8 xvalues[min(l + 1, len(xvalues) - 1)][0] >= excl): return min(l + 1, len(xvalues) - 1), 0, False xi = 0 for xi in range(len(xvalues[l]) - 1): if xvalues[l][xi] <= excl and xvalues[l][xi + 1] >= excl: return l, xi + 1, True return l, xi + 1, False if exclusions != 'None': for excl in exclusions: if excl != 'Automatic': l, xi, split_required = find_excl(excl) if split_required: xvalues.insert(l + 1, xvalues[l][xi:]) xvalues[l] = xvalues[l][:xi] points.insert(l + 1, points[l][xi:]) points[l] = points[l][:xi] # assert(xvalues[l][-1] <= excl <= xvalues[l+1][0]) # Adaptive Sampling - loop again and interpolate highly angled # sections # Cos of the maximum angle between successive line segments ang_thresh = cos(pi / 180) for line, line_xvalues in zip(points, xvalues): recursion_count = 0 smooth = False while not smooth and recursion_count < maxrecursion: recursion_count += 1 smooth = True i = 2 while i < len(line): vec1 = (xscale * (line[i - 1][0] - line[i - 2][0]), yscale * (line[i - 1][1] - line[i - 2][1])) vec2 = (xscale * (line[i][0] - line[i - 1][0]), yscale * (line[i][1] - line[i - 1][1])) try: angle = (vec1[0] * vec2[0] + vec1[1] * vec2[1]) \ / sqrt((vec1[0] ** 2 + vec1[1] ** 2) * (vec2[0] ** 2 + vec2[1] ** 2)) except ZeroDivisionError: angle = 0.0 if abs(angle) < ang_thresh: smooth = False incr = 0 x_value = 0.5 * (line_xvalues[i - 1] + line_xvalues[i]) point = self.eval_f(f, x_name, x_value, evaluation) if point is not None: line.insert(i, point) line_xvalues.insert(i, x_value) incr += 1 x_value = 0.5 * (line_xvalues[i - 2] + line_xvalues[i - 1]) point = self.eval_f(f, x_name, x_value, evaluation) if point is not None: line.insert(i - 1, point) line_xvalues.insert(i - 1, x_value) incr += 1 i += incr i += 1 if exclusions == 'None': # Join all the Lines points = [[(xx, yy) for line in points for xx, yy in line]] graphics.append(Expression('Hue', hue, 0.6, 0.6)) graphics.append(Expression('Line', from_python(points))) for line in points: plot_points.extend(line) if mesh == 'All': for line in points: tmp_mesh_points.extend(line) if mesh != 'None': mesh_points.append(tmp_mesh_points) function_hues.append(hue) if index % 4 == 0: hue += hue_pos else: hue += hue_neg if hue > 1: hue -= 1 if hue < 0: hue += 1 x_range = get_plot_range([xx for xx, yy in base_plot_points], [xx for xx, yy in plot_points], x_range) y_range = get_plot_range([yy for xx, yy in base_plot_points], [yy for xx, yy in plot_points], y_range) options['PlotRange'] = from_python([x_range, y_range]) if mesh != 'None': for hue, points in zip(function_hues, mesh_points): graphics.append(Expression('Hue', hue, 0.6, 0.6)) meshpoints = [Expression('List', xx, yy) for xx, yy in points] graphics.append(Expression( 'Point', Expression('List', *meshpoints))) return Expression('Graphics', Expression('List', *graphics), *options_to_rules(options))
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, r, evaluation): 'BoxMatrix[r_?RealNumberQ]' s = 1 + 2 * r.to_python() return from_python(skimage.morphology.rectangle(s, s).tolist())
def apply(self, points, evaluation, options): '%(name)s[points_, OptionsPattern[%(name)s]]' plot_name = self.get_name() all_points = points.to_python(n_evaluation=evaluation) expr = Expression(self.get_name(), points, *options_to_rules(options)) # PlotRange Option def check_range(range): if range in ('Automatic', 'All'): return True if isinstance(range, list) and len(range) == 2: if (isinstance(range[0], numbers.Real) and # noqa isinstance(range[1], numbers.Real)): return True return False plotrange_option = self.get_option(options, 'PlotRange', evaluation) plotrange = plotrange_option.to_python(n_evaluation=evaluation) if plotrange == 'All': plotrange = ['All', 'All'] elif plotrange == 'Automatic': plotrange = ['Automatic', 'Automatic'] elif isinstance(plotrange, numbers.Real): plotrange = [[-plotrange, plotrange], [-plotrange, plotrange]] elif isinstance(plotrange, list) and len(plotrange) == 2: if all(isinstance(pr, numbers.Real) for pr in plotrange): plotrange = ['All', plotrange] elif all(check_range(pr) for pr in plotrange): pass else: evaluation.message(self.get_name(), 'prng', plotrange_option) plotrange = ['Automatic', 'Automatic'] x_range, y_range = plotrange[0], plotrange[1] assert x_range in ('Automatic', 'All') or isinstance(x_range, list) assert y_range in ('Automatic', 'All') or isinstance(y_range, list) # Filling option # TODO: Fill between corresponding points in two datasets: filling_option = self.get_option(options, 'Filling', evaluation) filling = filling_option.to_python(n_evaluation=evaluation) if (filling in ['Top', 'Bottom', 'Axis'] or # noqa isinstance(filling, numbers.Real)): pass else: # Mathematica does not even check that filling is sane filling = None # Joined Option joined_option = self.get_option(options, 'Joined', evaluation) joined = joined_option.to_python() if joined not in [True, False]: evaluation.message(plot_name, 'joind', joined_option, expr) joined = False if isinstance(all_points, list) and len(all_points) != 0: if all(not isinstance(point, list) for point in all_points): # Only y values given all_points = [[[float(i + 1), all_points[i]] for i in range(len(all_points))]] elif all(isinstance(line, list) and len(line) == 2 for line in all_points): # Single list of (x,y) pairs all_points = [all_points] elif all(isinstance(line, list) for line in all_points): # List of lines if all(isinstance(point, list) and len(point) == 2 for line in all_points for point in line): pass elif all(not isinstance(point, list) for line in all_points for point in line): all_points = [ [[float(i + 1), l] for i, l in enumerate(line)] for line in all_points] else: return else: return else: return # Split into segments at missing data all_points = [[line] for line in all_points] for l, line in enumerate(all_points): i = 0 while i < len(all_points[l]): seg = line[i] for j, point in enumerate(seg): if not ((isinstance(point[0], float) or isinstance(point[0], int)) and (isinstance(point[1], float) or isinstance(point[1], int))): all_points[l].insert(i, seg[:j]) all_points[l][i + 1] = seg[j + 1:] i -= 1 break i += 1 y_range = get_plot_range( [y for line in all_points for seg in line for x, y in seg], [y for line in all_points for seg in line for x, y in seg], y_range) x_range = get_plot_range( [x for line in all_points for seg in line for x, y in seg], [x for line in all_points for seg in line for x, y in seg], x_range) if filling == 'Axis': # TODO: Handle arbitary axis intercepts filling = 0.0 elif filling == 'Bottom': filling = y_range[0] elif filling == 'Top': filling = y_range[1] hue = 0.67 hue_pos = 0.236068 hue_neg = -0.763932 graphics = [] for indx, line in enumerate(all_points): graphics.append(Expression('Hue', hue, 0.6, 0.6)) for segment in line: if joined: graphics.append(Expression('Line', from_python(segment))) if filling is not None: graphics.append(Expression('Hue', hue, 0.6, 0.6, 0.2)) fill_area = list(segment) fill_area.append([segment[-1][0], filling]) fill_area.append([segment[0][0], filling]) graphics.append(Expression( 'Polygon', from_python(fill_area))) else: graphics.append(Expression('Point', from_python(segment))) if filling is not None: for point in segment: graphics.append(Expression( 'Line', from_python([[point[0], filling], [point[0], point[1]]]))) if indx % 4 == 0: hue += hue_pos else: hue += hue_neg if hue > 1: hue -= 1 if hue < 0: hue += 1 options['PlotRange'] = from_python([x_range, y_range]) return Expression('Graphics', Expression('List', *graphics), *options_to_rules(options))
def apply(self, r, evaluation): 'DiamondMatrix[r_?RealNumberQ]' return from_python(skimage.morphology.diamond(r).tolist())
def _import(findfile, determine_filetype, elements, evaluation, options, data=None): current_predetermined_out = evaluation.predetermined_out # Check elements if elements.has_form('List', None): elements = elements.get_leaves() else: elements = [elements] for el in elements: if not isinstance(el, String): evaluation.message('Import', 'noelem', el) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elements = [el.get_string_value() for el in elements] # Determine file type for el in elements: if el in IMPORTERS.keys(): filetype = el elements.remove(el) break else: filetype = determine_filetype() if filetype not in IMPORTERS.keys(): evaluation.message('Import', 'fmtnosup', filetype) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the importer (conditionals, default_function, posts, importer_options) = IMPORTERS[filetype] stream_options, custom_options = _importer_exporter_options( importer_options.get("System`Options"), options, evaluation) function_channels = importer_options.get("System`FunctionChannels") if function_channels is None: # TODO message if data is None: evaluation.message('Import', 'emptyfch') else: evaluation.message('ImportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') default_element = importer_options.get("System`DefaultElement") if default_element is None: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') def get_results(tmp_function, findfile): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmpfile = False if findfile is None: tmpfile = True stream = Expression('OpenWrite').evaluate(evaluation) findfile = stream.leaves[0] if not data is None: Expression('WriteString', data).evaluate(evaluation) else: Expression('WriteString', String("")).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) stream = None tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) if tmpfile: Expression("DeleteFile", findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): if findfile is None: stream = Expression('StringToStream', data).evaluate(evaluation) else: stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') evaluation.predetermined_out = current_predetermined_out return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): evaluation.predetermined_out = current_predetermined_out return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} evaluation.predetermined_out = current_predetermined_out return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp]) # Perform the import defaults = None if not elements: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if default_element == Symbol("Automatic"): evaluation.predetermined_out = current_predetermined_out return Expression( 'List', *(Expression('Rule', String(key), defaults[key]) for key in defaults.keys())) else: result = defaults.get(default_element.get_string_value()) if result is None: evaluation.message('Import', 'noelem', default_element, from_python(filetype)) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') evaluation.predetermined_out = current_predetermined_out return result else: assert len(elements) == 1 el = elements[0] if el == "Elements": defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Use set() to remove duplicates evaluation.predetermined_out = current_predetermined_out return from_python( sorted( set( list(conditionals.keys()) + list(defaults.keys()) + list(posts.keys())))) else: if el in conditionals.keys(): result = get_results(conditionals[el], findfile) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if len(list(result.keys())) == 1 and list( result.keys())[0] == el: evaluation.predetermined_out = current_predetermined_out return list(result.values())[0] elif el in posts.keys(): # TODO: allow use of conditionals result = get_results(posts[el]) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') else: if defaults is None: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if el in defaults.keys(): evaluation.predetermined_out = current_predetermined_out return defaults[el] else: evaluation.message('Import', 'noelem', from_python(el), from_python(filetype)) evaluation.predetermined_out = current_predetermined_otu return Symbol('$Failed')
def apply(self, n, evaluation): "PrimePi[n_?NumericQ]" result = sympy.ntheory.primepi(n.to_python(n_evaluation=evaluation)) return from_python(result)