/* calculator.cpp implements a simple 8-function calculator.
 *
 * Input:  operand1, theOperator, operand2
 * Output: the result of applying theOperator to operand1 and operand2.
 *******************************************************************/

#include <iostream> // cin, cout, <<, >>
#include <string> // string
using namespace std;

double perform(char operation, double operand1, double operand2); 
int factorial(int n);

int main()
{
   const string MENU = "Enter:\n"
                       "  + for the addition operation\n"
                       "  - for the subtraction operation\n"
                       "  * for the multiplication operation\n"
                       "  / for the division operation\n"
                       "  ^ for the exponentiation operation\n"
                       "  l for the base-10 logarithm operation\n"
                       "  ! for the factorial operation and\n"
                       "  q to quit.\n"
                       "--> ";

   cout << "Welcome to the 8-function calculator!\n\n";

   double operand1,
          operand2,
          result;
   char theOperator;

   for (;;)
   {
      cout << MENU;
      cin >> theOperator;

      if (theOperator == 'q') break;

      cout << "Enter the first operand: ";
      cin >> operand1;

      if (theOperator == '+' || theOperator == '-' ||
          theOperator == '*' || theOperator == '/' ||
          theOperator == '^')
      {
         cout << "Enter the second operand: ";
         cin >> operand2;
      }
      result = perform(theOperator, operand1, operand2);

      cout << "The result is " << result << endl << endl;
   }
}



/* perform() applies operation to operand1 and operand2.
 *
 * Receive:      operation, a character
 *               operand1 and operand2, two doubles
 * Precondition: operation is one of +, -, *, /, ^, l, !
 * Return:       the result of applying operation to operand1 
 *                 and operand2
 *******************************************************************/

#include <cmath>           // pow(), log10()
using namespace std;

double perform(char operation, double operand1, double operand2)
{
   if (operation == '+')
      return operand1 + operand2;
   else if (operation == '-')
      return operand1 - operand2;
   else if (operation == '*')
      return operand1 * operand2;
   else if (operation == '/')
      if (operand2 != 0)
         return operand1 / operand2;
      else
      {
        cerr << "Operation Result: division by 0 -- "
                "result undefined!\n";
        return 0.0;
      }
   else if (operation == '^')
      return pow(operand1, operand2);
   else if (operation == 'l')
      return log10(operand1);
   else if (operation == '!')
      return (double)factorial((int)operand1);
   else
   {
      cerr << "OperationResult: invalid operator "
           << operation << " received!\n";
      return 0.0;
   }
}

/* factorial computes the factorial of a nonnegative integer. 
 *     
 * Receive:      n, an integer
 * Precondition: n is nonnegative
 * Return:       n!
 *************************************************************/

#include <cassert>             // assert()
using namespace std;

int factorial(int n)
{
   assert(n >= 0);

   int product = 1;

   for (int count = 2; count <= n; count++)
      product *= count;

   return product;
}


