# Ask user to enter an expression and display output
def main():
expression = input("Expression: ")
print(calculate(splitter(expression)))
# Split expression into components and assign to variables as float values
def splitter(expression):
x, y, z = expression.split()
return x, y, z
# Calculate expression result
def calculate(x, y, z):
x, z = float(x), float(z)
if y == "+":
return str(round((x + z), 1))
elif y == "-":
return str(round((x - z), 1))
elif y == "*":
return str(round((x * z), 1))
else:
return str(round((x / z), 1))
main()
I am getting traceback errors for any expression (1 + 1) I enter.
Yeah others have pointer out the error, but I want to really recommend using VSCode with the Python extension and static types. It will make finding these errors super easy because it adds a red underline exactly where the problem is.
Static types means:
def splitter(expression: str) -> tuple[str, str, str]: ... def calculate(x: str, y: str, z: str) -> str:
PyCharm is the way to go to write Python.
Yeah that’s a great option too. Not free though (although the pricing is very reasonable IMO). I think if you’re this much of a beginner it doesn’t make sense to pay for Pycharm.
There’s a !python@programming.dev community more appropriate to python specific questions
print(eval(input(“Expression:”)))
Unsafe coding is best coding ;)
Change this:
print(calculate(splitter(expression)))
to this:
print(calculate(* splitter(expression)))
The error is that
calculate
expects three float values (x
, andy
, andz
), butsplitter
returns a tuple object ((x, y, z)
as one object, similar to arrays in other languages):>>> type(splitter("1 + 2")) <class 'tuple'>
Prepending a tuple or a list with a
*
operator (unpacking or splatting) unpacks the object into its individual items that are then passed to the function as separate arguments.In fact,
str.split()
already returns a tuple. By assigning multiple values at once inx, y, z = expression.split()
, you actually unpack the returned tuple into individual values, then inreturn x, y, z
, you pack those values into a tuple.Functions in Python can only return a single value. While you are allowed to comma-separate additional values, as you have done, they are combined into a single tuple object that wraps the intended values.
As such, your splitter function is returning a single tuple containing three strings. Your calculate function is expecting three individual arguments (I’m guessing that the error trace mentions this).
To get around this, you can use the splat/asterisk operator to “unpack” the items from the tuple:
a, b, c = splitter(expression) # or, inline calculate(*splitter(expression))
Edit: removed bad asterisk
Functions in Python can only return a single value
that’s not
trueaccurate, this is valid code in this context:x, y, z = splitter(expression)
Where x, y, and z are strings. But when you do this, akin to what OP did:
value = splitter(expression)
then
value
is a tuple of 3 strings.In fact, unpacking with asterisk at assignment, like below, is not allowed:
x, y, z = *splitter(expression)
x, y, z = *splitter(expression) ^^^^^^^^^^^^^^^^^^^^^ SyntaxError: can't use starred expression here
Gahh, serves me right for blindly writing code on my phone!
After the split x becomes (1 and z becomes 1). They can’t be converted to float. I think that’s why. Let me run the code. Edit - Also as you are returning a, b, c from splitter but Python functions return a single object. The a, b, c turns to a tuple. But you are using js syntax I think. So we have to unwrap inside the calculate function.
Now my original comment is not useful but you can try to introduce a conditional to check of the numbers x and z are actually numbers before converting to floats
# Ask user to enter an expression and display output def main(): expression = input("Expression: ") print(calculate (splitter (expression))) # Split expression into components and assign to variables as float values def splitter (expression): print(expression) x, y, z = expression.split() print(expression.split()) return x, y, z # Calculate expression result # Changes Beginning def calculate(numbers): x,y,z = numbers # Changes End x, z = float(x), float(z) if y == "+": return str(round((x + z), 1)) elif y == "-": return str(round((xz), 1)) elif y == "*": return str(round((x*z), 1)) else: return str(round((x / z), 1)) main()
you’re missing the asterisk to expand the tuple returned by splitter:
print(calculate(*splitter(expression)))
if you’re using VS Code, check out the error lens extension