pax_global_header00006660000000000000000000000064117751412330014516gustar00rootroot0000000000000052 comment=036bec11ac63771ec5dab6a22f3175853a5b2bfe Geneagrapher-master/000077500000000000000000000000001177514123300147435ustar00rootroot00000000000000Geneagrapher-master/.gitignore000066400000000000000000000000571177514123300167350ustar00rootroot00000000000000*.pyc .cache Geneagrapher.egg-info dist build Geneagrapher-master/COPYING000066400000000000000000000020611177514123300157750ustar00rootroot00000000000000Copyright (c) 2008, 2009, 2010, 2011 David Alber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Geneagrapher-master/HACKING.txt000066400000000000000000000010021177514123300165410ustar00rootroot00000000000000Development setup ================= To create a buildout, $ python bootstrap.py $ bin/buildout Release HOWTO ============= To make a release, 1) Update release date/version in NEWS.txt and setup.py 2) Run 'python setup.py sdist'. Alternatively, run 'python makedist.py', which creates the distributions, hashes, and signatures. 3) Test the generated source distribution in dist/ 4) Upload to PyPI: 'python setup.py sdist register upload' 5) Increase version in setup.py (for next release) Geneagrapher-master/MANIFEST.in000066400000000000000000000000441177514123300164770ustar00rootroot00000000000000include README.rst include NEWS.txt Geneagrapher-master/NEWS.txt000066400000000000000000000070471177514123300162700ustar00rootroot00000000000000News ==== 1.0 --- *Release date: unreleased* *Redesigned data-grabbing interface to allow for the introduction of new data grabbers. *Added a new data grabber that builds a local cache of records. This allows subsequent geneagrapher calls to obtain cached records and avoiding a request over the network. *Added local test data, allowing for many tests that were previously making network requests to simply load local data. This speeds up running the test suite substantially. *Substantial refactoring and internal changes, including: -Better code coverage by the tests. -Updated packaging to more modern standards. -Improved test documentation and naming. -Internal graph structure now only stores the genealogy graph. Previously, the graph structure retained all edges from the Math Genealogy Project information. -Data is now extracted from Math Genealogy Project web pages using BeautifulSoup (http://www.crummy.com/software/BeautifulSoup/). This means that the Geneagrapher now has an external dependency, but I believe the advantages for testing and code readability, for this case, outweigh the disadvantage of taking a dependency. 0.2.1-r2 -------- *Release date: 11-Aug-2011* *A test in Geneagrapher 0.2.1-r1 was broken by new information added to the Mathematics Genealogy Project. This release fixes the test, but does not change the functionality from version 0.2.1-r1. 0.2.1-r1 -------- *Release date: 03-Nov-2010* *A few tests in Geneagrapher 0.2.1 have become broken since that version was released. This release fixes those tests, but does not change the functionality from version 0.2.1. 0.2.1 ----- *Release date: 01-Sep-2009* Changes made for this release: *Multiple advisors are now captured correctly. While this problem was manifesting itself, ancestor trees were coming out as a branch-free tree. *Added a test for the multiple advisor case, which enables quicker recognition of similar problems. *Updated a few tests that had become broken due to updates in the Math Genealogy Project’s database. 0.2-r1 ------ *Release date: 07-Oct-2008* *This Geneagrapher release slightly changes an installation-related file to enable installation on machines running Python 2.6 that have not yet installed Python setuptools. 0.2 --- *Release date: 06-Oct-2008* Here are the most significant changes, from the perspective of the user: *Descendant trees. Now trees can be built placing a starting node at the top and graphing all of its descendants. A couple points on this: -These sorts of graphs tend to have a lot of “fan out” because some people have a lot of students. -Be careful. Do not inadvertently (or intentionally!) run a job that requests the data for thousands of nodes. *Better character handling. I believe all characters are now displayed correctly, as long as the generated dot file is processed by Graphviz a certain way (see the Geneagrapher 0.2 Usage Guide). *No limit on the number of starting nodes. *This is a client application, meaning the user installs it somewhere and runs it there. Furthermore, this package only generates the input file to Graphviz, so that also needs to be installed. This is probably more of a hassle than most Geneagrapher users want to go through (not all, though), but this is just the first step. Additionally, behind-the-scenes changes happened: *Large portions of the code were rewritten. *Added a test suite to make it more maintainable. In particular, this should allow quicker diagnosis and modifications when the Mathematics Genealogy Project pages have changed. Geneagrapher-master/README.rst000066400000000000000000000007001177514123300164270ustar00rootroot00000000000000Geneagrapher is a tool for extracting information from the Mathematics Geanealogy Project (http://genealogy.math.ndsu.nodak.edu/) to form a geneagraphy. The output is a dot file, which can be used by Graphviz (http://graphviz.org/) to visualize the tree. For current usage information see: http://www.davidalber.net/2008/10/geneagrapher-02-usage-guide/. For more information on Geneagrapher releases see: http://www.davidalber.net/geneagrapher/. Geneagrapher-master/bootstrap.py000066400000000000000000000066731177514123300173460ustar00rootroot00000000000000############################################################################## # # Copyright (c) 2006 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Bootstrap a buildout-based project Simply run this script in a directory containing a buildout.cfg. The script accepts buildout command-line options, so you can use the -c option to specify an alternate configuration file. $Id: bootstrap.py 102545 2009-08-06 14:49:47Z chrisw $ """ import os, shutil, sys, tempfile, urllib2 from optparse import OptionParser tmpeggs = tempfile.mkdtemp() is_jython = sys.platform.startswith('java') # parsing arguments parser = OptionParser() parser.add_option("-v", "--version", dest="version", help="use a specific zc.buildout version") parser.add_option("-d", "--distribute", action="store_true", dest="distribute", default=True, help="Use Disribute rather than Setuptools.") options, args = parser.parse_args() if options.version is not None: VERSION = '==%s' % options.version else: VERSION = '' USE_DISTRIBUTE = options.distribute args = args + ['bootstrap'] to_reload = False try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): to_reload = True raise ImportError except ImportError: ez = {} if USE_DISTRIBUTE: exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) else: exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) if to_reload: reload(pkg_resources) else: import pkg_resources if sys.platform == 'win32': def quote(c): if ' ' in c: return '"%s"' % c # work around spawn lamosity on windows else: return c else: def quote (c): return c cmd = 'from setuptools.command.easy_install import main; main()' ws = pkg_resources.working_set if USE_DISTRIBUTE: requirement = 'distribute' else: requirement = 'setuptools' if is_jython: import subprocess assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', quote(tmpeggs), 'zc.buildout' + VERSION], env=dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse(requirement)).location ), ).wait() == 0 else: assert os.spawnle( os.P_WAIT, sys.executable, quote (sys.executable), '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION, dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse(requirement)).location ), ) == 0 ws.add_entry(tmpeggs) ws.require('zc.buildout' + VERSION) import zc.buildout.buildout zc.buildout.buildout.main(args) shutil.rmtree(tmpeggs) Geneagrapher-master/buildout.cfg000066400000000000000000000003221177514123300172500ustar00rootroot00000000000000[buildout] parts = python scripts develop = . eggs = geneagrapher [python] recipe = zc.recipe.egg interpreter = python eggs = ${buildout:eggs} [scripts] recipe = zc.recipe.egg:scripts eggs = ${buildout:eggs} Geneagrapher-master/distribute_setup.py000066400000000000000000000366151177514123300207260ustar00rootroot00000000000000#!python """Bootstrap distribute installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from distribute_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os import sys import time import fnmatch import tempfile import tarfile from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None try: import subprocess def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 except ImportError: # will be used for python 2.3 def _python_cmd(*args): args = (sys.executable,) + args # quoting arguments if windows if sys.platform == 'win32': def quote(arg): if ' ' in arg: return '"%s"' % arg return arg args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 DEFAULT_VERSION = "0.6.24" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" SETUPTOOLS_PKG_INFO = """\ Metadata-Version: 1.0 Name: setuptools Version: %s Summary: xxxx Home-page: xxx Author: xxx Author-email: xxx License: xxx Description: xxx """ % SETUPTOOLS_FAKED_VERSION def _install(tarball): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # installing log.warn('Installing Distribute') if not _python_cmd('setup.py', 'install'): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') finally: os.chdir(old_wd) def _build_egg(egg, tarball, to_dir): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # building an egg log.warn('Building a Distribute egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): tarball = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, tarball, to_dir) sys.path.insert(0, egg) import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15, no_fake=True): # making sure we use the absolute path to_dir = os.path.abspath(to_dir) was_imported = 'pkg_resources' in sys.modules or \ 'setuptools' in sys.modules try: try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): if not no_fake: _fake_setuptools() raise ImportError except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("distribute>="+version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of distribute (>=%s) is not available,\n" "and can't be installed while this script is running. Please\n" "install a more recent version first, using\n" "'easy_install -U distribute'." "\n\n(Currently using %r)\n" % (version, e.args[0])) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return _do_download(version, download_base, to_dir, download_delay) except pkg_resources.DistributionNotFound: return _do_download(version, download_base, to_dir, download_delay) finally: if not no_fake: _create_fake_setuptools_pkg_info(to_dir) def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename `version` should be a valid distribute version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen tgz_name = "distribute-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: log.warn("Downloading %s", url) src = urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = src.read() dst = open(saveto, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def _no_sandbox(function): def __no_sandbox(*args, **kw): try: from setuptools.sandbox import DirectorySandbox if not hasattr(DirectorySandbox, '_old'): def violation(*args): pass DirectorySandbox._old = DirectorySandbox._violation DirectorySandbox._violation = violation patched = True else: patched = False except ImportError: patched = False try: return function(*args, **kw) finally: if patched: DirectorySandbox._violation = DirectorySandbox._old del DirectorySandbox._old return __no_sandbox def _patch_file(path, content): """Will backup the file then patch it""" existing_content = open(path).read() if existing_content == content: # already patched log.warn('Already patched.') return False log.warn('Patching...') _rename_path(path) f = open(path, 'w') try: f.write(content) finally: f.close() return True _patch_file = _no_sandbox(_patch_file) def _same_content(path, content): return open(path).read() == content def _rename_path(path): new_name = path + '.OLD.%s' % time.time() log.warn('Renaming %s into %s', path, new_name) os.rename(path, new_name) return new_name def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) return False found = False for file in os.listdir(placeholder): if fnmatch.fnmatch(file, 'setuptools*.egg-info'): found = True break if not found: log.warn('Could not locate setuptools*.egg-info') return log.warn('Removing elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) else: patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) if not patched: log.warn('%s already patched.', pkg_info) return False # now let's move the files out of the way for element in ('setuptools', 'pkg_resources.py', 'site.py'): element = os.path.join(placeholder, element) if os.path.exists(element): _rename_path(element) else: log.warn('Could not find the %s element of the ' 'Setuptools distribution', element) return True _remove_flat_installation = _no_sandbox(_remove_flat_installation) def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') return pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) setuptools_file = 'setuptools-%s-py%s.egg-info' % \ (SETUPTOOLS_FAKED_VERSION, pyver) pkg_info = os.path.join(placeholder, setuptools_file) if os.path.exists(pkg_info): log.warn('%s already exists', pkg_info) return log.warn('Creating %s', pkg_info) f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() pth_file = os.path.join(placeholder, 'setuptools.pth') log.warn('Creating %s', pth_file) f = open(pth_file, 'w') try: f.write(os.path.join(os.curdir, setuptools_file)) finally: f.close() _create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info) def _patch_egg_dir(path): # let's check if it's already patched pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') if os.path.exists(pkg_info): if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): log.warn('%s already patched.', pkg_info) return False _rename_path(path) os.mkdir(path) os.mkdir(os.path.join(path, 'EGG-INFO')) pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() return True _patch_egg_dir = _no_sandbox(_patch_egg_dir) def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() def _under_prefix(location): if 'install' not in sys.argv: return True args = sys.argv[sys.argv.index('install')+1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): top_dir = arg.split('root=')[-1] return location.startswith(top_dir) elif arg == option: if len(args) > index: top_dir = args[index+1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) return True def _fake_setuptools(): log.warn('Scanning installed packages') try: import pkg_resources except ImportError: # we're cool log.warn('Setuptools or Distribute does not seem to be installed.') return ws = pkg_resources.working_set try: setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools', replacement=False)) except TypeError: # old distribute API setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools')) if setuptools_dist is None: log.warn('No setuptools distribution found') return # detecting if it was already faked setuptools_location = setuptools_dist.location log.warn('Setuptools installation detected at %s', setuptools_location) # if --root or --preix was provided, and if # setuptools is not located in them, we don't patch it if not _under_prefix(setuptools_location): log.warn('Not patching, --root or --prefix is installing Distribute' ' in another location') return # let's see if its an egg if not setuptools_location.endswith('.egg'): log.warn('Non-egg installation') res = _remove_flat_installation(setuptools_location) if not res: return else: log.warn('Egg installation') pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') if (os.path.exists(pkg_info) and _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): log.warn('Already patched.') return log.warn('Patching...') # let's create a fake egg replacing setuptools one res = _patch_egg_dir(setuptools_location) if not res: return log.warn('Patched done.') _relaunch() def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) def _extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ import copy import operator from tarfile import ExtractError directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. if sys.version_info < (2, 4): def sorter(dir1, dir2): return cmp(dir1.name, dir2.name) directories.sort(sorter) directories.reverse() else: directories.sort(key=operator.attrgetter('name'), reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError: e = sys.exc_info()[1] if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" tarball = download_setuptools() _install(tarball) if __name__ == '__main__': main(sys.argv[1:]) Geneagrapher-master/makedist.py000066400000000000000000000007631177514123300171240ustar00rootroot00000000000000"""This tool sets up a distribution of the software by automating several tasks that need to be done.""" import os if __name__ == '__main__': # Make the distribution. os.system('python setup.py sdist --format gztar,zip') # Compute digests and signatures. os.chdir('dist') dirl = os.listdir('.') for file in dirl: comm = 'sha1sum %s > %s.sha1' % (file, file) os.system(comm) comm = 'gpg -abs %s' % (file) os.system(comm) os.chdir('..') Geneagrapher-master/setup.py000066400000000000000000000020551177514123300164570ustar00rootroot00000000000000from distribute_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages import sys, os here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.rst')).read() NEWS = open(os.path.join(here, 'NEWS.txt')).read() version = '1.0c2' install_requires = [ 'BeautifulSoup >= 3.2.0' ] setup(name='geneagrapher', version=version, description="Generates mathematic genealogy graph files.", long_description=README + '\n\n' + NEWS, classifiers=[ # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers ], keywords='', author='David Alber', author_email='alber.david@gmail.com', url='http://www.davidalber.net/geneagrapher', license='MIT', packages=find_packages('src'), package_dir = {'': 'src'},include_package_data=True, zip_safe=False, install_requires=install_requires, entry_points={ 'console_scripts': ['ggrapher=geneagrapher.geneagrapher:ggrapher'] }, test_suite='tests.geneagrapher' ) Geneagrapher-master/src/000077500000000000000000000000001177514123300155325ustar00rootroot00000000000000Geneagrapher-master/src/geneagrapher/000077500000000000000000000000001177514123300201625ustar00rootroot00000000000000Geneagrapher-master/src/geneagrapher/__init__.py000066400000000000000000000000001177514123300222610ustar00rootroot00000000000000Geneagrapher-master/src/geneagrapher/cache_grabber.py000066400000000000000000000034201177514123300232620ustar00rootroot00000000000000import shelve from time import time from grabber import Grabber class CacheGrabber(): def __init__(self, filename='geneacache', record_grabber=Grabber, expiration_interval=604800.): self.filename = filename self.grabber = record_grabber() self.expiration_interval = float(expiration_interval) self.cache = shelve.open(filename) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.close() def close(self): """Close the cache. All methods after calling this will raise ValueError.""" self.cache.close() def is_expired(self, record): """Returns True if the given record is expired.""" return time() - record['timestamp'] > self.expiration_interval def get_record(self, id): """Return information for the mathematician associated with the given id.""" id_str = str(id) if self.is_cached(id_str): record = self.cache[id_str] record['message'] = 'cache hit' else: record = self.grabber.get_record(id) self.load_into_cache(id, record) record['message'] = 'cache miss' del(record['timestamp']) return record def is_cached(self, id): """Return True if an item with the given id is in the cache and has not expired.""" return str(id) in self.cache and \ not self.is_expired(self.cache[str(id)]) def load_into_cache(self, id, record): """Insert a new record into the cache. If the record already exists, its values are replaced with the values provided as input to this method.""" record['timestamp'] = time() self.cache[str(id)] = record Geneagrapher-master/src/geneagrapher/geneagrapher.py000066400000000000000000000146161177514123300231740ustar00rootroot00000000000000from argparse import ArgumentParser from collections import deque import pkg_resources import sys from cache_grabber import CacheGrabber from graph import Graph from grabber import Grabber class Geneagrapher: """ A class for building Graphviz "dot" files for math genealogies extracted from the Mathematics Genealogy Project website. """ def __init__(self): self.graph = Graph() self.seed_ids = [] self.get_ancestors = False self.get_descendants = False self.verbose = False self.write_filename = None self.use_cache = True self.cache_file = 'geneacache' def parse_input(self): """ Parse command-line information. """ pkg_env = pkg_resources.Environment() description = 'Create a Graphviz "dot" file for a mathematics \ genealogy, where ID is a record identifier from the Mathematics Genealogy \ Project. Multiple IDs may be passed.' self.parser = ArgumentParser(description=description) version = "{}".format(pkg_env[self.__module__.split('.')[0]][0]. version) self.parser.add_argument('--version', action='version', version='%(prog)s {0}'.format(version)) self.parser.add_argument("-f", "--file", dest="filename", help="write output to FILE [default: stdout]", metavar="FILE", default=None) self.parser.add_argument("-a", "--with-ancestors", action="store_true", dest="get_ancestors", default=False, help="retrieve ancestors of IDs and include \ in graph") self.parser.add_argument("-d", "--with-descendants", action="store_true", dest="get_descendants", default=False, help="retrieve descendants of IDs and \ include in graph") self.parser.add_argument('--disable-cache', action='store_false', dest='use_cache', default=True, help='do not store records in local cache') self.parser.add_argument('--cache-file', dest='cache_file', help='write cache to FILE [default: \ geneacache]', metavar='FILE', default='geneacache') self.parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", default=False, help="list nodes being retrieved") self.parser.add_argument('ids', metavar='ID', type=int, nargs='+', help='mathematician record ID') args = self.parser.parse_args() self.get_ancestors = args.get_ancestors self.get_descendants = args.get_descendants self.verbose = args.verbose self.write_filename = args.filename self.use_cache = args.use_cache self.cache_file = args.cache_file self.seed_ids = [int(arg) for arg in args.ids] def build_graph_portion(self, grab_queue, is_seed, grabber, **kwargs): """Handle grabbing and storing nodes in the graph. Depending on the arguments, this method handles seed nodes, ancestors, or descendants.""" while len(grab_queue) != 0: id = grab_queue.popleft() if not self.graph.has_node(id): # Then this information has not yet been grabbed. if self.verbose: sys.stdout.write('Grabbing record #{}...'.format(id)) record = grabber.get_record(id) if self.verbose: if 'message' in record: print record['message'] else: print self.graph.add_node(record['name'], record['institution'], record['year'], id, record['advisors'], record['descendants'], is_seed) if self.get_ancestors and 'ancestor_queue' in kwargs: kwargs['ancestor_queue'].extend(record['advisors']) if self.get_descendants and 'descendant_queue' in kwargs: kwargs['descendant_queue'].extend(record['descendants']) def build_graph_complete(self, record_grabber=Grabber, **kwargs): """ Populate the graph member by grabbing the mathematician pages and extracting relevant data. """ seed_queue = deque(self.seed_ids) ancestor_queue = deque() descendant_queue = deque() with record_grabber(**kwargs) as grabber: # Grab "seed" nodes. self.build_graph_portion(seed_queue, True, grabber, ancestor_queue=ancestor_queue, descendant_queue=descendant_queue) # Grab ancestors of seed nodes. if self.get_ancestors: self.build_graph_portion(ancestor_queue, False, grabber, ancestor_queue=ancestor_queue) # Grab descendants of seed nodes. if self.get_descendants: self.build_graph_portion(descendant_queue, False, grabber, descendant_queue=descendant_queue) def build_graph(self): """Call the graph builder method with the correct arguments, based on the command-line arguments.""" if self.use_cache: record_grabber = CacheGrabber else: record_grabber = Grabber self.build_graph_complete(record_grabber, filename=self.cache_file) def generate_dot_file(self): dotfile = self.graph.generate_dot_file(self.get_ancestors, self.get_descendants) dotfile = dotfile.encode('utf-8', 'replace') if self.write_filename is not None: outfile = open(self.write_filename, "w") outfile.write(dotfile) outfile.close() else: print dotfile, def ggrapher(): """Function to run the Geneagrapher. This is the function called when the ggrapher script is run.""" ggrapher = Geneagrapher() ggrapher.parse_input() try: ggrapher.build_graph() except ValueError, e: print e ggrapher.generate_dot_file() Geneagrapher-master/src/geneagrapher/grabber.py000066400000000000000000000062261177514123300221460ustar00rootroot00000000000000import urllib import re from BeautifulSoup import BeautifulSoup class Grabber: """ Class for grabbing and parsing mathematician information from Math Genealogy Database. """ def __init__(self, **kwargs): pass def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): pass def get_record(self, id): """ For the mathematician in this object, extract the list of advisor ids, the mathematician name, the mathematician institution, and the year of the mathematician's degree. """ url = 'http://genealogy.math.ndsu.nodak.edu/id.php?id=' + str(id) page = urllib.urlopen(url) soup = BeautifulSoup(page, convertEntities='html') page.close() return get_record_from_tree(soup, id) def get_record_from_tree(soup, id): """Extract and return the fields in the mathematician record using the input tree.""" if not has_record(soup): # Then a bad record id was given. Raise an exception. msg = "Invalid id {}".format(id) raise ValueError(msg) record = {} record['name'] = get_name(soup) record['institution'] = get_institution(soup) record['year'] = get_year(soup) record['advisors'] = get_advisors(soup) record['descendants'] = get_descendants(soup) return record def has_record(soup): """Return True if the input tree contains a mathematician record and False otherwise.""" if str(soup) == "Non-numeric id supplied. Aborting.": # This is received, for instance, by going to # http://genealogy.math.ndsu.nodak.edu/id.php?id=999999999999999999999. return False return not soup.firstText().text == u"You have specified an ID that does \ not exist in the database. Please back up and try again." def get_name(soup): """Extract the name from the given tree.""" return soup.find('h2').getText() def get_institution(soup): """Return institution name (or None, if there is no institution name).""" institution = soup.find('div', style="line-height: 30px; \ text-align: center; margin-bottom: 1ex").find('span').find('span').text if institution == u'': institution = None return institution def get_year(soup): """Return graduation year (or None, if there is no graduation year).""" inst_year = soup.find('div', style="line-height: 30px; text-align: \ center; margin-bottom: 1ex").find('span').contents[-1].strip() if inst_year.isdigit(): return int(inst_year) else: return None def get_advisors(soup): """Return the set of advisors.""" return set([extract_id(info.findNext()) for info in soup.findAll(text=re.compile('Advisor')) if 'Advisor: Unknown' not in info]) def get_descendants(soup): """Return the set of descendants.""" if soup.find('table') is not None: return set([extract_id(info) for info in soup.find('table').findAll('a')]) else: return set([]) def extract_id(tag): """Extract the ID from a tag with form .""" return int(tag.attrs[0][-1].split('=')[-1]) Geneagrapher-master/src/geneagrapher/graph/000077500000000000000000000000001177514123300212635ustar00rootroot00000000000000Geneagrapher-master/src/geneagrapher/graph/__init__.py000066400000000000000000000001341177514123300233720ustar00rootroot00000000000000from graph import DuplicateNodeError, Graph from node import Node from record import Record Geneagrapher-master/src/geneagrapher/graph/graph.py000066400000000000000000000133721177514123300227440ustar00rootroot00000000000000from node import Node from record import Record class DuplicateNodeError(Exception): def __init__(self, value): self.value = value def __str__(self): return self.value class Graph(dict): """ Class storing the representation of a genealogy graph. """ def __init__(self, seed_nodes=None): """ Graph class constructor. Parameters: seed_nodes: a set of Node objects representing the tree seed nodes (omit to create an empty graph) """ dict.__init__(self) # Verify type of seed_nodes is what we expect. if seed_nodes is not None: if not isinstance(seed_nodes, set): raise TypeError("Unexpected argument type: expected set of \ Node objects for 'seed_nodes'") for seed in seed_nodes: if not isinstance(seed, Node): raise TypeError("Unexpected parameter type: expected set \ of Node objects for 'seed_nodes'") if seed_nodes is None: self.seeds = set() else: self.seeds = set([seed.get_id() for seed in seed_nodes]) self.update([(seed.get_id(), seed) for seed in seed_nodes]) self.supp_id = -1 def has_node(self, id): """ Check if the graph contains a node with the given id. """ return id in self def get_node(self, id): """ Return the node in the graph with given id. Returns None if no such node exists. """ return self[id] def get_node_list(self): # NOTE: this method is unused """ Return a list of the nodes in the graph. """ return self.keys() def add_node(self, name, institution, year, id, advisors, advisees, is_seed=False): """ Add a new node to the graph if a matching node is not already present. """ record = Record(name, institution, year, id) # Ancestors is the set of advisors already in the graph. graph_ancestors = set([advisor for advisor in advisors if advisor in self]) # For each ancestor, add this node's id to the ancestor's descendant # set. for ancestor in graph_ancestors: self[ancestor].descendants.add(id) # Descendants is the set of advisees already in the graph. graph_descendants = set([descendant for descendant in advisees if descendant in self]) # For each descendant, add this node's id to the descendant's # ancestor set. for descendant in graph_descendants: self[descendant].ancestors.add(id) node = Node(record, graph_ancestors, graph_descendants) self.add_node_object(node, is_seed) def add_node_object(self, node, is_seed=False): """ Add a new node object to the graph if a node with the same id is not already present. """ if node.get_id() is not None and self.has_node(node.get_id()): msg = "node with id {} already exists".format(node.get_id()) raise DuplicateNodeError(msg) if node.get_id() is None: # Assign a "dummy" id. node.set_id(self.supp_id) self.supp_id -= 1 self[node.get_id()] = node if self.seeds == set() or is_seed: self.seeds.add(node.get_id()) def generate_dot_file(self, include_ancestors, include_descendants): """ Return a string that contains the content of the Graphviz dotfile format for this graph. """ if self.seeds == set(): return "" queue = [] for seed in self.seeds: queue.append(seed) edges = "" dotfile = "" dotfile += u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold];\n\n""" printed_nodes = {} while len(queue) > 0: node_id = queue.pop(0) if not self.has_node(node_id): # Skip this id if a corresponding node is not present. continue if node_id in printed_nodes: # Skip this id because it is already printed. continue node = self.get_node(node_id) printed_nodes[node_id] = node sorted_ancestors = sorted([a for a in node.ancestors if a in self], lambda x, y: cmp(self[x].record.name.split()[-1], self[y].record.name.split()[-1])) sorted_descendants = sorted([d for d in node.descendants if d in self], lambda x, y: cmp(self[x].record.name.split()[-1], self[y].record.name.split()[-1])) if include_ancestors: # Add this node's advisors to queue. queue += sorted_ancestors if include_descendants: # Add this node's descendants to queue. queue += sorted_descendants # Print this node's information. nodestr = u" {} [label=\"{}\"];".format(node_id, node) dotfile += nodestr # Store the connection information for this node. for advisor in sorted_ancestors: if self.has_node(advisor): edgestr = "\n {} -> {};".format(advisor, node_id) edges += edgestr dotfile += "\n" # Now print the connections between the nodes. dotfile += edges dotfile += "\n}\n" return dotfile Geneagrapher-master/src/geneagrapher/graph/node.py000066400000000000000000000035031177514123300225630ustar00rootroot00000000000000from record import Record class Node: """ Container class storing a node in the graph. """ def __init__(self, record, ancestors, descendants): """ Node class constructor. Parameters: record: instance of the Record class ancestors: list of the record's genealogical ancestors' IDs descendants: list of this record's genealogical descendants' IDs """ self.record = record self.ancestors = ancestors self.descendants = descendants # Verify parameter types. if not isinstance(self.record, Record): raise TypeError("Unexpected parameter type: expected Record \ object for 'record'") if not isinstance(self.ancestors, set): raise TypeError("Unexpected parameter type: expected set object \ for 'ancestors'") if not isinstance(self.descendants, set): raise TypeError("Unexpected parameter type: expected set object \ for 'descendants'") def __unicode__(self): return self.record.__unicode__() def __cmp__(self, n2): return self.record.__cmp__(n2.record) def __hash__(self): return hash(self.get_id()) def add_ancestor(self, ancestor): # NOTE: is this used? """ Add an ancestor id to the ancestor set. """ # Verify we were passed an int. if not isinstance(ancestor, int): raise TypeError("Unexpected parameter type: expected int for \ 'ancestor'") self.ancestors.add(ancestor) def get_id(self): """ Accessor method to retrieve the id of this node's record. """ return self.record.id def set_id(self, id): # NOTE: is this used? """ Sets the record id. """ self.record.id = id Geneagrapher-master/src/geneagrapher/graph/record.py000066400000000000000000000044621177514123300231210ustar00rootroot00000000000000class Record: """ Container class storing record of a mathematician in the graph. """ def __init__(self, name, institution=None, year=None, id=None): """ Record class constructor. Parameters: name: string containing mathematician's name institution: string containing mathematician's institution (empty if none) year: integer containing year degree was earned id: integer containing Math Genealogy Project id value """ self.name = name self.institution = institution self.year = year self.id = id # Verify we got the types wanted. if not isinstance(self.name, basestring): raise TypeError("Unexpected parameter type: expected string value \ for 'name'") if not isinstance(self.institution, basestring) and self.institution \ is not None: raise TypeError("Unexpected parameter type: expected string value \ for 'institution'") if not isinstance(self.year, int) and self.year is not None: raise TypeError("Unexpected parameter type: expected integer \ value for 'year'") if not isinstance(self.id, int) and self.id is not None: raise TypeError("Unexpected parameter type: expected integer \ value for 'id'") def __cmp__(self, r2): """ Compare a pair of mathematician records based on ids. """ return self.id.__cmp__(r2.id) def __unicode__(self): if self.has_institution(): if self.has_year(): return u'{} \\n{} ({})'.format(self.name, self.institution, self.year) else: return u'{} \\n{}'.format(self.name, self.institution) else: if self.has_year(): return u'{} \\n({})'.format(self.name, self.year) else: return self.name def has_institution(self): """ Return True if this record has an institution associated with it, else False. """ return self.institution is not None def has_year(self): """ Return True if this record has a year associated with it, else False. """ return self.year is not None Geneagrapher-master/tests/000077500000000000000000000000001177514123300161055ustar00rootroot00000000000000Geneagrapher-master/tests/__init__.py000066400000000000000000000000001177514123300202040ustar00rootroot00000000000000Geneagrapher-master/tests/geneagrapher/000077500000000000000000000000001177514123300205355ustar00rootroot00000000000000Geneagrapher-master/tests/geneagrapher/__init__.py000066400000000000000000000000001177514123300226340ustar00rootroot00000000000000Geneagrapher-master/tests/geneagrapher/local_data_grabber.py000066400000000000000000000017721177514123300246650ustar00rootroot00000000000000import os import sys from BeautifulSoup import BeautifulSoup from geneagrapher.grabber import get_record_from_tree class LocalDataGrabber: """A class for grabbing locally-cached test data.""" def __init__(self): pass def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): pass @classmethod def data_file(cls, filename): """Return the absolute path to the data file with given name.""" return os.path.join(cls.data_path, filename) def get_record(self, id): """Load the local data for the given id and use Grabber's functionas to extract the record data.""" with open(self.data_file('{0}.html'.format(id)), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') return get_record_from_tree(soup, id) file_path = os.path.abspath(__file__) LocalDataGrabber.data_path = os.path.join(os.path.dirname(file_path), 'testdata') Geneagrapher-master/tests/geneagrapher/test_cache_grabber.py000066400000000000000000000244141177514123300247020ustar00rootroot00000000000000import os from time import time import unittest from local_data_grabber import LocalDataGrabber from geneagrapher.cache_grabber import CacheGrabber from geneagrapher.grabber import Grabber class TestCacheGrabberMethods(unittest.TestCase): """Unit tests for the geneagrapher.CacheGrabber class.""" def setUp(self): self.name = u"Carl Friedrich Gau\xdf" self.institution = u"Universit\xe4t Helmstedt" self.year = 1799 self.advisors = set([18230]) self.descendants = set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876]) def tearDown(self): try: os.remove('geneacache') except OSError: pass def test_init1(self): """Test constructor.""" cache = CacheGrabber() self.assertEqual(cache.filename, 'geneacache') self.assertEqual(len(cache.cache), 0) self.assertIsInstance(cache.grabber, Grabber) self.assertEqual(cache.expiration_interval, 604800.) def test_init2(self): """Test constructor with non-default filename.""" cache = CacheGrabber('mycachename') self.assertEqual(cache.filename, 'mycachename') self.assertEqual(len(cache.cache), 0) self.assertIsInstance(cache.grabber, Grabber) self.assertEqual(cache.expiration_interval, 604800.) os.remove('mycachename') def test_init3(self): """Test constructor with non-default record grabber.""" cache = CacheGrabber(record_grabber=LocalDataGrabber) self.assertEqual(cache.filename, 'geneacache') self.assertEqual(len(cache.cache), 0) self.assertIsInstance(cache.grabber, LocalDataGrabber) self.assertEqual(cache.expiration_interval, 604800.) def test_init4(self): """Test constructor with non-default expiration interval.""" cache = CacheGrabber(expiration_interval=1209600.) self.assertEqual(cache.filename, 'geneacache') self.assertEqual(len(cache.cache), 0) self.assertIsInstance(cache.grabber, Grabber) self.assertEqual(cache.expiration_interval, 1209600.) def test_close(self): """Test the close method.""" cache = CacheGrabber(record_grabber=LocalDataGrabber) self.assertEqual(len(cache.cache), 0) cache.close() self.assertRaisesRegexp(ValueError, 'invalid operation on closed shelf', len, cache.cache) def test_is_expired_false(self): """Test the is_expired method.""" t = time() d = {'name': self.name, 'institution': self.institution, 'year': self.year, 'advisors': self.advisors, 'descendants': self.descendants, 'timestamp': t} with CacheGrabber() as cache: self.assertFalse(cache.is_expired(d)) d['timestamp'] = time() - cache.expiration_interval + 20 self.assertFalse(cache.is_expired(d)) def test_is_expired_true(self): """Test the is_expired method.""" with CacheGrabber() as cache: t = time() - cache.expiration_interval - 1 d = {'name': self.name, 'institution': self.institution, 'year': self.year, 'advisors': self.advisors, 'descendants': self.descendants, 'timestamp': t} self.assertTrue(cache.is_expired(d)) def test_context_manager(self): """Test the context manager methods.""" with CacheGrabber(record_grabber=LocalDataGrabber) as cache: self.assertEqual(len(cache.cache), 0) self.assertRaisesRegexp(ValueError, 'invalid operation on closed shelf', len, cache.cache) def test_get_record_bad(self): """Test the get_record method for a bad id.""" with CacheGrabber(record_grabber=LocalDataGrabber) as cache: self.assertEqual(len(cache.cache), 0) self.assertRaisesRegexp(ValueError, 'Invalid id 999999999', cache.get_record, 999999999) self.assertEqual(len(cache.cache), 0) def test_get_record(self): """Test the get_record method for a good id.""" with CacheGrabber(record_grabber=LocalDataGrabber) as cache: record = cache.get_record(18231) self.assertEqual(len(record), 6) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Universit\xe4t Helmstedt") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) self.assertEqual(record['message'], u"cache miss") self.assertEqual(len(cache.cache), 1) # Make the request again and verify the cached version is returned. d = cache.cache['18231'] d['institution'] = u'Rigged for test' cache.cache['18231'] = d record = cache.get_record(18231) self.assertEqual(len(record), 6) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Rigged for test") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) self.assertEqual(record['message'], u"cache hit") self.assertEqual(len(cache.cache), 1) with CacheGrabber(record_grabber=LocalDataGrabber) as cache: # Redo the last request, this time with a newly-loaded instance # of the cache from disk. self.assertEqual(len(cache.cache), 1) d = cache.cache['18231'] d['institution'] = u'Rigged for test' cache.cache['18231'] = d record = cache.get_record(18231) self.assertEqual(len(record), 6) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Rigged for test") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) self.assertEqual(record['message'], u"cache hit") self.assertEqual(len(cache.cache), 1) # Make another request, this time with the cached entry expired, # and verify a new version is retrieved. d['timestamp'] = time() - cache.expiration_interval - 1 cache.cache['18231'] = d record = cache.get_record(18231) self.assertEqual(len(record), 6) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Universit\xe4t Helmstedt") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) self.assertEqual(record['message'], u"cache miss") self.assertEqual(len(cache.cache), 1) def test_is_in_cache(self): """Test the is_in_cache method.""" d = {'name': self.name, 'institution': self.institution, 'year': self.year, 'advisors': self.advisors, 'descendants': self.descendants, 'timestamp': time()} with CacheGrabber(record_grabber=LocalDataGrabber) as cache: self.assertFalse(cache.is_cached(self.id)) cache.cache[str(self.id)] = d self.assertTrue(cache.is_cached(self.id)) new_timestamp = time() - cache.expiration_interval - 1 d['timestamp'] = new_timestamp cache.cache[str(self.id)] = d self.assertFalse(cache.is_cached(self.id)) def test_load_into_cache(self): """Test the load_into_cache method.""" with CacheGrabber(record_grabber=LocalDataGrabber) as cache: self.assertEqual(len(cache.cache), 0) new_record = {'name': self.name, 'institution': self.institution, 'year': self.year, 'advisors': self.advisors, 'descendants': self.descendants} cache.load_into_cache(self.id, new_record) self.assertEqual(len(cache.cache), 1) record = cache.cache[str(self.id)] self.assertEqual(record['name'], self.name) self.assertEqual(record['institution'], self.institution) self.assertEqual(record['year'], self.year) self.assertEqual(record['advisors'], self.advisors) self.assertEqual(record['descendants'], self.descendants) self.assertTrue(time() - record['timestamp'] < 20) # Insert the same record a second time to verify replacement # behavior. self.assertEqual(len(cache.cache), 1) record = cache.cache[str(self.id)] self.assertEqual(record['name'], self.name) self.assertEqual(record['institution'], self.institution) self.assertEqual(record['year'], self.year) self.assertEqual(record['advisors'], self.advisors) self.assertEqual(record['descendants'], self.descendants) self.assertTrue(time() - record['timestamp'] < 20) if __name__ == '__main__': unittest.main() Geneagrapher-master/tests/geneagrapher/test_geneagrapher_methods.py000066400000000000000000000436361177514123300263350ustar00rootroot00000000000000import os import sys import unittest import StringIO from geneagrapher import geneagrapher from geneagrapher.cache_grabber import CacheGrabber from geneagrapher.graph import Graph from local_data_grabber import LocalDataGrabber class TestGeneagrapherMethods(unittest.TestCase): """Unit tests for the geneagrapher.Geneagrapher class.""" def setUp(self): self.ggrapher = geneagrapher.Geneagrapher() def test_init(self): """Test constructor.""" self.assertEqual(isinstance(self.ggrapher.graph, Graph), True) self.assertEqual(self.ggrapher.seed_ids, []) self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.use_cache, True) self.assertEqual(self.ggrapher.cache_file, 'geneacache') def test_parse_empty(self): """Test parse_input() with no arguments.""" sys.argv = ['geneagrapher'] # Redirect stderr to capture output. stderr = sys.stderr stderr_intercept = StringIO.StringIO() sys.stderr = stderr_intercept expected = """usage: geneagrapher [-h] [--version] [-f FILE] [-a] \ [-d] [--disable-cache] [--cache-file FILE] [-v] ID [ID ...] geneagrapher: error: too few arguments """ try: self.ggrapher.parse_input() except SystemExit: self.assertEqual(stderr_intercept.getvalue().decode('utf-8'), expected) sys.stderr = stderr def test_parse_default(self): """Test parse_input() with no options.""" sys.argv = ['geneagrapher', '3'] self.ggrapher.get_ancestors = False self.ggrapher.get_descendents = True self.ggrapher.write_filename = "filler" self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.use_cache, True) self.assertEqual(self.ggrapher.cache_file, 'geneacache') self.assertEqual(self.ggrapher.seed_ids, [3]) def test_parse_options(self): """Test parse_input() with options.""" sys.argv = ['geneagrapher', '--with-ancestors', '--with-descendants', '--file=filler', '--verbose', '--disable-cache', '--cache-file', 'foo', '3', '43'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, True) self.assertEqual(self.ggrapher.get_descendants, True) self.assertEqual(self.ggrapher.verbose, True) self.assertEqual(self.ggrapher.write_filename, "filler") self.assertEqual(self.ggrapher.use_cache, False) self.assertEqual(self.ggrapher.cache_file, 'foo') self.assertEqual(self.ggrapher.seed_ids, [3, 43]) def test_parse_short_options(self): """Test parse_input() with short versions of the options.""" sys.argv = ['geneagrapher', '-a', '-d', '-f', 'filler', '-v', '3', '43'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, True) self.assertEqual(self.ggrapher.get_descendants, True) self.assertEqual(self.ggrapher.verbose, True) self.assertEqual(self.ggrapher.write_filename, "filler") self.assertEqual(self.ggrapher.use_cache, True) self.assertEqual(self.ggrapher.cache_file, 'geneacache') self.assertEqual(self.ggrapher.seed_ids, [3, 43]) def test_build_graph_complete_only_self(self): """Graph building with no ancestors or descendants.""" self.ggrapher.seed_ids.append(127946) self.ggrapher.build_graph_complete(LocalDataGrabber) graph = self.ggrapher.graph self.assertEqual(len(graph), 1) self.assertTrue(127946 in graph) node = graph[127946] self.assertEqual(node.ancestors, set()) self.assertEqual(node.descendants, set()) record = node.record self.assertEqual(record.name, "Christian Thomasius") self.assertEqual(record.institution, None) self.assertEqual(record.year, 1672) self.assertEqual(record.id, 127946) def test_build_graph_complete_only_self_verbose_cache_grabber(self): """Graph building with no ancestors or descendants using the cache grabber to verify its verbose printing.""" self.ggrapher.verbose = True self.ggrapher.seed_ids.append(127946) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept cache_fname = LocalDataGrabber.data_file( 'geneagrapher_verbose_cache_grabber_test') expiration = 1e15 self.ggrapher.build_graph_complete(CacheGrabber, filename=cache_fname, expiration_interval=expiration) sys.stdout = stdout self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), u"Grabbing record #127946...cache hit\n") def test_build_graph_complete_only_self_verbose_error(self): """Graph building with no ancestors or descendants given a bad ID.""" self.ggrapher.verbose = True self.ggrapher.seed_ids.append(999999999) self.assertRaises(ValueError, self.ggrapher.build_graph_complete, LocalDataGrabber) def test_build_graph_complete_only_self_verbose_error_long(self): """Graph building with no ancestors or descendants given a bad ID of the long variety.""" self.ggrapher.verbose = True self.ggrapher.seed_ids.append(999999999999999999999) self.assertRaises(ValueError, self.ggrapher.build_graph_complete, LocalDataGrabber) def test_build_graph_complete_only_self_verbose(self): """Graph building with no ancestors or descendants.""" self.ggrapher.verbose = True self.ggrapher.seed_ids.append(127946) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept self.ggrapher.build_graph_complete(LocalDataGrabber) sys.stdout = stdout graph = self.ggrapher.graph self.assertEqual(len(graph), 1) self.assertTrue(127946 in graph) node = graph[127946] self.assertEqual(node.ancestors, set()) self.assertEqual(node.descendants, set()) record = node.record self.assertEqual(record.name, "Christian Thomasius") self.assertEqual(record.institution, None) self.assertEqual(record.year, 1672) self.assertEqual(record.id, 127946) self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), u"Grabbing record #127946...\n") def test_build_graph_complete_with_ancestors(self): """Graph building with ancestors.""" self.ggrapher.seed_ids.append(127946) self.ggrapher.get_ancestors = True self.ggrapher.build_graph_complete(LocalDataGrabber) graph = self.ggrapher.graph self.assertEqual(len(graph), 4) self.assertTrue(127946 in graph) self.assertTrue(137717 in graph) self.assertTrue(137705 in graph) self.assertTrue(143630 in graph) node = graph[127946] self.assertEqual(node.ancestors, set([137717, 137705])) self.assertEqual(node.descendants, set()) record = node.record self.assertEqual(record.name, "Christian Thomasius") self.assertEqual(record.institution, None) self.assertEqual(record.year, 1672) self.assertEqual(record.id, 127946) node = graph[137717] self.assertEqual(node.ancestors, set([])) self.assertEqual(node.descendants, set([127946])) record = node.record self.assertEqual(record.name, "Valentin Alberti") self.assertEqual(record.institution, u"Universit\xe4t Leipzig") self.assertEqual(record.year, 1678) self.assertEqual(record.id, 137717) node = graph[137705] self.assertEqual(node.ancestors, set([143630])) self.assertEqual(node.descendants, set([127946])) record = node.record self.assertEqual(record.name, "Jakob Thomasius") self.assertEqual(record.institution, u"Universit\xe4t Leipzig") self.assertEqual(record.year, 1643) self.assertEqual(record.id, 137705) node = graph[143630] self.assertEqual(node.ancestors, set([])) self.assertEqual(node.descendants, set([137705])) record = node.record self.assertEqual(record.name, "Friedrich Leibniz") self.assertEqual(record.institution, None) self.assertEqual(record.year, None) self.assertEqual(record.id, 143630) def test_build_graph_complete_with_descendants(self): """Graph building with descendants.""" self.ggrapher.seed_ids.append(79568) self.ggrapher.get_descendants = True self.ggrapher.build_graph_complete(LocalDataGrabber) graph = self.ggrapher.graph self.assertEqual(len(graph), 3) self.assertTrue(79568 in graph) self.assertTrue(79562 in graph) self.assertTrue(99457 in graph) node = graph[79568] self.assertEqual(node.ancestors, set()) self.assertEqual(node.descendants, set([79562, 99457])) record = node.record self.assertEqual(record.name, "Ramdas Kumaresan") self.assertEqual(record.institution, u"University of Rhode Island") self.assertEqual(record.year, 1982) self.assertEqual(record.id, 79568) node = graph[79562] self.assertEqual(node.ancestors, set([79568])) self.assertEqual(node.descendants, set([])) record = node.record self.assertEqual(record.name, "C. S. Ramalingam") self.assertEqual(record.institution, u"University of Rhode Island") self.assertEqual(record.year, 1995) self.assertEqual(record.id, 79562) node = graph[99457] self.assertEqual(node.ancestors, set([79568])) self.assertEqual(node.descendants, set([])) record = node.record self.assertEqual(record.name, "Yadong Wang") self.assertEqual(record.institution, u"University of Rhode Island") self.assertEqual(record.year, 2003) self.assertEqual(record.id, 99457) def test_build_graph_complete_bad_id(self): """Graph building with a bad ID.""" self.ggrapher.seed_ids.append(79568583832) self.assertRaises(ValueError, self.ggrapher.build_graph_complete, LocalDataGrabber) try: self.ggrapher.build_graph_complete(LocalDataGrabber) except ValueError as e: self.assertEqual(str(e), "Invalid id 79568583832") else: self.fail() def test_end_to_end_self_stdout(self): """Complete test getting no ancestors or descendants and writing the result to stdout.""" sys.argv = ['geneagrapher', '30484'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.seed_ids, [30484]) self.ggrapher.build_graph_complete(LocalDataGrabber) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept self.ggrapher.generate_dot_file() sys.stdout = stdout expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 30484 [label="Peter Chris Pappas \\nThe Pennsylvania State University \ (1982)"]; } """ self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), expected) def test_end_to_end_cached_self_stdout(self): """Complete test using cache getting no ancestors or descendants and writing the result to stdout.""" cache_fname = LocalDataGrabber.data_file( 'end-to-end-30484') sys.argv = ['geneagrapher', '--cache-file', cache_fname, '30484'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.seed_ids, [30484]) self.ggrapher.build_graph_complete(CacheGrabber, filename=self.ggrapher.cache_file) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept self.ggrapher.generate_dot_file() sys.stdout = stdout expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 30484 [label="Peter Chris Pappas \\nThe Pennsylvania State University \ (1982)"]; } """ self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), expected) def test_end_to_end_ancestors_stdout(self): """ Complete test getting with ancestors, writing the result to stdout. """ sys.argv = ['geneagrapher', '-a', '127946'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, True) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.seed_ids, [127946]) self.ggrapher.build_graph_complete(LocalDataGrabber) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept self.ggrapher.generate_dot_file() sys.stdout = stdout expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 127946 [label="Christian Thomasius \\n(1672)"]; 137717 [label="Valentin Alberti \\nUniversit\xe4t Leipzig (1678)"]; 137705 [label="Jakob Thomasius \\nUniversit\xe4t Leipzig (1643)"]; 143630 [label="Friedrich Leibniz"]; 137717 -> 127946; 137705 -> 127946; 143630 -> 137705; } """ self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), expected) def test_end_to_end_descendants_stdout(self): """ Complete test getting with descendants, writing the result to stdout. """ sys.argv = ['geneagrapher', '-d', '79568'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, True) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, None) self.assertEqual(self.ggrapher.seed_ids, [79568]) self.ggrapher.build_graph_complete(LocalDataGrabber) # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept self.ggrapher.generate_dot_file() sys.stdout = stdout expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 79568 [label="Ramdas Kumaresan \\nUniversity of Rhode Island (1982)"]; 79562 [label="C. S. Ramalingam \\nUniversity of Rhode Island (1995)"]; 99457 [label="Yadong Wang \\nUniversity of Rhode Island (2003)"]; 79568 -> 79562; 79568 -> 99457; } """ self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), expected) def test_end_to_end_self_file(self): """Complete test getting no ancestors or descendants and writing the # result to stdout.""" outfname = 'outfile.test' sys.argv = ['geneagrapher', '-f', outfname, '30484'] self.ggrapher.parse_input() self.assertEqual(self.ggrapher.get_ancestors, False) self.assertEqual(self.ggrapher.get_descendants, False) self.assertEqual(self.ggrapher.verbose, False) self.assertEqual(self.ggrapher.write_filename, outfname) self.assertEqual(self.ggrapher.seed_ids, [30484]) self.ggrapher.build_graph_complete(LocalDataGrabber) self.ggrapher.generate_dot_file() expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 30484 [label="Peter Chris Pappas \\nThe Pennsylvania State University \ (1982)"]; } """ with open(outfname, 'r') as fin: self.assertEqual(fin.read().decode('utf-8'), expected) os.remove(outfname) def test_end_to_end_through_ggrapher_self_stdout(self): """Complete test calling ggrapher getting no ancestors or descendants and writing the result to stdout.""" cache_fname = LocalDataGrabber.data_file( 'end-to-end-30484') sys.argv = ['geneagrapher', '--cache-file', cache_fname, '30484'] # Redirect stdout to capture output. stdout = sys.stdout stdout_intercept = StringIO.StringIO() sys.stdout = stdout_intercept geneagrapher.ggrapher() sys.stdout = stdout expected = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 30484 [label="Peter Chris Pappas \\nThe Pennsylvania State University \ (1982)"]; } """ self.assertEqual(stdout_intercept.getvalue().decode('utf-8'), expected) if __name__ == '__main__': unittest.main() Geneagrapher-master/tests/geneagrapher/test_grabber_methods.py000066400000000000000000000174341177514123300253060ustar00rootroot00000000000000import os import sys from BeautifulSoup import BeautifulSoup import unittest from geneagrapher.grabber import * from local_data_grabber import LocalDataGrabber class TestGrabberMethods(unittest.TestCase): def data_file(self, filename): """Return the absolute path to the data file with given name.""" return LocalDataGrabber.data_file(filename) def test_init(self): """Test constructor.""" grabber = Grabber() self.assertIsInstance(grabber, Grabber) def test_get_record_bad(self): """Verify exception thrown from get_record() method for bad id.""" grabber = Grabber() self.assertRaises(ValueError, grabber.get_record, 999999999) try: grabber.get_record(999999999) except ValueError as e: self.assertEqual(str(e), "Invalid id 999999999") else: self.fail() def test_get_record_all_fields(self): """Test the get_record() method for a record containing all fields.""" grabber = Grabber() record = grabber.get_record(18231) self.assertEqual(len(record), 5) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Universit\xe4t Helmstedt") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) def test_get_record_from_tree_bad(self): """Verify exception thrown from get_record_from_tree() method for bad id.""" with open(self.data_file('999999999.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertRaises(ValueError, get_record_from_tree, soup, 999999999) try: get_record_from_tree(soup, 999999999) except ValueError as e: self.assertEqual(str(e), "Invalid id 999999999") else: self.fail() def test_get_record_from_tree_all_fields(self): """Test the get_record_from_tree() method for a record containing all fields.""" with open(self.data_file('18231.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') record = get_record_from_tree(soup, 18231) self.assertEqual(len(record), 5) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Universit\xe4t Helmstedt") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) # Verify calling get_record_from_tree() twice does not have side # effect. record = get_record_from_tree(soup, 18231) self.assertEqual(len(record), 5) self.assertEqual(record['name'], u"Carl Friedrich Gau\xdf") self.assertEqual(record['institution'], u"Universit\xe4t Helmstedt") self.assertEqual(record['year'], 1799) self.assertEqual(record['advisors'], set([18230])) self.assertEqual(record['descendants'], set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876])) def test_has_record_true(self): """Test the has_record() method with a tree containing a mathematician record.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertTrue(has_record(soup)) def test_has_record_false(self): """Test the record_exists() method with a tree not containing a mathematician record.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertTrue(has_record(soup)) def test_get_name(self): """Test the get_name() method.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(u"Valentin Alberti", get_name(soup)) def test_get_name_slash_l(self): """Test the get_name() method for a record containing a non-ASCII character.""" with open(self.data_file('7383.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(u"W\u0142adys\u0142aw Hugo Dyonizy Steinhaus", get_name(soup)) def test_get_institution(self): """Test the get_institution() method for a record with an institution.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(u"Universit\xe4t Leipzig", get_institution(soup)) def test_get_institution_no_institution(self): """Test the get_institution() method for a record with no institution.""" with open(self.data_file('52965.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertIsNone(get_institution(soup)) def test_get_year(self): """Test the get_year() method for a record with a graduation year.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_year(soup), 1678) def test_get_year_no_year(self): """Test the get_year() method for a record with no graduation year.""" with open(self.data_file('53658.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertIsNone(get_year(soup)) def test_get_advisors(self): """Test the get_advisors() method for a record with advisors.""" with open(self.data_file('18231.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_advisors(soup), set([18230])) def test_get_advisors_multiple(self): """Test the get_advisors() method for a record with multiple advisors.""" with open(self.data_file('19964.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_advisors(soup), set([17946, 47064])) def test_get_advisors_no_advisors(self): """Test the get_advisors() method for a record with no advisors.""" with open(self.data_file('137717.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_advisors(soup), set([])) def test_get_descendants(self): """Test the get_descendants() method for a record with descendants.""" expected_descendants = set([18603, 18233, 62547, 29642, 55175, 29458, 19953, 18232, 151876]) with open(self.data_file('18231.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_descendants(soup), expected_descendants) def test_get_descendants_no_descendants(self): """Test the get_descendants() method for a record with no descendants.""" with open(self.data_file('53658.html'), 'r') as fin: soup = BeautifulSoup(fin, convertEntities='html') self.assertEqual(get_descendants(soup), set([])) if __name__ == '__main__': file_path = os.path.abspath(sys.argv[0]) unittest.main() else: file_path = os.path.abspath(sys.argv[0]) Geneagrapher-master/tests/geneagrapher/test_graph_methods.py000066400000000000000000000341011177514123300247710ustar00rootroot00000000000000import unittest from geneagrapher.graph import DuplicateNodeError, Graph, Node, Record class TestGraphMethods(unittest.TestCase): """Unit tests for the Graph class.""" def setUp(self): self.record1 = Record(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231) self.node1 = Node(self.record1, set(), set()) self.graph1 = Graph(set([self.node1])) def test_init_empty(self): """Test the constructor with an empty seeds set.""" graph = Graph() self.assertEqual(graph.seeds, set()) def test_init(self): """Test the constructor.""" self.assertEqual(self.graph1.seeds, set([18231])) self.assertEqual(self.graph1.keys(), [18231]) self.assertEqual(self.graph1[18231], self.node1) def test_init_bad_seeds(self): """ Test the constructor when passed a bad type for the seeds parameter. """ self.assertRaises(TypeError, Graph, 3) def test_has_node_true(self): """Test the has_node() method for a True case.""" self.assertEqual(self.graph1.has_node(18231), True) def test_has_node_false(self): """Test the has_node() method for a False case.""" self.assertEqual(self.graph1.has_node(1), False) def test_contains_node_true(self): """Test the __contains__() method for a True case.""" self.assertEqual(18231 in self.graph1, True) def test_contains_node_false(self): """Test the __contains__() method for a False case.""" self.assertEqual(1 in self.graph1, False) def test_get_node(self): """Test the get_node() method.""" node = self.graph1.get_node(18231) self.assert_(node == self.node1) def test_get_node_not_found(self): """ Test the get_node() method for a case where the node does not exist. """ self.assertRaises(KeyError, self.graph1.get_node, 1) def test_get_node_list(self): """Test the get_node_list() method.""" self.assertEqual(self.graph1.get_node_list(), [18231]) def test_get_node_list_empty(self): """Test the get_node_list() method for an empty graph.""" graph = Graph() self.assertEqual(graph.get_node_list(), []) def test_add_node(self): """Test the add_node() method.""" self.graph1.add_node("Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set()) self.assertEqual([38586, 18231], self.graph1.get_node_list()) self.assertEqual(self.graph1.seeds, set([18231])) def test_add_second_node_seed(self): """Test the add_node() method when adding a second node and marking it as a seed node.""" self.graph1.add_node("Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set(), True) self.assertEqual([38586, 18231], self.graph1.get_node_list()) self.assertEqual(self.graph1.seeds, set([18231, 38586])) def test_add_node_seed(self): """Test the add_node() method when no seeds exist.""" graph = Graph() self.assertEqual(graph.seeds, set()) graph.add_node("Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set()) self.assertEqual(graph.seeds, set([38586])) def test_add_node_already_present(self): """Test for expected exception when adding a duplicate node.""" self.graph1.add_node("Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set()) self.assertEqual([38586, 18231], self.graph1.get_node_list()) self.assertRaises(DuplicateNodeError, self.graph1.add_node, "Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set()) try: self.graph1.add_node("Leonhard Euler", "Universitaet Basel", 1726, 38586, set(), set()) except DuplicateNodeError as e: self.assertEqual(str(e), "node with id {} already exists".format(38586)) else: self.fail() def test_add_node_object(self): """Test the add_node_object() method.""" record = Record("Leonhard Euler", "Universitaet Basel", 1726, 38586) node = Node(record, set(), set()) self.graph1.add_node_object(node) self.assertEqual([38586, 18231], self.graph1.get_node_list()) self.assertEqual(self.graph1.seeds, set([18231])) def test_generate_dot_file(self): """Test the generate_dot_file() method.""" dotfileexpt = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 18231 [label="Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt (1799)"]; } """ dotfile = self.graph1.generate_dot_file(True, False) self.assertEqual(dotfile, dotfileexpt) def test_generate_dot_file2(self): """Test the generate_dot_file() method. This is a larger example than test_generate_dot_file().""" graph = Graph() graph.add_node(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231, set([18230]), set()) graph.add_node(u"Johann Friedrich Pfaff", u"Georg-August-Universit\xe4t Goettingen", 1786, 18230, set([66476]), set([18231])) graph.add_node(u"Abraham Gotthelf Kaestner", u"Universit\xe4t Leipzig", 1739, 66476, set([57670]), set([18230])) graph.add_node(u"Christian August Hausen", u"Martin-Luther-Universit\xe4t Halle-Wittenberg", 1713, 57670, set([72669]), set([66476])) graph.add_node(u"Johann Christoph Wichmannshausen", u"Universit\xe4t Leipzig", 1685, 72669, set([21235]), set([57670])) graph.add_node(u"Otto Mencke", u"Universit\xe4t Leipzig", 1665, 21235, set(), set([72669])) dotfileexpt = u"""digraph genealogy { graph [charset="utf-8"]; node [shape=plaintext]; edge [style=bold]; 18231 [label="Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt (1799)"]; 18230 [label="Johann Friedrich Pfaff \\nGeorg-August-Universit\xe4t \ Goettingen (1786)"]; 66476 [label="Abraham Gotthelf Kaestner \\nUniversit\xe4t Leipzig (1739)"]; 57670 [label="Christian August Hausen \\nMartin-Luther-Universit\xe4t \ Halle-Wittenberg (1713)"]; 72669 [label="Johann Christoph Wichmannshausen \\nUniversit\xe4t Leipzig \ (1685)"]; 21235 [label="Otto Mencke \\nUniversit\xe4t Leipzig (1665)"]; 18230 -> 18231; 66476 -> 18230; 57670 -> 66476; 72669 -> 57670; 21235 -> 72669; } """ dotfile = graph.generate_dot_file(True, False) self.assertEqual(dotfile, dotfileexpt) def test_incremental_ancestor_descendant_check(self): """Test the contents of the ancestors and descendants members of a graph's nodes as they are added.""" graph = Graph() graph.add_node(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231, set([18230]), set([18603, 18233, 62547])) node1 = graph[18231] self.assertEqual(node1.ancestors, set()) self.assertEqual(node1.descendants, set()) graph.add_node(u"Johann Friedrich Pfaff", u"Georg-August-Universit\xe4t Goettingen", 1786, 18230, set([66476]), set([18231])) node2 = graph[18230] self.assertEqual(node1.ancestors, set([18230])) self.assertEqual(node1.descendants, set()) self.assertEqual(node2.ancestors, set()) self.assertEqual(node2.descendants, set([18231])) graph.add_node(u"Abraham Gotthelf Kaestner", u"Universit\xe4t Leipzig", 1739, 66476, set([57670]), set([18230])) node3 = graph[66476] self.assertEqual(node1.ancestors, set([18230])) self.assertEqual(node1.descendants, set()) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set([18231])) self.assertEqual(node3.ancestors, set()) self.assertEqual(node3.descendants, set([18230])) graph.add_node(u"Christian August Hausen", u"Martin-Luther-Universit\xe4t Halle-Wittenberg", 1713, 57670, set([72669]), set([66476])) node4 = graph[57670] self.assertEqual(node1.ancestors, set([18230])) self.assertEqual(node1.descendants, set()) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set([18231])) self.assertEqual(node3.ancestors, set([57670])) self.assertEqual(node3.descendants, set([18230])) self.assertEqual(node4.ancestors, set()) self.assertEqual(node4.descendants, set([66476])) graph.add_node(u"Johann Christoph Wichmannshausen", u"Universit\xe4t Leipzig", 1685, 72669, set([21235]), set([57670])) node5 = graph[72669] self.assertEqual(node1.ancestors, set([18230])) self.assertEqual(node1.descendants, set()) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set([18231])) self.assertEqual(node3.ancestors, set([57670])) self.assertEqual(node3.descendants, set([18230])) self.assertEqual(node4.ancestors, set([72669])) self.assertEqual(node4.descendants, set([66476])) self.assertEqual(node5.ancestors, set()) self.assertEqual(node5.descendants, set([57670])) graph.add_node(u"Otto Mencke", u"Universit\xe4t Leipzig", 1665, 21235, set(), set([72669])) node6 = graph[21235] self.assertEqual(node1.ancestors, set([18230])) self.assertEqual(node1.descendants, set()) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set([18231])) self.assertEqual(node3.ancestors, set([57670])) self.assertEqual(node3.descendants, set([18230])) self.assertEqual(node4.ancestors, set([72669])) self.assertEqual(node4.descendants, set([66476])) self.assertEqual(node5.ancestors, set([21235])) self.assertEqual(node5.descendants, set([57670])) self.assertEqual(node6.ancestors, set()) self.assertEqual(node6.descendants, set([72669])) def test_incremental_ancestor_descendant_check2(self): """Test the contents of the ancestors and descendants members of a # graph's nodes as they are added inserted in a different ofder than # in the previous test.""" graph = Graph() graph.add_node(u"Abraham Gotthelf Kaestner", u"Universit\xe4t Leipzig", 1739, 66476, set([57670]), set([18230])) node1 = graph[66476] self.assertEqual(node1.ancestors, set()) self.assertEqual(node1.descendants, set()) graph.add_node(u"Johann Friedrich Pfaff", u"Georg-August-Universit\xe4t Goettingen", 1786, 18230, set([66476]), set([18231])) node2 = graph[18230] self.assertEqual(node1.ancestors, set()) self.assertEqual(node1.descendants, set([18230])) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set()) graph.add_node(u"Christian August Hausen", u"Martin-Luther-Universit\xe4t Halle-Wittenberg", 1713, 57670, set([72669]), set([66476])) node3 = graph[57670] self.assertEqual(node1.ancestors, set([57670])) self.assertEqual(node1.descendants, set([18230])) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set()) self.assertEqual(node3.ancestors, set()) self.assertEqual(node3.descendants, set([66476])) graph.add_node(u"Johann Christoph Wichmannshausen", u"Universit\xe4t Leipzig", 1685, 72669, set([21235]), set([57670])) node4 = graph[72669] self.assertEqual(node1.ancestors, set([57670])) self.assertEqual(node1.descendants, set([18230])) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set()) self.assertEqual(node3.ancestors, set([72669])) self.assertEqual(node3.descendants, set([66476])) self.assertEqual(node4.ancestors, set()) self.assertEqual(node4.descendants, set([57670])) graph.add_node(u"Otto Mencke", u"Universit\xe4t Leipzig", 1665, 21235, set(), set([72669])) node5 = graph[21235] self.assertEqual(node1.ancestors, set([57670])) self.assertEqual(node1.descendants, set([18230])) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set()) self.assertEqual(node3.ancestors, set([72669])) self.assertEqual(node3.descendants, set([66476])) self.assertEqual(node4.ancestors, set([21235])) self.assertEqual(node4.descendants, set([57670])) self.assertEqual(node5.ancestors, set()) self.assertEqual(node5.descendants, set([72669])) graph.add_node(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231, set([18230]), set([18603, 18233, 62547])) node6 = graph[18231] self.assertEqual(node1.ancestors, set([57670])) self.assertEqual(node1.descendants, set([18230])) self.assertEqual(node2.ancestors, set([66476])) self.assertEqual(node2.descendants, set([18231])) self.assertEqual(node3.ancestors, set([72669])) self.assertEqual(node3.descendants, set([66476])) self.assertEqual(node4.ancestors, set([21235])) self.assertEqual(node4.descendants, set([57670])) self.assertEqual(node5.ancestors, set()) self.assertEqual(node5.descendants, set([72669])) self.assertEqual(node6.ancestors, set([18230])) self.assertEqual(node6.descendants, set()) if __name__ == '__main__': unittest.main() Geneagrapher-master/tests/geneagrapher/test_node_methods.py000066400000000000000000000101701177514123300246150ustar00rootroot00000000000000import unittest from geneagrapher.graph import Node, Record class TestNodeMethods(unittest.TestCase): """Unit tests for the Node class.""" def setUp(self): self.record = Record(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231) def test_init(self): """Test the constructor.""" node = Node(self.record, set(), set()) self.assertEqual(node.record, self.record) self.assertEqual(node.ancestors, set()) self.assertEqual(node.descendants, set()) def test_init_bad_record(self): """Test the constructor for a case where the record passed is not a Record object.""" self.assertRaises(TypeError, Node, 1, set(), set()) def test_init_bad_ancestor_list(self): """Test the constructor for a case where the ancestor list is not a list.""" self.assertRaises(TypeError, Node, self.record, 1, set()) def test_2_init_bad_descendent_list(self): """Test the constructor for a case where the descendent list is not a list.""" self.assertRaises(TypeError, Node, self.record, set(), 1) def test_unicode_full(self): """Test __unicode__() method for Node with complete record.""" node = Node(self.record, set(), set()) nodestr = node.__unicode__() nodestrexpt = u"Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt \ (1799)" self.assertEqual(nodestr, nodestrexpt) def test_unicode_no_year(self): """ Test __unicode__() method for Node containing record without year. """ record = Record(self.record.name, self.record.institution, None, 18231) node = Node(record, set(), set()) nodestr = node.__unicode__() nodestrexpt = u"Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt" self.assertEqual(nodestr, nodestrexpt) def test_unicode_no_inst(self): """Test __unicode__() method for Node containing record without institution.""" record = Record(self.record.name, None, 1799, 18231) node = Node(record, set(), set()) nodestr = node.__unicode__() nodestrexpt = u"Carl Friedrich Gau\xdf \\n(1799)" self.assertEqual(nodestr, nodestrexpt) def test_unicode_no_inst_no_id(self): """Test __unicode__() method for Node containing record without institution or year.""" record = Record(self.record.name, None, None, 18231) node = Node(record, set(), set()) nodestr = node.__unicode__() nodestrexpt = u"Carl Friedrich Gau\xdf" self.assertEqual(nodestr, nodestrexpt) def test_cmp_equal(self): """Test comparison method for Nodes with identical records.""" record2 = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) node1 = Node(self.record, set(), set()) node2 = Node(record2, set(), set()) self.assert_(node1 == node2) def test_cmp_unequal(self): """Test comparison method for Nodes with different records.""" record2 = Record("Leonhard Euler", "Universitaet Basel", 1726, 38586) node1 = Node(self.record, set(), set()) node2 = Node(record2, set(), set()) self.assert_(node1 < node2) def test_add_ancestor(self): """Test the add_ancestor() method.""" node = Node(self.record, set(), set()) node.add_ancestor(5) self.assertEqual(node.ancestors, set([5])) def test_add_ancestor_bad_type(self): """Test the add_ancestor() method for a case where the parameter type is incorrect.""" node = Node(self.record, set(), set()) self.assertRaises(TypeError, node.add_ancestor, '5') def test_get_id(self): """Test the get_id() method.""" node = Node(self.record, set(), set()) self.assertEqual(node.get_id(), 18231) def test_set_id(self): """Test the set_id() method.""" node = Node(self.record, set(), set()) self.assertEqual(node.get_id(), 18231) node.set_id(15) self.assertEqual(node.get_id(), 15) if __name__ == '__main__': unittest.main() Geneagrapher-master/tests/geneagrapher/test_record_methods.py000066400000000000000000000111411177514123300251450ustar00rootroot00000000000000import unittest from geneagrapher.graph import Record # Unit tests for graph-related classes. class TestRecordMethods(unittest.TestCase): """Unit tests for the Record class.""" def setUp(self): self.record = Record(u"Carl Friedrich Gau\xdf", u"Universit\xe4t Helmstedt", 1799, 18231) def test_init(self): """Test the constructor.""" record = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) self.assertEqual(record.name, "Carl Friedrich Gauss") self.assertEqual(record.institution, "Universitaet Helmstedt") self.assertEqual(record.year, 1799) self.assertEqual(record.id, 18231) def test_init_bad_name(self): """Test constructor with bad 'name' parameter.""" self.assertRaises(TypeError, Record, 1, "Universitaet Helmstedt", 1799, 18231) def test_init_bad_institution(self): """Test constructor with bad 'institution' parameter.""" self.assertRaises(TypeError, Record, "Carl Friedrich Gauss", 1, 1799, 18231) def test_init_bad_year(self): """Test constructor with bad 'year' parameter.""" self.assertRaises(TypeError, Record, "Carl Friedrich Gauss", "Universitaet Helmstedt", "1799", 18231) def test_init_bad_id(self): """Test constructor with bad 'id' parameter.""" self.assertRaises(TypeError, Record, "Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, "18231") def test_cmp_equal(self): """Verify two 'equal' records are compared correctly.""" record1 = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) record2 = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) self.assert_(record1 == record2) def test_cmp_unequal(self): """Verify two 'unequal' records are compared correctly.""" record1 = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) record2 = Record("Leonhard Euler", "Universitaet Basel", 1726, 38586) self.assert_(record1 < record2) def test_has_institution_yes(self): """Verify has_institution() method returns True when the conditions are right.""" record = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) self.assert_(record.has_institution()) def test_has_institution_no(self): """Verify has_institution() method returns False when the conditions are right.""" record = Record("Carl Friedrich Gauss", None, 1799, 18231) self.assert_(not record.has_institution()) def test_has_year_yes(self): """ Verify has_year() method returns True when the conditions are right. """ record = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", 1799, 18231) self.assert_(record.has_year()) def test_has_year_no(self): """ Verify has_year() method returns False when the conditions are right. """ record = Record("Carl Friedrich Gauss", "Universitaet Helmstedt", None, 18231) self.assert_(not record.has_year()) def test_unicode_full(self): """Test __unicode__() method for complete record.""" recstr = self.record.__unicode__() recstrexpt = u"Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt \ (1799)" self.assertEqual(recstr, recstrexpt) def test_unicode_no_year(self): """Test __unicode__() method for record without year.""" record = Record(self.record.name, self.record.institution, None, 18231) recstr = record.__unicode__() recstrexpt = u"Carl Friedrich Gau\xdf \\nUniversit\xe4t Helmstedt" self.assertEqual(recstr, recstrexpt) def test_unicode_no_inst(self): """Test __unicode__() method for record without institution.""" record = Record(self.record.name, None, 1799, 18231) recstr = record.__unicode__() recstrexpt = u"Carl Friedrich Gau\xdf \\n(1799)" self.assertEqual(recstr, recstrexpt) def test_unicode_no_inst_no_id(self): """Test __unicode__() method for record without institution or year.""" record = Record(self.record.name, None, None, 18231) recstr = record.__unicode__() recstrexpt = u"Carl Friedrich Gau\xdf" self.assertEqual(recstr, recstrexpt) if __name__ == '__main__': unittest.main() Geneagrapher-master/tests/geneagrapher/testdata/000077500000000000000000000000001177514123300223465ustar00rootroot00000000000000Geneagrapher-master/tests/geneagrapher/testdata/10275.html000066400000000000000000000333001177514123300237110ustar00rootroot00000000000000 The Mathematics Genealogy Project - Stefan Drobot

Stefan Drobot

MathSciNet


Ph.D. University of Lwów 1939 Poland
Dissertation:

Advisor: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Konrad HeuversThe Ohio State University1969
William Huffman IIIThe Ohio State University1979
Robert JohnsonThe Ohio State University1975
Kenneth KimbleThe Ohio State University19691
John LoganThe Ohio State University19707
David MayerThe Ohio State University1974
Benjamin PlybonThe Ohio State University1968
Adam RybarskiInstitute of Mathematics, Polish Academy of Science1957
Eugene SantosThe Ohio State University1965
Leonard SulskiUniversity of Notre Dame1963

According to our current on-line database, Stefan Drobot has 10 students and 18 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/12681.html000066400000000000000000000277451177514123300237340ustar00rootroot00000000000000 The Mathematics Genealogy Project - Stefan Banach

Stefan Banach

Biography MathSciNet


Ph.D. University of Lwów 1920 Poland
Dissertation: Sur les opérations dans les ensembles abstraits et leur application aux équations intégrales

Advisor: Władysław Hugo Dyonizy Steinhaus
Advisor 2: Kazimierz Twardowski

Student:

NameSchoolYearDescendants
Stanislaw MazurUniversity of Lwów1932132

According to our current on-line database, Stefan Banach has 1 student and 133 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/127470.html000066400000000000000000000273441177514123300240120ustar00rootroot00000000000000 The Mathematics Genealogy Project - Józef Łukaszewicz

Józef Łukaszewicz


Ph.D. Uniwersytet Wrocławski 1957 Poland
Dissertation:
Mathematics Subject Classification: 00—General

Advisor 1: Władysław Hugo Dyonizy Steinhaus

Student:

NameSchoolYearDescendants
Tomasz Rolski 6

According to our current on-line database, Józef Łukaszewicz has 1 student and 7 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/127946.html000066400000000000000000000276721177514123300240260ustar00rootroot00000000000000 The Mathematics Genealogy Project - Christian Thomasius

Christian Thomasius


M. Phil. 1672
Dissertation:

Advisor 1: Valentin Alberti
Advisor 2: Jakob Thomasius

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Nicolaus GundlingMartin-Luther-Universität Halle-Wittenberg17033935
Johann von LudewigMartin-Luther-Universität Halle-Wittenberg16902269

According to our current on-line database, Christian Thomasius has 2 students and 6163 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/137705.html000066400000000000000000000302361177514123300240060ustar00rootroot00000000000000 The Mathematics Genealogy Project - Jakob Thomasius

Jakob Thomasius


Magister der Philosophie Universität Leipzig 1643 Germany
Dissertation:

Advisor 1: Friedrich Leibniz

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Gottfried LeibnizUniversität Leipzig166666456
Otto MenckeUniversität Leipzig166565703
Christian Thomasius16726163

According to our current on-line database, Jakob Thomasius has 3 students and 91511 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/137717.html000066400000000000000000000270501177514123300240110ustar00rootroot00000000000000 The Mathematics Genealogy Project - Valentin Alberti

Valentin Alberti


Dr. theol. Universität Leipzig 1678 Germany
Dissertation:

Advisor: Unknown

Student:

NameSchoolYearDescendants
Christian Thomasius16726163

According to our current on-line database, Valentin Alberti has 1 student and 6164 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/143630.html000066400000000000000000000266371177514123300240120ustar00rootroot00000000000000 The Mathematics Genealogy Project - Friedrich Leibniz

Friedrich Leibniz


Dissertation:

Advisor: Unknown

Student:

NameSchoolYearDescendants
Jakob ThomasiusUniversität Leipzig164391511

According to our current on-line database, Friedrich Leibniz has 1 student and 91512 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/15165.html000066400000000000000000000277231177514123300237300ustar00rootroot00000000000000 The Mathematics Genealogy Project - Aleksander Rajchman

Aleksander Rajchman


Ph.D. University of Lwów 1921 Poland
Dissertation:

Advisor: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Zygmunt ZalcwasserUniwersytet Warszawski
Antoni ZygmundUniwersytet Warszawski1923986

According to our current on-line database, Aleksander Rajchman has 2 students and 988 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/151876.html000066400000000000000000000255711177514123300240210ustar00rootroot00000000000000 The Mathematics Genealogy Project - Karl von Staudt

Karl Georg Christian von Staudt

Biography


Ph.D. Friedrich-Alexander-Universität Erlangen-Nürnberg 1822 Germany
Dissertation:

Advisor: Carl Friedrich Gauß

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/17851.html000066400000000000000000000336041177514123300237270ustar00rootroot00000000000000 The Mathematics Genealogy Project - Mark Kac

Mark Kac

Biography MathSciNet


Ph.D. University of Lwów 1937 Poland
Dissertation:

Advisor: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Wayne BarrettNew York University19752
Ronald FoxThe Rockefeller University196913
Anatole JoffeCornell University19598
Talbot KatzThe Rockefeller University1982
Harry KestenCornell University195891
William LeVequeCornell University19485
Abraham MarkCornell University1948
William NewcombCornell University19523
Daniel RayCornell University195318
Murray RosenblattCornell University194988
Daniel StroockThe Rockefeller University196714

According to our current on-line database, Mark Kac has 11 students and 253 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/17946.html000066400000000000000000000330551177514123300237340ustar00rootroot00000000000000 The Mathematics Genealogy Project - Gustav Dirichlet

Gustav Peter Lejeune Dirichlet

Biography MathSciNet


Honorary Rheinische Friedrich-Wilhelms-Universität Bonn 1827 Germany
Dissertation: Partial Results on Fermat's Last Theorem, Exponent 5 (He studied with Poisson and Fourier before returning to Germany)
Mathematics Subject Classification: 11—Number theory

Advisor 1: Simeon Denis Poisson
Advisor 2: Jean-Baptiste Joseph Fourier

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Ferdinand EisensteinUniversität Berlin1845
August KramerHumboldt-Universität zu Berlin1839
Leopold KroneckerUniversität Berlin18453598
Rudolf LipschitzUniversität Berlin185335138
Gustav MichaelisHumboldt-Universität zu Berlin1837
Johann RoethigUniversität Berlin1857
Leo WituskiUniversität Berlin1853

According to our current on-line database, Gustav Dirichlet has 7 students and 36776 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/18230.html000066400000000000000000000311441177514123300237140ustar00rootroot00000000000000 The Mathematics Genealogy Project - Johann Pfaff

Johann Friedrich Pfaff

Biography


Dr. phil. Georg-August-Universität Göttingen 1786 Germany
Dissertation: Commentatio de ortibus et occasibus siderum apud auctores classicos commemoratis

Advisor 1: Abraham Gotthelf Kästner
Advisor 2: Johann Elert Bode

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Johann BartelsFriedrich-Schiller-Universität Jena17998329
Carl GaußUniversität Helmstedt179950610
August MöbiusUniversität Leipzig18153312
Karl MollweideUniversität Helmstedt179691

According to our current on-line database, Johann Pfaff has 4 students and 57270 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/18231.html000066400000000000000000000336021177514123300237160ustar00rootroot00000000000000 The Mathematics Genealogy Project - Carl Gauß

Carl Friedrich Gauß

Biography MathSciNet


Ph.D. Universität Helmstedt 1799 Germany
Dissertation: Demonstratio nova theorematis omnem functionem algebraicam rationalem integram unius variabilis in factores reales primi vel secundi gradus resolvi posse

Advisor: Johann Friedrich Pfaff

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Friedrich BesselGeorg-August-Universität Göttingen181022367
J. W. Richard DedekindGeorg-August-Universität Göttingen1852
Johann EnckeUniversität Berlin18446408
Christian GerlingGeorg-August-Universität Göttingen181235139
Sophie GermainGeorg-August-Universität Göttingen1830
Christoph GudermannGeorg-August-Universität Göttingen184118957
Johann ListingGeorg-August-Universität Göttingen1834
Georg RiemannGeorg-August-Universität Göttingen1851
Karl von StaudtFriedrich-Alexander-Universität Erlangen-Nürnberg1822

According to our current on-line database, Carl Gauß has 9 students and 50610 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/18232.html000066400000000000000000000261021177514123300237140ustar00rootroot00000000000000 The Mathematics Genealogy Project - Georg Riemann

Georg Friedrich Bernhard Riemann

Biography MathSciNet


Ph.D. Georg-August-Universität Göttingen 1851 Germany
Dissertation: Grundlagen für eine allgemeine Theorie der Funktionen einer veränderlichen complexen Größe

Advisor: Carl Friedrich Gauß

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/18233.html000066400000000000000000000256451177514123300237300ustar00rootroot00000000000000 The Mathematics Genealogy Project - J. W. Richard Dedekind

J. W. Richard (Julius Wilhelm) Dedekind

Biography


Ph.D. Georg-August-Universität Göttingen 1852 Germany
Dissertation: Über die Theorie der Eulerschen Integrale

Advisor: Carl Friedrich Gauß

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/18603.html000066400000000000000000000273571177514123300237330ustar00rootroot00000000000000 The Mathematics Genealogy Project - Friedrich Bessel

Friedrich Wilhelm Bessel

Biography


Ph.D. Georg-August-Universität Göttingen 1810 Germany
Dissertation:

Advisor: Carl Friedrich Gauß

Student:

NameSchoolYearDescendants
Heinrich ScherkUniversität Berlin182322366

According to our current on-line database, Friedrich Bessel has 1 student and 22367 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/19953.html000066400000000000000000000255761177514123300237450ustar00rootroot00000000000000 The Mathematics Genealogy Project - Johann Listing

Johann Benedict Listing

Biography


Ph.D. Georg-August-Universität Göttingen 1834 Germany
Dissertation: De Superficiebus secundi ordinis

Advisor: Carl Friedrich Gauß

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/19964.html000066400000000000000000000276171177514123300237450ustar00rootroot00000000000000 The Mathematics Genealogy Project - Rudolf Lipschitz

Rudolf Otto Sigismund Lipschitz

Biography


Dr. phil. Universität Berlin 1853 Germany
Dissertation: Determinatio status magnetici viribus inducentibus commoti in ellipsoide

Advisor 1: Gustav Peter Lejeune Dirichlet
Advisor 2: Martin Ohm

Student:

NameSchoolYearDescendants
C. Felix KleinRheinische Friedrich-Wilhelms-Universität Bonn186835137

According to our current on-line database, Rudolf Lipschitz has 1 student and 35138 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/28292.html000066400000000000000000000326221177514123300237270ustar00rootroot00000000000000 The Mathematics Genealogy Project - Z. W. (Bill) Birnbaum

Z. W. (Bill) (Zygmunt William) Birnbaum

Biography MathSciNet


Ph.D. University of Lwów 1929 Poland
Dissertation:

Advisor: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Orval KloseUniversity of Washington1956
Bennet LientzUniversity of Washington1968
Albert MarshallUniversity of Washington19589
Ronald PykeUniversity of Washington195660
John RaymondUniversity of Washington1949
Roger ShorackUniversity of Washington1969
Monroe SirkenUniversity of Washington1950
Fred TingeyUniversity of Washington1951

According to our current on-line database, Z. W. (Bill) Birnbaum has 8 students and 77 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/29458.html000066400000000000000000000274771177514123300237500ustar00rootroot00000000000000 The Mathematics Genealogy Project - Christoph Gudermann

Christoph Gudermann

Biography


Ph.D. Georg-August-Universität Göttingen 1841 Germany
Dissertation: Über die Entwicklung der Modularfunctionen

Advisor: Carl Friedrich Gauß

Student:

NameSchoolYearDescendants
Karl WeierstraßUniversität Königsberg185418956

According to our current on-line database, Christoph Gudermann has 1 student and 18957 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/29642.html000066400000000000000000000274421177514123300237330ustar00rootroot00000000000000 The Mathematics Genealogy Project - Christian Gerling

Christian Ludwig Gerling


Dr. phil. Georg-August-Universität Göttingen 1812 Germany
Dissertation: Methodi proiectionis orthographicae usum ad calculos parallacticos facilitandos explicavit simulque eclipsin solarem die

Advisor: Carl Friedrich Gauß

Student:

NameSchoolYearDescendants
Julius PlückerPhilipps-Universität Marburg182335138

According to our current on-line database, Christian Gerling has 1 student and 35139 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/30484.html000066400000000000000000000260371177514123300237260ustar00rootroot00000000000000 The Mathematics Genealogy Project - Peter Pappas

Peter Chris Pappas

MathSciNet


Ph.D. The Pennsylvania State University 1982 UnitedStates
Dissertation: The Model Theoretic Structure of Group Rings
Mathematics Subject Classification: 16—Associative rings and algebras

Advisor: Stephen George Simpson

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/36991.html000066400000000000000000000276771177514123300237520ustar00rootroot00000000000000 The Mathematics Genealogy Project - Marek Fisz

Marek Fisz

MathSciNet


Ph.D. Politechnika Wrocławska 1950 Poland
Dissertation: Quality Control of Mass Production by Variables
Mathematics Subject Classification: 60—Probability theory and stochastic processes

Advisor 1: Władysław Hugo Dyonizy Steinhaus
Advisor 2: Edward Marczewski

Student:

NameSchoolYearDescendants
Ignacy KotlarskiPolitechnika Wrocławska19503

According to our current on-line database, Marek Fisz has 1 student and 4 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/47064.html000066400000000000000000000340111177514123300237170ustar00rootroot00000000000000 The Mathematics Genealogy Project - Martin Ohm

Martin Ohm

Biography


Dr. phil. Friedrich-Alexander-Universität Erlangen-Nürnberg 1811 Germany
Dissertation: De elevatione serierum infinitarum secundi ordinis ad potestatem exponentis indeterminati

Advisor: Karl Christian von Langsdorf

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Friedrich AugustUniversität Berlin1862
Friedrich BachmannUniversität Berlin1861
Paul BachmannUniversität Berlin1862
Joseph BrutkowskiUniversität Berlin1859
Eduard HeineUniversität Berlin18423
Rudolf LipschitzUniversität Berlin185335138
Leo PochhammerUniversität Berlin18632
Friedrich PrymUniversität Berlin18631483
Wilhelm WagnerHumboldt-Universität zu Berlin1855
Hermann WaldaestelHumboldt-Universität zu Berlin1860
Wilhelm WernickeHumboldt-Universität zu Berlin1863

According to our current on-line database, Martin Ohm has 11 students and 35170 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/51261.html000066400000000000000000000344641177514123300237250ustar00rootroot00000000000000 The Mathematics Genealogy Project - Antonio Ambrosetti

Antonio Ambrosetti

MathSciNet


Ph.D.
Dissertation:

Advisor: Unknown

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Pietro BaldiScuola Internazionale Superiore di Studi Avanzati, Trieste2007
Massimiliano BertiUniversità di Pisa3
Luca BiascoScuola Internazionale Superiore di Studi Avanzati20021
Marco CalahorranoScuola Normale Superiore di Pisa and Escuela Politécnica Nacional-Quito2009
S. CingolaniScuola Normale Superiore di Pisa
Vittorio Coti ZelatiUniversità degli Studi di Trieste1
Veronica FelliScuola Internazionale Superiore di Studi Avanzati, Trieste2003
Pietro MajerUniversità di Pisa 1
Andrea MalchiodiScuola Internazionale Superiore di Studi Avanzati20001
P. MayerUniversità di Pisa
Simone SecchiScuola Internazionale Superiore di Studi Avanzati, Trieste2002
S. SolominiUniversità degli Studi di Trieste
Enzo Vitillaro

According to our current on-line database, Antonio Ambrosetti has 13 students and 17 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/51907.html000066400000000000000000000516701177514123300237320ustar00rootroot00000000000000 The Mathematics Genealogy Project - Władysław Orlicz

Władysław Roman Orlicz

Biography


Ph.D. University of Lwów 1928 Poland
Dissertation: Z teorii szeregów ortogonalnych (On the Theory of Orthogonal Series)
Mathematics Subject Classification: 46—Functional analysis

Advisor 1: Eustachy I. Żyliński
Advisor 2: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Jerzy AlbrychtUniwersytet im. Adama Mickiewicza Poznań1959
Andrzej AlexiewiczUniversity of Lwów194415
Feliks Barański1958
Dobiesław BobrowskiUniwersytet im. Adama Mickiewicza Poznań1962
Victor BogdanPolish Academy of Sciences196045
Czeslaw BylkaUniwersytet im. Adama Mickiewicza Poznań1976
Quan-Fu CiUniwersytet im. Adama Mickiewicza Poznań1960
Jaroslaw CiemnoczołowskiUniwersytet im. Adama Mickiewicza Poznań1984
Zbigniew CiesielskiUniwersytet im. Adama Mickiewicza Poznań196056
Lech DrewnowskiUniwersytet im. Adama Mickiewicza Poznań19714
Maria FilarUniwersytet im. Adama Mickiewicza Poznań1966
Barbara FirlejUniwersytet im. Adama Mickiewicza Poznań1972
Wojciech FriedrichUniwersytet im. Adama Mickiewicza Poznań1979
Danuta JachUniwersytet im. Adama Mickiewicza Poznań1980
Marian JaroszUniwersytet im. Adama Mickiewicza Poznań1963
Marek KarpińskiInstitute of Mathematics, Polish Academy of Science197312
Franciszek KlorekUniwersytet im. Adama Mickiewicza Poznań1970
Stanisław KnapowskiUniwersytet im. Adama Mickiewicza Poznań1957
Bogdan KotkowskiUniwersytet im. Adama Mickiewicza Poznań1969
Przemysław KranzInstitute of Mathematics, Polish Academy of Science1975
Iwo LabudaInstitute of Mathematics, Polish Academy of Science19732
Ryszard LeśniewiczUniwersytet im. Adama Mickiewicza Poznań19679
Lech MaligrandaUniwersytet im. Adama Mickiewicza Poznań19795
Wanda MatuszewskaUniwersytet im. Adama Mickiewicza Poznań1960
Józef MederUniwersytet im. Adama Mickiewicza Poznań1958
Julian MusielakUniwersytet im. Adama Mickiewicza Poznań195839
Jadwiga PawłowskaUniwersytet im. Adama Mickiewicza Poznań1964
Zbigniew PolniakowskiUniwersytet im. Adama Mickiewicza Poznań1962
Jerzy RadeckiUniwersytet im. Adama Mickiewicza Poznań1962
Zbigniew RatajczakUniwersytet im. Adama Mickiewicza Poznań1964
Henryk RatajskiUniwersytet im. Adama Mickiewicza Poznań1962
Jurand RyterskiUniwersytet im. Adama Mickiewicza Poznań1966
Henryk SampławskiUniwersytet im. Adama Mickiewicza Poznań1969
Ryszard SerafinUniwersytet im. Adama Mickiewicza Poznań1978
Stanisław SzuflaUniwersytet im. Adama Mickiewicza Poznań19723
Roman TaberskiUniwersytet im. Adama Mickiewicza Poznań19591
Eustachy TarnawskiUniwersytet im. Adama Mickiewicza Poznań1951
Adam WachułkaUniwersytet im. Adama Mickiewicza Poznań1965
Aleksander WaszakUniwersytet im. Adama Mickiewicza Poznań1967
Henryk WiśniewskiUniwersytet im. Adama Mickiewicza Poznań19644

According to our current on-line database, Władysław Orlicz has 40 students and 235 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/52965.html000066400000000000000000000265501177514123300237360ustar00rootroot00000000000000 The Mathematics Genealogy Project - Walter Mayer

Walter Mayer


Ph.D.
Dissertation:

Advisor: Unknown

Student:

NameSchoolYearDescendants
Gustav BergmannUniversität Wien1928

According to our current on-line database, Walter Mayer has 1 student and 1 descendant.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/52996.html000066400000000000000000000256111177514123300237370ustar00rootroot00000000000000 The Mathematics Genealogy Project - Gustav Bergmann

Gustav Bergmann

MathSciNet


Ph.D. Universität Wien 1928 Austria
Dissertation: Zwei Beiträge zur mehrdimensionalen Differentialgeometrie

Advisor: Walter Mayer

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/53658.html000066400000000000000000000255141177514123300237350ustar00rootroot00000000000000 The Mathematics Genealogy Project - S. Cingolani

S. Cingolani

MathSciNet


Ph.D. Scuola Normale Superiore di Pisa Italy
Dissertation:

Advisor: Antonio Ambrosetti

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/55175.html000066400000000000000000000256231177514123300237320ustar00rootroot00000000000000 The Mathematics Genealogy Project - Sophie Germain

Sophie Germain

Biography


Ph.D. Georg-August-Universität Göttingen 1830 Germany
Dissertation: Honorary degree awarded by Gottingen under pressure from Gauss

Advisor: Carl Friedrich Gauß

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/62547.html000066400000000000000000000324021177514123300237240ustar00rootroot00000000000000 The Mathematics Genealogy Project - Johann Encke

Johann Franz Friedrich Encke


Universität Berlin 1844 Germany
Dissertation: From 1811 on Encke studied mathematics in Goettingen as pupil of C.F. Gauss. In May 1816 he moved to Seeberg near Gotha to work as observer at the observatory there. In 1822 he was promoted Director of that observatory and in 1825 followed a call to be the Director of the Observatory at Berlin. He supervised the new construction of the observatory from 1832 -35. In 1844 he became ordinary professor at the University of Berlin and was allowed to lecture without receiving a doctorate. Closest to being his advisor in becoming a professor was therefore Carl Friedrich Gauss.
Mathematics Subject Classification: 85—Astronomy and astrophysics

Advisor: Carl Friedrich Gauß

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Carl BruhnsUniversität Berlin18562846
August KramerHumboldt-Universität zu Berlin1839
Leopold KroneckerUniversität Berlin18453598
Joseph RaatzHumboldt-Universität zu Berlin1861
Franz WoepckeHumboldt-Universität zu Berlin1847

According to our current on-line database, Johann Encke has 5 students and 6408 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/7298.html000066400000000000000000000711651177514123300236570ustar00rootroot00000000000000 The Mathematics Genealogy Project - David Hilbert

David Hilbert

Biography MathSciNet


Ph.D. Universität Königsberg 1885 Germany
Dissertation: Über invariante Eigenschaften specieller binärer Formen, insbesondere der Kugelfunctionen

Advisor: C. L. Ferdinand (Carl Louis) Lindemann

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Wilhelm AckermannGeorg-August-Universität Göttingen1925
Albert AndraeGeorg-August-Universität Göttingen1903
Bernhard BauleGeorg-August-Universität Göttingen1914
Fritz BeerGeorg-August-Universität Göttingen1899
Heinrich BehmannGeorg-August-Universität Göttingen1922
Felix BernsteinGeorg-August-Universität Göttingen190148
Sergej BernsteinUniversité Paris IV-Sorbonne190453
Otto BlumenthalGeorg-August-Universität Göttingen18985
Hans BolzaGeorg-August-Universität Göttingen1913
Anne BosworthGeorg-August-Universität Göttingen1899
Werner BoyGeorg-August-Universität Göttingen1901
Ugo BroggiGeorg-August-Universität Göttingen1907
William CairnsGeorg-August-Universität Göttingen1907
Richard CourantGeorg-August-Universität Göttingen19103972
Arthur CrathorneGeorg-August-Universität Göttingen19079
Haskell CurryGeorg-August-Universität Göttingen193010
Max DehnGeorg-August-Universität Göttingen1900753
Heinrich DörrieGeorg-August-Universität Göttingen1898
Michael FeldblumGeorg-August-Universität Göttingen1899
Ludwig FöpplGeorg-August-Universität Göttingen191218
Rudolf FueterGeorg-August-Universität Göttingen190329
Paul FunkGeorg-August-Universität Göttingen19111
Nadeschda GernetGeorg-August-Universität Göttingen1902
David GillespieGeorg-August-Universität Göttingen19061
Kurt GrellingGeorg-August-Universität Göttingen1910
Jakob GrommerGeorg-August-Universität Göttingen1914
Alfred HaarGeorg-August-Universität Göttingen1909
Georg HamelGeorg-August-Universität Göttingen1901252
Charles HasemanGeorg-August-Universität Göttingen1907
Erich HeckeGeorg-August-Universität Göttingen19102306
Earle HedrickGeorg-August-Universität Göttingen19011
Ernst HellingerGeorg-August-Universität Göttingen19073
Paul HertzGeorg-August-Universität Göttingen19041
Karl HilbertGeorg-August-Universität Göttingen1900
Wallie HurwitzGeorg-August-Universität Göttingen1910218
Gerhard JanßenGeorg-August-Universität Göttingen1913
Grete KahnGeorg-August-Universität Göttingen1909
Edward KasnerColumbia University1899584
Oliver KelloggGeorg-August-Universität Göttingen1902153
Paul KirchbergerGeorg-August-Universität Göttingen1902
Hugo KistlerGeorg-August-Universität Göttingen1905
Hellmuth KneserGeorg-August-Universität Göttingen19211207
Robert KönigGeorg-August-Universität Göttingen1907676
Albert KraftGeorg-August-Universität Göttingen1903
Wera LebedeffGeorg-August-Universität Göttingen1906
Karl Julius LietzmannGeorg-August-Universität Göttingen1904
Klara LöbensteinGeorg-August-Universität Göttingen1910
Georg LütkemeyerGeorg-August-Universität Göttingen1902
Sophus MarxsenGeorg-August-Universität Göttingen1900
Charles MasonGeorg-August-Universität Göttingen1903
Otto MühlendyckGeorg-August-Universität Göttingen1911
Johann MüllerGeorg-August-Universität Göttingen1902
Alexander MyllerGeorg-August-Universität Göttingen190674
Otto NeugebauerGeorg-August-Universität Göttingen192618
Charles NobleGeorg-August-Universität Göttingen1901
George PrangeGeorg-August-Universität Göttingen19151
Legh ReidGeorg-August-Universität Göttingen1899
Walther RosemannGeorg-August-Universität Göttingen1923
Gottfried RückleGeorg-August-Universität Göttingen1901
Ljubowj SapolskyGeorg-August-Universität Göttingen1900
Hans von SchaperGeorg-August-Universität Göttingen1898
Kurt SchellenbergGeorg-August-Universität Göttingen1915
Rudolf SchimmackGeorg-August-Universität Göttingen1908
Arnold SchmidtGeorg-August-Universität Göttingen19349
Erhard SchmidtGeorg-August-Universität Göttingen19057679
Kurt SchütteGeorg-August-Universität Göttingen1934148
Andreas SpeiserGeorg-August-Universität Göttingen190919
Władysław Hugo SteinhausGeorg-August-Universität Göttingen19111701
Gabriel SudanGeorg-August-Universität Göttingen1925
Teiji TakagiTokyo Imperial University1903400
Edgar TownsendGeorg-August-Universität Göttingen19002
Wilhelmus WestfallGeorg-August-Universität Göttingen19053
Hermann WeylGeorg-August-Universität Göttingen19081560
Willi WindauGeorg-August-Universität Göttingen1921
Otto ZollGeorg-August-Universität Göttingen1901

According to our current on-line database, David Hilbert has 75 students and 20387 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/7383.html000066400000000000000000000341331177514123300236440ustar00rootroot00000000000000 The Mathematics Genealogy Project - Władysław Hugo Steinhaus

Władysław Hugo Dyonizy Steinhaus

Biography


Ph.D. Georg-August-Universität Göttingen 1911 Germany
Dissertation: Neue Anwendungen des Dirichlet'schen Prinzips

Advisor: David Hilbert

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Stefan BanachUniversity of Lwów1920133
Z. W. (Bill) BirnbaumUniversity of Lwów192977
Stefan DrobotUniversity of Lwów193918
Henryk FastInstitute of Mathematics, Polish Academy of Science1958
Marek FiszPolitechnika Wrocławska19504
Mark KacUniversity of Lwów1937253
Józef ŁukaszewiczUniwersytet Wrocławski19577
Władysław OrliczUniversity of Lwów1928235
Aleksander RajchmanUniversity of Lwów1921988
Juliusz SchauderUniversity of Lwów1923
Stanislaw TrybulaUniwersytet Wrocławski1960, 196821

According to our current on-line database, Władysław Hugo Steinhaus has 11 students and 1701 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/79297.html000066400000000000000000000255621177514123300237470ustar00rootroot00000000000000 The Mathematics Genealogy Project - Henryk Fast

Henryk Fast

MathSciNet


Ph.D. Institute of Mathematics, Polish Academy of Science 1958 Poland
Dissertation:

Advisor: Władysław Hugo Dyonizy Steinhaus

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/79562.html000066400000000000000000000255021177514123300237340ustar00rootroot00000000000000 The Mathematics Genealogy Project - C. Ramalingam

C. S. Ramalingam


Ph.D. University of Rhode Island 1995 UnitedStates
Dissertation: Analysis of Non-Stationary, Multi-Component Signals with Application to Speech

Advisor: Ramdas Kumaresan

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/79568.html000066400000000000000000000302031177514123300237340ustar00rootroot00000000000000 The Mathematics Genealogy Project - Ramdas Kumaresan

Ramdas Kumaresan

MathSciNet


Ph.D. University of Rhode Island 1982 UnitedStates
Dissertation: Estimating the Parameters of Exponentially Damped or Undamped Sinusoidal Signals in Noise

Advisor: Donald Winston Tufts

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
C. RamalingamUniversity of Rhode Island1995
Yadong WangUniversity of Rhode Island2003

According to our current on-line database, Ramdas Kumaresan has 2 students and 2 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/79568583832.html000066400000000000000000000001421177514123300244300ustar00rootroot00000000000000

You have specified an ID that does not exist in the database. Please back up and try again.

Geneagrapher-master/tests/geneagrapher/testdata/84016.html000066400000000000000000000346141177514123300237260ustar00rootroot00000000000000 The Mathematics Genealogy Project - Stanislaw Trybula

Stanislaw Trybula

MathSciNet


Ph.D., Ph.D. Uniwersytet Wrocławski 1960, 1968 Poland
Dissertation: On Minmax Estimation, Sequential Estimation in Processes with Independent Increments
Mathematics Subject Classification: 62—Statistics

Advisor: Władysław Hugo Dyonizy Steinhaus

Students:
Click here to see the students listed in chronological order.

NameSchoolYearDescendants
Andrzej CegielskiPolitechnika Wrocławska19812
Andrzej GrzybowskiPolitechnika Wrocławska1991
Gabriel LemieszPolitechnika Wrocławska1979
Ryszard MagieraPolitechnika Wrocławska19761
Krzysztof OrlowskiPolitechnika Wrocławska1978
Zdzislaw PorosinskiPolitechnika Wrocławska1986
Tadeusz RadzikPolitechnika Wrocławska1978
Roman RozanskiUniwersytet Wrocławski1980
Magdalena RutkowskaPolitechnika Wrocławska1975
Antoni StyszynskiPolitechnika Wrocławska1976
Krzysztof SzajowskiPolitechnika Wrocławska19796
Maciej WilczyñskiPolitechnika Wrocławska1984

According to our current on-line database, Stanislaw Trybula has 12 students and 21 descendants.
We welcome any additional information.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/89841.html000066400000000000000000000256341177514123300237430ustar00rootroot00000000000000 The Mathematics Genealogy Project - Juliusz Schauder

Juliusz Pawel Schauder

Biography


Ph.D. University of Lwów 1923 Poland
Dissertation: A Bayesian Approach to the Design and Analysis of Case-Control Studies

Advisor: Władysław Hugo Dyonizy Steinhaus

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/99457.html000066400000000000000000000261231177514123300237410ustar00rootroot00000000000000 The Mathematics Genealogy Project - Yadong Wang

Yadong Wang

MathSciNet


Ph.D. University of Rhode Island 2003 UnitedStates
Dissertation: Representing Signals Using Only Timing Information and Feature Extraction for Automatic Speech Recognition
Mathematics Subject Classification: 94—Information and communication, circuits

Advisor: Ramdas Kumaresan

No students known.

If you have additional information or corrections regarding this mathematician, please use the update form. To submit students of this mathematician, please use the new data form.

Geneagrapher-master/tests/geneagrapher/testdata/999999999.html000066400000000000000000000001421177514123300243110ustar00rootroot00000000000000

You have specified an ID that does not exist in the database. Please back up and try again.

Geneagrapher-master/tests/geneagrapher/testdata/999999999999999999999.html000066400000000000000000000000421177514123300255640ustar00rootroot00000000000000Non-numeric id supplied. Aborting.Geneagrapher-master/tests/geneagrapher/testdata/end-to-end-30484000066400000000000000000000300001177514123300246740ustar00rootroot00000000000000a hэh^ hэh^(dp1 S'name' p2 VPeter Chris Pappas p3 sS'descendants' p4 c__builtin__ set p5 ((ltRp6 sS'timestamp' p7 F1325997041.716512 sS'advisors' p8 g5 ((lp9 I22617 atRp10 sS'year' p11 I1982 sS'institution' p12 VThe Pennsylvania State University p13 s.30484Geneagrapher-master/tests/geneagrapher/testdata/geneagrapher_verbose_cache_grabber_test000066400000000000000000000300001177514123300323050ustar00rootroot00000000000000a AW <}эh^   AW <}эh^(dp1 S'name' p2 VChristian Thomasius p3 sS'descendants' p4 c__builtin__ set p5 ((lp6 I127803 aI144155 atRp7 sS'timestamp' p8 F1325291597.5824139 sS'advisors' p9 g5 ((lp10 I137705 aI137717 atRp11 sS'year' p12 I1672 sS'institution' p13 Ns.127946Geneagrapher-master/tests/geneagrapher/testdata/get_data.py000066400000000000000000000014271177514123300244740ustar00rootroot00000000000000import urllib2 if __name__ == '__main__': record_ids = [7298, 7383, 10275, 12681, 15165, 17851, 17946, 18230, 18231, 18232, 18233, 18603, 19953, 19964, 28292, 29458, 29642, 30484, 36991, 47064, 51261, 51907, 52965, 52996, 53658, 55175, 62547, 79297, 79562, 79568, 84016, 89841, 99457, 127470, 127946, 137705, 137717, 143630, 151876, 999999999, 79568583832] for record_id in record_ids: url_base = 'http://genealogy.math.ndsu.nodak.edu/id.php?id=' url = '{0}{1}'.format(url_base, record_id) print 'Getting record {}'.format(record_id) page = urllib2.urlopen(url) with open('{}.html'.format(record_id), 'w') as fout: fout.write(page.read())