Library Catalogue: Aliasing, Keys and Cleaning
A school librarian stores the catalogue as a dictionary:
catalogue = {"CS101": "python basics", "CS102": " data structures ", "CS103": "Python Basics"} issued = ["CS101", "CS102"]
A student helper writes backup = issued, then backup.append("CS103"). Later the librarian finds that issued also contains CS103 and asks why. The helper then tries catalogue["cs101"] and gets a KeyError. The librarian also wants a clean, alphabetically sorted list of unique book titles with normal capitalisation and no extra spaces, so that the same title written in different ways is not counted twice. The helper suggests converting the titles to a set and then sorting them, but is unsure whether a set can be used directly as a dictionary key or whether a tuple would be better.
1. Explain why appending to backup changed issued. Show two correct ways to make an independent copy, and state whether a tuple would be a better choice for the issued list.
Read the worked answer
Lists are mutable, and assignment does not copy a list. backup = issued makes both names refer to the same list object, so backup.append("CS103") changes the one shared list and issued sees it too. Two correct copies are backup = issued.copy() and backup = list(issued). After either, appending to backup leaves issued unchanged. A tuple would prevent this accident entirely, because tuples are immutable: issued = ("CS101", "CS102") cannot be appended to. However, the library needs to add and remove issued books, so a list is the appropriate structure and the code should copy explicitly when a snapshot is needed. If the list later contains nested lists, a shallow copy is not enough and copy.deepcopy would be required.
2. Why does catalogue["cs101"] raise a KeyError? Explain how dictionary keys work and give two ways to make the lookup safer.
Read the worked answer
Dictionary keys are matched exactly and are case-sensitive, so "cs101" and "CS101" are different keys. The dictionary contains "CS101", not "cs101", so the lookup fails with a KeyError. Keys must also be hashable, which is why strings and tuples can be keys but lists cannot. A safer lookup is catalogue.get("cs101", "Not found"), which returns the default instead of raising an error. Alternatively, normalise the key before lookup, for example key = "cs101".strip().upper(), then use catalogue.get(key). Normalisation at the point where data is entered is even better: store every code in uppercase and strip spaces, so the dictionary has one consistent key form. This prevents duplicate entries such as CS101 and cs101 pointing to the same book.
3. Write a short plan to produce a sorted list of unique, cleaned titles from the dictionary values. Explain what each step does and why the set must be converted before sorting.
Read the worked answer
First extract the values, then clean each title with strip() to remove leading and trailing spaces and title() to standardise capitalisation. Build a set comprehension, for example cleaned = {t.strip().title() for t in catalogue.values()}. The set removes duplicates, so "python basics" and "Python Basics" become one entry once both are converted to "Python Basics". A set is unordered, so it cannot be printed in alphabetical order directly. Convert it to a list and sort: result = sorted(cleaned). The sorted() function returns a new list in alphabetical order. The final output is a list of unique titles with consistent spelling and spacing. If the original capitalisation matters for display, keep a separate display dictionary rather than relying on the set.