正剧开始:
星历2016年02月19日 12:09:48, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究百分数的运算。
对于百分数的读写,小伟也没有什么兴趣,因为就是对小数读写加了个百分号而已。
恩格尔系数要不要计算一下呢,小伟想了想,还是算了,今天的小伟真的很懒。
from fractions import *; import traceback; ### # @usage 百分数,分数, 小数各结果的运算 # @author mw # @date 2016年02月19日 星期五 10:42:16 # @param # @return # ### def calc(): # 可以将任意的四则运算表达式用分数进行计算, # 而不是将浮点结果简单转化成分数。 fin = open('input.txt'); fout= open('output.txt', 'a'); #结果为整数,此时小数表示和分数结果相同。 resultIsInt = False; #结果绝对值大于10, 此时用百分数表示不合适。 noPercentExpr = False; for line in fin.readlines(): if line[-1] == '\n': line = line[:-1]; if line == '': continue; elif line.startswith('#'): print(line); fout.write(line+'\n'); else: try: lines = line.split(sep=' '); for i in range(len(lines)): if lines[i]=='': continue; #消除空格 lines[i] = lines[i].replace(' ', ''); expCount = len(lines[i]); expression = ''; resultIsInt = False; noPercentExpr = False; originExpr = lines[i]; #看表达式中是否有百分号 havePercentOp = False; if lines[i].find('%') != -1: havePercentOp = True; OpsArray = []; if havePercentOp == True: for j in range(expCount): #操作符直接添加 if isOps(lines[i][j]): OpsArray.append(lines[i][j]); #处理百分号 if lines[i][j] == '%': if OpsArray[-1] == '/': expression+='*100'; else: expression+='/100'; else: expression+=lines[i][j]; lines[i] = expression; expCount = len(lines[i]); expression = ''; #小数结果 floatResult = 0; #百分数结果 percentResult = 0; result = eval(lines[i]); if (abs(result)>10): noPercentExpr = True; if (abs(result - int(result)) < 0.000001): resultIsInt = True; #小数结果 floatResult = int(result); percentResult = int(result)*100; else: #小数结果 floatResult = round(result, 3); result2 = result * 100; if (abs(result2 - int(result2)) < 0.000001): percentResult = int(result2); else: percentResult = round(result2, 3); #分割操作数 operands = []; stmp = ''; indexBeg = 0; indexEnd = 0; for j in range(expCount): if isOps(lines[i][j]): if stmp != '': operands.append(stmp); stmp = ''; else: stmp+=lines[i][j]; if stmp != '': operands.append(stmp); print(operands); #操作数修饰 operandCount = len(operands); operandString = []; #数字如1/7要转化成Fraction('1/7')这种样式才可以算出正确结果,引号不可以少掉。 for j in range(operandCount): stmp = ''; stmp = 'Fraction(\''+operands[j]+'\')'; operandString.append(stmp); #组装新表达式 typechange = 1; index = 0; expression = ''; for j in range(expCount): #操作符直接添加 if isOps(lines[i][j]): #记录操作符 OpsArray.append(lines[i][j]); expression+=lines[i][j]; else: if j > 0 and typechange == 0 and isOps(lines[i][j-1]): typechange = 1; #从操作数序列中选择对应操作数。 if typechange == 1: if index > len(operandString): break; expression += operandString[index]; index+=1; typechange = 0; #设置打印格式 if noPercentExpr == True: if resultIsInt == True: s = '{0} = {1}'.format(originExpr,eval(expression)); else: s = '{0} = {1} = {2}'.format(originExpr,eval(expression), floatResult); else: if resultIsInt == True: s = '{0} = {1} = {2}%'.format(originExpr,eval(expression),percentResult); else: s = '{0} = {1} = {2} = {3}%'.format(originExpr,eval(expression), floatResult, percentResult); print(s, end=', '); fout.write(s + ', '); print('\n'); fout.write('\n'); except: traceback.print_exc(); # ex = '{0} 表达式有误,无法进行计算。'.format(lines[i]); #print(ex); #fout.write(ex); fout.write('\n'); fout.close(); fin.close(); def isOps(c): if c == '+' or c == '-' or c == '/' or c == '*' or c == '(' or c ==')': return 1; else: return 0; if __name__ == '__main__': calc();
为什么这样说呢,打个比方,如果1*10%, 和1/10%,这个百分号的作用可不是一样呢。
不管怎么说,神器出炉,以后涉及到百分数的运算就是浮云了。
3/5 = 3/5 = 0.6 = 60%, 4/6 = 2/3 = 0.667 = 66.667%,
<span style="font-size: 18px;">1/5 = 1/5 = 0.2 = 20%, 4/5 = 4/5 = 0.8 = 80%, 1/14 = 1/14 = 0.071 = 7.143%, </span>
<span style="font-size:18px;">1-2700/4350 = 11/29 = 0.379 = 37.931%, 1600/40% = 4000, 1600/40%-1600 = 2400, (5*4*3-3*3*3)/(5*4*3) = 11/20 = 0.55 = 55%, </span>