File size: 16,505 Bytes
dfc428f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
import streamlit as st
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Circle, FancyArrowPatch

st.set_page_config(page_title="Circuit Analysis Simulator", layout="wide")

st.title("Interactive Circuit Analysis Simulator")
st.write("Explore basic circuit concepts including Ohm's Law, series and parallel circuits.")

# Sidebar for navigation
page = st.sidebar.radio("Choose a Simulation", 
                        ["Ohm's Law", "Series Circuit", "Parallel Circuit"])

if page == "Ohm's Law":
    st.header("Ohm's Law: V = I × R")
    st.write("""
    Ohm's Law describes the relationship between voltage (V), current (I), and resistance (R).
    Adjust the sliders to see how changing one parameter affects the others.
    """)
    
    col1, col2 = st.columns(2)
    
    with col1:
        # Let user control two of the variables and calculate the third
        calculation_mode = st.radio(
            "What do you want to calculate?",
            ["Voltage", "Current", "Resistance"]
        )
        
        if calculation_mode == "Voltage":
            current = st.slider("Current (A)", 0.1, 10.0, 1.0, 0.1)
            resistance = st.slider("Resistance (Ω)", 1.0, 100.0, 10.0, 1.0)
            voltage = current * resistance
            st.success(f"Calculated Voltage: {voltage:.2f} V")
        
        elif calculation_mode == "Current":
            voltage = st.slider("Voltage (V)", 1.0, 220.0, 12.0, 1.0)
            resistance = st.slider("Resistance (Ω)", 1.0, 100.0, 10.0, 1.0)
            current = voltage / resistance if resistance != 0 else float('inf')
            st.success(f"Calculated Current: {current:.2f} A")
        
        else:  # Resistance
            voltage = st.slider("Voltage (V)", 1.0, 220.0, 12.0, 1.0)
            current = st.slider("Current (A)", 0.1, 10.0, 1.0, 0.1)
            resistance = voltage / current if current != 0 else float('inf')
            st.success(f"Calculated Resistance: {resistance:.2f} Ω")
    
    with col2:
        # Create visualization
        fig, ax = plt.subplots(figsize=(8, 6))
        
        # Draw battery
        battery_height = 1.5
        battery_x = 1
        battery_y = 3
        
        # Long line
        ax.plot([battery_x, battery_x + 6], [battery_y + battery_height, battery_y + battery_height], 'k-', lw=2)
        # Bottom line
        ax.plot([battery_x, battery_x + 6], [battery_y, battery_y], 'k-', lw=2)
        
        # Battery
        ax.plot([battery_x, battery_x], [battery_y, battery_y + battery_height], 'k-', lw=2)
        ax.plot([battery_x + 0.2, battery_x + 0.2], [battery_y + 0.25, battery_y + battery_height - 0.25], 'k-', lw=4)
        ax.plot([battery_x + 0.5, battery_x + 0.5], [battery_y + 0.5, battery_y + battery_height - 0.5], 'k-', lw=2)
        
        # Resistor (zigzag)
        res_x = battery_x + 3
        res_y = battery_y + battery_height
        zigzag_width = 1.5
        zigzag_height = 0.5
        zigzag_pts = 7
        x_pts = np.linspace(res_x, res_x + zigzag_width, zigzag_pts)
        y_pts = np.array([0, 1, 0, 1, 0, 1, 0]) * zigzag_height + res_y
        ax.plot(x_pts, y_pts, 'k-', lw=2)
        
        # Add current direction arrow
        if calculation_mode == "Current" or calculation_mode == "Resistance":
            current_value = current
        else:
            current_value = current
        
        # Scale arrow size based on current
        arrow_scale = min(1, current_value / 5)
        arrow_width = 0.15 * (0.5 + arrow_scale)
        arrow = FancyArrowPatch((battery_x + 4.5, battery_y + 0.5), 
                              (battery_x + 3, battery_y + 0.5), 
                              arrowstyle='->', 
                              color='blue', 
                              lw=2,
                              mutation_scale=20)
        ax.add_patch(arrow)
        ax.text(battery_x + 3.8, battery_y + 0.3, f"{current:.1f} A", color='blue')
        
        # Add voltage label
        if calculation_mode == "Voltage" or calculation_mode == "Resistance":
            voltage_value = voltage
        else:
            voltage_value = voltage
            
        ax.text(battery_x + 0.7, battery_y + 0.75, f"{voltage:.1f} V", color='red')
        
        # Add resistance label
        if calculation_mode == "Resistance" or calculation_mode == "Voltage":
            resistance_value = resistance
        else:
            resistance_value = resistance
            
        ax.text(res_x + 0.2, res_y + 0.75, f"{resistance:.1f} Ω", color='green')
        
        ax.set_xlim(0, 8)
        ax.set_ylim(1, 6)
        ax.axis('equal')
        ax.axis('off')
        
        st.pyplot(fig)
        
        # Show the formula and calculation
        st.write("### Ohm's Law Formula")
        if calculation_mode == "Voltage":
            st.latex(r"V = I \times R")
            st.latex(f"V = {current:.2f} \, A \times {resistance:.2f} \, \Omega = {voltage:.2f} \, V")
        elif calculation_mode == "Current":
            st.latex(r"I = \frac{V}{R}")
            st.latex(f"I = \\frac{{{voltage:.2f} \, V}}{{{resistance:.2f} \, \Omega}} = {current:.2f} \, A")
        else:  # Resistance
            st.latex(r"R = \frac{V}{I}")
            st.latex(f"R = \\frac{{{voltage:.2f} \, V}}{{{current:.2f} \, A}} = {resistance:.2f} \, \Omega")

