[pd-calculators] Canadian Copyright Calculator Algorithm and Flowchart

Jonathan Gray jonathan.gray at okfn.org
Wed Dec 10 20:03:39 UTC 2008


I thought this might be of interest to people developing calculators.
Its from consortium of people working on Canada's calculator.

Warm regards,

Jonathan

---------- Forwarded message ----------
Have a look at the calculator's algorithm and the flowchart on which
it is based.

Algorithm online at: http://demo.openlibrary.org:9021/file/
4d3fc08999ba/pharos/plugins/copyright/copyrightstatus/ca.py
Flowchart online at: http://www.creativecommons.ca/blog/wp-content/
uploads/2008/04/pdregistryca-pd_flowchart.pdf


        1 from __future__ import with_statement

        2 import time

        3

        4 OLDEST_PERSON_EVER_IN_CANADA = 117

        5 current_year = int(time.strftime('%Y'))

        6

        7 def mmax(*args):

        8   """Return maximum of args given, ignoring any None
values.  If there are

        9   no non-None values, return None.

       10   >>> print mmax()

       11   None

       12   >>> print mmax(1)

       13   1

       14   >>> print mmax(2,None,4,3)

       15   4

       16   >>> print mmax(None,None,None)

       17   None"""

       18

       19   a = list(x for x in args if x is not None)

       20   if len(a) == 0:

       21     return None

       22   return max(a)

       23

       24 def copyright_status(edition):

       25   """Determine copyright status of edition.  Return value
is a dictionary containing

       26   the date at which the edition is conservatively expected
to enter the public domain,

       27   and a list of assumptions made during the calculation."""

       28

       29   assumptions = []

       30   assume = assumptions.append

       31

       32   assume("We're assuming the current year is %d."%
current_year)

       33

       34   pubyear = edition.publish_year

       35   if pubyear is None:

       36     pubyear = current_year

       37     assume("The publication year is unspecified, so we're
assuming that the year of publication is %d."% pubyear)

       38   else:

       39     assume("We're assuming the year of publication is %
d."% pubyear)

       40

       41   if len(edition.authors) > 0:

       42     assume("We're assuming the list of authors is complete.")

       43   else:

       44     assume("We're assuming the authorship is anonymous.")

       45

       46   maxauthordeath = None

       47

       48   def y(author, attr):

       49     """Extract attribute (i.e. a string-valued date field)
from author and

       50     convert it to integer.  If field is absent or no valid
conversion, return None."""

       51     r = author.get(attr, None)

       52     try:

       53       return int(r)

       54     except (ValueError, AttributeError, TypeError):

       55       return None

       56

       57   for author in edition.authors:

       58     ydeath, ybirth = y(author, 'death_date'), y(author,
'birth_date')

       59     aname = author.name

       60

       61     if ydeath:

       62       death_year = ydeath

       63       assume("We're assuming author (%s) died in %d."%
(aname, ydeath))

       64     elif ybirth:

       65       death_year = ybirth + OLDEST_PERSON_EVER_IN_CANADA

       66       assume("We're assuming author (%s) was born in %d."%
(aname, ybirth))

       67     elif pubyear:

       68       death_year = pubyear + OLDEST_PERSON_EVER_IN_CANADA

       69       assume("We're assuming author (%s) was born at the
time of publication, since we don't have a known birthdate."% (aname,))

       70     else:

       71       death_year = None

       72

       73     if death_year is not None and ydeath is None:

       74       if death_year < current_year:

       75         assume("We're assuming author (%s) didn't live
longer than the oldest person ever in Canada, \

       76 and therefore died no later than the year %d, since we
have no known death date."% (aname, death_year))

       77       else:

       78         assume("We're assuming author (%s) will live to
age %d, the same as the oldest person ever in Canada so far." % \

       79              (aname, OLDEST_PERSON_EVER_IN_CANADA))

       80

       81     maxauthordeath = mmax(maxauthordeath, death_year)

       82

       83   if maxauthordeath:

       84     if maxauthordeath < pubyear and pubyear < 1999:

       85       pdyear = pubyear + 50

       86     else:

       87       pdyear = maxauthordeath + 50

       88   else:

       89     pdyear = pubyear + 50

       90

       91   def nominal_death(author):

       92     ydeath, ybirth = y(author, 'death_date'), y(author,
'birth_date')

       93     if ydeath is not None:

       94       return ydeath

       95     if ybirth is not None:

       96       return ybirth + OLDEST_PERSON_EVER_IN_CANADA

       97     return None

       98

       99   if any(nominal_death(author) is None for author in
edition.authors):

      100     assume("We're assuming that the authors whose death
dates are missing didn't die after those whose are available.")

      101

      102   # assume(repr({ 'date': pdyear, 'assumptions':
assumptions })) # debugging diagnostic @@

      103   return { 'date': pdyear, 'assumptions': assumptions }

      104

      105 if __name__ == '__main__':

      106   import doctest

      107   doctest.testmod()

      108

_______________________________________________
Pdregistry mailing list
Pdregistry at archive.org
http://mail.archive.org/cgi-bin/mailman/listinfo/pdregistry




More information about the pd-discuss mailing list