["Watermelon"]

list(123)

list("123")

a = []
b = list()


a == b 

x = [0,1,2,3,4,5,6]

z = list()

y = list(range(7))

x == y

type(['one', 'two'])

type(['apples' , 50, False])

type([]) # Empty list

# Define a list
# Using list function to create empty list
a = list()
print(type(a))
print(a)

# Using brackets to create empty list
b = []
print(type(b))
print(b)

# We can also initilize lists with some content inside
c = [1,2,3] # Create list with integer values inside

# We can access specific elements of the list using index value
print(c[1])

print(c[0])

n = 0
tot1 = 0
while n < len(c):
    tot1 = tot1 + c[n]
    n  = n +1
tot1

tot = sum(c)
tot

total = c[0] + c[1] + c[2]
total

# Creates a list of elements from 0 to 9
lst = list(range(10)) 
print(lst)

a = 10

# Lets update(replace) an element of the list called lst
lst[2] = 19
print(lst)

# Let's remove an element from the list
del lst[2]
print(lst)

# We can add elements to the list using 2 different methods:

lst.insert(8,3) # adds element 3 at index 8
print(lst)

lst.append(4) # adds element 4 at the end of list
print(lst)

"""
Explanation: List Structures
The concept of a list is similar to oureveryday notion of a list. We read off (access) items on our to-do list, add items, cross off (delete) items, and so forth. We look at the use of lists next.

A list is a linear data structure , meaning that its elements have a linear ordering. (First, second, ...)
Each item in the list is identified by its index value (location) .
Index starts with 0


There are common operations performed on lists including; retrieve, update, insert, delete, and append.

Lists in Python

Mutable
Flexible length
Allowing mixed type elements
index 0...n-1
denoted with [value1, value2]
End of explanation
"""


nums = (10,20,30)

type(nums)

print(nums[2])

nums.insert(1,15) # Non alterable

del nums[2]

nums.append(40)

y = 75
x = 45

(x,y) = (y,x)

x

y

"""
Explanation: Tuples in Python
In contrast to lists, tuple is defined and cannot be altered. Otherwise, lists and tuples are essentially same. To denote tuples we use ( )
End of explanation
"""


# Initializing our variable 
s1 = 'hello'
s2 = 'world!'
t1 = (1,2,3,4)
t2 = (5,6)
l1 = ['apple', 'pear', 'peach']
l2 = [10,20,30,40,50,60,70]

"""
Explanation: Sequences
A sequence in Python is a linearly ordered set of elements accessed by an index number.
Lists, tuples, and strings are all sequences. 
We know what is string: "String"
Strings are also immutable like tuples, but we can we will use the intensively. 
Let's look at more operations we can use with sequences:
End of explanation
"""


# Finding length for string
print(len(s1))
print(len(s2))

# Finding length for tuples
print(len(t1))
print(len(t2))

# Finding length for lists
print(len(l1))
print(len(l2))

"""
Explanation: Finding length with len():
End of explanation
"""


print(s1[0])
print(s2[4])

print(t1[1])

print(l2[2])

"""
Explanation: Accessing elements by indexing:
End of explanation
"""


s1[1:4]

s2[3:]

l1[1:]

t1

t1[::-1] # Special Slicing feature

"""
Explanation: Slicing:
End of explanation
"""


s1.count('l') # Counting l occurences in the sequence

l2

l2.count(30)

t1

t1.count(15)

"""
Explanation: Counting elements:
End of explanation
"""


# c = s1.count("l") # 2
word = "This is a very nice day in Houston!"
user_input = input("Please enter a letter that I can find index for you: ")
i = 0
lst = []
c = word.count(user_input)
while i < len(word):
    if c > 1:
        if word[i] == user_input:
            lst.append(i)
    elif c == 0:
        print(0)
        break
    else:
        if word[i] == user_input:
            print(i)
            break
    i = i + 1
print(lst)
            
        
    

s1.index('l')

l1.index('peach')

t1.index(3)

"""
Explanation: Finding Indexes from elements:
End of explanation
"""


'h' in s1

9 in t2

30 in l2

"""
Explanation: Checking Membership with in :
End of explanation
"""


s1, s2

print(s1+s2)
print(s1 + " " +s2)

print(t1+t2)

print(l1+l2)

(s1 + " ")* 4

"""
Explanation: Concatenation:
End of explanation
"""


min(s2)

min(t2)

min(l1)

"""
Explanation: Finding minimum:
End of explanation
"""


max(s2)

max(t1)

max(l1)

"""
Explanation: Finding maximum:
End of explanation
"""


class_grades = [ [85, 91, 89], 
                 [78, 81, 86], 
                 [62, 75, 77] ]

class_grades

"""
Explanation: Lists and Tuples can used with more dimensions. Nested lists and tuples are giving this flexibility.
End of explanation
"""


class_grades[0] # Prints the first sub-list

# We can get the specific item like this in a long way 
student1_grades = class_grades[0]
student1_exam1 = student1_grades[0]
student1_exam1

