Module 1
Module 1
Descriptive Analytics:
Descriptive analytics is all about looking back in time to understand what has happened. It answers the
question, "What happened?" Data analysts use historical data to create reports and summaries that
provide a clear picture of past events and trends.
For example: A data analyst at an e-commerce company might examine past sales data to generate
reports that reveal revenue trends over the last year. This helps the company gain insights into its
historical performance.
1. Predictive Analytics:
Predictive analytics, on the other hand, is all about forecasting the future. It answers the question,
"What will happen?" Data scientists use historical data and various models to make predictions and
forecasts.
For example: A data scientist at a weather forecasting agency may use historical weather data and
models to predict future weather conditions, such as forecasting the likelihood of rain in a specific
location over the next week.
2. Prescriptive Analytics:
Prescriptive analytics goes a step further by providing recommendations on what actions to take. It
answers the question, "What should we do?" This advanced form of analysis guides organizations on
the best actions to achieve specific outcomes.
For example: In healthcare, a data analyst might predict patient readmission risks using a predictive
model. Prescriptive analytics takes it a step further by recommending personalized interventions and
treatment plans to reduce those risks, ultimately improving patient outcomes.
These three types of analytics work in harmony, with descriptive analytics providing historical context,
predictive analytics offering future insights, and prescriptive analytics guiding organizations in making informed
decisions. Together, they enable businesses and organizations to leverage data for improved strategies and
operations.
Data-related roles can be grouped into broader categories based on their primary functions and areas of
expertise. Here's a grouping of data roles:
Data Analysis and Reporting:
Data Analyst: Examines and interprets data to help organizations make informed decisions.
Business Intelligence Analyst: Focuses on transforming data into actionable insights to drive business
strategies.
Market Research Analyst: Collects and analyzes data to provide insights into market trends and
consumer behavior.
Healthcare Data Analyst: Specializes in analyzing healthcare data to improve patient care and
operational efficiency.
Data Science and Machine Learning:
Data Scientist: Develops models and algorithms to extract insights and knowledge from data.
Machine Learning Engineer: Designs and builds machine learning systems and models for predictive
analytics.
AI Engineer: Develops artificial intelligence systems and applications using machine learning and
deep learning techniques.
Statistician: Applies statistical methods to analyze data and draw meaningful conclusions.
1. Python:
Used for: Writing code to analyze, manipulate, and visualize data, as well as building machine learning models
for predictions and automation.
1. SQL (Structured Query Language):
Used for: Querying and managing large datasets in databases, enabling data retrieval, filtering, and aggregation
for analysis and reporting.
1. Excel:
Used for: Organizing, calculating, and conducting basic data analysis, making it a valuable tool for small-scale
data management and visualization.
1. Business Intelligence (BI) Tools:
Used for: Creating interactive, user-friendly dashboards and reports that help businesses and organizations make
informed decisions based on data insights.
1. Statistics:
Used for: Employing mathematical techniques to summarize, interpret, and draw conclusions from data,
allowing for a deeper understanding of underlying trends and patterns.
1. Machine Learning (ML) and Related Libraries:
Used for: Developing and applying algorithms that enable computers to learn from data, recognize patterns, and
make predictions or automated decisions, with applications ranging from image recognition to recommendation
systems.
Python also supports other numeric data types, such as complex numbers, bool for boolean values (True or
False) and decimal for fixed-precision decimal values. Additionally, Python provides a rich set of operators and
functions for performing arithmetic operations and other manipulations on numeric data.
Integers are just whole numbers, positive or negative. For example: 2 and -2 are examples of integers.
Floating point numbers in Python are notable because they have a decimal point in them, or use an exponential
(E) to define the number. For example 2.0 and -2.1 are examples of floating point numbers. 4E2 (4 times 10 to
the power of 2) is also an example of a floating point number in Python.
In computing, floating-point arithmetic is arithmetic using formulaic representation of real numbers as an
approximation to support a trade-off between range and precision. You can always control the number of digits
coming after the decimal, hence they are called floating-point numbers.
Basic Arithmetic:
# Addition= 3
2+1
# Subtraction= -3
2-5
# Multiplication= 4
2*2
# Division= 1.5
3/2
# Exponential= 8
2**3
# Order of Operations followed in Python= 105
2 + 10 * 10 + 3
Arithmetic Precedence:
In Python, the order of operations follows the PEMDAS rule, which is an acronym to help remember the
sequence of operations:
1. P - Parentheses:
o Operations enclosed in parentheses are performed first. Nested parentheses are evaluated from
the innermost level to the outermost.
2. E - Exponents:
o After parentheses, exponentiation is performed next. This includes powers and square roots.
3. M - Multiplication and D - Division:
o These operations are performed next and are of equal precedence. They are executed from left
to right. Division includes true division (/), floor division (//) and Modulo (%) . (You'll
learn about the differences soon enough).
4. A - Addition and S - Subtraction:
o Finally, addition and subtraction are performed, also from left to right. They are of equal
precedence.
Python adheres to this order of operations, which is consistent with the standard mathematical conventions.
Understanding PEMDAS is crucial for writing correct expressions in Python, as it dictates how complex
expressions will be evaluated and in what sequence the operations will occur.
Questions:
An operator working behind the scoreboard of a inter cohort AlmaBetter cricket tournament, is responsible for
updating the scores and points of each team. However, the operator is currently facing a challenge. He has been
tasked with updating the total number of points gained by Team London, but he does not possess the necessary
programming skills to complete this task. According to the tournament's rules, teams are awarded the following
points based on the outcome of a match:
wins: 3 points
draws: 1 point
losses: 0 points
Team London has played 9 matches in this tournament. They won 6 matches, lost 2 matches and drew 1. The
operator is in need of assistance to calculate the total number of points earned by Team London.
london_points = (6*3)+(2*0) + (1*1)
print(london_points)
What is a Variable?
Variables are entities which help us store information and retrieve it later.
A variable with a fixed name can store information of nature like numeric, textual, boolean etc.
A Python variable is a reserved memory location to store values. In other words, a variable in a python
program gives data to the computer for processing.
Questions:
Imagine you are a data analyst at a nutrition bar manufacturing company. Your department head approaches you
with a question. The company produces a nutrition bar that contains 50g of raisins, 60g of almonds, and 20g of
apricots. The head of the manufacturing department wants you to create an ingredient percentage list for the
nutrition bar using python.
# Calculate the percentage of raisins and print the variable
rai_sins=50/(50+60+20)*100
print(rai_sins)
# Calculate the percentage of almonds and print the variable
almonds=60/(50+60+20)*100
print(almonds)
# Calculate the percentage of apricots and print the variable
apricots=20/(50+60+20)*100
print(apricots)
Boolean Variables:
True or False
Comparison Operators:
These operators will allow us to compare variables and output a Boolean value (True or False).
If you have any sort of background in Math, these operators should be very straight forward.
First we'll present a table of the comparison operators and then work through some examples:
In the table below, a=3 and b=4.
Operators Example
== (a==b) is not true
!= (a!=b) is true
> a>b is not true
< a<b is true
>= a>=b is not true
<= a<=b is true
Python comes with Booleans (with predefined True and False displays that are basically just the integers 1 and
0). It also has a placeholder object called None.
# Set object to be a boolean
boolean_variable = False
type(boolean_variable) #bool
#Show
boolean_variable #False
== is a comparison operator, while = is an assignment operator.
History of Python:
Python is a popular programming language that was created in the late 1980s by Guido van Rossum while he
was working at the Centrum Wiskunde & Informatica (CWI) in the Netherlands. 🇳🇱
In 1991, van Rossum released the first version of Python, which was inspired by the ABC language and
designed to be easy to read and write. The name "Python" was inspired by the British comedy group Monty
Python, which van Rossum was a fan of.
Python quickly gained popularity in the scientific and academic communities, as well as among hobbyists and
developers. It was praised for its clean syntax, readability, and ease of use.
Over the years, Python has continued to evolve and improve, with new features and modules being added to the
language. One of the most significant updates was the release of Python 3 in 2008, which introduced several
important changes and improvements, including better Unicode support and a more consistent syntax.
Today, Python is one of the most widely used programming languages in the world, with a thriving community
of developers and users. It is used for everything from web development and data analysis to machine learning
and artificial intelligence.
Python's popularity can be attributed to its simplicity, versatility, and power. It is an accessible language for
beginners, yet powerful enough for advanced users to build complex applications. Python's community and
ecosystem are also strong, with a wealth of libraries, frameworks, and tools available to help developers.
Other Programming Languages similar to Python:
1. Ruby :
Ruby is a dynamic, object-oriented programming language that shares many similarities with Python. Both
languages emphasize simplicity, readability, and developer productivity. Ruby is often used for web
development, and is the primary language behind the popular web framework Ruby on Rails.
2. JavaScript :
JavaScript is a high-level, dynamic programming language that is commonly used for web development. Like
Python, JavaScript is easy to learn and has a simple syntax, and is often used for scripting and automation tasks.
JavaScript is also an interpreted language, meaning that it can be run directly in a web browser without the need
for compilation.
3. Perl :
Perl is a high-level, general-purpose programming language that shares many similarities with Python. Like
Python, Perl is easy to learn and has a simple syntax, and is often used for text processing and system
administration tasks. Perl is known for its powerful regular expression engine and its flexibility, making it ideal
for a wide range of applications.
4. Java :
Java is a general-purpose, object-oriented programming language that is widely used for enterprise
development. While Java has a more complex syntax than Python, it shares many similarities in terms of its
focus on readability, maintainability, and performance. Java is known for its platform independence, which
allows developers to write code once and run it on any platform that supports Java.
5. Julia :
Julia is a high-level, high-performance programming language that is designed for numerical and scientific
computing. Like Python, Julia is easy to learn and has a simple syntax, and is often used for data analysis,
machine learning, and scientific computing. Julia is known for its speed and performance, and is often used for
complex computations that require high-level abstractions and numerical precision.
Each of these programming languages has its own unique features and strengths, but all share a focus on
simplicity, readability, and ease of use. Whether you're building web applications, analyzing data, or working on
large-scale enterprise systems, there's a programming language that's right for your needs.
Python Syntax:
Python is a high-level programming language widely used for web development, data analysis, artificial
intelligence, and other applications. The syntax of Python is simple, readable, and easy to learn.
Syntax is the rule that defines a program's writing and structure.
Some of the critical components of python structure include:
Variables
Keywords
Identifiers
Indentation
Function
Data types → Numbers, String, List, Tuple, Set, Dictionary
Operators → Arithmetic, Relational
Input and Output
Python's syntax is designed to be easy to read and understand, with a simple and consistent structure. Here are
some examples of common elements of Python's syntax and how they are used:
Variables: Variables in Python are used to store data. You can assign a value to a variable using the
assignment operator (=). For example, the following code assigns the value "Hello, World!" to the
variable message:
message = "Hello, World!"
print(message)
# It will print: Hello, World!
Data types: Python has several built-in data types, including integers, floats, strings, and booleans. For
example, the following code assigns an integer, a float, a string, and a boolean value to four different
variables:
x = 5 # integer
y = 3.14 # float
name = "John" # string
is_student = True # Boolean
Operators: Python has several built-in operators, including arithmetic operators (e.g., +, -, *, /, %),
comparison operators (e.g., ==, !=, >, <, >=, <=), and logical operators (e.g., and, or, not). For example,
the following code uses the + operator to add two numbers and the == operator to compare two values:
x = 5
y = 3
z = x + y
print(z) # 8
a = "Hello"
b = "World"
c = a == b
print(c) # False
Identifiers: In Python, an identifier is a name given to a variable, function, class, module, or any other
object. Identifiers are used to refer to these objects in the code. There are some rules and conventions to
follow when naming identifiers in Python:
1. Identifiers can contain letters, numbers, and the underscore (_) character.
2. Identifiers cannot start with a number.
3. Identifiers cannot contain spaces.
4. Python has some reserved keywords that cannot be used as identifiers. (e.g. for, if, else, etc).
5. Python is case-sensitive, so the identifiers x and X are different. It is a good practice to follow the
convention of using lowercase letters for identifiers, with words separated by underscores.
Valid identifier
my_var
myVar
my_var_1
Invalid identifier
1_var - starts with a number
my var - contains a space
for - a reserved keyword
Loops: Python also has several looping structures that can be used to execute a block of code multiple
times. For example, the "for" loop is used to iterate over a sequence of elements. The following code
uses a "for" loop to print all the elements in a list:
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
Modules: Python has a vast library, which is a collection of modules that provides additional
functionality to the programming language. These modules can be imported into the program using the
"import" keyword. For example, the following code imports the "math" module and uses the "sqrt"
function from it to find the square root of a number:
import math
x = 16
result = math.sqrt(x) # 4.0
Control Flow: Python has several control flow statements, including if-else, for loops, and while
loops. For example, the following code uses an if-else statement to check whether a number is greater
than or less than 10:
x = 15
if x > 10:
print("x is greater than 10")
else:
print("x is less than 10")
Functions: Python allows you to define your own functions using the def keyword. Functions take
one or more arguments and return a value. For example, the following code defines a function that
takes two arguments and returns their sum:
def add(x, y):
return x + y
result = add(3, 5)
print(result) # 8
Many built-in functions come with the Python language. These functions can perform various tasks, such as
converting data types, manipulating strings, working with numbers, and more. Some of the most commonly
used built-in functions in Python include print(), type(), len(), str(), etc.
Line Structure:
In Python, the structure of a line of code is relatively simple and consistent. Most lines of code will follow a
similar structure, which can be broken down into the following parts:
Keywords: Python uses certain keywords to indicate different types of statements and expressions. For
example, keywords like "if", "for", "def", and "import" are used to indicate control structures, loops,
function definitions, and module imports, respectively.
Here is a list of some of the most commonly used Python keywords:
and: Logical operator
as: To create an alias
break: To exit a loop
class: To define a class
continue: To continue to the next iteration of a loop
def: To define a function
del : To delete an object
elif : Short for "else if" in a conditional statement
else : To specify an alternative block of code to execute
except : To handle exceptions
False: Boolean value
for: To create a for loop
from: To import specific elements from a module
while: To create a while loop
global: To indicate a global variable
if: To create a conditional statement
import: To import a module
in: To specify a membership test
is : To test object identity
lambda: To create an anonymous function
None: A special value that indicates the absence of a value
not: Logical operator
or: Logical operator
pass: A null statement, used as a placeholder
return: To exit a function and return a value
True: Boolean value
try: To handle exceptions
All the keywords except True, False, and None are in lowercase, and they must be written as it is.
Expressions: Expressions are used to perform operations on variables and values. They can include
mathematical operations, function calls, and variable assignments. For example, the following line of
code assigns the result of the expression "5 + 7" to a variable "x":
x = 5 + 7
Operators: Operators are used to performing operations on variables and values. They include
mathematical operators like "+", "-", "*", and "/", as well as comparison operators like "==", "!=", ">",
and "<".
For example, the following line of code compares two variables "x" and "y" and assigns the result to a
variable "result":
result = x > y
Separators: Separators are used to separate different parts of a line of code. They include punctuation
marks like commas and colons, as well as whitespace characters like spaces and tabs. For example, the
following line of code uses a comma to separate two arguments passed to the "print()" function:
print("Hello,", "world!")
Comments: Comments are used to provide explanations or documentation for the code. They are
ignored by the interpreter and are indicated by a "#" symbol at the beginning of the line. For example,
the following line of code is a comment:
# This is a comment
Overall, the structure of a line of code in Python is relatively simple and consistent. Most lines of code will
include a combination of keywords, expressions, operators, separators, and comments, depending on the type of
statement or expression being used.
Input/Output Structure:
In Python, some several built-in functions and methods can be used to handle input and output (I/O) operations.
Here are some examples of how to use the most common I/O structures in Python:
Input: The input() function reads input from the user. This function reads a line of text from the
user and returns it as a string. For example, the following code prompts the user to enter their name and
assigns the value to a variable "name":
name = input("What's your name? ")
Output: The print() function displays output to the user. This function takes one or more
arguments and displays them to the standard output (usually the console). For example, the following
code prints a string "Hello, world!" to the console:
print("Hello, world!")
File input/output: Python also provides functions and methods for reading from and writing to files.
The open() function is used to open a file, and the read() and write() methods are used to read
from and write to the file. For example, the following code opens a file "example.txt", reads the
contents of the file and assigns it to a variable "content", and then closes the file.
file = open("example.txt", "r")
content = file.read()
file.close()
String formatting: The format() method can insert values into a string. This method is used to
insert values into placeholders in a string, which are indicated by curly braces {}. For example, the
following code creates a string "Hello, {}!" with a placeholder and then uses the format method to
insert a value into the placeholder:
greeting = "Hello, {}!"
name = "John"
print(greeting.format(name))
Integer input/output: To read an integer input from the user, you can use the input() function and
then convert the result to an integer using the int() function. For example:
age = int(input("What's your age? "))
print("Your age is:", age)
Floating-point input/output: To read a floating-point input from the user, you can use
the input() function and then convert the result to a float using the float() function. For
example:
height = float(input("What's your height? "))
print("Your height is:", height)
List input/output: To read a list input from the user, you can use the input() function and then
convert the result to a list using the list() function. For example:
colors = list(input("What are your favorite colors? "))
print("Your favorite colors are:", colors)
Boolean input/output: To read a boolean input from the user, you can use the input() function and
then convert the result to a boolean using the bool() function. For example:
is_student = bool(input("Are you a student? "))
print("You are a student:", is_student)
JSON input/output: To read or write JSON data, you can use the json module. For example, the
following code writes a dictionary to a json file "example.json":
import json
data = {"name": "John", "age": 30}
with open("example.json", "w") as file:
json.dump(data, file)
Data types are basically labels that we use to categorize different types of information in our code. Python is a
dynamic language, which means that it can figure out the data type of a value on its own, based on what it looks
like.
f(x)=x^2+3x-4
Find the value of f(x) at x =2 , x=-1, and x=1
x=2
func_evaluated_at_2 = (x**2)+(3*x)-4
x=-1
func_evaluated_at_minus1 = (x**2)+(3*x)-4
x=1
func_evaluated_at_1 = (x**2)+(3*x)-4
#Check if func_evaluated_at_1 >= func_evaluated_at_minus1
func_evaluated_at_1 >= func_evaluated_at_minus1
Adhering to naming conventions for variables is important in Python as it helps improve code readability and
maintainability. Python follows some standard guidelines for naming variables.
Variable Names: Variable names should be descriptive and indicative of their purpose in the code. They should
be meaningful and reflect the data they store. Avoid using generic names like "a," "x," or "temp" unless they
serve a very specific purpose.
Case Sensitivity: Python is case-sensitive, meaning that variable names like "myVariable" and "myvariable" are
treated as two different variables. It's essential to use consistent casing for your variable names.
Snake Case: The recommended convention for naming variables is to use snake_case, where words are
separated by underscores. This makes the variable name more readable.
eg: snake_case_variable
Avoid Reserved Words: Do not use Python's reserved words (keywords) as variable names, as they have
specific meanings in the language. For example, you shouldn't use words like "print," "if," "while," "for," and so
on as variable names.
To create a string in Python you need to use either single quotes or double quotes. For example:
# Single word
my_first_string= ' Hello World !!! '
my_first_string
type(my_first_string) #str
print(my_first_string *2) #Hello World !!! Hello World!!!
# We can also use double quote
my_string = "String built with double quotes"
print(my_string) # Use the print command
type(my_string)
# Multiline String
print('''
Alok :Hi I am Alok.I will be your instructor for the first module
Anfal: Thank you
''')
Immutability:
message = "Hey muddy, how are you doing, man?"
# Oops, I made a typo! Meant buddy instead of muddy
message[4] = 'b' #this is called slicing. You'll learn more about it in
upcoming sessions
# message[1]
print(message) #error
#.replace hasn't corrected the string yet, you have to reassign the
variable.
# print(message)
message_1 = message.replace('muddy','buddy')
print(message) #Hey muddy, how are you doing, man?
# Data type from String to int Conversion or vice versa
string_int = '25.0'
string_to_int = float(string_int)
print(string_to_int)
type(string_to_int)
25.0
float
strings are immutable in Python, which means that once you create a string, you can't change it.
Program:
write a program that finds the number of occurance of letter 'e' .
# Store the user input in a variable
books = "Python for Everyone, Learn Python the Hard Way, Python Crash
Course , Starting Out with Python, Automate the Boring Stuff with Python"
# Store the count of books containing e in the title.
x_count = books.count('e')
print(x_count) #7
'a'*2 #aa
# Fill in the blanks
print("The total number of 'e's in the list of books is " + str(x_count))
#but this code would miss out on 'E's. So it might be a good idea to
convert the whole string to lower and then look for the 'e's
e_counts = books.lower().count('e')
print("The total number of 'e's in the list of books is " + str(e_counts))
The total number of 'e's in the list of books is 8
sample_string = "This is Alok hEre"
sample_string.count('e') #1
sample_string.lower().count('e') #2
Alex wants to convert a string representation of a number, "25", into an integer so that he can perform
mathematical operations with it. He wrote the following code:
num_str = "25"
num_int = int(num_str)
result = num_int + 5
print(result)
List:
we use lists and arrays to store collections of data, such as a list of names or a list of numbers. Arrays are similar
to lists, but they are more suited to working with large amounts of numerical data. Lists are constructed with
brackets [] and commas separating every element in the list.
# Assign a list to an variable named my_list
my_list = [1,2,3,4]
type(my_list) #list
In Python, lists are mutable, which means that you can modify them after you've created them.
# create a list
my_list = [1, 2, 3, 4, 5]
# modify the list
my_list[0] = 10
# print out the modified list
print(my_list)
Program: The teacher wants to calculate the mean score to assess the overall performance of the class.
marks = [87, 76, 95, 68, 80, 83, 92, 74, 79, 89]
# Calculate the mean of the marks. Use list functions.
mean_marks = sum(marks)/len(marks)
print(mean_marks)
Tuples:
Tuples are immutable, which means that you can't modify them after they've been created.
For example, if you have a set of data that you know won't change, you can store it in a tuple to make sure that it
stays the same. This can be particularly important if you're working on a large project with many different
pieces of code, because it helps to ensure that your data stays consistent throughout. The construction of a tuples
use () with elements separated by commas.
# Create a tuple
my_tuple = (1,2,3)
another_tuple = ('one',2, 4.53, 'asbc')
my_tuple[0] #1
my_tuple[0] = 'change' #error
# There is a way to change it , convert to list, change and then convert to
tuple
my_tuple_list = list(my_tuple)
my_tuple_list[0] = 'change'
my_tuple = tuple(my_tuple_list)
print(my_tuple) #('change', 2, 3)
Dictionaries:
They allow you to store key-value pairs, which can be used to represent complex data structures in a simple and
efficient way.
One of the key benefits of dictionaries is that they make it easy to look up values based on a key. This can be
particularly useful when you're working with large sets of data and need to find specific pieces of information
quickly. For example, imagine you're working on a project that involves storing information about a large
number of customers. You could use a dictionary to store each customer's information as a set of key-value
pairs, with the customer ID as the key and their information as the value.
A dictionary object is constructed using curly braces {key1:value1,key2:value2,key3:value3}
In Python, dictionaries are mutable, which means that you can modify their contents after they've been created.
This makes them a very flexible and powerful data structure for working with complex data.
When you modify a dictionary, you can add, remove, or update key-value pairs as needed. For example, you
might add a new key-value pair to represent a new piece of data, or update an existing key-value pair to reflect a
change in the data. You can also remove key-value pairs that are no longer needed.
customer = {
"id": 1234,
"name": "John Smith",
"email": "[email protected]"}
# Update the customer's email address
customer["email"] = "[email protected]"
# Add a new key-value pair
customer["phone"] = "555-555-1212"
# Remove the customer's ID
del customer["id"]
print(customer)
{'name': 'John Smith', 'email': '[email protected]', 'phone': '555-
555-1212'}
Basic Dictionary Methods:
keys() method returns the list of keys in the dictionary object
values() method returns the list of values in the dictionary object
items()Displays elements in a dictionary
marvel_dict.keys()
dict_keys(['Name', 'Place', 'Weapon', 1, 3, 'alibies', 'abc'])
list(marvel_dict.keys())
['Name', 'Place', 'Weapon', 1, 3, 'alibies', 'abc']
list(marvel_dict.values())
['Thor',
'Asgard',
'Hammer',
2,
'power',
['Ironman', 'Captain America'],
{1: 2, 4: 5}]
marvel_dict.items()
dict_items([('Name', 'Thor'), ('Place', 'Asgard'), ('Weapon', 'Hammer'), (1, 2), (3, 'power'), ('alibies', ['Ironman',
'Captain America']), ('abc', {1: 2, 4: 5})])
marvel_dict['abc'][1] #2
Sets:
In Python, sets are a powerful tool for working with collections of unique elements. They allow you to perform
operations like union, intersection, and difference on sets of data, making it easy to compare and manipulate
large data sets.
One of the key benefits of sets is that they ensure that each element is unique, so you don't have to worry about
duplicates. This can be particularly useful when you're working with data that has a lot of overlap or
redundancy. For example, imagine you're analyzing a large dataset of customer orders, and you want to identify
all of the unique products that have been ordered. By storing the product names in a set, you can ensure that
each product is only counted once, even if it appears in multiple orders.
Sets are an unordered collection of unique elements. We can construct them by using
the set() function.
Sets cannot have duplicates.
Sets are mutable just like lists.
You can create a non-empty set with curly braces by specifying elements separated by a comma.
# Create an empty set
empty_set = set()
type(empty_set) #set
# Create a non-empty set within curly braces
non_empty_set = {1,6,4,'abc'}
# Mutability in set
non_empty_set = non_empty_set | {1,7}
print(non_empty_set) # {1, 4, 6, 7, 'abc'}
An empty set cannot be represented as {}, which is reserved for an empty dictionary
my_object = {}
type(my_object) #dict
my_set = set()
type(my_set) #set
We can cast a list with multiple repeat elements to a set to get the unique elements.
# Create a list with repeats
my_list = [1,1,2,2,3,4,5,6,1,1]
# Cast as set to get unique values
my_set = set(my_list)
my_set # {1, 2, 3, 4, 5, 6}
In Python, data types can be broadly categorized into two groups: ordered and unordered data types. These
categories define how the elements in the data type are stored and accessed.
Ordered Data Types:
Ordered data types maintain the sequence or order of elements. You can access elements by their position, and
they are indexed with integers, starting from 0.
String (str): A string is a sequence of characters, and each character has a specific position within the string.
You can access individual characters or substrings by their index.
text = "Hello, Python!"
print(text[0]) # Output: 'H'
print(text[7:13]) # Output: 'Python'
List (list): Lists are ordered collections of items. You can access list elements by their index, and they maintain
the order in which items were added.
fruits = ['apple', 'banana', 'cherry']
print(fruits[1]) # Output: 'banana'
fruits = ['apple', 'banana', 'cherry']
fruits1= ['apple', 'cherry','banana'] #False
fruits==fruits1 #Using comparison operator to check if two variables are
equal.
Tuple (tuple): Tuples are similar to lists, but remember they are immutable, meaning their elements cannot be
changed after creation. They also maintain order.
coordinates = (3, 4)
print(coordinates[0]) # Output: 3
Set (set): A set is an unordered collection of unique elements. Sets are commonly used for membership testing
or eliminating duplicates.
colors = {"red", "green", "blue"}
colors[0] #Would throw you an error
Dictionary (dict): Dictionaries as you know are collections of key-value pairs. They are not ordered, but you
access values by their associated keys.
person = {"name": "John", "age": 30}
print(person["name"]) # Output: 'John'
Indexing & Slicing
In Python, slicing and indexing are fundamental techniques that enable you to access specific elements within a
sequence, including strings, lists, tuples and more.
Indexing helps retrieve individual elements from a sequence by their position, while slicing enables you to
extract a range of elements from a sequence.
Slicing is also commonly used in data analysis and visualization. For example, if you have a large dataset of
customer information, you can use slicing to extract a specific subset of the data based on certain criteria. This
can help you identify patterns and trends in the data more quickly.
In Python, indexing starts at 0, which means the first element in a sequence has an index of 0, the second
has an index of 1, and so on.
Indexing:
Strings are a type of sequence in Python, which means that they can be indexed using the square bracket []
notation.
my_string = "Hello, world!"
print(my_string[0]) # Output: "H"
print(my_string[-1]) # Output: "!"
Tuples, similar to strings, can be indexed using the square bracket [] notation.
my_tuple = (1, 2, 3, 4, 5)
print(my_tuple[2]) # Output: 3
print(my_tuple[-1]) # Output: 5
Lists are another type of sequence in Python, similar to tuples and strings, that can be indexed using the square
bracket [] notation.
my_list = [1, 2, 3, 4, 5]
print(my_list[2]) # Output: 3
print(my_list[-1]) # Output: 5
Sets are an unordered collection of unique elements in Python, and they do not support indexing.
my_set = {1, 2, 3, 4, 5}
print(my_set[2]) #error
Dictionaries are a collection of key-value pairs in Python, and they can be indexed using the keys.
my_dict = {"name": "John", "age": 30, "city": "New York"}
print(my_dict["name"]) # Output: "John"
print(my_dict["city"]) # Output: "New York"
Consider the following list of iconic marvel movie characters. Create two teams of superheroes based on their
index position: one team should consist of all the characters located at even index positions, while the other
team should consist of all the characters located at odd index positions.
#Here's the list
marvel_words = ['Avengers', 'X-Men', 'Spider-Man', 'Iron Man', 'Hulk',
'Thor', 'Black Widow', 'Captain America', 'Wolverine', 'Doctor
Strange','Namor']
team1=[marvel_words[0],marvel_words[2],marvel_words[4],marvel_words[6],marv
el_words[8],marvel_words[10]] #team odd
team2=[marvel_words[1],marvel_words[3],marvel_words[5],marvel_words[7],marv
el_words[9]] #team even
print(team1)
print(team2)
#Reverse the string- Namor
new_word=marvel_words[-1]
namor_reverse=new_word[::-1] #This step might be confusing for you right
now. Worry not. We'll explore this technique in a minute.
print(namor_reverse)
Slicing:
Slicing is another common operation in Python that allows us to extract a portion of a sequence, such as a string,
tuple, or list. Different types of data structures have different slicing methods, but the general syntax is similar
for all of them.
The basic syntax for slicing with a step size is as follows:
sequence[start:stop:step]
Here's what each part means:
start: The index from which the slicing begins (inclusive).
stop: The index at which the slicing ends (exclusive).
step: The number of elements to skip between each included element.
We can use the slice notation [start:end] to extract a portion of the string.
my_tuple = (1, 2, 3, 4, 5)
print(my_tuple[1:3]) # Output: (2, 3)
print(my_tuple[:2]) # Output: (1, 2)
my_list = [1, 2, 3, 4, 5]
print(my_list[2:]) # Output: [3, 4, 5]
print(my_list[:3]) # Output: [1, 2, 3]
print(my_list[1:4:2]) # Output: [2, 4]
Sets are an unordered collection of unique elements in Python, and they do not support slicing, since they don't
support indexing.
my_set = {1, 2, 3, 4, 5}
print(my_set[1:3]) # Error: 'set' object is not subscriptable
Dictionaries are a collection of key-value pairs in Python, and we can slice a dictionary using a list of keys.
However, unlike lists or tuples, slicing with dictionaries is not done using the : operator.
Instead, you can use the dict() constructor to create a new dictionary from a slice of an existing dictionary.
Indexing in a dictionary is done using the keys. You can access the value associated with a particular key by
using the square bracket notation with the key inside the brackets.
my_dict = {'a': 1, 'b': 2, 'c': 3}
value_a = my_dict['a'] # returns 1
value_a
Slicing a dictionary is not possible since dictionaries are unordered and do not support slicing. However, you
can get a subset of a dictionary by creating a new dictionary with only the desired keys. You can use the dict()
constructor and a list comprehension to achieve this. For example:
my_dict = {'a': 1, 'b': 2, 'c': 3}
subset_dict = dict((key, my_dict[key]) for key in ['a', 'c']) #This is an
advanced technique which you'll explore later. Don't worry if you don't
understand this yet.
# returns {'a': 1, 'c': 3}
subset_dict
In Python, Operators are like special symbols that you can use to perform different actions on your data. There
are so many types of operators available, including arithmetic, comparison, logical, assignment, and bitwise
operators. Each type has its own unique set of skills that can help you manipulate data in all sorts of ways.
Arithmetic operators:
Assignment operators =
Comparison operators: == != < > <= >=
1. Arithmetic Operators:
These are used for performing arithmetic operations on numerical values, such as addition, subtraction,
multiplication, division, and more.
Examples:
Addition (+): 2 + 3 = 5
Subtraction (-): 5 - 2 = 3
Multiplication (*): 2 * 3 = 6
Division (/): 6 / 3 = 2
x = 10
y = 3
print(x + y)
print(x - y)
print(x * y)
print(x / y)
2.Comparison Operators:
x = 5
y = 10
print(x == y) #False
print(x != y) #True
print(x > y) #False
print(x < y) #True
print(x >= y) #False
print(x <= y) #True
3. Logical Operators:
Boolean values (True or False) can be combined and manipulated using logical operators in Python.
Python has three logical operators:
AND: Returns True if both conditions are true, otherwise returns False.
OR: Returns True if at least one condition is true, otherwise returns False.
NOT: Returns the opposite of the condition, i.e., True if the condition is false and False if the condition is true.
Logical operators are useful in controlling the flow of execution based on multiple conditions in conditional
statements and loops. They are also a fundamental concept in Boolean algebra, which forms the basis of digital
electronics and computer science.
x = 5
y = 10
z = 5
print((x < y) and (x == z)) #True
print((x > y) or (x == z)) #True
print(not(x == z)) #False
Order of Precedence:
The conditional statements have a specific order of priority, also known as the "order of precedence," which
determines how they are executed when multiple conditions are present. The order of priority for conditional
statements in Python is as follows:
1. Parentheses (Grouping):
Parentheses () are used to group expressions, and they have the highest priority. When used within
conditional statements, they allow you to control the order of evaluation. Expressions inside
parentheses are evaluated first.
2. Comparison Operators:
Comparison operators like == (equal), != (not equal), < (less than), > (greater than), <= (less than or
equal to), and >= (greater than or equal to) are evaluated next. They are used to compare values and
return Boolean results (True or False).
3. Logical NOT (not):
The not operator is used to negate a Boolean value. It has higher precedence than other logical
operators. For example, not True is False.
4. Logical AND (and):
The and operator is used to combine two or more conditions. It returns True if all conditions are True.
It has lower precedence than the not operator.
5. Logical OR (or):
The or operator is used to combine two or more conditions. It returns True if at least one condition is
True. It has lower precedence than the and operator.
6. Ternary Conditional Operator (if-else):
The if-else conditional expression (also known as the ternary operator) has lower precedence than the
logical operators. It allows you to evaluate an expression based on a condition and return one of two
values.
7. Conditional Statements (if, elif, and else):
The if, elif (else if), and else statements are used for controlling the flow of your code based on
conditional expressions. They are executed sequentially from top to bottom, and each condition is
checked in the order they appear.
The order of priority is important when combining multiple conditions in a single statement, as it affects the
order in which conditions are evaluated. To override the default order of precedence, you can use parentheses to
explicitly specify the order in which conditions should be evaluated.
x = 10
y = 6
result = x > 5 or y < 10 and y == 5
result #True
True or True and False
1. In this expression, the and operator has higher precedence than the or operator. So, True and False is
evaluated first.
2. True and False results in False because both operands must be True for the and operation to yield True.
3. The expression now becomes True or False.
4. The or operator is evaluated, and it returns True because at least one of its operands is True.
4. Assignment Operators:
These are used for assigning values to variables.
Assignment operators in Python are used to assign values to variables. They combine the assignment operator
(=) with one of the arithmetic or bitwise operators to perform an operation and then assign the result to the
variable on the left-hand side. Here are some examples:
#Simple assignment (=): Assigns the value on the right-hand side to the
variable on the left-hand side.
x = 5
print(x)
#Addition assignment (+=): Adds the value on the right-hand side to the
variable on the left-hand side
#and assigns the result to the variable on the left-hand side.
x = 5
x += 3 # Equivalent to x = x + 3
print(x)
#Subtraction assignment (-=): Subtracts the value on the right-hand side
from the variable on the
#left-hand side and assigns the result to the variable on the left-hand
side.
x = 5
x -= 3 # Equivalent to x = x - 3
print(x)
#Multiplication assignment (*=): Multiplies the value on the right-hand
side with the variable on
# the left-hand side and assigns the result to the variable on the left-
hand side.
x = 5
x *= 3 # Equivalent to x = x * 3
print(x)
#Division assignment (/=): Divides the variable on the left-hand side by
the value on the right-hand
# side and assigns the result to the variable on the left-hand side.
x = 5
x /= 3 # Equivalent to x = x / 3
print(x)
#Modulus assignment (%=): Calculates the modulus of the variable on the
left-hand side with the value on the
#right-hand side and assigns the result to the variable on the left-hand
side.
x = 5
x %= 3 # Equivalent to x = x % 3
print(x)
#Floor division assignment (//=): Performs floor division of the variable
on the left-hand side by the value on the right-hand
# side and assigns the result to the variable on the left-hand side.
x = 5
x **= 3 # Equivalent to x = x ** 3
print(x)
5.Membership operators:
The membership operators in Python are "in" and "not in". These operators are used to test if a value is a
member of a sequence, such as a string, list, or tuple.
Here's an example: Imagine you have a string called "sentence" that contains a sentence. You can use the "in"
operator to check if a particular word is present in the sentence.
sentence = "The quick brown fox jumps over the lazy dog"
print("fox" in sentence) # True
print("cat" in sentence) # False
sentence = "The quick brown fox jumps over the lazy dog"
print("cat" not in sentence) # True
print("fox" not in sentence) # False
Program: Find out how many of your books contain the word "Python" in them.
books = [
"Python for Data Science Handbook by Jake VanderPlas",
"The Pragmatic Programmer by Andrew Hunt and David Thomas",
"Python Machine Learning by Sebastian Raschka",
"The Alchemist by Paulo Coelho",]
count=0
"Python" in books[0] # Change x to 0,1,2 and 3.
#If True, increase the count variable by 1.
count=count+1
print(count)
Lists:
Using the + operator to concatenate two lists
list1 = [1,2,3]
list2 = [4,5,6]
result = list1 + list2
print(result) #[1, 2, 3, 4, 5, 6]
Using the * operator to repeat a list
list1 = [1, 2, 3]
result = list1 * 3
print(result) #[1, 2, 3, 1, 2, 3, 1, 2, 3]
Strings:
use the + operator to concatenate two strings, or use the * operator to repeat a string a certain number of times.
# concatenation
string1 = "Hello"
string2 = "world"
result = string1 + " " + string2
print(result) # Output: "Hello world"
# repetition
string = "spam"
result = string * 3
print(result) # Output: "spamspamspam"
You can also use the in and not in operators to check if a substring exists in a larger string. These operators
return a Boolean value True or False.
# checking if a substring exists in a string
string = "Hello world"
print("world" in string) # Output: True
print("Python" in string) # Output: False
Tuples:
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
result = tuple1 + tuple2
print(result) #(1, 2, 3, 4, 5, 6)
tuple3=tuple1*2
print(tuple3) #(1, 2, 3, 1, 2, 3)
Dictionary:
Removing elements: Use the del keyword with the key to remove an element from the dictionary.
my_dict = {"apple": 2, "banana": 3, "cherry": 4}
del my_dict["banana"]
print(my_dict) # Output: {"apple": 2, "cherry": 4}
Checking for key existence: Use the in keyword to check if a key exists in the dictionary.
my_dict = {"apple": 2, "banana": 3, "cherry": 4}
print("apple" in my_dict) # Output: True
print("orange" in my_dict) # Output: False
Copying a dictionary: Use the copy() method to create a shallow copy of the dictionary.
my_dict = {"apple": 2, "banana": 3, "cherry": 4}
new_dict = my_dict.copy()
print(new_dict) # Output: {"apple": 2, "banana": 3, "cherry": 4}
Clearing a dictionary: Use the clear() method to remove all elements from the dictionary.
my_dict = {"apple": 2, "banana": 3, "cherry": 4}
my_dict.clear()
print(my_dict) # Output: {}
Sets:
Sets in Python are unordered collection of unique elements.
Sets have their own set of methods and operators. The most common operators used with sets include:
Union operator (|), returns a new set with all the elements from both sets
Intersection operator (&), returns a new set with only the common elements between both sets
Difference operator (-), returns a new set with only the elements from the first set that are not in the
second set
and many more...
set_a = {1, 2, 3}
set_b = {2, 3, 4}
# # union operator
# print(set_a | set_b) # {1, 2, 3, 4}
# # intersection operator
# print(set_a & set_b) # {2, 3}
# # difference operator
# print(set_a - set_b) # {1}
print((set_a | set_b) - (set_a & set_b))
Identity operators:
Identity operators in Python are used to compare the memory addresses of two objects to check if they refer to
the same object. These operators evaluate to True or False based on whether the two objects are the same or not.
There are two identity operators in Python:
is : Returns True if the two objects are the same, i.e., they have the same memory address.
is not : Returns True if the two objects are not the same, i.e., they have different memory addresses.
Identity operators are often used in Python to compare objects for equality. Since Python objects are created
dynamically and stored in memory, identity operators provide a way to compare objects based on their
memory address rather than their value. This is particularly useful when working with mutable objects, such
as lists and dictionaries, where two objects may have the same value but different memory addresses.
A = [1, 2, 3]
B = [1, 2, 3]
print(A is B) # False
print(A == B) # True since '==' compares value.
a = {"Alok","Anand"}
b = {"AlmaBetter","Instructor"}
a = b
print(a is b)
print(a)
print(b)
True
{'AlmaBetter', 'Instructor'}
{'AlmaBetter', 'Instructor'}
b.add("Head Instructor")
print(a)
print(b)
{'AlmaBetter', 'Instructor', 'Head Instructor'}
{'AlmaBetter', 'Instructor', 'Head Instructor'}
Bitwise Operators:
Bitwise operators are used to perform operations at the bit-level of binary numbers. They manipulate bits in a
number, changing their values to produce a result.
Types of Bitwise Operators
Python provides the following bitwise operators:
& - Bitwise AND
| - Bitwise OR
^ - Bitwise XOR
~ - Bitwise NOT
< < - Bitwise Left Shift
.>> - Bitwise Right Shift
a = 60 # 60 = 0011 1100
b = 13 # 13 = 0000 1101
# Bitwise AND
c = a & b # 12 = 0000 1100
print(c)
# Bitwise OR
c = a | b # 61 = 0011 1101
print(c)
# Bitwise XOR
c = a ^ b # 49 = 0011 0001
print(c)
# Bitwise NOT
c = ~a # -61 = 1100 0011
print(c)
# Bitwise Left Shift
c = a << 2 # 240 = 1111 0000
print(c)
# Bitwise Right Shift
c = a >> 2 # 15 = 0000 1111
print(c)
The input() function always returns a string, even if the user enters a number. If you need to convert the user
input into a different data type (such as an integer or a float), you can use the appropriate conversion function
(int(), float(), etc.) to convert it.
age_str = input("Enter your age: ")
age = int(age_str)
print("You will be " + str(age + 1) + " next year.")
Enter your age: 30
You will be 31 next year.
CRUD:
CRUD stands for Create, Read, Update, and Delete. It's a common paradigm used in software development to
describe the basic operations that can be performed on data. In Python, we can use functions and methods to
implement these CRUD operations on different data structures.
1.Create:
In Python, we can create new objects or data structures using functions such as list(), dict(), set(), tuple(), str(),
and int().
# Create a new list object
my_list = list([1, 2, 3])
print("my_list -", my_list) # Output: my_list - [1, 2, 3]
# Create a new dictionary object
my_dict = dict({'name': 'John', 'age': 30})
print("my_dict -", my_dict) # Output: my_dict - {'name': 'John', 'age':
30}
# Create a new set object
my_set = set(['apple', 'banana', 'cherry', 'apple'])
print("my_set -", my_set) # Output: my_set - {'apple', 'banana', 'cherry'}
# Create a new tuple object
my_tuple = tuple((1, 2, 3))
print("my_tuple -", my_tuple) # Output: my_tuple - (1, 2, 3)
# Create a new string object
my_string = str('Hello, world!')
print("my_string -", my_string) # Output: my_string - Hello, world!
# Create a new integer object
my_int = int(42)
print("my_int -", my_int) # Output: my_int – 42
2. Read:
We can use functions and methods to read or retrieve data from objects or data structures in Python.
# Retrieving
the length
of a list
my_list = [1, 2, 3, 4, 5]
print("Length of my_list:", len(my_list)) #5
# dict.keys()
print("Keys in the dictionary- ",list(my_dict.keys())) # output:
dict_keys(['apple', 'banana', 'orange'])
# dict.values()
print("Values in the dictionary- ",list(my_dict.values())) # output:
dict_values([2, 3, 4])
# dict.items()
print("Dictionary items- ",list(my_dict.items())) # output:
dict_items([('apple', 2), ('banana', 3), ('orange', 4)])
# dict.get(key, default)
print("Fetching value corresponding to 'apple'- ",my_dict.get("apple", 0))
# output: 2
print("Fetching value corresponding to 'grape' (non existent)-
",my_dict.get("grape", 0)) # output: 0
Note that in the dict.keys(), dict.values(), and dict.items() functions, the output is a special dictionary object
(e.g., dict_keys, dict_values, and dict_items). You can convert these to a regular list by wrapping them in a list()
function, as we did in the example.
3.Update:
We can use functions and methods to update or modify existing objects or data structures in Python.
# 1. sorted() - Sorts a list object in ascending order
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
sorted_list = sorted(my_list)
print("Original list:", my_list)
print("Sorted list:", sorted_list)
Original list: [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
Sorted list: [1, 1, 2, 3, 3, 4, 5, 5, 6, 9]
4.Delete:
We can use functions and methods to delete or remove objects or data structures in Python.
my_set={1,2,3,4}
my_set.clear()
print(my_set) #set()
Strings:
string.upper(): returns a copy of the string with all characters in upper case
string.lower(): returns a copy of the string with all characters in lower case
string.title(): returns a copy of the string with the first character of each word in title case (i.e. upper
case)
string.replace(old, new): returns a copy of the string with all occurrences of old replaced with new
string.split(separator): returns a list of substrings separated by the specified separator
string.join(iterable): returns a string that is the concatenation of the elements in the specified iterable,
separated by the string string
string.isnumeric(): returns True if all characters in the string are numeric, otherwise False
# Sample string
string = "alma better"
print("Original String ",string)
What is Unicode?
Unicode is a standard that assigns a unique number to every character, symbol, and emoji in every language and
writing system in the world. This makes it possible for computers to store, process, and communicate text in any
language or script, including emojis.
To find the Unicode of a character in Python, you can use the ord('character') method. And to generate a
character corresponding to a Unicode, you can use the chr('Unicode') method. You need not worry about these
now.
So in the case of "bear" and "Bear," the lowercase "b" has a higher Unicode value than the uppercase "B," which
is why "bear" is considered to be greater than "Bear" when comparing strings in Python.
animals=['Bear','bear']
print(max(animals)) #bear
print("Unicode for 'b'- ",ord('b')) #98
print("Unicode for 'B'- ",ord('B')) #66
Program:
statement= "arnav is writing a book titled 'python made easy'. His book is
expected to release in March"
1. Create a list containing the two sentences in the statement.
sentence_list=statement.split('.')
print(sentence_list)
["arnav is writing a book titled 'python made easy'", ' His book is
expected to release in March']
2. The name 'arnav' is spelled wrong. Replace it with 'Arnav'.
statement=statement.replace('arnav','Arnav')
print(statement)
Arnav is writing a book titled 'Python Made Easy'. His book is expected to
release in March
3. The title of the book is not written in the correct cases as well. Make corrections there.
statement=statement.replace('python made easy','python made easy'.title())
print(statement)
Arnav is writing a book titled 'Python Made Easy'. His book is expected to
release in March
4. Reschedule the release of the book to month of your choice. Take input of month from the user and repalce it
with "March" in the statement.
reschedule_month=input("Which month would you like to reschedule the launch
to? ")
statement=statement.replace("March",reschedule_month)
print(statement)
Which month would you like to reschedule the launch to? Aril
Arnav is writing a book titled 'Python Made Easy'. His book is expected to
release in April
Lists:
list.insert(index, item): inserts an item at a specific index in the list
list.reverse(): reverses the order of the items in the list
list.copy(): returns a copy of the list
# create a list
my_list = [4, 2, 8, 1, 6, 5]
my_list.reverse()
print("Reversed list:", my_list,'\n')
new_list = my_list.copy()
print("New copied list:", new_list,'\n')
Program: Finally, you want to be able to count how many movies you have in your collection and reverse the
order of the list.
# Start with an empty list
movie_collection = []
# Add some movies to the collection using the append() method
movie_collection.append("The Godfather")
movie_collection.append("The Shawshank Redemption")
movie_collection.append("The Dark Knight")
movie_collection.append("Pulp Fiction")
movie_collection.append("Goodfellas")
# Count how many movies are in the collection using the count() method
num_movies = len(movie_collection)
print("Number of The Godfather movies:", num_movies)
# Create a set
fruits = {"apple", "banana", "cherry"}
#Adding another fruit to the set
Program: A store sells different types of fruits in baskets. The storekeeper keeps track of the availability of
each fruit type in separate sets. The storekeeper wants to know which fruits are available in both baskets, which
fruits are unique to each basket, and the total number of fruits available.
# Define sets for fruits in each basket
basket1 = {'apple', 'banana', 'grape', 'orange'}
basket2 = {'banana', 'mango', 'pineapple', 'orange'}
Conditional statements are programming that allow a program to make based on certain conditions. These
statements enable the program to execute different depending on whether a particular condition is true or false.
In programming, conditional statements typically take the form of "if-then" statements, where the "if" part
specifies the condition, and the "then" part specifies what action the program should take if the condition is true.
There are also "if-then-else" statements that provide an alternative action to take if the condition is false.
Program: This conditional statement in Python checks whether the temperature is less than 90 degrees
Fahrenheit. If it's true, Jack will go to the park, and if it's false, he will stay inside and play video games.
temperature = 85
if temperature < 90:
print("Let's go to the park!")
else:
print("Let's stay inside and play video games.")
Indentation:
In Python, indentation is used to determine the grouping of code blocks. It is a way of visually indicating which
statements are part of a particular code block, such as a function, loop, or conditional statement.
Indentation is done using spaces or tabs, but it is important to be consistent in the style used throughout the
code. Typically, four spaces are used for each level of indentation.
Indentation is a fundamental part of Python's syntax, and it is important to use it correctly in order to ensure that
the code is readable and functions properly.
An "if" statement allows us to check a single condition and execute a block of code only if that condition is
true. An "else" statement allows us to execute a block of code if the condition in the "if" statement is false.
age = int(input())
if age >= 18:
print("You are an adult")
else:
print("You are not an adult")
An "elif" statement allows us to check multiple conditions and execute different blocks of code depending on
which condition is true.
age = int(input())
if age >= 18:
print("You are an adult")
elif age >= 13:
print("You are a teenager")
else:
print("You are a child")
A nested if statement is simply an if statement that is located within the body of another if statement. The nested
if statement is executed only if the condition of the outer if statement is true.
# asking user for input
age = int(input("Enter your age: "))
height = int(input("Enter your height in cm: "))
# nested if statements to determine eligibility for a rollercoaster ride
if age >= 10:
print("You are old enough to ride the rollercoaster")
if height >= 120:
print("And you meet the height requirement.")
else:
print("But you do not meet the height requirement.")
else:
print("You are not eligible to ride the rollercoaster because you are
too young.")
# Traditional way
a = 10
b = 15
if a > b:
max_val = a
else:
max_val = b
# Using one-line conditional
max_val = a if a > b else b
The one-line conditional provides a concise and readable way to express the same logic in a single line.
Program: Write a program that takes a string as input and counts the number of vowels (a, e, i, o, u) in the
string using a for loop.
# Take input from the user
string = input("Enter a string: ")
# Initialize a count variable to 0
count = 0
# Loop through each character in the string
for char in string:
# Check if the character is a vowel
if char in "aeiouAEIOU":
# If it is, increment the count
count += 1
# Print the count of vowels
print("The number of vowels in the string is:", count)
range() returns a special type of object that behaves like a sequence but does not actually generate the entire
sequence in memory. This can be more memory-efficient when dealing with large sequences. If you need to
generate the entire sequence at once, you can convert the range() object to a list using the list() function.
Using Breaks & continue:
Loops and iterations are powerful tools in Python programming that allow you to repeat a set of instructions
until a certain condition is met.
Sometimes you might want to exit a loop early or skip over certain iterations. This is where the break and
continue statements come in.
The break statement is used to exit a loop prematurely. When the break statement is encountered inside a loop,
the loop is immediately terminated and the program execution continues with the next statement outside of the
loop.
for i in range(10):
if i == 5:
break
print(i) #0 1 2 3 4
The continue statement is used to skip over certain iterations of a loop. When the continue statement is
encountered inside a loop, the current iteration is skipped and the loop continues with the next iteration.
for i in range(10):
if i % 2 == 0:
continue
print(i) #1 3 5 7 9
You're given a nested list of numbers, and your task is to count the number of odd and even numbers in the list.
# List of numbers
numbers = [
[2, 5, 11, 20, 8],
[9, 4, 15, 28, 17],
[1, 6, 21, 18, 3],
[10, 13, 25, 33, 30],
[14, 7, 16, 19, 22]]
# Initialize counters for odd and even numbers
even_count = 0
odd_count = 0
# Iterate through the main list and its sublists using nested loops
for sublist in numbers:
for number in sublist:
# Check if the number is odd or even and increment the counters
accordingly
if number % 2 == 0:
even_count += 1
else:
odd_count += 1
# Print the total count of odd and even numbers
print(f"Total even numbers: {even_count}")
print(f"Total odd numbers: {odd_count}")
Imagine you are a teacher and you need to calculate the average grade for a class of 25 students. You have a list
of grades for each student and you need to loop through the list to calculate the average grade for the class.
# Create a list of grades for each student
grades = [90, 85, 95, 80, 75, 85, 90, 85, 70, 80,
90, 75, 80, 85, 90, 95, 80, 75, 85, 90,
85, 90, 75, 80, 85]
# Use a for loop to calculate the total grade for the class
total_grade = 0
for grade in grades:
total_grade += grade
# Calculate the average grade for the class
average_grade = total_grade / len(grades)
# Print the average grade for the class
print(f"The average grade for the class is {average_grade}.")
You need to implement a feature that allows users to count the number of vowel in a string of text. You have a
string containing the text and you need to loop through the string to search for the character.
# for loop to count the number of vowels in a string
my_string = "Hello, World!"
count = 0
for char in my_string:
if char in "aeiouAEIOU":
count += 1
print(count)
you want to print out both the books and their authors
for book, author in library.items():
print(f"{book} is written by {author}")
Write a program that calculates the total revenue for each day of the week using a loop and prints the results.
#Below we have revenue for previous week. Update this and add this week's
revenue as well.
revenue = {
'Monday': 250,
'Tuesday': 230,
'Wednesday': 45,
'Thursday': 100,
'Friday': 109,
'Saturday': 234,
'Sunday': 567}
for day, sales_amount in sales.items():
revenue[day] += sales_amount
for day, revenue_amount in revenue.items():
print(f"{day}: ${revenue_amount}")
Write a program that takes a list of rolls as input for each player and uses a for loop to calculate the average roll
for each player. The winner gets bragging rights for being the luckiest!
# define a list of rolls for each player
player_rolls = [
[4, 2, 6, 3, 1], # player 1's rolls
[3, 5, 6, 4, 2], # player 2's rolls
[1, 2, 2, 6, 4] # player 3's rolls]
# create an empty list to store each player's average roll
average_rolls = []
# loop through each player's rolls
for i, rolls in enumerate(player_rolls, 1):
# calculate the average roll for the player using the sum() and len()
functions
# hint: the formula for average is sum of rolls divided by number of
rolls
avg_roll = sum(rolls) / len(rolls)
# add the player's average roll to the list of average rolls
average_rolls.append(avg_roll)
# loop through each player's average roll and print it out with the player
number
for i, avg_roll in enumerate(average_rolls):
print(f"Player {i+1}'s average roll: {avg_roll}")
Conditional Looping:
Conditional looping, also known as a "loop with a condition," is a control flow statement that allows a
programmer to execute a certain block of code repeatedly until a certain condition is no longer met. In Python,
there are two types of conditional loops: the "while loop" and the "for loop."
Write a Python program that takes a list of numbers as input and finds the largest even number in the list using
while loop.
numbers = [12, 7, 8, 15, 20, 10, 45]
numbers = [12, 7, 8, 15, 20, 10, 45]
# Initialize variable to hold largest even number found
largest_even = None
# Initialize counter variable for while loop
i = 0
# While loop to iterate over each number in the list
while i < len(numbers):
num = numbers[i]
i += 1
# Check if the number is even
if num % 2 == 0:
# If largest_even is None or the current number is greater than the
current largest_even, update largest_even
if largest_even is None or num > largest_even:
largest_even = num
# Output the largest even number found
if largest_even is not None:
print(f"The largest even number in the list is {largest_even}.")
else:
print("There are no even numbers in the list.")
Nesting a while loop within another while loop can lead to code that is difficult to understand and maintain.
It can also result in an loop, which can crash a program or cause it to run indefinitely.
When you have nested while loops, the inner loop will execute its entire code block multiple times for each
iteration of the outer loop. This can result in a large number of iterations, which can make your code less
efficient and slower to run. Additionally, if you need to make a change to the inner loop, you may need to
modify the outer loop as well, which can lead to errors and make your code more difficult to maintain.
Instead of using nested while loops, it's often better to use a single loop with conditional statements to
control the flow of the program. This approach can make your code more readable and easier to
understand, and it can also help you avoid common programming errors.
For loops are typically used when you know the number of iterations in advance or want to iterate over a
sequence of values. You could use a for loop when you want to perform a fixed number of tasks or iterate over a
list, tuple, or string.
While loops, on the other hand, are typically used when you don't know the number of iterations in advance or
want to iterate until a certain condition is met. You could use a while loop when you want to perform a task until
a certain condition is met or keep prompting the user for input until they enter a valid value.
Suppose you work at a bakery and you need to count the number of loaves of bread that are sold each day for a
week. You have a list daily_sales that contains the number of loaves sold each day. You need to calculate the
total number of loaves sold during the week, as well as the average number of loaves sold per day.
# Define the list of daily sales
daily_sales = [10, 15, 20, 12, 8, 17, 9]
# Initialize variables to store total sales and count of days
total_sales = 0
num_days = 0
# Loop through the daily sales list
for sales in daily_sales:
# Add the sales for the current day to the total sales
total_sales += sales
# Increment the count of days
num_days += 1
# Calculate the average number of loaves sold per day
avg_sales = total_sales / num_days
# Print the total number of loaves sold during the week and the average
number of loaves sold per day
print("Total loaves sold during the week:", total_sales)
print("Average loaves sold per day:", avg_sales)
height = int(input("Enter the height of the triangle: "))
for i in range(1, height+1):
for j in range(1, i+1):
print("*", end=" ")
print()
Suppose you work at a gym and you need to count the number of members who visited the gym each day for a
week. You have a list daily_visitors that contains the number of members who visited the gym each day. You
need to calculate the total number of members who visited the gym during the week, as well as the average
number of members who visited the gym per day.
You are a teacher who wants to grade student answers to a quiz. The quiz has 5 questions, and each question is
worth 10 points. You want to use a for loop to go through each question and assign a grade for that question
based on the student's answer. If the answer is correct, the student gets 1 mark for that question. If the answer is
incorrect, the student gets zero marks.
You are an emoji artist and you want to create a pattern of smiley faces using a for loop. You want to print out 5
smiley faces in a row, and then move to the next row and print 4 smiley faces, then 3, then 2, then 1. Your final
pattern should look like a pyramid of smiley faces.
Example output:
😊😊😊😊😊
😊😊😊😊
😊😊😊
😊😊
Write a program to calculate the sum of all the even numbers between 1 and 100.
sum_of_evens = 0
for num in range(1, 101):
if num % 2 == 0:
sum_of_evens += num
print("The sum of all the even numbers between 1 and 100 is:",
sum_of_evens)
Custom functions are user-defined functions in a programming language that allow developers to encapsulate a
block of code with a specific functionality, which can be called repeatedly throughout their programs.
Custom functions are blocks of code created by programmers to perform specific tasks or operations within a
program. They can be created in most programming languages and are often used to simplify and modularize
code by separating out specific functions that can be called upon multiple times within the program.
A custom function can be designed to take one or more input parameters, which can be used to customize its
behavior. These parameters allow the function to be called with different arguments, enabling it to perform the
same operation on different sets of data. The output of a function can also be customized, allowing it to return
specific results based on its inputs.
One of the main advantages of custom functions is that they can be reused throughout a program or even across
multiple programs. This reduces the amount of code that needs to be written, which can save time and effort.
Custom functions also make code easier to read and understand because they encapsulate complex operations in
a single function with a clear name and purpose.
Custom functions are widely used in programming tasks such as data processing, mathematical calculations, and
user interface design. They are an essential tool for any programmer looking to write efficient and maintainable
code.
In Python, you can create your own functions using the def keyword. Here is the basic syntax for defining
a function:
def function_name(parameters :"Parameter Hints" = "Default Parameter
Value"):
"""
Docstring
"""
# function code goes here
return output_value
def: This keyword indicates the start of a function definition. It stands for "define"
Function_name: This is the name of the function you are defining.
Parameters: These are the input values that the function will take. They are optional, and you can have
as many or as few as you need.
Parameter Hints : Pressing "Shift+Tab" while calling a function will display the parameter hints that
were initially defined.
Default Parameter Value : If a value is not provided when calling a function, this value will be used
instead.
Docstring : A docstring is a string literal that appears as the first statement in a module, function, class,
or method definition. Its purpose is to provide documentation for the code and to describe what the
function does, what arguments it takes, and what it returns.
Function code : This is the code that gets executed when the function is called. It can be any valid
Python code.
return: This keyword indicates the value that the function will return. This is also optional, and you
can have multiple return statements in a function.
you can simply use the "calculate_sales" function to get the total for that day
def calculate_sales(monday_sales=0, tuesday_sales=0, wednesday_sales=0,
thursday_sales=0, friday_sales=0, saturday_sales=0, sunday_sales=0):
"""
Calculates the total sales for a given week by adding up the sales for
each day of the week.
Args:
monday_sales (float): Sales figure for Monday.
tuesday_sales (float): Sales figure for Tuesday.
wednesday_sales (float): Sales figure for Wednesday.
thursday_sales (float): Sales figure for Thursday.
friday_sales (float): Sales figure for Friday.
saturday_sales (float): Sales figure for Saturday.
sunday_sales (float): Sales figure for Sunday.
Returns:
float: The total sales for the week.
"""
# Sum up the sales figures for each day of the week
total_sales = monday_sales + tuesday_sales + wednesday_sales +
thursday_sales + friday_sales + saturday_sales + sunday_sales
# Return the total sales
return total_sales
total_sales = calculate_sales(monday_sales = 100, tuesday_sales = 200,
wednesday_sales=150, thursday_sales=300, friday_sales=250,
saturday_sales=180, sunday_sales=150)
print(total_sales)
Write a program which would calculate the count of each unique characters in a words and returns an
appropriate dictionary. Use a custom function to achieve this.
word = "Custom Function"
def count_letters(word):
letter_count = {}
for letter in word:
if letter.isalpha():
letter = letter.lower()
letter_count[letter] = letter_count.get(letter, 0) + 1
return letter_count
# Try out here
word = "Custom Function"
result = count_letters(word)
print(result)
In Python, variables that are defined outside of a function are called global variables, while variables that are
defined inside a function are called local variables. The scope of a variable refers to the area of the program
where it can be accessed and used.
Global variables can be accessed and modified by any part of the program, including within functions. However,
local variables are only accessible within the function where they are defined.
# Defining a global variable
global_var = 10
def modify_global_var():
"""
Modifies the global variable by adding 5 to its current value.
"""
# Accessing the global variable
global global_var
def use_local_var():
"""
Prints the value of a local variable.
"""
# Defining a local variable
local_var = 20
In the above example, global_var is a global variable that can be accessed from any part of the program,
5️⃣
including within functions. The modify_global_var() function modifies the value of global_var by adding to it.
To modify a global variable within a function, you need to use the global keyword before the variable name.
The use_local_var() function defines a local variable local_var within the function. This variable is only
accessible within the function and cannot be accessed outside of it. When the function is called, it prints the
value of local_var.
It is generally considered best practice to use local variables whenever possible, rather than global variables.
This is because local variables have a smaller scope, meaning they are only accessible within the function where
they are defined. This can help to prevent unintended changes to the variable value and make the code more
modular.
On the other hand, global variables can be accessed and modified from any part of the program, which can make
it harder to keep track of changes to the variable value. Additionally, if multiple functions or modules in a
program use the same global variable, it can lead to naming conflicts and make the code harder to maintain.
However, there may be situations where using global variables is necessary. For example, if a variable needs to
be accessed and modified by multiple functions or modules in a program, using a global variable may be the
best option.
Write a function which takes a string arguments and returns the reversed string to the user.
my_string = "Hello, world!"
def reverse_string(string_input):
reversed_string = string_input[::-1]
return reversed_string
# Try out here
input_string = "Hello, World!"
reversed_string = reverse_string(input_string)
print(reversed_string)
Note that default parameters should always come after non-default parameters in the function definition. This is
because Python assigns values to parameters based on their position in the argument list.
# This is not allowed, since non-default parameter follows default
parameter
def my_function(y=10, x):
return x+y
# do something with x and y
my_function(10) #error
Write a function that uses a while loop to calculate calories burned. The function takes workout duration and
activity type as input and calculates calories burned based on the duration and activity type.
Refer to following chart: Running- Burns 10 calories per minute Swimming- Burns 8 calories per minute
Cycling- Burn 6 calories per minute.
def calculate_calories_burned(duration_mins, activity):
calories_burned = 0
while duration_mins > 0:
if activity.lower() == "running":
calories_burned += 10
elif activity.lower() == "swimming":
calories_burned += 8
elif activity.lower() == "cycling":
calories_burned += 6
duration_mins -= 1
return f"You burned {calories_burned} calories during the {activity}
workout."
# Test the function
calculate_calories_burned(duration_mins=20, activity="running")
You burned 200 calories during the running workout.
The function takes a dictionary of book titles as keys and current stock as values, as the input and should return
a dictionary consisting of title as the key and number of books to be ordered as the value.
# List of books and their current stock
books = {
"Harry Potter": 10,
"Lord of the Rings": 5,
"Game of Thrones": 2,
"The Hunger Games": 8,
"To Kill a Mockingbird": 4}
def calculate_books_to_order(books):
#Your code here
# Calculate books to order
calculate_books_to_order(books)
Recursion :
Recursion is a powerful concept in programming where a function calls itself from within its own. In Python,
recursion is often used to solve problems that can be broken down into smaller, similar problems.
In a recursive function, the function is called with a parameter that is gradually reduced or changed until it
reaches a base case that can be directly solved. The base case is the simplest possible case that the function can
solve without calling itself.
Recursive functions can be used to solve problems like searching through a list, or finding the factorial of a
number. However, it's important to be careful when using recursion, as it can lead to infinite loops or stack
overflow errors if not implemented correctly.
def factorial(n=0):
"""
Calculates the factorial of a non-negative integer.
Args:
n (int): A non-negative integer to calculate the factorial of.
Returns:
int: The factorial of the input integer.
"""
# Base case: if n is 0, the factorial is 1
if n == 0:
return 1
# Recursive case: multiply n by the factorial of n-1
else:
return n * factorial(n-1)
factorial(4) #24
A teacher wants to create a Python function to grade a multiple-choice test. The function should take one
argument: a list of answers given by a student. The function should compare the answers given by the
student with the predefined answer key and return the score obtained. Each correct answer is worth 1
point, and each incorrect answer is worth 0 points.
def grade_test(student_answers):
"""
Grades a test based on the student's answers and an answer key.
Args:
student_answers (list): A list of the student's answers to the test
questions.
Returns:
int: The student's score on the test.
"""
answer_key = ["A", "B", "C", "D", "E"]
score = 0
# Loop through each answer and compare it to the corresponding answer
in the answer key
for i in range(len(student_answers)):
if student_answers[i] == answer_key[i]:
score += 1 # Increment the score if the answer is correct
else:
score += 0 # No change in score if the answer is incorrect
return score
# Grade the test and print the score
score = grade_test(student_answers)
print(score)
Write a function that takes a list of integers as input and returns the sum of the squares of the even
numbers in the list.
def sum_of_even_squares(lst):
"""
Calculates the sum of the squares of all even numbers in a list.
Args:
lst (list): A list of numbers.
Returns:
int: The sum of the squares of all even numbers in the list.
"""
total = 0
for num in lst:
if num % 2 == 0:
total += num ** 2
return total
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares_sum = sum_of_even_squares(numbers)
print(even_squares_sum)
Write a function that takes a string as input and returns a new string with all vowels removed.
def remove_vowels(string):
"""
Removes vowels from a given string and returns the new string.
Args:
string (str): The input string.
Returns:
str: The input string with vowels removed.
"""
vowels = "aeiouAEIOU"
new_string = ""
for char in string:
if char not in vowels:
new_string += char
return new_string
my_string = "Hello, World!"
no_vowels_string = remove_vowels(my_string)
print(no_vowels_string)
Write a function that takes a list of strings as input and returns a new list with all strings in uppercase.
def uppercase_list(lst):
"""
Converts all strings in a list to uppercase.
Args:
lst (list): A list of strings.
Returns:
list: A new list with all strings in uppercase.
"""
new_list = []
for string in lst:
new_list.append(string.upper())
return new_list
words = ["apple", "banana", "cherry", "date"]
upper_words = uppercase_list(words)
print(upper_words)
Write a function that takes a dictionary as input and returns a new dictionary with the same keys but
with all values squared.
def square_dict_values(dct):
"""Given a dictionary, returns a new dictionary with the same keys as
the input dictionary, but with the values squared.
Args:
- dct: A dictionary with numeric values.
Returns:
- A new dictionary with the same keys as the input dictionary, but with
the values squared."""
new_dict = {}
for key, value in dct.items():
new_dict[key] = value ** 2
return new_dict
my_dict = {"a": 1, "b": 2, "c": 3, "d": 4}
squared_dict = square_dict_values(my_dict)
print(squared_dict)
Write a function reverse_string that takes a string as input and returns the string reversed.
def reverse_string(string):
"""
Return a reversed version of the input string.
"""
reversed_string = ""
for i in range(len(string)-1, -1, -1): # Loop over the string in
reverse order
reversed_string += string[i] # Add each character to the reversed
string
return reversed_string
my_string = "Hello, World!"
reversed_string = reverse_string(my_string)
print(reversed_string)
Comprehensions are a powerful feature of Python that allow you to create lists, sets, and dictionaries in a
concise and efficient way. They are particularly useful when working with large datasets or performing complex
transformations on data. Comprehensions in Python are a concise way to create data structures, such as lists,
sets, and dictionaries, using a compact syntax. They allow you to iterate over an iterable object, such as a list or
a range, and apply a condition or transformation to each element to generate a new iterable.
There are 3 types of Comprehensions in python:
1. List Comprehension
2. Set Comprehension
3. Dictionary Comprehension
Lambda functions:
A lambda function is a small, anonymous function in Python that can take any number of arguments, but can
only have one expression. Lambda functions are often used as a shortcut for creating simple, one-line functions.
basic syntax of a lambda function in Python:
lambda arguments: expression
The arguments are the inputs to the function, separated by commas. The expression is the output of the function,
which is evaluated and returned when the lambda function is called.
# A lambda function that adds two numbers
add = lambda x, y: x + y
# Call the lambda function
result = add(3, 4)
print(result) #7
This is equivalent to:
def add(x, y):
return x + y
# Call the custom function
result = add(3, 4)
print(result) #7
Write a lambda function that takes in two numbers as input and returns the quotient of the first number divided
by the second number. If the second number is zero, the function should return "undefined".
divide = lambda x, y: "undefined" if y == 0 else x/y
print(divide(10, 2)) # Output: 5.0
print(divide(10, 0)) # Output: undefined
In Python, filter() is a built-in function that allows you to filter elements of an iterable (such as a list, tuple, or
string) based on a certain condition. The filter() function returns an iterator containing only the elements for
which the condition is True.
The syntax for filter() is:
filter(function, iterable)
where function is a function that takes a single argument and returns a Boolean value (i.e., True or False) based
on some condition, and iterable is the iterable object that you want to filter.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4, 6, 8, 10]
The lambda function checks if a number is even by checking if its remainder after division by 2 is 0. We then
convert the filtered result to a list and print it.
Map Function:
The map() function in Python applies a given function to each item of an iterable (e.g. a list) and returns a new
iterable with the results. The syntax of the map() function is as follows:
map(function, iterable)
Here, function is the function to be applied to each item in the iterable, and iterable is the list or other iterable to
be operated upon.
# A list of integers
numbers = [1, 2, 3, 4, 5]
# Use map() with a lambda function to calculate squares
squares = list(map(lambda x: x**2, numbers))
# Print the list of squares
print(squares) #1 4 9 16 25
we define a list of numbers and then use the map() function with a lambda function to calculate the square of
each number in the list. The lambda function takes an input x and returns x**2, which is the square of x. The
resulting map object is then converted to a list using the list() function, and the list of squares is printed.
The map() function can be used with any function that takes a single argument and returns a single value, not
just lambda functions.
an example of using the map() function with a built-in function to convert a list of strings to a list of their
lengths:
# A list of strings
words = ["apple", "banana", "cherry"]
# Use map() with len() to calculate lengths
lengths = list(map(len, words))
# Print the list of lengths
print(lengths) [5,6,6]
we use the map() function with the built-in len() function to calculate the length of each string in the words list.
The resulting map object is then converted to a list using the list() function, and the list of lengths is printed.
Lambda functions can be especially useful when you need to perform a simple operation on each item in a list,
such as converting all the items to lowercase or removing any items that don't meet a certain criterion. By using
a lambda function with a built-in function like map() or filter(), you can perform these operations in a concise
and readable way.
List Comprehension:
List comprehensions are a concise and powerful way to create lists in Python. They allow you to create a new
list by iterating over an existing iterable object, such as a list, tuple, or string, and applying a condition or
expression to each element.
List comprehensions in Python are great, but mastering them can be tricky because they don’t solve a new
problem: they just provide a new syntax to solve an existing problem.
The basic syntax for a list comprehension is:
new_list = [expression for item in iterable if condition]
Here,
Expression is the operation you want to perform on each element of the iterable.
Item is a variable representing each element in the iterable,
Iterable is the iterable object you want to iterate over, and
Condition is an optional condition that filters the elements based on a Boolean expression.
You want to create a list of the squares of the first 10 positive integers
squares = []
for i in range(1, 11):
squares.append(i**2)
print(squares)
Using a list comprehension, you could accomplish the same task with less code:
squares = [i**2 for i in range(1, 11)]
print(squares)
The list comprehension consists of three parts:
The Output expression i**2 that calculates the square of each number in the range,
The variable i that represents each number in the range,
And the output predicate, the range itself range(1, 11) that specifies the numbers to be squared.
Question 1:
Instructions: Complete the lambda function to multiply each element of the list by 2 using mapping.
numbers = [1, 2, 3, 4, 5]
doubled_numbers = list(map(______, numbers))
Question 2:
Instructions: Complete the lambda function to convert each word in the list to uppercase using mapping.
words = ['hello', 'world', 'python', 'programming']
uppercase_words = list(map(______, words))
Question 3:
Instructions: Fill in the lambda function to calculate the square of each number in the list using mapping.
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(______, numbers))
Answers:
Question 1: Answer: lambda x: x * 2
Explanation: In this question, the lambda function takes an argument "x" and returns the result of multiplying
"x" by 2. The "map" function applies this lambda function to each element of the "numbers" list, creating a new
list "doubled_numbers" with all elements doubled.
Question 2: Answer: lambda word: word.upper()
Explanation: The lambda function takes a word as input and returns the uppercase version of that word using the
"upper()" method. The "map" function applies this lambda function to each word in the "words" list, creating a
new list "uppercase_words" with all words converted to uppercase.
Question 3: Answer: lambda x: x**2
Explanation: The lambda function takes a number "x" and returns the square of that number using the
expression "x2". The "map" function applies this lambda function to each number in the "numbers" list, creating
a new list "squared_numbers" with the square of each element.
Set Comprehension:
Set comprehensions are similar to list comprehensions, but instead of creating a new list, they create a new set.
The basic syntax for a set comprehension is:
new_set = {expression for item in iterable if condition}
Here,
Expression is the operation you want to perform on each element of the iterable.
Item is a variable representing each element in the iterable.
Iterable is the iterable object you want to iterate over.
Condition is an optional condition that filters the elements based on a Boolean expression.
You only want to include categories that have at least 10 books in stock. Using set comprehension, create a set
of all the unique book categories that have at least 10 books in stock.
books = [('fiction', 20), ('history', 15), ('biography', 5), ('mystery',
10), ('science', 8), ('fiction', 15), ('history', 10)]
# Using set comprehension to create a set of book categories with at least
10 books in stock
categories = {category for category, stock in books if stock >= 10}
print(categories)
Dictionary Comprehension:
Dictionary comprehension is a concise and efficient way to create a dictionary in Python. It allows you to create
a new dictionary by specifying a set of key-value pairs and an optional condition, all in a single line of code.
The basic syntax of dictionary comprehension is as follows:
{key_expression: value_expression for item in iterable if condition}
For example, let's say you have a list of names and you want to create a dictionary where the keys are the names
and the values are the lengths of the names. You can use dictionary comprehension to achieve this in a single
line of code:
names = ['Alice', 'Bob', 'Charlie', 'Dave']
name_lengths = {name: len(name) for name in names}
print(name_lengths)
{'Alice': 5, 'Bob': 3, 'Charlie': 7, 'Dave': 4}
For example, let's say you have a dictionary of students and their grades, and you want to create a new
dictionary that only includes students who received a passing grade (i.e., grade >= 60). You can use dictionary
comprehension with an if statement to achieve this:
grades = {'Alice': 80, 'Bob': 55, 'Charlie': 75, 'Dave': 90}
passing_grades = {name: grade for name, grade in grades.items() if grade >=
60}
print(passing_grades)
#This will create a new dictionary passing_grades with the following key-
value pairs:
{'Alice': 80, 'Charlie': 75, 'Dave': 90}
Suppose you have a dictionary containing the names and ages of some people. Write a Python program that uses
dictionary comprehension to generate a new dictionary containing the names of people who are over 18 years
old.
people = {'Alice': 25, 'Bob': 17, 'Charlie': 20, 'David': 30, 'Eve': 16}
# Using dictionary comprehension to filter names of people who are over 18
years old
adults = {name: age for name, age in people.items() if age > 18}
print(adults)
Answers:
1. Answer: d) {x, x*2 for x in range(5)}
Explanation: The correct syntax for dictionary comprehension is to use a colon (:) between the key
and value expressions. Option d) lacks the colon, making it incorrect.
2. Answer: c) {x: x**2 for x in [1, 2, 3, 4, 5] if x % 2 == 0}
Explanation: c) {x: x**2 for x in [1, 2, 3, 4, 5] if x % 2 == 0}
This dictionary comprehension is error-free and will create a dictionary successfully. It maps even
numbers to their squares.
3. Answer: b) {x: x**2 for x in range(5) if x % 2 == 0 else x**3}
Explanation: Option b) contains an error because it uses an incorrect syntax for the conditional
expression inside the dictionary comprehension. The correct syntax should use the "if" condition before
the "for" loop, or it should be avoided altogether for clarity. {x: x**2 if x % 2 == 0 else
x**3 for x in range(5)}
4. Answer: c) {x: x*2 for x in range(10) if x % 2 == 0}
Explanation: Option c) is the correct dictionary comprehension to create a dictionary with even
numbers (0, 2, 4, 6, and 8) and their corresponding values multiplied by 2. It uses the correct syntax for
filtering even numbers using the "if" condition.
Enumerate Function:
The "enumerate()" function is a powerful tool that simplifies looping over iterable objects, such as lists or
strings. It returns a tuple containing the index and the corresponding value for each element in the sequence.
This allows you to access both the index and the element during iteration, making code more concise and
readable.
fruits = ['apple', 'banana', 'orange']
for index, fruit in enumerate(fruits):
print(f"Index {index}: {fruit}")
Zip Function:
The "zip()" function is used to combine multiple iterables into a single iterable of tuples. It pairs elements from
different sequences based on their index. This is particularly useful when you want to loop through multiple lists
or strings simultaneously.
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}")
Generator Expressions:
Generator expressions are similar to list comprehensions, but they generate values on-the-fly rather than creating
a new list. This makes them memory-efficient when dealing with large datasets. They are denoted by
parentheses instead of square brackets.
numbers = [1, 2, 3, 4, 5]
squared_numbers = (num**2 for num in numbers)
print(next(squared_numbers)) # Output: 1
print(next(squared_numbers)) # Output: 4
OOPs in Python
OOPs (Object-Oriented Programming) is a programming paradigm that is based on the concept of objects. An
object is an instance of a class, which encapsulates data and functionality. In Python, everything is an object,
and therefore, Python is an object-oriented language.
Object-Oriented Programming is a programming paradigm that revolves around the concept of objects, which
can contain data and code to manipulate that data. In OOPs, programs are organized around objects, which can
communicate with each other to perform tasks. OOPs is used to create reusable code, improve the code's
readability and maintainability, and increase the program's modularity and scalability.
Think of objects as real-world entities that have attributes and behaviors. For example, a car is an object that has
attributes like make, model, and color, and behaviors like accelerating, braking, and turning.
Similarly, in OOPs, we define classes that represent real-world entities. These classes have attributes and
methods that define the characteristics and behaviors of the objects created from them.
For example, consider a class called Car. This class can have attributes like make, model, and color, and
methods like accelerate(), brake(), and turn(). When we create an object of this class, say a Toyota Camry, we
can set its attributes to make='Toyota', model='Camry', and color='Red'. We can then call its methods, such as
accelerate() to make it go faster, or brake() to slow it down.For this lesson we will construct our knowledge of
OOPs in Python by building on the various topics.
The main concept of OOPs is to bind the data and the functions that work on that together as a single
unit.
Class: In Python, a class is a blueprint for creating objects. It defines a set of attributes and methods that objects
of that class will have. A class can be thought of as a template or a blueprint, and an object can be thought of as
an instance of that class.
To define a class in Python, we use the class keyword followed by the name of the class.
class MyClass:
# Class Variables
variable1 = "Hello"
variable2 = "World"
# Class Method
def myMethod(self):
print("MyClass method called.")
# Accessing Variables
print(myObject.variable1)
print(myObject.variable2)
# Accessing Methods
myObject.myMethod()
In this example, we define a class called MyClass. This class has two class variables (variable1 and variable2)
and a class method (myMethod). We then create an object of this class called myObject and use it to access the
class variables and method.
Note that in Python, the self parameter is used to refer to the current instance of the class. This parameter is
automatically passed to instance methods, and you should include it as the first parameter of any method you
define in a class.
Attributes:
Attributes are variables that hold information about an object. In Python, attributes are defined inside the class
definition.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
In this example, we've defined a class called Person with two attributes: name and age.
We've also defined a constructor method called __ init__() that takes two arguments, name and age. Inside the
constructor, we use the self keyword to refer to the object being created and set the name and age attributes to
the corresponding arguments.
We can now create an object of the Person class and set its attributes:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("John", 30)
print(person.name)
print(person.age)
Objects:
An object is an instance of a class. We create objects by calling the class as if it were a function, passing in any
necessary arguments. Here's an example:
person = Person()
In this example, we've created an object of the Person class called person. This object doesn't have any attributes
or methods yet because we haven't defined them in the class.
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.is_engine_on = False
def start_engine(self):
self.is_engine_on = True
def stop_engine(self):
self.is_engine_on = False
def display_info(self):
print(f"Make: {self.make}")
print(f"Model: {self.model}")
print(f"Year: {self.year}")
print(f"Engine Status: {'On' if self.is_engine_on else 'Off'}")
Question 1: In the given Python code, what does the class Car represent?
Question 2: What are the attributes defined in the Car class?
Question 3: What is the purpose of the init method in the Car class?
Question 4: What does the method start_engine do?
Question 5: How can we create multiple instances (objects) of the Car class with different make, model, and
year?
Question 6: What is the significance of the self keyword used in the methods of the Car class?
1: The class Car represents a blueprint or template for creating car objects. It defines the common properties
(attributes) and behaviors (methods) that all car objects will have.
2: The attributes defined in the Car class are make, model, year, and is_engine_on.
3: The init method is a special method called the constructor. It is automatically executed when a new instance
of the Car class is created. It initializes the attributes of the object with the provided values.
4: The method start_engine sets the attribute is_engine_on to True, indicating that the car's engine is turned
on.
5: We can create multiple instances of the Car class by calling the class and passing different values for the
make, model, and year attributes. For example, car1 = Car("Toyota", "Corolla", 2022) and car2 =
Car("Honda", "Civic", 2023) create two instances of the Car class with different attributes.
6: The self keyword refers to the instance of the class itself. It allows the methods of the class to access and
modify the attributes specific to that instance. When calling a method of a class, Python automatically passes the
instance as the first argument (self), allowing the method to work with the object's data.
Methods:
Methods are functions that are defined inside a class and can be called on objects of that class. They are used to
perform operations on the attributes of the object or to return information about the object.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print("Hello, my name is", self.name)
In this example, we've defined a class called Person with a method called greet(). The method takes no
arguments and prints a greeting message that includes the object's name attribute. We can now call the greet()
method on an object of the Person class:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print("Hello, my name is", self.name)
person = Person("John", 30)
person.greet()
Hello, my name is John
You create a Calculator class that has methods for each of the basic arithmetic operations (add, subtract,
multiply, divide) as well as a clear method. The class stores a result attribute that holds the current result of the
calculator operations. Students can use this calculator to help them with their math problems, and you can use it
to double-check their answers.
class Calculator:
# Define the constructor method to initialize the class and set the
initial result to 0
def __init__(self):
self.result = 0
# Define a method to subtract num2 from num1 and store the result
def subtract(self, num1, num2):
self.result = num1 - num2
return self.result
# Define a method to divide num1 by num2 and store the result. Raise a
ValueError if dividing by 0.
def divide(self, num1, num2):
if num2 == 0:
raise ValueError("Cannot divide by zero.")
self.result = num1 / num2
return self.result
In this example, we define a class called Calculator. The init method initializes the result attribute to 0. The
class has four methods for performing basic arithmetic operations: add, subtract, multiply, and divide. Each
method takes a single argument num, which is the number to perform the operation with. The divide method
checks for a divide by zero error and raises a ValueError if the input is zero.
The class also has a clear method that sets the result attribute to 0, effectively resetting the calculator.
calc=Calculator()
#calling add method
addition=calc.add(42,6)
print("Addition- ",addition)
print("subtraction- ",subtraction)
print("division- ",division)
print("mulitplication- ",mulitplication)
You have been asked to develop a virtual pet program that simulates the experience of owning a pet. The
program should allow users to create a new pet, feed it, play with it, and monitor its health. Each pet should
have a name, age, and initial health level.
To implement this program, you decide to create a class called Pet that represents a virtual pet. The Pet class has
attributes for the pet's name, age, and health level. It also has methods for feeding the pet, playing with the pet,
and checking the pet's health.
class Pet:
# Define the constructor method to initialize the class with name, age and health_level
def __init__(self, name, age, energy_level):
self.name = name
self.age = age
self.energy_level = energy_level
# Define a method to decrease health level when playing with the pet
def play(self):
self.energy_level -= 5
# Define a method to check the health of the pet and print a message based on its health level
def check_health(self):
if self.energy_level < 50:
print("Your pet is not feeling well.")
else:
print("Your pet is healthy.")
In this example, we define a class called Pet. The init method initializes the pet's name, age, and health_level
attributes. The class has three methods for interacting with the pet: feed, play, and check_health.
The feed method increases the pet's health level by 10, while the play method decreases the health level by 5.
The check_health method checks the pet's current health level and prints a message indicating whether the pet
is healthy or not.
Create an object of Pet class and demonstrate the usage of it's methods
# Creating Object of Pet Class
my_pet = Pet("Fluffy", 2, 50)
# Feeding Pet
my_pet.feed()
# Playing with Pet
my_pet.play()
# Checking Pet Health
my_pet.check_health()
We can then define two subclasses of Animal: Dog and Cat. Both of these subclasses inherit the make_sound()
method from the Animal class, but they provide their own implementation of this method.
class Dog(Animal):
def make_sound(self):
print("Bark")
class Cat(Animal):
def make_sound(self):
print("Meow")
we can create instances of both the Dog and Cat classes and call their make_sound() methods. Even though both
of these methods have the same name, they produce different outputs, depending on the type of animal.
dog = Dog()
cat = Cat()
goat = Animal()
dog.make_sound()
cat.make_sound()
goat.make_sound()
This is an example of polymorphism, as we are able to treat objects of different classes (Dog and Cat) as if they
are objects of the same class (Animal). This allows us to write more flexible and reusable code, as we can create
generic functions that operate on any object that has a make_sound() method, regardless of its specific type.
You are building a shape calculator program that allows users to calculate the area of various shapes, including
squares, rectangles, and circles. Each shape has a different formula for calculating its area and perimeter.
To implement this program, you decide to use polymorphism, where each shape is represented by its own class
with its own methods for calculating area. The program should be able to accept inputs for the dimensions of the
different shapes and calculate their respective areas.
class Shape:
# Define abstract methods to calculate area and perimeter. Will be implemented by child classes.
def area(self):
pass
def perimeter(self):
pass
class Square(Shape):
# Define the constructor method to initialize the class with the length of the side
def __init__(self, side):
self.side = side
class Rectangle(Shape):
# Define the constructor method to initialize the class with the width and height
def __init__(self, width, height):
self.width = width
self.height = height
class Circle(Shape):
# Define the constructor method to initialize the class with the radius
def __init__(self, radius):
self.radius = radius
In this example, we define a base class Shape that has two methods, area and perimeter. We then create three
child classes, Square, Rectangle, and Circle, that inherit from the Shape class and override the area and
perimeter methods with their own formulas:
# Creating Objects of Shape Classes
square = Square(5)
rectangle = Rectangle(3, 4)
circle = Circle(2)
Create a Bank Account Management System using Object-Oriented Programming (OOPs) in Python. The
system should allow users to create and manage bank accounts, deposit and withdraw funds, and view account
details.
# Define a BankAccount class
class BankAccount:
Inheritance:
Inheritance is a core concept in object-oriented programming, which allows a new class to be based on an
existing class. Inheritance provides a way to create a new class by absorbing the properties and behaviors of an
existing class, while also allowing for the new class to add or modify its own unique properties and behaviors.
Let's consider an example of inheritance using a program that models different types of vehicles. We can define
a base class called Vehicle that contains common properties and methods that are shared by all types of vehicles.
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def start_engine(self):
print("Starting engine...")
We can then define a subclass called Car that inherits from the Vehicle class and adds its own unique properties
and methods.
class Car(Vehicle):
def __init__(self, make, model, year, num_doors):
super().__init__(make, model, year)
self.num_doors = num_doors
def drive(self):
print("Driving the car...")
In this example, the Car class inherits from the Vehicle class using the super() function. This means that the Car
class will have access to all the properties and methods of the Vehicle class. The init() method of the Car class
overrides the init() method of the Vehicle class to include an additional parameter for the number of doors. The
drive() method is unique to the Car class and is not present in the Vehicle class.
Now, we can create instances of both the Vehicle and Car classes and call their respective methods.
vehicle = Vehicle("Toyota", "Corolla", 2022)
car = Car("Tesla", "Model S", 2021, 4)
#vehicle.drive() # This will produce an error, as the drive() method is not defined for the Vehicle class
car.drive()
As we can see from this example, the Car class inherits properties and methods from the Vehicle class and adds
its own unique functionality. This allows us to write more concise and modular code, as we can define generic
behavior in the base class and specialize that behavior in the subclasses.
Question 1: What is the possible issue with the following code snippet?
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side):
self.side = side
super().__init(side, side)
rectangle = Rectangle(5, 3)
square = Square(4)
print(rectangle.area())
print(square.area())
Answer: The error is coming in super().__init(side,side)
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side) # Call the superclass's __init__ method
self.side = side
rectangle = Rectangle(5, 3)
square = Square(4)
print(rectangle.area())
print(square.area())
Question 2: What is the potential problem with the following code snippet that demonstrates inheritance and
polymorphism in Python?
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
def print_area(shape):
print("Area:", shape.area())
circle = Circle(5)
square = Square(4)
print_area(circle)
print_area(square)
print_area(triangle)
Answer:
The error in that code is we are calling undefined method
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
def print_area(shape):
print("Area:", shape.area())
circle = Circle(5)
square = Square(4)
print_area(circle)
print_area(square)
Encapsulation:
Encapsulation is one of the fundamental concepts in object-oriented programming (OOP), including in Python.
It refers to the bundling of data (attributes) and methods (functions) that operate on the data into a single unit or
class. Encapsulation also restricts direct access to some of an object's components, which is a means of
preventing accidental interference and misuse of the methods and data.
Here's a detailed look at encapsulation in Python:
1. Bundling Data and Methods: In encapsulation, data and the methods that manipulate that data are
kept together in a single entity, typically a class. This makes the code more organized and modular.
Each object created from the class can have its own attributes and methods, providing a clear structure
for organizing functionality.
2. Access Control: Encapsulation also involves controlling access to the internal state of the object. This
is usually achieved through access modifiers, which determine how and from where the class's
attributes and methods can be accessed.
o Public Access: Members (methods or attributes) of a class that are available from outside the
class. In Python, all members are public by default.
o Private Access: Members that are only available within the class itself. You can make a
member private in Python by prefixing its name with double underscores (__). Private
members cannot be accessed directly from outside the class but can be accessed within the
class.
o Protected Access: Members that are accessible within the class and its subclasses. Python
uses a single underscore (_) prefix to denote protected members. However, this is more of a
convention, and Python does not enforce strict access control.
class Car:
def __init__(self, model, year):
self.model = model # Public Attribute
self.__year = year # Private Attribute (with double underscores)
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
class Car(Vehicle):
def start(self):
print("Starting car with key")
class Motorcycle(Vehicle):
def start(self):
print("Starting motorcycle with button")
In this example:
Vehicle is an abstract class that defines an abstract method start(). This method acts as a template for
the start method that must be implemented in any subclass of Vehicle.
Car and Motorcycle are concrete classes that inherit from Vehicle and provide specific
implementations of the start method.
The actual implementation details of starting the vehicle are abstracted away. When you call start() on
a Car or Motorcycle object, you don’t need to know the internal details of how each vehicle starts.
You only need to know that they can start, which is the essence of abstraction.
Key Points:
Abstraction helps in reducing programming complexity and effort by hiding the unnecessary details
from the user.
It allows the programmer to focus on interactions at a higher level.
It is achieved through abstract classes and interfaces in many OOP languages.
Abstract methods define a common interface for different implementations in the derived classes.
Here's what happens when abstract methods are not defined while creating a child class:
#from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
Here, Car is a child class of Vehicle, but it doesn't implement the start() method.
Instantiating the Child Class:
my_car = Car()
TypeError: Can't instantiate abstract class Car with abstract method start
1. Result:
o When you try to instantiate Car, Python will raise a TypeError because Car has not
implemented the abstract method start() defined in its parent class Vehicle.
o The error message will typically say something like: "Can't instantiate abstract class Car
with abstract methods start".
2. Key Points:
o An abstract class is more like a template for its subclasses. It ensures that certain methods are
implemented in child classes.
o If a child class of an abstract class does not implement all the abstract methods, it cannot be
instantiated. This enforces a contract that the child classes must follow.
o This behavior is crucial for maintaining a consistent interface and ensuring that certain
functionalities are provided by all subclasses.
In programming, errors and exceptions refer to problems that occur when a program is running. Error and
exception handling is a technique used to detect and manage these problems, making the program more reliable
and easier to use.Error and exception handling is an important part of programming in Python. It allows you to
handle errors and unexpected situations in a graceful and controlled manner, instead of crashing the program.
Types of Errors:
Syntax Error:
# 1. Missing Parenthesis
print("Hello, world!"
SyntaxError: unexpected EOF while parsing
# 2. Misspelled Keyword
x=5
prnit(x)
NameError: name 'prnit' is not defined
# 3. Incorrect Indentation
for i in range(10):
print(i)
IndentationError: expected an indented block
# 4. Missing Colon
if x == 5
print("x is equal to 5")
SyntaxError: invalid syntax
Logical Errors:
Logical errors, also known as semantic errors, occur when the code runs without generating any syntax errors
but produces unexpected or incorrect output due to flawed reasoning or faulty assumptions in the code. Logical
errors can be difficult to identify since the program still runs, but the output may not match the intended result.
# 1. Division by zero
a=5
b=0
c = a/b
print(c)
ZeroDivisionError: division by zero
result = calculate_area(5, 4)
print("The area is: ", result)
print("The perimeter is: ", result * 2)
No Error
Question 3:
name = "John"
age = 25
result = "My name is " + name + " and I am " + age + " years old."
TypeError: can only concatenate str (not "int") to str
The try block contains the code that may raise an exception, and the except block contains the code that handles
the exception. ExceptionType is the type of exception that you want to handle. You can replace ExceptionType
with specific exception types like ZeroDivisionError, ValueError, etc. to handle those specific exceptions.
Here's an example of how to handle a ZeroDivisionError exception:
try:
x = 10
y=0
z = x/y
except ZeroDivisionError:
print("Error: Cannot divide by zero")
2. Raise Exception:
In Python, you can raise an exception using the raise keyword. When you raise an exception, you are indicating
that an error or exceptional situation has occurred in your program.
Here's the basic syntax for raising an exception:
raise ExceptionType("Error message")
ExceptionType is the type of exception that you want to raise, and "Error message" is the message that you want
to associate with the exception.
When using the "raise" keyword in Python, you can specify different types of errors to be raised. Here are some
examples:
1. SyntaxError: This error occurs when there is a problem with the syntax of your code. For example, if
you forget to close a parenthesis or use an invalid operator, you might see a SyntaxError.
2. ValueError: This error occurs when there is a problem with the value of a variable or argument. For
example, if you try to convert a string to an integer but the string contains non-numeric characters, you
might see a ValueError.
3. TypeError: This error occurs when you try to perform an operation on two objects that are not
compatible. For example, if you try to add a string and an integer, you might see a TypeError.
4. IndexError: This error occurs when you try to access an index that is out of range. For example, if you
try to access the 5th element of a list that only has 3 elements, you might see an IndexError.
5. KeyError: This error occurs when you try to access a dictionary key that does not exist. For example,
if you try to access the value for a key that is not in the dictionary, you might see a KeyError.
By using the "raise" keyword with these error types, you can create custom error messages that help you debug
your code and handle unexpected situations.
3. Finally Block:
In Python, the finally block is used in conjunction with the try and except blocks to provide a cleanup
mechanism for resources that need to be released, regardless of whether an exception was raised or not.
Here's the basic syntax for using the finally block:
try:
# code that may raise an exception
except ExceptionType:
# code that handles the exception
finally:
# code that will always be executed, regardless of whether an exception
was raised or not
The finally block contains code that will always be executed, regardless of whether an exception was raised or
not. This block is useful for releasing resources like file handles, database connections, network sockets, etc.
Here's an example:
In the Code below, we are asking the user to input a number, and then we are dividing 10 by that number. If the
user enters 0, the code will raise a ZeroDivisionError.
We have enclosed the division code in a try block, and in the except block, we are printing an error message if
the user enters 0.
Regardless of whether an exception is raised or not, we want to print a message to thank the user for using the
program. So, we have added a finally block to print the message.
If the user enters a non-zero number, the code in the try block will be executed, and then the finally block will
be executed to print the message.
try:
num = int(input("Enter a number: "))
result = 10 / num
print("The result is:", result)
except ZeroDivisionError:
print("Error: Cannot divide by zero")
finally:
print("Thank you for using the program!")
If the user enters 0, the except block will be executed to print the error message, and then the finally block will
be executed to print the message.
try:
num = int(input("Enter a number: "))
result = 10 / num
print("The result is:", result)
except ZeroDivisionError:
print("Error: Cannot divide by zero")
finally:
print("Thank you for using the program!")
In this example, the program prompts the user to enter two numbers and then divides them. The try block
contains the code that may raise an exception, while the except blocks handle the exceptions that may occur.
The finally block is executed regardless of whether an exception is raised or not and prints a message indicating
that the program has ended.
try:
x = int(input("Enter a number: "))
y = int(input("Enter another number: "))
z = x / y
print("The result is:", z)
except ZeroDivisionError:
print("You cannot divide by zero!")
except ValueError:
print("You must enter a number!")
except Exception as e:
print("An error occurred:", e)
finally:
print("The program has ended.")
Write a program that prompts the user to enter a temperature value in Fahrenheit. The program will then convert
the temperature to Celsius and display the result. If the user enters a non-numeric value, the program will
display an error message.
while True:
try:
fahrenheit = float(input("Enter temperature in Fahrenheit: "))
celsius = (fahrenheit - 32) * 5/9
print("The temperature in Celsius is", round(celsius, 2))
except ValueError:
print("Invalid input. Please enter a numeric value.")
Write a program that prompts the user to enter a song request. If the requested song is in your playlist, the
program will display a confirmation message. If the requested song is not in your playlist, the program will
display an error message.
playlist = ["Wild Thoughts", "All I Do Is Win", "No Brainer", "I'm the
One"]
while True:
song_request = input("Enter your song request (or type 'q' to quit): ")
if song_request.lower() == "q":
print("Exiting the program.")
break
try:
if song_request in playlist:
print(f"Thanks for requesting \"{song_request}\". It's in my
playlist!")
else:
print(f"Sorry, \"{song_request}\" is not in my playlist.")
except Exception as e:
print("An error occurred:", e)
Enter your song request (or type 'q' to quit): Wild Thoughts
Thanks for requesting "Wild Thoughts". It's in my playlist!
Enter your song request (or type 'q' to quit): Another one
Sorry, "Another one" is not in my playlist.
Enter your song request (or type 'q' to quit): q
Exiting the program.
Write a program that takes the customer's order for a taco and sides. If the order is valid, the program will
display a confirmation message and the total cost. If the order is not valid, the program will display an error
message and ask the customer to try again.
Welcome to the Mexican Restaurant!
Please enter your order.
Your order:
- Taco: chicken
- Sides: chips, guacamole
- Drink: coke
- Size: medium
If the user enters an invalid input, such as a misspelled word or an unsupported option, the program should
display an error message and ask the customer to try again.
def validate_order(item, options):
while True:
user_input = input(f"{item} ({', '.join(options)})? ").lower()
if user_input in options:
return user_input
else:
print("Invalid input. Please try again.")
try:
# Calculate the total cost
total_cost = taco_prices[taco] + sum(sides_prices[side] for side in
sides) + drink_prices[drink] + size_prices[size]
return total_cost
except KeyError as e:
print(f"Error: {e}")
return None
# Check if all inputs are valid and display the customer's order and total
cost
if all([taco, sides, drink, size]):
print("\nYour order:")
print(f"- Taco: {taco}")
print(f"- Sides: {', '.join(sides)}")
print(f"- Drink: {drink}")
print(f"- Size: {size}\n")
total_cost = calculate_total_cost(taco, sides, drink, size)
if total_cost is not None:
print(f"Total cost: ${total_cost:.2f}")
else:
print("Invalid input. Please try again.")
Welcome to the Mexican Restaurant!
Please enter your order.
Taco (chicken, vegetable)? vegetable
Sides (chips, salsa, guacamole)? salsa
Drink (coke, pepsi, sprite)? sprite
Size (small, medium, large)? medium
Your order:
- Taco: vegetable
- Sides: salsa
- Drink: sprite
- Size: medium
Total cost: $8.50
Question 1:
try:
# Code block where an exception may occur
num1 = int(input("Enter a number: "))
num2 = int(input("Enter another number: "))
result = num1 / num2
except _______:
print("An error occurred while performing the division.")
Question 2:
try:
# Code block where an exception may occur
file = open("myfile.txt", "r")
content = file.read()
file.close()
except _______:
print("An error occurred while reading the file.")
Question 3:
try:
# Code block where an exception may occur
data = [1, 2, 3, 4, 5]
index = int(input("Enter an index: "))
value = data[index]
except _______:
print("An error occurred while accessing the list")
1. Answer: A) ZeroDivisionError
Explanation: In the given code, the except block is catching the ZeroDivisionError exception. This
exception occurs when attempting to divide a number by zero, which can happen if the user enters 0 as
the value for num2.
2. Answer: A) FileNotFoundError
Explanation: In the given code, the except block is catching the FileNotFoundError exception. This
exception occurs when the file specified in the open() function does not exist or cannot be found.
3. Answer: A) IndexError
Explanation: In the given code, the except block is catching the IndexError exception. This exception
occurs when trying to access an index that is out of range in a list. For example, if the user enters an
index greater than the length of the list data, it will raise an IndexError.
Logging and debugging are tools to help you improve the quality of your software and ensure that it runs
smoothly.
Logging allows you to track application behavior, monitor performance, and diagnose problems, while
debugging helps you identify and fix errors in your code. Together, these tools can help you create more reliable
and efficient software that meets the needs of your users.
By using logging and debugging effectively, you can gain greater insight into how your software works, identify
areas for improvement, and resolve issues quickly and efficiently. This can save you time, money, and
headaches in the long run, while also improving the overall user experience of your software.
Logging:
Logging is the process of recording events and messages in software applications to help developers understand
what is happening during program execution. It's like keeping a detailed journal of everything that happens,
from the moment the application starts running to when it stops. Just like a journal helps you remember what
you did and when you did it, logging helps developers understand what the application did and when it did it, as
well as any errors or issues that may have occurred.
Logging can be used to track application behavior, monitor performance, and diagnose problems. Developers
can use logging to understand how the application is being used, what parts of the code are being executed, and
how long each step is taking. This information can be invaluable in identifying bottlenecks and optimizing
performance.
In Python, logging is implemented using the built-in logging module. Here's a basic example of how to use the
logging module to log messages in Python:
import logging # This is how we call premade libraries. You will
learn more.
Debugging:
Debugging is the process of removing bugs, or errors, from software code. It's like being a detective, where the
code is the crime scene, and the bugs are the clues that lead you to the culprit. Just like a detective must use their
skills and intuition to solve a case, a programmer must use their knowledge of coding languages and debugging
tools to find and fix errors in their code. And just like a detective may have to retrace their steps or gather more
evidence to solve a case, a programmer may have to test different scenarios or gather more data to identify and
resolve a bug.
Debug the program given below and correct the errors. The program should ask the user to enter the grades of
five subjects, calculate the average grade, and print it out.
grades = []
for i in range(5):
grade = int(input("Enter the grade for subject " + str(i+1) + ":"))
grades.append(grade)
# 2. Name errors
a = 5
print(z)
NameError: name 'z' is not defined
# 3. Index errors
a = [1, 2, 3]
print(a[3])
IndexError: list index out of range
# 4. Assertion errors
x = 5
assert x > 10, "x should be greater than 10"
AssertionError: x should be greater than 10
try:
print(1/0)
except ZeroDivisionError:
print("Cannot divide by zero!")