Skip to content

Instantly share code, notes, and snippets.

@MatrixManAtYrService
Last active May 23, 2024 19:32
Show Gist options
  • Save MatrixManAtYrService/7f40fd38b610cf138db3a994f2a6824f to your computer and use it in GitHub Desktop.
Save MatrixManAtYrService/7f40fd38b610cf138db3a994f2a6824f to your computer and use it in GitHub Desktop.
Challenge 4

Some more of the standard library

You already know something about sys and pathlib. Now it's time to learn about venv.

venv creates virtual environments (which are a more lightweight than a virtual machine, but they're similar in how they isolate their contents from the rest of your system. This lets us install third-party libraries in a sane way. If you don't use them, things get cluttered quickly.

Please read/watch the following:

Going beyond the standard library

In this challenge, we'll explore ipython and rich. These libraries are not in the standard library, you'll have to install them.

We'll be putting rich in a venv.

We'll be running ipython outside of a venv (unless your system python is weird for some reason, then we'll also run ipython in a venv).

ipython includes an executable component, so once it's installed, you'll be able to run it like:

$ ipython

Or like this:

$ python -m ipython

venv (which is already installed because it is part of the standard library) also has an excutable component, but unlike ipython, it doesn't bother add itself to your path, so you have to run it like this:

$ python -m venv

ipython is one of the very few things that I like to install system-wide (not in a venv). I use it as a calculator, and as a way to answer questions about python code which has no external dependencies.

If I ever refer to some python code and say:

try it

I probably mean:

type it into an ipython shell and see what happens

Please follow along with the commands in the next section. There I will show how to install, use, and exit ipython. It has many awesome features, most of which we will ignore for now.

If your system-installed python isn't making that easy, go ahead and do it in a venv instead.

