Python code, copied from book & website but still not working 3.4
Question: First of, i'm sort of new to Python so sorry if this question is obvious. The
detect english module appears to be wrong, but it functions perfectly fine
when calling it and running it on its own, theres no errors when running it
alone and i've rewritten it a couple times to triple check it.

    
    
    Traceback (most recent call last):
      File "H:\Python\Python Cipher Program\transposition hacker.py", line 49, in <module>
        main()
     File "H:\Python\Python Cipher Program\transposition hacker.py", line 11, in   main
     hackedMessage = hackTransposition(myMessage)
     File "H:\Python\Python Cipher Program\transposition hacker.py", line 34, in hackTransposition
      if detectEnglish.isEnglish(decryptedText):
    File "H:\Python\Python Cipher Program\detectEnglish.py", line 48, in isEnglish
     wordsMatch = getEnglishCount(message) * 100 >= wordPercentage
     TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
    

this is the error i am getting when trying to run the Transposition Hacker
(copied directly from
[here](http://inventwithpython.com/transpositionHacker.py)

Here is the code for the Detect English Module # Detect english Module

    
    
    # to use this code
    # import detectEnglish
    # detectEnglish.isEnglish(somestring)
    # returns true of false
    # there must be a dictionary.txt file in the same directory
    # all english words
    # one per line
    
    UPPERLETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + ' \t\n'
    
    
    def loadDictionary()
     dictionaryFile = open('Dictionary.txt')
    englishWords = {}
    for word in dictionaryFile.read().split('\n'):
        englishWords[word] = None
    dictionaryFile.close()
    return englishWords
    
     ENGLISH_WORDS = loadDictionary()
    
    def getEnglishCount(message):
    message = message.upper()
    message = removeNonLetters(message)
    possibleWords = message.split()
    if possibleWords == []:
        return 0.0
    
    matches = 0
    for word in possibleWords:
        if word in ENGLISH_WORDS:
            matches += 1
            return float(matches) / len(possibleWords)
    
    def removeNonLetters(message):
    lettersOnly = []
    for symbol in message:
        if symbol in LETTERS_AND_SPACE:
            lettersOnly.append(symbol)
    return ''.join(lettersOnly)
    
    def isEnglish(message, wordPercentage=20, letterPercentage=85):
    # by default 20% of the words mustr exist in dictionary file
    # 85% of charecters in messafe must be spaces or letters
    wordsMatch = getEnglishCount(message) * 100 >= wordPercentage
    numLetters = len(removeNonLetters(message))
    messageLettersPercentage = float(numLetters) / len(message) * 100
    lettersMatch = messageLettersPercentage >= letterPercentage
    return wordsMatch and lettersMatcht
    


Answer: `getEnglishCount` looks like it is missing a return statement. If python gets
to the end of a function without hitting a return statement it will return
`None` as you're seeing.

try this:

    
    
    def getEnglishCount(message):
        message = message.upper()
        message = removeNonLetters(message)
        possibleWords = message.split()
        # if possibleWords == []:  # redundant
        #     return 0.0
        return len(possibleWords)
    

**Edit:** @Kevin Yea I think you're right - there was more in that function.
Maybe try this:

    
    
    def getEnglishCount(message):
        message = message.upper()
        message = removeNonLetters(message)
        possibleWords = message.split()
        if possibleWords == []:
            return 0.0
    
        matches = 0.
        for word in possibleWords:
            if word in ENGLISH_WORDS:
                matches += 1
        return matches / len(possibleWords)
    

I'd guess the indentation somehow got changed when you copy and pasted the
code, with the return statement nested under the `if`.

