Sale!

SOLVED: COMP9021 Assignment 3 v. 1.1

Original price was: $35.00.Current price is: $30.00.

Category:

Description

5/5 - (4 votes)

2 The ring class (5 marks)
The main aim is to modify the meaning of slices so that we can select parts of a sequence in such a way
that wrapping around is possible. For that purpose, we define a ring module.
$ python3

>>> from ring import *
The class we are defining can operate on sequences, and on sequences only, including objects of class
Ring, with an empty list as default.
>>> ring = Ring ({1 , 2 , 3})
Traceback ( most recent call last ):

TypeError : ’set ’ object is not subscriptable
>>> ring = Ring (1)

TypeError : ’int ’ object is not subscriptable
>>> ring = Ring ([1 , 2 , 3])
>>> ring
Ring ([1 , 2 , 3])
>>> print ( ring )
[1 , 2 , 3]
>>> ring = Ring ((1 , 2 , 3))
>>> ring
Ring ((1 , 2 , 3))
>>> print ( ring )
(1 , 2 , 3)
>>> ring = Ring ()
>>> ring
Ring ([])
>>> ring = Ring ([1 , 2 , 3])
>>> Ring ( ring )
Ring ([1 , 2 , 3])
>>> ring = Ring ((1 , 2 , 3))
>>> Ring ( ring )
Ring ((1 , 2 , 3))
We can use indexes or slices, with the usual error messages when indexes or arguments of slices are not
integers:
>>> ring = Ring ([1 , 2 , 3])
>>> ring [ ’a ’]
Traceback ( most recent call last ):

TypeError : ring indices must be integers or slices , not str
>>> ring [ ’a ’: 1: 2]
Traceback ( most recent call last ):

TypeError : slice indices must be integers or None or have an __index__ method
>>> ring [0: : ’a ’]
Traceback ( most recent call last ):

TypeError : slice indices must be integers or None or have an __index__ method
2
We can use any integer as index, computing modulo the length of the sequence.
>>> ring = Ring ([1 , 2 , 3])
>>> len ( ring )
3 COMP9021
>>> ring [ -5] , ring [ -4] , ring [ -3] , ring [ -2] , ring [ -1]
(2 , 3 , 1 , 2 , 3)
>>> ring [0] , ring [1] , ring [2] , ring [3] , ring [4] , ring [5]
(1 , 2 , 3 , 1 , 2 , 3)
With slices, the second argument is included, not excluded, and we wrap around when needed:
>>> ring = Ring ( tuple ( range (5)))
>>> ring [2: 2]
(2 ,)
>>> ring [2: 3]
(2 , 3)
>>> ring [2: 4]
(2 , 3 , 4)
>>> ring [2: 5]
(2 , 3 , 4 , 0)
>>> ring [2: 6]
(2 , 3 , 4 , 0 , 1)
>>> ring [2: 7]
(2 ,)
>>> ring [3: 2]
(3 , 4 , 0 , 1 , 2)
>>> ring [4: 2]
(4 , 0 , 1 , 2)
>>> ring [5: 2]
(0 , 1 , 2)
>>> ring [6: 2]
(1 , 2)
>>> ring [7: 2]
(2 ,)
>>> ring [8: 2]
(3 , 4 , 0 , 1 , 2)
The first argument of a slice defaults to 0. The second argument defaults to the first argument minus
1 when step is positive, and to the first argument plus 1 when step is negative. The third argument
defaults to 1. Also, a step of 0 is acceptable, which always returns an empty sequence.
>>> ring [: ]
(0 , 1 , 2 , 3 , 4)
>>> ring [: : -1]
(0 , 4 , 3 , 2 , 1)
>>> ring [: 3]
(0 , 1 , 2 , 3)
>>> ring [: 3: -1]
(0 , 4 , 3)
>>> ring [3: : ]
(3 , 4 , 0 , 1 , 2)
>>> ring [3: : -1]
(3 , 2 , 1 , 0 , 4)
>>> ring [2: : 0]
()
3
More examples, with a step different to 1 or -1:
>>> ring = Ring ( list ( range (5)))
>>> ring [3: 1: 2]
[3 , 0]
>>> ring [2: 3: -2]
[2 , 0 , 3]
>>> ring [2: 1: 3]
[2 , 0]
>>> ring [2: 3: -3]
[2 , 4]
We can also change some Ring objects in place. Our interface is similar to the standard one when we
deal with indexes:
>>> ring = Ring ( tuple ( range (3)))
>>> ring [1] = 8
Traceback ( most recent call last ):

TypeError : ’ tuple ’ object does not support item assignment
>>> ring = Ring ( list ( range (5)))
>>> ring [2] = -2
>>> ring
Ring ([0 , 1 , -2 , 3 , 4])
>>> ring [21] = -1
>>> ring
Ring ([0 , -1 , -2 , 3 , 4])
But it is very different to the standard one when we deal with slices. First, we accept a step of 0, in
which case we replace simple slices. Note that when we replace part of the end and the beginning of a
sequence, the replacement is always placed at the beginning of the sequence.
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 4: 0] = [ -1]
>>> ring
Ring ([0 , 1 , -1])
>>> ring = Ring ( list ( range (5)))
>>> ring [4: 4: 0] = [ -1 , -2]
>>> ring
Ring ([0 , 1 , 2 , 3 , -1 , -2])
>>> ring = Ring ( list ( range (5)))
>>> ring [3: 2: 0] = ( -1 ,)
>>> ring
Ring ([ -1])
>>> ring = Ring ( list ( range (5)))
>>> ring [3: 1: 0] = ( -1 , -2 , -3)
>>> ring
Ring ([ -1 , -2 , -3 , 2])
4 COMP9021
For strictly positive steps, we insert data, between the start and the end, in a number of slots that has
to be equal to the number of data to insert:
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 4] = [ -1]
Traceback ( most recent call last ):

ValueError : attempt to insert sequence of size 1 to extended slice of size 2
>>> ring [2: 4] = [ -1 , -2 , -3]
Traceback ( most recent call last ):

ValueError : attempt to insert sequence of size 3 to extended slice of size 2
The following illustrates. Note that when we insert a datum between the last and the first element of a
sequence, that datum is always placed at the beginning of the sequence.
>>> ring = Ring ( list ( range (5)))
>>> ring [0: 3] = -1 , -2 , -3
>>> ring
Ring ([0 , -1 , 1 , -2 , 2 , -3 , 3 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 1] = -1 , -2 , -3 , -4
>>> ring
Ring ([ -3 , 0 , -4 , 1 , 2 , -1 , 3 , -2 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 0] = -1 , -2 , -3
>>> ring
Ring ([ -3 , 0 , 1 , 2 , -1 , 3 , -2 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [4: 1] = -1 , -2
>>> ring
Ring ([ -1 , 0 , -2 , 1 , 2 , 3 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [4: 0] = ( -1 ,)
>>> ring
Ring ([ -1 , 0 , 1 , 2 , 3 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [3: 3] = -1 , -2 , -3 , -4 , -5
>>> ring
Ring ([ -2 , 0 , -3 , 1 , -4 , 2 , -5 , 3 , -1 , 4])
>>> ring = Ring ( list ( range (10)))
>>> ring [1: 7: 2] = -1 , -2 , -3
>>> ring
Ring ([0 , 1 , -1 , 2 , 3 , -2 , 4 , 5 , -3 , 6 , 7 , 8 , 9])
>>> ring = Ring ( list ( range (10)))
>>> ring [7: 2: 2] = -1 , -2 , -3
>>> ring
Ring ([ -2 , 0 , 1 , -3 , 2 , 3 , 4 , 5 , 6 , 7 , -1 , 8 , 9])
5 COMP9021
For strictly negative steps, we replace data, between the start and the end, that have to be equal in
number to the number of data to replace:
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 4: -1] = [ -1 , -2]
Traceback ( most recent call last ):

ValueError : attempt to replace sequence of size 2 to extended slice of size 3
>>> ring [2: 4: -1] = [ -1 , -2 , -3 , -4]
Traceback ( most recent call last ):

ValueError : attempt to replace sequence of size 4 to extended slice of size 3
The following illustrates.
>>> ring = Ring ( list ( range (5)))
>>> ring [0: 3: -1] = -1 , -2 , -3 , -4
>>> ring
Ring ([ -1 , -2 , -3 , -4 , 4])
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 1: -1] = -1 , -2 , -3 , -4 , -5
>>> ring
Ring ([ -4 , -5 , -1 , -2 , -3])
>>> ring = Ring ( list ( range (5)))
>>> ring [2: 0: -1] = -1 , -2 , -3 , -4
>>> ring
Ring ([ -4 , 1 , -1 , -2 , -3])
>>> ring = Ring ( list ( range (5)))
>>> ring [4: 1: -1] = -1 , -2 , -3
>>> ring
Ring ([ -2 , -3 , 2 , 3 , -1])
>>> ring = Ring ( list ( range (5)))
>>> ring [4: 0: -1] = ( -1 , -2) # Note : fixed from original version
>>> ring
Ring ([ -2 , 1 , 2 , 3 , -1])
>>> ring = Ring ( list ( range (5)))
>>> ring [3: 3: -1] = -1 # Note : fixed from original version
>>> ring
Ring ([0 , 1 , 2 , -1 , 4])
>>> ring = Ring ( list ( range (10)))
>>> ring [1: 7: -2] = -1 , -2 , -3 , -4
>>> ring
Ring ([0 , -1 , 2 , -2 , 4 , -3 , 6 , -4 , 8 , 9])
>>> ring = Ring ( list ( range (10)))
>>> ring [7: 2: -2] = -1 , -2 , -3
>>> ring
Ring ([0 , -3 , 2 , 3 , 4 , 5 , 6 , -1 , 8 , -2])
6 COMP9021
Finally, we want Ring objects to be generators—they can be used only once. Starting point and increment,
set by default to 0 and 1, respectively, can be changed, and iteration will proceed till we reach an element
that has already been generated:
>>> ring = Ring ( list ( range (5)))
>>> for i in ring :
… print ( i )

0
1
2
3
4
>>> ring = Ring ( tuple ( range (5)))
>>> ring . start = 2
>>> ring . step = 2
>>> for i in ring :
… print ( i )

2
4
1
3
0
>>> ring = Ring ( range (12))
>>> ring . start = 5
>>> ring . step = -3
>>> for i in ring :
… print ( i )

5
2
11
8
>>> ring = Ring ( range (7))
>>> ring . start = 10
>>> ring . step = 4
>>> for i in ring :
… print ( i )

3
0
4
1
5
2
6
7
3 Solving tangrams (4 marks)
As expected and promised…
The aim is of course not to, for a given set of pieces and a shape, come up with a particular solution, but
come up with some solution.
$ python3

>>> from tangram import *
>>> file = open ( ’ pieces_A . xml ’)
>>> coloured_pieces = available_coloured_pieces ( file )
>>> file = open ( ’ shape_A_1 . xml ’)
>>> shape = available_coloured_pieces ( file )
>>> solution = solve ( coloured_pieces , shape )
>>> if solution :
… output_file = open ( ’ tangram_A_1_a . xml ’ , ’w ’)
… write_coloured_pieces_to_file ( solution , output_file )
… output_file . close ()
… else :
… print ( ’ No solution could be found . ’)

… file = open ( ’ tangram_A_1_a . xml ’)
>>> tangram = available_coloured_pieces ( file )
>>> is_solution ( tangram , shape )
True
8 COMP9021