From a0c8c38c127b54c2e5392afc4bb48dc8d5356fc9 Mon Sep 17 00:00:00 2001 From: Oliver Lago <81615448+olilag@users.noreply.github.com> Date: Sat, 28 Sep 2024 22:48:34 +0200 Subject: [PATCH] Add unique_letters function and add option to word-finder to print out words containing unique letters (#13) --- docs/applications/word-finder.rst | 2 ++ src/susi_lib/functions/__init__.py | 1 + src/susi_lib/functions/functions.py | 18 ++++++++++++++++++ src/susi_lib/word_finder_cli.py | 13 +++++++++++-- tests/test_functions.py | 6 +++++- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/docs/applications/word-finder.rst b/docs/applications/word-finder.rst index d48c025..7297019 100644 --- a/docs/applications/word-finder.rst +++ b/docs/applications/word-finder.rst @@ -27,6 +27,8 @@ Program vie meniť svoje správanie podľa toho, čo napíšeš za ``susi-word-f - tu nasleduje cesta k textovému súboru, v ktorom chceme hľadať alebo skratku slovníku :any:`Dictionary` * - ``-w/--word-length`` - nasleduje číslo, aké dlhé slová má hľadať alebo rozpätie ``x-y``, ktoré znamená, že vyhľadá všetky slová dlhé ``x`` až ``y`` + * - ``-u/--unique`` + - ak pridáme túto možnosť, tak program vypíše iba slová, ktorých písmená sa neopakujú Číslo pri ``-w/--word-length`` sa použije hlavne vtedy, ak nasleduje iba jeden argument. Ak sa ``-w/--word-length`` nepoužije, dĺžka slova sa určí diff --git a/src/susi_lib/functions/__init__.py b/src/susi_lib/functions/__init__.py index 35492aa..ba8b18c 100644 --- a/src/susi_lib/functions/__init__.py +++ b/src/susi_lib/functions/__init__.py @@ -6,4 +6,5 @@ encode, find_anagrams, is_palindrome, + unique_letters, ) diff --git a/src/susi_lib/functions/functions.py b/src/susi_lib/functions/functions.py index 01be3dc..61d87e2 100644 --- a/src/susi_lib/functions/functions.py +++ b/src/susi_lib/functions/functions.py @@ -157,3 +157,21 @@ def find_anagrams(word: str, word_list: list[str]) -> list[str]: found_words.append(w) return found_words + + +def unique_letters(word: str) -> bool: + """Function for checking if given ``word`` contains only unique letters. + + :raises: :py:class:`TypeError` when ``word`` is not :py:class:`str` + + :param word: Word to check + :return: ``True`` if it contains unique letters, ``False`` otherwise + """ + if not isinstance(word, str): + raise TypeError("Word must be a string") + found: set[str] = set() + for c in word: + if c in found: + return False + found.add(c) + return True diff --git a/src/susi_lib/word_finder_cli.py b/src/susi_lib/word_finder_cli.py index cf28a36..b6a790b 100644 --- a/src/susi_lib/word_finder_cli.py +++ b/src/susi_lib/word_finder_cli.py @@ -5,6 +5,7 @@ from typing import Literal, TypedDict, cast from susi_lib.dictionary import Dictionary, _Mapping +from susi_lib.functions import unique_letters from susi_lib.regex import Selection, create_regex @@ -83,11 +84,16 @@ def _translate( parser.add_argument( "-i", "--input-file", - type=str, default=None, help="Path to a input file, each word should be on separate line. Or a dictionary short: \ 'PM', 'PM_a', 'S', 'S_a', 'ZT', 'ZT_a'. Default: stdin", ) +parser.add_argument( + "-u", + "--unique", + action="store_true", + help="If set, it finds only words with unique letters", +) parser.add_argument( "wanted_letters", help="type wanted letters without spaces or space separated groups of wanted \ @@ -124,5 +130,8 @@ def main() -> Literal[0, 1]: args_parsed.wanted_letters, word_length, args_parsed.input_file ) regex = create_regex(*args, **kwargs) - print("\n".join(regex.execute())) + result = regex.execute() + if args_parsed.unique: + result = [w for w in result if unique_letters(w)] + print("\n".join(result)) return 0 diff --git a/tests/test_functions.py b/tests/test_functions.py index 7cc641f..69220cc 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -1,7 +1,7 @@ # pylint: skip-file import unittest -from susi_lib.functions import find_anagrams, is_palindrome +from susi_lib.functions import find_anagrams, is_palindrome, unique_letters from susi_lib.types import Symbols @@ -27,6 +27,10 @@ def test_find_anagrams(self): with self.assertRaises(TypeError): find_anagrams("kokos", [1, 2, 3]) + def test_unique_letters(self): + self.assertTrue(unique_letters("abc")) + self.assertFalse(unique_letters("kokos")) + if __name__ == "__main__": unittest.main()