A arte do erro sem mensagem: por que meu código Python interpretou minha variável como tupla ao invés de int
Tags: programming, braziliandevs, python
Published: 2023-12-16 22:06:42

Primeiramente, preciso agradecer imensamente a ajuda da @jesstemporal. Ela quem me apoiou no entendimento do meu código e me trouxe a reflexão de porque determinado comportamento acontecia em sua execução: eu queria um int para representar um dia e, na verdade, meu código interpretou como tupla.

![Gif de uma criança olhando confusa com as mãos viradas pra cima](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpbhnp2wqyr2uwryn9r9.gif)

É, eu sei, não faz o menor sentido e eu não estava entendendo como aquilo acontecia. Percebe que isso é um erro, mas não aqueles que dão mensagem e tudo mais? Então eu gastei um certo tempo tentando entender. E isso pode acontecer diversas vezes conosco (principalmente se já estivermos cansadas durante os estudos).

Bom, eu estava estudando Python com Programação Orientada a Objetos. E um dos exercícios, o objetivo era criar uma classe para representar uma data (com dia, mês e ano) e uma forma de retorná-la no formato: dd/mm/yyyy. E a ideia era construir isso na mão.

Certo. Então eu fiz duas coisas:
- o arquivo `main.py`;
- o arquivo `data.py` para desenvolver a classe Data.

O código da classe Data ficou assim:
```python
class Data:
    def __init__(self, day, month, year):
        self.day = day,
        self.month = month,
        self.year = year

    def format_date(self):
        print(f"{self.day}/{self.month}/{self.year}")

```

Existe a possibilidade de você já ter identificado o erro. Mas vamos por partes para que todes possam acompanhar o que aconteceu. Entenda que, para mim, essa classe estava desenvolvida da forma correta. Afinal eu fiz o construtor, defini os parâmetros e atributos e também desenvolvi a função que formataria a data que fosse enviada.

Certo? Ok, não tão certo assim. Mas veja também como eu desenvolvi a main:
```python
from datas import Data


def main():
    data = Data(
        day=21,
        month=11,
        year=2007
    )

    data.format_date()


if __name__ == '__main__':
    main()

```

Até aqui, tudo bem também. Eu criei o objeto data a partir da classe Data, já passando alguns valores para que eu pudesse chamar a função para imprimir na tela e testar.

O resultado que eu esperava, neste caso, era:
```
21/11/2007
```

E o resultado que eu recebi foi:
```
(21,)/(11,)/2007
```

Algumas horas depois, pesquisando e mexendo no código, tentando entender o que estava acontecendo, eu acabei desistindo e indo dormir. No dia seguinte, a @jesstemporal me mostrou o que estava causando esse problema: uma vírgula. SIM, APENAS UMA F*CKING VÍRGULA. Duas, na verdade. Segue o raciocínio.

## Conhecendo a tupla
[Tuplas](https://docs.python.org/3/library/stdtypes.html?highlight=tuple#tuple), segundo a documentação do Python, porque aqui só saímos de casa com a bibliografia pronta e na mão, são sequências imutáveis, normalmente utilizadas para coleções de dados diversos.

Para saber que uma sequência de dados é uma tupla, precisamos verificar como ela foi escrita. A vírgula define que aquela sequência é uma tupla. Ou seja:

```python
data = (dia, mes, ano) # esta é uma tupla
data2 = dia, mes, ano # esta também é uma tupla
```

Perceba que o parêntese não é necessário. Mas como dissemos, o que define a tupla é o uso da vírgula.

## Tupla não é lista
É importante também ressaltar que a tupla não é uma lista, apesar de lembrar uma. Assim como a vírgula é o que define a tupla, a lista é definida pelo uso de []. Ou seja:

```python
meses = ["Janeiro", "Fevereiro", "Março"] # esta é uma lista
```

## Entendendo onde estava o erro
Se você voltar no meu código, vai perceber que eu adicionei vírgula após os atributos day e month.

```python
class Data:
    def __init__(self, day, month, year):
        self.day = day, # aqui temos uma vírgula intrusa
        self.month = month, # e aqui também
        self.year = year
```

Talvez por vício de outras linguagens, eu acabei adicionando a vírgula no final, achando que isso encerraria aquela linha/comando. Mas no Python, isso não é necessário. Apenas o fato de estar em outra linha, a linguagem já entende que é outro comando.

O jeito certo, seria o código estar da seguinte forma:
```python
class Data:
    def __init__(self, day, month, year):
        self.day = day # sem vírgula por aqui
        self.month = month # aqui também
        self.year = year
```

E assim, ao criar o objeto e chamar o `format_date(self)`, o resultado será como o esperado:
```
21/11/2007
```

---

Espero que tenha gostado do conteúdo. E que ele tenha te inspirado a não desistir dos erros sem mensagens quando eles acontecerem com você.

Eu sei que isso parece mais assustador do que os erros que possuem mensagem, mas lembre-se sempre de descansar, pesquisar com calma e, quem sabe, contar com a ajuda da comunidade para entender o que está acontecendo.

Só não desista de evoluir. Bons estudos! E bons erros!