В этой статье разберем, как можно создать калькулятор на языке программирования Python. Сначала напишем несколько консольных вариантов, а потом создадим парочку калькуляторов с графическим интерфейсом.
Подготовка
Прежде чем начинать работу по созданию калькулятора необходимо подготовить средства разработки. Все исходники, которые будут приведены ниже рекомендуется запускать в виртуальном окружении. Поэтому будет полезно ознакомится с этой статьей. В ней есть вся необходимая информация по созданию и использованию виртуального окружения Python venv.
В качестве интегрированной среды разработки (IDE) идеально подойдет PyCharm или наша отечественная OpenIDE с плагином для разработки на Python. Подробнее об установке PyCharm и создании проекта можно прочитать в соответствующем разделе этой публикации. Так как OpenIDE основана на той же платформе, что и PyCharm, то устанавливается она тем же способом. Плагин под названием Python Community Edition можно найти в маркетплейсе:

Источник: автор статьи
Как видно, у нас он уже установлен. Проект также создается похожим способом, что и в PyCharm. Переходим в раздел «Проекты» и нажимаем там на кнопку «Новый проект». Выбираем в левой части окна пункт «Python»:

Источник: автор статьи
В правой части окна указываем имя и местоположение проекта, а также выбираем интерпретатор. Нажимаем на кнопку «Создать» и видим следующее:

Источник: автор статьи
Проект создан, но без файла скрипта. Чтобы его добавить надо в верхней части левой панели нажать на значок плюса и в появившемся меню выбрать пункт «Файл Python». Далее в открывшемся окне следует ввести имя файла и нажать Enter. Должно получиться примерно так:

