100 Days of Code
100 Days of Code
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?
Features of Python
• Python provides very big library support. Some of the popular libraries include NumPy,
Tensorflow, Selenium, OpenCV, etc.
• Python helps in Data Analytics to analyze and understand raw data for insights and trends.
• It is used in AI and Machine Learning to simulate human behavior and to learn from past
data without hard coding.
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.
Day 2 – Some Amazing
Projects
1. Jarvis Virtual Assistant
2. Love Calculator
3. Face Recognition
5. Snake Game
Day 3 - Modules and pip in
Python!
Module is like a code library which can be used to borrow code written by somebody else in our
python program. There are two types of modules in python:
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.
It can be used as a package manager pip to install a python module. Lets install a module called
pandas using the following command
We use the import syntax to import a module in Python. Here is an example code:
import pandas
df = pandas.read_csv('words.csv')
print(df) # This will display first few rows from the words.csv file
Similarly we can install other modules and look into their documentations for usage instructions.
We will find ourselved doing this often in the later part of this course
Day 4 - Our First Program
Today we will write our first ever python program from scratch. It will consist of a bunch of print
statements. print can be used to print something on the console in python
Quick Quiz
Write a program to print a poem in Python. Choose the poem of your choice and publish your repl
Please make sure you attempt this. Might be easy for some of you but please finish each and every
task
Day 5 - Comments, Escape
sequence & Print in Python
Welcome to Day 5 of 100DaysOfCode. Today we will talk about Comments, Escape Sequences and
little bit more about print statement in Python. We will also throw some light on Escape Sequences
Python Comments
A comment is a part of the coding file that the programmer does not want to execute, rather the
programmer uses it to either explain a block of code or to avoid the execution of a specific part of
code while testing.
Single-Line Comments:
Example 1
Output:
Example 2
Output:
Example 3:
print("Python Program")
#print("Python Program")
Output:
Python Program
Multi-Line Comments:
To write multi-line comments you can use ‘#’ at each line or you can use the multiline string.
#If the condition is false then it will execute another block of code.
p=7
if (p > 5):
else:
Output:
p is greater than 5.
p=7
if (p > 5):
else:
Output
p is greater than 5.
To insert characters that cannot be directly used in a string, we use an escape sequence character.
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:
1. object(s): Any object, and as many as you like. Will be converted to string before printed
2. sep='separator': Specify how to separate the objects, if there is more than one. Default is ' '
3. end='end': Specify what to print at the end. Default is '\n' (line feed)
Variable is like a container that holds data. Very similar to how our containers in kitchen holds sugar,
salt etc Creating a variable is like creating a placeholder in memory and assigning it some value. In
Python its as easy as writing:
a=1
b = True
c = "Harry"
d = None
Data type specifies the type of value a variable holds. This is required in programming to do various
operations without causing an error.
In python, we can print the type of any operator using type function:
a=1
print(type(a))
b = "1"
print(type(b))
• int: 3, -8, 0
• complex: 6 + 2i
3. Boolean data:
Example:
print(list1)
Output:
Tuple: A tuple is an ordered collection of data with elements separated by a comma and enclosed
within parentheses. Tuples are immutable and can not be modified after creation.
Example:
print(tuple1)
Output:
dict: A dictionary is an unordered collection of data containing a key:value pair. The key:value pairs
are enclosed within curly brackets.
Example:
print(dict1)
Output:
Python has different types of operators for different operations. To create a calculator we require
arithmetic operators.
Arithmetic operators
+ Addition 15+7
- Subtraction 15-7
* Multiplication 5*7
** Exponential 5**3
/ Division 5/3
% Modulus 15%7
Exercise
n = 15
m=7
ans1 = n+m
ans2 = n-m
ans3 = n*m
ans4 = n/m
ans5 = n%m
ans6 = n//m
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.
Day 8 – Exercise:-1 Calculator
Solution
Day 9 – Typecasting in python
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.
Explicit typecasting:
The conversion of one data type into another data type, done via developer or programmer's
intervention or manually as per the requirement, is known as explicit type conversion.
It can be achieved with the help of Python’s built-in type conversion functions such as int(), float(),
hex(), oct(), str(), etc .
string = "15"
number = 7
Output:
Data types in Python do not have the same level i.e. ordering of data types is not the same in Python.
Some of the data types have higher-order, and some have lower order. While performing any
operations on variables with different data types in Python, one of the variable's data types will be
changed to the higher data type. According to the level, one data type is converted into other by the
Python interpreter itself (automatically). This is called, implicit typecasting in python.
Python converts a smaller data type to a higher data type to prevent data loss.
# a to int
a=7
print(type(a))
b = 3.0
print(type(b))
c=a+b
print(c)
print(type(c))
Ouput:
<class 'int'>
<class 'float'>
10.0
<class 'float'>
Day 10 - Taking User Input in
python
In python, we can take user input directly by using input() function.This input function gives a return
value as string/character hence we have to pass that into a variable
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:
print(a)
Output:
Harry
Day 11 –Strings in Python
What are strings?
In python, anything that you enclose between single or double quotation marks is considered a
string. A string is essentially a sequence or array of textual data. Strings are used when working with
Unicode characters.
Example
name = "Harry"
Output
Hello, Harry
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(a)
In Python, string is like an array of characters. We can access parts of string by using its index which
starts from 0.
Square brackets can be used to access elements of the string.
print(name[0])
print(name[1])
print(character)
Above code prints all the characters in the string name one by one!
Day 12 –Strings Slicing and
Operator on String
String Slicing & Operations on String
Length of a String
Example:
fruit = "Mango"
len1 = len(fruit)
Output:
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:
pie = "ApplePie"
print(pie[:5])
Output:
Apple
Note: This method of specifying the start and end index to specify a part of a string is called slicing.
Slicing Example:
pie = "ApplePie"
Apple
Pie
pleP
ApplePie
Strings are arrays and arrays are iterable. Thus we can loop through strings.
Example:
alphabets = "ABCDE"
for i in alphabets:
print(i)
Output:
E
Day 13 –Strings Methods
String methods
Python provides a set of built-in methods that we can use to alter and modify the strings.
upper() :
Example:
str1 = "AbcDEfghIJ"
print(str1.upper())
Output:
ABCDEFGHIJ
lower()
Example:
str1 = "AbcDEfghIJ"
print(str1.lower())
Output:
abcdefghij
strip() :
The strip() method removes any white spaces before and after the string.
Example:
print(str2.strip)
Output:
Silver Spoon
rstrip() :
print(str3.rstrip("!"))
Output:
Hello
replace() :
The replace() method replaces all occurences of a string with another string. Example:
print(str2.replace("Sp", "M"))
Output:
Silver Moon
split() :
The split() method splits the given string at the specified instance and returns the separated strings
as list items.
Example:
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:
str1 = "hello"
capStr1 = str1.capitalize()
print(capStr1)
capStr2 = str2.capitalize()
print(capStr2)
Output:
Hello
Hello world
center() :
The center() method aligns the string to the center as per the parameters given by the user.
Example:
print(str1.center(50))
Output:
We can also provide padding character. It will fill the rest of the fill characters provided by the user.
Example:
print(str1.center(50, "."))
Output:
count() :
The count() method returns the number of times the given value has occurred within the given
string.
Example:
str2 = "Abracadabra"
countStr = str2.count("a")
print(countStr)
Output:
endswith() :
The endswith() method checks if the string ends with a given value. If yes then return True, else
return False.
Example :
print(str1.endswith("!!!"))
Output:
True
We can even also check for a value in-between the string by providing start and end index positions.
Example:
print(str1.endswith("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:
print(str1.find("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:
print(str1.find("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:
print(str1.index("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:
print(str1.index("Daniel"))
Output:
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(str1.isalnum())
Output:
True
isalpha() :
The isalnum() 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(str1.isalpha())
Output:
True
islower() :
The islower() method returns True if all the characters in the string are lower case, else it returns
False.
Example:
print(str1.islower())
Output:
True
isprintable() :
The isprintable() method returns True if all the values within the given string are printable, if not,
then return False.
Example :
print(str1.isprintable())
Output:
True
isspace() :
The isspace() method returns True only and only if the string contains white spaces, else returns
False.
Example:
print(str1.isspace())
print(str2.isspace())
Output:
True
True
istitle() :
The istitile() returns True only if the first letter of each word of the string is capitalized, else it returns
False.
Example:
print(str1.istitle())
Output:
True
Example:
print(str2.istitle())
Output:
False
isupper() :
The isupper() method returns True if all the characters in the string are upper case, else it returns
False.
Example :
print(str1.isupper())
Output:
True
startswith() :
The endswith() method checks if the string starts with a given value. If yes then return True, else
return False.
Example :
print(str1.startswith("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:
print(str1.swapcase())
Output:
title() :
The title() method capitalizes each letter of the word within the string.
Example:
print(str1.title())
Output:
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.
Execute the block of code inside if statement. After execution return to the code out of the if……else
block.\
Execute the block of code inside else statement. After execution return to the code out of the
if……else block.
Example:
applePrice = 210
budget = 200
else:
Output:
elif Statements
Sometimes, the programmer may want to evaluate more than one condition, this can be done using
an elif statement.
Working of an elif statement
Execute the block of code inside if statement if the initial expression evaluates to True. After
execution return to the code out of the if block.
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:
num = 0
print("Number is negative.")
print("Number is Zero.")
else:
print("Number is positive.")
Output:
Number is Zero.
Nested if statements
We can use if, if-else, elif statements inside other if statements as well.
Example:
num = 18
print("Number is negative.")
else:
else:
print("Number is zero")
Output:
Create a python program capable of greeting you with Good Morning, Good Afternoon and Good
Evening. Your program should use time module to get the current hour. Here is a sample program
and documentation link for you:
import time
timestamp = time.strftime('%H:%M:%S')
print(timestamp)
timestamp = time.strftime('%H')
print(timestamp)
timestamp = time.strftime('%M')
print(timestamp)
timestamp = time.strftime('%S')
print(timestamp)
# https://docs.python.org/3/library/time.html#time.strftime
Day 16 – Match Case
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.
The case clause consists of a pattern to be matched to the variable, a condition to be evaluated if the
pattern matches, and a set of statements to be executed if the pattern matches.
Syntax:
match variable_name:
Example:
x=4
match x:
# if x is 0
case 0:
print("x is zero")
case 4 if x % 2 == 0:
# default case(will only be matched if the above cases were not matched)
case _:
print(x)
Output:
x % 2 == 0 and case is 4
Day 17 - For Loops
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
for loops can iterate over a sequence of iterable objects in python. Iterating over a sequence is
nothing but iterating over strings, lists, tuples, sets and dictionaries.
name = 'Abhishek'
for i in name:
Output:
A, b, h, i, s, h, e, k,
for x in colors:
print(x)
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(5):
print(k)
Output:
0
1
2
3
4
Here, we can see that the loop starts from 0 by default and increments at each iteration.
Example:
for k in range(4,9):
print(k)
Output:
4
5
6
7
8
Quick Quiz
As the name suggests, while loops execute statements while the condition is True. As soon as the
condition becomes False, the interpreter comes out of the while loop.
Example:
count = 5
print(count)
count = count - 1
Output:
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.
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
print(x)
x=x-1
else:
print('counter is 0')
Output:
5
4
counter is 0
do..while is a loop in which a set of instructions will execute at least once (irrespective of the
condition) and then the repetition of loop's body will depend on the condition passed at the end of
the while loop. It is also known as an exit-controlled loop.
To create a do while loop in Python, you need to modify the while loop a bit in order to get similar
behavior to a do while loop.
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:
print(number)
break
Output
-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.
Day 19 – Break and Continue
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):
if(i==50):
break
else:
print("Mississippi")
print("Thank you")
output
1 Mississippi
2 Mississippi
3 Mississippi
4 Mississippi
5 Mississippi
50 Mississippi
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)
output
2
0
Day 20 – Functions in Python
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
• Create a function using the def keyword, followed by a function name, followed by a
paranthesis (()) and a colon(:).
• 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:
name("Sam", "Wilson")
Output:
• Default Arguments
• Keyword 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:
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:
Output:
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")\
Example 2: when number of arguments passed matches to the actual function definition.
Output:
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):
Output:
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 dictionary.
Example:
def name(**name):
Output:
return Statement
The return statement is used to return the value of the expression back to the calling function.
Example:
return "Hello, " + fname + " " + mname + " " + lname
Output:
• List items are separated by commas and enclosed within square brackets [].
Example 1:
lst1 = [1,2,2,3,5,4,6]
print(lst1)
print(lst2)
Output:
[1, 2, 2, 3, 5, 4, 6]
Example 2:
print(details)
Output:
As we can see, a single list can contain items of different data types.
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:
Positive Indexing:
As we have seen that list items have index, as such we can access items using these indexes.
Example:
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:
print(colors[-1])
print(colors[-3])
print(colors[-5])
Output:
Green
Blue
Red
We can check if a given item is present in the list. This is done using the in keyword.
if "Yellow" in colors:
print("Yellow is present.")
else:
print("Yellow is absent.")
Output:
Yellow is present.
if "Orange" in colors:
print("Orange is present.")
else:
print("Orange is absent.")
Output:
Orange is absent.
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"]
Output:
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"]
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"]
Output:
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"]
Output:
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[1:8:3])
Output:
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
print(namesWith_O)
Output:
print(namesWith_O)
Output:
list.sort()
This method sorts the list in ascending order. The original list is updated
Example 1:
colors.sort()
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
num.sort()
print(num)
Output:
[1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9]
Example:
colors.sort(reverse=True)
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
num.sort(reverse=True)
print(num)
Output:
[9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 1, 1]
Note: Do not mistake the reverse parameter with the reverse method.
reverse()
Example:
colors.reverse()
print(colors)
num = [4,2,5,3,6,1,2,1,2,8,9,7]
num.reverse()
print(num)
Output:
[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:
print(colors.index("green"))
num = [4,2,5,3,6,1,2,1,3,2,8,9,7]
print(num.index(3))
Output:
count()
Returns the count of the number of items with the given value.
Example:
print(colors.count("green"))
num = [4,2,5,3,6,1,2,1,3,2,8,9,7]
Output:
copy()
Returns copy of the list. This can be done to perform operations on the list without modifying the
original list.
Example:
newlist = colors.copy()
print(colors)
print(newlist)
Output:
append():
Example:
colors.append("green")
print(colors)
Output:
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:
Output:
extend():
This method adds an entire list or any other collection datatype (set, tuple, dictionary) to the existing
list.
Example 1:
colors.extend(rainbow)
print(colors)
Output:
Example:
print(colors + colors2)
Output:
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)
print(tuple1)
print(tuple2)
Output:
(1, 2, 2, 3, 5, 4, 6)
Example 2:
print(details)
Output:
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:
I. Positive Indexing:
As we have seen that tuple items have index, as such we can access items using these indexes.
Example:
print(country[1])
print(country[2])
Output:
Spain
Italy
India
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:
print(country[-3])
print(country[-4])
Output:
Germany
India
Italy
We can check if a given item is present in the tuple. This is done using the in keyword.
Example 1:
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.
You can print a range of tuple items by specifying where do 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")
Output:
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")
Output:
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
Output:
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")
Output:
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.
animals = ("cat", "dog", "bat", "mouse", "pig", "horse", "donkey", "goat", "cow")
print(animals[1:8:3])
Output:
Here, jump index is 3. Hence it prints every 3rd element within given index.
Day 25 – Operations on Tuple
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:
temp = list(countries)
countries = tuple(temp)
print(countries)
Output:
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:
print(southEastAsia)
Output:
Tuple methods
As tuple is immutable type of collection of elements it have limited built in methods.They are
explained below
count() Method
The count() method of Tuple returns the number of times the given element appears in the tuple.
Syntax:
tuple.count(element)
Example
Tuple1 = (0, 1, 2, 3, 2, 3, 1, 3, 2)
res = Tuple1.count(3)
Output
index() method
The Index() method returns the first occurrence of the given element from the tuple.
Syntax:
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 = Tuple.index(3)
Output
3
Day 26 -Exercise:- 2 Solutions
Excersice 2: Good Morning Sir
Create a python program capable of greeting you with Good Morning, Good Afternoon and Good
Evening. Your program should use time module to get the current hour. Here is a sample program
and documentation link for you:
import time
timestamp = time.strftime('%H:%M:%S')
print(timestamp)
timestamp = time.strftime('%H')
print(timestamp)
timestamp = time.strftime('%M')
print(timestamp)
timestamp = time.strftime('%S')
print(timestamp)
# https://docs.python.org/3/library/time.html#time.strftime
Day 27 -Excersice 3: KBC
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.
Day 28 – f-string
String formatting in python
print(txt.format(price = 49))
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 str.format() method. The f-string offers a convenient way to embed
Python expression inside string literals for formatting.
Example
val = 'Geeks'
name = 'Tushar'
age = 23
Output:
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
Day 29 – Docstrings in Python
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):
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
Parameters
----------
num1 : int
num2 : int
Returns
-------
int
See Also
--------
Examples
--------
>>> add(2, 2)
>>> add(25, 0)
25
"""
Python Comments
Comments are descriptions that help programmers better understand the intent and functionality of
the program. They are completely ignored by the Python interpreter.
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.
Whenever string literals are present just after the definition of a function, module, class or method,
they are associated with the object as their doc attribute. We can later use this attribute to retrieve
this docstring.
Example
def square(n):
'''Takes in a number n, returns the square of n'''
return n**2
print(square.__doc__)
Output:
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.
Long time Pythoneer Tim Peters succinctly channels the BDFL’s guiding principles for Python’s design
into 20 aphorisms, only 19 of which have been written down.
Readability counts.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Easter egg
import this
Day 30 – Recursions in Python
Recursion in python
In Python, we know that a function can call other functions. It is even possible for the function to call
itself. These types of construct are termed as recursive functions.
Example:
def factorial(num):
return 1
else:
# Driver Code
num = 7;
print("Number: ",num)
print("Factorial: ",factorial(num))
Output:
number: 7
Factorial: 5040
Day 31 - Sets
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:
print(info)
Output:
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:
print(item)
Output:
False
Carla
19
5.9
Day 32 – Set Methods
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.
The union() and update() methods prints all items that are present in the two sets. The union()
method returns a new set whereas update() method adds item into the existing set from another set.
Example:
cities3 = cities.union(cities2)
print(cities3)
Output:
Example:
cities.update(cities2)
print(cities)
Output:
The intersection() and intersection_update() methods prints only items that are similar to both the
sets. The intersection() method returns a new set whereas intersection_update() method updates
into the existing set from another set.
Example:
cities3 = cities.intersection(cities2)
print(cities3)
Output:
{'Madrid', 'Tokyo'}
Example :
cities.intersection_update(cities2)
print(cities)
Output:
{'Tokyo', 'Madrid'}
The symmetric_difference() and symmetric_difference_update() methods prints only items that are
not similar to both the sets. The symmetric_difference() method returns a new set whereas
symmetric_difference_update() method updates into the existing set from another set.
Example:
cities3 = cities.symmetric_difference(cities2)
print(cities3)
Output:
Example:
cities.symmetric_difference_update(cities2)
print(cities)
Output:
The difference() and difference_update() methods prints only items that are only present in the
original set and not in both the sets. The difference() method returns a new set whereas
difference_update() method updates into the existing set from another set.
Example:
cities3 = cities.difference(cities2)
print(cities3)
Output:
Example:
print(cities.difference(cities2))
Output:
Set Methods
There are several in-built methods used for the manipulation of set.They 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:
print(cities.isdisjoint(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:
print(cities.issuperset(cities2))
print(cities.issuperset(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:
print(cities2.issubset(cities))
Output:
True
add()
If you want to add a single item to the set use the add() method.
Example:
cities.add("Helsinki")
print(cities)
Output:
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.update(cities2)
print(cities)
Output:
remove()/discard()
We can use remove() and discard() methods to remove items form list.
Example :
cities = {"Tokyo", "Madrid", "Berlin", "Delhi"}
cities.remove("Tokyo")
print(cities)
Output:
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.remove("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:
item = cities.pop()
print(cities)
print(item)
Output:
del
del is not a method, rather it is a keyword which deletes the set entirely.
Example:
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.clear()
print(cities)
Output:
set()
Example
if "Carla" in info:
print("Carla is present.")
else:
print("Carla is absent.")
Output:
Carla is present.
Day 33 - Dictionary
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:
print(info)
Output:
Values in a dictionary can be accessed using keys. We can access dictionary values by mentioning
keys either in square brackets or by using get method.
Example:
print(info['name'])
print(info.get('eligible'))
Output:
Karan
True
We can print all the values in the dictionary using values() method.
Example:
print(info.values())
Output:
We can print all the keys in the dictionary using keys() method.
Example:
info = {'name':'Karan', 'age':19, 'eligible':True}
print(info.keys())
Output:
We can print all the key-value pairs in the dictionary using items() method.
Example:
print(info.items())
Output:
Dictionary uses several built-in methods for manipulation.They 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:
print(info)
info.update({'age':20})
info.update({'DOB':2001})
print(info)
Output:
There are a few methods that we can use to remove items from dictionary.
clear():
The clear() method removes all the items from the list.
Example:
info.clear()
print(info)
Output:
{}
pop():
The pop() method removes the key-value pair whose key is passed as a parameter.
Example:
info.pop('eligible')
print(info)
Output:
popitem():
The popitem() method removes the last key-value pair from the dictionary.
Example:
info.popitem()
print(info)
Output:
del:
Example:
del info['age']
print(info)
Output:
If key is not provided, then the del keyword will delete the dictionary entirely.
Example:
del info
print(info)
Output:
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
else:
Example:
for x in range(5):
else:
Output:
Out of loop
Day 36 - Exception Handling
Exception Handling
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:
#exception
except:
Example:
try:
except ValueError:
Output:
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:
#exception
except:
finally:
Example:
try:
except ValueError:
else:
print("Integer Accepted.")
finally:
Output 1:
Enter an integer: 19
Integer Accepted.
This block is always executed.
Output 2:
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.
In Python, we can define custom exceptions by creating a new class that is derived from the built-in
Exception class.
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.
Day 39 – Exercise:-3 Solution
KBC
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.
Day 40 – Exercise:-4 Secret
Code Language
Write a python program to translate a message into secret code language. Use the rules below to
translate 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 three 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
There is also a shorthand syntax for the if-else statement that can be used when the condition being
tested is simple and the code blocks to be executed are short. Here's an example:
a=2
b = 330
You can also have multiple else statements on the same line:
Example
a = 330
b = 330
Another Example
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.
Day 42 – Enumerate Function
in python
Enumerate function in python
The enumerate function is a built-in function in Python that allows you to loop over a sequence (such
as a list, tuple, or string) and get the index and value of each element in the sequence at the same
time. Here's a basic example of how it works:
# Loop over a list and print the index and value of each element
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.
By default, the enumerate function starts the index at 0, but you can specify a different starting index
by passing it as an argument to the enumerate function:
# Loop over a list and print the index (starting at 1) and value of each element
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:
fruits = ['apple', 'banana', 'mango']
print(f'{index+1}: {fruit}')
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
print(index, color)
# Loop over a string and print the index and value of each character
s = 'hello'
print(index, c)
Day 43 – Virtual Environment
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:
source myenv/bin/activate
myenv\Scripts\activate.bat
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
To create a requirements.txt file, you can use the pip freeze command, which outputs a list of
installed packages and their versions. For example:
To install the packages listed in the requirements.txt file, you can use the pip install command with
the -r flag:
# Install the packages listed in the requirements.txt file
Using a virtual environment and a requirements.txt 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.
Day 44 – How import works in
python
How importing in python works
Importing in Python is the process of loading code from a Python module into the current script. This
allows you to use the functions and variables defined in the module in your current script, as well as
any additional modules that the imported module may depend on.
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 = math.sqrt(9)
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)
You can also import multiple functions or variables at once by separating them with a comma:
result = sqrt(9)
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)
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.
import math as m
result = m.sqrt(9)
Finally, Python has a built-in function called dir that you can use to view the names of all the
functions and variables defined in a module. This can be helpful for exploring and understanding the
contents of a new module.
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.
Day 45 – if
__name__==”__main__” in
Python
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():
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():
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
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.
Day 46 -os Module
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
f = os.open("myfile.txt", os.O_RDONLY)
os.close(f)
To open a file for writing, you can use the os.O_WRONLY flag:
import os
f = os.open("myfile.txt", os.O_WRONLY)
os.close(f)
import os
files = os.listdir(".")
You can also use the os.mkdir function to create a new directory:
import os
os.mkdir("newdir")
Finally, the os module provides functions for running system commands. For example, you can use
the os.system function to run a command and get the output:
import os
output = os.system("ls")
You can also use the os.popen 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 = os.popen("ls")
output = f.read()
f.close()
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.
Day 47 – Exercise:-4 Solution
Write a python program to translate a message into secret code language. Use the rules below to
translate 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 three 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
st = input("Enter message")
print(coding)
if(coding):
nwords = []
if(len(word)>=3):
r1 = "dsf"
r2 = "jkr"
nwords.append(stnew)
else:
nwords.append(word[::-1])
print(" ".join(nwords))
else:
nwords = []
if(len(word)>=3):
stnew = word[3:-3]
nwords.append(stnew)
else:
nwords.append(word[::-1])
print(" ".join(nwords))
Day 48 – Local & Global
Variable
local and global variables
Before we dive into the differences between local and global variables, let's first recall what a
variable is in Python.
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!"
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.
Now, what if we want to modify a global variable from within a function? This is where the global
keyword comes in.
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
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!
Day 49 – File I/O inPython
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('myfile.txt', '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
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' ).
Once we have a file object, we can use various methods to read from the file.
The read() method reads the entire contents of the file and returns it as a string.
f = open('myfile.txt', 'r')
contents = f.read()
print(contents)
Writing to a File
f = open('myfile.txt', 'w')
f.write('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('myfile.txt', 'a')
f.write('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('myfile.txt', 'r')
f.close()
Alternatively, you can use the with statement to automatically close the file after you are done with
it.
The readline() method reads a single line from the file. If we want to read multiple lines, we can use a
loop.
f = open('myfile.txt', 'r')
while True:
line = f.readline()
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('myfile.txt', 'w')
f.writelines(lines)
f.close()
This will write the strings in the lines list to the file myfile.txt. 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('myfile.txt', 'w')
f.write(line + '\n')
f.close()
It is also a good practice to close the file after you are done with it.
Day 51 – seek(), tell() and
other functions
seek() and tell() functions
In Python, the seek() and tell() functions are used to work with file objects and their positions within
a file. These functions are part of the built-in io module, which provides a consistent interface for
reading and writing to various file-like objects, such as files, pipes, and in-memory buffers.
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:
f.seek(10)
data = f.read(5)
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:
data = f.read(10)
current_position = f.tell()
f.seek(current_position)
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.
f.write('Hello World!')
f.truncate(5)
print(f.read())
Day 52 – Lambda Function
Lambda Functions in Python
In Python, a lambda function is a small anonymous function without a name. It is defined using the
lambda keyword and has the following syntax:
Lambda functions are often used in situations where a small function is required for a short period of
time. They are commonly used as arguments to higher-order functions, such as map, filter, and
reduce.
def double(x):
return x * 2
lambda x: x * 2
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:
return x * y
lambda x, y: x * y
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.
Day 53 – Map, filter and
reduce
Map, Filter and Reduce
In Python, the map, filter, and reduce functions are built-in functions that allow you to apply a
function to a sequence of elements and return a new sequence. These functions are known as
higher-order functions, as they take other functions as arguments.
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]
print(list(doubled))
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.
numbers = [1, 2, 3, 4, 5]
print(list(evens))
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]
print(sum)
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.
Day 54 – ‘is’ vs ‘==’ in Python
'is' vs '==' in Python
In Python, is and == are both comparison operators that can be used to check if two values are equal.
However, there are some important differences between the two that you should be aware of.
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.
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.
Day 56 – Introductino to
OOP’s in Python
Introduction to Object-oriented programming
The procedure we are following till now is the “Procedural Programming” approach. So, in this
session, we will learn about Object Oriented Programming (OOP). The basic idea of object-oriented
programming (OOP) in Python is to use classes and objects to represent real-world concepts and
entities.
A class is a blueprint or template for creating objects. It defines the properties and methods that an
object of that class will have. Properties are the data or state of an object, and methods are the
actions or behaviors that an object can perform.
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.
Day 57 – Classes and objects
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:
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(obj1.name)
print(obj1.age)
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.
class Details:
name = "Rohan"
age = 20
def desc(self):
obj1 = Details()
obj1.desc()
Output:
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.
def __init__(self):
# initializations
init is one of the reserved functions in Python. In Object Oriented Programming, it is known as a
constructor.
1. Parameterized Constructor
2. Default Constructor
When the constructor accepts arguments along with self, it is known as parameterized constructor.
These arguments can be used inside the class to assign the values to the data members.
Example:
class Details:
self.animal = animal
self.group = group
Output:
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):
obj1=Details()
Output:
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.
One common use of decorators is to add logging to a function. For example, you could use a
decorator to log the arguments and return value of a function each time it is called:
import logging
def log_function_call(func):
return result
return decorated
@log_function_call
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.
Day 60 – Getters and Setters
in Python
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:
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:
>>> obj.value
10
Setters
It is important to note that the getters do not take any parameters and we cannot set the value
through getter method.For that we need setter method which can be added by decorating method
with @property_name.setter
class MyClass:
self._value = value
@property
def value(self):
return self._value
@value.setter
self._value = new_value
>>> obj.value = 20
>>> obj.value
20
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.
Day 61 – Inheritance in
Python
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.
class BaseClass:
class DerivedClass(BaseClass):
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):
class Child(Parent):
def func2(self):
print("This function is in child class.")
object = Child()
object.func1()
object.func2()
Output:
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(self.mothername)
class Father:
fathername = ""
def father(self):
print(self.fathername)
def parents(self):
s1 = Son()
s1.fathername = "Mommy"
s1.mothername = "Daddy"
s1.parents()
Output:
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:
self.grandfathername = grandfathername
class Father(Grandfather):
self.fathername = fathername
Grandfather.__init__(self, grandfathername)
class Son(Father):
self.sonname = sonname
def print_name(self):
print(s1.grandfathername)
s1.print_name()
Output:
George
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):
class Child1(Parent):
def func2(self):
class Child2(Parent):
def func3(self):
object1 = Child1()
object2 = Child2()
object1.func1()
object1.func2()
object2.func1()
object2.func3()
Output:
Hybrid Inheritance:
Example
class School:
def func1(self):
class Student1(School):
def func2(self):
class Student2(School):
def func3(self):
def func4(self):
object = Student3()
object.func1()
object.func2()
Output:
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.
6. Example:
7. class Student:
8. # constructor is defined
9. def __init__(self, age, name):
10. self.age = age # public variable
11. self.name = name # public variable
12.
13. obj = Student(21,"Harry")
14. print(obj.age)
15. print(obj.name)
16. Output:
17. 21
18. Harry
By definition, Private members of a class (variables or methods) are those members which are only
accessible inside the class. We cannot use private members outside of class.
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:
self.y = 34
print(self.y)
class Subject(Student):
pass
obj = Student(21,"Harry")
obj1 = Subject
print(obj.__age)
print(obj.__funName())
print(obj1.__age)
print(obj1.__funName())
Output:
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):
my_object = MyClass()
In object-oriented programming (OOP), the term "protected" is used to describe a member (i.e., a
method or attribute) of a class that is intended to be accessed only by the class itself and its
subclasses. In Python, the convention for indicating that a member is protected is to prefix its name
with a single underscore (_). For example, if a class has a method called _my_method, it is indicating
that the method should only be accessed by the class itself and its subclasses.
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"
return "CodeWithHarry"
class Subject(Student): #inherited class
pass
obj = Student()
obj1 = Subject()
print(obj._name)
print(obj._funName())
print(obj1._name)
print(obj1._funName())
Output:
Harry
CodeWithHarry
Harry
CodeWithHarry
Day 63 – Exercise:-5 Solution
snake water gun
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.
Day 64 – Exercise:-6 Library
Management System
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 different methods. Show that your program doesnt persist the books after
the program is stopped!
Day 65 – Static Method
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
return a + b
result = Math.add(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.
Day 66 – Instance & Class
Attribute
Instance vs class variables
In Python, variables can be defined at the class level or at the instance level. Understanding the
difference between these types of variables is crucial for writing efficient and maintainable code.
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:
self.name = name
def print_name(self):
print(self.name)
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 self.class.variable_name. But instance variables are defined
inside the methods and need to be explicitly declared as instance variable by using
self.variable_name.
Day 67 – Exercise:-6 Solution
Library Management System
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 different methods. Show that your program doesnt persist the books after
the program is stopped!
Day 68 – Exercise:-7 Clear the
clutter
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 1.png all the way till n.png where n is the number of png files in that
folder. Do the same for other file formats. For example:
In Python, classes are a way to define custom data types that can store data and define functions
that can manipulate that data. One type of function that can be defined within a class is called a
"method." In this blog post, we will explore what Python class methods are, why they are useful, and
how to use them.
A class method is a type of method that is bound to the class and not the instance of the class. In
other words, it operates on the class as a whole, rather than on a specific instance of the class. Class
methods are defined using the "@classmethod" decorator, followed by a function definition. The first
argument of the function is always "cls," which represents the class itself.
Class methods are useful in several situations. For example, you might want to create a factory
method that creates instances of your class in a specific way. You could define a class method that
creates the instance and returns it to the caller. Another common use case is to provide alternative
constructors for your class. This can be useful if you want to create instances of your class in multiple
ways, but still have a consistent interface for doing so.
To define a class method, you simply use the "@classmethod" decorator before the method
definition. The first argument of the method should always be "cls," which represents the class itself.
Here is an example of how to define a class method:
class ExampleClass:
@classmethod
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.
Day 70 – Class Method as
alternative Constructor
Class Methods as Alternative Constructors
In object-oriented programming, the term "constructor" refers to a special type of method that is
automatically executed when an object is created from a class. The purpose of a constructor is to
initialize the object's attributes, allowing the object to be fully functional and ready to use.
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:
self.name = name
self.age = 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:
self.name = name
self.age = age
@classmethod
Now you can create a Person object from a string like this:
class Rectangle:
self.width = width
self.height = 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:
self.width = width
self.height = height
@classmethod
rectangle = Rectangle.square(10)
Day 71 -
dir(), __dict__ and help() met
hods in python
dir(), __dict__ and help() methods in python
We must look into dir(), __dict__() and help() attribute/methods in python. They make it easy for us
to understand how classes resolve various functions and executes code. In Python, there are three
built-in functions that are commonly used to get information about objects: dir(), dict, and help().
Let's take a look at each of them:
dir(): The dir() function returns a list of all the attributes and methods (including dunder methods)
available for an object. It is a useful tool for discovering what you can do with an object. Example:
>>> x = [1, 2, 3]
>>> dir(x)
...
>>> p.__dict__
Output
{'name': 'John', 'age': 30}
help(): The help() function is used to get help documentation for an object, including a description of
its attributes and methods. Example:
>>> help(str)
class str(object)
| that will be decoded using the given encoding and error handler.
| or repr(object).
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.
Day 72 – Super Keyword
Super keyword in Python
The super() keyword in Python is used to refer to the parent class. It is especially useful when a class
inherits from multiple parent classes and you want to call a method from one of the parent classes.
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):
class ChildClass(ParentClass):
def child_method(self):
super().parent_method()
child_object = ChildClass()
child_object.child_method()
Output:
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):
def parent_method(self):
def child_method(self):
super().parent_method()
child_object = ChildClass()
child_object.child_method()
Output:
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.
Day 73 – Magic/Dunder
Methods in Python
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.
Day 74 – Method Overriding
Method Overriding in Python
Method overriding is a powerful feature in object-oriented programming that allows you to redefine
a method in a derived class. The method in the derived class is said to override the method in the
base class. When you create an instance of the derived class and call the overridden method, the
version of the method in the derived class is executed, rather than the version in the base class.
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):
self.radius = radius
def area(self):
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):
self.radius = radius
def area(self):
super().area()
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.
Day 75 - 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 1.png all the way till n.png where n is the number of png files in that
folder. Do the same for other file formats. For example:
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.
Day 77 – Operator
Overloading
Operator Overloading in Python: An Introduction
Operator Overloading is a feature in Python that allows developers to redefine the behavior of
mathematical and comparison operators for custom data types. This means that you can use the
standard mathematical operators (+, -, *, /, etc.) and comparison operators (>, <, ==, etc.) in your
own classes, just as you would for built-in data types like int, float, and str.
Operator overloading allows you to create more readable and intuitive code. For instance, consider a
custom class that represents a point in 2D space. You could define a method called 'add' to add two
points together, but using the + operator makes the code more concise and readable:
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
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:
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.
Day 78 – Single inheritance
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:
self.name = name
self.species = species
def make_sound(self):
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):
self.breed = 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.
Day 79 – Multiple inheritance
Multiple Inheritance in Python
Syntax
In Python, multiple inheritance is implemented by specifying multiple parent classes in the class
definition, separated by commas.
# class body
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:
self.name = name
self.species = species
def make_sound(self):
class Mammal:
self.name = name
self.fur_color = fur_color
self.breed = breed
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.
Day 80 – Multilevel
inheritance
Multilevel Inheritance in Python
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:
class DerivedClass1(BaseClass):
class DerivedClass2(DerivedClass1):
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:
self.name = name
self.species = species
def show_details(self):
print(f"Name: {self.name}")
print(f"Species: {self.species}")
class Dog(Animal):
self.breed = breed
def show_details(self):
Animal.show_details(self)
print(f"Breed: {self.breed}")
class GoldenRetriever(Dog):
self.color = color
def show_details(self):
Dog.show_details(self)
print(f"Color: {self.color}")
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.
dog.show_details()
Output:
Name: Max
Species: Dog
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 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:
class BaseClass2:
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:
self.name = name
self.age = age
def show_details(self):
print("Name:", self.name)
print("Age:", self.age)
class Person(Human):
self.address = address
def show_details(self):
Human.show_details(self)
print("Address:", self.address)
class Program:
self.program_name = program_name
self.duration = duration
def show_details(self):
print("Duration:", self.duration)
class Student(Person):
self.program = program
def show_details(self):
Person.show_details(self)
self.program.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.
student.show_details()
Output
Age: 25
Duration: 4
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
class Animal:
self.name = name
def show_details(self):
print("Name:", self.name)
class Dog(Animal):
Animal.__init__(self, name)
self.breed = breed
def show_details(self):
Animal.show_details(self)
print("Species: Dog")
print("Breed:", self.breed)
class Cat(Animal):
Animal.__init__(self, name)
self.color = color
def show_details(self):
Animal.show_details(self)
print("Species: Cat")
print("Color:", self.color)
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:
dog.show_details()
cat.show_details()
Output:
Name: Max
Species: Dog
Name: Luna
Species: Cat
Color: Black
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.
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.
Day 83 – Exercise:-9
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
Day 84 – Time Module
The time Module in Python
The time module in Python provides a set of functions to work with time-related operations, such as
timekeeping, formatting, and time conversions. This module is part of the Python Standard Library
and is available in all Python installations, making it a convenient and essential tool for a wide range
of applications. In this day 84 tutorial, we'll explore the time module in Python and see how it can be
used in different scenarios.
time.time()
The time.time() 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(time.time())
# 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.
time.sleep()
The time.sleep() 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:", time.time())
time.sleep(2)
print("End:", time.time())
# Output:
# Start: 1602299933.233374
# End: 1602299935.233376
As you can see, the function time.sleep() suspends the execution of the program for 2 seconds,
allowing other parts of the program to run during that time.
time.strftime()
The time.strftime() 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 = time.localtime()
print(formatted_time)
As you can see, the function time.strftime() formats the current time (obtained
using time.localtime()) 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.
Day 85 – Creating Command
line Utility in Python
Creating Command Line Utilities in Python
Command line utilities are programs that can be run from the terminal or command line interface,
and they are an essential part of many development workflows. In Python, you can create your own
command line utilities using the built-in argparse module.
Syntax
Here is the basic syntax for creating a command line utility using argparse in Python:
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
print(args.arg1)
print(args.arg2)
Examples
Here are a few examples to help you get started with creating command line utilities in Python:
The following example shows how to add an optional argument to your command line utility:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-o", "--optional", help="description of optional argument",
default="default_value")
args = parser.parse_args()
print(args.optional)
The following example shows how to add a positional argument to your command line utility:
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
print(args.positional)
The following example shows how to add an argument with a specified type:
import argparse
parser = argparse.ArgumentParser()
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.
Day 86 – Walrus Operator
The Walrus Operator in Python
The Walrus Operator is a new addition to Python 3.8 and allows you to assign a value to a variable
within an expression. This can be useful when you need to use a value multiple times in a loop, but
don't want to repeat the calculation.
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]
print(numbers.pop())
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.
print(f"Hello, {name}!")
else:
# walrus operator :=
# happy = True
# print(happy)
# print(happy := True)
# foods = list()
# while True:
# if food == "quit":
# break
# foods.append(food)
foods = list()
foods.append(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.
Day 87 – Shutil Module
Shutil Module in Python
Shutil is a Python module that provides a higher level interface for working with file and directories.
The name "shutil" is short for shell utility. It provides a convenient and efficient way to automate
tasks that are commonly performed on files and directories. In this repl, we'll take a closer look at the
shutil module and its various functions and how they can be used in Python.
Importing shutil
import shutil
Functions
The following are some of the most commonly used functions in the shutil module:
• shutil.copy(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 shutil.copy, but it also preserves more
metadata about the original file, such as the timestamp.
• shutil.copytree(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.
• shutil.move(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.
• shutil.rmtree(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
shutil.copy("src.txt", "dst.txt")
# Copying a directory
shutil.copytree("src_dir", "dst_dir")
# Moving a file
shutil.move("src.txt", "dst.txt")
# Deleting a directory
shutil.rmtree("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.
Day 88 – Exercise:-9 Solutions
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
Day 89 – Requests Module
Requests module in python
The Python Requests module is an HTTP library that enables developers to send HTTP requests in
Python. This module enables you to send HTTP requests using Python code and makes it possible to
interact with APIs and web services.
Installation
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 = requests.get("https://www.google.com")
print(response.text)
Post Request
Here is another example that sends a POST request to a web service and includes a custom header:
import requests
url = "https://api.example.com/login"
headers = {
"Content-Type": "application/json"
data = {
"username": "myusername",
"password": "mypassword"
print(response.text)
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.
Day 90 – Exercise:-10 News
App
Exercise 10
Use the NewsAPI and the requests module to fetch the daily news related to different topics. Go
to: https://newsapi.org/ and explore the various options to build you application
Day 91 – Generators in
Python
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.
Day 92 – Function Caching
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
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.
Function caching can have a significant impact on the performance of a program, particularly for
computationally expensive functions. By caching the results of a function, you can avoid having to
recompute the results every time the function is called, which can save a significant amount of time
and computational resources.
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.
Day 93 – Exercise:-10 Solution
News app
#Exercise 10 Use the NewsAPI and the requests module to fetch the daily news related to different
topics. Go to: https://newsapi.org/ and explore the various options to build you application
Day 94 – Exercise:-11 Drink
Water reminder
Exercise 11 - Drink Water Reminder
Write a python program which reminds you of drinking water every hour or two. Your program can
either beep or send desktop notifications for a specific operating system
Day 95 – Regular Expression
Regular Expressions in Python
Regular expressions, or "regex" for short, are a powerful tool for working with strings and text data in
Python. They allow you to match and manipulate strings based on patterns, making it easy to
perform complex string operations with just a few lines of code.
separated by it.
to match.
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
re.search() method either returns None (if the pattern doesn’t match), or a re.MatchObject that
contains information about the matching part of the string. This method stops after the first match,
so this is best suited for testing a regular expression more than extracting data. We can use re.search
method like this to search for a pattern in regular expression:
pattern = r"expression"
# Match the pattern against a string
if match:
print("Match found!")
else:
You can also use the re.findall function to find all occurrences of the pattern in a string:
import re
pattern = r"expression"
print(matches)
Replacing a pattern
import re
pattern = r"[a-z]+at"
print(matches)
The following example shows how to extract information from a string using regular expressions:
import re
pattern = r"\w+@\w+\.\w+"
if match:
email = match.group()
print(email)
# Output: [email protected]
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.
Day 96 – Async IO 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
import asyncio
await asyncio.sleep(1)
print(result)
asyncio.run(main())
L = await asyncio.gather(
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.
Day 97 – Multithreading in
Python
Multithreading in Python
Importing Threading
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():
thread = threading.Thread(target=my_func)
thread.start()
thread.join()
Functions
The following are some of the most commonly used functions in the threading module:
• threading.Thread(target, args): This function creates a new thread that runs the target
function with the specified arguments.
• threading.Lock(): This function creates a lock that can be used to synchronize access to
shared resources between threads.
Creating multiple threads is a common approach to using multithreading in Python. The idea is to
create a pool of worker threads and then assign tasks to them as needed. This allows you to take
advantage of multiple CPU cores and process tasks in parallel.
import threading
def thread_task(task):
if __name__ == '__main__':
threads = []
threads.append(thread)
thread.start()
thread.join()
When working with multithreading in python, locks can be used to synchronize access to shared
resources among multiple threads. A lock is an object that acts as a semaphore, allowing only one
thread at a time to execute a critical section of code. The lock is released when the thread finishes
executing the critical section.
import threading
for i in range(10000):
lock.acquire()
counter += 1
lock.release()
if __name__ == '__main__':
counter = 0
lock = threading.Lock()
threads = []
for i in range(2):
threads.append(thread)
thread.start()
thread.join()
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.
Day 98 – Miltiprocessing in
Python
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
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():
process = multiprocessing.Process(target=my_func)
process.start()
process.join()
Functions
The following are some of the most commonly used functions in the multiprocessing module:
• multiprocessing.Process(target, args): This function creates a new process that runs the
target function with the specified arguments.
• multiprocessing.Lock(): This function creates a lock that can be used to synchronize access to
shared resources between processes.
def process_task(task):
if __name__ == '__main__':
When working with multiple processes, it is often necessary to pass data between them. One way to
do this is by using a queue. A queue is a data structure that allows data to be inserted at one end and
removed from the other end. In the context of multiprocessing, a queue can be used to pass data
between processes.
def producer(queue):
for i in range(10):
queue.put(i)
def consumer(queue):
while True:
item = queue.get()
print(item)
queue = multiprocessing.Queue()
p1 = multiprocessing.Process(target=producer, args=(queue,))
p2 = multiprocessing.Process(target=consumer, args=(queue,))
p1.start()
p2.start()
When working with multiprocessing in python, locks can be used to synchronize access to shared
resources among multiple processes. A lock is an object that acts as a semaphore, allowing only one
process at a time to execute a critical section of code. The lock is released when the process finishes
executing the critical section.
for i in range(10000):
lock.acquire()
counter.value += 1
lock.release()
if __name__ == '__main__':
counter = multiprocessing.Value('i', 0)
lock = multiprocessing.Lock()
p1.start()
p2.start()
p1.join()
p2.join()
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.
Day 99 – Exercise:-11 Solution
Exercise 11 - Drink Water Reminder (Solution)
Write a python program which reminds you of drinking water every hour or two. Your program can
either beep or send desktop notifications for a specific operating system
Day 100 – Where to go
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).
• Tkinter - You can learn Tkinter which is used to create GUIs from here :
• Django - For Django, try the tutorial from the official documentation. Trust me its really good
Overall, the key to mastering Python (or any programming language) is to keep practicing and
experimenting. Set yourself challenges, work on personal projects, and stay curious. Good luck!