Previous Section Table of Contents Next Section

Encode Strings Using a Character Map

This function encodes strings using a simple character map. Letters are mapped to the letter that is 13 positions away in the alphabet, so A becomes N (and N becomes A), B becomes O, and so on. In addition, numbers are mapped to the symbol that occupies the same key on a standard U.S. keyboard, so 1 becomes !, 2 becomes @ (and vice versa), and so on. Other characters are left alone.

The built-in function index(), when called on a string, returns the index in the string of the first occurrence of a substring: It raises a ValueError exception if the substring is not found:


location = index("hey there", "th")


The function ord() converts a one-character string to its ASCII value, and chr() does the reverse, converting a number to a one-character string whose ASCII value is that number:


numA = ord("A")   # numA will be 65

strA = chr(65)    # strA will be "A"


Source Code


 1.     numbers = "1234567890"

 2.     symbols = "!@#$%^&*()"

 3.

 4.     def encode ( string ):

 5.       """ Encodes string using a simple mapping

 6.             string: the input string

 7.

 8.             Returns the mapped string.

 9.       """

10.

11.       # fill in the maps; a character at a given position

12.       # in map1 maps to the character at the same position

13.       # in map2, and vice versa.

14.

15.       map1, map2 = [ ], [ ]

16.

17.       # first do the letters, put the first half of the

18.       # alphabet in map1, then the rest in map2...

19.

20.       for k in range(ord("A"), ord("A")+13):

21.           map1.append(chr(k))

22.       for k in range(ord("a"), ord("a")+13):

23.            map1.append(chr(k))

24.       map2 = [chr(ord(x)-13) for x in map1]

25.

26.       # ...now do the numbers/symbols

27.

28.       for k in range(len(numbers)):

29.           map1.append(numbers[k])

30.           map2.append(symbols[k])

31.

32.       newstring = ""

33.

34.       # now map any character in map1 to the character at

35.       # the same position in map2, and any character in map2

36.       # to the same characters in map1.

37.

38.       for c in string:

39.           if (c in map1):

40.               newc = map2[map1.index(c)]

41.           elif (c in map2):

42.               newc = map1[map2.index(c)]

43.           else:

44.               newc = c

45.

46.           newstring = newstring + newc

47.

48.       return newstring


Suggestions

  1. As previously mentioned, the index() function raises a ValueError exception if the substring is not found. Because the program does not catch the exception, it would be an error if it were thrown. Check that this won't happen.

  2. Describe precisely the intended relationship between map1 and map2. Does the initialization of the two variables maintain this relationship?

  3. Think of empty, trivial, and already solved inputs for this function.

  4. Track where the return value newstring is modified and ensure that it is done correctly.

Hints

Walk through the function with the following inputs:

  1. A single lowercase letter: string == "a"

  2. A single uppercase letter: string == "A"

  3. A mix of letters and numbers: string == "abc123"

  4. Letters and a symbol: string == "bye?"

Explanation of the Bug

The code on line 24 to initialize the letter parts of map2


map2 = [chr(ord(x)-13) for x in map1]


has a B.expression error. The code intends to initialize map1 with the letters in the first half of the alphabet and map2 with the letters in the second half. This means that the ASCII values in map2 should be 13 higher than those in map1, so the code should be as follows:


map2 = [chr(ord(x)+13) for x in map1]


As a result of this error, the program maps the letters A through M, in upper- and lowercase, to a random collection of numbers, punctuation, and even other (incorrect) letters based on the happenstance arrangement of the ASCII table. All that mapping then also happens in reverse because of the way the program is designed.

    Previous Section Table of Contents Next Section