免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3171 | 回复: 5
打印 上一主题 下一主题

自己写的一个命令行下的计算器,无视空格输入,不过有BUG。。。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-28 18:19 |只看该作者 |倒序浏览
程序任务:在命令行下任意输入两个数字,比如123      *     -123,把所有空格去掉,算出结果,如果输入错误则报错。

结果,发现在算123 +         -123时提示左操作数错误。。。只有在出现 左操作数  +     -右操作数时,会提示错误,其他情况未发现报错。非常奇怪,如果是123  +   +  123或者123 *   -   123还有其他任意输入未发现报错(只要输入的是数字,不包含其他字符不会报错)

程序代码:
#!/usr/bin/python

############################ file name: lcal.py #######################################
############################ function: ################################################
# 1. normal calculation, including add, subtract, multiple, divide
# 2. mathematical power calculation, square root calculation (want to realize extraction
# root calculation in future )
# 3. other calculation will be realized in future if i think of it
#
#######################################################################################
#
############################ version 0.9 ###############################################


import math

class Calculator:
   # __init__ function  will just convert the argument string to 2 numbers and 1 operator
   '''About lcal:
  
   This programm can process +, -, *, /, %, **(power calculation, for example, 3 ** 2 = 9),
   //2 (extraction square root calculation, for example 9 // 2, '2' is required)
  
   the form of input should be just like 1 + 1, or 1+1, otherwise lcal will prompt an error
   message.

   '''
   def __init__  (self, string):
      operator_tp = "+", '-', '*', '/', '%', '**', '//' # there are 6 operators, ** (for power calculation),
      operator = ''                                               #// (for extraction square root)
      oper_index = 0 # save the position of operator in the string
      num1 = 0
      num2 = 0
      s = string.strip()
      self.statu = True

      for op in operator_tp[0:]: # find the which operator that users enter in
         for i in s[1:]: # if user enter - 123 + 456, searching operator from s[1] can avoid this mistake
            if op == i:
               operator = op
               oper_index = s.find (op, 1)
               break     # if the operator found, break the loop, avoid finding the next '-' or '+'
      
      if operator in operator_tp:
         if (operator == '*' and s[oper_index+1] == '*') or (operator == '/' and s[oper_index+1] == '/'):
            num1 = s[0per_index].strip() # remove ' ' from num1 and num 2
            num2 = s[oper_index+2:].strip()
            operator = operator + s[oper_index+1]
         else:
            num1 = s[0per_index].strip()
            num2 = s[oper_index+1:].strip()

         num1_sign = num1[0]
         num2_sign = num2[0]

         if num1_sign.isdigit():
            try:
               num1 = float(num1)
            except ValueError:
               print 'Left operand is invalid.'
               self.statu = False
         elif num1_sign[0] == '+' or num1_sign[0] == '-':
            num1 = num1[1:].strip()
            try:
               if num1_sign[0] == '+':
                  num1 = float(num1)
               else:
                  num1 = 0 - float(num1)
            except ValueError:
               print 'Left operand is invalid.'
               self.statu = False
         else:
             print 'Left operand is invalid.'
             self.statu = False
         if num2_sign.isdigit():
            try:
               num2 = float(num2)
            except ValueError:
               print 'Right operand is invalid'
               self.statu = False            
         elif num2_sign[0] == '+' or num2_sign[0] == '-':
            num2 = num2[1:].strip()
            try:
               if num2_sign[0] == '+':
                  num2 = float(num2)
               else:
                  num2 = 0 - float(num2)
         
            except ValueError:
               print 'Right operand is invalid'
               self.statu = False

         else:
             print 'Right operand is invalid.'
             self.statu = False
      #print num1, operator, num2
         self.leftoperand = num1
         self.rightoperand = num2
         self.op = operator

      else:
         self.statu = False

      #print num1, self.op, num2, self.statu

   def add (self):
      if int(self.leftoperand + self.rightoperand) == (self.leftoperand + self.rightoperand):
         return int(self.leftoperand + self.rightoperand)
      else:
         return self.leftoperand + self.rightoperand

   def subtract (self):
      if int(self.leftoperand - self.rightoperand) == (self.leftoperand - self.rightoperand):
         return int(self.leftoperand - self.rightoperand)
      else:
         return self.leftoperand - self.rightoperand

   def multiply (self):
      if int(self.leftoperand * self.rightoperand) == (self.leftoperand * self.rightoperand):
         return int(self.leftoperand * self.rightoperand)
      else:
         return self.leftoperand * self.rightoperand

   def divide (self):
      if self.rightoperand != 0:
         if int(self.leftoperand / self.rightoperand) == (self.leftoperand / self.rightoperand):
            return int(self.leftoperand / self.rightoperand)
         else:
            return self.leftoperand / self.rightoperand
      else:
         return "False! divisor must not be 0 !"

   def mod (self):
      int_left = int (self.leftoperand)
      int_right = int (self.rightoperand)

      if int_left != self.leftoperand or int_right != self.rightoperand:# 2 operands must be integers for mod operation
         return "lease enter integers!"
      else:
         if self.rightoperand != 0:
            return (int_left % int_right)
         else:
            return "False! divisor must not be 0 !"

   def power (self):
      if int(self.leftoperand ** self.rightoperand) == (self.leftoperand ** self.rightoperand):
         return int(self.leftoperand ** self.rightoperand)
      else:
         return self.leftoperand ** self.rightoperand

   def sqrt (self):
      if self.leftoperand >= 0:
         if int(math.sqrt(self.leftoperand)) == math.sqrt(self.leftoperand):
            return int(math.sqrt(self.leftoperand))
         else:
            return math.sqrt(self.leftoperand)
      else:
         return "The leftoperand for sqrt calculation must be greater than or equal to 0"

expr = raw_input ("type 'help' for help, 'version' to show version, 'quit' to quit\n>>"
judge = True

version = '''lcal Version: 0.9

          '''

while judge:
   if expr != 'quit':
      cal = Calculator (expr)

      if expr != 'help' and expr != 'version':
         if cal.statu == True:
            if cal.op == '+':
               print '>>', cal.add()
            elif cal.op == '-':
               print '>>', cal.subtract()
            elif cal.op == '*':
               print '>>', cal.multiply()
            elif cal.op == '/':
               print '>>', cal.divide()
            elif cal.op == '%':
               print '>>', cal.mod()
            elif cal.op == '**':
               print '>>', cal.power()
            else:
               print '>>', cal.sqrt()
         else:
            print '>>Wrong input! please input again.'
      elif expr == 'version':
         print version
      else:
         print cal.__doc__
         
      expr = raw_input (">>"

   else:
      judge = False

论坛徽章:
0
2 [报告]
发表于 2012-03-28 18:21 |只看该作者
怎么搞的有图标出来了。。。

论坛徽章:
0
3 [报告]
发表于 2012-03-28 18:40 |只看该作者
找到错误了,,,应该break两次

论坛徽章:
0
4 [报告]
发表于 2012-03-28 20:10 |只看该作者
发修改好的上来:
#!/usr/bin/python
#-*- coding: utf_8 -*-
############################ file name: lcal.py #######################################
############################ function: ################################################
# 1. normal calculation, including add, subtract, multiple, divide
# 2. mathematical power calculation, square root calculation (want to realize extraction
# root calculation in future )
# 3. other calculation will be realized in future if i think of it
#
#######################################################################################
#
############################ version 0.9 ###############################################


import math

class Calculator:
   # __init__ function  will just convert the argument string to 2 numbers and 1 operator
   u'''About lcal:
  
   This programm can process +, -, *, /, %, **(power calculation, for example, 3 ** 2 = 9),
   //2 (extraction square root calculation, for example 9 // 2, '2' is required)
  
   the form of input should be just like 1 + 1, or 1+1, otherwise lcal will prompt an error
   message.

   关于lcal:

   lcal可以进行加,减,乘,除,模,乘方,和开平方运算,对应运算符为+, -, *, /, %, **, //2。

   输入的模式为 1 + 1或者1+1等,如果输入错误,会有错误提示。输入help,显示本段信息,输入version
   显示版本信息,输入quit退出。
   '''
   def __init__  (self, string):
      operator_tp = '*', '/', '%', '-', '+'# 创建一个包含所需运算符的tuple,减号和加号必须放后面,不然很麻烦,
      operator = ''    #用于存储运算符                          #如果放开头,当出现计算  5 * - 3的情况,operator将会是减号“-”           
      oper_index = 0 #存储运算符所在的位置,即下标
      num1 = 0  #左操作数
      num2 = 0  #右操作数
      s = string.strip() #去头尾空格
      #print s, operator_tp
      self.statu = True  #用于判断输入是否有效,即是否可以正常转换成两个数字和运算符

      for op in operator_tp:
         if s.find(op, 1) != -1: 从下标1开始找,避免将 -123 + 456 的第一个符号当做运算符
            operator = op
            oper_index = s.find(op, 1)
            break  #一找到运算符,跳出循环, 避免将 123 -  -456的第二个减号当做运算符

      if operator == '-':
         if s.find('+', 1, oper_index) != -1: #如果出现 123 + -456的情况, 上面操作会把减号当做运算符,致使左操作数变成123 +,无法转换浮点数
            operator = '+'                           #所以这里检查是否存在这种情况,存在的话,重新设置运算符,和运算符下标
            oper_index = s.find('+', 1)

      if operator == '+':
         if s.find('-', 1, oper_index) != -1: #原因同上
            operator = '-'
            oper_index = s.find('-', 1)

      #print operator
      if operator in operator_tp:
         if (operator == '*' and s[oper_index+1] == '*') or \   #判断是否要进行乘方开方运算,是的话,重新设置运算符,运算符下标不用重设
            (operator == '/' and s[oper_index+1] == '/'):
            num1 = s[0per_index].strip() #并获取左右操作数
            num2 = s[oper_index+2:].strip()
            operator = operator + s[oper_index+1]
         else:
            num1 = s[0per_index].strip()   #获取左右操作数
            num2 = s[oper_index+1:].strip()

         num1_sign = num1[0]   #以下判断左右操作数字串第一位是否是正负号
         num2_sign = num2[0]

         if num1_sign.isdigit(): #如果第一位是数字,操作数直接转换成数字,无法转换的话,报错
            try:
               num1 = float(num1)
            except ValueError:
               print 'Left operand is invalid.'
               self.statu = False
         elif num1_sign[0] == '+' or num1_sign[0] == '-': #如果第一位是正负号,
            num1 = num1[1:].strip()  #去掉正负号和空格
            try:
               if num1_sign[0] == '+':  #正数的话,直接转
                  num1 = float(num1)
               else:
                  num1 = 0 - float(num1) #负数的话,用0减
            except ValueError:
               print 'Left operand is invalid.'
               self.statu = False  #无法转换,设置statu为False
         else:
             print 'Left operand is invalid.'
             self.statu = False
         if num2_sign.isdigit():   #以下同num1
            try:
               num2 = float(num2)
            except ValueError:
               print 'Right operand is invalid'
               self.statu = False            
         elif num2_sign[0] == '+' or num2_sign[0] == '-':
            num2 = num2[1:].strip()
            try:
               if num2_sign[0] == '+':
                  num2 = float(num2)
               else:
                  num2 = 0 - float(num2)
         
            except ValueError:
               print 'Right operand is invalid'
               self.statu = False

         else:
             print 'Right operand is invalid.'
             self.statu = False
            
         
         self.leftoperand = num1
         self.rightoperand = num2
         self.op = operator

      else:
         self.statu = False

      #print num1, self.op, num2, self.statu

   def add (self):
      if int(self.leftoperand + self.rightoperand) == (self.leftoperand + self.rightoperand):
         return int(self.leftoperand + self.rightoperand)
      else:
         return self.leftoperand + self.rightoperand

   def subtract (self):
      if int(self.leftoperand - self.rightoperand) == (self.leftoperand - self.rightoperand):
         return int(self.leftoperand - self.rightoperand)
      else:
         return self.leftoperand - self.rightoperand

   def multiply (self):
      if int(self.leftoperand * self.rightoperand) == (self.leftoperand * self.rightoperand):
         return int(self.leftoperand * self.rightoperand)
      else:
         return self.leftoperand * self.rightoperand

   def divide (self):
      if self.rightoperand != 0:
         if int(self.leftoperand / self.rightoperand) == (self.leftoperand / self.rightoperand):
            return int(self.leftoperand / self.rightoperand)
         else:
            return self.leftoperand / self.rightoperand
      else:
         return "False! divisor must not be 0 !"

   def mod (self):
      int_left = int (self.leftoperand)
      int_right = int (self.rightoperand)

      if int_left != self.leftoperand or int_right != self.rightoperand:# 2 operands must be integers for mod operation
         return "lease enter integers!"
      else:
         if self.rightoperand != 0:
            return (int_left % int_right)
         else:
            return "False! divisor must not be 0 !"

   def power (self):
      if int(self.leftoperand ** self.rightoperand) == (self.leftoperand ** self.rightoperand):
         return int(self.leftoperand ** self.rightoperand)
      else:
         return self.leftoperand ** self.rightoperand

   def sqrt (self):
      if self.leftoperand >= 0:
         if int(math.sqrt(self.leftoperand)) == math.sqrt(self.leftoperand):
            return int(math.sqrt(self.leftoperand))
         else:
            return math.sqrt(self.leftoperand)
      else:
         return "The leftoperand for sqrt calculation must be greater than or equal to 0"

expr = raw_input ("type 'help' for help, 'version' to show version, 'quit' to quit\n>>"
judge = True

version = u'''lcal Version: 0.9

         
          '''

while judge:
   if expr != 'quit':
      cal = Calculator (expr)

      if expr != 'help' and expr != 'version':
         if cal.statu == True:
            if cal.op == '+':
               print '>>', cal.add()
            elif cal.op == '-':
               print '>>', cal.subtract()
            elif cal.op == '*':
               print '>>', cal.multiply()
            elif cal.op == '/':
               print '>>', cal.divide()
            elif cal.op == '%':
               print '>>', cal.mod()
            elif cal.op == '**':
               print '>>', cal.power()
            else:
               print '>>', cal.sqrt()
         else:
            print '>>Wrong input! please input again.'
      elif expr == 'version':
         print version
      else:
         print cal.__doc__
         
      expr = raw_input (">>"

   else:
      judge = False

论坛徽章:
0
5 [报告]
发表于 2012-04-05 22:30 |只看该作者
扶持一个先。

论坛徽章:
0
6 [报告]
发表于 2012-04-06 09:19 |只看该作者
代码还是用专用的贴代码的格式来贴吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP