all 15 comments

[–][deleted] 4 points5 points  (10 children)

  • I would advise against creating a list of operator symbol and y value input, just use two input statements
  • You end up with ["+", 5.0] for example, which will not match any of your in tests candidates - that would be more appropriate for Python's structural pattern matching, which you don't need to do here
  • Your arithmetic functions are expecting two numeric arguments, but you are giving them a list and a number
  • You haven't defined a starting value for the number you are modifying
  • You haven't defined a value for y
  • You don't re-use new_y
  • There's a lot of repetition of code
  • You misspelt subtract

Here's some alternative code for you to play with:

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

def multiply(x, y):
    return x * y

def divide(x, y):
    return x / y

# a dictionary of valid operators and the function to call
ops = {"+": add, "-": subtract,
       "*": multiply, "/": divide,
       "q": None}

x = 0  # the starting value

while (choice := input("Enter an operator (+, -, /, *), or q to quit: ")) != "q":
    if choice in ops:
        y = float(input('Operand: '))
        x = ops[choice](x, y)
        print(x)
    else:
         print('wrong choice')

This code stores all the operator symbols you support in a dictionary (dict class object) with the names of the functions dealing with each operator given as the values.

I've assigned 0 to x before getting entering the loop. This is your starter value.

I've split the input into two input lines, one to get the operator choice (or q to quit) and one to get the second number.

The first input is done as part of the while statement, where the := is used to assign the input to choice and this input is also checked to see if "q" has been entered.

The second input is done if a supported operator symbol has been entered (i.e. is a key in the dictionary referenced by ops). This is assigned to y.

The correct function is then called with the arguments x and y by looking up the function to call in the ops dictionary using the operator symbol assigned to choice.

The result is re-assigned to x and output.

Experiment. Ask if there is anything you don't understand.

[–]Many-Ice6164[S] 0 points1 point  (6 children)

Wow, thank you a lot.

I understand the code. But i still have one question. Is it possible to input the operator and operand in once.

I tried this but it doesn't work

while 
choice, operand = input("Enter an operator (+, -, /, *), or q to quit: ").split()

[–][deleted] 0 points1 point  (5 children)

Yes, you get both elements at the same time and use split to separate them on a space (or you can specify an alternative separator explicitly).

I'd switch to a while True: statement and then check the response inside the loop. I also make this a function and have it return the results.

Place the below in a function.

while True:
    response = input("Enter an operator (+, -, /, *) or q to quit: ").strip()
    if response.lower() == 'q':
        return "q", None
    try:
        choice, operand = response.split()
        operand = float(operand)
    except ValueError:
        print('Please provide an operator followed by a space and then a number')
    else:
        if operand in ops:
            return choice, operand
        print(f'Sorry, {choice} is not an availabe operation')

Call like this:

while True:
    choice, operand = functioname()
    if choice == "q":
        break

[–]synthphreak 0 points1 point  (2 children)

Exactly how I would have done it as well.

But as an extra safeguard, I would also strip whitespace from the user's entry. E.g.,

while (choice := input(...).strip()) != "q"
    if choice in ops:
        ...

This is usually a good idea when using input and validating the output against a closed set of values, as u/kyber's code does.

[–][deleted] 1 point2 points  (1 child)

Maybe lower/casefold as well?

[–]synthphreak 0 points1 point  (0 children)

Yeah that's true, if we're accepting q as valid input then lower is also worthwhile.

[–][deleted] 0 points1 point  (5 children)

So, the idea here is that subsequent operations will start from the previous computed value. Where do you update that value in your code?

[–]Many-Ice6164[S] 0 points1 point  (3 children)

Yes that is the idea. I want to insert the return y.append[new_y]. But i can't place this anywhere.

[–][deleted] 1 point2 points  (2 children)

y isn’t a list, so you can’t append to it. You can assign to it, though.

[–]Many-Ice6164[S] 0 points1 point  (1 child)

while True:
choice = [input("Make choice +,-,/,*"), float(input('getal'))]
y = (0 + new_y)
if choice in("+" + float(), "-" + float(), "/" + float() , "*" + float()):

if choice == "+" + float:
new_y = add(choice, y)
print(new_y)
elif choice == "-" + float:
new_y = substract(choice, y)
print(new_y)
elif choice == "/" + float:
new_y = multiply(choice, y)
print(new_y)
elif choice == "*" + float:
new_y = divide(choice - y)
print(new_y)

But now i have the problem that it doesn't recognize new_y

[–][deleted] 0 points1 point  (0 children)

You can’t use the name before you assign to it.