$ python -m ipython
bash: ipython: command not found
$ pip install ipython
Collecting ipython
Downloading ipython-8.24.0-py3-none-any.whl.metadata (4.9 kB)
Collecting decorator (from ipython)
Downloading decorator-5.1.1-py3-none-any.whl.metadata (4.0 kB)
Collecting jedi>=0.16 (from ipython)
Downloading jedi-0.19.1-py2.py3-none-any.whl.metadata (22 kB)
Collecting matplotlib-inline (from ipython)
Downloading matplotlib_inline-0.1.7-py3-none-any.whl.metadata (3.9 kB)
Collecting prompt-toolkit<3.1.0,>=3.0.41 (from ipython)
Downloading prompt_toolkit-3.0.43-py3-none-any.whl.metadata (6.5 kB)
Collecting pygments>=2.4.0 (from ipython)
Downloading pygments-2.18.0-py3-none-any.whl.metadata (2.5 kB)
Collecting stack-data (from ipython)
Downloading stack_data-0.6.3-py3-none-any.whl.metadata (18 kB)
Collecting traitlets>=5.13.0 (from ipython)
Downloading traitlets-5.14.3-py3-none-any.whl.metadata (10 kB)
Collecting pexpect>4.3 (from ipython)
Downloading pexpect-4.9.0-py2.py3-none-any.whl.metadata (2.5 kB)
Collecting parso<0.9.0,>=0.8.3 (from jedi>=0.16->ipython)
Downloading parso-0.8.4-py2.py3-none-any.whl.metadata (7.7 kB)
Collecting ptyprocess>=0.5 (from pexpect>4.3->ipython)
Downloading ptyprocess-0.7.0-py2.py3-none-any.whl.metadata (1.3 kB)
Collecting wcwidth (from prompt-toolkit<3.1.0,>=3.0.41->ipython)
Downloading wcwidth-0.2.13-py2.py3-none-any.whl.metadata (14 kB)
Collecting executing>=1.2.0 (from stack-data->ipython)
Downloading executing-2.0.1-py2.py3-none-any.whl.metadata (9.0 kB)
Collecting asttokens>=2.1.0 (from stack-data->ipython)
Downloading asttokens-2.4.1-py2.py3-none-any.whl.metadata (5.2 kB)
Collecting pure-eval (from stack-data->ipython)
Downloading pure_eval-0.2.2-py3-none-any.whl.metadata (6.2 kB)
Collecting six>=1.12.0 (from asttokens>=2.1.0->stack-data->ipython)
Downloading six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Downloading ipython-8.24.0-py3-none-any.whl (816 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 816.5/816.5 kB 5.2 MB/s eta 0:00:00
Downloading jedi-0.19.1-py2.py3-none-any.whl (1.6 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 13.8 MB/s eta 0:00:00
Downloading pexpect-4.9.0-py2.py3-none-any.whl (63 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63.8/63.8 kB 3.2 MB/s eta 0:00:00
Downloading prompt_toolkit-3.0.43-py3-none-any.whl (386 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 386.1/386.1 kB 9.5 MB/s eta 0:00:00
Downloading pygments-2.18.0-py3-none-any.whl (1.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 13.9 MB/s eta 0:00:00
Downloading traitlets-5.14.3-py3-none-any.whl (85 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 85.4/85.4 kB 4.4 MB/s eta 0:00:00
Downloading decorator-5.1.1-py3-none-any.whl (9.1 kB)
Downloading matplotlib_inline-0.1.7-py3-none-any.whl (9.9 kB)
Downloading stack_data-0.6.3-py3-none-any.whl (24 kB)
Downloading asttokens-2.4.1-py2.py3-none-any.whl (27 kB)
Downloading executing-2.0.1-py2.py3-none-any.whl (24 kB)
Downloading parso-0.8.4-py2.py3-none-any.whl (103 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.7/103.7 kB 5.0 MB/s eta 0:00:00
Downloading ptyprocess-0.7.0-py2.py3-none-any.whl (13 kB)
Downloading pure_eval-0.2.2-py3-none-any.whl (11 kB)
Downloading wcwidth-0.2.13-py2.py3-none-any.whl (34 kB)
Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: wcwidth, pure-eval, ptyprocess, traitlets, six, pygments, prompt-toolkit, pexpect, parso, executing, decorator, matplotlib-inline, jedi, asttokens, stack-data, ipython
Successfully installed asttokens-2.4.1 decorator-5.1.1 executing-2.0.1 ipython-8.24.0 jedi-0.19.1 matplotlib-inline-0.1.7 parso-0.8.4 pexpect-4.9.0 prompt-toolkit-3.0.43 ptyprocess-0.7.0 pure-eval-0.2.2 pygments-2.18.0 six-1.16.0 stack-data-0.6.3 traitlets-5.14.3 wcwidth-0.2.13
$ python -m ipython
Python 3.12.3 (main, May 14 2024, 07:23:41) [GCC 12.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.24.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: print("hello")
hello
In [2]: exit
$

Making sure you're set up for the challenge

Below is a python script which depends on rich. Try to run it, it will probably fail.

Next, create a python venv, activate it, install rich (pip install rich), and run your script in that venv. You should see colored text.

from rich import print
print("Hello, [bold magenta]World[/bold magenta]!")

Some Context

A word on requirements.txt

requirements.txt is a casual way of communicating your project's dependencies to others. It's better than nothing, and we'll use it for now. Many people (scientists, students, etc) never graduate past requirements.txt.

The problem is that it requires the user (or the other developers) to create and manage the venv themselves. That becomes obnoxious if everybody doesn't manage their virtual environments in exactly the same way. So later on, we'll learn poetry which handles these things for you.

Feel free to get comfy with using venv, but know that it's the water-wings of python dependency management. We'll learn poetry later, then you'll be prepared to collaborate with others without cluttering up your README files with explanations of how to use venv with your particular project.

A word on rich

Unlike ipython, rich has no executable component. Whether you're in a venv or not, whether rich is installed or not, this will likely fail:

(venv) $ rich

rich is designed to be imported. So you can test for its presence like this:

(venv) $ python -c 'import rich'

Or like this

(venv) $ pip freeze | grep rich
rich==13.7.1

When you install rich, pip also installs all of the packages that rich depends on. That's why there are more packages than just rich in the output of pip freeze.

In the previous section that there are alternatives to requirements.txt. Don't worry too much about understanding the whole file, but take a look at rich/pyproject.toml. That's where rich defines its dependencies.

The Challenge

  1. create a new repo called "challenge4"
  2. add a requirements.txt (read about those here)
  3. add colored.py

I should be able to use your repo like this:

$ git clone git@github.com:{youruser}/{yourrepo}.git
$ cd {yourrepo}
$ python -m venv venv
$ . venv/bin/activate
(venv) $ pip install -r requirements.txt
(venv) $ python colored.py word to your mom red
    word to your mom
(venv) $ python colored.py word to your mom blue
    word to your mom

The text "word to your mom" should be displayed in red for the first invocation, and blue in the second.

Hints

  • sys.argv is a list, confirm this like so:
$ ipython
In [1]: import sys

In [2]: type(sys.argv)
Out[2]: list
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment