[ create a new paste ] login | about

Link: http://codepad.org/4dqrfHMR    [ raw code | fork ]

kimiliini - C, pasted on Feb 21:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/* **************************************************************************
 *                                                                          *
 *                          Helper functions                                *
 *                                                                          *
 * **************************************************************************/
/*
 * Get confirmation by y for yes or n for no.
 * Prints title and loops until one of the two is given.
 * Return 1 for yes, and 0 for no.
 * */
static int confirm(char *title)
{
        char buf[10];

        fprintf(stdout, "%s (y or n) ", title);
        while (1) {
                fgets(buf, sizeof(buf), stdin);
                switch (*buf) {
                case 'y': case 'Y':
                        return 1;
                case 'n': case 'N':
                        return 0;
                }
                fprintf(stderr, "Please answer with y for Yes or n for No: ");
        }
}
/* Crude function for reading float from user input.
 * Prints title, can be empty string.
 * */
static float get_float(char *title) {
        char buf[80];

        fputs(title, stdout);
        fgets(buf, sizeof(buf), stdin);
        return atof(buf);
}
/* Function to read in and summarize floats.
 *
 * Read and add values until "n" is given as response on request for more.
 * We could have used "0" to denote end of input, and that would perhaps
 * also be more user friendly.
 * */
static float get_info_float(char *type)
{
        float amount, total = 0;

        fprintf(stdout, "\n -- %s --\n", type);
        do {
                amount = get_float("\n Enter amount: ");
                total += amount;
                fprintf(stdout, "\n Do you have any more %s? ", type);
        } while(confirm(""));

        return total;
}

/* **************************************************************************
 *                                                                          *
 *                         INCOME ADJUSTMENTS                               *
 *                                                                          *
 * **************************************************************************/

/*
 * An array for each filing type / status.
 * Each index correspond to an income group starting with index 0 for <= 6000
 * index 1 for <= 9000 etc.
 * */
const float adjust_SH[]  = { 0.000, 0.038, 0.074, 0.110, 0.138, 0.154, 0.350 };
const float adjust_S[]   = { 0.028, 0.075, 0.096, 0.135, 0.155, 0.174, 0.350 };
const float adjust_MJ[]  = { 0.000, 0.052, 0.083, 0.122, 0.146, 0.163, 0.350 };
const float adjust_MS[]  = { 0.023, 0.072, 0.089, 0.131, 0.152, 0.172, 0.350 };
/* Income groups
 * */
const int income_group[] = { 6000, 9000, 15000, 21000, 25000, 30000 };

/*
 * Use defines to make the code both more readable and maintainable.
 * */
#define STATUS_S        1
#define STATUS_MJ       2
#define STATUS_MS       3
#define STATUS_SH       4
/* Max and min STATUS_xx values. */
#define STATUS_MIN      1
#define STATUS_MAX      4
/* Length of income group array. */
#define INCOME_GR_LEN   6

/* Get income group based in income.
 * Return index which in turn correspond to index of adjust_xx arrays.
 * */
static int get_income_group(float income)
{
        int i;
        /* Here we could have used sizeof(income_group) / INT_SIZE
         * instead of having a constant INCOME_GR_LEN
         * but not sure if that is stretching the "new information"
         * to far.
         * */
        for (i = 0; i < INCOME_GR_LEN; ++i) {
                if (income <= income_group[i])
                        return i;
        }
        return i;
}
/*
 * Get status / type for account.
 * This function could also have been grouped with the other "get_data"
 * functions, but found it was better to leave it here.
 * */
static int get_status() {
        int status = 0;

        fputs(  "\n"
                " Status types:\n"
                "   1. Single Filing\n"
                "   2. Married Filing Jointly\n"
                "   3. Married Filing Separately\n"
                "   4. Single Head of Household Filing\n"
                "\n"
                ,
                stdout
        );

        do {
                status = (int)get_float("Enter Status type number: ");
        } while (status < STATUS_MIN && status > STATUS_MAX);

        return status;
}
/* Calculate adjusted income based on income - dep and status.
 * */
