Exercises in this lecture  previous -- Keyboard shortcut: 'p'  next -- Keyboard shortcut: 'n'  Go to the slide, where this exercise belongs -- Keyboard shortcut: 'u'  

Exercise 1.13
Lexicographic photo file naming ***


Imagine that we have a collection of photo files, named arbitrarily. We also have a list of photo file names (or photo path names) which represents a desired order of the photos. In this exercise we wish to copy the collection of photos to a new destination. At the new destination, the photo files must be renamed lexicographically, relative to the given list of photo names. By that we mean that the name of the first photo file should be "AAA", the next "AAB", the twenty sixth "AAZ", the twenty senventh "ABA", and the last "ZZZ". With this kind of naming, most photo playing devices will show the photos in the desired order (because it will sort the photos alphabetically before showing them).

In the scenario above we have used names of three characters. The number of digits can/should be adopted to the number of photo files. In addition we have used the alphabet of capital letters from 'A' to 'Z'. Other alphabets may, of course, be possible.

Write a function

   (next_photo_name current-photo-name)

which returns the name after current-photo-name, in lexicographic order. Thus, for example

  (next_photo_name "A") => "B"
  (next_photo_name "AA") => "AB"
  (next_photo_name "AAAZ") => "AABA"
  (next_photo_name "HIJK") => "HIJL" 

Make a wise decision about the value of (next_photo_name "ZZZ").

Your function next_photo_name should be recursive. The function is simple in case the last letter in the string is lower than the last letter in the alphabet. A recursive solution is used if the last letter in the string is equal to the last letter of the alphabet.

For test purposes, write a function

  (list-of-photo-names first-name n) 

that generates a list of n photo names, each with the same number of letters as in first-name. As an example

  (list-of-photo-names "AAA" (* 26 26 26))

should generate the full list of all 17576 three letter photo file names from "AAA" to "ZZZ".

Given the functions next-photo-name and list-of-photo-names it is relatively simple to plug it into a useful file copy function, such as this function:

  (define (copy-photos! source-photo-name-list target-photo-name-list source-path destination-path)
    (for-each
      (lambda (source-photo-name target-photo-name)
        (let* ((source (string-append source-path source-photo-name))
               (destination (string-append destination-path target-photo-name)) 
              )
         (if (not (file-exists? destination))
             (copy-file source destination)
             (display-message "Destination file exists" destination "- NO copy made."))
        )
      )
      source-photo-name-list target-photo-name-list))
  
  (copy-photos! 
    some-photo-list
    (list-of-photo-names "AAA" (length some-photo-list))
    ...)

Notice that this function is imperative, a named accordingly (with an exclamation suffix in the function name). Notice also the use of file-exists?, copy-file and display-message (all of which are non R5RS procedures). In the sketch above we assume that a three-letter file length will be appropriate.


Solution