I l@ve RuBoard Previous Section Next Section

C.9 Chapter 9

  1. Redirecting stdout. This is simple: all you have to do is to replace the first line with:

    import fileinput, sys, string               # no change here
    sys.stdout = open(sys.argv[-1], 'w')        # open the output file
    del sys.argv[-1]                            # we've dealt with this argument
    ...                                         # continue as before
  2. Writing a simple shell. Mostly, the following script, which implements the Unix set of commands (well, some of them) should be self-explanatory. Note that we've only put a "help" message for the ls command, but there should be one for all the other commands as well:

    import cmd, os, string, sys, shutil
    
    class UnixShell(cmd.Cmd):
        def do_EOF(self, line):
            """ The do_EOF command is called when the user presses Ctrl-D (unix)
                or Ctrl-Z (PC). """
            sys.exit()
    
        def help_ls(self):
            print "ls <directory>: list the contents of the specified directory"
            print "                (current directory used by default)"
            
        def do_ls(self, line):
            # 'ls' by itself means 'list current directory'
            if line == '': dirs = [os.curdir]
            else: dirs = string.split(line)
            for dirname in dirs:
                print 'Listing of %s:' % dirname
                print string.join(os.listdir(dirname), '\n')
    
        def do_cd(self, dirname):
            # 'cd' by itself means 'go home'
            if dirname == '': dirname = os.environ['HOME']
            os.chdir(dirname)
    
        def do_mkdir(self, dirname):
            os.mkdir(dirname)
    
        def do_cp(self, line):
            words = string.split(line)
            sourcefiles,target = words[:-1], words[-1] # target could be a dir
            for sourcefile in sourcefiles:
                shutil.copy(sourcefile, target)
    
        def do_mv(self, line):
            source, target = string.split(line)
            os.rename(source, target)
    
        def do_rm(self, line):
            map(os.remove, string.split(line))
    
    class DirectoryPrompt:
        def __repr__(self):
            return os.getcwd()+'> '
    
    cmd.PROMPT = DirectoryPrompt()
    shell = UnixShell()
    shell.cmdloop()

    Note that we've reused the same trick as in Exercise 2 of Chapter 8 to have a prompt that adjusts with the current directory, combined with the trick of modifying the attribute PROMPT in the cmd module itself. Of course those weren't part of the assignment, but it's hard to just limit oneself to a simple thing when a full-featured one will do. It works, too!

    h:\David\book> python -i shell.py
    h:\David\book> cd ../tmp
    h:\David\tmp> ls
    Listing of .:
    api
    ERREUR.DOC
    ext
    giant_~1.jpg
    icons
    index.html
    lib
    pythlp.hhc
    pythlp.hhk
    ref
    tut
    h:\David\tmp> cd ..
    h:\David> cd tmp
    h:\David\tmp> cp index.html backup.html
    h:\David\tmp> rm backup.html
    h:\David\tmp> ^Z

    Of course, to be truly useful, this script needs a lot of error checking and many more features, all of which is left, as math textbooks say, as an exercise for the reader.

  3. Understanding map, reduce and filter. The following functions do as much of the job of map, reduce, and filter as we've told you about; if you're curious about the differences, check the reference manual.

    def map2(function, sequence):
        if function is None: return list(sequence)
        retvals = []
        for element in sequence:
            retvals.append(function(element))
        return retvals
    
    def reduce2(function, sequence):
        arg1 = function(sequence[0])
        for arg2 in sequence[1:]:
            arg1 = function(arg1, arg2)
        return arg1
    
    def filter2(function, sequence):
        retvals = []
        for element in sequence:
            if (function is None and element) or function(element):
                retvals.append(element)
        return retvals
I l@ve RuBoard Previous Section Next Section