1
$\begingroup$

I'm trying to do a small page counter with Mathematica, for leting me know about my reading progress on some books. I'm stuck on a problem:

Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6}
a[[1]] = 0
v1

With this, I'm trying to give 0 as a value to v1, but it seems that it swaps the v1 for 0 instead. I was expecting the evaluation of v1 to give me 0 as a value, but it still gives me v1, I've managed to partialy solve this with the following addition:

Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6}
Evaluate[a[[1]]] = 0
v1

When the v1 is evaluated, it gives me 0 as output, but it's not working in my program and I have no idea why this is happening.

I've also managed to perform a separate test by evaluation both:

Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6}
Evaluate[a[[1]]] = 0
v1

Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6}
a[[1]] = 0
v1

In this case, it the outputs for both v1's are v1. Why is this happening?

My program(If needed):

Clear["Global`*"]
g = 1; i = 1; l = {}; ln = {}; pi = {}; m = 1;
r1 := AppendTo[l, ToExpression["p" <> ToString[i++]]]
r2 := AppendTo[ln, n]
r3 := Clear[n]
r4 := AppendTo[pi, np] 
r5 := Clear[np]
r6 := Evaluate[l[[m]]] = 0 
r7 := m++

o1 = Button["+1", r1; r2; r3; r4; r5; r6; r7, ImageSize -> {30, 19}];
o2 = InputField[Dynamic[n], String, FieldSize -> {15, 1}];
o3 = InputField[Dynamic[np], Number, FieldSize -> {4, 1}];
o4 = {o1, o2, o3};
o5 = Style["Book", 12];
o6 = Style["Book Title", 12];
o7 = Style["# Pages", 12];
o8 = {o5, o6, o7};

Grid[{o8, o4}, Frame -> True]

t = Table[Button[ToString[x], Delete[l, {x}]], {x, 1, Length[l]}] // 
  Dynamic
l // Dynamic
ln // Dynamic
pi // Dynamic
$\endgroup$
2
  • $\begingroup$ Your "failing test" performs as expected here. (Mma 8.0, Win) $\endgroup$ Jan 10, 2013 at 6:46
  • $\begingroup$ I'm on 8.0 Win too. $\endgroup$
    – Red Banana
    Jan 10, 2013 at 7:07

2 Answers 2

6
$\begingroup$

It is because a[[1]] does not evaluate to v1 in the case of assignment a[[1]] = 0 because Set (=) has attribute HoldFirst:

In[1]:= Set // Attributes

Out[1]= {HoldFirst, Protected, SequenceHold}

So you just reassign the first element of the list a to 0:

In[6]:= Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6};
a[[1]] = 0;
a

Out[9]= {0, v2, v3, v4, v5, v6}

In the case of assignment Evaluate[a[[1]]] = 0 you override this attribute and assign to the variable v1 (if it is undefined).

The third piece of code in your question works as expected on my machine:

In[13]:= Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6};
Evaluate[a[[1]]] = 0;
v1

Clear["Global`*"]
a = {v1, v2, v3, v4, v5, v6};
a[[1]] = 0;
v1

Out[16]= 0

Out[20]= v1

P.S. You may be interested in this discussion: "Elegant manipulation of the variables list."

$\endgroup$
8
  • $\begingroup$ Did you see it doesn't work in the program? I have no idea why it's not working there. Did you test this solution with the entire program? $\endgroup$
    – Red Banana
    Jan 10, 2013 at 7:02
  • $\begingroup$ @GustavoBandeira I tried your program, but I was not able to understand what is the expected result $\endgroup$ Jan 10, 2013 at 7:10
  • $\begingroup$ @GustavoBandeira Your test code works as expected, see updated answer. $\endgroup$ Jan 10, 2013 at 7:11
  • $\begingroup$ @belisarius It's still not ready. I want to do a table with ProgressIndicators and a + button to increment the page by one. $\endgroup$
    – Red Banana
    Jan 10, 2013 at 7:20
  • 2
    $\begingroup$ @GustavoBandeira As to your program, you may start debugging it with replacement of the first Dynamic with Table[With[{x = x}, Button[ToString[x], l = Delete[l, {x}]]], {x, 1, Length[l]}] // Dynamic. I should note that the overall design is not clear and not very Mathematica and instead of debugging I would rewrite this program in more Mathematica-style from scratch. $\endgroup$ Jan 10, 2013 at 7:25
1
$\begingroup$

Please see Assigning values to a list of variable names, my answer to it, and the four linked questions in the comment below the question. There you will find a better alternative (indexed variables) and a way to work with a list of symbols should you insist.

A brief example:

assign[symbols_, idx_, val_] := symbols[[{idx}]] /. _[x_] :> (x = val)

a = Hold[v1, v2, v3, v4, v5, v6];

assign[a, 1, 0];

v1
0
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.