diff --git a/.travis.yml b/.travis.yml index 0377df2..314cfc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,8 @@ python: - '3.6' - '3.7' - '3.8' +- '3.9' +- '3.10' install: - python setup.py install - pip install coverage diff --git a/random_words/random_words.py b/random_words/random_words.py index b413f2b..c96f4a6 100644 --- a/random_words/random_words.py +++ b/random_words/random_words.py @@ -55,7 +55,7 @@ def load_nicknames(self, file): self.nicknames = json.load(f) @staticmethod - def check_count(count): + def check_int(a, count): """ Checks count @@ -63,9 +63,9 @@ def check_count(count): :raises: ValueError """ if type(count) is not int: - raise ValueError('Param "count" must be int.') + raise ValueError('Param "' + a + '" must be int.') if count < 1: - raise ValueError('Param "count" must be greater than 0.') + raise ValueError('Param "' + a + '" must be greater than 0.') class RandomWords(Random): @@ -75,56 +75,57 @@ def __init__(self): super(RandomWords, self).__init__('nouns') - def random_word(self, letter=None): + def random_word(self, letter=None, min_letter_count=1): """ Return random word. :param str letter: letter + :param int min_letter_count: minimum letter count :rtype: str :returns: random word """ - return self.random_words(letter)[0] + return self.random_words(letter, min_letter_count)[0] - def random_words(self, letter=None, count=1): + def random_words(self, letter=None, min_letter_count=1, count=1): """ Returns list of random words. :param str letter: letter + :param int min_letter_count: minimum letter count :param int count: how much words :rtype: list :returns: list of random words :raises: ValueError """ - self.check_count(count) + self.check_int("count", count) + self.check_int("min_letter_count", min_letter_count) words = [] if letter is None: - all_words = list( - chain.from_iterable(self.nouns.values())) + all_words = [w for w in chain.from_iterable(self.nouns.values()) if len(w) >= min_letter_count] try: words = sample(all_words, count) except ValueError: len_sample = len(all_words) - raise ValueError('Param "count" must be less than {0}. \ -(It is only {0} words)'.format(len_sample + 1, letter)) + raise ValueError('Param "count" must be less than {0}. (There are only {0} words)'.format(len_sample, letter)) elif type(letter) is not str: raise ValueError('Param "letter" must be string.') elif letter not in self.available_letters: raise ValueError( - 'Param "letter" must be in {0}.'.format( - self.available_letters)) + 'Param "letter" must be in {0}.'.format(self.available_letters)) elif letter in self.available_letters: + all_nouns_letter = [w for w in self.nouns[letter] if len(w) >= min_letter_count] + try: - words = sample(self.nouns[letter], count) + words = sample(all_nouns_letter, count) except ValueError: - len_sample = len(self.nouns[letter]) - raise ValueError('Param "count" must be less than {0}. \ -(It is only {0} words for letter "{1}")'.format(len_sample + 1, letter)) + len_sample = len(all_nouns_letter) + raise ValueError('Param "count" must be less than {0}. (There are only {0} words for letter "{1}")'.format(len_sample, letter)) return words @@ -161,7 +162,7 @@ def random_nicks(self, letter=None, gender='u', count=1): :returns: list of random nicks :raises: ValueError """ - self.check_count(count) + self.check_int("count", count) nicks = [] @@ -222,7 +223,7 @@ def randomMails(self, count=1): :rtype: list :returns: list of random e-mails """ - self.check_count(count) + self.check_int("count", count) random_nicks = self.rn.random_nicks(count=count) random_domains = sample(list(self.dmails), count) diff --git a/random_words/test/test_random_words.py b/random_words/test/test_random_words.py index a158d5a..c17999d 100644 --- a/random_words/test/test_random_words.py +++ b/random_words/test/test_random_words.py @@ -22,6 +22,18 @@ def test_random_word(self): word = self.rw.random_word(letter) assert word[0] == letter + def test_random_word_with_min_letter_count(self): + for letter in self.letters: + word = self.rw.random_word(letter, min_letter_count=5) + assert word[0] == letter + + def test_random_word_large_min_letter_count(self): + """ + min_letter_count is too large. + """ + for letter in self.letters: + pytest.raises(ValueError, self.rw.random_word, letter, min_letter_count=3443) + def test_random_word_value_error(self): pytest.raises(ValueError, self.rw.random_word, 'x') pytest.raises(ValueError, self.rw.random_word, 0) @@ -29,6 +41,10 @@ def test_random_word_value_error(self): pytest.raises(ValueError, self.rw.random_word, 9) pytest.raises(ValueError, self.rw.random_word, ['u']) pytest.raises(ValueError, self.rw.random_word, 'fs') + + pytest.raises(ValueError, self.rw.random_word, min_letter_count=-1) + pytest.raises(ValueError, self.rw.random_word, min_letter_count=None) + pytest.raises(ValueError, self.rw.random_word, min_letter_count="fds") def test_random_words(self): for letter in self.letters: @@ -36,20 +52,50 @@ def test_random_words(self): for word in words: assert word[0] == letter - def test_random_words_value_error(self): + def test_random_words_value_error_letter(self): pytest.raises(ValueError, self.rw.random_words, 'fa') pytest.raises(ValueError, self.rw.random_words, ['fha']) pytest.raises(ValueError, self.rw.random_words, 0) pytest.raises(ValueError, self.rw.random_words, -1) - - pytest.raises(ValueError, self.rw.random_words, letter=None, - count=1000000) - + pytest.raises(ValueError, self.rw.random_words, letter=None, count=1000000) + + def test_random_words_value_error_count(self): pytest.raises(ValueError, self.rw.random_words, count=0) pytest.raises(ValueError, self.rw.random_words, count=None) pytest.raises(ValueError, self.rw.random_words, count=[8]) pytest.raises(ValueError, self.rw.random_words, count=-5) + def test_random_words_value_error_min_letter_count(self): + pytest.raises(ValueError, self.rw.random_words, min_letter_count=0) + pytest.raises(ValueError, self.rw.random_words, min_letter_count=None) + pytest.raises(ValueError, self.rw.random_words, min_letter_count=[8]) + pytest.raises(ValueError, self.rw.random_words, min_letter_count=-5) + + def test_random_words_large_min_letter_count(self): + min_letter_count = 15 + words = self.rw.random_words(count=10, min_letter_count=min_letter_count) + for w in words: + assert len(w) >= min_letter_count + + def test_random_words_small_min_letter_count(self): + min_letter_count = 3 + words = self.rw.random_words(count=1000, min_letter_count=min_letter_count) + for w in words: + assert len(w) >= min_letter_count + + def test_random_words_z_letter_min_letter_count(self): + """ + There are not enough words for such query. + """ + pytest.raises(ValueError, self.rw.random_words, "z", count=5, min_letter_count=15) + + def test_random_words_min_letter_count(self): + for letter in self.letters: + min_letter_count = random.randint(1, 5) + words = self.rw.random_words(letter, count=2, min_letter_count=min_letter_count) + for w in words: + assert len(w) >= min_letter_count + def test_random_words_length_list(self): len_words = len(self.rw.random_words()) assert len_words == 1