Uploaded by ankushitguy

Python Tutorials

advertisement
Sure, I can provide a comprehensive tutorial on programming. We'll cover the basics,
intermediate topics, advanced concepts, and architectural aspects. Here's a structured outline:
1. Introduction to
o Installing
o Writing and running scripts
o Basic syntax
2. Basic Concepts
o Variables and Data Types
o Operators
o Control Flow (if, for, while)
o Functions
o Exception Handling
3. Data Structures
o Lists
o Tuples
o Sets
o Dictionaries
4. Modules and Packages
o Importing modules
o Standard library overview
o Creating and using packages
5. File Handling
o Reading and writing files
o Working with CSV and JSON files
6. Object-Oriented Programming (OOP)
o Classes and objects
o Inheritance
o Polymorphism
o Encapsulation
7. Advanced Topics
o Decorators
o Generators
o Context Managers
8. Working with Databases
o SQLite
o SQLAlchemy
9. Web Development
o Flask
o Django
10. Data Science and Machine Learning
o NumPy
o Pandas
o Matplotlib
o Scikit-learn
11. Architectural Patterns
o MVC (Model-View-Controller)
o Microservices
o RESTful APIs
12. Concurrency and Parallelism
o
o
o
Threading
Multiprocessing
Asyncio
Let's start with some basics and gradually move to more advanced topics. Feel free to ask for
specific details or examples on any topic.
1. Introduction to
Installing :
1. Download the installer from the official website.
2. Run the installer and follow the instructions. Make sure to check the box to add to
your PATH.
Writing and Running Scripts:
•
•
You can write code in any text editor (e.g., VSCode, PyCharm, Sublime Text) and
save the file with a .py extension.
To run the script, open a terminal or command prompt and type script_name.py.
Basic Syntax:
# This is a comment
print("Hello, World!")
# This prints Hello, World! to the console
2. Basic Concepts
Variables and Data Types:
x = 5 # Integer
y = 3.14 # Float
name = "Alice" # String
is_active = True # Boolean
print(x, y, name, is_active)
Operators:
# Arithmetic Operators
a = 10
b = 3
print(a + b) # Addition
print(a - b) # Subtraction
print(a * b) # Multiplication
print(a / b) # Division
print(a % b) # Modulus
print(a ** b) # Exponentiation
print(a // b)
# Floor Division
# Comparison Operators
print(a == b) # Equal to
print(a != b) # Not equal to
print(a > b) # Greater than
print(a < b) # Less than
print(a >= b) # Greater than or equal to
print(a <= b) # Less than or equal to
# Logical Operators
print(a > 5 and b < 5) # Logical AND
print(a > 5 or b < 5) # Logical OR
print(not(a > 5)) # Logical NOT
Control Flow:
# If-Else
age = 18
if age >= 18:
print("You are an adult.")
else:
print("You are a minor.")
# For Loop
for i in range(5):
print(i)
# While Loop
count = 0
while count < 5:
print(count)
count += 1
Functions:
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))
Exception Handling:
try:
x = 1 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
finally:
print("This will always execute.")
3. Data Structures
Lists:
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # Accessing elements
fruits.append("orange") # Adding elements
print(fruits)
fruits.remove("banana") # Removing elements
print(fruits)
Tuples:
coordinates = (10, 20)
print(coordinates[0]) # Accessing elements
# Tuples are immutable, so elements cannot be added or removed
Sets:
unique_numbers = {1, 2, 3, 3, 4}
print(unique_numbers) # Duplicates are removed
unique_numbers.add(5) # Adding elements
print(unique_numbers)
unique_numbers.remove(3) # Removing elements
print(unique_numbers)
Dictionaries:
student = {"name": "Alice", "age": 20, "courses": ["Math", "Science"]}
print(student["name"]) # Accessing elements
student["age"] = 21 # Modifying elements
print(student)
student["grade"] = "A" # Adding elements
print(student)
del student["courses"] # Removing elements
print(student)
Feel free to ask for more details on any topic or for specific examples!
4o
Write more advance part of
ChatGPT
4. Modules and Packages
Importing Modules:
import math
print(math.sqrt(16))
# Using the sqrt function from the math module
You can also import specific functions from a module:
from math import sqrt
print(sqrt(16))
# No need to prefix with 'math.'
Creating and Using Packages:
1. Create a directory structure for your package:
markdown
my_package/
__init__.py
module1.py
module2.py
2. Add code to your modules:
module1.py:
def greet(name):
return f"Hello, {name}!"
module2.py:
def add(a, b):
return a + b
3. Use your package in another script:
from my_package import module1, module2
print(module1.greet("Alice"))
print(module2.add(5, 3))
5. File Handling
Reading and Writing Files:
# Writing to a file
with open('example.txt', 'w') as file:
file.write("Hello, World!\n")
# Reading from a file
with open('example.txt', 'r') as file:
content = file.read()
print(content)
Working with CSV and JSON Files:
import csv
import json
# Writing to a CSV file
data = [
["Name", "Age"],
["Alice", 30],
["Bob", 25]
]
with open('data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(data)
# Reading from a CSV file
with open('data.csv', 'r') as file:
reader = csv.reader(file)
for row in reader:
print(row)
# Writing to a JSON file
data = {"name": "Alice", "age": 30}
with open('data.json', 'w') as file:
json.dump(data, file)
# Reading from a JSON file
with open('data.json', 'r') as file:
data = json.load(file)
print(data)
6. Object-Oriented Programming (OOP)
Classes and Objects:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years
old."
person = Person("Alice", 30)
print(person.greet())
Inheritance:
class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id
def greet(self):
return f"Hello, my name is {self.name}, I am {self.age} years old,
and my student ID is {self.student_id}."
student = Student("Bob", 25, "S12345")
print(student.greet())
Polymorphism:
class Animal:
def sound(self):
raise NotImplementedError("Subclasses must implement this method")
class Dog(Animal):
def sound(self):
return "Woof"
class Cat(Animal):
def sound(self):
return "Meow"
animals = [Dog(), Cat()]
for animal in animals:
print(animal.sound())
Encapsulation:
class BankAccount:
def __init__(self, balance):
self.__balance = balance
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
else:
print("Insufficient funds")
def get_balance(self):
return self.__balance
account = BankAccount(100)
account.deposit(50)
account.withdraw(30)
print(account.get_balance())
7. Advanced Topics
Decorators:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Generators:
def countdown(n):
while n > 0:
yield n
n -= 1
for count in countdown(5):
print(count)
Context Managers:
class FileOpener:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with FileOpener('example.txt', 'w') as file:
file.write("Hello, World!")
8. Working with Databases
SQLite:
import sqlite3
# Connecting to SQLite database
conn = sqlite3.connect('example.db')
c = conn.cursor()
# Creating a table
c.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name
TEXT, age INTEGER)''')
# Inserting data
c.execute("INSERT INTO users (name, age) VALUES ('Alice', 30)")
conn.commit()
# Querying data
c.execute("SELECT * FROM users")
rows = c.fetchall()
for row in rows:
print(row)
# Closing the connection
conn.close()
SQLAlchemy:
from sqlalchemy import create_engine, Column, Integer, String, Sequence
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///example.db')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
age = Column(Integer)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# Adding a new user
new_user = User(name='Bob', age=25)
session.add(new_user)
session.commit()
# Querying users
users = session.query(User).all()
for user in users:
print(user.name, user.age)
9. Web Development
Flask:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True)
Django:
1.
2.
3.
4.
Install Django: pip install django
Create a new project: django-admin startproject myproject
Create a new app: cd myproject && manage.py startapp myapp
Define a simple view in myapp/views.py:
from django.http import HttpResponse
def home(request):
return HttpResponse("Hello, World!")
5. Configure URLs in myproject/urls.py:
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home),
]
6. Run the development server: manage.py runserver
10. Data Science and Machine Learning
NumPy:
import numpy as np
a = np.array([1, 2, 3, 4, 5])
print(a)
print(a + 2)
print(a * 2)
Pandas:
import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35]}
df = pd.DataFrame(data)
print(df)
# Reading from and writing to CSV
df.to_csv('data.csv', index=False)
df = pd.read_csv('data.csv')
print(df)
Matplotlib:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 7, 11]
plt.plot(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Simple Plot')
plt.show()
Scikit-learn:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# Loading dataset
iris = load_iris()
X, y = iris.data, iris.target
# Splitting data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42)
# Training a model
clf = RandomForestClassifier()
clf.fit(X_train, y_train)
# Making predictions
y_pred = clf.predict(X_test)
# Evaluating the model
print(accuracy_score(y_test, y_pred))
11. Architectural Patterns
MVC (Model-View-Controller):
In a typical MVC architecture, you separate your application into three main components:
•
•
•
Model: Represents the data and the business logic.
View: Represents the user interface.
Controller: Manages the communication between the model and the view.
Example in Django:
# models.py (Model)
from django.db import models
4o
write different ways we can use and interchange datatypes also mix datatypes in and make
use of iterables and generators with multiple variations of examples
ChatGPT
Sure, let's dive into how we can use, interchange, and mix different data types in , as well as
how we can make use of iterables and generators with various examples.
Interchanging and Mixing Data Types
Converting Between Data Types:
# Integer to String
num = 123
num_str = str(num)
print(num_str, type(num_str))
# Output: '123' <class 'str'>
# String to Integer
str_num = "456"
int_num = int(str_num)
print(int_num, type(int_num))
# Output: 456 <class 'int'>
# Integer to Float
int_num = 789
float_num = float(int_num)
print(float_num, type(float_num))
# Float to Integer
float_num = 10.67
int_num = int(float_num)
print(int_num, type(int_num))
# Output: 789.0 <class 'float'>
# Output: 10 <class 'int'>
Mixing Data Types:
# Mixing integers and floats
result = 10 + 3.5
print(result, type(result)) # Output: 13.5 <class 'float'>
# Mixing strings and numbers (concatenation and repetition)
num = 10
num_str = "20"
mixed_str = str(num) + num_str
print(mixed_str) # Output: '1020'
repeat_str = "Hello" * 3
print(repeat_str) # Output: 'HelloHelloHello'
# Mixing lists and other data types
mixed_list = [1, "apple", 3.14, True]
print(mixed_list) # Output: [1, 'apple', 3.14, True]
# Using different data types in a dictionary
mixed_dict = {"age": 25, "name": "Alice", "is_student": False, "grades":
[88, 92, 75]}
print(mixed_dict)
Using Iterables and Generators
Iterables:
An iterable is an object that can return its members one at a time. Examples include lists,
tuples, dictionaries, sets, and strings.
# List iteration
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Tuple iteration
coordinates = (10, 20, 30)
for coordinate in coordinates:
print(coordinate)
# Dictionary iteration
student = {"name": "Alice", "age": 20, "grade": "A"}
for key, value in student.items():
print(f"{key}: {value}")
# Set iteration
unique_numbers = {1, 2, 3, 4, 5}
for number in unique_numbers:
print(number)
# String iteration
for char in "hello":
print(char)
Generators:
Generators allow you to iterate through a sequence of values. They are written like regular
functions but use yield instead of return.
# Simple generator
def simple_generator():
yield 1
yield 2
yield 3
for value in simple_generator():
print(value)
# Generator with a loop
def countdown(n):
while n > 0:
yield n
n -= 1
for count in countdown(5):
print(count)
# Generator expression (similar to list comprehension)
squares = (x * x for x in range(10))
for square in squares:
print(square)
Combining Iterables and Generators:
# Generator that filters even numbers from a list
def even_numbers(nums):
for num in nums:
if num % 2 == 0:
yield num
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for even in even_numbers(numbers):
print(even)
# Generator that combines strings from a list
def combine_strings(strings):
for string in strings:
yield string.upper()
words = ["hello", "world", ""]
for word in combine_strings(words):
print(word)
Advanced Generator Usage:
# Generator with multiple yields
def alternating_generator():
yield "odd"
yield "even"
yield "odd"
for value in alternating_generator():
print(value)
# Generator that produces an infinite sequence (use with caution)
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# Limit the output to avoid an infinite loop
for i, value in enumerate(infinite_sequence()):
if i >= 10:
break
print(value)
Chaining Generators:
You can also chain generators together to create more complex sequences:
def first_generator():
yield from range(3)
# This will yield 0, 1, 2
def second_generator():
yield from "abc" # This will yield 'a', 'b', 'c'
def combined_generator():
yield from first_generator()
yield from second_generator()
for value in combined_generator():
print(value)
By mixing and matching data types, iterables, and generators, you can create powerful and
flexible programs that efficiently handle a variety of tasks and data processing needs.
Testing code for different data types and multiple inputs can be achieved using various
methods, including built-in assertions, unit tests, and error handling. Here are some examples
demonstrating these concepts.
Using Built-in Assertions
Built-in assertions allow you to quickly check if your code behaves as expected.
# Function to test
def add(a, b):
return a + b
# Assertions
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(2.5, 0.5) == 3.0
assert add("hello", " world") == "hello world"
print("All assertions passed!")
Using Unit Tests
's unittest module provides a framework for writing and running tests.
import unittest
# Function to test
def multiply(a, b):
return a * b
class TestMathFunctions(unittest.TestCase):
def test_multiply_integers(self):
self.assertEqual(multiply(2, 3), 6)
def test_multiply_floats(self):
self.assertAlmostEqual(multiply(2.5, 0.5), 1.25)
def test_multiply_strings(self):
self.assertEqual(multiply("hello", 3), "hellohellohello")
def test_multiply_mixed(self):
with self.assertRaises(TypeError):
multiply(2, "three")
if __name__ == "__main__":
unittest.main()
Handling Multiple Inputs
You can use parameterized tests to handle multiple inputs.
import unittest
from parameterized import parameterized
# Function to test
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero!")
return a / b
class TestMathFunctions(unittest.TestCase):
@parameterized.expand([
(10, 2, 5),
(9, 3, 3),
(7.5, 2.5, 3),
(5, -1, -5)
])
def test_divide(self, a, b, expected):
self.assertAlmostEqual(divide(a, b), expected)
def test_divide_by_zero(self):
with self.assertRaises(ValueError):
divide(10, 0)
if __name__ == "__main__":
unittest.main()
Error Handling
Here's an example of handling different errors and testing them.
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "Cannot divide by zero!"
except TypeError:
return "Both arguments must be numbers!"
# Testing the function
print(safe_divide(10, 2)) # Expected: 5.0
print(safe_divide(10, 0)) # Expected: "Cannot divide by zero!"
print(safe_divide(10, "a")) # Expected: "Both arguments must be numbers!"
# Using unittest to test error handling
class TestSafeDivide(unittest.TestCase):
def test_safe_divide_valid(self):
self.assertEqual(safe_divide(10, 2), 5.0)
def test_safe_divide_zero_division(self):
self.assertEqual(safe_divide(10, 0), "Cannot divide by zero!")
def test_safe_divide_type_error(self):
self.assertEqual(safe_divide(10, "a"), "Both arguments must be
numbers!")
if __name__ == "__main__":
unittest.main()
Using pytest for Simplicity
pytest is another testing framework that simplifies writing and running tests.
# save this as test_functions.py
import pytest
def subtract(a, b):
return a - b
def test_subtract_integers():
assert subtract(5, 3) == 2
def test_subtract_floats():
assert subtract(5.5, 2.5) == 3.0
def test_subtract_strings():
with pytest.raises(TypeError):
subtract("hello", "world")
# Running the tests:
# pytest test_functions.py
In the above examples, we demonstrated how to:
1. Use built-in assertions to check if a function behaves as expected.
2. Write unit tests using 's unittest module and handle multiple inputs with the
parameterized module.
3. Handle errors in functions and test them using assertions.
4. Use pytest for writing simple tests and handling exceptions.
These examples cover testing functions with different data types, handling errors, and
running the tests efficiently.
let's explore some advanced functionalities of with working examples. This will include
decorators, context managers, metaclasses, advanced usage of comprehensions, and more.
Decorators
Decorators are a powerful tool for modifying the behavior of functions or classes.
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Advanced Decorator with Arguments:
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator_repeat
@repeat(num_times=3)
def greet(name):
print(f"Hello {name}")
greet("Alice")
Context Managers
Context managers allow you to allocate and release resources precisely when you want to.
You can use the with statement for this.
class FileOpener:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with FileOpener('example.txt', 'w') as file:
file.write("Hello, World!")
Using contextlib for Context Managers:
from contextlib import contextmanager
@contextmanager
def open_file(name, mode):
f = open(name, mode)
try:
yield f
finally:
f.close()
with open_file('example.txt', 'w') as f:
f.write('Hello, World!')
Metaclasses
Metaclasses allow you to control the creation of classes.
class Meta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=Meta):
pass
# Output: Creating class MyClass
Advanced Comprehensions
Comprehensions provide a concise way to create lists, dictionaries, and sets.
List Comprehensions:
squares = [x * x for x in range(10)]
print(squares) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Dictionary Comprehensions:
squares_dict = {x: x * x for x in range(10)}
print(squares_dict) # Output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6:
36, 7: 49, 8: 64, 9: 81}
Set Comprehensions:
unique_squares = {x * x for x in range(10)}
print(unique_squares) # Output: {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
Nested Comprehensions:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Coroutines
Coroutines are used for asynchronous programming.
import asyncio
async def main():
print("Hello")
await asyncio.sleep(1)
print("World")
asyncio.run(main())
More Advanced Coroutine Example:
async def fetch_data():
print("Start fetching")
await asyncio.sleep(2)
print("Done fetching")
return {"data": 42}
async def print_numbers():
for i in range(10):
print(i)
await asyncio.sleep(0.5)
async def main():
task1 = asyncio.create_task(fetch_data())
task2 = asyncio.create_task(print_numbers())
value = await task1
print(value)
await task2
asyncio.run(main())
Advanced Usage of Generators
Generators can be used for more complex tasks like managing state and pipeline processing.
def generate_numbers():
num = 0
while True:
yield num
num += 1
gen = generate_numbers()
for _ in range(10):
print(next(gen))
Pipeline Processing with Generators:
def generator1(n):
for i in range(n):
yield i
def generator2(n):
for i in generator1(n):
yield i * 2
def generator3(n):
for i in generator2(n):
yield i + 1
for value in generator3(5):
print(value) # Output: 1, 3, 5, 7, 9
Type Hints and Annotations
Type hints help with code readability and can be checked by static type checkers like mypy.
def greeting(name: str) -> str:
return 'Hello ' + name
print(greeting("Alice"))
Using typing Module for More Complex Annotations:
from typing import List, Dict
def process_data(data: List[Dict[str, int]]) -> List[int]:
return [item['value'] for item in data]
data = [{'value': 1}, {'value': 2}, {'value': 3}]
print(process_data(data)) # Output: [1, 2, 3]
Using dataclasses
dataclasses provide a decorator and functions for automatically adding special methods to
user-defined classes.
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p1 = Point(10, 20)
print(p1) # Output: Point(x=10, y=20)
Advanced Usage of dataclasses:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
age: int
friends: List[str] = field(default_factory=list)
p = Person("Alice", 30)
print(p) # Output: Person(name='Alice', age=30, friends=[])
These examples showcase various advanced functionalities in , highlighting the language's
versatility and power in handling complex tasks and structures.
Here are 100 puzzle questions based on the advanced functionalities of , including decorators,
context managers, metaclasses, comprehensions, coroutines, generators, type hints, and
dataclasses. Each puzzle is followed by its solution.
Decorators
1. Puzzle: Create a decorator that logs the arguments and return value of a function.
def log_args_and_return(func):
# Your code here
pass
@log_args_and_return
def add(a, b):
return a + b
add(2, 3)
Solution:
def log_args_and_return(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
print(f"Arguments: {args}, {kwargs}")
print(f"Return value: {result}")
return result
return wrapper
@log_args_and_return
def add(a, b):
return a + b
add(2, 3)
2. Puzzle: Write a decorator that measures the execution time of a function.
import time
def measure_time(func):
# Your code here
pass
@measure_time
def slow_function():
time.sleep(2)
slow_function()
Solution:
import time
def measure_time(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Execution time: {end - start} seconds")
return result
return wrapper
@measure_time
def slow_function():
time.sleep(2)
slow_function()
3. Puzzle: Create a decorator that caches the results of a function.
def cache_results(func):
# Your code here
pass
@cache_results
def fib(n):
if n in (0, 1):
return n
return fib(n-1) + fib(n-2)
print(fib(10))
Solution:
def cache_results(func):
cache = {}
def wrapper(n):
if n not in cache:
cache[n] = func(n)
return cache[n]
return wrapper
@cache_results
def fib(n):
if n in (0, 1):
return n
return fib(n-1) + fib(n-2)
print(fib(10))
4. Puzzle: Write a decorator that ensures a function is only called once.
def only_once(func):
# Your code here
pass
@only_once
def initialize():
print("Initialized!")
initialize()
initialize()
Solution:
def only_once(func):
called = False
def wrapper(*args, **kwargs):
nonlocal called
if not called:
called = True
return func(*args, **kwargs)
return wrapper
@only_once
def initialize():
print("Initialized!")
initialize()
initialize()
5. Puzzle: Create a decorator that retries a function call if it raises an exception.
import random
def retry(num_retries):
# Your code here
pass
@retry(3)
def might_fail():
if random.choice([True, False]):
raise ValueError("Failed!")
return "Success!"
print(might_fail())
Solution:
import random
def retry(num_retries):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_retries):
try:
return func(*args, **kwargs)
except Exception as e:
print(e)
return None
return wrapper
return decorator
@retry(3)
def might_fail():
if random.choice([True, False]):
raise ValueError("Failed!")
return "Success!"
print(might_fail())
Context Managers
6. Puzzle: Implement a context manager that times the execution of a block of code.
import time
class Timer:
# Your code here
pass
with Timer():
time.sleep(2)
Solution:
import time
class Timer:
def __enter__(self):
self.start = time.time()
def __exit__(self, exc_type, exc_value, traceback):
self.end = time.time()
print(f"Elapsed time: {self.end - self.start} seconds")
with Timer():
time.sleep(2)
7. Puzzle: Create a context manager that redirects standard output to a file.
import sys
class RedirectOutput:
# Your code here
pass
with RedirectOutput('output.txt'):
print("This should go to the file!")
Solution:
import sys
class RedirectOutput:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'w')
self._stdout = sys.stdout
sys.stdout = self.file
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self._stdout
self.file.close()
with RedirectOutput('output.txt'):
print("This should go to the file!")
8. Puzzle: Write a context manager using the contextlib module that prints "Entering"
and "Exiting" messages.
from contextlib import contextmanager
@contextmanager
def enter_exit():
# Your code here
pass
with enter_exit():
print("Inside the context!")
Solution:
from contextlib import contextmanager
@contextmanager
def enter_exit():
print("Entering")
yield
print("Exiting")
with enter_exit():
print("Inside the context!")
9. Puzzle: Implement a context manager that changes the current working directory.
import os
class ChangeDir:
# Your code here
pass
with ChangeDir('/tmp'):
print(os.getcwd())
Solution:
import os
class ChangeDir:
def __init__(self, path):
self.path = path
def __enter__(self):
self.old_path = os.getcwd()
os.chdir(self.path)
def __exit__(self, exc_type, exc_value, traceback):
os.chdir(self.old_path)
with ChangeDir('/tmp'):
print(os.getcwd())
10. Puzzle: Create a context manager that counts the number of exceptions raised within
its block.
class ExceptionCounter:
# Your code here
pass
with ExceptionCounter() as counter:
try:
1 / 0
except:
pass
try:
int('abc')
except:
pass
print(counter.exceptions)
Solution:
class ExceptionCounter:
def __enter__(self):
self.exceptions = 0
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
self.exceptions += 1
return True
with ExceptionCounter() as counter:
try:
1 / 0
except:
pass
try:
int('abc')
except:
pass
print(counter.exceptions)
Metaclasses
11. Puzzle: Create a metaclass that prints the name of each created class.
class PrintMeta(type):
# Your code here
pass
class MyClass(metaclass=PrintMeta):
pass
class AnotherClass(metaclass=PrintMeta):
pass
Solution:
class PrintMeta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=PrintMeta):
pass
class AnotherClass(metaclass=PrintMeta):
pass
12. Puzzle: Implement a metaclass that adds a class method to every class it creates.
class MethodAdderMeta(type):
# Your code here
pass
class MyClass(metaclass=MethodAdderMeta):
pass
MyClass.class_method()
Solution:
class MethodAdderMeta(type):
def __new__(cls, name, bases, dct):
dct['class_method'] = lambda cls: print(f"{cls.__name__}
class method called")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=MethodAdderMeta):
pass
MyClass.class_method()
13. Puzzle: Write a metaclass that prevents the creation of classes with a specific name.
class NoSpecificNameMeta(type):
# Your code here
pass
class Forbidden(metaclass=NoSpecificNameMeta):
pass
Solution:
class NoSpecificNameMeta(type):
def __new__(cls, name, bases, dct):
if name == 'Forbidden':
raise ValueError("Class name 'Forbidden' is not allowed")
return super().__new__(cls, name, bases, dct)
try:
class Forbidden(metaclass=NoSpecificNameMeta):
pass
except ValueError as e:
print(e)
14. Puzzle: Implement a metaclass that ensures all class attributes are uppercase.
class UppercaseAttributesMeta(type):
# Your code here
pass
class MyClass(metaclass=UppercaseAttributesMeta):
my_attr = 42
print(MyClass.MY_ATTR)
Solution:
class UppercaseAttributesMeta(type):
def __new__(cls, name, bases, dct):
dct = {key.upper(): value for key, value in dct.items()}
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=UppercaseAttributesMeta):
my_attr = 42
print(MyClass.MY_ATTR)
15. Puzzle: Write a metaclass that keeps track of the number of classes it has created.
class CountingMeta(type):
# Your code here
pass
class MyClass1(metaclass=CountingMeta):
pass
class MyClass2(metaclass=CountingMeta):
pass
print(CountingMeta.class_count)
Solution:
class CountingMeta(type):
class_count = 0
def __new__(cls, name, bases, dct):
cls.class_count += 1
return super().__new__(cls, name, bases, dct)
class MyClass1(metaclass=CountingMeta):
pass
class MyClass2(metaclass=CountingMeta):
pass
print(CountingMeta.class_count)
Advanced Comprehensions
16. Puzzle: Create a list comprehension that generates a list of the squares of the first 10
positive integers.
# Your code here
squares = []
print(squares)
Solution:
squares = [x ** 2 for x in range(1, 11)]
print(squares) # Output: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
17. Puzzle: Write a dictionary comprehension that maps the first 10 positive integers to
their cubes.
# Your code here
cubes = {}
print(cubes)
Solution:
cubes = {x: x ** 3 for x in range(1, 11)}
print(cubes) # Output: {1: 1, 2: 8, 3: 27, 4: 64, 5: 125, 6: 216, 7:
343, 8: 512, 9: 729, 10: 1000}
18. Puzzle: Create a set comprehension that generates a set of all unique characters in a
given string.
string = "hello world"
# Your code here
unique_chars = {}
print(unique_chars)
Solution:
string = "hello world"
unique_chars = {char for char in string}
print(unique_chars) # Output: {'h', 'e', 'l', 'o', ' ', 'w', 'r',
'd'}
19. Puzzle: Write a nested list comprehension that generates a 3x3 matrix filled with
zeros.
# Your code here
matrix = []
print(matrix)
Solution:
matrix = [[0 for _ in range(3)] for _ in range(3)]
print(matrix) # Output: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
20. Puzzle: Create a list comprehension that generates a list of tuples, each containing a
number and its square, for numbers 1 through 5.
# Your code here
number_squares = []
print(number_squares)
Solution:
number_squares = [(x, x ** 2) for x in range(1, 6)]
print(number_squares) # Output: [(1, 1), (2, 4), (3, 9), (4, 16),
(5, 25)]
Coroutines
21. Puzzle: Write a coroutine that takes an integer and prints it after a delay.
import asyncio
async def print_with_delay(number):
# Your code here
pass
asyncio.run(print_with_delay(5))
Solution:
import asyncio
async def print_with_delay(number):
await asyncio.sleep(1)
print(number)
asyncio.run(print_with_delay(5))
22. Puzzle: Create a coroutine that runs two coroutines concurrently using
asyncio.gather.
import asyncio
async def task1():
await asyncio.sleep(1)
print("Task 1")
async def task2():
await asyncio.sleep(1)
print("Task 2")
async def main():
# Your code here
pass
asyncio.run(main())
Solution:
import asyncio
async def task1():
await asyncio.sleep(1)
print("Task 1")
async def task2():
await asyncio.sleep(1)
print("Task 2")
async def main():
await asyncio.gather(task1(), task2())
asyncio.run(main())
23. Puzzle: Write a coroutine that returns the sum of two numbers after a delay.
import asyncio
async def async_sum(a, b):
# Your code here
pass
result = asyncio.run(async_sum(3, 5))
print(result)
Solution:
import asyncio
async def async_sum(a, b):
await asyncio.sleep(1)
return a + b
result = asyncio.run(async_sum(3, 5))
print(result) # Output: 8
24. Puzzle: Create a coroutine that handles multiple tasks and returns their results.
import asyncio
async def task(n):
await asyncio.sleep(n)
return n
async def main():
# Your code here
pass
results = asyncio.run(main())
print(results)
Solution:
import asyncio
async def task(n):
await asyncio.sleep(n)
return n
async def main():
results = await asyncio.gather(task(1), task(2), task(3))
return results
results = asyncio.run(main())
print(results) # Output: [1, 2, 3]
25. Puzzle: Write a coroutine that demonstrates the use of asyncio.sleep and returns a
message after a delay.
import asyncio
async def delayed_message(delay, message):
# Your code here
pass
result = asyncio.run(delayed_message(2, "Hello, Async!"))
print(result)
Solution:
import asyncio
async def delayed_message(delay, message):
await asyncio.sleep(delay)
return message
result = asyncio.run(delayed_message(2, "Hello, Async!"))
print(result) # Output: "Hello, Async!"
Generators
26. Puzzle: Create a generator that yields the first 10 positive integers.
def first_ten_integers():
# Your code here
pass
for num in first_ten_integers():
print(num)
Solution:
def first_ten_integers():
for i in range(1, 11):
yield i
for num in first_ten_integers():
print(num)
27. Puzzle: Write a generator that yields the squares of numbers up to a given limit.
def squares(limit):
# Your code here
pass
for square in squares(5):
print(square)
Solution:
def squares(limit):
for i in range(1, limit + 1):
yield i ** 2
for square in squares(5):
print(square) # Output: 1, 4, 9, 16, 25
28. Puzzle: Create a generator that yields even numbers up to a given limit.
def even_numbers(limit):
# Your code here
pass
for even in even_numbers(10):
print(even)
Solution:
def even_numbers(limit):
for i in range(2, limit + 1, 2):
yield i
for even in even_numbers(10):
print(even) # Output: 2, 4, 6, 8, 10
29. Puzzle: Write a generator that yields Fibonacci numbers up to a given limit.
def fibonacci(limit):
# Your code here
pass
for fib in fibonacci(10):
print(fib)
Solution:
def fibonacci(limit):
a, b = 0, 1
while a <= limit:
yield a
a, b = b, a + b
for fib in fibonacci(10):
print(fib) # Output: 0, 1, 1, 2, 3, 5, 8
30. Puzzle: Create a generator that yields prime numbers up to a given limit.
def primes(limit):
# Your code here
pass
for prime in primes(10):
print(prime)
Solution:
def primes(limit):
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
for num in range(2, limit + 1):
if is_prime(num):
yield num
for prime in primes(10):
print(prime) # Output: 2, 3, 5, 7
Type Hints
31. Puzzle: Write a function with type hints that takes two integers and returns their sum.
def add(a: int, b: int) -> int:
# Your code here
pass
print(add(2, 3))
Solution:
def add(a: int, b: int) -> int:
return a + b
print(add(2, 3))
# Output: 5
32. Puzzle: Create a function with type hints that takes a list of strings and returns the
longest string.
from typing import List
def longest_string(strings: List[str]) -> str:
# Your code here
pass
print(longest_string(["apple", "banana", "cherry"]))
Solution:
from typing import List
def longest_string(strings: List[str]) -> str:
return max(strings, key=len)
print(longest_string(["apple", "banana", "cherry"]))
"banana"
# Output:
33. Puzzle: Write a function with type hints that takes a dictionary and returns a list of its
keys.
from typing import Dict, List
def dict_keys(d: Dict) -> List:
# Your code here
pass
print(dict_keys({"a": 1, "b": 2, "c": 3}))
Solution:
from typing import Dict, List
def dict_keys(d: Dict) -> List:
return list(d.keys())
print(dict_keys({"a": 1, "b": 2, "c": 3}))
# Output: ["a", "b", "c"]
34. Puzzle: Create a function with type hints that takes a string and returns a dictionary of
character frequencies.
from typing import Dict
def char_freqs(s: str) -> Dict[str, int]:
# Your code here
pass
print(char_freqs("hello"))
Solution:
from typing import Dict
def char_freqs(s: str) -> Dict[str, int]:
freqs = {}
for char in s:
if char in freqs:
freqs[char] += 1
else:
freqs[char] = 1
return freqs
print(char_freqs("hello"))
1}
# Output: {"h": 1, "e": 1, "l": 2, "o":
35. Puzzle: Write a function with type hints that takes a list of integers and returns a list
of their squares.
from typing import List
def squares(nums: List[int]) -> List[int]:
# Your code here
pass
print(squares([1, 2, 3, 4]))
Solution:
from typing import List
def squares(nums: List[int]) -> List[int]:
return [x ** 2 for x in nums]
print(squares([1, 2, 3, 4]))
# Output: [1, 4, 9, 16]
Dataclasses
36. Puzzle: Create a simple dataclass for a Person with name and age attributes.
from dataclasses import dataclass
@dataclass
class Person:
# Your code here
pass
person = Person("Alice", 30)
print(person)
Solution:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
person = Person("Alice", 30)
print(person) # Output: Person(name='Alice', age=30)
37. Puzzle: Write a dataclass for a Book with title, author, and pages attributes.
from dataclasses import dataclass
@dataclass
class Book:
# Your code here
pass
book = Book("1984", "George Orwell", 328)
print(book)
Solution:
from dataclasses import dataclass
@dataclass
class Book:
title: str
author: str
pages: int
book = Book("1984", "George Orwell", 328)
print(book) # Output: Book(title='1984', author='George Orwell',
pages=328)
38. Puzzle: Create a dataclass with a default value for one of its attributes.
from dataclasses import dataclass
@dataclass
class Car:
make: str
model: str
year: int = 2020
car = Car("Toyota", "Corolla")
print(car)
Solution:
from dataclasses import dataclass
@dataclass
class Car:
make: str
model: str
year: int = 2020
car = Car("Toyota", "Corolla")
print(car) # Output: Car(make='Toyota', model='Corolla', year=2020)
39. Puzzle: Write a dataclass for a Rectangle with width, height, and a method to
calculate the area.
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
def area(self):
# Your code here
pass
rect = Rectangle(5, 10)
print(rect.area())
Solution:
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
def area(self):
return self.width * self.height
rect = Rectangle(5, 10)
print(rect.area()) # Output: 50.0
40. Puzzle: Create a dataclass with a method to compare the areas of two rectangles.
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
def area(self):
return self.width * self.height
def is_larger_than(self, other):
# Your code here
pass
rect1 = Rectangle(5, 10)
rect2 = Rectangle(4, 12)
print(rect1.is_larger_than(rect2))
Solution:
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
def area(self):
return self.width * self.height
def is_larger_than(self, other):
return self.area() > other.area()
rect1 = Rectangle(5, 10)
rect2 = Rectangle(4, 12)
print(rect1.is_larger_than(rect2))
# Output: True
Error Handling
41. Puzzle: Write a function that takes two integers and returns their division, handling
the case where the denominator is zero.
def safe_divide(a, b):
# Your code here
pass
print(safe_divide(10, 2))
print(safe_divide(10, 0))
Solution:
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "Division by zero is not allowed"
print(safe_divide(10, 2))
print(safe_divide(10, 0))
allowed"
# Output: 5.0
# Output: "Division by zero is not
42. Puzzle: Create a function that reads a file and returns its content, handling the case
where the file does not exist.
def read_file(file_path):
# Your code here
pass
print(read_file("existing_file.txt"))
print(read_file("non_existing_file.txt"))
Solution:
def read_file(file_path):
try:
with open(file_path, 'r') as file:
return file.read()
except FileNotFoundError:
return "File not found"
print(read_file("existing_file.txt")) # Output: (content of the
file)
print(read_file("non_existing_file.txt")) # Output: "File not found"
43. Puzzle: Write a function that takes a string and returns its integer value, handling the
case where the string is not a valid integer.
def safe_int(s):
# Your code here
pass
print(safe_int("123"))
print(safe_int("abc"))
Solution:
def safe_int(s):
try:
return int(s)
except ValueError:
return "Invalid integer"
print(safe_int("123"))
print(safe_int("abc"))
# Output: 123
# Output: "Invalid integer"
44. Puzzle: Create a function that handles multiple exceptions and returns appropriate
messages for TypeError and ValueError.
def handle_exceptions(value):
try:
# Your code here
pass
except TypeError:
return "Type error occurred"
except ValueError:
return "Value error occurred"
print(handle_exceptions(10))
print(handle_exceptions("abc"))
Solution:
def handle_exceptions(value):
try:
result = 10 / value
return int(result)
except TypeError:
return "Type error occurred"
except ValueError:
return "Value error occurred"
print(handle_exceptions(10)) # Output: 1
print(handle_exceptions("abc")) # Output: "Type error occurred"
45. Puzzle: Write a function that opens a file and writes to it, ensuring that the file is
properly closed even if an error occurs.
def safe_write(file_path, content):
# Your code here
pass
safe_write("output.txt", "Hello, world!")
Solution:
def safe_write(file_path, content):
try:
with open(file_path, 'w') as file:
file.write(content)
except Exception as e:
print(f"An error occurred: {e}")
safe_write("output.txt", "Hello, world!")
Context Managers
46. Puzzle: Write a context manager that measures the time taken by a block of code.
import time
class Timer:
# Your code here
pass
with Timer():
time.sleep(1)
Solution:
import time
class Timer:
def __enter__(self):
self.start_time = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
elapsed_time = time.time() - self.start_time
print(f"Elapsed time: {elapsed_time:.2f} seconds")
with Timer():
time.sleep(1)
# Output: Elapsed time: 1.00 seconds
47. Puzzle: Create a context manager that temporarily changes the current working
directory.
import os
class TempDir:
# Your code here
pass
with TempDir("/tmp"):
print(os.getcwd())
Solution:
import os
class TempDir:
def __init__(self, new_path):
self.new_path = new_path
def __enter__(self):
self.original_path = os.getcwd()
os.chdir(self.new_path)
def __exit__(self, exc_type, exc_val, exc_tb):
os.chdir(self.original_path)
with TempDir("/tmp"):
print(os.getcwd())
# Output: /tmp
48. Puzzle: Write a context manager that suppresses specific exceptions.
class SuppressException:
def __init__(self, *exceptions):
self.exceptions = exceptions
# Your code here
pass
with SuppressException(ZeroDivisionError):
print(1 / 0)
Solution:
class SuppressException:
def __init__(self, *exceptions):
self.exceptions = exceptions
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
return exc_type is not None and issubclass(exc_type,
self.exceptions)
with SuppressException(ZeroDivisionError):
print(1 / 0) # Output: None (exception is suppressed)
49. Puzzle: Create a context manager that logs entering and exiting a block of code.
class Logger:
# Your code here
pass
with Logger():
print("Inside the block")
Solution:
class Logger:
def __enter__(self):
print("Entering the block")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the block")
with Logger():
print("Inside the block")
the block\nExiting the block
# Output: Entering the block\nInside
50. Puzzle: Write a context manager that handles resource cleanup by closing a file.
class FileManager:
def __init__(self, file_name, mode):
self.file_name = file_name
self.mode = mode
# Your code here
pass
with FileManager("output.txt", "w") as f:
f.write("Hello, world!")
Solution:
class FileManager:
def __init__(self, file_name, mode):
self.file_name = file_name
self.mode = mode
def __enter__(self):
self.file = open(self.file_name, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with FileManager("output.txt", "w") as f:
f.write("Hello, world!") # File is automatically closed after
the block
Installing
1. Puzzle: What command do you use to check the installed version of ?
Solution:
shell
--version
2. Puzzle: How do you create a virtual environment in ?
Solution:
shell
-m venv myenv
3. Puzzle: What is the command to activate a virtual environment on Windows?
Solution:
shell
myenv\Scripts\activate
4. Puzzle: How do you install the pip package manager?
Solution:
shell
-m ensurepip --upgrade
5. Puzzle: What command do you use to install a package using pip?
Solution:
shell
pip install package_name
Writing and Running Scripts
6. Puzzle: How do you run a script from the command line?
Solution:
shell
script.py
7. Puzzle: What is the file extension for scripts?
Solution:
shell
.py
8. Puzzle: Write a simple "Hello, World!" script.
Solution:
print("Hello, World!")
9. Puzzle: How do you write a script that takes command-line arguments?
Solution:
import sys
print(sys.argv)
10. Puzzle: How do you make a script executable on Unix-based systems?
Solution:
shell
chmod +x script.py
./script.py
Basic Syntax
11. Puzzle: Write a script that prints the current date and time.
Solution:
from datetime import datetime
print(datetime.now())
12. Puzzle: Write a function that calculates the factorial of a number.
Solution:
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
print(factorial(5))
# Output: 120
13. Puzzle: Write a script that reads input from the user and prints it.
Solution:
user_input = input("Enter something: ")
print(user_input)
14. Puzzle: Write a script that prints numbers from 1 to 10 using a loop.
Solution:
for i in range(1, 11):
print(i)
15. Puzzle: Write a script that prints the even numbers from 1 to 10.
Solution:
for i in range(1, 11):
if i % 2 == 0:
print(i)
Variables and Data Types
16. Puzzle: How do you declare a variable and assign it a value in ?
Solution:
x = 10
17. Puzzle: Write a script that swaps the values of two variables.
Solution:
a = 5
b = 10
a, b = b, a
print(a, b)
# Output: 10 5
18. Puzzle: Write a script to concatenate two strings.
Solution:
str1 = "Hello, "
str2 = "World!"
result = str1 + str2
print(result) # Output: Hello, World!
19. Puzzle: Write a script to convert a string to an integer.
Solution:
str_num = "123"
int_num = int(str_num)
print(int_num) # Output: 123
20. Puzzle: Write a script to convert an integer to a string.
Solution:
int_num = 123
str_num = str(int_num)
print(str_num) # Output: "123"
Operators
21. Puzzle: Write a script to find the remainder of two numbers using the modulo
operator.
Solution:
a = 10
b = 3
result = a % b
print(result) # Output: 1
22. Puzzle: Write a script to check if a number is even or odd using the modulo operator.
Solution:
num = 10
if num % 2 == 0:
print("Even")
else:
print("Odd")
23. Puzzle: Write a script to calculate the power of a number using the exponentiation
operator.
Solution:
base = 2
exponent = 3
result = base ** exponent
print(result) # Output: 8
24. Puzzle: Write a script to check if two numbers are equal using the equality operator.
Solution:
a = 5
b = 5
print(a == b)
# Output: True
25. Puzzle: Write a script to check if one number is greater than another using the greater
than operator.
Solution:
a = 10
b = 5
print(a > b)
# Output: True
Control Flow
26. Puzzle: Write a script that prints "Hello" if a number is greater than 5.
Solution:
num = 6
if num > 5:
print("Hello")
27. Puzzle: Write a script that prints "Hello" if a number is greater than 5, otherwise
prints "Goodbye".
Solution:
num = 4
if num > 5:
print("Hello")
else:
print("Goodbye")
28. Puzzle: Write a script that prints numbers from 1 to 5 using a while loop.
Solution:
i = 1
while i <= 5:
print(i)
i += 1
29. Puzzle: Write a script that prints each character of a string using a for loop.
Solution:
string = "Hello"
for char in string:
print(char)
30. Puzzle: Write a script that uses a nested loop to print a 3x3 matrix of numbers.
Solution:
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end=" ")
print()
Functions
31. Puzzle: Write a function that returns the sum of two numbers.
Solution:
def add(a, b):
return a + b
print(add(3, 4))
# Output: 7
32. Puzzle: Write a function that returns the maximum of two numbers.
Solution:
def maximum(a, b):
return a if a > b else b
print(maximum(3, 4))
# Output: 4
33. Puzzle: Write a function that checks if a number is prime.
Solution:
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
print(is_prime(5))
# Output: True
34. Puzzle: Write a function that returns the reverse of a string.
Solution:
def reverse_string(s):
return s[::-1]
print(reverse_string("Hello"))
# Output: "olleH"
35. Puzzle: Write a function that calculates the sum of a list of numbers.
Solution:
def sum_list(lst):
return sum(lst)
print(sum_list([1, 2, 3, 4]))
# Output: 10
Exception Handling
36. Puzzle: Write a function that handles division by zero.
Solution:
def divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "Cannot divide by zero"
print(divide(10, 2))
print(divide(10, 0))
# Output: 5.0
# Output: "Cannot divide by zero"
37. Puzzle: Write a script that reads a file and handles the file not found error.
Solution:
try:
with open("non_existing_file.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("File not found")
38. Puzzle: Write a script that handles multiple exceptions (ValueError and TypeError).
Solution:
try:
num = int("abc")
except (ValueError, TypeError) as e:
print(f"Error occurred: {e}")
39. Puzzle: Write a function that uses a finally block to ensure a resource is closed.
Solution:
def read_file(file_path):
file = None
try:
file = open(file_path, "r")
return file.read()
except FileNotFoundError:
return "File not found"
finally:
if file:
file.close()
print(read_file("existing_file.txt"))
40. Puzzle: Write a script that raises a custom exception.
Solution:
class CustomError(Exception):
pass
def check_value(value):
if value < 0:
raise CustomError("Negative value not allowed")
try:
check_value(-1)
except CustomError as e:
print(e) # Output: Negative value not allowed
Data Structures
Lists
41. Puzzle: Write a script to append an item to a list.
Solution:
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # Output: [1, 2, 3, 4]
42. Puzzle: Write a script to remove an item from a list.
Solution:
my_list = [1, 2, 3]
my_list.remove(2)
print(my_list) # Output: [1, 3]
43. Puzzle: Write a script to sort a list.
Solution:
my_list = [3, 1, 2]
my_list.sort()
print(my_list) # Output: [1, 2, 3]
44. Puzzle: Write a script to reverse a list.
Solution:
my_list = [1, 2, 3]
my_list.reverse()
print(my_list) # Output: [3, 2, 1]
45. Puzzle: Write a script to find the index of an item in a list.
Solution:
my_list = [1, 2, 3]
index = my_list.index(2)
print(index) # Output: 1
Tuples
46. Puzzle: Write a script to create a tuple.
Solution:
my_tuple = (1, 2, 3)
print(my_tuple) # Output: (1, 2, 3)
47. Puzzle: Write a script to access an item in a tuple.
Solution:
my_tuple = (1, 2, 3)
print(my_tuple[1]) # Output: 2
48. Puzzle: Write a script to concatenate two tuples.
Solution:
tuple1 = (1, 2)
tuple2 = (3, 4)
result = tuple1 + tuple2
print(result) # Output: (1, 2, 3, 4)
49. Puzzle: Write a script to find the length of a tuple.
Solution:
my_tuple = (1, 2, 3)
length = len(my_tuple)
print(length) # Output: 3
50. Puzzle: Write a script to convert a list to a tuple.
Solution:
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(my_tuple) # Output: (1, 2, 3)
Sets
51. Puzzle: Write a script to create a set.
Solution:
my_set = {1, 2, 3}
print(my_set) # Output: {1, 2, 3}
52. Puzzle: Write a script to add an item to a set.
Solution:
my_set = {1, 2, 3}
my_set.add(4)
print(my_set) # Output: {1, 2, 3, 4}
53. Puzzle: Write a script to remove an item from a set.
Solution:
my_set = {1, 2, 3}
my_set.remove(2)
print(my_set) # Output: {1, 3}
54. Puzzle: Write a script to find the union of two sets.
Solution:
set1 = {1, 2}
set2 = {3, 4}
result = set1.union(set2)
print(result) # Output: {1, 2, 3, 4}
55. Puzzle: Write a script to find the intersection of two sets.
Solution:
set1 = {1, 2, 3}
set2 = {2, 3, 4}
result = set1.intersection(set2)
print(result) # Output: {2, 3}
Dictionaries
56. Puzzle: Write a script to create a dictionary.
Solution:
my_dict = {"a": 1, "b": 2, "c": 3}
print(my_dict) # Output: {'a': 1, 'b': 2, 'c': 3}
57. Puzzle: Write a script to access a value in a dictionary.
Solution:
my_dict = {"a": 1, "b": 2, "c": 3}
print(my_dict["b"]) # Output: 2
58. Puzzle: Write a script to add a key-value pair to a dictionary.
Solution:
my_dict = {"a": 1, "b": 2}
my_dict["c"] = 3
print(my_dict) # Output: {'a': 1, 'b': 2, 'c': 3}
59. Puzzle: Write a script to remove a key-value pair from a dictionary.
Solution:
my_dict = {"a": 1, "b": 2, "c": 3}
del my_dict["b"]
print(my_dict) # Output: {'a': 1, 'c': 3}
60. Puzzle: Write a script to iterate over the keys and values of a dictionary.
Solution:
my_dict = {"a": 1, "b": 2, "c": 3}
for key, value in my_dict.items():
print(f"{key}: {value}")
Modules and Packages
Importing Modules
61. Puzzle: Write a script to import the math module and use the sqrt function.
Solution:
import math
print(math.sqrt(16))
# Output: 4.0
62. Puzzle: Write a script to import the random module and use the randint function.
Solution:
import random
print(random.randint(1, 10))
10
# Output: Random integer between 1 and
63. Puzzle: Write a script to import a specific function from a module.
Solution:
from math import pi
print(pi)
# Output: 3.141592653589793
64. Puzzle: Write a script to import a module with an alias.
Solution:
import numpy as np
print(np.array([1, 2, 3]))
# Output: [1 2 3]
65. Puzzle: Write a script to create a custom module and import it.
Solution:
# Create a file named custom_module.py with the following content:
def greet(name):
return f"Hello, {name}!"
# In another script:
import custom_module
print(custom_module.greet("Alice"))
# Output: Hello, Alice!
Standard Library Overview
66. Puzzle: Write a script to use the datetime module to print the current date.
Solution:
from datetime import date
print(date.today())
# Output: Current date
67. Puzzle: Write a script to use the os module to list files in the current directory.
Solution:
import os
print(os.listdir("."))
directory
# Output: List of files in the current
68. Puzzle: Write a script to use the sys module to print command-line arguments.
Solution:
import sys
print(sys.argv)
# Output: List of command-line arguments
69. Puzzle: Write a script to use the time module to sleep for 2 seconds.
Solution:
import time
time.sleep(2)
print("Slept for 2 seconds")
70. Puzzle: Write a script to use the json module to parse a JSON string.
Solution:
import json
json_string = '{"name": "Alice", "age": 30}'
data = json.loads(json_string)
print(data) # Output: {'name': 'Alice', 'age': 30}
Creating and Using Packages
71. Puzzle: Write a script to create a package with an __init__.py file.
Solution:
# Directory structure:
# mypackage/
#
__init__.py
#
module1.py
# __init__.py
from .module1 import greet
# module1.py
def greet(name):
return f"Hello, {name}!"
# In another script:
import mypackage
print(mypackage.greet("Alice"))
# Output: Hello, Alice!
72. Puzzle: Write a script to import a module from a subpackage.
Solution:
# Directory structure:
# mypackage/
#
__init__.py
#
subpackage/
#
__init__.py
#
module1.py
# subpackage/module1.py
def greet(name):
return f"Hello, {name}!"
# In another script:
from mypackage.subpackage import module1
print(module1.greet("Alice"))
# Output: Hello, Alice!
73. Puzzle: Write a script to use a relative import within a package.
Solution:
# Directory structure:
# mypackage/
#
__init__.py
#
module1.py
#
module2.py
# module1.py
def greet(name):
return f"Hello, {name}!"
# module2.py
from .module1 import greet
print(greet("Alice"))
# Output: Hello, Alice!
74. Puzzle: Write a script to list all modules in a package.
Solution:
import pkgutil
package = mypackage
for module_info in pkgutil.iter_modules(package.__path__):
print(module_info.name)
75. Puzzle: Write a script to dynamically import a module by name.
Solution:
import importlib
module_name = "math"
math_module = importlib.import_module(module_name)
print(math_module.sqrt(16)) # Output: 4.0
File Handling
Reading and Writing Files
76. Puzzle: Write a script to write to a file.
Solution:
with open("output.txt", "w") as file:
file.write("Hello, World!")
77. Puzzle: Write a script to read from a file.
Solution:
with open("output.txt", "r") as file:
content = file.read()
print(content) # Output: Hello, World!
78. Puzzle: Write a script to read a file line by line.
Solution:
with open("output.txt", "r") as file:
for line in file:
print(line.strip())
79. Puzzle: Write a script to append to a file.
Solution:
with open("output.txt", "a") as file:
file.write("\nAppended text")
80. Puzzle: Write a script to count the number of lines in a file.
Solution:
with open("output.txt", "r") as file:
lines = file.readlines()
print(len(lines))
Working with CSV and JSON Files
81. Puzzle: Write a script to read a CSV file.
Solution:
import csv
with open("data.csv", "r") as file:
reader = csv.reader(file)
for row in reader:
print(row)
82. Puzzle: Write a script to write to a CSV file.
Solution:
import csv
with open("output.csv", "w", newline='') as file:
writer = csv.writer(file)
writer.writerow(["Name", "Age"])
writer.writerow(["Alice", 30])
83. Puzzle: Write a script to read a JSON file.
Solution:
import json
with open("data.json", "r") as file:
data = json.load(file)
print(data)
84. Puzzle: Write a script to write to a JSON file.
Solution:
import json
data = {"name": "Alice", "age": 30}
with open("output.json", "w") as file:
json.dump(data, file)
85. Puzzle: Write a script to convert a CSV file to a JSON file.
Solution:
import csv
import json
data = []
with open("data.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
data.append(row)
with open("output.json", "w") as file:
json.dump(data, file)
Object-Oriented Programming (OOP)
Classes and Objects
86. Puzzle: Write a class with an __init__ method.
Solution:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.name) # Output: Alice
87. Puzzle: Write a class with a method.
Solution:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, {self.name}!"
p = Person("Alice", 30)
print(p.greet()) # Output: Hello, Alice!
88. Puzzle: Write a class with a class variable.
Solution:
class Person:
species = "Homo sapiens"
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.species) # Output: Homo sapiens
89. Puzzle: Write a class with a static method.
Solution:
class Math:
@staticmethod
def add(a, b):
return a + b
print(Math.add(3, 4))
# Output: 7
90. Puzzle: Write a class with a class method.
Solution:
class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Person.count += 1
@classmethod
def get_count(cls):
return cls.count
p1 = Person("Alice", 30)
p2 = Person("Bob", 25)
print(Person.get_count())
# Output: 2
Inheritance
91. Puzzle: Write a class that inherits from another class.
Solution:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
d = Dog("Rex")
print(d.speak())
# Output: Woof!
92. Puzzle: Write a class that overrides a method in the parent class.
Solution:
class Animal:
def speak(self):
return "Generic animal sound"
class Dog(Animal):
def speak(self):
return "Woof!"
d = Dog()
print(d.speak())
# Output: Woof!
93. Puzzle: Write a class that uses super() to call the parent class method.
Solution:
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
d = Dog("Rex", "Labrador")
print(d.name) # Output: Rex
94. Puzzle: Write a class with multiple inheritance.
Solution:
class Flyable:
def fly(self):
return "Flying"
class Swimmable:
def swim(self):
return "Swimming"
class Duck(Flyable, Swimmable):
pass
d = Duck()
print(d.fly()) # Output: Flying
print(d.swim()) # Output: Swimming
95. Puzzle: Write a class with a method that returns the class name.
Solution:
class Animal:
def get_class_name(self):
return self.__class__.__name__
class Dog(Animal):
pass
d = Dog()
print(d.get_class_name())
# Output: Dog
Polymorphism
96. Puzzle: Write a script to demonstrate method overriding.
Solution:
class Animal:
def speak(self):
return "Generic animal sound"
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
animals = [Dog(), Cat()]
for animal in animals:
print(animal.speak())
97. Puzzle: Write a script to demonstrate method overloading (not natively supported in ,
but can be simulated).
Solution:
class Math:
def add(self, a, b, c=0):
return a + b + c
m = Math()
print(m.add(1, 2)) # Output: 3
print(m.add(1, 2, 3)) # Output: 6
98. Puzzle: Write a script to demonstrate operator overloading.
Solution:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Output: Vector(4, 6)
99. Puzzle: Write a script to demonstrate polymorphism with a common interface.
Solution:
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
def make_animal_speak(animal):
print(animal.speak())
make_animal_speak(Dog())
make_animal_speak(Cat())
100.
# Output: Woof!
# Output: Meow!
Puzzle: Write a script to demonstrate duck typing.
makefile
**Solution**:
```
class Bird:
def fly(self):
return "Flying"
class Airplane:
def fly(self):
return "Flying"
def make_it_fly(thing):
print(thing.fly())
make_it_fly(Bird()) # Output: Flying
make_it_fly(Airplane()) # Output: Flying
```
These puzzles will give you hands-on practice with basics and help you prepare for more
advanced topics. Let me know if you need any further explanations or additional puzzles!
Download