Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 135,937 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 2,688 people online right now. Registration is fast and FREE... Join Now!




"Bullet-Proofing" an RPN Calculator

 
Reply to this topicStart new topic

"Bullet-Proofing" an RPN Calculator

CrazyJ
26 Nov, 2007 - 12:42 AM
Post #1

D.I.C Head
**

Joined: 15 Oct, 2007
Posts: 51


My Contributions
I am looking for any creative or straightforward tips on the easiest and of course, logical manner in which to bullet proof my rpn calculator. For instance, I would like to be able to flag as an error condition the request to divide by zero is part of the bullet proofing. Would exception handling do the trick? If so, what would work best? Also, the program must check the user input for validity. If the input is incorrect, the program should allow the user to enter fresh input. This must be bullet proof. Any and all ideas are appreciated, thank you! icon_up.gif

CODE

namespace RPN_Calculator
{
    class Calculator
    {
        //      ===============================
        static void Main(string[] args)
        {
            char arithmeticOperator;
            double result;
            double number;

            string token;
            string expression;

            Stack stack = new Stack();

            Console.WriteLine("RPN Calculator Invoked.");
            Console.WriteLine();

            while (!CalculatorMethods.Quit())
            {
                stack.InitializeStack();

                Console.WriteLine("Enter an expression.");
                Console.WriteLine();
                Console.WriteLine();

                expression = Console.ReadLine();

                do
                {
                    CalculatorMethods.GetNextToken(out token,
                                                    ref expression);

                    if (CalculatorMethods.IsOperator(token))
                    {
                        arithmeticOperator = token[0];
                        CalculatorMethods.Evaluate(stack, arithmeticOperator);
                    }
                    else
                    {
                        number = Convert.ToDouble(token);
                        stack.Push(number);
                    } // else

                } while (expression.Length > 0);

                stack.Pop(out result);
                if (stack.StackEmpty())
                    Console.WriteLine("The answer is " + result + '\n');
                else
                    Console.WriteLine("Error state encountered." + '\n');

            } // while

        } // method Main
        //      ================

    } // class Calculator
} // namespace RPN_Calculator


Calc methods

CODE

class CalculatorMethods
    {            
//  =========================================
    public static void Evaluate( Stack stack,
                                 char  op )
    {
        double operand1;
        double operand2;

        stack.Pop( out operand2 );
        stack.Pop( out operand1 );

        switch( op ) {

            case '+' : stack.Push( operand1 + operand2 );
                break;
            case '-' : stack.Push( operand1 - operand2 );
                break;
            case '*' : stack.Push( operand1 * operand2 );
                break;
            case '/' : stack.Push( operand1 / operand2 );
                break;
            default:
                Console.WriteLine("From Evaluate: Unexpected Error.");
                break;

        }  // switch

    }  // method Evaluate
//  =====================    
        
//  ========================================================
    public static void GetNextToken( out string token,
                                     ref string expression )
    {
        int    indexOfSpace;

        if ( expression.Length > 0 )
        {
            indexOfSpace = expression.IndexOf(' ');

            if (indexOfSpace == -1)
            { // The last token if wanted
                token = expression.Substring(0, expression.Length);
                expression = "";
            }
            else
            {
                token = expression.Substring(0, indexOfSpace);

//              Remove from expression, i.e., the string containing the user's input
//              expression, the token (operand or operator) now held by token.
                expression = expression.Substring(indexOfSpace + 1,
                                                  expression.Length - (indexOfSpace + 1));
            }  // else

        }  // then
        else
        {
            token = ""; // There are no tokens left.
        }  // else

    }  // method GetNextToken
//  ========================

//  ===========================================
    public static bool IsOperator(string token)
    {
        return
        (  (token.Length == 1) &&
         ( (token[0] == '+') ||
           (token[0] == '-') ||
           (token[0] == '*') ||
           (token[0] == '/')
         )
        );
    } // method IsOperator
//  ======================

//  =========================
    public static bool Quit()
    {
        string answer;

        Console.WriteLine("Would you like to enter an expression? (yes/no)");
        answer = Console.ReadLine();

        return (answer.Equals("no"));
    }  // method Quit
//  ================

    }  // class CalculatorMethods
//  ============================


and Stack

CODE

    class Stack
    {
//  ==============================================
//      Instance variables for the Stack class. ==
//      ==========================================

//      ==========================
        private double[] elements;
        private uint top;
//      =================

//      ======================
//      End Instance variables
//  ==========================

//  =========================
//      Begin Constructors ==
//      =====================

//      ===============
        public Stack()
        {

            elements = new double[1];

            top = 0;
        } // constructor Stack
//      ======================

//      ===================
//      End Constructors ==
//  =======================


//  ====================
//      Begin Methods ==
//      ================

//      ==============================
        public void InitializeStack()
        {
            Array.Resize(ref elements, 1);
            elements[0] = 0.0;

            top = 0;
        } // method InitializeStack (interface operator)
//      ================================================

//      ==============================================================
//           The Pop operator does not check to determine if the stack
//      is empty before attempting to pop a value.  A pre-condition
//      required by Pop is that the stack has at least one value.  Code
//      that invokes Pop should invoke the operator StackEmpty first and
//      and only if the stack is not empty then pop a value.
//      =====================================
        public void Pop(out double stackValue)
        {
            top--;

            stackValue = elements[top];
            Array.Resize(ref elements, elements.Length - 1);

        } // method Pop (interface operator)
//      ====================================
//      =========================      
        public void PrintStack()
        {
            System.Console.WriteLine("Stack Top");

            if (StackEmpty())
                System.Console.WriteLine("The stack is empty.");
            else
            {
                for (int ii = (int)top - 1; ii >= 0; ii--)
                {
                    System.Console.Write("elements[" + ii + "] = ");
                    System.Console.WriteLine(elements[ii]);
                } // for
            } // else

            System.Console.WriteLine("Stack Bottom");
            System.Console.WriteLine();
        } // method PrintStack (interface operator)
//      ===========================================

//      =====================================
        public void Push(double stackValue)
        {
            Array.Resize(ref elements, elements.Length + 1);
            elements[top] = stackValue;

            top++;
        } // method Push (interface operator)
//      =====================================

//      ====================================================
//      If the stack is empty, then its length will be zero.
//      =========================
        public bool StackEmpty()
        {
            return top == 0;
        } // method StackEmpty (interface operator)
//      ===========================================

//      ========================
        public bool StackFull()
        {
            return false;
        } // method StackFull (interface operator)
//      ==========================================

//      ==============
//      End Methods ==
//  ==================

    } // class Stack


Thanks!
User is offlineProfile CardPM
+Quote Post

Martyr2
RE: "Bullet-Proofing" An RPN Calculator
26 Nov, 2007 - 12:03 PM
Post #2

Programming Theoretician
Group Icon

Joined: 18 Apr, 2007
Posts: 5,173



Thanked: 208 times
Expert In: C/C++, Java, VB, VB.NET, C#, PHP, Web Development, HTML & CSS, Javascript

My Contributions
Yes, error handling is the way to go with C# (as with any .NET language). You will need to design the handling in such a way to not interfere too much with the operation of the program, but instead record that the data is bad or invalid, write it out to file somewhere, and reset itself so that it can start fresh. You could then review the log later of any bad input.

Then you could apply something called "Fuzzy Data" which is a nice warm cuddly term for throwing the most random data at it as you can, attempting to test all the boundaries. I talk more about this in my blog at...

Martyr2's Programming Underground - What is all the "fuzz"ing about?

So the idea is that your program handles random fuzz data, if it causes an error, it writes the data used to generate the error and the error message to an external source, resets itself and continues all automatically.

You can then run this as long as you want until you are confident it won't break. You can review the output to make sure than nothing has failed and you should be good to go.

That is how I would go about doing it.

Hope this is what you were looking for. smile.gif
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/1/08 08:37AM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month