A C++ Program to calculate Income Tax

Do you have some suggestions for improvement. I have just written the half
of the program yet. Will continue the next half after suggestions for
improvement:

/* A program to find the Income Tax of an individual as per Indian Tax
Slabs:

Yearly Income slab (Rs.) Tax Rate (%)
Up to 1,50,000 NIL
Up to 1,80,000 (for women) NIL
Up to 2,25,000 NIL
(for resident individual of 65 years or above)

1,50,001 - 300,000 10
3,00,001 - 500,000 20
5,00,001 upwards 30

A surcharge of 10 per cent of the total tax liability is applicable where the total income exceeds Rs 1,000,000.
*
* DESIGN: 1st, we will write code to get information of the user
* 2nd, we calculate the Tax.
*
*
* VERSION 1.0
*
*/

/* a combination of long double and ULONG_MAX is a catch, because if you put "unsigned long int max_income" on Left hand side
and user inputs value larger then ULONG_MAX then program, automagically will convert (cast ?) the value to some lower value
to satify the Left Hand Side and that will make it behave strange in some ways, doing some information loss. So I used
the maximum I have got, long double.

Is this the correct solution ? .. I don't think so.. I don't want to print the income in e+06 format. It needs to be a number.
*/

std::cout << "1- Oldest man lived on this Earth was Jeanne Calment of France (1875-1997)\n"
<< "who died at age 122 years and 164 days\n\n"
<< "2- Minimum age of work is "
<< min_age_for_work
<< "\n\n"
<< "3- Nthign other than numbers is accepted\n\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}

Advertisements

I'm assuming that you're only doing real persons and not things like US
corporations or whatever the equivalent would be there.

class Person { // not a great name
// I leave what Money is to you, but floating types
// can be problematic for many uses of this kind.
Money income;
// I suspect it's much better to store a birthdate instead of
// an age.
Date birthdate;
// std::string doesn't strike me as a good choice for this
Sex sex;
..
..
..
};

>
> /* a combination of long double and ULONG_MAX is a catch, because if you put "unsigned long int max_income" on Left hand side
> and user inputs value larger then ULONG_MAX then program, automagically will convert (cast ?) the value to some lower value
> to satify the Left Hand Side and that will make it behave strange in some ways, doing some information loss. So I used
> the maximum I have got, long double.
>
> Is this the correct solution ? .. I don't think so.. I don't want to print the income in e+06 format. It needs to be a number.
> */
>

(I put all that on multiple lines to avoid wrapping problems.)
I'm not commenting here on the logic of your i/o, but on the issue of
defining constants and when to use them. You know what the min and max
values are, you should let your users know too. Similarly for sex below.
std::cout << "Don't play games. "
<< "Enter a valid figure, between "
<< min_income
<< " and "
<< max_income
<< "." << std::end;

