From: naath Date: Sun, 13 Apr 2014 10:23:22 +0000 (+0100) Subject: faff with graphs and searching X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~naath/git?a=commitdiff_plain;h=69474c9103a0f5c77d499a103d30bc9e23cd116e;p=familyTree.git faff with graphs and searching --- diff --git a/cgiFiles/ancestorGraph.py b/cgiFiles/ancestorGraph.py index 327754a..6c633e0 100755 --- a/cgiFiles/ancestorGraph.py +++ b/cgiFiles/ancestorGraph.py @@ -30,7 +30,7 @@ def add_parents(ID,Self): def make_graph(ID): global allAncestors - d.start_dot() + d.start_dot(8) Self = aQ.find_person(ID)[0] diff --git a/cgiFiles/bigGraph.py b/cgiFiles/bigGraph.py index 8834ba1..c98d294 100755 --- a/cgiFiles/bigGraph.py +++ b/cgiFiles/bigGraph.py @@ -18,7 +18,7 @@ conn = askQuestion.connect() famTree = askQuestion.list_people_parents() -d.start_dot() +d.start_dot(8) for i in range(len(famTree)): #for i in range(100): self = famTree[i][0] diff --git a/cgiFiles/jointAncestorGraph.py b/cgiFiles/jointAncestorGraph.py index 01a6319..7fdadd0 100755 --- a/cgiFiles/jointAncestorGraph.py +++ b/cgiFiles/jointAncestorGraph.py @@ -32,19 +32,95 @@ def add_parents(ID,name,startLevel,stopLevel): d.add_marriage(pair[0], pair[1],[name],1) -def make_graph(ID,ID2,LA,LB): +def find_oneside_path(ID,start,stop): + global myP + global myC + + start = start + 1 + if start == stop+1: + return + + [parents, parentIDs,parentNames] = aQ.find_parents(ID) + + for i in parentIDs: + myP.append(i) + myC.append(ID) + + for i in range(len(parents)): + if parentIDs[i]!=0: + newID = parentIDs[i] + find_oneside_path(newID,start,stop) + +def find_path(ID,ID2,LA,LB): + global myP + global myC + + myP = [] + myC = [] + find_oneside_path(ID,0,int(LA)) + aP = myP + [ID] + aC = myC + [ID] + myP = [] + myC = [] + find_oneside_path(ID2,0,int(LB)) + bP = myP + [ID2] + bC = myC +[ID2] + + z = set([0]) + cA = set(aP).intersection(set(bP)) + cA = cA.difference(z) + + for a in cA: + i = aP.index(a) + c = aC[i] - d.start_dot() + while c!=ID: + + [parents, parentIDs,parentNames] = aQ.find_parents(c) + s = aQ.find_person(c)[0] + + d.add_marriage(parents[0],parents[1],[s],1) + + + i = aP.index(c) + c = aC[i] + + [parents, parentIDs,parentNames] = aQ.find_parents(c) + s = aQ.find_person(c)[0] + + d.add_marriage(parents[0],parents[1],[s],1) + + for a in cA: + i = bP.index(a) + c = bC[i] + + while c!=ID2: + [parents, parentIDs,parentNames] = aQ.find_parents(c) + s = aQ.find_person(c)[0] + + d.add_marriage(parents[0],parents[1],[s],1) + i = bP.index(c) + c = bC[i] + [parents, parentIDs,parentNames] = aQ.find_parents(c) + s = aQ.find_person(c)[0] + + d.add_marriage(parents[0],parents[1],[s],1) + +def make_graph(ID,ID2,LA,LB): + d.start_dot(8) + done = 0 - if int(LA)!=0: - [Self, selfID, selfName] = aQ.find_person(ID) - d.add_highlight(Self) - add_parents(selfID,Self,0,LA) + find_path(ID,ID2,LA,LB) - if int(LB)!=0: - [Self, selfID, selfName] = aQ.find_person(ID2) - d.add_highlight(Self) - add_parents(selfID,Self,0,LB) +# if int(LA)!=0: +# [Self, selfID, selfName] = aQ.find_person(ID) +# d.add_highlight(Self) +# add_parents(selfID,Self,0,LA) +# +# if int(LB)!=0: +# [Self, selfID, selfName] = aQ.find_person(ID2) +# d.add_highlight(Self) +# add_parents(selfID,Self,0,LB) d.add_subgraphs() d.end_dot() diff --git a/cgiFiles/make_dot.py b/cgiFiles/make_dot.py index 9c9e20b..8006a79 100755 --- a/cgiFiles/make_dot.py +++ b/cgiFiles/make_dot.py @@ -60,22 +60,21 @@ def add_marriage(n1,n2,children,joinChildren): if len(children)>0 and joinChildren==1: cNode = jN + 'c' - e = [cNode,children[0]] - if has_node(cNode): - tcNode = cNode + children[0] - if len(cNodes[cNode])>0: - last = cNodes[cNode][-1] - else: - last = cNode - add_spot(tcNode) - cNodes[cNode].append(tcNode) - add_no_arrow(last,tcNode) - add_subgraph([tcNode,cNode]) + tcNode = cNode + children[0] + + if cNodes.has_key(cNode): + if not has_node(tcNode): + if len(cNodes[cNode])>0: + last = cNodes[cNode][-1] + add_spot(tcNode) + cNodes[cNode].append(tcNode) + add_no_arrow(last,tcNode) + add_subgraph([tcNode,last]) else: - tcNode = cNode - add_spot(cNode) - cNodes[cNode] = [] - add_no_arrow(jN,cNode) + add_spot(tcNode) + cNodes[cNode] = [tcNode] + add_no_arrow(jN,tcNode) + elif len(children)>0: tcNode = jN @@ -108,7 +107,7 @@ def end_dot(): global dot dot = dot + "}" -def start_dot(): +def start_dot(fs): global dot global nodes global edges @@ -120,7 +119,7 @@ def start_dot(): dot = "digraph G{\n" dot = dot + "ranksep = 0.5 nodesep = 0\n" subgraphs=[] - set_attr() + set_attr(fs) def add_highlight(name): add_node(name,highlight_attr) @@ -132,7 +131,7 @@ def add_spot(name): add_node(name,spot_attr) -def set_attr(): +def set_attr(fs): global person_attr global highlight_attr global spot_attr @@ -144,7 +143,7 @@ def set_attr(): global debug_attr global debug_edge_attr zero_size = [('width','0'),('height','0')] - person_attr = [('fontsize','8'),('shape','plaintext')] + zero_size + person_attr = [('fontsize',str(fs)),('shape','plaintext')] + zero_size highlight_attr = person_attr + \ [('fontcolor','red'),('shape','box'),('color','red')] debug_attr = person_attr + [('fontcolor','green')] diff --git a/cgiFiles/searchname.py b/cgiFiles/searchname.py index c798321..b248448 100755 --- a/cgiFiles/searchname.py +++ b/cgiFiles/searchname.py @@ -7,35 +7,92 @@ import cgitb import sys import re sys.path.append('/home/naath/familyTreeProject/familyTree') -import askQuestion +import askQuestion as aQ import everyPage + +def make_drop_down(n, IDs, Names): + if n==1: + formName = 'ID' + else: + formName = 'ID' + str(n) + + dd=\ + "Person "+str(n)+": " + + return dd + cgitb.enable() [conn,form]=everyPage.top() name = form.getvalue('name') -if name == None: - printMe = "
" - printMe = printMe + \ - "Search for:
" - printMe = printMe +"" - printMe = printMe + "
" +name2 = form.getvalue('name2') - everyPage.good(printMe) +thisName = '' +nameA='' +nameB='' +if name2==None and name !=None: + thisName = name +elif name2!=None and name!=None: + nameA = name + nameB = name2 + +oneSearch = "Search for people by name"+\ +"" + +pairSearch = "Search for pairs of people"+\ +" to find joint ancestors"+\ +"" +if name == None: + printMe = oneSearch + pairSearch + + everyPage.good(printMe) -else: +elif name2 ==None: result = re.match('[a-zA-z-% ]*$', name) if result == None: everyPage.bad() else: - printMe = askQuestion.search_name(name,'
') + printMe = \ + aQ.search_name(name,'
')[0] if len(printMe)<10: printMe = 'sorry, no data
' + printMe = printMe + '
' + oneSearch + pairSearch everyPage.good(printMe) +else: + + [out1,names1,IDs1] = aQ.search_name(name,'
') + [out2,names2,IDs2] = aQ.search_name(name2,'
') + + printMe = \ + "
"+\ + make_drop_down(1,IDs1,names1)+\ + "
"+\ + make_drop_down(2,IDs2,names2)+\ + "


"+\ + "
"+\ + oneSearch+ pairSearch + + everyPage.good(printMe) + everyPage.bottom(conn) + diff --git a/cgiFiles/smallGraph.py b/cgiFiles/smallGraph.py index 393d6df..b1bc179 100755 --- a/cgiFiles/smallGraph.py +++ b/cgiFiles/smallGraph.py @@ -8,44 +8,80 @@ sys.path.append('/home/naath/familyTreeProject/familyTree') import askQuestion as aQ cgitb.enable() - -#def make_graph(Self,parents,children,otherparents,spouses): -def make_graph(ID): - - d.start_dot() - +def add_parents(ID,s,cl,pl,pos,os): Self = aQ.find_person(ID)[0] - - d.add_highlight(Self) [parents, parentIDs,parentNames] = aQ.find_parents(ID) - countSame = 2; - for i in range(1,len(parents)): - if parents[i]==parents[i-1]: - parents[1]=parents[1] + ' '+str(countSame) - countSame = countSame +1 + if s==0: + d.add_marriage(parents[0],parents[1],[Self],1) + + else: + for p in parentIDs: + if p!=0: + add_children(p,cl+1,os) + if pl>1: + for p in parentIDs: + if p!=0: + add_parents(p,s,cl,pl-1,pos,os) + + if pos==1: + for p in parentIDs: + if p!=0: + add_spouses(p,os,cl) + + +def add_children(ID,cl,os): + Self = aQ.find_person(ID)[0] - d.add_marriage(parents[0],parents[1],[Self],1) - [children,childrenID,childrenNames\ - ,otherparents,otherparentsID,otherParentsNames\ - ,childrenBorn] = \ + [nodes,IDs,names,childrenBorn] = \ aQ.find_children(ID) - for i in range(len(otherparents)): - c = children[i] - op = otherparents[i] + children=[] + for n in nodes: + c = n[0] + children.append(c) + op = n[1] d.add_marriage(Self,op,[c],1) - + + #d.subgraphs.append(children) + + if cl>1: + for c in IDs: + add_children(c[0],cl-1,os) + add_spouses(c[0],os,cl-1) + +def add_spouses(ID,os,cl): + Self = aQ.find_person(ID)[0] + [spouses,spousesID,spousesNames] = aQ.find_spouses(ID) - for i in range(len(spouses)): - s = spouses[i] + for s in spouses: d.add_marriage(Self,s,[],1) + + + if os==1: + for s in spousesID: + if s!=0: + add_spouses(s,0,cl) + add_children(s,cl,os) + +def make_graph(ID,v,fs): + pl = v[0] + cl = v[1] + s = v[2] + os = v[3] + pos = v[4] + d.start_dot(fs) + Self = aQ.find_person(ID)[0] + + d.add_highlight(Self) - d.subgraphs.append(children) + add_parents(ID,s,cl,pl,pos,os) + add_children(ID,cl,os) + add_spouses(ID,os,cl) d.add_subgraphs() @@ -53,11 +89,40 @@ def make_graph(ID): d.render_dot() +def check_int(s): + try: + return int(s) + except ValueError: + return 1 form = cgi.FieldStorage() ID = form.getvalue('ID') + +variables = ['pl', 'cl', 's', 'os', 'pos'] +values=[] +for s in variables: + values.append(form.getvalue(s)) + +for i in range(len(values)): + v = values[i] + if v == None: + v = 0 + v = check_int(v) + if v<0: + v=0 + values[i] = v + +fs = form.getvalue('fs') +if fs==None: + fs=8 +fs = check_int(fs) +if fs==1: + fs=8 + conn = aQ.connect() -make_graph(ID) +make_graph(ID,values,fs) aQ.close(conn) + + diff --git a/familyTree/askQuestion.py b/familyTree/askQuestion.py index c6273cc..ecf810a 100755 --- a/familyTree/askQuestion.py +++ b/familyTree/askQuestion.py @@ -3,6 +3,7 @@ import sqlite3 import findYear from string import Template +import cgi global link_Template link_Template= Template(\ @@ -342,28 +343,35 @@ def search_name(name,newLine): +" WHERE name LIKE ?;" out = '' + IDs=[] + names=[] - out = out + 'Names start with ' + name + ':' + newLine + out = out + 'Names starting with ' + name + ':' + newLine t = (name + '%',) fullIDs=[] for row in run_query(s,t): out = out + name_html(row,newLine) + newLine fullIDs.append(row[1]) + names.append(row[0]) + IDs.append(row[1]) + t = ('%' + name + '%',) - out = out+newLine + 'Names contain ' + name + ':' + newLine + out = out+newLine + 'Names containing ' + name + ':' + newLine for row in run_query(s,t): if row[1] not in fullIDs: out = out + name_html(row,newLine) + newLine + names.append(row[0]) + IDs.append(row[1]) s = "SELECT name,people.ID,style"\ +" FROM people INNER JOIN styles"\ +" ON styles.id = people.id"\ +" WHERE style LIKE ?;" - out = out +newLine+ 'Styles contain ' + name + ':' + newLine + out = out +newLine+ 'Styles containing ' + name + ':' + newLine for row in run_query(s,t): out = out + name_html(row,newLine)+' ' + row[2] + newLine - return out + return [out,names,IDs] def people_with_name(name,newLine): @@ -493,8 +501,6 @@ def all_ancestors(personID,newLine): for row in run_query(t,id): out = out + name_html(row,newLine)+newLine - aDict={} - aDict[level] = ancestors while len(ancestors)>0: level = level+1 newA =[] @@ -515,14 +521,12 @@ def all_ancestors(personID,newLine): trackLevel.append(level) ancestors = newA - if len(ancestors)>0: - aDict[level]=ancestors out = out+thisout image = "" out = out+newLine + image+newLine - return [out, allAncestors,trackLevel,aDict] + return [out, allAncestors,trackLevel] def common_ancestors(IDA, IDB,newLine): @@ -613,13 +617,6 @@ def common_ancestors(IDA, IDB,newLine): out = out + ' of ' + name_html([names[0],IDA],newLine)+newLine - #out = out + newLine - #for b in indexB: - # t = (common[b],) - # out = out + print_tagged_query('',s,t,newLine) - # if b!=indexB[-1]: - # out = out + 'and' + newLine - out = out + parent_level(bLevels[indexB[0]],'parent') if len(indexB)>1: out = out + 's' @@ -815,56 +812,56 @@ def find_children(ID): t = (ID,ID) - children =[] - childrenID=[] - childrenNames=[] childrenBorn=[] - otherparents=[] - otherparentsID=[] - otherparentsNames=[] + nodes=[] + IDs=[] + names=[] for row in run_query(s,t): c = row[0] + ',' + str(row[1]) cID = row[1] cName = row[0] born = row[4] - children.append(c) - childrenID.append(cID) - childrenNames.append(cName) childrenBorn.append(born) if row[3]!=None: op = row[3] + ',' + str(row[2]) opID = row[2] opN = row[3] else: - op = row[2] + ',s ' + ID + op = row[2] + ',s ' + str(ID) opID = 0 opN = row[2] - otherparents.append(op) - otherparentsID.append(opID) - otherparentsNames.append(opN) - return [children,childrenID,childrenNames\ - ,otherparents,otherparentsID,otherparentsNames\ - ,childrenBorn] + nodes.append([c,op]) + IDs.append([cID,opID]) + names.append([cName,opN]) + + return [nodes,IDs,names,childrenBorn] def person_info(personID,newLine): t = (personID,) + if newLine=='
': + startP = '

' + endP = '

' + else: + startP = '' + endP = newLine + mainDiv = '' #Id, Name, Dates, Style, Style-Dates s = "SELECT * FROM people WHERE ID = ?" for row in run_query(s,t): - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP mainDiv = mainDiv + 'ID: '+str(row[0]) +newLine mainDiv = mainDiv + print_tagged_name('Name',[row[1], row[0]]\ ,newLine) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + endP name = row[1] url = row[9] picture = row[10] - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP mainDiv = mainDiv + newLine + 'Born: '+row[3] + newLine bornYear = row[4] mainDiv = mainDiv + 'Died: '+row[5] @@ -872,12 +869,12 @@ def person_info(personID,newLine): if row[6] != 0 and row[4] !=0: mainDiv = mainDiv + ", aged " \ +str(row[6]-row[4]) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + endP s = "SELECT * FROM styles WHERE ID = ?" for row in run_query(s,t): - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP mainDiv = mainDiv +newLine+ 'Style: '+row[1] + newLine mainDiv = mainDiv + 'Territories:' + newLine @@ -898,12 +895,12 @@ def person_info(personID,newLine): mainDiv = mainDiv + 'From: '+row[2] + newLine mainDiv = mainDiv + 'To: '+row[4] - mainDiv = mainDiv + '

' + mainDiv = mainDiv + endP - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP s = "SELECT people.Name,consort "\ +"FROM consorts LEFT JOIN people"\ +" ON people.ID = consorts.consort"\ @@ -911,22 +908,22 @@ def person_info(personID,newLine): for row in run_query(s,t): mainDiv = mainDiv + print_tagged_name\ ('Consort of',row,newLine) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + endP #find parents [parents,parentIDs,parentNames] = find_parents(personID) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP for i in range(len(parents)): r = [parentNames[i],parentIDs[i]] mainDiv = mainDiv + print_tagged_name('Parent',r,newLine) - mainDiv = mainDiv + "

" + mainDiv = mainDiv + endP #find spouses [spouses,spousesID,spousesNames] = find_spouses(personID) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + startP for i in range(len(spouses)): r = [spousesNames[i],spousesID[i]] @@ -934,24 +931,22 @@ def person_info(personID,newLine): mainDiv = mainDiv + \ relationship_html(personID,r[1],newLine) - mainDiv = mainDiv + '

' + mainDiv = mainDiv + endP #find children - [children,childrenID,childrenNames\ - ,otherparents,otherparentsID,otherparentsNames\ - ,childrenBorn] = \ + [nodes,IDs,names,childrenBorn] = \ find_children(personID) top = '' - for i in range(len(children)): - cr = [childrenNames[i],childrenID[i]] + for i in range(len(nodes)): + cr = [names[i][0],IDs[i][0]] thisChild = print_tagged_name('Child',cr,newLine) - opr=[otherparentsNames[i],otherparentsID[i]] - top = otherparentsNames[i] - if i==0 or top != otherparentsNames[i-1]: - mainDiv = mainDiv +'

' - mainDiv = mainDiv + '

' + opr=[names[i][1],IDs[i][1]] + top = names[i][1] + if i==0 or top != names[i-1][1]: + mainDiv = mainDiv +endP + mainDiv = mainDiv + startP mainDiv = mainDiv + print_tagged_name\ ('With',opr, newLine) @@ -964,42 +959,113 @@ def person_info(personID,newLine): " at the age of "+str(age) + newLine mainDiv = mainDiv + thisChild - mainDiv = mainDiv + '

' - - output = '
'; - output = output + mainDiv + "
" + mainDiv = mainDiv + endP - output = output + "
" - - imageDiv = '' - if picture!='.': - imageDiv = imageDiv + ""\ - +"wiki link"\ - + newLine - - elif url!='.' and url!='. ': - imageDiv = imageDiv + ""\ - +name + " (wiki link)"+newLine - - output = output + imageDiv + "
" - - graph = "smallGraph.py?ID="+str(personID) - - graph ="" - output = output + graph - output = output + "" + if newLine == '
': + output = '
'; + output = output + mainDiv + "
" + + output = output + "
" + + imageDiv = '' + if picture!='.': + imageDiv = imageDiv + ""\ + +"wiki link"\ + + newLine + + elif url!='.' and url!='. ': + imageDiv = imageDiv + ""\ + +name + " (wiki link)"+newLine + + output = output + imageDiv + "
" + + + url = 'http://www.chiark.greenend.org.uk/ucgi/~naath/'\ + +'smallGraph.py' + + form = '' + form = form + "
" + + form = form +\ + "
" + + form = form +\ + "Generations of Parents: "\ + +"" + form = form + newLine + form = form + \ + "Generations of Children: "\ + +" " + form = form + newLine + form = form + \ + "Show siblings: " + form = form + newLine + form = form + \ + "Show spouse's other spouses: " + form = form + newLine + form = form + \ + "Show parents' other spouses: " + form = form + newLine + form = form + \ + "Fount size: "+\ + "" + form = form + newLine + form = form + "
" + + graph = "smallGraph.py?ID="+str(personID)+"&fs=8" + + graph = "" + output = output + "

"+graph+"

" + output = output + "Draw this graph with more relatives:" + output = output + newLine + form + + output = output + "" + + output = output + "" + + output = output +\ + '' + else: + output = mainDiv return output def connect(): global conn - conn = sqlite3.connect('/home/naath/familyTreeProject/familyTree/tree.db') + conn = sqlite3.connect\ + ('/home/naath/familyTreeProject/familyTree/tree.db') return conn def make_cursor(): @@ -1008,13 +1074,3 @@ def make_cursor(): def close(conn): conn.close -#def main(): - -# [c, conn] = connect() -# -# person_info(1,c) -# person_info(17,c) -# person_info(38,c) -# person_info(90,c) -# -# close(conn) diff --git a/familyTree/notes b/familyTree/notes index 61295ee..553a123 100644 --- a/familyTree/notes +++ b/familyTree/notes @@ -14,3 +14,6 @@ fl.c. means "flourish circa" and should not be confused with "born circa" see especially Edith of Mercia Sigehelm (163) was NOT MARRIED TO Prince Edward (162) + +Check cousin marriages against: +http://en.wikipedia.org/wiki/List_of_coupled_cousins#Royalty