# In this task, we will add persistence to the ‹Shelter› class from # the previous installment (‹t1_shelter›). You should provide 2 new # functions, ‹load› and ‹store›. The basic requirement is that doing a # ‹store› → ‹load› → ‹store› sequence will produce two identical # copies of the same data. # # • Both ‹load› and ‹store› expect a ‹db› keyword argument, which # takes an open ‹sqlite3› connection. # • The ‹load› function accepts a single positional argument, an id # of the ‹Shelter› snapshot to load and returns a ‹Shelter› # instance. # • The ‹store› function takes a ‹Shelter› instance as its only # positional argument, and returns an id (which can be then # passed to ‹load›). # # Please note that storing multiple ‹Shelter› instances in a single # database must be possible. Moreover, each animal and human should # appear in the entire database only once, even if they appear in # multiple ‹Shelter› snapshots stored in that database. We consider # two people or two animals the same if all their attributes match, # with two exceptions: # # • the ‹max_capacity› of a foster parent: the same foster parent # may appear in multiple ‹Shelter› instances with a different # capacity, # • the ‹date_of_entry› of an animal, which works the same way # (the same animal still cannot re-enter the same shelter though). # # Beware! This is a departure from the semantics required in # ‹t1_shelter›, where it was possible to have multiple animals with # identical attribute sets. For this assignment, you will need to # modify ‹add_animal› to return an existing object if all attributes # match (again with the exception of ‹date_of_entry›: if all other # attributes match but not ‹date_of_entry›, raise a ‹RuntimeError›). # # Same with foster parents and ‹max_capacity›. A foster parent and an # adopter with the same name and address are, however, distinct # entities and should be allowed. In this case, the name and address # will repeat in the database (once as a foster parent and once as an # adopter). # # Finally, if ‹store› is called on a ‹Shelter› with the keyword # argument ‹deduplicate› set to ‹True›, and a snapshot with the # exact same information (i.e. the list of animals, adopters, foster # parents, fostering records and vet exams) is already present, do # not add anything to the database and return the id of the existing # snapshot. It is okay for this check to be, in the worst case, # linear in the number of snapshots already stored. # # The database schema is up to you, subject to the constraints above. # If ‹store› is called on an empty database, it should create the # necessary tables.