-1

I am working on a system that generates a language for use in fantasy storytelling and need a Markov Generator for it. I was able to find an open source Markov Generator in Python, and modify it to work for one word at a time. Problem is I don't need it to process one word once. I need it to make ~400 unique words, and push the output to a text file with one word per line so my main program can just run the.py, wait a bit, then continue on its merry day after loading the python file's output into memory.

In my normal programming language, I could just make the Markov a subroutine, then set up a loop like this:

set loop=400
:1
call Markov
set /a math=%loop%-1
set loop=%math%
if %loop% gtr 0 goto 1

Nice, simple, easy, intuitive. As long as the subroutine prints to the file, this works no problem, and I can execute it an arbitrary number of times.

Here is my code so far.

#Reads input.txt into an array.

def readFile(input):
        fileObj = open(input, "r") #opens the file in read mode
        words = fileObj.read().splitlines() #puts the file into an array
        fileObj.close()

#Creates new words using input.txt as a seed.

class Mdict:
    def __init__(self):
        self.d = {}
    def __getitem__(self, key):
        if key in self.d:
            return self.d[key]
        else:
            raise KeyError(key)
    def add_key(self, prefix, suffix):
        if prefix in self.d:
            self.d[prefix].append(suffix)
        else:
            self.d[prefix] = [suffix]
    def get_suffix(self,prefix):
        l = self[prefix]
        return random.choice(l)

class MName:
    """
    A name from a Markov chain
    """
    def __init__(self, chainlen = 2):
        """
        Building the dictionary
        """
        if chainlen > 10 or chainlen < 1:
            print ("Chain length must be between 1 and 10, inclusive")
            sys.exit(0)

        self.mcd = Mdict()
        oldnames = []
        self.chainlen = chainlen

        for l in words:
            l = l.strip()
            oldnames.append(l)
            s = " " * chainlen + l
            for n in range(0,len(l)):
                self.mcd.add_key(s[n:n+chainlen], s[n+chainlen])
            self.mcd.add_key(s[len(l):len(l)+chainlen], "\n")

    def New(self):
        """
        New name from the Markov chain
        """
        prefix = " " * self.chainlen
        name = ""
        suffix = ""
        while True:
            suffix = self.mcd.get_suffix(prefix)
            if suffix == "\n" or len(name) > 9:
                break
            else:
                name = name + suffix
                prefix = prefix[1:] + suffix
        return name.capitalize()

for i in range(1):
    word = (MName().New())

How do I make this execute an arbitrary number of times? How do I make it output to a text file?

martineau
  • 119,623
  • 25
  • 170
  • 301

1 Answers1

0

You can make the code loop 400 times by using

f = open('file.txt', 'w')
# open the file before the loop to prevent opening the file multiple times

for i in range(400):
  # Code that you want to run
  print(i)
  
  # write the output from the module in a text file
  f.write(outputfrommodule)

# close text file
f.close()

I'm not familiar with the module so if you can figure out how to get the output you can just use the code above

I'm available for questioning if you need help with my answer