<jupyter_start><jupyter_text>ModulesPython provides many built-in **functions**, such as `print()` and `len()`, and **classes**, such as **string** and **dictionary**.These are functionalities that are required in more or less every Python program, so they are always accessible.You have been defining new custom **functions** and **classes** in all the programs that you have written so far.However, the lifetime of each definition was only the program where it was written.If you had to use the same **function** in a second program, you had to write it again.**Modules** provide a way for organizing your code and being able to access to it from other programs.  Create your module**Modules** are just Python files that contain definitions of **functions** and **classes**. This directory contains a file named `fancy_module.py`. Open it and you will see that it contains the definition of a **function** named `sum_numbers()`. This is a very simple **module** made only of 1 definition.You can `import` the **module** to have access to that definition in a code block here.Then you can use the same syntax that you used for **methods** to call a **function** defined in the **module**.To call the **function** you have to use the name of the **module** followed by a dot `.` and by the name of the **function**.Some recommendations: - Modules are Python files and, as such, they require the extension `.py` in their name. - When working with a module (i.e. importing it or calling a function from it), you don't have to specify the extension, but only the name. The extension is only used by Python to know that it can process that file. - Always write `import` statements at the beginning of your program. This will make sure that definitions are already available when you want to use them. - Give meaningful names to the definitions in a module, as you will want to quickly understand what they do and to be able to re-use them.<jupyter_code>import fancy_module # Import the module

x = fancy_module.sum_numbers(1, 2) # Use a function from the imported module
print(x)<jupyter_output><empty_output><jupyter_text>A **module** is just a regular Python file.In order to create a new **module** within the Jupyter environment, you should open the directory where this lesson is present, then click `New` on the top right, and select `Text file`.You will have to rename this file into `something.py`, where `something` will be the name of your **module**.Don't forget the `.py` extension.  ExerciseCreate a new Python module in this directory. This module should provide the definition of: - a function that takes a string as input and returns the number of occurrences of the most occurring character in it. - a class that contains a dictionary in its state. The class should provide a method for updating the dictionary that takes a key as input and checks if it's already present in the dictionary or not. If it is not, it should create a new key-value pair using that key and assigning 10 as value. On the other hand, if it is already present, it should double the value associated with the provided key. The class should also provide a method that returns the key of the dictionary with the highest value.Import the module in the following code block.Create an object of the class and call the function on all the provided input strings.Use the returned values to update the dictionary using the first method provided by the created object.Check which character was the most occurring one among all the strings by using the second method provided by the created object.Hint: use the constructor function imported from a module.<jupyter_code># Input strings
a = "a"
b = "hello"
c = "area"<jupyter_output><empty_output><jupyter_text>The `math` moduleBesides the standard built-in definitions, Python also allows to use more specialized **functions** and **classes**, such as advanced mathematical operations, tools for drawing and much more.These additional functionalities are organized into Python **modules** as the one you created in the previous section.There are literally thousands and thousands of these **modules** created by developers across the world.In order to use these **modules** you have first to install them into your computer and then you are able to `import` them as done before.Note that the most popular **modules** are automatically installed together with Python, so they can be imported right away.Python always provides a **module** named `math` that defines many useful mathematical operations.For example, you may be interested in computing the square root of a number or its base 10 logarithm.Searching for this module in a Web Search Engine, should allow you to find its documentation at the following link: https://docs.python.org/3/library/math.html.Have a look at the link to see what is defined in the `math` **module**.You will see many **functions**, characterized by their name, their input parameters and a short description of what they do.You will not see the body of the **functions**. That's because this is not relevant in order to allow you to use the **function** and adding it would make impossible a quick analysis of the **module**.   ExerciseImport the math module and use the `gcd()` function for computing the greatest common divisor between the two input numbers.See the documentation for this function here: https://docs.python.org/3/library/math.htmlmath.gcd<jupyter_code># Input values
x = 16
y = 24<jupyter_output><empty_output><jupyter_text>Alternative import syntaxWhat you have done so far with the syntax `import math` is importing the whole `math` module into your Python program.Python provides also alternative syntaxes for achieving the same result.<jupyter_code># Import a whole module
import math
x = math.log(20)
print(x)

# Import a whole module using an alias
import math as m
x = m.log(20)
print(x)

# Import a single function from a module
from math import log
x = log(20)
print(x)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06461846718984805, 'fraction_numerical': 0.003172482885289698, 'mean_word_length': 4.866797257590598, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 2, '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': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '440674', 'license': 'MIT', 'n_tokens_mistral': 1434, 'n_tokens_neox': 1396, 'n_words': 907, 'path': '11_modules/modules.ipynb', 'repo_name': 'alsora/python3-course-notebooks', 'size': '5989'}