C# Value unitialized - c#

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;

Related

Pipe sizing C# code gives unwanted result

I am new to C# and trying to figure out how to write simple codes to perform basic calculations. I tried to write code for pipe diameter and everything seems to be fine but the result is NaN.
I've tried to change locations for variables declarations as I suspect that there is a problem with. I tried also static keyword but without success.
This is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Pipe_Sizing
//This simple code is intended to calculate diameter of the pipe after getting flow and velcity values from the user
{
class Program {
//This method is created to read input from users and convert it to number
static void readnum(string inp, double num) {
inp = Console.ReadLine();
while ((num = double.Parse(inp)) < 0) {
Console.WriteLine("Sorry, you need value in digits");
inp = Console.ReadLine();
}
Console.WriteLine(num);
}
static string flo;
static double flox;
static string vel;
static double velx;
static void Main()
{
// Get the Flow value from thre user
Console.WriteLine("Please Enter the value of Flow in m3/hr");
readnum(flo, flox);
// Get the Velocity value from the user
Console.WriteLine("Please Enter the value of velcoty in m/s");
readnum(vel, velx);
double dd = (4 * flox) / (3.14 * velx);
double d = Math.Sqrt(dd);
Console.WriteLine("The diameter required for the pipe is " + d);
Console.ReadLine();
}
}
}
How to get the result as a number?
The method readnum does not return anything. The parameters of readnum (inp and num) are local variables to the method - changing their values will have no effect outside the method. Therefore in the Main method the variables flox and velx will still have their default values of 0.0. Change readnum so that it returns the num it parsed from the user input.
Many big No's in your code
static void readnum(string inp, double num)
This is not doing what you think it does (I assume): double is a value Type, meaning it get passed by value and not by reference: you code is going to modify the local (to readnum method) variable. Same for string inp: even if string is a reference type, it works as a value type in this context (for more on this google string c# immutable)
When in Main you call readnum, the variable you are passing are not modified
num = double.Parse(inp)
Parse will throw an exception if the input string is not convertible to a double (same for Parse methods for int, date, etc). You may want to use TryParse and check it return value before proceeding
static double flox;
static double velx;
You actually don't need to have these variables static (nor even class member): just declare them local for the function you are using them: the bigger the scope of a variable, the harder to handle it
static string flo;
static string vel;
Same as above more or less, you actually just need a local variable within readnum
double dd = (4 * flox) / (3.14 * velx);
.Net has a very convenient Math.Pi, much better then a 3.14
This can be a cleaner (and maybe working, not tested) version of your code:
using System;
using System.Text;
public class Program
{
//This method is created to read input from users and convert it to number
static double readnum()
{
string inp = Console.ReadLine();
double res;
while (!double.TryParse(inp, out res)) // add check for negative value
{
Console.WriteLine("Sorry, you need value in digits");
inp = Console.ReadLine();
}
Console.WriteLine(res);
return res;
}
public static void Main()
{
// Get the Flow value from thre user
Console.WriteLine("Please Enter the value of Flow in m3/hr");
double flox = readnum();
// Get the Velocity value from the user
Console.WriteLine("Please Enter the value of velcoty in m/s");
double velx = readnum();
double dd = (4 * flox) / (Math.PI * velx); //
double d = Math.Sqrt(dd);
Console.WriteLine("The diameter required for the pipe is " + d);
Console.ReadLine();
}
}

How to write a function that takes an integer as a parameter and calculates and returns the squared value

Ahoy! I have just started methods but I am a tad confused when it comes to methods with math. First post so be nice :) I'm aware I out in NumberToSquare way too many times!
Write a program that asks the user to enter a number. In your program write a function called SquareValue that takes an integer parameter and calculates the square of integer parameter and returns this squared value. Your program should take this returned square value and display it. An example of the output is:
Please enter a number to square: 8
/ 8 squared is: 64
What I have so far is not so comprehensible. I thought along a few different avenues and was unsure as to what to delete. Help please.
namespace SquareValue
{
class Program
{
static void Main(string[] args)
{
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
string output;
Console.ReadKey();
}
public int SquareValue(NumberToSquare, NumberToSquare);
{
int result = NumberToSquare * NumberToSquare;
return result;
Console.WriteLine("{0} squared is "+result");
}
public int NumberToSquare()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = Console.ReadLine();
return NumberToSquare;
}
}
I see no reason to over complicate this:
public int Square(int x)
{
return (x * x);
}
or
public int Square(int x)
{
return Math.Pow(x,2);
}
Or just use Math.Pow as it exists with 2 as the Power Of number.
You seem very green on programming and I'm not sure SO is a place to go to learn the basics, but I'll run through what you've done and explain what's going wrong.
Your original program concept is fine but there are many issues with basic syntax. I understand you mightn't be familiar with reading compiler errors so I'll explain the errors that I see just reading through the code...
You put a ; at the end of the SquareValue(..., ...) method which teeminates the declaration so the body in braces isn't part of the method, then things go haywire later on.
You're not passing in the value captured from the NumberToSquare method...
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
NumberToSquare isn't a defined variable so NumberToSquare * NumberToSquare can't calculate, what you'd want is number * number where `number is the value entered by the user.
Your definition of int SquareValue(NumberToSquare, NumberToSquare) expects two parameters although you haven't speified the type. It should be
int SquareValue(int NumberToSquare, int NumberToSquare)
but you have the same variable declared twice which is another error and then you aren't passing two parameters anyway. You want to multiply a number by itself therefore you only have a single source number so why declared two parameters? You need a single parameter method
int SquareValue(int NumberToSquare)
and call like this
int number=NumberToSquare();
SquareValue(number);
Now the SquareValue() method returns an int but you never capture it in the calling code and display the result in the method. Follow the idea in this app that the Main method will do all the orchestration and display, but the SquareValue() method should ONLY do a calculation and not any I/O. I'd also rename the NumberToSquare() method a as what is actually happening ... GetNumberToSquareFromUser().
And there's also a stray " before the closing bracket.
Console.WriteLine("{0} squared is " + result");
And you defined a string output variable which is never used.
And your methods need to be static because main(..) is a static method, not instance. If you declare a Squaring class and instantiated it then you could call non static methods from that.
Also ReadLine() returns a string which can't be assigned to an int.
And finally the result line is implicitly using String.Format behind the scenes but you haven't specified the original number for the {0} token. You could also use interpolation. You could do either of these
Console.WriteLine("{0} squared is " + result, number);
Console.WriteLine($"{number} squared is " + result);
So here's your program revised
class Program
{
static void Main(string[] args)
{
int number = GetNumberToSquareFromUser();
int result = SquareValue(number);
Console.WriteLine("{0} squared is " + result, number);
Console.ReadKey();
}
public static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
public static int GetNumberToSquareFromUser()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = int.Parse(Console.ReadLine());
return NumberToSquare;
}
}
I hope this help, I know it's alot to take in, but I hope you take the time to read and really understand rather than just blindly submit the revised version.
When writing your methods, make them reusable. When you start using a method to output to the console in addition to its primary purpose (i.e. to square a number), its re-usability becomes minimal. It is much better to keep specific code in your main method, and put sub tasks into separate methods, such as squaring a number. Now, whenever you need to square a number, you already have a perfectly good method for that.
I didn't handle the case for users entering bad input, but that can be done in the else of the TryParse if block.
static void Main(string[] args)
{
int squredNum = 0;
int NumberToSquare = 0;
Console.WriteLine("Please enter a number to square: ");
if(int.TryParse(Console.ReadLine(), out NumberToSquare))
{
squredNum = SquareValue(NumberToSquare);
Console.WriteLine("{0} squared is {1}", NumberToSquare, squredNum);
}
Console.ReadKey();
}
static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
p.s. I would not recommend using Math.Pow() to square a number. No need to kill a fly with a bazooka!
Here is an example of such program with robust handling:
using System;
namespace ConsoleApp1
{
internal static class Program
{
private static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter value to square or X to exit");
var line = Console.ReadLine();
if (line == null)
continue;
if (line.Trim().Equals("X", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("Exitting ...");
break;
}
int result;
if (!int.TryParse(line, out result))
continue;
Console.WriteLine(result * result);
}
}
}
}
See the docs online, understand each statement, write your very own program then as your teacher will likely figure out you didn't pull that solely by yourself :)

