简体   繁体   中英

Passing in Global Variables in Python

I am a somewhat experienced Java programmer who is re-implemting some code in Python, as I am just learning the language. The issue that I am having is that a method is returning nothing when I pass in global variables, but returning intended code when a literals are passed in. The code returns a list of words of the specified length passed in, starting with the string passed in. For example:

print getNGramBeginsWords("ha", 5)

returns

['HAAFS', 'HAARS', 'HABIT', 'HABUS', 'HACEK', 'HACKS', 'HADAL', 'HADED', 'HADES',
 'HADJI', 'HADST', 'HAEMS', 'HAETS', 'HAFIZ', 'HAFTS', 'HAHAS', 'HAIKA', 'HAIKS',
 'HAIKU', 'HAILS', 'HAINT', 'HAIRS', 'HAIRY', 'HAJES', 'HAJIS', 'HAJJI', 'HAKES', 
 'HAKIM', 'HAKUS', 'HALAL', 'HALED', 'HALER', 'HALES', 'HALID', 'HALLO', 'HALLS',
 'HALMA','HALMS', 'HALON', 'HALOS', 'HALTS', 'HALVA', 'HALVE', 'HAMAL', 'HAMES',
 'HAMMY', 'HAMZA', 'HANCE', 'HANDS', 'HANDY', 'HANGS', 'HANKS', 'HANKY', 'HANSA', 
 'HANSE', 'HANTS', 'HAOLE', 'HAPAX', 'HAPLY', 'HAPPY', 'HARDS', 'HARDY', 'HARED',
 'HAREM', 'HARES', 'HARKS', 'HARLS', 'HARMS', 'HARPS', 'HARPY', 'HARRY', 'HARSH', 
 'HARTS', 'HASPS', 'HASTE', 'HASTY', 'HATCH', 'HATED', 'HATER', 'HATES', 'HAUGH', 
 'HAULM', 'HAULS', 'HAUNT', 'HAUTE', 'HAVEN', 'HAVER', 'HAVES', 'HAVOC', 'HAWED', 
 'HAWKS', 'HAWSE', 'HAYED', 'HAYER', 'HAYEY', 'HAZAN', 'HAZED', 'HAZEL', 'HAZER', 
 'HAZES']

as it should. However,

print inputString
print numLetters
print getNGramBeginsWords(inputString, numLetters)

returns

ha
5
[]

inputString and numLetters are global variables, which I have seen called "dangerous," though I don't know why, and was thinking that they could be the cause of this oddity? Even local copies of the global variables being used as parameters doesn't help. Perhaps I need to use the "global" keyword in the parameters of the method, although from my research it appears you don't need the "global" keyword unless you are changing the global variable? Any suggestion or help would be appreciated. On the off chance that it is an issue with the method, here it is:

def getNGramBeginsWords(nGram, length):
    dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in dict:
        if(len(line)>0):
            if(len(nGram)>len(line.strip()) | len(line.strip())!= length):
                continue
            s = line.strip()[:len(nGram)]
            if(s == nGram and len(line.strip()) == length):
                words.append(line.strip())
    return words

tl;dr: Global variables have nothing to do with this; it is almost certainly that you are passing a string instead of an int as your length parameter. Your code had a lot of redundancies.

Your code has a number of obvious problems, both stylistic and substantive:

def getNGramBeginsWords(nGram, length):
    # dict is the name of a builtin function, which you are confusingly overwriting
    # dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        # an empty string evaluates to False in a binary context; also no need for those brackets
        stripline = line.strip().upper() # you keep doing this; I added the upper here.
        # you don't need this if, because you immediately test length
        #if stripline: #I know I changed this, but you only refer to the stripped version below 
        # pipe | is bitwise OR. I bet you don't want that
        if len(nGram)>len(stripline) or len(stripline)!= length:
            continue
        # s = stripline[:len(nGram)] #you only use this once
        # you don't need to check that stripline is of length again; you already did that
        # also, you can just use `endswith` instead of slicing
        if stripline.endswith(nGram):
            words.append(stripline)
    return words

And, without comments:

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        stripline = line.strip() # you keep doing this
        # you can merge these two ifs
        if len(nGram)>len(stripline) or len(stripline)!= length:
            continue
        if stripline.endswith(nGram):
            words.append(stripline)
    return words

Merging the two adjacent ifs:

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        stripline = line.strip().upper() # you keep doing this
        # you can merge these two ifs
        # also this renders the comparison of ngram and stripline lengths redundant
        if (len(stripline) == length) and stripline.endswith(nGram):
            words.append(stripline)
    return words

Now, let's look at this last version - funnily enough, you never actually perform a numeric operation on length . Given that length is supposed to be a number, you might like to force it to a number; if it can't be converted, you'll get an exception.

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    length = int(length) # force to an int
    assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input
    for line in wlist:
        stripline = line.strip().upper() # you keep doing this
        # you can merge these two ifs
        if (len(stripline) == length) and stripline.endswith(nGram):
            words.append(stripline)
    return words

And finally, you never actually close the file explicitly. You'll have it hanging around for a while. It's better to use the with construct to close it automatically:

def getNGramBeginsWords(nGram, length):
    with open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') as wlist:
        nGram = nGram.upper()
        words = []
        length = int(length) # force to an int
        assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input
        for line in wlist:
            stripline = line.strip().upper() # you keep doing this
            #you should be using `endswith` instead of the slice
            if (len(stripline) == length) and stripline.endswith(nGram):
                words.append(stripline)
        return words

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM