{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Frações - Números Racionais\n", "\n", "A classe **Fraction** implementa operações numéricas para **[números racionais](https://pt.wikipedia.org/wiki/N%C3%BAmero_racional)** com base na API definida pelo **Rational** em numbers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Criando Instâncias de Fração\n", "\n", "Uma simples maneira de criarmos uma instância é através da separação dos valores **numerador** e **denominador**\n", "\n", "Vejamos exemplos" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/2 = 1/2\n", "2/4 = 1/2\n", "3/6 = 1/2\n", "5/7 = 5/7\n" ] } ], "source": [ "import fractions\n", "\n", "fracoes = [(1, 2), (2, 4), (3,6), (5,7)]\n", "\n", "# O menor denominador comum é mantido à medida que novos valores são calculados.\n", "for n, d in fracoes:\n", " f = fractions.Fraction(n, d)\n", " print(f'{n}/{d} = {f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra maneira de criar uma Fração é utilizando uma representação de string de `<numerador> / <denominador>`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2/4 = 1/2\n", "3/3 = 1\n", "5/2 = 5/2\n", "4/8 = 1/2\n" ] } ], "source": [ "frac = ['2/4', '3/3', '5/2', '4/8']\n", "\n", "for s in frac:\n", " f = fractions.Fraction(s)\n", " print(f'{s} = {f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As strings também podem usar a notação decimal ou ponto flutuante mais usual de `[<dígitos>].[<Dígitos>]`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.5 = 1/2\n", "1.5 = 3/2\n", "2.0 = 2\n", "5.2 = 26/5\n", "3.5 = 7/2\n" ] } ], "source": [ "numeros = ['0.5', '1.5', '2.0', '5.2', '3.5']\n", "\n", "for s in numeros:\n", " f = fractions.Fraction(s)\n", " print(f'{s} = {f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Existem métodos de classe para criar instâncias de Fração diretamente de outras representações de valores racionais, como **float** ou **decimal**" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.1 = 2476979795053773/2251799813685248\n", "2.2 = 2476979795053773/1125899906842624\n", "0.5 = 1/2\n", "1.5 = 3/2\n" ] } ], "source": [ "numbers = [1.1, 2.2, 0.5, 1.5]\n", "\n", "for v in numbers:\n", " print(f'{v} = {fractions.Fraction.from_float(v)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observe que, para valores de ponto flutuante que não podem ser expressos exatamente, a representação racional pode produzir resultados inesperados.\n", "\n", "O uso de **representações decimais** dos valores fornece os resultados esperados:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "import decimal" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.1 = 1/10\n", "0.5 = 1/2\n", "1.5 = 3/2\n", "2.0 = 2\n", "2.3 = 23/10\n", "5.8 = 29/5\n" ] } ], "source": [ "decimais = [decimal.Decimal('0.1'), \n", " decimal.Decimal('0.5'), \n", " decimal.Decimal('1.5'), \n", " decimal.Decimal('2.0'),\n", " decimal.Decimal('2.3'),\n", " decimal.Decimal('5.8'),]\n", "\n", "for v in decimais:\n", " print(f'{v} = {fractions.Fraction.from_decimal(v)}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Aritmética\n", "\n", "Depois que as frações são instanciadas, elas podem ser usadas em **expressões matemáticas** como esperado." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/2 + 5/4 = 7/4\n", "1/2 + 5/4 = -3/4\n", "1/2 + 5/4 = 5/8\n", "1/2 + 5/4 = 2/5\n" ] } ], "source": [ "f1 = fractions.Fraction(1, 2)\n", "f2 = fractions.Fraction(5, 4)\n", "\n", "print(f'{f1} + {f2} = {f1 + f2}')\n", "print(f'{f1} + {f2} = {f1 - f2}')\n", "print(f'{f1} + {f2} = {f1 * f2}')\n", "print(f'{f1} + {f2} = {f1 / f2}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Aproximando Valores\n", "\n", "Um recurso útil do **Fraction** é a capacidade de converter um número de ponto flutuante em um valor racional aproximado, limitando o tamanho do denominador." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PI: 3.141592653589793\n", "Sem Limite: 3141592653589793/1000000000000000\n" ] } ], "source": [ "import math\n", "\n", "f_pi = fractions.Fraction(str(math.pi))\n", "\n", "print(f'PI: {math.pi}')\n", "print(f'Sem Limite: {f_pi}' )" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 = 3\n", "6 = 19/6\n", "11 = 22/7\n", "16 = 22/7\n", "21 = 22/7\n", "26 = 22/7\n", "31 = 22/7\n", "36 = 22/7\n", "41 = 22/7\n", "46 = 22/7\n", "51 = 22/7\n", "56 = 22/7\n", "61 = 179/57\n", "66 = 201/64\n", "71 = 223/71\n", "76 = 223/71\n", "81 = 245/78\n", "86 = 267/85\n", "91 = 267/85\n", "96 = 289/92\n" ] } ], "source": [ "for i in range(1, 100, 5):\n", " limited = f_pi.limit_denominator(i)\n", " print(f'{i} = {limited}')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 2 }