PyShop Session 1

Exercises


These exercises are meant to help you to get to know the standard Python data types, their methods, and some useful built-in functions. Keep in mind that there are always many ways to solve these problems, but I encourage you to do so WITHOUT IMPORTING ANYTHING! That will help you to familiarize yourself with the native functionality.

The questions are in increasing difficulty, where the first question should take you less than a minute and the last one you might not be able to figure out. Good luck!

Note: I appologize for the solutions and questions not being next to each other, but there is a numbering issue in the Markdown that generates this text. Sorry, but it is a known bug that has yet to be fixed!

  1. Go have a look at the Python documentation regarding lists here . Once you've done that, define an empty list, called x and a list containing the numbers 1 through 100, called y. Finally, print your variables using a single line of code.

  2. Loop over your list y and fill x with the indices of y for all of the entries that are even. That is, if y[5] is even, add the index 5 to x. Again, print x and check your work. Hint: Take a look at the built in function "enumerate()". BONUS: Use a boolean test to check whether all of the elements of y indexed by the entries of x are even.

  3. For all of the odd numbers between zero and 100 (N = 1, 3, ... 99), generate a new list containing all of the integers less than N. Do this in one line using your two lists x and y. Your results should be contained in a list of lists, call it z. Use a slice and print only part of z to see how you did.

  4. Read in the 'jabberwocky.txt' file accompanying these exercises to a single string.

  5. Compare the raw string and the output from print. What is the difference?

  6. Use built in methods to split the poem into lines using the '\n' line break marker. What is still a problem with these strings? How is their formatting different? What characters are still a problem?

  7. Use built in methods to 'strip' (hint, hint!) the leading white space from the lines. Bonus points if you do it in a single line.

  8. Remove all punctuation, replace the remaining unicode markers for appostrophes with actual appostrophes, remove those corresponding to quotes, and convert the text to lower-case.

  9. Split the poem into words, ending up with a list of words. That means your list should be one dimensional! Check this by running len(words). Is the result a single number or several?

  10. Finally, write a small script that takes input from the user and generates a random poem from the words in Jabberwocky! My inputs are simply the number of words, but you can be as creative as you want!


In [2]:
x = []
y = [i for i in range(1,101)]
print(x,y)


[] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

In [4]:
for index, item in enumerate(y):
  if item%2 == 0: x.append(index)
print(x)

#BONUS!
print(any([y[i]%2 == 1 for i in x]))

#Just to show you that this worked, change one entry in x
x[0] = 0
print(any([y[i]%2 == 1 for i in x]))

#Let's change x back so we don't have more problems:
x[0] = 1


[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
False
True

In [5]:
z = [i for i in [y[:I] for I in x]]
print(z[:3])


[[1], [1, 2, 3], [1, 2, 3, 4, 5]]

In [8]:
f = open('jabberwocky.txt')
poem = f.read()
print(poem)
poem


Jabberwocky
BY LEWIS CARROLL
’Twas brillig, and the slithy toves
      Did gyre and gimble in the wabe:
All mimsy were the borogoves,
      And the mome raths outgrabe.

“Beware the Jabberwock, my son!
      The jaws that bite, the claws that catch!
Beware the Jubjub bird, and shun
      The frumious Bandersnatch!”

He took his vorpal sword in hand;
      Long time the manxome foe he sought—
So rested he by the Tumtum tree
      And stood awhile in thought.

And, as in uffish thought he stood,
      The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wood,
      And burbled as it came!

One, two! One, two! And through and through
      The vorpal blade went snicker-snack!
He left it dead, and with its head
      He went galumphing back.

“And hast thou slain the Jabberwock?
      Come to my arms, my beamish boy!
O frabjous day! Callooh! Callay!”
      He chortled in his joy.

’Twas brillig, and the slithy toves
      Did gyre and gimble in the wabe:
All mimsy were the borogoves,
      And the mome raths outgrabe.

Out[8]:
'Jabberwocky\nBY LEWIS CARROLL\n’Twas brillig, and the slithy toves\n      Did gyre and gimble in the wabe:\nAll mimsy were the borogoves,\n      And the mome raths outgrabe.\n\n“Beware the Jabberwock, my son!\n      The jaws that bite, the claws that catch!\nBeware the Jubjub bird, and shun\n      The frumious Bandersnatch!”\n\nHe took his vorpal sword in hand;\n      Long time the manxome foe he sought—\nSo rested he by the Tumtum tree\n      And stood awhile in thought.\n\nAnd, as in uffish thought he stood,\n      The Jabberwock, with eyes of flame,\nCame whiffling through the tulgey wood,\n      And burbled as it came!\n\nOne, two! One, two! And through and through\n      The vorpal blade went snicker-snack!\nHe left it dead, and with its head\n      He went galumphing back.\n\n“And hast thou slain the Jabberwock?\n      Come to my arms, my beamish boy!\nO frabjous day! Callooh! Callay!”\n      He chortled in his joy.\n\n’Twas brillig, and the slithy toves\n      Did gyre and gimble in the wabe:\nAll mimsy were the borogoves,\n      And the mome raths outgrabe.\n'

Notice that the raw string contains the line seperators, tab markers, etc., while print processes these and prints the desired styling. This is an important point, as if your raw strings contain these characters (the \ is the break character in Python) you will have errors.


In [9]:
lines = poem.split('\n')
lines


Out[9]:
['Jabberwocky',
 'BY LEWIS CARROLL',
 '’Twas brillig, and the slithy toves',
 '      Did gyre and gimble in the wabe:',
 'All mimsy were the borogoves,',
 '      And the mome raths outgrabe.',
 '',
 '“Beware the Jabberwock, my son!',
 '      The jaws that bite, the claws that catch!',
 'Beware the Jubjub bird, and shun',
 '      The frumious Bandersnatch!”',
 '',
 'He took his vorpal sword in hand;',
 '      Long time the manxome foe he sought—',
 'So rested he by the Tumtum tree',
 '      And stood awhile in thought.',
 '',
 'And, as in uffish thought he stood,',
 '      The Jabberwock, with eyes of flame,',
 'Came whiffling through the tulgey wood,',
 '      And burbled as it came!',
 '',
 'One, two! One, two! And through and through',
 '      The vorpal blade went snicker-snack!',
 'He left it dead, and with its head',
 '      He went galumphing back.',
 '',
 '“And hast thou slain the Jabberwock?',
 '      Come to my arms, my beamish boy!',
 'O frabjous day! Callooh! Callay!”',
 '      He chortled in his joy.',
 '',
 '’Twas brillig, and the slithy toves',
 '      Did gyre and gimble in the wabe:',
 'All mimsy were the borogoves,',
 '      And the mome raths outgrabe.',
 '']

You'll now notice that some of the strings contain leading white space that could be a problem for some algorithms or programs. Also, the quotation marks and appostrophes are still marked with their unicode markers.


In [10]:
lines = [line.lstrip() for line in lines]
lines


Out[10]:
['Jabberwocky',
 'BY LEWIS CARROLL',
 '’Twas brillig, and the slithy toves',
 'Did gyre and gimble in the wabe:',
 'All mimsy were the borogoves,',
 'And the mome raths outgrabe.',
 '',
 '“Beware the Jabberwock, my son!',
 'The jaws that bite, the claws that catch!',
 'Beware the Jubjub bird, and shun',
 'The frumious Bandersnatch!”',
 '',
 'He took his vorpal sword in hand;',
 'Long time the manxome foe he sought—',
 'So rested he by the Tumtum tree',
 'And stood awhile in thought.',
 '',
 'And, as in uffish thought he stood,',
 'The Jabberwock, with eyes of flame,',
 'Came whiffling through the tulgey wood,',
 'And burbled as it came!',
 '',
 'One, two! One, two! And through and through',
 'The vorpal blade went snicker-snack!',
 'He left it dead, and with its head',
 'He went galumphing back.',
 '',
 '“And hast thou slain the Jabberwock?',
 'Come to my arms, my beamish boy!',
 'O frabjous day! Callooh! Callay!”',
 'He chortled in his joy.',
 '',
 '’Twas brillig, and the slithy toves',
 'Did gyre and gimble in the wabe:',
 'All mimsy were the borogoves,',
 'And the mome raths outgrabe.',
 '']

In [24]:
#NOTE: I've shown two ways to do this here.  I understand there are packages that make
#this much more efficient, but I'm seeking to make this set of exercises solely built in python.

lines = ["".join(c for c in line if c not in (':', '.', '!', ';', '?')) for line in lines]
lines = [line for line in lines if not line == '']
lines = [line.replace('\xe2\x80\x9c', r"") for line in lines]
lines = [line.replace('\xe2\x80\x94', r"") for line in lines]
lines = [line.replace('\xe2\x80\x99', r"'") for line in lines]
lines = [line.replace('\xe2\x80\x9d', r"") for line in lines]
lines = [line.lower() for line in lines]
lines


Out[24]:
['jabberwocky',
 'by lewis carroll',
 '’twas brillig, and the slithy toves',
 'did gyre and gimble in the wabe',
 'all mimsy were the borogoves,',
 'and the mome raths outgrabe',
 '“beware the jabberwock, my son',
 'the jaws that bite, the claws that catch',
 'beware the jubjub bird, and shun',
 'the frumious bandersnatch”',
 'he took his vorpal sword in hand',
 'long time the manxome foe he sought—',
 'so rested he by the tumtum tree',
 'and stood awhile in thought',
 'and, as in uffish thought he stood,',
 'the jabberwock, with eyes of flame,',
 'came whiffling through the tulgey wood,',
 'and burbled as it came',
 'one, two one, two and through and through',
 'the vorpal blade went snicker-snack',
 'he left it dead, and with its head',
 'he went galumphing back',
 '“and hast thou slain the jabberwock',
 'come to my arms, my beamish boy',
 'o frabjous day callooh callay”',
 'he chortled in his joy',
 '’twas brillig, and the slithy toves',
 'did gyre and gimble in the wabe',
 'all mimsy were the borogoves,',
 'and the mome raths outgrabe']

This solution worked in Python 2, but in Python 3 I can't get the " out. If you can, good on you!


In [12]:
words = [word for line in lines for word in line.split()]
words


Out[12]:
['jabberwocky',
 'by',
 'lewis',
 'carroll',
 '’twas',
 'brillig,',
 'and',
 'the',
 'slithy',
 'toves',
 'did',
 'gyre',
 'and',
 'gimble',
 'in',
 'the',
 'wabe',
 'all',
 'mimsy',
 'were',
 'the',
 'borogoves,',
 'and',
 'the',
 'mome',
 'raths',
 'outgrabe',
 '“beware',
 'the',
 'jabberwock,',
 'my',
 'son',
 'the',
 'jaws',
 'that',
 'bite,',
 'the',
 'claws',
 'that',
 'catch',
 'beware',
 'the',
 'jubjub',
 'bird,',
 'and',
 'shun',
 'the',
 'frumious',
 'bandersnatch”',
 'he',
 'took',
 'his',
 'vorpal',
 'sword',
 'in',
 'hand',
 'long',
 'time',
 'the',
 'manxome',
 'foe',
 'he',
 'sought—',
 'so',
 'rested',
 'he',
 'by',
 'the',
 'tumtum',
 'tree',
 'and',
 'stood',
 'awhile',
 'in',
 'thought',
 'and,',
 'as',
 'in',
 'uffish',
 'thought',
 'he',
 'stood,',
 'the',
 'jabberwock,',
 'with',
 'eyes',
 'of',
 'flame,',
 'came',
 'whiffling',
 'through',
 'the',
 'tulgey',
 'wood,',
 'and',
 'burbled',
 'as',
 'it',
 'came',
 'one,',
 'two',
 'one,',
 'two',
 'and',
 'through',
 'and',
 'through',
 'the',
 'vorpal',
 'blade',
 'went',
 'snicker-snack',
 'he',
 'left',
 'it',
 'dead,',
 'and',
 'with',
 'its',
 'head',
 'he',
 'went',
 'galumphing',
 'back',
 '“and',
 'hast',
 'thou',
 'slain',
 'the',
 'jabberwock',
 'come',
 'to',
 'my',
 'arms,',
 'my',
 'beamish',
 'boy',
 'o',
 'frabjous',
 'day',
 'callooh',
 'callay”',
 'he',
 'chortled',
 'in',
 'his',
 'joy',
 '’twas',
 'brillig,',
 'and',
 'the',
 'slithy',
 'toves',
 'did',
 'gyre',
 'and',
 'gimble',
 'in',
 'the',
 'wabe',
 'all',
 'mimsy',
 'were',
 'the',
 'borogoves,',
 'and',
 'the',
 'mome',
 'raths',
 'outgrabe']

In [20]:
import random

print("So, you think Jabberwocky is ridiculous?  I bet I can do one better!")
print("How long should my poem be?  (be nice and put in an integer)  ")
number_of_words = int(input())

#Generate a string of random numbers, implying indices
ind = [random.randint(0, len(words) - 1) for i in range(0, number_of_words)]

#Generate a list of random numbers to represent words per line
words_per_line = [random.randint(0, 10) for i in range(number_of_words)] 

#Create the lines of the poem in a loop
line = 0
k = 0
crazy_poem_lines = ['']
for i in ind:
    crazy_poem_lines[line] += words[i] + " "
    k += 1
    if k >= words_per_line[line]:
        k = 0
        line += 1
        crazy_poem_lines.append('')

#When done, strip the trailing white space and add line breaks
crazy_poem_lines = [line.rstrip() for line in crazy_poem_lines]
crazy_poem_lines = [line + '\n ' for line in crazy_poem_lines]

#Finally, create a single poem
crazy_poem = "\n Here's a crazier poem: \n\n"
for line in crazy_poem_lines:
    crazy_poem += line
print(crazy_poem)


So, you think Jabberwocky is ridiculous?  I bet I can do one better!
How long should my poem be?  (be nice and put in an integer)  
100

 Here's a crazier poem: 

and
 he
 in the two
 and mome went he slain in came and
 his
 chortled back as the stood carroll and jabberwock he were
 son ’twas sought— “beware in
 as in raths
 wood, it lewis gyre in to borogoves, in jabberwocky
 his and mome jaws awhile as burbled
 gyre
 burbled with so mome the
 boy
 the and toves and and, callooh tulgey one, hast bite,
 with mimsy slain
 ’twas carroll came ’twas the he brillig,
 raths rested sword and, bite, callay” and hand
 and gyre
 in and one, lewis flame, borogoves,
 and through and, time ’twas raths slain toves
 wabe
 

In [ ]:
len(words)