Restart program from a certain line with an if statement? - c#

could anyone help me restart my program from line 46 if the user enters 1 (just after the comment where it states that the next code is going to ask the user for 2 inputs) and if the user enters -1 end it. I cannot think how to do it. I'm new to C# any help you could give would be great!
class Program
{
static void Main(string[] args)
{
//Displays data in correct Format
List<float> inputList = new List<float>();
TextReader tr = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
String input = Convert.ToString(tr.ReadToEnd());
String[] items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (int i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
// Ask for two inputs from the user which is then converted into 6 floats and transfered in class Coordinates
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
string point = Console.ReadLine();
string[] pointInput = point.Split(' ');
int pointNumber = Convert.ToInt16(pointInput[0]);
int pointNumber2 = Convert.ToInt16(pointInput[1]);
Coordinates distance = new Coordinates();
distance.latitude = (Convert.ToDouble(items[pointNumber * 3]));
distance.longtitude = (Convert.ToDouble(items[(pointNumber * 3) + 1]));
distance.elevation = (Convert.ToDouble(items[(pointNumber * 3) + 2]));
distance.latitude2 = (Convert.ToDouble(items[pointNumber2 * 3]));
distance.longtitude2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 1]));
distance.elevation2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 2]));
//Calculate the distance between two points
const double PIx = 3.141592653589793;
const double RADIO = 6371;
double dlat = ((distance.latitude2) * (PIx / 180)) - ((distance.latitude) * (PIx / 180));
double dlon = ((distance.longtitude2) * (PIx / 180)) - ((distance.longtitude) * (PIx / 180));
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos((distance.latitude) * (PIx / 180)) * Math.Cos((distance.latitude2) * (PIx / 180)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
double ultimateDistance = (angle * RADIO);
Console.WriteLine("The distance between your two points is...");
Console.WriteLine(ultimateDistance);
//Repeat the program if the user enters 1, end the program if the user enters -1
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
Console.ReadLine();
if (Convert.ToInt16(Console.ReadLine()) == 1);
{
//here is where I need it to repeat
}

bool exit = false;
do
{
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
...
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
string input;
do
{
input = Console.ReadLine().Trim();
}
while (input != "1" && input != "-1");
if (input == -1) exit = true;
}
while (!exit);
But you would do much better to think about pushing logic into methods and functions such that you program is built up of much smaller building blocks.
You should be aiming towards something like this:
bool exit = false;
do
{
Point[] points = ReadCoordinates();
Whatever result = CalculateWhatever();
DisplayResults(results);
exit = ShouldExit();
}
while (!exit);
This makes the outer loop of your program self documenting and the methods self explanatory.

if (Convert.ToInt16(Console.ReadLine()) == 1);
{
Main(args)
}

That's quite an odd thing to do.
Have you looked into the while loop?
You could make a method of the above structure and loop it, while userinput equals 1
if it equals -1, call the following statement
Application.Exit()

Can use Goto to make the program loop on user input.
public static void Main(string[] args)
{
RestartApplication:
//// Displays data in correct Format
TextReader textReader = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
var input = Convert.ToString(textReader.ReadToEnd());
var items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (var i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
//// Ask for two inputs from the user which is then converted into 6 floats and transferred in class Coordinates
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
var point = Console.ReadLine();
string[] pointInput;
if (point != null)
{
pointInput = point.Split(' ');
}
else
{
goto RestartApplication;
}
var pointNumber = Convert.ToInt16(pointInput[0]);
var pointNumber2 = Convert.ToInt16(pointInput[1]);
var distance = new Coordinates
{
Latitude = Convert.ToDouble(items[pointNumber * 3]),
Longtitude = Convert.ToDouble(items[(pointNumber * 3) + 1]),
Elevation = Convert.ToDouble(items[(pointNumber * 3) + 2]),
Latitude2 = Convert.ToDouble(items[pointNumber2 * 3]),
Longtitude2 = Convert.ToDouble(items[(pointNumber2 * 3) + 1]),
Elevation2 = Convert.ToDouble(items[(pointNumber2 * 3) + 2])
};
//// Calculate the distance between two points
const double PIx = 3.141592653589793;
const double Radio = 6371;
var dlat = (distance.Latitude2 * (PIx / 180)) - (distance.Latitude * (PIx / 180));
var dlon = (distance.Longtitude2 * (PIx / 180)) - (distance.Longtitude * (PIx / 180));
var a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(distance.Latitude * (PIx / 180)) * Math.Cos(distance.Latitude2 * (PIx / 180)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
var angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var ultimateDistance = angle * Radio;
Console.WriteLine("The distance between your two points is...");
Console.WriteLine(ultimateDistance);
//// Repeat the program if the user enters 1, end the program if the user enters -1
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
var userInput = Console.ReadLine();
if (Convert.ToInt16(userInput) == 1)
{
//// Here is where the application will repeat.
goto RestartApplication;
}
}
also did a bit of code formatting. Hope it helps.

You could do that with goto, be aware however that this is considered bad practice.
static void Main(string[] args)
{
...
MyLabel:
...
if (Convert.ToInt16(Console.ReadLine()) == 1);
{
//here is where I need it to repeat
goto MyLabel;
}

Related

How to show solutions for quadratic formula

So I wrote a Quadratic formula program in C#, how do I take the quadratic formula program and modify it so that the program correctly displays the number of solutions.
if there are two solutions,
(x - x1)(x - x2) = 0
if there is only one solution,
(x - x0)^2 = 0
if there are no solutions,
No Solution.
This is the program, if someone could show the solution to this for me that would be wonderful, I'm really stuck on how to do it.
using System;
namespace quadraticequation
{
class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine("Enter a number for a"); //ask the user for information
double a = double.Parse(Console.ReadLine()); //Gets a from the user
Console.WriteLine("Enter a number for b"); //asks the user for information
double b = double.Parse(Console.ReadLine()); //Gets b from the user
Console.WriteLine("Enter a number for c"); //asks the user for information
double c = double.Parse(Console.ReadLine()); //Gets c from the user
//double.Parse --> is used to convert a number or string to a double.
//Console.ReadLine() --> is used to take the input from the user.
//We call a function here
Quadratic(a, b, c);
}
//We need to create a new function
public static void Quadratic(double a, double b, double c)
{
double deltaRoot = Math.Sqrt(b * b - 4 * a * c); //Math.Sqrt takes the square root of the number
if (deltaRoot >= 0) // we use an if statement here to handle information
{
double x1 = (-b + deltaRoot) / 2 * a; //We write the information for x1 here
double x2 = (-b - deltaRoot) / 2 * a; //We write the information for x2 here
Console.WriteLine("x1 = " + x1 + " x2 = " + x2); //we use this to write the roots
}
else // we use an else statement so that we dont return an error when there are no roots
{
Console.WriteLine("There are no roots");
}
}
}
}
I think you have to review your second degree formula solution-skills. You write:
double deltaRoot = Math.Sqrt(b * b - 4 * a * c);
But the test is actually whether b2-4×a×c is larger than or equal to zero: indeed that is actually why we check it: because we cannot take the square root of a negative number (yeah there exist complex numbers that can take the square root of a negative number, but let's ignore that for now).
So the solution is to write it like:
public static void Quadratic(double a, double b, double c) {
double delta = b*b-4*a*c; //only delta
if (delta > 0) {
double deltaRoot = Math.Sqrt(delta);
double x1 = (-b + deltaRoot) / (2 * a); //We write the information for x1 here
double x2 = (-b - deltaRoot) / (2 * a); //We write the information for x2 here
Console.WriteLine("x1 = " + x1 + " x2 = " + x2); //we use this to write the roots
} else if(delta == 0) {
double x1 = -b/(2*a);
Console.WriteLine("x1 = " + x1); //we use this to write the roots
} else {
Console.WriteLine("There are no roots");
}
}
You also have to write (-b + deltaRoot) / (2*a) (with (2*a)), otherwise you will multiply (-b + deltaRoot) / 2 with a instead.
A final note is that equality comparisons with floating points is very tricky so delta == 0 will often fail since the result can be something 1e-20-ish, which is simply an error when performing floating point arithmetic. So it is perhaps better to use a small range of values.
This gives:
csharp> MainClass.Quadratic(1,1,1);
There are no roots
csharp> MainClass.Quadratic(1,1,0);
x1 = 0 x2 = -1
csharp> MainClass.Quadratic(1,0,0);
x1 = 0

How would i work out magnitude quickly for 3 values?

How can I use a Fast Magnitude calculation for 3 values (instead of using square root)? (+/- 3% is good enough)
public void RGBToComparison(Color32[] color)
{
DateTime start = DateTime.Now;
foreach (Color32 i in color)
{
var r = PivotRgb(i.r / 255.0);
var g = PivotRgb(i.g / 255.0);
var b = PivotRgb(i.b / 255.0);
var X = r * 0.4124 + g * 0.3576 + b * 0.1805;
var Y = r * 0.2126 + g * 0.7152 + b * 0.0722;
var Z = r * 0.0193 + g * 0.1192 + b * 0.9505;
var LB = PivotXyz(X / 95.047);
var AB = PivotXyz(Y / 100);
var BB = PivotXyz(Z / 108.883);
var L = Math.Max(0, 116 * AB - 16);
var A = 500 * (LB - AB);
var B = 200 * (AB - BB);
totalDifference += Math.Sqrt((L-LT)*(L-LT) + (A-AT)*(A-AT) + (B-BT)*(B-BT));
}
totalDifference = totalDifference / color.Length;
text.text = "Amount of Pixels: " + color.Length + " Time(MilliSeconds):" + DateTime.Now.Subtract(start).TotalMilliseconds + " Score (0 to 100)" + (totalDifference).ToString();
RandomOrNot();
}
private static double PivotRgb(double n)
{
return (n > 0.04045 ? Math.Pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
}
private static double PivotXyz(double n)
{
return n > 0.008856 ? CubicRoot(n) : (903.3 * n + 16) / 116;
}
private static double CubicRoot(double n)
{
return Math.Pow(n, 1.0 / 3.0);
}
This is the important part: totalDifference += Math.Sqrt((L-LT)*(L-LT) + (A-AT)*(A-AT) + (B-BT)*(B-BT));
I know there are FastMagnitude calculations online, but all the ones online are for two values, not three. For example, could i use the difference between the values to get a precise answer? (By implementing the difference value into the equation, and if the difference percentage-wise is big, falling back onto square root?)
Adding up the values and iterating the square root every 4 pixels is a last resort that I could do. But firstly, I want to find out if it is possible to have a good FastMagnitude calculation for 3 values.
I know I can multi-thread and parllelize it, but I want to optimize my code before I do that.
If you just want to compare the values, why not leave the square root out and work with the length squared?
Or use the taylor series of the square root of 1+x and cut off early :)

Correct way to use indexer in Parallel.For

I have a method which generates a (Waveform) bitmap based on a specific (Waveform)-function (in the examples below I am simply using Math.Sin to simplify things). Up until now this method was "serial" (no threads) however some of the functions used are relatively time consuming so I tried using Parallel.For and Parallel.ForEach, but I guess the index variable I use must get "corrupted" (or at least have another value than what I expect) the graphics being generated will either contain "spikes" or strange lines between points that are not neighbours.
Here first is my serial version (which works):
Point[] points = new Point[rect.Width];
byte[] ptTypes = new byte[rect.Width];
for (int i = 0; i < rect.Width; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int) (halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
using (GraphicsPath wavePath = new GraphicsPath(points, ptTypes))
{
gph.DrawPath(wavePen, wavePath);
}
As you can see the code simply uses 2 arrays (one for Points and one for PointTypes) so the order these values are inserted into the array should not matter, as long as the values are inserted into the correct elements of the arrays.
Next example is using Parallel.For (to simplify the examples I have omitted the creation of the arrays and the actual draw method):
Parallel.For(0, rect.Width,
i =>
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
});
Lastly I tried using a Partitioner with a Parallel.ForEach loop, but that did not fix the problem either:
var rangePartitioner = Partitioner.Create(0, rect.Width);
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
});
Pelle
newPoint = new Point(rect.Left + i, rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
newPoint is not scoped to your for() loop - it's likely threads are updating it before you get to the next line points[i] = newPoint;
Change it to var newPoint = ...
Otherwise, your Parallel.For looks fine.
Also, does this have different behavior?
Math.Sin(phase);//waveform.ValueAtPhase(phase);
Providing ValueAtPhase does not modify anything, you should be able to use it within the loop.

Dealing with imprecise, jittery gps signal

My goal is to use GPS to measure the distance that I moved with my phone. My problem is, that the results are imprecise. I've used the following code to calculate the distance:
public double getDistance(GeoCoordinate p1, GeoCoordinate p2)
{
double d = p1.Latitude * 0.017453292519943295;
double num3 = p1.Longitude * 0.017453292519943295;
double num4 = p2.Latitude * 0.017453292519943295;
double num5 = p2.Longitude * 0.017453292519943295;
double num6 = num5 - num3;
double num7 = num4 - d;
double num8 = Math.Pow(Math.Sin(num7 / 2.0), 2.0) + ((Math.Cos(d) * Math.Cos(num4)) * Math.Pow(Math.Sin(num6 / 2.0), 2.0));
double num9 = 2.0 * Math.Atan2(Math.Sqrt(num8), Math.Sqrt(1.0 - num8));
return (6376500.0 * num9);
}
This is my OnLocationChanged implementation:
bool begin = true;
public void OnLocationChanged(Location location)
{
_aktuellerOrt = location;
//aktuellerOrt.Speed is always 0, so I cannot use that.
if (_aktuellerOrt == null)
{
//message
}
else
{
if (_aktuellerOrt.Accuracy > 70) //I found values around 130 to be more or less good
{
_locationText.Text = String.Format("{0}, {1}", _aktuellerOrt.Latitude, _aktuellerOrt.Longitude);
GeoJetzt = new GeoCoordinate();
GeoJetzt.Latitude = _aktuellerOrt.Latitude;
GeoJetzt.Longitude = _aktuellerOrt.Longitude;
if (beginn)
{
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
beginn = false;
}
else
{
double abstand = getDistance(GeoVorher, GeoJetzt);
weg += abstand;
if (weg >= 1)
_distanzText.Text = weg + " kilometers";
else
_distanzText.Text = (weg * 1000) + " meters";
_distanzText.Text += " (" + abstand + ", " + _aktuellerOrt.Accuracy + ")";
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
}
}
else
_locationText.Text = "Too coarse, now " + _aktuellerOrt.Accuracy + ".";
}
}
The problem is, I get values for abstand within the kilometer range while not moving the phone.
What are best practices for imprecise signals? My goal is to measure the distance while jogging or running, so 10 - 16 km/h.

Getting runtime error, C# Converting Array to Int

for some reason this will compile but it comes out with an error at the end and I can't figure out why. The first part of the code is to display a table from a text file which works correctly, the second part doesn't.
I don't think it even gets to the Console.WriteLine bit, which was a way of checking whether it did. Can anyone see why?
Thanks for any help you can give!
class Program
{
static void Main(string[] args)
{
List<float> inputList = new List<float>();
TextReader tr = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
String input = Convert.ToString(tr.ReadToEnd());
String[] items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (int i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
// Ask for two bits of data which are then stored in Longtitude, Latitude and Elevation
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
string point = Console.ReadLine();
string[] pointInput = point.Split(' ');
int pointNumber = Convert.ToInt16 (pointInput[0]);
int pointNumber2 = Convert.ToInt16 (pointInput[1]);
int Latitude = (Convert.ToInt16(items[pointNumber*3]));
int Longtitude = (Convert.ToInt16(items[(pointNumber*3)+1]));
int Elevation = (Convert.ToInt16(items[(pointNumber*3)+2]));
int Latitude2 = (Convert.ToInt16(items[pointNumber2 * 3]));
int Longtitude2 = (Convert.ToInt16(items[(pointNumber2 * 3) + 1]));
int Elevation2 = (Convert.ToInt16(items[(pointNumber2 * 3) + 2]));
Console.WriteLine("Latitude");
Console.WriteLine("Latitude2");
You are using decimal values, which cannot be converted into Int16. So use float.
Also, Outputting "Latitude" will write the variable's name, not its value.
I modified your code:
float Latitude = (float.Parse(items[pointNumber*3]));
float Longtitude = (float.Parse(items[(pointNumber*3)+1]));
float Elevation = (float.Parse(items[(pointNumber*3)+2]));
float Latitude2 = (float.Parse(items[pointNumber2 * 3]));
float Longtitude2 = (float.Parse(items[(pointNumber2 * 3) + 1]));
float Elevation2 = (float.Parse(items[(pointNumber2 * 3) + 2]));
Console.WriteLine(Latitude);
Console.WriteLine(Latitude2);
Your input strings are of floating values, not integers. You can parse to floats like this:
float Latitude = (Convert.ToSingle(items[pointNumber * 3]));
float Longtitude = (Convert.ToSingle(items[(pointNumber * 3) + 1]));
float Elevation = (Convert.ToSingle(items[(pointNumber * 3) + 2]));
float Latitude2 = (Convert.ToSingle(items[pointNumber2 * 3]));
float Longtitude2 = (Convert.ToSingle(items[(pointNumber2 * 3) + 1]));
float Elevation2 = (Convert.ToSingle(items[(pointNumber2 * 3) + 2]));

Categories