简体   繁体   中英

Read file error in Python, even though print function is printing the list

I have been trying different ways of writing this code but cannot get past this. Currently the program will run all the way to the write_names(list) function and create the file, and the print function will print the sorted list. The program refuses to get the user input for the search_names() function but it will print anything I ask it to.

Debug highlights: while index < len(list) and in the debug I\\O only states "read file error". Hopefully someone has an idea what I'm doing wrong.

'#  Abstract:     This program creates a list of names.  The list is printed,
'#                sorted, printed again, written to file, and searched.
'#=============================================================================

'#define the main function

def main():

    #try:
        ##open data file for read
        #infile = open('names.txt', 'r')

    #call get_names function
    list = get_names()

    #call print function
    print_names(list)

    #sort list
    list.sort()

    #print sorted list
    print_names(list)

    #write sorted list to new file
    write_names(list)

    #allow user to search list
    search_names(list)



def get_names():

    try:
        infile = open('names.txt', 'r')
        #read file contents into a list
        list = infile.readlines()
        #close file
        infile.close()
        #strip \n from each element
        index = 0
        while index < len(list):
            list[index] = list[index].rstrip('\n')
            index += 1
        return list
    except IOError:
        print 'Read file error'

def print_names(list):

    #print header
    print '******************'
    #print list line by line
    index = 0
    while index < len(list):
        print list[index]
        index += 1
    return

def write_names(list):

    #open file for writing
    outfile = open('sortedNames.txt', 'w')
    #write the list to the file
    for item in list:
        outfile.write(str(item) + '\n')
    #close file
    outfile.close()

def search_names(list):

    #set user test variable
    again = 'Y'
    while again.upper == 'Y':
        #get search from user   
        search = raw_input('Enter a name to search for: ')
        #open list for search
        if search in list:
            try:
                item_index = list.index(search)
                print search, 'found.', item_index
            except ValueError:
                print search, 'not found.'



main()
'

Thanks in advance!

Your issue is that upper is a function, and you are not calling it. Your while in search_names() should read:

while again.upper() == 'Y':

instead of:

#strip \n from each element
index = 0
while index < len(list):
    list[index] = list[index].rstrip('\n')
    index += 1
return list

just use this list comprehension:

lines = infile.readlines()
infile.close()

return [ line.strip() for line in lines ]

edit:

It looks like you are using an index and a while loop where a for loop can be used.

Instead of:

while index < len(list):
    print list[index]
    index += 1

use:

    # using name_list instead of list
    for name in name_list:
        print name

also, your search_names() function looks flawed:

def search_names(list):

    #set user test variable
    again = 'Y'
    while again.upper == 'Y':
        #get search from user   
        search = raw_input('Enter a name to search for: ')
        #open list for search
        if search in list:
            try:
                item_index = list.index(search)
                print search, 'found.', item_index
            except ValueError:
                print search, 'not found.'

would never exit (again is never reassigned). try:

def search_names(names_list):
    again = 'Y'
    while again.upper() == 'Y':
        s_name = raw_input('Enter a name to search for: ')
        if s_name in names_list:
            print s_name, 'found.', names_list.index(s_name)
        else:
            print search, 'not found.'
        again = raw_input('Search for another name (Y|N)?: ')

or:

def search_names(names_list):
    again = 'Y'
    while again == 'Y':
        s_name = raw_input('Enter a name to search for: ')
        try:
            idx = names_list.index(s_name)
            print s_name, 'found.', idx
        except ValueError:
            print search, 'not found.'
        again = raw_input('Search for another name (Y|N)?: ').upper()

Which brings up the issue of when to catch exceptions vs using an if statement:

from msdn :

The method you choose depends on how often you expect the event to occur. If the event is truly exceptional and is an error (such as an unexpected end-of-file), using exception handling is better because less code is executed in the normal case. If the event happens routinely, using the programmatic method to check for errors is better. In this case, if an exception occurs, the exception will take longer to handle.

  1. Comments begin with # , not '# - you are making every other line of your header a docstring.

  2. You are using an index to iterate across lists, which is inefficient - just iterate on the list items.

  3. Calling a variable list is bad because it prevents you from accessing the list() datatype.

  4. Using with is a more reliable replacement for open() .. close()

  5. again.upper is a function reference - you have to call the function, ie again.upper() .

  6. You never change the value of again - this will be an infinite loop!

  7. You test if search in list but then do a try..except block which will only fail if it is not in the list (ie you are testing for the same failure twice).

.

#
# Operate on a list of names
#

def load_names(fname):
    try:
        with open(fname, 'r') as inf:
            return [line.strip() for line in inf]
    except IOError:
        print "Error reading file '{0}'".format(fname)
        return []

def print_names(namelist):
    print '******************'
    print '\n'.join(namelist)

def write_names(namelist, fname):
    with open(fname, 'w') as outf:
        outf.write('\n'.join(namelist))

def search_names(namelist):
    while True:
        lookfor = raw_input('Enter a name to search for (or nothing to quit): ').strip()
        if lookfor:
            try:
                ind = namelist.index(lookfor)
                print("{0} found.".format(lookfor))
            except ValueError:
                print("{0} not found.".format(lookfor))
        else:
            break

def main():
    namelist = load_names('names.txt')
    print_names(namelist)
    namelist.sort()
    print_names(namelist)
    write_names(namelist, 'sorted_names.txt')
    search_names(namelist)

if __name__=="__main__":
    main()

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