Compsci 101, Fall 2014, Transform HOWTO

Overview

This section provides a general overview of FileTransform.py in which you will write two functions. You can test these functions before testing the pig-latin and rot13 functions you will write in Transforms.py that are described below. You do not need to edit any of the other given Python files.

You can run the program and it will print the contents of a file to the Eclipse Console window. You will need to transform the data read from a file and print to a file rather than to the Console. Then you will need to write new transforms for pig-latin and rot13. These are described after the Getting Started section below.

Please note when editing the files we provide that you do not remove the comments we provide. In particular the GUI menu looks for a comment right after the def statement in the functions in Transforms.py and if you remove that comment the program will not run. It is ok to remove a comment that is beside code you need to replace.

Getting Started

You will run the provided program FileTransform.py which makes calls to code in Transforms.py as described below.

The main function transform_file will do three tasks by calling functions: you will write code that helps the second and third of these tasks.

  1. Get a file to open
  2. Get a transform to apply to each word and apply it
  3. Get a file to save transformed data to and save it

Each task is described below:

Open a file

When the program starts, a small rocket ship icon will appear in your program dock and, if the file dialog below does not appear, choosing that icon will bring it to the front:

open file

Use this dialog box to choose a file to transform. The data directory that comes with this assignment has the files shown above in it, although you can choose to transform any text file you have.

You will need to create and add a simple.txt datafile that has just a few lines of code. You may find that it is the most helpful in debugging your program.

You can also create additional files to test your program. You should not run it only on large files! Create a file to put in the data folder, by clicking on the data folder to highlight it, then select New>Other>General>Untitled Text File.

Choose a transform and transform

The way we have setup this program, when your program reads the file it creates a list of the lines in the file. Each line is represented by a list of words on that line. This list of lists of strings is returned by the function get_words which is completely written for you. The code then prompts the user for a transform by displaying a menu like the one below:

transform choice

The chosen transform should be applied to each word in the file being transformed. This means you must write code in the function transform to create a new list of lists, with each word in the parameter words being transformed by applying func. For example, if the parameter words is the two lines from a file represented by the two lists below:

[ ["This", "is", "the", "story"], ["of", "a", "streetcar", "named", "Desire"]]

Then if the parameter func represents pig-latin, you'll write code to return this list:

[ ["is-Thay", "is-way", "e-thay", "ory-stay"], ["of-way", "a-way", "eetcar-stray", "amed-nay", "esire-Day"]]

The code you're given in transform returns a copy of the list of words with just the first word transformed as an example. You should modify it to return a copy in which every word is transformed.

Writing the file

After the data from the file has been transformed, a new transformed file should be written. The file dialog below asks the user for a filename to save the transformed words in. Note, by default, it chooses to save files in the same data folder as the original files so use different names (like shown below) when saving your transforms to avoid overwriting the original data files.

save file

The program then calls write_words with a file open for writing and a list of transformed data/words. You must complete write_words so that it writes the transformed data to a file.

Whenever you print something to the console, you should also write it to the file open for output. You do that with the write method for file objects which takes a string as a parameter, two uses shown below:

outfile.write(word)  # to output any string
outfile.write("\n")  # to create a line, write the newline character

To make sure the output file is completely written, the last line of your code must close the file as below:

outfile.close()

This will ensure that all writing to the file happens, that the file is flushed and closed properly.

You will need to test both the code in FileTransform.py that reads and writes a file and the code in Transforms.py that does the transforms.

Once you write a file, you may have to right click on the data folder and refresh in eclipse to see the new file.

There is more detail on writing to files at the bottom of this page.


Transform functions

Modify the Python module named Transforms.py. In this module, start by writing the functions transform_pigify and transform_unpigify that each have a single string parameter and return a string that is either the pig-latin equivalent or that is reversed from pig-latin to normal text, respectively. You are given two transform functions, transform_identity and transform_uppercase, that serve as simple examples.

Pig-latin

These are the rules you should use to convert a word into pig-latin. We're using a hyphen to facilitate translating back from pig-latin to English. In creating pig-latin you will not be concerned with punctuation, so treat every character as either a vowel or not-a-vowel, and punctuation falls into the second category.
  1. If a word begins with 'a', 'e', 'i', 'o', or 'u', then append the string "-way" to form the pig-latin equivalent. Examples:
    Word pig-latin Equivalent
    anchor anchor-way
    elegant elegant-way
    oasis oasis-way
    isthmus isthmus-way
    only only-way

  2. If a word begins with a non-vowel (we will call this a consonant, but it could be a number, punctuation, or something else), move the prefix before the first vowel to the end with "ay" appended. Use a hyphen and treat 'y' as a vowel. If 'y' is the first letter of a word it should be considered a consonant.
    Word pig-latin Equivalent
    computer omputer-cay
    slander ander-slay
    spa a-spay
    pray ay-pray
    yesterday esterday-yay
    strident ident-stray
    rhythm ythm-rhay

  3. Words that begin with a 'qu' should be treated as though the 'u' is a consonant.
    Word pig-latin Equivalent
    quiet iet-quay
    queue eue-quay
    quay ay-quay

A few words will not conform to these rules, but the rules should always be used. If a word contains no vowels it should be treated as though it starts with a vowel. For example "zzz" will be translated to "zzz-way".

It is possible that different words will be transformed to the same pig-latin form. For example, "it" is "it-way", but "wit" is also "it-way" using the rules above.

ROT13

Write a function named transform_rot13 to use a ROT13 cipher to encode/decode a string, and then use this to encode every word in a file. The function transform_rot13 returns a rotated form of its string parameter: def transform_rot13(w): s = "" # write code to concatenate characters to s return s

To convert a letter character to its ROT13 equivalent we suggest using these strings, the find method for String that returns an index, and the string indexing operator.

   a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
   b = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
For example, the letter 'S' in the first string (labeled a above) is found at index 18. Note that a.find("S") will evaluate to 18. Then b[18] represents the encoding for 'S', namely 'F'. You can reverse the roles of the strings a and b since the ROT13 cipher is symmetric.

There are other ways to do the ROT13 cipher using the functions chr, ord and the % operator, but the approach suggested by using indexing and the strings above is much easier to get working.

You can identify non-letters by using the return value of the string find method which will be -1 for non-letters. Alternatively you can use the Python string module to identify letters. For example, the code below generates the output that follows it.

import string for a in "ABCDefg123!,#": if not a in string.letters: print a OUTPUT
    1
    2
    3
    !
    ,
    #

Note that you must import the string module to use its functions and constants, see the Python string docs for full information on the module.

More Detail on Writing to Files

Whenever you print something to the console, you should also write it to the file open for output. This way the transformed words will be written to the console in Eclipse and saved to a file. The current version of function write_words writes to the console only, but it takes a file parameter that you'll use when you modify the function. This is the code you're given: for line in words: for w in line: print w + " ", print Note the inner loop has a comma in the print statement, that keeps the output on a single line. The print statement after the inner loop moves to the next line, because one sub-list of words, which is one line of the transformed file, has been written completely to the console.

You must write the words to a file as well as to the console. To write to a file, you use the file .write method which takes a string as a parameter, two uses are shown below for a variable named outfile:

outfile.write(word) # to end a line, write the newline character outfile.write("\n") To make sure the output file is completely written, the last line of your code must close the file as below: outfile.close() This will ensure that all writing to the file happens, that the file is flushed and closed properly.

This means that completing write_words requires mirroring the print calls to also write to a file using file.write as follows:

Advice

Don't do the output file stuff until you've successfully written piglatin to the console.