0% found this document useful (0 votes)
13 views177 pages

Python

The document provides an overview of Python programming concepts, including variables, data types, functions, and key features of Python. It explains the differences between lists and tuples, demonstrates type conversion, and introduces list comprehensions. Additionally, it covers the use of dictionaries, sets, and string operations, along with examples of their usage.

Uploaded by

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

Python

The document provides an overview of Python programming concepts, including variables, data types, functions, and key features of Python. It explains the differences between lists and tuples, demonstrates type conversion, and introduces list comprehensions. Additionally, it covers the use of dictionaries, sets, and string operations, along with examples of their usage.

Uploaded by

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

1. Variables: A variable is a name given to a value stored in memory.

Key Points:
• Global variables: Defined outside a function, accessible inside functions.
• global keyword is needed only when assigning/changing variables, not for accessing.

Rules:
• Assignment inside a function assumes local unless global is declared.
• Variables only referenced inside a function are implicitly global.
a = 10
print("outside", a)
def fun():
global a
a = 15
print("inside", a)
fun()
print("outside", a)

#3
a = 10
print(id(a))
def fun():
a = 20
x = globals()["a"]
print(id(x))
print("inside", a)
globals()["a"] = 15
fun()
print("outside", a)

2. Common Number Functions


round(5.678, 2) # 5.68
abs(-7) #7
pow(2, 3) #8
divmod(10, 3) # (3, 1)
int(3.7) #3
float(3) # 3.0
complex(2, 3) # (2+3j)
bin(10) # '0b1010'
hex(255) # '0xff'
oct(8) # '0o10'

3. What is Python?
Python is a high-level, interpreted, interactive, dynamically typed object-oriented scripting
language.
Key features:
• It doesn’t need to be compiled before execution.
• Python allows programming in OOP and Procedural paradigms.
• Python is a cross-platform language, i.e., a Python program written on a Windows
system will also run on a Linux system with little or no modifications.

4. Purpose of PYTHONPATH Environment Variable


PYTHONPATH tells the Python interpreter where to locate the module files imported into a
program.

It should include:
The Python standard library directory, and
Any directories containing your own Python source code.

5. Data Types Supported in Python


Basic Data Types:
Numeric: int, float, complex
Sequence: list, tuple, str
Set Types: set, frozenset
Mapping: dict
Boolean: bool

Type annotations:
• While Python is a dynamically typed language, type annotations can clarify types.
Built-in types:
• int, float, bool, str, bytes

Complex types from typing module:


• List, Set, Dict, Tuple, Optional

Special Syntax
• Special variables: __name__
• Special methods: __init__
print(__name__)

# [Link]
print("Hi", __name__)

# [Link]
import cals
print(__name__)
14. Type Conversion in Python
Converting between data types.
one = 123
pin_code = "456"
result = str(one) + pin_code # Convert int to str for concatenation
print(result)

# Other conversions
float_result = float(one)
complex_result = complex(one)
binary_result = bin(19)
octal_result = oct(19)
hex_result = hex(19)
unicode_result = ord('A')
char_result = chr(98)

Data Types Overview


Tuple: Ordered, immutable
my_tuple = ("Max", 28, "New York")

List: Ordered, mutable


my_list = ["banana", "cherry", "apple"]

Set: Unordered, mutable, no duplicates


my_set = {1, 2, 3}

Dictionary: Unordered, mutable, key-value pairs


my_dict = {"name": "Max", "age": 28}

Why use tuples over lists:


Heterogeneous data
Faster iteration
Can be used as dictionary keys

Tuples
# Creating tuples
my_tuple = ("Max", 28, "New York")
my_tuple_2 = "Linda", 25, "Miami" # Parentheses are optional
my_tuple_3 = (25, 1, 2, 3, 4,) # trailing comma optional for single element tuples

x = my_tuple.count('Max')
x = my_tuple[-1]
x = my_tuple.index(28) # Return index of first occurrence of 28
x = len(my_tuple)
x = max(my_tuple_3)
x = min(my_tuple_3)
x = any(my_tuple_3)
x = all(my_tuple_3)
x = enumerate(my_tuple_3)
x = sum(my_tuple_3)
x = sorted(my_tuple_3)
x = tuple(my_tuple_3)

# Tuple unpacking
name, age, city = my_tuple
print(x)
print(name, age, city)

# Convert iterable to tuple


tuple_4 = tuple([1,2,3])
print(tuple_4)

# Tuple multiplication
my_tuple = ('a', 'b') * 5
print(my_tuple)

# Convert list to tuple


my_list = ['a', 'b', 'c', 'd']
list_to_tuple = tuple(my_list)
print(list_to_tuple)

# Convert tuple to list


tuple_to_list = list(list_to_tuple)
print(tuple_to_list)

# Convert string to tuple


string_to_tuple = tuple('Hello')
print(string_to_tuple)
Tuple Unpacking Examples

# Multiple variables with *


my_tuple = (0, 1, 2, 3, 4, 5)
first, *items_between, last = my_tuple
print(first, items_between, last)
# Nested tuples
a = ((0, 1), ('age', 'height'))
print(a[0])

Compare Tuple and List Performance


import sys, timeit
my_list = [0, 1, 2, "hello", True]
my_tuple = (0, 1, 2, "hello", True)
print([Link](my_list), "bytes") # Compare memory size
print([Link](my_tuple), "bytes")

# Compare execution time


print([Link](stmt="[0, 1, 2, 3, 4, 5]", number=1000000))
print([Link](stmt="(0, 1, 2, 3, 4, 5)", number=1000000))

Lists
my_list = ["banana", "cherry", "apple", 5, True, 0, 1, 1]
print(my_list)
list_2 = list() # empty list
print(list_2)

# List operations
x = my_list.append("orange")
x = my_list.index(1)
x = my_list.insert(1, "blueberry")
x = my_list.pop()
x = my_list.remove("cherry")
x = my_list.clear()
x = my_list.reverse()
x = my_list.sort()
x = my_list.count(0)
x = sum(my_list)
x = max(my_list)
x = min(my_list)
x = all(my_list)
x = any(my_list)
x = len(my_list)
x = enumerate(my_list)
print(x)

# Create list with repeated elements


list_with_zeros = [0] * 5
list_concat = list_with_zeros + my_list

# Convert string to list


string_to_list = list('Hello')

# Copy a list
list_org = ["banana", "cherry", "apple"]
list_copy = list_org.copy()
list_copy.append(True)
print(list_org)
print(list_copy)
# List Comprehension
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = [i * i for i in a]
print(b)

# Nested Lists
a = [[1, 2], [3, 4]]
print(a)
print(a[0])

27. Extract int type values from a list of heterogeneous element?


mixed_list = [10, 20, 3.4, 'Newton', True, 'School', False, 'Middleton']
# Extracting only the integers from the mixed list
int_values = [e for e in mixed_list if type(e) == int]

# Extracting only the strings from the mixed list


str_values = [e for e in mixed_list if type(e) == str]

# Extracting only the floats from the mixed list


float_values = [e for e in mixed_list if type(e) == float]

# Extracting only the booleans from the mixed list


bool_values = [e for e in mixed_list if type(e) == bool]

print("Integers:", int_values)
print("Strings:", str_values)
print("Floats:", float_values)
print("Booleans:", bool_values)

In this example, we use list comprehensions to create new lists containing values of
specific types from the original mixed list. The type() function is used to determine the type
of each element.
3. What is the difference between list and tuple?
Feature List Tuple
Mutability Mutable (can change) Immutable (cannot change)
Syntax [] (square brackets) () (parentheses)
Memory Usage Uses more memory Uses less memory
Speed Slower Faster
Methods Many methods (append, extend, clear,
Fewer methods (count, index)
Available etc.)
When frequent modifications are When data should remain
Use Case
needed constant

12. What is a list comprehension?


List comprehensions are a concise and powerful way to create lists in Python. The syntax is
straightforward, allowing you to express a list in a single line.

Generating a List of Even Numbers:


even_numbers = [x for x in range(1, 101) if x % 2 == 0]
print(even_numbers)

# Filtering even numbers from an existing list


numbers = [300, 500, 600, 520, 450, 200, 321]
even_numbers_from_list = [x for x in numbers if x % 2 == 0]
print(even_numbers_from_list)

List comprehensions are powerful because they allow you to create lists with a specified
pattern or condition in a concise manner. The syntax generally follows [expression for item
in iterable if condition].

Sets
# Create sets
my_set = {"apple", "banana", "cherry"}
my_set_2 = set(["one", "two", "three"])
my_set_3 = set("aaabbbcccdddeeeeeffff")

my_set.add("three")
my_set.remove("three")
my_set.discard("three")
my_set.pop()
my_set.clear()
print(my_set)
# Union and Intersection
odds = {1, 3, 5, 7, 9}
evens = {0, 2, 4, 6, 8}
u = [Link](evens)
i = [Link](evens)
print(u)
print(i)

# Difference and symmetric difference


setA = {1,2,3,4,5,6,7,8,9}
setB = {1,2,3,10,11,12}
diff_set = [Link](setB)
diff_set = [Link](setA)
diff_set = setA.symmetric_difference(setB)
diff_set = setB.symmetric_difference(setA)
print(diff_set)

# Updating sets
[Link](setB)
setA.intersection_update(setB)
setA.difference_update(setB)
setA.symmetric_difference_update(setB)

# Update with iterable


[Link]([1, 2, 3, 4, 5, 6])

# Subset, Superset, and Disjoint


setA = {1, 2, 3, 4, 5, 6}
setB = {1, 2, 3}
setC = {7, 8, 9}
print([Link](setB))
print([Link](setA))
print([Link](setB))
print([Link](setA))
print([Link](setB))
print([Link](setC))

Dictionaries
my_dict = {"name":"Max", "age":28, "city":"New York"}
my_dict_2 = dict(name="Lisa", age=27, city="Boston")

name_in_dict = my_dict["name"] # Accessing and modifying


my_dict["email"] = "max@[Link]"
# add key
my_dict["email"] = "coolmax@[Link]" # overwrite key
del my_dict["email"]

# delete key
print(my_dict)
print("popped value:", my_dict.pop("age"))
print("popped item:", my_dict.popitem())

# Checking keys
if "name" in my_dict:
print(my_dict["name"])
try:
print(my_dict["firstname"])
except KeyError:
print("No key found")

# Looping Through Dictionaries


for key in my_dict:
print(key, my_dict[key])
for key in my_dict.keys():
print(key)
for value in my_dict.values():
print(value)
for key, value in my_dict.items():
print(key, value)

Merging Dictionaries
my_dict = {"name":"Max", "age":28, "email":"max@[Link]"}
my_dict_2 = dict(name="Lisa", age=27, city="Boston")
my_dict.update(my_dict_2)
print(my_dict)

Dictionary Key Types


• Any immutable type (string, number, tuple) can be used as a key.
Dictionaries with Non-String Keys

# Keys are not indices of a list


my_dict = {3: 9, 6: 36, 9: 81} # numbers as keys
print(my_dict[3], my_dict[6], my_dict[9])

# Using a tuple as a key


my_tuple = (8, 7)
my_dict = {my_tuple: 15}
print(my_dict[my_tuple])
print(my_dict[8, 7])

# Using a list as a key is not possible (immutable required)


# my_list = [8, 7]
# my_dict = {my_list: 15} # TypeError

