Skip to content

Commit

Permalink
feat(main): refactor main not to violate DRY
Browse files Browse the repository at this point in the history
  • Loading branch information
Iamhexi committed Oct 4, 2024
1 parent d804be8 commit 3e4237f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 42 deletions.
52 changes: 10 additions & 42 deletions knowledge_verificator/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from knowledge_verificator.materials import MaterialDatabase
from knowledge_verificator.nli import NaturalLanguageInference, Relation
from knowledge_verificator.qg import QuestionGeneration
from knowledge_verificator.utils.string import clip_text
from knowledge_verificator.utils.menu import choose_from_menu


if __name__ == '__main__':
Expand Down Expand Up @@ -40,51 +40,19 @@
)
continue

console.print('Available materials:')
for i, material in enumerate(material_db.materials):
console.print(f'[{i+1}] {material.title}')
material_choice = input('Your choice: ')
console.print()

INCORRECT_CHOICE_WARNING = (
'This is incorrect choice. Next time, provide a number '
'next to a material from the list of available ones.'
)
if not material_choice.isnumeric():
console.print(INCORRECT_CHOICE_WARNING)
continue

chosen_index = int(material_choice) - 1
if chosen_index < 0 or chosen_index >= len(
material_db.materials
):
console.print(INCORRECT_CHOICE_WARNING)
continue

material = material_db.materials[chosen_index]

MAX_LENGTH_OF_CLIPPED_PARAGRAPH = 15
console.print('Available paragraphs: ')
for i, paragraph in enumerate(material.paragraphs):
console.print(
f'{i+1} {clip_text(paragraph, MAX_LENGTH_OF_CLIPPED_PARAGRAPH)}'
)

console.print('Which paragraph you want to learn? ')
paragraph_choice = input()

if not paragraph_choice.isnumeric():
console.print(INCORRECT_CHOICE_WARNING)
material_titles = [
material.title for material in material_db.materials
]
material = choose_from_menu(material_titles, 'materials')
if material is None:
continue

chosen_index = int(paragraph_choice) - 1
if chosen_index < 0 or chosen_index >= len(material.paragraphs):
console.print(INCORRECT_CHOICE_WARNING)
paragraph = str(
choose_from_menu(material.paragraphs, 'paragraphs')
)
if paragraph is None:
continue

# TODO: Refactor this fragment to apply DRY principle.
paragraph = material.paragraphs[chosen_index]

console.print('Learn this paragraph: ')
console.print(paragraph)
console.print()
Expand Down
43 changes: 43 additions & 0 deletions knowledge_verificator/utils/menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Module with utilities supporting creation of CLI menus."""

from typing import Any
from knowledge_verificator.io_handler import console
from knowledge_verificator.utils.string import clip_text


def choose_from_menu(
menu_elements: list[str], plural_name: str, max_line_width: int = 40
) -> Any | None:
"""
Prompt a user to choose an element from a list via terminal.
Args:
menu_elements (list[str]): List of elements to choose from.
Elements should be convertible to `str` (implement `__str__` method).
plural_name (str): Plural name of the elements. For example: options, paragraphs or names.
max_line_width (int): Maximum line width in number of columns. By default: 40.
Returns:
any | None: Element of a list or None if a user provided incorrect
value via a terminal.
"""
console.print(f'Available {plural_name}:')
for i, element in enumerate(menu_elements):
console.print(f'[{i+1}] {clip_text(element, max_line_width)}')
material_choice = input('Your choice: ')
console.print()

incorrect_choice_warning = (
'This is incorrect choice. Next time, provide a number '
'next to a element from the list of available ones.'
)
if not material_choice.isnumeric():
console.print(incorrect_choice_warning)
return None

chosen_index = int(material_choice) - 1
if chosen_index < 0 or chosen_index >= len(menu_elements):
console.print(incorrect_choice_warning)
return None

return menu_elements[chosen_index]

0 comments on commit 3e4237f

Please sign in to comment.