C# - higher or lower statement in a switch function - c#

Only if(artikelen > 50) works. I think I know why, but I don't know how to resolve the problem.
switch function, but I don't know how to use "< or >" in that function.
C#:
private void button1_Click(object sender, EventArgs e) {
double bruto = double.Parse(textBox1.Text);
double artikelen = double.Parse(textBox2.Text);
double loon;
if (artikelen < 10) {
double twee = bruto + (bruto / 100 * 2);
loon = twee;
textBox3.Text = loon.ToString();
}
if (artikelen >= 10 && bruto < 50) {
double vijf = bruto + (bruto / 100 * 5);
loon = vijf;
textBox3.Text = loon.ToString();
}
if (artikelen > 50) {
double tien = bruto + (bruto / 100 * 10);
loon = tien;
textBox3.Text = loon.ToString();
}
}
private void textBox1_TextChanged(object sender, EventArgs e) {
}

You can use less than or greater than in a switch statement with C# 7:
switch (value)
{
case var _ when value < 10:
// something
break;
case var _ when (value >= 10 && value < 50):
// something
break;
case var _ when value > 50:
// something
break;
default:
// something
break;
}
For multiple inputs, look at tuple patterns in C# 8.

Looks like a lot of duplicate code.
I'd split that into:
decimal GetFactor( decimal artikelen )
{ // order is important!
if( artikelen >= 50 ) return 10m;
if( artikelen >= 10 ) return 5m;
return 2m;
}
To get the factor. Then do the math:
decimal GetLoon( decimal bruto, decimal factor ) // With factor from above result
{
return bruto + (bruto / 100m * factor);
}
Resulting in
textBox3.Text = GetLoon( bruto, GetFactor( artikelen) ).ToString();
Some additional points:
I assume these are monetary amounts. => Use decimal, not floating point!
Always validate user input. What if a value cannot be parsed? What if artikelen < 0 ?

Related

Calculate EMA for MACD with 2 lines indicator in C#

I'm trying to write an indicator script that will plot the MACD with 2 lines in a practice trading tool.
At the moment, I'm following the formula which is using the EMA formula to calculate it.
I'm able to plot the chart. But somehow my indicator result does not have the exact same result as the one on meta trader 4 or on trading view. The indicator result on these apps is exactly the same.
I think I have missed something when I try to convert from the formula to actual code. Please help me fix it. Thank you.
Here is the part that will calculate the EMA.
/// ==================================================================
/// ======================== calculations ============================
/// ==================================================================
public void Calculate()
{
for (int i = 0; i < Bars.Length; i++){
if (i >= SlowEMA) {
MACD[i] = CalculateEMA(FastEMA, i) - CalculateEMA(SlowEMA, i);
Signal[i] = CalculateEMA_MACD(MACD, SignalEMA, i);
Histogram[i] = MACD[i] - Signal[i];
}
}
}
private double CalculateEMA(int Period, int index)
{
var currentValue = 0d;
var currentEMA = 0d;
var yesterdayEMA = 0d;
var smooth = 2d;
var multiplier = smooth / (1 + Period);
for (int i = 0; i < Period; i++){
currentValue = GetPrice(index + i - Period);
currentEMA = (currentValue * multiplier) + (yesterdayEMA * (1 - multiplier));
yesterdayEMA = currentEMA;
};
return yesterdayEMA;
}
private double CalculateEMA_MACD(double[] MACD, int Period, int index)
{
var currentValue = 0d;
var currentEMA = 0d;
var yesterdayEMA = 0d;
var smooth = 2d;
var multiplier = smooth / (1 + Period);
for (int i = 0; i < Period; i++){
currentValue = MACD[index + i - Period];
currentEMA = (currentValue * multiplier) + (yesterdayEMA * (1 - multiplier));
yesterdayEMA = currentEMA;
};
return yesterdayEMA;
}
private double GetPrice(int index)
{
Bar bar = Bars[index];
switch (Source)
{
case Sources.Close:
return bar.Close;
case Sources.Open:
return bar.Open;
case Sources.High:
return bar.High;
case Sources.Low:
return bar.Low;
case Sources.MedianPrice:
return (bar.High + bar.Low) / 2;
case Sources.TypicalPrice:
return (bar.High + bar.Low + bar.Close) / 3;
case Sources.WeightedClose:
return (bar.High + bar.Low + bar.Close + bar.Close) / 4;
}
throw new NotSupportedException("Unsupported price source type: " + Source);
}
It looks like your logic for EMA calculation is wrong. Based on your code, yesterdayEMA is always 0 and therefore right part of EMA equation is also 0.
private double CalculateEMA(int Period, int index)
{
...
var yesterdayEMA = 0D;
...
currentEMA = (currentValue * multiplier) + (yesterdayEMA * (1 - multiplier));
currentEMA = (currentValue * multiplier) + 0
...
}
You need to store yesterdayEMA outside of CalculateEMA and pass it as parameter for recursive calculation.
0 comes true in the first cycle, but yesterday EMA = current EMA; It starts to take values different from 0 in the next cycle due to its equality.

