(I have been newly introduced to the world of C# coding.) I am currently trying to work with the use of functions in the C# language. The program goal is to try to calculate the average using the total distance traveled and the total hours traveled and that will be multiplied by the time to get from NY city to MIAMI to get the distance from NY city to MIAMI.
How can i buld the functions(content wise) properly to give me the result(distance from NY city to MIAMI)? Should i make the function double void and declare them public or private?
4 Textboxes:
Starting Mileage
Ending Mileage
Total Driving Time
Time from NY city to MIAMI
I have placed my functions which will be executed by a button click. A brief Idea of how I plan to use the functions:
private void button1_Click(object sender, EventArgs e)
{
double v = Calculate_Velocity();
double t = Get_Time();
double d = Calculate_Distance (v,t);
Display_Results(v, t, d);
Clear_TextBoxes();
}
You'll want to make the functions private, or protected. The difference between private and protected is that private can only be accessed by code in the class or struct, and protected can only be used in the current class, and any class derived from it.
This is a link to a good explanation of Access Modifiers in CSharp.
Your code should look something like this:
private double CalculateVelocity()
{
double distance = 0;
double time = 0;
if(double.TryParse(tbDistance.Text, out distance) &&
double.TryParse(tbTime.Text, out time))
{
return distance/time;
}
return 0.0;
}
private double GetTime()
{
//Get Time
}
private double CalculateDistance(double velocity, double time)
{
//Calculate Distance
}
private double DisplayResults(double velocity, double time, double distance)
{
//Display Results
}
private double ClearTextboxes()
{
//Clear textboxes
}
private void button1_Click(object sender, EventArgs e)
{
//You get the idea
}
Since you're new to csharp this might be a good time to try using properties. GetTime for example can be written like this:
// Property to GetTime
public double GetTime
{
get
{
// variable to hold time
double time = double.MinValue;
// Safely parse the text into a double
if(double.TryParse(tbTime.Text, out time))
{
return time;
}
// Could just as easily return time here
return double.MinValue;
}
set
{
// Set tbTime
tbTime.Text = value.ToString();
}
}
And you can use the property like so:
double time = GetTime;
or
GetTime = time;
You might also consider using TimeSpan instead of a double for GetTime as well.
since i dont know the formulas i will just give you idea and you can build appication accordingly
just define function inside the class as
double i=0;
public double Calculate_Velocity()
{
i=double.parse(Starting Mileage.Text)*double.parse(TotalDrivingTime.Text );
return i;
//Formula may be wrong but you will get idea abt the things...
}
Likewise define all the functions...
Choosing double is fine if you want fractional miles. If you want a result back like 1500 or 1837 miles, then int is the way to go. By declaring it double, you will get a result back like 1500.33 miles (which would be 1500 miles and 1/3rd of a mile). So the choice is up to you if you want fractional miles (which is more precise) or whole number miles.
For your program, I'd make the functions private. Making them private means that the functions can't be called by instantiating an instance of your class. In other words, the end user wants just the end result. The end user doesn't have any business calling your "helper" functions.
Just as an FYI, you didn't ask but there is also a third visibility option called protected. Protected works just like private. The difference is, if your class is inherited by another class, that class has access to your protected functions and variables.
How can i buld the functions(content wise) properly to give me the
result(distance from NY city to MIAMI)?
First off, there is no absolutely correct answer and everyone will have their own opinion. In my opinion, I would suggest adding a new class to your project.
class Formulas
{
public static double CalculateVelocityFromMileage(double startMileage, double endMileage, double time)
{
return (endMileage - startMileage) / time;
}
}
This isolates the logic of calculating velocity, distance, average time to a separate place and it makes no assumption about what you name your TextBox controls or how the user is expected to enter information into those text boxes.
You should make these functions static. You should think of a static function as one that only requires the inputs provided in the definition of the function. A static function is a good thing, it does not depend on items that are hidden from the view of the person calling your function. Of course, for static functions, you have no other choice but to return double.
And you should make the function public, this way the code in your click event can call it like this:
Formulas.CalculateVelocityFromMileage(start, end, time);
Remember the following:
1. A function should do one thing and do one thing well
2. A function should not rely on hidden values, its output should rely only on its arguments.
You might find yourself writing slightly more code, but you will thank yourself when you start writing more code as your application grows.
But trust your own instincts, and find your own personal style and discover what works for you.
Related
I have a problem that I have been trying to sort out for quite a while now but I just can't wrap my head around it.
I have two double variables that are initialized. Obviously, I get an error for that because they should have a value. However, the only value I could set it to is 0. The issue with that is, if I set the value to 0, my program does not run correctly and the output of my program becomes 0 too.
Error: Local variable 'userSalary' might not be initialized before accessing
I am still kind of learning the ways of methods, parameters, and arguments.
class Program
{
static void Main(string[] args)
{
double userSalary;
double leftOver;
AskQuestion(userSalary);
CalculateTax(userSalary, leftOver);
}
static void AskQuestion(double userSalary)
{
Console.WriteLine("What is annual your salary?");
userSalary = Convert.ToDouble(Console.ReadLine());
}
static void CalculateTax(double userSalary, double leftOver)
{
if (userSalary <= 14_000) //10%
{
Console.WriteLine("You are in Tax Category 1. 10% of your Salary goes to the state!");
Console.WriteLine("Calculating Salary...");
Thread.Sleep(500);
leftOver = userSalary - (userSalary * 10 / 100);
Console.WriteLine("Your Salary after taxation is: $" + leftOver);
}
}
}
You have multiple problems here.
Firstly, your "Error: Local variable 'userSalary' might not be initialized before accessing" problem:
While fields (class-level variables) are initialized to their default values when constructing a class, method variables are not initialized. To do so, you would need to assign a value to them. For example:
double userSalary = 0;
double leftOver = 0;
The next problem you have is that all variables are passed by value (i.e. a copy is made) and not by reference. Note that this is not to say that the types being passed are not reference types, but that the pointer the variable represents is passed as a copy. You can read more on that here.
What this means for you is that, while AskQuestion changes its own userSalary argument variable, it doesn't change the calling method's variable. One way to solve this is to use the ref or out keywords. (ref is used where the variable is already initialized but the method changes it, out is used where the method initializes the variable). More on that here.
So you could write your code like this:
static void AskQuestion(out double userSalary)
And then call it like so:
double userSalary;
AskQuestion(out userSalary);
or simply:
AskQuestion(out double userSalary);
Though a better approach is to have the method simply return the result. We'll also remove the leftOver argument from CalculateTax as that isn't used anywhere:
Note : You should always use TryParse Style methods to validate user input
static double AskQuestion()
{
double userSalary;
Console.WriteLine("What is annual your salary?");
// simple validation loop
while (!double.TryParse(Console.ReadLine(), out userSalary))
Console.WriteLine("You had one job... What is annual your salary?");
return userSalary;
}
static void CalculateTax(double userSalary)
{
if (userSalary <= 14_000) //10%
{
Console.WriteLine("You are in Tax Category 1. 10% of your Salary goes to the state!");
Console.WriteLine("Calculating Salary...");
Thread.Sleep(500);
double leftOver = userSalary - (userSalary * 10 / 100);
Console.WriteLine("Your Salary after taxation is: $" + leftOver);
}
}
And then initialize userSalary and call CalculateTax like so:
userSalary = AskQuestion();
CalculateTax(userSalary);
Use:
double userSalary=0.0;
double leftOver=0.0;
Just a quick question so as to know if there is a better practice between updating the value of a property with a method that gets called everytime the value needs to be changed or just to do it in the getter.
For instance between this:
public double Balance { get; private set; }
private void UpdateBalance()
{
if (Payments.IsNullOrEmpty())
{
Balance = 0;
}
else
{
double amountSum = 0;
foreach (Payment payment in Payments)
{
amountSum += payment.Amount;
}
Balance = amountSum;
}
}
And this :
public double OtherBalance
{
get
{
if (Payments.IsNullOrEmpty())
return 0;
double amountSum = 0;
foreach (Payment payment in Payments)
{
amountSum += payment.Amount;
}
return amountSum;
}
}
The only difference I can think of is one of performance, since in the first case the getter runs through the whole list every time we try to get the value of the property. However, you don't need to worry about calling the Update method every time you do a change that might impact the value of the property like in the second option. Is that difference really significant ? Beyond that, is there any reason to chose one option over another ?
Thanks in advance
Well in first method for reading the balance you should call the getter again and in the second method there is no balance at all, personally I prefer second method because it's generate the value at the call time so you can be sure that it is always updated and it doesn't need to call a function and then read the value so it's cleaner and more maintainable.
To add to Kiani's answer, if you don't mind using Linq, you could turn your code to a one liner.
private double Balance=>(!Payments.Any())?0:Payments.Sum(t=>t.Amount);
This is a snippet of code from my C# application:
public Player GetSquareCache(int x, int y)
{
if (squaresCacheValid)
return (Player)SquaresCache[x,y];
else
//generate square cache and retry...
}
squareCacheValid is a private bool and SquaresCache is private uint[,].
The problem was that the application is running extremely slow and any optimization just made it slower, so I ran a tracing session.
I figured that GetSquareCache() gets 94.41% own time, and the if and return split that value mostly evenly (46% for if and 44.82% for return statement). Also the method is hit cca. 15,000 times in 30 seconds, in some tests going up to 20,000.
Before adding methods that call GetSquareCache(), program preformed pretty well but was using random value instead of actual GetSquareCache() calls.
My questions are: is it possible that these if/return statements used up so much CPU time? How is it possible that if statements GetSquareCache() is called in (which in total are hit the same number of times) have minimal own time? And is it possible to speed up the fundamental computing operation if?
Edit: Player is defined as
public enum Player
{
None = 0,
PL1 = 1,
PL2 = 2,
Both = 3
}
I would suggest a different approach , under the assumption that most of the values in the square hold no player, and that the square is very large remember only location where there are players,
It should look something like this :
public class PlayerLocaiton
{
Dictionary<Point, List<Player>> _playerLocation = new ...
public void SetPlayer(int x, int y, Player p)
{
_playerLocation[new Point(x,y)].add(p);
}
public Player GetSquareCache(int x, int y)
{
if (squaresCacheValid)
{
Player value;
Point p = new Point(x,y);
if(_playerLocation.TryGetValue(p, out value))
{
return value ;
}
return Player.None;
}
else
//generate square cache and retry...
}
}
The problem is just the fact that method is called way too many times. And indeed, 34,637 ms it gets in last trace, over 34,122 hits it got is a little over 1ms per hit. In decompiled CIL code there are also some assignments to local variables not present in code in both if branches because it needs one ret statement. The algorithm itself is what needs to be modified, and such modifications were planned anyway.
replace return type of this method to int and remove the casting
to Player
if cache is to be set once remove the if from this method so
it is always true when the method is called
replace array with single
dimension array and access it via unsafe fixed way
I know there are some questions about it but I want to consider it from a diffrent perspective.
My result after searching for this question was that there cant be an exact way to weight an instance by bit. But isnt there a way to approach a realistic size based on storage information?
For instance:
class Test
{
// Fields
private int high = 7;
private int low = 5;
private int GetHigh()
{
return High; // Access private field
}
private int GetLow()
{
return Low; // Access private field
}
public float Average ()
{
return (Gethigh() + Getlow()) / 2; // Access private methods
}
}
Test a = new Test();
Test b = new Test();
a.Average();
So my actual question is: can we asses the size of instance a (and b) in certain ways?
I mean we could simply calculate the fields:
2 int fields = 64 Bit
But what about metadata?
How / or can we actually weight the methods since they are part of the Class type object.
And methods are shared by their instances only differentiated by their this pointer.
Can somebody please help me to get a better understanding of this problem. To make it clear, its not about getting an exact value of bits or a method that can calculate this by manipulating VS. Its more about getting a better understanding of instances saved in memory.
I have this on a button:
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = "x12y04";
//make new instance for MyMath class
MyMath dRet01 = new MyMath();
//use the doubleArrayXY (in MyMath class) to get doubble array back
double[] retD = dRet01.doubleArrayXY(s);
//use the calcResultFromDoubleArray (in MyMath class) to get result
MyMath dRet02 = new MyMath();
double result = dRet02.calcResultFromDoubleArray(retD[0], retD[1]);
//DEBUG!
/*
string TEST1 = Convert.ToString(returnedDouble[0]);
MessageBox.Show(TEST1);
string TEST2 = Convert.ToString(returnedDouble[1]);
MessageBox.Show(TEST2);
string TEST3 = Convert.ToString(result);
MessageBox.Show(TEST3);
*/
}
where the class "MyMath" is:
public double[] doubleArrayXY(string inputValue)
{
//in case there are upper case letters, set all to lower
string inpLow = inputValue.ToLower();
//split the string on the Y (so this tech should also work for x89232y329)
//so this will create res[0] that is x89232 and an res[1] that is 329
string[] res = inpLow.Split(new string[] { "y" }, StringSplitOptions.None);
//in the first string that looks like x89232, remove the x
string resx = res[0].Replace("x", null);
//now get the x value to a double
double x = double.Parse(resx);
//now get the y valye to a double
double y = double.Parse(res[1]);
//return in a double array the x and then the y (x=double[0] and y=double[1])
return new double[] {x,y};
}
public double calcResultFromDoubleArray(double one, double two)
{
return (one * two);
}
Now I know the part in the class that is "calcResultFromDoubleArray" is kind of useless at this point, but I want to make that do some extra stuff later on.
what I wonder about the most is in the main code where I make this new dRet10, and later on make dRet02.
I was thinking at first I could do something like this:
double result = dRet01.calcResultFromDoubleArray(retD[0], retD[1]);
So in that case I would not need to create a new instance of MyMath, but this does not work.
So I need to call a new instance for the class (like I did), or can I do this in a more elegant way?
I'm still kind of new to C#, so I'm trying to learn how to program in a nice and elegant way, besides just making it work.
Since your methods don't really use any other state information besides the parameters passed they probably should be static so you would not have to create any instances of your class at all:
double[] retD = MyMath.DoubleArrayXY(s);
double result = MyMath.CalcResultFromDoubleArray(retD[0], retD[1]);
If all of your methods in MyMath are static, declare the class itself static - just like the System.Math class, so you cannot create instances at all.
You could make your calcResultFromDoubleArray method static, and then call it via MyMath.calcResultFromDoubleArray(val1, val2)
In your code there is not really a point of creating an instance of MyMath class. You can make the methods static
public static double[] doubleArrayXY(string inputValue) { ... }
public static double calcResultFromDoubleArray(double one, double two) { ... }
and call them like so
double[] retD = MyMath.doubleArrayXY(s);
double result = MyMath.calcResultFromDoubleArray(retD[0], retD[1]);
If you make your methods static you can do the following in your main class:
double result = MyMath.calcResultFromDoubleArray(MyMath.doubleArrayXY(s));
And change calcResultFromDoubleArray to take the array rather than two values (as its title suggests).
FYI you can also chain String operations because they return Strings as such:
string[] res = inputValue.ToLower().Split(new string[] { "y" }, StringSplitOptions.None);
No need to create double x and double y. Change the last part of the method to:
return new double[] {double.Parse(resx), double.Parse(res[1]};
While changes such as these (there are more, there often are) will be minimal increases in performance, they will increase it a bit (the most from the static part - new is relatively expensive).
Most importantly though, they make the code more readable and elegant.
It looks to me like the two methods on MyMath could (or possibly should) both be static since they rely on nothing at all outside the method. Quite often this is the case with things like Maths libraries. It seems others have said this too though.
In addition you may be better off to create a class or struct to represent your X/Y. It may be that it isn't appropriate but if it represents a thing then you might want a class to represent that thing as well. See for example the Point and PointF classes. I'd suggest one of these but they don't have the same precision that you are using (and your X/Y may not be points so it might not be appropriate)
Also the line you said didn't work:
double result = dRet01.calcResultFromDoubleArray(retD[0], retD[1]);
This should have worked with the code as shown. What error were you getting on it? dRet01 exists and so it should have worked just as well as creating a new instance. The comments that it should be static are most applicable but if you are new to C# I thought it worth pointing this out so you don't build up any wrong ideas about what is and isn't possible. :)