Máy tính python cơ bản

Oct 20 2020

Tôi có một người bạn trẻ đang bắt đầu học Python ở trường và nhờ tôi giao cho anh ấy một bài tập nhỏ. Tôi không phải là giáo viên hay chuyên gia về Python, nhưng tôi đã chấp nhận.

Lúc đầu, tôi nghĩ sẽ rất thú vị nếu bắt đầu với một chút phân tích cú pháp cho đầu vào của hoạt động, như:

Enter your operation : 3+3

Nhưng nó có vẻ hơi quá sức đối với anh ấy vì vậy chúng tôi đồng ý tách nó thành ba phần (số đầu tiên, toán hạng và số thứ hai).

Tôi đã chỉnh sửa một chút nhưng tôi thấy nó còn vụng về và mục đích của bài tập là chỉ cho anh ấy một số cách thực hành tốt.

Đây là mã của tôi:

calculate = True
while calculate:
    try:
        number1 = float(input("Enter the first number : "))
    except ValueError:
            print("Incorrect value")
            exit()
    symbol = input("Enter the operation symbol (+,-,/,*,%) : ")
    try:
        number2 = float(input("Enter the second number : "))
    except ValueError:
            print("Incorrect value")
            exit()
    operande = ["+", "-", "*", "/", "%"]
    resSentence = "Result of operation \"{} {} {}\" is :".format(number1, symbol, number2)
    if symbol not in operande:
        print("Incorrect symbol")
    elif symbol == "+":
        print(resSentence, number1 + number2)
    elif symbol == "-":
        print(resSentence, number1 - number2)
    elif symbol == "*":
        print(resSentence, number1 * number2)
    elif symbol == "/":
        print(resSentence, number1 / number2)
    elif symbol == "%":
        print(resSentence, number1 % number2)
    restart = input("Do you want to do another calcul (Y/n) ? ")
    while restart.lower() != "y" and restart.lower() != "n":
        print(restart.lower(), restart.lower(), restart.lower()=="n")
        restart = input("Please, enter \"y\" to continue or \"n\" to exit the program : ")
    if restart.lower() == "n":
        calculate = False

Tôi đã muốn thực hiện một vòng lặp khi number1hoặc number2không hợp lệ floatcho đến khi người dùng nhập một giá trị hợp lệ, nhưng tôi không tìm thấy một cách rõ ràng để làm điều đó. Tôi sẵn lòng chấp nhận lời khuyên về điều này (mặc dù tôi biết đây không phải là câu hỏi cho Stack Exchange này, một cách tốt của Pythonic để làm điều này sẽ rất tuyệt :)).

Trả lời

9 AryanParekh Oct 21 2020 at 04:59

Sử dụng nhiều chức năng hơn

Bạn có một hàm calculate(), nhưng nếu bạn thấy nó làm được nhiều việc hơn là chỉ tính toán, thì điều này khiến mã của bạn trông khó hiểu một cách vô lý. Nhưng có một giải pháp rất đơn giản, hãy sử dụng nhiều chức năng hơn. Điều gì sẽ xảy ra nếu vòng lặp chính của bạn có thể trông như thế nào

while True:
    number1,number2,operand = take_input()
    result = calculate(number1,number2,operand)
    print(f"Answer : {numebr1} {operand} {number2} = {result}")
    if input("Do you want to play again? (y/n): ").lower() == 'n':
        break 

Điều này giúp bạn dễ dàng duy trì chương trình của mình hơn.

continue khi có lỗi

try:
    number1 = float(input("Enter the first number : "))
except ValueError:
        print("Incorrect value")
        exit()

Hãy tự hỏi mình, tại sao một chương trình sẽ kết thúc nếu người dùng nhập đầu vào không hợp lệ? Hãy cho anh ấy một cơ hội khác xD

Duy trì thụt lề nhất quán

try:
    number2 = float(input("Enter the second number : "))
except ValueError:
            print("Incorrect value")
            exit()

Cố gắng duy trì thụt lề nhất quán, vì bạn đã sử dụng 4khoảng trắng trước đó, không có lý do chính đáng để sử dụng 8sau này, nó có thể chỉ gây nhầm lẫn cho những người đọc mã sau này.

Mã logic 1

Hãy xem xét đầu vào mẫu này

Enter the first number : 1
Enter the operation symbol (+,-,/,*,%) : I like python
Enter the second number : 2
Incorrect symbol

Rõ ràng symbollà sai. Tại sao tôi phải nhập số thứ hai, chỉ để phát hiện ra tôi đã nhập sai khi nhập symbol? Đáng lẽ nó phải cho tôi biết ngay rằng ký hiệu của tôi không chính xác, vì vậy tôi có thể sửa nó.

Chỉ cần di chuyển if symbol not in operandscâu lệnh để nó nằm ngay bên cạnh đầu vào.

eval

Đánh giá bằng Python

Đây sẽ là cải tiến lớn nhất trong chương trình của bạn, vì nó chuyển đổi khoảng 10-15 dòng mã thành một dòng.

Các eval()chức năng đánh giá sự biểu hiện cụ thể, nếu biểu thức là một tuyên bố Python pháp lý, nó sẽ được thực thi.

Nghe có vẻ quen thuộc, về cơ bản chúng ta không đánh giá các biểu thức đơn giản sao?

Sử dụng eval, phần tính toán của bạn sẽ giống như

result = eval(f"{number1}{operand}{number2}")

Thí dụ, number1 = 5,number2 = 10, operand = '+'

Đây là những gì cơ bản đang xảy ra

result = eval("5+10")

Sau cùng

Đây là mã với những cải tiến

def take_input():
    err_msg = "Invalid input"
    operands = ['+','-','*','/','%']
    try:
        num1 = float(input("Enter number 1: "))
    except Exception:
        print(err_msg)
        return take_input()
    try:
        num2 = float(input("Enter number 2: "))
    except Exception:
        print(err_msg)
        return take_input()

    print("Operands: " + ', '.join(x for x in operands))
    try:
        operand = input("Enter operand: ")
    except Exception:
        print(err_msg)
        return take_input()

    if operand not in operands:
        print(err_msg)
        return take_input()

    return num1,num2,operand

def calculate(num1,num2,operand):
    return eval(f"{num1}{operand}{num2}")


def mainloop():
    while True:
        num1,num2,operand = take_input()
        result = calculate(num1,num2,operand)
        print(f"Answer: {result}")
        if input("Do you want to play again? (y/n): ").lower() == 'n':
            break

mainloop()
5 Deep_Thoughts Oct 20 2020 at 21:54

Đây là một giải pháp thay thế cho mã của bạn, nó phức tạp hơn một chút nhưng cũng dễ đọc hơn. Tôi đã quản lý để làm điều vòng lặp nhưng nó là loại khó theo dõi. Lấy làm tiếc.

running = True
# Break Things up into functions each function does one single thing

def calculate(inputOne, operand, inputTwo):
    """
    Calculates inputOne operand and inputTwo
    """

    if operand == "+":
        return inputOne + inputTwo
    elif operand == "-":
        return inputOne - inputTwo
    elif operand == "*":
        return inputOne * inputTwo
    elif operand == "/":
        return inputOne / inputTwo
    elif operand == "%":
        return inputOne % inputTwo

def askInput():
    """
    Asks for a number until a number is given checks if each one is valid
    """

    isValid = [False, False, False] # none of the numbers are validated yet
    number1, symbol, number2 = ["", "", ""]
    
    # Here is a good implementation of the loop, it is kind of complex though
    while True:
        try:
            if not isValid[0]: # Asks for number1 if it is not valid
                number1 = int(input("Enter the first number : "))
                isValid[0] = True

            if not isValid[1]: # This is added functionality because there was a loophole in your program
                symbol = input("Enter the operation symbol (+,-,/,*,%) : ") # use tuples whenever possible
                supportedOperands = ("+", "-", "/", "*", "%")

                if symbol not in supportedOperands:
                    raise ValueError

                isValid[1] = True

            if not isValid[2]: # Asks for number2 if it is not valid
                number2 = int(input("Enter the second number : "))
                isValid[2] = True
            break
        
        except ValueError:
            continue # this just restarts the whole thing
    
    return number1, symbol, number2



def continueApp():
    """
    Checks if the input to restart is valid
    """
    restart = input("Do You want to do another calculation (Y/n) ? ").lower()

    while True:
        if restart == "y":
            return True
        elif restart == "n":
            return False
        else:
            restart = input("Please, enter \"y\" to continue or \"n\" to exit the program : ").lower()

while running:

    numberOne, operand, numberTwo = askInput()
    answer = calculate(numberOne, operand, numberTwo)
    resSentence = f"Result of operation {numberOne} {operand} {numberTwo} is : {answer}"
    print(resSentence)

    if continueApp():
        pass
    else:
        running = False
exit()


Lời khuyên:

  • Chia nhỏ mọi thứ thành các chức năng:

Các hàm chỉ là vùng chứa cho mã có thể được thực thi, các hàm PHẢI làm MỘT và chỉ MỘT điều nữa trên các hàm ở đây .

  • Vui lòng Cố gắng bình luận về mã của bạn, nó giúp bạn đọc và chỉnh sửa dễ dàng hơn.

Chức năng này

def calc():
    x = 1
    y = 12
    return (((x+y)/x)**y)+(3*x+4*y) # Please don't write like this in any case

sẽ tốt hơn nhiều với một lời giải thích hoặc những gì đang xảy ra

def calc():
    """
    Accepts: Nothing
    Does: Adds X and Y, then divides it by X to the power of Y
          then it adds  it to X multiplied by three and 4 multiplied by Y
    Returns: integer (the result of Does) ^^^^^
    """
    x = 1
    y = 12
    return ((x+y)/x**y)+(3*x+4*y) # Again, please don't write code like this
  • Sử dụng chuỗi f (điều này yêu cầu python 3.6 trở lên)

chuỗi f được sử dụng như thế này

value = "12"
print(f"Number {value} is an example of an f string") 

# Versus

print("Number {} is an example of an f string".format(value))
  • Cố gắng giải phóng mã của bạn

Tin tôi đi, điều này làm cho mã của bạn dễ đọc và dễ hiểu hơn.

def calc():
    """
    Accepts: Nothing
    Does: Adds X and Y, then divides it by X to the power of Y
          then it adds  it to X multiplied by three and 4 multiplied by Y
    Returns: integer (the result of Does) ^^^^^
    """
    x = 1
    y = 12
    ans = (x + y) / (x ** y)
    ans += (3 * x) + (4 * y) # just adds ans to the right side of the operator
    return ans