0

我有一个关于在 python 中编写家庭作业的问题,但我需要首先提到我以前从未使用 python 编写过代码。该作业应该让我们习惯基础知识,所以提前为缺乏知识(以及很长的帖子)道歉。

我们的工作是修改 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:哦,等等,明白了。哎呀。我只需要关于无替换选项的帮助。我想我应该逐行拆分并将其存储在列表中以便每次检查?有没有更高效的方法(只用我已经写好的模块,别的什么都不能用)

4

1 回答 1

2

首先,您需要读取第一个输入文件。因此,您还需要 open() 您读取的第一个输入文件。要添加换行符,请修改 while 循环以检查文件(在您 open() 之后)是否在末尾有一个新行,如果没有,则放一个。

为了实现无替换选项,您需要一些方法来检查您是否已经阅读了一行。为了按行拆分您读入的文件,只需使用

input.split('\n')

您的 randline 构造函数正在传递文件的内容,因此它在构造函数中尝试执行的操作没有意义。

对不起,如果这个答案似乎没有意义;我已经经历过并试图指出您需要解决的不同问题。我不能对东西发表评论,因为我没有声誉,所以我必须发布一个答案:。让我知道这是否有帮助!


如果没有替换,我会制作一个字典,将字符串作为键,将整数作为值。循环遍历所有输入文本,每次看到一行时,将其添加到字典中并增加相关的整数。然后,当您调用 chooseline 时,检查以确保您从随机行中获得的字符串的字典中的值大于 0。如果是,则减少相关值,然后返回您选择的字符串。否则,选择一个新行。


回复编辑 2.0:你可以这样做。然后,每次选择随机行时,都会将其从列表中删除。我认为那会奏效。

于 2012-04-22T04:04:23.263 回答