I want to create a Compound Interest Calculator in C# using two classes in different namespaces but can't for the life of me figure out why I keep getting errors.
PSA I am a beginner, I know this code probably looks awful, but please be kind.
Here is CompoundTest.cs
namespace CompoundTest
{
class Program
{
static void Main(string[] args)
{
CompoundClass newprogram = new CompoundClass();
Console.Write("\nPlease enter the initial balance for your account: ");
double balance = Convert.ToDouble(Console.ReadLine());
Console.Write("\nPlease enter the annual interest rate: ");
double interestRate = Convert.ToDouble(Console.ReadLine()) / 100;
Console.Write("\nHow many years will you acrue interest? ");
double annualAmount = Convert.ToDouble(Console.ReadLine());
Console.WriteLine($"Your balance after {annualAmount} years is {accountBalance:C}");
Console.ReadLine();
}
}
}
And here is Compound.cs
using System;
namespace Compound
{
public class CompoundClass
{
private double balance;
public int value { get; private set; }
public CompoundClass()
{
Balance = value;
}
public double Balance
{
get
{
return balance;
}
private set
{
if (value > 0)
{
balance = value;
}
}
}
public void Rate(double interestRate)
{
interestRate = value / 100;
}
public void Years(double annualAmount)
{
annualAmount = value * 12;
}
public void addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
accountBalance = balance * Math.Pow(1 + interestRate / annualAmount, annualAmount * i);
}
}
}
}
I get the error:
CS0103 C# The name '..' does not exist in the current context - in the public void addMethod(double accountBalance) method
You are not storing any data on the CompoundClass, the method
public void Rate(double interestRate)
{
interestRate = value / 100;
}
only operates on the input parameter interestrate inside the functions scope, after that the result of the calculation is lost
If you want to reuse a variable on the entire lifetime of the CompoundClass, then define it as a member variable like:
private double _interestRate
and change your function to
public void Rate()
{
_interestRate = value / 100;
}
and for the annualAmount as well
private double _annualAmount;
public void Years()
{
_annualAmount = value * 12;
}
and your calculation to
public double addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
accountBalance = balance * Math.Pow(1 + _interestRate / _annualAmount, _annualAmount * i);
}
return accountBalance;
}
There is more then one thing wrong with this code. And I am honestly not sure if I even got anything close to your problem yet.
using System;
namespace Compound
{
public class CompoundClass
{
private double balance;
public int value { get; private set; }
public CompoundClass()
{
//Balance with a big B is nowhere in context
Balance = value;
}
public double Balance
{
get
{
return balance;
}
private set
{
if (value > 0)
{
balance = value;
}
}
}
//As remarked by somebody else, this function does nothing. Without return or out parameter, interest rate will stay at nothing.
public void Rate(double interestRate)
{
interestRate = value / 100;
}
//The naming of this variable is bad. Did you mean "Amoung of Months"?
//Also as someone else pointed out, you do not return or otherwise persist this value
public void Years(double annualAmount)
{
annualAmount = value * 12;
}
//Method does not return anything.
//accountBalance is a local value and will not persist
public void addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
//Avoid putting that much stuff into 1 line. It really messes with your ability to debug
//1-2 operations + 1 assignment to a temporary variable per line
//Anything more and you will have serious issues debugging this
accountBalance = balance * Math.Pow(1 + interestRate / annualAmount, annualAmount * i);
}
}
}
}
Generally the variables this works with should be either purely parameters (wich means it should be a static class with static functions) or mostly class variables. You have both things mixed all over the place.
Related
I'm working on a small calculator program in Unity.
I only need the calculator to work with two numbers.
The feature I'm trying to implement:
After inputting the math operator, It should display the second number in the third index.
The issue:
Instead of Adding a second number, the first number is being overwritten if a different number is pressed on the keyboard.
Here's the script I've created:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Functions : MonoBehaviour
{
// Global Variable to display text on top panel
public Text panelText;
// Create a number variable
string num;
string num1;
string num2;
string mOpr;
string calNum;
string cbutton;
string opr;
bool isFirstNum;
// Start is called before the first frame update
void Start()
{
}
// A function with an int argument
public void NumberInputOne(string num)
{
num1 = num;
num2 = num;
if (panelText.text.Length < 1)
{
Debug.Log(num1);
panelText.text = num1;
isFirstNum = false;
}
else if (panelText.text.Length > 1 && panelText.text.Length < 3)
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
public void OperatorInput(string opr)
{
mOpr = opr;
if (panelText.text.Length > 0 && panelText.text.Length < 2)
{
panelText.text = num1 + mOpr;
}
}
// public void NumberInputTwo(int num)
//{
// ResNum2 = num;
// Debug.Log(ResNum2);
// if (panelText.text.Length > 1 && panelText.text.Length < 3)
// {
// panelText.text = ResNum1 + opr + ResNum2;
// }
// }
public void RestartCal(string cButton)
{
panelText.text = "";
}
}
I've also added a screen recording to capture the issue:
First number being overwritten
Do you have any suggestions?
Thank you
use the NumberInputOne func like below;
public void NumberInputOne(string num)
{
if (num1 is null)
{
Debug.Log(num1);
panelText.text = num1;
num1 = num
}
else
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
btw i recommend that you review the sample calculation application codes. because apart from what you're asking, there are places you need to improve in general.
This feels like a beginner programming exercise. But the right way to build a calculator involves programming concepts that you probably haven't been taught yet. Which makes this a poor choice as an assignment.
Personally I would build a calculator by defining a simple syntax tree to represent the formula being input. Including methods to display the formula and calculate the answer. For example;
public interface IValue
{
int Calculate();
string PrintValue();
}
public class Number : IValue
{
public int? Value;
public void AddDigit(int digit) => Value = (Value ?? 0) * 10 + digit;
public int Calculate() => Value ?? 0;
public string PrintValue() => Value?.ToString();
}
public abstract class BinaryOperator : IValue
{
public IValue Left;
public IValue Right;
public abstract int Operation(int left, int right);
public abstract char Operator { get; }
public int Calculate()
{
var left = Left.Calculate();
var right = Right.Calculate();
return Operation(left, right);
}
public string PrintValue() => $"{Left?.PrintValue()} {Operator} {Right?.PrintValue()}";
}
public class Addition : BinaryOperator
{
public override char Operator => '+';
public override int Operation(int left, int right) => left + right;
}
// TODO define other operators
Then think about how each button should change the syntax tree.
// the entire formula
public IValue Root;
// the number currently being typed
public Number Input;
public void Display() {
panelText.text = Root.PrintValue();
}
// start / clear
public void Start(){
Root = Input = new Number(){
Value = 0
};
Display();
}
public void Plus(){
// left as an exercise for the reader
Display();
}
public void Digit(int digit) {
Input.AddDigit(digit);
Display();
}
public void Calculate() {
// left as an exercise for the reader
Display();
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm having trouble and I was wondering if there is something wrong with my code.
The code should execute the following
When executed within the terminal the MoveAmount and Move should end up equal to each other.
Side A should follow the equation
(x*a)/(a+b) and execute with the correct value. (x representing the move and A and B representing their perspective ratio).
Move - SideA = Side B
Move = SideA + SideB
Unfortunately it doesn't seem to be working and I am unable to get the code to create the proper output.
If I try to input my values based on this graph the Calculated Movement of Side A and B return incorrectly and the output does not follow the desired perameters above.
If anyone can give me any tips let me know.
using System;
namespace Example
{
class CalculatedMove
{
public double Move = 0.0;
public double SideARatio = 0.0;
public double SideBRatio = 0.0;
public CalculatedMove(double SideARatio, double SideBRatio, double Move)
{
this.Move = Move;
this.SideARatio = SideARatio;
this.SideBRatio = SideBRatio;
}
public virtual void SideA()
{
double SideA = 0.0;
SideA = (Move * SideARatio) /(SideARatio + SideBRatio);
Console.WriteLine("Calculated Side A Movement is {00:00.0000}", SideA);
}
public void SideB()
{
double SideB = 0.0;
SideB = Move - SideARatio;
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
public void MovementAmount()
{
double MovementAmount = 0.0;
MovementAmount = SideARatio + SideBRatio;
Console.WriteLine("The Calculated Move Amount is {0:00.0000}", MovementAmount);
}
}
class Program
{
static void Main(string[] args)
{
double Move, SideARatio, SideBRatio = 0.0;
Console.WriteLine("Enter the Move Amount ");
Move = Double.Parse(Console.ReadLine());
Console.WriteLine("Side A Ratio");
SideARatio = Double.Parse(Console.ReadLine());
Console.WriteLine("Side B Ratio");
SideBRatio = Double.Parse(Console.ReadLine());
CalculatedMove objMove = new CalculatedMove(Move, SideARatio,SideBRatio);
objMove.SideA();
objMove.SideB();
objMove.MovementAmount();
Console.Read();
}
}
}
First of all, as JohnG said, the sequence of parameters is wrong when calling parameters.
Then when calculating SideB, SideARatio should not be subtracted, but SideA should be subtracted.
Finally, Move should be SideA+SideB, not SideARatio+SideBRatio.
using System;
namespace Example {
class CalculatedMove {
private double move =0.0;
public double Move {
get { return move; }
set { move=value; }
}
private double sideARatio=0.0;
public double SideARatio {
get { return sideARatio; }
set { sideARatio=value; }
}
private double sideBRatio = 0.0;
public double SideBRatio {
get { return sideBRatio; }
set { sideBRatio=value; }
}
private double sideA = 0.0;
public double SideA {
get { return sideA; }
set { sideA=value; }
}
private double sideB = 0.0;
public double SideB {
get { return sideB; }
set { sideB=value; }
}
private double movementAmount = 0.0;
public double MovementAmount {
get { return movementAmount; }
set { MovementAmount=value; }
}
public CalculatedMove(double SideARatio, double SideBRatio, double Move) {
this.move=Move;
this.sideARatio=SideARatio;
this.sideBRatio=SideBRatio;
}
public virtual void SideAMove() {
SideA=(Move*SideARatio)/(SideARatio+SideBRatio);
Console.WriteLine("Calculated Side A Movement is {00:00.0000}", SideA);
}
public void SideBMove() {
SideB=(Move*SideBRatio)/(SideARatio+SideBRatio);
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
public void MovementAmountMove() {
MovementAmount=SideA+SideB;
Console.WriteLine("The Calculated Move Amount is {0:00.0000}", MovementAmount);
}
}
class Program {
static void Main(string[] args) {
double Move, SideARatio, SideBRatio = 0.0;
Console.WriteLine("Enter the Move Amount ");
Move=Double.Parse(Console.ReadLine());
Console.WriteLine("Side A Ratio");
SideARatio=Double.Parse(Console.ReadLine());
Console.WriteLine("Side B Ratio");
SideBRatio=Double.Parse(Console.ReadLine());
CalculatedMove objMove = new CalculatedMove( SideARatio, SideBRatio,Move);
objMove.SideAMove();
objMove.SideBMove();
objMove.MovementAmountMove();
Console.Read();
}
}
}
Output:
As 3.Move - SideA = Side B :
public void SideB()
{
double SideB = 0.0;
SideB = Move - SideARatio; // Here is the problem;
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
Fix public void SideB()
public void SideB()
{
double SideB = 0.0;
SideB = (Move * SideBRatio) /(SideARatio + SideBRatio);
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
I cant figure out what to change. I have played with the void and int.
The problem is with the SlowDown and SpeedUp methods, and in the lines Car car1 = new Car("Ford", "Focus", 2010, car1Speed); The CS1729 is flagging the Car before the ("Ford", "Focus", 2010, car1Speed).
How do I fix these errors?
class Car
{
private int Speed;
private string Make;
private string Model;
private int Year;
public void Car1(string make, string model, int year, int speed)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = speed;
}
public void Car2(string make, string model, int year, int speed)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = 0;
}
public void SpeedUp()
{
Speed = Speed ++;
}
public void SlowDown()
{
Speed = Speed --;
}
public void Display()
{
Console.WriteLine(Year + " " + Make + " " + Model + " is going " + Speed + " MPH.");
}
public 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();
}
}
}
From what I gathered in your comments it seems this is one of those bad assignments where they teach you bad coding practices by providing poorly written code. This is disastrous practice that poisons the industry because bad habits don't come off easily. Here is the full code how it should be written and comments why it should be that way.
public class Car
{
// Member fields should be either "_camelCase" or "camelCase"
private string _make;
private string _model;
private int _year;
private int _speed;
// Don't duplicate the code, default value for speed makes it optional parameter.
// There is no need for a second constructor.
public Car(string make, string model, int year, int speed = 0)
{
_make = make;
_model = model;
_year = year;
_speed = speed;
}
public int SpeedUp()
{
// Increments speed and returns the value.
// Might as well be void without return since example doesn't use it anywhere.
return _speed++;
}
public int SlowDown()
{
// If speed is more than 1, decrement and then return the value
return _speed > 0 ? _speed-- : 0;
}
public void Display()
{
// String interpolations are much easier to read
Console.WriteLine($"{_year} {_make} {_model} is going {_speed} MPH.");
}
}
public class Program
{
// Main is entry point for your app, it doesn't belong in any type class like Car,
// because it's not relevant to it
private static void Main()
{
// Use descriptive names for variables, you already know one car is Ford and the
// other is Chevy so name them as such so you know which is which
// later in the code.
var fordCar = new Car("Ford", "Focus", 2010, 20);
var chevyCar = new Car("Chevy", "Cruze", 2018); // No speed parameter
// Ommited variables car1Speed, car2Speed. You shouldn't declare variables
// that serve no purpose and aren't even in use.
for (int i = 0; i < 60; i++)
{
if (i % 2 == 0)
{
// Returns int, but variable assignment ins't necessary to anything here
chevyCar.SpeedUp();
}
if (i % 3 == 0)
{
fordCar.SpeedUp();
}
if (i % 5 == 0)
{
fordCar.SlowDown();
chevyCar.SlowDown();
}
}
fordCar.Display();
chevyCar.Display();
}
}
Sounds like all you need is a single constructor with an optional parameter
class Car
{
public void Car(string make, string model, int year, int speed = 0)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = speed;
}
...
Additional Resources
Optional Arguments (C# Programming Guide)
Constructors (C# Programming Guide)
This is my first question. Please correct me if I have some mistake. THX
//Form.cs
Sweet sweet = new Sweet();
Donut donut = new Donut();
//classify the condition with int i;
if (i==0)
score.Text=sweet.TambahPoin().ToString();
else if (i==1)
score.Text=donut.DoublePoin().ToString();
This is the parent class
class Sweet
{
//field
int m_poin;
//properties
public int Poin
{
get{return m_poin;}
set
{
if (value < 0)
m_poin = 0;
else
m_poin = value;
}
}
//Method
public int TambahPoin()
{
Poin += 10;
return Poin;
}
}
I want to make a method that will double the TambahPoin() with condition it will add the score before.
if the initial Poin = 100 and then call TambahPoin() method will become 110 after that i want to call DoublePoin method so the score become 110+20=130.(I have tried with my own solution before but the score becomes 20 not 130)
You probably want something like this:
public int TambahPoin()
{
m_poin += 10;
return m_poin;
}
public int DoublePoin()
{
for (int i = 0; i < 2; i++)
{
TambahPoin();
}
return m_poin;
}
public int IncreasePoin()
{
if (m_poin == 100) TambahPoin();
DoublePoin();
return m_poin;
}
Inside the class you can work with private fields and is quicker because you are not calling get/set methods from properties.
Background
I'm working on a symmetric rounding class and I find that I'm stuck with regards to how to best find the number at position x that I will be rounding. I'm sure there is an efficient mathematical way to find the single digit and return it without having to resort to string parsing.
Problem
Suppose, I have the following (C#) psuedo-code:
var position = 3;
var value = 102.43587m;
// I want this no ↑ (that is 5)
protected static int FindNDigit(decimal value, int position)
{
// This snippet is what I am searching for
}
Also, it is worth noting that if my value is a whole number, I will need to return a zero for the result of FindNDigit.
Does anyone have any hints on how I should approach this problem? Is this something that is blaringly obvious that I'm missing?
(int)(value * Math.Pow(10, position)) % 10
How about:
(int)(double(value) * Math.Pow(10, position)) % 10
Basically you multiply by 10 ^ pos in order to move that digit to the one's place, and then you use the modulus operator % to divide out the rest of the number.
using System;
public static class DecimalExtensions
{
public static int DigitAtPosition(this decimal number, int position)
{
if (position <= 0)
{
throw new ArgumentException("Position must be positive.");
}
if (number < 0)
{
number = Math.Abs(number);
}
number -= Math.Floor(number);
if (number == 0)
{
return 0;
}
if (position == 1)
{
return (int)(number * 10);
}
return (number * 10).DigitAtPosition(position - 1);
}
}
Edit:
If you wish, you may separate the recursive call from the initial call, to remove the initial conditional checks during recursion:
using System;
public static class DecimalExtensions
{
public static int DigitAtPosition(this decimal number, int position)
{
if (position <= 0)
{
throw new ArgumentException("Position must be positive.");
}
if (number < 0)
{
number = Math.Abs(number);
}
return number.digitAtPosition(position);
}
static int digitAtPosition(this decimal sanitizedNumber, int validPosition)
{
sanitizedNumber -= Math.Floor(sanitizedNumber);
if (sanitizedNumber == 0)
{
return 0;
}
if (validPosition == 1)
{
return (int)(sanitizedNumber * 10);
}
return (sanitizedNumber * 10).digitAtPosition(validPosition - 1);
}
Here's a few tests:
using System;
using Xunit;
public class DecimalExtensionsTests
{
// digit positions
// 1234567890123456789012345678
const decimal number = .3216879846541681986310378765m;
[Fact]
public void Throws_ArgumentException_if_position_is_zero()
{
Assert.Throws<ArgumentException>(() => number.DigitAtPosition(0));
}
[Fact]
public void Throws_ArgumentException_if_position_is_negative()
{
Assert.Throws<ArgumentException>(() => number.DigitAtPosition(-5));
}
[Fact]
public void Works_for_1st_digit()
{
Assert.Equal(3, number.DigitAtPosition(1));
}
[Fact]
public void Works_for_28th_digit()
{
Assert.Equal(5, number.DigitAtPosition(28));
}
[Fact]
public void Works_for_negative_decimals()
{
const decimal negativeNumber = -number;
Assert.Equal(5, negativeNumber.DigitAtPosition(28));
}
[Fact]
public void Returns_zero_for_whole_numbers()
{
const decimal wholeNumber = decimal.MaxValue;
Assert.Equal(0, wholeNumber.DigitAtPosition(1));
}
[Fact]
public void Returns_zero_if_position_is_greater_than_the_number_of_decimal_digits()
{
Assert.Equal(0, number.DigitAtPosition(29));
}
[Fact]
public void Does_not_throw_if_number_is_max_decimal_value()
{
Assert.DoesNotThrow(() => decimal.MaxValue.DigitAtPosition(1));
}
[Fact]
public void Does_not_throw_if_number_is_min_decimal_value()
{
Assert.DoesNotThrow(() => decimal.MinValue.DigitAtPosition(1));
}
[Fact]
public void Does_not_throw_if_position_is_max_integer_value()
{
Assert.DoesNotThrow(() => number.DigitAtPosition(int.MaxValue));
}
}
Edited: Totally had the wrong and opposite answer here. I was calculating the position to the left of the decimal instead of the right. See the upvoted answers for the correct code.
I found this one here working:
public int ValueAtPosition(int value, int position)
{
var result = value / (int)Math.Pow(10, position);
result = result % 10;
return result;
}
And also this one to know the full value (i.e.: 111, position 3 = 100 , sorry I don't know the proper name):
public int FullValueAtPosition(int value, int position)
{
return this.ValueAtPosition(value, position) * (int)Math.Pow(10, position);
}
How about this:
protected static int FindNDigit(decimal value, int position)
{
var index = value.ToString().IndexOf(".");
position = position + index;
return (int)Char.GetNumericValue(value.ToString(), position);
}
None of the previous solutions worked for me, so here is a working one :
var result = value / Math.Pow(10, Math.Truncate((Math.Log10(value) + 1) - position));
return (int)(result % 10);