# Q1 (15 marks)
# Write a function that takes the number n and returns a list of all the perfect squares between 0 and n. A
# perfect square is a number s such that k 2 = s for some integer k. For example, get_perfect_squares(36)
# should return the list [0, 1, 4, 9, 16, 25, 36]


# Marking scheme:
# * 5 marks for checking if a number is a perfect square
# * 3 marks for the idea of iterating through possible answers
# * 3 marks for marks for building up res
# * 4 marks for putting everything together correctly
# * -1 for an off-by-one error
# * -1 for minor syntax issues
# * -2 for major syntax issues

# 3 min

def get_perfect_squares(n):
    res = []
    for i in range(n+1):
        if (int(i**0.5)) ** 2 == i:
            res.append(i)
    return res

# Q2(a) (15 marks)
# Write a function that computes the product of the elements of a list of integers. For example, prod([2, 3, 4])
# should return 24, since 2 × 3 × 4 = 24.
# Marking scheme:
# * 5 marks for iterating through a list
# * 5 marks for accumulating into a product
# * 5 marks for putting everything together correctly

# 1 min
def prod(L):
    res = 1
    for e in L:
        res *= e
    return res

# Q2(b) (15 marks)
#
# Write a function with the signature duplicates(list0), which returns True iff list0 contains at least two
# adjacent elements with the same value.

# Marking scheme
# * 3 marks for iterating through indices
# * 3 marks for comparing neighbours
# * 3 marks for correct early return (or correct use of state variable)
# * 3 marks for correctly handling the indices w/r/t 0 and len(s)-1 (no off-by one errors)
# * 3 marks for putting everything together correctly

# 1.5min
def duplicates(list0):
    for i in range(1, len(list0)):
        if list0[i] == list0[i-1]:
            return True
    return False

# Q3  (10 marks)
# Write code that repeatedly prompts the user for input, and then outputs the number of items that the
# user entered the input before the user entered "pumpkin spice latte" (with any capitalization)
# For example, an interaction with the user might look like
# What is your order? (User input:) Pumpkin pie
# What is your order? (User input:) Candy
# What is your order? (User input:) pumPkin Spice latte
# 2
# The number 2 is printed because the user ordered two items before ordering a pumpkin spice latte.

# Marking scheme
# (N.B.: function not required)
# * 4 marks: repeatedly calling input()
# * 4 marks: correctly outputting cound
# ** -2 for off-by-one error
# * 2 marks: putting everything together
# ** -1 for not correctly being case-insensitive

# 3 min
def repeated_order():
    order = ""
    count = -1
    while order.lower() != "pumpkin spice latte":
        order = input("What is your order?")
        count += 1
    print(count)

# Q4 (10 marks)
# 5 marks: correctly iterating through all possible (row, col)
# 2 marks: correctly adding element-wise
# 1 marks: putting everything together correcly
# -no marks off for modifying A and returning it instead of making a new res
# -marks off for not correctly building up res if they choose to do that
# 3 min

# 2 marks for correctly checking dimensions
def matrix_sum(A, B):

    if len(A) != len(B) or len(A[0]) != len(B[0]):

               return "ERROR"

    res = []
    for row in range(len(A)):
        res.append([0] * len(A[0]))

    for row in range(len(A)):
        for col in range(len(A[0])):
            res[row][col] += (A[row][col] + B[row][col])
    return res

# Q5 (10 marks)
# 5 marks for computing candy counts
# -- at most 2 marks if some progress is made
# 2 marks for getting the luckiest kid from the counts
# -- no part marks
# 3 marks for putting everything together
# -- Only give 3 marks if everything works. Take marks off depending on the
#    severity of the problem
# -- No marks for silly syntax errors
# 5 min
def luckiest_kid(haul_dataset):
    candy_count = {}
    for house, house_dat in haul_dataset.items():
        for kid, haul in house_dat.items():
            if kid not in candy_count:
                candy_count[kid] = len(haul)
            else:
                candy_count[kid] += len(haul)

    max_count = -1
    for kid, count in candy_count.items():
        if count > max_count:
            max_kid = kid
            max_count = count
    return max_kid

halloween_haul = {"house1": {"Annie": ["snickers", "mars"],
"Johnny": ["snickers"] },
"house2": {"Annie": ["coffee break", "mars"],
"Jackie":["coffee break"]}
}

luckiest_kid(halloween_haul)


# Q6 (10 marks)
# 4 marks for keeping track of which digit to return
# 4 marks for computing the correct digit
# -- if they CORRECTLY remembered the first 10 digits of pi and used that, that is fine as well
#    if they remembered incorrectly, no marks for this
# 2 marks for putting everything together
# -- Only give full marks if everything works


# 2 min
import math
cur_digit = -1
def next_digit_pi():
    global cur_digit
    cur_digit += 1
    return str(math.pi).replace(".", "")[cur_digit]



# 1.5 min

# Q7: all or nothing for everything except Q7(a) and Q7(e)
# for Q7(a) and Q7(e), -2 for "error" and then something in addition to "error"

# Q7 (3 marks each)
# Q7(a)
# def f(L):
#     global L
#     L = [1, 2, 3]
#     L[0] = 5
#     print(L[0])
#     L1 = [4, 5, 6]
# f(L1)
# print(L)
# print(L1)
# ERROR

# Q7(b)
def g(L):
    L = [1, 2, 3]
    L[0] = 3
L = [4, 5, 6]
g(L)
print(L)
# [4, 5, 6]

# Q7(c)
s = "abcd"
print(s)
sorted(s)
print(s)
# abcd
# abcd

# Q7(d)
L = [1, [2, 3], 4 ]
L1 = L[:]
L[0] = 7
L[1][0] = 8
L1[1][1] = 9
print(L)
print(L1)

# [7, [8, 9], 4]
# [1, [8, 9], 4]

# Q7(e)
def greeting(s):
    global s
    s = "Happy " + s
    print(s)
res = greeting(s)
print(res)

# ERROR
