python - Looping dictionary values -


i have program reads text file , answers set of queries based on input inside. serves figure out mothers of children questioned. i'm taking 1 step further , reprocessing these outputs provided display full family tree.

this text file containing parents on left hand side , kids on right. below queries being asked, followed outputs.

sue: chad, brenda, harris charlotte: tim brenda: freddy, alice alice: john, dick, harry  mother sue ancestors harry ancestors bernard ancestors charlotte  >>> mother not known >>> alice, brenda, sue >>> unknown person >>> no known ancestors 

the program able work out mother (thanks kampu help) i'm trying understand how take value , perhaps append new list or dictionary indefinitely looped find possible grandparents.

def lookup_ancestor(child):     ancestor = reverse_map.get(child)     if ancestor:         ancestor_list_add.append(ancestor)     if ancestor not in lines[0:]:         print("unknown person")     else:         print("no known ancestors") 

this have far, reverse_map has each child mapped parent in dictionary. i'm placing parents new list plan run again figure out their parents are. i'm stuck @ point can't find elegant way perform whole process without creating 3 new lists keep looping over. way it's setup @ moment, i'm assuming i'd need either append them via for loop or split() values afterwards keep values each other. ideally, i'd learn how loop process , find out each questions ancestors are.

i feel if have grasp on how should possibly knowledge of python prevents trial , error method being time efficient..

any appreciated!

edit: link - http://pastebin.com/vmpt1gvx

edit 2:

def process_commands(commands, relation_dict):     '''processes output'''     output = []     c in commands:          coms = c.split()         if len(coms) < 2:              output.append("invalid command")             continue         action = coms[0]         param = coms[1]  def mother_lookup(action, param, relation_dict):     output_a = []     if action == "mother":          name_found = search_name(relation_dict, param)         if not name_found:              output_a.append("unknown person")         else:              person = find_parent(relation_dict, param)             if person none:                  output_a.append("mother not known")             else:                  output_a.append(person)     return output_a  def ancestor_lookup(action, param, relation_dict):     output_b = []     if action == "ancestors":          name_found = search_name(relation_dict, param)         if not name_found:              output_b.append("unknown person")         else:              ancestor_list = []             person = param             while true:                  person = find_parent(relation_dict, person)                 if person == none:                      break                 else:                      ancestor_list.append(person)                 if ancestor_list:                      output_b.append(", ".join(ancestor_list))                 else:                      output_b.append("no known ancestors")     return output_b  def main():     '''definining file , outputting it'''     file_name = 'relationships.txt'     relations,commands = read_file(file_name)     #process relqations form dictionary of type      #{parent: [child1,child2,...]}     relation_dict = form_relation_dict(relations)     #now process commands in file     action = process_commands(commands, relation_dict)     param = process_commands(commands, relation_dict)     output_b = ancestor_lookup(action, param, relation_dict)     output_a = mother_lookup(action, param, relation_dict)     print('\n'.join(output_a))     print ('\n'.join(output_b))   if __name__ == '__main__':      main() 

as @nulluserexception said, tree (or resembling it) choice. answer posting quite different track have chosen problem.

you can define person object knows name , keeps track of parent is. parent isn't name person object! (kinda linked list). can keep collection of people single list.

while parsing file, keep adding people list while @ same time updating children/parent attribute correct objects.

later given person, matter of printing attributes find relationships

the following possible implementation (on python-2.6). text file in case contains relationships. queries later fired using interactive input

class person(object):      """information single name"""     def __init__(self,name):          self.name = name         self.parent = none         self.children = []  def search_people(people,name):      """searches name in known people , returns corresponding person object or none if not found"""     try:          return filter(lambda y: y.name == name,people)[0]     except indexerror:          return none  def search_add_and_return(people,name):      """search name in list of people. if not found add people. return person object in either case"""     old_name = search_people(people,name)     if old_name none:          #first time entry name         old_name = person(name)         people.append(old_name)     return old_name  def read_file(file_name,people):      fp = open(file_name,'r')     while true:          l = fp.readline()         l.strip('\n').strip()         if not l:              break         names = l.split(':')         mother = names[0].strip()         children = [x.strip() x in names[1].split(',')]         old_mother = search_add_and_return(people,mother)         #now children objects         child_objects = []         child in children:              old_child = search_add_and_return(people,child)             child_objects.append(old_child)         #all children have been gathered. link them         #set parent in child , add child parent's 'children'         old_mother.children.extend(child_objects)         c in child_objects:              c.parent = old_mother     fp.close()   def main():      file_name = 'try.txt'     people = []     read_file(file_name,people)      #now lets define language , start loop     while true:          command = raw_input("enter command or 0 quit\n")         if command == '0':              break         coms = command.split()         if len(coms) < 2:              print "wrong command"             continue         action = coms[0]         param = coms[1]         if action == "mother":              person = search_people(people,param)             if person == none:                  print "person not found"                 continue             else:                  if person.parent none:                      print "mother not known"                 else:                      print person.parent.name         elif action == "ancestors":              person = search_people(people,param)             if person == none:                  print "person not found"                 continue             else:                  ancestor_list = []                 #need keep looking parent till don't reach dead end                 #and collect names of each ancestor                 while true:                      person = person.parent                     if person none:                          break                     ancestor_list.append(person.name)                 if ancestor_list:                      print ",".join(ancestor_list)                     else:                      print "no known ancestors"  if __name__ == '__main__':      main() 

