Introduction to Python Programming
Introduction to Python Programming
What is Programming
Programming is a way for us to tell computers what to do. Computer is a very dumb machine and
it only does what we tell it to do. Hence, we learn programming and tell computers to do what we
are very slow at - computation. If I ask you to calculate 5+6, you will immediately say 11. How
about 23453453 X 56456?
You will start searching for a calculator or jump to a new tab to calculate the same. This 100 days
of code series will help you learn python from starting to the end. We will start from 0 and by the
time we end this course, I promise you will be a Job ready Python developer!
What is Python?
Python is a dynamically typed, general purpose programming language that supports an
object-oriented programming approach as well as a functional programming approach.
Python is an interpreted and a high-level programming language.
It was created by Guido Van Rossum in 1989.
Features of Python
Python is simple and easy to understand.
It is Interpreted and platform-independent which makes debugging very easy.
Python is an open-source programming language.
Python provides very big library support. Some of the popular libraries include NumPy,
Tensorflow, Selenium, OpenCV, etc.
It is possible to integrate other programming languages within python.
Why Replit?
Replit is very easy to share tutorials and code.
You can easily fork this repl and continue learning in your own style. Video, code as well as
text tutorial on the same page which makes things easy!
For fellow teachers out there, you create a .tutorial folder to create tutorials using replit.
I then learnt flask and got to work with Flask with a university professor abroad. Long story short,
Python made a huge impact in my career.
1. Built in Modules - These modules are ready to import and use and ships with the python
interpreter. there is no need to install such modules explicitly.
2. External Modules - These modules are imported from a third party file or can be installed
using a package manager like pip or conda. Since this code is written by someone else, we
can install different versions of a same module with time.
import pandas
Code :-
print("Hello World", 7)
print(5)
print("Bye")
print(17*13)
Quick Quiz
Write a program to print a poem in Python. Choose the poem of your choice and publish your repl
Single-Line Comments:
To write a comment just add a ‘#’ at the start of the line.
Example 1
#This is a 'Single-Line Comment'
print("This is a print statement.")
Output:
Multi-Line Comments:
To write multi-line comments you can use ‘#’ at each line or you can use the multiline string.
p is greater than 5.
Example 2: The use of multiline string.
An escape sequence character is a backslash \ followed by the character you want to insert.
An example of a character that cannot be directly used in a string is a double quote inside a string
that is surrounded by double quotes:
a=1
print(type(a))
b = "1"
print(type(b))
By default, python provides the following built-in data types:
3. Boolean data:
Boolean data consists of values True or False.
Example:
Example:
Example:
Code Output
a = complex(8, 2)
(8+2j)
b = True
True
c = "Harry"
(17+2j)
d = None
The type of a is <class 'complex'>
print(a)
The type of b is <class 'bool'>
print(b)
The type of c is <class 'str'>
a1 = 9
[8, 2.3, [-4, 5], ['apple', 'banana']]
print(a + a1)
(('parrot', 'sparrow'), ('Lion', 'Tiger'))
print("The type of a is ", type(a))
{'name': 'Sakshi', 'age': 20, 'canVote': True}
print("The type of b is ", type(b))
print("The type of c is ", type(c))
list1 = [8, 2.3, [-4, 5], ["apple", "banana"]]
print(list1)
tuple1 = (("parrot", "sparrow"), ("Lion", "Tiger"))
print(tuple1)
dict1 = {"name":"Sakshi", "age":20, "canVote":True}
print(dict1)
Operators
Python has different types of operators for different operations. To create a calculator we require
arithmetic operators.
Arithmetic operators
Operator Operator Name Example
+ Addition 15+7
- Subtraction 15-7
* Multiplication 5*7
** Exponential 5**3
/ Division 5/3
% Modulus 15%7
// Floor Division 15//7
Exercise
n = 15
m=7
ans1 = n+m
print("Addition of",n,"and",m,"is", ans1)
ans2 = n-m
print("Subtraction of",n,"and",m,"is", ans2)
ans3 = n*m
print("Multiplication of",n,"and",m,"is", ans3)
ans4 = n/m
print("Division of",n,"and",m,"is", ans4)
ans5 = n%m
print("Modulus of",n,"and",m,"is", ans5)
ans6 = n//m
print("Floor Division of",n,"and",m,"is", ans6)
Explaination
Here 'n' and 'm' are two variables in which the integer value is being stored. Variables 'ans1' ,
'ans2' ,'ans3', 'ans4','ans5' and 'ans6' contains the outputs corresponding to addition,
subtraction, multiplication, division, modulus and floor division respectively.
a = 50
b=3
print("The value of", a, "+", 3, "is: ", a + b)
print("The value of", a, "-", 3, "is: ", a - b)
print("The value of", a, "*", 3, "is: ", a * b)
print("The value of", a, "/", 3, "is: ", a / b)
Typecasting in python
The conversion of one data type into the other data type is known as type casting in python or
type conversion in python.
Python supports a wide variety of functions or methods like: int(), float(), str(), ord(), hex(), oct(),
tuple(), set(), list(), dict(), etc. for the type casting in python.
It can be achieved with the help of Python’s built-in type conversion functions such as int(),
float(), hex(), oct(), str(), etc .
Python converts a smaller data type to a higher data type to prevent data loss.
Syntax:
variable=input()
But input function returns the value as string. Hence we have to typecast them whenever
required to another datatype.
Example:
variable=int(input())
variable=float(input())
We can also display a text using input function. This will make input() function take user input
and display a message as well
Example:
a=input("Enter the name: ")
print(a)
Output:
Enter the name: Harry
Harry
Code Output
a = input("Enter your name: ")
print("My name is", a) Enter your name: Kamlesh Kumar
My name is Kamlesh Kumar
x = input("Enter first number: ") Enter first number: 797982
y = input("Enter second number: ") Enter second number: 7528
print(x + y) 7979827528
print(int(x) + int(y)) 805510
Example Output
name = "Harry" Hello, Harry
print("Hello, " + name)
Note: It does not matter whether you enclose your strings in single or double quotes, the output
remains the same.
Sometimes, the user might need to put quotation marks in between the strings. Example,
consider the sentence: He said, “I want to eat an apple”.
How will you print this statement in python?: He said, "I want to eat an apple". We will definitely use
single quotes for our convenience
Multiline Strings
If our string has multiple lines, we can create them like this:
print(name[0])
print(name[1])
"
I
w
a
n
t
t
o
e
a
t
a
n
a
p
p
l
e
String Slicing & Operations on String
Length of a String
We can find the length of a string using len() function.
Example: Output:
fruit = "Mango"
len1 = len(fruit)
Mango is a 5 letter word.
print("Mango is a", len1, "letter word.")
String as an array
A string is essentially a sequence of characters also called an array. Thus we can access the
elements of this array.
Example: Output:
pie = "ApplePie" Apple
print(pie[:5]) i
print(pie[6]) #returns character at specified index
Note: This method of specifying the start and end index to specify a part of a string is called
slicing.
Example: Output:
A
alphabets = "ABCDE" B
for i in alphabets: C
print(i) D
E
Code Output:
fruit = "Mango"
5
mangoLen = len(fruit)
print(mangoLen) Mang
print(fruit[0:4]) # including 0 but not 4 ang
print(fruit[1:4]) # including 1 but not 4 Mango
print(fruit[:5]) Ma
print(fruit[0:-3])
print(fruit[:len(fruit)-3]) Ma
print(fruit[-1:len(fruit) - 3])
print(fruit[-3:-1]) ng
String methods
Python provides a set of built-in methods that we can use to alter and modify the strings.
upper() :
The upper() method converts a string to upper case.
Example: Output:
str1 = "AbcDEfghIJ"
ABCDEFGHIJ
print([Link]())
lower()
The lower() method converts a string to lower case.
Example: Output:
str1 = "AbcDEfghIJ"
abcdefghij
print([Link]())
strip() :
The strip() method removes any white spaces before and after the string.
Example: Output:
str2 = " Silver Spoon "
Silver Spoon
print([Link])
rstrip() :
the rstrip() removes any trailing characters.
Example:
str3 = "Hello !!!"
print([Link]("!"))
Output:
Hello
replace() :
The replace() method replaces all occurences of a string with another string. Example:
split() :
The split() method splits the given string at the specified instance and returns the separated
strings as list items.
Example:
str2 = "Silver Spoon"
print([Link](" ")) #Splits the string at the whitespace " ".
Output:
['Silver', 'Spoon']
There are various other string methods that we can use to modify our strings.
capitalize() :
The capitalize() method turns only the first character of the string to uppercase and the rest other
characters of the string are turned to lowercase. The string has no effect if the first character is
already uppercase.
Example: Output:
str1 = "hello"
Hello
capStr1 = [Link]()
Hello world
print(capStr1)
str2 = "hello WorlD"
capStr2 = [Link]()
print(capStr2)
center() :
The center() method aligns the string to the center as per the parameters given by the user.
Example:
str1 = "Welcome to the Console!!!"
print([Link](50))
Output:
Welcome to the Console!!!
We can also provide padding character. It will fill the rest of the fill characters provided by the
user.
Example:
str1 = "Welcome to the Console!!!"
print([Link](50, "."))
Output:
............Welcome to the Console!!!.............
count() :
The count() method returns the number of times the given value has occurred within the given
string.
Example:
str2 = "Abracadabra"
countStr = [Link]("a")
print(countStr)
Output:
4
endswith() :
The endswith() method checks if the string ends with a given value. If yes then return True, else
return False.
Example :
str1 = "Welcome to the Console !!!"
print([Link]("!!!"))
Output:
True
We can even also check for a value in-between the string by providing start and end index
positions.
Example:
str1 = "Welcome to the Console !!!"
print([Link]("to", 4, 10))
Output:
True
find() :
The find() method searches for the first occurrence of the given value and returns the index
where it is present. If given value is absent from the string then return -1.
Example:
str1 = "He's name is Dan. He is an honest man."
print([Link]("is"))
Output:
10
As we can see, this method is somewhat similar to the index() method. The major difference
being that index() raises an exception if value is absent whereas find() does not.
Example:
str1 = "He's name is Dan. He is an honest man."
print([Link]("Daniel"))
Output:
-1
index() :
The index() method searches for the first occurrence of the given value and returns the index
where it is present. If given value is absent from the string then raise an exception.
Example:
str1 = "He's name is Dan. Dan is an honest man."
print([Link]("Dan"))
Output:
13
As we can see, this method is somewhat similar to the find() method. The major difference being
that index() raises an exception if value is absent whereas find() does not.
Example:
str1 = "He's name is Dan. Dan is an honest man."
print([Link]("Daniel"))
Output:
ValueError: substring not found
isalnum() :
The isalnum() method returns True only if the entire string only consists of A-Z, a-z, 0-9. If any
other characters or punctuations are present, then it returns False.
Example 1:
str1 = "WelcomeToTheConsole"
print([Link]())
Output:
True
isalpha() :
The isalpha() method returns True only if the entire string only consists of A-Z, a-z. If any other
characters or punctuations or numbers(0-9) are present, then it returns False.
Example :
str1 = "Welcome"
print([Link]())
Output:
True
islower() :
The islower() method returns True if all the characters in the string are lower case, else it returns
False.
Example:
str1 = "hello world"
print([Link]())
Output:
True
isprintable() :
The isprintable() method returns True if all the values within the given string are printable, if not,
then return False.
Example :
str1 = "We wish you a Merry Christmas"
print([Link]())
Output:
True
isspace() :
The isspace() method returns True only and only if the string contains white spaces, else returns
False.
Example: Output:
str1 = " " #using Spacebar
True
print([Link]())
True
str2 = " " #using Tab
print([Link]())
istitle() :
The istitile() returns True only if the first letter of each word of the string is capitalized, else it
returns False.
Example:
str1 = "World Health Organization"
print([Link]())
Output:
True
Example:
str2 = "To kill a Mocking bird"
print([Link]())
Output:
False
isupper() :
The isupper() method returns True if all the characters in the string are upper case, else it returns
False.
Example :
str1 = "WORLD HEALTH ORGANIZATION"
print([Link]())
Output:
True
startswith() :
The endswith() method checks if the string starts with a given value. If yes then return True, else
return False.
Example :
str1 = "Python is a Interpreted Language"
print([Link]("Python"))
Output:
True
swapcase() :
The swapcase() method changes the character casing of the string. Upper case are converted to
lower case and lower case to upper case.
Example:
str1 = "Python is a Interpreted Language"
print([Link]())
Output:
pYTHON IS A iNTERPRETED lANGUAGE
title() :
The title() method capitalizes each letter of the word within the string.
Example:
str1 = "He's name is Dan. Dan is an honest man."
print([Link]())
Output:
He's Name Is Dan. Dan Is An Honest Man.
if-else Statements
Sometimes the programmer needs to check the evaluation of certain expression(s), whether the
expression(s) evaluate to True or False. If the expression evaluates to False, then the program
execution follows a different path than it would have if the expression had evaluated to True.
Based on this, the conditional statements are further classified into following types:
if
if-else
if-else-elif
nested if-else-elif.
Example: Output:
applePrice = 210
budget = 200
Alexa, do not add Apples to the cart.
if (applePrice <= budget):
print("Alexa, add 1 kg Apples to the cart.")
else:
print("Alexa, do not add Apples to the cart.")
elif Statements
Sometimes, the programmer may want to evaluate more than one condition, this can be done
using an elif statement.
Execute the block of code inside the first elif statement if the expression inside it evaluates True.
After execution return to the code out of the if block.
Execute the block of code inside the second elif statement if the expression inside it evaluates
True. After execution return to the code out of the if block.
.
.
.
Execute the block of code inside the nth elif statement if the expression inside it evaluates True.
After execution return to the code out of the if block.
Execute the block of code inside else statement if none of the expression evaluates to True. After
execution return to the code out of the if block.
Example: Output:
num = 0 Number is Zero.
if (num < 0):
print("Number is negative.")
elif (num == 0):
print("Number is Zero.")
else:
print("Number is positive.")
Nested if statements
We can use if, if-else, elif statements inside other if statements as well.
Example:
num = 18
if (num < 0): Output:
print("Number is negative.")
elif (num > 0): Number is between 11-20
if (num <= 10):
print("Number is between 1-10")
elif (num > 10 and num <= 20):
print("Number is between 11-20")
else:
print("Number is greater than 20")
else:
print("Number is zero")
import time
timestamp = [Link]('%H:%M:%S')
print(timestamp)
timestamp = [Link]('%H')
print(timestamp)
timestamp = [Link]('%M')
print(timestamp)
timestamp = [Link]('%S')
print(timestamp)
# [Link]
Match Case Statements
To implement switch-case like characteristics very similar to if-else functionality, we use a match
case in python. If you are coming from a C, C++ or Java like language, you must have heard of
switch-case statements. If this is your first language, dont worry as I will tell you everything you
need to know about match case statements in this video!
A match statement will compare a given variable’s value to different shapes, also referred to as
the pattern. The main idea is to keep on comparing the variable with all the present patterns until
it fits into one.
Syntax:
match variable_name:
case ‘pattern1’ : //statement1
case ‘pattern2’ : //statement2
…
case ‘pattern n’ : //statement n
Example:
x=4
# x is the variable to match
match x:
# if x is 0
case 0:
print("x is zero")
# case with if-condition
case 4 if x % 2 == 0:
print("x % 2 == 0 and case is 4")
# Empty case with if-condition
case _ if x < 10:
print("x is < 10")
# default case(will only be matched if the above cases were not matched)
# so it is basically just an else:
case _:
print(x)
Output:
x % 2 == 0 and case is 4
Code
x = int(input("Enter the value of x: "))
# x is the variable to match
match x:
Output python3 [Link]
# if x is 0
case 0: python3 [Link] Enter the value of x: 85
print("x is zero")
# case with if-condition Enter the value of x: 4 85 is not 90
case 4:
print("case is 4") case is 4
case _ if x!=90:
print(x, "is not 90")
case _ if x!=80:
print(x, "is not 80")
case _:
print(x)
Introduction to Loops
Sometimes a programmer wants to execute a group of statements a certain number of times. This can be done
using loops. Based on this loops are further classified into following main types;
for loop
while loop
Output:
Red
Green
Blue
Yellow
range():
What if we do not want to iterate over a sequence? What if we want to use for loop for a specific number of
times?
Example:
for k in range(4,9):
print(k)
Output:
4
5
6
7
8
Quick Quiz
Explore about third parameter of range (ie range(x, y, z))
Example:
count = 5
while (count > 0):
print(count)
count = count - 1
Output:
5
4
3
2
1
Here, the count variable is set to 5 which decrements after each iteration. Depending upon the while loop
condition, we need to either increment or decrement the counter variable (the variable count, in our case) or
the loop will continue forever.
Else with While Loop
We can even use the else statement with the while loop. Essentially what the else statement does is that as
soon as the while loop condition becomes False, the interpreter comes out of the while loop and the else
statement is executed.
Example:
x=5
while (x > 0):
print(x)
x=x-1
else:
print('counter is 0')
Copied!
Output:
5
4
3
2
1
counter is 0
The most common technique to emulate a do-while loop in Python is to use an infinite while loop with a break
statement wrapped in an if statement that checks a given condition and breaks the iteration if that condition
becomes true:
Example
while True:
number = int(input("Enter a positive number: "))
print(number)
if not number > 0:
break
Output
Enter a positive number: 1
1
Enter a positive number: 4
4
Enter a positive number: -1
-1
Explanation
This loop uses True as its formal condition. This trick turns the loop into an infinite loop. Before the conditional
statement, the loop runs all the required processing and updates the breaking condition. If this condition
evaluates to true, then the break statement breaks out of the loop, and the program execution continues its
normal path.
Break statement
The break statement enables a program to skip over a part of the code. A break statement terminates the very
loop it lies within.
example
for i in range(1,101,1):
print(i ,end=" ")
if(i==50):
break
else:
print("Mississippi")
print("Thank you")
output
1 Mississippi
2 Mississippi
3 Mississippi
4 Mississippi
5 Mississippi
.
.
.
49 Mississippi
50 Thank you
Continue Statement
The continue statement skips the rest of the loop statements and causes the next iteration to occur.
example
for i in [2,3,4,6,8,0]:
if (i%2!=0):
continue
print(i)
Copied!
output
2
4
6
8
0
Python Functions
A function is a block of code that performs a specific task whenever it is called. In bigger programs, where we
have large amounts of code, it is advisable to create or use existing functions that make the program flow
organized and neat.
1. Built-in functions
2. User-defined functions
Built-in functions:
These functions are defined and pre-coded in python. Some examples of built-in functions are as follows:
min(), max(), len(), sum(), type(), range(), dict(), list(), tuple(), set(), print(), etc.
User-defined functions:
We can create functions to perform specific tasks as per our needs. Such functions are called user-defined
functions.
Syntax:
def function_name(parameters):
pass
# Code and Statements
Create a function using the def keyword, followed by a function name, followed by a paranthesis (())
and a colon(:).
Any parameters and arguments should be placed within the parentheses.
Rules to naming function are similar to that of naming variables.
Any statements and other code within the function should be indented.
Calling a function:
We call a function by giving the function name, followed by parameters (if any) in the parenthesis.
Example:
Output:
Hello, Sam Wilson
Code: Output:
def calculateGmean(a, b):
mean = (a*b)/(a+b) First number is greater
print(mean)
4.235294117647059
def isGreater(a, b):
Second number is greater or equal
if(a>b):
print("First number is greater") 7.219512195121951
else:
print("Second number is greater or equal")
a=9
b=8
isGreater(a, b)
calculateGmean(a, b)
# gmean1 = (a*b)/(a+b)
# print(gmean1)
c=8
d = 74
isGreater(c, d)
calculateGmean(c, d)
# gmean2 = (c*d)/(c+d)
# print(gmean2)
Default Arguments
Keyword Arguments
Variable length Arguments
Required Arguments
Default arguments:
We can provide a default value while creating a function. This way the function assumes a default value even if
a value is not provided in the function call for that argument.
Example:
name("Amy")
Output:
Hello, Amy Jhon Whatson
Keyword arguments:
We can provide arguments with key = value, this way the interpreter recognizes the arguments by the
parameter name. Hence, the the order in which the arguments are passed does not matter.
Example:
Required arguments:
In case we don’t pass the arguments with a key = value syntax, then it is necessary to pass the arguments in
the correct positional order and the number of arguments passed should match with actual function definition.
Example 1: when number of arguments passed does not match to the actual function definition.
name("Peter", "Quill")
Output:
name("Peter", "Quill")\
TypeError: name() missing 1 required positional argument: 'lname'
Example 2: when number of arguments passed matches to the actual function definition.
Output:
Hello, Peter Ego Quill
Variable-length arguments:
Sometimes we may need to pass more arguments than those defined in the actual function. This can be done
using variable-length arguments.
Arbitrary Arguments:
While creating a function, pass a * before the parameter name while defining the function. The function
accesses the arguments by processing them in the form of tuple.
Example:
def name(*name):
print("Hello,", name[0], name[1], name[2])
name("James", "Buchanan", "Barnes")
Output:
Example:
def name(**name):
print("Hello,", name["fname"], name["mname"], name["lname"])
return Statement
The return statement is used to return the value of the expression back to the calling function.
Example:
Python Lists
Lists are ordered collection of data items.
They store multiple items in a single variable.
List items are separated by commas and enclosed within square brackets [].
Lists are changeable meaning we can alter them after creation.
Example 1:
lst1 = [1,2,2,3,5,4,6]
lst2 = ["Red", "Green", "Blue"]
print(lst1)
print(lst2)
Output:
[1, 2, 2, 3, 5, 4, 6]
['Red', 'Green', 'Blue']
Example 2:
Output:
List Index
Each item/element in a list has its own unique index. This index can be used to access any particular item from
the list. The first item has index [0], second item has index [1], third item has index [2] and so on.
Example:
colors = ["Red", "Green", "Blue", "Yellow", "Green"]
# [0] [1] [2] [3] [4]
Positive Indexing:
As we have seen that list items have index, as such we can access items using these indexes.
Example:
colors = ["Red", "Green", "Blue", "Yellow", "Green"]
# [0] [1] [2] [3] [4]
print(colors[2])
print(colors[4])
print(colors[0])
Output:
Blue
Green
Red
Negative Indexing:
Similar to positive indexing, negative indexing is also used to access items, but from the end of the list. The last
item has index [-1], second last item has index [-2], third last item has index [-3] and so on.
Example:
colors = ["Red", "Green", "Blue", "Yellow", "Green"]
# [-5] [-4] [-3] [-2] [-1]
print(colors[-1])
print(colors[-3])
print(colors[-5])
Output
Green:
Blue
Red
Range of Index:
You can print a range of list items by specifying where you want to start, where do you want to end and if you
want to skip elements in between the range.
Syntax:
animals = ["cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow"]
print(animals[3:7]) #using positive indexes
print(animals[-7:-2]) #using negative indexes'
Output:
['mouse', 'pig', 'horse', 'donkey']
['bat', 'mouse', 'pig', 'horse', 'donkey']
Here, we provide index of the element from where we want to start and the index of the element till which we
want to print the values.
Note: The element of the end index provided will not be included.
Example: printing all element from a given index till the end
animals = ["cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow"]
print(animals[4:]) #using positive indexes
print(animals[-4:]) #using negative indexes
Output:
['pig', 'horse', 'donkey', 'goat', 'cow']
['horse', 'donkey', 'goat', 'cow']
When no end index is provided, the interpreter prints all the values till the end.
animals = ["cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow"]
print(animals[:6]) #using positive indexes
print(animals[:-3]) #using negative indexes
Output:
['cat', 'dog', 'bat', 'mouse', 'pig', 'horse']
['cat', 'dog', 'bat', 'mouse', 'pig', 'horse']
When no start index is provided, the interpreter prints all the values from start up to the end index provided.
animals = ["cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow"]
print(animals[::2]) #using positive indexes
print(animals[-8:-1:2]) #using negative indexes
Output:
['cat', 'bat', 'pig', 'donkey', 'cow']
['dog', 'mouse', 'horse', 'goat']
Here, we have not provided start and index, which means all the values will be considered. But as we have
provided a jump index of 2 only alternate values will be printed.
animals = ["cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow"]
print(animals[Link])
Output:
['dog', 'pig', 'goat
Here, jump index is 3. Hence it prints every 3rd element within given index.
List Comprehension
List comprehensions are used for creating new lists from other iterables like lists, tuples, dictionaries, sets, and
even in arrays and strings.
Syntax:
List = [Expression(item) for item in iterable if Condition]
Iterable: It can be list, tuples, dictionaries, sets, and even in arrays and strings.
Condition: Condition checks if the item should be added to the new list or not.
Example 1: Accepts items with the small letter “o” in the new list
Output:
['Milo', 'Bruno', 'Rosa']
Output:
['Sarah', 'Bruno', 'Anastasia']
List Methods
[Link]()
This method sorts the list in ascending order. The original list is updated
Example 1:
colors = ["voilet", "indigo", "blue", "green"]
[Link]()
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
[Link]()
print(num)
Output:
['blue', 'green', 'indigo', 'voilet']\
[1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9]
Example:
colors = ["voilet", "indigo", "blue", "green"]
[Link](reverse=True)
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
[Link](reverse=True)
print(num)
Output:
['voilet', 'indigo', 'green', 'blue']
[9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 1, 1]
Note: Do not mistake the reverse parameter with the reverse method.
reverse()
This method reverses the order of the list.
Example:
colors = ["voilet", "indigo", "blue", "green"]
[Link]()
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
[Link]()
print(num)
Output:
['green', 'blue', 'indigo', 'voilet']
[7, 9, 8, 2, 1, 2, 1, 6, 3, 5, 2, 4]
index()
This method returns the index of the first occurrence of the list item.
Example:
colors = ["voilet", "green", "indigo", "blue", "green"]
print([Link]("green"))
num = [4,2,5,3,6,1,2,1,3,2,8,9,7]
print([Link](3))
Output:
1
3
count()
Returns the count of the number of items with the given value.
Example:
colors = ["voilet", "green", "indigo", "blue", "green"]
print([Link]("green"))
num = [4,2,5,3,6,1,2,1,3,2,8,9,7]
Output:
2
3
copy()
Returns copy of the list. This can be done to perform operations on the list without modifying the original list.
Example:
colors = ["voilet", "green", "indigo", "blue"]
newlist = [Link]()
print(colors)
print(newlist)
Output:
['voilet', 'green', 'indigo', 'blue']
['voilet', 'green', 'indigo', 'blue']
append():
This method appends items to the end of the existing list.
Example:
colors = ["voilet", "indigo", "blue"]
[Link]("green")
print(colors)
Output:
['voilet', 'indigo', 'blue', 'green']
insert():
This method inserts an item at the given index. User has to specify index and the item to be inserted within the
insert() method.
Example:
colors = ["voilet", "indigo", "blue"]
# [0] [1] [2]
print(colors)
Output:
['voilet', 'green', 'indigo', 'blue']
extend():
This method adds an entire list or any other collection datatype (set, tuple, dictionary) to the existing list.
Example 1:
#add a list to a list
colors = ["voilet", "indigo", "blue"]
rainbow = ["green", "yellow", "orange", "red"]
[Link](rainbow)
print(colors)
Output:
['voilet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red']
Example:
colors = ["voilet", "indigo", "blue", "green"]
colors2 = ["yellow", "orange", "red"]
print(colors + colors2)
Output:
['voilet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red']
Python Tuples
Tuples are ordered collection of data items. They store multiple items in a single variable. Tuple items are
separated by commas and enclosed within round brackets (). Tuples are unchangeable meaning we can not
alter them after creation.
Example 1:
tuple1 = (1,2,2,3,5,4,6)
tuple2 = ("Red", "Green", "Blue")
print(tuple1)
print(tuple2)
Output:
(1, 2, 2, 3, 5, 4, 6)
('Red', 'Green', 'Blue')
Example 2:
details = ("Abhijeet", 18, "FYBScIT", 9.8)
print(details)
Output:
('Abhijeet', 18, 'FYBScIT', 9.8)
Tuple Indexes
Each item/element in a tuple has its own unique index. This index can be used to access any particular item
from the tuple. The first item has index [0], second item has index [1], third item has index [2] and so on.
Example:
country = ("Spain", "Italy", "India",)
# [0] [1] [2]
Example:
Output:
Spain
Italy
India
II. Negative Indexing:
Similar to positive indexing, negative indexing is also used to access items, but from the end of the tuple. The
last item has index [-1], second last item has index [-2], third last item has index [-3] and so on.
Example:
country = ("Spain", "Italy", "India", "England", "Germany")
# [0] [1] [2] [3] [4]
print(country[-1]) # Similar to print(country[len(country) - 1])
print(country[-3])
print(country[-4])
Output:
Germany
India
Italy
Example 1:
country = ("Spain", "Italy", "India", "England", "Germany")
if "Germany" in country:
print("Germany is present.")
else:
print("Germany is absent.")
Output:
Germany is present.
Example 2:
country = ("Spain", "Italy", "India", "England", "Germany")
if "Russia" in country:
print("Russia is present.")
else:
print("Russia is absent.")
Output:
Russia is absent.
Syntax:
Tuple[start : end : jumpIndex]
Note: jump Index is optional. We will see this in given examples.
Here, we provide index of the element from where we want to start and the index of the element till which we
want to print the values. Note: The element of the end index provided will not be included.
Example: Printing all element from a given index till the end
animals = ("cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow")
print(animals[4:]) #using positive indexes
print(animals[-4:]) #using negative indexes
Output:
('pig', 'horse', 'donkey', 'goat', 'cow')
('horse', 'donkey', 'goat', 'cow')
When no end index is provided, the interpreter prints all the values till the end.
Output:
('cat', 'dog', 'bat', 'mouse', 'pig', 'horse')
('cat', 'dog', 'bat', 'mouse', 'pig', 'horse')
When no start index is provided, the interpreter prints all the values from start up to the end index provided.
Output:
('cat', 'bat', 'pig', 'donkey', 'cow')
('dog', 'mouse', 'horse', 'goat')
Here, we have not provided start and end index, which means all the values will be considered. But as we have
provided a jump index of 2 only alternate values will be printed.
Output:
('dog', 'pig', 'goat')
Here, jump index is 3. Hence it prints every 3rd element within given index.
Manipulating Tuples
Tuples are immutable, hence if you want to add, remove or change tuple items, then first you must convert the
tuple to a list. Then perform operation on that list and convert it back to tuple.
Example:
countries = ("Spain", "Italy", "India", "England", "Germany")
temp = list(countries)
[Link]("Russia") #add item
[Link](3) #remove item
temp[2] = "Finland" #change item
countries = tuple(temp)
print(countries)
Output:
('Spain', 'Italy', 'Finland', 'Germany', 'Russia')
Thus, we convert the tuple to a list, manipulate items of the list using list methods, then convert list back to a
tuple.
However, we can directly concatenate two tuples without converting them to list.
Example:
countries = ("Pakistan", "Afghanistan", "Bangladesh", "ShriLanka")
countries2 = ("Vietnam", "India", "China")
southEastAsia = countries + countries2
print(southEastAsia)
Output:
('Pakistan', 'Afghanistan', 'Bangladesh', 'ShriLanka', 'Vietnam', 'India', 'China')
Tuple methods
As tuple is immutable type of collection of elements it have limited built in [Link] are explained below
count() Method
The count() method of Tuple returns the number of times the given element appears in the tuple.
Syntax:
[Link](element)
Example
Tuple1 = (0, 1, 2, 3, 2, 3, 1, 3, 2)
res = [Link](3)
print('Count of 3 in Tuple1 is:', res)
Output
3
index() method
The Index() method returns the first occurrence of the given element from the tuple.
Syntax:
[Link](element, start, end)
Note: This method raises a ValueError if the element is not found in the tuple.
Example
Tuple = (0, 1, 2, 3, 2, 3, 1, 3, 2)
res = [Link](3)
print('First occurrence of 3 is', res)
Output
3
import time
timestamp = [Link]('%H:%M:%S')
print(timestamp)
timestamp = [Link]('%H')
print(timestamp)
timestamp = [Link]('%M')
print(timestamp)
timestamp = [Link]('%S')
print(timestamp)
# [Link]
import time
t = [Link]('%H:%M:%S')
hour = int([Link]('%H'))
# hour = int(input("Enter hour: "))
# print(hour)
Excersice 3
Create a program capable of displaying questions to the user like KBC. Use List data type to store the questions
and their correct answers. Display the final amount the person is taking home after playing the game.
String formatting in python
String formatting can be done in python using the format method.
f-strings in python
It is a new string formatting mechanism introduced by the PEP 498. It is also known as Literal String
Interpolation or more commonly as F-strings (f character preceding the string literal). The primary focus of this
mechanism is to make the interpolation easier.
When we prefix the string with the letter 'f', the string becomes the f-string itself. The f-string can be formatted
in much same as the [Link]() method. The f-string offers a convenient way to embed Python expression
inside string literals for formatting.
Example
val = 'Geeks'
print(f"{val}for{val} is a portal for {val}.")
name = 'Tushar'
age = 23
print(f"Hello, My name is {name} and I'm {age} years old.")
Output:
Hello, My name is Tushar and I'm 23 years old.
In the above code, we have used the f-string to format the string. It evaluates at runtime; we can put all valid
Python expressions in them.
Example
print(f"{2 * 30})"
Output:
60
Docstrings in python
Python docstrings are the string literals that appear right after the definition of a function, method, class, or
module.
Example
def square(n):
'''Takes in a number n, returns the square of n'''
print(n**2)
square(5)
Here,
'''Takes in a number n, returns the square of n''' is a docstring which will not appear in output
Output:
25
This function simply wraps the ``+`` operator, and does not
do anything interesting, except for illustrating what
the docstring of a very simple function looks like.
Parameters
----------
num1 : int
First number to add.
num2 : int
Second number to add.
Returns
-------
int
The sum of ``num1`` and ``num2``.
See Also
--------
subtract : Subtract one integer from another.
Examples
--------
>>> add(2, 2)
4
>>> add(25, 0)
25
>>> add(10, -10)
0
"""
return num1 + num2
Python docstrings
As mentioned above, Python docstrings are strings used right after the definition of a function, method, class,
or module (like in Example 1). They are used to document our code.
Example
def square(n):
'''Takes in a number n, returns the square of n'''
return n**2
print(square.__doc__)
Output:
Takes in a number n, returns the square of n
PEP 8
PEP 8 is a document that provides guidelines and best practices on how to write Python code. It was written in
2001 by Guido van Rossum, Barry Warsaw, and Nick Coghlan. The primary focus of PEP 8 is to improve the
readability and consistency of Python code.
PEP stands for Python Enhancement Proposal, and there are several of them. A PEP is a document that
describes new features proposed for Python and documents aspects of Python, like design and style, for the
community.
Easter egg
import this
Recursion in python
Recursion is the process of defining something in terms of itself.
Example:
def factorial(num):
if (num == 1 or num == 0):
return 1
else:
return (num * factorial(num - 1))
# Driver Code
num = 7;
print("Number: ",num)
print("Factorial: ",factorial(num))
Output:
number: 7
Factorial: 5040
Python Sets
Sets are unordered collection of data items. They store multiple items in a single variable. Set items are
separated by commas and enclosed within curly brackets {}. Sets are unchangeable, meaning you cannot
change items of the set once created. Sets do not contain duplicate items.
Example:
info = {"Carla", 19, False, 5.9, 19}
print(info)
Output:
{False, 19, 5.9, 'Carla'}
Here we see that the items of set occur in random order and hence they cannot be accessed using index
numbers. Also sets do not allow duplicate values.
Quick Quiz: Try to create an empty set. Check using the type() function whether the type of your variable is a
set
Example:
info = {"Carla", 19, False, 5.9}
for item in info:
print(item)
Output:
False
Carla
19
5.9
Joining Sets
Sets in python more or less work in the same way as sets in mathematics. We can perform operations like
union and intersection on the sets just like in mathematics.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Tokyo", "Seoul", "Kabul", "Madrid"}
cities3 = [Link](cities2)
print(cities3)
Output:
{'Tokyo', 'Madrid', 'Kabul', 'Seoul', 'Berlin', 'Delhi'}
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Tokyo", "Seoul", "Kabul", "Madrid"}
[Link](cities2)
print(cities)
Output:
{'Berlin', 'Madrid', 'Tokyo', 'Delhi', 'Kabul', 'Seoul'}
Set Methods
There are several in-built methods used for the manipulation of [Link] are explained below
isdisjoint():
The isdisjoint() method checks if items of given set are present in another set. This method returns False if
items are present, else it returns True.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Tokyo", "Seoul", "Kabul", "Madrid"}
print([Link](cities2))
Output:
False
issuperset():
The issuperset() method checks if all the items of a particular set are present in the original set. It returns True
if all the items are present, else it returns False.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Seoul", "Kabul"}
print([Link](cities2))
cities3 = {"Seoul", "Madrid","Kabul"}
print([Link](cities3))
Output:
False
False
issubset():
The issubset() method checks if all the items of the original set are present in the particular set. It returns True
if all the items are present, else it returns False.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Delhi", "Madrid"}
print([Link](cities))
Output:
True
add()
If you want to add a single item to the set use the add() method.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
[Link]("Helsinki")
print(cities)
Output:
{'Tokyo', 'Helsinki', 'Madrid', 'Berlin', 'Delhi'}
update()
If you want to add more than one item, simply create another set or any other iterable object(list, tuple,
dictionary), and use the update() method to add it into the existing set.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities2 = {"Helsinki", "Warsaw", "Seoul"}
[Link](cities2)
print(cities)
Output:
{'Seoul', 'Berlin', 'Delhi', 'Tokyo', 'Warsaw', 'Helsinki', 'Madrid'}
remove()/discard()
We can use remove() and discard() methods to remove items form list.
Example :
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
[Link]("Tokyo")
print(cities)
Output:
{'Delhi', 'Berlin', 'Madrid'}
The main difference between remove and discard is that, if we try to delete an item which is not present in set,
then remove() raises an error, whereas discard() does not raise any error.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
[Link]("Seoul")
print(cities)
Output:
KeyError: 'Seoul'
pop()
This method removes the last item of the set but the catch is that we don’t know which item gets popped as
sets are unordered. However, you can access the popped item if you assign the pop() method to a variable.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
item = [Link]()
print(cities)
print(item)
Output:
{'Tokyo', 'Delhi', 'Berlin'} Madrid
del
del is not a method, rather it is a keyword which deletes the set entirely.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
del cities
print(cities)
Output:
NameError: name 'cities' is not defined We get an error because our entire set has been deleted and there is no
variable called cities which contains a set.
What if we don’t want to delete the entire set, we just want to delete all items within that set?
clear():
This method clears all items in the set and prints an empty set.
Example:
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
[Link]()
print(cities)
Output:
set()
Example
info = {"Carla", 19, False, 5.9}
if "Carla" in info:
print("Carla is present.")
else:
print("Carla is absent.")
Output:
Carla is present.
Python Dictionaries
Dictionaries are ordered collection of data items. They store multiple items in a single variable. Dictionary items
are key-value pairs that are separated by commas and enclosed within curly brackets {}.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print(info)
Output:
{'name': 'Karan', 'age': 19, 'eligible': True}
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print(info['name'])
print([Link]('eligible'))
Output:
Karan
True
II. Accessing multiple values:
We can print all the values in the dictionary using values() method.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print([Link]())
Output:
dict_values(['Karan', 19, True])
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print([Link]())
Output:
dict_keys(['name', 'age', 'eligible'])
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print([Link]())
Output:
dict_items([('name', 'Karan'), ('age', 19), ('eligible', True)])
Dictionary Methods
Dictionary uses several built-in methods for [Link] are listed below
update()
The update() method updates the value of the key provided to it if the item already exists in the dictionary, else
it creates a new key-value pair.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print(info)
[Link]({'age':20})
[Link]({'DOB':2001})
print(info)
Output:
{'name': 'Karan', 'age': 19, 'eligible': True}
{'name': 'Karan', 'age': 20, 'eligible': True, 'DOB': 2001}
clear():
The clear() method removes all the items from the list.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
[Link]()
print(info)
Output:
{}
pop():
The pop() method removes the key-value pair whose key is passed as a parameter.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
[Link]('eligible')
print(info)
Output:
{'name': 'Karan', 'age': 19}
popitem():
The popitem() method removes the last key-value pair from the dictionary.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True, 'DOB':2003}
[Link]()
print(info)
Output:
{'name': 'Karan', 'age': 19, 'eligible': True}
del:
we can also use the del keyword to remove a dictionary item.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True, 'DOB':2003}
del info['age']
print(info)
Output:
{'name': 'Karan', 'eligible': True, 'DOB': 2003}
If key is not provided, then the del keyword will delete the dictionary entirely.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True, 'DOB':2003}
del info
print(info)
Output:
NameError: name 'info' is not defined
Python - else in Loop
As you have learned before, the else clause is used along with the if statement.
Python allows the else keyword to be used with the for and while loops too. The else block appears after the
body of the loop. The statements in the else block will be executed after all iterations are completed. The
program exits the loop only after the else block is executed.
Syntax
for counter in sequence:
#Statements inside for loop block
else:
#Statements inside else block
Example:
for x in range(5):
print ("iteration no {} in for loop".format(x+1))
else:
print ("else block in loop")
print ("Out of loop")
Output:
iteration no 1 in for loop
iteration no 2 in for loop
iteration no 3 in for loop
iteration no 4 in for loop
iteration no 5 in for loop
else block in loop
Out of loop
Exception Handling
Exception handling is the process of responding to unwanted or unexpected events when a computer program
runs. Exception handling deals with these events to avoid the program or system crashing, and without this
process, exceptions would disrupt the normal operation of a program.
Exceptions in Python
Python has many built-in exceptions that are raised when your program encounters an error (something in the
program goes wrong).
When these exceptions occur, the Python interpreter stops the current process and passes it to the calling
process until it is handled. If not handled, the program will crash.
Python try...except
try….. except blocks are used in python to handle errors and exceptions. The code in try block runs when there
is no error. If the try block catches the error, then the except block is executed.
Syntax:
try:
#statements which could generate
#exception
except:
#Soloution of generated exception
Example:
try:
num = int(input("Enter an integer: "))
except ValueError:
print("Number entered is not an integer.")
Output:
Enter an integer: 6.022
Number entered is not an integer.
Finally Clause
The finally code block is also a part of exception handling. When we handle exception using the try and except
block, we can include a finally block at the end. The finally block is always executed, so it is generally used for
doing the concluding tasks like closing file resources or closing database connection or may be ending the
program execution with a delightful message.
Syntax:
try:
#statements which could generate
#exception
except:
#solution of generated exception
finally:
#block of code which is going to
#execute in any situation
The finally block is executed irrespective of the outcome of try……except…..else blocks
One of the important use cases of finally block is in a function which returns a value.
Example:
try:
num = int(input("Enter an integer: "))
except ValueError:
print("Number entered is not an integer.")
else:
print("Integer Accepted.")
finally:
print("This block is always executed.")
Output 1:
Enter an integer: 19
Integer Accepted.
This block is always executed.
Output 2:
Enter an integer: 3.142
Number entered is not an integer.
This block is always executed.
Output
In the previous tutorial, we learned about different built-in exceptions in Python and why it is important to
handle exceptions. However, sometimes we may need to create our own custom exceptions that serve our
purpose.
class CustomError(Exception):
# code ...
pass
try:
# code ...
except CustomError:
# code...
This is useful because sometimes we might want to do something when a particular exception is raised. For
example, sending an error report to the admin, calling an api, etc.
Exercise 3
Create a program capable of displaying questions to the user like KBC. Use List data type to store the questions
and their correct answers. Display the final amount the person is taking home after playing the game.
Solution
questions = [
[
"Which language was used to create fb?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create wh?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create tel?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create google?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create yoytub?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create github?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create linkedin?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create micros?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create insta?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create snap?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create kb?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create gb?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create rb?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create ab?", "Python", "French", "JavaScript",
"Php", "None", 4
],
[
"Which language was used to create bb?", "Python", "French", "JavaScript",
"Php", "None", 4
],
levels = [1000, 2000, 3000, 5000, 10000, 20000, 40000, 80000, 160000, 320000,640000,1250000,2500000,50000000,10
0000000]
money = 0
for i in range(0, len(questions)):
question = questions[i]
print(f"\n\nQuestion for Rs. {levels[i]}")
print(question[0])
#For options
print(f"a. {question[1]} b. {question[2]} ")
print(f"c. {question[3]} d. {question[4]} ")
print(f"e. {question[5]}")
reply = int(input("Enter your answer (1-5) or 0 to quit:\n" ))
if (reply == 0):
money = levels[i-1]
break
if(reply == question[-1]):
print(f"Correct answer, you have won Rs. {levels[i]}")
if(i == 4):
money = 10000
elif(i == 9):
money = 320000
elif(i == 14):
money = 10000000
else:
print("Wrong answer!")
break
Output
Question for Rs. 1000
Which language was used to create fb?
a. Python b. French
c. JavaScript d. Php
e. None
Enter your answer (1-5) or 0 to quit:
4
Correct answer, you have won Rs. 1000
Question for Rs. 2000
Which language was used to create wh?
a. Python b. French
c. JavaScript d. Php
e. None
Enter your answer (1-5) or 0 to quit:
2
Correct answer, you have won Rs. 2000
Exercise 4
Write a python program to translate a message into secret code language. Use the rules below to trans
late normal English into secret code language
Coding:
if the word contains atleast 3 characters, remove the first letter and append it at the end now append t
hree random characters at the starting and the end else: simply reverse the string
Decoding:
if the word contains less than 3 characters, reverse it else: remove 3 random characters from start and
end. Now remove the last letter and append it to the beginning
Your program should ask whether you want to code or decode
a=2
b = 330
print("A") if a > b else print("B")
You can also have multiple else statements on the same line:
Example
One line if else statement, with 3 conditions:
a = 330
b = 330
print("A") if a > b else print("=") if a == b else print("B")
Another Example
result = value_if_true if condition else value_if_false
if condition:
result = value_if_true
else:
result = value_if_false
Conclusion
The shorthand syntax can be a convenient way to write simple if-else statements, especially when you want to
assign a value to a variable based on a condition.
However, it's not suitable for more complex situations where you need to execute multiple statements or
perform more complex logic. In those cases, it's best to use the full if-else syntax.
# Loop over a list and print the index and value of each element
fruits = ['apple', 'banana', 'mango']
for index, fruit in enumerate(fruits):
print(index, fruit)
0 apple
1 banana
2 mango
As you can see, the enumerate function returns a tuple containing the index and value of each element in the
sequence. You can use the for loop to unpack these tuples and assign them to variables, as shown in the
example above.
# Loop over a list and print the index (starting at 1) and value of each element
fruits = ['apple', 'banana', 'mango']
for index, fruit in enumerate(fruits, start=1):
print(index, fruit)
1 apple
2 banana
3 mango
The enumerate function is often used when you need to loop over a sequence and perform some action with
both the index and value of each element. For example, you might use it to loop over a list of strings and print
the index and value of each string in a formatted way:
1: apple
2: banana
3: mango
In addition to lists, you can use the enumerate function with any other sequence type in Python, such as tuples
and strings. Here's an example with a tuple:
# Loop over a tuple and print the index and value of each element
colors = ('red', 'green', 'blue')
for index, color in enumerate(colors):
print(index, color)
# Loop over a string and print the index and value of each character
s = 'hello'
for index, c in enumerate(s):
print(index, c)
Virtual Environment
A virtual environment is a tool used to isolate specific Python environments on a single machine, allowing you
to work on multiple projects with different dependencies and packages without conflicts. This can be especially
useful when working on projects that have conflicting package versions or packages that are not compatible
with each other.
To create a virtual environment in Python, you can use the venv module that comes with Python. Here's an
example of how to create a virtual environment and activate it:
Once the virtual environment is activated, any packages that you install using pip will be installed in the virtual
environment, rather than in the global Python environment. This allows you to have a separate set of packages
for each project, without affecting the packages installed in the global environment.
To deactivate the virtual environment, you can use the deactivate command:
# Deactivate the virtual environment
deactivate
To create a [Link] file, you can use the pip freeze command, which outputs a list of installed
packages and their versions. For example:
Using a virtual environment and a [Link] file can help you manage the dependencies for your Python
projects and ensure that your projects are portable and can be easily set up on a new machine.
To import a module in Python, you use the import statement followed by the name of the module. For example,
to import the math module, which contains a variety of mathematical functions, you would use the following
statement:
import math
Once a module is imported, you can use any of the functions and variables defined in the module by using the
dot notation. For example, to use the sqrt function from the math module, you would write:
import math
result = [Link](9)
print(result) # Output: 3.0
from keyword
You can also import specific functions or variables from a module using the from keyword. For example, to
import only the sqrt function from the math module, you would write:
result = sqrt(9)
print(result) # Output: 3.0
You can also import multiple functions or variables at once by separating them with a comma:
from math import sqrt, pi
result = sqrt(9)
print(result) # Output: 3.0
importing everything
It's also possible to import all functions and variables from a module using the * wildcard. However, this is
generally not recommended as it can lead to confusion and make it harder to understand where specific
functions and variables are coming from.
result = sqrt(9)
print(result) # Output: 3.0
Python also allows you to rename imported modules using the as keyword. This can be useful if you want to
use a shorter or more descriptive name for a module, or if you want to avoid naming conflicts with other
modules or variables in your code.
result = [Link](9)
print(result) # Output: 3.0
import math
print(dir(math))
This will output a list of all the names defined in the math module, including functions like sqrt and pi, as well
as other variables and constants.
In summary, the import statement in Python allows you to access the functions and variables defined in a
module from within your current script. You can import the entire module, specific functions or variables, or
use the * wildcard to import everything. You can also use the as keyword to rename a module, and the dir
function to view the contents of a module.
if "__name__ == "__main__" in Python
The if __name__ == "__main__" idiom is a common pattern used in Python scripts to determine whether the script is
being run directly or being imported as a module into another script.
In Python, the __name__ variable is a built-in variable that is automatically set to the name of the current
module. When a Python script is run directly, the __name__ variable is set to the string __main__ When the script is
imported as a module into another script, the __name__ variable is set to the name of the module.
def main():
# Code to be run when the script is run directly
print("Running script directly")
if __name__ == "__main__":
main()
In this example, the main function contains the code that should be run when the script is run directly. The if
statement at the bottom checks whether the __name__ variable is equal to __main__. If it is, the main function is
called.
Why is it useful?
This idiom is useful because it allows you to reuse code from a script by importing it as a module into another
script, without running the code in the original script. For example, consider the following script:
def main():
print("Running script directly")
if __name__ == "__main__":
main()
If you run this script directly, it will output "Running script directly". However, if you import it as a module into
another script and call the main function from the imported module, it will not output anything:
import script
[Link]() # Output: "Running script directly"
This can be useful if you have code that you want to reuse in multiple scripts, but you only want it to run when
the script is run directly and not when it's imported as a module.
Is it a necessity?
It's important to note that the if __name__ == "__main__" idiom is not required to run a Python script. You can still
run a script without it by simply calling the functions or running the code you want to execute directly.
However, the if __name__ == "__main__" idiom can be a useful tool for organizing and separating code that should
be run directly from code that should be imported and used as a module.
In summary, the if __name__ == "__main__" idiom is a common pattern used in Python scripts to determine
whether the script is being run directly or being imported as a module into another script. It allows you to reuse
code from a script by importing it as a module into another script, without running the code in the original
script.
os Module in Python
The os module in Python is a built-in library that provides functions for interacting with the operating system. It
allows you to perform a wide variety of tasks, such as reading and writing files, interacting with the file system,
and running system commands.
Here are some common tasks you can perform with the os module:
Reading and writing files The os module provides functions for opening, reading, and writing files. For example,
to open a file for reading, you can use the open function:
import os
To open a file for writing, you can use the os.O_WRONLY flag:
import os
import os
import os
import os
You can also use the [Link] function to run a command and get the output as a file-like object:
import os
# Run the "ls" command and get the output as a file-like object
f = [Link]("ls")
In summary, the os module in Python is a built-in library that provides a wide variety of functions for interacting
with the operating system. It allows you to perform tasks such as reading and writing files, interacting with the
file system, and running system commands.
Exercise 4 Solution
Decoding:
if the word contains less than 3 characters, reverse it else: remove 3 random characters from start and end.
Now remove the last letter and append it to the beginning
else:
nwords = []
for word in words:
if(len(word)>=3):
stnew = word[3:-3]
stnew = stnew[-1] + stnew[:-1]
[Link](stnew)
else:
[Link](word[::-1])
print(" ".join(nwords))
A variable is a named location in memory that stores a value. In Python, we can assign values to variables using
the assignment operator =. For example:
x=5
y = "Hello, World!"
Now, let's talk about local and global variables.
A local variable is a variable that is defined within a function and is only accessible within that function. It is
created when the function is called and is destroyed when the function returns.
On the other hand, a global variable is a variable that is defined outside of a function and is accessible from
within any function in your code.
x = 10 # global variable
def my_function():
y = 5 # local variable
print(y)
my_function()
print(x)
print(y) # this will cause an error because y is a local variable and is not accessible outside of the function
In this example, we have a global variable x and a local variable y. We can access the value of the global
variable x from within the function, but we cannot access the value of the local variable y outside of the
function.
The global keyword is used to declare that a variable is a global variable and should be accessed from the
global scope. Here's an example:
x = 10 # global variable
def my_function():
global x
x = 5 # this will change the value of the global variable x
y = 5 # local variable
my_function()
print(x) # prints 5
print(y) # this will cause an error because y is a local variable and is not accessible outside of the function
In this example, we used the global keyword to declare that we want to modify the global variable x from within
the function. As a result, the value of x is changed to 5.
It's important to note that it's generally considered good practice to avoid modifying global variables from
within functions, as it can lead to unexpected behavior and make your code harder to debug.
I hope this tutorial has helped clarify the differences between local and global variables and how to use the
global keyword in Python. Thank you for watching!
Python provides several ways to manipulate files. Today, we will discuss how to handle files in Python.
Opening a File
Before we can perform any operations on a file, we must first open it. Python provides the open() function to
open a file. It takes two arguments: the name of the file and the mode in which the file should be opened. The
mode can be 'r' for reading, 'w' for writing, or 'a' for appending.
f = open('[Link]', 'r')
By default, the open() function returns a file object that can be used to read from or write to the file, depending
on the mode.
Modes in file
There are various modes in which we can open files.
1. read (r): This mode opens the file for reading only and gives an error if the file does not exist. This is the
default mode if no mode is passed as a parameter.
2. write (w): This mode opens the file for writing only and creates a new file if the file does not exist.
3. append (a): This mode opens the file for appending only and creates a new file if the file does not exist.
4. create (x): This mode creates a file and gives an error if the file already exists.
5. text (t): Apart from these modes we also need to specify how the file must be handled. t mode is used to
handle text files. t refers to the text mode. There is no difference between r and rt or w and wt since text
mode is the default. The default mode is 'r' (open for reading text, synonym of 'rt' ).
6. binary (b): used to handle binary files (images, pdfs, etc).
The read() method reads the entire contents of the file and returns it as a string.
f = open('[Link]', 'r')
contents = [Link]()
print(contents)
Writing to a File
To write to a file, we first need to open it in write mode.
f = open('[Link]', 'w')
f = open('[Link]', 'w')
[Link]('Hello, world!')
Keep in mind that writing to a file will overwrite its contents. If you want to append to a file instead of
overwriting it, you can open it in append mode.
f = open('[Link]', 'a')
[Link]('Hello, world!')
Closing a File
It is important to close a file after you are done with it. This releases the resources used by the file and allows
other programs to access it.
f = open('[Link]', 'r')
# ... do something with the file
[Link]()
readlines() method
The readline() method reads a single line from the file. If we want to read multiple lines, we can use a loop.
f = open('[Link]', 'r')
while True:
line = [Link]()
if not line:
break
print(line)
The readlines() method reads all the lines of the file and returns them as a list of strings.
writelines() method
The writelines() method in Python writes a sequence of strings to a file. The sequence can be any iterable
object, such as a list or a tuple.
f = open('[Link]', 'w')
lines = ['line 1\n', 'line 2\n', 'line 3\n']
[Link](lines)
[Link]()
This will write the strings in the lines list to the file [Link]. The \n characters are used to add newline
characters to the end of each string.
Keep in mind that the writelines() method does not add newline characters between the strings in the
sequence. If you want to add newlines between the strings, you can use a loop to write each string separately:
f = open('[Link]', 'w')
lines = ['line 1', 'line 2', 'line 3']
for line in lines:
[Link](line + '\n')
[Link]()
It is also a good practice to close the file after you are done with it.
seek() function
The seek() function allows you to move the current position within a file to a specific point. The position is
specified in bytes, and you can move either forward or backward from the current position. For example:
tell() function
The tell() function returns the current position within the file, in bytes. This can be useful for keeping track of
your location within the file or for seeking to a specific position relative to the current position. For example:
truncate() function
When you open a file in Python using the open function, you can specify the mode in which you want to open
the file. If you specify the mode as 'w' or 'a', the file is opened in write mode and you can write to the file.
However, if you want to truncate the file to a specific size, you can use the truncate function.
The above lambda function has the same functionality as the double function defined earlier. However, the
lambda function is anonymous, as it does not have a name.
Lambda functions can have multiple arguments, just like regular functions. Here is an example of a lambda
function with multiple arguments:
Lambda functions can also include multiple statements, but they are limited to a single expression. For
example:
In the above example, the lambda function includes a print statement, but it is still limited to a single
expression.
Lambda functions are often used in conjunction with higher-order functions, such as map, filter, and reduce
which we will look into later.
map
The map function applies a function to each element in a sequence and returns a new sequence containing the
transformed elements. The map function has the following syntax:
map(function, iterable)
The function argument is a function that is applied to each element in the iterable argument. The iterable
argument can be a list, tuple, or any other iterable object.
# List of numbers
numbers = [1, 2, 3, 4, 5]
In the above example, the lambda function lambda x: x * 2 is used to double each element in the numbers list.
The map function applies the lambda function to each element in the list and returns a new list containing the
doubled numbers.
filter
The filter function filters a sequence of elements based on a given predicate (a function that returns a boolean
value) and returns a new sequence containing only the elements that meet the predicate. The filter function
has the following syntax:
filter(predicate, iterable)
The predicate argument is a function that returns a boolean value and is applied to each element in the iterable
argument. The iterable argument can be a list, tuple, or any other iterable object.
# List of numbers
numbers = [1, 2, 3, 4, 5]
In the above example, the lambda function lambda x: x % 2 == 0 is used to filter the numbers list and return
only the even numbers. The filter function applies the lambda function to each element in the list and returns a
new list containing only the even numbers.
reduce
The reduce function is a higher-order function that applies a function to a sequence and returns a single value.
It is a part of the functools module in Python and has the following syntax:
reduce(function, iterable)
The function argument is a function that takes in two arguments and returns a single value. The iterable
argument is a sequence of elements, such as a list or tuple.
The reduce function applies the function to the first two elements in the iterable and then applies the function
to the result and the next element, and so on. The reduce function returns the final result.
# List of numbers
numbers = [1, 2, 3, 4, 5]
In the above example, the reduce function applies the lambda function lambda x, y: x + y to the elements in the
numbers list. The lambda function adds the two arguments x and y and returns the result. The reduce function
applies the lambda function to the first two elements in the list (1 and 2), then applies the function to the result
(3) and the next element (3), and so on. The final result is the sum of all the elements in the list, which is 15.
It is important to note that the reduce function requires the functools module to be imported in order to use it.
The is operator compares the identity of two objects, while the == operator compares the values of the objects.
This means that is will only return True if the objects being compared are the exact same object in memory,
while == will return True if the objects have the same value.
For example:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True
print(a is b) # False
In this case, a and b are two separate lists that have the same values, so == returns True. However, a and b are
not the same object in memory, so is returns False.
One important thing to note is that, in Python, strings and integers are immutable, which means that once they
are created, their value cannot be changed. This means that, for strings and integers, is and == will always
return the same result:
a = "hello"
b = "hello"
print(a == b) # True
print(a is b) # True
a=5
b=5
print(a == b) # True
print(a is b) # True
In these cases, a and b are both pointing to the same object in memory, so is and == both return True.
For mutable objects such as lists and dictionaries, is and == can behave differently. In general, you should use
== when you want to compare the values of two objects, and use is when you want to check if two objects are
the same object in memory.
Exercise 5
Snake Water Gun
Snake, Water and Gun is a variation of the children's game "rock-paper-scissors" where players use hand
gestures to represent a snake, water, or a gun. The gun beats the snake, the water beats the gun, and the
snake beats the water. Write a python program to create a Snake Water Gun game in Python using if-else
statements. Do not create any fancy GUI. Use proper functions to check for win.
An object is an instance of a class, and it contains its own data and methods. For example, you could create a
class called "Person" that has properties such as name and age, and methods such as speak() and walk(). Each
instance of the Person class would be a unique object with its own name and age, but they would all have the
same methods to speak and walk.
One of the key features of OOP in Python is encapsulation, which means that the internal state of an object is
hidden and can only be accessed or modified through the object's methods. This helps to protect the object's
data and prevent it from being modified in unexpected ways.
Another key feature of OOP in Python is inheritance, which allows new classes to be created that inherit the
properties and methods of an existing class. This allows for code reuse and makes it easy to create new classes
that have similar functionality to existing classes.
Polymorphism is also supported in Python, which means that objects of different classes can be treated as if
they were objects of a common class. This allows for greater flexibility in code and makes it easier to write
code that can work with multiple types of objects.
In summary, OOP in Python allows developers to model real-world concepts and entities using classes and
objects, encapsulate data, reuse code through inheritance, and write more flexible code through
polymorphism.
Python Class and Objects
A class is a blueprint or a template for creating objects, providing initial values for state (member variables or
attributes), and implementations of behavior (member functions or methods). The user-defined objects are
created using the class keyword.
Creating a Class:
Let us now create a class using the class keyword.
class Details:
name = "Rohan"
age = 20
Creating an Object:
Object is the instance of the class used to access the properties of the class Now lets create an object of the
class.
Example:
obj1 = Details()
Example:
class Details:
name = "Rohan"
age = 20
obj1 = Details()
print([Link])
print([Link])
Output:
Rohan
20
self parameter
The self parameter is a reference to the current instance of the class, and is used to access variables that
belongs to the class.
Example:
class Details:
name = "Rohan"
age = 20
def desc(self):
print("My name is", [Link], "and I'm", [Link], "years old.")
obj1 = Details()
[Link]()
Output:
My name is Rohan and I'm 20 years old.
Constructors
A constructor is a special method in a class used to create and initialize an object of a class. There are different
types of constructors. Constructor is invoked automatically when an object of a class is created.
A constructor is a unique function that gets called automatically when an object is created of a class. The main
purpose of a constructor is to initialize or assign values to the data members of that class. It cannot return any
value other than None.
init is one of the reserved functions in Python. In Object Oriented Programming, it is known as a constructor.
These arguments can be used inside the class to assign the values to the data members.
Example:
class Details:
def __init__(self, animal, group):
[Link] = animal
[Link] = group
Output:
Crab belongs to the Crustaceans group.
Default Constructor in Python
When the constructor doesn't accept any arguments from the object and has only one argument, self, in the
constructor, it is known as a Default constructor.
Example:
class Details:
def __init__(self):
print("animal Crab belongs to Crustaceans group")
obj1=Details()
Output:
animal Crab belongs to Crustaceans group
Python Decorators
Python decorators are a powerful and versatile tool that allow you to modify the behavior of functions and
methods. They are a way to extend the functionality of a function or method without modifying its source code.
A decorator is a function that takes another function as an argument and returns a new function that modifies
the behavior of the original function. The new function is often referred to as a "decorated" function. The basic
syntax for using a decorator is the following:
@decorator_function
def my_function():
pass
def my_function():
pass
my_function = decorator_function(my_function)
Decorators are often used to add functionality to functions and methods, such as logging, memoization, and
access control.
import logging
def log_function_call(func):
def decorated(*args, **kwargs):
[Link](f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
result = func(*args, **kwargs)
[Link](f"{func.__name__} returned {result}")
return result
return decorated
@log_function_call
def my_function(a, b):
return a + b
In this example, the log_function_call decorator takes a function as an argument and returns a new function
that logs the function call before and after the original function is called.
Conclusion
Decorators are a powerful and flexible feature in Python that can be used to add functionality to functions and
methods without modifying their source code. They are a great tool for separating concerns, reducing code
duplication, and making your code more readable and maintainable.
In conclusion, python decorators are a way to extend the functionality of functions and methods, by modifying
its behavior without modifying the source code. They are used for a variety of purposes, such as logging,
memoization, access control, and more. They are a powerful tool that can be used to make your code more
readable, maintainable, and extendable.
Getters
Getters in Python are methods that are used to access the values of an object's properties. They are used to
return the value of a specific property, and are typically defined using the @property decorator. Here is an
example of a simple class with a getter method:
class MyClass:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
In this example, the MyClass class has a single property, _value, which is initialized in the init method. The
value method is defined as a getter using the @property decorator, and is used to return the value of the _value
property.
To use the getter, we can create an instance of the MyClass class, and then access the value property as if it
were an attribute:
Setters
It is important to note that the getters do not take any parameters and we cannot set the value through getter
[Link] that we need setter method which can be added by decorating method with
@property_name.setter
@property
def value(self):
return self._value
@[Link]
def value(self, new_value):
self._value = new_value
In conclusion, getters are a convenient way to access the values of an object's properties, while keeping the
internal representation of the property hidden. This can be useful for encapsulation and data validation.
Inheritance in python
When a class derives from another class. The child class will inherit all the public and protected properties and
methods from the parent class. In addition, it can have its own properties and methods,this is called as
inheritance.
Derived class inherits features from the base class where new features can be added to it. This results in re-
usability of code.
Types of inheritance:
1. Single inheritance
2. Multiple inheritance
3. Multilevel inheritance
4. Hierarchical Inheritance
5. Hybrid Inheritance
We will see the explaination and example of each type of inheritance in the later tutorials
Single Inheritance:
Single inheritance enables a derived class to inherit properties from a single parent class, thus enabling code
reusability and the addition of new features to existing code.
Example:
class Parent:
def func1(self):
print("This function is in parent class.")
class Child(Parent):
def func2(self):
print("This function is in child class.")
object = Child()
object.func1()
object.func2()
Output:
This function is in parent class.
This function is in child class.
Multiple Inheritance:
When a class can be derived from more than one base class this type of inheritance is called multiple
inheritances. In multiple inheritances, all the features of the base classes are inherited into the derived class.
Example:
class Mother:
mothername = ""
def mother(self):
print([Link])
class Father:
fathername = ""
def father(self):
print([Link])
Output:
Father name is : Mommy
Mother name is : Daddy
Multilevel Inheritance :
In multilevel inheritance, features of the base class and the derived class are further inherited into the new
derived class. This is similar to a relationship representing a child and a grandfather.
Example:
class Grandfather:
class Father(Grandfather):
def __init__(self, fathername, grandfathername):
[Link] = fathername
Grandfather.__init__(self, grandfathername)
class Son(Father):
def __init__(self, sonname, fathername, grandfathername):
[Link] = sonname
Father.__init__(self, fathername, grandfathername)
def print_name(self):
print('Grandfather name :', [Link])
print("Father name :", [Link])
print("Son name :", [Link])
s1 = Son('Prince', 'Rampal', 'Lal mani')
print([Link])
s1.print_name()
Output:
George
Grandfather name : George
Father name : Philip
Son name : Charles
Hierarchical Inheritance:
When more than one derived class are created from a single base this type of inheritance is called hierarchical
inheritance. In this program, we have a parent (base) class and two child (derived) classes.
Example:
class Parent:
def func1(self):
print("This function is in parent class.")
class Child1(Parent):
def func2(self):
print("This function is in child 1.")
class Child2(Parent):
def func3(self):
print("This function is in child 2.")
object1 = Child1()
object2 = Child2()
object1.func1()
object1.func2()
object2.func1()
object2.func3()
Output:
This function is in parent class.
This function is in child 1.
This function is in parent class.
This function is in child 2.
Hybrid Inheritance:
Inheritance consisting of multiple types of inheritance is called hybrid inheritance.
Example
class School:
def func1(self):
print("This function is in school.")
class Student1(School):
def func2(self):
print("This function is in student 1. ")
class Student2(School):
def func3(self):
print("This function is in student 2.")
object = Student3()
object.func1()
object.func2()
Output:
This function is in school.
This function is in student 1.
Access Specifiers/Modifiers
Access specifiers or access modifiers in python programming are used to limit the access of class variables and
class methods outside of class while implementing the concepts of inheritance.
Example:
class Student:
# constructor is defined
def __init__(self, age, name):
[Link] = age # public variable
[Link] = name # public variable
obj = Student(21,"Harry")
print([Link])
print([Link])
Output:
21
Harry
In Python, there is no strict concept of "private" access modifiers like in some other programming languages.
However, a convention has been established to indicate that a variable or method should be considered private
by prefixing its name with a double underscore (__). This is known as a "weak internal use indicator" and it is a
convention only, not a strict rule. Code outside the class can still access these "private" variables and methods,
but it is generally understood that they should not be accessed or modified.
Example:
class Student:
def __init__(self, age, name):
self.__age = age # An indication of private variable
class Subject(Student):
pass
obj = Student(21,"Harry")
obj1 = Subject
Output:
AttributeError: 'student' object has no attribute '__age'
AttributeError: 'student' object has no method '__funName()'
AttributeError: 'subject' object has no attribute '__age'
AttributeError: 'student' object has no method '__funName()'
Private members of a class cannot be accessed or inherited outside of class. If we try to access or to inherit the
properties of private members to child class (derived class). Then it will show the error.
Name mangling
Name mangling in Python is a technique used to protect class-private and superclass-private attributes from
being accidentally overwritten by subclasses. Names of class-private and superclass-private attributes are
transformed by the addition of a single leading underscore and a double leading underscore respectively.
class MyClass:
def __init__(self):
self._nonmangled_attribute = "I am a nonmangled attribute"
self.__mangled_attribute = "I am a mangled attribute"
my_object = MyClass()
In the example above, the attribute _nonmangled_attribute is marked as nonmangled by convention, but can
still be accessed from outside the class. The attribute __mangled_attribute is private and its name is
"mangled" to _MyClass__mangled_attribute, so it can't be accessed directly from outside the class, but you
can access it by calling _MyClass__mangled_attribute
It's important to note that the single underscore is just a naming convention, and does not actually provide any
protection or restrict access to the member. The syntax we follow to make any variable protected is to write
variable name followed by a single underscore (_) ie. _varName.
Example:
class Student:
def __init__(self):
self._name = "Harry"
obj = Student()
obj1 = Subject()
Output:
Harry
CodeWithHarry
Harry
CodeWithHarry
Excercies 5
Snake Water Gun
Snake, Water and Gun is a variation of the children's game "rock-paper-scissors" where players use hand
gestures to represent a snake, water, or a gun. The gun beats the snake, the water beats the gun, and the
snake beats the water. Write a python program to create a Snake Water Gun game in Python using if-else
statements. Do not create any fancy GUI. Use proper functions to check for win.
Excercies 6
Write a Library class with no_of_books and books as two instance variables. Write a program to create a library
from this Library class and show how you can print all books, add a book and get the number of books using dif
ferent methods. Show that your program doesnt persist the books after the program is stopped!
Static methods
Static methods in Python are methods that belong to a class rather than an instance of the class. They are
defined using the @staticmethod decorator and do not have access to the instance of the class (i.e. self). They
are called on the class itself, not on an instance of the class. Static methods are often used to create utility
functions that don't need access to instance data.
class Math:
@staticmethod
def add(a, b):
return a + b
result = [Link](1, 2)
print(result) # Output: 3
In this example, the add method is a static method of the Math class. It takes two parameters a and b and
returns their sum. The method can be called on the class itself, without the need to create an instance of the
class.
Class Variables
Class variables are defined at the class level and are shared among all instances of the class. They are defined
outside of any method and are usually used to store information that is common to all instances of the class.
For example, a class variable can be used to store the number of instances of a class that have been created.
class MyClass:
class_variable = 0
def __init__(self):
MyClass.class_variable += 1
def print_class_variable(self):
print(MyClass.class_variable)
obj1 = MyClass()
obj2 = MyClass()
obj1.print_class_variable() # Output: 2
obj2.print_class_variable() # Output: 2
In the example above, the class_variable is shared among all instances of the class MyClass. When we create
new instances of MyClass, the value of class_variable is incremented. When we call the print_class_variable
method on obj1 and obj2, we get the same value of class_variable.
Instance Variables
Instance variables are defined at the instance level and are unique to each instance of the class. They are
defined inside the init method and are usually used to store information that is specific to each instance of the
class. For example, an instance variable can be used to store the name of an employee in a class that
represents an employee.
class MyClass:
def __init__(self, name):
[Link] = name
def print_name(self):
print([Link])
obj1 = MyClass("John")
obj2 = MyClass("Jane")
In the example above, each instance of the class MyClass has its own value for the name variable. When we
call the print_name method on obj1 and obj2, we get different values for name.
Summary
In summary, class variables are shared among all instances of a class and are used to store information that is
common to all instances. Instance variables are unique to each instance of a class and are used to store
information that is specific to each instance. Understanding the difference between class variables and
instance variables is crucial for writing efficient and maintainable code in Python.
It's also worth noting that, in python, class variables are defined outside of any methods and don't need to be
explicitly declared as class variable. They are defined in the class level and can be accessed via
classname.varibale_name or [Link].variable_name. But instance variables are defined inside the methods
and need to be explicitly declared as instance variable by using self.variable_name.
Excercies 6 Solution
class Library:
def __init__(self):
[Link] = 0
[Link] = []
def showInfo(self):
print(f"The library has {[Link]} books. The books are")
for book in [Link]:
print(book)
l1 = Library()
[Link]("Harry Potter1")
[Link]("Harry Potter2")
[Link]("Harry Potter3")
[Link]()
Excercies 7
Write a program to clear the clutter inside a folder on your computer. You should use os module to rename all
the png images from [Link] all the way till [Link] where n is the number of png files in that folder. Do the same
for other file formats. For example:
In this example, the "factory_method" is a class method that takes two arguments, "argument1" and
"argument2." It creates a new instance of the class "ExampleClass" using the "cls" keyword, and returns the
new instance to the caller.
It's important to note that class methods cannot modify the class in any way. If you need to modify the class,
you should use a class level variable instead.
Conclusion
Python class methods are a powerful tool for defining functions that operate on the class as a whole, rather
than on a specific instance of the class. They are useful for creating factory methods, alternative constructors,
and other types of methods that operate at the class level. With the knowledge of how to define and use class
methods, you can start writing more complex and organized code in Python.
However, there are times when you may want to create an object in a different way, or with different initial
values, than what is provided by the default constructor. This is where class methods can be used as
alternative constructors.
A class method belongs to the class rather than to an instance of the class. One common use case for class
methods as alternative constructors is when you want to create an object from data that is stored in a different
format, such as a string or a dictionary. For example, consider a class named "Person" that has two attributes:
"name" and "age". The default constructor for the class might look like this:
class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age
But what if you want to create a Person object from a string that contains the person's name and age,
separated by a comma? You can define a class method named "from_string" to do this:
class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age
@classmethod
def from_string(cls, string):
name, age = [Link](',')
return cls(name, int(age))
Now you can create a Person object from a string like this:
Another common use case for class methods as alternative constructors is when you want to create an object
with a different set of default values than what is provided by the default constructor. For example, consider a
class named "Rectangle" that has two attributes: "width" and "height". The default constructor for the class
might look like this:
class Rectangle:
def __init__(self, width, height):
[Link] = width
[Link] = height
But what if you want to create a Rectangle object with a default width of 10 and a default height of 5? You can
define a class method named "square" to do this:
class Rectangle:
def __init__(self, width, height):
[Link] = width
[Link] = height
@classmethod
def square(cls, size):
return cls(size, size)
Now you can create a square rectangle like this:
rectangle = [Link](10)
>>> x = [1, 2, 3]
>>> dir(x)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattri
bute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt_
_', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__
', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'rev
erse', 'sort']
Output
{'name': 'John', 'age': 30}
>>> help(str)
Help on class str in module builtins:
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object. If encoding or
| errors is specified, then the object must expose a data buffer
| that will be decoded using the given encoding and error handler.
| Otherwise, returns the result of object.__str__() (if defined)
| or repr(object).
| encoding defaults to [Link]().
| errors defaults to 'strict'.
In conclusion, dir(), dict, and help() are useful built-in functions in Python that can be used to get information
about objects. They are valuable tools for introspection and discovery.
When a class inherits from a parent class, it can override or extend the methods defined in the parent class.
However, sometimes you might want to use the parent class method in the child class. This is where the
super() keyword comes in handy.
Here's an example of how to use the super() keyword in a simple inheritance scenario:
class ParentClass:
def parent_method(self):
print("This is the parent method.")
class ChildClass(ParentClass):
def child_method(self):
print("This is the child method.")
super().parent_method()
child_object = ChildClass()
child_object.child_method()
Output:
This is the child method.
This is the parent method.
In this example, we have a ParentClass with a parent_method and a ChildClass that inherits from ParentClass
and overrides the child_method. When the child_method is called, it first prints "This is the child method." and
then calls the parent_method using the super() keyword.
The super() keyword is also useful when a class inherits from multiple parent classes. In this case, you can
specify the parent class from which you want to call the method.
Here's an example:
class ParentClass1:
def parent_method(self):
print("This is the parent method of ParentClass1.")
class ParentClass2:
def parent_method(self):
print("This is the parent method of ParentClass2.")
child_object = ChildClass()
child_object.child_method()
Output:
This is the child method.
This is the parent method of ParentClass1.
In this example, the ChildClass inherits from both ParentClass1 and ParentClass2. The child_method calls the
parent_method of the first parent class using the super() keyword.
In conclusion, the super() keyword is a useful tool in Python when you want to call a parent class method in a
child class. It can be used in inheritance scenarios with a single parent class or multiple parent classes.
Magic/Dunder Methods in Python
These are special methods that you can define in your classes, and when invoked, they give you a powerful way
to manipulate objects and their behaviour.
Magic methods, also known as “dunders” from the double underscores surrounding their names, are powerful
tools that allow you to customize the behaviour of your classes. They are used to implement special methods
such as the addition, subtraction and comparison operators, as well as some more advanced techniques like
descriptors and properties.
Let’s take a look at some of the most commonly used magic methods in Python.
__init__ method
The init method is a special method that is automatically invoked when you create a new instance of a class.
This method is responsible for setting up the object’s initial state, and it is where you would typically define any
instance variables that you need. Also called "constructor", we have discussed this method already
The str and repr methods are both used to convert an object to a string representation. The str method is used
when you want to print out an object, while the repr method is used when you want to get a string
representation of an object that can be used to recreate the object.
__len__ method
The len method is used to get the length of an object. This is useful when you want to be able to find the size of
a data structure, such as a list or dictionary.
__call__ method
The call method is used to make an object callable, meaning that you can pass it as a parameter to a function
and it will be executed when the function is called. This is an incredibly powerful tool that allows you to create
objects that behave like functions.
These are just a few of the many magic methods available in Python. They are incredibly powerful tools that
allow you to customize the behaviour of your objects, and can make your code much cleaner and easier to
understand. So if you’re looking for a way to take your Python code to the next level, take some time to learn
about these magic methods.
In Python, method overriding is a way to customize the behavior of a class based on its specific needs. For
example, consider the following base class:
class Shape:
def area(self):
pass
In this base class, the area method is defined, but does not have any implementation. If you want to create a
derived class that represents a circle, you can override the area method and provide an implementation that
calculates the area of a circle:
class Circle(Shape):
def __init__(self, radius):
[Link] = radius
def area(self):
return 3.14 * [Link] * [Link]
In this example, the Circle class inherits from the Shape class, and overrides the area method. The new
implementation of the area method calculates the area of a circle, based on its radius.
It's important to note that when you override a method, the new implementation must have the same method
signature as the original method. This means that the number and type of arguments, as well as the return
type, must be the same.
Another way to customize the behavior of a class is to call the base class method from the derived class
method. To do this, you can use the super function. The super function allows you to call the base class method
from the derived class method, and can be useful when you want to extend the behavior of the base class
method, rather than replace it.
class Shape:
def area(self):
print("Calculating area...")
In this base class, the area method prints a message indicating that the area is being calculated. If you want to
create a derived class that represents a circle, and you also want to print a message indicating the type of
shape, you can use the super function to call the base class method, and add your own message:
class Circle(Shape):
def __init__(self, radius):
[Link] = radius
def area(self):
print("Calculating area of a circle...")
super().area()
return 3.14 * [Link] * [Link]
In this example, the Circle class overrides the area method, and calls the base class method using the super
function. This allows you to extend the behavior of the base class method, while still maintaining its original
behavior.
In conclusion, method overriding is a powerful feature in Python that allows you to customize the behavior of a
class based on its specific needs. By using method overriding, you can create more robust and reliable code,
and ensure that your classes behave in the way that you need them to. Additionally, by using the super
function, you can extend the behavior of a base class method, rather than replace it, giving you even greater
flexibility and control over the behavior of your classes
Exercise 7 – Solution
Write a program to clear the clutter inside a folder on your computer. You should use os module to rename all
the png images from [Link] all the way till [Link] where n is the number of png files in that folder. Do the same
for other file formats. For example:
import os
files = [Link]("clutteredFolder")
i=1
for file in files:
if [Link](".png"):
print(file)
[Link](f"clutteredFolder/{file}", f"clutteredFolder/{i}.png")
i=i+1
Exercise 8
Write a program to manipulate pdf files using pyPDF. Your programs should be able to merge multiple pdf files
into a single pdf. You are welcome to add more functionalities
pypdf is a free and open-source pure-python PDF library capable of splitting, merging, cropping, and
transforming the pages of PDF files. It can also add custom data, viewing options, and passwords to PDF files.
pypdf can retrieve text and metadata from PDFs as well.
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3.x, p3.y) # prints 4, 6
How to overload an operator in Python?
You can overload an operator in Python by defining special methods in your class. These methods are identified
by their names, which start and end with double underscores (__). Here are some of the most commonly
overloaded operators and their corresponding special methods:
+ : __add__
- : __sub__
* : __mul__
/ : __truediv__
< : __lt__
> : __gt__
== : __eq__
For example, if you want to overload the + operator to add two instances of a custom class, you would define
the add method:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
It's important to note that operator overloading is not limited to the built-in operators, you can overload any
user-defined operator as well.
Conclusion
Operator overloading is a powerful feature in Python that allows you to create more readable and intuitive
code. By redefining the behavior of mathematical and comparison operators for custom data types, you can
write code that is both concise and expressive. However, it's important to use operator overloading wisely, as
overloading the wrong operator or using it inappropriately can lead to confusing or unexpected behavior.
class Vector:
def __init__(self, i, j, k):
self.i = i
self.j = j
self.k = k
def __str__(self):
return f"{self.i}i + {self.j}j + {self.k}k"
v2 = Vector(1, 2, 9)
print(v2)
print(v1 + v2)
print(type(v1 + v2))
Single Inheritance in Python
Single inheritance is a type of inheritance where a class inherits properties and behaviors from a single parent
class. This is the simplest and most common form of inheritance.
Syntax
The syntax for single inheritance in Python is straightforward and easy to understand. To create a new class
that inherits from a parent class, simply specify the parent class in the class definition, inside the parentheses,
like this:
class ChildClass(ParentClass):
# class body
Example
Let's consider a simple example of single inheritance in Python. Consider a class named "Animal" that contains
the attributes and behaviors that are common to all animals.
class Animal:
def __init__(self, name, species):
[Link] = name
[Link] = species
def make_sound(self):
print("Sound made by the animal")
If we want to create a new class for a specific type of animal, such as a dog, we can create a new class named
"Dog" that inherits from the Animal class.
class Dog(Animal):
def __init__(self, name, breed):
Animal.__init__(self, name, species="Dog")
[Link] = breed
def make_sound(self):
print("Bark!")
The Dog class inherits all the attributes and behaviors of the Animal class, including the __init__ method and
the make_sound method. Additionally, the Dog class has its own __init__ method that adds a new attribute for the
breed of the dog, and it also overrides the make_sound method to specify the sound that a dog makes.
Single inheritance is a powerful tool in Python that allows you to create new classes based on existing classes.
It allows you to reuse code, extend it to fit your needs, and make it easier to manage complex systems.
Understanding single inheritance is an important step in becoming proficient in object-oriented programming in
Python.
class Animal:
def __init__(self, name, species):
[Link] = name
[Link] = species
def make_sound(self):
print("Sound made by the animal")
class Dog(Animal):
def __init__(self, name, breed):
Animal.__init__(self, name, species="Dog")
[Link] = breed
def make_sound(self):
print("Bark!")
d = Dog("Dog", "Doggerman")
d.make_sound()
a = Animal("Dog", "Dog")
a.make_sound()
# Quick Quiz: Implement a Cat class by using the animal class. Add some methods specific to cat
Syntax
In Python, multiple inheritance is implemented by specifying multiple parent classes in the class definition,
separated by commas.
In this example, the ChildClass inherits attributes and methods from all three parent
classes: ParentClass1, ParentClass2, and ParentClass3.
It's important to note that, in case of multiple inheritance, Python follows a method resolution order (MRO) to
resolve conflicts between methods or attributes from different parent classes. The MRO determines the order
in which parent classes are searched for attributes and methods.
Example
class Animal:
def __init__(self, name, species):
[Link] = name
[Link] = species
def make_sound(self):
print("Sound made by the animal")
class Mammal:
def __init__(self, name, fur_color):
[Link] = name
self.fur_color = fur_color
def make_sound(self):
print("Bark!")
In this example, the Dog class inherits from both the Animal and Mammal classes, so it can use attributes and
methods from both parent classes.
class Employee:
def __init__(self, name):
[Link] = name
def show(self):
print(f"The name is {[Link]}")
class Dancer:
def __init__(self, dance):
[Link] = dance
def show(self):
print(f"The dance is {[Link]}")
o = DancerEmployee("Kathak", "Shivani")
print([Link])
print([Link])
[Link]()
print([Link]())
In Python, multilevel inheritance is achieved by using the class hierarchy. The syntax for multilevel inheritance
is quite simple and follows the same syntax as single inheritance.
Syntax
class BaseClass:
# Base class code
class DerivedClass1(BaseClass):
# Derived class 1 code
class DerivedClass2(DerivedClass1):
# Derived class 2 code
In the above example, we have three classes: BaseClass, DerivedClass1, and DerivedClass2.
The DerivedClass1 class inherits from the BaseClass, and the DerivedClass2 class inherits from
the DerivedClass1 class. This creates a hierarchy where DerivedClass2 has access to all the attributes and
methods of both DerivedClass1 and BaseClass.
Example
Let's take a look at an example to understand how multilevel inheritance works in Python. Consider the
following classes:
class Animal:
def __init__(self, name, species):
[Link] = name
[Link] = species
def show_details(self):
print(f"Name: {[Link]}")
print(f"Species: {[Link]}")
class Dog(Animal):
def __init__(self, name, breed):
Animal.__init__(self, name, species="Dog")
[Link] = breed
def show_details(self):
Animal.show_details(self)
print(f"Breed: {[Link]}")
class GoldenRetriever(Dog):
def __init__(self, name, color):
Dog.__init__(self, name, breed="Golden Retriever")
[Link] = color
def show_details(self):
Dog.show_details(self)
print(f"Color: {[Link]}")
In this example, we have three classes: Animal, Dog, and GoldenRetriever. The Dog class inherits from
the Animal class, and the GoldenRetriever class inherits from the Dog class.
Now, when we create an object of the GoldenRetriever class, it has access to all the attributes and methods of
the Animal class and the Dog class. We can also see that the GoldenRetriever class has its own attributes and
methods that are specific to the class.
Output:
Name: Max
Species: Dog
Breed: Golden Retriever
Color: Golden
As we can see from the output, the GoldenRetriever object has access to all the attributes and methods of
the Animal and Dog classes, and, it has also added its own unique attributes and methods. This is a powerful
feature of multilevel inheritance, as it allows you to create more complex and intricate classes by building upon
existing ones.
Another important aspect of multilevel inheritance is that it allows you to reuse code and avoid repeating the
same logic multiple times. This can lead to better maintainability and readability of your code, as you can
abstract away complex logic into base classes and build upon them.
In conclusion, multilevel inheritance is a powerful feature in object-oriented programming that allows you to
create complex and intricate classes by building upon existing ones. It provides the benefits of code reuse,
maintainability, and readability, while also requiring careful consideration to avoid potential problems.
class Animal:
def __init__(self, name, species):
[Link] = name
[Link] = species
def show_details(self):
print(f"Name: {[Link]}")
print(f"Species: {[Link]}")
class Dog(Animal):
def __init__(self, name, breed):
Animal.__init__(self, name, species="Dog")
[Link] = breed
def show_details(self):
Animal.show_details(self)
print(f"Breed: {[Link]}")
class GoldenRetriever(Dog):
def __init__(self, name, color):
Dog.__init__(self, name, breed="Golden Retriever")
[Link] = color
def show_details(self):
Dog.show_details(self)
print(f"Color: {[Link]}")
o = Dog("tommy", "Black")
o.show_details()
print([Link]())
In Python, hybrid inheritance can be implemented by creating a class hierarchy, in which a base class is
inherited by multiple derived classes, and one of the derived classes is further inherited by a sub-derived class.
Syntax
The syntax for implementing Hybrid Inheritance in Python is the same as for implementing Single Inheritance,
Multiple Inheritance, or Hierarchical Inheritance.
class BaseClass1:
# attributes and methods
class BaseClass2:
# attributes and methods
Example
Consider the example of a Student class that inherits from the Person class, which in turn inherits from
the Human class. The Student class also has a Program class that it is associated with.
class Human:
def __init__(self, name, age):
[Link] = name
[Link] = age
def show_details(self):
print("Name:", [Link])
print("Age:", [Link])
class Person(Human):
def __init__(self, name, age, address):
Human.__init__(self, name, age)
[Link] = address
def show_details(self):
Human.show_details(self)
print("Address:", [Link])
class Program:
def __init__(self, program_name, duration):
self.program_name = program_name
[Link] = duration
def show_details(self):
print("Program Name:", self.program_name)
print("Duration:", [Link])
class Student(Person):
def __init__(self, name, age, address, program):
Person.__init__(self, name, age, address)
[Link] = program
def show_details(self):
Person.show_details(self)
[Link].show_details()
In this example, the Student class inherits from the Person class, which in turn inherits from the Human class.
The Student class also has an association with the Program class. This is an example of Hybrid Inheritance in
action, as it uses both Single Inheritance and Association to achieve the desired inheritance structure.
As we can see from the output, the Student object has access to all the attributes and methods of
the Person and Human classes, as well as the Program class through association.
In this way, hybrid inheritance allows for a flexible and powerful way to inherit attributes and behaviors from
multiple classes in a hierarchy or chain.
Hierarchical Inheritance
Hierarchical Inheritance is a type of inheritance in Object-Oriented Programming where multiple subclasses
inherit from a single base class. In other words, a single base class acts as a parent class for multiple
subclasses. This is a way of establishing relationships between classes in a hierarchical manner.
class Animal:
def __init__(self, name):
[Link] = name
def show_details(self):
print("Name:", [Link])
class Dog(Animal):
def __init__(self, name, breed):
Animal.__init__(self, name)
[Link] = breed
def show_details(self):
Animal.show_details(self)
print("Species: Dog")
print("Breed:", [Link])
class Cat(Animal):
def __init__(self, name, color):
Animal.__init__(self, name)
[Link] = color
def show_details(self):
Animal.show_details(self)
print("Species: Cat")
print("Color:", [Link])
In the above code, the Animal class acts as the base class for two subclasses, Dog and Cat. The Dog class and
the Cat class inherit the attributes and methods of the Animal class. However, they can also add their own
unique attributes and methods.
Here's an example of creating objects of the Dog and Cat classes and accessing their attributes and methods:
As we can see from the outputs, the Dog and Cat classes have inherited the attributes and methods of
the Animal class, and have also added their own unique attributes and methods.
Exercise 8 Solution
Write a program to manipulate pdf files using pyPDF. Your programs should be able to merge multiple pdf files
into a single pdf. You are welcome to add more functionalities
pypdf is a free and open-source pure-python PDF library capable of splitting, merging, cropping, and
transforming the pages of PDF files. It can also add custom data, viewing options, and passwords to PDF files.
pypdf can retrieve text and metadata from PDFs as well.
merger = PdfWriter()
files = [file for file in [Link]() if [Link](".pdf")]
[Link]("[Link]")
[Link]()
Exercise 9
Write a program to pronounce list of names using win32 API. If you are given a list l as follows:
[Link]()
The [Link]() function returns the current time as a floating-point number, representing the number of
seconds since the epoch (the point in time when the time module was initialized). The returned value is based
on the computer's system clock and is affected by time adjustments made by the operating system, such as
daylight saving time. Here's an example:
import time
print([Link]())
# Output: 1602299933.233374
As you can see, the function returns the current time as a floating-point number, which can be used for various
purposes, such as measuring the duration of an operation or the elapsed time since a certain point in time.
[Link]()
The [Link]() function suspends the execution of the current thread for a specified number of seconds. This
function can be used to pause the program for a certain period of time, allowing other parts of the program to
run, or to synchronize the execution of multiple threads. Here's an example:
import time
print("Start:", [Link]())
[Link](2)
print("End:", [Link]())
# Output:
# Start: 1602299933.233374
# End: 1602299935.233376
As you can see, the function [Link]() suspends the execution of the program for 2 seconds, allowing other
parts of the program to run during that time.
[Link]()
The [Link]() function formats a time value as a string, based on a specified format. This function is
particularly useful for formatting dates and times in a human-readable format, such as for display in a GUI, a
log file, or a report. Here's an example:
import time
t = [Link]()
formatted_time = [Link]("%Y-%m-%d %H:%M:%S", t)
print(formatted_time)
# Output: 2022-11-08 [Link]
As you can see, the function [Link]() formats the current time (obtained using [Link]()) as a string,
using a specified format. The format string contains codes that represent different parts of the time value, such
as the year, the month, the day, the hour, the minute, and the second.
Conclusion
The time module in Python provides a set of functions to work with time-related operations, such as
timekeeping, formatting, and time conversions. Whether you are writing a script, a library, or an application,
the time module is a powerful tool that can help you perform time-related tasks with ease and efficiency. So, if
you haven't already, be sure to check out the time module in Python and see how it can help you write better,
more efficient code.
Syntax
Here is the basic syntax for creating a command line utility using argparse in Python:
import argparse
parser = [Link]()
import argparse
parser = [Link]()
args = parser.parse_args()
print([Link])
import argparse
parser = [Link]()
args = parser.parse_args()
print([Link])
import argparse
parser = [Link]()
args = parser.parse_args()
print(args.n)
Conclusion
Creating command line utilities in Python is a straightforward and flexible process thanks to
the argparse module. With a few lines of code, you can create powerful and customizable command line tools
that can make your development workflow easier and more efficient. Whether you're working on small scripts
or large applications, the argparse module is a must-have tool for any Python developer.
Command Line Utility Code
import argparse
import requests
parser = [Link]()
The Walrus Operator is represented by the := syntax and can be used in a variety of contexts including while
loops and if statements.
Here's an example of how you can use the Walrus Operator in a while loop:
numbers = [1, 2, 3, 4, 5]
In this example, the length of the numbers list is assigned to the variable n using the Walrus Operator. The value
of n is then used in the condition of the while loop, so that the loop will continue to execute until
the numbers list is empty.
# walrus operator :=
# happy = True
# print(happy)
# print(happy := True)
# foods = list()
# while True:
# food = input("What food do you like?: ")
# if food == "quit":
# break
# [Link](food)
foods = list()
while (food := input("What food do you like?: ")) != "quit":
[Link](food)
In this example, the user input is assigned to the variable name using the Walrus Operator. The value of name is
then used in the if statement to determine whether it is in the names list. If it is, the corresponding message is
printed, otherwise, a different message is printed.
It is important to note that the Walrus Operator should be used sparingly as it can make code less readable if
overused.
In conclusion, the Walrus Operator is a useful tool for Python developers to have in their toolkit. It can help
streamline code and reduce duplication, but it should be used with care to ensure code readability and
maintainability.
Importing shutil
The syntax for importing the shutil module is as follows:
import shutil
Functions
The following are some of the most commonly used functions in the shutil module:
[Link](src, dst): This function copies the file located at src to a new location specified by dst. If the
destination location already exists, the original file will be overwritten.
shutil.copy2(src, dst): This function is similar to [Link], but it also preserves more metadata about the
original file, such as the timestamp.
[Link](src, dst): This function recursively copies the directory located at src to a new location
specified by dst. If the destination location already exists, the original directory will be merged with it.
[Link](src, dst): This function moves the file located at src to a new location specified by dst. This
function is equivalent to renaming a file in most cases.
[Link](path): This function recursively deletes the directory located at path, along with all of its
contents. This function is similar to using the rm -rf command in a shell.
Examples
Here are some examples of how you can use the shutil module in your Python code:
import shutil
# Copying a file
[Link]("[Link]", "[Link]")
# Copying a directory
[Link]("src_dir", "dst_dir")
# Moving a file
[Link]("[Link]", "[Link]")
# Deleting a directory
[Link]("dir")
As you can see, the shutil module provides a simple and efficient way to perform common file and directory-
related tasks in Python. Whether you need to copy, move, delete, or preserve metadata about files and
directories, the shutil module has you covered.
In conclusion, the shutil module is a powerful tool for automating file and directory-related tasks in Python.
Whether you are a beginner or an experienced Python developer, the shutil module is an essential tool to have
in your toolbox.
Exercise 9 Solution
Write a program to pronounce list of names using win32 API. If you are given a list l as follows:
Shoutout to Rahul
Shoutout to Nishant
Shoutout to Harry
Note: If you are not using windows, try to figure out how to do the same thing using some other package
# For Mac
from os import system
names = ["StupidProgramm1","AayushGarg15", "Yuniek", "NiteshUpadhyay2", "RAMESHKUMAR69"
, "AshishKushwaha4", "AshokBhatt", "MILLANDREME", "ValorantAccoun4", "Sanjeevthakur8",
"vivekRaogaddema", "NilutpalBaruah", "Priyanshu48", "KenZi2", "RahulGoyal14", "Kartikey
Surbhi", "AnirbanPati", "RohanPudasaini", "TechBlogs", "joelthomas1103", "dhairyapawaia
", "PrithviSingh15", "GoogolChad", "Moinhusen", "mahi98989897", "Blitzfan1", "umang001"
, "AvijitManna1", "Mr-NeonNeon", "MaryamTatheer", "NishantJaiswal2", "AnonymousBuddy1",
"MaryamTatheer", "GyanKumar1", "StarVipin", "vivekRaogaddema", "RaviSharma34", "AhsanTa
riq3", "gagankj", "ProgrammerShray", "AvijitDey5", "Anshuman097", "AnchalGupta9", "Stup
idProgramm1", "HimanshuKumar96", "hnxpriyanshu", "MaxM50", "piyushgoyall", "DEMANDHERE"
, "KrishnaAnand2", "SurajVishwaka10", "NominathKuwar", "firozeeIII", "jawad9899", "Arun
avaAdhikari", "Quazi-Misbah-Raza", "HistoricMind", "Rajbir98", "AkshayNivate", "vivekRa
ogaddema", "maanitgill", "krushnsinh", "universelhome", "OPGAMEROPGAMERm", "universelho
me", "learningtocodewithabdullah", "Abdullah426351", "SagarPathak3", "SAMARTH-VERMA", "
PrithvirajPati3", "SAURABHTRIPATH6", "SumanRajak", "Swayam2004", "Joydip2002", "PulkitP
areek", "RatnakarGautam221b", "tassawerzaidi", "GRyHacker", "uatta8088", "Athcode", "Pr
asoonShrivast", "piyushgoyall", "Saptak291", "PratyakshDhankh", "ZayanAhmad2", "Ali-Raz
aRaza9", "TridevJha", "KrrishHalder", "HeroProgrammin1", "Sanjeev-Kumar78", "AryanKushw
aha2", "GalluBhai", "AB265", "AayushGarg15", "StupidProgramm1", "dheerajkumar68", "Arpi
tJaiswal2", "Fighters006", "AviPandit", "mrz004", "AviPandit", "MihirSingh4", "Nks-hkhk
", "msCoder5", "SURAJGUSAIN1", "DivyanandPandey", "AhmadShuja", "JaydeepSindhav", "Cham
p7239", "piyushgoyall", "Joydip2002", "MukulVerma8745", "V-Durgeshwar-Ra", "SaacheKapoo
r", "41-GauravGaurav", "VeersinghZanka1", "LegendVibhu", "YashAgr", "vivekRaogaddema",
"Priyanshu-kundu", "iamarghamallick", "samad90", "iamarghamallick", "MukulVerma8745", "
MaxM50", "ItZgooseBoy", "piyushgoyall", "pavanteja14", "sologamerq1", "YugamTiwana", "p
iyushgoyall", "ShubhamSaini12", "AvishJain24", "ItZgooseBoy", "Iswastikmishra", "srisri
dmulti", "AvishJain24", "MFaizan3", "anukoolchauhan", "codeWithPrawar", "ArshitRupani",
"Muhammad-Anas11"]
Installation
pip install requests
Get Request
Once you have installed the Requests module, you can start using it to send HTTP requests. Here is a simple
example that sends a GET request to the Google homepage:
import requests
response = [Link]("[Link]
print([Link])
Post Request
Here is another example that sends a POST request to a web service and includes a custom header:
import requests
url = "[Link]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/5
8.0.3029.110 Safari/537.36",
"Content-Type": "application/json"
}
data = {
"username": "myusername",
"password": "mypassword"
}
print([Link])
In this example, we send a POST request to a web service to authenticate a user. We include a custom User-
Agent header and a JSON payload with the user's credentials.
bs4 Module
There is another module called BeautifulSoup which is used for web scraping in Python. I have personally used
bs4 module to finish a lot of freelancing task.
Exercise 10
Use the NewsAPI and the requests module to fetch the daily news related to different topics. Go
to: [Link] and explore the various options to build you application
Generators in Python
Generators in Python are special type of functions that allow you to create an iterable sequence of values. A
generator function returns a generator object, which can be used to generate the values one-by-one as you
iterate over it. Generators are a powerful tool for working with large or complex data sets, as they allow you to
generate the values on-the-fly, rather than having to create and store the entire sequence in memory.
Creating a Generator
In Python, you can create a generator by using the yield statement in a function. The yield statement returns a
value from the generator and suspends the execution of the function until the next value is requested. Here's
an example:
def my_generator():
for i in range(5):
yield i
gen = my_generator()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
# Output:
#0
#1
#2
#3
#4
As you can see, the generator function my_generator() returns a generator object, which can be used to generate
the values in the range 0 to 4. The next() function is used to request the next value from the generator, and the
generator resumes its execution until it encounters another yield statement or until it reaches the end of the
function.
Using a Generator
Once you have created a generator, you can use it in a variety of ways, such as in a for loop, a list
comprehension, or a generator expression. Here's an example:
gen = my_generator()
for i in gen:
print(i)
# Output:
#0
#1
#2
#3
#4
As you can see, the generator can be used in a for loop, just like any other iterable sequence. The generator is
used to generate the values one-by-one as the loop iterates over it.
Benefits of Generators
Generators offer several benefits over other types of sequences, such as lists, tuples, and sets. One of the main
benefits of generators is that they allow you to generate the values on-the-fly, rather than having to create and
store the entire sequence in memory. This makes generators a powerful tool for working with large or complex
data sets, as you can generate the values as you need them, rather than having to store them all in memory at
once.
Another benefit of generators is that they are lazy, which means that the values are generated only when they
are requested. This allows you to generate the values in a more efficient and memory-friendly manner, as you
don't have to generate all the values up front.
Conclusion
Generators in Python are a powerful tool for working with large or complex data sets, allowing you to generate
the values on-the-fly and store only what you need in memory. Whether you are working with a large dataset,
performing complex calculations, or generating a sequence of values, generators are a must-have tool in your
programming toolkit. So, if you haven't already, be sure to check out generators in Python and see how they
can help you write better, more efficient code.
Function Caching in Python
Function caching is a technique for improving the performance of a program by storing the results of a function
call so that you can reuse the results instead of recomputing them every time the function is called. This can be
particularly useful when a function is computationally expensive, or when the inputs to the function are unlikely
to change frequently.
In Python, function caching can be achieved using the functools.lru_cache decorator. The functools.lru_cache
decorator is used to cache the results of a function so that you can reuse the results instead of recomputing
them every time the function is called. Here's an example:
import functools
@functools.lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(20))
# Output: 6765
As you can see, the functools.lru_cache decorator is used to cache the results of the fib function.
The maxsize parameter is used to specify the maximum number of results to cache. If maxsize is set to None, the
cache will have an unlimited size.
Another benefit of function caching is that it can simplify the code of a program by removing the need to
manually cache the results of a function. With the functools.lru_cache decorator, the caching is handled
automatically, so you can focus on writing the core logic of your program.
Conclusion
Function caching is a technique for improving the performance of a program by storing the results of a function
so that you can reuse the results instead of recomputing them every time the function is called. In Python 3,
function caching can be achieved using the functools.lru_cache decorator, which provides an easy and efficient
way to cache the results of a function. Whether you're writing a computationally expensive program, or just
want to simplify your code, function caching is a great technique to have in your toolbox.
Exercise 10 Solution
#Exercise 10 Use the NewsAPI and the requests module to fetch the daily news related to different topics. Go t
o: [Link] and explore the various options to build you application
import requests
import json
Importing re Package
In Python, regular expressions are supported by the re module. The basic syntax for working with regular
expressions in Python is as follows:
import re
if match:
print("Match found!")
else:
print("Match not found.")
import re
pattern = r"expression"
text = "The cat is in the hat."
print(matches)
# Output: ['cat', 'hat']
Replacing a pattern
The following example shows how to replace a pattern in a string:
import re
pattern = r"[a-z]+at"
text = "The cat is in the hat."
print(matches)
# Output: ['cat', 'hat']
print(new_text)
# Output: "The dog is in the dog."
Extracting information from a string
The following example shows how to extract information from a string using regular expressions:
import re
pattern = r"\w+@\w+\.\w+"
if match:
email = [Link]()
print(email)
# Output: example@[Link]
Conclusion
Regular expressions are a powerful tool for working with strings and text data in Python. Whether you're
matching patterns, replacing text, or extracting information, regular expressions make it easy to perform
complex string operations with just a few lines of code. With a little bit of practice, you'll be able to use regular
expressions to solve all sorts of string-related problems in Python.
Async IO in Python
Asynchronous I/O, or async for short, is a programming pattern that allows for high-performance I/O
operations in a concurrent and non-blocking manner. In Python, async programming is achieved through the
use of the asyncio module and asynchronous functions.
Syntax
Here is the basic syntax for creating an asynchronous function in Python:
import asyncio
[Link](main())
Another way to schedule tasks concurrently is as follows:
L = await [Link](
my_async_function(),
my_async_function(),
my_async_function(),
)
print(L)
Async IO is a powerful programming pattern that allows for high-performance and concurrent I/O operations in
Python. With the asyncio module and asynchronous functions, you can write efficient and scalable code that can
handle large amounts of data and I/O operations without blocking the main thread. Whether you're working on
web applications, network services, or data processing pipelines, async IO is an essential tool for any Python
developer.
[Link]
import time
import asyncio
import requests
async def function1():
print("func 1")
URL = "[Link]
-[Link]"
response = [Link](URL)
open("[Link]", "wb").write([Link])
return "Harry"
[Link](main())
Multithreading in Python
Multithreading is a technique in programming that allows multiple threads of execution to run concurrently
within a single process. In Python, we can use the threading module to implement multithreading. In this
tutorial, we will take a closer look at the threading module and its various functions and how they can be used
in Python.
Importing Threading
We can use threading by importing the threading module.
import threading
Creating a thread
To create a thread, we need to create a Thread object and then call its start() method. The start() method runs
the thread and then to stop the execution, we use the join() method. Here's how we can create a simple thread.
import threading
def my_func():
print("Hello from thread", threading.current_thread().name)
thread = [Link](target=my_func)
[Link]()
[Link]()
Functions
The following are some of the most commonly used functions in the threading module:
[Link](target, args): This function creates a new thread that runs the target function with the
specified arguments.
[Link](): This function creates a lock that can be used to synchronize access to shared resources
between threads.
import threading
def thread_task(task):
# Do some work here
print("Task processed:", task)
if __name__ == '__main__':
tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
threads = []
for task in tasks:
thread = [Link](target=thread_task, args=(task,))
[Link](thread)
[Link]()
import threading
if __name__ == '__main__':
counter = 0
lock = [Link]()
threads = []
for i in range(2):
thread = [Link](target=increment, args=(counter, lock))
[Link](thread)
[Link]()
Conclusion
As you can see, the threading module provides a simple and efficient way to implement multithreading in
Python. Whether you need to create a new thread, run a function across multiple input values, or synchronize
access to shared resources, the threading module has you covered.
In conclusion, the threading module is a powerful tool for parallelizing code in Python. Whether you are a
beginner or an experienced Python developer, the threading module is an essential tool to have in your toolbox.
With multithreading, you can take advantage of multiple CPU cores and significantly improve the performance
of your code.
[Link]
import threading
import time
from [Link] import ThreadPoolExecutor
def main():
time1 = time.perf_counter()
# Normal Code
# func(4)
# func(2)
# func(1)
[Link]()
[Link]()
[Link]()
# Calculating Time
time2 = time.perf_counter()
print(time2 - time1)
def poolingDemo():
with ThreadPoolExecutor() as executor:
# future1 = [Link](func, 3)
# future2 = [Link](func, 2)
# future3 = [Link](func, 4)
# print([Link]())
# print([Link]())
# print([Link]())
l = [3, 5, 1, 2]
results = [Link](func, l)
for result in results:
print(result)
poolingDemo()
Multiprocessing in Python
Multiprocessing is a Python module that provides a simple way to run multiple processes in parallel. It allows
you to take advantage of multiple cores or processors on your system and can significantly improve the
performance of your code. In this repl, we'll take a closer look at the multiprocessing module and its various
functions and how they can be used in Python.
Importing Multiprocessing
We can use multiprocessing by importing the multiprocessing module.
import multiprocessing
Now, to use multiprocessing we need to create a process object which calls a start() method. The start() method
runs the process and then to stop the execution, we use the join() method. Here's how we can create a simple
process.
Creating a process
import multiprocessing
def my_func():
print("Hello from process", multiprocessing.current_process().name)
process = [Link](target=my_func)
[Link]()
[Link]()
Functions
The following are some of the most commonly used functions in the multiprocessing module:
[Link](target, args): This function creates a new process that runs the target function with
the specified arguments.
[Link](processes): This function creates a pool of worker processes that can be used to
parallelize the execution of a function across multiple input values.
[Link](): This function creates a queue that can be used to communicate data between
processes.
[Link](): This function creates a lock that can be used to synchronize access to shared
resources between processes.
def process_task(task):
# Do some work here
print("Task processed:", task)
if __name__ == '__main__':
tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def producer(queue):
for i in range(10):
[Link](i)
def consumer(queue):
while True:
item = [Link]()
print(item)
queue = [Link]()
p1 = [Link](target=producer, args=(queue,))
p2 = [Link](target=consumer, args=(queue,))
[Link]()
[Link]()
if __name__ == '__main__':
counter = [Link]('i', 0)
lock = [Link]()
[Link]()
[Link]()
[Link]()
[Link]()
Conclusion
As you can see, the multiprocessing module provides a simple and efficient way to run multiple processes in
parallel. Whether you need to create a new process, run a function across multiple input values, communicate
data between processes, or synchronize access to shared resources, the multiprocessing module has you
covered.
In conclusion, the multiprocessing module is a powerful tool for parallelizing code in Python. Whether you are a
beginner or an experienced Python developer, the multiprocessing module is an essential tool to have in your
toolbox.
[Link]
import [Link]
import requests
url = "[Link]
# pros = []
# for i in range(50):
# # downloadFile(url, i)
# p = [Link](target=downloadFile, args=[url, i])
# [Link]()
# [Link](p)
# for p in pros:
# [Link]()
import os
import time
while True:
command = "osascript -e \'say \"Hey Harry drink water\"\'; osascript -e \'display ale
rt \"Hey Harry, Drink water\"\'"
[Link](command)
[Link](REPEAT_INTERVAL)
Conclusion
Congratulations on completing the 100 days of Python code challenge! You have likely gained a solid
foundation in the language and developed a range of skills, from basic syntax to more advanced concepts such
as object-oriented programming. However, this is just the beginning of your journey with Python. There are
many more topics to explore, including machine learning, web development, game development, and more.
Python books: There are many excellent books on Python that can help you deepen your knowledge and
skills. Some popular options include "Python Crash Course" by Eric Matthes, "Automate the Boring Stuff with
Python" by Al Sweigart, and "Fluent Python" by Luciano Ramalho. I would also like to recommend "Hands on
Machine Learning book by Aurélien Géron"
YouTube Projects: There are many YouTube projects available which can be watched after you have some
basic understanding of python
Python communities: There are many online communities where you can connect with other Python
learners and experts, ask questions, and share your knowledge. Some popular options include the Python
subreddit, the Python Discord server, and the Python community on Stack Overflow.
GitHub repositories: GitHub is a great resource for finding Python projects, libraries, and code snippets.
Some useful repositories to check out include "awesome-python" (a curated list of Python resources), "scikit-
learn" (a machine learning library), and "django" (a web development framework).