C# Console Application - Using Methods to Pass Arguments

I have an application assignment from school that I have been working on and have gotten stuck on. I am not understanding some of the concepts to complete my program. It is simple and I have the basic structure down. Could someone assist me in understanding and completing my program? Below is the listed information:
The following is the overall application assignment:
Write a program to display the average of some numbers. Your program will consist of three user defined methods named GetNums(), CalcAvg(), and DspAvg(). In GetNums() prompt for and read in 3 real numbers from the keyboard. After reading in the numbers, call CalcAvg() passing the three numbers as input. CalcAvg() must RETURN (use the return statement) the average of the 3 numbers. After calling CalcAvg(), call DspAvg() to display the average and the three numbers entered. Your program must not contain any variables with class-wide scope (all variables must be declared inside a method). All method calls (GetNums(), CalcAvg(), and DspAvg() must be called from main()). Using proper passing is important.
Your output should closely resemble the following.
The average of 10.20, 89.50, and 17.60 is 39.10.
Round the average to two decimal places. Display all values with two decimal places.
GetNums() will have three arguments, all pass by out. CalcAvg() will have three arguments, all pass by copy. Do not use four! DspAvg() will have four arguments, all pass by copy.
Below is the following code I have written, but have gotten stuck, based on the requirements above.
static void Main(string[] args)
{
int nu1, nu2, nu3, cavg;
GetNums();
CalcAvg();
DspAvg();
}
static void GetNums()
{
Console.Write("Please enter nu1: ");
nu1 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu2: ");
nu2 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu3: ");
nu3 = int.Parse(Console.ReadLine());
CalcAvg(DspAvg);
}
static void CalcAvg()
{
}
static void DspAvg()
{
}
}
}
You can't declare variables in one method and use them in another method. the second method doesn't know the variables in the first method.
As the specification said you need your GetNums() to have 3 parameters passed by out
static void GetNums(out decimal num1, out decimal num2, out decimal num3)
Start from here. If you need more help please let me know :)
Well, we won't do your homework for you, but I can give you a few pointers. Your Main should only call GetNums(). GetNums() should call CalcAvg() passing in the numbers read from the console not the DspAvg() function. Finally pass the returned value from CalcAvg() to DspAvg() to display the result to the console.
Start writing some code and if you are getting errors, then we will be able to help you more.
You are not using parameters as described in the assignment. Here is an example of using an out parameter with one method and sending it into another method and returning a value:
double parameter, result;
methodOne(out parameter);
result = methodTwo(parameter);
The methods:
static void methodOne(out double x) {
x = 42;
}
static double methodTwo(double x) {
return x;
}
That should get you started on how you need to modify your methods.
I will provide some suggestions, but this a very good introductory programming problem. I would very much recommend trying to solve this problem on your own as it uses basic programming concepts that you will use in the future.
Your variables nu1, nu2, nu3, and cavg should be double values. An int can not be used to store decimal values. (Note: to get a value with 2 decimal places, you should use the Math.Round method)
double nu1, nu2, nu3, cavg;
You seem to be stuck on how to pass paramaters to a method. For example, when you call the CalcAvg method in your main method, you should be passing the 3 values you read from the console into the method.
static void Main(string[] args){
CalcAvg(nu1,nu2,nu3);
}
static void CalcAvg(double nu1, double nu2, double nu3){
}
By doing this, you can now manipulate the values within your CalcAvg method.
Finally, once you have passed values into a method and manipulated them, you will want to return these values from the method. This can be done with the return statement. You can then call this method by passing in your paramaters and storing the returned value in another variable.
static void Main(string[] args){
double cavg;
cavg = CalcAvg(nu1,nu2,nu3);
}
static double CalcAvg(double nu1, double nu2, double nu3){
double cavg;
return cavg;
}
These three principles should help you complete this assignment. I STRONGLY recommend you do this assignment on your own and not copy the complete answer off of this or any other website. Learning these principles correctly will help you further down the road in your academic career. Good luck :)
I've made a few assumptions here. But I've gone ahead to give you a "working" app for you to consider
static void Main(string[] args)
{
int nu1, nu2, nu3, cavg;
GetNums(out nu1, out nu2, out nu3);
double average = CalcAvg(nu1, nu2, nu3);
DspAvg(average);
}
static void GetNums(out int nu1, out int nu2, out int nu3)
{
Console.Write("Please enter nu1: ");
nu1 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu2: ");
nu2 = int.Parse(Console.ReadLine());
Console.Write("Please enter nu3: ");
nu3 = int.Parse(Console.ReadLine());
}
static double CalcAvg(int nu1, int nu2, int nu3)
{
return (nu1 + nu2 + nu3) / 3;
}
static void DspAvg(double average)
{
Console.WriteLine(Math.Round(average, 2));
}

