<jupyter_start><jupyter_text>Functions - Best practicesIn this notebook we will discuss a bit about what are the best practices of documenting and writing functions. These topics won't be graded but they will give you a general idea of what to do once you start developing in real-world. They are also usable throughout any programming language.The following are just initial ideas for you to think about and use during the course. Commenting, what to comment and how to comment are open-ended discussions and different people have different opinions. Just make sure, pretty please 🙏, that you comment and document what you don't know. I can't stress this enough, **You don't know how many times people had to refactor code and redo everything just because they forgot what it did.**  CommentsEveryone likes comments and everyone knows that they are important. Leaving comments in the code allows others to understand our thought process and allows you to return to the code, after some days, and still understand what the hell you were trying to do at that time. I know it sounds troublesome and you think that you will remember what you were doing, but trust me when I say this:  You won't remember everything so might as well add some comments Initially, and after reading all these warnings your thought process will likely be![Comments everywhere](assets/comments-comments-everywhere.jpeg)But **be careful!** If you start commenting everything like in the function `adding_function` below, most of your comments will feel like noise and the important comments will be lost in the spam<jupyter_code># Example of spammy comments
def adding_function(int_1, int_2):
    # This function adds two integers -> as the name and parameters already suggest, useless comment
    
    # Adding variables a+b -> useless as well, any person that sees this knows that it's an adding operation
    result = int_1 + int_2
    
    #returns the result of the sum made above -> we know already 😂 
    return result

# In this case the code is very self-descriptive, so it may not need any comments really<jupyter_output><empty_output><jupyter_text>When taking comments into consideration, and this will be hard at first, you need to find balance between over-commenting and commenting what is needed. Your variables should also be descriptive of what you are trying to achieve<jupyter_code>import re

def sanitize_string(string):
    
    if type(string) is not str:
        # No need for a comment, you understand by the print and condition what is happening here
        print("Not a string!")
        return
    
    # Wow, what the *!F$% is this next piece of code doing? 
    #  -> Maybe I should document this for other people and myself in the future!
    
    # regex, removes any character that is not a space, number or letter
    clean_string = re.sub('[^A-Za-z0-9 ]+', '', string)
    
    # this you probably know, but if you don't -> comment! 
    # It lowercases the string
    return clean_string.lower()
    
weird_string = "^*ººHe'?llo Woç.,-rld!"
sanitize_string(weird_string)
sanitize_string(2)<jupyter_output>Not a string!<jupyter_text>Commenting is completely up to the programmer. It's **your responsability** to know what you are doing and to make sure that the people who are reading your code understand what you were doing at the time of writing!* Use clear, descriptive variables!* Use clear, descriptive function names - `function_one` doesn't add any information on what it does!* If you are making any assumption inside the code - document it!* If you are fixing an edge case (i.e., a very specific problem/condition of your solution) - document it!* If you feel that it's not clear what you have done - leave a comment!* Don't add comments to every line of the program describing every single thing you do, most of them probably won't add any value  DocstringsPython documentation strings - docstrings - are a way of providing a convenient and constant way of writing a description to any type of functions, classes and methods (the last two you will learn later on). There are several ways of writing docstrings, I'll introduce you to a specific one but in general they all tend to rotate around the same idea which is - **document and comment your function!**Usually every function should state its purpose and give a general description of what it receives (parameters) and what it returns. Moreover, some IDEs - like VSCode, not Jupyter - already come with this option so usually if you write `"""` and click enter after a function it will create a docstring for you to fillExample shown below  After pressing Enter this is what shows up!  Pretty cool right?! Some IDEs already give you all the tools to employ Docstrings so there is really no excuse! **Note:** You may need to activate this feature on your IDE. For VSCode you might need to install this plugin: https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring -> check its example for a detailed video on how to do thisUsing function `sanitize_string` as an example:<jupyter_code>def sanitize_string(string):
    """
    Cleans a string by removing any characters that are not spaces, numbers or letters. returns it in lowercase
    
    :param string: string to be cleaned
    :return: sanitized string
    """
    if type(string) is not str:
        print("Not a string!")
        return
    
    # removes any character that is not a space, number or letter
    clean_string = re.sub('[^A-Za-z0-9 ]+', '', string)
    
    return clean_string.lower()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.05427189682966147, 'fraction_numerical': 0.0016120365394948952, 'mean_word_length': 4.1042047531992685, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 18, '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': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '24784', 'license': 'MIT', 'n_tokens_mistral': 1399, 'n_tokens_neox': 1352, 'n_words': 807, 'path': 'Week 04/SLU08 - Functions Intermediate/Appendix.ipynb', 'repo_name': 'LDSSA/ds-prep-course-2021', 'size': '5583'}