Monthly Archives: April 2017

Lição 6: Os blocos

Desenhar os blocos

  • Igual que a gente tem uma função, palgame.draw_circle para desenhar uma círculo, a gente palgame.draw_rect para desenhar uma retângulo.
  • A gente sabe que precisa desenhar varias blocos – ou seja, a gente quer repetir os mesmo comando (draw_rect) varias vezes. Temos duas opções para repetir um comando: o for loop, e o while loop. Nesse caso qual deles é melhor?
  • Lembra que caso a gente saiba quantas vezes a gente quer repetir uma coisa, melhor usar o for loop. Aqui, sim a gente sabe quantas vezes a gente quer repetir, porque sabemos quantos blocos precisamos.
  • Vamos tentar desenhar varios blocos com o for loop então:
bloco_x = 5
bloco_y = 8
for i in range(10):
    palgame.draw_rect(bloco_x, bloco_y, 20, 10)
  • se a gente executar esses codigos, vai aparecer um bloco só. Por que? Por que mesmo que a gente desenhe 10 blocos, a gente nunca atualiza a posição ‘x’ e ‘y’ do bloco, então todos os blocos são desenhados no mesmo lugar!
  • Ai, vamos atualizar a posição ‘x’ do bloco, para ter uma linha dos 10 blocos
bloco_x = 5
bloco_y = 8
LARGURA_DO_BLOCO = 20
ALTURA_DO_BLOCO = 10

for i in range(10):
    palgame.draw_rect(bloco_x, bloco_y, LARGURA_DO_BLOCO, ALTURA_DO_BLOCO)
    bloco_x = bloco_x + LARGURA_DO_BLOCO + 5
  • Porem, a gente não quer uma linha só. Então a gente vai colocar esse for loop num outro for loop para ter um dobro for loop:
for i in range(LINHAS):
    posicao_x = 5
    for j in range(COLUNAS):
        palgame.draw_rect(posicao_x, posicao_y, LARGURA_DO_BLOCO, ALTURA_DO_BLOCO)
        posicao_x = posicao_x + LARGURA_DO_BLOCO + DISTANCA
    posicao_y = posicao_y + ALTURA_DO_BLOCO + 5

Assim, o programa vai desenhar varias linhas, e para cada linha, vai criar varios blocos. O resultado é um grade de blocos.

Remover blocos

  • Quando a bola bate o bloco, a gente quer que o bloco suma.
  • Para realizar isso, a gente tem que apresentar o ideia de ‘state’. O ‘state’ é o estado atual do programa. Se vc guarda o ‘state’ de um aplicativo, vc pode parar o programa em qualquer momento, e reiniciar num outro momento.
  • Então, nosso caso, a gente não quer simplesmente desenhar os blocos, a gente quer guardar a posição de cada bloco num lista, para lembrar quais blocos ainda existem e quais são destruidos.

Listas

  • No Python, no mesmo jeito que a gente tem variaveis que são Numeros, Strings (palavras), e Booleans, a gente pode ter variaveis que são listas. Uma lista pode possuir varias outros tipos de variaveis. Por exemplo:
lista = [3, 1, 9, 2]

print(lista) # vai imprimir 3, 1, 9, 2
  • Para anexar uma coisa no final de uma lista, a gente usa o append(). 
x = [3, 6, 1]
x.append(2)

print(x) # vai imprimir 3, 6, 1, 2
  • Para remover uma coisa da lista, a gente usa o remove()
x = [3, 9, 1, 4]

x.remove(3)

print(x) # vai imprimir 9, 1, 4
  • Os elementos na lista não precisam ser numeros
x = ["hello", 9, 3, True]

print(x) # vai imprimir "hello", 9, 3, True
  • Agora, a gente vai guardar a posição x e a posição y para cada bloco num lista. Além disso, a gente vai guardar cada ‘bloco’ – ou seja, cada ‘x’ e ‘y’ – num outro, grande lista. Assim, a gente vai ter uma lista de listas que parece assim:
blocos = [ [0, 8], [5, 8], [10, 8], [15, 8] ]
  • Nota aqui que cada elemento na lista é tambem uma lista pequena! Cada lista pequena, por exemplo [5, 8] representa um bloco.
  • Então para criar tudos os blocos, a gente usa a mesmo dobra for loop, só que agora para cada bloco a gente cria uma lista de dois elementos (posição x e posição y) e adiciona esse elemento ao lista grande de blocos.
COLUNAS = 8
LINHAS = 5

DISTANCA = 10
LARGURA_DO_BLOCO = (LARGURA_DA_TELA / COLUNAS) - DISTANCA
ALTURA = 16

