复杂字符串块的水平打印

Horizotal print of a complex string block

再次向您征求意见。我正在尝试打印一个复杂的字符串块,它应该如下所示:

  32         1      9999      523
+  8    - 3801    + 9999    -  49
----    ------    ------    -----
  40     -3800     19998      474

我以正确的格式编写了字符排列函数 arrange_printer(),可以重新用于打印列表。这是我的代码现在的样子:

import operator
import sys

def arithmetic_arranger(problems, boolean: bool):
    
    arranged_problems = []
    if len(problems) <= 5:
        for num in range(len(problems)):
            arranged_problems += arrange_printer(problems[num], boolean)
    else:
        sys.exit("Error: Too many problems")

    return print(*arranged_problems, end='    ')


def arrange_printer(oper: str, boolean: bool):

    oper = oper.split()
    ops = {"+": operator.add, "-": operator.sub}
    a = int(oper[0])
    b = int(oper[2])

    if len(oper[0]) > len(oper[2]):
        size = len(oper[0])
    elif len(oper[0]) < len(oper[2]):
        size = len(oper[2])
    else:
        size = len(oper[0])
    
    line = '------'
    ope = '  %*i\n%s %*i\n%s' % (size,a,oper[1],size,b,'------'[0:size+2])

    try:
        res = ops[oper[1]](a,b)
    except:
        sys.exit("Error: Operator must be '+' or '-'.")

    if boolean == True:
        ope = '%s\n%*i' % (ope,size+2, res)

    return ope

arithmetic_arranger(['20 + 300', '1563 - 465 '], True)
#arrange_printer(' 20 + 334 ', True)

遗憾的是,我得到的是这种格式:

      2 0
 +   3 0 0
 - - - - -
     3 2 0     1 5 6 3
 -     4 6 5
 - - - - - -
     1 0 9 8

如果您尝试像最后注释行那样打印 arrange_printer() 的 return,则格式是所需的。

任何改进我的代码或采用良好编码实践的建议都受到欢迎,我开始对 Python 中的编程有所了解。

感谢您的帮助!

我看到的第一个问题是您使用 += 将项目添加到 arranged_problems 列表。字符串是可迭代的。 somelist += someiterable 迭代 someiterable,并将每个元素附加到 somelist。要追加,请使用 somelist.append()

现在,一旦您解决了这个问题,它仍然不会像您期望的那样工作,因为 print() 的工作原理是在光标位置打印您提供的内容。一旦进入新行,就无法返回到上一行,因为光标已经在新行上。之后打印的任何内容都将转到光标所在位置的新行,因此您需要安排多个问题,以便首先打印第一行,然后打印第二行,依此类推。只需修复 append(),您就会得到以下输出:

   20
+ 300
-----
  320   1563
-  465
------
  1098   

你会得到一个字符串,其中 \n 表示每次调用 arrange_printer() 时新行的开始。您可以将此输出分成多行,然后分别处理每一行。

例如:

def arithmetic_arranger(problems, boolean:bool):
    arranged_problems = []
    if len(problems) > 5:
        print("Too many problems")
        return

    for problem in problems:
        # Arrange and split into individual lines
        lines = arrange_printer(problem, boolean).split('\n')
        # Append the list of lines to our main list
        arranged_problems.append(lines)

    # Now, arranged_problems contains one list for each problem.
    # Each list contains individual lines we want to print
    # Use zip() to iterate over all the lists inside arranged_problems simultaneously
    for problems_lines in zip(*arranged_problems):
        # problems_lines is e.g. 
        # ('   20', '  1563')
        # ('+ 300', '-  465') etc
        # Unpack this tuple and print it, separated by spaces.
        print(*problems_lines, sep="    ")

给出输出:

   20      1563
+ 300    -  465
-----    ------
  320      1098

如果您希望每个问题都有不同的行数,那么您可以使用 itertools.zip_longest() 函数而不是 zip()

要将我的所有其他评论集中在一个地方:

  • return print(...) 没什么用。 print() 没有 return 任何东西。 return print(...) 将始终导致您的函数 return None.
  • 不是遍历 range(len(problems)) 并访问 problems[num],而是执行 for problem in problems 然后使用 problem 而不是 problems[num]
  • Debugging 是一项重要的技能,在您的编程生涯中越早学习它,您的生活就会越好。
  • Stepping through your program with a debugger 让你看到每条语句如何影响你的程序,是一个非常宝贵的调试工具