Python Worksheet 0: How to actually run it
8 Sep 2023 , by
Before we go deep into how to write programmes, we will look at the many ways we can actually run it. This will not only help us learn better by allowing us to experiment in different ways, but it will actually make this new skill more useful – because there will be more places to apply it.
1. The Python interpreter
This is the most basic way to run Python. Just open whichever terminal you have, and type in
$ python3
and you should be greeted with a version number, along with some other details like so:
Python 3.11.4 (main, Jun 20 2023, 16:59:59) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
Notice the hint given at the end: Type “help” for more info.
The cursor must be blinking at us, in front of three >
symbols.
This >>>
is called a prompt.
It’s prompting us for input.
We can type any valid python here, and press Enter
to execute it.
In a sense, this is all that there is to Python.
Say we declare some variables,
>>> a = 1
>>> b = 2
>>> c = a + b
>>> print(c)
3
Now we have some variables in our state.
If we then type exit()
or press Ctrl+D
then we exit Python,
and those variables are gone.
Typing python3
again and then entering print(c)
will no longer print 3.
It will instead complain that it doesn’t know anything called c
.
I encourage you to try it, just for the sake of getting familiar with that error message. It’s worth it.
So that’s the plain, classic Python interpreter. We can press the up and down arrow keys to navigate through older commands, left and right arrow keys to navigate within each command.
This interpreter is generally the easiest way to test out parts of bigger programmes, or just try something out quickly. Similarly, it’s is useful to check whether a command works as well.
For example, if we’ve installed the package numpy
and want to verify that , then we can easily run python3
and type in
import numpy
If this command does not result in an error, then we know that Python found a package called numpy
and was able to import it, ready for us to use.
2. Python scripts
Say I use numpy
to invert matrices.
It goes something like this:
>>> import numpy as np
>>> A = np.array([
... [2,0],
... [0,2]
... ])
>>> np.linalg.inv(A)
array([[0.5, 0. ],
[0. , 0.5]])
Isn’t that cool? Say every time I want to invert my matrix, I don’t want to type out all the commands again. Woudn’t it be nice to be able to store those commands in a file, and then ask Python to just run those commands line by line, as if we had typed them?
We can do that!
Open any text editor1, then type out those commands exactly as we typed them before
(don’t type any of the output it printed, just the input we gave it)
and then save that file.
It need not have a .py
extension.
As long as that file is readable, it doesn’t matter what extension it has,
but it’s convenient to be able to quickly identify that this file contains Python commands because of its .py
extension.
Our file should look something like this:
import numpy as np
A = np.array([[2,0], [0,2]])
np.linalg.inv(A)
Suppose this file is saved as inv.py
in the current directory.
Then running python3 inv.py
in the terminal should work.
Try it. What do you see? Nothing? Oh, right. We didn’t ask it to print anything.
That’s a notable difference between running in the interactive mode and running files. In the interactive mode, the return value of the command is printed out by default. It’s like a conversation: you ask something, you get a reply. On the other hand, while running the same commands through a file, the result of every expression isn’t printed out unless we ask it to.
And that makes sense. Files can have so many lines. If each line printed something out, how would we find what we actually wanted?
Can you modify the file so that it prints the inverse of A
?
3. Modules
In the above examples, we imported numpy as np
.
This was because we wanted to be able to use the features of the numpy
package.
It comes with useful data types like numpy.array
and useful functions like
numpy.linalg.inv
.
We can make packages of our own! When it’s a single file, it’s usually called a module, while a package is a collection of modules. In the underlying technology, there’s not much of a difference.
Create a new file with the following contents
pi = 3.141597
def perimeter(radius):
return 2 * pi * radius
r = 2
p = perimeter(2)
print(f"If radius of a circle is {r} then the perimeter is {p}")
# Don't miss the `f` before the quotes (") in the last line!
cd
to the directory where the file from the earlier section is saved,
and run python3
to launch the python interpreter.
Now in the interpreter, type import file
.
If your file is named foo.py
you need to say import foo
.
What do you see? The perimeter line is printed out, but that’s not all that has happened. The interpreter has gone through the file – including the definitons.
We can verify this by trying out print(foo.pi)
.
Again, if your file is not called foo.py
then you will have to modify the above command aaccordingly. (It’s good practice to have meaningful names – it takes very little time, and saves a ton.)
Now try foo.perimeter(2)
.
It should say a number close to 4π.
What is going on here is that import foo
will run the file called foo.py
(if it exists)
and remember all the definitions within a separate namespace, called foo
.
That’s why just perimiter(2)
doesn’t work outside of the file foo.py
, but foo.perimeter(2)
does if you have import
ed foo
.
Separate namespaces are important for avoiding conflicts.
For example, the module math
has a function called sin
and so does numpy
.
import
ing both still works, because math
’s sin
can be called by math.sin()
and numpy
s sin
can be called by numpy.sin()
.
So that’s another way of running Python programmes: through other programmes. But there are two issues.
One is that I don’t want to have to type the name of the module every time I call its function, or access its variables.
That’s easy to fix, and we know it already!
import numpy as np
now lets us access all Numpy functions through np.function()
instead of numpy.function()
.
Same works for variables/constants like np.pi
, of course.
The second issue is a little more complicated.
Whenever I am importing our tiny perimiter module,
I get an irrelevant sentence.
But say I don’t want to remove those two print statements from my programme.
I want to keep them if I run the programme on it’s own.
Sometimes we want a script to behave differently when it’s run on it’s own,
and differently when it’s run because of an import
.
This can be solved by looking at the value of __name__
like so:
pi = 3.141597
def perimeter(radius):
return 2 * pi * radius
if __name__ == "__main__":
# Name is __main__, so we are not in an import. Okay to print
print(f"If radius of a circle is {r} then the perimeter is {p}")
Save this as a file.
Now run python3 foo.py
and check if it is different from
import foo
.
There we have it! Three different ways to run python programmes. In fact, we even created our own module! That’s going to be handy soon, I hope!
-
Examples of text editors are Notepad, VS Code, Notepad++, gedit, vim ↩︎