what is the replacement of long nested if else construct? - language-agnostic

I have a nested if else construct like below and i wanted to replace this
with the right type of programming statement.
if($provider[0][0]=='A' && $provider[1][0]=='B'){
return 'O';
}elseif($provider[0][0]=='B' && $provider[1][0]=='A'){
return 'O';
}elseif($provider[0][0] == 'A' && $provider[1][0] == '' ){
return 'A';
}elseif($provider[0][0] == 'B' && $provider[1][0] == '' ){
return 'B';
} else{
return 'Return nothing';
}

Not really avoiding nesting, but simplifying the reading:
<?php
function isOprovider($provider) {
return $provider[0][0]=='A' && $provider[1][0]=='B'
|| $provider[0][0]=='B' && $provider[1][0]=='A';
}
function isAprovider($provider) {
return $provider[0][0] == 'A' && $provider[1][0] == '';
}
function isBprovider($provider) {
return $provider[0][0] == 'B' && $provider[1][0] == '';
}
if (isOprovider($provider)) {
return '0';
} else if (isAprovider($provider)) {
return 'A';
} else if (isBprovider($provider)) {
return 'B';
} else {
return 'Return nothing';
}

One of the options to make it more readable-
if($provider[0][0]=='A') {
// other condition(s)
} else if($provider[0][0]=='B') {
// other condition(s)
} else {
// return nothing
}
You may try switch as well. In any case you would need nested conditions.

I would do something like this:
function IsCombinationOf($first, $second, $provider) {
return ($provider[0][0]==$first && $provider[1][0]==$second) ||
($provider[0][0]==$second && $provider[1][0]==$first);
}
if(IsCombinationOf('A', 'B', $provider)){
return 'O';
}
elseif(IsCombinationOf('', '', $provider)){
return 'Return Nothing';
}
elseif(IsCombinationOf('A', '', $provider)){
return 'A';
}
elseif(IsCombinationOf('B', '', $provider)){
return 'B';
}

I would replace most of this code with data and then use a loop to select the correct answer from the data. The idea here is to separate policy and implementation. The policy is: Given different combinations of providers, what do I return? The implementation is.... well, the implementation.
The example is in Ruby, but the idea applies to any language.
The data representing the policy might look like this:
PROVIDER_COMBOS = [
['A', 'B', 'O'],
['B', 'A', 'O'],
['A', '', 'A'],
['B', '', 'B'],
]
and the code that uses it might look like this:
def lookup_provider_combo(provider1, provider2)
PROVIDER_COMBOS.each do |key1, key2, result|
if provider1[0] == key1 && provider2[0] == key2
return result
end
end
return 'Return nothing'
end

Technically speaking that if..else statement is not nested. It is flat. Also, it is technically already at the state of minimum complexity. It is fairly simple code. It does "look" messy though. And the thing that makes it look messy is it's verbosity (don't confuse verbosity/messiness for complexity).
But you are right in complaining about verbosity. Verbose code, especially one with a lot of repeated bits, harms readibility. For the code in the example, one of the first obvious thing you can do to make it more readable is to factor out the array syntax:
p1 = $provider[0][0];
p2 = $provider[1][0];
if (p1 == 'A' && p2 == 'B') {
return 'O';
} elseif (p1 == 'B' && p2 == 'A') {
return 'O';
} elseif (p1 == 'A' && p2 == '' ) {
return 'A';
} elseif (p1 == 'B' && p2 == '' ) {
return 'B';
} else {
return 'Return nothing';
}
This alone removes cruft from the code making the logic clearer. There are other things you can do to remove more repeated bits from the code above to make it even clearer but they all boil down to what the code above does: basically a table of conditions and results.
In languages where the switch statement accept strings as input you can simply concatenate the two conditions into a single string as the switch condition:
switch (join([p1,p2],',')) {
'A,B' : return 'O'; break;
'B,A' : return 'O'; break;
'A,' : return 'A'; break;
'B,' : return 'B'; break;
default : return 'Return nothing'; break;
}
This makes it even more obvious that what you're doing is consulting a table. Alternatively you can achieve a similar layout using the ternary operator:
cond = join([p1,p2],',');
return cond == 'A,B' ? 'O' :
cond == 'B,A' ? 'O' :
cond == 'A,' ? 'A' :
cond == 'B,' ? 'B' :
'Return nothing';
Admittedly that still has the cond == bit repeated. But it is slightly easier to see the table compared to the original if..else statement.
In languages that has a dictionary/associative array/hash, you can simply encode the logic in a data structure and simply read that data structure:
conditions = {
'A' : {
'B' : 'O',
'' : 'A'
},
'B' : {
'A' : 'O',
'' : 'B'
}
}
result = conditions[p1][p2];
return result ? result : 'Return nothing';
Alternatively you can also use the following data structure:
conditions = {
'A,B' : 'O',
'B,A' : 'O',
'A,' : 'A',
'B,' : 'B'
}
result = conditions[join([p1,p2],',')];
return result ? result : 'Return nothing';
Keeping the conditional logic as pure data instead of code makes it even more obvious that what we're doing is looking up a table. Another advantage of keeping the conditions as pure data is that you can potentially create the data structure at runtime by reading it from a file (or from a socket over the internet). For example, the logic can potentially be encoded in a JSON or YAML formatted file and you can make the logic programmable.
As you can see, there are many ways to do this but it depends on what features are available in your programming language. They are all of the same complexity (and most compile to the same thing). The only difference is in terms of readability and maintainability.

