How to solve the following method issue in c# - c#

I have this in my main:
static void Main(string[] args)
{
Money m1 = new Money(2315.99);
Money m2 = new Money(4000, 25);
Console.WriteLine(m1);
Console.WriteLine(m2);
Console.WriteLine(m1.IncrementMoney(m2));
}
public void IncrementMoney(Money x)
{
//what do I put in here?
}
So
Money m1 = new Money(2315.99); is supposed to turn 2315.99 into "$2315.99"
and
Money m2 = new Money(4000, 25); forms "$4000.25"
I have all that done in Money class and it works fine.
Now what I'm supposed to do is add those two together using
m1.IncrementMoney(m2);
This is my "Money" class
class Money
{
//instance variables
private int dollars;
private int cents;
double amount;
public int Dollars
{
get { return dollars; }
set
{
if (value > 0)
dollars = value;
}
}
public int Cents
{
get { return cents; }
set
{
if (value > 0)
cents = value;
}
}
public Money(int Dol, int Cen)
{
Dollars = Dol;
Cents = Cen;
double Dollar = Convert.ToDouble(Dollars);
double Cent = Convert.ToDouble(Cents);
amount = Dollar + (Cent / 100);
}
public Money(double am)
{
int dol = Convert.ToInt32(am);
if (dol > am)
Dollars = dol - 1;
else if (dol < am)
Dollars = dol;
//Dollars
double cen = am % 1;
cen = cen * 100;
Cents = Convert.ToInt32(cen);
//Cents
double Dollar = Convert.ToDouble(Dollars);
double Cent = Convert.ToDouble(Cents);
amount = Dollar + (Cent / 100);
}
//override ToString()
public override string ToString()
{
return string.Format("{0:c}", amount);
}
}//end class Money
But I have no idea what to put into the IncrementMoney method. Please help?
and if not too much trouble, maybe a little insight to how it works? I'd really like to know.
Sorry if I didn't give enough info,
If anything else is required please let me know.
and thanks!

Since IncrementMoney is supposed to add the two money values together, your usage looks like it should instead be an extension method of the Money type. Which is fine, because extension methods are pretty awesome. A common joke on this site is that they're the solution to everything.
Your code should look similar to:
public static Money IncrementMoney(this Money x, Money y)
{
var totalCents = x.Cents + y.Cents;
var retCents = totalCents / 100;
var retDollars = x.Dollars + y.Dollars + (totalCents % 100)
return new Money(retDollars, retCents);
}
As for a quick explanation...
By adding this to the first argument, we are telling C# that we want to write an extension method. This will mean that this method we're writing will hang off the type of the this argument (in this case, Money) and allow us to use it exactly like it was always in the .NET framework. Extension methods have to be static, so you can't not use that modifier. Beyond that, you just write a method to do whatever you have in mind, exactly like you normally would!
I would suggest you name it something other than IncrementMoney, though. That's not very descriptive. AddMoney would be better.
You may also look into operator overloading, by the way. You could adapt what I just wrote to simply use the + operator to do exactly the same thing, like so:
public static Money operator +(Money x, Money y)
{
var totalCents = x.Cents + y.Cents;
var retCents = totalCents / 100;
var retDollars = x.Dollars + y.Dollars + (totalCents % 100)
return new Money(retDollars, retCents);
}
With this defined, you can simply go m1 + m2 and add them together.

public void IncrementMoney(Money x)
{
this.Dollars += x.Dollars;
var newCents = this.Cents + x.Cents;
this.Cents = newCents % 100;
this.Dollars += newCents / 100;
}
And I would actually name the function Add since you are taking the current value and adding the provided value, and no need for the Money modifier as it should be on the Money class and takes a Money object

Well first of all this line:
Console.WriteLine(m1.IncrementMoney(m2));
indicates that IncrementMoney should return something, but right now it returns void.
So it looks like it should be something like:
public void IncrementMoney(ClassA x)
{
this.Value += x.Value;
}
And then display it with:
ClassA m1 = new ClassA(2315.99);
ClassA m2 = new ClassA(4000, 25);
Console.WriteLine(m1);
Console.WriteLine(m2);
m1.IncrementMoney(m2);
Console.WriteLine(m1);

Related

Passing a value to a class keeps returning 0

this might be a simple/dumb question but I'm trying to figure out why my code keeps returning 0. I don't think my syntax for passing the value is correct but I cant figure out the proper way of doing it.
class ICESMARK
{
static int ICECount = 0;
public double average = 0;
public double[] ICES = new double[8];
public ICESMARK(double Mark)
{
Mark = ICES[ICECount];
if (ICECount == (ICES.Length - 1))
{
for (int x = 0; x < ICES.Length; x++)
{
average += ICES[x];
}
average /= ICES.Length;
}
ICECount++;
}
}
class Program
{
static void Main(string[] args)
{
ICESMARK[] ICE = new ICESMARK[8];
//LABSMARK[] LAB = new LABSMARK[6];
double userInput;
for (int counter = 0; counter < ICE.Length ; counter++)
{
Console.Write("Please enter your mark for ICE{0}: ", counter + 1 );
bool ifInt = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = new ICESMARK(userInput);
}
Console.WriteLine(ICE[1].average);
Console.ReadLine();
}
}
ICE[1].average - Displays 0
Also if anyone has a more efficient way of doing this, feel free to let me know. Except for the average, is gotta be a calculation, cant use the built in method.
Simplest code to get your work done:
void Main()
{
double[] ICE = new double[8];
double userInput = 0.0;
for (int counter = 0; counter < ICE.Length; counter++)
{
Console.WriteLine($"Please enter your mark for ICE {counter}: ");
bool isNumerical = false;
while(!isNumerical)
isNumerical = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = userInput;
}
Console.WriteLine("Average : " + ICE.Average());
Console.ReadLine();
}
How it works:
Removed all the frills, you don't need an extra class just for this purpose
Made it mandatory for code to enter valid double value to fill all the slots
Finally used Linq Average to calculate Average value
I want to clarify that yes there are easier ways to solve this, but the entire point of the project was to use a class and it specifically says I cant use built in methods such as "array.average".
Sorry that my code was super messy, I was honestly all over the place and very confused. Having that said I finally arrived to this solution. Thanks to everyone who tried to help! really appreciate it, some tips here were very helpful in solving and cleaning up my code.
class ICESMARK
{
public static int ICECount = 0;
public static double average = 0;
public ICESMARK(double Mark)
{
average += Mark;
if (ICECount < 8) { ICECount++; }
if (ICECount == 8) { average /= ICECount;}
}
}
class Program
{
static void Main(string[] args)
{
ICESMARK[] ICE = new ICESMARK[8];
double userInput;
for (int counter = 0; counter < ICE.Length ; counter++)
{
Console.Write("Please enter your mark for ICE{0}: ", counter + 1 );
bool ifInt = double.TryParse(Console.ReadLine(), out userInput);
ICE[counter] = new ICESMARK(userInput);
Console.WriteLine(ICESMARK.ICECount);
}
Console.WriteLine(ICESMARK.average);
Console.WriteLine(ICESMARK.ICECount);
Console.ReadLine();
}
}

How to assign variable to the result of a method in C#

I'm new to the concept of methods in C#, and I am trying to wrap my head around solving this problem that uses methods to calculate compound interest. I am having a couple problems with the code itself, but the main concept I am struggling with is how to return the variable "double finalAmount" through the use of my methods CalculateCompoundInterest (both variations). Here is my code so far:
using System;
namespace CompoundInterestCalculator
{
public class CompoundCalculator
{
const int EXIT = 0;
const int CALCULATE_DAILY = 1;
const int CALCULATE_QUARTERLY = 2;
const int CALCULATE_VARIABLE = 3;
const int NUM_OPTIONS = 3;
public static void Main()
{
int menuOption;
WelcomeMessage();
do
{
DisplayMenu();
menuOption = ReadOption();
if (menuOption != EXIT)
{
double finalAmount = CalculateInterest(menuOption);
OutputResult(finalAmount);
}
} while (menuOption != EXIT);
ExitProgram();
} // end Main
// Fill in the appropriate modifier and return type (_ _) in the method declaration
public static void WelcomeMessage()
{
Console.WriteLine("\n\n\tCompound Interest Calculator\n");
} // end WelcomeMessage
// Fill in the appropriate modifier and return type (_ _) in the method declaration
public static void ExitProgram()
{
Console.Write("\n\nPress enter to exit.");
Console.ReadLine();
} // end ExitProgram
static void DisplayMenu()
{
string menu = "\n\n1) Calculate final amount after interest (compounded daily)"
+ "\n2) Calculate final amount after interest (compounded quarterly)"
+ "\n3) Calculate final amount after interest (define number of times compounded yearly)"
+ "\n\nEnter your option(1-3 or 0 to exit): ";
Console.Write(menu);
} // end DisplayMenu
public static void OutputResult(double finalAmount)
{
// Display the message "The final amount of money plus interest is: $(amount)"
// The amount should display as currency, with two decimal places, e.g. $10,000.00
Console.WriteLine("The final amount of money plus interest is: ${0.2}", finalAmount);
} // end OutputResult
static int ReadOption()
{
string choice;
int option;
bool okayChoice;
do
{
choice = Console.ReadLine();
okayChoice = int.TryParse(choice, out option);
if (!okayChoice || option < 0 || option > NUM_OPTIONS)
{
okayChoice = false;
Console.WriteLine("You did not enter a correct option.\n\n Please try again");
DisplayMenu();
}
} while (!okayChoice);
return option;
} // end ReadOption
public static double CalculateInterest(int menuOption)
{
// (For this exercise, we will assume the user is inputting correct input.)
double principal;
double interestRate;
int numYears;
double finalAmount;
Console.Write("Enter the principal amount: ");
principal = Double.Parse(Console.ReadLine());
Console.Write("Enter the interest rate: ");
interestRate = Double.Parse(Console.ReadLine());
Console.Write("Enter the number of years that interest is accumulated for: ");
numYears = Int32.Parse(Console.ReadLine());
if (menuOption == CALCULATE_DAILY || menuOption == CALCULATE_QUARTERLY)
{
if (menuOption == CALCULATE_DAILY)
{
// Call the appropriate CalculateCompoundInterest method
CalculateCompoundInterest( principal, interestRate, numYears);
}
else
{
// Call the appropriate CalculateCompoundInterest method
CalculateCompoundInterest( principal, interestRate, numYears, 4);
}
}
else
{
Console.Write("Enter the number of times the interest is compounded yearly: ");
int numTimesCompounded = Int32.Parse(Console.ReadLine());
// Call the appropriate CalculateCompoundInterest method
CalculateCompoundInterest( principal, interestRate, numYears, numTimesCompounded);
}
Console.WriteLine();
// return the amount calculated by the compound interest method
return finalAmount;
} // End CalculateInterest
// Declare and implement the method CalculateCompoundInterest whose parameters are the principal, interest rate, and number of years (in that order)- make sure it is public!
// For the declaration select an appropriate modifier, return type, and types for the parameters
// This version assumes the interest is compounded daily (365 times a year)
// For both methods, you should assume the interest rate is input already in decimal form (i.e. 0.02 rather than 2 for a 2% rate)
public static double CalculateCompoundInterest(double principal, double interestRate, int numYears )
{
double compoundInterest;
compoundInterest = principal * Math.Pow(1 + interestRate / numYears, 1);
return compoundInterest;
}
// Declare and implement the method CalculateCompoundInterest whose parameters are the principal, interest rate, number of years, and number of times compounded yearly - make sure it is public!
// For the declaration select an appropriate modifier, return type, and types for the parameters
// This version allows the number of times compounded yearly to be specified.
public static double CalculateCompoundInterest(double principal, double interestRate, int numYears, int numTimesCompounded)
{
double compoundInterest;
compoundInterest = principal * Math.Pow(1 + interestRate / numYears, numTimesCompounded);
return compoundInterest;
}
}//end class
}//end namespace
Basically I am trying to figure out how to obtain results from methods, and how to use them in other methods (e.g. for value/parameter arithmetic). Feel free to let me know if you think there is something else that is wrong with the purpose of the program (to calculate compound interest). Also let me know if this is inappropriate for Stack Overflow, I am new to the website. Thanks guys.
I 'think' this is what you are looking for
var interest = CalculateCompoundInterest( principal, interestRate, numYears, 4);
edit
Additionally you may want to refactor the following 2 methods into 1 method. Hint - optional parameters
public static double CalculateCompoundInterest(double principal, double interestRate, int numYears )
{
double compoundInterest;
compoundInterest = principal * Math.Pow(1 + interestRate / numYears, 1);
return compoundInterest;
}
public static double CalculateCompoundInterest(double principal, double interestRate, int numYears, int numTimesCompounded)
{
double compoundInterest;
compoundInterest = principal * Math.Pow(1 + interestRate / numYears, numTimesCompounded);
return compoundInterest;
}
}

