Help with a C# conditional statement dealing with Strings - c#

In my attempt at dissecting a bit of C# I am afraid I do not understand either the goal or the logic of this bit of code:
if (!string.IsNullOrEmpty(str2) && (Strings.UCase(Strings.Left(str2, 1)) != Strings.Left(str2, 1)))
{
return false;
}
I understand the first part is checking if str2 is "not null", however the second part is coming off a bit flaky. So we UCase the first character of str2, and if it does not equal the first character of str2 (which is NOT "UCase"d), then return "false"?
Maybe I am not missing anything and what I described above is in fact what the code is doing. If this is the case, can we reform this into something else that offers the same result,say for example, check if str2 is uppercase or not? I feel like this is the end goal.
You thoughts?

Yes, you understood the code right.
It looks like something translated from VB using a translation tool, as it's using functions from the VisualBasic namespace. I would rather write it with String methods:
if (!String.IsNullOrEmpty(str2) && str2.Substring(0,1).ToUpper() != str2.SubString(0,1)) {
return false;
}
Or simply getting the first character as a character instead of as a string, and use the IsLower method of the Char class:
if (!string.IsNullOrEmpty(str2) && Char.IsLower(str2[0])) {
return false;
}

My bet is that they are really just testing whether the first character is uppercase. The initial "IsNullOrEmpty" test is just there to make sure that the real test doesn't throw an exception.
The big question: if there is no string value (null or empty) this will not return false. Is that the expected outcome?

Code Objective in English :)
If the non-empty string begins with a lower case character then return false

This is the same, but refactored:
if (!string.IsNullOrEmpty(str2)) {
string s = Strings.Left(str2, 1);
if (Strings.UCase(s) != s) {
return false;
}
}
It is clear that this code tests that the first letter of str2 is or isn't in uppercase when it has any character.

I share the perceptions you have when you say : "I do not understand either the goal or the logic of this bit of code" :) A test that returns only 'false is "fishy" : presumably "something" is waiting for a boolean to be returned, and nothing is returned if the result of this evaluates to 'true.
But if I had to write such a function I'd use the alternative OR logic :
return (! (String.IsNullOrEmpty(testString) || testString.ToUpper()[0] == testString[0]));

Related

c# Strange Pairs || I can't spot the difference between these 2 solutions?

I tried a challenge on edabit.com
It is about "strangepairs".
So the task is to return true if
"The 1st string's first letter = 2nd string's last letter.
The 1st string's last letter = 2nd string's first letter."
...also return true if both strings are null.
Who can spot the difference? Thanks in advance.
My Attempt:
public class Program
{
public static bool IsStrangePair(string str1, string str2)
{
if (str1[0] == str2[str2.Length - 1] && str2[0] == str1[str1.Length - 1])
return true;
if (str1 == "" && str1 == str2)
return true;
return false;
}
}
Their answer:
using System.Linq;
public class Program
{
public static bool IsStrangePair(string str1, string str2)
{
if(string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2))
{
return str1 == str2;
}
return str1.First() == str2.Last()
&& str2.First() == str1.Last();
}
}
I can't spot the difference. Can someone please tell me why my solution produces an IndexOutOfRangeException and theirs doesn't? My solution works overall, all but for 2 cases.
Sadly I can't see what the cases are, and I don't understand under which circumstances would produce this error.
the task is to ... return true if both strings are null.
Your code crashes if both strings are null.
You should always try the test cases that are specifically mentioned in the assignment.
You should internalize this for interviews as well; I frequently have interview candidates where I give them a coding task, I give them some sample inputs and outputs, and they never bother to verify that their code works on the sample inputs and outputs.
I don't understand under which circumstances would produce this error.
Always think about what test cases would crash your code. Think like an attacker. Suppose you were given your code and given the task "find a way to make it crash". What would you do? The easiest thing to start with is null and empty strings, so start with those.

UPDATE Keyword Equivalence From Java to C#

