# todo texto escrito após "#" é um comentário e não é interpretado pelo Python
1+2  # realiza a operação 1+2 e imprime na tela

2-1

3*5

7/2

7//2

2**3

5%2

"""
Explanation: Introdução à Programação em Python
Nesse Notebook aprenderemos:

operações básicas do Python, 
tipos básicos de variáveis,
entrada e saída de dados e, 
bibliotecas extras auxiliares.

 Operações Aritméticas 
O computador é essencialmente uma máquina de calcular. Para tanto temos diversas operações aritméticas disponíveis no Python:

soma (+): 1+2
subtração (-): 2-1
multiplicação (*): 3*5
divisão (/): 7/2
divisão inteira (//): 7//2
exponenciação (**): 2**3
resto da divisão (%): 5%2
End of explanation
"""


1 + 2 * 3

"""
Explanation: A ordem que as operações são executadas seguem uma ordem de precedência:
- primeiro as operações de divisão e multiplicação,
- em seguida adição e subtração.
End of explanation
"""


(1+2)*3

1 + (2*3)

"""
Explanation: A ordem pode ser alterada com o uso de parênteses.
End of explanation
"""


import math

math.sqrt(2.0) # raiz de 2

math.log(10)   # ln(10)

math.exp(1.0) # e^1 

math.log(math.exp(1.0)) # ln(e)

math.cos(math.pi) # cos(pi)

"""
Explanation: Além das operações básicas temos algumas operações mais complexas disponíveis.
Precisamos indicar que queremos usar tais funções com o comando:
python
import math
Nota: As funções matemáticas disponíveis podem ser consultadas na documentação.
End of explanation
"""


# Exercício 01

# Vamos fazer algumas operações básicas: escreva o código logo abaixo das instruções, ao completar a tarefa aperte "shift+enter"
# e verifique se a resposta está de acordo com o esperado

# 1) A razão áurea é dada pela eq. (1 + raiz(5))/2, imprima o resultado
# resultado deve ser 1.61803398875
 



# 2) A entropia é dada por:   -p*log(p) - (1-p)*log(1-p), 
# Note que o logaritmo é na base 2, procure na documentação como calcular log2.
# Calcule a entropia para:

# p = 0.5, resultado = 1.0




# p = 1.0, resultado = nan



# p = 0.0, resultado = nan



# p = 0.4, resultado = 0.970950594455



"""
Explanation: Os tipos numéricos em Python são chamados de:
- int, para números inteiros e,
- float, para números reais.
Complete os códigos abaixo e aperte SHIFT+ENTER para verificar se a saída é a esperada.
End of explanation
"""


x = 10 # o computador armazena o valor 10 na variável de nome x
x + 2

x * 3

"""
Explanation: Quando uma operação tem resultado indefinido o Python indica com o valor nan.
Variáveis
No exercício anterior, para calcular cada valor de entropia foi necessário digitar toda a fórmula para cada valor de p.
Além disso o valor de p era utilizado duas vezes em cada equação, tornando o trabalho tedioso e com tendência a erros.
Seria interessante criar uma célula do Notebook customizável para calcular a entropia de qualquer valor de p.
Da mesma forma que na matemática, podemos utilizar variáveis para generalizar uma expressão e alterar apenas os valores de tais variáveis.
No computador, tais variáveis armazenam valores em memória para uso posterior.
Para utilizarmos variáveis no Python basta dar um nome a ela e, em seguida, atribuir um valor utilizando o operador "=".
Uma vez que tal variável tem um valor, podemos realizar qualquer operação com ela:
End of explanation
"""


p = 0.4
-p*math.log(p,2) - (1.0-p)*math.log(1.0-p,2)

"""
Explanation: Dessa forma o calculo da entropia poderia ser feito como:
End of explanation
"""


p = float(input("Digite o valor de p: "))
-p*math.log(p,2) - (1.0-p)*math.log(1.0-p,2)

"""
Explanation: Ao alterar o valor de p, o programa retorna o resultado da nova entropia.
Podemos pedir que o usuário entre com os valores utilizando o comando input().
Esse comando vai esperar que o usuário digite algum valor e o atribuirá em uma variável.
Nota: precisamos especificar ao comando input o tipo de variável desejada, no nosso caso float.
End of explanation
"""


x = 1
type(x)

x = 1.0
type(x)

