Week 7: Tuples and data structure#
Important
First, download_week07.py
and run the script in VSCode.
You may need to confirm the download in your browser.
The script should end with Successfully completed!
. If you encounter an error, follow the instructions in the error message. If needed, you can proceed with the exercises and seek assistance from a TA later.
In this week, we discuss how data can be structured using tuples. At first sight, tuples are very similar to lists, but a tuple cannot be changed once it has been created. This makes tuples slightly more efficient and also means that they can be used as dictionary keys. Moreover, tuples are very powerful in combination with functions that return several values.
A tuple is defined by a number of values separated by commas.
coordinates = (23.456, 45.789)
In the provided example, we have a tuple coordinates
containing two elements, representing latitude and longitude coordinates, respectively. To access the elements within a tuple, you can do so like this:
>>> coordinates = (23.456, 45.789)
>>> print("These are the coordinates – latitude:", coordinates[0], "and longitude:", coordinates[1])
These are the coordinates – latitude: 23.456 and longitude: 45.789
In this lecture, we also cover pseudorandom numbers.
Exercise 7.1: Warm up - Tuples#
Exercise 7.1
Update: Unfortunately, the original videos were garbled due to some sort of computer issue on my end (you can hear me notice a problem with the preview at the end of the first video, but since I was too dumb to check the full recording, I thought the video were okay..). I have re-recorded the videos but will leave the first on as is since only the last 20 seconds are affected. The example that I type in at the very end is d[3,1]
, which evaluates to the same result as d[(3,1)]
.
Tuples share some properties with lists. For example, you can use the len()
function to determine the length of a tuple.
The most important difference between tuples and lists is that tuples are immutable. This means that you cannot change the values in a tuple after it has been created.
In this warm up exercise, you will try some simple operations with tuples.
Create an empty tuple and a tuple with one item
Check if two tuples have the same length (test your solution by inserting it into the file
cp/ex07/have_equal_length.py
)Use tuple assignment to swap the values of two variables (compare to the exercise in week 1 (1.8))
Try changing a value in a tuple, what happens?
Try adding a value to a tuple, what happens?
Tip
You can create an empty tuple by using empty parentheses
()
or thetuple()
function.When only adding one item, make sure to add a comma after the item, otherwise Python will not recognize it as a tuple.
Tuple assignment is described in chapter 12.2 in [Dow16].
You can add a value to a tuple by adding two tuples together.
Exercise 7.2: Warm up - Random numbers#
Exercise 7.2
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
In this exercise, you will use the random
module to generate random numbers and try some useful functions of the random module.
Import the
random
moduleGenerate a random number between 0 and 1
Generate a random integer between 1 and 10
Generate two random integers between 5 and 10
Choose a random element from a list of strings
Sample 10 times from [1, 2, 3, 4, 5] with replacement (i.e. the same number can be drawn multiple times)
Sample 10 times from [1, 2, 3, 4, 5] with the probabiltiy of drawing each number being proportional to the number itself (i.e. 1 is drawn with probability 1/15, 2 with probability 2/15, etc.)
Repeat all to see how the results change.
Now, fix the seed by using random.seed(42)
and repeat all to see how the results change. You should get the same results every time now, why can this be useful?
This works, because the generated numbers are pseudorandom, so they are actually generated by a deterministic process based on the seed.
Tip
You can generate a random number between 0 and 1 using the
random()
function.You can generate a random integer between 1 and 10 using the
randint()
function.You can generate two random integers between 5 and 10 using the
sample()
in combination with therange()
function.You can choose a random element from a list using the
choice()
orsample()
function.You can sample from a list multiple times using the
choices()
function.You can sample from a list with probabilities using the
choices()
function with theweights
argument.
Optional: Try testing your functions this week by generating some random inputs.
Exercise 7.3: Last difference#
Exercise 7.3
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
In this exercise we want to compute a difference between the values which are at the last position in two tuples, regardless of the length of the tuples.
Consider two tuples \((12, 25, 17.6)\) and \((14, 12.1, 18, -6.7)\). The last element of the first tuple is 17.6 while the last element of the second tuple is -6.7. So, the function should return \(17.6-(-6.7)=24.3\).
You can test your function by running the following code block:
>>> last_difference((12, 25, 17.6), (14, 12.1, 18, -6.7))
24.3
You can also test your function by inserting your solution into the file cp/ex07/last_difference.py
.
- cp.ex07.last_difference.last_difference(a, b)#
Return the difference between last elements regardless of length.
- Parameters
a (
tuple
) – The first tuple.b (
tuple
) – The second tuple.
- Return type
float
- Returns
The difference between the last elements of the two tuples.
Exercise 7.4: Returning multiple values#
Exercise 7.4
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
Using tuples, we can create functions that return multiple values. This can be very useful if you are intrested in multiple values from a function.
In this exercise, we want to return a list of all elements that are bigger than a threshold and the minimum value of the list. You are given a list and a threshold value. The function should return a list of all elements that are bigger than the threshold and the minimum value of the list in a tuple.
Consider a list \([3, 2.4, 1.2, 4.3, -0.5]\) and a threshold value of 2. The function should return the list \([3, 2.4, 4.3]\) and the minimum value of the list, which is -0.5. So, the function should return the tuple \(([3, 2.4, 4.3], -0.5)\).
You can test your function by running the following code block, also try assigning the outputs to separate variables:
>>> returning_multiple_values([3, 2.4, 1.2, 4.3, -0.5], 2)
([3, 2.4, 4.3], -0.5)
>>> threshold_list, minimum_value = returning_multiple_values([3, 2.4, 1.2, 4.3, -0.5], 2)
>>> print(threshold_list)
[3, 2.4, 4.3]
>>> print(minimum_value)
-0.5
You can also test your function by inserting your solution into the file cp/ex07/returning_multiple_values.py
.
- cp.ex07.returning_multiple_values.returning_multiple_values(values, threshold)#
Return a tuple containing a list of all elements in the list that are greater than the threshold and the minimum of the values.
- Parameters
values (
list
) – A list of integers.threshold (
int
) – An integer.
- Return type
tuple
- Returns
A tuple containing the a list of elements that are greater than the threshold and the minimum of values
Exercise 7.5: Box packing#
Exercise 7.5
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
We aim to determine whether a rectangular object can fit within another rectangle (the box). Both the dimensions of the rectangular object and the rectangular box are defined using two-element tuples. Our goal is to calculate the length that object is sticking out from the box for each dimension. When there is sufficient space in a dimension, the function should return 0 for that dimension.
Consider an object with dimensions \((2, 5)\) and a box with dimensions \((4, 2.1)\). In the first dimension there is sufficient space as \(4-2>0\), so the function should return 0 for the first dimension. In the second dimension there is not sufficient space as \(2.1-5<0\), and the object is sticking out. So the function should return \(5-2.1=2.9\) for the second dimension.
Write a function that takes two tuples as input and returns a tuple with the length that the object is sticking out from the box, or 0, for each dimension. You can test your function by running the following code block:
>>> box_packing((2, 5), (4, 2.1))
(0, 2.9)
You can also test your function by inserting your solution into the file cp/ex07/box_packing.py
.
- cp.ex07.box_packing.box_packing(object, box)#
Return the amount of object sticking in each dimension, or zero if sufficient space.
- Parameters
object (
tuple
) – Tuple (h,w) the dimensions of the objectbox (
tuple
) – Tuple (H, W) the dimensions of the box.
- Return type
tuple
- Returns
Tuple
Exercise 7.6: Color hue#
Exercise 7.6
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
For the next exercise we have to compute the hue of a color given the RGB values. RGB is a color model which uses three values indicating the amount of red, green and blue light. Here we use a convention where each of three RGB values is in a range \([0,1]\). The hue is the color component represented by an angle in degrees, where 0 degree is red, 120 degree is green and 240 degree is blue.
Given a color \((R, G, B)\), the hue can be computed according to the following formulas:
Write a function that takes a tuple of three RGB-values as input and returns the corresponding hue. You can assume that \(\Delta \neq 0\). Also note that:
If two of the RGB-values are both largest, the two corresponding lines from the formula will lead to the same result.
If the computed value of H is negative, you must add 360 to get the correct value in degrees, so that you have:
For example, consider RGB values \((0.6, 0.2, 0.3)\). We have \(\Delta = 0.6-0.2=0.4\). Since \(R\) is the largest RGB-value, we have \(H=60 \cdot \frac{0.2-0.3}{0.4}=-15^\circ\). Since \(H\) is negative, we have to add 360 to get the correct value in degrees, so that we have \(H=345^\circ\).
You can check your function by running the following code block:
>>> RGB = (0.6, 0.2, 0.3)
>>> rgb_to_hue(RGB)
345.0
You can also test the function by inserting your solution into the file cp/ex07/rgb_to_hue.py
.
- cp.ex07.rgb_to_hue.rgb_to_hue(RGB)#
Return the hue given RGB values.
- Parameters
RGB (
tuple
) – Tuple containing three RGB values.- Return type
float
- Returns
Hue in degrees.
Exercise 7.7: Code shift#
Exercise 7.7
Note: Regrettably, the videos for this week are affected by quality issues due to a hardware problem during recording which I did not catch last night. I will re-record the video when I have time, but unfortunately I do not have time before the class today –Tue
A bike lock has 4 dials each with digits from 0 to 9. The code is set by turning the dials in discrete steps. Turning a dial for one stop 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.
For this exercise create a function which takes as an input a 4-digit code as a tuple of int
, and a 4-digit tuple of int
, representing a turn of all dials for a number of steps in a positive or a negative direction. The function should return a tuple representing the code after the turn.
For example, consider code \((9, 9, 9, 9)\) and the turns \((1, -1, 2, -2)\). The first dial is turned one step in the positive direction, so the code becomes \((0, 9, 9, 9)\). The second dial is turned one step in the negative direction, so the code becomes \((0, 8, 9, 9)\). The third dial is turned two steps in the positive direction, so the code becomes \((0, 8, 1, 9)\). The fourth dial is turned one step in the negative direction, so the code becomes \((0, 8, 1, 7)\).
Tip
Think about what happens when you increase a number over 9. How can you use the modulo operator %
for this scenario to get the right number?
You can test your function by running the following code block:
>>> code_shift((9, 9, 9, 9), (1, -1, 2, -2))
(0, 8, 1, 7)
You can also test the function by inserting your solution into the file cp/ex07/code_shift.py
.
- cp.ex07.code_shift.code_shift(code, turn)#
Return the updated code pattern.
- Parameters
code (
tuple
) – Tuple with the initial code in the lockturn (
tuple
) – Tuple with the turn on each lock dial
- Return type
tuple
- Returns
Updated lock code.
Exercise 7.8: Morse code#
For project exercises in week 7, the focus is not on tuples, but on general competencies combining all you learned up to now.
Morse code is a method of transmitting messages using a series of short and long signals called “dots” and “dashes”.
Letters are separated by a single space ” “, and words are separated by a double space ” “.
The Morse alphabet is shown using a dict
below:
# Morse code dictionary mapping Morse code symbols to letters
morse_code_dict = {
'.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D', '.': 'E', '..-.': 'F', '--.': 'G',
'....': 'H', '..': 'I', '.---': 'J', '-.-': 'K', '.-..': 'L', '--': 'M', '-.': 'N',
'---': 'O', '.--.': 'P', '--.-': 'Q', '.-.': 'R', '...': 'S', '-': 'T', '..-': 'U',
'...-': 'V', '.--': 'W', '-..-': 'X', '-.--': 'Y', '--..': 'Z'}
Write a function that takes as input a string of Morse code and returns the corresponding text. You can assume that the input string is a valid Morse code string.
For example, consider the string .. .- -- .- ... --.- ..- .. .-. .-. . .-..
.
There are four words in this string, separated by two spaces. First word is ..
. It contains only one letter, letter I
.
Second word is .- --
which has two letters .-
and --
. Those letters are A
and M
, so second word is AM
.
The third word is one letter A
and the fourth word contains letters spelling SQUIRREL
. So the function should return I AM A SQUIRREL
.
You can test your function by running the following code block:
>>> morse_to_text(".. .- -- .- ... --.- ..- .. .-. .-. . .-..")
'I AM A SQUIRREL'
You can test the function by inserting your solution into the file cp/ex07/morse_to_text.py
.
Tip
You can split a string into a list of strings using the
split()
function.You can use the
join()
function to join a list of strings into a single string.
- cp.ex07.morse_to_text.morse_to_text(morse_code)#
Return the extracted message from its Morse code.
- Parameters
morse_code (
str
) – String with the initial message encoded in Morse.- Return type
str
- Returns
The decoded message.
Exercise 7.9: Astronomical season#
Task Description:
You are given a date represented as a tuple
with two elements:
The first element is the day of the month.
The second element is the name of the month (
jan
-dec
).
You can use the following dictionary:
month_name_to_month_number = {
'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6,
'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12
}
Your task is to write a Python function that as input takes a date as a tuple
and returns the string with the corresponding astronomical season.
Astronomical seasons start on specific days of the year:
Spring starts on the 20th of March (the first day of astronomical spring).
Summer starts on the 21st of June (the first day of astronomical summer).
Autumn starts on the 23rd of September (the first day of astronomical autumn).
Winter starts on the 21st of December (the first day of astronomical winter).
Your function should determine the season based on the provided date and return one of the following: spring
, summer
, autumn
or winter
.
Check the following examples to get a better understanding of how your implementation output should look like:
>>> astronomical_season((20, "mar"))
'spring'
>>> astronomical_season((21, "mar"))
'spring'
>>> astronomical_season((1, "jan"))
'winter'
You can test the function by inserting your solution into the file cp/ex07/astronomical_season.py
.
- cp.ex07.astronomical_season.astronomical_season(date)#
Return the astronomical season of the given date.
- Parameters
date (
tuple
) – Tuple with the given date.- Return type
str
- Returns
String with astronomical season