# Can someone tell me what's wrong with this nested IF? [duplicate]

I have written a very simple nested If as follows

atom = be;

If[atom == li,
lim = 5,

If[atom == be,
lim = 3,

If[atom == b,
lim = 2,

If[atom == c,
lim = 1,

If[atom == n,
lim = 0.5,

If[atom == o,
lim = 0.3,

If[atom == f,
lim = 0.1,

If[atom == ne,
lim = 0.05;

]]]]]]]];
atom
lim


but it works for atom=li namely just for first case, when I set atom=be for example it doesn't work and returns lim as unknown variable. What's wrong with it?

• Use Which instead of If? Dec 5 '21 at 6:41
• Thanks but I want to know why this doesn't work?!! Dec 5 '21 at 6:42
• do you see any problem in my code? Dec 5 '21 at 6:42
• Style of your code is very un-Mathematica, but the root cause of your problem is that atom == li evaluates to be == li which is neither True or False. The correct approach is to use === instead of == on comparison. Dec 5 '21 at 6:55
• If I were you, I'd consider some alternative approach, for instance atomlim = {li -> 5, be -> 3, b -> 2, c -> 1, n -> 0.5, o -> 0.3, f -> 0.1, ne -> 0.05}; atom = be; atom /. atomlim Dec 5 '21 at 7:03

Change it to === and not == (examples at end)

Clear["Global*"];
atom = be;
If[atom === li,
lim = 5,
If[atom === be,
lim = 3,
If[atom === b,
lim = 2,
If[atom === c,
lim = 1,
If[atom === n,
lim = 0.5,
If[atom === o,
lim = 0.3,
If[atom === f,
lim = 0.1,
If[atom === ne,
lim = 0.05
]
]
]
]
]
]
]
];


And now

lim gives 3

Compare the difference

ClearAll[be];
atom = be;
If[atom == li, "yes", "no", "can not decide"]


gives "can not decide" but

ClearAll[be];
atom = be;
If[atom === li, "yes", "no"]


gives "no".

In your original code, you had == which worked as follows (it did not evaluate)

ClearAll[be];
atom = be;
If[atom == li, "yes", "no"]


It did not evaluate, since it could not decide and there was no third argument to use for the result of If, so it returned unevaluated.

That is why your code did not evaluate.

• Thanks a lot. In general, can you tell me when should I use === instead of ==? Dec 5 '21 at 7:09
• @Wisdom The rule of thumb I try to use is this: When you are working with symbols with no values, using ===. When working with things like numbers, strings, etc.. i.e. variables with actual values assigned to them, use == . Help says === that requires exact correspondence between expressions. See help on == and === for more details. For example, if you want to check the Head is say DSolve, then using === and not == since this is symbolic equality (sameQ). I think this topic is covered better in .... Dec 5 '21 at 7:22
• Dec 5 '21 at 7:25
• Thank you so much for your detailed comment, exactly I had used this code for numbers and it didn't had any problem and that is why I wondered it doesn't work here. Thanks again. Dec 5 '21 at 7:28

Alternative using Switch

Clear["Global*"];
atom = be;
lim = Switch[atom,
li, 5, be, 3, b, 2, c, 1, n, 0.5, o, 0.3, f, 0.1, ne, 0.05]


3

Alternative method:

atomLim["li"] = 5;
atomLim["be"] = 3;
atomLim["b"] = 2;
atomLim["c"] = 1;
atomLim["n"] = .5;
atomLim["o"] = .3;
atomLim["f"] = .1;
atomLim["ne"] = .05;


Then you can use atomLim["be"] which gives 3. This code should be faster than using multiple if statements. It is also possible to make this more manageable when the number of elements gets large (I don't know if you're planning to implement the entire periodic table lol)

elements = ToString /@ {li, be, b, c, n, o, f, ne};
limvalues = {5, 3, 2, 1, .5, .3, .1, .05};
Do[
atomLim[elements[[i]]] = limvalues[[i]],
{i, 1, Length@elements}]

• Instead of Do loop, you can also write: MapThread[Set[atomLim[#1], #2] &, {elements, limvalues}] Dec 6 '21 at 17:29