23. Работа с списками в Python

Обработка списков в Python.
На прошлом занятии мы подготовили программу, в которой будем работать со списками.
Приведу полный код:

from random import randrange as rnd, choice
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 = []
colors = ['red','brown','green','lightgreen','yellow','black','blue']

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 = choice(colors)
    new_ball.pen_color = choice(colors)
    new_ball.width = rnd(0,5)
    balls += [new_ball]

for b in balls:
    b.paint()
    
mainloop()

Теперь, после того, как у нас есть заполненный список «шариков», мы можем с ним поработать.
Для начала попробуем выстроить уже имеющийся список в ряд:

x = 20
for b in balls:
    b.x = x
	b.y = 200
    x += 60

for b in balls:
    b.paint()

mainloop()

Однако, мы видим, что все шарики не помещаются на экране.
Чтобы изменить размер окна, добавьте перед mainloop():

root.geometry(str(x+30) + 'x400')

str — это функция, которая преобразовывет число в строку. Для задания размера нам нужно получить строку, вида ‘800×600’, вот мы ее и собираем по частям: сначала добавляем к центру последнего шарика еще 30, потом преобразовываем это число в строку, чтобы склеить со строкой ‘x400’.

Однако, мы делаем двойную работу, даже тройную: при создании шарика его координаты, размер и другие параметры равны нулю, потом мы меняем их на случайные, чтобы в третий раз подправить и расположить в ряд.
Думаю, что стоить уменить количество кода:

from random import randrange as rnd, choice
from tkinter import *

root = Tk()
root.geometry('400x400')
canv = Canvas(root, bg = 'white')
canv.pack(fill = BOTH, expand = 1)

colors = ['red','brown','green','lightgreen','yellow','black','blue']
class ball():
    def __init__(self):
        x = self.x = rnd(100,300)
        y = self.y = rnd(100,300)
        r = self.r = rnd(10,30)
        self.width = rnd(0,5)
        self.color = choice(colors)
        self.pen_color = choice(colors)
        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 = []

x = 30
for z in range(12):
    new_ball = ball()
    new_ball.x = x
    new_ball.y = 200
    x += 60
    new_ball.paint()
    balls += [new_ball]

root.geometry(str(x+30) + 'x400')

mainloop()

Теперь случайные значения для свойст шарика будет задавать в конструкторе, а выравнивать в горизонтальный ряд будет в процесс заполнения шариками списка.

1. Заполнить в ряд по вертикали (с изменением высоты окна, если нужно)
2014-10-03 11-47-45 Скриншот экрана

2. Заполнить в ряд по диагонали слева 2014-10-03 11-49-29 Скриншот экрана

3. Заполнить в ряд по диагонали справа 2014-10-03 11-50-27 Скриншот экрана

4. Заполнить в ряд по горизонтали с увеличивающимся радиусом от 10 (+2) 2014-10-03 11-52-33 Скриншот экрана

Дальнейшие задания мы будем делать в функциях и вызывать по щелчку или нажатию кнопки.
По щелчку заполнить случайными, выстроить их в ряд:

from random import randrange as rnd, choice
from tkinter import *

root = Tk()
root.geometry('800x600')
fr = Frame(root)
fr.pack(fill = X, pady = 5)
bt1 = Button(fr, width = 8, text = 1)
bt1.pack(side = 'left', padx = 2)

bt2 = Button(fr, width = 8, text = 2)
bt2.pack(side = 'left', padx = 2)

bt3 = Button(fr, width = 8, text = 3)
bt3.pack(side = 'left', padx = 2)

bt4 = Button(fr, width = 8, text = 4)
bt4.pack(side = 'left', padx = 2)

canv = Canvas(root, bg = 'white')
canv.pack(fill = BOTH, expand = 1)

colors = ['red','brown','green','lightgreen','yellow','black','blue']
class ball():
    def __init__(self):
        x = self.x = rnd(100,300)
        y = self.y = rnd(100,300)
        r = self.r = rnd(10,30)
        self.width = rnd(0,5)
        self.color = choice(colors)
        self.pen_color = choice(colors)
        self.id = canv.create_oval(x-r,y-r,x+r,y+r, width = self.width, fill = self.color, outline = self.pen_color )
        self.paint()
        
    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)

def align_x():
    global balls
    x = 30
    for b in balls:
        b.y = 200
        b.x = x
        x += 60
        b.paint()
    

def fill_random(event):
    global balls
    canv.delete(ALL) # очистить холст
    balls = [] # удалить уже существующие шарики, если они были
    for z in range(12):
        balls += [ball()]
    align_x()
    

def bt1_click(event):
    pass
    
def bt2_click(event):
    pass
    
def bt3_click(event):
    pass
    
def bt4_click(event):
    pass
    
canv.bind('<Button-1>', fill_random)
bt1.bind('<Button-1>',bt1_click)
bt2.bind('<Button-1>',bt2_click)
bt3.bind('<Button-1>',bt3_click)
bt4.bind('<Button-1>',bt4_click)

mainloop()

5. Сделать кнопку, по нажатию на которую размер красных увеличиться на 5
6. Сделать кнопку, по нажатию на которую размер тех шариков, у которых совпадает цвет линии и цвет заливки увеличится на 5
7. Сделать кнопку, …, которая делает тонкую черную линию у тех шариков, которые не имеют линии (толщина = 0)
8. Убрать линию и увеличить размер шарика на ее размер у тех шариков, у которых цвет линии совпадает с цветом заливки.
9. Распределить шарики по ширине окна (чтобы расстояние между ними было одинаковым).
Определить ширину окна можно так: canv.winfo_width()
10. Создать метод ball.kill для удаления шарика (чтобы удалять и из списка, и с холста):

    def kill(self):
        global balls
        canv.delete(self.id)
        balls.remove(self)

11. Удалить последний шарик
12. Удалить первый красный шарик
13. Удалить все красные шарики (проверять внимательно, иногда могут удалиться не все красные!)
См. справочник: работа со списками.
14. Удалить все, кроме последних 3-х штук
15. Удалить все, кроме первых 3-х штук
16. Удалить каждый второй
17. Удалить после красного (см. справочник: работа со списками)
18. Удалить перед красным
19. Удалить шарики без линии
20. Удалить шарики без линии, если перед ними стоит шарик с линией
21. Удалить шарики без линии, если слева и справа от них шарики с линией

One thought on “23. Работа с списками в Python

  1. Уведомление: Аноним

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *