2013-08-17 2 views
1

У меня есть сценарий, который должен читать в указанном пользователем 2-столбце csv-файле, расположенном в том же каталоге, выполнять некоторые математические данные и выводить результаты на stdout который является другим определяемым пользователем CSV-файлом. Я сделал это в 2.7.5, но теперь, вернувшись к 3.2, он не работает. Не шоком, которого я знаю, но я довольно неопытен в программировании, и у меня возникли проблемы с разработкой, как заставить его работать на Python 3.Указанное пользователем чтение и печать csv в Python 3

Я отменил код на его основные элементы для чтения и печати, которые использовали чтобы работать, и он все еще не работает в 3.2, несмотря на то, что он делает некоторые из более очевидных изменений, он просто застревает и никогда не печатает в новый файл. Я попытался использовать 2to3.py, но это порождает плохой ввод parseerror и никаких изменений не сделано! Я бы предпочел узнать, почему это сейчас не работает.

Тип команды, которой я хочу;

somedirectory>myscript inputdata.csv > outputdata.csv 

Вот раздели назад версию сценария Python 2.7.5, который работал, так что вы можете увидеть, что я делаю, (я оставил во все импорте)

import fileinput, math, sys, numpy as np 
from numpy import linspace, loadtxt, ones, convolve 
from optparse import OptionParser 

def main(): 
    parser = OptionParser() 
    options,args = parser.parse_args() 
    try: 
     data = [(line.rstrip()).split(',') for line in fileinput.input(args)] 
    except IOError as detail: 
     print >> sys.stderr, detail 
     sys.exit(2) 

    '''kept these lines in just to make sure the data is in the same format as when it worked before''' 
    t = [float(row[0]) for row in data] 
    m = [float(row[1]) for row in data] 
    result = [[a,b] for a,b in zip(t, m)] 

    for line in result: 
     print >> sys.stdout, str(line[0]) + ',' + str(line[1]) 

options = 0 
if __name__ == "__main__": 
    main() 

Очевидно Принт Теперь функция, осуждается Optparse может быть преобразован к Argparse и т.д.

, так что я думал, что что-то подобное было бы хорошо,

import fileinput, math, sys, inspect, numpy as np 
from numpy import linspace, loadtxt, ones, convolve 
from argparse import ArgumentParser 

def main(): 
    parser = ArgumentParser() 
    options,args = parser.parse_args() 
    try: 
     data = [(line.rstrip()).split(',') for line in fileinput.input(args)] 
    except IOError as detail: 
     print(detail, file=sys.stderr) 
     sys.exit(2) 

    '''kept these lines in just to make sure the data is in the same format as when it worked before''' 
    t = [float(row[0]) for row in data] 
    m = [float(row[1]) for row in data] 
    result = [[a,b] for a,b in zip(t, m)] 

    for line in result: 
     print(str(line[0]) + ',' + str(line[1]), file=sys.stdout) 

options = 0 
if __name__ == "__main__": 
    main() 

Есть, вероятно, некоторые вопиющие проблемы с этим, но после изучения всех элементов, которые я застрял, где именно он ломается.

Кроме того, есть, вероятно, лучшие способы выполнения этого типа чтения и записи csv-файлов, я просто застрял в этом, как знаю. сделал Работа. Например, я знаю о модуле csv, но я не могу найти примеры использования его в пользовательских файлах из командной строки, например, как мне это нужно, все примеры, которые я могу найти, определяют файл, который нужно открыть в самом скрипте.

Заранее спасибо.

ответ

0

Несколько вещей перед кодом. Если вы используете модуль argparse, вы должны указать, что он должен получать имя файла в качестве ввода. Это то, что я сделал с add_argument. Поскольку аргумент не является необязательным, приложение будет завершено, если пользователь не укажет имя файла.

Если пользователь указал имя файла, я пытаюсь его открыть и создать csv-ридер. csv reader - это просто итератор, анализирующий файл, поэтому я могу выполнять итерацию по каждой строке, которую я делаю, и заполнять результирующий список. Когда список заполняется, приложение выполняет итерацию по списку, распечатывая все элементы. try/except есть ли что-то пошло не так.

import io 
import csv 
import argparse 

def main(): 
    # Create the parser 
    parser = argparse.ArgumentParser() 
    parser.add_argument('filename', help='Name of the file you want to load') 
    args = parser.parse_args() 

    result = [] 
    with io.open(args.filename, 'r', encoding='utf-8') as f: 
     reader = csv.reader(f) 
     for row in reader: 
      result.append([row[0], row[1]]) 

    for item in result: 
     print('{0}, {1}'.format(*item)) 

if __name__ == "__main__": 
    try: 
     main() 
    except Exception as e: 
     print('Something went wrong {0}'.format(e)) 
+0

Спасибо, что выглядит очень много больше похоже на то, как это должно быть сделано! Однако я не могу заставить этот код работать. Если я не использую argparse и не изменяю объект в io.open() для определенного имени файла, это работает нормально, но когда я использую, как описано выше, я получаю «ошибка: несколько аргументов» при использовании команды в командной строке в формат, который я дал выше. Он должен работать так же, как и для состояний использования. На самом деле, как бы я ни старался, он, похоже, не распознает входной файл, который я вызываю. Как вы можете вызвать входной файл в команде для этого? – kodasik

+0

Вам не нужно ничего менять, просто сохраните его на 'myscript.py' и назовите его, как вы заявили в своем вопросе:' python myscript.py inputdata.csv> outputdata.csv' –

+0

Спасибо, после некоторых игр о I просто нашел это тоже. Это не совсем то, что я сказал. Со старым кодом я бы сменил каталог на местоположение моего скрипта и csv, 'CD C: \ somedirectory' и набрал команду' myscript inputdata.csv> outputdata.csv'. Теперь мне нужно указать «python» и расширение скрипта python, а не то, что я искал, но по крайней мере теперь он работает! – kodasik

0

Этот main работает, просто изменяя print:

def main(): 
    parser = OptionParser() 
    options,args = parser.parse_args() 
    try: 
     data = [(line.rstrip()).split(',') for line in fileinput.input(args)] 
    except IOError as detail: 
     print(detail, file=sys.stderr) 
     sys.exit(2) 

    '''kept these lines in just to make sure the data is in the same format as when it worked before''' 
    t = [float(row[0]) for row in data] 
    m = [float(row[1]) for row in data] 
    result = [[a,b] for a,b in zip(t, m)] 

    for line in result: 
     print(', '.join(str(x) for x in line), file=sys.stdout) 

Причина вы ничего не получите от 2-ой версии является Отступ sys.exit(2)

except IOError as detail: 
    print(detail, file=sys.stderr) 
sys.exit(2) 

Он выходит, не переходя к нормальному выходу

С поправками к argparse (с учетом 1 или более входных файлов):

def main(): 
    parser = ArgumentParser() 
    parser.add_argument('infiles',nargs='+') 
    args = parser.parse_args() 
    try: 
     data = [(line.rstrip()).split(',') for line in fileinput.input(args.infiles)] 
    except IOError as detail: 
     print(detail, file=sys.stderr) 
     sys.exit(2) 

    '''kept these lines in just to make sure the data is in the same format as when it worked before''' 
    t = [float(row[0]) for row in data] 
    m = [float(row[1]) for row in data] 
    result = [[a,b] for a,b in zip(t, m)] 

    for line in result: 
     print(', '.join(str(x) for x in line)) 

Или вы можете позволить argparse уход тейк открытия файла (ов) (и возникновения ошибки при необходимости):

import argparse 
def main(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument('infiles',nargs='+', type=argparse.FileType('r')) 
    args = parser.parse_args() 
    data = [row for file in args.infile for row in csv.reader(file)] 

    '''kept these lines in just to make sure the data is in the same format as when it worked before''' 
    t = [float(row[0]) for row in data] 
    m = [float(row[1]) for row in data] 
    result = [[a,b] for a,b in zip(t, m)] 

    for line in result: 
     print(', '.join(str(x) for x in line)) 

FileType также признает '-' в stdin (или для ('w') файла, stdout)

+0

Извините, с sys.exit (2) это всего лишь ошибка в форматировании в моем вопросе, это правильно в фактическом скрипте, который я запускал. Спасибо за ответ, хотя, как и в моем ответе Виктору, они все еще не работают, скорее всего, что-то не в порядке с моим концом!Если я использую первую версию main(), скрипт просто зависает и не выходит. Если я использую второй, я получаю тот же «_error: too few arguments_», как и с ответом Виктора (проблемы здесь должны быть чем-то связаны с argparse). С третьим странным я получаю «_NameError: глобальное имя« argparse »не определено_»! – kodasik

+0

'global name 'argparse' не определен' просто означает, что' argparse' не был импортирован. Я переключился на 'argparse.ArgumentParser', потому что я также использовал' argparse.FileType'. – hpaulj

+0

Иногда я добавляю 'print sys.argv', чтобы видеть строки, с которыми работает' argparse'. Обычно это должно быть '['scriptname.py', 'arg1', 'arg2', ...]. 'argparse' использует' sys.argv [1:] ', все, кроме 1-го. 'sys.argv [0]' используется как значение 'prog' по умолчанию (в сообщении об использовании). – hpaulj

Смежные вопросы