Tópico 10 – Iteração
Vamos aprender sobre laços em Python e um pouco sobre como gerar dados.
Resultados Esperados
- Entender laços (
for
) - Entender a geração de números aleatórios (
np.random
)
Material Adaptado do DSC10 (UCSD)
#In:
import babypandas as bpd
import numpy as np
Agenda
- Booleanos.
- Declarações condicionais (ou seja, declarações
if
). - Iteração (ou seja, loops
for
).
Observação:
- Concluímos a introdução de novas técnicas de manipulação de DataFrame.
- Hoje abordaremos algumas ferramentas básicas de programação, que serão muito relevantes à medida que começarmos a abordar mais ideias em estatística (na próxima semana).
Booleanos
Recapitulação: Booleanos
bool
é um tipo de dados em Python, assim comoint
,float
estr
.- Significa “Boolean”, em homenagem a George Boole, um dos primeiros matemáticos.
- Existem apenas dois valores booleanos possíveis:
True
ouFalse
. - Sim ou não.
- Ligado ou desligado.
- 1 ou 0.
- As comparações resultam em valores booleanos.
#In:
capstone = 'finished'
units = 123
#In:
units >= 180
False
#In:
type(units >= 180)
bool
Operadores booleanos; not
Existem três operadores que nos permitem realizar aritmética com booleanos – not
, and
e or
.
not
vira True
↔️ False
.
#In:
capstone
'finished'
#In:
capstone == 'finished'
True
#In:
not capstone == 'finished'
False
O operador e
O operador and
é colocado entre dois bool
s. É True
se ambos forem True
; caso contrário, é Falso
.
#In:
capstone
'finished'
#In:
units
123
#In:
capstone == 'finished' and units >= 180
False
#In:
capstone == 'finished' and units >= 120
True
O operador ou
O operador or
é colocado entre dois bool
s. É True
se pelo menos um for True
; caso contrário, é Falso
.
#In:
capstone
'finished'
#In:
units
123
#In:
capstone == 'finished' or units >= 180
True
#In:
# Both are True!
capstone == 'finished' or units >= 0
True
#In:
# Both are False!
capstone == 'not started' or units >= 180
False
Ordem de operações
- Por padrão, a ordem das operações é
not
,and
,or
. Veja a precedência de todos os operadores em Python here. - Como de costume, use
(
parênteses)
para tornar as expressões mais claras.
#In:
capstone
'finished'
#In:
units
123
#In:
capstone == 'finished' or (capstone == 'in progress' and units >= 180)
True
#In:
# Different meaning!
(capstone == 'finished' or capstone == 'in progress') and units >= 180
False
#In:
# "and" has precedence.
capstone == 'finished' or capstone == 'in progress' and units >= 180
True
Booleanos podem ser complicados!
Por exemplo, não (a e b)
é diferente de não a e não b
! Se você estiver curioso, leia mais sobre De Morgan’s Laws.
#In:
capstone
'finished'
#In:
units
123
#In:
not (capstone == 'finished' and units >= 180)
True
#In:
(not capstone == 'finished') and (not units >= 180)
False
Nota: &
e |
vs. e
e ou
- Use os operadores
&
e|
entre duas Séries. A aritmética será feita elemento a elemento (separadamente para cada linha). Isto é relevante ao escrever consultas DataFrame, por ex.
df[(df.get('capstone') == 'concluído') & (df.get('units') >= 180)]
.- Use os operadores
and
eor
entre dois booleanos individuais. - por exemplo.
capstone == 'acabado' e unidades >= 180
.
Verificação de conceito ✅ – Resposta em cc.dsc10.com
Suponha que definimos a = True
e b = True
. Qual é o valor da expressão a seguir?
not (((not a) and b) or ((not b) or a))
A. Verdade
Por exemplo, Falso
C. Poderia ser qualquer um
Além: o operador in
Às vezes, queremos verificar se um elemento específico está em uma lista/matriz ou se uma substring específica está em uma string. O operador in
pode fazer isso por nós:
#In:
3 in [1, 2, 3]
True
#In:
'hey' in 'hey my name is'
True
#In:
'dog' in 'hey my name is'
False
Condicionais
instruções if
- Freqüentemente, desejaremos executar um bloco de código somente se uma expressão condicional específica for
True
. - A sintaxe para isso é a seguinte (não esqueça dos dois pontos!):
if <condition>:
<body>
- O recuo é importante!
#In:
capstone = 'finished'
capstone
'finished'
#In:
if capstone == 'finished':
print('Looks like you are ready to graduate!')
Looks like you are ready to graduate!
else
else
: Faça outra coisa se a condição especificada for False
.
#In:
capstone = 'finished'
capstone
'finished'
#In:
if capstone == 'finished':
print('Looks like you are ready to graduate!')
else:
print('Before you graduate, you need to finish your capstone project.')
Looks like you are ready to graduate!
elif
- E se quisermos verificar mais de uma condição? Use
elif
. elif
: se a condição especificada forFalse
, verifique a próxima condição.- Se essa condição for
False
, verifique a próxima condição e assim por diante, até vermos uma condiçãoTrue
. - Depois de ver uma condição
True
, ele avalia o código recuado e para. - Se nenhuma das condições for
True
, o corpoelse
é executado.
#In:
capstone = 'in progress'
units = 123
#In:
if capstone == 'finished' and units >= 180:
print('Looks like you are ready to graduate!')
elif capstone != 'finished' and units < 180:
print('Before you graduate, you need to finish your capstone project and take', 180 - units, 'more units.')
elif units >= 180:
print('Before you graduate, you need to finish your capstone project.')
else:
print('Before you graduate, you need to take', 180 - units, 'more units.')
Before you graduate, you need to finish your capstone project and take 57 more units.
E se usarmos if
em vez de elif
?
#In:
if capstone == 'finished' and units >= 180:
print('Looks like you are ready to graduate!')
if capstone != 'finished' and units < 180:
print('Before you graduate, you need to finish your capstone project and take', 180 - units, 'more units.')
if units >= 180:
print('Before you graduate, you need to finish your capstone project.')
else:
print('Before you graduate, you need to take', 180 - units, 'more units.')
Before you graduate, you need to finish your capstone project and take 57 more units.
Before you graduate, you need to take 57 more units.
Exemplo: Porcentagem para nota em letras
Abaixo, complete a implementação da função grade_converter
, que recebe uma nota percentual (grade
) e retorna a letra da nota correspondente, conforme tabela:
Carta | Alcance |
---|---|
Um | [90, 100] |
B | [80, 90) |
C | [70, 80) |
D | [60, 70) |
F | [0, 60) |
Sua função deve funcionar nestes exemplos:
>>> grade_converter(84)
'B'
>>> grade_converter(60)
'D'
#In:
def grade_converter(grade):
...
#In:
grade_converter(84)
#In:
grade_converter(60)
Atividade
def mystery(a, b):
if (a + b > 4) and (b > 0):
return 'bear'
elif (a * b >= 4) or (b < 0):
return 'triton'
else:
return 'bruin'
Sem executar código:
- O que
mystery(2, 2)
retorna? - Encontre entradas para que chamar
mystery
produza'bruin'
.
#In:
def mystery(a, b):
if (a + b > 4) and (b > 0):
return 'bear'
elif (a * b >= 4) or (b < 0):
return 'triton'
else:
return 'bruin'
Iteração
loops for
#In:
import time
print('Launching in...')
for x in [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]:
print('t-minus', x)
time.sleep(0.5) # Pauses for half a second
print('Blast off! 🚀')
Launching in...
t-minus 10
t-minus 9
t-minus 8
t-minus 7
t-minus 6
t-minus 5
t-minus 4
t-minus 3
t-minus 2
t-minus 1
Blast off! 🚀
for
-loops
- Loops nos permitem repetir a execução do código. Existem dois tipos de loops em Python; o loop
for
é um deles. - A sintaxe de um loop
for
é a seguinte:for <element> in <sequence>: <for body>
- Leia isto como: “para cada elemento desta sequência, repita este código”.
- Nota: listas, arrays e strings são exemplos de sequências.
- Assim como nas instruções
if
, o recuo é importante!
Exemplo: Quadrados
#In:
num = 4
print(num, 'squared is', num ** 2)
num = 2
print(num, 'squared is', num ** 2)
num = 1
print(num, 'squared is', num ** 2)
num = 3
print(num, 'squared is', num ** 2)
4 squared is 16
2 squared is 4
1 squared is 1
3 squared is 9
#In:
# The loop variable can be anything!
list_of_numbers = [4, 2, 1, 3]
for num in list_of_numbers:
print(num, 'squared is', num ** 2)
4 squared is 16
2 squared is 4
1 squared is 1
3 squared is 9
A linha print(num, 'squared is', num ** 2)
é executada quatro vezes:
- Na primeira iteração,
num
é 4. - Na segunda iteração,
num
é 2. - Na terceira iteração,
num
é 1. - Na quarta iteração,
num
é 3.
Isso acontece mesmo que não haja num =
em lugar nenhum.
Atividade
Usando o array colleges
, escreva um loop for
que imprima:
Revelle College
John Muir College
Thurgood Marshall College
Earl Warren College
Eleanor Roosevelt College
Sixth College
Seventh College
#In:
colleges = np.array(['Revelle', 'John Muir', 'Thurgood Marshall',
'Earl Warren', 'Eleanor Roosevelt', 'Sixth', 'Seventh'])
#In:
...
Ellipsis
Gamas
- Lembre-se, cada elemento de uma lista/array possui uma posição numérica.
- A posição do primeiro elemento é 0, a posição do segundo elemento é 1, etc.
- Podemos escrever um loop
for
que acessa cada elemento em um array usando sua posição. np.arange
será útil.
#In:
actions = np.array(['ate', 'slept', 'exercised'])
feelings = np.array(['content 🙂', 'energized 😃', 'exhausted 😩'])
#In:
len(actions)
3
#In:
for i in np.arange(len(actions)):
print(i)
0
1
2
#In:
for i in np.arange(len(actions)):
print('I', actions[i], 'and I felt', feelings[i])
I ate and I felt content 🙂
I slept and I felt energized 😃
I exercised and I felt exhausted 😩
Exemplo: Cachinhos Dourados e os Três Ursos
Não precisamos usar a variável de loop!
#In:
for i in np.arange(3):
print('🐻')
print('👧🏼')
🐻
🐻
🐻
👧🏼
Randomização e iteração
Nas próximas aulas, aprenderemos como simular eventos aleatórios, como jogar uma moeda.
Freqüentemente, iremos:
- Execute um experimento, por ex. “jogue 10 moedas.”
- Acompanhe algum resultado, por ex. “número de cabeças.”
- Repita as etapas 1 e 2 muitas e muitas vezes usando um loop
for
.
Armazenando os resultados
- Para armazenar nossos resultados, normalmente usaremos um
int
ou um array. - Se estiver usando um
int
, definimos uma variávelint
(geralmente para0
) antes do loop, então usamos+
para adicioná-la dentro do loop. - Se estiver usando um array, criamos um array (geralmente vazio) antes do loop, então usamos
np.append
para adicioná-lo dentro do loop.
np.append
- Esta função recebe duas entradas:
- uma matriz
- um elemento para adicionar ao final do array
- Retorna um novo array. Não modifica a matriz de entrada.
- Normalmente usamos assim para estender um array em um elemento:
nome_do_array = np.append(nome_do_array, element_to_add)
- ⚠️ Lembre-se de armazenar o resultado!
#In:
some_array = np.array([])
#In:
np.append(some_array, 'hello')
array(['hello'], dtype='<U32')
#In:
some_array
array([], dtype=float64)
#In:
# Need to save the new array!
some_array = np.append(some_array, 'hello')
some_array
array(['hello'], dtype='<U32')
#In:
some_array = np.append(some_array, 'there')
some_array
array(['hello', 'there'], dtype='<U32')
Exemplo: lançamento de moeda
A função flip(n)
lança n
moedas justas e retorna o número de caras que viu. (Não se preocupe em como isso funciona por enquanto.)
#In:
def flip(n):
'''Returns the number of heads in n simulated coin flips, using randomness.'''
return np.random.multinomial(n, [0.5, 0.5])[0]
#In:
# Run this cell a few times – you'll see different results!
flip(10)
6
Vamos repetir o ato de lançar 10 moedas, 10.000 vezes.
- Cada vez, usaremos a função
flip
para lançar 10 moedas e calcular o número de caras que vimos. - Armazenaremos esses números em um array,
heads_array
. - Cada vez que usarmos nossa função
flip
para lançar 10 moedas, adicionaremos um elemento ao final deheads_array
.
#In:
# heads_array starts empty – before the simulation, we haven't flipped any coins!
heads_array = np.array([])
for i in np.arange(10000):
# Flip 10 coins and count the number of heads.
num_heads = flip(10)
# Add the number of heads seen to heads_array.
heads_array = np.append(heads_array, num_heads)
Agora, heads_array
contém 10.000 números, cada um correspondendo ao número de caras em 10 lançamentos de moeda simulados.
#In:
heads_array
array([5., 4., 5., ..., 7., 5., 4.])
#In:
len(heads_array)
10000
#In:
(bpd.DataFrame().assign(num_heads=heads_array)
.plot(kind='hist', density=True, bins=np.arange(0, 12), ec='w', legend=False,
title = 'Distribution of the number of heads in 10 coin flips')
);
O padrão acumulador
loops for
no DSC 10
- Quase todos os loops
for
no DSC 10 usarão o padrão acumulador. Isso significa que inicializamos uma variável e a adicionamos repetidamente dentro de um loop.
- Não use loops
for
para realizar operações matemáticas em cada elemento de um array ou série. Em vez disso, use manipulações de DataFrame e métodos de matriz ou série integrados.
- Vídeo útil 🎥: For Loops (and when not to use them) em DSC 10.
Trabalhando com strings
String são sequências, então podemos iterá-las também!
#In:
for letter in 'uc san diego':
print(letter.upper())
U
C
S
A
N
D
I
E
G
O
#In:
'california'.count('a')
2
Exemplo: contagem de vogais
Abaixo, complete a implementação da função vowel_count
, que retorna o número de vogais na string de entrada s
(incluindo repetições). Um exemplo de comportamento é mostrado abaixo.
>>> vowel_count('king triton')
3
>>> vowel_count('i go to uc san diego')
8
#In:
def vowel_count(s):
# We need to keep track of the number of vowels seen so far. Before we start, we've seen zero vowels.
number = 0
# For each of the 5 vowels:
# Count the number of occurrences of this vowel in s.
# Add this count to the variable number.
# Once we've gotten through all 5 vowels, return the answer.
#In:
vowel_count('king triton')
#In:
vowel_count('i go to uc san diego')
Resumo, da próxima vez
Resumo
- As instruções
if
nos permitem executar pedaços de código dependendo se certas condições sãoTrue
. for
-loops são usados para repetir a execução do código para cada elemento de uma sequência.- Listas, arrays e strings são exemplos de sequências.