I was tasked with creating a function that receives two numbers and returns True if both are equal and returns False if not. This is what I wrote:
int x = int.Parse(Console.ReadLine());
int y = int.Parse(Console.ReadLine());
if (x == y)
{
Console.WriteLine("True");
}
if (x != y)
{
Console.WriteLine("False");
}
I was hinted that it is possible to do this with only one line of code. Couldn't figure how to and would like to see how it's possible.
Sice Console.WriteLine(true); outputs True you can use
Console.WriteLine(int.Parse(Console.ReadLine()) == int.Parse(Console.ReadLine()));
using some newer c#7 Out variables:
Console.WriteLine(
int.TryParse(Console.ReadLine(), out int first) &&
int.TryParse(Console.ReadLine(), out int second) &&
first == second ? "True" : "False");
Console.WriteLine(int.Parse(Console.ReadLine()) ==
int.Parse(Console.ReadLine()) ? "True" : "False");
This will work for any custom words you need to print, just replace the corresponding strings.
Console.WriteLine(int.Parse(Console.ReadLine()) ==
int.Parse(Console.ReadLine());
Will also work if you always want to print "True" or "False" since the ToString() of boolean is conveniently capitalized.
Suppose your using a console to try this theory. The parsing and console reading aside.
private bool NumbersEqual(int number1, int number2)
{
return number1.Equals(number2);
}
:Edit
Without the method
var number1 = 1;
var number2 = 2;
var equal = number1.Equals(number2);
Or truly truly without variable declarations and 1 line
var equal = 1.Equals(2);
Related
I'm working on an implementation of the A-star algorithm in C# in Unity.
I need to evaluate a collection of Node :
class Node
{
public Cell cell;
public Node previous;
public int f;
public int h;
public Node(Cell cell, Node previous = null, int f = 0, int h = 0)
{
this.cell = cell;
this.previous = previous;
this.f = f;
this.h = h;
}
}
I have a SortedSet which allows me to store several Node, sorted by h property. Though, I need to be able to store two nodes with the same h property. So I've implemented a specific IComparer, in a way that allow me sorting by h property, and triggerring equality only when two nodes are representing the exact same cell.
class ByHCost : IComparer<Node>
{
public int Compare(Node n1, Node n2)
{
int result = n1.h.CompareTo(n2.h);
result = (result == 0) ? 1 : result;
result = (n1.cell == n2.cell) ? 0 : result;
return result;
}
}
My problem : I have a hard time to remove things from my SortedSet (I named it openSet).Here is an example:
At some point in the algorithm, I need to remove a node from the list based on some criteria (NB: I use isCell127 variable to focus my debug on an unique cell)
int removedNodesNb = openSet.RemoveWhere((Node n) => {
bool isSame = n.cell == candidateNode.cell;
bool hasWorseCost = n.f > candidateNode.f;
if(isCell127)
{
Debug.Log(isSame && hasWorseCost); // the predicate match exactly one time and debug.log return true
}
return isSame && hasWorseCost;
});
if(isCell127)
{
Debug.Log($"removed {removedNodesNb}"); // 0 nodes where removed
}
Here, the removeWhere method seems to find a match, but doesn't remove the node.
I tried another way :
Node worseNode = openSet.SingleOrDefault(n => {
bool isSame = n.cell == candidateNode.cell;
bool hasWorseCost = n.f > candidateNode.f;
return isSame && hasWorseCost;
});
if(isCell127)
{
Debug.Log($"does worseNode exists ? {worseNode != null}"); // Debug returns true, it does exist.
}
if(worseNode != null)
{
if(isCell127)
{
Debug.Log($"openSet length {openSet.Count}"); // 10
}
openSet.Remove(worseNode);
if(isCell127)
{
Debug.Log($"openSet length {openSet.Count}"); // 10 - It should have been 9.
}
}
I think the problem is related to my pretty unusual IComparer, but I can't figure whats exatcly the problem.
Also, I would like to know if there is a significative performance improvment about using an auto SortedSet instead of a manually sorted List, especially in the A-star algorithm use case.
If i write your test you do:
n1.h < n2.h
n1.cell = n2.cell -> final result = 0
n1.h > n2.h
n1.cell = n2.cell -> final result = 0
n1.h = n2.h
n1.cell != n2.cell -> final result = 1
n1.h < n2.h
n1.cell != n2.cell -> final result = -1
n1.h > n2.h
n1.cell != n2.cell -> final result = 1
when you have equality on h value (test number 3) you choose to have always the same result -> 1. so its no good you have to have another test on cell to clarify the position bacause there is a confusion with other test which gives the same result (test number 5)
So i could test with sample, but i am pretty sure you break the Sort.
So if you clarify the test, i suggest you to use Linq with a list...its best performance.
I'll answer my own topic because I've a pretty complete one.
Comparison
The comparison of the IComparer interface needs to follow some rules. Like #frenchy said, my own comparison was broken. Here are math fundamentals of a comparison I totally forgot (I found them here):
1) A.CompareTo(A) must return zero.
2) If A.CompareTo(B) returns zero, then B.CompareTo(A) must return zero.
3) If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero, then A.CompareTo(C) must return zero.
4) If A.CompareTo(B) returns a value other than zero, then B.CompareTo(A) must return a value of the opposite sign.
5) If A.CompareTo(B) returns a value x not equal to zero, and B.CompareTo(C) returns a value y of the same sign as x, then A.CompareTo(C) must return a value of the same sign as x and y.
6) By definition, any object compares greater than (or follows) null, and two null references compare equal to each other.
In my case, rule 4) - symetry - was broken.
I needed to store multiple node with the same h property, but also to sort by that h property. So, I needed to avoid equality when h property are the same.
What I decided to do, instead of a default value when h comparison lead to 0 (which broke 4th rule), is refine the comparison in a way that never lead to 0 with a unique value foreach node instance. Well, this implementation is probably not the best, maybe there is something better to do for a unique value, but here is what I did.
private class Node
{
private static int globalIncrement = 0;
public Cell cell;
public Node previous;
public int f;
public int h;
public int uid;
public Node(Cell cell, Node previous = null, int f = 0, int h = 0)
{
Node.globalIncrement++;
this.cell = cell;
this.previous = previous;
this.f = f;
this.h = h;
this.uid = Node.globalIncrement;
}
}
private class ByHCost : IComparer<Node>
{
public int Compare(Node n1, Node n2)
{
if(n1.cell == n2.cell)
{
return 0;
}
int result = n1.h.CompareTo(n2.h);
result = (result == 0) ? n1.uid.CompareTo(n2.uid) : result; // Here is the additional comparison which never lead to 0. Depending on use case and number of object, it would be better to use another system of unique values.
return result;
}
}
RemoveWhere method
RemoveWhere use a predicate to look into the collection so I didn't think it cares about comparison. But RemoveWhere use internally Remove method, which do care about the comparison. So, even if the RemoveWhere have found one element, if your comparison is inconstent, it will silently pass its way. That's a pretty weird implementation, no ?
I'm new to C# but not to programming in general.
I am trying to set add some error checking to my program. There are 3 textboxes and I am trying to make it so that if the text box is left blank, it assumes a value of 0. Here is my code so far:
private void btnCalculate_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(txtNumberOfClassATix.Text)) // Assumes 0 if no number entered for txtNumberOfClassATix.Text.
{
txtNumberOfClassATix.Text = "0";
}
if (String.IsNullOrEmpty(txtNumberOfClassBTix.Text)) // Assumes 0 if no number entered for txtNumberOfClassBTix.Text.
{
txtNumberOfClassBTix.Text = "0";
}
if (String.IsNullOrEmpty(txtNumberOfClassCTix.Text)) // Assumes 0 if no number entered for txtNumberOfClassCTix.Text.
{
txtNumberOfClassCTix.Text = "0";
}
int classANum = int.Parse(txtNumberOfClassATix.Text);
int classBNum = int.Parse(txtNumberOfClassBTix.Text);
int classCNum = int.Parse(txtNumberOfClassCTix.Text);
double classATotal = classANum * classAPrice;
double classBTotal = classBNum * classBPrice;
double classCTotal = classCNum * classCPrice;
lblCalculatedClassARevenue.Text = $"{classATotal:c}";
lblCalculatedClassBRevenue.Text = $"{classBTotal:c}";
lblCalculatedClassCRevenue.Text = $"{classCTotal:c}";
lblCalculatedTotalRevenue.Text = $"{(classATotal + classBTotal) + classCTotal:c}";
}
This code works but I'm sure I could replace those if statements with something simpler. I've seen how to set a variable to null if another is null using the null-conditional operator but I don't really grasp it enough to adapt it to my scenario.
So far maccettura's answer is the best, but can we do better? Sure we can. Let's make a general-purpose extension method:
internal static class Extensions
{
public static int? AsInt(this string s)
{
int result;
if (s == null)
return null;
else if (int.TryParse(s, out result))
return result;
else
return null;
}
}
And now:
int classANum = txtNumberOfClassATix.Text.AsInt() ?? 0;
If it's an int, you get the int. If it's not, you get zero. Easy peasy.
Or, you might want this extension method:
internal static class Extensions
{
public static int AsInt(this string s, int default = 0)
{
int result;
if (s == null)
return default;
else if (int.TryParse(s, out result))
return result;
else
return default;
}
}
And now you can say what you want the default to be without using ??.
This style of programming is called "fluent programming"; it can make code that is very easy to read and understand.
Notice that this solution does not update the UI with zeros; if you wanted to do that then I would recommend splitting that into two steps: one which causes the mutation, and then a separate step which computes the value. Operations which are useful for both their effects and their values can be confusing.
This is a perfect time to use a method so you arent repeating yourself:
private static int GetInputAsInt(TextBox textbox)
{
int outputValue = 0;
if(textbox?.Text != null && int.TryParse(textbox.Text, out outputValue))
{
return outputValue;
}
return 0;
}
Now you are checking if the textbox itself is not null, and that the value contained therein is a int, if anything fails it returns a 0;
Call it in your other method like this:
int classANum = GetInputAsInt(txtNumberOfClassATix);
Which means your button click event would be a bit simpler:
private void btnCalculate_Click(object sender, EventArgs e)
{
int classANum = GetInputAsInt(txtNumberOfClassATix);
int classBNum = GetInputAsInt(txtNumberOfClassBTix);
int classCNum = GetInputAsInt(txtNumberOfClassCTix);
double classATotal = classANum * classAPrice;
double classBTotal = classBNum * classBPrice;
double classCTotal = classCNum * classCPrice;
lblCalculatedClassARevenue.Text = $"{classATotal:c}";
lblCalculatedClassBRevenue.Text = $"{classBTotal:c}";
lblCalculatedClassCRevenue.Text = $"{classCTotal:c}";
lblCalculatedTotalRevenue.Text = $"{(classATotal + classBTotal) + classCTotal:c}";
}
To keep it simple, a good approach is to use the conditional operator. The full example is below (broken across two lines for readability):
txtNumberOfClassATix.Text =
String.IsNullOrEmpty(txtNumberOfClassATix.Text) ? "0" : txtNumberOfClassATix.Text;
This is a nice, readable, assignment for the first part:
myString = ...
The conditional operator breaks down by providing a boolean expression (true/ false) on the left side of the ?. So, for example:
myString = anotherString == "" ? ... // checking if another string is empty
The final part is the :. To the left is the assignment if the expression is true, and to the right goes the assignment if the expression is false. To finish the example:
myString = anotherString == "" ? "anotherString is empty" : "anotherString is not empty";
The above example can be written out in full to clear up any misunderstanding as:
if (anotherString == "")
{
myString = "anotherString is empty";
}
else
{
myString = "anotherString is not empty";
}
This can apply to all the statements. The documentation is found here.
The best way to reduce the line of code is use the function for your common operation(s). In your case, you can create function which checks whether or not the object is NULL or empty. Based on the return value of that function you can proceed ahead. On the other hand, you can handle it on front-end by using different validators such as RequiredFieldValidator, CustomValidator, etc.
I just learned Method Declaring and i don't know too much how to use it, i tried to make an algorithm that takes 2 numbers and return their smallest common divide, and if there is no common divider, return -1, thats the code:
class Program
{
static int Div(int a, int b)
{
int max = Math.Max(a, b);
bool div = false;
for(int i = 2; i <= max / 2; i++)
{
if (a % i == 0 && b % i == 0)
{
return i;
div = true;
i = max;
}
}
if (div == false)
{
return -1;
}
}
static void Main(string[] args)
{
Console.WriteLine("Please Enter 2 Numbers");
int num = int.Parse(Console.ReadLine());
int num2 = int.Parse(Console.ReadLine());
Console.WriteLine(Div(num, num2));
}
}
it tells me that there is an unreachable code, and not all code paths return a value, but why? if i get 2 numbers that does have a commong divider it will return it, and if not it will return -1, no execptions I think, thanks in advance
The compiler is not clever enough. But the last if is redundant anyway because it's always false there, so you can write following which also avoids the compiler error:
static int Div(int a, int b)
{
int max = Math.Max(a, b);
for (int i = 2; i <= max / 2; i++)
{
if (a % i == 0 && b % i == 0)
{
return i;
}
}
return -1;
}
The part after the return in the loop was unreachable and unnecessary, so i've removed it.
When you use return you exit the function immediately, no code beyond that line will execute therefore the lines after aren't reachable.
return i;
div = true; <<
i = max; <<
In your case, seems like you just want to set those values before you return.
if (a % i == 0 && b % i == 0)
{
return i;
div = true;
i = max;
}
The 2 lines after the return are never reached. Put them before the return. Also I don't think you need a div bool at all. It's redundant and can be optimized away.
Proving whether an arbitrary method can reach the end of the method without hitting a return or throwing an exception is provably an unsolvable problem. You can always construct a method such that the compiler would be unable to prove whether or not the endpoint is reachable, if you try hard enough. However, it's important for the compiler to not allow any programs that have a return value but no reachable endpoint.
As a consequence of this, there are false positives. The compiler does it's best to determine if a program has a reachable endpoint, and if it fails to prove it, it will error, even if you and I both know that the endpoint isn't actually reachable.
You'll need to change your code such that the compiler is able to prove that the endpoint isn't reachable, and the easiest way to do that is to remove the if (div == false) line and just always return -1;. You and I know that div will never be true there, but the compiler isn't sophisticated enough to prove it.
The return in the first if clause in the for loop is before the rest of the code, so there are 2 lines of code that will never get hit, these 2:
div = true;
i = max;
The reason they'll never get hit is because if the if statement is true, it'll immediately return, and if it's false it'll go to the second if.
2 reasons : The line div=true is unreachable, the code after return is not executed. Replace
return i;
div = true;
i = max;
by
int res=i;
div = true;
i = max;
return res;
And the last 'if' clause has no 'else' clause allowing to return in all cases;
I would like to know what to put in the if statement brackets to tell the program, if x or y equals a double, it can break out and continue carrying out the rest of my code.
Any suggestions?
while (true)
{
Console.Write("I need to pour this much from this one: ");
string thisOne = Console.ReadLine();
Double.TryParse(thisOne, out x);
if ( /* Here I want to put "x is a number/double*/ )
{
break;
}
}
while (true)
{
Console.Write("I need to pour this much from that one: ");
string thatOne = Console.ReadLine();
Double.TryParse(thatOne, out y);
if (/* Here I want to put "y is a number/double*/)
{
break;
}
}
TryParse returns a boolean to say whether the parse was successful
if (Double.TryParse(thatOne, out y))
{
break;
}
From documentation
A return value indicates whether the conversion succeeded or failed.
Double.TryParse returns a boolean, perfect fit for your if statement
if (Double.TryParse(thatOne, out y)) {
break;
}
You have a misconception about TryParse(). You want to check if x is a double. somewhere above in your code, you did not post it here there is probably a line like double x = 0;.
You defined x and y already as double. You want to check if your input which is string can be parsed to double:
The shorthand version is this:
if (Double.TryParse(thatOne, out x))
{
break;
}
This can also be written as:
bool isThisOneDouble = Double.TryParse(thisOne, out x);
if (isThisOneDouble)
{
break;
}
If you really want to check if a variable is of certain type without trying to parse it, try it like this:
double x = 3;
bool isXdouble = x.GetType() == typeof(double);
or
double x = 3;
if(x.GetType() == typeof(double))
{
// do something
}
According to the documentation, TryParse returns true if parsing succeeded so just put your tryparse into your if statement.
Control your loop with a bool, set the bool false when your condition is met...
bool running = true;
while (running)
{
Console.Write("I need to pour this much from this one: ");
string thisOne = Console.ReadLine();
if (Double.TryParse(thisOne, out y))
{
running = false
}
}
I am currently converting vb and vb.net to c# but have an issue. I would strongly like not to use the visualbasic dlls in the converted code and have been doing this fine so far.
But this code
Dim x as Double 'this was error saying it was integer
x = Val("1 23 45 x 6") ''#x is 12345
x = Val("1..23") ''#x is 1.23
x = Val("1 1,,,,,2,2..3") ''#x is 1122.3
Does not work the same as vb6 even with using "Val" from the visualbasic.conversion.dll Is there anyone that has solved this to work the same? A c# solution would be best.
None of the above seemed to satisfy my needs, so I wrote the following:
public static Double Val(string value)
{
String result = String.Empty;
foreach (char c in value)
{
if (Char.IsNumber(c) || (c.Equals('.') && result.Count(x => x.Equals('.')) == 0))
result += c;
else if (!c.Equals(' '))
return String.IsNullOrEmpty(result) ? 0 : Convert.ToDouble(result);
}
return String.IsNullOrEmpty(result) ? 0 : Convert.ToDouble(result);
}
Results of the test data:
"0 1 5.2123 123.123. 1 a" returns 15.21233123
" 1 5.2123 123a" returns 15.21233123
"a1 5.2123 123.123. 1 a" returns 0
"" returns 0
I know nothing of this VisualBasic.Conversion.dll (and neither does google), but the Microsoft.VisualBasic namespace (in Microsoft.VisualBasic.dll) is part of the core framework and perfectly fine and acceptable to use from C#. There are other nice gems in there as well (ie TextFieldParser), but this should have the exact Val() implementation you need.
If this is the library you've already tried and it doesn't seem right, then I'd go take another look at the unit tests on it.
Outside of this, the accepted ways in C# for converting strings to integers are int.Parse(), int.TryParse(), and Convert.ToInt32(). But, like it or not, the Val() function from the Microsoft.VisualBasic.dll library is the closest match you're going to find for your code's existing behavior.
Check out this site: http://www.dreamincode.net/forums/topic/36064-val-replacement/ where others give an example how to implement your own Val() function.
You could use the Convert static class. It's pretty close to Val() but you need to specify the convert to type. It's in the System namespace.
E.g.:
int x = Convert.ToInt32("23");
int y = Convert.ToDouble("23.342");
http://msdn.microsoft.com/en-us/library/system.convert(v=vs.71).aspx
There is no exact equivalent of vb6 val function in C#. But this function can be used by using Microsoft.VisualBasic namespace in C#.
To use val() function in C# add Microsoft.VisualBasic namespace and use following code:
Conversion.Val("09sdf");
From your examples it could look similar to this. But since I don't know the VB val specification it might not work on all strings correctly.
Decimal ParseNumerString(string s)
{
Decimal value=0;
Decimal multiplier=1;
bool decimalPart=false;
foreach(char c in s)
{
if(IsDigit(c))
{
int i=ParseDigit(c);
if(!decimalPart)
{
value=value*10+i;
}
else
{
muliplier/=10;
value=value+multiplier*i;
}
if(c=='.')
decimapPart=true;
}
return value;
}
This is pseudocode you need to implement parse digit and is digit yourself(trivial). I chose Decimal as internal representation because that way I don't get strange rounding errors in the fractional part.
Had the same issue, started with #ericosg 's answer, then realized I needed Negative Numbers and Scientific Notation
namespace VB6
{
public class Helper
{
public static double Val(object value)
{
double returnVal = 0;
string sToParse = value.ToString();
string result = string.Empty;
string num = string.Empty; //In the case of scientific notation e.g. 3e5 = 300000
foreach (char c in sToParse)
{
if (result.Length == 0 && c.Equals('-'))//negative numbers
result += c;
else if (Char.IsNumber(c) || (c.Equals('.') && result.Count(x => x.Equals('.')) == 0))
result += c;
else if ((c.Equals('e') || c.Equals('E')) && num.Length == 0 && result.Length != 0) //scientific notation
{
num = result;
result = string.Empty;
}
else if (!c.Equals(' '))
{
break;
}
}
if (num.Length > 0)
{
//scientific notation
double fSignificantFigures = string.IsNullOrEmpty(result) || result == "-" ? 1 : Math.Pow(10, Convert.ToDouble(result));
returnVal = num == "-" ? 0 : Convert.ToDouble(num) * fSignificantFigures;
}
else
{
returnVal = string.IsNullOrEmpty(result) || result == "-" ? 0 : Convert.ToDouble(result);
}
return returnVal;
}
}
}