DEV Community

Cover image for COMPLETE PYTHON CHEATSHEET
CodeWithDhanian
CodeWithDhanian

Posted on

COMPLETE PYTHON CHEATSHEET

"""
COMPLETE PYTHON CHEATSHEET - PYTHON 3.12+
=============================
"""

# ===========================================
# 1. BASIC SYNTAX & SETUP
# ===========================================

# Shebang (Unix/Linux)
#!/usr/bin/env python3

# Module docstring
"""Module documentation goes here."""

# Importing modules
import math                      # Standard import
import numpy as np               # Import with alias
from datetime import datetime    # Import specific item
from pathlib import Path         # Import from module
import sys, os                   # Multiple imports

# Python version check
import sys
if sys.version_info < (3, 8):
    print("Python 3.8+ required")
    sys.exit(1)

# ===========================================
# 2. DATA TYPES & VARIABLES
# ===========================================

# Basic types
integer = 42                     # int
floating = 3.14                  # float
complex_num = 2 + 3j             # complex
boolean = True                   # bool (True/False)
none_value = None                # NoneType

# Strings
single_quotes = 'hello'
double_quotes = "world"
triple_quotes = '''multiline
string'''
f_string = f"Hello {single_quotes}"  # f-string (Python 3.6+)
raw_string = r"C:\Users\Name"    # raw string

# Collections
list_var = [1, 2, 3, 4]          # List - mutable, ordered
tuple_var = (1, 2, 3)            # Tuple - immutable, ordered
set_var = {1, 2, 3}              # Set - mutable, unordered, unique
frozenset_var = frozenset([1, 2, 3])  # Immutable set
dict_var = {'a': 1, 'b': 2}      # Dictionary - key-value pairs
bytes_var = b'hello'             # Bytes
bytearray_var = bytearray(5)     # Mutable bytes
range_var = range(10)            # Range

# Type checking
type(integer)                    # <class 'int'>
isinstance(integer, int)         # True
issubclass(bool, int)            # True (bool is subclass of int)

# Type conversion
str(42)                          # '42'
int('42')                        # 42
float('3.14')                    # 3.14
list('hello')                    # ['h', 'e', 'l', 'l', 'o']
tuple([1, 2, 3])                 # (1, 2, 3)
set([1, 2, 2, 3])                # {1, 2, 3}
dict([('a', 1), ('b', 2)])       # {'a': 1, 'b': 2}

# ===========================================
# 3. STRING OPERATIONS
# ===========================================

s = "Hello World"

# Basic operations
len(s)                           # 11
s[0]                             # 'H'
s[-1]                            # 'd'
s[0:5]                           # 'Hello'
s[6:]                            # 'World'
s[::-1]                          # 'dlroW olleH' (reverse)

# String methods
s.lower()                        # 'hello world'
s.upper()                        # 'HELLO WORLD'
s.title()                        # 'Hello World'
s.capitalize()                   # 'Hello world'
s.swapcase()                     # 'hELLO wORLD'
s.strip()                        # Remove whitespace
s.lstrip()                       # Remove left whitespace
s.rstrip()                       # Remove right whitespace

# Search and replace
s.startswith('Hello')            # True
s.endswith('World')              # True
s.find('World')                  # 6 (index)
s.rfind('l')                     # 9 (last occurrence)
s.index('World')                 # 6 (raises ValueError if not found)
s.count('l')                     # 3
s.replace('World', 'Python')     # 'Hello Python'

# Splitting and joining
s.split()                        # ['Hello', 'World']
s.split('o')                     # ['Hell', ' W', 'rld']
'-'.join(['Hello', 'World'])     # 'Hello-World'

# Checking
s.isalpha()                      # False (has space)
s.isdigit()                      # False
s.isalnum()                      # False
s.isspace()                      # False
'123'.isdigit()                  # True

# Formatting
"{} {}".format("Hello", "World") # 'Hello World'
"{1} {0}".format("World", "Hello") # 'Hello World'
"{name} is {age} years old".format(name="John", age=30)
f"Value: {integer:.2f}"         # 'Value: 42.00'
f"{integer:05d}"                # '00042'

# ===========================================
# 4. LIST OPERATIONS
# ===========================================

lst = [1, 2, 3, 4, 5]

# Accessing
lst[0]                           # 1
lst[-1]                          # 5
lst[1:3]                         # [2, 3]
lst[::2]                         # [1, 3, 5]

