Skip to content

Commit

Permalink
Merge pull request #51 from vil02/28-make-the-input-of-puzzle_generat…
Browse files Browse the repository at this point in the history
…orcreate-human-friendly

feat: make input of `create_puzzle.create` more human friendly
  • Loading branch information
vil02 committed Jul 28, 2024
2 parents fca30b8 + 05c91be commit eb57696
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 27 deletions.
16 changes: 7 additions & 9 deletions examples/basic_usage.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from puzzle_generator.create_puzzle import create

_PUZZLE = {
"str": "What is 1+1?",
"pass": "2",
"rest": {
"str": "What is my name?",
"pass": "Piotr",
"rest": {"str": "Congratulations, you solved this quiz!"},
},
}
_PUZZLE = [
"What is 1+1?",
"2",
"What is my name?",
"Piotr",
"Congratulations, you solved this quiz!",
]

print(create(_PUZZLE))
18 changes: 16 additions & 2 deletions puzzle_generator/create_puzzle.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import inspect
import typing

from .puzzle_data_encryption import encrypt_data
from .configurators import configurators


def question_answer_list_to_dict(qa_list: typing.List[str]):
if len(qa_list) % 2 == 0:
raise ValueError("The question/answer list must have odd length.")
if len(qa_list) == 1:
return {"str": qa_list[0]}
return {
"str": qa_list[0],
"pass": qa_list[1],
"rest": question_answer_list_to_dict(qa_list[2:]),
}


def _create_str(in_encrypted_puzzle, configurator) -> str:
advertisement = """# generated with puzzle-generator
#
Expand Down Expand Up @@ -32,7 +45,8 @@ def _create_str(in_encrypted_puzzle, configurator) -> str:
)


def create(in_puzzle, **kwargs) -> str:
def create(qa_list: typing.List[str], **kwargs) -> str:
puzzle = question_answer_list_to_dict(qa_list)
configurator = configurators.get_configurator(**kwargs)
encrypted_puzzle = encrypt_data(in_puzzle, configurator.get_encrypt())
encrypted_puzzle = encrypt_data(puzzle, configurator.get_encrypt())
return _create_str(encrypted_puzzle, configurator)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "puzzle-generator"
version = "0.5.3"
version = "0.6.0"
description = "Generates python code representing a puzzle"
authors = ["piotr.idzik <[email protected]>"]
readme = "./puzzle_generator/README.md"
Expand Down
91 changes: 76 additions & 15 deletions tests/test_create_puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
_PuzzleTestCase = collections.namedtuple(
"_PuzzleTestCase",
[
"puzzle",
"qa_list",
"correct",
"wrong",
],
Expand All @@ -26,17 +26,15 @@

@pytest.fixture(name="puzzle_tc")
def fixture_puzzle_tc():
puzzle = {
"str": "Question 1?",
"pass": "Answer 1",
"rest": {
"str": "Question 2?",
"pass": "Is this the final answer?",
"rest": {"str": "Congratulations!"},
},
}
qa_list = [
"Question 1?",
"Answer 1",
"Question 2?",
"Is this the final answer?",
"Congratulations!",
]
return _PuzzleTestCase(
puzzle=puzzle,
qa_list=qa_list,
correct=_InputOutput(
input=["Answer 1", "Is this the final answer?"],
output="Question 1?\nQuestion 2?\nCongratulations!\n",
Expand Down Expand Up @@ -111,7 +109,7 @@ def test_all_good_answers(
puzzle_path: pathlib.Path,
configuration,
) -> None:
puzzle: str = cp.create(puzzle_tc.puzzle, **configuration)
puzzle: str = cp.create(puzzle_tc.qa_list, **configuration)
res = _run_puzzle_str(puzzle, puzzle_tc.correct.input, puzzle_path)

assert res.returncode == 0
Expand All @@ -126,7 +124,7 @@ def test_wrong_answers(
configuration,
) -> None:
for cur_wrong in puzzle_tc.wrong:
puzzle: str = cp.create(puzzle_tc.puzzle, **configuration)
puzzle: str = cp.create(puzzle_tc.qa_list, **configuration)
res = _run_puzzle_str(puzzle, cur_wrong.input, puzzle_path)
assert res.returncode == 1
assert res.stdout == cur_wrong.output
Expand Down Expand Up @@ -176,7 +174,9 @@ def _input_simulator() -> str:

@pytest.mark.parametrize(("encrypt", "decrypt"), _ENCRYPT_DECRYPT_PAIRS)
def test_run_puzzle_all_good_answers(capsys, puzzle_tc, encrypt, decrypt) -> None:
encrypted_puzzle = pde.encrypt_data(puzzle_tc.puzzle, encrypt)
encrypted_puzzle = pde.encrypt_data(
cp.question_answer_list_to_dict(puzzle_tc.qa_list), encrypt
)
rp.run_puzzle(
encrypted_puzzle, decrypt, _get_input_simulator(puzzle_tc.correct.input)
)
Expand All @@ -187,7 +187,9 @@ def test_run_puzzle_all_good_answers(capsys, puzzle_tc, encrypt, decrypt) -> Non
@pytest.mark.parametrize(("encrypt", "decrypt"), _ENCRYPT_DECRYPT_PAIRS)
def test_run_puzzle_wrong_answers(capsys, puzzle_tc, encrypt, decrypt) -> None:
for cur_wrong in puzzle_tc.wrong:
encrypted_puzzle = pde.encrypt_data(puzzle_tc.puzzle, encrypt)
encrypted_puzzle = pde.encrypt_data(
cp.question_answer_list_to_dict(puzzle_tc.qa_list), encrypt
)
with pytest.raises(SystemExit) as exc_info:
rp.run_puzzle(
encrypted_puzzle,
Expand All @@ -198,3 +200,62 @@ def test_run_puzzle_wrong_answers(capsys, puzzle_tc, encrypt, decrypt) -> None:
assert captured.out == cur_wrong.output
assert exc_info.type is SystemExit
assert exc_info.value.code == 1


@pytest.mark.parametrize(
("qa_list", "expected"),
[
(["Congratulations!"], {"str": "Congratulations!"}),
(
["Question 1?", "Answer 1", "Congratulations!"],
{
"str": "Question 1?",
"pass": "Answer 1",
"rest": {"str": "Congratulations!"},
},
),
(
[
"What is 1+1?",
"2",
"What is 2+2?",
"4",
"What is 3+3?",
"6",
"Congratulations!",
],
{
"str": "What is 1+1?",
"pass": "2",
"rest": {
"str": "What is 2+2?",
"pass": "4",
"rest": {
"str": "What is 3+3?",
"pass": "6",
"rest": {"str": "Congratulations!"},
},
},
},
),
],
)
def test_question_answer_list_to_dict(qa_list, expected):
assert cp.question_answer_list_to_dict(qa_list) == expected


@pytest.mark.parametrize(
"wrong_qa_list",
[
[],
["Question", "Answer"],
["Question 1", "Answer 1", "Question 2", "Answer 2"],
],
)
def test_question_answer_list_to_dict_raises_when_input_list_has_even_length(
wrong_qa_list,
):
with pytest.raises(
ValueError, match="The question/answer list must have odd length."
):
cp.question_answer_list_to_dict(wrong_qa_list)

0 comments on commit eb57696

Please sign in to comment.