# PCC_Exercises_1_with_solutions

Remember: Pair-Programming → take care of your neighbor

# Exercise 1 — Temperature Converter

• Write a generic temperature converter function (Kelvin, Fahrenheit, Celsius → Kelvin, Fahrenheit, Celsius)
• Check it against the one by google
``````

In [1]:

def K_to_C(t):
"""Convert temperature in Kelvin to Celsius"""
return t - 273.15

def F_to_C(t):
"""Convert temperature in Fahrenheit to Celsius"""
return 5*(t-32.)/9.

def C_to_K(t):
"""Convert temperature in Celsius to Kelvin"""
return t + 273.15

def C_to_F(t):
"""Convert temperature in Celsius to Fahrenheit"""
return 32+(t*9/5.)

def tconverter(temp, output_unit):
"""Temperature converter from Kelvin, Fahrenheit, Celsius to Kelvin, Fahrenheit, Celsius.

Input temperature `temp` is a string with unit, e.g. '10C' or '-13F' or '235K'
Output unit `output_unit` is one of 'C', 'F', 'K'
"""
units = ('C', 'F', 'K')
conversion = {'KC': K_to_C,
'FC': F_to_C,
'CK': C_to_K,
'CF': C_to_F}

# check that the input temperature has the right format
if not isinstance(temp, str) or temp[-1] not in units:
raise TypeError('Input temperature '+str(temp)+' has the wrong format!')
# check that requested output unit is known
if output_unit not in units:
raise ValueError('Output unit '+str(output_unit)+' not known!')
# set input unit
input_unit = temp[-1]
# set input temperature
temp = float(temp[:-1])
# convert input temperature to Celsius
if input_unit != 'C':
temp = conversion[input_unit+'C'](temp)
# convert temperature in Celsius to output unit
if output_unit != 'C':
temp = conversion['C'+output_unit](temp)
return temp

``````
``````

In [2]:

tconverter('10C', 'K')

``````
``````

Out[2]:

283.15

``````
``````

In [3]:

tconverter('-123F', 'C')

``````
``````

Out[3]:

-86.11111111111111

``````
``````

In [4]:

tconverter('148F', 'K')

``````
``````

Out[4]:

337.59444444444443

``````
``````

In [5]:

tconverter(10, 'F')

``````
``````

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-bd6667d7779a> in <module>()
----> 1 tconverter(10, 'F')

<ipython-input-1-112f7ba951ae> in tconverter(temp, output_unit)
29     # check that the input temperature has the right format
30     if not isinstance(temp, str) or temp[-1] not in units:
---> 31         raise TypeError('Input temperature '+str(temp)+' has the wrong format!')
32     # check that requested output unit is known
33     if output_unit not in units:

TypeError: Input temperature 10 has the wrong format!

``````
``````

In [6]:

tconverter('123', 'C')

``````
``````

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-b906fec85b3b> in <module>()
----> 1 tconverter('123', 'C')

<ipython-input-1-112f7ba951ae> in tconverter(temp, output_unit)
29     # check that the input temperature has the right format
30     if not isinstance(temp, str) or temp[-1] not in units:
---> 31         raise TypeError('Input temperature '+str(temp)+' has the wrong format!')
32     # check that requested output unit is known
33     if output_unit not in units:

TypeError: Input temperature 123 has the wrong format!

``````
``````

In [11]:

tconverter('12C', 'L')

``````
``````

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-6083c892c24f> in <module>()
----> 1 tconverter('12C', 'L')

<ipython-input-1-112f7ba951ae> in tconverter(temp, output_unit)
32     # check that requested output unit is known
33     if output_unit not in units:
---> 34         raise ValueError('Output unit '+str(output_unit)+' not known!')
35     # set input unit
36     input_unit = temp[-1]

ValueError: Output unit L not known!

``````

# Exercise 2 — A Deception Experiment

• Look for a text online that would be funny to deceive (max 1000 words) [we use here the beginning of Alice in Wonderland as an example: http://sabian.org/alice_in_wonderland1.php ]
• Copy it in a text file
• Create a dictionary of all words with their occurrences [think about what to do with casing, commas, dots, columns, etc.]
• Create a deception dictionary with at least 50 words [a deception dictionary maps a word to another word, e.g. `{'house': 'boat'}`]
• Write one or several functions in order to accomplish the following tasks:
• read two text files, one with an arbitrary text to be deceived and one with a deception map, where every line contains two words ["original word" "mapped word"]
• create and save to a third text file a deceived version of the input text
``````

In [13]:

text = open("text.txt", "r")

``````
``````

In [14]:

# show first ten line of the file (this is not Python)

``````
``````

Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book,' thought Alice `without pictures or conversation?'

So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.

There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, `Oh dear! Oh dear! I shall be late!' (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.

``````
``````

In [15]:

def standardize_word(word):
"""Standardize word.

A standard word is lower cased and only contains alphabetic
characters. Return two strings: (std_word, illegal_chars)
"""
# string containing the illegal characters found in the word
illegal = ''
# make word lower-case
word = word.lower()
if not word.isalpha():
# there are non alphabetic chars in the word
for char in word:
# collect non alphabetic chars
if not char.isalpha():
illegal += char
# remove non alphabetic chars from the word
word = word.translate(None, illegal)
return word, illegal

``````
``````

In [16]:

# initialize the word frequency map
wfreq = {}
# set of illegal (i.e. non alphabetic)characters found in the text
illegal = set()
# word counter
word_count = 0
# iterate over the lines in the input file
for line in text:
# split the line into words
# at this point, words may still contain illegal characters and have mixed case
words = line.split()
# iterate over words in the current line
for word in words:
# standardize words and get back the illegal characters
stdword, illegal_chars = standardize_word(word)
# update set of illegal chars
illegal.update(illegal_chars)
# we have got a new word
word_count += 1
# if the word is already in the dictionary update the counter,
# otherwise initialize the counter
wfreq[stdword] = wfreq.setdefault(stdword, 0) + 1
#if stdword in wfreq:
#    wfreq[stdword] += 1
#else:
#    # the word was not in the dictionary already: initialize the counter
#    wfreq[stdword] = 1

``````
``````

In [17]:

print "Total number of words in the text:", word_count

``````
``````

Total number of words in the text: 253

``````
``````

In [18]:

print "Number of different words:", len(wfreq)

``````
``````

Number of different words: 136

``````
``````

In [19]:

print "Illegal characters in text:", list(illegal)

``````
``````

Illegal characters in text: ['!', '`', "'", ')', '(', '-', ',', '.', ';', ':', '?']

``````
``````

In [20]:

# we now want to see what words are occurring more often:
# Sort the dictionary by value (this a so-called Python idiom)
import operator
wfreq_sorted = sorted(wfreq.items(), key=operator.itemgetter(1), reverse=True)

``````
``````

In [21]:

# print the 50 more frequent words
print wfreq_sorted[:50]

``````
``````

[('the', 13), ('it', 11), ('to', 9), ('of', 8), ('her', 8), ('and', 8), ('a', 8), ('she', 7), ('was', 5), ('very', 4), ('alice', 4), ('or', 4), ('rabbit', 4), ('in', 4), ('had', 3), ('out', 3), ('that', 3), ('but', 3), ('with', 3), ('at', 3), ('when', 3), ('so', 3), ('watch', 2), ('waistcoatpocket', 2), ('dear', 2), ('for', 2), ('pictures', 2), ('across', 2), ('be', 2), ('by', 2), ('on', 2), ('sister', 2), ('oh', 2), ('ran', 2), ('mind', 2), ('as', 2), ('book', 2), ('nothing', 2), ('thought', 2), ('time', 2), ('all', 1), ('remarkable', 1), ('hedge', 1), ('over', 1), ('sleepy', 1), ('its', 1), ('seemed', 1), ('just', 1), ('actually', 1), ('late', 1)]

``````
``````

In [22]:

"""Load a deception map from file.

Expected format is two words per line. If illegal characters
are detected, the behaviour depends on on_error:
if on_error is "fail" throw a ValueError, if on_error is "ignore"
ignore illegal chars.
"""
# initialize the deception map
dmap = {}
# open deception map file
fh = open(filename, 'r')
# iterate over lines in the file
for count, line in enumerate(fh):
# get the words on the current line
words = line.split()
if len(words) == 0:
# this is an empty line, we can skip to the next line
continue
elif len(words) != 2:
# we are expecting exactly two words per line
# this must be an invalid line: throw an error!
raise ValueError('Too many/few words on line '+str(count))
# Standardize words
key, illegal1 = standardize_word(words[0])
value, illegal2 = standardize_word(words[1])
if on_error == 'fail' and len(illegal1+illegal2) != 0:
# we are asked to fail if there are illegal characters in the current line
raise ValueError('Illegal chars on line '+str(count)+':'+illegal1+illegal2)
# add the word to the deception map
dmap[key] = value
# no checking is done to ensure that the word is not already in the map,
# i.e. the map may be inconsistent or redundant or non-invertible
return dmap

``````
``````

In [24]:

# load deception map from file

``````
``````

In [25]:

deception

``````
``````

Out[25]:

{'alice': 'john',
'be': 'have',
'her': 'his',
'i': 'you',
'is': 'was',
'rabbit': 'tiger',
'she': 'he',
'think': 'wait',
'this': 'that',
'you': 'i'}

``````
``````

In [26]:

def deceive_text(filename, deception_map):
"""Return a version of text in filename deceived by deception_map"""
text = open(filename, 'r')
# initiliaze a list of output lines
output = []
# iterate over the lines of the input text
for line in text:
# get the words on the current line
words = line.split()
# initiliaze the output line
newline = []
# iterate over the words on the current line
for word in words:
# standardize word
stdword, illegal_chars = standardize_word(word)
if stdword in deception_map:
# this word needs to be replaced, but we want to
# maintain the illegal chars (case is lost in translation)
# 1. make the word lower case
newword = word.lower()
# 2. replace within the original word+illegal_chars
newword = newword.replace(stdword, deception_map[stdword])
# 3. append the resulting word+illegal_chars in the current output line list of words
newline.append(newword)
else:
# this word does not need to be replaced, just put the word as-is in the output line list
newline.append(word)
# the output line we want to have consists of all words joined with a white space
newline = ' '.join(newline)
# append the current output line to the list of output lines
output.append(newline)

# the output text consists of all output lines joined with newline characters
output = '\n'.join(output)
return output

``````
``````

In [27]:

# get the deceived version of our text
newalice = deceive_text('text.txt', deception)

``````
``````

In [28]:

# show the first 20 lines
print '\n'.join(newalice.split('\n')[:20])

``````
``````

john was beginning to get very tired of sitting by his sister on the bank, and of having nothing to do: once or twice he had peeped into the book his sister was reading, but it had no pictures or conversations in it, `and what was the use of a book,' thought john `without pictures or conversation?'

So he was considering in his own mind (as bad as he could, for the hot day made his feel very sleepy and stupid), whether the pleasure of making a daisy-chain would have worth the trouble of getting up and picking the daisies, when suddenly a White tiger with pink eyes ran close by his.

There was nothing so very remarkable in that; nor did john wait it so very much out of the way to hear the tiger read to itself, `Oh dear! Oh dear! you shall have late!' (when he thought it over afterwards, it occurred to his that he ought to have wondered at that, but at the time it all seemed quite natural); but when the tiger actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, john started to his feet, for it flashed across his mind that he had never before seen a tiger with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, he ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.

``````
``````

In [29]:

# write out the modified text
newtext = open('newtext.txt', 'w')
newtext.write(newalice)
newtext.close()

``````
``````

In [ ]:

``````