Need Help fixing incorrect output to console window.

I'm working on an assignment for school that consists of both a Program.cs file and a separate class called Car. I have written all code for the Car class and pasted already provided code into the program.cs file. The resulting output is
2010 Ford Focus is going 20 MPH.
2018 Chevy Cruze is going 0 MPH.
The assignment calls for an expected output of
2010 Ford Focus is going 28 MPH.
2018 Chevy Cruze is going 18 MPH.
I need to know how to get the window to output the expected speed of 28 for Car 1 and 18 for car 2. I'm assuming that I'm not supposed to alter the code that was provided for program.cs to accomplish the right output for the application/assignment.
public class Car
{
private int Speed;
private string Make;
private string Model;
private int Year;
public Car (string make, string model, int year, int speed)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = speed;
}
public Car(string make, string model, int year)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = 0;
}
public int SpeedUp()
{
this.Speed = Speed++;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed = Speed--;
}
return (Speed);
}
public void Display()
{
Console.WriteLine(Year + " " + Make + " " + Model + " is going " + Speed + " MPH.");
Convert.ToString(Console.ReadLine());
}
}
and here is the given code that goes in program.cs
class Program
{
static void Main(string[] args)
{
int car1Speed = 20;
int car2Speed = 0;
Car car1 = new Car("Ford", "Focus", 2010, car1Speed);
Car car2 = new Car("Chevy", "Cruze", 2018, car2Speed);
for (int i = 0; i < 60; i++)
{
if (i % 2 == 0)
{
car2Speed = car2.SpeedUp();
}
if (i % 3 == 0)
{
car1Speed = car1.SpeedUp();
}
if (i % 5 == 0)
{
car1Speed = car1.SlowDown();
car2Speed = car2.SlowDown();
}
}
car1.Display();
car2.Display();
}
}
The line of code
this.Speed = Speed++;
Has no effect on the value of this.Speed.
The line of code is roughly equivalent to
int temp = this.Speed; // We store the original value of Speed.
this.Speed = Speed + 1; // We add one to Speed and assign it back to Speed.
this.Speed = temp; // We immediately replace Speed with the original value of Speed.
This is the due to the behavior of the '++' operator which, when appended to the end of a variable will add 1 to its current value and then assigns the result back to the variable. This operator however temporarily stores the original value and uses that as the result of the expression. This temporary result of the ++ operator is ultimately what you are assigning to this.Speed due to the '=' operator you're using in the same expression, this in turn is what is causing the variable to not actually be modified.
The correct usage would be to simply call
Speed++;
This will perform the addition of 1 and assignment back to Speed, and also discard the temporary variable, as it is not being assigned anywhere.
This issue also exists in your SpeedDown method with the '--' operator.
In your Car.cs class, here is a better way to increment the speed without modifying the Program.cs file:
public int SpeedUp()
{
this.Speed += 1;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed -= 1;
}
return (Speed);
}
That produces the output that you're after.

operation overloading error in C#?

