Skip to content

Commit e95ecfa

Browse files
Add missing type annotations for strings directory (TheAlgorithms#5817)
* Type annotations for `strings/autocomplete_using_trie.py` * Update autocomplete_using_trie.py * Update detecting_english_programmatically.py * Update detecting_english_programmatically.py * Update frequency_finder.py * Update frequency_finder.py * Update frequency_finder.py * Update word_occurrence.py * Update frequency_finder.py * Update z_function.py * Update z_function.py * Update frequency_finder.py
1 parent bbb88bb commit e95ecfa

5 files changed

+82
-102
lines changed

strings/autocomplete_using_trie.py

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
from __future__ import annotations
2+
13
END = "#"
24

35

46
class Trie:
5-
def __init__(self):
6-
self._trie = {}
7+
def __init__(self) -> None:
8+
self._trie: dict = {}
79

8-
def insert_word(self, text):
10+
def insert_word(self, text: str) -> None:
911
trie = self._trie
1012
for char in text:
1113
if char not in trie:
1214
trie[char] = {}
1315
trie = trie[char]
1416
trie[END] = True
1517

16-
def find_word(self, prefix):
18+
def find_word(self, prefix: str) -> tuple | list:
1719
trie = self._trie
1820
for char in prefix:
1921
if char in trie:
@@ -22,7 +24,7 @@ def find_word(self, prefix):
2224
return []
2325
return self._elements(trie)
2426

25-
def _elements(self, d):
27+
def _elements(self, d: dict) -> tuple:
2628
result = []
2729
for c, v in d.items():
2830
if c == END:
@@ -39,26 +41,28 @@ def _elements(self, d):
3941
trie.insert_word(word)
4042

4143

42-
def autocomplete_using_trie(s):
44+
def autocomplete_using_trie(string: str) -> tuple:
4345
"""
4446
>>> trie = Trie()
4547
>>> for word in words:
4648
... trie.insert_word(word)
4749
...
4850
>>> matches = autocomplete_using_trie("de")
49-
50-
"detergent " in matches
51+
>>> "detergent " in matches
5152
True
52-
"dog " in matches
53+
>>> "dog " in matches
5354
False
5455
"""
55-
suffixes = trie.find_word(s)
56-
return tuple(s + w for w in suffixes)
56+
suffixes = trie.find_word(string)
57+
return tuple(string + word for word in suffixes)
5758

5859

59-
def main():
60+
def main() -> None:
6061
print(autocomplete_using_trie("de"))
6162

6263

6364
if __name__ == "__main__":
65+
import doctest
66+
67+
doctest.testmod()
6468
main()

strings/detecting_english_programmatically.py

+27-26
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,56 @@
44
LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + " \t\n"
55

66

7-
def loadDictionary():
7+
def load_dictionary() -> dict[str, None]:
88
path = os.path.split(os.path.realpath(__file__))
9-
englishWords = {}
10-
with open(path[0] + "/dictionary.txt") as dictionaryFile:
11-
for word in dictionaryFile.read().split("\n"):
12-
englishWords[word] = None
13-
return englishWords
9+
english_words: dict[str, None] = {}
10+
with open(path[0] + "/dictionary.txt") as dictionary_file:
11+
for word in dictionary_file.read().split("\n"):
12+
english_words[word] = None
13+
return english_words
1414

1515

16-
ENGLISH_WORDS = loadDictionary()
16+
ENGLISH_WORDS = load_dictionary()
1717

1818

19-
def getEnglishCount(message):
19+
def get_english_count(message: str) -> float:
2020
message = message.upper()
21-
message = removeNonLetters(message)
22-
possibleWords = message.split()
21+
message = remove_non_letters(message)
22+
possible_words = message.split()
2323

24-
if possibleWords == []:
24+
if possible_words == []:
2525
return 0.0
2626

2727
matches = 0
28-
for word in possibleWords:
28+
for word in possible_words:
2929
if word in ENGLISH_WORDS:
3030
matches += 1
3131

32-
return float(matches) / len(possibleWords)
32+
return float(matches) / len(possible_words)
3333

3434

35-
def removeNonLetters(message):
36-
lettersOnly = []
35+
def remove_non_letters(message: str) -> str:
36+
letters_only = []
3737
for symbol in message:
3838
if symbol in LETTERS_AND_SPACE:
39-
lettersOnly.append(symbol)
40-
return "".join(lettersOnly)
39+
letters_only.append(symbol)
40+
return "".join(letters_only)
4141

4242

43-
def isEnglish(message, wordPercentage=20, letterPercentage=85):
43+
def is_english(
44+
message: str, word_percentage: int = 20, letter_percentage: int = 85
45+
) -> bool:
4446
"""
45-
>>> isEnglish('Hello World')
47+
>>> is_english('Hello World')
4648
True
47-
48-
>>> isEnglish('llold HorWd')
49+
>>> is_english('llold HorWd')
4950
False
5051
"""
51-
wordsMatch = getEnglishCount(message) * 100 >= wordPercentage
52-
numLetters = len(removeNonLetters(message))
53-
messageLettersPercentage = (float(numLetters) / len(message)) * 100
54-
lettersMatch = messageLettersPercentage >= letterPercentage
55-
return wordsMatch and lettersMatch
52+
words_match = get_english_count(message) * 100 >= word_percentage
53+
num_letters = len(remove_non_letters(message))
54+
message_letters_percentage = (float(num_letters) / len(message)) * 100
55+
letters_match = message_letters_percentage >= letter_percentage
56+
return words_match and letters_match
5657

5758

5859
if __name__ == "__main__":

strings/frequency_finder.py

+34-60
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Frequency Finder
22

3+
import string
4+
35
# frequency taken from http://en.wikipedia.org/wiki/Letter_frequency
4-
englishLetterFreq = {
6+
english_letter_freq = {
57
"E": 12.70,
68
"T": 9.06,
79
"A": 8.17,
@@ -33,85 +35,57 @@
3335
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3436

3537

36-
def getLetterCount(message):
37-
letterCount = {
38-
"A": 0,
39-
"B": 0,
40-
"C": 0,
41-
"D": 0,
42-
"E": 0,
43-
"F": 0,
44-
"G": 0,
45-
"H": 0,
46-
"I": 0,
47-
"J": 0,
48-
"K": 0,
49-
"L": 0,
50-
"M": 0,
51-
"N": 0,
52-
"O": 0,
53-
"P": 0,
54-
"Q": 0,
55-
"R": 0,
56-
"S": 0,
57-
"T": 0,
58-
"U": 0,
59-
"V": 0,
60-
"W": 0,
61-
"X": 0,
62-
"Y": 0,
63-
"Z": 0,
64-
}
38+
def get_letter_count(message: str) -> dict[str, int]:
39+
letter_count = {letter: 0 for letter in string.ascii_uppercase}
6540
for letter in message.upper():
6641
if letter in LETTERS:
67-
letterCount[letter] += 1
42+
letter_count[letter] += 1
6843

69-
return letterCount
44+
return letter_count
7045

7146

72-
def getItemAtIndexZero(x):
47+
def get_item_at_index_zero(x: tuple) -> str:
7348
return x[0]
7449

7550

76-
def getFrequencyOrder(message):
77-
letterToFreq = getLetterCount(message)
78-
freqToLetter = {}
51+
def get_frequency_order(message: str) -> str:
52+
letter_to_freq = get_letter_count(message)
53+
freq_to_letter: dict[int, list[str]] = {
54+
freq: [] for letter, freq in letter_to_freq.items()
55+
}
7956
for letter in LETTERS:
80-
if letterToFreq[letter] not in freqToLetter:
81-
freqToLetter[letterToFreq[letter]] = [letter]
82-
else:
83-
freqToLetter[letterToFreq[letter]].append(letter)
57+
freq_to_letter[letter_to_freq[letter]].append(letter)
58+
59+
freq_to_letter_str: dict[int, str] = {}
8460

85-
for freq in freqToLetter:
86-
freqToLetter[freq].sort(key=ETAOIN.find, reverse=True)
87-
freqToLetter[freq] = "".join(freqToLetter[freq])
61+
for freq in freq_to_letter:
62+
freq_to_letter[freq].sort(key=ETAOIN.find, reverse=True)
63+
freq_to_letter_str[freq] = "".join(freq_to_letter[freq])
8864

89-
freqPairs = list(freqToLetter.items())
90-
freqPairs.sort(key=getItemAtIndexZero, reverse=True)
65+
freq_pairs = list(freq_to_letter_str.items())
66+
freq_pairs.sort(key=get_item_at_index_zero, reverse=True)
9167

92-
freqOrder = []
93-
for freqPair in freqPairs:
94-
freqOrder.append(freqPair[1])
68+
freq_order: list[str] = [freq_pair[1] for freq_pair in freq_pairs]
9569

96-
return "".join(freqOrder)
70+
return "".join(freq_order)
9771

9872

99-
def englishFreqMatchScore(message):
73+
def english_freq_match_score(message: str) -> int:
10074
"""
101-
>>> englishFreqMatchScore('Hello World')
75+
>>> english_freq_match_score('Hello World')
10276
1
10377
"""
104-
freqOrder = getFrequencyOrder(message)
105-
matchScore = 0
106-
for commonLetter in ETAOIN[:6]:
107-
if commonLetter in freqOrder[:6]:
108-
matchScore += 1
78+
freq_order = get_frequency_order(message)
79+
match_score = 0
80+
for common_letter in ETAOIN[:6]:
81+
if common_letter in freq_order[:6]:
82+
match_score += 1
10983

110-
for uncommonLetter in ETAOIN[-6:]:
111-
if uncommonLetter in freqOrder[-6:]:
112-
matchScore += 1
84+
for uncommon_letter in ETAOIN[-6:]:
85+
if uncommon_letter in freq_order[-6:]:
86+
match_score += 1
11387

114-
return matchScore
88+
return match_score
11589

11690

11791
if __name__ == "__main__":

strings/word_occurrence.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Created by sarathkaul on 17/11/19
22
# Modified by Arkadip Bhattacharya(@darkmatter18) on 20/04/2020
33
from collections import defaultdict
4+
from typing import DefaultDict
45

56

67
def word_occurence(sentence: str) -> dict:
@@ -14,7 +15,7 @@ def word_occurence(sentence: str) -> dict:
1415
>>> dict(word_occurence("Two spaces"))
1516
{'Two': 1, 'spaces': 1}
1617
"""
17-
occurrence: dict = defaultdict(int)
18+
occurrence: DefaultDict[str, int] = defaultdict(int)
1819
# Creating a dictionary containing count of each word
1920
for word in sentence.split():
2021
occurrence[word] += 1

strings/z_function.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""
1111

1212

13-
def z_function(input_str: str) -> list:
13+
def z_function(input_str: str) -> list[int]:
1414
"""
1515
For the given string this function computes value for each index,
1616
which represents the maximal length substring starting from the index
@@ -27,7 +27,7 @@ def z_function(input_str: str) -> list:
2727
>>> z_function("zxxzxxz")
2828
[0, 0, 0, 4, 0, 0, 1]
2929
"""
30-
z_result = [0] * len(input_str)
30+
z_result = [0 for i in range(len(input_str))]
3131

3232
# initialize interval's left pointer and right pointer
3333
left_pointer, right_pointer = 0, 0
@@ -49,7 +49,7 @@ def z_function(input_str: str) -> list:
4949
return z_result
5050

5151

52-
def go_next(i, z_result, s):
52+
def go_next(i: int, z_result: list[int], s: str) -> bool:
5353
"""
5454
Check if we have to move forward to the next characters or not
5555
"""

0 commit comments

Comments
 (0)