<jupyter_start><jupyter_text>What Are [Modules](https://docs.python.org/3/tutorial/modules.html)?Modules allow you to logically organize your code and provide the ability to reuse it - thus:- minimizing the number of lines of code- creating additional opportunities for future reuseWhen you are grouping related pieces of code, you are also making it wasier to understand and use.Modules can define:- functions- classes- variablesThey can also be run & imported.  Importing ModulesThere are 2 ways to import a module or set of modules:1. `import MODULENAME`2. `from MODULENAME import var1[, ..., varN]`The first [imports all](https://docs.python.org/3/tutorial/modules.htmlimporting-from-a-package) from a module.  importYou can use any python source file as a module using the **import** statement. (Only needs to be done once.)If present in the search path (list of directories) python interpreter can import.  ExampleAssume we are in an empty folder with these two files ...1. support.py```python support.pydef print_func(var):    print("Hello, {}!".format(var))```2. hello.py```python hello.pyimport support call on function from imported filename = input("What is your name?\t")support.print_func(name)```What do you expect will happen if you run **_hello.py_**?**NOTE:** This cannot be done in this single notebook.  *from ... import* StatementIf you only wish to import a specific variable or function, you can do so using the `from ... import ...` to import.The `from` statement allows you to import specific attributes instead of the whole module.If you put a `*` after *import* it will bring in everything ...But this is __not__ recommended! Here are a few reasons why:1. As per some of the answers on [this Stack Overflow question](https://stackoverflow.com/questions/2386714/why-is-import-bad) ...- puts a lot of stuff into your namespace- could shadow/overwrite other objects & you won't know- you don't know exactly what's being imported- can't easily find which module created something specific- [it breaks](https://stackoverflow.com/a/2454460/10474024)- causes poor unreadable code2. As that SO article stated as well as [this](https://pythonconquerstheuniverse.wordpress.com/2011/03/28/why-import-star-is-a-bad-idea/), you basically cripply a static code analyzer (like [pyflakes](https://pypi.org/project/pyflakes)) making static type checking impossible.3. According to the [Zen of Python](http://www.python.org/dev/peps/pep-0020) ... "Explicit is better than implicit."4. What happens if modules change? You have no control over what is imported.  ExamplesImagine a python file ...```python fib.pydef fib(num):    """"""    result = []    num1, num2 = 0, 1    while num2 < num:        result.append(num2)        num1, num2 = num2, num1 + num2    return result```Now image your interpreter ...`from fib import fibfib(100)`... what would be the outcome?  Difference Between IMPORT and FROMPython's **import** loads a python module into it's own namespace. In order to use the functions or attributes of that module, you will have to abide by `dot notation`:```pythonimport feathersduster = feathers.ostrich("South Africa")```Python's **from** loads a python module into the current namespace so that you can refer to it without the need to mention the name again.```pythonfrom feathers import *duster = ostrich("South Africa")```... or ...```pythonfrom feathers import ostrichduster = ostrich("South Africa")```  Pros & Cons**import _module_**- less maintenance of imports- can be tedious to type __module.foo__ but can get around this with `import module as mo` and `mo.foo`__from *module* import *item*__- less typing, more control over accessed items- to use a new item form the module must update import statement- less context (e.g. **ceil()** vs **math.ceil()**  Additional Notes & ResourcesAvoid using global variables - only use variables in the functions of the module.Remember - using `import *` can cause of lot of issues, which is why it is not suggested.Additional links:- [importing packages/modules of "Sister packages"](https://docs.python.org/3/tutorial/modules.htmlintra-package-references) (files in the same folder structure)- [Programmings FAQs:  Modules](https://docs.python.org/3/faq/programming.htmlmodules)  How Do I Run A Python File As A Program?In order to allow the module to be run as a script or program, you must add in this function:```pythonif __name__ == "__main__":     call whatever you need to here    pass```This is only run when the module is executed as the main file. If imported, it will **not** run.<jupyter_code># https://gist.github.com/christopherlovell/e3e70880c0b0ad666e7b5fe311320a62#file-display-py-L5
from IPython.display import HTML

# Youtube or Facebook embed
HTML('<iframe width="560" height="315" src="https://www.youtube.com/embed/W1Ywl4_Gsiw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1047808764940239, 'fraction_numerical': 0.01852589641434263, 'mean_word_length': 4.692743764172335, 'pattern_counts': {'":': 1, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 10, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '607576', 'license': 'MIT', 'n_tokens_mistral': 1450, 'n_tokens_neox': 1343, 'n_words': 600, 'path': 'Week_2/Python_Basics_16_-_Modules.ipynb', 'repo_name': 'ProsperousHeart/Basics-Boot-Camp', 'size': '5020'}