[从头学数学] 第95节 百分数(一)

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入练气期第十一层功法的修炼,
这次要修炼的目标是[百分数(一)]。

正剧开始:

星历2016年02月19日 12:09:48, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究百分数的运算。




对于百分数的读写,小伟也没有什么兴趣,因为就是对小数读写加了个百分号而已。

[从头学数学] 第95节 百分数(一)_第1张图片


恩格尔系数要不要计算一下呢,小伟想了想,还是算了,今天的小伟真的很懒。




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%, 

[从头学数学] 第95节 百分数(一)_第2张图片

<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>


[从头学数学] 第95节 百分数(一)_第3张图片

<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>


本节到此结束,欲知后事如何,请看下回分解。



你可能感兴趣的:([从头学数学] 第95节 百分数(一))