From 2998707aec19344be0e547fce3de37ed34d301f3 Mon Sep 17 00:00:00 2001 From: docusland Date: Mon, 7 Oct 2024 12:28:18 +0200 Subject: [PATCH] =?UTF-8?q?D=C3=A9finition=20du=20sujet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 32 +++++++++++++++++ main.py | 23 +++++++++---- test_cryptarithme.py | 51 ++++++++++++++++++++++++++++ test_list_filenames_of_log_files.py | 38 +++++++++++++++++++++ test_list_ipv4_listed_in_logfiles.py | 46 +++++++++++++++++++++++++ 5 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 README.md create mode 100644 test_cryptarithme.py create mode 100644 test_list_filenames_of_log_files.py create mode 100644 test_list_ipv4_listed_in_logfiles.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a13d3f --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Evaluation Python +Vous devez implémenter les fonctions détaillées dans le fichier `main.py`. + +## Installation du projet + +```shell +# Clonez ce dépôt +git clone + +# Travaillez dans ce dépôt +cd +pip install -r requirements.txt +``` + +## Barème : + - implémentation des fonctions ( /22 Pts) +Faites en sorte que l'ensemble des tests unitaires fonctionnent. +```shell +pyunit +# ou +python -m pyunit . +``` + + - respect des bonnes pratiques de programmation en Python ( /2 Pts): +Votre code doit respecter les règles émises par le PEP. Note supérieure à 9/10 attendue lors de l'exection de la commande suivante : +```sh +pylint main.pylint +# ou +python -m pylint main.py +``` + +Pour votre gouverne, le barème total est sur 24 pts mais vous ne pourrez avoir plus que 20/20. \ No newline at end of file diff --git a/main.py b/main.py index 83f3094..d0445c1 100644 --- a/main.py +++ b/main.py @@ -37,13 +37,23 @@ def cryptarithme(message:str = "SEND + MORE = MONEY") -> list: """ The `message` is a formatted mathematical operation. Each letter represents a number between 0 and 9. + Each letter represents a different value. Find the value for each letter so that the full sentence is true. - Knowing that the first letter of each word cannot be a 0 if the word is longer than 1 letter. - It can occur that several results are possible. If so, all solutions must be returned in differents dictionnairies. + Knowing that if the word is longer than 1 letter, + the first letter of the word cannot be a 0. + + It can occur that several results are possible. + If so, all solutions must be returned in differents dictionnairies. The order is not relevant. - Example : A + A = C returns [{"A" : 1, "C" : 2}, {"A" : 2, "C" : 4}, {"A" : 3, "C" : 6}, {"A" : 4, "C" : 8}] + Example : A + A = C returns + [ + {"A" : 1, "C" : 2}, + {"A" : 2, "C" : 4}, + {"A" : 3, "C" : 6}, + {"A" : 4, "C" : 8} + ] :param message: The string to analyse :return: List of dictionnaries with the following format : { @@ -58,6 +68,7 @@ def cryptarithme(message:str = "SEND + MORE = MONEY") -> list: if __name__ == '__main__': - list_filenames_of_log_files('data') - list_ipv4_listed_in_logfiles('data') - cryptarithme("") + # list_filenames_of_log_files('data') + # list_ipv4_listed_in_logfiles('data') + # cryptarithme('A + A +A= B') + pass diff --git a/test_cryptarithme.py b/test_cryptarithme.py new file mode 100644 index 0000000..17b4fdb --- /dev/null +++ b/test_cryptarithme.py @@ -0,0 +1,51 @@ +from main import * +import pytest +import io +import sys + +def test_cryptarithme_fails_if_invalid_characters(): + with pytest.raises(ValueError) as e_info: + cryptarithme("AB_CD * WAIT ? = WHAT") + + +def test_cryptarithme_fails_if_invalid_format_too_many_letters(): + with pytest.raises(ValueError) as e_info: + cryptarithme("ABCDEF + GHIJKL = TOOMANYLETTERS") + +def test_cryptarithme_fails_if_invalid_format_too_many_equals(): + with pytest.raises(ValueError) as e_info: + cryptarithme("A + B = C = D") + +def test_cryptarithme_fails_if_invalid_format_too_many_plus(): + with pytest.raises(ValueError) as e_info: + cryptarithme("A + + B = C") + + +def test_cryptarithme_fails_if_impossible(): + with pytest.raises(CryptarithmeError) as e_info: + a = cryptarithme("ALPHA + BETA = GAMMA") + print(a) + +def test_cryptarithme_a_a_c(): + results = cryptarithme('A + A = B') + assert len(results) == 4 + +def test_cryptarithme_a_a_c_gives_proper_results(): + results = cryptarithme('A + A = B') + assert {"B": 2, "A": 1} in results + +def test_cryptarithme_planetes(): + result = cryptarithme('MARS + SATURNE + NEPTUNE = PLANETES') + assert len(result) == 1 + +def test_cryptarithme_a_a_a(): + results = cryptarithme('A + A = A') + assert len(results) == 1 + +def test_cryptarithme_prints_nothing(): + captured_output = io.StringIO() # Make StringIO. + sys.stdout = captured_output # Redirect stdout. + cryptarithme('A + A = B') # Call function. + sys.stdout = sys.__stdout__ # Reset redirect. + + assert len(captured_output.getvalue()) == 0, "The function printed an output in the console" diff --git a/test_list_filenames_of_log_files.py b/test_list_filenames_of_log_files.py new file mode 100644 index 0000000..b29bcce --- /dev/null +++ b/test_list_filenames_of_log_files.py @@ -0,0 +1,38 @@ +from main import * +import pytest +import io +import sys + + +def test_list_filenames_of_log_files_returns_a_list_of_log_files(): + files = list_filenames_of_log_files('data') + assert len(files) == 3 + + +def test_list_filenames_of_log_files_returns_only_log_files(): + files = list_filenames_of_log_files('data/oracle') + assert len(files) == 0 + + +def test_list_filenames_of_log_files_parses_all_folders(): + files = list_filenames_of_log_files('data/pangaia', 'data/systemfiles') + assert len(files) == 3 + + +def test_list_filenames_of_log_files_raises_the_exception(): + with pytest.raises(FileNotFoundError) as e_info: + list_filenames_of_log_files("non_existing_folder") + + +def test_list_filenames_of_log_files_raises_the_exception_with_several_folders(): + with pytest.raises(FileNotFoundError) as e_info: + list_filenames_of_log_files("data", "non_existing_folder") + + +def test_list_filenames_of_log_files_prints_nothing(): + captured_output = io.StringIO() # Make StringIO. + sys.stdout = captured_output # Redirect stdout. + list_filenames_of_log_files('data') # Call function. + sys.stdout = sys.__stdout__ # Reset redirect. + + assert len(captured_output.getvalue()) == 0, "The function printed an output in the console" diff --git a/test_list_ipv4_listed_in_logfiles.py b/test_list_ipv4_listed_in_logfiles.py new file mode 100644 index 0000000..c619470 --- /dev/null +++ b/test_list_ipv4_listed_in_logfiles.py @@ -0,0 +1,46 @@ +from main import * +import re +import io +import sys +import pytest + + +def test_list_ipv4_listed_in_logfiles_returns_list(): + res = list_ipv4_listed_in_logfiles('data') + assert type(res) == list + + +def test_list_ipv4_listed_in_logfiles_returns_correct_records(): + res = list_ipv4_listed_in_logfiles('data') + res = list(res) + assert '194.38.20.13' in res + + +def test_list_ipv4_listed_in_logfiles_returns_no_duplicates(): + res = list_ipv4_listed_in_logfiles('data') + res = list(res) + assert len(res) == 16 + + +def test_list_ipv4_listed_in_logfiles_prints_nothing(): + captured_output = io.StringIO() # Make StringIO. + sys.stdout = captured_output # Redirect stdout. + list_ipv4_listed_in_logfiles('data') # Call function. + sys.stdout = sys.__stdout__ # Reset redirect. + + assert len(captured_output.getvalue()) == 0, "The function printed an output in the console" + + +def test_list_ipv4_listed_in_logfiles_raises_the_exception_with_several_folders(): + with pytest.raises(FileNotFoundError) as e_info: + list_filenames_of_log_files("data", "non_existing_folder") + + +def test_refactoring_has_brought_a_generator(): + """ + Free points : +1 + """ + with open("main.py") as f: + lines : str = f.read() + found = re.search("yield", lines) + assert found, "No bonus linked to refactoring to a generator" \ No newline at end of file