# Modules
When we first learn to code in Python, we use the interactive Python interpreter. If we quit from the interpreter and enter it again, the statements are lost.
Therefore, we start using a text editor (VS Code) to store our codes and running them as scripts. We also learn how to use functions to create modular pieces for our program. As our program gets longer and more complex, we may split it into multiple files for better maintenance.
To support this idea, Python allows us to use the definitions (functions and variables) from a file in another script or in an interactive Python interpreter. Such a file is called a module.
# Custom module
A module is not a lot different than a normal Python script. We can simply put the function and variable definitions in it and make those functions and variables accessible elsewhere.
For example, let's create a module file named fibonacci.py
and define two functions and a variable in it.
desc = "In mathematics, the Fibonacci numbers form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1."
def fib(n): # return Fibonacci sequence up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a + b
return result
def use_fib():
print(desc)
print()
n = int(input("where do you want the Fibonacci sequence to end by? "))
print(f"The Fibonacci sequence is {fib(n)}")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Then we can import
the module and use the definitions in it.
import fibonacci
print(fibonacci.desc)
2
3
Sometimes we can use only parts of a module by the from
keyword
from fibonacci import fib
print(fib(100))
2
3
We can rename the definitions with the as
keyword
from fibonacci import use_fib as func
func()
2
3
# Package
When we group multiple modules together, we create a package. Modules can be managed in hierarchical folders for easy maintenance, with the help of __init__.py
files.
Python considers folders that containing the __init__.py
file as packages. Sometimes, __init__.py
can be empty, but it can also run initialization codes if needed.
Here's the structure of a toy package.
foo
├── __init__.py
├── bar.py
└── baz
├── __init__.py
└── qux.py
2
3
4
5
6
We can import the whole package or individual modules.
import foo
import foo.bar
import foo.baz.qux
2
3
We may see usage of from package import *
. By default, Python would not import any module in package
.
However, we can define __all__
in __init__.py
to control what should be imported.
For example, when we define only "bar" in __all__
of foo/__init__.py
__all__ = ["bar"]
from foo import *
would import bar
.
However, you can still explicitly import baz
and its submodules.
import foo.baz
from foo.baz import qux
2
# Built-in Packages
Python is battery-included. It comes with various packages for different use cases.
Use the import
statement to import a package
import math
print(math.pow(2, 5))
2
3
To import only parts from a package, use the from
keyword.
from datetime import datetime
print(datetime.now())
2
3
To rename when we import a package, use the as
keyword
from datetime import datetime as dt
import math as m
print(m.pow(2, 5))
print(dt.now())
2
3
4
5
Do you remember the guessing game we talk about when learning the while
loop?
We can make it a real guessing game with some small changes.
Create a script named real_guessing_game.py
and copy-paste the following codes.
from random import randint
to_play = True
secret = str(randint(1, 100))
while to_play:
guess = input("what is the secret (1-100)? ")
if secret == guess:
to_play = False
print(f"You've got it!")
else:
print(f"Wrong guess :( it's {'smaller' if secret < guess else 'larger'}")
2
3
4
5
6
7
8
9
10
11
To run it, simply
python real_guessing_game.py
The random
module creates a real secret (random number within range 1 to 100) and we need to guess what it is.
how to guess effectively?
The program would tell us whether the guess is larger or smaller before we make the right guess. What's the best strategy to guess the random number?
# Python Package Index
The Python Package Index (PyPI) is a repository of software for the Python programming language.
To install a package from PyPI, we use pip
, the package management system.
For example, we can install Flask
to make web applications.
pip install Flask
Create a script (say, flask_app.py
) with the following lines of codes
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<h1>Hello, World!</h1>"
if __name__ == "__main__":
app.run()
2
3
4
5
6
7
8
9
10
11
12
Then we can start the web application by running the script.
python flask_app.py
The Python community is robust and growing rapidly. There are numerous packages for us to do amazing things in different domain.
For another example, we can create GUI interfaces with PyQt
pip install PyQt5
Create another script (say, qt_app.py
with the following statements)
from PyQt5.QtWidgets import QApplication, QLabel
app = QApplication([])
label = QLabel("Hello World!")
label.show()
app.exec()
2
3
4
5
6
7
8
Similarly we can start the GUI application by running the script.
python qt_app.py
# Assignment 13
Restructure your codes for Assignment 12.
Put all the definitions for different shape functions in a module called shapes
and use them in a new script called terminal_drawing2.py
.
You can refer to Assignment 12 for the sample run. They should be identical.
Sample Solution
The shapes.py
file has the definitions.
def square():
rows = int(input("Enter number of rows for the square: "))
row = 0
while row < rows:
if row == 0 or row == rows - 1:
print("*" * rows)
else:
print("*" + " " * (rows - 2) + "*")
row += 1
def triangle():
rows = int(input("Enter number of rows for the triangle: "))
for i in range(rows):
print(" " * (rows - i - 1) + "*" * (i + 1))
def plus():
while True:
rows = int(input("Enter number of rows for the plus: "))
if rows % 2:
break
i = 0
while i < rows:
if i != rows // 2:
print(" " * (rows // 2) + "*")
else:
print("*" * rows)
i += 1
def diamond():
while True:
rows = int(input("Enter number of rows for the diamond: "))
if rows % 2:
break
for i in range(0, rows // 2):
print(" " * (rows // 2 - i) + "*" * (2 * i + 1))
print("*" * rows)
for i in range(rows // 2 - 1, -1, -1):
print(" " * (rows // 2 - i) + "*" * (2 * i + 1))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
And the terminal_drawing2.py
imports and uses them.
from shapes import square, diamond, triangle, plus
mapping = {
"1": square,
"2": diamond,
"3": triangle,
"4": plus,
}
while True:
print("1: square")
print("2: diamond")
print("3: triangle")
print("4: plus")
selection = input("Enter your selection: ")
func = mapping.get(selection)
if not func:
print("Goodbye!")
break
func()
print()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# What do you want to create?
Brainstorm and find your passion. Let's discuss what to build 🔨 !