I am trying to send a POST request to my Django backend ie djangorestframework, rest api, and I am trying to get the data from this request and make some computation and send it back to the client.
I get this error:
File "/Users/lambdainsphere/seminar/backend/seminar/api/evaluator.py", line 12, in evaluate operand, op, operand2 = exp ValueError: too many values to unpack (expected 3)
Here's my view:
@api_view(['POST'])
def compute_linear_algebra_expression(request):
"""
Given a Linear Algebra expression this view evaluates it.
@param request: Http POST request
@return: linear algbera expression
"""
serializer = LinearAlgebraSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
data = serializer.data
algebra_expr = data['expression']
#algebra_expr = tuple(algebra_expr)
print(algebra_expr)
algebra_expr = evaluate(algebra_expr)
return Response({"expression":algebra_expr}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
here is my evaluator: it consumes a python3 tuple:
def evaluate(exp):
"""
Evaluate a Linea Algebra expression.
"""
operand, op, operand2 = exp
if isinstance(operand, Vec) and op == ' ' and isinstance(operand2, Vec):
return operand operand2
elif isinstance(operand, Vec) and op == '-' and isinstance(operand2, Vec):
return operand - operand2
elif isinstance(operand, Vec) and op == '*' and isinstance(operand2, Vec):
return operand * operand2
elif isinstance(operand, Vec) and op == '*' and isinstance(operand2, int):
return operand * operand2
elif isinstance(operand, Matrix) and op == ' ' and isinstance(operand2, Matrix):
return operand operand2
elif isinstance(operand, Matrix) and op == '-' and isinstance(operand2, Matrix):
return operand - operand2
elif isinstance(operand, Matrix) and op == '*' and isinstance(operand2, int):
return operand * operand2
elif isinstance(operand, Matrix) and op == '*' and isinstance(operand2, Matrix):
return operand operand2
else:
raise ValueError("{} is not type Vec or type Matrix.".format(operand))
if I write my view like this everything works as expected minus the computation I want to make.
@api_view(['POST'])
def compute_linear_algebra_expression(request):
"""
Given a Linear Algebra expression this view evaluates it.
@param request: Http POST request
@return: linear algbera expression
"""
serializer = LinearAlgebraSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serialized.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
CodePudding user response:
The error occurs at the line operand, op, operand2 = exp
in the evaluate
function.
You assumed that the exp
is the tuple with 3 elements, but it seems to me that actually it's not.
You need to check the length of the tuple first using the command print(len(exp)
.
CodePudding user response:
So, after some investigation I was able to solve it.
I added the following code and I was able to see how the data looked like:
def evaluate(exp):
"""
Evaluate a Linea Algebra expression.
"""
if isinstance(exp, tuple):
if len(exp) == 3:
operand, op, operand2 = exp
else:
raise ValueError("tuple {} is not of size 3.".format(exp))
else:
raise ValueError("{} in not a tuple.".format(exp))
if isinstance(operand, Vec) and op == ' ' and isinstance(operand2, Vec):
return operand operand2
...
in my view (see above) I have this:
if serializer.is_valid():
serializer.save()
data = serializer.data
algebra_expr = data['expression']
algebra_expr = tuple(algebra_expr)
well it turns out that tuple
was dividing the input into characters separated by commas; hence the error.
so I solved it by:
if serializer.is_valid():
serializer.save()
data = serializer.data
algebra_expr = data['expression']
algebra_expr = eval(algebra_expr)
algebra_expr = evaluate(algebra_expr)
notice the eval
call. that solved it.