Repository navigation
Part assignment: lists of positions, All, negative positions and position 0 - #2083
Conversation
x[[{2, 5}]] = v crashed (SubExpression returned None for a
ListExpression position), x[[All, 1]] = v assigned to x[[1]] instead of
the first element of every row, x[[-1]] = v wrote the wrong element, and
a part that does not exist raised IndexError after some parts had
already been changed.
Positions are now resolved and checked before anything is replaced:
a list of positions, All and a Span select several parts, negative
positions count from the end, and a missing part gives Part::partw and
leaves the value unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
l[[0]] = f with l a List, m[[2, 0]] = g on a nested List, and k[[0]] = List crashed with a TypeError: a List cannot take another head in place. The part is now replaced by a new expression with the new head. The value assigned to is held while it changes, so that the value itself can be replaced as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pa[[{2, f[x]}]] = 5 raised an AttributeError; it now gives the message
WMA gives and leaves pa unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When I first tried using Mathics (as it was called back then) on these examples, I was very depressed by how badly it did. And I had very little in the way of even being able to easily isolate problems. And that's why I had to start with the older version of this, which was much simpler, albeit slower and more primitive. This is just to say a world of thanks for undertaking getting Mathics3 at least to the state that Mathematica was circa 2003! Any chance of getting these examples from the book into the Combinatorica package's test suite? |
|
There may still be problems here with negative indices. I see In[4]:= part = {1, 2, 3}; part[[-4]] = 0; part
part = {1, 2, 3}; part[[-4]] = 0; part
Out[4]= 0[1, 2, 3] (* Should there appear a Part::pw message above? *)
In[5]:=
In[5]:= part = {1, 2, 3}; part[[{ -4, 2}]] = {x, y}; part
part = {1, 2, 3}; part[[{ -4, 2}]] = {x, y}; part
Out[5]= x[1, y, 3] (* should there also be a Part:pw message above? *) |
part[[-4]] = 0 on a list of three elements turned -4 into position 0 and replaced the head, giving 0[1, 2, 3]. A negative position now has to be between -Length and -1, as in WMA; position 0 is reached only as 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@rocky Thank you, that means a lot. The groundwork you did is what made this possible: having Combinatorica in Mathics3 at all, plus its tests, gave us a place to start. Negative indices: you're right, thanks for catching it. With The values match WMA 15. One difference: WMA reports the message as The book's examples in the package's test suite: yes, I'd like to do that. We run every input cell of the book's notebooks (Chapters 3–5, plus the "new features" and tutorial notebooks, about 1,300 cells) under Mathics3 and under WMA 15's Combinatorica, and compare the results. With the PRs in this series, the share of cells that give WMA's result is now:
Most of what is left is speed: the book's timing experiments on large graphs. The plan is to take the cells that pass, are deterministic and run quickly, and add them with WMA's results as a test file in Mathics3-Package-Combinatorica. The cells that still fail will be listed with their reasons, so they turn into tests as they get fixed. I'll open that as a PR there. |
|
A big thanks for this and for picking up the mantle where I have not been able to do so! |
…2084) Found while running the examples of Skiena and Pemmaraju's *Computational Discrete Mathematics* with the Combinatorica package and comparing every result with WMA 15. **Builds on #2083 (Part assignment positions); please merge that one first.** - `b = a; b[[2, 1]] = 9` changed `a` too. - `k[] := (w = {1, {2}}; w[[2, 1]] = 5; w)` changed the definition of `k`. The parts on the way to the assigned position were changed in place, though they may be shared with other values and definitions. They are now copied first. WMA leaves `a` and the definition of `k` alone. Along the way: - A `ListExpression` changed with `set_element` now works out again whether it is literal; before, a stale literal flag could trip an assertion. - Span positions counted from the end, and spans with a negative step, now select the parts WMA selects. `m[[-2 ;; -1, 2]] = 0` changed nothing, and `x[[-1 ;; 1 ;; -2]] = 0` gave a span message. All the fixes from this series together, merged on one branch: full pytest 4336 passed, 0 failed; doctests 4679 passed, 0 failed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: rocky <rb@dustyfeet.com> Co-authored-by: R. Bernstein <rocky@users.noreply.github.com>
Found while running the examples of Skiena and Pemmaraju's Computational Discrete Mathematics with the Combinatorica package and comparing every result with WMA 15.
Part assignment crashed or changed the wrong parts in several cases:
x[[{2, 5}]] = vcrashed:SubExpressionreturnedNonefor a ListExpression position.x[[All, 1]] = vassigned tox[[1]]instead of the first element of every row.x[[-1]] = vwrote the wrong element.IndexError, after some parts had already been changed.l[[0]] = fon a List,m[[2, 0]] = gon a nested List, andk[[0]] = ListraisedTypeError.x[[{2, f[y]}]] = vraisedAttributeError.Positions are now resolved and checked before anything is replaced. A list of positions,
Alland aSpanselect several parts, and negative positions count from the end. A missing part givesPart::partwand leaves the value unchanged, and a non-integer position givespkspec1. Assigning to position 0 replaces the part by a new expression with the new head. The value is held while it changes, so the value itself can be replaced too.All the fixes from this series together, merged on one branch: full pytest 4336 passed, 0 failed; doctests 4679 passed, 0 failed.
🤖 Generated with Claude Code