static float get_income_adjusted(
                float inc_dep,
                int status
) {
        float adjusted_income = 0;
        int inc_group;

        /* This should likely be fixed. */
        assert(inc_dep > 0);
        if (inc_dep < 0) {
                fprintf(stderr, "FAIL!\n");
                return 0.0;
        }

        inc_group    = get_income_group(inc_dep);

        switch (status) {
        case STATUS_SH:
                adjusted_income = inc_dep * adjust_SH[inc_group];
                break;
        case STATUS_S:
                adjusted_income = inc_dep * adjust_S[inc_group];
                break;
        case STATUS_MJ:
                adjusted_income = inc_dep * adjust_MJ[inc_group];
                break;
        case STATUS_MS:
                adjusted_income = inc_dep * adjust_MS[inc_group];
                break;
        }

        return adjusted_income;
}

/* **************************************************************************
 *                                                                          *
 *                         PRINT FUNCTIONS                                  *
 *                                                                          *
 * **************************************************************************/
/*
 * Print result of one filing.
 * */
static void print_result(
                float wages,
                float income_other,
                float interests,
                float dividends,
                float income_dep,
                float income_adj
) {
        int hdr_w = 29;

        fprintf(stdout,
                "\n\n"
                "-----------------------------------------------\n"
                "  %-*s: %.2f\n"
                "  %-*s: %.2f\n"
                "  %-*s: %.2f\n"
                "  %-*s: %.2f\n"
                "  %-*s: %.2f\n"
                "\n"
                "  %-*s: %.2f\n"
                "-----------------------------------------------\n"
                "\n"
                ,
                hdr_w, "YOUR WAGES", wages,
                hdr_w, "YOUR OTHER INCOME", income_other,
                hdr_w, "YOUR INTEREST", interests,
                hdr_w, "YOUR DIVIDEND", dividends,
                hdr_w, "YOUR INCOME AFTER DEPENDANTS", income_dep,
                hdr_w,
                (
                 income_adj < 0 ?
                 "Your income tax RETURN is" :
                 "Your income tax OWED is"
                ),
                income_adj
        );
}
/* Print final statistics at exit.
 * */
static void print_filing_stats(
              int files_s,
              int files_mj,
              int files_ms,
              int files_sh
) {
        int hdr_w = 44;

        fprintf(stdout,
                "%-*s: %i\n"
                "%-*s: %i\n"
                "%-*s: %i\n"
                "%-*s: %i\n"
                ,
                hdr_w, "Number of Singles Filing", files_s,
                hdr_w, "Number of Married Filing Jointly", files_mj,
                hdr_w, "Number of Married Filing Separately",files_ms,
                hdr_w, "Number of Single Head of Household Filing", files_sh
        );
}
/* **************************************************************************
 *                                                                          *
 *                          DATA PROCESSING                                 *
 *                                                                          *
 * **************************************************************************/
#define DEP_FACTOR       2800
int process_filing()
{
       float wages,
              income_other,
              interests,
              dividends,
              income_dep,
              income_adj,
              sum;
        int dependents,
            status;

        /* Get the various accounting posts. */
        wages           = get_info_float("Wages");
        income_other    = get_info_float("Other income");
        interests       = get_info_float("Interest");
        dividends       = get_info_float("Dividends");

        dependents      = DEP_FACTOR * (int)get_info_float("Dependents");

        /* Calculate income minus dependents */
        sum             = wages + income_other + interests + dividends;
        income_dep      = sum - dependents;

        /* Get status / file type from user */
        status = get_status();

        /* Get tax results. */
        income_adj = get_income_adjusted(
                        income_dep,
                        status
        );

        /* Print final data. */
        print_result(
                wages,
                income_other,
                interests,
                dividends,
                income_dep,
                income_adj
        );

        /* Return status / type for statistics in main(). */
        return status;
}


int main(void)
{
        int loop,
            filing,                     /* Temporary filing value. */
            filings[] = {0, 0, 0, 0};   /* Counter for filings. */

        loop = confirm("Should we start? ");

        while (loop) {
                /* Process one filing and set "filing" to status/type returned
                 * by process_filing().*/
                filing = process_filing();
                /* Increment index for statistics. */
                filings[filing] += 1;
                /* Keep asking for more */
                loop = confirm("Would you like to file another? ");
        }

        /* Print final statistics. */
        print_filing_stats(
                filings[0],
                filings[1],
                filings[2],
                filings[3]
        );

        /* Print message instead of only pausing, as that could be interpreted
         * as application hang / crash at exit. */
        fprintf(stderr, "\nPress enter to quit. ");
        getchar();

        return 0;
}


Create a new paste based on this one


Comments: