ButterFly21 0 Newbie Poster
#include "p2.h"
#include <iomanip>
#include <string>

using namespace std;



/*
 * Converts an amount measured in cups to milliliters.
 * 1 cup = 236.518538 milliliter
 *
 * cups - amount measured in cups
 *
 * returns amount in milliliters
 */
double convertCupstoMilliliter(double cups)
{
    //modify -1 below to be your new calculated value.
    return cups * 236.518538;
}

/*
 * Returns the percent change from the original to the desired servings.
 * The percent is expressed as a decimal. i.e.:
 *    1   = 100%
 *    0.5 =  50%
 *    1.5 = 150%
 * If either of the serving values is 0, a value of 1 serving is assumed.
 *
 * To calculate the number of servings, the following formula is used:
 *
* Desired Servings =
 *   | Desired Servings / Original Servings | - 0.1 *
 *   (1 - |  Original Servings / Desired Servings | )
 *
 * where | x | is the absolute value of x
 *

 * original - number of servings the recipe was designed for
 * desired - the number of servings wanted
 *
 * returns the % change that should apply to all of the ingredients.
 */
double changeServings(int original, int desired)
{
    //stops any division by 0
    if (original == 0)
    {
        original = 1;
    }
    if (desired == 0)
    {
        desired = 1;
    }
    //end check


    // get absolute value for  | Original Serving / Desired Servings  |
    double rate = original / (double)desired;
    if (rate < 0)
        rate = -rate;

    //modify -1 below to be your new calculated value.
     return (rate - 0.1 * (1 - (1/rate)));
}



//given an amt and a percent change, find the new amt
/*
 * Given the amount of a ingredient and the % change due to the
 * change in the number of servings, calculates the new amount.
 *
 * amt - original amount from the recipe
 * changeInServings - % to change amt
 *
 * returns corrected amount
 */
double convertAmtByServings(double amt, double changeInServings)
{
    //modify -1 below to be your new calculated value.
    return amt * (changeInServings);
}


//out the ingredient, and amounts
//35, 12.2c, 12.2ml
/* Outputs a single ingredient and its amounts in both cup and milliliter units.
 *
 * Data should be formatted to the following constraints:
 *
 * Value        Width   Decimal places      Alignment
 * --------------------------------------------------
 * ingredient   35      -                   left
 * amtInCups    12      2                   right
 * amtInML      12      2                   right
 *
 * Floating-point numbers are displayed with a fixed decimal place.
 *
 * Amounts have their units placed after them
 *  c for cups
 *  ml for milliliters
 *
 * output - output stream to send data to
 * ingredient - ingredient name
 * amtInCups - amount in cup units
 * amtInML - amount in milliliter units
 *
 */
void formatIngredientOutput(ostream &output, string ingredient, double amtInCups, double amtInML)
{
    output << setw(35) << left << ingredient;
    output.precision(2);
    output << setw(12) << fixed << right << amtInCups << "c";
    output << setw(12) << fixed << right << amtInML << "ml";
    output << endl;
}


/*
 * Processes a single line from the recipe.  Reads values from the input stream,
 * converts the values into the correct serving size and units, and writes the values
 * to the output stream.
 *
 * The function also returns the amount of the ingredient in the desired serving size (cups).
 * (This will be useful for calculating the total amount.)
 *
 * Ingredients are assumed to be an a single line (and may have spaces).
 * Amounts are also on a single line.  After reading in the amount, everything else on the line
 * should be ignored.
 *
 * inputStream - input data
 * outputStream - output
 * changeAmt - % of change between the original and desired serving sizes
 *
 * returns amount of ingredient in desired serving size (cups)
 */
double processIngredient(istream &inputStream, ostream &outputStream, double changeAmt)
{
    // read name
    string ingredients;
    getline(inputStream, ingredients);

    // read amount
    double val;
    inputStream >> val;
    inputStream.ignore(1000, '\n');
    val = convertAmtByServings(val, changeAmt);

    // output the result
    formatIngredientOutput(outputStream, ingredients, val, convertCupstoMilliliter(val));
    return val;
}

//5 ingredients
//track total amounts
/*
 * Converts a recipe in terms of serving size and units.  Also prints the
 * total amount of ingredients in the course.
 *
 * The original and desired amount of servings should be read in first
 * (in that order).  Everything on the line after the desired amount should
 * be ignored.
 *
 * The five lines of ingredients should be processed and a total printed.
 * The total should follow the same format as that of the ingredients. (See
 * formatIngredientOutput)
 *
 * inputStream - input data
 * outputStream - output
 */
void convertRecipe(istream &inputStream, ostream &outputStream)
{
    int org, desired;
    inputStream >> org >> desired;
    inputStream.ignore(1000, '\n');
    double changeAmt = changeServings(org, desired);
    double total = 0;

    for (int i = 0; i < 5; i++)
    {
        total += processIngredient(inputStream, outputStream, changeAmt);
    }
    formatIngredientOutput(outputStream, "Total:", total, convertCupstoMilliliter(total));
}