#Wei Liu
#11/10/2021
#U3M2A2.3
#We are learning about Containment, Identity, and Operator Precedence

lst_container = [4, 8, 5, 6]
x = 5
if (x in lst_container):
print(x, "is contained in list")
else:
print(x, "is NOT contained in list")
x = 10
if (x in lst_container):
print(x, "is contained in list")
else:
print(x, "is NOT contained in list")

lst_container = [4, [7, 3], 'string element']
# 4 is an element in lst_container
x = 4
print(x, "contained in lst_container:", x in lst_container)
# 7 is an element of a list inside lst_container, but it is NOT an element of the lst_container
x = 7
print(x, "contained in lst_container:", x in lst_container)
# [7, 3] is an element of lst_container
x = [7, 3]
print(x, "contained in lst_container:", x in lst_container)

sentence = "This is a test sentence"
word1 = "test"
word2 = "something"
# testing if word1 is a substring of sentence
if (word1 in sentence):
print(word1, "is contained in:", sentence)
else:
print(word1, "is not contained in:", sentence)
# testing if word2 is a substring of sentence
if (word2 in sentence):
print(word2, "is contained in:", sentence)
else:
print(word2, "is not contained in:", sentence)
# another method to test if word2 is a substring of sentence
# using the not operator
if (word2 not in sentence):
print(word2, "is not contained in:", sentence)
else:
print(word2, "is contained in:", sentence)

# [ ] Write a program to prompt the user for an integer input between 0 and 100
# then print if the number is contained in `lst`
lst = [22, 89, 69, 78, 58, 22, 56, 13, 74, 8, 32, 58, 8, 63, 46, 79, 9, 38, 25, 96]
x=int(input("Please enter a number between 0 and 100: "))
print(x, "contained in lst:", x in lst)

# [ ] The `records` list contains information about a company's employees
# each of the elements in `records` is a list containing the name and ID of an employee.
# Write a program to test if `applicant` is contained in `records` and display an appropriate message
# Records of names and IDs
records = [['Colette', 22347], ['Skye', 35803], ['Alton', 45825], ['Jin', 24213]]
applicant = ['Joana', 20294]
if applicant in records:
print("Applicant is found in the records")
else:
print("Applicant is not found in the records")

# [ ] Write a program to prompt the user for a letter (capital or small) then print if the letter is a vowel
# HINT: Use a string containing all the vowels and the `in` or `not in` operator
vowels="AEIOU"
l=input("Please enter a letter either capital or lowercase")
if l.upper() in vowels:
print("Letter given is a vowel!")
else:
print("Letter given is not a vowel!")

# x, y: equal, identical
x = 5
y = 5
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# x, y: not equal, not identical
x = 5
y = 6
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# x, y: equal, not identical
x = 5.6
y = 5.6
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# x, y: not equal, not identical
x = 5.6
y = 10.6
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# Different lists containing the same data
x = [4, 9, 8]
y = [4, 9, 8]
# x and y are equal, because they contain the same data
# x and y are NOT identical, because they are saved in different memory locations
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)
# Because they are not identical, changing x does not affect y
x[1] = 5
print()
print("After changing x[1]")
print("x =", x)
print("y =", y)
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# Identical list
x = [4, 9, 8]
y = x
# x and y are equal, because they contain the same data
# x and y are identical, because they are saved in the same memory location
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)
# Because they are identical, changing x also changes y
x[1] = 5
print()
print("After changing x[1]")
print("x =", x)
print("y =", y)
print("x equal y ? ", x == y)
print("x is identical to y ?", x is y)

# s1, s2: equal, not identical
s1 = 'whole milk'
s2 = 'whole milk'
print("s1 equal s2 ? ", s1 == s2)
print("s1 is identical to s2 ?", s1 is s2)
print("s1 is not identical to s2 ?", s1 is not s2)

# s1, s2: equal, identical
s1 = 'whole milk'
s2 = s1
print("s1 equal s2 ? ", s1 == s2)
print("s1 is identical to s2 ?", s1 is s2)
print("s1 is not identical to s2 ?", s1 is not s2)

# s1, s2: equal, identical (after interpreter optimization)
s1 = 'python'
s2 = 'python'
print("s1 equal s2 ? ", s1 == s2)
print("s1 is identical to s2 ?", s1 is s2)
print("s1 is not identical to s2 ?", s1 is not s2)

# s1, s2: not equal, not identical
s1 = 'python'
s2 = 'java'
print("s1 equal s2 ? ", s1 == s2)
print("s1 is identical to s2 ?", s1 is s2)
print("s1 is not identical to s2 ?", s1 is not s2)

# [ ] Write a program to:
# 1) Create a variable `e` that is equal but NOT identical to `s`
# 2) Test the equality and identity of `s` and `e` and print the results
# 3) Create a variable `i` that is equal and identical to `s`
# 4) Test the equality and identity of `s` and `i` and print the results
# 5) Test the equality and identity of `e` and `i` and print the results
s = "Whole Wheat Bread"
e = "Whole Wheat Bread"
print("s equal e ?",s == e)
print("s is indentical to e ?", s is e, '\n')
i = s
print("s equal i ?", s == i)
print("s is indentical to i ?", s is i, '\n')
print("e equal e ?",s == i)
print("e is indentical to i ?", e is i, '\n')

# [ ] Write a program to:
# 1) Create a variable `e` that is equal but NOT identical to `x`
# 2) Test the equality and identity of `x` and `e` and print the results
# 3) Create a variable `i` that is equal and identical to `x`
# 4) Test the equality and identity of `x` and `i` and print the results
# 5) Test the equality and identity of `e` and `i` and print the results
x = [[-1, 2],[3, 4],[-5, 6]]
e = [[-1, 2],[3, 4],[-5, 6]]
print("x equal e ?", x == e)
print("x is indentical to e ?", x is e, '\n')
i = s
print("x equal i ?", x == i)
print("x is indentical to i ?", x is i, '\n')
print("e equal e ?", e == i)
print("e is indentical to i ?", e is i, '\n')

# * has higher precedence
2 + 3 * 6

# To change precedence, we add ( )
(2 + 3) * 6

# Arithmetic and relational operations
3 * 2 < 10

# Exponentiation has a higher precedence
2**3 + 1 == 16

# Adding () changes the precedence of 3 + 1 and the exponentiation operator
2 ** (3 + 1) == 16

# Arithmetic, relational, and Boolean operators
2 ** (3 + 1) == 16 and 3 * 2 < 10

# Arithmetic, relational, Boolean, and containment operators
2 ** (3 + 1) != 16 or 3 * 2 in [5, 6, 3]

# Unexpected outcome!
6 < 10 != True

# Unexpected outcome!
6 < 10 != False

# Expected outcome after adding ()
(6 < 10) != True

# [ ] Correct the following expression so the answer is `True`
(6 + 2 < 9) == True

# [ ] Correct the following expression so the answer is `True`
3 ** (2 + 1) >= 3 * 8 + 1

# [ ] Correct the following expression so the answer is `True`
(5 + 3) * 2 == 16

# [ ] Correct the following expression so the answer is `True`
(4 > 3) and ((5 + 6) > 7) == True