Please post a transcript of a failing run with the full output including
errors, a description of the input you gave it which was not handled,
and a description of what you intended should happen.
I certainly can’t run it (for one thing, where does
“calculate_def_external2” come from?) And anway would need to know what
input you gave it.
All that said, some remarks about the code as it stands, without running
it:
result = ""
I would e inclined to not set this - effictively you’re rpoviding a
result ahead of time. Just leave this out - that way if you try to use
'result" early, Python will tell you so rather than just proceeding with
the bogus value of “”. In larger programmes that might go a long way
before something is obviously wrong, making the bug harder to find.
again = ''
Similar here, but I would instead make this a Boolean, eg True. This way
it expresses your intent that the loop can run again, a true or false
idea.
user_name = input("Enter your name: ")
coursename = input("Enter your course name: ")
calculate_def_external2.welcome(user_name)
while again.lower() != 'q':
and therefore here I’d write:
while again:
(a) it’s easier to read and (b) it isn’t tied to your input("Enter q to quit: ")
function call. That way you can change the implementation (eg
change languages to one where “q” is unsuitable) without changing the
control logic itself.
user_operation = input("enter an operation +, -, *, /, %, sprt, farenheit, celsius: ")
while user_operation != "+" and user_operation != "-" and user_operation != "*" \
and user_operation != "/" and user_operation != "%" and user_operation != "sqrt"\
and user_operation != "farenheit" and user_operation != "celsius":
user_operation = input("enter an operation +, -, *, /, % sprt, farenheit, celsius: ")
Here, on the other hand, I would be inclined to go with the “set
user_operation up front” approach, basicly because Python does not have
a “do…until” version of “while”. So something like:
user_operation = None
while user_operation != "+" and user_operation != "-" and user_operation != "*" \
and user_operation != "/" and user_operation != "%" and user_operation != "sqrt"\
and user_operation != "farenheit" and user_operation != "celsius":
user_operation = input("enter an operation +, -, *, /, % sprt, farenheit, celsius: ")
In this way you’ve picked an initial value which is guarrenteed to fail
the test, ensuring that the input() prompt is made the first time.
You can also write the test more succinctly:
while user_operation not in ("+", "-", "*", "/", "%", "sqrt", "farenheit", "celsius"):
Now the loop body:
The first thing is that you have a single try/except for the whole piece
of code. This means that when an except happens you don’t really know
where it came from. Different operations raise diffferent exceptions for
different reasons. You only want to catch the exceptions you specific
know how to handle correctly. Because of this, you would normally try to
put a try/except around the smallest piece of code you can, eg:
try:
number1 = float(input("Enter 1st value: "))
except ValueError as e:
print("invalid value:", e)
continue
This catches exactly failure of float(), prints the actual exception
(which is important for debugging), and continues the outer loop.
Similarly the ZeroDivisionError should only be associated with the “/”
operation and so forth.
You almost never want to catch NameError at all - it means Python saw a
variable name it did not recognise. This is almost always an error in
your code. By printing just “Incorrect value. Try again.” you (a) are
not fixing or accomodating anything and (b) concealing the name what
caused the error, because you haven’t printed the exception itself.
The core rule of thumb is: catch only exceptions where you have a
meaningful thing to do to accomodate it. The objective is not to catch
all exceptions, it is to function correctly. Catching “anything which
you see happen” does not lead to a correctly operating programme.
Finally:
again = input("Enter q to quit: ")
With the change of “again” to be a Boolean I’d rewrite this to:
again = input("Enter q to quit: ") == "q"
That makes “again” True or False. The whole implementation is right here
instead of putting the test for “q” many lines away. This also makes it
easy to change if you decide to do that.
Cheers,
Cameron Simpson cs@cskk.id.au