0

This question relates to this one: Python app which reads and writes into its current working directory as a .app/exe

I got the path to the .txt file fine however now when I try to open it and read the contents it seems that it doesn't extract the data properly.

Here's the relevant code:

def getLines( filename ):
    path = Cocoa.NSBundle.mainBundle().bundlePath()

    real_path = path[0: len(path) - 8]

    print real_path

    f = open(real_path + filename, 'r') # open the file as an object

    if len(f.read()) <= 0:
        lines = {}                  # list to hold lines in the file
        for line in f.readlines():  # loop through the lines
            line = line.replace( "\r", "    " )
            line = line.replace( "\t", "    " )
            lines = line.split("    ")      # segment the columns using tabs as a base
        f.close()                   # close the file object

        return lines

lines = getLines( "raw.txt" )
for index, item in enumerate( lines ):        # iterate through lines
    # ...

These are the errors I'm getting:

  • 30/09/2012 10:28:49.103 [0x0-0x4e04e].org.pythonmac.unspecified.main: for index, item in enumerate( lines ): # iterate through lines
  • 30/09/2012 10:28:49.103 [0x0-0x4e04e].org.pythonmac.unspecified.main: TypeError: 'NoneType' object is not iterable

I kind of understand what the errors mean however I'm not sure why they are being flagged up because if I run my script with it not in a .app form it doesn't get these errors and extracts the data fine.

Community
  • 1
  • 1
Richard Bamford
  • 1,835
  • 3
  • 15
  • 19
  • 2
    Please don't use some other website to paste your code. While this may be good practice in IRC chatrooms, on stackoverflow it is preferable for you to paste the relevant code directly into the question. – Mark Hildreth Sep 30 '12 at 09:37
  • You want to convert tabs to spaces before pasting here though, it'll play havoc with the indentation otherwise. – Martijn Pieters Sep 30 '12 at 09:39

1 Answers1

4

You cannot read a file twice without resetting the read pointer. Moreover, your code actively prevents your file from being read properly.

Your code currently does this:

f= open(real_path + filename, 'r')  # open the file as an object

if len(f.read()) <= 0:
    lines = {}                  # list to hold lines in the file
    for line in f.readlines():  # loop through the lines

The .read() statement can read the whole file into memory in one go, resulting in the read pointer being moved to the end. The loop over .readlines() will not return anything.

But you also only run that code if your .read() call did not read anything. You are basically saying: If the file is empty, read the lines, otherwise do not read anything.

In the end this means your getlines() function always returns None, later leading to the error you see.

Loose the if len(f.read()) <= 0: altogether:

f= open(real_path + filename, 'r')  # open the file as an object

lines = {}                  # list to hold lines in the file
for line in f.readlines():  # loop through the lines

You then don't do anything much with lines = {} because for each line in your file you replace the lines variable: lines = line.split(" "). You probably meant to create a list instead, and append:

f= open(real_path + filename, 'r')  # open the file as an object

lines = []              # list to hold lines in the file
for line in f.readlines():  # loop through the lines
    # process line
    lines.append(line.split("    "))

Another tip: real_path = path[0: len(path) - 8] can be rewritten to real_path = path[:-8]. You probably want to look into the os.path module to manipulate your paths though; I suspect a os.path.split() call would work better and more reliably for you there.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343