[英]Pythonic way to write calculate function for a calculator - Python
I am creating a text calculator that does not work completely conventionally. 我正在创建一个文本计算器,它不能完全按常规方式工作。 It works like this:
它是这样的:
+
for addition, -
for subtraction, *
for multiplication, or /
for division) +
用于加法, -
用于减法, *
用于乘法,或/
用于除法) Calculation: 计算方式:
When a user enters in more than two operands , instead of doing: 当用户输入两个以上的操作数时 ,而不是这样做:
operand1 plus/minus/times/divided by operand2
, operand1 plus/minus/times/divided by operand2
,
It does: 它确实:
operand1 plus/minus/times/divided by operand2 plus/minus/times/divided by operand3
, operand1 plus/minus/times/divided by operand2 plus/minus/times/divided by operand3
,
And so on for all of the inputted operands. 对于所有输入的操作数,依此类推。
The code for this simply loops through the list of inputted operands, operandList
, and uses the chosen operation, operation
(and result
is the result of the calculation): 用于此的代码仅循环遍历输入操作数的列表
operandList
,并使用所选的操作, operation
( result
是计算的结果):
def Calculate():
global operation, operandList, result
operateCount = 0
result = 0
while operateCount < len(operandList):
if operation == '+':
result += operandList[operateCount]
elif operation == '-':
result -= operandList[operateCount]
elif operation == '*':
result *= operandList[operateCount]
elif operation == '/':
result /= operandList[operateCount]
operateCount += 1
if operation == '+':
resultName = 'Sum'
elif operation == '-':
resultName = 'Difference'
elif operation == '*':
resultName = 'Product'
elif operation == '/':
resultName = 'Quotient'
if result.is_integer():
print(int(result), '=', resultName)
else:
print(result, '=', resultName)
print()
This is super inefficient because it checks for the operation twice, and once inside the while loop, which is even worse. 这是超级低效的,因为它两次检查操作,而一次在while循环中进行检查,这甚至更糟。
Obviously if I write one of those while loop blocks for each operation and begin each one with an if statement to check for the operation that is much worse. 显然,如果我为每个操作编写了while循环块之一,并以if语句开始每个循环,以检查更糟糕的操作。
If I did that you would see that the only difference between each block of code is the operation sign in result +,-,*,/= operandList[operateCount]
. 如果我这样做了,您会发现每个代码块之间的唯一区别是
result +,-,*,/= operandList[operateCount]
。
How can I: 我怎样才能:
result
? result
时检查操作的冗余代码? Any help is greatly appreciated. 任何帮助是极大的赞赏。 Please ask for specifications if necessary.
请根据需要索取规格。 And if you down vote, please comment your reason for doing so so I can make changes.
如果您投了反对票,请评论您这样做的理由,以便我进行更改。
The key idea is, build a dict
: 关键思想是构建一个
dict
:
import operator
ops = {
'+': (operator.add, 'Sum', 0),
'-': (operator.sub, 'Difference', 0),
'*': (operator.mul, 'Product', 1),
'/': (operator.truediv, 'Quotient', 1),
}
I'm associating to each operator symbols three items: the function to use, the name to use, and (which you seem to have ignored!) the "neutral" starting point. 我将与每个运算符相关的三个项目相关联:要使用的功能,要使用的名称和 (中性的)起点(您似乎已经忽略了!)。 Starting always at
0
as you do makes products and quotient risible -- multiply and divide by whatever, it doesn't matter, if it starts at 0
, it stays at 0
forever, you know!-) 总是从
0
开始,这样就使乘积和商变得更容易-除以任何乘积都没关系,如果它从0
开始,就永远保持在0
!
Now things get simpler...: 现在事情变得更简单了:
def Calculate():
global result
op, resultName, result = ops[operation]
for item in operandList:
result = op(result, item)
if result == int(result):
print(int(result), '=', resultName)
else:
print(result, '=', resultName)
print()
I have no idea why you're so inordinately fond of global
and messing with indexing without necessity. 我不知道为什么您如此狂热地喜欢
global
并且不必要地使用索引。 is_number
apparently is a method only of float
s and you're initializing result
to an int
, so it could crash the code -- I've replaced it with a sensible check. is_number
显然仅是float
的一种方法,并且您正在将result
初始化为int
,因此它可能使代码崩溃—我已将其替换为明智的检查。
No need for global
for names you're only using and not assigning -- and of course it would make sense to lose the global result
and instead return result
at the end; 您只需要使用而不是分配的
global
名称就不需要了-当然,丢失global result
并在最后return result
是有意义的; but I've left it in just in case there might be any sane reason to have it global (I can't think of any). 但我留给它的目的是,以防万一有任何理智的理由将它全局化(我想不到)。
But the core idea is: in Python, for dispatching purposes, think dict
first and foremost! 但是核心思想是:在Python中,出于调度目的,首先要考虑
dict
!
Added: OP asks peculiar questions in comments, such as "What exactly is the function of the import statement?" 补充:OP在注释中提出了一些特殊的问题,例如“ import语句的功能到底是什么?” -- answer, obviously, is "to make another module available" (in this case, module
operator
from Python's standard library, to get its functions performing addition, multiplication, and so forth). -显然,答案是“使另一个模块可用”(在这种情况下,是Python标准库中的模块
operator
,以使其功能执行加,乘等操作)。 Also "what is the 'neutral starting point'" -- answer, obviously, is "the initial value of result
before you start adding, multiplying and so on. 另外,“什么是'中性起点'”-显然,答案是“开始加,乘等等之前
result
的初始值。
In the OP's original code in the Q, result
was unconditionally initialized to zero. 在OP的原始代码Q中,
result
被无条件初始化为零。 If you start with zero and multiply it by whatever number(s), it stays zero -- it's not a "neutral" starting point for a series of multiplication, it's more of a "fixed" point, a "black hole" in a sense. 如果您从零开始并乘以任何数字,它将保持为零-这不是一系列乘法的“中立”起点,它更像是“固定”点,即“黑洞”。感。 So, I used different initial values depending on the operation.
因此,我根据操作使用了不同的初始值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.