In [1]:
# ignore esse código inicial, é apenas para preparar a página
from IPython.display import YouTubeVideo, HTML, Image, display
css_file = './modelo.css'
HTML(open(css_file, "r").read())
Out[1]:
Anteriormente, vimos alguns exemplos de criação e manipulação de listas:
lista = [1,2,3,4,5]
print(lista[0])
Também vimos uma forma de criar listas de inteiros com a função range()
:
lista = list(range(1,11))
print(lista # [1,2,3,4,5,6,7,8,9,10])
Para acessar um elemento em uma lista fazemos:
print(lista[0]) # primeiro elemento
print(lista[-1]) # último elemento
E para uma faixa de valores:
print(lista[0:3]) # elemento 0, 1 e 2
print(lista[5:2:-1]) # do 5 ao 3, de -1 em -1
In [2]:
lista = list(range(1,11))
print(lista) # [1,2,3,4,5,6,7,8,9,10]
print(lista[0]) # primeiro elemento
print(lista[-1]) # último elemento
print(lista[0:3]) # elemento 0, 1 e 2
print(lista[5:2:-1]) # do 5 ao 3, de -1 em -1
Podemos também alterar um elemento de uma lista utilizando os índices:
In [3]:
lista[0] = 0
print(lista)
Os operadores +
e *
tem a função de concatenação e repetição:
In [4]:
print(list(range(0,5)) + list(range(5,10)))
print([1,2,3]*2)
Para adicionar um elemento ao final da lista temos o comando append
, que utilizado como mostrado a seguir:
In [5]:
print(lista)
lista.append(11)
print(lista)
Para remover um elemento, utilizamos o comando del
:
In [6]:
print(lista)
del lista[2] # remove o elemento na posição 2
print(lista)
O tamanho de uma lista pode ser obtido com o comando len
:
In [7]:
print(len(lista))
E podemos verificar se um certo elemento existe na lista com o comando in
:
In [8]:
print(10 in lista)
print(3 in lista)
Digamos que queremos efetuar uma operação para cada elemento dessa lista.
Por exemplo, imprimir o quadrado dos valores de um número:
Para cada x em lista:
print (x*x)
Para isso o Python utiliza a instrução for
da seguinte maneira:
In [9]:
for x in lista:
print(x*x)
A instrução for é outra estrutura de repetição que permite repertimos uma operação para cada elemento de uma lista ou por um determinado número de vezes.
Vamos criar uma função para calcular a soma dos N primeiros números, começando do 1.
In [10]:
def Soma(N):
soma = 0
for x in range(1,N+1): # é um intervalo aberto [a,b[
soma = soma + x
return soma
print (Soma(5))
print (Soma(10))
Podemos utilizar o comando for
para criar listas diferentes das geradas pelo comando range()
:
In [11]:
listaQuad = []
for x in range(1,11):
listaQuad.append(x*x) # cria a lista dos números de 1 a 10 ao quadrado
print (listaQuad)
FizzBuzz: crie uma função que imprima os números de 1 até N substituindo certos números com a seguinte regra:
In [15]:
def FizzBuzz(N):
FizzBuzz(10)
Potência: Crie uma função que calcule $y^b$, dados $y$ e $b$, repetindo a multiplicação de $y$ por $y$ $b$ vezes.
$3^4 = 3*3*3*3$
Uma forma de pensar na resolução desse problema é reduzi-lo para um caso simplificado.
Vamos tomar o exemplo anterior, $3^4$, podemos dizer que:
$$3^4 = 3^3 * 3$$Agora nosso problema se reduziu em descobrir o valor de $3^3$ bastanto multiplicar $3$ nesse resultado.
Seguindo o raciocínio temos:
$$3^4 = 3^3 * 3 = (3^2 * 3) * 3 = (( 3^1 * 3) * 3) * 3 = 3*3*3*3$$Então iniciando com o valor $3$, basta multiplicarmos sucessivamente por $3$ por $b-1$ vezes.
In [19]:
def Potencia(y,b):
"""
Calcula y^b
"""
print (Potencia(3,4), 3**4)
Monte Carlo: Na ciência experimental temos que realizar experimentos e medições para estimar certos valores. Ex.:
Porém, em certas ocasiões o custo de uma medição é elevado ou impossibilitado. Em muitos casos, o computador pode nos ajudar fazendo simulações.
Simulações Computacionais são simulações realizadas em um computador para reproduzir o comportamento de um sistema.
A simulação utiliza um abstrato que aproxima o comportamento real.
Uma técnica de simulação é conhecida como Monte Carlo em que medições aleatórios, seguindo certa distribuição, são realizadas.
Vamos exemplificar com um jogo de dardos.
Primeiro vamos plotar uma circunferência de raio $0.5$, para isso precisamos definir uma função que retorne o lado superior e outra para o lado inferior:
$$ \pm \sqrt{0.25 - (x-0.5)^{2}} + 0.5 $$
In [27]:
# Biblioteca matemática
import math
# Retorna parte superior e inferior da circunferencia
def Circ(x):
return math.sqrt(0.25 - (x - 0.5)**2) + 0.5
def CircNeg(x):
return -math.sqrt(0.25 - (x - 0.5)**2) + 0.5
Agora criaremos uma função PlotaCirculo()
que desenha uma circunferência na área de plotagem atual.
In [31]:
# Biblioteca de plotagem
%matplotlib inline
import matplotlib.pyplot as plt
from numpy import arange
def PlotaCirculo():
# vamos fazer uma lista com valores de 0 até 1, de 0.01 em 0.01
Xc = arange(0,1.01,0.01)
# Vamos aplicar as funções Circ e CircB nessa lista
Y1 = list(map(Circ, Xc))
Y2 = list(map(CircNeg, Xc))
# Agora plota cada parte da circunferência com o comando plot
plt.plot(Xc,Y1, color='blue')
plt.plot(Xc,Y2, color='blue')
In [32]:
# configura a área de plotagem
plt.figure(figsize=(5,5))
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.style.use('fivethirtyeight')
plt.hold(True) # indica que queremos plotar várias figuras na mesma área
PlotaCirculo()
Agora vamos criar uma função PlotaAlvo(X, Y)
que recebe uma lista de pontos X e Y para plotar.
In [34]:
def PlotaAlvo(X,Y):
# Prepara área de plotagem
plt.figure(figsize=(5,5))
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.style.use('fivethirtyeight')
plt.hold(True)
PlotaCirculo()
# Se existirem pontos X e Y, plota eles
if len(X) > 0 and len(Y) > 0:
plt.plot(X,Y,'.', color='red') # o '.' indica que não quero ligar os pontos na plotagem
plt.show()
PlotaAlvo([],[])
O alvo pode ser definido como um círculo inscrito em um quadrado de tamanho 1 x 1.
Se atirarmos os dardos aleatoriamente, teremos a mesma chance de atingir qualquer ponto dentro do quadrado.
Se atirarmos dardos suficientes, cobriremos o quadrado por completo.
Contando quantos dardos caíram dentro do círculo, podemos estimar a área dele.
Tendo a área do círculo e do quadrado temos que:
$$ Ac = \pi r^2 \\ Aq = L^2 = (2r)^2 = 4r^2 \\ \frac{Ac}{Aq} = \frac{\pi}{4} \\ \pi = 4\frac{Ac}{Aq} $$O algoritmo de Monte Carlos funciona da seguinte forma:
dentro = 0
Para i na faixa de 0 a N:
x, y = GeraPontos()
Se DentroCirc(x, y):
dentro = dentro + 1
retorna 4 * dentro / N
Sendo dentro
uma variável utilizada para contar quantos pontos estão dentro da Circunferência.
A função GeraPontos()
gera dois pontos aleatórios e DentroCirc(x,y)
checa se o ponto (x,y) está dentro da circunferência.
In [42]:
import random
def GeraPontos():
return random.random(), random.random()
def DentroCirc(x,y):
return (x-0.5)**2 + (y-0.5)**2 <= 0.25
In [43]:
def MonteCarlo(N):
X = []
Y = []
dentro = 0
for i in range(N):
x, y = GeraPontos()
X.append(x)
Y.append(y)
if DentroCirc(x,y):
dentro = dentro + 1
return 4*dentro/N, X, Y
In [44]:
pi, X, Y = MonteCarlo(1000)
print ("O valor de pi é ", pi)
PlotaAlvo(X,Y)
Syntactic Sugar: Podemos criar uma lista utilizando uma notação mais próxima da matemática:
ListaQuad = [ x*x for x in range(1,101)]
Esse formato de geração de lista é conhecido como list comprehension e pode ser combinado com instruções condicionais:
ListaQuadImpar = [x*x for x in range(1,101) if (x*x) % 2 == 1]
In [42]:
ListaQuad = [ x*x for x in range(1,11)]
ListaQuadImpar = [x*x for x in range(1,11) if (x*x) % 2 == 1]
print (ListaQuad)
print (ListaQuadImpar)
O comando sum()
calcula a somatória dos elementos numéricos de uma lista.
O comando zip(Lista1, Lista2)
cria uma lista de duplas combinando as duas listas passadas como parâmetros.
In [30]:
X = [1,2,3]
Y = [4,5,6]
print(list(zip(X,Y)))
for x,y in zip(X,Y):
print(x+y)
print (sum(X), sum(Y))
In [45]:
def MonteCarlo(N):
dentro = 0
X=[random.random() for _ in range(N)]
Y=[random.random() for _ in range(N)]
pontosDentro = [1 for x,y in zip(X,Y) if DentroCirc(x,y)]
pi = 4.0*sum( pontosDentro)/N
return pi, X, Y
pi, X, Y = MonteCarlo(1000)
print ("O valor de pi é ", pi)
PlotaAlvo(X,Y)