posicao_y = 0
blocos = []
for i in range(LINHAS):
    posicao_x = 5
    for j in range(COLUNAS):
        b = [posicao_x, posicao_y]
        blocos.append(b)
        posicao_x = posicao_x + LARGURA_DO_BLOCO + DISTANCA
    posicao_y = posicao_y + ALTURA + 5
  • Agora para desenhar os blocos, é só pega cada bloco na lista, extrair o ‘x’ e ‘y’, e desenha:
for b in blocos:
    palgame.draw_rect(b[0], b[1], LARGURA_DO_BLOCO, ALTURA)

 Collisões

  • Agora para checar se a bola bateu um bloco, a gente tem que checar, para cada bloco, se a posição da bola fica dentro do espaço do bloco. Caso essa seja verdade, a gente vai remover esse bloco da lista:
for a in blocos:
    if (bola_x + raio) >= a[0] and (bola_x - raio) <= (a[0] + LARGURA_DO_BLOCO) and (bola_y + raio) >= a[1] and (bola_y - raio) <= (a[1] + ALTURA):
        blocos.remove(a)
  • Também nesse caso a gente quer que a bola volte, então a gente vai invertir a velocidade da bola:
for a in blocos:
    if (bola_x + raio) >= a[0] and (bola_x - raio) <= (a[0] + LARGURA_DO_BLOCO) and (bola_y + raio) >= a[1] and (bola_y - raio) <= (a[1] + ALTURA):
        blocos.remove(a)
        velocidade_y = velocidade_y * -1

Lição 5: Movimento da bola

while loop infinito

  • Lembra na ultima aula a gente conheceu o while loop, um jeito para repetir uma coisa varias vezes até uma condição seja falso.
  • No caso de um jogo, a gente quer que a programa repita para sempre (na verdade, até o usario perca ou ganhe, mas para agora a gente pode pensar que é para sempre).
  • Para efetuar esse “while loop infinito”, a gente precisa uma condição que nunca vai virar falso. Uns exemplos:
    • while 3 > 2:
    • while "thiago" == "thiago"
  • Esses condições sempre são verdade, então o while loop vai continuar para sempre. Mas para ter um programa mais legivel, o Python tem um tipo de variavel, se chama “boolean” para significar “Verdade” (True) ou “Falso” (False). Então eu posso escrever:
    • while True:
    • Qualquer coisa abaxio desta linha vai ser repetido para sempre por que True sempre é ‘verdade’

Aqui tem o link para o modelo do programa que a gente vai usar para criar esse jogo

Movimento da bola

x = 20
y = 30
raio = 5
cor = (255, 0, 0)
while True:
    palgame.get_event()
    palgame.clear_screen()


    palgame.draw_circle(x, y, raio, cor)

    palgame.draw_everything()
  • Nota que dentro do while loop infinito, a gente está desenhando um círculo na posição (x, y) – nesse caso (20, 30) – e com um raio de 5 e cor vermelho.
  • Lembra que os codigos que ficam dentro do while loop estão sendo repetidos – cada millissegundo.

Agora quero que a bola se mova. Como a gente pode fazer isso? Movimento é simplesmente uma mudança na posição de um objeto em relação do tempo. Então a gente vai atualizar a posição da bola dentro do while loop. Assim, a posição da bola vai mudar cada millisegundo – como esse acontece tão rapido, vai criar a sensação do movimento.

x = 20
y = 30
raio = 5
cor = (255, 0, 0)
while True:
    palgame.get_event()
    palgame.clear_screen()

    x = x + 1 # atualizando a posição no eixo 'x'
    y = y + 1 # atualizando a posição no eixo 'y'

    palgame.draw_circle(x, y, raio, cor)

    palgame.draw_everything()
  • Se a gente quiser que a bola se mova mais rapido, é só aumentar a ‘velocidade’, ou seja, o tamanho da mudança:
    • x = x + 5
    • y = y + 5
  • Como sempre, é melhor usar uma variavel para esse valor:
x = 20
y = 30
velocidade_x = 5
velocidade_y = 5
raio = 5
cor = (255, 0, 0)
while True:
    palgame.get_event()
    palgame.clear_screen()

    x = x + velocidade_x # atualizando a posição no eixo 'x'
    y = y + velocidade_y # atualizando a posição no eixo 'y'

    palgame.draw_circle(x, y, raio, cor)

    palgame.draw_everything()

