Move markov nodes to be single strings
Separating strings by spaces is more memory-friendly than using tuples. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -21,7 +21,7 @@ def chain_inner_default() -> defaultdict[str | None, int]:
|
|||||||
return defaultdict(int)
|
return defaultdict(int)
|
||||||
|
|
||||||
|
|
||||||
def chain_default() -> defaultdict[tuple[str, ...], defaultdict[str | None, int]]:
|
def chain_default() -> defaultdict[str, defaultdict[str | None, int]]:
|
||||||
return defaultdict(chain_inner_default)
|
return defaultdict(chain_inner_default)
|
||||||
|
|
||||||
|
|
||||||
@@ -51,11 +51,11 @@ class Chain:
|
|||||||
return
|
return
|
||||||
self.__load()
|
self.__load()
|
||||||
for fragment in windows(parts + [None], self.order + 1):
|
for fragment in windows(parts + [None], self.order + 1):
|
||||||
head = tuple(fragment[0:-1])
|
head = fragment[0:-1]
|
||||||
tail = fragment[-1]
|
tail = fragment[-1]
|
||||||
self.__cache[head][tail] += 1
|
self.__cache[" ".join(head)][tail] += 1
|
||||||
|
|
||||||
def get(self, key: tuple[str, ...]) -> dict[str | None, int]:
|
def get(self, key: str) -> dict[str | None, int]:
|
||||||
self.__last_access = asyncio.get_running_loop().time()
|
self.__last_access = asyncio.get_running_loop().time()
|
||||||
if self.__cache:
|
if self.__cache:
|
||||||
if key in self.__cache:
|
if key in self.__cache:
|
||||||
@@ -67,7 +67,7 @@ class Chain:
|
|||||||
self.__load()
|
self.__load()
|
||||||
return self.__cache[key]
|
return self.__cache[key]
|
||||||
|
|
||||||
def set(self, key: tuple[str, ...], value: Mapping[str | None, int]):
|
def set(self, key: str, value: Mapping[str | None, int]):
|
||||||
self.__last_access = asyncio.get_running_loop().time()
|
self.__last_access = asyncio.get_running_loop().time()
|
||||||
if not self.__cache:
|
if not self.__cache:
|
||||||
# Attempt the cache before writing to it
|
# Attempt the cache before writing to it
|
||||||
@@ -85,7 +85,7 @@ class Chain:
|
|||||||
self.__cache = defaultdict(
|
self.__cache = defaultdict(
|
||||||
chain_inner_default,
|
chain_inner_default,
|
||||||
{
|
{
|
||||||
tuple(key.split(" ")): defaultdict(
|
key: defaultdict(
|
||||||
int,
|
int,
|
||||||
{
|
{
|
||||||
(None if not word else word): weight
|
(None if not word else word): weight
|
||||||
@@ -107,7 +107,7 @@ class Chain:
|
|||||||
with open(self.path, "w") as fp:
|
with open(self.path, "w") as fp:
|
||||||
json.dump(
|
json.dump(
|
||||||
{
|
{
|
||||||
" ".join(key): {
|
key: {
|
||||||
("" if word is None else word): weight
|
("" if word is None else word): weight
|
||||||
for word, weight in value.items()
|
for word, weight in value.items()
|
||||||
}
|
}
|
||||||
@@ -131,17 +131,16 @@ class Chain:
|
|||||||
|
|
||||||
words: List[str] = []
|
words: List[str] = []
|
||||||
|
|
||||||
node = random.choice(list(self.__cache.keys()))
|
node = random.choice(list(self.__cache.keys())).split(" ")
|
||||||
words += node
|
words += node
|
||||||
next: str | None = self.choose_next(node)
|
next: str | None = self.choose_next(" ".join(node))
|
||||||
while next:
|
while next:
|
||||||
words += [next]
|
words += [next]
|
||||||
node = (*node[1:], next)
|
node = [*node[1:], next]
|
||||||
next = self.choose_next(node)
|
next = self.choose_next(" ".join(node))
|
||||||
|
|
||||||
return " ".join(words)
|
return " ".join(words)
|
||||||
|
|
||||||
def choose_next(self, head: tuple[str, ...]) -> str | None:
|
def choose_next(self, head: str) -> str | None:
|
||||||
self.__load()
|
self.__load()
|
||||||
choices = self.__cache[head]
|
choices = self.__cache[head]
|
||||||
words = list(choices.keys())
|
words = list(choices.keys())
|
||||||
|
|||||||
Reference in New Issue
Block a user