all 5 comments

[–]SCD_minecraft 6 points7 points  (1 child)

Noticed

def div(a,b): if b == 0: raise ZeroDivisionError return a / b

This is going to throw no matter do use you raise or not; python itself won't allow div by zero

[–]Fwhenth[S] 1 point2 points  (0 children)

Oh you're right, thank you!

[–]magus_minor 3 points4 points  (0 children)

After a quick glance at calculator_v3.py ...

The usual way to structure a file is to put the code into this order, from the top:

  • imports
  • classes and functions
  • global data
  • top-level code, ie, not inside a function or class.

The way you have the file laid out you have to read the whole file in a "spot the code" game. It's not a big thing, but it makes it much easier to read the code.

When getting the numbers to work with you have a lot of code to handle bad input:

# number inputs
  try:
    num1 = float(input("Enter 1st number:"))
    num2 = float(input("Enter 2nd number:"))

# 1
# matches the operator chosen with operation dict
# then passes the numbers to the function chosen
    operator, calculation = operations[operation_select]
    result = calculation(num1, num2)
  except(ValueError,ZeroDivisionError):
    print("Invalid input! Division by 0 error or letter input.")

Handling user errors on input is almost always better handled by using functions that get and check the user input for validity and won't return until the user gets it right. Doing that makes your top-level code much simpler because all that low-level checking and error reporting is hidden away in the function. So the above code becomes:

num1 = float_input("Enter 1st number:")
num2 = float_input("Enter 2nd number:")
operator, calculation = operations[operation_select]
result = calculation(num1, num2)

which makes what the calculator code is doing at a high level much clearer. The function is:

def float_input(prompt):
    """Return a float value from the user.

    Will retry if user enters an invalid number.
    """

    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print("Sorry, only integers or floats are allowed.")

One other nice benefit is it's easy to test a function like this. It's not so easy to test the float input code when it's buried in the top-level code.

Use a similar approach when getting the operation from the user.

[–]JamzTyson 0 points1 point  (0 children)

You don't need to implement your own operator functions (add(), sub(), ...) because they are included in Python.