Python Runner + Syntax Examples

x = "Hello World"
word_list = x.lower().split()
print("Word list:", word_list)
👾 Python environment loading...

String

# Split
log = "2025-06-05 14:32:10,124 INFO User logged in"
list_of_str = log.split(",")
print(list_of_str)    # ['2025-06-05 14:32:10', '124 INFO User logged in'] 
# Partition
log = "2025-06-05 14:32:10,124 INFO User logged in"
timestamp, _, message = log.partition(" INFO ")
print(timestamp)  # '2025-06-05 14:32:10,124'
print(message)    # 'User logged in'
# Strip and find index
line = "  ERROR Something bad happened  \n"
cleaned = line.strip()
print(cleaned) # 'ERROR Something bad happened'

cleaned = cleaned.strip("hap")
print(cleaned) # 'ERROR Something bad happened'

cleaned = cleaned.strip("happened")
print(cleaned) # 'ERROR Something bad'

print(line.find("bad")) # 18
print(line.find("good")) # -1

print(line.startswith("ERROR"))  # False
print(cleaned.startswith("ERROR"))  # True
# Join and upper
words = ["hello", "world"]
joined = " ".join(words).upper()
print(joined)  # 'HELLO WORLD'
# Replace and count
s = "banana"
print(s.replace("a", "*"))  # 'b*n*n*'
print(s.count("a"))         # 3
# Check if numeric or alphabetic
s = "abc123"
print(s.isalnum())  # True
print(s.isnumeric())  # False
print(s.isalpha())  # False
# String zfill and rjust
s = "42"
print(s.zfill(5))     # '00042'
print(s.rjust(5, "7"))  # '77742'
# Check prefix and suffix
s = "digital physics"
print(s.startswith("digi"))  # True
print(s.endswith("physics"))    # True
# Slice and Search 'in'
s = "digital physics"

print(s[:4])    # 'digi
print("digit" in s)  # True

List

# List append, extend, and pop
stack = [1, 2, 3]
stack.append(4)
print(stack.pop())  # 4
print(stack)  # [1, 2, 3]
stack.extend([11, 12, 13]) 
print(stack)  # [1, 2, 3, 11, 12, 13]
# List sort and reverse
nums = [4, 1, 3, 2]
nums.sort()
print(nums)  # [1, 2, 3, 4]
nums.reverse()
print(nums)  # [4, 3, 2, 1]
# Remove by value and find 'in'
lst = [1, 2, 3, 4]
lst.remove(3) 
print(2 in lst)  # True
print(lst)       # [1, 2, 4]
# List slicing and negative indices
nums = [0, 1, 2, 3, 4]
print(nums[:4])    # [0, 1, 2, 3]
print(nums[-2:])    # [3, 4]
print(nums[::-1])    # [4, 3, 2, 1, 0]
print(nums[::2])    # [0, 2, 4]

Dictionary

# Basics
# initialize
d = {'a': 1, 'c': 7, 'd': 'prime'}
d2 = dict()

# add
d2['a'] = 1

# delete
del d['d']

# get keys and values
print(list(d.items())) # [('a', 1), ('c', 7)]
print(list(d2.items())) # [('a', 1)]

# convert the iterables to lists
print(list(d.keys())) # ['a', 'c']
print(list(d.values())) # [1, 7]
# Get value with default 
d = {'a': 1}

# get value
print(d['a']) # 1

# get value with default value (see defaultdict as well)
print(d.get('a', 0))  # 1
print(d.get('b', 0))  # 0

Set

# Set operations
a = {1, 2, 3}
b = set([2, 3, 4])
print(a & b)  # {2, 3}
print(a | b)  # {1, 2, 3, 4}
print(a - b)  # {1}
# Set add and remove
s = set()
s.add(1)
s.add(2)

s.remove(1)
print(s)  # {2}

s.discard(7)
print(s) # {2}

print(s.pop()) # 2

s.remove(7) # KeyError: 7

Enumeration

# Enumerate
fruits = ['apple', 'banana', 'cherry']
for i, fruit in enumerate(fruits):
    print(i, fruit)
# 0 apple
# 1 banana
# 2 cherry

Zip Function

# Using zip
names = ['a', 'b', 'c']
scores = [100, 90, 50]

print(zip(names, scores)) # zip object 
print(list(zip(names, scores))) # [('a', 100), ('b', 90), ('c', 50)]

for name, score in zip(names, scores):
    print(name, score)
# a 100
# b 90
# c 50

Comprehension

# Dictionary comprehension
numbers = [1, 2, 3, 4, 5]
squared_dict = {n: n**2 for n in numbers if n % 2 == 0}
print(squared_dict)  # {2: 4, 4: 16}
# Set comprehension
words = ["hello", "world", "hello", "python"]
unique_lengths = {len(word) for word in words}
print(unique_lengths)  # {5, 6}
# Nested list comprehension
matrix = [[1, 2, 3], [4, 5, 6]]
flattened = [num for row in matrix for num in row]
print(flattened)  # [1, 2, 3, 4, 5, 6]
# Generator comprehension
numbers = (x**2 for x in range(5))
print(sum(numbers))  # 30
print(type(numbers))  # class 'generator' 
# List comprehension with filtering
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [x for x in numbers if x % 2 == 0]
squares_of_odds = [x**2 for x in numbers if x % 2 == 1]
print(evens)  # [2, 4, 6, 8, 10]
print(squares_of_odds)  # [1, 9, 25, 49, 81]
# Multiple conditions in comprehensions
data = [("Alice", 85, "A"), ("Bob", 92, "A"), ("Charlie", 76, "B")]
high_achievers = [name for name, score, grade in data if score > 80 and grade == "A"]
print(high_achievers)  # ['Alice', 'Bob']

# Nested comprehension with condition
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_evens = [num for row in matrix for num in row if num % 2 == 0]
print(flattened_evens)  # [2, 4, 6, 8]
# Dict comprehension with if else conditional values
temperatures = {"Mon": 75, "Tue": 68, "Wed": 82, "Thu": 71}
comfort_levels = {day: "warm" if temp > 75 else "cool" for day, temp in temperatures.items()}
print(comfort_levels)  # {'Mon': 'cool', 'Tue': 'cool', 'Wed': 'warm', 'Thu': 'cool'}

# Complex conditional transformation
people = [("Alice", 25), ("Bob", 17), ("Charlie", 30)]
status = {name: "adult" if age >= 18 else "minor" for name, age in people}
print(status)  # {'Alice': 'adult', 'Bob': 'minor', 'Charlie': 'adult'}
# Combining filtering and conditional transformation
numbers = [-3, -1, 0, 2, 4, -2, 5]
# Only process positive numbers, square them if even, cube if odd
result = [x**2 if x % 2 == 0 else x**3 for x in numbers if x > 0]
print(result)  # [4, 16, 125]