elif page == "Series Circuit":
    st.header("Series Circuit Analysis")
    st.write("""
    In a series circuit, the same current flows through each component, and the total voltage is the sum of the voltages across each component.
    """)
    
    col1, col2 = st.columns(2)
    
    with col1:
        # User inputs
        voltage_source = st.slider("Voltage Source (V)", 1.0, 24.0, 12.0, 0.1)
        
        st.subheader("Resistors in Series")
        num_resistors = st.slider("Number of Resistors", 1, 5, 3)
        
        resistances = []
        for i in range(num_resistors):
            r = st.slider(f"R{i+1} (Ω)", 1.0, 100.0, 10.0 * (i+1), 1.0, key=f"series_r{i}")
            resistances.append(r)
        
        # Calculations
        total_resistance = sum(resistances)
        current = voltage_source / total_resistance if total_resistance > 0 else 0
        voltage_drops = [current * r for r in resistances]
        power_dissipations = [current**2 * r for r in resistances]
        
        st.subheader("Circuit Analysis Results")
        st.write(f"Total Resistance: {total_resistance:.2f} Ω")
        st.write(f"Current: {current:.2f} A")
        
        # Display voltage drops and power for each resistor
        for i in range(num_resistors):
            st.write(f"R{i+1}: Voltage Drop = {voltage_drops[i]:.2f} V, Power = {power_dissipations[i]:.2f} W")
    
    with col2:
        # Create visualization of series circuit
        fig, ax = plt.subplots(figsize=(8, 6))
        
        # Draw circuit
        start_x, start_y = 1, 5
        
        # Draw battery
        battery_height = 1.5
        battery_x = start_x
        battery_y = start_y - battery_height/2
        
        # Battery
        ax.plot([battery_x, battery_x], [battery_y, battery_y + battery_height], 'k-', lw=2)
        ax.plot([battery_x + 0.2, battery_x + 0.2], [battery_y + 0.25, battery_y + battery_height - 0.25], 'k-', lw=4)
        ax.plot([battery_x + 0.5, battery_x + 0.5], [battery_y + 0.5, battery_y + battery_height - 0.5], 'k-', lw=2)
        
        # Label voltage source
        ax.text(battery_x + 0.7, battery_y + 0.75, f"{voltage_source:.1f} V", color='red')
        
        # Draw wires and resistors in series
        line_length = 10 / (num_resistors + 1)
        
        # Top line from battery to first resistor
        ax.plot([battery_x + 0.5, battery_x + line_length], [battery_y + battery_height - 0.5, battery_y + battery_height - 0.5], 'k-', lw=2)
        
        # Draw resistors in series
        for i in range(num_resistors):
            res_x = battery_x + line_length * (i + 1)
            res_y = battery_y + battery_height - 0.5
            
            # Draw resistor (zigzag)
            zigzag_width = 1.0
            zigzag_height = 0.5
            zigzag_pts = 7
            x_pts = np.linspace(res_x, res_x + zigzag_width, zigzag_pts)
            y_pts = np.array([0, 1, 0, 1, 0, 1, 0]) * zigzag_height + res_y
            ax.plot(x_pts, y_pts, 'k-', lw=2)
            
            # Label resistor
            ax.text(res_x + 0.2, res_y + 0.8, f"R{i+1}\n{resistances[i]:.1f}Ω\n{voltage_drops[i]:.1f}V", fontsize=8)
            
            # Connect to next resistor if not the last one
            if i < num_resistors - 1:
                ax.plot([res_x + zigzag_width, res_x + line_length], [res_y, res_y], 'k-', lw=2)
        
        # Bottom line back to battery
        ax.plot([battery_x + line_length * (num_resistors + 1) - line_length + zigzag_width, battery_x + 0.5], 
                [res_y, battery_y + 0.5], 'k-', lw=2)
        
        # Add current direction arrow
        arrow = FancyArrowPatch((battery_x + 0.5, battery_y + 0.5), 
                              (battery_x + line_length/2, battery_y + 0.5), 
                              arrowstyle='->', 
                              color='blue', 
                              lw=2,
                              mutation_scale=15)
        ax.add_patch(arrow)
        ax.text(battery_x + line_length/4, battery_y + 0.2, f"{current:.1f}A", color='blue', fontsize=9)
        
        ax.set_xlim(0, 12)
        ax.set_ylim(2, 8)
        ax.axis('equal')
        ax.axis('off')
        
        st.pyplot(fig)
        
        # Show formulas
        st.write("### Series Circuit Formulas")
        st.latex(r"R_{total} = R_1 + R_2 + ... + R_n")
        st.latex(f"R_{{total}} = {' + '.join([f'{r:.1f}' for r in resistances])} = {total_resistance:.2f} \, \Omega")
        st.latex(r"I = \frac{V_{source}}{R_{total}}")
        st.latex(f"I = \\frac{{{voltage_source:.2f}}}{{{total_resistance:.2f}}} = {current:.2f} \, A")
        st.latex(r"V_n = I \times R_n")

