diff --git a/CHANGELOG.md b/CHANGELOG.md index b31df6e..3414e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Utilitário `remove_symbols_phone` [#188](https://github.com/brazilian-utils/brutils-python/pull/188) - Utilitário `remove_symbols_pis` [#236](https://github.com/brazilian-utils/brutils-python/pull/236) - Utilitário `remove_symbols_legal_process` [#209](https://github.com/brazilian-utils/brutils-python/pull/209) +- Utilitário `generate_titulo_eleitoral` [#220](https://github.com/brazilian-utils/brutils-python/pull/220) ### Removed diff --git a/README.md b/README.md index 63b9d5e..e158560 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ False - [Título Eleitoral](#titulo-eleitoral) - [is_valid_voter_id](#is_valid_voter_id) + - [generate_voter_id](#generate_voter_id) ## CPF @@ -897,6 +898,27 @@ False True ``` +### generate_voter_id + +Gera uma string de dígitos de Título de Eleitor válida aleatória a partir de um estado brasileiro informado. + +Args: + * federative_union (str): Unidade federativa para o título de eleitor que será gerado. O valor padrão "ZZ" é usado para títulos de eleitor emitidos para estrangeiros. + +Retorna: + * str: Um Título de eleitor válido gerado aleatoriamente. + +Exemplo: + +```python +>>> from brutils import generate_voter_id +>>> generate_voter_id() +'183475722801' +>>> generate_voter_id(federative_union ="MG") +'950125640248' +``` + + # Novos Utilitários e Reportar Bugs Caso queira sugerir novas funcionalidades ou reportar bugs, basta criar diff --git a/README_EN.md b/README_EN.md index 48e89b1..9688e72 100644 --- a/README_EN.md +++ b/README_EN.md @@ -84,6 +84,7 @@ False - [Voter ID](#voter-id) - [is_valid_voter_id](#is_valid_voter_id) + - [generate_voter_id](#generate_voter_id) ## CPF @@ -905,6 +906,26 @@ False True ``` +### generate_voter_id + +Generate a valid random Voter ID string of digits from an informed Brazilian federation union. + +Args: + * federative_union(str): federative union for the voter id that will be generated. The default value "ZZ" is used for voter IDs issued to foreigners. + +Returns: + * str: A randomly generated valid voter ID. + +Example: + +```python +>>> from brutils import generate_voter_id +>>> generate_voter_id() +'183475722801' +>>> generate_voter_id(federative_union ="MG") +'950125640248' +``` + # 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 afe7a62..b5ddd6c 100644 --- a/brutils/__init__.py +++ b/brutils/__init__.py @@ -90,6 +90,9 @@ from brutils.pis import ( remove_symbols as remove_symbols_pis, ) +from brutils.voter_id import ( + generate as generate_voter_id, +) from brutils.voter_id import ( is_valid as is_valid_voter_id, ) diff --git a/brutils/voter_id.py b/brutils/voter_id.py index 121ec35..5fad512 100644 --- a/brutils/voter_id.py +++ b/brutils/voter_id.py @@ -1,3 +1,6 @@ +from random import randint + + def is_valid(voter_id): # type: (str) -> bool """ Check if a Brazilian voter id number is valid. @@ -204,4 +207,59 @@ def _calculate_vd2(federative_union, vd1): # type: (str, int) -> str if federative_union in ["01", "02"] and rest == 0: vd2 = 1 + # edge case: rest == 10, declare vd2 as zero + if rest == 10: + vd2 = 0 + return vd2 + + +def generate(federative_union="ZZ") -> str: + """ + Generates a random valid Brazilian voter registration. + + Args: + federative_union(str): federative union for the voter id that will be generated. The default value "ZZ" is used for voter IDs issued to foreigners. + + Returns: + str: A randomly generated valid voter ID for the given federative union + """ + UFs = { + "SP": "01", + "MG": "02", + "RJ": "03", + "RS": "04", + "BA": "05", + "PR": "06", + "CE": "07", + "PE": "08", + "SC": "09", + "GO": "10", + "MA": "11", + "PB": "12", + "PA": "13", + "ES": "14", + "PI": "15", + "RN": "16", + "AL": "17", + "MT": "18", + "MS": "19", + "DF": "20", + "SE": "21", + "AM": "22", + "RO": "23", + "AC": "24", + "AP": "25", + "RR": "26", + "TO": "27", + "ZZ": "28", + } + + federative_union = federative_union.upper() + if federative_union in (UFs): + sequential_number = str(randint(0, 99999999)).zfill(8) + uf_number = UFs[federative_union] + if _is_federative_union_valid(uf_number): + vd1 = _calculate_vd1(sequential_number, uf_number) + vd2 = _calculate_vd2(uf_number, vd1) + return f"{sequential_number}{uf_number}{vd1}{vd2}" diff --git a/tests/test_voter_id.py b/tests/test_voter_id.py index 685a4a3..0797050 100644 --- a/tests/test_voter_id.py +++ b/tests/test_voter_id.py @@ -7,6 +7,7 @@ _get_sequential_number, _get_verifying_digits, _is_length_valid, + generate, is_valid, ) @@ -79,7 +80,9 @@ def test_calculate_vd1(self): self.assertIs(_calculate_vd1("73146415", "03"), 0) def test_calculate_vd2(self): - self.assertIs(_calculate_vd2("03", 7), 10) + self.assertIs(_calculate_vd2("02", 7), 2) + # edge case: if rest == 10, declare vd2 as zero + self.assertIs(_calculate_vd2("03", 7), 0) # edge case: if UF is "01" (for SP) and rest == 0 # declare dv2 as 1 instead self.assertIs(_calculate_vd2("01", 4), 1) @@ -87,6 +90,23 @@ def test_calculate_vd2(self): # declare dv2 as 1 instead self.assertIs(_calculate_vd2("02", 8), 1) + def test_generate_voter_id(self): + # test if is_valid a voter id from MG + voter_id = generate(federative_union="MG") + self.assertIs(is_valid(voter_id), True) + + # test if is_valid a voter id from AC + voter_id = generate(federative_union="AC") + self.assertIs(is_valid(voter_id), True) + + # test if is_valid a voter id from foreigner + voter_id = generate() + self.assertIs(is_valid(voter_id), True) + + # test if UF is not valid + voter_id = generate(federative_union="XX") + self.assertIs(is_valid(voter_id), False) + if __name__ == "__main__": main()