Skip to content

Commit

Permalink
Merge pull request #1061 from mathics/release-1.1.1
Browse files Browse the repository at this point in the history
Release 1.1.1
  • Loading branch information
rocky authored Dec 24, 2020
2 parents 2b545d7 + 612e045 commit cffa8b1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 65 deletions.
34 changes: 20 additions & 14 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,56 @@ CHANGES
1.1.1
-----

This is the last update before some major refactoring and interface changing occurs.
This may be the last update before some major refactoring and interface changing occurs.

After this relase, Django will no longer be bundled here. See `mathics-django <https://github.com/Mathics3/mathics-django>` for the unbundled replacement.
In a future 2.0.0 release, Django will no longer be bundled here. See `mathics-django <https://github.com/Mathics3/mathics-django>` for the unbundled replacement.

Some changes were made to support `Pymathics Graph <https://github.com/Mathics3/pymathics-graph>`_, a new graph package bundled separately,
and to support the ability for front-ends to handle rendering on their own.
and to support the ability for front-ends to handle rendering on their own. Note that currently this doesn't integrate well into the Django interface, although it works
well in ``mathicsscript``.


Package Updates
++++++++++++++++
+++++++++++++++

- sympy 1.7.1

Mathics Packages added:

- ``DiscreteMath`CombinatoricaV0.9`` and
``DiscreteMath`CombinatoricaV0.6``. V0.9 covers Steven Skiena's older "Implementing Discrete Mathematics: Combinatorics and Graph Theory" book.
- ``DiscreteMath`CombinatoricaV0.9`` (preferred) aand
``DiscreteMath`CombinatoricaV0.6``.

Both of these correspond to Steven Skiena's *older* book: "Implementing Discrete Mathematics: Combinatorics and Graph Theory" book.

If you have a package that you would like included in the distribution, and it works with Mathics, please contact us.
If you have a package that you would like included in the distribution, and it works with Mathics, please contact us

Rubi may appear in a future release, possibly in a year or so. However this might be speeded up if we can get people to help out with this.


New builtins:
++++++++++++++++++++++++++++

- ``StirlingS1``, ``StirlingS2`` (not all WL variations handled)
- ``MapAt`` (not all WL variations handled)
- ``PythonForm``, ``SympyForm`` these is not in WL. It simply will show a crude translation to ``sympy`` or ``python``. Expect more and better translation later
- ``PythonForm``, ``SympyForm``: these is not in WL. It simply will show a crude translation to ``sympy`` or ``python``. Expect more and better translation later
- ``Throw`` and ``Catch``
- ``With``
- Start ``FileNameTake``
- ``FileNameTake``

Enhancements and Bug fixes:
+++++++++++++++++++++++++++

- Workaround for ``Compile`` so it accepts functions ##1026
- Add ``Trace`` option to ``Get``. ``Get["fn", Trace->True]`` will show lines as they are read.
- Add bool for ``from_python``
- Convert to/from Boolean types properly in ``from_python``, ``to_python``. Previously they were 0, and 1.
- Extend ``DeleteCases`` to accept a levelspec parameter.
- Set Evaluation#exc_result to capture ``Aborted``, ``Timeout``, ``Overflow1``, etc.
- ``ImageData`` changed to get bits {0,1} not bools.
- add tokenizer symbols for <-> and -> and the unicode versions of those.
- fix ``Needs``
- Set ``Evaluation#exc_result`` to capture ``Aborted``, ``Timeout``, ``Overflow1``, etc.
- ``ImageData`` changed to get bits {0,1}, not booleans as previously.
- Add tokenizer symbols for <-> and -> and the unicode versions of those.
- Small corrections to ``Needs``, e.g check if already loaded, correct a typo, etc.
- ``System`$InputFileName`` is now set inside ``Needs`` and ``Get``
- Install shell scripts ``dmathicserver``, ``dmathicsscript``, and ``dmathics`` to simplify running docker
- Adjust $InputFileName inside ``Get`` and ``Needs``.

1.1.0
-----
Expand Down
3 changes: 2 additions & 1 deletion mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
Rational,
Real,
Symbol,
SymbolNull,
Complex,
String,
SymbolTrue,
Expand Down Expand Up @@ -916,7 +917,7 @@ def apply_check(self, x, y, evaluation):
return Symbol("ComplexInfinity")

result = self.apply(Expression("Sequence", x, y), evaluation)
if result is None or result != Symbol("Null"):
if result is None or result != SymbolNull:
return result


Expand Down
95 changes: 54 additions & 41 deletions mathics/builtin/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from mathics.builtin.base import Predefined, Builtin
from mathics.builtin.evaluation import Sequence
from mathics.core.expression import Expression, Symbol, String
from mathics.core.expression import Expression, Symbol, SymbolNull, String
from mathics.builtin.assignment import get_symbol_list


Expand Down Expand Up @@ -46,16 +46,16 @@ class Attributes(Builtin):
= {Listable}
"""

attributes = ('HoldAll', 'Listable')
attributes = ("HoldAll", "Listable")

def apply(self, expr, evaluation):
'Attributes[expr_]'
"Attributes[expr_]"

name = expr.get_lookup_name()
attributes = list(evaluation.definitions.get_attributes(name))
attributes.sort()
attr = [Symbol(attribute) for attribute in attributes]
return Expression('List', *attr)
return Expression("List", *attr)


class SetAttributes(Builtin):
Expand All @@ -75,26 +75,28 @@ class SetAttributes(Builtin):
= {Flat, Orderless}
"""

attributes = ('HoldFirst',)
attributes = ("HoldFirst",)

def apply(self, symbols, attributes, evaluation):
'SetAttributes[symbols_, attributes_]'
"SetAttributes[symbols_, attributes_]"

symbols = get_symbol_list(symbols, lambda item: evaluation.message(
'SetAttributes', 'sym', item, 1))
symbols = get_symbol_list(
symbols, lambda item: evaluation.message("SetAttributes", "sym", item, 1)
)
if symbols is None:
return
values = get_symbol_list(attributes, lambda item: evaluation.message(
'SetAttributes', 'sym', item, 2))
values = get_symbol_list(
attributes, lambda item: evaluation.message("SetAttributes", "sym", item, 2)
)
if values is None:
return
for symbol in symbols:
if 'System`Locked' in evaluation.definitions.get_attributes(symbol):
evaluation.message('SetAttributes', 'locked', Symbol(symbol))
if "System`Locked" in evaluation.definitions.get_attributes(symbol):
evaluation.message("SetAttributes", "locked", Symbol(symbol))
else:
for value in values:
evaluation.definitions.set_attribute(symbol, value)
return Symbol('Null')
return SymbolNull


class ClearAttributes(Builtin):
Expand All @@ -116,26 +118,29 @@ class ClearAttributes(Builtin):
= {}
"""

attributes = ('HoldFirst',)
attributes = ("HoldFirst",)

def apply(self, symbols, attributes, evaluation):
'ClearAttributes[symbols_, attributes_]'
"ClearAttributes[symbols_, attributes_]"

symbols = get_symbol_list(symbols, lambda item: evaluation.message(
'ClearAttributes', 'sym', item, 1))
symbols = get_symbol_list(
symbols, lambda item: evaluation.message("ClearAttributes", "sym", item, 1)
)
if symbols is None:
return
values = get_symbol_list(attributes, lambda item: evaluation.message(
'ClearAttributes', 'sym', item, 2))
values = get_symbol_list(
attributes,
lambda item: evaluation.message("ClearAttributes", "sym", item, 2),
)
if values is None:
return
for symbol in symbols:
if 'System`Locked' in evaluation.definitions.get_attributes(symbol):
evaluation.message('ClearAttributes', 'locked', Symbol(symbol))
if "System`Locked" in evaluation.definitions.get_attributes(symbol):
evaluation.message("ClearAttributes", "locked", Symbol(symbol))
else:
for value in values:
evaluation.definitions.clear_attribute(symbol, value)
return Symbol('Null')
return SymbolNull


class Protect(Builtin):
Expand All @@ -156,9 +161,9 @@ class Protect(Builtin):
= {1, 2, 3}
"""

attributes = ('HoldAll',)
attributes = ("HoldAll",)
messages = {
'ssym': "`1` is not a symbol or a string.",
"ssym": "`1` is not a symbol or a string.",
}

def apply(self, symbols, evaluation):
Expand All @@ -174,28 +179,32 @@ def apply(self, symbols, evaluation):
if symbols.get_head_name() in ("System`Sequence", "System`List"):
symbols = symbols.get_leaves()
else:
evaluation.message('Protect', 'ssym', symbols)
return Symbol("Null")
evaluation.message("Protect", "ssym", symbols)
return SymbolNull

for symbol in symbols:
if isinstance(symbol, Symbol):
items.append(symbol)
else:
pattern = symbol.get_string_value()
if not pattern or pattern=="":
evaluation.message('Protect', 'ssym', symbol)
if not pattern or pattern == "":
evaluation.message("Protect", "ssym", symbol)
continue

if pattern[0] == "`":
pattern = evaluation.definitions.get_current_context() + pattern[1:]
names = evaluation.definitions.get_matching_names(pattern)
for defn in names:
symbol = Symbol(defn)
if not 'System`Locked' in evaluation.definitions.get_attributes(defn):
if not "System`Locked" in evaluation.definitions.get_attributes(
defn
):
items.append(symbol)

Expression("SetAttributes", Expression("List", *items), protected).evaluate(evaluation)
return Symbol('Null')
Expression("SetAttributes", Expression("List", *items), protected).evaluate(
evaluation
)
return SymbolNull


class Unprotect(Builtin):
Expand All @@ -209,20 +218,20 @@ class Unprotect(Builtin):
</dl>
"""

attributes = ('HoldAll',)
attributes = ("HoldAll",)
messages = {
'ssym': "`1` is not a symbol or a string.",
"ssym": "`1` is not a symbol or a string.",
}

def apply(self, symbols, evaluation):
"Unprotect[symbols___]"
protected = Symbol("System`Protected")
items = []
if isinstance(symbols ,Symbol):
if isinstance(symbols, Symbol):
symbols = [symbols]
elif isinstance(symbols, Expression):
symbols = symbols.get_leaves()
elif isinstance(symbols ,String):
elif isinstance(symbols, String):
symbols = [symbols]
else:
symbols = symbols.get_sequence()
Expand All @@ -232,20 +241,24 @@ def apply(self, symbols, evaluation):
items.append(symbol)
else:
pattern = symbol.get_string_value()
if not pattern or pattern=="":
evaluation.message('Unprotect', 'ssym', symbol)
if not pattern or pattern == "":
evaluation.message("Unprotect", "ssym", symbol)
continue

if pattern[0] == "`":
pattern = evaluation.definitions.get_current_context() + pattern[1:]
names = evaluation.definitions.get_matching_names(pattern)
for defn in names:
symbol = Symbol(defn)
if not 'System`Locked' in evaluation.definitions.get_attributes(defn):
if not "System`Locked" in evaluation.definitions.get_attributes(
defn
):
items.append(symbol)

Expression("ClearAttributes", Expression("List", *items), protected).evaluate(evaluation)
return Symbol('Null')
Expression("ClearAttributes", Expression("List", *items), protected).evaluate(
evaluation
)
return SymbolNull


class Protected(Predefined):
Expand Down
2 changes: 1 addition & 1 deletion mathics/builtin/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -4930,7 +4930,7 @@ def apply(self, context, evaluation):
# Already loaded
return SymbolNull

# TODO: Look why this rises the message
# TODO: Figure out why this raises the message:
# "Select::normal: Nonatomic expression expected."
already_loaded = Expression('MemberQ',
Symbol('System`$Packages'), context)
Expand Down
3 changes: 2 additions & 1 deletion mathics/builtin/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Real,
MachineReal,
Symbol,
SymbolNull,
from_python,
)
from mathics.builtin.colors import (
Expand Down Expand Up @@ -242,7 +243,7 @@ def apply(self, path, expr, opts, evaluation):
"""ImageExport[path_?StringQ, expr_, opts___]"""
if isinstance(expr, Image):
expr.pil().save(path.get_string_value())
return Symbol("Null")
return SymbolNull
else:
return evaluation.message("ImageExport", "noimage")

Expand Down
13 changes: 7 additions & 6 deletions mathics/builtin/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
Expression,
String,
Symbol,
SymbolTrue,
SymbolNull,
SymbolFalse,
SymbolTrue,
Integer,
Rational,
strip_context,
Expand Down Expand Up @@ -291,9 +292,9 @@ def apply(self, p1, p2, evaluation):
"PatternsOrderedQ[p1_, p2_]"

if p1.get_sort_key(True) <= p2.get_sort_key(True):
return Symbol("True")
return SymbolTrue
else:
return Symbol("False")
return SymbolFalse


class OrderedQ(Builtin):
Expand All @@ -314,9 +315,9 @@ def apply(self, e1, e2, evaluation):
"OrderedQ[e1_, e2_]"

if e1 <= e2:
return Symbol("True")
return SymbolTrue
else:
return Symbol("False")
return SymbolFalse


class Order(Builtin):
Expand Down Expand Up @@ -657,7 +658,7 @@ def callback(level):
heads = self.get_option(options, "Heads", evaluation).is_true()
result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)

return Symbol("Null")
return SymbolNull


class MapIndexed(Builtin):
Expand Down
2 changes: 1 addition & 1 deletion mathics/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# This file is suitable for sourcing inside POSIX shell as
# well as importing into Python. That's why there is no
# space around "=" below.
__version__="1.1.1dev" # noqa
__version__="1.1.1" # noqa

0 comments on commit cffa8b1

Please sign in to comment.