# From a user perspective, modules are variables, functions, objects etc.
import math
# This line "imports" the math module, so that we can refer to it
math.log10(100)
# Now we're calling a function from the math module to compute log_10(100)
To recap, the namespace is all identifiers available to a line of code
Namespaces are organized hierarchically into sub-pieces using modules, functions, and classes
If you want to use a function from another module you need to import it into the namespace of your code and use '.' notation
import math # Imports the math module into the current namespace
# The '.' syntax is a way of indicating membership
math.sqrt(2) # sqrt is a function that "belongs" to the math module
# (Later we'll see this notation reused with objects)
from math import sqrt
sqrt(2.0) # Now sqrt is a just a function in the current program's name space,
# no dot notation required
from math import * # Import all functions from math
# But, this is generally a BAD IDEA, because you need to be sure
# this doesn't bring in things that will collide with other things
# used by the program
log(10)
# More useful is the "as" modifier
from math import sqrt as square_root # This imports the sqrt function from math
# but names it square_root. This is useful if you want to abbreviate a long function
# name, or if you want to import two separate things with the same name
square_root(2.0)
help('random')
You can write your own modules:
Create a file whose name is x.py, where x is the name of the module you want to create
Edit x.py to contain the functions you want
Create a new file y.py in the same directory and include "import x" at the top of y.py
You may write a program and then want to reuse some of the functions by importing them into another program.
The problem is that when you import a module it is executed.
Question: How do you stop the original program from running when you import it as a module?
Answer: By putting the logic for the program in a "main()", which is only called if the program is being run by the user, not imported as a module.
It is easy to rush and write poorly-structured, hard-to-read code. However, generally, this proves a false-economy, resulting in longer debug cycles, a larger maintenance burden, and less code reuse.
Although many sins have nothing to do with the cosmetics of the code, some can be fixed by adopting a consistent, sane set of coding conventions. Python did this with Python Enhancement Proposal (PEP) 8
Use print statements dotted around the code to figure out what code is doing at specific points of time
Use a debugger - this allows you to step through execution, line-by-line, seeing what the program is up to at each step.
Write unit-tests for individual parts of the code
Use assert to check that expected properties are true
STARE HARD AT IT! Semantic errors will generally require you to question your program's logic.