Week 7: Strings

Warning

This page shows last year’s version. We might still make small changes, but you’re welcome to take a look. We’ll remove this notice once the page is final.

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.

Consider the sentence Syntax is not sufficient for semantics. This sentence contains 6 words. The word syntax has one vowel, the word is has one vowel, the word not has one vowel, the word sufficient has four vowels, the word for has one vowel, and the word semantics has three vowels. Therefore the word sufficient has the highest number of vowels.

Pen & Paper

Determine the word with the highest number of vowels for the following sentences:

  • The quick brown fox jumps over the lazy dog.

  • Beautiful mountains overlook the peaceful ocean.

  • Programming requires patience and dedication.

  • Education opens many opportunities for everyone.

Demo 7.2: Change Case#

Two naming conventions for multi-word variable names are: snake case and camel case. Snake case uses underscores in the place of a space. Camel case indicates the separation of words using 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.

Pen & Paper

Write down the following variable names in the other case (either from snake case to camel case, or from camel case to snake case):

  • student_grade_average

  • calculateTotalPrice

  • user_input_validation

  • measurements

  • getCurrentDateTime

  • maximum_temperature_celsius

  • isValidEmailAddress

Coding Practice#

Code 7.3: Framed Sign#

Define a variable and assign it a sting 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!
-----------------------------

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! |
---------------------------------

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 print 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, you 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 form having a function which prints the framed message, we also want to have a function which return 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.

Test your function with several different messages. Make sure that 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.

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.

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 a 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.

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.

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: 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, were 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 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.

Hide tests

test0 = is_palindrome('racecar')
test1 = is_palindrome('A man, a plan, a canal: Panama!')
test2 = is_palindrome('Was it a car or a cat I saw?')
test3 = is_palindrome('Damejer nis berg greb sin rejemad.')
test4 = is_palindrome('A Santa at NASA.')
test5 = not is_palindrome('Morten')
test6 = not is_palindrome('Not a palindrome')
test7 = is_palindrome('Madam')
test8 = not is_palindrome('Palindromes are cool')
test9 = not is_palindrome('Level and level')
test10 = not is_palindrome('Sequence of letters.')

all_tests_passed = (test0 and test1 and test2 and test3 and test4 and test5 
        and test6 and test7 and test8 and test9 and test10) 
print("All tests passed:", all_tests_passed)

Problem 7.11: Punctuation Check#

In typed text, some punctuation marks should always be followed by a space. These include:

  • Punctuation used for ending an 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 a number of punctuation errors.

Consider the string ‘This is:a text, a text with many,many errors! But,who cares?' which has 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:

  • text

str

Input text to check.

Returns:

  • int

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.12: 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:

  • code

str

A 4-digit code.

  • turn

int

A number of steps to turn turn all lock dials.

Returns:

  • str

The code after turning all lock dials.

You can test your function with the following inputs.

Hide tests

test0 = code_shift('2638', 3) == '5961'
test1 = code_shift('0120', -3) == '7897'
test2 = code_shift('9165', 1) == '0276'

all_tests_passed = test0 and test1 and test2 
print("All tests passed:", all_tests_passed)