Are switch-case statements allowed for multiple conditions? - c#

I was going to do a complex number class, and I appear to have too many conditionals involving multiple statements on one of my functions. Here is a snippet of my program with a ToString() function:
public override string ToString()
{
if (this.real == 0 && this.imaginary == 0)
{
return "0";
}
else if (this.real == 0 && this.imaginary == 1)
{
return "i";
}
else if (this.real == 0 && this.imaginary == -1)
{
return "-i";
}
else if (this.real == 0 && (this.imaginary != 1 && this.imaginary != -1))
{
return String.Concat(this.imaginary.ToString(), "i");
}
else if (this.real != 0 && this.imaginary == 0)
{
return String.Concat(this.real.ToString());
}
else if (this.real != 0 && this.imaginary == 1)
{
return String.Concat(this.real.ToString(), " + i");
}
else if (this.real != 0 && this.imaginary == -1)
{
return String.Concat(this.real.ToString(), " - i");
}
else if (this.real != 0 && this.imaginary < -1)
{
this.imaginary = -this.imaginary;
return String.Concat(this.real.ToString(), " - ", this.imaginary.ToString(), "i");
}
return String.Concat(this.real.ToString(), " + ", this.imaginary.ToString(), "i");
}
Would switch statements be helpful for multiple conditions?

Make code more readable with eliminating redundant checks.
Use string interpolation instead of String.Concat
public override string ToString()
{
if (real == 0)
{
if (imaginary == 0)
{
return "0";
}
if (imaginary == 1)
{
return "i";
}
if (imaginary == -1)
{
return "-i";
}
if (imaginary != 1)
{
return $"{imaginary}i";
}
}
else
{
if (imaginary == 0)
{
return real.ToString();
}
if (imaginary == 1)
{
return $"{real} + i";
}
if (imaginary == -1)
{
return $"{real} - i";
}
if (imaginary < -1)
{
imaginary = -imaginary;
return $"{real} - {imaginary}i";
}
}
return $"{real} + {imaginary}i";
}