edit

since keep things simple, here way of using dictionaries (a single dictionary) want

the basic idea following. parse file form dictionary key mother , values list of children. when sample file parsed, dictionary like

relation_dict = {'charlotte': ['tim'], 'sue': ['chad', 'brenda', 'harris'], 'alice': ['john', 'dick', 'harry'], 'brenda': ['freddy', 'alice']} 

to find parent search if name in dictionary values , return key if found. if no mother found, return none

mother = none k,v in relation_dict.items():      if name in v:          mother = k         break return mother 

if want find ancestors, you'll need repeat process till none returned

ancestor_list = [] person = name while true:      person = find_parent(relation_dict,person)     if person == none:          #top of ancestor chain found         break     else:          ancestor_list.append(person) 

here's implementation in python-2.6. assumes text file structured such first there relations, blank line , commands.

def read_file(file_name):      fp = open(file_name,'r')     relations = []     commands = []     reading_relations = true     l in fp:          l = l.strip('\n')         if not l:              reading_relations = false             continue         if reading_relations:                  relations.append(l.strip())         else:              commands.append(l.strip())     fp.close()     return relations,commands  def form_relation_dict(relations):      relation_dict = {}     l in relations:          names = l.split(':')         mother = names[0].strip()         children = [x.strip() x in names[1].split(',')]         existing_children = relation_dict.get(mother,[])         existing_children.extend(children)         relation_dict[mother] = existing_children     return relation_dict  def search_name(relation_dict,name):      #returns true if name occurs anywhere in relation_dict     #else return false     k,v in relation_dict.items():          if name ==k or name in v:              return true     return false  def find_parent(relation_dict,param):      #finds parent of 'param' in relation_dict     #returns none if no mother found     #returns mother name otherwise     mother = none     k,v in relation_dict.items():          if param in v:              mother = k             break     return mother  def process_commands(commands,relation_dict):      output = []     c in commands:          coms = c.split()         if len(coms) < 2:              output.append("invalid command")             continue         action = coms[0]         param = coms[1]         if action == "mother":              name_found = search_name(relation_dict,param)             if not name_found:                  output.append("person not found")                 continue             else:                  person = find_parent(relation_dict,param)                 if person none:                      output.append("mother not known")                 else:                      output.append("mother - %s" %(person))         elif action == "ancestors":              name_found = search_name(relation_dict,param)             if not name_found:                  output.append("person not found")                 continue             else:                  #loop through find mother till dead - end (none) not reached                 ancestor_list = []                 person = param                 while true:                      person = find_parent(relation_dict,person)                     if person == none:                          #top of ancestor found                         break                     else:                          ancestor_list.append(person)                 if ancestor_list:                      output.append(",".join(ancestor_list))                 else:                      output.append("no known ancestors")     return output  def main():      file_name = 'try.txt'     relations,commands = read_file(file_name)     #process relqations form dictionary of type {parent: [child1,child2,...]}     relation_dict = form_relation_dict(relations)     print relation_dict     #now process commands in file     output = process_commands(commands,relation_dict)     print '\n'.join(output)   if __name__ == '__main__':      main() 

output sample input is

mother not known alice,brenda,sue person not found no known ancestors 

edit2

if want split further functions, here's how process_commands should look

def process_mother(relation_dict,name):      #processes mother command     #returns ouput string     output_str = ''     name_found = search_name(relation_dict,name)     if not name_found:          output_str = "person not found"     else:          person = find_parent(relation_dict,name)         if person none:              output_str = "mother not known"         else:              output_str = "mother - %s" %(person)     return output_str  def process_ancestors(relation_dict,name):      output_str = ''     name_found = search_name(relation_dict,name)     if not name_found:          output_str = "person not found"     else:          #loop through find mother till dead - end (none) not reached         ancestor_list = []         person = name         while true:              person = find_parent(relation_dict,person)             if person == none:                  #top of ancestor found                 break             else:                  ancestor_list.append(person)         if ancestor_list:              output_str = ",".join(ancestor_list)         else:              output_str = "no known ancestors"     return output_str  def process_commands(commands,relation_dict):      output = []     c in commands:          coms = c.split()         if len(coms) < 2:              output.append("invalid command")             continue         action = coms[0]         param = coms[1]         if action == "mother":              new_output = process_mother(relation_dict,param)         elif action == "ancestors":              new_output = process_ancestors(relation_dict,param)         if new_output:              output.append(new_output)         return output 

Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -