[pd-calculators] Canadian Copyright Calculator Algorithm and Flowchart
Jon Phillips
jon at rejon.org
Fri Dec 12 06:30:34 UTC 2008
And, theres soon to be an update as well for one inconsistency:
https://bugs.launchpad.net/pdregistry.ca/+bug/183052
On Wed, 2008-12-10 at 21:03 +0100, Jonathan Gray wrote:
> 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
>
> _______________________________________________
> pd-calculators mailing list
> pd-calculators at lists.okfn.org
> http://lists.okfn.org/cgi-bin/mailman/listinfo/pd-calculators
--
Jon Phillips
San Francisco + Beijing
GLOBAL +1.415.830.3884
CHINA +86.1.360.282.8624
http://rejon.org
IM/skype: kidproto
Jabber: rejon at gristle.org
More information about the pd-discuss
mailing list