-7
$\begingroup$

I have the module who should replace some elements of a matrix with checkboxes

addChekboxesTable[x0_] := Module[{x = x0},
  For[i = 1, i <= Length[x], i++,
    For[j = 1, j <= Length[x[[i]]], j++,
     If[x[[i, j]] == "x",
       x[[i, j]] = Checkbox[True];
       ]
      If[x[[i, j]] == "o",
       x[[i, j]] = Checkbox[False];
       ]
      If[x[[i, j]] == "u",
       x[[i, j]] = Checkbox[3, {1, 2, 3}];
       ]
     ]
    ]
   x
  ]

I call the module like:

pp = addChekboxesTable[{{"Datatype", "Variable Name", "S0", "S1", 
     "x"}}];

And then the string is corrupted :( It has some Nulls and Times

List[List[Times["Datatype",Null],Times["Variable Name",Null],Times["S0",Null],Times["S1",Null],Times[Null,Checkbox[True]]]]

I dont know why :(( Any ideas ?

Ps: if i extract the instruction from module, outside , the code works O_O

I changed the function to the next for by adding some ";" at the end of instructions. It fixed but i dont know why O_O

addChekboxesTable[x0_] := Module[{x = x0},
  For[i = 1, i <= Length[x], i++,
   For[j = 1, j <= Length[x[[i]]], j++,
     If[x[[i, j]] == "x",
      x[[i, j]] = Checkbox[True];
      ];
     If[x[[i, j]] == "o",
      x[[i, j]] = Checkbox[False];
      ];
     If[x[[i, j]] == "u",
      x[[i, j]] = Checkbox[3, {1, 2, 3}];
      ];
     ];
   ];
  x
  ]
$\endgroup$

closed as off-topic by Simon Woods, Dr. belisarius, Karsten 7., Mark McClure, Oleksandr R. Dec 19 '14 at 1:58

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – Simon Woods, Dr. belisarius, Karsten 7., Mark McClure, Oleksandr R.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    $\begingroup$ I would suggest putting a ; after each If like If[stuff]; What you have written is If[stuff] * If[more] * If[even more] * x. In Mathematica a b c is abc. $\endgroup$ – Ymareth Dec 18 '14 at 16:07
  • $\begingroup$ i did and didnt solve the corruption $\endgroup$ – TraceKira Dec 18 '14 at 16:13
  • $\begingroup$ Did it change the result? $\endgroup$ – Ymareth Dec 18 '14 at 16:14
  • $\begingroup$ NO it didnt change the result $\endgroup$ – TraceKira Dec 18 '14 at 16:15
  • 8
    $\begingroup$ it is not a hack to use proper syntax $\endgroup$ – chuy Dec 18 '14 at 16:25
4
$\begingroup$

There is a missing semicolon just behind the end of the outer For, just before the x, corrected below.

addChekboxesTable[x0_] := Module[{x = x0}, 
  For[i = 1, i <= Length[x], i++, 
   For[j = 1, j <= Length[x[[i]]], j++, 
    If[x[[i, j]] == "x", x[[i, j]] = Checkbox[True];] If[
      x[[i, j]] == "o", x[[i, j]] = Checkbox[False];] If[
      x[[i, j]] == "u", x[[i, j]] = Checkbox[3, {1, 2, 3}];]]]; x]

The result of the For block is Null so the result, without that semicolon, is Null times x.

$\endgroup$
  • $\begingroup$ The result of the For is not Null or else the code would NOT loop over the elements $\endgroup$ – TraceKira Dec 18 '14 at 16:30
  • 1
    $\begingroup$ Unless an explicit Return is used, the value returned by For is Null. $\endgroup$ – chuy Dec 18 '14 at 16:35
  • $\begingroup$ @timoftebogdan See (details section) here... reference.wolfram.com/language/ref/For.html Like a many Mathematica functions with side effects For returns Null (unless as Chuy points out you explicitly return something from it). That doesn't mean it doesn't do anything. $\endgroup$ – Ymareth Dec 18 '14 at 16:40
  • 2
    $\begingroup$ Mathematica is a functional language (mostly). Everything returns something. Those functions that operate mostly through side effects (like say, Do, For, Scan, Print) return Null. That aside, I'd suggest you take a look at replacement rules as I think that would make your code simpler. $\endgroup$ – Ymareth Dec 18 '14 at 16:51
8
$\begingroup$

Replacement rules make this much easier, as Ymareth indicated.

Make a list of rules like:

r2 = {"x" -> Checkbox[True], "o" -> Checkbox[False], 
   "u" -> Checkbox[3, {1, 2, 3}]};

Then apply these to the matrix m as:

m/.r2

Note that this code is idiomatic Mathematica and imminently readable by anyone familiar with it. Nested For loops and term by term rewriting are both strongly discouraged in Mathematica - and not just for aesthetic reasons - rule based and functional programming are typically much more efficient. Let's compare the two approaches. First, we'll generate a matrix of characters, which is (admittedly) absurdly large to illustrate the point.

m = RandomChoice[{"x", "o", "j"}, {1000, 1000}];

OK, let's try out the approach here:

mOut = m /. r2;  // AbsoluteTiming
mOut[[1;;10,1;;10]] // Grid
(* Out: {0.275804, Null} *)

enter image description here

Just over a quarter second - and looks good too! Let's try the other approach.

addChekboxesTable[m]; // AbsoluteTiming
(* Out: {58.618144, Null} *)

Nearly a full minute.

$\endgroup$
  • $\begingroup$ he already answered.Also this code is unreadable.My code is much beautifull !(procedural programming ftw !) $\endgroup$ – TraceKira Dec 18 '14 at 20:56
  • 3
    $\begingroup$ +1 @TraceKira This code is much more idiomatic and easily readable by anyone who is familiar with Mathematica. This style of programming is also much more efficient in Mathematica, as I've tried to illustrate in my edit. $\endgroup$ – Mark McClure Dec 19 '14 at 0:55
  • 2
    $\begingroup$ @TraceKira If you try to stick with procedural programming in Mathematica your experience will be painful. You are strongly advised to (gradually) embrace the functional style. $\endgroup$ – Ymareth Dec 19 '14 at 8:52

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