Strings
• Strings are immutable.
• Triple quotes """ are used for multiline strings.

txt = "My name is John, and I am {}"


my_string = """Hello
World"""
print(type(my_string))
print(my_string[1])
print(len(my_string))
print(my_string.strip())
print(my_string.lower())
print(my_string.upper())
print(my_string.replace("H", "J"))
print(my_string.split(","))
print(len(my_string))
print("hello".startswith("he"))
print("hello".endswith("llo"))
print("Hello".find("o")) # first index of substring, -1 if not found
print("Hello".count("e"))
my_list = ['How', 'are', 'you', 'doing']
str = ' '.join(my_list) # join elements of a list into a string
print(str)
b = my_string[0]

# get character by index


b = my_string[1:3] # substring
b = my_string[::2] # every second character
b = my_string[::-1] # reverse string

Iterating Over Strings


my_string = 'Hello'
for i in my_string:
print(i)
String Formatting
1. Using format()
a = "Hello {0} and {1}".format("Bob", "Tom") # positional placeholders
a = "Hello {} and {}".format("Bob", "Tom") # positions optional
a = "The integer value is {}".format(2)
print(a)

# Special format rules


a = "The float value is {0:.3f}".format(2.1234)
a = "The float value is {0:e}".format(2.1234)
a = "The binary value is {0:b}".format(2)
print(a)

# Old style formatting


print("Hello %s and %s" % ("Bob", "Tom"))
val = 3.14159265359
print("The decimal value is %d" % val)

2. f-Strings
name = "Eric"
age = 25
a = f"Hello, {name}. You are {age}."
print(a)
pi = 3.14159
a = f"Pi is {pi:.3f}"
print(a)
a = f"The value is {2 * 60}" # Expressions evaluated at runtime
print(a)

Immutability and String Concatenation


from timeit import default_timer as timer
my_list = ["a"] * 1000000
start = timer()
a = "".join(my_list)
end = timer()
print("concatenate string with join(): %.5f" % (end - start))

Regex Methods: split(), sub(), subn()


import re

# split
str = "Split string into list"
newStr = [Link]()
print(newStr)

# sub
newStr = [Link]("s", "9", str)
print(newStr)

# subn
str = [Link]('ov', '~*', 'The rain in Spain', flags=[Link])
print(str)

7. String operations using concat and contains


import operator
str1 = "geeksfor"
str2 = "geeks"
print([Link](str1, str2))
if [Link](str1, str2): # check if str1 contains str2
print("geeksfor")
else:
print("not contain geeks")

Array
vals = array('i', [1,2,3,4,5,-6,7,8,9,10])

# float array
floatArr = array('d', [2.5, 3.2, 3.3])
print([Link])
[Link](100)
[Link](1, 4)
[Link](1)
[Link](2)
[Link](2)
vals[2] = 6 # update element
print(len(vals))

import array as arr


a = [Link]('i', [1,2,3,4,5,6,7,8,9,10])
for i in range(0, 3):
print(a[i], end=" ")
# Sum of array
def _sum(arr):
return sum(arr)
ans = _sum([12, 3, 4, 15])
print(ans)

# Split array
def splitArr(arr, n, k):
for i in range(0, k):
x = arr[0]
for j in range(0, n-1):
arr[j] = arr[j + 1]
arr[n-1] = x
arr = [12, 10, 5, 6, 52, 36]
n = len(arr)
position = 2
splitArr(arr, n, position)
for i in range(0, n):
print(arr[i], end=' ')

16. Negative Indexes


Access elements from the end of a sequence.
my_list = [1, 2, 3, 4, 5]

last_element = my_list[-1] #5
second_last_element = my_list[-2] #4

Lambda Functions
f = lambda a, b: a + b
obj = f(2, 3)
print(obj)

# Recursive lambda
f = lambda n: 1 if n == 0 else n + f(n-1)
print(f(5))

6. Memory Management in Python


• Memory is managed by Python’s private heap space, inaccessible to the
programmer.
• The Python memory manager handles allocation/deallocation.
• The Garbage Collector reclaims unused memory automatically.
• Python uses dynamic memory allocation.
• Objects have reference counts; the Garbage Collector removes objects with zero
references.

7. Benefits of Python over Other Scripting Languages


Rapid and easy application development.

Extensive module/library support for:


• Data Analytics
• Machine Learning
• Math/Scientific applications

5. What is docstring in Python?


• Docstrings describe the functionality of a functions, classes, or modules.
• Can be accessed at runtime using the dot operator if it is the first statement in a
method/function.
• Optional in functions.

def power(a, b):


"""Returns arg1 raised to power arg2."""
return a ** b
print(power.__doc__)

9. Can you write code to determine the name of an object in Python?


• Objects in Python do not have intrinsic names — variables are just references.
• Objects don’t have associated names; assignment binds a name to a value.

class Test:
def __init__(self, name):
[Link] = []
[Link] = name
def __str__(self):
return '{} holds ...'.format([Link])
obj = Test('obj')
print(obj)

10. Complex numbers:


• Used in electronics, optics, quantum theory, Fourier transforms, audio signal processing,
and speech recognition.
Syntax: complex(real, imaginary)
num = 2 + 3j
num2 = complex(2, 3)
print([Link])
print([Link])

Applications:
• Fourier transforms
• Audio & speech recognition systems

11. Define Pass statement in Python?


• Used as a placeholder when code is syntactically required but not yet implemented.
• Pass is used when no action is required but syntactically a statement is needed.

For Loops and Control Statements


# Empty loop using pass
for i in range(5):
pass

12. What does the Python nonlocal statement do.


Allows inner functions to modify variables in the nearest enclosing scope (excluding
globals).
def count():
x=2
def increment():
nonlocal x # Allows modifying 'x' from the enclosing scope
x += 1
return x
return increment
c = count()
print(c()) #3
print(c()) #4

def count():
x=2
y=3
def sum_func(): # Avoid naming conflict with built-in sum()
print(x + y)
return sum_func # Return the function itself, not the result
c = count() # c is now the sum_func function
c() # Call it => prints 5
def count():
x=2
def sum_func():
nonlocal x
x += 1
return x
return sum_func
obj = count() # obj is a closure with its own x
obj2 = count() # obj2 is a separate closure with its own x
print(obj()) #3
print(obj()) #4
print(obj2()) # 3 (separate x)

13. Functions as First-Class Citizens


Functions in Python:
• Are objects.
• Can be assigned to variables.
• Can be passed as arguments or returned from other functions.

def shout(text):
return [Link]()
print(shout('Hello'))

def greet(func):
greeting = func("Hi, I am created by a function.")
print(greeting)
greet(shout)
greet(whisper)

def add(x):
def add2(y):
return x + y
return add2
obj = add(2) # obj is now add2 with x = 2
print(obj(3)) #5

14. Parameter Passing


Call-by-Object / Call-by-Object-Reference :
• Mutable objects (e.g. lists) can be changed inside a function.
• Immutable objects (e.g. ints, strings) cannot.
• Reference is passed by value.

# Immutable object
def fun(x):
x=5
var = 10
print('var inside fun():', var)
var = 10
print(var)
fun(var)
print(var)

# Mutable object
def fun(lst):
[Link](4)
list2 = [1, 2, 3]
print(list2)
fun(list2)
print(list2)
# fun(10) # This will cause an error

• Memoize factorial stores intermediate results in memory

7. Closure: A closure is a function that remembers values from its enclosing scope even
when the scope is not active.
A closure remembers values not present in memory.

Uses:
• Callback functions
• Data hiding
• Reducing global variables
def outer(a):
b=2
def inner():
nonlocal b
print(a + b)
return inner()
outer(3)

16. Logging
[Link](level=[Link])
[Link]('Info')

import logging
[Link](filename='[Link]', level=[Link])
def logger(func):
def log_func(*args):
[Link]('Running "{}" with arguments {}'.format(func.__name__, args))
print(func(*args))
return log_func

Logging in Python
Log Levels
• 5 levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
• Default logs WARNING and above

[Link]('This is a debug message')


[Link]('This is an info message')
[Link]('This is a warning message')
[Link]('This is an error message')
[Link]('This is a critical message')

Output:
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

def add(x, y):


return x + y
def sub(x, y):
return x - y
add_logger = logger(add)
sub_logger = logger(sub)
add_logger(3, 3)
add_logger(4, 5)

17. *args, **kwargs


• Allow variable numbers of positional and keyword arguments.
• *args (Non-Keyword Arguments): Accepts variable number of arguments.
• **kwargs (Keyword Arguments): Accepts variable-length keyworded argument list.

# Variable-length arguments
def fun(*args):
for item in args:
print(item)
fun("Hello", "Welcome", "to", "World")

# Keyword variable-length arguments


def fun(**kwargv):
for key, value in [Link]():
print("%s == %s" % (key, value))
fun(a="Hello", b="Welcome", c="to", d="World")

# Keyword arguments
def fun(a, b):
print(a, b)
fun(b="Practice", a="Geeks")

# One extra argument


def fun(arg1, **kwargv):
print("arg1:", arg1)
for key, value in [Link]():
print("%s == %s" % (key, value))
fun("Hi", a="Hello", b="Welcome", c="to", d="World")

18. Forced keyword arguments.


Use * to enforce keyword-only parameters.

Keyword-only arguments can be enforced using:


• If * is written in the function parameter list, all parameters after it must be passed as
keyword arguments.
• Arguments after variable-length arguments must be keyword arguments.
def fun(a, b, *, c, d):
print(a, b, c, d)
fun(1, 2, c=3, d=4)
# fun(1, 2, 3, 4) # not allowed

def fun(*args, last):


for arg in args:
print(arg)
print(last)
fun(8, 9, 10, last=50)

19. Function Arguments & Parameters


def fun(name): # 'name' is a parameter
print(name)
fun("Alex") # 'Alex' is an argument
17. Positional and Keyword Arguments
Benefits of keyword arguments:
• Call arguments by name
• More readable
• Useful if unable to assign positional argument
• Positional arguments cannot follow keyword arguments.

# Positional argument
def fun(a, b):
print(a, b)
fun(1, 2)

def fun(a, b, c):


print(a, b, c)
fun(1, 2, 3) # positional arguments
fun(a=1, b=2, c=3) # keyword arguments
fun(c=3, b=2, a=1) # order not important
# Not allowed:
# fun(1, b=2, 3) # positional argument after keyword argument
# fun(1, b=2, a=3) # multiple values for 'a'

18. Default Arguments


Must be defined at the end of parameter list
def fun(a, b, c, d=4):
print(a, b, c, d)
fun(1, 2, 3) # uses default d=4
fun(1, b=2, c=3, d=100) # overrides default with d=100

• Invalid example:
def fun(a, b=2, c, d=4):
print(a, b, c, d) # default arguments must be at the end

Unpacking arguments:
def fun(a, b, c):
print(a, b, c)
# Using a list (or tuple) with unpacking
list_ = [4, 5, 6]
fun(*list_)
# Using a dictionary with unpacking
dict_ = {'a': 1, 'b': 2, 'c': 3}
fun(**dict_)

23. Operator Overloading


Operator overloading allows custom behavior for built-in operators in user-defined classes.
Common Magic Methods:
Operator Magic Method Example
+ __add__(self, other) a+b
- __sub__(self, other) a-b
* __mul__(self, other) a*b
/ __truediv__(self, other) a / b
// __floordiv__(self, other) a // b
% __mod__(self, other) a%b
** __pow__(self, other) a ** b

class Plus:
def __init__(self, a):
self.a = a
def __add__(self, o):
return self.a + o.a
obj1 = Plus(1)
obj2 = Plus(2)
print(obj1 + obj2)

24. Any and All


Any: Returns True if any element in iterable is True
All: Returns True if all elements in iterable are True
obj = ["True", "True", "True"]
result = all(obj)
result = any(obj)
print(result)

Arithmetic Operators
import operator
a, b = 3, 3
print([Link](a, b))
print([Link](a, b))
print([Link](a, b))
print([Link](a, b)) # 1.0
print([Link](a, b)) # 1
print([Link](a, b)) # 27
print([Link](a, b))
27. Bitwise Operators
a, b = 3, 4
print(operator.and_(a, b)) # Bitwise AND
print(operator.or_(a, b)) # Bitwise OR
print([Link](a, b)) # Bitwise XOR
print([Link](a)) # Bitwise NOT

print(12 & 13) # & AND


print(12 | 13) # | OR
print(12 ^ 13) # ^ XOR
print(~12) # ~ NOT
print(10 << 2) # << Zero-fill left shift
print(10 >> 2) # >> Signed right shift

22. Assignment Operators


import operator

a, b, c = 3, 3, 4
if [Link](a, b): # a < b
print(a)
else:
print("a !< b")
if [Link](a, b): # a <= b
print("a<=b")
else:
print(b)
if [Link](a, b): # a == b
print("a==b")
else:
print(c)
if [Link](a, b): # a > b
print("a>b")
else:
print(b)
if [Link](a, b): # a >= b
print("a>=b")
else:
print(a)
if [Link](a, b): # a != b
print("a!==b")
else:
print(b)
20. Operators
val = input("Enter your value: ")
print(val)

Square Roots, Powers, and Constants


import math
print([Link](25))
x = [Link](15)
print([Link](x))
print([Link](x))
print(3**2)
print([Link](3,2))
print([Link])
from math import pow
print(pow(4,5))

Math Utilities
Simple and Compound Interest
# Simple interest
def simple_interest(p, t, r):
si = (p * t * r) / 100
print('The Simple Interest is', si)
return si
simple_interest(8, 6, 8)

Python random Module


# Random integer
import random
print([Link](0,9))

# Sum of two numbers


number1 = input("First number: ")
number2 = input("Second number: ")
sum_val = float(number1) + float(number2)
print("The sum of {0} and {1} is {2}".format(number1, number2, sum_val))

# Random floats and choices


import random

# 1. Random float in [0, 1)


a = [Link]()
print(a)
# 2. Random float in [1, 10]
a = [Link](1, 10)
print(a)
# 3. Random integer from 1 to 9 (10 excluded)
a = [Link](1, 10)
print(a)
# 4. Random float from a normal (Gaussian) distribution with mean=0, stddev=1
a = [Link](0, 1)
print(a)

# Gaussian distribution
a = [Link](list("ABCDEFGHI")) # single random element
a = [Link](list("ABCDEFGHI"), 3) # 3 unique elements
a = [Link](list("ABCDEFGHI"), k=3) # 3 elements with replacement
a_list = list("ABCDEFGHI")
[Link](a_list)
# shuffle in-place
print(a_list)

Seed Generator
import random
[Link](1)
print([Link]())
print([Link](1,10))
print([Link](list("ABCDEFGHI")))
[Link](42) # re-seed

Cryptographically Strong Random Numbers (secrets)


import secrets
# Random integer < 10
a = [Link](10)
print("randbelow(10):", a)
# Random integer with 5 random bits (0 to 31)
a = [Link](5)
print("randbits(5):", a)
# Random choice from a list
a = [Link](list("ABCDEFGHI"))
print("choice:", a)

Ternary operator:
a, b = 10, 20
min_val = a if a < b else b
print(min_val)
print("Both equal" if a == b else "a > b" if a > b else "b > a")

Tuple and dictionary selection:


print((b, a)[a < b]) # tuple
print({True: a, False: b}[a < b]) # dictionary
print((lambda: b, lambda: a)[a < b]()) # only one expression evaluated

Operator Overloading:
class Plus:
def __init__(self, a):
self.a = a
def __add__(self, o):
return self.a + o.a
obj1 = Plus(1)
obj2 = Plus(2)
obj3 = Plus("Geeks")
obj4 = Plus("For")
print(obj1 + obj2)
print(obj3 + obj4)

25. Sequence Manipulation


li = [1, 5, 6, 7, 8]
[Link](li, 3, 3) # assign 3 at index 3
[Link](li, 1)

# delete value at index 1


print([Link](li, 3)) # access element at index 3

27. Slice Operations


li = [1, 5, 6, 7, 8]
[Link](li, slice(1,4), [2,3,4])
[Link](li, slice(2,4))
print([Link](li, slice(0,2)))

For-Else Loop
for x in range(6):
print(x)
else:
print("Finally finished!")

28. ISS (Difference between == and is).


list1 = []
list2 = []
list3 = list1
print(list1 == list2) # True (same contents)
print(list1 is list2) # False (different objects)
print(list1 is list3) # True

24. Membership and Identity Operators


• Membership: Check if a value exists in a sequence (in, not in)

Identity Operators:
Check if two variables point to the same object (is, is not)
is → checks if tvariables point to the same object.
is not → checkif two variables do not point to the same object.

# Membership
list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9]
for item in list1:
if item in list2:
print(f"{item} overlapping")
else:
print(f"{item} not overlapping")

Regex Syntax & Functions


• Special Sequences:
o \d → [0-9]
o \d+ → one or more digits
o \w → [a-zA-Z0-9_]
o \w+ → one or more alphanumeric characters
o \W → non-alphanumeric characters
o \W+ → one or more non-alphanumeric
o \b → word boundary

• Functions:
o compile() → compile regex into a pattern object
o findall() → return all matches as a list
o split() → split string using regex
o sub() → replace matched pattern
o subn() → replace matched pattern and return tuple (new_string,
replacements_count)
o escape() → escape all non-alphanumeric characters

Examples
p = [Link]('[a-e]')
print([Link]("Aye, said Mr. Gibenson Stark"))

p = [Link]('\d')
print([Link]("I went to him at 11 A.M. on 4th July 1886"))

p = [Link]('\d+')
print([Link]("I went to him at 11 A.M. on 4th July 1886"))

p = [Link]('\w')
print([Link]("He said * in some_lang."))

p = [Link]('\w+')
print([Link]("I went to him at 11 A.M., he said *** in some_language."))

p = [Link]('\W')
print([Link]("he said *** in some_language."))

p = [Link]('ab*')
print([Link]("ababbaabbb"))

Split Example
from re import split
print(split('\W+', 'Words, words , Words'))
print(split('\W+', "Word's words Words"))
print(split('\W+', 'On 12th Jan 2016, at 11:02 AM'))
print(split('\d+', 'On 12th Jan 2016, at 11:02 AM'))

Sub & Subn Example


print([Link]('ub', '~*', 'Subject has Uber booked already', flags=[Link]))
print([Link]('ub', '~*', 'Subject has Uber booked already'))
print([Link]('ub', '~*', 'Subject', count=1, flags=[Link]))
print([Link](r'sANDs', ' & ', 'Baked', flags=[Link]))
print([Link]('ub', '~*', 'Subject booked already'))
t = [Link]('ub', '~*', 'Subject booked already', flags=[Link])
print(t)
print(len(t))
print(t[0])
30. For, While
num = 0
while num <= 10:
print(num)
num += 1

31. Break and Continue


for i in range(10):
if i == 5:
break
print(i)

for i in range(10):
if i % 2 == 0:
continue
print(i)

32. zip()
keys = ['fruit', 'mobile', 'count']
values = ['Apple', 'Sony', '1']
newDict = dict(zip(keys, values))
print(newDict)

Variable addresses and IDs


def arguments(num): # Formal argument
print(id(num))
arguments(10) # Actual argument

33. Tuple = count, index, len, max, min, any, all, enumerate, sum, sorted
34. List = append, index, insert, pop, remove, clear, reverse, sort, count
35. Set = add, remove, discard, pop, clear, update, issubset, isdisjoint, union, intersection,
difference, symmetric_difference
36. Array = append, extend, insert, remove, pop, clear, index, sort, count, reverse, copy,
len, sum, max, sorted, Slicing(lst[1:4])

37. Dictionaries = get, [Link], update, keys, items, has_key, type, cmp
• A dictionary is an unordered, mutable, and indexed collection.
• It stores data as key-value pairs.
• Keys must be unique and immutable (e.g., strings, numbers, tuples).
• Values can be any data type.
Property Description
Mutable Can add, update, or remove items
Indexed by Keys (not position)
Syntax {key: value, key2: value2, ...}
Ordered (since Python 3.7) Maintains insertion order
Nested Dictionaries Dictionaries can contain other dictionaries as values

students = {
"student1": {"name": "Alex", "age": 21},
"student2": {"name": "Maya", "age": 20}
}
print(students["student1"]["name"]) # Output: Alex

38. Frozenset
• A frozenset is an immutable version of a Python set.
• Like a regular set, it is unordered, contains unique elements, and supports set
operations (union, intersection, difference).
• But unlike set, it cannot be modified — meaning no add() or remove() methods.

# From a list
numbers = [1, 2, 3, 2, 1]
fset = frozenset(numbers)
print(fset)
# Output: frozenset({1, 2, 3})

# From a set
s = {4, 5, 6}
fset2 = frozenset(s)
print(fset2)
# Output: frozenset({4, 5, 6})

Frozen Sets
# Immutable sets
odds = frozenset({1, 3, 5, 7, 9})
evens = frozenset({0, 2, 4, 6, 8})
print([Link](evens))
print([Link](evens))
print([Link](evens))
39. Strings = count, endswith, find, format, index, isalnum, isalpha, isdecimal, isdigit,
islower, isspace, istitle, join, lstrip, partition, replace, split, title, translate, zfill.

Method Description Example Output


capitalize() Capitalize first letter "hello".capitalize() 'Hello'
upper() Convert to uppercase "hi".upper() 'HI'
lower() Convert to lowercase "HI".lower() 'hi'
title() Convert to title case "hello".title() 'Hello'
replace(a, b) Replace text a with b "hi hi".replace("hi","bye") 'bye bye'
split(sep) Split string into a list "a,b,c".split(",") ['a', 'b', 'c']
join(iterable) Join list/iterable into string " ".join(['a','b']) 'a b'
find(sub) Find index of substring "hello".find("e") 1
startswith(prefix) Check if string starts with prefix "hello".startswith("he") True

42. JSON Handling


Convert from Python to JSON.
[Link](): Convert string to Python dict.
Use when You have JSON data as a string (from an API or a file read as text).

[Link]() : Convert a Python object → JSON file.


Use when You want to save Python data into a JSON file.

import json
data = {"name":"John","phone":"12345"}
with open("[Link]","w") as f:
[Link](data, f)

# Reading JSON from file


f = open('[Link]')
data = [Link](f)
for i in data['emp_details']:
print(i)
[Link]()

43. Difference between sorted and sort function.


sort(): Alwase apply on list and return None. sort() do changes on original list.
sorted(): Alwase return list even pass tuples/ string.
• sorted() → returns a new list
• sort() → modifies the original list in place
Sorted
l = (4,3,5,6,8,0,1,2)
print(sorted(l))

Sort
l2 = [4,3,5,6,8,0,1,2]
print([Link]())

File Handling
# Write
f = open("[Link]","w")
[Link]("I love python")
[Link]()

# Read
with open("[Link]","r") as f:
for line in f:
print(line)

Using with Statement


# Read a file
with open('./[Link]','r') as fr:
print([Link]())

# Write to a file
with open('./[Link]','w') as fw:
data = 'some data to be written to the file'
print([Link](data))

Mode Description
r Read only. Raises FileNotFoundError if the file doesn’t exist.
r+ Read and write. Raises FileNotFoundError if the file doesn’t exist.
w Write only. Overwrites existing file or creates a new file if it doesn’t exist.
w+ Read and write. Overwrites existing file or creates a new file if it doesn’t exist.
a Append only. Creates file if it doesn’t exist.
a+ Append and read. Creates file if it doesn’t exist.
File Operations
# Read specific number of bytes vs readline
file1 = open("[Link]", "r")
print([Link](8))
print([Link](9))
[Link]()

# Append to a file
file1 = open("[Link]", "a")
[Link]("Today")
[Link]()
file1 = open("[Link]", "r")
print([Link]())
[Link]()

# Overwrite a file
file1 = open("[Link]", "w")
[Link]("Tomorrow")
[Link]()
file1 = open("[Link]", "r")
print([Link]())
[Link]()

Delete a File
import os
if [Link]("[Link]"):
[Link]("[Link]")
print("File deleted successfully")
else:
print("The file does not exist")

44. file-related modules = Open, with, Reading line by line.


Reading all lines as list = [Link]()

with open("[Link]", "w") as fw:


Writing to a file = [Link]("First line")

with open("[Link]", "a") as fa:


Appending to a file = [Link]("Appended line")

Using "x" mode → create only if file doesn’t exist


with open("[Link]", "x") as f:
45. Self: Represents the instance of the class itself.
__init__: Automatically called when you create a new object from a class, It initializes
object attributes.

25. Difference between instance object and class object?


Feature Class Object Instance Object
Definition Blueprint/template of a class Individual object created from the class
When the class is instantiated using obj
Created When When the class is defined
= Class()
Class variables (static variables),
Stores Instance variables (self.a, self.b, etc.)
methods
Memory Each instance has its own separate
Shared by all instances
Sharing memory
Accessed using class name
Access Accessed using instance (obj.a)
(Test.x)
Changing class variable affects all Changing instance variable affects only
Modification
instances that specific object
Example Test obj1 = Test(3, 4, 5)

How to create static member variables in class


A static member variable (class variable) is shared by all objects of a class.
Defined outside __init__, inside the class body.

class Student:
school_name = "ABC Public School" # static/class variable
def __init__(self, name, age):
[Link] = name # instance variable
[Link] = age

25. Instance Object vs Class Object


class Test:
x = 10 # Static variable
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def show(self):
print(f"You are a fool! {self.a}, {self.b}, {self.c}")
print(Test.x) # Class object
obj1 = Test(3, 4, 5) # Instance object
[Link]()

• Class object → shared among all instances


• Instance object → unique to each object

9. Instance Member Variables in a Class


class Test:
def __init__(self, name, age):
[Link] = name
[Link] = age
def display_info(self):
print(f"Name: {[Link]}, Age: {[Link]}")
# Creating instances
obj1 = Test("Titu", 21)
obj2 = Test("Daughter", 18)
obj1.display_info()
obj2.display_info()
# Adding instance member later
obj3 = Test("Scientist", 30)
[Link] = "Male"
print(f"Name: {[Link]}, Age: {[Link]}, Gender: {[Link]}")

Instance vs Class Variables


class Dog:
animal = 'dog' # class variable
def __init__(self, breed, color):
[Link] = breed # instance variable
[Link] = color # instance variable

23. Static Member Variables


• Static variables are shared among all instances.
• Accessible via class name or cls in class methods.
class MyClass:
static_variable_inside = 42 # Class (static) variable
def __init__(self, x):
self.x = x # Instance variable
def subscribe(self):
print(f"Static variable inside the class: {MyClass.static_variable_inside}")
@classmethod
def static_method(cls):
print(f"Static variable inside the class method: {cls.static_variable_inside}")
item = MyClass(10) # Create instance
print(f"Instance variable: {item.x}") # Access instance variable
print(f"Static variable outside the class: {MyClass.static_variable_inside}")
[Link]() # Call instance method
MyClass.static_method() # Call class method

47. How to define a class method and a static method?


Static Methods: Methods bound to the class rather than its object, marked with

Class Methods vs Static Methods


from datetime import date
class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age
@classmethod
def fromBirthYear(cls, name, year):
return cls(name, [Link]().year - year)
@staticmethod
def isAdult(age):
return age > 18
person1 = Person('mayank', 21)
person2 = [Link]('mayank', 1996)
print([Link])
print([Link](22))

Constructors
• Constructors are used for instantiating an object and initializing its data members.
• In Python, the __init__() method is called the constructor and is always called when
an object is created.
Default Constructor
class GeekforGeeks:
def __init__(self): # default constructor
[Link] = "GeekforGeeks"
def print_Geek(self):
print([Link])
obj = GeekforGeeks()
obj.print_Geek()
26. The __init__ Method
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def subscribe(self):
print(f"Subscribed! {self.a}, {self.b}")
t1 = Test(10, 20)
[Link]()
titu = Test(3, 4)
print(titu.a, titu.b)
• __init__ is automatically called on object creation
• Initializes instance variables

Parameterized Constructor
class Addition:
first = 0
second = 0
answer = 0
def __init__(self, f, s): # parameterized constructor
[Link] = f
[Link] = s
def display(self):
print("First number =", [Link])
print("Second number =", [Link])
print("Addition of two numbers =", [Link])
def calculate(self):
[Link] = [Link] + [Link]
obj = Addition(1000, 2000)
[Link]()
[Link]()

Destructors
• Destructors are called when an object is destroyed.
• In Python, destructors are not often needed due to garbage collection.
• The __del__() method is called when all references to the object are deleted.
class Employee:
def __init__(self):
print('Employee created.')
def __del__(self):
print('Destructor called, Employee deleted.')
obj = Employee()
del obj
49. Encapsulation
class Person:
def __init__(self):
[Link]='Ayansh'
def show(self):
print('Baby {}'.format([Link]))
def setName(self, age):
[Link]=age
obj=Person()
[Link]()
[Link]='Ayansh Singh'
[Link]()
[Link]('Ayansh')
[Link]()

50. Property Decorators: Used to define getters, setters and deleters to control attribute
access (@property).
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name

51. Inheritance.
class Person:
def __init__(self, name):
[Link] = name
def show():
pass
class Baby(Person):
def show(self):
return f"{[Link]} says"
obj = Baby("Ayansh")
print([Link]())

28. Does python supports multiple inheritance?


In Python, multiple inheritance is supported, similar to other object-oriented programming
languages.
Remember, when using multiple inheritance, you need to be mindful of the order in which
you mention the base classes. The order may impact the method resolution order (MRO)
and, therefore, affect how attributes and methods are inherited.

Multiple inheritance:
class Person:
def __init__(self, name):
[Link] = name
class Baby:
def __init__(self, age):
[Link] = age
class Girl(Person, Baby):
def __init__(self, name, age):
super().__init__(name)
[Link] = age
def fun(self):
print([Link], [Link])
obj = Girl("Ayansh", 10)
[Link]()

Multilevel inheritance:
class First:
def __init__(self, num1):
self.num1 = num1
class Second(First):
def __init__(self, num1, num2):
super().__init__(num1)
self.num2 = num2
def add(self):
return self.num1 + self.num2
class Third(Second):
def __init__(self, num1, num2, num3):
super().__init__(num1, num2)
self.num3 = num3
def add(self):
return self.num1 + self.num2 + self.num3
obj = First(10)
obj2 = Second(20, 30)
obj3 = Third(40, 50, 60)
print(obj.num1)
print([Link]())
print([Link]())
52. Private members of parent class.
class Sum(object):
def __init__(self):
self.c = 21
self.__d = 42 # private
class Test(Sum):
def __init__(self):
self.e = 84
Sum.__init__(self)
obj = Test()
print(obj.__d) # AttributeError
print(obj._Sum__d) # 42
Since ‘d’ is made private by those underscores, it is not available to the child class ‘Test’
and hence the error.

20. Function Overloading in Python


Python does not support traditional function overloading. The last defined function with
a given name overwrites previous definitions.
def F1():
print("Function F1 with no arguments")
def F2(arg1, arg2):
print(f"Function F2 with arguments: {arg1}, {arg2}")
# Using default arguments instead (Python does not support function overloading)
def F1(arg1=None, arg2=None):
if arg1 is None and arg2 is None:
print("Function F1 with no arguments")
else:
print(f"Function F1 with arguments: {arg1}, {arg2}")

• Use default arguments to mimic overloading behavior.

20. Does Python Support Function Overloading?


Point Explanation
Function Overloading No — Python does NOT support traditional function
Support overloading
Python does not distinguish functions by parameter type or
Reason
count; names must be unique
If two functions share the same name, the latest definition
Behavior
overrides the previous
Defining F1() and then F1(a, b) → the second one replaces the
Example
first completely
Point Explanation
Using default parameters, *args, and **kwargs to simulate
How Python Handles It
overloading
Workaround Combine all logic inside one function with flexible parameters
Example (Correct
def F1(a=None, b=None): ...
Approach)
The function decides internally what to do based on how many
Why This Works
and which arguments were passed

24. Name Mangling


Name mangling is a mechanism in Python where variables prefixed with __ (double
underscore) are internally renamed to _ClassName__variable to avoid accidental name
conflicts.
class Item:
__x = 10
# Accessing using mangled name
print(Item._Item__x) # Output: 10

# Direct access would raise AttributeError


# print(Item.__x)
• Python prepends _ClassName to private variables.
• Prevents accidental name conflicts.
It helps prevent accidental overriding in subclasses but does not provide true security.

53. Method Overloading


class Person:
def __init__(self, name):
[Link] = name
def add(self, a, b):
print(a + b)
def add(self, a, b):
print(a * b)
obj = Person('Ayansh')
[Link](2, 5)
[Link](2, 5)

Method Overriding
class Animal:
def __init__(self):
pass
def speak(self, price):
[Link] = price
print("Hi", [Link])
obj = Animal()
[Link](1)

#2
class Shape:
def area(self):
return 0
class Rectangle(Shape):
def __init__(self, width, height):
[Link] = width
[Link] = height
def area(self):
return [Link] * [Link]
class Circle(Shape):
def __init__(self, radius):
[Link] = radius
def area(self):
return [Link]**2
shapes = [Rectangle(5, 6), Circle(5)]
for shape in shapes:
print([Link]())

Polymorphism
class Person:
def add(self, a, b):
print(a + b)
class Calculator:
def add(self, a, b):
print(a * b)
# Polymorphism in action:
for obj in (Person(), Calculator()):
[Link](2, 5)

54. Abstract Class


• Abstract classes serve as blueprints and cannot be instantiated directly.
• Python uses the abc module to define abstract classes and methods.

from abc import ABC, abstractmethod


class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Circle(Shape):
def __init__(self, radius):
[Link] = radius
def area(self):
return 3.14 * [Link] * [Link]
def perimeter(self):
return 2 * 3.14 * [Link]
obj = Circle(5)
print([Link]())
print([Link]())

45. Handling Exceptions


Common Built-in Exceptions
• ImportError – module cannot be imported.
• NameError – variable not defined.
• FileNotFoundError – file not found.
• ValueError – correct type but inappropriate value.
• TypeError – wrong type of object.
• IndexError – invalid sequence index.
• KeyError – non-existent dictionary key.

Else clause: runs if no exception occurs.


Finally clause: always runs, used for cleanup.
try:
a=5/0
b = a + '10'
except ZeroDivisionError as e:
print('A ZeroDivisionError occured:', e)
except TypeError as e:
print('A TypeError occured:', e)
else:
print('Everything is ok')
finally:
print('Cleaning up some stuff...')
Custom Exceptions
class ValueTooHighError(Exception):
pass
class ValueTooLowError(Exception):
def __init__(self, message, value):
[Link] = message
[Link] = value
def test_value(a):
if a > 1000:
raise ValueTooHighError("Value is too high.")
if a < 5:
raise ValueTooLowError("Value is too low.", a)
return a
try:
test_value(1)
except ValueTooHighError as e:
print(e)
except ValueTooLowError as e:
print([Link], "The value is:", [Link])

50. NZEC (Non Zero Exit Code)


Occurs when a program fails to return 0.
Often happens on online coding platforms with space-separated inputs:
n, k = input().split(" ")
n = int(n)
k = int(k)
print(n, k)

51. Shallow Copy, Deep Copy


Shallow Copy
list1 = [1, 2, 3, 4]
list2 = [Link]()
list2[1] = 1000
print(list1) # unaffected
print(list2)

• Nested list issue:


list1 = [[1,2,3,4],[3,4,5,6]]
list2 = [Link]()
list2[1][0] = 1000
print(list1) # inner list affected
print(list2)
Deep Copy
import copy
list1 = [[1,2,3,4],[6,7,8,9]]
list2 = [Link](list1)
list2[0][0] = -10
print(list1) # unaffected
print(list2)

52. Define pickling and unpickling.


Python’s ways to serialize and deserialize objects.
Pickling is the process of converting Python objects, such as lists, dicts, etc., into a
character stream.
import pickle
# ---------- Pickling ----------
mylist = ['a', 'b', 'c', 'd']
# Serialize (write binary)
with open('[Link]', 'wb') as fh:
[Link](mylist, fh)

# ---------- Unpickling ----------


with open('[Link]', 'rb') as fh:
loaded_list = [Link](fh)
print("Original list:", mylist)
print("Loaded list:", loaded_list)

Difference between Pickling and Unpickling.


Feature Pickling Unpickling
Converting a Python object into a Converting a byte stream back into a
Meaning
byte stream Python object
Direction Object → Bytes Bytes → Object
Restore or use previously saved Python
Purpose Save or transfer Python objects
objects
Function
[Link]() / [Link]() [Link]() / [Link]()
Used
Writes serialized data to a file or Reads serialized data from a file or
Storage
memory memory
Usage
Serialization Deserialization
Scenario
53. Monkey patching: Changing or extending the behavior of classes or modules at
runtime.
[Link]
class X:
def func(self):
print("func() is being called")

# ---------- main ----------


import monkeyy
# Define a new function to replace the original one
def monkey_f(self):
print("monkey_f() is being called")
# Replace (patch) the original method at runtime
[Link] = monkey_f
obj = monkeyy.X()
[Link]()

Generators
• Functions that can be paused/resumed using yield, returning an object that can be
iterated over.
• Generators are functions that can be paused and resumed, returning an object that
can be iterated over.
• They are lazy and thus produce items one at a time and only when asked.

Advantages:
• Lazy evaluation, memory-efficient.
• Produce items one at a time.

def countdown(num):
print('Starting')
while num > 0:
yield num
num -= 1
cd = countdown(3)
print(next(cd))
print(next(cd))
print(next(cd))
# Without generator
def firstn(n):
num, nums = 0, []
while num < n:
[Link](num)
num += 1
return nums

sum_of_first_n = sum(firstn(1000000))
import sys
print([Link](firstn(1000000)), "bytes")

Fibonacci Generator
def fibonacci(limit):
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
fib = fibonacci(30)
print(list(fib))

Custom Generator Class


class firstn:
def __init__(self, n):
self.n = n
[Link] = 0
def __iter__(self):
return self
def __next__(self):
if [Link] < self.n:
cur = [Link]
[Link] += 1
return cur
else:
raise StopIteration()
firstn_object = firstn(1000000)
print(sum(firstn_object))

54. Threading
When Threading is Useful
• I/O-bound tasks: network, disk operations.
• Allows program to perform other tasks while waiting.

from time import sleep


from threading import Thread
class Hello(Thread):
def run(self):
for i in range(500):
print("Hello")
sleep(1)
class Hi(Thread):
def run(self):
for i in range(500):
print("Hi")
sleep(1)
t1 = Hello()
t2 = Hi()
[Link]()
sleep(0.2)
[Link]()
[Link]()
[Link]()
print("Bye")

56. Multiprocessing
Creating a process using [Link]():
target: callable function to run in the process.
args: tuple of arguments to pass to the function.
start(): begins execution of the process.
join(): waits for the process to finish before continuing.

from multiprocessing import Process


import os
def sqrt():
for i in range(1000):
result = i * i
print(result)
if __name__ == "__main__":
processes = []
num = os.cpu_count() # number of CPUs on the machine
print(f"Creating {num} processes...")
# create processes and assign a function for each process
for i in range(num):
process = Process(target=sqrt)
[Link](process)
# start all processes
for process in processes:
[Link]()
# wait for all processes to finish
for process in processes:
[Link]()
17. Iterators
Access elements one at a time using iter() and next().
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)

print(next(my_iterator)) # 1
print(next(my_iterator)) # 2
print(next(my_iterator)) # 3

• Iterators provide a pointer-like access to sequence elements.

18. Using next() with Iterators


The next() method retrieves the next element pointed by the iterator.
try:
print(next(my_iterator))
except StopIteration:
print("Iterator exhausted. No more elements.")

• Calling next() repeatedly allows sequential access.


• Once all elements are traversed, StopIteration is raised.
• Using try-except handles this gracefully.

57. Iterators
class RemoteControl:
def __init__(self):
[Link] = ["HBO","CNN","ESPN"]
[Link] = -1
def __iter__(self):
return self
def __next__(self):
[Link] += 1
if [Link] == len([Link]):
raise StopIteration
return [Link][[Link]]

class Condition:
class Condition:
def __init__(self, a):
self.a = a
def __gt__(self, other):
return self.a > other.a
obj1 = Condition(2)
obj2 = Condition(3)
if obj1 > obj2:
print("obj1")
else:
print("obj2")

# Divisions:
print(5 // 2) # Floor division → 2
print(-5.0 / 2) # True division → -2.5

5. Using setitem, getitem, delitem with lists


import operator
li = [1, 5, 6, 7, 8]
for i in range(len(li)):
print(li[i], end=" ")
print()
[Link](li, 3, 3) # set 3 at 4th position
for i in range(len(li)):
print(li[i], end=" ")
print()
[Link](li, 1)
for i in range(len(li)):
print(li[i], end=" ")
print()
print([Link](li, 3))

6. Using slices with setitem, getitem, delitem


import operator

li = [1, 5, 6, 7, 8]
for i in range(len(li)):
print(li[i], end=" ")
print()
[Link](li, slice(1, 4), [2, 3, 4]) # assign 2, 3, 4 at index 1 to 3
for i in range(len(li)):
print(li[i], end=" ")
print()
[Link](li, slice(2, 4)) # delete elements at index 2 and 3
for i in range(len(li)):
print(li[i], end=" ")
print()
print([Link](li, slice(0, 2)))

25. Conditions
print("Welcome to the rollercoaster")
height = int(input("What is your height in cm? "))
if height >= 120:
print("You can ride")

age = int(input("What is your age:"))


if age <= 12:
print("Please pay $5")
elif age <= 18:
print("Please pay $7")
else:
print("Please pay $10")
else:
print("Sorry")

26. Loops and iteration helpers


enumerate(), zip(), items()
# Enumerate
for key, value in enumerate(['The', 'Big', 'Bang', 'Theory']):
print(key, value)

# Zip
questions = ['name', 'colour', 'shape']
answers = ['apple', 'red', 'a circle']
for question, answer in zip(questions, answers):
print('What is your {0}? I am {1}.'.format(question, answer))

# Dictionary items
king = {'Akbar': 'The Great', 'Chandragupta': 'The Maurya', 'Modi': 'The Changer'}
for key, value in [Link]():
print(key, value)

# Dictionary iteration
d = dict()
d['xyz'] = 123
d['abc'] = 345
for i in d:
print("%s %d" % (i, d[i]))
15. Decorators
• A decorator extends the behavior of a function without modifying it directly.
• Use @decorator syntax.
def decor_result(result_function):
def distinction(marks):
for mark in marks:
if mark < 33:
print("Failed")
break
else:
print("Passed")
if all(mark >= 75 for mark in marks):
print("Distinction")
return distinction
@decor_result
def result(marks):
for mark in marks:
if mark < 33:
print("Failed")
break
else:
print("Passed")
result([80, 85, 90])
• Decorators wrap and extend functionality dynamically.
• Use @decorator_name above the function.

Function Decorators
def start_end_decorator(func):
def wrapper():
print('Start')
func()
print('End')
return wrapper
def print_name():
print('Alex')
print_name = start_end_decorator(print_name)
print_name()
Decorator Syntax
@start_end_decorator
def print_name():
print('Alex')
print_name()
Function Arguments
def start_end_decorator_2(func):
def wrapper(*args, **kwargs):
print('Start')
func(*args, **kwargs)
print('End')
return wrapper
@start_end_decorator_2
def add_5(x):
return x + 5
result = add_5(10)
print(result)

Returning Values
def start_end_decorator_3(func):
def wrapper(*args, **kwargs):
print('Start')
result = func(*args, **kwargs)
print('End')
return result
return wrapper

@start_end_decorator_3
def add_5(x):
return x + 5
result = add_5(10)
print(result)

Preserving Function Identity


import functools
def my_decorator(func):
@[Link](func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result
return wrapper

Decorator Function Arguments


• [Link] can be used inside decorators with arguments.
• Example: A repeat decorator that repeats a function num_times:
import functools
def repeat(num_times):
def decorator_repeat(func):
@[Link](func)
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator_repeat
@repeat(num_times=3)
def greet(name):
print(f"Hello {name}")
greet('Alex')

Nested Decorators
• Multiple decorators can be stacked; executed from bottom to top:
def debug(func):
@[Link](func)
def wrapper(*args, **kwargs):
args_repr = [repr(a) for a in args]
kwargs_repr = [f"{k}={v!r}" for k, v in [Link]()]
signature = ", ".join(args_repr + kwargs_repr)
print(f"Calling {func.__name__}({signature})")
result = func(*args, **kwargs)
print(f"{func.__name__!r} returned {result!r}")
return result
return wrapper
@debug
@start_end_decorator_4
def say_hello(name):
greeting = f'Hello {name}'
print(greeting)
return greeting
say_hello(name='Alex')

Class Decorators
• Classes can also be used as decorators by implementing the __call__() method:
import functools
class CountCalls:
def __init__(self, func):
functools.update_wrapper(self, func)
[Link] = func
self.num_calls = 0
def __call__(self, *args, **kwargs):
self.num_calls += 1
print(f"Call {self.num_calls} of {[Link].__name__!r}")
return [Link](*args, **kwargs)
@CountCalls
def say_hello(num):
print("Hello!")
say_hello(5)
say_hello(5)

Use Cases of Decorators


• Timer decorator to calculate execution time.
• Debug decorator to print arguments and return values.
• Check decorator to validate arguments.
• Register functions (plugins).
• Slow down code using [Link]() for testing.
• Cache return values for memoization.
• Maintain or update state.

# Lambda with map, filter, reduce


list(filter(lambda x: x > 6, range(9)))
list(map(lambda x: x**2, range(6)))
from functools import reduce
reduce(lambda x, y: x - y, [1,2,3,4,5])

Examples
# Lambda with one argument
f = lambda x: x + 10
val1 = f(5)
val2 = f(100)
print(val1, val2)

# Lambda with two arguments


f = lambda x, y: x * y
val3 = f(2, 10)
val4 = f(7, 5)
print(val3, val4)

Lambda inside another function


def myfunc(n):
return lambda x: x * n
doubler = myfunc(2)
print(doubler(6)) # Output: 12
points2D = [(1, 9), (4, 1), (5, -3), (10, 2)] # Custom sorting using lambda as key
sorted_by_y = sorted(points2D, key=lambda x: x[1])
print(sorted_by_y) # Sort by 2nd element (y value)
mylist = [-1, -4, -2, -3, 1, 2, 3, 4]
sorted_by_abs = sorted(mylist, key=lambda x: abs(x))
print(sorted_by_abs) # Sort by absolute values

Lambda with map() and filter()


a = [1, 2, 3, 4, 5, 6]
b = list(map(lambda x: x * 2, a))
c = [x * 2 for x in a]
print(b)
print(c)

b = list(filter(lambda x: (x % 2 == 0), a))


c = [x for x in a if x % 2 == 0]
print(b)
print(c)

Lambda with reduce()


from functools import reduce
a = [1, 2, 3, 4]
product_a = reduce(lambda x, y: x * y, a)
sum_a = reduce(lambda x, y: x + y, a)
print(product_a)
print(sum_a)

Iterators and StopIteration


class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)

Map Function
def addition(n):
return n + n
# Pass one or more iterables to the map() function
numbers = (1, 2, 3, 4)
result = map(addition, numbers)
print(list(result))

Template Encode and Decode Functions for Custom Classes


class User:
def __init__(self, name, age, active, balance, friends):
[Link] = name
[Link] = age
[Link] = active
[Link] = balance
[Link] = friends
class Player:
def __init__(self, name, nickname, level):
[Link] = name
[Link] = nickname
[Link] = level
# Encoder function
def encode_obj(obj):
obj_dict = {
"__class__": obj.__class__.__name__,
"__module__": obj.__module__
}
obj_dict.update(obj.__dict__)
return obj_dict
# Decoder function
def decode_dct(dct):
if "__class__" in dct:
class_name = [Link]("__class__")
module_name = [Link]("__module__")
module = __import__(module_name)
class_ = getattr(module, class_name)
obj = class_(**dct)
else:
obj = dct
return obj
# Usage examples
user = User(
name="John",
age=28,
friends=["Jane", "Tom"],
balance=20.70,
active=True
)
userJSON = [Link](user, default=encode_obj, sort_keys=True)
print(userJSON)
user_decoded = [Link](userJSON, object_hook=decode_dct)
print(type(user_decoded))
player = Player('Max', 'max1234', 5)
playerJSON = [Link](player, default=encode_obj, sort_keys=True)
print(playerJSON)
player_decoded = [Link](playerJSON, object_hook=decode_dct)
print(type(player_decoded))

Memory and Object References


Get memory address
class A:
pass
obj = A()
print(id(obj))
# Copying Objects
list1 = [1, 2, 3, 4]
list2 = list1
list2[1] = 1000
print(list1) # same memory
print(list2)

Custom Objects
class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age
p1 = Person('Alex', 27)
p2 = p1 # only copies reference
[Link] = 28
print([Link]) # 28
print([Link]) # 28
Monkey Patching: Modifying a class/module behavior at runtime.
# [Link]
class X:
def func(self):
print("func() is being called")

import monkeyy
def monkey_f(self):
print("monkey_f() is being called")
[Link] = monkey_f # Replace func with monkey_f
obj = monkeyy.X()
[Link]()
class Test: # Example with Test class
def __init__(self, x):
self.a = x
def get_data(self):
print("Some code to fetch data from database")
def f1(self):
self.get_data()
def f2(self):
self.get_data()
t1 = Test(5)
def new_get_data(self): # New method to replace get_data
print("Some code to fetch data from test data")
Test.get_data = new_get_data # Monkey patching the Test class
print("After Monkey Patching")
t1.f1()
t1.f2()

Threading vs Multiprocessing
Process
• Independent instance of a program.
• Separate memory, avoids GIL limitations.
• Great for CPU-bound tasks.
• Slower to start, larger memory footprint.

Thread
• Entity within a process.
• Shared memory.
• Faster to start, low memory footprint.
• Good for I/O-bound tasks.
• Limited by GIL for CPU-bound tasks.
Python Threading Example
from time import sleep
from threading import Thread
from multiprocessing import Process
import os
def sqrt():
for i in range(1000):
result = i * i
print(result)
if __name__ == "__main__":
processes = []
num = os.cpu_count() # number of CPUs
for i in range(num): # Create a process for each CPU
process = Process(target=sqrt)
[Link](process)
for process in processes: # Start all processes
[Link]()
for process in processes: # Wait for all processes to finish
[Link]()

When Multiprocessing is Useful


• For CPU-bound tasks involving heavy computation on large datasets.
• Example: Calculate squares for 1 to 1,000,000 by splitting numbers across
multiple processes.

Global Interpreter Lock (GIL)


A mutex that allows only one thread to execute Python bytecode at a time.
Reason: CPython uses reference counting for memory management, which is not
thread-safe. The GIL prevents race conditions on reference counts.

Ways to avoid GIL:


• Use multiprocessing instead of threading.
• Use free-threaded Python implementations like Jython or IronPython.
• Offload computation to binary extension modules (e.g., NumPy, SciPy).

Sharing Data Between Threads


Threads share memory, so race conditions may occur.
from threading import Thread
import time
database_value = 0
def increase():
global database_value
local_copy = database_value
local_copy += 1
[Link](0.1)
database_value = local_copy
if __name__ == "__main__":
print('Start value:', database_value)
t1 = Thread(target=increase)
t2 = Thread(target=increase)
[Link]()
[Link]()
[Link]()
[Link]()
print('End value:', database_value)
print('end main')

Sharing Data Between Processes


Processes do not share memory by default. Use Value or Array for shared memory.
from multiprocessing import Process, Value, Array
import time
def add_100(number):
for _ in range(100):
[Link](0.01)
[Link] += 1
def add_100_array(numbers):
for _ in range(100):
[Link](0.01)
for i in range(len(numbers)):
numbers[i] += 1
if __name__ == "__main__":
shared_number = Value('i', 0)
shared_array = Array('d', [0.0, 100.0, 200.0])
process1 = Process(target=add_100, args=(shared_number,))
process2 = Process(target=add_100, args=(shared_number,))
process3 = Process(target=add_100_array, args=(shared_array,))
process4 = Process(target=add_100_array, args=(shared_array,))
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
print('Value at end:', shared_number.value)
print('Array at end:', shared_array[:])
print('end main')

Locks to Avoid Race Conditions


Race Condition Example: Two threads modify a shared value simultaneously, causing
inconsistent results.
Solution: Use Locks.
from threading import Thread, Lock
import time
from multiprocessing import Value
def add_100(number, lock):
for _ in range(100):
[Link](0.01)
with lock: # safely lock and unlock
[Link] += 1

Lock Features:
[Link]() – locks the resource.
[Link]() – unlocks the resource.
Recommended: use context manager (with lock) to automatically handle
acquire/release.

Using Queues in Python


Queues are thread-safe and process-safe for data exchange.
from queue import Queue

q = Queue() # create queue


[Link](1)
[Link](2)
[Link](3)
first = [Link]() # removes first item
print(first)

Thread-Safe Queue Operations


• [Link](): remove & return first item (blocks if empty)
• [Link](item): add item (blocks if full)
• q.task_done(): indicate a processed item
• [Link](): block until all items processed
• [Link](): check if queue is empty

Queue with Multiple Threads


from threading import Thread, Lock, current_thread
from queue import Queue
def worker(q, lock):
while True:
value = [Link]() # blocks until item is available
with lock:
print(f"in {current_thread().name} got {value}")
q.task_done()
if __name__ == '__main__':
q = Queue()
num_threads = 10
lock = Lock()
for i in range(num_threads):
t = Thread(name=f"Thread{i+1}", target=worker, args=(q, lock))
[Link] = True # dies when main thread dies
[Link]()
for x in range(20): # fill queue
[Link](x)
[Link]() # wait until all items are processed
print('main done')

Daemon Threads
• Background threads that die when the main program exits.
• Infinite loops inside workers exit automatically.
• Resources may not be fully released if abruptly stopped.

Process Pools
A process pool manages a pool of worker processes to which jobs can be submitted.
Supports asynchronous results, timeouts, callbacks, and parallel map implementation.
Automatically manages available processors and splits data into smaller chunks for
parallel processing.

Important Methods:
map(func, iterable[, chunksize]): Chops the iterable int chunks, submits t the pool,
blocks until results ready.
close(): Prevents more tasks from being submitted.
join(): Waits for worker processes exit (must call close() first).
apply(func, args): Executes func with args in one worker, blocks until done.
Async variants: map_async() and apply_async().

from multiprocessing import Pool


def cube(number):
return number * number * number
if __name__ == "__main__":
numbers = range(10)
# Create a pool with the maximum number of available processors
with Pool() as p:
result = [Link](cube, numbers)
print(result)

# Alternative:
# result = [[Link](cube, args=(i,)) for i in numbers]

Collections Module
1. Counter
• Subclass of dict that counts elements.
• Elements as keys, counts as values. Can store zeros or negatives.
from collections import Counter
print(Counter(['B','B','A','B','C','A','B','B','A','C'])) # Sequence
print(Counter({'A':3, 'B':5, 'C':2}))

# Dictionary
print(Counter(A=3, B=5, C=2))

# Updating counter
coun = Counter()
[Link](['A','B','A'])
print(coun)

# Subtracting counters
c1 = Counter(A=4, B=3, C=10)
c2 = Counter(A=10, B=3, C=4)
[Link](c2)
print(c1)

# Count distinct elements


z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
print(Counter(z))

2. OrderedDict
• Subclass of dict that preserves insertion order.
• Key/value changes do not affect order. Deletion and reinsertion moves key to the
end.
# Creating OrderedDict
from collections import OrderedDict
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3
od['d'] = 4

# Key value change


od['c'] = 5

# Deletion and reinsertion


[Link]('c')
od['c'] = 3

3. Defaultdict
Subclass of dict that provides default values for missing keys (avoids KeyError).

from collections import defaultdict


def def_value():
return "Not Present"
d = defaultdict(def_value) # Using a default function
d["a"] = 1
d["b"] = 2
print(d["c"]) # Output: "Not Present"
d = defaultdict(lambda: "Not Present") # Using a lambda function
print(d.__missing__('a')) # Output: "Not Present" (key 'a' not set)
print(d.__missing__('d')) # Output: "Not Present" (key 'd' not set)

4. UserDict
Wrapper around a dictionary to customize behavior.

# Using UserDict with a regular dictionary


from collections import UserDict
d = {'a': 1, 'b': 2, 'c': 3}
userD = UserDict(d)
print([Link]) # Output: {'a': 1, 'b': 2, 'c': 3}
# Custom Dictionary: prevent deletion
class MyDict(UserDict):
def __delitem__(self, key):
raise RuntimeError("Deletion not allowed")
def pop(self, key=None):
raise RuntimeError("Deletion not allowed")
def popitem(self):
raise RuntimeError("Deletion not allowed")
d = MyDict({'a': 1, 'b': 2, 'c': 3})
print(d) # Output: {'a': 1, 'b': 2, 'c': 3}

5. UserList
Wrapper around a list to customize behavior.
from collections import UserList
L = [1, 2, 3, 4]
userL = UserList(L)
print([Link])

6. UserString
Wrapper around strings to customize behavior.

# Example with Mutable String


from collections import UserString
class Mystring(UserString):
def append(self, s):
[Link] += s
def remove(self, s):
[Link] = [Link](s, "")
s1 = Mystring("Geeks")
print("Original String:", [Link])
[Link]("s")
print("String After Appending:", [Link])
[Link]("e")
print("String after Removing:", [Link])

Collections Module (Advanced Tools)


Provides specialized container datatypes as alternatives to Python’s built-in dict, list, set,
and tuple.
1. namedtuple
• Lightweight object type; fields can be accessed by name.
• Usage: namedtuple('ClassName', 'field1 field2')

from collections import namedtuple


Point = namedtuple('Point','x, y')
pt = Point(1, -4)
print(pt)
print(pt._fields)
print(type(pt))
print(pt.x, pt.y)
Person = namedtuple('Person','name, age')
friend = Person(name='Tom', age=25)
print([Link], [Link])

3. ChainMap
• Encapsulates multiple dictionaries into one view.
• Useful for combining contexts or configuration layers.

from collections import ChainMap


d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
d3 = {'f': 5}
chain = ChainMap(d1, d2)
print([Link])
# [{'a': 1, 'b': 2}, {'b': 3, 'c': 4}]
chain1 = chain.new_child(d3)
print([Link])
print(chain1['b'])
# add new dict to front
# first dict takes precedence
[Link] = reversed([Link]) # reverse dict order
print(chain1['b'])

6. Capturing Stack Traces


Useful for troubleshooting exceptions.
import logging
import traceback
try:
a = [1, 2, 3]
value = a[3]
except IndexError as e:
[Link](e)
[Link](e, exc_info=True)

# Using traceback.format_exc()
try:
a = [1, 2, 3]
value = a[3]
except:
[Link]("uncaught exception: %s", traceback.format_exc())
4. Context Managers (Generator Approach)
• Can implement with statement functionality without a class.
• Use [Link] decorator.

from contextlib import contextmanager


@contextmanager
def open_managed_file(filename):
f = open(filename, 'w')
try:
yield f
finally:
[Link]()
# Using the custom context manager
with open_managed_file('[Link]') as f:
[Link]('some todo...')

• Explanation: Generator acquires resource, yields it to caller, then cleans up in


finally.

5. Password Validation (Without Regex)


def password_check(passwd):
SpecialSym = ['$', '@', '#', '%']
val = True

if len(passwd) < 6:
print('length should be 6')
val = False

if len(passwd) > 20:


print('length should not > 20')
val = False

if not any([Link]() for char in passwd):


print('Password should have at least one numeral')
val = False

if not any([Link]() for char in passwd):


print('Password should have at least one uppercase letter')
val = False

if not any([Link]() for char in passwd):


print('Password should have at least one lowercase letter')
val = False
if not any(char in SpecialSym for char in passwd):
print('Password should have at least one of the symbols $@#')
val = False

if val:
return val

def main():
passwd = 'Geek12@'
if password_check(passwd):
print("Password is valid")
else:
print("Invalid Password !!")

if __name__ == '__main__':
main()

6. Password Validation Using Regex


import re
def main():
passwd = 'Geek12@'
reg = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{6,20}$"
pat = [Link](reg) # compile regex
mat = [Link](pat, passwd) # search regex
if mat:
print("Password is valid.")
else:
print("Password invalid !!")
if __name__ == '__main__':
main()

7. Password Generator
import random
letters = [chr(i) for i in range(97, 123)] + [chr(i) for i in range(65, 91)]
numbers = [str(i) for i in range(10)]
symbols = ['!', '#', '$', '%', '&', '(', ')', '*', '+']
print("Welcome to the PyPassword Generator!")
nr_letters = int(input("How many letters would you like in your password?: "))
nr_symbols = int(input(f"How many symbols would you like?: "))
nr_numbers = int(input(f"How many numbers would you like?: "))
# Easy Level
password = ""
for char in range(1, nr_letters + 1):
password += [Link](letters)
for char in range(1, nr_symbols + 1):
password += [Link](symbols)
for char in range(1, nr_numbers + 1):
password += [Link](numbers)
print(password)

# Hard Level
password_list = []
for char in range(1, nr_letters + 1):
password_list.append([Link](letters))
for char in range(1, nr_symbols + 1):
password_list += [Link](symbols)
for char in range(1, nr_numbers + 1):
password_list += [Link](numbers)
[Link](password_list)
password = "".join(password_list)
print(f"Your password is: {password}")
Python Advanced Topics: Regex & Tkinter GUI

1. Regular Expressions (Regex)


Searching an Occurrence of a Pattern
import re
regex = r"([a-zA-Z]+) (\d+)" # Corrected: \d+ instead of d+
match = [Link](regex, "I was born on June 24")
if match != None:
print("Match at index %s, %s" % ([Link](), [Link]()))
print("Full match: %s" % ([Link](0)))
print("Month: %s" % ([Link](1)))
print("Day: %s" % ([Link](2)))
else:
print("The regex pattern does not match.")

Matching Using [Link]()


def findMonthAndDate(string):
regex = r"([a-zA-Z]+) (\d+)"
match = [Link](regex, string)
if match == None:
print("Not a valid date")
return
print("Given Data: %s" % ([Link]()))
print("Month: %s" % ([Link](1)))
print("Day: %s" % ([Link](2)))
findMonthAndDate("Jun 24")
print("")
findMonthAndDate("I was born on June 24")

Finding All Matches


string = """Hello my Number is 123456789 and
my friend's number is 987654321"""
regex = r'\d+'
match = [Link](regex, string)
print(match)