Related

Is variable assignment within if conditions possible?

You know how in C and JavaScript variable assignments can take place within conditions, such as
if ( boolean || (val = func(args)) == case1 ) {
/* Perform A */
} else if ( val == case2) {
/* Perform B */
} ...
such that don't need to write another elseif to perform code A.
Can this be done in Tcl; and, if so, how?
It's not very important but I'd like to know just the same.
Thank you.
You can use set and other commands in an expr-ression, and set returns the newly assigned value, so...
set boolean true
proc func {} { return case2 }
if {$boolean && [set val [func]] eq "case1"} {
puts "case 1 found"
} elseif {$val eq "case2"} {
puts "case 2 found"
}

Strcpy Null Value Obtained From MySQL in C

I am using Connector C to connect to my MySQL database. A modification that I have made to the database recently now allows the data in my url field to be NULL. Connector C does not appear to have any problems reading the NULL value, but when I try and pass the value to my array structure using strcpy, the program crashes. Here is a simplified version of my code:
mysql_real_connect(conn, server,user,password,database, port, NULL, 0);
mysql_query(conn, "SELECT * FROM main WHERE propType IN ('Single Family', 'Condominium')");
res = mysql_use_result(conn);
while (((row = mysql_fetch_row(res)) != NULL) && (row[0] != NULL)) {
props[count].uniqueID = atol(row[0]);
strcpy(props[count].address, row[1]);
.
.
.
strcpy(props[count].url, row[55]);
count++;
}
By tracing out output of the rows, I have determined that it is this line of code that is failing, and it is ONLY failing when row[55] is (null):
strcpy(props[count].url, row[55]);
I am fairly new to C, and I assume that the problem lies in trying to use strcpy with a null string.
Any suggestions?
As is suggested above in the comment the problem is that row[55] has the value NULL and so strcpy() will crash. Maybe you want to try the following:
if (row[55] != NULL)
strcpy(props[count].url, row[55]);
else
props[count].url[0] = '\0';
Here is another example code which use a bit to store if the database contains NULL or a empty value:
if (row[55] != NULL)
{
strcpy(props[count].url, row[55]);
props[count].urlEmpty = false;
}
else
{
props[count].url = '\0'; // Maybe you can skip this
props[count].urlEmpty = true;
}
In this case you need to expand your structure.

Use Conditional Split for multiple empty string

I have a scenario where I am generating two .CSV files from one .TXT file source.
One of the transformations required is this:
Identify records that contain at least one field with an empty string or NULL value
Send these records to a separate .CSV file destination
I need to check for this condition across multiple fields.
For example I have these fields in my source .TXT file:
col1
col2
col3
col4
col5
col6
col7
I need to check to see if any of these fields contain an empty string or a NULL value.
I am using a Conditional Split Transformation with this formula:
col1 !=""
That works as expected for one column, but not as expected when I try to write the formula for all columns in my text file:
col1 !="" || col2 !=""...
Some rows with an empty or NULL value in one of the fields are ending up in the wrong .CSV file.
Any help is appreciated!
If I have understood your question correctly, I think you just need to use the following formula in a Conditional Split Transformation:
ISNULL(col1) || ISNULL(col2) || ISNULL(col3) || ISNULL(col4) || ISNULL(col5) || ISNULL(col6) || ISNULL(col7) || TRIM(col1) == "" || TRIM(col2) == "" || TRIM(col3) == "" || TRIM(col4) == "" || TRIM(col5) == "" || TRIM(col6) == "" || TRIM(col7) == ""
There is a difference between an empty string and a NULL, although since your source is a .TXT file this might not be so obvious as it would be if your source was a database table.
Here is the SQL Fiddle for the sample data.
Screenshot of the Conditional Split Transformation Editor
Screenshot of the Data Flow results
Hope this helps.
I Figured it out. Used script component before conditional split to flag the rows.
Code:
/* Microsoft SQL Server Integration Services Script Component
* Write scripts using Microsoft Visual C# 2008.
* ScriptMain is the entry point class of the script.*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
/**string RecordID = "";
string ClientRequestID = "";
string AccountID = "";
string ClientMemberID = "";
string MemberDOB = "";
string ProviderPhone = "";**/
string Flag = "True";
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
if (Row.ClientRequestID == "" || Row.ClientMemberID == "" || Row.AccountID == "" || Row.MemberDOB == "" || Row.ProviderPhone == "")
{
Flag = "False";
}
else
{
Flag = "True";
}
Row.Flag = Flag;
}
}

