2
votes

I wrote some code to take in five Social Security Numbers, five gross income entries, and calculate tax for each one. The program will use default values for dollar limit, low rate, and high rate to calculate tax owed. But it will also let user to choose if he/she wants to use their own dollar limit, low rate, and high rate to calculate tax owed for a chosen taxpayer.

Problem: Whenever I enter my own dollar limit, low rate, and high rate to calculate tax owed it still uses default values (limit = 30000, low rate = .15 and high rate = .28). And that's how a get the wrong calculated tax owed values.

Question. Could it be because my "public static void GetRates(int income)" doesn't have a return type (it is void)? Should I be returning a value back to main after I call "Taxpayer.GetRates(taxPayer[x].grossIncome);" method?

Part of the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace assignment
{
    public class Rates
    {
        public int incomeLimit; // income limit
        public double lowTaxRate; // low tax rate
        public double highTaxRate; // high tax rate

        public int IncomeLimit // read only property
        {
            get
            {
                return incomeLimit;
            }
        }
        public double LowTaxRate // read only property
        {
            get
            {
                return lowTaxRate;
            }
        }
        public double HighTaxRate // read only property
        {
            get
            {
                return highTaxRate;
            }
        }

        public Rates()
        {
            DoRates();
        }

        public void DoRates() // class constructor that assigns default values 
        {
            // set default values for limit, lowRate, and highRate
            incomeLimit = 30000;
            lowTaxRate = .15;
            highTaxRate = .28;
        }

        public void DoRates(int limit, double lowRate, double highRate) // class constructor that takes three parameters
        {
            incomeLimit = limit; 
            lowTaxRate = lowRate;
            highTaxRate = highRate;
        }
        // CalculateTax method that takes an income parameter and computes the tax
        public int CalculateTax(int income)
        {
            int taxOwed = 0;

            if (income < incomeLimit)
            {
                taxOwed = Convert.ToInt32(income * lowTaxRate);

            }
            if (income >= incomeLimit)
            {
                taxOwed = Convert.ToInt32(income * highTaxRate);

            }
            return taxOwed;
        }  
    }
    public class Taxpayer : IComparable
    {
        string socialSecurityNum;
        int grossIncome;
        int taxOwed;

        // Use get and set accessors.
        public string SocialSecurityNum
        {
            get
            {
                return socialSecurityNum;
            }
            set
            {
                socialSecurityNum = value;
            }
        }
        // Use get and set accessors.
        public int GrossIncome
        {
            get
            {
                return grossIncome;
            }
            set
            {
                grossIncome = value;
            }
        }
        //  Use read-only accessor
        public int TaxOwed
        {
            get
            {
                return taxOwed;
            }
        }
        // objects are comparable to each other based on tax owed.
        int IComparable.CompareTo(Object o)
        {
            int returnVal;
            Taxpayer temp = (Taxpayer)o;
            if (this.taxOwed > temp.TaxOwed)
                returnVal = 1;
            else
                if (this.taxOwed < temp.TaxOwed)
                    returnVal = -1;
                else
                    returnVal = 0;
            return returnVal;
        }

        public static void GetRates(int income)
        {

            int incomeLimit;
            double lowRate;
            double highRate;

            char input;
            Rates rates = new Rates();

            Console.Write("Do you want default values (enter D) or enter your own (enter O)? ");
            input = Convert.ToChar(Console.ReadLine());


            switch (char.ToUpper(input)) // start switch
            {        
                case 'D': // if the input latter is d or a D
                    rates.DoRates();
                    break;
                case 'O': // if the input latter is o or an O
                    Console.Write("Enter the dollar limit ");
                    incomeLimit = Convert.ToInt32(Console.ReadLine());

                    Console.Write("Enter the low rate ");
                    lowRate = Convert.ToDouble(Console.ReadLine());

                    Console.Write("Enter the high rate ");
                    highRate = Convert.ToDouble(Console.ReadLine());

                    rates.DoRates(incomeLimit, lowRate, highRate);
                    rates.CalculateTax(income);
                    break;
                default: Console.WriteLine("You entered and incorrect option"); // display this messages if the input was something other than D or O
                    break;
            }


        }

        public static void Main()
        {
            // instantiate an array of five (5) Taxpayer objects.
            Taxpayer[] taxPayer = new Taxpayer[5];
            Rates taxRates = new Rates();

            // Implement a for-loop that will prompt the user 
            // to enter the Social Security Number and gross income.
            for (int x = 0; x < taxPayer.Length; ++x)
            {

                taxPayer[x] = new Taxpayer();
                Console.Write("Enter Social Security Number for taxpayer {0} ", x + 1);
                taxPayer[x].socialSecurityNum = Convert.ToString(Console.ReadLine());


                Console.Write("Enter gross income for taxpayer {0} ", x + 1);
                taxPayer[x].grossIncome = Convert.ToInt32(Console.ReadLine());

                Taxpayer.GetRates(taxPayer[x].grossIncome);


                taxPayer[x].taxOwed = taxRates.CalculateTax(taxPayer[x].grossIncome);

            }

Thank you for the help everyone. I think I did get carried away a little while writing this code. After isolating the code with my issue I finally figured it out. Here is what I did in case anyone wants to see.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace assignment
{
    public class Rates
    {
        public int incomeLimit; // income limit
        public double lowTaxRate; // low tax rate
        public double highTaxRate; // high tax rate

        public int IncomeLimit { get { return incomeLimit; } }// read only property
        public double LowTaxRate { get { return lowTaxRate; } } // read only property
        public double HighTaxRate { get { return highTaxRate; } }// read only property

        public Rates()
        {
            incomeLimit = 30000;
            lowTaxRate = .15;
            highTaxRate = .28;
        }

        public Rates(int incomeLim, double lowRate, double highRate)
        {   
            incomeLimit = incomeLim;
            lowTaxRate = lowRate;
            highTaxRate = highRate;

        }

        // CalculateTax method that takes an income parameter and computes the tax
        public int CalculateTax(int income)
        {
            int taxOwed = 0;

            if (income < incomeLimit)
            {
                taxOwed = Convert.ToInt32(income * lowTaxRate);
            }
            if (income >= incomeLimit)
            {
                taxOwed = Convert.ToInt32(income * highTaxRate);
            }
            return taxOwed;
        }
    }
    public class Taxpayer
    {
        string socialSecurityNum = null;
        int grossIncome = 0;
        int taxOwed = 0;

        // Use get and set accessors.
        public string SocialSecurityNum { get {return socialSecurityNum;} set {socialSecurityNum = value;} }
        // Use get and set accessors.
        public int GrossIncome { get { return grossIncome; } set { grossIncome = value; } }
        //  Use read-only accessor
        public int TaxOwed { get { return taxOwed; } }

        public void GetRates(int income)
        {
            int incomeLimit = 0;
            double lowRate = 0;
            double highRate = 0;
            char input;

            Console.Write("Do you want default values (enter D) or enter your own (enter O)? ");
            input = Convert.ToChar(Console.ReadLine());


            switch (char.ToUpper(input)) // start switch
            {
                case 'D': // if the input latter is d or a D
                    Rates rates = new Rates();
                    taxOwed = rates.CalculateTax(income);
                    break;
                case 'O': // if the input latter is o or an O
                    Console.Write("Enter the dollar limit ");
                    incomeLimit = Convert.ToInt32(Console.ReadLine());
                    Console.Write("Enter the low rate ");
                    lowRate = Convert.ToDouble(Console.ReadLine());
                    Console.Write("Enter the high rate ");
                    highRate = Convert.ToDouble(Console.ReadLine());
                    Rates myrates = new Rates(incomeLimit, lowRate, highRate);
                    taxOwed = myrates.CalculateTax(income);
                    break;
                default: Console.WriteLine("You entered and incorrect option"); // display this messages if the input was something other than D or O
                    break;
            }

        }
        public static void Main()
        {
            Taxpayer[] taxPayer = new Taxpayer[5];
            Rates taxRates = new Rates();

            Taxpayer myTaxpayer = new Taxpayer();
            // Implement a for-loop that will prompt the user 
            // to enter the Social Security Number and gross income.
            for (int x = 0; x < taxPayer.Length; ++x)
            {
                taxPayer[x] = new Taxpayer();
                Console.Write("Enter Social Security Number for taxpayer {0} ", x + 1);
                taxPayer[x].socialSecurityNum = Convert.ToString(Console.ReadLine());
                Console.Write("Enter gross income for taxpayer {0} ", x + 1);
                taxPayer[x].grossIncome = Convert.ToInt32(Console.ReadLine());
                myTaxpayer.GetRates(taxPayer[x].grossIncome);

                taxPayer[x].taxOwed = myTaxpayer.taxOwed;
            }
            // Implement a for-loop that will display each object 
            // as formatted taxpayer SSN, income and calculated tax.
            for (int y = 0; y < taxPayer.Length; ++y)
            {
                Console.WriteLine("Taxpayer # {0} SSN: {1} income {2:C} Tax is {3:C}", y + 1, taxPayer[y].socialSecurityNum,
                    taxPayer[y].grossIncome, taxPayer[y].taxOwed);
            }
        }
    }
}
2
How do expect it to change, given that you're never changing it? - SLaks
This is a really good first attempt at a question. That is a ton of code though. Can you narrow it down at all? You also have some bad practice, such as public fields (even weirder when you then expose them as read-only properties). - BradleyDotNET
Good question! Upvote and help (if you still need it, that is) follows, as soon as you replace your block of code with a minimal complete example. - Heinzi
Ok, Thanks guys. I'll rewrite it an make it shorter. - user4409056
Also tax is rarely calculated like this as it would mean that (using your default values as an example) a person on 35000 would have a much lower take home pay once tax has been deducted than a person on 30000 i.e. 25200 (35000-9800) vs 25500 (30000-4500). What normally happens is that only the money over the limit is taxed at a higher the tax rate and the money under the limit is taxed at the original rate e.g. 35000 - (30000 * .15) - (5000 * .28) = 29100 -which makes far more sense. - Shaun Wilde

2 Answers

1
votes

I'll recommend to you to change your code, a more clean code and using betters OOP techniques.

You should check the class Taxpayer, specifically the method called GetRates().

in that method you create a object of type Rates, now, if you check the constructor of the class Rates

public Rates()
    {
        DoRates();
    }

it calls the method Dorates() but without parameters, so, it will always call these DoRates method

public void DoRates() // class constructor that assigns default values 
    {
        // set default values for limit, lowRate, and highRate
        incomeLimit = 30000;
        lowTaxRate = .15;
        highTaxRate = .28;
    }
0
votes

I'm surprised your compiler didn't complain. In Taxpayer.GetRates(int) you make a call to Rates.CalculateTax(int), which returns an int value. It doesn't get stored or returned anywhere, so I'm not sure what the purpose of the call is there. Also, since the object rates is attached to the static method GetRates(int), you're not changing any values in the object taxratesthat you use to calculate the tax. Finally, as has been suggested, your constructor sets default values. You could potentially add another constructor to take parameters. From there, you might want to make sure you change the values in the object you're using to calculate tax.

Occam's razor: keep it simple stupid. I think you're getting carried away with OOP. Simplify some things to make it work.