# 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.

  • FizzyOrange@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    3 days ago

    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:
    
  • Troy@lemmy.ca
    link
    fedilink
    arrow-up
    0
    ·
    3 days ago

    print(eval(input(“Expression:”)))

    Unsafe coding is best coding ;)

  • cherrykraken@lemmy.ca
    link
    fedilink
    arrow-up
    0
    ·
    3 days ago

    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))
    
    • Eager Eagle@lemmy.world
      link
      fedilink
      English
      arrow-up
      0
      ·
      edit-2
      3 days ago

      Functions in Python can only return a single value

      that’s not true accurate, 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
      
  • rtxn@lemmy.world
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    3 days ago

    Change this:

        print(calculate(splitter(expression)))
    

    to this:

        print(calculate(* splitter(expression)))
    

    The error is that calculate expects three float values (x, and y, and z), but splitter 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 in x, y, z = expression.split(), you actually unpack the returned tuple into individual values, then in return x, y, z, you pack those values into a tuple.

  • Eager Eagle@lemmy.world
    link
    fedilink
    English
    arrow-up
    0
    ·
    edit-2
    3 days ago

    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

  • palmtrees2309@lemm.ee
    link
    fedilink
    English
    arrow-up
    0
    ·
    3 days ago

    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