Created
April 26, 2024 00:40
-
-
Save christopherwoodall/f04b96ba0e9ea6de306d356e8436aa23 to your computer and use it in GitHub Desktop.
simple-circuit-solver.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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