In [1]:
from okcode import *
=====================================================================
Assignment: Worksheet 12
OK, version v1.14.18
=====================================================================
Introduction to Mathematical Computing
¶
Phil Ramsden
¶
Worksheet 12: Sets, frozensets, dictionaries and classes
¶
Question 1¶
(i)¶
(a) Create a list, a tuple, a set and a frozenset, each containing the odd integers between 13 and 103 inclusive.
In [5]:
list1 = list(range(13,104,2))
tuple1 = tuple(range(13,104,2))
set1 = set(range(13,104,2))
fs1 = frozenset(13,104,2)
print(list1)
print(tuple1)
print(set1)
print(fs1)
—————————————————————————
TypeError Traceback (most recent call last)
2 tuple1 = tuple(range(13,104,2))
3 set1 = set(range(13,104,2))
—-> 4 fs1 = frozenset(13,104,2)
5
6 print(list1)
TypeError: frozenset expected at most 1 arguments, got 3
In [6]:
grade = ok.grade(‘question-1ia’)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests
———————————————————————
question 1ia > Suite 1 > Case 4
>>> fs1 == frozenset({13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103})
NameError: name ‘fs1’ is not defined
# Error: expected
# True
# but got
# Traceback (most recent call last):
# …
# NameError: name ‘fs1’ is not defined
Run only this test case with “python3 ok -q question-1ia –suite 1 –case 4”
———————————————————————
Test summary
Passed: 3
Failed: 1
[oooooook…] 75.0% passed
(b) Set up list2, identically equal to list1, and list3, a copy of list1 created using the copy function. Also set up set2, identically equal to set1, and set3, a copy of set1 created using the copy function.
In [7]:
# imports
list2 = list1
list3 = copy(list1)
set2 = set1
set3 = copy(set1)
print(list2)
print(list3)
print(set2)
print(set3)
—————————————————————————
NameError Traceback (most recent call last)
2
3 list2 = list1
—-> 4 list3 = copy(list1)
5 set2 = set1
6 set3 = copy(set1)
NameError: name ‘copy’ is not defined
In [8]:
grade = ok.grade(‘question-1ib’)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests
———————————————————————
question 1ib > Suite 1 > Case 2
>>> list3
NameError: name ‘list3’ is not defined
# Error: expected
# [13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103]
# but got
# Traceback (most recent call last):
# …
# NameError: name ‘list3’ is not defined
Run only this test case with “python3 ok -q question-1ib –suite 1 –case 2”
———————————————————————
Test summary
Passed: 1
Failed: 1
[oooook…..] 50.0% passed
(c) Introduce the element 105 to list1 using the append method, and introduce the element 105 to set1 using the add method.
In [9]:
print(list1)
print(set1)
[13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103]
{13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103}
In [10]:
grade = ok.grade(‘question-1ic’)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running tests
———————————————————————
question 1ic > Suite 1 > Case 1
>>> list1
[13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103]
# Error: expected
# [13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105]
# but got
# [13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103]
Run only this test case with “python3 ok -q question-1ic –suite 1 –case 1”
———————————————————————
Test summary
Passed: 0
Failed: 1
[k……….] 0.0% passed
(d) Check the values of list2, list3, set2 and set3. Which of the following is true?
1. The values of list2, list3, set2 and set3 have all changed.
2. The values of list2, list3, set2 and set3 have all stayed the same.
3. The values of list2 and set2 have changed, but the values of list3 and set3 have stayed the same.
4. The values of list3 and set3 have changed, but the values of list2 and set2 have stayed the same.
5. Onlylist2 has changed; the rest have have stayed the same.
6. Onlyset2 has changed; the rest have have stayed the same.
In [ ]:
question1id_answer =
In [ ]:
grade = ok.grade(‘question-1id’)
(e) Again, introduce the element 105 to list1 using the append method, and introduce the element 105 to set1 using the add method.
In [ ]:
# insert your code
print(list1)
print(set1)
In [ ]:
grade = ok.grade(‘question-1ie’)
(f) Once more, check the values of list2, list3, set2 and set3. Which of the following is true?
1. The values of list2, list3, set2 and set3 have all changed.
2. The values of list2, list3, set2 and set3 have all stayed the same.
3. The values of list2 and set2 have changed, but the values of list3 and set3 have stayed the same.
4. The values of list3 and set3 have changed, but the values of list2 and set2 have stayed the same.
5. Onlylist2 has changed; the rest have have stayed the same.
6. Onlyset2 has changed; the rest have have stayed the same.
In [ ]:
question1if_answer = # (insert one of 1, 2, 3, 4, 5, or 6)
In [ ]:
grade = ok.grade(‘question-1if’)
(g) Redefine list1 as the list of multiples of 5 between 1005 and 1305 inclusive, and redefine set1 as the set of multiples of 5 between 1005 and 1305 inclusive.
In [ ]:
# insert your code
print(list1)
print(set1)
In [ ]:
grade = ok.grade(‘question-1ig’)
(h) For a third time, check the values of list2, list3, set2 and set3. Which of the following is true?
1. The values of list2, list3, set2 and set3 have all changed.
2. The values of list2, list3, set2 and set3 have all stayed the same.
3. The values of list2 and set2 have changed, but the values of list3 and set3 have stayed the same.
4. The values of list3 and set3 have changed, but the values of list2 and set2 have stayed the same.
5. Onlylist2 has changed; the rest have have stayed the same.
6. Onlyset2 has changed; the rest have have stayed the same.
In [ ]:
question1ih_answer = # (insert one of 1, 2, 3, 4, 5, or 6)
In [ ]:
grade = ok.grade(‘question-1ih’)
(ii)¶
(a) Define row1 as [1, 3, 5], row2 as [1, 4, 7] and row3 as [1, 5, 9], and define list_of_lists1 as [row1, row2, row3].
Set up list_of_lists2 as identical to list_of_lists1, and list_of_lists3 as a copy of it.
In [ ]:
# insert your code
print(list_of_lists1)
print(list_of_lists2)
print(list_of_lists3)
In [ ]:
grade = ok.grade(‘question-1iia’)
(b) Type
list_of_lists1[1][1] = 400
Check the values of list_of_lists2 and list_of_lists3. Which of the following is true?
1. The values of list_of_lists2 and list_of_lists3 have both changed.
2. The values of list_of_lists2 and list_of_lists3 have both stayed the same.
3. The value of list_of_lists2 has changed, but that of list_of_lists3 has stayed the same.
4. The value of list_of_lists3 has changed, but that of list_of_lists2 has stayed the same.
In [ ]:
question1iib_answer = # (delete, and insert one of 1, 2, 3 or 4)
In [ ]:
grade = ok.grade(‘question-1iib’)
(c) Redefine row1, row2, row3 and list_of_lists1 as in (a) above.
Create an object, list_of_lists4, that is a deep copy of list_of_lists1: that is, not only is it itself a copy, but all three of the elements that make it up are copies of the corresponding elements of list_of_lists1. It should remain the same in the face of changes to any of the numbers that form part of list_of_lists1.
Note: don’t do this just by repeating the definition of list_of_lists1; find a smarter way! There are at least two ways of doing this task. One uses a comprehension, and the other uses another function from the copy module, whose name you might be able to guess (and which is in any case available on the Internet…)
In [ ]:
# insert your code
print(list_of_lists1)
print(list_of_lists4)
In [ ]:
grade = ok.grade(‘question-1iic’)
(d) Can you find the other method, calling your second deep copy list_of_lists5? (Autograding won’t be able to tell if you’ve “cheated” here by doing the same thing twice; but you’ll know!)
In [ ]:
# insert your code
print(list_of_lists1)
print(list_of_lists5)
In [ ]:
grade = ok.grade(‘question-1iid’)
Question 2¶
(i)¶
The following data consists of:
• Eight dictionaries, each with the same three keys: ‘radius’, ‘mass’ and ‘escape_velocity’; the value associated with each key is a float.
• One “master dictionary”, consisting of eight keys corresponding to the names of the planets in our solar system; the value associated with each key is a dictionary.
In [ ]:
mercury_data = {‘radius’ : 2.4e6, ‘mass’ : 3.3e23,
‘escape_velocity’ : 4.3e3}
venus_data = {‘radius’ : 6.1e6, ‘mass’ : 4.9e24,
‘escape_velocity’ : 1.0e4}
earth_data = {‘radius’ : 6.3e6, ‘mass’ : 6.0e24,
‘escape_velocity’ : 1.1e4}
mars_data = {‘radius’ : 3.4e6, ‘mass’ : 6.4e23,
‘escape_velocity’ : 5.0e3}
jupiter_data = {‘radius’ : 6.9e7, ‘mass’ : 1.9e27,
‘escape_velocity’ : 6.0e4}
saturn_data = {‘radius’ : 5.7e7, ‘mass’ : 5.6e26,
‘escape_velocity’ : 3.6e4}
uranus_data = {‘radius’ : 2.5e7, ‘mass’ : 8.7e25,
‘escape_velocity’ : 2.2e4}
neptune_data = {‘radius’ : 2.5e7, ‘mass’ : 1.0e26,
‘escape_velocity’ : 2.4e4}
planet_data = {
‘mercury’: mercury_data,
‘venus’: venus_data,
‘earth’: earth_data,
‘mars’: mars_data,
‘jupiter’: jupiter_data,
‘saturn’: saturn_data,
‘uranus’: uranus_data,
‘neptune’: neptune_data,
}
(a) Create a list containing all the planetary radii.
In [ ]:
radius_list = # insert your code
print(radius_list)
In [ ]:
grade = ok.grade(‘question-2ia’)
(b) Create a set containing all the names of the planets.
In [ ]:
name_set = # insert your code
print(name_set)
In [ ]:
grade = ok.grade(‘question-2ib’)
(c) Create a dictionary, the keys of which are the names of the planets and the associated values of which are the escape velocities.
In [ ]:
ev_dict = # insert your code
print(ev_dict)
In [ ]:
grade = ok.grade(‘question-2ic’)
(d) Create a dictionary, the keys of which are the names of the planets and the associated values of which are the quantities $$\frac{1}{v_e}\,\sqrt{\frac{M}{R}},$$ where $R$, $M$ and $v_e$ are, respectively, the radius, mass and escape velocity.
In [ ]:
# imports
combined_dict = # insert your code
print(combined_dict)
In [ ]:
grade = ok.grade(‘question-2id’)
(ii)¶
The following is an attempt to set up a little dictionary linking the IUPAC systematic and preferred designations of the isomers of xylene (dimethylbenzene).
In [ ]:
xylene_isomers = {
[1, 2] : ‘orthoxylene’,
[1, 3] : ‘metaxylene’,
[1, 4] : ‘paraxylene’}
The way it’s meant to work is that since, for example, 1,2-dimethylbenzene is also known as orthoxylene, I can type
xylene_isomers([1, 2])
and get the output ‘orthoxylene’.
(a) However, it doesn’t work. Fix it!
In [ ]:
xylene_isomers = # insert your code
print(xylene_isomers)
In [ ]:
grade = ok.grade(‘question-2iia’)
(b) Which of the following data types and data structures can serve as the keys in a dictionary? Type your answer as a set.
1. floats;
2. ints;
3. complexes;
4. strings;
5. lists;
6. tuples;
7. NumPy arrays;
8. sets;
9. frozensets;
10. dictionaries.
In [ ]:
question2iib_answer = # insert a set of ints
In [ ]:
grade = ok.grade(‘question-2iib’)
(c) Which of the following data types and data structures can serve as the values in a dictionary? Type your answer as a set.
1. floats;
2. ints;
3. complexes;
4. strings;
5. lists;
6. tuples;
7. NumPy arrays;
8. sets;
9. frozensets;
10. dictionaries.
In [ ]:
question2iic_answer = # insert a set of ints
In [ ]:
grade = ok.grade(‘question-2iic’)
Question 3¶
Write and test a function called power_set which takes as its argument a set, and returns the set of that set’s subsets (each subset being represented as a frozenset). So, for example,
power_set({0,1})
should return {frozenset(), frozenset({1}), frozenset({0}), frozenset({0, 1})}.
(I think this is a naturally recursive task. I also think this is quite tricky.)
In [ ]:
# insert your code
In [ ]:
grade = ok.grade(‘question-3’)
Question 4¶
(a) Write a class called Rational to represent fractions. It should have one attribute, called numden, which should be a tuple containing two integers, and methods called num and den, which do the obvious things.
So to instantiate the rational number 1/2, one would type
q1 = Rational(1,2)
Then q1.numden returns (1, 2), q1.num() returns 1 and q1.den() returns 2.
In [ ]:
# insert your code for the class Rational
In [ ]:
grade = ok.grade(‘question-4a’)
(b) Test your class by instantiating the objects Rational(1,2), Rational(2,4) and Rational(3,-6) as q1, q2 and q3 respectively, and using your two methods on them.
In [ ]:
q1 = # insert your code
q2 = # insert your code
q3 = # insert your code
print(q1.num())
print(q1.den())
print(q2.num())
print(q2.den())
print(q3.num())
print(q3.den())
In [ ]:
grade = ok.grade(‘question-4b’)
(c) By changing the __init__ method, or otherwise, make your Rational type automatically reduce fractions to their lowest terms, making the denominator positive. You’ll need a gcd function; here’s one you can use:
def gcd(a, b):
while b > 0:
a, b = b, a % b
return a
Note that you don’t need to write any recursive methods for this task.
In [ ]:
# insert your amended code for the class Rational
In [ ]:
grade = ok.grade(‘question-4c’)
(d) Test your class, as amended, by instantiating the objects Rational(1,2), Rational(2,4) and Rational(3,-6), and using your two methods on them.
In [ ]:
q1 = # insert your code
q2 = # insert your code
q3 = # insert your code
print(q1.num())
print(q1.den())
print(q2.num())
print(q2.den())
print(q3.num())
print(q3.den())
In [ ]:
grade = ok.grade(‘question-4d’)
(e) Write and test methods called negative and reciprocal. These should return instances of the Rational class, so that if
q1 = Rational(1,2)
then q1.negative() will return a Rational object with a numden value of (-1, 2), and q1.reciprocal() will return a Rational object with a numden value of (2, 1).
In [ ]:
# insert your further amended code for the class Rational
In [ ]:
grade = ok.grade(‘question-4e’)
(f) Write and test a method called plus, such that
q1.plus(q2)
returns the Rational representing the sum of the rationals q1 and q2.
Thus
q1 = Rational(1,6)
q2 = Rational(1,3)
r = q1.plus(q2)
r.numden
should return (1, 2).
In [ ]:
# insert your yet further amended code for the class Rational
In [ ]:
grade = ok.grade(‘question-4f’)
Question 5.¶
(a) Take your xylene_isomers dictionary, as corrected, and convert it into a string, xylene_isomers_string.
In [ ]:
# insert your code
In [ ]:
grade = ok.grade(‘question-5a’)
(b) Write this string to an external file called xylene_isomers.txt. Autograding can’t help you here!
In [ ]:
# insert your code
(c) Quit the Kernel, and then read in your external file as a string, xylene_isomers_string2.
In [ ]:
# insert your code
In [ ]:
grade = ok.grade(‘question-5c’)
(d) Convert this string back into a dictionary, xylene_isomers2.
In [ ]:
# insert your code
In [ ]:
grade = ok.grade(‘question-5d’)
(e) Take your xylene_isomers dictionary, as corrected, and pickle it as xylene_isomers.pickle. Autograding can’t help here!
In [ ]:
# insert your code
(f) Quit the kernel, and unpickle this file as xylene_isomers3.
In [ ]:
# insert your code
In [ ]:
grade = ok.grade(‘question-5f’)
In this same way, pickle and unpickle:
(g) the cos function from math;
(h) your power_set function;
(j) your Rational class.
Call the pickled-and-unpickled versions pickled_cos, pickled_power_set and PickledRational respectively.
In [ ]:
# insert your code for question 5g
In [ ]:
grade = ok.grade(‘question-5g’)
In [ ]:
# insert your code for question 5h
In [ ]:
grade = ok.grade(‘question-5h’)
In [ ]:
# insert your code for question 5j
In [ ]:
grade = ok.grade(‘question-5j’)
In [ ]: