Python for DA & BA — Complete Notes
PYTHON FOR DATA ANALYST
& BUSINESS ANALYST
Complete Structured Notes — 30 Phases
From Python Fundamentals to Capstone Analytics Projects
Page 1 of 60
Python for DA & BA — Complete Notes
Table of Contents
Page 2 of 60
Python for DA & BA — Complete Notes
PHASE 1: Python Fundamentals
Python is a high-level, interpreted, general-purpose programming language known for its simple,
readable syntax. It is the most widely used language in Data Analytics and Business Analytics because
of its rich ecosystem of libraries (Pandas, NumPy, Matplotlib) and gentle learning curve.
1.1 What is Python?
• Created by Guido van Rossum, first released in 1991.
• High-level language: abstracts away memory management and hardware details.
• Interpreted language: code executes line-by-line via the Python interpreter (no separate
compilation step).
• Dynamically typed: variable types are determined at runtime, not declared in advance.
• Multi-paradigm: supports procedural, object-oriented, and functional programming styles.
1.2 Key Features
• Easy to read and write - close to plain English syntax.
• Free and open source with a huge global community.
• Extensive standard library ('batteries included') plus third-party packages via pip.
• Portable - runs on Windows, macOS, and Linux without modification.
• Extensible - can be integrated with C, C++, Java, and used to glue other systems together.
1.3 Applications in Data & Business Analytics
• Data cleaning and transformation using Pandas and NumPy.
• Statistical analysis and hypothesis testing using SciPy/Statsmodels.
• Data visualization using Matplotlib, Seaborn, and Plotly.
• Automating Excel reports, dashboards, and recurring business reports.
• Connecting to databases (SQL) and APIs to pull business data.
1.4 Installing Python & IDEs
• Download the latest stable release from [Link] (Windows/macOS/Linux installers
available).
• During installation on Windows, tick 'Add Python to PATH'.
• Verify installation using the terminal command shown below.
• IDEs commonly used: VS Code (lightweight, extensible), Jupyter Notebook (cell-based, ideal
for data analysis), PyCharm (full-featured IDE).
Example:
python --version
pip --version
# Launch the interactive interpreter
python
Page 3 of 60
Python for DA & BA — Complete Notes
>>> print('Hello, Data Analyst!')
1.5 Running Python Programs
• Script mode: save code in a .py file and run it with 'python [Link]'.
• Interactive mode: type commands directly into the Python shell for quick testing.
• Notebook mode: run code in individual 'cells' inside Jupyter Notebook, ideal for exploratory
data analysis.
Example:
# save as [Link], then run: python [Link]
print('Running from a script file')
1.6 Comments
• Single-line comments start with a '#' symbol.
• Multi-line comments are written using triple-quoted strings (also used as docstrings).
• Comments are ignored by the interpreter and exist purely to document code for humans.
Example:
# This is a single-line comment
"""
This is a multi-line comment / docstring
used to describe what a function or script does.
"""
print('Comments help make code readable') # inline comment
Key Points & Interview Notes:
• Understand the difference between interpreted and compiled languages.
• Be comfortable installing packages using pip install <package_name>.
• Practice writing and running at least 5 small scripts before moving to Phase 2.
• Common interview question: 'Why is Python popular for Data Science?' - readability, libraries,
community support.
Page 4 of 60
Python for DA & BA — Complete Notes
PHASE 2: Variables & Data Types
Variables are named references to values stored in memory. Python is dynamically typed, meaning
you do not need to declare a variable's type explicitly - the interpreter infers it automatically based on
the assigned value.
2.1 Variables & Naming Rules
• A variable is created the moment you assign a value to it, e.g. x = 10.
• Names must start with a letter or underscore, followed by letters, digits, or underscores.
• Names are case-sensitive (age and Age are different variables).
• Cannot use Python reserved keywords (if, for, class, etc.) as variable names.
• Convention: use snake_case for variable names (total_sales, not TotalSales).
Example:
total_sales = 15000 # integer
avg_price = 249.99 # float
customer_name = 'Aarav' # string
is_active = True # boolean
x = y = z = 100 # multiple assignment
a, b, c = 1, 2, 3 # unpacking assignment
2.2 Memory Allocation & Dynamic Typing
• Every value in Python is an object stored in memory; a variable is simply a label pointing to that
object.
• Use id() to check the memory address (identity) of an object.
• Because typing is dynamic, the same variable name can be reassigned to a different data type
during execution.
• Python uses reference counting plus a garbage collector to automatically free memory that is no
longer referenced.
Example:
x = 10
print(id(x))
x = 'now a string' # dynamic typing - type changes at runtime
print(type(x)) # <class 'str'>
2.3 Core Data Types
• int - whole numbers, e.g. 10, -5, 2024.
• float - decimal numbers, e.g. 3.14, -0.5.
• complex - numbers with a real and imaginary part, e.g. 2 + 3j.
• bool - True or False, internally a subclass of int (True == 1).
• str - sequence of characters enclosed in quotes.
Page 5 of 60
Python for DA & BA — Complete Notes
• NoneType - represents the absence of a value (None).
Example:
a = 10 # int
b = 10.5 # float
c = 3 + 4j # complex
d = True # bool
e = 'Sales' # str
f = None # NoneType
print(type(a), type(b), type(c), type(d), type(e), type(f))
Key Points & Interview Notes:
• Use type() to check a variable's data type and id() to check its memory address.
• None is not the same as 0, False, or an empty string - it represents 'no value'.
• Common interview question: 'Is Python statically or dynamically typed?' - dynamically typed.
• Practice: write a script that stores your name, age, salary, and employment status in
appropriately typed variables.
Page 6 of 60
Python for DA & BA — Complete Notes
PHASE 3: Type Conversion
Type conversion (type casting) is the process of converting a value from one data type to another.
Python supports both implicit conversion (done automatically) and explicit conversion (done manually
using built-in functions).
3.1 Implicit Type Conversion
• Python automatically converts a smaller/lower data type to a larger/compatible type to avoid
data loss.
• Common example: int is automatically converted to float when combined in an arithmetic
expression.
• No explicit function call is required; the interpreter handles it internally.
Example:
a = 5 # int
b = 2.5 # float
c = a + b # int automatically converted to float
print(c, type(c)) # 7.5 <class 'float'>
3.2 Explicit Type Conversion
• int(x) - converts x to an integer (truncates decimals, parses numeric strings).
• float(x) - converts x to a floating-point number.
• str(x) - converts x to its string representation.
• bool(x) - converts x to True/False (0, None, empty collections are False; everything else is
True).
• list(x), tuple(x), dict(x) - convert compatible iterables into the respective collection type.
Example:
print(int('25')) # 25
print(float('3.14')) # 3.14
print(str(100)) # '100'
print(bool(0), bool(5)) # False True
print(list('abc')) # ['a', 'b', 'c']
print(tuple([1, 2, 3])) # (1, 2, 3)
print(dict([('a', 1), ('b', 2)])) # {'a': 1, 'b': 2}
Key Points & Interview Notes:
• Explicit conversion of a non-numeric string, e.g. int('abc'), raises a ValueError.
• bool(0) and bool('') are False; bool(' ') (a space) is True because the string is not empty.
• Interview tip: know which values are 'falsy' in Python - 0, 0.0, '', [], {}, (), None, False.
Page 7 of 60
Python for DA & BA — Complete Notes
PHASE 4: Input & Output and String Formatting
Programs need to interact with users and display results clearly. Python provides input() to read data
from the user and print() to display output, along with several string formatting techniques for
producing clean, business-ready output.
4.1 input() and print()
• input('prompt') displays a prompt and returns whatever the user types, always as a string.
• Numeric input must be explicitly converted, e.g. int(input('Enter age: ')).
• print() accepts multiple comma-separated values, and keyword arguments sep and end control
formatting.
Example:
name = input('Enter customer name: ')
age = int(input('Enter age: '))
print('Name:', name, 'Age:', age, sep=' | ', end='.\n')
4.2 String Formatting - f-strings, format(), %
• f-strings (Python 3.6+): prefix a string with f and embed expressions directly in {} - the modern,
recommended approach.
• [Link](): placeholders {} in the string are filled using the .format() method - flexible and
works in older Python versions.
• % operator (printf-style): legacy formatting inherited from C, still seen in older codebases.
• All three support width, precision, and alignment specifiers useful for report formatting.
Example:
sales = 125000.4567
name = 'Ravi'
# f-string (recommended)
print(f'{name} generated sales of {sales:,.2f}')
# .format() method
print('{} generated sales of {:,.2f}'.format(name, sales))
# % operator
print('%s generated sales of %.2f' % (name, sales))
Key Points & Interview Notes:
• Always cast input() results to int/float when doing numeric calculations - a common beginner
bug is treating input as a string.
• f-strings are preferred in modern Python for readability and performance.
• Format specifiers like :,.2f are heavily used in DA/BA reporting for currency and percentage
display.
Page 8 of 60
Python for DA & BA — Complete Notes
Page 9 of 60
Python for DA & BA — Complete Notes
PHASE 5: Operators
Operators are special symbols that perform operations on variables and values. Python groups
operators into several categories, each essential for writing business logic and data conditions.
5.1 Arithmetic, Comparison & Logical Operators
• Arithmetic: + - * / // % ** (// is floor/integer division, ** is exponentiation).
• Comparison: == != > < >= <= - return a boolean result.
• Logical: and, or, not - combine boolean expressions.
Example:
revenue = 50000
cost = 32000
profit = revenue - cost
margin = profit / revenue
print(profit, round(margin * 100, 2))
is_profitable = profit > 0 and margin > 0.1
print(is_profitable)
5.2 Assignment, Membership & Identity Operators
• Assignment: = += -= *= /= //= %= **= - shorthand for updating a variable in place.
• Membership: in, not in - check if a value exists within a sequence (list, string, dict keys).
• Identity: is, is not - check whether two variables reference the exact same object in memory (not
just equal value).
Example:
total = 100
total += 50 # total = total + 50 -> 150
regions = ['North', 'South', 'East']
print('North' in regions) # True
a = [1, 2, 3]
b = a
c = [1, 2, 3]
print(a is b) # True - same object
print(a is c) # False - equal value, different object
print(a == c) # True - values are equal
5.3 Bitwise Operators & Operator Precedence
• Bitwise operators (&, |, ^, ~, <<, >>) operate on the binary representation of integers - rarely
used in day-to-day analytics but common in interviews.
• Operator precedence determines evaluation order: parentheses > exponent >
multiplication/division > addition/subtraction > comparison > logical.
Page 10 of 60
Python for DA & BA — Complete Notes
• When in doubt, use parentheses to make evaluation order explicit and code readable.
Example:
print(5 & 3) # bitwise AND -> 1
print(5 | 3) # bitwise OR -> 7
print(5 ^ 3) # bitwise XOR -> 6
print(5 << 1) # left shift -> 10
result = 10 + 2 * 3 ** 2 # ** first, then *, then +
print(result) # 28
Key Points & Interview Notes:
• '==' compares values; 'is' compares object identity - a frequent interview question.
• Floor division (//) always rounds toward negative infinity, e.g. -7 // 2 = -4.
• Practice writing at least 5 compound conditions combining comparison and logical operators.
Page 11 of 60
Python for DA & BA — Complete Notes
PHASE 6: Control Flow - Conditionals & Loops
Control flow statements let a program make decisions and repeat actions. This is the foundation for
building any business logic - discount rules, KPI thresholds, or iterating through customer records.
6.1 Decision Making: if / elif / else
• if executes a block only when its condition is True.
• elif (else-if) checks additional conditions if the previous ones were False.
• else runs when none of the preceding conditions are True.
• Conditions can be nested inside one another for multi-level business rules.
Example:
score = 78
if score >= 90:
grade = 'A'
elif score >= 75:
grade = 'B'
elif score >= 60:
grade = 'C'
else:
grade = 'D'
print(grade) # B
6.2 for and while Loops
• for loop iterates over a sequence (list, string, range, dict) - use when the number of iterations is
known or based on a collection.
• while loop repeats as long as a condition remains True - use when the number of iterations is
not known in advance.
• range(start, stop, step) generates a sequence of numbers commonly used with for loops.
Example:
sales = [200, 450, 300, 150]
total = 0
for s in sales:
total += s
print('Total sales:', total)
count = 0
while count < 5:
print('Iteration', count)
count += 1
6.3 break, continue, pass & Nested Loops
• break immediately exits the loop entirely.
• continue skips the rest of the current iteration and moves to the next one.
Page 12 of 60
Python for DA & BA — Complete Notes
• pass is a no-op placeholder used where syntax requires a statement but no action is needed.
• Nested loops (a loop inside another loop) are used for tasks like comparing every pair of items
or building matrices/patterns.
Example:
for i in range(10):
if i == 3:
continue # skip 3
if i == 7:
break # stop at 7
print(i)
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end=' ')
print()
6.4 Pattern Problems
• Star patterns, number patterns, and pyramid patterns are classic beginner exercises that build
fluency with nested loops.
• The key skill is mapping each row and column index to what should be printed.
Example:
# Pyramid pattern (5 rows)
rows = 5
for i in range(1, rows + 1):
print(' ' * (rows - i) + '*' * (2 * i - 1))
Key Points & Interview Notes:
• for...else and while...else exist in Python - the else block runs only if the loop completes without
hitting a break.
• Common interview task: FizzBuzz - print 'Fizz' for multiples of 3, 'Buzz' for multiples of 5,
'FizzBuzz' for both.
• Practice at least 10 pattern problems (stars, numbers, pyramids) to build loop fluency.
Page 13 of 60
Python for DA & BA — Complete Notes
PHASE 7: Functions
Functions are reusable, named blocks of code that perform a specific task. They are central to writing
clean, maintainable analytics scripts instead of repeating logic everywhere.
7.1 Defining & Calling Functions
• Defined using the def keyword, followed by a name, parentheses for parameters, and a colon.
• The return statement sends a value back to the caller; a function without return implicitly
returns None.
• Functions are called by writing their name followed by parentheses containing any arguments.
Example:
def calculate_profit(revenue, cost):
profit = revenue - cost
return profit
result = calculate_profit(50000, 32000)
print(result) # 18000
7.2 Parameters, Arguments & Scope
• Positional arguments are matched to parameters by order; keyword arguments are matched by
name.
• Default arguments provide a fallback value if the caller does not supply one.
• Local variables exist only inside the function; global variables are defined outside and
accessible everywhere (use the global keyword to modify a global variable from inside a
function).
Example:
def apply_discount(price, discount=0.1):
return price - (price * discount)
print(apply_discount(1000)) # uses default 10%
print(apply_discount(1000, discount=0.2)) # keyword argument, 20%
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
7.3 *args and **kwargs
• *args collects any number of extra positional arguments into a tuple.
• **kwargs collects any number of extra keyword arguments into a dictionary.
Page 14 of 60
Python for DA & BA — Complete Notes
• Useful when the exact number of inputs is not known in advance, e.g. summing an arbitrary list
of monthly sales figures.
Example:
def total_sales(*args):
return sum(args)
print(total_sales(100, 200, 300)) # 600
def employee_info(**kwargs):
for key, value in [Link]():
print(f'{key}: {value}')
employee_info(name='Sita', role='Analyst', salary=60000)
7.4 Lambda, Recursive & Anonymous Functions
• A lambda function is a small, anonymous, single-expression function defined with the lambda
keyword - useful for short throwaway operations, e.g. inside sort() or map().
• A recursive function calls itself to solve a problem by breaking it into smaller sub-problems; it
must have a base case to stop recursion.
Example:
square = lambda x: x ** 2
print(square(5)) # 25
def factorial(n):
if n == 0: # base case
return 1
return n * factorial(n - 1) # recursive case
print(factorial(5)) # 120
Key Points & Interview Notes:
• A function should ideally do one thing well (single responsibility principle).
• Mutable default arguments (e.g. def f(x=[])) are a classic Python gotcha - the same list persists
across calls.
• Common interview question: difference between *args and **kwargs, and when recursion is
preferred over iteration.
Page 15 of 60
Python for DA & BA — Complete Notes
PHASE 8: Strings
Strings are immutable sequences of characters and one of the most heavily used data types in data
cleaning - customer names, addresses, product codes, and free-text fields all require string
manipulation.
8.1 Indexing, Slicing & Traversing
• Indexing accesses a single character using square brackets; Python supports negative indexing
from the end.
• Slicing string[start:stop:step] extracts a substring; stop is exclusive.
• Strings can be traversed character-by-character using a for loop.
Example:
text = 'DataAnalyst'
print(text[0]) # 'D'
print(text[-1]) # 't'
print(text[0:4]) # 'Data'
print(text[::-1]) # reversed string: 'tsylanAataD'
for ch in text[:4]:
print(ch)
8.2 Common String Methods
• upper(), lower(), title() - change case for standardizing text data.
• strip() - removes leading/trailing whitespace (very common when cleaning imported data).
• replace(old, new) - substitutes occurrences of a substring.
• split(delimiter) and join(iterable) - break a string into a list, or combine a list into a string.
• startswith(), endswith(), count(), find(), index() - search and pattern checks.
Example:
raw = ' Sales_Report_2024.csv '
clean = [Link]()
print([Link]())
parts = [Link]('_')
print(parts) # ['Sales', 'Report', '[Link]']
print('-'.join(parts)) # '[Link]'
print([Link]('Sales_'))
print([Link]('_'))
8.3 Classic String Interview Problems
• Reverse a string, check for palindrome, check for anagram.
• Count character frequency, remove duplicate characters, count vowels, find the longest word in
a sentence.
Example:
Page 16 of 60
Python for DA & BA — Complete Notes
def is_palindrome(s):
s = [Link]().replace(' ', '')
return s == s[::-1]
print(is_palindrome('Was it a car or a cat I saw')) # True
def char_frequency(s):
freq = {}
for ch in s:
freq[ch] = [Link](ch, 0) + 1
return freq
print(char_frequency('analyst'))
Key Points & Interview Notes:
• Strings are immutable - methods like replace() and upper() return a NEW string rather than
modifying the original.
• f-strings, .strip(), and .split() are the three most-used string tools in real-world data cleaning.
• Practice all 7 classic string problems listed above; they appear frequently in DA/BA coding
interviews.
Page 17 of 60
Python for DA & BA — Complete Notes
PHASE 9: Lists
Lists are ordered, mutable collections that can hold items of mixed data types. They are the most
flexible and commonly used data structure in Python for storing rows of data, results, and intermediate
calculations.
9.1 Creating, Indexing & Slicing
• Lists are created using square brackets [] and can contain any mix of data types.
• Indexing and slicing work the same way as with strings.
• Lists can be nested to represent tabular/matrix-like data.
Example:
sales = [1200, 1500, 900, 1750, 1100]
print(sales[0], sales[-1])
print(sales[1:4]) # [1500, 900, 1750]
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2]) # 6
9.2 List Methods
• append(x) - adds a single item to the end; extend(iterable) - adds multiple items.
• insert(index, x) - inserts at a specific position; remove(x) - removes the first matching value.
• pop(index) - removes and returns an item (default: last); clear() - empties the list.
• sort() sorts in place; sorted(list) returns a new sorted list; reverse() reverses in place; copy()
creates a shallow copy.
Example:
[Link](2000)
[Link]([1300, 1400])
[Link]()
print(sales)
top = [Link]() # removes and returns last element
print(top, sales)
9.3 List Comprehension
• A concise, Pythonic way to build a new list by applying an expression to each item of an
iterable, optionally with a filter condition.
• General form: [expression for item in iterable if condition].
• Nested list comprehensions can flatten or build matrices in a single line.
Example:
sales = [1200, 1500, 900, 1750, 1100]
high_sales = [s for s in sales if s > 1200]
print(high_sales) # [1500, 1750]
Page 18 of 60
Python for DA & BA — Complete Notes
discounted = [round(s * 0.9, 2) for s in sales]
print(discounted)
flat = [num for row in [[1, 2], [3, 4]] for num in row]
print(flat) # [1, 2, 3, 4]
9.4 Classic List Problems
• Find the largest and second-largest number without using max()/sorted() directly.
• Merge two lists, rotate a list by k positions, remove duplicates while preserving order.
Example:
def second_largest(nums):
unique = list(set(nums))
[Link]()
return unique[-2]
print(second_largest([10, 20, 4, 45, 99])) # 45
def rotate_list(lst, k):
k = k % len(lst)
return lst[-k:] + lst[:-k]
print(rotate_list([1, 2, 3, 4, 5], 2)) # [4, 5, 1, 2, 3]
Key Points & Interview Notes:
• Lists are mutable - be careful with 'list_b = list_a', which copies the reference, not the values;
use .copy() or list() for an independent copy.
• List comprehensions are generally faster and more readable than equivalent for-loops that build
a list.
• Time complexity: append() is O(1); insert() and remove() are O(n) because elements must shift.
Page 19 of 60
Python for DA & BA — Complete Notes
PHASE 10: Tuples
A tuple is an ordered, immutable collection. Once created, its contents cannot be changed, which
makes tuples useful for fixed data such as coordinates, database records, or function returns with
multiple values.
10.1 Creating, Packing & Unpacking
• Tuples are created using parentheses () or simply by separating values with commas.
• Packing: combining multiple values into a single tuple; unpacking: extracting tuple values into
separate variables.
• A single-element tuple requires a trailing comma, e.g. (5,) - without it, (5) is just an integer.
Example:
point = (10, 20) # packing
x, y = point # unpacking
print(x, y) # 10 20
single = (5,)
print(type(single)) # <class 'tuple'>
10.2 Tuple Methods & Immutability
• Tuples support only count() and index() since they cannot be modified after creation.
• Immutability makes tuples hashable, so they can be used as dictionary keys or set elements
(unlike lists).
• Use tuples when data should not change and lists when data needs to grow or be modified.
Example:
coordinates = (12.9, 77.5)
print([Link](12.9))
print([Link](77.5))
locations = {(28.6, 77.2): 'Delhi Office', (19.0, 72.8): 'Mumbai Office'}
print(locations[(28.6, 77.2)])
Key Points & Interview Notes:
• Tuples are typically faster than lists for iteration and use slightly less memory.
• When a function needs to return multiple values, Python packs them into a tuple automatically.
• Interview question: 'Why use a tuple instead of a list?' - immutability, hashability, and signaling
that data should not change.
Page 20 of 60
Python for DA & BA — Complete Notes
PHASE 11: Sets
A set is an unordered collection of unique, hashable elements. Sets are ideal for tasks like removing
duplicates and performing mathematical operations such as union, intersection, and difference - very
common when comparing two customer lists or product catalogs.
11.1 Creating Sets & Set Methods
• Sets are created using curly braces {} or the set() constructor (an empty {} creates a dict, not a
set).
• add(x) inserts a single element; remove(x) removes an element and raises an error if absent;
discard(x) removes silently if present.
• pop() removes an arbitrary element; clear() empties the set.
Example:
region_a = {'Delhi', 'Mumbai', 'Pune'}
region_a.add('Chennai')
region_a.discard('Pune')
print(region_a)
11.2 Set Operations
• Union (| or .union()) - combines all unique elements from both sets.
• Intersection (& or .intersection()) - elements common to both sets.
• Difference (- or .difference()) - elements in the first set but not the second.
• Symmetric Difference (^) - elements in either set but not in both.
• A frozenset is an immutable version of a set, usable as a dictionary key.
Example:
region_a = {'Delhi', 'Mumbai', 'Chennai'}
region_b = {'Mumbai', 'Pune', 'Kolkata'}
print(region_a | region_b) # union
print(region_a & region_b) # intersection -> {'Mumbai'}
print(region_a - region_b) # difference -> {'Delhi','Chennai'}
print(region_a ^ region_b) # symmetric difference
frozen = frozenset(region_a)
Key Points & Interview Notes:
• Sets automatically remove duplicates - a quick way to de-duplicate a list is list(set(my_list)).
• Membership testing ('x in my_set') is O(1) on average for sets, much faster than O(n) for lists.
• Sets are unordered - do not rely on the order of elements when iterating.
Page 21 of 60
Python for DA & BA — Complete Notes
PHASE 12: Dictionaries
A dictionary stores data as key-value pairs and is one of the most important data structures for data
analysts - it naturally represents records, JSON data, and lookup tables (e.g. mapping product ID to
product name).
12.1 Creating & Accessing Dictionaries
• Created using curly braces with key: value pairs, or the dict() constructor.
• Values are accessed via square brackets (raises KeyError if missing) or the safer .get(key,
default).
• Keys must be unique and hashable (strings, numbers, tuples); values can be any type.
Example:
employee = {'name': 'Meera', 'role': 'Analyst', 'salary': 65000}
print(employee['name'])
print([Link]('bonus', 0)) # returns 0 if key not found
12.2 Dictionary Methods
• keys(), values(), items() - return views of the keys, values, or key-value pairs for iteration.
• update(other_dict) - merges another dictionary in, overwriting duplicate keys.
• pop(key) - removes a key and returns its value; popitem() - removes the last inserted item.
• Dictionary comprehension: {key_expr: value_expr for item in iterable} builds dictionaries
concisely.
Example:
employee['bonus'] = 5000
[Link]({'department': 'Analytics'})
for key, value in [Link]():
print(key, '->', value)
prices = {'apple': 100, 'banana': 40, 'mango': 150}
discounted = {item: price * 0.9 for item, price in [Link]()}
print(discounted)
12.3 Classic Dictionary Problems
• Word count / frequency counter from a sentence or list.
• Building a small 'student database' as a dictionary of dictionaries.
Example:
text = 'data is the new oil and data is powerful'
word_count = {}
for word in [Link]():
word_count[word] = word_count.get(word, 0) + 1
Page 22 of 60
Python for DA & BA — Complete Notes
print(word_count)
students = {
'S001': {'name': 'Aman', 'marks': 88},
'S002': {'name': 'Priya', 'marks': 92}
}
print(students['S002']['marks'])
Key Points & Interview Notes:
• Since Python 3.7, dictionaries preserve insertion order by default.
• Use .get() instead of square brackets when a key might be missing, to avoid a KeyError crash.
• Dictionaries and JSON map almost one-to-one, making them essential when working with
APIs.
Page 23 of 60
Python for DA & BA — Complete Notes
PHASE 13: File Handling
Data analysts constantly read data from and write data to files - text files, CSVs, and JSON. Python's
built-in file handling functions, together with the 'with' statement, make this safe and efficient.
13.1 Reading, Writing & Appending Files
• open(filename, mode) opens a file: 'r' read, 'w' write (overwrites), 'a' append, 'x' create.
• The 'with' statement automatically closes the file even if an error occurs - always preferred over
manually calling open()/close().
• read(), readline(), and readlines() retrieve file contents in different granularities; write() and
writelines() output data.
Example:
with open('[Link]', 'w') as f:
[Link]('Monthly Sales Report\n')
[Link]('Total Sales: 50000\n')
with open('[Link]', 'r') as f:
content = [Link]()
print(content)
with open('[Link]', 'a') as f:
[Link]('Generated using Python\n')
13.2 Working with CSV and JSON Files
• The csv module reads/writes comma-separated files row by row using [Link] and [Link]
(or DictReader/DictWriter for header-based access).
• The json module converts between JSON text and Python dictionaries/lists using
[Link]()/[Link]() (read) and [Link]()/[Link]() (write).
• In practice, Pandas (Phase 16) is typically used for CSV work in analytics, but the csv module is
important for lightweight scripts and interviews.
Example:
import csv
with open('[Link]', 'w', newline='') as f:
writer = [Link](f)
[Link](['Product', 'Sales'])
[Link](['Laptop', 1200])
import json
data = {'product': 'Laptop', 'sales': 1200}
with open('[Link]', 'w') as f:
[Link](data, f)
with open('[Link]', 'r') as f:
loaded = [Link](f)
print(loaded['product'])
Page 24 of 60
Python for DA & BA — Complete Notes
Key Points & Interview Notes:
• Always use 'with open(...) as f' rather than manual open()/close() to avoid leaving files locked or
corrupted.
• newline='' should be passed to open() when writing CSV files on Windows to prevent extra
blank rows.
• Interview tip: know the difference between [Link] (file object) and [Link] (string).
Page 25 of 60
Python for DA & BA — Complete Notes
PHASE 14: Exception Handling
Real-world data is messy - missing files, wrong data types, divide-by-zero errors. Exception handling
lets a program respond to errors gracefully instead of crashing, which is critical for robust automation
and reporting scripts.
14.1 try / except / else / finally
• Code that might fail is placed inside a try block.
• except catches and handles a specific (or general) exception type.
• else runs only if no exception occurred; finally always runs, useful for cleanup (e.g. closing a
file or connection).
• Multiple except blocks can handle different error types differently.
Example:
try:
value = int(input('Enter a number: '))
result = 100 / value
except ValueError:
print('Please enter a valid number')
except ZeroDivisionError:
print('Cannot divide by zero')
else:
print('Result:', result)
finally:
print('Execution complete')
14.2 raise & Custom Exceptions
• raise manually triggers an exception, useful for enforcing business rules (e.g. negative sales
values should never occur).
• Custom exceptions are created by subclassing the built-in Exception class, letting you define
domain-specific error types.
Example:
class NegativeSalesError(Exception):
pass
def record_sale(amount):
if amount < 0:
raise NegativeSalesError('Sales amount cannot be negative')
return amount
try:
record_sale(-500)
except NegativeSalesError as e:
print('Error:', e)
Key Points & Interview Notes:
Page 26 of 60
Python for DA & BA — Complete Notes
• Catch the most specific exception possible instead of a bare 'except:' which can hide bugs.
• finally is commonly used to close database connections or files regardless of success or failure.
• Interview question: 'When would you create a custom exception?' - when a built-in exception
does not clearly express a domain-specific business rule violation.
Page 27 of 60
Python for DA & BA — Complete Notes
PHASE 15: Modules & Packages
Modules let you organize and reuse code across files, while packages group related modules together.
Python's standard library ships with many modules that are extremely useful for data analysis tasks.
15.1 import, from...import & Aliasing
• import module_name loads an entire module; access its contents with module_name.function().
• from module_name import function imports a specific function/class directly into your
namespace.
• Aliasing (import module as alias) shortens frequently used module names, e.g. 'import pandas as
pd'.
Example:
import math
print([Link](16))
from statistics import mean
print(mean([10, 20, 30]))
import numpy as np # common aliasing convention
15.2 Key Built-in Modules for Analytics
• math - mathematical functions (sqrt, floor, ceil, log, factorial).
• random - generate random numbers, sample data, shuffle lists (useful for simulations, train/test
splitting).
• os - interact with the operating system (file paths, directories, environment variables).
• datetime & time - work with dates, times, and durations - essential for time-series business data.
• statistics - basic statistical functions (mean, median, mode, stdev) without needing NumPy.
• collections - specialized containers like Counter, defaultdict, and namedtuple.
• itertools - efficient looping tools like permutations, combinations, and product.
Example:
import random
print([Link](1, 100))
print([Link](range(1, 50), 6)) # e.g. lottery draw
from datetime import datetime, timedelta
today = [Link]()
print([Link]('%Y-%m-%d'))
print(today + timedelta(days=30))
from collections import Counter
print(Counter(['a', 'b', 'a', 'c', 'a']))
Key Points & Interview Notes:
Page 28 of 60
Python for DA & BA — Complete Notes
• A package is simply a directory containing an __init__.py file and multiple related modules.
• pip install <package> is used to install third-party packages not in the standard library (e.g.
pandas, numpy, requests).
• [Link] is extremely handy for quick frequency analysis in interviews and real work
alike.
Page 29 of 60
Python for DA & BA — Complete Notes
PHASE 16: Object-Oriented Programming (OOP)
OOP organizes code around 'objects' that bundle data (attributes) and behavior (methods). While much
day-to-day analytics code is procedural/functional, understanding OOP is essential for reading library
source code, building reusable analysis pipelines, and interviews.
16.1 Classes, Objects & Constructors
• A class is a blueprint; an object (instance) is a specific realization of that blueprint.
• __init__() is the constructor - it runs automatically when an object is created and initializes
instance attributes.
• self refers to the specific instance calling the method and must be the first parameter of every
instance method.
Example:
class Employee:
def __init__(self, name, salary):
[Link] = name # instance variable
[Link] = salary
def annual_salary(self):
return [Link] * 12
e1 = Employee('Rohit', 55000)
print([Link], e1.annual_salary())
16.2 Instance vs Class Variables, Encapsulation
• Instance variables are unique to each object ([Link]); class variables are shared across all
instances of the class.
• Encapsulation restricts direct access to internal data using naming conventions - a single
underscore (_var) signals 'protected', double underscore (__var) triggers name-mangling for
'private' attributes.
• Getter/setter methods (or @property) provide controlled access to encapsulated attributes.
Example:
class Company:
industry = 'Technology' # class variable, shared by all instances
def __init__(self, name):
[Link] = name # instance variable
self.__revenue = 0 # 'private' attribute
def set_revenue(self, value):
if value >= 0:
self.__revenue = value
def get_revenue(self):
return self.__revenue
Page 30 of 60
Python for DA & BA — Complete Notes
16.3 Inheritance, Polymorphism & super()
• Inheritance lets a child class reuse and extend the attributes/methods of a parent class.
• super() calls the parent class's methods, commonly used inside __init__ to reuse the parent's
initialization logic.
• Polymorphism allows different classes to define methods with the same name but different
behavior; method overriding lets a subclass replace a parent method entirely.
Example:
class Person:
def __init__(self, name):
[Link] = name
def describe(self):
return f'{[Link]} is a person'
class Analyst(Person): # inheritance
def __init__(self, name, tool):
super().__init__(name) # reuse parent constructor
[Link] = tool
def describe(self): # method overriding (polymorphism)
return f'{[Link]} is a Data Analyst skilled in {[Link]}'
p = Analyst('Kavya', 'Python')
print([Link]())
16.4 Abstraction, Static/Class Methods & Magic Methods
• Abstraction hides complex implementation details and exposes only necessary functionality,
often via abstract base classes (module abc).
• @staticmethod defines a method that doesn't need access to self or the class - a utility function
grouped inside a class.
• @classmethod receives the class itself (cls) rather than an instance - often used as an alternative
constructor.
• Magic (dunder) methods like __str__, __len__, __add__ let custom objects work with built-in
functions and operators.
Example:
class Report:
def __init__(self, title):
[Link] = title
def __str__(self): # magic method
return f'Report: {[Link]}'
@staticmethod
def disclaimer():
return 'Confidential Business Document'
Page 31 of 60
Python for DA & BA — Complete Notes
r = Report('Q3 Sales')
print(r) # uses __str__ -> 'Report: Q3 Sales'
print([Link]())
Key Points & Interview Notes:
• The four pillars of OOP: Encapsulation, Inheritance, Polymorphism, Abstraction (frequently
asked interview question).
• self is a convention, not a keyword - any name would technically work, but always use 'self'.
• Method overriding is resolved at runtime (dynamic dispatch), enabling polymorphism.
Page 32 of 60
Python for DA & BA — Complete Notes
PHASE 17: Advanced Python
These advanced concepts explain how Python works 'under the hood' and enable memory-efficient,
elegant code - especially important when processing large datasets that don't fit comfortably in
memory.
17.1 Iterators & Generators
• An iterator is any object implementing __iter__() and __next__(), allowing it to be looped over.
• A generator is a simpler way to create an iterator using a function with the yield keyword -
values are produced lazily, one at a time, saving memory.
• Generator expressions (similar to list comprehensions but with parentheses) create generators
concisely.
Example:
def sales_generator(data):
for value in data:
yield value * 1.1 # apply 10% growth lazily
gen = sales_generator([1000, 2000, 3000])
for val in gen:
print(val)
squares = (x ** 2 for x in range(5)) # generator expression
print(list(squares))
17.2 Decorators & Closures
• A closure is a function that remembers variables from its enclosing scope even after that scope
has finished executing.
• A decorator is a function that wraps another function to extend its behavior without modifying
its source code - widely used for logging, timing, and access control.
Example:
def multiplier(factor): # closure
def multiply(x):
return x * factor
return multiply
double = multiplier(2)
print(double(10)) # 20
def log_execution(func): # decorator
def wrapper(*args, **kwargs):
print(f'Running {func.__name__}')
return func(*args, **kwargs)
return wrapper
@log_execution
def compute_total(sales):
return sum(sales)
Page 33 of 60
Python for DA & BA — Complete Notes
print(compute_total([100, 200, 300]))
17.3 Context Managers & Functional Tools
• A context manager (used with 'with') ensures setup/teardown logic runs automatically - files and
database connections are common examples.
• map(func, iterable) applies a function to every item; filter(func, iterable) keeps items where the
function returns True; [Link] accumulates a single result.
• zip() pairs up elements from multiple iterables; enumerate() adds an index while looping;
any()/all() test conditions across an iterable.
Example:
from functools import reduce
sales = [100, 200, 300, 400]
doubled = list(map(lambda x: x * 2, sales))
high = list(filter(lambda x: x > 150, sales))
total = reduce(lambda a, b: a + b, sales)
print(doubled, high, total)
names = ['Q1', 'Q2', 'Q3']
for idx, (period, value) in enumerate(zip(names, sales)):
print(idx, period, value)
print(any(s > 350 for s in sales), all(s > 0 for s in sales))
Key Points & Interview Notes:
• Generators are memory-efficient because they produce one value at a time instead of storing the
entire sequence.
• Decorators are heavily used in web frameworks (Flask/Django) and testing - understanding
them deeply helps read production code.
• Interview tip: be ready to explain 'What is the difference between a generator and an iterator?' -
every generator is an iterator, but not every iterator is a generator.
Page 34 of 60
Python for DA & BA — Complete Notes
PHASE 18: NumPy
NumPy (Numerical Python) is the foundational library for numerical computing in Python. It
introduces the ndarray, a fast, memory-efficient multi-dimensional array, and underpins Pandas,
Matplotlib, and most of the data science stack.
18.1 Arrays, Dimensions & Shape
• Arrays are created using [Link]() from a list or nested list; [Link](), [Link](), [Link](),
and [Link]() create arrays programmatically.
• ndim gives the number of dimensions, shape gives the size along each dimension, and reshape()
changes an array's shape without changing its data.
• Unlike Python lists, NumPy arrays are homogeneous (all elements share one data type) and
support vectorized operations.
Example:
import numpy as np
arr = [Link]([[1, 2, 3], [4, 5, 6]])
print([Link], [Link], [Link]) # 2 (2, 3) int64
reshaped = [Link](3, 2)
print(reshaped)
zeros = [Link]((2, 3))
seq = [Link](0, 10, 2) # [0 2 4 6 8]
18.2 Indexing, Slicing & Broadcasting
• NumPy supports advanced indexing: boolean masks, fancy indexing with lists of indices, and
multi-dimensional slicing.
• Broadcasting allows arithmetic operations between arrays of different (but compatible) shapes
without explicit loops - e.g. adding a scalar to every element.
• Universal functions (ufuncs) like [Link], [Link], [Link] apply element-wise operations
efficiently.
Example:
sales = [Link]([100, 250, 400, 150, 300])
print(sales[sales > 200]) # boolean mask -> [250 400 300]
bonus = sales * 0.1 # broadcasting a scalar
print(bonus)
matrix = [Link]([[1, 2], [3, 4]])
print(matrix + [Link]([10, 20])) # broadcasting a row vector
18.3 Statistics & Linear Algebra with NumPy
Page 35 of 60
Python for DA & BA — Complete Notes
• Aggregate functions: [Link], [Link], [Link], [Link], [Link], [Link], [Link], and their
axis parameter for row/column-wise computation.
• [Link] module generates random numbers, useful for simulations and sampling.
• Basic linear algebra: [Link]() for matrix multiplication, [Link]() for matrix inversion,
[Link]() for determinant.
Example:
data = [Link]([[85, 90], [70, 75], [95, 88]])
print([Link](axis=0)) # column-wise mean
print([Link](axis=1)) # row-wise mean
print([Link](data))
[Link](42)
sample = [Link](1, 100, size=5)
print(sample)
a = [Link]([[1, 2], [3, 4]])
b = [Link]([[5, 6], [7, 8]])
print([Link](a, b))
Key Points & Interview Notes:
• NumPy operations are implemented in C, making them dramatically faster than equivalent pure-
Python loops - this is called 'vectorization'.
• Always prefer vectorized operations (arr * 2) over manual for-loops when working with arrays.
• Interview tip: know the difference between a Python list and a NumPy array - homogeneity,
speed, and support for element-wise math.
Page 36 of 60
Python for DA & BA — Complete Notes
PHASE 19: Pandas
Pandas is the single most important library for data analysts working in Python. It provides the Series
(1D) and DataFrame (2D, table-like) structures, along with a rich toolkit for reading, cleaning,
transforming, and summarizing data.
19.1 Series & DataFrame Basics
• A Series is a one-dimensional labeled array (like a single column); a DataFrame is a two-
dimensional labeled table made of multiple Series.
• DataFrames can be created from dictionaries, lists of lists, or by reading external files (CSV,
Excel).
• head(), tail(), info(), describe(), shape, columns, and dtypes are the first commands used to
explore any new dataset.
Example:
import pandas as pd
data = {
'Product': ['Laptop', 'Mouse', 'Keyboard'],
'Sales': [1200, 300, 450],
'Region': ['North', 'South', 'North']
}
df = [Link](data)
print([Link]())
print([Link]())
print([Link]())
print([Link], [Link]())
19.2 Reading Files, Selection & Filtering
• pd.read_csv('[Link]') and pd.read_excel('[Link]') load external data into a DataFrame.
• Column selection: df['col'] or df[['col1', 'col2']]; row selection: .loc[] (label-based) and .iloc[]
(position-based).
• Boolean filtering: df[df['col'] > value] returns only rows matching the condition; multiple
conditions combine with & (and) / | (or), each wrapped in parentheses.
Example:
df = pd.read_csv('[Link]')
north_sales = df[df['Region'] == 'North']
high_value = df[(df['Sales'] > 400) & (df['Region'] == 'North')]
print([Link][0, 'Product']) # label-based access
print([Link][0, 1]) # position-based access
19.3 Sorting, GroupBy & Aggregation
• sort_values('col', ascending=False) sorts rows by one or more columns.
Page 37 of 60
Python for DA & BA — Complete Notes
• groupby('col') splits data into groups, on which aggregate functions (sum, mean, count, agg) are
then applied - the core 'split-apply-combine' pattern for business reporting.
• agg() allows multiple aggregations at once, optionally with different functions per column.
Example:
df.sort_values('Sales', ascending=False, inplace=True)
region_summary = [Link]('Region')['Sales'].sum()
print(region_summary)
summary = [Link]('Region').agg(
total_sales=('Sales', 'sum'),
avg_sales=('Sales', 'mean'),
orders=('Sales', 'count')
)
print(summary)
19.4 Merge, Join, Concat, Pivot & Crosstab
• [Link](df1, df2, on='key', how='inner') combines two DataFrames on common columns,
similar to a SQL JOIN (how can be 'inner', 'left', 'right', 'outer').
• [Link]([df1, df2]) stacks DataFrames vertically or horizontally.
• pivot_table() reshapes data, summarizing values across two categorical dimensions; crosstab()
computes frequency counts between two categorical variables.
Example:
orders = [Link]({'OrderID': [1, 2], 'CustID': [101, 102]})
customers = [Link]({'CustID': [101, 102], 'Name': ['A', 'B']})
merged = [Link](orders, customers, on='CustID', how='left')
pivot = df.pivot_table(values='Sales', index='Region', aggfunc='sum')
print(pivot)
cross = [Link](df['Region'], df['Product'])
print(cross)
19.5 Missing Values, Duplicates, DateTime & Apply
• isnull()/isna() flags missing data; fillna(value) fills gaps; dropna() removes rows/columns with
missing values.
• duplicated() flags duplicate rows; drop_duplicates() removes them.
• pd.to_datetime() converts a column to datetime type, unlocking .dt accessor features
like .[Link], .[Link].
• apply(func) runs a custom function across rows or columns; map()/replace() perform element-
wise substitutions on a Series.
Example:
Page 38 of 60
Python for DA & BA — Complete Notes
df['Sales'] = df['Sales'].fillna(df['Sales'].mean())
df.drop_duplicates(inplace=True)
df['OrderDate'] = pd.to_datetime(df['OrderDate'])
df['Month'] = df['OrderDate'].[Link]
df['SalesCategory'] = df['Sales'].apply(
lambda x: 'High' if x > 1000 else 'Low'
)
Key Points & Interview Notes:
• groupby + agg is the single most-used Pandas pattern in business reporting (e.g. total sales per
region per month).
• Always inspect data with .info() and .isnull().sum() immediately after loading a new dataset.
• Interview tip: know the difference between .loc (label-based, inclusive of end) and .iloc (integer
position-based, exclusive of end).
Page 39 of 60
Python for DA & BA — Complete Notes
PHASE 20: Data Cleaning
Real business data is rarely clean - it contains missing values, duplicates, inconsistent formats, and
outliers. Data cleaning is often 70-80% of a data analyst's actual workload and directly determines the
reliability of any analysis.
20.1 Missing Values & Duplicate Removal
• Strategies for missing data: drop rows/columns (when missingness is small and random),
impute with mean/median/mode (numeric), or impute with a placeholder/most frequent
category (categorical).
• [Link]() identifies exact duplicate rows; subset= can check duplicates based on specific
columns only (e.g. duplicate customer IDs).
Example:
print([Link]().sum()) # count missing per column
df['Age'].fillna(df['Age'].median(), inplace=True)
df['City'].fillna(df['City'].mode()[0], inplace=True)
df.drop_duplicates(subset='CustomerID', keep='first', inplace=True)
20.2 Outliers & Data Transformation
• Outliers are extreme values that can distort averages and models; common detection methods
are the IQR (Interquartile Range) rule and Z-score thresholds.
• Encoding converts categorical text data into numeric form: Label Encoding (assigns each
category an integer) or One-Hot Encoding (creates a binary column per category, avoiding false
ordinal relationships).
• Scaling standardizes numeric ranges: Min-Max scaling maps values to [0,1]; Standardization
(Z-score) centers data around mean 0 with standard deviation 1 - important before many
machine learning algorithms.
Example:
Q1 = df['Sales'].quantile(0.25)
Q3 = df['Sales'].quantile(0.75)
IQR = Q3 - Q1
lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
outliers = df[(df['Sales'] < lower) | (df['Sales'] > upper)]
df_encoded = pd.get_dummies(df, columns=['Region']) # one-hot encoding
df['Sales_scaled'] = (df['Sales'] - df['Sales'].min()) / \
(df['Sales'].max() - df['Sales'].min())
Key Points & Interview Notes:
• Always understand WHY data is missing before choosing a strategy - deleting can bias results if
data is not missing completely at random.
Page 40 of 60
Python for DA & BA — Complete Notes
• One-hot encoding avoids implying a false order between categories, unlike label encoding.
• Feature engineering (creating new, more informative columns from existing ones, e.g.
extracting 'day of week' from a date) often improves analysis more than model choice.
Page 41 of 60
Python for DA & BA — Complete Notes
PHASE 21: Exploratory Data Analysis (EDA)
EDA is the process of summarizing a dataset's main characteristics, often visually, before drawing
conclusions or building models. It answers: what does the data look like, what patterns exist, and what
business insight can be drawn from it?
21.1 Univariate, Bivariate & Multivariate Analysis
• Univariate analysis examines one variable at a time - distribution, central tendency, spread (e.g.
histogram of sales values).
• Bivariate analysis examines the relationship between two variables (e.g. scatter plot of
advertising spend vs. sales, or a grouped bar chart of sales by region).
• Multivariate analysis considers three or more variables together, often using grouping, color-
coding, or pair plots to reveal interactions.
Example:
print(df['Sales'].describe()) # univariate summary
print(df['Sales'].value_counts(bins=5)) # univariate distribution
print([Link]('Region')['Sales'].mean()) # bivariate: category vs numeric
print(df[['Sales', 'Profit']].corr()) # bivariate: numeric vs numeric
21.2 Correlation & Descriptive Statistics
• Correlation (typically Pearson's r) measures the strength and direction of a linear relationship
between two numeric variables, ranging from -1 to +1.
• [Link]() produces a full correlation matrix, often visualized as a heatmap.
• Descriptive statistics (mean, median, mode, std, percentiles via describe()) form the foundation
of any EDA before deeper analysis.
Example:
correlation_matrix = [Link](numeric_only=True)
print(correlation_matrix)
print(df['Sales'].skew()) # skewness - shape of distribution
print(df['Sales'].kurt()) # kurtosis - tailedness of distribution
21.3 Translating EDA into Business Insights
• Every EDA step should be tied back to a business question: 'Which region underperforms?',
'Does discount level affect order volume?'
• Look for trends over time, category-wise disparities, and anomalies that might indicate data
errors or genuine business events.
• Summarize findings in plain language for stakeholders, supported by clear visuals (Phase 22).
Key Points & Interview Notes:
• EDA is iterative - insights from one chart often lead to another question and another chart.
Page 42 of 60
Python for DA & BA — Complete Notes
• Correlation does NOT imply causation - a classic point raised in almost every analytics
interview.
• Always pair a statistic with a visualization; numbers alone can hide patterns that a chart reveals
instantly.
Page 43 of 60
Python for DA & BA — Complete Notes
PHASE 22: Data Visualization
Visualization turns numbers into insight that stakeholders can understand at a glance. Matplotlib
provides fine-grained static plotting control, while Plotly enables modern, interactive charts and
simple dashboards.
22.1 Matplotlib - Core Chart Types
• Line plot - trends over time (e.g. monthly revenue).
• Bar plot - comparing categories (e.g. sales by region).
• Pie chart - showing proportion of a whole (use sparingly - bar charts are often clearer).
• Scatter plot - relationship between two numeric variables.
• Histogram - distribution of a single numeric variable.
• Box plot - distribution, median, and outliers in one view.
Example:
import [Link] as plt
months = ['Jan', 'Feb', 'Mar', 'Apr']
revenue = [12000, 15000, 11000, 18000]
[Link](months, revenue, marker='o')
[Link]('Monthly Revenue Trend')
[Link]('Month'); [Link]('Revenue')
[Link]()
[Link](['North', 'South', 'East'], [25000, 18000, 21000])
[Link]('Sales by Region')
[Link]()
22.2 Subplots & Combining Charts
• [Link](rows, cols) creates a grid of multiple charts within a single figure, useful for side-
by-side comparison in a report.
• Always add titles, axis labels, and legends - an unlabeled chart is not analysis-ready.
Example:
fig, axes = [Link](1, 2, figsize=(10, 4))
axes[0].hist(df['Sales'], bins=10)
axes[0].set_title('Sales Distribution')
axes[1].boxplot(df['Sales'])
axes[1].set_title('Sales Outliers')
plt.tight_layout()
[Link]()
22.3 Plotly - Interactive Charts & Basic Dashboards
Page 44 of 60
Python for DA & BA — Complete Notes
• Plotly Express (px) creates interactive charts (zoom, hover tooltips, pan) with minimal code -
ideal for exploratory work and stakeholder-facing dashboards.
• Interactive dashboards can be assembled with Plotly Dash or simple Streamlit apps that
combine multiple charts and filters on one page.
Example:
import [Link] as px
fig = [Link](df, x='Region', y='Sales', color='Product',
title='Sales by Region and Product')
[Link]()
fig2 = [Link](df, x='OrderDate', y='Sales', title='Sales Over Time')
[Link]()
Key Points & Interview Notes:
• Choose chart type based on the message: trend -> line, comparison -> bar, distribution ->
histogram/box, relationship -> scatter, share of whole -> pie/donut (sparingly).
• Matplotlib is best for static, publication-quality charts; Plotly is best for interactive exploration
and dashboards.
• A good chart has a clear title, labeled axes, and removes unnecessary clutter (gridlines, 3D
effects, excessive colors).
Page 45 of 60
Python for DA & BA — Complete Notes
PHASE 23: Statistics for Data & Business Analysis
Statistics provides the rigorous foundation for turning raw data into defensible business conclusions
- from simple averages to formal hypothesis tests used in A/B testing and experimentation.
23.1 Descriptive Statistics
• Mean - the arithmetic average; sensitive to outliers.
• Median - the middle value when sorted; robust to outliers, often better for skewed data like
income or house prices.
• Mode - the most frequently occurring value; useful for categorical data.
• Variance & Standard Deviation - measure how spread out values are around the mean; standard
deviation is in the same units as the data.
• Percentiles & Quartiles - divide sorted data into 100 (or 4) equal parts, used to describe relative
standing (e.g. 90th percentile customer spend).
Example:
import statistics as stats
sales = [1200, 1500, 900, 1750, 1100, 5000]
print([Link](sales), [Link](sales))
print([Link](sales), [Link](sales))
import numpy as np
print([Link](sales, 90)) # 90th percentile
23.2 Probability, Normal Distribution & Z-Score
• Probability quantifies the likelihood of an event, ranging from 0 (impossible) to 1 (certain).
• The Normal (Gaussian) distribution is the classic bell-shaped curve; many natural and business
metrics approximately follow it.
• A Z-score expresses how many standard deviations a value is from the mean, allowing
comparison across different scales/datasets.
Example:
mean = [Link](sales)
std = [Link](sales)
z_scores = [(x - mean) / std for x in sales]
print(z_scores)
23.3 Sampling, Confidence Intervals & Hypothesis Testing
• Sampling draws a representative subset from a population when studying the entire population
is impractical; random sampling avoids selection bias.
• A confidence interval gives a range in which a population parameter (e.g. true mean) likely
falls, with a stated confidence level (e.g. 95%).
Page 46 of 60
Python for DA & BA — Complete Notes
• Hypothesis testing (e.g. t-test) formally checks whether an observed difference (e.g. between
two campaign groups) is statistically significant or could be due to chance - the p-value is
compared against a significance level (commonly 0.05).
Example:
from scipy import stats as sci_stats
group_a = [23, 25, 21, 30, 28] # e.g. conversion time, variant A
group_b = [19, 20, 22, 18, 24] # variant B
t_stat, p_value = sci_stats.ttest_ind(group_a, group_b)
print(t_stat, p_value)
if p_value < 0.05:
print('Statistically significant difference')
else:
print('No significant difference')
23.4 Correlation, Covariance & A/B Testing
• Covariance indicates the direction of a linear relationship between two variables; correlation
standardizes this into a value between -1 and +1 for easier interpretation.
• A/B testing compares two versions (A and B) of a business element (webpage, email, pricing)
by randomly splitting users into groups and measuring a target metric, then applying hypothesis
testing to determine if the difference is significant.
Key Points & Interview Notes:
• A p-value below the chosen significance level (commonly 0.05) suggests the observed effect is
unlikely to be due to random chance alone.
• Mean is pulled by outliers; median is not - always check both, especially for skewed business
data like revenue or salary.
• Interview tip: be ready to explain Type I error (false positive) vs. Type II error (false negative)
in hypothesis testing.
Page 47 of 60
Python for DA & BA — Complete Notes
PHASE 24: SQL with Python
Most business data lives in relational databases. Python can connect directly to databases, run SQL
queries, and pull results straight into Pandas DataFrames for analysis - bridging the gap between data
storage and analytics.
24.1 sqlite3 & SQLAlchemy Basics
• sqlite3 is Python's built-in module for working with lightweight SQLite databases - no separate
server required, ideal for learning and small projects.
• SQLAlchemy is a more powerful toolkit/ORM that can connect to many database engines
(PostgreSQL, MySQL, SQL Server) with a consistent interface.
• A connection object represents the link to the database; a cursor executes SQL statements and
fetches results.
Example:
import sqlite3
conn = [Link]('[Link]')
cursor = [Link]()
[Link]('''
CREATE TABLE IF NOT EXISTS sales (
id INTEGER PRIMARY KEY,
product TEXT,
amount REAL
)
''')
[Link]("INSERT INTO sales (product, amount) VALUES ('Laptop', 1200)")
[Link]()
24.2 Reading SQL into Pandas & Writing Back
• pd.read_sql(query, connection) runs a SQL query and returns the result directly as a DataFrame
- the most common pattern for analysts.
• df.to_sql('table_name', connection, if_exists='replace') writes a DataFrame back into a database
table.
• This workflow lets analysts combine SQL's efficient filtering/aggregation with Pandas' flexible
transformation and visualization.
Example:
import pandas as pd
df = pd.read_sql('SELECT * FROM sales WHERE amount > 1000', conn)
print(df)
summary = [Link]('product')['amount'].sum().reset_index()
summary.to_sql('sales_summary', conn, if_exists='replace', index=False)
Page 48 of 60
Python for DA & BA — Complete Notes
[Link]()
Key Points & Interview Notes:
• Always close database connections ([Link]()) or use a context manager to avoid locked
files/leaked connections.
• Pushing heavy filtering/aggregation into SQL (before loading into Pandas) is often faster than
pulling all raw rows and filtering in Python.
• Interview tip: know basic SQL clauses (SELECT, WHERE, GROUP BY, JOIN, ORDER BY)
since they map directly onto Pandas equivalents.
Page 49 of 60
Python for DA & BA — Complete Notes
PHASE 25: Excel Automation
Excel remains central to business reporting. The openpyxl library lets Python read, write, format, and
chart Excel files programmatically - ideal for automating repetitive weekly/monthly report generation.
25.1 Reading & Writing Excel Files
• openpyxl.load_workbook('[Link]') opens an existing workbook; Workbook() creates a new
one.
• A workbook contains one or more worksheets, accessed via wb['SheetName'] or [Link].
• Cells are accessed by coordinate (ws['A1']) or by row/column index ([Link](row=1,
column=1)).
Example:
from openpyxl import Workbook, load_workbook
wb = Workbook()
ws = [Link]
[Link] = 'Sales Report'
ws['A1'] = 'Product'
ws['B1'] = 'Sales'
[Link](['Laptop', 1200])
[Link](['Mouse', 300])
[Link]('[Link]')
wb2 = load_workbook('[Link]')
ws2 = wb2['Sales Report']
print(ws2['A2'].value)
25.2 Formatting, Charts & Multiple Sheets
• Cell styling (font, fill color, borders, number format) is applied through [Link] (Font,
PatternFill, Border).
• [Link] provides chart objects (BarChart, LineChart, PieChart) that can be inserted
directly into a worksheet.
• wb.create_sheet('SheetName') adds additional sheets, useful for separating raw data, summary
tables, and dashboards within one file.
Example:
from [Link] import Font, PatternFill
from [Link] import BarChart, Reference
ws['A1'].font = Font(bold=True, color='FFFFFF')
ws['A1'].fill = PatternFill('solid', fgColor='4472C4')
chart = BarChart()
data = Reference(ws, min_col=2, min_row=1, max_row=3)
categories = Reference(ws, min_col=1, min_row=2, max_row=3)
chart.add_data(data, titles_from_data=True)
chart.set_categories(categories)
Page 50 of 60
Python for DA & BA — Complete Notes
ws.add_chart(chart, 'D2')
wb.create_sheet('Summary')
[Link]('[Link]')
Key Points & Interview Notes:
• openpyxl does not calculate formulas - it can write formula strings, but Excel (or a library like
formulas) must evaluate them.
• Automating recurring reports (daily/weekly sales summaries) with openpyxl is one of the most
valued practical BA/DA skills.
• For very large datasets, consider pandas.to_excel() combined with openpyxl as the engine for
simpler cases.
Page 51 of 60
Python for DA & BA — Complete Notes
PHASE 26: APIs
APIs (Application Programming Interfaces) let programs exchange data over the internet. Many
business data sources - CRMs, marketing platforms, weather/finance services - expose REST APIs,
and Python's requests library makes consuming them straightforward.
26.1 REST APIs, GET & POST
• A REST API exposes 'endpoints' (URLs) that respond to HTTP methods - GET retrieves data,
POST sends/creates data, PUT updates, DELETE removes.
• Responses are commonly returned in JSON format, which maps naturally onto Python
dictionaries/lists.
• [Link](url) and [Link](url, json=payload) are the two most common calls for an
analyst pulling external data.
Example:
import requests
response = [Link]('[Link]
if response.status_code == 200:
data = [Link]()
print(data['rates']['INR'])
else:
print('Request failed:', response.status_code)
26.2 Authentication & Consuming Public APIs
• Many APIs require authentication via an API key (passed as a query parameter or header) or an
OAuth token.
• Always check response.status_code (200 = success, 4xx = client error, 5xx = server error)
before processing data.
• Query parameters filter or customize what data an API returns, typically passed via the params
argument.
Example:
api_key = 'YOUR_API_KEY'
headers = {'Authorization': f'Bearer {api_key}'}
params = {'country': 'IN', 'category': 'business'}
response = [Link]('[Link]
headers=headers, params=params)
articles = [Link]().get('articles', [])
for article in articles[:5]:
print(article['title'])
Key Points & Interview Notes:
• Never hard-code API keys directly in shared scripts - use environment variables or a config file
excluded from version control.
Page 52 of 60
Python for DA & BA — Complete Notes
• JSON responses often nest lists inside dictionaries inside lists - use [Link]() and inspect
the structure before extracting fields.
• Once JSON data is retrieved, pd.json_normalize() is a handy way to flatten it directly into a
DataFrame.
Page 53 of 60
Python for DA & BA — Complete Notes
PHASE 27: Web Scraping & Regular Expressions
When data isn't available through a clean API, web scraping extracts it directly from HTML pages.
Regular expressions (regex) provide powerful pattern matching used both in scraping and general
text/data cleaning.
27.1 Web Scraping with BeautifulSoup
• [Link](url) fetches the raw HTML of a page; BeautifulSoup parses that HTML into a
searchable tree structure.
• find()/find_all() locate HTML tags by name, class, or id; .text extracts visible text content from
a tag.
• Tables can be scraped tag-by-tag or, when well-structured, loaded directly with
pandas.read_html(). Pagination requires looping over multiple page URLs.
• Always check a website's [Link] and terms of service before scraping, and scrape
responsibly (rate-limit requests).
Example:
import requests
from bs4 import BeautifulSoup
url = '[Link]
response = [Link](url)
soup = BeautifulSoup([Link], '[Link]')
products = soup.find_all('div', class_='product-item')
for p in products:
name = [Link]('h2').[Link]()
price = [Link]('span', class_='price').[Link]()
print(name, price)
27.2 Regular Expressions (re module)
• [Link]() finds the first match anywhere in a string; [Link]() checks only at the start;
[Link]() returns all matches as a list.
• [Link](pattern, replacement, text) substitutes matched text - useful for cleaning inconsistent
formats.
• Common patterns: \d (digit), \w (word character), \s (whitespace), + (one or more), * (zero or
more), {n} (exact count).
Example:
import re
text = 'Contact: rahul@[Link] or call 98765-43210'
emails = [Link](r'[\w.-]+@[\w.-]+\.\w+', text)
phones = [Link](r'\d{5}-\d{5}', text)
print(emails, phones)
Page 54 of 60
Python for DA & BA — Complete Notes
cleaned = [Link](r'\s+', ' ', ' too many spaces ')
print([Link]())
Key Points & Interview Notes:
• Prefer an official API over scraping whenever one is available - it's more stable and legally
clearer.
• pandas.read_html() can scrape simple HTML tables in a single line without manual
BeautifulSoup parsing.
• Regex is invaluable for validating and extracting structured patterns (emails, phone numbers,
IDs) from messy free-text fields.
Page 55 of 60
Python for DA & BA — Complete Notes
PHASE 28: Business Analysis with Python & Automation
This phase connects Python skills directly to business analyst deliverables - calculating KPIs,
analyzing customer behavior, and automating recurring reporting workflows.
28.1 KPI Calculations & Core Business Analyses
• Common KPIs: Revenue, Gross Profit, Profit Margin, Customer Acquisition Cost (CAC),
Customer Lifetime Value (CLV), Conversion Rate.
• Sales analysis examines trends, seasonality, and top/bottom-performing products or regions.
• Customer segmentation groups customers by behavior/value (e.g. RFM: Recency, Frequency,
Monetary analysis) to target strategies effectively.
• Churn analysis identifies which customers are likely to stop purchasing/subscribing, often the
input to a retention campaign.
Example:
df['Profit'] = df['Revenue'] - df['Cost']
df['Margin_%'] = (df['Profit'] / df['Revenue']) * 100
rfm = [Link]('CustomerID').agg(
Recency=('OrderDate', lambda x: ([Link]() - [Link]()).days),
Frequency=('OrderID', 'count'),
Monetary=('Revenue', 'sum')
)
print([Link]())
28.2 Automation & Report Generation
• File automation: use the os and shutil modules to organize folders, rename files in bulk, and
move reports into archive directories.
• Email automation: the smtplib module can send automated report emails; schedule modules (or
OS-level task schedulers) trigger scripts at set times.
• PDF automation: combine Pandas summaries with libraries like reportlab or fpdf to auto-
generate PDF business reports.
• Excel automation (Phase 25) combined with scheduling turns a manual weekly reporting task
into a one-click or fully automatic pipeline.
Example:
import os, shutil
archive_folder = 'archive'
[Link](archive_folder, exist_ok=True)
for file in [Link]('.'):
if [Link]('.csv'):
[Link](file, [Link](archive_folder, file))
Key Points & Interview Notes:
Page 56 of 60
Python for DA & BA — Complete Notes
• Every KPI calculation should be traceable back to a clear business question and decision it
supports.
• Automating a report is only valuable if the underlying data pipeline is trustworthy - always
validate data quality first.
• Interview tip: be ready to explain how you would design a churn-prediction or RFM-
segmentation analysis end-to-end.
Page 57 of 60
Python for DA & BA — Complete Notes
PHASE 29: Data Analyst / Business Analyst Practice Projects
Hands-on projects consolidate every earlier phase into realistic, end-to-end analyses. Employers value
demonstrated project work highly - each of these can be built into a portfolio piece with a notebook,
charts, and a written summary of insights.
29.1 Suggested Project List
• Student Performance Analysis - explore how attendance, study hours, and parental background
relate to exam scores.
• IPL / Sports Data Analysis - analyze match results, player performance trends, and team
statistics over seasons.
• Netflix / Streaming Data Analysis - explore content type distribution, release trends, and genre
popularity by country.
• HR Analytics Dashboard - analyze attrition rate, department-wise headcount, tenure, and salary
bands.
• Amazon / E-commerce Sales Analysis - identify best-selling categories, seasonal demand, and
pricing patterns.
• Banking Analytics - loan default risk indicators, customer segments, transaction patterns.
• Retail Sales Dashboard - store-wise, region-wise, and category-wise performance tracking.
• Customer Churn Analysis - build an RFM model and flag at-risk customers.
• Financial Analysis Dashboard - revenue, expenses, profit trends, and ratio analysis over
multiple quarters.
29.2 A Recommended Project Workflow
• 1) Define the business question(s) the project should answer.
• 2) Load and inspect the raw dataset (.info(), .describe(), .isnull().sum()).
• 3) Clean the data - handle missing values, duplicates, incorrect types, outliers.
• 4) Perform EDA - univariate, bivariate, and multivariate exploration with charts.
• 5) Derive KPIs and segment/group data relevant to the business question.
• 6) Visualize final insights clearly (Matplotlib/Plotly), ideally as a one-page summary dashboard.
• 7) Write a short narrative summary translating findings into recommended business actions.
Key Points & Interview Notes:
• A strong project tells a story: business question -> analysis -> insight -> recommendation, not
just a series of disconnected charts.
• Document assumptions and data limitations honestly - this is often what separates strong analyst
candidates in interviews.
• Publish projects (GitHub, portfolio site, LinkedIn) with clear README explanations of
approach and findings.
Page 58 of 60
Python for DA & BA — Complete Notes
PHASE 30: Interview Preparation & Capstone Projects
The final phase consolidates coding practice, core conceptual interview topics, and capstone-level
dashboard projects that combine every skill learned - the strongest way to demonstrate job readiness.
30.1 Python Coding Practice for Interviews
• Palindrome, Fibonacci sequence, Prime number check, Factorial (iterative & recursive),
Armstrong number.
• Reverse a number, reverse a string, anagram check, character/word frequency count.
• Find a missing number in a sequence, find the second largest element, basic matrix operations
(transpose, sum, multiplication).
• File handling and dictionary-based problems (e.g. counting word occurrences across multiple
files).
Example:
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def is_armstrong(n):
digits = str(n)
power = len(digits)
return n == sum(int(d) ** power for d in digits)
print(is_prime(29), is_armstrong(153)) # True True
30.2 Core Python Interview Topics (Conceptual)
• Mutable vs Immutable: lists/dicts/sets are mutable; strings/tuples/numbers are immutable.
• List vs Tuple: lists are mutable and slower; tuples are immutable, faster, and hashable.
• is vs ==: 'is' checks identity (same object in memory); '==' checks value equality.
• Deep Copy vs Shallow Copy: a shallow copy ([Link]()) copies references to nested objects;
a deep copy ([Link]()) recursively copies everything, fully independent of the original.
• append() vs extend(): append() adds one element (even if it's a list, as a single nested item);
extend() adds each element of an iterable individually.
• sort() vs sorted(): sort() sorts a list in place and returns None; sorted() returns a new sorted list,
leaving the original unchanged, and works on any iterable.
• Generators vs Iterators: every generator is an iterator; generators are created with yield and
produce values lazily, saving memory.
• Decorators: functions that wrap other functions to add behavior without modifying their code.
Page 59 of 60
Python for DA & BA — Complete Notes
• GIL (Global Interpreter Lock): a mutex in CPython that allows only one thread to execute
Python bytecode at a time, limiting true multi-threaded CPU parallelism (multiprocessing
bypasses this).
• Time Complexity: list indexing/append are O(1); list search/insert/delete are O(n); dict/set
average-case lookup, insert, and delete are O(1).
30.3 Capstone Dashboard Projects
• End-to-End Sales Dashboard - ingest raw sales data, clean it, compute KPIs, and present an
interactive Plotly/Excel dashboard.
• HR Analytics Dashboard - attrition trends, department comparisons, and tenure analysis with
clear recommendations.
• Retail Business Dashboard - store performance, category trends, and inventory turnover.
• Customer Segmentation Project - full RFM analysis with segment labels (e.g. 'Champions', 'At
Risk', 'Loyal') and suggested actions per segment.
• Marketing Campaign Analysis - compare channel performance, cost per acquisition, and ROI
across campaigns.
• Executive KPI Dashboard - a single-page summary combining revenue, profit, growth rate, and
top movers for leadership review.
Key Points & Interview Notes:
• In interviews, always explain your reasoning aloud, not just the final code - interviewers assess
problem-solving process as much as syntax.
• For capstone projects, prioritize a clear business narrative over technical complexity - a simple,
well-explained dashboard beats an overly complex, confusing one.
• Revise this entire guide phase-by-phase, rebuilding each code example from memory, as the
final and most effective form of interview preparation.
Page 60 of 60