Python Preparation Guide
Python Preparation Guide
Table of Contents
1. Basic Operations
2. String Manipulation
3. Number Operations
4. Pattern Printing
5. File Handling
6. OOP Concepts
7. Advanced Concepts
8. Company-Specific Questions
Basic Operations
import decimal
integer = 10
result = decimal.Decimal(integer)
print(result) # Output: 10
print(type(result)) # Output: <class 'decimal.Decimal'>
integer = 10
result = float(integer)
print(result) # Output: 10.0
print(type(result)) # Output: <class 'float'>
2. Converting String to Decimal
import decimal
string = '12345'
result = decimal.Decimal(string)
print(result) # Output: 12345
print(type(result)) # Output: <class 'decimal.Decimal'>
string = '12345'
result = float(string)
print(result) # Output: 12345.0
print(type(result)) # Output: <class 'float'>
3. Reversing a String
4. Counting Vowels
5. Counting Consonants
import re
word = "programming"
count = len(re.findall('[^aeiou]', word))
print(count) # Output: 8
word = "programming"
character = 'g'
count = 0
for i in word:
if i == character:
count += 1
print(count) # Output: 2
7. Fibonacci Series
fib = [0, 1]
n=5
for i in range(n):
fib.append(fib[-1] + fib[-2])
print(','.join(str(e) for e in fib)) # Output: 0,1,1,2,3,5,8
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
res_lst = []
for i in range(len(lst1)):
res_lst.append(lst1[i] + lst2[i])
print(res_lst) # Output: [5, 7, 9]
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
res_lst = [lst1[i] + lst2[i] for i in range(len(lst1))]
print(res_lst) # Output: [5, 7, 9]
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
res_lst = [a + b for a, b in zip(lst1, lst2)]
print(res_lst) # Output: [5, 7, 9]
str1 = "Listen"
str2 = "Silent"
str1 = "Listen"
str2 = "Silent"
if Counter(str1) == Counter(str2):
print("True")
else:
print("False") # Output: True
if len(str1) != len(str2):
return False
freq = {}
for char in str1:
freq[char] = freq.get(char, 0) + 1
return True
str1 = "Kayak".lower()
if str1 == str1[::-1]:
print("True")
else:
print("False") # Output: True
def is_palindrome(s):
s = s.lower().replace(" ", "")
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
def is_palindrome(s):
s = s.lower().replace(" ", "")
return s == ''.join(reversed(s))
print(is_palindrome("Kayak")) # Output: True
import re
string = "P r ogram in g"
count = len(re.findall(r'\s', string))
print(count) # Output: 4
import re
name = ' is 1'
digitCount = re.sub("[^0-9]", "", name)
letterCount = re.sub("[^a-zA-Z]", "", name)
spaceCount = re.findall(r"\s", name)
print(len(digitCount)) # Output: 1
print(len(letterCount)) # Output: 7
print(len(spaceCount)) # Output: 2
print(digits) # Output: 1
print(letters) # Output: 7
print(spaces) # Output: 2
print(digits) # Output: 1
print(letters) # Output: 7
print(spaces) # Output: 2
17. Counting Special Characters
def count_sp_char(string):
sp_char = "|@#$%^&*()<>?/\\[]{};:~"
count = 0
for i in string:
if i in sp_char:
count += 1
return count
import re
def count_sp_char(string):
return len(re.findall(r'[^\w\s]', string))
import string
def count_sp_char(text):
return sum(1 for char in text if char in string.punctuation)
import re
string = "C O D E"
spaces = re.compile(r'\s+')
result = re.sub(spaces, "", string)
print(result) # Output: CODE
text
*
**
***
****
*****
n=5
for i in range(1, n+1):
for j in range(i):
print("*", end=" ")
print()
n=5
for i in range(1, n+1):
print("* " * i)
n=5
pattern = ["* " * i for i in range(1, n+1)]
print("\n".join(pattern))
Pattern 2: Inverted Right-Angled Triangle
text
*****
****
***
**
*
n=5
for i in range(n, 0, -1):
for j in range(i):
print("*", end=" ")
print()
n=5
for i in range(n, 0, -1):
print("* " * i)
n=5
for i in reversed(range(1, n+1)):
print("* " * i)
Pattern 3: Pyramid
text
*
**
***
****
*****
n=5
for i in range(1, n+1):
# Print spaces
for j in range(n - i):
print(" ", end="")
# Print stars
for k in range(i):
print("*", end=" ")
print()
n=5
for i in range(1, n+1):
print(" " * (n - i) + "* " * i)
n=5
for i in range(1, n+1):
print(("* " * i).center(2 * n))
text
*****
****
***
**
*
Method 1: Using nested loops
n=5
for i in range(n, 0, -1):
# Print spaces
for j in range(n - i):
print(" ", end="")
# Print stars
for k in range(i):
print("*", end=" ")
print()
n=5
for i in range(n, 0, -1):
print(" " * (n - i) + "* " * i)
n=5
for i in reversed(range(1, n+1)):
print(" " * (n - i) + "* " * i)
Number Patterns
text
1
12
123
1234
12345
n=5
for i in range(1, n+1):
for j in range(1, i+1):
print(j, end=" ")
print()
n=5
for i in range(1, n+1):
print(" ".join(str(j) for j in range(1, i+1)))
n=5
pattern = [" ".join(str(j) for j in range(1, i+1)) for i in range(1, n+1)]
print("\n".join(pattern))
text
1
22
333
4444
55555
n=5
for i in range(1, n+1):
print((str(i) + " ") * i)
n=5
pattern = [(str(i) + " ") * i for i in range(1, n+1)]
print("\n".join(pattern))
text
1
11
121
1331
14641
n=5
for i in range(n):
# Print leading spaces
print(" " * (n - i), end="")
n=5
triangle = []
for i in range(n):
row = [1] * (i + 1)
for j in range(1, i):
row[j] = triangle[i-1][j-1] + triangle[i-1][j]
triangle.append(row)
print(" " * (n - i) + " ".join(map(str, row)))
def pascal_triangle(n):
row = [1]
for i in range(n):
print(" " * (n - i) + " ".join(map(str, row)))
row = [1] + [row[j] + row[j+1] for j in range(len(row)-1)] + [1]
pascal_triangle(5)
text
1
23
456
7 8 9 10
11 12 13 14 15
n=5
for i in range(1, n+1):
start = (i * (i - 1)) // 2 + 1
end = (i * (i + 1)) // 2
print(" ".join(str(j) for j in range(start, end + 1)))
def floyd_generator(n):
num = 1
for i in range(1, n+1):
yield " ".join(str(num + j) for j in range(i))
num += i
Alphabet Patterns
text
A
BB
CCC
DDDD
EEEEE
n=5
for i in range(n):
for j in range(i+1):
print(chr(65 + i), end=" ")
print()
n=5
for i in range(n):
print((chr(65 + i) + " ") * (i + 1))
n=5
pattern = [(chr(65 + i) + " ") * (i + 1) for i in range(n)]
print("\n".join(pattern))
text
A
AB
ABC
ABCD
ABCDE
n=5
for i in range(1, n+1):
print(" ".join(chr(65 + j) for j in range(i)))
n=5
pattern = [" ".join(chr(65 + j) for j in range(i)) for i in range(1, n+1)]
print("\n".join(pattern))
text
A
BC
DEF
GHIJ
KLMNO
n=5
char = 65 # ASCII for 'A'
for i in range(n):
# Print spaces
print(" " * (n - i - 1), end="")
# Print characters
for j in range(i + 1):
print(chr(char), end=" ")
char += 1
print()
n=5
char = 65
for i in range(n):
chars = " ".join(chr(char + j) for j in range(i + 1))
print(f"{chars:^{2*n}}")
char += i + 1
def alphabet_diamond(n):
char = 65
for i in range(n):
row = " ".join(chr(char + j) for j in range(i + 1))
yield f"{row:^{2*n}}"
char += i + 1
text
A
BC
DEF
GHIJ
KLMNO
n=5
for i in range(n):
start_char = 65 + (i * (i + 1)) // 2
print(" ".join(chr(start_char + j) for j in range(i + 1)))
def alphabet_triangle(n):
char = 65
for i in range(n):
row = " ".join(chr(char + j) for j in range(i + 1))
yield row
char += i + 1
Diamond Patterns
text
*
**
***
****
*****
****
***
**
*
n=5
# Upper part
for i in range(n):
print(" " * (n - i - 1) + "* " * (i + 1))
# Lower part
for i in range(n - 2, -1, -1):
print(" " * (n - i - 1) + "* " * (i + 1))
n=5
for i in range(-n + 1, n):
spaces = abs(i)
stars = n - spaces
print(" " * spaces + "* " * stars)
n=5
for i in range(-n + 1, n):
row = "* " * (n - abs(i))
print(row.center(2 * n))
text
1
12
123
1234
12345
1234
123
12
1
n=5
# Upper part
for i in range(1, n + 1):
print(" " * (n - i), end="")
for j in range(1, i + 1):
print(j, end=" ")
print()
# Lower part
for i in range(n - 1, 0, -1):
print(" " * (n - i), end="")
for j in range(1, i + 1):
print(j, end=" ")
print()
n=5
for i in range(-n + 1, n):
row = " ".join(str(j) for j in range(1, n - abs(i) + 1))
print(f"{row:^{2*n}}")
n=5
pattern = []
for i in range(-n + 1, n):
row = " ".join(str(j) for j in range(1, n - abs(i) + 1))
pattern.append(f"{row:^{2*n}}")
print("\n".join(pattern))
text
*
**
* *
* *
* *
* *
* *
**
*
n=5
# Upper part
for i in range(n):
if i == 0:
print(" " * (n - 1) + "*")
else:
print(" " * (n - i - 1) + "*" + " " * (2 * i - 1) + "*")
# Lower part
for i in range(n - 2, -1, -1):
if i == 0:
print(" " * (n - 1) + "*")
else:
print(" " * (n - i - 1) + "*" + " " * (2 * i - 1) + "*")
n=5
for i in range(-n + 1, n):
row = ""
for j in range(-n + 1, n):
if abs(i) + abs(j) == n - 1:
row += "*"
else:
row += " "
print(row)
Triangle Patterns
text
*
**
***
****
*****
n=5
for i in range(1, n + 1):
print("* " * i)
n=5
print("\n".join(["* " * i for i in range(1, n + 1)]))
text
*****
****
***
**
*
n=5
for i in range(n, 0, -1):
for j in range(i):
print("*", end=" ")
print()
n=5
print("\n".join(["* " * i for i in range(n, 0, -1)]))
text
*
**
***
****
*****
n=5
for i in range(1, n + 1):
print(" " * (n - i) + "*" * i)
n=5
for i in range(1, n + 1):
print(f"{'*' * i:>{n}}")
n=5
for i in range(1, n + 1):
print(("*" * i).rjust(n))
Pattern 19: Hollow Right Triangle
text
*
**
* *
* *
*****
n=5
for i in range(1, n + 1):
if i == 1 or i == n:
print("* " * i)
else:
print("*" + " " * (2 * i - 3) + "*")
n=5
for i in range(n):
if i == 0:
print("*")
elif i == n - 1:
print("* " * n)
else:
print("*" + " " * (2 * i - 1) + "*")
n=5
pattern = []
for i in range(n):
if i == 0:
pattern.append("*")
elif i == n - 1:
pattern.append("* " * n)
else:
pattern.append("*" + " " * (2 * i - 1) + "*")
print("\n".join(pattern))
text
* *
** **
*** ***
********
********
*** ***
** **
* *
n=4
# Upper wing
for i in range(1, n + 1):
print("* " * i + " " * (n - i) * 2 + "* " * i)
# Lower wing
for i in range(n, 0, -1):
print("* " * i + " " * (n - i) * 2 + "* " * i)
n=4
for i in range(1, 2 * n):
if i <= n:
stars = i
spaces = 2 * (n - i)
else:
stars = 2 * n - i
spaces = 2 * (i - n)
text
*** ***
***** *****
***********
*********
*******
*****
***
*
heart = [
" *** *** ",
" ***** ***** ",
"***********",
" ********* ",
" ******* ",
" ***** ",
" *** ",
" * "
]
n=8
for i in range(n):
if i < 3:
# Top part of heart
spaces = abs(i - 1) * 2
stars = 5 - 2 * abs(i - 1)
line = " " * spaces + "*" * stars + " " * (10 - 2 * spaces - 2 * stars) + "*" * stars
print(line)
else:
# Bottom part of heart
spaces = i - 1
stars = 2 * (n - i) - 1
print(" " * spaces + "*" * stars)
import math
def heart_shape(size):
for y in range(size, -size, -1):
line = ""
for x in range(-size, size):
# Heart equation: (x^2 + y^2 - 1)^3 - x^2*y^3 <= 0
if ((x * 0.05) ** 2 + (y * 0.1) ** 2 - 1) ** 3 - (x * 0.05) ** 2 * (y * 0.1) ** 3 <= 0:
line += "*"
else:
line += " "
print(line)
heart_shape(15)
text
*
***
*****
*******
*********
|||
|||
n=5
# Tree part
for i in range(1, n + 1):
print(" " * (n - i) + "*" * (2 * i - 1))
# Trunk part
for i in range(2):
print(" " * (n - 2) + "|||")
n=5
# Tree part
for i in range(1, n + 1):
print(("*" * (2 * i - 1)).center(2 * n - 1))
# Trunk part
for i in range(2):
print("|||".center(2 * n - 1))
Method 3: Using generator function
def christmas_tree(height):
# Generate tree layers
for i in range(1, height + 1):
yield ("*" * (2 * i - 1)).center(2 * height - 1)
# Generate trunk
for i in range(2):
yield "|||".center(2 * height - 1)
Matrix Patterns
text
*****
*****
*****
*****
*****
n=5
for i in range(n):
for j in range(n):
print("*", end=" ")
print()
Method 2: Using string multiplication
n=5
for i in range(n):
print("* " * n)
n=5
pattern = ["* " * n for i in range(n)]
print("\n".join(pattern))
text
*****
* *
* *
* *
*****
n=5
for i in range(n):
for j in range(n):
if i == 0 or i == n - 1 or j == 0 or j == n - 1:
print("*", end=" ")
else:
print(" ", end=" ")
print()
n=5
pattern = []
for i in range(n):
if i == 0 or i == n - 1:
pattern.append("* " * n)
else:
pattern.append("*" + " " * (2 * n - 3) + "*")
print("\n".join(pattern))
text
*****
****
*****
****
*****
n=5
for i in range(n):
if i % 2 == 0:
print("* " * n)
else:
print(" *" * n)
Method 2: Using mathematical approach
n=5
for i in range(n):
row = ""
for j in range(n):
if (i + j) % 2 == 0:
row += "* "
else:
row += " "
print(row)
n=5
pattern = []
for i in range(n):
if i % 2 == 0:
pattern.append("* " * n)
else:
pattern.append(" *" * n)
print("\n".join(pattern))
text
12345
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
# Right column
for i in range(top, bottom + 1):
matrix[i][right] = num
num += 1
right -= 1
# Bottom row
for i in range(right, left - 1, -1):
matrix[bottom][i] = num
num += 1
bottom -= 1
# Left column
for i in range(bottom, top - 1, -1):
matrix[i][left] = num
num += 1
left += 1
return matrix
n=5
spiral = spiral_matrix(n)
for row in spiral:
print(" ".join(f"{num:2}" for num in row))
# Right column
for i in range(1, n):
matrix[i][n-1] = start + n - 1 + i
# Bottom row
for j in range(n-2, -1, -1):
matrix[n-1][j] = start + 2*n - 2 + (n-1-j)
# Left column
for i in range(n-2, 0, -1):
matrix[i][0] = start + 3*n - 3 + (n-1-i)
return matrix
n=5
spiral = spiral_matrix_recursive(n)
for row in spiral:
print(" ".join(f"{num:2}" for num in row))
Advanced Patterns
text
* * *
* * * *
* *
rows = 3
cols = 9
for i in range(rows):
for j in range(cols):
if (i + j) % 4 == 0 or (j - i) % 4 == 0 and i != 0:
print("*", end="")
else:
print(" ", end="")
print()
rows = 3
cols = 9
for i in range(rows):
j=i
line = [" "] * cols
while j < cols:
line[j] = "*"
if i == 0 or i == 2:
j += 4
else:
j += 2
print("".join(line))
text
* * *
* * *
**
**
* * *
* * *
n=6
for i in range(n):
for j in range(n):
if (i == j or i + j == n - 1) and (i <= n//2 or j <= n//2):
print("*", end="")
else:
print(" ", end="")
print()
n=6
for i in range(n):
line = []
for j in range(n):
if (i == j or i + j == n - 1) and (i < n//2 or j < n//2 or i == j == n//2):
line.append("*")
else:
line.append(" ")
print("".join(line))
n=6
half = n // 2
for i in range(n):
if i < half:
line = [" "] * n
line[i] = "*"
line[n - i - 1] = "*"
print("".join(line))
else:
line = [" "] * n
line[i] = "*"
line[n - i - 1] = "*"
print("".join(line))
text
* *
* *
*
* *
* *
n=5
for i in range(n):
for j in range(n):
if i == j or i + j == n - 1:
print("*", end="")
else:
print(" ", end="")
print()
n=5
for i in range(n):
line = [" "] * n
line[i] = "*"
line[n - i - 1] = "*"
print("".join(line))
n=5
pattern = []
for i in range(n):
row = [" "] * n
row[i] = "*"
row[n - i - 1] = "*"
pattern.append("".join(row))
print("\n".join(pattern))
Pattern 30: Arrow Pattern
text
*
**
***
****
***
**
*
n=4
for i in range(-n + 1, n):
print("* " * (n - abs(i)))
n=4
# Upper part
for i in range(1, n + 1):
print("* " * i)
# Lower part
for i in range(n - 1, 0, -1):
print("* " * i)
n=4
for i in range(1, 2 * n):
stars = i if i <= n else 2 * n - i
print("* " * stars)
19. Building a Pyramid
def pyramid(n):
for i in range(1, n+1):
print(' '*(n-i) + '*'*(2*i-1))
pyramid(5)
# Output:
# *
# ***
# *****
# *******
# *********
def number_pyramid(n):
for i in range(1, n+1):
print(' '*(n-i), end='')
for j in range(1, i+1):
print(j, end=' ')
print()
number_pyramid(5)
# Output:
# 1
# 12
# 123
# 1234
#12345
def alphabet_pyramid(n):
for i in range(1, n+1):
print(' '*(n-i), end='')
for j in range(i):
print(chr(65 + j), end=' ')
print()
alphabet_pyramid(5)
# Output:
# A
# AB
# ABC
# ABCD
#ABCDE
import random
def manual_shuffle(lst):
for i in range(len(lst)-1, 0, -1):
j = random.randint(0, i)
lst[i], lst[j] = lst[j], lst[i]
return lst
def isprime(num):
if num < 2:
return False
for i in range(2, int(num**0.5)+1):
if num % i == 0:
return False
return True
def prime_generator(n):
num = 2
count = 0
while count < n:
if isprime(num):
yield num
count += 1
num += 1
def prime_no(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
def prime_no(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
import random
def average(*args):
avg = sum(args)/len(args)
return avg
def print_details(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
add = lambda x, y: x + y
print(add(5, 3)) # Output: 8
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
import math
num = int(input("Enter a number: "))
print(f"The factorial of {num} is", math.factorial(num))
# Input: 5
# Output: The factorial of 5 is 120
Method 4: Using lambda recursion
# Create a matrix
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
print(matrix) # Output: [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
s1 = s1[::-1]
print(s1)
# Output: ['world', 'your', 'in', 'right', 'is', 'mind', 'your', 'in', 'right', 'is', 'What']
# Split by comma
csv_data = "John,30,New York"
data = csv_data.split(",")
print(data) # Output: ['John', '30', 'New York']
x = 5 # global variable
def f1():
global x
x = 15 # global variable updated
y = 10 # local variable
print(f"x={x} y={y}")
x = 5 # global variable
def f1():
x = 10 # local variable (shadows global x)
y = 10 # local variable
print(f"x={x} y={y}")
x = 5 # global variable
def fun():
x = 10 # local variable
d = globals() # d is dictionary
print(f"local x={x} global x={d['x']}")
x = int('123')
a = float('123.42')
b = complex('3+4j')
c = str(12)
d = bool('True')
e = bin(25) # binary
f = oct(25)
g = hex(25)
h = ord('A') # char to unicode
i = chr(98) # unicode to character
print(x, a, b, c, d, e, f, g, h, i, sep="\n")
# Output:
# 123
# 123.42
# (3+4j)
# 12
# True
# 0b11001
# 0o31
# 0x19
# 65
#b
s1 = '123'
print(type(s1)) # Output: <class 'str'>
Problem: Create a Person class with attributes name, age, and gender. Implement methods to
display person details and check if the person is an adult.
def display_details(self):
return f"Name: {self.name}, Age: {self.age}, Gender: {self.gender}"
def is_adult(self):
return self.age >= 18
# Usage
person1 = Person("Alice", 25, "Female")
print(person1.display_details()) # Output: Name: Alice, Age: 25, Gender: Female
print(person1.is_adult()) # Output: True
class Person:
def __init__(self, name, age, gender):
self._name = name
self._age = age
self._gender = gender
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@property
def gender(self):
return self._gender
def display_details(self):
return f"Name: {self.name}, Age: {self.age}, Gender: {self.gender}"
def is_adult(self):
return self.age >= 18
# Usage
person1 = Person("Bob", 16, "Male")
print(person1.display_details()) # Output: Name: Bob, Age: 16, Gender: Male
print(person1.is_adult()) # Output: False
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
@classmethod
def from_birth_year(cls, name, birth_year, gender):
from datetime import datetime
current_year = datetime.now().year
age = current_year - birth_year
return cls(name, age, gender)
@staticmethod
def is_valid_age(age):
return 0 <= age <= 120
def display_details(self):
return f"Name: {self.name}, Age: {self.age}, Gender: {self.gender}"
def is_adult(self):
return self.age >= 18
# Usage
person1 = Person.from_birth_year("Charlie", 1995, "Male")
print(person1.display_details()) # Output: Name: Charlie, Age: 29, Gender: Male
print(Person.is_valid_age(150)) # Output: False
Question 2: Bank Account System
Problem: Create a BankAccount class with methods for deposit, withdrawal, and checking
balance. Implement proper validation.
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder
self.balance = initial_balance
self.transaction_history = []
def get_balance(self):
return f"Balance: ${self.balance}"
def get_transaction_history(self):
return self.transaction_history
# Usage
account = BankAccount("John Doe", 1000)
print(account.deposit(500)) # Output: Deposited $500. New balance: $1500
print(account.withdraw(200)) # Output: Withdrew $200. New balance: $1300
print(account.get_balance()) # Output: Balance: $1300
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self._account_holder = account_holder
self._balance = initial_balance
self._transaction_history = []
@property
def balance(self):
return self._balance
@property
def account_holder(self):
return self._account_holder
def __str__(self):
return f"Account Holder: {self.account_holder}, Balance: ${self.balance}"
# Usage
account = BankAccount("Jane Smith", 2000)
account.deposit(300)
account.withdraw(100)
print(account) # Output: Account Holder: Jane Smith, Balance: $2200
class BankAccount:
def __init__(self, account_holder, initial_balance=0, interest_rate=0.01):
self.account_holder = account_holder
self.balance = initial_balance
self.interest_rate = interest_rate
self.transactions = []
def get_transaction_history(self):
return self.transactions
def get_balance(self):
return self.balance
# Usage
account = BankAccount("Tom Johnson", 1000, 0.02)
account.deposit(500, "Salary")
account.withdraw(200, "Rent")
account.add_interest()
print(f"Balance: ${account.get_balance():.2f}") # Output: Balance: $1326.00
Inheritance
Problem: Create a base class Vehicle and derived classes Car, Motorcycle, and Truck with
specific attributes and methods.
class Vehicle:
def __init__(self, make, model, year, color):
self.make = make
self.model = model
self.year = year
self.color = color
self.speed = 0
def __str__(self):
return f"{self.year} {self.make} {self.model} ({self.color})"
class Car(Vehicle):
def __init__(self, make, model, year, color, doors):
super().__init__(make, model, year, color)
self.doors = doors
def honk(self):
return "Beep beep!"
def __str__(self):
return f"{super().__str__()}, {self.doors} doors"
class Motorcycle(Vehicle):
def __init__(self, make, model, year, color, has_sidecar):
super().__init__(make, model, year, color)
self.has_sidecar = has_sidecar
def wheelie(self):
return "Doing a wheelie!"
def __str__(self):
sidecar_info = "with sidecar" if self.has_sidecar else "without sidecar"
return f"{super().__str__()}, {sidecar_info}"
# Usage
car = Car("Toyota", "Camry", 2022, "Blue", 4)
bike = Motorcycle("Harley", "Davidson", 2021, "Black", False)
class Vehicle(ABC):
def __init__(self, make, model, year, color):
self.make = make
self.model = model
self.year = year
self.color = color
self.speed = 0
@abstractmethod
def get_type(self):
pass
def __str__(self):
return f"{self.year} {self.make} {self.model} ({self.color})"
class Car(Vehicle):
def __init__(self, make, model, year, color, doors):
super().__init__(make, model, year, color)
self.doors = doors
def get_type(self):
return "Car"
def honk(self):
return "Beep beep!"
def __str__(self):
return f"{super().__str__()}, {self.doors} doors"
class Truck(Vehicle):
def __init__(self, make, model, year, color, cargo_capacity):
super().__init__(make, model, year, color)
self.cargo_capacity = cargo_capacity
def get_type(self):
return "Truck"
def __str__(self):
return f"{super().__str__()}, Capacity: {self.cargo_capacity} kg"
# Usage
vehicles = [
Car("Honda", "Civic", 2020, "Red", 4),
Truck("Ford", "F-150", 2019, "White", 2000)
]
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.speed = 0
def move(self):
return "Vehicle is moving"
def stop(self):
self.speed = 0
return "Vehicle stopped"
class LandVehicle(Vehicle):
def __init__(self, make, model, year, wheels):
super().__init__(make, model, year)
self.wheels = wheels
def drive(self):
return f"Driving on {self.wheels} wheels"
class WaterVehicle(Vehicle):
def __init__(self, make, model, year, displacement):
super().__init__(make, model, year)
self.displacement = displacement
def sail(self):
return f"Sailing with displacement {self.displacement} tons"
# Usage
amphibious = AmphibiousVehicle("Gibbs", "Aquada", 2023, 4, 1.5)
print(amphibious.operate("land")) # Output: Driving on 4 wheels
print(amphibious.operate("water")) # Output: Sailing with displacement 1.5 tons
class Employee:
def __init__(self, name, employee_id, base_salary):
self.name = name
self.employee_id = employee_id
self.base_salary = base_salary
def calculate_salary(self):
return self.base_salary
def __str__(self):
return f"{self.name} (ID: {self.employee_id})"
class Manager(Employee):
def __init__(self, name, employee_id, base_salary, bonus):
super().__init__(name, employee_id, base_salary)
self.bonus = bonus
def calculate_salary(self):
return self.base_salary + self.bonus
def __str__(self):
return f"Manager: {super().__str__()}"
class Developer(Employee):
def __init__(self, name, employee_id, base_salary, programming_language):
super().__init__(name, employee_id, base_salary)
self.programming_language = programming_language
def calculate_salary(self):
# Developers get 10% extra for their expertise
return self.base_salary * 1.10
def __str__(self):
return f"Developer: {super().__str__()} - {self.programming_language}"
class Designer(Employee):
def __init__(self, name, employee_id, base_salary, design_tool):
super().__init__(name, employee_id, base_salary)
self.design_tool = design_tool
def calculate_salary(self):
# Designers get 5% extra
return self.base_salary * 1.05
def __str__(self):
return f"Designer: {super().__str__()} - {self.design_tool}"
# Usage
employees = [
Manager("Alice Johnson", "M001", 80000, 15000),
Developer("Bob Smith", "D001", 70000, ""),
Designer("Charlie Brown", "DS001", 65000, "Figma")
]
class Employee(ABC):
def __init__(self, name, employee_id):
self.name = name
self.employee_id = employee_id
@abstractmethod
def calculate_salary(self):
pass
@abstractmethod
def get_role(self):
pass
def __str__(self):
return f"{self.get_role()}: {self.name} (ID: {self.employee_id})"
class FullTimeEmployee(Employee):
def __init__(self, name, employee_id, monthly_salary):
super().__init__(name, employee_id)
self.monthly_salary = monthly_salary
def calculate_salary(self):
return self.monthly_salary * 12
def get_role(self):
return "Full-time Employee"
class PartTimeEmployee(Employee):
def __init__(self, name, employee_id, hourly_rate, hours_per_week):
super().__init__(name, employee_id)
self.hourly_rate = hourly_rate
self.hours_per_week = hours_per_week
def calculate_salary(self):
return self.hourly_rate * self.hours_per_week * 52
def get_role(self):
return "Part-time Employee"
class Contractor(Employee):
def __init__(self, name, employee_id, project_rate, projects_completed):
super().__init__(name, employee_id)
self.project_rate = project_rate
self.projects_completed = projects_completed
def calculate_salary(self):
return self.project_rate * self.projects_completed
def get_role(self):
return "Contractor"
# Usage
employees = [
FullTimeEmployee("David Wilson", "FT001", 6000),
PartTimeEmployee("Eva Garcia", "PT001", 25, 20),
Contractor("Frank Miller", "C001", 5000, 3)
]
Problem: Create a shape hierarchy where different shapes can calculate their area and
perimeter using polymorphism.
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def __str__(self):
return f"{self.__class__.__name__} - Area: {self.area():.2f}, Perimeter: {self.perimeter():.2f}"
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
def perimeter(self):
return 2 * math.pi * self.radius
class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * (self.length + self.width)
class Triangle(Shape):
def __init__(self, side1, side2, side3):
self.side1 = side1
self.side2 = side2
self.side3 = side3
def area(self):
# Using Heron's formula
s = self.perimeter() / 2
return math.sqrt(s * (s - self.side1) * (s - self.side2) * (s - self.side3))
def perimeter(self):
return self.side1 + self.side2 + self.side3
# Usage
shapes = [
Circle(5),
Rectangle(4, 6),
Triangle(3, 4, 5)
]
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
def perimeter(self):
return 2 * math.pi * self.radius
class Square:
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
def perimeter(self):
return 4 * self.side
def print_shape_info(shape):
"""This function works with any object that has area() and perimeter() methods"""
print(f"{shape.__class__.__name__}: Area = {shape.area():.2f}, Perimeter = {shape.perimeter():.2f}")
# Usage
circle = Circle(7)
square = Square(5)
class Calculator:
def add(self, *args):
if len(args) == 2 and all(isinstance(arg, (int, float)) for arg in args):
return args[0] + args[1]
elif len(args) == 2 and all(isinstance(arg, str) for arg in args):
return args[0] + " " + args[1]
elif len(args) == 3:
return sum(args)
else:
raise ValueError("Unsupported operation")
# Usage
calc = Calculator()
print(calc.add(5, 3)) # Output: 8
print(calc.add("Hello", "World")) # Output: Hello World
print(calc.add(1, 2, 3)) # Output: 6
print(calc.multiply(4, 5)) # Output: 20
print(calc.multiply("Hi", 3)) # Output: HiHiHi
Encapsulation
Problem: Create a user account system with proper encapsulation, including private
attributes and validation.
class UserAccount:
def __init__(self, username, email, password):
self._username = username
self._email = email
self._set_password(password)
self._is_active = True
self._login_attempts = 0
if password == self._password:
self._login_attempts = 0
return True
else:
self._login_attempts += 1
if self._login_attempts >= 3:
self._is_active = False
print("Account locked due to too many failed attempts")
return False
@property
def email(self):
return self._email
@property
def is_active(self):
return self._is_active
# Usage
user = UserAccount("john_doe", "[email protected]", "secure123")
print(user.authenticate("wrong_pass")) # Output: False
print(user.authenticate("wrong_pass2")) # Output: False
print(user.authenticate("wrong_pass3")) # Output: False, then "Account locked due to too many failed attempts"
print(user.is_active) # Output: False
class UserProfile:
def __init__(self, username, email, age):
self._username = username
self._email = email
self._age = age
@property
def username(self):
return self._username
@username.setter
def username(self, value):
if not value or not isinstance(value, str):
raise ValueError("Username must be a non-empty string")
if len(value) < 3:
raise ValueError("Username must be at least 3 characters long")
self._username = value
@property
def email(self):
return self._email
@email.setter
def email(self, value):
if "@" not in value or "." not in value:
raise ValueError("Invalid email format")
self._email = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int) or value < 0 or value > 120:
raise ValueError("Age must be a positive integer between 0 and 120")
self._age = value
def __str__(self):
return f"User: {self.username}, Email: {self.email}, Age: {self.age}"
# Usage
profile = UserProfile("jane_doe", "[email protected]", 25)
print(profile) # Output: User: jane_doe, Email: [email protected], Age: 25
try:
profile.username = "ab" # Too short
except ValueError as e:
print(e) # Output: Username must be at least 3 characters long
try:
profile.email = "invalid-email" # Invalid format
except ValueError as e:
print(e) # Output: Invalid email format
profile.age = 30
print(profile.age) # Output: 30
import hashlib
import os
class SecureUser:
def __init__(self, username, password):
self.username = username
self._salt = os.urandom(32) # Generate a random salt
self._hashed_password = self._hash_password(password, self._salt)
self._is_locked = False
self._failed_attempts = 0
@property
def is_locked(self):
return self._is_locked
# Usage
user = SecureUser("alice", "mySecurePassword123")
print(user.verify_password("wrong_pass")) # Output: False
print(user.verify_password("mySecurePassword123")) # Output: True
user.change_password("mySecurePassword123", "newSecurePassword456")
print(user.verify_password("newSecurePassword456")) # Output: True
Abstraction
Problem: Create an abstract database connection class with concrete implementations for
different database types.
class DatabaseConnection(ABC):
@abstractmethod
def connect(self):
pass
@abstractmethod
def disconnect(self):
pass
@abstractmethod
def execute_query(self, query):
pass
@abstractmethod
def commit(self):
pass
@abstractmethod
def rollback(self):
pass
class MySQLConnection(DatabaseConnection):
def __init__(self, host, user, password, database):
self.host = host
self.user = user
self.password = password
self.database = database
self.connection = None
def connect(self):
# Simulate MySQL connection
print(f"Connecting to MySQL database {self.database} on {self.host}")
self.connection = f"mysql_connection_{self.database}"
return True
def disconnect(self):
if self.connection:
print(f"Disconnecting from MySQL database {self.database}")
self.connection = None
def commit(self):
print("Committing transaction in MySQL")
def rollback(self):
print("Rolling back transaction in MySQL")
class PostgreSQLConnection(DatabaseConnection):
def __init__(self, host, user, password, database):
self.host = host
self.user = user
self.password = password
self.database = database
self.connection = None
def connect(self):
# Simulate PostgreSQL connection
print(f"Connecting to PostgreSQL database {self.database} on {self.host}")
self.connection = f"postgresql_connection_{self.database}"
return True
def disconnect(self):
if self.connection:
print(f"Disconnecting from PostgreSQL database {self.database}")
self.connection = None
def commit(self):
print("Committing transaction in PostgreSQL")
def rollback(self):
print("Rolling back transaction in PostgreSQL")
# Usage
def database_operations(db_connection):
db_connection.connect()
result = db_connection.execute_query("SELECT * FROM users")
print(f"Result: {result}")
db_connection.commit()
db_connection.disconnect()
database_operations(mysql_db)
database_operations(postgresql_db)
class PaymentProcessor(ABC):
@abstractmethod
def process_payment(self, amount):
pass
@abstractmethod
def refund_payment(self, amount, transaction_id):
pass
class CreditCardProcessor(PaymentProcessor):
def __init__(self, card_number, expiry_date, cvv):
self.card_number = card_number
self.expiry_date = expiry_date
self.cvv = cvv
class PayPalProcessor(PaymentProcessor):
def __init__(self, email):
self.email = email
class CryptoProcessor(PaymentProcessor):
def __init__(self, wallet_address):
self.wallet_address = wallet_address
# Usage
def process_order(payment_processor, amount):
transaction_id = payment_processor.process_payment(amount)
print(f"Order processed with transaction: {transaction_id}")
return transaction_id
process_order(credit_card, 100)
process_order(paypal, 75)
process_order(crypto, 200)
Problem: Create a Vector class that supports mathematical operations through operator
overloading.
Method 1: Basic vector operations
class Vector:
def __init__(self, *components):
self.components = list(components)
def __repr__(self):
return f"Vector({', '.join(map(str, self.components))})"
def __abs__(self):
return sum(a ** 2 for a in self.components) ** 0.5
# Usage
v1 = Vector(1, 2, 3)
v2 = Vector(4, 5, 6)
class Matrix:
def __init__(self, rows, cols, data=None):
self.rows = rows
self.cols = cols
if data is None:
self.data = [[0] * cols for _ in range(rows)]
else:
if len(data) != rows or any(len(row) != cols for row in data):
raise ValueError("Invalid data dimensions")
self.data = data
def __repr__(self):
return "Matrix(\n" + "\n".join(" " + str(row) for row in self.data) + "\n)"
def transpose(self):
result = Matrix(self.cols, self.rows)
for i in range(self.rows):
for j in range(self.cols):
result.data[j][i] = self.data[i][j]
return result
# Usage
m1 = Matrix(2, 3, [[1, 2, 3], [4, 5, 6]])
m2 = Matrix(2, 3, [[7, 8, 9], [10, 11, 12]])
m3 = Matrix(3, 2, [[1, 2], [3, 4], [5, 6]])
print("Matrix 1:")
print(m1)
print("Matrix 2:")
print(m2)
print("Matrix 1 + Matrix 2:")
print(m1 + m2)
print("Matrix 1 * 3:")
print(m1 * 3)
print("Matrix 1 * Matrix 3:")
print(m1 * m3)
print("Transpose of Matrix 1:")
print(m1.transpose())
Problem: Implement a singleton database connection class that ensures only one instance
exists.
def _connect(self):
print(f"Connecting to database: {self.connection_string}")
return f"connection_to_{self.connection_string}"
def __str__(self):
return f"DatabaseConnection({self.connection_string})"
# Usage
db1 = DatabaseConnection("mysql://localhost:3306/mydb")
db2 = DatabaseConnection("postgresql://localhost:5432/mydb")
class Logger(metaclass=SingletonMeta):
def __init__(self, log_file="app.log"):
self.log_file = log_file
self._open_log_file()
def _open_log_file(self):
print(f"Opening log file: {self.log_file}")
self.file = open(self.log_file, "a")
def __del__(self):
if hasattr(self, 'file'):
self.file.close()
print("Log file closed")
# Usage
logger1 = Logger("application.log")
logger2 = Logger("different.log") # This will use the same instance
return get_instance
@singleton
class Configuration:
def __init__(self, config_file="config.ini"):
self.config_file = config_file
self.settings = self._load_config()
def _load_config(self):
print(f"Loading configuration from {self.config_file}")
# Simulate loading config
return {"database": "localhost", "port": 8080, "debug": True}
# Usage
config1 = Configuration()
config2 = Configuration("different.ini") # Same instance
class Document(ABC):
@abstractmethod
def create(self):
pass
@abstractmethod
def save(self):
pass
class PDFDocument(Document):
def create(self):
return "Creating PDF document"
def save(self):
return "Saving PDF document"
class WordDocument(Document):
def create(self):
return "Creating Word document"
def save(self):
return "Saving Word document"
class ExcelDocument(Document):
def create(self):
return "Creating Excel document"
def save(self):
return "Saving Excel document"
class DocumentFactory:
@staticmethod
def create_document(doc_type):
if doc_type == "pdf":
return PDFDocument()
elif doc_type == "word":
return WordDocument()
elif doc_type == "excel":
return ExcelDocument()
else:
raise ValueError(f"Unknown document type: {doc_type}")
# Usage
factory = DocumentFactory()
documents = [
factory.create_document("pdf"),
factory.create_document("word"),
factory.create_document("excel")
]
class Document(ABC):
@abstractmethod
def create(self):
pass
@abstractmethod
def save(self):
pass
class PDFDocument(Document):
def create(self):
return "Creating PDF document"
def save(self):
return "Saving PDF document"
class WordDocument(Document):
def create(self):
return "Creating Word document"
def save(self):
return "Saving Word document"
class DocumentFactory:
_creators = {}
@classmethod
def register_document(cls, doc_type, creator):
cls._creators[doc_type] = creator
@classmethod
def create_document(cls, doc_type, *args, **kwargs):
creator = cls._creators.get(doc_type)
if not creator:
raise ValueError(f"Unknown document type: {doc_type}")
return creator(*args, **kwargs)
# Usage
pdf_doc = DocumentFactory.create_document("pdf")
word_doc = DocumentFactory.create_document("word")
# Abstract products
class Button(ABC):
@abstractmethod
def render(self):
pass
class Checkbox(ABC):
@abstractmethod
def render(self):
pass
class WindowsCheckbox(Checkbox):
def render(self):
return "Rendering Windows checkbox"
class MacCheckbox(Checkbox):
def render(self):
return "Rendering Mac checkbox"
# Abstract factory
class GUIFactory(ABC):
@abstractmethod
def create_button(self):
pass
@abstractmethod
def create_checkbox(self):
pass
# Concrete factories
class WindowsFactory(GUIFactory):
def create_button(self):
return WindowsButton()
def create_checkbox(self):
return WindowsCheckbox()
class MacFactory(GUIFactory):
def create_button(self):
return MacButton()
def create_checkbox(self):
return MacCheckbox()
# Client code
def create_ui(factory):
button = factory.create_button()
checkbox = factory.create_checkbox()
print(button.render())
print(checkbox.render())
# Usage
windows_factory = WindowsFactory()
mac_factory = MacFactory()
print("Windows UI:")
create_ui(windows_factory)
print("\nMac UI:")
create_ui(mac_factory)
Design Patterns
class NewsPublisher:
def __init__(self):
self._subscribers = []
self._latest_news = None
def notify_subscribers(self):
for subscriber in self._subscribers:
subscriber.update(self._latest_news)
def get_latest_news(self):
return self._latest_news
class Subscriber:
def __init__(self, name):
self.name = name
self.received_news = []
def update(self, news):
self.received_news.append(news)
print(f"{self.name} received news: {news}")
def get_news_history(self):
return self.received_news
# Usage
publisher = NewsPublisher()
subscriber1 = Subscriber("Alice")
subscriber2 = Subscriber("Bob")
subscriber3 = Subscriber("Charlie")
publisher.attach(subscriber1)
publisher.attach(subscriber2)
publisher.attach(subscriber3)
publisher.add_news("Update: 4.0 release delayed")
# Output:
# Alice received news: Update: 4.0 release delayed
# Bob received news: Update: 4.0 release delayed
# Charlie received news: Update: 4.0 release delayed
publisher.detach(subscriber2)
publisher.add_news("Final: 3.12 is the latest")
# Output:
# Alice received news: Final: 3.12 is the latest
# Charlie received news: Final: 3.12 is the latest
class Observer(ABC):
@abstractmethod
def update(self, subject):
pass
class Subject(ABC):
def __init__(self):
self._observers = []
def notify(self):
for observer in self._observers:
observer.update(self)
class WeatherStation(Subject):
def __init__(self):
super().__init__()
self._temperature = 0
self._humidity = 0
self._pressure = 0
@property
def temperature(self):
return self._temperature
@property
def humidity(self):
return self._humidity
@property
def pressure(self):
return self._pressure
def __str__(self):
return f"Weather: {self.temperature}°C, {self.humidity}% humidity, {self.pressure} hPa"
class DisplayDevice(Observer):
def __init__(self, name):
self.name = name
self.last_update = None
def get_last_update(self):
return self.last_update
# Usage
weather_station = WeatherStation()
phone_display = DisplayDevice("Phone")
tv_display = DisplayDevice("TV")
tablet_display = DisplayDevice("Tablet")
weather_station.attach(phone_display)
weather_station.attach(tv_display)
Problem: Design an e-commerce system with products, shopping cart, and orders.
class Product:
def __init__(self, product_id: str, name: str, price: float, description: str = "", stock: int = 0):
self.product_id = product_id
self.name = name
self.price = price
self.description = description
self.stock = stock
def __str__(self):
return f"{self.name} - ${self.price:.2f} (Stock: {self.stock})"
class CartItem:
def __init__(self, product: Product, quantity: int = 1):
self.product = product
self.quantity = quantity
def get_total_price(self):
return self.product.price * self.quantity
def __str__(self):
return f"{self.product.name} x {self.quantity} = ${self.get_total_price():.2f}"
class ShoppingCart:
def __init__(self):
self.items: Dict[str, CartItem] = {}
def get_total(self):
return sum(item.get_total_price() for item in self.items.values())
def clear(self):
self.items.clear()
def __str__(self):
if not self.items:
return "Cart is empty"
class Order:
def __init__(self, order_id: str, cart: ShoppingCart, customer_name: str, shipping_address: str):
self.order_id = order_id
self.customer_name = customer_name
self.shipping_address = shipping_address
self.order_date = datetime.now()
self.items = cart.items.copy()
self.total_amount = cart.get_total()
self.status = "Pending"
def process_order(self):
# Check stock availability
for item in self.items.values():
if item.quantity > item.product.stock:
raise ValueError(f"Insufficient stock for {item.product.name}")
# Update stock
for item in self.items.values():
item.product.update_stock(-item.quantity)
self.status = "Processed"
return True
def cancel_order(self):
if self.status == "Cancelled":
return False
# Restore stock
for item in self.items.values():
item.product.update_stock(item.quantity)
self.status = "Cancelled"
return True
def __str__(self):
items_str = "\n".join(f" {item}" for item in self.items.values())
return (f"Order #{self.order_id}\n"
f"Customer: {self.customer_name}\n"
f"Date: {self.order_date.strftime('%Y-%m-%d %H:%M')}\n"
f"Status: {self.status}\n"
f"Items:\n{items_str}\n"
f"Total: ${self.total_amount:.2f}")
# Usage
# Create products
laptop = Product("P001", "Laptop", 999.99, "High-performance laptop", 10)
mouse = Product("P002", "Mouse", 25.50, "Wireless mouse", 50)
keyboard = Product("P003", "Keyboard", 75.00, "Mechanical keyboard", 25)
print("Shopping Cart:")
print(cart)
# Create order
order = Order("ORD001", cart, "John Doe", "123 Main St, Anytown")
print("\nOrder Details:")
print(order)
# Process order
try:
order.process_order()
print(f"\nOrder processed successfully. New status: {order.status}")
print(f"Laptop stock after order: {laptop.stock}")
except ValueError as e:
print(f"Error processing order: {e}")
30. Decorators
def welcome(fx):
def mfx(*args, **kwargs):
print("Before function execution")
result = fx(*args, **kwargs)
print("Thanks for using the function")
return result
return mfx
hello()
# Output:
# Before function execution
# Hello!
# Thanks for using the function
add(1, 3)
# Output:
# Before function execution
#4
# Thanks for using the function
class Calculator:
def __init__(self, func):
self.function = func
@Calculator
def add(a, b):
return a + b
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
# Output:
# Hello!
# Hello!
# Hello!
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""Getter method for radius"""
return self._radius
@radius.setter
def radius(self, value):
"""Setter method for radius"""
if value < 0:
raise ValueError("Value cannot be negative")
self._radius = value
@property
def area(self):
"""Method to calculate the area"""
return 3.14 * self._radius ** 2
obj = Circle(radius=5)
print(f"radius: {obj.radius}") # Output: radius: 5
print(f"area: {obj.area}") # Output: area: 78.5
31. Iterators
class CountDown:
def __init__(self, start):
self.current = start
self.end = 0
def __iter__(self):
return self
def __next__(self):
if self.current <= self.end:
raise StopIteration
else:
self.current -= 1
return self.current + 1
class EvenNumbers:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.max:
raise StopIteration
result = self.current
self.current += 2
return result
32. Generators
def countdown(n):
while n > 0:
yield n
n -= 1
for i in countdown(5):
print(i, end=" ")
# Output: 5 4 3 2 1
fib = fibonacci()
for _ in range(10):
print(next(fib), end=" ")
# Output: 0 1 1 2 3 5 8 13 21 34
try:
a = int(input("Enter a number: "))
b = int(input("Enter another number: "))
print(a / b)
except ZeroDivisionError:
print("Division by zero is not allowed")
except ValueError:
print("Please enter valid integers")
except Exception as e:
print(f"An error occurred: {e}")
else:
print("Division successful")
finally:
print("This will always execute")
try:
# Some code that might raise exceptions
result = 10 / int(input("Enter a number: "))
except (ZeroDivisionError, ValueError):
print("Invalid input or division by zero")
Method 3: Custom exceptions
class NegativeNumberError(Exception):
pass
def check_positive(number):
if number < 0:
raise NegativeNumberError("Number cannot be negative")
return number
try:
num = int(input("Enter a positive number: "))
check_positive(num)
print(f"You entered: {num}")
except NegativeNumberError as e:
print(e)
except ValueError:
print("Please enter a valid integer")
# Appending to a file
with open('output.txt', 'a') as file:
file.write("This line is appended\n")
import csv
# Writing to CSV
with open('data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Name', 'Age', 'City'])
writer.writerow(['John', '30', 'New York'])
writer.writerow(['Jane', '25', 'London'])
import re
# Split at pattern
result = re.split('\s', text)
print(result) # Output: ['The', 'rain', 'in', 'Spain', 'falls', 'mainly', 'in', 'the', 'plain.']
import re
# Replace pattern
result = re.sub('\s', '-', text)
print(result) # Output: The-rain-in-Spain-falls-mainly-in-the-plain.
import re
class Stack:
def __init__(self):
self.items = []
def pop(self):
if not self.is_empty():
return self.items.pop()
return None
def peek(self):
if not self.is_empty():
return self.items[-1]
return None
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop()) # Output: 3
print(stack.peek()) # Output: 2
class Queue:
def __init__(self):
self.items = deque()
def dequeue(self):
if not self.is_empty():
return self.items.popleft()
return None
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.dequeue()) # Output: 1
print(queue.dequeue()) # Output: 2
class LinkedList:
def __init__(self):
self.head = None
def display(self):
current = self.head
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
ll.display() # Output: 1 -> 2 -> 3 -> None
import threading
import time
def print_numbers():
for i in range(1, 6):
time.sleep(1)
print(i)
def print_letters():
for letter in 'ABCDE':
time.sleep(1.5)
print(letter)
# Create threads
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
# Start threads
t1.start()
t2.start()
print("Done!")
import multiprocessing
import time
def square_numbers():
for i in range(5):
time.sleep(1)
print(f"Square: {i*i}")
def cube_numbers():
for i in range(5):
time.sleep(1.5)
print(f"Cube: {i*i*i}")
# Create processes
p1 = multiprocessing.Process(target=square_numbers)
p2 = multiprocessing.Process(target=cube_numbers)
# Start processes
p1.start()
p2.start()
print("Done!")
def task(n):
time.sleep(1)
return n * n
# Create table
cursor.execute('''CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')
# Insert data
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('John', 30))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Jane', 25))
# Commit changes
conn.commit()
# Query data
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:
print(row)
# Close connection
conn.close()
import sqlite3
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
# Query users
users = session.query(User).all()
for user in users:
print(user.id, user.name, user.age)
import requests
from bs4 import BeautifulSoup
url = 'https://example.com'
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
class ExampleSpider(scrapy.Spider):
name = 'example'
start_urls = ['https://example.com']
yield {
'title': title,
'paragraphs': paragraphs
}
driver = webdriver.Chrome()
driver.get('https://example.com')
# Find elements
title = driver.find_element(By.TAG_NAME, 'h1').text
paragraphs = driver.find_elements(By.TAG_NAME, 'p')
for p in paragraphs:
print(p.text)
driver.quit()
import requests
# GET request
response = requests.get('https://api.github.com/users/octocat')
if response.status_code == 200:
data = response.json()
print(data['login'], data['id'])
# POST request
payload = {'key1': 'value1', 'key2': 'value2'}
response = requests.post('https://httpbin.org/post', data=payload)
print(response.json())
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
'https://api.github.com/user',
auth=HTTPBasicAuth('username', 'password')
)
print(response.json())
import requests
headers = {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}
response = requests.get('https://api.github.com/user', headers=headers)
print(response.json())
import pandas as pd
# Create DataFrame
data = {
'Name': ['John', 'Jane', 'Bob', 'Alice'],
'Age': [25, 30, 35, 40],
'City': ['New York', 'London', 'Paris', 'Tokyo']
}
df = pd.DataFrame(data)
print(df)
# Output:
# Name Age City
# 0 John 25 New York
# 1 Jane 30 London
# 2 Bob 35 Paris
# 3 Alice 40 Tokyo
# Basic operations
print(df.head(2)) # First 2 rows
print(df.describe()) # Statistical summary
print(df['Age'].mean()) # Average age
import pandas as pd
# Filter data
filtered_df = df[df['Age'] > 30]
print(filtered_df)
# Group by operation
grouped = df.groupby('City')['Age'].mean()
print(grouped)
import pandas as pd
import numpy as np
# Line plot
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
# Bar chart
categories = ['A', 'B', 'C', 'D']
values = [10, 20, 15, 25]
plt.bar(categories, values)
plt.show()
# Create visualization
sns.scatterplot(x='total_bill', y='tip', data=tips, hue='time')
plt.show()
# Box plot
sns.boxplot(x='day', y='total_bill', data=tips)
plt.show()
import plotly.express as px
# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Create and train model
model = LinearRegression()
model.fit(X_train, y_train)
# Make predictions
y_pred = model.predict(X_test)
# Evaluate model
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Coefficients: {model.coef_}")
print(f"Intercept: {model.intercept_}")
# Load data
iris = load_iris()
X, y = iris.data, iris.target
# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Make predictions
y_pred = model.predict(X_test)
# Evaluate model
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")
Method 3: Clustering with K-Means
# Apply K-Means
kmeans = KMeans(n_clusters=4)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)
# Visualize clusters
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75)
plt.show()
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
import string
text = "This is a sample sentence, showing off the stop words filtration."
# Tokenization
tokens = word_tokenize(text.lower())
print("Tokens:", tokens)
# Remove punctuation
tokens = [word for word in tokens if word not in string.punctuation]
print("Without punctuation:", tokens)
# Remove stopwords
stop_words = set(stopwords.words('english'))
filtered_tokens = [word for word in tokens if word not in stop_words]
print("Without stopwords:", filtered_tokens)
# Stemming
stemmer = PorterStemmer()
stemmed_tokens = [stemmer.stem(word) for word in filtered_tokens]
print("Stemmed:", stemmed_tokens)
print(f"Sentiment: {blob.sentiment}")
# Output: Sentiment: Sentiment(polarity=0.8, subjectivity=0.9)
# Correct spelling
text = "I havv goood speling!"
blob = TextBlob(text)
corrected = blob.correct()
print(f"Corrected: {corrected}")
# Output: Corrected: I have good spelling!
documents = [
"This is the first document.",
"This document is the second document.",
"And this is the third one.",
"Is this the first document?"
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(documents)
import tensorflow as tf
from tensorflow import keras
import numpy as np
# Build model
model = keras.Sequential([
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
# Compile model
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Train model
history = model.fit(X_train, y_train, epochs=5, validation_split=0.2)
# Evaluate model
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"Test accuracy: {test_acc}")
import tensorflow as tf
from tensorflow import keras
import tensorflow as tf
from tensorflow import keras
# Compile model
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
print(model.summary())
app = Flask(__name__)
@app.route('/')
def home():
return "Hello, World!"
@app.route('/greet/<name>')
def greet(name):
return f"Hello, {name}!"
if __name__ == '__main__':
app.run(debug=True)
app = Flask(__name__)
# Sample data
books = [
{'id': 1, 'title': 'Book 1', 'author': 'Author 1'},
{'id': 2, 'title': 'Book 2', 'author': 'Author 2'}
]
@app.route('/books', methods=['GET'])
def get_books():
return jsonify(books)
@app.route('/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
book = next((b for b in books if b['id'] == book_id), None)
if book:
return jsonify(book)
return jsonify({'error': 'Book not found'}), 404
@app.route('/books', methods=['POST'])
def add_book():
new_book = {
'id': len(books) + 1,
'title': request.json['title'],
'author': request.json['author']
}
books.append(new_book)
return jsonify(new_book), 201
if __name__ == '__main__':
app.run(debug=True)
app = Flask(__name__)
@app.route('/')
def index():
users = [
{'name': 'John', 'age': 25},
{'name': 'Jane', 'age': 30},
{'name': 'Bob', 'age': 35}
]
return render_template('index.html', users=users)
if __name__ == '__main__':
app.run(debug=True)
Templates would be in a templates folder:
index.html:
<!DOCTYPE html>
<html>
<body>
<h1>Users</h1>
<ul>
{% endfor %}
</ul>
</body>
</html>
text
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_subtract():
assert subtract(5, 3) == 2
assert subtract(0, 5) == -5
assert subtract(10, 10) == 0
@pytest.mark.parametrize("a,b,expected", [
(2, 3, 6),
(0, 5, 0),
(-2, 4, -8),
(2.5, 4, 10.0)
])
def test_multiply(a, b, expected):
assert multiply(a, b) == expected
import pytest
from unittest.mock import Mock
@pytest.fixture
def mock_database():
mock = Mock()
mock.get_user.return_value = {'name': 'John', 'age': 30}
return mock
def test_get_user(mock_database):
user = mock_database.get_user(1)
assert user['name'] == 'John'
assert user['age'] == 30
mock_database.get_user.assert_called_once_with(1)
import sys
# Without caching
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
start = time.time()
result = fibonacci(35)
end = time.time()
print(f"Without cache: {end - start:.4f} seconds")
# With caching
@lru_cache(maxsize=None)
def fibonacci_cached(n):
if n < 2:
return n
return fibonacci_cached(n-1) + fibonacci_cached(n-2)
start = time.time()
result = fibonacci_cached(35)
end = time.time()
print(f"With cache: {end - start:.4f} seconds")
# Specific date
d = date(2023, 12, 25)
print(f"Christmas: {d}")
# Time operations
tomorrow = now + timedelta(days=1)
print(f"Tomorrow: {tomorrow}")
# Formatting
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"Formatted: {formatted}")
# UTC time
utc_now = datetime.now(timezone.utc)
print(f"UTC time: {utc_now}")
# Relative dates
now = datetime.now()
next_month = now + relativedelta(months=1)
print(f"Next month: {next_month}")
# Last day of month
last_day = now + relativedelta(day=31)
print(f"Last day of month: {last_day}")
Method 1: Metaclasses
class Meta(type):
def __new__(cls, name, bases, dct):
# Add a class attribute
dct['created_by'] = 'Meta'
class MyClass(metaclass=Meta):
def my_method(self):
return "Hello from method"
obj = MyClass()
print(obj.MY_METHOD()) # Output: Hello from method
print(MyClass.created_by) # Output: Meta
@contextmanager
def open_file(filename, mode):
try:
f = open(filename, mode)
yield f
finally:
f.close()
Method 3: Descriptors
class PositiveNumber:
def __set_name__(self, owner, name):
self.name = name
class Circle:
radius = PositiveNumber()
@property
def area(self):
return 3.14 * self.radius ** 2
try:
c = Circle(5)
print(f"Radius: {c.radius}, Area: {c.area}")
Company-Specific Questions
class Node:
def __init__(self, data):
self.data = data
self.next = None
def reverse_linked_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
# Example usage
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
reversed_head = reverse_linked_list(head)
while reversed_head:
print(reversed_head.data, end=" ")
reversed_head = reversed_head.next
# Output: 4 3 2 1
def longest_substring(s):
char_set = set()
left = 0
max_length = 0
return max_length
print(longest_substring("abcabcbb")) # Output: 3
print(longest_substring("bbbbb")) # Output: 1
print(longest_substring("pwwkew")) # Output: 3
Facebook Interview Questions
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def level_order_traversal(root):
if not root:
return []
result = []
queue = [root]
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
node = queue.pop(0)
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result
# Example usage
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7)
def product_except_self(nums):
n = len(nums)
result = [1] * n
return result
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.cache = OrderedDict()
# Example usage
cache = LRUCache(2)
cache.put(1, 1)
cache.put(2, 2)
print(cache.get(1)) # Output: 1
cache.put(3, 3) # Evicts key 2
print(cache.get(2)) # Output: -1
def reverse_words(s):
words = s.split()
return ' '.join(words[::-1])
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def is_valid_bst(root):
def validate(node, low=-float('inf'), high=float('inf')):
if not node:
return True
if node.val <= low or node.val >= high:
return False
return (validate(node.left, low, node.val) and
validate(node.right, node.val, high))
return validate(root)
# Example usage
root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(3)
print(is_valid_bst(root)) # Output: True
root2 = TreeNode(5)
root2.left = TreeNode(1)
root2.right = TreeNode(4)
root2.right.left = TreeNode(3)
root2.right.right = TreeNode(6)
print(is_valid_bst(root2)) # Output: False
1. Merge intervals
def merge_intervals(intervals):
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
return merged
print(merge_intervals([[1,3],[2,6],[8,10],[15,18]]))
# Output: [[1,6],[8,10],[15,18]]
def pop(self):
if self.stack:
val = self.stack.pop()
if val == self.min_stack[-1]:
self.min_stack.pop()
return val
return None
def top(self):
if self.stack:
return self.stack[-1]
return None
def getMin(self):
if self.min_stack:
return self.min_stack[-1]
return None
# Example usage
min_stack = MinStack()
min_stack.push(-2)
min_stack.push(0)
min_stack.push(-3)
print(min_stack.getMin()) # Output: -3
min_stack.pop()
print(min_stack.top()) # Output: 0
print(min_stack.getMin()) # Output: -2