Anything you can do...

Issue familiar commands


In [1]:
pwd


Out[1]:
u'/home/catherine/talks/ipython/ipython-olf2013-talk'

In [2]:
ls


047-validator.sh*  demos.ipy            ipy-no-py.odg    ipy-vs-bash.png    presentation.ipynb        reveal.js/
Abstract.txt       demos.ipynb          ipy-no-py.png    isitpyconyet.com/  presentation.slides.html  serve.sh*
bio.txt            env_validator.ipynb  ipy-vs-bash.odg  LICENSE            README.md

In [3]:
cat bio.txt


A freak accident in 2000 transformed Catherine from a chemical engineering grad student to a database administrator and sometimes reluctant sysadmin, but she didn't gain superpowers until she picked up Python in 2003.  She was PyOhio's first chair and currently leads the Dayton Dynamic Languages group.  She works for Dell KACE, speaks around the region, blogs at catherinedevlin.blogspot.com, and releases code at github.com/catherinedevlin.

and less familiar commands


In [4]:
!wc *.txt


  3  65 410 Abstract.txt
  1  63 444 bio.txt
  4 128 854 total

Populate your aliases


In [5]:
%rehashx

In [6]:
wc bio.txt


  1  63 444 bio.txt

IPython aliases


In [7]:
%alias getpage wget -rkp -np %l

In [8]:
getpage http://isitpyconyet.com/


--2013-09-14 18:33:48--  http://isitpyconyet.com/
Resolving isitpyconyet.com (isitpyconyet.com)... 205.196.219.49
Connecting to isitpyconyet.com (isitpyconyet.com)|205.196.219.49|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 875 [text/html]
Saving to: ‘isitpyconyet.com/index.html’

100%[======================================>] 875         --.-K/s   in 0s      

2013-09-14 18:33:48 (129 MB/s) - ‘isitpyconyet.com/index.html’ saved [875/875]

Loading robots.txt; please ignore errors.
--2013-09-14 18:33:48--  http://isitpyconyet.com/robots.txt
Reusing existing connection to isitpyconyet.com:80.
HTTP request sent, awaiting response... 404 Not Found
2013-09-14 18:33:48 ERROR 404: Not Found.

--2013-09-14 18:33:48--  http://isitpyconyet.com/favicon.ico
Reusing existing connection to isitpyconyet.com:80.
HTTP request sent, awaiting response... 200 OK
Length: 3774 (3.7K) [image/x-icon]
Saving to: ‘isitpyconyet.com/favicon.ico’

100%[======================================>] 3,774       --.-K/s   in 0.002s  

2013-09-14 18:33:48 (1.53 MB/s) - ‘isitpyconyet.com/favicon.ico’ saved [3774/3774]

--2013-09-14 18:33:48--  http://isitpyconyet.com/pycon.js
Reusing existing connection to isitpyconyet.com:80.
HTTP request sent, awaiting response... 200 OK
Length: 924 [application/javascript]
Saving to: ‘isitpyconyet.com/pycon.js’

100%[======================================>] 924         --.-K/s   in 0s      

2013-09-14 18:33:48 (146 MB/s) - ‘isitpyconyet.com/pycon.js’ saved [924/924]

--2013-09-14 18:33:48--  http://isitpyconyet.com/pycon.css
Reusing existing connection to isitpyconyet.com:80.
HTTP request sent, awaiting response... 200 OK
Length: 109 [text/css]
Saving to: ‘isitpyconyet.com/pycon.css’

100%[======================================>] 109         --.-K/s   in 0s      

2013-09-14 18:33:48 (14.8 MB/s) - ‘isitpyconyet.com/pycon.css’ saved [109/109]

FINISHED --2013-09-14 18:33:48--
Total wall clock time: 0.6s
Downloaded: 4 files, 5.5K in 0.002s (2.29 MB/s)
Converting isitpyconyet.com/index.html... 3-0
Converting isitpyconyet.com/pycon.css... nothing to do.
Converted 2 files in 0 seconds.

Use tab completion


In [9]:
free


             total       used       free     shared    buffers     cached
Mem:       3929240    3738684     190556          0     181028    1268724
-/+ buffers/cache:    2288932    1640308
Swap:      3948540     667900    3280640

In [10]:
cat Abstract.txt


Break out of your (bash) shell!  IPython and the IPython Notebook have swept over the Python programming community, but they're not just for Python programmers - they make for superpowered shell replacements even with little to no Python knowledge.  They'll also let you document your work and collaborate with others like never before.  Find out how these beautiful tools can improve your daily Linux work!



In [11]:
%magic

Use scripts


In [12]:
!head 047-validator.sh


#!/bin/sh
# VALIDATOR - Checks to ensure that all environment variables are valid
#   looks at SHELL, HOME, PATH, EDITOR, MAIL, and PAGER
#
# from Wicked Cool Shell Scripts by Dave Taylor
# http://intuitive.com/wicked/wicked-cool-shell-script-library2.shtml

errors=0

in_path()

In [13]:
!./047-validator.sh


** PATH contains invalid directory /home/catherine/.local/bin
Errors encountered. Please notify sysadmin for help.

Better yet, load them into your Notebook


In [14]:
%load 047-validator.sh

In [ ]:
#!/bin/sh
# VALIDATOR - Checks to ensure that all environment variables are valid
#   looks at SHELL, HOME, PATH, EDITOR, MAIL, and PAGER
#
# from Wicked Cool Shell Scripts by Dave Taylor
# http://intuitive.com/wicked/wicked-cool-shell-script-library2.shtml

errors=0

in_path()
{
  # given a command and the PATH, try to find the command. Returns
  # 1 if found, 0 if not.  Note that this temporarily modifies the
  # the IFS input field seperator, but restores it upon completion.
  cmd=$1    path=$2    retval=0

  oldIFS=$IFS; IFS=":"

  for directory in $path 
  do
    if [ -x $directory/$cmd ] ; then
      retval=1      # if we're here, we found $cmd in $directory
    fi
  done
  IFS=$oldIFS
  return $retval
}

validate()
{
  varname=$1    varvalue=$2
  
  if [ ! -z $varvalue ] ; then
    if [ "${varvalue%${varvalue#?}}" = "/" ] ; then
      if [ ! -x $varvalue ] ; then
        echo "** $varname set to $varvalue, but I cannot find executable."
        errors=$(( $errors + 1 ))
      fi
    else
      if in_path $varvalue $PATH ; then 
        echo "** $varname set to $varvalue, but I cannot find it in PATH."
        errors=$(( $errors + 1 ))
      fi
    fi 
  fi
}

####### Beginning of actual shell script #######

if [ ! -x ${SHELL:?"Cannot proceed without SHELL being defined."} ] ; then
  echo "** SHELL set to $SHELL, but I cannot find that executable."
  errors=$(( $errors + 1 ))
fi

if [ ! -d ${HOME:?"You need to have your HOME set to your home directory"} ]
then
  echo "** HOME set to $HOME, but it's not a directory."
  errors=$(( $errors + 1 ))
fi

# Our first interesting test: are all the paths in PATH valid?

oldIFS=$IFS; IFS=":"     # IFS is the field separator. We'll change to ':'

for directory in $PATH
do
  if [ ! -d $directory ] ; then
      echo "** PATH contains invalid directory $directory"
      errors=$(( $errors + 1 ))
  fi
done

IFS=$oldIFS             # restore value for rest of script

# The following can be undefined, and they can also be a progname, rather
# than a fully qualified path.  Add additional variables as necessary for
# your site and user community.

validate "EDITOR" $EDITOR
validate "MAILER" $MAILER
validate "PAGER"  $PAGER

# and, finally, a different ending depending on whether errors > 0

if [ $errors -gt 0 ] ; then
  echo "Errors encountered. Please notify sysadmin for help."
else
  echo "Your environment checks out fine."
fi

exit 0

In [15]:
%%bash
#!/bin/sh
# VALIDATOR - Checks to ensure that all environment variables are valid
#   looks at SHELL, HOME, PATH, EDITOR, MAIL, and PAGER
#
# from Wicked Cool Shell Scripts by Dave Taylor
# http://intuitive.com/wicked/wicked-cool-shell-script-library2.shtml

errors=0

in_path()
{
  # given a command and the PATH, try to find the command. Returns
  # 1 if found, 0 if not.  Note that this temporarily modifies the
  # the IFS input field seperator, but restores it upon completion.
  cmd=$1    path=$2    retval=0

  oldIFS=$IFS; IFS=":"

  for directory in $path 
  do
    if [ -x $directory/$cmd ] ; then
      retval=1      # if we're here, we found $cmd in $directory
    fi
  done
  IFS=$oldIFS
  return $retval
}

validate()
{
  varname=$1    varvalue=$2
  
  if [ ! -z $varvalue ] ; then
    if [ "${varvalue%${varvalue#?}}" = "/" ] ; then
      if [ ! -x $varvalue ] ; then
        echo "** $varname set to $varvalue, but I cannot find executable."
        errors=$(( $errors + 1 ))
      fi
    else
      if in_path $varvalue $PATH ; then 
        echo "** $varname set to $varvalue, but I cannot find it in PATH."
        errors=$(( $errors + 1 ))
      fi
    fi 
  fi
}

####### Beginning of actual shell script #######

if [ ! -x ${SHELL:?"Cannot proceed without SHELL being defined."} ] ; then
  echo "** SHELL set to $SHELL, but I cannot find that executable."
  errors=$(( $errors + 1 ))
fi

if [ ! -d ${HOME:?"You need to have your HOME set to your home directory"} ]
then
  echo "** HOME set to $HOME, but it's not a directory."
  errors=$(( $errors + 1 ))
fi

# Our first interesting test: are all the paths in PATH valid?

oldIFS=$IFS; IFS=":"     # IFS is the field separator. We'll change to ':'

for directory in $PATH
do
  if [ ! -d $directory ] ; then
      echo "** PATH contains invalid directory $directory"
      errors=$(( $errors + 1 ))
  fi
done

IFS=$oldIFS             # restore value for rest of script

# The following can be undefined, and they can also be a progname, rather
# than a fully qualified path.  Add additional variables as necessary for
# your site and user community.

validate "EDITOR" $EDITOR
validate "MAILER" $MAILER
validate "PAGER"  $PAGER

# and, finally, a different ending depending on whether errors > 0

if [ $errors -gt 0 ] ; then
  echo "Errors encountered. Please notify sysadmin for help."
else
  echo "Your environment checks out fine."
fi

exit 0


** PATH contains invalid directory /home/catherine/.local/bin
Errors encountered. Please notify sysadmin for help.

And not just Bash scripts


In [16]:
%%ruby
say = "if that's your thing"
puts say.upcase


IF THAT'S YOUR THING

In [17]:
%%script perl
open (ABSTRACT, 'Abstract.txt');
  while (<ABSTRACT>) {
    $_ =~ s/([A-Z][a-z]*)/reverse($1)/ge; 
    print $_;
 }


kaerB out of your (bash) shell!  InohtyP and the InohtyP koobetoN have swept over the nohtyP programming community, but they're not just for nohtyP programmers - they make for superpowered shell replacements even with little to no nohtyP knowledge.  yehT'll also let you document your work and collaborate with others like never before.  dniF out how these beautiful tools can improve your daily xuniL work!


... I can do better!

Load from URL


In [18]:
%load http://catherinedevlin.pythoneers.com/047-validator.sh

In [ ]:
#!/bin/sh
# VALIDATOR - Checks to ensure that all environment variables are valid
#   looks at SHELL, HOME, PATH, EDITOR, MAIL, and PAGER
#
# from Wicked Cool Shell Scripts by Dave Taylor
# http://intuitive.com/wicked/wicked-cool-shell-script-library2.shtml

errors=0

in_path()
{
  # given a command and the PATH, try to find the command. Returns
  # 1 if found, 0 if not.  Note that this temporarily modifies the
  # the IFS input field seperator, but restores it upon completion.
  cmd=$1    path=$2    retval=0

  oldIFS=$IFS; IFS=":"

  for directory in $path 
  do
    if [ -x $directory/$cmd ] ; then
      retval=1      # if we're here, we found $cmd in $directory
    fi
  done
  IFS=$oldIFS
  return $retval
}

validate()
{
  varname=$1    varvalue=$2
  
  if [ ! -z $varvalue ] ; then
    if [ "${varvalue%${varvalue#?}}" = "/" ] ; then
      if [ ! -x $varvalue ] ; then
        echo "** $varname set to $varvalue, but I cannot find executable."
        errors=$(( $errors + 1 ))
      fi
    else
      if in_path $varvalue $PATH ; then 
        echo "** $varname set to $varvalue, but I cannot find it in PATH."
        errors=$(( $errors + 1 ))
      fi
    fi 
  fi
}

####### Beginning of actual shell script #######

if [ ! -x ${SHELL:?"Cannot proceed without SHELL being defined."} ] ; then
  echo "** SHELL set to $SHELL, but I cannot find that executable."
  errors=$(( $errors + 1 ))
fi

if [ ! -d ${HOME:?"You need to have your HOME set to your home directory"} ]
then
  echo "** HOME set to $HOME, but it's not a directory."
  errors=$(( $errors + 1 ))
fi

# Our first interesting test: are all the paths in PATH valid?

oldIFS=$IFS; IFS=":"     # IFS is the field separator. We'll change to ':'

for directory in $PATH
do
  if [ ! -d $directory ] ; then
      echo "** PATH contains invalid directory $directory"
      errors=$(( $errors + 1 ))
  fi
done

IFS=$oldIFS             # restore value for rest of script

# The following can be undefined, and they can also be a progname, rather
# than a fully qualified path.  Add additional variables as necessary for
# your site and user community.

validate "EDITOR" $EDITOR
validate "MAILER" $MAILER
validate "PAGER"  $PAGER

# and, finally, a different ending depending on whether errors > 0

if [ $errors -gt 0 ] ; then
  echo "Errors encountered. Please notify sysadmin for help."
else
  echo "Your environment checks out fine."
fi

exit 0

In [19]:
<html>
<head>
<meta http-equiv="refresh" content="0; url=http://hotspot.smartcity.com/login.html">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="-1">
</head>
<body>
</body>
</html>


  File "<ipython-input-19-e873a8771a80>", line 1
    <html>
    ^
SyntaxError: invalid syntax

Assign shell results with =!


In [ ]:
ls

In [ ]:
filenames =! ls *.{txt,md}
filenames

Hybrid scripts

  • For every textfile, make a copy as name_stem.bkup.extension.

In [ ]:
for filename in filenames:
    (stem, extension) = filename.split('.')
    newname = stem + ".bkup." + extension
    ! cp {filename} {newname}

In [ ]:
ls *.{md,txt}

And

  • If the file has more than 50 words, set permissions to 400.

In [ ]:
!wc *.bkup.{md,txt}

In [ ]:
bkupfiles =! ls *.bkup.*
for bkupfile in bkupfiles:
    wc_result =! wc {bkupfile}
    wordcount = int(wc_result[0].split()[1])
    print(bkupfile)
    print(wordcount)
    if wordcount > 50:
        !chmod 400 {bkupfile}
        print('making read-only')
    else:
        print('leaving it alone')

In [ ]:
ls -l *.bkup.*

In [ ]:
!chmod 700 *.bkup.*

In [ ]:
!rm *.bkup.*

Expand Python variables in shell commands


In [20]:
for filename in textfilenames:
    !wc -w {filename}


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-20-82e8bbbfb7d5> in <module>()
----> 1 for filename in textfilenames:
      2     get_ipython().system(u'wc -w {filename}')

NameError: name 'textfilenames' is not defined

Hate typing? Automatic parens and quotes available

automatic parens: \


In [21]:
round(82.621, 1)


Out[21]:
82.6

In [22]:
/round 82.621 1


Out[22]:
82.6

one automatically quoted string: ;


In [23]:
len("I wonder how long this sentence is.")


Out[23]:
35

In [24]:
;len I wonder how long this sentence is.


Out[24]:
35

comma-separated list of quoted strings: ,


In [25]:
max("go", "to", "the", "head", "of", "the", "class")


Out[25]:
'to'

In [26]:
,max go to the head of the class


Out[26]:
'to'

or use special SList methods


In [27]:
output =! wc -w *.txt
output


Out[27]:
[' 65 Abstract.txt', ' 63 bio.txt', '128 total']

In [28]:
type(output)


Out[28]:
IPython.utils.text.SList

In [29]:
output.s


Out[29]:
' 65 Abstract.txt  63 bio.txt 128 total'

In [30]:
print(output.s)


 65 Abstract.txt  63 bio.txt 128 total

In [31]:
output.fields()


Out[31]:
[['65', 'Abstract.txt'], ['63', 'bio.txt'], ['128', 'total']]

In [32]:
smallest = 10000000000000
for (char_size, file_name) in output.fields():
    print(file_name + " has " + char_size + " characters")
    size = int(char_size)
    if size < smallest:
        smallest = size
print("Files as small as  " + str(smallest) + " characters!")


Abstract.txt has 65 characters
bio.txt has 63 characters
total has 128 characters
Files as small as  63 characters!

Even works in functions


In [33]:
def wordcount(filename):
    output =! wc -w {filename}
    return int(output[0].split()[0])

wordcount('bio.txt')


Out[33]:
63

In [34]:
textfilenames = !ls *.txt
for filename in textfilenames:
    words = wordcount(filename)
    !echo {filename} has {words} words.


Abstract.txt has 65 words.
bio.txt has 63 words.

HELP!


In [35]:
%quickref

In [36]:
%lsmagic


Out[36]:
Available line magics:
%alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cd  %clear  %colors  %config  %connect_info  %debug  %dhist  %dirs  %doctest_mode  %ed  %edit  %env  %gui  %hist  %history  %install_default_config  %install_ext  %install_profiles  %killbgscripts  %less  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %lsmagic  %macro  %magic  %man  %matplotlib  %more  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %rep  %rerun  %reset  %reset_selective  %run  %save  %sc  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

Available cell magics:
%%!  %%HTML  %%SVG  %%bash  %%capture  %%debug  %%file  %%html  %%javascript  %%latex  %%perl  %%prun  %%pypy  %%python  %%python3  %%ruby  %%script  %%sh  %%svg  %%sx  %%system  %%time  %%timeit  %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

In [37]:
%load?

In [38]:
%load??

Life's big questions

  • Where am I?
  • What have I done?
  • What does it all mean?
  • Look! Look what I did!

Where am I?


In [39]:
pwd


Out[39]:
u'/home/catherine/talks/ipython/ipython-olf2013-talk'

In [40]:
cd ~


/home/catherine

In [41]:
cd /home/catherine/proj/opensourceshakespeare/


/home/catherine/proj/opensourceshakespeare

But where have I been?


In [42]:
cd -0


UsageError: option -0 not recognized ( allowed: "qb" )

In [43]:
cd --olf


/home/catherine/talks/ipython/ipython-olf2013-talk

In [44]:
cd --shakes


/home/catherine/proj/opensourceshakespeare

What have I done?


In [45]:
"ni!".upper()


Out[45]:
'NI!'

In [46]:
In[64]


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-46-3c04d6e7ea24> in <module>()
----> 1 In[64]

IndexError: list index out of range

In [47]:
Out[64]


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-47-a8c87b53b019> in <module>()
----> 1 Out[64]

KeyError: 64

In [48]:
%rerun 64


No lines in history match specification

In [49]:
%logstart


Activating auto-logging. Current session state plus future input saved.
Filename       : ipython_log.py
Mode           : rotate
Output logging : False
Raw input log  : False
Timestamping   : False
State          : active

In [50]:
!head ipython_log.py


# IPython log file

get_ipython().magic(u'pwd ')
get_ipython().system(u'ls -F --color ')
get_ipython().system(u'cat bio.txt')
get_ipython().system(u'wc *.txt')
get_ipython().magic(u'rehashx')
get_ipython().system(u'wc bio.txt')
get_ipython().magic(u'alias getpage wget -rkp -np %l')
get_ipython().system(u'wget -rkp -np http://isitpyconyet.com/ ')

... and the Notebook itself...

Why? What does it all mean?


In [51]:
cd --olf


/home/catherine/talks/ipython/ipython-olf2013-talk

In [52]:
!head 047-validator.sh


#!/bin/sh
# VALIDATOR - Checks to ensure that all environment variables are valid
#   looks at SHELL, HOME, PATH, EDITOR, MAIL, and PAGER
#
# from Wicked Cool Shell Scripts by Dave Taylor
# http://intuitive.com/wicked/wicked-cool-shell-script-library2.shtml

errors=0

in_path()

Complex multi-language process? Fold it into one annotated Notebook!

Worth a thousand words

WARNING: Python ahead


In [53]:
diskuse_raw = !du --max-depth=1 /home/catherine

In [54]:
diskuse_raw.fields()


Out[54]:
[['12508', '/home/catherine/.dropbox'],
 ['400', '/home/catherine/VirtualBox', 'VMs'],
 ['2048', '/home/catherine/projorig'],
 ['4', '/home/catherine/.gphoto'],
 ['92384', '/home/catherine/.opera'],
 ['532', '/home/catherine/Pictures'],
 ['4', '/home/catherine/Public'],
 ['8', '/home/catherine/.htsql'],
 ['48', '/home/catherine/.subversion'],
 ['3882988', '/home/catherine/kace'],
 ['33600', '/home/catherine/.dropbox-dist'],
 ['637840', '/home/catherine/.cache'],
 ['16', '/home/catherine/.gnupg'],
 ['342800', '/home/catherine/keep'],
 ['2892', '/home/catherine/.local'],
 ['2680', '/home/catherine/.wingide4'],
 ['12', '/home/catherine/.tuxpaint'],
 ['96', '/home/catherine/.VirtualBox'],
 ['4', '/home/catherine/Templates'],
 ['18604', '/home/catherine/Calibre', 'Library'],
 ['144272', '/home/catherine/talks'],
 ['107688', '/home/catherine/.config'],
 ['4', '/home/catherine/.continuum'],
 ['571688', '/home/catherine/Ubuntu', 'One'],
 ['4', '/home/catherine/Music'],
 ['4', '/home/catherine/Documents'],
 ['1324404', '/home/catherine/org'],
 ['36', '/home/catherine/.pki'],
 ['8', '/home/catherine/.vim'],
 ['5092260', '/home/catherine/.thunderbird'],
 ['748', '/home/catherine/.freecol'],
 ['85504', '/home/catherine/docs'],
 ['1643072', '/home/catherine/proj'],
 ['150740', '/home/catherine/.mozilla'],
 ['56', '/home/catherine/.matplotlib'],
 ['8', '/home/catherine/.gnome2'],
 ['505652', '/home/catherine/sw'],
 ['10172', '/home/catherine/.gem'],
 ['4', '/home/catherine/dwhelper'],
 ['2317320', '/home/catherine/Downloads'],
 ['4', '/home/catherine/vmshare'],
 ['53516', '/home/catherine/pers'],
 ['4', '/home/catherine/.gnome2_private'],
 ['688', '/home/catherine/.gstreamer-0.10'],
 ['380', '/home/catherine/temp'],
 ['64', '/home/catherine/.java'],
 ['104', '/home/catherine/.ssh'],
 ['1705372', '/home/catherine/Dropbox_safe'],
 ['12', '/home/catherine/bin'],
 ['4', '/home/catherine/Desktop'],
 ['445812', '/home/catherine/ve'],
 ['676', '/home/catherine/.pip'],
 ['1453964', '/home/catherine/Videos'],
 ['4', '/home/catherine/u1'],
 ['1644404', '/home/catherine/Dropbox'],
 ['1284344', '/home/catherine/anaconda'],
 ['23572624', '/home/catherine']]

In [55]:
diskuse = [[int(line[0]), line[1]] 
           for line in diskuse_raw.fields()[:-1] 
           if int(line[0]) > 1000000]

In [56]:
diskuse


Out[56]:
[[3882988, '/home/catherine/kace'],
 [1324404, '/home/catherine/org'],
 [5092260, '/home/catherine/.thunderbird'],
 [1643072, '/home/catherine/proj'],
 [2317320, '/home/catherine/Downloads'],
 [1705372, '/home/catherine/Dropbox_safe'],
 [1453964, '/home/catherine/Videos'],
 [1644404, '/home/catherine/Dropbox'],
 [1284344, '/home/catherine/anaconda']]

In [57]:
bytes = [b for (b, n) in diskuse]

In [58]:
names = [n for (b, n) in diskuse]

In [59]:
names


Out[59]:
['/home/catherine/kace',
 '/home/catherine/org',
 '/home/catherine/.thunderbird',
 '/home/catherine/proj',
 '/home/catherine/Downloads',
 '/home/catherine/Dropbox_safe',
 '/home/catherine/Videos',
 '/home/catherine/Dropbox',
 '/home/catherine/anaconda']

There are faster ways to extract the columns, but they're harder to understand


In [60]:
%matplotlib inline
import matplotlib.pyplot as plt

In [61]:
plt.pie([bytes for (bytes, name) in diskuse],
        labels=[name for (bytes, name) in diskuse])


Out[61]:
([<matplotlib.patches.Wedge at 0x342a7d0>,
  <matplotlib.patches.Wedge at 0x342ae10>,
  <matplotlib.patches.Wedge at 0x342e390>,
  <matplotlib.patches.Wedge at 0x342e890>,
  <matplotlib.patches.Wedge at 0x342ee10>,
  <matplotlib.patches.Wedge at 0x35523d0>,
  <matplotlib.patches.Wedge at 0x35528d0>,
  <matplotlib.patches.Wedge at 0x3552e50>,
  <matplotlib.patches.Wedge at 0x3557410>],
 [<matplotlib.text.Text at 0x342abd0>,
  <matplotlib.text.Text at 0x342e2d0>,
  <matplotlib.text.Text at 0x342e7d0>,
  <matplotlib.text.Text at 0x342ec10>,
  <matplotlib.text.Text at 0x35521d0>,
  <matplotlib.text.Text at 0x3552810>,
  <matplotlib.text.Text at 0x3552c50>,
  <matplotlib.text.Text at 0x3557210>,
  <matplotlib.text.Text at 0x3557790>])

In [62]:
class DiskUse(object):
    def __init__(self, directory='.', max_depth=1, min_bytes = 1000000):
        self.directory = directory
        self.max_depth = max_depth
        self.min_bytes = min_bytes
        self.raw_data =! du --max-depth={self.max_depth} {self.directory}
        self.data = [(int(line[0]), line[1]) for line in self.raw_data.fields()[:-1]]
        self.bytes = [bytes for (bytes, name) in self.data if bytes > self.min_bytes]
        self.names = [name for (bytes, name) in self.data if bytes > self.min_bytes]
    def _repr_html_(self):
        plt.pie(self.bytes, labels=self.names)

In [63]:
DiskUse('/home/catherine')


Out[63]:
<__main__.DiskUse at 0x3416a90>

In [63]: