Jupyter notebook (formerly iPython notebook) is the one tool I use every single day.
What's really nice about it, is the perfectly formatted and easily comprehensible output it creates:

Example output Jupyter notebook

Unfortunately this only works with one output, even though we wanted to see data.head() and data.describe(), only the latter is printed. For multiple outputs I would normally have to use a print statement, which isn't formatted very well.

With a small handy trick, we can change the notebook's behaviour to allow multiple outputs. To achieve this, there are only two additional lines of code needed:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

Add these lines to your first cell, where you usually import additional modules and run the cell.

Voilà, after the update, our output will look like this:
Multiple outputs in Jupyter notebook