Calculator steps - калькулятор по шагам
1. Создание интерфейса
Для начала создадим минимально необходимый интерфейс:
Задание:
Названия переменных должны быть корректными:
- существующие английские слова;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание: "button_zero".
Создадим виджет Entry():
- реализовать отображение нуля;
- с параметром выравнивания текста по правому краю;
- виджет должен растягиваться по горизонтали на всю ширину окна.
Создадим виджет Entry():
- реализовать отображение нуля;
- с параметром выравнивания текста по правому краю;
- задать стиль шрифта "Helvetica 30 bold";
- виджет должен растягиваться по горизонтали на всю ширину окна.
Создадим две кнопки обозначающие "0" и "1".
Рекомендации:
Виждеты Entry() лучше растянуть на несколько колоном с запасом, чтобы не исправлять растяжение каждый раз при добавлении новых кнопок. В данном случае было задано заполнение на 15 колонок.
Создаем только интерфейс, реализация функциональности кнопок на данном этапе не требуется.
2. Реализация функциональности двух кнопок
Визуально в интерфейсе измениться лишь заголовок версии калькулятора:
Задание:
Названия функций должны быть корректными:
- существующие английские слова;
- название начинается всегда с глагола отражающие суть/смысл функции;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
Создать и подключить функцию для кнопки "1":
- функция должна допечатывать цифру "1" в оба поля Entry().
- реализовать проверку при которой не будет происходить набор цифр на табло вида: "011" и т.п.
Создать и подключить функцию для кнопки "0":
- функция должна допечатывать цифру "0" в оба поля Entry().
- реализовать проверку при которой не будет происходить набор цифр на табло вида: "000" и т.п.
Проверить работу кнопок: "0" и "1":
- правильные цифры вида: 1, 101, 1100 и т.п.
- неправильные цифры вида: 01, 00, 001 и т.п. набираться не должны.
- не допустимо выведение ошибок в консоли.
Рекомендации:
На начальном этапе создания для проверки факта вызова функции можно использовать команду: print().
Если функцию для кнопки один написана верно, то функцию для нуля можно, написать скопировав функцию один с минимальными изменениями:
- изменив имя функции;
- изменив цифру выводимую на экранах.
Не забудьте изменить версию в заголовке программы на "Calc v.02"
3. Clear - добавление кнопки очистки
На следующем шаге добавим кнопку обнуления наших полей:
Задание:
- добавить кнопку очистки - "С" и реализовать функцию очистки - обнуления результатов.
4. Plus - добавление кнопки плюс
Добавим кнопку плюс и реализуем функциональной кнопки:
Задание:
Названия функций должны быть корректными:
- существующие английские слова;
- название начинается всегда с глагола отражающие суть/смысл функции;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
добавить кнопку плюс - "+" и реализовать функциональность:
- создать функцию, которая будет допечатывать в виждете выражения, не более одного "+";
- без реализации вычисления введенного выражения.
доработать функции нуля и единицы. Добавить проверки для корректности набора выражения:
- допустимые выражения: 1+0+10+11 и т.п.
- недопустимые выражения: 00++01+001 и т.п.
- не допустимо выведение ошибок в консоли.
Рекомендации:
Функция плюс только проверяет наличие в конце знака "+":
- если выражение заканчивается цифрой, то "+" доставляется в конец строки;
- если выражение заканчивается "+", то стирается "+" в конце исходного выражения, и "+" доставляется в конце строки;
Функции нуля и единицы, лучше дорабатывать добиваясь максимальной идентичности тела функции. На данном шаге различие тел функций можно свести только к разнице доставляемых "0" или "1".
В дальнейшем ещё планируется добавление цифр, поэтому колонка для размещения плюса указана 10.
На данном этапе калькулятор реализует только четыре функции:
- функция "нажата_очистка";
- функция "нажата_ноль";
- функция "нажата_один";
- функция "нажат_плюс".
5. Eval() - вычисляем выражение
Теперь будут вычисления:
Функция eval()
- позволяет вычислить значение примера переданного в виде строки:
answer = eval("3+3*3")
print(answer) # 12
answer = eval("4-3/2")
print(answer) # 2.5
2
3
4
Задание:
- Используя функцию eval(), доработайте функцию плюса:
- будет браться выражение из верхнего виджета;
- вычисляться;
- ответ выводиться в основной цифровой дисплей при нажатии кнопки "+".
- не допустимо выведение ошибок в консоли.
6. Equal - равно
Добавляем кнопку равно:
Задание:
Названия функций и переменных должны быть корректными:
- существующие английские слова;
- название функции всегда начинается с глагола отражающие суть/смысл функции;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
На основе функции "+" создаем функцию "=" с минимальными изменениями. В идеале они должны отличаться только знаком. При необходимости доработайте обе функции.
Прикрепите функцию "равно" к кнопке "=".
Проверьте корректность работы калькулятора:
- допустим ввод выражения: 11+10+1= и т.п. и выводом результата в основной цифровой дисплей: 22 и т.п.
- не допустим ввод выражения: 01++00=+01+= и т.п.
- не допустимо выведение ошибок в консоли.
На данном этапе калькулятор реализует пять функции:
- функция "нажата_очистка()";
- функция "нажата_ноль()";
- функция "нажата_один()";
- функция "нажат_плюс()";
- функция "нажато_равно()".
7. Division - деление
Добавляем кнопку деление:
Задание:
Названия функций и переменных должны быть корректными:
- существующие английские слова;
- название функции всегда начинается с глагола отражающие суть/смысл функции;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
На основе функции "+" или "=" создаем функцию "/" с минимальными изменениями. В идеале они должны отличаться только знаком. При необходимости доработайте функции.
Прикрепите функцию "равно" к кнопке "/".
Проверьте корректность работы калькулятора:
- допустим ввод выражения: 11+10/1= и т.п. и выводом результата в основной цифровой дисплей: 22 и т.п.
- не допустим ввод выражения: 01++/00=//01+=10//= и т.п.
- выведение ошибок в консоли допустимо только при вводе примера с делением на ноль вида: 1/0= и т.п.
На данном этапе калькулятор реализует функции:
- функция "нажата_очистка()";
- функция "нажата_ноль()";
- функция "нажата_один()";
- функция "нажат_плюс()";
- функция "нажато_деление()";
- функция "нажато_равно()".
8. Функция "нажато_число(число)" с параметром
Визуальные изменения будут следующие:
Функция с параметром number
имеет вид:
def print_parametr(number):
print(number)
2
Создадим дополнительную пробную программку вида:
Пример печати номера нажатой кнопки может быть следующим:
from tkinter import *
from tkinter.ttk import *
def click_one():
print(1, end=" ")
def click_two():
print(2, end=" ")
root = Tk()
Button(text="1", command=click_one).pack(side=LEFT)
Button(text="2", command=click_two).pack(side=LEFT)
root.mainloop()
2
3
4
5
6
7
8
9
10
11
12
13
Результат в зависимости последовательности от нажатия кнопок может быть:
1 2 2 1 2
Подобное поведение можно реализовать с помощью функции с параметром и lambda-функции
:
from tkinter import *
from tkinter.ttk import *
def click(number):
print(number, end=" ")
root = Tk()
Button(text="1", command=lambda: click(1)).pack(side=LEFT)
Button(text="2", command=lambda: click(2)).pack(side=LEFT)
root.mainloop()
2
3
4
5
6
7
8
9
10
Результат поведения будет подобен предыдущему коду:
1 2 2 1 2
Задание:
Названия функций и переменных должны быть корректными:
- существующие английские слова;
- название функции всегда начинается с глагола отражающие суть/смысл функции;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
На основе функции "1" создаем функцию с параметром, например: click_number(number). В том месте где явно выводили "1" на печать, заменяем параметром
number
Заменяем в кнопках "0" и "1" вызов функции на функцию с параметром добавив в скобках вызова нужное число.
Комментируем функции: "нажата_ноль()" и "нажата_один()"
Проверяем правильность работы калькулятора. Появление ошибок в консоли допустимо только при вводе примера с делением на ноль вида: 1/0= и т.п.
Добавляем кнопку "2" и подключаем к функцию с параметром.
Проверяем ещё раз. Работа нарушаться не должна.
Если все работает верно. Удаляем закомментированный ранее код.
На данном этапе калькулятор реализует функции:
- функция "нажата_очистка()";
- функция "нажата_цифра(цифра)";
- функция "нажат_плюс()";
- функция "нажато_деление()";
- функция "нажато_равно()".
9. Функция "нажат_знак(знак)" с параметром
Визуальные изменения будут следующие:
Задание:
Названия функций и переменных должны быть корректными:
- существующие английские слова;
- название функции всегда начинается с глагола отражающие суть/смысл функции;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание: "click_zero".
На основе функции "+" создаем функцию с параметром, например: click_sign(sign). В том месте где явно выводили "+" на печать, заменяем параметром
sing
.Заменяем в кнопках "+" и "/" вызов функции на функцию с параметром добавив в скобках вызова нужный символ.
Комментируем функции: "нажат_плюс()" и "нажато_деление()"
Проверяем правильность работы калькулятора. Появление ошибок в консоли допустимо, за исключением примера с делением на ноль вида: 1/0= и т.п.
Исправляем кнопку "=" и подключаем к функцию с параметром.
Проверяем ещё раз. Работа нарушаться не должна.
Если все работает верно. Удаляем закомментированный ранее код.
На данном этапе калькулятор реализует функции:
- функция "нажата_очистка()";
- функция "нажата_цифра(цифра)";
- функция "нажат_знак(знак)".
10. Проверка деления на ноль
Следующая версия:
Задание:
Проверку необходимо реализовывать только для строки кода в которой возможно возникновение ошибки, т.е. для единственной строки где вызывается функция
eval()
.Реализовать проверку, используя конструкцию:
try-except
. При делении на ноль можно выводить надпись на цифровом экране: "Cannot divide by zero".Доработать функцию нажатия цифр, что бы после выведения ошибки деления на ноль можно было корректно проводить новые вычисления.
Тип отлавливаемой ошибки лучше указывать явно. В случае "деления на ноль" - это пит ошибки
ZeroDivisionError
.Проверяем правильность работы калькулятора:
- недопустимые выражения: Cannot divide by zero0, Cannot divide by zero+ и т.п.
- не допустимо выведение ошибок в консоли.
Рекомендации:
- Реализовать проверку "деления на ноль" используя конструкцию
if... else
, вместоtry-except
.
На данном этапе калькулятор реализует функции:
- функция "нажата_очистка()";
- функция "нажата_цифра(цифра)";
- функция "нажат_знак(знак)".
11. Генерация кнопок с числами
Создадим дополнительную пробную программку вида:
Используя цикл и подключенную lambda-функции
получим следующий код:
from tkinter import *
from tkinter.ttk import *
def click(number):
print(number, end=" ")
root = Tk()
for i in range(5):
Button(text=i, command=lambda: click(i)).pack(side=LEFT)
root.mainloop()
2
3
4
5
6
7
8
9
10
При нажатии кнопок по порядку в консоль выводиться только "4". Переменная i
- динамическая, и цикле изменяет свое значение с 0 до 4. После генерации всех кнопок последнее значение i=4, поэтому после запуска программы, при нажатии на любые сгенерированные кнопки в консоль выводятся только "4":
4 4 4 4 4
Для внутреннего сохранения (связывания) значения i
момент генерации определенной кнопки, используется lambda-функция
с параметром:
from tkinter import *
from tkinter.ttk import *
def click(number):
print(number, end=" ")
root = Tk()
for i in range(5):
Button(text=i, command=lambda num=i: click(num)).pack(side=LEFT)
root.mainloop()
2
3
4
5
6
7
8
9
10
Результат нажатия кнопок по порядку:
1 2 3 4 5
Добавим дополнительный ряд кнопок с числами, преобразуем визуально:
Задание:
Сгенерировать кнопки используя "лямбда-функцию" с параметром.
Проверяем правильность работы калькулятора:
- выражение и числа должны вводиться и выводиться корректно.
- появление ошибок в консоли допустимо.
12. Генерация кнопок с математическими знаками
Добавим ряд кнопок со знаками:
Задание:
Сгенерировать базовых математических операций: "+", "-", "*", "/", используя "лямбда-функцию" с параметром.
Реализовать функциональность кнопок, внесите необходимые изменения в функции нажатия цифровых кнопок и кнопок математических операций.
Проверяем правильность работы калькулятора:
- выражение и числа должны вводиться и выводиться корректно.
- появление ошибок в консоли допустимо.
13. Дальнейше развитие
Задание:
Добавить кнопку "." и реализовать её функциональность.
Добавить кнопку стирания последней набранной цифры.
Добавить генерацию кнопок расширенных математических операций. Реализовать функциональность кнопок.
Добавить привязку нажатие клавиш на клавиатуре к соответствующим кнопкам калькулятора.
Реализовать полную генерацию разных интерфейсов на массива.
Создать свою функцию вычисления примеров в замен функции eval().
Рекомендации:
Для кнопки "." лучше использовать функцию чисел.
Полную генерацию кнопок интерфейса можно реализовать передав кнопки в виде двумерного массива.
Полностью реализуйте функциональность калькулятора. Программа должна стать законченным проектом.