You cannot have more than one condition in switch, but it looks like this.real has only two possibilities, 0 or 1, so you can take that out an use a switch for this.imaginary.
Also it is probably better to use String.Format() or String Interpolation instead of String.Concat().
public override string ToString() {
if (this.real == 0) {
switch(this.imaginary) {
case 0:
return "0";
case 1:
return "i";
case -1:
return "-i";
default:
return $"{this.imaginary}i";
}
else {
switch(this.imaginary) {
case 0:
return this.real.ToString();
case 1:
return $"{this.real} + i";
case -1:
return $"{this.real} - i";
default:
if (this.imaginary < -1) {
this.imaginary = -this.imaginary;
return $"{this.real} - {this.imaginary}i";
}
}
}
return $"{this.real} + {this.imaginary}i";
}

Your code is overcomplicated and redundant because you've come up with a separate branch for each possible situation. Your code will be a lot simpler if you break it down and do the following:
Get the real part (if there is one) and the imaginary part (if there is one)
Combine them together if there are two parts
The following will do this:
private string RealPartString()
{
if (real == 0) { return imaginary == 0 ? "0" : null; }
return real.ToString();
}
private string ImaginaryPartString()
{
if (imaginary == 0) { return null; }
var abs = Math.Abs(imaginary);
var number = abs == 1 ? "" : abs.ToString();
// Only include the sign here if there is no real part
var sign = real == 0 && imaginary < 0 ? "-" : "";
return sign + number + "i";
}
public override string ToString()
{
var parts = new[] { RealPartString(), ImaginaryPartString() }.Where(s => s != null);
var sign = imaginary < 0 ? " - " : " + ";
return string.Join(sign, parts);
}

Related

Comma misplaced on RightToLeft label

I'm trying to partially recreate the Windows 10 calculator but have run into some trouble. I have a code that looks like this for when the user enters a comma:
if (label_number.Text != null)
{
label_number.Text += ",";
}
else
{
label_number.Text = "0,";
}
So if the user enters the comma while the string is null I want the string to read out "0," but it only adds the "," to the label. And when I add a comma to a number, it comes out like this ",07839" instead of "07839,". Why is this happening? Like the title says my label is RightToLeft, but this also happens when that option is false.
Edit, here is the entire MouseClick EventHandler
'''
private void MouseClickEvent(object sender, MouseEventArgs e)
{
var obj = (sender as Label);
// Left click
if (e.Button == MouseButtons.Left)
{
if (obj.Name == "button_quit") // Quit
{
Application.Exit();
}
else if (obj.Name == "button_minimize") // Minimize
{
this.WindowState = FormWindowState.Minimized;
}
else if (obj.Name == "button_c") // Reset calc
{
label_input.Text = String.Empty;
label_number.Text = String.Empty;
}
else if (obj.Name == "button_ce") // Clear number
{
label_number.Text = String.Empty;
}
else if (obj.Name == "button_delete") // Delete
{
if (label_number.Text.Length == 1)
{
label_number.Text = String.Empty;
}
else if (label_number.Text.Length > 1)
{
label_number.Text = label_number.Text.Remove(label_number.Text.Length - 1, 1);
}
}
else if (obj.Name == "button_divide" || obj.Name == "button_multiply" || obj.Name == "button_subtract" || obj.Name == "button_add") // / * - +
{
switch (obj.Name)
{
case "button_divide":
break;
case "button_multiply":
break;
case "button_subtract":
break;
case "button_add":
break;
}
}
else if (obj.Name == "button_comma") // Comma
{
if (label_number.Text != String.Empty)
{
label_number.Text += ",";
}
else
{
label_number.Text = "0,";
}
}
else if (obj.Name == "button_equals") // Calculate equation
{
}
else // Number input
{
if (label_number.Text.Length < 13)
{
if (obj.Name != "button_0")
{
if (label_number.Text.Length == 1 && label_number.Text == "0")
{
label_number.Text = obj.Name[obj.Name.Length - 1].ToString();
}
else
{
label_number.Text += obj.Name[obj.Name.Length - 1].ToString();
}
}
else
{
label_number.Text += obj.Name[obj.Name.Length - 1].ToString();
}
}
}
}
}
'''

C# replace do..while with for loop

I usually know how to replace a do..while loop with a for loop, but in this case variable check2 is used 2 times for different loops with got me confused on how to correctly replace it with for loop.
public static void RelayChat(ref int con, ref string Message)
{
string temp_SubName = "relaychat";
WriteSub(ref temp_SubName);
int check2 = 0;
if (Message.Length == 0) return;
var check = UserConToCheck(con);
if (CheckMute(get_UserName(check)) || get_UserChat(check) > 4) return;
if (get_UserChat(check) < 8) set_UserChat(check, get_UserChat(check) + 1);
if (Message.Length > 100) Message = Message.Substring(0, 99);
if (Message[0] == '!')
{
if (UserCommand(con, Message.Substring(1).Split(" ".ToCharArray()))) return;
}
if (PlayerAdapter.get_Reference(check).get_IsAdmin(1))
{
if (Message.Substring(0, 1) == "#")
{
string[] temp_cmds = Message.Substring(1).Split(",".ToCharArray());
admin.AdminCommand(PlayerAdapter.get_Reference(check), ref temp_cmds);
return;
}
}
if (Message.StartsWith(":g::", true, null))
{
do
{
check2++;
var guild1 = get_UserGuild(check);
var guild2 = get_UserGuild(check2);
if (guild1 == null || guild2 == null || guild1.ToLower() != guild2.ToLower()) continue;
var thisuser = get_UserName(check);
var targetuser = get_UserName(check2);
var found = targetuser != null && thisuser != null &&
IgnoreUserList.ContainsKey(targetuser) &&
IgnoreUserList[targetuser].Contains(thisuser);
if (found == false)
{
Winsock.PrivMsg(get_UserCon(check2), "14,1,[ " + get_UserGuild(check2) + " ] Chat - " + get_UserName(check) + " : " + Message.Substring(4));
}
} while (check2 != UserMax);
return;
}
if (check <= 0) return;
do
{
check2++;
bool found = false;
var user = get_UserName(check2);
if (user != null && IgnoreUserList.ContainsKey(user))
{
found = Convert.ToBoolean(IgnoreUserList[get_UserName(check2)].Contains(get_UserName(check)));
}
if (found) return;
if (get_UserLanded(check2) != get_UserLanded(check)) return;
if (get_UserLanded(check2))
{
if (get_UserInBar(check2) == false &&
get_UserInUniversalBar(check2) == false) return;
if (get_UserInUniversalBar(check2) && get_UserInUniversalBar(check))
{
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
else if (get_UserInBar(check2) && get_UserInBar(check))
{
if (get_UserLastPlanet(check2) !=
get_UserLastPlanet(check)) return;
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
}
else if (get_UserLanded(check2) == false)
{
if (get_UserSector(check2) != get_UserSector(check)) return;
if (get_UserZone(check2) != get_UserZone(check)) return;
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
} while (check2 != UserMax);
}
I know that the function might be a lot complex, but please ignore that fact and focus on just the do..while loops. Thank you!
Just declare the for loop to use the existing variable.
int check2 = 0;
if (Message.StartsWith(":g::", true, null))
{
for (; check2 < UserMax; check2++)
{
// Do stuff
}
return;
}
if (check <= 0) return;
for (; check2 < 200; check2++)
{
// Do stuff
}

C# not all code paths return a value data collector class project [duplicate]

This question already has answers here:
Main: not all code paths return a value
(3 answers)
Closed 6 years ago.
I am trying to find out where the issue is in this code and I just can't find it.
beginning of statement....
private Units unitsToUse;
private int[] dataCaptured = new int[30];
private int mostRecentMeasure;
method at end of statement....
public int Measure(int v, Units u)
{
if (v != 0 && v != null)
{
mostRecentMeasure = v;
if (u == Units.Metric)
{
unitsToUse = u;
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && dataCaptured[i] != null && i < 29)
{
continue;
}
if (i == 29 && dataCaptured[i] != null)
{
i = 0;
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
}
else if (u == Units.Imperial)
{
unitsToUse = u;
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && dataCaptured[i] != null && i < 29)
{
continue;
}
if (i == 29 && dataCaptured[i] != null)
{
i = 0;
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
}
else
{
throw new ArgumentOutOfRangeException("Your units were neither of the available values.");
}
}
else
{
throw new ArgumentOutOfRangeException("Your value of measuring was not in the specified range.");
}
}
Now The method is going to receive a valid Enum value for Units and a valid value from the int V through a random 1-10 method elsewhere in the code. What i don't understand is where the code isn't returning a value or throwing an exception to handle any erroneous cases of the method executing outside of the parameters. I've been stuck here for a while and any help would be appreciated.
First off, consider restructuring your logical control statements to prevent less nesting. That makes it easier to detect paths that do not return.
Second, you are checking for null on value types, this is incorrect and the evaluation will never be true, since value types cannot be null.
Third, you should break out of loops when conditions are met and return from outside of the loop instead of trying to return from inside the loop.
public int Measure(int v, Units u)
{
if (v == 0)
throw new ArgumentOutOfRangeException(
"Your value of measuring was not in the specified range.");
mostRecentMeasure = v;
if (u == Units.Metric)
{
unitsToUse = u;
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && i < 29)
{
continue;
}
if (i == 29)
{
i = 0;
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
dataCaptured[i] = mostRecentMeasure;
break;
}
return mostRecentMeasure;
}
else if (u == Units.Imperial)
{
unitsToUse = u;
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && i < 29)
{
continue;
}
if (i == 29)
{
i = 0;
dataCaptured[i] = mostRecentMeasure;
break;
}
dataCaptured[i] = mostRecentMeasure;
break;
}
return mostRecentMeasure;
}
else
{
throw new ArgumentOutOfRangeException(
"Your units were neither of the available values.");
}
}
To Build On #DavidL's answer
Code to have the least nesting possible. That makes it easier.
You don't need to check for null on non nullable types (int v)
you should break out of loops when conditions are met and return from outside of the loop instead of trying to return from inside the loop.
Don't repeat the same code for your if statement, they can be combined
No need to explicitly set i = 0 before returning
There are still some more issues with your code:
// How Can i ever be greater than 29 but also less than 30?
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && i < 29)
{
continue;
}
}
public int Measure(int v, Units u)
{
if (v == 0)
{
throw new ArgumentOutOfRangeException("Your value of measuring was not in the specified range.");
}
if (false == (u == Units.Metric || u == Units.Imperial))
{
throw new ArgumentOutOfRangeException("Proper unit type not provided.");
}
mostRecentMeasure = v;
if (u == Units.Metric || u == Units.Imperial)
{
unitsToUse = u;
for (int i = 0; i < 30; i++)
{
if (dataCaptured[i] != 0 && i < 29)
{
continue;
}
if (i == 29)
{
dataCaptured[i] = mostRecentMeasure;
return mostRecentMeasure;
}
dataCaptured[i] = mostRecentMeasure;
break;
}
return mostRecentMeasure;
}
}