Источник: автор статьи
Вот теперь все готово! Сначала мы займемся созданием консольных калькуляторов, то есть таких калькуляторов, которые работают в командной строке, без графического интерфейса пользователя. А после перейдем к калькуляторам с графическим интерфейсом на Tkinter.
Консольные калькуляторы
Начнем с самого простого варианта.
Калькулятор с выводом результатов сразу четырех действий
Этот вариант калькулятора запрашивает у пользователя два числа и выводит в качестве результата их сумму, разность, произведение и частное. Вот так выглядит исходный код этого калькулятора:
number1 = float(input("Введите первое число: "))
number2 = float(input("Введите второе число: "))
print("Сумма: "+str(number1+number2)+"\nРазность: "+str(number1-number2)+"\nПроизведение: "+str(number1*number2)+"\nЧастное: "+str(number1/number2))
Запрос чисел происходит при помощи функции input. Эта функция выводит в консоли текст, который указывается в качестве ее аргумента и возвращает строку, которую ввел пользователь. Так как нам нужны числа, а не строки, то посредством функции float эти строки превращаются в числа с плавающей точкой. Результат вычислений выводится с помощью функции print. Функция str нужна для превращения чисел обратно в строки. Пример работы программы:
Введите первое число: 4 Введите второе число: 2 Сумма: 6.0 Разность: 2.0 Произведение: 8.0 Частное: 2.0
Калькулятор с выбором действий
Этот калькулятор предлагает после ввода первого числа выбрать одно из четырех арифметических действий. Потом предлагает ввести второе число и далее показывает результат. Код:
number1 = float(input("Введите первое число: "))
operation = input("Выберите операцию (+, -, * или /): ")
number2 = float(input("Введите второе число: "))
if operation == "+":
result = number1 + number2
elif operation == "-":
result = number1 - number2
elif operation == "*":
result = number1 * number2
elif operation == "/":
result = number1 / number2
else:
print("Неверная операция!")
print("Результат:", result)
Выбранное пользователем действие записывается в переменную operation. Далее с помощью условного оператора if – elif – else выбирается нужный вариант вычисления результата, который присваивается переменной result. Пример работы данного калькулятора:
Введите первое число: 14 Выберите операцию (+, -, * или /): + Введите второе число: 6 Результат: 20.0
Строковый калькулятор
Данный калькулятор позволяет пользователю вводить сразу все арифметическое выражение за один раз. Вычисления производятся с учетом порядка действий. Достигается это благодаря использованию функции eval. Код выглядит следующим образом:
expression = input("Введите выражение:\n")
try:
result = eval(expression)
print(result)
except Exception as ex:
print(ex)
Функция eval умеет не только вычислять значения арифметических выражений, но и выполнять любой произвольный код на языке Python, поэтому следует пользоваться этой функцией с осторожностью! Конструкция try – except, внутри которой вызывается eval предназначена для обработки возможных исключений. Пример работы калькулятора:
Введите выражение: 2+2*2 6
Теперь поместим 2+2 в скобочки:
Введите выражение: (2+2)*2 8
Ответ верный. Теперь попробуем разделить какое-нибудь число на ноль:
Введите выражение: 6/0 division by zero
Получили исключение с сообщением о делении на ноль. Далее рассмотрим парочку калькуляторов с графическим интерфейсом.
Калькуляторы с графическим интерфейсом пользователя
Создавать графический интерфейс будем на Tkinter. Tkinter — это достаточно популярная и простая в использовании библиотека графических компонентов. В ней есть все необходимое: кнопки, текстовые метки, поля для ввода текста и многое другое.
Строковый калькулятор на Tkinter
Чтобы использовать библиотеку Tkinter в своем проекте ее сначала надо импортировать. Поэтому в самом начале исходника следует прописать следующее:
from tkinter import *
Если библиотека не установлена в виртуальном окружении, то среда предложит ее установить. После установки библиотеки создаем виджет верхнего уровня (окно) и задаем ему заголовок:
root = Tk()
root.title("Калькулятор")
Интерфейс будет состоять всего из трех компонентов. Для ввода выражения мы используем поле для ввода текста Entry. Для вывода результата вычислений послужит текстовая метка Label, а для запуска процесса вычислений идеально подойдет кнопка Button.
Все эти компоненты надо как-то расположить относительно друг друга. Для компоновки мы используем виджет Frame. Frame — это такой виджет представляющий из себя контейнер, в который можно помещать другие виджеты. Создадим два таких контейнера:
frame_1 = Frame() frame_2 = Frame()
Далее создаем наши компоненты:
calc_entry = Entry(frame_1) calculate_button = Button(frame_1, text='Вычислить', command=on_calculate) result_label = Label(frame_2)
Для каждого компонента первым параметром указываем контейнер, где он будет расположен. Для кнопки также прописываем отображаемый на ней текст и имя функции, которая будет запускаться при нажатии. Следующим шагом упаковываем наши контейнеры:
frame_1.pack() frame_2.pack()
Но это еще не все. На следующим этапе надо указать для каждого компонента его расположение в контейнерах:
calc_entry.pack(side=LEFT) calculate_button.pack(side=RIGHT) result_label.pack(side=BOTTOM)
Как видим, поле ввода располагается слева, кнопка — справа, а текстовая метка снизу. Интерфейс готов! Осталось только запустить главный цикл приложения:
root.mainloop()
Теперь о функции вычисления результата. Она примерно такая же, что и в консольном варианте:
def on_calculate():
if calc_entry.index("end") == 0:
result_label.config(text="Введите выражение!")
return
expression = calc_entry.get()
try:
result = eval(expression)
except Exception as ex:
result_label.config(text=ex)
return
result_label.config
В самом начале происходит проверка поля на пустоту с выводом соответствующего сообщения, если оно окажется пустым. А дальше идет уже знакомая нам функция eval с обработкой исключений. Функцию on_calculate размещаем сразу после импорта библиотеки. Весь код калькулятора будет такой:
from tkinter import *
def on_calculate():
if calc_entry.index("end") == 0:
result_label.config(text="Введите выражение!")
return
expression = calc_entry.get()
try:
result = eval(expression)
except Exception as ex:
result_label.config(text=ex)
return
result_label.config(text=result)
root = Tk()
root.title("Калькулятор")
frame_1 = Frame()
frame_2 = Frame()
calc_entry = Entry(frame_1)
calculate_button = Button(frame_1, text='Вычислить', command=on_calculate)
result_label = Label(frame_2)
frame_1.pack()
frame_2.pack()
calc_entry.pack(side=LEFT)
calculate_button.pack(side=RIGHT)
result_label.pack(side=BOTTOM)
root.mainloop()
Запустим и проверим его работу:

