Why is my output not formatted as a string?
from milon@lemm.ee to programming@programming.dev on 01 Mar 02:20
https://lemm.ee/post/56928000

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

#programming

threaded - newest

palmtrees2309@lemm.ee on 01 Mar 02:32 next collapse

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()

eager_eagle@lemmy.world on 01 Mar 02:42 next collapse

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

<img alt="" src="https://lemmy.world/pictrs/image/9486ba06-84ca-468a-8fa4-0531f4035aba.png">

rtxn@lemmy.world on 01 Mar 02:44 next collapse

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.

cherrykraken@lemmy.ca on 01 Mar 03:01 next collapse

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

eager_eagle@lemmy.world on 01 Mar 03:14 collapse

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
cherrykraken@lemmy.ca on 01 Mar 04:34 collapse

Gahh, serves me right for blindly writing code on my phone!

troyunrau@lemmy.ca on 01 Mar 05:35 next collapse

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

Unsafe coding is best coding ;)

Kissaki@programming.dev on 01 Mar 10:04 next collapse

There’s a !python@programming.dev community more appropriate to python specific questions

FizzyOrange@programming.dev on 01 Mar 11:00 collapse

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:
bestboyfriendintheworld@sh.itjust.works on 01 Mar 12:23 collapse

PyCharm is the way to go to write Python.

FizzyOrange@programming.dev on 01 Mar 12:44 collapse

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.

crmsnbleyd@sopuli.xyz on 01 Mar 13:32 collapse

The community version is free right

FizzyOrange@programming.dev on 01 Mar 14:00 collapse

Ah yeah I don’t think that existed last time I used it.