0% found this document useful (0 votes)
5 views

Python Ch-5_Notes

This document covers the basics of strings and lists in Python, including how to create strings, string operations, and built-in string methods. It explains string immutability, indexing, slicing, and various string manipulations such as concatenation and repetition. Additionally, it introduces lists as a mutable and ordered collection of items that can store heterogeneous data types.

Uploaded by

hetshihora247
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Python Ch-5_Notes

This document covers the basics of strings and lists in Python, including how to create strings, string operations, and built-in string methods. It explains string immutability, indexing, slicing, and various string manipulations such as concatenation and repetition. Additionally, it introduces lists as a mutable and ordered collection of items that can store heterogeneous data types.

Uploaded by

hetshihora247
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Python Programming (UNIT-5) | 4311601

Unit-V: Strings and Lists (Marks-18)


Introduction to Strings
 Strings are amongst the most popular types in Python. We can create them simply by
enclosing characters in quotes.
 Python treats single quotes the same as double quotes. Creating strings is as simple as
assigning a value to a variable.
 Python string is the collection of the characters surrounded by single quotes, double
quotes, or triple quotes.
Syntax:
str = "Hi Python !"
Creating String in Python
We can create a string by enclosing the characters in single-quotes or double- quotes. Python
also provides triple-quotes to represent the string, but it is generally used for multiline string
or docstrings.
Example:
#Using single quotes
str1 = 'Hello Python'
print(str1)
#Using double quotes
str2 = "Hello Python"
print(str2)
#Using triple quotes
str3 = '''''Triple quotes are generally used for
represent the multiline or
docstring'''
print(str3)
O/P:
Hello Python
Hello Python
Triple quotes are generally used for
represent the multiline or
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 1
Python Programming (UNIT-5) | 4311601
docstring
Python String indexing
A string can only be replaced with a new string since its content cannot be partially replaced.
Strings are immutable in python.

Example 1

str = "HELLO"
str[0] = "h"
print(str)
O/P:
Traceback (most recent call last):
File "12.py", line 2, in <module>
str[0] = "h";
TypeError: 'str' object does not support item assignment

However, in example 1, the string str can be assigned completely to a new content as
specified in the following example.

Example 2

str = "HELLO"
print(str)
str = "hello"
print(str)
O/P:
HELLO
hello
Deleting the String

As we know that strings are immutable. We cannot delete or remove the characters from the
string. But we can delete the entire string using the del keyword.

str = "PYTHON"
del str[1]

O/P:
TypeError: 'str' object doesn't support item deletion

Now we are deleting entire string.

str1 = "PYTHON"
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 2
Python Programming (UNIT-5) | 4311601
del str1
print(str1)

O/P:
NameError: name 'str1' is not defined

List out various String operations and Explain any one with example WINTER 2021,2022,
SUMMER 2022
String Operations
Various operations that can be performed on strings are:
 Accessing String Characters
 Traversing a String
 Slicing a String
 Searching a String
 String Concatation
 String Repetition

Accessing String Characters


Like other languages, the indexing of the python strings starts from 0. For example, the
string "HELLO" is indexed as given in the below figure.
str="HELLO"

str[0]=H
str[1]=E
str[4]=O

Python allows negative indexing for its sequences.


The index of -1 refers to the last item, -2 to the second last item and so on.

str[-1]=O
str[-2]=L
str[-4]=E

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 3


Python Programming (UNIT-5) | 4311601
Example:
str = "Hello"
print(str[4]) # prints o
print(str[0]) # prints H
print(str[-2]) # prints l

Write a program to traverse the string using for and while loop. WINTER-2022
Traversing a String

Different ways to iterate strings in Python. You could use a while loop,for loop, range in
Python, a slicing operator, and a few more methods to traverse the characters in a string.

Using for loop to traverse a string


It is the most prominent and straightforward technique to iterate strings. Follow the below
sample code:
Example:
string_to_iterate = "Data Science"
for char in string_to_iterate:
print(char)

O/P: Data Science

Using for range() to traverse a string

Another quite simple way to traverse the string is by using the Python range function. This
method lets us access string elements using the index.
Example:
string_to_iterate = "Data Science"
for char_index in range(len(string_to_iterate)):
print(string_to_iterate[char_index])
O/P: Data Science
Slicing a String

Using slice operator to iterate strings partially


 You can traverse a string as a substring by using the Python slice operator ([]). It cuts
off a substring from the original string and we can iterate over it partially.
 The [] operator has the following syntax:

# Slicing Operator
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 4
Python Programming (UNIT-5) | 4311601
string [starting index : ending index : step value]
 To use this method, provide the starting and ending indices along with a step value and
then traverse the string. Below is the example code that iterates over the first six letters
of a string.
 Here, Start_Index is the starting index of the string. End_Index is the last index before
which all elements are considered.
 Steps are the number of steps to be jumped in each iteration. The Start_Index and Steps
are optional. The Start_Index is 0 by default. The step is 1 by default.
 Note that ending index is not included in the range.It means Mystring[3:7] starting
from Mystring[3] to Mystring[6].index 7 is not included.

Example:
string_to_iterate = "Python Data Science"
for char in string_to_iterate[0 : 6 : 1]:
print(char)
O/P: Python
 You can take the slice operator usage further by using it to iterate over a string but
leaving every alternate character. Check out the below example:

Example:
string_to_iterate = "Python_Data_Science"
for char in string_to_iterate[ : : 2]:
print(char)
O/P: P t o _ a a S i n e

Traverse string backward using the slice operator


 If you pass a -ve step value and skip the starting as well as ending indices, then you can
iterate in the backward direction. Go through the given code sample.

Example:
string_to_iterate = "Machine Learning"
for char in string_to_iterate[ : : -1]:
print(char)
O/P: g n i n r a e L e n i h c a M

Using indexing to iterate strings backward

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 5


Python Programming (UNIT-5) | 4311601
 The slice operator first generates a reversed string, and then we use the for loop to
traverse it. Instead of doing it, we can use the indexing to iterate strings backward.

Example:
string_to_iterate = "Machine Learning"
char_index = len(string_to_iterate) - 1
while char_index >= 0:
print(string_to_iterate[char_index])
char_index -= 1
O/P: g n i n r a e L e n i h c a
Searching a String
 If you want to check whether a particular substring exists in the string or not use the
Python string in operator.
 If the substring is present in the string, True is returned, otherwise False is returned. It
is case-sensitive.

Example:
Mystring = “Welcome To Python”
print(“Python” in Mystring)
print(“python” in Mystring)
O/P
True
False

String Concatation

 String concatenation means add strings together.


 Use the + operator to add a variable to another variable:

Example:

x = "Python is "
y = "awesome"
z= x+y
print(z)
O/P
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 6
Python Programming (UNIT-5) | 4311601
Python is awesome
String Repetition
 The repetition operator is denoted by a '*' symbol and is useful for repeating strings to
a certain length.
Example:
str = 'Python program'
print(str*3)
O/P
Python programPython programPython program

Strings Methods and Built-in Functions:


List out built-in methods of string and make use of any three with suitable
example.WINTER-2022
Explain usage of given string methods SUMMER-2022
i)islower( ) ii) replace( ) iii) isdigit( )
sPython provides various in-built functions that are used for string handling. Those are
Method Purpose Example
len() Returns length of the given Example:
string. str1="Python Language"
print(len(str1))
O/P:
15
lower() Returns all characters of given Example:
string in lowercase str=”PyTHOn”
print(str.lower())
O/P:
python
upper() Returns all characters of given Example:
string in uppercase str=”PyTHOn”
print(str.upper())
O/P:
PYTHON
replace() Replaces the old sequence of Example:
characters with the new str = "Java is Object-Oriented
sequence. If the optional and Java is Portable "
argument count is given, only str2=
the first count occurrences are str.replace("Java","Python")
replaced. print(str2)
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 7
Python Programming (UNIT-5) | 4311601
Syntax: str3 =
str.replace(old, new[, count]) str.replace("Java","Python",1
old : An old string which will )
be replaced. print(str3)
new : New string which will O/P:
replace the old string. Python is Object-Oriented
count : The number of times to and Python is Portable
process the replace. Python is Object-Oriented
and Java is Portable
Finds substring in the whole Example:
find() string and returns index of the str1 = "python is a
first match. It returns -1 if programming language"
substring does not match
str2 = str1.find("is")
Syntax:
str.find(sub[, start[,end]]) str3 = str1.find("java")
sub :it specifies sub string. print(str2,str3)
start :It specifies start index of O/P:
range. 7 -1
end : It specifies end index of
range.
index() method is same as the Example:
index() find() method except it returns str1 = "python is a
error on failure. This method programming language"
returns index of first occurred str2 = str1.index("is")
substring and an error if there is print(str2)
no match found str3 = str1.index("p",5)
print(str3)
Syntax:
str5 = str1.index("java")
index(sub[, start[,end]])
print(str5)
sub :it specifies sub string.
O/P:
start :It specifies start index of
7 12 Substring not found
range.
end : It specifies end index of
range.
Checks whether the all Example:
isalnum() characters of the string is str1 = "python"
alphanumeric or not. A str2 = "python123"
character which is either a letter str3 = "python@123"
or a number is known as print(str1. isalnum())
alphanumeric. It does not allow print(str2. isalnum())
special chars even spaces. print(str3. isalnum())
O/P:
True True False
Rreturns True if all the Example:
isdigit() characters in the string are str1 = "12345"
digits. It returns False if no str2 = "python123"
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 8
Python Programming (UNIT-5) | 4311601
character is digit in the string print(str1.isdigit())
print(str2.isdigit())
O/P:
True False
Returns True if all characters in Example:
islower() the string are in lowercase. It str1 = "python"
returns False if not in str2="PytHOn"
lowercase. O/P:
True False

Rreturns True if all characters Example:


isupper() in the string are in uppercase. It str1 = "PYTHON"
returns False if not in str2="PytHOn
uppercase. O/P:
True False

Returns a string where the first Example:


capitalize() character is upper case, and the str1 = "python is FUN!"
rest is lower case. x = str1.capitalize()
print (x)
O/P:
Python is fun!
Converts the first character of Example:
title() each word to upper case str1 = "Welcome to my
world"
x = str1.title()
print(x)
O/P:
Welcome To My World
Swaps cases, lower case Example:
swapcase() becomes upper case and vice str1 = "Hello My Name Is
versa PETER"
x = str1.swapcase()
print(x)
O/P:
hELLO mY nAME iS peter
Remove spaces at the Example:
strip() beginning and at the end of the str1 = " python "
string x = str1.strip()
print(x)
O/P:
pythonyho
Remove spaces to the left of Example:
lstrip() the string str1 = " banana "
x = str1.lstrip()
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 9
Python Programming (UNIT-5) | 4311601
print("of all fruits", x, "is my
favorite")
O/P:
of all fruits banana is my
favorite
Remove any white spaces at the Example:
rstrip() end of the string: str1 = " banana "
x = str1.rstrip()
print("of all fruits", x, "is my
favorite")
O/P:
of all fruits banana is my
favorite
Returns the number of times a Example:
count() specified value occurs in a str1 = "I love apples, apple
string are my favorite fruit"
x = str1.count("apple")
print(x)
O/P: 2
Converts the elements of an Example:
join() iterable into a string myTuple = ("John", "Peter",
"Vicky")
x = "#".join(myTuple)
print(x)
O/P:
John#Peter#Vicky
Splits the string at the specified Example:
split() separator, and returns a list str1 = "welcome to the
python"
x = str1.split()
print(x)
O/P:
['welcome', 'to', 'the', 'python']​
Returns True if all characters in Example:
isprintable() the string are printable str1 = "Hello! Are you #1?"
x = str1.isprintable()
print(x)
O/P: true

Introduction to List

 In Python, the sequence of various data types is stored in a list. A list is a collection of
different kinds of values or items. The comma (,) and the square brackets [enclose the
List's items] serve as separators.
 Lists are used to store multiple items in a single variable.
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 10
Python Programming (UNIT-5) | 4311601
 Elements of the List need not be of same type.It means List can represents
homogeneous(same) as well as heterogenous(different) elements.
 Lists are one of 4 built-in data types in Python used to store collections of data, the
other 3 are Tuple, Set, and Dictionary, all with different qualities and usage.

Characteristics of a Python List

Ordered: Lists maintain the order in which the data is inserted.

Mutable: In list element(s) are changeable. It means that we can modify the items stored
within the list.

Heterogenous: Lists can store elements of various data types.

Dynamic: List can expand or shrink automatically to accommodate the items accordingly.

Duplicate Elements: Lists allow us to store duplicate data.Lists are created using square
brackets:

Types of Lists:

Homogenous List:

integer_List = [26, 12, 97, 8]

string_List = ["Interviewbit", "Preparation", "India"]

Heterogenous List:

List = [1, "Interviewbit", 9.5, 'D']

List out various List operations and Explain any one with example. WINTER – 2021,
WINTER-2022
Explain how to create list by giving example. WINTER - 2021
Explain indexing and slicing operations in python list.WINTER-2022
List Operations
Various operations that can be performed on list are:
 Creating a list
 Access individual Element of the List.
 Traversing in a List
 Searching a List
 List Concatation
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 11
Python Programming (UNIT-5) | 4311601
 List Repetition
Creating a list
To create a list in Python, we use square brackets ([]). Here's what a list looks like:
ListName = [ListItem, ListItem1, ListItem2, ListItem3, ...]
# Creating an empty List

empty_List = []

# Creating a List of Integers

integer_List = [26, 12, 97, 8]

# Creating a List of floating point numbers

float_List = [5.8, 12.0, 9.7, 10.8]

# Creating a List of Strings

string_List = ["Interviewbit", "Preparation", "India"]

# Creating a List containing items of different data types

List = [1, "Interviewbit", 9.5, 'D']

# Creating a List containing duplicate items

duplicate_List = [1, 2, 1, 1, 3,3, 5, 8, 8]

The list() constructor returns a list in Python.


List_1 =list( (1, "Interviewbit", 9.5, 'D'))

Print(List_1)

Accessing Values/Elements in List in Python

 Elements stored in the lists are associated with a unique integer number known as an
index. The first element is indexed as 0, and the second is 1, and so on. So, a list
containing six elements will have an index from 0 to 5.
 For accessing the elements in the List, the index is mentioned within the index
operator ([ ]) preceded by the list's name.

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 12


Python Programming (UNIT-5) | 4311601
 Another way we can access elements/values from the list in python is using a negative
index. The negative index starts at -1 for the last element, -2 for the last second
element, and so on.

Example:

My_List = [3, 4, 6, 10, 8]

print(My_List[2])

print(My_List[4])

print(My_List[-1])

print(My_List[-5])

O/P: 6 8 8 3

Access Range of Elements in List

 we can access the elements stored in a range of indexes using the slicing operator (:).
 The index put on the left side of the slicing operator is inclusive, and that mentioned
on the right side is excluded.
 Slice itself means part of something. So when we want to access elements stored at
some part or range in a list we use slicing

Example:

my_List = ['i', 'n', 't', 'v', 'i', 'e', 'w', 'b', 'i', 't']

# Accessing elements from index beginning to 5th index

print(my_List[:6])

# Accessing elements from index 3 to 6

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 13


Python Programming (UNIT-5) | 4311601
print(my_List[3:7])

# Accessing elements from index 5 to end

print(my_List[5:])

# Accessing elements from beginning to end

print(my_List[:])

# Accessing elements from beginning to 4th index

print(my_List[:-6])

# Accessing elements from index -8th to -6th index

print(my_List[-8:-5])

sO/P:

['i', 'n', 't', 'v', 'i', 'e']

['v', 'i', 'e', 'w']

['e', 'w', 'b', 'i', 't']

['i', 'n', 't', 'v', 'i', 'e', 'w', 'b', 'i', 't']

['i', 'n', 't', 'v']

['t', 'v', 'i']

Traversing in a List
Traversing a list means access each elements of list.

Using while loop:

Example:

list1 = [3, 5, 7, 2, 4]
count = 0
while (count < len(list1)):
print (list1 [count])

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 14


Python Programming (UNIT-5) | 4311601
count = count + 1
O/P: 3 5 7 2 4

Using for loop:

Example:

list1 = [3, 5, 7, 2, 4]
for i in list1:
print (i)
O/P: 3 5 7 2 4

Using for and range:

Example:

list1 = [3, 5, 7, 2, 4]
length = len (list1)
for i in range (0, len (list1)):
print (list1 [i])
O/P: 3 5 7 2 4

Searching a List
 You can search elements in a list usinh Membership operator
 Membership Check of an element in a list: We can check whether a specific element is
a part/ member of a list or not.

Example:

my_List = [1, 2, 3, 4, 5, 6]
print(3 in my_List)
print(10 in my_List)
print(10 not in my_List)

O/P: True False True

List Concatation

 One list may be concatenated with itself or another list using ‘+’ operator.
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 15
Python Programming (UNIT-5) | 4311601
Example:

List1 = [1, 2, 3, 4]
List2 = [5, 6, 7, 8]
concat_List = List1 + List2
print(concat_List)
O/P: [1, 2, 3, 4, 5, 6, 7, 8]

List Repetition
 We can use the ‘*’ operator to repeat the list elements as many times as we want.

Example:

my_List = [1, 2, 3, 4]
print(my_List*2)
O/P: [1, 2, 3, 4, 1, 2, 3, 4]

List built in methods of list and give their use. WINTER – 2021
Differentiate remove( ) and pop( ) methods of list with suitable example. SUMMER-
2022
List Methods and Built-in Functions

Method Purpose Example


append() Adds an element at the end of the list Example:
fruits = ["apple", "banana",
"cherry"]
fruits.append("orange")
print(fruits)
O/P:['apple', 'banana', 'cherry',
'orange']
insert() Adds an element at the specified position Example:
fruits = ['apple', 'banana', 'cherry']
fruits.insert(1, "orange")
print(fruits)
O/P: ['apple', 'orange', 'banana',

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 16


Python Programming (UNIT-5) | 4311601
'cherry']
extend() Add the elements of a list (or any Example:
iterable), to the end of the current list fruits = ['apple', 'banana', 'cherry']
cars = ['Ford', 'BMW', 'Volvo']
fruits.extend(cars)
print(fruits)
O/P: ['apple', 'banana', 'cherry',
'Ford', 'BMW', 'Volvo']
clear() Removes all the elements from the list Example:
fruits = ["apple", "banana",
"cherry"]
fruits.clear()
print(fruits)
O/P: []
remove() Removes the item with the specified value Example:
fruits = ['apple', 'banana', 'cherry']
fruits.remove("banana")
print(fruits)
O/P: ['apple', 'cherry'][ae', ']

pop() Removes the element at the specified Example:


position.If you do not specify position fruits = ['apple', 'banana', 'cherry']
than it will remove the element from list fruits.pop(1)
which is added last. fruits.pop()

print(fruits)
print(fruits)
O/P: ['apple', 'cherry'] ['apple',
'banana']
count() Returns the number of elements with the Example:
specified value fruits = ["apple", "banana",
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 17
Python Programming (UNIT-5) | 4311601
"cherry"]
x = fruits.count("xyz")
print(x)
fruits = ["apple", "banana",
"cherry","banana"]
x = fruits.count("banana")
print(x)
O/P: 0 2
sort() Sort the list alphabetically Example:
cars = ['Ford', 'BMW', 'Volvo']
cars.sort()
print(cars)
O/P: ['BMW', 'Ford', 'Volvo']
reverse() Reverses the order of the list Example:
fruits = ['apple', 'banana', 'cherry']
fruits.reverse()
print(fruits)
O/P:['cherry', 'banana', 'apple']
index() Returns the index of the first element with Example:
the specified value fruits = ['apple', 'banana',
'cherry','cherry']
x = fruits.index("cherry")
print(x)
O/P:2
min() Returns the smallest of the values or the Example:
smallest item in an list list1 = [10, 20, 4, 45, 99]
print(min(list1))
O/P: 4
max() Returns the largest of the values or the Example:
largest item in an list list1 = [10, 20, 4, 45, 99]
print(max(list1))

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 18


Python Programming (UNIT-5) | 4311601
O/P: 99
sum() Returns sum of all elements of the list Example:
List1=[1,2,3,4,5]
Print(sum(list1))
O/P:15

Nested and Copying Lists:

Explain nested list by giving example. WINTER - 2021


Develop a code to create nested list and display elements. SUMMER-2022
Nested Lists:

 A list can contain another list (sublist), which in turn can contain sublists themselves,
and so on. This is known as nested list.
 You can use them to arrange data into hierarchical structures.

Create a Nested List


A nested list is created by placing a comma-separated sequence of sublists.

L = ['a', 'b', ['cc', 'dd', ['eee', 'fff']], 'g', 'h']

Access Nested List Items by Index


 You can access individual items in a nested list using multiple indexes.
 The indexes for the items in a nested list are illustrated as below:

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 19


Python Programming (UNIT-5) | 4311601

Example:

L = ['a', 'b', ['cc', 'dd', ['eee', 'fff']], 'g', 'h']


print(L[2])
print(L[2][2])
print(L[2][2][0])

O/P: ['cc', 'dd', ['eee', 'fff']] , ['eee', 'fff'] , eee


Copying List

 It is possible to create a copy of existing list into new list.


 In python we can copy an existing list into new list using following methods
(1) Slicing Method

An existing list can be copied into new list using slicing method

Example:
List1=[“A”,”B”,”C”]
List2 = List[ : ]
Print(List2)
O/P: [‘A’,’B’,’C’]
(2) Using list() constructor

An existing list can be copied into new list using list() method

Example:
INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 20
Python Programming (UNIT-5) | 4311601
List1=[“A”,”B”,”C”]
List2 = list(sList1)
Print(List2)
O/P: [‘A’,’B’,’C’]
(3) Using copy() method
An existing list can be copied into new list using copy() method available in standard
library named copy
Example:
Import copy
List1=[“A”,”B”,”C”]
List2 = copy.copy(List1)
Print(List2)
O/P: [‘A’,’B’,’C’]
 We can use assignment operator(=) in order to create an alias of existing list.
 Alias refers to the altername name of list.
Example:
List1=[“A”,”B”,”C”]
List2 = List1
 In above example we assign List1 to List2 using assignment operator.
 It will not create a copy od List1 but it create an alias of List1.
 It means, both List1 and List2 refers to the same element in memory.
 If you can change value of any element in List it will affect to both List.
Example:
List1=[“A”,”B”,”C”]
List2 = List1
List1[0]=”E”
print(List1)
print(List2)
O/P: [‘E’,’B’,’C’] , [‘E’,’B’,’C’]

List as Arguments to Function

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 21


Python Programming (UNIT-5) | 4311601
 You can send list data types of argument to a function and it will be treated as the
same data type inside the function.
 The function uses this alias to refer list.
 Any changes that are made in the list inside function will also affest original list

Example:

def my_function(food):
for x in food:
print(x)
fruits = ["apple", "banana", "cherry"]
my_function(fruits)

O/P: apple banana cherry

**********

“Do not give up, the beginning is always hardest!”

INFORMATION TECHNOLOGY [Mrs. Aesha K. Virani] 22

You might also like