基于标准形式的两个笛卡尔坐标打印线函数

时间:2018-04-21 21:34:07

标签: python geometry

几天前我接受了一次采访,遇到了以下问题。虽然我确实解决了它,但我想知道如何改进我的Python代码以使其成为pythonic并增强可读性,或者是否有任何边缘情况我没有检查。任何建议将不胜感激!

  

编写一个Python程序,它采用2个笛卡尔坐标并以标准形式输出一条线(Ax + By = C)。   请评论代码并确保符合PEP-8(最好使用库)。

我的解决方案:

import re  # used to check whether the input is a valid number
import sys  # used to read input from command line arguments


def process_input():
    """Process the input from command line arguments
    Args:
        None
    Returns:
        list: the return value. Empty list indicates
        the number of arguments is not four or all input
        are not valid numbers. Non-empty list contains
        the valid input numbers.
    """
    patternobj = re.compile(r'^-?\d+\.?\d*$')  # regex pattern object
    if len(sys.argv[1:]) == 4:  # input should have four arguments
        input = [float(num) for num in sys.argv[1:]
                 if patternobj.match(num)]  # string to float
    else:  # arguments doesn't have four arguments then return empty list
        return []
    return input


def standard_form(input: list):
    """Print the line function in standard form
    Args:
        param1: a list contains the coordinates information
    Returns:
        string: the return value. The string contains
        the line function in standard form or error
        message.
    """
    if len(input) != 4:  # the length of list should be 4 otherwise is invalid
        return 'Error: Invalid input format'

    [x1, y1, x2, y2] = input

    if x1 == x2 == y1 == y2:  # edge case 1: two same points
        return 'Error: Two equal coordinates'
    elif x1 == x2:  # edge case 2: the slope is infinite
        return 'x=' + str(int(x1) if x1.is_integer() else round(x1, 2))
    elif y1 == y2:  # edge case 3: the slope is 0
        return 'y=' + str(int(y1) if y1.is_integer() else round(y1, 2))

    A = y2 - y1  # get the value of A
    if A == 1:  # if A equals 1
        A = ''  # should not print 1
    elif A == -1:  # if A equals -1
        A = '-'  # should print a minus sign
    else:
        # to string and if it is integer convert to int
        A = str(int(A) if A.is_integer() else round(A, 2))

    B = x1 - x2  # get the value of B
    if B == 1:  # if B equals 1
        B = '+'  # should not print 1 but add a + sign
    elif B == -1:  # if B equals -1
        B = '-'  # should not print -1 but add a - sign
    else:
        if B > 0:  # if B is positive
            # to string and if it is integer convert to int
            B = '+' + str(int(B) if B.is_integer() else round(B, 2))
        else:
            # to string and if it is integer convert to int
            B = '-' + str(int(-B) if B.is_integer() else round(-B, 2))

    C = (x1 - x2) * y1 + (y2 - y1) * x1  # get the value of C
    # to string and if is integer convert to int
    C = str(int(C) if C.is_integer() else round(C, 2))
    return A + 'x' + B + 'y=' + C


def main():
    input = process_input()
    print(standard_form(input))


if __name__ == '__main__':
    main()

要使用它,您应该输入

python3 line.py 3 4 5 6

输出:

2x-2y=-2

另外,有没有更好的方法来处理参数?上面的方法有效,但我觉得它不是很优雅。

1 个答案:

答案 0 :(得分:0)

应该去代码审查,但我无法帮助自己。

Regexp可以使代码难以阅读。为什么不只是try呢?

def process_input():
    """
    Process the input from command line arguments
    return a list if the input is valid
    otherwise return a string indicates the input is invalid
    """
    if len(sys.argv[1:]) == 4:  # input should have four arguments
        try:                    # Try converting them all to float
            input_float = [float(x) for x in sys.argv[1:]]
            return input_float  # Return floats if successful
        except: pass    # else just pass to the final return statement
    return 'Error: Invalid input format'