Relative imports in Jupyter notebooks

How do we import a module from a .py or a .ipynb file into a Jupyter notebook from a different directory?
I wrote this post after answering a question on stackoverflow:

For example, if we have the directory structure:


How do we access the file or the notebook configuration_nb.ipynb?

The nbimporter module helps us here:

pip install nbimporter


class Configuration():
    def __init__(self):
        print('hello from')


import nbimporter
from src import configuration

new = configuration.Configuration()


hello from

We can also import and use modules from other notebooks. If you have configuration_nb.ipynb in the /src module:


class Configuration_nb():
    def __init__(self):
        print('hello from configuration notebook')


import nbimporter
from src import configuration_nb

new = configuration_nb.Configuration_nb()


Importing Jupyter notebook from ......\src\configuration_nb.ipynb
hello from configuration notebook

Using Python to detect activity in Sensory Software’s Grid 2

Update: March 2018. This work is being submitted to the Communications Matters conference.

Following on from the eyeBlink post, with the help of Fil at Beaumont, I modified the algorithm I’m using to detect when the Grid 2 or Grid 3 software is being used. The image below shows Sensory Software’s Grid 2 software being used to construct a sentence. The new text appears in the white area at the top of the window. Fil suggested that I change the Python script to just monitor this area at the top of the window. The script now looks for a change in the amount of black text in this area. After the usual software wrangling I think I got it working. The Python script looks at the top 20% of the window and counts the number of black pixels in this area. Every half second it recounts the number of black pixels. If there is a change in the number of black pixels above a threshold, then a trigger is sent to indicate that the Grid software is being actively used. I’m using a threshold of 20 pixels, so there needs to be an increase or decrease of 20 or more black pixels for a change to be detected. This allows you to move your mouse cursor around in the text area at the top of the Grid window without triggering that there has been a change. The activity detection script needs more testing, but preliminary results seem to show it works. Prior to this, I was monitoring the entire Grid window and looking for a change in the whole window above a threshold. This led to false triggers when cells were selected, but not activated. When a cell is selected, the colour of the cell changes, even when it is not activated to produce text. This change in colour was being detected.

Each time we test the script, we find new ways to break it, leading to some ‘try except’ exception handling clauses. The script is designed to run on Windows as Grid 2 and Grid 3 only work on this operating system. I use the win32gui library to interact with Windows and the python imaging library, PIL (known as pillow), to do the image processing.
Sensory Software’s Grid 2 Chatterbox grid being used to construct a sentence:
Grid 2 communications software by Sensory Software used to create speech.
The latest code and installation details on how to get this running using the BBC microbit to give a flash when the Grid software is being actively used can be found on my github site at:
If you have any questions, please ask.

Running pytest when the test files are in a different directory to the source files

I had a battle to get my testing directory structure to work outside of an IDE. Please find my solution below. Tested on Windows 7 using python 3.6 and Linux Mint using python 3.4, running the code using the command line:

python -m pytest

The file I wrote to be tested is called in a directory named \src. The file containing tests to be run using pytest is called in a subdirectory \tests, so the full directory path is \src\tests. I needed to add a file called to the \src\tests directory. This file is used in to enable access to in the directory above. The files are empty.

Directory structure:


\src\tests contains the script to be tested.

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import compress_files  

The line:

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__)

comes from the suggestion at the hitch hikers guide to python at:

This adds the path of the directory above the /src/tests directory to sys.path, which in this case is /src.

import os
import pytest
from .context import compress_files
from compress_files import *

# tests start here

I put this up as an answer to a stackoverflow question here.

Sending parameters to a Jupyter Notebook cell using click

Using libraries such as click and optparse we can send parameters to Python scripts when we run them from the command line. For example, passing a parameter called count with a value of 2 to a script called --count=2

How can I replicate this functionality in a cell of a Jupyter notebook? I like to run the same code in the notebook so that I can easily copy it to a stand alone script. Using sys.argv to pass parameters to the main function seemed one way to go and works with optparse:

from optparse import OptionParser
import sys

def main():
    parser = OptionParser()
    parser.add_option('-f', '--fake',
                help='Fake data')
    (options,args) = parser.parse_args()
    print('options:{} args: {}'.format(options, args))
    if options.fake:
        print('Fake detected')
def test_args():
if __name__ == '__main__':

    sys.argv = ['--fake', 'True' '--help']


options:{'fake': 'False'} args: ['True--help']

