1

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
Red Banana
  • 5,329
  • 2
  • 29
  • 47

2 Answers2

6

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."

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
  • 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? – Red Banana Jan 10 '13 at 07:02
  • @GustavoBandeira I tried your program, but I was not able to understand what is the expected result – Dr. belisarius Jan 10 '13 at 07:10
  • @GustavoBandeira Your test code works as expected, see updated answer. – Alexey Popkov Jan 10 '13 at 07:11
  • @belisarius It's still not ready. I want to do a table with ProgressIndicators and a + button to increment the page by one. – Red Banana Jan 10 '13 at 07:20
  • 2
    @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. – Alexey Popkov Jan 10 '13 at 07:25
  • @AlexeyPopkov It's not working here. When I press the + Book Button, it adds a book in the reading list, but trying to call the v1 variable still gives me a variable with no value. – Red Banana Jan 10 '13 at 07:28
  • @GustavoBandeira Your test example with the v1 variable works as expected as I showed in the answer. Does not it work for you? My suggestion in the last comment is not a solution - just a place to start. I just tried to correct the most obvious mistakes in your code. – Alexey Popkov Jan 10 '13 at 07:38
  • @AlexeyPopkov Oh, when I posted my comment, your comment wasn't shown here, slow internet. =/ – Red Banana Jan 10 '13 at 18:03
1

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
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371