# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 2
#     language: python
#     name: python2
# ---

# # [**Py-Intro**] Aula 01
# # Instalando Python, introdução a bibliotecas e estruturas de dados
#
# ## O que você vai aprender nesta aula?
#
# Após o término da aula você terá aprendido:
# - Informações úteis sobre a linguagem Python
# - Instalar o python
# - O que é o Jupyter Notebook, como instalá-lo e rodá-lo 
# - Usar o ambiente virtual
# - Instalar bibliotecas
# - Acessar páginas usando Python
# - Estruturas de dados do Python: listas e dicionários
#
# # Sobre a linguagem Python
#
# Se você já conhece a linguagem e está animado em aprendê-la já pode seguir para a próxima seção.
# Se, mesmo assim, você ainda estiver curioso para saber mais sobre Python fique convidado a ler os próximos parágrafos.
#
# Python é uma linguagem simples, enxuta e poderosa. Com poucas linhas e sintaxe clara é possível executar tarefas complexas. Essa característica se dá, pois os tipos de dados de alto nível permitem fazer operações complexas de uma única vez, além de não ser necessário declarar variáveis ou tipos dos argumentos.
#
# Python vem com pilhas inclusas. Em sua biblioteca padrão há soluções para diversos tipos de problemas recorrentes, como:
# - Interface gráfica (tkinter)
# - Internet (requisições HTTP, email, sockets etc.)
# - Data, hora e calendário
# - Acesso a arquivos e pastas
# - Execução de outras aplicações/processos
# - E muito mais: https://docs.python.org/3/library/
#
# A linguagem foi criada em 1991 e desde então vem crescendo constantemente ano a ano, tanto no quesito de número de usuário quanto em atualizações e melhorias do interpretador e da linguagem em si. Atualmente Python está na versão 3.5 que trouxe várias features interessantes que podem ser conferidas [aqui](https://docs.python.org/3.5/whatsnew/changelog.html).
#
# Muitas empresas como Google, Facebook, Mozilla, Microsoft, Intel, IBM, Globo e Magazine Luiza usam Python em produtos como Instagram, YouTube e o g1 (portal de notícias da globo).
#
# *PS: Dica para vida: os patrocinadores de grandes eventos como, por exemplo PyCon [2015](https://us.pycon.org/2015/) e [2016](https://us.pycon.org/2016/),  usam e estão patrocinando a linguagem. E isso também vale para **qualquer outra tecnlogia**.*
#
# Python é uma linguagem interpretada, ou seja, seu código-fonte executado diretamente pelo interpretador, sem precisar de compilar o programa em instruções de linguagem de máquina.
#
# *PS: para agilizar a execução de módulos o interpretador do Python cria caches. Para saber mais, veja: [“Compiled” Python files](https://docs.python.org/3/tutorial/modules.html#compiled-python-files)*
#
# Por ser interpretada a Python ganha diversas vantagens, como:
# - Ganho de tempo por não precisar compilar/linkar o programa
# - Interpretador pode ser usado de forma interativa tornando possível realizar testes e experimentos
# - Este "caderno" - o jupyter notebook
#
# A linguagem possui 20 príncipios que guiam seu desenvolvimento e podem ser conferidos rodando o seguinte comando:

import this

# Agora é hora de por as mãos na massa! Vamos do começo:
#
# ## Instalando o Python 3.5
#
# Caso você já tenha o Python 3.5 siga para a próxima sessão!
#
# #### Debian e derivados (ubuntu, mint etc.)
#
#     $ sudo apt-get install python3.5
#
# #### Windows e OS X
#
# https://www.python.org/downloads/
#
# Caso você esteja usando o windows não esqueça de marcar a opção: "Add Python.exe to Path", como mostrado na seguinte imagem:
#
# ![Instalando o Python no Windows](http://tutorial.djangogirls.org/pt/python_installation/images/add_python_to_windows_path.png)
# <center>(imagem retirada do [Django Girls Tutorial](http://tutorial.djangogirls.org/pt/))</center>
#
# ## Virtualenv (Ambiente virtual)
#
# O virtualenv é uma ferramenta que serve para manter as dependências de projetos diferentes em pastas separadas, desse modo é possível trabalhar me um projeto usando, por exemplo, o Django 1.9 enquanto se mantém um projeto antigo que usa a versão 1.5 do framework.
#
# O virtualenv cria uma pasta contendo todas as dependências que um projeto Python necessita.
#
# O virtualenv já vem instalado no Python 3.5, para criar um novo ambiente faça:
#
# ##### Linux e Mac
#     $ python3.5 -m venv env
# ##### Windows
# Abra o programa de linha de comando do Windows e digite o comando abaixo. Isso pode ser feito apertando o `botão do windows + R`, digitando `cmd` e apertando ENTER.
#
#     > C:\Python3.5\python -m venv env
#
# Esse comando criará uma pasta chamada **env/** contendo os executáveis do Python e uma cópia do pip para instalar outros pacotes. Vale lembrar que o nome do ambiente virtual **env** pode ser trocado por qualquer outro.
#
# Para usar o virtualenv é necessário antes que ele seja ativado:
# ##### Linux e Mac
#     $ source env/bin/activate
# ##### Windows
#     > env\Scripts\activate
#     
# Para sair de um ambiente virtual use o comando `deactivate`.
#     
# Agora nosso ambiente virtual está pronto para ser usado!
#
# # Instalando pacotes com o pip
#
# O pip permite instalar pacotes Python (listados no [PyPI: the Python Package Index](http://pypi.python.org/)) de forma fácil. O pip significa "**p**ip **i**nstall **packages**" (ou pip instala pacotes).
#
# Por exemplo, vamos instalar a biblioteca requests que usaremos mais para frente nesta aula:
#
#     (env) $ pip install requests
#
# ## Jupyter Notebook
#
#
# O Jupyter Notebook é uma aplicação web que permite a criação e compatilhamento de documentos (notebooks) que contém código ao vivo, equações, visualizações e textos explanatórios. Ele é muito utilizado para transformação de dados, modelagem estatística, simulação numérica, aprendizado de máquina e ensino.
#
# Para rodá-lo em sua máquina é preciso: instalar, rodar o servidor e acessr pelo navegador! É mais simples do que parece, vamos fazer esses passos.
#
# ### Instalando
#
# Vamos instalar o jupyter notebook executando o seguinte comando:
#
#     (env) $ pip install jupyter[notebook]
#     
# #### No linux
#
# Caso não seja possível instalar o jupyter[notebook] rode:
# ```
#     $ sudo apt-get install build-essential python3.5-dev
#     (env) $ pip install --upgrade pip
#     (env) $ pip install jupyter[notebook]
# ```    
# ### Rodando
#
# Não esqueça de baixar este documento (Aula01.ipynb) e rodar o jupyter notebook na **mesma pasta**.
#
# Para rodá-lo e tornar possivel o acesso do notebook pelo navegador, execute o seguinte comando:
#
#     (env) $ jupyter notebook
#
# Agora é só acessar a página http://localhost:8888/notebooks (que deve ter sido aberta automaticamente) e abrir o notebook Aula01.ipynb que já estamos prontos para codificar!
#
# Para rodar um código específico clique na caixa do código e pressione CTRL+Enter

# # Acessando páginas web
#
# Nosso primeiro exemplo será criar o código de uma aplicação que nos permite baixar o código-fonte de sites.
#
# Para isso vamos usar a biblioteca `requests` que foi instalada em um passo anterior (caso você não tenha instalado rode `pip install requests`).
#
# Primeiro preciamos importar a `requests`:

import requests

# Agora vamos fazer uma requisição HTTP ao Github para baixar o conteúdo do repositório deste curso (através da URL https://github.com/lamenezes/python-intro):

url = 'https://github.com/lamenezes/python-intro'  # não é necessário declarar variáveis em python
response = requests.get(url)  # e nem especificar seu tipo
response.status_code

# 200 é o código de resposta que informa que a requisição foi bem sucedida (ou OK).
#
# *PS: No curso de Desenvolvimento Web com Django será explicado com calma como funciona o protocolo HTTP.*
#
# Agora vamos analisar os cabeçalhos dessa resposta:

print(response.headers)

# O atributo headers de response (`response.headers`) nos trouxe os cabeçalhos em forma de um dicionário (ou dict). O dict é uma estrutura de dados do Python utilizada para armazenar informações na forma de chave e valor envoltas por chaves {}. Dicts serão explicados mais para frente.
#
# Por motivos técnicos a saída foi apresentada em um formato difícil de ler, para melhorá-la podemos fazer um pequeno workaround:

dict(response.headers)

# Para acessar um cabeçalho específico por sua chave fazemos:

response.headers['content-type']

response.headers['date']

response.text[:1000]  # retorna os 1000 primeiros caracteres do conteúdo da resposta

# Como visto anteriormente a biblioteca requests permite o envio de requisições HTTP de maneira extremamante fácil. Para obter mais informações sobre a `requests` acesse a [doumentação oficial](http://docs.python-requests.org/en/master/).
#
# Agora que já aprendemos o básico podemos partir para um exemplo mais interessante.
#
# ### Acessando os dados da API do github
#
# O Github oferece uma API que fornece dados de seus repositórios públicos. São dadas informações como quantos projetos estão cadastrados na plataforma, quantos contribuidores trabalharam em quais repositórios, a quais organizações essas fazem parte e muito mais. (mais informações na [documentação oficial](https://developer.github.com/v3/))
#
# O acesso aos dados dessa API é feito através do envio de requisições HTTP para diferentes caminhos na URL base https://api.github.com/. Caso você queira testar a API, pode acessar o link anterior pelo navegador e mudar a URL manualmente, porém nosso foco aqui será usar a biblioteca `requests` para pegar esses dados.
#
# Todas as respostas da API são em formato JSON. O JSON siginifca JavaScript Object Notation e pronuncia-se "djêizon" e é um formato fácil de processar e simples de utilizar. Para mais informações sobre o JSON acesse a [página oficial](http://json.org/). Falaremos mais sobre JSON no decorrer do curso, mas fique tranquilo que não segredo há algum nesse assunto.
#
# Vamos testar a API e pegar os repositórios de um usuário específico através da URL https://api.github.com/users/lamenezes/repos:

response = requests.get('https://api.github.com/users/lamenezes/repos')
response.status_code

response.text[:1000]  # pegando os primeiros 1000 caracters do conteúdo da resposta

# A resposta trouxe todos os repositórios do usuário `lamenezes` em uma string no padrão JSON.
#
# Essa string não é interessante para nós, pois é difícil acessar dados específicos do JSON através dela. Seria muito melhor para nós se essa resposta fosse traduzida para um dicionário do Python (que possui sintaxe muito parecida com o JSON).
#
# Normalmente teríamos que importar a biblioteca json e realizar a conversão, no pior caso poderia ser necessário escrever um parser específico para tratar casos especiais.
#
# No entanto, a biblioteca `requests` já faz esse trabalho para nós:

repositorios = response.json()
repo = repositorios[0]  # pegando apenas o primeiro repositório por brevidade
repo

# A resposta nos trouxe uma `lista` de `dicionários` com as informações dos repositórios do usuário `lamenezes`. Agora fica a dúvida: o que exatamente é uma lista e um dicionário?
#
# ### Listas
#
# Listas, como o próprio nome sugere, são estruturas de dados mutáveis que armanzenam listas de valores. Os valores da lista são acessados pelo número relativo a sua posição.
#
# Ao invés de gastar dedos digitando mais sobre o que é uma lista é mais fácil demonstrá-la:

numeros = [1, 2.5, 3, 4.5, 5]
numeros

numeros[0]

numeros[3]

numeros[-1]  # -1 acessa o último elemento da lista!

# Listas podem armazenar qualquer tipo de dados:

lista = ['foobar', False, ['a', 'b', 'c'], {'foo': 'bar'}, 10, -0.5]
lista

# Fazemos assim para verificar se um elemento faz parte de uma lista:

'foobar' in lista

'abc' in lista

-0.5 in lista 

# Para saber o tamanho de uma lista basta usar a função `len()`:

len(lista)

len(lista[2])  # o segundo elemento da lista é uma lista com 3 elementos!

len(numeros)

# Para remover elementos de uma lista existe a palavra reservada `del` que é utilizada assim:

lista

del lista[3]
lista

del lista[-1]  # remove último elemento
lista

# Iterar uma lista é simples:

for numero in numeros:
    print(numero)

# O for do Python, diferentemente de outras linguagens como C e Java, faz o controle dos índices internamente.
#
# Vamos fazer mais um exemplo para deixar claro:

numeros = range(1, 11)  # cria uma lista de números de 1 a 10
list(numeros)

for numero in numeros:
    print(numero ** 2)  # numero elevado a segunda potência

# A função range(inicio, fim) cria listas de valores no intervalo de inicio até fim - 1. Ao lidar com intervalos no python o primeiro número é sempre incluso e o último excluído. Segue alguns exemplos de uso da função range()

list(range(10))  # números de 0 a 9

list(range(10, 20))  # números de 10 a 19

list(range(10, 21))  # números de 10 a 20

# #### Exercício
#
# Crie uma lista de números de 2 a 8 e imprima cada número vezes pi. Substiua os ... por código python.

# +
from math import pi

numeros = ...  # crie a lista de números de 2 a 8
for numero in numeros:
    print( ... )  # imprime o número vezes pi
# -

# #### Exercicio
#
# Crie uma lista de preços de produtos em dólar (somente números) e imprima seu valor convertido para reais.

taxa_dolar = 3.53  # mude esse valor caso o valor do dólar tenha mudado
preços = ...  # python 3 permite declarar variáveis com acentos
for preço in preço:
    print(...)

# ### Dicionários
#
# Dicionários são estruturas de dados utilizadas para armazenar conjuntos de chaves e valores. Em algumas linguagens também são conhecidos como mapaemento.
#
# A diferança de uso entre lista e dicionáro é que o último é acessado por *chaves* e não pela *posição*. As chaves podem ser inteiros, strings, booleanos e tuplas (este será visto na próxima aula).
#
# A seguir temos alguns simples exemplos de uso de diconários.
#
# Criar um dict é simples:

notas = {'joao': 5, 'maria': 9, 'ana': 7}
notas

# Para acessar os elementos basta usar sua chave:

notas['ana']

notas['joao']

# Para alterar algum valor fazemos:

notas['joao'] = 6.5
notas

notas['ana'] = 7.5
notas

# Verificamos se uma chave existe no dicionário da seguinte maneira:

'joao' in notas  # verifica se o valor é uma chave do dicionário

'joana' in notas

'ana' in notas

# Para acessar somente as chaves fazemos:

list(notas.keys())

# Para acessar somente os valores:

list(notas.values())

# Para ter uma lista contendo as chaves e valores:

list(notas.items())

# Para iterar dicionáros é preciso ter cuidado. Por padrão as chaves do dicionário são iteradas:

for chave in notas:
    print(chave)

# Caso você queira imprimir os valores é preciso usar `notas.values()`:

for valor in notas.values():
    print(valor)

# Para iterar tanto a chave quanto o valor use a função `notas.items()` como mostrado a seguir:

for chave, valor in notas.items():
    print(chave, valor)

# Para ficar mais claro podemos mudar os nomes das variáveis e para ficar mais inteligível formatar a saída:

for nome, nota in notas.items():
    print('{0} tirou {1}.'.format(nome.capitalize(), nota))

list(notas.items())

# Como visto acima o `notas.items()` retorna uma lista de chaves e valores. Por esse motivo a cada iteração temos acesso a cada chave e valor do dicionário `notas`, tornando possível essa iteração mais simples e semântica.

# Agora que já temos uma noção das estruturas de dados utilizadas, podemos continuar a visualizar as informações dos repositórios do github:
#
# *PS: relaxe, pois nas próximas aulas veremos a fundo essas estruturas!*
#
# ### De volta à API do github
#
# Anteriormente realizamos uma requisição à API do github para pegar os repositórios do usuário `lamenezes` e armazenamos a resposta na variável `response`. Essa variável ainda está disponível para nós, o que nos permite continuar nosso exemplo anterior:

repositorios = response.json()  # lista de dicionários com dados de cada repositório
repo = repositorios[11]  # vamos analisar o décimo primeiro repositório
repo

repo['full_name']

repo['description']

repo['created_at']  # data de criação

repo['html_url']  # URL da página principal do repositório

# Também temos os dados do dono (owner) do repositório:

dono = repo['owner']
dono['login']

# `'owner'` é um dicionário dentro do dicionário do repositório (sim, é possível guardar dicionários dentro de dicionários)
#
# Também podemos acessar as informações diretamente sem recorrer à variável intermediária `dono`:

repo['owner']['login']

# ### Exercicios
#
# - Quantos repositórios o usuário `lamenezes` possui?
#
# Lembrando que esses repositórios estão armazenados na lista `repositorios`

# +
# digite o código aqui
# -

# - Imprima as URLs de todos os repositórios

# +
# digite o código aqui
# -

# Para os próximos exercícios será necessáro pegar os repositórios do usuário `gvanrossum`. Use a biblioteca requests e faça uma requição à API do github (https://api.github.com/) como demostrado anteriormente.

response = ...
response.status_code  # status_code deve ser 200

# Agora pegue o conteúdo da resposta em formato JSON e atribua à variável `repos`:

repos = ...
len(repos)  # esta linha deve retornar 5

# - Imprima o nome e descrição de todos os repositórios do `gvanrossum`:

# +
import requests

response = requests.get('https://api.github.com/users/gvanrossum/repos')
repositorios = response.json()
for repositorio in repositorios:
    print(repositorio['full_name'], repositorio['description'])
# -

# - Quantos forks o repositório gvanrossum/asyncio possui?

# +
# digite o código aqui
# -

# - Qual o link do perfil do dono dos repositórios?

# +
# digite o código aqui
# -

# Última pergunta:
#
# - Quem é `gvanrossum`?

# #### Fim da Aula 01

StarcoderdataJupyterScriptsDedupFiltered