практические работы по питону. МУ_ИНФОРМАТИКА_ПРОГРАММИРОВАНИЕ_ПИТОН Коренюгина_2021. Методические указания по подготовке к практическим занятиям, в том числе в интерактивной форме, и самостоятельному изучению дисциплины для школьников 911 классов общеобразовательных средних учебных заведений
![]()
|
= не создаѐт копию словаря. Он присваивает другое имя, но относящееся к тому же словарю, т. е. любое изменение нового словаря отражается на исходном. >>> fruits = {'Orange': 50, 'Apple': 65, 'Avocado': 160, 'Pear': 75} >>> fruits_2 = fruits >>> fruits_2.pop('Orange') 50 >>> print(fruits) {'Apple': 65, 'Avocado': 160, 'Pear': 75} 9. Определение длины словаря Чтобы выяснить сколько пар ключ-значение содержится в словаре, достаточно воспользоваться функцией len(): >>> print(population) {'Berlin': 3748148, 'Hamburg': 1822445, 'Munich': 1471508, 'Cologne': 1085664, 'Frankfurt': 753056} >>> print(len(population)) 5 10. Итерация словаря 10.1 Итерация ключей Чтобы перебрать все ключи, достаточно провести итерацию по элементам объекта словаря: >>> for city in population: ... print(city) Berlin Hamburg Munich 119 Cologne Frankfurt 10.2 Итерация значений Вычислим сколько людей проживает в пяти крупнейших городах Германии. Применим метод dict.values(), возвращающий список значений словаря: >>> print(population) {'Berlin': 3748148, 'Hamburg': 1822445, 'Munich': 1471508, 'Cologne': 1085664, 'Frankfurt': 753056} >>> inhabitants = 0 >>> for number in population.values(): ... inhabitants += number >>> print(inhabitants) 8880821 В пяти крупнейших городах Германии живут почти 9 миллионов человек. 10.3 Итерация ключей и значений В случае, если нужно работать с ключами и значениями одновременно, обратимся к методу dict.items(), возвращающему пары ключ-значение в виде списка кортежей. >>> min_grade = 10 >>> min_student = '' >>> for student, grade in grades.items(): ... if grade < min_grade: ... min_student = student ... min_grade = grade >>> print(min_student) Normando 11. Генераторы словарей Цикл for удобен, но сейчас попробуем более эффективный и быстрый способ – генератор словарей. Синтаксис выглядит так: {key: value for vars in iterable} Отфильтруем товары из словаря products по цене ниже 100 евро, используя как цикл for, так и генератор словарей. >>> print(products) {'table': 120, 'chair': 40, 'lamp': 14, 'bed': 250, 'mattress': 100, 'pillow': 10, 'shelf': 70, 'sofa': 400} >>> products_low = {} >>> for product, value in products.items(): ... if value < 100: ... products_low.update({product: value}) >>> print(products_low) {'chair': 40, 'lamp': 14, 'pillow': 10, 'shelf': 70} >>> products_low = {product: value for product, value in products.items() if value < 100} >>> print(products_low) {'chair': 40, 'lamp': 14, 'pillow': 10, 'shelf': 70} Результаты идентичны, при этом генератор словарей записан компактнее. 12. Вложенные словари 120 Вложенные словари – это словари, содержащие другие словари. Мы можем создать вложенный словарь так же, как мы создаем обычный словарь, используя фигурные скобки. Следующий вложенный словарь содержит информацию о пяти известных произведениях искусства. Как можно заметить, значениями словаря являются другие словари. # вложенный словарь, содержащий информацию об известных произведениях искусства works_of_art = {'The_Starry_Night': {'author': 'Van Gogh', 'year': 1889, 'style': 'post- impressionist'}, 'The_Birth_of_Venus': {'author': 'Sandro Botticelli', 'year': 1480, 'style': 'renaissance'}, 'Guernica': {'author': 'Pablo Picasso', 'year': 1937, 'style': 'cubist'}, 'American_Gothic': {'author': 'Grant Wood', 'year': 1930, 'style': 'regionalism'}, 'The_Kiss': {'author': 'Gustav Klimt', 'year': 1908, 'style': 'art nouveau'}} Создадим вложенный словарь, используя dict(), передавая пары ключ-значение в качестве именованных аргументов. # вложенный словарь, созданный при помощи dict() works_of_art = dict(The_Starry_Night={'author': 'Van Gogh', 'year': 1889, 'style': 'post- impressionist'}, The_Birth_of_Venus={'author': 'Sandro Botticelli', 'year': 1480, 'style': 'renaissance'}, Guernica={'author': 'Pablo Picasso', 'year': 1937, 'style': 'cubist'}, American_Gothic={'author': 'Grant Wood', 'year': 1930, 'style': 'regionalism'}, The_Kiss={'author': 'Gustav Klimt', 'year': 1908, 'style': 'art nouveau'}) Для доступа к элементам во вложенном словаре указываем ключи, используя несколько квадратных скобок ([ ][ ]). >>> print(works_of_art['Guernica']['author']) Pablo Picasso >>> print(works_of_art['American_Gothic']['style']) regionalism 13. Альтернативные типы данных Модуль collections предоставляет альтернативные типы данных: OrderedDict, defaultdict и Counter, расширяющие возможности обычных словарей. У нас есть подробная статья о модуле collections , которая помогает не изобретать уже известные структуры данных Python. Здесь мы остановимся на трех типах данных, наиболее близких к словарям. 13.1. OrderedDict OrderedDict содержит словарь, хранящий порядок добавления ключей. В Python 3.6+ словари запоминают порядок, а для предыдущих версий Python можно использовать OrderedDict. >>> import collections >>> dictionary = collections.OrderedDict({'hydrogen': 1, 'helium': 2, 'carbon': 6, 'oxygen': 8}) >>> print(type(dictionary)) С OrderedDict можно использовать операции с элементами, методы и функции, как при работе с обычным словарем. 13.2. defaultdict defaultdict – подкласс словаря, присваивающий значение по умолчанию при отсутствии ключа. Он никогда не выдаст KeyError, если мы попробуем получить доступ к элементу, 121 который отсутствует в словаре. Будет создана новая запись. В приведенном ниже примере ключи создаются с различными значениями в зависимости от функции, используемой в качестве первого аргумента. >>> default_1 = collections.defaultdict(int) >>> default_1['missing_entry'] 0 >>> print(default_1) defaultdict(, {'missing_entry': 0}) >>> default_2 = collections.defaultdict(list, {'a': 1, 'b': 2}) >>> default_2['missing_entry'] [] >>> print(default_2) defaultdict(, {'a': 1, 'b': 2, 'missing_entry': []}) >>> default_3 = collections.defaultdict(lambda : 'Not given', a=1, b=2) >>> default_3['missing_entry'] 'Not given' >>> print(default_3) defaultdict( at 0x7f75d97d6840>, {'a': 1, 'b': 2, 'missing_entry': 'Not given'}) >>> import numpy as np >>> default_4 = collections.defaultdict(lambda: np.zeros(2)) >>> default_4['missing_entry'] array = ([0., 0.]) >>> print(default_4) defaultdict( at 0x7f75bf7198c8>, {'missing_entry': array([0., 0.])}) 13.3. Counter Counter – подкласс словаря, подсчитывающий объекты хеш-таблицы. Функция возвращает объект Counter, в котором элементы хранятся как ключи, а их количество в виде значений. Эта функция позволяет подсчитать элементы списка: >>> letters = ['a', 'a', 'c', 'a', 'a', 'b', 'c', 'a'] >>> counter = collections.Counter(letters) >>> print(counter) Counter({'a': 5, 'c': 2, 'b': 1}) >>> print(counter.most_common(2)) [('a', 5), ('c', 2)] Как показано выше, мы можем легко получить наиболее часто используемые элементы с помощью метода most_common([n]). Этот метод возвращает список n наиболее часто встречающихся элементов и их количество. 14. Создание Pandas DataFrame из словаря Pandas DataFrame – это двумерная таблица со строками и столбцами, создаваемая в библиотеке анализа данных pandas. Это очень мощная библиотека для работы с данными. Ранее мы рассказывали как можно анализируовать данные с помощью одной строки на Python в pandas (да и вообще о разных трюках работы с библиотекой ). Объект DataFrame создается с помощью функции pandas.DataFrame(), принимающей различные типы данных (списки, словари, массивы numpy). В этой статье разберем только те способы создания датафрейма, которые предполагают использование словарей. 14.1. Создание DataFrame из словаря Создадим DataFrame из словаря, где ключами будут имена столбцов, а значениями – данные столбцов: import pandas as pd 122 # создать Pandas DataFrame из словаря - ключ (название столбца) - значение (информация в столбце) df = pd.DataFrame({'name': ['Mario', 'Violeta', 'Paula'], 'age': [22, 27, 19], 'grades': [9, 8.5, 7]}) print(df) По умолчанию индексом является номер строки (целое число, начинающееся с 0). Изменим индексы, передав список индексов в DataFrame. # создать Pandas DataFrame из словаря - ключ (название столбца) - значение (информация в столбце) - с собственными индексами import pandas as pd df_index = pd.DataFrame({'name': ['Mario', 'Violeta', 'Paula'], 'age': [22, 27, 19], 'grades': [9, 8.5, 7]}, index=['student_1', 'student_2', 'student_3']) print(df_index) 14.2. Создание DataFrame из списка словарей Список словарей также может быть использован для создания DataFrame, где ключи – имена столбцов. Как и раньше, мы можем изменять индексы, передавая список индексов в функцию DataFrame. # создать Pandas DataFrame из списка словарей - ключи (названия столбцов) с собственными индексами import pandas as pd df_2 = pd.DataFrame([{'name': 'Mario', 'age': 22, 'grades':9}, {'name': 'Violeta', 'age': 27, 'grades':8.5}, {'name': 'Paula', 'age': 19, 'grades':7}], index=['student_1', 'student_2', 'student_3']) print(df_2) 123 15. Функции в Pandas, использующие словари В Pandas есть несколько функций, использующих словари в качестве входных значений, например, pandas.DataFrame.rename и pandas.DataFrame.replace. 15.1. pandas.DataFrame.rename Эта функция возвращает DataFrame с переименованными метками осей. На вход можно подать словарь, в котором ключи – старые имена, а значения – новые. Метки, не содержащиеся в словаре, остаются неизменными. # изменить метки индекса в df_2 import pandas as pd df_2 = pd.DataFrame([{'name': 'Mario', 'age': 22, 'grades':9}, {'name': 'Violeta', 'age': 27, 'grades':8.5}, {'name': 'Paula', 'age': 19, 'grades':7}], index=['student_1', 'student_2', 'student_3']) df_2.rename(index={'student_1': 'new_label_1', 'student_2': 'new_label_2'}, inplace=True) print(df_2) 15.2. pandas.DataFrame.replace Эта функция меняет значения DataFrame на другие значения. Мы можем использовать словарь с функцией замены для изменения DataFrame, где ключи представляют собой существующие записи, а значения – новые. # заменить Mario --> Maria и Paula --> Paola import pandas as pd df_2 = pd.DataFrame([{'name': 'Mario', 'age': 22, 'grades':9}, {'name': 'Violeta', 'age': 27, 'grades':8.5}, 124 {'name': 'Paula', 'age': 19, 'grades':7}], index=['student_1', 'student_2', 'student_3']) df_2.replace({'Mario': 'Maria', 'Paula': 'Paola'}, inplace=True) print(df_2) *** Итак, мы рассмотрели разные способы создания словаря, базовые операции (добавление, изменение, удаление элементов). Также мы узнали когда стоит использовать глубокую копию словаря вместо поверхностной. Научились строить матрѐшки – вложенные словари. Такие конструкции встретятся, когда вы будете качать, например, с ВКонтакте через его API разнообразную информацию. Если вы любите Python, Библиотека программиста подготовила ещѐ много интересных материалов об этом замечательном языке: Программирование на Python: от новичка до профессионала Самые эффективные ресурсы и материалы для изучения Python Инструменты Python: лучшая шпаргалка для начинающих Свежие материалы доступны по тегу Python Источники https://towardsdatascience.com/15-things-you-should-know-about-dictionaries-in-python- 44c55e75405c Модуль tkinter. Урок №3 — Проект «Сложение двух чисел» На этом уроке мы создадим приложение, которое будет находить произведение двух чисел. Нам понадобятся две метки, три текстовых поля и одна кнопка 1. Создадим графический интерфейс: from tkinter import * root=Tk() # создаем главное окно root.title('Произведение двух чисел') Label(root,text='Первое число').pack() # создаем метку и сразу размещаем EntryA=Entry(root,width=10,font='Arial 16') # создаем текстовое поле ввода EntryA.pack() # размещаем в главно окне методом pack() Label(root,text='Второе число').pack() EntryB=Entry(root,width=10,font='Arial 16') EntryB.pack() EntryC=Entry(root,width=20,font='Arial 16') 125 EntryC.pack() but=Button(root,text='Произведение') but.pack() # размещаем кнопку в главном окне root.mainloop() # цикл прорисовки окна После запуска вы должны увидеть следующее окно приложения: Согласитесь, выглядит не очень симпатично. Что поделать, метод размещения виджетов pack() в данном случае нам не подходит. 2. Метод размещения Grid С помощью этого способа мы можем разместить виджеты по сетке, состоящей из столбцов и строк. Можно объединять столбцы и строки, указывать выравнивание элементов. Если внимательно посмотреть рисунок в начале этого урока, то вы можете заметить, что окно нашего приложения состоит из 4 строк и 2 столбцов, причем некоторые ячейки объединены. 3. Перепишем нашу программу с использованием Grid: from tkinter import * root = Tk() root.title('Произведение двух чисел') # первая метка в строке 0, столбце 0 (0 по умолчанию) # парамет sticky означает выравнивание. W, E,N,S — запад, восток, север, юг Label(root, text='Первое число').grid(row=0, sticky=W) # вторая метка в строке 1 Label(root, text='Второе число').grid(row=1, sticky=W) # создаем виджеты текстовых полей EntryA = Entry(root, width=10, font='Arial 16') EntryB = Entry(root, width=10, font='Arial 16') EntryC = Entry(root, width=20, font='Arial 16') # размещаем первые два поля справа от меток, второй столбец (отсчет от нуля) EntryA.grid(row=0, column=1, sticky=E) EntryB.grid(row=1, column=1, sticky=E) # третье текстовое поле ввода занимает всю ширину строки 2 # columnspan — объединение ячеек по столбцам; rowspan — по строкам EntryC.grid(row=2, columnspan=2) # размещаем кнопку в строке 3 во втором столбце 126 but = Button(root, text='Произведение') but.grid(row=3, column=1, sticky=E) root.mainloop() После запуска мы увидим правильно оформленное окно: Осталось написать функцию, вычисляющую произведение чисел и привязать к кнопке. 4. Напишем функцию обработчик нажатия кнопки: Эту функцию необходимо разместить до создания кнопки. def proizv(): a = EntryA.get() # берем текст из первого поля a = int(a) # преобразуем в число целого типа b = EntryB.get() b = int(b) result = str(a * b) # результат переведем в строку для дальнейшего вывода EntryC.delete(0, END) # очищаем текстовое поле полностью EntryC.insert(0, result) # вставляем результат в начало 5. Привяжем нажатие кнопки с функцией (добавьте команду для кнопки): but = Button(root, text='Произведение', command=proizv) Задание 1: Добавьте кнопки вычисления суммы, разности и вычисления частного (деление). Задание 2: Напишите программу, складывающую целые числа в одной из компьютерных систем: 127 Подсказки: 1) функция int(строка,2) преобразует преобразует исходную строку, представляющую двоичное число в целое десятичное число. Например, int('101',2) (результат 5) 2) Для обратного преобразования десятичного числа можно использовать встроенные функции, результатом которых будет строка: hex(18) (результат 0x12) oct(25) (результат 0o31) bin(17) (результат 0b10001) Модуль tkinter. Урок №2 — Виджеты и их свойства На этом уроке мы рассмотрим некоторые часто используемые графические объекты (виджеты) такие как радиокнопка, флажки, метка, текстовые поля ввода, списки. (рис. Поляков К.Ю.) 1. Объект переключатель (радиокнопка) Всегда используется группой. Служит для выбора одного значения из нескольких. var=IntVar() var.set(0) rad0 = Radiobutton(root,text="Первый вариант ", variable=var,value=0) rad1 = Radiobutton(root,text="Второй вариант", variable=var,value=1) rad2 = Radiobutton(root,text="Третий вариант", variable=var,value=2) rad0.pack() #размещаем в окне приложения rad1.pack() 128 rad2.pack() Все радиокнопки привязаны к одной переменной с именем var. В нашем случае она будет принимать значения 0,1 или 2. Начальное значение установлено как 0. 2. Флажок Объект checkbutton предназначен для выбора не взаимоисключающих пунктов в окне (в группе можно активировать один, два или более флажков или не один). В отличие от радиокнопок, значение каждого флажка привязывается к своей переменной, значение которой определяется опциями onvalue (включено) и offvalue (выключено) в описании флажка. c1 = IntVar() c2 = IntVar() che1 = Checkbutton(root,text="Первый флажок",variable=c1,onvalue=1,offvalue=0) che2 = Checkbutton(root,text="Второй флажок",variable=c2,onvalue=5,offvalue=0) che1.pack() #размещаем в окне приложения che2.pack() 3. Метки Метки (или надписи) — это достаточно простые виджеты, содержащие строку (или несколько строк) текста и служащие в основном для информирования пользователя. lab1 = Label(root, text="Это метка \n из двух строк.", font="Arial 12") lab1.pack() #размещаем в окне приложения 4. Текстовое поле ввода text1 = Entry(root,width=25,bd=2) text1.pack() #размещаем в окне приложения С помощью необязательного атрибута bd можно менять ширину границы поля. 5. Списки Списки (класс ListBox) позволяет выбрать один или несколько пунктов в зависимости от значения опции selectmode. Значение SINGLE позволяет выбрать только один пункт, MULTIPLY — несколько пунктов. В примере ниже создается список с возможностью множественного выбора: s = ['Java','Python','Pascal','C#'] list1 = Listbox(root,selectmode=MULTIPLE) 129 for x in s: list1.insert(END,x) list1.pack() В цикле for в конец списка добавляются названия языков программирования из массива s. Задание 1. Создайте почтовую форму, как на рисунке: Задание 2. Создайте форму с радиокнопками и флажками: Подсказка: для изменения цвета фона и цвета надписи виджета используются атрибуты bg и fg. Пример для кнопки: but = Button(root, text="Это кнопка", width=30,height=5, bg="white",fg="blue") УРОК 5. Canvas. Идентификаторы, теги и анимация Изучив размещение геометрических примитивов на экземпляре Canvas, в этом уроке рассмотрим, как можно обращаться к уже созданным фигурам для изменения их свойств, а также создадим анимацию. https://www.elibrary.ru/download/elibrary_38229190_93682534.pdf from tkinter import * 130 root=Tk() root.title('Пример библиотеки tkinter') v=Canvas(root,width=600,height=600,bg="lightblue",cursor="pencil") v.create_polygon([75,150],[160,20],[235,150],fill="green") v.create_polygon([50,300],[160,135],[270,300],fill="green") v.create_polygon([20,450],[160,275],[300,450],fill="green") v.create_rectangle(120,500,210,450,fill="brown",outline="black") v.create_oval(425,10,500,80,fill='yellow',width ='1') v.create_rectangle(0,500,600,600,fill='light green') v.create_rectangle(350,350,500,500,fill='brown',outline='black',width='2') v.create_rectangle(427,427,370,370,fill='yellow',outline='black',width ='2') v.create_rectangle(460,430,500,500,fill='white',outline='black',width='2') v.create_polygon(510,350,390,215,340,350,fill='brown',outline='black',width='2') v.pack() root.mainloop() 131 В Tkinter существует два способа "пометить" фигуры, размещенные на холсте, – это идентификаторы и теги. Первые всегда уникальны для каждого объекта. Два объекта не могут иметь одни и тот же идентификатор. Теги не уникальны. Группа объектов на холсте может иметь один и тот же тег. Это дает возможность менять свойства всей группы. Отдельно взятая фигура на Canvas может иметь как идентификатор, так и тег. Идентификаторы Методы, создающие фигуры на холсте, возвращают численные идентификаторы этих объектов, которые можно присвоить переменным, через которые позднее обращаться к созданным фигурам. Пример 1. Шарик двигают стрелки Canvas from tkinter import * root = Tk() c = Canvas(width = 300 , height = 300 , bg = 'white' ) c.focus_set() c.pack() ball = c.create_oval( 140 , 140 , 160 , 160 , fill = 'green' ) c.bind( ' , lambda event: c.move(ball , 0 , - 2 )) c.bind( ' , lambda event: c.move(ball , 0 , 2 )) c.bind( ' , lambda event: c.move(ball , - 2 , 0 )) c.bind( ' , lambda event: c.move(ball , 2 , 0 )) root.mainloop() В данном примере круг двигается по холсту с помощью стрелок на клавиатуре. Когда создавался круг, его идентификатор был присвоен переменной ball. Метод move объекта Canvas принимает идентификатор и смещение по осям. С помощью метода itemconfig можно изменять другие свойства. Метод coords устанавливает новые координаты фигуры, если они заданы. Если указывается только идентификатор или тег, то coords возвращает текущие координаты. from tkinter import * root = Tk() c = Canvas(width = 200 , height = 200 , bg = 'white' ) c.pack() rect = c.create_rectangle( 80 , 80 , 120 , 120 , fill = 'lightgreen' ) def in_focus(event): c.itemconfig(rect , fill = 'green' , width = 2 ) c.coords(rect , 70 , 70 , 130 , 130 ) c.bind( ' , in_focus) root.mainloop() Здесь при получении холстом фокуса (нажать Tab) изменится цвет и размер квадрата. 132 Теги В отличие от идентификаторов, которые являются уникальными для каждого объекта, один и тот же тег может присваиваться разным объектам. Дальнейшее обращение к такому тегу позволит изменить все объекты, в которых он был указан. В примере ниже эллипс и линия содержат один и тот же тег, а функция color изменяет цвет всех объектов с тегом group1. Обратите внимание, что в отличие от имени идентификатора (переменная), имя тега заключается в кавычки (строковое значение). Пример 2 Теги изменяют цвет фигур разом from tkinter import * def color(event): c.itemconfig( 'group1' , width = 3 , fill = "red" ) root = Tk() c = Canvas(width = 460 , height = 150 , bg = 'white' ) c.pack() oval = c.create_oval( 30 , 10 , 130 , 80 , tag = "group1" ) c.create_line( 10 , 100 , 450 , 100 , tag = "group1" ) c.bind( ' , color) root.mainloop() Метод tag_bind позволяет привязать событие (например, щелчок кнопкой мыши) к определенной фигуре на Canvas. Таким образом, можно реализовать обращение к различным областям холста с помощью одного и того же события. Пример ниже иллюстрирует, как изменения на холсте зависят от того, где произведен клик. Пример 3 Набираем очки при попадании в фигуру from tkinter import * def oval_func(event): c.delete(oval) c.create_text( 80 , 50 , text = "Круг +20 очков" ) def rect_func(event): c.delete( "rect" ) c.create_text( 230 , 50 , text = "Прямоугольник +10 очков" ) def triangle(event): c.delete(trian) c.create_text( 380 , 50 , text = "Треугольник + 5 очков" ) c = Canvas(width = 460 , height = 100 , 133 bg = 'grey80' ) c.pack() oval = c.create_oval( 30 , 10 , 130 , 80 , fill = "orange" ) c.create_rectangle( 180 , 10 , 280 , 80 , tag = "rect" , fill = "lightgreen" ) trian = c.create_polygon( 330 , 80 , 380 , 10 , 430 , 80 , fill = 'white' , outline = "black" ) c.tag_bind(oval , ' , oval_func) c.tag_bind( "rect" , ' , rect_func) c.tag_bind(trian , ' , triangle) mainloop() Метод delete удаляет объект. Если нужно очистить холст, то вместо идентификаторов или тегов используется константа ALL. Практическая работа. Анимация в tkinter В данной программе создается анимация круга, который движется от левой границы холста до правой: 134 Пример 4. Движется круг слева направо до упора from tkinter import * def motion(): c.move(ball , 1 , 0 ) if c.coords(ball)[ 2 ] < 500 : root.after( 10 , motion) root = Tk() c = Canvas(root , width = 500 , height = 200 , bg = "white" ) c.pack() ball = c.create_oval( 0 , 100 , 40 , 140 , fill = 'green' ) motion() root.mainloop() Выражение c.coords(ball) возвращает список текущих координат объекта (в данном случае это ball). Третий элемент списка соответствует его второй координате x. Метод after вызывает функцию, переданную вторым аргументом, через количество миллисекунд, указанных первым аргументом. Изучите приведенную программу и самостоятельно запрограммируйте постепенное движение фигуры в ту точку холста, где пользователь кликает левой кнопкой мыши. Координаты события хранятся в его атрибутах x и y (event.x, event.y). При вызове метода bind событие передается в качестве первого аргумента. Название события заключается в кавычки, а также в угловые скобки < и >. События описывается с помощью зарезервированных последовательностей ключевых слов. Часто используемые события, производимые мышью: и т. д. Пример: from tkinter import * def b1(event): root.title( "Левая кнопка мыши" ) def b3(event): root.title( "Правая кнопка мыши" ) def move(event): 135 x = event.x y = event.y s = "Движение мышью {}x{}" .format(x , y) root.title(s) root = Tk() root.minsize(width = 500 , height = 400 ) root.bind( ' , b1) root.bind( ' , b3) root.bind( ' , move) root.mainloop() В этой программе меняется надпись в заголовке главного окна в зависимости от того, двигается мышь, щелкают левой или правой кнопкой. Событие (Event) – это один из объектов tkinter. У событий есть атрибуты, как и у многих других объектов. В примере в функции move извлекаются значения атрибутов x и y объекта event, в которых хранятся координаты местоположения курсора мыши в пределах виджета, по отношению к которому было сгенерировано событие. В данном случае виджетом является главное окно, а событием – В программе ниже выводится информация об экземпляре Event и некоторым его свойствам. Все атрибуты можно посмотреть с помощью команды dir(event). У разных событий они одни и те же, меняются только значения. Для тех или иных событий часть атрибутов не имеет смысла, такие свойства имеют значения по умолчанию. В примере хотя обрабатывается событие нажатия клавиши клавиатуры, в поля x, y, x_root, y_root сохраняются координаты положения на экране курсора мыши. from tkinter import * def event_info(event): ( type (event)) (event) (event. time ) (event.x_root) (event.y_root) root = Tk() root.bind( 'a' , event_info) root.mainloop() Пример выполнения программы: 8379853 37 92 Для событий с клавиатуры буквенные клавиши можно записывать без угловых скобок (например, 'a'). Для неалфавитных клавиш существуют специальные зарезервированные слова. Например, 136 которое не имеет отношения к нажатию клавиши Enter, а происходит, когда курсор заходит в пределы виджета.) Рассмотрим программу: from tkinter import * def enter_leave(event): if str (event. type ) == 'Enter' : event.widget[ 'text' ] = 'In' elif str (event. type ) == 'Leave' : event.widget[ 'text' ] = 'Out' root = Tk() lab1 = Label(width = 20 , height = 3 , bg = 'white' ) lab1.pack() lab1.bind( ' , enter_leave) lab1.bind( ' , enter_leave) lab2 = Label(width = 20 , height = 3 , bg = 'black' , fg = 'white' ) lab2.pack() lab2.bind( ' , enter_leave) lab2.bind( ' , enter_leave) root.mainloop() В ней две метки используют одну и ту же функцию, и каждая метка использует эту функцию для обработки двух разных событий: ввода курсора в пределы виджета и вывода во границы. Функция, в зависимости от того, по отношению к какому виджету было зафиксировано событие, изменяет свойства только этого виджета. Как изменяет, зависит от произошедшего события. Свойство event.widget содержит ссылку на виджет, сгенерировавший событие. Свойство event.type описывает, что это было за событие. Вернемся к событиям клавиатуры. Сочетания клавиш пишутся через тире. В случае использования так называемого модификатора, он указывается первым, детали на третьем месте. Например, from tkinter import * def exit_win(event): root.destroy() 137 def to_label(event): t = ent.get() lbl.configure(text = t) def select_all(event): def select_all2(widget): widget.selection_range( 0 , END) widget.icursor(END) # курсор в конец root.after( 10 , select_all2 , event.widget) root = Tk() ent = Entry(width = 40 ) ent.focus_set() ent.pack() lbl = Label(height = 3 , fg = 'orange' , bg = 'darkgreen' , font = "Verdana 24" ) lbl.pack(fill = X) ent.bind( ' , to_label) ent.bind( ' , select_all) root.bind( ' , exit_win) root.mainloop() Здесь сочетание клавиш Ctrl+a выделяет текст в поле. Без root.after() выделение не работает. Метод after выполняет функцию, указанную во втором аргументе, через промежуток времени, указанный в первом аргументе. В третьем аргументе передается значение атрибута widget объекта event. В данном случае им будет поле ent. Именно оно будет передано как аргумент в функцию select_all2 и присвоено параметру widget. Практическая работа Напишите программу по описанию. Размеры многострочного текстового поля определяются значениями, введенными в однострочные текстовые поля. Изменение размера происходит при нажатии мышью на кнопку, а также при нажатии клавиши Enter. Цвет фона экземпляра Text светлосерый (lightgrey), когда поле не в фокусе, и белый, когда имеет фокус. Событие получения фокуса обозначается как Для справки: фокус перемещается по виджетам при нажатии Tab, Ctrl+Tab, Shift+Tab, а также при клике по ним мышью (к кнопкам последнее не относится). 138 Задания для самостоятельной работы (по вариантам) Вариант 1 Даны три целых числа. Выбрать из них те, которые принадлежат интервалу [1,3]. Вариант 2 Дан номер года (положительное целое число). Определить количество дней в этом году, учитывая, что обычный год насчитывает 365 дней, а високосный — 366 дней. Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400 (например, годы 300, 1300 и 1900 не являются високосными, а 1200 и 2000 — являются). Вариант 3 Написать программу вычисления стоимости покупки с учетом скидки. Скидка в 3% предоставляется в том случае, если сумма покупки больше 500 руб., в 5% - если сумма больше 1000 руб. Вариант 4 Написать программу, которая бы по введенному номеру единицы измерения (1 — килограмм, 2 — миллиграмм, 3 — грамм, 4 — тонна, 5 — центнер) и массе М выдавала соответствующее значение массы в килограммах. Вариант 5 Найти косинус минимального из 4 заданных чисел. Вариант 6 Вывести на экран синус максимального из 3 заданных чисел. Вариант 7 Даны три стороны одного треугольника и три стороны другого треугольника. Определить, будут ли эти треугольники равновеликими, т. е. имеют ли они равные площади. Если это не так, то вывести «Foul!!!» Вариант 8 Составьте программу подсчѐта площади равнобедренного треугольника. Если площадь треугольника чѐтная, разделить еѐ на 2, в противном случае вывести сообщение «Не могу делить на 2!» Вариант 9 139 Составить программу, которая по данному числу (1-12) выводит название соответствующего ему месяца на английском языке. Вариант 10 Составить программу, осуществляющую перевод величин из радианной меры в градусную или наоборот. Программа должна запрашивать, какой перевод нужно осуществить, и выполнять указанное действие. Вариант 11 Дано три числа. Найти количество положительных чисел среди них; Вариант 12 Если действительные числа x и y – одного знака, найти их среднее геометрическое, в противном случае найти их среднее арифметическое. Вариант 13 Определить, существует ли прямоугольный треугольник со сторонами x,y,z. Если – да, вычислить его площадь. Вариант 14 Определить, существует ли треугольник с длинами сторон a, b, c. Если – да, вычислить его площадь по формуле Герона. Формула Герона имеет вид: S=p(p-a)(p-b)(p-c), где p=12(a+b+c) Вариант 15 Вычислить значение функции f(x), если |