1

I'm working on a PDF generator project. The goal is to have a program that takes document files and generate a PDF file. I'm having trouble in finding a way to input a file into the program to be converted.

I started out by using the input function, where I input the file in the terminal. As a test, I wanted to input, open, read, and print a csv file containing US zipcode data. The rest of the program opens, reads and prints out some of the data. Here is the code:

import csv

file = input("Drop file here: ")
with open(file, 'r', encoding='utf8') as zf:
    rf = csv.reader(zf, delimiter=',')
    header = next(rf)
    data = [row for row in rf]
    print(header)
    print(data[1])
    print(data[10])
    print(data[100])
    print(data[1000])

When I opened the terminal to input the file this error (TypeError: 'encoding' is an invalid keyword argument for this function) appeared.

Is there a better way I can code a program to input a file so it can be open and converted into a PDF?

  • 1
    What version of python are you using? python 2.7 does not support the keyword `encoding` for `open()`, but in python 3.x it does. See [this thread](https://stackoverflow.com/questions/10971033/backporting-python-3-openencoding-utf-8-to-python-2) for workaround if you must use python 2.7 with encoding. Or simply don't enforce the encoding if you don't need to. – r.ook Feb 10 '18 at 04:46
  • On the text editor, I'm using 3x. The terminal's default is 2.7 so that might be the problem. How can I change the default in the Terminal? – Arsene Bwasisi Feb 10 '18 at 04:50
  • You can try `python3 your_script.py` instead of `python your_script.py`. Check to see `python3 --version` beforehand if necessary. – r.ook Feb 10 '18 at 04:53

1 Answers1

0

There are more things going on and as was mentioned in the comments, in this case it is very relevant which version of python are you using. A bit more of the back story.

input built-in has different meaning in Python2 (https://docs.python.org/2.7/library/functions.html#input) or Python3 (https://docs.python.org/3.6/library/functions.html#input). In Python2 it reads the user input and tries to execute it as python code, which is unlikely what you actually wanted.

Then as pointed out, open arguments are different as well (https://docs.python.org/2.7/library/functions.html#open and https://docs.python.org/3.6/library/functions.html#open).

In short, as suggested by @idlehands, if you have both version installed try calling python3 instead of python and this code should actually run.

Recommendation: I would suggest not to use interactive input like this at all (unless there is a good reason to do that) and instead let the desired filename be passed in from outside. I'd opt for argparse (https://docs.python.org/3.6/library/argparse.html#module-argparse) in this case which very comfortably gives you great flexibility, for instance myscript.py:

#!/usr/bin/env python3
import argparse
import sys

parser = argparse.ArgumentParser(description='My script to do stuff.')
parser.add_argument('-o', '--output', metavar='OUTFILE', dest='out_file',
                    type=argparse.FileType('w'), default=sys.stdout,
                    help='Resulting file.')
parser.add_argument('in_file', metavar='INFILE', nargs="?",
                    type=argparse.FileType('r'), default=sys.stdin,
                    help='File to be processed.')

args = parser.parse_args()
args.out_file.write(args.in_file.read())  # replace with actual action

This gives you the ability to run the script as a pass through pipe stuff in and out, work on specified file(s) as well as explicitly use - to denote stdin/stdout are to be used. argparse also gives you command line usage/help for free.

You may want the specifics tweak for different behavior, but bottom line, I'd still go with a command line argument.

EDIT: I should add more more comment for consideration. I'd write the actual code (a function or more complex object) performing the wanted action so that it exposes ins/outs through its interfaces and write the command line to gather these bits and call my action code with it. That way you can reuse it from another Python script easily or write a GUI for that should you need/want to.

Ondrej K.
  • 8,841
  • 11
  • 24
  • 39
  • So does this allow me to drop a chosen document file into the program to be converted? The objective is to convert a text file into PDF, I'm trying to figure out how to input the file in the program so it can be converted. So essentially the steps to this project were: Input a text file, open and read file, convert to PDF, and return the PDF output. Would this steps work with the argparse module? – Arsene Bwasisi Mar 11 '18 at 00:19
  • With the give example, you could run `./myscript.py -o outpur_file input_file` which is hopefully what you wanted. I presume the "drop" does not refer to drug&drop of a GUI. – Ondrej K. Mar 12 '18 at 07:39
  • Yeah I can't use GUI, it's all backend. I just want to replicate that function to make it easy for any document to be converted. So this code opens a file in the terminal? – Arsene Bwasisi Mar 17 '18 at 00:46