I am trying to write some operation overloading and assertion routine.
I have a struct named Degree, and following is my code;
public struct Degree
{
public float InnerValue;
public Degree(float value)
{
InnerValue = value;
}
public static Degree operator +(Degree a, Degree b)
{
return new Degree(a.InnerValue + b.InnerValue);
}
public static void UnitTest()
{
Random rd = new Random();
Degree lhs = rd.NextDegree(-(Degree)360, (Degree)360);
Degree rhs = rd.NextDegree(-(Degree)360, (Degree)360);
float f = rd.NextFloat(-100, 100);
float temp = lhs.InnerValue + rhs.InnerValue;
Debug.Assert((lhs + rhs).InnerValue == temp);
Debug.Assert((lhs + rhs).InnerValue == lhs.InnerValue + rhs.InnerValue);
}
}
my code seems looks very well for operator overloading, but assertion fails.
The problem is only second Assert fails.
I am unable to understand the reason for the same. Any help would be appreciated.

What does "Use of unassigned local variable" mean?

This question already has answers here:
Why did I get the compile error "Use of unassigned local variable"?
(10 answers)
Closed 4 days ago.
I keep getting this error for annualRate, monthlyCharge, and lateFee.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab_5___Danny_Curro
{
class Program
{
static void Main(string[] args)
{
string firstName;
string lastName;
int accNumber;
string creditPlan;
double balance;
string status;
Boolean late = false;
double lateFee;
double monthlyCharge;
double annualRate;
double netBalance;
Console.Write("Enter First Name: ");
firstName = Console.ReadLine();
Console.Write("Enter Last Name: ");
lastName = Console.ReadLine();
Console.Write("Enter Account Number: ");
accNumber = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Credit Card Plan Number[Blank Will Enter Plan 0]: ");
creditPlan = Console.ReadLine();
Console.Write("Enter Balance: ");
balance = Convert.ToDouble(Console.ReadLine());
Console.Write("Is This Account Late?: ");
status = Console.ReadLine().Trim().ToLower();
if (creditPlan == "0")
{
annualRate = 0.35; //35%
lateFee = 0.0;
monthlyCharge = balance * (annualRate * (1 / 12));
return;
}
if (creditPlan == "1")
{
annualRate = 0.30; //30%
if (status == "y")
{
late = true;
}
else if (status == "n")
{
late = false;
}
if (late == true)
{
lateFee = 25.00;
}
monthlyCharge = balance * (annualRate * (1 / 12));
return;
}
if (creditPlan == "2")
{
annualRate = 0.20; //20%
if (status == "y")
{
late = true;
}
else if (status == "n")
{
late = false;
}
if (late == true)
{
lateFee = 35.00;
}
if (balance > 100)
{
monthlyCharge = balance * (annualRate * (1 / 12));
}
else
{
monthlyCharge = 0;
}
return;
}
if (creditPlan == "3")
{
annualRate = 0.15; //15%
lateFee = 0.00;
if (balance > 500)
{
monthlyCharge = (balance - 500) * (annualRate * (1 / 12));
}
else
{
monthlyCharge = 0;
}
return;
}
netBalance = balance - (lateFee + monthlyCharge);
Console.WriteLine("Name: \t\t\t {0} {1}", firstName, lastName);
Console.WriteLine("Account Number: \t{0}", accNumber);
Console.WriteLine("Credit Plane: \t\t{0}",creditPlan);
Console.WriteLine("Account Late: \t\t{0}", late);
Console.WriteLine("Balance: \t\t{0}", balance);
Console.WriteLine("Late Fee: \t\t{0}", lateFee);
Console.WriteLine("Interest Charge: \t{0}", monthlyCharge);
Console.WriteLine("Net Balance: \t\t{0}",netBalance);
Console.WriteLine("Annual Rate: \t\t{0}", annualRate);
Console.ReadKey();
}
}
}
The compiler isn't smart enough to know that at least one of your if blocks will be executed. Therefore, it doesn't see that variables like annualRate will be assigned no matter what. Here's how you can make the compiler understand:
if (creditPlan == "0")
{
// ...
}
else if (creditPlan == "1")
{
// ...
}
else if (creditPlan == "2")
{
// ...
}
else
{
// ...
}
The compiler knows that with an if/else block, one of the blocks is guaranteed to be executed, and therefore if you're assigning the variable in all of the blocks, it won't give the compiler error.
By the way, you can also use a switch statement instead of ifs to maybe make your code cleaner.
Change your declarations to this:
double lateFee = 0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
The error is caused because there is at least one path through your code where these variables end up not getting set to anything.
Because if none of the if statements evaluate to true then the local variable will be unassigned. Throw an else statement in there and assign some values to those variables in case the if statements don't evaluate to true. Post back here if that doesn't make the error go away.
Your other option is to initialize the variables to some default value when you declare them at the beginning of your code.
Give them a default value:
double lateFee=0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
Basically, all possible paths don't initialize these variables.
Use the keyword "default"!!!
string myString = default;
double myDouble = default;
if(!String.IsNullOrEmpty(myString))
myDouble = 1.5;
return myDouble;
There are many paths through your code whereby your variables are not initialized, which is why the compiler complains.
Specifically, you are not validating the user input for creditPlan - if the user enters a value of anything else than "0","1","2" or "3", then none of the branches indicated will be executed (and creditPlan will not be defaulted to zero as per your user prompt).
As others have mentioned, the compiler error can be avoided by either a default initialization of all derived variables before the branches are checked, OR ensuring that at least one of the branches is executed (viz, mutual exclusivity of the branches, with a fall through else statement).
I would however like to point out other potential improvements:
Validate user input before you trust it for use in your code.
Model the parameters as a whole - there are several properties and calculations applicable to each plan.
Use more appropriate types for data. e.g. CreditPlan appears to have a finite domain and is better suited to an enumeration or Dictionary than a string. Financial data and percentages should always be modelled as decimal, not double to avoid rounding issues, and 'status' appears to be a boolean.
DRY up repetitive code. The calculation, monthlyCharge = balance * annualRate * (1/12)) is common to more than one branch. For maintenance reasons, do not duplicate this code.
Possibly more advanced, but note that Functions are now first class citizens of C#, so you can assign a function or lambda as a property, field or parameter!.
e.g. here is an alternative representation of your model:
// Keep all Credit Plan parameters together in a model
public class CreditPlan
{
public Func<decimal, decimal, decimal> MonthlyCharge { get; set; }
public decimal AnnualRate { get; set; }
public Func<bool, Decimal> LateFee { get; set; }
}
// DRY up repeated calculations
static private decimal StandardMonthlyCharge(decimal balance, decimal annualRate)
{
return balance * annualRate / 12;
}
public static Dictionary<int, CreditPlan> CreditPlans = new Dictionary<int, CreditPlan>
{
{ 0, new CreditPlan
{
AnnualRate = .35M,
LateFee = _ => 0.0M,
MonthlyCharge = StandardMonthlyCharge
}
},
{ 1, new CreditPlan
{
AnnualRate = .30M,
LateFee = late => late ? 0 : 25.0M,
MonthlyCharge = StandardMonthlyCharge
}
},
{ 2, new CreditPlan
{
AnnualRate = .20M,
LateFee = late => late ? 0 : 35.0M,
MonthlyCharge = (balance, annualRate) => balance > 100
? balance * annualRate / 12
: 0
}
},
{ 3, new CreditPlan
{
AnnualRate = .15M,
LateFee = _ => 0.0M,
MonthlyCharge = (balance, annualRate) => balance > 500
? (balance - 500) * annualRate / 12
: 0
}
}
};
Your assignments are all nested within your conditional if blocks which means that there is potential for them to never be assigned.
At the top of your class, initialise them to 0 or some other value
The compiler is saying that annualRate will not have a value if the CreditPlan is not recognised.
When creating the local variables ( annualRate, monthlyCharge, and lateFee) assign a default value (0) to them.
Also, you should display an error if the credit plan is unknown.
Not all code paths set a value for lateFee. You may want to set a default value for it at the top.
You don't assign values outside of the if statements ... and it is possible that credit might be something other than 0, 1, 2, or 3, as #iomaxx noted.
Try changing the separate if statements to a single if/else if/else if/else. Or assign default values up at the top.
If you declare the variable "annualRate" like
class Program
{
**static double annualRate;**
public static void Main() {
Try it..

Categories