Python实现的简单计算器
Python实现的简单计算器
运行截图:
其实,python本来就是一个很强大的计算器:^_^,
<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+U291cmNlIENvZGWjujwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">__author__ = 'Joel'
class ExpStack():
#init method
def __init__(self):
self.top = -1
self.data = []
#whether Stack is empty
def is_empty(self):
return -1 == self.top
#pop an element from stack
def pop(self):
if self.is_empty():
print "Stack is Empty..."
else:
self.data.pop(self.top)
self.top -= 1
#push an element into stack
def push(self, e):
self.data.append(e)
self.top += 1
#get an element in the top of the stack
def get_top(self):
if self.is_empty():
print "Stack is Empty"
return None
else:
return self.data[self.top]
#get the size of the stack
def size(self):
return self.top + 1
#clear stack
def clear(self):
self.top = -1
self.data = []
#get data of stack
def get_data(self):
return self.data
#whether a char is a number
def is_number(char):
return ("0" == char or "1" == char or "2" == char or "3" == char or
"4" == char or "5" == char or "6" == char or "7" == char or
"8" == char or "9" == char)
#whether a char is dot
def is_dot(char):
return "." == char
#whether a char is calculator operation
def is_calculator_option(char):
return ("+" == char or "-" == char or "*" == char or "/" == char
or "(" == char or ")" == char or "^" == char)
#get calculator string
def get_calculator_str():
return raw_input("Please input calculator string(no '=') end with '-1':\n")
#whether a string consists of numbers
def is_number_str(m_str):
for n in m_str:
if (not is_number(n)) and (not is_dot(n)):
return False
return True
#filter blanks from a string
def str_trim(src_str):
ret_str = ""
for c in src_str:
if " " != c:
ret_str += c
return ret_str
#filter useless characters from a string
def str_filter(src_str):
ret_str = ""
for c in src_str:
if is_number(c) or is_calculator_option(c) or is_dot(c):
ret_str += c
return ret_str
#print elements in the stack
def print_calculator_stack(stack):
print "---stack content---"
print stack.get_data()
print
#compare operators, return an integer
#1: higher priority; 0:lower priority; -1:wrong operator; 2:same priority
def compare_operator(op1, op2):
if "^" == op1:
if "^" == op2:
return 2
elif "+" == op2 or "-" == op2 or "*" == op3 or "/" == op3:
return 1
else:
return -1
elif "*" == op1 or "/" == op1:
if "^" == op2:
return 0
elif "*" == op2 or "/" == op2:
return 2
elif "+" == op2 or "-" == op2:
return 1
else:
return -1
elif "+" == op1 or "-" == op1:
if "^" == op2 or "*" == op2 or "/" == op2:
return 0
elif "+" == op2 or "-" == op2:
return 2
else:
return -1
else:
return -1
#get all elements from calculator string and return a stack
def get_calculator_stack(cal_str):
exp_stack = ExpStack()
ele = "" # one element, a number or operator
get_a_number = False # whether get a number
#if calculator string start with "-(", push 0 in the bottom of the stack
if len(cal_str) > 2 and "-" == cal_str[0] and "(" == cal_str[1]:
exp_stack.push("0")
for tem_char in cal_str:
if (((not get_a_number) and "-" == tem_char)
or (not is_calculator_option(tem_char))): # is a number
ele += tem_char
get_a_number = True
else: # is a operator
if "" != ele:
exp_stack.push(ele)
ele = ""
exp_stack.push(tem_char)
if ")" != tem_char: # is )
get_a_number = False
else: # is (
get_a_number = True
if len(ele) != 0:
exp_stack.push(ele)
return exp_stack
#turn prefix stack into suffix stack
def prefix_to_suffix(prefix_stack):
data = prefix_stack.get_data()
suffix_stack = ExpStack()
tem_stack = ExpStack()
get_a_number = False
get_a_operator = False
for ele in data:
if is_number_str(ele): # is number, put it into suffix
get_a_operator = False
if get_a_number:
suffix_stack.push(ele)
suffix_stack.push("*")
else:
suffix_stack.push(ele)
get_a_number = True
elif "(" == ele: # is (, push elements into stack
tem_stack.push(ele)
elif ")" == ele: # is ),
while "(" != tem_stack.get_top():
suffix_stack.push(tem_stack.get_top())
tem_stack.pop()
if tem_stack.is_empty():
print "Brackets not match!"
return None
if "(" == tem_stack.get_top():
tem_stack.pop()
elif is_calculator_option(ele): # is operator
get_a_number = False
if get_a_operator: # no numbers between 2 operators
print "Wrong Exps."
return None
else:
get_a_operator = True
while ((not tem_stack.is_empty())
and "(" != tem_stack.get_top()
and compare_operator(tem_stack.get_top(), ele)>0):
suffix_stack.push(tem_stack.get_top())
tem_stack.pop()
tem_stack.push(ele)
while not tem_stack.is_empty():
if "(" == tem_stack.get_top():
print "Brackets not match!"
return None
suffix_stack.push(tem_stack.get_top())
tem_stack.pop()
return suffix_stack
#calculate from stack, return result string
def calculate_from_stack(suffix_stack):
error_str = "error"
nan_str = "NaN"
if None == suffix_stack:
print "stack is empty!"
return error_str
data = suffix_stack.get_data()
calculate_stack = ExpStack()
for ele in data:
if is_number_str(ele):
calculate_stack.push(ele)
elif is_calculator_option(ele):
if calculate_stack.size()<2:
print "Wrong suffix exps."
print_calculator_stack(suffix_stack)
return error_str
try:
num1 = float(calculate_stack.get_top())
calculate_stack.pop()
num2 = float(calculate_stack.get_top())
calculate_stack.pop()
if "+" == ele:
calculate_stack.push(num1+num2)
elif "-" == ele:
calculate_stack.push(num2-num1)
elif "*" == ele:
calculate_stack.push(num2*num1)
elif "/" == ele:
calculate_stack.push(num2/num1)
elif "^" == ele:
calculate_stack.push(num2**num1)
else:
print "Unknow calculator operator", ele
return error_str
except TypeError, e:
print "type error:", e
return error_str
except ValueError, e:
print "value error:", e
return error_str
except ZeroDivisionError, e:
print "divide zero error: e"
return nan_str
if 1 == calculate_stack.size():
return str(calculate_stack.get_top())
else:
print "Unknow error, calculate stack:"
print_calculator_stack(calculate_stack)
return error_str
########### several test function ############
def test_stack():
my_stack = ExpStack()
print my_stack.is_empty()
my_stack.push("1")
my_stack.push(2)
my_stack.push(3.14)
print my_stack.is_empty()
print my_stack.get_data()
print my_stack.size()
print_calculator_stack(my_stack)
def test_isnum():
num = ["1", "2", 1., '0']
i = 0
while i < len(num):
if is_number(num[i]):
print num[i], " is number"
else:
print num[i], "is not number"
i += 1
########### END ############
def main():
if __name__ == "__main__":
cal_str = get_calculator_str()
cal_str = str_filter(cal_str) # filter string
# main loop
while "-1" != cal_str:
prefix_stack = get_calculator_stack(cal_str)
print "cal str:", cal_str
print "prefix stack:"
print_calculator_stack(prefix_stack)
# make prefix to suffix
suffix_stack = prefix_to_suffix(prefix_stack)
print "suffix stack:"
print_calculator_stack(suffix_stack)
# calculate suffix
print "---calculator result---"
print calculate_from_stack(suffix_stack)
cal_str = get_calculator_str()
cal_str = str_filter(cal_str) # filter string
print "bye~"
else:
print __name__
#the main!
main()
评论关闭