Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

THE ULTIMATE

PYTHON GUIDE FOR


VBA DEVELOPERS™

Indenta�on and Control Structures www.pyxll.com pyxll.com 1


TABLE OF CONTENTS

GETTING STARTED ..........................................................................................5


Installing Python 5
First Steps Running Python 6
Writing a Python Script 8

PYTHON CODE EDITORS ............................................................................. 10


Different Python Development Environments 11

INDENTATION AND CONTROL STRUCTURES ............................................ 13


Conditionals 14
Loops 15
Exceptions 17
Control structures Cheat Sheet 19

BASIC DATATYPES ........................................................................................ 20


Collections 20

FUNCTIONS .................................................................................................. 24

MODULES AND PACKAGES ......................................................................... 28


Modules 28
Packages 31

INSTALLING PACKAGES ............................................................................... 33

NUMPY, PANDAS AND SCIPY ..................................................................... 35


NumPy 35
Pandas 36

IPYTHON AND JUPYTER NOTEBOOKS ....................................................... 38


IPython 38
Jupyter Notebooks 40

EXCEL INTEGRATION ................................................................................... 43


Reading and Writing Excel Files 43
Writing Excel Add-Ins 44
WRITE EXCEL
ADD-INS IN
PYTHON
Learning Python is a fantas�c goal and this book will give you the best
possible start on your journey.

As a VBA developer you are no doubt familiar with the benefits of working
in Excel. Just because you’re learning Python doesn’t mean you have to
leave all of that behind!

Did you know you can write Excel add-ins in Python, and call Python code
in place of VBA worksheet func�ons and macros? In fact, with Python you
can do everything you are used to doing in VBA plus a lot more.

Find out how by visi�ng our website h�ps://www.pyxll.com or contact us


for a product tour.

REQUEST DEMO

Download and try out PyXLL for yourself


today. You can download PyXLL and try out
all of its features completely free for 30 days,
and if you have any difficul�es or have any
ques�ons then our support team are always
there and will be happy to help you.

FREE TRIAL
THE ULTIMATE
PYTHON GUIDE FOR
VBA DEVELOPERS™

Everyone’s talking about Python these days! As a VBA developer or Excel user you may
have asked yourself what this means for you and your career, and whether or not you
should learn Python.

This guide will show you that it’s easier than you think, and prepare you for your journey
to become a Python master!

As this is a guide for VBA developers and Excel users, as well as covering everything you
need to know about how to get started with Python and set you on the path to
mastering the Python programming language, we will also cover how to use Python to
work with Excel.

By learning Python you will unlock incredible productivity and tackle difficult
programming problems with ease, but that doesn’t mean you have to give up Excel. The
combina�on of Excel and Python together will be a complete game changer for you and
make you glad you stuck this guide out to the end!

4 pyxll.com The Ul�mate Python Guide For VBA Developers™


GETTING STARTED

One of the benefits of VBA that makes it so accessible is that it’s right there in Office.
There’s no need to install anything extra you can just start using it straight away.

With Python you have to understand that things are a little different. Python is a
programming language without just one single programming interface. Instead Python
runs scripts, wri�en as text files saved on your computer. There are many different tools
to help you write and debug those scripts.

This chapter will take you through installing Python and wri�ng your first Python script.
It’s a li�le more involved than just opening a Python editor but it will help you
understand the mechanics of how Python works. This will set you up to be in a great
posi�on to make the most of other Python tools later.

INSTALLING PYTHON
There are several different distribu�ons of Python. A distribu�on is just what we call the There are
collec�on of the Python program along with packages and other tools to help us write several different
Python code. We’ll come back to what packages are later but for now just know that distribu�ons of
unlike VBA there are mul�ple Python distribu�ons to choose from; ul�mately they are all Python.
Python!

To begin with first we need to choose a Python distribu�on, download it and install it. If
you are completely new to Python then star�ng with Anaconda (h�ps://
www.anaconda.com/) is probably the best op�on for you. Go ahead and download the
latest version now and install it. The Anaconda distribu�on is very large as it contains a
lot of third party packages. These will be useful to you, but not immediately. If you want
a minimal installa�on of Python you can download a smaller distribu�on from h�ps://
www.python.org/downloads/.

Whichever Python distribution you choose, you will have a choice of whether to
download the 32 bit or 64 bit version. If you are interested in wri�ng an Excel add-in with
Python later (which we highly recommend!) choosing the version to match your version
of Excel at this stage will save you �me later. For example, if you are using the 64 bit
version of Excel you should install the 64 bit version of Python.

Different Python Distribu�ons


There are several different Python distribu�ons to choose from. Below is a selec�on of
the most popular ones to choose from. For the purposes of this guide, you can’t go
wrong, any will do just fine! Remember that they’re all Python, and code you write using
one can be used by another. If you change your mind later that’s not going to be a
problem.

Ge�ng Started pyxll.com 5


Anaconda
Anaconda includes all major packages you’re likely to need. Takes up a lot of space and
you won’t need it all, but you won’t have to worry about installing addi�onal packages
later.

Recommended for Python first-�mers.


h�ps://www.anaconda.com/

Python.org
The official Python distribu�on is a complete Python installa�on including the full
standard library of Python packages included. It does not include any of the popular third
party packages included with Anaconda, but these can be installed later. If you want the
very latest version of Python then go for this at it takes �me for the other distribu�ons
to catch up.

Recommended for most users, especially if you need a specific Python version.
h�ps://www.python.org/downloads/

Miniconda
Miniconda is a light-weight version of Anaconda without all the baggage. You can use
Anaconda’s packages but with nothing pre-installed.

Recommended for intermediate or advanced users.


h�ps://docs.conda.io/en/latest/miniconda.html

Microso� Store
If you are using Windows you can install Python from the Microso� Store. This is a really
easy way to get Python installed on your PC. It doesn’t download any addi�onal
packages, but you can add those later as you need. There is no 32 bit version available so
not recommended if you are using the 32 bit version of Office.

Recommended for Windows users who want to get started quickly.


h�ps://www.microso�.com/en-gb/p/python-38/9mssz�1n39l

FIRST STEPS RUNNING PYTHON


This might seem At this stage you’re probably eager to start wri�ng some Python, and might be tempted
a bit “low level” to install a Python code editor or IDE and get cracking – we’ll get to that soon! First
but trust me! though we’ll look at what the Python we’ve just installed actually is and how to use it
without any additional tools. This might seem a bit “low level” but trust me,
understanding this now will really help you get to grips with more advanced Python later.

First of all open a command prompt if you’re using Windows, or terminal window if
you’re using a Mac or Linux. On Windows you can do this by searching for “cmd” in the
start menu and you’ll find the “Command Prompt” applica�on. The command prompt (or
terminal) allows us to run commands, and we’ll use this to show how to run Python
scripts.
Type “where python” into the command prompt and press enter. For Mac or Linux users,
enter “which python” and press enter. This will show us the loca�on of the Python
executable, and it’s this that is used to actually run Python scripts. Whenever we run
some Python code it’s this Python command that’s being used. Some IDEs will need to
know the loca�on of this Python command and now we know how to find it!

Type “where
python” into the
command
prompt and
press enter.

Note: If the Python executable is not found the probable cause is that Python hasn’t
been added to your system PATH when installing it. If that is the case, you will the
installer has added an item to your Start menu (on Windows) to open a special command
prompt for you to use that’s configured to be able to find the Python executable. Use this
command prompt instead of the default one.

Now you have a command prompt or terminal open and Python installed, what happens
if we run the Python executable? Python has a “REPL” mode. “REPL” stands for Read-
Eval-Print-Loop. It Reads a line of code, Evaluates that line, Prints the result and Loops
back ready to read the next line. It’s a bit like the Immediate Window in the Office VBA
editor.

Ge�ng Started pyxll.com 7


To start the Python REPL (commonly referred to as the “Python Prompt”) type “python”
into your command prompt or terminal window and press enter. Now we get to write our
first line of Python code! Type “print(‘Hello’)” and press enter to call Python’s “print”
func�on.

The Python REPL is useful for experimen�ng and running short bits of Python code, but
usually we will write the Python code as scripts or modules – both of which are just plain
text files containing Python code, but named with the file extension “.py”.

WRITING A PYTHON SCRIPT


We saw in the last sec�on how to start the Python executable and run lines of Python
code. Rather than entering code like this line by line, to really use Python we need to be
able to write a sequence of Python commands and be able to run and re-run them. That
is what we call a Python script.
To write a
Python script To write a Python script we don’t need a special editor, any text editor will do. There are
we don’t need a lots of reasons to use a specialized Python editor that we will come to later, but while
special editor, we’re star�ng it’s helpful to understand that all we’re dealing with are plain text files.
any text editor Open any text editor, for example Notepad if you are using Windows or TextEdit on a
will do. Mac. In this file write a couple of lines of code in the same way we did in the REPL. We’ll
just use the “print” command for now but don’t worry we’ll come on to more useful
coding very soon!

Save the file and name it with a “.py” extension. All Python scripts must end with the “.py”
extension and not “.txt” (which your editor may default to). Remember where you saved
the script to as we will need that in order to run it.
Go back to the command prompt that you started in the previous sec�on and quit out of
Python. Depending on the version of Python you have installed you will do that by
pressing Ctrl+Z or Ctrl+D followed by enter.

In the command prompt type “python” followed by the filename of the file you just
saved, including the full path. If you are using Windows, you can type “python” followed
by a space and then drag the file from an Explorer window onto the Command Prompt to
copy the full path without typing it. Then press enter to complete the command.
Congratula�ons! You’ve just run your first Python script!

Congratula�ons!
You’ve just run
your first Python
script!

Now know how to edit and run a Python script we can start exploring the language. Even
if now you run all your future Python scripts via a Python editor and not on the command
line like this, now you understand what’s happening when you run a Python script and
can see there’s nothing complicated about it.

Ge�ng Started pyxll.com 9


PYTHON CODE
EDITORS

So far you have seen how to write a Python script using a simple text editor. Coming
from the Office VBA editor this probably seems like a step backwards! Unlike VBA, there
is no one single Python editor that you have to use. Instead there are many different
ones to choose from. This can be daun�ng for a first �me Python user as how do you
know which to choose?
Using a
Using a dedicated Python editor instead of a simple text editor like Notepad will make
dedicated
wri�ng Python code much easier. A decent Python IDE (Integrated Development
Python editor
Environment) will have the features you are used to from the Office VBA editor such as
instead of a
syntax highligh�ng, auto-comple�on and an interac�ve debugger that will allow you to
simple text step through your code line by line.
editor like
Notepad will You may have heard of Jupyter Notebooks as a way to write and run Python code. We
make wri�ng will come to these later in this guide. They’re a great way of doing interac�ve compu�ng
Python code with Python, but for learning Python and wri�ng re-usable code it’s be�er to start off
much easier. with a Python IDE. Once you’ve got to grips with the Python language and how to write
func�ons and modules you will be in a much be�er posi�on to use Jupyter Notebooks.
Some Python IDEs now include Jupyter Notebooks and so you if you choose one of
those then it will be a very natural progression!

For the rest of this guide we won’t assume any one par�cular IDE so feel free to find one
that works for you. As we now know, Python scripts and modules are just text files so if
you start with one but then want to switch to another later then that won’t be a problem.
You can even install mul�ple different ones and play around with each to see which you
prefer.
All Python IDEs will of at the very least syntax highligh�ng and a way to run your Python
script. Remember, you know how to run a Python script yourself and that’s all the Python
IDE is doing for you! Using an IDE just provides a nicer environment in which to write
and test your Python code in a similar way to the Office VBA editor.

All Python IDEs have the ability to run Python scripts!

DIFFERENT PYTHON DEVELOPMENT ENVIRONMENTS


To help you choose which Python IDE to install we’ve compiled a list of some of the more
popular ones. This isn’t an exhaus�ve list by any means and any Python IDE you decide
to use will be fine! You can switch later since the Python code is just text files and so not
specific to one IDE or another.

Each of these IDEs have their own documenta�on and can be configured to use the
Python distribu�on you’ve recently installed.

PyCharm
PyCharm is one of most comprehensive Python IDEs available. If you are serious about
Python development then this is well worth a look. PyCharm has features to support all
types of Python development, from web development to scien�fic compu�ng and
Jupyter Notebooks. There is a free version (PyCharm CE, Community Edi�on) available
which is very capable although lacks some of the features of the Professional version.
PyCharm is available for all pla�orms.

h�ps://www.jetbrains.com/pycharm/

Python Code Editors pyxll.com 11


Visual Studio Code
Visual Studio Code (or VS Code) is a very popular development environment for many
different languages. Its free and open source, and available for all pla�orms. VS Code is
light weight and feels fast to use. While it’s not a dedicated Python IDE it has great
Python support. Its interac�ve debugger is solid and it has support for Jupyter
Notebooks.

Visual Studio Code


h�ps://code.visualstudio.com/

Python in Visual Studio Code


h�ps://code.visualstudio.com/docs/languages/python

Wing IDE
Wing is a professional Python development environment wri�en solely for Python.
Unlike some of the others it’s not a general purpose IDE with Python support, Wing was
built from the ground up just for Python. It’s easy to setup and get started with and is
very popular with professional Python developers. Wing IDE is a commercial applica�on
but has a free version, and is available on all pla�orms.

Wing IDE
h�ps://wingware.com/

Spyder
Spyder is a free, open source Python IDE. If you’re using the Anaconda Python
distribu�on then you already have it as it’s included! This one is popular with data
scien�sts as it includes some Matlab-like features, but it lacks some other features found
in some of the other IDEs. Spyder is open source for all pla�orms and is included as part
of Anaconda.

Spyder IDE
h�ps://www.spyder-ide.org/

Eclipse and PyDev


Eclipse is free and open source. It was originally a Java IDE but through extensions it has
grown to support many different languages. For Python development it has the PyDev
extension which provides good Python support. It can be a bit trickier to set up than
some of the other IDEs men�oned, but it’s customizable so with a bit of effort you can
configure it just how you want. Eclipse is available for all pla�orms.

Eclipse
h�ps://www.eclipse.org/

PyDev Python Extension for Eclipse


h�p://www.pydev.org/
INDENTATION AND
CONTROL
STRUCTURES

All but the most simple code follows certain condi�onal paths and loops. If X is true then
do Y. For each item in X do Z. That sort of thing! These are what we call control structures
and no doubt you will be very familiar with them already from VBA.

When wri�ng your control structures in VBA you will be used to inden�ng your code as
you write it, or le�ng the VBA editor indent it for you. Such indenta�on makes your code
more readable and look nicer, but it doesn’t actually affect how your code runs.

In Python, indenta�on ma�ers! It’s what people refer to as significant whitespace. This
In Python,
means that the way you indent your code actually affects how the code runs, and if you
indenta�on
get it wrong your code will not do the right thing or may not even by valid.
ma�ers! It’s
Significant whitespace in Python is a controversial issue. Most Python developers agree what people
however that, once you get used to it, it’s a very natural and elegant way to write code. refer to as
Coming from VBA the biggest change you will no�ce is that there is no End X expression significant
in Python. In VBA End is used at the end of a block or control structure, but in Python the whitespace.
end of the indenta�on is the end of the block.

Let’s look at an example. Take the following VBA code:

If condition Then
Debug.Print("Condition is true")
Else
Debug.Print("Condition is not true")
Debug.Print("Indentation is not important")
End If

Debug.Print("All done!")

In VBA the If block is followed by an Else block, which is ended by the End If. The same
code if wri�en in Python looks as follows:

if condition:
print("Condition is true")
else:
print("Condition is not true")
print("Indentation is very important!")

print("All done!")

Indenta�on and Control Structures pyxll.com 13


No�ce how in Python there is no End If. The next statement a�er the else clause is not
indented, and so that means in Python it is not part of that else clause.

In Python, You may have no�ced a couple of other difference too. There is no Then keyword
keywords (like Python. Control statements like if or else are followed by a colon (:) at the end of the line
if, else, for etc.) a�er any condi�on. In Python, keywords (like if, else, for etc...) are all in lowercase.
are all in Python is case sensi�ve so Else is not the same as else. You will need to be careful to
lowercase. always use the correct case in Python! While you are ge�ng used to these differences
your IDE will help you by highligh�ng errors, but it’s best to try and always pay a�en�on
to these small details and get used to the differences between the two languages.

CONDITIONALS
We’ve already seen the if keyword in the previous sec�on. It works in the same way in
Python and VBA. The if keywork is followed by a condi�on, and if that condi�on is true
then the block is executed. If the condi�on isn’t true the op�onal else block is executed
instead.

In Python, an condi�on evaluates to true if it is truthy. It doesn’t actually have to be the


value True or False (the Boolean true and false constants in Python), it can be something
else that’s considered true for the purposes of tes�ng its truthy-ness. This all sounds
very complicated, but really it’s not! If a value is True, 1 (or any number other than zero),
a non-empty string or a non-empty collec�on then it’s considered to be True. Once
you’re aware of this it can save addi�onal checks resul�ng in more concise code.

Here’s an example:

if x != 0:
print("x is not zero")

This can be re-wri�en as:

if x:
print("x is true")

As well as the basic if condi�onal we also have else and an else if as we do in VBA. In
Python, the else if clause is shortened to elif. Here’s an example to illustrate:

if x:
print("x is true")
elif y:
print("x is false but y is true")
elif z:
print("x and y are false but z is true")
else:
print("x, y and z are all false")
LOOPS
A loop is a control structure that executes a block of code a number of �mes, usually un�l
some condi�on is met. VBA has a number of these loop control structures; While, Do
While, Do Un�l, For Next and For Each Next. Python only has two, but we will see how two
is enough to do everything these four in VBA can do! In Python, the two loop control
structures are for and while.

In Python, the keyword for is used for all for loops. Unlike VBA, there is no special for In Python, the
loop for itera�ng through a sequence of numbers and instead Python’s for loop always keyword for is
iterates over a sequence of objects (in Python, everything is an object including used for all for
numbers). Python has some standard func�ons to help create these.
loops.