Paredes

  • Agora a gente tem a bola movendo, mas quando a bola chega a beira da tela, ela continua e some. Em vez disso, a gente quer que a bola reassalte nas paredes.
  • Em termos do programa, a gente quer que a bola troque sentido.
  • Primeiro, como a gente pode saber que a bola chegou na parede?
    • É quando a posição da bola é igual (ou maior) do que a posição fixo da parede:
if x >= 700:
    # Aqui a gente sabe que a bola bateu a parede direita
if x <= 0:
    # Aqui a gente sabe que a bola bateu a parede izquerda
if y <= 0:
    # Aqui a gente sabe que a bola bateu a parede superior
if y >= 400:
    # Aqui a gente sabe que a bola bateu a parede inferior
  • Segundo, como a gente consegue inverter o sentido da bola?
    • Lembra que o movimento da bola é controlado pela velocidade, então para inverter o sentido do movimento, é só inverter a velocidade:
if x >= 700:
    velocidade_x = velocidade_x * -1
if x <= 0:
    velocidade_x = velocidade_x * -1
if y <= 0:
    velocidade_y = velocidade_y * -1
if y > 400:
    velocidade_y = velocidade_y * -1

Nota que a gente pode combinar essas linhas pq mesmo batendo parede izquerda ou parede direita, a gente vai inverter velocidade_x

if x >= 700 or x <= 0:
    velocidade_x = velocidade_x * -1
if y <= 0 or y >= 400:
    velocidade_y = velocidade_y * -1

Lição 4: while loop

while loop

  • Na segunda aula, a gente aprendeu o ‘for loop’, um jeito para repetir os mesmos comandos varias vezes
  • No caso do for loop, a gente tinha que saber exatamente quantas vezes a gente quer repetir uma coisa. Por exemplo:
import turtle

for i in range (4):
    turtle.forward(100)
    turtle.right(90)

 Nesse exemplo, a gente sabe antecipadamente que a gente quer fazer o seguinte 4 vezes, nem mais nem menos.

  • Porém, há situações onde o desenvolvedor nem sabe quantas vezes ele quer repetir uma coisa. Ele simplesmente sabe que ele quer repetir uma coisa até que uma condição seja cumprida.
numero = 1

while numero < 100:
    numero = numero * 2

Aqui eu quero multiplicar um numero por 2 até que o numero seja maior do que 100. Eu não sei quantas vezes eu preciso fazer isso, só sei que quero fazer isso até o numero seja maior do que 100.

  • As condições que a gente usa no while loop são iguais do que elas que a gente usa no if statement. Então a gente pode usar as conjunções ‘<‘, ‘>’, ‘<=’, ‘>=’, ‘==’, ‘!=’
  • Agora, vamos fazer um exemplo mais complicado com o while loop. A gente vai implementar o Conjectura de Collatz:

Esta conjectura aplica-se a qualquer número natural, e diz-nos para, se este número for par, o dividir por 2 (/2), e se for impar, para multiplicar por 3 e adicionar 1 (*3+1). Desta forma, por exemplo, se a sequência iniciar com o número 5 ter-se-á: 5; 16; 8; 4; 2; 1. A conjectura apresenta uma regra dizendo que, qualquer número natural, quando aplicado a esta regra, eventualmente sempre chegará a 4, que se converte em 2 e termina em 1.

numero = 18

while numero != 1:
    if numero % 2 == 0:
        numero = numero / 2
    else:
        numero = (numero * 3) + 1
    print(numero)
  • Enquanto que o numero não seja 1, a gente vai fazer o seguinte: se o numero for par, divide por 2, se o numero não for par, multiplica por 3 e adiciona 1.

Lição 3: if/else statements

Na última aula a gente aprendeu alguns ferramentos que nos deixa escrever codigos com mais facilidade: variaveis (para guardar, reutilizar e modificar valores) o ‘for loop’ (para repetir uma coisa varias vezes) e o ‘function’ (para organizar um serie de instruções num lugar). Agora a gente vai aprender outros e no fim dessa aula, vcs terão tudos os ferramentos que precisam para esse curso e a gente pode começar criar programas mais complexos.

if statement

  • Até agora, o computador sempre executava todas as instruções que a gente escreveu. Porem, para programas e aplicativos mais complexos, a gente não quer sempre executar tudos os codigos.
  • Em vez disso, a gente quer controlar o fluxo do programa e executar partes determinidos do programa, dependendo de uma condição. Por exemplo, num site como Facebook, se um usuario tem permissões para ver um post, o Facebook vai mostrar, mas, se ele não tem, não vai aparecer o post.
  • Para fazer isso, a gente escreve um ‘if’, depois uma condição, e em baixo, os codigos que a gente quer executar caso essa condição seja verdade:
