-
Notifications
You must be signed in to change notification settings - Fork 0
/
word-randomizer.py
executable file
·155 lines (128 loc) · 4.71 KB
/
word-randomizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
# ./word-randomizer.py --help
# ./word-randomizer.py --word foobar --number 5
import sys
import random
import argparse
from enum import Enum
from typing import List
VOWELS = ["a", "e", "i", "o", "u", "y"]
HARD_CONSONANTS = ["b", "c", "d", "g", "j", "k", "p", "q", "t", "x"]
SOFT_CONSONANTS = ["f", "h", "l", "m", "n", "r", "s", "v", "w", "z"]
class Strategy(Enum):
ROTATE_RANDOM_LETTER = "rotate-random-letter"
ROTATE_WORD = "rotate-word"
RANDOMIZE_WORD = "randomize-word"
RANDOMIZE_RANDOM_LETTER = "randomize-random-letter"
class ConfigService:
word: str
suffix: str
prefix: str
number: int
exclude: List[str]
strategy: str
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument(
"--word",
required=True,
metavar="",
type=str,
)
parser.add_argument(
"--suffix",
default="",
metavar="",
type=str,
)
parser.add_argument(
"--prefix",
default="",
metavar="",
type=str,
)
parser.add_argument(
"--number",
default=100,
metavar="",
type=int,
help="how many word to generate",
)
parser.add_argument(
"--exclude",
default="",
metavar="LIST",
type=list,
help='which letters to not consider, for example "abcd"',
)
parser.add_argument(
"--strategy",
default=Strategy.RANDOMIZE_RANDOM_LETTER.value,
metavar="",
type=str,
help=(
'one of "rotate-random-letter", "rotate-word", "randomize-word" or '
'"randomize-random-letter" (default)'
),
)
args = parser.parse_args()
self.word = args.word
self.suffix = args.suffix
self.prefix = args.prefix
self.number = args.number
self.exclude = args.exclude
self.strategy = args.strategy
class Main:
def __init__(self, config_service: ConfigService):
self.config_service = config_service
def main(self):
word = self.config_service.word
strategy = self.config_service.strategy
for _ in range(self.config_service.number):
if strategy == Strategy.ROTATE_WORD.value:
word = self._rotate_word(word)
elif strategy == Strategy.ROTATE_RANDOM_LETTER.value:
word = self._rotate_random_letter(word)
elif strategy == Strategy.RANDOMIZE_RANDOM_LETTER.value:
word = self._randomize_random_letter(word)
elif strategy == Strategy.RANDOMIZE_WORD.value:
word = self._randomize_word(word)
else:
raise Exception(f'Unknown strategy "{strategy}"')
sys.stdout.write(self.config_service.prefix)
sys.stdout.write(word)
sys.stdout.write(self.config_service.suffix)
sys.stdout.write(" ")
sys.stdout.write("\n")
def _get_related_letters(self, letter: str) -> List[str]:
letters = HARD_CONSONANTS
if letter in VOWELS:
letters = VOWELS
if letter in SOFT_CONSONANTS:
letters = SOFT_CONSONANTS
return letters
def _rotate_letter(self, letter: str) -> str:
letters = self._get_related_letters(letter)
new_letter = letters[(letters.index(letter) + 1) % len(letters)]
while new_letter in self.config_service.exclude:
new_letter = letters[(letters.index(new_letter) + 1) % len(letters)]
if new_letter == letter:
raise Exception(f'Failed to find a new letter to replace "{letter}"')
return new_letter
def _pick_random_letter(self, letter: str) -> str:
letters = self._get_related_letters(letter)
return random.choice(
[letter for letter in letters if letter not in self.config_service.exclude]
)
def _rotate_word(self, word: str) -> str:
return "".join([self._rotate_letter(letter) for letter in word])
def _randomize_word(self, word: str) -> str:
return "".join([self._pick_random_letter(letter) for letter in word])
def _rotate_random_letter(self, word: str) -> str:
index = random.randint(0, len(word) - 1)
return word[:index] + self._rotate_letter(word[index]) + word[index + 1 :]
def _randomize_random_letter(self, word: str) -> str:
index = random.randint(0, len(word) - 1)
return word[:index] + self._pick_random_letter(word[index]) + word[index + 1 :]
if __name__ == "__main__":
Main(ConfigService()).main()