# Modifying
lst[0] = 10                      # [10, 2, 3, 4, 5]
lst.append(6)                    # Add to end
lst.extend([7, 8])               # Extend with another list
lst.insert(0, 0)                 # Insert at index
lst.remove(3)                    # Remove first occurrence of 3
lst.pop()                        # Remove and return last item
lst.pop(0)                       # Remove and return first item
del lst[0]                       # Delete item at index
lst.clear()                      # Remove all items

# List comprehensions
[x**2 for x in range(5)]         # [0, 1, 4, 9, 16]
[x for x in range(10) if x % 2 == 0]  # Even numbers
[(x, y) for x in [1,2] for y in [3,4]] # Cartesian product

# Operations
len(lst)                         # Length
lst + [9, 10]                    # Concatenation
[0] * 3                          # [0, 0, 0]
3 in lst                         # Membership check
lst.index(4)                     # Find index of value
lst.count(2)                     # Count occurrences

# Sorting and reversing
lst.sort()                       # In-place sort
sorted(lst)                      # New sorted list
lst.sort(reverse=True)           # Descending sort
lst.reverse()                    # Reverse in-place
reversed(lst)                    # Reverse iterator

# Built-in functions
min(lst), max(lst), sum(lst)     # Min, max, sum
any(lst), all(lst)               # Any/all true
list(enumerate(lst))             # [(0,1), (1,2), ...]
list(zip([1,2], [3,4]))          # [(1,3), (2,4)]

# ===========================================
# 5. TUPLE OPERATIONS
# ===========================================

tup = (1, 2, 3, 4, 5)

# Tuples are immutable
tup[0]                           # 1
tup[1:3]                         # (2, 3)
len(tup)                         # 5
tup.count(2)                     # Count occurrences
tup.index(3)                     # Find index

# Tuple unpacking
a, b, c = (1, 2, 3)
a, *rest = (1, 2, 3, 4)         # a=1, rest=[2,3,4]
first, *middle, last = (1,2,3,4) # first=1, middle=[2,3], last=4

# ===========================================
# 6. DICTIONARY OPERATIONS
# ===========================================

d = {'a': 1, 'b': 2, 'c': 3}

# Accessing
d['a']                           # 1
d.get('a')                       # 1
d.get('d', 0)                    # 0 (default if key not found)
d.setdefault('e', 5)             # Set default if key doesn't exist

# Modifying
d['a'] = 10                      # Update value
d.update({'d': 4, 'e': 5})       # Update multiple
del d['a']                       # Delete key
value = d.pop('b')               # Remove and return value
d.popitem()                      # Remove and return last (k,v) pair
d.clear()                        # Remove all items

# Views
d.keys()                         # dict_keys(['a', 'b', 'c'])
d.values()                       # dict_values([1, 2, 3])
d.items()                        # dict_items([('a', 1), ('b', 2)])

# Dictionary comprehensions
{x: x**2 for x in range(5)}      # {0:0, 1:1, 2:4, 3:9, 4:16}
{k.upper(): v*2 for k, v in d.items()}

# Merging dictionaries (Python 3.9+)
d1 = {'a': 1}
d2 = {'b': 2}
d3 = d1 | d2                     # {'a': 1, 'b': 2}
d1 |= d2                         # Update d1

# ===========================================
# 7. SET OPERATIONS
# ===========================================

s1 = {1, 2, 3}
s2 = {3, 4, 5}

# Set operations
s1 | s2                          # Union: {1, 2, 3, 4, 5}
s1 & s2                          # Intersection: {3}
s1 - s2                          # Difference: {1, 2}
s1 ^ s2                          # Symmetric difference: {1, 2, 4, 5}

# Set methods
s1.add(4)                        # Add element
s1.update([5, 6])                # Add multiple
s1.remove(1)                     # Remove (raises KeyError if missing)
s1.discard(1)                    # Remove (no error if missing)
s1.pop()                         # Remove and return arbitrary element
s1.clear()                       # Remove all elements

# Set comprehensions
{x for x in range(10) if x % 2 == 0}  # {0, 2, 4, 6, 8}

# ===========================================
# 8. CONTROL FLOW
# ===========================================

# If-elif-else
x = 10
if x > 10:
    print("Greater than 10")
elif x == 10:
    print("Equal to 10")
else:
    print("Less than 10")

# Ternary operator
result = "Even" if x % 2 == 0 else "Odd"

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

for i, value in enumerate(['a', 'b', 'c']):
    print(i, value)              # 0 a, 1 b, 2 c

for key, value in {'a': 1, 'b': 2}.items():
    print(key, value)

# While loops
count = 0
while count < 5:
    print(count)
    count += 1

# Loop control
for i in range(10):
    if i == 3:
        continue                 # Skip this iteration
    if i == 7:
        break                    # Exit loop
    print(i)
else:
    print("Loop completed")      # Executes if no break

# ===========================================
# 9. FUNCTIONS
# ===========================================

# Basic function
def greet(name):
    """Return a greeting message."""
    return f"Hello, {name}!"

# Default arguments
def power(base, exponent=2):
    return base ** exponent

# Variable-length arguments
def sum_all(*args):
    return sum(args)

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

# Type hints (Python 3.5+)
def add(a: int, b: int) -> int:
    return a + b

# Lambda functions
square = lambda x: x ** 2
add = lambda x, y: x + y

# Decorators
def decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function")
        result = func(*args, **kwargs)
        print("After function")
        return result
    return wrapper

@decorator
def say_hello():
    print("Hello!")

# Generator functions
def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

# ===========================================
# 10. CLASSES AND OOP
# ===========================================

class Person:
    # Class variable
    species = "Homo sapiens"

    # Constructor
    def __init__(self, name: str, age: int):
        self.name = name          # Instance variable
        self.age = age
        self._protected = "protected"  # Protected convention
        self.__private = "private"     # Name mangled

    # Instance method
    def greet(self):
        return f"Hello, I'm {self.name}"

    # Class method
    @classmethod
    def from_birth_year(cls, name, birth_year):
        age = datetime.now().year - birth_year
        return cls(name, age)

    # Static method
    @staticmethod
    def is_adult(age):
        return age >= 18

    # Property decorator
    @property
    def adult(self):
        return self.age >= 18

    # String representation
    def __str__(self):
        return f"Person(name={self.name}, age={self.age})"

    def __repr__(self):
        return f"Person('{self.name}', {self.age})"

# Inheritance
class Student(Person):
    def __init__(self, name, age, student_id):
        super().__init__(name, age)  # Call parent constructor
        self.student_id = student_id

    def greet(self):
        return f"Hello, I'm {self.name}, a student"

# Multiple inheritance
class TeachingAssistant(Student, Person):
    pass

# Abstract Base Class
from abc import ABC, abstractmethod
class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

# Dataclasses (Python 3.7+)
from dataclasses import dataclass
@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0  # Default value

# ===========================================
# 11. EXCEPTION HANDLING
# ===========================================

try:
    result = 10 / 0
    value = int("not_a_number")
except ZeroDivisionError:
    print("Cannot divide by zero")
except ValueError as e:
    print(f"Value error: {e}")
except (TypeError, NameError):
    print("Type or name error")
except Exception as e:
    print(f"Other error: {e}")
else:
    print("No exceptions occurred")
finally:
    print("This always executes")

# Raising exceptions
def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    return age

# Custom exceptions
class CustomError(Exception):
    def __init__(self, message):
        super().__init__(message)
        self.message = message

# Context managers
with open('file.txt', 'r') as f:
    content = f.read()

# Custom context manager
from contextlib import contextmanager
@contextmanager
def managed_resource():
    resource = acquire_resource()
    try:
        yield resource
    finally:
        release_resource(resource)

# ===========================================
# 12. FILE OPERATIONS
# ===========================================

# Reading files
with open('file.txt', 'r') as f:
    content = f.read()            # Read entire file
    lines = f.readlines()         # Read all lines as list
    line = f.readline()           # Read single line

# Writing files
with open('file.txt', 'w') as f:
    f.write("Hello\n")
    f.writelines(["Line1\n", "Line2\n"])

# Appending
with open('file.txt', 'a') as f:
    f.write("Appended text\n")

# Different modes: 'r', 'w', 'a', 'rb', 'wb', 'r+', 'w+', 'a+'

# Working with paths
from pathlib import Path
p = Path('/home/user/file.txt')
p.name                           # 'file.txt'
p.stem                           # 'file'
p.suffix                         # '.txt'
p.parent                         # '/home/user'
p.exists()                       # True/False
p.is_file()                      # True/False
p.is_dir()                       # True/False

# JSON
import json
data = {'name': 'John', 'age': 30}
json_str = json.dumps(data)      # Convert to JSON string
parsed = json.loads(json_str)    # Parse JSON string
with open('data.json', 'w') as f:
    json.dump(data, f)           # Write JSON to file
with open('data.json', 'r') as f:
    data = json.load(f)          # Read JSON from file

# CSV
import csv
with open('data.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['Name', 'Age'])
    writer.writerow(['John', 30])
    writer.writerows([['Alice', 25], ['Bob', 35]])

with open('data.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

# ===========================================
# 13. MODULES AND PACKAGES
# ===========================================

"""
Module Structure:
mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
    ├── __init__.py
    └── module3.py
"""

# Importing from package
# import mypackage.module1
# from mypackage import module1
# from mypackage.module1 import function1

# Relative imports (within package)
# from . import module1
# from .. import other_module
# from .subpackage import module3

# Python path
import sys
sys.path.append('/custom/path')

# Package metadata
# In __init__.py:
# __version__ = '1.0.0'
# __author__ = 'Your Name'

# ===========================================
# 14. ITERATORS AND GENERATORS
# ===========================================

# Iterator protocol
class CountDown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        else:
            self.current -= 1
            return self.current + 1

# Generator expressions
gen = (x**2 for x in range(10))
next(gen)                         # 0
list(gen)                         # [1, 4, 9, ..., 81]

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

# itertools
import itertools
# Infinite iterators: count(), cycle(), repeat()
# Combinatorics: product(), permutations(), combinations()
# Filtering: compress(), dropwhile(), takewhile()

# ===========================================
# 15. DECORATORS AND CONTEXT MANAGERS
# ===========================================

# Function decorator with arguments
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(times=3)
def say_hello():
    print("Hello")

# Class-based decorator
class DecoratorClass:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before")
        result = self.func(*args, **kwargs)
        print("After")
        return result

# Class-based context manager
class DatabaseConnection:
    def __enter__(self):
        self.connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.disconnect()

    def connect(self):
        print("Connecting...")

    def disconnect(self):
        print("Disconnecting...")

# ===========================================
# 16. CONCURRENCY AND PARALLELISM
# ===========================================

# Threading
import threading
def worker():
    print("Worker thread")

thread = threading.Thread(target=worker)
thread.start()
thread.join()

# Thread pool
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=3) as executor:
    future = executor.submit(pow, 2, 3)
    result = future.result()      # 8

# Multiprocessing
import multiprocessing
def cpu_bound_task(x):
    return x * x

if __name__ == '__main__':
    with multiprocessing.Pool() as pool:
        results = pool.map(cpu_bound_task, range(10))

# Asyncio
import asyncio
async def fetch_data():
    await asyncio.sleep(1)
    return "data"

async def main():
    task = asyncio.create_task(fetch_data())
    result = await task
    print(result)

asyncio.run(main())

# ===========================================
# 17. REGULAR EXPRESSIONS
# ===========================================

import re

# Basic patterns
pattern = r'\d+'                  # One or more digits
text = "There are 123 apples"

# Searching
match = re.search(pattern, text)  # First match
if match:
    print(match.group())          # '123'

# Finding all
all_matches = re.findall(pattern, text)  # ['123']

# Splitting
re.split(r'\s+', text)            # Split on whitespace

# Replacing
re.sub(r'\d+', 'NUM', text)       # 'There are NUM apples'

# Compiling patterns
compiled = re.compile(r'\d{3}-\d{3}-\d{4}')
compiled.search("Phone: 123-456-7890")

# Groups
pattern = r'(\d{3})-(\d{3})-(\d{4})'
match = re.search(pattern, "123-456-7890")
match.group(1)                    # '123'
match.groups()                    # ('123', '456', '7890')

# ===========================================
# 18. COMMON LIBRARIES
# ===========================================

# Collections
from collections import defaultdict, Counter, deque, OrderedDict, namedtuple

# Counter
count = Counter(['a', 'b', 'a', 'c'])
count.most_common(2)              # [('a', 2), ('b', 1)]

# Defaultdict
dd = defaultdict(list)
dd['key'].append('value')

# Deque
dq = deque([1, 2, 3])
dq.appendleft(0)                  # [0, 1, 2, 3]
dq.pop()                          # 3

# Namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)

# itertools (already mentioned)
# functools
from functools import lru_cache, partial, reduce

@lru_cache(maxsize=128)
def expensive_function(x):
    return x ** x

add_five = partial(lambda x, y: x + y, 5)

# operator
import operator
operator.add(1, 2)                # 3
operator.itemgetter(1)([1, 2, 3]) # 2

# ===========================================
# 19. DEBUGGING AND PROFILING
# ===========================================

# Debugging
import pdb
pdb.set_trace()                   # Set breakpoint

# Logging
import logging
logging.basicConfig(level=logging.INFO)
logging.debug("Debug message")
logging.info("Info message")
logging.warning("Warning message")
logging.error("Error message")
logging.critical("Critical message")

# Assertions
assert x > 0, "x must be positive"

# Profiling
import cProfile
cProfile.run('sum(range(1000000))')

# Timeit
import timeit
timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)

# ===========================================
# 20. ADVANCED FEATURES (PYTHON 3.8+)
# ===========================================

# Walrus operator (:=)
if (n := len([1,2,3])) > 2:
    print(f"List has {n} elements")

# Positional-only parameters (Python 3.8)
def func(a, b, /, c, d, *, e, f):
    # a and b are positional-only
    # c and d can be positional or keyword
    # e and f are keyword-only
    pass

# Type hints improvements
from typing import List, Dict, Optional, Union, Any, Callable, TypeVar, Generic

# Match statement (Python 3.10+)
def handle_command(command):
    match command.split():
        case ["quit"]:
            print("Quitting")
        case ["load", filename]:
            print(f"Loading {filename}")
        case ["save", filename]:
            print(f"Saving {filename}")
        case _:
            print("Unknown command")

# Structural pattern matching
match value:
    case 0 | 1 | 2:
        print("Small number")
    case [x, y]:
        print(f"Two elements: {x}, {y}")
    case {"name": name, "age": age}:
        print(f"{name} is {age} years old")

# Zoneinfo (Python 3.9+)
from zoneinfo import ZoneInfo
dt = datetime(2024, 1, 1, tzinfo=ZoneInfo("America/New_York"))

# ===========================================
# 21. VIRTUAL ENVIRONMENTS AND DEPENDENCIES
# ===========================================

"""
# Create virtual environment
python -m venv venv

# Activate (Windows)
venv\Scripts\activate

# Activate (Unix/macOS)
source venv/bin/activate

# Install packages
pip install package_name
pip install -r requirements.txt

# Freeze dependencies
pip freeze > requirements.txt

# Poetry (modern dependency management)
poetry new project-name
poetry add package-name
poetry install
"""

# ===========================================
# 22. BEST PRACTICES AND IDIOMS
# ===========================================

# List comprehensions over loops
# Good: [x**2 for x in range(10)]
# Bad: result = []; for x in range(10): result.append(x**2)

# Use enumerate for index
for i, value in enumerate(items):
    pass

# Use zip for parallel iteration
for a, b in zip(list1, list2):
    pass

# Use context managers for resources
with open('file.txt') as f:
    pass

# Use generators for large datasets
def read_large_file(file):
    with open(file) as f:
        for line in f:
            yield line

# Use dictionary.get() with default
value = my_dict.get('key', 'default')

# Use f-strings for formatting (Python 3.6+)
name = "John"
age = 30
f"{name} is {age} years old"

# Use pathlib for file paths
from pathlib import Path
path = Path('folder/file.txt')

# Type hints
def process(items: List[str]) -> Dict[str, int]:
    pass

# Error handling - be specific
try:
    # code
except ValueError as e:
    # handle ValueError
except KeyError as e:
    # handle KeyError

# ===========================================
# 23. COMMON PATTERNS
# ===========================================

# Singleton pattern
class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# Factory pattern
class Button:
    pass

class ButtonFactory:
    @staticmethod
    def create_button(button_type):
        if button_type == "windows":
            return WindowsButton()
        elif button_type == "mac":
            return MacButton()

# Observer pattern
class Observer:
    def update(self, message):
        pass

class Observable:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        self._observers.append(observer)

    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

# ===========================================
# 24. TESTING
# ===========================================

import unittest
import pytest

# unittest example
class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1 + 1, 2)

    def test_divide(self):
        with self.assertRaises(ZeroDivisionError):
            1 / 0

# pytest example (in separate test file)
def test_add():
    assert 1 + 1 == 2

def test_list():
    assert [1, 2, 3] == [1, 2, 3]

# Mocking
from unittest.mock import Mock, patch

def test_with_mock():
    mock_obj = Mock()
    mock_obj.method.return_value = 42
    assert mock_obj.method() == 42

# ===========================================
# 25. WEB DEVELOPMENT BASICS
# ===========================================

# HTTP requests
import requests
response = requests.get('https://api.github.com')
response.status_code              # 200
response.json()                   # Parse JSON response

# Simple HTTP server
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'Hello World')

# server = HTTPServer(('localhost', 8000), Handler)
# server.serve_forever()

# Web frameworks
"""
Flask:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
    return 'Hello World'

FastAPI:
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
def read_root():
    return {'Hello': 'World'}
"""

# ===========================================
# 26. DATA SCIENCE BASICS
# ===========================================

# numpy
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
arr.mean(), arr.std(), arr.sum()

# pandas
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df.describe()
df.groupby('A').mean()

# matplotlib
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Title')
# plt.show()

"""
This cheatsheet covers Python from basics to advanced topics.
Remember to practice by building projects and solving problems!
"""
Enter fullscreen mode Exit fullscreen mode

Grab this ebook to master PYTHON: (https://codewithdhanian.gumroad.com/l/xtwar)

Top comments (0)