Источник: автор статьи
Калькулятор работает! Идем дальше.
Кнопочный калькулятор на Tkinter
Здесь, также как и в случае со строковым калькулятором, сначала необходимо импортировать библиотеку и создать окно с заголовком:
from tkinter import *
root = Tk()
root.title("Калькулятор")
Далее создаем поле для отображения вводимых выражений и результатов. В качестве этого поля используем виджет Entry:
calc_entry = Entry(width=45)
Параметр width со значением 45 устанавливает ширину поля. Для расположения компонентов относительно друг друга в нашем случае отлично подойдет метод grid. Он располагает виджеты в виде сетки и при помощи параметров row (строка) и column (столбец) позволяет указать нужную ячейку, где будет размещаться виджет. Для нашего поля применение этого метода будет выглядеть так:
calc_entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)
Как видим, наше поле должно быть расположено в ячейке находящейся на нулевой строке и в нулевом столбце. Это левый и верхний угол сетки. Параметр columnspan задает количество столбцов, которые должен занимать компонент. Так что в нашем случае поле растянется сразу на четыре ячейки. Но так как для него жестко прописан параметр ширины, то поле просто займет среднюю позицию в нулевой строке сетки. Параметры padx и pady устанавливают горизонтальные и вертикальные отступы от границ ячейки до границ компонента.
Далее создадим список кнопок:
buttons = [
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', 'C', '+'
]
На следующем шаге установим начальные значения для строк и столбцов:
row = 1 col = 0
И теперь запускаем цикл, который расставит кнопки из списка по своим местам:
for button in buttons:
if button == 'C':
Button(text=button, padx=40, pady=20, command=click_on_button_clear).grid(row=row, column=col)
else:
Button(text=button, padx=40, pady=20, command=lambda x=button: click_on_button(x)).grid(row=row, column=col)
col += 1
if col > 3:
col = 0
row += 1
При помощи параметра command привязываем к кнопкам пока еще не написанные функции. В конце каждой итерации значение переменной col увеличивается на единицу, но когда оно становится больше трех, значение переменной обнуляется, при этом увеличивается на единицу переменная row. И таким нехитрым способом наши кнопки выстраиваются нужным нам образом. Но не хватает кнопки со знаком «равно». Разместим ее в самом низу:
Button(text="=", padx=80, pady=20, command=click_on_button_equal).grid(row=5, column=1, columnspan=2)
С интерфейсом закончили. Запускаем главный цикл приложения:
root.mainloop()
Теперь займемся функциями. Как видно из вышеприведенных фрагментов кода, их у нас будет три. Первая функция, которую мы рассмотрим — это click_on_button. Она привязана к большинству кнопок и служит для ввода выражений:
def click_on_button(number): current = calc_entry.get() calc_entry.delete(0, END) calc_entry.insert(0, str(current) + str(number))
В переменной current хранится текущее содержимое поля ввода. При помощи функции insert в поле добавляются новые символы. Следующая функция — click_on_button_clear:
def click_on_button_clear(): calc_entry.delete(0, END)
Срабатывает при нажатии на кнопку «C» и очищает поле от всего содержимого с помощью функции delete. Третья функция — click_on_button_equal:
def click_on_button_equal(): try: result = eval(calc_entry.get()) calc_entry.delete(0, END) calc_entry.insert(0, result) except Exception as ex: calc_entry.delete(0, END) calc_entry.insert(0, ex)
Вызывается при нажатии на кнопку «равно». Вычисления производятся посредством функции eval. Весь код калькулятора получается такой:
from tkinter import *
def click_on_button(number):
current = calc_entry.get()
calc_entry.delete(0, END)
calc_entry.insert(0, str(current) + str(number))
def click_on_button_clear():
calc_entry.delete(0, END)
def click_on_button_equal():
try:
result = eval(calc_entry.get())
calc_entry.delete(0, END)
calc_entry.insert(0, result)
except Exception as ex:
calc_entry.delete(0, END)
calc_entry.insert(0, ex)
root = Tk()
root.title("Калькулятор")
calc_entry = Entry(width=45)
calc_entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)
buttons = [
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', 'C', '+'
]
row = 1
col = 0
for button in buttons:
if button == 'C':
Button(text=button, padx=40, pady=20, command=click_on_button_clear).grid(row=row, column=col)
else:
Button(text=button, padx=40, pady=20, command=lambda x=button: click_on_button(x)).grid(row=row, column=col)
col += 1
if col > 3:
col = 0
row += 1
Button(text="=", padx=80, pady=20, command=click_on_button_equal).grid(row=5, column=1, columnspan=2)
root.mainloop()
А выглядит наш калькулятор следующим образом:

