i1 = [1, 2, 3]
a1 = [1, 3, 5]
assert set(a1) == set(add_index(i1))

i2 = [0, 0, 0, 9, 10, 11]
o2 = 12
a2 = [12, 13, 14, 24, 26, 28]
assert set(a2) == set(add_index(i2, o2))

"""
Explanation: Q1
In this question, you'll write some basic functions.
Part A
Write a function that adds an amount to each element of a list equal to the index of that element in the list, plus an optional offset.
Your function should:

be named add_index
take 2 arguments: a list of numbers, and an optional (default: 0) offset that is added to each element
return 1 value: a list of numbers with their values properly incremented

For example, add_index([1, 2, 3]) should return [1, 3, 5]. Since the 1 is at index 0, nothing is added; however, the 2 is at index 1, so 1 is added to make 3. Finally, the 3 is at index 2, so 2 is added to make 5.
Another example: add_index([1, 2, 3], 5) should return [6, 8, 10]. Again, the 1 is at index 0, so 0 is added, resulting in 1. However, the additional offset of 5 results in 6. Same again for the 2: 1 is added for the index (making 3), plus the offset of 5 for a final value of 8. Finally for the 3, 2 is added for the index (making 5), plus the offset of 5 making 10.
You cannot use any built-in or imported functions.
End of explanation
"""


i1 = [1, 2, 3]
a1 = [2]
assert set(a1) == set(remove_odds(i1))

i2 = [0, 0, 0, 9, 10, 11]
a2 = [0, 0, 0, 10]
assert set(a2) == set(remove_odds(i2))

"""
Explanation: Part B
Write a function which deletes all the odd numbers from a list of numbers.
Your function should:

be named remove_odds
take 1 argument, a list of numbers
return 1 value: the original list of numbers, but with all the odd elements stripped out

For example, remove_odds([1, 2, 3, 4, 5]) should return [2, 4]. 0 counts as even.
You cannot use any built-in or imported functions.
End of explanation
"""


i1 = [1, 2, 1]
assert is_palindrome(i1)

i2 = [1, 1, 2, 1]
assert not is_palindrome(i2)

i3 = [1, 2, 3, 4, 5, 4, 3, 2, 1]
assert is_palindrome(i3)

i4 = [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
assert is_palindrome(i4)

i5 = [1, 2, 3, 4, 5, 5, 4, 3, 2]
assert not is_palindrome(i5)

"""
Explanation: Part C
Write a function which determines whether or not a list is a palindrome. Recall a palindrome is typically a word or sequence of words that reads identically forwards as backwards.
Your function should:

be named is_palindrome
take 1 argument, a list
return 1 value, a boolean: True if the input list is a palindrome, False otherwise

For example, is_palindrome([1, 2, 1]) would return True, but is_palindrome([1, 1, 2, 1]) would return False.
You cannot use any built-in or imported functions.
End of explanation
"""


i1 = [1, 2, 3]
n1 = 1
a1 = [2]
assert set(a1) == set(strip_n(i1, n1))

i2 = [1, 2, 3, 4]
n2 = 2
a2 = []
assert set(a2) == set(strip_n(i2, n2))

i3 = [1, 2, 3, 4, 5]
n3 = 3
try:
    strip_n(i3, n3)
except ValueError:
    assert True
else:
    assert False

"""
Explanation: Part D
Write a function that chops a specified number of elements off the front and back of a list.
Your function should:

be named strip_n
take 2 arguments: a list of numbers, and the number of list elements to remove from the front and back of the list
return 1 value: the modified input list with specified number of leading and tailing elements removed

If the number of elements specified to strip from the list is infeasible--for example, asking to chop 3 elements off the front and back of a 1-element list--you should raise a ValueError.
For example, strip_n([1, 2, 3], 1) should return [2]. The second argument "1" means you should chop 1 element off the front (1) and 1 element off the back (3) and return the remaining list [2]. If the number of elements to chop off had been 2 instead of 1, you would have raised a ValueError, since you can't chop 2 elements off the front and back--a total of 4 elements--when your list only has 3 elements total.
You cannot use any built-in functions or additional imports.
End of explanation
"""


