Subversion Repositories programming

Rev

Rev 124 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/python
#Copyright: Ira W. Snyder
# Start Date: 2005-10-08
# End Date: 
# License: Public Domain
#
# Changelog Follows:
#   -- 2005-10-08 1830
#       Wrote and debugged the entire automaton class
#

import sys, string

class automaton:
    
    def __init__(self):
        self.__clear()
        self.verbose = False
    
    def __clear(self):
        self.num_states = 0
        self.num_letters = 0
        self.final_states = []
        self.trans_function = []
        
    def main_menu(self):
        done = False

        while(not done):
            print "Menu:"
            print "========================================"
            print "1. Enter an automaton"
            print "2. Run automaton"
            print "3. Enable Verbose Mode"
            print "4. Disable Verbose Mode"
            print "5. Quit"
            print
            s = raw_input("Choice >>> ")
            print

            if s == '1':
                self.__clear()
                self.read_automaton()
                print
            elif s == '2':
                input = raw_input("Enter string to test: ")
                self.run_automaton(input)
                print
            elif s == '3':
                self.verbose = True
                print "Verbose Mode Enabled!"
                print
            elif s == '4':
                self.verbose = False
                print "Verbose Mode Disabled!"
                print
            elif s == '5':
                done = True
            else:
                print 'Bad Selection'
                print

    def read_automaton(self):
        done = False
    
        ### Find out the number of states
        while(not done):
            s = raw_input("How many states?: ")

            try:
                self.num_states = int(s)
                done = True
            except (TypeError, ValueError):
                print "That wasn't an integer, try again!"
                print
            
        ### Find out what the last letter is
        done = False

        while(not done):
            s = raw_input("What is the last letter?: ")

            if len(s) != 1:
                print "One letter only please, try again!"
                print
        
            ### Lowercase the input
            s = s.lower()
            
            for i in range(26):
                if string.letters[i] == s:
                    self.num_letters = i + 1
                    done = True

            if not done:
                print "That was not a letter, try again!"
                print

        ### Find out which states are final states
        done = False

        print
        print "Enter a blank line to stop entering Final States"
        print

        while(not done):
            s = raw_input("Final state: ")

            ### Done reading input
            if len(s) == 0:
                done = True
                break
        
            if self.check_state(s):
                self.final_states.append(int(s))
            else:
                print "That was not a valid state, try again!"
            
        ### Read each state / letter pair
        for i in range(self.num_states):
            sublist = []
        
            for j in range(self.num_letters):
                done = False
                while not done:
                    s = raw_input("Enter state %d, letter %s -> state " % (i, string.letters[j]))

                    if self.check_state(s):
                        sublist.append(int(s))
                        done = True
                    else:
                        print "Not a valid state, try again!"
                        print

            self.trans_function.append(sublist)
        
        print "Done reading the automaton!"

    def check_state(self, s):
        """Checks the string representing a state to see if it's a valid state.
        Returns True if it is valid, False otherwise"""
        retVal = True
    
        try:
            state = int(s)
        except (TypeError, ValueError):
            retVal = False
            state = 99999999

        if state >= self.num_states:
            retVal = False

        return retVal
    
    def get_letter_num(self, s):
        s = s.lower()

        for i in range(26):
            if s == string.letters[i]:
                return i

        return -1

    def next_state(self, cur_state, letter):
        letter_num = self.get_letter_num(letter)

        if letter_num == -1 or letter_num >= self.num_letters:
            print "There was a bad letter in the input"
            print "*** I WILL STAY AT THE CURRENT STATE ***"
            return cur_state
            #sys.exit(1)
    
        next_state = self.trans_function[cur_state][letter_num]
    
        if self.verbose:
            print "state %d letter %s -> state %d" % (cur_state, letter, next_state)

        return next_state

    def run_automaton(self, input_string):
        cur_state = 0 #initial state is always q0
        
        for c in input_string:
            cur_state = self.next_state(cur_state, c)

        print "Done Running"
        print
        print "Final State: %d" % cur_state
        print "Accepted: %s" % (self.is_final_state(cur_state) and "Yes" or "No", )
        print
        print
        s = raw_input('Press ENTER to return to the main menu')

    def is_final_state(self, s):
        """Returns True if s is a final state, False otherwise"""
        retVal = True

        try:
            self.final_states.index(s)
        except ValueError:
            retVal = False

        return retVal

    def enable_verbose(self):
        self.verbose = True

    def disable_verbose(self):
        self.verbose = False

if __name__ == '__main__':
    a = automaton()
    a.main_menu()