tags:

views:

346

answers:

10

If a variable can take n values should we check for the validity of the values or assume that if all the n-i checks fail it would be the nth value.

For example if we have a variable that stores gender as M or F. Use this:

If gender = "M"
   do male_processing
else
   do female_processing
endif

Or this:

If gender = "M"
  do male_processing
else
  if gender = "F"
     do female_processing
  else
     print "Something has gone wrong Gender has a value " Gender
  endif

endif
+4  A: 

Shortly - that depends on what type the variable is. If it's a boolean or an enumeration of some sort and there's no other value it can possible have (including null), a simple else clause will suffice.

You can even add a simple comment like so:

if male:
    do_male_stuff()
else: #obviously female
    do_female_stuff()

Having something like this just seems wrong:

bool = SOME_BOOLEAN_VALUE
if bool:
    do1()
elif not bool:
    do2()
else:
    huh() #?!?!

Bottom line: have an if/else/else if clause for each possible scenario, but no more than that, and keep it readable.

Yuval A
A: 

If a third value, other than M or F, is possible, you should use the second form. If the variable being tested is of a type that can only take on the values M and F, you should use the first.

anon
Not necessarily. If some (any) value other than M or F is possible, then it may be that they want "do_female_stuff()" to be the default action - in which case, you likely still only want two options ("M" or *other*). However, you would definitely want to comment that it's an intentional default.
hemp
I'm sooo glad you didn't include an illustration of this.
T.E.D.
@hemp It is obvious from the OP's second example, which is supposed to be congruent with the first, that this is is not the case.
anon
+2  A: 

...or, in OO world you could create a base class, say Gender and extend it with Male and Female classes. Instead of assigning value 'M' or 'F' to a variable, you could assign an instance of Male or Female class. Then simply call a method specified in the base class, for example doGenderSpecificStuff(). No need for if-elses there.

fish
OP is asking specifically about if-else clauses. Of course this can be done in an OO way, but this is not the question.
Yuval A
Then what is the point of having if-else??
VoodooChild
@Yuval: If the OP finds this answer inappropriate, I will remove it. But please let the OP decide.
fish
@VoodooChild: You may still need it with for example boolean values.
fish
Even if you use polymorphism to expose the selection, the selection still has to be made. For example, if the data set only contains "M" or "F" then you will need, for instance, a Factory Method to choose based on the value (M or F) whether to construct a Male object or a Female object. That factory method will likely contain an if/else or a switch - which is still the question the OP is asking.
hemp
+10  A: 

For that example, I wouldn't use IF at all, I'd either use SWITCH for your second example

switch (gender) 
    case "M":
        do male_processing
        break
    case "F":
        do female_processing
        break
    default:
        print "Something has gone wrong Gender has a value " Gender
 endswitch

or for your first example, I'd simply treat exceptions as an error using ASSERT

assert (gender = "M" or gender = "F")
blissapp
Not all languages can `switch` on all variable types... Most languages however do have if-else constructs.
Yuval A
+1 - not for the switch, but just for treating the third case. You -**SHOULD** treat the third case - doesn't matter if it's an `ELSE`, `DEFAULT`, `ASSERT` or however you do it. Check for it. Your follower/future self will thank you.
Konerak
+1  A: 

For this type of construct, I like to use the switch statement. Not because it is shorter (it is not), but it is more readable (IMHO):

switch(gender) {
  case "M":
    doMaleSpecificStuff();
    break;
  case "F":
    doFemaleSpecificStuff();
    break;
  default:
    throw AnyError;
}
Marc
+1  A: 

If the values of gendre can only be 'M' or 'F', then you could use an assert to make this clear:

Assert(gender = "M" OR gender = "F")
If gender = "M"
   do male_processing
else
   do female_processing
endif
GarethOwen
A: 

When enumerating ways to handle the various possible forms of a datatype, you should use pattern matching if your language supports it or, if it doesn't, switch statements (the poor man's pattern matching). The main reason for this is that, should the datatype be extended with more potential forms, you want to be warned at compile time about an incomplete pattern match (or switch statement.) Thus you can rest easy knowing that, should datatypes be extended, you'll find out about it sooner rather than later.

Using a default case unfortunately undoes such benefits, so in most situations you should prefer to enumerate all known possibilities explicitly.

pelotom
A: 

If there is an user input for 'F' or 'M' then you should threat 3 scenarios ie. F , M and other. If there is no user input, you can use two and have a bool value ie. isMale for if statement so it would be far more readable.

eugeneK
+1  A: 

If you use enumerated type then it will only have the values you expect and you don't have to deal with unexpected values in the IF, only at assignment.

leancz
A: 

Try to check inputs and normalise as soon as possible, then you can safely use the first option.

If your user interface allows the input to this variable to be anything (e.g. a text box), then in your example, you could get "M", "Male", "Man", "Boy" or "Männlich" as possible honest inputs for male, before even considering that someone might proffer a stupid answer. By checking (and normalising) these values before you need to use them, you can offer more responsive feedback to the user.

If your user interface constrains this to a radio button, then it is normalised even earlier.

If the value is fetched from some kind of data store, then, depending on the application, and your knowledge of the integrity of that datastore, there may or may not be any value in checking the validity of the record prior to acting upon the values held within.

If most records are likely to conform, and the actions that various values invoke are cheap and reversible, I'd use the second option, and throw an exception if a value is inappropriate.

Paul Butcher