A document from MCS 260 Fall 2021, instructor David Dumas. You can also get the notebook file.

# MCS 260 Fall 2021 Worksheet 4 Solutions¶

• Course instructor: David Dumas

## Topics¶

The main topics on this worksheets are strings, integers, and list comprehensions.

## Instructions¶

• Work on the exercises below during lab. Complete them afterward if you don't finish during the lab period.
• This worksheet will prepare you for the upcoming homework assignment.
• Most of the exercises ask you to write Python scripts to accomplish a certain task. We recommend making a folder (with a name like "worksheet3") to store the scripts you prepare today.
• Seek assistance from your TA or from fellow students if you run into trouble.

## Collaboration¶

Collaboration on worksheets is strongly encouraged.

## Resources¶

The main course materials to refer to for this worksheet are:

(Lecture videos are not linked on worksheets, but are also useful to review while working on worksheets. Video links can be found in the course course Blackboard site.)

## 1. Indexing practice¶

Here is a list of lists:

In [2]:
Q = [ ["Elizabeth","Victoria","Elizabeth"],
["Eleanor","Blanche","Margaret","Isabella","Anne","Catherine","Marguerite","Mary","Anne"],
["Artemisia","Kratesipolis","Nikaia","Olympias"]
]


In the list Q, each item is itself a list. So Q[0] refers to the item at index 0,

In [4]:
Q[0]

Out[4]:
['Elizabeth', 'Victoria', 'Elizabeth']

And these items that are lists can be further indexed. Here we take the last element of Q[0]:

In [5]:
Q[0][-1]

Out[5]:
'Elizabeth'

Determine indexing or slicing expressions like this that match the following descriptions, and evaluate them to make sure they give the expected values:

1. The second to last element of the last element of Q
2. Q with its first and last elements dropped
3. All but the last element of the second element of Q (index 1)
4. All of the index expressions using only positive numbers that evaluate to "Anne"
• Note: You don't need to write code to check for the value "Anne". Rather, this problem is checking whether you can find it yourself and then translate what you see into a set of numerical indices to use.
5. The third letter of the third string in the third item of Q

### Solutions¶

1. Q[-1][-2]
2. Q[1:-1]
3. Q[1][:-1]
4. Q[1][4] and Q[1][8]
5. Q[2][2][2]

## 2. List comprehension practice¶

We continue working with the list of lists Q from problem 1.

Write a list comprehension to do each of the following:

1. A list of the lengths of the items of Q, which should be [3,9,4,4]
2. A list of the middle letters of all the strings in Q[1] (use integer division to select the index, which selects the earlier of the two possibilites if a string has no middle letter)
3. A list of all the strings from Q[1] that contain the letter n.
4. A list of all the strings from Q[1] that contain the letter n at least two times.
5. A list that looks like Q[3], but where every word has been replaced by the same number of stars, i.e. ['*********', '************', '******', '********']
6. A list of strings that is like Q[2] but with any entry equal to "Sultana" dropped and consecutive number labels added to the remaining ones, i.e. ["'1. Padmini", "2. Chennamma", "3. Holkar"]

Note that you should be writing a single line of code consisting of a list comprehension for each answer. There are other ways you could solve these problems with the Python we've learned, but this exercise is testing your ability to solve them with list comprehensions.

### Solutions¶

In [8]:
# 1. A list of the lengths of the items of Q, which should be [3,9,4,4]
[ len(L) for L in Q ]

Out[8]:
[3, 9, 4, 4]
In [9]:
# 2. A list of the middle letters of all the strings in Q[1] (use integer division to
# select the index, which selects the earlier of the two possibilites if a string has no middle letter)

# MISTAKE IN THE QUESTION: The easiest way to use integer division doesn't actually select the earlier
# of the two possibilities if there is no middle letter.