# Set comprehension with conditional values
words = ["apple", "banana", "cherry", "date"]
modified = {word.upper() if len(word) > 5 else word.lower() for word in words}
print(modified)  # {'apple', 'BANANA', 'CHERRY', 'date'}

Variable Assignment with If Else

# Ternary operator
age = 25
status = "adult" if age >= 18 else "minor"
print(status)  # adult
# Nested ternary operators
score = 85
grade = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "F"
print(grade)  # B

# With function calls
numbers = [1, 2, 3, 4, 5]
result = max(numbers) if numbers else 0
print(result)  # 5
# Ternary in list/dict assignments
temperature = 75
clothing = ["shorts", "t-shirt"] if temperature > 70 else ["pants", "jacket"]
print(clothing)  # ['shorts', 't-shirt']

weather_config = {"AC": "on"} if temperature > 75 else {"heater": "on"}
print(weather_config)  # {'heater': 'on'}

Loop Control

# Break and continue in nested loops
for i in range(3):
    for j in range(3):
        if i == 1 and j == 1:
            continue
        if i == 2:
            break
        print(f"({i}, {j})")
# (0, 0), (0, 1), (0, 2), (1, 0), (1, 2)
# Loop with else clause
for i in range(3):
    if i == 5:  # Never true
        break
else:
    print("Loop completed normally")  # This prints

for i in range(3):
    if i == 1:
        break
else:
    print("This won't print")
# While loop with break/continue
count = 0
while count < 10:
    count += 1
    if count % 2 == 0:
        continue
    if count > 7:
        break
    print(count)  # Prints 1, 3, 5, 7

Unpacking with * and **

# Basic tuple/list unpacking
point = (3, 4)
x, y = point
print(x + y)  # 7

coordinates = [10, 20, 30]
x, y, z = coordinates
print(f"x={x}, y={y}, z={z}")  # x=10, y=20, z=30
# * unpacking in function calls
def add_three(a, b, c):
    return a + b + c

numbers = [1, 2, 3]
result = add_three(*numbers)  # Same as add_three(1, 2, 3)
print(result)  # 6
# * unpacking for collecting remaining values
data = [1, 2, 3, 4, 5]
first, *middle, last = data
print(f"first: {first}")    # first: 1
print(f"middle: {middle}")  # middle: [2, 3, 4]
print(f"last: {last}")      # last: 5
# * unpacking to combine iterables
list1 = [1, 2, 3]
list2 = [4, 5, 6]
tuple1 = (7, 8)

combined_list = [*list1, *list2, *tuple1]
print(combined_list)  # [1, 2, 3, 4, 5, 6, 7, 8]

combined_tuple = (*list1, *list2)
print(combined_tuple)  # (1, 2, 3, 4, 5, 6)
# ** unpacking dictionaries in function calls
def greet(name, age, city):
    return f"Hello {name}, age {age}, from {city}"

person = {"name": "Alice", "age": 25, "city": "NYC"}
message = greet(**person)  # Same as greet(name="Alice", age=25, city="NYC")
print(message)
# ** unpacking to merge dictionaries
dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
dict3 = {"e": 5}

merged = {**dict1, **dict2, **dict3}
print(merged)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

# Override values
override = {**dict1, "b": 99, **dict2}
print(override)  # {'a': 1, 'b': 99, 'c': 3, 'd': 4}
# *args and **kwargs in function definitions REPACK
# new args tuple and kwargs dictionary are available for internal use
def flexible_func(*args, **kwargs):
    print(f"Positional args: {args}")
    print(f"Keyword args: {kwargs}")

flexible_func(1, 2, 3, name="Alice", age=25)
# Positional args: (1, 2, 3)
# Keyword args: {'name': 'Alice', 'age': 25}
# Unpacking with enumerate and zip
data = ['a', 'b', 'c']
numbers = [1, 2, 3]

# Unpack enumerate results
for i, letter in enumerate(data):
    print(f"{i}: {letter}")

# Unpack zip results  
for letter, num in zip(data, numbers):
    print(f"{letter} = {num}")  # a = 1, b = 2, c = 3
# Advanced unpacking patterns
# Ignore values with *_
numbers = [1, 2, 3, 4, 5, 6]
first, second, *_ = numbers
print(f"first: {first}, second: {second}")  # first: 1, second: 2

# Multiple * unpacking in one expression
a, b = [1, 2], [3, 4]
result = [*a, 0, *b]
print(result)  # [1, 2, 0, 3, 4]
# Unpacking nested structures
nested = [(1, 2), (3, 4), (5, 6)]
for x, y in nested:
    print(f"x={x}, y={y}")

# Unpacking dictionary items
person = {"name": "Bob", "age": 30}
for key, value in person.items():
    print(f"{key}: {value}")
# Convert range to list using *
numbers = [*range(5)]
print(numbers)  # [0, 1, 2, 3, 4]

# Unpack string into characters
word = "hello"
chars = [*word]
print(chars)  # ['h', 'e', 'l', 'l', 'o']
# Unpacking in list/dict comprehensions
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers = [num for num, _ in pairs]
letters = [letter for _, letter in pairs]
print(numbers)  # [1, 2, 3]
print(letters)  # ['a', 'b', 'c']

# Create dict from unpacked pairs
result = {num: letter for num, letter in pairs}
print(result)  # {1: 'a', 2: 'b', 3: 'c'}

Math

# Absolute, maximum, minimum, infinity
a, b = -5, 3

print(abs(a))    # 5

print(max(a, b)) # 3
print(min(a, b)) # -5

print(float("inf"))
print(float("-inf"))
# Math library
import math

# Basic functions
print(math.sqrt(16))     # 4.0
print(math.pow(2, 3))    # 8.0
print(math.ceil(4.3))    # 5
print(math.floor(4.7))   # 4

# Trigonometric functions
print(math.sin(math.pi/2))  # 1.0
print(math.cos(0))          # 1.0
print(math.tan(math.pi/4))  # 1.0

# Logarithmic functions
print(math.log(10))      # 2.302585092994046 (natural log)
print(math.log10(100))   # 2.0 (base 10 log)
print(math.exp(1))       # 2.718281828459045 (e^1)

# Constants
print(math.pi)           # 3.141592653589793
print(math.e)            # 2.718281828459045

# Other useful functions
print(math.factorial(5)) # 120
print(math.degrees(math.pi))  # 180.0
print(math.radians(180))      # 3.141592653589793
print(math.gcd(12, 18))  # 6
print(math.lcm(4, 6))    # 12 (Python 3.9+)
print(math.isqrt(10))  # 3

Heap

# Use heapq for min-heap
import heapq

nums = [3, 1, 4, 2]
heapq.heapify(nums)
print(heapq.heappop(nums))  # 1

