Basic calculator program in Python as a beginner I'm a beginning coding and this is my very first Python program - a basic calculator. I would very much appreciate any recommendations or fixes!

if restart != "Y":
        print("It was a pleasure calculating with you!")
        time.sleep(1)
        print("\nGoodbye!")
        time.sleep(1)
        sys.exit()

# Modules:

import time     # Provides time-related functions
import sys      # Used to exit the program when needed


# Operations:

def add(num1, num2):
    #   Returns the sum of num1 and num2
    return num1 + num2


def sub(num1, num2):
    #   Returns the difference of num1 and num2
    return num1 - num2


def mul(num1, num2):
    #   Returns the product of num1 and num2
    return num1 * num2


def div(num1, num2):
    #   Returns the quotient of num1 and num2
    try:
        return num1 / num2
    except ZeroDivisionError:
        # Handles division by zero
        print("Division by zero cannot be done. You have broken the universe. Returning zero...")
        return 0


def exp(num1, num2):
    #   Returns the result of num1 being the base and num2 being the exponent
    return num1 ** num2


# Run operational functions:

def run_operation(operation, num1, num2):
    # Determine operationz
    if operation == int("1"):
        print("Adding...\n")
        time.sleep(1)
        print(num1, "+", num2, "=", add(num1, num2))
    elif operation == int("2"):
        print("Subtracting...\n")
        time.sleep(1)
        print(num1, "-", num2, "=", sub(num1, num2))
    elif operation == int("3"):
        print("Multiplying...\n")
        time.sleep(1)
        print(num1, "*", num2, "=", mul(num1, num2))
    elif operation == int("4"):
        print("Dividing...\n")
        time.sleep(1)
        print(num1, "/", num2, "=", div(num1, num2))
    elif operation == int("5"):
        print("Exponentiating...\n")
        time.sleep(1)
        print(num1, "^", num2, "=", exp(num1, num2))
    else:
        print("I don't understand. Please try again.")
        time.sleep(1)


def main():
    while True:                   # Loops if user would like to restart program
        valid_input = False
        while not valid_input:    # Loops if user enters an invalid input. Avoids error
            try:
                # Acquire user input
                num1 = (int(input("What is number 1? ")))
                num2 = (int(input("What is number 2? ")))
                operation = int(input("What would you like to do? \n1. Addition, 2. Subtraction, 3. Multiplication, "4. Division, 5. Exponentiation \nPlease choose an operation: "))
                valid_input = True
            except ValueError:      # Handles any value errors
                print("Invalid input. Please try again.")
                time.sleep(1)
        run_operation(operation, num1, num2)
        time.sleep(1)
        # Ask if the user wants to do more calculations or exit:
        restart = (str(input("Would you like to make more calculations? Enter (Y) for yes, or any other character for no. ")))


I'm having a lot of trouble with the code block below. It doesn't recognize "Y" and instead outputs: "It was a pleasure calculating with you! Goodbye!" What could I do?

if restart != "Y":
    print("It was a pleasure calculating with you!")
    time.sleep(1)
    print("\nGoodbye!")
    time.sleep(1)
    sys.exit()


#  Title Sequence
print('\n\nCalculator\n\n')
time.sleep(1)
print('      ---LOADING---\n\n')
time.sleep(2)
print('Hello. I am your personal calculator. \nBEEP BOOP BEEP. \n\n')
time.sleep(1)


#  Calls the main function to start program
main()

# Turns my program into an importable module
if __name__ == '__calculator__':
    main()
Thanks for asking your question! I'll try and give a concise answer to the main issues with your code. Overall it is well done for a beginner.

First, I'll address the code block you're having trouble with. The restart variable is never defined, so I'm not even sure how your code ran at all. You will need to give restart some initial value, supposedly "Y" as that would have it skip over that code in the beginning.

There is a bigger problem here though, which is that you are putting code in the global scope and also in a main function. Usually, Python scripts do one or the other, as they mean different things to other Python programmers. Although it is completely valid what you're doing, it's not good Python. The purpose of the main function and the if __name__ == '__main__' conditional is so that you can separate the "executable" part of your program from the "library" part.

(See this StackOverflow answer for more detail: https://stackoverflow.com/questions/419163/what-does-if-name-main-do)

The main function allows your code to have different behavior when your program is run on its own, as opposed to when it's imported and usually this means that the imported code does not run anything on its own especially the blocks you're having trouble with.

I would suggest putting all the "running" code, that is, the restart check, and the "calculator startup" all in the main function. And, if you want to logically separate these ideas, then put them all in separate functions that run from main. Something perhaps along the following lines:

def restart(response):
    # uses "in" to check multiple values,
    # a replacement for (response == "Y" or response == "y")
    # which is longer and harder to read.
    if response in ("Y", "y"):
        return True
    else:
        # statements you want to print to the screen before exiting
        ...
        return False


And in the main function:

def main():
    ...
    setup_calculator()  # something you would write, feel free to give it a better name
    ...
    restart_msg = "Would you like to make more calculations?" \
                  "Enter (Y) for yes, or any other character for no. "
    if not restart(str(input(restart_msg))):  # uses the function I wrote
        return  # would not need to import "sys", just exit from main normally


You can do a similar thing for the calculator startup, but I'll leave that to you.

In your run_operation function, you write conditionals with int("1"), int("2"), ... etc. You can just write 1, 2, ... etc, for each if statement. Also, you don't have to worry about typecasting the inputs to run_operation because you do that in the input in main. Once you have the types from the user input, assume that your code runs on that specific type.

One more thing I noticed is that almost everytime you print to the console, you also perform a time.sleep(1), (in one case a time.sleep(2)). What I suggest, so that you don't repeat yourself, is to write your own print function that also performs a sleep every time,

def calculator_print(*args, delay=1):
    print(*args)
    time.sleep(delay)


You could give it a better name, I'm just concerned with the form that it has. This would probably halve your line count and improve readability by many times. The *args is a way for you to accept any number of arguments to calculator_print to match the way that print itself can and does accept many arguments, like in your run_operation function. The delay default argument is there to set the sleep delay to a different value other than 1 like in your calculator startup. This will get rid of all of your explicit time.sleep calls and abstracts away the details of the printing itself. (Say you wanted to change it to do something different, you can still use the rest of the code you've written in the same way. You would only have to change the calculator_print function. Encapsulation is good!)

If you fix these few problems, I think you will be rid of any bugs that you have already and your readability will skyrocket. A very very important part of programming that is grossly overlooked is readability. This should always be taught alongside syntax. As a programmer you will be reading code more than writing it so you should be good at reading good (and bad) code and writing code that makes it easier for others to read; you may even be reading your own old code one day. Writing comments and clear code are both essential for readability.

You've done a really good job here as a beginner. Let me know if you have any questions about what I've said or about anything else Python.

Keep up the good work!