2012-04-22 2 views
0

У меня вопрос о кодировании в python для домашнего задания, но прежде всего мне нужно упомянуть, что я никогда раньше не кодировал на python. Предполагается, что назначение будет использоваться нами для основы, поэтому заблаговременно извиняемся за недостаток знаний (и действительно длинный пост).Изменение программ python (python 2.7)

Наша работа состоит в том, чтобы изменить файл randline.py (данное здесь, в своей оригинальностью):

import random, sys 
from optparse import OptionParser 

class randline: 
    def __init__(self, filename): 
     f = open(filename, 'r') 
     self.lines = f.readlines() 
     f.close() 

    def chooseline(self): 
     return random.choice(self.lines) 

def main(): 
    version_msg = "%prog 2.0" 
    usage_msg = """%prog [OPTION]... FILE 

Output randomly selected lines from FILE.""" 

    parser = OptionParser(version=version_msg, 
          usage=usage_msg) 
    parser.add_option("-n", "--numlines", 
         action="store", dest="numlines", default=1, 
         help="output NUMLINES lines (default 1)") 
    options, args = parser.parse_args(sys.argv[1:]) 

    try: 
     numlines = int(options.numlines) 
    except: 
     parser.error("invalid NUMLINES: {0}". 
        format(options.numlines)) 
    if numlines < 0: 
     parser.error("negative count: {0}". 
        format(numlines)) 
    if len(args) != 1: 
     parser.error("wrong number of operands") 
    input_file = args[0] 

    try: 
     generator = randline(input_file) 
     for index in range(numlines): 
      sys.stdout.write(generator.chooseline()) 
    except IOError as (errno, strerror): 
     parser.error("I/O error({0}): {1}". 
        format(errno, strerror)) 

if __name__ == "__main__": 
    main() 

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

И я также должен добавить новые параметры. У меня есть уникальная работа, но другой вариант, который я должен сделать, это без замены, что делает его так, что каждая выходная строка появляется только при максимальном количестве раз, когда она появилась как вход (если мы не используем -u опция, единственный раз, когда вывод может быть дубликатом, если он был дубликат во входном файле для начала). Я знаю, что мой метод ошибочен, так как наборы автоматически избавляются от всех дубликатов, и я только хочу, чтобы выходные строки записывались без замены. Но я понятия не имею, что еще я могу использовать.

import random, sys, string 
from optparse import OptionParser 

version_msg = "%prog 2.0" 
usage_msg = """%prog [OPTION]... FILE 

Output randomly selected lines from FILE""" 
parser = OptionParser(version=version_msg, 
         usage=usage_msg) 
parser.add_option("-n", "--numlines", 
        action="store", dest="numlines", default=1, 
        help="output NUMLINES lines (default 1)") 
parser.add_option("-u", "--unique", action="store_true", 
        dest="unique", default=False, 
        help="ignores duplicate lines in a file") 
parser.add_option("-w", "--without-replacement", action="store_true", 
        dest="without", default=False, 
        help="prints lines without replacement") 
options, args = parser.parse_args(sys.argv[1:]) 

without = bool(options.without) 
unique = bool(options.unique) 
try: 
    numlines = int(options.numlines) 
except: 
    parser.error("invalid NUMLINES: {0}". 
     format(options.numlines)) 

def main(): 
    if numlines < 0: 
     parser.error("negative count: {0}". 
        format(numlines)) 

    ##Here is one of the major changes 
    input_file = args[0] 
    count = 0 
    while (count < len(args)-1): 
     input_file = input_file + '\n' + args[count + 1] 
     count = count + 1 

    ##And here 
    try: 
     generator = randline(input_file) 
     for index in range(numlines): 
      if options.without: 
       line = generator.chooseline() 
       if line not in no_repeat: 
        sys.stdout.write(line) 
        no_repeat.add(line) 
      else: 
       sys.stdout.write(generator.chooseline()) 
    except IOError as (errno, strerror): 
     parser.error("I/O error({0}): {1}". 
        format(errno, strerror)) 

class randline: 
    def __init__(self, filename): 
    if unique: 
     uniquelines = set(open(filename).readlines()) 
     f = open(filename, 'w').writelines(set(uniquelines)) 
     f = open(filename, 'r') 
    if without: 
     countlines = len(f.readlines()) 
     if (countlines < numlines): 
     parser.error("too few lines in input". 
       format(without)) 
     self.lines = f.readlines() 
     f.close() 

    def chooseline(self): 
     return random.choice(self.lines) 

if __name__ == "__main__": 
    main() 

Резюмируя, я не могу заставить его прочитать несколько файлов должным образом (в то же время обрабатывать все файлы в один длинный файл) и вариант без замены, не будет правильно работать.

EDIT: Ах, я понял, так как передал имена файлов в списке аргументов, поэтому, даже если они только текстовые файлы, они не рассматриваются как строки. Я пытался изменить его, но он по-прежнему не работает именно:

input_file = args[0] 
count = 0 
content = open(args[0]).read() 
while (count < len(args) - 1): 
content = content + open(args[count + 1]).read() 
    count = count + 1 
open(input_file, 'wb').write(content) 
try: 
    generator = randline(input_file) 

Он продолжает добавлять дополнительный символ новой строки между двумя файлами. Я хочу, чтобы файлы соединялись по строкам, но я получаю пустую строку между тем, где заканчивается первый файл, а второй начинается.

EDIT 2.0: О, подождите, понял. Упс. Мне просто нужна помощь без опции замены. Думаю, я должен разделить его по строкам и сохранить его в списке, чтобы каждый раз проверять его? Есть ли более эффективный способ (только с использованием модулей, которые я уже написал, мы не можем ничего использовать)

+1

Рефактор сначала, * затем * дополнение. –

+0

Я бы посмотрел на 'цепочку' из' itertools' –

+0

К сожалению, единственными модулями, которые мне разрешено использовать, являются те, которые заданы, и строка. –

ответ

2

Прежде всего, вам необходимо прочитать первый входной файл. Поэтому вам нужно открыть() первый файл ввода, который вы читаете. Чтобы добавить новую строку, измените цикл while, чтобы проверить, имеет ли файл (после того, как вы откроете() он), в конце появится новая строка, а если нет, поместите его туда.

Чтобы реализовать вариант без замены, вам необходимо каким-то образом проверить, действительно ли вы прочитали строку. Для того, чтобы разделить файл вы читали в линиях, просто используйте

input.split('\n') 

Вашего randline конструктор становится передается содержимое файлов, так что он пытается сделать в конструкторе не имеет смысла.

Извините, если этот ответ не имеет смысла; Я прошел и попытался указать на разные вещи, которые вам нужно исправить. Я не могу комментировать вещи, потому что у меня нет репутации, поэтому я должен отправить ответ:. Позвольте мне знать, если это помогает!

Чтобы сделать без замены, я бы сделал словарь, который содержит строки как ключи, так и ints как значения. Перебирайте все входные тексты и каждый раз, когда вы видите строку, добавьте ее в словарь и добавьте связанное целое число. Затем, когда вы вызываете chooseline, проверьте, чтобы значение в словаре для строки, полученной вами от выбора случайной строки, больше 0. Если это так, уменьшите связанное значение и затем верните выбранную вами строку. В противном случае выберите новую строку.


Ответить Edit 2,0: Вы можете сделать это. Затем, каждый раз, когда вы выбираете случайную строку, вы удаляете ее из списка. Думаю, это сработает.

+0

Да, я забыл, что это был файл, а не строка на секунду. У меня такой фиксированный (за исключением дополнительной строки). Что касается без замены, я думаю, что я мог бы разбить вход и сохранить его в списке и использовать функцию count для проверки каждой строки, которую я пытаюсь вывести. –

+0

О, doi. Словарь тоже будет работать. Спасибо, однако, это большая помощь. –

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