2. Logic and Algorithms


Decimal ↔ Binary Conversion
Decimal → Binary
binary_num, base = 0, 1
decimal_num = int(input("Enter a Decimal number:"))

while decimal_num > 0:


remainder = decimal_num % 2
binary_num = binary_num + remainder * base
decimal_num = decimal_num // 2
base = base * 10

print(binary_num)
Binary → Decimal
decimal_val, base = 0, 1
binary_val = 1010

while binary_val > 0:


rem = binary_val % 10
decimal_val = decimal_val + rem * base
binary_val = binary_val // 10
base = base * 2

print(decimal_val)

58. Leap Year Check


year = int(input("Which year you want to check? "))
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
print(f"{year} is a Leap Year")
else:
print(f"{year} is not a Leap Year")
else:
print(f"{year} is a Leap Year")
else:
print(f"{year} is not a Leap Year")

Factorial
n=4
fact = 1
for i in range(1, n+1):
fact *= i
print(fact)

First N Numbers
def printFun():
num = 10
for i in range(1, num):
print(i, end=",")
printFun()

Sum of Natural Numbers


def printFun():
num = 10
result = 0
for i in range(1, num):
result += i
print(result, end=",")
printFun()

Multiply N Numbers Without *


def multiply():
num1 = 3
num2 = 4
product = 0
for i in range(0, num2):
product += num1
print(product)
multiply()

Reverse Numbers
def printFun():
num = 10
for i in range(num, 0, -1):
print(i, end=",")
printFun()
First Digit of Number
def firstDigit():
n = 123
while n >= 10:
n = n // 10
print(n)
firstDigit()

Odd or Even Numbers


def firstEODigit():
n = 10
for i in range(1, n):
if i % 2 == 0:
print('even', i)
else:
print('Odd', i)
firstEODigit()

Armstrong Number
num = 407
sum = 0
temp = num
while temp > 0:
digit = temp % 10
sum += digit ** 3
temp //= 10
if num == sum:
print(num, "is an Armstrong number")
else:
print(num, "is not an Armstrong number")
Count Number of Each Vowel
vowels = 'aeiou'
str = 'Hello, have you tried our tutorial section yet?'
str = [Link]()
count = {}.fromkeys(vowels, 0)
for char in str:
if char in count:
count[char] += 1
print(count)

Fibonacci Sequence (<80)


a, b = 0, 1
while b < 80:
c=a+b
print(c)
a=b
b=c

Palindrome Check
def palindrom():
str = 'madam'
str2 = ''
for i in str:
str2 = i + str2
if str == str2:
print('Palindrome', str2)
else:
print('Not Palindrome', str2)
palindrom()

Prime Numbers (0-10)


for num in range(0, 10 + 1):
for i in range(2, num):
if (num % i) == 0:
break
else:
print(num)

Alternative Method
def pyraminds():
num = 100
for i in range(1, num):
count = 0
for j in range(2, i):
if (i % j == 0):
count += 1
if count < 1:
print(i)
pyraminds()

Shuffle Deck of Cards


import itertools, random
deck = list([Link](range(1,14), ['Spade','Heart','Diamond','Club']))
[Link](deck)
for i in range(5):
print(deck[i][0], "of", deck[i][1])

Itertools Functions
product()
from itertools import product
# Cartesian product
prod = product([1, 2], [3, 4])
print(list(prod))

# product with repeat


prod = product([1, 2], [3], repeat=2)
print(list(prod))
permutations()
from itertools import permutations
perm = permutations([1, 2, 3])
print(list(perm))
perm = permutations([1, 2, 3], 2) # length of permutation tuples
print(list(perm))

combinations() and combinations_with_replacement()


from itertools import combinations, combinations_with_replacement
comb = combinations([1, 2, 3, 4], 2)
print(list(comb))
comb = combinations_with_replacement([1, 2, 3, 4], 2)
print(list(comb))
accumulate()
from itertools import accumulate
import operator
Infinite Iterators: count(), cycle(), repeat()
from itertools import count, cycle, repeat
# count
for i in count(10):
print(i)
if i >= 13:
break

# cycle
sum = 0
for i in cycle([1, 2, 3]):
print(i)
sum += i
if sum >= 12:
break

# repeat
for i in repeat("A", 3):
print(i)

# accumulated sums
acc = accumulate([1,2,3,4])
print(list(acc))

# accumulated multiplication
from itertools import accumulate, groupby
# Using accumulate with max function
acc = accumulate([1, 5, 2, 6, 3, 4], func=max)
print(list(acc))

# Using groupby
def smaller_than_3(x):
return x < 3 # function as key
group_obj = groupby([1, 2, 3, 4], key=smaller_than_3)
for key, group in group_obj:
print(key, list(group))

Star Patterns
Single-Sided Star
n=3
for i in range(n, 0, -1):
print((n-i) * ' ' + i * '*')
Double-Sided Star
def pattern():
n = 10
for i in range(1, n+1):
k = i + 1 if i % 2 != 0 else i
for g in range(k, n):
print(end=" ")
for j in range(0, k):
if j == k - 1:
print(" * ")
else:
print(" * ", end=" ")
pattern()

LCM of Two Numbers


def lcm(x, y):
if x > y:
greater = y
else:
greater = x
for i in range(1, greater + 1):
if (x % i == 0) and (y % i == 0):
lcm_val = i
return lcm_val
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
print("The L.C.M. of", num1, "and", num2, "is", lcm(num1, num2))

Largest of Three Numbers


num1 = 10
num2 = 14
num3 = 12
if (num1 >= num2) and (num1 >= num3):
largest = num1
elif (num2 >= num1) and (num2 >= num3):
largest = num2
else:
largest = num3
print("The largest number is", largest)
HCF of Two Numbers
def hcf(x, y):
smaller = min(x, y)
for i in range(1, smaller + 1):
if x % i == 0 and y % i == 0:
hcf_val = i
return hcf_val
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
print("The H.C.F. of", num1, "and", num2, "is", hcf(num1, num2))

Area of Triangle (Heron’s Formula)


a=5
b=6
c=7
s = (a + b + c) / 2 # semi-perimeter
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('The area of the triangle is %0.2f' % area)

# Compound interest
def compound_interest(principle, rate, time):
CI = principle * (pow((1 + rate / 100), time))
print("Compound interest is", CI)
compound_interest(10000, 10.25, 5)

Convert 12-hour to 24-hour Time


def convert24(str1):
if str1[-2:] == "AM" and str1[:2] == "12":
return "00" + str1[2:-2]
elif str1[-2:] == "AM":
return str1[:-2]
elif str1[-2:] == "PM" and str1[:2] == "12":
return str1[:-2]
else:
return str(int(str1[:2]) + 12) + str1[2:8]
print(convert24("08:05:45 PM"))

19. Calculate Percentiles using NumPy


import numpy as np

a = [Link]([1, 2, 3, 4, 5, 6, 7])
p = [Link](a, 50)
print(p)

20. Data Conversion: int(), float(), bool()


birth_year = input('Birth Year: ')
print(type(birth_year))
age = 2019 - int(birth_year)
print(age)

21. Pounds to Kilograms Conversion


weight_lbs = input('Weight(lbs):')
weight_kg = int(weight_lbs) * 0.45
print(weight_kg)

22. Remove Duplicates from a List


numbers = [5, 4, 3, 6, 7, 3, 6]
uniques = []
for number in numbers:
if number not in uniques:
[Link](number)
print(uniques)

13. Palindome
def palindrom():
str_ = 'madam'
str2 = ''
for i in str_:
str2 = i + str2
if str_ == str2:
print('Palindrome:', str2)
else:
print('Not Palindrome:', str2)
palindrom()

23. Find Maximum Number in Array


numbers = [10, 3, 6, 2]
max_val = numbers[0]
for number in numbers:
if number > max_val:
max_val = number
print("Maximum value:", max_val)

# Sum of Three Maximum Numbers


def maxSum():
num = [2, 3, 5, 6, 0, 8]
[Link]()
sum_val = num[-1] + num[-2] + num[-3]
print("Sum of three maximum numbers:", sum_val)
maxSum()

24. Compare Two Tuples for Equality


print("Enter elements separated by comma for first tuple")
t1 = tuple([eval(e) for e in input().split(',')])
print("Enter elements separated by comma for second tuple")
t2 = tuple([eval(e) for e in input().split(',')])
if t1 == t2:
print("Tuples are same")
else:
print("Tuples are different")

# Remove Duplicate Characters from String


s = 'Enter a string'
i=0
s1 = ""
for x in s:
if [Link](x) == i:
s1 += x
i += 1
print(s1)

26. Arrange Three Words in Dictionary Order


print("Enter three city names")
a, b, c = input(), input(), input()
if a < b < c:
print(a, b, c)
elif a < c < b:
print(a, c, b)
elif b < a < c:
print(b, a, c)
elif b < c < a:
print(b, c, a)
elif c < a < b:
print(c, a, b)
else:
print(c, b, a)

27. Output of map(list, x)


x = ['ab', 'cd']
print(len(list(map(list, x))))
# Each element of x is converted into a list

28. Palindrome Check (Non-Iterative)


def fun(string):
s1 = string
s = string[::-1]
if s1 == s:
return 'true'
else:
return 'false'
print(fun('madam'))

29. Sum of List Using Recursion


def sum_list(num):
if len(num) == 1:
return num[0]
else:
return num[0] + sum_list(num[1:])
print(sum_list([2, 4, 5, 6, 7]))

30. Read a Random Line from File


import random
def read_random(fname):
lines = open(fname).read().splitlines()
return [Link](lines)

31. Shuffle List in Place


import random
lst = [2, 18, 8, 4]
print("Prior Shuffling - 0", lst)
[Link](lst)
print("After Shuffling - 1", lst)
[Link](lst)
print("After Shuffling - 2", lst)
32. Default Mutable Arguments Pitfall
def fast(items=[]):
[Link](1)
return items
print(fast()) # [1]
print(fast()) # [1, 1]

34. Nested loop


for x in range(4):
for y in range(3):
print(f'({x}, {y})')

35. List-Based Patterns


numbers = [5, 2, 5, 2, 2]
for x_count in numbers:
output = ''
for count in range(x_count):
output += 'X'
print(output)

37. Phone Digit to Words


phone = input("Phone: ")
digits_mapping = {
"1": "One",
"2": "Two",
"3": "Three",
"4": "Four"
}
output = ""
for ch in phone:
output += digits_mapping.get(ch, "!") + " "
print(output)

38. Emoji Converter


def emoji_converter(message):
words = [Link](" ")
emojis = {":)": "*", ":(": "%"}
output = ""
for word in words:
output += [Link](word, word) + " "
return output
message = input(">")
print(emoji_converter(message))
39. Generate Random Numbers
import random
for i in range(3):
print([Link](10, 20))

40. Dice Simulator


import random
class Dice:
def roll(self):
first = [Link](1, 6)
second = [Link](1, 6)
return first, second
dice = Dice()
print([Link]())

41. Read Excel Spreadsheet


import openpyxl as xl
wb = xl.load_workbook('[Link]')
sheet = wb['Sheet1']
cell = sheet['A1']
print([Link])
for row in range(2, sheet.max_row + 1):
cell = [Link](row, 3)
print([Link])

42. Create New Column in Excel


import openpyxl as xl
wb = xl.load_workbook('[Link]')
sheet = wb['Sheet1']
for row in range(2, sheet.max_row + 1):
cell = [Link](row, 3)
corrected_price = [Link] * 2
corrected_price_cell = [Link](row, 4)
corrected_price_cell.value = corrected_price
[Link]('[Link]')

43. Next Prime Number Function


def nextPrime(n):
while True:
n += 1
for i in range(2, n):
if n % i == 0:
break
else:
print(n)
return n
nextPrime(13)

18. Create Tuples with Homogeneous Elements


x = (30, 4.5, 26, 3+4j, 'abc', True, 5.6, 2-1j)
t1, t2, t3, t4, t5 = [], [], [], [], []
for e in x:
if type(e) == int:
[Link](e)
elif type(e) == float:
[Link](e)
elif type(e) == complex:
[Link](e)
elif type(e) == str:
[Link](e)
elif type(e) == bool:
[Link](e)
t1 = tuple(t1)
t2 = tuple(t2)
t3 = tuple(t3)
t4 = tuple(t4)
t5 = tuple(t5)
print(t1, t2, t3, t4, t5, sep='\n')

19. Find Greatest Number from a Tuple of Integers


print('Enter numbers')
t1 = tuple([int(e) for e in input().split(',')])
print('Greatest number:', max(t1))

20. Merge Two Sorted Tuples


t1 = (10, 20, 30, 40)
t2 = (5, 9, 12, 18, 22, 25)
t3 = []
i, j, k = 0, 0, 0
while i < len(t1) and j < len(t2):
if t1[i] < t2[j]:
[Link](t1[i])
i += 1
k += 1
else:
[Link](t2[j])
j += 1
k += 1
if i == len(t1):
while j < len(t2):
[Link](t2[j])
j += 1
k += 1
elif j == len(t2):
while i < len(t1):
[Link](t1[i])
i += 1
k += 1
t3 = tuple(t3)
print(t3)

21. Print Indices of All Occurrences of an Element in a List


l = [eval(x) for x in input("Enter list elements: ").split(',')]
element = eval(input("Enter element value: "))
index = 0

while index < len(l):


if l[index] == element:
print(index, end=' ')
index += 1

22. Recursive Function to Calculate Sum of Squares of First N Natural Numbers


def sum_squares(n):
if n == 1:
return 1
return n**2 + sum_squares(n-1)

print(sum_squares(4))

23. Return Multiple Values from a Function


def fun():
return 1, 2, 3
x = fun()
print(x)

24. ASCII Value of a Character


c = input("Enter a character: ")
print("The ASCII value of '" + c + "' is", ord(c))

25. Decimal Conversion to Binary, Octal, Hexadecimal


dec = int(input("Enter a decimal number: "))
print(bin(dec), "in binary.")
print(oct(dec), "in octal.")
print(hex(dec), "in hexadecimal.")

26. Matrix Operations


matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for row in matrix:
for item in row:
print(item)
Multiply Two Matrices
X = [[12, 7, 3],
[4, 5, 6],
[7, 8, 9]]
Y = [[5, 8, 1, 2],
[6, 7, 3, 0],
[4, 5, 9, 1]]
result = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
for i in range(len(X)): # rows of X
for j in range(len(Y[0])): # columns of Y
for k in range(len(Y)): # rows of Y
result[i][j] += X[i][k] * Y[k][j]
for r in result:
print(r)
27. Tower of Hanoi
def TowerOfHanoi(n, source, destination, auxiliary):
if n == 1:
print("Move disk 1 from source", source, "to destination", destination)
return
TowerOfHanoi(n-1, source, auxiliary, destination)
print("Move disk", n, "from source", source, "to destination", destination)
TowerOfHanoi(n-1, auxiliary, destination, source)
n=4
TowerOfHanoi(n, 'A', 'B', 'C')

28. Simple Calculator


def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(x, y):
return x / y
print("Select operation.")
print("[Link]")
print("[Link]")
print("[Link]")
print("[Link]")
while True:
choice = input("Enter choice(1/2/3/4): ")
if choice in ('1', '2', '3', '4'):
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
if choice == '1':
print(num1, "+", num2, "=", add(num1, num2))
elif choice == '2':
print(num1, "-", num2, "=", subtract(num1, num2))
elif choice == '3':
print(num1, "*", num2, "=", multiply(num1, num2))
elif choice == '4':
print(num1, "/", num2, "=", divide(num1, num2))
break
else:
print("Invalid Input")
# Calling the generator to get first 10 prime numbers
prime_gen = prime_generator(10)
for prime_number in prime_gen:
print(prime_number, end=' ')

# Reverse traversal
for i in range(len(my_list)-1, -1, -1):
print(my_list[i])

Array Operations
from array import *

# Left rotate array


def leftRotate(arr, d, n):
for i in range(d):
leftRotatebyOne(arr, n)
def leftRotatebyOne(arr, n):
temp = arr[0]
for i in range(n-1):
arr[i] = arr[i+1]
arr[n-1] = temp
def printArray(arr, size):
for i in range(size):
print("%d"% arr[i], end=" ")
arr = [1,2,3,4,5,6,7]
leftRotate(arr, 2, 7)
printArray(arr, 7)

# Reverse Array Rotation


def rverseArray(arr, start, end):
while (start < end):
temp = arr[start]
arr[start] = arr[end]
arr[end] = temp
start += 1
end -= 1
def leftRotate(arr, d):
n = len(arr)
rverseArray(arr, 0, d-1)
rverseArray(arr, d, n-1)
rverseArray(arr, 0, n-1)
def printArray(arr):
for i in range(0, len(arr)):
print(arr[i])
arr = [1,2,3,4,5,6,7]
leftRotate(arr, 2)
printArray(arr)

Monotonic Array Check


def isMonotonic(A):
return (all(A[i] <= A[i + 1] for i in range(len(A) - 1)) or
all(A[i] >= A[i + 1] for i in range(len(A) - 1)))
A = [6,5,4,4]
print(isMonotonic(A))

28. Extract Values by Type from Mixed List


mixed_list = [10, 20, 3.4, 'Newton', True, 'School', False, 'Middleton']
int_values = [e for e in mixed_list if type(e) == int]
str_values = [e for e in mixed_list if type(e) == str]
float_values = [e for e in mixed_list if type(e) == float]
bool_values = [e for e in mixed_list if type(e) == bool]
print("Integers:", int_values)
print("Strings:", str_values)
print("Floats:", float_values)
print("Booleans:", bool_values)
• Uses list comprehension and type() to filter elements.

1. Migration in Django
• A model represents the structure of your database (like a schema in SQL).
• Define a model as a class inside [Link], inheriting from [Link].
• Each attribute corresponds to a database field.

class Student([Link]):
name = [Link](max_length=100)
gender = [Link](max_length=10)
dob = [Link]()

• Migrations: Files generated by makemigrations encapsulate changes to the database


schema.
• Django tracks changes intelligently by comparing the current state with the last migration.
• Ensures your database stays synchronized with your models.
2. Seeding Data in Django
• Seeding: Inserting initial or essential data into a database.
• Example: Roles like super admin, editor, viewer.
• Approaches:
1. Seeder classes – define data and insert using Django’s ORM.
2. class RoleSeeder:
roles = ["Super Admin", "Editor", "Viewer"]
# Insert roles using ORM
5. Within migration files – add data after creating tables.
6. Manual insertion – using tools like Django shell, SQL clients.
• Choice depends on project requirements and whether the data needs to be replicated.

3. Aggregation and Annotation in Django


• Aggregate functions summarize data: Sum, Avg, Min, Max.
• Example: Calculate total marks for students.
• Annotate allows grouping data and analyzing subsets.
from [Link] import Count, Avg
[Link]('marks').annotate(count=Count('id'))
• Use aggregate for summary statistics, annotate for grouped data insights.

6. Django ORM vs SQL Queries


• ORM (Object-Relational Mapping) allows interacting with the database using
Python instead of raw SQL.
• Example:
[Link]() # ORM → SELECT * FROM student;

Benefits of ORM:
• Write in Python, not SQL.
• Easier database migration.
• Built-in features (filter, annotate, aggregate).
• Adapter/driver connects ORM to database (e.g., PostgreSQL via psycopg2).

Weaknesses:
• Not always as optimized as raw SQL.
• Impedance mismatch between objects and tables.
• Initial configuration can be unfamiliar to SQL experts.

7. Django ORM Overview


• Converts incompatible type systems using Python objects.
• Objects & Managers:
o student → table
o objects → manager
o all() → fetch all records
• ORM translates Python code to SQL behind the scenes.
• Allows database interaction while maintaining Python syntax and object orientation.

DSA
Heap Queue (heapq)
• Implements a priority queue (min-heap by default).

Operations:
o heapify(iterable): convert list to heap
o heappush(heap, ele): insert element
o heappop(heap): pop smallest element
o heappushpop(heap, ele): push then pop
o heapreplace(heap, ele): pop then push
o nlargest(k, iterable, key), nsmallest(k, iterable, key)

import heapq
li = [5, 7, 9, 1, 3]
[Link](li)
[Link](li, 4)
print(list(li))
print([Link](li))
li1 = [5, 7, 9, 4, 3]
li2 = [5, 7, 9, 4, 3]
[Link](li1)
print([Link](li1, 2))
print([Link](li2, 2))
print([Link](3, li1))
print([Link](3, li1))

2. deque (Advanced Operations)


• Double-ended queue with O(1) operations at both ends. Supports thread-safe
memory-efficient appends/pops.
• Advanced methods: index(), insert(), remove(), count(), extend(), extendleft(),
reverse(), rotate().

from collections import deque


d = deque(['a', 'b', 'c', 'd'])
[Link](['e', 'f', 'g'])
[Link](['h', 'i', 'j'])
print(d)
print([Link]('h'))
[Link](1)
[Link](-2)
# extend right
# extend left (reversed order)
# rotate right
# rotate left

1. Hash Table
class HashTable:
def __init__(self):
[Link]={}
def hashFunction(self,key):
hashValue=0
for char in key:
hashValue += ord(char)
return hashValue % 100
def insert(self,key,value):
index=[Link](key)
if index not in [Link]:
[Link][index]={}
[Link][index][key]=value
def getAll(self,key):
arr=[]
for index in [Link]:
for key in [Link][index]:
[Link]([Link][index][key])
return arr
def get(self,key):
if index in [Link] and key in [Link][index]:
return [Link][index][key]
def remove(self,key):
del [Link][index][key]
def updates(self,key,value):
[Link][index][key]=value
if __name__=="__main__":
obj=HashTable()
[Link]("name", "John")
[Link]("country", "India")
[Link]("city", "Noida")
[Link]("age", 30)
print([Link]('age'))
# [Link]('country')
[Link]('city','Dharmsala')
print([Link]('city'))
2. Find Stock Price on per day of March month.
stock_prices = [ "march 6,310", "march 7,340", "march 8,380",
"march 9,302", "march 10,297", "march 11,323" ]
result = []
for line in stock_prices:
tokens = [Link](',')
day = tokens[0]
price = float(tokens[1])
[Link]([day, price])
print(result)
print(result[0])

3. Find stock price on March 9


target = "march 9"
found_price = None
for day, price in data:
if day == target:
found_price = price
break
if found_price is not None:
print(f"The stock price on {target} is {found_price}")
else:
print(f"Stock price data for {target} was not found.")

4. Implement Hash Table


def hashFun(key):
hash = 0
for char in key:
hash += ord(char)
return hash % 100
print(hashFun('march 6'))

5. Hash Table: New York City Weather Analysis


data = ["Jan 1,27", "Jan 2,31", "Jan 3,23", "Jan 4,34", "Jan 5,37",
"Jan 6,38", "Jan 7,29", "Jan 8,30", "Jan 9,35", "Jan 10,30"]
1. What was the average temperature in first week of Jan
2. What was the maximum temperature in first 10 days of Jan
arr = []
for line in data:
tokens = [Link](',')
try:
temperature = int(tokens[1])
[Link](temperature)
except ValueError:
print("Invalid temperature", [Link]())
avg = sum(arr[0:7])/len(arr[0:7])
min = arr[0:10]
max = max(arr[0:10])
print(avg)
print(min)
print(max)

6. The best data structure to use here was a list because all we
wanted was access of temperature elements
3. What was the temperature on Jan 9?
4. What was the temperature on Jan 4?
result = {}
day = tokens[0]
result[day] = temperature
print("Invalid temperature.", [Link]())
temp = result['Jan 9']
temp2 = result['Jan 4']
print(temp)
print(temp2)

7. Connect n ropes with minimum cost


Given are N ropes of different lengths, the task is to connect these
ropes into one rope with minimum cost, such that the cost to connect
two ropes is equal to the sum of their lengths.
Input: arr[] = {4,3,2,6} , N = 4
Output: 29
Explanation:
First, connect ropes of lengths 2 and 3. Now we have three ropes of
lengths 4, 6, and 5.
Now connect ropes of lengths 4 and 5. Now we have two ropes of
lengths 6 and 9.
Finally connect the two ropes and all ropes have connected.
Approach: If we observe the above problem closely, we can notice
that the lengths of the ropes which are picked first are included more
than once in the total cost. Therefore, the idea is to connect the
smallest two ropes first and recur for the remaining ropes. This
approach is similar to Huffman Coding. We put the smallest ropes
down the tree so they can be repeated multiple times rather than the
longer ones.
def fun():
arr=[4, 3, 2, 6]
result=0
while len(arr)>1:
a=min(arr)
[Link](a)
b=min(arr)
[Link](b)
cost=a+b
result += cost
[Link](cost)
return result
print(fun())

8. Print K largest(or smallest) elements in an array.


arr = [1, 23, 12, 9, 30, 2, 50]
k=3
[Link](reverse=True)
for i in range(k):
print(arr[i], end=' ')
fun()

9. Find median in a array.


class Fun:
[Link] = []
def insert(self, num: int):
[Link](num)
[Link]()
def findMedian(self):
n = len([Link])
if n % 2 == 0:
# If the number of elements is even.
mid1 = n // 2
mid2 = n // 2 - 1
return ([Link][mid1] + [Link][mid2]) / 2.0
else:
mid = n // 2
return [Link][mid]
obj = Fun()
[Link](1)
[Link](2)
[Link](3)
[Link](4)
print([Link]())

10. Find median in a stream of running integers.


o If Odd number of elements than center of element is Mediad.
o If Even than Median = sum/no. of element
[Link]=[]
def insert(self,data):
[Link](data)
n=len([Link])
if n%2==0:
mid1=n//2
mid2=n//2-1
return ([Link][mid1] + [Link][mid2]) / 2
mid=n//2
return [Link][mid]
def median(stream):
result=[]
medianFind=Fun()
for num in stream:
[Link](num)
[Link]([Link]())
stream=[1,2,3,4]
obj=median(stream)
print(obj)

Letter Combinations of a Phone Number.


def fun(digits):
arr = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z'],
}
result = []
def insert(combination, next_digits):
if len(next_digits) == 0:
[Link](combination)
return
current_letters = arr[next_digits[0]]
for letter in current_letters:
insert(combination + letter, next_digits[1:])
insert('', digits)
result = fun('23')
1. Implement Stack class using a deque
class Stack:
[Link] = deque()
def insert(self, value):
[Link](value)
def remove(self):
return [Link]()
def peek(self):
return [Link][-1]
def isEmpty(self):
return len([Link]) == 0
def len(self):
return len([Link])
obj=Stack()
[Link](5)
print([Link]())
print([Link]())
print([Link]())
print([Link]())