Datetime

# Convert string to datetime object (string parse time)
from datetime import datetime

log_time = "2025-06-05 14:32:10,124"
dt = datetime.strptime(log_time, "%Y-%m-%d %H:%M:%S,%f")
print(type(dt))  # 'class datetime.datetime'
# Convert Datetime to String (string format time)
from datetime import datetime

log_time = "2025-06-05 14:32:10,124"
dt = datetime.strptime(log_time, "%Y-%m-%d %H:%M:%S,%f")
print(dt.strftime("%b %d %Y, %I:%M %p"))  # 'Jun 05 2025, 02:32 PM'
# Time difference
from datetime import datetime, timedelta

log_time = "2025-06-05 14:32:10,124"
dt = datetime.strptime(log_time, "%Y-%m-%d %H:%M:%S,%f")
now = datetime.now()
elapsed = now - dt
print("Seconds since log:", elapsed.total_seconds())
print("One week from now:", now + timedelta(days=7))
# Parse different date formats
from datetime import datetime

dates = [
    "2025-06-05",
    "06/05/2025", 
    "Jun 5, 2025",
    "Thursday, June 5, 2025"
]
formats = ["%Y-%m-%d", "%m/%d/%Y", "%b %d, %Y", "%A, %B %d, %Y"]

for date_str, fmt in zip(dates, formats):
    dt = datetime.strptime(date_str, fmt)
    print(dt.strftime("%Y-%m-%d"))
# Timezone handling
from datetime import datetime, timezone, timedelta

utc_now = datetime.now(timezone.utc)
est = timezone(timedelta(hours=-5))
est_time = utc_now.astimezone(est)
print(f"UTC: {utc_now.strftime('%H:%M')}")
print(f"EST: {est_time.strftime('%H:%M')}")
# Custom datetime formatting
from datetime import datetime

now = datetime.now()
print(now.strftime("%A, %B %d, %Y at %I:%M %p"))
print(now.strftime("Week %U of %Y"))  # Week number
print(now.strftime("%j"))  # Day of year

Functional Tools

# Use map and lambda
nums = [1, 2, 3]
doubled = list(map(lambda x: x * 2, nums))
print(doubled)  # [2, 4, 6]
# Filter even numbers
nums = [1, 2, 3, 4]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens)  # [2, 4]

Binary and Bitwise

# Bitwise operations
a = 5  # 0b101
b = 3  # 0b011
print(a & b)  # 1
print(a | b)  # 7
print(a ^ b)  # 6
print(a << 1) # 10
print(a >> 1) # 2
# Count set bits
n = 29  # 0b11101
print(bin(n).count('1'))  # 4

Stack and Queue

# Using deque (double-ended queue) as stack and queue
from collections import deque

dq = deque()
dq.append(1)      # push to right
dq.appendleft(2)  # push to left
print(dq.pop())   # 1
print(dq.popleft())  # 2

any() and all()

# Generator expression with any() and all()
nums = [1, 3, 5, 18]

gen = (x % 2 == 1 for x in nums)
print(gen) # generator object

for bool in gen:
    print(bool) # True True True False

print(any(x % 2 == 0 for x in nums))  # True
print(any((x % 2 == 0 for x in nums)))  # True
print(all(x < 10 for x in nums))      # False

print(any([2, 4, 5]))  # True

Nested Lists; 2D Arrays

# Initialize 2D array
rows, cols = 2, 3
grid = [[0] * cols for _ in range(rows)]
print(grid)  # [[0, 0, 0], [0, 0, 0]]
# Transpose matrix
matrix = [[1, 2], [3, 4]]
transposed = list(zip(*matrix))
print(transposed)  # [(1, 3), (2, 4)]

Memoization with LRU cache

# LRU Cache with limited size showing eviction
from functools import lru_cache

# Small cache size to demonstrate eviction
@lru_cache(maxsize=3)
def expensive_computation(x):
    """Simulate an expensive computation"""
    print(f"  → Computing result for {x}")
    return x * x * x  # Cube the number

# Function to show cache info
def show_cache_info():
    info = expensive_computation.cache_info()
    print(f"Cache: hits={info.hits}, misses={info.misses}, "
          f"current_size={info.currsize}, max_size={info.maxsize}")

print("=== LRU Cache Eviction Demo ===")
print("Cache size limit: 3 items")
print()

# Fill the cache completely
print("1. Filling cache to capacity:")
for i in [1, 2, 3]:
    result = expensive_computation(i)
    print(f"   expensive_computation({i}) = {result}")
show_cache_info()
print()

# Access items to show cache hits
print("2. Accessing cached items (no computation needed):")
for i in [1, 2, 3]:
    result = expensive_computation(i)
    print(f"   expensive_computation({i}) = {result} (cached)")
show_cache_info()
print()

# Add new item - should evict least recently used (1)
print("3. Adding new item (will evict LRU item):")
result = expensive_computation(4)
print(f"   expensive_computation(4) = {result}")
show_cache_info()
print()

# Try to access evicted item - should recompute
print("4. Accessing evicted item (needs recomputation):")
result = expensive_computation(1)
print(f"   expensive_computation(1) = {result}")
show_cache_info()
print()

# Clear cache
expensive_computation.cache_clear()
print("5. Cache cleared")
show_cache_info()

OrderedDict and namedtuple

# OrderedDict maintains insertion order
from collections import OrderedDict

od = OrderedDict()
od['first'] = 1
od['second'] = 2
od['third'] = 3
print(list(od.keys()))  # ['first', 'second', 'third']
# namedtuple creates tuple subclass with named fields
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 4)
print(p.x, p.y)  # 3 4
print(p._asdict())  # {'x': 3, 'y': 4}

Defaultdict and Counter

# Using defaultdict for grouping
from collections import defaultdict

groups = defaultdict(list)
words = ["bat", "tab", "cat"]
for word in words:
    groups["".join(sorted(word))].append(word)
print(groups)  # {'abt': ['bat', 'tab'], 'act': ['cat']}
# Using Counter for frequency
from collections import Counter

nums = [1, 2, 2, 3, 3, 3]
count = Counter(nums)
print(count)        # Counter({3: 3, 2: 2, 1: 1})
print(count[2])     # 2

Sorted Containers

# SortedList - maintains sorted order automatically
from sortedcontainers import SortedList

sl = SortedList([3, 1, 4, 1, 5, 9, 2, 6])
print(sl)  # SortedList([1, 1, 2, 3, 4, 5, 6, 9])

sl.add(7)
sl.add(0)
print(sl)  # SortedList([0, 1, 1, 2, 3, 4, 5, 6, 7, 9])

# Remove elements
sl.remove(1)  # Removes first occurrence
print(sl)  # SortedList([0, 1, 2, 3, 4, 5, 6, 7, 9])
# SortedDict - maintains sorted keys
from sortedcontainers import SortedDict

sd = SortedDict({'banana': 3, 'apple': 1, 'cherry': 2})
print(sd)  # SortedDict({'apple': 1, 'banana': 3, 'cherry': 2})

sd['elderberry'] = 4
sd['apricot'] = 1.5
print(sd)  # SortedDict({'apple': 1, 'apricot': 1.5, 'banana': 3, 'cherry': 2, 'elderberry': 4})

# Access by index
print(sd.peekitem(0))  # ('apple', 1)
print(sd.peekitem(-1))  # ('elderberry', 4)
# SortedSet - maintains sorted unique elements
from sortedcontainers import SortedSet

ss = SortedSet([3, 1, 4, 1, 5, 9, 2, 6])
print(ss)  # SortedSet([1, 2, 3, 4, 5, 6, 9])

ss.add(7)
ss.add(1)  # Duplicate, won't be added
print(ss)  # SortedSet([1, 2, 3, 4, 5, 6, 7, 9])

# Set operations maintain sorted order
ss2 = SortedSet([0, 2, 4, 8])
print(ss & ss2)  # SortedSet([2, 4]) - intersection
print(ss | ss2)  # SortedSet([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) - union

.sort() and sorted()

# .sort() modifies original list, sorted() returns new list
numbers = [64, 34, 25, 12, 22, 11, 90]
original = numbers.copy()

# In-place sorting
numbers.sort()
print("Original:", original)  # [64, 34, 25, 12, 22, 11, 90]
print("Sorted in-place:", numbers)  # [11, 12, 22, 25, 34, 64, 90]

# Create new sorted list
letters = ['d', 'b', 'a', 'c']
new_sorted = sorted(letters)
print("Original letters:", letters)  # ['d', 'b', 'a', 'c']
print("New sorted:", new_sorted)  # ['a', 'b', 'c', 'd']
# Sorting with reverse parameter
numbers = [5, 2, 8, 1, 9]
numbers.sort(reverse=True)
print("Descending:", numbers)  # [9, 8, 5, 2, 1]

words = ["zebra", "apple", "monkey", "cat"]
ascending = sorted(words)
descending = sorted(words, reverse=True)
print("Ascending:", ascending)  # ['apple', 'cat', 'monkey', 'zebra']
print("Descending:", descending)  # ['zebra', 'monkey', 'cat', 'apple']
# Sorting with key functions
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
students.sort(key=lambda x: x[1])  # Sort by grade
print("By grade:", students)  # [('Charlie', 78), ('Alice', 85), ('Bob', 92)]

# Sort strings by length
words = ["python", "java", "c", "javascript"]
by_length = sorted(words, key=len)
print("By length:", by_length)  # ['c', 'java', 'python', 'javascript']

# Case-insensitive sorting
mixed_case = ["Apple", "banana", "Cherry", "date"]
case_insensitive = sorted(mixed_case, key=str.lower)
print("Case-insensitive:", case_insensitive)  # ['Apple', 'banana', 'Cherry', 'date']
# Sort by custom key (length of string)
words = ["a", "abc", "ab"]
words.sort(key=len)
print(words)  # ['a', 'ab', 'abc']
# Sorting by multiple criteria
pairs = [[1, 3], [2, 2], [1, 2]]
pairs.sort(key=lambda x: (x[0], -x[1])) # first by the 0th element, then by the negative of the second element
print(pairs)  # [[1, 3], [1, 2], [2, 2]]

.reverse() and reversed()

# .reverse() modifies original list, reversed() returns iterator
numbers = [1, 2, 3, 4, 5]
original = numbers.copy()

# In-place reversal
numbers.reverse()
print("Original:", original)  # [1, 2, 3, 4, 5]
print("Reversed in-place:", numbers)  # [5, 4, 3, 2, 1]

# Create reversed iterator
letters = ['a', 'b', 'c', 'd']
reversed_iter = reversed(letters)
reversed_list = list(reversed_iter)
print("Original letters:", letters)  # ['a', 'b', 'c', 'd']
print("New reversed:", reversed_list)  # ['d', 'c', 'b', 'a']
# Using reversed() with different data types
# Reverse a string
text = "hello"
reversed_text = ''.join(reversed(text))
print("Reversed string:", reversed_text)  # olleh

# Reverse a tuple (creates list)
colors = ("red", "green", "blue")
reversed_colors = list(reversed(colors))
print("Reversed tuple:", reversed_colors)  # ['blue', 'green', 'red']
# Combining reverse with other operations
numbers = [1, 2, 3, 4, 5, 6]

# Sort then reverse
sorted_desc = sorted(numbers, reverse=True)
print("Sorted descending:", sorted_desc)  # [6, 5, 4, 3, 2, 1]

# Reverse then process
words = ["python", "java", "ruby"]
for word in reversed(words):
    print(word.upper())  # RUBY, JAVA, PYTHON

# Slice notation for reversal (alternative)
slice_reversed = numbers[::-1]
print("Slice reversed:", slice_reversed)  # [6, 5, 4, 3, 2, 1]

ord() Function and Character-Based Sorting

# Basic ord() usage - converts character to ASCII value
print(ord('A'))  # 65
print(ord('a'))  # 97
print(ord('0'))  # 48
print(ord(' '))  # 32

# Compare characters using ord()
char1, char2 = 'b', 'a'
print(f"'{char1}' comes after '{char2}':", ord(char1) > ord(char2))  # True
# Sorting names: alphabetical by first letter of first name, reverse alphabetical by first letter of last name 
names = [("John", "Smith"), ("Alice", "Johnson"), ("John", "Adams"), ("Alice", "Brown")]

# Sort by first name (ascending), then by last name (descending)
sorted_names = sorted(names, key=lambda x: (ord(x[0][0]), -ord(x[1][0])))
print("Sorted by first char of first name, then reverse by first char of last name:")
for name in sorted_names:
    print(f"{name[0]} {name[1]}")
# Alice Johnson  
# Alice Brown
# John Smith
# John Adams

Sorted Dict Operations

# Sort dict by multiple criteria
students = {'Alice': 85, 'Bob': 90, 'Charlie': 85, 'David': 92}
# Sort by grade desc, then name asc
sorted_students = dict(sorted(students.items(), key=lambda x: (-x[1], x[0])))
sorted_students2 = dict(sorted(students.items(), key=lambda x: (x[1], x[0]), reverse=True))
print(sorted_students)  # {'David': 92, 'Bob': 90, 'Alice': 85, 'Charlie': 85}
print(sorted_students2)  # {'David': 92, 'Bob': 90, 'Charlie': 85, 'Alice': 85}
# Sort nested dictionary
data = {'a': {'score': 10}, 'b': {'score': 5}, 'c': {'score': 15}}
sorted_data = dict(sorted(data.items(), key=lambda x: x[1]['score']))
print(sorted_data)  # {'b': {'score': 5}, 'a': {'score': 10}, 'c': {'score': 15}}

Type Hints

# Basic type hints
def greet(name: str, age: int) -> str:
    return f"Hello {name}, you are {age} years old"

result: str = greet("Alice", 25)
print(result)
# Complex type hints
from typing import List, Dict, Optional, Union

def process_data(items: List[int], 
                config: Dict[str, Union[str, int]], 
                debug: Optional[bool] = None) -> List[str]:
    return [str(x) for x in items]

result = process_data([1, 2, 3], {"mode": "fast", "threads": 4})
print(result)  # ['1', '2', '3']
# Generic type hints
from typing import TypeVar, Generic, List

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: List[T] = []
    
    def push(self, item: T) -> None:
        self._items.append(item)

stack = Stack[int]()
stack.push(42)

Pandas DataFrame

# Basic DataFrame operations
import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'city': ['NYC', 'LA', 'Chicago']
})
print(df.head())
print(df.info())
# DataFrame filtering and grouping
import pandas as pd

df = pd.DataFrame({
    'product': ['A', 'B', 'A', 'B'],
    'sales': [100, 150, 200, 120],
    'region': ['North', 'South', 'North', 'South']
})
filtered = df[df['sales'] > 120]
grouped = df.groupby('product')['sales'].sum()
print(grouped)
# DataFrame merge and pivot
import pandas as pd

df1 = pd.DataFrame({'id': [1, 2], 'name': ['A', 'B']})
df2 = pd.DataFrame({'id': [1, 2], 'value': [10, 20]})
merged = pd.merge(df1, df2, on='id')
print(merged)

NumPy Arrays

# Basic NumPy operations
import numpy as np

arr = np.array([1, 2, 3, 4, 5])
print(arr * 2)  # [2 4 6 8 10]
print(arr.mean())  # 3.0
print(arr.reshape(5, 1).shape)  # (5, 1)
# NumPy array creation and indexing
import numpy as np

zeros = np.zeros((2, 3))
ones = np.ones(5)
linspace = np.linspace(0, 10, 5)
print(linspace)  # [0. 2.5 5. 7.5 10.]
# NumPy mathematical operations
import numpy as np

arr = np.array([[1, 2], [3, 4]])
print(np.sum(arr, axis=0))  # [4 6]
print(np.dot(arr, arr))  # Matrix multiplication

Regular Expressions

# Basic regex patterns
import re

text = "Contact us at john@email.com or call 555-123-4567"
emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
phones = re.findall(r'\d{3}-\d{3}-\d{4}', text)
print(emails)  # ['john@email.com']
print(phones)  # ['555-123-4567']
# Regex groups and substitution
import re

text = "Date: 2025-06-05"
match = re.search(r'(\d{4})-(\d{2})-(\d{2})', text)
if match:
    year, month, day = match.groups()
    print(f"Year: {year}, Month: {month}, Day: {day}")

new_text = re.sub(r'\d{4}-\d{2}-\d{2}', 'REDACTED', text)
print(new_text)  # Date: REDACTED
# Regex compile and flags
import re

pattern = re.compile(r'hello', re.IGNORECASE)
text = "Hello World, HELLO Python"
matches = pattern.findall(text)
print(matches)  # ['Hello', 'HELLO']

Itertools

# Combinations and permutations
from itertools import combinations, permutations

items = ['A', 'B', 'C']
print(list(combinations(items, 2)))  # [('A', 'B'), ('A', 'C'), ('B', 'C')]
print(list(permutations(items, 2)))  # [('A', 'B'), ('A', 'C'), ('B', 'A'), ...]
# Groupby and chain
from itertools import groupby, chain

data = [1, 1, 2, 2, 2, 3]
grouped = [(k, list(g)) for k, g in groupby(data)]
print(grouped)  # [(1, [1, 1]), (2, [2, 2, 2]), (3, [3])]

nested = [[1, 2], [3, 4], [5]]
flattened = list(chain.from_iterable(nested))
print(flattened)  # [1, 2, 3, 4, 5]
# Cycle and islice
from itertools import cycle, islice

colors = cycle(['red', 'green', 'blue'])
first_10 = list(islice(colors, 10))
print(first_10[:6])  # ['red', 'green', 'blue', 'red', 'green', 'blue']

OS Module

# OS path operations
import os

current_dir = os.getcwd()
print(f"Current directory: {current_dir}")

path = os.path.join("folder", "subfolder", "file.txt")
print(f"Joined path: {path}")
print(f"Directory: {os.path.dirname(path)}")
print(f"Filename: {os.path.basename(path)}")
# Environment variables
import os

# Get environment variable with default
home = os.getenv('HOME', '/default/home')
print(f"Home directory: {home}")

# Set environment variable
os.environ['MY_VAR'] = 'Hello World'
print(os.environ.get('MY_VAR'))
# File system operations
import os

# Check if path exists
if os.path.exists('.'):
    print("Current directory exists")

# List directory contents
try:
    files = os.listdir('.')
    print(f"Files in current dir: {len(files)}")
except PermissionError:
    print("Permission denied")

Sys Module

# System information
import sys

print(f"Python version: {sys.version}")
print(f"Platform: {sys.platform}")
print(f"Max integer: {sys.maxsize}")
print(f"Python path: {sys.path[0]}")
# Command line arguments
import sys

print(f"Script name: {sys.argv[0] if sys.argv else 'N/A'}")
print(f"Arguments: {sys.argv[1:] if len(sys.argv) > 1 else 'None'}")

# Exit with status code
# sys.exit(0)  # Uncomment to exit
# Memory and recursion limits
import sys

print(f"Recursion limit: {sys.getrecursionlimit()}")
# sys.setrecursionlimit(2000)  # Increase limit

# Reference counting (CPython specific)
a = []
print(f"Reference count: {sys.getrefcount(a)}")

JSON Operations

# JSON serialization and deserialization
import json

data = {'name': 'Alice', 'age': 30, 'hobbies': ['reading', 'coding']}
json_str = json.dumps(data, indent=2)
print(json_str)

parsed_data = json.loads(json_str)
print(parsed_data['name'])  # Alice
# JSON with custom encoder
import json
from datetime import datetime

class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

data = {'timestamp': datetime.now(), 'message': 'Hello'}
json_str = json.dumps(data, cls=DateTimeEncoder)
print(json_str)

File Operations

# Basic file operations with context manager
with open('temp.txt', 'w') as f:
    f.write('Hello World\n')
    f.write('Python is awesome!')

with open('temp.txt', 'r') as f:
    content = f.read()
    print(content)
# Reading file line by line
with open('temp.txt', 'w') as f:
    f.write('Line 1\nLine 2\nLine 3')

