Welcome to Day 2 of the Learn IPython in 10 Days mini-course! Today you'll learn about some of IPython's main features, such as syntax highlighting, tab completion, object details, and multiline editing.
By the end of today, you'll know:
- What syntax highlighting and bracket matching are in IPython
- How to create an IPython profile and change the color scheme
- How to use tab completions in IPython
- How to view details about a code object
- What an IPython code block is
- How to edit multiple lines in IPython
Before you start today's lesson, make sure you have a working Python installation on your computer (preferably Python 3.8 or greater). You should also have IPython installed and have worked through the Day 1 lesson:
One of the first things you'll notice about IPython is that, unlike the standard Python REPL which is black and white by default, you get syntax highlighting out-of-the-box:
By default, keywords like
def and built-in function names like
print() are displayed in green, function names in a function definition, like
greet() in the example above, are displayed in blue, and strings are displayed in yellow.
IPython also matches brackets and parentheses by highlighting matched pairs when closing brackets:
Bracket matching makes it easy to see at a glance which bracket or parenthesis is being closed and is especially helpful with nested function calls or nested lists and tuples.
Syntax highlighting is one of those features that feels like a breath of fresh air coming from the standard Python REPL. Depending on your terminal set-up, however, the colors may not be ideal. For example, I find the blue function names difficult to read against a black terminal background.
Fortunately, you can change the default color scheme.
IPython Profiles and Configuration
To change IPython's color scheme, the first thing you need to do is create a new IPython profile. Exit IPython and return to your shell, then execute the following command:
$ ipython profile create
You'll see a message telling you that a default configuration file has been created, along with the location of that configuration file:
[ProfileCreate] Generating default config file: PosixPath('/Users/damos/.ipython/profile_default/ipython_config.py')
Take note of the configuration file's location and open it in your favorite text editor. For example, here's how I open my configuration file from the terminal in Visual Studio Code:
$ code ~/.ipython/profile_default/ipython_config.py
This launches VS Code with the configuration file ready to edit:
There is a lot to take in here, and you'll learn more about configuring IPython in a future lesson. If your editor supports it, press
Cmd+F on macOS) and search for
c.InteractiveShell.colors to find the line for changing the color scheme:
c.InteractiveShell.colors is set to
'Neutral'. But there are three other options:
'NoColor'removes syntax highlight. You probably don't want this.
'Linux'works best on terminals with dark backgrounds.
'LightBG'works best on terminals with light backgrounds.
To change the color scheme, uncomment the line containing
c.InteractiveShell.colors and then change the value to your desired setting.
'Linux', so I'm going to change my color scheme to that:
Save the configuration file and close your text editor. Then launch IPython again and check out your new color scheme:
If you want to go back to the default color scheme, open your configuration file again and change
c.InteractiveShell.colors back to
The standard Python shell has minimal tab completion. For example, if you create a variable called
name on one line, and then type
na<TAB> on another line, the Python shell will try and complete the variable name for you. But IPython offers so much more.
To see IPython tab completions in action, type the letter
g into the prompt and press
Tab. Assuming the function
greet() from the previous example is in your namespace, you'll see that option, as well as several built-ins, displayed in an overlay:
Down arrow key to enter the overlay and then use the arrow keys to select the name you want to use:
Notice that function signatures are shown below the overlay whenever a function is in focus. For instance, with
greet() selected, the signature
function(name) is shown below the overlay. For an even better example of this, select
getattr() to see what a more complex signature looks like:
If the function was defined with type hints, these also show up in the overlay! To select a name to use, use the arrow keys to bring the name into focus. Then press
If you type a few characters of a name into the prompt, and there is only one completion available matching the characters you typed in, the IPython will not show an overlay and will just complete the name for you.
IPython can even infer the types of items in a list, tuple, or dictionary and offer helpful completions based on the type. For instance, create a list with various types of objects in it, like a number, string, and another list:
In : mylist = [3.14, "pi", [3, 1, 4]]
In the next prompt, type
mylist.<TAB> and you'll get an overlay with available methods and attributes for the floating-point number
You can see all the methods and attributes on the string
"pi" by typing
The same goes for lists, like the nested list
[3, 1, 4] inside of
Tab completions are a small, but useful feature, especially if you can't remember the exact name for a method that you want to call on an object!
View Object Details
On Day 1 you learned how to access IPython's help page by typing
? into a prompt and pressing
Enter. The question mark is also used to inspect objects and get help with commands.
For instance, type
print? into a prompt and press
Enter. IPython shows you the
print() function's docstring and tells you what type of object it is:
? works with any code object available in your current namespace, including modules, classes, and variables. If the name doesn't exist — such as trying to get help for the
math module before importing it — IPython will warn you that the object can't be found:
In : math? Object `math` not found.
You can get more details about an object by using two question marks instead of one. This depends on what information is available, however. For example, typing
print?? and pressing
Enter doesn't display any additional information:
For some objects, such as the
Path class from the
pathlib module, inspecting them with
?? shows you a ton of information, including the code used to define them. Import the
pathlib module, then type
pathlib.Path?? and press
In : import pathlib In : pathlib.Path??
IPython displays a screen with all of the information about the
Path class, and even highlights the syntax for its source code:
You can navigate the help page using
PgDown, and the arrow keys. To quit the help page and return to the REPL, press
?? work with objects imported from anywhere, including third-party packages and your own source code files. It's a great way to get help on objects and, in my opinion, offers a significantly better experience than Python's built-in
One of the biggest upgrades the IPython offers over the standard Python shell, as far as basic features go, is multiline editing.
You probably noticed that IPython displays line numbers in the REPL prompt. Really these numbers refer to cells that can contain multiple lines of code, and you can edit each line of code in a cell.
To see this in action, write a function called
absolute_value() that returns the absolute value of a number. (Yes, I know there is a built-in
abs() function! Just roll with me for a minute here.) Type the following code into your prompt:
In : def absolute_value(num): ...: """Returns the absolute value of a number.""" ...: if num > 0: ...: return num ...: else: ...: return -num
Look closely. Do you see a mistake?
What happens if you pass
absolute_value()? It will return
-0.0 since the case where
num = 0 isn't handled explicitly but instead flows into the negative case:
In : absolute_value(0.0) Out: -0.0
That's probably not what you want!
You can fix this in IPython rather easily. Press the
Up arrow twice to bring up the code for the
absolute_value() function. Unlike the standard Python shell, the history isn't recalled line-by-line, but cell-by-cell!
Then you can use the up arrows to move your cursor to the line you want to edit and fix the issue:
Multiline editing is one of those features that you just can't live without once you have it at your disposal. If there's one feature of IPython that sells you on it, this might be it!
But, as you'll see in coming lessons, there are plenty of other features that will make switching from IPython back to the standard IPython REPL hard to do.
Day 2 Activities:
Continue to use IPython in your daily workflow. Keep recording things you like as well as any struggles you encounter.
In addition to that, here are some exercises to get some practice with the new features you learned today:
- Try out all of the color schemes in your profile configuration. Which one do you like the best?
- Practice using
??while coding. For what kind of objects does
??give you more detail? (See the answer below!)
- What happens if you have a syntax error while typing out a multiline function definition? Practice fixing errors like that using multiline editing.
I hope you enjoyed today's lesson. See you tomorrow for Day 3 of Learn IPython in 10 Days.
Day 2 Answers:
What kind of objects does
?? show your more detail for? There are many, but you might notice that only object written in Python get their source code displayed with
??. For example, try importing the
math module and inspecting the
math.sqrt() is implemented in C, not Python, so you can't see its source code!
Enjoying this course? Why not share it with a friend or colleague that you think will benefit from it? Just right-click on this link, copy the URL, and send it to them in an email!