1

I have a Python program with class definitions, method definitions, and finally a main method which calls those methods and classes. When I run the program in the terminal, it outputs nothing, without an error message. Should I change the way my program is written?

The main method is at the bottom.

import re
import random

class node:
    def __init__(self, parent, daughters, edge):
        self.parent = parent
        self.daughters = daughters
        self.edge = edge
        trie.append(self)
        self.index = len(trie) - 1

def BruteForcePatternMatching(text, patterns):
    indices = []
    for pattern in patterns:
        pattern = re.compile(pattern)
        indices += pattern.finditer(text)
    return indices

def TrieConstruction(patterns, trie):
    trie.append(node(0, [], 0))
    for pattern in patterns:
        currentNode = trie[0]
        for base in pattern:
            for daughter in currentNode.daughters:
                if base == daughter.edge:
                    currentNode = daughter
                    break
            else:
                trie.append(node(currentNode, [], base))
                currentNode = trie[-1]

def PrefixTrieMatching(text, trie):
    v = trie[0]
    for index, base in enumerate(text):
        if v.daughters == []:
            pattern_out = []
            climb(v.index)
            return ''.join(pattern_out)
        else:
            for daughter in v.daughters:
                if base == daughter.edge:
                    v = daughter
                    break
            else:
                print('No matches found.')
                return

def climb(index):
    if index == 0:
        return
    else:
        pattern_out.append(node.edge)
        climb(trie[index].parent)

def TrieMatching(text, trie):
    while not text == []:
        PrefixTrieMatching(text, trie)
        text = text[:-1]

def SuffixTrieConstruction(text):
    trie = [node(0, [1], 0), node(0, [], len(text) + 1)] #we use normal nodes, but if they are leaves, we give them integers for indices

    for index in range(len(text)): 
        start = len(text) - index
        slide = text[start:-1]
        currentNode = trie[0]

        for symbol in slide:
            for daughter in currentNode.daughters:
                if symbol == daughter.edge:
                    currentNode = daughter
                    break
            else:
                trie.append(node(currentNode.index, [], symbol)) 
                currentNode = trie[-1]

            if symbol == slide[-1]:
                trie.append(node(currentNode.index, [], start))

    return trie

def SuffixTreeConstruction(trie):
    for node in trie:
        if len(node.daughters) == 1:
            node.edge = node.edge + trie[node.daughter[0]].edge
            trie[node.daughters[0]].parent = node.index
            node.daughters = trie[currentNode.daughters[0]].daughters
            del trie[node.daughter[0]]

    for node in trie:
        for daughter in node.daughters:
            print('(%d, %d, %s') % (node.index, daughter, node.edge)


def main():

    print('First, we open a file of DNA sequences and generate a random DNA string of length 3000, representative of the reference genome.')

    patterns = list(open('patterns'))
    text = ''
    for count in range(3000):
        text += choice('ACTG')

    print('We will first check for matches using the Brute Force matching method, which scans the text for matches of each pattern.')
    BruteForcePatternMatching(text, patterns)
    print('It returns the indices in the text where matches occur.')
    print('Next, we generate a trie with the patterns, and then run the text over the trie to search for matches.')
    trie = []
    TrieConstruction(patterns, trie)
    TrieMatching(text, trie)
    print('It returns all matched patterns.')
    print('Finally, we can construct a suffix tree from the text. This is the concatenation of all non-branching nodes into a single node.')
    SuffixTreeConstruction(SuffixTrieConstruction(text))
    print('It returns the adjacency list - (parent, daughter, edge).')
jukhamil
  • 779
  • 2
  • 11
  • 18

3 Answers3

5

Assuming that your code is saved in myfile.py.

You can, as other stated, add:

if __name__ == "__main__":
    main()

at the end of your file and run it with python myfile.py.

If, however, for some obscure reasons, you can not modify the content of your file, you can still achieve this with:

python -c "import myfile; myfile.main()"

from the command line. (as long as you run this from the directory containing myfile)

301_Moved_Permanently
  • 4,007
  • 14
  • 28
1

Simply call the main function at the end

main()
  • In this case the function will be run any time the program runs.

You can use

if __name__ == "__main__": main()
  • Only runs if that file is run (/ the module is executed)
Peter
  • 2,172
  • 1
  • 15
  • 11
1

As stated by NightShadeQueen and Chief.

Use

if __name__ == "__main__":
    main()

At the end of your program. This way, the program can be run from the command line and have all the functions defined within the program be importable without executing main().

See this post for a more detailed explanation of __name__ and it's uses.

Here is a StackOverflow post which goes into detail about a few of the things you can do with this and restates the original explanation in many different words for your leisure.

Zenohm
  • 548
  • 6
  • 17