### Sesc Av. Paulista
## Grupo de estudos em Python
# `hackmd.io/@sesc-av-paulista/estudos-em-python-17-abril`
- Thonny + py5 https://abav.lugaralgum.com/como-instalar-py5/
- Dica de livro https://automatetheboringstuff.com/
## Autômatos Celulares
- Outros exemplos: https://abav.lugaralgum.com/material-aulas/Processing-Python-py5/automatos-celulares.html
Primeiro passo: um tabuleiro com um dicionário
```python=
from random import choice
W = 10
tabuleiro = {} # dicionario vazio
def setup():
global colunas, filas
size(600, 400)
colunas = int(width / W)
filas = int(height / W)
zera_tabuleiro()
def zera_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = 0
def sorteia_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = choice([0, 1])
def draw():
for chave, valor in tabuleiro.items():
coluna, fila = chave
x = coluna * W
y = fila * W
if valor == 1:
fill('black')
else:
fill('white')
square(x, y, W)
def key_pressed():
if key == ' ':
zera_tabuleiro()
elif key == 's':
sorteia_tabuleiro()
```
Exemplo funcionando!
```python=
from random import choice
W = 10
tabuleiro = {} # dicionario vazio
VIZINHANÇA = (
(-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
)
rodando = False
amostra = 10
def setup():
global colunas, filas
size(600, 400)
colunas = int(width / W)
filas = int(height / W)
zera_tabuleiro()
no_stroke()
def zera_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = 0
def sorteia_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = choice([0, 1])
def conta_vizinhos(coluna, fila):
contagem = 0
for dc, df in VIZINHANÇA:
contagem += tabuleiro[(coluna + dc) % colunas,
(fila + df) % filas]
return contagem
def passo():
global tabuleiro
proximo_tabuleiro = {}
for chave, estado in tabuleiro.items():
coluna, fila = chave
soma_vizinhos = conta_vizinhos(coluna, fila)
# morte por solidão (morre com menos de 2 vizinhos)
if estado == 1 and soma_vizinhos < 2:
proximo_tabuleiro[coluna, fila] = 0
# morte por superpopulação (morre com 4 ou mais vizinhos)
elif estado == 1 and soma_vizinhos > 3:
proximo_tabuleiro[coluna, fila] = 0
# nascimento (com 3 vizinhos nasce
elif estado == 0 and soma_vizinhos == 3:
proximo_tabuleiro[coluna, fila] = 1
else:
proximo_tabuleiro[coluna, fila] = estado
tabuleiro = proximo_tabuleiro
def draw():
for chave, valor in tabuleiro.items():
coluna, fila = chave
x = coluna * W
y = fila * W
if valor == 1:
fill('black')
else:
fill('white')
square(x, y, W)
# fill('red')
# text_align(CENTER, CENTER)
# c = conta_vizinhos(coluna, fila)
# text(c, x + W / 2, y + W / 2)
if rodando and (frame_count % amostra) == 0:
passo()
def key_pressed():
global rodando
if key == 'c':
zera_tabuleiro()
elif key == 's':
sorteia_tabuleiro()
elif key == ' ':
rodando = not rodando
```

---
```python=
from random import choice
W = 10
tabuleiro = {} # dicionario vazio
VIZINHANÇA = (
(-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
)
rodando = False
amostra = 10
def setup():
global colunas, filas
size(600, 400)
colunas = int(width / W)
filas = int(height / W)
zera_tabuleiro()
no_stroke()
color_mode(HSB)
def zera_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = 0
def sorteia_tabuleiro():
for coluna in range(colunas):
for fila in range(filas):
tabuleiro[coluna, fila] = choice([0, 1])
def conta_vizinhos(coluna, fila):
contagem = 0
for dc, df in VIZINHANÇA:
contagem += tabuleiro[(coluna + dc) % colunas,
(fila + df) % filas]
return contagem
def passo():
global tabuleiro
proximo_tabuleiro = {}
for chave, estado in tabuleiro.items():
coluna, fila = chave
soma_vizinhos = conta_vizinhos(coluna, fila)
# morte por solidão (morre com menos de 2 vizinhos)
if estado == 1 and soma_vizinhos < 2:
proximo_tabuleiro[coluna, fila] = 0
# morte por superpopulação (morre com 4 ou mais vizinhos)
elif estado == 1 and soma_vizinhos > 3:
proximo_tabuleiro[coluna, fila] = 0
# nascimento (com 3 vizinhos nasce
elif estado == 0 and soma_vizinhos == 3:
proximo_tabuleiro[coluna, fila] = 1
else:
proximo_tabuleiro[coluna, fila] = estado
tabuleiro = proximo_tabuleiro
def draw():
for chave, valor in tabuleiro.items():
coluna, fila = chave
x = coluna * W
y = fila * W
if valor == 1:
c = conta_vizinhos(coluna, fila)
fill(c * 25, 200, 200)
else:
fill('white')
square(x, y, W)
if rodando and (frame_count % amostra) == 0:
passo()
def key_pressed():
global rodando
if key == 'c':
zera_tabuleiro()
elif key == 's':
sorteia_tabuleiro()
elif key == ' ':
rodando = not rodando
```

```python=
from random import choice
from itertools import product
import py5
W = 10 # cell size
nbs = ( # neighbourhood
(-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
)
board = {} # empty dict
live_nbs_count = {}
debug = False
play = False
sample = 10 # smaller is faster
def setup():
global cols, rows
py5.size(800, 600)
cols = int(py5.width / W)
rows = int(py5.height / W)
clear_board()
py5.no_stroke()
py5.color_mode(py5.HSB)
def clear_board():
for col, row in product(range(cols), range(rows)):
board[col, row] = 0
nbs_count_update()
def random_board():
for col, row in product(range(cols), range(rows)):
board[col, row] = choice([0, 1])
nbs_count_update()
def nbs_count_update():
for col, row in product(range(cols), range(rows)):
live_nbs_count[col, row] = sum(
board[(col + dc) % cols, (row + df) % rows]
for dc, df in nbs)
def step():
global board
next_board = {}
for (col, row), state in board.items():
live_nbs = live_nbs_count[col, row]
# death by loneliness
if state == 1 and live_nbs < 2:
next_board[col, row] = 0
# death by overcrowding
elif state == 1 and live_nbs > 3:
next_board[col, row] = 0
# birth
elif state == 0 and live_nbs == 3:
next_board[col, row] = 1
# keep same
else:
next_board[col, row] = state
board = next_board
nbs_count_update()
def draw():
for (col, row), state in board.items():
x, y = col * W, row * W
live_nbs = live_nbs_count[col, row]
if state == 1:
py5.fill(live_nbs * 32, 200, 200)
elif live_nbs == 3: # state == 0 but will become alive next.
py5.fill(64)
else: # state == 0
py5.fill(0)
py5.square(x, y, W)
if debug:
py5.fill(255)
py5.text_align(py5.CENTER, py5.CENTER)
py5.text(live_nbs, x + W / 2, y + W / 2)
if play and (py5.frame_count % sample) == 0:
step()
def key_pressed():
global play
if py5.key == 'c':
clear_board()
elif py5.key == 'r':
random_board()
elif py5.key == ' ':
play = not play
py5.run_sketch(block=False)
```
