<jupyter_start><jupyter_text>Teste 0: O primeiro treinoEste teste tem como intuito revisar os conceitos básicos de computação assim como de acostumar você aluno com a plataforma jupyter que usaremos durante os todo o curso de Científica I.  Conceitos chaveNas primeiras semanas do curso, além das operações aritméticas básicas (`+`, `-`, `*`, `/` e `**`),iremos usar na maior parte do tempo apenas três conceitos básicos do Python,logo é de suma importância estar confortável com eles:- `if/else`, para controle;- `for` para iterações;- a chamada de funções.Além disso, usaremos principalmente listas como estrutura de dados,então é bom estar confortável com- Acesso e modificação em listas; e- `append()`, para agregar elementos (em geral dentro de `for`s).Enfim, a função- `print()`, é bastante útil para debug.A recomendação aqui é que começando já nesse teste você começe a usar o `print` para visualizar a execução das funções que você elaborou e entender melhor se o código executa as tarefas da mesma maneira que você havia planejado (sempre que houver necessidade desse esforço adicional, é claro).  Potências de 2 Questão 1Escreva a função `list_pow_2` que dado um $n \geq 0$ retorna a lista com as $n$ primeiras potências de $2$.Na célula abaixo você irá escrever sua solução, essa solução será usada para executar os testes na célula seguinte.<jupyter_code>def list_pow_2(n):
    lst = []
    while n>0:
        pot = 2**(n-1) ## Calcula 2^n
        lst.append(pot) ## Insere na lista lst[] o termo 2^n
        n-=1
    lst.reverse() ## invertendo a lista, pois foi inserido do maior para o menor
    return lst<jupyter_output><empty_output><jupyter_text>Dica:Se os `assert`s estiverem dando errado, faça uma nova caixa com:```print(list_pow_2(1))print(list_pow_2(4))```<jupyter_code>assert list_pow_2(1) == [1]
assert list_pow_2(4) == [1,2,4,8]
assert list_pow_2(10) == [1,2,4,8,16,32,64,128,256,512]<jupyter_output><empty_output><jupyter_text>Questão 2:Escreva a função `sum_pow_2` que retorna a soma das potências $2^0 + 2^1 + ... + 2^{n-1}$ Dica: use uma função que você já fez!<jupyter_code>def sum_pow_2(n):    
    return sum(list_pow_2(n))
assert sum_pow_2(1) == 1
assert sum_pow_2(4) == 15
assert sum_pow_2(10) == 1023
## Nesta célula há testes ocultos: não a apague<jupyter_output><empty_output><jupyter_text>Brincando com polinômiosNessa parte, iremos representar um polinômio$p(x) = a_0 + a_1x^1 + \cdots + a_nx^n$pela sua lista de coeficientes $[a_0, \ldots, a_n]$. Questão 3: Calculando o valor do polinômio em um pontoImplemente a função `eval_pol(x,coefs)` que, dado um ponto $x$ e os coeficientes do polinômio,retorna o valor de $p(x)$.<jupyter_code>def eval_pol(x,coefs):    
    lst = []
    i=0
    while i<len(coefs):
        pol = (x**i)*coefs[i]
        lst.append(pol)
        i+=1 
    return sum(lst)
## Teste sua solução nesta caixa!

p = [0,0,1] # p(x) = x^2
eval_pol(2,p) ## p(2) = 2^2

# Você pode também usar print() se quiser, mas talvez seja mais fácil criar novas caixas e ver o resultado ;-)
# Um polinômio simples
p1 = [0,0,1]

assert eval_pol(1,p1) == 1
assert eval_pol(2,p1) == 4
assert eval_pol(10,p1) == 100
# Um polinômio um pouco mais complicado
p2 = [0,1,2,3]
assert eval_pol(1,p2) == 6
assert eval_pol(2,p2) == 34
## Mais testes ocultos<jupyter_output><empty_output><jupyter_text>Questão 4: Integrando um polinômio de grau conhecidoDurante todo o nosso curso, integração será um assunto importante.Comecemos então com a nossa primeira integral numérica (não tão numérica assim...).Escreva a função `integrate_small(x,coefs)` que,dados um número real $x$ e a lista de coeficientes do polinômio $p(x) = a_0 + a_1x + a_2x^2$ (de grau 2)retorna o valor da sua integral definida: $q(x) = \int_{0}^{x} p(t)dt.$<jupyter_code>def integrate_small(x,coefs):    
    ## Aplicando o TFC terminamos com o polinomio: a_0*x + (a_1*x^2)/2 + (a_2*x^3)/3
    
    cof = coefs.copy() ## Cria uma cópia da lista
    cof[1]=cof[1]/2.0 ## altera a lista para o TFC aplicado ao coeficiente
    cof[2]=cof[2]/3.0 ## altera a lista para o TFC aplicado ao coeficiente
    cof.insert(0,0) ## Insere 0 no indíce 0, pois eval_pol() considera o coeficiente x=0
    
    val = eval_pol(x,cof) ##soma o polinomio 0+a_0*x+(a_1)/2*x^2+(a_2)/3*x^3
    return val
p1 = [0,2,0]
p2 = [1,0,1]

assert integrate_small(1,p1) == 1
assert integrate_small(2,p1) == 4
assert integrate_small(3,p2) == 12
assert integrate_small(-3,p2) == -12 # Essa resposta faz sentido???<jupyter_output><empty_output><jupyter_text>Questão 5: Integrando polinômios de grau qualquerAgora, implemente a função `integrate(x,coefs)` que,dados um número real $x$ e a lista de coeficientes (de tamanho arbitrário) $[a_0,a_1,...,a_n]$,retorna o valor da sua integral definida $q(x) = \int_{0}^{x} p(t) \, dt$.<jupyter_code>def integrate(x,coefs):
    ## Aplicando o TFC terminamos com o polinomio: a_0*x + (a_1*x^2)/2 + (a_2*x^3)/3
    
    cof = coefs.copy() ## Cria uma cópia da lista
    for i in range(len(cof)):
        cof[i]=cof[i]/(1+i) ## altera a lista para o TFC aplicado ao coeficiente
    cof.insert(0,0) ## Insere 0 no indíce 0, pois eval_pol() considera o coeficiente x=0
    
    val = eval_pol(x,cof) ##soma o polinomio 0+a_0*x+(a_1)/2*x^2+(a_2)/3*x^3
    return val

assert np.isclose(integrate(3, [1,4,0,2,-1]), 12.9, atol=1e-12, rtol=1e-12)
assert np.isclose(integrate(1, [1,2,3,4,5,6,7,8,9,10]), 10, atol=1e-12, rtol=1e-12)
# Se tudo deu certo, os asserts "aleatórios" a seguir deveriam funcionar

np.random.seed(1)
valores = np.random.random(100) # Gera 100 números aleatórios entre 0 e 1

def gera_coefs(n):
    """Gera os coeficientes de um polinômio de grau $n$"""
    coefs = []    
    for k in range(n+1):
        coefs.append(1/math.factorial(k))
    return coefs

coefs = gera_coefs(10) # Gera os coeficientes do polinômio

for x in valores:
    diferenca = eval_pol(x, coefs) - integrate(x, coefs)
    assert abs(diferenca - 1) < 0.01 # Testa se a diferença está próxima de 1<jupyter_output><empty_output><jupyter_text>No teste acima vimos que o polinômio $p(x)$ é tal que $\int_{0}^{x} p(t)\,dt \approx p(x) - 1$. Pergunta: Qual função do cálculo 1 você conhece que se comporta de forma parecida com esse polinômio?Responda na caixa abaixo. $$f(x)=e^x$$  Questão 6 (Bônus): Produto de dois polinômiosEscreva a função `prod_pol(p,q)` que,dadas duas listas com os coeficientes de $p(x) = a_0 + a_1x + ... + a_nx^{n-1}$ e $q(x) = b_0 + b_1x + ... + b_mx^{m-1}$ retorne a lista dos coeficientes de $r(x) = p(x)q(x)$.<jupyter_code>def prod_pol(p,q):
    r = [] ## Polinomio produto
    pol = [] ## Matriz auxiliar do calculo
    
    ## Criação da variavel grau, que guarda o grau do polinomio produto r(x)
    ## Grau de r(x): pegar o termo de maior grau de cada polinomio e somar seus "graus"
    grau=len(p)+len(q)-1
    ## montagem das linhas da matriz auxiliar
    for i in range(len(p)):
        pol.append([])
        i+=1
    ## Criando a matriz pol[]
    for i in range(len(p)):
        
        ## Preenchendo com 0 os termos iniciais de cada linha da matriz, onde necessário for
        if(i>0):
            for w in range (i):
                pol[i].append(0)
                w+=1
        ## Preenchendo os coeficientes na matriz        
        for j in range(len(q)):
            pol[i].append(p[i]*q[j])
        ## Preenchendo com 0 os termos finais da matriz, onde necessário for
        for z in range(grau-len(pol[i])):
            pol[i].append(0)
            z+=1
    
    for i in range(grau): ## Criação do polinomio r(x)
        r.append(0)

    ## Somando os termos de mesmo grau e preenchendo os coeficientes em r(x)
    for i in range(grau):
        for j in range(len(p)):
            r[i] += pol[j][i]
    return r
assert prod_pol([1,2],[2,1]) == [2,5,2]
assert prod_pol([0,1],[0,0,1]) == [0,0,0,1]
assert prod_pol([1,2,3],[1,2]) == [1,4,7,6]
assert prod_pol([1,2,3],[3,2,1]) == [3,8,14,8,3]
coefs = prod_pol([0],[1,2,3])

for x in np.random.random(100):
    assert eval_pol(x,prod_pol([0],[1,2,3])) == 0 # Produto por zero deveria ser o polinômio zero não?
# Testando com polinômios de tamanho e coeficientes aleatórios<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1315018315018315, 'fraction_numerical': 0.03894993894993895, 'mean_word_length': 3.8930704898446833, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '330966', 'license': 'MIT', 'n_tokens_mistral': 3506, 'n_tokens_neox': 3374, 'n_words': 963, 'path': 'comp-cientifica-I-2018-2/testes/Teste0.ipynb', 'repo_name': 'mirandagil/university-courses', 'size': '8190'}