Monday, October 26th, 2026¶
Last week, we generated a checkerboard tartan and discusses some ideas for generating the authentic tartan pattern.
Next steps¶
- The project asks you to produce a
500by500tartan image based on your assigned pattern. The assigned pattern length is less than500, so you will need to think about how to repeat the pattern enough times to fill in the full500by500image. - It would be good to create functions that perform the tasks of creating these various arrays. For example, a function
get_vertical_stripescould take in the tartan recipe as inputs and return the correspondingvertical_stripesarray. When it comes time to actually generate your assigned tartan, we can then just call upon these helper functions. - While we have made big improvements in how we generate the
vertical_stripesarray, there still was some amount of manual work on our part. Can we do better?
String processing¶
In generating our tartan images, we interpreted the tartan recipe by defining lists for the widths and colors. It would be nice if we could use Python to generate the list of widths and colors automatically. In other words, it would be convenient if we could define a string like tartan_recipe = 'B14 K6 B6 K6 B6 K32 OG32' and process this string to pull out these two lists.
tartan_recipe = 'B14 K6 B6 K6 B6 K32 OG32'
We have already seen some useful tools for working with strings in Python. For example:
- The
.joinmethod allows us to concatenate a list of strings using a given string as a separator. - The
.formatmethod allows us to plug values into a string template.
Another helpful tool is the .split method, which allows us to separate a string into a list of substrings. The syntax is something like:
some_string.split(some_separator)
This will separate the some_string string into a list of substrings, where each separation occurs whenever the some_separator string is found within some_string.
my_string = "This is a sample string. We are in MTH 337."
my_string.split(' ')
['This', 'is', 'a', 'sample', 'string.', 'We', 'are', 'in', 'MTH', '337.']
my_string.split('s')
['Thi', ' i', ' a ', 'ample ', 'tring. We are in MTH 337.']
Note: If we call the .split method with no input variable, by default the string will be split anywhere there is white space (e.g. spaces, tabs, line breaks, etc.).
my_string = "This is a string with a lot of white space."
my_string.split(' ')
['This', 'is', 'a', '', '', '', '', 'string', 'with', '', '', '', '', '', '', 'a', 'lot', 'of', '', '', '', 'white', 'space.']
my_string.split()
['This', 'is', 'a', 'string', 'with', 'a', 'lot', 'of', 'white', 'space.']
We can then apply the .split method to the tartan_recipe string to get a sequence of substrings, each of which represents a particular stripe.
print(tartan_recipe)
B14 K6 B6 K6 B6 K32 OG32
stripe_recipes = tartan_recipe.split()
Can we iterate through each of these stripe recipes and pick out the color and width?
stripe_recipe = stripe_recipes[0] # Get the first stripe recipe
print(stripe_recipe)
B14
stripe_recipe[0]
'B'
stripe_recipe[1:]
'14'
Problem: We can't just take the first character from stripe_recipe as the color code, because some color codes have two characters (e.g. 'OG').
It would be very helpful if we could pick out which parts of a string are letters and which parts of a string are numbers. The following methods (called on a string) can help with this:
- The
.isalphamethod will returnTrueif the string contains only alphabetic characters (i.e. letters). - The
.isnumericmethod will returnTrueif the string contains only numeric characters (i.e. numbers).
s = 'This is a string with spaces and letters'
s.isalpha()
False
word = s.split()[0]
print(word)
print(word.isalpha())
This True
'123456'.isnumeric()
True
'1a2b3c'.isnumeric()
False
'one'.isnumeric()
False
Exercise: Write a function that takes in a tartan recipe string and returns a list of color codes (e.g. ['B', 'K', 'B', ...]) and widths.
print(tartan_recipe)
stripe_recipes = tartan_recipe.split()
stripe_recipe = stripe_recipes[0]
print(stripe_recipe)
color_code = ''
for char in stripe_recipe:
if char.isalpha():
color_code += char
print(color_code)
B14 K6 B6 K6 B6 K32 OG32 B14 B
print(tartan_recipe)
stripe_recipes = tartan_recipe.split()
for stripe_recipe in stripe_recipes:
color_code = ''
for char in stripe_recipe:
if char.isalpha():
color_code += char
print(color_code)
B14 K6 B6 K6 B6 K32 OG32 B K B K B K OG
print(tartan_recipe)
stripe_recipes = tartan_recipe.split()
color_codes = []
for stripe_recipe in stripe_recipes:
color_code = ''
for char in stripe_recipe:
if char.isalpha():
color_code += char
color_codes.append(color_code)
print(color_codes)
B14 K6 B6 K6 B6 K32 OG32 ['B', 'K', 'B', 'K', 'B', 'K', 'OG']
my_string = 'Hello, this is Jon Lottes. Today is Monday, October 26th, 2026'
print(my_string.split())
['Hello,', 'this', 'is', 'Jon', 'Lottes.', 'Today', 'is', 'Monday,', 'October', '26th,', '2026']
words_with_s = [word for word in my_string.split() if 's' in word]
print(words_with_s)
['this', 'is', 'Lottes.', 'is']
my_string = 'OG32'
for char in my_string:
print(char)
O G 3 2
for char in my_string:
if char.isnumeric():
print(char)
3 2
Exercise: Write a function that takes in a tartan recipe string and returns a list of color codes (e.g. ['B', 'K', 'B', ...]) and widths using list comprehensions.
From the above, we can pick out the color code strings from the tartan recipe. On the other hand, in order to generate our vertical_stripes array, we need to get the corresponding RGB triples (not just the color code strings). How can accomplish this?
print(color_codes)
['B', 'K', 'B', 'K', 'B', 'K', 'OG']
colors = []
for color_code in color_codes:
if color_code == 'B':
colors.append([52/255, 80/255, 100/255])
elif color_code == 'K':
colors.append([16/255, 16/255, 16/255])
elif color_code == 'OG':
colors.append([92/255, 100/255, 40/255])
for color_code, color in zip(color_codes, colors):
print(color_code, color)
B [0.20392156862745098, 0.3137254901960784, 0.39215686274509803] K [0.06274509803921569, 0.06274509803921569, 0.06274509803921569] B [0.20392156862745098, 0.3137254901960784, 0.39215686274509803] K [0.06274509803921569, 0.06274509803921569, 0.06274509803921569] B [0.20392156862745098, 0.3137254901960784, 0.39215686274509803] K [0.06274509803921569, 0.06274509803921569, 0.06274509803921569] OG [0.3607843137254902, 0.39215686274509803, 0.1568627450980392]
It would be convenient if we could define a mapping that maps each color code to its respective RGB triple.
Dictionaries¶
Let's consider a list, my_list.
my_list = ['Hello', 'World', 'Goodbye', 7]
We can think of my_list as a mapping between indices 0, 1, 2, 3, and values 'Hello', 'World', 'Goodbye', 7. That is, we have the following mappings:
- index
0maps to value'Hello', - index
1maps to value'World', - index
2maps to value'Goodbye', - index
3maps to value7.
To retrieve values of a list, we can "plug in" an index using square brackets []:
my_list[0]
'Hello'
my_list[1]
'World'
my_list[2]
'Goodbye'
A Python dictionary works very similarly, except that instead of a map from indices to values, we have a map from keys to values. These keys do not need to be integers 0, 1, 2, ..., but are more flexible. Dictionary keys can include integers, floats, strings, tuples, functions, and many other types (anything that is immutable).
To define a dictionary, we can use curly braces {} containing a comma-separated sequence of <key>:<value> mappings. For example, suppose we want to construct a dictionary with the following mappings:
- key
5maps to value'Hello!', - key
(0,255,0)maps to'Green', - key
'Good'maps to value10, - key
'Bad'maps to value0, - key
'Red'maps to value(255,0,0).
my_dict = {5: 'Hello!',
(0,255,0): 'Green',
'Good': 10,
'Bad': 0,
'Red': (255,0,0)}
Just like with lists, we can "plug in" a key to the dictionary and retrieve the corresponding value using square brackets [].
my_dict[5]
'Hello!'
my_dict['Good']
10
my_dict['Red']
(255, 0, 0)
my_dict['Blue']
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[48], line 1 ----> 1 my_dict['Blue'] KeyError: 'Blue'
Note: unlike lists , we cannot use slicing with dictionaries. This is because the dictionaries do not have any inherent order in Python.
If desired, we can access the keys of a dictionary using the .keys method. Similarly, we can access the values using the .values method. Finally, we can access key/value pairs using the .items method. This allows us to iterate through dictionaries in several ways:
for key in my_dictionary.keys()will iterate through each key of the dictionary. We can also writefor key in my_dictionary, which will still iterate through the keys.for value in my_dictionary.values()will iterate through each value of the dictionary.for key, value in my_dictionary.items()will iterate through each key/value pair.
for key in my_dict.keys():
print(key)
5 (0, 255, 0) Good Bad Red
for value in my_dict.values():
print(value)
Hello! Green 10 0 (255, 0, 0)
for key, value in my_dict.items():
print(key, value)
5 Hello! (0, 255, 0) Green Good 10 Bad 0 Red (255, 0, 0)
Exercise: Write a dictionary whose keys are the color codes 'B', 'K', and 'OG' and whose values are the corresponding RGB triples.
color_dict = {'B': [52/255, 80/255, 100/255],
'K': [16/255, 16/255, 16/255],
'OG':[92/255, 100/255, 40/255]}
color_dict['B']
[0.20392156862745098, 0.3137254901960784, 0.39215686274509803]
Exercise: Use the color_codes list and the above dictionary to construct a list colors containing the RGB triples for each stripe in the tartan recipe.