# In short this is more conventional
class_grades[0][0]

# Let's write a small script that calculates the class average.
k = 0
exam_avg = []
while k < len(class_grades):
    avg = (class_grades[k][0] + class_grades[k][1] + class_grades[k][2]) / 3.0
    exam_avg.append(avg)
    k += 1

format((sum(exam_avg) / 3.0), '.2f')

"""
Explanation: When we trying to get the specific elements in nested lists or tuples, we should do something different:
End of explanation
"""


nums = [10,20,30,40,50,60]
for k in nums:
    print(k)

"""
Explanation: Apply It!
<p style=color:red>
Write a small program that finds your Chineze Zodiac and its characteristics using tuples and datetime module, resulting output:
</p>

This program will display your Chinese Zodiac Sign and Associated personal characteristics.

Enter your year of birth (yyyy): 1984
Your Chinese Zodiac sign is the Rat

Your personal charactersitics...
Forthright, industrious, sensitive, intellectual, sociable

Would you like to enter another year? (y/n): n

<p style=color:red>
Here are the characteristics: <br>

rat = 'Forthright, industrious, sensitive, intellectual, sociable' <br>
ox = 'Dependable, methodical, modest, born leader, patient' <br>
tiger = 'Unpredictable, rebellious, passionate, daring, impulsive' <br>
rabbit = 'Good friend, kind, soft-spoken, cautious, artistic' <br>
dragon = 'Strong, self-assured, proud. decisive, loyal' <br>
snake = 'Deep thinker, creative, responsible, calm, purposeful' <br>
horse = 'Cheerful, quick-witted, perceptive, talkative, open-minded' <br>
goat = 'Sincere, sympathetic, shy, generous, mothering' <br>
monkey = 'Motivator, inquisitive, flexible, innovative, problem solver' <br>
rooster = 'Organizer, self-assured, decisive, perfectionist, zealous' <br>
dog = 'Honest, unpretentious, idealistic, moralistic, easy going' <br>
pig = 'Peace-loving, hard-working, trusting, understanding, thoughtful' <br>
</p>

Test Time
Question1: Which of the following sequence types is a mutable type?
a) Strings
b) Lists
c) Tuples

Question2: What is the result of the following snippet:
lst = [4,2,9,1]
lst.insert(2,3)

a) [4,2,3,9,1]
b) [4,3,2,9,1]
c) [4,2,9,2,1]

Question3: Which of the following set of operations can be applied to any sequence?
a) len(s), s[i], s+w (concatenation)
b) max(s), s[i], sum(s) 
c) len(s), s[i], s.sort()

Iterating Over Sequences
We can iterate over sequences using while loop, the one that we learned last lecture. However there is a better and more Pythonic way, it is called For loops

For loops are used to construct definite loops. 

Syntax:
for k in sequence:
    statements
End of explanation
"""


k = 0
while k < len(nums):
    print(nums[k])
    k += 1

"""
Explanation: In the example above k is called loop variable. In the list we had 6 elements so our loop iterated six times. We can create the same script with while loop as follows:
End of explanation
"""


for ch in 'Hello World!':
    print(ch)

"""
Explanation: For statement can be applied to all sequence types, including strings. Let's see how:
End of explanation
"""


list(range(2))

list(range(2,11))

list(range(1, 11, 2))

"""
Explanation: Now since we know about the beautiful for loops, it's time to learn a built-in function most commonly used with for loops: a built-in range() function
End of explanation
"""


tot = 0
for k in range(1, 11, 2):
    tot = tot + k
    print(k)
    
print("Total is", tot)

"""
Explanation: As you can see range() function creates a list so we can use it with for loops:
End of explanation
"""


nums=[12, 4, 11, 23, 18, 41, 27]
k = 0
while k < len(nums) and nums[k] != 18:
    k += 1
print(k)

fruit = "Strawberry"
for k in range(0, len(fruit),2):
    print(fruit[k], end='')

"""
Explanation: Test Time
Question1: For nums=[10,30,20,40] , what does the following for loop output?
for k in nums:
    print(k)

Questions2: For fruit='strawberry' , what does the following for loop output?
for k in range(0,len(fruit),2):
    print(fruit[k], end='')

Question3: For nums=[12, 4, 11, 23, 18, 41, 27] , what is the value of k when the while loop terminates?
k = 0
while k &lt; len(nums) and nums[k] != 18:
    k += 1
End of explanation
"""


[x**2 for x in [1,2,3]]

[x**2 for x in range(10)]

nums = [-1,1,-2,2,-3,3,-4,4,-5,5]
[x for x in nums if x >= 0]

[ord(ch) for ch in 'Hello World']

vowels = ('a', 'e', 'i','o', 'u')
w = 'Hello World!'
[ch for ch in w if ch in vowels]

"""
Explanation: List Comprehension
The range function allows for the generation of sequences of integers in fixed increments.
List Comprehensions in Python can be used to generate more varied sequences.
End of explanation
"""