# This was the intended solution, but it doesn't do exactly what was asked.
[ x[len(x)//2] for x in Q[1] ]

Out[9]:
['a', 'n', 'a', 'e', 'n', 'e', 'e', 'r', 'n']
In [24]:
# Here is a solution to the problem exactly as written.
[ x[(len(x)+1)//2] for x in Q[1] ]

Out[24]:
['n', 'c', 'a', 'e', 'n', 'r', 'e', 'r', 'n']
In [11]:
# 3. A list of all the strings from Q[1] that contain the letter n.
[ x for x in Q[1] if "n" in x ]

Out[11]:
['Eleanor', 'Blanche', 'Anne', 'Catherine', 'Anne']
In [12]:
# 4. A list of all the strings from Q[1] that contain the letter n at least two times.
[ x for x in Q[1] if len( [c for c in x if c == "n"] ) >= 2 ]

Out[12]:
['Anne', 'Anne']
In [13]:
# 5. A list that looks like Q[3], but where every word has been replaced by the same number of stars,
# i.e. ['*********', '************', '******', '********']
[ "*"*len(x) for x in Q[3] ]

Out[13]:
['*********', '************', '******', '********']
In [22]:
# 6. A list of strings that is like Q[2] but with any entry equal to "Sultana"
# dropped and consecutive number labels added to the remaining ones
[ str(i+1)+". " +x for i,x in enumerate( [x for x in Q[2] if x != "Sultana"] ) ]

# Notice we enumerate *after* filtering so that we get consecutive numbers despite
# dropping some elements.

Out[22]:
['1. Padmini', '2. Chennamma', '3. Holkar']

## 3. Adventures in unicode and escape sequences¶

Look up code point numbers from the charts at https://www.compart.com/en/unicode/block or https://unicode.org/charts/ and use them to make Python code that uses \uXXXX escape sequences to print the following strings. This means your code should only contain characters that appear on a standard US keyboard, but should produce the accented or non-latin characters shown here when it runs:

1. Pudín de limón
2. That's the "φ" model
3. Mathematicians often use the letter-like mathematical symbol ℂ for the set of complex numbers

Accented i and o are in the "Latin-1 supplement", while the letter phi is in the "Greek and Coptic" block.

Note: The default font used by Windows Powershell doesn't include ℂ, and instead of looking for another font which includes that character, it will just produce a symbol that looks like a square with a question mark inside. (That's a sign that a character is present, but can't be shown in the current font.) To confirm you've actually produced ℂ, you can copy the mystery character into the clipboard and paste it into another application (e.g. Discord, Word, the search bar in your web browser, ...).

### Solutions¶

In [20]:
# 1
print("Pud\u00EDn de lim\u00F3n")
# 2
print("That\'s the \"\u03C6\" model")
# 3
print("Mathematicians often use the letter-like mathematical symbol \u2102 for the set of complex numbers")

Pudín de limón
That's the "φ" model
Mathematicians often use the letter-like mathematical symbol ℂ for the set of complex numbers


## 4. Indexer¶

Write a Python program indexer.py that lets a user enter any number of strings, and which remembers each distinct string it has seen in a list. If it receives a string it has seen before, it tells the user the 0-based index where that string appears in the list.

More precisely, when the program is run, it starts with an empty list. It then enters an endless loop of doing the following:

• Display a prompt -> and wait for the user to type a string
• If the string they entered is already in the list, print a message showing the index where it appears
• If the string they entered is not in the list, add it to the end of the list and print a message showing its new index

Here's a sample session of using the program:

->David
David = 0  (new)
->Grogu
Grogu = 1  (new)
->Groudon
Groudon = 2  (new)
->Lisa
Lisa = 3  (new)
->David
David = 0
->Tina
Tina = 4  (new)
->Chin-Sun
Chin-Sun = 5  (new)
->Grogu
Grogu = 1
->Chin-Sun
Chin-Sun = 5
->David
David = 0

Notice that the first time David is entered, it is new and gets the index 0, but the next time it is entered, the program recognizes that it was seen before and again reports the index as 0.

### Solution¶

In [21]:
# MCS 260 Fall 2021 Worksheet 4 Problem 4
# Content of indexer.py
# David Dumas

L = [] # List of names seen so far
while True:
s = input('->')
if s in L:
print(s,"=",L.index(s))
else:
L.append(s)
print(s,"=",L.index(s)," (new)")

->David
David = 0  (new)
->Grogu
Grogu = 1  (new)
->Groudon
Groudon = 2  (new)
->Lisa
Lisa = 3  (new)
->David
David = 0
->Tina
Tina = 4  (new)
->Chin-Sun
Chin-Sun = 5  (new)
->Grogu
Grogu = 1
->Chin-Sun
Chin-Sun = 5
->David
David = 0

---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-21-9a8be8bf1978> in <module>
4 L = []
5 while True:
----> 6     s = input('->')
7     if s in L:
8         print(s,"=",L.index(s))

/usr/lib/python3/dist-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
858                 "raw_input was called, but this frontend does not support input requests."
859             )
--> 860         return self._input_request(str(prompt),
861             self._parent_ident,
KeyboardInterrupt: Interrupted by user