Advertisement
Guest User

Untitled

a guest
Sep 26th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.48 KB | None | 0 0
  1. import time
  2.  
  3. def isNumber(s):
  4. #s must be a non-empty string
  5. #returns True if it's convertible to float, else False
  6. if (len(s)==0 and not s =='') or not isinstance(s, str):
  7. print("type mismatch error: isNumber")
  8. return "type mismatch error: isNumber"
  9. try:
  10. s = float(s)
  11. return True
  12. except ValueError:
  13. #print("type mismatch error: isNumber")
  14. return False
  15.  
  16.  
  17. def cleanUp(s):
  18. priorSpace = True
  19. inDecimal = False
  20. ops = ["+","-","*","/","^"]
  21. s = s.replace("+", " + ").replace("-", " - ").replace("*", " * ").replace("/", " / ").replace("^", " ^ ").replace(" - - ", " + ")
  22. st = list(s)
  23. for i,c in enumerate(s):
  24. if (not isNumber(c) and c not in ops) and priorSpace:
  25. if c == "." and not inDecimal:
  26. inDecimal = True
  27. elif c == "." and inDecimal:
  28. st[i] = ""
  29. else:
  30. st[i] = ""
  31. inDecimal = False
  32. elif (not isNumber(c) and c not in ops) and not priorSpace:
  33. if c == "." and not inDecimal:
  34. inDecimal = True
  35. elif c == "." and inDecimal:
  36. st[i] = ""
  37. else:
  38. st[i] = " "
  39. priorSpace = True
  40. inDecimal = False
  41. else:
  42. priorSpace = False
  43. final = ''.join(st).strip().split(' ')
  44. if '-' in final[0]:
  45. del final[0]
  46. final[0] = '-' + final[0]
  47. newNumber, newOpr, oprPos = getNextNumber(final, 0)
  48. if oprPos == None:
  49. return newNumber
  50. cacheNum=newNumber
  51. pos=oprPos+1 #the new current position
  52. opr=newOpr
  53. while pos<(len(final)-1):
  54. newNumber, newOpr, oprPos = getNextNumber(final, pos)
  55. if (newOpr == None):
  56. break
  57. if (not isNumber(newNumber) and newNumber == '-'):
  58. nex = getNextNumber(final, oprPos)[0] #BOOKMARK
  59. del final[final.index(newNumber)] #BOOKMARK
  60. index = final.index(nex)
  61. final[index] = '-' + final[index]
  62. temp = final[index]
  63. if (not isNumber(newNumber) and newNumber != '-'):
  64. print("error at line AB", newNumber)
  65. return "error at line AB"
  66. pos=oprPos+1
  67. return (final)
  68.  
  69.  
  70. def getNextNumber(expr, pos):
  71. #expr is a given arithmetic formula in string
  72. temp = expr
  73. #pos = start position in expr
  74. #1st returned value = the next number (None if N/A)
  75. #2nd returned value = the next operator (None if N/A)
  76. #3rd retruned value = the next operator position (None if N/A)
  77. ops = ["+","-","*","/"]
  78. if len(expr)==0 or pos<0 or pos>=len(expr) or not isinstance(pos, int):
  79. print("type mismatch error: getNextNumber")
  80. return None, None, "type mismatch error: getNextNumber"
  81. #--- function code starts ---#
  82. res3 = 0
  83. res2 = 0
  84. if (pos+1) < len(temp):
  85. res3 = pos+1
  86. res2 = temp[pos+1]
  87. else:
  88. res3 = None
  89. res2 = None
  90. return ((temp[pos], res2, res3))
  91.  
  92.  
  93.  
  94. #--- function code ends ---#
  95.  
  96.  
  97. def exeOpr(num1, opr, num2):
  98. #This is a simple utility function skipping type check
  99. if opr=="+":
  100. return num1+num2
  101. elif opr=="-":
  102. return num1-num2
  103. elif opr=="*":
  104. return num1*num2
  105. elif opr=="/":
  106. return num1/num2
  107. elif opr=="^":
  108. return num1**num2
  109. else:
  110. return None
  111.  
  112.  
  113. def calc(expr):
  114. #expr: nonempty string that is an arithmetic expression
  115. #the fuction returns the calculated result
  116. expr = cleanUp(expr)
  117. if len(expr)<=0:
  118. print("argument error: line A in eval_expr") #Line A
  119. return "argument error: line A in eval_expr"
  120. #Hold two modes: "addition" and "multiplication"
  121. #Initializtion: get the first number
  122. newNumber, newOpr, oprPos = getNextNumber(expr, 0)
  123. ops = ["^","*","/","+","-"]
  124. if newNumber is None or not isNumber(newNumber):
  125. print("input formula error: line B in eval_expr") #Line B
  126. return "input formula error: line B in eval_expr"
  127. elif newOpr is None or not newOpr in ops:
  128. return newNumber
  129. cacheNum=newNumber
  130. pos=oprPos+1 #the new current position
  131. opr=newOpr #the new current operator
  132. #start the calculation. Use the above functions effectively.
  133. new_expr = expr
  134. while True:
  135. newNumber, newOpr, oprPos = getNextNumber(new_expr, pos)
  136. #print(cacheNum, opr, newNumber, "The next opr however is", newOpr)
  137. if (not isNumber(newNumber)):
  138. print("input formula error: line C in eval_expr") #Line C
  139. return "input formula error: line C in eval_expr"
  140. if (newOpr == None):
  141. break
  142. if(newOpr == "^"):
  143. temp = getNextNumber(new_expr, oprPos+1)[0]
  144. if (not isNumber(temp)):
  145. print("input formula error: line D in eval_expr") #Line D
  146. return "input formula error: line D in eval_expr"
  147. #print("Weee", newOpr, newNumber, "with", temp)
  148. subs = exeOpr(float(newNumber), newOpr, float(temp))
  149. del new_expr[oprPos-1]
  150. del new_expr[oprPos-1]
  151. new_expr[oprPos-1] = str(subs)
  152. #print("The new expression to start calculating is: " + new_expr)
  153. elif((newOpr == "*" or newOpr == "/") and (opr not in ["^","*","/"])):
  154. temp, temp_Opr, temp_Pos = getNextNumber(new_expr, oprPos+1)
  155. #print("uhhh", temp_Opr)
  156. if temp_Opr == "^":
  157. temp2 = getNextNumber(new_expr, oprPos+3)[0]
  158. if (not isNumber(temp)):
  159. print("input formula error: line D in eval_expr") #Line D
  160. return "input formula error: line D in eval_expr"
  161. #print("We", temp_Opr, temp, "with", temp2)
  162. subs = exeOpr(float(temp), temp_Opr, float(temp2))
  163. del new_expr[temp_Pos-1]
  164. del new_expr[temp_Pos-1]
  165. new_expr[temp_Pos-1] = str(subs)
  166. #print("The new expression to start calculating is: " + new_expr)
  167. else:
  168. if (not isNumber(temp)):
  169. print("input formula error: line D in eval_expr") #Line D
  170. return "input formula error: line D in eval_expr"
  171. #print("Weee", newOpr, newNumber, "with", temp)
  172. subs = exeOpr(float(newNumber), newOpr, float(temp))
  173. del new_expr[oprPos-1]
  174. del new_expr[oprPos-1]
  175. new_expr[oprPos-1] = str(subs)
  176. #print("The new expression to start calculating is: " + new_expr)
  177. elif((newOpr == "+" or newOpr == "-") and opr not in ["+","-"]):
  178. subs = exeOpr(float(cacheNum), opr, float(newNumber))
  179. del new_expr[pos-2]
  180. del new_expr[pos-2]
  181. new_expr[pos-2] = str(subs)
  182. cacheNum=str(subs)
  183. opr=newOpr
  184. #print("The new expressionn to start calculating is: " + new_expr)
  185. else:
  186. subs = exeOpr(float(cacheNum), opr, float(newNumber))
  187. del new_expr[pos-2]
  188. del new_expr[pos-2]
  189. new_expr[pos-2] = str(subs)
  190. #print("The new expression to start calculating is: " + new_expr)
  191. cacheNum=str(subs)
  192. opr=newOpr
  193. subs = exeOpr(float(cacheNum), opr, float(newNumber))
  194. #print(new_expr)
  195. del new_expr[new_expr.index(cacheNum)]
  196. del new_expr[new_expr.index(opr)]
  197. new_expr[new_expr.index(newNumber)] = str(subs)
  198. return float(new_expr[0])
  199.  
  200. print(calc("2+2 -4 * 1 / 3.344 - -2")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement