Python – Aula 3

Computação Simbólica no IPython Notebook usando sympy

Disciplina “Computação no Ensino de Física” (CEF) da UFES/Alegre

Curso de Licenciatura em Física – Turma 2013/2

Autoria : Prof. Ramón Giostri Campos – 2014/1.

Veremos abaixo como usar o IPython notebook para realizar cálculos simbólicos, usando o pacote sympy, no processo vamos exercitar a definição de funções (def) em python e gráficos usando o próprio sympy.

Carregar o IPyhon notebook e os pacotes iniciais:

Digite $ipython notebook

no terminal do seu sistema operacional (shell no linux e prompt no windowns);

Abaixo vamos chamar os principais pacotes

In [1]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib

É importante usar os pacotes compatíveis, como estamos usando o ipython novo, devemos usar o sympy novo.

No ubuntu uma solução é fazer download do sympy mais novo no sítio:

http://sympy.org/pt/download.html

Dai descompactamos e colocamos o arquivo que queremos executar (file.ipynb) dentro do diretório do recém descompactado.

In [2]:
import sympy as sym # importa as funções do sympy em um contexto diferenciado (no caso sym)
from sympy import *

A mudança de contexto presente na primeira linha é importante para não sobrepor as funções vindas do sympy com as funções nativas do python e do pylab.

Executamos agora um comando para ver qual a versão do sympy, se tudo foi feito corretamente, o número que aparece aqui é o mesmo que está no pacote baixado do site e descompactado posteriormente;

In [3]:
from sympy import __version__
__version__
Out[3]:
'0.7.4.1'

Primeiro estágio: Operações básicas e considerações iniciais

In [4]:
3*pi/2 + exp(I*x) / (x**2 + y)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-057106a93d7b> in <module>()
----> 1 3*pi/2 + exp(I*x) / (x**2 + y)

NameError: name 'x' is not defined

É importante dizer para o sympy quais as objetos são SÍMBOLOS;

In [5]:
x, y, z, t = symbols("x y z t") # Define símbolos para variáveis genericas
k, m, n = symbols("k m n", integer=True)  # Define símbolos para variáveis inteiras
f, g, h = map(Function, 'fgh') # define símbolos para funções
In [6]:
3*pi/2 + sym.exp(I*x) / (x**2 + y)
Out[6]:
3*pi/2 + exp(I*x)/(x**2 + y)

Agora o Python entendeu o que fazer, pois x e y são símbolos.

Mas essa forma 1D é difícil de ler e muito feia…vamos melhorar isso.

Para isso devemos carregar o comando abaixo:

In [7]:
init_printing()

Vamos repetir o nosso teste;

In [8]:
3*pi/2 + sym.exp(I*x) / (x**2 + y)
#Muito mais bonito!
Out[8]:
3π2+eixx2+y

Algumas ações que podem ser feitas com expressões simbólicas: expandir (expand), simplificar(simplify) e resolver(solve);

 

In [9]:
eq = ((x+y)**2 * (x+1))
eq
Out[9]:
(x+1)(x+y)2
In [10]:
expand(eq)
Out[10]:
x3+2x2y+x2+xy2+2xy+y2
In [11]:
a = 1/x + (x*sin(x) - 1)/x
print(a) #assim fica feito
display(a) #assim fica bonito
In [12]:
simplify(a)
Out[12]:
sin(x)
In [13]:
eq2 = Eq(x**3 - 3*x**2 + 4*x + 8., 0)
display(eq2)
x3−3×2+4x+8.0=0

Notem que a equação gerada usa o comando “Eq”, para definir a igualdade;

In [14]:
solve(eq2,x)
Out[14]:
[−1.0,2.0−2.0i,2.0+2.0i]

Exercícios 1: Tente resolver equações de ordem maior que 3 e equações transcendentais com o solve para ver o que ocorre;

Terceiro esstágio: Física B;

Vamos começar com o sistema massa mola: F=-kx; A segunda lei de Newtom para ele nos gera ma+k*x=0, que em termo de derivadas e já dividindo pela massa fica:

In [15]:
w0=symbols("w_0",real=True)

Atentem para a Flag “real”, isso significa que o símbolo w0 é REAL;

In [16]:
eqn = Eq(Derivative(x(t),t,t) + w0**2*x(t), 0) # já trocamos k/m por w0**2
display(eqn)
dsolve(eqn, x(t))

E se houvesse atrito, como ficaria.

In [17]:

b=symbols("b",real=True)
In [18]:
eqn2 = Eq(Derivative(x(t),t,t) +b*Derivative(x(t),t)+ w0**2*x(t), 0) # já trocamos k/m por w0**2
display(eqn2)
dsolve(eqn2, x(t))
Out[18]:

Não se assunste, isso é feio assim pois o sympy não sabe quem é maior, b ou w0

Se b e w0 forem conhecidos teremoss algo relativamente simples;

In [19]:
eqn2_crit = Eq(Derivative(x(t),t,t) +4*Derivative(x(t),t)+ (2**2)*x(t), 0) # já trocamos w0=2 e b=4
display(eqn2_crit)
dsolve(eqn2_crit, x(t))
Out[19]:
In [20]:
eqn2_super = Eq(Derivative(x(t),t,t) +5*Derivative(x(t),t)+ (2**2)*x(t), 0) # já trocamos w0=2 e b=5
display(eqn2_super)
dsolve(eqn2_super, x(t))
Out[20]:
In [21]:
eqn2_sub = Eq(Derivative(x(t),t,t) +3*Derivative(x(t),t)+ (2**2)*x(t), 0) # já trocamos w0=2 e b=3
display(eqn2_sub)
dsolve(eqn2_sub, x(t))
Out[21]:

E se houvesse uma força externa, por exemplo senoidal!

In [22]:
wp, A=symbols("w_p A",real=True)
In [23]:
eqn3 = Eq(Derivative(x(t),t,t) + w0**2*x(t)-A*sin(wp*t), 0) # já trocamos k/m por w0**2
display(eqn3)
sol3=dsolve(eqn3, x(t))
display(sol3)

Exercício 2: Descubra se é possível reaproveitar o que é gerado do solve e do dsolve sem necessariamente digitar as equações manualmente;

 

Terceiro estágio: Cálculo B;

Primeiro vejamos uma derivada, já usamos ela acima nas equações diferencias.

Usamos os comandos “Derivative” para escrever a derivada e o comando “diff” para realizar a derivação;

In [24]:
Derivative(cos(m*x**k)**10,x)
Out[24]: Esse mostra a equação
In [25]:
diff(cos(m*x**k)**10,x)
Out[25]: Esse resolve a equação

Note que o comando “Derivative” é esperto, e se tivermos uma expressão com duas VARIÁVEIS, ele imprime na tela uma derivada parcial em lugar da derivada ordinária;

In [26]:
Derivative(cos(y*x**k),x)
Out[26]:
∂cos(xky)/∂x

Agora vamos a integral, não necessariamente uma simples.

Usamos o comando “Integral” para escrever a INTEGRAL sem resolve-la e o comando “integrate” para INTEGRAR e ver o resultado;

In [27]:
Integral(sin(k*x)*sin(m*x),(x,-pi/2,pi/2))
Out[27]: Esse mostra a equação
In [28]:
integrate(sin(k*x)*sin(m*x),(x,-pi/2,pi/2))
Out[28]: Esse resolve a equação

Essa é uma das integrais da base da Série de Fourier, usada nas séries de Fourier, muito importante para resolver problemas de MECÂNICA CLÁSSICA e ELETROMAGNETISMO.

Exercício 3: Pesquise quais as outras integrais dessa base e use o sympy para resolve-las;

Vamos a um exemplo mais trabalhoso, vamos investigar as Séries de Taylor:

Séries de Taylor (e outros tipos) são uma formas de aproximar funções ao redor de um ponto de avaliação.

In [29]:
series(f(x),x,0,6)
Out[29]:

Ainda é possível fazer de outra forma…

In [30]:
f(x).series(x,0,6)
Out[30]:

Adiantes vamos estudar graficamente a questão da aproximação das seríes de Taylor.

Tendo o SYMPY em funcionamento, é possivel fazer gráficos nele usando um comando tipo PLOT, porém o sym.plot é menos rico que o plt.plot (do MATPLOTLIB) que usamos na aula passada. Mas ele quebra bem o galho e tem uma sintax super simples;

Plot do sympy básico

In [31]:
sym.plot(cos(x))
Out[31]:
<sympy.plotting.plot.Plot at 0x5d261d0>

Note que não houve necessidade de gerar o dois vetores de números (usando NUMPY ARANGE) para gerar o gráfico (na verdade essa sintax é absurdamente simples).

In [32]:
sym.plot(cos(x),sin(x),log(x)) # vários gráficos
Out[32]:
<sympy.plotting.plot.Plot at 0x61eb810>
In [33]:
sym.plot(cos(x),log(x),(x,0.1,2*pi)) # gráficos com intervalos semelhantes definidos
Out[33]:
<sympy.plotting.plot.Plot at 0x6203490>
In [34]:

sym.plot((cos(x),(x,-pi,2*pi)),(log(x),(x,0.1,2*pi))) # gráficos com intervalos diferentes definidos
Out[34]:
<sympy.plotting.plot.Plot at 0x6478950>

Para inspecionar coisas simples, esse comando funciona muito bem, para gráficos realmente profissionais devemos usar o MATPLOTLIB. A a sintax simples é muito limitada e mesmo ações simples como mudar a cor dos gráficos já deixa deixa a simplicidade de lado;

In [35]:
p=sym.plot((cos(x),(x,-pi,2*pi)),(log(x),(x,0.1,2*pi)), show=False)
p[0].line_color = 'red'
p[1].line_color = 'green'
p.title = 'Figuras Coloridass'
p.show()
In [36]:
p=sym.plot((cos(x),(x,-pi,2*pi)),(log(x),(x,0.1,2*pi)), show=False)
p[0].line_color = (0.5,1,1) #aqui usando RGB;
p[1].line_color = lambda a : log(a) # Aqui usando uma função para mapear a cor;
p.title = 'Figuras Coloridass'
p.show()

Exercício 4: Pesquise se é possível colocar o nome dos eixos nos gráficos do sympy; Se sim, mostre um exemplo;

Quarto estágio: O que você não faria facilmente;

Vamos agora fazer uma função que faça a comparação da função e da séries;

In [37]:
def f_taylor_ordem(func, var=x, ordem=5):
    ftaylor = func.series(var,0,ordem).removeO()
    return ftaylor

Definimos uma função que faz a série de Taylor de uma função genérica (variável func), expandida na variável específica (var), que por omissão é escolhida variável x (var=x) e na ordem que quisermos (ordem), que por omissão é a ordem 5 (ordem=5);

Atente para o remove0() do final, ele serve para transformar a sérei em polinômio.

In [38]:
f_taylor_ordem(sinh(x*cos(t))) #tudo funcionando por omissão
Out[38]:
x36cos3(t)+xcos(t)
In [39]:
f_taylor_ordem(sinh(x*cos(t)),t,5)#aqui espeficicando a variável e a ordem
Out[39]:
t4(x28sinh(x)+x24cosh(x))−t2x2cosh(x)+sinh(x)

Vamos agora unir essa função a estrutura que gera gráficos do sympy;

In [40]:
def plot_taylor_compara(func, var=x, rang=(-1,1),yrang=(-1.2,1.2),ordem=[1,5]):
    xrang = (var,)+rang
    arg_plot=(func,)+tuple(map(lambda num:f_taylor_ordem(func,var,num),ordem))+(xrang,)
    display(arg_plot)
    sym.plot(*arg_plot,ylim=yrang)

Existem 4 soluções importantes usadas aqui que merecem destaque:

1 – Operações com TUPLAS: Note que a forma de definir o intervalo do plot é uma tupla, fazermos uma operação de soma com duas tuplas para gerar o formato esperado pelo plot;

2 – Uso do MAP, map mapeia em uma função os elementos listados;

map(f(x),[1,2,3]) = [f(1),f(2),f(3)]

Mas o map mapeia em uma função e devemos avisar para ele qual é a variável que ele deve mapear, para isso usamos…

3 – Função LAMBDA, essa função basicamente deixa aberto o espaço da variável declarada na função em que está aplicada. O map mapeará nesse espaço aberto;

O MAP + LAMBDA poderiam ser substituidos por um loop, mas em geral o loop é mais lento que o MAP + LAMBDA;

4 – Usar o “” para aplicar uma tupla como argumento de uma função do python; Apenas substituir a tupla não funciona, umando nome_da_tupla, os n elementos são aplicados um após o outro como argumentos da função;

Exercício 5: Como verificamos que a forma de definir intervalo no sym.plot é uma tupla?

Exercício 6: Faça o loop correspondente ao MAP abaixo;

In [41]:
map(lambda x:sin(pi*x/8),range(10))

Vamos testar nossa criação: plot_taylor_compara

In [42]:
plot_taylor_compara(tan(x)) # com omissão dos parâmetros
(tan(x),0,x33+x,(x,−1,1))
In [43]:

plot_taylor_compara(tan(x),x,(-1.5,1.5),(-3,3),[1,3,5,7,9]) # especificando tudo
(tan(x),0,x,x33+x,2×515+x33+x,17×7315+2×515+x33+x,(x,−1.5,1.5))

Fica uma confusão para ler essses gráficos;

Vamos incluir cores:

In [44]:
def plot_taylor_compara_color(func, var=x, rang=(-3.14,3.14),yrang=(-1.2,1.2),ordem=[1,5]):
    xrang = (var,)+rang
    arg_plot=(func,)+tuple(map(lambda num:f_taylor_ordem(func,var,num),ordem))+(xrang,)
    gr=sym.plot(*arg_plot,ylim=yrang,title= "Grafico "+string0(func) + "e suas expansoes nas ordens "+string0(ordem),show=False)
    for i in range(1,len(ordem)+1):
        rgb=((1./random_integers(1,15)),(1./random_integers(1,15)),(1./random_integers(5,15)))
        gr[i].line_color = rgb  
    gr.show()
    print 'A função ' + string0(func) + ' sempre é azul!'

Exercício 7: Qual a serventia do random_integers?

Vamos ver o resultado do nosso trabalho…

In [45]:
plot_taylor_compara_color(exp(x)) # isso não ajudou muito!
A função exp(x) sempre é azul!
In [46]:
plot_taylor_compara_color(exp(x),x,(-8,20),(-10,200),range(1,8,1)) # especificando tudo
A função exp(x) sempre é azul!
In [47]:
plot_taylor_compara_color(exp(x),x,(-8,20),(155,165),range(1,8,1)) # Vamos mexer no yrange para ver melhor o que ocorre x=5;
A função exp(x) sempre é azul!
In [48]:
plot_taylor_compara_color(log(x+1),x,(0,2),(-0.75,1.5),range(2,15,1)) # Só está aqui pq é legal!
A função log(x + 1) sempre é azul!

Um pouco mais sobre gráficos do sympy

Como dissemos antes, para gráficos realmente profissionais devemos usar o MATPLOTLIB.

Mas mesmo com suas limitações, os gráficos do sympy são bastante versátis e com eles é possível esboçar muita coisa;

Gráficos implícitos;

In [49]:
sym.plot_implicit(Eq(x**2 + y**2, 4))
Out[49]:
<sympy.plotting.plot.Plot at 0x69da0d0>
In [50]:
plot_implicit(y > x**2 ,(x,-1,1)) # podemos pintar áreas
Out[50]:
<sympy.plotting.plot.Plot at 0x79d1390>
In [51]:
plot_implicit(And(y > x**2 , y < sqrt(x)),(x,-1,1.5),(y,-1,2),title='Intersecao de duas curvas') # podemos fazer algumas operações lógicas
Out[51]:
<sympy.plotting.plot.Plot at 0x6729750>
In [52]:
plot_implicit(Or(And(y > x**2 , y < sqrt(x)),And(y < -x**2 , y > -sqrt(-x))),(x,-1,1.5),(y,-1,2)) 
# Um pouco mais de operações lógicas
Out[52]:
<sympy.plotting.plot.Plot at 0x7d442d0>

Gráficos paramétricos

In [53]:
from sympy.plotting import plot_parametric
In [54]:
plot_parametric(cos(x), sin(x), (x, 0, 2*pi))
Out[54]:
<sympy.plotting.plot.Plot at 0x79d1110>
In [55]:
plot_parametric(x*cos(x), x*sin(x), (x, 0, 10*pi))
Out[55]:
<sympy.plotting.plot.Plot at 0x6217390>
In [56]:
plot_parametric(cos(x)*cos(x), cos(x)*sin(x), (x, 0, 2*pi))
Out[56]:
<sympy.plotting.plot.Plot at 0x7a6bf90>
In [57]:
plot_parametric(cos(20*x)*cos(x), cos(10*x)*sin(x), (x, 0, 2*pi),axis=False) # Até um pouco de arte da para fazer!
Out[57]:
<sympy.plotting.plot.Plot at 0xb155e50>
In [58]:
pl=plot_parametric(cos(20*x)*cos(x), cos(10*x)*sin(x), (x, 0, 2*pi),axis=False,show=False)
pl[0].line_color= lambda a: log(0.001*a)
pl.show()

Exercício 8 : Descubra se sympy faz gráficos 3D, em caso afirmativo mostre exemplos.

Python – Aula 2

Primeiros Passos no IPython Notebook

Disciplina “Computação no Ensino de Física” (CEF) da UFES/Alegre

Curso de Licenciatura em Física – Turma 2013/2

 Autoria : Prof. Ramón Giostri Campos – 2014/1.

 

Veremos abaixo como usar o IPython notebook como calculadora inteligente, como manipular strings, como criar estruturas (testes, loop, funçoes e et cetera), vamos tentar fazer alguns gráficos mais simples.

Depois veremos como misturar essas coisas;

Carregar o IPyhon notebook:

Digite $ipython notebook –pylab inline

A primeira parte “ipython notebook” é comum. A segunda parte ” –pylab inline” é opcional, porém ela é muito interessante pois permite que incluir os gráficos do matplotlib feitos aqui diretamente no corpo deste documento; Inclusive isso carrega automaticamente o PyLab (numpy e matplotlib);

Exercício 1

Pesquise outra forma de carregar o Pylab, para o caso de não usarmos o comando “–pylab inline” (isso as vezes é conveniente);

Usando como uma calculadora:

Note que apertar “enter”, apenas pula de linha (isso será útil mais tarde) e para executar a linha damos “shift+enter”

In [1]:
1+1
Out[1]:
2

In [2]:

(50-5*6)/4
Out[2]:
5
In [3]:
5/2
Out[3]:
2

Opa!!! Tem algo estranho aqui … sabemos que 5/2 = 2,5 . Mas o Python, assim como Fortran, C, Pascal, divisão de INTEIROS é truncada e com resultado INTEIRO;

Resolvemos o impasse simplismente enfiando um número REAL (tipo float) na conta;

In [4]:
5/float(2)
Out[4]:
2.5

Ou de forma mais simples, coloque um ponto em algum dos números!

In [5]:
5/2.
Out[5]:
2.5
In [6]:
5./2
Out[6]:
2.5

Note que claramente 2 não é igual a 2. (pelo menos no contexto de programação), por outro lado em termos de quantidade eles representam a mesma coisa.

In [7]:
2 is 2.

Out[7]:

False
In [8]:
2==2.
Out[8]:
True

Falaremos mais sobre testes em outro momento. Agora vamos continuar com a calculadora.

In [9]:
sqrt(2)
Out[9]:
1.4142135623730951
In [10]:
exp(1)
Out[10]:
2.7182818284590451
In [11]:
log(1.1)
Out[11]:
0.095310179804324935
In [12]:
pi
Out[12]:
3.141592653589793

In [13]:

sin(pi/4)
Out[13]:
0.70710678118654746
In [14]:
tan(pi/2)
Out[14]:
16331239353195370.0

Note que por ser tratar de um cálculo numérico, a tangente de pi/2 é calculada (só que dá um número muito grante). Sabemos que isso não é verdade.

Vamos definir algumas variáveis agora,

In [15]:
comprimento =10
largura = 20
area = comprimento * largura
area
Out[15]:
200
In [16]:
altura = 5
volume = area * altura
volume
Out[16]:
1000

Apesar do PyLab carregar muitas funções matemáticas, algumas ainda estão de fora, uma delas é o fatorial.

n! = n (n-1)(n-2)(n-3)…432*1

Corrigimos isso importando a seguinte função do pacote matemático MATH;

In [17]:
from math import factorial
In [18]:
factorial(12)
Out[18]:
479001600

Agora vamos manipular algumas STRINGS

In [19]:
'Assim pintamos strings'
Out[19]:
'Assim pintamos strings'
In [20]:
saldacao = ' Como vai?'
In [21]:
complemento = ' E ai Fulano!'
In [22]:
complemento + saldacao
Out[22]:
' E ai Fulano! Como vai?'
In [23]:
"Funciona com duas aspas"
Out[23]:
'Funciona com duas aspas'
In [24]:
"Mas os acentos não funcionam"
Out[24]:
'Mas os acentos n\xc3\xa3o funcionam'

Para esses casos use o PRINT

In [25]:
print complemento + saldacao, " não está bem!"
 E ai Fulano! Como vai?  não está bem!

Listas

Isso é natural no Python

In [26]:
dias_da_semana = ["domingo","segunda","terça","quarta", "quinta", "sexta", "sábado"]
In [27]:
dias_da_semana[2]
Out[27]:
'ter\xc3\xa7a'
In [28]:
print dias_da_semana[-1]
sábado
In [29]:
len(dias_da_semana)

Out[29]:

7

Exercício 2

Pesquise como descobrir mais informações sobre esse comando “len”?

Listas numéricas agora.

Usamos o RANGE (significa série ou variação em inglês)

In [157]:
?range
In [32]:
range(10)
Out[32]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [33]:
range(5,10)
Out[33]:
[5, 6, 7, 8, 9]
In [34]:
range(1,10,2)
Out[34]:
[1, 3, 5, 7, 9]
In [35]:
range(1,10,0.2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-cab7b13a5a94> in <module>()
----> 1 range(1,10,0.2)

TypeError: range() integer step argument expected, got float.

Usamos para isso o arange, que é uma rotina do NumPy

In [36]:
lista_float=arange(1,10,0.2)
print lista_float
type(lista_float)
[ 1.   1.2  1.4  1.6  1.8  2.   2.2  2.4  2.6  2.8  3.   3.2  3.4  3.6  3.8
  4.   4.2  4.4  4.6  4.8  5.   5.2  5.4  5.6  5.8  6.   6.2  6.4  6.6  6.8
  7.   7.2  7.4  7.6  7.8  8.   8.2  8.4  8.6  8.8  9.   9.2  9.4  9.6  9.8]
Out[36]:
numpy.ndarray
In [37]:
lista_float
Out[37]:
array([ 1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,  3. ,
        3.2,  3.4,  3.6,  3.8,  4. ,  4.2,  4.4,  4.6,  4.8,  5. ,  5.2,
        5.4,  5.6,  5.8,  6. ,  6.2,  6.4,  6.6,  6.8,  7. ,  7.2,  7.4,
        7.6,  7.8,  8. ,  8.2,  8.4,  8.6,  8.8,  9. ,  9.2,  9.4,  9.6,
        9.8])

Listas MISTAS

In [38]:
mista = [1, "lista", "estranha", 100.]
mista
Out[38]:
[1, 'lista', 'estranha', 100.0]
In [39]:
type(mista)
Out[39]:
list
In [40]:
?list

Cuidado, pois dependendo de como você gera uma “lista”, ela pode não ser defato uma lista (seja ela mista ou não).

In [41]:
tupla_mista = (1, "lista", "estranha", 100.)
In [42]:
type(tupla_mista)
Out[42]:
tuple
In [43]:
?tuple
In [44]:
set_mista = {1, "lista", "estranha", 100.}
In [45]:
type(set_mista)
Out[45]:
set
In [46]:
?set

Vamos as estruturas:

Loop

Exercício 3 – Tente ler o comando abaixo:

In [47]:
for i in range(len(mista)):
    tipo = type(mista[i])
    print tipo
<type 'int'>
<type 'str'>
<type 'str'>
<type 'float'>

Teste verdadeiro ou falso:

Teste de Igual

In [49]:
2==2.
Out[49]:
True

O duplo igual (==) é usado para o teste, pois tradicionalmente o igual simples (=) é usado para atribuição de valor;

In [16]:
v=2
In [50]:
v==float(2)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-50-1fafca712b6d> in <module>()
----> 1 v==float(2)

NameError: name 'v' is not defined

Outros testes:

In [19]:
2!=2.0
Out[19]:
False
In [51]:
2<1.01
Out[51]:
False
In [52]:
2<=1.01
Out[52]:
False
In [53]:
2>1.01
Out[53]:
True
In [54]:
2>=1.01
Out[54]:
True
In [55]:
for dia in dias_da_semana:
    qual_dia = "Hoje é " + dia
    print qual_dia
    if dia == "domingo":
        print "   Durmi até tarde"
    elif dia == "sábado":
        print "   Dia de tormir tarde..."
    else:
        print "   Vou ao trabalho"
Hoje é domingo
   Durmi até tarde
Hoje é segunda
   Vou ao trabalho
Hoje é terça
   Vou ao trabalho
Hoje é quarta
   Vou ao trabalho
Hoje é quinta
   Vou ao trabalho
Hoje é sexta
   Vou ao trabalho
Hoje é sábado
   Dia de tormir tarde...

Definindo funções

Vamos voltar ao tal do fatorial(n!), poderíamos fazer um no lugar de pegar um pronto.

Construindo a função Fatorial (Exercício 4 -> pesquisar outra forma de fazer o fatorial)

In [56]:
def fatorial(m):   # aqui dizemos quem é a função
    j = 1       # 
    n = m 
    if n > 1:  # Faz o teste se o número é maior que um;
        for i in range(1, n + 1): # Loop para fazer as multiplicações
             j = j * i # Interação
        return j      # Retorno o resultado
    else:
        return 1
#Cuidado com a identação ela pode gerar erros!
In [57]:
fatorial(12)
Out[57]:
479001600
In [58]:
fatorial(12.11)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-58-408a4ad43407> in <module>()
----> 1 fatorial(12.11)

<ipython-input-56-477990fc6bce> in fatorial(m)
      3     n = m
      4     if n > 1:  # Faz o teste se o número é maior que um;
----> 5         for i in range(1, n + 1): # Loop para fazer as multiplicações
      6              j = j * i # Interação
      7         return j      # Retorno o resultado

TypeError: range() integer end argument expected, got float.
In [59]:
factorial(12.1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-59-c8a524155186> in <module>()
----> 1 factorial(12.1)

ValueError: factorial() only accepts integral values

Exercício 5 – Tente bolar um filtro para números interios no nosso fatorial construído;

Soma da PA (Progressão Aritmética)

In [60]:
def somapa(a1,n,r):
    an = a1 + (n-1)*r #n-ésimo termo;
    sn = n*(a1+an)/2 #soma dos n primeiros termos
    return sn
In [75]:
somapa(1,10,2)
Out[75]:
100

Soma da PG (Progressão Geométrica)

In [62]:
def somapg(a1,n,q):
    sn = a1*(1-q**n)/(1-q) #soma dos n primeiros termos
    return sn
In [63]:
somapg(1,10,2)
Out[63]:
1023

Um pouco de gráficos (só para sentir o gostinho)

Primeiro vamos carregar o módulo gráfico

In [64]:
import matplotlib.pyplot as plt

Essa forma de carregar acrescente o prefixo plt nas funções carregadas pelo módulo. Funções com essa característica estão num CONTEXTO específico (nesse caso plt);

Digite os comandos help(plt) e dir(plt), para ver respectivamente o HELP do pacote e a LISTA de funções carregadas

In [122]:
x=arange(2,10,0.1)
print x
[ 2.   2.1  2.2  2.3  2.4  2.5  2.6  2.7  2.8  2.9  3.   3.1  3.2  3.3  3.4
  3.5  3.6  3.7  3.8  3.9  4.   4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9
  5.   5.1  5.2  5.3  5.4  5.5  5.6  5.7  5.8  5.9  6.   6.1  6.2  6.3  6.4
  6.5  6.6  6.7  6.8  6.9  7.   7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9
  8.   8.1  8.2  8.3  8.4  8.5  8.6  8.7  8.8  8.9  9.   9.1  9.2  9.3  9.4
  9.5  9.6  9.7  9.8  9.9]

É importante usar o ARANGE, no lugar do RANGE, para gerar uma lista passivel de ser usada pela função;

In [123]:
ypa=somapa(1,x,2)
print ypa
[  4.     4.41   4.84   5.29   5.76   6.25   6.76   7.29   7.84   8.41   9.
   9.61  10.24  10.89  11.56  12.25  12.96  13.69  14.44  15.21  16.    16.81
  17.64  18.49  19.36  20.25  21.16  22.09  23.04  24.01  25.    26.01
  27.04  28.09  29.16  30.25  31.36  32.49  33.64  34.81  36.    37.21
  38.44  39.69  40.96  42.25  43.56  44.89  46.24  47.61  49.    50.41
  51.84  53.29  54.76  56.25  57.76  59.29  60.84  62.41  64.    65.61
  67.24  68.89  70.56  72.25  73.96  75.69  77.44  79.21  81.    82.81
  84.64  86.49  88.36  90.25  92.16  94.09  96.04  98.01]
In [124]:
ypg=somapg(1,x,2)
print ypg
[   3.            3.28709385    3.59479342    3.92457765    4.27803164
    4.65685425    5.06286627    5.49801917    5.96440451    6.46426393
    7.            7.5741877     8.18958684    8.84915531    9.55606329
   10.3137085    11.12573253   11.99603834   12.92880901   13.92852786
   15.           16.1483754    17.37917368   18.69831061   20.11212657
   21.627417     23.25146506   24.99207668   26.85761803   28.85705573
   31.           33.2967508    35.75834736   38.39662123   41.22425314
   44.254834     47.50293013   50.98415337   54.71523605   58.71411146
   63.           67.5935016    72.51669472   77.79324245   83.44850629
   89.50966799   96.00586026  102.96830673  110.4304721   118.42822292
  127.          136.1870032   146.03338944  156.58648491  167.89701258
  180.01933598  193.01172051  206.93661347  221.8609442   237.85644583
  255.          273.37400641  293.06677888  314.17296982  336.79402516
  361.03867197  387.02344103  414.87322693  444.72188841  476.71289167
  511.          547.74801282  587.13355776  629.34593963  674.58805032
  723.07734394  775.04688205  830.74645387  890.44377682  954.42578333]
In [125]:
plt.plot(x,ypa,x,ypg)
Out[125]:
[<matplotlib.lines.Line2D at 0x44ba790>,
 <matplotlib.lines.Line2D at 0x44ba610>]

Primeiros Passos no IPython Notebook

Disciplina “Computação no Ensino de Física” (CEF) da UFES/Alegre

Curso de Licenciatura em Física – Turma 2013/2

 Autoria : Prof. Ramón Giostri Campos – 2014/1.

 

Veremos abaixo como usar o IPython notebook como calculadora inteligente, como manipular strings, como criar estruturas (testes, loop, funçoes e et cetera), vamos tentar fazer alguns gráficos mais simples.

Depois veremos como misturar essas coisas;

Carregar o IPyhon notebook:

Digite $ipython notebook –pylab inline

A primeira parte “ipython notebook” é comum. A segunda parte “–pylab inline” é opcional, porém ela é muito interessante pois permite que incluir os gráficos do matplotlib feitos aqui diretamente no corpo deste documento; Inclusive isso carrega automaticamente o PyLab (numpy e matplotlib);

Exercício 1

Pesquise outra forma de carregar o Pylab, para o caso de não usarmos o comando “–pylab inline” (isso as vezes é conveniente);

Usando como uma calculadora:

Note que apertar “enter”, apenas pula de linha (isso será útil mais tarde) e para executar a linha damos “shift+enter”

In [1]:
1+1
Out[1]:
2

In [2]:

(50-5*6)/4
Out[2]:
5
In [3]:
5/2
Out[3]:
2

Opa!!! Tem algo estranho aqui … sabemos que 5/2 = 2,5 . Mas o Python, assim como Fortran, C, Pascal, divisão de INTEIROS é truncada e com resultado INTEIRO;

Resolvemos o impasse simplismente enfiando um número REAL (tipo float) na conta;

In [4]:
5/float(2)
Out[4]:
2.5

Ou de forma mais simples, coloque um ponto em algum dos números!

In [5]:
5/2.
Out[5]:
2.5
In [6]:
5./2
Out[6]:
2.5

Note que claramente 2 não é igual a 2. (pelo menos no contexto de programação), por outro lado em termos de quantidade eles representam a mesma coisa.

In [7]:
2 is 2.

Out[7]:

False
In [8]:
2==2.
Out[8]:
True

Falaremos mais sobre testes em outro momento. Agora vamos continuar com a calculadora.

In [9]:
sqrt(2)
Out[9]:
1.4142135623730951
In [10]:
exp(1)
Out[10]:
2.7182818284590451
In [11]:
log(1.1)
Out[11]:
0.095310179804324935
In [12]:
pi
Out[12]:
3.141592653589793

In [13]:

sin(pi/4)
Out[13]:
0.70710678118654746
In [14]:
tan(pi/2)
Out[14]:
16331239353195370.0

Note que por ser tratar de um cálculo numérico, a tangente de pi/2 é calculada (só que dá um número muito grante). Sabemos que isso não é verdade.

Vamos definir algumas variáveis agora,

In [15]:
comprimento =10
largura = 20
area = comprimento * largura
area
Out[15]:
200
In [16]:
altura = 5
volume = area * altura
volume
Out[16]:
1000

Apesar do PyLab carregar muitas funções matemáticas, algumas ainda estão de fora, uma delas é o fatorial.

n! = n (n-1)(n-2)(n-3)…432*1

Corrigimos isso importando a seguinte função do pacote matemático MATH;

In [17]:
from math import factorial
In [18]:
factorial(12)
Out[18]:
479001600

Agora vamos manipular algumas STRINGS

In [19]:
'Assim pintamos strings'
Out[19]:
'Assim pintamos strings'
In [20]:
saldacao = ' Como vai?'
In [21]:
complemento = ' E ai Fulano!'
In [22]:
complemento + saldacao
Out[22]:
' E ai Fulano! Como vai?'
In [23]:
"Funciona com duas aspas"
Out[23]:
'Funciona com duas aspas'
In [24]:
"Mas os acentos não funcionam"
Out[24]:
'Mas os acentos n\xc3\xa3o funcionam'

Para esses casos use o PRINT

In [25]:
print complemento + saldacao, " não está bem!"
 E ai Fulano! Como vai?  não está bem!

Listas

Isso é natural no Python

In [26]:
dias_da_semana = ["domingo","segunda","terça","quarta", "quinta", "sexta", "sábado"]
In [27]:
dias_da_semana[2]
Out[27]:
'ter\xc3\xa7a'
In [28]:
print dias_da_semana[-1]
sábado
In [29]:
len(dias_da_semana)

Out[29]:

7

Exercício 2

Pesquise como descobrir mais informações sobre esse comando “len”?

Listas numéricas agora.

Usamos o RANGE (significa série ou variação em inglês)

In [157]:
?range
In [32]:
range(10)
Out[32]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [33]:
range(5,10)
Out[33]:
[5, 6, 7, 8, 9]
In [34]:
range(1,10,2)
Out[34]:
[1, 3, 5, 7, 9]
In [35]:
range(1,10,0.2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-cab7b13a5a94> in <module>()
----> 1 range(1,10,0.2)

TypeError: range() integer step argument expected, got float.

Usamos para isso o arange, que é uma rotina do NumPy

In [36]:
lista_float=arange(1,10,0.2)
print lista_float
type(lista_float)
[ 1.   1.2  1.4  1.6  1.8  2.   2.2  2.4  2.6  2.8  3.   3.2  3.4  3.6  3.8
  4.   4.2  4.4  4.6  4.8  5.   5.2  5.4  5.6  5.8  6.   6.2  6.4  6.6  6.8
  7.   7.2  7.4  7.6  7.8  8.   8.2  8.4  8.6  8.8  9.   9.2  9.4  9.6  9.8]
Out[36]:
numpy.ndarray
In [37]:
lista_float
Out[37]:
array([ 1. ,  1.2,  1.4,  1.6,  1.8,  2. ,  2.2,  2.4,  2.6,  2.8,  3. ,
        3.2,  3.4,  3.6,  3.8,  4. ,  4.2,  4.4,  4.6,  4.8,  5. ,  5.2,
        5.4,  5.6,  5.8,  6. ,  6.2,  6.4,  6.6,  6.8,  7. ,  7.2,  7.4,
        7.6,  7.8,  8. ,  8.2,  8.4,  8.6,  8.8,  9. ,  9.2,  9.4,  9.6,
        9.8])

Listas MISTAS

In [38]:
mista = [1, "lista", "estranha", 100.]
mista
Out[38]:
[1, 'lista', 'estranha', 100.0]
In [39]:
type(mista)
Out[39]:
list
In [40]:
?list

Cuidado, pois dependendo de como você gera uma “lista”, ela pode não ser defato uma lista (seja ela mista ou não).

In [41]:
tupla_mista = (1, "lista", "estranha", 100.)
In [42]:
type(tupla_mista)
Out[42]:
tuple
In [43]:
?tuple
In [44]:
set_mista = {1, "lista", "estranha", 100.}
In [45]:
type(set_mista)
Out[45]:
set
In [46]:
?set

Vamos as estruturas:

Loop

Exercício 3 – Tente ler o comando abaixo:

In [47]:
for i in range(len(mista)):
    tipo = type(mista[i])
    print tipo
<type 'int'>
<type 'str'>
<type 'str'>
<type 'float'>

Teste verdadeiro ou falso:

Teste de Igual

In [49]:
2==2.
Out[49]:
True

O duplo igual (==) é usado para o teste, pois tradicionalmente o igual simples (=) é usado para atribuição de valor;

In [16]:
v=2
In [50]:
v==float(2)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-50-1fafca712b6d> in <module>()
----> 1 v==float(2)

NameError: name 'v' is not defined

Outros testes:

In [19]:
2!=2.0
Out[19]:
False
In [51]:
2<1.01
Out[51]:
False
In [52]:
2<=1.01
Out[52]:
False
In [53]:
2>1.01
Out[53]:
True
In [54]:
2>=1.01
Out[54]:
True
In [55]:
for dia in dias_da_semana:
    qual_dia = "Hoje é " + dia
    print qual_dia
    if dia == "domingo":
        print "   Durmi até tarde"
    elif dia == "sábado":
        print "   Dia de tormir tarde..."
    else:
        print "   Vou ao trabalho"
Hoje é domingo
   Durmi até tarde
Hoje é segunda
   Vou ao trabalho
Hoje é terça
   Vou ao trabalho
Hoje é quarta
   Vou ao trabalho
Hoje é quinta
   Vou ao trabalho
Hoje é sexta
   Vou ao trabalho
Hoje é sábado
   Dia de tormir tarde...

Definindo funções

Vamos voltar ao tal do fatorial(n!), poderíamos fazer um no lugar de pegar um pronto.

Construindo a função Fatorial (Exercício 4 -> pesquisar outra forma de fazer o fatorial)

In [56]:
def fatorial(m):   # aqui dizemos quem é a função
    j = 1       # 
    n = m 
    if n > 1:  # Faz o teste se o número é maior que um;
        for i in range(1, n + 1): # Loop para fazer as multiplicações
             j = j * i # Interação
        return j      # Retorno o resultado
    else:
        return 1
#Cuidado com a identação ela pode gerar erros!
In [57]:
fatorial(12)
Out[57]:
479001600
In [58]:
fatorial(12.11)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-58-408a4ad43407> in <module>()
----> 1 fatorial(12.11)

<ipython-input-56-477990fc6bce> in fatorial(m)
      3     n = m
      4     if n > 1:  # Faz o teste se o número é maior que um;
----> 5         for i in range(1, n + 1): # Loop para fazer as multiplicações
      6              j = j * i # Interação
      7         return j      # Retorno o resultado

TypeError: range() integer end argument expected, got float.
In [59]:
factorial(12.1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-59-c8a524155186> in <module>()
----> 1 factorial(12.1)

ValueError: factorial() only accepts integral values

Exercício 5 – Tente bolar um filtro para números interios no nosso fatorial construído;

Soma da PA (Progressão Aritmética)

In [60]:
def somapa(a1,n,r):
    an = a1 + (n-1)*r #n-ésimo termo;
    sn = n*(a1+an)/2 #soma dos n primeiros termos
    return sn
In [75]:
somapa(1,10,2)
Out[75]:
100

Soma da PG (Progressão Geométrica)

In [62]:
def somapg(a1,n,q):
    sn = a1*(1-q**n)/(1-q) #soma dos n primeiros termos
    return sn
In [63]:
somapg(1,10,2)
Out[63]:
1023

Um pouco de gráficos (só para sentir o gostinho)

Primeiro vamos carregar o módulo gráfico

In [64]:
import matplotlib.pyplot as plt

Essa forma de carregar acrescente o prefixo plt nas funções carregadas pelo módulo. Funções com essa característica estão num CONTEXTO específico (nesse caso plt);

Digite os comandos help(plt) e dir(plt), para ver respectivamente o HELP do pacote e a LISTA de funções carregadas

In [122]:
x=arange(2,10,0.1)
print x
[ 2.   2.1  2.2  2.3  2.4  2.5  2.6  2.7  2.8  2.9  3.   3.1  3.2  3.3  3.4
  3.5  3.6  3.7  3.8  3.9  4.   4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9
  5.   5.1  5.2  5.3  5.4  5.5  5.6  5.7  5.8  5.9  6.   6.1  6.2  6.3  6.4
  6.5  6.6  6.7  6.8  6.9  7.   7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9
  8.   8.1  8.2  8.3  8.4  8.5  8.6  8.7  8.8  8.9  9.   9.1  9.2  9.3  9.4
  9.5  9.6  9.7  9.8  9.9]

É importante usar o ARANGE, no lugar do RANGE, para gerar uma lista passivel de ser usada pela função;

In [123]:
ypa=somapa(1,x,2)
print ypa
[  4.     4.41   4.84   5.29   5.76   6.25   6.76   7.29   7.84   8.41   9.
   9.61  10.24  10.89  11.56  12.25  12.96  13.69  14.44  15.21  16.    16.81
  17.64  18.49  19.36  20.25  21.16  22.09  23.04  24.01  25.    26.01
  27.04  28.09  29.16  30.25  31.36  32.49  33.64  34.81  36.    37.21
  38.44  39.69  40.96  42.25  43.56  44.89  46.24  47.61  49.    50.41
  51.84  53.29  54.76  56.25  57.76  59.29  60.84  62.41  64.    65.61
  67.24  68.89  70.56  72.25  73.96  75.69  77.44  79.21  81.    82.81
  84.64  86.49  88.36  90.25  92.16  94.09  96.04  98.01]
In [124]:
ypg=somapg(1,x,2)
print ypg
[   3.            3.28709385    3.59479342    3.92457765    4.27803164
    4.65685425    5.06286627    5.49801917    5.96440451    6.46426393
    7.            7.5741877     8.18958684    8.84915531    9.55606329
   10.3137085    11.12573253   11.99603834   12.92880901   13.92852786
   15.           16.1483754    17.37917368   18.69831061   20.11212657
   21.627417     23.25146506   24.99207668   26.85761803   28.85705573
   31.           33.2967508    35.75834736   38.39662123   41.22425314
   44.254834     47.50293013   50.98415337   54.71523605   58.71411146
   63.           67.5935016    72.51669472   77.79324245   83.44850629
   89.50966799   96.00586026  102.96830673  110.4304721   118.42822292
  127.          136.1870032   146.03338944  156.58648491  167.89701258
  180.01933598  193.01172051  206.93661347  221.8609442   237.85644583
  255.          273.37400641  293.06677888  314.17296982  336.79402516
  361.03867197  387.02344103  414.87322693  444.72188841  476.71289167
  511.          547.74801282  587.13355776  629.34593963  674.58805032
  723.07734394  775.04688205  830.74645387  890.44377682  954.42578333]
In [125]:
plt.plot(x,ypa,x,ypg)
Out[125]:
[<matplotlib.lines.Line2D at 0x44ba790>,
 <matplotlib.lines.Line2D at 0x44ba610>]
In [134]:
plt.plot(x,ypa,x,ypg)
plt.xlabel('Numero de Termos') # Abaixo inserimos os nomes dos eixos
plt.ylabel('Soma dos termos')
plt.title('Evolucao da soma da PA e PG') # Isso acrescenta o título (sem acentos por hora)!
plt.show() # Isso mostra
In [167]:
plt.plot(x,ypa,x,ypg)
plt.xlabel('Numero de Termos') # Abaixo inserimos os nomes dos eixos
plt.ylabel('Soma dos termos')
plt.title('Evolucao da soma da PA e PG') # Isso acrescenta o título (sem acentos por hora)!
plt.legend(["PA", "PG"],loc=2) # Essa linha coloca a Legenda;
plt.show() # Isso mostra

Exercício 6 – Colocar acentos nos gráficos do matplotlib