Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
16: Complex Numbers in Python
Wait, why is it "j" and not "i"?
If you remember your high school algebra, you probably know the imaginary unit as i. However, if you try to use i in Python, the interpreter will think you're referencing a variable name and throw a NameError. Python follows the convention used in electrical engineering, where j is used to avoid confusion with current (which is usually denoted by i).
You can define a complex number literally by appending a j to a number, or by using the complex() constructor. I usually prefer the literal notation because it's cleaner, but the constructor is a lifesaver if your values are coming from variables.
# Literal notation
z1 = 3 + 4j
# Using the constructor (useful for dynamic values)
real_part = 10
imag_part = -5
z2 = complex(real_part, imag_part)
print(f"z1: {z1}") # (3+4j)
print(f"z2: {z2}") # (10-5j)
How do I pull the parts apart or find the magnitude?
Once you've got a complex number, you'll often need to isolate the real or imaginary components. Python makes this easy with built-in attributes. Just a heads-up: these attributes always return a float, regardless of whether you used integers to create the number.
If you need the magnitude (the distance from the origin in the complex plane), you use the built-in abs() function. It's essentially calculating the hypotenuse of the triangle formed by the real and imaginary parts.
z = 3 + 4j
print(z.real) # 3.0
print(z.imag) # 4.0
print(abs(z)) # 5.0 (The classic 3-4-5 triangle!)
Can I use the standard math module for this?
Here is where most people trip up. The standard math module is designed for real numbers. If you try to take the square root of a negative number using math.sqrt(-1), Python will scream at you with a ValueError.
To handle complex math, you need the cmath module (think "complex math"). It mirrors most of the math module's API but knows how to handle complex types. I've found this is especially useful when dealing with phases or polar coordinates.
import cmath
# This would crash with the regular math module
print(cmath.sqrt(-1)) # 1j
# Converting a complex number to polar coordinates (radius, phase)
z = 1 + 1j
radius, phase = cmath.polar(z)
print(f"Radius: {radius}, Phase: {phase}")
When would I actually use this in a real project?
I'll be honest: if you're building a website or a basic data scraper, you'll likely never touch this. But if you move into signal processing, physics simulations, or electrical engineering, it's non-negotiable.
Take AC circuit analysis, for example. In these circuits, resistance and reactance are combined into a single value called "impedance." Instead of juggling two different numbers for the real and imaginary parts of the impedance, you can just represent the entire state as a single complex number. It makes the algebra significantly cleaner because you can add, subtract, and multiply impedances using standard operators.
📋 Practical Task
Calculating AC Circuit Impedance
In electrical engineering, the total impedance (Z) of a series circuit is the sum of its individual impedances. You are tasked with calculating the total impedance of a circuit consisting of a resistor and an inductor.
Requirements:
- Create a complex number
z_resistorwith a real part of 50 (ohms) and an imaginary part of 0. - Create a complex number
z_inductorwith a real part of 0 and an imaginary part of 120 (ohms). - Calculate the total impedance
z_totalby adding the two together. - Print the total impedance, its magnitude (using
abs()), and the imaginary component.
# Your code here
There are no comments for now.