From 6fbe6ec01890d3d3a96b14ecb0868e2a764d919d Mon Sep 17 00:00:00 2001 From: Lucas Alves Date: Wed, 23 Oct 2024 11:47:16 -0300 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20adi=C3=A7=C3=A3o=20da=20fun=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20is=5Fvalid=5Frenavam,=20que=20verifica=20o=20ren?= =?UTF-8?q?avam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 35 +++++++++++++++++++++++++++++++++- README_EN.md | 38 +++++++++++++++++++++++++++++++++++-- brutils/__init__.py | 9 ++++++++- brutils/renavam.py | 44 +++++++++++++++++++++++++++++++++++++++++++ tests/test_renavam.py | 35 ++++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 brutils/renavam.py create mode 100644 tests/test_renavam.py diff --git a/README.md b/README.md index 73769b04..5718ba61 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ False - [generate_voter_id](#generate_voter_id) - [IBGE](#ibge) - [convert_code_to_uf](#convert_code_to_uf) +- [RENAVAM](#renavam) + - [is_valid_renavam](#is_valid_renavam) ## CPF @@ -1109,6 +1111,37 @@ Exemplo: >>> ``` +## RENAVAM + +### is_valid_renavam +Valida o número de registro dos veículos brasileiros (RENAVAM). + +Essa função recebe a string do RENAVAM e veirifíca se está válido. +Um renavam válido é constituído por 11 digitos, onde o último é o digito verificador que é calculado por meio dos 10 digitos anteriores. + +Args: + * renavam (str): A string do RENAVAM para ser validado. + +Retorna: + * bool: Verdadeiro caso o RENAVAM seja válido, Falso caso contrário. + +Exemplo: +```python + >>> is_valid_renavam('12345678900') + True + >>> is_valid_renavam('12345678901') + False + >>> is_valid_renavam('1234567890a') + False + >>> is_valid_renavam('12345678 901') + False + >>> is_valid_renavam('12345678') # Less than 11 digits + False + >>> is_valid_renavam('') # Empty string + False + >>> is_valid_renavam(None) # None + False +``` # Novos Utilitários e Reportar Bugs @@ -1139,4 +1172,4 @@ Vamos construir juntos! 🚀🚀 [github-discussions-doc]: https://docs.github.com/pt/discussions [github-discussions]: https://github.com/brazilian-utils/brutils-python/discussions [github-issues-doc]: https://docs.github.com/pt/issues/tracking-your-work-with-issues/creating-an-issue -[github-issues]: https://github.com/brazilian-utils/brutils-python/issues +[github-issues]: https://github.com/brazilian-utils/brutils-python/issues \ No newline at end of file diff --git a/README_EN.md b/README_EN.md index 7917b673..6fe11b21 100644 --- a/README_EN.md +++ b/README_EN.md @@ -89,7 +89,8 @@ False - [generate_voter_id](#generate_voter_id) - [IBGE](#ibge) - [convert_code_to_uf](#convert_code_to_uf) - +- [RENAVAM](#renavam) + - [is_valid_renavam](#is_valid_renavam) ## CPF ### is_valid_cpf @@ -1112,6 +1113,39 @@ Exemplo: >>> ``` +## RENAVAM + +### is_valid_renavam +Validates the Brazilian vehicle registration number (RENAVAM). + +This function takes a RENAVAM string and checks if it is valid. +A valid RENAVAM consists of exactly 11 digits, with the last digit as +a verification digit calculated from the previous 10 digits. + +Args: + * renavam (str): The RENAVAM string to be validated. + +Returns: + * bool: True if the RENAVAM is valid, False otherwise. + +Example: +```python + >>> is_valid_renavam('12345678900') + True + >>> is_valid_renavam('12345678901') + False + >>> is_valid_renavam('1234567890a') + False + >>> is_valid_renavam('12345678 901') + False + >>> is_valid_renavam('12345678') # Less than 11 digits + False + >>> is_valid_renavam('') # Empty string + False + >>> is_valid_renavam(None) # None + False +``` + # Feature Request and Bug Report If you want to suggest new features or report bugs, simply create @@ -1141,4 +1175,4 @@ Let's build it together 🚀🚀 [github-discussions-doc]: https://docs.github.com/en/discussions [github-discussions]: https://github.com/brazilian-utils/brutils-python/discussions [github-issues-doc]: https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue -[github-issues]: https://github.com/brazilian-utils/brutils-python/issues +[github-issues]: https://github.com/brazilian-utils/brutils-python/issues \ No newline at end of file diff --git a/brutils/__init__.py b/brutils/__init__.py index 6959a0d0..b05503fe 100644 --- a/brutils/__init__.py +++ b/brutils/__init__.py @@ -122,6 +122,11 @@ is_valid as is_valid_voter_id, ) +# RENAVAM Imports +from brutils.renavam import ( + is_valid_renavam, +) + # Defining __all__ to expose the public methods __all__ = [ # CEP @@ -172,4 +177,6 @@ "is_valid_voter_id", # IBGE "convert_code_to_uf", -] + # RENAVAM + 'is_valid_renavam', +] \ No newline at end of file diff --git a/brutils/renavam.py b/brutils/renavam.py new file mode 100644 index 00000000..a693f207 --- /dev/null +++ b/brutils/renavam.py @@ -0,0 +1,44 @@ +def is_valid_renavam(renavam): # type: (str) -> bool + """ + Validates the Brazilian vehicle registration number (RENAVAM). + + This function takes a RENAVAM string and checks if it is valid. + A valid RENAVAM consists of exactly 11 digits, with the last digit as + a verification digit calculated from the previous 10 digits. + + Args: + renavam (str): The RENAVAM string to be validated. + + Returns: + bool: True if the RENAVAM is valid, False otherwise. + + Example: + >>> is_valid_renavam('12345678900') + True + >>> is_valid_renavam('12345678901') + False + >>> is_valid_renavam('1234567890a') + False + >>> is_valid_renavam('12345678 901') + False + >>> is_valid_renavam('12345678') # Less than 11 digits + False + >>> is_valid_renavam('') # Empty string + False + >>> is_valid_renavam(None) # None + False + """ + if renavam and len(renavam) == 11 and renavam.isnumeric(): + check_digit = int(renavam[-1:]) + renavam_digitis = [int(d) for d in renavam] + renavam_digitis = renavam_digitis[:-1] + multipliers = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3] + sum_digits = sum(digit * multipliers[i] for i, digit in enumerate(renavam_digitis[::-1])) + remainder_division = sum_digits % 11 + if remainder_division <= 1: + check_digit_calculated = 0 + else: + check_digit_calculated = 11 - remainder_division + if check_digit == check_digit_calculated: + return True + return False \ No newline at end of file diff --git a/tests/test_renavam.py b/tests/test_renavam.py new file mode 100644 index 00000000..23055017 --- /dev/null +++ b/tests/test_renavam.py @@ -0,0 +1,35 @@ +from unittest import TestCase +from brutils.renavam import is_valid_renavam + + +class TestRENAVAM(TestCase): + def test_is_valid_renavam(self): + # Testes para RENAVAM válidos + self.assertFalse(is_valid_renavam('12345678901')) + self.assertFalse(is_valid_renavam('09945438645')) + self.assertFalse(is_valid_renavam('94521237655')) + self.assertFalse(is_valid_renavam('45403264305')) + self.assertFalse(is_valid_renavam('45403471665')) + self.assertFalse(is_valid_renavam('34743721835')) + self.assertFalse(is_valid_renavam('69277208515')) + + self.assertTrue(is_valid_renavam('12345678900')) + self.assertTrue(is_valid_renavam('92876838150')) + self.assertTrue(is_valid_renavam('65720648534')) + self.assertTrue(is_valid_renavam('63601073019')) + self.assertTrue(is_valid_renavam('09945438641')) + self.assertTrue(is_valid_renavam('94521237651')) + self.assertTrue(is_valid_renavam('45403264308')) + self.assertTrue(is_valid_renavam('45403471664')) + self.assertTrue(is_valid_renavam('34743721831')) + self.assertTrue(is_valid_renavam('69277208510')) + + # Testes para entradas inválidas + self.assertFalse(is_valid_renavam('1234567890a')) # Contém letra + self.assertFalse(is_valid_renavam('12345678 901')) # Contém espaço + self.assertFalse(is_valid_renavam('12345678')) # Menos de 11 dígitos + self.assertFalse(is_valid_renavam('')) # String vazia + self.assertFalse(is_valid_renavam('123456789012')) # Mais de 11 dígitos + self.assertFalse(is_valid_renavam('abcdefghijk')) # Apenas letras + self.assertFalse(is_valid_renavam('12345678901!')) # Contém caractere especial + self.assertFalse(is_valid_renavam(None)) # Contém caractere especial From b2873494dcf67533cab9b0cbd8fff08f95b50688 Mon Sep 17 00:00:00 2001 From: Lucas Alves Date: Wed, 23 Oct 2024 13:21:58 -0300 Subject: [PATCH 2/3] =?UTF-8?q?doc:=20atualiza=C3=A7=C3=A3o=20changelog=20?= =?UTF-8?q?#430=20is=5Fvalid=5Frenavam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1546edc..ef1216c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Utilitário `convert_code_to_uf` [#397](https://github.com/brazilian-utils/brutils-python/pull/410) +- Utilitário `is_valid_renavam` [#430](https://github.com/brazilian-utils/brutils-python/pull/440) + ## [2.2.0] - 2024-09-12 ### Added From 347fb9412605b0a3bc73c5b03bf3f0c15e0aee88 Mon Sep 17 00:00:00 2001 From: Lucas Alves Date: Wed, 23 Oct 2024 13:27:40 -0300 Subject: [PATCH 3/3] =?UTF-8?q?ci:=20ajustes=20formata=C3=A7=C3=A3o=20#430?= =?UTF-8?q?=20is=5Fvalid=5Frenavam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- brutils/__init__.py | 14 ++++++------ brutils/renavam.py | 7 ++++-- tests/test_renavam.py | 51 +++++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/brutils/__init__.py b/brutils/__init__.py index b05503fe..f5ccf068 100644 --- a/brutils/__init__.py +++ b/brutils/__init__.py @@ -111,6 +111,11 @@ remove_symbols as remove_symbols_pis, ) +# RENAVAM Imports +from brutils.renavam import ( + is_valid_renavam, +) + # Voter ID Imports from brutils.voter_id import ( format_voter_id, @@ -122,11 +127,6 @@ is_valid as is_valid_voter_id, ) -# RENAVAM Imports -from brutils.renavam import ( - is_valid_renavam, -) - # Defining __all__ to expose the public methods __all__ = [ # CEP @@ -178,5 +178,5 @@ # IBGE "convert_code_to_uf", # RENAVAM - 'is_valid_renavam', -] \ No newline at end of file + "is_valid_renavam", +] diff --git a/brutils/renavam.py b/brutils/renavam.py index a693f207..c64e1d36 100644 --- a/brutils/renavam.py +++ b/brutils/renavam.py @@ -33,7 +33,10 @@ def is_valid_renavam(renavam): # type: (str) -> bool renavam_digitis = [int(d) for d in renavam] renavam_digitis = renavam_digitis[:-1] multipliers = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3] - sum_digits = sum(digit * multipliers[i] for i, digit in enumerate(renavam_digitis[::-1])) + sum_digits = sum( + digit * multipliers[i] + for i, digit in enumerate(renavam_digitis[::-1]) + ) remainder_division = sum_digits % 11 if remainder_division <= 1: check_digit_calculated = 0 @@ -41,4 +44,4 @@ def is_valid_renavam(renavam): # type: (str) -> bool check_digit_calculated = 11 - remainder_division if check_digit == check_digit_calculated: return True - return False \ No newline at end of file + return False diff --git a/tests/test_renavam.py b/tests/test_renavam.py index 23055017..d3e7e1d2 100644 --- a/tests/test_renavam.py +++ b/tests/test_renavam.py @@ -1,35 +1,38 @@ from unittest import TestCase + from brutils.renavam import is_valid_renavam class TestRENAVAM(TestCase): def test_is_valid_renavam(self): # Testes para RENAVAM válidos - self.assertFalse(is_valid_renavam('12345678901')) - self.assertFalse(is_valid_renavam('09945438645')) - self.assertFalse(is_valid_renavam('94521237655')) - self.assertFalse(is_valid_renavam('45403264305')) - self.assertFalse(is_valid_renavam('45403471665')) - self.assertFalse(is_valid_renavam('34743721835')) - self.assertFalse(is_valid_renavam('69277208515')) + self.assertFalse(is_valid_renavam("12345678901")) + self.assertFalse(is_valid_renavam("09945438645")) + self.assertFalse(is_valid_renavam("94521237655")) + self.assertFalse(is_valid_renavam("45403264305")) + self.assertFalse(is_valid_renavam("45403471665")) + self.assertFalse(is_valid_renavam("34743721835")) + self.assertFalse(is_valid_renavam("69277208515")) - self.assertTrue(is_valid_renavam('12345678900')) - self.assertTrue(is_valid_renavam('92876838150')) - self.assertTrue(is_valid_renavam('65720648534')) - self.assertTrue(is_valid_renavam('63601073019')) - self.assertTrue(is_valid_renavam('09945438641')) - self.assertTrue(is_valid_renavam('94521237651')) - self.assertTrue(is_valid_renavam('45403264308')) - self.assertTrue(is_valid_renavam('45403471664')) - self.assertTrue(is_valid_renavam('34743721831')) - self.assertTrue(is_valid_renavam('69277208510')) + self.assertTrue(is_valid_renavam("12345678900")) + self.assertTrue(is_valid_renavam("92876838150")) + self.assertTrue(is_valid_renavam("65720648534")) + self.assertTrue(is_valid_renavam("63601073019")) + self.assertTrue(is_valid_renavam("09945438641")) + self.assertTrue(is_valid_renavam("94521237651")) + self.assertTrue(is_valid_renavam("45403264308")) + self.assertTrue(is_valid_renavam("45403471664")) + self.assertTrue(is_valid_renavam("34743721831")) + self.assertTrue(is_valid_renavam("69277208510")) # Testes para entradas inválidas - self.assertFalse(is_valid_renavam('1234567890a')) # Contém letra - self.assertFalse(is_valid_renavam('12345678 901')) # Contém espaço - self.assertFalse(is_valid_renavam('12345678')) # Menos de 11 dígitos - self.assertFalse(is_valid_renavam('')) # String vazia - self.assertFalse(is_valid_renavam('123456789012')) # Mais de 11 dígitos - self.assertFalse(is_valid_renavam('abcdefghijk')) # Apenas letras - self.assertFalse(is_valid_renavam('12345678901!')) # Contém caractere especial + self.assertFalse(is_valid_renavam("1234567890a")) # Contém letra + self.assertFalse(is_valid_renavam("12345678 901")) # Contém espaço + self.assertFalse(is_valid_renavam("12345678")) # Menos de 11 dígitos + self.assertFalse(is_valid_renavam("")) # String vazia + self.assertFalse(is_valid_renavam("123456789012")) # Mais de 11 dígitos + self.assertFalse(is_valid_renavam("abcdefghijk")) # Apenas letras + self.assertFalse( + is_valid_renavam("12345678901!") + ) # Contém caractere especial self.assertFalse(is_valid_renavam(None)) # Contém caractere especial