Repository: brazilian-utils/brutils-python (language: python)

Issue:
Conversão de Código do IBGE de Estado para UF
**Seu pedido de recurso está relacionado a um problema? Por favor, descreva.**

Dado um código do IBGE de dois dígitos que representa um estado brasileiro, quero obter a sigla de Unidade Federativa (UF) correspondente. Isso é útil para conversão de códigos numéricos do IBGE em siglas de estados para sistemas e documentos.

Por exemplo, converter `"12"` para `"AM"` (Amazonas).

**Descreva a solução que você gostaria**

* Uma função `convert_code_to_uf`, que recebe um código do IBGE (string de 2 dígitos) e retorna a sigla de UF correspondente.
* A função deve verificar se o código do IBGE é válido e retornar a sigla da UF correspondente.
* Se o código do IBGE não for válido, a função deve retornar `None`.
* A função deve lidar com todos os estados e o Distrito Federal do Brasil.
* Os códigos do IBGE devem ser representados como strings de dois dígitos.
* Já existe um enum dos códigos do IBGE e suas correspondências com UF no arquivo `brutils/data/enums/ibge_uf.py`, porém o enum não mapeia para o código. Criar um novo Enum no mesmo arquivo que mapeie código e UF.

**Descreva alternativas que você considerou**

1. Seguir até o passo 8 do [guia de contribuição](https://github.com/brazilian-utils/brutils-python/blob/main/CONTRIBUTING.md#primeira-contribui%C3%A7%C3%A3o).

2. Como parte do passo 8, criar o arquivo: `brutils-python/brutils/ibge/uf.py`.

    ```python
    def convert_code_to_uf(code): # type: (str) -> str | None
        """
        Converts a given IBGE code (2-digit string) to its corresponding UF (state abbreviation).

        This function takes a 2-digit IBGE code and returns the corresponding UF code. 
        It handles all Brazilian states and the Federal District. 

        Args:
            code (str): The 2-digit IBGE code to be converted.

        Returns:
            str or None: The UF code corresponding to the IBGE code, 
                or None if the IBGE code is invalid.

        Example:
            >>> convert_code_to_uf('12')
            "AM"
            >>> convert_code_to_uf('33')
            "RJ"
            >>> convert_code_to_uf('99')
            None
        """
        # implementar a lógica da função aqui
    ```

    Importar a nova função no arquivo `brutils-python/brutils/__init__.py`:

    ```python
    # IBGE Imports    
    from brutils.ibge.uf import (
        convert_code_to_uf,
    )
    ```

    E adicionar o nome da nova função na lista `__all__` do mesmo arquivo `brutils-python/brutils/__init__.py`:

    ```python
    __all__ = [
        ...
        # IBGE
        'convert_code_to_uf',
    ]
    ```

3. Como parte do passo 9, criar o arquivo de teste: `brutils-python/tests/ibge/test_uf.py`.

    ```python
    from unittest import TestCase
    from brutils.ibge.uf import convert_code_to_uf

    class TestUF(TestCase):
        def test_convert_code_to_uf(self):
            # Testes para códigos válidos
            self.assertEqual(convert_code_to_uf('12'), "AM")  # Amazonas
            self.assertEqual(convert_code_to_uf('33'), "RJ")  # Rio de Janeiro
            self.assertEqual(convert_code_to_uf('31'), "MG")  # Minas Gerais
            self.assertEqual(convert_code_to_uf('52'), "GO")  # Goiás

            # Testes para códigos inválidos
            self.assertIsNone(convert_code_to_uf('99'))  # Código não existe
            self.assertIsNone(convert_code_to_uf('00'))  # Código não existe
            self.assertIsNone(convert_code_to_uf(''))   # Código vazio
            self.assertIsNone(convert_code_to_uf('AB'))  # Código não numérico

            # implementar mais casos de teste aqui se necessário
    ```

4. Seguir os passos seguintes do [guia de contribuição](https://github.com/brazilian-utils/brutils-python/blob/main/CONTRIBUTING.md#primeira-contribui%C3%A7%C3%A3o).

**Contexto adicional**

* A lista de códigos do IBGE e suas correspondências com as UFs é definida pelo Instituto Brasileiro de Geografia e Estatística (IBGE). Para mais detalhes, consulte o [site do IBGE](https://www.ibge.gov.br/).
* A lista de códigos e suas correspondências pode ser encontrada em: [https://www.ibge.gov.br/explicacoes-para-publico/explicacoes-para-publico/33180-tabela-de-codigos-de-unidade-federativa-uf.html](https://www.ibge.gov.br/explicacoes-para-publico/explicacoes-para-publico/33180-tabela-de-codigos-de-unidade-federativa-uf.html).


Discussion / hints:
Podemos pegar essa issue?
Assign feito @FSBEZERRA !

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3efcab1..b1546ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Added
+
+- Utilitário `convert_code_to_uf` [#397](https://github.com/brazilian-utils/brutils-python/pull/410)
 
 ## [2.2.0] - 2024-09-12
 
diff --git a/README.md b/README.md
index ae47d91..73769b0 100644
--- a/README.md
+++ b/README.md
@@ -87,6 +87,8 @@ False
   - [is_valid_voter_id](#is_valid_voter_id)
   - [format_voter_id](#format_voter_id)
   - [generate_voter_id](#generate_voter_id)
+- [IBGE](#ibge)
+  - [convert_code_to_uf](#convert_code_to_uf)
 
 ## CPF
 
@@ -1084,6 +1086,29 @@ Exemplo:
 '950125640248'
 ```
 
+## IBGE
+### convert_code_to_uf
+Converte um determinado código do IBGE (string de 2 dígitos) para sua UF (abreviatura estadual) correspondente.
+
+Args:
+  * code (str): O código IBGE de 2 dígitos a ser convertido.
+
+Retorna:
+  * str or None: O código UF correspondente ao código IBGE, ou None se o
+                 código IBGE for inválido.
+
+Exemplo:
+
+```python
+>>> from brutils.ibge.uf import convert_code_to_uf
+>>> convert_code_to_uf("12")
+'AC'
+>>> convert_code_to_uf("33")
+'RJ'
+>>> convert_code_to_uf("99")
+>>>
+```
+
 
 # Novos Utilitários e Reportar Bugs
 
diff --git a/README_EN.md b/README_EN.md
index 921e65a..7917b67 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -87,6 +87,8 @@ False
   - [is_valid_voter_id](#is_valid_voter_id)
   - [format_voter_id](#format_voter_id)
   - [generate_voter_id](#generate_voter_id)
+- [IBGE](#ibge)
+  - [convert_code_to_uf](#convert_code_to_uf)
 
 ## CPF
 
@@ -1087,6 +1089,29 @@ Example:
 '950125640248'
 ```
 
+## IBGE
+### convert_code_to_uf
+Converts a given IBGE code (2-digit string) to its corresponding UF (state abbreviation).
+
+Args:
+  * code (str): The 2-digit IBGE code to be converted.
+
+Retorna:
+  * str or None: The UF code corresponding to the IBGE code, or None if the
+                 IBGE code is invalid.
+
+Exemplo:
+
+```python
+>>> from brutils.ibge.uf import convert_code_to_uf
+>>> convert_code_to_uf("12")
+'AC'
+>>> convert_code_to_uf("33")
+'RJ'
+>>> convert_code_to_uf("99")
+>>>
+```
+
 # Feature Request and Bug Report
 
 If you want to suggest new features or report bugs, simply create
diff --git a/brutils/__init__.py b/brutils/__init__.py
index cbfa194..6959a0d 100644
--- a/brutils/__init__.py
+++ b/brutils/__init__.py
@@ -45,6 +45,11 @@
 # Email Import
 from brutils.email import is_valid as is_valid_email
 
+# IBGE Imports
+from brutils.ibge.uf import (
+    convert_code_to_uf,
+)
+
 # Legal Process Imports
 from brutils.legal_process import (
     format_legal_process,
@@ -165,4 +170,6 @@
     "format_voter_id",
     "generate_voter_id",
     "is_valid_voter_id",
+    # IBGE
+    "convert_code_to_uf",
 ]
diff --git a/brutils/data/enums/__init__.py b/brutils/data/enums/__init__.py
index 5a6997e..705fc82 100644
--- a/brutils/data/enums/__init__.py
+++ b/brutils/data/enums/__init__.py
@@ -1,1 +1,1 @@
-from .uf import UF
+from .uf import CODE_TO_UF, UF
diff --git a/brutils/data/enums/uf.py b/brutils/data/enums/uf.py
index aef6010..9bdb971 100644
--- a/brutils/data/enums/uf.py
+++ b/brutils/data/enums/uf.py
@@ -29,3 +29,33 @@ class UF(BetterEnum):
     SP = "São Paulo"
     SE = "Sergipe"
     TO = "Tocantins"
+
+
+class CODE_TO_UF(BetterEnum):
+    AC = "12"
+    AL = "27"
+    AP = "16"
+    AM = "13"
+    BA = "29"
+    CE = "23"
+    DF = "53"
+    ES = "32"
+    GO = "52"
+    MA = "21"
+    MT = "51"
+    MS = "52"
+    MG = "31"
+    PA = "15"
+    PB = "25"
+    PR = "41"
+    PE = "26"
+    PI = "22"
+    RJ = "33"
+    RN = "24"
+    RS = "43"
+    RO = "11"
+    RR = "14"
+    SC = "42"
+    SP = "35"
+    SE = "28"
+    TO = "17"
diff --git a/brutils/ibge/__init__.py b/brutils/ibge/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/brutils/ibge/uf.py b/brutils/ibge/uf.py
new file mode 100644
index 0000000..30dc741
--- /dev/null
+++ b/brutils/ibge/uf.py
@@ -0,0 +1,32 @@
+from brutils.data.enums.uf import CODE_TO_UF
+
+
+def convert_code_to_uf(code):  # type: (str) -> str | None
+    """
+    Converts a given IBGE code (2-digit string) to its corresponding UF (state abbreviation).
+
+    This function takes a 2-digit IBGE code and returns the corresponding UF code.
+    It handles all Brazilian states and the Federal District.
+
+    Args:
+        code (str): The 2-digit IBGE code to be converted.
+
+    Returns:
+        str or None: The UF code corresponding to the IBGE code,
+            or None if the IBGE code is invalid.
+
+    Example:
+        >>> convert_code_to_uf('12')
+        'AC'
+        >>> convert_code_to_uf('33')
+        'RJ'
+        >>> convert_code_to_uf('99')
+        >>>
+    """
+
+    result = None
+
+    if code in CODE_TO_UF.values:
+        result = CODE_TO_UF(code).name
+
+    return result


Test patch:
diff --git a/tests/ibge/__init__.py b/tests/ibge/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/ibge/test_uf.py b/tests/ibge/test_uf.py
new file mode 100644
index 0000000..389dec7
--- /dev/null
+++ b/tests/ibge/test_uf.py
@@ -0,0 +1,18 @@
+from unittest import TestCase
+
+from brutils.ibge.uf import convert_code_to_uf
+
+
+class TestUF(TestCase):
+    def test_convert_code_to_uf(self):
+        # Testes para códigos válidos
+        self.assertEqual(convert_code_to_uf("12"), "AC")
+        self.assertEqual(convert_code_to_uf("33"), "RJ")
+        self.assertEqual(convert_code_to_uf("31"), "MG")
+        self.assertEqual(convert_code_to_uf("52"), "GO")
+
+        # Testes para códigos inválidos
+        self.assertIsNone(convert_code_to_uf("99"))
+        self.assertIsNone(convert_code_to_uf("00"))
+        self.assertIsNone(convert_code_to_uf(""))
+        self.assertIsNone(convert_code_to_uf("AB"))