2017-05-30 81 views
-1

我在编程竞赛中(我不知道为什么,我几乎不知道任何高级Python),因为我的老师认为这是一个好主意。其中一个练习项目是创建一个包含6个函数的字符串编辑器,分别是Insert,Delete,Reverse,Update/Replace,Append和Prepend一个字符串。对于输入的语法应该是这样的:Python字符串编辑器

computer I 3 BIT 

comper 

输出所以第一部分是编辑字符串,第二个是操作(I可以进行插入,为d删除,R表示反向等)。问题是,其余的东西是不同的。对于I,D和R,共有4个部分。第三是操作的起点。第四个是为I插入的字符串,以及为D删除的字符数,R可以处理的字符数。但是,更新/替换包含5个部分。字符串,修饰符(U),开始位置,要替换的字符数以及要替换的子字符串。

同样,Append和Prepend有3个部分。原始字符串,修饰符(A或P)以及要添加或附加的子字符串。

到目前为止,我已经拿出下面的代码。

while True: 
    Full_String = input("Please enter a string, modifier, start character, and iteration modifier: ") 
    string, modifier, start, itermod = Full_String.split (" ") 
    print (string) 
    print (modifier) 
    print (start) 
    print (itermod) 

打印命令只是为了确保字符串正确拆分。然而,每当我尝试使用某些操作所需的3或5个参数时,我会得到一个ValueError。通常,我可以添加Try-Except块来捕获错误,但我无法弄清楚如何在没有2级用户输入的情况下执行此操作。

那么,无论如何,我该如何设法将这个问题归结为一行输入?对于每个输入应类似于以下:

插入:字符串I 2新

删除:字符串d 2 3

反向:字符串R 2 3

更新/替换:字符串ù 2 3个新(字符串的长度必须是不管以前的说法是,即3个新的,4日消息,5大)

附加:字符串的新

Prepen d:字符串P新

任何帮助都非常感谢。

+0

使用拆分,但将结果保留在单个列表中:'result = Full_String.split(“”)'。然后,你可以参考'result [3]'和'result [4]'等,这取决于result [0]的值。 –

+0

你需要看看*加星号的表达*。 –

+0

通常,在你的问题中追加堆栈跟踪(这种情况下的ValueError)是有帮助的 – rinderwahn

回答

0

如果我想要干净的代码,我会亲自解决这个问题,如:

full_string = input("Please enter a string, modifier, start character, and iteration modifier:") 
command = full_string.strip().split() # doesn't care about amount of whitespace used 

if command[1] == 'I': 
    # insert specific instructions 
    string, _, start, itermod = command 
    ... 
... 
elif command[1] == 'R': 
    # replace specific 
    string, _, index1, index2, new_string = command 
... 

制作,每串指令的情况下。

可以或许也可以使用如在注释中描述的星号的语法:

string, command, *args = full_string.split(" ") # args is now a list of arguments 

但在python2这不会工作

更新:由布鲁诺desthuilliers指出,理想情况下你会使用每种情况下的功能。虽然我个人更喜欢避免会导致额外复杂性的构造(如dictionairies /函数指针)。

如果要使用额外的功能,我可能会做这样的自己:

def do_insert(string, start, itermod): 
    ... program logic ... 

def do_update(string, index1, index2, replacement): 
    ... program logic ... 

... 

while True: 
    full_string = input("Please enter a string, modifier, start character, and iteration modifier:") 

    # doesn't care about amount of whitespace used 
    command = full_string.strip().split() 

    # split the command into string, modifier and additional variable args 
    string, modifier, extra_args = command[0], command[1], command[2:] 

    if modifier == 'I': 
     do_insert(string, *extra_args) 
    elif modifier == 'D': 
     do_delete(string, *extra_args) 
    elif modifier == 'U': 
     do_update(string, *extra_args) 
    ... 

这里的*extra_args将插入的extra_args的元素作为参数。 例如调用func(a, b, *[1,2,3])将被转换为func(a, b, 1, 2, 3)

+1

“干净的”代码会抽象出参数解析,因此主循环不必关心它。事实上,明星语法不适用于Python 2. –

+0

我同意理想情况下,应该使用方法。虽然我觉得这个目标相对简单,但更简单的设置会更好,尤其是如果你只是一个初学者。虽然优雅,但您的解决方案可能有点复杂。 –

+0

“方法”(以及类等)不是唯一可用的抽象...只是使用基本的东西(函数,字典,列表,元组),你已经可以使主循环完全通用的Wrt /操作特性,参考我的答案。 –

0

输入内容以及应如何解析取决于命令,所以你应该有每个命令一个解析器。为此,可以使用一个字典映射命令做(“I”,“d”,“R”等)的解析器功能:

def parse_insert(args): 
    # code to parse arguments for an insert 
    return { 
     "start": args[0], 
     "itermod": args[1] 
    } 



def parse_delete(args): 
    # code to parse argumenst for a delete 
    # cf example above 

# etc 

PARSERS = { 
    "I" : parse_insert, 
    "D" : parse_delete, 
    # etc 
} 


def main(): 
    while True: 
     full_string = input("Please enter a string, modifier, start character, and iteration modifier: ") 
     parts = full_string.split (" ") 
     line = parts[0] 
     parser = PARSERS[parts[1]] 
     op_args = parser(parts[2:]) 

你可能需要操作类似,即:

def do_delete(line, start, itermod): 
    # code here 


def do_insert(line, ....) 
    # idem 


OPERATIONS = { 
    "D" : do_delete, 
    "I": do_insert, 
    # etc 
} 



def main(): 
    while True: 
     full_string = input("Please enter a string, modifier, start character, and iteration modifier: ") 
     parts = full_string.split (" ") 
     line = parts[0] 
     opid = parts[1] 
     parser = PARSERS[opid] 
     op_args = parser(parts[2:]) 
     print(line, opid, op_args) 
     op = OPERATORS[opid] 
     result = op(line, **op_args) 
     print(result) 

这仍然需要一些错误处理,但这应该让你开始。

0

让我们来解决你的分裂问题,你可以自己编写剩余的程序。 split()需要第二个参数来告诉它可能会分裂多少次。你的编辑命令有三个固定的参数,其次是不同的东西。所以,你可以分成最多三个部分,检查命令,并继续酌情:

string, cmd, rest = full_string.split(" ", 2) 
if cmd == "I": 
    start, toinsert = rest.split(" ", 1) # `toinsert` string could contain spaces? 
elif cmd == "R": 
    <etc.> 

或者,你可以收集可变长度部分到一个列表,稍后解释。但是,如果允许插入的字符串包含空格,这是非理想的,因为它们会在字符串中造成额外的中断。

string, cmd, start, *rest = full_string.split() 

这里,rest变得与额外的参数(如果有的话)的列表,并且可以基于命令再次重新分配。

if cmd == "I": 
    toinsert = rest[0] 
elif cmd == "R": 
    <etc.>