# Lillian Lee, LJL2, April 2021

"""Quick and dirty code for 2019SP prelim 2 questions."""

import copy # for checking no change in input



##################
# Q2(a)
def find_max(my_list):
    pass

# some testing code
print("Checking find_max")
testcases = [
    # format: (input, output)
    ([0], 0),
    ([4,0,12], 12),
    ([-4,-10,-2], -2)
    ]

for item in testcases:
    (inlist, expected) = item
    origlist = copy.deepcopy(inlist)

    error_msg_start = "find_max problem " # prepare for any errors
    error_msg_start += "on input " + str(repr(inlist)) + ": "

    result = find_max(inlist)
    
    # didn't change original list
    assert inlist == origlist, \
        error_msg_start + "input list was changed! It's now " + repr(inlist)

    # check values are correct
    assert result == expected, \
        error_msg_start + "expected " + repr(expected) \
        + " but got " + repr(result)

print("Checking find_max finished")




##################
# Q3

def redact_emails(email_list, token):
    pass

# some testing code
print("Checking redact_emails")
testcases = [
    (   [["call", "me", "ASAP"],["meet", "me", "at", "3", "PM"]], 
        "me",
        [["call", "xx", "ASAP"],["xxxx", "xx", "at", "3", "PM"]]),
    (   [["call", "me", "ASAP"],["meet", "me", "at", "3", "PM"]],
        "a",
         [["xxxx", "me", "ASAP"],["meet", "me", "xx", "3", "PM"]]),
    (   [[],["", "", "i", "miss", "you"], ["Hi", "please", "email", "back"]],
        "i",
        [[],["", "", "x", "xxxx", "you"], ["xx", "please", "xxxxx", "back"]]),
    (   [[],["", "", "i", "miss", "you"], ["Hi", "please", "email", "back"]],
        "x",
         [[],["", "", "i", "miss", "you"], ["Hi", "please", "email", "back"]])

    ]

for item in testcases:
    inlist = item[0]
    token = item[1]
    correct_change = item[2]
    error_msg_start = "redact_emails problem " # prepare for any errors
    error_msg_start += "on input " + str(repr((inlist, token))) + ": "

    result = redact_emails(inlist,token)
    
    # shouldn't return anything
    assert result is None, \
        error_msg_start + "should return None, but returned " + repr(result)

    # check values are correct
    assert inlist == correct_change, \
        error_msg_start + "expected the list to become " + repr(correct_change) \
        + " but it became/stayed " + repr(inlist)
print("Checking redact_emails finished")


################
# Q5b

class Person:

    population = 0

    def add_parents(self, parents):
        for p in parents:
            self.parents.append(p)

    def add_children(self, children):
        for c in children:
            self.children.append(c)


    # Added so can do equality checking
    def __eq__(self, other):
        if not isinstance(other, Person):
            return NotImplemented
        if not (self.first == other.first and self.last == other.last and \
                self.parents == other.parents): 
            return False

        # hack for children checking to avoid cycling - just look at names
        if len(self.children) != len(other.children):
            return False
        for i in range(len(self.children)):
            if self.children[i].first != other.children[i].first or \
                self.children[i].last != other.children[i].last:
                return False
        return True


    # Added so can see who there might be an error for
    def __str__(self):
        return self.first + " " + self.last


    def count_the_kidless(self):
        pass


# some testing code
print("Checking method count_the_kidless")


p1 = Person("no", "children")
grand = Person("grand", "parent")
parent1 = Person("parent", "1", [grand])
parent2 = Person("parent", "2", [grand])
kids = []
for i in range(2):
    kids.append(Person("kid", str(i), [parent1]))
for i in range(2,4):
    kids.append(Person("kid", str(i), [parent2]))

testcases = [
    (p1, 1),
    (parent1, 2),
    (grand, 4)
]

for item in testcases:
    p = item[0]
    expected = item[1]
    orig = copy.deepcopy(p)

    error_msg_start = "count_the_kidless problem " # prepare for any errors
    error_msg_start += "on input " + str(p) + ": "

    result = p.count_the_kidless()

    # check for changes to the original object
    assert p == orig, error_msg_start + "changed person " + str(p) + " so that" \
        + " the original attributes " + str(orig.__dict__) + " are now " + str(p.__dict__)

    assert result == expected, error_msg_start + "expected " + str(expected) \
                                + " but got " +  str(result)

print("Checking method count_the_kidless finished")


################
# Q5c

def blend(p1, p2):

    for c in p1.children:
        c.add_parents([p2])
    for c in p2.children:
        c.add_parents([p1])

    p2_orig_kids = p2.children[:]

    p2.add_children(p1.children)
    p1.add_children(p2_orig_kids)

# some testing code
print("Checking  blend") 
p1 = Person("p", "1")
c1 = Person("c", "1", [p1])
p2 = Person("p", "2")

error_msg_start = "blend problem " # prepare for any errors
error_msg_start += "on input " + str((str(p1), str(p2))) + ": "

result = blend(p1, p2)
assert result is None, error_msg_start \
    + "should return None, but instead returned " + repr(result)
assert p1.children == [c1], error_msg_start \
    + "p1.children is not [c1] but " + str(p1.children)
assert p2.children == [c1], error_msg_start \
    + "p2.children is not [c1] but " + str(p2.children)
assert p1 in c1.parents and p2 in c1.parents, error_msg_start \
    + "c1.parents is not [p1, p2] but " + str(c1.parents)

print("Checking  blend finished") 



 



