#!/usr/bin/env python3

import automata.automaton as automaton


class NFA(automaton.Automaton):
    """a nondeterministic finite automaton"""

    def validate_automaton(self):
        """returns True if this NFA is internally consistent;
        raises the appropriate exception if this NFA is invalid"""

        for state in self.states:
            if state not in self.transitions:
                raise automaton.MissingStateError(
                    'state {} is missing from transition function'.format(
                        state))

        for start_state, paths in self.transitions.items():

            path_symbols = set(paths.keys())
            invalid_symbols = path_symbols - self.symbols.union({''})
            if invalid_symbols:
                raise automaton.InvalidSymbolError(
                    'symbols are not valid ({})'.format(
                        ', '.join(invalid_symbols)))

            path_states = set().union(*paths.values())
            invalid_states = path_states - self.states
            if invalid_states:
                raise automaton.InvalidStateError(
                    'states are not valid ({})'.format(
                        ', '.join(invalid_states)))

        if self.initial_state not in self.states:
            raise automaton.InvalidStateError(
                '{} is not a valid state'.format(self.initial_state))

        for state in self.final_states:
            if state not in self.states:
                raise automaton.InvalidStateError(
                    '{} is not a valid state'.format(state))

        return True

    def validate_input(self, input_str):
        """returns True if the given string is accepted by this NFA;
        raises the appropriate exception if the string is not accepted"""

        current_states = {self.initial_state}

        for symbol in input_str:

            if symbol not in self.symbols:
                raise automaton.InvalidSymbolError(
                    '{} is not a valid symbol'.format(symbol))

            new_current_states = set()
            for current_state in current_states:
                if (symbol in self.transitions[current_state] or
                        '' in self.transitions[current_state]):
                    if symbol in self.transitions[current_state]:
                        for state in self.transitions[current_state][symbol]:
                            new_current_states.add(state)
                    if '' in self.transitions[current_state]:
                        for state in self.transitions[current_state]['']:
                            new_current_states.add(state)
                else:
                    new_current_states.add(current_state)

            current_states = new_current_states

        new_current_states = set()
        for current_state in current_states:
            if '' in self.transitions[current_state]:
                for end_state in self.transitions[current_state]['']:
                    new_current_states.add(end_state)
            else:
                new_current_states.add(current_state)
        current_states = new_current_states

        if not (current_states & self.final_states):
            raise automaton.FinalStateError(
                'the automaton stopped on all non-final states ({})'.format(
                    (current_states - self.final_states)))

        return current_states

@@ -2100,32 +2100,33 @@
 current_states:%0A
+%0A
                 
@@ -2129,12 +2129,28 @@
     
-if (
+symbol_transition = 
 symb
@@ -2190,14 +2190,9 @@
 ate%5D
- or%0A  
+%0A
     
@@ -2203,21 +2203,38 @@
         
-     
+empty_str_transition =
  '' in s
@@ -2263,23 +2263,18 @@
 t_state%5D
-):%0A    
+%0A%0A
         
@@ -2286,33 +2286,25 @@
    if symbol
- in self.
+_
 transitions%5B
@@ -2301,38 +2301,18 @@
 ansition
-s%5Bcurrent_state%5D:%0A    
+:%0A
         
@@ -2319,32 +2319,36 @@
             for 
+end_
 state in self.tr
@@ -2397,36 +2397,32 @@
                 
-    
 new_current_stat
@@ -2424,35 +2424,36 @@
 _states.add(
+end_
 state)%0A
-    
+%0A
             
@@ -2463,51 +2463,30 @@
  if 
-'' in self.transitions%5Bcurrent_state%5D:%0A    
+empty_str_transition:%0A
     
@@ -2497,32 +2497,36 @@
             for 
+end_
 state in self.tr
@@ -2571,36 +2571,32 @@
                 
-    
 new_current_stat
@@ -2602,23 +2602,28 @@
 tes.add(
+end_
 state)%0A
+%0A
         
@@ -2622,36 +2622,85 @@
                 
-else
+if not symbol_transition and not empty_str_transition
 :%0A              

Clean up empty string logic in validate_input