I am converting code from Java to C#, but having issues figuring out some keyword equivalence. I have looked over the web and can't find anything. Updated added number 3.
1) Does anyone know what C# uses for charAt()? Below is how I am trying to use it.
curr = tokens[i].charAt(0);
2) Also having issues converting isEmpty() to C# syntax.
if (par.isEmpty())
3) How should I convert this:
op2 = compute.pop().intValue();
Thanks!
1) Strings can have their characters accessed by using the [] operator:
curr = (tokens[i])[0];
2) IsEmpty becomes String.IsNullOrEmpty or String.IsNullOrWhiteSpace depending on what you want (the second is only available in .NET 4+ as well).
3) From what research I could find, it looks like intValue deals with boxing/unboxing. If you stick with working with ints, you shouldn't need to worry about that in C#. "Pop" will work the same if you have a Stack collection. Hopefully that gives you enough to convert the line.
1) In C# a string is also an array of characters.So you can access a character using the indexer:
curr = tokens[i][0]
2) You can compare your string with string.Empty or use String.IsNullOrEmpty method to check whether a string is empty or not:
if( par == string.Empty )
OR:
if( string.IsNullOrEmpty(par) );
Assuming tokens[i] is a string, treat the string as an array of characters:
var firstCharacter = tokens[i][0];
Assuming par is also a string, the string.IsNullOrEmpty() method can help you test whether or not a particular string is empty:
if (string.IsNullOrEmpty(par))
{
}
If par is a Stack<String> as you've indicated, then you could test whether it was empty (has no elements) with a simple bit of LINQ:
if (!par.Any())
{
// par has no elements
}
Alternatively, you could use the Count property in the Stack class:
if (par.Count == 0)
{
// par has no elements
}
A different approach:
1) You can use curr = tokens[i].ElementAt(0); This will return the same result as charAt(0)
2) if( string.IsNullOrEmpty(par) ); will do the job.

does contain and does not contain in same if

For some reason i cannot get this if statement to work
if (htmlCode.Contains("Sign out") && !htmlCode.Contains("bye bye"))
{
// do stuff...
}
is there any way to get contains and does not contain to work in same if statement?
First of all check the htmlCode, the text could be mixed with some html tags or something like that, also the issue can be with cases, when trying to find some string in the text you should always remember about cases.
You can use .Contains method or .IndexOf, actually the contains method in the Framework is implemented like this:
public bool Contains(string value)
{
return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}
For comparing large strings without knowing the case I would use:
htmlCode.IndexOf("Sign out", StringComparison.InvariantCultureIgnoreCase);
htmlCode.IndexOf("Bye bye", StringComparison.InvariantCultureIgnoreCase);
If you know that response will be small, you can use .ToLower() or .ToUpper()
Try to compare by converting either upper case or lower case.
if (htmlCode.ToUpper().Contains("SIGN OUT") && !htmlCode.ToUpper().Contains("BYE BYE"))
{
// do stuff...
}
You if clause works correctly
It might be not working because of the string case
So i would suggest you do it this way
if (htmlCode.ToUpper().Contains("Sign out".ToUpper()) && !htmlCode.ToUpper().Contains("bye bye".ToUpper()))

Why does my comparison always return false?

I have bunch of usernames in this arraylist and I want to check whether username exists in the arraylist or not but the method always returns false.
public bool check_username(ArrayList userList, string username)
{
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].ToString() == username)
{
return true;
}
}
return false;
}
Consider making your string comparison case insensitive.
username.Equals(userList[i].ToString(), StringComparison.OrdinalIgnoreCase);
Or, assuming all elements of your ArrayList userList are strings, and you're using .NET 3.5 or later, you can simplify this using LINQ:
public bool check_username(ArrayList userList, string username)
{
return userList.Cast<string>()
.Any(s => s.Equals(username, StringComparison.OrdinalIgnoreCase);
}
Without seeing your list or what you are passing we can't know for sure, but it could be a normalization problem.
Bob, bob, BOB, BOb etc... are not the same when comparing strings.
Replace your if statement with this:
if(userList[i].ToString().ToLower() == username.ToLower())
{
return true;
}
There are several reasons I could think of that could cause that function to always return false.
Are you sure that your userList and username will always have the same casing? It would be a good practice to use .ToLower() or .ToUpper() to insure that the casing matches unless you intend for casing to be part of the match.
Are you sure there is no extra whitespace on either string? It is good practice to use .Trim() when you are comparing strings where there may be extra whitespace.
Using the .Equals() method when comparing string is more reliable than the logical operator ==. Occasionally the logical operator produces incorrect results.
Are you positive that you should be getting a true result? Is it possible one string contains a hidden character that you are unaware of? Use the debugger to check the values of the strings to be sure.

Is it acceptable to only use the 'else' portion of an 'if-else' statement?

Sometimes, I feel like it is easier to check if all of the conditions are true, but then only handle the "other" situation.
I guess I sometimes feel that it is easier to know that something is valid, and assume all other cases are not valid.
For example, let's say that we only really care about when there is something wrong:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
// All the conditions passed, but we don't actually do anything
}
else
{
// Do my stuff here, like error handling
}
Or should I just change that to be:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
Or (which I find ugly):
object value = GetValueFromSomeAPIOrOtherMethod();
if(!((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop))))
{
// Do my stuff here, like error handling
}
Though rare for me, I sometimes feel that writing in this form leads to the clearest code in some cases. Go for the form that provides the most clarity. The compiler won't care, and should generate essentially (probably exactly) the same code.
It may be clearer, though, to define a boolean variable that is assigned the condition in the if () statement, then write your code as a negation of that variable:
bool myCondition = (....);
if (!myCondition)
{
...
}
Having an empty if block with statements in the else is ... just bad style. Sorry, this is one of my pet peeves. There is nothing functionally wrong with it, it just makes my eyes bleed.
Simply ! out the if statement and put your code there. IMHO it reduces the noise and makes the code more readable.
I should preface this by saying that it's my own personal preference, but I find myself usually pulling the validation logic out of the code and into its own validate function. At that point, your code becomes much "neater" by just saying:
if(!ValidateAPIValue(value))
That, in my mind, seems a lot more concise and understandable.
Just using the else part isn't acceptable. You needn't go to the trouble of applying De-Morgan's rule, just not the whole expresssion. That is, go from if (cond) to if (!(cond)).
I think it's completely unacceptable.
The only reason at all would be to avoid a single negation and pair of parentheses around the expression. I agree that the expressions in your example are horrible, but they are unacceptably convoluted to begin with! Divide the expression into parts of acceptable clarity, store those into booleans (or make methods out of them), and combine those to make your if-statement condition.
One similar design I do often use is exiting early. I don't write code like this:
if (validityCheck1)
{
if (validityCheck2)
{
// Do lots and lots of things
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic (version 2)
}
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic. (version 1)
}
Instead I write this:
if (!validityCheck1)
{
// Throw some exception, return false, or do some other simple logic. (version 1)
}
if (!validityCheck2)
{
// Throw some exception, return false, or do some other simple logic. (version 2)
}
// Do lots and lots of things
This has two advantages:
Only a few input cases are invalid, and they have simple handling. They should be handled immediately so we can throw them out of our mental model as soon as possible and fully concentrate on the important logic. Especially when there are multiple validity checks in nested if-statements.
The block of code that handles the valid cases will usually be the largest part of the method and contain nested blocks of its own. It's a lot less cluttered if this block of code is not itself nested (possibly multiple times) in an if-statement.
So the code is more readable and easier to reason about.
Extract your conditions, then call
if(!ConditionsMetFor(value))
{
//Do Something
}
Although this is not always practical, I usually prefer to change
if (complexcondition){} else {/*stuff*/}
to
if (complexcondition) continue;
/*stuff*/
(or break out with return, break, etc.). Of course if the condition is too complex, you can replace it with several conditions, all of which cause the code to break out of what it is doing. This mostly applies to validation and error-checking types of code, where you probably want to get out if something goes wrong.
If I see an "if", I expect it to do something.
if(!condition)
is far more readable.
if(condition) {
//do nothing
}
else {
//do stuff
}
essentially reads, "If my condition is met, do nothing, otherwise do something."
If we are to read your code as prose (which good, self-documenting code should be able to be read in that fashion) that's simply too wordy and introduces more concepts than necessary to accomplish your goal. Stick with the "!".
This is bad style, consider some very useful alternatives:
Use a guard clause style:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
return;
}
// do stuff here
Extract the conditional into its own method, this keeps things logical and easy to read:
bool ValueHasProperty(object value)
{
return (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
}
void SomeMethod()
{
object value = GetValueFromSomeAPIOrOtherMethod();
if(!ValueHasProperty(value))
{
// do stuff here
}
}
Your question is similar to my answer(simplifying the conditions) on favorite programmer ignorance pet peeve's
For languages that don't support an until construct, chaining multiple NOTs makes our eyes bleed
Which one is easier to read?
This:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
Or this:
until (keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
I am of the opinion that the latter is way easier to grok than the first one. The first one involves far too many NOTs and AND conditions makes the logic more sticky, it forces you to read the entire expression before you can be sure that your code is indeed correct, and it will be far more harder to read if your logic involves complex logic (entails chaining more ANDs, very sticky).
During college, De Morgan theorem is taught in our class. I really appreciate that logics can be simplified using his theorem. So for language construct that doesn't support until statement, use this:
while !(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
But since C don't support parenthesis-less while/if statement, we need to add parenthesis on our DeMorgan'd code:
while (!(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key))
And that's what could have prompted Dan C's comment that the DeMorgan'd code hurts his eyes more on my answer on favorite programmer ignorance pet peeve's
But really, the DeMorgan'd code is way easier to read than having multiple NOTS and sticky ANDs
[EDIT]
Your code (the DeMorgan'd one):
object value = GetValueFromSomeAPIOrOtherMethod();
if ( value == null || string.IsNullOrEmpty(value.Prop)
|| !possibleValues.Contains(value.prop) )
{
// Do my stuff here, like error handling
}
..is perfectly fine. In fact, that's what most programmers(especially from languages that don't have try/catch/finally constructs from the get-go) do to make sure that conditions are met(e.g. no using of null pointers, has proper values, etc) before continuing with the operations.
Note: I took the liberty of removing superfluous parenthesis on your code, maybe you came from Delphi/Pascal language.
I do it when my brain can easily wrap itself around the logic of the success but it is cumbersome to understand the logic of the failure.
I usually just put a comment "// no op" so people know it isn't a mistake.
This is not a good practice. If you were using ruby you'd do:
unless condition
do something
end
If your language doesn't allow that, instead of doing
if(a){}else{something}
do
if(!a){something}
I find it to be unacceptable (even though I'm sure I've done it in the past) to have an empty block like that. It implies that something should be done.
I see the other questions state that it's more readable the second way. Personally, I say neither of your examples is particularly readable. The examples you provided are begging for an "IsValueValid(...)" method.
I occasionally find myself in a related but slightly different situation:
if ( TheMainThingIsNormal () )
; // nothing special to do
else if ( SomethingElseIsSpecial () ) // only possible/meaningful if ! TheMainThingIsNormal ()
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ... you see where I'm going here
// and then finish up
The only way to take out the empty block is to create more nesting:
if ( ! TheMainThingIsNormal () )
{
if ( SomethingElseIsSpecial () )
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ...
}
I'm not checking for exception or validation conditions -- I'm just taking care of special or one-off cases -- so I can't just bail out early.
My answer would usually be no....but i think good programming style is based on consistency.....
so if i have a lot of expressions that look like
if (condition)
{
// do something
}
else
{
// do something else
}
Then an occasional "empty" if block is fine e.g.
if (condition)
{ } // do nothing
else
{
// do something else
}
The reason for this is that if your eyes sees something several times, their less likely to notice a change e.g. a tiny "!". So even though its a bad thing to do in isolation, its far likely to make someone maintaining the code in future realize that this particular if..else... is different from the rest...
The other specific scenerio where it might be acceptable is for some kind of state machine logic e.g.
if (!step1done)
{} // do nothing, but we might decide to put something in here later
else if (!step2done)
{
// do stuff here
}
else if (!step3done)
{
// do stuff here
}
This is clearly highlighting the sequential flow of the states, the steps performed at each (even if its nothing). Id prefer it over something like...
if (step1done && !step2Done)
{
// do stuff here
}
if (step1done && step2done && !state3Done)
{
// do stuff here
}
I like the second version. It makes code more clean. Actually this is one of the things I would ask to correct during the code review.
I always try and refactor out big conditions like this into a property or method, for readability. So this:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
becomes something like this:
object value = GetValueFromSomeAPIOrOtherMethod();
if (IsValueUnacceptable(value))
{
// Do my stuff here, like error handling
}
...
/// <summary>
/// Determines if the value is acceptable.
/// </summary>
/// <param name="value">The value to criticize.</param>
private bool IsValueUnacceptable(object value)
{
return (value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop))
}
Now you can always reuse the method/property if needed, and you don't have to think too much in the consuming method.
Of course, IsValueUnacceptable would probably be a more specific name.
1st:
object value = GetValueFromSomeAPIOrOtherMethod();
var isValidValue = (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
if(!isValidValue)
{
// Do my stuff here, like error handling
}
2cnd:
object value = GetValueFromSomeAPIOrOtherMethod();
if(!isValidAPIValue(value))
{
// Do my stuff here, like error handling
}
Are all the expressions really the same? In languages that support short-circuiting, making the change between ands and ors can be fatal. Remember &&'s use as a guard to prevent the other conditions from even being checked.
Be careful when converting. There are more mistakes made than you would expect.
In these cases you may wish to abstract the validation logic into the class itself to help un-clutter your application code.
For example
class MyClass
{
public string Prop{ get; set; }
// ... snip ...
public bool IsValid
{
bool valid = false;
if((value != null) &&
(!string.IsNullOrEmpty(value.Prop)) &&
(possibleValues.Contains(value.prop)))
{
valid = true
}
return valid;
}
// ...snip...
}
Now your application code
MyClass = value = GetValueFromSomewhere();
if( value.IsValie == false )
{
// Handle bad case here...
}
I'm a fan of DeMorgan's Rule which takes your ex3 and produces your ex2. An empty if block is a mental block imo. You have to stop to read the nothing that exists - then you have to wonder why.
If you have to leave comments like // This left blank on purpose; then the code isn't very self-explanatory.
The style that follow to have one block empty of if-else is considered as a bad style..
for good programming practice if you dont have to write in if block you need to put (!) 'Not' in if block ..no need to write else
If(condition)
//blank
else
//code
can be replaced as
if(!condition)
//code
this is a saving of extra line of code also..
I wouldn't do this in C#. But I do it in Python, because Python has a keyword that means "don't do anything":
if primary_condition:
pass
elif secondary_condition1:
do_one_thing()
elif secondary_condition2:
do_another_thing()
You could say that { } is functionally equivalent to pass, which it is. But it's not (to humans) semantically equivalent. pass means "do nothing," while to me, { } typically means "there used to be code here and now there isn't."
But in general, if I get to the point where it's even an issue whether sticking a ! in front of a condition makes it harder to read, I've got a problem. If I find myself writing code like this:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
it's pretty clear to me that what I'm actually going to want over the long term is more like this:
var activeKeys = new[] { escape_key, alt_f4_key, ctrl_w_key };
while (!activeKeys.Contains(keypress))
because that makes explicit a concept ("these keys are active") that's only implicit in the preceding code, and makes the logic "this is what you happens when an inactive key is pressed" instead of "this is what happens when a key that's not one ESC, ALT+F4 or CTRL+W is pressed."

Categories

Resources