image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image
Lorena Assis
Lorena Assis04/10/2023 17:56
Compartilhe

[Continuação] Introdução ao Python: lógica da programação em Python

  • #Python

Essa é uma continuação do meu primeiro artigo, na qual me aprofundo sobre Python, explicando conceitos básicos da linguagem e sobre lógica da programação. São abordados nesse artigo alguns assuntos como comentários em código, valores e variáveis, tipos de dados básicos em Python, objetos e operadores.

Para poupar seus esforços, o artigo foi escrito no formato de resumo – fique à vontade para salvá-lo e utilizá-lo sempre como referência em seus estudos.

Boa leitura!

Comentários no código

É possível incluir textos que serão ignorados durante a compilação do código. Eles são chamados de comentários, e são muito importantes para realizar a documentação de um arquivo de código, explicando para que serve determinada função ou para dividir o código em seções.

Deve-se tomar cuidado para não exagerar na quantidade de comentários.

Em Python, utilizamos # <texto> para comentar. Não existem comentários em bloco.

Valores e variáveis

O valor é um dado, é a unidade mais básica e fundamental que temos na programação. É um pedaço de memória que recebe um nome, o qual você pode alocar específicos tipos de dados. Ele pode ser um número, uma string (sequência de caracteres), uma booleana, etc. Os valores podem ser armazenados em variáveis para serem reutilizados no código.

Em Python utilizamos o operador de atribuição de valores (=). Por exemplo: radius = 1.

Convenções para nomeação de variáveis

Em Python, os nomes das variáveis podem conter letra, número, underscore. A seguir, algumas convenções utilizadas pelos desenvolvedores de Python para padronizar a nomeação de variáveis:

  • Utilizar a notação snake_case
  • Não iniciar nem terminar as variáveis com dois underscores, pois o Python utiliza esse formato para os chamados dunder variables, atributos especiais
  • Não inserir números no início do nome
  • Não nomear variáveis com palavras-chaves (palavras reservadas) da própria linguagem, por exemplo def, if, and, etc.
  • Utilizar a notação camelCase para classes
  • Escrever todas as letras em maiúsculo quando a variável for um valor constante
  • Nomear as variáveis de forma mais descritível o possível, ou seja, deve ser fácil entender sobre o que se trata a variável

Tipos de dados básicos

Os computadores armazenam números utilizando o sistema binário, que se utiliza somente de 0s e 1s para representar números integrais ou decimais. O número decimal 0.625 por exemplo, pode ser representado de forma binária como:

1/2¹ + 0/2² + 1/2³

É um número finito. No entanto, assim como algumas frações (por exemplo: 1/3) não possuem representação finita no sistema decimal, alguns números decimais não possuem representação finita no sistema binário. Portanto, o tipo float não é sempre exato, e isso pode trazer problemas quando utilizamos esse tipo de dado para aplicações financeiras.

Um ponto importante a se atentar é evitar a comparação de float uns com os outros.

Observação: isso não é uma limitação apenas do Python. Qualquer linguagem que utilize frações binárias possuem esse problema.

Há um tipo de dado capaz de fazer representações exatas de frações decimais, chamado decimal. No entanto, ele não é tão eficiente, nem do ponto de vista de memória quanto computacional, ou fácil de trabalhar quanto o tipo float.

int

O tipo int é utilizado para representar números integrais, como 0, 1, 100, -100, etc.

Em Python, as integrais possuem representação exata e podem ser de qualquer magnitude (positiva, ou negativa), desde que haja espaço para isso na memória da máquina.

Os números integrais podem ser criados por literais – ou seja, basta digitar literalmente o número no código – ou como resultado de alguma expressão. Eles também podem ser divididos por underscore para facilitar a leitura, por exemplo 10_500_000. Isso não afeta como o código é compilado ou interpretado.

float

O tipo float é utilizado para representar números racionais (pontos flutuantes), como 3.14, -1.3, etc. Assim como nos números do tipo int, pode-se utilizar underscore para facilitar a leitura, por exemplo 1_234.567_876. Os números do tipo float também podem ser definidos a partir de literais.

Objetos

Objetos são entidades criadas pelo Python que contém estados e métodos, sendo:

  • estados: dados
  • métodos: funcionalidades

Ambos estão encapsulados dentro do objeto. Geralmente utilizamos objetos para representar coisas do mundo real, como um carro.

Por exemplo: Carro

Estado (dados)

  • marca → Toyota
  • modelo → Prius LE
  • portas → 4
  • ano → 2020
  • quilometragem → 5_402

Funcionalidades

  • acelerar( )
  • frear( )
  • calibrar( )
  • ligar_seta_esquerda( ) </aside>

Observação: todos os tipos de dados em Python são objetos.

int como objeto

Uma integral é considerada um objeto em Python porque ela tem um estado (que é o valor da integral) e possui funcionalidade. Ela sabe, por exemplo, como adicionar si mesma a outra integral por meio do operador (+) e pelo método __add__. Uma integral também sabe como representar si mesma como uma string (para o output visual).

float como objeto

Assim como as integrais, os números do tipo float também são considerados objetos, pois seus valores também são estados e também possuem funcionalidades. Além do __add__, possuem outros métodos, como por exemplo o .as_integer_ratio( ), que retorna o float como uma fração.

Atributos de um objeto

Denominamos o encapsulamento (estado e métodos) como atributos de um objeto, uma definição genérica. Alguns atributos são para o estado, outros para a funcionalidade. Podemos acessar esses atributos através da notação de ponto.

Exemplificação:

  • car.brand: acessa o atributo brand do objeto car
  • car.model: acessa o atributo model do objeto car

Para atributos que representam a funcionalidade (métodos), devemos chamar o atributo para realizar a ação, assim como chamamos as funções. Para isso, devemos passar parâmetros adicionais para que funcione.

Por exemplo:

car.accelerate(10, 'km')
(10).__add__(100)

Mutabilidade e imutabilidade

Um objeto é considerável mutável se seu estado interno pode ser alterado, ou seja, se pelo menos um dos seus atributos podem ser mudados.

Um objeto é considerável imutável se seu estado interno não pode ser alterado.

Em Python, muitos tipos de dados são imutáveis, tais como int, float, bool, str, tuple, etc. Outros são mutáveis, como list, dict, set, etc.

Operadores

Precedência de operadores

Operadores têm precedência, ou seja, eles são classificados de modo que uma operação é avaliada antes de outra.

No que se refere aos operadores aritméticos, temos a seguinte classificação, da menor para maior precedência:

  • Operadores binários + e -
  • Operadores binários * e /
  • Operadores unários + e -
  • Operador de exponenciação **, exceto quando há um operador unário à direita do **

Por exemplo:

2 * 10 + 5 # (2 * 10) + 5 = 25
2 * 2 ** 3 # 2 * (2 ** 3) = 2 * 8 = 16
-2 ** 4 # -(2 ** 4) = -16
2 ** -3 # 2 ** (-3) = 0.125

Recurso/Documentação: Expressions

Depender da precedência de operadores automática pode resultar em bugs, por isso, é melhor sempre utilizar parênteses para especificar as expressões, mesmo que sejam apenas adição e subtração.

Operadores aritméticos

Terminologia

Um operador, em uma linguagem da programação, é um símbolo que realiza uma operação em um ou mais valores. Eles podem ser do tipo:

  • Aritmético
  • Comparativo (ou de relação)
  • Lógico

Os valores sob os quais os operadores agem são chamados de operandos. Os operadores podem ser classificados de acordo com a quantidade de operandos sob os quais eles operam:

  • Unário: apenas um operando
  • Binário: dois operandos
  • Ternário: três operandos

Operadores aritméticos

Unários

  • Unário menos: -10
  • Unário mais: +10

Binários

  • Adição: 10 + 20
  • Subtração: 20 - 10
  • Multiplicação: 10 * 2
  • Divisão: 10 / 2
  • Exponenciação: 2 ** 4
  • Módulo: 131 % 3

O operador de exponenciação

O operador de exponenciação pode retornar um int ou um float dependendo de seus operandos.

Por exemplo:

  • 2 ** 4 = 16, retorna um int
  • 2 ** (-4) = 0.0625, retorna um float

Assim como uma exponenciação matemática, o Python aceita float para ambos os operandos do operador **. E também aceita bases negativas com exponentes reais, ou seja, números complexos. Inclusive, existe um tipo numérico conhecido como complex em Python.

O operador de divisão

Em Python, existe um símbolo para realizar divisões de integrais que, sendo exatas ou não, retornam uma integral //. No caso de divisões não exatas, ela retorna o valor antes do decimal – o restante é descartado, por exemplo 131 // 3 = 43.

O Python utiliza a função floor( ) para retornar uma integral como resultado de uma operação com o operador //. A função floor( ) retorna o maior número integral <= x. Na prática, funciona bem para números positivos, mas para números negativos não é ideal.

Por exemplo:

  • floor(3.14) = 3
  • floor(-3.14) = -4, ao invés de -3
  • 12 // 5 = 2
  • -12 // 5 = -3, ao invés de -2

O operador mod (%)

Da maneira como o módulo é definido em Python, ele acaba por resultar em comportamentos “estranhos” (não-intuitivos) para números negativos e do tipo float.

Por exemplo:

  • 12 % 5 = 2
  • 12 % -5 = -3
  • -12 % 5 = 3
  • -12 % -5 = -2

