Author: Amber Colvin

  • JavaScript filter: Array.filter() With Practical Examples

    JavaScript filter: Array.filter() With Practical Examples

    JavaScript filter keeps the elements in an array that satisfy a condition. Its main method, Array.filter(), calls a callback for each existing element and returns a new array containing every element whose callback result is truthy.

    Use it for collections with zero, one, or many matches. The original array remains unchanged, so the method is suitable for creating filtered views of data without removing elements from the source.

    How JavaScript filter works

    The JavaScript filter function receives up to three callback arguments: the current element, its index, and the complete array. Most callbacks use only the element:

    Example: const numbers = [3, 8, 12, 15]; const multiples = numbers.filter((element) => element % 3 === 0);

    The returned value is [3, 12, 15]. To access all callback arguments, use this form:

    Example: const firstHalf = numbers.filter((element, index, array) => index < array.length / 2 && element > 5);

    A callback does not need to return the words true or false. Any truthy result keeps the element; false, 0, “”, null, and undefined exclude it. Returning a boolean expression makes the intended rule clearest.

    filter() does not mutate the original array. It creates a new array, although object elements inside it still reference the same objects. If no elements pass the condition, the result is an empty array: [].

    How does the JavaScript filter function select numbers and strings?

    For numbers, write a predicate that describes the allowed value. This example keeps values at least 10:

    Example: const scores = [7, 10, 14, 18]; const passing = scores.filter(score => score >= 10);

    The result is [10, 14, 18], while scores is unchanged. The same pattern works with strings. Combine typeof with a text condition when an array may contain different data types:

    Example: const values = [“JavaScript”, 42, “filter”, null]; const words = values.filter(value => typeof value === “string” && value.length > 5);

    This returns [“JavaScript”, “filter”]. The filter function JavaScript developers use can therefore select by type, length, range, pattern, or any other callback condition.

    How JavaScript Array.filter() handles objects, missing values, and multiple conditions

    For objects, inspect a property inside the callback. This example keeps active users:

    Example: const users = [{ name: “Ana”, active: true }, { name: “Bo”, active: false }, { name: “Cy”, active: true }]; const activeUsers = users.filter(user => user.active === true);

    The result contains Ana and Cy. A missing property evaluates to undefined, so an explicit comparison such as user.active === true safely excludes an object without an active property.

    Filter out missing or invalid values by checking the value before using it:

    Example: const values = [10, undefined, 25, null, 40]; const validNumbers = values.filter(value => typeof value === “number”);

    The result is [10, 25, 40]. For a sparse array with genuinely empty slots, filter() skips those unassigned slots rather than calling the callback for them.

    Use logical operators for compound conditions. This example keeps in-stock products costing no more than 50:

    Example: const products = [{ name: “Pen”, price: 3, inStock: true }, { name: “Bag”, price: 45, inStock: false }, { name: “Lamp”, price: 38, inStock: true }]; const affordable = products.filter(product => product.inStock && product.price <= 50);

    The && operator requires both conditions to pass. Use || when either condition is acceptable, such as selecting products in the “office” or “school” category.

    When should you use the filter function in JavaScript instead of find or map?

    Choose filter() when the required result is an array containing every match. Its result always has array shape, including an empty array when nothing matches.

    Choose find() when you need one element: specifically, the first match. It returns that element or undefined, not an array. Do not use filter() when a single first match is the required result.

    Choose map() when every element should produce a transformed value. It normally returns an array with the same number of elements, whereas filter() removes elements that fail its predicate.

  • How to Exit a Python Script: Graceful Ways to Stop It

    How to Exit a Python Script: Graceful Ways to Stop It

    To exit Python script execution, choose the least forceful option that matches the situation. Let the script reach the end for normal completion, use return or break for local control flow, and use sys.exit() when the whole process must report a deliberate status. Reserve subprocess termination for a separate process that cannot finish cooperatively.

    These choices are not interchangeable: returning from a function does not stop the interpreter, while killing a process does not provide normal function cleanup.

    How do you exit a Python script normally?

    A Python script exits normally when its top-level code reaches the end. The interpreter then closes, and the operating system usually receives exit code 0. This is the cleanest way to close a Python program after all required work succeeds.

    Put reusable work in a function and return from that function when its job is complete. A return value goes to the caller; it does not automatically exit the entire script. At the top level, reaching the end is equivalent to completing normally, but a top-level return is not valid Python syntax.

    Use a context manager for resources that need predictable cleanup. For example, with open(“output.txt”, “w”) as file: closes the file when the block ends, including when an exception interrupts it. For custom cleanup, place it in a finally block:

    try: perform_work()
    finally: release_resource()

    How do sys.exit() and SystemExit set exit codes while cleanup runs?

    Call sys.exit() when a function needs to stop the whole interpreter intentionally. It raises the SystemExit exception, allowing Python to run active finally blocks and context-manager cleanup while unwinding the stack.

    sys.exit(0) indicates success. A nonzero integer, such as sys.exit(2), signals an error or another meaningful failure state to the shell, scheduler, or calling process. Passing a string prints that message and normally produces a nonzero exit status.

    SystemExit is an exception, but it inherits directly from BaseException rather than Exception. Code that catches SystemExit explicitly can prevent the process from ending, so only intercept it when an embedding application genuinely needs that behavior. Cleanup still belongs in finally or a context manager, not after a call that may exit.

    How do return, break, Ctrl+C, and KeyboardInterrupt affect how you close a Python program?

    • return leaves the current function and gives a value to its caller. It does not terminate the script unless the caller uses that result to end execution.
    • break leaves the nearest loop only. Execution continues with the first statement after that loop.
    • Ctrl+C sends an interrupt from the terminal. Python normally represents it as KeyboardInterrupt in the main thread.
    • KeyboardInterrupt can be handled to log a message, save state, or perform an orderly shutdown. Without a handler, Python stops with an interrupt traceback and a nonzero status.

    Handle interruption around the operation that needs protection: try the work, except KeyboardInterrupt to choose a response, and use finally for cleanup. Do not use break when an exception or process-wide exit is required.

    How do you terminate or kill a subprocess, and when might you kill a Python program?

    For a child process created with subprocess.Popen, call process.terminate() first. It requests termination and may allow the child to handle the signal and release resources. Then call process.wait() and inspect process.returncode to verify the final state.

    If the child ignores termination or exceeds a shutdown timeout, call process.kill(), then call wait() again. On Unix-like systems, terminate commonly sends SIGTERM and kill sends SIGKILL; platform behavior differs, but kill is the forceful option. It can prevent application-level cleanup.

    Use kill a Python program only when cooperative shutdown has failed or the process is unsafe or irreparably stuck. A parent process can check process.poll() before and after termination: None means the child is still running, while a numeric return code confirms that it has exited.

  • Python file existence: check paths with pathlib and os.path

    Python file existence: check paths with pathlib and os.path

    A Python file exists check is easiest with pathlib. To check if file exists in Python, create a Path object and call exists(). This works with both relative and absolute paths.

    Use a pre-check when you need to choose a response for a missing path. When you immediately need to open the file, catch FileNotFoundError as well, because a path can change after the check.

    Python file existence: check a path with pathlib

    Import Path, then call exists() on the path you want to test:

    from pathlib import Path

    relative_path = Path(“reports/today.txt”)

    absolute_path = Path(“/var/data/reports/today.txt”)

    if relative_path.exists():

        print(“The path exists”)

    Path(“reports/today.txt”) is a relative path. Python resolves it against the process’s current working directory, which may differ from the directory containing your script. Use Path.cwd() to see that directory:

    print(Path.cwd())

    An absolute path identifies its location from the filesystem root, such as /var/data/reports/today.txt on Linux and macOS. Windows paths can use a raw string such as Path(r”C:\data\reports\today.txt”).

    How do you distinguish files and directories?

    exists() returns True for both files and directories. Use is_file() when the path must identify a regular file, and is_dir() when it must identify a directory:

    path = Path(“reports/today.txt”)

    if path.is_file():

        print(“A file is available”)

    elif path.is_dir():

        print(“A directory is available”)

    else:

        print(“The path is missing”)

    For a missing path, all three methods return False. A directory makes exists() and is_dir() true, but is_file() false. A file produces the opposite file-versus-directory result.

    What are the os.path equivalents?

    The older os.path functions provide the same basic tests and accept string paths:

    import os

    path = “reports/today.txt”

    os.path.exists(path)

    os.path.isfile(path)

    os.path.isdir(path)

    Use os.path.exists() for either type, os.path.isfile() for a file, and os.path.isdir() for a directory. os.path.abspath(path) converts a relative path to an absolute string. For new code, pathlib usually keeps path construction and file operations more readable.

    What if a file disappears after the check?

    An existence check is not a guarantee that the path will still exist when you use it. Another process can delete, replace, or rename the file between exists() and open(). This check-then-use race can also occur if a directory in the path changes.

    For actual file access, open the path and handle the failure directly. This is how to check if a file exists while safely attempting to read it:

    try:

        with path.open(“r”, encoding=”utf-8″) as file:

            contents = file.read()

    except FileNotFoundError:

        contents = “”

    Use exists() for validation or user-facing messages, but rely on the exception when opening the file is the operation that matters.

  • Python dict to JSON: Serialize Text or a File

    Python dict to JSON: Serialize Text or a File

    For a Python dict to JSON conversion, use json.dumps() when you need JSON text in memory. Use json.dump() when you need to write the dictionary directly to a file. Both functions serialize Python data, but they produce different outputs.

    To convert a dict to JSON in Python, import the standard-library json module and pass your dictionary to the appropriate function. JSON uses double-quoted strings and standardized values, so str() or repr() is not a substitute for serialization.

    Python dict to JSON with json.dumps(): Get JSON Text

    json.dumps() returns a JSON-formatted Python string. It does not create a file or modify the original dictionary.

    import json
    data = {“name”: “Ada”, “active”: True, “roles”: [“admin”, “editor”]}
    json_text = json.dumps(data)

    The value of json_text is a string such as {“name”: “Ada”, “active”: true, “roles”: [“admin”, “editor”]}. Notice that Python’s True becomes JSON’s true. Use this approach when sending a payload through an API, storing serialized text in a database, or passing JSON to another component.

    For readable output, add formatting options directly to the call:

    json_text = json.dumps(data, indent=2)

    The return type remains str, whether the output is compact or indented.

    Write a dict to a JSON file with json.dump() using UTF-8 encoding

    json.dump() writes JSON to an open, file-like object and returns None. Open the file with write mode and explicit UTF-8 encoding:

    with open(“data.json”, “w”, encoding=”utf-8″) as file:
        json.dump(data, file, indent=2, ensure_ascii=False)

    This creates or replaces data.json. The file contains JSON, while data remains a Python dictionary in memory. The with statement closes the file even if an error occurs. Unlike json.dumps(), json.dump() does not return the serialized document as a string.

    Use encoding=”utf-8″ for predictable handling of names, labels, and other non-ASCII characters. The encoding controls how Python writes characters to the file; it is separate from JSON’s formatting options.

    Format dict to JSON in Python with indent, Unicode, and sorted keys

    • indent=2 adds two spaces per nesting level. Use indent=4 for more spacing, or omit it for compact output.
    • ensure_ascii=False keeps characters such as é and 東京 readable. The default, True, escapes them with Unicode sequences such as \u00e9.
    • sort_keys=True writes object keys in alphabetical order. This makes generated files easier to compare and produces stable output for tests.

    For a consistently formatted JSON string, combine the options: json.dumps(data, indent=2, ensure_ascii=False, sort_keys=True). Key ordering affects presentation, not the meaning of a JSON object.

    Convert a Python dict to JSON with supported types and a default handler

    The built-in encoder supports dictionaries, lists, tuples, strings, integers, floating-point numbers, booleans, and None. These become JSON objects, arrays, strings, numbers, true, false, and null. JSON object keys should be strings; Python also accepts some simple non-string keys and converts them to strings.

    Values such as sets, bytes, dates, decimals, and most custom objects are not serializable by default. The encoder raises TypeError when it encounters one. Supply a default function that converts a known type into a JSON-supported value:

    from datetime import date, datetime
    def encode_value(value):
        if isinstance(value, (date, datetime)):
            return value.isoformat()
        raise TypeError(f”Unsupported type: {type(value).__name__}”)

    Then pass it to either serializer: json.dumps(data, default=encode_value) or json.dump(data, file, default=encode_value). This strategy stores dates as ISO 8601 strings and fails clearly for types you have not deliberately mapped.

  • How to Print Variables in Python: A Practical Guide

    How to Print Variables in Python: A Practical Guide

    To learn how to print variables in Python, start with the built-in print() function. It displays a value in your program’s output, adds a newline by default, and can show strings, numbers, lists, and other objects.

    The basic way to print a variable in Python is to pass its name to print(). Python evaluates the variable and displays its current value.

    How do you print a variable in Python?

    Assign a value to a variable, then provide that variable as the argument to print():

    name = ‘Mina’; print(name)

    Output: Mina

    This works with numeric values as well:

    age = 29; print(age)

    Output: 29

    When the variable contains a string, print() displays the characters without quotation marks. For numbers, it displays the numeric value directly. You do not need to convert either value before passing it to print().

    How do you print labels and several values?

    Pass several arguments to print(), separated by commas. Python converts each value for display and places a space between arguments by default:

    name = ‘Mina’; age = 29; print(‘Name:’, name, ‘Age:’, age)

    Output: Name: Mina Age: 29

    This approach is useful for quick status messages because it safely displays text and non-string values together. It also avoids trying to combine text and numbers with an incompatible string operation.

    Use the sep parameter to replace the default space between arguments:

    print(‘2025′, ’03’, ’08’, sep=’-‘)

    Output: 2025-03-08

    The end parameter controls what follows the printed value. Its default is a newline. Set it to another string when output should continue on the same line:

    print(‘Loading’, end=’…’); print(‘done’)

    Output: Loading…done

    How does printing variables in Python work with f-strings?

    F-strings place variable values inside a text template. Add the letter f before the opening quote, then put each variable or expression inside braces:

    name = ‘Mina’; score = 94; print(f'{name} scored {score} points.’)

    Output: Mina scored 94 points.

    F-strings are usually the clearest choice when a message contains labels and several values. They also support conversion and formatting specifiers. Add a colon inside the braces to format a number:

    price = 19.5; print(f’Price: ${price:.2f}’)

    Output: Price: $19.50

    Here, :.2f displays a floating-point number with two digits after the decimal point. Use a comma to group large numbers:

    total = 1234567; print(f'{total:,}’)

    Output: 1,234,567

    Expressions can also appear inside an f-string:

    items = 3; price = 4.5; print(f’Total: ${items * price:.2f}’)

    Output: Total: $13.50

    How do str and repr help when debugging?

    For ordinary output, print() uses a value’s human-readable string form, called str. This keeps displayed text easy to read. The repr form is designed for debugging and aims to reveal the value more precisely.

    The difference is especially visible with strings containing escape characters:

    message = ‘A\nB’; print(message)

    This displays A and B on separate lines. By contrast:

    print(repr(message))

    Output: ‘A\nB’

    The repr() result shows quotation marks and the literal escape sequence, making hidden characters easier to identify. It is also useful for distinguishing a string from a number or spotting extra spaces.

    Use the !r conversion inside an f-string when you need that debug-friendly representation:

    print(f’message={message!r}’)

    Output: message=’A\nB’

    Use !s when you explicitly want the normal string form. For routine messages, use standard interpolation or comma-separated arguments; reserve repr() and !r for inspecting values and diagnosing unexpected output.

  • Python __init__.py: What Does It Do?

    Python __init__.py: What Does It Do?

    In Python, __init__.py is the package’s initialization module. A directory containing it is recognized as a regular package, and the file can be empty. If you are asking what is __init__.py, it is the place where a package can define setup code, metadata, and convenient package-level names.

    What does __init__.py do? Python runs its top-level code when the package is imported. It also lets a package expose a smaller, clearer public API instead of making users import every name from an internal module.

    How Python __init__.py Defines Package Behavior

    A regular package is a directory that normally contains __init__.py. The file tells Python to treat that directory as one package and gives the package a module body that can configure its behavior. It is unrelated to a class’s __init__ method, which initializes an object instance.

    For example, this small package tree contains a pricing module and a nested web package:

    • shop/
      • __init__.py
      • pricing.py
      • web/
        • __init__.py
        • routes.py

    With this structure, users can write import shop, from shop import pricing, or from shop.web.routes import home, assuming the corresponding names exist. An empty initializer is enough when the package only needs this structure and does not need package-level setup.

    What Is __init__.py? Package Discovery and Import Timing

    When Python evaluates import shop.web.routes, it loads shop/__init__.py first, then shop/web/__init__.py, and finally routes.py. Each module’s top-level statements execute as that module is loaded. Python normally caches the resulting modules in sys.modules, so a second import in the same process does not repeat ordinary initialization.

    This timing makes imports inside an initializer useful for setup and composition. For example, shop/__init__.py might contain from .pricing import TaxRule. Importing shop then loads pricing.py and binds TaxRule on the package object. Code elsewhere can use from shop import TaxRule without knowing where the class is implemented.

    Initialization code also runs when a user imports a submodule, because Python must initialize each parent package first. An exception raised in __init__.py causes the package import to fail. Importing the package alone does not automatically execute every other module in its directory; those modules run only when imported directly or by the initializer.

    What Does __init__.py Do for Re-Exports and __all__?

    A re-export imports a name from an internal module and makes it available through the package’s top-level namespace. A concise initializer might contain:

    from .pricing import TaxRule
    from .pricing import calculate_total

    Users can then write from shop import TaxRule, calculate_total. This creates a stable public entry point even if the implementation later moves from pricing.py to another module. Re-export only names that belong to the supported API; importing too much can increase startup time and create circular-import problems.

    The special variable __all__ declares names for wildcard imports such as from shop import *. For the example above, an initializer could define __all__ = [“TaxRule”, “calculate_total”]. The listed names should be available in the package namespace, usually through imports in the same file.

    __all__ does not prevent explicit imports and is not a security boundary. It documents the intended wildcard surface and controls which names that form imports. An initializer can also define metadata such as __version__, package-level constants, or a small configuration value.

    When Is an Empty __init__.py Enough?

    Leave the file empty when the package needs only a regular package boundary and direct submodule imports. This choice avoids unnecessary work during every package import and reduces the risk of circular imports or surprising side effects. Add code only when package-level re-exports, metadata, registration, or lightweight setup provides a clear benefit.

    Not every Python package needs an __init__.py file. Since Python 3.3, namespace packages can be formed from directories without an initializer. Their portions can be distributed across multiple directories or installed distributions and combined under one package name. Because there is no initializer, there is also no package-specific file in which to run initialization code or define re-exports.

    Use a regular package when you want explicit initialization and a controlled top-level API. Use an empty initializer when that boundary is useful but no setup is needed. Avoid network calls, expensive I/O, and unrelated application work in __init__.py; imports should remain predictable and lightweight.

  • Python Web Server: Run a Simple HTTP Server Locally

    Python Web Server: Run a Simple HTTP Server Locally

    Run a Python web server from the directory you want to share with this command:

    python -m http.server

    Python starts a simple HTTP server on port 8000. Open http://localhost:8000/ in a browser to view the directory contents. On systems where the launcher is named differently, use python3 -m http.server on macOS or Linux, or py -m http.server on Windows.

    Start a Python web server with python -m http.server (or python3/py)

    The command serves files from your current working directory: the folder selected in the terminal when you start the process. For example, to serve a site stored in a folder named website:

    cd website

    python -m http.server

    Then visit http://localhost:8000/. If the directory contains an index.html file, the server displays it as the default page. Otherwise, the built-in handler shows a directory listing that lets you open individual files.

    This simple HTTP server with Python is useful for previewing static HTML, CSS, JavaScript, images, and other files on your own computer. It does not execute server-side Python, PHP, or JavaScript application code.

    Choose the directory, port, and bind address with –directory and –bind

    Use –directory to serve a folder without changing the terminal’s working directory:

    python -m http.server –directory ./website

    A relative path starts from the current working directory. You can also provide an absolute path. Combine it with a port number when 8000 is already in use:

    python -m http.server 9000 –directory ./website

    Open http://localhost:9000/ for that server. A port conflict means another process is already listening on the selected port. Stop that process or choose another unused port, such as 9000 or 8080. The same options work with python3 and py:

    py -m http.server 9000 –directory .\website

    By default, the server can listen beyond the local machine, depending on the platform and network configuration. Use –bind 127.0.0.1 to restrict access to the computer running the server:

    python -m http.server 8000 –directory ./website –bind 127.0.0.1

    To make the server reachable from other devices on the same network, bind it to the computer’s LAN address or use –bind 0.0.0.0, then browse to the host computer’s local IP address and port. Only expose files you intend to share.

    Open http://localhost:8000, read request logs, and stop the server

    With the default command running, browse to http://localhost:8000/. Each browser request appears in the terminal, typically with the client address, method, path, protocol, and status code:

    127.0.0.1 – – “GET /index.html HTTP/1.1” 200 –

    A 200 status means the file was served successfully. A 404 indicates that the requested path was not found. Browsers may make additional requests for stylesheets, scripts, icons, or source maps, so several log lines can appear for one page load.

    Keep the terminal process running while you use the server. Press Ctrl+C to stop it cleanly. Refreshing the browser after changing a file displays the updated version, although browser caching can sometimes require a hard refresh.

    Create a simple Python server with a custom handler—and know its limits

    Use a custom handler when you need a fixed response or a small change to request behavior. Save the following as server.py:

    from http.server import BaseHTTPRequestHandler, HTTPServer

    class Handler(BaseHTTPRequestHandler):

    def do_GET(self):

    body = b”Hello from Python\n”

    self.send_response(200)

    self.send_header(“Content-Type”, “text/plain; charset=utf-8”)

    self.send_header(“Content-Length”, str(len(body)))

    self.end_headers()

    self.wfile.write(body)

    server = HTTPServer((“127.0.0.1”, 8000), Handler)

    server.serve_forever()

    Start it with python server.py, python3 server.py, or py server.py, then open http://localhost:8000/. This simple Python server responds to GET requests with plain text instead of serving files. You can add path checks, headers, or different response bodies inside do_GET.

    The built-in server is intended for local development, testing, and quick file sharing. It provides basic HTTP handling and request logging, but it is not a production application server: it lacks the routing, security controls, concurrency features, deployment tooling, and application framework integration required for a public service.

  • Import Python File: A Practical Guide to Local Modules

    Import Python File: A Practical Guide to Local Modules

    Python loads a local file as a module when its directory is available on Python’s module search path. To load a local module, use its filename without the .py extension. A Python import of another Python file works the same way whether the file contains functions, classes, or constants.

    The simplest setup keeps both files in one directory, then expands to packages when the project grows.

    Import Python file from the same directory

    Suppose a directory contains main.py and helpers.py. The module name is helpers, not helpers.py.

    • helpers.py: GREETING = “Hello” and def greet(name): return f”{GREETING}, {name}”.
    • main.py: import helpers, from helpers import greet, print(helpers.GREETING), and greet(“Mina”).

    The statement import helpers imports the module and keeps its names under the helpers namespace. Use helpers.GREETING or helpers.greet() to access them. The statement from helpers import greet binds only greet in main.py, so you can call greet() directly.

    Do not include the .py extension, and avoid filenames containing spaces, hyphens, or names that conflict with standard-library modules.

    How to import another Python file selectively

    Use from module import name when you need specific functions, classes, or constants:

    • from helpers import greet, GREETING imports two names.
    • from helpers import greet as say_hello assigns an alias.
    • import helpers as h shortens the module reference while retaining its namespace.

    Selective imports make calls shorter, but they can make the source of a name less obvious. Use the module form when a file exposes many similarly named objects or when clarity matters. Python executes a module’s top-level code during its first import, then normally reuses the loaded module.

    Import another Python file from a package

    A package is a directory containing related modules. A predictable structure might look like this:

    • app/__init__.py
    • app/main.py
    • app/tools/__init__.py
    • app/tools/formatters.py

    Inside app/main.py, an absolute import can be from app.tools.formatters import clean. A package-relative import can be from .tools.formatters import clean. The leading dot means “from this package”; two dots refer to the parent package, as in from ..shared import settings.

    The parent directory of app must be on the search path for the absolute form to work. An __init__.py file makes package boundaries explicit and supports consistent behavior across tools, even though modern Python also supports namespace packages without one.

    Fix module search paths, entry points, and circular imports

    Python searches sys.path, which commonly includes the directory containing the launched script, the current directory for interactive or module execution, configured PYTHONPATH entries, the standard library, and installed packages. A ModuleNotFoundError usually means the module’s directory or the package’s parent is missing from that list.

    1. Run a package module from the project’s parent directory: python -m app.main. This gives relative imports the package context they require.
    2. Use if __name__ == “__main__”: to separate reusable definitions from script-only behavior. Put startup code in a main() function, then call it beneath the guard. Importing the file will define its functions without launching the script.
    3. Check spelling, capitalization, package names, and the directory from which the command runs. Also check that a local file is not shadowing a standard-library or installed module.

    Running python app/main.py directly can break a relative import because Python treats the file as a standalone script rather than as part of app. Prefer python -m app.main or configure the project as an installed package. Arbitrary sys.path mutation may hide the underlying structure problem and should not be the default fix.

    Circular imports occur when a.py imports b.py while b.py imports a.py. Typical symptoms include “cannot import name,” a “partially initialized module” message, or missing attributes during startup. Move shared functions or constants into a third module, make imports flow in one direction, or defer a genuinely optional import inside a function.

  • df.rename: How to rename a pandas column in a DataFrame

    df.rename: How to rename a pandas column in a DataFrame

    Use df.rename() to rename a pandas column, several columns, or index labels without rebuilding the DataFrame. The method accepts explicit old-to-new mappings for targeted edits and callable functions for systematic cleanup.

    By default, rename() returns a new DataFrame and leaves the original unchanged. That behavior makes it suitable for a clear, assignable pandas DataFrame’s rename method.

    How to rename a DataFrame column or several columns with df.rename()

    Use columns={old: new} when you rename a pandas DataFrame

    Pass a dictionary to columns. Each key is the existing column label, and each value is its replacement. The mapping always goes from old name to new name:

    renamed = df.rename(columns={“Name”: “name”})

    This creates a new DataFrame with Name changed to name. The original df still has its original labels. To rename several columns, include multiple entries:

    renamed = df.rename(columns={
        “First Name”: “first_name”,
        “Order Total”: “order_total”
    })

    Columns not listed in the dictionary remain unchanged. This is the direct way to rename a DataFrame column when you know the exact labels. Do not reverse the dictionary: {“name”: “Name”} searches for a column already named name and changes it to Name.

    Should you return a new DataFrame or change a DataFrame column name in place?

    Return a new DataFrame by default and assign it

    The default operation returns a renamed copy-like DataFrame object:

    df2 = df.rename(columns={“old_name”: “new_name”})

    Use assignment when you want to preserve the original DataFrame, keep a clearly named transformed object, or chain the result with other operations. You can also replace the original variable:

    df = df.rename(columns={“old_name”: “new_name”})

    Use inplace=True when you do not need a returned object

    Set inplace=True to update df directly:

    df.rename(columns={“old_name”: “new_name”}, inplace=True)

    This operation returns None, so do not assign its result back to df. Choose the default returned-DataFrame behavior when you want easier debugging, reversible steps, or a transformation pipeline. Choose in-place behavior when direct mutation is intentional and you do not need the method’s return value.

    Choose errors=’raise’ or ‘ignore’ for missing labels

    By default, errors=”ignore” leaves a mapping unchanged if its old label is absent. To catch misspelled or unexpected labels, use:

    df.rename(columns={“Oder Total”: “order_total”}, errors=”raise”)

    A missing source label then raises a KeyError. Use errors=”ignore” when a mapping may apply only to some DataFrames, and errors=”raise” when every requested rename must succeed.

    How to transform every column label with a callable

    Use a callable to clean labels and display the final columns

    Pass a function to columns when every label needs the same transformation. The callable receives one label at a time and must return its replacement. This example strips surrounding whitespace, converts labels to lowercase, and replaces spaces with underscores:

    clean = df.rename(
        columns=lambda column: column.strip().lower().replace(” “, “_”)
    )

    For input labels Customer ID, Order Total, and Order Date, display the result with:

    print(clean.columns.tolist())

    [‘customer_id’, ‘order_total’, ‘order_date’]

    A callable is useful for consistent label cleanup, while a dictionary is safer when only selected columns should change. If labels are not all strings, account for their types before calling string methods.

    How to rename index labels or a MultiIndex level

    Rename ordinary index labels

    Use index instead of columns to rename row labels:

    df2 = df.rename(index={0: “first”, 1: “second”})

    This changes labels, not row positions or the values stored in the DataFrame.

    Rename one level of a MultiIndex

    For hierarchical columns or rows, supply the level name or number. To rename labels in the second level of a MultiIndex column:

    df2 = df.rename(
        columns={“Q1”: “first_quarter”},
        level=1
    )

    Use index= for a MultiIndex on rows. The level argument limits the mapping to one hierarchy level, leaving labels in the other levels unchanged.

  • SQL split string: SQL string splitting by database engine

    SQL split string: SQL string splitting by database engine

    An SQL split string operation is database-specific. SQL Server, PostgreSQL, MySQL, and Oracle use different functions and return different shapes. To split string in SQL, choose the syntax for your database engine, then define how ordering, empty tokens, and delimiters should behave.

    This SQL string split guide returns usable rows or array elements rather than treating one function as portable standard SQL.

    SQL split string: SQL Server STRING_SPLIT, ordinals, and empty tokens

    SQL Server uses STRING_SPLIT and normally returns one row per token in a value column. SQL Server 2022 and supported Azure versions can also return an ordinal column by passing 1 as the third argument.

    Input and query:

    DECLARE @s nvarchar(100) = N’red,,blue’;

    SELECT s.ordinal, s.value
    FROM STRING_SPLIT(@s, N’,’, 1) AS s
    ORDER BY s.ordinal;

    The result is ordered rows: red, an empty value, and blue. Without the ordinal option, output order is not guaranteed. Consecutive delimiters produce empty substrings; filter them with WHERE s.value <> N” when they are not meaningful. STRING_SPLIT accepts a single-character separator, so use another method for multi-character delimiters.

    PostgreSQL: string_to_array and regexp_split_to_table for arrays or rows

    PostgreSQL offers a literal-delimiter function and a regular-expression function. string_to_array returns one array, supports multi-character text delimiters, and preserves empty fields between delimiters.

    Array input:

    SELECT string_to_array(‘red,,blue’, ‘,’) AS pieces;

    To turn that array into ordered rows, use unnest with ordinality:

    SELECT x.position, x.piece
    FROM unnest(string_to_array(‘red,,blue’, ‘,’)) WITH ORDINALITY AS x(piece, position)
    ORDER BY x.position;

    For a regular-expression delimiter, use regexp_split_to_table:

    SELECT x.piece
    FROM regexp_split_to_table(‘red||blue||green’, E’\|\|’) AS x(piece);

    This returns rows directly. Regex matching determines the split behavior; zero-length matches at the beginning or end are ignored. Use a pattern that matches the delimiter itself when empty values matter.

    MySQL: JSON_TABLE or recursive splitting for rows

    MySQL 8.0 has no general-purpose native split function. JSON_TABLE provides a compact row-producing pattern by converting the delimited value to a JSON array. The example below supports a multi-character literal delimiter and preserves empty values.

    Input and query:

    SET @s = ‘red||||blue’;

    SET @delimiter = ‘||’;

    SELECT j.item_no, j.value
    FROM JSON_TABLE(
    CONCAT(‘[‘, REPLACE(JSON_QUOTE(@s), @delimiter, ‘”,”‘), ‘]’),
    ‘$[*]’ COLUMNS (
    item_no FOR ORDINALITY,
    value VARCHAR(100) PATH ‘$’
    )
    ) AS j
    ORDER BY j.item_no;

    The returned rows are red, an empty value, and blue. This conversion treats the delimiter literally, not as a regular expression, and assumes the delimiter does not occur inside a value. For more complex parsing rules, a recursive common table expression can repeatedly locate the delimiter with LOCATE or INSTR and return each piece with its position.

    Oracle: REGEXP_SUBSTR for ordered rows and regex delimiters

    Oracle can extract the nth token with REGEXP_SUBSTR. REGEXP_COUNT supplies the number of rows, making the result ordered and allowing empty tokens to remain visible as NULL.

    Input and query:

    SELECT LEVEL AS position,
    REGEXP_SUBSTR(‘red,,blue’, ‘([^,]*)(,|$)’, 1, LEVEL, NULL, 1) AS piece
    FROM dual
    CONNECT BY LEVEL <= REGEXP_COUNT(‘red,,blue’, ‘,’) + 1
    ORDER BY position;

    The first capture group returns each token, including the empty middle token; Oracle represents an empty string as NULL. REGEXP_SUBSTR accepts regular-expression delimiters, so the capture pattern can be adapted for multi-character separators such as :: or more complex boundary rules. Keep the row-count expression aligned with that delimiter and use ORDER BY position for deterministic output.