Whats wrong with these beginner style codes?

I'm a beginner and I was reading https://stackoverflow.com/questions/237241/what-coding-mistakes-are-a-telltale-giveaway-of-an-inexperienced-programmer. I didn't get few things.
1.Why writing something like this is frowned up on?
if (IsAManMan == true) {
Console.WriteLine("It's a MAN, man!");
}
2.what about this?
if (test) {
return true;
}
else {
return false;
}
I don't write code like above. Should it be written this way: return test? or for readability I sometimes write it like return test?true:false or return (test==true)? true:false
In this example:
if (IsAManMan == true) {
Console.WriteLine("It's a MAN, man!");
}
In most languages, if conditions always evaluate a Boolean expression, which means IsAManMan can only either be true or false. Comparing to true or false is thus unnecessary because it's implied. So we just write this instead:
if (IsAManMan) {
Console.WriteLine("It's a MAN, man!");
}
And in this example:
if (test) {
return true;
}
else {
return false;
}
Following the above example, this means test can only either be true or false, which is like saying:
if (true) {
return true;
}
else { // If it's not true, it's false
return false;
}
That's again unnecessarily verbose code, so we just
return test;
instead.
In the end, it's still a matter of preference and readability. For example, if you think if (IsAManMan == true) is easier to interpret than if (IsAManMan), you can still write it that way and the compiler won't mind.
It's just a tautology. If it rains and If it's true that it rains is exactly the same and therefore, you can (or should) leave out superfluous comparisons, checks and returns.
In both cases you're testing the value of a boolean variable. Because your value is already a boolean, there's no need to explicitly test against true because it's implied in the if statement (and similar constructs that contain a boolean test, like loops)
For example
if(isAManMan == true){
//...
}
could evaluate to
if(true == true){ //answer: true
//...
}
or
if(false == true){ //answer: false
//...
}
which is the same as just writing
if(isAManMan){
//...
}
In your 2nd example, you're examining the value of another boolean value before deciding what boolean to return.
Again,
if (test) {
return true;
}else {
return false;
}
could evaluate to
if (true == true) { //returns true
return true;
}else {
return false;
}
or
if (false == true) { //returns false
return true;
}else {
return false;
}
The if statement is redundant, because the variable already holds the value you want to return, hence this is equivalent, and preferred:
return test;
It's important to note though, that your examples are completely valid, however a good compiler will optimise them into the improved versions I gave, so ultimately it comes down to readability and convention. I believe the versions I gave are more readable and closer to the generally accepted conventions.
These codes do same things. In my opinion, its just readability.
Due to this being tagged language-agnostic:
There are languages where keywords can be used for variable names. In FORTRAN, this is a valid statement: IF IF THEN THEN ELSE ELSE.
If true is defined to be a boolean variable with value false, the proposed shorthand solutions are not the same as the more verbose ones. Neither if test, IsAMan, true, and false are not boolean values in the first place.
A real world example in Python 2.0
>>>True = False
>>>True
False
Tongue in cheek.
Say you want to return a boolean, and not the actual value of test for the 2nd case.
You could do
return !!test
in most languages, or something like
return bool(test)
which is more explicit and readable.

How do I write an if else statement in Reporting Services expression language?

I would like to write a Reporting Services "Expression" that basically behaves as the following (pseudo code)...
if ([Fields!StateProvinceId.Value] == 1)
{
return "Ontario";
}
else if ([Fields!StateProvinceId.Value] == 2)
{
return "Quebec";
}
else if ([Fields!StateProvinceId.Value] == 3)
{
return "Manitoba";
}
// ...
// more cases same pattern
I don't see this type of logic do I have to nest a bunch of IIF?
=IIF(Fields!StateProvinceId.Value = 1, "Ontario", IIF(Fields!StateProvinceId.Value = 2, "Quebec", IFF(Fields!StateProvinceId.Value = 3, "Manitoba", "Unknown Province")))
Have you tried a switch statement?
= Switch( Fields!StateProvinceId.value=1,"Ontario", Fields!StateProvinceId.value=2,"Quebec", Fields!StateProvinceId.value=3,"Manitoba")
See "decision functions" on this page for example:
http://msdn.microsoft.com/en-us/library/ms157328.aspx