Exercises

To make writing and testing your exercises much easier:

  1. Download the exercises skeleton files
  2. Extract the ZIP file
  3. Write your exercises in the provided Python files

Validation Exercises

Hint

Match objects are always “truthy” and None is always “falsey”. Truthy meas when you convert something to a boolean, it’ll be True.

You can convert the result of re.search to a boolean to get True or False for a match or non-match like this:

>>> bool(re.search(r'hello', sentence))
True
>>> bool(re.search(r'hi', sentence))
False

Has Vowels

Create a function has_vowel, that accepts a string and returns True if the string contains a vowel (a, e, i, o, or u) returns False otherwise.

Tip

Modify the has_vowel function in the validation module.

Your function should work like this:

>>> has_vowel("rhythm")
False
>>> has_vowel("exit")
True

Is Integer

Create a function is_integer that accepts a string and returns True if the string represents an integer.

By our definition, an integer:

  • Consists of 1 or more digits
  • May optionally begin with -
  • Does not contain any other non-digit characters.

Tip

Modify the is_integer function in the validation module.

Your function should work like this:

>>> is_integer("")
False
>>> is_integer(" 5")
False
>>> is_integer("5000")
True
>>> is_integer("-999")
True
>>> is_integer("+999")
False
>>> is_integer("00")
True
>>> is_integer("0.0")
False

Is Fraction

Create a function is_fraction that accepts a string and returns True if the string represents a fraction.

By our definition a fraction consists of:

  1. An optional - character
  2. Followed by 1 or more digits
  3. Followed by a /
  4. Followed by 1 or more digits, at least one of which is non-zero (the denominator cannot be the number 0).

Tip

Modify the is_fraction function in the validation module.

Your function should work like this:

>>> is_fraction("")
False
>>> is_fraction("5000")
False
>>> is_fraction("-999/1")
True
>>> is_fraction("+999/1")
False
>>> is_fraction("00/1")
True
>>> is_fraction("/5")
False
>>> is_fraction("5/0")
False
>>> is_fraction("5/010")
True
>>> is_fraction("5/105")
True
>>> is_fraction("5 / 1")
False

Search Exercises

Most of these exercises involves searching in a dictionary.

Hint

You can open and read from the dictionary file like this:

with open('dictionary.txt') as dict_file:
    dictionary = dict_file.read()

Get File Extension

Make a function that accepts a full file path and returns the file extension.

Tip

Modify the get_extension function in the search module.

Example usage:

>>> get_extension('archive.zip')
'zip'
>>> get_extension('image.jpeg')
'jpeg'
>>> get_extension('index.xhtml')
'xhtml'
>>> get_extension('archive.tar.gz')
'gz'

Hexadecimal Words

Find every word that consists solely of the letters A, B, C, D, E, and F.

Tip

Modify the hexadecimal function in the search module.

Examples: decaf, bead, cab

Tetravocalic

Find all words that include four consecutive vowels.

Tip

Modify the tetravocalic function in the search module.

Hexaconsonantal

Find at least one word with 6 consecutive consonants. For this problem treat y as a vowel.

Tip

Modify the hexaconsonantal function in the search module.

Crossword Helper

Make a function possible_words that accepts a partial word with underscores representing missing letters and returns a list of all possible matches.

Tip

Modify the possible_words function in the search module.

Use your crossword helper function to solve the following:

  1. water tank: CIS____
  2. pastry: ___TE
  3. temporary: __A_S_E__

Repeat Letter

Find every word with 5 repeat letters.

Tip

Modify the five_repeats function in the search module.

More Regular Expression Exercises

Decimal Numbers

Write a function to match decimal numbers.

We want to allow an optional - and we want to match numbers with or without one decimal point.

Tip

Modify the is_number function in the validation module.

Example usage:

>>> is_number("5")
True
>>> is_number("5.")
True
>>> is_number(".5.")
False
>>> is_number(".5")
True
>>> is_number("01.5")
True
>>> is_number("-123.859")
True
>>> is_number("-123.859.")
False
>>> is_number(".")
False

Abbreviate

Make a function that creates an acronym from a phrase.

Tip

Modify the abbreviate function in the search module.

Example usage:

>>> abbreviate('Graphics Interchange Format')
'GIF'
>>> abbreviate('frequently asked questions')
'FAQ'
>>> abbreviate('cascading style sheets')
'CSS'
>>> abbreviate('Joint Photographic Experts Group')
'JPEG'
>>> abbreviate('content management system')
'CMS'
>>> abbreviate('JavaScript Object Notation')
'JSON'
>>> abbreviate('HyperText Markup Language')
'HTML'

Hex Colors

Write a function to match hexadecimal color codes. Hex color codes consist of an octothorpe symbol followed by either 3 or 6 hexadecimal digits (that’s 0 to 9 or a to f).

Tip

Modify the is_hex_color function in the validation module.

Example usage:

>>> is_hex_color("#639")
True
>>> is_hex_color("#6349")
False
>>> is_hex_color("#63459")
False
>>> is_hex_color("#634569")
True
>>> is_hex_color("#663399")
True
>>> is_hex_color("#000000")
True
>>> is_hex_color("#00")
False
>>> is_hex_color("#FFffFF")
True
>>> is_hex_color("#decaff")
True
>>> is_hex_color("#decafz")
False

Valid Date

Create a function that returns True if given a date in YYYY-MM-DD format.

For this exercise we’re more worried about accepting valid dates than we are about excluding invalid dates.

A regular expression is often used as a first wave of validation. Complete validation of dates should be done in our code outside of regular expressions.

Tip

Create this is_valid_date function in the validation module.

Example usage:

>>> is_valid_date("2016-01-02")
True
>>> is_valid_date("1900-01-01")
True
>>> is_valid_date("2016-02-99")
False
>>> is_valid_date("20-02-20")
False
>>> is_valid_date("1980-30-05")
False

Capture Exercises

Palindromes

Using the dictionary file, find all five letter palindromes.

Tip

Modify the palindrome5 function in the search module.

Double Double

Find all words that have a consecutive repeated letter two times with only one other letter between them.

Tip

Modify the double_double function in the search module.

For example, these words should be matched:

  • freebee
  • assessed
  • voodoo

Repetitive Words

Find all words that consist of the same letters repeated two times.

Tip

Modify the repeaters function in the search module.

Examples:

  • tutu
  • cancan
  • murmur

Substitution Exercises

Normalize JPEG Extension

Make a function that accepts a JPEG filename and returns a new filename with jpg lowercased without an e.

Tip

Modify the normalize_jpeg function in the substitution module.

Hint

Lookup how to pass flags to the re.sub function.

Example usage:

>>> normalize_jpeg('avatar.jpeg')
'avatar.jpg'
>>> normalize_jpeg('Avatar.JPEG')
'Avatar.jpg'
>>> normalize_jpeg('AVATAR.Jpg')
'AVATAR.jpg'

Normalize Whitespace

Make a function that replaces all instances of one or more whitespace characters with a single space.

Tip

Modify the normalize_whitespace function in the substitution module.

Example usage:

>>> normalize_whitespace("hello  there")
"hello there"
>>> normalize_whitespace("""Hold fast to dreams
... For if dreams die
... Life is a broken-winged bird
... That cannot fly.
...
... Hold fast to dreams
... For when dreams go
... Life is a barren field
... Frozen with snow.""")
'Hold fast to dreams For if dreams die Life is a broken-winged bird That cannot fly. Hold fast to dreams For when dreams go Life is a barren field Frozen with snow.'

Compress blank lines

Write a function that accepts a string and an integer N and compresses runs of N or more consecutive empty lines into just N empty lines.

Tip

Modify the compress_blank_lines function in the substitution module.

Example usage:

>>> compress_blank_lines("a\n\nb", max_blanks=1)
'a\n\nb'
>>> compress_blank_lines("a\n\nb", max_blanks=0)
'ab'
>>> compress_blank_lines("a\n\nb", max_blanks=2)
'a\n\nb'
>>> compress_blank_lines("a\n\n\n\nb\n\n\nc", max_blanks=2)
'a\n\n\nb\n\n\nc'

Normalize URL

I own the domain treyhunner.com. I prefer to link to my website as https://treyhunner.com, but I have some links that use http or use a www subdomain.

Write a function that normalizes all www.treyhunner.com and treyhunner.com links to use HTTPS and remove the www subdomain.

Tip

Modify the normalize_domain function in the substitution module.

Example usage:

>>> normalize_domain("http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/")
'https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/'
>>> normalize_domain("https://treyhunner.com/2016/02/how-to-merge-dictionaries-in-python/")
'https://treyhunner.com/2016/02/how-to-merge-dictionaries-in-python/'
>>> normalize_domain("http://www.treyhunner.com/2015/11/counting-things-in-python/")
'https://treyhunner.com/2015/11/counting-things-in-python/'
>>> normalize_domain("http://www.treyhunner.com")
'https://treyhunner.com'
>>> normalize_domain("http://trey.in/give-a-talk")
'http://trey.in/give-a-talk'

Linebreaks

Write a function that accepts a string and converts linebreaks to HTML in the following way:

  • text is surrounded by paragraphs
  • text with two or more line breaks between is considered two separate paragraphs
  • text with a single line break between is separated by a <br>

Tip

Modify the convert_linebreaks function in the substitution module.

Example usage:

>>> convert_linebreaks("hello")
'<p>hello</p>'
>>> convert_linebreaks("hello\nthere")
'<p>hello<br>there</p>'
>>> convert_linebreaks("hello\n\nthere")
'<p>hello</p><p>there</p>'
>>> convert_linebreaks("hello\nthere\n\nworld")
'<p>hello<br>there</p><p>world</p>'

Lookahead Exercises

All Vowels

Find all words that are at most 9 letters long and contain every vowel (a, e, i, o, u) in any order.

Tip

Modify the have_all_vowels function in the lookahead module.

Unique Letters

Find all words that have at least 10 letters and do not have any repeating letters.

Tip

Modify the no_repeats function in the lookahead module.

HTML Encode Ampersands

Replace all & characters which are not part of HTML escape sequences by an HTML-encoded ampersand (&amp;).

Tip

Modify the encode_ampersands function in the lookahead module.

Example usage:

>>> encode_ampersands("This &amp; that & that &#38; this.")
'This &amp; that &amp; that &#38; this.'
>>> encode_ampersands("A&W")
'A&amp;W'

Pig Latin

Create a function that translates English phrases to pig latin.

Tip

Modify the to_pig_latin function in the lookahead module.

Example usage:

>>> to_pig_latin("pig")
'igpay'
>>> to_pig_latin("trust")
'usttray'
>>> to_pig_latin("quack")
'ackquay'
>>> to_pig_latin("squeak")
'eaksquay'
>>> to_pig_latin("enqueue")
'enqueueay'
>>> to_pig_latin("sequoia")
'equoiasay'

Camel Case to Underscore

Make a function that converts camelCase strings to under_score strings.

Tip

Modify the camel_to_underscore function in the lookahead module.