首页 > 解决方案 > localhost上的Python计算器 - 获取结果时出现意外结果

问题描述

我正在尝试制作一个“本地主机计算器”,您可以在其中将任何方程式发送到服务器,然后服务器将返回方程式的结果。现在我只是在服务器程序中打印结果。

问题

我有一个小问题;当我运行程序时,我得到了意想不到的结果。例如:“10 + 45”将计算为“65”,这是不对的。

我有一种感觉,我错过了一些简单的东西。

编码

这是我的代码:

服务器tmServer.py

"""
   This is the server, that hosts the connection between the client
   and the server.
   This server stores the clients math equation, finds out what kind
   of equation it is, and returns back the final answer to the equation.
"""

import socket
import sys

import exceptions as exc

# Socket for creating a connection.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = ''

# Try getting the port from the commandline.
try:
    port = int(sys.argv[1])
except IndexError:
    err = True
else:
    err = False

# If err is True, no argument is provided.
# Raise exception.
if err == True:
    msg = "You can't run this in the main with no port argument!"
    raise exc.RunningInMainFileOrNoArgumentException(msg)

# Host the connection with s.bind()
s.bind((host, port))

# Listen after request for connection
# and if so, accept connection.
s.listen(1)
print("Waiting for connection with client...")
conn, addr = s.accept()
print("Client is at", str(addr))

# Get the raw math equation from client.
client_data = conn.recv(100000)

# Decode the data to string.
decoded_data = client_data.decode()

# Split the lines into understandable characters,
# and make all the numbers integer.
splitted_eq = decoded_data.split(' ')
new_splitted_eq = []
for item in splitted_eq:
    try:
        new_splitted_eq.append(int(item))
    except ValueError:
        # If not a number, just append.
        new_splitted_eq.append(item)

# Use this variable, for knowing when to check for math signs.
last_was_num = False
done = False

final_result = 0
checking_signs = ['+', '-', '*', '/']

# Then, go through the new list.
for index, item in enumerate(new_splitted_eq):
    if type(item) == int:
        # Then it's a number.
        # Set last_was_num to True.
        last_was_num = True
        # Loop back.
        continue
    if last_was_num == True:
        # Check for math signs.
        for sign in checking_signs:
            if item == sign:
                if item == '+':
                    # Just add the last number to the final_result.
                    final_result += new_splitted_eq[index-1]

                    # Check that the index does not exceed the lists boundaries.
                    if index+2 < len(new_splitted_eq):
                        if new_splitted_eq[index+2] == new_splitted_eq[-1]:
                            # Then it's the last number in the list.
                            # Just add it, and break.
                            final_result += new_splitted_eq[index+2]
                            break
                    else:
                        # Then it's the last two numbers.
                        final_result += new_splitted_eq[index-1]
                        final_result += new_splitted_eq[-1]


# Print the final result, for now.
# Next step, is to send it back to the client.

# But there are unexpected outputs, 
# it's plussing the first number in the equation
# at the last iteration, so fx:
# 10 + 45 = 65
print(str(final_result))

客户tmClient.py

"""
   This is the client that is sending the raw math equation
   to the server.
"""

import socket
import sys

import exceptions as exc

# Create socket.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the server via. locahost.
host = '127.0.0.1'

# Try getting the port from the commandline.
try:
    port = int(sys.argv[1])
except IndexError:
    err = True
else:
    err = False

# If err is True, no argument is provided.
# Raise exception.
if err == True:
    msg = "You can't run this in the main or with no port argument!"
    raise exc.RunningInMainFileOrNoArgumentException(msg)

# Ask for connection.
s.connect((host, port))

# Ask for an equation by the user.
equation = input("Write an equation with spaces to seperate: ")

# Send the equation to the server, for evaluation.
s.send(str(equation).encode())

# Read the answer.
i = 0
# Make the final result an empty string.
eq_result = ''

while(True):
    # Ask for the data.
    # Allow the client to read up to 100.000 bytes.
    data = s.recv(100000)
    # To minimize lag, read the output in chunks.
    if i < 5:
        eq_result += str(data.decode())

    # If the output is done;
    # break out of loop.
    if not data:
        break

# Print the equations result.
if eq_result:
    print("The answer to " + equation + " is equal to " + eq_result)
else:
    print("No result has been returned. Please try again later.")

# Finally, terminate the connection with the server.
s.close()

非常感谢任何帮助。

标签: python

解决方案


if new_splitted_eq[index+2] == new_splitted_eq[-1]:如果您之前不检查索引,您正在访问的列表将始终超出范围。例如,如果您的列表有 1 个项目,但您尝试访问第三个元素,您会收到错误消息。

由于您编辑了代码以反映我的答案中的更正,第二个问题是您使用final_result += new_splitted_eq[index-1]了两次,一次在 new 之前if else,一次在 else 分支内,这就是您在计算中得到错误结果的原因。


推荐阅读