About this page: The page allows changing SyntaxHiglighter and Theme.
The Engine options are - Esm Shiki and Highlight.js via CDNJS and Cloudflare

Python cheatsheet

Shell commands

$ python -m pip install requests

$ python -m pip freeze > requirements.txt
$ python -m pip install -r requirements.txt
                        

$ python -m venv .venv  # Creates a virtual environment
$ source .venv/bin/activate
(.venv) $ deactivate

Basic Python

repeat = "Meow!" * 3            # "Meow!Meow!Meow!"]
" a ".strip()                   # "a"
str.lstrip()
str.rstrip()
"abc".replace("bc", "ha")       # "aha"
"a b".split()                   # ["a", "b"]
" ".join(["Hello", "World"])    # results in "Hello World"

text = "Python"
text[0]      # "P" (first)
text[-1]     # "n" (last)
text[:-2]    # "Pyth" (remove last two)
text[1:4]    # "yth" (slice)
text[:3]     # "Pyt" (from start)
text[3:]     # "hon" (to end)
text[::2]    # "Pto" (every 2nd)
text[::-1]   # "nohtyP" (reverse)

str.split(",")
str=str.rsplit(".", 1)[0] # split the string one time, begining from
    # right. Return the first part.
    # This will remove file extension.

str.find(",")  # the lowest index where the substring is found, or -1
str.index(",") # same, but raises IndexError
str.count(",")

str.lower()
str.upper()
str.title()

# Format method
template = "Hello, {name}! You're {age}."
template.format(name="Aubrey", age=2)    # "Hello, Aubrey! You're 2."

>>> f'{-12345:0=10}'  # negative numbers
'-000012345'
>>> f'{12345:010}'    # [0] shortcut (no align)
'0000012345'
>>> f'{-12345:010}'
'-000012345'
>>> import math       # [.precision]
>>> math.pi
3.141592653589793
>>> f'{math.pi:.2f}'
'3.14'
>>> f'{1000000:,.2f}' # [grouping_option]
'1,000,000.00'
>>> f'{1000000:_.2f}'
'1_000_000.00'
>>> f'{0.25:0%}'      # percentage
'25.000000%'
>>> f'{0.25:.0%}'
'25%'
>>> f'{12345:+}'      # [sign] (+/-)
'+12345'
>>> f'{-12345:+}'
'-12345'
>>> f'{-12345:+10}'
'    -12345'
>>> f'{-12345:+010}'
'-000012345'

# Loop through range
for i in range(5):      # 0, 1, 2, 3, 4
    print(i)

# With enumerate for index
fruits = ["apple", "banana"]
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")

square = lambda x: x**2
result = square(5)  # 25

# With map and filter
numbers = [1, 2, 3, 4]
squared_dict = map(x: x**2, numbers)

even_numbers = list(filter(x: x % 2 == 0, numbers))

(lambda x: x > 2)(3)  # => True

(lambda x, y: x ** 2 + y ** 2)(2, 1)  # => 5

class Dog:
  def __init__(self, name, age): # the constructor
    self.name = name
    self.age = age

  def bark(self):
    return f"{self.name} says Woof!" # self - refers to the instance

# Create instance
my_dog = Dog("Frieda", 3)
print(my_dog.bark())  # Frieda says Woof!

---------------------------------------
# @classmethod
# @classmethod - transforms a standard method into a class method,
#   which is bound to the class itself rather than a specific
#   object instance.

# Example
from datetime import date

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # This is a factory method (alternative constructor)
    @classmethod
    def from_birth_year(cls, name, birth_year):
        # cls refers to the User class itself
        current_year = date.today().year
        age = current_year - birth_year
        return cls(name, age)  # Instantiates and returns a new User

# Standard instantiation
user1 = User("Alice", 30)

# Creating a user using the class method
user2 = User.from_birth_year("Bob", 1995)

print(f"{user2.name} is {user2.age} years old.")
--------------------------------------

# Inheritance
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

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

# Positional
def varargs(*args):
    return args

varargs(1, 2, 3)  # => (1, 2, 3)

# ---------------------------------
# Keyword arguments
def keyword_args(**kwargs):
    return kwargs

# => {"big": "foot", "loch": "ness"}
keyword_args(big="foot", loch="ness")

# ---------------------------------
# Default value
def add(x, y=10):
    return x + y