elif page == "Parallel Circuit":
    st.header("Parallel Circuit Analysis")
    st.write("""
    In a parallel circuit, each component has the same voltage across it, and the total current is the sum of the currents through each path.
    """)
    
    col1, col2 = st.columns(2)
    
    with col1:
        # User inputs
        voltage_source = st.slider("Voltage Source (V)", 1.0, 24.0, 12.0, 0.1)
        
        st.subheader("Resistors in Parallel")
        num_resistors = st.slider("Number of Resistors", 1, 5, 3)
        
        resistances = []
        for i in range(num_resistors):
            r = st.slider(f"R{i+1} (Ω)", 1.0, 100.0, float(10.0 * (i+1)), 1.0, key=f"parallel_r{i}")
            resistances.append(r)
        
        # Calculations
        inverse_resistance_sum = sum(1/r for r in resistances) if resistances else 0
        total_resistance = 1/inverse_resistance_sum if inverse_resistance_sum > 0 else float('inf')
        
        branch_currents = [voltage_source / r for r in resistances]
        total_current = sum(branch_currents)
        power_dissipations = [(voltage_source ** 2) / r for r in resistances]
        total_power = voltage_source * total_current
        
        st.subheader("Circuit Analysis Results")
        st.write(f"Total Resistance: {total_resistance:.2f} Ω")
        st.write(f"Total Current: {total_current:.2f} A")
        
        # Display current and power for each resistor
        for i in range(num_resistors):
            st.write(f"R{i+1}: Current = {branch_currents[i]:.2f} A, Power = {power_dissipations[i]:.2f} W")
    
    with col2:
        # Create visualization of parallel circuit
        fig, ax = plt.subplots(figsize=(8, 6))
        
        # Draw circuit
        start_x, start_y = 1, 5
        end_x = 9
        
        # Draw battery
        battery_height = 1.5
        battery_x = start_x
        battery_y = start_y - battery_height/2
        
        # Battery
        ax.plot([battery_x, battery_x], [battery_y, battery_y + battery_height], 'k-', lw=2)
        ax.plot([battery_x + 0.2, battery_x + 0.2], [battery_y + 0.25, battery_y + battery_height - 0.25], 'k-', lw=4)
        ax.plot([battery_x + 0.5, battery_x + 0.5], [battery_y + 0.5, battery_y + battery_height - 0.5], 'k-', lw=2)
        
        # Label voltage source
        ax.text(battery_x + 0.7, battery_y + 0.75, f"{voltage_source:.1f} V", color='red')
        
        # Top horizontal line
        ax.plot([battery_x + 0.5, end_x], [battery_y + battery_height - 0.5, battery_y + battery_height - 0.5], 'k-', lw=2)
        
        # Bottom horizontal line
        ax.plot([battery_x + 0.5, end_x], [battery_y + 0.5, battery_y + 0.5], 'k-', lw=2)
        
        # Add main current arrow
        arrow = FancyArrowPatch((battery_x + 1.5, battery_y + battery_height - 0.5), 
                              (battery_x + 2.5, battery_y + battery_height - 0.5), 
                              arrowstyle='->', 
                              color='blue', 
                              lw=2,
                              mutation_scale=15)
        ax.add_patch(arrow)
        ax.text(battery_x + 1.5, battery_y + battery_height - 0.8, f"{total_current:.1f}A", color='blue')
        
        # Draw resistors in parallel
        spacing = 5.0 / (num_resistors + 1)
        for i in range(num_resistors):
            res_x = battery_x + 2.5 + i * spacing
            res_y_top = battery_y + battery_height - 0.5
            res_y_bottom = battery_y + 0.5
            
            # Vertical lines to resistor
            ax.plot([res_x, res_x], [res_y_top, res_y_top - 1], 'k-', lw=2)
            ax.plot([res_x, res_x], [res_y_bottom, res_y_bottom + 1], 'k-', lw=2)
            
            # Draw resistor (zigzag horizontal)
            zigzag_height = 1.0
            zigzag_width = 0.5
            zigzag_pts = 7
            y_pts = np.linspace(res_y_top - 1, res_y_bottom + 1, zigzag_pts)
            x_pts = np.array([0, 1, 0, 1, 0, 1, 0]) * zigzag_width + res_x
            ax.plot(x_pts, y_pts, 'k-', lw=2)
            
            # Branch current arrow
            branch_arrow = FancyArrowPatch((res_x - 0.3, res_y_top - 0.5), 
                                        (res_x - 0.3, res_y_top - 1.5), 
                                        arrowstyle='->', 
                                        color='blue', 
                                        lw=2,
                                        mutation_scale=15)
            ax.add_patch(branch_arrow)
            
            # Label resistor and current
            ax.text(res_x + 0.6, res_y_top - 1.5, f"R{i+1}\n{resistances[i]:.1f}Ω\n{branch_currents[i]:.2f}A", fontsize=8)
        
        ax.set_xlim(0, 12)
        ax.set_ylim(2, 8)
        ax.axis('equal')
        ax.axis('off')
        
        st.pyplot(fig)
        
        # Show formulas
        st.write("### Parallel Circuit Formulas")
        st.latex(r"\frac{1}{R_{total}} = \frac{1}{R_1} + \frac{1}{R_2} + ... + \frac{1}{R_n}")
        
        # Create the fractions part without f-strings
        fractions_parts = []
        for r in resistances:
            fractions_parts.append(r"\frac{1}{" + f"{r:.1f}" + "}")
        fractions_text = " + ".join(fractions_parts)
        
        st.latex(r"\frac{1}{R_{total}} = " + fractions_text + f" = {inverse_resistance_sum:.4f}")
        st.latex(r"R_{total} = \frac{1}{" + f"{inverse_resistance_sum:.4f}" + r"} = " + f"{total_resistance:.2f} \, \Omega")
        st.latex(r"I_{total} = I_1 + I_2 + ... + I_n")
        st.latex(f"I_{{total}} = {' + '.join([f'{i:.2f}' for i in branch_currents])} = {total_current:.2f} \, A")
        st.latex(r"I_n = \frac{V}{R_n}")

st.sidebar.markdown('''File "D:\projects\physics-simulations\pages\basic-circuit-analysis.py", line 359
              fractions_parts.append(r""\frac{1}{""" + f"{r:.1f}" + r""}""")
                                                                           ^
SyntaxError: unexpected character after line continuation character
### Basic Circuit Concepts

**Ohm's Law:** V = IR  
- V: Voltage (Volts)
- I: Current (Amperes)
- R: Resistance (Ohms)

**Series Circuit Properties:**
- Same current through all components
- Rtotal = R1 + R2 + ... + Rn
- Vtotal = V1 + V2 + ... + Vn

**Parallel Circuit Properties:**
- Same voltage across all components
- 1/Rtotal = 1/R1 + 1/R2 + ... + 1/Rn
- Itotal = I1 + I2 + ... + In
''')