python - 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()
非常感谢任何帮助。
解决方案
if new_splitted_eq[index+2] == new_splitted_eq[-1]:
如果您之前不检查索引,您正在访问的列表将始终超出范围。例如,如果您的列表有 1 个项目,但您尝试访问第三个元素,您会收到错误消息。
由于您编辑了代码以反映我的答案中的更正,第二个问题是您使用final_result += new_splitted_eq[index-1]
了两次,一次在 new 之前if else
,一次在 else 分支内,这就是您在计算中得到错误结果的原因。
推荐阅读
- reactjs - 扩展airbnb时如何在eslint中启用绝对导入?
- android - 使用导航组件通过后退按钮向上导航
- excel - vba - 如何根据找到定义的变量的次数进行编码
- python - 自 Spyder 升级以来 Python 崩溃
- rsync - Rsync 复制“不安全”的符号链接,但不更新符号链接目标的修改时间
- ios - 将类名称添加到视图控制器时 Segue 不起作用
- ios - 导航栏上的搜索栏未在 viewdidload() 上显示
- excel - 将大量数据从多个范围移动到列的 Excel VBA 代码
- c# - 在 asp.net 核心中的控制器测试期间停止保存 Guid.Empty
- angular - 当我滚动图表时阻止滚动事件滚动整个页面