Python
Python
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)
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.
It should include:
The Python standard library directory, and
Any directories containing your own Python source code.
Type annotations:
• While Python is a dynamically typed language, type annotations can clarify types.
Built-in types:
• int, float, bool, str, bytes
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)
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)
# Tuple multiplication
my_tuple = ('a', 'b') * 5
print(my_tuple)
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)
# 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])
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
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)
# Updating sets
[Link](setB)
setA.intersection_update(setB)
setA.difference_update(setB)
setA.symmetric_difference_update(setB)
Dictionaries
my_dict = {"name":"Max", "age":28, "city":"New York"}
my_dict_2 = dict(name="Lisa", age=27, city="Boston")
# 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")
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)
Strings
• Strings are immutable.
• Triple quotes """ are used for multiline strings.
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)
# 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)
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))
# 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=' ')
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))
class Test:
def __init__(self, name):
[Link] = []
[Link] = name
def __str__(self):
return '{} holds ...'.format([Link])
obj = Test('obj')
print(obj)
Applications:
• Fourier transforms
• Audio & speech recognition systems
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)
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
# 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
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
Output:
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message
# Variable-length arguments
def fun(*args):
for item in args:
print(item)
fun("Hello", "Welcome", "to", "World")
# Keyword arguments
def fun(a, b):
print(a, b)
fun(b="Practice", a="Geeks")
# Positional argument
def fun(a, b):
print(a, b)
fun(1, 2)
• 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_)
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)
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
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)
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)
# 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
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")
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)
For-Else Loop
for x in range(6):
print(x)
else:
print("Finally finished!")
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")
• 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'))
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)
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.
import json
data = {"name":"John","phone":"12345"}
with open("[Link]","w") as f:
[Link](data, f)
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)
# 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")
class Student:
school_name = "ABC Public School" # static/class variable
def __init__(self, name, age):
[Link] = name # instance variable
[Link] = age
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]())
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.
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)
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))
54. Threading
When Threading is Useful
• I/O-bound tasks: network, disk operations.
• Allows program to perform other tasks while waiting.
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.
print(next(my_iterator)) # 1
print(next(my_iterator)) # 2
print(next(my_iterator)) # 3
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
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")
# 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)
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)
Examples
# Lambda with one argument
f = lambda x: x + 10
val1 = f(5)
val2 = f(100)
print(val1, val2)
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))
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]()
Lock Features:
[Link]() – locks the resource.
[Link]() – unlocks the resource.
Recommended: use context manager (with lock) to automatically handle
acquire/release.
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().
# 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)
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
3. Defaultdict
Subclass of dict that provides default values for missing keys (avoids KeyError).
4. UserDict
Wrapper around a dictionary to customize behavior.
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.
3. ChainMap
• Encapsulates multiple dictionaries into one view.
• Useful for combining contexts or configuration layers.
# 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.
if len(passwd) < 6:
print('length should be 6')
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()
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
print(binary_num)
Binary → Decimal
decimal_val, base = 0, 1
binary_val = 1010
print(decimal_val)
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()
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()
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)
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()
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()
Itertools Functions
product()
from itertools import product
# Cartesian product
prod = product([1, 2], [3, 4])
print(list(prod))
# 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()
# 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)
a = [Link]([1, 2, 3, 4, 5, 6, 7])
p = [Link](a, 50)
print(p)
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()
print(sum_squares(4))
# Reverse traversal
for i in range(len(my_list)-1, -1, -1):
print(my_list[i])
Array Operations
from array import *
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]()
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.
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))
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])
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)
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
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)
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"])
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]
//
arr = list('apple')
for i in range(len(arr)):
if arr[i] in result:
[Link](arr[i])
[Link](arr[i])
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:")
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")
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))
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)
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)
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.")
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]()
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))
[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))
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}")
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, []);
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))