add(5)      # => 15
add(5, 20)  # => 25

# ---------------------------------
# Return multiple
def swap(x, y):
    return y, x

x = 1
y = 2
x, y = swap(x, y)  # => x = 2, y = 1

Advanced Python

More about Decorators
# Decorators let you add extra behavior to a function, without
# changing the function's code.
# A decorator is a function that takes another function as input
# and returns a new function.
def changecase(func):
  def myinner(*args, **kwargs):
    # *args - take all positional argumets, if any
    # **kwargs - take all named arguments, if any
    return func(*args, **kwargs).upper() # convert to upper case
  return myinner

@changecase
def myfunction(name):
  return "Hello " + name

print(myfunction("John"))

# ---------------------------------------------------------------
# Decorator With Arguments
def changecase(n):
  def changecase(func):
    def myinner():
      if n == 1:
        a = func().lower()
      else:
        a = func().upper()
      return a
    return myinner
  return changecase

@changecase(1)
def myfunction():
  return "Hello Linus"

# ---------------------------------------------------------------
# Preserving Function Metadata
# Functions have metadata, which could be accessed using the __name__
# and __doc__ attributes.
#   Example :
def myfunction():
  return "Have a great day!"

print(myfunction.__name__)

# when a function is decorated, the metadata of the original function
# is lost. To fix this, there is a built-in function called
# functools.wraps that can be used to preserve the original function's
# name and docstring
import functools

def changecase(func):
  @functools.wraps(func)
  def myinner():
    return func().upper()
  return myinner

@changecase
def myfunction():
  return "Have a great day!"

print(myfunction.__name__)

Collections

# Creating lists
empty = []
mixed = [1, "two", 3.0, True]

# List methods
nums.append("x")         # Add to end
nums.insert(0, "y")      # Insert at index 0
nums.extend(["z", 5])    # Extend with iterable
nums.remove("x")         # Remove first "x"
last = nums.pop()        # Pop returns last element

# List indexing and checks
fruits = ["banana", "apple", "orange"]
fruits[0]                # "banana"
fruits[-1]               # "orange"
"apple" in fruits        # True
len(fruits)              # 3

# Syntax
a_list[start:end]
a_list[start:end:step]

>>> a = ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[2:5]
['bacon', 'tomato', 'ham']
>>> a[-5:-2]
['egg', 'bacon', 'tomato']
>>> a[1:4]
['egg', 'bacon', 'tomato']

# ----------------------------------------------------------
# Omitting index
>>> a[:4]
['spam', 'egg', 'bacon', 'tomato']
>>> a[0:4]
['spam', 'egg', 'bacon', 'tomato']
>>> a[2:]
['bacon', 'tomato', 'ham', 'lobster']
>>> a[2:len(a)]
['bacon', 'tomato', 'ham', 'lobster']
>>> a
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[:]
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']

# ----------------------------------------------------------
# With a stride
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[0:6:2]
['spam', 'bacon', 'ham']
>>> a[1:6:2]
['egg', 'tomato', 'lobster']
>>> a[6:0:-2]
['lobster', 'tomato', 'egg']
>>> a
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[::-1]
['lobster', 'ham', 'tomato', 'bacon', 'egg', 'spam']

# Creating tuples
point = (3, 4)
single = (1,)    # Note the comma!
empty = ()

# Basic tuple unpacking
point = (3, 4)
x, y = point

# Extended unpacking
first, *rest = (1, 2, 3, 4)
first            # 1
rest             # [2, 3, 4]

# Creating Sets
a = {1, 2, 3}
b = set([3, 4, 4, 5])

# Set Operations
a | b            # {1, 2, 3, 4, 5}
a & b            # {3}
a - b            # {1, 2}
a ^ b            # {1, 2, 4, 5}

# Creating Dictionaries
empty = {}
pet = {"name": "Leo", "age": 42}

# Dictionary Operations
pet["sound"] = "Purr!"   # Add key and value
pet["age"] = 7           # Update value
pet.update({"age": 4})
age = pet.get("age", 0)  # Get with default
del pet["sound"]         # Delete key
pet.pop("age")           # Remove and return

# Dictionary Methods
pet = {"name": "Frieda", "sound": "Bark!"}
pet.keys()         # dict_keys(['name', 'sound'])
pet.values()       # dict_values(['Frieda', 'Bark!'])
pet.items()        # dict_items([('name', 'Frieda'), ('sound', 'Bark!')])

squares = [x**2 for x in range(10)]

# With condition
even_numbers = [x for x in range(20) if x % 2 == 0]

# Nested
matrix = [[i*j for j in range(3)] for i in range(3)]

# Dictionary comprehension
word_lengths = {word: len(word) for word in ["hello", "world"]}

# Set comprehension
unique_lengths = {len(word) for word in ["who", "what", "why"]}

# Generator Comprehension
  # List Comprehension (uses memory for all 1 million items)
  squares_list = [x**2 for x in range(1000000)]

  # Generator Comprehension (uses almost zero memory)
  squares_gen = (x**2 for x in range(1000000))

  print(squares_gen)

# Flatten a list of lists
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for sublist in matrix for item in sublist]

# Read an entire file
with open("file.txt", mode="r", encoding="utf-8") as file:
    content = file.read()

# Read a file line by line
with open("file.txt", mode="r", encoding="utf-8") as file:
    for line in file:
        print(line.strip())

# Write a file
with open("output.txt", mode="w", encoding="utf-8") as file:
    file.write("Hello, World!\n")

# Append to a File
with open("log.txt", mode="a", encoding="utf-8") as file:
    file.write("New log entry\n")

# --------------------------------------------------------
# Delete a file
import os
if os.path.exists("myfile.txt"):
    os.remove("myfile.txt")
else:
    print("The file does not exist

# --------------------------------------------------------
# Delete a folder
import os
os.rmdir("myfolder")

# --------------------------------------------------------
# Write a simple object
import json
contents = {"aa": 12, "bb": 21}
with open("myfile2.txt", "w+") as file:
    file.write(json.dumps(contents))

# --------------------------------------------------------
# Read a simple object
with open('myfile2.txt', "r+") as file:
    contents = json.load(file)
print(contents)

# --------------------------------------------------------
# Read/Write complex object
from pydantic import BaseModel

class VideoMetaData(BaseModel):
    title: str
    ...

@classmethod
def from_mootube_object(cls, mt: MooTube):
  """Custom factory """
  return cls(
    title = mt.title,
    ...
   )
...
meta_data = VideoMetaData.from_mootube_object(yt)
with open(json_filename, "w+") as file:
  file.write(meta_data.model_dump_json())
with open(json_filename, 'r') as f:
  meta_data = VideoMetaData.model_validate_json(f.read())

# Equivalent to Java's <> ? <> : <> operator
                                                         r = "a" if a > b else "b"

# --------------------------------
# Use zip to pack into a tuple list
words = ['Mon', 'Tue', 'Wed']
nums = [1, 2, 3]
for w, n in zip(words, nums):
    print('%d:%s, ' %(n, w))
# Prints: 1:Mon, 2:Tue, 3:Wed,

Python Advanced Data Types

Heaps are binary trees for which every parent node has a value less than or equal to any of its children. Useful for accessing min/max value quickly. Time complexity: O(n) for heapify, O(log n) push and pop.
import heapq

myList = [9, 5, 4, 1, 3, 2]
heapq.heapify(myList) # turn myList into a Min Heap
print(myList)    # => [1, 3, 2, 5, 9, 4]
print(myList[0]) # first value is always the smallest in the heap

heapq.heappush(myList, 10) # insert 10
x = heapq.heappop(myList)  # pop and return smallest item
print(x)                   # => 1

# ------------------------------------------------------
# Negate all values to use Min Heap as Max Heap
myList = [9, 5, 4, 1, 3, 2]
myList = [-val for val in myList] # multiply by -1 to negate
heapq.heapify(myList)

x = heapq.heappop(myList)
print(-x) # => 9 (making sure to multiply by -1 again)

                        

from typing import Final
ILLEGAL_CHARS: Final[str] = "()/&'.|,:"
ILLEGAL_CHAR_MAPPING: Final[dict[int, int]] = str.maketrans(
                    ILLEGAL_CHARS, "_" * len(ILLEGAL_CHARS))

# --------------------------------------------------------
# Hint the class member types
class VideoMetaData:
     def __init__(self, mt: MooTube):
        self.title: str = mt.title
        ...

# --------------------------------------------------------
# Hint the return value type
def select_audio_stream(the_streams: "StreamQuery",
        desired_resoulution: str) -> MooTube.str: