Python 3 - simple temperature program I have been teaching myself Python (as well as Tkinter) and today one of the sites I was reading, asked us to write a program to covert one value from Fahrenheit to Celsius, once - an easy three line program. As you can read in the comments for the program below, I wanted to expand on this.

This program is one of the most complex and best organized for me thus far. I have feed it through a PEP8 program and it returned no errors, and the program itself runs as I intended and I haven't crashed it when passing errors.

I would be grateful for any comments on the structure of the program, as well as areas I can improve and/or streamline the code - any and all constructive feedback is welcomed!

#!/usr/bin/python
"""
Program: Temperature Coversion (C to F, or F to C)
Date:    02 May 2019
Author:  Jason P. Karle
Remark:  This program was inspired by a Python exercise that
asks you to create a program that will convert one Celsius value to Fahrenheit;
so a program that can be executed with three lines of code.
However, I wanted to make something that would allow the user to
convert to and from either C of F, and do so multiple times, until the user
decides to end the program. This was also an exercise for me to
advance not only my code skills, but how I structure a program.
"""


def quitContinue():
    print("\nDo you want to:\n")
    print("     1. Make another conversion; or")
    print("     2. Exit the program?\n")
    answer = input("Make you selection: ")
    try:
        if answer == "1":
            mainProg()
        else:
            return
    except:
        print("That is not a valid choice.")
        quitContinue()


def CtoF_Calc():
    print("\nThank you, please enter the")
    print("value you want to convert.")
    print("Enter a value between -273.5°C to")
    print("+5.5 dectillion °C")
    value = float(input(": "))
    try:
        if value &lt; -273.5 or value &gt; 5.5**30:
            print("That is not a valid range.")
            celciusCalc()
        else:
            answer = (value*(9/5))+32
            print(f"{value}°C equals: {answer}°F")
            quitContinue()
    except:
        print("Please entet a number!")
        CtoF_Calc()


def FtoC_Calc():
    print("\nThank you, please enter the")
    print("value you want to convert.")
    print("Enter a value between -273.5°C to")
    print("+5.5 dectillion °C")
    value = float(input(": "))
    try:
        if value &lt; -459.5 or value &gt; 42**30:
            print("That is not a valid entry.")
            celciusCalc()
        else:
            answer = (5/9)*(value-32)
            print(f"{value}°F equals: {answer}°C")
            quitContinue()
    except:
        print("That is not a number!\n")
        FtoC_Calc


def makeSelection(selection):
    try:
        if selection == "1":
            CtoF_Calc()
        elif selection == "2":
            FtoC_Calc()
        else:
            return
    except:
        print("That is not a valid selection")
        makeSelection(selection)


def mainProg():
    print("Please enter the number")
    print("corresponding to what you")
    print("want to convert:")
    print("     1. Celcius to Farenheit")
    print("     2. Farenheit to Celcius")
    print("     3. Exit\n")
    selection = input("Enter 1, 2 or 3: ")
    makeSelection(selection)


if __name__ == "__main__":
    print("Welcome to the temperature")
    print("conversion program!\n")
    mainProg()
At first glance your code looks nice and clean. And even though the naming goes against PEP8 would be near perfect style.

I then entered your code into PyCharm, and then and there I knew this was unfortunately a facade.

Firstly I don't think you've set your linter up correctly. As within seconds I knew your code wasn't PEP8 compliant due to using camel case function names.


  I have feed it through a PEP8 program and it returned no errors



PEP 8 convention is to use snake_case rather than quitContinue or CtoF_Calc.
You have a couple of miss-spelt words, Prog and "entet".
It's advised against having bare except statements as they catch too many errors and lead to hard to debug errors. This can actually be seen in your program, it's hidden a bug that you probably don't know about.
celciusCalc is undefined, and so is a bug in your program.
PEP8 and linters are quite finicky when it comes to whitespace. value*(9/5) should have spaces either side of the operators.
You have a 'pointless statement', FtoC_Calc. This is as you forgot to call the function. And so causes a bug in your program.


And so I recommend you look into configuring your linter to get the maximum amount of warnings possible. I personally use Prospector and Flake 8 with a butt tone of plugins.




In FtoC_Calc you state the range in celsius, which is confusing. If I'm using your program I likely won't know what the equivalent in Fahrenheit is.
Keep the code in the try statement to be as small as possible. Looking at the except it looks like the purpose is to handle when you don't enter floating point integer values.


You haven't put the call to float in the try and so you have another bug.
You should use except ValueError.
You can put all the code that is currently in the try in an else statement.
You should replace celciusCalc() with FtoC_Calc and CtoF_Calc.

Currently your design is sub-optimal, FtoC_Calc interacts with the user and performs the mathematical calculations.

It also uses recursion rather than loops to cycle through the function calls, leading not only to spaghetti code, but toward getting a RuntimeError where you exceed the recursion depth.

This is all rather easy to deal with. Split the function into three distinct functions:


One that gets a floating point integer from the user. And handles interactions with the user if they enter an incorrect value.

If a user enters an incorrect value you'll want to have your try statement in a while loop to continuously ask for input.

By giving a range or an 'is_invalid' function to this function you can reduce the amount of duplicated code.
The function to convert C to F.
The function that calls both of these functions.

The majority of your code in make_selection is not needed. No exceptions should be raised from these functions, and it isn't the correct place to handle them.
quit_continue should be changed to a function that returns a boolean. This can be used in mainProg to determine if the user will continue using the program or exit.

This means mainProg should contain a while loop to continuously allow the user to enter values they want to convert.

It should be noted that quit_continue shouldn't need the try and should never reach the except. However adding more code the way you did would make this assumption to be less safe as the program becomes more and more problematic.
I changed your string delimiters as one of my tools errors on ", as I commonly use '. Using " is perfectly acceptable.


#!/usr/bin/python
"""
Program: Temperature Coversion (C to F, or F to C)
Date:    02 May 2019
Author:  Jason P. Karle
Remark:  This program was inspired by a Python exercise that
asks you to create a program that will convert one Celsius value to Fahrenheit;
so a program that can be executed with three lines of code.
However, I wanted to make something that would allow the user to
convert to and from either C of F, and do so multiple times, until the user
decides to end the program. This was also an exercise for me to
advance not only my code skills, but how I structure a program.
"""


def input_float(prompt, is_invalid):
    while True:
        try:
            value = float(input(prompt))
        except ValueError:
            print('That is not a number!')
        else:
            if is_invalid(value):
                print('That is not a valid number.')
                continue
            return value


def c_to_f(value):
    return (value * (9 / 5)) + 32


def f_to_c(value):
    return (5 / 9) * (value - 32)


def convert_c_to_f():
    print('\nThank you, please enter the')
    print('value you want to convert.')
    print('Enter a value between -273.5°C to')
    print('+5.5 dectillion °C')
    celsius = input_float(': ', lambda v: v &lt; -273.5 or 5.5**30 &lt; v)
    fahrenheit = c_to_f(celsius)
    print(f'{celsius}°C equals: {fahrenheit}°F')


def convert_f_to_c():
    print('\nThank you, please enter the')
    print('value you want to convert.')
    print('Enter a value between -459.5°F to')
    print('+42 dectillion °F')
    celsius = input_float(': ', lambda v: v &lt; -459.5 or 42**30 &lt; v)
    celsius = f_to_c(fahrenheit)
    print(f'{fahrenheit}°F equals: {celsius}°C')


def quit_continue():
    print('\nDo you want to:\n')
    print('     1. Make another conversion; or')
    print('     2. Exit the program?\n')
    answer = input('Make you selection: ')
    return answer == '1'


def main():
    while True:
        print('Please enter the number')
        print('corresponding to what you')
        print('want to convert:')
        print('     1. Celsius to Fahrenheit')
        print('     2. Fahrenheit to Celsius')
        print('     3. Exit\n')
        selection = input('Enter 1, 2 or 3: ')
        if selection == '1':
            convert_c_to_f()
        elif selection == '2':
            convert_f_to_c()
        else:
            return
        if not quit_continue():
            return


if __name__ == '__main__':
    print('Welcome to the temperature')
    print('conversion program!\n')
    main()