The following VBA code adds the numbers 0 to 9 (inclusive) using a For Next loop.

Dim Total As Integer


Dim Count As Integer
Total = 0
For Count = 0 To 9
Total = Total + Count
Next Count
Debug.Print("total")

In Python, we use the a for loop combined with the Python func�on range to achieve the
same thing. The range func�on returns what is called an iterator. An iterator provides a
sequence of objects we can iterate over using a for loop. The range func�on can be called
with a single argument stop and will produce a sequence star�ng at zero and ending at
stop – 1. For example, range(3) would produce the sequence of length 3, [0, 1, 2].

Below we use range to count from 0 to 9, remembering that the sequence does not
include the stop value. Note how again the indenta�on is used to indicate the body of
the for loop structure and there is no Next or For.

total = 0
for i in range(10):
total = total + i
print(total)

The range can also be called with the arguments range(start, stop) allowing us to set the
star�ng value. Formally, the values of the sequence i are the numbers where i >= start
and i < stop. A third argument step can be provided to set the increment between steps
in the sequence.

There is only one form of the for loop in Python there is no for each structure. To iterate
over a list of values we use the same for loop we’ve already seen. In Python, a list is
constructed using square braces as follows:

values = [1, 2, 3, 4, 5]
for value in values:
print(value)

Indenta�on and Control Structures pyxll.com 15


While loops execute the code block while a condi�on is true. In Python there is only one
while control structure. In VBA the Do While and Do Un�l control structures can put the
condi�onal test either at the beginning or end of the loop. In Python, the condi�onal test
is always at the start of the loop.

Below is a Do While loop in VBA that prints the value of i while i is less than or equal to 3.
The loop ends once the condi�on is no longer true, when i is greater than 3.

Dim i As Integer
i = 0
Do While i <= 3
Debug.Print(i)
i = i + 1
Loop

In Python the while loop behaves in exactly the same way. Again, note the use of
indenta�on and the block does not need to be explicitly ended. Here we also see the use
of the in-place add operator in Python that adds a number to i.

i = 0
while i <= 3:
print(i)
i += 1

In VBA we can put the While condi�onal test at the end of the loop, but in Python the
test is always at the start. We can get the same effect in Python by breaking out of the
loop once the condi�on is no longer met using Python’s break keyword. In Python, break
is similar to VBA’s Exit.

Dim i As Integer
i = 0
Do
Debug.Print(i)
i = i + 1
Loop While i <= 3

The above loop is different to the first because the test is performed at the end of the
loop rather than the start. It will always print the ini�al value of i, regardless of whether
we set i to be more than 3 ini�ally or not. In the previous example if i was ini�alised to be
more than 3 the body of the loop would not be executed.

In Python we always have to have a test at the start of the while loop and so to get the
same behaviour use a test that is always true and add a second test at the end of the loop
to break out of it. The simplest test that is always true is the Boolean value True.

i = 0
while True:
print(i)
i += 1
if i > 3:
break
Here we have inverted the test so we break out of the loop when i is greater than 3. This
is equivalent to VBA’s Do Un�l control structure. We could have used Python’s not
operator to invert the test if the test was more complicated.

i = 0
while True:
print(i)
i += 1
if not i <= 3:
break

As well as breaking out of the current loop, we can also con�nue to the next itera�on of
the loop using con�nue.

i = 0
while True:
print(i)
i += 1
if i <= 3:
continue
break

When using loops like this it’s important to check through what condi�ons are needed to
terminate the loop so it doesn’t con�nue looping indefinitely, as that will cause our
program to hang!

EXCEPTIONS
In VBA we use On Error to handle unexpected errors in a controlled way. O�en this is In VBA we use
using GoTo or Resume Next. In Python there is no goto concept. Instead, unexpected On Error to
errors are handled as Excep�ons. Python has an excep�on handling control structure try/ handle
except/finally that is used to catch any excep�ons raised by the code inside the try/except unexpected
block. errors in a
controlled way.
The following VBA code sets up an error handler. When we try to evaluate x = 1/0 that
will cause a divide by zero error and the code jumps to the ErrorHandler label.

On Error GoTo ErrorHandler

Dim x As Long
x = 1 / 0

Done:
Exit Sub

ErrorHandler:
Debug.Print("An error occurred")

Indenta�on and Control Structures pyxll.com 17


In Python this would be handled by a try/except block. When the same divide by zero
error occurs, an excep�on is raised. The following Python code shows how we could
handle the same situa�on as above.
try:
x = 1 / 0
except:
print("An error occurred")

You may have used a Switch statement in VBA to handle different types of errors and so
this is the way we do the same thing in Python. In the try/except block we can specify
what type of excep�ons we are expec�ng, and so we can either handle one or more
specific types or all excep�ons (as above).

Generally it is be�er prac�ce to only handle the excep�on types we might expect and
allow other types to bubble up through the program. In the above example, the exact
type of excep�on that will be raised is a ZeroDivisionError so we can explicitly check for
that. We can add mul�ple except blocks to handle different excep�on types. These must
be ordered from most specicifc to least specific as the checks are performed in the order
they are wri�en.

try:
x = 1 / 0
except ZeroDivisionError:
print("A divide by zero error occurred")
except RuntimeError:
print("A runtime error occurred")
except Exception:
print("An unknown error occurred")

To raise an excep�on in Python use the raise keyword. This can be used if there is some
error and will cause the program to jump to the excep�on handler. If there is no
excep�on handler the program will end.

try:
if x <= 0:
raise RuntimeError("Expected x to be greater than 0")
except RuntimeError e:
print(f"A runtime error occurred: {e}")

The above uses a really useful feature of Python called f-strings. We won’t go into those
here, but hopefully the intent is self-explanatory!
CONTROL STRUCTURES CHEAT SHEET
VBA Python Example

If / Else / Elseif /End if / else / elif if x:


print("x is true")

For / End for for x in range(10):


print(x)

For Each / End for for x in [1, 2, 3, 4, 5]:


print(x)

While / Wend while i = 0


while i < 10:
i += 1

Do While / Loop while i = 0


while i < 10:
i += 1

Do / Loop While while / break i = 0


while True:
i += 1
if i >= 10:
break

Do Un�l / Loop while i = 0


while i < 10:
i += 1

Do / Loop Un�l while i = 0


while True:
i += 1
if i >= 10:
break

OnError / GoTo try / except try:


x = 5 / 0
except Exception e:
print(f"Error: {e}")

Indenta�on and Control Structures pyxll.com 19


BASIC DATATYPES

In the last sec�ons we’ve already seen a few of the basic data types in Python, such as
integers,strings and lists. In this sec�on we’ll take a look at some other Python data types
as well as go over some differences between VBA and Python we should be aware of.

Python is what’s Python is what’s known as a dynamically typed language. What this means is that the type
of a variable (integer, floa�ng point, string etc.) is only known when the program runs.
known as a
Some other languages are sta�cally typed, which means variable types can be determined
dynamically
ahead of when the program is run. VBA has op�onal typing because you can use Dim As
typed language.
to declare a variable’s type ahead of using it.

One other interes�ng thing about Python is that everything is an object. In VBA you will
be used to using Set to assign object references, and not needing to use Set for value
types such as integers. In Python there is no such dis�nc�on and everything is an object
reference, even simple types like integers. Variables in Python are really just labels
referring to objects, and those labels can be re-assigned to another object of a different
type.

x = 1 # x is a reference to the integer object 1


x = 2 # x now references a different integer object 2
x = "Hello" # x can be assigned to reference an object
# of a different type

It may seem like an odd detail, but it’s important to remember that variables are just
labels to objects. If you make a change to an object you will affect all the variables that
reference that object, which might not be what you intended to do! Basic types like
integers in Python are immutable (they can’t be modified) for this reason.

Python Type Example

int i = 1

float f = 1.0

bool b = True
b = False
b = f >= 1.0

str s = "a string"


s = f"f-strings in Python are cool! {i}"

COLLECTIONS
Python has a four main collec�on types: lists, tuples, dic�onaries and sets. We have
already come across lists briefly when looking at for loops. All of the collec�on types are
iterators and we can use a for loop to iterate over their contents.
Lists, Arrays and Indexing
In VBA the most common collec�on type is the array. The closest equivalent of the
standard types in Python is the list type. Unlike a VBA array we do not need to declare
the size of the list up-front, nor do we need to manually resize the list before we can add
elements. Unlike a VBA array, a Python list is only a one dimensional list. To represent
mul�-dimensional arrays in Python we must either use a different non-standard type
(such as a numpy array type, which we will come to later) or use a list of lists.

To declare a list in Python we use the square bracket nota�on.

x = [1, 2, 3, 4, 5]
y = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]

Above x is a 1d list of integers, and y is a list of lists of integers.

Lists can be appended to or added together. Remember what we learnt earlier about
changes to an object affec�ng all variables poin�ng to that object? If you append to a list
you are changing the list, but if you add two lists together you create a new list.

x = [1, 2, 3]
x.append(4) # x now contains 1, 2, 3 and 4
y = x + [5] # y contains 1, 2, 3, 4 and 5,
# but x is not changed

Unlike VBA, indexing into a list to fetch an item is also done using the square bracket
Python lists are
nota�on and not using round parentheses. Python lists are always indexed from zero (0).
always indexed
This is an important difference between Python and VBA and worth remembering!
from zero (0).
a = x[0] # a is the first item of list x

List indexes in Python can be nega�ve. A nega�ve index selects an item from the end of
the list. For example, indexing using -1 gets the last item in the list, and -2 gets the
penul�mate one.

z = x[-1] # z is the last item of list x

Python lists can be sliced. This is a really useful feature that lets us get just part of a list.
Slicing is done using the index nota�on “start:stop”. This should seem familiar from what
we saw earlier with the range func�on! The start and stop in the slice nota�on can be
omi�ed and will default to be start and end of the list respec�vely. Combined with
nega�ve indexing this lets us do some convenient things.

y = x[:-1] # try this one for yourself in a Python prompt!

Indexing a list of lists can be done in one go. The first index opera�on selects the inner
list from the outer list, and the second selects from the inner list.

x = [ [1, 2], [3, 4] ]


a = x[0][0] # x[0] selects the inner list,
# x[0][0] selects the item

Basic Datatypes pyxll.com 21


Tuples
A tuple is another collec�on type in Python that is very similar to the list type. The major
difference is that it is immutable, which means once created it cannot be modified.

Tuples are used for a number of things. Using a tuple instead of a list is a clear indica�on
to someone reading your code that the collec�on should not be modified. Tuples are
o�en used as keys to dic�onaries (which we will come to next).

To create a tuple use the () nota�on. It’s the same as construc�ng a list, but using
parentheses. One quirk of the Python grammar is that to create a tuple of length one,
you need a comma a�er the first element.

a = (1, 2, 3, 4, 5) # a is a tuple with 5 values


b = (1, ) # b is a tuple with a single value

Tuples can also be created from any sequence, such as a list. Similarly, lists can also be
created from any sequence, such as a tuple!

x = [1, 2, 3, 4, 5] # x is a list
y = tuple(x) # y is a tuple
z = list(y) # and z is a list!

Indexing and slicing of tuples is iden�cal to lists.

Dic�onaries
A dic�onary is a The dict type (short for dic�onary) is one of the most important and useful types in
type that maps Python. If you have come across the Scrip�ng.Dic�onary type in VBA then you will be
from one object familiar with the concept of a dic�onary. A dic�onary is a type that maps from one object
to another. to another. For example, it could be a mapping of strings represen�ng a country name to
integers represen�ng the popula�on of that country. We call the object that is being
mapped from the key and the object that is being mapped to the value. In the example of
countries to popula�ons the country name is the key and the popula�on number is the
value.

Unlike the VBA Scrip�ng.Dic�onary a Python dict can have keys of types other than
strings. Not any object can be used as a key however. For an object to be used as a key
in a dic�onary it needs to be hashable and comparable. We won’t go into exactly what it
means at this stage, though when you learn about wri�ng your own classes I would
encourage you to go back and learn what these things mean. For now, it is sufficient to
understand that the basic types such as int, float, bool and str can all be used as
dic�onary keys, as can tuples of these types.

Dic�onaries are constructed using curly braces {} and with a colon : separa�ng each key
from its value. They are indexed using the same square bracket [] nota�on as lists and
tuples (that’s how all indexable types are indexed in Python).

bag = {
"apples": 5,
"oranges": 3
}

num_apples = bag["apples"]
num_oranges = bag["oranges"]

We can iterate over a dic�onary using a for loop, just as we can with a list or tuple. The
sequency of items we will see when itera�ng over the dic�onary is the keys.

for key in bag:


value = bag[key]

To avoid having to do this look up to get the item, the dict object has an items method
that returns a sequence of (key, value) tuples.

for key, value in bag.items():


print(f"In my bag I have {value} {key}s")

As well as indexing to retrieve items from the dic�onary we can also set new items or
update exis�ng items in the dic�onary.

bag["lemons"] = 4

There is only ever one value for a key in a dict, and so when se�ng a value like this any
previous value is replaced.

Sets
Sets are another collec�on type very similar to dic�onaries. The difference between a set Sets are
and a dic�onary is that sets have no values, only keys. This might sound like an odd type another
of collec�on and you may be thinking why not just use a list? The benefit of sets is the collec�on type
speed at which you can check whether an item is already in the set or not. It is much very similar to
faster to check if an item is in a set than it is to check if it’s in a list. The �me it takes to dic�onaries.
check if an item is in a list increases linearly with the length of the list, but this is not so
for a set. This makes sets ideal for cases where you need to check for set membership
o�en and where speed is important, or when dealing with poten�ally large numbers of
items.

Sets are constructed using the same curly brace {} nota�on as dic�onaries but with no
values. To create an empty set we construct an instance of the set class directly.

s = {1, 2, 3} # s contains 3 items


z = set() # z is empty

There’s no indexing operator for sets, since there are no values. Instead, items are added
using the add method and we test whether an item is in the list or not using the in

Basic Datatypes pyxll.com 23


operator.

s = {1, 2, 3}
s.add(4) # Adds an item, modifying the original set

if 4 in s:
print("4 is in our set")

if 5 not in s:
print("5 is not in our set")

The constraints for what can be used in a set is the same as what can be a key in a
dic�onary. That is, it must be hashable and comparable. That is, basic types such as int,
float, bool and str, and tuples of those types.

FUNCTIONS

A func�on is a Wri�ng func�ons is essen�al to organizing your code. Not only do func�ons allow you to
re-use code, but they also improve the readability and therefore maintainability of your
block of code
code.
that takes some
inputs and Put simply, a func�on is a block of code that takes some inputs and returns a result. We
returns a result. call the inputs to the func�on arguments or parameters. While a func�on may have many
arguments, it only has one return value (though that return value can be a collec�on,
such as a tuple).

When star�ng to learn to program it is not uncommon to end up with a script many lines
long. A�er a certain length the code becomes hard to follow. Making changes to long
scripts becomes harder the longer the script as tracking down all the consequences of a
change becomes more and more difficult. You may not have done it yourself, but I bet
you have seen VBA subrou�nes many screens long where the intent is not obvious even
a�er a few minutes of reading.

Breaking up a script into a number of func�ons makes code development simpler. It is


much easier to reason about a short script that calls a number of different func�ons, than
a long script that does the same thing but with no func�on calls.

VBA has both func�ons and subrou�nes, using the Func�on and Sub keywords
respec�vely. In Python there are only func�ons. Both VBA func�ons and Python
func�ons return a result. Unlike VBA though, where there is a separate concept of a
subrou�ne that doesn’t return a value, in Python there are only func�ons. If a Python
func�on doesn’t explicitly return a value then it will return the Python value None.

To define a func�on in Python we use the def keyword followed by the name of the
func�on and the arguments it expects. To return a value from the func�on the return
keyword is used.

def celsius_to_fahrenheit(degrees_c):
degrees_f = degrees_c * 1.8 + 32.0
return deg_f

To call the func�on we reference it by name and pass the argument and assign the result
to another variable.

input = 25
ouput = celsius_to_fahrenheit(input)

Func�on Documenta�on
As we’ve seen already, Python is dynamically typed. Here this means that there’s nothing
to stop us passing something other than a number in to this func�on. What would happen
if you passed a string or a collec�on to this func�on instead of a number? Rather than
li�ering your code with checks to make sure each object is of the correct type, it is be�er
(more Pythonic) to instead document the func�on to make it clear what the func�on
expects. Most IDEs will have tool�ps to show you func�on documenta�on when wri�ng
code which can be very helpful.

Consider the following:

def c2f(x):
return x * 1.8 + 32.0

Instead of wri�ng a func�on like this, consider spending a li�le more �me to name the
func�on and its arguments descrip�vely and adding a small amount of documenta�on.
When someone else (or you in a weeks’ �me) next looks at the code again it should be
clear what the intent of the func�on is. It can also help with debugging. If the intent of
the func�on is clear, but the func�on does something else, it’s then apparent how the
func�on should behave and it can be fixed accordingly.

Python func�ons are documented using what’s called a docstring. This is some text
surrounded by triple quotes at the start of the func�on. It is usual to document the
parameters and what the func�on returns too.

def celsius_to_fahrenheit(degrees_c):
"""Convert a temperature in degrees Celsius
to Fahrenheit.

:param degrees_c: Number in degrees Celsius.


:return: Returns the temperature in Fahrenheit.
"""
return degrees_c * 1.8 + 32.0

It’s now clear what the intent of this func�on is, and that the input parameter degrees_c
should be a number. It may have taken an extra thirty seconds or so to write, but wri�ng
func�ons like this will help make your Python code understandable by others and
yourself.

Func�ons pyxll.com 25
Type Hints

We can go one step further with documen�ng our func�on and provide type hints. These
won’t prent us from passing objects of the wrong type to a func�on, but it will provide
more informa�on to anyone using your func�on (including yourself!) and also most IDEs
will recognise these hints to make refactoring your code easier.

For example, the previous func�on can be annotated as follows to specify that the
degrees_c argument should be of type float, and the func�on returns a float.

def celsius_to_fahrenheit(degrees_c: float) -> float:


"""Convert a temperature in degrees Celsius
to Fahrenheit.

:param degrees_c: Number in degrees Celsius.


:return: Returns the temperature in Fahrenheit.
"""
return degrees_c * 1.8 + 32.0

Type hin�ng in Python is a large topic. If you are interested in reading about it further
you can find more informa�on in the Python documenta�on h�ps://docs.python.org/3/
library/typing.html.

Op�onal Arguments
Python When wri�ng func�ons it o�en makes sense for a func�on to have several parameters,
func�ons can but not all of those are always needed, or the same default value can be used in most
cases. Python func�ons can have parameters with default values. If the caller of the
have
func�on omits a parameter with a default value, then the func�on will s�ll be called but
parameters with
with the default values for any missing parameters.
default values.

Parameters with default arguments come a�er parameters without default values when
wri�ng the func�on. For parameters where it is acceptable for that parameter not to
have a value, the Python object None may be used.

def function_with_defaults(a, b=1, c=None):


"""This is an example function. A real function would
have a meaningful description here.
"""
# do some calculation involving a and b
result = a + b

# only do something involving c if c is not None


if c is not None:
result += c

return result
The previous func�on can be called with just a, in which case b and c will be their default
values, or with a and b, or with a, b and c.

x = function_with_defaults(1)
y = function_with_defaults(1, 2)
z = function_with_defaults(1, 2, 3)

Named Arguments
When a func�on has mul�ple op�onal arguments, some�mes you will want to specify
some of those arguments without specifying one or more than come before them. Or, for
func�ons that take a number of arguments, including the argument names when you call
the func�on can make the code easier to read.

Python can pass named arguments to func�ons in a similar way to how named
arguments are passed in VBA. The syntax is a li�le different, but the effect is the same.

To pass a named argument to a func�on in Python use “name=value” when calling the
func�on. Named arguments must come a�er un-named arguments, and the order is not
important.

z = function_with_defaults(1, c=10)

Modules and Packages pyxll.com 27


MODULES AND
PACKAGES

In the previous sec�on we saw how func�ons can be used to create re-usable blocks of
code. Appropriate use of func�ons makes our code more readable and more
maintainable. O�en it makes sense to share these func�ons between mul�ple Python
scripts, or it can be �dier to have them be completely separate from our Python script.

Python modules are the answer to this. As in VBA, Python code can be par��oned into
mul�ple logical modules to help us make sense of our code and to be able to re-use
func�ons from another module.

MODULES
A Python A Python module is no different from a Python script. It is just a text file with the “.py” file
module is no extension. It may surprise you to know that the script you’ve been wri�ng while working
different from a through this guide is also a Python module and can be imported from any other Python
script!
Python script.

Impor�ng a module in Python is done using the import keyword. Once imported we can
reference any func�ons or objects from that module.

# import a module named 'mymodule'


import mymodule

# Call a function 'func' from the module


mymodule.func()

What’s happening here? When we as Python to import a module name “mymodule” it


looks for a file called “mymodule.py” in a list of folders called the Python Path. Most IDEs
will set the Python Path so that your source folder is included. You may need to mark the
folder your source code is in as a source folder in your IDE for it to do that.

If you are running Python from the command line you can set the environment variable
PYTHONPATH to a list of paths where Python should look for your modules.
We can try this without an IDE by crea�ng a file called “mymodule.py” and saving it
somewhere on our PC.

In a command prompt we set the PYTHONPATH environment variable to the folder


where we saved “mymodule.py” and then start Python. This brings up the REPL we saw
earlier, and from that we can import our “mymodule” module.

It’s more convenient to use an IDE and have it set the Python Path correctly, but doing it
this way on the command line takes all the mystery out of how impor�ng works.

Modules and Packages pyxll.com 29


Earlier it was stated that a Python module was no different from a Python script, so what
actually happens when a Python file is imported? The script is run, in the same way as it
would be as if you ran it using Python on the command line. You can try this for yourself,
just add a print statement somewhere in the main body of the module we just wrote.

Now when we import this module the code in the body of the module is run, just in the
way it would be run as a script.

This is an important thing to be aware of when wri�ng Python modules. Anything you
write in the body of the module will be run when the module is imported.

There’s a trick that’s commonly used to avoid code being run when a Python file is
imported as a module, and only run it when that Python file is being run as a script. When
Python imports a module it sets a special module level variable __name__ (that’s two
underscores before and a�er name) to the name of the module. When running a Python
file as a script, that same module level variable __name__ is set to “__main__”. We can use
this to only run code if the module is being run as a script, and not when it’s being
imported. This is really useful for tes�ng where we want to quickly run a module from
our IDE, but we s�ll want to be able to import it from elsewhere.

# This function can be imported and used elsewhere


def func(x, y):
return something

# This is what we want to run if run as a script


def main():
# do something
return

# Call the 'main' function if being run as a script


if __name__ == "__main__":
main()

PACKAGES
In the last sec�on we learnt that Python modules are the same as Python scripts, and as
long as they can be found on the Python Path we can import them from other Python
scripts. This helps us re-use code and organize our project. Python Packages take that to
the next level.

A Python Package is a collec�on of related Python Modules with their own hierarchy A Python
(folder structure). Rather than having all of your Python Modules in a single folder, where Package is a
they will quickly become hard to manage, you can arrange them into a logical structure collec�on of
of folders. related Python
For a folder to be a Python Package, and not just a plain folder, it’s needs to contain a file
Modules with
called “__init__.py” (those are double underscores before and a�er “init” again; you’ll see their own
double underscores a lot in Python). This “__init__.py” file is the root module in our hierarchy (folder
package. For example, if we wanted to change our “mymodule.py” module from the structure).
previous sec�on to a package, all that is needed is to create a new folder for the package
(let’s call it “mypackage”) and copy the contents of the “mymodule.py” file into a new
“__init__.py” file inside the “mypackage” folder.

Modules and Packages pyxll.com 31


This new package “mypackage” is imported in the same way as we imported “mymodule”.
The only difference now is that the “__init__.py” file from the “mypackage” folder is what
gets imported. When copying the contents of “mymodule.py” to ”mypackage/
__init__.py” I changed the print statement so it’s clear that it’s the package being
imported.

There’s no need to use the command line for this. Your Python IDE will let you create the
folder and __init__.py file, but I find it’s always helpful to know exactly what’s happening
‘under the hood’.

Modules can be added to the package by pu�ng them in the package folder. These are
Modules can be imported using as “package.module”. For example, to move our mymodule module to be
added to inside our mypackage package, we would move the file and then import it as
packages by “mypackage.mymodule”.
pu�ng them in
the package
folder.

Here we see that the package __init__.py file is imported first, followed by the module file
mymodule.py that is now inside the package.

Packages can contain other sub-packages as well as modules, allowing you to build up a
hierarchy of modules in whatever way is logical for your applica�on. Keeping you code
organized like this make it easier to manage and also easier to re-use across projects.

Packages are the primary way of sharing Python code with others. In the next sec�on we
will learn how we can install and use third-party packages.
INSTALLING
PACKAGES

The number and diversity of Python Packages available is one of the key factors that has
made Python so popular. Even the most basic Python install contains a large number of
Python modules and packages for us to import and use in our code, but even more can
be found online to download and install.
The main
The main repository of Python packages is the Python Package Index (also known as PyI). repository of
You can find it online and search it at h�ps://pypi.org/. Included in most Python
Python
distribu�ons is the command line tool pip, which is used to download and manage
packages is the
packages downloaded from the Python Package Index PyPI.
Python Package
If you are using the Anaconda or Miniconda Python distribu�on, you can also access Index (also
Anaconda’s own Python Package repositories. Anaconda and Miniconda have their own known as PyI).
command line tool for managing packages called conda which you can use to download
and install packages.

As an example, requests is a popular Python package that makes it simple to send HTTP
requests. It’s used for fetching web data and making REST calls to web services. To install
it using pip run pip install requests on the command line or terminal. If using Anaconda or
Miniconda, use conda install requests instead.

Now we can import requests in our own modules and use all the func�onality it provides!
There are many thousands of Python packages available to help you with your par�cular
applica�on.

Installing Packages pyxll.com 33


What is actually happening when a package is installed like this? Inside your Python
distribu�on there is a folder called “site-packages”. This folder is always added to the
Python Path and so any packages placed in this folder are available to be imported.
When you install a package using pip or conda the package is installed into this “site-
packages” folder.
As you con�nue As you con�nue to learn more about Python you will rely on more and more on third
to learn more party packages. You may work on different projects with different requirements and
about Python want to separate your Python installa�ons so that you can install different versions of
you will rely on the same packages for different projects. Python has a concept of a virtual environment
more and more for this purpose. A virtual environment enables you to set up mul�ple different Python
on third party environments with different sets of packages installed in each. This is useful for more
packages. complex development problems, and for now it is sufficient that you are aware that it
exists.
NUMPY, PANDAS
AND SCIPY

Pandas, NumPy and SciPy are three third party packages that almost all Python Pandas, NumPy
developers will want to use at some point. There are far too many Python packages and SciPy are
available to go into in this guide (but hopefully you have learned enough now to explore packages that
them on your own!), but these three are worthy of special men�on. all Python
There are countless guides on the web to effec�vely using these packages, as well as
developers will
their own documenta�on. This sec�on is intended just to make you aware of these want to use at
packages and to whet your appe�te! some point.

NUMPY
As we saw earlier in this guide the na�ve Python list type is a simple data structure for
dealing with lists of objects. When working with larger n-dimensional arrays of numeric
data a list is not the most efficient, or easiest, data structure to work with. This is where
NumPy comes in.

h�ps://numpy.org/

NumPy provides us with a new type, the ndarray. An ndarray is another array type that
works more efficiently for n-dimensional arrays (include 1d arrays) of numeric types like
floats and integers. Array and matrix opera�ons performed using NumPy are much faster
than their equivalents wri�en in plain Python.

One key reason why NumPy arrays can perform so much faster is that they are what’s
known as homogeneous arrays. That is a fancy way of saying that all items in the array
are of the same type. In NumPy, the data type of the items stored in an array is called the
dtype.

NumPy can be installed using pip (or conda for Anaconda and Miniconda users).

pip install numpy

Once installed we can import it and create a NumPy array from a Python list (or list of
lists) using the array func�on. In the code below we use a feature of Python’s import
statement we’ve not seen before. Using import as lets us import a module or package but

NumPy, Pandas and SciPy pyxll.com 35


give it an alias so we don’t have to keep typing the whole name in our code.

import numpy as np

x = np.array([ [1, 2], [3, 4] ])


y = np.array([ [5, 6], [7, 8] ])
z = x + y
a = z[0, 0]

NumPy arrays There’s a huge amount more to NumPy than covered here. NumPy’s arrays are the
always use founda�on for many other numerical Python packages and so it’s an important package
zero-based to at least be aware of as you con�nue to learn Python.
indexing,
Note: Unlike VBA, NumPy arrays always use zero-based indexing. That means the first
item is indexed with 0 not 1.

PANDAS
If you’re working with arrays of data then the Pandas package will likely be a big help to
you! NumPy is great for efficient opera�ons on matrices and large arrays of data, but it
doesn’t deal with tables of data where each column might be a different type. It also
lacks column and index labels meaning everything has to be indexed numerically which
can be hard to manage.

h�ps://pandas.pydata.org/

A simple descrip�on of Pandas would be to say it was like NumPy with column labels.
That is accurate, but doesn’t tell the whole story. The main data type added by Pandas is
the DataFrame. It allows heterogenous array management (use different data types
within a single DataFrame object) with column labels, which is a massively helpful thing
on its own, but it offers a lot more than that too. It’s like a swiss army knife for your data
wrangling needs!

Installa�on can be done using pip or conda in the same way as other packages.

pip install pandas

A Pandas DataFrame can be constructed in lots of different ways, but one common one
is using a dic�onary of lists. There are methods available for loading a csv file or Excel file
directly into a DataFrame too which make it really quick to get your data into Python.

import pandas as pd

data = {
"A": [1.0, 2.0, 3.0, 4.0, 5.0],
"B": [10, 20, 30, 40, 50],
"C": ['a', 'b', 'c', 'd', 'e']
}

# A DataFrame can be constructed from a dict


df = pd.DataFrame(data)

# Columns can be indexed using their column labels


df["D"] = df["A"] * df["B"]
Once the data is in a DataFrame we can index it in various different ways and even add
new columns. This is really just scratching the surface so I encourage you to read more
about Pandas online if you need to deal with tables of data in your applica�ons!

SCIPY
If you’ve ever
SciPy builds on top of NumPy. Where NumPy gives us the fast, efficient data structures, used a system
SciPy gives us hundreds of mathema�cal algorithms. If you’ve ever used a system like
like MATLAB,
MATLAB, IDL, Octave, R-Lab or SciLab then you’ll find a similar level of func�onality with
IDL, Octave, R-
SciPy.
Lab or SciLab
h�ps://www.scipy.org/ then you’ll find
a similar level of
This guide won’t go into the details of what’s available in SciPy. As with the previous two
func�onality
sec�ons the key point is to understand that it’s available. Before implemen�ng a
standard mathema�cal or sta�s�cal rou�ne yourself, check whether it’s already available with SciPy.
in SciPy!

IPython and Jupyter Notebooks pyxll.com 37


IPYTHON AND
JUPYTER NOTEBOOKS

So far we’ve learnt how to write and run Python code as scripts, using modules and
IPython and packages. We’ve already use the Python command line prompt (the REPL), and seen that
Jupyter there is a choice of IDEs available to help us write our Python code.
Notebooks are
IPython and Jupyter Notebooks are two related tools for Interac�ve Compu�ng. In the
related tools for
same way you might use Excel to visualize and manipulate data interac�vely, you can use
Interac�ve
these Python tools in a similar way. If you’ve used something like MATLAB or R-Studio
Compu�ng. before then this concept will be familiar to you.

You can also use Excel as a front-end to your Python code, allowing you to use Excel for
interac�ve compu�ng with Python instead of VBA. That is something we’ll explore in the
next chapter.

IPYTHON
You may have felt the standard Python prompt is a li�le primi�ve. For quickly running a
line of code it’s fine, but it could be be�er! Fortunately there is an alterna�ve called
IPython.

h�ps://ipython.org/

IPython is a powerful Python shell for interac�ve Python work. We wouldn’t use it to
write code, but it’s really useful for working with code. For example, suppose you’d
written a Python module for loading some data and a collection of functions for
manipula�ng and calcula�ng results from that data. You could write a script to do
everything, but some�mes our work is more itera�ve and explora�ve than that. An
IPython prompt lets you play around with your code and data in a nicer environment
than the plain Python prompt.

To install IPython all that’s needed is to install the IPython package using pip or conda.

pip install ipython


Once installed we can run “ipython” to start the IPython prompt.

For learning Python the IPython prompt is amazingly helpful. Use it to try things out, and
take advantage of its online help to access documenta�on on Python packages and
objects. For example, in the last sec�on were introduced to the pandas package. Why For learning
not try crea�ng a pandas DataFrame object and then see what you can do with that Python the
DataFrame? IPython prompt
is amazingly
helpful.

Press Tab to bring up a list of possible comple�ons, and type “?” a�er an object, func�on,
method, class or module to read any help available. Interac�ng directly with Python in
this way is a fantas�c way to explore APIs and to learn.

IPython and Jupyter Notebooks pyxll.com 39


JUPYTER NOTEBOOKS
Jupyter notebooks are interac�ve, web-based notebooks for working with data and
Jupyter presen�ng ideas. They have become very popular among the data science and other
Notebooks are scien�fic communi�es. A Jupyter notebook provides an easy to use pla�orm for running
an easy to use Python code snippets and visualizing the results easily. Notebooks can be shared, and
pla�orm for there are several online services that host the notebooks in the cloud, making them ideal
for reproducible or peer-reviewed work.
running Python
code snippets. h�ps://jupyter.org/

If you have used an online Jupyter notebook service before you may be wondering why
we didn’t simply start with that and learn Python from there. There’s a good reason for
that. Jupyter notebooks are great for wri�ng snippets of Python code, but that does not
teach you to become a good Python developer. Learning how Python actually works and
building up to Jupyter notebooks with that understanding will make you a much be�er
Python developer in the long run!

Jupyter notebooks started life as an extension to IPython, and even now both projects
are closely related. The Python code you run in Jupyter is running in what’s called an
IPython kernel, and all the IPython func�onality is available to the Jupyter notebook.

To get started with Jypyter notebooks you will need to install JupyterLab. JupyterLab is
the latest incarna�on of Jupyter notebooks and is what we recommend you to use.
JupyterLab is distributed as a Python package and can be installed as any other package
using pip, or conda for Anaconda and Miniconda users.

pip install jupyterlab

Once installed to run JupyterLab we run “jupyter lab” in the command prompt or
terminal.

jupyter lab

This will open a new browser window and navigate to h�p://localhost:8888/lab.


From the main launcher page we can create a new notebook, or load an exis�ng
notebook from the file browser on the le�.

Create a new notebook and you’ll get a black document with a single blank cell at the top
of the page. This blank cell is where we write our Python code! Here’s where it starts to
get interes�ng. We can write some code in that empty cell and run it by pressing the play
icon or using the keyboard shortcut “Shi�+Enter”. This runs the code in that cell and
advances to the next cell where we can enter more code, using the results of the
previous cell. The notebook structure means we can go back to a previous cell and make
changes and re-run it immediately without having to re-run everything in the sheet.

Each cell is just


like a line
entered in
IPython but the
notebook
makes it much
easier to keep
track of what
we’re doing.

Each cell is just like a line entered in IPython but the notebook makes it much easier to
keep track of what we’re doing. We can save the notebook and come back to it later or

IPython and Jupyter Notebooks pyxll.com 41


share it with someone else.

Just like in IPython, the result of running the code in a cell is displayed as output. You can
test this by entering something simple like “1+2” into a cell and running it by pressing
“Shi�+Enter”. You should see “3” displayed under the cell. Unlike IPython however,
Jupyter has the ability to render certain types nicely as forma�ed html and can display
things like pandas DataFrames inline in your notebooks.

As well as returning numbers and DataFrames we can also plot data as charts directly in
a Jupyter notebook. For this we will need one of Python’s many char�ng packages
installed. The best well known of these is matplotlib. The matplotlib package is extremely
capable and even though there are newer alterna�ves, all with different advantages and
disadvantages, you will s�ll want to know matplotlib.

Install matplotlib using pip or conda in the same way as any other package.

pip install matplotlib

A�er installing a new package like this you will need to restart the Jupyter kernel. The
kernel is the Python process that runs the Python code in the notebook. Any �me we
add a new package we need to restart it by pressing the “Restart kernel” bu�on at the
top of the notebook. When restar�ng the kernel we lose all the state of our notebook
and each cell has to be re-run in order. This can be done by repeatedly pressing
“Shi�+Enter” or going to the Run menu and selec�ng “Run All Cells”.

The pandas package we saw previously has integra�on with matplotlib. This makes
plo�ng data in a Jupyter notebook really convenient. To plot some data, construct your
pandas DataFrame and then call the plot method on the DataFrame object to plot it.
There are various op�ons to control how it is plo�ed which are covered in the plot
func�on documenta�on, as well as the pandas online documenta�on.

TIP: We saw earlier that in IPython we can access help using “?”. You can do exactly the
same in Jupyter. For example, to find out more about the DataFrame plot method used
here, try running “df.plot?” in a cell and you will get the func�on help without having to
leave your notebook.
EXCEL INTEGRATION

This guide is for VBA developers, so we hope we don’t have to convince you of the
benefits of using Excel for some workflows! Just because you’re learning Python doesn’t Just because
mean you have to leave Excel behind. We’ll see in this sec�on how you can write Excel you are learning
add-ins in Python, and use Python for all the tasks you currently rely on VBA for and Python doesn’t
more. mean you have
to leave Excel
behind!

READING AND WRITING EXCEL FILES


Excel workbooks are a very common file format for people wan�ng to share data or
produce reports for others to read. Luckily for us, Python has packages that are capable
of reading and wri�ng Excel workbooks.

We saw the Pandas package earlier. Using Pandas is the easiest way to load some data
from an Excel workbook into Python. Before we can do so we need to install an extra
package that Pandas uses to read the Excel file, xlrd.

pip install xlrd

Once xlrd is installed we can use the Pandas func�on read_excel to read an Excel
workbook and load a DataFrame.

import pandas as pd

df = pd.read_excel("C:/Users/tony/Workbooks/Book1.xlsx")

To write a DataFrame as an Excel workbook Pandas has the to_excel method on its
DataFrame object. Before we can use this we need to install yet another package,
openpyxl.

pip install openpyxl

Once openpyxl is installed wri�ng out a DataFrame to an Excel workbook is as easy as it


was to read in.

df = pd.to_excel("C:/Users/tony/Workbooks/Book2.xlsx")

These Pandas methods are great for simple tasks like reading in table data from a single
sheet or wri�ng out a single DataFrame to a workbook. For anything more complex like
wri�ng Excel reports you will want to use some of the other Python tools available.

Excel Integra�on pyxll.com 43


The openpyxl package is the best all round choice for wri�ng Excel workbook files, and
for reading any files that you can’t easily read with Pandas.
h�ps://openpyxl.readthedocs.io/

You can find a roundup of the other Python Excel tools available in the following blog
post.
h�ps://www.pyxll.com/blog/tools-for-working-with-excel-and-python/

WRITING EXCEL ADD-INS


Imagine if you could use everything Python has to offer from within Excel. What would
You can use you do if you could write UDFs (User Defined Func�ons) and macros in Python using all
everything the available Python packages, instead of VBA?
Python has to
offer from Wri�ng Excel add-ins isn’t just limited to C++ developers. You can write fully featured
within Excel. Excel add-ins en�rely in Python, using everything you’ve learned about so far in this
book.

Wri�ng an Excel add-in in Python makes perfect sense. You can write your func�ons and
macros in Python and use Excel as your user-interface where you can call those
func�ons interac�vely. You can build dashboards or live reports in Excel, but using
Python code to do all the calcula�ons.

Installing PyXLL
To start off we need to download and install PyXLL. PyXLL is the tool that will allow us to
expose our own Python code to Excel. The download from www.pyxll.com includes a
free 30 day trial.

h�ps://www.pyxll.com/download.html

Go to the download page on the PyXLL website above and select the version of Python
you are using, and whether you are using the 32 bit or 64 bit version of Excel. At this
stage also check whether you are using the 32 bit of 64 bit version of Python by star�ng
a Python prompt. You when the Python prompt starts it prints which version it is. If it is
different from the Excel version you will either need to install a version of Python that
matches the Excel bit-ness, or install a version of Excel that matches your Python
version. To see what version of Excel you are using, go to File → Account → About Excel.

Once you’ve got matching versions of Excel and Python installed and you’ve downloaded
the relevant version of PyXLL, extract the zip-file wherever you want to install PyXLL
from. In there you’ll see a file named pyxll.cfg. Open this in any text editor and look for
the se�ng executable. Uncomment the executable line in the config and set the value to
be that path of your Python executable. Remember you can use “where python” to find
that!

That’s all the configura�on needed to get started with. Now in Excel go to File → If you have any
Op�ons → Add-Ins → Manage Excel Add-Ins and then browse for the pyxll.xll file that trouble
was included in the zip file. If Excel asks you if you want to copy that file to your add-ins installing PyXLL,
folder select No – we want to leave it where it is. check the user
Included in the downloaded zip file is an example folder with some sample code showing guide or contact
many of the features of PyXLL. There is also an examples.xlsx file included which you can the support
open to check everything is working and see some of the features in ac�on. team.

The installa�on instruc�ons are also available online. If you have any trouble, use the
contact form on the website to contact the PyXLL support team.

h�ps://www.pyxll.com/docs/userguide/installa�on.html

Wri�ng a User Defined Func�on


With PyXLL installed wri�ng our first user defined func�on, or worksheet func�on, in
Python is straigh�orward. You may be familiar with user defined func�ons wri�en in
VBA already; they are func�ons that can be called from the Excel workbook in formulas.
We can put into prac�ce all we’ve learnt about Python so far and write a func�on we can
call from Excel.

Let’s start off with a very simple func�on to test things out. We’ll create a new module
(remember, that’s just a plain text file with the “.py” extension) and in that we’ll declare a
func�on that just adds two numbers together.

To expose our func�on to Excel we use what’s called a decorator. Decorators are an
interes�ng feature of Python that we’ve not come across yet! A decorator is a special
Python func�on that can be applied to another func�on, either to add some informa�on
to the func�on or to change it in some way.

The decorator we’ll be using is xl_func from the pyxll package and it’s used to register our
Python func�on as an Excel worksheet func�on. To apply it, we must first import it and
then use the “@” symbol followed by the decorator name on the line above the func�on
defini�on.

from pyxll import xl_func

@xl_func
def add_two_numbers(x, y):
return x + y

Excel Integra�on pyxll.com 45


Note: We can s�ll import this module as we would with the other modules we wrote
previously. To do so though the pyxll package needs to be installed using “pip install”
followed by the filename of the “.whl” file included in the PyXLL download, e.g.

; change this to where you unzipped PyXLL


cd c:/users/johndoe/pyxll-4.4.2

; change the filename for your version


pip install pyxll-4.4.2-cp37-none-win_amd64.whl

In order for PyXLL to load that func�on and expose it to Excel we need to tell it to import
our new module. Any func�ons decorated with @xl_func when imported by PyXLL will be
exposed to Excel as worksheet func�ons. The modules that PyXLL will import are listed
in the pyxll.cfg config file that we saw earlier. There is also a pythonpath op�on that we
will need to update to include the folder containing our module.

For example, if we called our new module fle “my_new_module.py” and saved it in the
folder “C:/users/johndoe/PythonSrc” then the pyxll.cfg would be updated with the
following se�ngs. At this stage it’s fine to leave the exis�ng example modules and
pythonpath and append our se�ngs to the end of these lists.

[PYXLL]
modules =
my_new_module

[PYTHON]
pythonpath =
C:/users/johndoe/PythonSrc

Once that is done, now when we start Excel with the PyXLL module loaded our Python
func�on “add_two_numbers” is available to us to call directly from Excel! If anything is
not working then check the PyXLL log file, located in the logs folder where you unzipped
PyXLL to.

Note: If Excel is already open it is not necessary to restart it. Instead, go to the PyXLL tab
or the PyXLL menu in the add-ins tab and click “Reload PyXLL”. You can make changes to
your code and reload without having to restart Excel. There is even an “auto_reload”
op�on in the pyxll.cfg file you can enable.
Our Python
func�on is
available for us
to call directly
from Excel!

Although this is a very simple example, hopefully it has got you thinking about the
endless possibili�es for wri�ng your own more complex Python func�ons for you to use
in Excel.

Worksheet func�ons are not just limited to simple numbers or strings. Func�ons can
take arrays of data and return arrays too, allowing us to do data analysis of whole ranges
of data in Excel using Python. Even Python objects themselves can be returned to Excel
and then passed to other Python func�ons. We will look at some examples of this in the
next sec�on, but I also encourage you to play with the PyXLL examples and to take a look
at the PyXLL user guide.

h�ps://www.pyxll.com/docs/userguide/index.html

Using Pandas in Excel


As we’ve seen earlier, Pandas greatly simplifies tasks involving data in Python. It fits
nicely with Excel since both deal with tables of data. We can use Pandas in our Excel
func�ons and write worksheet func�ons that take Pandas DataFrames as arguments and
return them to Excel.

To begin with lets take the earlier example of building a Pandas DataFrame and see what
happens when we return it to Excel. Like before, we add the @xl_func decorator to the
func�on to expose it to Excel and add the module to the pyxll.cfg file if necessary.

from pyxll import xl_func


import pandas as pd

@xl_func
def get_dataframe():
data = {
"A": [1.0, 2.0, 3.0, 4.0, 5.0],
"B": [10, 20, 30, 40, 50],
"C": ['a', 'b', 'c', 'd', 'e']
}

return pd.DataFrame(data)

Excel Integra�on pyxll.com 47


When you call the “=get_dataframe()” in Excel you’ll get a result that looks like
“DataFrame@0”. This is probably not quite what you expected! The value that’s been
returned represents the Python object and it can be passed to other Python func�ons.
Passing around DataFrames like this means that we can pass around large datasets
without having them take up a lot of space in Excel, slowing down our workbook.

To illustrate this, try this second func�on:

@xl_func
def sum_column(df, col):
return df[col].sum()

This func�on takes a pandas DataFrame and a column name, and returns the sum of that
column. We can call this with the result of the earlier func�on “get_dataframe”.

Python objects
can be returned
to Excel and
passed to other
Python
func�ons.

This is useful in some cases, but other �mes we want pass a range of data in to our Excel
func�on. PyXLL lets us do that too. We can set what type a func�on argument should be
when registering our func�on with @xl_func. PyXLL uses this informa�on to convert
from the Excel type to the appropriate Python type. The simplest way to do this is by
passing a func�on signature to the @xl_func decorator.

@xl_func("dataframe, str: float")


def sum_column(df, col):
return df[col].sum()

Here we’re passing a func�on signature to @xl_func as a string. This is what PyXLL uses
tell it how to convert the Excel inputs into Python objects, and how to convert the
Python result to Excel. The types before the colon “:” are the argument types, and the
type a�er is the return type. If an argument can be any type we can use the “var” type.
Many other types are supported and you should refer to the PyXLL user guide for full
documenta�on of these types.

h�ps://www.pyxll.com/docs/userguide/udfs/index.html

Now our sum_column func�on has a func�on signature we can pass a range of data to it
and PyXLL will construct the DataFrame for us.

PyXLL can
automa�cally
construct a
DataFrame from
a range of
values.

DataFrames can just as easily be returned as arrays. All that is needed is to specify the
return type in the func�on signature. You can also use the “auto_resize=True” op�on to
have PyXLL automa�cally resize the formula to fit the size of the DataFrame. Note that
this func�on below has no arguments, so there is nothing before the “:” that separates
the arguments from the return type in the func�on signature.

@xl_func(": dataframe", auto_resize=True)


def get_dataframe():
data = {
"A": [1.0, 2.0, 3.0, 4.0, 5.0],
"B": [10, 20, 30, 40, 50],
"C": ['a', 'b', 'c', 'd', 'e']
}

return pd.DataFrame(data)

DataFrames can
be returned as
ranges using an
auto-resizing
array func�on.

These are simple examples but the ability to be able to pass DataFrames around between
Excel and Python, both as arrays and by object reference, is really powerful. We can use
all the tools in the Pandas package, as well as other third party packages, on Excel data

Excel Integra�on pyxll.com 49


and return results back to Excel. This is perfect for interac�ve analysis and live
dashboards. Remember, the Python code can be used outside of Excel too so you can
have one consistent set of code across any other scripts or applica�ons you develop as
well as in Excel.

There is more informa�on available about how to use Pandas in Excel in the PyXLL user
guide.

h�ps://www.pyxll.com/docs/userguide/pandas.html

Wri�ng Excel Macros in Python


Virtually As a VBA developer you will be well used to wri�ng Excel macros (or “Subs” as they’re
everything in some�mes called, a�er the VBA Sub keyword used to declare them). Virtually everything
Excel can be can be automated in Excel using a macro and it may surprise you to learn that anything
automated you can do in a VBA macro can also be done in Python!
using Python. When wri�ng VBA to interact with Excel you’re using the Excel Object Model. This is the
name for the API that includes the Workbook, Applica�on and Range classes as well as
all the other classes you use when wri�ng VBA macros. The en�re Excel Object Model is
available to other languages using a Microso� technology called COM. Fortunately for us
Python has excellent COM support.

You don’t need to be running Python code inside Excel to call Excel from Python. We will
show how to do that in a moment, but for now start off by installing the pywin32 package
using pip or conda and we’ll see how we can interact with Excel from a plain Python
prompt.

pip install pywin32

With Excel open, start a new Python prompt (or Jupyter notebook even!) and try out the
following code.

from win32com.client import Dispatch

xl = Dispatch("Excel.Application")
xl_range = xl.Range("A1")
xl_range.Value = "Hello!"

Look at cell A1 in your open Excel. We’ve just set the value of that cell using these few
lines of Python! So what’s going on here? First of all Dispatch("Excel.Applica�on") is
finding an Excel COM object owned by the Excel process that’s already running. If Excel
wasn’t already running it would start one but without the window. That Excel.Applica�on
object is exactly the same as the one you are used to from VBA and we can use it to do
everything we can in VBA.

We’ve covered a lot of the language differences between VBA and Python already, but
for more details specifically related to calling the Excel Object Model from Python see
the PyXLL user guide.

h�ps://www.pyxll.com/docs/userguide/vba.html

Now we’ve seen it’s possible to interact with Excel from Python, how can we use that to
write an Excel macro to be called from Excel? For example, in response to a bu�on press
on a worksheet. For this we use PyXLL again.

Macros are defined in almost the same way as worksheet func�ons, but instead of using
@xl_func we use @xl_macro. We will also introduce a new PyXLL func�on – xl_app. The
xl_app func�on gets the same Excel Applica�on object we saw earlier but instead of
ge�ng any current Excel process it always gets the one that our macro is being run by.

The following example is a short Excel macro that sets the value of the currently selected
cell.

from pyxll import xl_macro, xl_app

@xl_macro
def set_current_cell():
# Get the Excel Application object
xl = xl_app()

# Set the value of the selected cell to "Hello"


xl.Selection.Value = "Hello"

Just like a VBA Sub, we can associate this macro with a bu�on or even call it from VBA
using the Applica�on.Run method.
Just like a VBA
Sub a Python
macro can be
linked to a
bu�on in Excel
or called from
VBA using Run.

Excel Integra�on pyxll.com 51


As with worksheet func�ons, PyXLL has support for using Pandas DataFrames from
macros too. The following macro copies a Pandas DataFrame to a range in Excel using
PyXLL’s XLCell class. This XLCell class has op�ons so we can tell it how to convert the
data to Excel, and to auto-resize the range when se�ng the data.

Anything you from pyxll import xl_macro, xl_app, XLCell


can do in VBA import pandas as pd
you can also do
@xl_macro
in Python!
def set_dataframe():
# Get the Excel Application object
xl = xl_app()

# Get the A1 cell


xl_range = xl.Range("A1")

# Get an XLCell object from the range


cell = XLCell.from_range(xl_range)

# Get a DataFrame from somewhere


df = get_dataframe()

# Set the dataframe on the cell and expand


cell.options(type="dataframe",
auto_resize=True).value = df

The most important takeaway from this sec�on is that the en�re Excel Object Model is
available to Python, and so anything you could do in VBA you can also do in Python!
READY TO TAKE THE
NEXT STEP?

At the beginning of this sec�on we stated you can write a complete Excel
add-in in Python, and PyXLL is what makes that possible. This includes not
just the worksheet func�ons and macros that we’ve seen, but real �me data
feeds, ribbon customiza�ons, context menus and more.

Email info@pyxll.com to arrange a product tour. We will help you figure out
how you can use Python to solve any difficul�es you have with your exis�ng
VBA based approach, or give you advice on how Python can help you
achieve your goals. We works with hundreds of clients from Finance,
Engineering, Data Sciences and many other backgrounds and are perfectly
placed to give you the help you need.

There are many more features to PyXLL


than we can cover in this sec�on, and if
you’re interested in learning more then
full details can be found in the user
guide.

USER GUIDE

Download and try out PyXLL for yourself


today. You can download PyXLL and try out
all of its features completely free for 30 days,
and if you have any difficul�es or have any
ques�ons then our support team are always
there and will be happy to help you.

DOWNLOAD PYXLL

Excel Integra�on pyxll.com 53

You might also like