Examples

This page collects several simple code examples which use ged4py.

Example 1

Trivial example of opening the file, iterating over INDI records (which produces Individual instances) and printing basic information for each person. format() method is used to produce printable representation of a name, though this is only one of possible ways to format names. Method sub_tag_value() is used to access the values of subordinate tags of the record, it can follow many levels of tags.

import sys
from ged4py.parser import GedcomReader

# open GEDCOM file
with GedcomReader(sys.argv[1]) as parser:
    # iterate over each INDI record in a file
    for i, indi in enumerate(parser.records0("INDI")):
        # Print a name (one of many possible representations)
        print(f"{i}: {indi.name.format()}")

        father = indi.father
        if father: 
            print(f"    father: {father.name.format()}")

        mother = indi.mother
        if mother: 
            print(f"    mother: {mother.name.format()}")

        # Get _value_ of the BIRT/DATE tag
        birth_date = indi.sub_tag_value("BIRT/DATE")
        if birth_date:
            print(f"    birth date: {birth_date}")

        # Get _value_ of the BIRT/PLAC tag
        birth_place = indi.sub_tag_value("BIRT/PLAC")
        if birth_place:
            print(f"    birth place: {birth_place}")

Example 2

This example iterates over FAM records in the file which represent family structure. FAM records do not have special record type so they produce generic Record instances. This example shows the use of sub_tag() method which can dereference pointer records contained in FAM records to retrieve corresponding INDI records.

import sys
from ged4py.parser import GedcomReader

with GedcomReader(sys.argv[1]) as parser:
    # iterate over each FAM record in a file
    for i, fam in enumerate(parser.records0("FAM")):

        print(f"{i}:")

        # Get records for spouses, FAM record contains pointers to INDI
        # records but sub_tag knows how to follow the pointers and return
        # the referenced records instead.
        husband, wife = fam.sub_tag("HUSB"), fam.sub_tag("WIFE")
        if husband: 
            print(f"    husband: {husband.name.format()}")
        if wife: 
            print(f"    wife: {wife.name.format()}")

        # Get _value_ of the MARR/DATE tag
        marr_date = fam.sub_tag_value("MARR/DATE")
        if marr_date:
            print(f"    marriage date: {marr_date}")

        # access all CHIL records, sub_tags method returns list (possibly empty)
        children = fam.sub_tags("CHIL")
        for child in children:
            # print name and date of birth
            print(f"    child: {child.name.format()}")
            birth_date = child.sub_tag_value("BIRT/DATE")
            if birth_date:
                print(f"        birth date: {birth_date}")

Example 3

This example shows how to specialize date formatting. Date representation in different calendars is a very complicated topic and ged4py cannot solve it in any general way. Instead it gives clients an option to specialize date handling in whatever way clients prefer. This is done by implementing DateValueVisitor interface and passing a visitor instance to ged4py.date.DateValue.accept() method. For completeness one also has to implement CalendarDateVisitor to format or do anything else to the instances of CalendarDate, this is not shown in the example.

import sys
from ged4py.parser import GedcomReader
from ged4py.date import DateValueVisitor


class DateFormatter(DateValueVisitor):
    """Visitor class that produces string representation of dates.
    """
    def visitSimple(self, date):
        return f"{date.date}"

    def visitPeriod(self, date):
        return f"from {date.date1} to {date.date2}"

    def visitFrom(self, date):
        return f"from {date.date}"

    def visitTo(self, date):
        return f"to {date.date}"

    def visitRange(self, date):
        return f"between {date.date1} and {date.date2}"

    def visitBefore(self, date):
        return f"before {date.date}"

    def visitAfter(self, date):
        return f"after {date.date}"

    def visitAbout(self, date):
        return f"about {date.date}"

    def visitCalculated(self, date):
        return f"calculated {date.date}"

    def visitEstimated(self, date):
        return f"estimated {date.date}"

    def visitInterpreted(self, date):
        return f"interpreted {date.date} ({date.phrase})"

    def visitPhrase(self, date):
        return f"({date.phrase})"


format_visitor = DateFormatter()

with GedcomReader(sys.argv[1]) as parser:
    # iterate over each INDI record in a file
    for i, indi in enumerate(parser.records0("INDI")):
        print(f"{i}: {indi.name.format()}")

        # get all possible event types and print their dates,
        # full list of events is longer, this is only an example
        events = indi.sub_tags("BIRT", "CHR", "DEAT", "BURI", "ADOP", "EVEN")
        for event in events:
            date = event.sub_tag_value("DATE")
            # Some event types like generic EVEN can define TYPE tag
            event_type = event.sub_tag_value("TYPE")
            # pass a visitor to format the date
            if date:
                date_str = date.accept(format_visitor)
            else:
                date_str = "N/A"
            print(f"    event: {event.tag} date: {date_str} type: {event_type}")