python简单的加法问题_3.14 用Python实现的简单加法器

3.14 用Python实现的简单加法器

感谢:Brett Cannon

任务

你想用Python制作一个简单的加法器,使用精确的十进制数(而不是二进制浮点数),并以整洁的纵列显示计算结果。

解决方案

为了执行计算,必须使用decimal模块。我们的程序接受输入行,每行由一个数字紧跟一个数学运算符组成,空行表示收到了计算当前结果的请求,输入q则表示结束当前程序:import decimal, re, operator

parse_input=re.compile(r'''(?x) # 允许RE中的注释和空白符

(\d+\.?\d*) # 带有可选的小数部分的数

\s* # 可选的空白符

([-+/*]) # 运算符

$''') # 字符串结束

oper= { '+': operator.add, '-': operator.sub,

'*': operator.mul, '/': operator.truediv,

}

total=decimal.Decimal('0')

def print_total( ):

print '== == =\n', total

print """Welcome to Adding Machine:

Enter a number and operator,

an empty line to see the current subtotal,

or q to quit: """

while True:

try:

tape_line=raw_input( ).strip( )

except EOFError:

tape_line='q'

if not tape_line:

print_total( )

continue

eliftape_line== 'q':

print_total( )

break

try:

num_text,op=parse_input.match(tape_line).groups( )

except AttributeError:

print 'Invalid entry: %r' % tape_line

print 'Enter number and operator,

empty line for total, q to quit'

continue

total=oper[op](total, decimal.Decimal(num_text))

讨论

Python的交互式解释器是很有用的计算器,但一个简单的"加法器"也还是有用的。举个例子,像2345634+2894756-2345823这样的表达式很不易读,所以检查用于计算的输入数字并不像想象的那么简单。而一个简单的加法器可以用一种很整洁的、纵列的方式显示数字,这样可以很容易地多次检查你的输入。另外,decimal模块使用一种基于十进制的计算方式,那也正是我们需要的,我们很多时候并不需要科学家、工程师或计算机所偏爱的浮点数学计算。

当在命令行shell下运行此脚本时(此脚本并不是为在Python交互式解释器中运行而设计的),它会给出使用提示,然后一直等待输入。可以敲入一个数字(一位或者多位数字,加上一个可选的小数点,然后是可选的小数位数字),紧跟一个运算符(/、*、-和+,这4个字符可以在键盘的数字区找到),然后回车。脚本会根据运算符将输入的数计入到总数中。当你输入空行时,程序将打印出当前的计算结果。当输入q并回车时,程序会退出。这种简单的输入输出的界面符合一个典型的简单加法器的需求。

decimal包是Python 2.4标准库的一个组成部分。如果你使用Python 2.3,请访问http://www.taniquetil.com.ar/facundo/bdvfiles/get_decimal.html,下载并安装这个包。decimal可支持高精度的十进制数学运算,相比于二进制浮点运算,它的应用面更加广泛(比如涉及财务的计算),当然浮点运算是计算机上速度最快的运算,也是Python默认的运算方式。你再也无须花费时间和精力去学习难于理解的二进制浮点运算。如3.13节所示,可以将默认的截断规则ROUND_HALF_EVEN按需求修改成其他规则。

本节的代码非常简单,也有很多可以提升性能的地方。一个有用的加强方法是,将外界输入记录到硬盘以备查用。可以简单地做到这一点-只需要在循环之前加一条语句,打开一个文本文件以供添加信息:tapefile=open('tapefile.txt', 'a')

然后,在获得tape_line的值的try/except语句之后,加一条语句以便将值写入文件之中:tapefile.write(tape_line+'\n')

如果做了上面这些操作,也许你还想继续加强print_total函数,使得它既能够输出信息到命令行窗口,同时还能将信息写入到文件中。因此,该函数可以被修改为:def print_total( ):

print '==== =\n', total

tapefile.write('==== =\n' + str(total) + '\n')

file对象的write方法接受一个字符串作为参数,但是并不默认地在字符串末尾加上换行,这和print语句的行为方式有些不同,所以我们要明确地调用内建的str函数,明确地在末尾增加了一个'\n'。***,此版本的print_total函数的第二条语句还可以被改写为:print>>tapefile, '==== =\n', total

有些人非常讨厌这种print >>> somefile的语法,但有时这种写法真的很方便,上面的应用就是一个例子。

还有一些可能的改进,比如现在每次输入完运算符之后都需要按回车键,进一步的改进可以不用按回车就直接进行处理(不过这意味着我们需要处理无缓冲的输入,并且每次要单个处理一个字符,而不能使用方便的基于行的内建函数raw_input,可以参考2.23节提供的一种跨平台的处理无缓冲输入的方法),再比如增加一个clear函数(或者增加提示功能,如果用户输入0*会把结果清空成0),甚至给这个加法器增加一个GUI外壳。不过,我准备把这些部分留给读者作为练习。

本节实现中非常重要的一点是oper字典,它用运算符(/、*、-和+)作为键,用内建的operator模块中的数学运算函数作为键的对应值。这个功能也可以用更冗长一点的方法实现,比如,一长串if/elif,如下:ifop== '+':

totaltotal= total + decimal.Decimal(num_text)

elifop== '-':

totaltotal= total - decimal.Decimal(num_text)

elifop== '*':

... and so on ...

不过,Python的字典用法明显更理想也更方便,而且不会产生重复性的代码,也更容易维护。

更多资料

【责任编辑:云霞 TEL:(010)68476606】

点赞 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值