The Python Audio Cookbook Recipes For Audio Scripting With Python Alexandros Drymonitis instant download
The Python Audio Cookbook Recipes For Audio Scripting With Python Alexandros Drymonitis instant download
https://ebookbell.com/product/the-python-audio-cookbook-recipes-
for-audio-scripting-with-python-alexandros-drymonitis-53851322
The Python Apprentice Robert Smallshire Austin Bingham And Sixty North
https://ebookbell.com/product/the-python-apprentice-robert-smallshire-
austin-bingham-and-sixty-north-46856626
https://ebookbell.com/product/the-python-workshop-write-python-code-
to-solve-challenging-realworld-problems-2nd-edition-2nd-edition-corey-
wade-47257520
https://ebookbell.com/product/the-python-quiz-book-michael-
driscoll-49153292
https://ebookbell.com/product/the-python-apprentice-a-practical-and-
thorough-introduction-to-the-python-programming-language-robert-
smallshire-austin-bingham-50194552
The Python Book Rob Mastrodomenico
https://ebookbell.com/product/the-python-book-rob-
mastrodomenico-51685086
The Python Advantage Python For Excel In 2024 Hayden Van Der Post
https://ebookbell.com/product/the-python-advantage-python-for-excel-
in-2024-hayden-van-der-post-54837502
https://ebookbell.com/product/the-python-automation-cookbook-a-recipe-
guide-to-automate-your-life-bisette-56039642
The Python Bible For Beginners The Stepbystep Roadmap For Aspiring
Programmers To Achieve Coding Mastery And Unlock Rewarding Tech
Careers Pacey Islas
https://ebookbell.com/product/the-python-bible-for-beginners-the-
stepbystep-roadmap-for-aspiring-programmers-to-achieve-coding-mastery-
and-unlock-rewarding-tech-careers-pacey-islas-56502436
https://ebookbell.com/product/the-python-for-finance-handbook-
unlocking-financial-insights-with-python-hayden-van-der-post-vincent-
bisette-57116210
The Python Audio Cookbook
The Python Audio Cookbook offers an introduction to Python for sound and multimedia
applications, with chapters that cover writing your first Python programs, controlling Pyo with
physical computing, and writing your own GUI, among many other topics.
Guiding the reader through a variety of audio synthesis techniques, the book empowers
readers to combine their projects with popular platforms, from the Arduino to Twitter, and state-
of-the-art practices such as AI. The Python Audio Cookbook balances accessible explanations
for theoretical concepts, including Python syntax, audio processing and machine learning, with
practical applications.
This book is an essential introductory guide to Python for sound and multimedia practitioners,
as well as programmers interested in audio applications.
Alexandros Drymonitis is a sound and new media artist. He has a PhD in the creation of
musical works with the programming language Python. His artistic practice focuses on new
techniques utilising new media such as computer programming, live coding, AI, or even older
practices, like modular synthesis.
The Python Audio Cookbook
Recipes for Audio Scripting with Python
Alexandros Drymonitis
Designed cover image: © pressureUA / Getty images
First published 2024
by Routledge
4 Park Square, Milton Park, Abingdon, Oxon OX14 4RN
and by Routledge
605 Third Avenue, New York, NY 10158
Routledge is an imprint of the Taylor & Francis Group, an informa business
© 2024 Alexandros Drymonitis
The right of Alexandros Drymonitis to be identified as author of this work has been asserted
in accordance with sections 77 and 78 of the Copyright, Designs and Patents Act 1988.
All rights reserved. No part of this book may be reprinted or reproduced or utilised in any
form or by any electronic, mechanical, or other means, now known or hereafter invented,
including photocopying and recording, or in any information storage or retrieval system,
without permission in writing from the publishers.
Trademark notice: Product or corporate names may be trademarks or registered trademarks,
and are used only for identification and explanation without intent to infringe.
British Library Cataloguing-in-Publication Data
A catalogue record for this book is available from the British Library
Library of Congress Cataloging-in-Publication Data
Names: Drymonitis, Alexandros, author.
Title: The Python audio cookbook : recipes for audio scripting with Python / Alexandros
Drymonitis.
Description: Abingdon, Oxon ; New York : Routledge, 2023. | Includes bibliographical
references and index. | Identifiers: LCCN 2023030282 (print) | LCCN 2023030283 (ebook) |
ISBN 9781032480114 (paperback) | ISBN 9781032480145 (hardback) |
ISBN 9781003386964 (ebook)
Subjects: LCSH: Python (Computer program language) | Computer sound processing. |
Software synthesizers.
Classification: LCC ML74.4.P97 D78 2023 (print) | LCC ML74.4.P97 (ebook) |
DDC 780.285—dc23/eng/20230829
LC record available at https://lccn.loc.gov/2023030282
LC ebook record available at https://lccn.loc.gov/2023030283
ISBN: 978-1-032-48014-5 (hbk)
ISBN: 978-1-032-48011-4 (pbk)
ISBN: 978-1-003-38696-4 (ebk)
DOI: 10.4324/9781003386964
Typeset in Times New Roman
by Apex CoVantage, LLC
To Katia and Alina
Contents
Acknowledgements xiii
Glossary xiv
1 Getting Started 1
1.1 Installing Python 2
1.2 Installing Python’s Package Manager 3
1.2.1 Searching Modules with Pip 4
1.2.2 Uninstalling Modules with Pip 4
1.3 Installing an Integrated Development Environment 5
1.4 Installing Pyo 6
1.4.1 Installing Pyo with Pip 6
1.4.2 Compiling Pyo from Sources 7
1.5 Coding Conventions 8
1.6 Conclusion 9
Bibliography 9
Conclusion 295
Index 296
Acknowledgements
I would like to thank Olivier Bélanger, the developer of the Pyo module for DSP in Python, as
this book is based entirely on this module. Apart from the development of Pyo, I would also
like to thank him for supporting its community and updating this module with new features.
Pyo is a free and open-source module that Olivier is developing in his free time. I hope this
book will help to expand the Pyo community, as this software deserves more attention than it
currently gets.
Hannah Rowe and Emily Tagg from Routledge have been very helpful and friendly and re-
plied promptly to any queries I had during the writing of this book.
I would like to thank Anton Mikhailov for providing code for the drum machine project in
Chapter 3.
Louizos, Terry, and Yannis helped me out by trusting me with their computers so I could
test things out.
Glossary
A
ADSR Acronym for Attack – Decay – Sustain – Release, the four stages of a standard ampli-
tude envelope that simulates the amplitude envelope of acoustic instruments
API Acronym for Application Programming Interface. An API is a set of rules that enables
different applications to communicate with each other.
Additive Synthesis Computer music synthesis technique, where simple tones with no or a
few harmonics, like sine waves, are added together, to create a more complex waveform.
Aliasing An effect that occurs in digital audio, when a frequency higher than half the sam-
pling rate (called the Nyquist frequency) is attempted to be produced by an oscillator. Since
each oscillation cycle requires at least two points to be sampled, the highest frequency that
can be produced is half the sampling rate. When a frequency higher than that is attempted
to be produced, the computer samples less frequently than required, resulting in a tone
being produced with a pitch lower than the Nyquist frequency, as much as the attempted
frequency is higher than that.
Amplitude Modulation (AM) Computer music synthesis technique where an oscillator of
(usually) a low frequency modulates the amplitude of a sound source.
Arduino Electronics prototyping board and programming language for physical computing.
Enables the user to utilise sensors in their projects, but also to control elements like motors,
lights, solenoids and others, through computer software.
Asynchronous Type of Granular Synthesis, where grains are being triggered sparsely instead
of at regular intervals, resulting in a more spread sound.
B
Baud The speed at which data is sent over a communication channel. Named after its inven-
tor, Émile Baudot.
Backend Part of software not visible to the user, usually referred to as the data access layer.
Opposite of frontend, usually called the presentation layer, which is the part of the software
visible to the user.
Band-limited Term referring to oscillators that have a fixed number of harmonics, usually
created with Additive Synthesis.
Bandpass Type of filter that lets a band around its cutoff frequency to pass, while frequencies
on either side of its band are attenuated. The width of the band is controlled by the Q.
Bipolar Refers to oscillators whose amplitude alternates between positive and negative. These
oscillators are used for audio, whereas unipolar oscillators are used for control.
Glossary xv
Bit depth The number of bits used to represent amplitude samples of audio. The more bits
used, the greater the dynamic range of an audio signal. The bit depth also determines the
signal-to-noise ratio (SNR) in a signal.
Boolean Data type that is common among programming languages, named after the math-
ematician George Boole. A Boolean value can be either True or False.
Buffer size The number of samples stored in an audio system, before these are processed, also
referred to as the block size.
C
C A general-purpose programming language developed by Dennis Ritchie at Bell Labs, in the
early 1970s. It is used by many operating systems and software engineers. It is a common
language among audio processing environments.
C++ A general-purpose programming language developed in the 1980s by Bjarne Stroustrup,
as an extension to C.
Carrier The sounding oscillator in various synthesis techniques like Frequency Modulation,
Ring Modulation, Amplitude Modulation, and Phase Modulation.
Casting Technique that changes the type of a datum, used in languages like C and C++.
Class Abstraction of code that creates a structure with variables and methods, inherent to
instances of the class that are created when a program runs.
Compiler A computer program that translates computer code written in one programming
language, to another, low-level programming language, referred to as machine code. The
latter is used to create an executable program.
Cross-synthesis Synthesis technique that mixes the amplitudes of one sound source, with the
frequencies of another.
D
DFT Discrete Fourier Transform. An algorithm that outputs a discrete-frequency spectrum
from a short sound segment. Named after the French mathematician and physicist Jean-
Baptiste Joseph Fourier
Directory A place in a computer file system with a tree-structure. A directory is similar to, and
often inter-changeable with the concept of the folder, which is used to organise the files in
a computer system. A directory might contain files or other directories. The root directory
in a file system is the starting point of the entire system, that contains all files and other
directories.
E
Envelope A description of how a characteristic of sound changes over time. Most often, en-
velopes are used to control the amplitude of oscillators over time, with the most popular
amplitude envelope being the ADSR.
F
FFT An efficient implementation of the DFT.
See: DFT
Float Data type that represents numbers containing a fractional part, like 3.14.
xvi Glossary
Frequency Modulation (FM) Synthesis technique where one oscillator, the modulator, mod-
ulates the frequency of another oscillator, the carrier. Used to simulate the vibrato effect,
but most notably, used to create a variety of sonic textures with minimal resources (two
oscillators).
G
Granular Synthesis Synthesis technique where a sound source is chopped up in very small
segments, which are played back in a cloud-like structure, to either control the pitch or
the playback speed, independently of one another, but also to create sonic textures that are
completely different from the source.
H
Harmonic Part of a complex sound, where the oscillation at the base frequency is the first
harmonic, and the rest of the harmonics are the overtones. In harmonic sounds, the frequen-
cies of the harmonics are integer multiples of the base frequency. They are also referred to
as partials.
Highpass Filter type that lets the frequencies above its cutoff frequency pass, while it attenu-
ates frequencies below it.
I
IDE Acronym for Integrated Development Environment. Refers to editors used to write
computer code that include features like colour highlighting, word completion, auto-
indentation, compilers, and others.
Index In FM, the index is the amount by which the modulator will modulate the frequency of
the carrier. In programming languages, the index is used to locate a value in a list or array.
Integer (Int) Data type that represents numbers without a fractional part, like 5, 24, or 358.
K
Kwargs Abbreviation of Keyword Arguments.
L
LFO Acronym for Low Frequency Oscillator.
Latency The amount of time it takes for sound to be processed by a computer and output to
the speakers.
Lowpass Filter type that lets the frequencies below its cutoff frequency pass, while it attenu-
ates the frequencies above it.
M
MIDI Acronym for Musical Instrument Digital Interface. A communication protocol devel-
oped in the 1980s, used for communication between hardware.
Modulator The oscillator that modulates the carrier in various synthesis techinques, like Fre-
quency Modulation, Ring Modulation, Amplitude Modulation, and Phase Modulation.
Glossary xvii
N
Neural Network A set of artificial neurons that interconnect and exchange numeric data.
They consist of the input layer, the hidden layers, and the output layer. In dense feed-
forward Neural Networks, each neuron in all layers connects to all neurons in the next
layer. Each neuron in all layers but the input includes a weight for each connection, which
is multiplied by the input, and the weighted inputs are summed and added to a bias. The
result of this is fed to an activation function and then passed to all neurons in the next layer.
Normalize Method that confines the amplitude of a waveform to the audio range, between -1
and 1. Used in band-limited waveforms, and other techniques.
Null A reference that does not currently refer to valid data.
O
OSC Acronym for Open Sound Control. A communication protocol developed in the 1990s,
initially as a replacement to MIDI, avoiding the short comings of the latter, eventually used
for networked communication between different machines, or between software running
on the same machine.
Object An instance of a class.
See: Class.
Object-Oriented Programming (OOP) Programming paradigm that employs classes and
objects.
Oscillator Tone generators. An algorithm that causes fast changes in values which, when sent
to the Digital-to-Analog Converter (DAC), they cause an oscillation in the electric signal
sent to the speakers, causing their woofers to move back and forth, thus creating sound.
Oscilloscope A graphic representation of (audio) signals that represent the signal on a 2D
plane, where the X axis represents time, and the Y axis represents air pressure (amplitude).
Overtone See: Harmonic.
P
Panning The action of moving the sound in a 2D plane, between speakers.
Partial See: Harmonic.
Phase Modulation (PM) Synthesis technique where one oscillator, the modulator, modulates
the phase of another oscillator, the carrier. With PM it is possible to get the same results as
with FM.
Phase Vocoder Spectral analysis tool, initially used to alter the duration or the pitch of sound,
independently from one another. Now it is used for numerous ways, from cross-synthesis,
to spectral filtering or morphing, and others.
Physical computing Physical computing encompasses various Human-Computer Interaction
(HCI) practices through the use of sensors that convert analogue signals to digital, transfer-
ring information from the physical world to the computer, and vice versa.
Pure Data Open-source multi-media programming environment, following the visual pro-
gramming paradigm. Developed in the 1990s by Miller Puckette.
Q
Q Abbreviation of Quality Factor. The Q controls the width of the band in bandpass filters.
xviii Glossary
R
Recursion A method in computer programming where a function can call itself. Useful for
compacting code that needs to be repeated. An example of a recursive function is one that
outputs Fibonacci series.
Ring Modulation Synthesis technique where two oscillators are multiplied. The perceived
sound is two tones with distinct pitches. These pitches are the sum and differences of the
pitches of the two oscillators.
S
Sampling rate The rate at which a computer samples amplitude values of audio signals. Typical
sampling rates are 44,100Hz (or 44.1kHz), 48kHz, 96kHz, or even 192kHz.
Sawtooth Waveform type where the output signal is a linear ramp that either goes from low to
high, or vice versa, and when it reaches its highest point, it resets to its initial value.
Scope Part of code where a variable exists. When a variable is created inside a function, it
exists only within the scope of that function, and the rest of the program has no access to it.
Sine wave Waveform type that outputs the sine (or cosine) of a steadily and constantly rising
angle, from 0 to 2*pi.
SNR Acronym for signal-to-noise. Refers to the ration between signal and noise, that is deter-
mined by the bit depth of an audio system.
See: Bit depth.
Spectrum The range of all audible frequencies, and the energy that is present in each region
of it, when a sound is analysed in this respect.
Square wave Waveform type where for half of the cycle it outputs a high voltage (or a 1 in its
digital version), and for the other half it outputs a low voltage (or a -1 in digital). If a square
wave oscillator includes a duty cycle control, then the latter will control the percentage of
one period for which the oscillator will output a high voltage and for which it will output
a low voltage.
String Refers to a string of characters in computer code, encapsulated in double or single
quotes, depending on the language. An example is: “Hello World!”.
Subtractive Synthesis Synthesis technique where a sound rich in harmonic content is filtered,
so we can obtain a sound with less harmonics. Typical sound sources for Subtractive Syn-
thesis are sawtooth oscillators and white noise.
SuperCollider Computer music programming language and environment, developed in the
1990s, by James McCarthy.
Synchronous Type of Granular Synthesis, the opposite of asynchronous.
See: Asynchronous.
T
Table-lookup Type of oscillator whose waveform is stored in a table, instead of consisting of
an algorithm that creates its waveform by making calculations.
Traceback Stack trace information printed on the console when an error occurs in Python.
Triangle wave Waveform type where the output signal rises linearly for half its cycle, and
then falls linearly.
Tuple Python data type that is like a list, but is immutable. A tuple can contain any other data
type as its element, including another tuple.
Glossary xix
U
Unipolar Refers to oscillators whose amplitude oscillates in one pole, usually the positive
one. These oscillators are used for control.
V
Variable A placeholder for a value that varies during the execution of a computer program.
W
Waveform The shape of one period of an oscillator. Typical oscillator waveforms are sine
waves, triangle waves, sawtooth waves, and square waves.
Window A shape used to control the amplitude of a sound source in short time segments.
Granular Synthesis, or FFT use windowing.
1 Getting Started
Python is one of the most popular programming languages for a number of reasons. One reason
is that it is simpler than other languages, like C/C++ or Java. It has a rather simple syntax, it is
interpreted – which means that you can run Python line by line, without needing to compile your
code before you see the result – and it has a very large community and many different forums,
where users can seek help and solutions to their problems. Another reason that makes Python
so popular is its incredible number of modules (packages), either native or external, that greatly
extend the capabilities of the language. Python is taught at many schools and universities, rang-
ing from primary schools up to Bachelor, Master, or even PhD degrees being achieved using or
studying Python.
Python software is actually an interpreter – when you install Python on your computer, you
install a program that interprets what you have written in your Python script, and if there are
no errors in your code, then this program creates an executable program for every single line in
your code. This makes Python slow compared to compiled languages like C or C++ (De Pra and
Fontana, 2020), but the benefits of this language usually overshadow this deficiency. For our
purposes, we need a language that is very efficient, as audio is a very demanding task with strict
temporal requirements. That should make Python not a good candidate for this task, but we will
do all our audio processing using the Pyo module. The signal processing parts of this module
are written in C and its interface is pure Python (Bélanger, 2016, p. 1214), therefore it utilises
the simplicity of Python and the effectiveness of C, bringing together the best of both worlds.
Even though the Pyo module has existed since 2010, its community is rather small and the
module remains rather obscure compared to other audio programming environments, like Pure
Data or SuperCollider. The existing literature on these environments includes many books that
have been written either as educational tools specifically for these languages, like the SuperCol-
lider Book (Wilson, Cottle and Collins, 2011) and Electronic Music and Sound Design (Cipriani
and Giri, 2009), or as tutorials on Digital Signal Processing (DSP) practices using these envi-
ronments, like Designing Sound (Farnell, 2010). Even though Pyo is a very efficient module for
DSP, and is part of one of the most popular and versatile programming languages, up to now it
lacks a comprehensive guide that covers all of its features and at the same time teaches computer
programming and DSP. This book aims to fill this gap by providing an educational tool that
targets both beginner and experienced programmers, and both beginner and experienced musi-
cians, from either the electronic or the acoustic music field.
There are many Python modules for audio or DSP, including scipy.signal, librosa, madmom,
and sc3. Among these modules, the only one aimed at audio synthesis is sc3, a module to control
SuperCollider through Python. The scipy.signal module is aimed more at scientific analysis of
signals, whereas librosa and madmom are aimed more at audio analysis than synthesis. This
book focuses on audio synthesis with Python, and, concerning the sc3 module, it is advised even
DOI: 10.4324/9781003386964-1
2 Getting Started
by its developers that users should first learn SuperCollider through its own language, and this,
therefore, does not fit our purposes. The Pyo module is entirely based on Python, for both its
interface and audio synthesis, without the requirement to learn another language. It is therefore
the best fit to learn audio in and through Python.
This first chapter will help the reader install all the necessary software so they can then focus
on the programming and creative aspects this book discusses. If you have Python installed on
your system, do give this chapter a read, as it covers the installation of the Pyo and the wxPython
modules – the latter is used by Pyo for its Graphical User Interface (GUI) widgets. If you have
all these modules and you are already programming in Python, you can skip this chapter.
Ingredients:
Process:
Python comes in various different versions, with the latest stable one, at the time of writing,
being 3.11. There is no real need to use the latest and greatest version of the language, as what
we will be doing throughout this book is feasible even with earlier versions. What is necessary
though is that you use Python3 and not Python2! Python2 has been declared End-of-Life (EOL)
software, and, in 2020, development and support stopped for that version of Python, leaving
Python3 the only actively developed and maintained major version.
To check what Python version is installed on our system, we need to open a terminal
emulator. On macOS, this is in Applications → Utilities → Terminal.app. On Linux, this is
Getting Started 3
found in the applications menu, or on Ubuntu, you can hit Ctl+Alt+T. On Windows there are
a few ways to launch a command line prompt. Either hit Windows+X and click on “Command
Prompt”, or click “Start” and type “cmd”. Once you have a terminal window open, type the
following:
python --version
If you don’t get a command not found reply, then this will print the version installed.
In case this command returns something like Python 2.x.x, where x is some number – most
likely 2.7.18 or something similar – then the default Python on your system is Python2. If this
is the case, or if you do get a command not found reply, check if changing python with
python3 in the command above gives you Python3. If you don’t get a command not found
reply, then you have Python3 installed, and this is the one you should use.
If the command is not found, then you have to install Python3, either through your sys-
tem’s package manager, or through the official Python website1. On macOS and Windows this
should be a straight-forward process, as Python’s website includes installers for these OSes.
As already mentioned, on Windows, typing python in the command prompt will launch the
Windows Store, and you can simply install Python from there. On macOS you might get a
window pop up stating that you have to install the command line developer tools. Just click
on the “Install” button, and Python3 will be installed alongside the command line developer
tools.
On Linux you will either have to use your system’s package manager – e.g. apt-get
install for Debian and Ubuntu – or download Python’s source code and compile it your-
self. The source code from the official website comes with the Makefile needed to compile
the Python interpreter. All you need to do, as stated in the source’s README file, is type the
following:
./configure
make
make test
sudo make install
It is much easier though to just use your system’s package manager, as it should be a more
streamlined process, and probably the preferred method.
Ingredients:
• Python3
• An internet connection
• A terminal window
4 Getting Started
Process:
To determine which Python version has Pip installed, type the following line in a terminal
window:
pip3 --version
This will print information concerning the Pip version, but also the Python version for which Pip
is installed. Pip is the standard way for installing Python packages – also called modules – even
though sometimes we might need to compile a package from its source. Installing a package is
as easy as typing the following line:
When the line above is typed in a terminal, it installs the NumPy module (Harris et al., 2020),
a module for scientific computing that is widely used among Python programmers. We might
need to install a Python package for a specific Python version instead of the default. This sce-
nario is possible when you have the latest Python as your default, but a module you need has no
wheels – is not available through Pip – for this Python version. Installing a module for a specific
Python version is possible when Pip is invoked through that Python version. The example line
below installs NumPy for Python 3.10:
pip_search packagename
A list with all the relevant modules will be printed on the console. If this doesn’t work, you
might need to invoke the module through Python, by typing the following line:
If we need to uninstall a Python module that we have installed with Pip, all we need to do is
type the following line:
This command is likely to invoke the removal of more packages than the one specified, as
many Python modules do come with dependencies that are installed by the package manager.
Getting Started 5
It is therefore likely that you will be asked if you are willing to uninstall certain packages that
are related to the one you want to uninstall. Usually this should not cause any problems, so you
should go ahead and uninstall everything Pip suggests.
Ingredients:
Process:
There are a lot of IDEs designed for Python, or including Python in their features. Perhaps, the
most popular Python IDE is IDLE, which is Python’s official IDE. IDLE is a simple Python IDE
but it does provide features that can facilitate the development process of your projects. Its main
advantage is that it has both a shell window and an editor window. In the editor window you can
write your Python code, and in the shell window you can run it. Having both, side by side, can
speed up the process of development, as you can easily test your scripts frequently, spot bugs, or
enhance features as you go. When you install Python from the installers provided by Python’s
official website or from your system’s package manager, IDLE is also installed on your system,
so you don’t need to do anything else. On Linux, IDLE is not installed by default, but you can
easily install it from your system’s package manager by typing the following line on Debian,
Ubuntu, and other Debian based distributions:
Apart from IDLE though, there are many more IDEs you can use with Python. Actually, you
can use any text editor to write your scripts, and then run them from a terminal window. Us-
ing a generic text editor though will lack the features an IDE has, like colour highlighting,
automatic indentation, code completion, and others, so you are strongly encouraged to use
an IDE that has these features. Other popular IDEs used for developing in Python include
PyCharm, Visual Studio, and Sublime Text. At the time of writing, one very popular editor,
Atom, has been sunset by its developer team. The Pulsar editor is a replacement of Atom that
you might want to consider, but at the time of writing, it is still very new, with features still
being developed.
One thing to note when it comes to editors and a specific programming language, is the
support of this editor for the given language. Python being very popular, is supported by most
editors for programming. Another feature that is convenient when coding in Python is launching
scripts from the editor. IDLE, Visual Studio, Sublime Text, and PyCharm can all run your Python
code. Of course, Vim and Emacs are among the text editors used by Python programmers, but,
even though these are very flexible editors, learning how to use them is a rather involved pro-
cess that is beyond the scope of this book. Therefore, they are mentioned only in the interest of
completeness. Regardless of which editor you choose to use, make sure to install any available
6 Getting Started
Python packages – e.g. a Jupyter Notebook extension can be very helpful when developing in
Python.
Another editor that will be useful throughout this book is E-Pyo, Pyo’s own editor. This edi-
tor is written entirely in Python and includes features targeted at Pyo usage. Compared to the
rest of the editors, E-Pyo lacks many features, like word completion, or code documentation
pop-up, and it might seem inferior. It does include many audio examples, though, plus you can
run your Python/Pyo code from the editor, so it is definitely worth giving it a try. The E-Pyo
script comes with Pyo, whether you install the module with Pip or you compile from sources.
Since this is just a Python script, there is no need to install anything. All you need to do is run
the script by typing the following line in a terminal window:
epyo
If you use an editor that cannot launch Python scripts, you can still launch scripts from a termi-
nal window, using the python3 command. If you specify the Python file to be launched, then
your Python program will run. If you run this command without any arguments – any extensions
to the command – the python interpreter will launch and you can write Python code interac-
tively. All this is explained later on in this chapter.
The easiest way to install Pyo is to let your system’s package manager install it for you. Compil-
ing from source is not a difficult task, but using the system’s package manager is generally the
preferred method.
Ingredients:
• Python3
• Pip
• An internet connection
• A terminal window
Process:
Installing a Python module with Pip is extremely easy. Pyo’s documentation3 covers how to
install it this way. The only caveat with this approach is that Pyo will not always have wheels
for the latest Python version. At the time of writing, Python’s latest version is 3.11, and the lat-
est Pyo does support this. It is very likely though that you will find the two not always synced.
If you want to install it through Pip, you can either install it with the Pip version that launches
with the pip3 command, or you can target a specific Python version, by typing the following
line in a terminal window:
Getting Started 7
python3.10 -m pip install --user pyo
This will install Pyo for Python3.10 on your system. Read Pyo’s documentation page for more
information. As already mentioned, Pyo includes a set of GUI widgets that are written with the
wxPython module, including the E-Pyo editor. To be able to use these widgets – we will be us-
ing them often throughout the book – you will have to install this module as well. Make sure to
use a Python version that has wheels for both modules, Pyo and wxPython. It is likely that this
version is not the latest Python.
Ingredients:
• Python3
• An internet connection
• A terminal window
Process:
Pyo is open-source and the code can be found on GitHub.4 Pyo’s documentation5 includes in-
structions on how to compile it from source. There are a few things to consider before attempt-
ing to compile Pyo. First of all, if you want to use Pyo’s GUI – and you are strongly encouraged
to use it – you should make sure you have the wxPython module installed in your system, for the
Python version you will compile Pyo against. If you want to compile Pyo for a Python version
that has no wheels for wxPython, head over to wxPython’s website6 and get the sources, as you
will have to compile that yourself too.
Another thing you must decide is which audio server you want Pyo to compiled against. On
macOS you might want to use CoreAudio, and on Linux or macOS, you might want to use Jack.
The following line is the command to compile Pyo without specifying an audio server:
Run this command from the root directory of the Pyo source. Make sure to use the Python ver-
sion you want to compile Pyo against – Python3.11, or simply Python3, depending on the ver-
sion. If you want to specify the audio server, you have to include the corresponding flag, so the
command above can be modified as in the line below:
If you want to compile Pyo with 64-bit resolution – note that this refers to the sample resolu-
tion, not the resolution of your system – you have to include the --use-double flag. If
8 Getting Started
you want to combine the 64-bit flag with the audio server flag, you have to compile with the
following line:
Pyo includes some scripts that take care of all of this for Linux and macOS. Check the documen-
tation page, or the scripts/ directory that comes with Pyo, for further information.
Even though using your system’s package manager to install software is often the preferred
method, compiling software yourself can provide greater flexibility. At the time of writing, in-
stalling Pyo with Pip installs Pyo without Jack support. If you really need to use Pyo with Jack –
and it is likely that this is the case when using Linux, for example – you will have to compile it
yourself, so you can customise the installation according to your needs.
Below this paragraph we have Shell 1.1, the first shell of the first chapter. Shells refer to an
interactive Python session. Such a session can be launched either with the python com-
mand without any arguments in a terminal, in an IDLE shell, using a Jupyter Notebook either
inside your IDE or in your browser, or in some other way that your setup might support –
e.g. the Pulsar editor includes the Hydrogen package, a former Atom package, that enables
interactive Python coding in the editor. The leading prompt “>>> ” in Shell 1.1, is the
prompt in a terminal or IDLE session. Depending on how you use Python interactively, this
might differ.
The difference between a script and an interactive shell session is that with the latter, every
typed line is immediately interpreted, enabling interactive programming. A script on the other
hand, has to be saved in a file and invoked with the Python interpreter. A script will run
from top to bottom and exit, unless we define a way to keep the script alive until we quit it
explicitly.
A shell might seem more flexible, as coding is interactive, but what is typed in a shell can-
not usually be changed. So, if a mistake in the code occurs, the user can’t edit the code, so they
will have to re-write it. A script on the other hand is not interactive, but the code is editable. An
in-editor Jupyter Notebook or another way to run Python code interactively inside an editor is a
feature that can prove to be very helpful, especially when it comes to debugging code, or when
trying to get calculations right.
Getting Started 9
Throughout this book, code will be shown in scripts and shells inter-changeably, though for
the most part, it will be shown in scripts. When running an interactive shell in a terminal, on
Linux and macOS we can type Ctl+D to exit it. On Windows we can type Ctl+Z and then hit the
Return key (the Enter key) to exit, or call the exit() command. When running a script that
doesn’t exit because it has been explicitly programmed to stay alive, or because it gets stuck, we
can type Ctl+C to force quit it if it has been launched from a terminal.
There are some cases in this book where a line of code is too long either because of the names
of variables or functions, or because of indentation, and it has to be broken to fit these pages.
This is not necessarily the case when writing code in an IDE. Throughout this book, such long
lines are broken in more, shorter ones. Script 1.2 shows some examples with pseudo-code.
Script 1.2
1 some_module_with_a_long_name.some_long_named_function(
2 a_long_named_argument,
3 another_long_argument
4 )
5
6 an_indented_function_name(first_argument,
7 second_argument)
8
9 an_indented_variable = some_value *\
10 another_value
In some chapters we will visit code from other programming languages and environments.
As with the Python code, it will be headlined and numbered, like the script and shell above.
Depending on the language used, a different terminology will be used instead of script or shell,
like sketch for Arduino code. By the time you get to these chapters you will have become ac-
customed to the way code is illustrated in this book.
1.6 Conclusion
We have installed Python, Pip, Pyo, at least one text editor, and probably wxPython. We have
also learned about different Python versions, how to distinguish them in our system, and how
to target a specific Python version when installing modules. We have seen how we can install
and uninstall a package with Pip, and how to compile Pyo from its source. We are now ready to
move on to the next chapter and start writing code!
Notes
1 www.python.org/
2 https://pypi.org/
3 https://belangeo.github.io/pyo/download.html
4 https://github.com/belangeo/pyo
5 https://belangeo.github.io/pyo/compiling.html
6 www.wxpython.org/
Bibliography
Bélanger, O. (2016) ‘Pyo, the Python DSP Toolbox’, in Proceedings of the 24th ACM International
Conference on Multimedia. New York, NY, USA: Association for Computing Machinery (MM ’16),
pp. 1214–1217. Available at: https://doi.org/10.1145/2964284.2973804.
10 Getting Started
Cipriani, A. and Giri, M. (2009) Electronic Music and Sound Design. Rome: ConTempoNet s.a.s.
De Pra, Y. and Fontana, F. (2020) ‘Programming Real-Time Sound in Python’, Applied Sciences, 10,
p. 4214. Available at: https://doi.org/10.3390/app10124214.
Farnell, A. (2010) Designing Sound. Cambridge, Massachusetts: MIT Press.
Harris, C.R. et al. (2020) ‘Array programming with NumPy’, Nature, 585(7825), pp. 357–362. Available
at: https://doi.org/10.1038/s41586-020-2649-2.
Wilson, S., Cottle, David and Collins, N. (2011) The SuperCollider Book. Cambridge, Massachusetts:
MIT Press.
2 Writing Your First Python Programs
In this chapter we will learn how to write small Python programs, to undertake various tasks of
varying complexity. By the end of this chapter you will be able to write Python scripts, using
code structures and functions to facilitate your development. If you are competent in Python
programming, you can skip this chapter and move on to the next, where we will learn various
audio synthesis techniques. If you are new to Python, this chapter will get you up and running
so you can follow the rest of this book.
After you have read this chapter you will be able to:
Ingredients:
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
DOI: 10.4324/9781003386964-2
12 Writing Your First Python Programs
Process:
The easiest way to write the “Hello World!” program in Python is the shown in Script 2.1.
Write the line in Script 2.1 into a file called “hello_world.py” (or whatever name you want to
give it, just make sure the .py suffix is there), and run it. Sure enough, you will see Hello
World! printed on your console. Note that in a terminal, you have to be in the directory where
you saved your script, so that Python can find it and run it. Depending on the editor you use,
there might be other ways to run Python scripts. In the E-Pyo editor you can run a script from
the Process→Run menu, or with the Ctrl+R shortcut. This one-liner program is totally legal
in Python. Do mind though, that the way we have written it does not convey proper program
structuring. To write a better “Hello World!” program in Python we have to include our one-
liner into a function, and call it. Functions in Python are explained further on in this chapter, so
let’s move on.
Ingredients:
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
Process:
In Python comments start with # and have no effect on the script. For example, the line in Script
2.2 is our print() program, including a comment that is completely ignored by the Python
interpreter.
If you run this script, you will get exactly the same result as with our first recipe. This comment
explains what this line of code does. This specific example is trivial, but is enough to explain
what comments are, and how and why they are used.
Writing Your First Python Programs 13
2.3 Data Types in Python
Python includes different data types that can be assigned to variables. These can be roughly
categorised in the following groups: numeric, Boolean, sequence, dictionary, and set.
The first data type we will look at is the various numeric data types. This data type group con-
sists of three members, integer, float, and complex. The integer data type is used for storing
integer values, like 1, 2, 3, -5, 1000000. To improve readability, we can separate groups of digits
with underscores. For example, 1000000 can be written like this: 1_000_000. These two num-
bers are exactly the same, one million. In programming jargon, integers are called ints.
The other numeric data type is float. This data type stores non-integer values like 3.14,
100.5897, and -5.893459. Python includes a third numeric data type, called complex. This data
type stores complex values that include a real and an imaginary part. Such a value can be ex-
pressed like this: 2 + 3j, where the second value is the imaginary. We will not be using complex
numbers in this book at all.
Ingredients:
• Python3
• An interactive Python shell
Process:
Numeric values are usually stored in variables which, as a good programming practice, are
given self-explanatory names. For example, if we want to store the value of a hypotenuse, we
could name the variable that will hold this value hypot, or something similar. The pseudo-code
in Shell 2.1 is an example of self-explanatory variables holding some float values.
While this is pseudo-code, it is almost valid Python code. If you run this code, though, you will
get an error message when you execute the third line. This specific example is a bit more in-
volved, and it is used here as an example only, to explain the role of variables and how to make
them self-explanatory.
In many programming languages, mixing data types is only possible through what is called
casting. In Python it is possible to combine different numeric types without explicitly changing
the types of variables. The code in Shell 2.2, being perfectly valid, stores some arbitrary values
of all three numeric data types, and combines them. Launch a Python shell and write the lines in
Shell 2.2 without the comments, hitting the Return key at the end.
The first three variables have somewhat explanatory names, as we named the integer i, the
float f, and the complex c. The rest of the variables take arbitrary names for the sake of simplic-
ity, since this example only explains the numeric data types of Python, and these values have no
actual functionality.
14 Writing Your First Python Programs
There two things to note here. The complex data type has two values, both of which are
floats, even though we define these values as integers. We can access them separately using the
real and imag members of this data type. The second thing to note is that if we add a float to
an integer, and store the result to the latter, it switches from integer to float, as in the last line of
Shell 2.2.
The next data type we will look at is the Boolean. This is a standard data type in many pro-
gramming languages. It is a true/false value, essentially a 1 and a 0. Booleans are used in condi-
tional tests to determine whether a part of our code will be executed or not. Python reserves the
keywords True and False for the Boolean data type.
Ingredients:
• Python3
• An interactive Python shell
Process:
We can create a Boolean variable by simply assigning one of these two keywords to it. Shell 2.3
is an example. Note that arithmetic operations with Booleans are valid in Python. The lines in
Shell 2.4 are perfectly legal. When we make arithmetic operations with Booleans, the latter are
treated as integers with the values of 1 for True and 0 for False.
The third data type we will look at is the sequence data type. This group includes strings, lists,
and tuples.
Writing Your First Python Programs 15
Ingredients:
• Python3
• An interactive Python shell
Process:
The string data type is common among many programming languages, with Python being
among them. We will look at this data type first.
In computer programming, a string is a sequence of characters. Shell 2.5 shows a Python string.
If you type it in a Python interpreter, you will see it being echoed back on the console. Usually
we store strings in variables, in which case there is no echoing, or we pass them to functions as
arguments (more on functions and arguments later on).
In Python, strings are encapsulated either in double or single quotes. If we want to include
quotes inside our string, so these are printed, we have to use the quote sign that is not used to
encapsulate our string. For example, the string in Shell 2.6 is valid. This string can also be writ-
ten with the quotes inverted, meaning that we can encapsulate our string in single quotes, and
use double quotes around a.
Strings are typically used for printing information on the console, or to convey arbitrary infor-
mation that can be expressed more easily with a natural language, instead of numeric data types.
Since Python3.6 there is a special type of string, call the f-string. This string type allows us to in-
sert expressions inside strings. For example, the code in Shell 2.7 including an f-string is valid.
Shell 2.7 will print “a+1 equals 6” as the {a+1} will print the value of the expression of the a
variable + 1, which is 6. We will be using this kind of string formatting throughout this book, so
you are strongly encouraged to use Python3.6 or greater.
A list is a sequence of arbitrary data types. A single list can contain numeric values (all three
types), strings, even other lists. In Python, lists are denoted with square brackets. The examples
in Shell 2.8 are all valid Python lists.
16 Writing Your First Python Programs
Shell 2.8 Various lists.
>>> lis1 = [1, 4, 19.7, 5_900]
>>> list2 = [“a”, “list”, “of”, “strings”]
>>> list3 = [54, list1, 178.4678, list2]
Notice that we included the first two lists in the third one. This is perfectly valid and, in many
cases, very effective. A list can also be updated with new elements. The code in Shell 2.9 defines
an empty list, and then inserts a few elements in it. The resulting list will have the following
elements: 0, 5.48, “foo”, [1,2,3].
The last sequence data type is the tuple. This is very similar to the list, but it is immutable. A
tuple can contain any kind of data types, like the list does, but once it is defined, its elements
cannot change, neither can the tuple be updated, like the list can. Tuples are denoted with round
brackets. Shell 2.10 includes some examples of valid tuples:
As in many other programming languages, in Python indexing sequence data types is zero-
based. This means that the first item of such a data type has the index 0, the second item has
the index 1, and so on. Indexing sequence data types is done with square brackets. Shell 2.11
includes some examples of indexing.
As we can see, indexing can go as deep as the items we want to index. The fifth line accesses the
fourth item of the list l, indexed with 3, which is a list with two values, 8 and 7, and then ac-
cesses the second item of this sub-list, indexed with 1, the value 7. The last example accesses the
Writing Your First Python Programs 17
third item of t, which is indexed with 2 and contains the string “foo”, and the first character
of this string, indexed with 0, which is the letter “f”.
In Python, it is possible to group values together and index them in a more arbitrary way instead
of zero-based sequential indexes, like the ones used with lists, strings, and tuples.
Ingredients:
• Python3
• An interactive Python shell
Process:
Python includes a special data type called a dictionary. Dictionaries are a bit like lists, only
in this case, we define the index together with the value the index is pointing to. In this case,
indexes are called keys. Dictionaries in Python are denoted with curly brackets. Their keys are
separated from their values with a colon, and key and value pairs are separated with a comma.
The example in Shell 2.12 is a valid Python dictionary.
The keys we have defined in this dictionary are “one”, “two”, and 5. Note that keys consist
of both strings and ints. Data types that can be used for dictionary keys include ints, strings,
floats, and Booleans, though, numeric data types might not be so meaningful in dictionaries,
especially ints and Booleans, as ints are used to index lists and tuples, and Booleans are more
or less treated likes ints. On the other hand, dictionary keys are not incremented like they are in
the example above of Shell 2.11. In Shell 2.12, the third key is 5, whereas in a list or tuple, the
third item would be indexed with 2.
We can thus see that dictionary keys can be created arbitrarily, to fit our needs. Nevertheless,
dictionary keys are most often strings. The values of dictionaries are accessed through their
keys. The dictionary in Shell 2.12 can be accessed the way it is shown in Shell 2.13.
Dictionary values can be changed, or new key/value pairs can be inserted. The lines in Shell
2.14 are valid. The first line changes the value of the key ‘one’, and from the integer 56, the
value is now the string ‘bar’. The second line adds a new key/value pair to our dictionary,
with the key ‘three’ and the value 89.
The dictionary data type is very convenient in many cases, and we will encounter them a few
times throughout this book.
18 Writing Your First Python Programs
Shell 2.14 Changing and adding dictionary values.
>>> d[“one”] = “bar”
>>> d[“three”] = 89
The last data type we will look at is the set. This is an unordered collection of data types that is
iterable, mutable, and has no duplicated elements. We will sparsely use sets in this book, so we
will explain them here in brief.
Ingredients:
• Python3
• An interactive Python shell
Process:
A set is denoted with curly brackets, a bit like the dictionary, but it only includes values and no
keys. A set is useful though if created from a string or a list, so duplicated elements can be easily
discarded. Shell 2.15 shows some examples of sets.
Note that the order of the elements of the list or the string we used to create a set was not main-
tained. In the case of the string, each character was separated and used only once, so we get only
one “s” character.
Accessing items of sets is done either with loops, or by converting a set to a list, and then us-
ing normal list indexing. Shell 2.16 demonstrates this. Note that we will talk about loops further
on in this chapter, so don’t worry if you don’t really understand how the loop in this shell works.
This loop results is printing all the elements of myset sequentially. Note that after hitting the
Return key after typing the colon, the prompt will change from three > characters, to three dots.
This is a prompt of code structures in the Python interpreter. These prompts are not present in
text editors, but only when we write Python code inside the interpreter in a terminal or in IDLE.
Also note that after the print(item) line, you must hit Return twice, to exit the loop body.
The last line accesses the second element of newset. Sets include operations to remove or
insert items. See the example in Shell 2.17.
Writing Your First Python Programs 19
Shell 2.17 Adding and removing set items.
>>> myset.remove(‘foo’)
>>> newset.pop() # this removes the first item, in this case 3
>>> lastset.add(‘l’) # adds ‘l’ to lastset
>>> lastset.add(‘s’) # has no effect as ‘s’ is already included
Each data type in Python has a reserved keyword that can be used to create such a data type.
The following keywords are reserved by Python, and can be used to initialise a variable with
the given data type:
Note the round brackets used with the keywords. This is because all these types are actually
classes in Python, and the variables of these classes are called objects. We will learn more
about classes and objects in Chapter 8, but bear in mind that these two terms will be used inter-
changeably throughout this book.
Ingredients:
• Python3
• An interactive Python shell
Process:
We can initialise a variable of any of these data types by using the respective keyword, as shown
in Shell 2.18. The first two lines initialise variables with the value of 0 assigned to them, while
the third line initialises an empty dictionary and the fourth an empty list. The last line initialises
an empty tuple. This is probably redundant, as tuples are immutable, so once initialised, no
modifications to it are possible, so we will be left with an empty tuple.
2.3.7 NoneType
Python has a special data type that is equivalent to the Null data type of other languages. This
type is called a NoneType and inside our code we access it by typing None. This is a neutral
data type that holds no actual value.
Ingredients:
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
20 Writing Your First Python Programs
Process:
The NoneType can be useful for initialising variables whose data type is still unknown, or
when we want to check if an operation succeeded or failed. In case it fails, such an operation
could return a NoneType, so we could test against it to see what happened. Script 2.3 is a
pseudo-code example.
Even though we referred to instances of data types as variables, since their content varies, these
elements are actually what in Python and other languages is called an object. All the data types
we learnt in this section are different classes. The code in Shell 2.19 demonstrates that.
We can see that the result of type(i) prints <class ‘int’> telling us that the variable i
is an instance of the class ‘int’. Python is an Object-Oriented Programming language (OOP),
and in programming jargon, the instance of a class is called an object of that class. We will see
objects in many places throughout this book, even in this chapter, so it is good to get acquainted
with this terminology from an early stage. Do keep in mind though that when creating objects of
the data types we covered in this section, we will still refer to them as variables and not objects.
Syntax conventions in Python will help you differentiate what is called a variable and what an
object, as usually we refer to a class instance as an object when the class is written with its initial
letter in upper case. For now, keep this information in mind and it will start making sense as you
read through this chapter and the book.
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
Process:
If we want to print something on the console if a value is above a threshold, we can do it the
way it is shown in Script 2.4.
If we save this code to a script and then run it, we will have the string passed to print()
printed on the console. Of course this specific conditional test is rather useless, as the value of
the variable val is hard-coded and we know the result of the test in advance. This is only a dem-
onstration to show how the if test works in Python. This test is used with variables that change
while a program runs, or with variables that are not known prior to this test (e.g. a variable that
gets its value from input from the user).
What is important is to learn the structure of this test, where the if reserved keyword is
followed by the condition (in this case, val < 10) and then a colon. After the colon we write
the body of the code to be run in case the condition is true. If this body of code is a single line,
it can be written in the same line with the condition, right after the colon. Otherwise it has to be
written one line (or more) below.
What is important is the indentation. Indentation is very important in Python, as this lan-
guage does not use curly brackets or some other way to encapsulate code snippets. The amount
of indentation is up to the user, but it should be consistent throughout the entire script. This can
be done either with horizontal tabs or sequential white spaces. By convention, indentation in
Python is one horizontal tab. Many text editors that support coding in Python import these tabs
automatically.
The code in Script 2.4 runs only when our condition is true, but we can have more code that
will be executed if our condition is false. The code in Script 2.4 can be extended to the code in
Script 2.5.
Now we have changed the code a bit and we are testing if val is greater than 10, instead of less.
This condition is false, so our test will fail. In this case, the code of else will be executed. We
can extend our code though even more and include more cases, in between if and else. This
is done with the elif reserved keyword, which stands for “else if”. So our code now changes
to the code in Script 2.6.
22 Writing Your First Python Programs
Script 2.6 An if/elif/else test.
1 val = 5
2 if val > 10:
3 print(“val is greater than 10”)
4 elif val == 5:
5 print(“val is equal to 5”)
6 else:
7 print(“val is less than 10 and not equal to 5”)
This script will print “val is equal to 5” on the console, since val is equal to 5, and this is the
test of our elif. In a conditional test, if and else can be used only once, with the former at
the beginning and the latter at the end. elif, though, can be used as many times as you want,
and these tests should be in between if and else.
Note the double equal sign used in the elif test. This is a test for equality and should not be
confused with the single equal sign which is used for value assignment. The two lines in Shell
2.20 are completely different, but sometimes easy to be mixed.
The first line assigns the value of 5 to a variable called val, and the second line tests if val is
equal to 5. The first line, apart from assigning a value to the variable val, defines this variable,
in case it has not yet been defined. Note that if no value assignment has been made to val,
then using the second line will produce an error, since the variable val will have not yet been
defined.
Ingredients:
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
• An interactive Python shell
Process:
A function is a set of computations that might take some input or not, and they produce some
output. For example, a simple function that adds together two numbers should take two input
values and produce one output. Such a function is defined in Shell 2.21.
Since we are writing this in an interactive shell, the output of the function will be printed on
the console, even though we are not using print(). This is because our function is returning
a value that we are not storing anywhere. When defining functions that return something, it is
meaningful to store the returned value in a variable for later use. This is done with the line in
Shell 2.23.
This line calls our function and stores the returned value in a variable called a. Note that the first
argument of our function is also named a, but there is no conflict in this case as the argument
a of our function is local to the scope of the function, whereas the variable a that stores the
returned value is local outside the scope of the function. We will talk more about scope further
on in this chapter.
To go back to our “Hello World!” program, we can structure it better by including our one-
liner in a function that will be called when we run our script. The code in Script 2.7 does exactly
that.
Now we have included a number of standard coding elements, like functions, conditional tests,
and a standard way of running Python scripts. In this script we define a function called main()
which takes no arguments, hence the round brackets are empty. All this function does is print
“Hello World!” on the console. Notice that it doesn’t return anything, as we don’t need to store
24 Writing Your First Python Programs
any value from this function. You might have also noticed that print() has a function struc-
ture, as it is followed by round brackets with something in them – in this case, the “Hello
World!” string. This is because print() is actually a function included in Python by default.
Since we put the print() function inside another function, we must call the top level func-
tion, main(), at some place in our program. This happens at the last two lines of our script.
These two lines are very standard in Python and they will be explained in detail later on in this
chapter.
The arguments we have passed to the function that adds them are called positional arguments.
This is because the order in which we write them when we call such a function matters. Python
includes another type of argument, called keyword, abbreviated with kwargs (pronounced
“quargs”).
Ingredients:
• Python3
• An interactive Python shell
Process:
Kwargs are identified by their keyword and we provide them in any order, as their position
doesn’t matter when calling such a function. Shell 2.24 includes an example of a function with
kwargs. They are very flexible as they can be totally omitted, or we can provide only some of
them when calling a function with kwargs. Also note one line before the last, where we first pro-
vide arg2 and then arg1, still we get arg1 printed first. In the last line we provide values as
positional arguments. This is perfectly valid, and the arguments will be assigned to the kwargs
in the order we provide them.
In Python, a function can call itself. This practice is called recursion. The code in Script 2.8 is a
usual example of how recursion can help calculate a Fibonacci series.
Note line 5 where the function is calling back itself, passing its own argument subtracted by 1
and by 2. Take a minute to think about what is happening here. Line 2 tests if the argument is
found in the list [0, 1], and if it is, the argument is returned intact, as the first two values of a
Fibonacci series are 0 and 1. If the argument is not in this list, then line 5 will be invoked. Let’s
say that the argument is 2, then line 5 will result in calling the fibonacci(n) function twice,
once with the argument 1 and once with the argument 0. These two function calls will result in
the values 1 and 0 being returned, as they are in the list [0, 1], and they will be added and
returned, so we will get 1 returned. If the argument passed is 3, then this process will be repeated
until all recursive function calls are caught by the if test in line 2. So, the function will keep on
calling itself as long as the test in line 2 fails.
Recursion in functions can be helpful and can make your code look concise and elegant,
but they should be used carefully, as you might get a RecursionError from Python, if you
haven’t made sure that there is some limit in the function calling back itself. We will learn more
about errors in Python in Section 2.8 of this chapter.
Ingredients:
• Python3
• An interactive Python shell
Process:
There are two different ways to run code in a loop, using the for or the while reserved
keywords. Let us include the if test we already wrote, in a for loop. The code is shown in
Shell 2.25.
In this script, we have used the for keyword, combined with range(). range(), which is
a class rather than a function (more on classes in Chapter 8), takes from one to three arguments.
Here we have passed one argument which is the “stop” argument. This means that range()
will iterate over a range from value 0, until it reaches [stop – 1], and it will increment by 1 every
time. Essentially, when using range() with one argument only, it will iterate as many times as
the argument we pass to it, in our case, it will iterate ten times.
26 Writing Your First Python Programs
range() returns a list with the values it iterates over. In this code it will return the follow-
ing list:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
The for loop will iterate over this list and will assign each of its values to the variable i, every
time assigning the next item of the list. Inside the body of our loop we can use this variable for
any task we want. This example is very simple and all it does is print on the console the value of
i except from the iteration where i is equal to 5. This is achieved by using the reversed keyword
continue. This word skips any code of the structure that includes it, that is written below it.
So, when our if test is true, the code written below this test will be skipped, and the for loop
will continue to the next iteration. Running this script will print the following on the console.
0
1
2
3
4
6
7
8
9
If the if test with the continue keyword was written after print(i), then it would have
no effect at all, since there would be no more code left in the loop to skip.
The same loop can be achieved with the while loop, although we should understand its dif-
ference to the for loop. The latter works with a specific number of iterations, while the former
works with a conditional test. While the test is true, the loop will run, and when the test is false,
the loop exits. We have to be careful when using while as we can create an infinite loop where
the conditional test can never be false. The code in Shell 2.26 is an example of an infinite loop.
while tests its condition – in this case i < 10 – and if it is true, it will execute the code in its
body. After this code is run, while will return back to its conditional test to determine whether
it will execute its code again. If the test is false, the loop will exit, and the script will go on to
whatever is written after the body of the loop. Note that in the example above, i is set to 0 and
while is testing if this variable is less than 10. Since we do not increment i inside our loop, it
will always be less than 10, and our while loop will not be able to exit, stalling our program.
If you happen to run this loop you can exit it by hitting Ctl+C, as Ctl+D will not work. The for
loop we wrote in Shell 2.25 can be written with while the way it is shown in Shell 2.27.
Shell 2.27 The for loop of Script 2.25 implemented with while.
>>> i = 0
>>> while i < 10:
Writing Your First Python Programs 27
... if i == 5:
... continue
... print(i)
... i += 1
...
>>>
In this code we initialise i to 0 and then we enter the while loop. The conditional test of the
loop will succeed since 0 is less than 10 and the body of the loop will be executed. The code
of the loop is almost identical to the for loop we wrote earlier, only this time, before we exit
the body of our loop, we increment i by 1. The syntax used in the last line of this example is
equivalent to the line in Shell 2.28.
By incrementing the variable by one, we make sure that we will print incrementing values, omit-
ting 5 as we use continue when i equals 5. But most importantly, we make sure that our loop
will exit after ten iterations. Omitting to increment the i variable will not only print a constant 0,
but will disable our loop from exiting, like with the previous example.
Another functionality of the for loop is to initialise lists, the way it is shown in Shell 2.29.
In Python, the square brackets denote a list. The notation above uses the for loop combined
with range() to iterate ten times and since it is encapsulated in square brackets, it will return
the following list.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Initialising lists like this is called list comprehension in Python jargon, and it is a very convenient
way to initialise a list with items. We will be using this technique in a few examples in this book.
2.7 Scope
Like in many other languages, Python implements scope, where variables are local to a certain
scope.
Ingredients:
• Python3
• An interactive Python shell
Process:
Now that we have learned the basics about functions and loops, we can understand scope. Take
the example of Shell 2.30, where we want to create a function that will take an integer as an
argument, and it will return this integer added to a constant value.
28 Writing Your First Python Programs
Shell 2.30 Trying to access a local variable outside of its scope.
>>> def func(arg):
... a = 5
... return a + arg
...
>>> b = func(a)
In this example, the fifth line will throw an error, as we are trying to access the variable a which
is defined inside our function and it is local to the scope of that function only. The rest of our
code is not aware of the existence of this variable and doesn’t have access to it. This variable
is created on-the-fly whenever we call this function, it remains accessible only within the func-
tion, and it is destroyed when the function exits. Shell 2.31 does not produce any errors as the
variable a is in the global scope.
A way to define global variables within a function is by using the reserved keyword global.
The code in Shell 2.32 creates a inside the function, but now its scope is global, so we can ac-
cess it outside of the function.
The way we define the variable a above enables us to both call the function and use the variable
outside the scope of this function. Global variables are usually considered a bad practice by
many programmers, as being able to access a variable from anywhere inside a program might
lead to accidental modifications of it, plus access to global variables is slower than trying to ac-
cess a local one. Pyo classes, though, run on a different thread than the main thread of Python,
and they are often initialised in the global scope, so we will be using global variables in various
parts in this book, especially for Pyo classes.
2.8 Traceback
When there is a bug in our code, we need a way to tell where this bug resides. The Python inter-
preter prints errors on the console when something is not correct. This is called the traceback,
and it gives useful information as to which part of our code produced the error, and what type
of error that was.
Writing Your First Python Programs 29
Ingredients:
• Python3
• An interactive Python shell
Process:
Take the code in Shell 2.33 as an example. It will throw an error since we haven’t defined the
key “age” in our dictionary. The printed traceback is shown in Shell 2.34. The traceback tells
us that the error is produced in line 1, and the error type is KeyError, after which the unde-
fined key ‘age’ is also printed, which is the key that produced the error. The error was spotted
in line 1 because we run this example in the Python interpreter, and not by saving and running
a pre-defined script. If we write this code in a script and run it, then the traceback would report
line 4, and instead of “<stdin>” as the file name, it would print the entire path to the actual
Python script we run.
Shell 2.33 Trying to access a dictionary key that does not exist.
>>> d = {“name”: “Alice”, “place”: “Wonderland”}
>>> print(d[“name”])
>>> print(d[“place”])
>>> print(d[“age”])
Python has various error types. The most common probably are: IndexError, KeyError,
NameError, IndentationError, and perhaps RuntimeError. The names of these er-
rors give us information as to what they relate to. For example, the IndexError is raised
when we try to index an item of a list that is out of the bounds of the list. The NameError
concerns undefined variables, functions, and classes. The IndentationError includes er-
rors concerning bad indentation. The RuntimeError is special, as this is raised whenever the
error occurred does not fall under any of the other error types.
2.8.1 Exceptions
We might find ourselves in a situation where an error is produced at a certain part of our code,
causing it to crash, and the traceback doesn’t provide enough information to debug it. In Python
we can avoid terminating our program when an error is raised, so we can diagnose our code.
This is achieved with the exception feature.
Ingredients:
• Python3
• A text editor (preferably an IDE with Python support)
• A terminal window in case your editor does not launch Python scripts
Random documents with unrelated
content Scribd suggests to you:
to England to plot against you, and then intended when you were
put out of the way to get the money from Natty. That poor lad
doesn't know it, but I believe his life is not safe."
"Ah!" Frank started, and spoke in a rather agitated tone. "I forgot
that in my troubles. Have you got it?"
"Yes. But I am afraid to use it. The light might be seen from the
road."
"And if Mrs. Baker saw it she would certainly make inquiries. We'll
wait for a bit. I'll show you the letter before I go, and then I must
talk to Mildred and Mrs. Perth. But about Berry. I wonder if anyone
knows details of his past life?"
Jarman paused for a moment, and then went on: "Frank, do you
think there is negro blood in Darrel?"
"It's curious you should say that, Jarman. Jenny Arrow saw that
portrait of Balkis, and she thought it resembled Darrel."
"I haven't seen that portrait. Miss Cork took it away, you said."
"She might--she might," mused Jarman "Well, I'll soon know her
also, for I am going to look her up at the Docks."
"Oh, but that's absurd, Eustace. Darrel comes from Africa." Jarman
laughed. "He went out there in the first instance. He talked of being
in Los Angeles. That is in Mexico, and Mexico is in the same latitude
as the West Indies."
"Yes, I do." And Eustace told Frank of the poster, and how Fan had
denied having anything to do with it. "And I'm sure she spoke the
truth," he said decisively, "for she asked me if I had posted the Bat.
Of course, she must guess that you have it tattooed on your arm,
and thought that I made use of it."
"But for what purpose? You and I are not supposed to know
anything about the fortune--if there is one."
"Oh, there is one, sure enough, and the Berry lot think I know much
more about it than I do. And there's another negro mixed up in the
matter besides Balkis. The lawyers I called on told me that one came
to ask after you." And Jarman gave details.
"Well," said Frank, more and more puzzled, "there's only one thing
to be done. We must open the sealed letter."
"All right. Here you are," and in the darkness Jarman passed it
along. Frank opened it, but it was impossible to see. Therefore
Eustace lighted a match, which was not likely to be seen from the
road, and held it while Frank read the letter. The paper had a Scarlet
Bat drawn in one corner with red ink, and the writing consisted of
only a few words. "My son," ran the writing, "when you are twenty-
five send your address to 'Tamaroo, The General Post-Office,
London. To be called for.' Then wait events."
"And Tamaroo is the name on the bills!" said Eustace under his
breath.
CHAPTER XVIII
A QUEER VISITOR
"It isn't that," said Mr. Denham, gloomily. "I've been square enough,
but I've been having trouble."
"Oh dear me!" cried Miss Arrow, sympathetically. "Not bad, I hope?"
Jenny looked rather dismayed. She fancied herself in love with Mr.
Denham, as by this time she had quite got over her romantic
affection for the Irish secretary.
"I'm sorry," she said pensively. "And you will regret leaving--
Mildred!" She looked at him sharply.
"I'll regret leaving all my friends. Those at Wargrove are the best
I've struck in the old country. I don't know that Miss Starth's any
great sorrow to me, though. She don't care a red cent for me."
"That's so, and I don't see much good my hovering round. I should
like to marry a real sweet English girl."
Jenny blushed, but she was not vain enough to take the compliment
to herself. Yet she could have done so, for Denham was thinking of
her when he paid it. Jenny was not pretty, but she had the freshness
of youth, and a sweet, frank face of her own which appealed to the
man.
"I want to say goodbye," said he, "and there are other things I have
to do. Deliver a letter, for one thing."
"To Mr. Jarman?"
"To Miss Starth. And it's from Miss Berry. You've heard me speak of
my friends, I guess?"
"Well," drawled Natty, flushing, "they were, but they ain't now. I've
had a row. Berry hasn't been acting square by me, and I don't
cotton to his goings-on nohow. I'll give them a wide berth for the
future."
"Guess you don't care much for me?" said he, with a shrug.
"Oh, but I--" Jenny was about to say that she did, and only changed
the sentence in time. "But I like you, really."
"I'm going to stop for a few days, and we can talk of that," said
Natty, looking peculiarly at her. "I suppose Jarman will put me up?"
"Oh, I'm sure he will," said Jenny. "Mr. Jarman likes you. He's rather
troubled now on account of Mr. O'Neil leaving him."
"I don't know. I think he left without giving notice," said Jenny.
"I don't know that he ain't wise, that young man," said Natty, in a
dry tone. "The billet didn't suit him."
"What folk seem, ain't often what they feel," rejoined the American,
and again fixed Jenny with his eyes. "Now, you'd never think that in
your company I feel different to what I say."
"Really?" Jenny did not know where to look, and was thankful that
the old gentleman was in the carriage. She felt that Natty was in
measurable distance of a proposal, and the timidity of maidenhood
seized upon her. Consequently she became voluble, and drew
Denham's attention to the scenery, to the pictures in the magazines,
and to the news of the day. Natty, not accustomed to this innocence,
was delighted, and thought Jenny just charming. He made up his
mind to propose within the week, being used to carry through
business smartly.
"Here you are!" said Natty, shaking hands. "I've just come down to
put up with you for a day or two. Can you fix me?"
"Of course, I can put you up," said Jarman. "Shall we drive?"
"No, I guess not. Let us send on the baggage and walk across. I
have something important to say."
"Wondering what this could be, Jarman saw that Natty's trunk was
put on a fly, and, after directing the man to take it to the Shanty,
walked on with his unexpected guest. Eustace had long since posted
a letter written by Frank, according to the instruction of the sealed
epistle, and it had been sent to Tamaroo at the General Post-Office.
The man (for Tamaroo was a man according to Fan's half-
confession) was directed to call at the Shanty and see Mr. Lancaster.
But, needless to say, it was Jarman's intention to interview the
visitor in place of Frank. Thus, if it was a plot in any way--but that
was unlikely, seeing that the sealed letter came from Frank's father--
the young fellow would not run the risk of being arrested.
"I suppose you know that my secretary has left me?" said Eustace,
seeing that Natty did not seem inclined to begin the conversation.
"You came down with Miss Arrow, and she knows. Consequently--"
"Well, she did tell me that Mr. O'Neil had made tracks," interrupted
Natty, calmly, "but she did not mention that he was Lancaster."
Eustace stopped and looked hard at his companion. "You recognised
him, then, Denham?"
"No. I was sold--completely sold, though I knew Lancaster's looks
well enough to spot him. His disguise was very clever, so I got sent
up. Miss Berry told me."
"I thought as much," replied Eustace, with a shrug. "She said she
would say nothing about the matter, and of course she did."
"She told Berry, and I was in the room. And then--" Denham
clenched his fist and looked angry. "They wanted me to play the
spy," he burst out; "but don't you think I'm down here for that
purpose. I've given those two the chuck."
"Why did they wish you to play the spy?" asked Eustace, quietly.
"Well, you see, I come into money when I'm twenty-five. Not from
my father. He was rich, but spent nearly all he had. He left me with
enough to get along on without working, anyhow. But I was told by
Berry, who is my guardian, as you know, that I might inherit a
million. He would not give me particulars, saying he would engineer
the job. That's what brought me over here. Now, it seems that to
get this money, Lancaster has to be found, that he may give
evidence. He has some papers which prove that I am entitled to the
fortune. And Berry, hang, him! asked me to hunt him down."
This statement was a very ingenious one on the part of the Captain,
as it simply set forth that Frank was wanted for a reasonable
purpose. Jarman could not conjecture why Natty should be angered.
"I can't see that in searching for Lancaster you are playing the spy."
Denham looked surprised. "Why, you know that Lancaster was with
you. Miss Berry came down, having discovered it somehow."
"No. I guess she never says more than is needful. But she saw you,
and heard that Frank Lancaster had skipped. Then Berry said that he
was certain you knew the whereabouts of the fellow, and asked me
to come down and try to get the truth from you. That's what I call
acting a spy. Well, I am here, and I came to tell you this."
"He said as much," replied the young man, "but I pointed out that if
Lancaster were to come forward he might be hanged, and that no
fellow could be expected to be such a fool. Upon my word!" said
Denham, walking and talking very fast, "I believe for some reason
that Berry wants the poor chap lynched."
"No, and I don't like Miss Berry. I know too much about both. It's a
pity, Denham--since we are now confidential--that you are with
these people."
"I believe so. My father lived at Los Angeles and the Berrys were
often at our house. My father seemed thick with Berry, and, to tell
you the truth, rather afraid of him. He died a year or so ago, and by
his will I was handed over to Berry on account of this fortune. I was
shunted here to look after it, but if the getting of it includes the
chance of a man being lynched--I pass. I don't need to hang on to
this gang, as I've enough to marry on. Berry can go to blazes for
me. I sha'n't recognise his guardianship any longer."
"I don't see that you ever needed him as a guardian," said Eustace.
"You appear to be well able to look after yourself."
"I reckon not. It's all my own, and I don't let him, or anyone else,
interfere. I'll just cut back to the States, I guess."
Eustace thought for a moment. "Tell me, Mr. Denham, did Berry or
your father say anything about that Scarlet Bat on your arm?"
"No!" Natty stopped short and stared. "You saw that when I was
bathing, I expect. I was stolen by Indians, so my father told me, and
they tattooed the mark. I was a kid then, and don't remember
anything about it. And the queer thing is," added Denham, "that all
London is placarded with the Bat."
"And with the word Tamaroo. Do you know what that means?"
"I guess not. But you do. See here, Jarman, you're up to some
game?"
"I'll tell you that later. We must have a talk when we get in."
"All right," agreed the American, with a keen glance. "I'm glad I
dropped across you, as I don't trust the Berrys a cent now. I always
thought there was something queer about the fortune business. But
before I enter your house I have to deliver a letter to Miss Starth!"
"Ah!" said Eustace, quickly, "from Miss Berry?"
"I know a great deal," replied Eustace, drily, "and I hope to know
more. I'm glad you have been frank with me, Denham. I may be
able to help you a lot. No, don't ask questions now. Deliver your
letter, and when you come to me we can have a talk. There's the
road up to the cottage. _Au revoir_ for an hour."
"You write dis?" he asked, holding out Frank's letter, and when
Jarman nodded, grinned again. "I am Tamaroo," said the black man.
CHAPTER XIX
In a few minutes they were seated in the study. Jarman, since the
departure of Miss Cork, had not sought out another housekeeper, so
he had no fear of eavesdroppers. Denham was likely to be engaged
with Mildred for at least an hour, so the interview between himself
and Tamaroo would not be interrupted. He observed that the negro
was much above the ordinary class. He had a certain dignity about
him, wore none of the barbaric colours in which his race delight,
and, moreover, spoke surprisingly good English. Occasionally he
lisped in the true nigger fashion, but on the whole his speech would
not have disgraced a moderately educated white man. As soon as he
sat down, Tamaroo gravely mounted a pair of spectacles, and took
out a bundle of papers tied up with red tape.
"Yes. It was me, sir." Tamaroo did not say "sah" as an ordinary negro
would have done. "I wanted to know where you were, and as you
were hiding I could do nothing else to make you know that I wanted
to see you."
"Hold on!" said Jarman, seeing the mistake. "How do you know I am
Frank Lancaster?"
"You could not have written this letter if you were not, sir," said
Tamaroo, decisively. "My old master gave a direction to the lady aunt
who looked after you, and it was to be given to you on--"
"No, sir. But I thought you might get the letter before. The mark on
your arm, sir, would draw your attention to the Scarlet Bat on the
walls, and you would ask for the letter."
"But I say, Tamaroo, why do you come along before the time?"
Tamaroo was on his feet before Eustace finished, and in his right
hand he held a revolver.
"Keep back!" he cried shrilly. "You have trapped me, but I fight--yes,
I fight."
Jarman maintained his seat and smoked coolly. "There's no need for
you to fight, man," he said soothingly. "Should I know about the
Scarlet Bat and that letter if I were not Mr. Lancaster's friend?"
"Others know, and they are not friends," said the negro, doubtfully,
but lowering the revolver.
Tamaroo groaned. "I know it," he said, "and if I had only come to
England sooner it would not have happened. I arrived just after the
trouble, and heard that my young master was accused."
"No, sir. Certainly I do not. Captain Berry came to England to try and
get my young master hanged."
"But I am his friend. I may as well tell you that after he got into
trouble he came to me. He stopped for a time, then, being in danger
of discovery, he fled."
Tamaroo moved towards the door. "No, sir," he said sternly; "my old
master told me to read them and to give them to Mr. Lancaster
alone. Oh! tell me where he is, I beg you, sir?"
In his turn Tamaroo replied: "You said that before, sir. It is in the
papers which I carry."
"They will. They contain the whole story of the Scarlet Bat and of
the Indian treasure--"
"Ah!" interpolated Eustace with grim satisfaction. "I knew there was
a treasure. How much, Tamaroo? A million?"
"Yes, sir," said the negro with emotion. "He died a year ago. And I
could not see him die, alas!" he added, much moved.
Tamaroo again shook his head and looked mournful. Then, sinking
his voice to a whisper, he said: "My master was a leper."
"It was I, sir. My master told me to send it, till I could give up the
fortune to my young master."
"Yes, sir. But only to him will I tell the story and give the papers."
"Oh, that's all right," replied Eustace, patting the old man on the
back. "And we'll be able to baffle this conspiracy?"
"Yes," cried Tamaroo, wiping his eyes, "we will save my master."
"By the way," asked Jarman, suddenly, "do you know a young fellow
called Natty Denham?"
"Oh, he's told him as little as he could. But, I say, does Berry know
of the contents of those papers?"
Eustace laughed and nodded. "You needn't worry," he said, "I know
of that. Mrs. Anchor, who is now called Miss Berry, learnt about the
fortune from her husband."
"Yes. But I suspect that Berry killed him. And you were the negro
who was waiting at his house for him."
"I did not wait at the house," said Tamaroo, quietly. "Mr. Anchor was
a friend of my master, and had some of the papers connected with
the fortune of the Scarlet Bat. When he was going after his wife he
told me to come and get them. Then he thought he would give them
to you, and I waited while he visited you. But I grew weary, and
followed. I saw you speaking to Mr. Anchor, and heard the shot!"
"I have come to ask you a question," said Mildred, entering the
room. "Oh!" She started back. "Who is this?"
"Yes," said Tamaroo, with a hanging head. "But I cannot prove it."
"No sir," he replied, looking strangely at the young man; "but who
killed him I cannot say."
After this he refused to say any more, and sat down, seemingly
quite worn out. Jarman, who wished him to be prepared for the
interview with Frank, insisted that he should lie down. So the negro
went to the bedroom formerly occupied by the Irish secretary. He
locked the door when he entered, apparently fearful for the safety of
his papers. Eustace smiled approvingly. Every action of Tamaroo's
showed how devoted he was to Frank Lancaster. He returned to the
room where Mildred still waited with the American.
"It doesn't matter just now," she replied, with a glance at Denham.
"Later I can talk of it. This arrival of Tamaroo has driven all else out
of my head."
"I know all that Frank could tell me," she replied. "My dear Eustace,
Frank has told me all of your doings since he came to you. You don't
mind my calling him Frank, do you?" she said, pleadingly, as she saw
him frown. "He is in such difficulties, and I am so sorry."
Jarman looked at her a little sadly, seeing that she was slipping away
from him. "No," he replied, quietly, "I don't mind. Have you told Mr.
Denham anything?"
"To the Berrys? Not much. I've chucked them. They have been
making use of me, and have been trying to get Lancaster hanged--"
"And are trying," interrupted Eustace, quickly. "It's all right, Mildred.
So sure am I of Denham that I intend to trust him."
"You need have no fear," said Denham, colouring with pleasure. "I'm
straight all through. Don't you trust me, Miss Starth?"
Mildred looked at him with her innocent eyes, and he met her gaze
without dropping his own.
"In that case," said Eustace, rubbing his hands, "Mr. Denham can be
present when Tamaroo explains to Frank."
"Explains what?"
"I've heard him mention Lancaster's name," said Natty, slowly; "but
Tamaroo never came along."
"He lay low, as your countrymen say. But it will all be explained to-
night--in this room."
"He least of all," said Denham. "He doesn't know where I am, and if
by chance he does turn up, I'll keep him going till we can smuggle
back Lancaster to his hole."
"I was educated at a negro university," replied the man. "I am better
educated than many a man of your colour, sir. But later on I will tell
you my story. To-night I must relate what I know of his father to Mr.
Lancaster."
In a few minutes Frank was in the Shanty and shaking hands with
Tamaroo. The old man was much affected at the sight of his
master's son.
"You are not at all like your father, sir," he said, "but like your dear
mother, Heaven bless her!"
"She died in my arms," said Tamaroo, quietly, and then took out his
bundle of papers.
Denham, Frank, and Eustace waited anxiously to hear how the old
negro would begin. Tamaroo untied the bundle and selected a long,
official-looking paper. "The will," he said. "By this, Mr. Frank, you
inherit close on a million if you are not hanged!"
A STRANGE WILL
"Do you mean to say that such a condition is in the will?" asked
Frank.
"Yes, sir. I paid the monthly money through them. I was afraid to
bring the original will with me, as I thought Captain Berry might kill
me to get possession of it. But he has only a copy."
"That is part of the story," said the negro, adjusting his spectacles.
"It is all written out here. But it will be best for me to tell it in my
own way, and then, Mr. Frank, you can read the papers afterwards
when you have time."
Frank looked grim. "I have plenty of time," he said; "the whole
twenty-four hours of the day. But tell the story in your own way."
The negro nodded, and seemed pleased that he was allowed to do
what he liked. The four men were seated at the end of the room
furthest from the window. Outside it was a particularly dark night,
and rain was falling. At times the wind shook the house, which was
old. The blinds of the big, square window at the end, where
Jarman's desk stood, were pulled down, but the curtains had not
been drawn. Occasionally a flare of bluish lightning would show
against the blinds, and more clearly where they did not quite cover
the window. What with the drench of the rain, the howling of the
wind, and the rolling of distant thunder, the noise at times drowned
the negro's voice. Therefore the three who listened were obliged to
bend their heads in order to hear clearly. The lamp was drawn close
to Tamaroo's elbow so that he could refer at his ease to the papers.
But this he rarely did, as he seemed to know what they contained by
heart. He began his narrative by asking questions.
"Oh, I guess I do," replied Natty, nodding. "He didn't die so very
long ago. We hung out in Los Angeles, and Berry was an old friend
of the governor's."
"Quite so," nodded Tamaroo; "and he was the ruin of your father. He
induced him to drink more than was good."
Natty, who had not quite got over the contempt of the American for
the black race, would have replied in rather a fiery manner, but that
Tamaroo gave him no time.
"Oh, certainly. The daughter of his sister, and a very wicked woman."
"You don't need to add that last," put in Eustace. "I know how she
treated poor Anchor. But go on with the story."
"I must begin at the beginning, then," said Tamaroo, and cleared his
throat. "I need not be very particular as to time," he said, "as the
dates are all in the papers here. I'll just tell you the story as shortly
as possible, and then you can read it at leisure for yourselves."
"I am a very old man," continued Tamaroo. "You mightn't believe it,
but I am over eighty. In my youth I was a slave on a plantation near
New Orleans. I was wickedly treated by a brutal master, and Mr.
Lancaster, seeing me being flogged one day, bought me out of pity. I
was not very young then, but I was strong, and Mr. Lancaster found
that I could work for him. I did. Heaven bless him!" said Tamaroo,
with emotion. "He was a good friend to me. He set me free, and he
sent me to school, where I learnt to talk as I do. Afterwards, when
old, I went to a negro college and learnt still more. But when Mr.
Lancaster bought me I was very ignorant. He was a handsome
young man then, and fond of roving. He took me with him to the
Californian diggings, and we had a wild time. It was there that we
first met Captain Berry."
"I don't know; he had so many. But he was originally a sailor. I think
his true name was Berry, as he used that oftener than the others,
and always when he was well off. When in difficulties he called
himself by other names."
"Such as Sakers, at San Francisco," murmured Eustace. "Ah! that
was because he took to the sea again and lost a schooner in the
South Seas. But when my master met him he was called Banjo
Berry, because he played so well on that instrument. The name took
his fancy, and he kept it."
"And anything else he could lay his hands on," said Denham. "I've
heard him twang the banjo, and he can scrape a bit."
"Berry and my master got on very well, and were always together. I
did not like him myself, and warned Mr. Lancaster against him, but
my master would always have his own way. Then Mr. Denham
came."
"Yes, sir. He was a gay young man then also, and he took a liking to
my master. Berry was friendly with both. The three set to work to
make money at the diggings, but ill-luck pursued them. At last my
master grew disgusted, and thought of returning to England. But
before he went he fancied he would like to travel about Mexico for a
time. He took me with him, but left Berry and Mr. Denham behind at
the diggings. We went into the wilds of Mexico, and had many
adventures--oh very many--and were in much danger. But we came
through all, and I saved my master's life twice."
The old man nodded with a proud look. "I loved my master. He had
saved me from slavery, and what else could I do but save him? For
two years we travelled in the wilds. Then we met with an Indian. He
had been deserted by his tribe and was dying. My master, always
kind, nursed him for a long time; but he grew weak, and at last he
died."
Tamaroo nodded. "You are clever, Mr. Jarman. Yes, this Indian told
my master, when dying, that he knew of a treasure hidden under the
sign of the Scarlet Bat."
Tamaroo looked puzzled. "I do not know what that is," he said
simply, "but the Scarlet Bat was a sign set by the great King
Montezuma on a rock, under which he concealed part of his
treasure. The Indian--he was a cacique--enraged by the desertion of
those who should have saved his life, told the secret to my master."
"No, sir. It was a wild country where there were many Indians. We
should have been killed had we gone alone. My master returned to
the diggings and offered to share the treasure with Berry and with
Mr. Denham, if they would come with him to find it."
"You are not altogether right, Mr. Jarman," said the negro, quietly.
"Only Mr. Denham would go. Berry was making money at the
diggings, and preferred the bird in the hand to the two in the bush.
But he came with us for a little way. Mr. Lancaster, knowing he was a
good shot and a fearless man, wanted him greatly to come, and
promised him a share. But he refused and turned back. We went on
without him."
"So that's how my father made his money," muttered Natty. "He
spent it on a large scale."
"He did, sir," said the negro, gravely. "He spent all he had, with the
exception of that portion he saved for you."
Natty stared and looked angry. "My father was afraid of nothing."
"He was afraid of Berry," insisted Tamaroo. "And Mr. Lancaster was
also afraid."
This time Frank protested. "I can't believe that."
"It is true enough. You see, gentlemen, both Mr. Denham and Mr.
Lancaster married when they got the money. You two gentlemen"--
he looked at Frank and Natty--"were born on the same day."
"It pleased both my master and Mr. Denham, for they were such
good friends. So that you should both be certain of inheriting the
treasure, they had you both tattooed with the Scarlet Bat."
"Oh! was that it," said Natty, thinking of his story of the Indians.
"Mine is on the left arm. And yours, Lancaster?"
"To get the money. He had bad luck at the diggings, and when he
returned to San Francisco he found that the treasure had been
discovered. He claimed a share, which claim was refused."
"I should jolly well think so," said Jarman, emphatically, "considering
Berry did nothing towards getting it. What cheek!"
"So my master and Mr. Denham thought," said the negro, with a
smile. "They refused the claim, and then Berry threatened to kidnap
you two gentlemen. He thought he would then be able to force
those who possessed the treasure to part with some of it. The
tattooing was done so that if the kidnapping took place both of you
would be recognised. But Berry never made the attempt."
ebookbell.com