activate functions only when a bool is true? - c#

I want that when it becomes a bool it becomes false the conditions indicate inside "if" they cancel.
I have this situation where floats remain altered by the bool even when it is false.
float x = 2;
if (Input.GetKeyDown(KeyCode.LeftShift) b = true;
if (b == true) { x = 3);
if (Input.GetKeyUp(KeyCode.LeftShift) b = false;
Isn't there a way to assert X to its original value, without adding X = 2 to b = false ..?

float x = 2f;
float xfall = 2f;
if(Input.GetKeyDown(KeyCode.LeftShift))
{
b = true;
}
else if(Input.GetKeyUp(KeyCode.LeftShift))
{
b = false;
x = xfall;
}
if(b)
{
x = 3f;
}
A lot of your code cannot be even used, next time try to make it clearer for people to read.
Another thing to note is that you do not have to if(b == true) if(b) will return the same thing because it is the same line of code.

You could use a ternary operator to simplify it somewhat if that's what you mean
x = b ? 3 : 2;

Related

Is there a faster way to compare these decimals?

I have a stream of decimals and I am trying to compare the most recent decimal to the difference of the last 6 decimals, I may increase this number
I have the following class
public class CompareRandom
{
private const decimal DIFFERENCE = 1.8m;
public decimal a;
public decimal b;
public decimal c;
public decimal d;
public decimal e;
public decimal f;
public decimal g;
public bool Compare(decimal num)
{
this.g = this.f;
this.f = this.e;
this.e = this.d;
this.d = this.c;
this.c = this.b;
this.b = this.a;
this.a = num;
if (b != decimal.Zero && b / DIFFERENCE > a)
{
return true;
}
if (c != decimal.Zero && c / DIFFERENCE > a)
{
return true;
}
if (d != decimal.Zero && d / DIFFERENCE > a)
{
return true;
}
if (e != decimal.Zero && e / DIFFERENCE > a)
{
return true;
}
if (f != decimal.Zero && f / DIFFERENCE > a)
{
return true;
}
if (g != decimal.Zero && g / DIFFERENCE > a)
{
return true;
}
return false;
}
}
Then I initialize it as volatile
volatile static CompareRandom CompareRandom = new CompareRandom();
Then I call CompareRandom.Compare(value) synchronously as part of a loop that updates every 1ms to compare the values.
The part I am the most interested in knowing if there is a faster way to do is this part
this.g = this.f;
this.f = this.e;
this.e = this.d;
this.d = this.c;
this.c = this.b;
this.b = this.a;
this.a = num;
A successful answer will demonstrate a faster execution of the method Compare
See if you can make it faster:
https://dotnetfiddle.net/tLw8qM
https://dotnetfiddle.net/jd0bSF
You don't need to perform the division every time. Instead, multiply a by DIFFERENCE to obtain a threshold:
// Name changed to be more conventional
private const decimal Difference = 1.8m;
public bool Compare(decimal num)
{
g = f;
f = e;
e = d;
d = c;
c = b;
b = a;
a = num;
var threshold = num * Difference;
return (b != decimal.Zero && b > threshold) ||
(c != decimal.Zero && c > threshold) ||
(d != decimal.Zero && d > threshold) ||
(e != decimal.Zero && e > threshold) ||
(f != decimal.Zero && f > threshold) ||
(g != decimal.Zero && g > threshold);
};
As asides:
It's odd for a Compare method to return bool rather than an integer; given that it's not the "common" meaning of Compare, it's probably worth renaming it for clarity
It's very odd for a comparison method to change the state of an object, as this is doing (assigning to a) - another good reason to change the name.
Using a collection instead of separate variables would make all of this more maintainable, but I'd be surprised if it improved the speed.
I also really like the idea of eliminating the division, but I don't like the way you're handling booleans: the original question says something like:
if condition1 then return true;
if condition2 then return true;
if condition3 then return true;
If condition1 is true, then the code does not bother about the calculation of the other conditions (why would it, when one condition is true, then the OR of all conditions also is true).
The proposal from Jon looks as follows:
return (condition1 || condition2 || condition3)
This does exactly the same thing, but the fact if the calculation of the OR equation is determined by the compiler: if you're dealing with an older compiler, not performing optimsation, then the entire calculation is done, even if condition1 is true.

Compacting multiple similar if statements in C#

I would like to make some code for a game a little more compact. Here is the original.
if (killPosX != 0) // float x position you would like the object to be destroyed at
{
killX = true; // automatically makes the value of killX true
}
if (killPosY != 0) // float y position you would like the object to be destroyed at
{
killY = true; // automatically makes the value of killY true
}
if (killPosT != 0) // float position in time you would like the object to be destroyed at
{
killT = true; // automatically makes the value of killT true
}
And I want to turn it into something like this:
if ([killPosX, killPosY, killPosT] != 0)
{
[killPosX, killPosY, killPosT] = true;
}
How would I do that?
if (killPosX != 0)
{
killX = true;
}
Could be translated as follow
killX = (killPosX != 0) ? true : killX;
Or more simply
killX |= killPosX != 0;
if (killPosX != 0)
{
killX = true;
}
else
{
killX = false;
}
Could be translated as follow
killX = (killPosX != 0) ? true : false;
Or more simply
killX = killPosX != 0;
But since comparing floats using == or != is not advised, I would go for:
killX |= !Mathf.Approximately( killPosX, 0 );
killY |= !Mathf.Approximately( killPosY, 0 );
killT |= !Mathf.Approximately( killPosT, 0 );
AFAIK, there is no built-in syntax similar to what you wrote in order to achieve what you want.
I'm not sure if this applies to what you're working on (and there may be a better way in Unity), but it seems to me that one way to do it would be to make the KillN properties calculated on the value of their corresponding KillPosN property:
public class SomeClass
{
public float KillPosX { get; set; }
public float KillPosY { get; set; }
public float KillPosT { get; set; }
// Values are based on the related property values and cannot be set directly
public bool KillX => !IsRoughlyZero(KillPosX);
public bool KillY => !IsRoughlyZero(KillPosY);
public bool KillT => !IsRoughlyZero(KillPosT);
private static bool IsRoughlyZero(float input)
{
// Use a tolerance for comparing floating point numbers to 0
return Math.Abs(input) < .0000001;
}
}
I can't think of a way to do it as you suggest but it might be a little neater and more compact to use a variation of the approach hellium suggested:
public void fnc(ref bool t1, float t2) { t1 |= !Mathf.Approximately( t2, 0 ); }
fnc(ref KillX, KillPosX);
fnc(ref KillY, KillPosY);
fnc(ref KillT, KillPosT);
You could of course wrap it in a method which uses arrays as parameters but unless you need a generic way to do this for variable sized arrays, the setup cost is bulkier than just using discrete calls.

Use of unassigned local variable error for currency converter? I'm Sorry

I am very new to coding and I am trying to make a currency converter for my class using C#.
My problem is that my decGrossConvrt is red under my "// Calculations", and the error is "Use of unassigned local variable 'decGrossConvrt'" I'm not sure what to do to fix this, any help would be appreciated.
// If Valid
if (blnValid)
{
if (radUSDFrom.Checked && radEURTo.Checked)
{
decConvrtRate = decUSDToEUR;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
else if (radUSDFrom.Checked && radMXNTo.Checked)
{
decConvrtRate = decUSDToMXN;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
else if (radEURFrom.Checked && radUSDTo.Checked)
{
decConvrtRate = decEURToUSD;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
else if (radEURFrom.Checked && radMXNTo.Checked)
{
decConvrtRate = decEURToMXN;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
else if (radMXNFrom.Checked && radUSDTo.Checked)
{
decConvrtRate = decMXNToUSD;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
else
{
decConvrtRate = decMXNToEUR;
decGrossConvrt = decMoneyInput * decConvrtRate;
}
}
// Calculations
decServiceFee = decServiceRate *decGrossConvrt;
decNetConvrt = decGrossConvrt - decServiceFee;
// Display Output
lblGross.Text = decGrossConvrt.ToString("c2");
lblNet.Text = decNetConvrt.ToString("c2");
lblService.Text = decServiceFee.ToString("c2");
// Display Message Box
MessageBox.Show("" + strErr);
Problem
You are declaring decGrossConvrt outside the if... block and are assigning it a value inside the if... block. As a result, there is a chance that your code will never initialize decGrossCovert (i.e. will never assign a value to it.) That's a problem because:
The C# compiler does not allow the use of uninitialized variables.
Here is some code with the same problem. When the condition is false, the code never assigns a value to someNumber.
int someNumber;
bool condition = false;
if (condition)
{
someNumber = 5;
}
var result = 10 * someNumber;
// Use of unassigned local variable 'someNumber'
Solution
To resolve it, make sure that all code paths assign a value to someNumber.
We can accomplish that like this:
int someNumber;
bool condition = false;
if (condition)
{
someNumber = 5;
}
else
{
someNumber = 0; // Assign the default value here
}
var result = 10 * someNumber; // Works
Or we can do it like this:
int someNumber = 0; // Assign the default value here
bool condition = false;
if (condition)
{
someNumber = 5;
}
var result = 10 * someNumber; // Works

Call method with new parameter values for each loop in C#

[HttpPost]
public ActionResult ShowDetailRate(FormCollection form)
{
List<Calculation> finalList = new List<Calculation>();
Calculation calc3 = new Calculation();
double InterestRate = 0;
double guess = 0.01;
double guess2 = 0.03;
for (int i = 0; i < 50; i++)
{
InterestRate = secantInterestRate(guess, guess2, form);
if (radio == "inArrears")
{
radioCalc = 0;
}
else
{
radioCalc = InvoiceAmount;
}
calc3.PeriodStartDate = PeriodStartDate;
calc3.PeriodEndDate = PeriodEndDate;
if (DTC == "365/365")
{
calc3.NumberOfDays = Convert.ToInt32((calc3.PeriodEndDate - calc3.PeriodStartDate).Days) + 1;
}
else if (DTC == "360/360")
{
calc3.NumberOfDays = 30;
}
calc3.InvoiceAmount = InvoiceAmount;
calc3.InterestRate = InterestRate;
calc3.InterestAmount = (PV - radioCalc) * InterestRate / DTCyear * calc3.NumberOfDays;
calc3.Amortization = (calc3.InvoiceAmount - calc3.InterestAmount);
calc3.PresentValue = PV - calc3.Amortization;
calc3.StartValue = PV;
finalList.Add(calc3);
var count = finalList.Count();
if (finalList[count].PresentValue != FV)
{
guess = guess2;
guess2 = calc3.InterestRate;
continue;
}
else
break;
}
return PartialView("ShowDetail", finalList);
}
In my method above I'm using my variable InterestRate to call a method called secantInterestRate with 3 parameters (double, double, FormCollection). The first round for the loop I want the first 2 parameters to be set as they are (0.01, 0.03), but in the second loop-round I want guess = guess 2, and guess2 = calc3.InterestRate. And still be calling the method secantInterestRate in the beginning of the loop but with the new values. I have tried with a small if in the end:
var count = finalList.Count() - 3;
if (finalList[count].PresentValue != FV)
{
guess = guess2;
guess2 = calc3.InterestRate;
continue;
}
else
break;
But this don't work because when the loop starts over guess will be 0.01 and guess2 will be 0.03 again, and not like I want it.
Is it possible to make guess = guess2 and guess2 = calc3.InterestRate for every new round in the loop?
something like this?
if (i==0) {
guess = guess2;
guess2 = calc3.InterestRate;
} else {
// you don't want to change the values after the first time through; do nothing
}
PS: I suggest you factor out the calculation code from the form-processing code, or in some other way make the method more readable. Currently it's really hard to see the logic as there's so many lines of code, and that's probably the main reason it's hard to solve any small problems like this one.
Change your code according to the following:
....
for (int i = 0; i < 50; i++)
{
if (i > 0)
{
guess = guess2;
guess2 = calc3.InterestRate;
}
InterestRate = secantInterestRate(guess, guess2, form);
...

Checking valid combination of items in list

I have a list of items that I need to validate. The list can contain any number of items of the type A, B and C, but before the list can be saved, it must confirm to the following rules:
If you have A, you need either B or C
If you have B, you need A
I have ended up with the following code (saudo code):
bool IsListValid()
{
var a = list.ContainsAny(A);
var b = list.ContainsAny(B);
var c = list.ContainsAny(C);
if (!a && !b)
return true;
if (a && (b || c)
return true;
return false;
}
I don't like this code.
1. The use of Any three times in a row will potentially iterate the list three times
2. The if's doesn't look good to me.
Of cause it would be better with different variable names and by extracting the test into methods with good names, but I think there are better ways of solving this entirely. I'm just not sure how...
Any tips?
I would use a simple loop, it's both, comprehensible and efficient.
bool containsA = false, containsB = false, containsC = false;
for (int i = 0; i < list.Count; i++)
{
Type itemType = list[i].GetType();
if (!containsA) containsA = itemType == typeof(A);
if (!containsB) containsB = itemType == typeof(B);
if (!containsC) containsC = itemType == typeof(C);
if (containsA && (containsB || containsC)) return true;
}
return (!containsA && !containsB);
If it's so important that you only go through the list once, you could do this:
bool a = false;
bool b = false;
bool c = false;
foreach(var x in list)
{
if (x is A) a = true;
if (x is B) b = true;
if (x is C) c = true;
}
But I'd leave it as it is. If profiling later shows that this code is becoming a bottleneck, you can revisit it then.
As for the if's, that looks fine to me. As long as A, B and C are properly named (something like hasNotifyEmail or needsResponse, something that explains why you want them to work with the specified rules) then it should be easy for others to understand.
var hasA = list.Any(x => x.GetType() == typeof(A));
var hasB = list.Any(x => x.GetType() == typeof(B));
var hasC = list.Any(x => x.GetType() == typeof(C));
//If you have A, you need either B or C
// A AND (B xor C)
if (hasA && (hasB ^= hasC))
return true;
//If you have B, you need A
if (hasB && hasA)
return true;
return false;

Categories

Resources