Bus2

Consider a dictionary (dict) with information about the passengers of an interurban bus. Let’s call it a passengers dictionary (or psgD for short).

The keys in psgD are person identifiers, each composed of a 2-component tuple with a number (int) and one capital letter (str). The values in psgD are 4-component tuple with:

  • the passenger’s name (srt)

  • the row and seat where his/her is supposed to seat (int)

  • the passenger’s destination or stop (srt)

For example:


>>> d = {
... (122, 'D'): ('Badosa', 3, 4, 'Olot'),
... (563, 'P'): ('Lopez', 1, 4, 'Olot'),
... (765, 'P'): ('Espígol', 3, 2, 'Amer'),
... (444, 'N'): ('Penosa', 2, 1, 'Amer'),
... (771, 'L'): ('Vila', 1, 3, 'Amer'),
... (666, 'G'): ('Guell', 1, 2, 'Olot'),
... }

You are required to implement the following functions and deliver all of them in the same module bus2 (file bus2.py). The tentative weight for each problem is 60%, 10%, 20% and 10% respectively, although the weight of the former function could be increased.

Warning

Do not leave pieces of code that are wither incomplete or contain syntax errors in the file to deliver since that would result in a 0.0 grade for all the functions.


First we need to generate a new dictionary for the bus driver indicating the passengers that are suposed to get off the bus at each stop. To that purpose, you are asked to deliver the following function:

gen_stop_seats_D(psgD)

such that

given psgD a passenger’s dict as described above

returns a new dict where:

  1. The keys are the stops (str) where at least one passenger is supposed to get off.

  2. The value associated to each stop is a list of the row and seat (tuple) of the passengers supposed to get off at that stop. The seats will preserve the order coming from the psgG traversal order (so they do not need to be re-ordered right now).

The input dict should not be modified.

For example:


>>> d = {
... (122, 'D'): ('Badosa', 3, 4, 'Olot'),
... (563, 'P'): ('Lopez', 1, 4, 'Olot'),
... (765, 'P'): ('Espígol', 3, 2, 'Amer'),
... (444, 'N'): ('Penosa', 2, 1, 'Amer'),
... (771, 'L'): ('Vila', 1, 3, 'Amer'),
... (666, 'G'): ('Guell', 1, 2, 'Olot'),
... }

--in-fi

>>> dcorr = {
... 'Olot': [(3, 4), (1, 4), (1, 2)],
... 'Amer': [(3, 2), (2, 1), (1, 3)],
... }

Doctests are available in the gen_stop_seats_D.test file.


Second, we want the lists of seats in the dict output of the previous function to be increasingly ordered:

sort_stop_seats_D(stpD)

such that

given stpD a dict as described for the output of the previous function

updates stpD by ordering the lists of seats in the values of all keys as follows: increasingly by the row, and, the seats in the same row also increasingly by the seat. Nothing else should be changed.

For example:


>>> d = {
... 'Olot': [(3, 4), (1, 4), (1, 2)],
... 'Amer': [(3, 2), (2, 1), (1, 3)],
... }

>>> sort_stop_seats_D(d)

>>> dcorr = {
... 'Olot': [(1, 2), (1, 4), (3, 4)],
... 'Amer': [(1, 3), (2, 1), (3, 2)],
... }

Doctests are available in the sort_stop_seats_D.test file.


Third, we need a function to support the change of the seat of a particular passenger:

move_passenger(psgD, name, new_row, new_seat)

such that

given psgD a dict as described above

does 2 things:

updates psgD by changing the row and seat of the passenger named name to new_row, new_seat respectively. If there is no passenger with that name in psgD then no modification is done.

returns the passenger identifier (tuple of int and str) and his/her new row and seat (tuple of int). If there is no passenger with that name in psgD then the empty tuple is returned instead of the passenger’s identifier, together with the intended new row and seat.

For example:


>>> d = {
... (771, 'L'): ('Vila', 1, 3, 'Amer'),
... (122, 'D'): ('Badosa', 1, 4, 'Olot'),
... (563, 'P'): ('Lopez', 2, 4, 'Olot'),
... (444, 'N'): ('Penosa', 2, 1, 'Amer'),
... (765, 'P'): ('Espigol', 1, 2, 'Amer'),
... }

>>> res = move_passenger(d, 'Vila', 2, 2)
    
>>> dref = {
... (122, 'D'): ('Badosa', 1, 4, 'Olot'),
... (563, 'P'): ('Lopez', 2, 4, 'Olot'),
... (444, 'N'): ('Penosa', 2, 1, 'Amer'),
... (765, 'P'): ('Espigol', 1, 2, 'Amer'),
... (771, 'L'): ('Vila', 2, 2, 'Amer'),
... }
    
>>> if res == ((771, 'L'), (2, 2)) and d == dref:
... 	True
... else: 
... 	(res, d)
True


>>> res = move_passenger(d, 'Sanchez', 1, 1)

>>> if res == ((), (1, 1)) and d == dref:
... 	True
... else: 
... 	(res, d)
True

Doctests are available in the move_passenger.test file.


Fourth, we wish to generate and sort a list from a given passengers dict as described above at the beginning. To that purpose you have to implement the following function:

sort_pass_L_2(psgD)

such that

given psgD a dict as described above

returns a list such that

  • It contains exactly all the information of psgD in the following way: for each entry in psgD there is a single tuple with the information from both the key and the value of that entry.

  • The tuples are ordered according to the following criteria (ordered from higher to lower priority):

    1. The name of the distination in alphabetical order.

    2. The number of row in decreasing order.

    3. The passanger’s identifier number, increasingly.

For example:


>>> D = {
... (771, 'L'): ('Vila', 1, 3, 'Amer'),
... (122, 'D'): ('Badosa', 1, 4, 'Olot'),
... (563, 'P'): ('Lopez', 2, 4, 'Olot'),
... (444, 'N'): ('Penosa', 1, 1, 'Amer'),
... (765, 'P'): ('Espigol', 1, 2, 'Amer'),
... (556, 'A'): ('Ramos', 2, 2, 'Amer'),
... }

>>> corrL = [
... (556, 'A', 'Ramos', 2, 2, 'Amer'), 
... (444, 'N', 'Penosa', 1, 1, 'Amer'), 
... (765, 'P', 'Espigol', 1, 2, 'Amer'), 
... (771, 'L', 'Vila', 1, 3, 'Amer'), 
... (563, 'P', 'Lopez', 2, 4, 'Olot'), 
... (122, 'D', 'Badosa', 1, 4, 'Olot'),
... ]

Doctests are available in the sort_pass_L_2.test file.