2. Write a function that can reverse a string using stack data structure.
str='Apple Banana'
stack=[]
newstr=''
for char in str:
[Link](char)
while len(stack)>0:
newstr += [Link]()
return newstr

The issue with using a list as a stack is that list uses dymanic array internally and when it
reaches its capacity it will reallocate a big chunk of memory somewhere else in memory
area and

copy all the elements.


3. Using deque as a stack
def fun(str):
stack=deque()
while len(stack) > 0:
newstr +=[Link]()
print(newstr)
fun('Apple, Banana')
4. Write a function in python that checks if paranthesis in the string are balanced or not.
Possible parantheses are "',"()" or "[]".
[Link](data)
def size(self):
def isMatch(char1, char2):
dict={ ')':'(', ']':'[','}':'{'}
return dict[char1]==char2
def isBalence(str):
stack = Stack()
if char=='(' or char=='{' or char == '[':
[Link](char)
if char==')' or char=='}' or char == ']':
if [Link]()==0:
return False
if not isMatch(char,[Link]()):
return [Link]()==0
print(isBalence("({a+b})"))
print(isBalence("))((a+b}{"))
print(isBalence("((a+b))"))
print(isBalence("((a+g))"))
print(isBalence("))"))
print(isBalence("[a+b]*(x+2y)*{gg+kk}"))

5. Find the next greater element in an array.


we iterate through the array while using a stack to keep track of
elements for which we haven't found the next greater element yet.
When we encounter a larger element, we update the result for the
elements in the stack that are smaller. This way, we find the next
greater element for each element in the array.
arr = [4, 2, 10, 1, 9]
result = [-1] * len(arr) # Initialize
the result array with -1 for each element
stack = []
for i in range(len(arr)):
while stack and arr[i] > arr[stack[-1]]:
result[[Link]()] = arr[i]
[Link](i)

6. Get minimum element from the stack (Amazon).


self.min_stack = deque()
def insert(self, data):
if not self.min_stack or data <= self.min_stack[-1]:
self.min_stack.append(data)
def minStack(self):
if not self.min_stack:
return None
return self.min_stack[-1]
obj = Stack()
[Link](30)
[Link](10)
[Link](20)
min = [Link]()

7. Valid Parentheses.
left = '('
right = ')'
for i in range(4):
if i % 2 == 0:
[Link](left)
[Link](right)
print(''.join(result))

Generate Parentheses.
def fun(n):
stack = [('', 0, 0)]
while stack:
current, open_count, close_count = [Link]()
if len(current) == 2 * n:
[Link](current)
if open_count < n:
[Link]((current + '(', open_count + 1,
close_count))
if close_count < open_count:
[Link]((current + ')', open_count, close_count
+ 1))
print(result)
fun(3)

1. Implement queue using stacks.


To implement a queue using stacks, you can use two stacks: one for
enqueueing elements and another for dequeueing elements.
class Queue:
[Link]=[]
[Link]=[]
def enque(self,value):
[Link](value)
def deque(self):
if not [Link]:
if not [Link]:
return None
while [Link]:
[Link]([Link]())
return [Link]()
obj=Queue()
[Link](3)
[Link](2)
[Link](1)
print([Link]())
def isEmpty(self):
return len([Link]) == 0 and len([Link]) == 0
def size(self):
return len([Link]) + len([Link])

2. Write a program to print binary numbers from 1 to 10 using


Queue.
[Link]=deque()
return [Link](value)
if not [Link]:
return [Link]()
return [Link][-1]
def binaryNum(n):
num=Queue()
[Link]("1")
for i in range(n):
front=[Link]()
[Link](front+"0")
[Link](front+"1")
[Link]()
print(front)
binaryNum(10)

3. Design a food ordering system where your python program will run two threads,
1. Place Order: This thread will be placing an order and inserting
that into a queue. This thread places new order every 0.5
second.

2. Serve Order: This thread will server the order. All you need to
do is pop the order out of the queue and print it. This thread
serves an order every 2 seconds. Also start this thread 1
second after place order thread is started.
import threading
import time
[Link] = deque()
def enqueue(self, val):
[Link](val)
def dequeue(self):
if len([Link])==0:
print("Queue is empty")
foodOrder = Queue()
def placeOrder(orders):
for order in orders:
print("Placing order for:", order)
[Link](order)
[Link](0.5)
def serveOrder():
[Link](1)
while True:
order = [Link]()
print("Now serving:", order)
[Link](2)
orders = ['pizza','samosa','pasta','biryani','burger']
t1 = [Link](target=placeOrder, args=(orders,))
t2 = [Link](target=serveOrder)
[Link]()
[Link]()

Linked List
1. Append
class Node:
def __init__(self, data=None, next=None):
[Link] = data
[Link] = next
class LinkList:
[Link] = None
def first(self, data):
node = Node(data, [Link])
[Link] = node
def ends(self, data):
if [Link] is None:
node = [Link](data, None)
[Link] = node
itr = [Link]
while [Link]:
itr = [Link]
[Link] = Node(data, None)
def prints(self):
listr = ''
while itr:
listr += str([Link]) + '->'
print(listr)
obj = LinkList()
[Link](3)
[Link](1)
[Link](2)
[Link](6)
[Link](0)
[Link]()

2. Insert At
def insertAt(self, data, index):
if index==0:
[Link](data)
count=0
itr=[Link]
if count == index-1:
node = Node(data, [Link])
[Link] = node
break
count += 1
[Link](4,1)
[Link]()

3. Delete
def delete(self, value):
if [Link] == value:
[Link] = [Link]
if [Link] == value:
[Link] = [Link]
return
[Link](3)

4. Length
def len(self):
count = 0
count+=1
return count
5. List
def first(self,data):
def lists(self,li):
for data in li:
obj=LinkList()
[Link](["banana","mango","grapes","orange"])

6. Insert After in a List


def insertAfter(self,after,value):
if [Link] == after:
[Link]=Node(value, [Link])
itr=[Link]
[Link]("mango","apple")

7. Search
def searchs(self,target):
if [Link]==target:
return [Link]
result = [Link](1)
if result:
print('Found element', result)
print('Not Fount', result)

8. Reverse
def reverse(self):
prev = None
current = [Link]
next_node = None
while current:
next_node = [Link]
[Link] = prev
prev = current
current = next_node
[Link] = prev
return [Link]
current = [Link]()
while current:
print([Link], end=" ")
current = [Link]

9. Words that appear only once in the string.


def unique(self):
unique_chars = ''
is_unique = True
runner = [Link]
while runner != current:
if [Link] == [Link]:
is_unique = False
break
runner = [Link]
if is_unique:
unique_chars += [Link]
current = [Link]
return unique_chars
print([Link]())

//
arr = list('apple')
for i in range(len(arr)):
if arr[i] in result:
[Link](arr[i])
[Link](arr[i])

10. Duplicate Character.


for j in range(i + 1, len(arr)):
if arr[i] == arr[j]:
count += 1
if count >= 1:

11. Implement doubly linked list.


def __init__(self,data=None, next=None, prev=None):
class DLinkList:
[Link]=None
node=Node(data,[Link])
[Link]=node
itr = [Link]
while [Link]:
itr = [Link]
node = Node(data, prev=itr)
[Link] = node
def prepend(self,data):
node=Node(data,None)
if [Link]:
[Link]=[Link]
[Link]=node
obj=DLinkList()
[Link](4)
12. Delete.
def delete(self, target):
if [Link] == target:
if itr == [Link]:
[Link] = [Link]
if [Link]:
[Link] = None
else:
[Link] = [Link]
if [Link]:
[Link] = [Link]

13. Linked List Cycle.


[Link] = None
if [Link] is None:
[Link] = node
def cyclic(self):
return False
slow = [Link]
fast = [Link]
while fast and [Link]:
slow = [Link]
fast = [Link]
if slow == fast:
return True
return False
if [Link] is not None:
[Link] = [Link]
if [Link]():
print('Cycle detected')
print('No cycle detected')

14. BreakCycle
def breakCycle(self):
if [Link] and [Link]():
slow=[Link]
fast=[Link]
while fast and [Link]:
slow=[Link]
fast=[Link]
if slow==fast:
if fast is None or [Link] is None:
while slow!=fast:
fast=[Link]
[Link]()
print("Linked List after breaking the cycle:")

15. Remove Nth Node From End of List


// Add above codes
def removeNthFromEnd(self, n):
for _ in range(n):
#Move the fast pointer N nodes ahead
fast = [Link]
while fast: #Move both pointers
until the fast pointer reaches the end
prev = slow

if prev: #slow points to the Nth


node from the end
[Link] = [Link] #Remove the Nth node by
updating the next pointer of the node before it
[Link] = [Link]
print("After removing 2nd node from the end:")
[Link](2)

16. Merge Two Sorted Lists.


[Link]=None
node=Node(data,[Link])
def merge(self, list):
if [Link] is not None:
if [Link] is None:
[Link] = [Link]
[Link] = [Link]
else:
if [Link] is not None:
[Link] = [Link]
[Link] = [Link]
obj2=LinkList()
[Link](6)
[Link](4)
[Link](5)
[Link](obj2)

17. Reverse a linked list


To reverse a singly linked list, you can iterate through the list while
modifying the next pointers of each node to point in the reverse
direction.
newnode = [Link]
current = newnode
[Link]()

18. Reverse a Linked List in groups of given size (Amazon).


def reverse(self, head, k):
if head == None:
current = head
next = None
while(current is not None and count < k): # Reverse the
first k nodes of the linked list
next = [Link]
[Link] = prev
prev = current
current = next
if next is not None: # 'next' is now a
pointer to the (k+1)th node Recursively call
[Link] = [Link](next, k) #from 'current'.
And make the
#rest of the list as the next of the first node
return prev # 'prev' is the
new head of the input list
llist = LinkedList()
[Link](5)
[Link](4)
[Link](3)
[Link](2)
[Link](1)
[Link]()
[Link] = [Link]([Link], 3)
print("Reversed:")
[Link]()

19. Reverse a linked list in sets of k elements


You can break the original list into segments of size k, reverse each
segment, and then reattach them.
def reverse_k_elements(self, head, k):
if k <= 1 or head is None:
return head
prev_tail = None
new_head = None
while head:
current_head = head
current_tail = None
prev = None
for i in range(k):
if head:
temp = [Link]
[Link] = prev
prev = head
head = temp
if not current_tail:
current_tail = prev
if prev_tail:
prev_tail.next = prev
new_head = prev
prev_tail = current_head
return new_head
[Link](8)
[Link](7)
[Link](6)
k=3
[Link]([Link])
reversed_head = obj.reverse_k_elements([Link], k)
print(f"Reversed linked list in sets of {k} elements:")
[Link](reversed_head)

20. Add 2 LinkedList value into Result


def reverse(self):
def adds(list1, list2):
result = LinkList()
carry = 0
current1 = [Link]
current2 = [Link]
while current1 or current2:
data1 = [Link] if current1 else 0
data2 = [Link] if current2 else 0
total = data1 + data2 + carry
carry = total // 10
[Link](total % 10)
if current1:
current1 = [Link]
if current2:
current2 = [Link]
if carry:
[Link](carry)
obj2 = LinkList()
[Link](9)
[Link]()
[Link]()
result = adds(obj, obj2)
[Link]()

21. Swap Kth node from beginning with Kth node from end in a Linked List (Amazon).
class Node:
def __init__(self, data, next=None):
[Link] = data
[Link] = next
class LinkedList:
def __init__(self, *args, **kwargs):
[Link] = Node(None)
def push(self, data):
node = Node(data)
[Link] = [Link]
[Link] = node
def printList(self):
node = [Link]
while [Link] is not None:
print([Link], end=" ")
node = [Link]
def countNodes(self): #count
number of node in linked list
count = 0
count += 1
return count
def swapKth(self, k): #Function for swapping
kth nodes from both ends of linked list
n = [Link]()
if n < k:
return
if (2 * k - 1) == n: #If x (kth node from
start) and y(kth node from end) are same
x = [Link] #Find the
kth node from beginning of linked list.
x_prev = Node(None) #We also
find previous of kth node because we need
for i in range(k - 1): #to update
next pointer of the previous.
x_prev = x
x = [Link]
y = [Link] #Similarly, find
the kth node from end and its previous.
y_prev = Node(None) #kth node from
end is (n-k + 1)th node from beginning.
for i in range(n - k):
y_prev = y
y = [Link]
if x_prev is not None: #If x_prev exists,
then new next of it will be y. Consider the
x_prev.next = y #case when y->next is
x, in this case, x_prev and y are same.
prev->next = y"
creates a self loop. This
#self loo#So the
statement "x_p will be broken when we change y->next.
if y_prev is not None: #Same
thing applies to y_prev
y_prev.next = x
temp = [Link] #Swap next
pointers of x and y. These statements also
[Link] = [Link] #break self
loop if x->next is y or y->next is x
[Link] = temp
if k == 1: #Change
head pointers when k is 1 or n
[Link] = y
if k == n:
[Link] = x
for i in range(8, 0, -1):
[Link](i)
[Link]()
print("nl")

for i in range(1, 9):


[Link](i)
print("Modified List for k = ", i)
[Link]()
print("nl")

22. Given two numbers represented by two lists, write a function that returns the sum
in the form of a linked list (Amazon).
75946 + 84 = 76030
def __init__(self, data):
[Link] = None
class LinkedList:
def insert(self, val):
[Link] = Node(val)
[Link] = [Link]
[Link] = Node(val)
[Link] = [Link]
class Solution:
def reverse(self, head):
if head is None or [Link] is None:
curr = head
while curr is not None:
next = [Link]
[Link] = prev
prev = curr
curr = next
head = prev
return head
def addTwoLists(self, first, second): # Function
to add two numbers represented by linked list.
curr1 = [Link](first)
curr2 = [Link](second)
total_sum = 0
carry = 0
res = None
# res is the head node of the resultant list
while curr1 is not None or curr2 is not None:
# while both lists have at least one node
#Calculating sum of last digits
total_sum = carry + ([Link] if curr1 else 0) +
([Link] if curr2 else 0)
carry = 1 if total_sum >= 10 else 0
#update carry for next calculation
total_sum = total_sum % 10
#update sum if it is greater than 10
temp = Node(total_sum)
# Create a new node with the sum as data
if res is None: # if this is
first node, set it as head of the resultant list
res = temp
else: # If this
is not the first node, connect it to the rest.
[Link] = temp
prev = temp # Set prev
for the next insertion
if curr1: # Move
first and second pointers to the next nodes
curr1 = [Link]
if curr2:
curr2 = [Link]
if carry > 0: # if carry
from previous sums is remaining
[Link] = Node(carry)
ans = [Link](res)
return ans
def prints(self, n):
while n:
print([Link], end=' ')
n = [Link]
print()
arr1 = [7, 5, 9, 4, 6]
LL1 = LinkedList()
for i in arr1:
[Link](i)
obj = Solution()
[Link]([Link])
arr2 = [8, 4]
LL2 = LinkedList()
for i in arr2:
[Link](i)
[Link]([Link])
res = [Link]([Link], [Link])
[Link](res)

Tree
1. InOrder
def __init__(self, data=None, left=None, right=None):
[Link] = left
[Link] = right
class Tree:
def createNode(self, data):
node = Node(data)
return node
def insert(self, node, data):
if node is None:
return [Link](data)
if data<[Link]:
[Link] = [Link]([Link], data)
[Link] = [Link]([Link], data)
def inOrder(self, root):
if root is not None:
[Link]([Link])
print([Link], end=' ')
[Link]([Link])
obj=Tree()
root=[Link](2)
# print([Link])
[Link](root, 3)
[Link](root, 1)
[Link](root, 5)
[Link](root, 0)
[Link](root)

2. PreOrder
def PreOrder(self, root):
if root is not None:
print([Link], end=' ')
[Link]([Link])
[Link]([Link])

3. PostOrder
def postOrder(self, root):
[Link]([Link])
[Link]([Link])
print([Link], end = ' ')

4. Delete
def delete(self, root, key):
if root is None:
return root
if key < [Link]:
[Link] = [Link]([Link], key)
elif key > [Link]:
[Link] = [Link]([Link], key)
if [Link] is None:
#Node with only one child or no child
return [Link]
elif [Link] is None:
return [Link]
current = [Link]
#Node with two children
while [Link] is not None:
current = [Link]
[Link] = [Link]
[Link] = [Link]([Link], [Link])
return root
root = [Link](root, 3)

5. Update
def findNode(self, root, target):
if root is None or [Link] == target:
if target < [Link]:
return [Link]([Link], target)
return [Link]([Link], target)
def updates(self, root, target, newValue):
updateNode = [Link](root, target)
if updateNode:
[Link] = newValue
newValue = 4
[Link](root, 3, newValue)

6. Height
def height(self, root):
if root is None:
return -1
return max([Link]([Link]), [Link]([Link])) + 1
print([Link](root))

7. Level Order Traversal


def levels(self, root):
return
queue = deque()
[Link]((root, 0))
while queue:
node, level = [Link]()
print(f"Level {level}: {[Link]}", end=' ')
if [Link]:
[Link](([Link], level + 1))
if [Link]:
[Link](([Link], level + 1))
[Link](root)

9. Unique Binary Search Trees.


if root is None or [Link] == target:
if target < [Link]:
return [Link]([Link], target)
return [Link]([Link], target)
result = [Link](root, 1)
print(f"Found {[Link]}")
print("Not found.")
10. Validate Binary Search Tree.
def isValid(self, node=None, minVal=any, maxVal=any):
return True
if not (minVal < [Link] < maxVal):
return (
[Link]([Link], minVal, [Link])
and [Link]([Link], [Link], maxVal)
)
obj=BinaryTree()
root=[Link](5)
[Link](root,5)
[Link](root,2)
[Link](root,7)
[Link](root,1)
print("Is Valid BST:", [Link]())

11. Same Tree.


def isSame(root1, root2):
if root1 is None and root2 is None:
return True
if root1 is not None and root2 is not None:
return ([Link] == [Link]) and isSame([Link],
[Link]) and isSame([Link], [Link])
return False
obj1 = BinaryTree()
root1 = [Link](5)
[Link](root1, 2)
[Link](root1, 7)
[Link](root1, 1)
obj2 = BinaryTree()
root2 = [Link](5)
[Link](root2, 2)
[Link](root2, 7)
[Link](root2, 1)
if isSame(root1, root2):
print("The trees are the same.")
print("The trees are not the same.")

12. Symmetric Tree.


def isMirror(left, right):
if left is None and right is None:
if left is None or right is None:
return Falsess
return ([Link] == [Link]) and isMirror([Link],
[Link]) and isMirror([Link], [Link])
def isSymmetric(root):
return root is None or isMirror([Link], [Link])
obj = BinaryTree()
root = [Link](1)
[Link](root, 2)
[Link](root, 4)
if isSymmetric(root):
print("The tree is symmetric.")
print("The tree is not symmetric.")

13. Find the number of leaf nodes for a given node.


14. Serialize and Deserialize a Binary Tree (Amazon)
o Serialization: Is to store the tree in a file so that it can be later
restored. The structure of the tree must be maintained.
o Deserialization: Is reading the tree back from a file.
This solution requires space twice the size of the Binary Tree. We
can save space by storing Preorder traversal and a marker for NULL
pointers.
3. Store all possible child nodes for each node.
4. If there is no child node then push -1 for that child.
5. Put this preorder traversal in the file.
def serialize(self, root):
return 'None'
left_str = [Link]([Link])
right_str = [Link]([Link])
return f"{[Link]},{left_str},{right_str}"
def deserialize(self, data):
data_list = [Link](',')
def helper():
val = data_list.pop(0)
if val == "None":
node = [Link](int(val))
[Link] = helper()
[Link] = helper()
return helper()
obj = Tree()
root = [Link](4)
seriali = [Link](root)
print("Serialized tree:", seriali)
deseriali = [Link](seriali)
[Link](deseriali)

15. Print a Binary Tree in Vertical Order (Amazon).


def verticalOrder(self, root):
vertical = {} #
Dictionary to store nodes at each vertical level
queue = []
# Queue to perform level order traversal
[Link]((root, 0)) # Enqueue
the root node with its vertical level as 0
while queue:
node, level = [Link](0)
if level in vertical: # Check if the
current vertical level is in the dictionary
vertical[level].append([Link])
vertical[level] = [[Link]]
if [Link]: # Enqueue left and
right children with updated vertical levels
[Link](([Link], level - 1))
if [Link]:
[Link](([Link], level + 1))
sortedLevel = sorted(vertical)
# Sort the vertical levels
for level in sortedLevel:
print(" ".join(map(str, vertical[level])))
[Link](root, 30)
[Link](root, 8)
[Link](root)

16. Maximum difference between node and its ancestors (Amazon).


o maxDiffUtil(t, res): Recursive function to calculate maximum
ancestor-node difference in binary tree. It updates value at 'res'
to store the result. The returned value of this function is
minimum value in subtree rooted with 't'
_MIN = -2147483648
_MAX = 2147483648
def maxDiffUtil(self, t, res):
if t is None: #Returning Maximum
value if node is not there (one child case)
return _MAX, res
if [Link] is None and [Link] is None: #If leaf node then
just return node's value
return [Link], res
a, res = [Link]([Link], res) #Recursively
calling left and right subtree for minimum value
b, res = [Link]([Link], res)
val = min(a, b)
res = max(res, [Link] - val) #Updating res if (minimum value from subtree) is bigger than res
return min(val, [Link]), res #Returning minimum value got so far
def maxDiff(self, root):
res = _MIN
x, res = [Link](root, res)
return res
root = [Link](8)
[Link](root, 6)
result = [Link](root)

17. Given a Binary Tree, convert it to a Binary Search Tree. The conversion must be done in
such a way that keeps the original structure of Binary Tree (Amazon).
def storeInorder(root, inOrder):
storeInorder([Link], inOrder)
[Link]([Link])
storeInorder([Link], inOrder)
list = []
storeInorder(root, list)
print(list)

18. Management hierarchy of a company.


class TreeNode:
[Link] = []
[Link] = None
def get_level(self):
level = 0
p = [Link]
while p:
level += 1
p = [Link]
return level
def print_tree(self):
spaces = ' ' * self.get_level() * 3
prefix = spaces + "|__" if [Link] else ""
print(prefix + [Link])
if [Link]:
for child in [Link]:
child.print_tree()
def add_child(self, child):
[Link] = self
[Link](child)
def build_product_tree():
root = TreeNode("Electronics")
laptop = TreeNode("Laptop")
laptop.add_child(TreeNode("Mac"))
laptop.add_child(TreeNode("Surface"))
laptop.add_child(TreeNode("Thinkpad"))
cellphone = TreeNode("Cell Phone")
cellphone.add_child(TreeNode("iPhone"))
cellphone.add_child(TreeNode("Google Pixel"))
cellphone.add_child(TreeNode("Vivo"))
tv = TreeNode("TV")
tv.add_child(TreeNode("Samsung"))
tv.add_child(TreeNode("LG"))
root.add_child(laptop)
root.add_child(cellphone)
root.add_child(tv)
root.print_tree()
if __name__ == '__main__':
build_product_tree()

19. Location hierarchy


def print_tree(self, level):
if self.get_level() > level:
child.print_tree(level)
def build_location_tree():
root = TreeNode("Global")
india = TreeNode("India")
gujarat = TreeNode("Gujarat")
gujarat.add_child(TreeNode("Ahmedabad"))
gujarat.add_child(TreeNode("Baroda"))
karnataka = TreeNode("Karnataka")
karnataka.add_child(TreeNode("Bangluru"))
karnataka.add_child(TreeNode("Mysore"))
india.add_child(gujarat)
india.add_child(karnataka)
usa = TreeNode("USA")
nj = TreeNode("New Jersey")
nj.add_child(TreeNode("Princeton"))
nj.add_child(TreeNode("Trenton"))
california = TreeNode("California")
california.add_child(TreeNode("San Francisco"))
california.add_child(TreeNode("Mountain View"))
california.add_child(TreeNode("Palo Alto"))
usa.add_child(nj)
usa.add_child(california)
root.add_child(india)
root.add_child(usa)
return root
root_node = build_location_tree()
root_node.print_tree(3)

Binary Tree
1. find_min(): finds minimum element in entire binary tree
2. find_max(): finds maximum element in entire binary tree
3. calculate_sum(): calcualtes sum of all elements
4. post_order_traversal(): performs post order traversal of a binary tree
5. pre_order_traversal(): perofrms pre order traversal of a binary tree
def createNode(data):
def insert(root, data):
return [Link](data)
if data < [Link]:
[Link] = [Link]([Link], data)
[Link] = [Link]([Link], data)
def inOrder(root):
[Link]([Link])
[Link]([Link])
def buildTree(elements):
if not elements:
return None
root = [Link](elements[0])
for i in range(1, len(elements)):
root = [Link](root, elements[i])
numbers = [17, 4, 1, 20, 9, 23, 18, 34]
obj = buildTree(numbers)
[Link](obj)

2. Sum, Min, Max


def findMax(root):
if [Link] is None:
return [Link]
return [Link]([Link])
def findMin(root):
if [Link] is None:
return [Link]([Link])
def addSum(root):
return 0
leftSum = [Link]([Link])
rightSum = [Link]([Link])
return [Link] + leftSum + rightSum
print("Min:", [Link](obj))
print("Max:", [Link](obj))
print("Sum:", [Link](obj))

3. Search
root = Tree().createNode(elements[0])
root = Tree().insert(root, elements[i])
# numbers = [17, 4, 1, 20, 9, 23, 18, 34]
numbers = ["India","Pakistan","Germany","USA","China","India","UK","USA"]
print(numbers)
result = Tree().findNode(obj, "India")
# Node with only one child or no child
# Node with two children
if root:
print([Link], end=" ")
numbers = ["India", "Pakistan", "Germany", "China", "UK", "USA"]
Tree().inOrder(obj)
obj = Tree().delete(obj, "USA")
print("Updated Tree:")

5. Binary Search, Find index of all the occurances of a number from sorted list.
def bSearch(lists, target):
left_index = 0
right_index = len(lists) - 1
mid_index = 0
while left_index <= right_index:
mid_index = (left_index + right_index) // 2
mid_number = lists[mid_index]
if mid_number == target:
return mid_index
if mid_number < target: #
number is in right hand side of the list
left_index = mid_index + 1
else:
right_index = mid_index - 1
return -1
def find_all_occurances(numbers, target):
index = bSearch(numbers, target)
indices = [index]
i = index-1
while i >=0: #
find indices on left hand side
if numbers[i] == target:
[Link](i)
break
i=i-1
i = index + 1 #
find indices on right hand side
while i<len(numbers):
i=i+1
return sorted(indices)
numbers = [1,4,6,9,11,15,15,15,17,21,34,34,56]
indices = find_all_occurances(numbers, 15)
print(f"Indices of occurances of {15} are {indices}")

6. Find two elements in a BST such that their sum is equal to k. You can use a two-pointer
approach by simultaneously traversing the BST in-order.
def target(self, root, k):
def inOrder(node):
if not node:
return []
return inOrder([Link]) + [[Link]] +
inOrder([Link])
elements = inOrder(root)
left, right = 0, len(elements) - 1
while left < right:
current_sum = elements[left] + elements[right]
if current_sum == k:
return elements[left], elements[right]
elif current_sum < k:
left += 1
right -= 1
root = [Link](5)
[Link](root, 7)
k=9
result = [Link](root, k)
print(f"Pair with sum {k} found: {result[0]} and {result[1]}")
print(f"No pair with sum {k} found in the BST.")

7. Write a program to convert a given single Linked list to BST


o Find the middle element of the linked list, which will be the root of the BST.
o Recursively convert the left and right halves of the linked list into the left and right
subtrees of the root.
o Repeat this process for each level of the BST.
class ListNode:
def __init__(self, value):
[Link] = value
[Link] = None
[Link] = None
node = ListNode(data, [Link])
def inOrder(self,root):
print([Link], end=" ")
def list_to_bst(head):
if not head:
if not [Link]:
return TreeNode([Link])
slow, fast = head, head
prev = None
while fast and [Link]:
fast = [Link]
prev, slow = slow, [Link]
[Link] = None
root = TreeNode([Link])
[Link] = list_to_bst(head)
[Link] = list_to_bst([Link])
obj = TreeNode(5)
root = list_to_bst([Link]) # Use
[Link] to pass the ListNode data

8. Binary tree traversal questions like left view, right view, top view, bottom view, maximum
of a level, minimum of a level, children sum property, diameter (Amazon).
def left_view(self, root):
if not root:
return []
result = []
queue = [root]
[Link](queue[0].data)
size = len(queue)
for i in range(size):
node = [Link](0)
if [Link]:
[Link]([Link])
if [Link]:
[Link]([Link])
return result
def right_view(self, root):
[Link](queue[-1].data)
def top_view(self, root):
result = {}
queue = [(root, 0)]
node, hd = [Link](0)
if hd not in result:
result[hd] = [Link]
if [Link]:
[Link](([Link], hd - 1))
[Link](([Link], hd + 1))
return [result[hd] for hd in sorted([Link]())]
def bottom_view(self, root):
result[hd] = [Link]
def max_min_level(self, root, level):
if not root or level < 0:
return (float('-inf'), float('inf'))
if level == 0:
return ([Link], [Link])
left_max, left_min = self.max_min_level([Link], level - 1)
right_max, right_min = self.max_min_level([Link], level -
1)
return (max(left_max, right_max), min(left_min, right_min))
def children_sum(self, root):
if not root or (not [Link] and not [Link]):
left_val = [Link] if [Link] else 0
right_val = [Link] if [Link] else 0
if [Link] != left_val + right_val:
return self.children_sum([Link]) and
self.children_sum([Link])
def diameter(self, root):
def height(node):
return 0
left_height = height([Link])
right_height = height([Link])
[Link] = max([Link], left_height +
right_height)
return 1 + max(left_height, right_height)
[Link] = 0
height(root)
return [Link]
root = [Link](20)
[Link](root, 22)
[Link](root, 12)
[Link](root, 10)
[Link](root, 14)
print("Left View:", obj.left_view(root))
print("Right View:", obj.right_view(root))
print("Top View:", obj.top_view(root))
print("Bottom View:", obj.bottom_view(root))
print("Maximum of Level 2:", obj.max_min_level(root, 2)[0])
print("Minimum of Level 2:", obj.max_min_level(root, 2)[1])
print("Children Sum Property:", obj.children_sum(root))
print("Diameter of Binary Tree:", [Link](root))

9. Convert given Binary Tree to (DLL) Doubly Linked List in Linear time (Amazon).
class BinaryTree:
def BToDll(self, root):
[Link]([Link])
# Recursively convert right subtree
[Link] = [Link]
# Insert root into doubly linked list
if [Link] is not None:
# Change left pointer of previous head
[Link] = root
[Link] = root
# Change head of doubly linked list
[Link]([Link])
# Recursively convert left subtree
print('Extracted Double Linked list is:')
while current is not None:
print([Link], end=' ')
current = [Link]
converter = BinaryTree()
[Link](root)
[Link]()

10. Convert Sorted List to Binary Search Tree.


def __init__(self, data, left=None, right=None):
def show(self):
return [Link]
class BinarySearchTree:
[Link] = None
def sorted_to_bst(self, arr):
[Link] = self.sorted_array(arr, 0, len(arr) - 1)
def sorted_array(self, arr, start, end):
if start > end:
mid = (start + end) // 2
node = ListNode(arr[mid])
[Link] = self.sorted_array(arr, start, mid - 1)
[Link] = self.sorted_array(arr, mid + 1, end)
def postOrder(node):
if node is not None:
postOrder([Link])
postOrder([Link])
print([Link](), end=" ")
obj = BinarySearchTree()
obj.sorted_to_bst([1, 2, 3, 5, 7])
postOrder([Link])

11. Lowest Common Ancestor in a Binary Tree(Amazon). Tree that has both of the given
nodes as descendants. In other words, it is the deepest node that is an ancestor of both
nodes. To find the LCA of two nodes in a binary tree, you can use a recursive algorithm.
def findPath(self, root, path, k): # Path from root node to given root of the tree.
if root is None: # Stores the path in a list path[], returns true if path
return False
[Link]([Link]) # Store this node is path vector. The node will be
# removed if not in path from root to k
if [Link] == k:
# Check if k is found in left or right sub-tree
if (([Link] is not None and [Link]([Link], path, k)) or
([Link] is not None and [Link]([Link], path, k))):
[Link]() # If not present in subtree rooted with root, remove
return False # root from path and return False
def findLCA(self, n1, n2):
path1 = []
path2 = [] # Find paths from root to n1 and root to n2.
#If either n1 or n2 is not present , return -1
if (not [Link]([Link], path1, n1) or not
[Link]([Link], path2, n2)):
return -1
i=0 # Compare the paths to get the first different value
while i < len(path1) and i < len(path2):
if path1[i] != path2[i]:
i += 1
return path1[i - 1]
[Link] = [Link](1)
[Link]([Link], 2)
[Link]([Link], 3)
[Link]([Link], 4)
[Link]([Link], 5)
[Link]([Link], 6)
[Link]([Link], 7)
print("LCA(4, 5) =", [Link](4, 5))
print("LCA(2, 4) =", [Link](2, 4))

12. Level Order Traversal (Amazon).


Level Order Traversal technique is defined as a method to traverse a Tree such that all
nodes present in the same level are traversed completely before traversing the next level.
recursive
def printLevelOrder(self, root):
h = [Link](root)
for i in range(1, h + 1):
[Link](root, i)
def printCurrentLevel(self, root, level):
if level == 1:
elif level > 1:
[Link]([Link], level - 1)
[Link]([Link], level - 1)
def height(self, node):
lheight = [Link]([Link])
rheight = [Link]([Link])
if lheight > rheight:
return lheight + 1
return rheight + 1
print("Level order traversal of binary tree is -")
[Link](root)

13. Min distance between two given nodes of a binary tree


def pathToNode(root, path, k):
[Link]([Link])
if [Link] == k:
# If the k is same as root's data

if (([Link] is not None and pathToNode([Link], path, k)) or


#If k is found in left or right sub-tree
([Link] is not None and pathToNode([Link], path, k))):

[Link]()
#If not present in subtree rooted with root,
return False
# remove root from path and return False
def distance(root, data1, data2):
if root:
path1 = []
# store path corresponding to node: data1
pathToNode(root, path1, data1)
pathToNode(root, path2, data2)
i=0
while i < len(path1) and i < len(path2): #iterate through the paths to find the
common path length
if path1[i] != path2[i]: #get out as soon as path differs or any path's length
break #get exhausted
i=i+1
return (len(path1) + len(path2) - 2 * i)
else:
return 0
dist = distance(root, 4, 5)
print("Distance between node {} & {}: {}".format(4, 5, dist))
dist = distance(root, 4, 6)
print("Distance between node {} & {}: {}".format(4, 6, dist))
dist = distance(root, 3, 4)
print("Distance between node {} & {}: {}".format(3, 4, dist))

14. Count ways to reach nth stair (Amazon).


Input: n = 1
Output: 1 There is only one way to climb 1 stair
Input: n=2
Output: 2 There are two ways: (1, 1) and (2)
Input: n = 4
Output: 5 (1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2)
15. You are given a pointer to the root of a binary search tree
and values to be inserted into the tree. Insert the values into
their appropriate position in the binary search tree and return
the root of the updated binary tree.
[0, 2, 3, 5]
def __init__(self, data, left=None, right=None):
[Link] = data
[Link] = left
[Link] = right
if [Link] is None:
[Link] = Node(data)
node = [Link]
while node:
if data < [Link]:
if [Link] is None:
[Link] = Node(data)
break
node = [Link]
if [Link] is None:
[Link] = Node(data)
node = [Link]
def inOrder(self, root, end=' '):
print([Link])
[Link](0)
[Link]([Link])
# Recursive function to find Nth Fibonacci number
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# Returns the number of ways to reach the nth stair
def countWays(s):
return fib(s + 1)
s=4
print("Number of ways =", countWays(s))

Graph
1. Create Graph Dictionay
class Graph:
def __init__(self, edges):
[Link]=edges
[Link] = {}
for start, end in edges:
if start in [Link]:
[Link][start].append(end)
[Link][start] = [end]
def addE(self, start, end):
if start in [Link]:
[Link][start].append(end)
[Link][start] = [end]
def addV(self, vertex):
if vertex not in [Link]:
[Link][vertex] = []
return [Link]
routes = [
("Mumbai", "Pune"),
("Mumbai", "Surat"),
("Surat", "Bangaluru"),
("Pune", "Hyderabad"),
("Pune", "Mysuru"),
("Hyderabad", "Bangaluru"),
("Hyderabad", "Chennai"),
("Mysuru", "Bangaluru"),
("Chennai", "Bangaluru")
]
obj = Graph(routes)
d = {"Mumbai": ["Bangaluru", "Pune"]}
[Link]("Goa")
[Link]("Goa", "Mumbai")
print([Link]())
2. Remove
def removeV(self, vertex):
if vertex in [Link]:
del [Link][vertex]
for key in [Link]:
[Link][key] = [v for v in [Link][key]
if v != vertex]
def removeE(self, start, end):
if start in [Link] and end in [Link][start]:
[Link][start].remove(end)
[Link]("Surat")
[Link]("Hyderabad", "Chennai")

3. Update
def updatesE(self, vertex, new_edges):
if vertex in [Link]:
[Link][vertex] = new_edges
[Link]("Mumbai", ["Chennai", "Hyderabad"])

4. Get Path
def getPath(self, start, end, path=[]):
path=path+[start]
if start==end:
return [path]
if start not in [Link]:
paths=[]
for node in [Link][start]:
if node not in path:
newpath=[Link](node,end,path)
for i in newpath:
[Link](i)
return paths
start = "Mumbai"
end = "Bangaluru"
print(f"All paths between: {start} and {end}:
",[Link](start,end))

5. Sortest Path
def sortestPath(self, start, end, path=[]):
path = path + [start]
if start == end:
return path
shortest_path = None
sp = [Link](node, end, path)
if sp:
if shortest_path is None or len(sp) <
len(shortest_path):
shortest_path = sp
return shortest_path
print(f"Shortest path between {start} and {end}: ",
[Link](start,end))

6. Given a graph containing managers and their employees as a dictionary of sets, print all
employees reporting to a given manager.
data = {
"karan": {"darshan","nikhil"},
"darshan": {"khantil", "tanuj"},
"tanuj": {"nikhil"},
"krinish": {"hetul"},
"khantil" : set(),
"nikhil" : set()
}
Find all employees who are reporting to Karan.
#depth first search
def find_employees(data, start, employee, visited=set()):
if start not in visited: # if
not visited print it
print(start, end=" ")
if start == employee:
print(":", end=" ")
[Link](start)
for i in data[start] - visited:
find_employees(data, i, visited) # if
not visited go in depth of it
return
"karan": {"darshan", "nikhil"},
"darshan": {"khantil", "tanuj"},
"tanuj": {"nikhil"},
"krinish": {"hetul"},
"khantil": set(),
"nikhil": set()
find_employees(data, "karan", "karan")

7. DFS
def dfs(data, start, visited=set()):
if start not in visited:
dfs(data, i, visited) # if not visited go in depth of it
'A': {'B'},
'B': {'A', 'C', 'D'},
'C': {'B', 'E'},
'D': {'B', 'E'},
'E': {'C', 'D', 'F'},
'F': {'E'}
}
dfs(data, 'A')

8. BFS
Implement a function to find whether a path exists for a given set of airline routes. The
routes are depicted using graphs as a dictionary of sets, where keys represent as source
and elements of sets represent destinations. Print the path if it exists.
'A': {'B'},
'B': {'A', 'C', 'D'},
'C': {'B', 'E'},
'D': {'B', 'E'},
'E': {'C', 'D', 'F'},
'F': {'E'}
def bfs(data, start, end, visited=[]):
queue = [start]
current_node = [Link](0)
if current_node==end:
print("Path: " + "->".join(visited) + "->" + end)
[Link](current_node)
for i in data[current_node] - set(visited):
[Link](i)
print("Path does not exist!")
data = {
'A': {'B'},
'B': {'C', 'D'},
'C': {'E'},
'D': {'E'},
'E': {'F'},
'F': set()
}
bfs(data, 'A', 'D')

9.
def bfs(data, start, visited=set()):
if current_node not in visited:
print(current_node, end=" ")
[Link](current_node)
for i in data[current_node] - visited:
data = {
'A': {'B'}, 'B': {'A', 'C', 'D'}, 'C': {'B', 'E'}, 'D': {'B', 'E'},
'E': {'C', 'D', 'F'}, 'F': {'E'}
bfs(data, 'A')

10. Given some strings, find the order in which characters are appearing You can use the
topological sorting algorithm. You need to construct a directed graph representing the
character order and then perform a topological sort to determine the order.
from collections import defaultdict
[Link] = defaultdict(list)
[Link] = set()
[Link] = []
def add_edge(self, u, v):
[Link][u].append(v)
def topological_sort(self, v):
[Link](v)
for neighbor in [Link][v]:
if neighbor not in [Link]:
self.topological_sort(neighbor)
[Link](0, v)
def find_character_order(words):
graph = Graph()
for i in range(len(words) - 1):
word1, word2 = words[i], words[i + 1]
for j in range(min(len(word1), len(word2))):
if word1[j] != word2[j]:
graph.add_edge(word1[j], word2[j])
for char in list([Link]): # Iterate over a copy of the keys
if char not in [Link]:
graph.topological_sort(char)
return ''.join([Link])
words = ["wrt", "wrf", "er", "ett", "rft"]
order = find_character_order(words)
print(order)

11. Find the number of possibilities to move from one point to another point in a chess
board kind of square box. This function uses recursion to explore all possible paths from
the starting point to the ending point on an n x n chessboard. It counts the number of
unique paths by summing the possibilities of moving in each of the four directions (up,
down, left, and right) while ensuring that the points are within the boundaries of the
chessboard.
def count_paths(n, start_x, start_y, end_x, end_y):
paths = [[0] * n for _ in range(n)] #Create a 2D grid to store the number of paths for
each cell
paths[start_x][start_y] = 1 #Initialize the
starting point with 1 path
for x in range(start_x, end_x + 1): #Iterate through the grid to calculate the number
of paths
for y in range(start_y, end_y + 1):
if x > 0:
paths[x][y] += paths[x - 1][y]
if y > 0:
paths[x][y] += paths[x][y - 1]
return paths[end_x][end_y] #The result is stored in the destination cell
n=5 # Size of the
chessboard (5x5 in this case)
start_x, start_y = 0, 0 # Starting point
end_x, end_y = 4, 4 # Ending point
result = count_paths(n, start_x, start_y, end_x, end_y)
print(f"Number of paths from ({start_x}, {start_y}) to ({end_x},
{end_y}) on a {n}x{n} chessboard: {result}")

12. The Celebrity Problem (Amazon).


In a party of N people, only one person is known to everyone. Such a person may be present
at the party, if yes, (s)he doesn’t know anyone at the party. We can only ask questions like
“does A know B? “. Find the stranger (celebrity) in the minimum number of questions.
We can describe the problem input as an array of numbers/characters representing
persons in the party. We also have a hypothetical function HaveAcquaintance(A, B) which
returns true if A knows B, and false otherwise. How can we solve the problem?
def celebrity(M, n):
adj = [[] for i in range(n)]
for i in range(n):
for j in range(n):
if M[i][j] == 1:
adj[i].append(j)
for i in range(n): # Check if there is a person who doesn't know
if not adj[i]: # anyone but everyone knows him/her
flag = True
for j in range(n):
if i == j:
continue
if i not in adj[j]:
flag = False
break
if flag:
return i
M = [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 1, 0]]
n = len(M)
Celebrity = celebrity(M, n)
if Celebrity != -1:
print("Celebrity is : ", Celebrity)
print("No celebrity")

13. Print a given matrix in spiral form (Amazon).


def spiralOrder(matrix):
ans = []
if (len(matrix) == 0):
return ans
m = len(matrix)
n = len(matrix[0])
seen = [[0 for i in range(n)] for j in range(m)]
dr = [0, 1, 0, -1]
dc = [1, 0, -1, 0]
x=0
y=0
di = 0
for i in range(m * n):
# Iterate from 0 to R * C - 1
[Link](matrix[x][y])
seen[x][y] = True
cr = x + dr[di]
cc = y + dc[di]
if (0 <= cr and cr < m and 0 <= cc and cc < n and
not(seen[cr][cc])):
x = cr
y = cc
else:
di = (di + 1) % 4
x += dr[di]
y += dc[di]
return ans
arr = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]]
for obj in spiralOrder(arr):
print(obj, end=" ")
print()
14. Minimum cost required to travel from top left to the bottom
right in a matrix (Amazon).
import sys
R=3
C=3
def minCost(cost, m, n):
if (n < 0 or m < 0):
return [Link]
elif (m == 0 and n == 0):
return cost[m][n]
else:
return cost[m][n] + min(minCost(cost, m-1, n-1),
minCost(cost, m-1, n),
minCost(cost, m, n-1))
def min(x, y, z):
#function that returns minimum of 3 integers
if (x < y):
return x if (x < z) else z
return y if (y < z) else z
cost = [[1, 2, 3],
[4, 8, 2],
[1, 5, 3]]
print(minCost(cost, 2, 2))
1. Bubble Sort
def bubble_sort(ele):
size = len(ele)
for i in range(size-1):
swapped = False
for j in range(size-1-i):
if ele[j] > ele[j+1]:
tmp = ele[j]
ele[j] = ele[j+1]
ele[j+1] = tmp
swapped = True
if not swapped:
ele = [5,9,2,1,67,34,88,34]
ele = ["mona", "dhaval", "aamir", "tina", "chang"]
bubble_sort(ele)
print(ele)
2.
def bubble_sort(ele, key=None):
a = ele[j][key]
b = ele[j+1][key]
if a > b:
ele = [
{ 'name': 'mona', 'transaction_amount': 1000, 'device':
'iphone-10'},
{ 'name': 'dhaval', 'transaction_amount': 400, 'device': 'google
pixel'},
{ 'name': 'kathy', 'transaction_amount': 200, 'device':
'vivo'},
{ 'name': 'aamir', 'transaction_amount': 800, 'device':
'iphone-8'},
bubble_sort(ele, key='transaction_amount')
3. Implement quick sort using lumoto partition scheme.
# implementation of quick sort using hoare partition scheme
def swap(a, b, arr):
if a!=b:
tmp = arr[a]
arr[a] = arr[b]
arr[b] = tmp
def quick_sort(ele, start, end):
if start < end:
pi = partition(ele, start, end)
quick_sort(ele, start, pi-1)
quick_sort(ele, pi+1, end)
def partition(ele, start, end):
pivot_index = start
pivot = ele[pivot_index]
while start < end:
while start < len(ele) and ele[start] <= pivot:
start+=1
while ele[end] > pivot:
end-=1
if start < end:
swap(start, end, ele)
swap(pivot_index, end, ele)
return end
ele = [11,9,29,7,2,15,28]
# ele = ["mona", "dhaval", "aamir", "tina", "chang"]
quick_sort(ele, 0, len(ele)-1)
print(ele)
tests = [
[11,9,29,7,2,15,28],
[3, 7, 9, 11],
[25, 22, 21, 10],
[29, 15, 28],
[],
[6]
]
for ele in tests:
quick_sort(ele, 0, len(ele)-1)
print(f'sorted array: {ele}')
4.
# This implements quick sort lomuto partition scheme
def quick_sort(elements, start, end):
if len(elements)== 1:
pi = partition(elements, start, end)
quick_sort(elements, start, pi-1)
quick_sort(elements, pi+1, end)
def partition(elements, start, end):
pivot = elements[end]
p_index = start
for i in range(start, end):
if elements[i] <= pivot:
swap(i, p_index, elements)
p_index += 1
swap(p_index, end, elements)
return p_index
# elements = ["mona", "dhaval", "aamir", "tina", "chang"]
for elements in tests:
quick_sort(elements, 0, len(elements)-1)
print(f'sorted array: {elements}')
5. Insertion Sort
o Compute the running median of a sequence of numbers. That
is, given a stream of numbers, print out the median of the list
so far on each new element.
o The median of an even-numbered list is the average of the two
middle numbers in a *sorted list*.
For example, given the sequence [2, 1, 5, 7, 2, 0, 5], your algorithm
should print out:
2
1.5
3.5
def place_to_insert(array, key):
index = 0
for i in array:
if i > key:
index += 1
return index
def insert_to_sorted(array, key):
index = place_to_insert(array, key)
return array[0:index]+[key]+array[index:]
if __name__ == "__main__":
array = [2, 1, 5, 7, 2, 0, 5]
stream = []
count = 0
while(True):
i = int(input())
count += 1
stream = insert_to_sorted(stream, i)
if count % 2 == 1:
print(f"Median of {stream} : {stream[(count)//2]}")
i1 = count//2
i2 = (count//2) - 1
print(f"Median of {stream} : {(stream[i1] +
stream[i2])/2}")
6.
def insertion_sort(elements):
anchor = elements[i]
j=i-1
while j>=0 and anchor < elements[j]:
elements[j+1] = elements[j]
j=j-1
elements[j+1] = anchor
elements = [11,9,29,7,2,15,28]
insertion_sort(elements)
print(elements)
#
insertion_sort(elements)
7. Merge Sort
def merge_sort(arr):
if len(arr) <= 1:
mid = len(arr)//2
left = arr[:mid]
right = arr[mid:]
left = merge_sort(left)
right = merge_sort(right)
return merge_two_sorted_lists(left, right)
def merge_two_sorted_lists(a,b):
sorted_list = []
len_a = len(a)
len_b = len(b)
i=j=0
while i < len_a and j < len_b:
if a[i] <= b[j]:
sorted_list.append(a[i])
i+=1
sorted_list.append(b[j])
j+=1
while i < len_a:
sorted_list.append(a[i])
i+=1
while j < len_b:
sorted_list.append(b[j])
j+=1
return sorted_list
arr = [10,3,15,7,8,23,98,29]
print(merge_sort(arr))
8.
merge_sort(left)
merge_sort(right)
merge_two_sorted_lists(left, right, arr)
def merge_two_sorted_lists(a,b,arr):
i=j=k=0
arr[k] = a[i]
arr[k] = b[j]
k+=1
arr[k] = a[i]
arr[k] = b[j]
test_cases = [
[10, 3, 15, 7, 8, 23, 98, 29],
[3],
[9,8,7,2],
[1,2,3,4,5]
for arr in test_cases:
merge_sort(arr)
print(arr)
def merge_sort(elements, key, descending=False):
size = len(elements)
if size == 1:
return elements
left_list = merge_sort(elements[0:size//2], key, descending)
right_list = merge_sort(elements[size//2:], key, descending)
sorted_list = merge(left_list, right_list, key, descending)
def merge(left_list, right_list, key, descending=False):
merged = []
if descending:
while len(left_list) > 0 and len(right_list) > 0:
if left_list[0][key] >= right_list[0][key]:
[Link](left_list.pop(0))
[Link](right_list.pop(0))
if left_list[0][key] <= right_list[0][key]:
[Link](left_list)
[Link](right_list)
return merged
elements = [
{ 'name': 'vedanth', 'age': 17, 'time_hours': 1},
{ 'name': 'rajab', 'age': 12, 'time_hours': 3},
{ 'name': 'vignesh', 'age': 21, 'time_hours': 2.5},
{ 'name': 'chinmay', 'age': 24, 'time_hours': 1.5},
sorted_list = merge_sort(elements, key='time_hours',
descending=True)
print(sorted_list)
10. Shell Sort
3. Sort the elements of a given list using shell sort, but with a
slight modification. Remove all the repeating occurances of
elements while sorting.
4. Traditionally, when comparing two elements in shell sort, we
swap if first element is bigger than second, and do nothing
otherwise.
5. In this modified shell sort with duplicate removal, we will swap if
first element is bigger than second, and do nothing if element is
smaller, but if values are same, we will delete one of the two
elements we are comparing before starting the next pass for
the reduced gap.
def shell_sort(arr):
n = len(arr)
div = 2
gap = n//div
while gap > 0:
index_to_delete = []
for i in range(gap, n):
temp = arr[i]
j=i
while j >= gap and arr[j-gap] >= temp:
if arr[j-gap] == temp:
index_to_delete.append(j)
arr[j] = arr[j-gap]
j -= gap
arr[j] = temp
index_to_delete=list(set(index_to_delete))
index_to_delete.sort()
if index_to_delete:
for i in index_to_delete[-1::-1]:
del arr[i]
div *= 2
n = len(arr)
gap = n//div
elements = [2, 1, 5, 7, 2, 0, 5, 1, 2, 9, 5, 8, 3]
print(f'Given unsorted list: {elements}')
shell_sort(elements)
print(f'List after Sorting : {elements}')
11. Selection Sort
o Implement a Multi-Level Sort of a given list of dictionaries
based on a given sorting order. If user wants to sort dictionary
based on First Key 'A', Then Key 'B', they shall pass list of keys
in the order of preference as a list ['A','B']. Your code should be
able to sort list of dictionaries for any number of keys in sorting
order list.
def multilevel_selection_sort(elements, sort_by_list):
for sort_by in sort_by_list[-1::-1]:
for x in range(len(elements)):
min_index = x
for y in range(x, len(elements)):
if elements[y][sort_by] <
elements[min_index][sort_by]:
min_index = y
if x != min_index:
elements[x], elements[min_index] =
elements[min_index], elements[x]
{'First Name': 'Raj', 'Last Name': 'Nayyar'},
{'First Name': 'Suraj', 'Last Name': 'Sharma'},
{'First Name': 'Karan', 'Last Name': 'Kumar'},
{'First Name': 'Jade', 'Last Name': 'Canary'},
{'First Name': 'Raj', 'Last Name': 'Thakur'},
{'First Name': 'Raj', 'Last Name': 'Sharma'},
{'First Name': 'Kiran', 'Last Name': 'Kamla'},
{'First Name': 'Armaan', 'Last Name': 'Kumar'},
{'First Name': 'Jaya', 'Last Name': 'Sharma'},
{'First Name': 'Ingrid', 'Last Name': 'Galore'},
{'First Name': 'Jaya', 'Last Name': 'Seth'},
{'First Name': 'Armaan', 'Last Name': 'Dadra'},
{'First Name': 'Ingrid', 'Last Name': 'Maverick'},
{'First Name': 'Aahana', 'Last Name': 'Arora'}
print(f'Given unsorted array:', *elements, sep='
')
multilevel_selection_sort(
elements, ['First Name', 'Last Name'])
print(f'Array after Multi-Level Sorting:', *elements, sep='
12.
def selection_sort(arr):
size = len(arr)
min_index = i
for j in range(min_index+1,size):
if arr[j] < arr[min_index]:
min_index = j
if i != min_index:
arr[i], arr[min_index] = arr[min_index], arr[i]
[89, 78, 61, 53, 23, 21, 17, 12, 9, 7, 6, 2, 1],
[1,5,8,9],
[234,3,1,56,34,12,9,12,1300],
[78, 12, 15, 8, 61, 53, 23, 27],
[5]
selection_sort(elements)
print(elements)
13. Recursion
def find_sum(n):
if n==1:
return 1
return n + find_sum(n-1)
if n==0 or n==1:
return fib(n-1) + fib(n-2)
if __name__=='__main__':
print(find_sum(5))
print(fib(10))
14. Print number 1.
num = 19
for i in range(num + 1):
count += str(i).count('2')
print(count)
15. Prime
def primes():
num = 100
for i in range(2, num + 1):
is_prime = True
for j in range(2, int(i**0.5) + 1):
if i % j == 0:
is_prime = False
if is_prime:
[Link](i)
primes()
16. Add Digits.
num = 2568
sum = 0
newnum = list(str(num))
for digit in newnum:
sum += int(digit)
print(sum)
17. Remove number from number.
num = 915765
target = '5'
if target in newnum:
index = [Link](target)
[Link](index)
result = ''.join(newnum)
18. Remove last 3 characters of string or number in python.
def remove():
num = 1437000
num_str = str(num)
num_str = num_str[:-3]
print(num_str)
remove()
19. Reverse Integer.
def reverse(num):
target = str(num)
result = int(target[::-1])
reverse(123)
20. Power of Two.
num = 16
if 2**i == num:
print(i)
21. Pow(x, n).
def myPow(x, n):
if n == 0:
temp = myPow(x, abs(n) // 2)
result = temp * temp if n % 2 == 0 else x * temp * temp
return 1 / result if n < 0 else result
print(myPow(2.00000, 10))
1. Detect loop in a linked list. solved it using standard tortoise
hair algorithm.
def has_cycle(head):
if head is None or [Link] is None:
slow = head
fast = head
while fast is not None and [Link] is not None:
slow = [Link] #Tortoise
moves one step
fast = [Link] #Hare
moves two steps
if slow == fast:
return True # Cycle
detected
return False
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
[Link] = node2
[Link] = node3
[Link] = node4
[Link] = node5
[Link] = node2
#Creating a cycle
print(has_cycle(node1))
#True (because of the cycle)
2. Given an integer array, consisting of positive and negative
values, find the contiguous subarray start and end indices
which contain the max sum.
You can find the contiguous subarray with the maximum sum in a
given integer array using the Kadane's algorithm.
3. Given a large database of strings and we have to find the
frequency of each unique string.
Use a dictionary to keep track of the counts of each string.
def count_string_frequency(strings):
frequency_dict = {}
for string in strings:
if string in frequency_dict:
frequency_dict[string] += 1
frequency_dict[string] = 1
return frequency_dict
database = ["apple", "banana", "apple", "cherry", "banana", "apple"]
frequency = count_string_frequency(database)
for string, count in [Link]():
print(f"{string}: {count} times")
4. Remove spaces in a string without using inbuilt function and
taking constant space.
def remove_spaces(input_str):
if input_str is None or len(input_str) == 0:
return input_str
str_list = list(input_str) # Convert to
a list of characters
read_ptr = write_ptr = 0 # Initialize
two pointers for in-place string manipulation
while read_ptr < len(str_list):
if str_list[read_ptr] != ' ':
str_list[write_ptr] = str_list[read_ptr] # Copy
non-space characters to the write_ptr position
write_ptr += 1
read_ptr += 1
str_list = str_list[:write_ptr] #
Truncate the string to the new length (write_ptr)
result = ''.join(str_list) #
Convert the list of characters back to a string
input_str = "Apple, World!"
result = remove_spaces(input_str)
5. Edit Distance (Amazon).
Given two strings str1 and str2 of length M and N respectively and
below operations that can be performed on str1. Find the minimum
number of edits (operations) to convert ‘str1‘ into ‘str2‘.
# recursive
def editDistance(str1, str2, m, n):
if m == 0: # If first
string is empty, the only option is to
return n # insert all
characters of second string into first
if n == 0: # If second
return m # remove all
characters of first string
if str1[m-1] == str2[n-1]: # If last
characters of two strings are same, nothing
return editDistance(str1, str2, m-1, n-1) # much to do.
Ignore last characters and get count for
#
remaining strings.
return 1 + min(editDistance(str1, str2, m, n-1),
# Insert
editDistance(str1, str2, m-1, n),
# Remove
editDistance(str1, str2, m-1, n-1)
# Replace
)
str1 = "sunday"
str2 = "saturday"
print (editDistance(str1, str2, len(str1), len(str2)))
6. Assembly Line Scheduling (Amazon).
Assembly line scheduling is a problem in operations management
that involves determining the optimal sequence of tasks or operations
on an assembly line to minimize production costs or maximize
efficiency. This problem can be solved using various data structures
and algorithms. One common approach is dynamic programming,
which involves breaking the problem down into smaller sub-problems
and solving them recursively.
def fun(a, t, cl, cs, x1, x2, n):
if cs == n - 1:
if cl == 0:
# exiting from (current) line =0
return x1
else:
# exiting from line 2
return x2
same = fun(a, t, cl, cs + 1, x1, x2, n) + a[cl][cs + 1]
# continue on same line
diff = fun(a, t, not cl, cs + 1, x1, x2, n) + a[not cl][cs + 1] +
t[cl][cs + 1] #continue on different line
return min(same, diff)
stations = 4
t = [[4, 5, 3, 2], [2, 10, 1, 4]]
#time take each station
t2 = [[0, 7, 4, 5], [0, 9, 2, 8]]
#time take switch line
e1 = 10
# time taken to enter first line
e2 = 12
# time taken to enter second line
x1 = 18
# time taken to exit first line
x2 = 7
# time taken to exit second line
entry_from_1st_line = fun(t, t2, 0, 0, x1, x2, stations) + e1 +
t[0][0]
entry_from_2nd_line = fun(t, t2, 1, 0, x1, x2, stations) + e2 +
t[1][0]
print(min(entry_from_1st_line, entry_from_2nd_line))
7. Smallest window in a String containing all characters of other
String (Amazon).
o Input: string = “this is a test string”, pattern = “tist”
o Output: “t stri”
o Explanation: “t stri” contains all the characters of pattern.
def containsAllCharacters(substr, pattern):
count = [0] * 256
for ch in pattern:
count[ord(ch)] += 1
for ch in substr:
if count[ord(ch)] > 0:
count[ord(ch)] -= 1
for i in range(256): # If all counts
in the count array are zero, the
if count[i] > 0: # substring
contains all characters of the pattern
return False
return True
def fun(s, pattern):
len_str = len(s)
smallestSubstring = ""
minLength = float('inf')
for i in range(len_str): #
Generate all substrings of the given string
for j in range(i, len_str):
substr = s[i:j+1]

if containsAllCharacters(substr, pattern): #
Substring contains all characters of pattern
currentLength = len(substr)
if currentLength < minLength:
# Update the smallestSubstring
minLength = currentLength
smallestSubstring = substr
return smallestSubstring
str1 = "this is a test string"
pattern1 = "tist"
print("Input: string =" + str1 + ", pattern = " + pattern1)
print("Output: " + fun(str1, pattern1))
8. Maximum of all subarrays of size K (Amazon).
o Input: arr[] = [1, 2, 3, 1, 4, 5, 2, 3, 6], K = 3
o Output: 3 3 4 5 5 5 6
Explanation
▪ Maximum of 1, 2, 3 is 3
▪ Maximum of 1, 4, 5 is 5
▪ Maximum of 2, 3, 1 is 3
def printMax(arr, N, K):
max = 0
for i in range(N - K + 1):
max = arr[i]
for j in range(1, K):
if arr[i + j] > max:
max = arr[i + j]
print(str(max), end=" ")
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
printMax(arr, len(arr), 3)
9. Minimum number of swaps required for arranging pairs
adjacent to each other (Amazon).
There are n-pairs and therefore 2n people. everyone has one unique
number ranging from 1 to 2n. All these 2n persons are arranged in
random fashion in an Array of size 2n. We are also given who is
partner of whom. Find the minimum number of swaps required to
arrange these pairs such that all pairs become adjacent to each
other.
Input:
n=3
pairs[] = {1->3, 2->6, 4->5} // 1 is partner of 3 and so on
arr[] = {3, 5, 6, 4, 1, 2}
Output: 2
We can get {3, 1, 5, 4, 6, 2} by swapping 5 & 6, and 6 & 1
def updateindex(index,a,ai,b,bi):
index[a] = ai
index[b] = bi
def minSwapsUtil(arr,pairs,index,i,n):
if (i > n): # If all
pairs processed so no swapping needed return 0
return 0
if (pairs[arr[i]] == arr[i+1]): # If current
pair is valid so move ahead.
return minSwapsUtil(arr, pairs, index, i+2, n)
one = arr[i+1]
indextwo = i+1
indexone = index[pairs[arr[i]]]
two = arr[index[pairs[arr[i]]]]
arr[i+1],arr[indexone]=arr[indexone],arr[i+1]
updateindex(index, one, indexone, two, indextwo)
a = minSwapsUtil(arr, pairs, index, i+2, n)
arr[i+1],arr[indexone]=arr[indexone],arr[i+1] # Backtrack to
previous configuration.
updateindex(index, one, indextwo, two, indexone) # Also restore
the previous indices,of one and two
one = arr[i]
indexone = index[pairs[arr[i+1]]]
two = arr[index[pairs[arr[i+1]]]] # Swap arr[i]
with pair of arr[i+1] and recursively
indextwo = i # compute
minimum swaps required for subproblem
arr[i],arr[indexone]=arr[indexone],arr[i] # after this
move
b = minSwapsUtil(arr, pairs, index, i+2, n)
arr[i],arr[indexone]=arr[indexone],arr[i]
updateindex(index, one, indextwo, two, indexone)
return 1 + min(a, b) # Return minimum
of two cases
def minSwaps(n,pairs,arr):
index=[] # To store
indices of array elements
for i in range(2*n+1+1):
[Link](0)
for i in range(1,2*n+1): # Store index of
each element in array index
index[arr[i]] = i
return minSwapsUtil(arr, pairs, index, 1, 2*n)
arr = [0, 3, 5, 6, 4, 1, 2]
pairs= [0, 3, 6, 1, 5, 4, 2] # if (a, b) is pair
than we have assigned elements
# in array such
that pairs[a] = b and pairs[b] = a
m = len(pairs)
n = m//2 # Number of pairs n
is half of total elements
print(minSwaps(n, pairs, arr)) # If there are n
elements in array, then
# there are n pairs
10. Given two string print them inter leaving strings characters
def toString(List):
return "".join(List)
def printIlsRecur(str1, str2, iStr, m, n, i):
if m==0 and n==0: # If all
characters of str1 & str2 have been included
print (toString(iStr)) # in
output string, then print the output string
if m != 0: # Some
characters of str1 are left to be included,
iStr[i] = str1[0] # then
include first character from remaining
printIlsRecur(str1[1:], str2, iStr, m-1, n, i+1) #
characters and recur for rest
if n != 0:
iStr[i] = str2[0]
printIlsRecur(str1, str2[1:], iStr, m, n-1, i+1)
def printIls(str1, str2, m, n):
# Allocates memory for output string
iStr = [''] * (m+n)
printIlsRecur(str1, str2, iStr, m, n, 0)
str1 = "AB"
str2 = "CD"
printIls(str1, str2, len(str1), len(str2))
11. Find the longest common prefix string amongst an array of
strings.
//Iterative
def fun(arr):
if not arr:
return ""
result = arr[0]
while not arr[i].startswith(result):
result = result[:-1]
arr = ["flower", "flow", "flight"]
result = fun(arr)
//Recursion
def fun(arr, index=0, result=None):
if result is None:
result = arr[0]
if index == len(arr):
print(result)
while not arr[index].startswith(result):
result = result[:-1]
fun(arr, index + 1, result)
fun(["flower", "flow", "flight"])
//Stack
if len(arr) == 0:
stack = list(arr[0])
for i in range(1, len(arr)):
while not arr[i].startswith(''.join(stack)):
[Link]()
print(''.join(stack))
12. Unique Char.
def find_unique_words():
str = "Java is great Grails is also great Grails is also great"
new_str = [Link](' ')
for word in new_str:
if word not in result:
[Link](word)
find_unique_words()
13. Find vowel
def find_vowels():
str = 'apple'
vowel = 'aeiou'
result = ''
if char in vowel:
result += char
find_vowels()
14. Remove All Adjacent Duplicates In String.
str = "wwelcom"
if stack and char == stack[-1]:
[Link](char)
result = ''.join(stack)
15. Destroy Those Pairs.
str = 'abccd'
new_str = []
if char not in new_str:
new_str.append(char)
new_str.pop()
result = ''.join(new_str)
16. Longest Substring from a String.
str = 'second itemlonger is longer than the third one'
arr = [Link](' ')
for word in arr:
if len(word) > len(result):
result = word
17. Longest Substring Without Repeating Characters.
str = 'applaaops'
current_str = ''
longest_str = ''
if char in current_str:
# Remove characters from the beginning of current_str
until the repeated character
current_str = current_str[current_str.index(char) + 1:] +
char
current_str += char
if len(current_str) > len(longest_str):
longest_str = current_str
print(longest_str)
18. Isomorphic Strings.
def fun(str1, str2):
if len(str1) != len(str2):
mapping1 = {}
mapping2 = {}
for i in range(len(str1)):
char1, char2 = str1[i], str2[i]
if char1 in mapping1:
if mapping1[char1] != char2:
mapping1[char1] = char2
if char2 in mapping2:
if mapping2[char2] != char1:
mapping2[char2] = char1
return True
str1 = 'egg'
str2 = 'add'
print(fun(str1, str2))
1.
Let us say your expense for every month are listed below,
1. January - 2200
2. February - 2350
3. March - 2600
4. April - 2130
5. May - 2190
Create a list to store these monthly expenses and using that find out,
o In Feb, how many dollars you spent extra compare to January?
o Find out your total expense in first quarter of the year.
o Find out if you spent exactly 2000 dollars in any month
o June month just finished and your expense is 1980 dollar. Add
this item to our monthly expense list
o You returned an item that you bought in a month of April and
got a refund of 200$. Make a correction to your monthly
expense list based on this
exp = [2200,2350,2600,2130,2190]
print(exp[1]-exp[0])
print(exp[0]+exp[1]+exp[2])
print(2000 in exp)
[Link](1980)
print('Expenses at the end of June ',exp)
exp[3] = exp[3]-200
print('Expenses after 200$ return in April', exp)
2. You have a list of your favourite marvel super heros.
heros=['spider man','thor','hulk','iron man','captain america']
Using this find out,
o Length of the list
o Add 'black panther' at the end of this list
o You realize that you need to add 'black panther' after 'hulk', so
remove it from the list first and then add it after 'hulk'
o Now you don't like thor and hulk because they get angry easily
:) So you want to remove thor and hulk from list and replace
them with doctor strange.
o Sort the heros list in alphabetical order
print(len(heros))
[Link]('black panther')
print(heros)
[Link]('black panther')
[Link](3,'black panther')
print(heros)
heros[1:3]=['doctor strange']
[Link]()
3. Create a list of all odd numbers between 1 and a max number.
max = int(input("Enter max number: "))
odd_numbers = []
for i in range(1, max):
if i % 2 == 1:
odd_numbers.append(i)
print(odd_numbers)
4. Given an integer array, consisting of positive and negative
def max_subarray_sum(arr):
if not arr:
return None
max_sum = arr[0]
current_sum = arr[0]
start = end = 0
temp_start = 0
if arr[i] > current_sum + arr[i]:
current_sum = arr[i]
temp_start = i
current_sum += arr[i]
if current_sum > max_sum:
max_sum = current_sum
start = temp_start
end = i
return start, end
arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
start, end = max_subarray_sum(arr)
print("Start index:", start)
print("End index:", end)
print("Maximum sum:", sum(arr[start:end+1]))
5. Write code to multiply two matrix
def multiply(matrix1, matrix2):
rows1 = len(matrix1) #
Dimensions of the input matrices
cols1 = len(matrix1[0])
rows2 = len(matrix2)
cols2 = len(matrix2[0])
if cols1 != rows2:
raise ValueError("Columns in the first matrix must be equal
to the rows in the second matrix.")
result = [[0 for _ in range(cols2)] for _ in range(rows1)] #
Initialize the result matrix with zeros
for i in range(rows1): #
Perform matrix multiplication
for j in range(cols2):
for k in range(cols1):
result[i][j] += matrix1[i][k] * matrix2[k][j]
matrix1 = [[1, 2, 3], [4, 5, 6]]
matrix2 = [[7, 8], [9, 10], [11, 12]]
result = multiply(matrix1, matrix2)
for row in result:
print(row)
6. Find Maximum sum in an array such that no 2 elements are
adjacent. In this, 1 more condition was also there that first and
last elements should also not be taken together.
Solve this problem using dynamic programming.
This function first calculates the maximum sum without including the
first element and then calculates the maximum sum without including
the last element.
7. Pythagorean Triplet in an array (Amazon).
16.
17.
find a triplet with sum equal to 0.
Find a pair with given sum.
All such questions are efficiently solved using hashing.
def isTriplet(ar, n):
for i in range(n):
ar[i] = ar[i] * ar[i]
[Link]()
for i in range(n - 1, 1, -1):
left = 0
right = i - 1
while left < right:
if ar[left] + ar[right] == ar[i]:
return 1
triplet
# Found a
if ar[left] + ar[right] < ar[i]:
left += 1
right -= 1
return 0
# If we
reach here, no triplet found
ar = [3, 1, 4, 6, 5]
if isTriplet(ar, len(ar)):
print("Yes")
print("No")
8. Given an array, print the Next Greater Element (NGE) for every
element (Amazon).
Input: arr[] = [ 4 , 5 , 2 , 25 ]
Output: 4 –>
5
5 –>
25
2 –>
25 –> -1
Explanation: except 25 every element has an element greater than them
present on the right side
def printNGE(arr):
for i in range(0, len(arr), 1):
next = -1
for j in range(i+1, len(arr), 1):
if arr[i] < arr[j]:
next = arr[j]
break
print(str(arr[i]) + " -- " + str(next))
arr = [11, 13, 21, 3]
printNGE(arr)
9. Maximum Index, Given an array arr[], find the maximum j – i
such that arr[i] lteq arr[j] (Amazon).
Input: {34, 8, 10, 3, 2, 80, 30, 33, 1}
Output: 6 (j = 7, i = 1)
Input: {9, 2, 3, 4, 5, 6, 7, 8, 18, 0}
Output: 8 ( j = 8, i = 0)
def maxIndexDiff(arr, n):
maxDiff = -1
for i in range(0, n):
j=n-1
while(j > i):
if arr[j] > arr[i] and maxDiff < (j - i):
maxDiff = j - i
j -= 1
return maxDiff
arr = [9, 2, 3, 4, 5, 6, 7, 8, 18, 0]
n = len(arr)
maxDiff = maxIndexDiff(arr, n)
print(maxDiff)
10. Arrange given numbers to form the biggest number
Given an array of numbers, arrange them in a way that yields the
largest value. For example, if the given numbers are [54, 546, 548,
60], the arrangement 6054854654 gives the largest value. And if the
given numbers are [1, 34, 3, 98, 9, 76, 45, 4], then the arrangement
998764543431 gives the largest value.
def fun(array):
if len(array)==1: #If one element in the list,
the element itself is the largest element.
return str(array[0])
for i in range(len(array)): #Convert a list into a string
array that is suitable for concatenation
array[i]=str(array[i]) #
[54,546,548,60]=>['54','546','548','60']
for i in range(len(array)):
#Find the largest element by swapping.
for j in range(1+i,len(array)):
if array[j]+array[i]>array[i]+array[j]:
array[i],array[j]=array[j],array[i]
result=''.join(array)
if(result=='0'*len(result)):
#If all elements are 0, answer must be 0
return '0'
return result
print(fun([54, 546, 548, 60]))
11. Given a list of numbers of odd length design an algorithm to
remove a number and divide the rest numbers equally so as it
makes their sum same (Aazon).
Input: arr = [6, 2, 3, 2, 1]
Output: true
Explanation: On removing element 2 at index 1,
the array gets divided into two subarrays [6]
and [3, 2, 1] having equal sum
Input: arr = [6, 1, 3, 2, 5]
Explanation: On removing element 3 at index 2,
the array gets divided into two subarrays [6, 1]
and [2, 5] having equal sum.
def printSubArray(arr, start, end):
print ("[ ", end = "")
for i in range(start, end+1):
print (arr[i], end =" ")
print ("]", end ="")
def divideArray(arr, n):
sum = 0 # sum
of all elements of the array
sum += arr[i]
sum_so_far = 0 # sum
stores sum till previous index of array
if 2 * sum_so_far + arr[i] == sum: # Removing
arr[i], we get equals left and right half
print ("two subarrays are -", end = "")
printSubArray(arr, 0, i - 1)
printSubArray(arr, i + 1, n - 1)
return True
sum_so_far += arr[i]
# add current element to sum_so_far
return False
arr = [6, 2, 3, 2, 1]
divideArray(arr, len(arr))
12. Find the length of maximum numbers of consecutive
numbers jumped up in an array (Amazon).
13. Delete the elements in a linklist whose sum is equal to
zero(Amazon)
14. Evaluate Reverse Polish Notation
def fun(tokens):
for tok in tokens:
if [Link]() or (tok[0] == '-' and tok[1:].isdigit()):
[Link](int(tok))
b = [Link]()
a = [Link]()
if tok == "+":
[Link](a + b)
elif tok == "*":
[Link](a * b)
elif tok == "-":
[Link](a - b)
elif tok == "/":
[Link](int(a / b))
return [Link]()
result = fun(["2", "1", "+", "3", "*"])
15. Find Sum of an array.
arr = [-1, 2, 1, -4]
for item in arr:
sum += item
def fun(arr, index=0):
return arr[index] + fun(arr, index + 1)
result = fun([-1, 2, 1, -4])
stack = 0
while arr:
stack += [Link]()
print(stack)
fun([-1, 2, 1, -4])
//Queue
stack += [Link](0)
16. Close 3 sum equal to 1.
def fun(nums, target):
closest_sum = float('inf')
closest_triplet = []
[Link]()
for i in range(len(nums) - 2):
left, right = i + 1, len(nums) - 1
current_sum = nums[i] + nums[left] + nums[right]
if abs(current_sum - target) < abs(closest_sum - target):
closest_sum = current_sum
closest_triplet = [nums[i], nums[left], nums[right]]
if current_sum < target:
return closest_triplet
nums = [-1, 3, 2, 5, 10, 4, -2]
target = 1
result = fun(nums, target)
17. Intersection of 3 Sorted Arrays
arr = [1, 5, 10, 20, 40, 80]
arr2 = [6, 7, 20, 80, 100]
arr3 = [3, 4, 15, 20, 30, 70, 80, 120]
for num in arr:
if num in arr2 and num in arr3:
[Link](num)
18. Sort
arr = [0, 9, 8, 7, 6]
for i in range(len(arr)):
for j in range(i, len(arr)):
if arr[i] > arr[j]:
arr[i], arr[j] = arr[j], arr[i]
print(arr)
19. Remove Duplicates
arr = [1, 2, 3, 4, 3, 0, 9, 0, 1]
for j in range(len(arr)):
if count == 1:
20. Compare Array
def compare():
arr = [1, 2, 3, 4, 5, 6]
arr2 = [5, 6, 7, 8, 9, 0]
if num in arr2:
compare()
21. Sort Those Squares.
arr = [-7, -3, 2, 3, 11]
[Link](num * num)
for i in range(len(result)):
for j in range(i, len(result)):
if result[i] > result[j]:
result[i], result[j] = result[j], result[i]
22. Occurence of Elements.
arr = [1, 2, 3, 4, 5, 6, 1, 2, 1, 3]
hash = {}
if num in hash:
hash[num] += 1
hash[num] = 1
print(hash)
23. Target Elements.
arr = [1, 2, 3, 4, 5, 6]
target = 6
if target in arr:
[Link](target)
24. Sepate Number and Character
arr = [
2, 'a', 10, 'b', 'c', 'e',
'f', 'g', 25, 44, 'h', 'k',
'l', 55, 60, 67, 'm', 'x',
'y', 100, 101, 'z'
str_list = []
num_list = []
for item in arr:
if isinstance(item, int):
num_list.append(item)
elif isinstance(item, str):
str_list.append(item)
print("Numbers:", num_list)
print("Strings:", str_list)
25. Combination Sum
arr = [1, 2, 3, 6, 4, 5]
target = 7
for j in range(i, len(arr)):
if arr[i] + arr[j] == target:
[Link]([arr[i], arr[j]])
26. Remove Element
arr = [1, 2, 3, 5, 4]
num = 5
if num in arr:
index = [Link](num)
[Link](index)
print(arr)
27. Replace Element
newnum = 6
arr[index] = newnum
28. Shuffle the Array.
def suffle(arr):
seed = int(([Link]() * 1000) % 1000)
j = (i + seed) % n
arr[i], arr[j] = arr[j], arr[i]
arr = [7, 8, 9, 10]
suffle(arr)
29. Missing Ranges.
arr = [1, 2, 4, 8]
missing = []
count = 1
for num in arr:
while count < num:
[Link](count)
count = num + 1
while count <= arr[-1]:
[Link](count)
count += 1
print(missing)
30. Product of Array Except Self.
arr = [1, 2, 3, 4]
prod = 1
if i != j:
prod *= arr[j]
[Link](prod)
print(prod)
31. Count of Smaller Numbers After Self.
arr = [5, 2, 6, 1]
result = [0] * len(arr)
if arr[i] > arr[j]:
result[i] += 1
32. Subarray max sum
arr = [1, 3, -1, 6, 2, 2, 0, 3, 2, 1]
result = 0
if arr[i] <= 0:
sum = 0
sum += arr[i]
result = max(result, sum)
33. Maximum Product Subarray.
result = 1
product = 1
product = 1
product *= arr[i]
result = max(result, product)
1. Star
star=""
for i in range(3):
for j in range(i+1):
star += '*'
star += 'newline'
print(star)
2. Armstrong Number
def arm():
num = int(input('Enter number'))
temp = num
while temp > 0:
remainder = temp % 10
sum += remainder**3
temp = temp // 10
if sum == num:
print('Armstrong', num)
print('Not an Armstrong', num)
arm()
3. Permutations
def arm(s):
currentChar = ''
remainingChar = ''
if len(s) == 0:
return [""]
if len(s) == 1:
return [s]
for i in range(len(s)):
currentChar = s[i]
remainingChar = s[:i] + s[i+1:]
for sub_permutation in arm(remainingChar):
for j in range(len(sub_permutation) + 1):
new_permutation = sub_permutation[:j] + currentChar +
sub_permutation[j:]
if new_permutation not in result:
[Link](new_permutation)
permutations = arm('abc')
for perm in permutations:
print(perm, end=' ')
4. Given an amount of money, return the minimum number of
coins needed to make that change.
def min_coin(amount, coins):
for i in range(len(coins)):
while coins[i] <= amount:
amount -= coins[i]
min_coin(87, [25, 10, 5, 1])
5. Sort an Array
arr = [3, 5, 1, 9, 6, 2, 1, -1]
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
[Link](arr[i])
6. Occurence elements in the array.
arr = [1, 2, 3, 3, 2]
count = {}
for el in arr:
count[el] = [Link](el, 0) + 1
print(count)
7. Find unque element in array
def unique(arr):
if item not in count:
count[item] = 1
count[item] += 1
if count[item] == 1:
[Link](item)
return result
print(unique([2, 3, 4, 3, 2, 5]))
8. Remove a specific item from an array
arr = [1, 2, 3, 4, 5, 3]
value = 2
if value in arr:
[Link](value)
9. Insert an element at specific place in Array
arr = [1, 2, 3, 4, 5]
[Link](2, 7)
print(','.join(map(str, arr)))
Largest Perimeter Triangle.
arr = [2, 1, 2, 5, 6, 7, 8, 9, 3]
[Link]()
for i in range(len(arr) - 3, -1, -1):
if arr[i] + arr[i + 1] > arr[i + 2]:
result = arr[i] + arr[i + 1] + arr[i + 2]
Pascal's Triangle
def fun(numRows):
for i in range(numRows):
currentRow = []
num = 1 # The first element in each row is always 1
for j in range(i + 1):
[Link](num)
num = num * (i - j) // (j + 1) # Calculate the next
number based on the previous number
[Link](currentRow)
numRows = 5
pascals_triangle = fun(numRows)
for row in pascals_triangle:
Rectangle Area.
arr = [-3, 0, 3, 4, 0, -1, 9, 2]
maxArea = 0
length = abs(arr[i])
width = abs(arr[j])
area = length * width
if area > maxArea:
maxArea = area
print(maxArea)
1. Linked List
Append
function createList(data){
const head={value:data, next:null};
let tail=null;
function append(item){
let newnode={value:item, next:null}
if(tail==null){
[Link]=newnode;
tail=newnode;
}else{
[Link]=newnode;
}
function print(){
let currentNode=head;
let current='';
while(currentNode){
current += [Link];
if([Link]){
current += '->'
currentNode=[Link];
[Link](current)
return {append, print}
const obj=new createList(2);
[Link](1)
[Link](3)
[Link]()
Traversing
function traversing(){
let mapnode=head;
while(mapnode){
[Link]([Link]);
mapnode=[Link]
Delete
function deletes(index){
let lend=head;
let counter=1;
while(counter < index-1){
lend=[Link];
counter++;
if([Link]){
let nextNode=[Link];
[Link]=nextNode;
size -= 1;
2. Hash Table
function HashTable() {
const hash = {};
function hashFunction(key) {
let hashValue = 0;
for (let i = 0; i < [Link]; i++) {
hashValue += [Link](i);
return hashValue % 100; // You can adjust the size of the hash
table as needed.
function insert(key, value) {
const index = hashFunction(key);
if (!hash[index]) {
hash[index] = {};
hash[index][key] = value;
function get(key) {
if (hash[index] && hash[index][key] !== undefined) {
return hash[index][key];
} else {
return null;
}
function update(key, value) {
throw new Error('Key not found');
function remove(key) {
delete hash[index][key];
function getAll() {
const values = [];
for (const index in hash) {
const keys = [Link](hash[index]);
for (const key of keys) {
[Link](hash[index][key]);
return values;
return { insert, get, update, remove, getAll };
const myHashTable = new HashTable();
[Link]('name', 'John');
[Link]('country', 'India');
[Link]('city', 'Noida');
[Link]('age', 30);
[Link]([Link]('name'));
[Link]('age', 31);
[Link]([Link]('age'));
[Link]('age');
[Link]([Link]());
3. Create Tree
function Nodes(data, left, right){
[Link]=data;
[Link]=left;
[Link]=right;
[Link]=show;
function show(){
return [Link];
function bst(){
[Link]=null;
[Link]=insert;
function insert(data){
const node=new Nodes(data,null,null)
if([Link] === null){
[Link]=node;
var current=[Link];
var parrent;
while(current){
parrent=current;
if(data < [Link]){
current=[Link];
if(current === null){
[Link]=node;
current = [Link];
[Link] = node;
const obj= new bst();
[Link](3)
[Link](5)
[Link](2)
[Link](7)
[Link](1)
[Link]([Link])
function preOrder(node) {
if (node !== null) {
[Link]([Link]() + " ");
preOrder([Link]);
preOrder([Link]);
preOrder([Link]);
function deleteNode(root, key){
if(root === null){
return root;
if(key < [Link]){
[Link] = deleteNode([Link], key)
}else if(key > [Link]){
[Link] = deleteNode([Link], key)
}else {
if([Link] === null){
return [Link];
}else if([Link] === null){
[Link] = deleteNode([Link], 6)
inOrder([Link])
Updates
function updateNode(node, target, newValue) {
if (node === null) {
return null; // Target node not
found
if (target < [Link]) {
[Link] = updateNode([Link], target, newValue);
} else if (target > [Link]) {
[Link] = updateNode([Link], target, newValue);
[Link] = newValue; // Found the target
node, update its data
return node;
[Link] = updateNode([Link], 4, 10);
inOrder([Link]);
4. Graph
Create
function createGraph() {
return {
vertices: new Map(),
};
function addVertex(graph, vertex) {
if (![Link](vertex)) {
[Link](vertex, []);
return graph;
function addEdge(graph, vertex1, vertex2) {
if ([Link](vertex1) && [Link](vertex2)) {
[Link](vertex1).push(vertex2);
[Link](vertex2).push(vertex1);
const graph = createGraph();
addVertex(graph, 'A');
addVertex(graph, 'B');
addVertex(graph, 'C');
addVertex(graph, 'D');
addEdge(graph, 'A', 'B');
addEdge(graph, 'B', 'C');
addEdge(graph, 'C', 'D');
addEdge(graph, 'D', 'A');
[Link](graph);
Remove
function removeVertex(graph, vertex) {
if ([Link](vertex)) {
const neighbors = [Link](vertex);
for (const neighbor of neighbors) {
const adjList = [Link](neighbor);
const index = [Link](vertex);
if (index !== -1) {
[Link](index, 1);
[Link](vertex);
function removeEdge(graph, vertex1, vertex2) {
const adjList1 = [Link](vertex1);
const index1 = [Link](vertex2);
if (index1 !== -1) {
[Link](index1, 1);
const adjList2 = [Link](vertex2);
const index2 = [Link](vertex1);
if (index2 !== -1) {
[Link](index2, 1);
removeVertex(obj, 'B');
Update
function updateVertex(graph, oldVertex, newVertex) {
if ([Link](oldVertex)) {
const neighbors = [Link](oldVertex);
[Link](oldVertex);
[Link](newVertex, neighbors);
for (const [vertex, adjList] of [Link]) {
if ([Link](oldVertex)) {
const index = [Link](oldVertex);
adjList[index] = newVertex;
updateVertex(obj, 'A', 'D');
LinkList:
[Link]=data
[Link]=next
class LinlLinst:
print('None')
listr=''
node = Node(data, None)
[Link]=node
return
[Link]=Node(data, None)
li = LinlLinst()
[Link](1)
[Link](2)
[Link](3)
[Link](4)
def insertAt(self, data, index):
def __init__(self, data=None, next=None, prev=None):
[Link] = prev
class DLinkedList:
def append(self, data):
while [Link]:
newnode = Node(data, prev=current)
[Link] = newnode
def prepend(self, data):
newnode = Node(data)
[Link] = [Link]
[Link] = newnode
[Link] = newnode
def delete(self, target):
if [Link] == target:
if current == [Link]:
[Link] = [Link]
[Link] = [Link]
if [Link]:
[Link] = [Link]
listr += str([Link]) + ' <-> '
print(listr)
dll = DLinkedList()
[Link](1)
[Link](2)
[Link](3)
[Link](4)
[Link](0)
[Link]()
[Link](2)
[Link](0)
[Link](5)
print([Link]())
def insert_values(self, data_list):
for data in data_list:
li = LinlLinst()
li.insert_values(["banana","mango","grapes","orange"])
[Link]()
def __init__(self, initial_data=None):
if initial_data:
for data in initial_data:
[Link](data)
def insert_after(self, after, insertData):
if [Link]==after:
[Link] = Node(insertData,[Link])
[Link] = Node(insertData, [Link])
li = LinlLinst(["banana","mango","grapes","orange"])
li.insert_after("mango","apple")
node=Node(data, [Link])
def search(self, target):
index = 0
return index
return -1
li=LinkList()
[Link](1)
[Link](2)
[Link](3)
sea=[Link](1)
if sea !=-1:
print(f"Found {sea}")
print(f"Not Found")
8. Implement doubly linked list.
print(listr[:-5])
li = DLinkedList()
[Link](1)
[Link](2)
[Link](5)
[Link](7)
[Link](3)
9. Delete.
new_node = Node(data, prev=current)
[Link] = new_node
new_node = Node(data)
new_node.next = [Link]
[Link] = new_node
[Link] = new_node
list_str = ''
list_str += str([Link]) + ' <-> '
print(list_str)
10. Linked List Cycle.
[Link] = Node(data)
def append(self, item):
newnode = Node(item)
[Link] = newnode
[Link] = newnode
[Link] = newnode
current_node = [Link]
while current_node:
print(current_node.data)
current_node = current_node.next
if [Link] and [Link]:
[Link] = [Link]
def breakCycle(self):
[Link] = None
list = LinkedList(1)
[Link](2)
[Link](4)
# [Link]()
[Link]()
# [Link]()
Hash Table
def hasFunction(self, key):
def insert(self, key, value):
index = [Link](key)
[Link][index] = {}
[Link][index][key] = value
def get(self, key):
def update(self, key, value):
[Link][index][key] = value
raise KeyError("Key not found")
def remove(self, key):
def get_all(self):
values = []
[Link]([Link][index][key])
return values
obj = HashTable()
[Link]("name", "John")
[Link]("country", "India")
[Link]("city", "Noida")
[Link]("age", 30)
print([Link]("name"))
print(obj.get_all())
[Link]("age", 31)
print([Link]("age"))
[Link]("age")
stock_prices_data = [
"march 6,310",
"march 7,340",
"march 8,380",
"march 9,302",
"march 10,297",
"march 11,323"
stock_prices = []
for line in stock_prices_data:
stock_prices.append([day, price])
print(stock_prices)
print(stock_prices[0])
data = [
["march 6", 310],
["march 7", 340],
["march 8", 380],
["march 9", 302],
["march 10", 297],
["march 11", 323]
5.
class HashTable:
[Link] = 100
[Link] = [None for i in range([Link])]
def get_hash(self, key):
hash = 0
hash += ord(char)
return hash % [Link]
def __getitem__(self, key):
h = self.get_hash(key)
return [Link][h]
def __setitem__(self, key, val):
[Link][h] = val
def __delitem__(self, key):
[Link][h] = None
t = HashTable()
# Set values
t["march 6"] = 310
t["march 7"] = 420
print([Link])
t["dec 30"] = 88
print(t["dec 30"])
del t["march 6"]
1. Write a function that can reverse a string using stack data
stack = []
[Link]('Apple')
[Link]('B')
[Link]('C')
[Link]('D')
[Link]()
print(stack[-1])
The issue with using a list as a stack is that list uses dymanic array
internally and when it reaches its capacity it will reallocate a big
chunk of memory somewhere else in memory area and copy all the
elements.
2. Using deque as a stack
stack = deque()
print(stack)
3. Implement Stack class using a deque
[Link] = deque()
def push(self, data):
[Link](data)
def pop(self):
return [Link]()
return [Link][-1]
return len([Link]) == 0
return len([Link])
[Link](5)
[Link](9)
4. Write a function in python that checks if paranthesis in the string
are balanced or not. Possible parantheses are "',"()" or "[]".
def push(self, val):
[Link](val)
def is_empty(self):
def is_match(ch1, ch2):
match_dict = {
')': '(',
']': '[',
'}': '{'
return match_dict[ch1] == ch2
def is_balanced(s):
for ch in s:
if ch=='(' or ch=='{' or ch == '[':
[Link](ch)
if ch==')' or ch=='}' or ch == ']':
if not is_match(ch,[Link]()):
print(is_balanced("({a+b})"))
print(is_balanced("))((a+b}{"))
print(is_balanced("((a+b))"))
print(is_balanced("((a+g))"))
print(is_balanced("))"))
print(is_balanced("[a+b]*(x+2y)*{gg+kk}"))
5. Reverse String
def reverse_string(s):
[Link](ch)
rstr = ''
while [Link]()!=0:
rstr += [Link]()
return rstr
print(reverse_string("We will conquere COVI-19"))
1. Write a program to print binary numbers from 1 to 10 using
return len([Link]) == 0
return len([Link])
def front(self):
num = Queue()
[Link]("1")
front = [Link]()
print(front)
[Link](front + "0")
[Link](front + "1")
[Link]()
binaryNum(10)
1. Create Tree
print([Link])
for child in [Link]:
print([Link])
def addChild(self, child):
def productTree():
root = Node("Electronics")
laptop = Node("Laptop")
[Link](Node("Mac"))
[Link](Node("Surface"))
[Link](Node("Thinkpad"))
cellphone = Node("Cell Phone")
[Link](Node("iPhone"))
[Link](Node("Google Pixel"))
[Link](Node("Vivo"))
tv = Node("TV")
[Link](Node("Samsung"))
[Link](Node("LG"))
[Link](laptop)
[Link](cellphone)
[Link](tv)
[Link]()
productTree()
2. Print Children
[Link]()
3. Print Tree
ParentLev = [Link]
while ParentLev:
ParentLev = [Link]
def buildTree():
buildTree()
5. Delete
def delete_child(self, target):
new_children = [child for child in [Link] if
[Link] != target]
[Link] = new_children
laptop.delete_child("Thinkpad")
[Link]()
6. Update
def updates(self, target_data, new_data):
if [Link] == target_data:
[Link] = new_data
[Link](target_data, new_data)
[Link](laptop)7
[Link]("Surface", "NewSurface")
4. post_order_traversal(): performs post order traversal of a binary
class BNode:
def addChild(self, data):
if data == [Link]:
#node already exist
return
if data < [Link]:
if [Link]:
[Link](data)
[Link] = BNode(data)
if [Link]:
[Link](data)
[Link] = BNode(data)
def inOrder(self):
elements = []
if [Link]:
elements += [Link]()
[Link]([Link])
if [Link]:
elements += [Link]()
def postOrder(self):
elements += [Link]()
elements += [Link]()
def preOrder(self):
elements = [[Link]]
elements += [Link]()
elements += [Link]()
root = BNode(elements[0])
for i in range(1,len(elements)):
[Link](elements[i])
numbers = [17, 4, 1, 20, 9, 23, 18, 34]
numbers_tree = buildTree(numbers)
print(numbers)
print(numbers_tree.inOrder())
print(numbers_tree.preOrder())
print(numbers_tree.postOrder())
if data == [Link]:
def findMax(self):
if [Link] is None:
return [Link]
return [Link]()
def findMin(self):
if [Link] is None:
return [Link]()
def addSum(self):
leftSum = [Link]() if [Link] else 0
rightSum = [Link]() if [Link] else 0
return [Link] + leftSum + rightSum
print("Min:",numbers_tree.findMin())
print("Max:",numbers_tree.findMax())
print("Sum:", numbers_tree.addSum())
def search(self, val):
if [Link] == val:
if val < [Link]:
return [Link](val)
if val > [Link]:
return [Link](val)
#numbers = ["India","Pakistan","Germany",
print(numbers_tree.search(20))
def findMAx(self):
return [Link]()
def delete(self, val):
[Link] = [Link](val)
elif val > [Link]:
[Link] = [Link](val)
if [Link] is None and [Link] is None:
elif [Link] is None:
return [Link]
elif [Link] is None:
max_val = [Link]()
[Link] = max_val
[Link] = [Link](max_val)
return self
numbers_tree.delete(20)
Binary Search, Find index of all the occurances of a number from
sorted list
def binary_search(numbers_list, number_to_find):
right_index = len(numbers_list) - 1
mid_number = numbers_list[mid_index]
if mid_number == number_to_find:
if mid_number < number_to_find: # this means number is in
right hand side of the list
else: # number to find is on left hand side of the list
def find_all_occurances(numbers, number_to_find):
index = binary_search(numbers, number_to_find)
# find indices on left hand side
i = index-1
while i >=0:
if numbers[i] == number_to_find:
# find indices on right hand side
i = index + 1
numbers = [1,4,6,9,11,15,15,15,17,21,34,34,56]
number_to_find = 15
indices = find_all_occurances(numbers, number_to_find)
print(f"Indices of occurances of {number_to_find} are {indices}")
1. Graph Dictionay
[Link] = edges
print("Graph Dict:", [Link])
routes = [
("Mumbai","Pune"),
("Mumbai", "Surat"),
("Surat", "Bangaluru"),
("Pune","Hyderabad"),
("Pune","Mysuru"),
("Hyderabad","Bangaluru"),
("Hyderabad", "Chennai"),
("Mysuru", "Bangaluru"),
("Chennai", "Bangaluru")
route_graph = Graph(routes)
d={"Mumbai": ["Paris", "Dubai"]}
2. Get Path
def getPath(self, start, end, path=[]):
paths = []
new_paths = [Link](node, end, path)
for p in new_paths:
[Link](p)
return paths
start = "Mumbai"
end = "Bangaluru"
print(f"All paths between: {start} and {end}:
",route_graph.getPath(start,end))
3. Sortest Path
def sortestPath(self, start, end, path=[]):
print(f"Shortest path between {start} and {end}: ",
route_graph.sortestPath(start,end))

You might also like