Что-то часто в последнее время стали попадаться просьбы помочь с написанием калькуляторов. Наверно, в школах это задают, не знаю. Обычно эти все калькуляторы имеют примерно такой вид:
В принципе, это неплохо, орлята учатся летать. Но, на мой взгляд, можно, не сильно усложняя программу, сделать эту задачу поинтереснее.
Когда-то давно, на закате СССР, в ходу были замечательные калькуляторы, "Электроника МК-61". У них было много чудесных свойств, о которых даже есть отдельная статья в википедии, но я бы хотел напомнить одно, важное в контексте обсуждаемого вопроса. Это свойство - обратная польская запись при проведении вычислений.
В обычном калькуляторе, если нам надо сложить, скажем, 23+45, мы делаем так:
- набираем число "23"
- нажимаем кнопку операции сложения "+"
- набираем число "45"
- нажимаем "=" и получаем ответ.
А в тех калькуляторах был стек (на пять чисел, если правильно помню) и кнопка "В↑", предшественница современного "Enter↵". Поэтому чтобы сложить 23 и 45, требовалось поступить так:
- набираем число "23", оно автоматически заносится в стек
- нажимаем кнопку "В↑", при этом число 23 передвигается "вглубь" стека
- набираем число "45", оно автоматически заносится в стек
- нажимаем кнопку операции сложения "+", при этом последнее число извлекается из стека, прибавляется к бывшему предпоследнему, и этот получившийся результат выводится на экран.
Но к чему такие сложности, спросите вы. А вот к чему. Дело в том, что обратная польская запись позволяет, не вдаваясь синтаксический анализ и расстановку скобок, обсчитывать достаточно сложные выражения. Например, чтобы посчитать выражение 12*(34-45)+67/89, достаточно ввести следующие команды:
"67", "В↑", "89", "/", "В↑", "34", "В↑", "45", "-", "В↑", "12", "*", "+"
Смысл их довольно прост:
Как видим, используя обратную польскую запись наш простейший калькулятор можно превратить в сравнительно мощный инструмент. Осталось только реализовать это на Python.
Делается это просто и никаких дополнительных знаний, помимо ветвлений и циклов не требует.
И тогда результат работы этой программы, например, по вычислению вышеприведенного выражения 12*(34-45)+67/89 будет таким:
Содержимое стека:
A = 0.0 <- результат последнего вычисления
B = 0.0
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): 67
Содержимое стека:
A = 67.0 <- результат последнего вычисления
B = 0.0
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): 89
Содержимое стека:
A = 89.0 <- результат последнего вычисления
B = 67.0
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): /
Содержимое стека:
A = 0.7528089887640449 <- результат последнего вычисления
B = 0.0
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): 34
Содержимое стека:
A = 34.0 <- результат последнего вычисления
B = 0.7528089887640449
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): 45
Содержимое стека:
A = 45.0 <- результат последнего вычисления
B = 34.0
C = 0.7528089887640449
D = 0.0
E = 0.0
Введите число или команду (q - выход): -
Содержимое стека:
A = -11.0 <- результат последнего вычисления
B = 0.7528089887640449
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): 12
Содержимое стека:
A = 12.0 <- результат последнего вычисления
B = -11.0
C = 0.7528089887640449
D = 0.0
E = 0.0
Введите число или команду (q - выход): *
Содержимое стека:
A = -132.0 <- результат последнего вычисления
B = 0.7528089887640449
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): +
Содержимое стека:
A = -131.24719101123594 <- результат последнего вычисления
B = 0.0
C = 0.0
D = 0.0
E = 0.0
Введите число или команду (q - выход): q
Разумеется, этот вариант калькулятора - из тех задач, что в учебниках помечаются звёздочкой, но, думается, лишь из-за необходимости "врубиться" в обратную польскую запись. Ну и, конечно, программку можно будет сделать ещё гибче и компактнее, когда дело дойдёт до списков и обработки исключений.