2012-04-22 60 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() 

综上所述,我不能让它正确读取多个文件(同时还处理所有的文件作为一个长文件),并且没有替代选项不正确工作的。

编辑︰啊,我意识到,因为我是在参数列表中传递文件名,所以即使他们只是文本文件,他们不被视为字符串。我试图改变它,但它仍然无法确切地工作:

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) 

它不断添加这两个文件之间额外的换行符。我想要逐行连接的文件,但在第一个文件结束和第二个文件开始之间出现空行。

编辑2.0:哦,等等,明白了。哎呦。我只需要无替换选项的帮助。我想我应该逐行将它分开并将其存储在列表中以检查每次?有没有更高效的方法(只使用我已经编写的模块,我们不能使用其他任何东西)

+1

先重构*,然后*扩充。 – 2012-04-22 03:06:32

+0

我会从'itertools'看'chain' – 2012-04-22 03:23:20

+0

不幸的是,我允许使用的唯一模块是给定的和字符串。 – 2012-04-22 03:43:03

回答

2

首先,你需要读取第一个输入文件。所以你需要打开()你读的第一个输入文件。 要添加换行符,请修改while循环以检查文件(在打开()它)后是否在最后有一个新行,如果没有,则将其放在那里。

为了实现无替换选项,您需要一些方法来检查您是否已经读取了一行。为了分割你的线读取一个文件,只是使用

input.split('\n') 

你randline构造函数获得通过的文件的内容,所以它正试图在构造函数中做没有意义。

对不起,如果这个答案似乎没有道理;我已经通过并试图指出你需要修复的不同事情。我不能评论这些东西,因为我没有名誉,所以我必须发表一个答案:。让我知道如果这有帮助!


不做替换,我会做一个字典,保存字符串作为键,并作为值整数。遍历所有输入文本,并且每次看到一行时,将它添加到字典中并递增相关的整数。然后,当您调用chooseline时,请检查并确保字典中您从拾取随机行获得的字符串值大于0.如果是,则减小相关值,然后返回您选择的字符串。否则,请选择一个新行。


回复编辑2.0: 您可以这样做。然后,每次你选择一个随机线,你从列表中删除它。我认为这会奏效。

+0

是的,我忘了它是一个文件,而不是一秒钟的字符串。我有那种固定的(除了额外的换行符)。至于没有更换,我想我可以拆分输入并将其存储在一个列表中,并使用计数函数来检查我尝试输出的每一行。 – 2012-04-22 04:07:52

+0

哦,doi。字典会工作太过于。不过谢谢,这有很多帮助。 – 2012-04-22 04:40:14