Python implements a simple arithmetic calculator, python

Source: Internet
Author: User

Python implements a simple arithmetic calculator, python

I. Algorithms

1. The main idea of the algorithm is to convert an Infix expression into a Postfix expression, and then use the stack's simple data structure, returns the result of an expression.

2. The detailed description of how to convert a common expression to a suffix expression and how to process a suffix expression and calculate the result is not described here.

Ii. Simple Calculator

Instructions for use

A simple example of using this calculator class is as follows:

# usagec = Calculator()print('result: {:f}'.formart(c.get_result('1.11+2.22-3.33*4.44/5.55')))# output:result: 0.666000

Test Case

To effectively test the calculator, several groups of test cases are designed. The test results are as follows:

Test No.1: (1.11) = 1.110000Test No.2: 1.11+2.22-3.33*4.44/5.55 = 0.666000Test No.3: 1.11+(2.22-3.33)*4.44/5.55 = 0.222000Test No.4: 1.11+(2.22-3.33)*(4.44+5.55)/6.66 = -0.555000Test No.5: 1.11*((2.22-3.33)*(4.44+5.55))/(6.66+7.77) = -0.852992Test No.6: (1.11+2.22)*(3.33+4.44)/5.55*6.66 = 31.048920Test No.7: (1.11-2.22)/(3.33+4.44)/5.55*(6.66+7.77)/(8.88) = -0.041828Test No.8: Error: (1.11+2.22)*(3.33+4.44: missing ")", please check your expressionTest No.9: Error: (1.11+2.22)*3.33/0+(34-45): divisor cannot be zeroTest No.10: Error: 12+89^7: invalid character: ^

Implementation Code

Stack implementation

The stack is actually a restricted table. All operations can only be performed at the top of the stack (for example, inbound and outbound stacks). The following is a simple stack implemented using Python code:

class Stack(object):  """  The structure of a Stack.  The user don't have to know the definition.  """  def __init__(self):    self.__container = list()  def __is_empty(self):    """    Test if the stack is empty or not    :return: True or False    """    return len(self.__container) == 0  def push(self, element):    """    Add a new element to the stack    :param element: the element you want to add    :return: None    """    self.__container.append(element)  def top(self):    """    Get the top element of the stack    :return: top element    """    if self.__is_empty():      return None    return self.__container[-1]  def pop(self):    """    Remove the top element of the stack    :return: None or the top element of the stack    """    return None if self.__is_empty() else self.__container.pop()  def clear(self):    """    We'll make an empty stack    :return: self    """    self.__container.clear()    return self

Calculator implementation

In the calculator class, we put the expression legality verification in a single function, but in fact, you can also directly put it in a function with an infix expression to a suffix expression, in this way, you only need to traverse the expression once to complete verification and conversion at the same time. However, in order to keep the structure clear, it is better to implement the function separately. It is more practical to do the best thing possible for each function.

In this calculator class, there are many extreme cases that are not taken into account, because the entire implementation code will be more. However, you can continue to expand the entire class at a later stage. It is also possible to add new functions. Currently, the main framework is implemented, including basic error detection and computation. The focus is to use the seemingly simple but powerful data structure of stack to solve the problem.

class Calculator(object):  """  A simple calculator, just for fun  """  def __init__(self):    self.__exp = ''  def __validate(self):    """    We have to make sure the expression is legal.    1. We only accept the `()` to specify the priority of a sub-expression. Notes: `[ {` and `] }` will be    replaced by `(` and `)` respectively.    2. Valid characters should be `+`, `-`, `*`, `/`, `(`, `)` and numbers(int, float)    - Invalid expression examples, but we can only handle the 4th case. The implementation will    be much more sophisticated if we want to handle all the possible cases.:      1. `a+b-+c`      2. `a+b+-`      3. `a+(b+c`      4. `a+(+b-)`      5. etc    :return: True or False    """    if not isinstance(self.__exp, str):      print('Error: {}: expression should be a string'.format(self.__exp))      return False    # Save the non-space expression    val_exp = ''    s = Stack()    for x in self.__exp:      # We should ignore the space characters      if x == ' ':        continue      if self.__is_bracket(x) or self.__is_digit(x) or self.__is_operators(x) \          or x == '.':        if x == '(':          s.push(x)        elif x == ')':          s.pop()        val_exp += x      else:        print('Error: {}: invalid character: {}'.format(self.__exp, x))        return False    if s.top():      print('Error: {}: missing ")", please check your expression'.format(self.__exp))      return False    self.__exp = val_exp    return True  def __convert2postfix_exp(self):    """    Convert the infix expression to a postfix expression    :return: the converted expression    """    # highest priority: ()    # middle: * /    # lowest: + -    converted_exp = ''    stk = Stack()    for x in self.__exp:      if self.__is_digit(x) or x == '.':        converted_exp += x      elif self.__is_operators(x):        converted_exp += ' '        tp = stk.top()        if tp:          if tp == '(':            stk.push(x)            continue          x_pri = self.__get_priority(x)          tp_pri = self.__get_priority(tp)          if x_pri > tp_pri:            stk.push(x)          elif x_pri == tp_pri:            converted_exp += stk.pop() + ' '            stk.push(x)          else:            while stk.top():              if self.__get_priority(stk.top()) != x_pri:                converted_exp += stk.pop() + ' '              else:                break            stk.push(x)        else:          stk.push(x)      elif self.__is_bracket(x):        converted_exp += ' '        if x == '(':          stk.push(x)        else:          while stk.top() and stk.top() != '(':            converted_exp += stk.pop() + ' '          stk.pop()    # pop all the operators    while stk.top():      converted_exp += ' ' + stk.pop() + ' '    return converted_exp  def __get_result(self, operand_2, operand_1, operator):    if operator == '+':      return operand_1 + operand_2    elif operator == '-':      return operand_1 - operand_2    elif operator == '*':      return operand_1 * operand_2    elif operator == '/':      if operand_2 != 0:        return operand_1 / operand_2      else:        print('Error: {}: divisor cannot be zero'.format(self.__exp))        return None  def __calc_postfix_exp(self, exp):    """    Get the result from a converted postfix expression    e.g. 6 5 2 3 + 8 * + 3 + *    :return: result    """    assert isinstance(exp, str)    stk = Stack()    exp_split = exp.strip().split()    for x in exp_split:      if self.__is_operators(x):        # pop two top numbers in the stack        r = self.__get_result(stk.pop(), stk.pop(), x)        if r is None:          return None        else:          stk.push(r)      else:        # push the converted number to the stack        stk.push(float(x))    return stk.pop()  def __calc(self):    """    Try to get the result of the expression    :return: None or result    """    # Validate    if self.__validate():      # Convert, then run the algorithm to get the result      return self.__calc_postfix_exp(self.__convert2postfix_exp())    else:      return None  def get_result(self, expression):    """    Get the result of an expression    Suppose we have got a valid expression    :return: None or result    """    self.__exp = expression.strip()    return self.__calc()  """  Utilities  """  @staticmethod  def __is_operators(x):    return x in ['+', '-', '*', '/']  @staticmethod  def __is_bracket(x):    return x in ['(', ')']  @staticmethod  def __is_digit(x):    return x.isdigit()  @staticmethod  def __get_priority(op):    if op in ['+', '-']:      return 0    elif op in ['*', '/']:      return 1

Summary

The above is the use of Python to implement all the content of the simple arithmetic calculator. I hope the content in this article will be helpful for your study or work. If you have any questions, please leave a message.

Reference

Description of algorithms in data structure and algorithm (c)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.