3

I'm making a Python code to manipulate text files. The code will receive from the command line input file and output file names and a flag -sort, -reverse etc according to manipulation to apply on the input file and finally write the data to output file. I need to do all this job inside a class so the code will be inheritable. So far I have a code like this:

import argparse  
import random  

class Xiv(object):  

    def __init__(self):  
        parser = argparse.ArgumentParser()  
        group = parser.add_mutually_exclusive_group()  
        group.add_argument("-s", "-sort", action="store_true")  
        group.add_argument("-r", "-reverse", action="store_true")  
        group.add_argument("-sh", "-shuffle", action="store_true")  
        parser.add_argument("inputfile", type = file, help="Input file name")  
        parser.add_argument("outputfile", type = file, help="Output file name")  
        args = parser.parse_args()  
        source =args.inputfile  
        dist = args.outputfile  

    def sort(self):  
     f = open(source, "r")  
     list1 = [line for line in f if line.strip()]  
     f.close()  
     list.sort()  
     with open(dist, 'wb') as fl:  
       for item in list:  
        fl.write("%s" % item)  

    def reverse(self, source, dist):  
     f = open(source, "r")  
     list2 = [line for line in f if line.strip()]  
     f.close()  
     list2.reverse()  
     with open(dist, 'wb') as f2:  
       for item in list2:  
         f2.write("%s" % item)      

def shuffle(self, source, dist):  
    f = open(source, "r")  
    list3 = [line for line in f if line.strip()]  
    f.close()  
    random.shuffle(list3)  
    with open(dist, 'wb') as f3:  
     for item in list3:  
      f3.write("%s" % item)  

x = Xiv();  

Now when I run it as

python xiv.py -s text.txt out.txt 

it presents the following error

IOError: [Errno 2] No such file or directory 'out.txt'  

But 'out.txt' is going to be the output file, I suggest the code to create it in case the file is not already existing. And it worked before I put this code inside the class....

Prophet
  • 32,350
  • 22
  • 54
  • 79
  • Where do you call sort, reverse or shuffle ? I can't reproduce your error. Also, I don't understand why you use %s to write in file, `item` is already a string, and why do you open with "wb" ? Finally see [this question](http://stackoverflow.com/questions/15233340/getting-rid-of-n-when-using-readlines) for other way to read the source file. – Mel Aug 21 '15 at 15:18
  • I currently still not calling sort, reverse or shuffle, just calling the __init__ by creating 'x' instance of the 'Xiv" class. I'm using %s and "wb" since I took it from some example I found and it worked before ;) Anyway, my question is why error is presented for output file? It is not the source file to be read from disk.. – Prophet Aug 21 '15 at 15:28
  • Actually to get it to work I had to remove `type=file`. It gave me `NameError: name 'file' is not defined` – Mel Aug 21 '15 at 15:31
  • Please show the WHOLE traceback. This includes valuable information such as the line on which the error occurs. Also, note that your `sort()` method will raise a `NameError` exception, because the `source` variable will be undefined – holdenweb Aug 21 '15 at 15:31
  • This question [How to open file using argparse?](http://stackoverflow.com/questions/18862836/how-to-open-file-using-argparse) suggests that `type=file` is not what you should do. – Mel Aug 21 '15 at 15:33
  • the traceback is inside C:\Python27\lib\argparse.py Will this info help you? The only reference to my code is about the following line: line 45 `x = `Xiv()`. I saw that question you mentioned but find no answer to my problem ;( – Prophet Aug 21 '15 at 15:45

3 Answers3

1

In Python 2, when I call file on a nonexistent file I get this error:

In [13]: file('out.txt')
---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)
<ipython-input-13-d0d554b7d5b3> in <module>()
----> 1 file('out.txt')

IOError: [Errno 2] No such file or directory: 'out.txt'

In Py2, file is equivalent to open. It opens a file, default in r mode, and thus will give this error if the file does not exist.

In argparse, the type=foo means run the function foo using the input string. It does not mean 'interpret the string as an object of this type'.

In your code:

with open(dist, 'wb') as f2:  
   for item in list2:  
       f2.write("%s" % item)

That means you expect dist to be a filename, a string. You don't want the parser to open the file first. You are doing that yourself. So don't specify a type parameter.

@tmoreau - Python3 dropped that file function, leaving only open.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
1

The open function opens a file for reading by default. What you want is to open it in write/create mode, which will create it if it doesn't exist and allow you to write to it:

with open(dist, 'w+') as f3:

The second argument specifies the open mode, and it defaults to 'r', meaning read only.

I'm not sure why it worked before you moved it into the class - by all accounts, it should make no difference.

zrneely
  • 1,802
  • 3
  • 17
  • 26
1

I was getting this error..

jemdoc index Traceback (most recent call last): File "/usr/bin/jemdoc", line 1563, in main() File "/usr/bin/jemdoc", line 1555, in main infile = open(inname, 'rUb') IOError: [Errno 2] No such file or directory: 'index.jemdoc'

then i have changed

infile = open(inname, 'rUb') 

to

infile = open(inname, 'w+')

Then the error was solved.

SamWhan
  • 8,296
  • 1
  • 18
  • 45
  • 1
    Hi, this seems to be an answer to a different problem specific to jemdoc. – Luna May 27 '16 at 15:01
  • 1
    It appears as if you've answered this question to me. However, a suggestion: try to be more specific when answering though. And use different formats, e.g. to make code stand out. I took the liberty of doing some for you :) – SamWhan May 27 '16 at 15:13