# Which function not giving numerical answer [closed]

Here's my problem:

My functions:

Xhcmaleorfemale[maleorfemale_,h_] :=
Which[ (h<3|h>7),0,(h>2&&h<8),
Which[maleorfemale==0,Xhcmale,maleorfemale==1,Xhcfemale][[h-2]] ];

X[t_,h_,region_,hc_,nh_,maleorfemale_] :=
((1+growthLTC)^(t/12))*(Which[ hc==1,Xhcmaleorfemale[maleorfemale,h],
nh==1,Xnh [[region]] ]);


Xhcmale and Xhcfemale are two lists defined this way:

Xhcmale={45.33,113.12,215.22,312.67,449.85};
Xhcfemale={77.76,113.12,215.22,312.67,449.85};


Now I want to test the functions to see the results:

X[0,1,1,1,0,1] (* technically 0 in the 1st argument and 1 in the 4th or 5th is not possible but just for a test *)
X[12,3,1,1,0,1]
X[12,7,1,1,0,1]


The results should be:

0
(1+.035)^(12/12)*77.76=80.4816
(1+.035)^(12/12)*449.85=465.595


Instead this is what I get:

1. Which[True | False, 0, 1 > 2 && 1 < 8,
Which[1 == 0, Xhcmale, 1 == 1, Xhcfemale][[1 - 2]]]

80.4816

465.595


I have often this problem with Which and If functions. What am I doing wrong or what should I change? Thanks a lot, answers have been rapidly coming.

-

## closed as too localized by Yves Klett, Artes, m_goldberg, Sjoerd C. de Vries, SilviaMay 10 '13 at 19:16

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

Don't use | use the logical Or || in (h<3|h>7) –  Matariki May 10 '13 at 11:52

As Matariki pointed out in comments, this is a simple syntax error. The infix version of Or in Mathematica is ||, not |.

Change this, like so:

Xhcmaleorfemale[maleorfemale_, h_] :=
Which[(h < 3 || h > 7), 0, (h > 2 && h < 8),
Which[maleorfemale == 0, Xhcmale, maleorfemale == 1,
Xhcfemale][[h - 2]]];


And you will get sensible answers, bearing in mind that growthLTC wasn't defined in your question.

In[38]:= X[0, 1, 1, 1, 0, 1]
Out[38]= 0

In[39]:= X[12, 3, 1, 1, 0, 1]
Out[39]= 77.76 (1 + growthLTC)

In[40]:= X[12, 7, 1, 1, 0, 1]
Out[40]= 449.85 (1 + growthLTC)


As a general comment on your code, I think you would find it useful to use Condition statements and pattern matching in your definition of Xhcmaleorfemale to exclude nonsense inputs.

Xhcmaleorfemale[maleorfemale_Integer, h_Integer?Positive] /;
h > 2 && (maleorfemale == 0 || maleorfemale == 1) :=
Which[(h < 3 || h > 7), 0, (h > 2 && h < 8),
Which[maleorfemale == 0, Xhcmale, maleorfemale == 1,
Xhcfemale][[h - 2]]];


More generally, since you have defined the maleorfemale input to Xhcmaleorfemale via a result of X, I think you would have more readable code if you used Boolean (True/False) values not zero and 1.

Finally, and this isn't a Mathematica-specific issue, I don't think it's good practice to create a variable that is 1 or True when male, and 0 or False when female, and then call it maleorfemale. Your code becomes less readable. It does matter how you name your variables. For more on this, I recently read The Art of Readable Code by Dustin Boswell and would recommend it even though it isn't specifically about Mathematica.

I would suggest that you instead have a variable isMale that takes a Boolean value. So your code would become the much simpler:

Xhcmaleorfemale[isMale : (True | False), h_Integer?Positive] /;  h > 2 :=
Which[(h < 3 || h > 7), 0, (h > 2 && h < 8),
If[isMale, Xhcmale, Xhcfemale][[h - 2]]];


Notice the use of the single pipe |. This is for Alternatives in patterns, which is not the same as Or.

-