In its 2011 November issue, NWT Magazine published the Underground map of Science below. The challenge of this assignment consists of adding new data types to Python that allow to construct, expand and question such underground maps. An underground map is built from a number of underground lines that link different stations in a set order The traffic on an underground line goes in only one direction, and for this assignment, underground lines never form a loop. Some stations can be on multiple underground lines, so that it is possible to transfer from one line to another.

metrokaart der exacte wetenschappen
Underground map of Science

Assignment

Define a class Station with which the underground stations can be represented on a map. Every underground station possesses the properties name, year and description, that each represent a string (the year can also be described as for example: 6th century BC). From every station you can go to zero or more other metro stations, but each of these outgoing connections are on a different underground line. To represent these outgoing connections, every station possesses a property lines that refers to a dictionary. This dictionary prints the underground lines that leave from a station, by portraying each name of a line (a string; here always the name of a science) on the following line.

metrostation
Schematic representation of the objects of the class Station.

The objects of the class Station must possess at least the following methods:

Define a class UndergroundMap with which underground maps can be represented. Underground maps are built from a number of underground lines that connect various stations in a set order. Every underground map possesses a property lines, that refers to a dictionary. This dictionary portrays the name (a string; here always the name of a science) for every underground line on the map on the begin station of the underground line (an object of the class Station). The objects of the class UndergroundMap must at least contain the following methods:

Make sure you use the methods you have already implemented optimally when implementing the classes Station and UndergroundMap.

Example (class Station)

>>> station1 = Station('James Watson', '1953', 'clarification DNA-structure')
>>> station1.name
'James Watson'
>>> station1.year
'1953'
>>> station1.description
'clarification DNA-structure'
>>> station1.lines
{}
>>> station1 == station1
True
>>> station1
Station(name='James Watson', year='1953', description='clarification DNA-structure')

>>> station2 = Station(name='Ernst Mayr', year='1942', description='biological species')
>>> print(station2)
Ernst Mayr (1942, biological species)
>>> station1 == station2
False

>>> station1.link('biology', station2)
>>> station1.lines
{'biology': Station(name='Ernst Mayr', year='1942', description='biological species')}
>>> station1.next('biology')
Station(name='Ernst Mayr', jaar='1942', description='biological species')
>>> print(station1.next('chemistry'))
None

>>> station3 = Station('Marshall Warren Nirenberg', '1962', 'genetic code')
>>> station4 = Station('Ilya Prigogine', '1955', 'self-organization and non-balance')    
>>> station1.link('chemistry', station3)
>>> station1.link('chemistry', station4)
Traceback (most recent call last):
AssertionError: station is already linked with line chemistry
>>> station1.link('genomics', station4)
>>> station1.lines
{'biologie': Station(name='Ernst Mayr', yearr='1942', description='biological species'), 'genomics': Station(name='Ilya Prigogine', year='1955', description='self-organization and non-balance'), 'chemistry': Station(name='Marshall Warren Nirenberg', year='1962', description='genetic code')}
>>> print(station1.next('chemistry'))
Marshall Warren Nirenberg (1962, genetic code)
>>> print(station1.next('genomics'))
Ilya Prigogine (1955, self-organization and non-balance)

Example (class Metromap)

In the example session below we assume that the text file milestones.txt1 is situated in the current directory.

>>> metromap = Metrokaart()
>>> metromap.expand('genomics', Station('James Watson', '1953', 'clarification DNA-structure'))
>>> metromap.expand('genomics', Station('Marshall Warren Nirenberg', '1962', 'genetic code'))
>>> metromap.expand('genomics', Station(name='Frederick Sanger', year='1977', description='sequencing'))
>>> metromap.beginstation('genomics')
Station(naam='James Watson', year='1953', description='clarification DNA-structure')
>>> metromap.terminal('genomics')
Station(name='Frederick Sanger', year='1977', description='sequencing')
>>> metromap.expand('chemistry', Station('Robert Boyle', '1661', 'The Sceptical Chymist'))
>>> metromap.beginstation('chemistry')
Station(name='Robert Boyle', year='1661', description='The Sceptical Chymist')
>>> metromap.terminal('chemistry')
Station(name='Robert Boyle', year='1661', description='The Sceptical Chymist')

>>> metromap2 = Undergroundmetromap('milestones.txt')
>>> metromap2.beginstation('chemistry')
Station(name='Robert Boyle', year='1661', description='The Sceptical Chymist')
>>> metromap2.terminal('chemistry')
Station(name='Paul Crutzen', year='1985', description='atmospheric chemistry')

>>> station = metromap2.beginstation('genomics')
>>> station
Station(name='James Watson', year='1953', description='clarification DNA-structure')
>>> station.next('biology')
Station(name='Ernst Mayr', year='1942', description='biological species')
>>> print(station.next('genomics'))
Marshall Warren Nirenberg (1962, genetic code)
>>> print(station.next('chemistry'))
Ilya Prigogine (1955, self-organization and non-balance)
>>> station.next('genomics').next('genomics')
Station(name='Frederick Sanger', year='1977', description='sequencing')

>>> metromap2.expand('chemistry', Station('Martin Karplus', '2013', 'computational chemistry'))
>>> metromap2.expand('informatics', Station('Martin Karplus', '2013', 'computational chemistry'))
>>> station = metromap2.terminal('chemistry')
>>> station
Station(name='Martin Karplus', year='2013', description='computational chemistry')
>>> metromap2.expand('chemistry', Station('Michael Levitt', '2014', 'computational chemistry'))
>>> metromap2.expand('informatics', Station('Arieh Warshel', '2014', 'computational chemistry'))
>>> station.lines
{'informatics': Station(name='Arieh Warshel', year='2014', description='computational chemistry'), 'chemistry': Station(name='Michael Levitt', year='2014', description='computational chemistry')}