Our previous implementation was incorrect because it even matched cases
where 'UUUlUUU' (Upper...lower...Upper) was surrounded by add'l
uppercase letters, i.e. 'UUUUlUUUUU' would match 'UUUlUUU' despite
there being extra uppercase letters in front and behind the matched
pattern.

We therefore changed our regex to look for the pattern UUUlUUU while
also checking that there was at least one non-uppercase letter before and
after the pattern i.e. [^A-Z]...[^A-Z]

This keeps us from finding matches from strings like 'UUUUlUUUUU', but
it doesn't exactly match the pattern 'UUUlUUU' because we will get
matches like 'lUUUlUUUll'

Our next step was to create another regex that plucks the pattern
'UUUlUUU' from the first list of matches.

Finally, we erased all upper-case letters from the second list of
matches using re.sub() (substitute), substituting '' for uppercase.
We rewrote our initial regex so that it doesn't use the complement
operator ^ within groups []. Instead of looking for 'UUUlUUU' with at
least one 'non-uppercase' letter to the left and right, we now look
for 'UUUlUUU' with at least one lowercase letter to the left and right:

r'[a-z]+[A-Z]{3}[a-z][A-Z]{3}[a-z]+'
We edited our first regex slightly; 'UUUlUUU' with just one lowercase
letter to the left and right

[a-z]...[a-z]

instead of [a-z]+
We were able to get rid of the helper function pluckMiddle() because
we learned that it is possible to return just one part of a larger regex
pattern match by using parens ().

Once we have matched the larger pattern

[a-z][A-Z]{3}[a-z][A-Z]{3}[a-z]

we can return just one part of the pattern by putting parens around it.

To return the middle lowercase letter in between both [A-Z]{3}
expressions, we just put parens around [a-z]:

[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]

The output of XXXoXXX() is

['l', 'i', 'n', 'k', 'e', 'd', 'l', 'i', 's', 't']