|
7 | 7 | BinaryOperator, |
8 | 8 | Test, |
9 | 9 | MessageException, |
| 10 | + PartRangeError, |
10 | 11 | ) |
11 | 12 | from mathics.core.expression import ( |
12 | 13 | Expression, |
13 | 14 | String, |
14 | 15 | Symbol, |
| 16 | + SymbolTrue, |
| 17 | + SymbolFalse, |
15 | 18 | Integer, |
16 | 19 | Rational, |
17 | 20 | strip_context, |
18 | 21 | ) |
19 | | -from mathics.core.rules import Pattern |
| 22 | +from mathics.core.rules import Pattern, Rule |
20 | 23 |
|
21 | | -from mathics.builtin.lists import python_levelspec, walk_levels, InvalidLevelspecError, List |
| 24 | +from mathics.builtin.lists import ( |
| 25 | + python_levelspec, |
| 26 | + walk_levels, |
| 27 | + InvalidLevelspecError, |
| 28 | + List, |
| 29 | +) |
22 | 30 | from mathics.builtin.functional import Identity |
23 | 31 |
|
24 | 32 | import platform |
@@ -524,25 +532,44 @@ class MapAt(Builtin): |
524 | 532 | <dd>applies $f$ to the element at position $n$ in $expr$. If $n$ is negative, the position is counted from the end. |
525 | 533 | </dl> |
526 | 534 |
|
| 535 | + Map $f$ onto the part at position 2: |
527 | 536 | >> MapAt[f, {a, b, c, d}, 2] |
528 | 537 | = {a, f[b], c, d} |
| 538 | +
|
| 539 | + Map $f$ onto the at the end: |
529 | 540 | >> MapAt[f, {a, b, c, d}, -1] |
530 | 541 | = {a, b, c, f[d]} |
| 542 | +
|
| 543 | + Map $f$ onto an association: |
| 544 | + >> MapAt[f, <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4, "e" -> 5|>, 3] |
| 545 | + = {a -> 1, b -> 2, c -> f[3], d -> 4, e -> 5} |
| 546 | +
|
| 547 | + Use negative position in an association: |
| 548 | + >> MapAt[f, <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>, -3] |
| 549 | + = {a -> 1, b -> f[2], c -> 3, d -> 4} |
531 | 550 | """ |
532 | 551 |
|
533 | 552 | def apply(self, f, expr, n, evaluation, options={}): |
534 | 553 | "MapAt[f_, expr_, n_Integer]" |
535 | 554 | i = n.get_int_value() |
536 | 555 | m = len(expr.leaves) |
537 | 556 | if 1 <= i <= m: |
538 | | - j = i -1 |
| 557 | + j = i - 1 |
539 | 558 | elif -m <= i <= -1: |
540 | 559 | j = m + i |
541 | 560 | else: |
542 | | - evaluation.message('MapAt', 'normal') |
| 561 | + raise PartRangeError |
543 | 562 |
|
544 | 563 | new_leaves = list(expr.leaves) |
545 | | - new_leaves[j] = Expression(f, new_leaves[j]) |
| 564 | + replace_leaf = new_leaves[j] |
| 565 | + if hasattr(replace_leaf, "head") and replace_leaf.head == Symbol("System`Rule"): |
| 566 | + new_leaves[j] = Expression( |
| 567 | + "System`Rule", |
| 568 | + replace_leaf.leaves[0], |
| 569 | + Expression(f, replace_leaf.leaves[1]), |
| 570 | + ) |
| 571 | + else: |
| 572 | + new_leaves[j] = Expression(f, replace_leaf) |
546 | 573 | return List(*new_leaves) |
547 | 574 |
|
548 | 575 |
|
@@ -854,9 +881,9 @@ def apply(self, expr, form, evaluation): |
854 | 881 |
|
855 | 882 | form = Pattern.create(form) |
856 | 883 | if expr.is_free(form, evaluation): |
857 | | - return Symbol("True") |
| 884 | + return SymbolTrue |
858 | 885 | else: |
859 | | - return Symbol("False") |
| 886 | + return SymbolFalse |
860 | 887 |
|
861 | 888 |
|
862 | 889 | class Flatten(Builtin): |
@@ -1060,6 +1087,7 @@ def insert_leaf(leaves): |
1060 | 1087 | new_leaves.append(Expression(h, *insert_leaf(group))) |
1061 | 1088 |
|
1062 | 1089 | return new_leaves |
| 1090 | + |
1063 | 1091 | return Expression(h, *insert_leaf(leaves)) |
1064 | 1092 |
|
1065 | 1093 | def apply(self, expr, n, h, evaluation): |
|
0 commit comments