with open('temp.txt', 'r') as f:
    for i, line in enumerate(f, 1):
        print(f"Line {i}: {line.strip()}")
# File operations with error handling
try:
    with open('nonexistent.txt', 'r') as f:
        content = f.read()
except FileNotFoundError:
    print("File not found!")
except PermissionError:
    print("Permission denied!")
finally:
    print("File operation completed")

Random Module

# Random numbers and choices
import random

print(random.randint(1, 10))  # Random integer between 1-10
print(random.random())        # Random float between 0-1
print(random.uniform(1.5, 10.5))  # Random float in range

colors = ['red', 'green', 'blue']
print(random.choice(colors))  # Random choice from list
# Random sampling and shuffling
import random

numbers = list(range(1, 11))
sample = random.sample(numbers, 3)
print(f"Sample: {sample}")

random.shuffle(numbers)
print(f"Shuffled: {numbers[:5]}")  # First 5 elements
# Random with seed for reproducibility
import random

random.seed(42)
print(random.randint(1, 100))  # Always same result with seed 42

# Generate random string
import string
random_str = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
print(f"Random string: {random_str}")

Enums

# Basic enum usage
from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

print(Color.RED)           # Color.RED
print(Color.RED.name)      # RED
print(Color.RED.value)     # 1
print(Color(2))            # Color.GREEN

def enum_type_func(input: Color) -> str:
    """the input type is not a plain, unspecific str or int, but a specifically enumerated type"""
    if isinstance(input, Color):
        return f"Valid color: {input.name}"
    return "Invalid input"
# String enums and auto values
from enum import Enum, auto

class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"

class Priority(Enum):
    LOW = auto()
    MEDIUM = auto()
    HIGH = auto()

print(Status.PENDING.value)  # pending
print(Priority.HIGH.value)   # 3
# Functional enum and iteration
from enum import Enum

# Functional API
Animal = Enum('Animal', 'CAT DOG BIRD')
print(Animal.CAT)  # Animal.CAT

# Iterating through enum members
class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3

for day in Day:
    print(f"{day.name}: {day.value}")

Type Conversions

# Basic type conversions
# String to other types
num_str = "42"
print(int(num_str))      # 42
print(float(num_str))    # 42.0
print(list(num_str))     # ['4', '2']

# Number to string
number = 123
print(str(number))       # "123"
print(f"{number}")       # "123" (f-string)
# Collection conversions
# String to list/tuple/set
text = "hello"
print(list(text))        # ['h', 'e', 'l', 'l', 'o']
print(tuple(text))       # ('h', 'e', 'l', 'l', 'o')
print(set(text))         # {'h', 'e', 'l', 'o'}

# List to other collections
numbers = [1, 2, 3, 2, 1]
print(tuple(numbers))    # (1, 2, 3, 2, 1)
print(set(numbers))      # {1, 2, 3} - removes duplicates
# Advanced conversions with error handling
def safe_convert(value, target_type):
    try:
        return target_type(value)
    except (ValueError, TypeError) as e:
        return f"Conversion failed: {e}"

print(safe_convert("123", int))      # 123
print(safe_convert("abc", int))      # Conversion failed: invalid literal...
print(safe_convert([1,2,3], str))    # [1, 2, 3]

# Join list to string
words = ["hello", "world", "python"]
print(" ".join(words))               # hello world python

Mutable vs Immutable

# Dangerous default mutable argument
def bad_append(item, target_list=[]):  # DON'T DO THIS!
    target_list.append(item)
    return target_list

print(bad_append(1))      # [1]
print(bad_append(2))      # [1, 2] - Unexpected!
print(bad_append(3))      # [1, 2, 3] - Still growing!

# Correct way with None default
def good_append(item, target_list=None):
    if target_list is None:
        target_list = []
    target_list.append(item)
    return target_list
# Immutable types cannot be modified in place
# Strings are immutable
text = "hello"
original_id = id(text)
text += " world"         # Creates new string object
print(f"ID changed: {id(text) != original_id}")  # True

# Tuples are immutable
coords = (1, 2)
# coords[0] = 3  # This would raise TypeError

# But tuple with mutable elements
nested = ([1, 2], [3, 4])
nested[0].append(3)      # This works - modifying list inside tuple
print(nested)            # ([1, 2, 3], [3, 4])
# Mutable objects and assignment behavior
# Lists are mutable
original_list = [1, 2, 3]
same_list = original_list        # Same object reference
copy_list = original_list.copy() # New object

original_list.append(4)
print(f"Original: {original_list}")  # [1, 2, 3, 4]
print(f"Same ref: {same_list}")      # [1, 2, 3, 4] - Modified too!
print(f"Copy: {copy_list}")          # [1, 2, 3] - Unchanged

# Checking object identity
print(f"Same object: {original_list is same_list}")  # True
print(f"Different object: {original_list is copy_list}")  # False

Pytest Examples

# Basic pytest test functions
def add(a, b):
    return a + b

def test_add():
    assert add(2, 3) == 5
    assert add(-1, 1) == 0
    assert add(0, 0) == 0

def test_add_strings():
    assert add("hello", "world") == "helloworld"
# Pytest fixtures and parametrize
import pytest

@pytest.fixture
def sample_data():
    return [1, 2, 3, 4, 5]

@pytest.mark.parametrize("input,expected", [
    (2, 4),
    (3, 9),
    (4, 16)
])
def test_square(input, expected):
    assert input ** 2 == expected
# Pytest exception testing
import pytest

def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

def test_divide_by_zero():
    with pytest.raises(ValueError, match="Cannot divide by zero"):
        divide(10, 0)

Unittest Examples

# Basic unittest class
import unittest

class Calculator:
    def add(self, a, b):
        return a + b

class TestCalculator(unittest.TestCase):
    def setUp(self):
        self.calc = Calculator()
    
    def test_add(self):
        self.assertEqual(self.calc.add(2, 3), 5)
        self.assertNotEqual(self.calc.add(2, 3), 6)

# Run the tests
test = TestCalculator()
test.setUp()
test.test_add()
print("All tests passed!")
# Unittest assertions and mocking
import unittest
from unittest.mock import patch, MagicMock

class TestWithMock(unittest.TestCase):
    def test_with_mock(self):
        mock_obj = MagicMock()
        mock_obj.method.return_value = 42
        
        result = mock_obj.method()
        self.assertEqual(result, 42)
        mock_obj.method.assert_called_once()

# Run the tests
test = TestWithMock()
test.test_with_mock()
print("All tests passed!")
# Unittest with setUp and tearDown
import unittest

class TestLifecycle(unittest.TestCase):
    def setUp(self):
        self.data = [1, 2, 3]
    
    def tearDown(self):
        self.data.clear()
    
    def test_data_length(self):
        self.assertEqual(len(self.data), 3)
        
    def test_data_content(self):
        self.assertIn(2, self.data)

# Run the tests
test = TestLifecycle()
test.setUp()
test.test_data_length()
test.test_data_content()
test.tearDown()
print("All tests passed!")

Exception Handling

# Basic try/except/finally
try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
else:
    print("No exceptions occurred")
finally:
    print("This always runs")
# Multiple exception types
try:
    data = {"key": "value"}
    result = data["missing_key"]
    number = int("not_a_number")
except (KeyError, ValueError) as e:
    print(f"Expected error: {e}")
except Exception as e:
    print(f"Unexpected: {e}")
# Raising custom exceptions
class CustomError(Exception):
    pass

def validate_age(age):
    if age < 0:
        raise CustomError("Age cannot be negative")
    return age

try:
    validate_age(-5)
except CustomError as e:
    print(f"Validation error: {e}")

Classes and Objects

# Basic class with inheritance
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

dog = Dog("Buddy")
print(dog.speak())  # Buddy says Woof!
# Class with properties and methods
class Circle:
    def __init__(self, radius):
        self._radius = radius
    
    @property
    def radius(self):
        return self._radius
    
    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("Radius must be positive")
        self._radius = value
    
    @property
    def area(self):
        return 3.14159 * self._radius ** 2

circle = Circle(5)
print(f"Area: {circle.area:.2f}")  # Area: 78.54
# Class methods and static methods
class MathUtils:
    pi = 3.14159
    
    @classmethod
    def circle_area(cls, radius):
        return cls.pi * radius ** 2
    
    @staticmethod
    def add(a, b):
        return a + b

print(MathUtils.circle_area(3))  # 28.27
print(MathUtils.add(5, 7))       # 12

Context Managers

# Custom context manager
class MyContext:
    def __enter__(self):
        print("Entering context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting context")
        return False  # Don't suppress exceptions

with MyContext() as ctx:
    print("Inside context")
# Output: Entering context, Inside context, Exiting context
# Context manager with exception handling
class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"Exception occurred: {exc_val}")
        return True  # Suppress exceptions

with SafeContext():
    print("This works")
    # raise ValueError("Test error")  # Would be suppressed

Decorators

# Simple decorator
def timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.time() - start:.4f} seconds")
        return result
    return wrapper

@timer
def slow_function():
    import time
    time.sleep(0.1)
    return "Done"

result = slow_function()  # Prints timing info
# Decorator with parameters
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")  # Prints greeting 3 times
# Multiple decorators
def bold(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return f"{result}"
    return wrapper

def italic(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return f"{result}"
    return wrapper

@bold
@italic
def format_text(text):
    return text

print(format_text("Hello"))  # Hello

Lambda Functions and Closures

# Lambda with sorted and filter
students = [('Alice', 85), ('Bob', 90), ('Charlie', 78)]
sorted_by_grade = sorted(students, key=lambda x: x[1])
high_scores = list(filter(lambda x: x[1] > 80, students))
print(sorted_by_grade)  # [('Charlie', 78), ('Alice', 85), ('Bob', 90)]
print(high_scores)      # [('Alice', 85), ('Bob', 90)]
# Closure example
def make_multiplier(factor):
    def multiplier(number):
        return number * factor
    return multiplier

double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5))  # 10
print(triple(5))  # 15
# Lambda in comprehensions
numbers = [1, 2, 3, 4, 5]
operations = [lambda x, n=n: x * n for n in range(1, 4)]
results = [op(5) for op in operations]
print(results)  # [5, 10, 15]

Boolean Logic and Truthiness

# Truthiness examples
falsy_values = [False, 0, 0.0, '', [], {}, None]
truthy_values = [True, 1, 'hello', [1], {'a': 1}]

print(all(falsy_values))   # False
print(any(truthy_values))  # True
print(any(falsy_values))   # False
print(all(truthy_values))  # True
# Short-circuit evaluation
x = None
result = x and x.upper()  # Won't raise AttributeError
print(result)  # None

y = "hello"
result = y and y.upper()  # Will execute y.upper()
print(result)  # HELLO
# Boolean operators with non-boolean values
a = [] or [1, 2, 3]        # [1, 2, 3]
b = "hello" and "world"    # "world"
c = 0 or 5 or 10          # 5
d = "test" and [] or "fallback"  # "fallback"
print(a, b, c, d)

Variable Scope

# Global and nonlocal keywords
count = 0  # Global

def outer():
    count = 10  # Local to outer
    
    def inner():
        nonlocal count
        count += 1
        print(f"Inner count: {count}")
    
    inner()
    return count

print(f"Outer result: {outer()}")  # 11
print(f"Global count: {count}")    # 0
# Global variable modification
counter = 0

def increment():
    global counter
    counter += 1
    return counter

print(increment())  # 1
print(increment())  # 2
print(counter)      # 2

Import Variations

# Different import styles
import math
from math import sqrt, pi
from collections import Counter as C
import json as js

print(math.sqrt(16))  # 4.0
print(sqrt(25))       # 5.0
print(pi)            # 3.141592653589793
counter = C([1, 1, 2, 3])
print(counter)       # Counter({1: 2, 2: 1, 3: 1})
# Conditional imports
try:
    import numpy as np
    has_numpy = True
except ImportError:
    has_numpy = False
    print("NumPy not available")

if has_numpy:
    arr = np.array([1, 2, 3])
    print(f"NumPy array: {arr}")
else:
    arr = [1, 2, 3]
    print(f"Regular list: {arr}")

Walrus Operator (Python 3.8+)

# Assignment expressions
numbers = [1, 2, 3, 4, 5]
if (n := len(numbers)) > 3:
    print(f"List has {n} items")

# In while loop
data = [1, 2, 3, 4, 5]
while (item := data.pop() if data else None) is not None:
    print(f"Processing: {item}")
    if item == 2:
        break
# Walrus in list comprehension
data = ['hello', 'world', 'python', 'code']
long_words = [(word, length) for word in data if (length := len(word)) > 4]
print(long_words)  # [('hello', 5), ('world', 5), ('python', 6)]

# Walrus with regex
import re
text = "Phone: 123-456-7890"
if (match := re.search(r'\d{3}-\d{3}-\d{4}', text)):
    print(f"Found phone: {match.group()}")

Match Statement (Python 3.10+)

# Pattern matching
def handle_data(data):
    match data:
        case int() if data > 0:
            return f"Positive integer: {data}"
        case str() if len(data) > 0:
            return f"Non-empty string: {data}"
        case []:
            return "Empty list"
        case [x] if isinstance(x, int):
            return f"List with one integer: {x}"
        case _:
            return "Unknown data type"

print(handle_data(42))        # Positive integer: 42
print(handle_data("hello"))   # Non-empty string: hello
print(handle_data([]))        # Empty list
# Complex pattern matching
def process_point(point):
    match point:
        case (0, 0):
            return "Origin"
        case (0, y):
            return f"On Y-axis at {y}"
        case (x, 0):
            return f"On X-axis at {x}"
        case (x, y) if x == y:
            return f"On diagonal at ({x}, {y})"
        case (x, y):
            return f"Point at ({x}, {y})"

print(process_point((0, 0)))   # Origin
print(process_point((3, 3)))   # On diagonal at (3, 3)
print(process_point((1, 2)))   # Point at (1, 2)

F-string Advanced Formatting

# Advanced f-string formatting
name = "Alice"
score = 87.6789
width = 10

print(f"{name:>10}")        # Right align: '     Alice'
print(f"{name:<10}")        # Left align: 'Alice     '
print(f"{name:^10}")        # Center align: '  Alice   '
print(f"{score:.2f}")       # 87.68
print(f"{score:0{width}.2f}")  # 0000087.68
# F-string with expressions and formatting
numbers = [1234567, 9876543]
for num in numbers:
    print(f"{num:,}")           # Thousands separator
    print(f"{num:_}")           # Underscore separator
    print(f"{num:>15,}")        # Right align with commas

percentage = 0.847
print(f"{percentage:.1%}")      # 84.7%
print(f"{percentage:.2%}")      # 84.70%
# F-string with conditional expressions
debug = True
name = "Alice"
score = 95

print(f"{'Debug:' if debug else ''} {name} scored {score}")
print(f"{name} {'passed' if score >= 60 else 'failed'}")

# F-string with datetime
from datetime import datetime
now = datetime.now()
print(f"Current time: {now:%Y-%m-%d %H:%M:%S}")
print(f"Date: {now:%B %d, %Y}")

Chained Comparisons

# Multiple comparisons
x = 5
if 0 < x < 10:
    print("x is between 0 and 10")

age = 25
if 18 <= age < 65:
    print("Working age")

# Chained equality
a = b = c = [1, 2, 3]  # All reference same list
if a is b is c:
    print("All variables reference the same object")
# Complex chained comparisons
score = 85
if 80 <= score < 90:
    grade = 'B'
elif 90 <= score <= 100:
    grade = 'A'
else:
    grade = 'C'

print(f"Score {score} is grade {grade}")

# Multiple conditions
temperature = 72
humidity = 45
if 68 <= temperature <= 78 and 30 <= humidity <= 50:
    print("Ideal conditions")

Generators

# Generator function
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# Get first 10 fibonacci numbers
fib = fibonacci()
first_10 = [next(fib) for _ in range(10)]
print(first_10)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# Generator with yield from
def count_up_to(max_count):
    count = 1
    while count <= max_count:
        yield count
        count += 1

def count_and_repeat(max_count, repeat_times):
    for _ in range(repeat_times):
        yield from count_up_to(max_count)

result = list(count_and_repeat(3, 2))
print(result)  # [1, 2, 3, 1, 2, 3]

Assertions

# Basic assertions
def divide(a, b):
    assert b != 0, "Division by zero is not allowed"
    return a / b

result = divide(10, 2)
print(result)  # 5.0

# This would raise AssertionError
# divide(10, 0)
# Assertions for debugging
def process_list(items):
    assert isinstance(items, list), "Input must be a list"
    assert len(items) > 0, "List cannot be empty"
    
    result = []
    for item in items:
        assert isinstance(item, (int, float)), f"Item {item} must be a number"
        result.append(item * 2)
    
    return result

numbers = [1, 2, 3, 4]
doubled = process_list(numbers)
print(doubled)  # [2, 4, 6, 8]

Dynamic Function Execution

# Global Namespace Function Execution
def run_functions(function_list):
    function_name = function_list[0]
    args = function_list[1:]
    
    if function_name in globals():
        return globals()[function_name](*args)
    else: # 'riskier' alternative way
        # be careful with exposing an eval() function that can run anything to a user
        function = eval(function_name)
        return function(*args)

# Built-in and custom functions
def add(a, b):
    return a + b

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

# Execute various functions
operations = [
    ['len', 'hello world'],
    ['max', 5, 3, 8, 1], 
    ['add', 10, 5],
    ['greet', 'Alice', 'Hi']
]

for op in operations:
    result = run_functions(op)
    print(f"{op[0]}{tuple(op[1:])} = {result}")
# len('hello world',) = 11
# max(5, 3, 8, 1) = 8
# add(10, 5) = 15
# greet('Alice', 'Hi') = Hi, Alice!
# Object and Module Methods
import math

def run_methods_on_object(obj, method_list):
    method_name = method_list[0]
    args = method_list[1:]
    method = getattr(obj, method_name)
    return method(*args)

# Working with objects
my_list = [1, 2, 3]
run_methods_on_object(my_list, ['append', 4])
run_methods_on_object(my_list, ['extend', [5, 6]])
count = run_methods_on_object(my_list, ['count', 2])

print(my_list)  # [1, 2, 3, 4, 5, 6]
print(count)    # 1

standard_lib_ops = [
    ['math.sqrt', 16],
    ['math.pow', 2, 3]
]

for op in standard_lib_ops:
    result = eval(f"{op[0]}{tuple(op[1:])}")
    print(f"{op[0]}{tuple(op[1:])} = {result}")
# math.sqrt(16,) = 4.0
# math.pow(2, 3) = 8.0
# Dynamic Method Calling with 'Has Attribute' and 'Get Attribute'
class DataProcessor:
    def __init__(self):
        self.data = []
    
    def execute_operation(self, method_list):
        """Execute method on self using the method list format"""
        method_name = method_list[0]
        args = method_list[1:]
        
        # Handle self.method_name
        if method_name.startswith('self.'):
            method_name = method_name[5:]
        
        if hasattr(self, method_name):
            method = getattr(self, method_name)
            return method(*args)
        else:
            return None
    
    def add_data(self, *elements):
        self.data.extend(elements)
        return len(self.data)
    
    def get_sum(self):
        return sum(self.data)

processor = DataProcessor()
commands = [
    ['self.add_data', 1, 2, 3, 4],
    ['self.get_sum'],
    ['self.digital_physics'],
    ['add_data', 5, 6],  # Works with or without 'self.'
    ['get_sum']
]

for cmd in commands:
    result = processor.execute_operation(cmd)
    print(f"{cmd[0]}{tuple(cmd[1:]) if len(cmd) > 1 else '()'} = {result}")

# self.add_data(1, 2, 3, 4) = 4
# self.get_sum() = 10
# self.digital_physics() = None
# add_data(5, 6) = 6
# get_sum() = 21
Bugs, Questions, Requests, Comments, etc.: jdkhanlian@gmail.com