It is used in a broad range of applications including performing scientific calculations thanks to the SciPy libraries.

This blog entry links to a pair of Google Colaboratory documents. Colaboratory documents are Python Jupyter Notebooks hosted in a Google Drive account that run the code in virtual machines owned by Google.

That way you don't need to have

**Python**installed to try or modify the proposed code.

### Solving circuits with SymPy

SymPy is one of the**SciPy**libraries. It enables you to perform symbolic calculations. This can come handy to solve electrical circuits like the one below:

In order to solve a circuit, you need to obtain a set of equations whose solution is the magnitude you want to know. In the above circuit, let's say that we want to know the value of

**Vo**as function of

**Vs**,

**R1**,

**R2**and

**Is**.

You start defining

**symbols**for the circuit. We need symbols for the component values

**Vs**,

**R1**,

**R2**and

**Is**and for the solution

**Vo**.

As we will solve the circuit using the nodal method that applies current equations in all nodes except the

**ground**one, we also need symbols for the nodal voltages

**V1**and

**V2**.

Also, using the full nodal method requires as to add a symbol, like

**iVs**for the current in the source voltages.

# Create the circuit symbols

Vs,iVs,R1,R2,Is,Vo, V1, V2 = sympy.symbols('Vs,iVs,R1,R2,Is,Vo,V1,V2')

Now we define the equations of nodes 1 and 2. To do that, we initizalize an empty list of equations and add the two equations to this list. Using the nodal method, we apply the Kirchhoff KCL law on each node:

# Create an empty list of equations

equations = []

# Nodal equations

equations.append(iVs-(V1-V2)/R1) # Node 1

equations.append(Is-(V2-V1)/R1-V2/R2) # Node 2

In

**SymPy**it is assumed that all equations are equal to zero.

In the nodal method we also need to add an equation for each

**voltage source**that relates it to the node voltages. In SymPy,

**Eq**means equal, so, Eq(Vs,V1) means Vs = V1.

# Voltage source equations

equations.append(sympy.Eq(Vs,V1))

The final equation is the one that contains the result we want to obtain for the circuit:

# Measurement equations

equations.append(sympy.Eq(Vo,V2))

Now we have a full set of equations:

```
iVs - (V1 - V2)/R1
Is - V2/R2 - (-V1 + V2)/R1
Eq(Vs, V1)
Eq(Vo, V2)
```

Those equations enables us to obtain

**Vo**but a smaller set of equation will also work. In particular, as the first equation contains an unknown

**iVs**that is not found in any other equation, we can eliminate this equation if the only unknown we care for is

**Vo**. We don't need, however, to know that to solve the circuit.

In these equations, some variables are unknowns, we make a list of them:

unknowns = [V1,V2,iVs,Vo]

Then we can solve the circuit using the

**solve**function of the

**SymPy**library:

# Solve the circuit

solution = sympy.solve(equations,unknowns)

That will yield the

**solutions**for the

**unknowns**:

```
V1 = Vs
V2 = R2*(Is*R1 + Vs)/(R1 + R2)
iVs = (-Is*R2 + Vs)/(R1 + R2)
Vo = R2*(Is*R1 + Vs)/(R1 + R2)
```

If you want to see more details, more circuit solutions or you want to test te code yourself, open this colaboratory document.

### Automating the solution

As you can see we have followed a recipe for solving the circuit. That means that it can be automated. The**circuit**Python module, just does that: Solves a circuit using the nodal method recipe.

As we remember the circuit is:

We can describe it just with a list of

**components**and

**measurements**:

# Circuit 1 definiton

c1 = circuit.circuit() # New circuit

c1.addV('Vs',1,0,5) # Vs between 1 and GND with 5 V value

c1.addR('R1',1,2,1000) # R1 between 1 and 2 with 1000 Ohm value

c1.addR('R2',2,0,1000) # R2 between 2 and GND with 1000 Ohm value

c1.addI('Is',2,0,0.01) # Is going from GND to 2 with 10 mA value

c1.addVM('Vo',2,0) # Measurement Vo between 2 and GND

Then we can obtain the symbolic solution for

**Vo**:

# Symbolic solution

print('Vo =',c1.solution['Vo'],' (Symbolic)')

That yields:

`Vo = R2*(Is*R1 + Vs)/(R1 + R2) (Symbolic)`

Note that this is the very same solution we obtained previously without using the

**SymPy**module.

Also, as we have indicated the component values, we can also obtain the numerical solution:

# Numeric solution

print('Vo =',c1.particular['Vo'],'V (Particular)')

That yields:

`Vo = 7.5 V (Particular)`

If you want to see more about the

**circuit**module, see other solutions or use your own code, open this colaboratory document.