Источник: автор статьи
Проверим его в работе. Введем какое-нибудь выражение:

Источник: автор статьи
И нажмем на кнопку равно:

Источник: автор статьи
Получили верный ответ. Калькулятор работает.
Задания для самостоятельного выполнения
Задание №1
В первых двух консольных калькуляторах не учитывается деление на ноль. Дополните код таким образом, чтобы это деление учитывалось и пользователь получал соответствующее сообщение.
Решение задания №1
Для калькулятора выводящего результаты сразу четырех действий можно ввести новую переменную, специально предназначенную для результатов деления. Если второе число равно нулю, то в переменную записывается сообщение о том, что на ноль делить нельзя. В противном случае переменной присваивается результат деления.
number1 = float(input("Введите первое число: "))
number2 = float(input("Введите второе число: "))
if number2 == 0:
result_division = "На ноль делить нельзя!"
else:
result_division = str(number1/number2)
print("Сумма: "+str(number1+number2)+"\nРазность: "+str(number1-number2)+"\nПроизведение: "+str(number1*number2)+"\nЧастное: "+result_division)
Пример работы:
Введите первое число: 4 Введите второе число: 0 Сумма: 4.0 Разность: 4.0 Произведение: 0.0 Частное: На ноль делить нельзя!
Для калькулятора с выбором действия можно действовать похожим образом, но переменную там создавать не нужно:
number1 = float(input("Введите первое число: "))
operation = input("Выберите операцию (+, -, * или /): ")
number2 = float(input("Введите второе число: "))
if operation == "+":
result = number1 + number2
elif operation == "-":
result = number1 * number2
elif operation == "*":
result = number1 * number2
elif operation == "/":
if number2 == 0:
result = "На ноль делить нельзя!"
else:
result = number1 / number2
else:
print("Неверная операция!")
print("Результат:", result)
Пример работы:
Введите первое число: 12 Выберите операцию (+, -, * или /): / Введите второе число: 0 Результат: На ноль делить нельзя!
Задание №2
Измените код консольного строкового калькулятора так, чтобы после совершения операции он задавал пользователю вопрос о продолжении или завершении работы по типу «Продолжить? д/н».
Решение задания №2
А здесь нам поможет цикл while. Весь код калькулятора расположим внутри цикла. Создадим переменную answer, в которой будет храниться ответ на вопрос о завершении или продолжении работы калькулятора. Вопрос задается при помощи функции input. В самом конце пропишем условие выхода из цикла.
while True:
expression = input("Введите выражение:\n")
try:
result = eval(expression)
print(result)
except Exception as ex:
print(ex)
answer = input("Продолжить? д/н\n")
if answer != "д" and answer != "y":
break
Пример работы калькулятора без продолжения:
Введите выражение: 5+15 20 Продолжить? д/н н Процесс завершен с кодом выхода 0
А это пример работы с продолжением:
Введите выражение: 4+12 16 Продолжить? д/н д Введите выражение: 17-9