How to remove parentheses only when the whole text is surrounded by them?

I want to remove parentheses only when the whole text is surrounded by them. For example:
(text (text) text)
need's to be convert to:
text (text) text
I have a very simple check:
value = (value [0] == '(' && value [value .Length - 1] == ')') ? value.Substring(1, value .Length - 2) : value;
but it fails and incorrectly removes the parentheses of these kind of strings:
(text (text) ) text (text)
Could anyone tell a way to handle all cases? Using regular expression is OK as well.
Note, that the parentheses are balanced. For example, such case is not possible:
( text ( text )
Use a simple loop for testing, if it's "valid" for removal, remove first & last:
bool isValid = value[0] == '(' && value[value.Length - 1] == ')';
int i = 1;
int c = 0;
for(; isValid && c >= 0 && i < value.Length - 1; i++)
{
if(value[i] == '(')
c++;
else if(value[i] == ')')
c--;
}
if(isValid && i == (value.Length - 1) && c == 0)
value = value.Substring(1, value.Length - 2);
This extension method should work;
public static class StringExtensions
{
public static string RemoveParentheses(this string value)
{
if (value == null || value[0] != '(' || value[value.Length - 1 ] != ')') return value;
var cantrim = false;
var openparenthesesIndex = new Stack<int>();
var count = 0;
foreach (char c in value)
{
if (c == '(')
{
openparenthesesIndex.Push(count);
}
if (c == ')')
{
cantrim = (count == value.Length - 1 && openparenthesesIndex.Count == 1 && openparenthesesIndex.Peek() == 0);
openparenthesesIndex.Pop();
}
count++;
}
if (cantrim)
{
return value.Trim(new[] { '(', ')' });
}
return value;
}
}
Use it like this
Console.WriteLine("(text (text) ) text (text)".RemoveParentheses());
Ran a few test cases and I think this is good
public string CleanString(string CleanMe)
{
if (string.IsNullOrEmpty(CleanMe)) return CleanMe;
string input = CleanMe.Trim();
if (input.Length <= 2) return input;
if (input[0] != '(') return input;
if (input[input.Length-1] != ')') return input;
int netParen = 1; // starting loop at 1 have one paren already
StringBuilder sb = new StringBuilder();
for (int i = 1; i < input.Length-1; i++)
{
char c = input[i];
sb.Append(c);
if (c == '(') netParen++;
else if (c == ')') netParen--;
if (netParen == 0) return input; // this is the key did the () get closed out
}
return sb.ToString();
}
I started this before the answer from Amit but I think it is the same basic logic

Bracket Checker Using Stack and Queue in C#

I am having an issue solving Bracket Checker .
i cant seem to solve the problem if user input this sequence of bracket then my program must print its not a right sequence
Input:
({}[)
Output:
Not a Right Sequence
My code is below
Stack s = new Stack();
Queue q = new Queue();
bool isok = true;
string FinalData = "0";
Console.WriteLine("Enter Brackets");
string data = Console.ReadLine();
for (int i = 0; i < data.Length; i++)
{
if (data.Substring(i, 1) == "{"
|| data.Substring(i, 1) == "["
|| data.Substring(i, 1) == "("
)
{
s.Push(data.Substring(i, 1));
}
else
{
q.Enqueue(data.Substring(i, 1));
}
}
while (s.Count > 0 && q.Count > 0)
{
FinalData = (String)s.Pop();
string value = (String)q.Dequeue();
if (FinalData == value)
{
isok = false;
break;
}
}
if (isok)
Console.WriteLine(data + " is a Right Sequence.");
else
Console.WriteLine(data + " is Not a Right Sequence.");
Console.ReadLine();
}
I'l give you a few hints and the basic idea:
you don't need the Queue, just a Stack<char>.
read the input, for each char:
if the char is an open brace, push it
if the char is a close brace, pop the stack and compare.
discard other chars
boolean isCorrect;
public boolean checkBraces(String braces)
{
Stack<Character>stack = new Stack<Character>();
int openBCount = 0;
int closeBCount = 0;
for(int c = 0; c<=braces.length()-1; c++)
{
//check for open braces push to stack
if(braces.charAt(c)=='{' || braces.charAt(c)=='[' ||braces.charAt(c)=='(')
{
stack.push(braces.charAt(c));
openBCount++;
} ////check for close braces. pop the open braces
//compare it to the closed braces using the the
//method ValidatePerBraces
//therefor checking for CORRECTNEES of how the braces //are closed
else if(braces.charAt(c)=='}' || braces.charAt(c)==']' || braces.charAt(c)==')')
{
closeBCount++;
if(!ValidatePerBraces(stack.pop(), braces.charAt(c)))
{
isCorrect = false; //return false in case where they dont match
return isCorrect;
}
}
//for braces to be complete, open and close braces
//should be even, if they are not even then it is
//for sure wrong at least for the specification.
if(c>=braces.length()-1)
{
if(openBCount != closeBCount)
{
isCorrect = false;
return isCorrect;
}
}
}
isCorrect = true; // true if they all match
return isCorrect;
}
// returns true if validated
public boolean ValidatePerBraces(char a, char b)
{
return a == '(' && b== ')' || a == '[' && b == ']' || a == '{' && b== '}' ;
}
public bool CheckBraces(string data)
{
Stack<char> stack = new Stack<char>();
foreach(char c in data){
switch(c){
case '(':
case '[':
case '{':
stack.Push(c);
break;
case ')':
case ']':
case '}':
if(!CheckMatch(stack.Pop(),c)){
return false;
}
break;
}
}
return true;
}
private bool CheckMatch(char a, char b){
return a=='(' && b==')' ||
a=='[' && b==']' ||
a=='{' && b=='}';
}
Thannks Guys I have Solved The Problem Using stack And Queue Both AT the Same time. Here's the code
Stack s = new Stack();
Queue q = new Queue();
bool isRight = true;
char OpeningBracket = ' ';
char closingBracket = ' ';
Console.WriteLine("Enter Brackets");
string data = Console.ReadLine();
char[] character = data.ToCharArray();
for (int i = 0; i < character.Length; i++)
{
if (character[i] == '(' || character[i] == '{' ||
character[i] == '[')
{
s.Push(character[i]);
}
else
q.Enqueue(character[i]);
}
if (s.Count == 0 || q.Count == 0)
isRight = false;
while (s.Count > 0 && q.Count > 0)
{
OpeningBracket = (char)s.Pop();
closingBracket = (char)q.Dequeue();
if ((OpeningBracket == '(' && closingBracket != ')')
|| (OpeningBracket == '[' && closingBracket != ']')
|| (OpeningBracket == '{' && closingBracket != '}')
)
{
isRight = false;
}
}
if (isRight)
Console.WriteLine(data + " is a Right Sequence.");
else
Console.WriteLine(data + " is Not Right Sequence.");
Console.ReadLine();
}
private static bool IsCorrectBracketSeq(string sequence)
{
var stack = new Stack<char>();
foreach (var sign in sequence)
{
if(sign == '(' || sign == '[' || sign == '{')
stack.Push(sign);
else if (sign == ')' || sign == ']' || sign == '}')
{
if (!stack.Any())
return false;
var topSing = stack.Pop();
var str = $"{topSing}{sign}";
if (str != "[]" && str != "{}" && str != "()")
return false;
}
}
return stack.Count == 0;
}
static bool IsBracesValidator(string input)
{
bool IsValidBraces = true;
char[] chrArray = input.ToCharArray();
List<Char> foundOpenParanthesis = new List<char>();
List<Char> foundClosedParanthesis = new List<char>();
char[] chrOpenParanthesis = { '{', '[', '(', '<' };
char[] chrClosedParanthesis = { '}', ']', ')', '>' };
for (int i = 0; i <= chrArray.Length - 1; i++)
{
if (chrOpenParanthesis.Contains(chrArray[i]))
{
foundOpenParanthesis.Add(chrArray[i]);
}
if (chrClosedParanthesis.Contains(chrArray[i]))
{
foundClosedParanthesis.Add(chrArray[i]);
}
}
if (foundOpenParanthesis.Count == foundClosedParanthesis.Count)
{
for(int i=0;i< foundOpenParanthesis.Count;i++)
{
char chr = foundOpenParanthesis[i];
switch (chr)
{
case '[': chr = ']'; break;
case '<': chr = '>'; break;
case '(': chr = ')'; break;
case '{': chr = '}'; break;
}
if (!chr.Equals(foundClosedParanthesis[foundClosedParanthesis.Count - i-1]))
{
IsValidBraces = false;
break;
}
}
} else
{
IsValidBraces = false;
}
return IsValidBraces;
}

Categories