Method parameters with exception handling

I'm obviously a newbie when it comes to C# and the following program is from a Charles Petzold book that I don't fully understand. The parameter in the GetDouble method is a string named prompt. Nowhere is this declared and I think that's what's messing me up. I see that the Main method is calling GetDouble and is printing three strings to the console, but this whole thing looks weird to me. Is this typical programming design, or is this not industry standard, but for purposes of showing how things can be done? The book doesn't give an answer either way. My fledgling programming self wouldn't pass a string to the Main method. Can someone help straighten me out?
using System;
class InputDoubles
{
static void Main()
{
double dbase = GetDouble("Enter the base: ");
double exp = GetDouble("enter the exponent: ");
Console.WriteLine("{0} to the power of {1} is {2}", dbase, exp, Math.Pow(dbase, exp));
}
static double GetDouble(string prompt)
{
double value = Double.NaN;
do
{
Console.Write(prompt);
try
{
value = Double.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine();
Console.WriteLine("you enter an invalid number!");
Console.WriteLine("please try again");
Console.WriteLine();
}
}
while (Double.IsNaN(value));
return value;
}
}
Nowhere is this declared and I think that's what's messing me up.
Wait, it's declared right there - in the header of the method:
static double GetDouble(string prompt)
// ^^^^^^^^^^^^^ This is the declaration of prompt
prompt is different from other variables that you have seen in that it is not a normal variable: it is a formal parameter of a method.
Unlike regular variables which you initialize and assign explicitly with the assignment operator =, formal parameters are assigned implicitly by virtue of calling a method. When you call the method, you pass it an expression with the actual parameter, which acts as an assignment of that expression to the formal parameter. Imagine that the prompt variable is assigned "Enter the base: " before the first call, and then it is assigned "enter the exponent: " before the second call to understand what is going on when you call GetDouble.
The GetDouble(string) method does just that - it gets a double from the input.
The text that is prompted to the user is a parameter, because there are two different values to be entered: first the base number, second the exponent.
By making the prompt a parameter, the GetDouble(string) method can handle everything from prompting the user for input to returning the value.
The alternative would be to prompt the user outside of GetDouble(string). Which of these two options is preferable is a matter of taste.
Oh, and as you've probably figured by now, this has nothing to do with the exception handling in the method.
You can change it this way. It does the same but I think more understandable:
static void Main()
{
string messageForDbaseParam="Enter the base: ";
double dbase = GetDouble(messageForDbaseParam);
string messageForExpParam ="enter the exponent: ";
double exp = GetDouble(messageForExpParam);
Console.WriteLine("{0} to the power of {1} is {2}", dbase, exp, Math.Pow(dbase, exp));
}
static double GetDouble(string prompt)
{
double value = Double.NaN;
Boolean incorrectValue=true;
while(incorrectValue)
{
Console.Write(prompt);
try
{
value = Double.Parse(Console.ReadLine());
incorrectValue=false;
}
catch
{
Console.WriteLine("error");
}
}
return value;
}

C# Functions inside a button click for calculating distance

(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.

Categories

Resources