how to convert series of integers into ordinals in C#

i am having a texbox1 with series of integers i would like to know if their is any way i can apply the conversion of these integers into ordinals. below is what i have tried:
when my button convert is clicked with code:
private void btnconvert_Click(object sender, RoutedEventArgs e)
{
foreach (int num in txtresults.ToString())
{
string[] parts = txtresults.Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
double[] numbers = parts.Select(p => double.Parse(p)).ToArray();
double maximum = numbers.Max();
int position = Array.IndexOf(numbers, maximum);
parts[position] = **Ordinal(num);**
txtresults.Text = string.Join(" ", parts);
}
}
this is my method of conversion
public static string **Ordinal(int num)**
{
if (num <= 0) return num.ToString();
switch (num % 100)
{
case 11:
case 12:
case 13:
return num + "th";
}
switch (num % 10)
{
case 1:
return num + "st";
case 2:
return num + "nd";
case 3:
return num + "rd";
default:
return num + "th";
}
}
can i be thought how to do it right please (thanks in advance) (am using c# in wpf)

Tuition Increase

I am trying to get this to display Year 1 original tuition + interest rate then have all the interest rates compound afterwards. It gets stuck on Year 2 then just repeats.
private void button1_Click(object sender, EventArgs e)
{
double originalTuition = 6000.00;
double newTuition;
double interestRate = 0.02;
tuitionListBox.Items.Clear();
for (int year = 1; year <= 5; year++)
{
if (year == 1)
newTuition = originalTuition;
else
newTuition = originalTuition + (originalTuition * interestRate);
newTuition = newTuition + (newTuition * interestRate);
tuitionListBox.Items.Add(year + "\t" + newTuition.ToString("c"));
}
}
newTuition will always start with the same value after year 1 due to your ‘else’ block. My guess is you want to remove the first line of code after the ‘else’.
First initialize newTuition variable.
Then below code:
for (int year = 1; year <= 5; year++)
{
if (year == 1)
newTuition = originalTuition;
else
newTuition = newTuition + (newTuition * interestRate);
tuitionListBox.Items.Add(year + "\t" + newTuition.ToString("c"));
}
I would suggest creating a new method for clarity and reusability. Using brackets with if/else statements makes the code more easy to read, and thereby identifying the problem.
private List<double> GetAnnualTuitions(double originalTuition, double interestRate, int numOfYears)
{
double newTuition = 0;
List<double> tuitions = new List<double>();
for (int year = 1; year <= numOfYears; year++)
{
if (year == 1)
{
newTuition = originalTuition;
}
else
{
newTuition += (newTuition * interestRate);
}
tuitions.Add(newTuition);
}
return tuitions;
}

How to compare 2 character strings?

I am making a typing game and I need to compare a generated string and input string character by character to and then calculate % accuracy.
But it seems am missing something because the function does no compare well.
Am I doing something wrong ?
private void Button_Click(object sender, RoutedEventArgs e)
{
int percentage = 0;
int mistakes = 0;
string input = TextBox1.Text;
string letter = TextBox2.Text;
char[] letters1 = letter.ToCharArray();
char[] input1 = input.ToCharArray();
for (int j = 0; j < input1.Length; j++)
{
if (input1[j] != letters1[j])
mistakes = mistakes +1;
else if (input1[j] == letters1[j])
mistakes = mistakes;
}
percentage = 100 - ((mistakes / letters1.Length) * 100);
Label2.Content = percentage;
}
You're performing integer arithmetic and losing the fractional portion of the result of your division. When you divide two integers, the result is another integer (and you lose the fractional part).
percentage = 100 - ((mistakes / letters1.Length) * 100);
Given your code above, and assuming letters1 is 30 characters long and there are 20 mistakes, then 20 / 30 (or any amount of mistakes from the total characters available, except when every character is wrong), will result in:
percentage = 100 - ((20 / 30) * 100);
// 100 - ((0) * 100) == 100
Converting one of those values to a double should retain the fractional portion of the division:
percentage = 100 - ((mistakes / Convert.ToDouble(letters1.Length) * 100);
// = 100 - ((20 / 30.0) * 100) == 100 - ((0.6666666) * 100) == 33.333333
Hope this works for you.
private void Button_Click(object sender, RoutedEventArgs e)
{
float percentage = 0;
float mistakes = 0;
string input = TextBox1.Text;
string letter = TextBox2.Text;
char[] letters1 = letter.ToCharArray();
char[] input1 = input.ToCharArray();
for (int j = 0; j < input1.Length; j++)
{
if (input1[j] != letters1[j])
{
mistakes++;
}
}
percentage = 100 - ((mistakes / letters1.Length) * 100);
Label2.Content = percentage.ToString();
}

Round any n-digit number to (n-1) zero-digits

Sorry hard to formulate.
I need to round like this:
12 -> 10
152 -> 200
1538 -> 2000
25000 -> 30000
etc.
Twisting my head, but can't see how to make this. Must work for any n number of digits. Anyone got an elegant method for it?
c# or vb.net
How about this:
double num = 152;
int pow = (int)Math.Log10(num);
int factor = (int)Math.Pow(10, pow);
double temp = num / factor;
double result = Math.Round(temp) * factor;
I think you should try with something like this:
public int Round( int number)
{
int power = number.ToString().Length - 1;
int sz = Math.Pow(10, power);
int rounded = (int)Math.Round( number / sz );
return rounded * sz;
}
The idea is to get the size of the nearest 10 power, available by the length of the number expressed as a string. Then divide the number by that power, leaving it like 1,2 and then round it using the Math.Round method and restore the size by remultiplying it to the power.
Much like the previous answer...
I would do it this way:
double d = 25000;
int power = d.ToString().Length - 1;
double multipler = Math.Pow(10,power);
d = Math.Round(d / multipler) * multipler;
Console.WriteLine(d);
One of the way could be
Convert the number to Decimal
Divide it by 10^(n-1) (where n is number of digits)
Now use round function (Decimal.Round)
Multiply again by 10^(n-1)
Divide the number by 10n and round the result, then multiply the result back with 10n;
int MyRound(int num)
{
double divisor = Math.Pow(10, num.ToString().Length - 1);
return (int)(Math.Round(num / divisor, MidpointRounding.AwayFromZero) * divisor);
}
Note that we should use MidpointRounding.AwayFromZero when rounding because of the default banker's rounding.
int MakeOneSigFig(int value)
{
int neg = 1;
if(value <= 10 && value >= -10) { return value; }
if(value == int.MinValue) { value = int.MaxValue; neg = -1; }
if(value < 0) { value = -value; neg = -1; }
int mult = 10; // start at 10 because we've got 'firstDigit = value / 10' below
while(value > 99) { value /= 10; mult *= 10; }
int firstDigit = value / 10;
if(value % 10 >= 5) firstDigit++;
return neg * firstDigit * mult;
}
This is equivalent to MidpointRounding.AwayFromZero. This method doesn't do any double math or string conversions. If you didn't want to loop, you could replace that with the if block below. That would be more efficient, but more code and not quite as easy to read.
if(value < 100) { mult = 10; }
else if(value < 1000) { mult = 100; value /= 10; }
else if(value < 10000) { mult = 1000; value /= 100; }
else if(value < 100000) { mult = 10000; value /= 1000; }
// etc.

Categories

Resources