"""
Explanation: O nome das variáveis deve:
- começar com uma letra e,
- conter apenas letras, números e o símbolo "_".
Além disso existem alguns nomes já utilizados pelo Python e que não devem ser utilizados:
python
    and, as, assert, break, class, continue, def, del, elif, 
    else, except, exec, finally, for, from, global, if, 
    import, in, is, lambda, not, or, pass, print, raise,
    return, try, while, with, yield    
O Python determina automaticamente o tipo que a variável vai conter, de acordo com o que é atribuído a ela.
Podemos utilizar o comando type() para determinar o tipo atual da variável:
End of explanation
"""


True and False

True and True

True or False

True or True

not True

not False

x = 1
y = 2
x == y

x != y

x > y

x <= y

x <= y and x != y    # x < y?

x <= y and not (x != y)   # x >= y e x == y ==> x == y?

"""
Explanation: Outros tipos de dados
Booleanos
Além dos tipos numéricos temos também os tipos lógicos que podem conter o valor de verdadeiro (True) ou falso (False).
Esses valores são gerados através de operadores relacionais:
- Igualdade: 1 == 2 => False
- Desigualdade: 1 != 2 => True
- Maior e Maior ou igual: 1 &gt; 2, 1 &gt;= 2 => False
- Menor e Menor ou igual: 1 &lt; 2, 1 &lt;= 2 => True
E compostos com operadores booleanos:
- E: True and False => False
- Ou: True or False => True
- Não: not True => False
End of explanation
"""


texto = "Olá Mundo"
type(texto)

len(texto)

"""
Explanation: Strings
Temos também a opção de trabalhar com textos, ou strings.
Esse tipo é caracterizado por aspas simples ou duplas.
End of explanation
"""


ola = "Olá"
espaco = " "
mundo = "Mundo"
ola + espaco + mundo

(ola + espaco) * 6 + mundo

"""
Explanation: Podemos usar os operadores + e *, representando concatenação e repetição:
End of explanation
"""


texto = "Olá Mundo"
texto[0]

texto[2] # terceira letra

"""
Explanation: Podemos também obter um caractere da string utilizando o conceito de indexação.
Na indexação, colocamos um valor entre colchetes após o nome da variável para indicar a posição do elemento que nos interessa naquele momento.
A contagem de posição inicia do 0.
End of explanation
"""


texto[0:3]

texto[4:]  # omitir o último valor significa que quero ir até o fim

texto[:3] # nesse caso omiti o valor inicial

texto[-1]  # índice negativo representa uma contagem de trás para frente

texto[-1:-6:-1]  # o último valor, -1, indica que quero andar de trás para frente.

"""
Explanation: Podemos também usar a indexação para pegar faixas de valores:
End of explanation
"""


coordenadas = [1.0, 3.0]
coordenadas

lista = [1,2,3.0,'batata',True]
lista

len(lista)

"""
Explanation: Listas
Listas de valores são criadas colocando elementos de quaisquer tipos entre colchetes e separados por vírgulas.
As listas podem ser úteis para armazenar uma coleção de valores que utilizaremos em nosso programa.
End of explanation
"""


lista[0]  # imprime o primeiro elemento da lista

lista[0:3] # imprime os 3 primeiros elementos

lista[-1] # último elemento

"""
Explanation: O acesso aos elementos da lista é feito de forma similar às strings:
End of explanation
"""


#Exercício 02
import math
# 1) entre com o numero do mes do seu nascimento na variavel 'mes' e siga as instruções abaixo colocando o resultado
# na variável 'resultado'.
mes = int(input('Digite o mes do seu nascimento: '))
resultado = 0

# 1) multiplique o número por 2 e armazene na variavel de nome resultado

# 2) some 5 ao resultado e armazene nela mesma

# 3) multiplique por 50 armazenando em resultado

# 4) some sua idade ao resultado
idade = int(input('Digite sua idade: '))

# 5) subtraia resultado por 250

# o primeiro digito deve ser o mês e os dois últimos sua idade
print(resultado)

#Exercício 03

# 1) Peça para o usuario digitar o nome e imprima "Ola <nome>, como vai?"
# não esqueça que o nome deve ser digitado entre aspas.
nome = 
print()



# 2) Crie uma lista com 3 zeros peça para o usuário digitar 2 valores, armazenando nas 2 primeiras
# posicoes. Calcule a media dos dois primeiros valores e armazene na terceira posição.

# utilize input() para capturar os valores
lista =

print(lista)

"""
Explanation: Existem outros tipos mais avançados que veremos ao longo do curso.
Complete o código abaixo para realizar o que é pedido:
End of explanation
"""


x = float(input("Entre com um valor numérico: ")) # o valor digitado será um número em ponto flutuante
x/2

"""
Explanation: Entrada e Saída de Dados
Entrada de Dados
Durante essa primeira aula vimos sobre os comandos input() para capturar valores digitados pelo usuário e print() para imprimir os valores dos resultados.
O comando input() captura uma string digitada pelo usuário, essa string deve ser convertida de acordo com o que se espera dela:
End of explanation
"""


x = 10
int(x) + 2

float(x) * 2

str(x) * 2

"""
Explanation: Alguns dos comandos de conversão disponíveis são: int() para inteiros, float() para ponto flutuante e str() para strings.
End of explanation
"""


print(2) # imprime 2 e vai para a próxima linha
print(3, "ola", 4+5) # imprime múltiplos valores de diferentes tipos e vai para a próxima linha
print(1, 2, end=" ")   # imprime os dois valores mas não pula para a próxima linha
print(3,4) # continua impressão na mesma linha

"""
Explanation: Saída de Dados
A função print() permite escrever o valor de uma variável ou expressão na tela pulando para a próxima linha ao final.
Esse comando permite a impressão de diversos valores na mesma linha separando-os por ",".
Adicionalmente, se o último argumento da função for end=" " ele não pula para a próxima linha após a impressão.
End of explanation
"""


m = 1
n = 6
d = 1/float(n)
print('{}: {}/{} = {:.4}'.format("O valor da divisão", m, n, d)) 
# {} indica que as lacunas devem ser preenchidas e .4 é o número de casas decimais para o número.

print("Elemento 1 \t Elemento 2 \nElemento 3 \t Elemento 4")

"""
Explanation: A função print() permite o uso de alguns caracteres especiais como:
- '\t': adiciona uma tabulação
- '\n': pula uma linha
Podemos complementar a formatação da string com o comando format():
End of explanation
"""


import math
math.sqrt(2)

"""
Explanation: Bibliotecas Extras
O Python conta com diversas bibliotecas que automatizam muitas tarefas e permitem realizarmos experimentos interessantes.
Usualmente as bibliotecas, ou módulos, são importados através do comando:
python
import NOME 
e as funções das bibliotecas são chamadas precedidas pelo NOME do módulo.
Vimos isso anteriormente com a biblioteca math:
End of explanation
"""


from math import sqrt, exp
print(sqrt(2), exp(3))

"""
Explanation: Se soubermos exatamente as funções que iremos utilizar do módulo, podemos importá-los seletivamente com a sintaxe:
python
from NOME import FUNCAO
Nesse caso não precisamos preceder a função com NOME para executá-la:
End of explanation
"""


import math as mt
print(mt.sqrt(2), mt.exp(3))

"""
Explanation: Finalmente podemos apelidar o nome do módulo para facilitar a chamada de funções:
End of explanation
"""


print(dir(math))

"""
Explanation: O comando dir lista todas as funções disponíveis em uma biblioteca:
End of explanation
"""


help(math.sin)

"""
Explanation: E o comando help imprime uma ajuda sobre determinada função:
End of explanation
"""


%matplotlib inline
import matplotlib.pyplot as plt

x = [-5,-4,-3,-2,-1,0,1,2,3,4,5]
y = [25,16,9,4,1,0,1,4,9,16,25]

plt.figure(figsize=(8,8))   # Cria uma nova figura com largura e altura definida por figsize
plt.style.use('fivethirtyeight') # define um estilo de plotagem: # http://tonysyu.github.io/raw_content/matplotlib-style-gallery/gallery.html

plt.title('Eq. do Segundo Grau') # Escreve um título para o gráfico
plt.xlabel('x') # nome do eixo x
plt.ylabel(r'$x^2$') # nome do eixo y, as strings entre $ $ são formatadas como no latex

plt.plot(x,y, color='green') # cria um gráfico de linha com os valores de x e y e a cor definida por "color"

plt.show() # mostra o gráfico

# Leiam mais em: http://matplotlib.org/users/pyplot_tutorial.html

"""
Explanation: A biblioteca matplotlib permite plotar gráficos diversos.
Para usá-la no Jupyter Notebook primeiro devemos importar os comandos de plotagem:
python
%matplotlib inline 
import matplotlib.pyplot as plt
O comando %matplotlib inline indica para o Jupyter que todos os gráficos devem ser mostrados dentro do próprio notebook.
Vamos plotar alguns pontos de uma função quadrática utilizando o comando:
python
plt.plot(x,y)
onde x e y são listas com valores correspondentes a abscissa e ordenada, respectivamente.
Basicamente temos que:
- x será uma lista de pontos que queremos plotar e,
- y a aplicação da função $f(x) = x^2$ em cada ponto de x.
End of explanation
"""