x = 7

if x > 5:
    print("ola")
  • Nessa caso, o que vai acontecer? O computador guarda o valor ‘7’ na variavel ‘x’. E depois, ele vai checar: se o variavel ‘x’ (ou seja, 7) for maior do que 5. Como que 7 sim é maior do que 5, o computador vai executar os codigos dentro do ‘if statement’ e vai imprimir “ola”
  • Agora vamos modificar o exemplo:
x = 3

if x > 5:
    print ("ola")
  • Agora, o valor do ‘x’ não é maior do que 5, então o computador não vai imprimir nada
  • Nota que a gente usa o simbilo ‘>’ para significar “maior do que”. Além disso, existem outros simbilos:
    • ‘<‘ (menor do que)
    • ‘<=’ (menor do que ou igual a)
    • ‘>=’ (maior do que ou igual a)
    • ‘==’ (igual a)
    • ‘!=’ (não é igual a)
  • Esses simbilos de comparação funcionam com palavras tambem:
nome = "thiago"

if nome == "thiago":
    print("bom dia")

Esse programa vai imprimir “bom dia” por que o variavel ‘nome’ é igaul a “thiago”. Nota: no contexto das palavras (‘strings’) o simbilo ‘>’ significa ‘vem primeiro alfabeticamente’. Por exemplo:

nome = "pedro"

if nome > "thiago":
    print ("bom dia")

Nesse caso, o computador não vai imprimir “bom dia” por que a palavra “thiago” vem depois do que “pedro” alfabeticamente, ou seja, “pedro” é maior do que “thiago”.

Combinar condições

  • É possivel combinar varias condições num ‘if statement’. Há duas conjunções: ‘and‘ (e) e ‘or‘ (ou).
x = 5
y = 9
if x > 4 and y > 12:

Nesse exemplo, o computador não vai imprimir nada, por que mesmo que o ‘x’ seja maior do que 4, o ‘y’ não é maior do que 12. Como que a gente tem a conjução ‘and’ entres as duas condições, as duas tem que ser verdade para executar os codigos em baixo.

nacionalidade = "brasileiro"
idade = 35
if nacionalidade == "brasileiro" and idade >= 18:
    print ("pode votar")

Nesse exemplo, as duas condições são verdade, ou seja, ‘nacionalidade’ é igual a “brasileiro” e idade e maior do que (ou igaul a) 18, então o computador vai imprimir “pode votar”.

idade = 70

if idade < 18 or idade > 65:
    preco = 15
    print ("preco é", preco)

Aqui, a gente usa a conjução ‘or’. Então só uma das duas condições tem que ser verdade. Nesse caso a primeira condição (idade < 18) não é verdade, mais a segunda (idade > 65) é verdade, então os codigos dentro do if statement vai ser executados.

  • Lembra que os espaços são importantes! Qualquer codigos que voçê quer colocar ‘dentro’ do if statement tem que começar com um ‘tab’

else

  • Para ter ainda mais controle no fluxo do programa, a gente pode usar o ‘else statement’. ‘else’ significa ‘se não’ e o ‘else statement’ é usado conjunto com o ‘if statement’. Por exemplo
def ingresso (idade):
    if idade < 18 or idade > 65:
        print "preco meia"
    else:
        print "preco inteiro"

ingresso(45)

Aqui, caso a condição seja verdade, vai imprimir “preco meia”, mas caso não, vai imprimir preco inteiro”. Como que idade é 45 (eu passo o valor como um parâmetro no function) Não esqueça os dois pontinhos depois do ‘else’!

Vamos combinar o if statement e o for loop para escrever um function que pode detectar se um numero for primo ou não.

  • Para saber se um numero for primo, a gente tem que checar todos os numeros desde 2 até o numero, e ver se un deles divide o numero sem sobrar nada.
  • A gente usa o ‘for loop’ para anda por todos os numeros
  • A gente usa o ‘if statement’ para checar a condição de cada numero.
  • Assim que a gente ache um numero que divide o numero original sem sobrar nada, a gente pode terminar, pois não se precisa checar os outros. Aí nesse caso a gente imprime “numero não é primo” e ‘return’ para sair do function.
  • Caso a gente verifique que nenhum dos numeros divide o numero original (ou seja, o for loop termina) a gente pode dizer nesse momento que o numero original realmente é primo.
def isprime (num):
    for i in range (2, num):
        if num % i == 0:
            print ("numero não é primo")
            return
    print("numero é primo")

isprime(13)