Mohit's Blog

A Pythonic Journey Through Key Topics

24 Sep 2023

Python, with its vast ecosystem and libraries, is a versatile language used in diverse fields. In this post, we’ll embark on a journey through some of the fundamental topics, exploring them with code snippets.

1. List Comprehensions and Generators

List comprehensions provide a concise way to create lists.

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

Generators generate values on-the-fly and consume less memory:

squared_gen = (x**2 for x in range(10))

2. Special Methods

These “magic methods” let us emulate built-in behaviors:

class Sample:
    def __repr__(self):
        return "Sample() instance"
    def __str__(self):
        return "Sample instance"

3. Concurrency and Parallelism

Threads are great for I/O-bound tasks:

import threading

def print_numbers():
    for i in range(5):
        print(i)

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

4. Data Structures

Python’s versatile list and tuple:

lst = [1, 2, 3]
tpl = (1, 'a', 2.5)

5. Sockets and Networking

Basic server using socket:

import socket

s = socket.socket()
s.bind(('localhost', 9999))
s.listen(1)
conn, addr = s.accept()
print(f"Connection from {addr}")
conn.close()

6. File Handling

Always close files, or better, use with:

with open('sample.txt', 'r') as file:
    data = file.read()

7. Type Hints and Annotations

Provide clues about variable types:

def greet(name: str) -> str:
    return f"Hello, {name}!"

8. Error Handling

Gracefully handle unexpected events:

try:
    x = 1/0
except ZeroDivisionError:
    print("Can't divide by zero!")

9. Duck Typing and Polymorphism

Python relies on the “if it walks like a duck and quacks like a duck, then it’s a duck” philosophy:

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

class Cat:
    def speak(self):
        return "Meow!"

def animal_sounds(animal):
    print(animal.speak())

animal_sounds(Dog())
animal_sounds(Cat())

10. Subprocesses

Run external commands:

import subprocess
result = subprocess.run(['echo', 'Hello from subprocess!'], capture_output=True, text=True)
print(result.stdout)

11. asyncio and Coroutines

Leverage asynchronous programming:

import asyncio

async def main():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

asyncio.run(main())

12. Inheritance and Data Encapsulation

Using classes and their inheritance properties:

class Base:
    def __init__(self):
        self._protected_var = "Protected"
        self.__private_var = "Private"

class Derived(Base):
    def access_base(self):
        print(self._protected_var)

obj = Derived()
obj.access_base()

13. Data Manipulation with Lists and Tuples

Efficiently manipulating data:

book_ids = [1081, 1802, 1003]
overdue_ids = [1802, 1003]
overdue_books = [x for x in book_ids if x in overdue_ids]

14. Python’s Dynamic Typing

Python’s typing system allows for flexibility:

def dynamic_function(data):
    return f"Received {data} of type {type(data)}"

print(dynamic_function(5))
print(dynamic_function("Hello"))

15. Closures and Decorators

Leverage the power of higher-order functions:

def outer_function(msg):
    def inner_function():
        print(msg)
    return inner_function

hi_func = outer_function('Hi')
bye_func = outer_function('Bye')

hi_func()
bye_func()

16. Python’s Memory Management

Understanding nuances of Python memory:

a = [1, 2, 3]
b = a
b.append(4)

print(a)  # [1, 2, 3, 4]

17. Functional Programming with map, filter, and reduce

numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))

18. Exception Handling and Control Flow

Robust code handles unexpected scenarios:

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Can't divide by zero!")
finally:
    print("This always executes.")

19. Understanding Variable Scope and nonlocal Keyword

In Python, the scope of a variable is the portion of the code where the variable can be accessed or modified. The nonlocal keyword is used in nested functions to declare that a variable refers to a variable in the nearest enclosing scope that is not a global scope:

def outer_function():
    x = 10
    def inner_function():
        nonlocal x
        x = 20
    inner_function()
    print(x)  # This will print 20

outer_function()

20. Manipulating Data Structures: Sets, Lists, and Dictionaries

Python offers a rich collection of data structures. Sets, for example, are great for membership tests:

set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}

intersection = set_a & set_b
print(intersection)  # {3, 4}

By embracing the full spectrum of Python’s features and understanding the underlying mechanisms, developers can write efficient, clean, and maintainable code that scales well with the problem domain.

Tweet