Мы разобрали уже несколько заданий, в которых фигурировали списки, настал черед поработать с ними посерьезнее. Python дает большие возможности для работы со списками, многие идеи для которых были взяты из языка LISP, название которого прямо указывает, что язык создан для работы со списками. Когда изучают Паскаль или Си, то работают с массивами. Массивы в Python тоже есть, но они убраны поглубже, в модуль array. Массивы в Питоне, как и в других языках, не позволяют использовать элементы разного типа, в отличие от списков. Стоит сказать, что списки есть и в Си и в Паскале, но удобство использование уступает спискам Питона значительно.
Как и было сказано вначале учебника, я предпочитаю обучение на практике, поэтому перечень методов и функций для работы со списками ищете в справочнике.
Создадим список шариков и будем по разным критериям удалять, изменять, добавлять и менять порядок.
Первое, что нужно сделать: создать окно и canvas внутри:
from random import randrange as rnd from tkinter import * root = Tk() root.geometry('400x400') canv = Canvas(root, bg = 'white') canv.pack(fill = BOTH, expand = 1) mainloop()
Тут должно быть все понятно, проверьте программу — должно появится белое окно, никаких объектов, никаких ошибок.
Продолжим, создам класс ball():
class ball(): def __init__(self): x = self.x = 0 y = self.y = 0 r = self.r = 0 self.width = 0 self.color = '' self.pen_color = '' self.id = canv.create_oval(x-r,y-r,x+r,y+r, width = self.width, fill = self.color, outline = self.pen_color )
Один метод — конструктор, в котором будут созданы переменные, отвечающие за размер, положение, цвет линии, цвет заливки и толщину линии. Это и будут те критерии, по которым мы будет выбирать шарики.
Для проверки создадим экземпляр класса и изменим его свойства:
b1 = ball() b1.x = 200 b1.y = 200 b1.r = 20 b1.color = 'green'
Пришла пора создать список и наполнить его. Приведу полный текст программы:
from random import randrange as rnd from tkinter import * root = Tk() root.geometry('400x400') canv = Canvas(root, bg = 'white') canv.pack(fill = BOTH, expand = 1) class ball(): def __init__(self): x = self.x = 0 y = self.y = 0 r = self.r = 0 self.width = 0 self.color = '' self.pen_color = '' self.id = canv.create_oval(x-r,y-r,x+r,y+r, width = self.width, fill = self.color, outline = self.pen_color ) balls = [] for z in range(12): balls += [ball()] mainloop()
Но что это? По-прежнему белый экран? Это та же проблема, что и в предыдущем случае.
Прежде, чем я дам ответ, проверим, действительно ли список ball наполнен объектами. Для этого перед mainloop() вставьте код:
print(len(balls)) for b in balls: print(b)
Первая строка покажет количество элементов в списке, а цикл позволит нам увидеть, что элементами списка являются объекты, и они разные.
Список есть? Есть. Объекты в списке есть? Тоже есть. Но координаты, размеры и цвета не заданы. Может быть в этом и была проблема?
Измените создание списка:
balls = [] for z in range(12): new_ball = ball() new_ball.x = rnd(100,300) new_ball.y = rnd(100,300) new_ball.r = rnd(10,30) new_ball.color = 'green' balls += [new_ball]
Все равно белый экран? Давайте посмотрим на координаты, может быть они не изменились?
Вывод информации поправим так:
for b in balls: print(b.x,b.y,b.r,b.color,b.id)
Я вижу, что координаты заданы, размер задан, цвет задан и даже с id проблем нет.
Еще раз спрошу, подумали ли вы над проблемой, прежде, чем узнать решение?
Мы создаем изображение кругов в конструкторе. Изменение координат на положение графического примитива уже не влияют! Как и в Пушке нужно добавить метод paint() в класс ball(), и вызывать его каждый раз, когда вы изменяете координаты шарика. Приведу полный код программы:
from random import randrange as rnd from tkinter import * root = Tk() root.geometry('400x400') canv = Canvas(root, bg = 'white') canv.pack(fill = BOTH, expand = 1) class ball(): def __init__(self): x = self.x = 0 y = self.y = 0 r = self.r = 0 self.width = 0 self.color = '' self.pen_color = '' self.id = canv.create_oval(x-r,y-r,x+r,y+r, width = self.width, fill = self.color, outline = self.pen_color ) def paint(self): x = self.x y = self.y r = self.r canv.coords(self.id,x-r,y-r,x+r,y+r) canv.itemconfig (self.id, width = self.width, fill = self.color, outline = self.pen_color) balls = [] for z in range(12): new_ball = ball() new_ball.x = rnd(100,300) new_ball.y = rnd(100,300) new_ball.r = rnd(10,30) new_ball.color = 'green' balls += [new_ball] for b in balls: b.paint() mainloop()
2. Добавить случайным цветом и случайную толщину (от 0 до 5) рамки (линии)
3. Расположить шарики в горизонтальный ряд
4. Расположить шарики в вертикальный ряд
5. Расположить шарики случайно, так, чтобы ни один полностью не закрывал другой (допускается частично)
6. Добавить метку с номером для каждого шарика (можно использовать self.id)
7. Сделать так, чтобы по щелчку в консоли печатался номер шарика, по которому щелкнули, если попали по шарику
Вопросы жду в комментариях (лучше в «обычных» комментариях, а не ВК, потому что так я быстрее замечу, что есть вопрос)
Гоняю по спискам, результаты в ссылках http://pastebin.com/hkyVtmBh
№3 мячики в ряд http://pastebin.com/dL95X0zY
№4 вертикальный ряд http://pastebin.com/8FkFHA5X