# How would I have an improper DMS value input return a message to the user in a Python 3 function? [closed]

My question is about input functions in python 3 specifically for a latitude conversion function from dms to dd.

I'm new to python3 and having some trouble understanding how I would allow a user to input their latitude DMS coordinate and have them limited by a 0-90 range, so if they put something like 100, or -1, the code would return a statement asking them to input a valid latitude DMS format.

Below is my code - I think my if statement is where the trouble is happening. When I'm indicating if variable(x,x,x) - would that indicate the format the user would need to input their coordinate in?

``````def dmslat_convert_to_dd(degrees, minutes, seconds):
dd = degrees + float(minutes) / 60 + float(seconds) / 3600
return dd

if dmslat_convert_to_dd(degrees, minutes, seconds) in range(0, 90):
print(dd)
else:
print("Please enter correct DMS Latitude coordinates")
``````
• 100 degrees is valid for longitude, as is 180, -1, and -180. Your conversion function will not generate correct results in the western or southern hemisphere, and your validity test only considers integer values. – Vince Apr 15 '19 at 1:55
• Ah! Thanks - I should have clarified that I'm looking for latitude conversion first with the 0 to 90 range. I'll update the question. – Chris Apr 15 '19 at 2:05
• You still have two fundamental Python errors: 1) `range(0,90)` doesn't include 90, and 2) No non-integral value in the range 0...90 will return True – Vince Apr 15 '19 at 2:14
• Oh! I gotcha, okay so the range would have to be 0-91 to actually include 90. Then for the second error - I need to use the float() method to include both integral and non-integral values? (trying right now, just typing out loud) – Chris Apr 15 '19 at 2:26
• No, I'd expect you'd need to use the more traditional `val >= 0 and val <= 90` – Vince Apr 15 '19 at 3:17

Writing functions that are supposed to return a certain thing (or things) and can actually return something else is bad practice and can cause unexpected errors to creep in.

The standard way of doing this is to raise an exception with an informative message.

``````# Handle Python 2.x.
try:input = raw_input
except NameError:pass

def dms2dd(degrees, minutes, seconds):
degrees, minutes, seconds = float(degrees), float(minutes), float(seconds)
if degrees < -180 or degrees > 180 or minutes >= 60 or seconds >= 60:  # Note use of -180 - 180 to handle longitude as well...
raise ValueError('invalid values, degrees must be from -180 - 180, minutes from 0 - 60 and seconds from 0 - 60')
dd = abs(degrees) + minutes / 60 + seconds / 3600

return dd if degrees >= 0 else -dd

degrees, minutes, seconds = input('Please enter your DMS coordinate for Latitude: ').split()
try:
dd = dms2dd(degrees, minutes, seconds)
print(dd)
except ValueError as the_error:
print('Please enter correct DMS Latitude coordinates: ', the_error)
``````

For example:

``````Please enter your DMS coordinate for Latitude: >? 123 45 6
123.75166666666667

-123.751666667

Please enter correct DMS Latitude coordinates:  invalid values, degrees must be from -180 - 180, minutes from 0 - 60 and seconds from 0 - 60
``````

And note that this will handle some expected other issues, such as non numeric input:

``````Please enter your DMS coordinate for Latitude: >? a b c
Please enter correct DMS Latitude coordinates:  could not convert string to float: 'a'
``````
• Thank you - I hadn't realized it would be bad practice to have it return just the one latitude output. I have a lot to learn. Okay, apologies if this is a dumb question - what is the e for at the end of print('Please enter correct DMS Latitude coordinates: ', e)? I'm not understanding how it called the ValueError string at the top! Edit: Nevermind, I just saw that you made made ValueError also represented by e! What is the .split() for? I know the split() method returns lines, but I wasn't sure how it's being applied in your code. – Chris Apr 15 '19 at 4:44
• @Chris, note update to handle negative degrees and note my version of code was written and tested in Python 3 where the `input()` function is the equivalent of Python 2's `raw_input()` function, both of which return strings. Which is why I used `.split()`. I don't like using Python 2's `input()` function because it evaluates untrusted input as python code, equivalent to `eval(raw_input())` – user2856 Apr 16 '19 at 0:08