PROG0594 - Panini

no tags 

Panini football stickers are pure nostalgia! They are produced by the Italian-based Panini company that is specialized in the distribution of self-adhesive sticker collections. Ever since its foundation the company produces sticker collections about movies and computer games, but the football collections have always been by far the most popular ones.

Mexico 86
Panini football stickers of some of the player of the Red Devils, the Belgian football team that participated in the 1986 World Cup soccer in Mexico.

Every Panini booklet contains hundreds of empty placeholders that need to be covered by different stickers. The stickers are numbered sequentially so that their position in the booklet can be found easily. Four or five randomly selected stickers are bundled together in a sealed container. This way, you collectors do not know in advance what stickers they purchase. As a result, it becomes extremely hard to complete the entire collection, creating a collective rage whereby collectors mutually exchange their duplicate stickers.

Because collectors need to be able to quickly lookup what stickers that already have in their possession while exchanging stickers, they use a shorthand notation to describe their collection. Say, for example, that a collector has the following stickers in his possession

1, 3, 4, 5, 6, 7, 9, 10, 11, 17, 19, 20

then he will describe his collection using the following shorthand notation.

1, 3-7, 9-11, 17, 19-20

This notation abbreviates each sequence of successive integers as the first and the last integer in the sequence, separated from each other using a dash (-). Individual integers and integer sequences are listed in increasing order, separated from each other using a comma (,) and a space.

Assignment

Define a class Panini that can be used to represent collections of Panini stickers. Each sticker occurs at most once in the collection. The class must support at least the following methods:

  • An initialisation method that either takes an integer (that represents the number of a single sticker) or a list, a tuple or a set of integers (that represent the numbers of all stickers in the collection). In case the argument passed to the initialisation does not meet this condition, the method must raise an AssertionError with the message invalid stickers. The list or tuple passed to the method must not necessarily contain the integers in increasing order. In case the list or tuple passed to the method contains duplicate integers, these stickers must be included in the collection just once.
  • A method that allows to add to collections of stickers using the + operator. In doing so, the original collections must remain unchanges, with the addition resulting in a new collection (an object of the class Panini) that contains the stickers that are in either of the two intial collections. This new collection may not contain duplicate stickers.
  • A method that allows to generate a new collection that contains the stickers that are in one collection but not in another collection using the - operator. In doing so, the original collections must remain unchanges, but the subtraction should result in a new collection (an object of the class Panini) that contains all stickers from the lefthand collection that do not occur in the righthand collection.

In addition, it should also be possible to use the built-in functions repr and str to generate a string representation for each object of the class Panini. The string returned by these functions must contain the shorthand notation of the collection of stickers represented by the object. Both function thus should return the same string representation of an object.

Example

>>> collection1 = Panini([1, 3, 4, 5, 6, 7, 9, 10, 11, 17, 19, 20])
>>> collection1
1, 3-7, 9-11, 17, 19-20
>>> print(collection1)
1, 3-7, 9-11, 17, 19-20

>>> collection2 = Panini(8)
>>> collection2
8
>>> print(collection2)
8

>>> collection3 = collection1 + collection2
>>> isinstance(collection3, Panini)
True
>>> collection3
1, 3-11, 17, 19-20

>>> collection4 = collection1 - Panini((5, 8))
>>> isinstance(collection4, Panini)
True
>>> collection4
1, 3-4, 6-7, 9-11, 17, 19-20

>>> collection1 - Panini({1, 2, 3, 4}) + Panini(list(range(10, 19)))
5-7, 9-20

>>> Panini('spam')
Traceback (most recent call last):
AssertionError: invalid stickers
>>> Panini([1, 2, 3.14])
Traceback (most recent call last):
AssertionError: invalid stickers

Panini-voetbalstickers zijn pure nostalgie! Ze worden gemaakt door het Italiaanse bedrijf Panini dat gespecialiseerd is in het maken van verzamelbare stickers. Sinds haar bestaan produceert de firma stickers van onder andere films en computerspelletjes, maar de voetbalstickers zijn altijd veruit het populairst geweest.

Mexico 86
Panini-voetbalstickers van enkele spelers die deel uitmaakten van "de rode duivels", de Belgische ploeg die deelnam aan het WK voetbal van 1986 in Mexico.

Elk panini-album bevat honderden lege plaatsen waarop verschillende stickers moeten ingeplakt worden. De stickers zijn oplopend genummerd zodat hun positie in het plakboek makkelijk kan teruggevonden worden. Vier of vijf willekeurig gekozen stickers zitten samen in een gesloten verpakking. Op die manier kan men bij aankoop niet kan zien welke stickers men krijgt. Hierdoor wordt het ontzettend moeilijk om een album volledig te vullen, en ontstaat er een verzamelwoede waarbij verzamelaars hun dubbele stickers onderling met elkaar uitwisselen.

Omdat verzamelaars bij het uitwisselen van stickers snel moeten kunnen zien welke stickers ze reeds in hun bezit hebben, gebruiken ze een verkorte notatie om hun collectie te beschrijven. Stel bijvoorbeeld dat een verzamelaar de volgende stickers in zijn bezit heeft

1, 3, 4, 5, 6, 7, 9, 10, 11, 17, 19, 20

dan omschrijft hij zijn collectie met de volgende verkorte notatie.

1, 3-7, 9-11, 17, 19-20

Hierbij worden alle reeksen opeenvolgende natuurlijke getallen afgekort tot het eerste en het laatste getal van de reeks, van elkaar gescheiden door een koppelteken (-). Individuele getallen en reeksen getallen worden in oplopende volgorde opgelijst, en van elkaar gescheiden door een komma (,) en een spatie.

Opgave

Definieer een klasse Panini waarmee collecties stickers kunnen voorgesteld worden. Elke sticker komt hoogstens één keer in een collectie voor. Deze klasse moet ondersteuning bieden aan de volgende methoden:

  • Een initialisatiemethode waaraan ofwel een integer moet doorgegeven worden (die het nummer van één enkele sticker voorstelt), ofwel een lijst, een tuple of een verzameling van integers (die de nummers van alle stickers in de collectie voorstellen). Indien het argument van de initialisatiemethode niet aan deze voorwaarde voldoet, dan moet de methode een AssertionError opwerpen met de boodschap ongeldige stickers. De integers moeten niet noodzakelijk in oplopende volgorde gerangschikt zijn in de lijst of het tuple dat aan de initialisatiemethode wordt doorgegeven. Indien er in de gegeven lijst of het gegeven tuple dubbele stickers zouden voorkomen, dan moeten die maar één keer in de collectie opgenomen worden.
  • Een methode die toelaat om twee collecties stickers samen te voegen aan de hand van de + operator. Hierbij moeten de twee oorspronkelijke collecties ongewijzigd blijven, maar moet de optelling resulteren in een nieuwe collectie (een object van de klasse Panini) waarin de stickers van de oorspronkelijke collecties samengevoegd werden. Deze nieuwe collectie mag geen dubbels bevatten.
  • Een methode die toelaat om de stickers van één collectie die voorkomen in een andere collectie, uit die collectie te verwijderen aan de hand van de - operator. Hierbij moeten de twee oorspronkelijke collecties ongewijzigd blijven, maar moet de aftrekking resulteren in een nieuwe collectie (een object van de klasse Panini) die bestaat uit de stickers van de linkse collectie waaruit de stickers van de rechtse collectie verwijderd werden (als ze in de linkse collectie voorkwamen).

Bovendien moet het mogelijk zijn om met de ingebouwde functies repr en str een stringvoorstelling te genereren van elk object van de klasse Panini. De string die door deze functies wordt teruggegeven, moet de verkorte notatie bevatten van de collectie stickers die door het object worden voorgesteld. Beide functies moeten dus dezelfde stringvoorstelling van een object teruggeven.

Voorbeeld

>>> collectie1 = Panini([1, 3, 4, 5, 6, 7, 9, 10, 11, 17, 19, 20])
>>> collectie1
1, 3-7, 9-11, 17, 19-20
>>> print(collectie1)
1, 3-7, 9-11, 17, 19-20

>>> collectie2 = Panini(8)
>>> collectie2
8
>>> print(collectie2)
8

>>> collectie3 = collectie1 + collectie2
>>> isinstance(collectie3, Panini)
True
>>> collectie3
1, 3-11, 17, 19-20

>>> collectie4 = collectie1 - Panini((5, 8))
>>> isinstance(collectie4, Panini)
True
>>> collectie4
1, 3-4, 6-7, 9-11, 17, 19-20

>>> collectie1 - Panini({1, 2, 3, 4}) + Panini(list(range(10, 19)))
5-7, 9-20

>>> Panini('spam')
Traceback (most recent call last):
AssertionError: ongeldige stickers
>>> Panini([1, 2, 3.14])
Traceback (most recent call last):
AssertionError: ongeldige stickers


Added by:Peter Dawyndt
Date:2015-11-22
Time limit:10s
Source limit:50000B
Memory limit:1536MB
Cluster: Cube (Intel G860)
Languages:PY_NBC