Skip to content

Instantly share code, notes, and snippets.

@christopherwoodall
Created April 26, 2024 00:40
Show Gist options
  • Save christopherwoodall/f04b96ba0e9ea6de306d356e8436aa23 to your computer and use it in GitHub Desktop.
Save christopherwoodall/f04b96ba0e9ea6de306d356e8436aa23 to your computer and use it in GitHub Desktop.
simple-circuit-solver.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyOc64x5ofamptujb09OCohZ",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/0xchrisw/f04b96ba0e9ea6de306d356e8436aa23/simple-circuit-solver.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"source": [
"# Formatting & Conversion Utilities"
],
"metadata": {
"id": "Kp1DgJiEkIK6"
}
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {
"id": "7YORrJqgkEXa"
},
"outputs": [],
"source": [
"from typing import Any, List, Tuple\n",
"\n",
"\n",
"def parse_metric_input(value: str) -> float:\n",
" \"\"\"\n",
" Parses a string containing a metric value and returns the value in its base unit,\n",
" removing any non-numeric, non-postfix characters.\n",
" \"\"\"\n",
" postfixes: Tuple[Tuple[str, float], ...] = (\n",
" (\"k\", 1e3), # kilo\n",
" (\"M\", 1e6), # Mega\n",
" (\"G\", 1e9), # Giga\n",
" (\"m\", 1e-3), # milli\n",
" (\"u\", 1e-6), # micro\n",
" (\"n\", 1e-9), # nano\n",
" (\"p\", 1e-12), # pico\n",
" )\n",
"\n",
" # Filter out non-numeric, non-metric characters (e.g., \"V\" for voltage or \"Ω\" for resistance)\n",
" value_cleaned: str = \"\".join(\n",
" filter(\n",
" lambda x: x.isdigit()\n",
" or x == \".\"\n",
" or any(postfix[0] == x for postfix in postfixes),\n",
" value,\n",
" )\n",
" )\n",
"\n",
" # Extract the numeric part and the postfix\n",
" for postfix, multiplier in postfixes:\n",
" if postfix in value_cleaned:\n",
" num_part, _ = value_cleaned.split(postfix)\n",
" return float(num_part) * multiplier\n",
" return float(value_cleaned)\n",
"\n",
"\n",
"def format_metric_output(value: float) -> str:\n",
" \"\"\"\n",
" Formats a value to include the most suitable metric postfix.\n",
" \"\"\"\n",
" postfixes: List[Tuple[float, str]] = [\n",
" (1e9, \"G\"),\n",
" (1e6, \"M\"),\n",
" (1e3, \"k\"),\n",
" (1, \"\"),\n",
" (1e-3, \"m\"),\n",
" (1e-6, \"u\"),\n",
" (1e-9, \"n\"),\n",
" (1e-12, \"p\"),\n",
" ]\n",
" for divisor, postfix in postfixes:\n",
" if abs(value) >= divisor:\n",
" return f\"{value / divisor:.2f}{postfix}\"\n",
" return str(value)\n",
"\n",
"\n",
"def print_results(results: Dict[str, Any]) -> None:\n",
" \"\"\"\n",
" Pretty print the results\n",
" \"\"\"\n",
" print(\"Circuit Analysis Results:\")\n",
" for key, value in results.items():\n",
" if key != \"resistors\":\n",
" print(f\"{key.capitalize()}: {value}\")\n",
" else:\n",
" print(\"Resistor Details:\")\n",
" for i, resistor in enumerate(value, 1):\n",
" print(f\" Resistor {i}:\")\n",
" for res_key, res_value in resistor.items():\n",
" print(f\" {res_key.capitalize()}: {res_value}\")\n"
]
},
{
"cell_type": "markdown",
"source": [
"# Parameterized Dataclass"
],
"metadata": {
"id": "nvsrxif_shay"
}
},
{
"cell_type": "code",
"source": [
"from dataclasses import dataclass\n",
"\n",
"\n",
"@dataclass\n",
"class CircuitParameters:\n",
" \"\"\"\n",
" Represents the parameters for a circuit calculation.\n",
"\n",
" Attributes:\n",
" - circuit_type (str): The type of circuit, either 'series' or 'parallel'.\n",
" - voltage (str): The voltage of the circuit, specified with a metric postfix.\n",
" - resistors (List[str]): A list of resistor values, each specified with a metric postfix.\n",
" \"\"\"\n",
" circuit_type: str\n",
" voltage: str\n",
" resistors: List[str]\n"
],
"metadata": {
"id": "gzjxtfpDshqm"
},
"execution_count": 25,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Circuit Solver Logic"
],
"metadata": {
"id": "GDhIky9UkxYX"
}
},
{
"cell_type": "code",
"source": [
"from typing import Dict, Any, List\n",
"\n",
"\n",
"def calculate_circuit(parameters: CircuitParameters) -> Dict[str, Any]:\n",
" \"\"\"\n",
" Calculates voltage, total resistance, current, and power for either a series\n",
" or parallel circuit, including the appropriate details for each resistor.\n",
"\n",
" Parameters:\n",
" - parameters: A CircuitParameters object with attributes 'circuit_type', 'voltage',\n",
" and 'resistors', where 'circuit_type' specifies the circuit type (either 'series' or 'parallel'),\n",
" 'voltage' is a string that may contain a metric postfix, and 'resistors' is a\n",
" list of resistor values (also as strings with potential postfixes).\n",
"\n",
" Returns:\n",
" - A dictionary with keys 'total_resistance', 'voltage', 'current', 'power',\n",
" and 'resistors', where 'resistors' is a list of dictionaries, each containing\n",
" 'resistance', 'current' (if applicable), and 'power_dissipation' for each resistor.\n",
" \"\"\"\n",
" circuit_type: str = parameters.circuit_type\n",
" voltage: float = (\n",
" parse_metric_input(parameters.voltage)\n",
" if parameters.voltage\n",
" else None\n",
" )\n",
" resistors: List[float] = [\n",
" parse_metric_input(r) for r in parameters.resistors if r\n",
" ]\n",
"\n",
" if circuit_type == \"series\":\n",
" total_resistance: float = sum(resistors)\n",
" current: float = voltage / total_resistance if voltage is not None else None\n",
" power: float = voltage * current if voltage and current else None\n",
"\n",
" resistor_details: List[Dict[str, Any]] = []\n",
" for resistor in resistors:\n",
" voltage_drop: float = current * resistor if current is not None else None\n",
" power_dissipation: float = (\n",
" (current**2) * resistor if current is not None else None\n",
" )\n",
" resistor_details.append(\n",
" {\n",
" \"resistance\": format_metric_output(resistor),\n",
" \"voltage_drop\": format_metric_output(voltage_drop)\n",
" if voltage_drop is not None\n",
" else \"N/A\",\n",
" \"power_dissipation\": format_metric_output(power_dissipation)\n",
" if power_dissipation is not None\n",
" else \"N/A\",\n",
" }\n",
" )\n",
"\n",
" elif circuit_type == \"parallel\":\n",
" total_conductance: float = sum([1 / r for r in resistors])\n",
" total_resistance: float = 1 / total_conductance if total_conductance != 0 else float('inf')\n",
" current: float = voltage / total_resistance if voltage is not None else None\n",
" power: float = voltage * current if voltage and current else None\n",
"\n",
" resistor_details: List[Dict[str, Any]] = []\n",
" for resistor in resistors:\n",
" resistor_current: float = (\n",
" voltage / resistor if voltage is not None else None\n",
" )\n",
" power_dissipation: float = (\n",
" (resistor_current**2) * resistor\n",
" if resistor_current is not None\n",
" else None\n",
" )\n",
" resistor_details.append(\n",
" {\n",
" \"resistance\": format_metric_output(resistor),\n",
" \"current\": format_metric_output(resistor_current)\n",
" if resistor_current is not None\n",
" else \"N/A\",\n",
" \"power_dissipation\": format_metric_output(power_dissipation)\n",
" if power_dissipation is not None\n",
" else \"N/A\",\n",
" }\n",
" )\n",
"\n",
" else:\n",
" raise ValueError(\n",
" \"Invalid circuit type. Supported types are 'series' and 'parallel'.\"\n",
" )\n",
"\n",
" results: Dict[str, Any] = {\n",
" \"total_resistance\": format_metric_output(total_resistance),\n",
" \"voltage\": format_metric_output(voltage) if voltage is not None else \"N/A\",\n",
" \"current\": format_metric_output(current) if current is not None else \"N/A\",\n",
" \"power\": format_metric_output(power) if power is not None else \"N/A\",\n",
" \"resistors\": resistor_details,\n",
" }\n",
"\n",
" return results\n"
],
"metadata": {
"id": "QbX467-lkxAE"
},
"execution_count": 35,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# Series Example"
],
"metadata": {
"id": "GuVq052rnIlX"
}
},
{
"cell_type": "code",
"source": [
"parameters = CircuitParameters(\n",
" circuit_type=\"series\", # [ series | parallel ]\n",
" voltage=\"240V\", # Voltage with the \"V\" prefix\n",
" resistors=[\"80k\", \"20\", \"60Ω\"], # Resistor values in metric format\n",
")\n",
"\n",
"results = calculate_circuit(parameters)\n",
"print_results(results)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "alCdiM8jnI8w",
"outputId": "c67fc620-ca84-4172-a32f-5490a56ebc28"
},
"execution_count": 71,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Circuit Analysis Results:\n",
"Total_resistance: 80.08k\n",
"Voltage: 240.00\n",
"Current: 3.00m\n",
"Power: 719.28m\n",
"Resistor Details:\n",
" Resistor 1:\n",
" Resistance: 80.00k\n",
" Voltage_drop: 239.76\n",
" Power_dissipation: 718.56m\n",
" Resistor 2:\n",
" Resistance: 20.00\n",
" Voltage_drop: 59.94m\n",
" Power_dissipation: 179.64u\n",
" Resistor 3:\n",
" Resistance: 60.00\n",
" Voltage_drop: 179.82m\n",
" Power_dissipation: 538.92u\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# Parallel Example"
],
"metadata": {
"id": "iPOmyQGjmZ_U"
}
},
{
"cell_type": "code",
"source": [
"parameters = CircuitParameters(\n",
" circuit_type=\"parallel\", # [ series | parallel ]\n",
" voltage=\"120V\", # Voltage with the \"V\" prefix\n",
" resistors=[\"80k\", \"20\", \"60Ω\"], # Resistor values in metric format\n",
")\n",
"\n",
"results = calculate_circuit(parameters)\n",
"print_results(results)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "dzj0LlPXlADJ",
"outputId": "6013d7a2-87ed-43b4-95fd-4137ca53a01f"
},
"execution_count": 70,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Circuit Analysis Results:\n",
"Total_resistance: 15.00\n",
"Voltage: 120.00\n",
"Current: 8.00\n",
"Power: 960.18\n",
"Resistor Details:\n",
" Resistor 1:\n",
" Resistance: 80.00k\n",
" Current: 1.50m\n",
" Power_dissipation: 180.00m\n",
" Resistor 2:\n",
" Resistance: 20.00\n",
" Current: 6.00\n",
" Power_dissipation: 720.00\n",
" Resistor 3:\n",
" Resistance: 60.00\n",
" Current: 2.00\n",
" Power_dissipation: 240.00\n"
]
}
]
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "zlEwRLUEnjtj"
},
"execution_count": null,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment