
Week 7: In-Class#
Demo#
Demo 7.1: Most Vowels#
Each word in a sentence might contain several vowels. We would like to find the word with the highest vowel count in a sentence.
Here, vowels are aeiou in either upper or lower case. If multiple words have the same highest number of vowels, we are interested in the first one. You can assume that at least one word contains a vowel.
Pen & Paper
Come up with two sentences to test a function solving this problem. The sentences should cover different cases. For each sentence, write down which word should be returned, and which case the sentence covers.
If you do not have a pen or paper at hand, you can type your answers here:
| Sentence | Returned word | Case covered |
|---|---|---|
Demo
Implement a function which, as input, takes a string with words separated by space. The function should return the word that has the highest number of vowels. Return the word with the same capitalization as in the sentence, and if the word is followed by punctuation, return the word together with the punctuation.
The expected behavior of the function is shown below:
>>> most_vowels("Programming requires patience and dedication.")
'dedication.'
The filename and requirements are in the box below:
most_vowels.py
most_vowels(sentence)
Returns the word with the highest number of vowels in a sentence. If multiple words have the same highest number of vowels, returns the first one.
Parameters:
|
|
A string containing words separated by spaces. |
Returns:
|
The word with the highest number of vowels. |
Use the following script to check your function test_most_vowels.py.
Demo 7.2: Standardize Address#
We need to combine addresses from multiple sources, which write the postal code and city name in different ways. The differences are:
Some write the postal code first (e.g.
2840 Holte), while others write the city first (e.g.Holte 2840).Some use spaces to separate the words (as above), while others use underscores (e.g.
2840_Holte).
We want to standardize the addresses such that the postal code always comes first, and a space is always used for separating the parts of the address. The city name may consist of multiple words, but you may assume that it only consists of letters and word separators (space or underscore). The postal code can have any length, but it consists only of digits.
Pen & Paper
Come up with four addresses to test a function solving this problem. The addresses should together cover different cases. For each address, write down which case it covers.
If you do not have a pen or paper at hand, you can type your answers here:
| Address | Case covered |
|---|---|
Demo
Implement a function which, as input, takes a string with an address in one of the formats described above. The function should return the standardized address.
The expected behavior of the function is shown below:
>>> standardize_address("Kongens_Lyngby_2800")
'2800 Kongens Lyngby'
The filename and requirements are in the box below:
standardize_address.py
standardize_address(address)
Returns the address with the postal code first and parts separated by spaces.
Parameters:
|
|
An address with a postal code and a city name, in either order, separated by spaces or underscores. |
Returns:
|
The standardized address. |
Use the following script to check your function test_standardize_address.py.
Coding Practice#
Code 7.3: Framed Sign#
Define a variable and assign it a string value which is not longer than a line, for example This is my important message!. Write Python code to print the message between two border lines as shown below. Your code should work for any string value assigned to the variable.
-----------------------------
This is my important message!
-----------------------------
Hint
You should use the len() function to determine the length of the message and then print the horizontal borders by repeating the character -.
Modify your code such that it also prints the vertical bars on the left and right side of the message as shown below.
---------------------------------
| This is my important message! |
---------------------------------
Hint
You can first make the middle line of text, and then proceed as you did before to print the horizontal borders.
Make another modification to your code where you define a variable to store a character, for example *. This character will be used for the horizontal borders, such that the code now prints the message below.
*********************************
| This is my important message! |
*********************************
Code 7.4: Framed Sign Function#
Based on the previous code, write a function print_framed_sign(message, border_char) that takes two arguments, a message and a character to be used for the border. The function should print the message between two border lines as shown below. Your function should work for any string value assigned to the variable.
Test your function with several different messages.
Add yet another argument to the function, is_important, which is a boolean value. If is_important is True, the function should print the message in uppercase letters. If is_important is False, the function should print the message as it is.
Now, your function should work as shown below.
>>> print_framed_sign("Harry, did you put your name in the goblet of fire?", "~", True)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| HARRY, DID YOU PUT YOUR NAME IN THE GOBLET OF FIRE? |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lastly, apart from having a function which prints the framed message, we also want to have a function which returns a string instead of printing it. Make another function framed_sign(message, border_char, is_important) which returns the framed message instead of printing it. Start by copying the code from the previous function and modify it to return the framed message instead of printing it. The returned string value should contain the framed message in three lines of text.
Hint
Instead of printing the lines, make a variable which contains the lines separated by a newline character \n. Then return this variable.
Test your function with several different messages. Make sure that the framed_sign() function does not print anything when called.
It should work as shown below.
>>> sign = framed_sign("Harry, did you put your name in the goblet of fire?", "X", True)
>>> print(sign)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
| HARRY, DID YOU PUT YOUR NAME IN THE GOBLET OF FIRE? |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Code 7.5: Count Vowels#
Define a variable and assign it a string value, for example Hello, what a beautiful day!. Write Python code to traverse the string, and print every character in the string.
Now change your code so that it for every character prints whether this character is a vowel or not. We consider the vowels to be a, e, i, o, and u.
Hint
You can make a string containing all the vowels, and then check if each character in the string is in the vowels string. To handle both uppercase and lowercase letters, you can convert the character to lowercase before checking.
Modify your code such that it also counts the number of vowels in the string and prints the total number of vowels at the end.
Hint
Before starting to traverse the string, you should define a variable with the value 0 to store the count of vowels. Then, for every character which is a vowel, you should increment this variable by one.
Code 7.6: Count Vowels Function#
Based on the previous code, write a function vowel_count(message) that takes a message as an argument and returns the number of vowels in the message. This function should not print anything, only return the number of vowels. It should work as shown below.
>>> vowel_count("Hello, what's up?")
4
>>> vowel_count("OMG, I can't believe it!")
8
>>> vowel_count("This is a day when I'm feeling good")
11
Code 7.7: Format Dates#
Define a string variable with your birth date formatted as dd/mm/yyyy for example 13/01/1982. Write Python code to split the string into three strings, the day, the month, and the year. Now define a string variable with the date formatted as yyyy-mm-dd.
Hint
You know the length of the fields for day, month, and year, so you can use slicing to extract the parts of the date. Alternatively, you can use the split() method to split the string into a list of strings, and then index the list to get the parts.
Now we want to format the date as dd-Mon-yy, for example 13-Jan-82. To accomplish this make a list of strings with the 3-letter abbreviation for each month. You need to appropriately manipulate the month part of the date to get the abbreviation.
Hint
You need to cast the month part of the date to an integer to get the month number. And since the list of month abbreviations is zero-indexed, you need to subtract 1 from the month number to get the correct index in the list of month abbreviations.
Code 7.8: Format Dates Function#
Based on the previous code, write a function format_date(date) that takes a date string in dd/mm/yyyy format, and returns the date in dd-Mon-yy format. The function should work as shown below.
>>> format_date("01/08/2020")
'01-Aug-20'
Problem Solving#
Problem 7.9: DNA Complement#
A strand of DNA may be represented as text consisting of letters A, T, C, and G. The complement of a DNA string is formed by replacing each nucleotide with its complement: A with T, T with A, C with G, and G with C. For example, the complement of AATTCG is TTAAGC. The reverse complement of a DNA string is the complement of the string read in reverse. For example, the reverse complement of AATTCG is CGAATT.
Write a function dna_complement which takes two inputs: a string dna representing a DNA strand, and a boolean reverse. The function should return the complement of the DNA strand. If reverse is True, the function should return the reverse complement.
Problem 7.10: Change Case#
Two naming conventions for multi-word variable names are snake case and camel case. Snake case uses underscores instead of spaces. Camel case separates words with a single capitalized letter (here, the first letter is lowercase). An example of snake case is circle_radius, and the corresponding camel case is circleRadius. Single-word variable names are the same in both conventions.
Create a function that takes as input a string with the variable name in either snake case or camel case, and returns a string with the variable name in the other case. The variable name may be a single word or a multi-word name.
For example, consider the variable name thisIsAnIdentifierName. The presence of capital letters indicates that this is camel case. The individual words are: this is an identifier name. Written using snake case, this would be this_is_an_identifier_name.
change_case.py
change_case(name)
Changes camel case to snake case and vice versa.
Parameters:
|
|
A variable name in either camel case or snake case. |
Returns:
|
The variable name in the other case. |
You can test your function with the following inputs.
Problem 7.11: Generalized Palindrome#
A palindrome is a word that reads the same forwards and backwards. For example, racecar is a palindrome. A sentence or phrase can also be a palindrome, where punctuation and spaces are ignored. For example, A man, a plan, a canal: Panama! is a palindrome, and so is Was it a car or a cat I saw?.
Write a function is_palindrome that takes as input a string containing a word or a sentence. The function should return True if the string is a palindrome and False otherwise. The function should ignore punctuation, spaces, and capitalization. You can consider punctuation to be any of the following characters: ,.?!:;.
Test your function on the following inputs.
Problem 7.12: Punctuation Check#
In typed text, some punctuation marks should always be followed by a space. These include:
Punctuation used for ending a sentence: period (.), question mark (?), and exclamation mark (!).
Punctuation indicating a pause: comma (,), colon (:), and semicolon (;).
For an automatic text evaluation, we need to count the number of punctuation errors, where punctuation marks (.), (?), (!), (,), (:), and (;) are not followed by a space. If the last character in the text is a punctuation mark, it should not be counted as an error.
Write a function punctuation_check that takes as input a string representing a typed text and returns the number of punctuation errors.
Consider the string 'This is:a text, a text with many,many errors! But,who cares?' which has the following punctuation errors: :a, ,m, and ,w. So the function should return 3 for this string.
The function should have the following specifications:
punctuation_check.py
punctuation_check(text)
Counts the number of punctuation marks that are not followed by a space.
Parameters:
|
|
Input text to check. |
Returns:
|
Number of punctuation marks not followed by a space. |
Try to run the following code to test your function on ten different strings. The expected output is: 3, 2, 1, 0, 0, 2, 1, 8, 0, 5.
print(punctuation_check("This is:a text, a text with many,many errors! But,who cares?"))
print(punctuation_check("Here we have no errors.Or do we?!"))
print(punctuation_check("No,I am sure this is error-free!"))
print(punctuation_check("Whataboutonlyasingleword? "))
print(punctuation_check(" almost empty ? "))
print(punctuation_check("3 times.is.not enough"))
print(punctuation_check("!Whou, this is strange!"))
print(punctuation_check("A,B,C,D,E,F,G,H,I"))
print(punctuation_check("Number nine is a good example, almost no problems there-I think."))
print(punctuation_check("But!The last text is bad.Really,really bad.No space at all.Squeezed!"))
Problem 7.13: Code Shift#
A bike lock has 4 dials each with the digits from 0 to 9. The code is set by turning the dials in discrete steps. Turning a dial for one step will increment the digits from 0 to 9, but digit 9 will be set to 0. The dials can be turned in both directions, and we define the positive direction as the direction where digits smaller than 9 increase. If all dials of the lock are turned at once, all code digits will change.
Write a function code_shift which as an input takes a string representing the 4-digit code, and an integer representing a turn of all dials for a number of steps in a positive or a negative direction. The function should return the string with the new code after the turn.
For example, consider the code '2638' and the shift 3. The code consists of digits 2, 6, 3, and 8. Turning the dials for three steps in a positive direction will change the first digit into 2+3=5, the second digit will become 9, the third digit will become 6. The last digit will become 1, as it changes from 8 over 9 and 0 to 1. So the function should return '5961'.
The function should have the following specifications:
code_shift.py
code_shift(code, turn)
Shifts the code by a given number of steps.
Parameters:
|
|
A 4-digit code. |
|
|
A number of steps to turn all lock dials. |
Returns:
|
The code after turning all lock dials. |
You can test your function with the following inputs.
Solutions to Demo Tasks
Solution to Demo 7.1: Most Vowels
def most_vowels(sentence):
vowels = "aeiou"
words = sentence.split()
vowel_counts = []
for word in words:
vowel_count = 0
for char in word.lower():
vowel_count += char in vowels
vowel_counts.append(vowel_count)
max_vowel_count = max(vowel_counts)
return words[vowel_counts.index(max_vowel_count)]
Solution to Demo 7.2: Standardize Address
def standardize_address(address):
address = address.replace("_", " ")
if address[0] in "0123456789":
return address
words = address.split(" ")
postal_code = words[-1]
city = " ".join(words[:-1])
return postal_code + " " + city