Isso ocorre porque a operação mod equivale a % b = a - b (a // b).

Para visualizar isso na prática, vamos tomar como exemplo a seguinte equivalência 131/3 = 43 + 2/3. Ela pode ser escrita também da seguinte forma:

131/3 = floor(131/3) + (131%3)/3

cuja fórmula pode ser descrita como:

a/b = a//b + (a%b)/b
a%b = b * (a/b - a// b)
a%b = a - b * (a//b)

Tipos dos operandos

Operadores aritméticos podem operar em qualquer tipo numérico (int, float, etc).

No entanto, a operação realizada pelo operador é na verdade determinada pelo tipo dos operandos.

Um operador pode operar em operandos de tipos mistos.

Exemplificação:

  • 2 + 2 retorna um int
  • 2 + 2.0 retorna um float
  • 5.5 * 2 retorna um float
  • 4 / 2 retorna um float (esse símbolo é chamado de divisão de float – o símbolo para divisão de int é //)

Como Python implementa os operadores matemáticos

Quando somamos dois números, o Python executa o método dunder __add__ para avaliar a expressão. Por exemplo: a.__add__(b), sendo a = 10 e b = 20, resulta em 30.

Qualquer tipo pode implementar o método __add__ como queira, de tal modo que o Python poderá então utilizar esse método para avaliar a expressão type_1 + type_2.

Operadores comparativos

Também conhecidos como operadores relacionais, eles são utilizados para comparar dois dados, retornando um valor booleano (verdadeiro ou falso).

Alguns operadores são:

  • == comparador de igualdade
  • != comparador de diferença
  • <, <=, >, >= menor, menor ou igual, maior, maior ou igual – estes comparadores assumem que os operandos sejam comparáveis, como 10.5 < 100, ao invés de olá > 100 (o que não faz sentido)

Quando o operador de igualdade é utilizado entre operandos que não são comparáveis, o resultado retornado é False. No entanto, quando o mesmo ocorre com os operadores menor, maior, menor ou igual ou maior ou igual, é retornada uma exceção, neste caso, um TypeError. Caso a exceção não seja resolvida, o programa não roda.

Objetos do mesmo tipo normalmente são comparáveis, e objetos numéricos como int e float também são comparáveis entre si. No entanto, é preciso se atentar aos problemas de precisão de float, como explicado anteriormente, onde, por exemplo, 0.1 + 0.1 + 0.1 == 0.3 retorna False.

Logo, quando utilizando float, não devemos utilizar o comparador de igualdade.

O que é necessário para que dois objetos sejam considerados iguais?

Tudo em Python é um objeto, tal como 1 é um objeto int e 1.0 é um objeto float. Temos que 1 e 1.0 não são o mesmo objeto, mas possuem o mesmo valor.

Para checar se dois objetos são o mesmo, utilizamos a palavra-chave is, enquanto para verificar se dois objetos (compatíveis) possuem o mesmo valor utilizamos o comparador de igualdade ==.

Sempre utilizamos o comparador de igualdade para números, pois em Python há um bug no qual o número 1 é armazenado no mesmo objeto, mesmo que sejam criadas variáveis diferentes.

Por exemplo:

  • Se a = 1 e b = 1, temos que a == b retorna True e a is b também retorna True
  • Se d = 500 e e = 500, temos que d == e retorna True e d is e retorna False

De fato, o operador is está apenas interessado no endereço da memória dos objetos, e por isso é conhecido como comparador de identidade.

O operador de igualdade, assim como o operador de soma aritmética, é implementado pelo tipo, ou seja, pode ser definido de acordo com tipos customizáveis utilizando o método dunder __eq__.

Outros operadores de comparação

Temos os operadores de afiliação in e not in, que funcionam junto com as coleções para determinar se um objeto está incluso em determinada coleção. Para isso, ele realiza uma comparação de igualdade, e não de identidade.

Por exemplo:

s = {1, 2, 3.14, True, 5.1}

# 1 in s retorna True
# 10 in s retorna False
# 10 not in s retorna True

Operadores lógicos

Em álgebra booleana, temos apenas dois valores possíveis: True e False (verdadeiro ou falso). Temos três operadores básicos: e, ou, não (and, or, not).

Pela sintaxe de Python, not é um operador unário, por exemplo not True e not (a < b). Já and e or são operadores binários, por exemplo True or False, True and False e (enabled == True) and (withdraw <= balance).

Tabelas-verdade

O operador not simplesmente inverte os valores.

O operador and só retorna verdadeiro se tanto a e b são verdadeiros, do contrário é falso.

O operador or retorna falso se tanto a e b são falsos, do contrário é verdadeiro.

Se a é falso, a e b será sempre falso; se a é verdadeiro, a ou b será sempre verdadeiro. Saber disso pode otimizar processos ao realizar uma avaliação de curto-circuito no código, ou seja, interromper ele prematuramente para poupar recursos.

Compartilhe
Recomendados para você
Suzano - Python Developer
BairesDev - Machine Learning Practitioner
Santander Bootcamp Cibersegurança #2
Comentários (1)
Igor Santos
Igor Santos - 04/10/2023 18:03

Ótimo conteúdo, Python me fez voltar a estudar programação e nunca estive tão empolgado na area!