> }
> }
>
>
>
> /* get age of the user, I have made sure it can handle stupid users */
> void get_payee_age( int& age )
> {

Or
int get_payee_age() { ...

I think that naming a variable this way is not a good idea. It is
amusing though.
> const int calments_age = 122;

I suspect that the message below will require maintenance. Useful
programs spend most of their time in maintenance, it's not generally a
good idea to do something that will add to that. Sadly, I suspect that
my name will not appear in the message below, but it's likely, if your
program is useful, that eventually someone else's name will.

If the constants should ever change, then it's easier to not have to
change the messages too.
std::cout << "Please enter whether you are a " << m << " or a "
<< w << " (only in small letters please): ";

Advertisements

> On Mon, 05 Jan 2009 12:16:13 -0500, LR wrote:
> I'm assuming that you're only doing real persons and not things like US
> corporations or whatever the equivalent would be there.

Right, for general middle class Indian. Thats why I wanted to stick with
the values less than long integer, as five digits is the rare maximum of
what an Indian middle class man gets.

> class Person { // not a great name
> // I leave what Money is to you, but floating types
> // can be problematic for many uses of this kind.
> Money income;
> // I suspect it's much better to store a birthdate instead of
> // an age.
> Date birthdate;
> // std::string doesn't strike me as a good choice for this
> Sex sex;

I really wonder why you bring out the Class here, if I do it by the
procedural Style, will it be fine or using Class gives me some advantage ?

2nd, If I use date of birth, not age, then I have to add some more lines
of code, first to fetch the original value like Jan 24th, 1980 and then
converting it to integer (1980 in our case), it will add one more function
(or member function) increasing the complexity of the code.

> Consider making a ctor, or a function that returns a Person

you mean a constructor (ctor) ?

I have never ever done any OOP, heck I even don't know how to write a
class, I learned C++ first and then C but these days all I am *able* to
think is of procedures/functions and not of std::istream or <template>.
Seems like as if I never learned them

okay, I will learn how to write a template but first how to even read one.
this will be the first template of my life

> Wasn't Jeanne Calment of France a woman?

Eh.. my mistake. I got some very strange information about her from
Wikipedia: At age 85, she took up fencing, and at 100, she was still
riding a bicycle. She gave up smoking only five years before her death. On
the top of that she lived on her own till she was 110 years of age.

arnuld wrote:
>> On Mon, 05 Jan 2009 12:16:13 -0500, LR wrote:
>
>> I'm assuming that you're only doing real persons and not things like US
>> corporations or whatever the equivalent would be there.
>
> Right, for general middle class Indian. Thats why I wanted to stick with
> the values less than long integer, as five digits is the rare maximum of
> what an Indian middle class man gets.

But someone might use your code who doesn't fit in this category,
perhaps even to calculate the tax owed by someone else, an employee
perhaps. Or someone might like your code so much they'll want you to
rewrite it to handle corporations or limited partnerships or whatnot. Be
prepared.

But maybe you're right. Get the simpler case to work first, and then
build on it.

>> class Person { // not a great name
>> // I leave what Money is to you, but floating types
>> // can be problematic for many uses of this kind.
>> Money income;
>> // I suspect it's much better to store a birthdate instead of
>> // an age.
>> Date birthdate;
>> // std::string doesn't strike me as a good choice for this
>> Sex sex;
>
> I really wonder why you bring out the Class here, if I do it by the
> procedural Style, will it be fine or using Class gives me some advantage ?

Of course you can write your code with out classes. But IMHO easier to
write this with classes. At the very least makes it easier to pass the
data around.
>
> 2nd, If I use date of birth, not age, then I have to add some more lines
> of code, first to fetch the original value like Jan 24th, 1980 and then
> converting it to integer (1980 in our case), it will add one more function
> (or member function) increasing the complexity of the code.

I don't know how taxation works in India. But I'll make some
assumptions. Consider your user, you ask their age, they enter it, and
you do the taxes. But they may not remember that they're entering the
wrong age for the year they were interested in. Suppose they want to
calculate their taxes for fiscal 1998, or 2014? I think it's much nicer
for the computer to do that work.

>> Consider making a ctor, or a function that returns a Person
>
> you mean a constructor (ctor) ?

Yes.
>
> I have never ever done any OOP, heck I even don't know how to write a
> class, I learned C++ first and then C but these days all I am *able* to
> think is of procedures/functions and not of std::istream or <template>.
> Seems like as if I never learned them

No time like the present. It's easier to get started then you think.
You don't have to worry too much about getting everything all at once,
and I think this type of problem offers a nice trade off, not too easy,
not too complicated.

Go ahead. Just write one little class.

>> Why not just make these double?
>> const long double min_income = 0.0;
>> const long double max_income =
>> std::numeric_limits<long double>::max();
>
> actually using double (or long double) prints income in e+ format which is
> not what I want. A readable number is desired like 213476.

Then print them that way. You can control the format. Look up the
<iomanip> and <ios> headers and for things like std::setprecision and
std::fixed etc.

But creating a Money class might help with this. You may want to look
at the <locale> header for info on things like punctuation and io. But
if that's too much, then even just making a simple class like:

will be useful. But be careful if you need to calculate paise. Those
doubles can be pretty tricky. OTOH, if you decide that double isn't what
you want, then changing the type of amount to something else shouldn't
be too hard. Easier than going through all of your code and changing
individual variables.

Just consider yourself lucky that you're not doing this for rupees,
annas and pice.

>> I think this loop is hard to read.
>
> it is ..

IMO, writing code is a communicative art. Even if you're just writing
it for yourself. Names of variables and constants should communicate
what their purpose is. Things like conditions in loops should be easy
to read and understand. Someone, maybe you, will have to maintain your
code, striving for readability isn't a bad idea.

>> consider implementing two template functions,
>>
>> template<typename T>
>> bool isInInclusiveRange(const T &low, const T &value, const T &high) {
>> // maybe better to write these with only the < operator return low
>> <= value && value <= high;
>> }
>> }
>> and a similar one for isInExclusiveRange
>
>
> okay, I will learn how to write a template but first how to even read one.
> this will be the first template of my life

If this is your first template, then write this function first, again I
formatted things this way to avoid line wrapping (untested):

/* This function can not handle a little larger inputs. It goes into
an infinite loop
for larger values like 1234567890123. Can we fix it ? */
Income get_payee_income()
{
Income x;
const long int min_income = 0;
const long int max_income = LONG_MAX ; /* using
std::numeric_limits<int>::max; gives error */

The name is misleading, too. With "if_*", you except it to do something
with side-effects. A function that only checks and returns a bool would
be better named is_in_range.
> Income get_payee_income();
> Age get_payee_age();
> Sex get_payee_sex();
>
>
>
> class Person
> {
> Income income;
> Age age;
> Sex sex;
>
> public:
> Person(); /* This is constructor declaration, we will define it
> later, don't put code of functions into the class */
> /* ~Person(); don't know whow to write a destructor yet */

Make tax() and person() free functions.
If they diplay information, it should be included in their name and they
should take the stream to use in parameter (for parametrization from above):
display_tax(ostream& os);
display_information(ostream& os);

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!