Python Workspace¶
Intro¶
In [1]:
a = 4
print(a)
4
Python Coding Tips: Lessons I Wish I Knew When I Started Coding¶
by Livia Ellen published on Medium
In [2]:
# f-string dynamic string formattin
name = "John"
age = 26
message = f"My name is {name}, and I am {age} years old."
print(message)
My name is John, and I am 26 years old.
In [4]:
# decorator
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__} executed in {end_time - start_time} seconds')
return result
return wrapper
def fibonacci_of(n):
if n in {0, 1}: # Base case
return n
return fibonacci_of(n - 1) + fibonacci_of(n - 2) # Recursive case
@timer_decorator
def example_function():
print(fibonacci_of(10))
example_function()
55 example_function executed in 0.0014181137084960938
In [2]:
# decorator
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__} executed in {end_time - start_time} seconds')
return result
return wrapper
def fibonacci_of(n):
if n in {0, 1}: # Base case
return n
return fibonacci_of(n - 1) + fibonacci_of(n - 2) # Recursive case
@timer_decorator
def example_function():
print(fibonacci_of(10))
example_function()
# decorator as a context
from contextlib import contextmanager
@contextmanager
def timer_b(name):
try:
# print(f'TIMER: {name} start')
start_time = time.time()
yield
finally:
end_time = time.time()
print(f'TIMER: {name} executed in {end_time - start_time} seconds')
@timer_b(name='fibonacci')
def example_function_b():
print(fibonacci_of(10))
example_function_b()
with timer_b(name='fibonacci timer'):
print(fibonacci_of(10))
55 example_function executed in 0.0004971027374267578 seconds 55 TIMER: fibonacci executed in 4.029273986816406e-05 seconds 55 TIMER: fibonacci timer executed in 3.647804260253906e-05 seconds
In [6]:
# help() Function
def calculate_square(number):
"""
Calculates the square of a given number.Parameters:
- number (int): The input number.
Returns:
- int: The square of the input number.
"""
return number ** 2
# accessing help for the calculate_square function
help(calculate_square)
print(calculate_square(10))
Help on function calculate_square in module __main__: calculate_square(number) Calculates the square of a given number.Parameters: - number (int): The input number. Returns: - int: The square of the input number. 100
In [7]:
# list comprehensions
# finding squares of even numbers in a range
squares = [x**2 for x in range(10) if x % 2 == 0]
print(squares)
[0, 4, 16, 36, 64]
In [8]:
# lambda functions
# adding two numbers with a lambda function
add_numbers = lambda x, y: x + y
result = add_numbers(3, 5)
print(result)
8
In [10]:
# iteration with enumerate and zip
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 22]
# enumerate for index and value
for index, name in enumerate(names):
print(f"Person {index + 1}: {name}")
print('...')
# zip for parallel iteration
for name, age in zip(names, ages):
print(f"{name} is {age} years old.")
Person 1: Alice Person 2: Bob Person 3: Charlie ... Alice is 25 years old. Bob is 30 years old. Charlie is 22 years old.
In [26]:
# *args and **kwargs
def multiply_args(*args, **kwargs):
result = 1
for num in args:
result *= num
return result
print(multiply_args(2,3,4))
def multiply_kwargs(*args, **kwargs):
result = 1
for key, value in kwargs.items():
result *= value
return result
print(multiply_kwargs(two=2,three=3,four=4))
24 24
In [27]:
# error Handling with try and except
# Example: Graceful error handling with try and except
def divide_numbers(a, b):
try:
result = a / b
print(f"The result of {a} divided by {b} is: {result}")
except ZeroDivisionError:
print("Cannot divide by zero! Please provide a non-zero denominator.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
else:
print("Division successful!")
# Testing the function
divide_numbers(10, 2) # Normal division
divide_numbers(5, 0) # Division by zero
divide_numbers("a", 2) # Unexpected error (TypeError)
The result of 10 divided by 2 is: 5.0 Division successful! Cannot divide by zero! Please provide a non-zero denominator. An unexpected error occurred: unsupported operand type(s) for /: 'str' and 'int'
In [28]:
# list slicing:
# extracting a sublist from index 2 to 5
original_list = [1, 2, 3, 4, 5, 6, 7]
sublist = original_list[2:6]
print(sublist)
[3, 4, 5, 6]
In [31]:
# generators
# fibonacci sequence generator
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for n in fibonacci(10):
print(n)
0 1 1 2 3 5 8 13 21 34
In [32]:
# assertions
# assertion for checking if a variable is positive
num = -5
assert num > 0, "Number must be positive"
--------------------------------------------------------------------------- AssertionError Traceback (most recent call last) Cell In[32], line 4 1 # assertions 2 # assertion for checking if a variable is positive 3 num = -5 ----> 4 assert num > 0, "Number must be positive" AssertionError: Number must be positive
In [36]:
# namedtuples: self-documenting data structures
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
alice = Person(name="Alice", age=30)
print(alice)
print(alice.name)
print(alice.age)
Person(name='Alice', age=30) Alice 30
In [37]:
# zipping lists: combine sequences
# matching user inputs with corresponding answers in a quiz
names = ["Alice", "Bob"]
scores = [85, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}")
Alice: 85 Bob: 92
In [39]:
# dictionaries
data = {"name": "Alice"}
age = data.get("age", 30)
data.setdefault("country", "USA")
print(data, age)
{'name': 'Alice', 'country': 'USA'} 30
In [40]:
# the asterisk (*) operator
# passing a dynamic list of values to a function expecting separate arguments
def func(a, b, c):
return a + b + c
values = [1, 2, 3]
print(func(*values))
6
In [41]:
# merging dictionaries
# using the update() method
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
dict1.update(dict2)
print(dict1)
{'a': 1, 'b': 3, 'c': 4}
Context Managers In Python¶
by Yanick Andrade published on Medium
In [5]:
class AuthManager:
def __init__(self, username: str, password: str) -> None:
print('init')
self.username = username
self.password = password
def __enter__(self):
print('enter')
return self
def __exit__(self, exc_type, exc_value, traceback):
print('exit')
# let's assume that we have some logic to log user out
self.logout()
# we will se why we are returning True
return True
def login(self):
print('login')
# let's assume that we have some logic to log user in
pass
def logout(self):
print('logout')
# let's assume that we have some logic to log user out
pass
with AuthManager(username="random", password="random") as auth:
# let's assume that we have some logic to log user in
auth.login()
init enter login exit logout
In [3]:
# decorator as a context
from contextlib import contextmanager
import time
@contextmanager
def timer_b(name):
try:
# print(f'TIMER: {name} start')
start_time = time.time()
yield
finally:
end_time = time.time()
print(f'TIMER: {name} executed in {end_time - start_time} seconds')
@timer_b(name='fibonacci')
def example_function_b():
print(fibonacci_of(10))
example_function_b()
with timer_b(name='fibonacci timer'):
print(fibonacci_of(10))
55 TIMER: fibonacci executed in 0.0008521080017089844 seconds 55 TIMER: fibonacci timer executed in 4.3392181396484375e-05 seconds
How to Filter a List in Python¶
comparing methods for filtering lists in Python
Method | Example | Advantages | Disadvantages |
---|---|---|---|
filter() |
result = filter(lambda x: x%2 == 0, num_list) |
(i) Efficient for complex conditions or reusable filters; (ii) Concise and readable | (i) Not as efficient as list comprehension for simple cases; (ii) Requires defining a separate function. |
List comprehension | result = [x for x in num_list if x%2 == 0] |
(i) Concise and efficient for simple filtering. | (i) Less flexible than filter() for complex conditions; (ii) Can be less readable with complex logic. |
Loop | result = []for x in num_list: if x%2 == 0: new_list.append(x) |
(i) Easiest to understand for beginners | (i) Less efficient than filter() or list comprehension; (ii) Longer and less readable for complex tasks. |
Built-in functions | result = max(num_list) |
(i) Highly efficient for specific tasks like finding min/max; (ii) Built-in and easy to use. | (i) Limited to specific tasks; (ii) Not suitable for more complex filtering criteria. |
using the filter()
function¶
In [8]:
nums = [11, 22, 31, 42, 51]
def is_num_odd(z):
return z % 2 != 0
out_nums = filter(is_num_odd, nums)
# Convert the iterator to a list
out_nums = list(out_nums)
print(out_nums)
[11, 31, 51]
using list comprehension¶
In [7]:
nums = [11, 22, 31, 42, 51]
result = [x for x in nums if x % 2 == 0]
print(result)
[22, 42]
using a loop¶
In [9]:
nums = [11, 22, 31, 42, 51]
outNums = []
for n in nums:
if n % 2 == 0:
outNums.append(n)
print(outNums)
[22, 42]
filtering using regular expressions¶
In [10]:
import re
texts = [
"My email is johndoe@example.com.",
"Contact me at johnsmith123@gmail.com",
"This website has no contact information."
]
emails = [re.findall(r"[\w.]+@\w+\.\w+", text) for text in texts]
print(emails)
[['johndoe@example.com'], ['johnsmith123@gmail.com'], []]