Search code examples
pythonpython-3.xtypeerrornonetype

Getting unexpected error using decorator


I am trying to write a code which will allow person to enter a sentence, after which the sentence will be checked for vowels and censorship, it should also return total amount of vowels found in sentence. Here's what I have so far, however instead of running input once, I get it several times and then code comes up with following error: TypeError: 'NoneType' object is not iterable.

def vowel(func):
  def wrapper():
    vowels = "aeiouAEIOU"
    vowel_count = 0
    for items in func():
        if items in vowels:
            vowel_count += 1
            print("Vowel found: " + items)
    print("Total amount of vowels", vowel_count)
    return wrapper


def censorship(func):
    def wrapper():
        censorship_list = ["Word", "Word1", "Word2", "Word3"]
        for words in censorship_list:
            if words in func():
                print("You are not allowed to use those word(s) in set order: ", words)
    return wrapper


@vowel
@censorship
def sentence():
    sent = input("Input your sentence: ")
    return sent

sentence()

Solution

  • There are two issues. First, none of the wrapper functions are returning a value. Thus, when sentence is called, the first wrapper, in censorship, will not return the necessary values to use in vowel. Second, the func call in vowel will return all values from the previous decorator return (in censorship); however, even if wrapper in censorship returned a value, it would have to also include a copy of the original string input:

    def vowel(func):
      def wrapper():
        vowels = "aeiouAEIOU"
        vowel_count = 0
        start_val = func()
        for items in start_val:
          if items in vowels:
            vowel_count += 1
        return start_val, vowel_count
      return wrapper
    
    def censorship(func):
      def wrapper():
         censorship_list = ["Word", "Word1", "Word2", "Word3"]
         string = func()
         for words in censorship_list:
           if words in string:
             raise ValueError("You are not allowed to use those word(s) in set order: ")
         return string
      return wrapper
    
    @vowel
    @censorship
    def sentence():
      sent = input("Input your sentence: ")
      return sent