Chapter 5 Chapter 5
15.5.11 Programming a Decoder
Now that we have a program to turn a message into a sequence of numbers, it would be nice if our friend on the other end had a similar program to turn
5.5. String Methods
the numbers back into a readable message. Let's solve that problem next. Our decoder program will prompt the user for a sequence of Unicode numbers and then print out the text message with the corresponding characters. This program presents us with a couple of challenges; we'll address these as we go along.
The overall outline of the decoder program looks very similar to the encoder program. One change in structure is that the decoding version will collect the characters of the message in a string and print out the entire message at the end of the program. To do this, we need to use an accumulator variable, a pattern we saw in the factorial program from Chapter 3. Here is the decoding algorithm:
get the sequence of numbers to decode message = 11 11
for each number in the input :
convert the number to the corresponding Unicode character add the character to the end of message
print message
Before the loop, the accumulator variable
message
is initialized to be anempty string;
that is, a string that contains no characters( 11 11 ) .
Each time through the loop, a number from the input is converted into an appropriate character and appended to the end of the message constructed so far.The algorithm seems simple enough, but even the first step presents us with a problem. How exactly do we get the sequence of numbers to decode? We don't even know how many numbers there will be. To solve this problem, we are going to rely on some more string manipulation operations.
First, we will read the entire sequence of numbers as a single string using
input .
Then we will split the big string into a sequence of smaller strings, each of which represents one of the numbers. Finally, we can iterate through the list of smaller strings, convert each into a number, and use that number to produce the corresponding Unicode character. Here is the complete algorithm:get the sequence of numbers as a string, inString split inString into a sequence of smaller strings message = 11 11
for each of the smaller strings :
change the string of digits into the number it represent s append the Unicode character for that number to message print message
143
This looks complicated, but Python provides some functions that do just what we need.
You may have noticed all along that I've been talking about string objects.
Remember from the last chapter, objects have both data and operations (they
"know stuff" and "do stuff.") By virtue of being objects, strings have some built-in methods in addition to the generic sequence operations that we have used so far. We'll use some of those abilities here to solve our decoder problem.
For our decoder, we will make use of the
split
method. This method splits a string into a list of substrings. By default, it will split the string wherever a space occurs. Here's an example:>>> myString = "Hello, string methods ! "
>>> myString . split ( )
['Hello, ' , 'string' , 'methods ! ']
Naturally, the
split
operation is called using the usual dot notation for invoking one of an object's methods. In the result, you can see howsplit
has turned the original string"Hello, string methods ! "
into a list of three substrings:"Hello, ", " string",
and"methods ! ".
By the way,
split
can be used to split a string at places other than spaces by supplying the character to split on as a parameter. For example, if we have a string of numbers separated by commas, we could split on the commas:>>> " 32, 24, 25, 57 " . split ( ", " ) [' 32' ' '24' ' '25' ' '57']
This is useful for getting multiple inputs from the user without resorting to the use of
eval.
For example, we could get the x and y values of a point in a single input string, turn it into a list using thesplit
method, and then index into the resulting list to get the individual component strings as illustrated in the following interaction:>>> coords = input ( " Enter the point coordinates (x, y) : " ) . split ( ", " ) Enter the point coordinates (x, y) : 3.4, 6.25
>>> coords
[ ' 3 . 4' ' ' 6 . 25 ' ]
>>> coords [O]
'3.4'
>>coords [1]
'6 . 25'
5.5. String Methods
Of course, we still need to convert those strings into the corresponding numbers.
Recall from Chapter 3 that we can use the type conversion functions
int
andfloat
to convert strings into the appropriate numeric type. In this case, we will usefloat
and combine this all into a couple lines of code:coords = input ( " Enter the point coordinates (x, y) : " ) . split ( ", " ) x, y = float (coords [O] ) , f loat ( coords [1] )
Returning to our decoder, we can use a similar technique. Since our pro
gram should accept the same format that was produced by the encoder pro
gram, namely a sequence of Unicode numbers with spaces between, the default version of
split
works nicely:145
>>> " 87 104 97 1 16 32 97 32 83 1 1 1 1 17 1 14 1 12 1 17 1 15 1 15 33 " . split 0 ['87', '104', '97', '116', '32', '97', '32', '83', '1 1 1', ' 1 17',
'1 14', '1 12', ' 1 17', '1 15', '1 15', '33']
Again, the result is not a list of numbers, but a list of strings. It just so happens these strings contain only digits and
could
be interpreted as numbers. In this case, the strings are int literals, so we'll apply theint
function to each one in order to convert it to a number.Using
split
andint
we can write our decoder program:# numbers2text . py
# A program to convert a sequence of Unicode numbers into
# a string of text .
def main ( ) :
print ( " This program converts a sequence of Unicode numbers into " ) print ( " the string of text that it represents . \n" )
# Get the message to encode
inString = input ( " Please enter the Unicode-encoded message : " )
# Loop through each substring and build Unicode message message = " "
for numStr in inString . split ( ) :
codeNum - int (numStr) # convert digits to a number
message = message + chr ( codeNum) # concatentate character to message
print ( " \nThe decoded message is : ", message) main ( )
Study this program a bit and you should be able to understand exactly how it accomplishes its task. The heart of the program is the loop:
for numStr in inString . split ( ) : codeNum
=int (numStr)
message
=message + chr (codeNum)
The
split
method produces a list of (sub)strings, andnumStr
takes on each successive string in the list. I called the loop variablenumStr
to emphasize that its value is a string of digits that represents some number. Each time through the loop, the next substring is converted to a number byint
ing it. This number is converted to the corresponding Unicode character viachr
and appended to the end of the accumulator,message.
When the loop is finished, every number ininString
has been processed andmessage
contains the decoded text.Here is an example of the program in action: