<jupyter_start><jupyter_text>Exception Handling BasicsThere's one more way that you can control the flow of code and that's with exception handling. Exception handling is the process of "catching" an error that would otherwise halt execution of your code. This allows you to potentially recover from a somewhat fatal situation.Exception handling is a powerful tool, but sometimes can be overused or used improperly.  Rememeber these simple rules when doing exception handling:- Only catch exception you can gracefully recover from.- It's ok to have exception in your code, they're meant to be there for situations that you didn't account for.- Don't try to account for every exception possible.- If you have to catch all execption (for example in an always running script) log the exception.- Keep your `try` blocks as small as possible.  Types of Errors- A full list of default errors can be found in the [official Python documentation](https://docs.python.org/3.8/library/exceptions.html).- Some common one are:    - **`ValueError`:** An operation encounters an invalid value.    - **`TypeError`:** An operation is performed on a value of the wrong type.    - **`NameError`:** A variable name was used that hasn't been defined.    - **`ZeroDivisionError`:** The divisor in a division operation is 0.    - **`OverflowError`:** The result of an arithmetic operation is too large.  Catching Exceptions Using `try`/`except` StatementsTo "catch" an exception, you use the `try` and `except` statements:- **`try`:** Try the the following indented code.- **`except`:** if an exception is raised in the `try` blokc, run the following indented code.<jupyter_code># Let's try a small example where we want to make sure
# we get an integer value from the user
num_is_valid = False

while not num_is_valid:
    number_str = input("Please enter a number: ")

    try: 
        number = int(number_str)
        num_is_valid = True
    except ValueError:
        print("That is not an integer!")
        
print(number)
# you can also chain exceptions
def safe_division(A, B):
    try:
        print(A / B)
    except TypeError:
        print("A and B must be numbers!")
    except ZeroDivisionError:
        print("B cannot be 0")
        
safe_division(10, '5')
safe_division(10, 0)
safe_division(10, 2)<jupyter_output>A and B must be numbers!
B cannot be 0
5.0<jupyter_text>In-Class Assignment- Write a program that prompts the user to enter in a float and continues to do so until they do.  If the user enters an invalid value, use the `ValueError` to print out to the user "Try Again".- Write a program that prompts the user to enter in a string and then an integer.  Using the integer, display the value of the character that the number indexes into for the passed in string.  Some off-nominal use cases to consider are:    - Invalid integer entry    - An index value that's outside the scope of the string    - You may need to look at the Python documentation to find the correct Errors to catch  Solution<jupyter_code>while True:
    prompt = input("Please enter a valid float: ")
    try:
        val = float(prompt)
        print(f'Your value was: {val}')
        break
    except ValueError:
        print('Try Again')
user_str = input("Please enter a string: ")

while True:
    user_num = input("Please enter the location of the character to display: ")
    try:
        num = int(user_num)
        print(user_str[num])
        break
    except ValueError:
        print('Not an Integer!')
    except IndexError:
        print('location is invalid!')<jupyter_output>Please enter a string: KronosKoderS
Please enter the location of the character to display: meh
Not an Integer!
Please enter the location of the character to display: 100
location is invalid!
Please enter the location of the character to display: 3
n
{'fraction_non_alphanumeric': 0.07315154693235448, 'fraction_numerical': 0.005243838489774515, 'mean_word_length': 3.629854368932039, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '32550', 'license': 'MIT', 'n_tokens_mistral': 1033, 'n_tokens_neox': 995, 'n_words': 523, 'path': 'Lecture Material/07_Conditional_Logic_and_Control_Flow/07.5_ExceptionHandlingBasics.ipynb', 'repo_name': 'knherrera/pcc-cis-012-intro-to-programming-python', 'size': '3814'}