Fake detected

Click seems to be flavor of the month, but I kept on getting a screen full of errors when I tried to run click through a Jupyter notebook cell. If we consider the Click example code:

import click

@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
            help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':

If this file is called, then running from a command line: 'Max' --count=3 

Gives this output:

Hello Max!

Hello Max!

Hello Max!

But using the same sys.argv trick that works with optparse produces a screen full of errors when the same code is run from a Jupyter notebook cell. The solution is to put the %%python magic at the start of the cell:


import sys
import click

@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
            help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    with open('echo.txt', 'w') as fobj:
        for x in range(count):
            click.echo('Hello %s!' % name)

if __name__ == '__main__':
    # first element is the script name, use empty string instead
    sys.argv = ['', '--name', 'Max', '--count', '3']

A small tip, but one which cost me an hour or two of pondering. Finally I asked the hive mind of Stackoverflow. Please see this stackoverflow solution.

Bash script to mount and unmount a BBC Micro:bit

I develop using the BBC Micro:bit (which I’ll call a microbit from now on) using Linux. To get a new hex file on to the microbit, the microbit has to be mounted on to the file system. Which may seem obvious. But the microbit has a habit of unmounting itself after being programmed. Or not mounting when it is plugged in. So I wrote a script to make things easier. Because I can. To be more accurate, I copied a script from Stackoverflow and made a few minor modifications. Don’t pretend this isn’t how you have written a lot of your scripts.
Find the code at the bottom of this post. Copy and paste it to a file called Make the file executable (chmod +x ./ and run using either ‘mount’ or ‘unmount’ as an argument. I’ve got these aliased to ‘mm’ and ‘md’ in my .bashrc.

Example usage:

bill@bill ~ $ mount

found one MICROBIT, device: /dev/sdb
MICROBIT was unmounted
Mounted /dev/sdb at /media/bill/MICROBIT.

bill@bill ~ $ unmount

found one MICROBIT, device: /dev/sdb
MICROBIT was mounted
Unmounted /dev/sdb.

Comments and improvements welcome. The script is:

# mount and unmount microbit
# modified from>
# v1.0 matt oppenheim October 2017

if [ $# -eq 0 ] 
    echo "no argument supplied, use 'mount' or >
    exit 1

# how many MICRO found in udiksctl dump
RESULTS=$(udisksctl dump | grep IdLabel | grep >

0 )     echo "no $MICRO found in 'udkisksctl du>
        exit 0

        # if [[ -z $(mount | grep "$DEVICE") &&>
        if [[ -z $(mount | grep "$DEVICE") ]]
            echo "$DEVICELABEL was unmounted"
            if [ $1 == "mount" ]
                udisksctl mount -b "$DEVICE"
                exit 0
                echo "$DEVICELABEL was mounted"
                if [ $1 == "unmount" ]
                    udisksctl unmount -b "$DEVI>
                    exit 0

Getting the BBC Micro:bit radio to work with the mbed online C/C++ compiler

This blog explains how to get the example programs for working with the non-Bluetooth radio on the BBC Micro:bit to compile correctly using the Mbed online C/C++ compiler.

Short story

Two options:

1 Place the line:


in the MicroBit.h library and forget about the config.json file.


2 Create an mbed_app.json file instead of the config.json file with this content:

"macros": [ "MICROBIT_BLE_ENABLED=0" ]

Long story

The Mbed online compiler and the yotta offline compiler for the BBC Micro:bit are explained at the Lancaster University github site here:

I couldn’t get the example radio programs supplied with the online Mbed C/C++ compiler to work with the BBC Micro:bit. These programs did work with the yotta offline compiler. It took a while to figure out that the config.json file supplied with the examples is being ignored by the Mbed online compiler. The BBC Micro:bit has a custom radio setup which does not work when Bluetooth is enabled. The compiler needs to be told that Bluetooth is disabled. In the examples supplied for both the yotta offline compiler and for the mbed online compiler this is done using a config.json file containing:

            enabled: 0 

The example programs are called simple-radio-rx and simple-radio-tx. For the Mbed online compiler, these can be found at:

For the offline yotta compiler the same programs and config.json files can be found at:

The hex files created using the Mbed online compiler resolutely refused to do anything when I loaded them onto the microbits. I figured out that the the config.json file was being ignored by the Mbed online compiler. To disable the Bluetooth through code, place this line:


in the MicroBit.h library. After doing this, the hex files produced by compiling the example programs using the Mbed online compiler ran correctly.

I posted this on the Mbed questions site and an Mbed moderator said that the issue will be fixed:

A while later, a helpful guy on Stackoverflow advised me to use an mbed_app.json file instead of the config.json file with this content:

    "macros": [ "MICROBIT_BLE_ENABLED=0" ]

Setting up yotta and C with the BBC Micro:bit by modifying the examples directory

I set up to program the BBC Micro:bit (which I’ll call the microbit from now on) in C/C++ under Linux. I’ve been using micropython to program the boards up to now, but want to leverage the increased performance that using C can give and some of the C libraries that are available for e.g. encryption.

There is good documentation on the Lancaster University microbit github page:

I installed the offline tools as I spend a lot of time working at sea where you can’t always rely on having an internet connection. I got a demo compiled and loaded by following the instructionso n the Lancaster University github site. Now it was time to write my own code. I had a little trouble getting this going, so here’s what I had to do to get my first program compiled and loaded. I did this by modifying the structure of the examples directory that was created by following the github instructions.

I downloaded the github repository linked above into


Initially I made a new directory under:


Whenever I ran ‘yt build’, I got a weird error referring to one of the bluetooth example programs. Plus yt build took longer than I thought it ought to. So…..



out of:


Put these folders one level above this folder. Only put the main.cpp file into


Then run:

yt clean


yt build

I copied the file:


to the microbit. After waiting for the flashing LEDs to stop, it worked!

The microbit unmounts itself each time that you load a new hex file. So using the bash script that I detailed in an earlier blog to quickly mount the microbit is a time saver.

This is a quick way of getting started by building on top of the examples directory that most folk will start with.

disclaimer: I loiter in the same department as the authors of the C/C++ BBC Micro:bit repository.

Enabling the analog to digital converter (ADC) on the BBC Micro:bit using C/C++

To get the example ADC code to work on the Lancaster Github site, change the line:




I tested this using both the online Mbed compiler and the yotta compiler.

eyeBlink – enabling natural two way conversation with somebody who uses an eyetracker

It can be difficult to tell when a student who uses an eye tracker to operate their communications software is actively using the software. So the temptation is to go and look over their shoulder. The Head Technologist at Beaumont College asked if it is possible to have a light flash to indicate when the communications software is being used. This makes for a more natural two way conversation. You talk to the student and you see the light flashing, so you know that a reply is being composed.

After some false starts, I think I have some code that will detect when the software is being used. My script makes an image of the screen each second and looks for a difference. I set a minimum threshold for the difference between the images so that a blinking cursor will not continuously indicate a change.
I use a BBC micro:bit to do the flashing as they are cheap, cheerful and reliable. I reckon to have two of these qualities.
Please find a picture of Craig, one of the technologists at Beaumont, testing the prototype of the eyeBlink system using a Tobii eyetracker and Sensory Software’s Grid 2 software. You will have to take my word for it that the microbit does indeed flash when the Grid 2 is being used.
Craig testing the eyeBlink hardware at Beaumont College, Lancaster.

Booting a new Lenovo Thinkpad from USB stick to use Clonezilla

All I wanted to do was boot from my trusty Clonezilla USB stick to make a system back up of my shiny new Thinkpad X260. Long story short, you need to disable the ‘Secure Boot’ option in the UEFI (what used to be called BIOS) to boot from a bootable Clonezilla USB stick.

I bought the X260 a couple of month’s ago. This is last year’s model, so I got it at a discount. Usually I’d buy a 2/3 year old Thinkpad and replace the drive and keyboard, but found I could buy a new laptop, albeit last year’s model for about half of what it would’ve cost a year ago. A quick cleansing of the OS by installing Linux Mint. The usual kerfuffle to configure the system and remember how to partition the drive, then try to remember how to mount said partitions. Time to make an image of the OS partition. I’ve learned this is a good idea the hard way. When I tried to boot from my Clonezilla USB sticks, none of them would work! Somehow I had made a bootable USB stick that would install Linux Mint. I spent a good hour before checking on the ‘Secure Boot’ option in the UEFI screen, which by default is Enabled. Flicking this to Disabled solved this issue. 
Now I have an image of my OS on an external drive for when I manage to destroy the installation. Not if. When. Still, that’s how we learn, by breaking and fixing. Probably a good thing that I don’t work in medicine.