<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Introdução à Programação em Python
Manipulação de Listas
Anteriormente, vimos alguns exemplos de criação e manipulação de listas
Step1:  Podemos também alterar um elemento de uma lista utilizando os índices
Step2:  Os operadores + e * tem a função de concatenação e repetição
Step3:  Para adicionar um elemento ao final da lista temos o comando append, que utilizado como mostrado a seguir
Step4:  Para remover um elemento, utilizamos o comando del
Step5:  O tamanho de uma lista pode ser obtido com o comando len
Step6:  E podemos verificar se um certo elemento existe na lista com o comando in
Step7:  Digamos que queremos efetuar uma operação para cada elemento dessa lista.
Por exemplo, imprimir o quadrado dos valores de um número
Step8:  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.
Step9:  Podemos utilizar o comando for para criar listas diferentes das geradas pelo comando range()
Step10:  FizzBuzz
Step12:  Potência
Step13:  Monte Carlo
Step14:  Agora criaremos uma função PlotaCirculo() que desenha uma circunferência na área de plotagem atual.
Step15:  Agora vamos criar uma função PlotaAlvo(X, Y) que recebe uma lista de pontos X e Y para plotar.
Step16:  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
Step17:  Opcional
Syntactic Sugar
Step18:  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.
<ASSISTANT_TASK:>
Python Code:
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
Explanation: Introdução à Programação em Python
Manipulação de Listas
Anteriormente, vimos alguns exemplos de criação e manipulação de listas:
python
lista = [1,2,3,4,5]
print(lista[0])
Também vimos uma forma de criar listas de inteiros com a função range():
python
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:
python
print(lista[0]) # primeiro elemento
print(lista[-1]) # último elemento
E para uma faixa de valores:
python
print(lista[0:3]) # elemento 0, 1 e 2
print(lista[5:2:-1]) # do 5 ao 3, de -1 em -1
End of explanation
lista[0] = 0
print(lista)
Explanation: Podemos também alterar um elemento de uma lista utilizando os índices:
End of explanation
print(list(range(0,5)) + list(range(5,10)))
print([1,2,3]*2)
Explanation: Os operadores + e * tem a função de concatenação e repetição:
End of explanation
print(lista)
lista.append(11)
print(lista)
Explanation: Para adicionar um elemento ao final da lista temos o comando append, que utilizado como mostrado a seguir:
End of explanation
print(lista)
del lista[2] # remove o elemento na posição 2
print(lista)
Explanation: Para remover um elemento, utilizamos o comando del:
End of explanation
print(len(lista))
Explanation: O tamanho de uma lista pode ser obtido com o comando len:
End of explanation
print(10 in lista)
print(3 in lista)
Explanation: E podemos verificar se um certo elemento existe na lista com o comando in:
End of explanation
for x in lista:
    print(x*x)
Explanation: Digamos que queremos efetuar uma operação para cada elemento dessa lista.
Por exemplo, imprimir o quadrado dos valores de um número:
python
Para cada x em lista:
    print (x*x)    
Para isso o Python utiliza a instrução for da seguinte maneira:
End of explanation
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))
Explanation: 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.
End of explanation
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)
Explanation: Podemos utilizar o comando for para criar listas diferentes das geradas pelo comando range():
End of explanation
def FizzBuzz(N):
    
    
    
    
FizzBuzz(10)
Explanation: FizzBuzz: crie uma função que imprima os números de 1 até N substituindo certos números com a seguinte regra:
Se o número for múltiplo de 3, imprima Fizz
Se o número for múltiplo de 5, imprima Buzz
Se o número for múltiplo de 3 e 5, imprima FizzBuzz
End of explanation
def Potencia(y,b):
    
    Calcula y^b
    
    
    
    
print (Potencia(3,4), 3**4)
Explanation: 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 = 333*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 = 333*3$$
Então iniciando com o valor $3$, basta multiplicarmos sucessivamente por $3$ por $b-1$ vezes.
End of explanation
# 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
Explanation: Monte Carlo: Na ciência experimental temos que realizar experimentos e medições para estimar certos valores. Ex.:
Distribuição da altura dos alunos
Relação entre Altura dos alunos e CR
Velocidade média do vôo de uma andorinha
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 $$
End of explanation
# 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')
# 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()
Explanation: Agora criaremos uma função PlotaCirculo() que desenha uma circunferência na área de plotagem atual.
End of explanation
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([],[])
Explanation: Agora vamos criar uma função PlotaAlvo(X, Y) que recebe uma lista de pontos X e Y para plotar.
End of explanation
import random
def GeraPontos():
    return random.random(), random.random()
def DentroCirc(x,y):
    return (x-0.5)**2 + (y-0.5)**2 <= 0.25
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
pi, X, Y = MonteCarlo(1000)
print ("O valor de pi é ", pi)
PlotaAlvo(X,Y)
Explanation: 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.
End of explanation
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)
Explanation: Opcional
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]
End of explanation
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))
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)
Explanation: 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.
End of explanation
<END_TASK>