#################################################
# quiz5.py
# name:
# andrew id:
#################################################

import cs112_f22_week5_linter
import math, copy

"""
Remember: 
- You may not use any concepts (including builtin functions) we have not 
    covered in the notes this semester.
- You may not use dictionaries, sets, or recursion.
- We may test your code using additional test cases. Do not hardcode.
- Assume almostEqual(x, y) and roundHalfUp(n) are both supplied for you. You 
    must write all other helper functions you wish to use.
"""

#################################################
# Helper functions
#################################################

def almostEqual(d1, d2, epsilon=10**-7): #helper-fn
    # note: use math.isclose() outside 15-112 with Python version 3.5 or later
    return (abs(d2 - d1) < epsilon)

import decimal
def roundHalfUp(d): #helper-fn
    # Round to nearest with ties going away from zero.
    rounding = decimal.ROUND_HALF_UP
    # See other rounding options here:
    # https://docs.python.org/3/library/decimal.html#rounding-modes
    return int(decimal.Decimal(d).to_integral_value(rounding=rounding))

#################################################
# Place your quiz5 solutions below
#################################################

# Free Response 1: destructiveTile(L) [45 points]
"""
Write the function destructiveTile(L) which takes a 2d rectangular list L (with 
at least one row and one column), and *destructively* modifies the list so that 
it contains twice as many rows and columns, and with the inner values arranged 
as if four duplicates of L were placed inside. Study the test cases to 
understand the pattern! As usual for destructive functions, this function 
returns None.
Also, make sure that *none of the rows are aliased* to each other!

Note: The autograder will only give credit for destructive solutions!
Your solution MUST be destructive!  (This is different from what we 
told you on the paper quiz.)
"""

def destructiveTile(L):
    return 42


# Free Response 2: makeMultiplicationTable(n) [40 points]
"""
Write the function makeMultiplicationTable(n) that takes a positive integer n 
and returns a multiplication table in the form of a 2D list with n rows and n 
columns. Each cell should be the product of the integer at the beginning of its 
row and the top of its column. Look at the test cases to identify this pattern.
"""

def makeMultiplicationTable(n):
    return 42


#################################################
# Test Functions
#################################################

def testDestructiveTile():
    print("Testing destructiveTile...", end = " ")
    L = [['a', 'b'],
         ['c', 'd']]
    assert(destructiveTile(L) == None)
    assert(L == [['a', 'b', 'a', 'b'],
                 ['c', 'd', 'c', 'd'],
                 ['a', 'b', 'a', 'b'],
                 ['c', 'd', 'c', 'd']])

    L = [[112]]
    assert(destructiveTile(L) == None)
    assert(L == [[112, 112],
                 [112, 112]])
    
    L = [[10],
         [20],
         [30]]
    assert(destructiveTile(L) == None)
    assert(L == [[10, 10],
                 [20, 20],
                 [30, 30],
                 [10, 10],
                 [20, 20],
                 [30, 30]])

    L = [[10, 20, 30]]
    assert(destructiveTile(L) == None)
    assert(L == [[10, 20, 30, 10, 20, 30],
                 [10, 20, 30, 10, 20, 30]])
    #Test that the rows are not aliased:
    L[0][0] = 40
    assert(L == [[40, 20, 30, 10, 20, 30],
                 [10, 20, 30, 10, 20, 30]])
    print('Passed!')



def testMakeMultiplicationTable():
    print("Testing makeMultiplicationTable...", end = " ")
    assert(makeMultiplicationTable(1) == [[1]])
    assert(makeMultiplicationTable(2) == [[1, 2],
                                          [2, 4]])
    assert(makeMultiplicationTable(3) == [[1, 2, 3],
                                          [2, 4, 6],
                                          [3, 6, 9]])
    assert(makeMultiplicationTable(5) == [[1, 2, 3, 4, 5],
                                          [2, 4, 6, 8, 10],
                                          [3, 6, 9, 12, 15],
                                          [4, 8, 12, 16, 20],
                                          [5, 10, 15, 20, 25]])
    print('Passed!')


#################################################
# testAll and main
#################################################

def testAll():
    # comment out the tests you do not wish to run!
    testDestructiveTile()
    testMakeMultiplicationTable()
 
def main():
    cs112_f22_week5_linter.lint()
    testAll()

if __name__ == '__main__':
    main()
