\documentclass[twocolumn]{article}
% \documentclass{article}

\setlength{\oddsidemargin}{-0.5in}
\setlength{\evensidemargin}{-0.5in}
\setlength{\topmargin}{0.0in}
\setlength{\headheight}{0in}
\setlength{\headsep}{0in}
\setlength{\textwidth}{7.0in}
\setlength{\textheight}{9.5in}
\setlength{\parindent}{0in}
\setlength{\parskip}{0.05in}
\setlength{\columnseprule}{0.3pt}

\setlength\columnsep{25pt}

\usepackage{fancyvrb}
\usepackage{relsize}
\usepackage{hyperref}

\usepackage{listings}
\usepackage{amsmath}

\begin{document}

\lstset{xleftmargin=5mm,framexleftmargin=10mm,basicstyle=\footnotesize}

Name: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

Directions: MAKE SURE TO COPY YOUR ANSWERS TO A SEPARATE SHEET FOR SENDING
ME AN ELECTRONIC COPY LATER.

{\bf 1.} (60) In this problem, we will develop a function {\bf
rmnulldirs()}.  It will remove all empty directories within the
specified directory tree.

For instance, say {\bf rmnulldirs()} is invoked on a directory whose
only contents is a subdirectory {\bf u}, which in turn contains further
subdirectories {\bf v} and {\bf w}, with {\bf v} empty.  Within {\bf u}
and {\bf w}, there are nondirectory files {\bf zu} and {\bf zw},
respectively.  The result will be that {\bf v} will be removed, with
nothing else changed.

Note:  {\bf os.rmdir(drcty)} removes the directory whose full path name
is in {\bf drcty}.

Fill in the blanks.  

\begin{lstlisting}
# descends the directory tree rooted at 
# rootdir, removing all empty directories

import os  

def checklocalempty(dummyarg,dir,flst):
   for f in flst:
      fullf = os.path.join(dir,f)
      if   blank (a)  (fullf):
         subdirfls = blank (b) (fullf)
         if blank (c)  :  blank (d)

def rmnulldirs(rootdir):
   fullrootdir =  blank (e)  (rootdir)
   blank (f) (fullrootdir,checklocalempty,None)
\end{lstlisting}

{\bf 2.} (40) In the code below, we have an iterator that fetches words
one at a time from a text file.  (It's actually the same as in Section
6.2.3, but as an ordinary iterator, not a generator.)  Here is an
example:

The file {\bf x} consists of

\begin{lstlisting}
abc de f
 g
 h ij
klm nopq rstuv
\end{lstlisting}

We run the code:

\begin{lstlisting}
>>> from wordfetch import *
>>> g = wordfetch(open('x'))
>>> for word in g: print word
... 
abc
de
f
g
h
ij
klm
nopq
rstuv
\end{lstlisting}

Fill in the blanks:

\begin{lstlisting}
class wordfetch:
   def __init__(self,fl):
      self.fl = fl
      # words remaining in current line
      self.words = []
   def __iter__(self): return self
   def next(self):
      if self.words == []:
         line =   blank (a)
         # check for end-of-file
         if line == '':  blank (b)
         # remove end-of-line char
         line = line[:-1]
         self.words =  blank (c)
      firstword = self.words[0]
      self.words =  blank (d)
      return firstword
\end{lstlisting}

\end{document}


# descends the directory tree rooted at rootdir, removing all empty
# directories

import os

def checklocalempty(dummyarg,dir,flst):
   for f in flst:
      fullf = os.path.join(dir,f)
      if os.path.isdir(fullf):
         subdirfls = os.listdir(fullf)
         if subdirfls == []:  os.rmdir(fullf)

def rmnulldirs(rootdir):
   fullrootdir = os.path.abspath(rootdir)
   os.path.walk(fullrootdir,checklocalempty,None)

def main():
   rmnulldirs('.')

if __name__ == '__main__': main()





class wordfetch:
   def __init__(self,fl):
      self.fl = fl
      # words remaining in current line
      self.words = []
   def __iter__(self): return self
   def next(self):
      if self.words == []:
         line = self.fl.readline()
         # check for end-of-file
         if line == '': raise StopIteration
         # remove end-of-line char
         line = line[:-1]
         self.words = line.split()
      firstword = self.words[0]
      self.words = self.words[1:]
      return firstword

def main():
   f = wordfetch(open('x'))
   for word in f: print word

if __name__ == '__main__': main()
      
