I have a modual(Is that the right term?)called WordPlay which has severl functions for exercises in Chapter 9 of "How to Think Like a (Python) Programmer". Below is my code for Ex9.3.2, which has the user input a string letters and then searches a .txt file(Attachment) for words that do not contain any of the letters in the string. The function returns the number of word that did not contain any of the letters.

fin = open ('E:/words.txt')

def avoid(word,forbid):
###Function to search word for any letter if list forbid.  Returns True in no letters in word###

    i=0
    answer='True'
    while i<len(forbid):
        if forbid[i] in word:
            answer='False'
            return answer
        else:
            i=i+1
    return answer

def has_none():
###Function to take a string of  letters from the user and search a list of words.  The number of words that do not cotain any of the letters will be given###

    contain=0
    notcontain=0
    input=raw_input("Please input a string of letters i.e. jdheu")
    for line in fin:
        if avoid(line,input)=='True':
            notcontain+=1
        elif avoid(line,input)=='False':
            contain+=1
    print str(notcontain) +" out of " + str(contain+notcontain) + " did not contain the letters " + input

The Problem:
The first time I call the function it run correctly but if I call the function again with a different set of letter I get 0 returned regardless of the string(Below is an example). I am sure the problem is that the .txt file needs to be reloaded, but I do not know the best way to do this, or any way really.

>>> from WordPlay import*
>>> has_none()
Please input a string of letters i.e. jdheuou
50582 out of 113809 did not contain the letters ou
>>> has_none()
Please input a string of letters i.e. jdheuo
0 out of 0 did not contain the letters o
>>>

Thanx in advance for the help! Let me know if any thing is unclear, and I apologize if it is.

Lanier

Recommended Answers

All 3 Replies

First of all, please use the Python style guide by GVR himself:
http://www.python.org/peps/pep-0008.html
To make code easier to read.

I used a different Words.txt, but this should work ...

# WordPlay.py
# saved the module in D:\Python25\Atest\Bull
# use sys.path.append(r'D:\Python25\Atest\Bull') so PYTHONPATH can find it

def avoid(word, forbid):
    """
    Function to search word for any letter if list forbid.
    Returns True if no letters in word
    """
    i = 0
    answer = True
    while i < len(forbid):
        if forbid[i] in word:
            answer = False
            return answer
        else:
            i = i + 1
    return answer

def has_none():
    """
    Function to take a string of letters from the user and search a list of words.
    The number of words that do not cotain any of the letters will be returned.
    """
    contain = 0
    notcontain = 0
    my_input = raw_input("Please input a string of letters (i.e. jdheu): ")
    for line in file(r'D:\Python25\Atest\Bull\Words.txt'):
        if avoid(line, my_input) == True:
            notcontain += 1
        elif avoid(line, my_input) == False:
            contain += 1
    print str(notcontain) + "words out of " + str(contain + notcontain) + \
        " did not contain the letters " + my_input
    
# test the module
if __name__ == '__main__':
    has_none()

The Python shell results ...

>>> import sys, os
>>> sys.path.append(r'D:\Python25\Atest\Bull')
>>> from WordPlay import *
>>> has_none()
Please input a string of letters (i.e. jdheu): aeui
1980words out of 74744 did not contain the letters aeui
>>> has_none()
Please input a string of letters (i.e. jdheu): aeui
1980words out of 74744 did not contain the letters aeui
>>>

The problem is line 2
fin = open ('E:/words.txt')
You open the file as a global and in line 23 process each record in the file via a for() loop, leaving the pointer at the end of the file. So the second time through you read the file starting at the end of the file, that is no records are read. You can use vegaseat's solution, or move the open into the function and then close the file (which does the same thing as vegaseat). That is somewhat inefficient since you read the same file every time the function is called but if the file is not large it is not much of a difference. has_none() would become

def has_none():

###Function to take a string of letters from the user and search a list of words. 
##The number of words that do not cotain any of the letters will be given###

     contain=0
     notcontain=0

     input=raw_input("Please input a string of letters i.e. jdheu")

     fin = open ('E:/words.txt')
     for line in fin:
          if avoid(line,input)=='True':
               notcontain+=1
          elif avoid(line,input)=='False':
               contain+=1
     fin.close()
     print str(notcontain) +" out of " + str(contain+notcontain) + " did not contain the letters " + input

Woooee is right. When you read a file line-by-line in a loop, it stops once it encounters EOF. Hence, you find nothing after that.

You can use seek(0) method of file handler to seek or move file-pointer to start of the file, without having to open and close the file recurssively.

>>> f = open("C:\\Documents and Settings\c5090455\Desktop\A.pm")
>>> f.tell()  # current position of the file pointer, now start of the file
0L
>>> f.read()
'\n# A.pm\npackage A;\nuse warnings;'
>>> f.tell()  # current position of the file, now EOF
361L
>>f.seek(0)  # move file pointer to start of the file.
>>> f.read()
'\n# A.pm\npackage A;\nuse warnings;'
>>f.close()
>>

katharnakh

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.