-1

I'm working on a very simple temperature converter in Python (just for practice), and am struggling with some of the UX components. I'd like to have checks in place to continue prompting for variable input when invalid entries are made. My full code is below:

o_temp = ''

def temp_input(o_temp):
    o_temp = raw_input('Enter a temperature (round to nearest integer): ')
    return o_temp

def temp_input_check(o_temp):   
    o_temp = list(o_temp)
    for i in o_temp:
        if i not in '1234567890':
            print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
            temp_input(o_temp)
        else:
            break

def converter(o_temp):
    unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
    unit  = unit.upper()
    if unit == 'F' or unit == 'f':
        n_temp = (9.0/5.0) * int(o_temp) + 32
        print '%d C = %d F' % (o_temp, n_temp)
        quit()
    elif unit == 'C' or unit == 'c':
        n_temp = (5.0/9.0) * (int(o_temp) - 32)
        print '%d F = %d C' % (o_temp, n_temp)
        quit()
    else: #check for valid entry
        print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
        unit_input()

def temp_converter():
#title, call sub-functions
    print ''
    print 'Temperature Converter'
    print ''
    temp_input(o_temp)
    temp_input_check(o_temp)
    converter(o_temp)

temp_converter()

However, when I enter an invalid entry (say, a letter or a combination of letters and numbers) into the o_temp prompt, the code does not seem to recognize that this is invalid and continues with the unit prompt. Am I not correctly returning the variable? What's the issue here? I tried removing the initial o_temp declaration but then I got "NameError: global name 'o_temp' is not defined"

EDIT

I came up with this solution, any further suggestions to refine the code at all?

def converter():
    print 'Temperature Converter'
    while 1:
        temp = raw_input('Starting temperature? ')
        try:
            temp = float(temp)
        except ValueError:
            print 'Invalid entry. Please enter only the numerical temperature measurement.'
        else:
            break
    while 1:
        unit = raw_input('Convert to Fahrenheit or Celsius? ')    
        if unit.upper().startswith('F') == True:
            print "%f C = %f F" % (temp, temp*9./5+32)
            return False
        elif unit.upper().startswith('C') == True:
            print "%f F = %f C" % (temp, (temp-32)*5./9)
            return False
        else:
            print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'

converter()
grrothman
  • 171
  • 1
  • 11
  • 1
    What is your actual question? What happens when you run this code and how is that different from what you expected? – kindall Jun 05 '15 at 21:24
  • Sorry, hadn't finished writing question and accidentally submitted prematurely. Full code and question is now up! – grrothman Jun 05 '15 at 21:26
  • Also, the reason you were getting "name error" is because your o_temp is never assigned anywhere in temp_converter. You're passing in a variable that has no value to your functions! – Matthew Runchey Jun 05 '15 at 21:40

3 Answers3

0

Your for loop isn't implemented correctly.

def temp_input_check(o_temp):   
    o_temp = list(o_temp)
    for i in o_temp:
        if i not in '1234567890':
            print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
            temp_input(o_temp)
        else:
            break

You check every character for an invalid entry. If you typed in multiple invalid characters, it'll keep hitting the trigger after you have already determined that the string is invalid!

Also, if your first character is valid, you're telling it to break from the for loop (in your code 1fdsdfdsf would be a valid temperature, because it would skip every character after hitting that else statement and breakout from the loop).

Also, your temp_input doesn't need to accept an argument in the function (you're just gonna return the user's input). You actually want to assign it after you call the function instead of having it as an argument

Also, you're calling temp_input again to get the user input, but not capturing that anywhere with a return - so it's ultimately not doing anything. You should have your function return a True or False, and then catch that on the outside of the checker if you want to have the user try and enter a better temperature:

def temp_input_check(o_temp):   
    o_temp = list(o_temp)
    for i in o_temp:
        if i not in '1234567890':
            print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
            return False
        else:
            pass # nothing is wrong with this character, keep checking
    return True # if we hit this line, there were no problem characters

Then, when you call the stuff:

while(1):
    o_temp = temp_input()
    if temp_input_check(o_temp):
        break # this means our o_temp is allllright. 
              # otherwise, go back to the start of the loop and ask for another temp
converter(o_temp)
Matthew Runchey
  • 234
  • 2
  • 6
0

You define some functions, then call temp_coverter(). This function calls temp_input(otemp), sending it an empty string for no reason that I can see, other than the possibility that you're unaware that you can define a function with no parameters. This function then returns a value, which you don't save.

After that, temp_input_check(otemp) is called, which attempts to validate the same empty string. This function's returned value isn't saved, which isn't a big loss, because None isn't a particularly useful value to save.

Then converter(otemp) sends the same old empty string to the actual converter. Mayhem results.

I recommend spending some quality time with the tutorial.

When you're done, the code should look more like this:

def converter():
    print 'Temperature Converter'
    unit = raw_input('Convert to Fahrenheit or Celsius? ')
    while 1:
        temp = raw_input('Starting temperature? ')
        try:
            temp = float(temp)
        except ValueError:
            print 'Not a valid temperature.'
        else:
            break
    if unit.lower().startswith('f'):
        print "%f C = %f F" % (temp, temp*9./5+32)
    else:
        print "%f F = %f C" % (temp, (temp-32)*5./9)

converter()
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
0

because you mentioned 'o_temp' as the function parameter in the end but mentioned it as a empty string at Start. Don't give same names for global & function variables (just to avoid confusion). the function took the o_temp you mentioned above as parameter and neglects the one inside them.

Also the raw_input won't consider the input as string. Try input instead to avoid the sensibility of not using str to correct the loop.

This will do:

def converter():
    o_temp = float(raw_input('Enter a temperature (round to nearest integer): '))
    for i in str(o_temp):
        if i not in ['1','2','3','4','5','6','7','8','9','0','.']:
            print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
    unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
    if unit in ['f','F']:
        n_temp = (9.0/5.0) * float(o_temp) + 32
        print '%f C = %f F' % (o_temp, n_temp)
    elif unit in ['c','C']:
        n_temp = (5.0/9.0) * (float(o_temp) - 32)
        print '%f F = %f C' % (o_temp, n_temp)
    else: #check for valid entry
        print 'Invalid entry. Please enter F for Fahrenheit or C for    Celsius'
        unit_input()

def temp_converter():
#title, call sub-functions
    print ''
    print 'Temperature Converter'
    print ''
    converter()

print temp_converter()
Thuruv
  • 78
  • 9