Buscar

04 Aula Estrutura e tipos de dados

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

{
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Tipos de Dados e Estrutura de Dados¶"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Sumário <a name=\"CP3-sumario\"></a> \n",
 "\n",
 "* [Variáveis](#CP3-variaveis)\n",
 "* [O que é um tipo?](#CP3-o-que-e-um-tipo)\n",
 "* [Números](#CP3-numeros)\n",
 " - [Outras informações](#CP3-num-outras-inf)\n",
 " - [Números inteiros](#CP3-numeros-inteiros)\n",
 " + [Limite dos inteiros](#CP3-limite-int)\n",
 " - [Números de ponto flutuante](#CP3-numeros-float)\n",
 " - [Erro de Representação](#CP3-Erros-de-Representação)\n",
 " - [Módulo Decimal](#CP3-Modulo-Decimal)\n",
 " - [Tipo Fração: A função Fraction](#CP3-Tipo-Fracao)\n",
 " - [Números complexos](#CP3-numeros-complexos) \n",
 " - [Funções aplicáveis a todos os tipos de números](#CP3-func-numeros)\n",
 "* [Sequências](#CP3-sequencias)\n",
 " - [Sequência tipo 1: String](#CP3-sequencias-t1)\n",
 " - [Sequência tipo 2: Lista](#CP3-sequencias-t2)\n",
 " + [O comando range()](#CP3-cmd-range)\n",
 " - [Sequência tipo 3: Tupla](#CP3-sequencias-t3)\n",
 " - [Indexando Sequências](#CP3-index-seq)\n",
 " - [Fatiamento de sequências](#CP3-fat-seq)\n",
 " - [Expressões asteriscos](#CP3-Exp-asterisco)\n",
 " - [Exemplo: Ano Bissexto](#CP3-Ex-ano-bissexto)\n",
 "* [Conjuntos (set e frozenset)](#CP3-Conjuntos)\n",
 " - [O que são sets](#CP3-OQSSets)\n",
 " - [Operações lógicas](#CP3-OperacoesLogicas)\n",
 " - [União](#CP3-Uniao)\n",
 " - [Interseção](#CP3-Intersecao)\n",
 " - [Diferença](#CP3-Diferencas)\n",
 " - [Diferença Simétrica](#CP3-DifSim)\n",
 " - [Pertinência](#CP3-Pertinencia)\n",
 " - [Subconjuntos](#CP3-Subconjuntos)\n",
 " - [Operações entre conjuntos set e frozenset](#CP3-Op-set-frozenset)\n",
 "* [Dicionários](#CP3-dicionarios)\n",
 " - [Exemplo de uso dos dicionários](#CP3-Exemplo-dicionarios)\n",
 "* [Passando argumentos para funções](#CP3-pass-arg-func)\n",
 " - [Chamada por valor](#CP3-func-cham-valor)\n",
 " - [Chamada por referência](#CP3-func-cham-ref)\n",
 "* [Passagem de Argumentos no Python](#CP3-pass-arg-py)\n",
 " - [Considerações Sobre Performance](#CP3-performance)\n",
 " - [Modificações Inadevertidas de Dados ](#CP3-mod-in-dados)\n",
 " - [Copiando objetos](#CP3-cop-objs)\n",
 "* [Igualdade e Identidade/Semelhança](#CP3-Igualdade-identidade)\n",
 " - [Igualdade](#CP3-Igualdade)\n",
 " - [Identidade/Semelhança](#CP3-Identidade)\n",
 " - [Exemplo: Igualdade e identidade](#CP3-Exemplo-ig-id)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Variáveis <a name=\"CP3-variaveis\"></a>\n",
 "\n",
 "\n",
 "Variáveis no interpretador Python são criadas através da atribuição e destruídas pelo coletor de lixo (garbage collector), quando não existem mais referências a elas.\n",
 "\n",
 "Os nomes das variáveis devem começar com letra (sem acentuação) ou sublinhado (_) e seguido por letras (sem acentuação), dígitos ou sublinhados (_), sendo que maiúsculas e minúsculas são consideradas diferentes.\n",
 "\n",
 "\n",
 "## O que é um tipo? <a name=\"CP3-o-que-e-um-tipo\"></a>\n",
 "\n",
 "\n",
 "Existem vários tipos simples de dados pré-definidos no Python, tais como:\n",
 "\n",
 "+ Números:\n",
 " - Inteiros (int)\n",
 " - Reais de ponto flutuantes (float)\n",
 " - complexos (complex)\n",
 "+ Texto (string)\n",
 "+ Boleanas\n",
 " - True\n",
 " - False\n",
 "\n",
 "Além disso, existem tipos que funcionam como coleções. Os principais são:\n",
 "\n",
 "+ Lista\n",
 "+ Tupla\n",
 "+ Dicionário\n",
 "+ Conjuntos\n",
 "\n",
 "Os tipos no Python podem ser:\n",
 "\n",
 "+ Mutáveis: permitem que os conteúdos das variáveis sejam alterados.\n",
 "+ Imutáveis: não permitem que os conteúdos das variáveis sejam alterados.\n",
 "\n",
 "Em Python, os nomes de variáveis são referências, que podem ser alteradas em tempos de execução.\n",
 "\n",
 "Os tipos e rotinas mais comuns estão implementados na forma de *builtins*, ou seja, eles estão sempre disponíveis em tempo de execução, sem a necessdade de importar nenhuma biblioteca.\n",
 "\n",
 "O Python conhece diferentes tipos de dados. Para encontrar o tipo de uma variável, use a função `type()`. Como exemplo considere as seguintes atribuições:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = 45\n",
 "type(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "b = 'Isso é uma string. Um texto ou palavra são strings. '\n",
 "type(b)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "No python os operadores + e * atuam nas strings concatenando elas. Vejamos os examplos a seguir:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "c=\"O que é isso? \" + b"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(c,2*c)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O python é uma linguagem de tipagem dinâmica, observer que antes c era do tipo string a agora:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "c = 2 + 1j\n",
 "type(c)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(c)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "d = [1, 3, 56]\n",
 "type(d)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(c, d)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 " Números <a name=\"CP3-numeros\"></a> \n",
 "\n",
 "Python oferece alguns tipos numéricos na forma de *builtins*:\n",
 "\n",
 "+ Inteiro (*int*): i = 1\n",
 "+ Real de ponto flutuante (*float*): f = 3.14\n",
 "+ Complexo (*complex*): c = 3 + 4j\n",
 "\n",
 "Além dos números inteiros convencionais, existem também os inteiros longos, que tem dimensão arbitrária e são limitados pela memória disponível. As conversões entre inteiro e longo são realizadas de forma automática. A função *builtin int()* pode ser usada para converter outros tipos para inteiro, incluindo mudanças de base.\n",
 "\n",
 "## Outras informações <a name=\"CP3-num-outras-inf\"></a>\n",
 "\n",
 "- Introdução Informal aos números. [Python tutorial, section 3.1.1](http://docs.python.org/tutorial/introduction.html#using-python-as-a-calculator)\n",
 "\n",
 "- Biblioteca de Referência do Python: uma visão formal do tipos numéricos, <http://docs.python.org/library/stdtypes.html#numeric-types-int-float-long-complex>\n",
 "\n",
 "- Como Pensar Como um Cientista da Computação [seção 2.1](https://panda.ime.usp.br/pensepy/static/pensepy/) ou no original em inglês Think Python, [Sec 2.1](http://www.greenteapress.com/thinkpython/html/book003.html)\n",
 "\n",
 "\n",
 "Os tipos numéricos builtin são os inteiros, os números de ponto flutuante (veja [Números de ponto flutuante](#Números
de ponto flutuante)) e os números complexos de ponto flutuante ([Números complexos](#Números complexos)).\n",
 "\n",
 "## Inteiros <a name=\"CP3-numeros-inteiros\"></a> \n",
 "\n",
 "Os numeros inteiros já foram visto em [Capítulo 3](03-Aula-Uma-poderosa-calculadora.ipynb). Os alertas quanto aos cuidados que se deve ter na divisão de inteiros já foi feito em ([integer division](03-Aula-Uma-poderosa-calculadora.ipynb#Divisão Inteira (Integer division))).\n",
 "\n",
 "Se precisamos converter uma string contendo um número inteiro para um inteiro podemos usar a função `int()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = '34' # a é uma string contendo os caracteres 3 e 4\n",
 "print(\"A variável a é do tipo\", type(a),\" e o seu conteúdo é: \", a)\n",
 "x = int(a) # x será um número inteiro, como pode ser visto\n",
 "print(\"A variável x é do tipo\", type(x),\" e o seu conteúdo é: \", x)\n",
 "print(\"x+2 = \", x+2)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a+3"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A função `int()` também converterá números de ponto flutuante em inteiros:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(int(7.2),int(7.8))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note que int irá truncar qualquer parte não-inteira de um número de ponto flutuante. Para arredondar use a função `round` um número de ponto flutuante para um inteiro, use o comando `round()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(round(7.9),round(6.2),round(8.51),round(9.459))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Limite dos inteiros <a name=\"CP3-limite-int\"></a>\n",
 "\n",
 "Inteiros em Python 3 são ilimitados; O Python atribuirá automaticamente mais memória conforme necessário à medida que os números crescerem. Isso significa que podemos calcular números muito grandes sem etapas especiais."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Em muitas outras linguagens de programação, como C e FORTRAN, os inteiros possuem um tamanho fixo - mais freqüentemente de 4 bytes, o que permite $2^{32}$ valores diferentes -, mas diferentes tipos estão disponíveis com tamanhos diferentes. Para números que se encaixam nesses limites, os cálculos podem ser mais rápidos, mas talvez seja necessário verificar se os números não ultrapassam os limites. Cálculo de um número além dos limites é chamado de *overflow de inteiro*, e pode produzir resultados bizarros.\n",
 "\n",
 "Mesmo em Python, precisamos estar cientes disso quando usamos numpy (ver [Capítulo 14](14-numpy.ipynb)). A biblioteca Numpy usa números inteiros com um tamanho fixo, porque armazena muitos deles juntos e precisa rrealizar seus calculos de forma eficiente com eles. [Numpy data types](http://docs.scipy.org/doc/numpy/user/basics.types.html) incluem um intervalo de tipos inteiros nomeados para o seu tamanho, por exemplo. `Int16` é um inteiro de 16 bits, com $2^{16}$ valores possíveis.\n",
 "\n",
 "Os tipos inteiros também podem ser *signed* ou *unsigned*. Os inteiros *signed* permitem valores positivos ou negativos, os inteiros *unsigned* permitem apenas valores positivos. Por exemplo:\n",
 "\n",
 "* uint16 (unsigned) varia de 0 até $2^{16}-1$\n",
 "* int16 (signed) varia de $-2^{15}$ até $2^{15}-1$"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "35**84"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Para usar o último resultado use `_`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "2*_"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a=str(_)\n",
 "print(a, len(a))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Números de ponto flutuante <a name=\"CP3-numeros-float\"></a> \n",
 "\n",
 "Uma string contendo um número de ponto flutuante pode ser convertida em um número de ponto flutuante usando o comando `float()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = '35.342' # a é uma string \n",
 "print(\"A variável a é do tipo\", type(a),\" e o seu conteúdo é: \", a)\n",
 "x = float(a) # x será um número de ponto flutuante, como pode ser visto\n",
 "print(\"A variável x é do tipo\", type(x),\" e o seu conteúdo é: \", x)\n",
 "print(\"x+1.102 = \", x+1.1020)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type(b)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "<span style=\"color:red\"; font-size:100%;>\n",
 "<span style=\"background-color:yellow\"; font-family:'Liberations'; font-size: 14pt;>A sessão abaixo foi incluída simplesmente por uma questão de completeza, não precisa ser lida em, uma primeira leitura</span> </span>\n",
 "\n",
 "\n",
 "### Python `str()` ou `repr()` em um número de ponto flutuante?\n",
 "\n",
 "Muitas vezes precisamos converter objetos em sua representação de sequência de caracteres para saída agradável. Para fazer isso em python, podemos usar a função built-in `str()`. No entanto, pode não ser sempre a melhor função para usar. Isto é especialmente verdadeiro se queremos produzir com precisão número de ponto flutuante como uma string:\n",
 "\n",
 "```pyyhon\n",
 ">>> x = 1.000000000009\n",
 ">>> str(x)\n",
 "'1.00000000001'\n",
 "```\n",
 "\n",
 "No python 3 foi introduzida o módulo [`reprlib`](https://docs.python.org/3/library/reprlib.html?highlight=reprlib#module-reprlib) o qual fornece um meio para produzir representações de objeto com limites no tamanho das cadeias resultantes. Isso é usado no depurador Python e pode ser útil em outros contextos também.\n",
 "\n",
 "Este módulo fornece uma classe, uma instância e uma função:\n",
 "\n",
 "> class reprlib.Repr\n",
 ">\n",
 "> Classe que fornece serviços de formatação úteis na implementação de funções semelhantes ao built-in `repr()`; Os limites de tamanho para diferentes tipos de objetos são adicionados para evitar a geração de representações que são excessivamente longas.\n",
 "\n",
 "\n",
 "Do manual do [python 3](https://docs.python.org/3/library/functions.html?highlight=repr#repr) a função `repr()` *retorna uma string contendo uma representação imprimível de um objeto. Para muitos tipos, essa função faz uma tentativa de retornar uma string que renderia um objeto com o mesmo valor quando passada para `eval()`, caso contrário a representação é uma string entre colchetes angulares que contém o nome do tipo do objeto em junto com informações adicionais, muitas vezes incluindo o nome e o endereço do objeto. Uma classe pode controlar o que essa função retorna para suas instâncias definindo um método `__repr__ ()`.*\n",
 "\n",
 "> Classe str (object = '')\n",
 ">\n",
 "> Retorna uma string contendo uma representação bem imprimível
de um objeto. Para strings, isso retorna a sequência em si. A diferença com repr (objeto) é que str (objeto) nem sempre tenta retornar uma string que é aceitável para eval (); Seu objetivo é retornar uma sequência imprimível. Se nenhum argumento é fornecido, retorna a sequência vazia ' '.\n",
 "\n",
 "Então, se quisermos mostrar o número de ponto flutuante exato, precisamos usar `repr()` em vez de `str()`:\n",
 "\n",
 "```python\n",
 ">>> x = 1.000000000009\n",
 ">>> repr(x)\n",
 "'1.000000000009'\n",
 "```\n",
 "\n",
 "Curiosamente, chamar `str()` em uma tupla contendo um número de ponto flutuante produz o seguinte resultado:\n",
 "\n",
 "```python\n",
 ">>> X = (1.000000000009, 3)\n",
 ">>> str(x)\n",
 "'(1.000000000009, 3)'\n",
 "```\n",
 "\n",
 "Acontece que isso ocorre porque a impressão de uma tupla usa PyObject_Print que tem a seguinte documentação:\n",
 "\n",
 "> int PyObject_Print(PyObject *o, FILE *fp, int flags)\n",
 ">\n",
 "> Imprimir um objeto o, no arquivo fp. Retorna -1 em caso de erro. O argumento flags é usado para ativar certas opções de impressão. A única opção atualmente suportada é Py_PRINT_RAW; Se for dado, o `str()` do objeto ela é escrita em vez do `repr()`.\n",
 "\n",
 "A chamada para PyObject_Print dentro função de impressão tupla não tem o sinalizador Py_PRINT_RAW definido e, portanto, imprime o repr de cada objeto dentro dele. Portanto, mesmo se você chamar `str()` na tupla você terá suas representações representativas de objetos, o que pode não ser o que você está esperando!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x = 1.000000000009\n",
 "X = (1.000000000009, 3)\n",
 "str(X)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "repr(x)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Retorna ao [Sumário](#CP3-sumario)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Representação dos números de ponto flutuante\n",
 "\n",
 "Mairoes detalhes sobre os números de ponto flutuante são obtidos no excelente artigo [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) e na página [What Every Programmer Should Know About Floating-Point Arithmetic or Why don’t my numbers add up?](http://floating-point-gui.de/). Também é uma boa fonte o manual do python 3 a seção [15. Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3/tutorial/floatingpoint.html?highlight=float%20point) e a [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3/library/decimal.html?highlight=float%20point). Uma relação completa dos [objetos de ponto flutuantes do python 3](https://docs.python.org/3/c-api/float.html?highlight=float%20point) e as funções intrínsecas do python 3 são encontradas na seção [2. Built-in Functions](https://docs.python.org/3/library/functions.html).\n",
 "\n",
 "\n",
 "Os números de ponto flutuante são representados no hardware do computador como frações na base 2 (binária). Por exemplo, a fração decimal 0.125 tem o seguinte valor\n",
 "\n",
 "$$ 0.125 = \\frac{1}{10}+\\frac{2}{100}+\\frac{5}{1000},$$\n",
 "\n",
 "e do mesmo modo a fração binária 0.001 tem o seguinte valor\n",
 "\n",
 "$$ 0.001 = \\frac{0}{2}+\\frac{0}{4}+\\frac{1}{8}.$$\n",
 "\n",
 "Essas duas frações possuem valores identicos, a única diferença real deve-se ao fato de que a primeira foi escrita na notação de fração na base 10 enquanto a segunda foi escrita na base 2.\n",
 "\n",
 "Infelizmente, a maioria das frações decimais não pode ser representada exatamente como frações binárias. Uma consequência disso é que, em geral, os números decimais de ponto flutuante que você digita são aproximados apenas pelos números binários de ponto flutuante que são realmente armazenados na máquina.\n",
 "\n",
 "O problema é mais fácil de entender no início na base 10. Considere a fração 1/3. Você pode aproximar isso como uma fração de base 10:\n",
 "\n",
 "$$0.3 \\qquad \\text{ou} \\qquad 0.33 \\qquad \\text{ou} \\qquad 0.333 \\qquad \\text{ou} \\qquad \\ldots $$\n",
 "\n",
 "Não importa quantos dígitos você está disposto a escrever, o resultado nunca será exatamente 1/3, mas será uma aproximação cada vez melhor de 1/3.\n",
 "\n",
 "Da mesma forma, não importa quantos dígitos de base 2 você está disposto a usar, o valor decimal 0.1 não pode ser representado exatamente como uma fração de base 2. Na base 2, 1/10 é a fracção de repetição infinita\n",
 "\n",
 "$$0.0001100110011001100110011001100110011001100110011 \\ldots$$\n",
 "\n",
 "Ao parar em qualquer número finito de bits, e obtém-se uma aproximação. Na maioria das máquinas de hoje, os números de ponto flutuantes são aproximados usando uma fração binária com o numerador usando os primeiros 53 bits começando com o bit mais significativo e com o denominador como uma potência de dois. No caso de 1/10, a fracção binária é\n",
 "\n",
 "$$ 0.1 = \\frac{1}{10} = \\frac{3602879701896397}{2^{55}},$$\n",
 "\n",
 "o que está próximo mas não é exatamente igual ao valor verdadeiro de 1/10.\n",
 "\n",
 "Muitos usuários não estão cientes da aproximação devido à forma como os valores são exibidos. O Python só imprime uma aproximação decimal do valor decimal verdadeiro da aproximação binária armazenada pela máquina. Na maioria das máquinas, se o Python imprimisse o valor decimal verdadeiro da aproximação binária armazenada para 0.1, teria que exibir\n",
 "\n",
 "$$ 0.1 = 0.1000000000000000055511151231257827021181583404541015625 $$\n",
 "\n",
 "Isso é mais dígitos do que a maioria das pessoas achar útil, então Python mantém o número de dígitos gerenciável exibindo um valor arredondado em vez disso.\n",
 "\n",
 "Basta lembrar, mesmo que o resultado impresso pareça o valor exato de 1/10, o valor real armazenado é a fração binária representável mais próxima.\n",
 "\n",
 "Curiosamente, existem muitos números decimais diferentes que compartilham a mesma fração binária aproximada mais próxima. Por exemplo, os números 0.1 e 0.10000000000000001 e 0.1000000000000000055511151231257827021181583404541015625 são todos aproximados por\n",
 "\n",
 "$$\\frac{3602879701896397}{2^{55}}.$$\n",
 "\n",
 "Como todos esses valores decimais compartilham a mesma aproximação, qualquer um deles poderia ser exibido enquanto ainda preservando a invariante eval(repr(x)) == x.\n",
 "\n",
 "Historicamente, o prompt do Python e a função repr() incorporada escolheriam aquele com 17 dígitos significativos, 0.10000000000000001. Começando com Python 3.1, Python (na maioria dos sistemas) agora é capaz de escolher o mais curto destes e simplesmente exibir 0.1.\n",
 "\n",
 "Note que esta é a própria natureza do ponto flutuante binário: este não é um bug no Python, e não é um bug no seu código. Você verá o mesmo tipo de coisa em todas as linguagens de programação que suportam a aritmética de ponto flutuante do seu hardware (embora algumas linguagens de programação não exibam a diferença por padrão ou em todos os modos de saída).\n",
 "\n",
 "Para obter uma saída mais agradável, você pode usar a formatação de string para produzir um número limitado de dígitos significativos:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import math\n",
 "format(math.pi, '.12g') # fornece 12 digitos significantes "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata":
{
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "# Para exepressar diretamente o número\n",
 "'%.12g' % math.pi"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "format(math.pi, '.2f') # fornece 2 digitos após o ponto decimal "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "repr(math.pi)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "len(repr(math.pi))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Logo esse número foi representado internamente com 15 dígitos após o ponto decimal. O que ocorre no caso em que"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "format(math.pi, '.25f')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "É importante perceber que isso é, em um sentido real, uma ilusão: você está simplesmente arredondando a exibição do verdadeiro valor da máquina.\n",
 "\n",
 "Uma ilusão pode gerar outra. Por exemplo, uma vez que 0.1 não é exatamente 1/10, somar três valores de 0.1 pode não resultar exatamente 0.3 assim:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 ".1 + .1 + .1 == .3"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A representação interna é"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "repr(0.1+0.1+0.1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Além disso, uma vez que o 0.1 não pode chegar mais perto do valor exato de 1/10 e 0.3 não pode chegar mais perto do valor exato de 3/10, em seguida, o pré-arredondamento com função round() não pode ajudar:\n"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "round(.1 + .1 + .1, 10) == round(.3, 10)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Aritmética binária de ponto flutuante mantém muitas surpresas como esta. O problema com \"0.1\" é explicado em detalhes precisos abaixo, na seção \"Erro de Representação\". Veja Os [Perigos do Ponto Flutuante](http://www.lahey.com/float.htm) para um relato mais completo de outras surpresas comuns.\n",
 "\n",
 "Como se diz, perto do final, \"não há respostas fáceis\". Ainda assim, não se sinta excessivamente cauteloso com o ponto flutuante! Os erros nas operações de ponto flutuante (os floats) no Python são herdados do ponto flutuante hardware e na maioria das máquinas são da ordem de não mais do que 1 parte em $2^{53}$ por operação. Isso é mais do que adequado para a maioria das tarefas, mas você precisa ter em mente que não é aritmética decimal e que cada operação de flutuação pode sofrer um novo erro de arredondamento.\n",
 "\n",
 "Embora existam casos patológicos, para o uso mais casual de aritmética de ponto flutuante, você verá o resultado esperado no final se você simplesmente arredondar a exibição de seus resultados finais para o número de dígitos decimais que você espera. A função [str()](https://docs.python.org/3/library/stdtypes.html#str) geralmente é suficiente, e para um controle mais fino veja os especificadores de formato do método [str.format()](https://docs.python.org/3/library/stdtypes.html#str.format) em [Format String Syntax](https://docs.python.org/3/library/string.html#formatstrings).\n",
 "\n",
 "Para casos de uso que exigem representação decimal exata, tente usar o módulo decimal que implementa a aritmética decimal adequada para aplicativos de contabilidade e aplicações de alta precisão.\n",
 "\n",
 "Considere novamente,"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "0.1+0.1+0.1-0.3"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Como foi visualizado brevemente quando exploramos comparações, a matemática de ponto flutuante é menos do que exata devido ao espaço limitado usado para armazenar valores. Por exemplo, o resultado acima deveria ser zero, mas não é. O resultado é próximo de zero, porque não há bits suficientes para ser preciso.\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Se você for um grande usuário de operações de ponto flutuante, você deve dar uma olhada no pacote Numérico Python e em muitos outros pacotes para operações matemáticas e estatísticas fornecidas pelo projeto SciPy. Consulte <https://scipy.org>.\n",
 "\n",
 "O Python fornece ferramentas que podem ajudar nessas raras ocasiões em que você realmente quer saber o valor exato de um número de ponto flutuante. O método [float.as_integer_ratio()](https://docs.python.org/3/library/stdtypes.html#float.as_integer_ratio) expressa o valor de um um número de ponto flutuante (um float) como uma fração:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x = 3.14159\n",
 "x.as_integer_ratio()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Como a relação é exata, ela pode ser usada para recriar sem perdas o valor original:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x == 3537115888337719 / 1125899906842624"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O método [float.hex()](https://docs.python.org/3/library/stdtypes.html#float.hex) expressa um número de ponto flutuante em hexadecimal (base 16), dando novamente o valor exato armazenado pelo seu computador:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x == float.fromhex('0x1.921f9f01b866ep+1')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma vez que a representação é exata, ela é útil para portar valores confiáveis em diferentes versões do Python (independente de plataforma) e trocar dados com outras linguagens de programação que suportam o mesmo formato (como o Java, o C99, o Fortan 2008, etc).\n",
 "\n",
 "Outra ferramenta útil é a função [math.fsum()](https://docs.python.org/3/library/math.html#math.fsum) que ajuda a mitigar a perda de precisão durante o somatório. Ele rastreia \"dígitos perdidos\" como valores são adicionados em um total rodando. Isso pode fazer uma diferença na precisão geral para que os erros não se acumulam ao ponto onde eles afetam o total final:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "sum([0.1] * 10) == 1.0\n",
 "math.fsum([0.1] * 10) == 1.0"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Erro de Representação <a name=\"CP3-Erros-de-Representação\"></a>\n",
 "\n",
 "Aqui será explicado o exemplo do número \"0.1\" em detalhes e será mostrado como se pode realizar uma análise exata de outros casos como este.\n",
 "\n",
 "O erro de representação refere-se ao fato de que algumas (na maioria das vezes, as frações decimais) não podem
ser representadas exatamente como frações binárias (base 2). Esta é a principal razão pela qual o Python (ou Perl, C, C++, Java, Fortran e muitas outras linguagens) muitas vezes não exibirá o número decimal exato que você espera.\n",
 "\n",
 "Por que é que? 1/10 não é exatamente representável como uma fração binária. Quase todas as máquinas hoje (a patir de novembro de 2000) usam a aritmética de ponto flutuante IEEE-754, e quase todas as plataformas mapeiam os número de ponto flutuante em Python para IEEE-754 \"dupla precisão\". A dupla precisão do 754 contêm 53 bits de precisão, por isso na entrada do computador se esforça para converter 0.1 para a fração mais próxima que pode da forma $J/2^N$ onde $J$ é um número inteiro contendo exatamente 53 bits. Reescrevendo\n",
 "\n",
 "$$ 1 / 10 ~= J / (2^N) $$\n",
 "\n",
 "como\n",
 "\n",
 "$$ J ~= 2^N / 10 $$\n",
 "\n",
 "e lembrando que J tem exatamente 53 bits (isto é $ \\ge 2^{52}$ mas $<2^{53}$), o melhor valor para $N$ é 56:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "2**52 <= 2**56 // 10 < 2**53"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ou seja, 56 é o único valor para N que deixa J com exatamente 53 bits. O melhor valor possível para J é então aquele com o quociente arredondado:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "q, r = divmod(2**56, 10)\n",
 "r"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma vez que o restante é mais da metade de 10, a melhor aproximação é obtida arredondando para cima:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "q+1"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Portanto, a melhor aproximação possível para 1/10 em 754 dupla precisão é:\n",
 "\n",
 "$$7205759403792794 / 2^{56} = \\frac{7205759403792794}{2^{56}} $$\n",
 "\n",
 "Dividindo o numerador e o denominador por dois reduz-se a fração para:\n",
 "\n",
 "$$ 3602879701896397 / 2^{55} = \\frac{3602879701896397}{2^{55}} $$\n",
 "\n",
 "Note que, uma vez que arredondado para cima, este é realmente um pouco maior do que 1/10; Se não tivéssemos arredondado para cima, o quociente teria sido um pouco menor do que 1/10. Mas em nenhum caso pode ser exatamente 1/10!\n",
 "\n",
 "Então o computador nunca \"vê\" 1/10: o que ele vê é a fração exata dada acima, a melhor aproximação em precisão dupla que a 754 pode obter é:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "0.1 * 2 ** 55"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Se multiplicarmos essa fração por $10^{55}$, podemos ver o valor acima de 55 dígitos decimais:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "3602879701896397 * 10 ** 55 // 2 ** 55"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O que significa que o número exato armazenado no computador é igual ao valor decimal 0.1000000000000000055511151231257827021181583404541015625. Em vez de exibir o valor decimal completo, muitas linguagens de programação (incluindo versões mais antigas do Python), arredondam o resultado para 17 dígitos significativos:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "format(0.1, '.17f')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As [frações](https://docs.python.org/3/library/fractions.html#module-fractions) e os [módulos decimais](https://docs.python.org/3/library/decimal.html#module-decimal) facilitam esses cálculos:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "from decimal import Decimal\n",
 "from fractions import Fraction"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Fraction.from_float(0.1)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "(0.1).as_integer_ratio()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Decimal.from_float(0.1)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "format(Decimal.from_float(0.1), '.17')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Retorna ao [Sumário](#CP3-sumario)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Módulo Decimal <a name=\"CP3-Modulo-Decimal\"></a>\n",
 "\n",
 "O [módulo decimal](https://pymotw.com/2/decimal/) implementa a aritmética de ponto fixo e flutuante usando o modelo familiar para a maioria das pessoas, ao invés da versão de ponto flutuante IEEE implementada pela maioria do hardware do computador. Uma instância Decimal pode representar qualquer número exatamente, arredondar para cima ou para baixo e aplicar um limite ao número de dígitos significativos.\n",
 "\n",
 "### Decimal\n",
 "\n",
 "Os valores decimais são representados como instâncias da classe Decimal. O construtor toma como argumento um número inteiro, ou uma string. Os números de ponto flutuante devem ser convertidos em uma sequência de caracteres antes de serem usados para criar um decimal, permitindo que o chamador explicitamente lidar com o número de dígitos para valores que não podem ser expressos exatamente usando um hardware com representações de ponto flutuante."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import decimal\n",
 "\n",
 "fmt = '{0:<20} {1:<20}'\n",
 "print (fmt.format('Entrada', 'Saída'))\n",
 "print (fmt.format('-' * 20, '-' * 20))\n",
 "\n",
 "# Integer --> Números inteiros\n",
 "print (fmt.format(5, decimal.Decimal(5)))\n",
 "\n",
 "# String --> Palvras/textos\n",
 "print (fmt.format('3.14', decimal.Decimal('3.14')))\n",
 "\n",
 "# Float --> Números de ponto flutuantes\n",
 "print (fmt.format(repr(0.1), decimal.Decimal(str(0.1))))\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Observe que o valor de ponto flutuante de 0.1 não é representado como um valor exato, portanto, a representação como um números de ponto flutuante (um float) é diferente do valor Decimal.\n",
 "\n",
 "Menos convenientemente, Decimais também podem ser criados a partir de tuplas contendo uma sinalização (0 para positivo, 1 para negativo), uma tupla de dígitos e um expoente inteiro."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import decimal\n",
 "\n",
 "# Tupla\n",
 "t = (1, (1, 1), -2)\n",
 "print ('Entrada:', t)\n",
 "print ('Decimal:', decimal.Decimal(t))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Aritmética\n",
 "\n",
"Decimal sobrecarrega os operadores aritméticos simples assim que você tem um valor que você pode manipulá-lo em muito da mesma maneira como os tipos numéricos embutidos."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import decimal\n",
 "\n",
 "a = decimal.Decimal('5.1')\n",
 "b = decimal.Decimal('3.14')\n",
 "c = 4\n",
 "d = 3.14\n",
 "\n",
 "print ('a =', a)\n",
 "print ('b =', b)\n",
 "print ('c =', c)\n",
 "print ('d =', d)\n",
 "print ()\n",
 "\n",
 "print ('a + b =', a + b)\n",
 "print ('a - b =', a - b)\n",
 "print ('a * b =', a * b)\n",
 "print ('a / b =', a / b)\n",
 "print ()\n",
 "\n",
 "print ('a + c =', a + c)\n",
 "print ('a - c =', a - c)\n",
 "print ('a * c =', a * c)\n",
 "print ('a / c =', a / c)\n",
 "print ()\n",
 "\n",
 "print ('a + d =', float(a) + d)\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "No computador todos os números são armazenados na forma binária. No Python, é possivel obter a forma textual de um dado número inteiro usando a função `bin(Numero)` como "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "b=bin(10)\n",
 "b"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "e o inverso"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "i=int(b,2)\n",
 "i"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Podemos criar objetos decimais chamando a função construtor de decimal do módulo decimal e passando strings que possuem o número desejado de dígitos decimais para o objeto resultante (usando a função str para converter valores de ponto flutuante em strings, se necessário), e o resultado é"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "from decimal import Decimal\n",
 "Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Quando decimais de precisão diferente são misturados em expressões, o Python converte automaticamente o maior número de dígitos decimais:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "from decimal import Decimal\n",
 "Decimal('0.10') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Ajustando globalmente a precisão decimal\n",
 "\n",
 "Outras ferramentas do módulo decimal podem ser usadas para definir a precisão de todos os números decimais, organizar o tratamento de erros e muito mais. Por exemplo, um objeto de contexto neste módulo permite especificar precisão (número de decimais) e modos de arredondamento (baixo, teto, etc.). A precisão é aplicada globalmente para todos os decimais criados no segmento de chamada:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import decimal\n",
 "decimal.Decimal(1) / decimal.Decimal(7)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x=decimal.Decimal(1) / decimal.Decimal(7)\n",
 "print('x =', x, 'digitos = ',len(str(x))-2) # Com o (-2) retiro o zero e o ponto"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Portanto, como padrão temos 28 dígitos após o ponto decimal. Vamos ajustar a precisão"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "decimal.getcontext().prec = 6 \n",
 "x=decimal.Decimal(1) / decimal.Decimal(7)\n",
 "print('x =', x, 'digitos = ',len(str(x))-2)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "decimal.getcontext().prec = 4\n",
 "decimal.Decimal(0.1) + decimal.Decimal(0.1) + decimal.Decimal(0.1) - decimal.Decimal(0.3)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "with decimal.localcontext() as ctx:\n",
 " ctx.prec = 2\n",
 " x = decimal.Decimal('1.00') / decimal.Decimal('3.00')\n",
 "x"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Outra forma de aritmética exata é suportada pelo módulo de frações que implementam a aritmética baseada em números racionais (assim os números como 1/3 podem ser representados exatamente)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Tipo fração: A função Fraction <a name=\"CP3-Tipo-Fracao\"></a>\n",
 "\n",
 "A **Fraction** é um novo tipo numérico, que implementa um objeto de número racional. Ele essencialmente mantém um numerador e um denominador explicitamente, de modo a evitar algumas das imprecisões e limitações da matemática de ponto flutuante. Como decimais, as frações não mapeiam tão perto do hardware do computador quanto os números de ponto flutuante. Isso significa que seu desempenho pode não ser tão bom, mas também permite que eles forneçam utilidade extra em uma ferramenta padrão quando necessário ou útil.\n",
 "\n",
 "A fração é um primo funcional para o tipo Decimal de precisão fixa descrito na seção anterior, pois ambos podem ser usados para resolver as imprecisões numéricas do tipo de ponto flutuante. Também é usado de maneiras semelhantes como Decimal, a Fração reside em um módulo; importe seu construtor e passe num numerador e um denominador para criar uma fração (entre outros esquemas). A seguinte interação mostra como:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "from fractions import Fraction\n",
 "x = Fraction(1, 3) \n",
 "y = Fraction(4, 6)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "print(y)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma vez criado, as frações podem ser usadas em expressões matemáticas como de costume:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "# Operações básicas\n",
 "print(\"x + y = \", x+y)\n",
 "print(\"x - y = \", x-y)\n",
 "print(\"x * y = \", x*y)\n",
 "print(\"x / y = \", x/y)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Objetos de fração também podem ser criados a partir de números de ponto flutuante, bem como decimais:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true,
 "scrolled": true
},
 "outputs": [],
 "source": [
 "Fraction('.25')"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Fraction('1.25')"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Fraction('.25') + Fraction('1.25')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Conversões de frações e tipos mistos\n",
 "\n",
 "Para suportar conversões de frações, os objetos de ponto flutuante agora têm um método que produz a razão entre o seu numerador e denominador, as frações possuem um método `from_float` e `float` aceita uma `Fraction` como argumento. Trace através da seguinte interação para ver como isso funciona (o * no segundo teste é uma sintaxe especial que expande uma tupla em argumentos individuais):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "(4.5).as_integer_ratio() # método do objeto float "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "s=9.5\n",
 "x=Fraction(*s.as_integer_ratio()) # converte float em Fraction\n",
 "print('x = ', x)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "y = Fraction(1,2)\n",
 "x+y"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "float(x)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "float(x+y)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Fraction.from_float(1.75) "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Fraction(*(1.75).as_integer_ratio())"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x+3 # Fraction + int -> Fraction"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x+2.0 # Fraction + float -> float"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x+(1.0/3) # Fraction + float -> float"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x + Fraction(4, 3) # Fraction + Fraction -> Fraction"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "4.0 / 3"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "(4.0 / 3).as_integer_ratio() # Perda de precisão do float"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = x + Fraction(*(4.0 / 3).as_integer_ratio())\n",
 "print('a = ',a)\n",
 "a"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "48788995963180373/4503599627370496.0"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a.limit_denominator(10) # Simplifica para a fração mais próxima"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Retorna ao [Sumário](#CP3-sumario)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Números complexos <a name=\"CP3-numeros-complexos\"></a> \n",
 "\n",
 "Python (como Fortran e Matlab) tem incorporado números complexos, entretanto ele usa o símbolo 'j' (assim como nas engenharias) para identificar a parte imaginária do número. Aqui estão alguns exemplos de como usá-los:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x = 1 + 3j\n",
 "x"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "abs(x) "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x.real"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x.imag"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x * x.conjugate()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "float((x * x.conjugate()).real)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "3 * x"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note que se você quiser executar operações mais complicadas (como a raiz quadrada, etc) você tem que usar o módulo `cmath` (Matemática complexa):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import cmath\n",
 "cmath.sqrt(x)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As funções matemáticas que estão disponibilizadas pela biblioteca `cmath`, podem ser listadas com o seguinte comando:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "dir(cmath)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "r=cmath.polar(x)\n",
 "r"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Funções aplicáveis a todos os tipos de números <a name=\"CP3-func-numeros\"></a> \n",
 "\n",
 "A função `abs()` retorna o valor absoluto de um número qualquer (também chamado de módulo):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = -45.463\n",
 "x = 3 -4j \n",
 "print(\"O módulo de a = \", abs(a))\n",
 "print(\"O módulo de x = \", abs(x))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Observe que `abs()` também funciona para números complexos (veja acima)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Sequências <a name=\"CP3-sequencias\"></a>\n",
"\n",
 "As strings, listas e tuplas são *sequências*, e como tal, elas podem ser *indexados* e *fatiadas*. Com a indexação conseguimos nos referir a qualquer elemento da sequência. Por Exemplo considere a string \"Física Computacional\", a sua indexação seria dada pela atribuição de um índice para a posição de cada letra que compõe a palavra\n",
 "\n",
 "```bash\n",
 " +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+\n",
 " | F | í | s | i | c | a | | C | o | m | p | u | t | a | c | i | o | n | a | l |\n",
 " +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+\n",
 " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <-- indexador da posição\n",
 "```\n",
 "\n",
 "Com o fatiamento significa que podemos obter e no referir a uma parte ou pedaço da sequência, ou seja, note que a variável a receba a palavra acima, \n",
 "```python\n",
 "a = \"Física Computacional\"\n",
 "```\n",
 "logo a a seguinte sequência\n",
 "```python\n",
 "b = a[4:6]+a[10]+a[5]+a[12:16]+a[12:14]\n",
 "print(b)\n",
 "\n",
 "capacita\n",
 "```\n",
 "\n",
 "Tuplas e strings são \"imutáveis\" (o que basicamente significa que não podemos alterar elementos individuais dentro da tupla, e não podemos alterar caracteres individuais dentro de uma string) enquanto as listas são \"mutáveis\" (*isto é* podemos alterar elementos em uma lista.)\n",
 "\n",
 "As sequências compartilham as seguintes operações\n",
 "\n",
 "<table>\n",
 "<tr><td>`a[i]`</td><td>retorna *i*-ésio elemento de `a`</td></tr>\n",
 "<tr><td>`a[i:j]`</td><td>retorna os elementos de *i* até *j* − 1</td></tr>\n",
 "<tr><td>`len(a)`</td><td>retorna o número de elementos na sequência/td></tr>\n",
 "<tr><td>`min(a)`</td><td>retorna o menor valor da sequência</td></tr>\n",
 "<tr><td>`max(a)`</td><td>retorna o maior valor da sequência</td></tr>\n",
 "<tr><td>`x in a`</td><td>retorna `True` se `x` é um elemento de `a`</td></tr>\n",
 "<tr><td>`a + b`</td><td>concatena `a` e `b`</td></tr>\n",
 "<tr><td>`n * a`</td><td>cria `n` cópias da sequência `a`</td></tr>\n",
 "</table>"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a=\"Física Computacional\"\n",
 "b = a[4:6]+a[10]+a[5]+a[12:16]+a[12:14]\n",
 "print(b)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Sequência tipo 1: String <a name=\"CP3-sequencias-t1\"></a>\n",
 "\n",
 "##### Outras informações\n",
 "\n",
 "- Introduction to strings, [Python tutorial 3.1.2](http://docs.python.org/tutorial/introduction.html#strings)\n",
 "\n",
 "Uma sequência de caracteres é uma sequência (imutável) de caracteres. Uma string pode ser definida usando aspas simples:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = 'Olá Mundo'"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "aspas duplas:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Olá Mundo\""
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "ou aspas triplas de qualquer espécie"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"\"\"Olá Mundo\"\"\"\n",
 "a = '''Olá Mundo'''"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O tipo de uma string é str e a string vazia é dada por ``\"\"``:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Olá Mundo\"\n",
 "type(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "b = \"\"\n",
 "type(b)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type(\"Olá Mundo\")"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type(\"\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O número de caracteres de uma string (que é o seu *comprimento*) pode ser obtido usando a função `len()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Física computacional. Que maravilha!\"\n",
 "len(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = 'Física'\n",
 "len(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "len('Computacional')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Você pode combinar (\"concatenar\") duas strings usando o operador `+`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "'Física' + ' Computacional'"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O operador * também atua nas strings"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "\"Física \"*2"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "'='*80"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O tipo string no python possui inúmeros métodos, incluindo por exemplo o `upper()` o qual returna a string passa em maíuscula. Os diversos métodos de uma string são: "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Física computacional. Que maravilha!\"\n",
 "a.upper()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a.capitalize()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a.swapcase()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a.lower()"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "len(a)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma lista de métodos de string disponíveis pode ser encontrada na [documentação de referência do Python](https://docs.python.org/3.6/library/string.html). Se um prompt de Python estiver disponível, use a função `dir` e `help` para recuperar esta informação, *isto é* `dir()` fornece a lista de métodos, `help` pode ser usado para aprender sobre cada método.\n",
 "\n",
 "Um método particularmente útil é `split()` que converte uma string em uma lista de strings:"
 ]
 },
{
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Física computacional. Que maravilha!\"\n",
 "a.split()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O método `split()` irá separar a string onde ele encontrar *um espaço em branco*. Espaço em branco significa qualquer caractere impresso como espaço em branco, como um espaço ou vários espaços ou uma tabulação (tab).\n",
 "\n",
 "Ao passar um caractere de separação para o método `split()`, uma string pode se dividir em partes diferentes. Suponha, por exemplo, que queremos obter uma lista de frases completas:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Física Computacional. Linguagens de Programação. Shell Script. Cálculo Numérico\"\n",
 "a.split(\".\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O método de string oposto a `split` é o `join` que pode ser usado da seguinte forma:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = \"Física Computacional. Linguagens de Programação. Shell Script. Cálculo Numérico\"\n",
 "s = a.split('.')\n",
 "s"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[7:21]"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "\".\".join(s)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "\" e\".join(s)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Sequência tipo 2: Lista <a name=\"CP3-sequencias-t2\"></a>\n",
 "\n",
 "##### Maiores informações \n",
 "\n",
 "- Introduction to Lists, [Python tutorial, section 3.1.4](http://docs.python.org/tutorial/introduction.html#lists)\n",
 "\n",
 "Uma lista é uma sequência de objetos. Os objetos podem ser de qualquer tipo, por exemplo inteiros:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = [34, 12, 54, 25, 98]\n",
 "b = [17, 12 ,36, 47, 86]\n",
 "print(\"a+b = \", a+b) # soma"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "ou strings, como a seguinte lista de animais em inglês"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = ['dog', 'cat', 'mouse', 'snake', 'bird']"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma lista vazia é criada com `[]`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = []"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O tipo é list:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type([])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Como com strings, o número de elementos em uma lista pode ser obtido usando a função `len()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = ['dog', 'cat', 'mouse', 'snake', 'bird']\n",
 "len(a)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[2]"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Também é possível *misturar* tipos diferentes na mesma lista:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "ctes = [3.0e8, 'Speed of light', -1.602e-19, 'electron charge', 1/2, 'spin of electron', 9.8, 'acceleration of gravity']"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "No Python, uma lista é um objeto. Portanto, é possível que uma lista contenha outras listas (porque uma lista mantém uma sequência de objetos):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = [1, 4, 56, [5, 3, 1], 300, 400]"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[3][1]"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ou você pode adicionar um objeto ao final de uma lista usando o método `append()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = [34, 56, 23]\n",
 "a.append(42)\n",
 "a"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[1:4]"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Você pode excluir um objeto de uma lista chamando o método `remove()` e passando o objeto a ser excluído. Por exemplo:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = [34, 56, 23, 42]\n",
 "a.remove(56)\n",
 "a"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### O comando range() <a name=\"CP3-cmd-range\"></a>\n",
 "\n",
 "Um tipo especial de lista é frequentemente requerido (muitas vezes junto com `loops for`) e para isso existe um comando para gerar essa lista: o comando `range(n)` gera números inteiros começando de 0 e indo até *mas não incluindo* N. Aqui estão alguns exemplos:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "list(range(3))"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "list(range(10))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Esse comando é freqüentemente usado com loops for. Por exemplo, para imprimir os números 0 <sup>2</sup>,1<sup>2</sup>,2 <sup>2</sup>,3<sup>2</sup>,...,10<sup>2</sup>, o seguinte programa pode ser usado:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "for i in range(11):\n",
 " print(i ** 2)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "O comando `range()` assume um parâmetro opcional para o início da sequência de números inteiros (start) e outro parâmetro opcional para o tamanho da etapa. Isto é frequentemente escrito como `range([inicio],fim,[passo])` onde os argumentos entre colchetes (*isto é* inicio e passo) são opcionais. Aqui apresentamos
alguns exemplos:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "list(range(3, 10)) # inicio=3, fim=9"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "list(range(3, 10, 2)) # inicio=3, fim=9, passo=2"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "list(range(10, 0, -1)) # inicio=10, fim=1, passo=-1"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Por que estamos chamando `list(range ())`?\n",
 "\n",
 "No Python 3, `range()` gera os números sob demanda. Quando você usa `range()` em um loop for, isso é mais eficiente, porque ele não ocupa memória com uma lista de números. Passá-lo para `list()` obriga a gerar todos os seus números, para que possamos ver o que ele faz.\n",
 "\n",
 "Para obter o mesmo comportamento eficiente em Python 2, use `xrange()` em vez de `range()`."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Sequência tipo 3: Tuplas <a name=\"CP3-sequencias-t3\"></a>\n",
 "\n",
 "Uma *tupla* é uma sequência (imutável) de objetos. As tuplas são muito semelhantes em comportamento às listas, com a excepção de que elas não podem ser modificadas (isto é, são imutáveis).\n",
 "\n",
 "Por exemplo, os objetos em uma sequência podem ser de qualquer tipo:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = (1643, 1727, 'Newton')\n",
 "a"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[0]"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Os parênteses não são necessários para definir uma tupla: apenas uma sequência de objetos separados por vírgulas é suficiente para definir uma tupla:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = 1879, 1955, 'Einstein'\n",
 "a"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "b=(2,'Nome',4,'Contribuição')\n",
 "b"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Embora seja uma boa prática incluir os parênteses o qual ajuda a mostrar a definição da tupla.\n",
 "\n",
 "Tuplas também podem ser usados para fazer duas tarefas ao mesmo tempo:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x, y = 10, 20\n",
 "x"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "y"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Isso pode ser usado para *trocar* objetos dentro de uma linha. Por exemplo"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x = 1\n",
 "y = 2\n",
 "x, y = y, x\n",
 "x"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "y"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Exercício: lógica \n",
 "Notem que a grande caracterísitca da tupla foi trocar o de trocar o valor das variáveis sem usar uma variável auxiliar. Para dois valores arbitrários quaisquer `x = 7` e ` y = 15`, escreva um trecho de código sem usar tuplas e sem usar uma variável auxiliar para trocar o valor das variáveis:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "x = 7; y =15\n",
 "pass # aqui você deve completar o código\n",
 "print('O novo valor de x = %d e y = %d ' % (x,y))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Uma tupla vazia é dada por `()`:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "t = ()\n",
 "len(t)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "type(t)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A notação para uma tupla que contém um valor pode parecer um pouco estranho no início:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "t = (42,)\n",
 "type(t)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "len(t)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A vírgula extra é necessária para distinguir `(42,)` de `(42)`, onde neste último caso o parêntese seria lido como definindo a precedência do operador: `(42)` simplifica para `42` que é apenas um número:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "t = (42)\n",
 "type(t)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Este exemplo mostra a imutabilidade de uma tupla:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a = (1643, 1727, 'Newton')\n",
 "a[0]"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ao tentar atribuir um novo valor a um dos elementos da tupla, o python irá emitir uma mensagem de erro, conforme exemplo a seguir:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "a[0] = 1642"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A imutabilidade é a principal diferença entre uma tupla e uma lista (sendo esta última mutável). Devemos usar tuplas quando não queremos que o conteúdo mude. Observe que as funções Python que retornam mais de um valor, retornam-nas em tuplas (o que faz sentido porque você não deseja que esses valores sejam alterados). "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Indexando Sequências <a name=\"CP3-index-seq\"></a>\n",
 "\n",
 "##### Mais informação\n",
 "\n",
 "- Introdução a strings e indexando em [Python tutorial, section 3.1.2](http://docs.python.org/tutorial/introduction.html#strings), a seção relevante inicia após a introdução das strings.\n",
 "\n",
 "Objetos individuais em listas podem ser acessados usando o índice do objeto e colchetes (`[` e `] `):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "Cientistas = ['Galileo', 'Newton', 'Lagrange', 'Maxwell','Einstein']\n",
 "Cientistas[0]"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed":

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Continue navegando