Mathematica Asked by Saeki Amae on December 21, 2020
Ok, so here is example code:
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p, k] = 0;
p
After that I get the message
Set::write: Tag If in If[True,p,k] is Protected.
And p is still 2 instead of 0.
How can I make the p equal to 0 in this case?
EDIT: My question is general – how to return the symbol from some function, not only If – and be able to change its value later (for example by Set)
EDIT #2: I know that with associations I can do that easily:
Clear[p, flag, k];
v = <||>;
v[p] = 2;
v[k] = 1;
flag = True;
v[If[flag, p, k]] = 0;
v[p]
I just wish I could the same just on symbols..
Here are two methods that are essentially the same.
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
Evaluate[If[flag, p =.; p, k =.; k]] = 0;
p {* 0 *}
If you want to use a function, maybe this method:
Clear[func, p, flag, k];
func[flag_?BooleanQ, str1_String, str2_String] := If[flag,
Clear[str1]; ToExpression[str1],
Clear[str2]; ToExpression[str2]]
p = 2;
k = 1;
flag = True;
Evaluate[func[flag, "p", "k"]] = 0;
p (* 0 *)
The salient points are (1) the symbol must be cleared or unset and (2) use Evaluate
on the left side of the equals sign.
Answered by LouisB on December 21, 2020
Here is a fairly concise but still silly way to do it.
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
ToExpression[If[flag, "p", "k"] <> "=0"];
p
0
However, I would rather write
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p = 0, k = 0];
p
and, I believe, so would everybody else. it is the standard practice and is both more concise and efficient then any playing games to limit the code to one written Set
expression.
Answered by m_goldberg on December 21, 2020
At first I wasn’t sure how to realize this, but upon seeing m_goldberg’s example with Set
inside of If
, it hit me:
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, Set[p,#], Set[k,#]]&[0];
p
And this, of course, returns 0
if flag = True
and 2
if flag = False
.
It might be easier to see it this way:
Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p=#, k=#]&[0];
p
which also works like the above. You could streamline this a bit more & wrap it into a function, but I think this answers your question & gives it to you in a form that is loose enough for you to modify to your desires! Nothing fancy, just anonymous functions.
Answered by CA Trevillian on December 21, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP